- Insert of Project from Opportunity trigger.
- Update of Project from Opportunity trigger.
trigger OpportunityUpdateProjectTrigger on Opportunity ( after insert ) {
// Create List of Projects that we will insert.
List<Project__c> createProjectList = new List<Project__c>();
// Going through all Opportunities and creating Project for each one.
for( Opportunity opportunityItem : trigger.new )
createProjectList.add( new Project__c( Name = opportunityItem.Name,
Opportunity__c = opportunityItem.Id ) );
if ( !createProjectList.isEmpty() ){
try{
// Trying to insert Projects.
insert createProjectList;
} catch( DMLException dmlEx ){
// Going through all errors.
for( Integer i = 0; i < dmlEx.getNumDml(); i++ ){
String errorMessage = 'Error on creation of Project: ' + dmlEx.getDmlMessage( i );
// Attaching error to appropriate Opportunity from Trigger.newMap.
trigger.newMap.get( createProjectList[ dmlEx.getDmlIndex( i ) ].Opportunity__c ).addError(errorMessage);
}
}
}
}
Lets look what we can use in second case, where we have try/catch on update. Here we have update of Project on update of Opportunity. Trigger on Opportunity after update will query from database Projects that are related to this Opportunities, make some changes and update them. On update of Projects can be errors that we need to display on appropriate Opportunity, like in first case. But here we have Project Id. For this we will use DMLException method getDmlId, that returns Id of failed objects. We can use getDmlIndex, like previously. But in this case it would be better to use DMLException method getDmlId() will return Id of failed object. Lets look in to the code:
trigger OpportunityUpdateProjectTrigger on Opportunity ( after update ) {
// Create Map of Projects that we will updated.
Map<id,Project__c> projectsToUpdateMap =
new Map<id,Project__c>( [SELECT Id, Opportunity__c
FROM Project__c
WHERE Opportunity__c IN : trigger.newMap.keySet() ] );
/*
Here we have some updates on projects.
*/
if( !projectsToUpdateMap.keySet().isEmpty() ){
try{
// Trying to update Projects.
update projectsToUpdateMap.values();
} catch( DMLException dmlEx ){
for( Integer i = 0; i < dmlEx.getNumDml(); i++ ){
String errorMessage = 'Error creation of Project: ' + dmlEx.getDmlMessage( i );
// Attaching error to appropriate Opportunity from Trigger.newMap.
trigger.newMap.get( projectsToUpdateMap.get( dmlEx.getDmlId( i ) ).Opportunity__c ).addError( errorMessage );
}
}
}
}
So now we know we know how to add errors to failed one, and can make one more thing. In both cases valid Projects were not inserted, and as they didn't get errors we can try insert them in catch. For this we need to create new list of Projects that will include only valid ones and insert it.
...
try{
insert createProjectList;
} catch( DMLException dmlEx ){
// Crete new list of Projects to insert and fill it from old one
List<Project__c> validProjectsToInsert = createProjectList;
// Going through all errors.
for( Integer i = 0; i < dmlEx.getNumDml(); i++ ){
String errorMessage = 'Error on creation of Project: ' + dmlEx.getDmlMessage( i );
trigger.newMap.get ( createProjectList[ dmlEx.getDmlIndex( i ) ].Opportunity__c ).addError(errorMessage);
// Remove failed one
validProjectsToInsert.remove( dmlEx.getDmlIndex( i ) );
}
// And final insert of valid
insert validProjectsToInsert;
}
...
In the end want to say that we can also use getDmlType() and getDmlStatusCode() to identify what specific error was. Or getDmlFields() with getDmlFieldNames() to know if error was on fields.
Enjoy.
No comments:
Post a Comment