Search in sources :

Example 11 with ProductPosition

use of com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition in project 2021-msk-food-delivery by netcracker-edu.

the class OrderServiceImpl1 method buildOrder.

private Order buildOrder(User user, Geometry coords, CreateOrderDTO dto, List<ProductPosition> productPositions) {
    Order order = new Order();
    final int weightLimit = 15000;
    int currentWeight = 0;
    Map<Long, Integer> currOrderPositions = new HashMap<>();
    // adding records in DB table 'orders_product_positions'
    for (int j = 0; j < productPositions.size() && weightLimit != currentWeight; j++) {
        ProductPosition currPos = productPositions.get(j);
        int currPosWeight = currPos.getProduct().getWeight();
        if ((weightLimit - currentWeight) >= currPosWeight) {
            currentWeight += currPosWeight;
            currOrderPositions.merge(currPos.getId(), 1, Integer::sum);
            productPositions.remove(j);
            j--;
        }
    }
    Double orderCost = 0d;
    Double orderDiscount = 0d;
    for (Long psId : currOrderPositions.keySet()) {
        int amount = currOrderPositions.get(psId);
        ProductPosition ps = productPositionRepo.findById(psId).get();
        Double price = (ps.getProduct().getPrice() - ps.getProduct().getDiscount()) * amount;
        Double discount = amount * ps.getProduct().getDiscount();
        orderCost += price;
        orderDiscount += discount;
    }
    order.setDiscount(orderDiscount);
    order.setHighDemandCoeff(dto.getHighDemandCoeff());
    order.setOverallCost(orderCost);
    order.setClient(user.getClient());
    order.setWarehouse(warehouseService.findById(dto.getWarehouseId()));
    order.setAddress(dto.getAddress());
    order.setCoordinates(coords);
    order.setStatus(OrderStatus.CREATED);
    order.setDateStart(LocalDateTime.now());
    order = orderRepo.save(order);
    for (Long psId : currOrderPositions.keySet()) {
        int amount = currOrderPositions.get(psId);
        ProductPosition ps = productPositionRepo.findById(psId).get();
        orderProductPositionRepo.save(new OrderProductPosition(order, ps, amount, (ps.getProduct().getPrice() - ps.getProduct().getDiscount()) * amount));
    }
    return order;
}
Also used : Order(com.ncedu.fooddelivery.api.v1.entities.order.Order) OrderProductPosition(com.ncedu.fooddelivery.api.v1.entities.orderProductPosition.OrderProductPosition) OrderProductPosition(com.ncedu.fooddelivery.api.v1.entities.orderProductPosition.OrderProductPosition) ProductPosition(com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition)

Example 12 with ProductPosition

use of com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition in project 2021-msk-food-delivery by netcracker-edu.

the class OrderServiceImpl1 method countOrderCost.

