# 依頼文

作業フォルダ: <lab>\runs\4_1（リポジトリ harukaze）

## 1. 目的
harukaze に新しいサブコマンド order-suggest を足します。`python -m harukaze order-suggest --date 2026-10-26` と打つと、基準日の時点で有効在庫が発注点を下回っている「販売中」の商品と、その発注数が CSV で標準出力に出るようにします。出力は既存の発注書 CSV と同じ列に「保留」列を足した形にし、仕入先ごとに並べます。

## 2. 背景
購買担当は毎週月曜、発注点を切った商品を目で探して発注書を作っています。時間がかかり、見落としも出ています。このコマンドの出力は、そのまま発注書づくりに使います。

## 3. 触ってよい範囲
- 新しく足してよいファイル: harukaze/ 直下の .py を1つ（例: harukaze/suggest.py）と、tests/ 直下の test_*.py を1つ（例: tests/test_suggest.py）
- 既存で変えてよいファイル: harukaze/cli.py（サブコマンドの登録だけ）、README.md（「コマンド一覧」の表に1行足すだけ）

## 4. やらないこと
- 上の範囲以外のファイルやフォルダは、作らない・変えない・消さない。data/ の CSV、harukaze/orders.py、harukaze/stock.py、harukaze/store.py、harukaze/csvout.py、tests/helpers.py と既存のテストファイルも含みます。
- orders.py の PO_COLUMNS は書き換えない。po-export の出力は今と1文字も変えない。
- 出力ファイルを作業フォルダに残さない（テストで使う一時ファイルは一時フォルダに作る）。
- コミットしない。
- 仕入先の最低発注金額（suppliers.csv）は、今回は使わない。
- Python の標準ライブラリ以外は使わない。

## 5. 決まり（要件）
1. サブコマンド名は order-suggest。cli.py の command デコレータで登録する。--date（YYYY-MM-DD）は必須とし、既存の _date_arg を使う。--data-dir は他のコマンドと同じように受け付ける。
2. 対象は、products.csv の状態が「販売中」の商品だけ。「終売予定」など、それ以外の状態の商品は候補に出さない。
3. 有効在庫は「基準日時点の現在庫 ＋ 発注済み未入荷の数 − 引当済みの数」。既存の関数をそのまま使う。現在庫は stock.py の stock_as_of（基準日を含めて、その日までを数える）、発注済み未入荷は stock.py の open_orders の行のうちその商品の数量の合計、引当済みは stock.py の allocated_qty、足し引きは stock.py の available_stock で行う。open_orders の行は、発注日・入荷予定日で絞らずにすべて数える。
4. 候補にするのは、有効在庫が発注点より小さい商品だけ。有効在庫と発注点が等しい商品は候補にしない。発注点が 0 でも同じ規則で判断する（有効在庫がマイナスなら候補になる）。
5. 発注数は「発注点の2倍 − 有効在庫」を、orders.py の round_up_to_case で入数の倍数に切り上げた数。
6. 列は orders.py の PO_COLUMNS と同じ並び（仕入先コード、仕入先名、商品コード、商品名、入数、発注数、仕入単価（税抜）、金額）で、その末尾に「保留」列を1つ足す。PO_COLUMNS は書き換えず、新しいファイル側で列の並びを定義する。仕入先名は suppliers.csv から引き、金額は発注数 × 仕入単価（税抜）。保留以外の各列の値の作り方は、po-export（orders.py の build_po_rows）に合わせる。
7. 行の並びは、仕入先コードの昇順、同じ仕入先の中では商品コードの昇順。
8. 書き出しは csvout.py の write_csv を使う（UTF-8、改行 LF、見出し行あり）。候補が0件なら見出し行だけを出して、終了コード 0。
9. 商品の仕入先コードが suppliers.csv にないときは、cli.py の main がすでに持っているエラー処理に任せる（エラーメッセージを標準エラーに出して終了コード 1）。そのために新しい例外処理は足さない。
10. 「保留」列の値をどう決めるかは、まだ決まっていない（依頼者に確認中）。推測で決めないこと。列は末尾に置き、値はいったん空欄にしてかまいません。保留の値の決め方について知る必要があることは、最終メッセージに質問として書いてください。質問は1行に1つにしてください。
11. README.md の「コマンド一覧」の表に、order-suggest の行を1行足す。

## 6. 注意点
- 基準日の当日に記録された入出庫も含めて数える（stock_as_of と同じ扱い）。
- 商品コード・仕入先コードは固定幅の文字列なので、文字列のまま並べてよい。
- テストのデータは、既存のテストと同じく tests/helpers.py の make_data_dir で一時フォルダに作る。CLI のテストは tests/test_cli.py の run_cli と同じ方法（subprocess、PYTHONIOENCODING=utf-8）で動かす。
- 環境は Windows。標準出力に CR が混ざらないこと（write_csv を使えば守られる）。
- 同梱の data/ で基準日 2026-10-26 のとき、期待する行は次の10行（仕入先コード, 商品コード, 発注数）。
  201,1001,50 / 201,1022,50 / 201,1023,20 / 202,1007,40 / 202,1009,18 / 202,1014,10 / 203,1004,80 / 203,1012,60 / 204,1015,20 / 204,1018,15
  入らないことを確かめたい商品: 1003 と 1006（発注残を足すと発注点以上）、1019 と 1024（発注点と等しい）、1011 と 1020（終売予定）、1017（発注点 0、有効在庫はプラス）。

## 7. 完了の条件と確かめ方
- `python -m unittest discover -s tests` を作業フォルダで実行し、既存のテストと新しいテストがすべて通る。
- 新しいテストで、少なくとも次を確かめる: 等しいときは候補にしない、終売予定を除く、発注残と引当を数に入れる、入数で切り上げる、仕入先→商品の順に並ぶ、列の並び（PO_COLUMNS の後に保留）、0件なら見出しだけ、--date がないとエラー。
- `python -m harukaze order-suggest --date 2026-10-26` の出力が、6. に書いた10行と一致する（保留列を除く）。
- `python -m harukaze po-export` の出力と、既存のテストの結果が変わっていない。
- 3. 以外のファイルに変更がなく、作業フォルダに出力ファイルが残っていない。
- 最終メッセージには、変えたファイル、テストの結果、5.10 の保留についての質問（あれば）を書いてください。

分からない点があれば、変更せずに質問を列挙して終えてよい。
