function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
NeedhelpforsandyNeedhelpforsandy 

Update account record using trigger

Hi Team,
I am inserting the account records into the salesforce through another system.
for account record we have written code to generate the external ID of the records based on the i.e.First Name , Last Name and Primary Email.
if customer is inserting the same record with same 3 field values (i.e.First Name , Last Name and Primary Email) then these record should update the existing records only.
but now update operation is not working. only insert operation is working.
Kindly check below code of Handler Class:

=============Handler Class========Trigger EVENT : After Insert======
    
     public void Uniqueaccount(){
           
        list<Account> accToUpdate = new list<Account>(); 
        for(Account accountObj : newAccountList){
             
            Integer blankCount = 0;
            Account acc = accountObj.clone();
            acc.Id = accountObj.Id;
            if(!String.IsBlank(accountObj.FirstName)) {
                                          
                acc.SVC_ExternalCustomerId__c = accountObj.FirstName + '|';
            } else {  
               
                acc.SVC_ExternalCustomerId__c = '|';
                
                blankCount++;
            }            
            if(!String.IsBlank(accountObj.LastName )) {                
               
                acc.SVC_ExternalCustomerId__c = acc.SVC_ExternalCustomerId__c + accountObj.LastName + '|';
            } else {                
               
                acc.SVC_ExternalCustomerId__c = accountObj.SVC_ExternalCustomerId__c + '|';
                blankCount++;
            }            
            if(!String.IsBlank(accountObj.PersonEmail)){                
                
                acc.SVC_ExternalCustomerId__c = acc.SVC_ExternalCustomerId__c + accountObj.PersonEmail; 
            }
            else {                
                blankCount++;
            }   
           
            if(String.isNotBlank(accountObj.clearmdm__MDMStatus__c) &&
               accountObj.clearmdm__MDMStatus__c.equalsIgnoreCase('Merge Source')){                   
                  
                   acc.SVC_ExternalCustomerId__c = acc.SVC_ExternalCustomerId__c + '|' + accountObj.Id;
               }
            else if(blankCount > 0){
                acc.SVC_ExternalCustomerId__c = accountObj.SVC_ExternalCustomerId__c + '|' + accountObj.Id;
                acc.SVC_ExternalCustomerId__c = acc.SVC_ExternalCustomerId__c + '|' + accountObj.Id;
            }
            accToUpdate.add(acc);
            
        }
        try{
           
            update accToUpdate; 
            
        }
        Catch(DmlException e) {
            System.debug('An exception occurred:setCustomerUniqueKey** ' + e.getMessage());
        
        }
       
    }
MoonpieMoonpie
Hi Needhelpforsandy,

Could you kindly re-post all of that code by doing the following...

In your reply, click the <> button (highlighted below) at the top of your reply box.
User-added image

Then paste your code inside the popup text box.

User-added image

That will make it much easier to read and follow, and it will give your code line numbers that anyone helping can use for reference.
NeedhelpforsandyNeedhelpforsandy
=============Handler Class========Trigger EVENT : After Insert======
    
     public void Uniqueaccount(){
           
        list<Account> accToUpdate = new list<Account>(); 
        for(Account accountObj : newAccountList){
             
            Integer blankCount = 0;
            Account acc = accountObj.clone();
            acc.Id = accountObj.Id;
            if(!String.IsBlank(accountObj.FirstName)) {
                                          
                acc.SVC_ExternalCustomerId__c = accountObj.FirstName + '|';
            } else {  
               
                acc.SVC_ExternalCustomerId__c = '|';
                
                blankCount++;
            }            
            if(!String.IsBlank(accountObj.LastName )) {                
               
                acc.SVC_ExternalCustomerId__c = acc.SVC_ExternalCustomerId__c + accountObj.LastName + '|';
            } else {                
               
                acc.SVC_ExternalCustomerId__c = accountObj.SVC_ExternalCustomerId__c + '|';
                blankCount++;
            }            
            if(!String.IsBlank(accountObj.PersonEmail)){                
                
                acc.SVC_ExternalCustomerId__c = acc.SVC_ExternalCustomerId__c + accountObj.PersonEmail; 
            }
            else {                
                blankCount++;
            }   
           
            if(String.isNotBlank(accountObj.clearmdm__MDMStatus__c) &&
               accountObj.clearmdm__MDMStatus__c.equalsIgnoreCase('Merge Source')){                   
                  
                   acc.SVC_ExternalCustomerId__c = acc.SVC_ExternalCustomerId__c + '|' + accountObj.Id;
               }
            else if(blankCount > 0){
                acc.SVC_ExternalCustomerId__c = accountObj.SVC_ExternalCustomerId__c + '|' + accountObj.Id;
                acc.SVC_ExternalCustomerId__c = acc.SVC_ExternalCustomerId__c + '|' + accountObj.Id;
            }
            accToUpdate.add(acc);
            
        }
        try{
           
            update accToUpdate; 
            
        }
        Catch(DmlException e) {
            System.debug('An exception occurred:setCustomerUniqueKey** ' + e.getMessage());
        
        }
       
    }

Problem: Suppose i am inserting customer record where First Name: Test1 , Last Name : Acc and Primary Email : test1@mail.com.
then record would be inserted. and external id would be populated as per below code.
External ID: test1|Acc|test1@gmail.com.

But if i am inserting another record where also have First Name: Test1 , Last Name : Acc and Primary Email : test1@mail.com.
then this record should be updated to existing record. if it will create new record then external id would be populated same and it is unique so it will throw error.
So finally i don't want any error display, if any record where first name , last name, and primary email is same as existing record then existing record should be updated.
MoonpieMoonpie
Hi Needhelpforsandy,

1) You say "customer record" and talk about first & last name and email; but your code is looking at Accounts.  For clarification, please answer this question: When you say "customer record" are you talking about a Person Account?

