• jonathanbernddf20131.387825590468351E12
  • NEWBIE
  • 30 Points
  • Member since 2013

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 11
    Questions
  • 18
    Replies
Hi folks
My newbie journey continues. Now I'm trying to write a deep clone button. I'm not sure of the available methods/best practices.  Here is what I want in process/pseudo code form and I'd be grateful for help in terms of class/methods to use and order of events.

Here is an object chart of the relevant objects:

object chart
  1. Button on parent is clicked. (AM__c SOjbect).
    1. AM record is cloned in it's entirety and Name is changed to a specific concatenation.  And along with it the following are cloned in correct 'generations':
      1. PF__c child records attached to this particular AM__c SObject record (via Join object) are copied with all their fields.
        1. G__c grandchildren records (via Join PF_G) attached to each PF__c record are copied with all their fields
          1. F__c great grandchildren records (via Join_G_F) records that are attached 
Once all of that is cloned, I want to lock down either this version or the old version to read only.
Hi folks
I have a method called by a simple js button. 
Questions:
1) How do I write a test class to simulate clicking the button?
2) In surfing the web there appears to be a question as to whether test coverage is necessary? If it isn't doesn't that count against code coverage?

Simple button script is below from which you can see the name of the method (All works fine. Just need to sort out test coverage question).
{!REQUIRESCRIPT("/soap/ajax/29.0/connection.js")} 
{!REQUIRESCRIPT("/soap/ajax/29.0/apex.js")} 
var result = sforce.apex.execute("PubVersionNumber","buttonVersionNumber",{}); 
alert("App is Published." ); 
window.location.reload();

 
I've written a trigger and class that work currently off a checkbox being true on the parent object. Now I'd like to replace this checkbox with a button 'Publish'.  Could you help me figure out where the 'missing link' is between my very rudimentary js and my method. I know the button is on an object, but I'm not seeing exactly how to tell the button execute the method on this record on this SObject now.

Here's the beginnings of my js.
{!REQUIRESCRIPT("/soap/ajax/10.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/10.0/apex.js")}
var pubApp = sforce.apex.execute("PubVersionNumber", "buttonVersionNumber", {});
window.alert("App is Published." );

 
As a Newbie, I'm still learning, so the answer to there is probably a very simple issue with my code to remedy my problem.

Here is my use case:
When a checkbox is true on a custom master object a new child record is created with 1) a concatenation of values in the 'name' field, 2) Now() in a published date field and 3) obviously the master.id in the child_master__c field.

I have my class (enclosed below) which appears to work with a trigger that has no conditions.
I have my trigger with no conditions below.

I want to add the following conditions to my trigger:
If(Trigger.isInsert && am.Published__c = true) {execute class}  if(Trigger.isUpdate && am.Published__c = true && Trigger.old.am.Published__c != Trigger.new.am.Published__c){execute class}

I was wondering about putting if(am.Published__c = true) into the class, but was concerned that I'd then have too many nested if statements.

Even with my 'working' simple trigger and class, it does not appear possible to delete a record (hoping that will change when I get my conditions).

Class
Public with sharing class InsertVersionNumber {
    
    //Initialize Static Variable
    Public Static Boolean firstcall=True;
           
    Public static void setVersionNumber(List<App_Master__c> appMasts) {
    
    if(!firstcall) {return;}
    else{firstcall = false;}
    
    //Make lists for update
    List<App_Published_Version__c> appPVs = new List<App_Published_Version__c>();

    for(App_Master__c am :appMasts) {

        App_Published_Version__c apv = new App_Published_Version__c();
         if(am.Number_of_Versions__c >= 10) {
         apv.Name = am.Name + '-' + (am.Number_of_Versions__c + 1);
         } else {
         apv.Name = am.Name + '-0' + (am.Number_of_Versions__c + 1);
         }
        apv.Published_Date__c = datetime.Now();
        apv.App_Master__c = am.Id;
        appPVs.add(apv);

    }

    insert appPVs;
   }  
                    
}

Trigger
trigger publishApp on App_Master__c (after insert, after update) {

        for(App_Master__c am :Trigger.New) {
        
               InsertVersionNumber.setVersionNumber(Trigger.New);
          }

}

 
Having trouble figuring out the best way (or any way that works for my apex class for that matter) to get the following end result. I can get most of the way there with SOQL and Group by Cube but that doesn't work with apex, and I'm thinking a for loop with a set would be better anyway.

Here's what I'm trying to do - step by step

Find Id, start_date__c, completion_date__c, parentId where parentId has more than one customchild__c record that has null for completion_date__c.

Return list and then from this list - 

I need to create a new list (unless I can do this all in the same initial query which would be great)   - group my previous list by parentId and grab only the customchild__c record from each group where start_date__c is the earliest and return that into a new list.

Help would be much valued.


Hi folks
Still learning. Got a dilemma. I have a test class that seems like it should work, and I have a class and trigger that does work in a sandbox. However, if I remove this clause from the class - if(!firstcall && newOpp[0].Name != 'Trigger') {  //can add if needed 
  //System.debug('Exiting method to update OPportunity Stage History because of !firstcall');
    return;}
    else {firstcall=false;}

