In a previous developer post, we introduced a new paradigm for structuring SuiteScript files in a project. As we address some of the details of the following structure, we come to the topic of enums.
Enums, short for “enumerated types” or “enumerations,” is basically a separate JavaScript library file where we store all the hardcoded values in our automation. This way, we can update the automation by simply changing a value in the enums folder. No one likes hunting through a pile of scripts trying to find every occurrence of a hard-coded string! Many languages including TypeScript, a specialized extension of JavaScript, have a unique enums data type. But native JavaScript does not have this feature. So when we use the term enums, we just mean a separate JS file that stores all our technical information as an object.
By the way, if you notice a change in our naming convention, that’s because we recently started using Google’s Style Guide for our naming convention.
Methods for Exporting
A basic JavaScript enums file for NetSuite will have this structure:
define([], function () {
/**
* @author First and Last Name
*/
var exports = {};
var SomeFunctionOrValue = "test";
exports.SomeFunctionOrValue = SomeFunctionOrValue;
return exports;
})
There are two options to export enums for use in other scripts. The first option is to place them directly in the “exports” object.
var exports = {
EnumHello: 'hello,',
EnumWorld: ' world!'
};
Another option is to define a separate variable and attach that to the exports object at the end of your script.
define([], function () {
/**
* @author Ben Rogol (SuiteRep)
*/
var exports = {};
var HelloObj = {
EnumHello: 'hello,',
EnumWorld: ' world!'
};
exports.HelloObj = HelloObj;
return exports;
})
We generally try to keep everything directly in the exports object unless we need to reference another value in the enums. In that case, we define a separate variable.
define([], function () {
/**
* @author Ben Rogol (SuiteRep)
*/
var exports = {};
var HelloObjectOne = {
hello: 'hello world!'
};
var HelloObjectTwo = {
HelloString: 'I will say, ' + HelloObjectOne.hello
};
exports.HelloObjectOne = HelloObjectOne;
exports.HelloObjectTwo = HelloObjectTwo;
return exports;
})
Of course, there is quite a bit of liberty here with structure. Feel free to explore and find out what works best for you.
Example
Here’s real example of an enums file for a supply-chain management Suitelet. We hope it can help give you a good idea of the potential.
define([], function () {
var Ids = {
Scripts: {
SUT_SCRIPT_ID: 'customscript_sr_supply_chain_sut',
SUT_DEPLOYMENT_ID: 'customdeploy_supplychain_management_sut',
},
Fields: {
Sublists: {
PoLine: {
INTERNAL_ID: 'custpage_po_sublist_internal_id',
TRAN_ID: 'custpage_po_sublist_tranid',
SUPPLIER: 'custpage_po_sublist_supplier',
SUPPLIER_PHONE: 'custpage_po_sublist_supplier_phone',
PURCHASE_DATE: 'custpage_po_sublist_purchase_date',
EXP_RECEIPT_DATE: 'custpage_po_sublist_expected_receipt_date',
TOTAL_QTY: 'custpage_po_sublist_qty',
RECEIVED_QTY: 'custpage_po_sublist_qty_received',
BILLED_QTY: 'custpage_po_sublist_qty_billed',
OUTSTANDING_SO_QTY: 'custpage_po_sublist_outstanding_so_items',
PARTIALLY_RECEIVED: 'custpage_po_sublist_partially_received',
FULLY_BILLED: 'custpage_po_sublist_fully_billed',
EMAILED: 'custpage_po_sublist_emailed',
EMAIL_ACKNOWLEDGED: 'custpage_po_sublist_email_acknowledged',
URGENT: 'custpage_po_sublist_urgent',
URGENT_NOTE: 'custpage_po_sublist_urgent_con_note',
OVER_7_DAYS: 'custpage_po_sublist_over_seven_days'
},
SoLine: {
ITEM_INTERNAL_ID: 'custpage_so_sublist_internal_item_id',
INTERNAL_ID: 'custpage_so_sublist_internal_id',
TRAN_ID: 'custpage_so_sublist_tranid',
SALE_DATE: 'custpage_so_sublist_sale_date',
CUSTOMER_NAME: 'custpage_so_sublist_name',
CUSTOMER_PHONE: 'custpage_so_sublist_customer_phone',
CUSTOMER_MOBILE: 'custpage_so_sublist_mobile_phone',
PO_NUM: 'custpage_so_sublist_so_ponum',
RELATED_PO: 'custpage_so_sublist_so_related_po',
PARTIALLY_FILLED: 'custpage_so_sublist_partially_filled',
FULLY_FILLED: 'custpage_so_sublist_fully_filled',
URGENT: 'custpage_so_sublist_urgent',
URGENT_NOTE: 'custpage_so_sublist_urgent_con_note',
OVER_7_DAYS: 'custpage_so_sublist_over_seven_days'
}
}
},
Sublists: {
PO_SUBLIST: 'custpage_po_sublist',
SO_SUBLIST: 'custpage_so_sublist',
}
}
var exports = {
Form: {
LABEL: 'Supply Chain Management',
SUBMIT_BUTTON: { label: "Submit Changes" },
REFRESH_BUTTON: { id: 'custpage_refresh_button', label: 'Refresh Filters', functionName: 'onRefreshButtonClick' },
FILTER_FIELD_GROUP: { id: 'filters', label: 'Filters' },
Fields: {
PoFilter: {
ID: 'custpage_filter_po', LABEL: 'Filter Purchase Orders', CONTAINERS: 'filters', SELECT_OPTIONS: [
{ field: '', text: '- No Filters -', isSelected: true },
{ field: 'custbody_po_over_7_days', text: 'Over 7 Days (Nothing Received/Billed)', value: 'T' },
{ field: 'custbody4', text: 'Unaknowledged POs', value: 'F' },
{ field: 'custbody_po_emailed', text: 'Un-emailed POs', value: 'F' },
{ field: 'custbody_po_urgent', text: 'Urgent', value: 'T' }
]
},
SoFilter: {
ID: 'custpage_filter_so', LABEL: 'Filter Sales Orders', CONTAINER: 'filters', SELECT_OPTIONS: [
{ field: '', text: '- No Filters -', isSelected: true },
{ field: 'custbody_so_partially_fulfilled', text: 'Partially-Fulfilled', value: 'T' },
{ field: 'custbody_so_urgent', text: 'Urgent', value: 'T' },
{ field: 'custbody_so_over_7_days', text: 'Over 7 Days Old', value: 'T' },
]
},
OPEN_PO_COUNT: { id: 'custpage_open_po_count', label: 'Open Purchase Order Count' },
OPEN_SO_COUNT: { id: 'custpage_open_so_count', label: 'Open Sales Order Count' }
}
},
Sublists: {
PoSublist: {
ID: Ids.Sublists.PO_SUBLIST, LABEL: 'Open Purchase Orders', FIELDS: [
{ id: Ids.Fields.Sublists.PoLine.INTERNAL_ID, mappedField: 'internalid', label: 'Internal ID', type: 'text', displayType: 'hidden', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.PoLine.TRAN_ID, mappedField: 'tranid', label: 'Purchase Order', type: 'text', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.PoLine.SUPPLIER, mappedField: 'companyname', join: 'vendor', label: 'Supplier', type: 'text', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.PoLine.SUPPLIER_PHONE, mappedField: 'phone', join: 'vendor', label: 'Supplier Phone', type: 'text', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.PoLine.PURCHASE_DATE, mappedField: 'trandate', label: 'Purchase Date', type: 'text', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.PoLine.EXP_RECEIPT_DATE, mappedField: 'expectedreceiptdate', label: 'Soonest Expected Receipt Date', type: 'date', summary: 'min', editable: false },
{ id: Ids.Fields.Sublists.PoLine.TOTAL_QTY, mappedField: 'quantity', label: 'Total Qty', type: 'integer', summary: 'sum', editable: false },
{ id: Ids.Fields.Sublists.PoLine.RECEIVED_QTY, mappedField: 'quantityshiprecv', label: 'Qty Received', type: 'integer', summary: 'sum', editable: false },
{ id: Ids.Fields.Sublists.PoLine.BILLED_QTY, mappedField: 'quantitybilled', label: 'Qty Billed', type: 'integer', summary: 'sum', editable: false },
{ id: Ids.Fields.Sublists.PoLine.OUTSTANDING_SO_QTY, mappedField: 'custcol_sr_qty_reserved', label: 'Qty Reserved on Sales Orders', type: 'integer', summary: 'sum', editable: false },
{ id: Ids.Fields.Sublists.PoLine.PARTIALLY_RECEIVED, mappedField: 'status', label: 'Partially Received', type: 'checkbox', displayType: 'disabled', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.PoLine.FULLY_BILLED, mappedField: '', label: 'Fully Billed', type: 'checkbox', displayType: 'disabled', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.PoLine.EMAILED, mappedField: 'custbody_po_emailed', label: 'Email Sent', type: 'checkbox', displayType: 'disabled', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.PoLine.EMAIL_ACKNOWLEDGED, mappedField: 'custbody4', label: 'Email Acknowledged', type: 'checkbox', displayType: 'disabled', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.PoLine.URGENT, mappedField: 'custbody_po_urgent', label: 'Urgent', type: 'checkbox', summary: 'group', editable: true },
{ id: Ids.Fields.Sublists.PoLine.URGENT_NOTE, mappedField: 'custbody_po_urgent_con_note', label: 'Urgent Con Note', type: 'text', displayType: 'entry', summary: 'group', editable: true },
{ id: Ids.Fields.Sublists.PoLine.OVER_7_DAYS, mappedField: 'custbody_po_over_7_days', label: 'Over 7 Days Old', type: 'checkbox', displayType: 'disabled', summary: 'group', editable: false }
]
},
SoSublist: {
ID: Ids.Sublists.SO_SUBLIST, LABEL: 'Open Sales Orders', FIELDS: [
{ id: Ids.Fields.Sublists.SoLine.INTERNAL_ID, mappedField: 'internalid', label: 'Internal ID', type: 'text', displayType: 'hidden', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.SoLine.TRAN_ID, mappedField: 'tranid', label: 'Sales Order', type: 'text', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.SoLine.SALE_DATE, mappedField: 'trandate', label: 'Sale Date', type: 'text', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.SoLine.CUSTOMER_NAME, mappedField: 'companyname', join: 'customer', label: 'Customer Name', type: 'text', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.SoLine.CUSTOMER_PHONE, mappedField: 'phone', join: 'customer', label: 'Customer Phone', type: 'text', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.SoLine.CUSTOMER_MOBILE, mappedField: 'custbody9', label: 'Mobile Phone', type: 'text', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.SoLine.PO_NUM, mappedField: 'otherrefnum', label: 'PO#', type: 'text', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.SoLine.RELATED_PO, mappedField: 'purchaseorder', label: 'Related Purchase Order', type: 'text', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.SoLine.PARTIALLY_FILLED, mappedField: 'status', label: 'Partially Fulfilled', type: 'checkbox', displayType: 'disabled', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.SoLine.FULLY_FILLED, mappedField: '', label: 'Fully Fulfilled', type: 'checkbox', displayType: 'disabled', summary: 'group', editable: false },
{ id: Ids.Fields.Sublists.SoLine.URGENT, mappedField: 'custbody_so_urgent', label: 'Urgent', type: 'checkbox', summary: 'group', editable: true },
{ id: Ids.Fields.Sublists.SoLine.URGENT_NOTE, mappedField: 'custbody_so_urgent_con_note', label: 'Urgent Con Note', type: 'text', displayType: 'entry', summary: 'group', editable: true },
{ id: Ids.Fields.Sublists.SoLine.OVER_7_DAYS, mappedField: 'custbody_so_over_7_days', label: 'Over 7 Days Old', type: 'checkbox', displayType: 'disabled', summary: 'group', editable: false }
]
}
},
searches: {
PoSearch: {
FILTERS: [
["type", "anyof", "PurchOrd"],
"AND",
["status", "anyof", "PurchOrd:D", "PurchOrd:E", "PurchOrd:B"],
"AND",
["mainline", "is", "F"],
"AND",
["closed", "is", "F"],
"AND",
["taxline", "is", "F"],
"AND",
["cogs", "is", "F"],
"AND",
["shipping", "is", "F"],
"AND",
["formulanumeric: CASE WHEN {quantity} > '0' THEN 1 ELSE 0 END", "equalto", "1"],
"AND",
["expectedreceiptdate", "before", "today"]
]
},
SoSearch: {
FILTERS: [
["type", "anyof", "SalesOrd"],
"AND",
["status", "anyof", "SalesOrd:D", "SalesOrd:B", "SalesOrd:E", "SalesOrd:F"],
"AND",
["mainline", "is", "F"],
"AND",
["closed", "is", "F"],
"AND",
["taxline", "is", "F"],
"AND",
["cogs", "is", "F"],
"AND",
["shipping", "is", "F"]
]
}
},
Urls: {
PO_URL: '/app/accounting/transactions/purchord.nl?id=',
SO_URL: '/app/accounting/transactions/salesord.nl?id='
},
EmailInfo: {
AUTHOR: '',
RECIPIENTS: ''
}
};
exports.Ids = Ids;
return exports;
});
There may be better ways to organize the above code, so feel free comment down below what your thoughts are! The great thing about keeping everything in an enums file is that we can easily add, remove, or rearrange Suitelet sublist columns and adjust a whole host of other things. It essentially acts as the “settings” for the SuiteScript project.
Conclusion
Learning how to use enums effectively in SuiteScript can revolutionize the way you customize NetSuite. Stay tuned for our next blog where we explain how to dramatically reduce the size of your scripts by looping over enums arrays or objects. And remember to subscribe to our email list!