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

Can't access Account Name in Opp Trigger

I've been looking for some help accessing the account name of an opportunity in my trigger, but none of the suggestions I've gotten so far have helped. This trigger duplicates opportunities in order to create followup opps. Currently we just append "annual 2015" or whatever year it is to the end of the opportunity name, but we want to make it so that the name of the new opp has the account name of the original opp followed by the word annual and the year. So rather than "oppNew.Name = oppNew.Name  + ' - Annual ' + o.CloseDate.year();" it would be "oppNew.Name = o.Account.Name + ' - Annual" + o.CloseDate.year();" or something like that. The suggestions I already tried either created opps with "null" for the account part of the name, or completely stopped duplicating opps altogether. Any help on figuring this out would be greatly appreciated. Thanks!

trigger Create_followup on Opportunity (before update, after insert) {
    List<Pricebook2> standardBook = [SELECT Id FROM Pricebook2 WHERE Name = :'Ambition'];//Create an instance of the standard pricebook
        List<Opportunity> listOppor = new List<Opportunity>();
        for (Opportunity o:{
            if (o.StageName == 'Closed Won' && o.Stage_Change__c == false){

                Opportunity oppNew = o.clone();
                oppNew.Name = oppNew.Name  + ' - Annual ' + o.CloseDate.year();
                if(o.Renewal_Date__c != null){
                oppNew.Renewal_Date__c = o.Renewal_Date__c.addYears(1);
                oppNew.CloseDate = o.Renewal_Date__c;}
                oppNew.StageName = 'Discovery';
                oppNew.Probability = 25;
                oppNew.Parent_Opportunity__c = o.Id;
                oppNew.Pricebook2Id = standardBook[0].Id;//associate the standard pricebook with this opportunity
                oppNew.Is_Clone__c = true;
                o.Stage_Change__c = true;

        }//end of for loop

        if(listOppor.size() > 0){
            insert listOppor;
            List<OpportunityContactRole> ocrList = [SELECT OpportunityId, ContactId, Role FROM OpportunityContactRole WHERE OpportunityId IN :Trigger.New];
            List<OpportunityContactRole> newOcrList = new List<OpportunityContactRole>();

            if(!ocrList.isEmpty()) {
                Map<Id, Id> oldOpNewOpIdMap = new Map<Id, Id>();
                for(Opportunity opNew : listOppor) {
                    oldOpNewOpIdMap.put(opNew.Parent_Opportunity__c, opNew.Id);
                for(OpportunityContactRole ocr : ocrList) {
                    OpportunityContactRole newOcr = new OpportunityContactRole();
                    newOcr.ContactId = ocr.ContactId;
                    newOcr.Role = ocr.Role;
                    newOcr.OpportunityId = oldOpNewOpIdMap.get(ocr.OpportunityId);
                insert newOcrList;
          List<OpportunityLineItem> oliList = [SELECT OpportunityId, PricebookEntryId, UnitPrice, Quantity, Duration__c, Payment_Terms__c, Discount FROM OpportunityLineItem WHERE OpportunityId IN :Trigger.New];
          List<OpportunityLineItem> newoliList = new List<OpportunityLineItem>();
          if(!oliList.isEmpty()) {
                Map<Id, Id> oldOpNewOpIdMap2 = new Map<Id, Id>();
                for(Opportunity opNew : listOppor) {
                    oldOpNewOpIdMap2.put(opNew.Parent_Opportunity__c, opNew.Id);
                for(OpportunityLineItem oli : oliList) {
                    OpportunityLineItem newOli = new OpportunityLineItem();
                    newOli.UnitPrice = oli.UnitPrice;
                    newOli.PricebookEntryId = oli.PricebookEntryId;
                    newOli.Quantity = oli.Quantity;
                    newOli.Duration__c = 12;
                    newOli.Payment_Terms__c = oli.Payment_Terms__c;
                    newOli.Discount = oli.Discount;
                    newOli.OpportunityId = oldOpNewOpIdMap2.get(oli.OpportunityId);
                insert newoliList;



            //OpportunityLineItem[] lines = new OpportunityLineItem[0];
            //PricebookEntry entry = [SELECT Id, UnitPrice FROM PricebookEntry WHERE Pricebook2Id = :standardBook.Id AND Product2.ProductCode = 'ENTERPRISE_ANNUAL_UPFRONT'];
            List<Event> eventList = new List<Event>();
            //List<Note> noteList = new List<Note>();

            for(Opportunity o:{
                if(o.Is_Clone__c == true){

                    //noteList.add(new Note(,Title='Matt is the Apex_God',Body='Matt is the Apex_God',isPrivate=false));

                    //lines.add(new OpportunityLineItem(PricebookEntryId=entry.Id, OpportunityId=o.Id, UnitPrice=entry.UnitPrice, Quantity=1));

                    if(o.Renewal_Date__c != null){

                        DateTime myDateTime = o.Renewal_Date__c.addMonths(-10);
                        eventList.add(new Event(,startdatetime=myDateTime,subject='Account Management Follow-Up', EndDateTime=myDateTime, IsAllDayEvent=true));
                        eventList.add(new Event(,startdatetime=myDateTime.addMonths(2),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(2), IsAllDayEvent=true));
                        eventList.add(new Event(,startdatetime=myDateTime.addMonths(4),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(4), IsAllDayEvent=true));
                        eventList.add(new Event(,startdatetime=myDateTime.addMonths(6),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(6), IsAllDayEvent=true));
                        eventList.add(new Event(,startdatetime=myDateTime.addMonths(8),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(8), IsAllDayEvent=true));
                        eventList.add(new Event(,startdatetime=myDateTime.addMonths(10),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(10), IsAllDayEvent=true));
                        eventList.add(new Event(,startdatetime=myDateTime.addMonths(10),subject='Renewal',EndDateTime=myDateTime.addMonths(10), IsAllDayEvent=true));
                        eventList.add(new Event(,startdatetime=myDateTime.addMonths(9),subject='Sales Contract Follow-Up',EndDateTime=myDateTime.addMonths(9), IsAllDayEvent=true));

                    }//end of if

            //insert lines;
            insert eventList;
            //insert noteList;

        catch(Exception e){

Shashikant SharmaShashikant Sharma

In order to get parent record field value you need to query the parent record Account in your case. You could will be something like below.
Map<Id, Account> mapAccount = new Map<Id, Account>();
Set<Id> accountIds  = new Set<Id>();
for( Opportunity opp : ) {
     accountIds.add( opp.AccountId );
Map<Id, Account> mapAccount = new Map<Id, Account>([ Select Name From Account Where Id in : accountIds ]);

for( Opportunity opp : ) {
     String accountName = mapAccount.containsKey( opp.AccountId ) ? mapAccount.get( opp.AccountId ).Name : '';
     opp.Name = accountName + ' - Annual ' + o.CloseDate.year();

Shashikant SharmaShashikant Sharma
I think i decalared map Map<Id, Account> mapAccount  twice so remove the first one.
I'm having a hard time figuring out how to fit this into my trigger....I think some of it needs to go before my for loop and some needs to go inside it, but I'm not sure how to divide it up. I keep getting errors when I try to compile.
Amit Chaudhary 8Amit Chaudhary 8
Please try below code. And let us know if that will help u
trigger Create_followup on Opportunity (before update, after insert) 
    List<Pricebook2> standardBook = [SELECT Id FROM Pricebook2 WHERE Name = :'Ambition'];//Create an instance of the standard pricebook
        List<Opportunity> listOppor = new List<Opportunity>();
		Set<String> setOppId = new Set<String>();
		for(Opportunity o:
		List<Opportunity> lstOpportunity = [select id,StageName,Stage_Change__c,CloseDate,account.Name ,Name,,Renewal_Date__c,Probability,
											Parent_Opportunity__c,Pricebook2Id  from Opportunity where id in :setOppId
        for (Opportunity o: lstOpportunity)
            if (o.StageName == 'Closed Won' && o.Stage_Change__c == false){

                Opportunity oppNew = o.clone();
                oppNew.Name = o.account.Name  + ' - Annual ' + o.CloseDate.year();
                if(o.Renewal_Date__c != null){
                oppNew.Renewal_Date__c = o.Renewal_Date__c.addYears(1);
                oppNew.CloseDate = o.Renewal_Date__c;}
                oppNew.StageName = 'Discovery';
                oppNew.Probability = 25;
                oppNew.Parent_Opportunity__c = o.Id;
                oppNew.Pricebook2Id = standardBook[0].Id;//associate the standard pricebook with this opportunity
                oppNew.Is_Clone__c = true;
                o.Stage_Change__c = true;

        }//end of for loop

        if(listOppor.size() > 0){
            insert listOppor;
            List<OpportunityContactRole> ocrList = [SELECT OpportunityId, ContactId, Role FROM OpportunityContactRole WHERE OpportunityId IN :Trigger.New];
            List<OpportunityContactRole> newOcrList = new List<OpportunityContactRole>();

            if(!ocrList.isEmpty()) {
                Map<Id, Id> oldOpNewOpIdMap = new Map<Id, Id>();
                for(Opportunity opNew : listOppor) {
                    oldOpNewOpIdMap.put(opNew.Parent_Opportunity__c, opNew.Id);
                for(OpportunityContactRole ocr : ocrList) {
                    OpportunityContactRole newOcr = new OpportunityContactRole();
                    newOcr.ContactId = ocr.ContactId;
                    newOcr.Role = ocr.Role;
                    newOcr.OpportunityId = oldOpNewOpIdMap.get(ocr.OpportunityId);
                insert newOcrList;
          List<OpportunityLineItem> oliList = [SELECT OpportunityId, PricebookEntryId, UnitPrice, Quantity, Duration__c, Payment_Terms__c, Discount FROM OpportunityLineItem WHERE OpportunityId IN :Trigger.New];
          List<OpportunityLineItem> newoliList = new List<OpportunityLineItem>();
          if(!oliList.isEmpty()) {
                Map<Id, Id> oldOpNewOpIdMap2 = new Map<Id, Id>();
                for(Opportunity opNew : listOppor) {
                    oldOpNewOpIdMap2.put(opNew.Parent_Opportunity__c, opNew.Id);
                for(OpportunityLineItem oli : oliList) {
                    OpportunityLineItem newOli = new OpportunityLineItem();
                    newOli.UnitPrice = oli.UnitPrice;
                    newOli.PricebookEntryId = oli.PricebookEntryId;
                    newOli.Quantity = oli.Quantity;
                    newOli.Duration__c = 12;
                    newOli.Payment_Terms__c = oli.Payment_Terms__c;
                    newOli.Discount = oli.Discount;
                    newOli.OpportunityId = oldOpNewOpIdMap2.get(oli.OpportunityId);
                insert newoliList;



            //OpportunityLineItem[] lines = new OpportunityLineItem[0];
            //PricebookEntry entry = [SELECT Id, UnitPrice FROM PricebookEntry WHERE Pricebook2Id = :standardBook.Id AND Product2.ProductCode = 'ENTERPRISE_ANNUAL_UPFRONT'];
            List<Event> eventList = new List<Event>();
            //List<Note> noteList = new List<Note>();

            for(Opportunity o:{
                if(o.Is_Clone__c == true){

                    //noteList.add(new Note(,Title='Matt is the Apex_God',Body='Matt is the Apex_God',isPrivate=false));

                    //lines.add(new OpportunityLineItem(PricebookEntryId=entry.Id, OpportunityId=o.Id, UnitPrice=entry.UnitPrice, Quantity=1));

                    if(o.Renewal_Date__c != null){

                        DateTime myDateTime = o.Renewal_Date__c.addMonths(-10);
                        eventList.add(new Event(,startdatetime=myDateTime,subject='Account Management Follow-Up', EndDateTime=myDateTime, IsAllDayEvent=true));
                        eventList.add(new Event(,startdatetime=myDateTime.addMonths(2),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(2), IsAllDayEvent=true));
                        eventList.add(new Event(,startdatetime=myDateTime.addMonths(4),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(4), IsAllDayEvent=true));
                        eventList.add(new Event(,startdatetime=myDateTime.addMonths(6),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(6), IsAllDayEvent=true));
                        eventList.add(new Event(,startdatetime=myDateTime.addMonths(8),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(8), IsAllDayEvent=true));
                        eventList.add(new Event(,startdatetime=myDateTime.addMonths(10),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(10), IsAllDayEvent=true));
                        eventList.add(new Event(,startdatetime=myDateTime.addMonths(10),subject='Renewal',EndDateTime=myDateTime.addMonths(10), IsAllDayEvent=true));
                        eventList.add(new Event(,startdatetime=myDateTime.addMonths(9),subject='Sales Contract Follow-Up',EndDateTime=myDateTime.addMonths(9), IsAllDayEvent=true));

                    }//end of if

            //insert lines;
            insert eventList;
            //insert noteList;

        catch(Exception e){


Something is still not working right...When I change an opportunity to closed won and the follow-up opportunity is created, the "Stage Change" checkbox in the original opportunity isn't being checked. Any time the opp is duplicated, that box should be getting checked, so I'm not sure why this is happening. 

line 38:   o.Stage_Change__c = true;

this line isn't running for some reason. The duplicate account has the right name now though, so that's good...