the update isn't called. If I put it back the update creates an extra record with a date that should not be there.  Another way the after update fails is if I change the name to something other than Trigger in my Test Class. [I did want to do bulk testing, but as I failed I simplified it down to this one test record].  Any help would be greatly appreciated.

Here is the code for the trigger
trigger OppStageHistory on Opportunity (after insert, before update, after update) {

    if(Trigger.isInsert) {
        OppStageHistory.createOppStageHistory(Trigger.new);
    }
    if(Trigger.isUpdate) {
        for (Opportunity newOpp: Trigger.new)  {
            Integer i = 0;
            if(newOpp.StageName != Trigger.old[i].StageName) {
                OppStageHistory.updOppStageHistory(Trigger.old, Trigger.new);
            }
            i++;
        }
    }
}
Here is the code for the class 
public with sharing class OppStageHistory {

  //Initialize Static Variable
  public Static Boolean firstcall=True;    
  
  //Method to insert new Opportunity Stage History record with brand new Opportunity
  public static void updOppStageHistory(List<Opportunity> oldOpp, List<Opportunity> newOpp){

  if(!firstcall && newOpp[0].Name != 'Trigger') {  //can add if needed  
  //System.debug('Exiting method to update OPportunity Stage History because of !firstcall');
    return;}
    else {firstcall=false;}
    
   //Declare a set of the Ids in this update
   Set<Id> oppStageIds = new Set<Id>();
   for (Opportunity oppO : oldOpp) {
   //Grab the Ids from the opp List
   oppStageIds.add(oppO.Id);
   }

   //Declare a list of Opportunity Stage History
   List <Opportunity_Stage_History__c> prevOpshList = new List <Opportunity_Stage_History__c> ();
   
   //Fill the list with records that match the Id from the trigger and has a Null Completion Date
   prevOpshList = [SELECT Id, Name, Stage__c, Start_Date__c, Completion_Date__c FROM Opportunity_Stage_History__c 
                   WHERE Opportunity__c IN :oppStageIds AND Completion_Date__c = NULL]; 
                   
   //For each record in prevOpshList, set the Completion date
   for(Opportunity_Stage_History__c prevOpsh : prevOpshList) {
       prevOpsh.Completion_Date__c = date.TODAY();
    }
       
       //Update the rows in the list
       try {
           update prevOpshList;
           }
           catch (DmlException e) {
                      // Process exception here
           }
    //Declare a new List of Opportunity Stage History
    List <Opportunity_Stage_History__c> opsh = new List <Opportunity_Stage_History__c> ();
    for(Opportunity oppN: newOpp) {
              integer i = 0;   //Keeps oldOpp in sync with oppN which is newOpp 
              System.debug('oldOpp Stage is ' + oldOpp[i].StageName + '-- oppN.Stage is  ' + oppN.StageName);
              if(oppN.StageName <> oldOpp[i].StageName && oldOpp[i].StageName <> NULL) {
                   Opportunity_Stage_History__c newOpsh = new Opportunity_Stage_History__c();
                   newOpsh.Stage__c = oppN.StageName;
                   newOpsh.Start_Date__c = date.TODAY();
                   newOpsh.Opportunity__c = oppN.Id;
          
                   //System.debug('adding ' + String.valueOf(oppN.Id) + ' to List newOpsh');
                   opsh.add(newOpsh);
                 } else { //This handles the exeption when the previous Stage was blank but the Opportunity has been created with no stage
                     
                       if(oppN.StageName <> oldOpp[i].StageName) {
                           Opportunity_Stage_History__c newOpsh = new Opportunity_Stage_History__c();
                           newOpsh.Stage__c = oppN.StageName;
                           newOpsh.Start_Date__c = date.TODAY();
                           newOpsh.Opportunity__c = oppN.Id;
          
                           opsh.add(newOpsh);
                           i = i + 1;
                         }

                       } // end of else
               } // end of for loop oppN 
               //Insert the new rows
               insert opsh; 
  } //end of updOppStageHistory Method                     

  public static void createOppStageHistory(List<Opportunity> newOpp)
  {
   if(!firstcall) {
     System.debug('Exiting updOppStageHistory because of !firstcall');
     return;}
     else {firstcall=false;}
   
   List <Opportunity_Stage_History__c> opsh = new List <Opportunity_Stage_History__c> ();
   for(Opportunity oppN: newOpp) {
          Opportunity_Stage_History__c newOpsh = new Opportunity_Stage_History__c();
      
         //Set Values for New Opportunity
             if(oppN.StageName <> NULL && oppN.StageName <> '--None--')
             {
                newOpsh.Stage__c = oppN.StageName;
                newOpsh.Start_Date__c = date.TODAY();
                newOpsh.Opportunity__c = oppN.Id;
       
                opsh.add(newOpsh);
             }
          }
    insert opsh;
  }
 
}
Here is the code for the Test class (PS, when I leave the class as is, there is a duplication of the debug at line 44).
@isTest
public class TestOppStageHistory {
    
