Skip to main content

Custom Fields

Custom Fields extend standard NetSuite records with additional data fields specific to your business needs.


Types of Custom Fields

┌─────────────────────────────────────────────────────────────────────────────┐
│ CUSTOM FIELD TYPES │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│ ENTITY FIELDS │
│ ───────────────────────────────────────────────────────────────────────── │
│ Added to: Customer, Vendor, Employee, Contact, Partner, etc. │
│ Prefix: custentity_ │
│ Example: custentity_credit_rating │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│ TRANSACTION BODY FIELDS │
│ ───────────────────────────────────────────────────────────────────────── │
│ Added to: Transaction header (Sales Order, Invoice, PO, etc.) │
│ Prefix: custbody_ │
│ Example: custbody_approval_status │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│ TRANSACTION LINE FIELDS │
│ ───────────────────────────────────────────────────────────────────────── │
│ Added to: Transaction line items │
│ Prefix: custcol_ │
│ Example: custcol_commission_rate │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│ ITEM FIELDS │
│ ───────────────────────────────────────────────────────────────────────── │
│ Added to: Inventory Item, Service Item, etc. │
│ Prefix: custitem_ │
│ Example: custitem_hazmat_class │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│ CRM FIELDS │
│ ───────────────────────────────────────────────────────────────────────── │
│ Added to: Cases, Events, Tasks, Campaigns, etc. │
│ Prefix: custevent_ (events/tasks), custrecord_ (cases) │
│ Example: custevent_follow_up_required │
└─────────────────────────────────────────────────────────────────────────────┘

Field Prefix Reference

Field TypePrefixApplies To
Entitycustentity_Customer, Vendor, Employee
Transaction Bodycustbody_All transaction headers
Transaction Columncustcol_Transaction line items
Itemcustitem_All item types
Eventcustevent_Calendar events, tasks
Other Recordcustrecord_Custom records

Entity Field XML

<?xml version="1.0" encoding="UTF-8"?>
<entitycustomfield scriptid="custentity_credit_rating">
<label>Credit Rating</label>
<description>Customer credit rating from external agency</description>

<!-- Field Type -->
<fieldtype>SELECT</fieldtype>
<selectrecordtype>[customlist_credit_ratings]</selectrecordtype>

<!-- Display Settings -->
<displaytype>NORMAL</displaytype>
<displayheight>1</displayheight>

<!-- Validation -->
<ismandatory>F</ismandatory>
<isparent>F</isparent>

<!-- Search/Filter -->
<searchlevel>2</searchlevel>
<showinlist>T</showinlist>
<globalfilter>F</globalfilter>

<!-- Applies To -->
<appliestocustomer>T</appliestocustomer>
<appliestolead>T</appliestolead>
<appliestoprospect>T</appliestoprospect>
<appliestovendor>F</appliestovendor>
<appliestoemployee>F</appliestoemployee>
<appliestocontact>F</appliestocontact>
<appliestopartner>F</appliestopartner>
<appliestoothername>F</appliestoothername>

<!-- Form Placement -->
<storevalue>T</storevalue>

<!-- Access -->
<accesslevel>2</accesslevel>

<customfieldfilters>
<!-- Optional: Filter dropdown options based on other fields -->
</customfieldfilters>

</entitycustomfield>

Transaction Body Field XML

<?xml version="1.0" encoding="UTF-8"?>
<transactionbodycustomfield scriptid="custbody_approval_status">
<label>Approval Status</label>
<description>Current approval workflow status</description>

<!-- Field Type -->
<fieldtype>SELECT</fieldtype>
<selectrecordtype>[customlist_approval_status]</selectrecordtype>

<!-- Display -->
<displaytype>NORMAL</displaytype>
<isformula>F</isformula>

<!-- Validation -->
<ismandatory>F</ismandatory>

<!-- Search -->
<searchlevel>2</searchlevel>
<showinlist>T</showinlist>

<!-- Transaction Types -->
<appliestosale>T</appliestosale>
<appliestopurchase>T</appliestopurchase>

<!-- Specific Transaction Types -->
<appliestosalesorder>T</appliestosalesorder>
<appliestoinvoice>T</appliestoinvoice>
<appliestopurchaseorder>T</appliestopurchaseorder>
<appliestovendorbill>T</appliestovendorbill>

<!-- Exclude Transaction Types -->
<appliestoestimate>F</appliestoestimate>
<appliestoquote>F</appliestoquote>

<!-- Storage -->
<storevalue>T</storevalue>

</transactionbodycustomfield>

Transaction Column (Line) Field XML

<?xml version="1.0" encoding="UTF-8"?>
<transactioncolumncustomfield scriptid="custcol_commission_rate">
<label>Commission Rate</label>
<description>Commission percentage for this line item</description>

<!-- Field Type -->
<fieldtype>PERCENT</fieldtype>

<!-- Display -->
<displaytype>NORMAL</displaytype>

