コンテンツにスキップ

iDempiere 販売手数料及びロイヤリティー計算結果の使い方|販売管理 操作マニュアル・技術仕様

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

販売手数料及びロイヤリティー計算結果は、手数料ルールの「手数料作成」ボタンで生成された 計算結果を確認・修正し、支払用の仕入請求伝票を作成する ウィンドウです。計算結果は「計算単位(実行 1 回)」「計算行ごとの金額」「対象取引ごとの内訳」の 3 階層で保持されます。

📌 ポイント: 金額を直接書き換えることもできますが、推奨は 手数料詳細(内訳)に補正行を追加する 方法です。金額欄を直接修正すると内訳の合計と一致しなくなり、後から根拠を追えなくなります。

販売手数料の計算結果でできること

Section titled “販売手数料の計算結果でできること”
  • 実行した手数料計算の結果一覧の確認(伝票番号・開始日付・総合計)
  • 計算行(手数料詳細)ごとの手数料額の確認
  • 手数料の根拠となった受注明細・請求明細の内訳確認
  • 金額・数量の手修正、および補正行の追加
  • 修正内容に応じた総合計の自動再計算
  • 計算結果からの仕入請求伝票(買掛請求)の自動作成
  • 作成された仕入請求伝票へのリンク参照

計算結果は 3 階層のタブ構成です。

タブ名テーブル項目数役割
手数料計算C_CommissionRun10項目実行 1 回分のヘッダー(期間・総合計・請求書)
手数料金額C_CommissionAmt8項目計算行ごとの手数料額
手数料詳細C_CommissionDetail11項目対象取引(受注明細/請求明細)ごとの内訳
graph TD
    subgraph "販売手数料及びロイヤリティー計算結果(Window ID: 210)"
        T1["🧮 手数料計算<br/>C_CommissionRun<br/>10項目"]
        T2["&nbsp;&nbsp;└ 手数料金額<br/>&nbsp;&nbsp;&nbsp;&nbsp;C_CommissionAmt<br/>&nbsp;&nbsp;&nbsp;&nbsp;8項目"]
        T3["&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;└ 手数料詳細<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C_CommissionDetail<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;11項目"]
    end
    T1 --> T2
    T2 --> T3

販売手数料及びロイヤリティー計算結果(Window ID: 210) 手数料計算 C_CommissionRun 10項目   └ 手数料金額     C_CommissionAmt     8項目       └ 手数料詳細         C_CommissionDetail         11項目

💡 ヒント: 手数料詳細(内訳)が作られるのは、手数料ルール側で「手数料詳細作成(ListDetails)」にチェックがある場合です。チェックなしで実行すると通貨単位で集約された金額のみが記録され、取引ごとの内訳は残りません。

graph TD
    A["▶️ 手数料ルール画面で<br/>手数料作成を実行"] --> B["🚀 メニューから開く<br/>販売管理 > 販売管理設定 > 販売手数料及びロイヤリティー計算結果"]
    B --> C["🔍 対象の計算結果を選択<br/>(伝票番号・開始日付で特定)"]
    C --> D["📊 手数料金額タブで<br/>計算行ごとの金額を確認"]
    D --> E["🔎 手数料詳細タブで<br/>対象取引の内訳を確認"]
    E --> F{"金額は妥当?"}
    F -->|要修正| G["➕ 手数料詳細に補正行を追加<br/>(推奨)"]
    G --> H["🔄 金額・総合計が自動再計算"]
    H --> F
    F -->|妥当| I["🧾 請求書作成ボタンを実行"]
    I --> J["📄 仕入請求伝票が作成され<br/>処理済みフラグが立つ"]
    J --> K["💳 通常の支払処理へ"]

▶ 手数料ルール画面で 手数料作成を実行 メニューから開く 販売管理 > 販売管理設定 > 販売手数料及びロイヤリティー計算結果 対象の計算結果を選択 (伝票番号・開始日付で特定) 手数料金額タブで 計算行ごとの金額を確認 手数料詳細タブで 対象取引の内訳を確認 金額は妥当? 手数料詳細に補正行を追加 (推奨) 金額・総合計が自動再計算 請求書作成ボタンを実行 仕入請求伝票が作成され 処理済みフラグが立つ 通常の支払処理へ 要修正 妥当

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

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

