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
sales4cesales4ce 

Opportunity Line Items being attached to Service Agreements

Hi,

 

I have Opportunity and Service Agreement being related via Look up(on Service Agreement).

Upon changing the stage of opportunity to "Won" , i want to create a New Service agreement and then carry over any Opportunity Line Items (Products) associated with that opportunity to Service Line agreements related to the Service agreement thats being created.

 

Can i accomplish this by writing one trigger on Opportunity itself or should i write 2 triggers, one on opportunity that would create the Service agreement and another on Service agreement that would again get the Opportunity products associated with that Service agreement.

 

Any help/pointers on this is highly appreciated.

 

I was able to create service agreements from the Opportunity, but was unsuccessful in adding the Opportunity Line Items within the same trigger.

 

 

trigger createAgreement on Opportunity (before update) {
List<ServiceContract> newServicecontract=New List<ServiceContract>();
Set<Id> oppIds=New Set<Id>();
for(Opportunity op : Trigger.New){
if(op.StageName=='Won' && op.workflow_Update__c==false && Trigger.oldMap.get(op.Id).StageName!='Won')
oppIds.Add(op.Id);
}
List<Opportunity> oppty=[Select Id,Name,AccountId,CloseDate,Contract_Activation_Date__c From Opportunity Where Id IN:oppIds];
System.Debug('List Size=='+oppty.size());
for(Integer i=0;i<oppty.size();i++){
ServiceContract sc=new ServiceContract();
String name='Service Contract For-';
sc.AccountId=oppty[i].AccountId;
sc.Name=name+oppty[i].Name;
sc.Opportunity__c=oppty[i].Id;
newServicecontract.Add(sc);
}
System.debug('Agreement Size=='+newServicecontract.size());
Database.insert(newServicecontract);
}

 

 

 

 

Thanks,

Sales4ce

dmchengdmcheng

You should be able to do it within the opp trigger.  You'll need to do a SOQL relationship query to pull the opp line items for all the opps into a map.  After you insert the service agreement records and have their new IDs, you  loop through those records and create the service line item records based on the opp line item map.

 

If you have not done SOQL relationship queries before, here is the doc:

http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_soql_relationships.htm

 

BTW - when posting code, you should cick the "C" icon in the edit window so it you can post in a fixed-space font that's easier to read.

sales4cesales4ce

Thanks for your reply!

Should it be this way:

 

Map<Id, Opportunity> Oppty=New Map<Id, Opportunity>([

SELECT Id, Name, (SELECT Quantity, ListPrice,
  PriceBookEntry.UnitPrice, PricebookEntry.Name,
  PricebookEntry.product2.Family FROM OpportunityLineItems)
  FROM Opportunity  ]);

 

Also, after the insertion of the service agreements, to get the Ids, is the order preserved?

How can i loop through the inserted recordIds?

 

Thanks,

Sales4ce

dmchengdmcheng

Yes that is the correct format.

 

Loop through the inserted records like this:

 

for(ServiceContract sc : newServicecontract) {

}

 

Remember that the newServicecontract list contains IDs after you have inserted it.

sales4cesales4ce

Thanks for the help!

But, i am unable to get the line items from the map.It is raising an error saying illegal assignment.

Ami doing anything wrong? can you help me out here.

 

trigger createServiceContract on Opportunity (before update) {
    
    
    List<ServiceContract> newServicecontract=New List<ServiceContract>();
    
    Set<Id> oppIds=New Set<Id>();
    
    for(Opportunity op : Trigger.New){
        
        if(op.StageName=='Won' && op.workflow_Update__c==false && Trigger.oldMap.get(op.Id).StageName!='Won')
            oppIds.Add(op.Id);
    }
    
    List<Opportunity> oppty=[Select Id,Name,AccountId,CloseDate,Contract_Activation_Date__c From Opportunity Where Id IN:oppIds]; 
    
    Map<Id, Opportunity> oppty1=New Map<Id, Opportunity>([SELECT Amount, Id, Name, (SELECT Quantity, ListPrice,
  PriceBookEntry.UnitPrice, PricebookEntry.Name,
  PricebookEntry.product2.Family FROM OpportunityLineItems)
  FROM Opportunity Where Id IN:oppIds]);  
 
    System.Debug('List Size=='+oppty.size());
    for(Integer i=0;i<oppty.size();i++){
        
        
        ServiceContract sc=new ServiceContract();
        String name='Service Contract For-';        
        sc.AccountId=oppty[i].AccountId;
        sc.Name=name+oppty[i].Name;        
        sc.Opportunity__c=oppty[i].Id;        
        newServicecontract.Add(sc);
        
    }
    System.debug('Entitlement Size=='+newServicecontract.size());
    Database.insert(newServicecontract);
    
    List<ContractLineItem> newContractLineItems=New List<ContractLineItem>();
    
    for(ServiceContract sc : newServiceContract){
    
     List<contractLineItem> cli;
cli=oppty1.get(sc.Opportunity__c);
} }

 

Thanks,

Sales4ce

dmchengdmcheng

Your oppty1 map has to be defined for a List of opportunities since the select returns a list.

Map<Id, Opportunity[]> oppty1=New Map<Id, Opportunity[]>([SELECT Amount ... blah blah bah

The oppty1.get method returns a list of opportunities, so that's why your contract line item assignment fails.  I imagine you'll have to construct your contract line item record like this:

new ContractLineItem(Name = oppty1.get(sc.Opportunity__c).yourfield, blah blah blah

Itayb34Itayb34

Can you publish your revised code?