Skip to content

iDempiere 仕入先別品目購買情報の使い方|在庫管理 操作マニュアル・技術仕様

This content is not available in your language yet.

📖 在庫管理の全体像: 在庫管理の業務フロー全体図 も合わせてご覧ください。

仕入先別品目購買情報は、仕入先を軸に取扱品目の購買条件(仕入価格・納期・最小発注数量・仕入先品番)を一覧表示・編集する画面です。品目マスタの「購買情報」タブと同じ M_Product_PO テーブルを扱いますが、こちらは仕入先単位でまとめてメンテナンスできる点が異なります。

📌 ポイント: 1 つの品目に対して「現在の仕入先」にできるのは 1 社だけです。2 社目にチェックを入れようとすると保存エラーになります。

仕入先別品目購買情報でできること

Section titled “仕入先別品目購買情報でできること”
  • 仕入先を選択して、その仕入先の取扱品目を一括表示
  • 仕入先ごとの仕入価格(営業定価・仕入価格・使用料金)の登録
  • 仕入先品番(VendorProductNo)・仕入先カテゴリ・製造業者の管理
  • 最小注文数量・注文パック数量の設定
  • 納品予定日数・実納品時間の記録
  • 最終発注価格・最終請求価格の参照(読み取り専用)
  • 「現在の仕入先」の指定(価格算定・在庫補充で使用)
  • 品質レイティングによる仕入先評価
  • 取扱終了フラグ・取扱終了日の記録

仕入先別品目購買情報は 2 タブ構成です。

タブ名テーブル項目数役割
仕入先C_BPartner5項目仕入先の選択(親タブ・参照中心)
仕入品目購買情報M_Product_PO25項目選択した仕入先の品目別購買条件

💡 ヒント: 親タブ(仕入先)は取引先マスタのビューです。取引先の詳細登録は取引先マスタから行ってください。

graph TD
    A["🚀 メニューから開く<br/>在庫管理 > 品目マスタ管理 ><br/>仕入先別品目購買情報"] --> B["🔍 仕入先タブで<br/>対象の仕入先を検索・選択"]
    B --> C["📋 仕入品目購買情報タブへ移動<br/>(取扱品目が一覧表示)"]
    C --> D{新しい取扱品目を<br/>追加する?}
    D -->|する| E["➕ 新規 → 品目を選択<br/>仕入先の項目コードを入力"]
    D -->|しない| F["✏ 既存行の価格・納期を編集"]
    E --> G["💴 価格を入力<br/>営業定価 / 仕入価格 / 通貨"]
    F --> G
    G --> H["📦 発注条件を入力<br/>最小注文数量 / 注文パック数量 / 納品予定日数"]
    H --> I{この仕入先を<br/>主取引先にする?}
    I -->|する| J["⭐ 現在の仕入先にチェック<br/>(品目につき1社のみ)"]
    I -->|しない| K["☐ チェックを外す"]
    J --> L["💾 保存"]
    K --> L
    L --> M["🛒 発注伝票・在庫補充で<br/>価格・納期が参照される"]

メニューから開く 在庫管理 > 品目マスタ管理 > 仕入先別品目購買情報 仕入先タブで 対象の仕入先を検索・選択 仕入品目購買情報タブへ移動 (取扱品目が一覧表示) 新規 → 品目を選択 仕入先の項目コードを入力 既存行の価格・納期を編集 価格を入力 営業定価 / 仕入価格 / 通貨 発注条件を入力 最小注文数量 / 注文パック数量 / 納品予定日数 現在の仕入先にチェック (品目につき1社のみ) チェックを外す 保存 発注伝票・在庫補充で 価格・納期が参照される 新しい取扱品目を 追加する? この仕入先を 主取引先にする? する しない

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

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

