Search in sources :

Example 1 with CreateOrderDTO

use of com.ncedu.fooddelivery.api.v1.dto.order.CreateOrderDTO in project 2021-msk-food-delivery by netcracker-edu.

the class OrderServiceImpl1 method buildOrder.

private Order buildOrder(User user, Geometry coords, CreateOrderDTO dto, Map<Long, Double> productPosPriceMap, Map<Long, Integer> productPosAmountMap) {
    Order order = new Order();
    order.setDiscount(dto.getDiscount());
    order.setHighDemandCoeff(dto.getHighDemandCoeff());
    order.setOverallCost(dto.getOverallCost());
    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);
    // adding records in DB table 'orders_product_positions'
    for (Long productPositionId : productPosAmountMap.keySet()) {
        orderProductPositionRepo.save(new OrderProductPosition(order, productPositionRepo.findById(productPositionId).get(), productPosAmountMap.get(productPositionId), productPosPriceMap.get(productPositionId)));
    }
    return orderRepo.save(order);
}
Also used : Order(com.ncedu.fooddelivery.api.v1.entities.order.Order) OrderProductPosition(com.ncedu.fooddelivery.api.v1.entities.orderProductPosition.OrderProductPosition)

Example 2 with CreateOrderDTO

use of com.ncedu.fooddelivery.api.v1.dto.order.CreateOrderDTO 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 3 with CreateOrderDTO

use of com.ncedu.fooddelivery.api.v1.dto.order.CreateOrderDTO 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 4 with CreateOrderDTO

use of com.ncedu.fooddelivery.api.v1.dto.order.CreateOrderDTO in project 2021-msk-food-delivery by netcracker-edu.

the class OrderServiceImpl1 method checkOrderDataActuality.

private void checkOrderDataActuality(CreateOrderDTO dto) {
    Double clientCost = dto.getOverallCost();
    Double clientDiscount = dto.getDiscount();
    Double clientHighDemandCoeff = dto.getHighDemandCoeff();
    // checking that client data is still actual
    Double[] repeatedCalculation = countOrderCost(dto.getGeo(), dto.getProductAmountPairs(), dto.getWarehouseId());
    Double countedCost = repeatedCalculation[0];
    Double countedDiscount = repeatedCalculation[1];
    Double countedHighDemandCoeff = repeatedCalculation[2];
    if (!clientCost.equals(countedCost) || !clientHighDemandCoeff.equals(countedHighDemandCoeff) || !clientDiscount.equals(countedDiscount))
        throw new OrderCostChangedEx(countedCost, countedDiscount, countedHighDemandCoeff);
}
Also used : OrderCostChangedEx(com.ncedu.fooddelivery.api.v1.errors.orderRegistration.OrderCostChangedEx)

Example 5 with CreateOrderDTO

use of com.ncedu.fooddelivery.api.v1.dto.order.CreateOrderDTO in project 2021-msk-food-delivery by netcracker-edu.

the class OrderServiceTest method createOrderTest.

@Test
public void createOrderTest() {
    CreateOrderDTO fakeDTO = new CreateOrderDTO();
    User fakeUser = getFakeUserClient();
    HashMap<Long, Integer> fakeHashMap = new HashMap<>();
    fakeHashMap.put(1L, 2);
    fakeHashMap.put(2L, 3);
    fakeHashMap.put(3L, 5);
    fakeDTO.setProductAmountPairs(fakeHashMap);
    fakeDTO.setOverallCost(380.0);
    fakeDTO.setHighDemandCoeff(1.0);
    fakeDTO.setDiscount(20.0);
    fakeDTO.setAddress("address");
    fakeDTO.setGeo(getFakeCoordsDTO());
    fakeDTO.setWarehouseId(1L);
    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) 50);
    Mockito.when(warehouseService.getNearestWarehouse(Mockito.any(BigDecimal.class), Mockito.any(BigDecimal.class))).thenReturn(fakeWarehouseInfoDTO);
    Mockito.when(warehouseService.findById(1L)).thenReturn(getFakeWarehouse1());
    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(productPositionRepo.findById(1L)).thenReturn(Optional.of(fakePositions.get(0)));
    Mockito.when(productPositionRepo.findById(2L)).thenReturn(Optional.of(fakePositions.get(1)));
    Mockito.when(productPositionRepo.findById(3L)).thenReturn(Optional.of(fakePositions.get(2)));
    Mockito.when(productPositionRepo.findById(4L)).thenReturn(Optional.of(fakePositions.get(3)));
    Mockito.when(productPositionRepo.findById(5L)).thenReturn(Optional.of(fakePositions.get(4)));
    Mockito.when(productPositionRepo.findById(6L)).thenReturn(Optional.of(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)));
    Mockito.when(orderRepo.save(Mockito.any(Order.class))).thenReturn(getFakeOrder());
    Mockito.when(courierRepo.getWaitingCourierByWarehouse(1L)).thenReturn(Mockito.mock(Courier.class));
    Mockito.when(orderProductPositionRepo.save(Mockito.any(OrderProductPosition.class))).thenReturn(Mockito.mock(OrderProductPosition.class));
    orderService.createOrder(fakeDTO, fakeUser);
    Mockito.verify(courierRepo, Mockito.times(1)).countWorkingCouriersByWarehouse(1L);
    Mockito.verify(courierRepo, Mockito.times(1)).countDeliveringCouriersByWarehouse(1L);
    Mockito.verify(productPositionRepo, Mockito.times(6)).findByProductIdAndWarehouseIdWithLock(Mockito.any(Long.class), Mockito.eq(1L));
    Mockito.verify(warehouseService, Mockito.times(1)).getNearestWarehouse(Mockito.any(BigDecimal.class), Mockito.any(BigDecimal.class));
    Mockito.verify(orderProductPositionRepo, Mockito.times(3)).save(Mockito.any(OrderProductPosition.class));
}
Also used : Order(com.ncedu.fooddelivery.api.v1.entities.order.Order) OrderProductPosition(com.ncedu.fooddelivery.api.v1.entities.orderProductPosition.OrderProductPosition) BigDecimal(java.math.BigDecimal) CreateOrderDTO(com.ncedu.fooddelivery.api.v1.dto.order.CreateOrderDTO) 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

Order (com.ncedu.fooddelivery.api.v1.entities.order.Order)4 OrderProductPosition (com.ncedu.fooddelivery.api.v1.entities.orderProductPosition.OrderProductPosition)4 ProductPosition (com.ncedu.fooddelivery.api.v1.entities.productPosition.ProductPosition)3 com.ncedu.fooddelivery.api.v1.dto.areCreatedDTO (com.ncedu.fooddelivery.api.v1.dto.areCreatedDTO)1 CreateOrderDTO (com.ncedu.fooddelivery.api.v1.dto.order.CreateOrderDTO)1 WarehouseInfoDTO (com.ncedu.fooddelivery.api.v1.dto.warehouseDTOs.WarehouseInfoDTO)1 CourierAvailabilityEx (com.ncedu.fooddelivery.api.v1.errors.orderRegistration.CourierAvailabilityEx)1 OrderCostChangedEx (com.ncedu.fooddelivery.api.v1.errors.orderRegistration.OrderCostChangedEx)1 Coordinate (com.vividsolutions.jts.geom.Coordinate)1 Geometry (com.vividsolutions.jts.geom.Geometry)1 BigDecimal (java.math.BigDecimal)1 Test (org.junit.jupiter.api.Test)1 SpringBootTest (org.springframework.boot.test.context.SpringBootTest)1 Transactional (org.springframework.transaction.annotation.Transactional)1