36 Trigger Scenarios in Salesforce with Solution – Part 1


1. Write a trigger on Account, when an account is inserted, automatically account billing address should populate into the account shipping address.

When it comes to Account Billing and Shipping Address, we cannot directly enter the values to the field Address because the Address is split into Street, City, State, PostalCode, and Country. We are using ” before insert ” because we need to change the values of the account which is getting inserted. If we use ” after insert ” then the fields of the account we are inserting will become read-only and we will not be able to update that account. This is the reason we are using ” before insert “.

 

 

2. Write a trigger on the Account when the Account is updated check all opportunities related to the account. Update all Opportunities Stage to close lost if an opportunity created date is greater than 30 days from today and stage not equal to close won.

Here we have to update Account related Opportunities based on a condition which is mentioned above in Question. So here we are using ” after update ” because once the Account is updated we are not making changes for the Account which is getting updated instead we are making changes for its related Object Opportunity.

First, we have to get the Account Id’s of the Account which is getting updated in a Set<Id> and write a query to get that particular Account Id’s Opportunities, then loop the list of that opportunities and check for the condition given in question then change the values according to the question and also check for the mandatory fields to update in opportunity. Later update the list of Opportunities for which the changes have been applied by adding those to a separate list and updating that list.

 

3. Once an Account is inserted an email should go to the System Admin user with specified text below.

An account has been created and the name is “Account Name”.

From the above question, we can clearly come to the conclusion that Email has to be sent after the Account is Inserted, so we use “after insert “. When there is bulk insertion then we have to send a list of emails that is why we are using List<Messaging.SingleEmailMessage>. Since the Email has to be sent to System Administrator, we should first get the Email of the Admin using the query. Then we have to loop the Accounts which are getting inserted, then check whether the email id of the Admin is null or not before creating a mail to send. Later for each Account, we have to add a single mail because when each Account is added the System Admin should get an email. Then pass the required fields for sending mail add it to the List of mails and check if the list of emails is empty or not. After that, we are ready to send the list of emails. We can also check whether the mail is sent or not, if not sent you can also check the errors in the logs using the last ” if ” condition which I have written below code.

 

4. Once an Account will update then that Account will update with the total amount from All its Opportunities on the Account Level. The account field name would be ” Total Opportunity Amount “.

The first thing we have to see is which trigger to use ” before ” or ” after “,  here we have to update the Account itself again so we cannot use the ” after ” trigger because once the Accounts are updated the fields of the Account becomes ” read-only ” i.e, we will not be able to do changes to the Account data. So if we use ” before update ” then we will be able to make changes to the Account fields later it will get updated by default. This is the reason we are using ” before update “.

In the below code first, we are getting the list of Account Id’s  to get its related Opportunities. We have created a Map<Id,Double> where Id contains the Account Id and Double contains the sum of Amount of a particular Account’s related Opportunities so that it will be easy for us to insert the sum of amount according to the Account Id’s. Then we are getting the “Aggregate Result” i.e, we use this when we use sum or average in a query. We are putting all the data of the Aggregate Result to the Map which we have written before. Later we are looping the Accounts which are getting updated and check if that Account Id is there in Map, if it is there then we are changing the value of the ” Total Amount Opportunity ” field in Account.

 

 

5. Create a field on Account Named (Client Contact lookup to Contact). Once an Account is inserted a Contact will create with the name of the Account and that Contact will be the Client Contact on the Account.

Here we are using “after insert” because here the condition is first we should insert contact and then a related contact with the same name as account name, so to get the Account Id to make its related contact first the Account has to be inserted then only we will be able to get the Account Id. So we have to use ” after insert”.

We are looping the Accounts which are getting inserted and then also creating a Contact that has the same name as the Account and we are making it related to that particular Account only. Immediately after this, we are inserting those Contacts. Then we are getting the records of the inserted Account to put it into the Map<Id,Account> where Id contains Account Id and Account contains that particular Id’s records. After this, we are looping the inserted Contact and checking if the Contact’s Account Id is present in the Map. If present we are getting that particular Account’s record and given the Contact Id value to the field “Client Contact” of Account. Then we are adding it to a separate list to update it later. And finally, we are updating the Accounts for which the changes have been done.

 

