Home SuiteScript API: N/record - Part 1
Post
Cancel

SuiteScript API: N/record - Part 1

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.

This post is licensed under CC BY 4.0 by the author.

SuiteScript API: N/record - Part 2

SuiteScript API: N/search