0

I'm confusing myself with lists/maps. I want when criteria is met to put 4 values into a container. Id, Sales Participant Id(a lookup), Sales Participant Name, and an Integer. I have 3 separate Sales Participant lookup fields so if one is changed I want to add the id to the container. Finally, I want to take the container of the 4 values and generate a new record. Looping through each row in the container to create a new record.

How can I collect this data to pass to a handler? With a map or a list? In my current code I used a map which seems to only pull the two ids over but I cannot figure out how to get the lookup id to populate for the field.

Example Code:

public static void createSalesParticipant(Map<Id, Opportunity> newMap, Map<Id, Opportunity> oldMap)
{
    List<
    Map<Id, Id> salesParticipants = new Map<Id, Id>();
    for(Opportunity oppy : newMap.values())
    {
        if(oppy.Sales_Participant_1__c != null && oldMap.get(oppy.Id).Sales_Participant_1__c != oppy.Sales_Participant_1__c)
        {
            salesParticipants.put(oppy.Id, oppy.Sales_Participant_1__c);
        }
        if(oppy.Sales_Participant_2__c != null && oldMap.get(oppy.Id).Sales_Participant_2__c != oppy.Sales_Participant_2__c)
        {
            salesParticipants.put(oppy.Id, oppy.Sales_Participant_2__c);
        }
        if(oppy.Sales_Participant_3__c != null && oldMap.get(oppy.Id).Sales_Participant_3__c != oppy.Sales_Participant_3__c)
        {
            salesParticipants.put(oppy.Id, oppy.Sales_Participant_3__c);
        }
    }
    SalesParticipantHandler.createParticipant(salesParticipants);
}    

Handler:

    public with sharing class SalesParticipantHandler {
    public static void createParticipant(Map<Id, Id> salesParticipants){

        List<Sales_Participant__c> salesParticipantsToInsert = new List<Sales_Participant__c>();
        for(Sales_Participant__c salesP : salesParticipants) {

            salesParticipantsToInsert.add(new Sales_Participant__c(
                Name = 'test',
                Opportunity__c = salesP.Id,
                Sales_Participant__c = salesP.Sales_Participant_1__c
                ));         
        }
        insert salesParticipantsToInsert;   
    }
}
0

In this context, we can see that you're overwriting the key if there's more than one change. Since you need to know the opportunity Id of the participant, you actually need to reverse your logic:

salesParticipants.put(oppy.Sales_Participant_1__c, oppy.Id);

However, that's really not good enough, because there could be more than one Sales Participant across multiple Opportunities, which means you'll still miss data.

Realistically, your best bet in this scenario is to use just a plain array of arrays, like this:

List<List<Id>> values = new List<List<Id>>();

Which you'd populate using:

salesParticipants.add(new List<Id> { oppy.Sales_Participant_1__c, oppy.Id });

And then you'd handle by using:

for(Id[] recordIds: salesParticipants) {
    salesParticipantsToInsert.add(new Sales_Participant__c(
            Name = 'test',
            Opportunity__c = recordIds[1],
            Sales_Participant__c = recordIds[0]
            ));
}

I realize that there's a risk of getting them backwards, so you could also choose to write a class:

public class ParticipantOppMapping {
    public Id opportunityId, participantId;
}

Note that I advise against using a constructor here, because you could accidentally get things mixed up later, especially if you don't have auto-complete in your IDE. So, you can just do this:

ParticipantOppMapping pom = new ParticipantOppMapping();
pom.opportunityId = oppy.Id;
pom.participantId = oppy.Sales_Participant_1__c;
salesParticipants.add(pom);

This is marginally slower performance-wise, but keeps your code clear and intentional.

  • In the line salesParticipants.add(new List<Id> { oppy.Sales_Participant_1__c, oppy.Id }); Can I add other variables to the list as well so a 1 when it's sales Participant 1 and the Name? Or am I stuck at 2? – Dan Wooding Jan 5 '17 at 21:58
  • @DanWooding A list of Id could accept Id values. Try using the wrapper class I suggested. – sfdcfox Jan 5 '17 at 22:55
1

You need to change the Handler code like this:

a) loop through the Opportunity Ids

b) from the salesParticipants map, retrieve the Sales_Participant__c based on Opportunity Id

public with sharing class SalesParticipantHandler {
    public static void createParticipant(Map<Id, Id> salesParticipants){

        List<Sales_Participant__c> salesParticipantsToInsert = new List<Sales_Participant__c>();

        for(Id OpptyId : salesParticipants.keySet()) {

            salesParticipantsToInsert.add(new Sales_Participant__c(
                Name = 'test',
                Opportunity__c = OpptyId,
                Sales_Participant__c = salesParticipants.get(OpptyId)
                ));         
        }
        insert salesParticipantsToInsert;   
    }
}
0

All the fields are all part of the opportunity sObject yes? Then your map should be

map<id, Opportuninity> salesParticpants = new map<id, Opportunity>();

Then you can put the opportunity into the map

salesParticipants.put(oppy.Id oppy);

Note that you can also change just a field in the map

salesParticpants.get(oppy.id).name = 'new value';
  • Can you put variables in the map that are not fields? I want to get the participant name which would be Sales_Participant_1__r.Name if you were doing a formula. And I want to populate an integer that would be based off the participant 1,2,or3 and store it to be used later. – Dan Wooding Jan 5 '17 at 22:00
  • Yes you should be able to as long as the field was queried. – Krone Jan 5 '17 at 23:16

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.