メニューから「販売管理 > 販売管理設定 > 販売手数料及びロイヤリティー計算結果」を開きます。

⚠️ 注意: この画面でレコードを新規作成することは通常ありません。計算結果は手数料ルール画面の「手数料作成」ボタン(CommissionCalc プロセス)が生成します。まず手数料ルール側で実行してください。

  1. 対象の計算結果を検索(伝票番号 または 開始日付
  2. ヘッダーで 手数料(どのルールか)、開始日付総合計 を確認
  3. 手数料金額」タブで計算行ごとの金額を確認:
    • 手数料明細: どの計算行に対応する金額か
    • 換算金額: 対象取引の金額合計(手数料通貨へ換算済み)
    • 実績数量: 対象取引の数量合計
    • 手数料金額: 計算式を適用した結果
  4. 手数料詳細」タブで対象になった取引を確認:
    • 発注伝票明細 / 仕入請求伝票明細: 手数料の根拠となった明細行へのリンク
    • 実績金額 / 通貨 / 換算金額 / 実績数量

金額の修正(補正行の追加:推奨)

Section titled “金額の修正(補正行の追加:推奨)”
  1. 手数料詳細」タブへ移動
  2. 新規」で補正行を追加し、実績金額通貨実績数量 を入力
  3. リファレンス / インフォメーション に補正理由を記入
  4. 保存後、再度その行を開いて保存し直すか、既存行を更新すると上位(手数料金額・総合計)が再計算されます

⚠️ 注意: 内訳行を 新規追加した時点 では上位金額の自動再計算が走りません(MCommissionDetail.afterSave()newRecord=false のときだけ再計算するため)。追加後に行を更新するか、上位タブの金額を確認して必要なら再保存してください。既存行の 更新・削除 では確実に再計算されます。

  1. ヘッダーの「請求書作成」ボタンをクリック
  2. 手数料ルールの受取取引先宛に、買掛の請求伝票が作成されます
  3. 明細は 1 行のみ(数量 1・単価=総合計)で、料金または品目は手数料ルールの設定が使われます
  4. 作成後、仕入請求伝票 項目にリンクが設定され、処理済み にチェックが入ります

⚠️ 注意: 総合計が 0 の計算結果では請求書を作成できません(@GrandTotal@ = 0 エラー)。また、手数料ルールの通貨と受取取引先の購買価格表の通貨が異なる場合もエラーになります。

項目名カラム必須説明
手数料C_Commission_ID必須選択元になった手数料ルール
伝票番号DocumentNo必須文字列(30)計算結果の伝票番号(識別子)
説明Description-文字列(255)対象期間が自動セットされる
開始日付StartDate必須日付対象期間の開始日
総合計GrandTotal必須金額手数料金額の合計(自動計算)
請求書作成Processing-ボタン仕入請求伝票の作成
仕入請求伝票C_Invoice_ID-選択作成された請求伝票へのリンク
処理済みProcessed必須チェック請求書作成済みかどうか
項目名カラム必須説明
手数料計算C_CommissionRun_ID必須選択親(計算結果ヘッダー)
手数料明細C_CommissionLine_ID必須選択対応する計算行
換算金額ConvertedAmt必須金額内訳の換算金額合計
実績数量ActualQty必須数量内訳の数量合計
手数料金額CommissionAmt必須金額計算式適用後の手数料額
項目名カラム必須説明
手数料金額C_CommissionAmt_ID必須選択親(計算行別の金額)
リファレンスReference-文字列(60)参照情報(識別子)
インフォメーションInfo-文字列(60)補足情報
発注伝票明細C_OrderLine_ID-選択根拠となる受注明細
仕入請求伝票明細C_InvoiceLine_ID-選択根拠となる請求明細
実績金額ActualAmt必須金額取引通貨での金額
通貨C_Currency_ID必須選択取引通貨
換算金額ConvertedAmt必須金額手数料通貨への換算後金額
実績数量ActualQty必須数値数量

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

graph TD
    A["手数料詳細(内訳)<br/>C_CommissionDetail<br/>実績金額・換算金額・数量"] --> B["手数料金額<br/>C_CommissionAmt<br/>換算金額合計・数量合計"]
    B --> C["計算式の適用<br/>控除・乗数・正数のみ"]
    C --> D["手数料金額<br/>CommissionAmt"]
    D --> E["手数料計算ヘッダー<br/>C_CommissionRun<br/>GrandTotal"]
    E --> F["仕入請求伝票<br/>数量1・単価=総合計"]

手数料詳細(内訳) C_CommissionDetail 実績金額・換算金額・数量 手数料金額 C_CommissionAmt 換算金額合計・数量合計 計算式の適用 控除・乗数・正数のみ 手数料金額 CommissionAmt 手数料計算ヘッダー C_CommissionRun GrandTotal 仕入請求伝票 数量1・単価=総合計

Q. 総合計が内訳と合いません。

Section titled “Q. 総合計が内訳と合いません。”

「手数料金額」タブの金額欄を直接書き換えた可能性があります。金額欄の手修正は内訳(C_CommissionDetail)とは独立に保持されるため、内訳合計との整合は取られません。整合を保つには金額欄を直接触らず、内訳に補正行を追加してください。既存の内訳行を更新・削除すると calculateCommission() が再実行され、内訳合計から手数料金額と総合計が再計算されます。

Q. 請求書作成ボタンでエラーになります。

Section titled “Q. 請求書作成ボタンでエラーになります。”

CommissionAPInvoice プロセスが投げる代表的なエラーは次の 3 つです。

エラー内容原因対処
@GrandTotal@ = 0総合計が 0内訳・計算行を見直して 0 以外にする
No Charge or Product on Commission手数料ルールに料金・品目が未設定手数料ルール側で料金または品目を設定
Currency of PO Price List not Commission Currency手数料通貨と受取取引先の購買価格表の通貨が不一致通貨を揃えるか、購買価格表を修正

Q. 作成された請求伝票はどうなりますか?

Section titled “Q. 作成された請求伝票はどうなりますか?”

伝票タイプ 買掛請求(AP Invoice) の請求伝票が、手数料ルールの受取取引先宛に作成されます。明細は 1 行(数量 1・単価=計算結果の総合計)で、料金または品目は手数料ルールで設定した値が使われます。税は setTax() により自動判定されます。作成された伝票は下書き状態のため、仕入請求伝票画面で内容を確認し、完了処理を行ってください。

Q. 同じ期間で 2 回実行してしまいました。

Section titled “Q. 同じ期間で 2 回実行してしまいました。”

計算結果は実行のたびに新しい C_CommissionRun レコードとして作成され、重複チェックは行われません。不要な計算結果は請求書を作成する前に削除してください。請求書作成後は「処理済み」フラグが立ち、C_Invoice_ID へリンクが張られるため、先に請求伝票側を取り消す必要があります。

Q. 手数料詳細に何も表示されません。

Section titled “Q. 手数料詳細に何も表示されません。”

手数料ルールの「手数料詳細作成(ListDetails)」がオフの状態で計算を実行した可能性があります。オフの場合は通貨単位で集約された金額のみが C_CommissionAmt に記録され、取引ごとの内訳は作られません。内訳を残したい場合はルール側でチェックを入れて再実行してください。

Q. どの取引が対象になったか一覧で見たいです。

Section titled “Q. どの取引が対象になったか一覧で見たいです。”

メニューのレポート「手数料計算明細(Commission Run Detail)」を使うと、計算結果を受注/請求の明細情報付きで出力できます(ビュー RV_CommissionRunDetail を参照)。

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

販売手数料及びロイヤリティー計算結果は 3 階層のトランザクションウィンドウ(AD_Window_ID: 210)で、C_CommissionRun(ヘッダー)/C_CommissionAmt(計算行別金額)/C_CommissionDetail(取引別内訳)で構成されます。いずれも AccessLevel=1(組織レベル)/IsDeleteable=Y。ビジネスロジックは MCommissionRun(136行)・MCommissionAmt(187行)・MCommissionDetail(156行)が担います。DocStatus / DocAction を持たない 非 Document 型 で、状態管理は Processed フラグと Processing ボタンのみです。

classDiagram
    class MCommissionRun {
        +MCommissionRun(MCommission)
        +getAmts() MCommissionAmt[]
        +updateFromAmt() void
    }
    class MCommissionAmt {
        +MCommissionAmt(MCommissionRun, int)
        +getDetails() MCommissionDetail[]
        +calculateCommission() void
        #afterSave(boolean, boolean) boolean
        #afterDelete(boolean) boolean
        -updateRunHeader() void
    }
    class MCommissionDetail {
        +setLineIDs(int, int) void
        +setConvertedAmt(Timestamp) void
        #afterSave(boolean, boolean) boolean
        #afterDelete(boolean) boolean
        -updateAmtHeader() void
    }
    class PO {
        <<abstract>>
    }
    class CommissionAPInvoice {
        <<SvrProcess>>
        #doIt() String
    }
    MCommissionRun --|> PO
    MCommissionAmt --|> PO
    MCommissionDetail --|> PO
    MCommissionRun --> MCommissionAmt : has many
    MCommissionAmt --> MCommissionDetail : has many
    CommissionAPInvoice --> MCommissionRun : reads
    CommissionAPInvoice --> MInvoice : creates

+MCommissionRun(MCommission) +getAmts() MCommissionAmt[] +updateFromAmt() void +MCommissionAmt(MCommissionRun, int) +getDetails() MCommissionDetail[] +calculateCommission() void #afterSave(boolean, boolean) boolean #afterDelete(boolean) boolean -updateRunHeader() void +setLineIDs(int, int) void +setConvertedAmt(Timestamp) void #afterSave(boolean, boolean) boolean #afterDelete(boolean) boolean -updateAmtHeader() void <> <> #doIt() String > PO MCommissionAmt --

パッケージ: org.compiere.model / org.compiere.process ソースファイル:

  • org.adempiere.base/src/org/compiere/model/MCommissionRun.java
  • org.adempiere.base/src/org/compiere/model/MCommissionAmt.java
  • org.adempiere.base/src/org/compiere/model/MCommissionDetail.java
  • org.adempiere.base.process/src/org/compiere/process/CommissionAPInvoice.java(114行)

C_CommissionRun(手数料計算=実行ヘッダー)

Section titled “C_CommissionRun(手数料計算=実行ヘッダー)”
カラム名必須説明備考
C_CommissionRun_IDIDPK計算結果ID主キー
C_CommissionRun_UUUUIDNUUID
AD_Client_IDTable DirectYクライアントdefault @#AD_Client_ID@
AD_Org_IDTable DirectY組織default @#AD_Org_ID@
C_Commission_IDTable DirectY手数料ルールFK
DocumentNoString(30)Y伝票番号識別子(IsIdentifier=Y)
DescriptionString(255)N説明対象期間が自動セット
StartDateDateY開始日付対象期間の始点
GrandTotalAmountY総合計updateFromAmt() で再計算
ProcessingButtonN請求書作成CommissionAPInvoice を起動
C_Invoice_IDSearchN仕入請求伝票作成された請求伝票
ProcessedYes-NoY処理済み請求書作成で Y

C_CommissionAmt(手数料金額=計算行別)

Section titled “C_CommissionAmt(手数料金額=計算行別)”
カラム名必須説明備考
C_CommissionAmt_IDIDPK手数料金額ID主キー・識別子
C_CommissionRun_IDSearchY計算結果FK親(IsParent=Y)
C_CommissionLine_IDTable DirectY計算行FKどのルール行の結果か
ConvertedAmtAmountY換算金額内訳の合計
ActualQtyQuantityY実績数量内訳の合計
CommissionAmtAmountY手数料金額計算式適用後

C_CommissionDetail(手数料詳細=取引別内訳)

Section titled “C_CommissionDetail(手数料詳細=取引別内訳)”
カラム名必須説明備考
C_CommissionDetail_IDIDPK内訳ID主キー
C_CommissionAmt_IDSearchY手数料金額FK親(IsParent=Y)
C_OrderLine_IDSearchN受注明細計算ベース O のとき
C_InvoiceLine_IDSearchN請求明細計算ベース I のとき
ReferenceString(60)Nリファレンス識別子
InfoString(60)Nインフォメーション
ActualAmtAmountY実績金額取引通貨
C_Currency_IDTable DirectY通貨取引通貨
ConvertedAmtAmountY換算金額手数料通貨へ換算
ActualQtyNumberY実績数量
erDiagram
    C_Commission ||--o{ C_CommissionRun : "executed as"
    C_CommissionRun ||--o{ C_CommissionAmt : "amounts"
    C_CommissionAmt ||--o{ C_CommissionDetail : "details"
    C_CommissionLine ||--o{ C_CommissionAmt : "rule line"
    C_CommissionDetail }o--o| C_OrderLine : "source order line"
    C_CommissionDetail }o--o| C_InvoiceLine : "source invoice line"
    C_CommissionRun ||--o| C_Invoice : "AP invoice"
    C_CommissionDetail }o--|| C_Currency : "transaction currency"

executed as rule line source order line source invoice line AP invoice transaction currency

金額の整合は、下位から上位へ伝播するカスケードで保たれます。

flowchart TD
    A["C_CommissionDetail 更新/削除"] --> B["afterSave / afterDelete"]
    B --> C["updateAmtHeader<br/>親 MCommissionAmt を取得"]
    C --> D["calculateCommission<br/>内訳合計 → 計算式適用"]
    D --> E["amt.saveEx"]
    E --> F["MCommissionAmt.afterSave"]
    F --> G["updateRunHeader<br/>親 MCommissionRun を取得"]
    G --> H["updateFromAmt<br/>CommissionAmt を合算"]
    H --> I["run.saveEx → GrandTotal 更新"]

C_CommissionDetail 更新/削除 afterSave / afterDelete updateAmtHeader 親 MCommissionAmt を取得 calculateCommission 内訳合計 → 計算式適用 amt.saveEx MCommissionAmt.afterSave updateRunHeader 親 MCommissionRun を取得 updateFromAmt CommissionAmt を合算 run.saveEx → GrandTotal 更新

⚠️ 注意: MCommissionDetail.afterSave()MCommissionAmt.afterSave() はいずれも if (!newRecord) の条件付きで上位を更新します。新規レコードの挿入では再計算が走りません。これは CommissionCalc が大量の内訳を挿入する際に、1 行ごとにヘッダーを更新して性能を落とさないための設計です。UI から補正行を新規追加した場合は、その行を再保存するか既存行を更新して再計算を発火させてください。

内訳の ConvertedAmtActualQty を合計したうえで、対応する MCommissionLine のパラメータを適用します。

  1. 内訳をループして ConvertedAmtActualQty を合算し、自身にセット
  2. C_CommissionLine を読み込む
  3. 数量: ActualQty - QtySubtractIsPositiveOnly かつ負なら 0)→ × QtyMultiplier
  4. 金額: ConvertedAmt - AmtSubtractIsPositiveOnly かつ負なら 0)→ × AmtMultiplier
  5. CommissionAmt = 金額項 + 数量項 をセット

