You need to sign in to do that
Don't have an account?
mengel
Need help with Update Trigger / test case
I have a custom object called Branch.
My Account and Opportunity both have a lookup field to this object.
I need to ensure that the Opportunity Branch always contains the same value in the Account Branch if the opportunity is edited - I know this is very simple but i'm hitting a mental roadblock.
My trigger below does not appear to be firing when I do an edit and save on the Opportunity record.
Also any help with setting up the test case for this would also be helpful.
I am new to this and did figure out how to retreive the code using Ant and Eclipse from the sandbox - but I know it will fail on deploy when I try to put it to production without a test case. I am not particullary savy when it comes to java script.
Any input would be appreciated.
trigger OppBranchEqualAccBranch_Update on Opportunity (before update) { if (System.Trigger.isUpdate) { for(Opportunity oppnew :[select Id, Branch__c, Account.ID, Account.Branch__c from Opportunity where Id in:Trigger.new]) { if(oppnew.Account.Branch__c == null) oppnew.Branch__c = null; else oppnew.Branch__c = oppnew.Account.Branch__c; // Update oppnew; } } }
If you plan on doing select statements where you return Ids, you would write it like this:
The keySet() will return a Map of Ids, whereas Trigger.new returns an array of opportunity objects.
Message Edited by Whyser on 11-13-2008 10:27 AM
Much simpler than keeping two denormalized fields in sync.
What you want to do is add a new formula field of type Text to Opportunity (say, "Related Branch") so the formula looks like this:
Related Branch (Text) =
Now you have a custom field on Opportunity called Related_Branch__c that contains the value of the Opportunity's Account's Branch's Name field, and it's always in sync.
It all comes down to how you want to use this field.
- If you need the Branch ID when you are querying Opportunities in SOQL (from Apex or an integration) you don't need a formula field at all--you can just included "Account.Branch__c" (or the equivalent "Account.Branch__r.Id") in your SELECT statement and it will pull down that information in your query.
- If you want to display fields from the Branch on the Opportunity page layout, then you'll need to create the explicit formula field(s) on Opportunity referencing Branch fields across the Account relationship.
If you go the formula field path, use the "Insert Field" button to easily find the field you're looking for and insert it into the formula text area.Hi Whyser,
I like the idea of using the workflow rule however, it Looks like I can't use a workflow rule to update a lookup field. it's not available for update in the drop-down list.
I also toyed with Jon's suggestion of changing the field to a formula
that however will entail additional changes to s-controls etc. we already have customized.
Sooo I think my only option is the trigger but still having issues getting the update to occur without the recursive update.
Thanks for the suggestions!
You're probably going to have to go through your trigger step by step then:
- Use Apex Explorer or Eclipse to ensure that the query you're attempting to run returns the correct data (replace your Trigger.newMap.keySet() with an actual opportunity id or multiple Ids)
- Write some System.Debug(' '); statements in places around your trigger to ensure you're getting the right data.
- Write your testmethod code that will run this trigger, and then either in Salesforce or Eclipse, run the tests and view your debug log for your System.Debug statements.
Message Edited by Whyser on 11-17-2008 08:19 AM
I must admit I'm skeptical about your statement that your existing s-controls would be impacted by using a formula field rather than a trigger. It sounds like you have a lookup field right now, but it doesn't work, so none of your s-controls that use that field would work either. If your s-controls need an Id value rather than a Name, create a lookup to the Id instead. If you need both the branch Id and Name (e.g. for s-controls and for page layouts) then use both.
If your s-controls are setting the Branch__c lookup field, doesn't that interfere with your trigger logic anyway?
Could you say more about the s-control/other constraints that are driving you to use a trigger (which based on my current understanding sounds very much like the wrong long term solution)?
Thanks,
Jon
I must admit I'm skeptical about your statement that your existing s-controls would be impacted by using a formula field rather than a trigger. It sounds like you have a lookup field right now, but it doesn't work, so none of your s-controls that use that field would work either. If your s-controls need an Id value rather than a Name, create a lookup to the Id instead. If you need both the branch Id and Name (e.g. for s-controls and for page layouts) then use both.
If your s-controls are setting the Branch__c lookup field, doesn't that interfere with your trigger logic anyway?
Could you say more about the s-control/other constraints that are driving you to use a trigger (which based on my current understanding sounds very much like the wrong long term solution)?
"
But I am still having an issue with the Opportunity Update. I am not real handy with apex code and have been struggling to find just some simple samples. I think what i'm doing is more complicated then it needs to be.
thanks, Jackie
my last attempt resulted in this error:
Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger OppBranchEqualAccBranch_Update caused an unexpected exception, contact your administrator: OppBranchEqualAccBranch_Update: execution of BeforeUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id 006T0000003uCfZIAU; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = 006T0000003uCfZ) is currently being updated in trigger OppBranchEqualAccBranch_Update: [Id]: Trigger.OppBranchEqualAccBranch_Update: line 34, column 5
// This loop iterates over the list, and adds any that have updates
for (Integer i = 0; i < Trigger.new.size(); i++) {
updOpps.put(Trigger.old[i].id, Trigger.new[i]);
}
// 1) iterating over an embedded SOQL query
// 2) binding an array directly to a SOQL query with 'in'
FROM opportunity WHERE Id in :updOpps.keySet()]) {
// Rather than insert the contacts individually, add the
// contacts to a list and bulk insert it. This makes the
// trigger run faster and allows us to avoid hitting the
// governor limit on DML statements
}
}
All the values in Trigger.New will be used when saving the record, so you don't need to call an update command.
Message Edited by Whyser on 11-18-2008 01:08 PM