6. Create a field on Opportunity Line item(Serial No (Text)) and populate increment values once an Opportunity Line Item is added. Let’s say if we add 3 products then the sequence would be “1,2,3”. Now if we delete 2 and again add one more product this must be 4 irrespective of the deleted sequence number.

The very first thing we have to do is create a field with the name “Serial No” of datatype “Text” in an “Opportunity Product” (also called as OpportunityLineItem). Later check whether there is “Product” on the related tab of “Opportunity”. So when you add a new “Product” in a particular Opportunity this Trigger is going to work. And also we will write a trigger on insert because the question tells on adding a product.

Here we are using “before insert” because when we add a new Product on a particular Opportunity then we also need to update the Serial No field of that particular OpportunityLineItem. And if we use ” after insert ” then the OpportunityLineItem field will become read-only and we will not be able to update that OpportunityLineItem.

In the below code we are getting all the OpportunityId in one Set so that we can get all the OpportunityLineItem of that particular Opportunity and the Serial No of that Opportunity Product. We are also using Map<Id, String> where Id contains OpportunityId and String contacts the new Serial No of that particular Opportunity Product. We are looping the OpportunityLineItem’s which we got through the query and checking if the Serial NO field is null, if it is null then we are making the Serial No field as 1. If not then we are getting the last number of the old value of the Serial No and converting it to Integer because we need to Increment it and append it. Then we are making chances in the Serial No field then adding the OpportunityLineItem to List so that we can update it later, and also adding the values to the Map. After this, we are updating the OpportunityLineItem’s which was previously present, and in which we made changes for the Serial No. Now the only thing left is changing the Serial No field of the newly inserting OpportunityLineItem, so we loop the inserting List of OpportunityLineItem check if its OpportunityId is present in Map, if present then get that Map values and place it to Serial No field else we are just passing 1 to that Serial No field.

Looking for part 2? – Trigger Scenarios Solution Part 2

If you didn’t go through the 36 Apex Triggers Scenarios in Salesforce Post Make sure to visit over there to check out the Trigger Scenarios
36 Trigger Scenarios in Salesforce

If you feel the solution can be optimized further please reach out to us.

Spread the love

Related Posts

