You need to sign in to do that
Don't have an account?
APEX trigger re-firing workflow rule
Hi, I have an APEX trigger that creates a new account record and then updates the contact record associating the contact to the new account via the 'account' lookup field (parent/child). Everything works correctly except that the contact update fires two workflows rules that have already fired and based on the evaluation criteria: "When a record is created, or when a record is edited and did not previously meet the rule criteria". The APEX trigger update does not update any of the fields referenced in the workflows' criterias. I tried to replicate the problem in the org.'s sandbox, but could not. It's as though the apex trigger update is erasing the workflow history that they workflow has already run. (logically as though trigger.old is not reference or is erased for the workflow). Has anyone experienced this issue before or has any idea of why this would be occuring besides a Salesforce bug?
Related code below:
Trigger:
trigger ConverttoHouseholdTrigger on Contact (before insert, before update) {contactHouseholdFellowship.contactHouseholdFellowshipMethod(trigger.new);
}
CLASS:
public class contactHouseholdFellowship
{
public static void contactHouseholdFellowshipMethod(contact[] contacts)
{
//Account - Build a "reversed" record type map for Account so that the record type name becomes the Key
//and the id is the Value.
Map<String, Id> AccountRecTypesRev = new Map<String, Id>();
for(RecordType rec :[select id, DeveloperName, sObjectType from RecordType
where sObjectType = 'Account']) {
AccountRecTypesRev.put(rec.DeveloperName, rec.Id); }
id HHaccRec = AccountRecTypesRev.get('Household');
list<contact>contactList = new list<contact>();
list<account>accountList = new list<account>();
set<id>contactSet = new set<id>();
map<id,id>accountMap = new map<id,id>();
map<id,id>contactMap = new map<id,id>();
for (contact c : contacts)
{
contactset.add(c.id);
}
//Contact list is necessary because we can't obtain parent 'account' field values without a SOQL query
contactList = [select id, name, firstName, LastName, account.recordtypeId, email, Do_Not_Mail__c,
HasOptedOutOfEmail,DoNotCall,HomePhone,Phone,MailingStreet,MailingCity,MailingState,MailingPostalCode,
OtherStreet,OtherCity,OtherState,OtherPostalCode,Fellowship_Status__c
from contact where id in : contactSet];
for (contact c : contactList)
{
//only if contact is not already the child of a 'Household' account and only if 'offer Accepted' as
//per current related workflow rule criteria
if (c.account.recordTypeId != HHaccRec && c.Fellowship_Status__c == 'Offer Accepted')
{
//Create map for contacts to be updated for contact.accountid update below
contactMap.put(c.id,c.id);
account account = new account();
account.name = c.firstname + ' ' + c.lastName + ' Household';
account.Addressee__c = c.firstname + ' ' + c.lastName;
account.Addressee_Informal__c = c.firstname;
account.Email__c = c.Email;
account.Do_Not_Mail__c = c.Do_Not_Mail__c;
account.Do_Not_Email__c = c.HasOptedOutOfEmail;
account.Do_Not_Call__c = c.DoNotCall;
account.recordtypeid = HHaccRec;
If (c.HomePhone != null)
{
account.phone = c.HomePhone;
}
else
{
account.phone = c.Phone;
}
account.BillingStreet = c.MailingStreet;
account.BillingCity = c.MailingCity;
account.BillingState = c.MailingState;
account.BillingPostalCode = c.MailingPostalCode;
account.ShippingStreet = c.OtherStreet;
account.ShippingCity = c.OtherCity;
account.ShippingState = c.OtherState;
account.ShippingPostalCode = c.OtherPostalCode;
//set primary contact record for household account
account.Primary_Contact__c = c.id;
accountList.add(account);
}
}
insert accountList;
//map primary contact id to account id so we can reference which account the contact
//should be updated to via the parent/child account/contact relationship
for (account a : accountList)
{
accountMap.put(a.Primary_Contact__c, a.id);
}
for (contact c: contacts)
{
//only update contacts that fit the criteria for the contactList
if (contactMap.get(c.id) != null)
{
c.accountid = accountMap.get(c.id);
}
}
}
Here is the Execution Sequence that Salesforce follows for Triggers and Workflows:
3. Executes all before triggers.
4. Runs most system validation steps again, such as verifying that all required fields have a non-null value, and runs any
user-defined validation rules. The only system validation that Salesforce.com does not run a second time (when the request
comes from a standard UI edit page) is the enforcement of layout-specific rules.
5. Saves the record to the database, but does not commit yet.
6. Executes all after triggers.
7. Executes assignment rules.
8. Executes auto-response rules.
9. Executes workflow rules.
10. If there are workflow field updates, updates the record again.
11. If the record was updated with workflow field updates, fires before and after triggers one more time (and only one
more time).
Note: The before and after triggers fire one more time only if something needs to be updated. If the fields
have already been set to a value, the triggers are not fired again.