Here's some the gaps filled in. I am assuming that Competitor__c
is your MultiSelect field, that Win_Reason__c
is a Picklist and that Unsolicited_Bid__c
is a Checkbox. If not, adjust accordingly.
------------------------------------------------------
-- Field Type * Data Type --
------------------------------------------------------
-- Picklist * String --
-- Text * String --
-- Checkbox * Boolean --
-- MultiSelect * String with ; to delimit values --
-- Number * Decimal --
-- Currency * Decimal --
-- Date * Date --
-- Datetime * Datetime --
-- Master-Detail * Id --
-- Loookup * Id --
-- TextArea * String --
------------------------------------------------------
trigger UpdateOpportunity on Opportunity (before insert, before update){
for(Opportunity opp :Trigger.new){
// MultiSelect Fields are a single String with values delimited by a semi-colon
// TODO: Double check Field API Names
// TODO: Double check Field values spelling for Case Sensitivity
if(opp.win_reason__c == 'No Competitor'){
opp.Competitor__c = 'No Competiton;Sole Source';
}
if(opp.Unsolicited_Bid__c == true){
opp.Competitor__c = 'No Competiton;Sole Source';
}
}
}
Here's some helpful docs when working with Triggers:
Update
To neatly add the condition not to have the above execute if the Stage = 0%
, I will introduce using an Apex Class static function. Separating what we are doing into individual methods simplifies logic and code-readability.
First let's create an Apex Class:
public Class OpportunityMethods {
public static void updateOppCompetitor(Opportunity opp){
if(opp.win_reason__c == 'No Competitor'){
opp.Competitor__c = 'No Competiton;Sole Source';
}
if(opp.Unsolicited_Bid__c == true){
opp.Competitor__c = 'No Competiton;Sole Source';
}
}
}
Now rewrite the trigger to use the OpportunityMethods.updateOppCompetitor(...)
method:
trigger UpdateOpportunity on Opportunity (before insert, before update){
for(Opportunity opp: trigger.new){
OpportunityMethods.updateCompetitor(opp);
}
}
Cool. The rewritten trigger does look a bit simpler. But we still need to only updateOppCompetitor
if the opp.StageName != 0 %
. (Or you might be referring to the opp.Probability = 0
where the Opportunity Probability is a decimal, so adjust accordingly.) To do this, let's add a simple if statement and execute updateCompetitor(opp)
if opp.StageName != '0 %'
:
trigger UpdateOpportunity on Opportunity (before insert, before update){
for(Opportunity opp: trigger.new){
if(opp.StageName != '0 %'){
OpportunityMethods.updateOppCompetitor(opp);
}
}
}
Double cool. That does exactly what we want it to do, and just reading the code tell us simply what it's doing.
Being astute, we notice, "Hey, could put that StageName-condition in the updateCompetitor
method directly?" And the answer is, "Yes. Furthermore, instead of sending each Opportunity
through the method, we could send the whole List<Opportunity>
through and do all the processing there in a method."
One path to realizing this is through the following: First let's add to our OpportunityMethods
class
public Class OpportunityMethods {
public static void updateOppCompetitor(Opportunity opp){
if(opp.win_reason__c == 'No Competitor'){
opp.Competitor__c = 'No Competiton;Sole Source';
}
if(opp.Unsolicited_Bid__c == true){
opp.Competitor__c = 'No Competiton;Sole Source';
}
}
public static void updateComptetitor(List<Opportunity> newList){
for(Opportunity op :newList){
if(opp.StageName != '0 %'){
OpportunityMethods.updateOppCompetitor(opp);
}
}
}
}
And the trigger simplifies to:
trigger UpdateOpportunity on Opportunity (before insert, before update){
OpportunityMethods.updateCompetitor(trigger.new);
}
Notice how we re-used the updateOppCompetitor
-method in the updateCompetitor
-method. We already did the work of writing the method, so let's reuse what we have. Also, with any type of code, there are many ways to go about accomplishing the same end result. The key to good programming is having the flexibility to accomplish the same results using various paths -- sometimes certain paths offer a much shorter route than others, and each path-lengths depends on the destination. When Limits are imposed on a situations, cough cough Governor Limits, some paths may be closed off, so it's handy to know alternative routes when necessary.