@Override
public Double[] countOrderCost(CoordsDTO geo, HashMap<Long, Integer> pairs, Long clientWarehouseId) {
    WarehouseInfoDTO warehouse = warehouseService.getNearestWarehouse(geo.getLat(), geo.getLon());
    if (warehouse == null)
        throw new NotFoundEx(String.format("Lat: %s; lon: %s", geo.getLat().toString(), geo.getLon().toString()));
    Long warehouseId = warehouse.getId();
    if (!warehouseId.equals(clientWarehouseId))
        throw new WarehouseCoordsBindingEx();
    Map<Long, Integer> productsAvailableAmounts = new HashMap<>();
    Double overallOrderCost = 0.0;
    Double overallOrderDiscount = 0.0;
    Double orderHighDemandCoeff;
    boolean enoughProductPositions = true;
    for (Map.Entry<Long, Integer> pair : pairs.entrySet()) {
        Long productId = pair.getKey();
        Integer requestedAmount = pair.getValue();
        // 'findByProductIdAndWarehouseIdWithLock' sets lock on every product position in result set. So no one
        // other thread
        // will be able to interact with these positions before whole transaction will complete.
        List<ProductPosition> productPositions = productPositionRepo.findByProductIdAndWarehouseIdWithLock(productId, warehouseId);
        // filtering expired product positions
        productPositions = productPositions.stream().filter(new Predicate<ProductPosition>() {

            @Override
            public boolean test(ProductPosition productPosition) {
                Short expirationDays = productPosition.getProduct().getExpirationDays();
                Date manufactureDate = productPosition.getManufactureDate();
                Calendar c = Calendar.getInstance();
                c.setTime(manufactureDate);
                c.add(Calendar.DATE, expirationDays);
                if (c.before(Calendar.getInstance()))
                    return false;
                return true;
            }
        }).collect(Collectors.toList());
        Integer overallAmount = 0;
        for (ProductPosition pos : productPositions) {
            overallAmount += pos.getCurrentAmount();
        }
        if (overallAmount < requestedAmount) {
            productsAvailableAmounts.put(productId, overallAmount);
            enoughProductPositions = false;
        }
        if (enoughProductPositions) {
            // product price count
            Product product = productPositions.get(0).getProduct();
            Double productDiscount = product.getDiscount();
            Double productPrice = product.getPrice();
            overallOrderCost += requestedAmount * (productPrice - productDiscount);
            overallOrderDiscount += productDiscount * requestedAmount;
        }
    }
    if (!enoughProductPositions) {
        throw new ProductAvailabilityEx(productsAvailableAmounts);
    }
    orderHighDemandCoeff = countHighDemandCoeff(warehouseId);
    overallOrderCost = Math.round(overallOrderCost * orderHighDemandCoeff * 100.0) / 100.0;
    return new Double[] { overallOrderCost, overallOrderDiscount, orderHighDemandCoeff };
}
Also used : ProductAvailabilityEx(com.ncedu.fooddelivery.api.v1.errors.orderRegistration.ProductAvailabilityEx) WarehouseCoordsBindingEx(com.ncedu.fooddelivery.api.v1.errors.orderRegistration.WarehouseCoordsBindingEx) NotFoundEx(com.ncedu.fooddelivery.api.v1.errors.notfound.NotFoundEx) OrderProductPosition(com.ncedu.fooddelivery.api.v1.entities.orderProductPosition.OrderProductPosition) ProductPosition(com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition) WarehouseInfoDTO(com.ncedu.fooddelivery.api.v1.dto.warehouseDTOs.WarehouseInfoDTO)

Example 13 with ProductPosition

use of com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition in project 2021-msk-food-delivery by netcracker-edu.

the class ProductPositionServiceImpl1 method acceptSupply.

@Override
public Long acceptSupply(AcceptSupplyDTO acceptSupplyDTO) {
    ProductPosition productPosition = convertToProductPosition(acceptSupplyDTO);
    Long id = productPositionRepo.save(productPosition).getId();
    return id;
}
Also used : OrderProductPosition(com.ncedu.fooddelivery.api.v1.entities.orderProductPosition.OrderProductPosition) ProductPosition(com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition)

Example 14 with ProductPosition

use of com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition in project 2021-msk-food-delivery by netcracker-edu.

the class ProductPositionServiceImpl1 method nullifyProductPosition.

@Override
public boolean nullifyProductPosition(Long id) {
    ProductPosition productPosition = getProductPosition(id);
    if (productPosition == null)
        return false;
    productPosition.setCurrentAmount(0);
    productPositionRepo.save(productPosition);
    return true;
}
Also used : OrderProductPosition(com.ncedu.fooddelivery.api.v1.entities.orderProductPosition.OrderProductPosition) ProductPosition(com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition)

Example 15 with ProductPosition

use of com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition in project 2021-msk-food-delivery by netcracker-edu.

the class OrderServiceTest method countOrderCostNotAvailableExTest.

