0

I am trying to update a custom object records based on standard User object.

Here are my conditions:

  1. If a New user is added then the Status of the ERP_SalesAgent__c (custom object)is set to Add.
  2. If Any Changes Happened on User in step1 then the ERP_SalesAgent__c's status is set to "Change".
  3. If User in Step1 is inactive then Status is set to "Delete". while testing the 3rd condition i am facing Mixed DML Operation exception. to avoid this I ran the update on User in Future class but no luck.

Here is my code:

public with sharing class InternalSalesAgent {
public static void ErpInternalSalesAgentRecord( list< User> newUsers )
    {
        set<Id>usersIdsSet = new set<Id>();
        set<string> erpCompanyNumbers = new set<String>();
        list<ERPSalesAgent__c> salesAgents = new list<ERPSalesAgent__c>();
        map< string, list< ERPSalesAgent__c > > erpRecordsMap = new  map< string, list< ERPSalesAgent__c > >( );
        map<string,User> Usermap = new map<string,User>();
        list<User>updateUsers = new list<User>();
        set<Id>UserIdsUpdate = new set<Id>();
        for(User usr:newUsers)
        {
            usersIdsSet.add(usr.Id);
            erpCompanyNumbers.add(usr.ERP_Company_Number__c);
            //System.debug('The new record is:+' +acc.Name);
        }
        for(ERPSalesAgent__c erpExternalAgents:[select id,User__c, Action__c, ERP_Company_Number__c,ERPSalesAgent_ID__c from ERPSalesAgent__c where User__c IN : usersIdsSet and ERP_Company_Number__c IN: erpCompanyNumbers])
        {
            list< ERPSalesAgent__c> erpagents = erpRecordsMap.get( erpExternalAgents.User__c + erpExternalAgents.ERP_Company_Number__c );
            if ( erpagents == null ) {
                erpagents = new list< ERPSalesAgent__c >( );
                erpRecordsMap.put( erpExternalAgents.User__c + erpExternalAgents.ERP_Company_Number__c , erpagents);
            }
            erpagents.add( erpExternalAgents );
        }
        for(User usrs:[select id,Name,ERP_Company_Number__c,IsSalesAgent__c,SalesAgent_ID__c,IsChange__c,IsActive from User where id IN:usersIdsSet and IsSalesAgent__c = true and ERP_Company_Number__c!=null])
        {

              System.debug('The new record is'+usrs);
               Usermap.put(usrs.id + usrs.ERP_Company_Number__c, usrs);
                if(usrs.SalesAgent_ID__c==null && (!erpRecordsMap.containsKey(usrs.Id + usrs.ERP_Company_Number__c) ||  erpRecordsMap.isEmpty() ) )
                {

                    ERPSalesAgent__c  erpagentsRecord = new ERPSalesAgent__c ();
                    erpagentsRecord.User__c = usrs.Id;
                    erpagentsRecord.Action__c = 'Add';
                    erpagentsRecord.ERP_Company_Number__c = usrs.ERP_Company_Number__c;
                    System.debug('The SalesAgent record is:' +erpagentsRecord.User__c);
                    salesAgents.add(erpagentsRecord);

                }
                else if(usrs.SalesAgent_ID__c!=null && erpRecordsMap.containsKey(usrs.Id + usrs.ERP_Company_Number__c) && usrs.IsChange__c && usrs.IsActive)
                {
                    UserIdsUpdate.add(usrs.Id);
                 for(ERPSalesAgent__c erpagentsRecord1 :erpRecordsMap.get(usrs.Id + usrs.ERP_Company_Number__c))
                 {
                    erpagentsRecord1.Action__c = 'Change';
                     salesAgents.add(erpagentsRecord1);
                 }
                 //comment them   
             /* User updtUsers = new User(Id=usrs.Id,IsChange__c = false);
              updateUsers.add( updtUsers );
                    UserIdsUpdate.add(usrs.Id);*/

                }
                else if(usrs.SalesAgent_ID__c!=null && erpRecordsMap.containsKey(usrs.Id + usrs.ERP_Company_Number__c) && !usrs.IsActive)
                {
                    UserIdsUpdate.add(usrs.Id);
                    System.debug('The Inactive SalesAgent is:'+usrs);
                 for(ERPSalesAgent__c erpagentsRecord2 :erpRecordsMap.get(usrs.Id + usrs.ERP_Company_Number__c))
                 {
                    erpagentsRecord2.Action__c = 'Delete';
                     salesAgents.add(erpagentsRecord2);
                 }
                   //comment them 
              /*User updtUsers1 = new User(Id=usrs.Id,IsChange__c = false);
              updateUsers.add( updtUsers1 );
                    UserIdsUpdate.add(usrs.Id);*/

                }



        }

        if(salesAgents.isEmpty())
            return;
        update salesAgents;
      //  if(UserIdsUpdate.isEmpty())
          //  return;
       UserHandler.UpdateUsers(UserIdsUpdate);
       // isRecursive = false;
       // update updateUsers;
        //isRecursive = true;

    }


}

public with sharing class UserHandler {
    @future
    public static void UpdateUsers(set<Id>UserIdsUpdate){
     List<User>newUsers = new List<User>();
     for(Id userIds:UserIdsUpdate)
     {

         newUsers.add(new User(Id = userIds,IsChange__c=false));
     }
        update newUsers;
}
}
0

I figured out the solution. Here it is:

You can't perform a DML operation on a setup and a non-setup operation in a single class or trigger. In the above situation User is a setup object and ERPSalesAgent is a non-setup object.

The solution is I have changed the operation on setup object to where it's now in the normal call and the non-setup operation has been moved into a call to an @future class. That seems to work without any errors.

  • User is not a "setup" object. I think you'll find the reason for your problem is that your class was on User, thus the reason the DML needed to be performed within the class. ERPSalesAgent is a derivative of User, as in it's a child or has a look-up relationship of some kind to User, and as such, could be moved to the @future method since User needed to be updated first. – crmprogdev Jun 21 '15 at 15:36
  • Also, this answer is more or less technically inaccurate. You can't mix setup and non-setup DML within the same transaction, no matter how many classes or triggers are involved. Future spawns a separate transaction. – sfdcfox Jun 21 '15 at 17:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.