How can I track which fields have been edited in Netsuite when syncing NetSuite sales orders to Salesforce?

I’m working on a project where I need to sync sales orders between NetSuite and Salesforce. Specifically, I’m trying to track which fields have been updated in NetSuite and ensure these changes are accurately reflected in Salesforce.

I have a User Event script in NetSuite that triggers when a sales order is edited. This script updates the corresponding Salesforce order. However, I’m struggling with tracking which specific fields have changed during the update. Here’s a simplified version of my code:

function afterSubmit(context) {
var accessToken = ‘abcd’;
var rec = context.newRecord;

try {
if (context.type === context.UserEventType.EDIT) {
var salesforceId = rec.getValue({ fieldId: ‘custbody_salesforce_order_id’ });
log.debug(“SO salesforceId”, salesforceId);
updateSalesforceOrder(accessToken, updateData, salesforceId)
if (salesforceId) {
updateSalesforceOrderItems(rec, accessToken, salesforceId);
} else {
log.error(‘Salesforce Order ID not found’, ‘Cannot update order in Salesforce without Salesforce Order ID.’);
}
}
} catch (e) {
log.error(‘Error processing order’, e.message);
}
}

function updateSalesforceOrder(accessToken, updateData, salesforceId) {
log.debug(“updateData”, updateData);
log.debug(“salesforceId”, salesforceId);
var response = https.post({
url: ‘https://xyz-ed.develop.my.salesforce.com/services/data/v61.0/sobjects/Order/’ + salesforceId + ‘?_HttpMethod=PATCH’,
headers: {
Authorization: ‘Bearer ‘ + accessToken,
‘Content-Type’: ‘application/json’
},
body: JSON.stringify(updateData)
});

var responseBody = JSON.parse(response.body);
log.debug(“response—>”, response);
if (response.code === 204) {
return {
success: true
};
} else {
log.error(‘Error updating order in Salesforce’, responseBody);
return {
success: false,
error: responseBody
};
}
}

function updateSalesforceOrderItems(rec, accessToken, salesforceOrderId) {
log.debug(“updateSalesforceOrderItems function called”, {
recId: rec.id,
salesforceOrderId: salesforceOrderId
});

// Fetch existing order items from Salesforce
var existingItems = getSalesforceOrderItems(accessToken, salesforceOrderId);
log.debug(“existingItems”, existingItems);

if (!existingItems.success) {
log.error(‘Error fetching Salesforce order items’, existingItems.error);
return;
}

var existingItemRecords = existingItems.records;
log.debug(“existingItemRecords”, existingItemRecords);

// Prepare to process NetSuite order items
var itemCount = rec.getLineCount({ sublistId: ‘item’ });
log.debug(“itemCount”, itemCount);

for (var i = 0; i < itemCount; i++) {
var itemId = rec.getSublistValue({ sublistId: ‘item’, fieldId: ‘item’, line: i });
var quantity = rec.getSublistValue({ sublistId: ‘item’, fieldId: ‘quantity’, line: i });
var rate = rec.getSublistValue({ sublistId: ‘item’, fieldId: ‘rate’, line: i });

log.debug(“Processing Item”, {
itemId: itemId,
quantity: quantity,
rate: rate
});

var salesforceProductId = getSalesforceProductId(itemId);
log.debug(“salesforceProductId–>”, salesforceProductId);

var priceBookEntryId = getpriceBookProductId(accessToken, salesforceProductId);
log.debug(“priceBookEntryId”, priceBookEntryId);
var pbid = priceBookEntryId.records[0].Id;
log.debug(“pbid”, pbid);

if (salesforceProductId) {
var orderItemData = {
Quantity: quantity,
UnitPrice: rate
};
log.debug(“orderItemData”, orderItemData);

var itemFound = false;
for (var j = 0; j < existingItemRecords.length; j++) {
if (existingItemRecords[j].Product2Id === salesforceProductId) {
// Update existing item
var existingItemId = existingItemRecords[j].Id;
log.debug(“Updating item”, existingItemId);

var response = https.post({
url: ‘https://xyz-ed.develop.my.salesforce.com/services/data/v61.0/sobjects/OrderItem/’ + existingItemId + ‘?_HttpMethod=PATCH’,
headers: {
‘Authorization’: ‘Bearer ‘ + accessToken,
‘Content-Type’: ‘application/json’
},
body: JSON.stringify(orderItemData)
});

log.debug(“Response code”, response.code);
log.debug(“Response body”, response.body);

if (response.code === 204) {
log.debug(‘Salesforce Order Item Updated’, existingItemId);
} else {
var responseBody = JSON.parse(response.body);
log.error(‘Error updating order item in Salesforce’, responseBody);
}

itemFound = true;
break;
}
}

if (!itemFound) {
// Create new item
var newOrderItemData = {
OrderId: salesforceOrderId,
Product2Id: salesforceProductId,
PricebookEntryId: pbid,
Quantity: quantity,
UnitPrice: rate
};
log.debug(“Creating new item”, salesforceProductId);

var response = https.post({
url: ‘https://xyz-ed.develop.my.salesforce.com/services/data/v61.0/sobjects/OrderItem/’,
headers: {
‘Authorization’: ‘Bearer ‘ + accessToken,
‘Content-Type’: ‘application/json’
},
body: JSON.stringify(newOrderItemData)
});

log.debug(“Response code”, response.code);
log.debug(“Response body”, response.body);

if (response.code === 201) {
var responseBody = JSON.parse(response.body);
log.debug(‘Salesforce Order Item Created’, responseBody.id);
} else {
var responseBody = JSON.parse(response.body);
log.error(‘Error creating order item in Salesforce’, responseBody);
}
}
} else {
log.error(‘Salesforce Product ID not found’, ‘Cannot process order item without Salesforce Product ID.’);
}
}

}

