diff --git a/application/src/main/java/br/com/ifsp/tickets/app/ticket/check/CheckTicketUseCase.java b/application/src/main/java/br/com/ifsp/tickets/app/ticket/check/CheckTicketUseCase.java index 55a6dbe..f34f4ff 100644 --- a/application/src/main/java/br/com/ifsp/tickets/app/ticket/check/CheckTicketUseCase.java +++ b/application/src/main/java/br/com/ifsp/tickets/app/ticket/check/CheckTicketUseCase.java @@ -4,13 +4,16 @@ import br.com.ifsp.tickets.domain.event.EventID; import br.com.ifsp.tickets.domain.event.IEventGateway; import br.com.ifsp.tickets.domain.shared.IDomainEventPublisher; -import br.com.ifsp.tickets.domain.shared.event.ConsumeTicketError; -import br.com.ifsp.tickets.domain.shared.exceptions.*; +import br.com.ifsp.tickets.domain.shared.exceptions.DomainException; +import br.com.ifsp.tickets.domain.shared.exceptions.IllegalResourceAccessException; +import br.com.ifsp.tickets.domain.shared.exceptions.NotFoundException; import br.com.ifsp.tickets.domain.ticket.ITicketGateway; import br.com.ifsp.tickets.domain.ticket.Ticket; import br.com.ifsp.tickets.domain.ticket.TicketID; import br.com.ifsp.tickets.domain.user.User; +import java.util.Optional; + public class CheckTicketUseCase implements ICheckTicketUseCase { private final ITicketGateway ticketGateway; private final IEventGateway eventGateway; @@ -33,16 +36,11 @@ public void execute(CheckTicketInput anIn) { if ((!user.canManageTickets() || !user.getCompanyID().equals(event.getCompanyID())) && !user.canManageAnyTicket()) throw new IllegalResourceAccessException("You don't have permission to check this ticket"); - DomainException exception = null; - try { - ticket.consume(event); - } catch (TicketConsumeException | TicketExpiredException e) { - ticket.registerEvent(new ConsumeTicketError(ticket, e.getMessage())); - exception = e; - } - ticket.publishDomainEvents(eventPublisher); - if (exception != null) throw exception; + final Optional optionalException = ticket.consume(event); this.ticketGateway.update(ticket); + + ticket.publishDomainEvents(eventPublisher); + if (optionalException.isPresent()) throw optionalException.get(); } } diff --git a/domain/src/main/java/br/com/ifsp/tickets/domain/shared/exceptions/TicketConsumeException.java b/domain/src/main/java/br/com/ifsp/tickets/domain/shared/exceptions/TicketConsumeException.java index f8d0e66..a561b9d 100644 --- a/domain/src/main/java/br/com/ifsp/tickets/domain/shared/exceptions/TicketConsumeException.java +++ b/domain/src/main/java/br/com/ifsp/tickets/domain/shared/exceptions/TicketConsumeException.java @@ -1,6 +1,6 @@ package br.com.ifsp.tickets.domain.shared.exceptions; -public class TicketConsumeException extends DomainException{ +public class TicketConsumeException extends DomainException { public TicketConsumeException(String aMessage) { super(aMessage); diff --git a/domain/src/main/java/br/com/ifsp/tickets/domain/shared/exceptions/TicketExpiredException.java b/domain/src/main/java/br/com/ifsp/tickets/domain/shared/exceptions/TicketExpiredException.java deleted file mode 100644 index 81bf200..0000000 --- a/domain/src/main/java/br/com/ifsp/tickets/domain/shared/exceptions/TicketExpiredException.java +++ /dev/null @@ -1,11 +0,0 @@ -package br.com.ifsp.tickets.domain.shared.exceptions; - -import br.com.ifsp.tickets.domain.ticket.TicketID; - -public class TicketExpiredException extends DomainException { - - public TicketExpiredException(TicketID ticketID) { - super("Ticket " + ticketID.getValue() + " is expired"); - } - -} diff --git a/domain/src/main/java/br/com/ifsp/tickets/domain/ticket/Ticket.java b/domain/src/main/java/br/com/ifsp/tickets/domain/ticket/Ticket.java index 48717bd..f14106e 100644 --- a/domain/src/main/java/br/com/ifsp/tickets/domain/ticket/Ticket.java +++ b/domain/src/main/java/br/com/ifsp/tickets/domain/ticket/Ticket.java @@ -5,10 +5,11 @@ import br.com.ifsp.tickets.domain.event.sale.TicketSale; import br.com.ifsp.tickets.domain.event.sale.TicketSaleID; import br.com.ifsp.tickets.domain.shared.Entity; +import br.com.ifsp.tickets.domain.shared.event.ConsumeTicketError; import br.com.ifsp.tickets.domain.shared.event.ConsumeTicketSuccess; import br.com.ifsp.tickets.domain.shared.exceptions.ChangeTicketStatusException; +import br.com.ifsp.tickets.domain.shared.exceptions.DomainException; import br.com.ifsp.tickets.domain.shared.exceptions.TicketConsumeException; -import br.com.ifsp.tickets.domain.shared.exceptions.TicketExpiredException; import br.com.ifsp.tickets.domain.shared.validation.IValidationHandler; import br.com.ifsp.tickets.domain.ticket.vo.TicketCode; import br.com.ifsp.tickets.domain.user.UserID; @@ -73,35 +74,58 @@ private boolean expire() { } else return false; } + public boolean isValidToConsume() { + final LocalDateTime now = LocalDateTime.now(); + return !now.toLocalDate().isBefore(this.validIn); + } + public void cancel() { if (this.status.isCanceled()) throw new ChangeTicketStatusException("Ticket is already canceled"); this.status = TicketStatus.CANCELED; } - public void consume(Event event) { - if (!event.getStatus().isOpened() && !event.getStatus().isInProgress()) - throw new TicketConsumeException("Event is not open and is not in progress"); - if (!event.getId().equals(this.eventID)) - throw new TicketConsumeException("Ticket does not belong to this event"); - if (this.status.isCanceled()) - throw new TicketConsumeException("Ticket is canceled"); - if (this.status.isConsumed()) - throw new TicketConsumeException("Ticket is already consumed"); - if (this.status.isExpired() || this.expire()) - throw new TicketExpiredException(this.getId()); - - final LocalDateTime now = LocalDateTime.now(); - - if (now.toLocalDate().isBefore(this.validIn)) - throw new TicketConsumeException("Ticket is not valid yet"); - - if (now.toLocalDate().isAfter(this.expiredIn)) - throw new TicketExpiredException(this.getId()); + public Optional consume(Event event) { + if (!event.getStatus().isOpened() && !event.getStatus().isInProgress()) { + final TicketConsumeException exception = new TicketConsumeException("Event is not open and is not in progress"); + this.registerEvent(new ConsumeTicketError(this, exception.getMessage())); + return Optional.of(exception); + } + + if (!event.getId().equals(this.eventID)) { + final TicketConsumeException exception = new TicketConsumeException("Ticket does not belong to this event"); + this.registerEvent(new ConsumeTicketError(this, exception.getMessage())); + return Optional.of(exception); + } + + if (this.status.isCanceled()) { + final TicketConsumeException exception = new TicketConsumeException("Ticket is canceled"); + this.registerEvent(new ConsumeTicketError(this, exception.getMessage())); + return Optional.of(exception); + } + + if (this.status.isConsumed()) { + final TicketConsumeException exception = new TicketConsumeException("Ticket is already consumed"); + this.registerEvent(new ConsumeTicketError(this, exception.getMessage())); + return Optional.of(exception); + } + + if (this.status.isExpired() || this.expire()) { + final TicketConsumeException exception = new TicketConsumeException("Ticket is expired"); + this.registerEvent(new ConsumeTicketError(this, exception.getMessage())); + return Optional.of(exception); + } + + if (this.isValidToConsume()) { + final TicketConsumeException exception = new TicketConsumeException("Ticket is not valid yet"); + this.registerEvent(new ConsumeTicketError(this, exception.getMessage())); + return Optional.of(exception); + } this.status = TicketStatus.CONSUMED; - this.lastTimeConsumed = now; + this.lastTimeConsumed = LocalDateTime.now(); this.registerEvent(new ConsumeTicketSuccess(this)); + return Optional.empty(); } @Override diff --git a/infrastructure/src/main/java/br/com/ifsp/tickets/infra/config/AsynchronousSpringEventsConfig.java b/infrastructure/src/main/java/br/com/ifsp/tickets/infra/config/AsynchronousSpringEventsConfig.java new file mode 100644 index 0000000..6de5804 --- /dev/null +++ b/infrastructure/src/main/java/br/com/ifsp/tickets/infra/config/AsynchronousSpringEventsConfig.java @@ -0,0 +1,20 @@ +package br.com.ifsp.tickets.infra.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.event.ApplicationEventMulticaster; +import org.springframework.context.event.SimpleApplicationEventMulticaster; +import org.springframework.core.task.SimpleAsyncTaskExecutor; + +@Configuration +public class AsynchronousSpringEventsConfig { + + @Bean(name = "applicationEventMulticaster") + public ApplicationEventMulticaster simpleApplicationEventMulticaster() { + final SimpleApplicationEventMulticaster eventMulticaster = + new SimpleApplicationEventMulticaster(); + + eventMulticaster.setTaskExecutor(new SimpleAsyncTaskExecutor()); + return eventMulticaster; + } +} diff --git a/infrastructure/src/main/java/br/com/ifsp/tickets/infra/shared/event/DomainEventListener.java b/infrastructure/src/main/java/br/com/ifsp/tickets/infra/shared/event/DomainEventListener.java index a9e2c12..5cd0fc1 100644 --- a/infrastructure/src/main/java/br/com/ifsp/tickets/infra/shared/event/DomainEventListener.java +++ b/infrastructure/src/main/java/br/com/ifsp/tickets/infra/shared/event/DomainEventListener.java @@ -33,4 +33,5 @@ public void onApplicationEvent(@NotNull InfraAppEvent event) { case DEBUG -> log.debug(message); } } + }