Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Author: <>
Description: Creates a sales order using an invoice beforeSubmit call
If you are debugging:
2. User Event
3. Name: Create SalesOrder for Invoice
4. ID: _create_so_for_invoice
5. Befire Submit: beforeSubmit
6. Deployments: Invoice. Event Type: Create. Ensure accessible to all roles and executes as admin.
"An invoice can be created in the UI from a sales order by clicking the Bill button or by script through the usage of nlapiTransformRecord. In both cases the Created From field maintains the link to the sales order from which the invoice was created, only if at least one of the initially present line items is still present when the record is submitted.
If after creating the invoice from the sales order and before submitting the invoice all line items are removed and new ones are added, then the Created From field is not populated with the reference to the original sales order.
For example, the following snippet creates an invoice linked through the Created From field to the sales order:"
function log(msg) {
nlapiLogExecution('DEBUG', msg);
function isWebServicesContext() {
var context = nlapiGetContext();
var executionContext = context.getExecutionContext();
return executionContext == 'webservices';
var LINE_ITEM_GROUP_NAME = 'item';
function beforeSubmit(type) {
if(isWebServicesContext() && type == 'create') {
function processBeforeSubmit() {
var customerId = nlapiGetFieldValue('entity');
var salesOrderId = copyInvoiceToSalesOrder(customerId);
var salesOrder = nlapiLoadRecord('salesorder', salesOrderId);
log("created sales order: " + salesOrderId)
// NOTE we can use the invoice line item count since it should match the sales order
var lineItemCount = parseInt(salesOrder.getLineItemCount('item'));
for(var i = 1; i <= lineItemCount; i++) {
nlapiSelectLineItem(LINE_ITEM_GROUP_NAME, i);
nlapiSetCurrentLineItemValue(LINE_ITEM_GROUP_NAME, 'itemisfulfilled', 'T', false)
nlapiSetCurrentLineItemValue(LINE_ITEM_GROUP_NAME, 'orderdoc', salesOrderId, false)
// NOTE `orderline` is not always a sequentially increasing value; this needs to be pulled directly from the line on the SO
nlapiSetCurrentLineItemValue(LINE_ITEM_GROUP_NAME, 'orderline', salesOrder.getLineItemValue(LINE_ITEM_GROUP_NAME, 'line', i), false)
function copyInvoiceToSalesOrder(customerId) {
var salesOrder = nlapiCreateRecord('salesorder', {
entity: customerId
salesOrder.setFieldValue('memo', "SalesOrder generated from invoice: " + nlapiGetFieldValue('externalid'))
var invoiceLineItemCount = parseInt(nlapiGetLineItemCount(LINE_ITEM_GROUP_NAME));
// NOTE depending on the required fields on your account you may need to adjust the required fields here
var fieldsToCopy = ["item", "quantity", "amount", "taxcode", "shipmethod"];
log("creating sales order for invoice with line item count: " + invoiceLineItemCount)
for(var i = 1; i <= invoiceLineItemCount; i++) {
nlapiSelectLineItem(LINE_ITEM_GROUP_NAME, i);
log("adding line item to sales order: " + nlapiGetCurrentLineItemValue(LINE_ITEM_GROUP_NAME, 'item'))
for(var fieldIndex in fieldsToCopy) {
salesOrder.setCurrentLineItemValue(LINE_ITEM_GROUP_NAME, fieldsToCopy[fieldIndex], nlapiGetCurrentLineItemValue(LINE_ITEM_GROUP_NAME, fieldsToCopy[fieldIndex]))
var salesOrderId = nlapiSubmitRecord(salesOrder);
return salesOrderId;
if(nlapiGetContext().getExecutionContext() == 'debugger') {
var exampleInvoiceID = 14707;
var customerId = nlapiLookupField('invoice', exampleInvoiceID, 'entity');
var salesOrderId = copyInvoiceToSalesOrder(customerId);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment