コンテンツにスキップ

iDempiere 得意先(顧客)の担当者の使い方|販売管理 操作マニュアル・技術仕様

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

得意先(顧客)の担当者は、取引先に所属する個人(窓口担当者)を管理する画面です。氏名・メールアドレス・電話番号といった連絡先に加え、その担当者に対して行った営業活動(タスク・メール・電話・面談)を子タブで時系列に記録できます。

📌 ポイント: このウィンドウは AD_User テーブルを扱います。同じテーブルはシステムのログインユーザーも保持しているため、パスワードを設定した瞬間に「ログインできるユーザー」としての一意性検証が働きます。単なる連絡先として登録する場合はパスワードを空のままにしてください。

得意先(顧客)の担当者でできること

Section titled “得意先(顧客)の担当者でできること”
  • 取引先(C_BPartner_ID)に所属する担当者の連絡先を登録する
  • メールアドレス・電話番号・電話番号2・FAX を管理する
  • 取引先住所(C_BPartner_Location_ID)と役職(C_Job_ID)を紐付ける
  • 生年月日・肩書き(タイトル)を記録し、記念日対応や敬称に活用する
  • 最新履歴日(LastContact)・最新履歴情報(LastResult)で直近の接触結果を残す
  • 営業活動タブでタスク・メール・電話・面談を期間付きで記録し、完了フラグで管理する
  • 各営業活動を営業案件(C_Opportunity_ID)に紐付けて案件単位の履歴とする

ヘッダー1タブ+営業活動の子タブという2タブ構成です。

タブ名テーブル階層項目数役割
顧客担当者AD_User0約17項目担当者の基本情報・連絡先
営業活動(アクティビティ)C_ContactActivity111項目タスク・メール・電話・面談の記録
graph TD
    T1["👤 顧客担当者<br/>AD_User<br/>約17項目"]
    T2["📅 営業活動(アクティビティ)<br/>C_ContactActivity<br/>11項目"]
    T1 --> T2
    T2 --> T3["🎯 営業案件<br/>C_Opportunity<br/>(参照)"]

顧客担当者 AD_User 約17項目 営業活動(アクティビティ) C_ContactActivity 11項目 営業案件 C_Opportunity (参照)

💡 ヒント: 同じ AD_User テーブルを扱う画面として「見込顧客の担当者(Lead)」があります。まだ取引先になっていない相手は Lead 側で管理し、商談化して取引先が作られた後にこちらの画面で管理する、という使い分けが標準の流れです。

graph TD
    A["🚀 メニューから開く<br/>販売管理 > 見込顧客管理 > 得意先(顧客)の担当者"] --> B["➕ 新規<br/>名称を入力(必須)"]
    B --> C["🏢 取引先を選択<br/>(所属する会社)"]
    C --> D["📍 取引先住所・役職を選択"]
    D --> E["✉️ Eメール・電話番号を入力"]
    E --> F["💾 保存"]
    F --> G["📅 営業活動タブへ移動"]
    G --> H["➕ 営業活動タイプを選択<br/>(タスク/メール/電話/面談)"]
    H --> I["📝 説明・開始日付を入力<br/>(いずれも必須)"]
    I --> J{"案件に紐付ける?"}
    J -->|Yes| K["🎯 営業案件を選択"]
    J -->|No| L["💾 保存"]
    K --> L
    L --> M["✅ 完了したら<br/>「完成」にチェック"]

メニューから開く 販売管理 > 見込顧客管理 > 得意先(顧客)の担当者 新規 名称を入力(必須) 取引先を選択 (所属する会社) 取引先住所・役職を選択 Eメール・電話番号を入力 保存 営業活動タブへ移動 営業活動タイプを選択 (タスク/メール/電話/面談) 説明・開始日付を入力 (いずれも必須) 案件に紐付ける? 営業案件を選択 完了したら 「完成」にチェック

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

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

