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
Money Care 7Money Care 7 

How to Update picklist value

Hi Guys
I am facing one challenge for long time .I have two object Account and Discount__c with lookup relationship ,Account object have a picklist filed with value LEAD and CUSTOMER.

Now i have created a account record with picklist value LEAD. my requirment is when i am going to create a record on discount__c object the picklist value which was LEAD is converted to CUSTOMER autometically.that mean the parent object which have have child record then it will happens.how to achieve this solution ?
 
Best Answer chosen by Money Care 7
Dhanya NDhanya N
Add delete event in trigger.

Add this in trigger:
if(trigger.isDelete && trigger.isAfter)
	objHandler.onAfterDelete(trigger.old);

Add this method in Class:
public void OnAfterInsert(list<Discount__c> lstDiscount) {
		
	set<Id> setOldAccountId = new set<Id>();
	for(Discount__c objDiscount : lstDiscount) {
	
		setOldAccountId.add(objDiscount.lookup_toAccount);
	}
	
	for(Account objAccount : [Select Id, picklist_field From Account Where Id IN: setOldAccountId]) {
		
		objAccount.picklist_field = 'LEAD';
		lstAccount.add(objAccount);
	}
	if(!lstAccount.isEmpty())
		update lstAccount;
}

 

All Answers

Lucian Mihai CiobanuLucian Mihai Ciobanu
You can acvieve this in multiple ways. My personal option is an AFTER INSERT trigger on  Discount__c, but you have other declarative methods like workflows or process builder.
Money Care 7Money Care 7
Hi @Lucian Mihai Ciobanu

Could you share some after insert trigger sample code...
Dhanya NDhanya N
Hi MoneyCare,

Refer below trigger and controller:

Trigger:
trigger DiscountTrigger on Discount__c (after insert) 
{
    DiscountHandler objHandler = new DiscountHandler();
   
    if(trigger.isInsert && trigger.isAfter)
    {
        objHandler.OnAfterInsert(trigger.new);
    }

}

Controller:
public with sharing class DiscountHandler 
{
    set<Id> setAccountId = new set<Id>();
	list<Account> lstAccount = new list<Account>();
  
    public void OnAfterInsert(list<Discount__c> lstDiscount) {
	
		for(Discount__c objDiscount : lstDiscount) {
		
			setAccountId.add(objDiscount.lookup_toAccount);
		}
		
		for(Account objAccount : [Select Id, picklist_field From Account Where Id IN: setAccountId]) {
			
			objAccount.picklist_field = 'CUSTOMER';
			lstAccount.add(objAccount);
		}
		if(!lstAccount.isEmpty())
			update lstAccount;
	}
	
}

Thanks,
Dhanya
mritzimritzi
trigger DiscountCheck on Discount__c(after insert) {
    List<Account> accountList = new List<Account>
    Set<Id> accountids = new Set<id>();
    for(Discount__c d:Trigger.new){
        if(d.lookupFieldApiName!='')
            accountids.add(d.lookupFieldApiName);
    }
    accountList = [Select id, picklistApiName From Account Where id IN: accountids AND picklistApiName='LEAD'];
    for(Account a:accountList)
        a.picklistApiName = 'CUSTOMER';
    update accountList;
}
please replace "lookupFieldApiName"  and "picklistApiName" with actual field api names.

Mark this as Best Answer, if this solves your problem.
Money Care 7Money Care 7
Hi @Mohammed Rizwan I have modified the code but its showing error like Error: Compile Error: unexpected token: 'Set' at line 5 column 4 trigger TypeCheck on Purchase_Order__c(after insert) { List accountList = new List Set accountids = new Set(); for(Purchase_Order__c d :Trigger.new){ if(d.Account_Lookup__c!='') accountids.add(d.Account_Lookup__c); } accountList = [Select id, Type From Account Where id IN: accountids AND Type='Prospect']; for(Account a:accountList) a.Type= 'Customer'; }
mritzimritzi
trigger DiscountCheck on Discount__c(after insert) {
    List<Account> accountList = new List<Account>();
    set<Id> accountids = new set<id>();
    for(Discount__c d:Trigger.new){
        if(d.Account_Lookup__c!='')
            accountids.add(d.Account_Lookup__c);
    }
    accountList = [Select id, Type From Account Where id IN: accountids AND Type='Prospect'];
    for(Account a:accountList)
        a.Type = 'Customer';
    update accountList;
}

 
Money Care 7Money Care 7
Thanks to All for quick reply.
what you all share is only working on new record creation.which is working fine  as per my requirment.

