• travis.truett
  • NEWBIE
  • 70 Points
  • Member since 2014
  • CEO
  • Ambition

  • Chatter
    Feed
  • 0
    Best Answers
  • 1
    Likes Received
  • 0
    Likes Given
  • 35
    Questions
  • 76
    Replies
My apex text class for a trigger I wrote has started failing ever since I added code to the trigger to avoid recursion. As I understand it, I need to update my test in order to ensure the class I wrote to stop the recursion in the trigger is covered. Here's the class I'm using. My trigger calls it before it runs to ensure the trigger only fires once:

public Class checkRecursive{
    private static boolean run = true;
    public static boolean runOnce(){
    if(run){
     run=false;
     return true;
    }else{
        return run;
    }
    }
}


And here's the test class:

@isTest (seeAllData=true)
private class testEditSchedule{

static testMethod void testUpdateSchedule() {
 
List<Account> aList = new List<Account>();    
Account a = new Account(
      Name = 'Test Account'
    );
    aList.add(a);
    
    insert aList;
    

List<Opportunity> oList = new List<Opportunity>();
Opportunity o = new Opportunity(
      Name = 'Test Opportunity', 
      StageName = 'Discovery', 
      CloseDate = Date.today(),
      Contract_Start_Date__c = Date.today(), 
      AccountId = a.Id
    );
    
    oList.add(o);
    insert oList;
    
        //Create Product
        Product2 prod = new Product2();
        prod.IsActive = true;
        prod.Name = 'Onboarding';
        prod.CanUseRevenueSchedule=true;
        insert prod;
        //Create PriceBook
        Pricebook2 pb = new Pricebook2();
        pb.Name = 'Test';
        pb.IsActive = true;
        insert pb;
        List<Pricebook2> PbList = [Select Id, Name, IsActive From Pricebook2 where IsStandard = true LIMIT 1];
    //Pricebook2 standardpb = [Select Id, Name, IsActive From Pricebook2 where IsStandard = true LIMIT 1];
        
            
        PricebookEntry standardpbe = new PricebookEntry();
        standardpbe.Pricebook2Id = PbList[0].Id;
        standardpbe.Product2Id = prod.Id;
        standardpbe.UnitPrice = 10000;
        standardpbe.IsActive = true;
        standardpbe.UseStandardPrice = false;
        insert standardpbe;
        
        PricebookEntry pbe = new PricebookEntry();
        pbe.Pricebook2Id = pb.Id;
        pbe.Product2Id = prod.Id;
        pbe.UnitPrice = 10000;
        pbe.IsActive = true;
        pbe.UseStandardPrice = false;
        insert pbe;
        
List<OpportunityLineItem> oliList = new List<OpportunityLineItem>(); 
List<OpportunityLineItem> oliAnnuallyList = new List<OpportunityLineItem>(); 
List<OpportunityLineItem> oliQuarterlyList = new List<OpportunityLineItem>(); 
List<OpportunityLineItem> oliMonthlyList = new List<OpportunityLineItem>(); 
       
OpportunityLineItem oliAnnually = new OpportunityLineItem(
        OpportunityId = o.Id,  
        PricebookEntryId = pbe.id,
        TotalPrice = 1,
        Quantity=2,
        Payment_Terms__c ='Annually',
        Duration__c = 12
        
    );
    OpportunityLineItem oliMonthly= new OpportunityLineItem(
        OpportunityId = o.Id,  
        PricebookEntryId = pbe.id,
        TotalPrice = 1,
        Quantity=2,
        Payment_Terms__c ='Monthly',
        Duration__c = 1
        
    );
    OpportunityLineItem oliQuarterly= new OpportunityLineItem(
        OpportunityId = o.Id,  
        PricebookEntryId = pbe.id,
        TotalPrice = 1,
        Quantity=2,
        Payment_Terms__c ='Quarterly',
        Duration__c = 3
        
    );
    OpportunityLineItem oli= new OpportunityLineItem(
        OpportunityId = o.Id,  
        PricebookEntryId = pbe.id,
        TotalPrice = 1,
        Quantity=2,
        Payment_Terms__c = 'Up Front',
        Duration__c = 12
        
    );
    oliAnnuallyList.add(oliAnnually);
    oliMonthlyList.add(oliMonthly);
    oliQuarterlyList.add(oliQuarterly);
    oliList.add(oli);
    insert oliList;
    insert oliAnnuallyList;
    insert oliQuarterlyList;
    insert oliMonthlyList;
    
    //Your trigger should have OpportunityLineItemSchedule logic then following asert will pass else it will fail
    List<OpportunityLineItem> lstOptyLi =[SELECT HasRevenueSchedule from OpportunityLineItem where Id =:oli.id];
    System.assertEquals(True, lstOptyLi[0].HasRevenueSchedule);
    List<OpportunityLineItem> lstOptyLi_2 =[SELECT HasRevenueSchedule from OpportunityLineItem where Id =:oliAnnually.id];
    System.assertEquals(True, lstOptyLi_2[0].HasRevenueSchedule);
    List<OpportunityLineItem> lstOptyLi_3 =[SELECT HasRevenueSchedule from OpportunityLineItem where Id =:oliQuarterly.id];
    System.assertEquals(True, lstOptyLi_3[0].HasRevenueSchedule);
    List<OpportunityLineItem> lstOptyLi_4 =[SELECT HasRevenueSchedule from OpportunityLineItem where Id =:oliMonthly.id];
    System.assertEquals(True, lstOptyLi_4[0].HasRevenueSchedule);
   
  }
    
}


