In a trigger for Cases, I need to know how many opportunities relate to each of those cases, through a lookup in the Case, that is Case.Oportunidade__c . This is the code:

    // this at the start of the trigger handler constructor, to create newMap
    private Map<Id, Case> newMap;
    this.newMap = (Map<Id, case>) Trigger.newMap;
    // my method

    private void updateCountProvisioningCases(){
        Map<String, List<Case>> provisioningOppCasesMap = new Map<String, List<Case>>();
        for(Case cs : newMap.values()){
            if(cs.Oportunidade__c != null){ // lookup to Opportunity

                    List<Case> casesList = new List<Case>();
                    provisioningOppCasesMap.put(cs.Oportunidade__c, casesList);
                } else {
        for(String k: provisioningOppCasesMap.keySet()){
           System.debug('opp Id: ' + k);
        for(List<Case> csl : provisioningOppCasesMap.values()){   
           System.debug('csl: ' + csl);
           for(Case cs: csl) System.debug('cs: ' + cs);
        // Map<String, List<Case>> provisioningOppCasesMap = new Map<String, List<Case>>();
        // String == opportunity.id
        // Going to count cases related with this id, trhough a lookup in the case 
        List<Opportunity> oppsUpd = new List<Opportunity>(); 
        for(String oppId : provisioningOppCasesMap.keySet()){
            Integer caseCount = 0;
            Opportunity opp = new Opportunity(id = oppId);
            opp.provisioningCasesCount__c = provisioningOppCasesMap.get(oppId).size(); 
            for(Case cs : provisioningOppCasesMap.get(oppId)){
                System.debug('cs: ' + cs);
        update oppsUpd;

        for(Opportunity op : oppsUpd){
           System.debug('op: ' + op);
           System.debug('op: ' + op.provisioningCasesCount__c);

So after that, i loop the Cases of each opp, count them, and update a numeric field in the opportunity. Ah, also cant do this with a rollup field on the opp, because i will add a condition to only find a specific case recordtype

22:31:25:865 USER_DEBUG [161]|DEBUG|op: Opportunity:{Id=0060E00000dICApQAO, provisioningCasesCount__c=1}

debugging provisioningOppCasesMap:

enter image description here

I can see Opportunity '0060E00000dICApQAO' has 3 related Cases the in UI, but in of them of closed, so i think its filtered in the view

Classic UI

and check with SOQL:

select id, Oportunidade__c, Oportunidade__r.provisioningCasesCount__c from Case where Oportunidade__c != null and Oportunidade__c = '0060E00000dICApQAO'

enter image description here


If I'm understanding this correctly, you have a trigger on the Case object. So what you are seeing is consistent with what would happen if you updated only one Case record (the one with Id ending QAH). Because Trigger.new is what you are iterating over, and if you're only updating the one case, it'll only iterate over that record.

Here, where you say 'my 2 cases' - it isn't two cases, it's just one. You have two separate System.debug('cs: ' + cs); lines consecutively which is why you have two debug lines that look the same.

enter image description here

If you are updating all three cases you would need to do this in a batch update where all three cases are being processed in the same transaction to get the results I think you are expecting (because if all three cases were updated in the same transaction, you would get a list of size() = 3 in your provisioningOppCasesMap).

So unless your cases are updated in batch, (and then you would need to ensure all the cases associated with an Opp are all processed in the same batch) you are only ever going to get a count of 1.

You've only ever got one case in your hands the whole time.

So what to do? When a Case is associated with an Opportunity, why not increment a count on that Opportunity? And if the case is removed from the Opp, decrement the count.

  • About those releated lines: wow that my rookie mistake of the week! If an Opportunity has N related cases, regardless of how many are updated in a given proccess, all of them must be counted, and that value save in that opportunity field. I just don't understand why i need to do it in a batch, and not a regular update oppsUpd; Black magic Apex? – Luis Aguiar Mar 7 at 13:20
  • 1
    When you update a Case record, trigger.new only holds the record that is being updated. No other Case records. Nowhere in your code are you querying the other case records that are associated with your Opportunity. So it won't be able to count them... All triggers have to be written in a 'bulkified' way, which is that it should expect a batch of records to come through. In that circumstance, trigger.new will contain several case records. Does that make sense? I'm afraid your approach won't work unless you issue a query on the Case object constrained by the OppId... – edralph Mar 7 at 13:27
  • The code is too long in 44 chars to post, so pseudocode after the first loop in newMap.values(): 1. query opportunities in that .keySet() 2. query all cases with Oportunidade__c in :provisioningOppCasesMap.keySet() 3. loop the opportunities, and in this scope, i initialize a counter of cases 4. and inside that loop, another of cases, where Oportunidade__c in :provisioningOppCasesMap.keySet() 5. update map of opp: update oppsUpd.values(); btw, this method fires on a after case update trigger event – Luis Aguiar Mar 7 at 18:20
  • 1
    ok, i get it now: i was updating the values in the second loop, but wasnt adding this to the updating list: Opportunity opp = new Opportunity(id = oppId);. Solved now!. Your tip took me in the right direction. Thanks! – Luis Aguiar Mar 7 at 18:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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