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
Dan RamirezDan Ramirez 

Set Opportunity Record Type with Apex Class based on Order Type

We currently use an Apex Class that will generate opportunities from Orders that are imported nightly from an SSIS package. Originally the only orders that would generate opportunities were the ones that were of the Sales_Order type, but recently we changed the trigger to also include Service_Orders, so now we have to figure out how to modify our code so that it'll assign the correct opportunity record type based on the order type. The class was written by someone else and I'm REALLY new to coding so I'm hoping you guys can help me. Here is the class:
 
 

https://www.dropbox.com/s/dvotyvt765pv6we/Order_Helper.pdf?dl=0

(I had to do it this way because there's a charater limit.)

If I understand this correctly, the class puts all the orders on a list and runs through the Opportunity Number field. If it has a valid number it'll simply link the Order to the Opportunity with that number. However, if the Order does not have an Opportunity Number, or the number does not match an existing Opportunity's number, it'll generate a new opportunity through the Order Wrapper section. I'm pretty sure that the part that the part that currently sets the record type is the part that I've put in bold letters, my question is: why did they put that section there and not define it in the Order Wrapper section that sets the other Opportunity fields? And, I tried replacing that part with the loop below but got an error saying we had maxed out our SOQL inquiries, how can I rewrite this to work? Or, if you think there's a better way, how would you do it? 
list<Id> oppRT = new list<id>();
            String rtLabel = '';
            for(Order__c xxx:orders ){
            if(xxx.Order_Type__c=='Sales_order' ){
           
            for(RecordType rt : [SELECT Id, Name FROM RecordType WHERE IsActive = true AND SobjectType = 'Opportunity' AND DeveloperName = 'Standard_Quote_Order']){
                oppRT.add(rt.Id);
                         

                rtLabel = rt.Name;
            } 
            }
            else{
            for(RecordType rt : [SELECT Id, Name FROM RecordType WHERE IsActive = true AND SobjectType = 'Opportunity' AND DeveloperName = 'Service_Job']){
                       

                oppRT.add(rt.Id);
                rtLabel = rt.Name;
            } 
            }}
            integer o1=0;
            for(OrderOppWrapper oow : orderOppWrapList){
                if(acctMap.containsKey(oow.order.AccountId__c)){
                    if(oppRt != null){
                        oow.oppty.RecordTypeId = oppRt[o1];
                        o1++;
                    }
                    if(takerId.containsKey(oow.order.Taker__c)){
                        oow.oppty.OwnerId = takerId.get(oow.order.Taker__c);
                    }
                    else if(defaultUser instanceof Id){
                        oow.oppty.OwnerId = defaultUser;
                    }
                    else{
                        oow.oppty.OwnerId = acctMap.get(oow.order.AccountId__c).OwnerId;
                    }                   
                    upsertOpps.add(oow.oppty);
                }
            }
            if(upsertOpps.size() > 0 && isInsert){
                upsert upsertOpps;
            }

 
RaidanRaidan
Hi Dan,

You are not supposed to use a SOQL or DML statement inside of a loop. It might hit the limit if you are updating a large number of records. I don't see your full code here. However, the code below will give you the idea how to implement the change.
 
Map<String, Id> rtMap = new Map<String, Id>();
for (RecordType rt : [SELECT Id, Name FROM RecordType 
                        WHERE SObjectType = 'Opportunity' 
                        AND DeveloperName IN ('Standard_Quote_Order', 'Service_Job')];
    rtMap.put(rt.Name, rt.Id);
}

for(Order__c xxx:orders ){
    Id rtId = (xxx.Order_Type__c=='Sales_order' )? rtMap.get('Standard_Quote_Order') : rtMap.get('Service_Job');
    for(OrderOppWrapper oow : orderOppWrapList){
        oow.oppty.RecordTypeId = rtId;
        if(acctMap.containsKey(oow.order.AccountId__c)){
            if(takerId.containsKey(oow.order.Taker__c)){
                oow.oppty.OwnerId = takerId.get(oow.order.Taker__c);
            }
            else if(defaultUser instanceof Id){
                oow.oppty.OwnerId = defaultUser;
            }
            else{
                oow.oppty.OwnerId = acctMap.get(oow.order.AccountId__c).OwnerId;
            }                   
            upsertOpps.add(oow.oppty);
        }
    }
}

if(upsertOpps.size() > 0 && isInsert){
    upsert upsertOpps;
}

 
Dan RamirezDan Ramirez
Hi Raidan,

Thanks for your help! After I saw the Dreamforce video on Apex Triggers where the guy mentions doing laundry and being a good neighbor to explaing why we shouldn't use SOQL statements in loops, I realized my mistake, but I wasn't sure how to fix it. We import anywhere from 100-200 orders every night, and I believe the SOQL max is 100 queries so I guess that explains why we were getting the error messages. 

Since there is a character limit I had to upload the full code as a PDF to my drobox account and put that link in the body of the email. I'll give this a shot and let you know how it goes :)