I have a before insert handler class, that based on criteria tries to find a custom object (responsible party) record with a matching key and then populate a lookup on the OpportunityLineItem. This seems to work great in the sandbox where I am developing and testing as long as there is a record to match against. What I want to add to the logic is that if no match is found I want to create a new responsible party record and attach that to the OLI.
I can't seem to wrap my head around when I should check that a match is not found and then create the record. I'll post my methods that I have for an example that filter, query, then update the OLI. When I go to update the OLI and there is no match do I go off and then create a record and make another method to attach it? Or do I figure out that no match was found before going to the update that way I can create and then match against the map?
public without sharing class NPD_Responsible_Party_Locator
{
public static void filterInsert(List<OpportunityLineItem> newList)
{
List<OpportunityLineItem> olis = new List<OpportunityLineItem>();
Set<String> olikeys = new Set<String>();
Set<Id> oppIds = new Set<Id>();
Set<Id> prodIds = new Set<Id>();
// Create a set of all the unique Opp Ids that we need to query for
for(OpportunityLineItem oliO : newList)
oppIds.add(oliO.OpportunityId);
// Create a map so that Opportunity is locatable by its Id (key)
Map<Id, Opportunity> oppsMap = new Map<Id, Opportunity>(
[SELECT Id, Account.OwnerId, AccountId FROM Opportunity WHERE Id IN :oppIds]);
// Create a set of all the unique Product Ids that we need to query for
for(OpportunityLineItem oliP : newList)
prodIds.add(oliP.Product2Id);
// Create a map so that the Product is locatable by its Id (key)
Map<Id, Product2> prodsMap = new Map<Id, Product2>(
[SELECT Id, Formula_LOB__c, Practice__c, Practice__r.Key_Type__c FROM Product2 WHERE Id IN :prodIds]);
// On Insert we add to all products
for(OpportunityLineItem oppyLine : newList)
{
if(prodsMap.get(oppyLine.Product2Id).Practice__r.Key_Type__c == 'Account Owner - Practice')
{
olikeys.add(oppsMap.get(oppyLine.OpportunityId).Account.OwnerId + '-' + prodsMap.get(oppyLine.Product2Id).Practice__c);
olis.add(oppyLine);
}
if(prodsMap.get(oppyLine.Product2Id).Practice__r.Key_Type__c == 'Account - Accounting Unit')
{
olikeys.add(oppsMap.get(oppyLine.OpportunityId).AccountId + '-' + prodsMap.get(oppyLine.Product2Id).Formula_LOB__c);
olis.add(oppyLine);
}
if(prodsMap.get(oppyLine.Product2Id).Practice__r.Key_Type__c == 'Account - Practice')
{
olikeys.add(oppsMap.get(oppyLine.OpportunityId).AccountId + '-' + prodsMap.get(oppyLine.Product2Id).Practice__c);
olis.add(oppyLine);
}
}
Map<String, Responsible_Party__c> rmap = getResParty(olikeys);
updateOLI(rmap, olis, oppsMap, prodsMap);
}
public static Map<String, Responsible_Party__c> getResParty(Set<String> olikeys)
{
Map<String, Responsible_Party__c> rmap = new Map<String, Responsible_Party__c>();
for(Responsible_Party__c r : [SELECT Id,
Name,
User__c,
Sector__c,
Key__c
FROM Responsible_Party__c
WHERE Key__c IN : olikeys])
{
rmap.put(r.Key__c, r);
}
return rmap;
}
public static void updateOLI(Map<String, Responsible_Party__c> rmap, List<OpportunityLineItem> olis, Map<Id, Opportunity> oppsMap, Map<Id, Product2> prodsMap)
{
Responsible_Party__c r = new Responsible_Party__c();
for(OpportunityLineItem o : olis)
{
if(prodsMap.get(o.Product2Id).Practice__r.Key_Type__c == 'Account Owner - Practice')
{
r = rmap.get(oppsMap.get(o.OpportunityId).Account.OwnerId + '-' + prodsMap.get(o.Product2Id).Practice__c);
}
if(prodsMap.get(o.Product2Id).Practice__r.Key_Type__c == 'Account - Accounting Unit')
{
r = rmap.get(oppsMap.get(o.OpportunityId).AccountId + '-' + prodsMap.get(o.Product2Id).Formula_LOB__c);
}
if(prodsMap.get(o.Product2Id).Practice__r.Key_Type__c == 'Account - Practice')
{
r = rmap.get(oppsMap.get(o.OpportunityId).AccountId + '-' + prodsMap.get(o.Product2Id).Practice__c);
}
if(r != null)
{
o.Responsible_Party__c = r.Id;
}
else{
o.Responsible_Party__c = null;
}
}
}