WOaky / 生産実績連携

みつるシステム → WOaky
生産実績連携のしくみ

会津の工場・梱包アプリ(GAS製・通称「みつるシステム」)で日々つけている生産実績を、 基幹システム WOaky に自動で流し込み、伝票登録と在庫反映まで一気に済ませる連携です。 これまで運営課が基幹に手打ちしていた分が丸ごと不要になります。

WOaky側 実装・本番デプロイ済(2026-07-24 / PR #8) GAS側 実装完了・ドライラン済(2026-08-03) dry_run(お試し送信)追加(2026-08-05 / PR #13・v74) 連携開始日 未定 過不足の扱い 保留

1. 全体像

現場の入力からWOakyの在庫が動くまで、そして結果がシートに返るまで。

ポイントは 「アーカイブ=確定」 という取り決めです。 現場が入力した実績を運営課が目視チェックしてアーカイブした行だけが送信対象になり、 WOakyはそれを受け取った瞬間に完了扱いで在庫まで反映します(実績取込方式)。 WOaky側に承認画面はありません。

工場アプリ / 梱包アプリ 成形・塗り・スクリーン・梱包 良品 / B級 / 処分 / 返品 を入力 単品コード・B品コードも入力 みつるシステム(GAS) 運営課が目視チェック アーカイブ=確定 送信前チェック4種 WOaky 受信API POST /api/ production-slips/import Bearer認証・最大500件/回 WOaky 本体 生産伝票を completed で登録 在庫を増減 stock_ledgers に全件記録 日次 JSON 結果を行ごとにシートへ書き戻し 取込済 / 取込済(重複) / エラー理由 + エラー時はメール通知 results(送信順・全行分)

2. 送るデータ

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_codeB品ありなら必須振替先のB品コード(現場が入力)
disposal_quantity任意処分数
return_quantity任意返品数
single_product_codeB品/処分/返品ありなら必須振替元の単品コード(*付き)。現場が入力
重要な制約 数量はすべて0以上でしか受けません。マイナスの訂正伝票は受け付けない方針です(→ 5章「負の数量」)。

3. WOaky側で起きること

受信した1行につき、以下の4パターンが該当分だけ実行されます。全ての在庫移動は stock_ledgers に記録されます。

01 完成品を積む+材料を落とす completed_quantity + adjustment_quantity
完成品 指定倉庫 + 調整後の完成数
BOM構成品(複数) 同じ倉庫 − 完成数 × BOM数量

完成数が0のときは在庫加算もBOM展開も行いません。BOMは商品マスタの部品構成から自動で発火します。

02 B品(品番の振替) b_grade_quantity
単品 生産倉庫 B品コードの商品 同じ倉庫

倉庫は動かさず、品番だけ変わります。どのB品コードに振り替えるかは現場の知識なので、システムでは引けません(→ 5章)。

03 処分(倉庫の振替) disposal_quantity
単品 生産倉庫 単品のまま 0025 会津処分

その場で在庫から消さず、いったん処分倉庫に寄せます(廃棄待ちの見える化)。実際に捨てるときに処分倉庫から落とす2段階運用です。

04 返品(倉庫の振替) return_quantity
単品 生産倉庫 単品のまま 0098 返品

返品倉庫0098は出荷不可(can_ship=false)。当初話していた「素地コードへの振替」は戻し先の自動判別ルールが決まらず、単純版で確定させています。

倉庫コードの整理

コード名称実データから見た性格
0002会津在庫650件中、単品は14件(2%)= ほぼ完成品の置き場
0003会津工場在庫1,170件中、単品266件(23%)= 単品と完成品が混在
0024不良商品在庫49件中、単品38件(78%)= 検品で弾いた単品の置き場に見える。用途未確定・連携では未使用
0025会津処分処分の振替先(連携で使用)
0098返品返品の振替先(連携用に新設・出荷不可)

製造6部門(成形・会津工場・第1工場・第2工場・スクリーン・梱包)に対応する倉庫は存在しません。6部門は「会津工場という1拠点の中の工程」です。

4. 返し方とエラー運用

送信した全行の結果が、送信順のまま返ります。GAS側はそれをそのままシートの各行に書き戻せます。

imported

取込成功。WOakyで発番した伝票番号(PP-YYYYMMDD-nnn)が返ります。

validated

dry_run のときのみ。取込可能だが登録はしていない状態。伝票番号は返りません。

skipped

同じ external_key が取込済みのためスキップ。再送しても二重にならない仕組み。

error

その行だけ失敗。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_requiredB品/処分/返品があるのに単品コードが無い現場(シート)
b_grade_product_code_requiredB品があるのにB品コードが無い現場(シート)
completed_negative過不足を足したら完成数がマイナスになった運営課で確認
disposal_warehouse_missing
return_warehouse_missing
WOaky側の設定不備(0025/0098が無い)岡崎
unexpected想定外のエラー岡崎

エラーが出たときの流れ

5. dry_run(お試し送信)

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 が商品マスタに見つかりません" }
  ]
}

