商談の役割にプライマリーをつける


さて、ベストアンサーが付くか。ちょっと疲れました。
今回はApex バッチです。

[How to update primary contact on opportunities by individual donors?](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000E06BkSAJ)

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); 
    }

}
```