[SalesForce] Apex – populate field with a value stored in mapping object

I am trying to solve the following problem: There is a text field "Product" on Opportunity object and I need to change the values of that and map it to picklist. There is already data in the system which means about 200 different values of Product field that, in the end, will be mapped to one of 5 picklist values according to mapping that I have already stored in object ProductMap__c.

Mapping example:

ProductMap__c.Former__c   ProductMap__c.Actual__c
"Leasing KA"              "Leasing"
"Leasing 100k"            "Leasing"

I was thinking of creating a List of Opportunities and then somehow use a Map of ProductMap, find a value of Map and store it on the Opportunity.
Can you guys help me? I am quite new to Apex and I don't know how to continue or maybe my thoughts are completely wrong..

list<Opportunity> opps = [select id, name, Product__c from Opportunity where Product__c != ''];
for(Opportunity opp : opps){
...?Map of ProductMap?

Best Answer

Welcome to SF.SE Marting. A map contains a key and a value. What I'm gathering from your example is that you want to update values containing ProductMap__c.Former__c to ProductMap__c.Actual__c. I'm also gathering that ProductMap__c.Former__c values will be unique, but ProductMap__c.Actual__c values will not. In a map, the keys need to be unique while the values do not. That means your map needs to be something like

map<string,string>ProdMapNewOld = new map<string, string>(); 

You'd use ProductMap__c.Former__c as the key and ProductMap__c.Actual__c as the value for each key when assembling the map. The pattern is to use mapname.put(key,value).

When updating your Opportunities, I'd recommend your do your query as a Map. That way it looks like:

map<Id,Opportunity> oppsMap = new map<id,Opportunity([select id, name, Product__c from Opportunity where Product__c != '']);

You can then do

For(Id oid:oppsMap.keyset()){
   If(ProdMapNewOld.containsKey(oppsMap.get(oid).Product__c)){
       string tempstr =  ProdMapNewOld.get(oppsMap.get(oid).Product__c;
       oppsMap.get(oid).Product__c = tempstr;
   }
}

You can also add them to a new list or whatever you wish in order to update the Opps. This is just to give you the concept. In the above, you need to get the key before you can reassign the value.

Edit

//I tried to fill in the map with select, but it doesn't work, is that possible?

//Map pm = new Map([SELECT Former__c, Actual__c FROM ProductMap__c]);

First, you need to declare the map properly as map<string,string> pm. But in this case, you're querying an object, so you'd need to get the list and then create the map. I'm guessing your map probably would be created by doing something like this:

map<string,string>pm = new map<string,string>();
map<Id,ProductMap__c>pmc = new map<Id,ProductMap__c>([select Id, Former__c, Actual__c FROM ProductMap__c]);
//This query returns all of your old and new values in a map by record Id 
//Now, you can iterate on the map's Ids to "put" the pairs into the map you want to use
for(Id i:pmc.keyset()){
    pm.put(pmc.get(i).Former__c,pmc.get(i).Actual__c);
}

And yes, adding your values to a new list is a perfectly acceptable way to do what you wanted to do, however, using your code, you'd have wanted to do it as follows:

//List of opportunities to update
List ou = new List();

//Compare products with map of products and store new value
For(Id oid : om.keyset()){
   If(pm.containsKey(om.get(oid).Product__c)){
       Opportunity o = new Opportunity(Id = oid);
       o.ProdPick__c = pm.get(om.get(oid).Product__c); 
       //store it in the new picklist 
       //you could also have simply done this to pm and did the update to pm
       ou.add(o);
   }
}
update ou;
Related Topic