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
NevDevNevDev 

Trigger that creates a custom record if a checkbox is true

Hi guys,

I'm new to Apex and I am trying to create a trigger that creates a duplicate record called Section_2_Balance_Sheet on a Contacts record, if a checkbox called Joint_c is true. 

I have created a lookup field on the contact record which looks up to contacts. If this lookup field is populated I'd like this clients name to automatically populate the Client_c field in the Section_2_Balance_Sheet record.

Is this possible? 
Santosh Kumar 275Santosh Kumar 275
trigger createDup on <ObjectName>(after insert, after Update){
List<ObjectName> dupRecordList = new List<ObjectName>();
for(ObjectName ob : trigger.new){
     if(ob.Joint__c == true){
        dupRecordList.add(ob.deepClone());
     }
}
insert  dupRecordList ;
}

OR
trigger createDup on <ObjectName>(after insert, after Update){
List<ObjectName> dupRecordList = new List<ObjectName>();
for(ObjectName ob : trigger.new){
     if(ob.Joint__c == true){
        ObjectName dupRecord = new ObjectName(field1=ob.field1, field2 = ob.field2......so on)
        dupRecordList.add(dupRecord );
     }
}
insert  dupRecordList ;
}

 
NevDevNevDev
Thanks for this Santosh,

I seem to be running into an error, also, do I need to write some class before I migrate it from the Sandbox to production?

User-added image
Santosh Kumar 275Santosh Kumar 275
What is your object name on which you are writing the trigger?
Here remove "<>" bracket from line 1.
And whenever you are using any custom object or custom field it is appended with __c. 
NevDevNevDev
ok so I have removed "< >" but now I am getting this error

User-added image
NevDevNevDev
The custom object where the "Joint_c"checkbox is located is called Sheet_2_Balance_Sheet_c, which is related to the Contact object. The Contact object has a lookup field whic looks up Contacts. What I'm trying to achieve is that if I create a Sheet_2_Balance_Sheet_c record and Joint_c = true, then a Sheet_2_Balance_Sheet_c record is automatically created for the Lookup Contact.

So when I open the Contact record directly from the lookup field, then that record also has the same Sheet_2_Balance_Sheet_c record associated to it.
Santosh Kumar 275Santosh Kumar 275
I can't see your line no 5 but i tgink you missed a semi colon at the end.
NevDevNevDev
Sorry Santosh,

I'm getting this error now

Error: Compile Error: Invalid type: Section_2_Balance_Sheet at line 5 column 49
 
NevDevNevDev
User-added image
NevDevNevDev
Hi Santosh,

So I've managed to correct the issue, but the trigger is creating a duplicate record of the custom object within the same Contact record. What I was hoping to achieve was that it would create a duplicate record within the Contact record that is populating the Contact Lookup field. 
NevDevNevDev
I'd really appreciate any help that anyone can give me on this guys. It looks like we almost have it but it's just duplicating the record onto the wrong record. 
Pankaj_GanwaniPankaj_Ganwani
Hi Nevin,

I made some edits in the above code. Please update the lookup__c with the field api name which you have created as self lookup on Contact:
 
trigger Object_Update on section_2_Balance_Sheet__c(after insert, after Update){
List<section_2_Balance_Sheet__c> dupRecordList = new List<section_2_Balance_Sheet__c>();
List<section_2_Balance_Sheet__c> processedList = new List<section_2_Balance_Sheet__c>();
Set<Id> setConId = new Set<Id>();
for(section_2_Balance_Sheet__c ob : trigger.new){
     if(ob.Joint__c && ob.Client_balance_sheet__c!=NULL){
        setConId.add(ob.Client_balance_sheet__c);
		processedList.add(ob);
     }
}
map<Id,Contact> mapIdToContact = new Map<Id,Contact>([select Id, lookup__c from Contact where Id In : setConId and lookup__c!=NULL]);

for(section_2_Balance_Sheet__c ob : processedList)
{
	if(mapIdToContact.containskey(ob.Client_balance_sheet__c))
		section_2_Balance_Sheet__c objCloned = ob.Clone(false, true, false, false);
		objCloned.Client_balance_sheet__c = mapIdToContact.get(ob.Client_balance_sheet__c).lookup__c;
		dupRecordList.add(objCloned);
}
insert dupRecordList;
}

 
Santosh Kumar 275Santosh Kumar 275
Hi nevin,
Please try this code : 
trigger createDupReocrd on Section_2_Balance_Sheet__c (after insert, after update) {
    List<Contact> dupRecordlist = new List<Contact>();
    for(Section_2_Balance_Sheet__c ob: trigger.new){
        if(ob.Joint__c = true){
            Section_2_Balance_Sheet__c dupRecord = new Section_2_Balance_Sheet__c(
                                      ​id = ob.ContactLookup,Client_Balance_Sheet__c=ob.Client_Balance_Sheet__c);
            dupRecordlist.add(dupRecord);
        }
    }
    upsert dupRecordlist;
}
Instead of "ContactLookup"  in id = ob.ContactLookup use your Contact LookUp Name.
NevDevNevDev
Hi Pankaj,

