コンテンツにスキップ

iDempiere 発注照合伝票の使い方|購買管理 操作マニュアル・技術仕様

📖 購買管理の全体像: 購買管理の全体図 も合わせてご覧ください。

発注照合伝票(Matched Purchase Orders)は、発注伝票明細と入荷伝票明細、または発注伝票明細と仕入請求伝票明細を照合した結果を記録・照会する画面です。発注した品目が正しく入荷・請求されたかを確認し、架空請求や過大請求を防ぐための台帳として機能します。

📌 ポイント: 発注照合伝票には 価格差異許容範囲(PriceMatchDifference という専用項目があり、「発注単価」と「請求単価」の差額が明細単位で保持されます。仕入価格の食い違いを調べる起点はこの列です。

  • 発注伝票明細(C_OrderLine)と入荷明細(M_InOutLine)の照合結果の照会
  • 発注伝票明細と仕入請求伝票明細(C_InvoiceLine)の照合結果の照会
  • 照合数量(Qty)と品目・属性セットインスタンスの確認
  • 発注単価と請求単価の価格差異PriceMatchDifference)の確認
  • 承認済み(IsApproved)フラグによる価格差異の承認管理
  • 誤った照合レコードの削除(「削除」ボタン=Processing
  • 転記状態(Posted)と転記日付(DateAcct)の確認

発注照合伝票は 1 タブ構成の照会ウィンドウです。

タブ名テーブル項目数役割
発注照合伝票M_MatchPO18項目発注・入荷・請求の三者照合結果の照会・削除

💡 ヒント: 1 レコードは「発注明細 1 行 × 入荷明細 1 行(および必要に応じて請求明細 1 行)× 数量」の 1 組を表します。分割入荷・分割請求を行うと、その回数だけレコードが増えます。

graph TD
    A["📝 発注伝票を完了"] --> B["📥 入荷伝票を完了<br/>(発注参照)"]
    B --> C["🔗 発注×入荷の照合<br/>M_MatchPO 自動生成"]
    A --> D["🧾 仕入請求伝票を完了<br/>(発注参照)"]
    D --> E["🔗 発注×請求の照合<br/>M_MatchPO 自動生成"]
    C --> F["🔍 発注照合伝票ウィンドウで<br/>照合結果を照会"]
    E --> F
    F --> G{"価格差異<br/>PriceMatchDifference"}
    G -->|差異なし| H["✅ 転記状態を確認"]
    G -->|差異あり| I["🧐 発注単価と請求単価を照合<br/>承認済みフラグで承認"]
    I --> J["🗑 必要なら削除ボタンで<br/>照合を取消し再処理"]

発注伝票を完了 入荷伝票を完了 (発注参照) 発注×入荷の照合 M_MatchPO 自動生成 仕入請求伝票を完了 (発注参照) 発注×請求の照合 M_MatchPO 自動生成 発注照合伝票ウィンドウで 照合結果を照会 価格差異 PriceMatchDifference 転記状態を確認 発注単価と請求単価を照合 承認済みフラグで承認 必要なら削除ボタンで 照合を取消し再処理 差異なし 差異あり

⚠️ 注意: 照合レコードの削除は、発注に対する入荷済/請求済の紐付けを解除します。会計・購買実績に影響するため、原因を特定してから実施してください。

アクセス方法(メニューパス)

Section titled “アクセス方法(メニューパス)”

メニューから「購買管理 > 発注照合伝票」を開きます。

  1. メニューから「発注照合伝票」を開く
  2. 検索で対象を絞り込む
    • 発注伝票明細: 特定の発注行の消化状況を調べる場合
    • 入荷明細 / 仕入請求伝票明細: 入荷側・請求側から遡る場合
    • 品目: 品目単位で照合状況を俯瞰する場合
  3. 数量価格差異許容範囲を確認する
  1. 一覧で「価格差異許容範囲PriceMatchDifference)」列を表示する
  2. 値がゼロでない行は、発注単価と請求単価に差が生じています
  3. 差異が妥当な場合(値引・送料調整など)は「承認済み」にチェックして承認記録を残します
  4. 差異が誤りの場合は、仕入請求伝票側の単価を修正のうえ再照合します
  1. 対象の照合レコードを選択
  2. 削除」ボタン(カラム名 Processing、説明は “Delete PO Matching Record”)を実行
  3. 元の発注・入荷・請求伝票を修正し、再度照合を成立させます

