Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat : 티켓상품 옵션 생성하기 #195

Merged
merged 1 commit into from
Jan 25, 2023
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package band.gosrock.api.ticketItem.controller;


import band.gosrock.api.ticketItem.dto.request.CreateTicketOptionRequest;
import band.gosrock.api.ticketItem.dto.response.CreateTicketOptionResponse;
import band.gosrock.api.ticketItem.service.CreateTicketOptionUseCase;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

@SecurityRequirement(name = "access-token")
@Tag(name = "티켓상품 옵션 관련 컨트롤러")
@RestController
@RequestMapping("/v1/{eventId}/ticketOptions")
@RequiredArgsConstructor
public class TicketOptionController {

private final CreateTicketOptionUseCase createTicketOptionUseCase;

@Operation(summary = "특정 이벤트에 속하는 티켓옵션을 생성합니다.")
@PostMapping
public CreateTicketOptionResponse createTicketOption(
@RequestBody @Valid CreateTicketOptionRequest createTicketOptionRequest,
@PathVariable Long eventId) {
return createTicketOptionUseCase.execute(createTicketOptionRequest, eventId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package band.gosrock.api.ticketItem.dto.request;


import band.gosrock.common.annotation.Enum;
import band.gosrock.domain.domains.ticket_item.domain.OptionGroupType;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.NotNull;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.lang.Nullable;

@Getter
@RequiredArgsConstructor
public class CreateTicketOptionRequest {

@NotNull
@Schema(nullable = false, defaultValue = "Y/N")
@Enum(message = "Y/N, 주관식, 객관식만 허용됩니다")
private OptionGroupType type;

@NotNull
@Schema(nullable = false, example = "뒷풀이 참여 여부")
private String name;
Comment on lines +21 to +23
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"" 같은 빈 문자열도 검증하려면 @NotBlank 쓰는 방법도 좋을 거 같아요!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

동감합니당


@Nullable
@Schema(nullable = true, example = "공연이 끝난 후 오케이포차에서 진행하는 뒷풀이에 참여할 것인가요?")
private String description;

@NotNull
@Schema(nullable = false, example = "10000")
private Long additionalPrice;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package band.gosrock.api.ticketItem.dto.response;


import band.gosrock.domain.domains.ticket_item.domain.OptionGroup;
import band.gosrock.domain.domains.ticket_item.domain.OptionGroupType;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class CreateTicketOptionResponse {
@Schema(description = "옵션그룹 id")
private final Long optionGroupId;

@Schema(description = "티켓 타입")
private final OptionGroupType type;

@Schema(description = "이름")
private final String name;

@Schema(description = "설명")
private final String description;

private final List<OptionResponse> options;

public static CreateTicketOptionResponse from(OptionGroup optionGroup) {

return CreateTicketOptionResponse.builder()
.optionGroupId(optionGroup.getId())
.type(optionGroup.getType())
.name(optionGroup.getName())
.description(optionGroup.getDescription())
.options(optionGroup.getOptions().stream().map(OptionResponse::from).toList())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package band.gosrock.api.ticketItem.dto.response;


import band.gosrock.domain.common.vo.Money;
import band.gosrock.domain.domains.ticket_item.domain.Option;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class OptionResponse {
@Schema(description = "옵션 id")
private final Long optionId;

@Schema(description = "응답")
private final String answer;

@Schema(description = "추가 금액")
private final Money additionalPrice;

public static OptionResponse from(Option option) {

return OptionResponse.builder()
.optionId(option.getId())
.answer(option.getAnswer())
.additionalPrice(option.getAdditionalPrice())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package band.gosrock.api.ticketItem.mapper;

public class TicketItemMapper {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package band.gosrock.api.ticketItem.mapper;


import band.gosrock.api.ticketItem.dto.request.CreateTicketOptionRequest;
import band.gosrock.common.annotation.Mapper;
import band.gosrock.domain.domains.event.domain.Event;
import band.gosrock.domain.domains.ticket_item.domain.OptionGroup;
import java.util.ArrayList;
import lombok.RequiredArgsConstructor;

@Mapper
@RequiredArgsConstructor
public class TicketOptionMapper {

public OptionGroup toOptionGroup(
CreateTicketOptionRequest createTicketOptionRequest, Event event) {
return OptionGroup.builder()
.event(event)
.type(createTicketOptionRequest.getType())
.name(createTicketOptionRequest.getName())
.description(createTicketOptionRequest.getDescription())
.isEssential(true)
.options(new ArrayList<>())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package band.gosrock.api.ticketItem.service;


import band.gosrock.api.common.UserUtils;
import band.gosrock.api.ticketItem.dto.request.CreateTicketOptionRequest;
import band.gosrock.api.ticketItem.dto.response.CreateTicketOptionResponse;
import band.gosrock.api.ticketItem.mapper.TicketOptionMapper;
import band.gosrock.common.annotation.UseCase;
import band.gosrock.domain.common.vo.Money;
import band.gosrock.domain.domains.event.adaptor.EventAdaptor;
import band.gosrock.domain.domains.event.domain.Event;
import band.gosrock.domain.domains.host.adaptor.HostAdaptor;
import band.gosrock.domain.domains.host.domain.Host;
import band.gosrock.domain.domains.ticket_item.domain.OptionGroup;
import band.gosrock.domain.domains.ticket_item.service.TicketOptionService;
import band.gosrock.domain.domains.user.domain.User;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

@UseCase
@RequiredArgsConstructor
public class CreateTicketOptionUseCase {

private final UserUtils userUtils;
private final EventAdaptor eventAdaptor;
private final HostAdaptor hostAdaptor;
private final TicketOptionMapper ticketOptionMapper;
private final TicketOptionService ticketOptionService;

@Transactional
public CreateTicketOptionResponse execute(
CreateTicketOptionRequest createTicketOptionRequest, Long eventId) {
User user = userUtils.getCurrentUser();
Event event = eventAdaptor.findById(eventId);

Host host = hostAdaptor.findById(event.getHostId());
// 권한 체크 ( 해당 이벤트의 호스트인지 )
host.hasHostUserId(user.getId());
Comment on lines +36 to +38
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 한 줄로 검증할 수 있게 HostService 에다가 한 번 만들어볼게요

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aop 로 만들수 있으면 좋을것 같긴합니다.
@gengminy

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aop 로 만들수 있으면 좋을것 같긴합니다. @gengminy

만들어주시죠

OptionGroup ticketOption =
ticketOptionMapper
.toOptionGroup(createTicketOptionRequest, event)
.createTicketOption(
Money.wons(createTicketOptionRequest.getAdditionalPrice()));
OptionGroup ticketOptionResult = ticketOptionService.createTicketOption(ticketOption);
return CreateTicketOptionResponse.from(ticketOptionResult);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

import band.gosrock.common.annotation.Adaptor;
import band.gosrock.domain.domains.ticket_item.domain.Option;
import band.gosrock.domain.domains.ticket_item.domain.OptionGroup;
import band.gosrock.domain.domains.ticket_item.exception.OptionNotFoundException;
import band.gosrock.domain.domains.ticket_item.repository.OptionGroupRepository;
import band.gosrock.domain.domains.ticket_item.repository.OptionRepository;
import lombok.RequiredArgsConstructor;

Expand All @@ -12,10 +14,15 @@
public class OptionAdaptor {

private final OptionRepository optionRepository;
private final OptionGroupRepository optionGroupRepository;

public Option queryOption(Long optionId) {
return optionRepository
.findById(optionId)
.orElseThrow(() -> OptionNotFoundException.EXCEPTION);
}

public OptionGroup save(OptionGroup optionGroup) {
return optionGroupRepository.save(optionGroup);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,18 @@ public class Option {
private OptionGroup optionGroup;

@Builder
public Option(String answer, Money additionalPrice) {
public Option(String answer, Money additionalPrice, OptionGroup optionGroup) {
this.answer = answer;
this.additionalPrice = additionalPrice;
this.optionGroup = optionGroup;
}

public static Option create(String answer, Money additionalPrice, OptionGroup optionGroup) {
return Option.builder()
.answer(answer)
.additionalPrice(additionalPrice)
.optionGroup(optionGroup)
.build();
}

public void setOptionGroup(OptionGroup optionGroup) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package band.gosrock.domain.domains.ticket_item.domain;

import static band.gosrock.domain.common.vo.Money.ZERO;
import static band.gosrock.domain.domains.ticket_item.domain.OptionGroupType.*;

import band.gosrock.domain.common.vo.Money;
import band.gosrock.domain.domains.event.domain.Event;
import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -57,4 +60,15 @@ public OptionGroup(
this.options.addAll(options);
options.forEach(option -> option.setOptionGroup(this));
}

public OptionGroup createTicketOption(Money additionalPrice) {
OptionGroupType type = this.getType();
if (type == TRUE_FALSE) {
this.options.add(Option.create("YES", additionalPrice, this));
this.options.add(Option.create("NO", ZERO, this));
} else if (type == SUBJECTIVE) {
this.options.add(Option.create("", ZERO, this));
}
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package band.gosrock.domain.domains.ticket_item.service;


import band.gosrock.common.annotation.DomainService;
import band.gosrock.domain.domains.ticket_item.adaptor.OptionAdaptor;
import band.gosrock.domain.domains.ticket_item.domain.OptionGroup;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

@DomainService
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class TicketOptionService {

private final OptionAdaptor optionAdaptor;

@Transactional
public OptionGroup createTicketOption(OptionGroup optionGroup) {
return optionAdaptor.save(optionGroup);
}
}