iDempiere プライスリストスキーマの使い方|在庫管理 操作マニュアル・技術仕様
📖 在庫管理の全体像: 在庫管理の業務フロー全体図 も合わせてご覧ください。
プライスリストスキーマは、価格表(プライスリスト)の価格を自動計算するルールを定義するマスタです。「仕入原価に20%上乗せして定価を作る」「限度価格は仕入発注の限度価格をそのまま使う」といった計算式を明細行として登録し、価格表バージョンの作成プロセスから適用します。
📌 ポイント: プライスリストスキーマ自体は価格を持ちません。価格の計算式を持つだけです。実際の価格は価格表バージョンに対してスキーマを適用したときに生成されます。
定価(List)・標準価格(Standard)・限度価格(Limit)の3系統それぞれについて、基準価格・付加金額・割引率・マージン下限/上限・丸め処理を個別に設定できるのが特徴です。
プライスリストスキーマでできること
Section titled “プライスリストスキーマでできること”- 定価・標準価格・限度価格それぞれの計算基準(基準金額)の指定
- 基準価格に対する付加金額と**割引率(%)**の適用
- 元の限度価格に対する最小マージン・最大マージンによる上下限クランプ
- 固定金額の直接指定(計算せず固定値を使用)
- 通貨レートタイプ・換算日付を指定した他通貨価格表からの換算
- 品目・品目カテゴリ・取引先・分類・グループ別の適用条件設定
- 明細のシーケンスNo一括再採番(再計算ボタン)
プライスリストスキーマはヘッダー+明細の2タブ構成です。
| タブ名 | テーブル | 項目数 | 役割 |
|---|---|---|---|
| プライスリストスキーマ | M_DiscountSchema | 8項目 | スキーマ名・割引タイプ・有効開始日 |
| プライスリストスキーマ明細 | M_DiscountSchemaLine | 36項目 | 適用条件と定価/標準価格/限度価格の計算パラメータ |
💡 ヒント: 明細はシーケンスNo順に評価されます。品目・カテゴリ・取引先の条件が細かい行を先(小さいシーケンスNo)に、汎用的な行を後に配置してください。
基本操作手順
Section titled “基本操作手順”graph TD
A["📂 メニューから<br/>プライスリストスキーマを開く"] --> B["➕ 新規<br/>名称・有効開始日を入力"]
B --> C["⚙️ 割引タイプを選択<br/>(プライスリスト等)"]
C --> D["💾 保存"]
D --> E["📋 明細タブで<br/>適用条件を設定<br/>(品目・カテゴリ・取引先)"]
E --> F["💴 定価の計算式を設定<br/>基準金額・付加金額・割引%・丸め"]
F --> G["💵 標準価格の計算式を設定"]
G --> H["💷 限度価格の計算式を設定"]
H --> I["🔢 シーケンスNoで<br/>評価順を調整"]
I --> J["🔄 再計算ボタンで<br/>シーケンスNoを 10 刻みに再採番"]
J --> K["🔗 価格表バージョンに<br/>スキーマを紐付けて実行"]
アクセス方法(メニューパス)
Section titled “アクセス方法(メニューパス)”メニューから「在庫管理 > 品目マスタ管理 > プライスリストスキーマ」を開きます。
新規登録(スキーマ本体)
Section titled “新規登録(スキーマ本体)”- ツールバーの「新規」ボタンをクリック
- 基本情報を入力:
- 名称: スキーマ名(必須・60桁)
- 説明: 用途のメモ(任意)
- 有効開始日: 適用開始日(必須。未入力の場合、保存時に当日が自動セットされます)
- 割引タイプ: 計算方式(必須)
- 「保存」をクリック
明細(計算ルール)の登録
Section titled “明細(計算ルール)の登録”- 「プライスリストスキーマ明細」タブに移動
- 適用条件を設定(すべて任意。未指定なら全件が対象):
- 品目 / 品目カテゴリ / 取引先 / 分類 / Group1 / Group2 / 仕入先の項目カテゴリ
- 換算条件を設定:
- 通貨レートタイプ(必須)・換算日付(必須。初期値は当日)
- 定価・標準価格・限度価格それぞれの計算式を設定:
- 基準金額: 計算の元にする価格(定価・標準価格・限度価格・品目原価・固定価格)
- 付加金額: 基準価格に加算する金額
- 割引 %: 加算後の金額から差し引く割合(マイナス値で上乗せも可能)
- 最小金額 / 最大金額: 元の限度価格に対するマージン下限・上限(0 なら無視)
- 丸め処理: 計算結果の丸め方法
- 固定金額: 計算せず固定値を使いたい場合に入力
- シーケンスNoは既存最大値+10 が自動設定されます
- 「保存」をクリック
⚠️ 注意: 最小金額・最大金額は「元の限度価格との差額」に対する制限です。0 の場合は制限なしとして扱われます。上限だけを効かせたい場合は最小金額を 0 のままにしてください。
リファレンス情報に記載された計算順序は次のとおりです。
graph TD
A["基準価格を参照価格表から取得"] --> B["通貨換算<br/>Convert(BasePrice)"]
B --> C["+ 付加金額 Surcharge"]
C --> D["× (100 - 割引%) / 100"]
D --> E{"最小マージン ≠ 0?"}
E -->|"Yes"| F["Max(結果, 元限度価格 + 最小マージン)"]
E -->|"No"| G{"最大マージン ≠ 0?"}
F --> G
G -->|"Yes"| H["Min(結果, 元限度価格 + 最大マージン)"]
G -->|"No"| I["丸め処理"]
H --> I
I --> J["新価格として価格表に書き込み"]
計算式を数式で表すと次のようになります。
NewPrice = (Convert(BasePrice) + Surcharge) * (100 - Discount) / 100
if MinMargin <> 0 then NewPrice = Max(NewPrice, Convert(OrigLimitPrice) + MinMargin)if MaxMargin <> 0 then NewPrice = Min(NewPrice, Convert(OrigLimitPrice) + MaxMargin)項目リファレンス
Section titled “項目リファレンス”プライスリストスキーマタブ
Section titled “プライスリストスキーマタブ”| 項目名 | 必須 | 型 | 説明 |
|---|---|---|---|
| 名称 | 必須 | 文字列 | スキーマ名(60桁) |
| 説明 | - | 文字列 | 用途のメモ(255桁) |
| 有効開始日 | 必須 | 日付 | 適用開始日(未入力なら保存時に当日) |
| 割引タイプ | 必須 | リスト | 計算方式(後述) |
| 有効 | 必須 | チェック | アクティブ(初期値 Y) |
| 再計算 | - | ボタン | 明細のシーケンスNoを 10 刻みで再採番 |
プライスリストスキーマ明細タブ(主要項目)
Section titled “プライスリストスキーマ明細タブ(主要項目)”| 項目名 | 必須 | 型 | 説明 |
|---|---|---|---|
| シーケンスNo | 必須 | 整数 | 評価順(既存最大+10 が自動設定) |
| 通貨レートタイプ | 必須 | 選択 | 為替換算のレートタイプ |
| 換算日付 | 必須 | 日付 | レート選択の基準日(初期値 当日) |
| 品目 | - | 検索 | 適用対象の品目 |
| 品目カテゴリ | - | 選択 | 適用対象のカテゴリ |
| 取引先 | - | 検索 | 適用対象の取引先 |
| 分類 / Group1 / Group2 | - | 文字列 | 品目のグルーピング条件 |
| 仕入先の項目カテゴリ | - | 文字列 | 取引先側の品目カテゴリ |
| 定価の基準金額 | 必須 | リスト | 定価計算の基準(初期値 定価) |
| 定価への付加金額 | 必須 | 金額 | 基準価格への加算額 |
| 定価の割引 % | 必須 | 数値 | 加算後の金額からの割引率 |
| 定価の最小金額 / 最大金額 | 必須 | 金額 | マージン下限・上限(0 で無視) |
| 定価の丸め処理 | 必須 | リスト | 初期値 通貨精度 |
| 定価の固定金額 | - | 金額 | 計算せず固定値を使用 |
| 標準価格の各項目 | 必須 | 各種 | 初期基準金額は標準価格 |
| 限度価格の各項目 | 必須 | 各種 | 初期基準金額は仕入発注限度価格 |
| Ignore Current Vendor Flag | 必須 | チェック | 全仕入価格を対象にする(初期値 N) |
割引タイプの選択肢
Section titled “割引タイプの選択肢”| 表示 | コード | 説明 |
|---|---|---|
| Breaks(数量段階) | B | 数量ブレークによる段階割引 |
| Flat Percent(定率) | F | 一律の割引率 |
| Pricelist(プライスリスト) | P | 価格表の計算ルール(本ウィンドウの明細タブが対象) |
| Formula(スクリプト) | S | スクリプトによる計算 |
📌 ポイント: 本ウィンドウの「プライスリストスキーマ明細」タブは**割引タイプ = Pricelist(P)**で使用する計算ルールです。数量段階割引(Breaks)を使う場合は割引スキーマ側のブレーク定義を使用します。
基準金額の選択肢
Section titled “基準金額の選択肢”| 表示 | コード | 説明 |
|---|---|---|
| List Price(定価) | L | 参照価格表の定価 |
| Standard Price(標準価格) | S | 参照価格表の標準価格 |
| Limit PO Price(限度価格) | X | 仕入発注の限度価格 |
| Product Cost(品目原価) | P | 品目の原価 |
| Fixed Price(固定価格) | F | 固定金額欄の値をそのまま使用 |
丸め処理の選択肢
Section titled “丸め処理の選択肢”| 表示 | コード | 説明 |
|---|---|---|
| 通貨精度 | C | 通貨の小数桁で丸め(初期値) |
| 丸めなし | N | 丸め処理を行わない |
| 整数(.00) | 0 | 小数以下を丸める |
| 5円/セント単位 | 5 | 05・10・15 単位で丸め |
| 10単位 | D | 10・20・30 単位で丸め |
| 25単位 | Q | 25・50・75 単位で丸め |
| 末尾 .95 | 9 | 末尾を 95 にする |
| 10の位 | T | 1000・2000 単位で丸め |
| 100単位 | h | 100 単位で丸め |
| 1000単位 | t | 1000 単位で丸め |
よくある質問(FAQ)
Section titled “よくある質問(FAQ)”Q. 有効開始日を空欄で保存したらどうなりますか?
Section titled “Q. 有効開始日を空欄で保存したらどうなりますか?”保存時に当日日付が自動セットされます(beforeSave() の処理)。意図した適用開始日がある場合は必ず明示的に入力してください。
Q. シーケンスNoが飛び飛びになってしまいました。
Section titled “Q. シーケンスNoが飛び飛びになってしまいました。”ヘッダータブの「再計算」ボタンを実行すると、明細のシーケンスNoが 10・20・30… と 10 刻みで再採番されます。数量ブレークの定義がある場合はそちらも同時に再採番されます。
Q. 取引先を空欄にすると「Ignore Current Vendor Flag」はどうなりますか?
Section titled “Q. 取引先を空欄にすると「Ignore Current Vendor Flag」はどうなりますか?”取引先が未指定(0)の場合、保存時に Ignore Current Vendor Flag が自動的に OFF になります。このフラグは取引先を指定した明細でのみ意味を持ちます。
Q. 固定金額を入れると計算式は無視されますか?
Section titled “Q. 固定金額を入れると計算式は無視されますか?”基準金額を「Fixed Price(F)」に設定した場合に固定金額欄の値が使われます。基準金額が固定価格以外のままだと、固定金額欄を入力しても計算式が優先されます。
Q. マージンの下限・上限が効きません。
Section titled “Q. マージンの下限・上限が効きません。”最小金額・最大金額は **0 の場合は「制限なし」**として扱われる仕様です。値を 0 以外に設定してください。また、これらは「元の限度価格+マージン」との比較であり、基準価格との比較ではない点に注意が必要です。
🛠 技術仕様(開発者向け)
プライスリストスキーマはマスタデータ型のウィンドウ(AD_Window_ID: 337)で、ヘッダーは M_DiscountSchema、明細は M_DiscountSchemaLine テーブルに格納されます。MDiscountSchema クラス(488行)は ImmutablePOSupport を実装しキャッシュ経由の高速参照(MDiscountSchema.get(M_DiscountSchema_ID))をサポートします。MDiscountSchemaLine クラスは119行の軽量クラスです。両テーブルとも AccessLevel = 3(Client + Organization)です。
同じ M_DiscountSchema テーブルは、価格表計算(Pricelist)だけでなく数量段階割引(Breaks / M_DiscountSchemaBreak)や取引先向け定率割引(Flat Percent)でも共有されます。
アーキテクチャ概要
Section titled “アーキテクチャ概要”classDiagram
class MDiscountSchema {
+get(int) MDiscountSchema
+getLines(boolean) MDiscountSchemaLine[]
+getBreaks(boolean) MDiscountSchemaBreak[]
+calculatePrice(...) BigDecimal
+calculateDiscount(...) BigDecimal
+calculateDiscountedPrice(BigDecimal, BigDecimal)$ BigDecimal
+reSeq() int
#beforeSave(boolean) boolean
+markImmutable() MDiscountSchema
}
class MDiscountSchemaLine {
#beforeSave(boolean) boolean
+markImmutable() MDiscountSchemaLine
}
class X_M_DiscountSchema {
<<generated>>
}
class PO {
<<abstract>>
}
class ImmutablePOSupport {
<<interface>>
}
MDiscountSchema --|> X_M_DiscountSchema
X_M_DiscountSchema --|> PO
MDiscountSchema ..|> ImmutablePOSupport
MDiscountSchemaLine ..|> ImmutablePOSupport
MDiscountSchema --> MDiscountSchemaLine : has many
MDiscountSchema --> MDiscountSchemaBreak : has many
パッケージ: org.compiere.model
ソースファイル: org.adempiere.base/src/org/compiere/model/MDiscountSchema.java(488行) / MDiscountSchemaLine.java(119行)
関連DBテーブル
Section titled “関連DBテーブル”M_DiscountSchema(プライスリストスキーマ)
Section titled “M_DiscountSchema(プライスリストスキーマ)”| カラム名 | 型 | 必須 | 説明 | 備考 |
|---|---|---|---|---|
| M_DiscountSchema_ID | ID | PK | スキーマID | 主キー |
| AD_Client_ID | Table Direct | Y | テナント | 既定 @#AD_Client_ID@ |
| AD_Org_ID | Table Direct | Y | 組織 | 既定 @#AD_Org_ID@ |
| Name | String(60) | Y | 名称 | |
| Description | String(255) | N | 説明 | |
| ValidFrom | Date | Y | 有効開始日 | 未設定時は保存時に当日 |
| DiscountType | List(1) | Y | 割引タイプ | B / F / P / S |
| IsQuantityBased | Yes-No | Y | 数量ベース | 既定 Y |
| FlatDiscount | Number | N | 定率割引 % | DiscountType=F で使用 |
| CumulativeLevel | List(1) | N | 累積レベル | 既定 L(明細) |
| IsBPartnerFlatDiscount | Yes-No | Y | 取引先の定率割引を使用 | |
| Script | Text(2000) | N | スクリプト | DiscountType=S で使用 |
| Processing | Button | N | 再計算 | reSeq() を実行 |
| IsActive | Yes-No | Y | 有効 | 既定 Y |
M_DiscountSchemaLine(プライスリストスキーマ明細・主要カラム)
Section titled “M_DiscountSchemaLine(プライスリストスキーマ明細・主要カラム)”| カラム名 | 型 | 必須 | 説明 | 備考 |
|---|---|---|---|---|
| M_DiscountSchemaLine_ID | ID | PK | 明細ID | 主キー |
| M_DiscountSchema_ID | Table | Y | 親スキーマFK | 更新不可 |
| SeqNo | Integer | Y | シーケンスNo | 既定 MAX(SeqNo)+10 の SQL 既定値 |
| C_ConversionType_ID | Table Direct | Y | 通貨レートタイプ | |
| ConversionDate | Date | Y | 換算日付 | 既定 @#Date@ |
| M_Product_ID | Search | N | 品目 | 適用条件 |
| M_Product_Category_ID | Table Direct | N | 品目カテゴリ | 適用条件 |
| C_BPartner_ID | Search | N | 取引先 | 適用条件 |
| Classification | String(12) | N | 分類 | 適用条件 |
| Group1 / Group2 | String(255) | N | グループ | 適用条件 |
| VendorCategory | String(30) | N | 仕入先の項目カテゴリ | 適用条件 |
| List_Base | List(1) | Y | 定価の基準金額 | 既定 L |
| List_AddAmt | Amount | Y | 定価への付加金額 | |
| List_Discount | Number | Y | 定価の割引 % | |
| List_MinAmt / List_MaxAmt | Amount | Y | 定価のマージン下限・上限 | 0 で無視 |
| List_Rounding | List(1) | Y | 定価の丸め処理 | 既定 C |
| List_Fixed | Amount | N | 定価の固定金額 | |
| Std_Base | List(1) | Y | 標準価格の基準金額 | 既定 S |
| Std_AddAmt / Std_Discount / Std_MinAmt / Std_MaxAmt / Std_Rounding / Std_Fixed | 各種 | Y/N | 標準価格の計算パラメータ | Std_Rounding 既定 C |
| Limit_Base | List(1) | Y | 限度価格の基準金額 | 既定 X(仕入発注限度価格) |
| Limit_AddAmt / Limit_Discount / Limit_MinAmt / Limit_MaxAmt / Limit_Rounding / Limit_Fixed | 各種 | Y/N | 限度価格の計算パラメータ | Limit_Rounding 既定 C |
| IsIgnoreIsCurrentVendor | Yes-No | Y | 現在仕入先フラグを無視 | 既定 N |
erDiagram
M_DiscountSchema ||--o{ M_DiscountSchemaLine : "pricelist rules"
M_DiscountSchema ||--o{ M_DiscountSchemaBreak : "quantity breaks"
M_DiscountSchemaLine }o--o| M_Product : "condition"
M_DiscountSchemaLine }o--o| M_Product_Category : "condition"
M_DiscountSchemaLine }o--o| C_BPartner : "condition"
M_DiscountSchemaLine }o--|| C_ConversionType : "currency rate"
M_DiscountSchema ||--o{ M_PriceList_Version : "applied to"
ビジネスロジック
Section titled “ビジネスロジック”MDiscountSchema.beforeSave()
Section titled “MDiscountSchema.beforeSave()”ValidFrom が null の場合に TimeUtil.getDay(null)(当日)を自動セットするのみの、非常に軽量な実装です。
MDiscountSchema.reSeq()
Section titled “MDiscountSchema.reSeq()”「再計算」ボタン(Processing)から呼ばれ、明細とブレークのシーケンスNoを再採番します。
getLines(true)で明細を再取得i番目の行に(i+1) * 10をセット(既存値と異なる行のみsave())getBreaks(true)で数量ブレークを再取得し、同様に(i+1) * 10を再採番- 内部キャッシュ(
m_lines/m_breaks)を破棄し、更新件数を返却
MDiscountSchemaLine.beforeSave()
Section titled “MDiscountSchemaLine.beforeSave()”C_BPartner_ID が 0(取引先未指定)の場合に IsIgnoreIsCurrentVendor を false に強制します。取引先条件のない明細でこのフラグを立てても意味を持たないためです。
価格・割引計算 API
Section titled “価格・割引計算 API”| メソッド | 用途 |
|---|---|
calculatePrice(Qty, Price, ...) | 数量・基準価格からスキーマ適用後の価格を算出 |
calculateDiscount(Qty, Price, ...) | 適用される割引率を算出 |
calculateDiscountedPrice(price, discount) | 価格と割引率から割引後価格を算出(static) |
イミュータブルキャッシュ
Section titled “イミュータブルキャッシュ”MDiscountSchema は ImmutablePOSupport を実装しており、MDiscountSchema.get(M_DiscountSchema_ID) でキャッシュ経由の参照が可能です。価格計算は明細処理のたびに呼ばれるため、ループ内では new MDiscountSchema(...) ではなく get() を使用してください。markImmutable() で読み取り専用インスタンス化されます。
拡張ポイント(カスタマイズ箇所)
Section titled “拡張ポイント(カスタマイズ箇所)”OSGi Model Validator(推奨)
Section titled “OSGi Model Validator(推奨)”public class CustomPriceListSchemaValidator implements ModelValidator { @Override public int modelChange(PO po, int type) throws Exception { if (po instanceof MDiscountSchemaLine && (type == TYPE_BEFORE_NEW || type == TYPE_BEFORE_CHANGE)) { MDiscountSchemaLine line = (MDiscountSchemaLine) po; // 例: 定価の割引率が負値(=値上げ)になる設定を禁止する if (line.getList_Discount().signum() < 0) { throw new AdempiereException("定価の割引%にマイナス値は設定できません"); } } return null; }}IPricingRule によるカスタム価格計算
Section titled “IPricingRule によるカスタム価格計算”伝票上の実売価格計算そのものを拡張したい場合は、IPricingRule インターフェースを実装し OSGi サービスとして登録します。プライスリストスキーマは「価格表を作るときのルール」であり、IPricingRule は「伝票入力時に価格を決めるルール」である点が異なります。用途に応じて使い分けてください。
Callout
Section titled “Callout”M_DiscountSchema / M_DiscountSchemaLine の各カラムには標準の Callout は設定されていません(AD メタデータ上 Callout 列は空)。
関連プロセス
Section titled “関連プロセス”| プロセス名 | 説明 |
|---|---|
| 再計算(Processing ボタン) | 明細・数量ブレークのシーケンスNoを 10 刻みで再採番 |
関連ドキュメント
Section titled “関連ドキュメント”iDempiereカスタマイズのご相談
Section titled “iDempiereカスタマイズのご相談”価格の自動計算ルールは、業種ごとに独自の掛率体系や端数処理を持つことが多く、標準機能だけでは表現しきれない場合があります。
IPricingRule の実装や Model Validator により、コア改変なしで自社の価格ロジックを組み込めます。
As-Link株式会社では、OSGiプラグインによる安全なカスタマイズを提供しています。