元の質問 : 多対多リレーションの重複禁止
trigger BuyerCandidateTrigger on BuyerCandidate__c (before insert , before update) {
//https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000JdMxmSAF
//A主:Opportunity A従:BuyerCandidate__c B主:Account
//Set<Opportunity__c> productIds = new Set<Opportunity__c>();
//List<BuyerCandidate__c> ls = [SELECT CompanyName__c, Id, Name, Opportunity__c
//FROM BuyerCandidate__c
//WHERE Opportunity__c = :productIds]
//Map<Id, BuyerCandidate__c> m = new Map<Id, BuyerCandidate__c>(ls);
Map<String,BuyerCandidate__c> checkMap = new Map<String,BuyerCandidate__c>();
Set<Id> oppIdSet = new Set<Id>();
Boolean sw01 = true;
for (BuyerCandidate__c bc : Trigger.new){
String keyStringO = bc.Opportunity__c ;
String keyStringA = bc.Account__c;
String keyString = keyStringO + ':' + keyStringA;
BuyerCandidate__c keyObj = (BuyerCandidate__c) checkMap.Get(keyString);
if (keyObj == null) {
//同じものはない
checkMap.put(keyString,bc);
oppIdSet.add(bc.Opportunity__c);
} else {
//同じものがある
bc.addError('Error 1 : Name ' + bc.Name + 'で選択されている商談Id' + bc.Opportunity__c + 'と取引先Id' +bc.Account__c + 'が' + keyObj.Name + 'と重複しています。');
sw01 = false;
}
}//end of for loop
if(sw01 ) {
List<BuyerCandidate__c> bcList = [SELECT Id,Name,Opportunity__c,Account__c FROM BuyerCandidate__c WHERE Opportunity__c =: oppIdSet];
for (BuyerCandidate__c bc : bcList){
String keyStringO = bc.Opportunity__c ;
String keyStringA = bc.Account__c;
String keyString = keyStringO + ':' + keyStringA;
BuyerCandidate__c keyObj = (BuyerCandidate__c) checkMap.Get(keyString);
if (keyObj == null) {
//同じものはない
} else {
//同じものがある
bc.addError('Error 2 : Name ' + keyObj.Name + 'で選択されている商談Id' + keyObj.Opportunity__c + 'と取引先Id' +keyObj.Account__c + 'が' + bc.Name + 'と重複しています。');
}
}//end of for loop
}
}
テストクラス
@isTest
public class BuyerCandidateTrigger_test {
@isTest
public static void test01() {
//既に入力したデータに同じものがある。
Test.startTest();
Account acc = new Account();
acc.name = 'test';
insert acc;
Opportunity opp1 = new Opportunity();
opp1.Name = 'test 001';
opp1.StageName = 'Qualification';
opp1.CloseDate = Date.Today() + 10;
opp1.AccountId = acc.Id;
insert opp1;
BuyerCandidate__c bc1 = new BuyerCandidate__c();
bc1.Opportunity__c = opp1.Id;
bc1.Account__c = acc.Id;
insert bc1;
try {
BuyerCandidate__c bc2 = new BuyerCandidate__c();
bc2.Opportunity__c = opp1.Id;
bc2.Account__c = acc.Id;
insert bc2;
} catch (Exception e) {
System.debug('addError');
}
Test.stopTest();
}
@isTest
public static void test02() {
//同時に入力したデータに同じものがある。
Test.startTest();
Account acc = new Account();
acc.name = 'test';
insert acc;
Opportunity opp1 = new Opportunity();
opp1.Name = 'test 001';
opp1.StageName = 'Qualification';
opp1.CloseDate = Date.Today() + 10;
opp1.AccountId = acc.Id;
insert opp1;
List<BuyerCandidate__c> bcList = new List<BuyerCandidate__c>();
BuyerCandidate__c bc1 = new BuyerCandidate__c();
bc1.Opportunity__c = opp1.Id;
bc1.Account__c = acc.Id;
bcList.add( bc1);
BuyerCandidate__c bc2 = new BuyerCandidate__c();
bc2.Opportunity__c = opp1.Id;
bc2.Account__c = acc.Id;
bcList.add( bc2);
try {
insert bcList;
} catch (Exception e) {
System.debug('addError');
}
Test.stopTest();
}
@isTest
public static void test03() {
//重複なし
Test.startTest();
Account acc = new Account();
acc.name = 'test';
insert acc;
Opportunity opp1 = new Opportunity();
opp1.Name = 'test 001';
opp1.StageName = 'Qualification';
opp1.CloseDate = Date.Today() + 10;
opp1.AccountId = acc.Id;
insert opp1;
Opportunity opp2 = new Opportunity();
opp2.Name = 'test 002';
opp2.StageName = 'Qualification';
opp2.CloseDate = Date.Today() + 10;
opp2.AccountId = acc.Id;
insert opp2;
BuyerCandidate__c bc1 = new BuyerCandidate__c();
bc1.Opportunity__c = opp1.Id;
bc1.Account__c = acc.Id;
insert bc1;
try {
BuyerCandidate__c bc2 = new BuyerCandidate__c();
bc2.Opportunity__c = opp2.Id;
bc2.Account__c = acc.Id;
insert bc2;
} catch (Exception e) {
System.debug('addError');
}
Test.stopTest();
}
}