35 thoughts on “36 Trigger Scenarios in Salesforce with Solution – Part 1

  1. How to write a trigger to update the field City, Street, Country, Postal Code in all related opportunities,
    when the same corresponding fields (from Billing Address) is updated in an account?

    1. Hi Harold,

      Write a Trigger on Account for after update and check if there is change in Billing Address of Account if yes then assign the updating Account Ids in a set. Then get all the Opportunities related to those Account Ids then loop all those opportunities and assign its particular account’s Billing address to those fields of Opportunity. Later update those Opportunities whose values are changing.

      Thank You.

  2. // could you please tell me why my code is not working

    I am new in Salesforce and I am trying to learn salesforce concepts

    Please tell me

    When Primary Contact is True then only selected Contact address is same as Account address

    trigger UpdateAddress on Contact (after update) {
    Set contactIds = new Set();
    for (Contact a : Trigger.new) {
    Contact old = Trigger.oldMap.get(a.Id);
    if (a.BillingStreet != old.BillingStreet || …) {
    contactIds.add(a.Id);
    }
    }
    if (contactIds.size() > 0) {
    Account[] updates = [
    select Id, AccountId
    from Account
    where AccountId in :contactIds
    ];
    for (Account c : updates) {
    Contact a = Trigger.newMap.get(c.ContactId);
    c.BillingStreet = a.BillingStreet;

    }
    update updates;
    }
    }

    1. Hi Rahul,
      In Your trigger you are getting the Contact Ids in “contactIds” variable and In the query your passing It for Account. And the query is Completely wrong because in Account there isn’t any field called AccountId. Check those again and re-write it.
      Thank You

    1. Write a “after update” trigger on Account and check if there is change in the Service Status. If there is change in Service Status field then get that particular Account Id and query its related List(Contact) and List(Case) make the changes you need and put both the records into a List(sObject) and later check if that list is not empty and then update that list.

  3. i want to write a trigger when an Account new record is created The industry is equal to Education It will Assign Another user The record owner get Changed

    1. Hi Vijaya,
      “The industry is equal to Education It will Assign Another user The record owner get Changed” does this mean that when ever you create a record and if the “Industry” field is “Education”. Then you want to change the record owner? And also tell me is there any condition while assigning the owner. Like the user profile has to be “System Administrator” or “Standard User”. Any conditions like this?

  4. trigger Tri_21_09_Acc_up_con_bill on Account (after update)
    {
    if(trigger.isafter && trigger.isupdate)
    {
    set accids=new set();

    List conlisttoupdate=new List();
    list acc=trigger.new;

    for(Account EACC:acc)
    {
    accids.add(EACC.Id);

    list conlist=[select Accountid,MailingAddress,MailingCity,MailingCountry,MailingPostalCode from contact where Accountid IN :accids];

    for(contact ECON:conlist)
    {

    if(ECON.MailingAddress==null)
    {
    ECON.MailingCity=EACC.BillingCity;
    ECON.MailingCountry=EACC.BillingCountry;
    ECON.MailingPostalCode=EACC.BillingPostalCode;
    conlisttoupdate.add(ECON);
    }
    }
    }
    update conlisttoupdate;

    }

    }

    1. Hi Balaji,
      The code you have written doesn’t work when you update more than 120 records because you have written the SOQL query inside the “for” loop. Which is not a best Practice.
      Thank You.

      1. Balaji Say
        @@@@ now it’s works ,I inserted 200 records Through data loader

        trigger Tri_21_09_Acc_up_con_bill on Account (after update)
        {
        if(trigger.isafter && trigger.isupdate)
        {
        set accids=new set();
        list conlist=[select Accountid,MailingAddress,MailingCity,MailingCountry,MailingPostalCode from contact where Accountid IN :accids];
        List conlisttoupdate=new List();
        list acc=trigger.new;

        for(Account EACC:acc)
        {
        accids.add(EACC.Id);

        for(contact ECON:conlist)
        {

        if(ECON.MailingAddress==null)
        {
        ECON.MailingCity=EACC.BillingCity;
        ECON.MailingCountry=EACC.BillingCountry;
        ECON.MailingPostalCode=EACC.BillingPostalCode;
        conlisttoupdate.add(ECON);
        }

        else if(ECON.MailingAddress != null)
        {
        ECON.MailingCity=EACC.BillingCity;
        ECON.MailingCountry=EACC.BillingCountry;
        ECON.MailingPostalCode=EACC.BillingPostalCode;
        conlisttoupdate.add(ECON);
        }
        }
        }
        if(conlisttoupdate.size()>0)
        {
        update conlisttoupdate;
        }
        }

        }

  5. trigger Tri_21_09_Acc_up_con_bill on Account (after update)
    {
    if(trigger.isafter && trigger.isupdate)
    {
    set accids=new set();
    list conlist=[select Accountid,MailingAddress,MailingCity,MailingCountry,MailingPostalCode from contact where Accountid IN :accids];
    List conlisttoupdate=new List();
    list acc=trigger.new;

    for(Account EACC:acc)
    {
    accids.add(EACC.Id);

    for(contact ECON:conlist)
    {

    if(ECON.MailingAddress==null)
    {
    ECON.MailingCity=EACC.BillingCity;
    ECON.MailingCountry=EACC.BillingCountry;
    ECON.MailingPostalCode=EACC.BillingPostalCode;
    conlisttoupdate.add(ECON);
    }

    else if(ECON.MailingAddress != null)
    {
    ECON.MailingCity=EACC.BillingCity;
    ECON.MailingCountry=EACC.BillingCountry;
    ECON.MailingPostalCode=EACC.BillingPostalCode;
    conlisttoupdate.add(ECON);
    }
    }
    }
    if(conlisttoupdate.size()>0)
    {
    update conlisttoupdate;
    }
    }

    }

    @@@@ I think now it will work i inserted 200 records from data loader i worked successfully……!

    1. Hi balaji,
      It still doesn’t work because you have not added any value inside the set “accids” so by default the list(Contact) will be null. Close the for loop after the line where your adding the values to set and put that SOQL query after that.
      Thank you

  6. Write a trigger on Opportunity when an account is update when Opportunity Stage Change send email to Client contacts of Opportunity Account that your Opportunity Stage has been change.
    Subject: Account Update Info
    Body : Your account information has been updated successfully.

    1. Hi Atish,

      A similar scenario is present in https://salesforcegeek.in/trigger-scenarios-in-salesforce-part-2/ the 6th Scenario in this part 2 you can also go through that just that you need to make minor changes. First create a trigger on Opportunity with “after update” and skip all the lines from the lines until line 16 of the previous told similar example replace OpportunityLineItem with Opportunity and OpportunityId with Id and in line 18 change the if condition to check if the Opportunity Stage field has changed and AccountId field is not null then remove the line 19 and rest remains the same and check the line 20 and line 23 to get the Opportunities Account Client Contact and change the Body and Subject accordingly. And another thing I hope the Client Contact is a Lookup field on Account. Check all this and any queries you can revert back here.

      Thank You.

  7. Create the field called “contact relationship” checkbox on the contact object and create the object called ”contact Relationship” which is related list to the contacts(Lookup relationship) . Now logic is when we create contact by checking contact relationship checkbox, then contact relationship will be created automatically for that Contact . ?

    1. Hi Raj,

      The logic is simple create a trigger on Contact with “after insert”. Now loop all the contact that are getting create using ” for(Contact c : Trigger.new) ” now write a ” if ” condition to check if the check box field is true the inside the if loop create a instance of Contact Relationship Object and make sure you assign values for mandatory fields then remember to assign the Contact Id to the contact lookup field on Contact Relationship. Add that instance to a List of Contact Relationship variable which would be defined out of all the if conditions and for loops. Now at the last check if this List of Contact Relationship variable is not null then inside the if condition insert that List of Contact Relationship variable. That is all you have to do. If you have any queries, you can revert back here.

      Thank You.

  8. Write a trigger – ABC firm wants to create the student record and relate that with contact records.

    Requirement Details:-

    Create 1 custom object Student with fields Name, Email id, phone number, DOB, Address,etc

    On creation of student record, check contact email id if it is present then create Student record related to contact.

    If not present, then create contact and relate student records to that contact.

    Send mail by using student email id to inform the joining date and courses.

    1. Hi PU ,

      As per your question write a trigger on Student Object with “after insert” and first thing you have to do is write a instance for Map(Email, Id) and write a query where you get the list of Contact with fields Id and Email where Email should not be null and loop those list and add its Email and Id for the Map(Email, Id) that you declared. Now loop all the Student records that are getting inserted and add a if condition if the email id of Student is present in map. If it is present then get the value of that particular Email (i.e. we have passed the contact Id to map as values) and assign it to the Student’s Contact lookup field. Now lets go for else part where the Email Id of Student is not present in the Map(Email, Id) write a new instance of Contact object assign required field values and also do not forget to assign the Student’s Email to Contact’s Email then add the instance to List of Contact variable. Now check if the List of Contact variable is empty or not and then insert the List of Contact. Now loop all the Contacts which you just inserted and add its email and Id to the Map(Email, Id) and now just copy paste the code of looping the students that is getting inserted just that do not write the else condition. And in the same loop write an instance for Messaging.SingleEmailMessage and write all the required things like Subject, Body according to the requirement and do not forget to set the toAddress as the Student’s Email Id and add the single instance of Messaging.SingleEmailMessage to List of Messaging.SingleEmailMessage Instance and check if the List of Messaging.SingleEmailMessage is not empty and Send the List of Messaging.SingleEmailMessage. For the Email part you can check the https://salesforcegeek.in/trigger-scenarios-in-salesforce-part-2/ 6th scenario. If you have doubts you can revert back here.

      Thank You.

    1. Hi Shaktivel,
      You can do this with different ways Validation Rules and also with Triggers. If you want with triggers then Lets consider 2 Objects namely Parent Object and Child Object (remember Child Object has a Look up or Master Detail relationship field with Parent Object). Create a Trigger on Child Object with “before insert”. First declare Map(Id, Id) in which you will pass the Id of Parent and Id of Child(remember the key should contain the Parent Id and value should contain the Child Id) . And write a List of Child Object whose Parent field is not null and loop all those and add the Parent Id and Id of child to Map(Id, Id). Now lets loop the Child records which is getting inserted add a if condition where you will check if the Child’s Parent Id is present in the Map(Id, Id) If it is present the lets show a error message during insertion using childVariableLooping.addError(‘Error Message’); where childVariableLooping is the child variable which is looping. If you have any queries you can revert back.

      Thank You.

    1. Hi Shivansh,

      In Map(Id,Double) I’m passing the Id of Account and its respective Opportunities Total amount as per the SOQl query written in line 12 which would give me the Id of the Account and its respected Opportunities Total Amount. Now in Map we have have different Methods (You can go through the document https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_methods_system_map.htm for different methods in Map). In that we also have a Method ” get(key) ” and you call it like this ” mapName.get(mapKey) “. In the Map that I have declared the Id is Key which will always be unique and Double is its respected values. Now with ” amountmap.get(acc.Id) ” I’ll get the value of the Account Id mentioned inside the get parameter, that is I’ll get the Account Id’s repected Total Amount. This is how I’m updating the Total Opportunity Value on Account’s field.

      Thank You.

    1. Hi Vinu,

      As per your question the trigger has to be written on opportunity and on “after create”. Then loop the Trigger.new Opportunities and get all its Account Ids and put it into the set of Id and then write a query for getting the Account list whose Id contains in the set of Id you created and then further make changes as of the requirement and update that list of account thats all. And one more thing if you are updating the account field with value of a opportunity field then try using map of Id and the datatype of the field where in Id field you will be saving the account Ids and in the values of map you will add the value which you want to update for that particular account and then proceed.

      If you didn’t understand anything feel free to ask me.

      Thank You.

  9. create an account, contact and opportunity if a lead has status warm .the account name ,lead name ,l and opportunity name should match the lead name trigger

    1. Hi Akshay,

      According to your question write a trigger on Lead with “after insert” loop all the leads which are inserted using for loop. Write a if condition to check if the Status field is equal to warm then create a Instance for Account, Opportunity and Contact inside the for loop itself and make sure the Name of the Account, Opportunity and Contact contains the Name of the Lead, also do not forget the give some values for the mandatory fields which contains in Account, Opportunity and Contact. Then add those Instances to a List of sObject which should be declared outside the for loops and if loops. Later in the end check if the List of sObject is not empty, if not insert the List of sObject. That is all you have to do. In case you have any doubt you can ask me.

      Thank You.

  10. Whenever a new account is inserted and count of contact (for
    example you give 5)then automatically 5 records are created on
    a contact

    1. Hi Aryan Kumar,

      Your scenario tell that if you given a number for the count of contact in Account while insertion then we have to create contacts based on the number present in that count of contact field.

      So write a trigger on account with “after insert”. Then loop the accounts that is getting inserted with for loop then check for the count of contact field, if the field is not null then write a for loop like ” for(Integer i=0; i< a.count_of_contact__c; i++) " where " a " is the account which is looping and " count_of_contact__c " is the field which contains the number of contacts that has to be inserted and then declare a new contact instance and then make sure the contact name contains the account name and also the AccountId field in contact contains the looping account Id so that it would be easy for you to check the contacts in accounts related tab once the assigning of values is done add that particular Contact to a list of contact. Do not perform the DML operation inside the for loop. At the end check whether the List of contact is empty if not perform insert Operation for it. If any doubt feel free to ask it over.

      Thank You.

  11. In the 6th Question, you are considering that there will always be one Opp Line Item record to get Serial Num data from. But its not correct right? If all records are deleted, it will again start from Serial Num 1.
    We will need to create a field on Opp to keep how many were created & use that as base to increment.

    1. Hi Mohit,

      As per the question it tells that each time a Opportunity Line Item is added the serial number has to be concatenated with the number of the insertion of Opportunity Line Item for a particular Opportunity is happening, exclusion of the count of deletion. The trigger that T have written will give the serial number as 1 if it is first insertion and for the rest it continues with the number of time the insertion is happening. I have written the trigger based on the requirement of the question. Please check it again.

      Thank you.

  12. In Q6 the Serial no Always show 1…..i created 3 product the s.no show 1 in each nd every product..why???

Leave a Reply

Your email address will not be published. Required fields are marked *