    //Start method 1 - insert new
    static testmethod void createInsOppData() {
        
        //Create an opportunity
        Opportunity insOpp = new Opportunity(
        Name = 'Trigger',
        StageName = 'Qualification/Prospecting',
        Probability = 1,
        CloseDate = date.TODAY() + 10,
        Type = 'New Business');
        
        //Run test
        Test.startTest();
        
        insert insOpp;

        Test.stopTest();
      
        //Test to see if opportunity stage history record was created
        List<Opportunity> insTestOpps = [Select Id, StageName FROM Opportunity WHERE Id = :insOpp.Id];
        String stval1 = insTestOpps[0].Id;   
        System.debug('Value of Id in Opportunity in record is ' + stval1);
            
        Opportunity_Stage_History__c newOppsh = [Select Id, Opportunity__c, Stage__c, Start_Date__c, Completion_Date__c 
                                                 FROM Opportunity_Stage_History__c WHERE Opportunity__c = :insOpp.Id];

        System.assertEquals(newOppsh.Stage__c, insOpp.StageName, 'Did not get the expected Stage__c value');
        System.assertEquals(newOppsh.Start_Date__c, date.TODAY(), 'Did not get the expected date today()');
        System.assertEquals(newOppsh.Completion_Date__c, NULL, 'Did not get the expected completion date value null');
        System.assertEquals(newOppsh.Opportunity__c, insOpp.Id, 'Did not get related to correct Opportunity parent record');
            
        //Do we have the right values?
        List<Opportunity_Stage_History__c> insertedShRecs= [SELECT Id, Stage__c, Start_Date__c, Completion_Date__c, Opportunity__c
                                                            FROM Opportunity_Stage_History__c WHERE Opportunity__c = : insOpp.Id ];
        System.debug('The number of recs in the list is ' + insertedShRecs.size());
        String stval2 = insertedShRecs[0].Stage__c;   
        System.debug('Value of Stage__c in record is ' + stval2);
        
        //End method 1
    }

    //Start method 2 - update existing
    static testmethod void createUpdOppData() {
        
        
        //Create an opportunity
        Opportunity insNewOpp = new Opportunity(
        Name = 'Trigger',
        StageName = 'Qualification/Prospecting',
        Probability = 1,
        CloseDate = date.TODAY() + 10,
        Type = 'New Business');
        
               
        //Test.startTest();
        insert insNewOpp;
        //Test.stopTest();

        
        String stval3 = insNewOpp.Id;   
        System.debug('Value of Id in Opportunity in record is ' + stval3); 
        
       
        
        Opportunity_Stage_History__c oldOsh = [SELECT Id, Completion_Date__c, Stage__c, Start_Date__c FROM Opportunity_Stage_History__c 
                                                WHERE stage__c = :insNewOpp.StageName AND Completion_Date__c = Null];
        
        String stval4 = oldOsh.Id;   
        System.debug('Value of Id in Old Stage History in record is ' + stval4);  
        System.assertEquals(oldOsh.Stage__c, insNewOpp.StageName);
        System.assertEquals(oldOsh.Start_Date__c, date.TODAY());
        
        
        //Run test 2 - update existing opportunity
        Opportunity updOpp = [SELECT Id, StageName FROM Opportunity WHERE Id = :insNewOpp.Id AND StageName = :insNewOpp.StageName];
        
        String stval5 = updOpp.Id;   
        System.debug('Value of Id in Opportunity in record is ' + stval5);
        
       
        Test.startTest();
        updOpp.StageName = 'Needs Analysis';
        

        update updOpp; 
        Test.stopTest();
        
        /*String stval5 = insNewOpp.StageName;
        System.debug('Value of StageName in updOpp record is '+stval5);*/
        
        //Did trigger update old stage history?
        List<Opportunity_Stage_History__c> updatedShRecs= [SELECT Id, Stage__c, Start_Date__c, Completion_Date__c, Opportunity__c
                                                           FROM Opportunity_Stage_History__c WHERE Opportunity__c = : updOpp.Id];
                                                           
        String stval6 = updatedShRecs[0].Id;   
        System.debug('Value of Id in Old Stage History in record is ' + stval6);  
        
        String stval7 = updatedShRecs[1].Id;   
        System.debug('Value of Id in New Stage History in record is ' + stval7);  
        
        System.assertEquals(updatedShRecs[0].Stage__c, oldOsh.Stage__c, 'Did not get expected Stage__c value');
        System.assertEquals(updatedShRecs[0].Completion_Date__c, date.TODAY(), 'Completion Date was not updated from null to today()');
        
        //Did trigger kick off new stage history rec?
        List<Opportunity_Stage_History__c> insertedShRecs= [SELECT Id, Stage__c, Start_Date__c, Completion_Date__c, Opportunity__c
                                                           FROM Opportunity_Stage_History__c WHERE Stage__c = : updOpp.StageName
                                                           AND Completion_Date__c = null];
        
        System.assertEquals(insertedShRecs[0].Stage__c, 'Needs Analysis', 'Did not get new value of Stage__c - Needs Analysis');
        System.assertEquals(insertedShRecs[0].Completion_Date__c, null, 'Did not get expected blank completion date');
        System.assertEquals(insertedShRecs[0].Start_Date__c, date.TODAY(), 'Did not get expected start date of today');
        


    }    
    
}


Hi folks
As a newbie to SF, can someone explain to me why nothing I do actually updates my record AND activates my trigger?
I have a trigger on Opportunity to a custom object. It creates a record based on the stage value. Trigger and Class work in sandbox.
I'm trying to get test coverage and I'm running into a roadblock.

I have managed to update a StageName value in the Test class but it didn't call the trigger. (which is supposed to update a previous custom object record and create a new one with the new StageName).
I tried putting in Test.startTest(); and Test.stopTest(); but it didn't make a difference. 
I tried creating bulk records, but only succeeded in creating multiple initial inserts, but did not manage to call the update part of the trigger.
I tried a single opportunity test record, and did update the value in StageName but did not call the trigger.
I'm still trying with a single record and have the test code below.  Please can someone explain to me what I clearly don't understand? Thanks
@isTest
public class TestOppStageHistory {

    static testmethod void createInsOppData() {
        
        Test.startTest();
        
        //Create an opportunity
        Opportunity insOpp = new Opportunity();
        insOpp.Name = 'TestUpdate';
        insOpp.StageName = 'Qualification/Prospecting';
        insOpp.Probability = 1;
        insOpp.CloseDate = date.TODAY() + 10;
        insOpp.Type = 'New Business';
        insert insOpp;

      
        //Test to see if opportunity stage history record was created
        List<Opportunity> insTestOpps = [Select Id, StageName FROM Opportunity WHERE Id = :insOpp.Id];
        String stval1 = insTestOpps[0].Id;   
        System.debug('Value of Id in Opportunity in record is ' + stval1);
            
        Opportunity_Stage_History__c newOppsh = [Select Id, Opportunity__c, Stage__c, Start_Date__c, Completion_Date__c 
                                                 FROM Opportunity_Stage_History__c WHERE Opportunity__c = :insOpp.Id];

        System.assertEquals(newOppsh.Stage__c, insOpp.StageName);
        System.assertEquals(newOppsh.Start_Date__c, date.TODAY());
        System.assertEquals(newOppsh.Completion_Date__c, NULL);
        System.assertEquals(newOppsh.Opportunity__c, insOpp.Id);
            
        //Do we have the right values?
        List<Opportunity_Stage_History__c> insertedShRecs= [SELECT Id, Stage__c, Start_Date__c, Completion_Date__c, Opportunity__c
                                                            FROM Opportunity_Stage_History__c WHERE Opportunity__c = : insOpp.Id ];
        System.debug('The number of recs in the list is ' + insertedShRecs.size());
        String stval2 = insertedShRecs[0].Stage__c;   
        System.debug('Value of Stage__c in record is ' + stval2);
        

        //update StageName on opportunity

        Opportunity updOpp = [SELECT Id, StageName, Probability FROM Opportunity WHERE Id= :insOpp.Id];
        String stval3 = updOpp.Id;
        System.debug('Value of Id in updOpp record is ' + stval3); 
        String stval4 = updOpp.StageName;
        System.debug('Value of StageName in updOpp record is '+stval4);
        
        updOpp.StageName = 'Needs Analysis';
        updOpp.Probability = 25;
        //update.updOpp(); - can't do this. Do I need to map something? Do I need to break to two methods - how to use same record?
        
        Test.stopTest();
        
    }
    
}

Hi
Having some trouble. Wrote a trigger/class to post info from a new case to the lead object. I cannot get a test class to insert a case.

The above is the error message with 'radioCaseToLead: execution of AfterInsert'

The line of code to referred to as a problem is 'insert newleads;'

Any insight would be great.
I'm new to apex and am having difficulty with a test class for a working trigger and class in my sandbox.
The trigger and class I have work after insert and after update on a field value ('Stage') on a parent object. 
If the parent is new, then a new child object is created with a Stage__c field that mirrors the parent object 'Stage' field

I started writing a bulk test class, but as I couldn't get it to properly create new records, I started again from scratch with a single test record.
I insert the test record and a child record is created exactly as it should be. (System.debug, assert etc. confirm).

Then I take that same test parent record and update the 'Stage' field to a new value. The after update trigger should create another new child record with the new 'Stage__c' value and also find the old child record and update a field there. 

Even though System.debug says I've successfully updated the field 'Stage' on the parent object, the trigger is clearly not being called as it doesn't created a second child object.

I'm using oldStage.Stage = 'new value';  update oldStage;  

Guessing the Test environment never really 'saved' my initial record so it doesn't recognize this is a legit update. 

Can you help me understand best practice and solution(s)?

Thanks
Hi folks
Still new but getting there bit by bit. I have this trigger, It is supposed to update certain specific fields based on different picklist values. I'm thinking it's not bulkified like it should be. I'm thinking (but could be wrong) I need to make a set/list and update the values of the set before letting it go ahead and do it's stuff, so I can do everything with one update.  Here's the trigger.

trigger updateAppNum on CustomObject__c (before insert, before update) {

   //Get set of Incomplete ids
    List<Integer> appUps = new List<Integer>();
   
    for(CustomObject__c ap :trigger.new) {
        if (ap.Status__c == 'Incomplete') {
          ap.AppInc__c = 1;
        }
        if (ap.Status__c == 'Complete - Pending Review') {
          ap.AppCompP__c = 1;
        }
        if (ap.Status__c == 'Complete - Decision Made') {
          ap.AppCompD__c = 1;
        }
        if (ap.Status__c == 'Deferred') {
          ap.AppDef__c = 1;
        }
        if (ap.Status__c == 'Withdrawn') {
          ap.AppW__c = 1;
        }
    }

}
Hi
As a newbie, I wonder if you could help me with this issue:
I'm trying to write a trigger that populates a number of fields on the contact object based on different picklist values in the same child object. I need a trigger as there are not enough roll-up summary fields.  There will be thousands in the counts of each value.
Here is what I am attempting to do:

