iDempiere 販売手数料及びロイヤリティー計算結果の使い方|販売管理 操作マニュアル・技術仕様
📖 販売管理の全体像: 販売管理の全体図 も合わせてご覧ください。
販売手数料及びロイヤリティー計算結果は、手数料ルールの「手数料作成」ボタンで生成された 計算結果を確認・修正し、支払用の仕入請求伝票を作成する ウィンドウです。計算結果は「計算単位(実行 1 回)」「計算行ごとの金額」「対象取引ごとの内訳」の 3 階層で保持されます。
📌 ポイント: 金額を直接書き換えることもできますが、推奨は 手数料詳細(内訳)に補正行を追加する 方法です。金額欄を直接修正すると内訳の合計と一致しなくなり、後から根拠を追えなくなります。
販売手数料の計算結果でできること
Section titled “販売手数料の計算結果でできること”- 実行した手数料計算の結果一覧の確認(伝票番号・開始日付・総合計)
- 計算行(手数料詳細)ごとの手数料額の確認
- 手数料の根拠となった受注明細・請求明細の内訳確認
- 金額・数量の手修正、および補正行の追加
- 修正内容に応じた総合計の自動再計算
- 計算結果からの仕入請求伝票(買掛請求)の自動作成
- 作成された仕入請求伝票へのリンク参照
計算結果は 3 階層のタブ構成です。
| タブ名 | テーブル | 項目数 | 役割 |
|---|---|---|---|
| 手数料計算 | C_CommissionRun | 10項目 | 実行 1 回分のヘッダー(期間・総合計・請求書) |
| 手数料金額 | C_CommissionAmt | 8項目 | 計算行ごとの手数料額 |
| 手数料詳細 | C_CommissionDetail | 11項目 | 対象取引(受注明細/請求明細)ごとの内訳 |
graph TD
subgraph "販売手数料及びロイヤリティー計算結果(Window ID: 210)"
T1["🧮 手数料計算<br/>C_CommissionRun<br/>10項目"]
T2[" └ 手数料金額<br/> C_CommissionAmt<br/> 8項目"]
T3[" └ 手数料詳細<br/> C_CommissionDetail<br/> 11項目"]
end
T1 --> T2
T2 --> T3
💡 ヒント: 手数料詳細(内訳)が作られるのは、手数料ルール側で「手数料詳細作成(ListDetails)」にチェックがある場合です。チェックなしで実行すると通貨単位で集約された金額のみが記録され、取引ごとの内訳は残りません。
基本操作手順
Section titled “基本操作手順”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プロセス)が生成します。まず手数料ルール側で実行してください。
計算結果の確認
Section titled “計算結果の確認”- 対象の計算結果を検索(伝票番号 または 開始日付)
- ヘッダーで 手数料(どのルールか)、開始日付、総合計 を確認
- 「手数料金額」タブで計算行ごとの金額を確認:
- 手数料明細: どの計算行に対応する金額か
- 換算金額: 対象取引の金額合計(手数料通貨へ換算済み)
- 実績数量: 対象取引の数量合計
- 手数料金額: 計算式を適用した結果
- 「手数料詳細」タブで対象になった取引を確認:
- 発注伝票明細 / 仕入請求伝票明細: 手数料の根拠となった明細行へのリンク
- 実績金額 / 通貨 / 換算金額 / 実績数量
金額の修正(補正行の追加:推奨)
Section titled “金額の修正(補正行の追加:推奨)”- 「手数料詳細」タブへ移動
- 「新規」で補正行を追加し、実績金額・通貨・実績数量 を入力
- リファレンス / インフォメーション に補正理由を記入
- 保存後、再度その行を開いて保存し直すか、既存行を更新すると上位(手数料金額・総合計)が再計算されます
⚠️ 注意: 内訳行を 新規追加した時点 では上位金額の自動再計算が走りません(
MCommissionDetail.afterSave()はnewRecord=falseのときだけ再計算するため)。追加後に行を更新するか、上位タブの金額を確認して必要なら再保存してください。既存行の 更新・削除 では確実に再計算されます。
仕入請求伝票の作成
Section titled “仕入請求伝票の作成”- ヘッダーの「請求書作成」ボタンをクリック
- 手数料ルールの受取取引先宛に、買掛の請求伝票が作成されます
- 明細は 1 行のみ(数量 1・単価=総合計)で、料金または品目は手数料ルールの設定が使われます
- 作成後、仕入請求伝票 項目にリンクが設定され、処理済み にチェックが入ります
⚠️ 注意: 総合計が 0 の計算結果では請求書を作成できません(
@GrandTotal@ = 0エラー)。また、手数料ルールの通貨と受取取引先の購買価格表の通貨が異なる場合もエラーになります。
項目リファレンス
Section titled “項目リファレンス”手数料計算タブ
Section titled “手数料計算タブ”| 項目名 | カラム | 必須 | 型 | 説明 |
|---|---|---|---|---|
| 手数料 | C_Commission_ID | 必須 | 選択 | 元になった手数料ルール |
| 伝票番号 | DocumentNo | 必須 | 文字列(30) | 計算結果の伝票番号(識別子) |
| 説明 | Description | - | 文字列(255) | 対象期間が自動セットされる |
| 開始日付 | StartDate | 必須 | 日付 | 対象期間の開始日 |
| 総合計 | GrandTotal | 必須 | 金額 | 手数料金額の合計(自動計算) |
| 請求書作成 | Processing | - | ボタン | 仕入請求伝票の作成 |
| 仕入請求伝票 | C_Invoice_ID | - | 選択 | 作成された請求伝票へのリンク |
| 処理済み | Processed | 必須 | チェック | 請求書作成済みかどうか |
手数料金額タブ
Section titled “手数料金額タブ”| 項目名 | カラム | 必須 | 型 | 説明 |
|---|---|---|---|---|
| 手数料計算 | C_CommissionRun_ID | 必須 | 選択 | 親(計算結果ヘッダー) |
| 手数料明細 | C_CommissionLine_ID | 必須 | 選択 | 対応する計算行 |
| 換算金額 | ConvertedAmt | 必須 | 金額 | 内訳の換算金額合計 |
| 実績数量 | ActualQty | 必須 | 数量 | 内訳の数量合計 |
| 手数料金額 | CommissionAmt | 必須 | 金額 | 計算式適用後の手数料額 |
手数料詳細タブ
Section titled “手数料詳細タブ”| 項目名 | カラム | 必須 | 型 | 説明 |
|---|---|---|---|---|
| 手数料金額 | C_CommissionAmt_ID | 必須 | 選択 | 親(計算行別の金額) |
| リファレンス | Reference | - | 文字列(60) | 参照情報(識別子) |
| インフォメーション | Info | - | 文字列(60) | 補足情報 |
| 発注伝票明細 | C_OrderLine_ID | - | 選択 | 根拠となる受注明細 |
| 仕入請求伝票明細 | C_InvoiceLine_ID | - | 選択 | 根拠となる請求明細 |
| 実績金額 | ActualAmt | 必須 | 金額 | 取引通貨での金額 |
| 通貨 | C_Currency_ID | 必須 | 選択 | 取引通貨 |
| 換算金額 | ConvertedAmt | 必須 | 金額 | 手数料通貨への換算後金額 |
| 実績数量 | ActualQty | 必須 | 数値 | 数量 |
金額の集計構造
Section titled “金額の集計構造”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・単価=総合計"]
よくある質問(FAQ)
Section titled “よくある質問(FAQ)”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 を参照)。
- 販売手数料及びロイヤリティー計算(ルール定義)の使い方
- 仕入請求伝票(Purchase Invoice)の使い方
- 売上請求書(Sales Invoice)の使い方
- 受注伝票(Sales Order)の使い方
- 画面リファレンス: 販売手数料及びロイヤリティー計算結果
🛠 技術仕様(開発者向け)
販売手数料及びロイヤリティー計算結果は 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 ボタンのみです。
アーキテクチャ概要
Section titled “アーキテクチャ概要”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
パッケージ: org.compiere.model / org.compiere.process
ソースファイル:
org.adempiere.base/src/org/compiere/model/MCommissionRun.javaorg.adempiere.base/src/org/compiere/model/MCommissionAmt.javaorg.adempiere.base/src/org/compiere/model/MCommissionDetail.javaorg.adempiere.base.process/src/org/compiere/process/CommissionAPInvoice.java(114行)
関連DBテーブル
Section titled “関連DBテーブル”C_CommissionRun(手数料計算=実行ヘッダー)
Section titled “C_CommissionRun(手数料計算=実行ヘッダー)”| カラム名 | 型 | 必須 | 説明 | 備考 |
|---|---|---|---|---|
| C_CommissionRun_ID | ID | PK | 計算結果ID | 主キー |
| C_CommissionRun_UU | UUID | N | UUID | |
| AD_Client_ID | Table Direct | Y | クライアント | default @#AD_Client_ID@ |
| AD_Org_ID | Table Direct | Y | 組織 | default @#AD_Org_ID@ |
| C_Commission_ID | Table Direct | Y | 手数料ルールFK | |
| DocumentNo | String(30) | Y | 伝票番号 | 識別子(IsIdentifier=Y) |
| Description | String(255) | N | 説明 | 対象期間が自動セット |
| StartDate | Date | Y | 開始日付 | 対象期間の始点 |
| GrandTotal | Amount | Y | 総合計 | updateFromAmt() で再計算 |
| Processing | Button | N | 請求書作成 | CommissionAPInvoice を起動 |
| C_Invoice_ID | Search | N | 仕入請求伝票 | 作成された請求伝票 |
| Processed | Yes-No | Y | 処理済み | 請求書作成で Y |
C_CommissionAmt(手数料金額=計算行別)
Section titled “C_CommissionAmt(手数料金額=計算行別)”| カラム名 | 型 | 必須 | 説明 | 備考 |
|---|---|---|---|---|
| C_CommissionAmt_ID | ID | PK | 手数料金額ID | 主キー・識別子 |
| C_CommissionRun_ID | Search | Y | 計算結果FK | 親(IsParent=Y) |
| C_CommissionLine_ID | Table Direct | Y | 計算行FK | どのルール行の結果か |
| ConvertedAmt | Amount | Y | 換算金額 | 内訳の合計 |
| ActualQty | Quantity | Y | 実績数量 | 内訳の合計 |
| CommissionAmt | Amount | Y | 手数料金額 | 計算式適用後 |
C_CommissionDetail(手数料詳細=取引別内訳)
Section titled “C_CommissionDetail(手数料詳細=取引別内訳)”| カラム名 | 型 | 必須 | 説明 | 備考 |
|---|---|---|---|---|
| C_CommissionDetail_ID | ID | PK | 内訳ID | 主キー |
| C_CommissionAmt_ID | Search | Y | 手数料金額FK | 親(IsParent=Y) |
| C_OrderLine_ID | Search | N | 受注明細 | 計算ベース O のとき |
| C_InvoiceLine_ID | Search | N | 請求明細 | 計算ベース I のとき |
| Reference | String(60) | N | リファレンス | 識別子 |
| Info | String(60) | N | インフォメーション | |
| ActualAmt | Amount | Y | 実績金額 | 取引通貨 |
| C_Currency_ID | Table Direct | Y | 通貨 | 取引通貨 |
| ConvertedAmt | Amount | Y | 換算金額 | 手数料通貨へ換算 |
| ActualQty | Number | Y | 実績数量 |
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"
ビジネスロジック
Section titled “ビジネスロジック”3 階層の再計算カスケード
Section titled “3 階層の再計算カスケード”金額の整合は、下位から上位へ伝播するカスケードで保たれます。
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 更新"]
⚠️ 注意:
MCommissionDetail.afterSave()とMCommissionAmt.afterSave()はいずれもif (!newRecord)の条件付きで上位を更新します。新規レコードの挿入では再計算が走りません。これはCommissionCalcが大量の内訳を挿入する際に、1 行ごとにヘッダーを更新して性能を落とさないための設計です。UI から補正行を新規追加した場合は、その行を再保存するか既存行を更新して再計算を発火させてください。
MCommissionAmt.calculateCommission()
Section titled “MCommissionAmt.calculateCommission()”内訳の ConvertedAmt と ActualQty を合計したうえで、対応する MCommissionLine のパラメータを適用します。
- 内訳をループして
ConvertedAmtとActualQtyを合算し、自身にセット C_CommissionLineを読み込む- 数量:
ActualQty - QtySubtract(IsPositiveOnlyかつ負なら 0)→× QtyMultiplier - 金額:
ConvertedAmt - AmtSubtract(IsPositiveOnlyかつ負なら 0)→× AmtMultiplier CommissionAmt = 金額項 + 数量項をセット
MCommissionRun.updateFromAmt()
Section titled “MCommissionRun.updateFromAmt()”getAmts() で取得した全 C_CommissionAmt の CommissionAmt を合算し、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);処理の要点:
- 総合計 0 の計算結果は拒否
- 手数料ルールに料金・品目のいずれも無ければ拒否
- 伝票タイプは 買掛請求(AP Invoice)、取引先は手数料ルールの受取先
- 請求伝票の通貨(受取先の購買価格表由来)が手数料通貨と異なる場合は拒否
- 明細は 1 行のみ(数量 1・単価=総合計)、税は
setTax()で自動判定 - 計算結果に
C_Invoice_IDを書き戻しProcessed=Yをセット
拡張ポイント(カスタマイズ箇所)
Section titled “拡張ポイント(カスタマイズ箇所)”OSGi Model Validator(推奨)
Section titled “OSGi Model Validator(推奨)”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 のクラス名を差し替えるのが最小改変の方法です。
内訳への外部データ取り込み
Section titled “内訳への外部データ取り込み”MCommissionDetail には setLineIDs(C_OrderLine_ID, C_InvoiceLine_ID) と setConvertedAmt(Timestamp) が公開されているため、外部システムの販売実績を内訳として取り込むカスタムプロセスも実装できます。挿入後は上位の MCommissionAmt.calculateCommission() と MCommissionRun.updateFromAmt() を明示的に呼び出してください(新規挿入では自動再計算されないため)。
関連プロセス
Section titled “関連プロセス”| プロセス名 | 実装クラス | 説明 |
|---|---|---|
| 請求書作成(Create Invoice) | CommissionAPInvoice(114行) | 計算結果から買掛請求伝票を作成 |
| 手数料作成(Generate Commission) | CommissionCalc(454行) | 手数料ルール画面から計算結果を生成 |
| 手数料計算明細レポート | レポート(RV_CommissionRunDetail) | 計算結果を受注/請求の内訳付きで出力 |
関連ドキュメント
Section titled “関連ドキュメント”iDempiereカスタマイズのご相談
Section titled “iDempiereカスタマイズのご相談”手数料の計算結果は監査対象になりやすく、「どの取引がいくらの手数料になったか」を追える形で残せるかが運用の分かれ目になります。内訳の粒度設計や請求書生成ロジックの調整は、コアを触らずプロセス継承で実現できます。
As-Link株式会社では、OSGiプラグインによる安全なカスタマイズを提供しています。