From 150e910a69031691fc2e6d8856916a9a30b6f8cd Mon Sep 17 00:00:00 2001 From: Murilo Kakazu <yuri.kakazu@gmail.com> Date: Sun, 19 May 2024 21:54:16 -0300 Subject: [PATCH] refactor: implement order actions as use cases --- Makefile | 7 +- .../adapters/in/rest/OrderResource.java | 52 +++++---- .../exceptions/ResourceExceptionHandler.java | 14 --- .../application/services/OrderService.java | 19 ---- ...angeOrderProductsAfterSubmitException.java | 17 +++ ...ntSubmitOrderWithoutProductsException.java | 16 +++ .../exceptions/DomainValidationException.java | 15 +++ .../exceptions/InvalidCpfException.java | 16 +++ .../ResourceBadRequestException.java | 6 +- ...erCantChangeOrderAfterSubmitException.java | 16 --- .../services/impl/CustomerServiceImpl.java | 4 +- .../services/impl/OrderServiceImpl.java | 106 ------------------ .../commands/AddProductToOrderCommand.java | 10 -- .../RemoveProductFromOrderCommand.java | 9 -- .../domain/commands/SubmitOrderCommand.java | 8 -- .../order/AddProductToOrderUseCase.java | 47 ++++++++ .../usecases/order/GetOrderUseCase.java | 28 +++++ .../order/RemoveProductFromOrderUseCase.java | 44 ++++++++ .../usecases/order/StartNewOrderUseCase.java | 26 +++++ .../usecases/order/SubmitOrderUseCase.java | 35 ++++++ .../persistence/jpa/entities/OrderEntity.java | 4 + 21 files changed, 289 insertions(+), 210 deletions(-) delete mode 100644 src/main/java/br/com/fiap/grupo30/fastfood/application/services/OrderService.java create mode 100644 src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/CantChangeOrderProductsAfterSubmitException.java create mode 100644 src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/CantSubmitOrderWithoutProductsException.java create mode 100644 src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/DomainValidationException.java create mode 100644 src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/InvalidCpfException.java delete mode 100644 src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/UserCantChangeOrderAfterSubmitException.java delete mode 100644 src/main/java/br/com/fiap/grupo30/fastfood/application/services/impl/OrderServiceImpl.java delete mode 100644 src/main/java/br/com/fiap/grupo30/fastfood/domain/commands/AddProductToOrderCommand.java delete mode 100644 src/main/java/br/com/fiap/grupo30/fastfood/domain/commands/RemoveProductFromOrderCommand.java delete mode 100644 src/main/java/br/com/fiap/grupo30/fastfood/domain/commands/SubmitOrderCommand.java create mode 100644 src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/AddProductToOrderUseCase.java create mode 100644 src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/GetOrderUseCase.java create mode 100644 src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/RemoveProductFromOrderUseCase.java create mode 100644 src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/StartNewOrderUseCase.java create mode 100644 src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/SubmitOrderUseCase.java diff --git a/Makefile b/Makefile index d36ba89..d256ab1 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +.PHONY: test build run debug lint/fix + test: ./gradlew test @@ -8,4 +10,7 @@ run: ./gradlew bootRun debug: - ./gradlew bootRun --debug-jvm \ No newline at end of file + ./gradlew bootRun --debug-jvm + +lint/fix: + ./gradlew spotlessApply \ No newline at end of file diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/adapters/in/rest/OrderResource.java b/src/main/java/br/com/fiap/grupo30/fastfood/adapters/in/rest/OrderResource.java index 24f3632..9a1147b 100644 --- a/src/main/java/br/com/fiap/grupo30/fastfood/adapters/in/rest/OrderResource.java +++ b/src/main/java/br/com/fiap/grupo30/fastfood/adapters/in/rest/OrderResource.java @@ -2,10 +2,11 @@ import br.com.fiap.grupo30.fastfood.application.dto.AddOrderProductRequest; import br.com.fiap.grupo30.fastfood.application.dto.OrderDTO; -import br.com.fiap.grupo30.fastfood.application.services.OrderService; -import br.com.fiap.grupo30.fastfood.domain.commands.AddProductToOrderCommand; -import br.com.fiap.grupo30.fastfood.domain.commands.RemoveProductFromOrderCommand; -import br.com.fiap.grupo30.fastfood.domain.commands.SubmitOrderCommand; +import br.com.fiap.grupo30.fastfood.domain.usecases.order.AddProductToOrderUseCase; +import br.com.fiap.grupo30.fastfood.domain.usecases.order.GetOrderUseCase; +import br.com.fiap.grupo30.fastfood.domain.usecases.order.RemoveProductFromOrderUseCase; +import br.com.fiap.grupo30.fastfood.domain.usecases.order.StartNewOrderUseCase; +import br.com.fiap.grupo30.fastfood.domain.usecases.order.SubmitOrderUseCase; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import java.net.URI; @@ -19,11 +20,24 @@ @Tag(name = "Orders Resource", description = "RESTful API for managing orders.") public class OrderResource { - private final OrderService orderService; + private final StartNewOrderUseCase startNewOrderUseCase; + private final AddProductToOrderUseCase addProductToOrderUseCase; + private final RemoveProductFromOrderUseCase removeProductFromOrderUseCase; + private final GetOrderUseCase getOrderUseCase; + private final SubmitOrderUseCase submitOrderUseCase; @Autowired - public OrderResource(OrderService orderService) { - this.orderService = orderService; + public OrderResource( + StartNewOrderUseCase startNewOrderUseCase, + AddProductToOrderUseCase addProductToOrderUseCase, + RemoveProductFromOrderUseCase removeProductFromOrderUseCase, + GetOrderUseCase getOrderUseCase, + SubmitOrderUseCase submitOrderUseCase) { + this.startNewOrderUseCase = startNewOrderUseCase; + this.addProductToOrderUseCase = addProductToOrderUseCase; + this.removeProductFromOrderUseCase = removeProductFromOrderUseCase; + this.getOrderUseCase = getOrderUseCase; + this.submitOrderUseCase = submitOrderUseCase; } @GetMapping(value = "/{orderId}") @@ -31,7 +45,7 @@ public OrderResource(OrderService orderService) { summary = "Get an order by ID", description = "Retrieve a specific order based on its ID") public ResponseEntity<OrderDTO> findById(@PathVariable Long orderId) { - OrderDTO order = orderService.getOrder(orderId); + OrderDTO order = this.getOrderUseCase.execute(orderId); return ResponseEntity.ok().body(order); } @@ -40,7 +54,7 @@ public ResponseEntity<OrderDTO> findById(@PathVariable Long orderId) { summary = "Create a new order", description = "Create a new order and return the new order's data") public ResponseEntity<OrderDTO> startNewOrder() { - OrderDTO order = orderService.startNewOrder(); + OrderDTO order = this.startNewOrderUseCase.execute(); URI uri = ServletUriComponentsBuilder.fromCurrentRequest() .path("/{orderId}") @@ -53,12 +67,9 @@ public ResponseEntity<OrderDTO> startNewOrder() { @Operation(summary = "Add a product to an order", description = "Adds a product to an order") public ResponseEntity<OrderDTO> addProduct( @PathVariable Long orderId, @RequestBody AddOrderProductRequest request) { - var command = new AddProductToOrderCommand(); - command.setOrderId(orderId); - command.setProductId(request.getProductId()); - command.setProductQuantity(request.getQuantity()); - - OrderDTO order = orderService.addProductToOrder(command); + OrderDTO order = + this.addProductToOrderUseCase.execute( + orderId, request.getProductId(), request.getQuantity()); return ResponseEntity.ok().body(order); } @@ -68,11 +79,7 @@ public ResponseEntity<OrderDTO> addProduct( description = "Removes a product from an order") public ResponseEntity<OrderDTO> removeProduct( @PathVariable Long orderId, @PathVariable Long productId) { - var command = new RemoveProductFromOrderCommand(); - command.setOrderId(orderId); - command.setProductId(productId); - - OrderDTO order = orderService.removeProductFromOrder(command); + OrderDTO order = this.removeProductFromOrderUseCase.execute(orderId, productId); return ResponseEntity.ok().body(order); } @@ -81,10 +88,7 @@ public ResponseEntity<OrderDTO> removeProduct( summary = "Submit an order for preparation", description = "Submits an order for preparation and return the order's data") public ResponseEntity<OrderDTO> submitOrder(@PathVariable Long orderId) { - var command = new SubmitOrderCommand(); - command.setOrderId(orderId); - - OrderDTO order = orderService.submitOrder(command); + OrderDTO order = this.submitOrderUseCase.execute(orderId); return ResponseEntity.ok().body(order); } } diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/adapters/in/rest/exceptions/ResourceExceptionHandler.java b/src/main/java/br/com/fiap/grupo30/fastfood/adapters/in/rest/exceptions/ResourceExceptionHandler.java index 19eae55..14fd3ce 100644 --- a/src/main/java/br/com/fiap/grupo30/fastfood/adapters/in/rest/exceptions/ResourceExceptionHandler.java +++ b/src/main/java/br/com/fiap/grupo30/fastfood/adapters/in/rest/exceptions/ResourceExceptionHandler.java @@ -4,7 +4,6 @@ import br.com.fiap.grupo30.fastfood.application.services.exceptions.ResourceBadRequestException; import br.com.fiap.grupo30.fastfood.application.services.exceptions.ResourceConflictException; import br.com.fiap.grupo30.fastfood.application.services.exceptions.ResourceNotFoundException; -import br.com.fiap.grupo30.fastfood.application.services.exceptions.UserCantChangeOrderAfterSubmitException; import jakarta.servlet.http.HttpServletRequest; import java.time.Instant; import org.springframework.http.HttpStatus; @@ -65,17 +64,4 @@ public ResponseEntity<StandardError> database(DatabaseException e, HttpServletRe err.setPath(request.getRequestURI()); return ResponseEntity.status(status).body(err); } - - @ExceptionHandler(UserCantChangeOrderAfterSubmitException.class) - public ResponseEntity<StandardError> userCantChangeOrderAfterSubmit( - UserCantChangeOrderAfterSubmitException e, HttpServletRequest request) { - HttpStatus status = HttpStatus.BAD_REQUEST; - StandardError err = new StandardError(); - err.setTimestamp(Instant.now()); - err.setStatus(status.value()); - err.setError("UserCantChangeOrderAfterSubmit exception"); - err.setMessage(e.getMessage()); - err.setPath(request.getRequestURI()); - return ResponseEntity.status(status).body(err); - } } diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/application/services/OrderService.java b/src/main/java/br/com/fiap/grupo30/fastfood/application/services/OrderService.java deleted file mode 100644 index d037495..0000000 --- a/src/main/java/br/com/fiap/grupo30/fastfood/application/services/OrderService.java +++ /dev/null @@ -1,19 +0,0 @@ -package br.com.fiap.grupo30.fastfood.application.services; - -import br.com.fiap.grupo30.fastfood.application.dto.OrderDTO; -import br.com.fiap.grupo30.fastfood.domain.commands.AddProductToOrderCommand; -import br.com.fiap.grupo30.fastfood.domain.commands.RemoveProductFromOrderCommand; -import br.com.fiap.grupo30.fastfood.domain.commands.SubmitOrderCommand; - -public interface OrderService { - - public OrderDTO startNewOrder(); - - public OrderDTO addProductToOrder(AddProductToOrderCommand command); - - public OrderDTO removeProductFromOrder(RemoveProductFromOrderCommand command); - - public OrderDTO submitOrder(SubmitOrderCommand command); - - public OrderDTO getOrder(Long orderId); -} diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/CantChangeOrderProductsAfterSubmitException.java b/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/CantChangeOrderProductsAfterSubmitException.java new file mode 100644 index 0000000..1d4434f --- /dev/null +++ b/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/CantChangeOrderProductsAfterSubmitException.java @@ -0,0 +1,17 @@ +package br.com.fiap.grupo30.fastfood.application.services.exceptions; + +import java.io.Serial; + +public class CantChangeOrderProductsAfterSubmitException extends DomainValidationException { + + @Serial private static final long serialVersionUID = 1L; + private static final String MESSAGE = "Can not change products of a submitted order"; + + public CantChangeOrderProductsAfterSubmitException() { + super(MESSAGE); + } + + public CantChangeOrderProductsAfterSubmitException(Throwable exception) { + super(MESSAGE, exception); + } +} diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/CantSubmitOrderWithoutProductsException.java b/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/CantSubmitOrderWithoutProductsException.java new file mode 100644 index 0000000..7b18055 --- /dev/null +++ b/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/CantSubmitOrderWithoutProductsException.java @@ -0,0 +1,16 @@ +package br.com.fiap.grupo30.fastfood.application.services.exceptions; + +import java.io.Serial; + +public class CantSubmitOrderWithoutProductsException extends DomainValidationException { + @Serial private static final long serialVersionUID = 1L; + private static final String MESSAGE = "Can not submit order without products"; + + public CantSubmitOrderWithoutProductsException() { + super(MESSAGE); + } + + public CantSubmitOrderWithoutProductsException(Throwable exception) { + super(MESSAGE, exception); + } +} diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/DomainValidationException.java b/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/DomainValidationException.java new file mode 100644 index 0000000..81ea5ef --- /dev/null +++ b/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/DomainValidationException.java @@ -0,0 +1,15 @@ +package br.com.fiap.grupo30.fastfood.application.services.exceptions; + +import java.io.Serial; + +public abstract class DomainValidationException extends ResourceBadRequestException { + @Serial private static final long serialVersionUID = 1L; + + public DomainValidationException(String msg) { + super(msg); + } + + public DomainValidationException(String msg, Throwable exception) { + super(msg, exception); + } +} diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/InvalidCpfException.java b/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/InvalidCpfException.java new file mode 100644 index 0000000..1c54b2b --- /dev/null +++ b/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/InvalidCpfException.java @@ -0,0 +1,16 @@ +package br.com.fiap.grupo30.fastfood.application.services.exceptions; + +import java.io.Serial; + +public class InvalidCpfException extends DomainValidationException { + @Serial private static final long serialVersionUID = 1L; + private static final String MESSAGE_TEMPLATE = "Invalid CPF: %s"; + + public InvalidCpfException(String cpf) { + super(String.format(MESSAGE_TEMPLATE, cpf)); + } + + public InvalidCpfException(String cpf, Throwable exception) { + super(String.format(MESSAGE_TEMPLATE, cpf), exception); + } +} diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/ResourceBadRequestException.java b/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/ResourceBadRequestException.java index 780999f..1117b05 100644 --- a/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/ResourceBadRequestException.java +++ b/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/ResourceBadRequestException.java @@ -2,10 +2,14 @@ import java.io.Serial; -public class ResourceBadRequestException extends RuntimeException { +public abstract class ResourceBadRequestException extends RuntimeException { @Serial private static final long serialVersionUID = 1L; public ResourceBadRequestException(String msg) { super(msg); } + + public ResourceBadRequestException(String msg, Throwable exception) { + super(msg, exception); + } } diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/UserCantChangeOrderAfterSubmitException.java b/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/UserCantChangeOrderAfterSubmitException.java deleted file mode 100644 index 9d874f4..0000000 --- a/src/main/java/br/com/fiap/grupo30/fastfood/application/services/exceptions/UserCantChangeOrderAfterSubmitException.java +++ /dev/null @@ -1,16 +0,0 @@ -package br.com.fiap.grupo30.fastfood.application.services.exceptions; - -import java.io.Serial; - -public class UserCantChangeOrderAfterSubmitException extends RuntimeException { - - @Serial private static final long serialVersionUID = 1L; - - public UserCantChangeOrderAfterSubmitException(String msg) { - super(msg); - } - - public UserCantChangeOrderAfterSubmitException(String msg, Throwable exception) { - super(msg, exception); - } -} diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/application/services/impl/CustomerServiceImpl.java b/src/main/java/br/com/fiap/grupo30/fastfood/application/services/impl/CustomerServiceImpl.java index 3f7035a..fe37d8f 100644 --- a/src/main/java/br/com/fiap/grupo30/fastfood/application/services/impl/CustomerServiceImpl.java +++ b/src/main/java/br/com/fiap/grupo30/fastfood/application/services/impl/CustomerServiceImpl.java @@ -4,7 +4,7 @@ import br.com.fiap.grupo30.fastfood.application.mapper.impl.CustomerDTOMapper; import br.com.fiap.grupo30.fastfood.application.mapper.impl.CustomerMapper; import br.com.fiap.grupo30.fastfood.application.services.CustomerService; -import br.com.fiap.grupo30.fastfood.application.services.exceptions.ResourceBadRequestException; +import br.com.fiap.grupo30.fastfood.application.services.exceptions.InvalidCpfException; import br.com.fiap.grupo30.fastfood.application.services.exceptions.ResourceConflictException; import br.com.fiap.grupo30.fastfood.application.services.exceptions.ResourceNotFoundException; import br.com.fiap.grupo30.fastfood.domain.vo.CPF; @@ -45,7 +45,7 @@ public CustomerDTO findCustomerByCpf(String cpf) { public CustomerDTO insert(CustomerDTO dto) { String cpfDTO = dto.getCpf(); if (!CPF.isValid(cpfDTO)) { - throw new ResourceBadRequestException("Invalid CPF: " + cpfDTO); + throw new InvalidCpfException(cpfDTO); } try { dto.setCpf(CPF.removeNonDigits(cpfDTO)); diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/application/services/impl/OrderServiceImpl.java b/src/main/java/br/com/fiap/grupo30/fastfood/application/services/impl/OrderServiceImpl.java deleted file mode 100644 index ced289b..0000000 --- a/src/main/java/br/com/fiap/grupo30/fastfood/application/services/impl/OrderServiceImpl.java +++ /dev/null @@ -1,106 +0,0 @@ -package br.com.fiap.grupo30.fastfood.application.services.impl; - -import br.com.fiap.grupo30.fastfood.application.dto.OrderDTO; -import br.com.fiap.grupo30.fastfood.application.services.OrderService; -import br.com.fiap.grupo30.fastfood.application.services.exceptions.ResourceNotFoundException; -import br.com.fiap.grupo30.fastfood.application.services.exceptions.UserCantChangeOrderAfterSubmitException; -import br.com.fiap.grupo30.fastfood.domain.commands.AddProductToOrderCommand; -import br.com.fiap.grupo30.fastfood.domain.commands.RemoveProductFromOrderCommand; -import br.com.fiap.grupo30.fastfood.domain.commands.SubmitOrderCommand; -import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.entities.OrderEntity; -import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.entities.OrderStatus; -import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.entities.ProductEntity; -import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.repositories.OrderRepository; -import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.repositories.ProductRepository; -import jakarta.transaction.Transactional; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class OrderServiceImpl implements OrderService { - - private final String ORDER_NOT_FOUND_MESSAGE = "Order not found"; - - private final OrderRepository orderRepository; - private final ProductRepository productRepository; - - @Autowired - public OrderServiceImpl(OrderRepository orderRepository, ProductRepository productRepository) { - this.orderRepository = orderRepository; - this.productRepository = productRepository; - } - - @Override - @Transactional - public OrderDTO startNewOrder() { - OrderEntity newOrder = OrderEntity.create(); - newOrder = this.orderRepository.save(newOrder); - return newOrder.toDTO(); - } - - @Override - @Transactional - public OrderDTO addProductToOrder(AddProductToOrderCommand command) { - OrderEntity order = - this.orderRepository - .findById(command.getOrderId()) - .orElseThrow(() -> new ResourceNotFoundException(ORDER_NOT_FOUND_MESSAGE)); - - if (!order.isDraft()) { - throw new UserCantChangeOrderAfterSubmitException( - "Can only add products to an order in draft"); - } - - ProductEntity product = - this.productRepository - .findById(command.getProductId()) - .orElseThrow(() -> new ResourceNotFoundException("Product not found")); - - order.addProduct(product, command.getProductQuantity()); - return this.orderRepository.save(order).toDTO(); - } - - @Override - @Transactional - public OrderDTO removeProductFromOrder(RemoveProductFromOrderCommand command) { - OrderEntity order = - this.orderRepository - .findById(command.getOrderId()) - .orElseThrow(() -> new ResourceNotFoundException(ORDER_NOT_FOUND_MESSAGE)); - - if (!order.isDraft()) { - throw new UserCantChangeOrderAfterSubmitException( - "Can only remove products from an order in draft"); - } - - ProductEntity product = - this.productRepository - .findById(command.getProductId()) - .orElseThrow(() -> new ResourceNotFoundException("Product not found")); - - order.removeProduct(product); - return this.orderRepository.save(order).toDTO(); - } - - @Override - @Transactional - public OrderDTO submitOrder(SubmitOrderCommand command) { - OrderEntity order = - this.orderRepository - .findById(command.getOrderId()) - .orElseThrow(() -> new ResourceNotFoundException(ORDER_NOT_FOUND_MESSAGE)); - - order.setStatus(OrderStatus.SUBMITTED); - return this.orderRepository.save(order).toDTO(); - } - - @Override - public OrderDTO getOrder(Long orderId) { - OrderEntity order = - this.orderRepository - .findById(orderId) - .orElseThrow(() -> new ResourceNotFoundException(ORDER_NOT_FOUND_MESSAGE)); - - return order.toDTO(); - } -} diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/domain/commands/AddProductToOrderCommand.java b/src/main/java/br/com/fiap/grupo30/fastfood/domain/commands/AddProductToOrderCommand.java deleted file mode 100644 index 0288bb3..0000000 --- a/src/main/java/br/com/fiap/grupo30/fastfood/domain/commands/AddProductToOrderCommand.java +++ /dev/null @@ -1,10 +0,0 @@ -package br.com.fiap.grupo30.fastfood.domain.commands; - -import lombok.Data; - -@Data -public class AddProductToOrderCommand { - private Long orderId; - private Long productId; - private Long productQuantity; -} diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/domain/commands/RemoveProductFromOrderCommand.java b/src/main/java/br/com/fiap/grupo30/fastfood/domain/commands/RemoveProductFromOrderCommand.java deleted file mode 100644 index a3ff108..0000000 --- a/src/main/java/br/com/fiap/grupo30/fastfood/domain/commands/RemoveProductFromOrderCommand.java +++ /dev/null @@ -1,9 +0,0 @@ -package br.com.fiap.grupo30.fastfood.domain.commands; - -import lombok.Data; - -@Data -public class RemoveProductFromOrderCommand { - private Long orderId; - private Long productId; -} diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/domain/commands/SubmitOrderCommand.java b/src/main/java/br/com/fiap/grupo30/fastfood/domain/commands/SubmitOrderCommand.java deleted file mode 100644 index c1a3765..0000000 --- a/src/main/java/br/com/fiap/grupo30/fastfood/domain/commands/SubmitOrderCommand.java +++ /dev/null @@ -1,8 +0,0 @@ -package br.com.fiap.grupo30.fastfood.domain.commands; - -import lombok.Data; - -@Data -public class SubmitOrderCommand { - private Long orderId; -} diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/AddProductToOrderUseCase.java b/src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/AddProductToOrderUseCase.java new file mode 100644 index 0000000..a196524 --- /dev/null +++ b/src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/AddProductToOrderUseCase.java @@ -0,0 +1,47 @@ +package br.com.fiap.grupo30.fastfood.domain.usecases.order; + +import br.com.fiap.grupo30.fastfood.application.dto.OrderDTO; +import br.com.fiap.grupo30.fastfood.application.services.exceptions.CantChangeOrderProductsAfterSubmitException; +import br.com.fiap.grupo30.fastfood.application.services.exceptions.ResourceNotFoundException; +import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.entities.OrderEntity; +import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.entities.ProductEntity; +import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.repositories.OrderRepository; +import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.repositories.ProductRepository; +import jakarta.transaction.Transactional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class AddProductToOrderUseCase { + + private final OrderRepository orderRepository; + private final ProductRepository productRepository; + + @Autowired + public AddProductToOrderUseCase( + OrderRepository orderRepository, ProductRepository productRepository) { + this.orderRepository = orderRepository; + this.productRepository = productRepository; + } + + @Transactional + public OrderDTO execute(Long orderId, Long productId, Long productQuantity) { + OrderEntity order = + this.orderRepository + .findById(orderId) + .orElseThrow(() -> new ResourceNotFoundException("Order not found")); + + if (!order.isDraft()) { + throw new CantChangeOrderProductsAfterSubmitException(); + } + + ProductEntity product = + this.productRepository + .findById(productId) + .orElseThrow(() -> new ResourceNotFoundException("Product not found")); + + order.addProduct(product, productQuantity); + + return this.orderRepository.save(order).toDTO(); + } +} diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/GetOrderUseCase.java b/src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/GetOrderUseCase.java new file mode 100644 index 0000000..025b1ef --- /dev/null +++ b/src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/GetOrderUseCase.java @@ -0,0 +1,28 @@ +package br.com.fiap.grupo30.fastfood.domain.usecases.order; + +import br.com.fiap.grupo30.fastfood.application.dto.OrderDTO; +import br.com.fiap.grupo30.fastfood.application.services.exceptions.ResourceNotFoundException; +import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.entities.OrderEntity; +import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.repositories.OrderRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class GetOrderUseCase { + + private final OrderRepository orderRepository; + + @Autowired + public GetOrderUseCase(OrderRepository orderRepository) { + this.orderRepository = orderRepository; + } + + public OrderDTO execute(Long orderId) { + OrderEntity order = + this.orderRepository + .findById(orderId) + .orElseThrow(() -> new ResourceNotFoundException("Order not found")); + + return order.toDTO(); + } +} diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/RemoveProductFromOrderUseCase.java b/src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/RemoveProductFromOrderUseCase.java new file mode 100644 index 0000000..019a0f0 --- /dev/null +++ b/src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/RemoveProductFromOrderUseCase.java @@ -0,0 +1,44 @@ +package br.com.fiap.grupo30.fastfood.domain.usecases.order; + +import br.com.fiap.grupo30.fastfood.application.dto.OrderDTO; +import br.com.fiap.grupo30.fastfood.application.services.exceptions.CantChangeOrderProductsAfterSubmitException; +import br.com.fiap.grupo30.fastfood.application.services.exceptions.ResourceNotFoundException; +import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.entities.OrderEntity; +import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.entities.ProductEntity; +import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.repositories.OrderRepository; +import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.repositories.ProductRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class RemoveProductFromOrderUseCase { + + private final OrderRepository orderRepository; + private final ProductRepository productRepository; + + @Autowired + public RemoveProductFromOrderUseCase( + OrderRepository orderRepository, ProductRepository productRepository) { + this.orderRepository = orderRepository; + this.productRepository = productRepository; + } + + public OrderDTO execute(Long orderId, Long productId) { + OrderEntity order = + this.orderRepository + .findById(orderId) + .orElseThrow(() -> new ResourceNotFoundException("Order not found")); + + if (!order.isDraft()) { + throw new CantChangeOrderProductsAfterSubmitException(); + } + + ProductEntity product = + this.productRepository + .findById(productId) + .orElseThrow(() -> new ResourceNotFoundException("Product not found")); + + order.removeProduct(product); + return this.orderRepository.save(order).toDTO(); + } +} diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/StartNewOrderUseCase.java b/src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/StartNewOrderUseCase.java new file mode 100644 index 0000000..9932874 --- /dev/null +++ b/src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/StartNewOrderUseCase.java @@ -0,0 +1,26 @@ +package br.com.fiap.grupo30.fastfood.domain.usecases.order; + +import br.com.fiap.grupo30.fastfood.application.dto.OrderDTO; +import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.entities.OrderEntity; +import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.repositories.OrderRepository; +import jakarta.transaction.Transactional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class StartNewOrderUseCase { + + private final OrderRepository orderRepository; + + @Autowired + public StartNewOrderUseCase(OrderRepository orderRepository) { + this.orderRepository = orderRepository; + } + + @Transactional + public OrderDTO execute() { + OrderEntity newOrder = OrderEntity.create(); + newOrder = this.orderRepository.save(newOrder); + return newOrder.toDTO(); + } +} diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/SubmitOrderUseCase.java b/src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/SubmitOrderUseCase.java new file mode 100644 index 0000000..252e65e --- /dev/null +++ b/src/main/java/br/com/fiap/grupo30/fastfood/domain/usecases/order/SubmitOrderUseCase.java @@ -0,0 +1,35 @@ +package br.com.fiap.grupo30.fastfood.domain.usecases.order; + +import br.com.fiap.grupo30.fastfood.application.dto.OrderDTO; +import br.com.fiap.grupo30.fastfood.application.services.exceptions.CantSubmitOrderWithoutProductsException; +import br.com.fiap.grupo30.fastfood.application.services.exceptions.ResourceNotFoundException; +import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.entities.OrderEntity; +import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.entities.OrderStatus; +import br.com.fiap.grupo30.fastfood.infrastructure.out.persistence.jpa.repositories.OrderRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class SubmitOrderUseCase { + + private final OrderRepository orderRepository; + + @Autowired + public SubmitOrderUseCase(OrderRepository orderRepository) { + this.orderRepository = orderRepository; + } + + public OrderDTO execute(Long orderId) { + OrderEntity order = + this.orderRepository + .findById(orderId) + .orElseThrow(() -> new ResourceNotFoundException("Order not found")); + + if (!order.hasProducts()) { + throw new CantSubmitOrderWithoutProductsException(); + } + + order.setStatus(OrderStatus.SUBMITTED); + return this.orderRepository.save(order).toDTO(); + } +} diff --git a/src/main/java/br/com/fiap/grupo30/fastfood/infrastructure/out/persistence/jpa/entities/OrderEntity.java b/src/main/java/br/com/fiap/grupo30/fastfood/infrastructure/out/persistence/jpa/entities/OrderEntity.java index a66b4d7..d18f785 100644 --- a/src/main/java/br/com/fiap/grupo30/fastfood/infrastructure/out/persistence/jpa/entities/OrderEntity.java +++ b/src/main/java/br/com/fiap/grupo30/fastfood/infrastructure/out/persistence/jpa/entities/OrderEntity.java @@ -71,6 +71,10 @@ public Boolean isDraft() { return OrderStatus.DRAFT.equals(this.status); } + public Boolean hasProducts() { + return !this.items.isEmpty(); + } + public void setStatus(OrderStatus status) { this.status = status; }