You need to sign in to do that
Don't have an account?
Miller 95
Apex Trigger and Testing Question
Hi,
I am new to trigger creation and have mostly built what I wanted which is to have my trigger create a quote automatically once the sales Rep creates the opportunity. The only thing that is missing si to have the trigger also open up that quote that was just created, so the structure would be: Open new Opportunity -> input data -> Click save -> Trigger executes and creates a new quote from that opportunity -> the sales rep lands within the quote ready to select the products (this part is missing.
Not sure if this is possible for a triggers. Here is what I have:
trigger QuoteCreator on Opportunity (after insert, after update) {
Map<Quote, Id> quoteMap = new Map<Quote, Id>();
for (Opportunity o : Trigger.new) {
Quote q = new Quote();
q.name = 'Quote-' + o.name;
q.opportunityId = o.id;
insert q;
quoteMap.put(q, o.accountId);
}
Account[] accList = [SELECT
billingStreet,
billingCity,
billingState,
billingCountry
FROM
Account
WHERE
id IN :quoteMap.values()];
for (Quote quote : quoteMap.KeySet()) {
for (Account a : accList) {
if (quoteMap.get(quote) == a.Id) {
quote.billingStreet = a.billingStreet;
quote.billingCity = a.billingCity;
quote.billingState = a.billingState;
quote.billingCountry = a.billingCountry;
}
update quote;
}
}
}
The second part is creating a test class for it so I can get it moved into production. The Trigger works great within the sandbox, but the testing is needed from what I know about trigger dev into production. Please let me know if I am even doing it right. Here is what I have:
@isTest
private class QuoteCreator {
static testMethod void QuoteCreator() {
Map<Quote, Id> quoteMap = new Map<Quote, Id>();
for (Opportunity o : Trigger.new) {
Quote q = new Quote();
q.name = 'Quote-' + o.name;
q.opportunityId = o.id;
insert q;
quoteMap.put(q, o.accountId);
}
test.startTest();
update quoteMap;
test.stopTest();
}
}
I am new to trigger creation and have mostly built what I wanted which is to have my trigger create a quote automatically once the sales Rep creates the opportunity. The only thing that is missing si to have the trigger also open up that quote that was just created, so the structure would be: Open new Opportunity -> input data -> Click save -> Trigger executes and creates a new quote from that opportunity -> the sales rep lands within the quote ready to select the products (this part is missing.
Not sure if this is possible for a triggers. Here is what I have:
trigger QuoteCreator on Opportunity (after insert, after update) {
Map<Quote, Id> quoteMap = new Map<Quote, Id>();
for (Opportunity o : Trigger.new) {
Quote q = new Quote();
q.name = 'Quote-' + o.name;
q.opportunityId = o.id;
insert q;
quoteMap.put(q, o.accountId);
}
Account[] accList = [SELECT
billingStreet,
billingCity,
billingState,
billingCountry
FROM
Account
WHERE
id IN :quoteMap.values()];
for (Quote quote : quoteMap.KeySet()) {
for (Account a : accList) {
if (quoteMap.get(quote) == a.Id) {
quote.billingStreet = a.billingStreet;
quote.billingCity = a.billingCity;
quote.billingState = a.billingState;
quote.billingCountry = a.billingCountry;
}
update quote;
}
}
}
The second part is creating a test class for it so I can get it moved into production. The Trigger works great within the sandbox, but the testing is needed from what I know about trigger dev into production. Please let me know if I am even doing it right. Here is what I have:
@isTest
private class QuoteCreator {
static testMethod void QuoteCreator() {
Map<Quote, Id> quoteMap = new Map<Quote, Id>();
for (Opportunity o : Trigger.new) {
Quote q = new Quote();
q.name = 'Quote-' + o.name;
q.opportunityId = o.id;
insert q;
quoteMap.put(q, o.accountId);
}
test.startTest();
update quoteMap;
test.stopTest();
}
}
This is not possible with a trigger because triggers are not directly linked to the Salesforce UI. Creating an opportunity can happen from anywhere (UI or any of the various APIs available). The only way to do this is to override the default Opportunity "New" page with a custom visualforce page and controller. You would have to override the standard "save" method in the controller and manually insert the quote in that method in order to get the ID of the of quote so you could send them to the desired page.
That may be a bunch of jibber-jabber to you, but overall, I would say avoid it. It isn't a pretty solution and it would be very difficult to maintain. Urge your Sales team to simply click on the newly created quote after inserting the opporunity.
I hope that helps!
See this code:
The idea here is that you don't want to insert quotes and then update them. Ideally you insert all of them at once with all the information they need from the beginning. Here I first gather all of the Account IDs, then gather the billing information from those records, then go through the opporunities and create quotes for all of them. Finally, I insert all of the quotes at once at the end.
You test class should look a little different as well:
The idea here is that you want to actually test the functionality of the Opportunity trigger. You want to insert opportunities and check that quotes are inserted. I first set up the account, then 200 opportunities. After inserting the opportunities (notice the startTest/stopTest is around the functionality we are testing), I query for quotes and verify they have the right info.
Test classes do not share data with your org (and data is rolled back when the test is finished executing), so querying for all quotes will only give you quotes inserted in your test class.
Let me know if this helps!
Now on the testing piece; am I going about it the right way or am I way off? When trying to get it moved into production I get the typical erros: 0% tested and need 1%, also overall of 73% class tested and you need 75%.
One final comment, you should probably remove your "after update" from the trigger. I would hate to see a new quote created EVERY time an opportunity was updated.