Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I have built a Trigger on the opportunity, my query looks at the Opportunity and it's child Service_Contract__r and validates the the child size is not greater than 0.

for(Opportunity opp:Trigger.new){   //  For Loop that removes Opportunities that already had PO In and only has updated Opportunitues with PO In
        if(Trigger.oldMap.get(opp.id).stageName != 'PO In (100%)' && opp.stageName == 'PO In (100%)' && opp.recordTypeId == oppRecordID)      
            oppIds.add(opp.id);
      }   
      List<Opportunity> oppsFromDb =    [   SELECT
                                            id,
                                           (SELECT id FROM Service_Contracts__r WHERE isDeleted = FALSE),                                                                           
                                            FROM
                                            Opportunity 
                                            WHERE
                                            id IN:oppIds
                                                                    ];                                              
        if(Trigger.isBefore){   // Error checking, will verify that a contract child does not exist, will also verify that if any variables are null. 
            for(Opportunity verifyOpp: oppsFromDB){             
                if(verifyOpp.service_Contracts__r.size() > 0)                               
                    trigger.newMap.get(verifyOpp.Id).addError('A Service Contract already exists, cannot have more than one contract '+ verifyOpp.service_Contracts__r.size()+ ' '+ verifyOpp.service_Contracts__r.get(0).id);

In the live server, after deleting a Service contract and going through the process again it gives me the addError that the size > 0 (it says there is 1 that exists and I pulled it's id and when I tried to look at it on SF it said it did not exist.

Do I need to do something like a deconstructor and delete all my lists after they are done being used? I don't understand how it is still getting a size greater than 0. when I do an 'Execute Anonymous' the size comes up as 0 ... Any thoughts?

(Small note, it ran fine in my sandboxes. Only errors on the live.)

UPDATE Still not working, I tried to do oppsFromDb.clear() (and so on with the other lists) at the end of the trigger. Still no luck, very puzzling to me. As Well from the trigger I pulled up the field of isDeleted and it returned FALSE, however I still cannot see this Service Contract.

Here is the entire Trigger:

trigger trig_Opportunity_CreateServContract on Opportunity (before update, after update) {
      //Get the record type required
     ID oppRecordID;    //the Opportunity Hyperstream record ID 
     ID sCRecordID;  //the Service Contract Hyperstream record ID
     list<RecordType> recHyperStream = [ SELECT 
                                           description, id, sObjectType, businessProcessId 
                                         FROM 
                                           RecordType 
                                         WHERE 
                                           developerName = 'someValue' 
                                                                        ];   
      for(RecordType r: recHyperStream){    //for loop created to find which Record type is for the opportunity and Service Contract
        if(r.sObjectType=='Opportunity')
            oppRecordID= r.id;
        else if(r.sObjectType == 'ServiceContract') //only two options, if the SobjectType is not Opportunity then it is ServiceContract!
            sCRecordID = r.id;  
      }

      List<id> oppIds = new List<id>(); //Get the Id of all new opportunity updates
      List<ServiceContract> sContract = new List<ServiceContract>(); // List that will contain all the new Service Contracts that need to be added

      for(Opportunity opp:Trigger.new){ //  For Loop that removes Opportunities that already had PO In and only has updated Opportunitues with PO In
        if(Trigger.oldMap.get(opp.id).stageName != 'PO In (100%)' && opp.stageName == 'PO In (100%)' && opp.recordTypeId == oppRecordID)      
            oppIds.add(opp.id);
      }   
      List<Opportunity> oppsFromDb = [ SELECT
                                        id, stageName, name, accountid, owner__c, end_user_contact__c, recordTypeId, ownerId,Opportunity_Contact__c,
                                       (SELECT id FROM Service_Contracts__r WHERE isDeleted = FALSE), 
                                       (SELECT id From quotes WHERE IsSyncing= TRUE)
                                      FROM
                                        Opportunity 
                                      WHERE
                                        id IN:oppIds
                                       ];                                               
        if(Trigger.isBefore){   // Error checking, will verify that a contract child does not exist, will also verify that if any variables are null. 
            for(Opportunity verifyOpp: oppsFromDB){             
                if(verifyOpp.service_Contracts__r.size() > 0)                               
                    trigger.newMap.get(verifyOpp.Id).addError('A Service Contract already exists, cannot have more than one contract '+ verifyOpp.service_Contracts__r.size()+ ' '+ verifyOpp.service_Contracts__r.get(0).id);                              
                else if(verifyOpp.quotes.size() == 0 || verifyOpp.quotes.size()== null)             
                    trigger.newMap.get(verifyOpp.Id).addError('A quote is either not synced or does not exist, please verify that the quote is correct.');                                                      
                else if(verifyOpp.quotes.get(0).Agreement_Term__c == '' ||verifyOpp.quotes.get(0).Agreement_Term__c ==null) //Verify if Agreement Term is not null in Synced Quote
                    trigger.newMap.get(verifyOpp.Id).addError('The service agreement is not set in the quote, please set it before changing the stage.');
                else if(verifyOpp.quotes.get(0).Commencement_Date__c == null) //Verify if Commencement Date is not null
                    trigger.newMap.get(verifyOpp.Id).addError('The service commencement date has not been chosen, please pick a commencement date.');   
                //Need to add more error checking.          
            }       
        }   


        if(Trigger.isAfter){
            for(Opportunity goodOpps: oppsFromDb){                                  
                SContract.add(new ServiceContract( name = goodOpps.name, accountId = goodOpps.accountId,
                        recordTypeId = sCRecordID, opportunity__c = goodOpps.id,Agreement_Term__c = goodOpps.quotes.get(0).Agreement_Term__c ,  
                        ownerId = goodOpps.OwnerId, Quote__c = goodOpps.quotes.get(0).id, ContactId = goodOpps.Opportunity_Contact__c,
                        Commencement_Date__c = goodOpps.quotes.get(0).Commencement_Date__c, Set_Up_Fee_Totals__c = goodOpps.quotes.get(0).Set_Up_Fee_Totals__c,
                        Data_Transfer_Overage_Rate__c = goodOpps.quotes.get(0).Data_Transfer_Overage__c, Entitled_Transcoding__c= goodOpps.quotes.get(0).Entitled_Transcoding__c, Transcoding_Overage_Rate__c= goodOpps.quotes.get(0).Transcoding_Overage__c,
                        Entitled_Media_Storage__c= goodOpps.quotes.get(0).Entitled_Media_Storage__c, Entitled_Media_Reqest__c= goodOpps.quotes.get(0).Entitled_Media_Reqest__c, 
                        Entitled_Media_Object__c= goodOpps.quotes.get(0).Entitled_Media_Object__c, Entitled_Data_Transfer__c= goodOpps.quotes.get(0).Entitled_Data_Transfer__c, Equipment_Totals__c= goodOpps.quotes.get(0).Equipment_Totals__c,
                        Monthly_Recurring_Totals__c= goodOpps.quotes.get(0).Monthly_Recurring_Totals__c, Media_Storage_Overage_Rate__c= goodOpps.quotes.get(0).Media_Storage_Overage__c, 
                        Media_Request_Overage_Rate__c= goodOpps.quotes.get(0).Media_Request_Storage_Overage__c, Media_Object_Overage_Rate__c= goodOpps.quotes.get(0).Media_Object_Overage__c));
            }
            insert sContract;   //add all the Service Contracts
            //clearing lists
            oppIds.clear();
            sContract.clear();
            oppsFromDb.clear();
        }       
}// END OF TRIGGER 
share|improve this question
    
How are you testing this? Are you testing this for a single opportunity record or multiple opportunities? If you are testing for multiple opportunities, might be a case that other opportunities have child record and hence you get the error. –  Shailesh Deshpande Feb 26 '13 at 18:25
    
Hi Shailesh, I am only testing with a single opportunity, and I think even if it were to have multiple opportunities I would be going through different service agreement lists no? –  jnoel10 Feb 26 '13 at 18:28
    
No. If there is atleast one opportunity with service contract, then your trigger will throw the error(yes it will mention which opp. Is related, but still the error will be thrown). Anyways, thats not the case here as you are testing single opportunity currently. I am sure you must have done this, but if not then other things that are worth checking is if you have any additional triggers/field updates written on insert of service contracts which are updating the opportunity again. –  Shailesh Deshpande Feb 26 '13 at 19:39
    
Thanks for the input Shailesh, for the moment there are no triggers in service contract. And since my list is (i imagine a 2 dimensional list) where I look at the current Opportunity.ServiceContract__r.size() it would only show the information regarding to the location of the one opportunity. –  jnoel10 Feb 26 '13 at 19:44
add comment

1 Answer

Hey Can you post the whole trigger body pr atleast the events associated ? Probably its happening because you are trying to access child records from Before trigger.

PS : In before event of trigger changes are not committed to the db and hence when you will query the db you will find unchanged or uncommitted values.

For further details go through this link http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_context_variables_considerations.htm

Update Also can you please post the following result by running the following code in developer console?

List<Opportunity> oppsFromDb = [ SELECT
                                        id, stageName, name, accountid, owner__c, end_user_contact__c, recordTypeId, ownerId,Opportunity_Contact__c,
                                       (SELECT id FROM Service_Contracts__r WHERE isDeleted = FALSE), 
                                       (SELECT id From quotes WHERE IsSyncing= TRUE)
                                      FROM
                                        Opportunity 
                                      WHERE
                                        id :<Your RecordId>
                                       ];    

for(Opportunity opp : oppsFromDb ){ System.debug('RecId:'+opp.Id+' SIZE: '+opp.service_Contracts__r.size()); }

Since you have the record Id just replace the same.

share|improve this answer
    
Thanks Avidev9, I have added the entire trigger –  jnoel10 Feb 26 '13 at 17:59
    
I also agree with you on the before trigger information, I am just reading the size and not changing anything though. It is like it is referencing a very old map that still has the information of two days ago. –  jnoel10 Feb 26 '13 at 18:17
    
Ok I thought it was the same transaction!. If its showing two days old information trigger context wont help you :( . Anyways it happening for every record? or any specific records? –  Avidev9 Feb 26 '13 at 18:33
    
Well, if I try and add a service Contract when one did not exist before it works. I have only tried it on one Opportunity so far where I had to delete the sContract and this is where it is failing. I fear trying to do it on any other as this is the live server. On the test server it is running fine –  jnoel10 Feb 26 '13 at 18:50
    
@jnoel10 update the answer please post the result –  Avidev9 Feb 27 '13 at 11:55
show 4 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.