Search in sources :

Example 1 with Warehouse

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

the class OrderServiceTest method getFakeProductPositions.

private List<ProductPosition> getFakeProductPositions() {
    List<Product> fakeProducts = getFakeProducts();
    Warehouse fakeWarehouse = getFakeWarehouse1();
    Date d1 = new Date();
    cal.setTime(d1);
    cal.add(Calendar.DATE, -10);
    d1.setTime(cal.getTime().getTime());
    Date d2 = new Date();
    cal.setTime(d2);
    cal.add(Calendar.DATE, -1);
    d2.setTime(cal.getTime().getTime());
    Date d3 = new Date();
    cal.setTime(d3);
    cal.add(Calendar.DATE, -40);
    d3.setTime(cal.getTime().getTime());
    ProductPosition ps1 = new ProductPosition(1L, fakeProducts.get(0), fakeWarehouse, "AAA", 5, 3, d1, new BigDecimal(10000.0), "ИП ИВАНОВ", true, d1);
    ps1.setId(1L);
    ProductPosition ps2 = new ProductPosition(1L, fakeProducts.get(0), fakeWarehouse, "AAA", 5, 3, d2, new BigDecimal(10000.0), "ИП ИВАНОВ", true, d2);
    ps2.setId(2L);
    ProductPosition ps3 = new ProductPosition(2L, fakeProducts.get(1), fakeWarehouse, "AAA", 5, 3, d1, new BigDecimal(10000.0), "ИП ПЕТРОВ", true, d1);
    ps3.setId(3L);
    ProductPosition ps4 = new ProductPosition(2L, fakeProducts.get(1), fakeWarehouse, "AAA", 10, 8, d2, new BigDecimal(10000.0), "ИП ПЕТРОВ", true, d2);
    ps4.setId(4L);
    ProductPosition ps5 = new ProductPosition(3L, fakeProducts.get(2), fakeWarehouse, "AAA", 20, 20, d3, new BigDecimal(10000.0), "ИП ФЕДОРОВ", true, d3);
    ps5.setId(5L);
    ProductPosition ps6 = new ProductPosition(3L, fakeProducts.get(2), fakeWarehouse, "AAA", 15, 15, d1, new BigDecimal(10000.0), "ИП ФЕДОРОВ", true, d1);
    ps6.setId(6L);
    return new ArrayList<>(Arrays.asList(ps1, ps2, ps3, ps4, ps5, ps6));
}
Also used : OrderProductPosition(com.ncedu.fooddelivery.api.v1.entities.orderProductPosition.OrderProductPosition) ProductPosition(com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition) BigDecimal(java.math.BigDecimal)

Example 2 with Warehouse

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

the class OrderServiceImpl1 method countOrderCost.

