はじめに
Odooでは『モデル』がデータの設計図です。受注や請求、在庫移動など、業務で扱うあらゆるデータはモデルとして定義され、データベースに格納されます。
モデルの理解は、開発者だけでなく業務担当にも不可欠です。モデルがフィールド、関連、業務ロジックの土台となり、システム挙動の多くを決めます。
この記事はOdooにおける重要モデルの一つ、stock.moveに焦点を当てます。倉庫周りのカスタム機能、外部システム連携、在庫ワークフローの設定を行う際、必ず触れるモデルです。
stock.moveとは何か
stock.moveは製品の“移動”を表すレコードです。棚から出て別のロケーションに移るたびに1件の移動が記録され、出荷・入荷・棚替えなど全てがこのモデルで表現されます。
Inventory(在庫)モジュールがこのモデルを中心に動きます。販売、購買、製造、ECなど複数機能が在庫操作を行う際にstock.moveを生成・更新します。出荷確定や入庫受入、製造完了はすべてstock.moveの作成・更新を伴います。
stockモジュールで基本定義され、他モジュールは継承して必要な連携フィールドを追加します。Saleはsale_line_id、Purchaseはpurchase_line_id、Manufacturingはproduction_idといった具合に、重複を避けつつ機能を拡張します。
モデル内の主要フィールド
以下はstock.moveで頻繁に使う主要フィールドです。これらを押さえると在庫移動の処理やカスタマイズがぐっと楽になります。
1. name
型:Char。移動のタイトルや説明を格納します。通常は製品名や数量から組み立てられ、一覧表示での識別に使われます。
2. product_id
型:Many2one (product.product)。移動対象の商品。必須フィールドで、数量管理や在庫ルール適用の基点になります。
3. product_uom
型:Many2one (uom.uom)。数量の単位。通常は製品の標準単位と一致し、数量がどの単位で表されるかを示します。
4. product_uom_qty
型:Float。移動要求の数量(要求量)。処理完了後はquantity_doneに実際に処理された数量が入ります。
5. quantity
型:Float。表示用または計算用の数量フィールド。product_uom_qtyと同じ場合も、別単位に換算した表示の場合もあります。
6. location_id
型:Many2one (stock.location)。出発元ロケーション。どこから商品が出るのかを示します。必須。
7. location_dest_id
型:Many2one (stock.location)。到着先ロケーション。どこへ移動するかを示す必須フィールドです。
8. picking_id
型:Many2one (stock.picking)。この移動を束ねるピッキング(伝票)。出荷指示や入庫伝票で関連付けられ、ユーザー操作はピッキング単位で行われます。
9. picking_type_id
型:Many2one (stock.picking.type)。操作種別を表します(出荷・入荷・社内移動など)。デフォルトロケーションやワークフローを決める重要な要素です。
10. state
型:Selection。移動の状態(draft / waiting / confirmed / assigned / done / cancelled)。在庫の引当や完了判定に使われます。
11. date
型:Datetime。予定日時。優先順位付けや運用スケジュールに使われます。
12. date_deadline
型:Datetime。納期や約束日。顧客納品の約束日管理や緊急度判定に利用されます。
13. origin
型:Char。元のドキュメント参照(受注番号や発注番号など)。トレーサビリティのために重要です。
14. move_dest_id
型:Many2one (stock.move)。チェーン先の移動。ある移動が次の移動を生む場合、このリンクでつなぎます。
15. move_orig_ids
型:One2many (stock.move)。元となる移動の一覧。move_dest_idの逆参照で、どの移動が本移動に繋がっているかを示します。
16. move_line_ids
型:One2many (stock.move.line)。ロット/シリアルや実際のピッキング詳細を持つ行。引当や処理時に詳細なmove.lineが生成されます。
17. partner_id
型:Many2one (res.partner)。取引先(顧客や仕入先)。配送先や請求先、レポート集計に使います。
18. company_id
型:Many2one (res.company)。マルチカンパニー環境で所属する会社を示します。表示権限やインターカンパニー規則に影響します。
19. quantity_done
型:Float。実際に処理された数量。ピッキング検品や受入入力で更新され、要求数量と一致すれば移動は完了となります。
20. reserved_availability
型:Float。この移動のために確保された在庫量。割り当て(assigned)時に更新され、利用可能量の把握に使います。
21. create_date
型:Datetime。レコード作成日時。監査やレポートで参照します。
22. write_date
型:Datetime。最終更新日時。データ更新のタイムスタンプとして有用です。
23. sequence
型:Integer。ピッキング内での表示順。小さい順に表示され、ユーザーの作業順序に影響します。
24. priority
型:Selection。緊急度。通常は標準(0)や優先(1)などを持ち、スケジューリングで優先順位に影響します。
25. description_picking
型:Char。ピッキング用メモや特記事項。作業指示や取り扱い注意を伝えるために伝票上で表示されます。
26. reference
型:Char。社内参照や外部連携用コード。外部システムと紐付ける際に便利です。
27. group_id
型:Many2one (procurement.group)。調達グループ。同じ調達から発生した移動をまとめて管理するためのキーです。
28. procure_method
型:Selection。Make to Stock(在庫引当)かMake to Order(発注・生産トリガー)かを決めます。調達挙動に直結します。
29. sale_line_id
型:Many2one (sale.order.line)。販売モジュールが付与するリンク。どの受注行がこの移動を作ったか追跡できます。
30. purchase_line_id
型:Many2one (purchase.order.line)。購買モジュール由来のリンク。仕入れの受入と紐づけられます。
31. production_id
型:Many2one (mrp.production)。製造モジュールが付与するリンク。原料の消費や製品の入庫を製造指示と関連付けます。
32. active
型:Boolean。ソフトデリート用フラグ。Falseにするとアーカイブ扱いになり、既定ビューから隠れます。
業務フローでの使われ方
1. 顧客への出荷
受注確定で受注行ごとにstock.moveが生成されます。出発元は社内在庫ロケーション、到着先は顧客ロケーションとなり、ピッキングでまとめられます。倉庫が出荷処理を行うとquantity_doneが更新され、stateがdoneになります。
2. 仕入品の入庫
発注確定時に入荷用のstock.moveが作られます。仕入先ロケーションから社内在庫への移動として扱われ、入荷時に検品してquantity_doneを登録します。
3. 社内移動
倉庫間や棚替えなど社内での移動にもstock.moveを使います。出発先と到着先のロケーションを指定して、補充や在庫バランス調整を行います。
4. 製造関連
製造オーダーは原材料を生産エリアへ移す移動と、完成品を倉庫へ戻す移動の双方を作ります。production_idで製造オーダーに紐づき、出力はmove_dest_idで下流の出荷へ連結されることが多いです。
5. 返品とスクラップ
顧客返品は逆方向の移動で表現され、スクラップは廃棄ロケーションへの移動として処理されます。どの操作かはpicking_type_idで判定され、同じモデルで全て扱います。
開発者による拡張方法
開発者はOdooの継承パターンを使ってstock.moveを拡張します。モデル継承が代表的な手法です。
モデル継承について
_modelの継承である _inherit = 'stock.move' を使い、新フィールド追加やメソッドの上書きを行います。拡張は別モジュールにまとめることでアップグレード性を保てます。
フィールド追加の方法
継承モデルに新しいOdooフィールドを定義します。CharやMany2one、Boolean、Integer、Text、Selection等を用途に合わせて選びます。マルチカンパニーではcompany-dependentな設計も検討しましょう。移動に関する拡張例はトラッキング番号や配送業者参照、バッチ属性などです。
Pythonでの拡張
_action_doneや_action_assign、_action_cancel等をオーバーライドして追加ロジックを組みます。既存処理はsuper()で呼び出し、在庫更新やチェーン処理を壊さないよう注意してください。
Odoo Studioの活用
Odoo Studioならコードを書かずにフィールド追加が可能で、簡単なフォーム改修や表示項目の追加に向いています。ただし高度なワークフロー変更や複雑なロジックはカスタムモジュールで実装した方が保守性が高くなります。
ベストプラクティス
- location_idとlocation_dest_idは必ず正しく設定すること。誤ったロケーションは在庫数量の齟齬を招きます。
- 関連する移動は必ずpicking_idでまとめる。伝票に属する移動を個別に作ると引当や作業が混乱します。
- API連携ではXML-RPCやJSON-RPCを使います。stock.moveはAPIで公開されているため、外部IDのマッピングは慎重に行ってください。
- 独自フィールドにはモジュール接頭辞(x_や自社プレフィックス)を付け、将来のOdooバージョンとの衝突を避けましょう。
- プログラムでチェーン移動を生成する際はmove_dest_idとmove_orig_idsを正しくリンクし、トレーサビリティを保つこと。
- 検証時はproduct_uom_qtyとquantity_doneの差異に注意。部分出荷や部分受入が発生するため、数量の扱いを設計で許容しておきます。
よくある失敗例
- 誤ったロケーション種別で移動を作成すること。出発と到着が両方とも顧客ロケーションなど、矛盾した組合せは避けてください。
- move_lineが存在する状態でproduct_uom_qtyを勝手に変更すること。既存の移動行と数量の不整合を生み、在庫差異を引き起こします。必要ならキャンセルして再作成するべきです。
- originを未設定のままにすること。出所が分からない移動は監査やトレーサビリティで問題になります。
_action_doneを上書きしてsuper()を呼ばない実装。結果として在庫残高更新や他モジュール連携が壊れる可能性があります。- 正しいワークフローを通さずに直接moveを作ること(例:pickingを経由しない)。引当や割当処理が機能しなくなるリスクがあります。
- 分割・結合時にmove_dest_idを無視すること。チェーンが切れて移動が孤立し、トレーサビリティが失われます。
まとめ
stock.moveはOdooの在庫管理の中核です。ロケーション間のあらゆる流れを記録し、フィールドや外部モジュールによる拡張で多様な業務を実現します。仕組みを理解すれば、設定やカスタマイズ、連携が確実になります。
倉庫プロセスを設計する業務担当者でも、カスタムモジュールを作る開発者でも、stock.moveの理解があれば工数削減とミス防止につながります。
Odoo導入の支援が必要ですか?
DasoloはOdoo導入・カスタマイズ・最適化を支援します。API連携や開発に強みがあり、stock.moveを含むデータ設計の豊富な経験があります。
Odooの導入やカスタム開発、外部連携でお困りなら、お気軽にご相談ください。 デモを予約する プロジェクトについて詳しくお話ししましょう。