0

I have a dom class handler which I am calling from batch class. I am looping through the response to perform dml operations across certain objects. Since I have to use the response across different objects, I had to use queries inside the loop. This is causing issues since it is close to limit. I am not sure how I could remove this out of the loop. I want this code to be bulkified, but not sure how I could process the response outside the loop.

response contained 12 rows for each data element.

Here is my code

for (DOM.XMLNode node: grandchild.getChildElements()) {
                String paymentid = node.getAttributeValue('Name', '');
                if(paymentid=='ID')dataelementmap.put(node.getText(), grandchild);
            }
        }
        If(!dataelementmap.isEmpty()){
            for(String str:dataelementmap.keyset()){
                Map<String,String> tempmap=New Map<String,String>();
                for (DOM.XMLNode node: dataelementmap.get(str).getChildElements()) {
                    tempmap.put(node.getAttributeValue('Name', ''),node.getText());
                }
                finaldataelementmap.put(str, tempmap);

            }
        }
         for(String str:finaldataelementmap.keySet()){
            prodname='';
            Id entry;
            tempmap=finaldataelementmap.get(str);

            Act = tempmap.get('Companyname');
            AccId = tempmap.get('Company Number');
        }
            AcList.add(AccId);
            Transfer = tempmap.get('Mode');

            List<Account> act1 = [Select id,name, type from Account where Name =:Act limit 1];
            if(AccId =='' || AccId == null){
                for(Account aa: act1){
                     AcList.add(aa.Id);
                    AccId = aa.Id;
                }
            } 

            OrderDetails = tempmap.get('OrderDetails');
            List<Account> atlst = [select id, OrderApi__Primary_Contact__c from Account where Id =:AccId limit 1];  

            String st = tempmap.get('Email');

            List<Contact> ctlst = [select id, Email from Contact where Email =:st limit 1];
            if (ctlst.size()>0){
                for(Contact cont : ctlst){
                    cocnt = cont.Id;
                }
            }

     if(!Transfer.contains('System')){
            List<Opportunity> opplst=[Select Id,StageName,AccountId,(SELECT Id,Product2.Name FROM OpportunityLineItems Where Product2.Name like:prodname) from Opportunity Where AccountId =: AccId];
           if(opplst.size()== 0){
                  Opportunity opp=New Opportunity();
                        opp.Name = 'Test One';
                        opp.AccountId = AccId;
                        opp.StageName='Proposal/Price Quote';
                 Insert Opp;
               insert olineitems;
              opp.StageName = 'Closed/Signed';
               update opp;
                    }           
        else if (opplst.size()> 0){
            system.debug('Entered second');
             for(Opportunity o : opplst){
                if(o.OpportunityLineItems.size() == 0){
                     oppids.add(o);
                    if (prodname == 'Test'){
                        OpportunityLineItem olinew=New OpportunityLineItem();
                        olinew.OpportunityId=o.Id;                       

            Database.upsert(oli); 
            List<Opportunity> ooo = new List<Opportunity>();                            

            List<Opportunity> oplist = [Select Id,StageName,AccountId,(SELECT Id,Product2.Name FROM OpportunityLineItems Where Product2.Name like:prodname) from Opportunity Where AccountId=:AccId and StageName <> 'Closed/Signed'];
           if(oplist.size()> 0){

           for(opportunity oo : oplist){

                oo.StageName = 'Closed/Signed';
               ooo.add(oo);
            }
           }
            insert ocr;
             update(ooo);


 List<Opportunity> opplist = [Select Id,StageName,AccountId,(SELECT Id,Product2.Name FROM OpportunityLineItems Where Product2.Name like:prodname) from Opportunity Where AccountId=:AccId and Category__c = 'Booth Sales' and StageName = 'Closed/Signed'];             

for(Opportunity o : opplist){
                if(o.OpportunityLineItems.size()>0){
                    AcOpp.put(o.Id,o.AccountId);
                }
            }                       

   List<Order__c> solst = [select id,Opportunity__c from Order__c where Opportunity__c IN : AcOpp.keyset()];            

                       if(solst.size()>0){

                for(Order__c so : solst){                    
                    if(so.Status__c <> 'Closed'){
                        so.Status__c = 'Closed';
                        ids.add(so);
                    }
                }

             update ids;
                    for(Order__c so : solst){
                        if(so.Status__c == 'Closed' && so.Posting__c <> 'Posted'){
                            so.Posting__c = 'Posted';
                            idsfinal.add(so);
                        }
                    }
                }
                update salesidsfinal;

  List<Invoice__c> invlst = [select id, Order__c,Account__c,Balance__c,Status__c from Invoice__c where Order__r.Opportunity__c IN : AcOpp.keyset() and Balance__c > 0];                      

                        for(OrderApi__Invoice__c inv : invlst){
                           insert payment;
                       }
                        }
SOQl for payment;
insert payment lines;
update payment;
} //loop ends here for finaldataelement map
1

First of all split your method into few smaller methods. Make your code easier to read and understand.

Second. Apex DOM API is not very convenient. If you work a lot with DOM try to use some third party lib like this https://github.com/JenniferSimonds/apex-xpath

Just write xpath query and get your data easily.

Some examples of xpath queries:

  • [@id='w3c_home_upcoming _events'] - get any element with id = w3c_home_upcoming_events

  • div[@id='w3c_home_upcoming_events']/p/a - find all a tags inside p tag inside div with id = ...

Work with this library for sure will free you from many for loops as you won't write nested loops in order to get required Nodes anymore.

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.