発注照合伝票タブ(主要項目)

Section titled “発注照合伝票タブ(主要項目)”
項目名必須説明
クライアント必須選択テナント
組織必須選択組織
伝票番号-文字列照合レコードの伝票番号
取引日付必須日付照合が行われた取引日
転記日付必須日付会計計上日
発注伝票明細必須検索照合対象の発注明細
入荷明細必須検索照合対象の入荷明細
仕入請求伝票明細-検索照合対象の請求明細
品目必須検索照合対象の品目
属性セットインスタンス-品目属性ロット・シリアル等の属性
数量必須数量照合された数量
価格差異許容範囲-金額発注単価と請求単価の差額
承認済み-チェック承認が必要な場合のフラグ(既定 N)
Referenced Match PO-検索参照元の照合レコード(取消時に使用)
説明-文字列任意の説明
処理済み必須チェック処理済みフラグ
転記必須ボタン転記状態の確認
削除必須ボタン照合レコードの削除処理

全項目一覧はリファレンス参照

Q. 価格差異許容範囲(PriceMatchDifference)とは何ですか?

Section titled “Q. 価格差異許容範囲(PriceMatchDifference)とは何ですか?”

照合された明細単位での「発注価格と請求価格の差額」です(項目説明: “Difference between Purchase and Invoice Price per matched line”)。MMatchPOgetInvoicePriceActual() で請求側の実単価を取得でき、発注単価との差が本項目に反映されます。差異が出る典型例は、発注後の値引き交渉や単価改定を請求書だけに反映したケースです。

Q. 入荷だけ登録したのに請求明細が自動でセットされました

Section titled “Q. 入荷だけ登録したのに請求明細が自動でセットされました”

MMatchPO.beforeSave() は、新規レコードで請求明細が未設定かつ取消レコードでない場合、同じ入荷明細に紐づく請求照合(M_MatchInv)を走査します。属性セットインスタンスが一致し、かつ数量が完全に一致する照合が見つかると、その請求明細 ID を自動セットします。数量が異なる場合は、その数量に対応する M_MatchPO レコードが別途新規作成されます。

Q. 発注伝票明細を指定していないのに埋まっているのはなぜですか?

Section titled “Q. 発注伝票明細を指定していないのに埋まっているのはなぜですか?”

beforeSave() は発注明細が未設定の場合、まず請求明細(C_InvoiceLine.C_OrderLine_ID)から、続いて入荷明細(M_InOutLine.C_OrderLine_ID)から発注明細を逆引きしてセットします。発注を参照して作成した入荷・請求であれば、発注明細は自動的に決まります。

Q. 転記日付はどのように決まりますか?

Section titled “Q. 転記日付はどのように決まりますか?”

beforeSave() で、DateTrx が未設定なら当日日時、DateAcct が未設定なら getNewerDateAcct()(関連伝票側の新しい方の転記日付)、それも取得できない場合は DateTrx がセットされます。

画面の「削除」ボタンのほか、モデル側では reverse(Timestamp reversalDate) および reverse(Timestamp, boolean reverseMatchingOnly) が用意されています。取消後は isReversal() が真となり、Ref_MatchPO_ID / Reversal_ID で元レコードとの対応を追跡できます。

Q. 請求照合伝票との使い分けは?

Section titled “Q. 請求照合伝票との使い分けは?”

入荷と請求の突合だけを見る場合は請求照合伝票、発注を起点に「発注どおり入荷・請求されたか」を見る場合は発注照合伝票を使用します。MMatchPO.getMatchInvCreated() のように、発注照合の処理過程で請求照合が生成されるケースもあるため、両者はセットで確認するのが確実です。

🛠 技術仕様(開発者向け)

発注照合伝票は M_MatchPO テーブルに格納されます。テーブル説明は “Match Purchase Order to Shipment/Receipt and Invoice”、アクセスレベルは 3(クライアント+組織)、削除可能(IsDeleteable=Y)です。モデルクラスは MMatchPO(1,480行)で、X_M_MatchPO を継承します。Document 型ではありませんが Posted / DateAcct を持つ転記対象レコードです。三者照合ロジックを担うため、購買系モデルの中でも大きなクラスです。