@Test
public void countOrderCostNotAvailableExTest() {
    WarehouseInfoDTO fakeWarehouseInfoDTO = getFakeWarehouseInfoDTO();
    List<Product> fakeProducts = getFakeProducts();
    List<ProductPosition> fakePositions = getFakeProductPositions();
    Mockito.when(courierRepo.countWorkingCouriersByWarehouse(Mockito.any(Long.class))).thenReturn((short) 100);
    Mockito.when(courierRepo.countDeliveringCouriersByWarehouse(Mockito.any(Long.class))).thenReturn((short) 100);
    Mockito.when(warehouseService.getNearestWarehouse(Mockito.any(BigDecimal.class), Mockito.any(BigDecimal.class))).thenReturn(fakeWarehouseInfoDTO);
    Mockito.when(productPositionRepo.findByProductIdAndWarehouseIdWithLock(1L, 1L)).thenReturn(Arrays.asList(fakePositions.get(0), fakePositions.get(1)));
    Mockito.when(productPositionRepo.findByProductIdAndWarehouseIdWithLock(2L, 1L)).thenReturn(Arrays.asList(fakePositions.get(2), fakePositions.get(3)));
    Mockito.when(productPositionRepo.findByProductIdAndWarehouseIdWithLock(3L, 1L)).thenReturn(Arrays.asList(fakePositions.get(4), fakePositions.get(5)));
    Mockito.when(productRepo.findById(1l)).thenReturn(Optional.of(fakeProducts.get(0)));
    Mockito.when(productRepo.findById(2l)).thenReturn(Optional.of(fakeProducts.get(1)));
    Mockito.when(productRepo.findById(3l)).thenReturn(Optional.of(fakeProducts.get(2)));
    HashMap<Long, Integer> fakeHashMap = new HashMap<>();
    fakeHashMap.put(1L, 4);
    fakeHashMap.put(2L, 3);
    fakeHashMap.put(3L, 5);
    Assertions.assertThrows(ProductAvailabilityEx.class, new Executable() {

        @Override
        public void execute() throws Throwable {
            orderService.countOrderCost(getFakeCoordsDTO(), fakeHashMap, 1L);
        }
    });
    Mockito.verify(productPositionRepo, Mockito.times(3)).findByProductIdAndWarehouseIdWithLock(Mockito.any(Long.class), Mockito.eq(1L));
    Mockito.verify(warehouseService, Mockito.times(1)).getNearestWarehouse(Mockito.any(BigDecimal.class), Mockito.any(BigDecimal.class));
}
Also used : BigDecimal(java.math.BigDecimal) Executable(org.junit.jupiter.api.function.Executable) OrderProductPosition(com.ncedu.fooddelivery.api.v1.entities.orderProductPosition.OrderProductPosition) ProductPosition(com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition) WarehouseInfoDTO(com.ncedu.fooddelivery.api.v1.dto.warehouseDTOs.WarehouseInfoDTO) Test(org.junit.jupiter.api.Test) SpringBootTest(org.springframework.boot.test.context.SpringBootTest)

Aggregations

ProductPosition (com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition)21 OrderProductPosition (com.ncedu.fooddelivery.api.v1.entities.orderProductPosition.OrderProductPosition)14 Test (org.junit.jupiter.api.Test)7 SpringBootTest (org.springframework.boot.test.context.SpringBootTest)7 WarehouseInfoDTO (com.ncedu.fooddelivery.api.v1.dto.warehouseDTOs.WarehouseInfoDTO)5 NotFoundEx (com.ncedu.fooddelivery.api.v1.errors.notfound.NotFoundEx)5 Order (com.ncedu.fooddelivery.api.v1.entities.order.Order)4 CustomAccessDeniedException (com.ncedu.fooddelivery.api.v1.errors.security.CustomAccessDeniedException)4 BigDecimal (java.math.BigDecimal)4 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)4 ProductAvailabilityEx (com.ncedu.fooddelivery.api.v1.errors.orderRegistration.ProductAvailabilityEx)2 WarehouseCoordsBindingEx (com.ncedu.fooddelivery.api.v1.errors.orderRegistration.WarehouseCoordsBindingEx)2 Executable (org.junit.jupiter.api.function.Executable)2 ResponseEntity (org.springframework.http.ResponseEntity)2 ProductPositionsShipmentDTO (com.ncedu.fooddelivery.api.v1.dto.ProductPositionDTOs.ProductPositionsShipmentDTO)1 com.ncedu.fooddelivery.api.v1.dto.areCreatedDTO (com.ncedu.fooddelivery.api.v1.dto.areCreatedDTO)1 com.ncedu.fooddelivery.api.v1.dto.isCreatedDTO (com.ncedu.fooddelivery.api.v1.dto.isCreatedDTO)1 CreateOrderDTO (com.ncedu.fooddelivery.api.v1.dto.order.CreateOrderDTO)1 Warehouse (com.ncedu.fooddelivery.api.v1.entities.Warehouse)1 CourierAvailabilityEx (com.ncedu.fooddelivery.api.v1.errors.orderRegistration.CourierAvailabilityEx)1