From db9b92fa1a2581b16230ca561e069972f118f6c7 Mon Sep 17 00:00:00 2001 From: Alexey Zinchenko Date: Fri, 10 May 2019 00:02:52 +0300 Subject: [PATCH] Added additional validation. Small refactoring. --- .../carrepair/controller/OrderController.java | 29 ++-------------- .../carrepair/service/OrderService.java | 25 +++++++++++++- .../carrepair/validation/OrderValidator.java | 33 +++++++++++++++++++ src/main/resources/messages.properties | 4 +++ src/main/resources/messages_en.properties | 4 +++ src/main/resources/messages_ru.properties | 4 +++ 6 files changed, 72 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/github/prominence/carrepair/validation/OrderValidator.java diff --git a/src/main/java/com/github/prominence/carrepair/controller/OrderController.java b/src/main/java/com/github/prominence/carrepair/controller/OrderController.java index a70888d..911cae4 100644 --- a/src/main/java/com/github/prominence/carrepair/controller/OrderController.java +++ b/src/main/java/com/github/prominence/carrepair/controller/OrderController.java @@ -3,8 +3,6 @@ package com.github.prominence.carrepair.controller; import com.github.prominence.carrepair.enums.OrderStatus; import com.github.prominence.carrepair.model.Order; import com.github.prominence.carrepair.repository.spec.OrderSpecifications; -import com.github.prominence.carrepair.service.ClientService; -import com.github.prominence.carrepair.service.MechanicService; import com.github.prominence.carrepair.service.OrderService; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -14,7 +12,6 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.validation.BindingResult; -import org.springframework.validation.SmartValidator; import org.springframework.web.bind.annotation.*; import java.util.Optional; @@ -24,15 +21,9 @@ import java.util.Optional; public class OrderController { private OrderService orderService; - private ClientService clientService; - private MechanicService mechanicService; - private SmartValidator smartValidator; - public OrderController(OrderService orderService, ClientService clientService, MechanicService mechanicService, SmartValidator smartValidator) { + public OrderController(OrderService orderService) { this.orderService = orderService; - this.clientService = clientService; - this.mechanicService = mechanicService; - this.smartValidator = smartValidator; } @GetMapping @@ -50,8 +41,6 @@ public class OrderController { @GetMapping(value = "/create") public String create(Model model) { model.addAttribute("order", new Order()); - model.addAttribute("clientIdsList", clientService.getAllClientIds()); - model.addAttribute("mechanicIdsList", mechanicService.getAllMechanicIds()); model.addAttribute("orderStatuses", OrderStatus.values()); return "order/edit"; @@ -72,13 +61,7 @@ public class OrderController { @PostMapping(value = "/update/{id}") public String update(Order order, BindingResult bindingResult, @PathVariable long id, Long clientId, Long mechanicId, Model model) { - if (clientId != null) { - clientService.findById(clientId).ifPresent(order::setClient); - } - if (mechanicId != null) { - mechanicService.findById(mechanicId).ifPresent(order::setMechanic); - } - smartValidator.validate(order, bindingResult); + orderService.fetchNestedObjectsAndValidate(order, clientId, mechanicId, bindingResult); if (bindingResult.hasErrors()) { order.setId(id); // why should we do this? model.addAttribute("orderStatuses", OrderStatus.values()); @@ -91,13 +74,7 @@ public class OrderController { @PostMapping(value = "/create") public String save(Order order, BindingResult bindingResult, Long clientId, Long mechanicId, Model model) { - if (clientId != null) { - clientService.findById(clientId).ifPresent(order::setClient); - } - if (mechanicId != null) { - mechanicService.findById(mechanicId).ifPresent(order::setMechanic); - } - smartValidator.validate(order, bindingResult); + orderService.fetchNestedObjectsAndValidate(order, clientId, mechanicId, bindingResult); if (bindingResult.hasErrors()) { model.addAttribute("orderStatuses", OrderStatus.values()); return "order/edit"; diff --git a/src/main/java/com/github/prominence/carrepair/service/OrderService.java b/src/main/java/com/github/prominence/carrepair/service/OrderService.java index fb4c50b..5c34468 100644 --- a/src/main/java/com/github/prominence/carrepair/service/OrderService.java +++ b/src/main/java/com/github/prominence/carrepair/service/OrderService.java @@ -2,10 +2,13 @@ package com.github.prominence.carrepair.service; import com.github.prominence.carrepair.model.Order; import com.github.prominence.carrepair.repository.OrderRepository; +import com.github.prominence.carrepair.validation.OrderValidator; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; +import org.springframework.validation.BindingResult; +import org.springframework.validation.SmartValidator; import java.util.Optional; @@ -14,8 +17,17 @@ public class OrderService { private OrderRepository orderRepository; - public OrderService(OrderRepository orderRepository) { + private ClientService clientService; + private MechanicService mechanicService; + private SmartValidator smartValidator; + private OrderValidator orderValidator; + + public OrderService(OrderRepository orderRepository, ClientService clientService, MechanicService mechanicService, SmartValidator smartValidator, OrderValidator orderValidator) { this.orderRepository = orderRepository; + this.clientService = clientService; + this.mechanicService = mechanicService; + this.smartValidator = smartValidator; + this.orderValidator = orderValidator; } public Page findAll(Pageable pageable) { @@ -46,4 +58,15 @@ public class OrderService { public long getOrderCount() { return orderRepository.count(); } + + public void fetchNestedObjectsAndValidate(Order order, Long clientId, Long mechanicId, BindingResult bindingResult) { + if (clientId != null) { + clientService.findById(clientId).ifPresent(order::setClient); + } + if (mechanicId != null) { + mechanicService.findById(mechanicId).ifPresent(order::setMechanic); + } + smartValidator.validate(order, bindingResult); + orderValidator.validate(order, bindingResult); + } } diff --git a/src/main/java/com/github/prominence/carrepair/validation/OrderValidator.java b/src/main/java/com/github/prominence/carrepair/validation/OrderValidator.java new file mode 100644 index 0000000..ab2eb05 --- /dev/null +++ b/src/main/java/com/github/prominence/carrepair/validation/OrderValidator.java @@ -0,0 +1,33 @@ +package com.github.prominence.carrepair.validation; + +import com.github.prominence.carrepair.enums.OrderStatus; +import com.github.prominence.carrepair.model.Order; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; +import org.springframework.validation.Validator; + +import java.time.LocalDateTime; + +@Component +public class OrderValidator implements Validator { + @Override + public boolean supports(Class aClass) { + return Order.class.isAssignableFrom(aClass); + } + + @Override + public void validate(Object o, Errors errors) { + Order order = (Order) o; + LocalDateTime finishedOn = order.getFinishedOn(); + if (finishedOn != null) { + LocalDateTime startedOn = order.getCreatedOn(); + if (startedOn != null && order.getFinishedOn().isBefore(order.getCreatedOn())) { + errors.rejectValue("finishedOn", "error.finishedOn.finishedBeforeStarted"); + } + + if (order.getOrderStatus() != OrderStatus.ACCEPTED) { + errors.rejectValue("finishedOn", "error.finishedOn.incompatibleStatus"); + } + } + } +} diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 1925142..1f94d21 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -39,3 +39,7 @@ common.search.button = Search common.nothingFound.label = Nothing was found. common.deleteConfirmation.label = Are you sure to delete? + +# validation +error.finishedOn.finishedBeforeStarted = value must be after starting date +error.finishedOn.incompatibleStatus = order cannot be finished until it isn't accepted by client diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 1925142..1f94d21 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -39,3 +39,7 @@ common.search.button = Search common.nothingFound.label = Nothing was found. common.deleteConfirmation.label = Are you sure to delete? + +# validation +error.finishedOn.finishedBeforeStarted = value must be after starting date +error.finishedOn.incompatibleStatus = order cannot be finished until it isn't accepted by client diff --git a/src/main/resources/messages_ru.properties b/src/main/resources/messages_ru.properties index 280a42e..3abf531 100644 --- a/src/main/resources/messages_ru.properties +++ b/src/main/resources/messages_ru.properties @@ -39,3 +39,7 @@ common.search.button = Поиск common.nothingFound.label = Ничего не найдено. common.deleteConfirmation.label = Вы действительно хотите удалить? + +# validation +error.finishedOn.finishedBeforeStarted = дата окончания должна быть после даты начала +error.finishedOn.incompatibleStatus = заказ не может быть закончен если клиент еще не принял его