1. Guidelines
NetSuite SuiteScript 2.x API guidelines are a set of rules and best practices that developers should follow while using SuiteScript APIs. These guidelines are designed to ensure consistency and maintainability of SuiteScript code, as well as to optimize the performance of SuiteScript scripts.
Some of the key consideration before we proceed with customization are:
- Walkthrough the standard functionality (terms and functionalities)
- This will help us to understand how the current system behaves and what is the required change.
- Does enabling of any NetSuite feature will impact the customization
- We need to investigate whether enabling any new features or using any existing feature will impact our customization.
- For example: If we consider only Inventory Item types for our requirement, and if the customer choses to uses Kit Item in the future, then we have to define the scope of our customization before proceeding with it
- Does it impact existing customization
- We have to investigate whether there are any other customization/workflows already deployed in the account which will affect the functionality of our new customization as well as how the functionality in the new customization effect existing business process.
- Determine which SuiteScript is best suited for Situation
- We have to analyze which SuiteScript type is best suited for the situation. We need to determine whether we need server-side script, client-side script or scheduled script for this and what are the drawback for each of these. We must consider both usage governance as well as time governance for each SuiteScript type.
- For example: If we need to do a validation when the record is saved, client script can validate it only when the user create the record via User-Interface whereas User Event script can do the validation in all scenarios including CSV import, Integration etc.
- Required SuiteScript 2.0 modules and governance
- We need to have a better understanding on which are the NetSuite 2.0 modules which we will be using, the governance for each of this as well as the usage limit on the SuiteScript.
- Concurrency Limit
- If we are dealing with integration, we need to identify the current concurrency limit and whether the mechanism are in place to address the concurrency issue.
- Does the User’s Set Preference will have any impact on the customization
- We have to investigate whether changes the User’s preference such as Date format will impact our customization.
- Usage of account specific Internal IDs
- We need to determine whether our customization will be using has any account specific Internal IDs, URLs etc. If it does, we need to determine whether we can dynamically resolve it based on the environment or whether we need to store it in a constant library file or custom records/fields.
- Checking NetSuite environment for Integrations
- If there is an integration or SFTP connection in place, we need to check the NetSuite environment and dynamically resolve the API credentials.
- For example: Consider there is an integration running in a scheduled manner (runs every hour) on the NetSuite production instance which sends transaction data to a third-party production/live instance. If there happens to a Sandbox refresh for Sandbox or Release Preview account, then the code executing on the production will starts to execute on the Sandbox or Release preview account.
- Context awareness
- We need to determine whether on which all context should our customization works.
- For example:
- a) If our validation needs to run on save action of record, then it might nor be required on delete context.
- b) If an integration sets some values on fields, then on Copy context we might need to reset the values on those fields.
- Role, Employee, Department, Subsidiary awareness
- We need to determine whether for which all roles/departments/subsidiaries/employees should our customization works.
- Impact of bundle
- If we plan to move the customization from Sandbox to Production instance via SuiteBundle, then we need to identify the risk associated with it such as
- a) Whether the bundle will overwrite the values in production
- b) Whether the bundle will duplicate the fields/records in production
- c) Whether the bundle will merge with the existing values in production
- Performance Degradation
- We need to identify the performance impact of our customization and resolve it by identify the right SuiteScript type as well as optimizing our code.
- Impact of new NetSuite Release or update in SuiteApp/SuiteBundle
- We need to identify if any new release or update in SuiteApp/SuiteBundle can cause an issue with the expected
- behavior of the customization. If it does, then we have to define the scope of our customization before proceeding with it.
- Unit of Measure, Multi-Currency, Price-Level, Multi-Department, Multi-Location, Multi Segments, Approval-Routing, etc.
- If the features such as Unit of Measure, Multi-Currency, Price-Level, Multi-Department, Multi-Location, Multi-Segments, Approval, etc are enabled in the NetSuite account, and any change in its value on the record can effect our customization, then we have to define the scope of our customization before proceeding with it.
- Order of precedence in Script/Workflow
- We need to investigate whether the order of precedence of SuiteScript or Workflow can impact our customization.
- For example: The after-submit event of User-Event script is triggered before the after-submit event of Workflow.
- Likewise, there is precedence in order during execution among multiple User-Event scripts or Workflows.
2. Deploying Customization/SuiteScript/Workflows
Before deploying customization or SuiteScript in NetSuite, it is important to consider the following:
- Performance impact
- Customizations and scripts can have a significant impact on the performance of NetSuite, particularly when they involve large data sets or complex logic. It is important to thoroughly test customizations and scripts before deploying them to ensure that they do not adversely affect system performance.
- Data integrity
- Customizations and scripts can affect the integrity of data in NetSuite. It is important to ensure that customizations and scripts are thoroughly tested to ensure that they do not create data inconsistencies or other problems.
- Security
- Customizations and scripts can potentially create security vulnerabilities in NetSuite. It is important to ensure that customizations and scripts are designed with security in mind and are thoroughly tested to ensure that they do not create security risks.
- Compatibility
- Customizations and scripts can be impacted by updates and changes to NetSuite. It is important to ensure that customizations and scripts are designed to be compatible with future updates and changes to NetSuite.
- Maintenance
- Customizations and scripts require ongoing maintenance and support. It is important to ensure that adequate knowledge on each project are well documented and are available to maintain and support customizations and scripts over the long term.
By considering these factors before deploying customizations and scripts in NetSuite, we can ensure that their systems are stable, secure, and optimized for performance.
3. SuiteScript Best Practices
- Always thoroughly test your code before using it on your live NetSuite data.
- Type all record, field, sublist, tab, and subtab IDs in lowercase in your SuiteScript code.
- Prefix all custom script IDs and deployment IDs with an underscore (_).
- Do not hard-code any passwords in scripts. The password and password2 fields are supported for scripting.
- If the same code is used across multiple forms, ensure that you test any changes in the code for each form that the code is associated with.
- Include proper error handling sequences in your script wherever data may be inconsistent, not available, or invalid for certain functions.
- For example, if your script requires a field value to validate another, ensure that the field value is available.
- Organize your code into reusable chunks. Many functions can be used in a variety of forms. Any reusable functions should be stored in a common library file and then called into specific event functions for the required forms as needed.
- Place all custom code and markup, including third party libraries, in your own namespace.
- Important: Custom code must not be used to access the NetSuite DOM. Developers must use SuiteScript APIs to access NetSuite UI components.
- Use the built in Library functions whenever possible for reading/writing Date/Currency fields and for querying XML documents.
- During script development, break your scripts into components, load them individually, and then test each one — inactivating all but the one you are testing when multiple components are tied to a single user event.
- When working with script type events, your function name should correspond with the event.
- For example, a pageInit event can be named PageInit or formAPageInit.
- Since name values can change, ensure that you use static ID values in your API calls where applicable.
- Although you can use any desired naming conventions for functions within your code, you should use custom namespaces or unique prefixes for all your function names.
- Thoroughly comment your code. This practice helps with debugging and development and assists NetSuite Customer Support in locating problems if necessary.
- You must use the runtime.getCurrentScript() function in the runtime module to reference script parameters.
- For example, use the following code to obtain the value of a script parameter named custscript_case_field:
define(['N/runtime'], function (runtime) {
function pageInit(context) {
let strField =runtime.getCurrentScript().getParameter('SCRIPT', 'custscript_case_field');
}
});
- Make sure that your script does not take a long time to execute. A script may execute for a long time if any or all of the following occur:
- The script performs a large number of record operations without going over the usage limit.
- The script causes a large number of user event scripts or workflows to execute.
- The script performs database searches or updates that collectively take a long time to finish
- Each server script type or application has a time limit for execution. This limit is not fixed and depends on the script type or application. If a single execution of a server script or application takes longer than the time limit for that script type or application, a SSS_TIME_LIMIT_EXCEEDED error is thrown. This error can also be thrown from a script that is executed by another script (for example, from a user event script that is executed by a scheduled script).
4. Cases for JavaScript Unit Test
- Type Check
- Investigate whether a change in data type can cause an error.
- For example: Number becomes string or Integer, Boolean becomes Number etc. In such scenarios, we need to identify whether our function/code causes any deviation from the expected behavior.
- Value Check
- Investigate whether a change in the expected value can cause an error.
- For example: Our function/code expected a non-empty value but received null, ‘’ , undefined, NaN etc. We need to identify whether this causes any deviation from the expected behavior.
- Error handling
- Investigate whether the script executed as expected when there is an error.
- Should we stop the script execution OR whether we need to handle the error for the script to continue execution?
- For example: An error in Loop, error in a function etc.
- Standardize error handling before invoking Data Type functions
- For example: When we need to check the length of the ‘Array’ from a response, make sure the data type is an ‘Array’ ( as data type ‘String’ also have length property)
- Unit Test
- Whether the function in the script can be unit tested using
- a) SuiteCloud Unit Testing
- b) SuiteCloud Unit Testing with Jest
- c) NetSuite Mocker – Unit test your SuiteScript 2.0 script
5.1 SuiteScript Unit Test
- Should the script be deployed to All Users/Subsidiaries/Roles/Departments/Contexts?
- Should the permission level be Current Role/Admin/Specific Roles?
- Should there be empty/unnecessary entry points on the script?
- Does the User Preference have an impact on the customization?
- For example: User Date Preference is different from company preference.
- The date format can be changed on the user preferences and the script should consider such variations into account.
- When setting a value to the reference field (List/Record) or Date field, always try to set it by setValue rather than setText.
- For example: An account name can be changed, or setting can be changed to show/hide parent hierarchy. But internal Id stays the same.
- There are instances where setText is more appropriate.
- For example: When the custom List is static such as Country, when the reference follows a common rule etc.
- Reference Path: Try to maintain a relative reference path for custom Module/script rather than an absolute path.
- Is there a possibility for the governance (usage) to exceed the limit.
- Is there a possibility for the execution time to exceed the limit.
- If there are multiple saved searches, can some of them be combined to optimize the time/speed of execution?
- Is there unnecessary logs on the script? Is proper log level utilized?
- For example: Script is deployed in one log level and the log level defined in the script is another.
- To log errors, using log.error rather than log.debug etc.
- Does the new customization have taken into account the impact it has on existing customization, or the impact existing customization have on it.
- For example: Lock record will restrict the load action of a record in other scripts. This will cause the failure of other scripts.
- What is the degree of the performance hit on the system due to the current customization and is there any way we can fix/mitigate the same.
- Does the record already have a multitude of customizations deployed?
- Is the usage of the NetSuite SuiteScript module/function parameters are properly taken into account as per the requirement. Most of them are using default values for the optional parameters.
- For example: ignoreFieldChange and forceSyncSourcing in record.setSublistValue
- Is the API credentials of Integration/SFTP are being properly resolved dynamically based on NetSuite environment. Will sandbox refresh (or Release Preview) cause the production script to run in Sandbox and invoke the API with production API credentials.
- If dealing with Date, is the Date Time is properly resolved based on the time zone a desired.
5.2 UserEvent Script and Workflow Action Script Unit Test
- Does a change in value between an oldRecord and a newRecord will cause an issue?
- Will a change in the expected value cause an error?
- For Example: We expects a value in Old Record/new Record but there might not be one in the case of record.submit /Inline Edit/ Xedit.
- Will deploying the script to all events cause an issue? Are the required events (create, edit, delete, copy etc ) properly handled?
- For example: Trying to access the record on the afterSubmit entry point on the delete event
- Does everything work as expected if they are created/modified form multiple context (CSV/SOAP/RESTlet/REST/Suitelet etc)
- When creating/updating the line items, does the item type take into consideration?
- For Example: End of Group line in group item cannot be edited.
- Is change in preferred form effect customization (such as disabling or hiding certain fields in specific forms)
5.3 Client Script Unit Test
- Should there be empty/unnecessary entry points on the script?
- Is there a proper return statement on the required entry points?
- If there are saved searches or other operations, should it be dependent or independent on the current role?
- Can the saved searches/record operations in the field change/sublist changed/validate field etc. entry point be avoided (as this will affect the performance).
- Does the log commands are properly implemented (Eg: log.debug on deployed client script and console.log on undeployed client script).
- Is there a chance for the events to get into infinite/cyclic loop?
- For example: fieldChange trigger set the value on another field which will trigger the event to update the first field.
- When creating/updating the line items, does the item type take into consideration?
- For Example: End of Group line in group item cannot be edited.
- Is verified on multiple browsers (if browser related function as well as styles are applied)
- Is change in preferred form effect customization (such as disabling or hiding certain fields in specific forms)
5.4 Suitelet/RESTlet Unit Test
- For Integration
a) Is there a need for request log for audit purpose and if so, is it already setup?
b) Is a proper mechanism for error Handling is defined?
c) Does a proper and consistent response (predefined structure) is returned?
d) Should the URL be publicly available?
6. SuiteBundle Unit Test
- Is the reference path relative?
- Can the static reference (if any) can be resolved dynamically?
- Is the impact of bundle installation intended?
- For example: Clearing existing fields, duplicating fields/list/record/custom segments, duplicating values etc.
- Did the bundle configured with proper object preferences (merge/preserve/overwrite) when creating and installing bundles.
7. Custom Record Unit Test
- Does the necessary permission is available for users other than the owner?
- Ensure that the field help should be defined for the custom fields and records.
- Is the ID (not internal ID) unique across all instances?
- Does the field type match with the field purpose?
- For example: If field purpose is to store amount, then the type can be currency.
- Does the ‘System notes’ is required auditing purpose and if so, is it enabled on the custom record.
- Are the custom record ID and Field ID of the custom fields unique (not system generated generic id)
8. Item Record and Item Sublist Unit Test
- Does the customization depend upon various Item Types and Item Preference?
- For example:
- Include Start/End Lines in Item group
- Kit Item
- Discount/Markup Items
- Non-Inventory Items
- Service Item
- Drop Ship/Special Order Item
- Work Order for Assembly Item
- Matrix Item
- Item Options
- Bins
- Lot/Serial Locations
- Location (Line and Body)
- Price Level
- Quantity Pricing
- Which all event types we need to consider: Item add/removal, field change such as quantity change, line level validations etc.
9. Saved Searches Unit Test
- Does the filter are properly added to restrict the volume of data?
- Does the amount field correctly represent the Transaction/Foreign currency rather than the base currency (unless defined otherwise)
- Does the quantity field properly represent the value in Transaction UOM quantity
- Are the duplicate lines scenarios properly handled?
- Is the mainline filter properly working?
- Are we correctly filtering unwanted lines such as Shipping lines, Tax lines, COGS lines etc. (unless defined otherwise)
- Does the saved search features such as Sort By, When Ordered By, Summary Type, Summary Filter, Formula, Function etc works properly (both in NetSuite User-Interface as well as in SuiteScript)?
- Is there any role-based restriction being applied to Saved Search?
- Is the saved search ID unique (not system generated generic ID)
10. Custom Fields, Names, Field ID etc Unit Test
- Is the Field IDs are unique across instances and those can be easily migrated from one instance to another without modifying the same
- Is the store value filed unchecked. Will this cause any issues.
- Is the value on the custom fields is derived from saved search or formula. If so, does this has any performance impact on the system.
- Are other fields being depend on the value in the custom field
11. System Preference, Accounting Preference, Company Preference, Enable Features etc. Unit Test
- Does enabling/disabling System Preference, Accounting Preference, Email Preference, Printing & Fax Preferences, Advance Order Management, Sales Preference, Support Preference, Company Preference, Enable Features, etc impact the customization and if it does, is it within the scope of work.
12. Folders/Files Unit Test
- Does the access restriction on this will affect the customization?
- Are there any confidential files that should be restricted among employees within the organization?
- Should any of the files be publicly accessible?