今日、架空の発注表をPythonで試したら、同じ商品Aの追加発注が36個から0個に変わりました。入荷予定の24個を計算に入れた結果です。手元の残りだけで発注数を決めると、買い足しすぎる。僕は入荷予定まで同じ表に置きたいです。
商品Aは在庫12個、受注済みの引当10個。すぐ使える数は2個です。ここだけ見て「30個まで補充する」と、足りない28個を発注したくなります。12個入りの箱で買うなら36個。
ところが、すでに24個を注文済みでした。これも補充の計算に含めると26個。今回決めた発注点15個を上回るので、追加は0個になりました。発注前にこの差を出す。ここ地味に効きます。
Pythonで発注点と箱単位を試す
この例では「引当後の在庫+確定した入荷予定」が15個以下になったら、30個まで補充します。発注は12個単位。15、30、12は説明用の設定値です。需要予測から求めた数字ではありません。
Python 3.14.8で実行済み。追加パッケージは不要です。order_check.pyに保存し、python3 order_check.pyで動きます。外部へ発注する処理はありません。
def plan(stock, reserved, incoming, point=15, target=30, lot=12):
values = (stock, reserved, incoming, point, target, lot)
if any(type(v) is not int or v < 0 for v in values):
raise ValueError("数量は0以上の整数")
if lot == 0 or target < point:
raise ValueError("箱数と発注設定を確認")
available = stock - reserved
position = available + incoming
order = 0
if position <= point:
gap = target - position
order = ((gap + lot - 1) // lot) * lot
return available, position, order
cases = {
"A": (12, 10, 24),
"B": (12, 10, 0),
"C": (20, 5, 0),
}
assert plan(*cases["A"]) == (2, 26, 0)
assert plan(12, 10, 0)[2] == 36
assert plan(*cases["B"]) == (2, 2, 36)
assert plan(*cases["C"]) == (15, 15, 24)
assert plan(16, 0, 0)[2] == 0
assert plan(0, 4, 0)[2] == 36
try:
plan(12, 10, 0, lot=0)
except ValueError as e:
assert str(e) == "箱数と発注設定を確認"
else:
raise AssertionError("箱数0を通してはいけない")
for sku, args in cases.items():
a, p, q = plan(*args)
print(f"{sku}: 引当後={a}, 入荷込み={p}, 発注={q}")
実行結果です。
A: 引当後=2, 入荷込み=26, 発注=0
B: 引当後=2, 入荷込み=2, 発注=36
C: 引当後=15, 入荷込み=15, 発注=24
商品AとBは、入荷予定だけが違います。Aの入荷予定を0にした検証でも36個になりました。架空データなので、削減実績としては数えません。
商品Cは境目の確認用。15個ちょうどでも発注するよう、条件を<=にしました。16個なら0個。ここが曖昧だと、表計算とスクリプトで結果が食い違います。
箱単位の計算も一段あります。Bの不足は28個なので、(28 + 11) // 12で3箱に切り上げ、36個を返します。引当後の2個に足すと38個。目標30個を8個超えますが、12個単位ならそうなります。assertには引当が在庫を超えた場合も入れました。差が負になった分も補充数に加わります。
発注表に持ち込む前に
入荷込みの26個を、今日出荷できる数として使うと困ります。Aでいま使えるのは2個。発注の計算と出荷の確認には、それぞれの数字を残します。「在庫」という列名だけだと、後から読む人も迷いますね。
この計算は日付を持ちません。入荷前に追加の注文が来るか、仕入先が遅れるかは判定できません。実際の表では、どの期間の入荷予定を含めるか決める必要があります。未確定の注文や、すでに入庫して在庫へ足した数量を含めると、発注数が少なく出ます。
在庫と引当も同じ時点でそろえます。出荷後に在庫だけ更新し、引当を残すと二重に引きます。返品や複数倉庫は今回の範囲外です。
まずは商品別に、引当後・入荷込み・発注数を並べて確認します。自動発注まで進めるなら、その前に入庫や出荷で各列をいつ更新するか決めたいです。手作業が減るほど、更新のずれが発注数に出やすくなると見ています。あなたの業務では、発注点と発注単位にどの設定値を使いますか。
