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
sieb4mesieb4me 

need help on following code

Hi,

I' have following code, however it always pulls the first cases account value of [0],  and always updating opportunities of that account on all the cases. in the setcaseid.

 

How do i get account from their respective cases from setcaseid instead of it pulling always first [0].

 

Thanks

 

 

lstCase = [Select Id, AccountId,Status from Case where Id = :setCaseId];

if(lstCase[0].AccountId != null){
accId = lstCase[0].AccountId;
lstOppty = [Select Id, Name, Probability, Amount from Opportunity
where AccountId =: accId
AND StageName IN ('Qualification','Prospecting')
AND CloseDate = THIS_QUARTER
AND CloseDate <= NEXT_QUARTER];
}

CountOpportunity = lstOppty.size();

for(Opportunity opp: lstOppty){

if(opp.Amount != null){
SLic += opp.Amount*conRate;
}

}

List<Case> cs = new List<Case>();
if (!setCaseId.ISEMPTY()){
for(Case c: lstcase){
if(c.Status !=null){

c.SumLicence__c = SLic;
c.Total_opp__c = CountOpportunity;
//c.Status = 'Working';
cs.add(c);
}

}
Update cs;

Best Answer chosen by Admin (Salesforce Developers) 
ForcepowerForcepower

ok - try this with your modifications:

 

Integer oppCount = 0;
Integer caseIndex = 0;
for (Opportunity opp: lstOppty){
    String thisAcctId = opp.AccountId;
    if (thisAcctId != previousAcctId) {
        if (previousAcctId != '') {
            // skip past any non matching account id's - should not be any
            while ((caseIndex < lstCase.size()) && (lstCase[caseIndex].AccountId != previousAcctId))
                caseIndex++;
            while ((caseIndex < lstCase.size()) && (lstCase[caseIndex].AccountId == previousAcctId)) {
                Case c = lstCase[caseIndex];
                if ((c != null) && (c.Status !=null)) {
                
                    c.SumLicence__c = SLic;
                    c.Total_opp__c = oppCount;
                //c.Status = 'Working';
                    cs.add(c);            
                }
                caseIndex++;
            }
        }
        previousAcctId = thisAcctId;
        SLic = 0;
        oppCount = 0;
        
    }
    oppCount++;

    if(opp.Amount != null){
        SLic += opp.Amount*conRate;
    }

}
// handle the opportunities for the last account
            while ((caseIndex < lstCase.size()) && (lstCase[caseIndex].AccountId == previousAcctId)) {
                Case c = lstCase[caseIndex];
                if ((c != null) && (c.Status !=null)) {
                
                    c.SumLicence__c = SLic;
                    c.Total_opp__c = oppCount;
                //c.Status = 'Working';
                    cs.add(c);            
                }
                caseIndex++;
            }

Update cs;
}       
}

All Answers

ForcepowerForcepower

Sieb4me,

 

In case you get multiple cases for the same account id, do you put the same info in terms of the aggregation you're doing with opportunities?

 

Ram

ForcepowerForcepower

Never mind - you have it as a set (based on your name for the container, setCaseId) - so should be unique.

 

Try this. It does look different from your original - so you'd need to digest it and see if it's doing what you intend it to do

 

List<Case> lstCase = [Select Id, AccountId,Status from Case where Id IN :setCaseId and AccountId != null
order by AccountId];
List<Id> accountIdList = new List<Id>();
Map<Id, Case> account2CaseMap = new Map<Id, Case>();
List<Case> cs = new List<Case>();

 

// collect the account id's into a list and create a map of account id to case
for (Case case1 : lstCase) {he
    accountIdList.add(case1.AccountId);
    account2CaseMap.put(case1.AccountId, case1);
}

 

// get opportunities for all accounts of interest
lstOppty = [Select Id, Name, Probability, Amount from Opportunity
where AccountId in : accountIdList
AND StageName IN ('Qualification','Prospecting')
AND CloseDate = THIS_QUARTER
AND CloseDate <= NEXT_QUARTER order by AccountId];


//CountOpportunity = lstOppty.size();
String previousAcctId = '';
SLic = 0;
//Decimal conRate = ?
Integer oppCount = 0;

// iterate through opportunities grouping by account id
for (Opportunity opp: lstOppty){
    if (opp.AccountId != previousAcctId) {
        if (previousAcctId != '') {
            Case c =  account2CaseMap.get(previousAcctId);
            if ((c != null) && (c.Status !=null)) {
            
                c.SumLicence__c = SLic;
                c.Total_opp__c = oppCount;
            //c.Status = 'Working';
                cs.add(c);            
            }
        }

        // initialize for the next account
        previousAcctId = opp.AccountId;
        SLic = 0;
        oppCount = 0;
        
    }
    oppCount++;

    if(opp.Amount != null){
        SLic += opp.Amount*conRate;
    }

}
// handle the opportunities for the last account
if (previousAcctId != '') {
    Case c =  account2CaseMap.get(previousAcctId);
    if ((c != null) && (c.Status !=null)) {
            
        c.SumLicence__c = SLic;
        c.Total_opp__c = oppCount;
        cs.add(c);        

    }   
}

Update cs;
}

 

 

Hope that helps.

Ram

sieb4mesieb4me

