I hope everyone enjoyed their Halloween weekend. Halloween weekend in San Francisco is amazing; as is every weekend I have spent here. Out of all the cities I have ever been to, east coast and west coast, San Francisco is hands down the most fun. That being said not everything is about my wild nights in the city; my time is primarily focused on becoming a better developer. This leads us into creating our 2nd Apex trigger…. (I’m really good at transitions)
We will utilize the Apex Code editor again to develop our second trigger. Here is a repeat screen shot of what the editor looks like on the Salesforce page:
The trigger we are creating will maintain the invoice’s payment status based on the scheduled payments. Begin by opening the Scheduled Payment object definition by going to ‘Setup’, ‘Build’, then ‘Objects’. Scroll down to the triggers section and hit ‘New’. Replace the blank trigger template with the following code:
// This trigger scans the list of updated Scheduled Payments
// and updates the invoice status if it has changed as a result
// of one of the payments becoming past due or a payment has
// been made.
trigger ScheduledPayment_After_Update on Scheduled_Payment__c
( after update )
{
// Apex Code's maximum batch size for updates, inserts and
// deletes. The final key word indicates a constant.
final Integer MAX_BATCH_SIZE = 200;
List<Scheduled_Payment__c> statusChanges;
List<Scheduled_Invoice__c> updateInvoices;
List<Scheduled_Invoice__c> queryResults;
Set<Id> invoiceIds = new Set<Id>();
statusChanges = new List<Scheduled_Payment__c>();
updateInvoices = new List<Scheduled_Invoice__c>();
// Loop through the updated payments and see if any statuses changed.
// If they did, add them to the statusChanges list.
// The trigger object has two properties containing lists of updated
// objects, new and old. For insert triggers only the new property
// has values.
for ( Integer x = 0; x < trigger.new.size(); x++ )
{
if ( trigger.new[x].Status__c != trigger.old[x].Status__c )
statusChanges.add( trigger.new[x] );
}
// If there aren't any status changes, exit.
if ( statusChanges.size() == 0 )
return;
// Loop through the list of updated payments and get all the
// unique invoice IDs.
// Adding the Ids to a set will ensure that no Ids are
// duplicated within the list.
for ( Scheduled_Payment__c payment : statusChanges)
{
invoiceIds.add( payment.Invoice__c );
}
// Query both the invoice object and the related
// payment objects at once to retrieve their status.
// Only query invoices in invoice ID set.
// Querying child objects is similar to a correlated sub-query
// but the join to the parent object is implicit.
queryResults = [SELECT Id, Status__c, (SELECT Id, Status__c
FROM Scheduled_Payments__r) FROM Scheduled_Invoice__c
WHERE Id IN :invoiceIds];
// Loop through the results and check the status of the
// payments for the affected invoices and add the invoice
// to the update list if the status needs changing.
for ( Scheduled_Invoice__c invoice : queryResults )
{
String newStatus = 'Paid in Full';
// Loop through the Scheduled Payment child objects
// of this invoice, using the Master-Detail relationship
// you defined previously. The relationship name has
// "__r" appended to it to indicate that it's a custom
// relationship.
// The status of each payment is checked. If any
// payment is past due, the invoice is marked past due
// and if all payments are paid, the invoice is marked
// as paid in full, otherwise the invoice is marked as current.
for ( Scheduled_Payment__c payment :
invoice.Scheduled_Payments__r )
{
if ( payment.Status__c != newStatus )
{
if ( payment.Status__c == 'Pending'
&& newStatus == 'Paid in Full' )
{
newStatus = 'Current';
}
else if ( payment.Status__c == 'Past Due' )
{
newStatus = 'Past Due';
}
}
} // payments loop
if ( invoice.Status__c != newStatus )
{
// The invoice status needs to be changed.
// Change the invoice's status and add it to the list
// of invoices to update. Salesforce.com will only modify
// the actual field you update in code, it will not re-save
// the values you pulled from the database.
invoice.Status__c = newStatus;
updateInvoices.add( invoice );
}
// If you're at the batch size limit, update Salesforce.com
// and clear the update list.
if ( updateInvoices.size() == MAX_BATCH_SIZE )
{
Database.update( updateInvoices );
updateInvoices.clear();
}
} // queryResults loop.
// Update Salesforce.com if there are any pending changes.
if ( updateInvoices.size() > 0 )
{
Database.update( updateInvoices );
}
}
This trigger fires after a payment is updated, and if the payment's status changes it checks to see if the parent invoice needs its status updated as well. For example if the payment is past due, the parent invoice changes its status to past due.
Now that both triggers have been completed we will need to test them, which will do in our next post.
No comments:
Post a Comment