SELECT Id, Picklist_value__c FROM ChildObject__c WHERE Picklist_Value__c ='value a'
Count the total of Child records put the COUNT number into a 'Count 'value a' Roll-up' field on the Contact Object.
SELECT Id, Picklist_value__c FROM ChildObject__c WHERE Picklist_Value__c ='value b'
Count the total of Child records put the COUNT number into a 'Count 'value b' Roll-up' field on the Contact Object.
SELECT Id, Picklist_value__c FROM ChildObject__c WHERE Picklist_Value__c ='value c'
Count the total of Child records put the COUNT number into a 'Count 'value c' Roll-up' field on the Contact Object.
SELECT Id, Picklist_value__c FROM ChildObject__c WHERE Picklist_Value__c ='value d'
Count the total of Child records put the COUNT number into a 'Count 'value d' Roll-up' field on the Contact Object.

Thanks in advance for any help
Hi folks
I have a method called by a simple js button. 
Questions:
1) How do I write a test class to simulate clicking the button?
2) In surfing the web there appears to be a question as to whether test coverage is necessary? If it isn't doesn't that count against code coverage?

Simple button script is below from which you can see the name of the method (All works fine. Just need to sort out test coverage question).
{!REQUIRESCRIPT("/soap/ajax/29.0/connection.js")} 
{!REQUIRESCRIPT("/soap/ajax/29.0/apex.js")} 
var result = sforce.apex.execute("PubVersionNumber","buttonVersionNumber",{}); 
alert("App is Published." ); 
window.location.reload();

 
I've written a trigger and class that work currently off a checkbox being true on the parent object. Now I'd like to replace this checkbox with a button 'Publish'.  Could you help me figure out where the 'missing link' is between my very rudimentary js and my method. I know the button is on an object, but I'm not seeing exactly how to tell the button execute the method on this record on this SObject now.

Here's the beginnings of my js.
{!REQUIRESCRIPT("/soap/ajax/10.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/10.0/apex.js")}
var pubApp = sforce.apex.execute("PubVersionNumber", "buttonVersionNumber", {});
window.alert("App is Published." );

 
As a Newbie, I'm still learning, so the answer to there is probably a very simple issue with my code to remedy my problem.

Here is my use case:
When a checkbox is true on a custom master object a new child record is created with 1) a concatenation of values in the 'name' field, 2) Now() in a published date field and 3) obviously the master.id in the child_master__c field.

I have my class (enclosed below) which appears to work with a trigger that has no conditions.
I have my trigger with no conditions below.

I want to add the following conditions to my trigger:
If(Trigger.isInsert && am.Published__c = true) {execute class}  if(Trigger.isUpdate && am.Published__c = true && Trigger.old.am.Published__c != Trigger.new.am.Published__c){execute class}

I was wondering about putting if(am.Published__c = true) into the class, but was concerned that I'd then have too many nested if statements.

Even with my 'working' simple trigger and class, it does not appear possible to delete a record (hoping that will change when I get my conditions).

Class
Public with sharing class InsertVersionNumber {
    
    //Initialize Static Variable
    Public Static Boolean firstcall=True;
           
    Public static void setVersionNumber(List<App_Master__c> appMasts) {
    
    if(!firstcall) {return;}
    else{firstcall = false;}
    
    //Make lists for update
    List<App_Published_Version__c> appPVs = new List<App_Published_Version__c>();

    for(App_Master__c am :appMasts) {

        App_Published_Version__c apv = new App_Published_Version__c();
         if(am.Number_of_Versions__c >= 10) {
         apv.Name = am.Name + '-' + (am.Number_of_Versions__c + 1);
         } else {
         apv.Name = am.Name + '-0' + (am.Number_of_Versions__c + 1);
         }
        apv.Published_Date__c = datetime.Now();
        apv.App_Master__c = am.Id;
        appPVs.add(apv);

    }

    insert appPVs;
   }  
                    
}

Trigger
trigger publishApp on App_Master__c (after insert, after update) {

        for(App_Master__c am :Trigger.New) {
        
               InsertVersionNumber.setVersionNumber(Trigger.New);
          }

}

 
Hi folks
Still learning. Got a dilemma. I have a test class that seems like it should work, and I have a class and trigger that does work in a sandbox. However, if I remove this clause from the class - if(!firstcall && newOpp[0].Name != 'Trigger') {  //can add if needed 
  //System.debug('Exiting method to update OPportunity Stage History because of !firstcall');
    return;}
    else {firstcall=false;}

the update isn't called. If I put it back the update creates an extra record with a date that should not be there.  Another way the after update fails is if I change the name to something other than Trigger in my Test Class. [I did want to do bulk testing, but as I failed I simplified it down to this one test record].  Any help would be greatly appreciated.