<!-- Validation -->
<ismandatory>F</ismandatory>

<!-- Default -->
<defaultvalue>10</defaultvalue>

<!-- Applies To -->
<colsale>T</colsale>
<colpurchase>F</colpurchase>

<!-- Sublist Types -->
<colitem>T</colitem>
<colexpense>F</colexpense>

<!-- Specific Transactions -->
<colsalesorder>T</colsalesorder>
<colinvoice>T</colinvoice>
<colopportunity>T</colopportunity>

<!-- Storage -->
<storevalue>T</storevalue>

</transactioncolumncustomfield>

Item Field XML

<?xml version="1.0" encoding="UTF-8"?>
<itemcustomfield scriptid="custitem_hazmat_class">
<label>Hazmat Classification</label>
<description>Hazardous material classification for shipping</description>

<!-- Field Type -->
<fieldtype>SELECT</fieldtype>
<selectrecordtype>[customlist_hazmat_classes]</selectrecordtype>

<!-- Display -->
<displaytype>NORMAL</displaytype>

<!-- Validation -->
<ismandatory>F</ismandatory>

<!-- Search -->
<searchlevel>2</searchlevel>
<showinlist>T</showinlist>

<!-- Item Types -->
<appliestoinventory>T</appliestoinventory>
<appliestoassembly>T</appliestoassembly>
<appliestononinventory>T</appliestononinventory>
<appliestoservice>F</appliestoservice>
<appliestokit>T</appliestokit>

<!-- Storage -->
<storevalue>T</storevalue>

</itemcustomfield>

Field Display Types

┌─────────────────────────────────────────────────────────────────────────────┐
│ DISPLAY TYPE OPTIONS │
└─────────────────────────────────────────────────────────────────────────────┘

┌────────────────────┬───────────────────────────────────────────────────┐
│ NORMAL │ Standard editable field │
│ │ <displaytype>NORMAL</displaytype> │
├────────────────────┼───────────────────────────────────────────────────┤
│ HIDDEN │ Not visible on form (still stores data) │
│ │ <displaytype>HIDDEN</displaytype> │
├────────────────────┼───────────────────────────────────────────────────┤
│ INLINE │ Read-only, visible but not editable │
│ │ <displaytype>INLINE</displaytype> │
├────────────────────┼───────────────────────────────────────────────────┤
│ DISABLED │ Visible but greyed out │
│ │ <displaytype>DISABLED</displaytype> │
├────────────────────┼───────────────────────────────────────────────────┤
│ LOCKED │ Locked after initial value set │
│ │ (Only for custom record fields) │
└────────────────────┴───────────────────────────────────────────────────┘

Complete Example: Sales Order Custom Fields

Body Field: Requires Approval

<?xml version="1.0" encoding="UTF-8"?>
<transactionbodycustomfield scriptid="custbody_requires_approval">
<label>Requires Approval</label>
<description>Flag indicating if order needs manager approval</description>

<fieldtype>CHECKBOX</fieldtype>
<displaytype>NORMAL</displaytype>
<defaultvalue>F</defaultvalue>

<ismandatory>F</ismandatory>
<searchlevel>2</searchlevel>

<!-- Only for Sales Orders -->
<appliestosale>T</appliestosale>
<appliestosalesorder>T</appliestosalesorder>
<appliestoinvoice>F</appliestoinvoice>
<appliestoestimate>F</appliestoestimate>

<storevalue>T</storevalue>

</transactionbodycustomfield>

Body Field: Approved By

<?xml version="1.0" encoding="UTF-8"?>
<transactionbodycustomfield scriptid="custbody_approved_by">
<label>Approved By</label>
<description>Employee who approved the order</description>

<fieldtype>SELECT</fieldtype>
<selectrecordtype>-4</selectrecordtype> <!-- Employee -->

<displaytype>INLINE</displaytype>
<ismandatory>F</ismandatory>
<searchlevel>2</searchlevel>
<showinlist>T</showinlist>

<appliestosale>T</appliestosale>
<appliestosalesorder>T</appliestosalesorder>

<storevalue>T</storevalue>

</transactionbodycustomfield>

Line Field: Special Instructions

<?xml version="1.0" encoding="UTF-8"?>
<transactioncolumncustomfield scriptid="custcol_special_instructions">
<label>Special Instructions</label>
<description>Special handling or delivery instructions for this item</description>

<fieldtype>TEXTAREA</fieldtype>
<displaytype>NORMAL</displaytype>

<ismandatory>F</ismandatory>

<colsale>T</colsale>
<colitem>T</colitem>

<colsalesorder>T</colsalesorder>
<colinvoice>T</colinvoice>

<storevalue>T</storevalue>

</transactioncolumncustomfield>

Working with Custom Fields in Scripts

Reading Field Values

const record = require('N/record');
const search = require('N/search');

// Load record and read custom field
const salesOrder = record.load({
type: record.Type.SALES_ORDER,
id: 12345
});

