さて、ベストアンサーが付くか。ちょっと疲れました。
今回はApex バッチです。
How to update primary contact on opportunities by individual donors?
Apex
public class BAT_UpdateOpportunityContactRole implements Database.Batchable<sObject> {
public Database.QueryLocator start(Database.BatchableContext BC) {
// collect the batches of records or objects to be passed to execute
String query = 'Select Id,Name,AccountId, (Select IsPrimary,ContactId,OpportunityId From OpportunityContactRoles) From Opportunity';
return Database.getQueryLocator(query);
}
public void execute(Database.BatchableContext BC, List<Opportunity> oppList) {
System.debug('******** oppList ' + oppList);
// process each batch of records default size is 200
Set<Id> AccountIdSet = new Set<Id>();
Map<String,Id> OpportunityContactRolesMap = new Map<String,Id>();
//Map<Id,Opportunity> existOpportunityContactRoleMap = new Map<Id,Opportunity>();
for(Opportunity opp : oppList) {
if (opp.OpportunityContactRoles.size() > 0) {
Boolean IsPrimary = false;
for (OpportunityContactRole oppCR : opp.OpportunityContactRoles){
String mKey = (String)oppCR.OpportunityId + (String)oppCR.ContactId;
OpportunityContactRolesMap.put(mKey,oppCR.Id);
if (oppCR.IsPrimary){
IsPrimary = true;
break;
}//end of if
}//end of for
if (IsPrimary){
} else {
AccountIdSet.add(opp.AccountId);
//existOpportunityContactRoleMap.put(opp.Id,opp);
}
} else {
AccountIdSet.add(opp.AccountId);
}
}//end of for
List<OpportunityContactRole> insertOpportunityContactRoleList = new List<OpportunityContactRole>();
List<OpportunityContactRole> updateOpportunityContactRoleList = new List<OpportunityContactRole>();
System.debug('******** AccountIdSet ' + AccountIdSet);
if (AccountIdSet.size() >0) {
List<Contact> conList = [SELECT Id,AccountId,FirstName,LastName FROM Contact WHERE AccountId =: AccountIdSet ORDER BY AccountId];
System.debug('******** conList ' + conList);
Id keyAccountId = null;
List<Contact> conList2 = new List<Contact>();
Map<Id,List<Contact>> AccountMap = new Map<Id,List<Contact>>();
for( Contact con : conList){
if (keyAccountId == con.AccountId) {
conList2.add(con);
} else {
if (keyAccountId != null) AccountMap.put(keyAccountId,conList2);
keyAccountId = con.AccountId;
conList2 = new List<Contact>();
conList2.add(con);
}
}//end of for
AccountMap.put(keyAccountId,conList2);
Map<Id,Id> OpportunityContactMap = new Map<Id,Id>();
for(Opportunity opp : oppList) {
if (opp.AccountId != null){
List<Contact> conList3 = (List<Contact>)AccountMap.get(opp.AccountId);
for (Contact con : conList3){
if (opp.Name == con.FirstName + con.LastName ){
OpportunityContactMap.put(opp.Id,con.Id);
}
}// end of for
}
}//end of for
for(Id stId : OpportunityContactMap.keyset()) {
Id conId = (Id)OpportunityContactMap.get(stId);
if (conId != null){//<--
String mKey2 = (String)stId + (String)conId;
Id oppCRId = (Id)OpportunityContactRolesMap.get(mKey2);
if (oppCRId != null){
OpportunityContactRole oppCR3 = new OpportunityContactRole();
oppCR3.Id = oppCRId;
oppCR3.IsPrimary = true;
updateOpportunityContactRoleList.add(oppCR3);
} else {
Id conId2 = (Id)OpportunityContactMap.get(stId);
if (conId2 != null){
OpportunityContactRole oppCR2 = new OpportunityContactRole();
oppCR2.OpportunityId = stId;
oppCR2.ContactId = conId2;
oppCR2.IsPrimary = true;
insertOpportunityContactRoleList.add(oppCR2);
}
}
}
}//end of for
}
try {
System.debug('******** updateOpportunityContactRoleList.size() ' + updateOpportunityContactRoleList.size());
System.debug('******** insertOpportunityContactRoleList.size() ' + insertOpportunityContactRoleList.size());
if(updateOpportunityContactRoleList.size() > 0) update updateOpportunityContactRoleList;
if(insertOpportunityContactRoleList.size() > 0) insert insertOpportunityContactRoleList;
} catch(Exception e) {
System.debug(e);
}
}
public void finish(Database.BatchableContext BC) {
// execute any post-processing operations like sending email}
}
}
test code
@isTest
public class BAT_UpdateOpportunityContactRole_test {
private static testMethod void test01() {
Test.startTest();
Account acc = new Account();
acc.Name = 'Test 001';
insert acc;
Contact con = new Contact();
con.FirstName = 'ABC';
con.LastName = 'EFG';
con.AccountId = acc.Id;
insert con;
Opportunity opp = new Opportunity();
opp.Name = 'ABCEFG';
opp.AccountId = acc.Id;
opp.StageName = 'Prospecting';
opp.CloseDate = Date.Today() + 10;
insert opp;
OpportunityContactRole oppCR = new OpportunityContactRole();
oppCR.ContactId = con.Id;
oppCR.OpportunityId = opp.Id;
oppCR.IsPrimary = false;
insert oppCR;
System.debug('-------- BAT start ' );
BAT_UpdateOpportunityContactRole bat = new BAT_UpdateOpportunityContactRole();
ID jobId = Database.executeBatch(bat);
Test.stopTest();
List<OpportunityContactRole> ResultList = [SELECT IsPrimary From OpportunityContactRole WHERE ContactId =: con.Id AND OpportunityId =: opp.Id ];
System.debug('-------- ResultList ' + ResultList);
System.assertEquals(ResultList.size(), 1);
System.assertEquals(ResultList[0].IsPrimary, true);
}
private static testMethod void test02() {
Test.startTest();
Account acc = new Account();
acc.Name = 'Test 001';
insert acc;
Contact con = new Contact();
con.FirstName = 'ABC';
con.LastName = 'EFG';
con.AccountId = acc.Id;
insert con;
Opportunity opp = new Opportunity();
opp.Name = 'ABCEFG';
opp.AccountId = acc.Id;
opp.StageName = 'Prospecting';
opp.CloseDate = Date.Today() + 10;
insert opp;
OpportunityContactRole oppCR = new OpportunityContactRole();
oppCR.ContactId = con.Id;
oppCR.OpportunityId = opp.Id;
oppCR.IsPrimary = true;
insert oppCR;
System.debug('-------- BAT start ' );
BAT_UpdateOpportunityContactRole bat = new BAT_UpdateOpportunityContactRole();
ID jobId = Database.executeBatch(bat);
Test.stopTest();
List<OpportunityContactRole> ResultList = [SELECT IsPrimary From OpportunityContactRole WHERE ContactId =: con.Id AND OpportunityId =: opp.Id ];
System.debug('-------- ResultList ' + ResultList);
System.assertEquals(ResultList.size(), 1);
System.assertEquals(ResultList[0].IsPrimary, true);
}
private static testMethod void test03() {
Test.startTest();
Account acc = new Account();
acc.Name = 'Test 001';
insert acc;
Contact con = new Contact();
con.FirstName = 'ABC';
con.LastName = 'EFG';
con.AccountId = acc.Id;
insert con;
Opportunity opp = new Opportunity();
opp.Name = 'ABCEFG';
opp.AccountId = acc.Id;
opp.StageName = 'Prospecting';
opp.CloseDate = Date.Today() + 10;
insert opp;
//OpportunityContactRole oppCR = new OpportunityContactRole();
//oppCR.ContactId = con.Id;
//oppCR.OpportunityId = opp.Id;
//oppCR.IsPrimary = false;
//insert oppCR;
System.debug('-------- BAT start ' );
BAT_UpdateOpportunityContactRole bat = new BAT_UpdateOpportunityContactRole();
ID jobId = Database.executeBatch(bat);
Test.stopTest();
List<OpportunityContactRole> ResultList = [SELECT IsPrimary From OpportunityContactRole WHERE ContactId =: con.Id AND OpportunityId =: opp.Id ];
System.debug('-------- ResultList ' + ResultList);
System.assertEquals(ResultList.size(), 1);
System.assertEquals(ResultList[0].IsPrimary, true);
}
private static testMethod void test04() {
Test.startTest();
Account acc = new Account();
acc.Name = 'Test 001';
insert acc;
Contact con = new Contact();
con.FirstName = 'ABC';
con.LastName = 'Z';
con.AccountId = acc.Id;
insert con;
Opportunity opp = new Opportunity();
opp.Name = 'ABCEFG';
opp.AccountId = acc.Id;
opp.StageName = 'Prospecting';
opp.CloseDate = Date.Today() + 10;
insert opp;
OpportunityContactRole oppCR = new OpportunityContactRole();
oppCR.ContactId = con.Id;
oppCR.OpportunityId = opp.Id;
oppCR.IsPrimary = false;
insert oppCR;
Contact con2 = new Contact();
con2.FirstName = 'ABC';
con2.LastName = 'EFG';
con2.AccountId = acc.Id;
insert con2;
System.debug('-------- BAT start ' );
BAT_UpdateOpportunityContactRole bat = new BAT_UpdateOpportunityContactRole();
ID jobId = Database.executeBatch(bat);
Test.stopTest();
List<OpportunityContactRole> ResultList = [SELECT IsPrimary From OpportunityContactRole WHERE ContactId =: con2.Id AND OpportunityId =: opp.Id ];
System.debug('-------- ResultList ' + ResultList);
System.assertEquals(ResultList.size(), 1);
System.assertEquals(ResultList[0].IsPrimary, true);
}
}