diff --git a/src/main/java/com/t3t/bookstoreapi/member/controller/MemberGradePolicyController.java b/src/main/java/com/t3t/bookstoreapi/member/controller/MemberGradePolicyController.java new file mode 100644 index 00000000..5e2b87ca --- /dev/null +++ b/src/main/java/com/t3t/bookstoreapi/member/controller/MemberGradePolicyController.java @@ -0,0 +1,92 @@ +package com.t3t.bookstoreapi.member.controller; + +import com.t3t.bookstoreapi.member.model.dto.MemberGradePolicyDto; +import com.t3t.bookstoreapi.member.model.request.CreateMemberGradePolicyRequest; +import com.t3t.bookstoreapi.member.service.MemberGradePolicyService; +import com.t3t.bookstoreapi.model.response.BaseResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 회원 등급 정책에 관한 HTTP 요청을 처리하는 컨트롤러 + */ +@RestController +@RequiredArgsConstructor +public class MemberGradePolicyController { + private final MemberGradePolicyService memberGradePolicyService; + + /** + * 모든 회원 등급 정책 조회 + * @return 회원 등급 정책 목록을 포함한 BaseResponse 객체 반환 + * + * @author hydrationn(박수화) + */ + @GetMapping("/policy") + public ResponseEntity>> getMemberGradePolicyList() { + List memberGradePolicyDtoList = memberGradePolicyService.getMemberGradePolicyList(); + return ResponseEntity.ok(new BaseResponse>().data(memberGradePolicyDtoList)); + } + + /** + * 특정 ID를 기반으로 한 회원 등급 정책 조회 + * @param policyId 조회할 회원 등급 정책의 ID + * @return 조회된 회원 등급 정책을 포함한 BaseResponse 객체 반환 + * + * @author hydrationn(박수화) + */ + @GetMapping("/policy") + public ResponseEntity> getMemberGradePolicy(@RequestParam Long policyId) { + MemberGradePolicyDto policy = memberGradePolicyService.getMemberGradePolicy(policyId); + return ResponseEntity.ok(new BaseResponse().data(policy)); + } + + /** + * 새로운 회원 등급 정책 생성 + * @param request 생성할 회원 등급 정책의 정보를 담은 요청 객체 + * @return 생성된 회원 등급 정책을 포함한 BaseResponse 객체 반환 + * + * @author hydrationn(박수화) + */ + @PostMapping("/policy") + public ResponseEntity> createMemberGradePolicy(@RequestBody CreateMemberGradePolicyRequest request) { + MemberGradePolicyDto createdPolicy = memberGradePolicyService.createMemberGradePolicy(request); + return ResponseEntity.ok(new BaseResponse().data(createdPolicy)); + } + + /** + * 기존의 회원 등급 정책 업데이트 + * @param policyId 업데이트할 회원 등급 정책의 ID + * @param startAmount 기준 시작 금액 + * @param endAmount 기준 종료 금액 + * @param rate 포인트 적립 비율 + * @return 업데이트된 회원 등급 정책을 포함한 BaseResponse 객체 반환 + * + * @author hydrationn(박수화) + */ + @PutMapping("/policy/{policyId}") + public ResponseEntity> updateMemberGradePolicy(@PathVariable Long policyId, + @RequestParam BigDecimal startAmount, + @RequestParam BigDecimal endAmount, + @RequestParam int rate) { + MemberGradePolicyDto updatedPolicy = memberGradePolicyService.updateMemberGradePolicy(policyId, startAmount, endAmount, rate); + return ResponseEntity.ok(new BaseResponse().data(updatedPolicy)); + } + + /** + * 특정 ID를 가진 회원 등급 정책 삭제 + * @param policyId 삭제할 회원 등급 정책의 ID + * @return 삭제 성공 메시지를 포함한 BaseResponse 객체 반환 + * + * @author hydrationn(박수화) + */ + @DeleteMapping("/policy/{policyId}") + public ResponseEntity> deleteMemberGradePolicy(@PathVariable Long policyId) { + memberGradePolicyService.deleteMemberGradePolicy(policyId); + return ResponseEntity.status(HttpStatus.NO_CONTENT).body(new BaseResponse().message("해당 회원 등급 정책이 성공적으로 삭제되었습니다.")); + } +} diff --git a/src/main/java/com/t3t/bookstoreapi/member/exception/MemberGradePolicyNotFoundException.java b/src/main/java/com/t3t/bookstoreapi/member/exception/MemberGradePolicyNotFoundException.java new file mode 100644 index 00000000..94be7681 --- /dev/null +++ b/src/main/java/com/t3t/bookstoreapi/member/exception/MemberGradePolicyNotFoundException.java @@ -0,0 +1,17 @@ +package com.t3t.bookstoreapi.member.exception; + +/** + * 존재하지 않는 회원 등급 정책(MemberGradePolicy)에 대해 조회를 시도하는 경우 발생하는 예외 + * + * @author hydrationn(박수화) + */ +public class MemberGradePolicyNotFoundException extends RuntimeException { + private static final String DEFAULT_MESSAGE = "존재하지 않는 회원 등급 정책입니다."; + public MemberGradePolicyNotFoundException() { + super(DEFAULT_MESSAGE); + } + + public MemberGradePolicyNotFoundException(Long forTarget) { + super(String.format("%s (%s)", DEFAULT_MESSAGE, forTarget)); + } +} diff --git a/src/main/java/com/t3t/bookstoreapi/member/model/dto/MemberGradePolicyDto.java b/src/main/java/com/t3t/bookstoreapi/member/model/dto/MemberGradePolicyDto.java new file mode 100644 index 00000000..46932c1e --- /dev/null +++ b/src/main/java/com/t3t/bookstoreapi/member/model/dto/MemberGradePolicyDto.java @@ -0,0 +1,35 @@ +package com.t3t.bookstoreapi.member.model.dto; + +import com.t3t.bookstoreapi.member.model.entity.MemberGradePolicy; + +import lombok.Builder; +import lombok.Data; +import lombok.Getter; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +/** + * 회원 등급 정책 생성 정보를 전송하는 데 사용되는 Data Transfer Object(DTO) + * @author hydrationn(박수화) + */ +@Data +@Getter +@Builder +public class MemberGradePolicyDto { + + @NotNull + private Long policyId; + private BigDecimal startAmount; + private BigDecimal endAmount; + private int rate; + + public static MemberGradePolicyDto of(MemberGradePolicy memberGradePolicy) { + return MemberGradePolicyDto.builder() + .policyId(memberGradePolicy.getPolicyId()) + .startAmount(memberGradePolicy.getStartAmount()) + .endAmount(memberGradePolicy.getEndAmount()) + .rate(memberGradePolicy.getRate()) + .build(); + } +} diff --git a/src/main/java/com/t3t/bookstoreapi/member/model/entity/MemberGrade.java b/src/main/java/com/t3t/bookstoreapi/member/model/entity/MemberGrade.java index 2dd6ebf6..73527720 100644 --- a/src/main/java/com/t3t/bookstoreapi/member/model/entity/MemberGrade.java +++ b/src/main/java/com/t3t/bookstoreapi/member/model/entity/MemberGrade.java @@ -1,5 +1,6 @@ package com.t3t.bookstoreapi.member.model.entity; +import com.t3t.bookstoreapi.membergradepolicies.model.entity.MemberGradePolicy; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/com/t3t/bookstoreapi/member/model/entity/MemberGradePolicy.java b/src/main/java/com/t3t/bookstoreapi/member/model/entity/MemberGradePolicy.java index f9ab0934..6d754f31 100644 --- a/src/main/java/com/t3t/bookstoreapi/member/model/entity/MemberGradePolicy.java +++ b/src/main/java/com/t3t/bookstoreapi/member/model/entity/MemberGradePolicy.java @@ -1,13 +1,17 @@ package com.t3t.bookstoreapi.member.model.entity; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import org.hibernate.annotations.Comment; import javax.persistence.*; import java.math.BigDecimal; + +/** + * 회원 등금 정책 를 관리하는 Entity class + * 회원 등급 정책에 대한 상세한 정보 저장 + * + * @Author hydrationn(박수화) + */ @Builder @AllArgsConstructor @NoArgsConstructor @@ -32,4 +36,31 @@ public class MemberGradePolicy { @Column(name = "point_rate", nullable = false) @Comment("포인트 적립 비율") private int rate; + + /** + * 회원 등급 정책 변경에 따른 기준 시작 금액 업데이트 처리 + * @param updateStartAmount + * @author hydrationn(박수화) + */ + public void updateStartAmount(BigDecimal updateStartAmount) { + this.startAmount = updateStartAmount; + } + + /** + * 회원 등급 정책 변경에 따른 기준 종료 금액 업데이트 처리 + * @param updateEndAmount + * @author hydrationn(박수화) + */ + public void updateEndAmount(BigDecimal updateEndAmount) { + this.endAmount = updateEndAmount; + } + + /** + * 회원 등급 정책 변경에 따른 포인트 적립 비율 업데이트 처리 + * @param updateRate + * @author hydrationn(박수화) + */ + public void updateRate(int updateRate) { + this.rate = updateRate; + } } diff --git a/src/main/java/com/t3t/bookstoreapi/member/model/request/CreateMemberGradePolicyRequest.java b/src/main/java/com/t3t/bookstoreapi/member/model/request/CreateMemberGradePolicyRequest.java new file mode 100644 index 00000000..230b8b7e --- /dev/null +++ b/src/main/java/com/t3t/bookstoreapi/member/model/request/CreateMemberGradePolicyRequest.java @@ -0,0 +1,22 @@ +package com.t3t.bookstoreapi.member.model.request; + +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 회원 등급 정책 정보 생성을 위한 요청 데이터 모델 + * 관리자가 정책에 대한 상세 정보를 생성할 때 필요한 정보를 전달하는 데 사용 + * + * @author hydrationn(박수화) + */ +@Data +@AllArgsConstructor +public class CreateMemberGradePolicyRequest { + + private BigDecimal startAmount; + private BigDecimal endAmount; + private int rate; + +} diff --git a/src/main/java/com/t3t/bookstoreapi/member/service/MemberGradePolicyService.java b/src/main/java/com/t3t/bookstoreapi/member/service/MemberGradePolicyService.java new file mode 100644 index 00000000..5f8be7e1 --- /dev/null +++ b/src/main/java/com/t3t/bookstoreapi/member/service/MemberGradePolicyService.java @@ -0,0 +1,105 @@ +package com.t3t.bookstoreapi.member.service; + +import com.t3t.bookstoreapi.member.exception.MemberGradePolicyNotFoundException; +import com.t3t.bookstoreapi.member.model.dto.MemberGradePolicyDto; +import com.t3t.bookstoreapi.member.model.entity.MemberGradePolicy; +import com.t3t.bookstoreapi.member.model.request.CreateMemberGradePolicyRequest; +import com.t3t.bookstoreapi.member.repository.MemberGradePolicyRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 회원 등급 정책을 관리하는 서비스. + * 회원 등급 정책의 생성, 조회, 수정, 삭제 기능 제공 + */ +@Service +@Transactional +@RequiredArgsConstructor +public class MemberGradePolicyService { + private final MemberGradePolicyRepository memberGradePolicyRepository; + + /** + * 모든 회원 등급 정책 조회 + * @return 등록된 모든 회원 등급 정책의 리스트 반환 + * + * @author hydrationn(박수화) + */ + @Transactional(readOnly = true) + public List getMemberGradePolicyList() { + List policies = memberGradePolicyRepository.findAll(); + return policies.stream() + .map(MemberGradePolicyDto::of) + .collect(Collectors.toList()); + } + + /** + * 특정 ID를 가진 회원 등급 정책 조회 + * @param policyId 조회할 회원 등급 정책 ID + * @return 조회된 회원 등급 정책 DTO + * @throws MemberGradePolicyNotFoundException 해당 ID의 정책을 찾을 수 없을 경우 예외 발생 + * + * @author hydrationn(박수화) + */ + @Transactional(readOnly = true) + public MemberGradePolicyDto getMemberGradePolicy(Long policyId) { + MemberGradePolicy policy = memberGradePolicyRepository.findById(policyId) + .orElseThrow(() -> new MemberGradePolicyNotFoundException(policyId)); + + return MemberGradePolicyDto.of(policy); + } + + /** + * 새로운 회원 등급 정책 생성 + * @param request 회원 등급 정책 생성 요청 정보 + * @return 생성된 회원 등급 정책의 DTO + * + * @author hydrationn(박수화) + */ + public MemberGradePolicyDto createMemberGradePolicy(CreateMemberGradePolicyRequest request) { + MemberGradePolicy newMemberGradePolicy = MemberGradePolicy.builder() + .startAmount(request.getStartAmount()) + .endAmount(request.getEndAmount()) + .rate(request.getRate()) + .build(); + + return MemberGradePolicyDto.of(memberGradePolicyRepository.save(newMemberGradePolicy)); + } + + /** + * 기존의 회원 등급 정책 수정 + * + * @param policyId 수정할 회원 등급 정책의 ID + * @param startAmount 기준 시작 금액 + * @param endAmount 기준 종료 금액 + * @param rate 포인트 적립 비율 + * @return 수정된 회원 등급 정책의 DTO + * @throws MemberGradePolicyNotFoundException 해당 ID의 정책을 찾을 수 없을 경우 예외 발생 + */ + public MemberGradePolicyDto updateMemberGradePolicy(Long policyId, BigDecimal startAmount, BigDecimal endAmount, int rate) { + MemberGradePolicy policy = memberGradePolicyRepository.findById(policyId) + .orElseThrow(() -> new MemberGradePolicyNotFoundException(policyId)); + + policy.updateStartAmount(startAmount); + policy.updateEndAmount(endAmount); + policy.updateRate(rate); + + return MemberGradePolicyDto.of(memberGradePolicyRepository.save(policy)); + } + + /** + * 특정 ID를 가진 회원 등급 정책 삭제 + * + * @param policyId 삭제할 회원 등급 정책의 ID + * @throws MemberGradePolicyNotFoundException 해당 ID의 정책을 찾을 수 없을 경우 예외 발생 + */ + public void deleteMemberGradePolicy(Long policyId) { + memberGradePolicyRepository.delete(memberGradePolicyRepository.findById(policyId) + .orElseThrow(() -> new MemberGradePolicyNotFoundException(policyId))); + } + +}