Here is the way to Automatically
Sync new Quote with Opportunity in Apex Trigger. Before that some of the information
about Quote and Opportunity Field Details that are,
In Quote object there is a field called IsSyncing, This is a Read Only field in
salesforce. If you run the below snippet in developer console the field result
such as isCreatable, isUpdatable is false. So you can’t create/update this
field value.
1.
Schema.DescribeFieldResult dfr = Schema.sObjectType.Quote.fields.IsSyncing;
2.
System.debug(dfr);
In Opportunity object there is a field called SyncedQuoteID, If you run the below
snippet in developer console the field result such as isCreatable, isUpdatable
is True. I.e. you can do insert and update on this field.
1.
Schema.DescribeFieldResult dfr = Schema.sObjectType.Opportunity.fields.SyncedQuoteId;
2.
System.debug(dfr);
But if you update the Opportunity field SyncedQuoteID in a trigger, you will
get the below error.
“The
opportunity SyncedQuote field is read only within a trigger”
For security reason
by default in salesforce trigger you can’t update the SyncedQuoteID field even
if you move the update coding in to separate class.
To overcome this
problem you need to go for @future, By using this it will go with the separate transaction
and the DML operation allowed. The below code snippet will useful to this
problem.
Apex Trigger
trigger QuoteAutoSync on Quote (after insert)
{
Map<Id, Id> quoteMap = new Map<Id, Id>();
for(Quote currentQuote : Trigger.New)
{
quoteMap.put(currentQuote.Id, currentQuote.OpportunityId);
}
QuoteAutoSyncUtil.syncQuote(quoteMap);
}
Apex Class
public class QuoteAutoSyncUtil
{
@future
public static void syncQuote(Map<Id, Id> quoteMap)
{
Map<Id, Opportunity> oppMap = new Map<Id, Opportunity>();
for(Id currentQuote : quoteMap.keyset())
{
Opportunity opp = new Opportunity();
opp.Id = quoteMap.get(currentQuote);
opp.SyncedQuoteId = currentQuote;
oppMap.put(opp.Id, opp);
}
update oppMap.values();
}
}
Test Class
@isTest
private class TestQuoteAutoSync
{
static testMethod void insertQuote()
{
Opportunity opp = new Opportunity();
opp.Name = 'Test Opportunity';
opp.StageName = 'Prospecting';
opp.CloseDate = system.today();
insert opp;
Quote quo = new Quote();
quo.Name = 'Test Quote';
quo.OpportunityId = opp.Id;
Test.startTest();
insert quo;
Test.stopTest();
Opportunity o = [select SyncedQuoteId from opportunity where id=:opp.Id];
system.assert(o.SyncedQuoteId != null);
}
}