I have tried your code but I receive the below error

User-added image
NevDevNevDev
Hi Santosh,

I have also tried yours but also receiving errors:

Error: Compile Error: expecting right curly bracket, found '&' at line 4 column 0

User-added image
Santosh Kumar 275Santosh Kumar 275
Hey why are you adding those "&nbsp" remove them.
trigger createDupReocrd on Section_2_Balance_Sheet__c (after insert, after update) {
    List<Contact> dupRecordlist = new List<Contact>();
    for(Section_2_Balance_Sheet__c ob: trigger.new){
		if(ob.Joint__c = true){
			Section_2_Balance_Sheet__c dupRecord = new Section_2_Balance_Sheet__c(id=ob.Spouse__c,Client_Balance_Sheet__c=ob.Client_Balance_Sheet__c);;
			dupRecordlist.add(dupRecord);
		}
    }
    upsert dupRecordlist;
}

Use this code.
NevDevNevDev
Sorry Santosh,

They all seemed to come across when I copied your code to my clipboard.

I'm getting the below error now. 
Error: Compile Error: Invalid field Spouse__c for SObject Section_2_Balance_Sheet__c at line 5 column 86

So this is what I am looking for 
  • I have renamed the Contact object as Client
  • Client record has a Lookup field to Client called Spouse_c
  • Custom object called Section_2_Balance_Sheet__c which is related to Client object
  • Inside the Section_2_Balance_Sheet__c I have created a custom checkbox called Joint_c.
  • If I create a Section_2_Balance_Sheet__c record and Joint_c = true then I want a Section_2_Balance_Sheet__c record to be created on the Spouse_c record.
Does that make any sense? 
 
Pankaj_GanwaniPankaj_Ganwani
Hi Nevin,

I just modified my above code. Please try with this:
 
trigger Object_Update on section_2_Balance_Sheet__c(after insert, after Update){
List<section_2_Balance_Sheet__c> dupRecordList = new List<section_2_Balance_Sheet__c>();
List<section_2_Balance_Sheet__c> processedList = new List<section_2_Balance_Sheet__c>();
Set<Id> setConId = new Set<Id>();
for(section_2_Balance_Sheet__c ob : trigger.new){
     if(ob.Joint__c && ob.Client_balance_sheet__c!=NULL){
        setConId.add(ob.Client_balance_sheet__c);
		processedList.add(ob);
     }
}
map<Id,Contact> mapIdToContact = new Map<Id,Contact>([select Id, spouse__c from Contact where Id In : setConId and spouse__c!=NULL]);

for(section_2_Balance_Sheet__c ob : processedList)
{
	if(mapIdToContact.containskey(ob.Client_balance_sheet__c))
		section_2_Balance_Sheet__c objCloned = ob.Clone(false, true, false, false);
		objCloned.put('Client_balance_sheet__c',mapIdToContact.get(ob.Client_balance_sheet__c).spouse__c);
		dupRecordList.add(objCloned);
}
insert dupRecordList;
}

 
NevDevNevDev

Error: Compile Error: Variable does not exist: objCloned at line 18 column 27
 
Pankaj_GanwaniPankaj_Ganwani
Hi,

Just forgot to wrap within braces:
 
trigger Object_Update on section_2_Balance_Sheet__c(after insert, after Update){
List<section_2_Balance_Sheet__c> dupRecordList = new List<section_2_Balance_Sheet__c>();
List<section_2_Balance_Sheet__c> processedList = new List<section_2_Balance_Sheet__c>();
Set<Id> setConId = new Set<Id>();
for(section_2_Balance_Sheet__c ob : trigger.new){
     if(ob.Joint__c && ob.Client_balance_sheet__c!=NULL){
        setConId.add(ob.Client_balance_sheet__c);
		processedList.add(ob);
     }
}
map<Id,Contact> mapIdToContact = new Map<Id,Contact>([select Id, spouse__c from Contact where Id In : setConId and spouse__c!=NULL]);

for(section_2_Balance_Sheet__c ob : processedList)
{
	if(mapIdToContact.containskey(ob.Client_balance_sheet__c))
{
		section_2_Balance_Sheet__c objCloned = ob.Clone(false, true, false, false);
		objCloned.put('Client_balance_sheet__c',mapIdToContact.get(ob.Client_balance_sheet__c).spouse__c);
		dupRecordList.add(objCloned);
}
}
insert dupRecordList;
}

 
NevDevNevDev
The trigger saved find but now I'm receiving an Error message when I try to save the record

User-added image
Pankaj_GanwaniPankaj_Ganwani
Got it, Trigger is going into recurssion. Please use below mentioned code. I made Joint__c to false while attaching the record with parent contact:
 