classDiagram
    class MMatchPO {
        +create(MInvoiceLine, MInOutLine, ...) MMatchPO
        +getOrCreate(C_OrderLine_ID, qty, MInOutLine, trxName) MMatchPO
        +getOrderLine(ctx, C_OrderLine_ID, trxName) MMatchPO[]
        +getInOut(ctx, ...) MMatchPO[]
        +getInvoice(ctx, ...) MMatchPO[]
        +getInvoicePriceActual() BigDecimal
        +getMatchInvCreated() MMatchInv
        +getNewerDateAcct() Timestamp
        +reverse(Timestamp) boolean
        +reverse(Timestamp, boolean) boolean
        +isReversal() boolean
        #beforeSave(boolean) boolean
        #afterSave(boolean, boolean) boolean
    }
    class X_M_MatchPO {
        <<generated>>
    }
    class PO {
        <<abstract>>
    }
    MMatchPO --|> X_M_MatchPO
    X_M_MatchPO --|> PO
    MMatchPO --> MOrderLine : matches
    MMatchPO --> MInOutLine : matches
    MMatchPO --> MInvoiceLine : matches
    MMatchPO --> MMatchInv : creates

+create(MInvoiceLine, MInOutLine, ...) MMatchPO +getOrCreate(C_OrderLine_ID, qty, MInOutLine, trxName) MMatchPO +getOrderLine(ctx, C_OrderLine_ID, trxName) MMatchPO[] +getInOut(ctx, ...) MMatchPO[] +getInvoice(ctx, ...) MMatchPO[] +getInvoicePriceActual() BigDecimal +getMatchInvCreated() MMatchInv +getNewerDateAcct() Timestamp +reverse(Timestamp) boolean +reverse(Timestamp, boolean) boolean +isReversal() boolean #beforeSave(boolean) boolean #afterSave(boolean, boolean) boolean <> <> > X_M_MatchPO X_M_MatchPO --

パッケージ: org.compiere.model ソースファイル: org.adempiere.base/src/org/compiere/model/MMatchPO.java

