+ Start a Discussion
Ronaldo CostaRonaldo Costa 

trigger as roll-up summary

Hello all, I have the following code to roll-up summary products name to an opportunity text-long field, I need a summary of purchased products separated by commas.
Everything runs good with no errors, however I get no results, nothing happens, can you please take a look and help me?

Trigger:
trigger OppProductsTrigger on OpportunityLineItem (after delete, after insert, after update) {

    // fires after both insert and update
    if((Trigger.isInsert || Trigger.isUpdate) && Trigger.isAfter){

      // find the ids of all opps that were affected
      Set<Id> oppIds = new Set<Id>();
      for (OpportunityLineItem ar : [select Id, name, OpportunityId from OpportunityLineItem 
        where Id IN :Trigger.newMap.keySet()])
        oppIds.add(ar.OpportunityId);

      // process the opps  
      OppProductsTriggerHandler.ProcessProductsAsync(oppIds);


    // fires when records are deleted. may want to do undelete also?
    } else if(Trigger.isDelete && Trigger.isAfter){

      // find the ids of all opps that were affected
      Set<Id> oppIds = new Set<Id>();
      for (ID id : Trigger.oldMap.keySet())
        oppIds.add(Trigger.oldMap.get(id).OpportunityId);

      // process the opps
      OppProductsTriggerHandler.ProcessProductsAsync(oppIds);

    }

  }

Class: 
public with sharing class OppProductsTriggerHandler {

  @future 
  public static void ProcessProductsAsync(Set<ID> oppIds){

    // holds a map of the opp id and comma separated products to build
    Map<Id, String> oppProductMap = new Map<Id, String>();

    // get ALL of the products for all affected opps so we can build
    List<OpportunityLineItem> oppProducts = [select id, name, OpportunityId 
      from OpportunityLineItem 
      where OpportunityId IN :oppIds order by Name];

    for (OpportunityLineItem ar : oppProducts) {
      if (!oppProductMap.containsKey(ar.OpportunityId)) {
        // if the key (opp) doesn't exist, add it with product name
        oppProductMap.put(ar.OpportunityId,ar.Name);
      } else {
        // if the key (opp) already exist, add ", product-name"
        oppProductMap.put(ar.OpportunityId,oppProductMap.get(ar.OpportunityId) + 
          ', ' + ar.Name);
      }
    }

    // get the opps that were affected
    List<Opportunity> opps = [select id from Opportunity where Id IN :oppIds];

    // add the comma separated list of regions
    for (Opportunity a : opps)
      a.Products_Purchased__c = oppProductMap.get(a.id);

    // update the opps
    update opps;

  }  

}

Thank you!
Ron
Best Answer chosen by Ronaldo Costa
kirubakaran viswanathankirubakaran viswanathan
Hi Ron,

Try changing the FOR loop like below, by this you may avoid the Governor limits of hitting the DML exception.
List<Opportunity> Opps1 = new List<Opportunity>();

// add the comma separated list of regions
    for (Opportunity a : opps)
{
      Opportunity op1 = new Opportunity();

      op1.Products_Purchased__c = oppProductMap.get(a.id);
      op1.id = a.id;
      Opps1.add(op1);

}
    // update the opps
    update opps1;
Please let us know if this resolves the issue.
 

All Answers

Niket SFNiket SF
You are firing a future job might be possible something is failing in it ? 

For testing can we add send email function ? to your personal id ?


Something like this ?

public with sharing class OppProductsTriggerHandler {

  @future 
  public static void ProcessProductsAsync(Set<ID> oppIds){

    // holds a map of the opp id and comma separated products to build
    Map<Id, String> oppProductMap = new Map<Id, String>();

    // get ALL of the products for all affected opps so we can build
    List<OpportunityLineItem> oppProducts = [select id, name, OpportunityId 
      from OpportunityLineItem 
      where OpportunityId IN :oppIds order by Name];

    for (OpportunityLineItem ar : oppProducts) {
      if (!oppProductMap.containsKey(ar.OpportunityId)) {
        // if the key (opp) doesn't exist, add it with product name
        oppProductMap.put(ar.OpportunityId,ar.Name);
      } else {
        // if the key (opp) already exist, add ", product-name"
        oppProductMap.put(ar.OpportunityId,oppProductMap.get(ar.OpportunityId) + 
          ', ' + ar.Name);
      }
    }

    // get the opps that were affected
    List<Opportunity> opps = [select id from Opportunity where Id IN :oppIds];

    // add the comma separated list of regions
    for (Opportunity a : opps)
      a.Products_Purchased__c = oppProductMap.get(a.id);

    // update the opps
    List<Database.SaveResult> lstdbResult = database.update(opps);
    
    Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
    message.toAddresses = new String[] { 'yoouremail@adderss.com' };
    message.subject = 'Future job is working';
    message.plainTextBody = 'Future job is firing';
    Messaging.SingleEmailMessage[] messages = new List<Messaging.SingleEmailMessage> {message};
             Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);
    if (results[0].success) {
        System.debug('The email was sent successfully.');
    } else {
        System.debug('The email failed to send: '
              + lstdbResult[0]);
    }

  }  
}
Ronaldo CostaRonaldo Costa
Thank you, please see below.

Class.AccountRegionTriggerHandler.ProcessRegionsAsync: line 17, column 1
16:28:43.14 (45940892)|FATAL_ERROR|System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: OpportunityLineItem.Name
kirubakaran viswanathankirubakaran viswanathan
Hi Ron,

Try changing the FOR loop like below, by this you may avoid the Governor limits of hitting the DML exception.
List<Opportunity> Opps1 = new List<Opportunity>();

// add the comma separated list of regions
    for (Opportunity a : opps)
{
      Opportunity op1 = new Opportunity();

      op1.Products_Purchased__c = oppProductMap.get(a.id);
      op1.id = a.id;
      Opps1.add(op1);

}
    // update the opps
    update opps1;
Please let us know if this resolves the issue.
 
This was selected as the best answer