getAmts() で取得した全 C_CommissionAmtCommissionAmt を合算し、GrandTotal にセットします。呼び出し元は MCommissionAmt.updateRunHeader() です。

MCommissionDetail.setConvertedAmt(Timestamp)

Section titled “MCommissionDetail.setConvertedAmt(Timestamp)”

MConversionRate.convertBase() を使い、ActualAmt を取引通貨から基準通貨へ、指定日付のレートで換算します(換算タイプは 0=既定)。換算結果が null(レート未登録)の場合は ConvertedAmt を更新しません。

⚠️ 注意: 為替レートが未登録だと換算金額が 0 のまま残り、手数料が過少計算されます。外貨取引を含む場合は対象期間の為替レートを事前に登録してください。

CommissionAPInvoice(請求書作成プロセス)

Section titled “CommissionAPInvoice(請求書作成プロセス)”
MCommissionRun comRun = new MCommissionRun(getCtx(), getRecord_ID(), get_TrxName());
if (Env.ZERO.compareTo(comRun.getGrandTotal()) == 0)
throw new IllegalArgumentException("@GrandTotal@ = 0");
...
invoice.setC_DocTypeTarget_ID(MDocType.DOCBASETYPE_APInvoice);
invoice.setBPartner(bp);
invoice.setSalesRep_ID(getAD_User_ID());
if (com.getC_Currency_ID() != invoice.getC_Currency_ID())
throw new IllegalArgumentException("CommissionAPInvoice - Currency of PO Price List not Commission Currency");
...
MInvoiceLine iLine = new MInvoiceLine(invoice);
if (com.getC_Charge_ID() > 0) iLine.setC_Charge_ID(com.getC_Charge_ID());
else iLine.setM_Product_ID(com.getM_Product_ID());
iLine.setQty(1);
iLine.setPrice(comRun.getGrandTotal());
iLine.setTax();
...
comRun.setC_Invoice_ID(invoice.getC_Invoice_ID());
comRun.setProcessed(true);