Here is the code for the trigger
trigger OppStageHistory on Opportunity (after insert, before update, after update) {

    if(Trigger.isInsert) {
        OppStageHistory.createOppStageHistory(Trigger.new);
    }
    if(Trigger.isUpdate) {
        for (Opportunity newOpp: Trigger.new)  {
            Integer i = 0;
            if(newOpp.StageName != Trigger.old[i].StageName) {
                OppStageHistory.updOppStageHistory(Trigger.old, Trigger.new);
            }
            i++;
        }
    }
}
Here is the code for the class 
public with sharing class OppStageHistory {

  //Initialize Static Variable
  public Static Boolean firstcall=True;    
  
  //Method to insert new Opportunity Stage History record with brand new Opportunity
  public static void updOppStageHistory(List<Opportunity> oldOpp, List<Opportunity> newOpp){

  if(!firstcall && newOpp[0].Name != 'Trigger') {  //can add if needed  
  //System.debug('Exiting method to update OPportunity Stage History because of !firstcall');
    return;}
    else {firstcall=false;}
    
   //Declare a set of the Ids in this update
   Set<Id> oppStageIds = new Set<Id>();
   for (Opportunity oppO : oldOpp) {
   //Grab the Ids from the opp List
   oppStageIds.add(oppO.Id);
   }

   //Declare a list of Opportunity Stage History
   List <Opportunity_Stage_History__c> prevOpshList = new List <Opportunity_Stage_History__c> ();
   
   //Fill the list with records that match the Id from the trigger and has a Null Completion Date
   prevOpshList = [SELECT Id, Name, Stage__c, Start_Date__c, Completion_Date__c FROM Opportunity_Stage_History__c 
                   WHERE Opportunity__c IN :oppStageIds AND Completion_Date__c = NULL]; 
                   
   //For each record in prevOpshList, set the Completion date
   for(Opportunity_Stage_History__c prevOpsh : prevOpshList) {
       prevOpsh.Completion_Date__c = date.TODAY();
    }
       
       //Update the rows in the list
       try {
           update prevOpshList;
           }
           catch (DmlException e) {
                      // Process exception here
           }
    //Declare a new List of Opportunity Stage History
    List <Opportunity_Stage_History__c> opsh = new List <Opportunity_Stage_History__c> ();
    for(Opportunity oppN: newOpp) {
              integer i = 0;   //Keeps oldOpp in sync with oppN which is newOpp 
              System.debug('oldOpp Stage is ' + oldOpp[i].StageName + '-- oppN.Stage is  ' + oppN.StageName);
              if(oppN.StageName <> oldOpp[i].StageName && oldOpp[i].StageName <> NULL) {
                   Opportunity_Stage_History__c newOpsh = new Opportunity_Stage_History__c();
                   newOpsh.Stage__c = oppN.StageName;
                   newOpsh.Start_Date__c = date.TODAY();
                   newOpsh.Opportunity__c = oppN.Id;
          
                   //System.debug('adding ' + String.valueOf(oppN.Id) + ' to List newOpsh');
                   opsh.add(newOpsh);
                 } else { //This handles the exeption when the previous Stage was blank but the Opportunity has been created with no stage
                     
                       if(oppN.StageName <> oldOpp[i].StageName) {
                           Opportunity_Stage_History__c newOpsh = new Opportunity_Stage_History__c();
                           newOpsh.Stage__c = oppN.StageName;
                           newOpsh.Start_Date__c = date.TODAY();
                           newOpsh.Opportunity__c = oppN.Id;
          
                           opsh.add(newOpsh);
                           i = i + 1;
                         }

                       } // end of else
               } // end of for loop oppN 
               //Insert the new rows
               insert opsh; 
  } //end of updOppStageHistory Method                     

  public static void createOppStageHistory(List<Opportunity> newOpp)
  {
   if(!firstcall) {
     System.debug('Exiting updOppStageHistory because of !firstcall');
     return;}
     else {firstcall=false;}
   
   List <Opportunity_Stage_History__c> opsh = new List <Opportunity_Stage_History__c> ();
   for(Opportunity oppN: newOpp) {
          Opportunity_Stage_History__c newOpsh = new Opportunity_Stage_History__c();
      
         //Set Values for New Opportunity
             if(oppN.StageName <> NULL && oppN.StageName <> '--None--')
             {
                newOpsh.Stage__c = oppN.StageName;
                newOpsh.Start_Date__c = date.TODAY();
                newOpsh.Opportunity__c = oppN.Id;
       
                opsh.add(newOpsh);
             }
          }
    insert opsh;
  }
 
}
Here is the code for the Test class (PS, when I leave the class as is, there is a duplication of the debug at line 44).
@isTest
public class TestOppStageHistory {
    
