Module 5: SuiteScript Modules

Week 3 • NetSuite SuiteScript 2.0 Training • ~75 minutes

🎯 Learning Objectives

By the end of this module, you will be able to:

1. What Are SuiteScript Modules?

Modules are libraries of functionality that you add to your scripts. Think of them as toolboxes - you only bring the tools you need for the job.

💡 Why Modules Matter

In SuiteScript 1.0, all functions were in the global scope, using memory for capabilities you might never use. SuiteScript 2.x modules let you load only what you need, making scripts more efficient and maintainable.

Module Naming Convention

NetSuite modules start with N/ to indicate they're built-in NetSuite APIs:

2. Loading Modules with define()

Basic Syntax

/**
 * @NApiVersion 2.1
 * @NScriptType UserEventScript
 */
define(['N/record', 'N/email', 'N/runtime'], function(record, email, runtime) {
    
    // Now you can use record.load(), email.send(), runtime.getCurrentUser()
    
    function afterSubmit(context) {
        // Your code here
    }
    
    return { afterSubmit: afterSubmit };
});
⚠️ Order Matters!

The order of modules in the array must match the order of parameters in the callback function. If you list ['N/record', 'N/email'], your function must be function(record, email) - not function(email, record).

Variable Naming

You can name the variables anything, but convention is to use the module name:

// Standard (recommended)
define(['N/record'], function(record) { ... });

// Also valid, but non-standard
define(['N/record'], function(rec) { ... });
define(['N/record'], function(recordModule) { ... });

3. The N/record Module

The N/record module is essential for working with NetSuite records programmatically.

Loading a Record

var customerRecord = record.load({
    type: record.Type.CUSTOMER,  // or 'customer'
    id: 123,
    isDynamic: false  // Static mode (default)
});

// Now read/modify the record
var name = customerRecord.getValue('companyname');
customerRecord.setValue('phone', '555-1234');
customerRecord.save();

Creating a Record

var phoneCall = record.create({
    type: record.Type.PHONE_CALL,
    isDynamic: true
});

phoneCall.setValue('title', 'Follow-up call');
phoneCall.setValue('phone', '555-1234');

var newId = phoneCall.save();
log.debug('Created Phone Call', 'ID: ' + newId);

Transforming Records

Transform creates a new record from an existing one, copying relevant values:

// Create Invoice from Sales Order
var invoice = record.transform({
    fromType: record.Type.SALES_ORDER,
    fromId: 456,
    toType: record.Type.INVOICE
});

var invoiceId = invoice.save();

Dynamic vs Standard Mode

FeatureStandard ModeDynamic Mode
Field sourcingManualAutomatic
Sublist editingBy line numberSelect → Edit → Commit
PerformanceFasterSlower
Use caseBulk operationsUI-like behavior
✅ Best Practice

Use Standard mode (isDynamic: false) for server-side scripts processing multiple records. Use Dynamic mode (isDynamic: true) when you need automatic field sourcing or are simulating UI behavior.

4. Other Common Modules

N/email - Send Emails

define(['N/email'], function(email) {
    
    email.send({
        author: 123,           // Employee internal ID
        recipients: 'user@example.com',
        subject: 'Order Confirmation',
        body: 'Thank you for your order!'
    });
    
});

N/runtime - Script & User Context

define(['N/runtime'], function(runtime) {
    
    // Get current user info
    var user = runtime.getCurrentUser();
    log.debug('User', user.name + ' (ID: ' + user.id + ')');
    
    // Get current script info
    var script = runtime.getCurrentScript();
    log.debug('Remaining Governance', script.getRemainingUsage());
    
    // Get script parameters
    var paramValue = script.getParameter('custscript_my_param');
    
});

N/url - Generate URLs

define(['N/url'], function(url) {
    
    // URL to a record
    var recordUrl = url.resolveRecord({
        recordType: 'customer',
        recordId: 123,
        isEditMode: false
    });
    
    // URL to a Suitelet
    var suiteletUrl = url.resolveScript({
        scriptId: 'customscript_my_suitelet',
        deploymentId: 'customdeploy_my_suitelet',
        params: { custparam_id: 456 }
    });
    
});

N/format - Date/Number Formatting

define(['N/format'], function(format) {
    
    // Parse a date string to Date object
    var dateObj = format.parse({
        value: '12/25/2024',
        type: format.Type.DATE
    });
    
    // Format a Date object to string
    var dateStr = format.format({
        value: new Date(),
        type: format.Type.DATETIME
    });
    
});

Common Modules Reference

ModulePurposeKey Functions
N/recordRecord CRUDload, create, delete, transform
N/searchSearchingcreate, load, lookupFields
N/emailEmailsend, sendBulk
N/runtimeContext infogetCurrentUser, getCurrentScript
N/urlURL buildingresolveRecord, resolveScript
N/formatFormattingparse, format
N/fileFile Cabinetcreate, load, delete
N/httpHTTP callsget, post, request
N/redirectPage redirecttoRecord, toSuitelet

5. Promises in SuiteScript

Some operations have .promise() versions for asynchronous execution:

// Synchronous (blocks until complete)
var rec = record.load({
    type: 'customer',
    id: 123
});
log.debug('Loaded', rec.getValue('companyname'));

// Asynchronous (returns promise)
record.load.promise({
    type: 'customer',
    id: 123
}).then(function(rec) {
    log.debug('Loaded', rec.getValue('companyname'));
}).catch(function(error) {
    log.error('Load Failed', error.message);
});
🔮 When to Use Promises

Promises are useful in client scripts where you don't want to freeze the UI while waiting for server responses. In server-side scripts, synchronous calls are usually simpler and sufficient.

🏋️ Practice Exercises

Exercise 1: Load and Modify

Create a User Event script that loads a related Customer record when a Sales Order is saved, and logs the customer's email address.

Exercise 2: Create Related Record

When a new Employee is created, automatically create a Phone Call record assigned to them with subject "HR Onboarding Call".

Exercise 3: Send Notification

Create an afterSubmit script that sends an email to the sales rep when a Sales Order total exceeds $10,000.

🎯 Key Takeaways

  • Modules are loaded via define(['N/module'], function(module) {...})
  • Array order must match function parameter order
  • N/record provides load(), create(), transform(), delete()
  • Use standard mode for performance, dynamic mode for UI-like behavior
  • Always pass parameters as objects: { type: 'customer', id: 123 }
  • Check Help Center for full module documentation