mirror of
https://github.com/Prominence/car-repair-site.git
synced 2026-01-09 19:56:43 +03:00
Validation & UI fixes.
This commit is contained in:
parent
af110658b6
commit
1b07e1d3fe
@ -15,7 +15,7 @@ public class OrderStatusFormatter implements Formatter<OrderStatus> {
|
||||
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;
|
||||
|
||||
@ -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<OrderDto> ordersToOrderDtoList(List<Order> orders);
|
||||
abstract public List<OrderDto> ordersToOrderDtoList(List<Order> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -47,3 +47,4 @@ common.deleteConfirmation.label = Вы действительно хотите
|
||||
# validation
|
||||
error.finishedOn.finishedBeforeStarted = дата окончания должна быть после даты начала
|
||||
error.finishedOn.incompatibleStatus = заказ не может быть закончен если клиент еще не принял его
|
||||
error.orderStatus.acceptedButNotFinished = заказ не может быть принят пока он не закончен
|
||||
|
||||
@ -36,10 +36,10 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div class="float-right">
|
||||
<a th:href="@{?lang=en}">
|
||||
<a th:href="@{/?lang=en}">
|
||||
<img th:src="@{/images/us.png}" th:alt="#{lang.en}"/>
|
||||
</a>
|
||||
<a th:href="@{?lang=ru}">
|
||||
<a th:href="@{/?lang=ru}">
|
||||
<img th:src="@{/images/ru.png}" th:alt="#{lang.ru}"/>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@ -68,7 +68,7 @@
|
||||
<label for="orderStatus" class="col-sm-2 col-form-label" th:text="#{status.label}"></label>
|
||||
<div class="col-sm-10">
|
||||
<select name="orderStatus" class="form-control custom-select" id="orderStatus" th:field="*{orderStatus}" th:errorclass="is-invalid" th:value="${orderDto.orderStatus}">
|
||||
<option th:each="orderStatus : ${orderStatuses}" th:value="${orderStatus.toString()}" th:text="${{orderStatus}}"></option>
|
||||
<option th:each="orderStatus : ${orderStatuses}" th:value="${{orderStatus}}" th:text="${{orderStatus}}"></option>
|
||||
</select>
|
||||
<div th:replace="common::errors('orderStatus')"></div>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user