メニューから「販売管理 > 見込顧客管理 > 得意先(顧客)の担当者」を開きます(AD_Window_ID: 53152)。

  1. ツールバーの「新規」ボタンをクリック
  2. 必須項目を入力:
    • クライアント: 対象テナント(コンテキスト @#AD_Client_ID@ から自動セット)
    • 組織: 対象組織
    • 名称: 担当者の氏名(最大60文字)
  3. 連絡先情報を入力:
    • 取引先: 所属する会社
    • 取引先住所: 所属する会社の該当拠点
    • 役職: 役職マスタ(C_Job)から選択
    • Eメール: メールアドレス(形式チェックあり)
    • 電話番号 / 電話番号2 / FAX
    • タイトル: 肩書き
  4. 保存」をクリック

⚠️ 注意: メールアドレスは保存時に形式が検証されます。不正な形式の場合は「InvalidEMailFormat」というエラーで保存が中断されます。また既存担当者のメールアドレスを変更すると、メール検証日(EMailVerifyDate)が自動的にクリアされます。

  1. 営業活動(アクティビティ)」タブに移動
  2. 必須項目を入力:
    • 営業活動タイプ: TA=タスク / EM=メール / PC=電話 / ME=面談
    • 説明: 活動内容の要約(最大255文字)
    • 開始日付: 既定値は当日(SYSDATE
  3. 任意項目を入力:
    • 終了日付: 活動の終了日時
    • 社内担当者: 既定値はログインユーザーの営業担当(@#SalesRep_ID@
    • 営業案件: 紐付ける営業案件
    • コメント: 詳細な議事メモ
  4. 活動が完了したら「完成」(IsComplete)にチェックを入れて保存
営業活動タイプコード用途
タスクTA対応予定・ToDo
メールEMメール送受信の記録
電話PC架電・受電の記録
面談ME訪問・打合せの記録
項目名必須説明
クライアント必須選択対象テナント
組織必須選択対象組織
名称必須文字列(60)担当者の氏名
取引先-検索所属する取引先
取引先住所-選択所属拠点の住所
役職-選択役職(C_Job
Eメール-文字列(60)メールアドレス(形式チェックあり)
電話番号-文字列(40)主たる電話番号
電話番号2-文字列(40)サブ電話番号、緊急連絡先
FAX-文字列(40)FAX 番号
タイトル-文字列(40)肩書き
生年月日-日付誕生日・記念日
最新履歴日-日付最後に接触した日
最新履歴情報-文字列(255)最後の接触結果
説明-文字列(255)短い補足
コメント-テキスト(2000)詳細メモ
有効必須チェックレコードが有効か
項目名必須説明
営業活動タイプ必須リストTA / EM / PC / ME
説明必須文字列(255)活動内容の要約
開始日付必須日時既定値 SYSDATE
終了日付-日時活動の終了日時
ユーザー-検索対象の担当者(既定値 @AD_User_ID@
社内担当者-選択自社の営業担当(既定値 @#SalesRep_ID@
営業案件-選択紐付ける営業案件(既定値 @C_Opportunity_ID@
コメント-テキスト詳細な議事メモ
完成-チェック活動が完了したか

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

Q. メールアドレスを入力したら保存できません

Section titled “Q. メールアドレスを入力したら保存できません”

MUser.beforeSave() が IDEMPIERE-1409 の対応としてメールアドレスの形式検証(isEMailValid())を行っています。新規登録時、またはメールアドレスを変更した時に不正な形式だと「InvalidEMailFormat」で保存が拒否されます。全角文字や余分な空白が混入していないか確認してください。

Q. 「メールアドレスが重複しています」と表示されました

Section titled “Q. 「メールアドレスが重複しています」と表示されました”

パスワードを設定した担当者にのみ発生します。システム設定 USE_EMAIL_FOR_LOGIN が有効な場合、beforeSave() は「パスワードが設定されている同一テナント内のユーザー」に対してメールアドレスの一意性を SQL で検証します。連絡先としてだけ登録する担当者にはパスワードを設定しないでください。

Q. パスワードなしでもメールアドレスは必須ですか?

Section titled “Q. パスワードなしでもメールアドレスは必須ですか?”

いいえ。メールアドレスが必須になるのは、USE_EMAIL_FOR_LOGIN が有効かつパスワードを設定している場合のみです。パスワードが空であれば、メールアドレスなしでも保存できます。

Q. パスワードを設定したら「名称が重複しています」と出ました

Section titled “Q. パスワードを設定したら「名称が重複しています」と出ました”

USE_EMAIL_FOR_LOGIN が無効の場合、beforeSave() は IDEMPIERE-1672 の対応として COALESCE(LDAPUser, Name) の一意性を、同一テナント内のパスワード保持ユーザーに対して検証します。同姓同名の担当者にログイン権限を与える場合は、LDAP ユーザー名で区別してください。

Q. パスワードのルールはどこで決まりますか?

Section titled “Q. パスワードのルールはどこで決まりますか?”

パスワードルール(MPasswordRule)が定義されている場合、beforeSave()pwdrule.validate() で長さ・文字種・過去パスワードの再利用を検証します。検証に通ると DatePasswordChanged が現在時刻で更新され、afterSave() がパスワード履歴(AD_Password_History)を保存します。

Q. 営業活動の「完成」チェックは何に使いますか?

Section titled “Q. 営業活動の「完成」チェックは何に使いますか?”

IsComplete は活動の完了フラグです。未完了のタスクだけを抽出する等の絞り込みに使用します。チェックしても活動レコードが読み取り専用になるわけではありません。

Q. 営業活動を後から案件に紐付けられますか?

Section titled “Q. 営業活動を後から案件に紐付けられますか?”

できます。営業活動タブの「営業案件」を後から選択して保存してください。なお、見込顧客の変換プロセス(ConvertLead)を実行すると、その担当者に紐づく有効な営業活動がすべて新規作成された営業案件へ自動的に付け替えられます。

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

得意先(顧客)の担当者はマスタデータ型のウィンドウ(AD_Window_ID: 53152)で、ヘッダーは AD_User、子タブは C_ContactActivity テーブルに格納されます。モデルクラスは MUser(1,193行)で、生成クラス X_AD_User を継承します。C_ContactActivity には手書きモデルクラスがなく、生成クラス X_C_ContactActivity(364行)とインターフェース I_C_ContactActivity のみが提供されています。いずれも Document 型ではありません。

テーブル属性: AD_User はアクセスレベル 7(すべて)・削除可・大量データ扱い(IsHighVolume=YC_ContactActivity はアクセスレベル 3(クライアント+組織)・削除可です。

📌 ポイント: AD_UserIsHighVolume=Y のため、ウィンドウを開いた際に全件が自動ロードされず検索ダイアログが先に表示されます。担当者が増えても画面応答が劣化しにくい設計です。

classDiagram
    class MUser {
        +get(int) MUser
        +get(Properties, int) MUser
        +get(Properties, String, String) MUser
        +getCopy(Properties, int, String) MUser
        +isEMailValid() boolean
        #beforeSave(boolean) boolean
        #afterSave(boolean, boolean) boolean
    }
    class X_AD_User {
        <<generated>>
    }
    class X_C_ContactActivity {
        <<generated>>
    }
    class PO {
        <<abstract>>
    }
    MUser --|> X_AD_User
    X_AD_User --|> PO
    X_C_ContactActivity --|> PO
    MUser --> X_C_ContactActivity : has many
    MUser --> MBPartner : belongs to
    X_C_ContactActivity --> MOpportunity : linked to

+get(int) MUser +get(Properties, int) MUser +get(Properties, String, String) MUser +getCopy(Properties, int, String) MUser +isEMailValid() boolean #beforeSave(boolean) boolean #afterSave(boolean, boolean) boolean <> <> > X_AD_User X_AD_User --

パッケージ: org.compiere.model ソースファイル: org.adempiere.base/src/org/compiere/model/MUser.java(子タブ: X_C_ContactActivity.java / I_C_ContactActivity.java

AD_User(ユーザー/担当者)主要カラム

Section titled “AD_User(ユーザー/担当者)主要カラム”
カラム名必須説明備考
AD_User_IDIDYユーザーID主キー
AD_Client_IDTable DirectYクライアント既定値 @#AD_Client_ID@
AD_Org_IDTable DirectY組織既定値 @AD_Org_ID@
NameString(60)Y名称パスワード設定時は一意性検証あり
ValueString(40)N検索キーbeforeSave() で再セット
C_BPartner_IDSearchN取引先
C_BPartner_Location_IDTable DirectN取引先住所
C_Job_IDTable DirectN役職
EMailString(60)NEメール形式検証あり
Phone / Phone2 / FaxString(40)N電話・電話2・FAX
TitleString(40)Nタイトル(肩書き)
BirthdayDateN生年月日
LastContactDateN最新履歴日
LastResultString(255)N最新履歴情報
CommentsText(2000)Nコメント
PasswordString(1024)Nパスワードハッシュ化対象
SaltString(32)Nソルトハッシュ用
DatePasswordChangedDate+TimeNパスワード変更日自動セット
EMailVerifyDateDate+TimeNメール検証日メール変更時にクリア
FailedLoginCountIntegerYログイン失敗回数既定値 0
IsLocked / IsExpiredYes-NoYロック/有効期限切れ既定値 'N' / N
IsSalesLead / IsVendorLeadYes-NoY見込顧客/仕入見込先Lead 画面で使用
カラム名必須説明備考
C_ContactActivity_IDIDY営業活動ID主キー
AD_Client_ID / AD_Org_IDTable DirectYクライアント/組織既定値 @#AD_Client_ID@ / @#AD_Org_ID@
AD_User_IDSearchNユーザー既定値 @AD_User_ID@
ContactActivityTypeList(10)Y営業活動タイプTA / EM / PC / ME
DescriptionString(255)Y説明必須
StartDateDate+TimeY開始日付既定値 @SQL=SELECT SYSDATE ...
EndDateDate+TimeN終了日付
SalesRep_IDTableN社内担当者既定値 @#SalesRep_ID@
C_Opportunity_IDTable DirectN営業案件既定値 @C_Opportunity_ID@
CommentsTextNコメント
IsCompleteYes-NoN完成
IsActiveYes-NoY有効既定値 Y

営業活動タイプの定数は X_C_ContactActivity に定義されています(AD_Reference_ID=53423)。

定数
CONTACTACTIVITYTYPE_EmailEM
CONTACTACTIVITYTYPE_MeetingME
CONTACTACTIVITYTYPE_PhoneCallPC
CONTACTACTIVITYTYPE_TaskTA
erDiagram
    C_BPartner ||--o{ AD_User : "contacts"
    C_BPartner_Location ||--o{ AD_User : "location"
    C_Job ||--o{ AD_User : "position"
    AD_User ||--o{ C_ContactActivity : "activities"
    C_Opportunity ||--o{ C_ContactActivity : "opportunity activities"
    AD_User ||--o{ AD_User_Roles : "roles"
    AD_User ||--o{ AD_Password_History : "password history"

opportunity activities password history

flowchart TD
    A["beforeSave(newRecord)"] --> B{"EMail が変更された?"}
    B -->|Yes| C["EMailVerifyDate を null に"]
    B -->|No| D
    C --> D{"EMail が非空かつ<br/>新規 or 変更?"}
    D -->|Yes| E{"isEMailValid()?"}
    E -->|No| F["InvalidEMailFormat<br/>→ return false"]
    E -->|Yes| G
    D -->|No| G["Value を再セット"]
    G --> H{"Password が設定済み?"}
    H -->|No| N["return true"]
    H -->|Yes| I{"USE_EMAIL_FOR_LOGIN?"}
    I -->|Yes| J["EMail 必須 +<br/>テナント内 EMail 一意チェック"]
    I -->|No| K["COALESCE(LDAPUser,Name)<br/>の一意チェック"]
    J --> L["MPasswordRule.validate()<br/>+ DatePasswordChanged 更新"]
    K --> L
    L --> M{"USER_PASSWORD_HASH?"}
    M -->|Yes| O["setPassword() でハッシュ化"]
    M -->|No| N
    O --> N

beforeSave(newRecord) EMail が変更された? EMailVerifyDate を null に EMail が非空かつ 新規 or 変更? isEMailValid()? InvalidEMailFormat → return false Value を再セット Password が設定済み? return true USE_EMAIL_FOR_LOGIN? EMail 必須 + テナント内 EMail 一意チェック COALESCE(LDAPUser,Name) の一意チェック MPasswordRule.validate() + DatePasswordChanged 更新 USER_PASSWORD_HASH? setPassword() でハッシュ化

主要なシステム設定(AD_SysConfig):

設定キー影響
USE_EMAIL_FOR_LOGINログイン ID にメールを使う。ON でメール必須+一意性検証
USER_PASSWORD_HASHパスワードをハッシュ化して保存する(IDEMPIERE-347)

パスワードが設定されており、かつ新規または変更された場合に、パスワードルールの再利用禁止日数(getDays_Reuse_Password())が 0 より大きければ MPasswordHistory レコードを保存します。ハッシュ化が無効な状態で履歴を保存すると、AD_Password_History に平文が残る可能性があるため log.severe() で警告が出力されます。

⚠️ 注意: パスワード履歴を利用する場合は、必ず USER_PASSWORD_HASH を有効にしてください。

MUser.get(int AD_User_ID) / MUser.get(Properties ctx, int AD_User_ID) が用意されており、コンテキストからの取得(MUser.get(ctx))、名前とパスワードによる認証取得(MUser.get(ctx, name, password) / SSO 版)もサポートされています。更新目的では getCopy(ctx, AD_User_ID, trxName) を使用してください。

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

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

AD_User / C_ContactActivity の各カラムには Callout(AD_Column.Callout)が定義されていません。独自の検証は Model Validator で追加します。

public class ContactValidator implements ModelValidator {
@Override
public int modelChange(PO po, int type) throws Exception {
if (po instanceof MUser && (type == TYPE_BEFORE_NEW || type == TYPE_BEFORE_CHANGE)) {
MUser user = (MUser) po;
// 例: 取引先に紐づく担当者はメールアドレスを必須にする
if (user.getC_BPartner_ID() > 0 && Util.isEmpty(user.getEMail()))
throw new AdempiereException("取引先担当者にはメールアドレスが必要です");
}
if (X_C_ContactActivity.Table_Name.equals(po.get_TableName()) && type == TYPE_BEFORE_NEW) {
// 例: 面談(ME)は終了日付を必須にする
}
return null;
}
@Override
public String docValidate(PO po, int timing) {
return null; // AD_User / C_ContactActivity は Document 型ではないため不要
}
}
プロセス名説明
Convert Lead(ConvertLead見込顧客を取引先・営業案件へ変換し、営業活動を案件へ付け替える。「見込顧客の担当者」画面のボタンから実行

担当者情報と営業活動履歴は、AD_User というシステムユーザーと共通のテーブルに載るため、権限設計とデータ品質の両立が重要になります。 必須項目の追加、メール配信基盤との連携、活動履歴の自動記録など、コア改変なしに拡張できます。

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

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