Audience:
NetSuite SuiteScript Developers who are trying to resolve issues related to USAGE LIMIT EXCEEDED issues due to script governance limitations.
Introduction:
Recently we had a client that required us to create a custom commission module within NetSuite. The project was quite extensive and allowed the company to define an extensive number of attributes that could be tracked and managed from an employee’s custom commission record. One of the features that was built into this module was the ability to manage and calculate vendor spiffs by item, which identified and tagged items on invoices. If the item had an associated spiff definition for payouts to employees, it would be tagged. This also allowed us to automatically generate spiff claim invoices to each vendor offering spiff promotions.
Using the new process developed, there were no issues and it was rolled out and managed by the customer’s internal team. However, after six months, system notifications began to arrive via email with the following unfriendly error message:
Type: User Event
Function: beforeSubmit
Error: SSS_USAGE_LIMIT_EXCEEDED
We sought to determine if our script, which looped through the items on an invoice to determine if each item contained a qualifying spiff definition record was the culprit. The issue causing the script to fail and produce the error message was any invoice containing more than 100 items (10 units per lookup, 1,000 units max allowed). This was verified when monitoring the script usage as it processed each item lookup. To monitor the actual usage of scripts during execution, you can add the following code to debug and see the remaining units during execution:
var scriptObj = runtime.getCurrentScript();
log.debug({
title: "Remaining usage units: ",
details: scriptObj.getRemainingUsage()
});
The ‘fail fast’ solution process:
After pondering alternatives, we vacillated on multiple options during the solution design process. The final process needed to look at each item to determine if there was a qualifying spiff in order to tag the item and generate a spiff commission record. However, we needed an alternative solution for how to handle invoices with a large volume of items.
We considered having the user event script count the number of items on the invoice and have it execute a map-reduce script if it exceeded a certain number. This seemed like a great idea initially, until we realized the map-reduce script would fail because it would execute while the user event script was still running and result in a record has changed error.
Even if this had worked, it would have its own issues in that only one instance of the map-reduce script can execute at a time. If multiple records encountered this issue and executed the script, it would fail unless we created multiple deployments and used some round-robin logic to assign execution to one that was not currently running.
Solution:
After walking away from the problem for a few hours, which usually does the trick, an epiphany occurred. By putting all of the items from the invoice into an array, we could execute a single search of the spiff definition records and push the array of items as a filter to the search instead of calling a lookup function for each of the items during execution.
var spiffItems = [];
for (var s = 0; s < lineCount; s++) {
var objectItems = {};
var item = rec.getSublistValue({"sublistId": "item", "fieldId": "item", "line": s});
objectItems.item = item;
spiffItems.push(item);
}
if(spiffItems.length > 0) {
var allSpiffs = getAllSpiffs(spiffItems);
}
Using the above search only items that contained a related spiff definition were returned.
From the results list, we would then loop through the item sublist again and use a nested loop to cycle through the array of results from the search. If the item on the line matched the item in the array, it would then be able to tag the item with the related spiff definition record.
This solution worked perfectly and as a result, governance that previously exceeded 2,000 units (10 units x 200 items) was reduced to only using 10 units for the entire process since we were only executing a single search instead of performing one search for each item.
If you need any assistance in the above mentioned solution, please feel free to connect with NetSuite experts, they will be happy to help you in every way possible.
for (var i = 0; i < lineCount; i++) { //Loop through the item sublist
var item = rec.getSublistValue({"sublistId": "item", "fieldId": "item", "line": i});
for (var j = 0; j < allSpiffs.length; j++) { //loop through the results of the spiff search
var spiffid = allSpiffs[j].getValue('custrecord_spiff_item');
if(item == spiffid) { //compare the item id with the item from the spiff results, if a match update item record
rec.setSublistValue({"sublistId": "item", "fieldId": "custcol_spiff_id", "line": i, value: spiffId});
}
}
}
Conclusion:
When working with NetSuite SuiteScript, it is generally a good practice to consider the script governance limits for each script type and to plan your script development to monitor and account for unexpected occasions where usage limits can become a hindrance.
Utilizing arrays, especially embedding them as filters to perform the same functions, can be a more elegant and efficient way to achieve one’s goals. Ironically, in the week following the implementation of this solution, several other cases for its recommended usage cropped up with other members of our development team and their projects. It was nice to be able to recommend this solution to the customer and hopefully, this approach will help achieve more efficient solutions.
For developer reference, here is a link to Oracle’s Script Type Usage Unit Limits.
About Us
We are a NetSuite Solutions Partner and reseller with 30+ years of combined experience. We specialize in implementation, optimization, integration, rapid project recovery and rescue as well as custom development to meet any business need. If you would like more information on NetSuite or are in need of consultation for your project or implementation, feel free to contact NetSuite support.
To Contact Us Click Here