    //Start method 1 - insert new
    static testmethod void createInsOppData() {
        
        //Create an opportunity
        Opportunity insOpp = new Opportunity(
        Name = 'Trigger',
        StageName = 'Qualification/Prospecting',
        Probability = 1,
        CloseDate = date.TODAY() + 10,
        Type = 'New Business');
        
        //Run test
        Test.startTest();
        
        insert insOpp;

        Test.stopTest();
      
        //Test to see if opportunity stage history record was created
        List<Opportunity> insTestOpps = [Select Id, StageName FROM Opportunity WHERE Id = :insOpp.Id];
        String stval1 = insTestOpps[0].Id;   
        System.debug('Value of Id in Opportunity in record is ' + stval1);
            
        Opportunity_Stage_History__c newOppsh = [Select Id, Opportunity__c, Stage__c, Start_Date__c, Completion_Date__c 
                                                 FROM Opportunity_Stage_History__c WHERE Opportunity__c = :insOpp.Id];

        System.assertEquals(newOppsh.Stage__c, insOpp.StageName, 'Did not get the expected Stage__c value');
        System.assertEquals(newOppsh.Start_Date__c, date.TODAY(), 'Did not get the expected date today()');
        System.assertEquals(newOppsh.Completion_Date__c, NULL, 'Did not get the expected completion date value null');
        System.assertEquals(newOppsh.Opportunity__c, insOpp.Id, 'Did not get related to correct Opportunity parent record');
            
        //Do we have the right values?
        List<Opportunity_Stage_History__c> insertedShRecs= [SELECT Id, Stage__c, Start_Date__c, Completion_Date__c, Opportunity__c
                                                            FROM Opportunity_Stage_History__c WHERE Opportunity__c = : insOpp.Id ];
        System.debug('The number of recs in the list is ' + insertedShRecs.size());
        String stval2 = insertedShRecs[0].Stage__c;   
        System.debug('Value of Stage__c in record is ' + stval2);
        
        //End method 1
    }

    //Start method 2 - update existing
    static testmethod void createUpdOppData() {
        
        
        //Create an opportunity
        Opportunity insNewOpp = new Opportunity(
        Name = 'Trigger',
        StageName = 'Qualification/Prospecting',
        Probability = 1,
        CloseDate = date.TODAY() + 10,
        Type = 'New Business');
        
               
        //Test.startTest();
        insert insNewOpp;
        //Test.stopTest();

        
        String stval3 = insNewOpp.Id;   
        System.debug('Value of Id in Opportunity in record is ' + stval3); 
        
       
        
        Opportunity_Stage_History__c oldOsh = [SELECT Id, Completion_Date__c, Stage__c, Start_Date__c FROM Opportunity_Stage_History__c 
                                                WHERE stage__c = :insNewOpp.StageName AND Completion_Date__c = Null];
        
        String stval4 = oldOsh.Id;   
        System.debug('Value of Id in Old Stage History in record is ' + stval4);  
        System.assertEquals(oldOsh.Stage__c, insNewOpp.StageName);
        System.assertEquals(oldOsh.Start_Date__c, date.TODAY());
        
        
        //Run test 2 - update existing opportunity
        Opportunity updOpp = [SELECT Id, StageName FROM Opportunity WHERE Id = :insNewOpp.Id AND StageName = :insNewOpp.StageName];
        
        String stval5 = updOpp.Id;   
        System.debug('Value of Id in Opportunity in record is ' + stval5);
        
       
        Test.startTest();
        updOpp.StageName = 'Needs Analysis';
        

        update updOpp; 
        Test.stopTest();
        
        /*String stval5 = insNewOpp.StageName;
        System.debug('Value of StageName in updOpp record is '+stval5);*/
        
        //Did trigger update old stage history?
        List<Opportunity_Stage_History__c> updatedShRecs= [SELECT Id, Stage__c, Start_Date__c, Completion_Date__c, Opportunity__c
                                                           FROM Opportunity_Stage_History__c WHERE Opportunity__c = : updOpp.Id];
                                                           
        String stval6 = updatedShRecs[0].Id;   
        System.debug('Value of Id in Old Stage History in record is ' + stval6);  
        
        String stval7 = updatedShRecs[1].Id;   
        System.debug('Value of Id in New Stage History in record is ' + stval7);  
        
        System.assertEquals(updatedShRecs[0].Stage__c, oldOsh.Stage__c, 'Did not get expected Stage__c value');
        System.assertEquals(updatedShRecs[0].Completion_Date__c, date.TODAY(), 'Completion Date was not updated from null to today()');
        
        //Did trigger kick off new stage history rec?
        List<Opportunity_Stage_History__c> insertedShRecs= [SELECT Id, Stage__c, Start_Date__c, Completion_Date__c, Opportunity__c
                                                           FROM Opportunity_Stage_History__c WHERE Stage__c = : updOpp.StageName
                                                           AND Completion_Date__c = null];
        
        System.assertEquals(insertedShRecs[0].Stage__c, 'Needs Analysis', 'Did not get new value of Stage__c - Needs Analysis');
        System.assertEquals(insertedShRecs[0].Completion_Date__c, null, 'Did not get expected blank completion date');
        System.assertEquals(insertedShRecs[0].Start_Date__c, date.TODAY(), 'Did not get expected start date of today');
        


    }    
    
}


Hi folks
As a newbie to SF, can someone explain to me why nothing I do actually updates my record AND activates my trigger?
I have a trigger on Opportunity to a custom object. It creates a record based on the stage value. Trigger and Class work in sandbox.
I'm trying to get test coverage and I'm running into a roadblock.

