From 4b3f96c6cf561ef00b76e27bc3b131aa9ce38ddf Mon Sep 17 00:00:00 2001 From: ONE ZIN <80401705+kim-wonjin@users.noreply.github.com> Date: Sat, 11 Feb 2023 00:19:09 +0900 Subject: [PATCH] =?UTF-8?q?refactor=20:=20=ED=8B=B0=EC=BC=93=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EA=B8=B0=ED=9A=8D=20=EC=88=98=EC=A0=95=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20=20(#339)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(ticketItem) : 티켓타입 기획 수정 * refactor(ticketItem) : 티켓타입 기획 수정 --- .../controller/TicketItemController.java | 2 +- .../dto/request/CreateTicketItemRequest.java | 19 ++++++- .../dto/response/TicketItemResponse.java | 15 ++++- .../ticketItem/mapper/TicketItemMapper.java | 5 +- .../ticket_item/domain/TicketItem.java | 55 ++++++++++++++++--- .../ticket_item/domain/TicketPayType.java | 21 +++++++ .../EmptyAccountNumberException.java | 13 +++++ .../exception/InvalidPartnerException.java | 13 +++++ .../exception/InvalidTicketTypeException.java | 13 +++++ .../exception/TicketItemErrorCode.java | 12 +++- .../service/TicketItemService.java | 5 +- 11 files changed, 152 insertions(+), 21 deletions(-) create mode 100644 DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/domain/TicketPayType.java create mode 100644 DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/EmptyAccountNumberException.java create mode 100644 DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/InvalidPartnerException.java create mode 100644 DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/InvalidTicketTypeException.java diff --git a/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/controller/TicketItemController.java b/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/controller/TicketItemController.java index 3c51d335..c5befd98 100644 --- a/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/controller/TicketItemController.java +++ b/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/controller/TicketItemController.java @@ -32,7 +32,7 @@ public class TicketItemController { @Operation( summary = "특정 이벤트에 속하는 티켓 상품을 생성합니다.", - description = "제휴 되지 않은 회원은 티켓 가격 0으로 강제해 보내주세요!") + description = "두둥티켓은 승인형식만, 유료티켓은 선착순형식만 가능합니다.") @PostMapping public TicketItemResponse createTicketItem( @RequestBody @Valid CreateTicketItemRequest createTicketItemRequest, diff --git a/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/dto/request/CreateTicketItemRequest.java b/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/dto/request/CreateTicketItemRequest.java index 0d8d62ef..ce78efa7 100644 --- a/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/dto/request/CreateTicketItemRequest.java +++ b/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/dto/request/CreateTicketItemRequest.java @@ -2,6 +2,7 @@ import band.gosrock.common.annotation.Enum; +import band.gosrock.domain.domains.ticket_item.domain.TicketPayType; import band.gosrock.domain.domains.ticket_item.domain.TicketType; import io.swagger.v3.oas.annotations.media.Schema; import javax.validation.constraints.NotEmpty; @@ -14,9 +15,9 @@ @RequiredArgsConstructor public class CreateTicketItemRequest { - @Schema(nullable = false, defaultValue = "선착순") - @Enum(message = "선착순, 승인만 허용됩니다") - private TicketType type; + @Schema(nullable = false, defaultValue = "두둥티켓") + @Enum(message = "두둥티켓, 무료티켓, 유료티켓만 허용됩니다") + private TicketPayType payType; @NotEmpty(message = "티켓상품 이름을 입력해주세요") @Schema(nullable = false, example = "일반 티켓") @@ -26,6 +27,10 @@ public class CreateTicketItemRequest { @Schema(nullable = true, example = "일반 입장 티켓입니다.") private String description; + @Nullable + @Schema(nullable = true, example = "신한은행 110-123-1234567") + private String accountNumber; + @NotNull @Schema(defaultValue = "0", nullable = false, example = "4000") private Long price; @@ -34,6 +39,14 @@ public class CreateTicketItemRequest { @Schema(nullable = false, example = "100") private Long supplyCount; + @Schema(nullable = false, defaultValue = "선착순") + @Enum(message = "선착순, 승인만 허용됩니다") + private TicketType approveType; + + @NotNull + @Schema(nullable = false, example = "true") + private Boolean isQuantityPublic; + @NotNull @Schema(nullable = false, example = "1") private Long purchaseLimit; diff --git a/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/dto/response/TicketItemResponse.java b/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/dto/response/TicketItemResponse.java index a85965e9..b1fb0265 100644 --- a/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/dto/response/TicketItemResponse.java +++ b/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/dto/response/TicketItemResponse.java @@ -3,6 +3,7 @@ import band.gosrock.domain.common.vo.Money; import band.gosrock.domain.domains.ticket_item.domain.TicketItem; +import band.gosrock.domain.domains.ticket_item.domain.TicketPayType; import band.gosrock.domain.domains.ticket_item.domain.TicketType; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; @@ -14,6 +15,9 @@ public class TicketItemResponse { @Schema(description = "티켓상품 id") private final Long ticketItemId; + @Schema(description = "티켓 지불 타입") + private final TicketPayType payType; + @Schema(description = "이름") private final String ticketName; @@ -23,8 +27,8 @@ public class TicketItemResponse { @Schema(description = "가격") private final Money price; - @Schema(description = "티켓 타입") - private final TicketType type; + @Schema(description = "티켓 승인 타입") + private final TicketType approveType; @Schema(description = "1인당 구매 제한 매수") private final Long purchaseLimit; @@ -35,17 +39,22 @@ public class TicketItemResponse { @Schema(description = "재고") private final Long quantity; + @Schema(description = "재고공개 여부") + private final Boolean isQuantityPublic; + public static TicketItemResponse from(TicketItem ticketItem) { return TicketItemResponse.builder() .ticketItemId(ticketItem.getId()) + .payType(ticketItem.getPayType()) .ticketName(ticketItem.getName()) .description(ticketItem.getDescription()) .price(ticketItem.getPrice()) - .type(ticketItem.getType()) + .approveType(ticketItem.getType()) .purchaseLimit(ticketItem.getPurchaseLimit()) .supplyCount(ticketItem.getSupplyCount()) .quantity(ticketItem.getQuantity()) + .isQuantityPublic(ticketItem.getIsQuantityPublic()) .build(); } } diff --git a/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/mapper/TicketItemMapper.java b/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/mapper/TicketItemMapper.java index 80beb77a..d90b8bdf 100644 --- a/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/mapper/TicketItemMapper.java +++ b/DuDoong-Api/src/main/java/band/gosrock/api/ticketItem/mapper/TicketItemMapper.java @@ -25,13 +25,16 @@ public class TicketItemMapper { public TicketItem toTicketItem(CreateTicketItemRequest createTicketItemRequest, Event event) { return TicketItem.builder() - .type(createTicketItemRequest.getType()) + .payType(createTicketItemRequest.getPayType()) .name(createTicketItemRequest.getName()) .description(createTicketItemRequest.getDescription()) .price(Money.wons(createTicketItemRequest.getPrice())) .quantity(createTicketItemRequest.getSupplyCount()) .supplyCount(createTicketItemRequest.getSupplyCount()) .purchaseLimit(createTicketItemRequest.getPurchaseLimit()) + .type(createTicketItemRequest.getApproveType()) + .accountNumber(createTicketItemRequest.getAccountNumber()) + .isQuantityPublic(createTicketItemRequest.getIsQuantityPublic()) .isSellable(true) .event(event) .build(); diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/domain/TicketItem.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/domain/TicketItem.java index c2e3dc48..6f6a6603 100644 --- a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/domain/TicketItem.java +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/domain/TicketItem.java @@ -16,6 +16,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import org.hibernate.annotations.ColumnDefault; +import org.springframework.util.StringUtils; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -27,9 +28,9 @@ public class TicketItem extends BaseTimeEntity { @Column(name = "ticket_item_id") private Long id; - // 티켓 타입 + // 티켓 지불 타입 @Enumerated(EnumType.STRING) - private TicketType type; + private TicketPayType payType; // 티켓 이름 private String name; @@ -49,6 +50,16 @@ public class TicketItem extends BaseTimeEntity { // 1인당 구매 매수 제한 private Long purchaseLimit; + // 티켓 승인 타입 + @Enumerated(EnumType.STRING) + private TicketType type; + + // 계좌번호 + private String accountNumber; + + // 재고 공개 여부 + private Boolean isQuantityPublic; + // 판매 가능 여부 private Boolean isSellable; @@ -72,24 +83,30 @@ public class TicketItem extends BaseTimeEntity { @Builder public TicketItem( - TicketType type, + TicketPayType payType, String name, String description, Money price, Long quantity, Long supplyCount, Long purchaseLimit, + TicketType type, + String accountNumber, + Boolean isQuantityPublic, Boolean isSellable, LocalDateTime saleStartAt, LocalDateTime saleEndAt, Event event) { - this.type = type; + this.payType = payType; this.name = name; this.description = description; this.price = price; this.quantity = quantity; this.supplyCount = supplyCount; this.purchaseLimit = purchaseLimit; + this.type = type; + this.accountNumber = accountNumber; + this.isQuantityPublic = isQuantityPublic; this.isSellable = isSellable; this.saleStartAt = saleStartAt; this.saleEndAt = saleEndAt; @@ -132,9 +149,33 @@ public void validateEventId(Long eventId) { } } - public void validateTicketPrice() { - if (!Money.ZERO.equals(this.price)) { - throw InvalidTicketPriceException.EXCEPTION; + public void validateTicketPayType(Boolean isPartner) { + // 두둥티켓은 무조건 승인 + 계좌번호 필요 + if (this.payType.equals(TicketPayType.DUDOONG_TICKET)) { + if (!this.type.equals(TicketType.APPROVAL)) { + throw InvalidTicketTypeException.EXCEPTION; + } + if (StringUtils.isEmpty(this.accountNumber)) { + throw EmptyAccountNumberException.EXCEPTION; + } + } + // 유료티켓은 무조건 선착순 + 제휴 확인 + 1000원 이상 + else if (this.payType.equals(TicketPayType.PRICE_TICKET)) { + if (!this.type.equals(TicketType.FIRST_COME_FIRST_SERVED)) { + throw InvalidTicketTypeException.EXCEPTION; + } + if (!isPartner) { + throw InvalidPartnerException.EXCEPTION; + } + if (this.price.isLessThan(Money.wons(1000))) { + throw InvalidTicketPriceException.EXCEPTION; + } + } + // 무료티켓은 무조건 0원 + else { + if (!this.price.equals(Money.ZERO)) { + throw InvalidTicketPriceException.EXCEPTION; + } } } diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/domain/TicketPayType.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/domain/TicketPayType.java new file mode 100644 index 00000000..f9fafb39 --- /dev/null +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/domain/TicketPayType.java @@ -0,0 +1,21 @@ +package band.gosrock.domain.domains.ticket_item.domain; + + +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum TicketPayType { + // 두둥티켓 + DUDOONG_TICKET("DUDOONG_TICKET", "두둥티켓"), + // 무료티켓 + FREE_TICKET("FREE_TICKET", "무료티켓"), + // 유료티켓 + PRICE_TICKET("PRICE_TICKET", "유료티켓"); + + private String value; + + @JsonValue private String kr; +} diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/EmptyAccountNumberException.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/EmptyAccountNumberException.java new file mode 100644 index 00000000..d46df006 --- /dev/null +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/EmptyAccountNumberException.java @@ -0,0 +1,13 @@ +package band.gosrock.domain.domains.ticket_item.exception; + + +import band.gosrock.common.exception.DuDoongCodeException; + +public class EmptyAccountNumberException extends DuDoongCodeException { + + public static final DuDoongCodeException EXCEPTION = new EmptyAccountNumberException(); + + private EmptyAccountNumberException() { + super(TicketItemErrorCode.EMPTY_ACCOUT_NUMBER); + } +} diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/InvalidPartnerException.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/InvalidPartnerException.java new file mode 100644 index 00000000..b7e47c50 --- /dev/null +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/InvalidPartnerException.java @@ -0,0 +1,13 @@ +package band.gosrock.domain.domains.ticket_item.exception; + + +import band.gosrock.common.exception.DuDoongCodeException; + +public class InvalidPartnerException extends DuDoongCodeException { + + public static final DuDoongCodeException EXCEPTION = new InvalidPartnerException(); + + private InvalidPartnerException() { + super(TicketItemErrorCode.INVALID_PARTNER); + } +} diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/InvalidTicketTypeException.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/InvalidTicketTypeException.java new file mode 100644 index 00000000..2ef283de --- /dev/null +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/InvalidTicketTypeException.java @@ -0,0 +1,13 @@ +package band.gosrock.domain.domains.ticket_item.exception; + + +import band.gosrock.common.exception.DuDoongCodeException; + +public class InvalidTicketTypeException extends DuDoongCodeException { + + public static final DuDoongCodeException EXCEPTION = new InvalidTicketTypeException(); + + private InvalidTicketTypeException() { + super(TicketItemErrorCode.INVALID_TICKET_TYPE); + } +} diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/TicketItemErrorCode.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/TicketItemErrorCode.java index 055d1129..03c43e66 100644 --- a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/TicketItemErrorCode.java +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/exception/TicketItemErrorCode.java @@ -22,8 +22,8 @@ public enum TicketItemErrorCode implements BaseErrorCode { @ExplainError("주문 및 승인 요청 시 티켓 상품 재고보다 많은 양을 주문 시 발생하는 오류입니다.") TICKET_ITEM_QUANTITY_LESS_THAN_ZERO( BAD_REQUEST, "Ticket_Item_400_2", "티켓 아이템 재고가 0보다 작을 수 없습니다."), - @ExplainError("제휴되지 않은 호스트가 티켓 가격을 0이 아닌 값으로 요청했을때 발생하는 오류입니다.") - INVALID_TICKET_PRICE(BAD_REQUEST, "Ticket_Item_400_3", "티켓 가격을 설정할 수 없습니다."), + @ExplainError("설정할수 없는 티켓 가격일때 발생하는 오류입니다.") + INVALID_TICKET_PRICE(BAD_REQUEST, "Ticket_Item_400_3", "설정할 수 없는 티켓 가격입니다."), @ExplainError("예매 취소 및 티켓 취소 요청 시 티켓 상품 공급량보다 많은 양이 반환될 때 발생하는 오류입니다.") TICKET_ITEM_QUANTITY_LARGER_THAN_SUPPLY_COUNT( BAD_REQUEST, "Ticket_Item_400_4", "공급량보다 많은 티켓 아이템 재고가 설정되었습니다."), @@ -43,7 +43,13 @@ public enum TicketItemErrorCode implements BaseErrorCode { @ExplainError("이미 재고가 감소되어 티켓상품 삭제가 불가능할 경우 발생하는 오류입니다.") FORBIDDEN_TICKET_ITEM_DELETE(BAD_REQUEST, "Ticket_Item_400_7", "티켓상품 삭제가 불가능한 상태입니다."), @ExplainError("이미 적용되어 옵션그룹 삭제가 불가능할 경우 발생하는 오류입니다.") - FORBIDDEN_OPTION_GROUP_DELETE(BAD_REQUEST, "Option_Group_400_2", "옵션그룹 삭제가 불가능한 상태입니다."); + FORBIDDEN_OPTION_GROUP_DELETE(BAD_REQUEST, "Option_Group_400_2", "옵션그룹 삭제가 불가능한 상태입니다."), + @ExplainError("두둥티켓 타입에 계좌번호가 입력되지 않았을 경우 발생하는 오류입니다.") + EMPTY_ACCOUT_NUMBER(BAD_REQUEST, "Ticket_Item_400_8", "계좌번호가 필요합니다."), + @ExplainError("티켓 지불방식과 승인방식이 불가능한 조합일때 발생하는 오류입니다.") + INVALID_TICKET_TYPE(BAD_REQUEST, "Ticket_Item_400_9", "잘못된 티켓 승인타입입니다."), + @ExplainError("제휴되지 않은 호스트가 유료티켓 생성을 요청했을때 발생하는 오류입니다.") + INVALID_PARTNER(BAD_REQUEST, "Ticket_Item_400_3", "제휴된 호스트가 아닙니다."); private Integer status; private String code; diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/service/TicketItemService.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/service/TicketItemService.java index b08c2d01..9c870ada 100644 --- a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/service/TicketItemService.java +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/ticket_item/service/TicketItemService.java @@ -18,9 +18,8 @@ public class TicketItemService { @Transactional public TicketItem createTicketItem(TicketItem ticketItem, Boolean isPartner) { - if (!isPartner) { - ticketItem.validateTicketPrice(); - } + + ticketItem.validateTicketPayType(isPartner); return ticketItemAdaptor.save(ticketItem); }