処理の要点:

  1. 総合計 0 の計算結果は拒否
  2. 手数料ルールに料金・品目のいずれも無ければ拒否
  3. 伝票タイプは 買掛請求(AP Invoice)、取引先は手数料ルールの受取先
  4. 請求伝票の通貨(受取先の購買価格表由来)が手数料通貨と異なる場合は拒否
  5. 明細は 1 行のみ(数量 1・単価=総合計)、税は setTax() で自動判定
  6. 計算結果に C_Invoice_ID を書き戻し Processed=Y をセット

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

Section titled “拡張ポイント(カスタマイズ箇所)”
public class CustomCommissionRunValidator implements ModelValidator {
@Override
public int modelChange(PO po, int type) throws Exception {
if (po instanceof MCommissionRun) {
MCommissionRun run = (MCommissionRun) po;
// 例: 処理済みの計算結果は削除させない
if (type == TYPE_BEFORE_DELETE && run.isProcessed()) {
throw new AdempiereException("請求書作成済みの手数料計算結果は削除できません");
}
}
return null;
}
@Override
public String docValidate(PO po, int timing) {
// 作成された仕入請求伝票の完了時に手数料固有の処理を挟む場合はここ
return null;
}
}

請求書作成ロジックの差し替え

Section titled “請求書作成ロジックの差し替え”