Problem is i have 3000 existing record in account object,i want to update all existing record  picklist value to CUSTOMER which account record have child record i mean Discount__c.how to achieve this .....


Thanks in advance
Dhanya NDhanya N
You can create a batch and run it once to update all existing records. 
Money Care 7Money Care 7
Okay.how to check which parent record have child record .could you share sample code...
Dhanya NDhanya N
Try this batch:
global with sharing class DiscountBatch implements Database.Batchable<sObject> {
    
    
    public Database.QueryLocator start(Database.BatchableContext BC) {
	
		String strQuery = 'Select Id, picklist_field from Account';
        return Database.getQueryLocator(strQuery); 
	}
	
	public void execute(Database.BatchableContext BC, List<Account> lstOfAccount) { 
		
		list<Account> lstAccountToUpdate = new list<Account>();
		for(Account objAccount : [Select Id, picklist_field, (Select Id From Discount__r limit 1) From Account Where Id IN: lstOfAccount]) {
		
			if(!objAccount.Discount__r.isEmpty()) {
				objAccount.picklist_field = 'CUSTOMER';
				lstAccountToUpdate.add(objAccount);
			}				
		}
		
		if(!lstAccountToUpdate.isEmpty())
			update lstAccountToUpdate;
	}
	
	public void finish(Database.BatchableContext BC) {
	
	
	}
}

 
Money Care 7Money Care 7
Hi @ Dhanya N

After modification its showing error

Error: Compile Error: Didn't understand relationship 'Discount__r' in FROM part of query call. If you are attempting to use a custom relationship, be sure to append the '__r' after the custom relationship name. Please reference your WSDL or the describe call for the appropriate names. at line 13 column 34
 
global with sharing class DiscountBatch implements Database.Batchable<sObject> {
    
    
    public Database.QueryLocator start(Database.BatchableContext BC) {
    
        String strQuery = 'Select Id,Type from Account';
        return Database.getQueryLocator(strQuery); 
    }
    
    public void execute(Database.BatchableContext BC, List<Account> lstOfAccount) { 
        
        list<Account> lstAccountToUpdate = new list<Account>();
        for(Account objAccount : [Select Id,Type,(Select Id From Discount__r limit 1) From Account Where Id IN: lstOfAccount]) {
        
            if(!objAccount.Discount__r.isEmpty()) {
                objAccount.Type = 'Customer';
                lstAccountToUpdate.add(objAccount);
            }               
        }
        
        if(!lstAccountToUpdate.isEmpty())
            update lstAccountToUpdate;
    }
    
    public void finish(Database.BatchableContext BC) {
    
    
    }
}

 
Dhanya NDhanya N
You have to find out correct child relationship name.
Refer this link for checking child relationship name: http://www.soliantconsulting.com/blog/2012/10/sfdc-best-practice-child-relationship-names 
Dhanya NDhanya N
Money Care,
Are you able to get child relationship name?
Money Care 7Money Care 7
Yes Dhanya N

How to write test class for above batch class....
Dhanya NDhanya N
Here is the Test class:
@isTest
private class DiscountBatch _Test {
    
    @isTest static void test_DiscountBatch () {
        
        

        Account objAccount = new Account(Name = 'Test-001', BillingState = 'AL');
        insert objAccount;
        system.assert(objAccount.Id != NULL);
		
		Discount__c objDiscount = new Discount__c)(Name = 'Test Discount');
		insert objDiscount;
		system.assert(objDiscount.Id != NULL);

        Test.startTest();

        DiscountBatch  batch = new DiscountBatch ();
        database.executeBatch(batch, 100);

        Test.stopTest();
		
		System.assertEquals('CUSTOMER', [Select picklist_field From Account Where Id =: objAccount.Id].picklist_field);
    } 
}

Refer this link for more information about Batch Test Class : https://developer.salesforce.com/docs/atlas.en-us.apex_workbook.meta/apex_workbook/apex_batch_2.htm
Money Care 7Money Care 7
Hi Dhanya N
 
