SuiteScript Sales Order to Cash Sale Transformation

in , , , August 27th, 2024

Let's say you need to create a cash sale from a sales order on the creation of a sales order record, and you want to close out the sales order as well. This will be done in a UserEvent script.

Closed Sales Order #95

Cash Sale from SO #95

Set Order Status to Pending Fulfillment in SuiteScript

The first thing to know when doing this transformation within SuiteScript is that the order status must be set to ‘Pending Fulfillment’ for the transform method to work. You can easily do this within the beforeSubmit entry point, as shown below.

function beforeSubmit(context) {
        try {
            if (context.type !== context.UserEventType.CREATE) {
                return;
            }
            let salesOrder = context.newRecord;


            //Make sure the sales order is coming from Big Commerece by checking to see if these fields exist
            const storefront = salesOrder.getValue({ fieldId: 'custbody_fa_channel', });
            const storefrontOrderNum = salesOrder.getValue({ fieldId: 'custbody_fa_channel_order', });
            const orderTotal = salesOrder.getValue({ fieldId: 'custbody_fa_order_total', });
            const shipTax = salesOrder.getValue({ fieldId: 'custbody_fa_shipping_tax', });


            const pendingFulfillment = 'B';
            if (storefront && storefrontOrderNum && orderTotal && shipTax) {
                salesOrder.setValue({
                    fieldId: 'orderstatus',
                    value: pendingFulfillment
                });
            }
        } catch (e) {
            log.error({
                title: e.name,
                details: e.message
            });
        }


    }

If you need to check if other fields are filled before setting this value, you can do what is shown here when checking for the BigCommerce fields to see if the Sales Order came from BigCommerce.

Using record.transform, Loading and Closing the Sales Orders

Following this, you will need to use the record.transform() method from the record module within the afterSubmit entry point. Check any necessary fields before using the method in case you want to limit what Sales Orders are transformed, as mentioned previously with the ones from BigCommerce. Make any changes to the new Cash Sale, and don’t forget to save it. To close the Sales Order, you will need to loop through each line item, close the item individually, and then save it once finished. You will also need to load the Sales Order after the Cash Sale is created, otherwise the record.save() method will not work.

Select a Payment Method When Creating the Sales Order

One more requirement for the transformation to work is that a payment method be selected when creating the Sales Order; otherwise, the transformation will fail.

function afterSubmit(context) {
        try {
            if (context.type !== context.UserEventType.CREATE) {
                return;
            }


            const newSalesOrder = context.newRecord;


            //Make sure the sales order is coming from Big Commerece by checking these fields
            const storefront = newSalesOrder.getValue({ fieldId: 'custbody_fa_channel', });
            const storefrontOrderNum = newSalesOrder.getValue({ fieldId: 'custbody_fa_channel_order', });
            const orderTotal = newSalesOrder.getValue({ fieldId: 'custbody_fa_order_total', });
            const shipTax = newSalesOrder.getValue({ fieldId: 'custbody_fa_shipping_tax', });


            if (storefront && storefrontOrderNum && orderTotal && shipTax) {
                let cashSale = record.transform({
                    fromType: record.Type.SALES_ORDER,
                    fromId: Number(newSalesOrder.getValue({ fieldId: 'id' })),
                    toType: record.Type.CASH_SALE,
                });


                cashSale.setValue({
                    fieldId: 'custbody_bc_created_from',
                    value: cashSale.getValue({ fieldId: 'createdfrom' })
                });


                const cashSaleId = cashSale.save();


                //The sales order is loaded here again to make sure the .save() method later on works
                salesOrder = record.load({
                    type: record.Type.SALES_ORDER,
                    id: newSalesOrder.getValue({ fieldId: 'id' })
                });
                for (let i = 0; i < salesOrder.getLineCount({ sublistId: 'item' }); i++) {
                    //Close out the lines on old Sales Order record
                    salesOrder.setSublistValue({
                        sublistId: 'item',
                        fieldId: 'isclosed',
                        line: i,
                        value: true
                    });
                };


                const soId = salesOrder.save();
            }
        } catch (e) {
            log.error({
                title: e.name,
                details: e.message
            });
        }
    }

Author: Brandon Doser


Got stuck on a step in this article?

We like to update our blogs and articles to make sure they help resolve any troubleshooting difficulties you are having. Sometimes, there is a related feature to enable or a field to fill out that we miss during the instructions. If this article didn't resolve the issue, please use the chat and let us know so that we can update this article!

 
 

Want to keep learning?

Our team of NetSuite professionals has written articles on a wide variety of NetSuite topics, from SuiteCommerce tips, to recommended NetSuite solutions, to available support services, and more! 

Your cart