CommissionAPInvoice は明細 1 行・数量 1・単価=総合計という固定的な生成を行います。計算行ごとに請求明細を分けたい、源泉徴収を明細として付加したいといった要件がある場合は、CommissionAPInvoice を継承したクラスを作成し、AD_Process のクラス名を差し替えるのが最小改変の方法です。

MCommissionDetail には setLineIDs(C_OrderLine_ID, C_InvoiceLine_ID)setConvertedAmt(Timestamp) が公開されているため、外部システムの販売実績を内訳として取り込むカスタムプロセスも実装できます。挿入後は上位の MCommissionAmt.calculateCommission()MCommissionRun.updateFromAmt() を明示的に呼び出してください(新規挿入では自動再計算されないため)。

プロセス名実装クラス説明
請求書作成(Create Invoice)CommissionAPInvoice(114行)計算結果から買掛請求伝票を作成
手数料作成(Generate Commission)CommissionCalc(454行)手数料ルール画面から計算結果を生成
手数料計算明細レポートレポート(RV_CommissionRunDetail計算結果を受注/請求の内訳付きで出力

手数料の計算結果は監査対象になりやすく、「どの取引がいくらの手数料になったか」を追える形で残せるかが運用の分かれ目になります。内訳の粒度設計や請求書生成ロジックの調整は、コアを触らずプロセス継承で実現できます。

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

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