How can i add Account on AccountContactRelation based on AccountHierarchy using Apex trigger

accountcontactrelationapextrigger

My goal :

  1. When creating new contact and we assign it to specific account , the Account should have specific role
    [![enter image description here][1]][1]

  2. when creating new Relationship , the new Account should be part of the existing Account hierarchy and have different role

Here's my trigger :

public with sharing  class C3S_TRG100_AccountContactHandler  extends C3S_TRG00_TriggerHandler {

private static final String CLASS_NAME = C3S_TRG100_AccountContactHandler.class.getName();
public  C3S_TRG100_AccountContactHandler(){}
public override void beforeInsert(){
    
    C3S_TRG100_AccountContactHandler.setAccountContactRelation(null,Trigger.New);
}

public override void beforeUpdate(){
    
    C3S_TRG100_AccountContactHandler.setAccountContactRelation((Map<Id, AccountContactRelation>) Trigger.oldMap, Trigger.new);
}



public static void setAccountContactRelation(Map<Id, AccountContactRelation> oldMapAccCont,List<AccountContactRelation> accscons) {
    for (AccountContactRelation accr: accscons) {
        List<Id> accountIds = New List<Id>();
            if(oldMapAccCont == null && accr == null){
                accr.Roles == 'PGM';
                accountIds.add(accr.Id);
            }else {
                AccountContactRelation oldAccCont = oldMapAccCont.get(accr.Id);
                
                if(oldAccCont.Roles == 'PGM'){
                    accr.addError('Theres already an account with this Role');
                }
            }
       
    }List<Account> AccList = [Select Parent.Parent.Parent.Parent.Parent.ParentId, Parent.Parent.Parent.Parent.ParentId, Parent.Parent.Parent.ParentId, Parent.Parent.ParentId, Parent.ParentId, ParentId From Account where Id In :accountIds ]
}

}

I'm stuck on how to do it , should it be in BeforeUpdate ? Should i use Map instead of List ?
[1]: https://i.stack.imgur.com/NYR8w.png

Best Answer

Solved, here's the trigger how it should look like :

public with sharing  class C3S_TRG_AccountContRelationHandler  extends C3S_TRG00_TriggerHandler {

    private static final String CLASS_NAME = C3S_TRG_AccountContRelationHandler.class.getName();

    public  C3S_TRG_AccountContRelationHandler(){}

    public override void beforeInsert(){
        C3S_TRG_AccountContRelationHandler.setAccountContactRelation(null,Trigger.New);
    }

    public override void beforeUpdate(){
        C3S_TRG_AccountContRelationHandler.setAccountContactRelation((Map<Id, AccountContactRelation>)Trigger.oldMap,Trigger.New);
    }

    public static void setAccountContactRelation(Map<Id, AccountContactRelation> oldMapAccCont,List<AccountContactRelation> accscons) {
        Set<Id> accountIds = New Set<Id>();
        Set<Id> ContactIds = New Set<Id>();
        List<AccountContactRelation> recordsToProcess = New List<AccountContactRelation>();

        for (AccountContactRelation AccContRelation: accscons) {
            if(AccContRelation.IsDirect == true){
                AccContRelation.Roles = C3S_UTI01_Constants.ROLE;    
            }

            ContactIds.add(AccContRelation.ContactId);
            accountIds.add(AccContRelation.AccountId);
            recordsToProcess.add(AccContRelation);
        }

        List<AccountContactRelation> existingRecords = [
            Select id, ContactId, AccountId , Roles
            FROM AccountContactRelation
            WHERE  Id !=: recordsToProcess
            AND ContactId =: ContactIds
        ];

        List<String> AccountHierarchy = new List<String>();

        // chaine des parents des contacts id
        List<Contact> Contacts = [Select Id, AccountId, Account.ParentId, Account.Parent.ParentId, Account.Parent.Parent.ParentId, Account.Parent.Parent.Parent.ParentId
            from Contact where id in :ContactIds];

        Map<Id, Id> ConMap = new Map<Id,ID>();

        for(Contact Cont : Contacts){
            Id ContAccountID = Cont.Account.Parent.Parent.Parent.ParentId;
            if(ContAccountID == null) ContAccountID = Cont.Account.Parent.Parent.ParentId;
            if(ContAccountID == null) ContAccountID = Cont.Account.Parent.ParentId;
            if(ContAccountID == null) ContAccountID = Cont.Account.ParentId;
            if(ContAccountID == null) ContAccountID = Cont.AccountId;
            ConMap.put(Cont.id, ContAccountID);
        }

        Account[] Accounts  = [Select Id, ParentId, Parent.ParentId, Parent.Parent.ParentId, Parent.Parent.Parent.ParentId from Account where id in :accountIds];

        Map<Id, Id> AccMap = new Map<Id,ID>();

        for(Account Acc : Accounts){
            Id AccountID = Acc.Parent.Parent.Parent.ParentId;
            if(AccountID == null) AccountID = Acc.Parent.Parent.ParentId;
            if(AccountID == null) AccountID = Acc.Parent.ParentId;
            if(AccountID == null) AccountID = Acc.ParentId;
            if(AccountID == null) AccountID =Acc.Id;
            AccMap.put(Acc.id, AccountID);
        }
         // Test if new accounts have Role Main Partner or if they are not part of Account Hierarchy of the contact's account
        For(AccountContactRelation junctionObj : accscons) {
            For(AccountContactRelation EveryExistingRecord : existingRecords) {
                If((EveryExistingRecord.Roles != null && junctionObj.Roles != null &&  junctionObj.Roles.contains(EveryExistingRecord.Roles) && junctionObj.Roles.contains(C3S_UTI01_Constants.ROLE)) && junctionObj.ContactId == EveryExistingRecord.ContactId  ) {
                    junctionObj.addError('Theres already account with this role');
                }else If(ConMap.get(junctionObj.ContactId) != AccMap.get(junctionObj.AccountId)){
                    junctionObj.addError('The account you selected isnt part of the primary Account Hierarchy');
                }
            }
        }
    }
}
Related Topic