OTIF准时足量交货分析 — 供应商交货履约率量化与预测性缓冲策略
Skill-OTIF-On-Time-In-Full-Analytics · 04-供应链
1. 解决的问题
供应商OTIF 71%被当成"还行",实际月隐性成本$2653——OTIF量化将供应商真实成本水落石出,迁移至高OTIF供应商年净节省$23436(即使报价高5%)
2. 核心算法逻辑
业务背景(陈凤霞实战经验):书中强调OTIF(OnTime InFull,准时足量)是评估供应商/物流商最核心的KPI之一。"OnTime"=按承诺交期到货,"InFull"=按承诺数量足量到货,两个条件同时满足才算OTIF=1,任何一个不满足即OTIF=0(不可按比例)。书中目标:稳定供应商OTIF≥95%;波动大的供应商必须额外持有缓冲库存以吸收其不确定性,而这个缓冲库存的成本最终应被归因到该供应商的"真实采购成本"中。
3. 业务应用场景
- 业务问题:某卖家有5家供应商,直觉认为"都还不错",但实际上1家吸奶器供应商连续3个月交期平均延迟8天,每次导致FBA库存告急触发空运补货,额外成本$8/件 - 数据要求:12个月采购订单记录(承诺交期/实际交期/承诺数量/实际到货量) - 算法应用: 1. 计算5家供应商OTIF:S-001=96%(优秀),S-002=87%(待改进),S-003=71%(不合格),S-004=94%,S-005=98% 2. S-003 OTIF 71%,计算隐性成本:每月多持有安全库存400件($15200),月资金成本$253;加上因延误触发空运约$2400/月,真实月成本额外$2653 3. S
- **业务问题**:Q4大促前2个月下了大额备货订单,担心历史OTIF 87%的供应商再次延误,影响Prime Day库存 - **算法应用**:ML模型预测该订单OTIF失败概率45%(基于旺季产能紧张+当前铜价上涨);触发:提前2周催单+安排质检驻场+备用供应商预下小批量订单(保底) - **预期产出**:大促备货到位率从历史87%提升至95%,旺季缺货风险大幅降低
4. 输入数据要求
请查看原始代码模板获取输入规格。
5. 输出结果
请查看原始代码模板获取输出规格。
6. 业务价值 / ROI
- ROI 预估:识别1个OTIF 71%的问题供应商,月隐性成本约$2653;迁移至OTIF 97%的替代供应商后月净节省$1953,年化$23436;系统建设成本$3万,ROI≈78%首年,第二年起ROI=781%
- 实施难度:⭐⭐☆☆☆(数据全在采购PO系统里,建模逻辑简单;关键是建立"每个PO必须记录实际到货日和到货量"的数据规范)
- 优先级:⭐⭐⭐⭐⭐(供应商管理最被低估的维度,OTIF量化能直接改变供应商谈判筹码和选择决策)
- 适用规模:每月>5个采购订单的卖家
- 数据依赖:采购PO系统(承诺交期/实际到货日/承诺数量/实际到货量)、延误根因记录
7. 代码模板
代码块数量:2 · 路径:未检测到
"""
OTIF准时足量交货分析系统
功能:OTIF精确计算 + 缓冲库存成本化 + 供应商分级 + 根因归因 + 预警
"""
import numpy as np
import pandas as pd
from dataclasses import dataclass, field
from typing import List, Dict, Optional, Tuple
from datetime import datetime, timedelta
import warnings
warnings.filterwarnings('ignore')
@dataclass
class PurchaseOrder:
"""采购订单记录"""
po_id: str
supplier_id: str
sku_id: str
promised_qty: int
actual_qty: int
promised_date: datetime
actual_date: datetime
delay_reason: str = "" # 根因类型
@property
def on_time(self) -> bool:
return self.actual_date <= self.promised_date
@property
def in_full(self) -> bool:
return self.actual_qty >= self.promised_qty * 0.98 # 允许2%短装
@property
def otif(self) -> bool:
return self.on_time and self.in_full
@property
def delay_days(self) -> int:
return max((self.actual_date - self.promised_date).days, 0)
@property
def fill_rate(self) -> float:
return self.actual_qty / max(self.promised_qty, 1)
class OTIFAnalyzer:
"""OTIF分析引擎"""
OTIF_GRADES = {
(0.97, 1.00): ('🟢优秀', '正常合作,优先选用'),
(0.90, 0.97): ('🟡良好', '一般监控,关注趋势'),
(0.80, 0.90): ('🟠待改进', '发送改进通知,增加缓冲库存'),
(0.00, 0.80): ('🔴不合格', '限制新订单,评估替换'),
}
DELAY_REASONS = [
'PRODUCTION_DELAY', 'MATERIAL_SHORTAGE', 'QUALITY_FAIL',
'LOGISTICS_DELAY', 'DOCUMENT_ISSUE', 'OTHER',
]8. 论文来源
- 2403.04521