Skip to content

Commit 5a426e5

Browse files
authored
[FU-191] 기본 스케줄 관리 (#89)
* FU-191 feat: 기본 스케줄 엔티티 구현 * FU-191 feat: 기본 스케줄 업데이트 로직 구현 * FU-191 feat: 회원가입 시 디폴트 기본 스케줄 생성 * FU-191 feat: 기본 스케줄 시간설정에 대한 에러명 수정 * FU-191 feat: 기본 스케줄 조회 * FU-191 feat: 회원탈퇴시 기본 스케줄 삭제 * FU-191 feat: 회원가입시 운영 시간 단위를 초기화 * FU-191 feat: 스케줄 운영시간 단위 조회 * FU-191 feat: 스케줄 운영시간 단위 수정 * FU-191 feat: 기본 스케줄에 휴무 여부 필드 추가 * FU-191 feat: 스케줄 비활성화시 디폴트 운영시간 적용 * FU-191 refactor: 단위 테스트를 하기 위한 메서드 분리 * FU-191 feat: 변경감지를 위한 Transactional 처리 및 오류 수정 * FU-191 feat: updateSchedule 메서드에 대한 테스트 코드 추가 * FU-191 refactor: entity를 dto로 변환하는 로직 메서드 분리 * FU-191 feat: 기본 스케줄 변경시 시작시간과 종료시간이 같을 때도 예외처리 되도록 검증부 추가 * FU-191 feat: 운영시간 단위 변경시 기본 스케줄 초기화 * FU-191 feat: initializeScheduleInfo()메서드에서 save()메서드 제거 이미 completePhotographerSignup()메서드에서 photographer에 대한 JPA 영속화가 진행되어 더티 체킹이 일어나서 없어도 저장가능 * FU-191 refactor: 메서드 분리 및 가독성을 위한 Stream API 사용 * FU-191 feat: 요청 Json객체에 각 필드 검증을 위한 @Valid 추가 * FU-191 feat: 클라이언트단에 아무런 변화가 없을 때 응답하는 에러메시지 삭제 * FU-191 refactor: 멤버 객체를 setUp()메서드를 통해 각 테스트에 제공하도록 변경
1 parent 6c37ca0 commit 5a426e5

14 files changed

Lines changed: 552 additions & 0 deletions

File tree

src/main/java/com/foru/freebe/auth/service/KakaoUnlinkService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.springframework.web.reactive.function.client.WebClientException;
1414

1515
import com.foru.freebe.auth.dto.UnlinkRequest;
16+
import com.foru.freebe.schedule.service.BaseScheduleService;
1617
import com.foru.freebe.errors.errorcode.MemberErrorCode;
1718
import com.foru.freebe.errors.exception.RestApiException;
1819
import com.foru.freebe.jwt.service.JwtService;
@@ -45,6 +46,7 @@ public class KakaoUnlinkService {
4546
private final DeletedMemberRepository deletedMemberRepository;
4647
private final PhotographerNoticeService photographerNoticeService;
4748
private final JwtService jwtService;
49+
private final BaseScheduleService baseScheduleService;
4850

4951
@Value("${KAKAO_API_ADMIN_KEY}")
5052
private String adminKey;
@@ -81,6 +83,7 @@ private void deleteInfoOfPhotographer(Member member) {
8183
deletePhotographerProducts(member);
8284
photographerNoticeService.deleteAllNotices(member);
8385
photographerProfileService.deleteProfile(member);
86+
baseScheduleService.deleteBaseSchedule(member);
8487
}
8588
}
8689

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.foru.freebe.errors.errorcode;
2+
3+
import lombok.Getter;
4+
import lombok.RequiredArgsConstructor;
5+
6+
@Getter
7+
@RequiredArgsConstructor
8+
public enum ScheduleErrorCode implements ErrorCode {
9+
10+
START_TIME_AFTER_END_TIME(400, "시작시간과 종료시간이 올바르지 않습니다.");
11+
12+
13+
private final int httpStatus;
14+
private final String message;
15+
}

src/main/java/com/foru/freebe/member/entity/Member.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,17 @@ public class Member extends BaseEntity {
5151

5252
private String instagramId;
5353

54+
@Enumerated(EnumType.STRING)
55+
private ScheduleUnit scheduleUnit;
56+
57+
public void initializeScheduleUnit() {
58+
this.scheduleUnit = ScheduleUnit.SIXTY_MINUTES;
59+
}
60+
61+
public void updateScheduleUnit(ScheduleUnit scheduleUnit) {
62+
this.scheduleUnit = scheduleUnit;
63+
}
64+
5465
public void assignRole(Role role) {
5566
this.role = role;
5667
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.foru.freebe.member.entity;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
public enum ScheduleUnit {
6+
7+
@JsonProperty("THIRTY_MINUTES")
8+
THIRTY_MINUTES,
9+
@JsonProperty("SIXTY_MINUTES")
10+
SIXTY_MINUTES
11+
}

src/main/java/com/foru/freebe/member/service/PhotographerJoinService.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import com.foru.freebe.auth.model.ServiceTermsAgreement;
66
import com.foru.freebe.auth.service.KakaoAuthService;
7+
import com.foru.freebe.schedule.service.BaseScheduleService;
78
import com.foru.freebe.member.dto.PhotographerJoinRequest;
89
import com.foru.freebe.member.entity.Member;
910
import com.foru.freebe.member.entity.MemberTermAgreement;
@@ -23,6 +24,7 @@ public class PhotographerJoinService {
2324
private final MemberRepository memberRepository;
2425
private final MemberTermAgreementRepository memberTermAgreementRepository;
2526
private final KakaoAuthService kakaoAuthService;
27+
private final BaseScheduleService baseScheduleService;
2628

2729
@Transactional
2830
public String joinPhotographer(Member member, PhotographerJoinRequest request) {
@@ -33,9 +35,16 @@ public String joinPhotographer(Member member, PhotographerJoinRequest request) {
3335
Profile profile = profileService.initialProfileSetting(photographer, request.getProfileName(),
3436
request.getContact());
3537

38+
initializeScheduleInfo(photographer);
39+
3640
return profile.getProfileName();
3741
}
3842

43+
private void initializeScheduleInfo(Member photographer) {
44+
baseScheduleService.createDefaultSchedule(photographer);
45+
photographer.initializeScheduleUnit();
46+
}
47+
3948
private Member completePhotographerSignup(Member member) {
4049
member.assignRole(Role.PHOTOGRAPHER);
4150
return memberRepository.save(member);
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package com.foru.freebe.schedule.controller;
2+
3+
import java.util.List;
4+
5+
import org.springframework.http.HttpStatus;
6+
import org.springframework.http.ResponseEntity;
7+
import org.springframework.security.core.annotation.AuthenticationPrincipal;
8+
import org.springframework.web.bind.annotation.GetMapping;
9+
import org.springframework.web.bind.annotation.PutMapping;
10+
import org.springframework.web.bind.annotation.RequestBody;
11+
import org.springframework.web.bind.annotation.RequestMapping;
12+
import org.springframework.web.bind.annotation.RestController;
13+
14+
import com.foru.freebe.auth.model.MemberAdapter;
15+
import com.foru.freebe.schedule.dto.BaseScheduleDto;
16+
import com.foru.freebe.schedule.dto.ScheduleUnitDto;
17+
import com.foru.freebe.schedule.service.BaseScheduleService;
18+
import com.foru.freebe.common.dto.ResponseBody;
19+
import com.foru.freebe.member.entity.Member;
20+
21+
import jakarta.validation.Valid;
22+
import lombok.RequiredArgsConstructor;
23+
24+
@RestController
25+
@RequiredArgsConstructor
26+
@RequestMapping("/photographer")
27+
public class BaseScheduleController {
28+
29+
private final BaseScheduleService baseScheduleService;
30+
31+
@GetMapping("/schedule/base")
32+
public ResponseEntity<ResponseBody<List<BaseScheduleDto>>> getBaseSchedules(
33+
@AuthenticationPrincipal MemberAdapter memberAdapter) {
34+
Member photographer = memberAdapter.getMember();
35+
List<BaseScheduleDto> responseData = baseScheduleService.getBaseSchedules(photographer.getId());
36+
37+
ResponseBody<List<BaseScheduleDto>> responseBody = ResponseBody
38+
.<List<BaseScheduleDto>>builder()
39+
.message("Successfully retrieve basic schedules.")
40+
.data(responseData)
41+
.build();
42+
43+
return ResponseEntity.status(HttpStatus.OK.value())
44+
.body(responseBody);
45+
}
46+
47+
@PutMapping("/schedule/base")
48+
public ResponseEntity<ResponseBody<Void>> updateBaseSchedule(@AuthenticationPrincipal MemberAdapter memberAdapter,
49+
@Valid @RequestBody List<BaseScheduleDto> request) {
50+
51+
Member photographer = memberAdapter.getMember();
52+
baseScheduleService.updateBaseSchedule(request, photographer.getId());
53+
54+
ResponseBody<Void> responseBody = ResponseBody.<Void>builder()
55+
.message("Basic schedule successfully changed")
56+
.data(null)
57+
.build();
58+
59+
return ResponseEntity.status(HttpStatus.OK.value())
60+
.body(responseBody);
61+
}
62+
63+
@GetMapping("/schedule/unit")
64+
public ResponseEntity<ResponseBody<ScheduleUnitDto>> getScheduleUnit(
65+
@AuthenticationPrincipal MemberAdapter memberAdapter) {
66+
67+
Member photographer = memberAdapter.getMember();
68+
ScheduleUnitDto responseData = baseScheduleService.getScheduleUnit(photographer.getId());
69+
70+
ResponseBody<ScheduleUnitDto> responseBody = ResponseBody
71+
.<ScheduleUnitDto>builder()
72+
.message("Successfully retrieve schedule unit.")
73+
.data(responseData)
74+
.build();
75+
76+
return ResponseEntity.status(HttpStatus.OK.value())
77+
.body(responseBody);
78+
}
79+
80+
81+
@PutMapping("/schedule/unit")
82+
public ResponseEntity<ResponseBody<Void>> updateScheduleUnit(@Valid @RequestBody ScheduleUnitDto request, @AuthenticationPrincipal MemberAdapter memberAdapter) {
83+
84+
Member photographer = memberAdapter.getMember();
85+
baseScheduleService.updateScheduleUnit(photographer.getId(), request);
86+
87+
ResponseBody<Void> responseBody = ResponseBody.<Void>builder()
88+
.message("Schedule Unit successfully changed")
89+
.data(null)
90+
.build();
91+
92+
return ResponseEntity.status(HttpStatus.OK.value())
93+
.body(responseBody);
94+
}
95+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.foru.freebe.schedule.dto;
2+
3+
import java.time.LocalTime;
4+
5+
import com.foru.freebe.schedule.entity.DayOfWeek;
6+
import com.foru.freebe.schedule.entity.OperationStatus;
7+
8+
import jakarta.validation.constraints.NotNull;
9+
import lombok.Builder;
10+
import lombok.Getter;
11+
import lombok.NoArgsConstructor;
12+
13+
@Getter
14+
@NoArgsConstructor
15+
public class BaseScheduleDto {
16+
17+
@NotNull
18+
private DayOfWeek dayOfWeek;
19+
20+
@NotNull
21+
private LocalTime startTime;
22+
23+
@NotNull
24+
private LocalTime endTime;
25+
26+
@NotNull
27+
private OperationStatus operationStatus;
28+
29+
@Builder
30+
public BaseScheduleDto(DayOfWeek dayOfWeek, LocalTime startTime, LocalTime endTime,
31+
OperationStatus operationStatus) {
32+
this.dayOfWeek = dayOfWeek;
33+
this.startTime = startTime;
34+
this.endTime = endTime;
35+
this.operationStatus = operationStatus;
36+
}
37+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.foru.freebe.schedule.dto;
2+
3+
import com.foru.freebe.member.entity.ScheduleUnit;
4+
5+
import jakarta.validation.constraints.NotNull;
6+
import lombok.Getter;
7+
import lombok.NoArgsConstructor;
8+
9+
@Getter
10+
@NoArgsConstructor
11+
public class ScheduleUnitDto {
12+
13+
@NotNull
14+
ScheduleUnit scheduleUnit;
15+
16+
public ScheduleUnitDto(ScheduleUnit scheduleUnit) {
17+
this.scheduleUnit = scheduleUnit;
18+
}
19+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.foru.freebe.schedule.entity;
2+
3+
4+
import java.time.LocalTime;
5+
6+
import com.foru.freebe.common.entity.BaseEntity;
7+
import com.foru.freebe.member.entity.Member;
8+
9+
import jakarta.persistence.Column;
10+
import jakarta.persistence.Entity;
11+
import jakarta.persistence.EnumType;
12+
import jakarta.persistence.Enumerated;
13+
import jakarta.persistence.FetchType;
14+
import jakarta.persistence.GeneratedValue;
15+
import jakarta.persistence.GenerationType;
16+
import jakarta.persistence.Id;
17+
import jakarta.persistence.JoinColumn;
18+
import jakarta.persistence.ManyToOne;
19+
import jakarta.validation.constraints.NotNull;
20+
import lombok.AccessLevel;
21+
import lombok.Builder;
22+
import lombok.Getter;
23+
import lombok.NoArgsConstructor;
24+
25+
@Getter
26+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
27+
@Entity
28+
public class BaseSchedule extends BaseEntity {
29+
@Id
30+
@GeneratedValue(strategy = GenerationType.IDENTITY)
31+
@Column(name = "base_schedule_id")
32+
private Long id;
33+
34+
@ManyToOne(fetch = FetchType.LAZY)
35+
@JoinColumn(name = "photographer_id")
36+
@NotNull(message = "Photographer must not be null")
37+
private Member photographer;
38+
39+
@NotNull(message = "DayOfWeek must not be null")
40+
@Enumerated(EnumType.STRING)
41+
private DayOfWeek dayOfWeek;
42+
43+
@NotNull(message = "Start time must not be null")
44+
private LocalTime startTime;
45+
46+
@NotNull(message = "End time must not be null")
47+
private LocalTime endTime;
48+
49+
@NotNull(message = "Operation status must not be null")
50+
@Enumerated(EnumType.STRING)
51+
private OperationStatus operationStatus;
52+
53+
public void updateScheduleTime(LocalTime startTime, LocalTime endTime, OperationStatus operationStatus) {
54+
if (operationStatus == OperationStatus.INACTIVE) {
55+
this.startTime = LocalTime.of(9,0,0);
56+
this.endTime = LocalTime.of(18,0,0);
57+
} else {
58+
this.startTime = startTime;
59+
this.endTime = endTime;
60+
}
61+
this.operationStatus = operationStatus;
62+
}
63+
64+
public void initializeSchedule() {
65+
this.startTime = LocalTime.of(9,0,0);
66+
this.endTime = LocalTime.of(18,0,0);
67+
this.operationStatus = OperationStatus.ACTIVE;
68+
}
69+
70+
@Builder
71+
public BaseSchedule(Member photographer, DayOfWeek dayOfWeek, LocalTime startTime, LocalTime endTime,
72+
OperationStatus operationStatus) {
73+
this.photographer = photographer;
74+
this.dayOfWeek = dayOfWeek;
75+
this.startTime = startTime;
76+
this.endTime = endTime;
77+
this.operationStatus = operationStatus;
78+
}
79+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.foru.freebe.schedule.entity;
2+
3+
public enum DayOfWeek {
4+
5+
MONDAY,
6+
TUESDAY,
7+
WEDNESDAY,
8+
THURSDAY,
9+
FRIDAY,
10+
SATURDAY,
11+
SUNDAY;
12+
}

0 commit comments

Comments
 (0)