Java Logic for Food Delivery Order Management

Food Delivery Order Management System

This implementation focuses on the OrderManager class to handle various aspects of a food delivery service, including statistics, fee calculation, and partner recommendations.

Order Statistics in OrderManager

Implementing getOrderStatistics

The following method calculates the total, active, and closed orders within the system.

OrderStats getOrderStatistics() {
    int total = orders.size();
    int active = 0;
    int closed = 0;

    for (Order order : orders) {
        if (order.status == OrderStatus.PLACED ||
            order.status == OrderStatus.PREPARING ||
            order.status == OrderStatus.OUT_FOR_DELIVERY) {
            active++;
        } else if (order.status == OrderStatus.DELIVERED ||
                   order.status == OrderStatus.CANCELED) {
            closed++;
        }
    }
    return new OrderStats(total, active, closed);
}

Delivery Management Methods

Adding Deliveries with addDelivery

Use the addDelivery method to associate a delivery object with a specific order ID.

void addDelivery(int orderId, Delivery delivery) {
    for (Order order : orders) {
        if (order.orderId == orderId) {
            order.deliveries.add(delivery);
            return;
        }
    }
}

Calculating Average Delivery Time

This method calculates the average delivery duration for each restaurant based on completed deliveries.

Map<Integer, Double> getAverageDeliveryTimeByRestaurant() {
    Map<Integer, Integer> totalDuration = new HashMap<>();
    Map<Integer, Integer> totalCount = new HashMap<>();
    Map<Integer, Double> avg = new HashMap<>();

    for (Order order : orders) {
        for (Delivery delivery : order.deliveries) {
            int restaurantId = order.restaurantId;
            totalDuration.put(restaurantId, totalDuration.getOrDefault(restaurantId, 0) + delivery.getDurationMinutes());
            totalCount.put(restaurantId, totalCount.getOrDefault(restaurantId, 0) + 1);
        }
    }

    for (Integer restaurantID : totalDuration.keySet()) {
        avg.put(restaurantID, (double) totalDuration.get(restaurantID) / totalCount.get(restaurantID));
    }

    return avg;
}

Financial Calculations

Determining Delivery Fees

The getDeliveryFees method determines the cost based on distance and order value.

Map<Integer, Double> getDeliveryFees() {
    Map<Integer, Double> fees = new HashMap<>();

    for (Order order : orders) {
        int roundedKm = (int) Math.ceil(order.distanceKm);
        int baseFees;

        if (roundedKm <= 1) {
            baseFees = 2;
        } else {
            baseFees = roundedKm + 1;
        }

        double fee;
        if (order.orderValue >= 50) {
            fee = 0.0;
        } else if (order.orderValue >= 30) {
            fee = baseFees * 0.5;
        } else {
            fee = baseFees;
        }

        fees.put(order.orderId, fee);
    }
    return fees;
}

Partner Delivery Logic

Adding Partner Deliveries

void addPartnerDelivery(PartnerDelivery delivery) {
    partnerDeliveries.computeIfAbsent(delivery.partnerId, a -> new ArrayList<>()).add(delivery);
}

Calculating Overlap and Recommendations

The following methods calculate the overlap in minutes between partners and provide recommendations based on shared delivery times.

private int overlapMinutes(PartnerDelivery a, PartnerDelivery b) {
    int start = Math.max(a.startMinute, b.startMinute);
    int end = Math.min(a.endMinute, b.endMinute);
    return Math.max(0, end - start);
}

private int totalOverlap(int partner1Id, int partner2Id) {
    List<PartnerDelivery> list1 = partnerDeliveries.getOrDefault(partner1Id, Collections.emptyList());
    List<PartnerDelivery> list2 = partnerDeliveries.getOrDefault(partner2Id, Collections.emptyList());
    int total = 0;
    for (PartnerDelivery a : list1) {
        for (PartnerDelivery b : list2) {
            total += overlapMinutes(a, b);
        }
    }
    return total;
}

Map<Integer, List<int[]>> getRecommendedPartners() {
    Map<Integer, List<int[]>> res = new HashMap<>();
    List<Integer> partnerIds = new ArrayList<>(partnerDeliveries.keySet());
    for (Integer p1 : partnerIds) {
        List<int[]> recommendations = new ArrayList<>();
        for (Integer p2 : partnerIds) {
            if (p1.equals(p2)) {
                continue;
            }
            int overlap = totalOverlap(p1, p2);
            if (overlap > 0) {
                recommendations.add(new int[]{p2, overlap});
            }
        }
        recommendations.sort((a, b) -> {
            if (b[1] != a[1]) {
                return Integer.compare(b[1], a[1]);
            }
            return Integer.compare(a[0], b[0]);
        });
        res.put(p1, recommendations);
    }
    return res;
}