public with sharing class DiscountHandler 
{
    set<Id> setAccountId = new set<Id>();
	list<Account> lstAccount = new list<Account>();
  
    public void OnAfterInsert(list<Discount__c> lstDiscount) {
	
		for(Discount__c objDiscount : lstDiscount) {
		
			setAccountId.add(objDiscount.lookup_toAccount);
		}
		
		for(Account objAccount : [Select Id, picklist_field From Account Where Id IN: setAccountId]) {
			
			objAccount.picklist_field = 'CUSTOMER';
			lstAccount.add(objAccount);
		}
		if(!lstAccount.isEmpty())
			update lstAccount;
	}
	
}
trigger DiscountTrigger on Discount__c (after insert) 
{
    DiscountHandler objHandler = new DiscountHandler();
   
    if(trigger.isInsert && trigger.isAfter)
    {
        objHandler.OnAfterInsert(trigger.new);
    }

}
This is working fine when child record created, parent record Account Type field autometically updated This is ok for inserting/creating record

for example i did delete the child record then parent record back to the post value "LEAD" autometically i mean how to implement backword process .



 
Dhanya NDhanya N
Add delete event in trigger.

Add this in trigger:
if(trigger.isDelete && trigger.isAfter)
	objHandler.onAfterDelete(trigger.old);

Add this method in Class:
public void OnAfterInsert(list<Discount__c> lstDiscount) {
		
	set<Id> setOldAccountId = new set<Id>();
	for(Discount__c objDiscount : lstDiscount) {
	
		setOldAccountId.add(objDiscount.lookup_toAccount);
	}
	
	for(Account objAccount : [Select Id, picklist_field From Account Where Id IN: setOldAccountId]) {
		
		objAccount.picklist_field = 'LEAD';
		lstAccount.add(objAccount);
	}
	if(!lstAccount.isEmpty())
		update lstAccount;
}

 
This was selected as the best answer
Money Care 7Money Care 7

@isTest private class PicklistHandlerTestMethod
{
    static testMethod void TestPicklistHandler()
    {
        
   
    account a=new account(name='test',Region__c='East', Type='Prospect');
        insert a;
               Test.startTest();
        update a;
        Test.stopTest();
       
        
        Master_Product__c mp=new Master_Product__c(name='test name',Product_Code__c='c2');
        insert mp;
        
        contact c=new contact(firstname='Meenakshmi',lastname='Goswami',Designation__c='Developer',Accountid=a.id);
        insert c;


        Opportunity2__c op=new Opportunity2__c(Name='test1',Account__c=a.id,Master_Product__c=mp.id,Technical_Bid_date__c=date.Today(),Type_of_Business__c='Regular',Contact_Person__c=c.id);
        insert op;
        
        Opportunity_Product_Detail__c opd=new Opportunity_Product_Detail__c(Opportunity__c=op.id,Company__c=a.id,Quantity__c=10);
        insert opd;
        
        Quote__c qt=new Quote__c(Opportunity_Product_Detail__c=opd.id,Purpose_of_Sales__c='SEZ',Declaration_form_be_provided__c='No');
        insert qt;
        
       Purchase_Order__c sco=new Purchase_Order__c(Quote__c=qt.id,Opportunity__c=op.id, Company__c = a.id);
insert sco;
        Call_Up_Order__c cuo=new Call_Up_Order__c(name='test call up order',Quote__c=qt.id,Sale_Confirmation_Order__c=sco.id,Call_Up_Quantity__c=1);
        insert cuo;
        
        Invoice_Dispatch_details__c idd=new Invoice_Dispatch_details__c(Call_Up_Order__c=cuo.id,Purchase_Order__c=sco.id, Account_Lookup__c=a.id);
        insert idd;
        
        op.Approved_Artwork_Received__c=false;
        update op;
        
        
       
    }
    
    
    static testMethod void TestPicklistHandler1()
    {
        
        
        
          account a=new account(name='test',Region__c='East', Type='Customer');             
            insert a;
      
       
        
        Master_Product__c mp=new Master_Product__c(name='test name',Product_Code__c='c2');
        insert mp;
        
        contact c=new contact(firstname='Meenakshmi',lastname='Goswami',Designation__c='Developer',Accountid=a.id);
        insert c;


        Opportunity2__c op=new Opportunity2__c(Name='test1',Account__c=a.id,Master_Product__c=mp.id,Technical_Bid_date__c=date.Today(),Type_of_Business__c='Regular',Contact_Person__c=c.id);
        insert op;
        
        Opportunity_Product_Detail__c opd=new Opportunity_Product_Detail__c(Opportunity__c=op.id,Company__c=a.id,Quantity__c=10);
        insert opd;
        
        Quote__c qt=new Quote__c(Opportunity_Product_Detail__c=opd.id,Purpose_of_Sales__c='SEZ',Declaration_form_be_provided__c='No');
        insert qt;
        
       Purchase_Order__c sco=new Purchase_Order__c(Quote__c=qt.id,Opportunity__c=op.id, Company__c = a.id);
insert sco;
  Test.startTest();
              
delete a;
Test.stopTest();
        Call_Up_Order__c cuo=new Call_Up_Order__c(name='test call up order',Quote__c=qt.id,Sale_Confirmation_Order__c=sco.id,Call_Up_Quantity__c=1);
        insert cuo;
        
        Invoice_Dispatch_details__c idd=new Invoice_Dispatch_details__c(Call_Up_Order__c=cuo.id,Purchase_Order__c=sco.id, Account_Lookup__c=a.id);
        insert idd;
        
        op.Approved_Artwork_Received__c=false;
        update op;
        
        
       
    }
}
This will be showing this error in test class
Error MessageSystem.DmlException: Insert failed. First exception on row 0; first error: ENTITY_IS_DELETED, entity is deleted: []
 
