From 1b07e1d3fe3420e922d385e2a2ace976c0513908 Mon Sep 17 00:00:00 2001 From: Alexey Zinchenko Date: Thu, 16 May 2019 00:32:30 +0300 Subject: [PATCH] Validation & UI fixes. --- .../formatter/OrderStatusFormatter.java | 2 +- .../carrepair/model/mapper/OrderMapper.java | 41 +++++++++++++++---- .../carrepair/validation/OrderValidator.java | 39 ++++++++++-------- src/main/resources/messages.properties | 1 + src/main/resources/messages_en.properties | 1 + src/main/resources/messages_ru.properties | 1 + src/main/resources/templates/main.html | 4 +- src/main/resources/templates/order/edit.html | 2 +- 8 files changed, 60 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/github/prominence/carrepair/formatter/OrderStatusFormatter.java b/src/main/java/com/github/prominence/carrepair/formatter/OrderStatusFormatter.java index a99c4ae..43eb233 100644 --- a/src/main/java/com/github/prominence/carrepair/formatter/OrderStatusFormatter.java +++ b/src/main/java/com/github/prominence/carrepair/formatter/OrderStatusFormatter.java @@ -15,7 +15,7 @@ public class OrderStatusFormatter implements Formatter { private static final Logger logger = LogManager.getLogger(OrderStatusFormatter.class); @Override - public OrderStatus parse(String text, Locale locale) throws ParseException { + public OrderStatus parse(String text, Locale locale) { final OrderStatus parsedOrderStatus = OrderStatus.valueOf(text.toUpperCase()); logger.trace("Parsing String[{}] to OrderStatus instance: {}.", () -> text, () -> parsedOrderStatus); return parsedOrderStatus; diff --git a/src/main/java/com/github/prominence/carrepair/model/mapper/OrderMapper.java b/src/main/java/com/github/prominence/carrepair/model/mapper/OrderMapper.java index 9e4aeab..fb14c97 100644 --- a/src/main/java/com/github/prominence/carrepair/model/mapper/OrderMapper.java +++ b/src/main/java/com/github/prominence/carrepair/model/mapper/OrderMapper.java @@ -1,17 +1,21 @@ package com.github.prominence.carrepair.model.mapper; +import com.github.prominence.carrepair.enums.OrderStatus; import com.github.prominence.carrepair.formatter.CustomDateTimeFormatter; +import com.github.prominence.carrepair.formatter.OrderStatusFormatter; import com.github.prominence.carrepair.model.domain.Order; import com.github.prominence.carrepair.model.dto.OrderDto; -import org.mapstruct.InheritInverseConfiguration; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; +import org.apache.commons.lang3.StringUtils; +import org.mapstruct.*; +import org.springframework.beans.factory.annotation.Autowired; import java.util.List; -@Mapper(componentModel = "spring") -public interface OrderMapper { +@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR) +public abstract class OrderMapper { + + @Autowired + protected OrderStatusFormatter orderStatusFormatter; @Mappings({ @Mapping(source = "id", target = "id"), @@ -26,10 +30,29 @@ public interface OrderMapper { @Mapping(source = "createdOn", target = "createdOnDate", dateFormat = CustomDateTimeFormatter.DATETIME_PATTERN), @Mapping(source = "finishedOn", target = "finishedOnDate", dateFormat = CustomDateTimeFormatter.DATETIME_PATTERN) }) - OrderDto orderToOrderDto(Order order); + abstract public OrderDto orderToOrderDto(Order order); @InheritInverseConfiguration - Order orderDtoToOrder(OrderDto orderDto); + abstract public Order orderDtoToOrder(OrderDto orderDto); - List ordersToOrderDtoList(List orders); + abstract public List ordersToOrderDtoList(List orders); + + public String orderStatusToString(OrderStatus orderStatus) { + return orderStatusFormatter.print(orderStatus, null); + } + + public OrderStatus stringToOrderStatus(String status) { + return orderStatusFormatter.parse(status, null); + } + + @BeforeMapping + protected void checkForEmptyStrings(OrderDto orderDto) { + if (StringUtils.isEmpty(orderDto.getCreatedOnDate())) { + orderDto.setCreatedOnDate(null); + } + + if (StringUtils.isEmpty(orderDto.getFinishedOnDate())) { + orderDto.setFinishedOnDate(null); + } + } } diff --git a/src/main/java/com/github/prominence/carrepair/validation/OrderValidator.java b/src/main/java/com/github/prominence/carrepair/validation/OrderValidator.java index 41df7b4..d44a599 100644 --- a/src/main/java/com/github/prominence/carrepair/validation/OrderValidator.java +++ b/src/main/java/com/github/prominence/carrepair/validation/OrderValidator.java @@ -4,6 +4,7 @@ import com.github.prominence.carrepair.enums.OrderStatus; import com.github.prominence.carrepair.formatter.CustomDateTimeFormatter; import com.github.prominence.carrepair.formatter.OrderStatusFormatter; import com.github.prominence.carrepair.model.dto.OrderDto; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.context.i18n.LocaleContextHolder; @@ -11,7 +12,6 @@ import org.springframework.stereotype.Component; import org.springframework.validation.Errors; import org.springframework.validation.Validator; -import java.text.ParseException; import java.time.LocalDateTime; import java.util.Locale; @@ -37,25 +37,28 @@ public class OrderValidator implements Validator { OrderDto order = (OrderDto) o; Locale locale = LocaleContextHolder.getLocale(); + OrderStatus orderStatus = orderStatusFormatter.parse(order.getOrderStatus(), locale); - if (order.getFinishedOnDate() != null) { - try { - LocalDateTime finishedOn = customDateTimeFormatter.parse(order.getFinishedOnDate(), locale); - LocalDateTime createdOn = customDateTimeFormatter.parse(order.getCreatedOnDate(), locale); - if (createdOn != null && finishedOn != null && finishedOn.isBefore(createdOn)) { - logger.debug("[{}] validation error: \"finishedOnDate\" value[{}] is before \"createdOn\"[{}].", - () -> order, () -> finishedOn, () -> createdOn); - errors.rejectValue("finishedOnDate", "error.finishedOn.finishedBeforeStarted"); - } + if (StringUtils.isNotBlank(order.getFinishedOnDate())) { + LocalDateTime finishedOn = customDateTimeFormatter.parse(order.getFinishedOnDate(), locale); + LocalDateTime createdOn = customDateTimeFormatter.parse(order.getCreatedOnDate(), locale); + if (createdOn != null && finishedOn != null && finishedOn.isBefore(createdOn)) { + logger.debug("[{}] validation error: \"finishedOnDate\" value[{}] is before \"createdOn\"[{}].", + () -> order, () -> finishedOn, () -> createdOn); + errors.rejectValue("finishedOnDate", "error.finishedOn.finishedBeforeStarted"); + } - OrderStatus orderStatus = orderStatusFormatter.parse(order.getOrderStatus(), locale); - if (finishedOn != null && orderStatus != OrderStatus.ACCEPTED) { - logger.debug("[{}] validation error: \"finishedOn\" cannot be set for order in status differ from {}.", - () -> order, () -> OrderStatus.ACCEPTED); - errors.rejectValue("finishedOnDate", "error.finishedOn.incompatibleStatus"); - } - } catch (ParseException ex) { - logger.debug("Cannot parse: {}", () -> ex); + + if (finishedOn != null && orderStatus != OrderStatus.ACCEPTED) { + logger.debug("[{}] validation error: \"finishedOn\" cannot be set for order in status differ from {}.", + () -> order, () -> OrderStatus.ACCEPTED); + errors.rejectValue("finishedOnDate", "error.finishedOn.incompatibleStatus"); + } + } else { + if (orderStatus == OrderStatus.ACCEPTED) { + logger.debug("[{}] validation error: \"orderStatus\" cannot be set to {} until \"finishedOn\" isn't set.", + () -> order, () -> OrderStatus.ACCEPTED); + errors.rejectValue("orderStatus", "error.orderStatus.acceptedButNotFinished"); } } } diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index f17ad71..1229b2c 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -47,3 +47,4 @@ 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 +error.orderStatus.acceptedButNotFinished = order cannot be accepter until it isn't finished diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index f17ad71..1229b2c 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -47,3 +47,4 @@ 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 +error.orderStatus.acceptedButNotFinished = order cannot be accepter until it isn't finished diff --git a/src/main/resources/messages_ru.properties b/src/main/resources/messages_ru.properties index 08f0638..ed7e141 100644 --- a/src/main/resources/messages_ru.properties +++ b/src/main/resources/messages_ru.properties @@ -47,3 +47,4 @@ common.deleteConfirmation.label = Вы действительно хотите # validation error.finishedOn.finishedBeforeStarted = дата окончания должна быть после даты начала error.finishedOn.incompatibleStatus = заказ не может быть закончен если клиент еще не принял его +error.orderStatus.acceptedButNotFinished = заказ не может быть принят пока он не закончен diff --git a/src/main/resources/templates/main.html b/src/main/resources/templates/main.html index d35df31..a506b78 100644 --- a/src/main/resources/templates/main.html +++ b/src/main/resources/templates/main.html @@ -36,10 +36,10 @@ diff --git a/src/main/resources/templates/order/edit.html b/src/main/resources/templates/order/edit.html index 7477fd9..93614c1 100644 --- a/src/main/resources/templates/order/edit.html +++ b/src/main/resources/templates/order/edit.html @@ -68,7 +68,7 @@