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 Type | Prefix | Applies To |
|---|---|---|
| Entity | custentity_ | Customer, Vendor, Employee |
| Transaction Body | custbody_ | All transaction headers |
| Transaction Column | custcol_ | Transaction line items |
| Item | custitem_ | All item types |
| Event | custevent_ | Calendar events, tasks |
| Other Record | custrecord_ | 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
| Practice | Description |
|---|---|
| Consistent naming | Use descriptive names: custbody_approval_status |
| Appropriate type | Choose correct field type for data |
| Limit mandatory | Only require truly essential fields |
| Search levels | Enable search for filterable fields |
| Store vs source | Source from parent when possible |
| Access control | Restrict sensitive fields by role |
Next Steps
- Custom Lists - Create dropdown options
- Saved Searches - Search by custom fields
- Client Script - Add field validation