function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
nil_von_9wonil_von_9wo 

Trying to figure out the best way to update several totals

We have a custom object called "Label Orders" which stores a number "Number of Labels" and two rollups (of a custom object "Label Lookups") "Total Lookups" and "Total Unique Lookups").  The last rollup filters by Label_Lookup__c.First_Lookup = true, which is made true as required by a trigger on Label Lookup.

 

Each "Label Order" is associated with both an Account object and a Product object. 

 

For each Account object and Product object, we need to keep track of:

 

1. Total Number of Labels

2. Total Number of Lookups

3. Total Number of Unique Lookups.

 

Unfortunately, due to limitations within SalesForce,  I can't simply use rollups of the Label Orders since I can't make either Account and Product as master's of Label Order.

 

As SalesForce govern's lines of script execution and database queries, I'm wondering what might be the best way to keep these totals accurate. 

Best Answer chosen by Admin (Salesforce Developers) 
nil_von_9wonil_von_9wo

Seems the problem was that some old records didn't include a default value (i.e., zero) for totals; it was attempting to dereference these that caused the problem.

 

Easily fixed by inserting

 

 

if (a.PiqqoLabels__Total_Unique_Lookups__c == null) {a.PiqqoLabels__Total_Unique_Lookups__c = 0;}

 

Before the line in question. 

 

 

 

 Complete solution:

 

 