I have managed to update a StageName value in the Test class but it didn't call the trigger. (which is supposed to update a previous custom object record and create a new one with the new StageName).
I tried putting in Test.startTest(); and Test.stopTest(); but it didn't make a difference. 
I tried creating bulk records, but only succeeded in creating multiple initial inserts, but did not manage to call the update part of the trigger.
I tried a single opportunity test record, and did update the value in StageName but did not call the trigger.
I'm still trying with a single record and have the test code below.  Please can someone explain to me what I clearly don't understand? Thanks
@isTest
public class TestOppStageHistory {

    static testmethod void createInsOppData() {
        
        Test.startTest();
        
        //Create an opportunity
        Opportunity insOpp = new Opportunity();
        insOpp.Name = 'TestUpdate';
        insOpp.StageName = 'Qualification/Prospecting';
        insOpp.Probability = 1;
        insOpp.CloseDate = date.TODAY() + 10;
        insOpp.Type = 'New Business';
        insert insOpp;

      
        //Test to see if opportunity stage history record was created
        List<Opportunity> insTestOpps = [Select Id, StageName FROM Opportunity WHERE Id = :insOpp.Id];
        String stval1 = insTestOpps[0].Id;   
        System.debug('Value of Id in Opportunity in record is ' + stval1);
            
        Opportunity_Stage_History__c newOppsh = [Select Id, Opportunity__c, Stage__c, Start_Date__c, Completion_Date__c 
                                                 FROM Opportunity_Stage_History__c WHERE Opportunity__c = :insOpp.Id];

        System.assertEquals(newOppsh.Stage__c, insOpp.StageName);
        System.assertEquals(newOppsh.Start_Date__c, date.TODAY());
        System.assertEquals(newOppsh.Completion_Date__c, NULL);
        System.assertEquals(newOppsh.Opportunity__c, insOpp.Id);
            
        //Do we have the right values?
        List<Opportunity_Stage_History__c> insertedShRecs= [SELECT Id, Stage__c, Start_Date__c, Completion_Date__c, Opportunity__c
                                                            FROM Opportunity_Stage_History__c WHERE Opportunity__c = : insOpp.Id ];
        System.debug('The number of recs in the list is ' + insertedShRecs.size());
        String stval2 = insertedShRecs[0].Stage__c;   
        System.debug('Value of Stage__c in record is ' + stval2);
        

        //update StageName on opportunity

        Opportunity updOpp = [SELECT Id, StageName, Probability FROM Opportunity WHERE Id= :insOpp.Id];
        String stval3 = updOpp.Id;
        System.debug('Value of Id in updOpp record is ' + stval3); 
        String stval4 = updOpp.StageName;
        System.debug('Value of StageName in updOpp record is '+stval4);
        
        updOpp.StageName = 'Needs Analysis';
        updOpp.Probability = 25;
        //update.updOpp(); - can't do this. Do I need to map something? Do I need to break to two methods - how to use same record?
        
        Test.stopTest();
        
    }
    
}

Hi
Having some trouble. Wrote a trigger/class to post info from a new case to the lead object. I cannot get a test class to insert a case.

The above is the error message with 'radioCaseToLead: execution of AfterInsert'

The line of code to referred to as a problem is 'insert newleads;'

Any insight would be great.
Hi folks
Still new but getting there bit by bit. I have this trigger, It is supposed to update certain specific fields based on different picklist values. I'm thinking it's not bulkified like it should be. I'm thinking (but could be wrong) I need to make a set/list and update the values of the set before letting it go ahead and do it's stuff, so I can do everything with one update.  Here's the trigger.

trigger updateAppNum on CustomObject__c (before insert, before update) {

   //Get set of Incomplete ids
    List<Integer> appUps = new List<Integer>();
   
    for(CustomObject__c ap :trigger.new) {
        if (ap.Status__c == 'Incomplete') {
          ap.AppInc__c = 1;
        }
        if (ap.Status__c == 'Complete - Pending Review') {
          ap.AppCompP__c = 1;
        }
        if (ap.Status__c == 'Complete - Decision Made') {
          ap.AppCompD__c = 1;
        }
        if (ap.Status__c == 'Deferred') {
          ap.AppDef__c = 1;
        }
        if (ap.Status__c == 'Withdrawn') {
          ap.AppW__c = 1;
        }
    }

}
Hi
As a newbie, I wonder if you could help me with this issue:
I'm trying to write a trigger that populates a number of fields on the contact object based on different picklist values in the same child object. I need a trigger as there are not enough roll-up summary fields.  There will be thousands in the counts of each value.
Here is what I am attempting to do:

SELECT Id, Picklist_value__c FROM ChildObject__c WHERE Picklist_Value__c ='value a'
Count the total of Child records put the COUNT number into a 'Count 'value a' Roll-up' field on the Contact Object.
SELECT Id, Picklist_value__c FROM ChildObject__c WHERE Picklist_Value__c ='value b'
Count the total of Child records put the COUNT number into a 'Count 'value b' Roll-up' field on the Contact Object.
SELECT Id, Picklist_value__c FROM ChildObject__c WHERE Picklist_Value__c ='value c'
Count the total of Child records put the COUNT number into a 'Count 'value c' Roll-up' field on the Contact Object.
SELECT Id, Picklist_value__c FROM ChildObject__c WHERE Picklist_Value__c ='value d'
Count the total of Child records put the COUNT number into a 'Count 'value d' Roll-up' field on the Contact Object.

Thanks in advance for any help