2) I see a potential issue in the very first line of your posted code.  For clarification, please answer this question: Is it an Account trigger that calls this handler class?  If not, please tell what type of object record the trigger is on.

3) Regardless of the answers to those question, can you please show us the first lines of this helper class?  At least show the lines from the class name up to the first method (i.e., show any class variables).  I am asking because in Line 06 of the code you posted, you reference a variable called newAccountList that is not defined in any code that we can see.  So either A) you are leaving out some code that would be helpful for us to see, or B) that could be part of your problem - you are referencing a variable that does not exist.
 
NeedhelpforsandyNeedhelpforsandy
Hi Moonpie,

As per your above point :
1:- Yes, Customer record is Person Account.
2. Yes it is Account Trigger (After Insert).
3. For Point 3 please see below code of handler class:-
public class AccountTriggerHandler extends TriggerHandler  {
    
    // List to store incoming Account records
    public List<Account> newAccountList = new List<Account>();
    
    // Maps to store incoming old and new Account records map
    public Map<ID, Account> newAccountMap = new Map<ID, Account>();
    public Map<ID, Account> oldAccountMap = new Map<ID, Account>();
    Public User Usr = new User();
    Public  List<Preferred_Language_Locale_Mapping__mdt> pflMapList = new  
    List<Preferred_Language_Locale_Mapping__mdt>();
    Public List<DuplicateRule> duplicatRule = new List<DuplicateRule>();
    
    
    public static Boolean updateFlag = True;

Please help me out of this problem. If you need any more details please let us know.

Thanks,​​​​​​​
 
MoonpieMoonpie
Thank you for the clarifications and the additional code.  I now see that newAccountList is defined.

However, if this is all of the handler code, I do not see where you are actually handling the List of Accounts and the Maps that I assume are being passed in from the Account trigger.

(In other words, where are Trigger.new, Trigger.newMap, and Trigger.oldMap actually being received here?)
NeedhelpforsandyNeedhelpforsandy
After Insert Context in the below method in handler class.
/* This method is the overridder version of base class method.
* This method is called in the afterInsert context
*/     
    public override void afterInsert() {
        system.debug('before after insert trigger event');
       
        //Create ExternalCustomerId
        setCustomerUniqueKey();
       
    }
Trigger on Account object:
trigger AccTrigger on Account (before insert, after insert, before update, after update) {
    
    new SVC_AccountTriggerHandler().run();
}

Kindly let me know if you need any more info.
Thanks.
 
MoonpieMoonpie
Ok, this is more complex and/or advanced trigger framework than I am used to.  But let's see what we can do....

I don't know what trigger framework you are using, but it looks a lot like Kevin O'Hara's SFDC trigger framework (https://github.com/kevinohara80/sfdc-trigger-framework).

Assuming yours is that one or very close, notice in that framework there is handling of the Trigger.new list of objects that "tripped" the trigger:
User-added image
I see in your AccountTriggerHandler where you create maps and lists to hold the incoming lists of records, but I don't see where you are actually handing the Trigger.new, Trigger.oldMap or Trigger.newMap lists (similar to O'Hara's example above).

If you are handling them and you just haven't shared that part of your code, I apologize.  But - especially when trying to help determine problem sources and hopefully solve the issues - I do not like to assume anything.
(Just like if you told me your coffee maker was not working, unless you had told me up front that it was getting power, the first question I would ask is if it is plugged in.)
NeedhelpforsandyNeedhelpforsandy
Please see below code 
public AccountTriggerHandler() {
        
      
        newAccountList = Trigger.New;
        newAccountMap = (Map<ID, Account>)Trigger.NewMap;
        oldAccountMap = (Map<ID, Account>)Trigger.OldMap;
        Usr = [SELECT CanAutoMergeCustomers__c, Id FROM User WHERE Id = : UserInfo.getUserId()];
        pflMapList = [select id, Preferred_Locale__c, Preferred_Language__c from Preferred_Language_Locale_Mapping__mdt];
        duplicatRule = [SELECT Id FROM DuplicateRule WHERE DeveloperName =: Label.DuplicateRuleNameForInverseRule];
        
        
    }

Now please check it.
MoonpieMoonpie
If this new code is the constructor for your AccountTriggerHandler class, that looks like it should work (assuming your earlier code that defines these variables is still in place). 

But..

1) Looking through all of the previous code that you posted, I still do not see where any of that code is doing anything with newAccountMap or oldAccountMap..

The first code you posted is a method called Uniqueaccount(), and in it I see where it uses newAccountList.  However, your after insert code calls setCustomerUniqueKey(). I do not see where Uniqueaccount() is ever called.


2) I just noticed that in your trigger AccTrigger on Account code you are calling...
new SVC_AccountTriggerHandler().run();
But the handler class you shared the code for is called...
AccountTriggerHandler
If all of this is, in fact, your code as you are trying to run it, then the "chain of custody" is broken because you are not calling the correct class/method.

---
This is very confusing with all the different names.

It seems that you are either A) trying all sorts of different things left and right, and not naming things consistently in your attempts, or B) posting code that you've copied/pasted from different sources in trying to attempt to get this to work, or C) not sharing all of your code.  (I don't actually mean ALL of your code, but at least the class and method definitions, and the sections of code that manipulate the Account records that fire the trigger.)
MoonpieMoonpie
In an attempt at further clarification, here is what I have pieced together from all the code you have shared so far....

It appears to me that this is what you currently have in place

User-added image

NOTE: The red functions are called, but do not appear to be defined anywhere; and the orange functions are defined but do not appear to be called from anywhere.

It seems to me that - unless you have more code that you have not yet shared where other functions are defined and/or called - this might be what you are trying to do or need to do

User-added image