4つの性質

設計判断 検証専用のロジックは書かず、本番と同じ処理を通してから必ずロールバックする。 バリデーションだけ別実装にすると、本番経路と挙動がだんだんズレていくためです。 商品・倉庫コードの照合、BOM展開、B品振替、処分/返品倉庫の存在チェックまで、本番と完全に同じ判定結果が返ります。

想定している使い方

本番環境(v74)で動作確認済み。存在しないコードは product_not_found、実在するコードは validated を返し、 同じ external_key を再送しても消費されないことを確認しています。

6. 決着した論点

7/23〜8/3のやりとりで固まった設計判断。ここが連携の性格を決めています。

決定 ① 単品コード・B品コードは人が入力する(案A)。 完成品のBOMから * 付きコードで単品を自動特定する案は、該当率97%で例外があり不採用。 B品はさらに厳しく、2026-07フルダンプ(商品9,375件)で調べたところ、 単品2,012件のうち規則どおり(コード+"-1")のB品が実在するのは20件=1%。 規則で導出すると99%が存在しないコードになります。 「この単品でB品が出たらどのB品コードへ振り替えるか」は現場の知識で、マスタから導出できません。

※ GAS側から「マスタが二重持ちになるのでは」という指摘がありましたが、GAS側に持つのは対応表ではなく入力欄です。対応表はWOaky側にしか存在しません。

決定 ② 倉庫の指定は一律GAS側が正。 仕様書初版の「生産倉庫0003固定」は撤回。APIは元々行ごとに warehouse_code を受ける作りなので改修不要でした。 現場が入力した倉庫にそのまま在庫が立ちます。
決定 ③ 返品は単品のまま0098へ倉庫振替(単純版)。 7/23時点では「返品倉庫にある素地コードへ振替」で話していましたが、戻し先素地コードの自動判別ルールが決まらず、 7/24に単純版で確定。素地コードへの振替は将来課題で実装予定なしです。
決定 ④ WOakyは負の数量(訂正伝票)を受けない。 アーカイブ=目視チェック済み=確定、という前提を守るためです。 ここに訂正の口を開けると1日1品目の在庫の動きが細切れのプラスマイナスに分かれ、あとから追えなくなります。 アーカイブ後の工場側修正は、みつるシステム側かオペレーションで吸収してもらう方針。
保留 ⑤ 「過不足」が何と何の差なのか、両者で認識が違う。
WOaky仕様書v2 … 完成品側の調整(完成100・過不足−10なら完成90として積む)
みつるシステムの画面 … 投入側の差(投入(入力) = 投入(理論) + 過不足)
向きを間違えたまま送ると完成品在庫とBOM構成品の消費が両方ずれて戻すのが面倒なので、 当面は送らない(ops_config の「過不足を送信する」= FALSE、completed_quantity は良品数のみ)。 ズレても数個の規模なので棚卸で吸収できる、という判断です。現場に定義を確認してから決め直します。

7. 見つかった穴

8/3にGAS側の実装コード(Code.gs / index.html)を突き合わせて分かったこと。修正依頼済みです。

「良品0・過不足−1・B品6」という謎の行の正体

アーカイブ後に工場側が実績を修正すると、差分だけが新しい行として現れます。 GAS側の api_getOpsViewData が「工場の最新値 − アーカイブ済み合計」を全項目で引き算しているためで、 工場が下方修正すれば良品・B級・処分・返品・過不足のどれもがマイナスになりえます。

8. これまでの経緯

9. 残っている宿題

WOaky側(岡崎)

みつるシステム側

用語メモ