Split vs. Consolidation — Trade-off cốt lõi

Khi đơn hàng có nhiều món nhưng các món nằm ở nhiều kho khác nhau, hệ thống phải đối mặt với quyết định kinh điển:

Đơn hàng: 3 món (A ở kho HN, B ở kho HCM, C ở kho ĐN)
Giao cho khách ở Hà Nội

Phương án 1: SPLIT (Tách gửi từ 3 kho)
  Kho HN → Khách: A (1 kiện)     — 30.000đ, 2 giờ
  Kho HCM → Khách: B (1 kiện)    — 85.000đ, 2 ngày
  Kho ĐN → Khách: C (1 kiện)     — 65.000đ, 1.5 ngày
  Tổng: 180.000đ, 3 lần giao, 3 hộp

Phương án 2: CONSOLIDATE (Gom về 1 kho rồi gửi)
  Kho HCM → Kho HN: B (nội bộ)   — 40.000đ, 1 ngày
  Kho ĐN → Kho HN: C (nội bộ)    — 35.000đ, 1 ngày
  Kho HN → Khách: A+B+C (1 kiện) — 45.000đ, 2 giờ
  Tổng: 120.000đ, 1 lần giao, 1 hộp, nhưng chậm hơn 1-2 ngày

Trade-off: Nhanh + tốn  vs.  Chậm + tiết kiệm

Decision Matrix

Yếu tốƯu tiên SplitƯu tiên Consolidate
SLAGiao nhanh (same-day, 2h)Giao tiêu chuẩn (3-5 ngày)
Chi phíKhách trả phí shipFree shipping (seller chịu)
Trải nghiệmKhách cần gấp từng mónKhách muốn nhận đủ 1 lần
Giá trị đơnĐơn nhỏ (không đáng gom)Đơn lớn (gom tiết kiệm đáng kể)
Loại hàngHàng tươi/khẩn cấpHàng khô, không gấp

Thuật toán quyết định Split/Consolidate

Function: decideFulfillmentStrategy(order, warehouses)

  // Bước 1: Kiểm tra xem có kho nào có ĐỦ tất cả items không
  single_source = findWarehouseWithAllItems(order.items, warehouses)
  if single_source exists:
    return SINGLE_SOURCE(single_source)  // Lý tưởng nhất

  // Bước 2: Tính chi phí cho mỗi phương án
  split_cost = calculateSplitCost(order)
  consolidate_cost = calculateConsolidateCost(order)

  // Bước 3: Kiểm tra SLA
  if order.sla == "SAME_DAY" or order.sla == "2_HOURS":
    return SPLIT  // Không đủ thời gian gom

  // Bước 4: So sánh chi phí
  savings = split_cost - consolidate_cost
  consolidation_delay = estimateConsolidationDelay(order)

  // Chỉ gom nếu tiết kiệm > ngưỡng VÀ delay chấp nhận được
  if savings > THRESHOLD and consolidation_delay <= order.max_acceptable_delay:
    return CONSOLIDATE
  else:
    return SPLIT

Last-Mile Delivery — Chặng cuối đắt đỏ

Last-mile là chặng cuối từ hub/kho đến tay khách hàng. Dù chỉ dài vài km, nó chiếm 53% tổng chi phí logistics vì:

Vận chuyển đường dài (Line-haul):
  1 xe tải chở 10.000 kiện, đi 500km
  Chi phí/kiện: ~5.000đ

Last-mile:
  1 tài xế giao 20-30 kiện, đi 50km quanh thành phố
  Chi phí/kiện: ~15.000-25.000đ  ← Đắt gấp 3-5 lần!

Lý do:
  - Tốc độ thấp (kẹt xe, đèn đỏ)
  - Nhiều điểm dừng (mỗi kiện 1 địa chỉ)
  - Thời gian chờ (khách không ở nhà)
  - Chi phí nhân công cao (1 tài xế/20-30 kiện)

Tối ưu Last-Mile

1. Delivery Density — Mật độ giao hàng:

Mật độ thấp:                Mật độ cao:
  ○                            ○ ○
     ○                         ○ ○ ○
  ○       ○                    ○ ○
                               ○ ○ ○
  10 kiện, 30km                10 kiện, 5km
  Chi phí/kiện: 25.000đ       Chi phí/kiện: 8.000đ

CONDOR tăng mật độ bằng cách gom đơn cùng khu vực → giảm cost.

2. Time Windows — Khung giờ giao:

Cho khách chọn khung giờ giao:
  8:00-10:00  | 10:00-12:00 | 14:00-16:00 | 18:00-20:00

Lợi ích: Tài xế biết chính xác khi nào khách ở nhà
→ Giảm giao lại (re-delivery) từ 15% xuống 3%
→ Tối ưu lộ trình theo time window

3. Delivery Locker / Pickup Points:

Thay vì giao tận nhà (last-mile tốn kém):
  → Khách đến lấy tại tủ locker gần nhà
  → 1 chuyến tài xế giao 50 kiện vào 1 locker (thay vì 50 địa chỉ)
  → Chi phí/kiện giảm 60-70%

SKU Affinity — Xếp hàng thông minh

Sản phẩm thường được mua cùng nhau nên được đặt cùng kho:

Phân tích dữ liệu mua hàng:

  iPhone thường mua cùng: ốp lưng (78%), cáp sạc (65%), tai nghe (45%)
  Bột giặt thường mua cùng: nước xả (82%), khăn giấy (40%)
  Sữa tươi thường mua cùng: ngũ cốc (55%), trứng (48%)

→ Đặt iPhone + ốp lưng + cáp sạc CÙNG KHO
→ Giảm xác suất split shipment từ 30% xuống 12%
-- Tính SKU affinity từ dữ liệu order
SELECT
    a.sku AS sku_a,
    b.sku AS sku_b,
    COUNT(DISTINCT a.order_id) AS co_occurrence,
    COUNT(DISTINCT a.order_id)::float / 
      (SELECT COUNT(DISTINCT order_id) FROM order_items WHERE sku = a.sku) AS affinity_score
FROM order_items a
JOIN order_items b ON a.order_id = b.order_id AND a.sku < b.sku
GROUP BY a.sku, b.sku
HAVING COUNT(DISTINCT a.order_id) > 100
ORDER BY affinity_score DESC;

Metrics Last-Mile

MetricÝ nghĩaMục tiêu
Cost per deliveryChi phí trung bình mỗi lần giao< 15.000đ
Stops per routeSố điểm dừng mỗi lộ trình> 25
Delivery densitySố kiện/km²> 5
First attempt success% giao thành công lần đầu> 95%
Split shipment rate% đơn bị tách< 15%
On-time delivery% giao đúng hẹn> 98%

Phần cuối cùng — đến lúc thực hành! Bạn sẽ xây dựng Mini Order Allocation Engine với 1 kho, N tài xế có min/max capacity, và đơn hàng có capacity cost khác nhau. Đọc tiếp Phần 6 — Thực hành: Xây dựng Mini Order Allocation Engine.