trigger Object_Update on section_2_Balance_Sheet__c(after insert, after Update){
List<section_2_Balance_Sheet__c> dupRecordList = new List<section_2_Balance_Sheet__c>();
List<section_2_Balance_Sheet__c> processedList = new List<section_2_Balance_Sheet__c>();
Set<Id> setConId = new Set<Id>();
for(section_2_Balance_Sheet__c ob : trigger.new){
     if(ob.Joint__c && ob.Client_balance_sheet__c!=NULL){
        setConId.add(ob.Client_balance_sheet__c);
		processedList.add(ob);
     }
}
map<Id,Contact> mapIdToContact = new Map<Id,Contact>([select Id, spouse__c from Contact where Id In : setConId and spouse__c!=NULL]);

for(section_2_Balance_Sheet__c ob : processedList)
{
	if(mapIdToContact.containskey(ob.Client_balance_sheet__c))
{
		section_2_Balance_Sheet__c objCloned = ob.Clone(false, true, false, false);
		objCloned.put('Client_balance_sheet__c',mapIdToContact.get(ob.Client_balance_sheet__c).spouse__c);
objCloned.put('Joint__c',false);
		dupRecordList.add(objCloned);
}
}
insert dupRecordList;
}

 
NevDevNevDev
Thanks Pankaj,

To deploy this, do I need to write a class?
Pankaj_GanwaniPankaj_Ganwani
Yes, you will have to write a test class for this.
NevDevNevDev
Are these straight forward? I've never written one before.
Pankaj_GanwaniPankaj_Ganwani
Please refer below mentioned link for creating test class:

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_qs_test.htm
NevDevNevDev
Also, one thing that I have spotted here. When I open the duplicate record the Joint_c checkbox = false. This needs to be true on both of the client related records. 
Pankaj_GanwaniPankaj_Ganwani
Okay, In that case you will have to write a recurssion handler to avoid the cycle of the self calling of trigger:

Handler:
trigger Object_Update on section_2_Balance_Sheet__c(after insert, after Update){
if(RecursionHandler.isrun)
{
List<section_2_Balance_Sheet__c> dupRecordList = new List<section_2_Balance_Sheet__c>();
List<section_2_Balance_Sheet__c> processedList = new List<section_2_Balance_Sheet__c>();
Set<Id> setConId = new Set<Id>();
for(section_2_Balance_Sheet__c ob : trigger.new){
     if(ob.Joint__c && ob.Client_balance_sheet__c!=NULL){
        setConId.add(ob.Client_balance_sheet__c);
		processedList.add(ob);
     }
}
map<Id,Contact> mapIdToContact = new Map<Id,Contact>([select Id, spouse__c from Contact where Id In : setConId and spouse__c!=NULL]);

for(section_2_Balance_Sheet__c ob : processedList)
{
	if(mapIdToContact.containskey(ob.Client_balance_sheet__c))
{
		section_2_Balance_Sheet__c objCloned = ob.Clone(false, true, false, false);
		objCloned.put('Client_balance_sheet__c',mapIdToContact.get(ob.Client_balance_sheet__c).spouse__c);
objCloned.put('Joint__c',false);
		dupRecordList.add(objCloned);
}
}
insert dupRecordList;
RecursionHandler.isrun = false;
}
}

Recursion Handler:
 
public class RecursionHandler
{
	public static Boolean isrun = true;
}

 
NevDevNevDev
Error: Compile Error: Variable does not exist: RecursionHandler.isrun at line 26 column 1
 
Pankaj_GanwaniPankaj_Ganwani
You will have to create RecursionHandler class in salesforce.
NevDevNevDev
Hi Pankaj,

Could you please help me with this final bit?

Do I just add the code you provided above into the trigger?

public class RecursionHandler
{
    public static Boolean isrun = true;
}
NevDevNevDev
Hi guys,

For some reason I am receoving the below error message on when I try and action this trigger. It was working fine, but now it will not work.

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger Object_Update_2 caused an unexpected exception, contact your administrator: Object_Update_2: execution of AfterInsert caused by: System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, Object_Update_2: maximum trigger depth exceeded Personal_Finances trigger event AfterInsert for [a013600000EgiJY] Personal_Finances trigger event AfterInsert for [a013600000EgiJZ] Personal_Finances trigger event AfterInsert for [a013600000EgiJa] Personal_Finances trigger event AfterInsert for [a013600000EgiJb] Personal_Finances trigger event AfterInsert for [a013600000EgiJc] Personal_Finances trigger event AfterInsert for [a013600000EgiJd] Personal_Finances trigger event AfterInsert for [a013600000EgiJe] Personal_Finances trigger event AfterInsert for [a013600000EgiJf] Personal_Finances trigger event AfterInsert for [a013600000EgiJg] Personal_Finances trigger event AfterInsert for [a013600000EgiJh] Personal_Finances trigger event AfterInsert for [a013600000EgiJi] Personal_Finances trigger event AfterInsert for [a013600000EgiJj] Personal_Finances trigger event AfterInsert for [a013600000EgiJk] Personal_Finances trigger event AfterInsert for [a013600000EgiJl] Personal_Finances trigger event AfterInsert for [a013600000EgiJm] Personal_Finances trigger event AfterInsert for [a013600000EgiJn]: []: Trigger.Object_Update_2: line 25, column 1