function getSalesforceOrderItems(accessToken, salesforceOrderId) {
var response = https.get({
url: ‘https://xyzxyz-ed.develop.my.salesforce.com/services/data/v61.0/query/?q=SELECT+Id,+Product2Id+FROM+OrderItem+WHERE+OrderId=\” + salesforceOrderId + ‘\”,
headers: {
‘Authorization’: ‘Bearer ‘ + accessToken
}
});

}

 

 

Beginner Asked on July 24, 2024 in SuiteScript.
Add Comment
3 Answer(s)

Hi,

Have you tried context.oldRecord which contains the values of the fields on the old record?

Thanks,

Chris

Advanced Answered on August 2, 2024.
Add Comment

Tracking which fields were edited on a sales order in NetSuite when syncing to Salesforce can actually be handled with its built‑in audit tools, no need for hacks. NetSuite logs field changes in System Notes and the audit trail so you see who changed what, when, and even the old and new values. You can pull those via a saved search (filter on record type and field changes) or view the transaction’s Audit Trail under Transactions → Management.

For more automated syncing, some use SuiteScript or middleware. We also tried data sync platforms like Skyvia that can map changes and push only deltas out of the box, which helped cut down custom code.

Rookie Answered on July 22, 2025.
Add Comment

@

Yes. The best way is to use NetSuite System Notes as the audit trail.

  • Open the Sales Order → System Information → System Notes. NetSuite records the field changed, old value, new value, timestamp, user, and change context.
  • For Salesforce synchronization, create a System Notes saved search filtered by the Sales Order and the relevant fields. You can also filter by context to identify changes made through web services, SuiteScript, CSV, etc.
  • If you need to automate the comparison, System Notes are searchable through SuiteScript, allowing you to retrieve the changed field and old/new values.

Recommended approach: Before syncing to Salesforce, query the Sales Order’s System Notes for changes since the last sync, identify the modified fields, and send only those fields to Salesforce. This gives you a reliable NetSuite → Salesforce change-tracking mechanism without having to compare the entire Sales Order each time.

Rookie Answered on August 19, 2026.
Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.
  • This site made possible by our sponsors:   Tipalti   Celigo   SuiteMigration   Become a Sponsor