// Read body field
const requiresApproval = salesOrder.getValue({
fieldId: 'custbody_requires_approval'
});

const approvedBy = salesOrder.getText({
fieldId: 'custbody_approved_by'
});

// Read line field
const lineCount = salesOrder.getLineCount({ sublistId: 'item' });

for (let i = 0; i < lineCount; i++) {
const instructions = salesOrder.getSublistValue({
sublistId: 'item',
fieldId: 'custcol_special_instructions',
line: i
});

log.debug(`Line ${i}`, instructions);
}

Setting Field Values

// Set body field
salesOrder.setValue({
fieldId: 'custbody_requires_approval',
value: true
});

salesOrder.setValue({
fieldId: 'custbody_approved_by',
value: runtime.getCurrentUser().id
});

// Set line field
salesOrder.setSublistValue({
sublistId: 'item',
fieldId: 'custcol_special_instructions',
line: 0,
value: 'Handle with care'
});

salesOrder.save();

Searching by Custom Fields

const findUnapprovedOrders = () => {
return search.create({
type: search.Type.SALES_ORDER,
filters: [
['mainline', 'is', 'T'],
'AND',
['custbody_requires_approval', 'is', 'T'],
'AND',
['custbody_approved_by', 'isempty', '']
],
columns: [
'tranid',
'entity',
'total',
'custbody_requires_approval'
]
});
};

Sourcing and Filtering

Source from Parent Record

<?xml version="1.0" encoding="UTF-8"?>
<transactionbodycustomfield scriptid="custbody_customer_credit_limit">
<label>Customer Credit Limit</label>

<fieldtype>CURRENCY</fieldtype>
<displaytype>INLINE</displaytype>

<!-- Source from customer record -->
<sourcefrom>entity</sourcefrom>
<sourcelist>custentity_credit_limit</sourcelist>

<appliestosale>T</appliestosale>
<storevalue>F</storevalue> <!-- Don't store, always source -->

</transactionbodycustomfield>

Filter Dropdown Based on Another Field

<?xml version="1.0" encoding="UTF-8"?>
<transactionbodycustomfield scriptid="custbody_regional_manager">
<label>Regional Manager</label>

<fieldtype>SELECT</fieldtype>
<selectrecordtype>-4</selectrecordtype> <!-- Employee -->

<!-- Filter employees by subsidiary -->
<customfieldfilters>
<customfieldfilter>
<fldfilter>subsidiary</fldfilter>
<fldfiltercomparetype>EQ</fldfiltercomparetype>
<fldfiltersel>subsidiary</fldfiltersel>
<fldfilternotnull>T</fldfilternotnull>
</customfieldfilter>
</customfieldfilters>

<appliestosale>T</appliestosale>
<storevalue>T</storevalue>

</transactionbodycustomfield>

Field Access Levels

┌─────────────────────────────────────────────────────────────────────────────┐
│ ACCESS LEVEL SETTINGS │
└─────────────────────────────────────────────────────────────────────────────┘

<accesslevel>0</accesslevel> → None (no access)
<accesslevel>1</accesslevel> → View (read-only)
<accesslevel>2</accesslevel> → Edit (read and write)

<!-- Role-specific access -->
<roleaccesses>
<roleaccess>
<role>ADMINISTRATOR</role>
<accesslevel>2</accesslevel> <!-- Full edit -->
</roleaccess>
<roleaccess>
<role>SALESREP</role>
<accesslevel>1</accesslevel> <!-- View only -->
</roleaccess>
</roleaccesses>

Formula Fields

Create calculated fields using formulas:

<?xml version="1.0" encoding="UTF-8"?>
<transactionbodycustomfield scriptid="custbody_days_outstanding">
<label>Days Outstanding</label>

<fieldtype>INTEGER</fieldtype>
<displaytype>INLINE</displaytype>
<isformula>T</isformula>

<!-- Formula: Days since transaction date -->
<defaultvalue>{today}-{trandate}</defaultvalue>

<appliestosale>T</appliestosale>
<appliestoinvoice>T</appliestoinvoice>
<storevalue>F</storevalue>

</transactionbodycustomfield>

Import Existing Fields

# Import entity custom fields
suitecloud object:import --type entitycustomfield --destinationfolder Objects

# Import transaction body fields
suitecloud object:import --type transactionbodycustomfield --destinationfolder Objects

# Import transaction column fields
suitecloud object:import --type transactioncolumncustomfield --destinationfolder Objects

# Import item fields
suitecloud object:import --type itemcustomfield --destinationfolder Objects

Best Practices

PracticeDescription
Consistent namingUse descriptive names: custbody_approval_status
Appropriate typeChoose correct field type for data
Limit mandatoryOnly require truly essential fields
Search levelsEnable search for filterable fields
Store vs sourceSource from parent when possible
Access controlRestrict sensitive fields by role

Next Steps