Skip to content

Commit

Permalink
feat : 공연 삭제 기능 추가 (#382)
Browse files Browse the repository at this point in the history
* feat : 이벤트 삭제 프로토타입

* feat : 오픈 상태이거나 발급 티켓 있으면 삭제 불가
  • Loading branch information
gengminy authored Feb 20, 2023
1 parent 3013286 commit d2c26fe
Show file tree
Hide file tree
Showing 16 changed files with 120 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public class EventController {
private final UpdateEventBasicUseCase updateEventBasicUseCase;
private final UpdateEventDetailUseCase updateEventDetailUseCase;
private final UpdateEventStatusUseCase updateEventStatusUseCase;
private final OpenEventUseCase openEventStatusUseCase;
private final OpenEventUseCase openEventUseCase;
private final DeleteEventUseCase deleteEventUseCase;

@Operation(summary = "자신이 관리 중인 이벤트 리스트를 가져옵니다.")
@GetMapping
Expand Down Expand Up @@ -83,7 +84,7 @@ public EventResponse updateEventDetail(
@Operation(summary = "공연을 오픈 상태로 변경합니다. 모든 체크리스트를 달성해야 합니다.")
@PatchMapping("/{eventId}/open")
public EventResponse updateEventStatus(@PathVariable Long eventId) {
return openEventStatusUseCase.execute(eventId);
return openEventUseCase.execute(eventId);
}

@Operation(summary = "공연 상태를 변경합니다. (OPEN 제외)")
Expand All @@ -93,4 +94,10 @@ public EventResponse updateEventStatus(
@RequestBody @Valid UpdateEventStatusRequest updateEventDetailRequest) {
return updateEventStatusUseCase.execute(eventId, updateEventDetailRequest);
}

@Operation(summary = "공연을 삭제합니다. 조건에 맞지 않을 경우 삭제할 수 없습니다.")
@PatchMapping("/{eventId}/delete")
public EventResponse deleteEvent(@PathVariable Long eventId) {
return deleteEventUseCase.execute(eventId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package band.gosrock.api.event.service;

import static band.gosrock.api.common.aop.hostRole.FindHostFrom.EVENT_ID;
import static band.gosrock.api.common.aop.hostRole.HostQualification.MANAGER;

import band.gosrock.api.common.aop.hostRole.HostRolesAllowed;
import band.gosrock.api.event.model.dto.response.EventResponse;
import band.gosrock.common.annotation.UseCase;
import band.gosrock.domain.domains.event.adaptor.EventAdaptor;
import band.gosrock.domain.domains.event.domain.Event;
import band.gosrock.domain.domains.event.service.EventService;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

@UseCase
@RequiredArgsConstructor
public class DeleteEventUseCase {
private final EventService eventService;
private final EventAdaptor eventAdaptor;

@Transactional
@HostRolesAllowed(role = MANAGER, findHostFrom = EVENT_ID)
public EventResponse execute(Long eventId) {
final Event event = eventAdaptor.findById(eventId);
return EventResponse.of(eventService.deleteEventSoft(event));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import static band.gosrock.api.common.aop.hostRole.FindHostFrom.EVENT_ID;
import static band.gosrock.api.common.aop.hostRole.HostQualification.MANAGER;

import band.gosrock.api.common.UserUtils;
import band.gosrock.api.common.aop.hostRole.HostRolesAllowed;
import band.gosrock.api.event.model.dto.request.UpdateEventBasicRequest;
import band.gosrock.api.event.model.dto.response.EventResponse;
Expand All @@ -14,15 +13,12 @@
import band.gosrock.domain.domains.event.domain.EventBasic;
import band.gosrock.domain.domains.event.domain.EventPlace;
import band.gosrock.domain.domains.event.service.EventService;
import band.gosrock.domain.domains.host.service.HostService;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

@UseCase
@RequiredArgsConstructor
public class UpdateEventBasicUseCase {
private final UserUtils userUtils;
private final HostService hostService;
private final EventService eventService;
private final EventAdaptor eventAdaptor;
private final EventMapper eventMapper;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import static band.gosrock.api.common.aop.hostRole.FindHostFrom.EVENT_ID;
import static band.gosrock.api.common.aop.hostRole.HostQualification.MANAGER;

import band.gosrock.api.common.UserUtils;
import band.gosrock.api.common.aop.hostRole.HostRolesAllowed;
import band.gosrock.api.event.model.dto.request.UpdateEventStatusRequest;
import band.gosrock.api.event.model.dto.response.EventResponse;
Expand All @@ -12,15 +11,12 @@
import band.gosrock.domain.domains.event.domain.Event;
import band.gosrock.domain.domains.event.domain.EventStatus;
import band.gosrock.domain.domains.event.service.EventService;
import band.gosrock.domain.domains.host.service.HostService;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

@UseCase
@RequiredArgsConstructor
public class UpdateEventStatusUseCase {
private final UserUtils userUtils;
private final HostService hostService;
private final EventService eventService;
private final EventAdaptor eventAdaptor;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

import band.gosrock.domain.common.alarm.EventSlackAlarm;
import band.gosrock.domain.common.events.event.EventDeletionEvent;
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.infrastructure.config.slack.SlackMessageProvider;
Expand All @@ -20,7 +18,6 @@
@Slf4j
public class EventDeletionEventHandler {
private final HostAdaptor hostAdaptor;
private final EventAdaptor eventAdaptor;
private final SlackMessageProvider slackMessageProvider;

@Async
Expand All @@ -29,9 +26,8 @@ public class EventDeletionEventHandler {
phase = TransactionPhase.AFTER_COMMIT)
public void handle(EventDeletionEvent eventDeletionEvent) {
final Host host = hostAdaptor.findById(eventDeletionEvent.getHostId());
final Event event = eventAdaptor.findById(eventDeletionEvent.getEventId());
final String message = EventSlackAlarm.deletionOf(event);

final String eventName = eventDeletionEvent.getEventName();
final String message = EventSlackAlarm.deletionOf(eventName);
slackMessageProvider.sendMessage(host.getSlackUrl(), message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ public static String changeContentOf(Event event) {
return nameOf(event) + "의 내용이 변경되었습니다. 확인해주세요!";
}

public static String deletionOf(Event event) {
return nameOf(event) + "이(가) 삭제되었습니다.";
public static String deletionOf(String eventName) {
return "'" + eventName + "' 공연이 삭제되었습니다.";
}

private static String nameOf(Event event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
@ToString
public class EventDeletionEvent extends DomainEvent {
private final Long hostId;
private final Long eventId;
private final String eventName;

public static EventDeletionEvent of(Event event) {
return EventDeletionEvent.builder()
.hostId(event.getHostId())
.eventId(event.getId())
.eventName(event.getEventBasic().getName())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import band.gosrock.domain.common.aop.domainEvent.Events;
import band.gosrock.domain.common.events.event.EventContentChangeEvent;
import band.gosrock.domain.common.events.event.EventCreationEvent;
import band.gosrock.domain.common.events.event.EventDeletionEvent;
import band.gosrock.domain.common.events.event.EventStatusChangeEvent;
import band.gosrock.domain.common.model.BaseTimeEntity;
import band.gosrock.domain.common.vo.*;
Expand All @@ -16,9 +17,11 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Where;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Where(clause = "status != 'DELETED'")
@Entity(name = "tbl_event")
public class Event extends BaseTimeEntity {
@Id
Expand Down Expand Up @@ -161,4 +164,12 @@ private void updateStatus(EventStatus status, DuDoongCodeException exception) {
this.status = status;
Events.raise(EventStatusChangeEvent.of(this));
}

public void deleteSoft() {
// 오픈된 이벤트는 삭제 불가
if (this.status == OPEN) throw CannotDeleteByOpenEventException.EXCEPTION;
if (this.status == DELETED) throw AlreadyDeletedStatusException.EXCEPTION;
this.status = DELETED;
Events.raise(EventDeletionEvent.of(this));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ public enum EventStatus {
CALCULATING("CALCULATING", "정산중"),

// 지난 공연
CLOSED("CLOSED", "지난공연");
CLOSED("CLOSED", "지난공연"),

// 삭제된 공연
DELETED("DELETED", "삭제된공연");

private final String name;
@JsonValue private final String value;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package band.gosrock.domain.domains.event.exception;


import band.gosrock.common.exception.DuDoongCodeException;

public class AlreadyDeletedStatusException extends DuDoongCodeException {

public static final DuDoongCodeException EXCEPTION = new AlreadyDeletedStatusException();

private AlreadyDeletedStatusException() {
super(EventErrorCode.ALREADY_DELETED_STATUS);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package band.gosrock.domain.domains.event.exception;


import band.gosrock.common.exception.DuDoongCodeException;

public class CannotDeleteByIssuedTicketException extends DuDoongCodeException {

public static final DuDoongCodeException EXCEPTION = new CannotDeleteByIssuedTicketException();

private CannotDeleteByIssuedTicketException() {
super(EventErrorCode.CANNOT_DELETE_BY_ISSUED_TICKET);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package band.gosrock.domain.domains.event.exception;


import band.gosrock.common.exception.DuDoongCodeException;

public class CannotDeleteByOpenEventException extends DuDoongCodeException {

public static final DuDoongCodeException EXCEPTION = new CannotDeleteByOpenEventException();

private CannotDeleteByOpenEventException() {
super(EventErrorCode.CANNOT_DELETE_BY_OPEN_EVENT);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ public enum EventErrorCode implements BaseErrorCode {
ALREADY_CALCULATING_STATUS(BAD_REQUEST, "Event_400_9", "이미 정산중인 이벤트입니다."),
ALREADY_CLOSE_STATUS(BAD_REQUEST, "Event_400_10", "이미 닫은 이벤트입니다."),
ALREADY_PREPARING_STATUS(BAD_REQUEST, "Event_400_11", "이미 준비중인 이벤트입니다."),
ALREADY_DELETED_STATUS(BAD_REQUEST, "Event_400_12", "이미 삭제된 이벤트입니다."),
CANNOT_DELETE_BY_ISSUED_TICKET(BAD_REQUEST, "Event_400_13", "발급 티켓이 있는 이벤트는 삭제할 수 없습니다."),
CANNOT_DELETE_BY_OPEN_EVENT(BAD_REQUEST, "Event_400_14", "오픈 상태인 이벤트는 삭제할 수 없습니다."),

USE_OTHER_API(BAD_REQUEST, "Event_400_8", "잘못된 접근입니다.");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import band.gosrock.common.annotation.DomainService;
import band.gosrock.domain.domains.event.adaptor.EventAdaptor;
import band.gosrock.domain.domains.event.domain.*;
import band.gosrock.domain.domains.event.exception.CannotDeleteByIssuedTicketException;
import band.gosrock.domain.domains.event.exception.CannotOpenEventException;
import band.gosrock.domain.domains.event.exception.UseOtherApiException;
import band.gosrock.domain.domains.event.repository.EventRepository;
import band.gosrock.domain.domains.issuedTicket.adaptor.IssuedTicketAdaptor;
import band.gosrock.domain.domains.ticket_item.service.TicketItemService;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -18,6 +20,7 @@ public class EventService {
private final EventRepository eventRepository;
private final EventAdaptor eventAdaptor;
private final TicketItemService ticketItemService;
private final IssuedTicketAdaptor issuedTicketAdaptor;

public Event createEvent(Event event) {
return eventRepository.save(event);
Expand All @@ -40,15 +43,12 @@ public Event updateEventPlace(Event event, EventPlace eventPlace) {
}

public void validateEventBasicExistence(Event event) {
if (!event.hasEventBasic() || !event.hasEventPlace()) {
if (!event.hasEventBasic() || !event.hasEventPlace())
throw CannotOpenEventException.EXCEPTION;
}
}

public void validateEventDetailExistence(Event event) {
if (!event.hasEventDetail()) {
throw CannotOpenEventException.EXCEPTION;
}
if (!event.hasEventDetail()) throw CannotOpenEventException.EXCEPTION;
}

public Event openEvent(Event event) {
Expand All @@ -60,11 +60,18 @@ public Event openEvent(Event event) {
}

public Event updateEventStatus(Event event, EventStatus status) {
if (status == EventStatus.OPEN) {
throw UseOtherApiException.EXCEPTION; // open 은 다른 API 강제
} else if (status == EventStatus.CLOSED) event.close();
if (status == EventStatus.CLOSED) event.close();
else if (status == EventStatus.CALCULATING) event.calculate();
else if (status == EventStatus.PREPARING) event.prepare();
else throw UseOtherApiException.EXCEPTION; // open, deleteSoft 는 다른 API 강제
return eventRepository.save(event);
}

public Event deleteEventSoft(Event event) {
// 발급된 티켓이 있다면 삭제 불가
if (issuedTicketAdaptor.existsByEventId(event.getId()))
throw CannotDeleteByIssuedTicketException.EXCEPTION;
event.deleteSoft();
return eventRepository.save(event);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ public IssuedTicket queryIssuedTicket(Long issuedTicketId) {
.orElseThrow(() -> IssuedTicketNotFoundException.EXCEPTION);
}

public Boolean existsByEventId(Long eventId) {
return issuedTicketRepository.existsByEventId(eventId);
}

public Page<IssuedTicket> searchIssuedTicket(Long page, IssuedTicketCondition condition) {
PageRequest pageRequest =
PageRequest.of(Math.toIntExact(page), 10, Sort.by("id").descending());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ public interface IssuedTicketRepository
List<IssuedTicket> findAllByOrderUuid(String orderId);

Optional<IssuedTicket> findByIssuedTicketNo(String issuedTicketNo);

Boolean existsByEventId(Long eventId);
}

0 comments on commit d2c26fe

Please sign in to comment.