2

I've been dealing with this for a while now, and still haven't found a solution on the problem I am currently facing.

So.. here is the situation. I have programmed a Trigger for the Opportunity object that is being executed onBeforeInsert and onBeforeUpdate. What I am trying to achieve is assign an auto-generated, sequential code number for a custom field of the Object, named Ref__c. The trigger loops through all the Accounts, and for each of its Opportunities, assigns a value, that is, a concatenation of a custom field of Account, i.e Codigo_Socio__c and a number, that increases based on the number of the Opps that this Account holds(e.g An account with 10 Opps and value of Codigo_Socio__c = 0001, will hold the following values in its Opps, 0001-1, 0001-2, 0001-3, etc..)

The problem is that for a reason that still is opaque to me, for some Opportunities the values are being repeated when the execution of inserting Opportunities occurs. Here is an example in the following screenshot attachment: enter image description here

As you can see, The Account Cheque Regalo has duplicate values for some of its Opportunities(dupl. value for 0013-3 and 0013-4).

Below is the method of the Opportunity Trigger that generates the values for the Ref__c field of Opportunities.

//PUBLIC METHODS
    /**
     * Generates unique Ref Code for opportunity
     *
     * @param {@code List<Opportunity>} opportunity list
     * @return {@code void}
     */
    public void generateRefCode(List<Opportunity> newList) {

        //Paso 0. Set collections based on objet relationships
        Map<Id,String> accountIdToLatestOppRefMap = new Map<Id,String>();
        Map<Id,List<Opportunity>> accountIdToListOppMap = new Map<Id,List<Opportunity>>();

        for(Opportunity theOpp : newList) {
            accountIdToLatestOppRefMap.put(theOpp.AccountId, '');
            if(accountIdToListOppMap.containsKey(theOpp.AccountId)) {
                accountIdToListOppMap.get(theOpp.AccountId).add(theOpp);
            }else{
                accountIdToListOppMap.put(theOpp.AccountId,new List<Opportunity>{theOpp});
            }
        }

        String refToAssign;
        String lastRef;
        Integer lastNumber;

        for(Account theAcc : [SELECT Id, Codigo_Socio__c,
                             (SELECT Id, Ref__c,CreatedDate FROM Opportunities  ORDER By CreatedDate DESC LIMIT 1)
                              FROM Account
                              WHERE Id IN : accountIdToListOppMap.keySet() 
                              AND Codigo_Socio__c <> '']){

            //Paso 1. Gather Accounts' codigo de socio and latest Opp Ref.
            String codigoDeSocio = theAcc.Codigo_Socio__c;


            //if opplist is empty
            //extract codigoSocio and start from Codigo_Socio__c-1.

            if(theAcc.Opportunities.isEmpty()){ 
                codigoDeSocio += '-1';
                accountIdToLatestOppRefMap.put(theAcc.Id,codigoDeSocio);
                System.debug('@@Account with empty opps!');
                System.debug('@@REF_UPDATE: FIRST REF obtained: ' + codigoDeSocio + ' for Account:' + theAcc.Codigo_Socio__c);

            }else{

                lastRef = theAcc.Opportunities.get(0).Ref__c;
                System.debug('@@REF_UPDATE: LAST_REF obtained: ' + lastRef);


                accountIdToLatestOppRefMap.put(theAcc.Id,lastRef);
            }       

            //Paso 2. Assign opportunity's ref
            //como nos aseguramos aqui obtenemos 
            for(Opportunity theOpp : accountIdToListOppMap.get(theAcc.Id)){

                lastRef = accountIdToLatestOppRefMap.get(theAcc.Id);
                lastNumber = Integer.valueOf(lastRef.split('-')[1]);

                ++lastNumber;
                refToAssign = lastRef.split('-')[0] + '-' + String.valueOf(lastNumber);

                theOpp.Ref__c = refToAssign;

                System.debug('@@REF_UPDATE: REF Assigned: ' + refToAssign);
                accountIdToLatestOppRefMap.put(theAcc.Id, theOpp.Ref__c);
            }
        }
    }   

I'd be glad to here any suggestions, remarks, insights or (even) solutions for this problem.

Thank you a priori.

  • I think there is problem with the logic especially how 'lastRef ' is set. Clearly if you insert two Opportunities in a single bulk insert, both will take same number. – Amit Bangad Jul 21 '15 at 9:03
0

The code might fail in batch mode because of the 'lastRef' parameter. This parameter is evaluated first but the issue is whenever a batch has two opportunities corresponding to same account lastRef should be incremental i.e. lastRef should really be set again which is not being done. So can you try below (PS - I am just adding a single line to your code)

Add line accountIdToLatestOppRefMap.put(theAcc.Id,refToAssign); under line theOpp.Ref__c = refToAssign; and test if it works.

| improve this answer | |
  • Thanks for the reply. I have added the line you're mentioning but still, the same thing occurs. Ref__c is being duplicated for some opportunities and then it increases its number until it's duplicated again. – Menio Jul 21 '15 at 9:52
  • ok. Do you want the numbers to be assigned from '2' onwards ? and do you assign numbers to Opportunity again even though they are assigned once? – Amit Bangad Jul 21 '15 at 10:13
  • If the Opportunity List of the corresponding Account is empty, I start from number '-1' and onwards. The numbers have to be assigned once and only once for each Opportunity. If the assignment happens again(e.g a massive Update of Opportunity happens via DataLoader) the assignment of numbers must be assigned once and only once. – Menio Jul 21 '15 at 10:29

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.