カラム名必須説明備考
M_MatchPO_IDIDPK照合ID主キー
AD_Client_IDTable DirectYクライアントdefault @#AD_Client_ID@
AD_Org_IDTable DirectY組織default @#AD_Org_ID@
DocumentNoStringN伝票番号
DateTrxDateY取引日付未設定時は beforeSave で当日
DateAcctDateY転記日付未設定時は getNewerDateAcct()
C_OrderLine_IDSearchY発注伝票明細未設定時は請求/入荷から逆引き
M_InOutLine_IDSearchY入荷明細
C_InvoiceLine_IDSearchN仕入請求伝票明細MatchInv から自動補完あり
M_Product_IDSearchY品目
M_AttributeSetInstance_IDProduct AttributeN属性セットインスタンス入荷明細から自動コピー
QtyQuantityY数量照合数量
PriceMatchDifferenceAmountN価格差異発注価格と請求価格の差
IsApprovedYes-NoN承認済みdefault N
Ref_MatchPO_IDSearchN参照元照合レコード取消用
Reversal_IDSearchN取消ID
ProcessedYes-NoY処理済み
ProcessedOnNumberN処理日時
ProcessingButtonY削除処理ボタンDelete PO Matching Record
PostedButtonY転記状態
DescriptionStringN説明
erDiagram
    C_OrderLine ||--o{ M_MatchPO : "matched by"
    M_InOutLine ||--o{ M_MatchPO : "matched by"
    C_InvoiceLine ||--o{ M_MatchPO : "matched by"
    M_MatchPO ||--o| M_MatchPO : "Ref_MatchPO_ID reversal"
    M_MatchPO ||--o| M_MatchInv : "may create"
    C_Order ||--o{ C_OrderLine : "lines"
    M_InOut ||--o{ M_InOutLine : "lines"
    C_Invoice ||--o{ C_InvoiceLine : "lines"

matched by Ref_MatchPO_ID reversal may create

flowchart TD
    A[beforeSave] --> B{DateTrx null?}
    B -->|Yes| C[当日日時をセット]
    B -->|No| D{DateAcct null?}
    C --> D
    D -->|Yes| E["getNewerDateAcct() → null なら DateTrx"]
    D -->|No| F{"ASI=0 かつ 入荷明細あり?"}
    E --> F
    F -->|Yes| G[入荷明細の ASI をコピー]
    F -->|No| H{"新規 かつ 請求明細未設定 かつ 非取消?"}
    G --> H
    H -->|Yes| I["同一入荷明細の M_MatchInv を走査"]
    I --> J{"数量が一致?"}
    J -->|Yes| K[請求明細IDをセット]
    J -->|No| L["その数量の MMatchPO を別途生成"]
    H -->|No| M{"C_OrderLine_ID = 0?"}
    K --> M
    L --> M
    M -->|Yes| N["請求明細 → 入荷明細の順で<br/>発注明細を逆引き"]
    M -->|No| O[保存続行]
    N --> O

getNewerDateAcct() → null なら DateTrx ASI=0 かつ 入荷明細あり? 新規 かつ 請求明細未設定 かつ 非取消? 同一入荷明細の M_MatchInv を走査 数量が一致? その数量の MMatchPO を別途生成 C_OrderLine_ID = 0? 請求明細 → 入荷明細の順で 発注明細を逆引き DateTrx null? DateAcct null? 当日日時をセット 入荷明細の ASI をコピー 請求明細IDをセット 保存続行

請求照合レコードを走査する際、既に同一組み合わせ(同一入荷明細+同一請求明細)の M_MatchPO が存在する場合はスキップされ、二重照合が防止されます。

MMatchPOm_isInvoiceLineChange / m_isInOutLineChange という protected フラグを持ち、setC_InvoiceLine_ID() / setM_InOutLine_ID() の呼び出しで請求明細・入荷明細が差し替わったかを記録します。afterSave() はこのフラグに応じて関連レコードの再計算・整合処理を分岐させます。

メソッド用途
create(MInvoiceLine, MInOutLine, ...)請求明細と入荷明細から照合を生成
getOrCreate(C_OrderLine_ID, qty, MInOutLine, trxName)既存照合を取得、無ければ生成
getOrderLine(ctx, C_OrderLine_ID, trxName)発注明細に紐づく照合を取得
getInOut(ctx, ...) / getInvoice(ctx, ...)入荷伝票/請求伝票単位で取得
getMatchInvCreated()処理過程で生成された請求照合を取得

reverse(Timestamp reversalDate) は照合全体の取消、reverse(Timestamp, boolean reverseMatchingOnly) は照合関係のみの取消に対応します。取消レコードは isReversal() で判定できます。

拡張ポイント(カスタマイズ箇所)

Section titled “拡張ポイント(カスタマイズ箇所)”

価格差異のしきい値管理は Model Validator で実装するのが定石です。

public class CustomMatchPOValidator implements ModelValidator {
@Override
public int modelChange(PO po, int type) throws Exception {
if (po instanceof MMatchPO && (type == TYPE_BEFORE_NEW || type == TYPE_BEFORE_CHANGE)) {
MMatchPO mp = (MMatchPO) po;
BigDecimal diff = mp.getPriceMatchDifference();
// 例: 価格差異が一定額を超える場合は承認済みを必須にする
if (diff != null && diff.abs().compareTo(new BigDecimal("10000")) > 0
&& !mp.isApproved()) {
throw new AdempiereException("価格差異が大きいため、承認済みチェックが必要です");
}
}
return null;
}
}

M_MatchPO の各カラムには標準の Callout(AD_Column.Callout)が設定されていません。画面上の入力補助が必要な場合は独自 Callout を登録します。

照合は入荷・請求の処理経路から生成されるため、生成条件を変えたい場合は M_InOut / C_InvoicedocValidate()TIMING_AFTER_COMPLETE)でフックします。


発注・入荷・請求の三者照合は、検収基準や価格差異の許容ルールが企業ごとに異なる領域です。 差異のしきい値管理や承認ワークフローとの連携は、Model Validator と OSGi プラグインでコア改変なしに実装できます。

As-Link株式会社では、OSGiプラグインによる安全なカスタマイズを提供しています。

OSS ERP導入・カスタマイズサービスの詳細はこちら