What do I need to do to add coverage for the new class?

Thanks
I wrote the following class to call from my triggers and ensure they don't run recursively. This is the code:

public Class checkRecursive{
    private static boolean run = true;
    public static boolean runOnce(){
    if(run){
     run=false;
     return true;
    }else{
        return run;
    }
    }
}

Do I need to write a test class for this class in order to push it to our instance? If so, can someone point me in the right direction? Thanks.
I'm getting the following error when I try to set an opportunity to closed won:

Error:Apex trigger Create_followup caused an unexpected exception, contact your administrator: Create_followup: execution of BeforeUpdate caused by: System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, editSchedule: execution of AfterInsert caused by: System.DmlException: Insert failed. First exception on row 0 with id 00oU0000002ulNkIAI; first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call: [Id] Trigger.editSchedule: line 144, column 1: []: Trigger.Create_followup: line 88, column 1

The two triggers mentioned in the error are both triggers I wrote. Can anyone tell me what this type of error might be caused by?

Thanks
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
    
    if(Trigger.isUpdate){
        List<Opportunity> listOppor = new List<Opportunity>();
        for (Opportunity o: Trigger.new){
            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;
                listOppor.add(oppNew);
                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);
                    newOcrList.add(newOcr);
                }
                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);
                    
                    
                    newoliList.add(newOli);
                }
                insert newoliList;
            }

            
        }
        
        

    }

    if(trigger.isInsert){
        try{
            //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: Trigger.new){
                if(o.Is_Clone__c == true){

                    //noteList.add(new Note(ParentId=o.id,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(whatid=o.id,startdatetime=myDateTime,subject='Account Management Follow-Up', EndDateTime=myDateTime, IsAllDayEvent=true));
                        eventList.add(new Event(whatid=o.id,startdatetime=myDateTime.addMonths(2),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(2), IsAllDayEvent=true));
                        eventList.add(new Event(whatid=o.id,startdatetime=myDateTime.addMonths(4),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(4), IsAllDayEvent=true));
                        eventList.add(new Event(whatid=o.id,startdatetime=myDateTime.addMonths(6),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(6), IsAllDayEvent=true));
                        eventList.add(new Event(whatid=o.id,startdatetime=myDateTime.addMonths(8),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(8), IsAllDayEvent=true));
                        eventList.add(new Event(whatid=o.id,startdatetime=myDateTime.addMonths(10),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(10), IsAllDayEvent=true));
                        eventList.add(new Event(whatid=o.id,startdatetime=myDateTime.addMonths(10),subject='Renewal',EndDateTime=myDateTime.addMonths(10), IsAllDayEvent=true));
                        eventList.add(new Event(whatid=o.id,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){

        }
    }
}
I have a trigger that duplicates opportunities when we close them. Currently, the trigger just appends the word Annual and the current year to the end of the name of the duplicated opp for the name of the new opp. What I would like to do, however, is use the name of the opportunity's associated account instead. Is there an easy way to pull that info in and access the account's name? Here's my code, with the section I'm talking about bolded: 

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
    
    if(Trigger.isUpdate){
        List<Opportunity> listOppor = new List<Opportunity>();
        for (Opportunity o: Trigger.new){
            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;
                listOppor.add(oppNew);
                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);
                    newOcrList.add(newOcr);
                }
                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);
                    
                    
                    newoliList.add(newOli);
                }
                insert newoliList;
            }

            
        }
        
        

    }

    if(trigger.isInsert){
        try{
            //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: Trigger.new){
                if(o.Is_Clone__c == true){

                    //noteList.add(new Note(ParentId=o.id,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(whatid=o.id,startdatetime=myDateTime,subject='Account Management Follow-Up', EndDateTime=myDateTime, IsAllDayEvent=true));
                        eventList.add(new Event(whatid=o.id,startdatetime=myDateTime.addMonths(2),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(2), IsAllDayEvent=true));
                        eventList.add(new Event(whatid=o.id,startdatetime=myDateTime.addMonths(4),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(4), IsAllDayEvent=true));
                        eventList.add(new Event(whatid=o.id,startdatetime=myDateTime.addMonths(6),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(6), IsAllDayEvent=true));
                        eventList.add(new Event(whatid=o.id,startdatetime=myDateTime.addMonths(8),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(8), IsAllDayEvent=true));
                        eventList.add(new Event(whatid=o.id,startdatetime=myDateTime.addMonths(10),subject='Account Management Follow-Up', EndDateTime=myDateTime.addMonths(10), IsAllDayEvent=true));
                        eventList.add(new Event(whatid=o.id,startdatetime=myDateTime.addMonths(10),subject='Renewal',EndDateTime=myDateTime.addMonths(10), IsAllDayEvent=true));
                        eventList.add(new Event(whatid=o.id,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){

        }
    }
}
I wrote a trigger and a test class for it. The code coverage is 83% in the sandbox. When I try to roll it out, however, I get an error saying my code coverage is only 65% and that I can't deploy. I'm not sure why this is happening...

User-added image

Don't understand why my coverage changes when I go from the sandbox to deployment. I'm someone could help me figure this out, I'd appreciate it. Thanks
I wrote a trigger that duplicates Opportunities when their stage is updated to "Closed Won." The trigger also copies over some associated objects from the duplicated opp, changes the name of the new opp, and populates a field in the "Child Opportunity" called Parent_Opportunity__c, which contains the Id of the parent. The following code is my test, which I can't get to work right. It fails at the assertion statement. I'm trying to create an opportunity, add a product to it, and then change the stage to Closed Won, which should run the trigger, and then test that there exists a new opportunity with the original opportunity's Id as its Parent Opportunity.

Thanks in advance for the help. Here's the code:

@isTest (seeAllData=true)
private class testCreateFollowup{

static testMethod void test_Create_Followup() {

List<Account> aList = new List<Account>();    
Account a = new Account(
      Name = 'Test Account'
    );
    aList.add(a);
    
    insert aList;
    

List<Opportunity> oList = new List<Opportunity>();
Opportunity o = new Opportunity(
      Name = 'Test Opportunity', 
      StageName = 'Discovery', 
      CloseDate = Date.today(), 
      AccountId = a.Id
    );
    
    oList.add(o);
    insert oList;


        //Create Product
        Product2 prod = new Product2();
        prod.IsActive = true;
        prod.Name = 'Onboarding';
        prod.CanUseRevenueSchedule=true;
        insert prod;
        //Create PriceBook
        Pricebook2 pb = new Pricebook2();
        pb.Name = 'Test';
        pb.IsActive = true;
        insert pb;
    Pricebook2 standardpb = [Select Id, Name, IsActive From Pricebook2 where IsStandard = true LIMIT 1];
        
            
        PricebookEntry standardpbe = new PricebookEntry();
        standardpbe.Pricebook2Id = standardpb.Id;
        standardpbe.Product2Id = prod.Id;
        standardpbe.UnitPrice = 10000;
        standardpbe.IsActive = true;
        standardpbe.UseStandardPrice = false;
        insert standardpbe;
        
        PricebookEntry pbe = new PricebookEntry();
        pbe.Pricebook2Id = pb.Id;
        pbe.Product2Id = prod.Id;
        pbe.UnitPrice = 10000;
        pbe.IsActive = true;
        pbe.UseStandardPrice = false;
        insert pbe;
        

List<OpportunityLineItem> oliAnnuallyList = new List<OpportunityLineItem>(); 
       
OpportunityLineItem oliAnnually = new OpportunityLineItem(
        OpportunityId = o.Id,  
        PricebookEntryId = pbe.id,
        TotalPrice = 1,
        Quantity=2,
        Payment_Terms__c ='Annually',
        Duration__c = 12
        
    );
    
    oliAnnuallyList.add(oliAnnually);
    
    insert oliAnnuallyList;
    
    o.Stagename = 'Closed Won';

 List<Opportunity> lstOpty =[SELECT Parent_Opportunity__c from Opportunity];
 System.assertequals(lstOpty[0].Parent_Opportunity__c, o.Id);

}
}