diff --git a/core/src/main/java/greencity/configuration/SecurityConfig.java b/core/src/main/java/greencity/configuration/SecurityConfig.java index 4721adbcc..7ab85619b 100644 --- a/core/src/main/java/greencity/configuration/SecurityConfig.java +++ b/core/src/main/java/greencity/configuration/SecurityConfig.java @@ -144,6 +144,7 @@ protected void configure(HttpSecurity http) throws Exception { SUPER_ADMIN_LINK + "/editService/{id}", SUPER_ADMIN_LINK + "/setTariffLimits/{tariffId}", SUPER_ADMIN_LINK + "/editTariffInfo/{id}", + SUPER_ADMIN_LINK + "/activate-employee/{id}", SUPER_ADMIN_LINK + "/**") .hasAnyRole(ADMIN, UBS_EMPLOYEE) .antMatchers(HttpMethod.DELETE, diff --git a/core/src/main/java/greencity/controller/ManagementEmployeeController.java b/core/src/main/java/greencity/controller/ManagementEmployeeController.java index d64e8b604..d606fbc30 100644 --- a/core/src/main/java/greencity/controller/ManagementEmployeeController.java +++ b/core/src/main/java/greencity/controller/ManagementEmployeeController.java @@ -1,6 +1,5 @@ package greencity.controller; -import greencity.annotations.ApiPageable; import greencity.constants.HttpStatuses; import greencity.constants.SwaggerExampleModel; import greencity.dto.employee.EmployeeWithTariffsIdDto; @@ -8,6 +7,7 @@ import greencity.dto.employee.GetEmployeeDto; import greencity.dto.employee.UserEmployeeAuthorityDto; import greencity.dto.pageble.PageableAdvancedDto; +import greencity.dto.pageble.PageableDto; import greencity.dto.position.PositionAuthoritiesDto; import greencity.dto.position.PositionDto; import greencity.dto.tariff.GetTariffInfoForEmployeeDto; @@ -20,7 +20,6 @@ import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -75,8 +74,9 @@ public ResponseEntity saveEmployee( /** * Controller gets all employees. * - * @return {@link PageableAdvancedDto} pageable employees. + * @return PageableDto of {@link GetEmployeeDto} employees. * @author Mykola Danylko. + * @author Olena Sotnik. */ @ApiOperation(value = "Get all employees") @ApiResponses(value = { @@ -84,10 +84,9 @@ public ResponseEntity saveEmployee( @ApiResponse(code = 401, message = HttpStatuses.UNAUTHORIZED), @ApiResponse(code = 403, message = HttpStatuses.FORBIDDEN) }) - @ApiPageable @PreAuthorize("@preAuthorizer.hasAuthority('SEE_EMPLOYEES_PAGE', authentication)") @GetMapping("/getAll-employees") - public ResponseEntity> getAllEmployees( + public ResponseEntity> getAllEmployees( EmployeePage employeePage, EmployeeFilterCriteria employeeFilterCriteria) { return ResponseEntity.status(HttpStatus.OK) @@ -138,6 +137,27 @@ public ResponseEntity deleteEmployee(@PathVariable Long id) { return new ResponseEntity<>(HttpStatus.OK); } + /** + * Controller activate employee. + * + * @return {@link HttpStatus} + * @author Oksana Spodaryk. + */ + @ApiOperation(value = "Activate employee") + @ApiResponses(value = { + @ApiResponse(code = 200, message = HttpStatuses.OK), + @ApiResponse(code = 400, message = HttpStatuses.BAD_REQUEST), + @ApiResponse(code = 401, message = HttpStatuses.UNAUTHORIZED), + @ApiResponse(code = 403, message = HttpStatuses.FORBIDDEN), + @ApiResponse(code = 404, message = HttpStatuses.NOT_FOUND) + }) + @PreAuthorize("@preAuthorizer.hasAuthority('DEACTIVATE_EMPLOYEE', authentication)") + @PutMapping("/activate-employee/{id}") + public ResponseEntity activateEmployee(@PathVariable Long id) { + employeeService.activateEmployee(id); + return new ResponseEntity<>(HttpStatus.OK); + } + /** * Controller gets all employee positions. * diff --git a/core/src/main/java/greencity/controller/ManagementOrderController.java b/core/src/main/java/greencity/controller/ManagementOrderController.java index e30347559..380fe9ce2 100644 --- a/core/src/main/java/greencity/controller/ManagementOrderController.java +++ b/core/src/main/java/greencity/controller/ManagementOrderController.java @@ -39,11 +39,11 @@ import greencity.dto.violation.ViolationDetailInfoDto; import greencity.dto.violation.ViolationsInfoDto; import greencity.entity.parameters.CustomTableView; -import greencity.entity.user.User; import greencity.filters.CertificateFilterCriteria; import greencity.filters.CertificatePage; import greencity.filters.OrderPage; import greencity.filters.OrderSearchCriteria; +import greencity.repository.OrderRepository; import greencity.service.ubs.CertificateService; import greencity.service.ubs.CoordinateService; import greencity.service.ubs.UBSClientService; @@ -94,6 +94,7 @@ public class ManagementOrderController { private final CoordinateService coordinateService; private final ViolationService violationService; private final BigOrderTableServiceView bigOrderTableService; + private final OrderRepository orderRepository; /** * Controller getting all certificates with sorting possibility. @@ -1006,30 +1007,6 @@ public ResponseEntity getNotTakenOrderReason( .body(ubsManagementService.getNotTakenOrderReason(orderId)); } - /** - * Controller updates info about order cancellation reason. - * - * @param id {@link Long}. - * @param dto {@link OrderCancellationReasonDto} - * @param uuid current {@link User}'s uuid. - * @return {@link HttpStatus} - http status. - */ - @ApiOperation(value = "updates info about order cancellation reason ") - @ApiResponses(value = { - @ApiResponse(code = 200, message = HttpStatuses.OK, response = OrderCancellationReasonDto.class), - @ApiResponse(code = 400, message = HttpStatuses.BAD_REQUEST), - @ApiResponse(code = 401, message = HttpStatuses.UNAUTHORIZED), - @ApiResponse(code = 403, message = HttpStatuses.FORBIDDEN), - @ApiResponse(code = 404, message = HttpStatuses.NOT_FOUND) - }) - @PostMapping("/order/{id}/cancellation") - public ResponseEntity updateCancellationReason( - @RequestBody final OrderCancellationReasonDto dto, - @PathVariable("id") final Long id, - @ApiIgnore @CurrentUserUuid String uuid) { - return ResponseEntity.status(HttpStatus.OK).body(ubsClientService.updateOrderCancellationReason(id, dto, uuid)); - } - /** * Controller saves order ID of order for which we need to make a refund. * @@ -1052,4 +1029,5 @@ public ResponseEntity saveOrderIdForRefund( ubsManagementService.saveOrderIdForRefund(orderId); return new ResponseEntity<>(HttpStatus.CREATED); } + } diff --git a/core/src/main/java/greencity/controller/OrderController.java b/core/src/main/java/greencity/controller/OrderController.java index 523457ef3..8be71a576 100644 --- a/core/src/main/java/greencity/controller/OrderController.java +++ b/core/src/main/java/greencity/controller/OrderController.java @@ -23,6 +23,8 @@ import greencity.dto.user.UserPointsAndAllBagsDto; import greencity.dto.user.UserVO; import greencity.entity.user.User; +import greencity.enums.OrderStatus; +import greencity.enums.PaymentStatus; import greencity.service.ubs.NotificationService; import greencity.service.ubs.UBSClientService; import greencity.service.ubs.UBSManagementService; @@ -50,6 +52,7 @@ import java.io.IOException; import java.security.Principal; import java.util.List; +import java.util.Locale; import java.util.Optional; @RestController @@ -175,7 +178,8 @@ public ResponseEntity processOrder( @Valid @PathVariable("id") Optional id) { if (id.isPresent()) { OrderDetailStatusDto orderDetailStatusDto = ubsManagementService.getOrderDetailStatus(id.get()); - if (orderDetailStatusDto.getPaymentStatus().equals("PAID")) { + if (PaymentStatus.PAID.name().equals(orderDetailStatusDto.getPaymentStatus()) + || !OrderStatus.FORMED.name().equals(orderDetailStatusDto.getOrderStatus())) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); } return ResponseEntity.status(HttpStatus.OK) @@ -233,7 +237,8 @@ public ResponseEntity getOrderDetailsByOrderId( /** * Controller gets info about events history from,order by order id. * - * @param id {@link Long}. + * @param id {@link Long}. + * @param locale {@link Locale}. * @return {@link HttpStatus} - http status. * @author Yuriy Bahlay. */ @@ -248,8 +253,10 @@ public ResponseEntity getOrderDetailsByOrderId( @GetMapping("/order_history/{orderId}") public ResponseEntity> getOderHistoryByOrderId( @Valid @PathVariable("orderId") Long id, - Principal principal) { - return ResponseEntity.ok().body(ubsClientService.getAllEventsForOrder(id, principal.getName())); + Principal principal, + @ApiIgnore Locale locale) { + return ResponseEntity.ok() + .body(ubsClientService.getAllEventsForOrder(id, principal.getName(), locale.getLanguage())); } /** diff --git a/core/src/test/java/greencity/ModelUtils.java b/core/src/test/java/greencity/ModelUtils.java index 6e108bb3e..a1829bfcf 100644 --- a/core/src/test/java/greencity/ModelUtils.java +++ b/core/src/test/java/greencity/ModelUtils.java @@ -226,11 +226,15 @@ public static UbsCustomersDto getUbsCustomersDto() { .build(); } - public static OrderDetailStatusDto getOrderDetailStatusDto() { - return getOrderDetailStatusDto(PaymentStatus.PAID); + public static OrderDetailStatusDto getPaidOrderDetailStatusDto() { + return getPaidOrderDetailStatusDto(PaymentStatus.PAID); } - public static OrderDetailStatusDto getOrderDetailStatusDto(PaymentStatus paymentStatus) { + public static OrderDetailStatusDto getUnpaidOrderDetailStatusDto() { + return getPaidOrderDetailStatusDto(PaymentStatus.UNPAID); + } + + public static OrderDetailStatusDto getPaidOrderDetailStatusDto(PaymentStatus paymentStatus) { return OrderDetailStatusDto.builder() .paymentStatus(paymentStatus.name()) .orderStatus(OrderStatus.CONFIRMED.name()) diff --git a/core/src/test/java/greencity/controller/ManagementEmployeeControllerTest.java b/core/src/test/java/greencity/controller/ManagementEmployeeControllerTest.java index bbab38890..adf97be38 100644 --- a/core/src/test/java/greencity/controller/ManagementEmployeeControllerTest.java +++ b/core/src/test/java/greencity/controller/ManagementEmployeeControllerTest.java @@ -55,6 +55,7 @@ class ManagementEmployeeControllerTest { private final String UPDATE_LINK = "/update-employee"; private final String FIND_ALL_LINK = "/getAll-employees"; private final String DELETE_LINK = "/deactivate-employee"; + private final String ACTIVATE_LINK = "/activate-employee"; private final String GET_ALL_POSITIONS_LINK = "/get-all-positions"; private final String DELETE_IMAGE_LINK = "/delete-employee-image/"; private final String GET_ALL_TARIFFS = "/getTariffs"; @@ -161,6 +162,15 @@ void deleteEmployeeTest() throws Exception { verify(service, times(1)).deactivateEmployee(1L); } + @Test + void activateEmployeeTest() throws Exception { + doNothing().when(service).activateEmployee(1L); + + mockMvc.perform(put(UBS_LINK + ACTIVATE_LINK + "/" + 1) + .principal(principal)).andExpect(status().isOk()); + verify(service, times(1)).activateEmployee(1L); + } + @Test void deleteEmployeeImage() throws Exception { mockMvc.perform(delete(UBS_LINK + DELETE_IMAGE_LINK + 1) diff --git a/core/src/test/java/greencity/controller/ManagementOrderControllerTest.java b/core/src/test/java/greencity/controller/ManagementOrderControllerTest.java index 73617dbfd..e494a26af 100644 --- a/core/src/test/java/greencity/controller/ManagementOrderControllerTest.java +++ b/core/src/test/java/greencity/controller/ManagementOrderControllerTest.java @@ -6,7 +6,6 @@ import greencity.dto.order.AdminCommentDto; import greencity.dto.order.EcoNumberDto; import greencity.dto.order.ExportDetailsDto; -import greencity.dto.order.OrderCancellationReasonDto; import greencity.dto.order.OrderDetailStatusDto; import greencity.dto.order.UpdateAllOrderPageDto; import greencity.dto.order.UpdateOrderPageAdminDto; @@ -208,7 +207,7 @@ void returnsDetailsAboutViolationWithGivenOrderId() throws Exception { @Test void updateOrderStatusesDetail() throws Exception { - OrderDetailStatusDto dto = ModelUtils.getOrderDetailStatusDto(); + OrderDetailStatusDto dto = ModelUtils.getPaidOrderDetailStatusDto(); ObjectMapper objectMapper = new ObjectMapper(); String orderResponceDtoJSON = objectMapper.writeValueAsString(dto); this.mockMvc.perform(put(ubsLink + "/update-order-detail-status" + "/{id}", 1L) @@ -494,14 +493,36 @@ void getNotTakenOrderReason() throws Exception { } @Test - void updatesCancellationReason() throws Exception { - OrderCancellationReasonDto dto = ModelUtils.getCancellationDto(); + void saveOrderIdForRefundTest() throws Exception { + mockMvc.perform(post(ubsLink + "/save-order-for-refund/{orderId}", 1L) + .principal(principal)).andExpect(status().isCreated()); + } + + @Test + void updatePageAdminInfoTest() throws Exception { + UpdateOrderPageAdminDto dto = getUpdateOrderPageAdminDto(); ObjectMapper objectMapper = new ObjectMapper(); - mockMvc.perform(post(ubsLink + "/order/{id}/cancellation", 1L) - .principal(ModelUtils.getPrincipal()) - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(dto))) - .andExpect(status().isOk()); + String responseJSON = objectMapper.writeValueAsString(dto); + + MockMultipartFile jsonFile = new MockMultipartFile( + "updateOrderPageAdminDto", + "updateOrderPageAdminDto.json", + "application/json", + responseJSON.getBytes()); + + MockMultipartHttpServletRequestBuilder builder = + MockMvcRequestBuilders.multipart(ubsLink + "/update-order-page-admin-info/{id}", 1L); + builder.with(request -> { + request.setMethod("PATCH"); + return request; + }); + + mockMvc.perform( + builder.file(jsonFile) + .param("language", "en") + .principal(principal) + .contentType(MediaType.MULTIPART_FORM_DATA)) + .andExpect(status().isCreated()); } @Test diff --git a/core/src/test/java/greencity/controller/OrderControllerTest.java b/core/src/test/java/greencity/controller/OrderControllerTest.java index 9f2c9c312..8aeee8c11 100644 --- a/core/src/test/java/greencity/controller/OrderControllerTest.java +++ b/core/src/test/java/greencity/controller/OrderControllerTest.java @@ -8,11 +8,13 @@ import greencity.converters.UserArgumentResolver; import greencity.dto.customer.UbsCustomersDto; import greencity.dto.customer.UbsCustomersDtoUpdate; +import greencity.dto.order.FondyOrderResponse; import greencity.dto.order.OrderCancellationReasonDto; import greencity.dto.order.OrderDetailStatusDto; import greencity.dto.order.OrderResponseDto; import greencity.dto.payment.PaymentResponseDto; import greencity.dto.user.UserInfoDto; +import greencity.enums.OrderStatus; import greencity.exceptions.user.UBSuserNotFoundException; import greencity.repository.OrderRepository; import greencity.repository.UBSuserRepository; @@ -23,6 +25,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -41,6 +45,7 @@ import static greencity.ModelUtils.getUbsCustomersDto; import static greencity.ModelUtils.getUbsCustomersDtoUpdate; import static greencity.ModelUtils.getUserInfoDto; +import static greencity.ModelUtils.getUnpaidOrderDetailStatusDto; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -50,9 +55,11 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.never; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @ExtendWith(MockitoExtension.class) @@ -160,10 +167,45 @@ void processOrder() throws Exception { verify(userRemoteClient).findUuidByEmail("test@gmail.com"); } + @Test + void processOrderId() throws Exception { + Long orderId = 1L; + String uuid = "35467585763t4sfgchjfuyetf"; + ObjectMapper objectMapper = new ObjectMapper(); + OrderResponseDto dto = ModelUtils.getOrderResponseDto(); + String orderResponseDtoJSON = objectMapper.writeValueAsString(dto); + + OrderDetailStatusDto orderDetailStatusDto = getUnpaidOrderDetailStatusDto(); + orderDetailStatusDto.setOrderStatus(OrderStatus.FORMED.name()); + + FondyOrderResponse resultObject = FondyOrderResponse.builder() + .orderId(orderId) + .link("Link") + .build(); + String resultJson = objectMapper.writeValueAsString(resultObject); + + when(userRemoteClient.findUuidByEmail(anyString())).thenReturn(uuid); + when(ubsManagementService.getOrderDetailStatus(orderId)).thenReturn(orderDetailStatusDto); + when(ubsClientService.saveFullOrderToDB(any(OrderResponseDto.class), anyString(), anyLong())) + .thenReturn(resultObject); + + mockMvc.perform(post(ubsLink + "/processOrder/{id}", orderId) + .content(orderResponseDtoJSON) + .principal(principal) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().json(resultJson)); + + verify(userRemoteClient).findUuidByEmail(anyString()); + verify(ubsManagementService).getOrderDetailStatus(orderId); + verify(ubsClientService).saveFullOrderToDB(any(OrderResponseDto.class), anyString(), anyLong()); + } + @Test void processPaidOrderId() throws Exception { OrderResponseDto dto = ModelUtils.getOrderResponseDto(); - OrderDetailStatusDto orderDetailStatusDto = ModelUtils.getOrderDetailStatusDto(); + OrderDetailStatusDto orderDetailStatusDto = ModelUtils.getPaidOrderDetailStatusDto(); when(userRemoteClient.findUuidByEmail((anyString()))).thenReturn("35467585763t4sfgchjfuyetf"); when(ubsManagementService.getOrderDetailStatus(anyLong())).thenReturn(orderDetailStatusDto); @@ -178,6 +220,33 @@ void processPaidOrderId() throws Exception { .andExpect(status().isBadRequest()); } + @ParameterizedTest + @EnumSource(value = OrderStatus.class, + names = "FORMED", + mode = EnumSource.Mode.EXCLUDE) + void processPaidOrderIdWithUnacceptableOrderStatusesTest(OrderStatus orderStatus) throws Exception { + Long orderId = 1L; + OrderResponseDto dto = ModelUtils.getOrderResponseDto(); + OrderDetailStatusDto orderDetailStatusDto = ModelUtils.getPaidOrderDetailStatusDto(); + orderDetailStatusDto.setOrderStatus(orderStatus.name()); + + when(userRemoteClient.findUuidByEmail(anyString())).thenReturn("35467585763t4sfgchjfuyetf"); + when(ubsManagementService.getOrderDetailStatus(anyLong())).thenReturn(orderDetailStatusDto); + + ObjectMapper objectMapper = new ObjectMapper(); + String orderResponseDtoJSON = objectMapper.writeValueAsString(dto); + + mockMvc.perform(post(ubsLink + "/processOrder/{id}", orderId) + .content(orderResponseDtoJSON) + .principal(principal) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()); + + verify(userRemoteClient).findUuidByEmail(anyString()); + verify(ubsManagementService).getOrderDetailStatus(orderId); + verify(ubsClientService, never()).saveFullOrderToDB(any(OrderResponseDto.class), anyString(), anyLong()); + } + @Test void getOrderDetailsByOrderId() throws Exception { UserInfoDto userInfoDto = getUserInfoDto(); @@ -245,7 +314,7 @@ void testGetOrderHistoryByOrderId() throws Exception { .andExpect(status().isOk()); verify(ubsClientService, times(1)) - .getAllEventsForOrder(1L, "test@gmail.com"); + .getAllEventsForOrder(1L, "test@gmail.com", "en"); } @Test diff --git a/dao/src/main/java/greencity/entity/notifications/NotificationParameter.java b/dao/src/main/java/greencity/entity/notifications/NotificationParameter.java index dc01d7e6d..0c3c51c0d 100644 --- a/dao/src/main/java/greencity/entity/notifications/NotificationParameter.java +++ b/dao/src/main/java/greencity/entity/notifications/NotificationParameter.java @@ -18,6 +18,7 @@ public class NotificationParameter { @ManyToOne @JoinColumn(name = "notification_id", nullable = false) + @ToString.Exclude private UserNotification userNotification; @Column(nullable = false, name = "key", length = 50) diff --git a/dao/src/main/java/greencity/entity/order/Event.java b/dao/src/main/java/greencity/entity/order/Event.java index fa80b4649..4a3306ef2 100644 --- a/dao/src/main/java/greencity/entity/order/Event.java +++ b/dao/src/main/java/greencity/entity/order/Event.java @@ -26,6 +26,12 @@ public class Event { @Column(name = "author", nullable = false) private String authorName; + @Column(name = "event_name_eng", nullable = false) + private String eventNameEng; + + @Column(name = "author_eng", nullable = false) + private String authorNameEng; + @ManyToOne private Order order; -} \ No newline at end of file +} diff --git a/dao/src/main/java/greencity/entity/order/Order.java b/dao/src/main/java/greencity/entity/order/Order.java index af48dfe0b..118eb3aba 100644 --- a/dao/src/main/java/greencity/entity/order/Order.java +++ b/dao/src/main/java/greencity/entity/order/Order.java @@ -10,14 +10,16 @@ import greencity.enums.OrderPaymentStatus; import greencity.enums.OrderStatus; import greencity.filters.StringListConverter; +import lombok.NoArgsConstructor; import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.EqualsAndHashCode; import lombok.Getter; -import lombok.NoArgsConstructor; import lombok.Setter; +import lombok.Builder; +import lombok.EqualsAndHashCode; import lombok.ToString; +import lombok.AccessLevel; import org.hibernate.annotations.Cascade; +import org.springframework.util.CollectionUtils; import javax.persistence.CascadeType; import javax.persistence.CollectionTable; @@ -187,5 +189,57 @@ public class Order { mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true) + @Setter(AccessLevel.PRIVATE) + @Builder.Default private List orderBags = new ArrayList<>(); + + /** + * Updates the list of order bags associated with this order. This method + * replaces all current items with new ones. It also sets the order reference + * for each order bag in the new list. This method should be used instead of the + * default setter to prevent exception that occur when the owner entity instance + * no longer references collections with cascade="all-delete-orphan". + * + * @param orderBags The new list of order bags to associate with this order. + * @throws NullPointerException If the provided 'orderBags' argument is null. + */ + public void updateWithNewOrderBags(List orderBags) { + if (!CollectionUtils.isEmpty(this.orderBags)) { + this.orderBags.clear(); + } + initOrderBagsIfNull(); + this.orderBags.addAll(orderBags); + this.orderBags.forEach(ob -> ob.setOrder(this)); + } + + /** + * Adds an ordered bag to the list of order bags associated with this order. + * This method adds the specified order bag to the list and sets the order + * reference for the order bag. + * + * @param orderBag The order bag to add to this order. + */ + public void addOrderedBag(OrderBag orderBag) { + initOrderBagsIfNull(); + this.orderBags.add(orderBag); + orderBag.setOrder(this); + } + + /** + * Removes an ordered bag from the list of order bags associated with this + * order. This method removes the specified order bag from the list. + * + * @param orderBag The order bag to remove from this order. + */ + public void removeOrderBag(OrderBag orderBag) { + if (!CollectionUtils.isEmpty(this.orderBags)) { + orderBags.remove(orderBag); + } + } + + private void initOrderBagsIfNull() { + if (this.orderBags == null) { + this.orderBags = new ArrayList<>(); + } + } } diff --git a/dao/src/main/java/greencity/repository/EmployeeCriteriaRepository.java b/dao/src/main/java/greencity/repository/EmployeeCriteriaRepository.java index 4c4356a0a..7beca01d5 100644 --- a/dao/src/main/java/greencity/repository/EmployeeCriteriaRepository.java +++ b/dao/src/main/java/greencity/repository/EmployeeCriteriaRepository.java @@ -3,23 +3,32 @@ import greencity.entity.user.employee.EmployeeFilterView; import greencity.filters.EmployeeFilterCriteria; import greencity.filters.EmployeePage; -import org.springframework.data.domain.*; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Repository; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; -import javax.persistence.criteria.*; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; +import javax.persistence.criteria.Order; +import javax.persistence.criteria.Subquery; +import javax.persistence.criteria.Expression; + import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -import static greencity.enums.EmployeeStatus.*; -import static java.util.Arrays.*; +import static greencity.enums.EmployeeStatus.employeeStatusExist; +import static java.util.Arrays.stream; @Repository public class EmployeeCriteriaRepository { private final EntityManager entityManager; private final CriteriaBuilder criteriaBuilder; + private static final String POSITION_ID = "positionId"; + private static final String EMPLOYEE_ID = "employeeId"; /** * Constructor to initialize EntityManager and CriteriaBuilder. @@ -40,13 +49,8 @@ private List getAllEmployees(EmployeePage employeePage, EmployeeFilterCriteria employeeFilterCriteria) { CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(EmployeeFilterView.class); Root employeeRoot = criteriaQuery.from(EmployeeFilterView.class); - - Predicate predicate = composePredicateForFiltering(employeeFilterCriteria, employeeRoot); - - criteriaQuery.select(employeeRoot).where(predicate); - - setOrderBy(employeePage, criteriaQuery, employeeRoot); - + Predicate predicate = composePredicateForFiltering(employeeFilterCriteria, employeeRoot, criteriaQuery); + criteriaQuery.select(employeeRoot).where(predicate).orderBy(getOrderBy(employeePage, employeeRoot)); return processEmployees(employeePage, criteriaQuery); } @@ -58,26 +62,26 @@ private List processEmployees(EmployeePage employeePage, return employeeTypedQuery.getResultList(); } - private void setOrderBy(EmployeePage employeePage, CriteriaQuery criteriaQuery, - Root employeeRoot) { - String[] split = employeePage.getSortBy().split("\\."); - criteriaQuery.orderBy(stream(split) - .map(x -> employeePage.getSortDirection().equals(Sort.Direction.ASC) - ? criteriaBuilder.asc(employeeRoot.get(x)) - : criteriaBuilder.desc(employeeRoot.get(x))) - .collect(Collectors.toList())); + private Order getOrderBy(EmployeePage employeePage, Root root) { + return employeePage.getSortDirection().equals(Sort.Direction.ASC) + ? criteriaBuilder.asc(root.get(employeePage.getSortBy())) + : criteriaBuilder.desc(root.get(employeePage.getSortBy())); } private Predicate composePredicateForFiltering(EmployeeFilterCriteria employeeFilterCriteria, - Root employeeFilterViewRoot) { - List predicates = collectAllPredicatesToList(employeeFilterCriteria, employeeFilterViewRoot); + Root employeeFilterViewRoot, + CriteriaQuery criteriaQuery) { + List predicates = collectAllPredicatesToList( + employeeFilterCriteria, employeeFilterViewRoot, criteriaQuery); return criteriaBuilder.and(predicates.toArray(Predicate[]::new)); } private List collectAllPredicatesToList(EmployeeFilterCriteria employeeFilterCriteria, - Root employeeFilterViewRoot) { + Root employeeFilterViewRoot, + CriteriaQuery criteriaQuery) { List predicates = new ArrayList<>(); + addPredicateDistinctUniqueEmployeesFromQuery(criteriaQuery, employeeFilterViewRoot, predicates); addSearchLinePredicates(employeeFilterCriteria, employeeFilterViewRoot, predicates); addEmployeeStatusPredicate(employeeFilterCriteria, employeeFilterViewRoot, predicates); addEmployeePositionPredicate(employeeFilterCriteria, employeeFilterViewRoot, predicates); @@ -87,6 +91,16 @@ private List collectAllPredicatesToList(EmployeeFilterCriteria employ return predicates; } + private void addPredicateDistinctUniqueEmployeesFromQuery(CriteriaQuery criteriaQuery, + Root employeeFilterViewRoot, + List predicates) { + Subquery subQuery = criteriaQuery.subquery(Long.class); + Root subQueryRoot = subQuery.from(EmployeeFilterView.class); + subQuery.select(criteriaBuilder.min(subQueryRoot.get(POSITION_ID))) + .where(criteriaBuilder.equal(subQueryRoot.get(EMPLOYEE_ID), employeeFilterViewRoot.get(EMPLOYEE_ID))); + predicates.add(criteriaBuilder.equal(employeeFilterViewRoot.get(POSITION_ID), subQuery)); + } + private void addCourierPredicate(EmployeeFilterCriteria employeeFilterCriteria, Root employeeFilterViewRoot, List predicates) { @@ -118,7 +132,7 @@ private void addEmployeePositionPredicate(EmployeeFilterCriteria employeeFilterC Root employeeFilterViewRoot, List predicates) { if (isListNotNullAndNotEmpty(employeeFilterCriteria.getPositions())) { - predicates.add(employeeFilterViewRoot.get("positionId") + predicates.add(employeeFilterViewRoot.get(POSITION_ID) .in(employeeFilterCriteria.getPositions())); } } diff --git a/dao/src/main/java/greencity/repository/OrderRepository.java b/dao/src/main/java/greencity/repository/OrderRepository.java index a4616a199..7f5b6dfdf 100644 --- a/dao/src/main/java/greencity/repository/OrderRepository.java +++ b/dao/src/main/java/greencity/repository/OrderRepository.java @@ -168,14 +168,14 @@ void changeReceivingStationForAllOrders(@Param("receiving_station") Long station /** * Method sets order status by order's id. * - * @param orderId - order's ID - * @param orderStatus - order status to set + * @param orderId - order's ID + * @param orderPaymentStatus - order status to set */ @Modifying @Transactional @Query(nativeQuery = true, - value = "UPDATE orders SET order_payment_status = :orderStatus WHERE id = :orderId") - void updateOrderPaymentStatus(@Param(value = "orderId") Long orderId, @Param("orderStatus") String orderStatus); + value = "UPDATE orders SET order_payment_status = :orderPaymentStatus WHERE id = :orderId") + void updateOrderPaymentStatus(Long orderId, String orderPaymentStatus); /** * Return sum of discounts by order id. diff --git a/dao/src/main/java/greencity/repository/OrdersForUserRepository.java b/dao/src/main/java/greencity/repository/OrdersForUserRepository.java index eefda878c..2fe310c84 100644 --- a/dao/src/main/java/greencity/repository/OrdersForUserRepository.java +++ b/dao/src/main/java/greencity/repository/OrdersForUserRepository.java @@ -5,6 +5,7 @@ import greencity.entity.user.User; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @@ -27,6 +28,9 @@ public interface OrdersForUserRepository extends PagingAndSortingRepository getAllByUserUuid(Pageable pageable, String uuid); /** @@ -38,6 +42,11 @@ public interface OrdersForUserRepository extends PagingAndSortingRepository getAllByUserUuidAndOrderStatusIn(Pageable pageable, String uuid, List statuses); /** diff --git a/dao/src/main/resources/db/changelog/db.changelog-master.xml b/dao/src/main/resources/db/changelog/db.changelog-master.xml index 8047a3d2f..bc2e9c06f 100644 --- a/dao/src/main/resources/db/changelog/db.changelog-master.xml +++ b/dao/src/main/resources/db/changelog/db.changelog-master.xml @@ -220,5 +220,9 @@ + + - \ No newline at end of file + + + diff --git a/dao/src/main/resources/db/changelog/logs/ch-add-columns-nameEventEng-and-authorEng-to-Events-Bokalo.xml b/dao/src/main/resources/db/changelog/logs/ch-add-columns-nameEventEng-and-authorEng-to-Events-Bokalo.xml new file mode 100644 index 000000000..34da1dc62 --- /dev/null +++ b/dao/src/main/resources/db/changelog/logs/ch-add-columns-nameEventEng-and-authorEng-to-Events-Bokalo.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/dao/src/main/resources/db/changelog/logs/ch-insert-into-users-Spodaryk.xml b/dao/src/main/resources/db/changelog/logs/ch-insert-into-users-Spodaryk.xml new file mode 100644 index 000000000..89ac62999 --- /dev/null +++ b/dao/src/main/resources/db/changelog/logs/ch-insert-into-users-Spodaryk.xml @@ -0,0 +1,26 @@ + + + + + + + SELECT COUNT(*) FROM users WHERE recipient_email = 'admin.greencity@starmaker.email'; + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dao/src/test/java/greencity/entity/order/OrderTest.java b/dao/src/test/java/greencity/entity/order/OrderTest.java new file mode 100644 index 000000000..28a6f5b33 --- /dev/null +++ b/dao/src/test/java/greencity/entity/order/OrderTest.java @@ -0,0 +1,130 @@ +package greencity.entity.order; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertNull; + +class OrderTest { + @Test + void updateWithNewOrderBagsTest() { + Order order = new Order(); + OrderBag oldBag = OrderBag.builder().id(4L).build(); + order.addOrderedBag(oldBag); + List previous = order.getOrderBags(); + List bags = List.of( + OrderBag.builder().id(1L).build(), + OrderBag.builder().id(2L).build(), + OrderBag.builder().id(3L).build()); + + order.updateWithNewOrderBags(bags); + + assertSame(previous, order.getOrderBags()); + assertNotSame(bags, order.getOrderBags()); + assertTrue(order.getOrderBags().containsAll(bags) && order.getOrderBags().size() == bags.size()); + assertFalse(order.getOrderBags().contains(oldBag)); + } + + @Test + void updateWithNewOrderBagsNullOrderBagsTest() { + Order order = Order.builder() + .orderBags(null) + .build(); + List previous = order.getOrderBags(); + List bags = List.of( + OrderBag.builder().id(1L).build(), + OrderBag.builder().id(2L).build(), + OrderBag.builder().id(3L).build()); + + order.updateWithNewOrderBags(bags); + + assertNotNull(order.getOrderBags()); + assertNull(previous); + assertNotSame(bags, order.getOrderBags()); + assertTrue(order.getOrderBags().containsAll(bags) && order.getOrderBags().size() == bags.size()); + + } + + @Test + void updateWithNewOrderBagsNullArgExceptionTest() { + Order order = Order.builder().build(); + List bags = null; + assertThrows(NullPointerException.class, () -> order.updateWithNewOrderBags(bags)); + } + + @Test + void addOrderedBagTest() { + Order order = new Order(); + List previous = order.getOrderBags(); + List bags = List.of( + OrderBag.builder().id(1L).build(), + OrderBag.builder().id(2L).build(), + OrderBag.builder().id(3L).build()); + + order.addOrderedBag(bags.get(0)); + order.addOrderedBag(bags.get(1)); + order.addOrderedBag(bags.get(2)); + + assertSame(previous, order.getOrderBags()); + assertNotSame(bags, order.getOrderBags()); + assertTrue(order.getOrderBags().containsAll(bags) && order.getOrderBags().size() == bags.size()); + } + + @Test + void addOrderedBagToNullFieldTest() { + Order order = Order.builder() + .orderBags(null) + .build(); + List previous = order.getOrderBags(); + OrderBag orderBag = OrderBag.builder() + .id(1L) + .build(); + + order.addOrderedBag(orderBag); + + assertNull(previous); + assertTrue(order.getOrderBags().contains(orderBag) && order.getOrderBags().size() == 1); + } + + @Test + void removeOrderBagTest() { + Order order = new Order(); + List previous = order.getOrderBags(); + List bags = new ArrayList<>(List.of( + OrderBag.builder().id(1L).build(), + OrderBag.builder().id(2L).build(), + OrderBag.builder().id(3L).build())); + order.updateWithNewOrderBags(bags); + order.removeOrderBag(bags.get(0)); + bags.remove(bags.get(0)); + + assertSame(previous, order.getOrderBags()); + assertNotSame(bags, order.getOrderBags()); + assertTrue(order.getOrderBags().containsAll(bags) && order.getOrderBags().size() == bags.size() + && order.getOrderBags().size() == 2); + } + + @Test + void removeOrderBagNullFieldTest() { + Order order = Order.builder() + .orderBags(null) + .build(); + List previous = order.getOrderBags(); + OrderBag orderBag = OrderBag.builder() + .id(1L) + .build(); + + order.removeOrderBag(orderBag); + + assertNull(previous); + assertNull(order.getOrderBags()); + } +} \ No newline at end of file diff --git a/service-api/src/main/java/greencity/client/UserRemoteClient.java b/service-api/src/main/java/greencity/client/UserRemoteClient.java index cbdd6fcc7..01ac5cd5d 100644 --- a/service-api/src/main/java/greencity/client/UserRemoteClient.java +++ b/service-api/src/main/java/greencity/client/UserRemoteClient.java @@ -166,4 +166,12 @@ public interface UserRemoteClient { */ @PutMapping("/user/deactivate-employee") void deactivateEmployee(@RequestParam String uuid); + + /** + * Activate employee by uuid. + * + * @param uuid - uuid of employee. + */ + @PutMapping("/user/markUserAsActivated") + void activateEmployee(@RequestParam String uuid); } diff --git a/service-api/src/main/java/greencity/client/config/UserRemoteClientFallbackFactory.java b/service-api/src/main/java/greencity/client/config/UserRemoteClientFallbackFactory.java index 47afebe24..41691c2da 100644 --- a/service-api/src/main/java/greencity/client/config/UserRemoteClientFallbackFactory.java +++ b/service-api/src/main/java/greencity/client/config/UserRemoteClientFallbackFactory.java @@ -111,6 +111,13 @@ public void deactivateEmployee(String uuid) { throw new RemoteServerUnavailableException(ErrorMessage.EMPLOYEE_WITH_CURRENT_UUID_WAS_NOT_DEACTIVATED, throwable); } + + @Override + public void activateEmployee(String uuid) { + log.error(String.format(ErrorMessage.EMPLOYEE_WITH_CURRENT_UUID_WAS_NOT_ACTIVATED, uuid)); + throw new RemoteServerUnavailableException( + String.format(ErrorMessage.EMPLOYEE_WITH_CURRENT_UUID_WAS_NOT_ACTIVATED, uuid)); + } }; } } diff --git a/service-api/src/main/java/greencity/constant/ErrorMessage.java b/service-api/src/main/java/greencity/constant/ErrorMessage.java index 5793d2a82..125894abd 100644 --- a/service-api/src/main/java/greencity/constant/ErrorMessage.java +++ b/service-api/src/main/java/greencity/constant/ErrorMessage.java @@ -137,6 +137,8 @@ public final class ErrorMessage { public static final String MIN_MAX_VALUE_RESTRICTION = "Min and Max fields must have different values"; public static final String EMPLOYEE_WITH_CURRENT_UUID_WAS_NOT_DEACTIVATED = "Employee with current uuid was not " + "deactivated."; + public static final String EMPLOYEE_WITH_CURRENT_UUID_WAS_NOT_ACTIVATED = "Employee with uuid: %s was not " + + "activated."; public static final String BAG_FOR_TARIFF_NOT_EXIST = "Could not find bag with id %d for tariff with id %d"; public static final String TARIFF_ALREADY_HAS_THIS_STATUS = "Tariff with id %d already has status: %s"; public static final String TARIFF_ACTIVATION_RESTRICTION_DUE_TO_UNSPECIFIED_LIMITS = diff --git a/service-api/src/main/java/greencity/constant/OrderHistory.java b/service-api/src/main/java/greencity/constant/OrderHistory.java index 23b6892e9..2f8a61c5f 100644 --- a/service-api/src/main/java/greencity/constant/OrderHistory.java +++ b/service-api/src/main/java/greencity/constant/OrderHistory.java @@ -4,15 +4,23 @@ public final class OrderHistory { public static final String ORDER_ON_THE_ROUTE = "Статус Замовлення - На маршруті"; public static final String ORDER_DONE = "Статус Замовлення - Виконано"; public static final String ORDER_BROUGHT_IT_HIMSELF = "Статус Замовлення - Привезе сам"; + public static final String ORDER_BROUGHT_IT_HIMSELF_ENG = "Order status - Will bring it myself"; public static final String ORDER_CANCELLED = "Статус Замовлення - Скасовано"; public static final String ORDER_PAID = "Замовлення Оплачено"; + public static final String ORDER_PAID_ENG = "Order Paid"; public static final String ORDER_HALF_PAID = "Замовлення Частково оплачено"; + public static final String ORDER_HALF_PAID_ENG = "Order partially paid"; public static final String SYSTEM = "Система"; + public static final String SYSTEM_ENG = "System"; public static final String ORDER_FORMED = "Статус Замовлення - Сформовано"; + public static final String ORDER_FORMED_ENG = "Order Status - Formed"; public static final String CLIENT = "Клієнт"; + public static final String CLIENT_ENG = "Client"; public static final String CHANGE_ORDER_DETAILS = "Змінено деталі замовлення."; public static final String ORDER_ADJUSTMENT = "Статус Замовлення - Узгодження"; + public static final String ORDER_ADJUSTMENT_ENG = "Order Status - Approval"; public static final String ORDER_CONFIRMED = "Статус Замовлення - Підтверджено"; + public static final String ORDER_CONFIRMED_ENG = "Order Status - Confirmed"; public static final String ORDER_NOT_TAKEN_OUT = "Статус Замовлення - Не вивезли"; public static final String ASSIGN_DRIVER = "Закріплено водія"; public static final String ASSIGN_LOGIEST = "Закріплено логіста"; @@ -25,10 +33,15 @@ public final class OrderHistory { public static final String ADD_VIOLATION = "Додано порушення"; public static final String CHANGES_VIOLATION = "Змінено деталі порушення"; public static final String DELETE_VIOLATION = "Видалено порушення"; + public static final String DELETE_VIOLATION_ENG = "Violation removed"; public static final String ADD_PAYMENT_MANUALLY = "Додано оплату №"; + public static final String ADD_PAYMENT_MANUALLY_ENG = "Added payment №"; public static final String UPDATE_PAYMENT_MANUALLY = "Змінено деталі оплати № "; + public static final String UPDATE_PAYMENT_MANUALLY_ENG = "Payment details changed № "; public static final String DELETE_PAYMENT_MANUALLY = "Видалено оплату №"; + public static final String DELETE_PAYMENT_MANUALLY_ENG = "Payment removed №"; public static final String ADD_PAYMENT_SYSTEM = "Додано оплату №"; + public static final String ADD_PAYMENT_SYSTEM_ENG = "Added payment №"; public static final String UPDATE_EXPORT_DETAILS = "Змінено деталі вивезення."; public static final String UPDATE_EXPORT_DATA = " Дата вивезення: %s."; public static final String UPDATE_DELIVERY_TIME = " Час вивезення: %s - %s."; @@ -39,6 +52,7 @@ public final class OrderHistory { public static final String RETURN_BONUSES_TO_CLIENT = "Невикористані бонуси повернено на бонусний рахунок клієнта"; public static final String WASTE_REMOVAL_ADDRESS_CHANGE = "Змінено адресу вивезення відходів"; public static final String ADD_ADMIN_COMMENT = "Додано коментар"; + public static final String ADD_ADMIN_COMMENT_ENG = "Comment added"; public static final String ADD_NEW_ECO_NUMBER = "Додано номер замовлення з магазину"; public static final String DELETED_ECO_NUMBER = "Видалено номер замовлення з магазину"; public static final String CHANGED_SENDER = "Змінено дані Відправника"; diff --git a/service-api/src/main/java/greencity/constant/ValidationConstant.java b/service-api/src/main/java/greencity/constant/ValidationConstant.java index 3e9d52c78..426952546 100644 --- a/service-api/src/main/java/greencity/constant/ValidationConstant.java +++ b/service-api/src/main/java/greencity/constant/ValidationConstant.java @@ -20,6 +20,11 @@ public class ValidationConstant { public static final String NAME_REGEXP = "^(?!\\.)(?!.*\\.$)(?!.*?\\.\\.)(?!.*?\\-\\-)(?!.*?\\'\\')(?!\\s*$)" + "[-'ʼ ґҐіІєЄїЇА-Яа-я+\\w.]{1,30}$"; + public static final String STREET_REGEXP = "^(?![0-9]+$)[-A-Za-zА-Яа-яЇїІіЄєҐґ .,ʼ'`ʹ0-9-]*$"; + public static final String STREET_VALIDATION_MESSAGE = + "Use only English, or Ukrainian letters. Both English or Ukrainian letters valid, " + + "for cases, when user inputs street address by yourself instead of using Google Api, " + + "in that cases sets the same value for both localizations."; /** * Constructor. diff --git a/service-api/src/main/java/greencity/dto/CreateAddressRequestDto.java b/service-api/src/main/java/greencity/dto/CreateAddressRequestDto.java index bc67fb868..fc1bbff9d 100644 --- a/service-api/src/main/java/greencity/dto/CreateAddressRequestDto.java +++ b/service-api/src/main/java/greencity/dto/CreateAddressRequestDto.java @@ -11,6 +11,9 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; +import static greencity.constant.ValidationConstant.STREET_REGEXP; +import static greencity.constant.ValidationConstant.STREET_VALIDATION_MESSAGE; + @Getter @AllArgsConstructor @NoArgsConstructor @@ -19,7 +22,7 @@ @Builder public class CreateAddressRequestDto { // CHECKSTYLE:OFF - private static final String validationMessage = "Use only English,or Ukrainian letter"; + private static final String validationMessage = "Use only English, or Ukrainian letter"; private static final String notEmptyValidationMessage = "Name must not be empty"; private static final String houseNumberNotValid = "House number is invalid"; @@ -63,11 +66,11 @@ public class CreateAddressRequestDto { @NotEmpty(message = notEmptyValidationMessage) private String cityEn; - @Pattern(regexp = "[-A-Za-zА-Яа-яЇїІіЄєҐґ .,ʼ'`ʹ]*", message = validationMessage) + @Pattern(regexp = STREET_REGEXP, message = STREET_VALIDATION_MESSAGE) @NotEmpty(message = notEmptyValidationMessage) private String street; - @Pattern(regexp = "[-A-Za-zА-Яа-яЇїІіЄєҐґ .,ʼ'`ʹ]*", message = validationMessage) + @Pattern(regexp = STREET_REGEXP, message = STREET_VALIDATION_MESSAGE) @NotEmpty(message = notEmptyValidationMessage) private String streetEn; } diff --git a/service-api/src/main/java/greencity/dto/address/AddressDto.java b/service-api/src/main/java/greencity/dto/address/AddressDto.java index 72863ca1c..d369bcb7d 100644 --- a/service-api/src/main/java/greencity/dto/address/AddressDto.java +++ b/service-api/src/main/java/greencity/dto/address/AddressDto.java @@ -5,7 +5,6 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; - import lombok.NoArgsConstructor; import org.hibernate.validator.constraints.Length; @@ -20,6 +19,8 @@ import static greencity.constant.ValidationConstant.CH_UA; import static greencity.constant.ValidationConstant.CITY_EN_REGEXP; import static greencity.constant.ValidationConstant.CITY_UK_REGEXP; +import static greencity.constant.ValidationConstant.STREET_REGEXP; +import static greencity.constant.ValidationConstant.STREET_VALIDATION_MESSAGE; @Builder @Data @@ -29,25 +30,32 @@ public class AddressDto implements Serializable { @NotNull @Min(1) private Long id; + @Length(max = 30) @Pattern(regexp = CITY_UK_REGEXP) private String city; + @Length(max = 30) @Pattern(regexp = CH_UA + "{1,30}") private String district; + @Length(max = 30) @Pattern(regexp = CH_UA + "{1,30}") private String region; + @Length(max = 4) @Pattern(regexp = CH_NUM + "{1,4}") private String entranceNumber; + @Length(max = 5) @Pattern(regexp = CH_NUM + "{1,5}") private String houseCorpus; + @Pattern(regexp = CH_NUM + "{1,10}") private String houseNumber; + @Length(max = 50) - @Pattern(regexp = CH_UA + "{1,50}") + @Pattern(regexp = STREET_REGEXP, message = STREET_VALIDATION_MESSAGE) private String street; @Length(max = 255) @@ -56,19 +64,24 @@ public class AddressDto implements Serializable { private Coordinates coordinates; private Boolean actual; + @Length(max = 30) @Pattern(regexp = CITY_EN_REGEXP) private String cityEn; + @Length(max = 30) @Pattern(regexp = CH_EN + "{1,30}") private String regionEn; + @Length(max = 50) - @Pattern(regexp = CH_EN + "{1,50}") + @Pattern(regexp = STREET_REGEXP, message = STREET_VALIDATION_MESSAGE) private String streetEn; + @Length(max = 30) @Pattern(regexp = CH_EN + "{1,30}") private String districtEn; private String placeId; + private List addressRegionDistrictList; } \ No newline at end of file diff --git a/service-api/src/main/java/greencity/dto/location/RegionTranslationDto.java b/service-api/src/main/java/greencity/dto/location/RegionTranslationDto.java index 43afdedf4..d34ed9a3e 100644 --- a/service-api/src/main/java/greencity/dto/location/RegionTranslationDto.java +++ b/service-api/src/main/java/greencity/dto/location/RegionTranslationDto.java @@ -12,7 +12,7 @@ @ToString @Builder public class RegionTranslationDto { - @Pattern(regexp = "[A-Za-zА-Яа-яЇїІіЄєҐґ '-]*", message = "use only English,Ukrainian or Russian letters") + @Pattern(regexp = "[A-Za-zА-Яа-яЇїІіЄєҐґ '-]*", message = "use only English or Ukrainian letters") @NotEmpty(message = "name must not be empty") private String regionName; @Pattern(regexp = "[A-Za-zА']*", message = "use only English letters") diff --git a/service-api/src/main/java/greencity/dto/order/OrderAddressDtoRequest.java b/service-api/src/main/java/greencity/dto/order/OrderAddressDtoRequest.java index 04204c294..41d8dc36d 100644 --- a/service-api/src/main/java/greencity/dto/order/OrderAddressDtoRequest.java +++ b/service-api/src/main/java/greencity/dto/order/OrderAddressDtoRequest.java @@ -1,15 +1,21 @@ package greencity.dto.order; import greencity.entity.coords.Coordinates; -import lombok.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.Max; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Pattern; -import static greencity.constant.ValidationConstant.CH_EN; -import static greencity.constant.ValidationConstant.CH_UA; +import static greencity.constant.ValidationConstant.STREET_REGEXP; +import static greencity.constant.ValidationConstant.STREET_VALIDATION_MESSAGE; @Getter @Setter @@ -21,29 +27,36 @@ public class OrderAddressDtoRequest { @Max(1000000) private Long id; + @NotBlank @Length(max = 30) @Pattern(regexp = "[ЁёІіЇїҐґЄєА-Яа-яA-Za-z-\\s'.]{3,30}") private String region; + @NotBlank @Length(max = 30) @Pattern(regexp = "[ЁёІіЇїҐґЄєА-Яа-яA-Za-z-\\s'.]{3,30}") private String city; + @NotBlank @Length(max = 30) @Pattern(regexp = "[ЁёІіЇїҐґЄєА-Яа-яA-Za-z-\\s'.]{3,30}") private String district; + @Length(max = 4) @Pattern(regexp = "[ЁёІіЇїҐґЄєА-Яа-яA-Z0-9a-z-.]{0,2}") private String entranceNumber; + @Length(max = 5) @Pattern(regexp = "[ЁёІіЇїҐґЄєА-Яа-яA-Z0-9a-z-.]{0,5}") private String houseCorpus; + @Length(max = 10) @Pattern(regexp = "[-A-Za-zА-Яа-яЁёЇїІіЄєҐґ0-9.,ʼ'`ʹ—/\"\\s]" + "{1,10}") private String houseNumber; + @Length(max = 50) - @Pattern(regexp = CH_UA + "{3,40}") + @Pattern(regexp = STREET_REGEXP, message = STREET_VALIDATION_MESSAGE) private String street; @Length(max = 255) @@ -54,17 +67,22 @@ public class OrderAddressDtoRequest { private Coordinates coordinates; private Boolean actual; + @Length(max = 30) @Pattern(regexp = "[a-zA-Z-\\s'.]{3,30}") private String cityEn; + @Length(max = 30) @Pattern(regexp = "[a-zA-Z-\\s'.]{3,30}") private String regionEn; + @Length(max = 50) - @Pattern(regexp = CH_EN + "{3,40}") + @Pattern(regexp = STREET_REGEXP, message = STREET_VALIDATION_MESSAGE) private String streetEn; + @Length(max = 30) @Pattern(regexp = "[a-zA-Z-\\s'.]{3,30}") private String districtEn; + private String placeId; } diff --git a/service-api/src/main/java/greencity/dto/order/OrderResponseDto.java b/service-api/src/main/java/greencity/dto/order/OrderResponseDto.java index 9aca45b92..bdebe3c40 100644 --- a/service-api/src/main/java/greencity/dto/order/OrderResponseDto.java +++ b/service-api/src/main/java/greencity/dto/order/OrderResponseDto.java @@ -35,7 +35,7 @@ public class OrderResponseDto implements Serializable { private Set<@Pattern(regexp = "(\\d{4}-\\d{4})|(^$)", message = "This certificate code is not valid") String> certificates; - private Set<@Pattern(regexp = "\\d{0,8}") String> additionalOrders; + private Set<@Pattern(regexp = "\\d{4,10}") String> additionalOrders; @Length(max = 255) private String orderComment; diff --git a/service-api/src/main/java/greencity/service/locations/LocationApiService.java b/service-api/src/main/java/greencity/service/locations/LocationApiService.java new file mode 100644 index 000000000..3e1c93589 --- /dev/null +++ b/service-api/src/main/java/greencity/service/locations/LocationApiService.java @@ -0,0 +1,160 @@ +package greencity.service.locations; + +import greencity.dto.location.api.LocationDto; +import greencity.exceptions.NotFoundException; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.stereotype.Service; +import java.net.URI; +import java.util.*; + +@Service +@EnableCaching +public interface LocationApiService { + /** + * Retrieves all districts in a city by the city's name. There's a special case + * for Kyiv, the capital of Ukraine. In the system, due to the API having + * references only to the previous element, the search for districts occurs + * sequentially: region -> district in region -> local community -> city -> + * district. Generally, the city corresponds to level 4 in the hierarchical + * structure. However, Kyiv is unique in that it is at level 1, and its + * districts are at level 5. Therefore, a separate logic is implemented because + * the system can't go through all the steps from level 1 to level 4, and has to + * directly access the districts from level 5 when dealing with Kyiv. + * + * @param regionName The name of the region. + * @param cityName The name of the city. + * @return A list of LocationDto that represent districts in the city. + */ + List getAllDistrictsInCityByNames(String regionName, String cityName); + + /** + * Retrieves a list of cities by name. + * + * @param regionName The name of the region. + * @param cityName The name of the city. + * @return A list of matching city locations. + */ + List getCitiesByName(String regionName, String cityName); + + /** + * Finds a location by its name. + * + * @param locations The list of locations. + * @param locationName The location name. + * @return A LocationDto matching the provided name. + */ + LocationDto findLocationByName(List locations, String locationName); + + /** + * Retrieves a city by name from a specified region. + * + * @param regionName The name of the region. + * @param cityName The name of the city. + * @return The LocationDto that represents the city in the specified region. + * @throws NotFoundException if the city is not found. + */ + LocationDto getCityByNameFromRegionSide(String regionName, String cityName); + + /** + * Retrieves a region by name. + * + * @param regionName The name of the region. + * @return The region matching the provided name. + */ + LocationDto getRegionByName(String regionName); + + /** + * Retrieves the city in a specified region. + * + * @param regionName The name of the region. + * @param cities A list of LocationDto that represent cities. + * @return The LocationDto that represents the city in the specified region. + * @throws NotFoundException if the city is not found in the region. + */ + LocationDto getCityInRegion(String regionName, List cities); + + /** + * Retrieves all regions. + * + * @return A list of LocationDto that represent all regions. + */ + List getAllRegions(); + + /** + * Retrieves all cities by their ID. + * + * @param upperId The ID of the city. + * @return A list of LocationDto that represent the cities. + */ + List getAllCitiesById(String upperId); + + /** + * Retrieves all districts in the region by the region's ID. + * + * @param upperId The ID of the region. + * @return A list of LocationDto that represent districts in the region. + */ + List getAllDistrictInTheRegionsById(String upperId); + + /** + * Retrieves all local communities by their ID. + * + * @param upperId The ID of the local community. + * @return A list of LocationDto that represent local communities. + */ + List getAllLocalCommunitiesById(String upperId); + + /** + * Retrieves all districts in a city by the city's ID. + * + * @param upperId The ID of the city. + * @return A list of LocationDto that represent districts in the city. + */ + List getAllDistrictsInCityByCityID(String upperId); + + /** + * Retrieves location data by level and code. + * + * @param level The hierarchical level of the location. + * @param code The code of the location. + * @return The LocationDto that matches the specified level and code. + * @throws NotFoundException if the location is not found. + */ + LocationDto getLocationDataByCode(int level, String code); + + /** + * Fetches a list of location data by level. + * + * @param level The level of the location. + * @return A list of LocationDto for the specified level. + */ + List getLocationDataByLevel(int level); + + /** + * Retrieves a list of location data by level and name. + * + * @param level The hierarchical level of the location. + * @param name The name of the location. + * @return A list of LocationDto that matches the specified level and name. + * @throws IllegalArgumentException if the name is null. + */ + List getLocationDataByName(int level, String name); + + /** + * Extracts location data from a URL. + * + * @param url The URL to retrieve the data from. + * @return A list of LocationDto. + */ + List getResultFromUrl(URI url); + + /** + * Retrieves location data by its upper Id. + * + * @param level The hierarchical level of the location. + * @param upperId The upperId associated with the location. + * @return A list of LocationDto associated with the specified upperId. + * @throws IllegalArgumentException if the upperId is null. + */ + List getLocationDataByUpperId(int level, String upperId); +} diff --git a/service-api/src/main/java/greencity/service/ubs/NotificationService.java b/service-api/src/main/java/greencity/service/ubs/NotificationService.java index 9604cfd08..04ea920c3 100644 --- a/service-api/src/main/java/greencity/service/ubs/NotificationService.java +++ b/service-api/src/main/java/greencity/service/ubs/NotificationService.java @@ -86,6 +86,15 @@ public interface NotificationService { */ void notifyUnpaidOrder(Order order); + /** + * Notifies the customer that the order status has been changed to "Brought by + * himself". + * + * @param order The order {@link Order} which status was changed. + * @author Maksym Lenets + */ + public void notifySelfPickupOrder(Order order); + /** * Method that returns page with notifications for user by UUID. * diff --git a/service-api/src/main/java/greencity/service/ubs/OrdersAdminsPageService.java b/service-api/src/main/java/greencity/service/ubs/OrdersAdminsPageService.java index 625e93336..b3c764725 100644 --- a/service-api/src/main/java/greencity/service/ubs/OrdersAdminsPageService.java +++ b/service-api/src/main/java/greencity/service/ubs/OrdersAdminsPageService.java @@ -5,6 +5,7 @@ import greencity.dto.order.RequestToChangeOrdersDataDto; import greencity.dto.table.ColumnWidthDto; import greencity.dto.table.TableParamsDto; +import greencity.entity.user.employee.Employee; import java.util.List; @@ -48,12 +49,12 @@ ChangeOrderResponseDTO chooseOrdersDataSwitcher(String email, /** * Method changing order's status. * - * @param value of {@link String} - * @param ordersId of {@link List} - * @param employeeId of {@link Long} + * @param value of {@link String} + * @param ordersId of {@link List} + * @param employee of {@link Employee} * @author Liubomyr Pater */ - List orderStatusForDevelopStage(List ordersId, String value, Long employeeId); + List orderStatusForDevelopStage(List ordersId, String value, Employee employee); /** * Method changing order's date of export. diff --git a/service-api/src/main/java/greencity/service/ubs/UBSClientService.java b/service-api/src/main/java/greencity/service/ubs/UBSClientService.java index 7274ce035..e1df6f3b6 100644 --- a/service-api/src/main/java/greencity/service/ubs/UBSClientService.java +++ b/service-api/src/main/java/greencity/service/ubs/UBSClientService.java @@ -279,27 +279,16 @@ public interface UBSClientService { */ OrderCancellationReasonDto getOrderCancellationReason(Long orderId, String uuid); - /** - * Method updates cancellation reason and comment. - * - * @param id {@link Long}; - * @param dto {@link OrderCancellationReasonDto}; - * @param uuid current {@link User}'s uuid; - * @return {@link OrderCancellationReasonDto} dto that contains cancellation - * reason and comment; - * @author Oleksandr Khomiakov - */ - OrderCancellationReasonDto updateOrderCancellationReason(long id, OrderCancellationReasonDto dto, String uuid); - /** * Methods for finding all events for Order. * - * @param orderId {@link Long} id. - * @param email {@link String}; + * @param orderId {@link Long} id. + * @param email {@link String}; + * @param language {@link String}; * @return {@link List} that contains list of EventsDTOS. * @author Yuriy Bahlay. */ - List getAllEventsForOrder(Long orderId, String email); + List getAllEventsForOrder(Long orderId, String email, String language); /** * Method that returns order info for surcharge. diff --git a/service-api/src/main/java/greencity/service/ubs/UBSManagementEmployeeService.java b/service-api/src/main/java/greencity/service/ubs/UBSManagementEmployeeService.java index f2c792c80..6a15e6dc8 100644 --- a/service-api/src/main/java/greencity/service/ubs/UBSManagementEmployeeService.java +++ b/service-api/src/main/java/greencity/service/ubs/UBSManagementEmployeeService.java @@ -3,12 +3,12 @@ import greencity.dto.employee.EmployeeWithTariffsDto; import greencity.dto.employee.GetEmployeeDto; import greencity.dto.employee.EmployeeWithTariffsIdDto; +import greencity.dto.pageble.PageableDto; import greencity.dto.position.AddingPositionDto; import greencity.dto.position.PositionDto; import greencity.dto.tariff.GetTariffInfoForEmployeeDto; import greencity.filters.EmployeeFilterCriteria; import greencity.filters.EmployeePage; -import org.springframework.data.domain.Page; import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -28,7 +28,7 @@ public interface UBSManagementEmployeeService { /** * {@inheritDoc} */ - Page findAll(EmployeePage employeePage, EmployeeFilterCriteria employeeFilterCriteria); + PageableDto findAll(EmployeePage employeePage, EmployeeFilterCriteria employeeFilterCriteria); /** * Method updates information about employee. @@ -51,13 +51,21 @@ public interface UBSManagementEmployeeService { PositionDto update(PositionDto dto); /** - * Method deletes employee from database by id. + * Method deletes employee by id. * * @param id {@link Long} * @author Mykola Danylko */ void deactivateEmployee(Long id); + /** + * Method activate employee by id. + * + * @param id {@link Long} + * @author Oksana Spodaryk + */ + void activateEmployee(Long id); + /** * Method creates new employee position. * diff --git a/service-api/src/test/java/greencity/client/config/UserRemoteClientFallbackFactoryTest.java b/service-api/src/test/java/greencity/client/config/UserRemoteClientFallbackFactoryTest.java index b059fab3f..93f1563b7 100644 --- a/service-api/src/test/java/greencity/client/config/UserRemoteClientFallbackFactoryTest.java +++ b/service-api/src/test/java/greencity/client/config/UserRemoteClientFallbackFactoryTest.java @@ -121,4 +121,10 @@ void deactivateEmployee() { String uuid = "87df9ad5-6393-441f-8423-8b2e770b01a8"; assertThrows(RemoteServerUnavailableException.class, () -> client.deactivateEmployee(uuid)); } + + @Test + void activateEmployee() { + String uuid = "87df9ad5-6393-441f-8423-8b2e770b01a8"; + assertThrows(RemoteServerUnavailableException.class, () -> client.activateEmployee(uuid)); + } } \ No newline at end of file diff --git a/service-api/src/test/java/greencity/dto/CreateAddressRequestDtoTest.java b/service-api/src/test/java/greencity/dto/CreateAddressRequestDtoTest.java new file mode 100644 index 000000000..570192c6d --- /dev/null +++ b/service-api/src/test/java/greencity/dto/CreateAddressRequestDtoTest.java @@ -0,0 +1,92 @@ +package greencity.dto; + +import lombok.SneakyThrows; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import java.util.Set; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +class CreateAddressRequestDtoTest { + + @SneakyThrows + @ParameterizedTest + @MethodSource("provideFieldsAndValidValues") + void validFieldsInAddressDtoTest(String street) { + var dto = CreateAddressRequestDto.builder() + .region("region") + .regionEn("regionEn") + .district("district") + .districtEn("districtEn") + .houseNumber("1") + .city("city") + .cityEn("cityEn") + .street(street) + .streetEn(street) + .build(); + + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + final Validator validator = factory.getValidator(); + + Set> constraintViolations = + validator.validate(dto); + + assertThat(constraintViolations).isEmpty(); + } + + @SneakyThrows + @ParameterizedTest + @MethodSource("provideFieldsAndInvalidValues") + void invalidFieldsInAddressDtoTest(String street) { + var dto = CreateAddressRequestDto.builder() + .region("region") + .regionEn("regionEn") + .district("district") + .districtEn("districtEn") + .houseNumber("1") + .city("city") + .cityEn("cityEn") + .street(street) + .streetEn(street) + .build(); + + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + final Validator validator = factory.getValidator(); + + Set> constraintViolations = + validator.validate(dto); + + assertThat(constraintViolations).hasSize(2); + } + + private static Stream provideFieldsAndValidValues() { + return Stream.of( + Arguments.of("Shevchenka"), + Arguments.of("Шевченка"), + Arguments.of("Shevchenka-Khreschatyk"), + Arguments.of("Шевченка-Хрещатик"), + Arguments.of("Street-Вулиця"), + Arguments.of("Sviatoshins'ka"), + Arguments.of("Святошиньска"), + Arguments.of("Незалежності"), + Arguments.of("їҐґЄє"), + Arguments.of("1-ho Travnya"), + Arguments.of("Protasiv Yar"), + Arguments.of("Протасів Яр")); + } + + private static Stream provideFieldsAndInvalidValues() { + return Stream.of( + Arguments.of("Shevchenka+1"), + Arguments.of("~Шевченка"), + Arguments.of("123"), + Arguments.of("!Хрещатик2")); + } +} diff --git a/service-api/src/test/java/greencity/dto/courier/address/AddressDtoTest.java b/service-api/src/test/java/greencity/dto/address/AddressDtoTest.java similarity index 53% rename from service-api/src/test/java/greencity/dto/courier/address/AddressDtoTest.java rename to service-api/src/test/java/greencity/dto/address/AddressDtoTest.java index 9648e8432..034e3e3ea 100644 --- a/service-api/src/test/java/greencity/dto/courier/address/AddressDtoTest.java +++ b/service-api/src/test/java/greencity/dto/address/AddressDtoTest.java @@ -1,6 +1,5 @@ -package greencity.dto.courier.address; +package greencity.dto.address; -import greencity.dto.address.AddressDto; import lombok.SneakyThrows; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -20,11 +19,13 @@ class AddressDtoTest { @SneakyThrows @ParameterizedTest @MethodSource("provideFieldsAndValidValues") - void validFieldsInAddressDtoTest(String houseNumber, String cityEn) { + void validFieldsInAddressDtoTest(String houseNumber, String cityEn, String street) { var dto = AddressDto.builder() .id(1L) .houseNumber(houseNumber) .cityEn(cityEn) + .street(street) + .streetEn(street) .build(); ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); @@ -39,11 +40,13 @@ void validFieldsInAddressDtoTest(String houseNumber, String cityEn) { @SneakyThrows @ParameterizedTest @MethodSource("provideFieldsAndInvalidValues") - void invalidFieldsInAddressDtoTest(String houseNumber, String cityEn) { + void invalidFieldsInAddressDtoTest(String houseNumber, String cityEn, String street) { var dto = AddressDto.builder() .id(1L) .houseNumber(houseNumber) .cityEn(cityEn) + .street(street) + .streetEn(street) .build(); ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); @@ -52,33 +55,33 @@ void invalidFieldsInAddressDtoTest(String houseNumber, String cityEn) { Set> constraintViolations = validator.validate(dto); - assertThat(constraintViolations).hasSize(2); + assertThat(constraintViolations).hasSize(4); } private static Stream provideFieldsAndValidValues() { return Stream.of( - Arguments.of("1", "Kharkiv"), - Arguments.of("1F", "Kyiv"), - Arguments.of("1B", "Pryp'yat'"), - Arguments.of("1Ї", "Kam'yanets Podilskyi"), - Arguments.of("1-А", "Korsun Shevchenkivskiy"), - Arguments.of("1.Б", "Bila Krynytsya"), - Arguments.of("1 G", "Kam'yanets Podilskyi"), - Arguments.of("ЁёІіЇ", "Bilgorod-Dnistrovskyi"), - Arguments.of("їҐґЄє", "Blagovishchens'k"), - Arguments.of("1/3", "Ternopil'"), - Arguments.of("35/34", "Vinnitsa"), - Arguments.of("35-/34", "Vilnohirs'k"), - Arguments.of("35-/ 34", "Rivne"), - Arguments.of("35-/\"34", "Pereyaslav"), - Arguments.of("14\"o\"", "Zytomyr")); + Arguments.of("1", "Kharkiv", "Shevchenka"), + Arguments.of("1F", "Kyiv", "Шевченка"), + Arguments.of("1B", "Pryp'yat'", "Khreschatyk"), + Arguments.of("1Ї", "Kam'yanets Podilskyi", "Хрещатик"), + Arguments.of("1-А", "Korsun Shevchenkivskiy", "Shevchenka-Khreschatyk"), + Arguments.of("1.Б", "Bila Krynytsya", "Шевченка-Хрещатик"), + Arguments.of("1 G", "Kam'yanets Podilskyi", "Street"), + Arguments.of("ЁёІіЇ", "Bilgorod-Dnistrovskyi", "Вулиця"), + Arguments.of("їҐґЄє", "Blagovishchens'k", "Street-Вулиця"), + Arguments.of("1/3", "Ternopil'", "Sviatoshins'ka"), + Arguments.of("35/34", "Vinnitsa", "Святошиньска"), + Arguments.of("35-/34", "Vilnohirs'k", "Незалежності"), + Arguments.of("35-/ 34", "Rivne", "1-ho Travnya"), + Arguments.of("35-/\"34", "Pereyaslav", "Protasiv Yar"), + Arguments.of("14\"o\"", "Zytomyr", "Протасів Яр")); } private static Stream provideFieldsAndInvalidValues() { return Stream.of( - Arguments.of("", "0Kharkiv"), - Arguments.of("@#$", "kyiv"), - Arguments.of("Testtttttttt", " kharkiv"), - Arguments.of("Тесттттттттт", "-Rivne")); + Arguments.of("", "0Kharkiv", "Shevchenka+1"), + Arguments.of("@#$", "kyiv", "~Шевченка"), + Arguments.of("Testtttttttt", " kharkiv", "+шевченка"), + Arguments.of("Тесттттттттт", "-Rivne", "1234")); } } diff --git a/service-api/src/test/java/greencity/dto/courier/employee/EmployeeWithTariffsIdDtoTest.java b/service-api/src/test/java/greencity/dto/employee/EmployeeWithTariffsIdDtoTest.java similarity index 96% rename from service-api/src/test/java/greencity/dto/courier/employee/EmployeeWithTariffsIdDtoTest.java rename to service-api/src/test/java/greencity/dto/employee/EmployeeWithTariffsIdDtoTest.java index 0f5db2f40..1ecd3d287 100644 --- a/service-api/src/test/java/greencity/dto/courier/employee/EmployeeWithTariffsIdDtoTest.java +++ b/service-api/src/test/java/greencity/dto/employee/EmployeeWithTariffsIdDtoTest.java @@ -1,8 +1,6 @@ -package greencity.dto.courier.employee; +package greencity.dto.employee; import greencity.ModelUtils; -import greencity.dto.employee.EmployeeDto; -import greencity.dto.employee.EmployeeWithTariffsIdDto; import lombok.SneakyThrows; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; diff --git a/service-api/src/test/java/greencity/dto/order/OrderAddressDtoRequestTest.java b/service-api/src/test/java/greencity/dto/order/OrderAddressDtoRequestTest.java new file mode 100644 index 000000000..0cd9b65ed --- /dev/null +++ b/service-api/src/test/java/greencity/dto/order/OrderAddressDtoRequestTest.java @@ -0,0 +1,92 @@ +package greencity.dto.order; + +import lombok.SneakyThrows; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import java.util.Set; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +class OrderAddressDtoRequestTest { + + @SneakyThrows + @ParameterizedTest + @MethodSource("provideFieldsAndValidValues") + void validFieldsInAddressDtoTest(String street) { + var dto = OrderAddressDtoRequest.builder() + .region("region") + .regionEn("regionEn") + .district("district") + .districtEn("districtEn") + .houseNumber("1") + .city("city") + .cityEn("cityEn") + .street(street) + .streetEn(street) + .build(); + + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + final Validator validator = factory.getValidator(); + + Set> constraintViolations = + validator.validate(dto); + + assertThat(constraintViolations).isEmpty(); + } + + @SneakyThrows + @ParameterizedTest + @MethodSource("provideFieldsAndInvalidValues") + void invalidFieldsInAddressDtoTest(String street) { + var dto = OrderAddressDtoRequest.builder() + .region("region") + .regionEn("regionEn") + .district("district") + .districtEn("districtEn") + .houseNumber("1") + .city("city") + .cityEn("cityEn") + .street(street) + .streetEn(street) + .build(); + + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + final Validator validator = factory.getValidator(); + + Set> constraintViolations = + validator.validate(dto); + + assertThat(constraintViolations).hasSize(2); + } + + private static Stream provideFieldsAndValidValues() { + return Stream.of( + Arguments.of("Shevchenka"), + Arguments.of("Шевченка"), + Arguments.of("Shevchenka-Khreschatyk"), + Arguments.of("Шевченка-Хрещатик"), + Arguments.of("Street-Вулиця"), + Arguments.of("Sviatoshins'ka"), + Arguments.of("Святошиньска"), + Arguments.of("Незалежності"), + Arguments.of("їҐґЄє"), + Arguments.of("1-ho Travnya"), + Arguments.of("Protasiv Yar"), + Arguments.of("Протасів Яр")); + } + + private static Stream provideFieldsAndInvalidValues() { + return Stream.of( + Arguments.of("Shevchenka+1"), + Arguments.of("~Шевченка"), + Arguments.of("123"), + Arguments.of("!Хрещатик2")); + } +} diff --git a/service-api/src/test/java/greencity/dto/courier/tariff/AddNewTariffDtoTest.java b/service-api/src/test/java/greencity/dto/tariff/AddNewTariffDtoTest.java similarity index 97% rename from service-api/src/test/java/greencity/dto/courier/tariff/AddNewTariffDtoTest.java rename to service-api/src/test/java/greencity/dto/tariff/AddNewTariffDtoTest.java index 3a77092f7..669f194da 100644 --- a/service-api/src/test/java/greencity/dto/courier/tariff/AddNewTariffDtoTest.java +++ b/service-api/src/test/java/greencity/dto/tariff/AddNewTariffDtoTest.java @@ -1,4 +1,4 @@ -package greencity.dto.courier.tariff; +package greencity.dto.tariff; import greencity.ModelUtils; import greencity.dto.AddNewTariffDto; @@ -12,7 +12,6 @@ import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; -import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Stream; diff --git a/service/src/main/java/greencity/service/locations/LocationApiService.java b/service/src/main/java/greencity/service/locations/LocationApiServiceImpl.java similarity index 63% rename from service/src/main/java/greencity/service/locations/LocationApiService.java rename to service/src/main/java/greencity/service/locations/LocationApiServiceImpl.java index d0beaa163..a26969a5e 100644 --- a/service/src/main/java/greencity/service/locations/LocationApiService.java +++ b/service/src/main/java/greencity/service/locations/LocationApiServiceImpl.java @@ -6,6 +6,7 @@ import greencity.exceptions.NotFoundException; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.EnableCaching; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; @@ -25,8 +26,11 @@ import org.apache.commons.collections4.CollectionUtils; +import org.springframework.cache.annotation.Cacheable; + @Service -public class LocationApiService { +@EnableCaching +public class LocationApiServiceImpl implements LocationApiService { private static final String API_URL = "https://directory.org.ua/api/katottg"; private static final int DEFAULT_PAGE_SIZE = 125; private static final String LEVEL = "level"; @@ -52,25 +56,15 @@ public class LocationApiService { * @param restTemplate An instance of RestTemplate for making HTTP requests. */ @Autowired - public LocationApiService(RestTemplate restTemplate) { + public LocationApiServiceImpl(RestTemplate restTemplate) { this.restTemplate = restTemplate; } /** - * Retrieves all districts in a city by the city's name. There's a special case - * for Kyiv, the capital of Ukraine. In the system, due to the API having - * references only to the previous element, the search for districts occurs - * sequentially: region -> district in region -> local community -> city -> - * district. Generally, the city corresponds to level 4 in the hierarchical - * structure. However, Kyiv is unique in that it is at level 1, and its - * districts are at level 5. Therefore, a separate logic is implemented because - * the system can't go through all the steps from level 1 to level 4, and has to - * directly access the districts from level 5 when dealing with Kyiv. - * - * @param regionName The name of the region. - * @param cityName The name of the city. - * @return A list of LocationDto that represent districts in the city. + * {@inheritDoc} */ + @Override + @Cacheable(value = "districtList", key = "#regionName + '_' + #cityName") public List getAllDistrictsInCityByNames(String regionName, String cityName) { checkIfNotNull(regionName, cityName); regionName = removeWordRegion(regionName); @@ -102,13 +96,11 @@ static String replaceAllQuotes(String input) { } /** - * Retrieves a list of cities by name. - * - * @param regionName The name of the region. - * @param cityName The name of the city. - * @return A list of matching city locations. + * {@inheritDoc} */ - private List getCitiesByName(String regionName, String cityName) { + @Override + @Cacheable(value = "cityList", key = "#regionName + '_' + #cityName ") + public List getCitiesByName(String regionName, String cityName) { List allCities = getLocationDataByName(LocationDivision.CITY.getLevelId(), cityName); if (allCities.isEmpty()) { allCities.add(getCityByNameFromRegionSide(regionName, cityName)); @@ -120,13 +112,11 @@ private List getCitiesByName(String regionName, String cityName) { } /** - * Finds a location by its name. - * - * @param locations The list of locations. - * @param locationName The location name. - * @return A LocationDto matching the provided name. + * {@inheritDoc} */ - private LocationDto findLocationByName(List locations, String locationName) { + @Override + @Cacheable(value = "locationByName", key = "#locations.size() + '_' + #locationName") + public LocationDto findLocationByName(List locations, String locationName) { return locations.stream() .filter(location -> location.getLocationNameMap().containsValue(locationName)) .findFirst() @@ -134,14 +124,11 @@ private LocationDto findLocationByName(List locations, String locat } /** - * Retrieves a city by name from a specified region. - * - * @param regionName The name of the region. - * @param cityName The name of the city. - * @return The LocationDto that represents the city in the specified region. - * @throws NotFoundException if the city is not found. + * {@inheritDoc} */ - private LocationDto getCityByNameFromRegionSide(String regionName, String cityName) { + @Override + @Cacheable(value = "cityByNameFromRegionSide", key = "#regionName + '_' + #cityName ") + public LocationDto getCityByNameFromRegionSide(String regionName, String cityName) { LocationDto region = getRegionByName(regionName); List districts = getAllDistrictInTheRegionsById(region.getId()); List localCommunities = districts.stream() @@ -157,12 +144,11 @@ private LocationDto getCityByNameFromRegionSide(String regionName, String cityNa } /** - * Retrieves a region by name. - * - * @param regionName The name of the region. - * @return The region matching the provided name. + * {@inheritDoc} */ - private LocationDto getRegionByName(String regionName) { + @Override + @Cacheable(value = "regionByName", key = "#regionName") + public LocationDto getRegionByName(String regionName) { List allRegions; try { allRegions = getLocationDataByName(LocationDivision.REGION.getLevelId(), regionName); @@ -180,17 +166,13 @@ private LocationDto getRegionByName(String regionName) { } /** - * Retrieves the city in a specified region. - * - * @param regionName The name of the region. - * @param cities A list of LocationDto that represent cities. - * @return The LocationDto that represents the city in the specified region. - * @throws NotFoundException if the city is not found in the region. + * {@inheritDoc} */ - private LocationDto getCityInRegion(String regionName, List cities) { + @Override + @Cacheable(value = "cityInRegion", key = "#regionName +'_'+#cities.size()") + public LocationDto getCityInRegion(String regionName, List cities) { LocationDto region = getRegionByName(regionName); String regionID = region.getId(); - return cities.stream() .filter(city -> { if (checkIfRegionIdEqualsUpperId(region.getId(), city.getParentId())) { @@ -207,65 +189,56 @@ private LocationDto getCityInRegion(String regionName, List cities) } /** - * Retrieves all regions. - * - * @return A list of LocationDto that represent all regions. + * {@inheritDoc} */ - - private List getAllRegions() { + @Override + @Cacheable(value = "allRegions", key = "allRegions") + public List getAllRegions() { return getLocationDataByLevel(LocationDivision.REGION.getLevelId()); } /** - * Retrieves all cities by their ID. - * - * @param upperId The ID of the city. - * @return A list of LocationDto that represent the cities. + * {@inheritDoc} */ - - private List getAllCitiesById(String upperId) { + @Override + @Cacheable(value = "allCitiesById", key = "#upperId") + public List getAllCitiesById(String upperId) { return getLocationDataByUpperId(LocationDivision.CITY.getLevelId(), upperId); } /** - * Retrieves all districts in the region by the region's ID. - * - * @param upperId The ID of the region. - * @return A list of LocationDto that represent districts in the region. + * {@inheritDoc} */ - private List getAllDistrictInTheRegionsById(String upperId) { + @Override + @Cacheable(value = "allDistrictInTheRegionsById", key = "#upperId") + public List getAllDistrictInTheRegionsById(String upperId) { return getLocationDataByUpperId(LocationDivision.DISTRICT_IN_REGION.getLevelId(), upperId); } /** - * Retrieves all local communities by their ID. - * - * @param upperId The ID of the local community. - * @return A list of LocationDto that represent local communities. + * {@inheritDoc} */ - private List getAllLocalCommunitiesById(String upperId) { + @Override + @Cacheable(value = "allLocalCommunitiesById", key = "#upperId") + public List getAllLocalCommunitiesById(String upperId) { return getLocationDataByUpperId(LocationDivision.LOCAL_COMMUNITY.getLevelId(), upperId); } /** - * Retrieves all districts in a city by the city's ID. - * - * @param upperId The ID of the city. - * @return A list of LocationDto that represent districts in the city. + * {@inheritDoc} */ - private List getAllDistrictsInCityByCityID(String upperId) { + @Override + @Cacheable(value = "allDistrictsInCityByCityID", key = "#upperId") + public List getAllDistrictsInCityByCityID(String upperId) { return getLocationDataByUpperId(LocationDivision.DISTRICT_IN_CITY.getLevelId(), upperId); } /** - * Retrieves location data by level and code. - * - * @param level The hierarchical level of the location. - * @param code The code of the location. - * @return The LocationDto that matches the specified level and code. - * @throws NotFoundException if the location is not found. + * {@inheritDoc} */ - private LocationDto getLocationDataByCode(int level, String code) { + @Override + @Cacheable(value = "locationDataByCode", key = "#level+'_'+#code") + public LocationDto getLocationDataByCode(int level, String code) { UriComponentsBuilder builder = buildUrl() .queryParam(CODE, code) .queryParam(LEVEL, level); @@ -277,29 +250,12 @@ private LocationDto getLocationDataByCode(int level, String code) { return resultFromUrl.get(0); } - private boolean checkIfRegionIdEqualsUpperId(String regionId, String cityUpperId) { - return regionId.equals(cityUpperId); - } - - private static String removeWordRegion(String sentence) { - String withoutSpaces = sentence.replace(" ", ""); - String withoutRegion = withoutSpaces.replaceAll("(?iu)region", ""); - return replaceAllQuotes(withoutRegion.replaceAll("(?iu)область", "")); - } - - private static String removeWordCity(String sentence) { - String withoutSpaces = sentence.replace(" ", ""); - String withoutRegion = withoutSpaces.replaceAll("(?iu)city", ""); - return replaceAllQuotes(withoutRegion.replaceAll("(?iu)місто", "")); - } - /** - * Fetches a list of location data by level. - * - * @param level The level of the location. - * @return A list of LocationDto for the specified level. + * {@inheritDoc} */ - private List getLocationDataByLevel(int level) { + @Override + @Cacheable(value = "locationDataByLevel", key = "#level") + public List getLocationDataByLevel(int level) { UriComponentsBuilder builder = buildUrl().queryParam(LEVEL, level); return getResultFromUrl(builder.build().encode().toUri()); } @@ -312,15 +268,11 @@ private static boolean checkIfNotNull(String... names) { } /** - * Retrieves a list of location data by level and name. - * - * @param level The hierarchical level of the location. - * @param name The name of the location. - * @return A list of LocationDto that matches the specified level and name. - * @throws IllegalArgumentException if the name is null. + * {@inheritDoc} */ - - private List getLocationDataByName(int level, String name) { + @Override + @Cacheable(value = "locationDataByName", key = "#level+'_'+#name") + public List getLocationDataByName(int level, String name) { UriComponentsBuilder builder = buildUrl() .queryParam(NAME, name) .queryParam(LEVEL, level); @@ -328,12 +280,11 @@ private List getLocationDataByName(int level, String name) { } /** - * Extracts location data from a URL. - * - * @param url The URL to retrieve the data from. - * @return A list of LocationDto. + * {@inheritDoc} */ - private List getResultFromUrl(URI url) { + @Override + @Cacheable(value = "resultFromUrl", key = "#url") + public List getResultFromUrl(URI url) { ParameterizedTypeReference> typeRef = new ParameterizedTypeReference>() { }; @@ -348,11 +299,21 @@ private List getResultFromUrl(URI url) { } /** - * Transforms a map into a LocationDto. - * - * @param result The map with location data. - * @return The transformed LocationDto. + * {@inheritDoc} */ + @Override + @Cacheable(value = "locationDataByUpperId", key = "#level+'_'+#upperId") + public List getLocationDataByUpperId(int level, String upperId) { + UriComponentsBuilder builder = buildUrl().queryParam(LEVEL, level) + .queryParam(PARENT, upperId); + return getResultFromUrl(builder.build().encode().toUri()); + } + + private UriComponentsBuilder buildUrl() { + return UriComponentsBuilder.fromHttpUrl(API_URL) + .queryParam(PAGE_SIZE, DEFAULT_PAGE_SIZE); + } + private LocationDto mapToLocationDto(Map result) { Map nameMap = new HashMap<>(); nameMap.put(NAME, getValueFromMap(result, NAME)); @@ -364,40 +325,23 @@ private LocationDto mapToLocationDto(Map result) { .build(); } - /** - * Retrieves a value from a map based on a specified key. - * - * @param The type of the object being returned. - * @param map The map from which to retrieve the value. - * @param key The key associated with the value to retrieve. - * @return The value associated with the specified key. - */ private T getValueFromMap(Map map, String key) { return (T) map.get(key); } - /** - * Retrieves location data by its upper Id. - * - * @param level The hierarchical level of the location. - * @param upperId The upperId associated with the location. - * @return A list of LocationDto associated with the specified upperId. - * @throws IllegalArgumentException if the upperId is null. - */ - private List getLocationDataByUpperId(int level, String upperId) { - UriComponentsBuilder builder = buildUrl().queryParam(LEVEL, level) - .queryParam(PARENT, upperId); - return getResultFromUrl(builder.build().encode().toUri()); + private boolean checkIfRegionIdEqualsUpperId(String regionId, String cityUpperId) { + return regionId.equals(cityUpperId); } - /** - * Constructs a URL using UriComponentsBuilder. - * - * @return A UriComponentsBuilder instance with the API URL, page, and page size - * parameters set. - */ - private UriComponentsBuilder buildUrl() { - return UriComponentsBuilder.fromHttpUrl(API_URL) - .queryParam(PAGE_SIZE, DEFAULT_PAGE_SIZE); + private static String removeWordRegion(String sentence) { + String withoutSpaces = sentence.replace(" ", ""); + String withoutRegion = withoutSpaces.replaceAll("(?iu)region", ""); + return replaceAllQuotes(withoutRegion.replaceAll("(?iu)область", "")); + } + + private static String removeWordCity(String sentence) { + String withoutSpaces = sentence.replace(" ", ""); + String withoutRegion = withoutSpaces.replaceAll("(?iu)city", ""); + return replaceAllQuotes(withoutRegion.replaceAll("(?iu)місто", "")); } } diff --git a/service/src/main/java/greencity/service/notification/NotificationServiceImpl.java b/service/src/main/java/greencity/service/notification/NotificationServiceImpl.java index 8f0cb757f..aff2cf162 100644 --- a/service/src/main/java/greencity/service/notification/NotificationServiceImpl.java +++ b/service/src/main/java/greencity/service/notification/NotificationServiceImpl.java @@ -226,6 +226,18 @@ public void notifyUnpaidOrder(Order order) { } } + /** + * {@inheritDoc} + */ + @Override + public void notifySelfPickupOrder(Order order) { + Set parameters = Set.of(NotificationParameter.builder() + .key(ORDER_NUMBER_KEY) + .value(order.getId().toString()) + .build()); + fillAndSendNotification(parameters, order, NotificationType.ORDER_STATUS_CHANGED); + } + private Double getAmountToPay(Order order) { long bonusesInCoins = order.getPointsToUse() == null ? 0L : order.getPointsToUse() * 100L; long certificatesInCoins = order.getCertificates() == null ? 0L diff --git a/service/src/main/java/greencity/service/ubs/EventServiceImpl.java b/service/src/main/java/greencity/service/ubs/EventServiceImpl.java index 85a1828d0..50535e3a3 100644 --- a/service/src/main/java/greencity/service/ubs/EventServiceImpl.java +++ b/service/src/main/java/greencity/service/ubs/EventServiceImpl.java @@ -15,6 +15,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.HashMap; import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; @@ -45,6 +46,10 @@ public void save(String eventName, String eventAuthor, Order order) { event.setEventDate(LocalDateTime.now()); event.setEventName(eventName); event.setAuthorName(eventAuthor); + event.setEventNameEng(getEventNameEng(eventName)); + event.setAuthorNameEng(getAuthorNameEng(eventAuthor)); + getEventNameEngWithNumbers(eventName, event); + if (order.getEvents() != null) { List events = new ArrayList<>(order.getEvents()); events.add(event); @@ -54,6 +59,49 @@ public void save(String eventName, String eventAuthor, Order order) { eventRepository.save(event); } + private void getEventNameEngWithNumbers(String eventName, Event event) { + if (eventName.startsWith(OrderHistory.ADD_PAYMENT_SYSTEM)) { + event.setEventNameEng( + OrderHistory.ADD_PAYMENT_SYSTEM_ENG + eventName.substring(OrderHistory.ADD_PAYMENT_SYSTEM.length())); + } else if (eventName.startsWith(OrderHistory.DELETE_PAYMENT_MANUALLY)) { + event.setEventNameEng(OrderHistory.DELETE_PAYMENT_MANUALLY_ENG + + eventName.substring(OrderHistory.DELETE_PAYMENT_MANUALLY.length())); + } else if (eventName.startsWith(OrderHistory.UPDATE_PAYMENT_MANUALLY)) { + event.setEventNameEng(OrderHistory.UPDATE_PAYMENT_MANUALLY_ENG + + eventName.substring(OrderHistory.UPDATE_PAYMENT_MANUALLY.length())); + } else if (eventName.startsWith(OrderHistory.ADD_PAYMENT_MANUALLY)) { + event.setEventNameEng(OrderHistory.ADD_PAYMENT_MANUALLY_ENG + + eventName.substring(OrderHistory.ADD_PAYMENT_MANUALLY.length())); + } + } + + private static final Map eventNameToEngMap = new HashMap<>(); + + static { + eventNameToEngMap.put(OrderHistory.ORDER_FORMED, OrderHistory.ORDER_FORMED_ENG); + eventNameToEngMap.put(OrderHistory.ORDER_PAID, OrderHistory.ORDER_PAID_ENG); + eventNameToEngMap.put(OrderHistory.ORDER_ADJUSTMENT, OrderHistory.ORDER_ADJUSTMENT_ENG); + eventNameToEngMap.put(OrderHistory.ORDER_BROUGHT_IT_HIMSELF, OrderHistory.ORDER_BROUGHT_IT_HIMSELF_ENG); + eventNameToEngMap.put(OrderHistory.ORDER_CONFIRMED, OrderHistory.ORDER_CONFIRMED_ENG); + eventNameToEngMap.put(OrderHistory.ORDER_HALF_PAID, OrderHistory.ORDER_HALF_PAID_ENG); + eventNameToEngMap.put(OrderHistory.ADD_ADMIN_COMMENT, OrderHistory.ADD_ADMIN_COMMENT_ENG); + eventNameToEngMap.put(OrderHistory.DELETE_VIOLATION, OrderHistory.DELETE_VIOLATION_ENG); + } + + private static String getEventNameEng(String eventName) { + return eventNameToEngMap.getOrDefault(eventName, eventName); + } + + private static String getAuthorNameEng(String eventAuthor) { + if (OrderHistory.SYSTEM.equals(eventAuthor)) { + return OrderHistory.SYSTEM_ENG; + } else if (OrderHistory.CLIENT.equals(eventAuthor)) { + return OrderHistory.CLIENT_ENG; + } else { + return eventAuthor; + } + } + /** * This method return correct status for changes with Responsible employee. * diff --git a/service/src/main/java/greencity/service/ubs/OrdersAdminsPageServiceImpl.java b/service/src/main/java/greencity/service/ubs/OrdersAdminsPageServiceImpl.java index 947a66e20..3d95813c4 100644 --- a/service/src/main/java/greencity/service/ubs/OrdersAdminsPageServiceImpl.java +++ b/service/src/main/java/greencity/service/ubs/OrdersAdminsPageServiceImpl.java @@ -241,7 +241,7 @@ public ChangeOrderResponseDTO chooseOrdersDataSwitcher(String email, .orElseThrow(() -> new EntityNotFoundException(EMPLOYEE_NOT_FOUND)); switch (columnName) { case ORDER_STATUS: - return createReturnForSwitchChangeOrder(orderStatusForDevelopStage(ordersId, value, employee.getId())); + return createReturnForSwitchChangeOrder(orderStatusForDevelopStage(ordersId, value, employee)); case DATE_OF_EXPORT: return createReturnForSwitchChangeOrder(dateOfExportForDevelopStage(ordersId, value, employee.getId())); case TIME_OF_EXPORT: @@ -454,22 +454,24 @@ private List includeItemsWithoutResponsiblePerson(String nam /* methods for changing order */ @Override - public synchronized List orderStatusForDevelopStage(List ordersId, String value, Long employeeId) { + public synchronized List orderStatusForDevelopStage(List ordersId, String updatedStatusValue, + Employee employee) { List unresolvedGoals = new ArrayList<>(); for (Long orderId : ordersId) { try { Order existedOrder = orderRepository.findById(orderId) .orElseThrow(() -> new EntityNotFoundException(ORDER_WITH_CURRENT_ID_DOES_NOT_EXIST)); - if (isOrderBlockedByAnotherEmployee(existedOrder, employeeId)) { + if (isOrderBlockedByAnotherEmployee(existedOrder, employee.getId())) { throw new IllegalArgumentException(ORDER_IS_BLOCKED + existedOrder.getBlockedByEmployee().getId()); } - if (existedOrder.getOrderStatus().checkPossibleStatus(value)) { - existedOrder.setOrderStatus(OrderStatus.valueOf(value)); + if (existedOrder.getOrderStatus().checkPossibleStatus(updatedStatusValue)) { + existedOrder.setOrderStatus(OrderStatus.valueOf(updatedStatusValue)); removePickUpDetailsAndResponsibleEmployees(existedOrder); } else { throw new BadRequestException( "Such desired status isn't applicable with current status!"); } + if (existedOrder.getOrderStatus() == OrderStatus.CANCELED && (existedOrder.getPointsToUse() != 0 || !existedOrder.getCertificates().isEmpty())) { notificationService.notifyBonusesFromCanceledOrder(existedOrder); @@ -478,6 +480,12 @@ public synchronized List orderStatusForDevelopStage(List ordersId, S existedOrder.setBlocked(false); existedOrder.setBlockedByEmployee(null); orderRepository.save(existedOrder); + + if (OrderStatus.BROUGHT_IT_HIMSELF == OrderStatus.valueOf(updatedStatusValue)) { + eventService.save(OrderHistory.ORDER_BROUGHT_IT_HIMSELF, + employee.getFirstName() + " " + employee.getLastName(), existedOrder); + notificationService.notifySelfPickupOrder(existedOrder); + } } catch (Exception e) { unresolvedGoals.add(orderId); } diff --git a/service/src/main/java/greencity/service/ubs/SuperAdminServiceImpl.java b/service/src/main/java/greencity/service/ubs/SuperAdminServiceImpl.java index 78f3d053f..d98c6e9cc 100644 --- a/service/src/main/java/greencity/service/ubs/SuperAdminServiceImpl.java +++ b/service/src/main/java/greencity/service/ubs/SuperAdminServiceImpl.java @@ -172,7 +172,7 @@ private void deleteBagFromOrder(Order order, Bag bag) { Integer totalBagsAmount = amount.values().stream().reduce(0, Integer::sum); if (amount.get(bagId).equals(0) || order.getOrderPaymentStatus().equals(OrderPaymentStatus.UNPAID)) { if (totalBagsAmount.equals(amount.get(bagId))) { - order.setOrderBags(new ArrayList<>()); + order.updateWithNewOrderBags(new ArrayList<>()); orderRepository.delete(order); return; } @@ -767,7 +767,6 @@ public void setTariffLimits(Long tariffId, SetTariffLimitsDto dto) { tariffsInfo.setMax(dto.getMax()); tariffsInfo.setCourierLimit(dto.getCourierLimit()); tariffsInfo.setLimitDescription(dto.getLimitDescription()); - tariffsInfo.setTariffStatus(getChangedTariffStatus(dto.getMin(), dto.getMax())); tariffsInfoRepository.save(tariffsInfo); } @@ -810,12 +809,6 @@ private Bag changeBagLimitIncluded(BagLimitDto dto, Long tariffId) { return bag; } - private TariffStatus getChangedTariffStatus(Long min, Long max) { - return min != null || max != null - ? TariffStatus.ACTIVE - : TariffStatus.DEACTIVATED; - } - @Override @Transactional public void switchTariffStatus(Long tariffId, String tariffStatus) { diff --git a/service/src/main/java/greencity/service/ubs/UBSClientServiceImpl.java b/service/src/main/java/greencity/service/ubs/UBSClientServiceImpl.java index 02d749e0d..d61167e5d 100644 --- a/service/src/main/java/greencity/service/ubs/UBSClientServiceImpl.java +++ b/service/src/main/java/greencity/service/ubs/UBSClientServiceImpl.java @@ -258,6 +258,7 @@ public class UBSClientServiceImpl implements UBSClientService { private static final String KYIV_REGION_UA = "Київська область"; private static final String KYIV_EN = "Kyiv"; private static final String KYIV_UA = "місто Київ"; + private static final String LANGUAGE_EN = "en"; @Override @Transactional @@ -609,8 +610,10 @@ public OrderWithAddressesResponseDto updateCurrentAddressForOrder(OrderAddressDt List
addresses = addressRepo.findAllNonDeletedAddressesByUserId(currentUser.getId()); if (addressRequestDto.getPlaceId() == null) { - address.setAddressComment(addressRequestDto.getAddressComment()); - addressRepo.save(address); + Address addressWithNullPlaceId = modelMapper.map(addressRequestDto, Address.class); + addressWithNullPlaceId.setUser(currentUser); + addressWithNullPlaceId.setAddressStatus(address.getAddressStatus()); + addressRepo.save(addressWithNullPlaceId); return findAllAddressesForCurrentOrder(uuid); } @@ -1094,7 +1097,7 @@ private Order formAndSaveOrder(Order order, Set orderCertificates, User currentUser, long sumToPayInCoins) { order.setOrderStatus(OrderStatus.FORMED); order.setCertificates(orderCertificates); - order.setOrderBags(bagsOrdered); + order.updateWithNewOrderBags(bagsOrdered); order.setUbsUser(userData); order.setUser(currentUser); order.setSumTotalAmountWithoutDiscounts( @@ -1113,7 +1116,6 @@ private Order formAndSaveOrder(Order order, Set orderCertificates, order.setPayment(new ArrayList<>()); } order.getPayment().add(payment); - bagsOrdered.forEach(orderBag -> orderBag.setOrder(order)); orderRepository.save(order); return order; } @@ -1330,7 +1332,7 @@ public AllPointsUserDto findAllCurrentPointsForUser(String uuid) { * {@inheritDoc} */ @Override - public List getAllEventsForOrder(Long orderId, String email) { + public List getAllEventsForOrder(Long orderId, String email, String language) { Optional order = orderRepository.findById(orderId); if (order.isEmpty()) { throw new NotFoundException(ORDER_WITH_CURRENT_ID_DOES_NOT_EXIST); @@ -1339,6 +1341,16 @@ public List getAllEventsForOrder(Long orderId, String email) { if (orderEvents.isEmpty()) { throw new NotFoundException(EVENTS_NOT_FOUND_EXCEPTION + orderId); } + if (LANGUAGE_EN.equals(language)) { + return orderEvents + .stream() + .peek(event -> { + event.setEventName(event.getEventNameEng()); + event.setAuthorName(event.getAuthorNameEng()); + }) + .map(event -> modelMapper.map(event, EventDto.class)) + .collect(toList()); + } return orderEvents .stream() .map(event -> modelMapper.map(event, EventDto.class)) @@ -1357,7 +1369,6 @@ public UserProfileUpdateDto updateProfileData(String uuid, UserProfileUpdateDto setTelegramAndViberBots(user, userProfileUpdateDto.getTelegramIsNotify(), userProfileUpdateDto.getViberIsNotify()); userProfileUpdateDto.getAddressDto().stream() - .filter(addressDto -> addressDto.getPlaceId() != null) .map(a -> modelMapper.map(a, OrderAddressDtoRequest.class)) .forEach(addressRequestDto -> updateCurrentAddressForOrder(addressRequestDto, uuid)); User savedUser = userRepository.save(user); @@ -1422,22 +1433,6 @@ public OrderCancellationReasonDto getOrderCancellationReason(final Long orderId, .build(); } - @Override - public OrderCancellationReasonDto updateOrderCancellationReason( - long id, OrderCancellationReasonDto dto, String uuid) { - Order order = orderRepository.findById(id) - .orElseThrow(() -> new NotFoundException(ORDER_WITH_CURRENT_ID_DOES_NOT_EXIST)); - if (!order.getUser().equals(userRepository.findByUuid(uuid))) { - throw new AccessDeniedException(CANNOT_ACCESS_ORDER_CANCELLATION_REASON); - } - eventService.saveEvent(OrderHistory.ORDER_CANCELLED, uuid, order); - order.setCancellationReason(dto.getCancellationReason()); - order.setCancellationComment(dto.getCancellationComment()); - order.setId(id); - orderRepository.save(order); - return dto; - } - private long reduceOrderSumDueToUsedPoints(long sumToPayInCoins, int pointsToUse) { if (sumToPayInCoins >= pointsToUse * 100L) { sumToPayInCoins -= pointsToUse * 100L; @@ -1492,8 +1487,9 @@ public void deleteOrder(String uuid, Long id) { if (order == null) { throw new NotFoundException(ORDER_WITH_CURRENT_ID_DOES_NOT_EXIST); } - order.setOrderBags(Collections.emptyList()); - orderRepository.delete(order); + order.updateWithNewOrderBags(Collections.emptyList()); + order.setOrderStatus(OrderStatus.CANCELED); + orderRepository.save(order); } @Override @@ -1504,6 +1500,7 @@ public FondyOrderResponse processOrderFondyClient(OrderFondyClientDto dto, Strin checkForNullCounter(order); long sumToPayInCoins = calculateSumToPay(dto, order, currentUser); + transferUserPointsToOrder(order, dto.getPointsToUse()); paymentVerification(sumToPayInCoins, order); @@ -1963,4 +1960,4 @@ public List getAllDistricts(String region, String city) { return locationDtos.stream().map(p -> modelMapper.map(p, DistrictDto.class)) .collect(Collectors.toList()); } -} \ No newline at end of file +} diff --git a/service/src/main/java/greencity/service/ubs/UBSManagementEmployeeServiceImpl.java b/service/src/main/java/greencity/service/ubs/UBSManagementEmployeeServiceImpl.java index a637cc54a..239ddc34e 100644 --- a/service/src/main/java/greencity/service/ubs/UBSManagementEmployeeServiceImpl.java +++ b/service/src/main/java/greencity/service/ubs/UBSManagementEmployeeServiceImpl.java @@ -4,13 +4,12 @@ import greencity.client.UserRemoteClient; import greencity.constant.AppConstant; import greencity.constant.ErrorMessage; -import greencity.dto.LocationsDtos; -import greencity.dto.courier.GetReceivingStationDto; import greencity.dto.employee.EmployeeWithTariffsIdDto; import greencity.dto.employee.EmployeeSignUpDto; import greencity.dto.employee.EmployeeWithTariffsDto; import greencity.dto.employee.GetEmployeeDto; import greencity.dto.employee.EmployeePositionsDto; +import greencity.dto.pageble.PageableDto; import greencity.dto.position.AddingPositionDto; import greencity.dto.position.PositionDto; import greencity.dto.tariff.GetTariffInfoForEmployeeDto; @@ -41,7 +40,7 @@ import java.util.List; import java.util.ArrayList; import java.util.Map; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.UUID; import java.util.stream.Collectors; @@ -112,108 +111,69 @@ private void signUpEmployee(Employee employee) { * {@inheritDoc} */ @Override - public Page findAll(EmployeePage employeePage, EmployeeFilterCriteria employeeFilterCriteria) { - List employeeFilterViews = - employeeCriteriaRepository.findAll(employeePage, employeeFilterCriteria); - - Map getEmployeeDtoMap = new HashMap<>(); - for (var employeeFilterView : employeeFilterViews) { - var getEmployeeDto = getEmployeeDtoMap.computeIfAbsent( - employeeFilterView.getEmployeeId(), id -> modelMapper.map(employeeFilterView, GetEmployeeDto.class)); - - initializeGetEmployeeDtoCollectionsIfNeeded(getEmployeeDto); - - fillGetEmployeeDto(employeeFilterView, getEmployeeDto); - } - - var resultList = new ArrayList<>(getEmployeeDtoMap.values()); - Sort sort = Sort.by(employeePage.getSortDirection(), employeePage.getSortBy()); - Pageable pageable = PageRequest.of(employeePage.getPageNumber(), - employeePage.getPageSize(), sort); - return new PageImpl<>(resultList, pageable, employeeFilterViews.size()); - } - - private void fillGetEmployeeDto(EmployeeFilterView emplView, GetEmployeeDto getEmployeeDto) { - fillGetTariffInfoForEmployeeDto(emplView, getEmployeeDto); - fillPositionDto(emplView, getEmployeeDto); - } - - private void fillPositionDto(EmployeeFilterView emplView, GetEmployeeDto getEmployeeDto) { - if (isPositionIdAbsent(emplView.getPositionId(), getEmployeeDto)) { - var positionDto = modelMapper.map(emplView, PositionDto.class); - getEmployeeDto.getEmployeePositions().add(positionDto); - } + public PageableDto findAll(EmployeePage employeePage, EmployeeFilterCriteria filterCriteria) { + List employeeFilterViews = employeeCriteriaRepository.findAll(employeePage, filterCriteria); + List resultList = mapEmployeeFilterViewsToGetEmployeeDtos(employeeFilterViews); + Pageable pageable = getPageable(employeePage); + return getAllTranslationDto(new PageImpl<>(resultList, pageable, employeeFilterViews.size())); } - private void fillGetTariffInfoForEmployeeDto(EmployeeFilterView emplView, GetEmployeeDto getEmployeeDto) { - GetTariffInfoForEmployeeDto tariffInfoDto; - if (isMainInfoAboutCurrentTariffAbsent(emplView.getTariffsInfoId(), getEmployeeDto)) { - tariffInfoDto = modelMapper.map(emplView, GetTariffInfoForEmployeeDto.class); - initializeTariffInfoDtoCollections(tariffInfoDto); - fillGetTariffInfoForEmployeeDtoCollections(emplView, tariffInfoDto); - getEmployeeDto.getTariffs().add(tariffInfoDto); - } else { - tariffInfoDto = extractTariffInfoForEmployeeDto(emplView, getEmployeeDto); - fillGetTariffInfoForEmployeeDtoCollections(emplView, tariffInfoDto); + private List mapEmployeeFilterViewsToGetEmployeeDtos(List employeeFilterViews) { + List employees = employeeRepository.findAll(); + Map getEmployeeDtoMap = new LinkedHashMap<>(); + for (var employeeFilterView : employeeFilterViews) { + var getEmployeeDto = getEmployeeDtoMap.computeIfAbsent(employeeFilterView.getEmployeeId(), + id -> modelMapper.map(employeeFilterView, GetEmployeeDto.class)); + initializeGetEmployeeDtoCollections(getEmployeeDto); + fillGetEmployeeDto(employeeFilterView, getEmployeeDto, employees); } + return new ArrayList<>(getEmployeeDtoMap.values()); } - private void fillGetTariffInfoForEmployeeDtoCollections(EmployeeFilterView emplView, - GetTariffInfoForEmployeeDto tariffInfoDto) { - if (isLocationIdAbsent(emplView.getLocationId(), tariffInfoDto)) { - tariffInfoDto.getLocationsDtos().add(modelMapper.map(emplView, LocationsDtos.class)); - } - if (isReceivingStationIdAbsent(emplView.getReceivingStationId(), tariffInfoDto)) { - tariffInfoDto.getReceivingStationDtos().add(modelMapper.map(emplView, GetReceivingStationDto.class)); - } + private Pageable getPageable(EmployeePage employeePage) { + Sort sort = Sort.by(employeePage.getSortDirection(), employeePage.getSortBy()); + return PageRequest.of(employeePage.getPageNumber(), employeePage.getPageSize(), sort); } - private boolean isMainInfoAboutCurrentTariffAbsent(Long tariffInfoId, GetEmployeeDto getEmployeeDto) { - return getEmployeeDto.getTariffs() - .stream() - .noneMatch(tariffInfoDto -> tariffInfoDto.getId().equals(tariffInfoId)); + private void fillGetEmployeeDto(EmployeeFilterView emplView, GetEmployeeDto getEmployeeDto, + List employees) { + fillGetTariffInfoForEmployeeDto(emplView, getEmployeeDto, employees); + fillPositionDto(emplView, getEmployeeDto, employees); } - private static boolean isReceivingStationIdAbsent(Long receivingStationId, - GetTariffInfoForEmployeeDto tariffInfoDto) { - return tariffInfoDto.getReceivingStationDtos() - .stream() - .noneMatch(dto -> dto.getStationId().equals(receivingStationId)); - } + private void fillPositionDto(EmployeeFilterView emplView, GetEmployeeDto getEmployeeDto, List employees) { + List positionsDtos = employees.stream() + .filter(employee -> employee.getId().equals(emplView.getEmployeeId())) + .flatMap(employee -> employee.getEmployeePosition().stream() + .map(position -> modelMapper.map(position, PositionDto.class))) + .collect(Collectors.toList()); - private boolean isLocationIdAbsent(Long locationId, GetTariffInfoForEmployeeDto tariffInfoDto) { - return tariffInfoDto.getLocationsDtos() - .stream() - .noneMatch(locationDto -> locationDto.getLocationId().equals(locationId)); + getEmployeeDto.getEmployeePositions().addAll(positionsDtos); } - private GetTariffInfoForEmployeeDto extractTariffInfoForEmployeeDto(EmployeeFilterView emplView, - GetEmployeeDto getEmployeeDto) { - return getEmployeeDto.getTariffs() - .stream() - .filter(tariffInfoDto -> tariffInfoDto.getId().equals(emplView.getTariffsInfoId())) - .findAny() - .orElseThrow(); - } + private void fillGetTariffInfoForEmployeeDto( + EmployeeFilterView emplView, GetEmployeeDto getEmployeeDto, List employees) { + List tariffsInfoDtos = employees.stream() + .filter(employee -> employee.getId().equals(emplView.getEmployeeId())) + .flatMap(employee -> employee.getTariffInfos().stream() + .map(tariffsInfo -> modelMapper.map(tariffsInfo, GetTariffInfoForEmployeeDto.class))) + .collect(Collectors.toList()); - private void initializeTariffInfoDtoCollections(GetTariffInfoForEmployeeDto tariffInfoDto) { - if (tariffInfoDto.getLocationsDtos() == null || tariffInfoDto.getReceivingStationDtos() == null) { - tariffInfoDto.setLocationsDtos(new ArrayList<>()); - tariffInfoDto.setReceivingStationDtos(new ArrayList<>()); - } + getEmployeeDto.getTariffs().addAll(tariffsInfoDtos); } - private boolean isPositionIdAbsent(Long positionId, GetEmployeeDto getEmployeeDto) { - return getEmployeeDto.getEmployeePositions() - .stream() - .noneMatch(dto -> dto.getId().equals(positionId)); + private void initializeGetEmployeeDtoCollections(GetEmployeeDto getEmployeeDto) { + getEmployeeDto.setEmployeePositions(new ArrayList<>()); + getEmployeeDto.setTariffs(new ArrayList<>()); } - private void initializeGetEmployeeDtoCollectionsIfNeeded(GetEmployeeDto getEmployeeDto) { - if (getEmployeeDto.getEmployeePositions() == null || getEmployeeDto.getTariffs() == null) { - getEmployeeDto.setEmployeePositions(new ArrayList<>()); - getEmployeeDto.setTariffs(new ArrayList<>()); - } + private PageableDto getAllTranslationDto(Page pages) { + List getEmployeeDtos = pages.getContent(); + return new PageableDto<>( + getEmployeeDtos, + pages.getTotalElements(), + pages.getPageable().getPageNumber(), + pages.getTotalPages()); } /** @@ -225,8 +185,8 @@ public EmployeeWithTariffsDto update(EmployeeWithTariffsIdDto dto, MultipartFile final Employee upEmployee = employeeRepository.findById(dto.getEmployeeDto().getId()).orElseThrow( () -> new NotFoundException(ErrorMessage.EMPLOYEE_NOT_FOUND + dto.getEmployeeDto().getId())); - if (!employeeRepository - .findEmployeesByEmailAndIdNot(dto.getEmployeeDto().getEmail(), dto.getEmployeeDto().getId()).isEmpty()) { + if (!employeeRepository.findEmployeesByEmailAndIdNot( + dto.getEmployeeDto().getEmail(), dto.getEmployeeDto().getId()).isEmpty()) { throw new BadRequestException( "Email already exist in another employee: " + dto.getEmployeeDto().getEmail()); } @@ -283,7 +243,26 @@ public void deactivateEmployee(Long id) { try { userRemoteClient.deactivateEmployee(employee.getUuid()); } catch (HystrixRuntimeException e) { - throw new BadRequestException("Employee with current uuid doesn't exist: " + employee.getUuid()); + throw new BadRequestException(ErrorMessage.EMPLOYEE_WITH_UUID_NOT_FOUND + employee.getUuid()); + } + employeeRepository.save(employee); + } + } + + /** + * {@inheritDoc} + */ + @Override + @Transactional + public void activateEmployee(Long id) { + Employee employee = employeeRepository.findById(id) + .orElseThrow(() -> new NotFoundException(ErrorMessage.EMPLOYEE_NOT_FOUND + id)); + if (employee.getEmployeeStatus() == EmployeeStatus.INACTIVE) { + employee.setEmployeeStatus(EmployeeStatus.ACTIVE); + try { + userRemoteClient.activateEmployee(employee.getUuid()); + } catch (HystrixRuntimeException e) { + throw new BadRequestException(ErrorMessage.EMPLOYEE_WITH_UUID_NOT_FOUND + employee.getUuid()); } employeeRepository.save(employee); } @@ -350,8 +329,8 @@ public void deletePosition(Long id) { } private void updateEmployeeEmail(EmployeeWithTariffsIdDto dto, String uuid) { - Employee employee = employeeRepository.findById(dto.getEmployeeDto().getId()) - .orElseThrow(() -> new NotFoundException(ErrorMessage.EMPLOYEE_NOT_FOUND + dto.getEmployeeDto().getId())); + Employee employee = employeeRepository.findById(dto.getEmployeeDto().getId()).orElseThrow( + () -> new NotFoundException(ErrorMessage.EMPLOYEE_NOT_FOUND + dto.getEmployeeDto().getId())); String oldEmail = employee.getEmail(); String newEmail = dto.getEmployeeDto().getEmail(); if (!oldEmail.equals(newEmail)) { diff --git a/service/src/main/java/greencity/service/ubs/UBSManagementServiceImpl.java b/service/src/main/java/greencity/service/ubs/UBSManagementServiceImpl.java index 2c0fbe526..6fc12c2fc 100644 --- a/service/src/main/java/greencity/service/ubs/UBSManagementServiceImpl.java +++ b/service/src/main/java/greencity/service/ubs/UBSManagementServiceImpl.java @@ -110,11 +110,13 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.server.ResponseStatusException; + import javax.persistence.EntityNotFoundException; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collection; @@ -434,7 +436,6 @@ private Boolean isContainsExportedBags(CounterOrderDetailsDto dto) { * * @param address {@link Address}. * @return {@link AddressExportDetailsDto}. - * * @author Yuriy Bahlay. */ private AddressExportDetailsDto getAddressDtoForAdminPage(OrderAddress address) { @@ -466,7 +467,6 @@ private AddressExportDetailsDto getAddressDtoForAdminPage(OrderAddress address) * * @param order {@link Order}. * @return {@link GeneralOrderInfo}. - * * @author Yuriy Bahlay. */ private GeneralOrderInfo getInfoAboutStatusesAndDateFormed(Optional order) { @@ -506,7 +506,6 @@ private GeneralOrderInfo getInfoAboutStatusesAndDateFormed(Optional order * ua and en. * * @return {@link List}. - * * @author Yuriy Bahlay. */ private List getOrderStatusesTranslation() { @@ -538,7 +537,6 @@ private List getOrderStatusesTranslation() { * * @param orderStatusTranslation {@link OrderStatusTranslation}. * @param orderStatusesTranslationDto {@link OrderStatusesTranslationDto}. - * * @author Yuriy Bahlay. */ private void setValueForOrderStatusIsNotTakenOutOrDoneOrCancelledAsTrue( @@ -554,7 +552,6 @@ private void setValueForOrderStatusIsNotTakenOutOrDoneOrCancelledAsTrue( * This is method which is get order payment statuses translation. * * @return {@link List}. - * * @author Yuriy Bahlay. */ private List getOrderPaymentStatusesTranslation() { @@ -618,7 +615,6 @@ public void setOrderDetail(Order order, orderDetailRepository .updateConfirm(entry.getValue(), orderId, entry.getKey().longValue()); - orderDetailRepository.deleteIfConfirmedQuantityIsZero(orderId, entry.getKey().longValue()); } } @@ -632,7 +628,6 @@ public void setOrderDetail(Order order, orderDetailRepository .updateExporter(entry.getValue(), orderId, entry.getKey().longValue()); - orderDetailRepository.deleteIfExportedQuantityIsZero(orderId, entry.getKey().longValue()); } } @@ -648,25 +643,30 @@ private void updatePaymentStatus(Order order, long wasPaidInCoins, long discount Long orderId = order.getId(); if (needToPayInCoins == 0) { + order.setOrderPaymentStatus(OrderPaymentStatus.PAID); orderRepository.updateOrderPaymentStatus(orderId, OrderPaymentStatus.PAID.name()); return; } if (totalPriceInCoins - wasPaidInCoins >= 0 && needToPayInCoins < 0) { + order.setOrderPaymentStatus(OrderPaymentStatus.PAID); orderRepository.updateOrderPaymentStatus(orderId, OrderPaymentStatus.PAID.name()); recalculateCertificates(totalPriceInCoins - wasPaidInCoins, order); return; } if (totalPriceInCoins < wasPaidInCoins) { + order.setOrderPaymentStatus(OrderPaymentStatus.PAID); orderRepository.updateOrderPaymentStatus(orderId, OrderPaymentStatus.PAID.name()); recalculateCertificates(0L, order); return; } if (needToPayInCoins > 0 && wasPaidInCoins + discountInCoins != 0) { + order.setOrderPaymentStatus(OrderPaymentStatus.HALF_PAID); orderRepository.updateOrderPaymentStatus(orderId, OrderPaymentStatus.HALF_PAID.name()); notificationService.notifyHalfPaidPackage(order); return; } if (wasPaidInCoins + discountInCoins == 0) { + order.setOrderPaymentStatus(OrderPaymentStatus.UNPAID); orderRepository.updateOrderPaymentStatus(orderId, OrderPaymentStatus.UNPAID.name()); } } @@ -826,7 +826,7 @@ private CounterOrderDetailsDto getPriceDetails(Long id) { CounterOrderDetailsDto dto = new CounterOrderDetailsDto(); Order order = orderRepository.getOrderDetails(id) .orElseThrow(() -> new NotFoundException(ORDER_WITH_CURRENT_ID_DOES_NOT_EXIST + id)); - List bag = orderBagService.findAllBagsInOrderBagsList(orderBagRepository.findOrderBagsByOrderId(id)); + List bag = orderBagService.findAllBagsInOrderBagsList(order.getOrderBags()); final List currentCertificate = certificateRepository.findCertificate(id); long sumAmountInCoins = 0; @@ -1030,6 +1030,7 @@ public OrderDetailStatusDto updateOrderDetailStatus(Order order, OrderDetailStat eventService.saveEvent(OrderHistory.ORDER_DONE, email, order); } else if (order.getOrderStatus() == OrderStatus.BROUGHT_IT_HIMSELF) { eventService.saveEvent(OrderHistory.ORDER_BROUGHT_IT_HIMSELF, email, order); + notificationService.notifySelfPickupOrder(order); } else if (order.getOrderStatus() == OrderStatus.ON_THE_ROUTE) { eventService.saveEvent(OrderHistory.ORDER_ON_THE_ROUTE, email, order); } @@ -1607,7 +1608,7 @@ public void updateEcoNumberForOrder(EcoNumberDto ecoNumberDto, Order order, Stri && !added.contains("")) { historyChanges.append(collectInfoAboutChangesOfEcoNumber(added, OrderHistory.ADD_NEW_ECO_NUMBER)); added.forEach(newNumber -> { - if (!newNumber.matches("[0-9]+") || newNumber.length() != 10) { + if (!newNumber.matches("\\d{4,10}")) { throw new BadRequestException(INCORRECT_ECO_NUMBER); } order.getAdditionalOrders().add(newNumber); @@ -1680,7 +1681,6 @@ private void updateOrderPageFields(UpdateOrderPageAdminDto updateOrderPageDto, O * @param language {@link String}. * @param email {@link String}. * @param images {@link MultipartFile}. - * * @author Anton Bondar. */ @Override @@ -1689,7 +1689,6 @@ public void updateOrderAdminPageInfoAndSaveReason(Long orderId, UpdateOrderPageA String language, String email, MultipartFile[] images) { Order order = orderRepository.findById(orderId) .orElseThrow(() -> new NotFoundException(ORDER_WITH_CURRENT_ID_DOES_NOT_EXIST + orderId)); - updateOrderAdminPageInfo(updateOrderPageAdminDto, order, language, email); saveReason(order, updateOrderPageAdminDto.getNotTakenOutReason(), images); } @@ -1868,7 +1867,7 @@ private void transferPointsToUser(Order order, User user, long pointsInCoins) { public void updateOrderStatusToExpected() { orderRepository.updateOrderStatusToExpected(OrderStatus.CONFIRMED.name(), OrderStatus.ON_THE_ROUTE.name(), - LocalDate.now()); + LocalDate.now(ZoneId.of("Europe/Kiev"))); } @Override diff --git a/service/src/test/java/greencity/ModelUtils.java b/service/src/test/java/greencity/ModelUtils.java index be8b5de8b..e998d74fa 100644 --- a/service/src/test/java/greencity/ModelUtils.java +++ b/service/src/test/java/greencity/ModelUtils.java @@ -173,6 +173,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -188,6 +189,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; + import static greencity.enums.NotificationReceiverType.EMAIL; import static greencity.enums.NotificationReceiverType.MOBILE; import static greencity.enums.NotificationReceiverType.SITE; @@ -305,6 +307,39 @@ public static List getEmployeeFilterViewListForOneEmployeeWi getEmployeeFilterViewWithPassedIds(employeeId, 7L, tariffsInfoId)); } + public static List getEmployeeListForGetAllMethod() { + return List.of( + Employee.builder() + .id(1L) + .firstName("First Name") + .lastName("Last Name") + .phoneNumber("Phone Number") + .email("employee@gmail.com") + .employeeStatus(EmployeeStatus.ACTIVE) + .employeePosition(new HashSet<>()) + .tariffInfos(new HashSet<>()) + .imagePath("path") + .tariffs(List.of(getTariffInfo())) + .build()); + } + + public static GetEmployeeDto getEmployeeDtoWithoutPositionsAndTariffsForGetAllMethod() { + var getEmployeeDto = getEmployeeDto(); + getEmployeeDto.setEmployeePositions(new ArrayList<>()); + getEmployeeDto.setTariffs(new ArrayList<>()); + return getEmployeeDto; + } + + public static GetEmployeeDto getEmployeeDtoWithPositionsForGetAllMethod() { + var getEmployeeDto = getEmployeeDto(); + getEmployeeDto.setEmployeePositions(List.of( + getPositionDto(3L), + getPositionDto(5L), + getPositionDto(7L))); + getEmployeeDto.setTariffs(new ArrayList<>()); + return getEmployeeDto; + } + public static GetEmployeeDto getEmployeeDtoWithPositionsAndTariffs() { var getEmployeeDto = getEmployeeDto(); @@ -534,6 +569,7 @@ public static ChangeOfPoints getChangeOfPoints() { public static Order getOrder() { return Order.builder() .id(1L) + .orderDate(LocalDateTime.of(2023, 10, 20, 14, 58)) .payment(Lists.newArrayList(Payment.builder() .id(1L) .paymentId("1") @@ -1505,6 +1541,32 @@ public static List addressDtoList() { return list; } + public static List addressDtoListWithNullPlaceId() { + List list = new ArrayList<>(); + list.add(AddressDto.builder() + .id(1L) + .entranceNumber("7a") + .houseCorpus("2") + .houseNumber("7") + .street("Gorodotska") + .coordinates(Coordinates.builder().latitude(2.3).longitude(5.6).build()) + .district("Zaliznuchnuy") + .city("Lviv") + .actual(false) + .build()); + list.add(AddressDto.builder().id(2L) + .entranceNumber("9a") + .houseCorpus("2") + .houseNumber("7") + .street("Shevchenka") + .coordinates(Coordinates.builder().latitude(3.3).longitude(6.6).build()) + .district("Zaliznuchnuy") + .city("Lviv") + .actual(false) + .build()); + return list; + } + public static UserProfileDto userProfileDto() { return UserProfileDto.builder() .recipientName("Dima") @@ -1851,6 +1913,14 @@ public static Position getPosition() { .build(); } + public static Position getPosition(Long id) { + return Position.builder() + .id(id) + .name("Водій") + .nameEn("Driver") + .build(); + } + public static PositionDto getPositionDto(Long id) { return PositionDto.builder() .id(id) @@ -1949,6 +2019,21 @@ public static Payment getPayment() { .build(); } + public static Payment getPayment2() { + return Payment.builder() + .id(1L) + .paymentStatus(PaymentStatus.PAID) + .amount(0L) + .currency("UAH") + .orderStatus("approved") + .responseStatus("approved") + .order(getOrder()) + .paymentId("1") + .settlementDate(LocalDate.now().toString()) + .fee(0L) + .build(); + } + public static User getUser() { return User.builder() .id(1L) @@ -2091,7 +2176,7 @@ public static Order getFormedOrder() { return Order.builder() .id(1L) .events(List.of(new Event(1L, LocalDateTime.now(), - "Roman", "Roman", new Order()))) + "Roman", "Roman", "Roman", "Roman", new Order()))) .orderStatus(OrderStatus.FORMED) .payment(singletonList(Payment.builder() .id(1L) @@ -2113,7 +2198,7 @@ public static Order getCanceledPaidOrder() { return Order.builder() .id(1L) .events(List.of(new Event(1L, LocalDateTime.now(), - "Roman", "Roman", new Order()))) + "Roman", "Roman", "Roman", "Roman", new Order()))) .orderStatus(OrderStatus.CANCELED) .payment(singletonList(Payment.builder() .id(1L) @@ -2135,7 +2220,7 @@ public static Order getAdjustmentPaidOrder() { return Order.builder() .id(1L) .events(List.of(new Event(1L, LocalDateTime.now(), - "Roman", "Roman", new Order()))) + "Roman", "Roman", "Roman", "Roman", new Order()))) .orderStatus(OrderStatus.ADJUSTMENT) .payment(singletonList(Payment.builder() .id(1L) @@ -2157,7 +2242,7 @@ public static Order getFormedHalfPaidOrder() { return Order.builder() .id(1L) .events(List.of(new Event(1L, LocalDateTime.now(), - "Roman", "Roman", new Order()))) + "Roman", "Roman", "Roman", "Roman", new Order()))) .orderStatus(OrderStatus.FORMED) .payment(singletonList(Payment.builder() .id(1L) @@ -2179,7 +2264,7 @@ public static Order getCanceledHalfPaidOrder() { return Order.builder() .id(1L) .events(List.of(new Event(1L, LocalDateTime.now(), - "Roman", "Roman", new Order()))) + "Roman", "Roman", "Roman", "Roman", new Order()))) .orderStatus(OrderStatus.CANCELED) .payment(singletonList(Payment.builder() .id(1L) @@ -4703,6 +4788,25 @@ public static OrderAddressDtoRequest getTestOrderAddressDtoRequest() { .build(); } + public static OrderAddressDtoRequest getTestOrderAddressDtoRequestWithNullPlaceId() { + return OrderAddressDtoRequest.builder() + .id(0L) + .region("fake region") + .searchAddress("fake street name, 13, fake street, 02000") + .city("fake street") + .district("Район") + .districtEn("District") + .entranceNumber("1") + .houseNumber("13") + .houseCorpus("1") + .street("fake street name") + .streetEn("fake street name") + .coordinates(new Coordinates(50.5555555d, 50.5555555d)) + .cityEn("fake street") + .regionEn("fake region") + .build(); + } + public static OrderAddressDtoRequest getTestOrderAddressLocationDto() { return getTestOrderAddressLocationDto(true); } @@ -5198,4 +5302,4 @@ public static PositionWithTranslateDto getPositionWithTranslateDto(Long id) { public static Refund getRefund(Long id) { return Refund.builder().orderId(id).build(); } -} \ No newline at end of file +} diff --git a/service/src/test/java/greencity/service/locations/LocationApiServiceTest.java b/service/src/test/java/greencity/service/locations/LocationApiServiceTest.java index dec417acd..569bc32da 100644 --- a/service/src/test/java/greencity/service/locations/LocationApiServiceTest.java +++ b/service/src/test/java/greencity/service/locations/LocationApiServiceTest.java @@ -42,8 +42,9 @@ class LocationApiServiceTest { private static final String PARENT = "parent"; private static final String PARENT_ID = "parent_id"; private static final String RESULTS = "results"; + @InjectMocks - LocationApiService locationApiService; + LocationApiServiceImpl locationApiService; @Mock RestTemplate restTemplate; diff --git a/service/src/test/java/greencity/service/notification/NotificationServiceImplTest.java b/service/src/test/java/greencity/service/notification/NotificationServiceImplTest.java index 83f4ab80b..12466b288 100644 --- a/service/src/test/java/greencity/service/notification/NotificationServiceImplTest.java +++ b/service/src/test/java/greencity/service/notification/NotificationServiceImplTest.java @@ -667,4 +667,30 @@ void createNotificationDtoTitleEnLanguageTest() { assertEquals(TEST_NOTIFICATION_TEMPLATE.getTitleEng(), result.getTitle()); } + @Test + void notifySelfPickupOrderTest() { + User user = getUser(); + Long orderId = 2L; + Order order = Order.builder() + .id(orderId) + .user(user) + .build(); + UserNotification notification = new UserNotification(); + notification.setNotificationType(NotificationType.ORDER_STATUS_CHANGED); + notification.setUser(user); + notification.setOrder(order); + Set parameters = Set.of(NotificationParameter.builder() + .key("orderNumber") + .value(orderId.toString()) + .userNotification(notification) + .build()); + + when(userNotificationRepository.save(any())).thenReturn(notification); + when(notificationParameterRepository.saveAll(any())).thenReturn(new ArrayList<>(parameters)); + + notificationService.notifySelfPickupOrder(order); + + verify(userNotificationRepository).save(notification); + verify(notificationParameterRepository).saveAll(parameters); + } } diff --git a/service/src/test/java/greencity/service/ubs/EventServiceImplTest.java b/service/src/test/java/greencity/service/ubs/EventServiceImplTest.java index 7262fa075..5c9363e5f 100644 --- a/service/src/test/java/greencity/service/ubs/EventServiceImplTest.java +++ b/service/src/test/java/greencity/service/ubs/EventServiceImplTest.java @@ -8,12 +8,17 @@ import greencity.service.ubs.EventServiceImpl; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.MethodSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import java.util.Arrays; import java.util.Optional; +import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; @@ -46,6 +51,59 @@ void saveEmptyEventTest() { verify(eventRepository, times(0)).save(any()); } + @Test + void testSaveEventEng() { + String eventAuthorSystem = "Система"; + String eventAuthorClient = "Клієнт"; + Order order = ModelUtils.getOrder(); + order.setEvents(Arrays.asList(ModelUtils.getListOfEvents().get(0), + ModelUtils.getListOfEvents().get(1))); + when(eventRepository.save(any())).thenReturn(ModelUtils.getListOfEvents().get(0)); + + eventService.save(OrderHistory.ORDER_FORMED, eventAuthorSystem, order); + eventService.save(OrderHistory.ORDER_PAID, eventAuthorClient, order); + eventService.save(OrderHistory.ADD_PAYMENT_SYSTEM, eventAuthorSystem, order); + eventService.save(OrderHistory.ORDER_ADJUSTMENT, eventAuthorSystem, order); + eventService.save(OrderHistory.ORDER_CONFIRMED, eventAuthorSystem, order); + + assertEquals("Order Status - Formed", OrderHistory.ORDER_FORMED_ENG); + assertEquals("System", OrderHistory.SYSTEM_ENG); + assertEquals("Client", OrderHistory.CLIENT_ENG); + assertEquals("Order Paid", OrderHistory.ORDER_PAID_ENG); + assertEquals("Added payment №", OrderHistory.ADD_PAYMENT_SYSTEM_ENG); + assertEquals("Added payment №", OrderHistory.ADD_PAYMENT_SYSTEM_ENG); + assertEquals("Order Status - Approval", OrderHistory.ORDER_ADJUSTMENT_ENG); + assertEquals("Order Status - Confirmed", OrderHistory.ORDER_CONFIRMED_ENG); + verify(eventRepository, times(5)).save(any()); + } + + @Test + void testSaveEventEngWithUserName() { + String userName = "Test"; + Order order = ModelUtils.getOrder(); + order.setEvents(Arrays.asList(ModelUtils.getListOfEvents().get(0), + ModelUtils.getListOfEvents().get(1))); + when(eventRepository.save(any())).thenReturn(ModelUtils.getListOfEvents().get(0)); + + eventService.save(OrderHistory.DELETE_PAYMENT_MANUALLY, userName, order); + eventService.save(OrderHistory.ORDER_BROUGHT_IT_HIMSELF, userName, order); + eventService.save(OrderHistory.UPDATE_PAYMENT_MANUALLY, userName, order); + eventService.save(OrderHistory.ORDER_HALF_PAID, userName, order); + eventService.save(OrderHistory.ADD_PAYMENT_MANUALLY, userName, order); + eventService.save(OrderHistory.ADD_ADMIN_COMMENT, userName, order); + eventService.save(OrderHistory.DELETE_VIOLATION, userName, order); + + assertEquals("Payment removed №", OrderHistory.DELETE_PAYMENT_MANUALLY_ENG); + assertEquals("Order status - Will bring it myself", OrderHistory.ORDER_BROUGHT_IT_HIMSELF_ENG); + assertEquals("Payment details changed № ", OrderHistory.UPDATE_PAYMENT_MANUALLY_ENG); + assertEquals("Order partially paid", OrderHistory.ORDER_HALF_PAID_ENG); + assertEquals("Added payment №", OrderHistory.ADD_PAYMENT_MANUALLY_ENG); + assertEquals("Comment added", OrderHistory.ADD_ADMIN_COMMENT_ENG); + assertEquals("Violation removed", OrderHistory.DELETE_VIOLATION_ENG); + + verify(eventRepository, times(7)).save(any()); + } + @Test void changesWithResponsibleEmployeeTest() { String existedCallManager = eventService.changesWithResponsibleEmployee(2L, Boolean.TRUE); diff --git a/service/src/test/java/greencity/service/ubs/OrdersAdminsPageServiceImplTest.java b/service/src/test/java/greencity/service/ubs/OrdersAdminsPageServiceImplTest.java index ebf8f0dab..df9817d00 100644 --- a/service/src/test/java/greencity/service/ubs/OrdersAdminsPageServiceImplTest.java +++ b/service/src/test/java/greencity/service/ubs/OrdersAdminsPageServiceImplTest.java @@ -524,7 +524,7 @@ void orderStatusForDevelopStage(String oldStatus, String newStatus) { when(orderRepository.findById(1L)).thenReturn(Optional.of(order)); - ordersAdminsPageService.orderStatusForDevelopStage(List.of(1L), newStatus, 1L); + ordersAdminsPageService.orderStatusForDevelopStage(List.of(1L), newStatus, ModelUtils.getEmployee()); assertNotNull(order.getDateOfExport()); assertNotNull(order.getDeliverFrom()); @@ -535,6 +535,28 @@ void orderStatusForDevelopStage(String oldStatus, String newStatus) { verify(orderRepository).save(order); } + @Test + void orderStatusForDevelopStageChangeStatusToBroughtItHimselfTest() { + String newStatus = "BROUGHT_IT_HIMSELF"; + Order saved = ModelUtils.getOrder(); + saved.setOrderStatus(OrderStatus.FORMED); + + Order expected = ModelUtils.getOrder(); + expected.setOrderStatus(OrderStatus.BROUGHT_IT_HIMSELF); + expected.setDateOfExport(null); + expected.setDeliverFrom(null); + expected.setDeliverTo(null); + expected.setReceivingStation(null); + + when(orderRepository.findById(1L)).thenReturn(Optional.of(saved)); + + ordersAdminsPageService.orderStatusForDevelopStage(List.of(1L), newStatus, ModelUtils.getEmployee()); + + verify(eventService).save(eq(OrderHistory.ORDER_BROUGHT_IT_HIMSELF), anyString(), any(Order.class)); + verify(notificationService).notifySelfPickupOrder(expected); + verify(orderRepository).save(expected); + } + @ParameterizedTest @CsvSource({ "CONFIRMED, FORMED", @@ -556,7 +578,7 @@ void orderStatusForDevelopStageErasedPickUpDetailsAndResponsibleEmployees(String when(orderRepository.findById(1L)).thenReturn(Optional.of(order)); - ordersAdminsPageService.orderStatusForDevelopStage(List.of(1L), newStatus, 1L); + ordersAdminsPageService.orderStatusForDevelopStage(List.of(1L), newStatus, ModelUtils.getEmployee()); verify(orderRepository).save(order); } @@ -565,7 +587,7 @@ void orderStatusForDevelopStageErasedPickUpDetailsAndResponsibleEmployees(String void orderStatusForDevelopStageEntityNotFoundException() { when(orderRepository.findById(1L)).thenReturn(Optional.empty()); assertEquals(List.of(1L), - ordersAdminsPageService.orderStatusForDevelopStage(List.of(1L), "", 1L)); + ordersAdminsPageService.orderStatusForDevelopStage(List.of(1L), "", ModelUtils.getEmployee())); } @Test @@ -573,7 +595,7 @@ void orderStatusForDevelopStageBadOrderStatusRequestException() { when(orderRepository.findById(1L)) .thenReturn(Optional.of(ModelUtils.getOrder().setOrderStatus(OrderStatus.FORMED))); assertEquals(List.of(1L), - ordersAdminsPageService.orderStatusForDevelopStage(List.of(1L), "DONE", 1L)); + ordersAdminsPageService.orderStatusForDevelopStage(List.of(1L), "DONE", ModelUtils.getEmployee())); } @Test @@ -581,7 +603,6 @@ void orderStatusForDevelopStageBlockedByAnotherEmployeeThrowExceptionTest() { var orderId = 1L; var ordersId = List.of(orderId); var newValue = "CONFIRMED"; - var employeeId = 3L; var anotherEmployeeId = 4L; var order = Order.builder() @@ -593,7 +614,7 @@ void orderStatusForDevelopStageBlockedByAnotherEmployeeThrowExceptionTest() { when(orderRepository.findById(orderId)).thenReturn(Optional.of(order)); - var result = ordersAdminsPageService.orderStatusForDevelopStage(ordersId, newValue, employeeId); + var result = ordersAdminsPageService.orderStatusForDevelopStage(ordersId, newValue, ModelUtils.getEmployee()); verify(orderRepository).findById(orderId); verify(orderRepository, never()).save(any(Order.class)); diff --git a/service/src/test/java/greencity/service/ubs/SuperAdminServiceImplTest.java b/service/src/test/java/greencity/service/ubs/SuperAdminServiceImplTest.java index 994107bba..a856c8256 100644 --- a/service/src/test/java/greencity/service/ubs/SuperAdminServiceImplTest.java +++ b/service/src/test/java/greencity/service/ubs/SuperAdminServiceImplTest.java @@ -254,7 +254,7 @@ void deleteTariffServiceWhenThereAreMoreThan1TypeOfBag() { Bag bagDeleted = ModelUtils.getBagDeleted(); TariffsInfo tariffsInfo = ModelUtils.getTariffInfo(); Order order = ModelUtils.getOrder(); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag(), ModelUtils.getOrderBag2())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag(), ModelUtils.getOrderBag2())); when(bagRepository.findActiveBagById(1)).thenReturn(Optional.of(bag)); when(bagRepository.save(bag)).thenReturn(bagDeleted); when(bagRepository.findAllActiveBagsByTariffsInfoId(1L)).thenReturn(List.of(bag, getBag2())); @@ -288,7 +288,7 @@ void deleteTariffServiceWhenTariffBagsWithLimits() { Bag bagDeleted = ModelUtils.getBagDeleted(); TariffsInfo tariffsInfo = ModelUtils.getTariffInfo(); Order order = ModelUtils.getOrder(); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); Map hashMap = new HashMap<>(); hashMap.put(1, 1); when(bagRepository.findActiveBagById(1)).thenReturn(Optional.of(bag)); @@ -361,7 +361,7 @@ void editTariffServiceWithUnpaidOrder() { GetTariffServiceDto editedDto = ModelUtils.getGetTariffServiceDto(); Order order = ModelUtils.getOrder(); String uuid = UUID.randomUUID().toString(); - order.setOrderBags(List.of(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(List.of(ModelUtils.getOrderBag())); when(employeeRepository.findByUuid(uuid)).thenReturn(Optional.of(employee)); when(bagRepository.findActiveBagById(1)).thenReturn(Optional.of(bag)); @@ -397,7 +397,7 @@ void editTariffServiceWithUnpaidOrderAndBagConfirmedAmount() { GetTariffServiceDto editedDto = ModelUtils.getGetTariffServiceDto(); Order order = ModelUtils.getOrder(); String uuid = UUID.randomUUID().toString(); - order.setOrderBags(List.of(ModelUtils.getOrderBagWithConfirmedAmount())); + order.updateWithNewOrderBags(List.of(ModelUtils.getOrderBagWithConfirmedAmount())); when(employeeRepository.findByUuid(uuid)).thenReturn(Optional.of(employee)); when(bagRepository.findActiveBagById(1)).thenReturn(Optional.of(bag)); @@ -433,7 +433,7 @@ void editTariffServiceWithUnpaidOrderAndBagExportedAmount() { GetTariffServiceDto editedDto = ModelUtils.getGetTariffServiceDto(); Order order = ModelUtils.getOrder(); String uuid = UUID.randomUUID().toString(); - order.setOrderBags(List.of(ModelUtils.getOrderBagWithExportedAmount())); + order.updateWithNewOrderBags(List.of(ModelUtils.getOrderBagWithExportedAmount())); when(employeeRepository.findByUuid(uuid)).thenReturn(Optional.of(employee)); when(bagRepository.findActiveBagById(1)).thenReturn(Optional.of(bag)); diff --git a/service/src/test/java/greencity/service/ubs/UBSClientServiceImplTest.java b/service/src/test/java/greencity/service/ubs/UBSClientServiceImplTest.java index 7dc225a97..e475f2b90 100644 --- a/service/src/test/java/greencity/service/ubs/UBSClientServiceImplTest.java +++ b/service/src/test/java/greencity/service/ubs/UBSClientServiceImplTest.java @@ -8,7 +8,6 @@ import greencity.dto.OrderCourierPopUpDto; import greencity.dto.TariffsForLocationDto; import greencity.dto.address.AddressDto; - import greencity.dto.bag.BagDto; import greencity.dto.bag.BagForUserDto; import greencity.dto.bag.BagOrderDto; @@ -43,7 +42,15 @@ import greencity.dto.user.UserProfileDto; import greencity.dto.user.UserProfileUpdateDto; import greencity.entity.coords.Coordinates; -import greencity.entity.order.*; +import greencity.entity.order.Bag; +import greencity.entity.order.Certificate; +import greencity.entity.order.Event; +import greencity.entity.order.Order; +import greencity.entity.order.OrderBag; +import greencity.entity.order.OrderPaymentStatusTranslation; +import greencity.entity.order.OrderStatusTranslation; +import greencity.entity.order.Payment; +import greencity.entity.order.TariffsInfo; import greencity.entity.telegram.TelegramBot; import greencity.entity.user.User; import greencity.entity.user.employee.Employee; @@ -121,12 +128,12 @@ import static greencity.ModelUtils.KYIV_REGION_EN; import static greencity.ModelUtils.KYIV_REGION_UA; import static greencity.ModelUtils.TEST_BAG_FOR_USER_DTO; -import static greencity.ModelUtils.TEST_BAG_LIST; import static greencity.ModelUtils.TEST_EMAIL; import static greencity.ModelUtils.TEST_ORDER_ADDRESS_DTO_REQUEST; import static greencity.ModelUtils.TEST_PAYMENT_LIST; import static greencity.ModelUtils.addressDto; import static greencity.ModelUtils.addressDtoList; +import static greencity.ModelUtils.addressDtoListWithNullPlaceId; import static greencity.ModelUtils.addressList; import static greencity.ModelUtils.addressWithEmptyPlaceIdDto; import static greencity.ModelUtils.addressWithKyivRegionDto; @@ -137,6 +144,7 @@ import static greencity.ModelUtils.getAddressDtoResponse; import static greencity.ModelUtils.getAddressRequestDto; import static greencity.ModelUtils.getAddressRequestToSaveDto; +import static greencity.ModelUtils.getAddressRequestToSaveDto_WithoutDistricts; import static greencity.ModelUtils.getAddressRequestWithEmptyPlaceIdDto; import static greencity.ModelUtils.getAddressRequestWithEmptyPlaceIdToSaveDto; import static greencity.ModelUtils.getAddressWithKyivRegionRequestDto; @@ -149,7 +157,6 @@ import static greencity.ModelUtils.getCancellationDto; import static greencity.ModelUtils.getCertificate; import static greencity.ModelUtils.getCourier; -import static greencity.ModelUtils.getAddressRequestToSaveDto_WithoutDistricts; import static greencity.ModelUtils.getCourierDto; import static greencity.ModelUtils.getCourierDtoList; import static greencity.ModelUtils.getEmployee; @@ -188,6 +195,7 @@ import static greencity.ModelUtils.getTariffsInfo; import static greencity.ModelUtils.getTelegramBotNotifyTrue; import static greencity.ModelUtils.getTestOrderAddressDtoRequest; +import static greencity.ModelUtils.getTestOrderAddressDtoRequestWithNullPlaceId; import static greencity.ModelUtils.getTestOrderAddressLocationDto; import static greencity.ModelUtils.getTestUser; import static greencity.ModelUtils.getUBSuser; @@ -204,7 +212,6 @@ import static greencity.ModelUtils.getUserWithBotNotifyTrue; import static greencity.ModelUtils.getUserWithLastLocation; import static greencity.ModelUtils.getViberBotNotifyTrue; - import static greencity.constant.ErrorMessage.ACTUAL_ADDRESS_NOT_FOUND; import static greencity.constant.ErrorMessage.ADDRESS_ALREADY_EXISTS; import static greencity.constant.ErrorMessage.CANNOT_ACCESS_PERSONAL_INFO; @@ -220,6 +227,7 @@ import static greencity.constant.ErrorMessage.TARIFF_NOT_FOUND; import static greencity.constant.ErrorMessage.TARIFF_OR_LOCATION_IS_DEACTIVATED; import static greencity.constant.ErrorMessage.USER_WITH_CURRENT_UUID_DOES_NOT_EXIST; +import static java.util.stream.Collectors.toList; import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -781,7 +789,7 @@ void testSaveToDB() throws IllegalAccessException { } } tariffsInfo.setBags(Arrays.asList(bag)); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); when(userRepository.findByUuid("35467585763t4sfgchjfuyetf")).thenReturn(user); when(tariffsInfoRepository.findTariffsInfoByBagIdAndLocationId(anyList(), anyLong())) .thenReturn(Optional.of(tariffsInfo)); @@ -834,7 +842,7 @@ void testSaveToDB_AddressNotEqualsUsers() throws IllegalAccessException { } } tariffsInfo.setBags(Arrays.asList(bag)); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); when(userRepository.findByUuid("35467585763t4sfgchjfuyetf")).thenReturn(user.setId(null), user); when(tariffsInfoRepository.findTariffsInfoByBagIdAndLocationId(anyList(), anyLong())) .thenReturn(Optional.of(tariffsInfo)); @@ -887,7 +895,7 @@ void testSaveToDB_AddressStatusDeleted() throws IllegalAccessException { } } tariffsInfo.setBags(Arrays.asList(bag)); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); when(userRepository.findByUuid("35467585763t4sfgchjfuyetf")).thenReturn(user.setId(null), user); when(tariffsInfoRepository.findTariffsInfoByBagIdAndLocationId(anyList(), anyLong())) .thenReturn(Optional.of(tariffsInfo)); @@ -936,9 +944,11 @@ void testSaveToDBWithTwoBags() throws IllegalAccessException { Payment payment1 = getPayment(); payment1.setId(1L); order1.getPayment().add(payment1); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag(), ModelUtils.getOrderBag(), ModelUtils.getOrderBag())); + order.updateWithNewOrderBags( + Arrays.asList(ModelUtils.getOrderBag(), ModelUtils.getOrderBag(), ModelUtils.getOrderBag())); order1 - .setOrderBags(Arrays.asList(ModelUtils.getOrderBag(), ModelUtils.getOrderBag(), ModelUtils.getOrderBag())); + .updateWithNewOrderBags( + Arrays.asList(ModelUtils.getOrderBag(), ModelUtils.getOrderBag(), ModelUtils.getOrderBag())); Field[] fields = UBSClientServiceImpl.class.getDeclaredFields(); for (Field f : fields) { if (f.getName().equals("merchantId")) { @@ -1134,7 +1144,7 @@ void testSaveToDbThrowBadRequestExceptionPriceLowerThanLimit() throws IllegalAcc dto.getBags().get(0).setAmount(1); Bag bag = getBagForOrder(); Order order = getOrder(); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); TariffsInfo tariffsInfo = getTariffInfo(); tariffsInfo.setBags(Arrays.asList(bag)); user.setOrders(new ArrayList<>()); @@ -1371,7 +1381,7 @@ void saveToDBFailPaidOrder() { dto.getBags().get(0).setAmount(5); Order order = getOrder(); order.setOrderPaymentStatus(OrderPaymentStatus.PAID); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); Bag bag = getBagForOrder(); TariffsInfo tariffsInfo = getTariffInfo(); @@ -1822,14 +1832,22 @@ void updateProfileDataWhenAddressPlaceIdIsNull() { User user = getUserWithBotNotifyTrue(); TelegramBot telegramBot = getTelegramBotNotifyTrue(); ViberBot viberBot = getViberBotNotifyTrue(); + List addressDto = addressDtoListWithNullPlaceId(); + UserProfileUpdateDto userProfileUpdateDto = getUserProfileUpdateDto(); userProfileUpdateDto.getAddressDto().get(0).setPlaceId(null); userProfileUpdateDto.getAddressDto().get(1).setPlaceId(null); + String uuid = UUID.randomUUID().toString(); + OrderAddressDtoRequest updateAddressRequestDto = getTestOrderAddressDtoRequestWithNullPlaceId(); when(userRepository.findUserByUuid(uuid)).thenReturn(Optional.of(user)); when(telegramBotRepository.findByUser(user)).thenReturn(Optional.of(telegramBot)); when(viberBotRepository.findByUser(user)).thenReturn(Optional.of(viberBot)); + when(modelMapper.map(addressDto.get(0), OrderAddressDtoRequest.class)).thenReturn(updateAddressRequestDto); + when(modelMapper.map(addressDto.get(1), OrderAddressDtoRequest.class)).thenReturn(updateAddressRequestDto); + doReturn(new OrderWithAddressesResponseDto()).when(ubsClientService) + .updateCurrentAddressForOrder(updateAddressRequestDto, uuid); when(userRepository.save(user)).thenReturn(user); when(modelMapper.map(user, UserProfileUpdateDto.class)).thenReturn(userProfileUpdateDto); @@ -1838,8 +1856,9 @@ void updateProfileDataWhenAddressPlaceIdIsNull() { verify(userRepository).findUserByUuid(uuid); verify(telegramBotRepository).findByUser(user); verify(viberBotRepository).findByUser(user); - verify(modelMapper, times(0)).map(any(), any(OrderAddressDtoRequest.class)); - verify(ubsClientService, times(0)).updateCurrentAddressForOrder(any(), anyString()); + verify(modelMapper).map(addressDto.get(0), OrderAddressDtoRequest.class); + verify(modelMapper).map(addressDto.get(1), OrderAddressDtoRequest.class); + verify(ubsClientService, times(2)).updateCurrentAddressForOrder(updateAddressRequestDto, uuid); verify(userRepository).save(user); verify(modelMapper).map(user, UserProfileUpdateDto.class); } @@ -2413,6 +2432,7 @@ void testUpdateCurrentAddressForOrderWhenPlaceIdIsNull() { when(userRepository.findByUuid(uuid)).thenReturn(user); when(addressRepository.findById(addressId)).thenReturn(Optional.of(address)); doReturn(new OrderWithAddressesResponseDto()).when(ubsClientService).findAllAddressesForCurrentOrder(uuid); + when(modelMapper.map(dtoRequest, Address.class)).thenReturn(address.setAddressComment(newComment)); ubsClientService.updateCurrentAddressForOrder(dtoRequest, uuid); @@ -2420,8 +2440,9 @@ void testUpdateCurrentAddressForOrderWhenPlaceIdIsNull() { verify(userRepository).findByUuid(uuid); verify(addressRepository).findById(addressId); - verify(addressRepository).save(address); verify(ubsClientService).findAllAddressesForCurrentOrder(uuid); + verify(modelMapper).map(dtoRequest, Address.class); + verify(addressRepository).save(address); } @Test @@ -2793,54 +2814,36 @@ void getOrderCancellationReasonAccessDeniedException() { } @Test - void testUpdateOrderCancellationReason() { - OrderCancellationReasonDto dto = getCancellationDto(); - Order orderDto = getOrderTest(); - when(orderRepository.findById(anyLong())).thenReturn(Optional.ofNullable(orderDto)); - assert orderDto != null; - when(userRepository.findByUuid(anyString())).thenReturn(orderDto.getUser()); - when(orderRepository.save(any())).thenReturn(orderDto); - OrderCancellationReasonDto result = ubsService.updateOrderCancellationReason(1L, dto, anyString()); - - verify(eventService, times(1)) - .saveEvent("Статус Замовлення - Скасовано", "", orderDto); - assertEquals(dto.getCancellationReason(), result.getCancellationReason()); - assertEquals(dto.getCancellationComment(), result.getCancellationComment()); - verify(orderRepository).save(orderDto); - verify(orderRepository).findById(1L); - } - - @Test - void updateOrderCancellationReasonOrderNotFoundException() { - when(orderRepository.findById(anyLong())).thenReturn(Optional.empty()); - assertThrows(NotFoundException.class, - () -> ubsService.updateOrderCancellationReason(1L, null, "abc")); - } - - @Test - void updateOrderCancellationReasonAccessDeniedException() { - when(orderRepository.findById(anyLong())).thenReturn(Optional.ofNullable(getOrderTest())); - when(userRepository.findByUuid(anyString())).thenReturn(getTestUser()); - assertThrows(AccessDeniedException.class, - () -> ubsService.updateOrderCancellationReason(1L, null, "abc")); + void testGelAllEventsFromOrderByOrderId() { + List orderEvents = getListOfEvents(); + when(orderRepository.findById(1L)).thenReturn(getOrderWithEvents()); + when(eventRepository.findAllEventsByOrderId(1L)).thenReturn(orderEvents); + List eventDTOS = orderEvents.stream() + .map(event -> modelMapper.map(event, EventDto.class)) + .collect(Collectors.toList()); + assertEquals(eventDTOS, ubsService.getAllEventsForOrder(1L, anyString(), "ua")); } @Test - void testGelAllEventsFromOrderByOrderId() { + void testGelAllEventsFromOrderByOrderIdWithEng() { List orderEvents = getListOfEvents(); when(orderRepository.findById(1L)).thenReturn(getOrderWithEvents()); when(eventRepository.findAllEventsByOrderId(1L)).thenReturn(orderEvents); List eventDTOS = orderEvents.stream() + .peek(event -> { + event.setEventName(event.getEventNameEng()); + event.setAuthorName(event.getAuthorNameEng()); + }) .map(event -> modelMapper.map(event, EventDto.class)) - .collect(Collectors.toList()); - assertEquals(eventDTOS, ubsService.getAllEventsForOrder(1L, anyString())); + .collect(toList()); + assertEquals(eventDTOS, ubsService.getAllEventsForOrder(1L, anyString(), "en")); } @Test void testGelAllEventsFromOrderByOrderIdWithThrowingOrderNotFindException() { when(orderRepository.findById(1L)).thenReturn(Optional.empty()); assertThrows(NotFoundException.class, - () -> ubsService.getAllEventsForOrder(1L, "abc")); + () -> ubsService.getAllEventsForOrder(1L, "abc", "en")); } @Test @@ -2848,7 +2851,7 @@ void testGelAllEventsFromOrderByOrderIdWithThrowingEventsNotFoundException() { when(orderRepository.findById(1L)).thenReturn(getOrderWithEvents()); when(eventRepository.findAllEventsByOrderId(1L)).thenReturn(Collections.emptyList()); assertThrows(NotFoundException.class, - () -> ubsService.getAllEventsForOrder(1L, "abc")); + () -> ubsService.getAllEventsForOrder(1L, "abc", "en")); } @Test @@ -2859,7 +2862,8 @@ void deleteOrder() { ubsService.deleteOrder(order.getUser().getUuid(), 1L); - verify(orderRepository).delete(order); + verify(orderRepository).save(order); + verify(ordersForUserRepository).getAllByUserUuidAndId(order.getUser().getUuid(), order.getId()); } @Test @@ -2895,7 +2899,7 @@ void processOrderFondyClient2() throws Exception { order.setCertificates(Set.of(getCertificate())); order.setPayment(TEST_PAYMENT_LIST); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); Field[] fields = UBSClientServiceImpl.class.getDeclaredFields(); for (Field f : fields) { if (f.getName().equals("merchantId")) { @@ -2906,7 +2910,7 @@ void processOrderFondyClient2() throws Exception { order.setPointsToUse(-10000); CertificateDto certificateDto = createCertificateDto(); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); when(orderRepository.findById(1L)).thenReturn(Optional.of(order)); when(userRepository.findUserByUuid("uuid")).thenReturn(Optional.of(user)); @@ -2955,7 +2959,7 @@ void processOrderFondyClientCertificeteNotFoundExeption() throws Exception { CertificateDto certificateDto = createCertificateDto(); certificateDto.setPoints(1500); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); when(orderBagService.getActualBagsAmountForOrder(Arrays.asList(ModelUtils.getOrderBag()))) .thenReturn(ModelUtils.getAmount()); when(orderRepository.findById(1L)).thenReturn(Optional.of(order)); @@ -3004,7 +3008,7 @@ void processOrderFondyClientCertificeteNotFoundExeption2() throws Exception { CertificateDto certificateDto = createCertificateDto(); certificateDto.setPoints(1500); order.setPointsToUse(-1000); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); when(orderRepository.findById(1L)).thenReturn(Optional.of(order)); when(userRepository.findUserByUuid("uuid")).thenReturn(Optional.of(user)); when(certificateRepository.findAllByCodeAndCertificateStatus(new ArrayList<>(dto.getCertificates()), @@ -3040,7 +3044,7 @@ void processOrderFondyClientIfSumToPayLessThanPoints() throws Exception { user.setChangeOfPointsList(new ArrayList<>()); order.setUser(user); order.setPointsToUse(-10000); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); OrderFondyClientDto dto = getOrderFondyClientDto(); Field[] fields = UBSClientServiceImpl.class.getDeclaredFields(); for (Field f : fields) { @@ -3104,8 +3108,8 @@ void saveFullOrderToDBForIF() throws IllegalAccessException { Payment payment1 = getPayment(); payment1.setId(1L); order1.getPayment().add(payment1); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); - order1.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order1.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); Field[] fields = UBSClientServiceImpl.class.getDeclaredFields(); for (Field f : fields) { @@ -3149,7 +3153,7 @@ void saveFullOrderToDBWhenSumToPayeqNull() throws IllegalAccessException { user.setOrders(new ArrayList<>()); user.getOrders().add(order); user.setChangeOfPointsList(new ArrayList<>()); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag(), ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag(), ModelUtils.getOrderBag())); Bag bag = getBagForOrder(); UBSuser ubSuser = getUBSuser().setId(null); @@ -3438,7 +3442,7 @@ void getOrderForUserTest() { order.setAmountOfBagsOrdered(Map.of(1, 10)); bags.add(bag); order.setUser(user); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); order.setOrderPaymentStatus(OrderPaymentStatus.PAID); orderList.add(order); when(modelMapper.map(any(OrderBag.class), eq(BagForUserDto.class))).thenReturn(TEST_BAG_FOR_USER_DTO); @@ -3498,7 +3502,7 @@ void getOrdersForUserTest() { orderList.add(order); Pageable pageable = PageRequest.of(0, 10, Sort.by("order_date").descending()); Page page = new PageImpl<>(orderList, pageable, 1); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); when(ordersForUserRepository.getAllByUserUuid(pageable, user.getUuid())) .thenReturn(page); @@ -3531,7 +3535,7 @@ void testOrdersForUserWithExportedQuantity() { OrderPaymentStatusTranslation orderPaymentStatusTranslation = getOrderPaymentStatusTranslation(); OrdersDataForUserDto ordersDataForUserDto = getOrderStatusDto(); Order order = getOrderTest(); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); User user = getTestUser(); Bag bag = bagDto(); @@ -3592,7 +3596,7 @@ void testOrdersForUserWithConfirmedQuantity() { order.setConfirmedQuantity(Map.of(1, 10)); bags.add(bag); order.setUser(user); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); order.setOrderPaymentStatus(OrderPaymentStatus.PAID); orderList.add(order); Pageable pageable = PageRequest.of(0, 10, Sort.by("order_date").descending()); @@ -3634,7 +3638,7 @@ void senderInfoDtoBuilderTest() { order.setAmountOfBagsOrdered(Map.of(1, 10)); order.setUser(user); order.setOrderPaymentStatus(OrderPaymentStatus.PAID); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); orderList.add(order); Pageable pageable = PageRequest.of(0, 10, Sort.by("order_date").descending()); Page page = new PageImpl<>(orderList, pageable, 1); @@ -3765,7 +3769,7 @@ void checkIfAddressHasBeenDeletedTest() throws IllegalAccessException { user.setOrders(new ArrayList<>()); user.getOrders().add(order); user.setChangeOfPointsList(new ArrayList<>()); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); Bag bag = getBagForOrder(); UBSuser ubSuser = getUBSuser(); @@ -3944,7 +3948,7 @@ void testOrdersForUserWithQuantity() { bag.setFullPrice(1200_00L); bags.add(bag); order.setUser(user); - order.setOrderBags(Arrays.asList(ModelUtils.getOrderBag())); + order.updateWithNewOrderBags(Arrays.asList(ModelUtils.getOrderBag())); order.setOrderPaymentStatus(OrderPaymentStatus.PAID); orderList.add(order); Pageable pageable = PageRequest.of(0, 10, Sort.by("order_date").descending()); diff --git a/service/src/test/java/greencity/service/ubs/UBSManagementEmployeeServiceImplTest.java b/service/src/test/java/greencity/service/ubs/UBSManagementEmployeeServiceImplTest.java index c538ea98a..d281c1e19 100644 --- a/service/src/test/java/greencity/service/ubs/UBSManagementEmployeeServiceImplTest.java +++ b/service/src/test/java/greencity/service/ubs/UBSManagementEmployeeServiceImplTest.java @@ -4,18 +4,13 @@ import greencity.client.UserRemoteClient; import greencity.constant.AppConstant; import greencity.constant.ErrorMessage; -import greencity.dto.LocationsDtos; -import greencity.dto.courier.GetReceivingStationDto; import greencity.dto.employee.EmployeeWithTariffsIdDto; import greencity.dto.employee.GetEmployeeDto; -import greencity.dto.location.api.DistrictDto; -import greencity.dto.location.api.LocationDto; import greencity.dto.position.AddingPositionDto; import greencity.dto.position.PositionDto; import greencity.dto.tariff.GetTariffInfoForEmployeeDto; import greencity.entity.order.TariffsInfo; import greencity.entity.user.employee.Employee; -import greencity.entity.user.employee.EmployeeFilterView; import greencity.entity.user.employee.Position; import greencity.enums.EmployeeStatus; import greencity.exceptions.BadRequestException; @@ -23,27 +18,24 @@ import greencity.exceptions.UnprocessableEntityException; import greencity.filters.EmployeeFilterCriteria; import greencity.filters.EmployeePage; -import greencity.repository.*; -import greencity.service.locations.LocationApiService; +import greencity.repository.EmployeeRepository; +import greencity.repository.PositionRepository; +import greencity.repository.TariffsInfoRepository; +import greencity.repository.EmployeeCriteriaRepository; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; import org.mockito.junit.jupiter.MockitoExtension; import org.modelmapper.ModelMapper; import org.springframework.mock.web.MockMultipartFile; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; -import java.util.ArrayList; import java.util.Set; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; import static greencity.ModelUtils.*; import static org.mockito.ArgumentMatchers.any; @@ -52,7 +44,6 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.anyLong; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.eq; @@ -65,8 +56,6 @@ class UBSManagementEmployeeServiceImplTest { @Mock private PositionRepository positionRepository; @Mock - private ReceivingStationRepository stationRepository; - @Mock private TariffsInfoRepository tariffsInfoRepository; @Mock private FileService fileService; @@ -78,10 +67,6 @@ class UBSManagementEmployeeServiceImplTest { private UBSManagementEmployeeServiceImpl employeeService; @Mock private EmployeeCriteriaRepository employeeCriteriaRepository; - @Mock - private LocationApiService locationApiService; - @Mock - private UBSClientServiceImpl ubsClientService; @Test void saveEmployeeTest() { @@ -153,58 +138,28 @@ void findAllTest() { var employeeFilterCriteria = new EmployeeFilterCriteria(); var employeeId = 1L; var tariffsInfoId = 10L; - var employeeFilterViews = getEmployeeFilterViewListForOneEmployeeWithDifferentPositions( - employeeId, tariffsInfoId); - var expectedGetEmployeeDto = getEmployeeDtoWithPositionsAndTariffs(); + var employeeFilterViews = + getEmployeeFilterViewListForOneEmployeeWithDifferentPositions(employeeId, tariffsInfoId); + var expectedGetEmployeeDto = getEmployeeDtoWithoutPositionsAndTariffsForGetAllMethod(); + var expectedEmployeesList = getEmployeeListForGetAllMethod(); + var firstElement = employeeFilterViews.get(0); when(employeeCriteriaRepository.findAll(employeePage, employeeFilterCriteria)) .thenReturn(employeeFilterViews); - mockModelMapperBehaviourForEmployeeFilterViewCollection(employeeFilterViews); + when(repository.findAll()).thenReturn(expectedEmployeesList); + when(modelMapper.map(firstElement, GetEmployeeDto.class)) + .thenReturn(getEmployeeDto()); - var getEmployeeDtoPage = employeeService.findAll(employeePage, employeeFilterCriteria); - var actualGetEmployeeDto = getEmployeeDtoPage.get() - .findAny() - .orElseThrow(); + var getPageableDtoGetEmployeeDto = + employeeService.findAll(employeePage, employeeFilterCriteria); + var actualGetEmployeeDto = getPageableDtoGetEmployeeDto.getPage().get(0); assertEquals(expectedGetEmployeeDto, actualGetEmployeeDto); + assertEquals(expectedGetEmployeeDto.getId(), actualGetEmployeeDto.getId()); + assertEquals(expectedGetEmployeeDto.getEmail(), actualGetEmployeeDto.getEmail()); verify(employeeCriteriaRepository).findAll(employeePage, employeeFilterCriteria); - verifyAllModelMappersWasInvokedForFirstRecordOfEmployeeFilterViewCollection(employeeFilterViews); - verifyOnlyModelMapperToPositionDtoWasInvoked(employeeFilterViews); - } - - private void verifyOnlyModelMapperToPositionDtoWasInvoked(List employeeFilterViews) { - for (int i = 1; i < employeeFilterViews.size(); i++) { - verify(modelMapper, never()).map(employeeFilterViews.get(i), GetEmployeeDto.class); - verify(modelMapper, never()).map(employeeFilterViews.get(i), GetTariffInfoForEmployeeDto.class); - verify(modelMapper, never()).map(employeeFilterViews.get(i), LocationsDtos.class); - verify(modelMapper, never()).map(employeeFilterViews.get(i), GetReceivingStationDto.class); - verify(modelMapper, times(1)).map(employeeFilterViews.get(i), PositionDto.class); - } - } - - private void verifyAllModelMappersWasInvokedForFirstRecordOfEmployeeFilterViewCollection( - List employeeFilterViews) { verify(modelMapper, times(1)).map(employeeFilterViews.get(0), GetEmployeeDto.class); - verify(modelMapper, times(1)).map(employeeFilterViews.get(0), GetTariffInfoForEmployeeDto.class); - verify(modelMapper, times(1)).map(employeeFilterViews.get(0), LocationsDtos.class); - verify(modelMapper, times(1)).map(employeeFilterViews.get(0), GetReceivingStationDto.class); - verify(modelMapper, times(1)).map(employeeFilterViews.get(0), PositionDto.class); - } - - private void mockModelMapperBehaviourForEmployeeFilterViewCollection(List employeeFilterViews) { - var firstElement = employeeFilterViews.get(0); - when(modelMapper.map(firstElement, GetEmployeeDto.class)) - .thenReturn(getEmployeeDto()); - when(modelMapper.map(firstElement, GetTariffInfoForEmployeeDto.class)) - .thenReturn(getTariffInfoForEmployeeDto2()); - when(modelMapper.map(firstElement, LocationsDtos.class)) - .thenReturn(getLocationsDtos(firstElement.getLocationId())); - when(modelMapper.map(firstElement, GetReceivingStationDto.class)) - .thenReturn(getReceivingStationDto2()); - for (var employeeFilterView : employeeFilterViews) { - when(modelMapper.map(employeeFilterView, PositionDto.class)) - .thenReturn(getPositionDto(employeeFilterView.getPositionId())); - } + verify(repository).findAll(); } @Test @@ -310,6 +265,40 @@ void deactivateEmployeeTest() { assertEquals(thrown.getMessage(), ErrorMessage.EMPLOYEE_NOT_FOUND + 2L); } + @Test + void activateEmployeeTestNotFound() { + Employee employee = getEmployee(); + employee.setEmployeeStatus(EmployeeStatus.INACTIVE); + employee.setImagePath("Pass"); + when(repository.findById(1L)).thenReturn(Optional.of(employee)); + employeeService.activateEmployee(1L); + verify(repository).findById(1L); + assertEquals(EmployeeStatus.ACTIVE, employee.getEmployeeStatus()); + Exception thrown = assertThrows(NotFoundException.class, + () -> employeeService.deactivateEmployee(2L)); + assertEquals(thrown.getMessage(), ErrorMessage.EMPLOYEE_NOT_FOUND + 2L); + } + + @Test + void activateEmployeeActiveTest() { + Employee employee = getEmployee(); + employee.setImagePath("Pass"); + employee.setEmployeeStatus(EmployeeStatus.ACTIVE); + when(repository.findById(1L)).thenReturn(Optional.of(employee)); + employeeService.activateEmployee(employee.getId()); + assertEquals(EmployeeStatus.ACTIVE, employee.getEmployeeStatus()); + } + + @Test + void activateEmployeeTest() { + Employee employee = getEmployee(); + employee.setImagePath("Pass"); + employee.setEmployeeStatus(EmployeeStatus.INACTIVE); + when(repository.findById(1L)).thenReturn(Optional.of(employee)); + employeeService.activateEmployee(employee.getId()); + assertEquals(EmployeeStatus.ACTIVE, employee.getEmployeeStatus()); + } + @Test void deactivateEmployeeInactiveTest() { Employee employee = getEmployee(); @@ -331,6 +320,20 @@ void deactivateEmployeeHystrixRuntimeExceptionTest() { verify(repository).findById(1L); } + @Test + void activateEmployeeHystrixRuntimeExceptionTest() { + Employee employee = getEmployee(); + employee.setEmployeeStatus(EmployeeStatus.INACTIVE); + long employeeId = employee.getId(); + employee.setImagePath("Pass"); + when(repository.findById(1L)).thenReturn(Optional.of(employee)); + + doThrow(HystrixRuntimeException.class).when(userRemoteClient).activateEmployee("Test"); + assertThrows(BadRequestException.class, () -> employeeService.activateEmployee(employeeId)); + + verify(repository).findById(1L); + } + @Test void createPositionTest() { AddingPositionDto addingPositionDto = AddingPositionDto.builder().name("Водій").build(); @@ -450,5 +453,4 @@ void getTariffsForEmployeeTest() { verify(modelMapper, times(1)).map(any(), any()); verify(tariffsInfoRepository).findAll(); } - } diff --git a/service/src/test/java/greencity/service/ubs/UBSManagementServiceImplTest.java b/service/src/test/java/greencity/service/ubs/UBSManagementServiceImplTest.java index 93223f269..823b8e99b 100644 --- a/service/src/test/java/greencity/service/ubs/UBSManagementServiceImplTest.java +++ b/service/src/test/java/greencity/service/ubs/UBSManagementServiceImplTest.java @@ -80,6 +80,7 @@ import org.junit.jupiter.params.provider.MethodSource; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.modelmapper.ModelMapper; @@ -97,6 +98,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; @@ -123,6 +125,7 @@ import static greencity.ModelUtils.TEST_PAYMENT_LIST; import static greencity.ModelUtils.TEST_USER; import static greencity.ModelUtils.UPDATE_ORDER_PAGE_ADMIN_DTO; +import static greencity.ModelUtils.getOrdersStatusFormedDto2; import static greencity.ModelUtils.getAddBonusesToUserDto; import static greencity.ModelUtils.getAdminCommentDto; import static greencity.ModelUtils.getBagInfoDto; @@ -171,6 +174,7 @@ import static greencity.ModelUtils.getTestUser; import static greencity.ModelUtils.updateAllOrderPageDto; import static greencity.ModelUtils.updateOrderPageAdminDto; + import static greencity.constant.ErrorMessage.EMPLOYEE_NOT_FOUND; import static greencity.constant.ErrorMessage.ORDER_CAN_NOT_BE_UPDATED; import static java.util.Collections.singletonList; @@ -922,6 +926,29 @@ void updateOrderDetailStatusSecond() { verify(orderRepository, times(2)).save(any()); } + @Test + void updateOrderDetailStatusToBroughtItHimselfTest() { + String email = "some@email.com"; + Order saved = getOrder(); + saved.setOrderStatus(OrderStatus.FORMED); + Order updated = getOrder(); + updated.setOrderStatus(OrderStatus.BROUGHT_IT_HIMSELF); + + when(paymentRepository.findAllByOrderId(saved.getId())).thenReturn(saved.getPayment()); + + OrderDetailStatusRequestDto detailStatusDto = OrderDetailStatusRequestDto.builder() + .orderStatus("BROUGHT_IT_HIMSELF") + .build(); + + OrderDetailStatusDto result = ubsManagementService.updateOrderDetailStatus(saved, detailStatusDto, email); + + verify(eventService).saveEvent(OrderHistory.ORDER_BROUGHT_IT_HIMSELF, email, updated); + verify(notificationService).notifySelfPickupOrder(updated); + verify(orderRepository).save(updated); + + assertEquals(OrderStatus.BROUGHT_IT_HIMSELF.name(), result.getOrderStatus()); + } + @Test void getAllEmployeesByPosition() { Order order = getOrder(); @@ -1290,7 +1317,7 @@ void testSetOrderDetailIfPaidAndPriceLessThanDiscount() { when(certificateRepository.findCertificate(order.getId())).thenReturn(List.of(ModelUtils.getCertificate2())); when(orderRepository.findSumOfCertificatesByOrderId(order.getId())).thenReturn(600L); when(orderRepository.getOrderDetails(1L)) - .thenReturn(Optional.ofNullable(ModelUtils.getOrdersStatusFormedDto2())); + .thenReturn(Optional.ofNullable(getOrdersStatusFormedDto2())); ubsManagementService.setOrderDetail(order, UPDATE_ORDER_PAGE_ADMIN_DTO.getOrderDetailDto().getAmountOfBagsConfirmed(), @@ -1307,7 +1334,7 @@ void testSetOrderDetailIfPaidAndPriceLessThanPaidSum() { when(certificateRepository.findCertificate(order.getId())).thenReturn(List.of(ModelUtils.getCertificate2())); when(orderRepository.findSumOfCertificatesByOrderId(order.getId())).thenReturn(600L); when(orderRepository.getOrderDetails(1L)) - .thenReturn(Optional.ofNullable(ModelUtils.getOrdersStatusFormedDto2())); + .thenReturn(Optional.ofNullable(getOrdersStatusFormedDto2())); // when(bagRepository.findActiveBagById(1)).thenReturn(Optional.of(ModelUtils.getTariffBag())); ubsManagementService.setOrderDetail(order, @@ -2694,10 +2721,19 @@ void checkEmployeeForOrderTest() { @Test void updateOrderStatusToExpected() { - ubsManagementService.updateOrderStatusToExpected(); - verify(orderRepository).updateOrderStatusToExpected(OrderStatus.CONFIRMED.name(), - OrderStatus.ON_THE_ROUTE.name(), - LocalDate.now()); + ZoneId expectedZoneId = ZoneId.of("Europe/Kiev"); + LocalDate expectedLocalDate = LocalDate.of(2019, 1, 2); + + try (MockedStatic localDate = Mockito.mockStatic(LocalDate.class)) { + localDate.when(() -> LocalDate.now(expectedZoneId)) + .thenReturn(expectedLocalDate); + + ubsManagementService.updateOrderStatusToExpected(); + + verify(orderRepository).updateOrderStatusToExpected(OrderStatus.CONFIRMED.name(), + OrderStatus.ON_THE_ROUTE.name(), + expectedLocalDate); + } } @ParameterizedTest @@ -2879,7 +2915,6 @@ void updateOrderAdminPageInfoAndSaveReasonTest() { ubsManagementService.updateOrderAdminPageInfoAndSaveReason(1L, dto, "en", "test@gmail.com", multipartFiles); - verify(orderRepository).findById(1L); verify(employeeRepository).findByEmail("test@gmail.com"); verify(tariffsInfoRepository).findTariffsInfoByIdForEmployee(1L, 1L); verify(paymentRepository).findAllByOrderId(1L); @@ -2888,6 +2923,119 @@ void updateOrderAdminPageInfoAndSaveReasonTest() { verify(receivingStationRepository).findAll(); verify(receivingStationRepository).findById(1L); - verify(orderRepository).getOrderDetails(1L); } + + @Test + void updateOrderAdminPageInfoAndSaveReasonTest_OrderPaid() { + var dto = updateOrderPageAdminDto(); + MockMultipartFile[] multipartFiles = new MockMultipartFile[0]; + + Order order = getOrder(); + TariffsInfo tariffsInfo = getTariffsInfo(); + order.setOrderDate(LocalDateTime.now()).setTariffsInfo(tariffsInfo); + order.setOrderPaymentStatus(OrderPaymentStatus.UNPAID); + Employee employee = getEmployee(); + + when(orderRepository.findById(1L)).thenReturn(Optional.of(order)); + when(employeeRepository.findByEmail("test@gmail.com")).thenReturn(Optional.of(employee)); + when(tariffsInfoRepository.findTariffsInfoByIdForEmployee(1L, 1L)) + .thenReturn(Optional.of(tariffsInfo)); + when(paymentRepository.findAllByOrderId(1L)).thenReturn(List.of(getPayment())); + + when(orderAddressRepository.findById(1L)).thenReturn(Optional.of(getOrderAddress())); + when(receivingStationRepository.findAll()).thenReturn(List.of(getReceivingStation())); + + var receivingStation = getReceivingStation(); + + when(receivingStationRepository.findById(1L)).thenReturn(Optional.of(receivingStation)); + when(orderRepository.getOrderDetails(1L)).thenReturn(Optional.ofNullable(getOrdersStatusFormedDto())); + + ubsManagementService.updateOrderAdminPageInfoAndSaveReason(1L, dto, "en", "test@gmail.com", multipartFiles); + + verify(employeeRepository).findByEmail("test@gmail.com"); + verify(tariffsInfoRepository).findTariffsInfoByIdForEmployee(1L, 1L); + verify(paymentRepository).findAllByOrderId(1L); + + verify(orderAddressRepository).findById(1L); + verify(receivingStationRepository).findAll(); + + verify(receivingStationRepository).findById(1L); + } + + @Test + void updateOrderAdminPageInfoAndSaveReasonTest_OrderPaidAndUpdate() { + var dto = updateOrderPageAdminDto(); + MockMultipartFile[] multipartFiles = new MockMultipartFile[0]; + + Order order = getOrder(); + order.setPointsToUse(-10000); + TariffsInfo tariffsInfo = getTariffsInfo(); + order.setOrderDate(LocalDateTime.now()).setTariffsInfo(tariffsInfo); + order.setOrderPaymentStatus(OrderPaymentStatus.PAID); + Employee employee = getEmployee(); + + when(orderRepository.findById(1L)).thenReturn(Optional.of(order)); + when(employeeRepository.findByEmail("test@gmail.com")).thenReturn(Optional.of(employee)); + when(tariffsInfoRepository.findTariffsInfoByIdForEmployee(1L, 1L)) + .thenReturn(Optional.of(tariffsInfo)); + when(paymentRepository.findAllByOrderId(1L)).thenReturn(List.of(getPayment())); + + when(orderAddressRepository.findById(1L)).thenReturn(Optional.of(getOrderAddress())); + when(receivingStationRepository.findAll()).thenReturn(List.of(getReceivingStation())); + + var receivingStation = getReceivingStation(); + + when(receivingStationRepository.findById(1L)).thenReturn(Optional.of(receivingStation)); + when(orderRepository.getOrderDetails(1L)).thenReturn(Optional.ofNullable(getOrdersStatusFormedDto())); + + ubsManagementService.updateOrderAdminPageInfoAndSaveReason(1L, dto, "en", "test@gmail.com", multipartFiles); + + verify(employeeRepository).findByEmail("test@gmail.com"); + verify(tariffsInfoRepository).findTariffsInfoByIdForEmployee(1L, 1L); + verify(paymentRepository).findAllByOrderId(1L); + + verify(orderAddressRepository).findById(1L); + verify(receivingStationRepository).findAll(); + + verify(receivingStationRepository).findById(1L); + } + + @Test + void updateOrderAdminPageInfoAndSaveReasonTest_OrderUnPaidAndUpdate() { + var dto = updateOrderPageAdminDto(); + MockMultipartFile[] multipartFiles = new MockMultipartFile[0]; + + Order order = getOrder(); + order.setPointsToUse(-10000); + TariffsInfo tariffsInfo = getTariffsInfo(); + order.setOrderDate(LocalDateTime.now()).setTariffsInfo(tariffsInfo); + order.setOrderPaymentStatus(OrderPaymentStatus.UNPAID); + Employee employee = getEmployee(); + + when(orderRepository.findById(1L)).thenReturn(Optional.of(order)); + when(employeeRepository.findByEmail("test@gmail.com")).thenReturn(Optional.of(employee)); + when(tariffsInfoRepository.findTariffsInfoByIdForEmployee(1L, 1L)) + .thenReturn(Optional.of(tariffsInfo)); + when(paymentRepository.findAllByOrderId(1L)).thenReturn(List.of(getPayment())); + + when(orderAddressRepository.findById(1L)).thenReturn(Optional.of(getOrderAddress())); + when(receivingStationRepository.findAll()).thenReturn(List.of(getReceivingStation())); + + var receivingStation = getReceivingStation(); + + when(receivingStationRepository.findById(1L)).thenReturn(Optional.of(receivingStation)); + when(orderRepository.getOrderDetails(1L)).thenReturn(Optional.ofNullable(getOrdersStatusFormedDto())); + + ubsManagementService.updateOrderAdminPageInfoAndSaveReason(1L, dto, "en", "test@gmail.com", multipartFiles); + + verify(employeeRepository).findByEmail("test@gmail.com"); + verify(tariffsInfoRepository).findTariffsInfoByIdForEmployee(1L, 1L); + verify(paymentRepository).findAllByOrderId(1L); + + verify(orderAddressRepository).findById(1L); + verify(receivingStationRepository).findAll(); + + verify(receivingStationRepository).findById(1L); + } + }