WOaky / 生産実績連携
会津の工場・梱包アプリ(GAS製・通称「みつるシステム」)で日々つけている生産実績を、 基幹システム WOaky に自動で流し込み、伝票登録と在庫反映まで一気に済ませる連携です。 これまで運営課が基幹に手打ちしていた分が丸ごと不要になります。
現場の入力からWOakyの在庫が動くまで、そして結果がシートに返るまで。
ポイントは 「アーカイブ=確定」 という取り決めです。 現場が入力した実績を運営課が目視チェックしてアーカイブした行だけが送信対象になり、 WOakyはそれを受け取った瞬間に完了扱いで在庫まで反映します(実績取込方式)。 WOaky側に承認画面はありません。
1行 = 1生産伝票。1リクエストに最大500件まとめられます。
// POST /api/production-slips/import // Authorization: Bearer <GAS_IMPORT_TOKEN> ※値はHeroku環境変数。ここには載せません { "dry_run": false, // true にすると検証のみ(→ 5章) "slips": [ { "external_key": "20260724_1000201_0003_1", "produced_at": "2026-07-24", "warehouse_code": "0003", "product_code": "1000201", "completed_quantity": 100, "adjustment_quantity": -10, "b_grade_quantity": 5, "b_grade_product_code": "1000201-1", "disposal_quantity": 10, "return_quantity": 20, "single_product_code": "*1000201" } ] }
| 項目 | 必須 | 内容 |
|---|---|---|
| external_key | 必須 | 行を一意に特定するキー。GAS側は YYYYMMDD_商品コード_倉庫コード_連番 で発番。同じキーの2回目以降はスキップされる(=再送しても二重登録されない) |
| produced_at | 必須 | 生産日(YYYY-MM-DD) |
| warehouse_code | 必須 | 生産倉庫コード。GAS側が送った値がそのまま正(WOaky側で固定・補正はしない) |
| product_code | 必須 | 完成品の商品コード |
| completed_quantity | 必須 | 完成品数。0以上の整数。0でも伝票は成立する(B品・処分・返品の振替だけ走る) |
| adjustment_quantity | 任意 | 過不足。完成数に加算される。現在は意味の食い違いのため送信停止中(→ 5章) |
| b_grade_quantity | 任意 | B品数 |
| b_grade_product_code | B品ありなら必須 | 振替先のB品コード(現場が入力) |
| disposal_quantity | 任意 | 処分数 |
| return_quantity | 任意 | 返品数 |
| single_product_code | B品/処分/返品ありなら必須 | 振替元の単品コード(*付き)。現場が入力 |
受信した1行につき、以下の4パターンが該当分だけ実行されます。全ての在庫移動は stock_ledgers に記録されます。
完成数が0のときは在庫加算もBOM展開も行いません。BOMは商品マスタの部品構成から自動で発火します。
倉庫は動かさず、品番だけ変わります。どのB品コードに振り替えるかは現場の知識なので、システムでは引けません(→ 5章)。
その場で在庫から消さず、いったん処分倉庫に寄せます(廃棄待ちの見える化)。実際に捨てるときに処分倉庫から落とす2段階運用です。
返品倉庫0098は出荷不可(can_ship=false)。当初話していた「素地コードへの振替」は戻し先の自動判別ルールが決まらず、単純版で確定させています。
| コード | 名称 | 実データから見た性格 |
|---|---|---|
| 0002 | 会津 | 在庫650件中、単品は14件(2%)= ほぼ完成品の置き場 |
| 0003 | 会津工場 | 在庫1,170件中、単品266件(23%)= 単品と完成品が混在 |
| 0024 | 不良商品 | 在庫49件中、単品38件(78%)= 検品で弾いた単品の置き場に見える。用途未確定・連携では未使用 |
| 0025 | 会津処分 | 処分の振替先(連携で使用) |
| 0098 | 返品 | 返品の振替先(連携用に新設・出荷不可) |
製造6部門(成形・会津工場・第1工場・第2工場・スクリーン・梱包)に対応する倉庫は存在しません。6部門は「会津工場という1拠点の中の工程」です。
送信した全行の結果が、送信順のまま返ります。GAS側はそれをそのままシートの各行に書き戻せます。
取込成功。WOakyで発番した伝票番号(PP-YYYYMMDD-nnn)が返ります。
dry_run のときのみ。取込可能だが登録はしていない状態。伝票番号は返りません。
同じ external_key が取込済みのためスキップ。再送しても二重にならない仕組み。
その行だけ失敗。error_code / field / value と日本語メッセージが返ります。
1行ずつ独立したトランザクションで処理するので、エラー行があっても正常な行は取り込まれます。
HTTPステータスは全行OKなら 200、エラー行が1件でもあれば 207。
認証エラーは 401、リクエスト自体の形式エラー(slipsが無い・501件以上)は 422 です。
{
"summary": { "total": 4, "imported": 1, "skipped": 1, "error": 2 },
"results": [
{ "index": 0, "status": "imported", "slip_no": "PP-20260724-001",
"message": "取り込みました(伝票番号 PP-20260724-001)" },
{ "index": 1, "status": "skipped", "slip_no": "PP-20260723-005",
"message": "取込済みのためスキップしました(伝票番号 PP-20260723-005)" },
{ "index": 2, "status": "error", "error_code": "product_not_found",
"field": "product_code", "value": "ZZZ-9999",
"message": "商品コード ZZZ-9999 が商品マスタに見つかりません" }
]
}
| error_code | 意味 | 直す人 |
|---|---|---|
| validation_failed | 必須欠落・型違いなど。fieldに対象項目 | 現場(シート) |
| product_not_found | 商品コードがWOakyの商品マスタに無い | 現場 or マスタ登録 |
| warehouse_not_found | 倉庫コードが倉庫マスタに無い | 現場 or マスタ登録 |
| single_product_required | B品/処分/返品があるのに単品コードが無い | 現場(シート) |
| b_grade_product_code_required | B品があるのにB品コードが無い | 現場(シート) |
| completed_negative | 過不足を足したら完成数がマイナスになった | 運営課で確認 |
| disposal_warehouse_missing return_warehouse_missing | WOaky側の設定不備(0025/0098が無い) | 岡崎 |
| unexpected | 想定外のエラー | 岡崎 |
2026-08-05追加。連携開始前に、在庫を1件も動かさずにエラーだけ洗い出すための仕組み。
このAPIは受信した瞬間に伝票を completed で登録して在庫まで動かすため、これまで「試しに送る」ができませんでした。
しかも一度送った行は external_key が取込済みになり、あとから本番として入れ直せません。
公式運用開始まで時間があるうちにエラーを潰しきるために、検証専用の口を用意しました。
{
"dry_run": true,
"slips": [ ... ]
}
// 返り
{
"dry_run": true,
"summary": { "total": 2, "imported": 0, "validated": 1, "skipped": 0, "error": 1 },
"results": [
{ "index": 0, "status": "validated",
"message": "取込可能です(検証のみ。伝票は登録していません)" },
{ "index": 1, "status": "error", "error_code": "product_not_found",
"field": "product_code", "value": "ZZZ-9999",
"message": "商品コード ZZZ-9999 が商品マスタに見つかりません" }
]
}
external_key を消費しない — 何度投げても、あとから同じキーで本番送信できる(ここが一番大事)dry_run / summary.validated)なので、既存のGAS実装は書き換えなくても動く
本番環境(v74)で動作確認済み。存在しないコードは product_not_found、実在するコードは validated を返し、
同じ external_key を再送しても消費されないことを確認しています。
7/23〜8/3のやりとりで固まった設計判断。ここが連携の性格を決めています。
* 付きコードで単品を自動特定する案は、該当率97%で例外があり不採用。
B品はさらに厳しく、2026-07フルダンプ(商品9,375件)で調べたところ、
単品2,012件のうち規則どおり(コード+"-1")のB品が実在するのは20件=1%。
規則で導出すると99%が存在しないコードになります。
「この単品でB品が出たらどのB品コードへ振り替えるか」は現場の知識で、マスタから導出できません。
※ GAS側から「マスタが二重持ちになるのでは」という指摘がありましたが、GAS側に持つのは対応表ではなく入力欄です。対応表はWOaky側にしか存在しません。
warehouse_code を受ける作りなので改修不要でした。
現場が入力した倉庫にそのまま在庫が立ちます。
8/3にGAS側の実装コード(Code.gs / index.html)を突き合わせて分かったこと。修正依頼済みです。
アーカイブ後に工場側が実績を修正すると、差分だけが新しい行として現れます。
GAS側の api_getOpsViewData が「工場の最新値 − アーカイブ済み合計」を全項目で引き算しているためで、
工場が下方修正すれば良品・B級・処分・返品・過不足のどれもがマイナスになりえます。
単品/B品コードの持ち方、返品の戻し先が未決のまま終了。
案A採用、処分は0025へ振替、返品は0098へ単純振替。仕様書v2をGAS側へ共有。
summary + results 形式に。シートへそのまま書き戻せる設計へ。
案Aを実データ根拠つきで維持、0003固定を撤回、返品はv2が正、と回答。
ドライラン結果は送信可218件/要確認242件(大半は単品コード未入力)。差分行の正体と3つの穴が判明。
公式運用開始まで時間があるうちに繋いでエラーを潰しきるため。在庫を汚さず何度でも試せる。
倉庫・商品マスタを整えてから dry_run で残りのエラーを潰す。連携開始日は運営課に「基幹への手打ちをいつまで続けるか」を確認して日単位で切る。未設定のうちは何も送らない既定。
b_grade_warehouse_code 等)。現状はB品=生産倉庫、処分=0025、返品=0098でハードコード。運用が固まってから判断dry_run を渡すだけ。仕様書v3にサンプルコードあり)* が付く。スクリーン作業で別の単品になることもある