本記事の内容
- 応募者レコードを作成した時、応募者番号を自動で採番する処理
- カスタム設定の作成
- Apexクラスの実装
全体像
★採用アプリ範囲
★社員管理アプリ範囲
カスタム設定関連の設定
★カスタム設定を作成
- 設定アイコン押下
- クイック検索で「カスタム設定」と検索し、カスタム設定を選択
- 新規ボタン押下
- 下記内容で作成
★カスタム設定のカスタム項目を作成
★カスタム設定のレコードを作成
- 設定アイコン押下
- クイック検索で「カスタム設定」と検索し、カスタム設定を選択
- 一覧から「自動採番インデックス」を選択
- 「Manage」ボタン押下
- 新規ボタン押下
- 下記内容でレコードを作成
実装するApexクラス一覧
Constants.cls
public class Constants {
/**
* 応募者
*/
/** オブジェクト名 */
public static final String APPLICANT_OBJECT = 'Applicant__c';
/** レコードタイプ */
public static final String APPLICANT_RECORDTYPE_NEWGRADUATE = 'RecordType_NewGraduate';
public static final String APPLICANT_RECORDTYPE_MIDCAREER = 'RecordType_MidCareer';
}
public class Constants {
/**
* トリガ種別
*/
public static final String TRIGGER_TIMING_BEFORE = 'before';
public static final String TRIGGER_TIMING_AFTER = 'after';
public static final String TRIGGER_TYPE_INSERT = 'insert';
public static final String TRIGGER_TYPE_UPDATE = 'update';
public static final String TRIGGER_TYPE_DELETE = 'delete';
public static final String TRIGGER_TYPE_UNDELETE = 'undelete';
/** 処理種別 */
public static final String CUSTOMMETA_PROCESSCATEGORY_COPY = 'コピー';
public static final String CUSTOMMETA_PROCESSCATEGORY_INSERT = '作成';
public static final String CUSTOMMETA_PROCESSCATEGORY_UPDATE = '更新';
public static final String CUSTOMMETA_PROCESSCATEGORY_CHECK = 'チェック';
public static final String CUSTOMMETA_PROCESSCATEGORY_SUM = '集計';
public static final String CUSTOMMETA_PROCESSCATEGORY_SET = 'セット';
public static final String CUSTOMMETA_PROCESSCATEGORY_SERIAL = '連番';
/**
* ひらがな・カタカナ変換用
*/
public static final Integer CONVERT_DIFFERENCE_NUM = 96; // ひらがな・カタカナ間のUnicode値の差
public static final Integer CONVERT_HIRAGANA_START_CODE = 12353;
public static final Integer CONVERT_HIRAGANA_END_CODE = 12438;
public static final Integer CONVERT_KATAKANA_START_CODE = 12449;
public static final Integer CONVERT_KATAKANA_END_CODE = 12534;
/**
* 応募者
*/
/** オブジェクト名 */
public static final String APPLICANT_OBJECT = 'Applicant__c';
/** レコードタイプ */
public static final String APPLICANT_RECORDTYPE_NEWGRADUATE = 'RecordType_NewGraduate';
public static final String APPLICANT_RECORDTYPE_MIDCAREER = 'RecordType_MidCareer';
}
CommonMethod.cls
public class CommonMethod {
/**
* レコードタイプ名からレコードタイプIDを取得
* @param objName オブジェクト名
* @param rtName レコードタイプ名
* @return rtId レコードタイプID
*/
public static Id getRecordTypeId(String objName, String rtName) {
Schema.DescribeSObjectResult so = Schema.getGlobalDescribe().get(objName).getDescribe();
List<Schema.RecordTypeInfo> rtList = so.getRecordTypeInfos();
Id rtId = null;
for (Schema.RecordTypeInfo rt : rtList) {
if (rt.getDeveloperName().equals(rtName)) {
rtId = rt.getRecordTypeId();
break;
}
}
return rtId;
}
/**
* 会計年度を考慮した今年度を取得
* @return currentYear
*/
public static String getCurrentYear() {
// 組織の会計年度開始月を取得
Organization org = [SELECT
FiscalYearStartMonth
FROM
Organization
WHERE
id = :UserInfo.getOrganizationId()];
String currentYear = ''; // 今年度
Date today = Date.today(); // 本日
// 今月が会計年度開始月より大きい場合
if (today.month() >= org.FiscalYearStartMonth) {
currentYear = String.valueOf(today.year());
// 今月が会計年度開始月より小さい場合
} else {
currentYear = String.valueOf(today.year() - 1);
}
return currentYear;
}
ApplicantTrigger.trigger
trigger ApplicantTrigger on Applicant__c (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
// スキップユーザを指定
String skipUserName = SkipUserFlg__c.getOrgDefaults().ApplicantTrgSkipUser__c;
if (!String.isBlank(skipUserName) && UserInfo.getUserName().equals(skipUserName)) return;
new ApplicantHandler().run();
}
ApplicantHandler.cls
public class ApplicantHandler extends TriggerHandler {
private static boolean firstRunBeforeInsert = true;
private static boolean firstRunBeforeUpdate = true;
private static boolean firstRunBeforeDelete = true;
private static boolean firstRunAfterInsert = true;
private static boolean firstRunAfterUpdate = true;
private static boolean firstRunAfterDelete = true;
private static boolean firstRunAfterUnDelete = true;
private List<SObject> newList;
private List<SObject> oldList;
/**
* コンストラクタ
*/
public ApplicantHandler() {
this.newList = Trigger.new;
this.oldList = Trigger.old;
}
/** Before Insert */
public override void onBeforeInsert() {
// 2重起動防止
if (!firstRunBeforeInsert) return;
firstRunBeforeInsert = false;
ApplicantLogic logic = new ApplicantLogic(Constants.TRIGGER_TIMING_BEFORE, Constants.TRIGGER_TYPE_INSERT, this.newList);
logic.onBeforeInsert(this.newList);
}
/** Before Update */
public override void onBeforeUpdate() {
// 2重起動防止
if (!firstRunBeforeUpdate) return;
firstRunBeforeUpdate = false;
ApplicantLogic logic = new ApplicantLogic(Constants.TRIGGER_TIMING_BEFORE, Constants.TRIGGER_TYPE_UPDATE, this.newList);
logic.onBeforeUpdate(this.oldList, this.newList);
}
/** Before Delete */
public override void onBeforeDelete() {
// 2重起動防止
if (!firstRunBeforeDelete) return;
firstRunBeforeDelete = false;
}
/** After Insert */
public override void onAfterInsert() {
// 2重起動防止
if (!firstRunAfterInsert) return;
firstRunAfterInsert = false;
}
/** After Update */
public override void onAfterUpdate() {
// 2重起動防止
if (!firstRunAfterUpdate) return;
firstRunAfterUpdate = false;
}
/** After Delete */
public override void onAfterDelete() {
// 2重起動防止
if (!firstRunAfterDelete) return;
firstRunAfterDelete = false;
}
/** After UnDelete */
public override void onAfterUnDelete() {
// 2重起動防止
if (!firstRunAfterUnDelete) return;
firstRunAfterUnDelete = false;
}
}
ApplicantLogic.cls
public class ApplicantLogic {
String triggerType; // トリガ種別
ID newRtId; // レコードタイプ「新卒」
ID midRtId; // レコードタイプ「中途」
AutoNumberingIndex__c index; // 自動採番インデックス
/**
* コンストラクタ
*/
public ApplicantLogic(String triggerTiming, String triggerType, List<Applicant__c> newAppList) {
/** 共通 */
initCommonTrigger(triggerTiming, triggerType, newAppList);
/** Before */
if ((Constants.TRIGGER_TIMING_BEFORE.equals(triggerTiming) && Constants.TRIGGER_TYPE_INSERT.equals(triggerType))
|| (Constants.TRIGGER_TIMING_BEFORE.equals(triggerTiming) && Constants.TRIGGER_TYPE_UPDATE.equals(triggerType))) {
initBeforeTrigger(newAppList);
}
}
/**
* 共通初期処理
*/
private void initCommonTrigger(String triggerTiming, String triggerType, List<Applicant__c> newAppList) {
this.triggerType = triggerType;
this.newRtId = CommonMethod.getRecordTypeId(Constants.APPLICANT_OBJECT, Constants.APPLICANT_RECORDTYPE_NEWGRADUATE); // レコードタイプID取得:新卒
this.midRtId = CommonMethod.getRecordTypeId(Constants.APPLICANT_OBJECT, Constants.APPLICANT_RECORDTYPE_MIDCAREER); // レコードタイプID取得:中途
}
/**
* Beforeトリガ用初期処理
*/
private void initBeforeTrigger(List<Applicant__c> newAppList) { // END: 処理毎のカスタムメタデータ型Listを作成
this.index = new AutoNumberingIndex__c(); // カスタム設定「自動採番インデックス」を取得
this.index = AutoNumberingIndex__c.getInstance('Applicant');
}
/**
* Before Insert
*/
public void onBeforeInsert(List<Applicant__c> newAppList) {
for (Applicant__c newApp : newAppList) {
setApplicantDataLogic(null, newApp); // 応募者レコードに関する処理
}
update this.index; // 応募番号インデックスを更新
}
/**
* Before Update
*/
public void onBeforeUpdate(List<Applicant__c> oldAppList, List<Applicant__c> newAppList) {
for (Integer i = 0; i < newAppList.size(); i++) {
Applicant__c oldApp = oldAppList.get(i);
Applicant__c newApp = newAppList.get(i);
setApplicantDataLogic(oldApp, newApp); // 応募者レコードに関する処理
}
}
/**
* 応募者レコードに関する処理
* @param oldApp 更新前応募者レコード
* @param newApp 更新後応募者レコード
*/
private void setApplicantDataLogic(Applicant__c oldApp, Applicant__c newApp) {
/** Insert */
if (Constants.TRIGGER_TYPE_INSERT.equals(this.triggerType)) {
setAppNumber(newApp); // 応募番号自動採番
/** Update */
} else if (Constants.TRIGGER_TYPE_UPDATE.equals(this.triggerType)) {
}
/** Insert & Update */
}
/**
* 応募番号自動採番
* @param newApp 応募者レコード
*/
private void setAppNumber(Applicant__c newApp) {
Decimal appNum = this.index.Index__c; // インデックス取得
String year = CommonMethod.getCurrentYear(); // 今年度を取得
newApp.Name = year + String.valueOf(appNum.intValue()).leftPad(3, '0'); // 文字列に変換し、5桁まで左詰め
appNum += 1; // インデックスに「1」加算
this.index.Index__c = appNum; // 「1」加算した値をカスタム設定に設定
}
}
次回記事