@Override
public CountOrderCostResponseDTO countOrderCost(CountOrderCostRequestDTO dto) {
    WarehouseInfoDTO warehouse = warehouseService.getNearestWarehouse(dto.getGeo().getLat(), dto.getGeo().getLon());
    if (warehouse == null)
        throw new NotFoundEx(String.format("{Lat: %s; lon: %s}", dto.getGeo().getLat().toString(), dto.getGeo().getLon().toString()));
    Long warehouseId = warehouse.getId();
    if (!warehouseId.equals(dto.getWarehouseId()))
        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 : dto.getProductAmountPairs().entrySet()) {
        Long productId = pair.getKey();
        Integer requestedAmount = pair.getValue();
        List<ProductPosition> productPositions = productPositionRepo.findByProductIdAndWarehouseId(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 = productRepo.findById(productId).get();
            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 CountOrderCostResponseDTO(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 3 with Warehouse

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

the class OrderServiceImpl1 method createOrder.

@Override
@Transactional
public areCreatedDTO createOrder(CreateOrderDTO dto, User user) {
    checkOrderDataActuality(dto);
    Long warehouseId = dto.getWarehouseId();
    Geometry coords = geometryFactory.createPoint(new Coordinate(dto.getGeo().getLon().doubleValue(), dto.getGeo().getLat().doubleValue()));
    HashMap<Long, Integer> pairs = dto.getProductAmountPairs();
    Object[] productPosMaps = getProductPositionsData(pairs, warehouseId);
    // we will use later Maps below to reserve product positions from warehouse and put them in order(s)
    HashMap<Long, Double> productPosPriceMap = (HashMap<Long, Double>) productPosMaps[0];
    HashMap<Long, Integer> productPosAmountMap = (HashMap<Long, Integer>) productPosMaps[1];
    Double orderWeight = countOrderWeight(pairs);
    if (orderWeight > 15000d) {
        int neededCouriersAmount = (int) Math.ceil(orderWeight / 15000d);
        List<ProductPosition> productPositions = getSortedProductPositions(productPosAmountMap);
        // we've got sorted by weight sequence of product positions, so we can put them into different orders
        List<Order> orders = new ArrayList<>();
        for (int i = 0; i < neededCouriersAmount; i++) {
            Order order = buildOrder(user, coords, dto, productPositions);
            // attaching courier and then order status = 'courier_appointed'
            Courier courier;
            try {
                courier = courierService.findFreeCourier(warehouseId);
            } catch (CourierAvailabilityEx ex) {
                for (Order o : orders) {
                    // DB trigger will return all reserved product
                    o.setStatus(OrderStatus.CANCELLED);
                    // positions back to warehouse
                    orderRepo.save(o);
                }
                throw ex;
            }
            order.setCourier(courier);
            order.setStatus(OrderStatus.COURIER_APPOINTED);
            orders.add(orderRepo.save(order));
        }
        return new areCreatedDTO(orders.stream().map(order -> order.getId()).collect(Collectors.toList()));
    } else {
        Order order = buildOrder(user, coords, dto, productPosPriceMap, productPosAmountMap);
        // attaching courier and then order status = 'courier_appointed'
        Courier courier;
        try {
            courier = courierService.findFreeCourier(warehouseId);
        } catch (CourierAvailabilityEx ex) {
            // DB trigger will return all reserved product positions back
            order.setStatus(OrderStatus.CANCELLED);
            // to warehouse
            orderRepo.save(order);
            throw ex;
        }
        order.setCourier(courier);
        order.setStatus(OrderStatus.COURIER_APPOINTED);
        orderRepo.save(order);
        return new areCreatedDTO(List.of(order.getId()));
    }
}
Also used : Order(com.ncedu.fooddelivery.api.v1.entities.order.Order) CourierAvailabilityEx(com.ncedu.fooddelivery.api.v1.errors.orderRegistration.CourierAvailabilityEx) Geometry(com.vividsolutions.jts.geom.Geometry) Coordinate(com.vividsolutions.jts.geom.Coordinate) com.ncedu.fooddelivery.api.v1.dto.areCreatedDTO(com.ncedu.fooddelivery.api.v1.dto.areCreatedDTO) OrderProductPosition(com.ncedu.fooddelivery.api.v1.entities.orderProductPosition.OrderProductPosition) ProductPosition(com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition) Transactional(org.springframework.transaction.annotation.Transactional)

Example 4 with Warehouse

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

the class ProductPositionServiceImpl1 method convertToProductPosition.

public ProductPosition convertToProductPosition(AcceptSupplyDTO acceptSupplyDTO) {
    Optional<Product> productOptional = productRepo.findById(acceptSupplyDTO.getProductId());
    Optional<Warehouse> warehouseOptional = warehouseRepo.findById(acceptSupplyDTO.getWarehouseId());
    if (warehouseOptional.isEmpty())
        throw new NotFoundEx(String.valueOf(acceptSupplyDTO.getWarehouseId()));
    if (productOptional.isEmpty())
        throw new NotFoundEx(String.valueOf(acceptSupplyDTO.getProductId()));
    Product product = productOptional.get();
    Warehouse warehouse = warehouseOptional.get();
    ProductPosition productPosition = new ProductPosition(null, product, warehouse, acceptSupplyDTO.getWarehouseSection(), acceptSupplyDTO.getSupplyAmount(), acceptSupplyDTO.getSupplyAmount(), acceptSupplyDTO.getManufactureDate(), acceptSupplyDTO.getSupplierInvoice(), acceptSupplyDTO.getSupplierName(), acceptSupplyDTO.getIsInvoicePaid(), acceptSupplyDTO.getManufactureDate());
    if (acceptSupplyDTO.getIsInvoicePaid() == null) {
        productPosition.setIsInvoicePaid(false);
    }
    return productPosition;
}
Also used : OrderProductPosition(com.ncedu.fooddelivery.api.v1.entities.orderProductPosition.OrderProductPosition) ProductPosition(com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition)

Example 5 with Warehouse

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

the class WarehouseServiceTest method getNearestWarehouseTest.

@Test
public void getNearestWarehouseTest() {
    List<Warehouse> mockWarehouses = getMockActiveWarehouses();
    Mockito.when(warehouseRepo.getActiveWarehouses()).thenReturn(mockWarehouses);
    Point mockInputPoint = Mockito.mock(Point.class);
    Assertions.assertEquals(2L, warehouseService.getNearestWarehouse(mockInputPoint).getId());
    Mockito.verify(mockWarehouses.get(0).getDeliveryZone(), Mockito.times(1)).covers(mockInputPoint);
    Mockito.verify(mockWarehouses.get(1).getDeliveryZone(), Mockito.times(1)).covers(mockInputPoint);
    Mockito.verify(mockWarehouses.get(2).getDeliveryZone(), Mockito.times(1)).covers(mockInputPoint);
    Mockito.verify(mockWarehouses.get(3).getDeliveryZone(), Mockito.times(1)).covers(mockInputPoint);
    Mockito.verify(mockWarehouses.get(3).getGeo(), Mockito.never()).distance(mockInputPoint);
}
Also used : Warehouse(com.ncedu.fooddelivery.api.v1.entities.Warehouse) Point(com.vividsolutions.jts.geom.Point) Test(org.junit.jupiter.api.Test) SpringBootTest(org.springframework.boot.test.context.SpringBootTest)

Aggregations

ProductPosition (com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition)6 OrderProductPosition (com.ncedu.fooddelivery.api.v1.entities.orderProductPosition.OrderProductPosition)5 WarehouseInfoDTO (com.ncedu.fooddelivery.api.v1.dto.warehouseDTOs.WarehouseInfoDTO)4 Warehouse (com.ncedu.fooddelivery.api.v1.entities.Warehouse)4 Point (com.vividsolutions.jts.geom.Point)4 Order (com.ncedu.fooddelivery.api.v1.entities.order.Order)3 Test (org.junit.jupiter.api.Test)3 SpringBootTest (org.springframework.boot.test.context.SpringBootTest)3 ProductPositionsShipmentDTO (com.ncedu.fooddelivery.api.v1.dto.ProductPositionDTOs.ProductPositionsShipmentDTO)2 NotFoundEx (com.ncedu.fooddelivery.api.v1.errors.notfound.NotFoundEx)2 ProductAvailabilityEx (com.ncedu.fooddelivery.api.v1.errors.orderRegistration.ProductAvailabilityEx)2 WarehouseCoordsBindingEx (com.ncedu.fooddelivery.api.v1.errors.orderRegistration.WarehouseCoordsBindingEx)2 Coordinate (com.vividsolutions.jts.geom.Coordinate)2 Geometry (com.vividsolutions.jts.geom.Geometry)2 Executable (org.junit.jupiter.api.function.Executable)2 com.ncedu.fooddelivery.api.v1.dto.areCreatedDTO (com.ncedu.fooddelivery.api.v1.dto.areCreatedDTO)1 CourierAvailabilityEx (com.ncedu.fooddelivery.api.v1.errors.orderRegistration.CourierAvailabilityEx)1 BigDecimal (java.math.BigDecimal)1 ArrayList (java.util.ArrayList)1 ResponseEntity (org.springframework.http.ResponseEntity)1