メニューから「在庫管理 > 品目マスタ管理 > 仕入先別品目購買情報」を開きます。

  1. 仕入先」タブで対象の仕入先を検索・選択します
  2. 参照できる項目: 検索キー・名称・説明・取引先グループ・債権債務残高
  1. 仕入品目購買情報」タブに移動
  2. 新規」をクリックし、必須項目を入力:
    • 取引先: 親タブから自動セット
    • 品目: 対象品目(既定値 @M_Product_ID@
    • 仕入先の項目コード: 仕入先側の品番(既定値 @Value@ = 品目の検索キー)
  3. 価格情報を入力:
    • 通貨: 取引通貨
    • 営業定価: 仕入先の定価
    • 仕入価格: 実際の仕入単価
    • 価格有効日: 価格の適用開始日
    • 使用料金: 著作権料等の内包金額
  4. 発注条件を入力:
    • 数量単位 / 最小注文数量 / 注文パック数量
    • 納品予定日数: 発注から納品までの約束日数
    • 注文毎の固定費: 発注 1 回あたりの固定費
  5. 必要に応じて 現在の仕入先 にチェック
  6. 保存」をクリック

⚠️ 注意: 「最終発注価格」「最終請求価格」は更新不可(IsUpdateable=N)の項目で、発注・請求処理によって自動更新されます。手入力はできません。

仕入品目購買情報タブ(主要項目)

Section titled “仕入品目購買情報タブ(主要項目)”
項目名必須説明
取引先必須検索仕入先(親レコード)
品目必須検索対象品目(既定値 @M_Product_ID@
仕入先の項目コード必須文字列(40)仕入先側の品番(既定値 @Value@
現在の仕入先必須チェック価格・在庫補充に使う主仕入先(既定値 Y)
通貨-選択取引通貨
営業定価-金額仕入先の定価
仕入価格-金額実際の仕入単価
価格有効日-日付価格の適用開始日
使用料金-金額内包される著作権料等
最終発注価格-金額直近の発注価格(更新不可・自動更新)
最終請求価格-金額直近の請求価格(更新不可・自動更新)
数量単位-選択発注単位
最小注文数量-数量最小発注ロット
注文パック数量-数量発注単位数量(例: 5個セット)
納品予定日数-整数発注から納品までの約束日数
実納品時間-整数実績の所要日数
注文毎の固定費-金額発注 1 回あたりの固定費
品質レイティング-整数仕入先評価
JAN/UPC/EAN-文字列(20)バーコード
仕入先の項目カテゴリ-文字列(30)仕入先側のカテゴリ
製造業者-文字列(30)製造業者名
取扱終了-チェック取扱終了フラグ
取扱終了日-日付取扱終了日

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

Q. 「現在の仕入先」にチェックしたら保存できません

Section titled “Q. 「現在の仕入先」にチェックしたら保存できません”

同じ品目に対して、有効かつ「現在の仕入先」が Y のレコードが既に別の取引先で存在しています。MProductPO.beforeSave()M_Product_PO を件数チェックし、他の取引先に該当行があると一意制約エラー(SAVE_ERROR_NOT_UNIQUE_MSG + 「現在の仕入先」)で保存を中止します。先に既存仕入先のチェックを外してください。

Q. 品目マスタの「購買情報」タブとの違いは何ですか?

Section titled “Q. 品目マスタの「購買情報」タブとの違いは何ですか?”

対象テーブルは同じ M_Product_PO で、データも共通です。違いは軸だけで、品目マスタは「品目 → 仕入先」、この画面は「仕入先 → 品目」の順で辿ります。仕入先との価格改定交渉のように、1 社の取扱品目をまとめて更新する作業ではこちらが効率的です。

Q. 「仕入先の項目コード」は必ず入力が必要ですか?

Section titled “Q. 「仕入先の項目コード」は必ず入力が必要ですか?”

必須項目です。既定値として品目の検索キー(@Value@)がセットされるため、仕入先側の品番が自社コードと同じ場合はそのまま保存できます。発注書に仕入先品番を印字する運用では、実際の仕入先品番に置き換えてください。

Q. 複数通貨の仕入価格を管理できますか?

Section titled “Q. 複数通貨の仕入価格を管理できますか?”

できます。C_Currency_ID を行ごとに設定できるため、仕入先ごとに異なる通貨での価格登録が可能です。ただし 1 つの品目・仕入先の組み合わせは 1 レコードのため、同一仕入先で複数通貨を併記することはできません。

Q. 取扱終了した品目はどう扱いますか?

Section titled “Q. 取扱終了した品目はどう扱いますか?”

「取扱終了」にチェックし、「取扱終了日」を入力します。レコードを削除すると発注履歴からの参照や価格の経緯が追えなくなるため、フラグでの管理を推奨します。

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

仕入先別品目購買情報はマスタデータ型のウィンドウ(AD_Window_ID: 176)で、親タブが C_BPartner、子タブが M_Product_PO(アクセスレベル 3)です。MProductPO クラス(122行)は非常に薄く、beforeSave() による「現在の仕入先」の一意チェックと、品目単位の取得ユーティリティ getOfProduct() のみを持ちます。Document 型ではありません。

classDiagram
    class MProductPO {
        +getOfProduct(ctx, M_Product_ID, trxName) MProductPO[]
        +beforeSave(newRecord) boolean
    }
    class X_M_Product_PO {
        <<generated>>
    }
    class PO {
        <<abstract>>
    }
    MProductPO --|> X_M_Product_PO
    X_M_Product_PO --|> PO
    MProductPO --> MProduct : purchasing info for
    MProductPO --> MBPartner : vendor

+getOfProduct(ctx, M_Product_ID, trxName) MProductPO[] +beforeSave(newRecord) boolean <> <> > X_M_Product_PO X_M_Product_PO --

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

主キーは M_Product_ID + C_BPartner_ID の複合です。

カラム名必須説明備考
M_Product_IDSearchY品目IsParent=Y・既定値 @M_Product_ID@
C_BPartner_IDSearchY取引先(仕入先)IsParent=Y
AD_Client_IDTable DirectYクライアント既定値 @AD_Client_ID@
AD_Org_IDTable DirectY組織既定値 @AD_Org_ID@
VendorProductNoString(40)Y仕入先の項目コード既定値 @Value@
IsCurrentVendorYes-NoY現在の仕入先既定値 Y・beforeSave で一意チェック
C_Currency_IDTable DirectN通貨
PriceListCosts+PricesN営業定価
PricePOCosts+PricesN仕入価格
PriceEffectiveDateN価格有効日
PriceLastPOCosts+PricesN最終発注価格IsUpdateable=N
PriceLastInvCosts+PricesN最終請求価格IsUpdateable=N
RoyaltyAmtAmountN使用料金
C_UOM_IDTable DirectN数量単位
Order_MinQuantityN最小注文数量
Order_PackQuantityN注文パック数量
DeliveryTime_PromisedIntegerN納品予定日数
DeliveryTime_ActualIntegerN実納品時間
CostPerOrderCosts+PricesN注文毎の固定費
QualityRatingIntegerN品質レイティング
UPCString(20)NJAN/UPC/EAN
VendorCategoryString(30)N仕入先の項目カテゴリ
ManufacturerString(30)N製造業者
DiscontinuedYes-NoN取扱終了
DiscontinuedAtDateN取扱終了日
IsActiveYes-NoY有効既定値 Y
erDiagram
    C_BPartner ||--o{ M_Product_PO : "supplies"
    M_Product ||--o{ M_Product_PO : "vendor info"
    M_Product_PO }o--o| C_UOM : "order UOM"
    M_Product_PO }o--o| C_Currency : "currency"
    M_Product ||--o{ M_Replenish : "replenishment"
    C_Order ||--o{ C_OrderLine : "purchase order"

vendor info order UOM purchase order

beforeSave() — 現在の仕入先の一意チェック

Section titled “beforeSave() — 現在の仕入先の一意チェック”
if (isActive() && isCurrentVendor())
{
int cnt = DB.getSQLValue(get_TrxName(),
"SELECT COUNT(*) FROM M_Product_PO WHERE IsActive='Y' AND IsCurrentVendor='Y'"
+ " AND C_BPartner_ID!=? AND M_Product_ID=?",
getC_BPartner_ID(), getM_Product_ID());
if (cnt > 0) {
log.saveError("SaveError", ... + Msg.getElement(getCtx(), COLUMNNAME_IsCurrentVendor));
return false;
}
}

処理の要点:

  1. 有効(IsActive=Y)かつ「現在の仕入先」(IsCurrentVendor=Y のレコードのみが検証対象
  2. 同一品目で自分以外の取引先に有効な「現在の仕入先」行が存在すれば保存を中止
  3. 無効化されたレコードは件数に含まれないため、旧仕入先を無効化すれば新仕入先を主取引先にできる

💡 ヒント: 主仕入先を切り替える際は「旧レコードの IsCurrentVendor を外して保存 → 新レコードにチェックして保存」の順に行ってください。逆順ではこの beforeSave() チェックに阻まれます。

MProductPO.getOfProduct(Properties ctx, int M_Product_ID, String trxName) は、指定品目に紐づく全仕入先情報を MProductPO[] で返します。発注価格の決定や在庫補充処理から利用されます。

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

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

M_Product_PO の各カラムには標準の Callout は定義されていません。既定値は AD の DefaultValue@M_Product_ID@@Value@@AD_Client_ID@ 等)で解決されます。

public class CustomProductPOValidator implements ModelValidator {
@Override
public int modelChange(PO po, int type) throws Exception {
if (po instanceof MProductPO && (type == TYPE_BEFORE_NEW || type == TYPE_BEFORE_CHANGE)) {
MProductPO ppo = (MProductPO) po;
// 例: 仕入価格が営業定価を上回る登録を禁止
if (ppo.getPricePO() != null && ppo.getPriceList() != null
&& ppo.getPricePO().compareTo(ppo.getPriceList()) > 0) {
throw new AdempiereException("仕入価格が営業定価を上回っています");
}
}
return null;
}
}

発注価格決定ロジックへの介入

Section titled “発注価格決定ロジックへの介入”

発注価格の決定は価格表エンジン(IPricingRule)と M_Product_PO の組み合わせで行われます。仕入先別の独自価格ロジック(数量帯別仕入価格など)が必要な場合は、IPricingRule を OSGi サービスとして追加する方式が、コア改変なしで実現できます。

リファレンスページ・メニューに、このウィンドウ固有の標準プロセス(ボタン起動プロセス)は登録されていません。


仕入先別の価格・納期情報は、発注業務の自動化と在庫補充の精度を左右します。iDempiere では標準の M_Product_PO を活かしたまま、価格ルールや承認フローを OSGi プラグインで追加できます。

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

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