Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/main/java/com/somemore/location/domain/Location.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
import static lombok.AccessLevel.PROTECTED;

import com.somemore.global.common.BaseEntity;
import com.somemore.location.dto.request.LocationUpdateRequestDto;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.math.BigDecimal;
import java.math.RoundingMode;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -36,7 +38,13 @@ public class Location extends BaseEntity {
@Builder
public Location(String address, BigDecimal latitude, BigDecimal longitude) {
this.address = address;
this.latitude = latitude;
this.longitude = longitude;
this.latitude = latitude.setScale(8, RoundingMode.HALF_UP);
this.longitude = longitude.setScale(8, RoundingMode.HALF_UP);
}

public void updateWith(LocationUpdateRequestDto requestDto) {
this.address = requestDto.address();
this.latitude = requestDto.latitude().setScale(8, RoundingMode.HALF_UP);
this.longitude = requestDto.longitude().setScale(8, RoundingMode.HALF_UP);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.somemore.location.dto.request;

import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.math.BigDecimal;
import lombok.Builder;

@JsonNaming(SnakeCaseStrategy.class)
@Builder
public record LocationUpdateRequestDto(
@Schema(description = "도로명 주소", example = "서울특별시 서초구 반포대로 45, 4층(서초동, 명정빌딩)")
@NotBlank(message = "주소는 필수 입력 값입니다.")
String address,
@Schema(description = "주소에 해당하는 위도 정보", example = "37.4845373748015")
@NotNull(message = "위도는 필수 입력 값입니다.")
@DecimalMin(value = "33", message = "위도는 33도 이상이어야 합니다.")
@DecimalMax(value = "39", message = "위도는 38도 이하이어야 합니다.")
BigDecimal latitude,
@Schema(description = "주소에 해당하는 경도 정보", example = "127.010842267696")
@NotNull(message = "경도는 필수 입력 값입니다.")
@DecimalMin(value = "124", message = "경도는 124도 이상이어야 합니다.")
@DecimalMax(value = "132", message = "경도는 132도 이하이어야 합니다.")
BigDecimal longitude
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ public interface LocationRepository {

Location save(Location location);

Location saveAndFlush(Location location);

Optional<Location> findById(Long id);

void deleteAllInBatch();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ public Location save(Location location) {
return locationJpaRepository.save(location);
}

@Override
public Location saveAndFlush(Location location) {
return locationJpaRepository.saveAndFlush(location);
}

@Override
public Optional<Location> findById(Long id) {
return locationJpaRepository.findById(id);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.somemore.location.service.command;

import com.somemore.location.domain.Location;
import com.somemore.location.dto.request.LocationUpdateRequestDto;
import com.somemore.location.repository.LocationRepository;
import com.somemore.location.usecase.command.UpdateLocationUseCase;
import com.somemore.location.usecase.query.LocationQueryUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Transactional
@Service
public class UpdateLocationService implements UpdateLocationUseCase {

private final LocationQueryUseCase locationQueryUseCase;
private final LocationRepository locationRepository;

@Override
public void updateLocation(LocationUpdateRequestDto requestDto, Long locationId) {
Location location = locationQueryUseCase.findByIdOrThrow(locationId);
location.updateWith(requestDto);
locationRepository.save(location);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.somemore.location.service.query;

import com.somemore.global.exception.BadRequestException;
import com.somemore.location.domain.Location;
import com.somemore.location.repository.LocationRepository;
import com.somemore.location.usecase.query.LocationQueryUseCase;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Transactional(readOnly = true)
@Service
public class LocationQueryService implements LocationQueryUseCase {

private final LocationRepository locationRepository;

@Override
public Optional<Location> findById(Long id) {
return locationRepository.findById(id);
}

@Override
public Location findByIdOrThrow(Long id) {
return locationRepository.findById(id).orElseThrow(
() -> new BadRequestException("존재하지 않는 위치입니다.")
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.somemore.location.usecase.command;

import com.somemore.location.dto.request.LocationUpdateRequestDto;

public interface UpdateLocationUseCase {

void updateLocation(LocationUpdateRequestDto requestDto, Long locationId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.somemore.location.usecase.query;

import com.somemore.location.domain.Location;
import java.util.Optional;

public interface LocationQueryUseCase {

Optional<Location> findById(Long id);

Location findByIdOrThrow(Long id);

}
80 changes: 37 additions & 43 deletions src/main/java/com/somemore/recruitboard/domain/RecruitBoard.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
import static lombok.AccessLevel.PROTECTED;

import com.somemore.global.common.BaseEntity;
import com.somemore.recruitboard.dto.request.RecruitBoardUpdateRequestDto;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import jakarta.persistence.Table;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.UUID;
import lombok.Builder;
Expand Down Expand Up @@ -44,64 +44,58 @@ public class RecruitBoard extends BaseEntity {
@Column(name = "content", nullable = false)
private String content;

@Column(name = "region", nullable = false)
private String region;

@Column(name = "recruitment_count", nullable = false)
private Integer recruitmentCount;

@Column(name = "img_url", nullable = false)
private String imgUrl;
@Embedded
private VolunteerInfo volunteerInfo;

@Enumerated(value = STRING)
@Column(name = "recruit_status", nullable = false, length = 20)
private RecruitStatus recruitStatus = RECRUITING;

@Column(name = "volunteer_start_date_time", nullable = false)
private LocalDateTime volunteerStartDateTime;

@Column(name = "volunteer_end_date_time", nullable = false)
private LocalDateTime volunteerEndDateTime;

@Enumerated(value = STRING)
@Column(name = "volunteer_type", nullable = false, length = 30)
private VolunteerType volunteerType;

@Column(name = "admitted", nullable = false)
private Boolean admitted;
@Column(name = "img_url", nullable = false)
private String imgUrl;

@Builder
public RecruitBoard(UUID centerId, Long locationId, String title, String content, String region,
Integer recruitmentCount, String imgUrl, LocalDateTime volunteerStartDateTime,
LocalDateTime volunteerEndDateTime, VolunteerType volunteerType, Boolean admitted) {

validateVolunteerDateTime(volunteerStartDateTime, volunteerEndDateTime);

public RecruitBoard(UUID centerId, Long locationId, String title, String content,
VolunteerInfo volunteerInfo, String imgUrl) {
this.centerId = centerId;
this.locationId = locationId;
this.title = title;
this.content = content;
this.region = region;
this.recruitmentCount = recruitmentCount;
this.volunteerInfo = volunteerInfo;
this.imgUrl = imgUrl;
this.volunteerStartDateTime = volunteerStartDateTime;
this.volunteerEndDateTime = volunteerEndDateTime;
this.volunteerType = volunteerType;
this.admitted = admitted;
}

public LocalTime calculateVolunteerTime() {
Duration duration = Duration.between(volunteerStartDateTime, volunteerEndDateTime);
public LocalTime getVolunteerHours() {
return volunteerInfo.calculateVolunteerTime();
}

public boolean isWriter(UUID centerId) {
return this.centerId.equals(centerId);
}

public boolean isNotWriter(UUID centerId) {
return !isWriter(centerId);
}

long hours = duration.toHours();
long minutes = duration.toMinutes() % 60;
public void updateWith(RecruitBoardUpdateRequestDto dto, String imgUrl) {
updateVolunteerInfo(dto);
this.title = dto.title();
this.content = dto.content();
this.imgUrl = imgUrl;
}

return LocalTime.of((int) hours, (int) minutes);
public void updateWith(String region) {
volunteerInfo.updateWith(region);
}

private void validateVolunteerDateTime(LocalDateTime startDateTime, LocalDateTime endDateTime) {
if (endDateTime.isEqual(startDateTime) || endDateTime.isBefore(startDateTime)) {
throw new IllegalArgumentException("종료 시간은 시작 시간보다 이후여야 합니다.");
}
private void updateVolunteerInfo(RecruitBoardUpdateRequestDto dto) {
volunteerInfo.updateWith(
dto.recruitmentCount(),
dto.volunteerType(),
dto.volunteerStartDateTime(),
dto.volunteerEndDateTime(),
dto.admitted()
);
}

}
86 changes: 86 additions & 0 deletions src/main/java/com/somemore/recruitboard/domain/VolunteerInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.somemore.recruitboard.domain;

import static jakarta.persistence.EnumType.STRING;
import static lombok.AccessLevel.PROTECTED;

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.persistence.Enumerated;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = PROTECTED)
@Embeddable
public class VolunteerInfo {

@Column(name = "region", nullable = false)
private String region;

@Column(name = "recruitment_count", nullable = false)
private Integer recruitmentCount;

@Column(name = "volunteer_start_date_time", nullable = false)
private LocalDateTime volunteerStartDateTime;

@Column(name = "volunteer_end_date_time", nullable = false)
private LocalDateTime volunteerEndDateTime;

@Enumerated(value = STRING)
@Column(name = "volunteer_type", nullable = false, length = 30)
private VolunteerType volunteerType;

@Column(name = "admitted", nullable = false)
private Boolean admitted;

@Builder
public VolunteerInfo(String region, Integer recruitmentCount,
LocalDateTime volunteerStartDateTime, LocalDateTime volunteerEndDateTime,
VolunteerType volunteerType, Boolean admitted) {

validateVolunteerDateTime(volunteerStartDateTime, volunteerEndDateTime);

this.region = region;
this.recruitmentCount = recruitmentCount;
this.volunteerStartDateTime = volunteerStartDateTime;
this.volunteerEndDateTime = volunteerEndDateTime;
this.volunteerType = volunteerType;
this.admitted = admitted;
}

public LocalTime calculateVolunteerTime() {
Duration duration = Duration.between(volunteerStartDateTime, volunteerEndDateTime);

long hours = duration.toHours();
long minutes = duration.toMinutes() % 60;

return LocalTime.of((int) hours, (int) minutes);
}

public void updateWith(Integer recruitmentCount, VolunteerType volunteerType,
LocalDateTime volunteerStartDateTime, LocalDateTime volunteerEndDateTime,
Boolean admitted) {

validateVolunteerDateTime(volunteerStartDateTime, volunteerEndDateTime);

this.recruitmentCount = recruitmentCount;
this.volunteerType = volunteerType;
this.volunteerStartDateTime = volunteerStartDateTime;
this.volunteerEndDateTime = volunteerEndDateTime;
this.admitted = admitted;
}

public void updateWith(String region) {
this.region = region;
}

private void validateVolunteerDateTime(LocalDateTime startDateTime, LocalDateTime endDateTime) {
if (endDateTime.isEqual(startDateTime) || endDateTime.isBefore(startDateTime)) {
throw new IllegalArgumentException("종료 시간은 시작 시간보다 이후여야 합니다.");
}
}
}
Loading
Loading