Introduction
This post will discuss how to use the N/record
module. The N/record
module is a common module used to create, modify, or delete records.
The NetSuite documentation is fairly good when it comes to the SuiteScript API. This post, and other posts in this series will discuss give a very accessible introduction to the APIs and discuss some of the main features the API offers.
I will also be using these modules in a scheduled script as the footprint of a scheduled script is very small.
For more information regarding the different script types, see the Anatomy of SuiteScript series
Importing the Module
Here is the boilerplate for a scheduled script that imports the N/record
module:
1
2
3
4
5
6
7
8
9
10
11
12
/**
*@NApiVersion 2.1
*@NScriptType ScheduledScript
*/
define(['N/record'], function(record) {
function execute(context) {
//code goes here
}
return {execute: execute}
})
As we can see we list the N/record
module in the first argument of the define
function. Our callback function will have the record
module as an argument. Note that we can call the module something other than record
if we want to:
1
2
3
4
5
6
7
8
9
10
11
/**
*@NApiVersion 2.1
*@NScriptType ScheduledScript
*/
define(['N/record'], function(myRecord) {
function execute(context) {
//code goes here
}
return {execute: execute}
})
Loading a Record
To load a record we use the record.load
function.
This function takes an object that contains the following properties:
type
- The type of record we want to load (required)id
- The internal id of the record we want to load (required)isDynamic
- A boolean that determines whether the record is dynamic or not (optional, defaults to false)
The type
argument represents the type of record we want to load. Common examples include:
customer
vendor
salesorder
workorder
Instead of passing a string to the type
argument, we can also pass a constant from the record.Type
object.
record.Type.CUSTOMER
record.Type.VENDOR
record.Type.SALES_ORDER
record.Type.WORK_ORDER
For a full list, see the NetSuite documentation.
When loading a custom record, we can pass the internal id of the custom record type to the type
argument.
custrecord_my_custom_record
custrecord_my_other_custom_record
These ids won’t be found in the record.Type
enum.
Dynamic vs Standard Records
When loading a record, we can specify whether we want to load a dynamic or standard record. When loading a record in dynamic mode, the record will very closely resemble the UI. So field checks will be performed as we set the fields of the record. So if I set an inventory detail that doesn’t match the line, if I load it in dynamic mode, I will get an error as soon as I set the field. If I load the record in standard mode, I will only get an error when I save the record.
Another difference is the ability to set fields with their text values if the field is a select field. So for customer records, we have a field called subsidiary
which is a (multi)select field. If our subsidaries look as follows:
- 1 - US
- 2 - Canada
If I am loading the record in dynamic mode, I can set the subsidiary field to US
or Canada
. If I am loading the record in standard mode, I can only set the subsidiary field to 1
or 2
.
There are other differences between dynamic and standard records that will be discussed below. Getting and setting sublists is one of the main differences is discussed in (this post)[/posts/2023-04-25-suitescript-api-record-part-2/].
In this post unless specified otherwise, we will be able to use the functions both in dynamic and standard mode.
Example
Here is an example of loading a customer record in dynamic mode:
1
2
3
4
5
6
7
const execute(context) {
const customer = record.load({
type: record.Type.CUSTOMER,
id: 123,
isDynamic: true
})
}
Setting Fields
To set a field, we use the setValue
function. This function takes an object that has two arguments:
fieldId
- The internal id of the field we want to set (required)value
- The value we want to set the field to (required)
1
2
3
4
5
6
7
8
const execute(context) {
const customerrec = record.load(...)
customerrec.setValue({
fieldId: 'subsidiary',
value: 1 /* Internal id of the US subsidiary */
})
}
Note that we aren’t using record.setValue
but rather customerrec.setValue
i.e. we are calling the setValue
function on the record object we loaded.
I am able to set the field to the text value of the field using the setText
function.
1
2
3
4
5
6
7
8
const execute(context) {
const customerrec = record.load(...)
customerrec.setText({
fieldId: 'subsidiary',
text: 'US' /* Text value of the US subsidiary */
})
}
If the field is a text value, even if the record is in standard mode, I can set the field to the text value.
1
2
3
4
5
6
7
8
9
10
11
12
const execute(context) {
const customerrec = record.load({
type: record.Type.CUSTOMER,
id: 123,
isDynamic: false
})
customerrec.setValue({
fieldId: 'email',
value: 'test@example.com'
})
}
Getting Fields
To get a field, we use the getValue
function. This function takes an object that has one argument:
fieldId
- The internal id of the field we want to get (required)
1
2
3
4
5
6
7
const execute(context) {
const customerrec = record.load(...)
const subsidiary = customerrec.getValue({
fieldId: 'subsidiary'
})
}
If the field type is a select field, the getValue
function will return the internal id of the field. Generally, NetSuite will return the value of the field in the type that matches the field type. So if I load the transaction date of a sales order, I will get a Date
object. If I load the quantity of a work order, I will get a Number
object. If we have set the record using the setText
function, a m then able to get the text representation using getText
.
1
2
3
4
5
6
7
const execute(context) {
const customerrec = record.load(...)
const subsidiary = customerrec.getText({
fieldId: 'subsidiary'
})
}
Saving Records
To save a record, we use the save
function.
1
2
3
4
5
const execute(context) {
const customerrec = record.load(...)
customerrec.setValue(...)
customerrec.save()
}
This will return the internal id of the saved record This function takes an optional object that has the following arguments:
enableSourcing
- A boolean that determines whether to enable sourcing (optional, defaults to true)ignoreMandatoryFields
- A boolean that determines whether to ignore mandatory fields (optional, defaults to false)
record.submitFields
If we want to set fields without loading the record, we can use the record.submitFields
function.
This function takes an object that has the following arguments:
type
- The type of record we want to load (required)id
- The internal id of the record we want to load (required)values
- An object that contains the fields we want to set (required)
The type and id arguments are the same as the record.load
function. The values argument is an object that contains the fields we want to set.
1
2
3
4
{
subsidiary: 1,
email: 'test@example.com'
}
Here is an example of using the record.submitFields
function:
1
2
3
4
5
6
7
8
9
10
const execute(context) {
record.submitFields({
type: record.Type.CUSTOMER,
id: 123,
values: {
subsidiary: 1,
email: 'test@example.com'
}
})
}
Creating Records
Creating records is very similar to loading records.
To create a record, we use the record.create
function.
This function takes an object that has the following arguments:
type
- The type of record we want to create (required)defaultValues
- An object that contains the default values of the record (optional)
The default values argument is used when we need the value to exist on the record before loading it. For example some fields are unique to a certain form. So if we load the record, even if we set the form after with setValue
we still won’t have access to the fields.
In this case we can set the form with the defaultValues
object and then the fields will be available:
1
2
3
4
5
6
7
8
const execute(context) {
const customerrec = record.create({
type: record.Type.CUSTOMER,
defaultValues: {
customform: 123
}
})
}
Now the fields will be available.
record.transform
Some records can not exist in isolation. For example item fullfillment records can only exist if there is an order that we are fulfilling.
In this case, we won’t be able to use the record.create
function. We use the record.transform
function instead. This function takes an object that has the following arguments:
fromType
- The type of record we want to transform from (required)fromId
- The internal id of the record we want to transform from (required)toType
- The type of record we want to transform to (required)defaultValues
- An object that contains the default values of the record (optional)
Here is an example of using the record.transform
function:
1
2
3
4
5
6
7
const execute(context) {
const itemfulfillment = record.transform({
fromType: record.Type.SALES_ORDER,
fromId: 123,
toType: record.Type.ITEM_FULFILLMENT
})
}
Now we have a record object that we can set values on and save.
Conclusion
In this post we learned the basics of working with records in SuiteScript 2.0. Two very important concepts were skipped in this post Sublists and Subrecords. This will be covered in part 2.