I am trying to get a trigger on the opportunity that will look at the contact roles, check to see if there is a contact role with the "role" that equals "fulfillment" and then return the number of contacts that meet the criteria. Basically I just need to know that the Opp has a contact role added and that it has the "role" of "fulfillment". I thought the counting would work so that I could create a pop-up window that alerts the users that a fulfillment contact needs to be added. And once past a certain stage a validation that will not let you move to a "win" without that contact role defined.
Below is my trigger, however it does not update the count. Any pointers? Is there a better more streamline way to accomplish this? Thanks!
trigger fulfillmentcontactcreatedopp on Opportunity (before delete, before insert) {
String Role;
Integer iCount;
Map<String, Opportunity> oppty_con = new Map<String, Opportunity>();//check if the contact role is needed and add it to the oppty_con map
for (Integer i = 0; i < Trigger.new.size(); i++)
{
oppty_con.put(Trigger.new[i].id,
Trigger.new[i]);
}
Role = 'Fulfillment';
for (List<OpportunityContactRole> oppcntctrle :[select OpportunityId from OpportunityContactRole where (Role = 'Fulfillment')])
{
if (oppcntctrle .Size() <0)
{
Role = 'Fulfillment';
}
}
iCount = 0;
for (List<OpportunityContactRole> oppcntctrle2 : [select OpportunityId from OpportunityContactRole where (OpportunityContactRole.OpportunityId in :oppty_con.keySet())])//Query for Contact Roles
{
if (oppcntctrle2 .Size()>0)
{
iCount= oppcntctrle2 .Size();
}
}
for (Opportunity Oppty : system.trigger.new) //Check if roles exist in the map or contact role isn't required
{
Oppty.Number_of_Fulfillment_Contacts__c = iCount;
}
}
Here is the newly updated code... notice I had to change the last line..opportunity.Number_of_Fulfillment_Contacts__c = aggCount.get('expr0');
and now I get the error that Expression cannot be assigned.
trigger fulfillmentcontactcreatedopp on Opportunity (before insert, before update) {
Integer Total;
// Only need to enforce rule if going into the "Win" stage
Map<Id, Opportunity> oppsToCheckMap = new Map<Id, Opportunity>();
for(Opportunity opp : trigger.new) {
// Add the opp Id to a Map(Id to Opp) if it is an insert trigger with a won stage
// or if it is an update changing into a won stage (use trigger.oldMap to find the value before the change.
if(opp.StageName == '09-Win') { // <== Your "Won" stage name here.
if(trigger.isInsert ||
trigger.isUpdate && trigger.oldMap.get(opp.Id).StageName != opp.StageName)
oppsToCheckMap.put(opp.Id, opp);
}}
// For each Opportunity in the map keyset get the count of the
// OpportunityContactRole with role = fulfillment.
List<AggregateResult> result = [
select OpportunityId, count(Id)
from OpportunityContactRole
where (Role = 'Fulfillment') and
OpportunityId in :oppsToCheckMap.keySet() group by OpportunityId];
// If the count is zero use addError to prevent the insert/update from committing.
for(AggregateResult aggCount : result) {
// Here expr0 should be the count(Id) result.
// I.e. How many Fulfillment Contact Roles each Opportunity has.
if(aggCount.get('expr0') == 0) {
Id oppId = (Id)aggCount.get('OpportunityId');
Opportunity opp = oppsToCheckMap.get(oppId);
opp.StageName.addError('Requires Fulfillment Contact Role to be Won');
}
// If you don't want to use addError you can also update the count field here
// The problem is that this won't update the count when the
// OpportunityContactRole records change.
opportunity.Number_of_Fulfillment_Contacts__c = aggCount.get('expr0');
}
}
Update -- working code to get a count of fulfillment contact roles on the opp above a certain stage.
trigger fulfillmentcontactcreatedopp on Opportunity (before insert, before update) {
// Only need to enforce rule if going into the "Win" stage
Map<Id, Opportunity> oppsToCheckMap = new Map<Id, Opportunity>();
for(Opportunity opp : trigger.new) {
// Add the opp Id to a Map(Id to Opp) if it is an insert trigger with a won stage
// or if it is an update changing into a won stage (use trigger.oldMap to find the value before the change.
if(opp.Stage_Calc__c >= 5 ){ // <== Your "Won" stage name here.
if(trigger.isInsert ||
trigger.isUpdate && trigger.oldMap.get(opp.Id).StageName != opp.StageName)
oppsToCheckMap.put(opp.Id, opp);
}
// For each Opportunity in the map keyset get the count of the
// OpportunityContactRole with role = fulfillment.
List<AggregateResult> result = [
select OpportunityId, count(Id)
from OpportunityContactRole
where (Role = 'Fulfillment') and
OpportunityId in :oppsToCheckMap.keySet() group by OpportunityId];
// If the count is zero use addError to prevent the insert/update from committing.
for(AggregateResult aggCount : result) {
// Here expr0 should be the count(Id) result.
// I.e. How many Fulfillment Contact Roles each Opportunity has.
if(aggCount.get('expr0') == 0) {
Id oppId = (Id)aggCount.get('OpportunityId');
Opportunity oppo = oppsToCheckMap.get(oppId);
//oppo.StageName.addError('Requires Fulfillment Contact Role to be 05-Short List - Vendor Assessement');
}
Integer fulcount = Integer.valueOf(aggCount.get('expr0'));
// If you don't want to use addError you can also update the count field here
// The problem is that this won't update the count when the
// OpportunityContactRole records change.
opp.Number_of_Fulfillment_Contacts__c = fulcount;
}
}
}