yes thats true, since we are calculating all oppportunites for that account (acocunt is on case).

sieb4mesieb4me
Thanks Ram.
It errors our while running at line 71
if (opp.AccountId != previousAcctId) {

18:47:06:103 EXCEPTION_THROWN [71]|System.StringException: Invalid id:

then i have some value 123 and
got
18:47:06:103 EXCEPTION_THROWN [71]|System.StringException: Invalid id: 123
ForcepowerForcepower

Sieb4me,

 

Try this: changes in bold

 

    String thisAcctId = opp.AccountId;
    if (thisAcctId != previousAcctId) {
        if (previousAcctId != '') {
            Case c =  account2CaseMap.get(previousAcctId);
            if ((c != null) && (c.Status !=null)) {
            
                c.SumLicence__c = SLic;
                c.Total_opp__c = oppCount;
            //c.Status = 'Working';
                cs.add(c);            
            }
        }
        previousAcctId = thisAcctId;
        SLic = 0;
        oppCount = 0;
        
    }

 

sieb4mesieb4me
Thanks Ram.
I actually fixed your old code and made sure that previous id is set as Id and '' as null and changed wherever needed to null and then code ran fine.

I noticed code works good and properly updates based on account id, however problem is here, it only updates once for each account meaning i had 2 cases for accout A and 2 for acct b and both had opportunities, it only updated 1 case with accout A and 1 case with account B and did not update other cases, why is that?
thanks
ForcepowerForcepower

ok - try this with your modifications:

 

Integer oppCount = 0;
Integer caseIndex = 0;
for (Opportunity opp: lstOppty){
    String thisAcctId = opp.AccountId;
    if (thisAcctId != previousAcctId) {
        if (previousAcctId != '') {
            // skip past any non matching account id's - should not be any
            while ((caseIndex < lstCase.size()) && (lstCase[caseIndex].AccountId != previousAcctId))
                caseIndex++;
            while ((caseIndex < lstCase.size()) && (lstCase[caseIndex].AccountId == previousAcctId)) {
                Case c = lstCase[caseIndex];
                if ((c != null) && (c.Status !=null)) {
                
                    c.SumLicence__c = SLic;
                    c.Total_opp__c = oppCount;
                //c.Status = 'Working';
                    cs.add(c);            
                }
                caseIndex++;
            }
        }
        previousAcctId = thisAcctId;
        SLic = 0;
        oppCount = 0;
        
    }
    oppCount++;

    if(opp.Amount != null){
        SLic += opp.Amount*conRate;
    }

}
// handle the opportunities for the last account
            while ((caseIndex < lstCase.size()) && (lstCase[caseIndex].AccountId == previousAcctId)) {
                Case c = lstCase[caseIndex];
                if ((c != null) && (c.Status !=null)) {
                
                    c.SumLicence__c = SLic;
                    c.Total_opp__c = oppCount;
                //c.Status = 'Working';
                    cs.add(c);            
                }
                caseIndex++;
            }

Update cs;
}       
}

This was selected as the best answer
sieb4mesieb4me
Thanks so much Ram. This solved the problem and its working as expected. I will review the code and try to undetstand it.

Thanks a lot!
ForcepowerForcepower
You're very welcome, Sieb4me. Glad to hear it.
Best,
Ram
sieb4mesieb4me
Ram,
I am trying to understand code and little confused.
Can you please explain me how it

I have following questions.
Initially when account isnull it sets case field values for oppt to 0, is that right, since calculation isdone for oppt variables after setting case field values, so in the next round it updates them with proper calculated values?

Also i noticed that we are incrementing the caseindex so wont it skip the case after evaluating 1st time when it comes to lets say 2nd opportunity in the loop?

Code is working fine but i am still confused on the above 2 questions.

Also one last question i had was for opportunities for the last account, we are setting case fields but calulation is not there
which is SLic += opp.Amount*conRate;

Is that to be added in the last while loop?

Thanks.
sieb4mesieb4me
I think probably this is what code is doing, can you please confirm, its taking all the cases with that account and updating the case. that should answer my quesiton on caseindex.
ForcepowerForcepower

sieb4me,

 

That is correct. If account id is null, such cases are not picked up for processing. But when you associate an account, it calculates the values.

 

Re: Also i noticed that we are incrementing the caseindex so wont it skip the case after evaluating 1st time when it comes to lets say 2nd opportunity in the loop?

 

The idea here is that the opportunities are ordered by account id and so are the cases. We are looping through opportunities with the same account id and aggregating the info for opp'ties with the same account and as soon as we hit a different account id, we go through all cases for that previous account id and assign the aggregates calculated on the related opp'ties.  The next time thru' the for loop, we are dealing with a different account and so the cases we dealt with so far won't be related to it and we would want to skip them. Hope that makes sense.

 

Ram

sieb4mesieb4me
Thanks Ram.

for the last account, we are setting case fields but calculation is not there
which is SLic += opp.Amount*conRate;

Is that to be added in the last while loop?
ForcepowerForcepower
Sieb4me - not needed. The last account's aggregation is done by the time we drop out of that loop. Since there is no next account after it that is different in value, we don't go thru' the code that compares the previous account and this account. This is the part that needs to be (and has been) compensated at the end.
sieb4mesieb4me
Thanks Ram.