Money Care 7Money Care 7
Hi @Dhanya N

I have created and modified the handler class and trigger which is working in sandbox properly.but in production some user facing this type of issue

Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, TypeCheck: execution of AfterInsert caused by: System.DmlException: Update failed. First exception on row 0 with id 0019000000uJACTAA4; first error: INSUFFICIENT_ACCESS_OR_READONLY, insufficient access rights on object id: [] Class.PicklistHandler.OnAfterInsert: line 21, column 1 Trigger.TypeCheck: line 7, column 1: []

How to achieve this issue,anybody have idea.
 
public with sharing class PicklistHandler 
{
    set<Id> setAccountId = new set<Id>();
    list<Account> lstAccount = new list<Account>();
  
    public void OnAfterInsert(list<Purchase_Order__c> lstDiscount) {
    
        for(Purchase_Order__c objDiscount : lstDiscount) {
        
            setAccountId.add(objDiscount.Company__c);
        }
        
        for(Account objAccount : [Select Id,Type From Account Where Id IN: setAccountId]) 
        {
            
            objAccount.Type = 'Customer';
            lstAccount.add(objAccount);
        }
        
       if(!lstAccount.isEmpty())
           update lstAccount;
    }
        
      public void onAfterDelete(list<Purchase_Order__c> lstDiscount) 
      {
    
        for(Purchase_Order__c objDiscount : lstDiscount) {
        
            setAccountId.add(objDiscount.Company__c);
        }
        
        for(Account objAccount : [Select Id,Type From Account Where Id IN: setAccountId]) 
        {
            
            objAccount.Type = 'Prospect';
            lstAccount.add(objAccount);
        }
        
        
        if(!lstAccount.isEmpty())
            update lstAccount;
    }
    
}
trigger TypeCheck on Purchase_Order__c(after insert , after delete) {

PicklistHandler objHandler = new PicklistHandler ();
   
    if(trigger.isInsert && trigger.isAfter)
    {
        objHandler.OnAfterInsert(trigger.new);
    }
    
    if(trigger.isDelete && trigger.isAfter)
    {
    objHandler.onAfterDelete(trigger.old);
    }

}


 
Dhanya NDhanya N
Check if that user's profile is having edit permission for that object and also to field.
Money Care 7Money Care 7
Yes .user have edit permission for Account object
Dhanya NDhanya N
Also check if that field Type is having Visible permission in Set Field-Level Security 
Money Care 7Money Care 7
Field Type having visible permission in Set Field-Level Security 
Dhanya NDhanya N
Is the custom object Purchase_Order__c is having Create permission?
 
Money Care 7Money Care 7
Yes ,this object have Edit,Read and Create Permission