trigger markFirstLabelLookupBeforeInsert on PiqqoLabels__Label_Lookup__c (before insert) { /** * Create and Initialize variables */ // Get Label Lookup List List<PiqqoLabels__Label_Lookup__c> triggerList = trigger.new; // Create set for UNIQUE numbers looked up. Set<String> lookedNumberSet = new Set<String>(); Map<String, PiqqoLabels__Label_Lookup__c> previouslyLookedNumberMap = new Map<String, PiqqoLabels__Label_Lookup__c>(); Map<string, Id> lookedNumberOrderIdMap = new Map<string, Id>(); Set<Id> lookedOrderSet = new Set<Id>(); Map<Id, double> addToLookMap = new Map<Id, double>(); Map<Id, double> addToUniqueLookMap = new Map<Id, double>(); // Populate set of unique numbers from the trigger list for (PiqqoLabels__Label_Lookup__c triggerLabelLookup: triggerList) { if(triggerLabelLookup.Label_Number__c == null) return; if (!lookedNumberSet.contains(triggerLabelLookup.Label_Number__c)) { lookedNumberSet.add(triggerLabelLookup.Label_Number__c); previouslyLookedNumberMap.put(triggerLabelLookup.Label_Number__c, triggerLabelLookup); lookedNumberOrderIdMap.put (triggerLabelLookup.Label_Number__c, triggerLabelLookup.Label_Batch__c); } // Collect batch data (which batches, how many looks?) lookedOrderSet.add(triggerLabelLookup.PiqqoLabels__Label_Batch__c); MapToolkit.addOneToMap(triggerLabelLookup.PiqqoLabels__Label_Batch__c, addToLookMap); } // Create complete list of Label Lookups of these Label Numbers flagged as "First Lookup". List<PiqqoLabels__Label_Lookup__c> labelLookupList = new List<PiqqoLabels__Label_Lookup__c>([ Select First_Lookup__c, Label_Number__c, Label_Batch__c from PiqqoLabels__Label_Lookup__c where ( (Label_Number__c In : lookedNumberSet) AND (First_Lookup__c = true) ) ]); // Check if lookedNumbers with First_Lookup__c is already in database. // If not, flag first (and only first) object in triggerList as "First Lookup". for (String lookedNumber : lookedNumberSet) { // Assume lookedNumber is not in database boolean isIn = false; // Loop through database for (PiqqoLabels__Label_Lookup__c oldLook: labelLookupList) { // If lookedNumber is in database, assumption was false: value = true. isIn |= (lookedNumber == oldLook.Label_Number__c); // no need to complete loop once value is known true. if (isIn) break; } // if value is still false, the trigger lookup is the first. if (!isIn) { previouslyLookedNumberMap.get(lookedNumber).First_Lookup__c = (!isIn); MapToolkit.addOneToMap(lookedNumberOrderIdMap.get(lookedNumber) , addToUniqueLookMap); System.debug('&&&&&&&&&&&&&&&&&&& Order Id = ' + lookedNumberOrderIdMap.get(lookedNumber)); System.debug('&&&&&&&&&&&&&&&&&&& Add amount = ' + addToUniqueLookMap.get(lookedNumberOrderIdMap.get(lookedNumber))); } } // Totals for ORDERS have been mapped. // ************************************************************************ // Get relevant orders List<Label_Order__c> labelOrdersList = New List<Label_Order__c>( [ select id, PiqqoLabels__Account__c, PiqqoLabels__Product__c from Label_Order__c where id in :lookedOrderSet ] ); Set<Id> OrderAccountSet = New Set<Id>(); Map<Id, double> addToAccountLookMap = new Map<Id, double>(); Map<Id, double> addToAccountUniqueLookMap = new Map<Id, double>(); Set<Id> OrderProductSet = New Set<Id>(); Map<Id, double> addToProductLookMap = new Map<Id, double>(); Map<Id, double> addToProductUniqueLookMap = new Map<Id, double>(); for (Label_Order__c o : labelOrdersList) { OrderAccountSet.add(o.PiqqoLabels__Account__c); MapToolkit.addToMap(o.PiqqoLabels__Account__c, addToAccountLookMap, addToLookMap.get(o.id)); MapToolkit.addToMap(o.PiqqoLabels__Account__c, addToAccountUniqueLookMap, addToUniqueLookMap.get(o.id)); OrderProductSet.add(o.PiqqoLabels__Product__c); MapToolkit.addToMap(o.PiqqoLabels__Product__c, addToProductLookMap, addToLookMap.get(o.id)); MapToolkit.addToMap(o.PiqqoLabels__Product__c, addToProductUniqueLookMap, addToUniqueLookMap.get(o.id)); } // Get Accounts and Products to update List<Account> accountsToUpdate = new List<Account>([ select id, PiqqoLabels__Total_Lookups__c, PiqqoLabels__Total_Unique_Lookups__c from Account where (id in :OrderAccountSet) ]); List<Product2> productsToUpdate = new List<Product2>([ select id, PiqqoLabels__Total_Lookups__c, PiqqoLabels__Total_Unique_Lookups__c from Product2 where (id in :OrderProductSet) ]); for (Account a : accountsToUpdate) { if (a.PiqqoLabels__Total_Lookups__c == null) {a.PiqqoLabels__Total_Lookups__c = 0;} a.PiqqoLabels__Total_Lookups__c += addToAccountLookMap.get(a.id); System.debug('&&&&&&&&&&&&&&&&&&& Account Id = ' + a.id); System.debug('&&&&&&&&&&&&&&&&&&& Add amount = ' + addToAccountUniqueLookMap.get(a.id)); if (addToAccountUniqueLookMap.get(a.id) != null) { if (a.PiqqoLabels__Total_Unique_Lookups__c == null) {a.PiqqoLabels__Total_Unique_Lookups__c = 0;} System.debug('&&&&&&&&&&&&&&&&&&& Account Id = ' + a.id); System.debug('&&&&&&&&&&&&&&&&&&& Old amount = ' + a.PiqqoLabels__Total_Unique_Lookups__c); System.debug('&&&&&&&&&&&&&&&&&&& Add amount = ' + addToAccountUniqueLookMap.get(a.id)); a.PiqqoLabels__Total_Unique_Lookups__c += addToAccountUniqueLookMap.get(a.id); System.debug('&&&&&&&&&&&&&&&&&&& New amount = ' + a.PiqqoLabels__Total_Unique_Lookups__c); } } update accountsToUpdate; for (Product2 p : productsToUpdate) { if (p.PiqqoLabels__Total_Lookups__c == null) {p.PiqqoLabels__Total_Lookups__c = 0;} p.PiqqoLabels__Total_Lookups__c += addToProductLookMap.get(p.id); if (addToProductUniqueLookMap.get(p.id) != null) { if (p.PiqqoLabels__Total_Unique_Lookups__c == null) {p.PiqqoLabels__Total_Unique_Lookups__c = 0;} p.PiqqoLabels__Total_Unique_Lookups__c += addToProductUniqueLookMap.get(p.id); } } update productsToUpdate;}

 

 

 

Message Edited by nil_von_9wo on 08-15-2009 04:00 AM

All Answers

aalbertaalbert

You could write triggers that "on insert" of the children records, updates a counter field on the related/parent objects (Account, Product). Instead of doing the full calculation, just use triggers to add one or subtract one from the appropriate totals.

 

 

nil_von_9wonil_von_9wo

That could help for keeping a total of the Lookup records (assuming those records are never modified), which are technicaly "grandchildren" of Account and Product.

 

For the Total Number of Labels, it would be more complicated, as

 

1. An arbitrary number of labels could be ordered at once.

2. An order may be modified or canceled prior to being fulfilled. 

 

 

aalbertaalbert

The trigger logic should be written to handle many labels being processed (inserted, updated, deleted) at once regardless. So you can have logic to figure out how many labels were added, how many labels were changed, and how many were deleted. Then apply the updated totals or calculations to the grandparent records.

 

 

nil_von_9wonil_von_9wo

So I modified some existing code, hoping it would update the Total Number of Labels for both Accounts and Products while it performed its previous function

 

Unfortunately, while it executes without error, it also seems to be executing without effect (with regard to the totals; the previous date updating is still working).  Any idea what is going wrong here?

 

 

/** * * This function was originally intended (and still does) update Last Order Date on Products * Additionally, (for statistical purposes) it updates the total number of labels * for both Accounts and Products * */trigger UpdateLastLabelOrder on Label_Order__c (after delete, after insert, after undelete, after update) { // Get trigger list List<Label_Order__c> triggerList = (trigger.isDelete || trigger.isUndelete ? trigger.old : trigger.new); // Initialize sets Set<Id> accountIds = new Set<Id>(); Set<Id> productIds = new Set<Id>(); // Collect relevant account ids and product ids into sets. for (Label_Order__c labelOrder: triggerList) { if(labelOrder.Product__c == null) return; accountIds.add(labelOrder.Account__c); productIds.add(labelOrder.Product__c); } // Collect relevant accounts with needed fields List<Account> accountList = new List<Account>([ Select Id, PiqqoLabels__Total_Labels__c from Account where Id In : accountIds]); // Collect relevant products with needed fields List<Product2> prodList = new List<Product2>([ Select Id, Last_Label_Order_Creation_Date__c, Last_Label_Order_Modification_Date__c, PiqqoLabels__Total_Labels__c from Product2 where Id In : productIds]); // Create maps // ... Irrelevant Code Deleted // Create maps for updating totals in accounts Map<Id, double> accountTotalLabelsMap = new Map<Id, double>(); for (Account account: AccountList) { accountTotalLabelsMap.put (account.id, account.PiqqoLabels__Total_Labels__c); } // Create maps for updating totals in products Map<Id, double> productTotalLabelsMap = new Map<Id, double>(); for (Product2 product: prodList) { productTotalLabelsMap.put (product.id, product.PiqqoLabels__Total_Labels__c); } // ************************************************************************************* for (Label_Order__c labelOrder: triggerList) { if(labelOrder.Product__c == null) return; // ... Irrelevant Code Deleted // ***************************************************************************************** // Determine Total Number of Labels double oldValue = (Trigger.oldMap != null) ? (Trigger.oldMap.get(labelOrder.id).Number_of_Labels__c) : 0; System.debug('************ oldValue = ' + oldValue); boolean orderNowVoid = (triggerLabelOrderToolkit.VOIDLABELS.contains(labelOrder.Status__c)); boolean justChangedToVoid = ( trigger.isUpdate && (triggerLabelOrderToolkit.VOIDLABELS.contains(labelOrder.Status__c)) && (!triggerLabelOrderToolkit.VOIDLABELS.contains(trigger.oldMap.get(labelOrder.id).Status__c)) ); double addToTotal = 0; if ( (!trigger.isUpdate) && (!orderNowVoid) ) { addToTotal = labelOrder.Number_of_Labels__c * ((!trigger.isDelete)?1:-1); // multiple by -1 to subtract if delete } else { if ( (trigger.isUpdate) && (!orderNowVoid) ) { addToTotal = labelOrder.Number_of_Labels__c - oldValue; } else { if (orderNowVoid && justChangedToVoid) { addToTotal = -labelOrder.Number_of_Labels__c; } } } System.debug('************ addToTotal = ' + addToTotal); // Determine Total Number of Labels for Account double oldAccountTotal = ( (accountTotalLabelsMap.get(labelOrder.PiqqoLabels__Account__r.id) != null) ? accountTotalLabelsMap.get(labelOrder.PiqqoLabels__Account__r.id) : 0 ); System.debug('************ oldAccountTotal = ' + oldAccountTotal); double newAccountTotal = oldAccountTotal + addToTotal; System.debug('************ newAccountTotal = ' + newAccountTotal); accountTotalLabelsMap.put (labelOrder.PiqqoLabels__Account__r.id, newAccountTotal); System.debug('************ accountTotalLabelsMap = ' + accountTotalLabelsMap.get(labelOrder.PiqqoLabels__Account__r.id)); // ------------------------------------------------------ // Determine Total Number of Labels for Product double oldProductTotal = ( (productTotalLabelsMap.get(labelOrder.PiqqoLabels__Product__r.id) != null) ? productTotalLabelsMap.get(labelOrder.PiqqoLabels__Product__r.id) : 0 ); System.debug('************ oldProductTotal = ' + oldProductTotal); double newProductTotal = oldProductTotal + addToTotal; System.debug('************ newProductTotal = ' + newProductTotal); productTotalLabelsMap.put (labelOrder.PiqqoLabels__Product__r.id, newProductTotal); System.debug('************ productTotalLabelsMap = ' + productTotalLabelsMap.get(labelOrder.PiqqoLabels__Product__r.id)); } // ************************************************************************************* // Update Products for( List<Product2> updateProdList : [ Select Id, Last_Label_Order_Creation_Date__c, Last_Label_Order_Modification_Date__c, PiqqoLabels__Total_Labels__c From Product2 Where Id In : productIds ] ) { for(Product2 p : updateProdList) { // ... Irrelevant Code Deleted if(productTotalLabelsMap.get(p.Id) != null) { p.PiqqoLabels__Total_Labels__c = productTotalLabelsMap.get(p.Id); } } update updateProdList; } // ************************************************************************************* // Update Accounts for( List<Account> updateAccountList : [ Select Id, PiqqoLabels__Total_Labels__c From Account Where Id In : accountIds ] ) { for(Account a : updateAccountList) { if(accountTotalLabelsMap.get(a.Id) != null) { a.PiqqoLabels__Total_Labels__c = accountTotalLabelsMap.get(a.Id); } } update updateAccountList; }}

 

 

Message Edited by nil_von_9wo on 08-13-2009 03:57 PM
nil_von_9wonil_von_9wo

Figured out how to make this code work

 

"labelOrder.PiqqoLabels__Account__r.id" should be "labelOrder.Account__c"

"labelOrder.PiqqoLabels__Product__r.id" should be "labelOrder.Product__c" 

 

... Now I just need to create a separate trigger for tallying the lookups... 

 

-Brian. 

nil_von_9wonil_von_9wo

Making progress, but having a strange problem.

 

When I run the test class and check the log, the trigger below works fine:

 

 

trigger markFirstLabelLookupBeforeInsert on PiqqoLabels__Label_Lookup__c (before insert) { /** * Create and Initialize variables */ // Get Label Lookup List List<PiqqoLabels__Label_Lookup__c> triggerList = trigger.new; // Create set for UNIQUE numbers looked up. Set<String> lookedNumberSet = new Set<String>(); Map<String, PiqqoLabels__Label_Lookup__c> previouslyLookedNumberMap = new Map<String, PiqqoLabels__Label_Lookup__c>(); Map<string, Id> lookedNumberOrderIdMap = new Map<string, Id>(); Set<Id> lookedOrderSet = new Set<Id>(); Map<Id, double> addToLookMap = new Map<Id, double>(); Map<Id, double> addToUniqueLookMap = new Map<Id, double>(); // Populate set of unique numbers from the trigger list for (PiqqoLabels__Label_Lookup__c triggerLabelLookup: triggerList) { if(triggerLabelLookup.Label_Number__c == null) return; if (!lookedNumberSet.contains(triggerLabelLookup.Label_Number__c)) { lookedNumberSet.add(triggerLabelLookup.Label_Number__c); previouslyLookedNumberMap.put(triggerLabelLookup.Label_Number__c, triggerLabelLookup); lookedNumberOrderIdMap.put (triggerLabelLookup.Label_Number__c, triggerLabelLookup.Label_Batch__c); } // Collect batch data (which batches, how many looks?) lookedOrderSet.add(triggerLabelLookup.PiqqoLabels__Label_Batch__c); MapToolkit.addOneToMap(triggerLabelLookup.PiqqoLabels__Label_Batch__c, addToLookMap); } // Create complete list of Label Lookups of these Label Numbers flagged as "First Lookup". List<PiqqoLabels__Label_Lookup__c> labelLookupList = new List<PiqqoLabels__Label_Lookup__c>([ Select First_Lookup__c, Label_Number__c, Label_Batch__c from PiqqoLabels__Label_Lookup__c where ( (Label_Number__c In : lookedNumberSet) AND (First_Lookup__c = true) ) ]); // Check if lookedNumbers with First_Lookup__c is already in database. // If not, flag first (and only first) object in triggerList as "First Lookup". for (String lookedNumber : lookedNumberSet) { // Assume lookedNumber is not in database boolean isIn = false; // Loop through database for (PiqqoLabels__Label_Lookup__c oldLook: labelLookupList) { // If lookedNumber is in database, assumption was false: value = true. isIn |= (lookedNumber == oldLook.Label_Number__c); // no need to complete loop once value is known true. if (isIn) break; } // if value is still false, the trigger lookup is the first. if (!isIn) { previouslyLookedNumberMap.get(lookedNumber).First_Lookup__c = (!isIn); MapToolkit.addOneToMap(lookedNumberOrderIdMap.get(lookedNumber) , addToUniqueLookMap); System.debug('&&&&&&&&&&&&&&&&&&& Order Id = ' + lookedNumberOrderIdMap.get(lookedNumber)); System.debug('&&&&&&&&&&&&&&&&&&& Add amount = ' + addToUniqueLookMap.get(lookedNumberOrderIdMap.get(lookedNumber))); } } // Totals for ORDERS have been mapped. // ************************************************************************ // Get relevant orders List<Label_Order__c> labelOrdersList = New List<Label_Order__c>( [ select id, PiqqoLabels__Account__c, PiqqoLabels__Product__c from Label_Order__c where id in :lookedOrderSet ] ); Set<Id> OrderAccountSet = New Set<Id>(); Map<Id, double> addToAccountLookMap = new Map<Id, double>(); Map<Id, double> addToAccountUniqueLookMap = new Map<Id, double>(); Set<Id> OrderProductSet = New Set<Id>(); Map<Id, double> addToProductLookMap = new Map<Id, double>(); Map<Id, double> addToProductUniqueLookMap = new Map<Id, double>(); for (Label_Order__c o : labelOrdersList) { OrderAccountSet.add(o.PiqqoLabels__Account__c); MapToolkit.addToMap(o.PiqqoLabels__Account__c, addToAccountLookMap, addToLookMap.get(o.id)); MapToolkit.addToMap(o.PiqqoLabels__Account__c, addToAccountUniqueLookMap, addToUniqueLookMap.get(o.id)); OrderProductSet.add(o.PiqqoLabels__Product__c); MapToolkit.addToMap(o.PiqqoLabels__Product__c, addToProductLookMap, addToLookMap.get(o.id)); MapToolkit.addToMap(o.PiqqoLabels__Product__c, addToProductUniqueLookMap, addToUniqueLookMap.get(o.id)); } // Get Accounts and Products to update List<Account> accountsToUpdate = new List<Account>([ select id, PiqqoLabels__Total_Lookups__c, PiqqoLabels__Total_Unique_Lookups__c from Account where (id in :OrderAccountSet) ]); List<Product2> productsToUpdate = new List<Product2>([ select id, PiqqoLabels__Total_Lookups__c, PiqqoLabels__Total_Unique_Lookups__c from Product2 where (id in :OrderProductSet) ]); for (Account a : accountsToUpdate) { a.PiqqoLabels__Total_Lookups__c += addToAccountLookMap.get(a.id); System.debug('&&&&&&&&&&&&&&&&&&& Account Id = ' + a.id); System.debug('&&&&&&&&&&&&&&&&&&& Add amount = ' + addToAccountUniqueLookMap.get(a.id)); if (addToAccountUniqueLookMap.get(a.id) != null) { System.debug('&&&&&&&&&&&&&&&&&&& Account Id = ' + a.id); System.debug('&&&&&&&&&&&&&&&&&&& Old amount = ' + a.PiqqoLabels__Total_Unique_Lookups__c); System.debug('&&&&&&&&&&&&&&&&&&& Add amount = ' + addToAccountUniqueLookMap.get(a.id)); a.PiqqoLabels__Total_Unique_Lookups__c += addToAccountUniqueLookMap.get(a.id); System.debug('&&&&&&&&&&&&&&&&&&& New amount = ' + a.PiqqoLabels__Total_Unique_Lookups__c); } } update accountsToUpdate; for (Product2 p : productsToUpdate) { p.PiqqoLabels__Total_Lookups__c += addToProductLookMap.get(p.id); if (addToProductUniqueLookMap.get(p.id) != null) { p.PiqqoLabels__Total_Unique_Lookups__c += addToProductUniqueLookMap.get(p.id); } } update productsToUpdate;}

 

 

 

 

However, when I manually add a new record, I get an error which makes no sense:

 

Error: Invalid Data. 
Review all error messages below to correct your data.

Apex trigger PiqqoLabels.markFirstLabelLookupBeforeInsert caused an unexpected exception, contact your administrator: PiqqoLabels.markFirstLabelLookupBeforeInsert: execution of BeforeInsert caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.PiqqoLabels.markFirstLabelLookupBeforeInsert: line 126, column 6

 

 

 The line in question is:

 

 

a.PiqqoLabels__Total_Unique_Lookups__c += addToAccountUniqueLookMap.get(a.id);

 

 But if the object was null (which it shouldn't be, and according to the test class log, isn't), this line should never be executed because it sits in the middle of the block:

 

 

if (addToAccountUniqueLookMap.get(a.id) != null) { System.debug('&&&&&&&&&&&&&&&&&&& Account Id = ' + a.id); System.debug('&&&&&&&&&&&&&&&&&&& Old amount = ' + a.PiqqoLabels__Total_Unique_Lookups__c); System.debug('&&&&&&&&&&&&&&&&&&& Add amount = ' + addToAccountUniqueLookMap.get(a.id)); a.PiqqoLabels__Total_Unique_Lookups__c += addToAccountUniqueLookMap.get(a.id); System.debug('&&&&&&&&&&&&&&&&&&& New amount = ' + a.PiqqoLabels__Total_Unique_Lookups__c); }

 

 

Test case log shows:

 

20090815103443.688:Trigger.PiqqoLabels.markFirstLabelLookupBeforeInsert: line 119, column 4: System.debug(String)

20090815103443.688:Trigger.PiqqoLabels.markFirstLabelLookupBeforeInsert: line 119, column 4: &&&&&&&&&&&&&&&&&&& Account Id = 0018000000VVamFAAT

20090815103443.688:Trigger.PiqqoLabels.markFirstLabelLookupBeforeInsert: line 120, column 4: System.debug(String)

20090815103443.688:Trigger.PiqqoLabels.markFirstLabelLookupBeforeInsert: line 120, column 4: &&&&&&&&&&&&&&&&&&& Add amount = 1.0

20090815103443.688:Trigger.PiqqoLabels.markFirstLabelLookupBeforeInsert: line 123, column 6: System.debug(String)

20090815103443.688:Trigger.PiqqoLabels.markFirstLabelLookupBeforeInsert: line 123, column 6: &&&&&&&&&&&&&&&&&&& Account Id = 0018000000VVamFAAT

20090815103443.688:Trigger.PiqqoLabels.markFirstLabelLookupBeforeInsert: line 124, column 6: System.debug(String)

20090815103443.688:Trigger.PiqqoLabels.markFirstLabelLookupBeforeInsert: line 124, column 6: &&&&&&&&&&&&&&&&&&& Old amount = 0

20090815103443.688:Trigger.PiqqoLabels.markFirstLabelLookupBeforeInsert: line 125, column 6: System.debug(String)

20090815103443.688:Trigger.PiqqoLabels.markFirstLabelLookupBeforeInsert: line 125, column 6: &&&&&&&&&&&&&&&&&&& Add amount = 1.0

20090815103443.688:Trigger.PiqqoLabels.markFirstLabelLookupBeforeInsert: line 126, column 6: SOBJECT:Account a.PiqqoLabels__Total_Unique_Lookups__c <= Add

20090815103443.688:Trigger.PiqqoLabels.markFirstLabelLookupBeforeInsert: line 127, column 6: System.debug(String)

20090815103443.688:Trigger.PiqqoLabels.markFirstLabelLookupBeforeInsert: line 127, column 6: &&&&&&&&&&&&&&&&&&& New amount = 1.0 

 

 

So, how can this be going wrong and how might I fix it? 

 

 

nil_von_9wonil_von_9wo

Seems the problem was that some old records didn't include a default value (i.e., zero) for totals; it was attempting to dereference these that caused the problem.

 

Easily fixed by inserting

 

 

if (a.PiqqoLabels__Total_Unique_Lookups__c == null) {a.PiqqoLabels__Total_Unique_Lookups__c = 0;}

 

Before the line in question. 

 

 

 

 Complete solution:

 

 

trigger markFirstLabelLookupBeforeInsert on PiqqoLabels__Label_Lookup__c (before insert) { /** * Create and Initialize variables */ // Get Label Lookup List List<PiqqoLabels__Label_Lookup__c> triggerList = trigger.new; // Create set for UNIQUE numbers looked up. Set<String> lookedNumberSet = new Set<String>(); Map<String, PiqqoLabels__Label_Lookup__c> previouslyLookedNumberMap = new Map<String, PiqqoLabels__Label_Lookup__c>(); Map<string, Id> lookedNumberOrderIdMap = new Map<string, Id>(); Set<Id> lookedOrderSet = new Set<Id>(); Map<Id, double> addToLookMap = new Map<Id, double>(); Map<Id, double> addToUniqueLookMap = new Map<Id, double>(); // Populate set of unique numbers from the trigger list for (PiqqoLabels__Label_Lookup__c triggerLabelLookup: triggerList) { if(triggerLabelLookup.Label_Number__c == null) return; if (!lookedNumberSet.contains(triggerLabelLookup.Label_Number__c)) { lookedNumberSet.add(triggerLabelLookup.Label_Number__c); previouslyLookedNumberMap.put(triggerLabelLookup.Label_Number__c, triggerLabelLookup); lookedNumberOrderIdMap.put (triggerLabelLookup.Label_Number__c, triggerLabelLookup.Label_Batch__c); } // Collect batch data (which batches, how many looks?) lookedOrderSet.add(triggerLabelLookup.PiqqoLabels__Label_Batch__c); MapToolkit.addOneToMap(triggerLabelLookup.PiqqoLabels__Label_Batch__c, addToLookMap); } // Create complete list of Label Lookups of these Label Numbers flagged as "First Lookup". List<PiqqoLabels__Label_Lookup__c> labelLookupList = new List<PiqqoLabels__Label_Lookup__c>([ Select First_Lookup__c, Label_Number__c, Label_Batch__c from PiqqoLabels__Label_Lookup__c where ( (Label_Number__c In : lookedNumberSet) AND (First_Lookup__c = true) ) ]); // Check if lookedNumbers with First_Lookup__c is already in database. // If not, flag first (and only first) object in triggerList as "First Lookup". for (String lookedNumber : lookedNumberSet) { // Assume lookedNumber is not in database boolean isIn = false; // Loop through database for (PiqqoLabels__Label_Lookup__c oldLook: labelLookupList) { // If lookedNumber is in database, assumption was false: value = true. isIn |= (lookedNumber == oldLook.Label_Number__c); // no need to complete loop once value is known true. if (isIn) break; } // if value is still false, the trigger lookup is the first. if (!isIn) { previouslyLookedNumberMap.get(lookedNumber).First_Lookup__c = (!isIn); MapToolkit.addOneToMap(lookedNumberOrderIdMap.get(lookedNumber) , addToUniqueLookMap); System.debug('&&&&&&&&&&&&&&&&&&& Order Id = ' + lookedNumberOrderIdMap.get(lookedNumber)); System.debug('&&&&&&&&&&&&&&&&&&& Add amount = ' + addToUniqueLookMap.get(lookedNumberOrderIdMap.get(lookedNumber))); } } // Totals for ORDERS have been mapped. // ************************************************************************ // Get relevant orders List<Label_Order__c> labelOrdersList = New List<Label_Order__c>( [ select id, PiqqoLabels__Account__c, PiqqoLabels__Product__c from Label_Order__c where id in :lookedOrderSet ] ); Set<Id> OrderAccountSet = New Set<Id>(); Map<Id, double> addToAccountLookMap = new Map<Id, double>(); Map<Id, double> addToAccountUniqueLookMap = new Map<Id, double>(); Set<Id> OrderProductSet = New Set<Id>(); Map<Id, double> addToProductLookMap = new Map<Id, double>(); Map<Id, double> addToProductUniqueLookMap = new Map<Id, double>(); for (Label_Order__c o : labelOrdersList) { OrderAccountSet.add(o.PiqqoLabels__Account__c); MapToolkit.addToMap(o.PiqqoLabels__Account__c, addToAccountLookMap, addToLookMap.get(o.id)); MapToolkit.addToMap(o.PiqqoLabels__Account__c, addToAccountUniqueLookMap, addToUniqueLookMap.get(o.id)); OrderProductSet.add(o.PiqqoLabels__Product__c); MapToolkit.addToMap(o.PiqqoLabels__Product__c, addToProductLookMap, addToLookMap.get(o.id)); MapToolkit.addToMap(o.PiqqoLabels__Product__c, addToProductUniqueLookMap, addToUniqueLookMap.get(o.id)); } // Get Accounts and Products to update List<Account> accountsToUpdate = new List<Account>([ select id, PiqqoLabels__Total_Lookups__c, PiqqoLabels__Total_Unique_Lookups__c from Account where (id in :OrderAccountSet) ]); List<Product2> productsToUpdate = new List<Product2>([ select id, PiqqoLabels__Total_Lookups__c, PiqqoLabels__Total_Unique_Lookups__c from Product2 where (id in :OrderProductSet) ]); for (Account a : accountsToUpdate) { if (a.PiqqoLabels__Total_Lookups__c == null) {a.PiqqoLabels__Total_Lookups__c = 0;} a.PiqqoLabels__Total_Lookups__c += addToAccountLookMap.get(a.id); System.debug('&&&&&&&&&&&&&&&&&&& Account Id = ' + a.id); System.debug('&&&&&&&&&&&&&&&&&&& Add amount = ' + addToAccountUniqueLookMap.get(a.id)); if (addToAccountUniqueLookMap.get(a.id) != null) { if (a.PiqqoLabels__Total_Unique_Lookups__c == null) {a.PiqqoLabels__Total_Unique_Lookups__c = 0;} System.debug('&&&&&&&&&&&&&&&&&&& Account Id = ' + a.id); System.debug('&&&&&&&&&&&&&&&&&&& Old amount = ' + a.PiqqoLabels__Total_Unique_Lookups__c); System.debug('&&&&&&&&&&&&&&&&&&& Add amount = ' + addToAccountUniqueLookMap.get(a.id)); a.PiqqoLabels__Total_Unique_Lookups__c += addToAccountUniqueLookMap.get(a.id); System.debug('&&&&&&&&&&&&&&&&&&& New amount = ' + a.PiqqoLabels__Total_Unique_Lookups__c); } } update accountsToUpdate; for (Product2 p : productsToUpdate) { if (p.PiqqoLabels__Total_Lookups__c == null) {p.PiqqoLabels__Total_Lookups__c = 0;} p.PiqqoLabels__Total_Lookups__c += addToProductLookMap.get(p.id); if (addToProductUniqueLookMap.get(p.id) != null) { if (p.PiqqoLabels__Total_Unique_Lookups__c == null) {p.PiqqoLabels__Total_Unique_Lookups__c = 0;} p.PiqqoLabels__Total_Unique_Lookups__c += addToProductUniqueLookMap.get(p.id); } } update productsToUpdate;}

 

 

 

Message Edited by nil_von_9wo on 08-15-2009 04:00 AM
This was selected as the best answer