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
mohamed Sufiyan 8mohamed Sufiyan 8 

Deactivate user and customer portal user from contact checkbox

I need to deactivate a  user and portal user by clicking checkbox in contact page. 
trigger activeuser on Contact (after update) {
    ID contactId = [Select contactid from User where id =:UserInfo.getUserId()].contactId; 
   
  for(Contact c : Trigger.new){
    if(c.isactive__c == true) 
            {             
        User u = [SELECT Id,ContactId,IsActive,IsPortalEnabled FROM User  WHERE contactId =:contactId ];
                
                 
                     u.CompanyName ='test';
                    u.IsActive=false;
                    u.IsPortalEnabled=false;
           Update u;

                }
            }
}

am getting error 
System.DmlException: Insert failed. First exception on row 0; first error: MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa)


any help..
Best Answer chosen by mohamed Sufiyan 8
Glyn Anderson (Slalom)Glyn Anderson (Slalom)
Mohamed,  Mixed DML happens when you try to do DML on certain "setup" objects, like User, Group and Profile, when you have already done DML on non-setup objects.  It's a security thing.  The usual solution is to do the User update asynchronously - i.e. in an @future method in a helper class.  The code below does this.  Please check my logic -- I am deactivating Users when the Contact.IsActive__c field is "false", while you were doing it when Contact.IsActive__c is "true".  I thought this might be a bug.  Also, in the future, be careful not to do DML inside of a for-loop, as your trigger is doing.  This is not best-practice and makes the trigger unable to process bulk updates.

<pre>
trigger ActiveUser on Contact ( after update )
{
    ContractTriggerHelper.deactivateUsers_future( Trigger.newMap.keySet() );
}

public class ContractTriggerHelper
{
    @future
    public static void deactivateUsers_future( List<Id> contactIds )
    {
        List<User> usersToUpdate = new List<User>();
        for ( User user :
            [   SELECT  Id, IsActive
                FROM    User
                WHERE   (   Contact.IsActive__c = false
                        AND ContactId IN :contactIds
                        AND IsActive = true
                        )
            ]
            )
        {
            user.IsActive = false;
            usersToUpdate.add( user );
        }
        update usersToUpdate;
    }
}
</pre>

All Answers

Glyn Anderson (Slalom)Glyn Anderson (Slalom)
Mohamed,  Mixed DML happens when you try to do DML on certain "setup" objects, like User, Group and Profile, when you have already done DML on non-setup objects.  It's a security thing.  The usual solution is to do the User update asynchronously - i.e. in an @future method in a helper class.  The code below does this.  Please check my logic -- I am deactivating Users when the Contact.IsActive__c field is "false", while you were doing it when Contact.IsActive__c is "true".  I thought this might be a bug.  Also, in the future, be careful not to do DML inside of a for-loop, as your trigger is doing.  This is not best-practice and makes the trigger unable to process bulk updates.

<pre>
trigger ActiveUser on Contact ( after update )
{
    ContractTriggerHelper.deactivateUsers_future( Trigger.newMap.keySet() );
}

public class ContractTriggerHelper
{
    @future
    public static void deactivateUsers_future( List<Id> contactIds )
    {
        List<User> usersToUpdate = new List<User>();
        for ( User user :
            [   SELECT  Id, IsActive
                FROM    User
                WHERE   (   Contact.IsActive__c = false
                        AND ContactId IN :contactIds
                        AND IsActive = true
                        )
            ]
            )
        {
            user.IsActive = false;
            usersToUpdate.add( user );
        }
        update usersToUpdate;
    }
}
</pre>
This was selected as the best answer
Raj VakatiRaj Vakati

DML operations on certain sObjects, sometimes referred to as setup objects, can’t be mixed with DML on other sObjects in the same transaction. This restriction exists because some sObjects affect the user’s access to records in the org. You must insert or update these types of sObjects in a different transaction to prevent operations from happening with incorrect access-level permissions. For example, you can’t update an account and a user role in a single transaction. However, deleting a DML operation has no restrictions. 

To Avoid the MIXED DML ERROR 
  1. Create a method that performs a DML operation on one type of sObject.
  2. Create a second method that uses the future annotation to manipulate a second sObject type.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_non_mix_sobjects.htm
mohamed Sufiyan 8mohamed Sufiyan 8
How to write test class for this .???
trigger CreateNewChangeRequest on Request__c (After Update) {

    JIRA_Triggers_Activation__c activateTriggers = JIRA_Triggers_Activation__c.getInstance();
    if ( activateTriggers.Activate_Triggers__c == TRUE ) {
    
        if(system.isFuture()) return;
        if(recursivecheck36.runOnce()){
            
        
          for(Request__c v :trigger.new)
          {
            if (trigger.isUpdate)
            { 
               ReqCallOut.updateCase(v.Id);
                break;
            }
          }      
        }
 
}



   @isTest
Public class Requesttest {
     @isTest(seeAllData=true)
    Public static  void createnew(){ 
        try{
                          Id chId ;
Test.StartTest();

       ReqCallOut.updateCase(chid);
        Test.StopTest(); 
        }Catch(Exception e){
            System.debug(' Requesttest Exception ' + e.getMessage());
        }
    }
Sandy123Sandy123
Hi. When excuting blow trigger and class getting error: Method does not exist or incorrect signature: void deactivateUsers(Set<Id>) from the type ContactTriggerHelper
trigger ActiveUser on Contact ( after update )
{     ContactTriggerHelper.deactivateUsers_future( Trigger.newMap.keySet() );
}

public class ContractTriggerHelper {    
@future  
  public static void deactivateUsers_future( List<Id> contactIds )  
  {         List<User> usersToUpdate = new List<User>();      
  for ( User user :             [   SELECT  Id, IsActive                 FROM    User                 WHERE   (   Contact.IsActive__c = false                         AND ContactId IN :contactIds                         AND IsActive = true                         )             ]             )    
    {            
user.IsActive = false;    
        usersToUpdate.add( user );  
      }      
  update usersToUpdate;  
  }
}