Shopify – NetSuite Live Sync Orders

Jira Code : DAZ-32

This task accomplishes the live sync of the orders from Shopify to NetSuite. Whenever orders are created in Shopify, corresponding sales order, invoice and payment records will be created in NetSuite.

The task works in the following way. Once an order is created, an email is sent to NetSuite. On receiving this email, an email capture script is triggered and from there, it goes to a Suitelet and finally to a Scheduled script. Orders and its corresponding records are created at this instance.

DAZ-32 Create Orders from Shopify (Email Capture)

function process(email) {
    try {
        // log all information in email
        var fromAddress = email.getFrom();
        log("fromAddress", fromAddress);

        var subject = email.getSubject();
        log("fromAddress", fromAddress);
        var recordid = createtask(true);
    } catch (e) {
        log('error in main', e)
    }
}

function createtask(type) {
    try {
        var url = nlapiResolveURL("SUITELET", "customscript_daz_12_sl_scheduler", "customdeploy_daz_12_sl_scheduler", "external");
        log('rl', url);
        var res = nlapiRequestURL(url, null, 'POST', 'POST');

    } catch (e) {

        log('error in createtask', e)

    }

}


function log(label, text) {
    nlapiLogExecution('DEBUG', label, text);
}

DAZ-32 Create Orders from Shopify (Suitelet)

/**
 * * @NApiVersion 2.x
 * @NScriptType Suitelet
 */
/**
 * Script Description: Fetch Data from Shopify to Netsute on Order Email Trigger
 */
/*******************************************************************************
 * * Shopify - Netsuite Integeration * *
 * **************************************************************************
 * Date: 30/04/19 SS Shopify - Netsuite Connector:
 * 
 * parameters : 
 * 
 ******************************************************************************/
define(['N/email', 'N/file', 'N/http', 'N/https', 'N/record', 'N/runtime', 'N/search', 'N/ui/serverWidget', 'N/task'],
    /**
     * @param {email} email
     * @param {file} file
     * @param {http} http
     * @param {https} https
     * @param {record} record
     * @param {runtime} runtime
     * @param {search} search
     * @param {serverWidget} serverWidget
     */
    function(email, file, http, https, record, runtime, search, serverWidget, task) {
        var main = {
            onRequest: function(context) {
                log.debug("afaf", context)
                main.scheduleAnother(0);
                context.response.write('Success');

            },
            scheduleAnother: function(count) {
                var scheduleScrptTask = task.create({
                    taskType: task.TaskType.SCHEDULED_SCRIPT,
                    scriptId: "customscriptdaz_12_ss_shopify_netsuite",
                    deploymentId: 'customdeploydaz_12_ss_shopify_netsuite',
                    params: {
                        custscript_current_position: count
                    }
                });
                scheduleScrptTask.submit();
            }
        };

        for (var key in main) {
            if (typeof main[key] === 'function') {
                main[key] = trycatch(main[key], key);
            }
        }

        function trycatch(myfunction, key) {
            return function() {
                try {
                    return myfunction.apply(this, arguments);
                } catch (e) {
                    log.debug("e in  " + key, e);

                    return e
                }
            }
        };


        return main
    });

DAZ-32 SS Live Sync Orders

/**
 * * @NApiVersion 2.x
 * @NScriptType ScheduledScript
 */
/**
 * Script Description: Fetch Data from Shopify to Netsute on Order Email Trigger
 */
/*******************************************************************************
 * * Shopify - Netsuite Integeration * *
 * **************************************************************************
 * Date: 30/04/19 SS Shopify - Netsuite Connector:
 * 
 * parameters : 
 * 
 ******************************************************************************/

define(
    ['N/https', 'N/record', 'N/runtime', 'N/search', 'N/format', "N/file", 'N/task', 'N/email'],

    function(https, record, runtime, search, format, file, task, email) {

        var main = {
            checkUsage: function(type) {
                var scriptObj = runtime.getCurrentScript();
                var remainingUsage = scriptObj.getRemainingUsage();
                log.debug("Remaining governance units@  " + type, remainingUsage);
                return remainingUsage;
            },
            scheduleAnother: function(count) {
                var scheduleScrptTask = task.create({
                    taskType: task.TaskType.SCHEDULED_SCRIPT,
                    scriptId: "customscriptdaz_12_ss_shopify_netsuite",
                    deploymentId: 'customdeploydaz_12_ss_shopify_netsuite',
                    params: {
                        custscript_current_position: count
                    }
                });
                scheduleScrptTask.submit();
            },
            createFile: function(netsuitedata, name) {
                var fileObj = file.create({
                    name: name + '.txt',
                    fileType: file.Type.JSON,
                    contents: JSON.stringify(netsuitedata),
                    encoding: file.Encoding.UTF8,
                    folder: 1749,
                    isOnline: true
                });
                var fileid = fileObj.save();
                return fileid;
            },
            getCount: function(currentCount) {
                var orderCount = https.get({
                    url: 'https://bfbb2c59c5c96793ca4acddc69ac3e70:c3d1104a816cd8b3ee224b2697ae266d@7daze-manufacturing.myshopify.com/admin/api/2019-04/orders/count.json',
                });
                var orderCount = JSON.parse(orderCount.body);
                log.debug("orderCount", orderCount);
                return orderCount;
            },
            fetchOrder: function(orderId) {
                log.debug("orderId", orderId)
                var shopifyResponse = https.get({
                    url: 'https://bfbb2c59c5c96793ca4acddc69ac3e70:c3d1104a816cd8b3ee224b2697ae266d@7daze-manufacturing.myshopify.com/admin/api/2019-04/orders.json?since_id=' + orderId,
                });
                var shopifyResponse = JSON.parse(shopifyResponse.body);
                log.debug(shopifyResponse.orders.length, shopifyResponse);
                main.createItem(shopifyResponse, 'shopifyResponse');

                return shopifyResponse;
            },
            getFile: function(fileid) {
                var fileObj = file.load({
                    id: fileid
                });
                if (fileObj.size < 10485760) {
                    var content = fileObj.getContents();
                }
                return content
            },
            execute: function(scriptContext) {
                var rescheduleFlag = runtime.getCurrentScript().getParameter("custscript_reschedule");
                var writeFile = runtime.getCurrentScript().getParameter("custscript_order_file");
                if (rescheduleFlag == 'false') {
                    var folderId = runtime.getCurrentScript().getParameter("custscript_folder_id");
                    var previousOrder = runtime.getCurrentScript().getParameter("custscript_previous_count");
                    var previousOrder = main.getFile(previousOrder);
                    //var previousOrder = 1039450931287
                    // var currentCount = main.getCount();
                    // log.debug("currentCount", currentCount);
                    if (previousOrder) var orderDetails = main.fetchOrder(previousOrder);
                    var orders = orderDetails.orders;
                    var currentLoop = 0;
                } else {
                    var currentLoop = runtime.getCurrentScript().getParameter("custscript_current_loop");
                    log.debug("currentLoop", currentLoop);

                    var orderDetails = main.getFile(writeFile);
                    log.debug("orderDetails", orderDetails);

                    var orders = JSON.parse(orderDetails).orders;
                    log.debug("orders", orders);

                }
                for (var i = currentLoop; i < orders.length; i++) {
                    if ((i + 1) == orders.length) {
                        main.createFile(orders[i].id, 'prevCount');
                    }
                    main.processOrders(orders[i]);
                    if (main.checkUsage() < 1000) {
                        main.scheduleAnother(i);
                        return true;
                        break;
                    }
                }
            },
            processOrders: function(orderObj) {
                var customerId = main.fetchCustomer(orderObj);
                var orderId = main.createOrder(customerId, orderObj);

                if (orderId)
                    main.createInvCusPmnt(orderId, orderObj.id);


            },
            createOrder: function(customerId, orderObj) {
                var objRecord = record.transform({
                    fromType: record.Type.CUSTOMER,
                    fromId: customerId,
                    toType: record.Type.SALES_ORDER,
                    isDynamic: false,
                    ignoreMandatoryFields: true
                });
                objRecord.setText({
                    fieldId: 'memo',
                    text: 'Live order from Shopify (original posting date) ' + orderObj.id
                });
                log.debug('test');
                objRecord.setValue({ fieldId: 'orderstatus', value: 'B' });
                objRecord.setValue({ fieldId: 'externalid', value: "" + orderObj.id });

                var shopifyItems = orderObj.line_items;
                log.debug('shopifyItems', shopifyItems);
                log.debug('Length of shopifyItems', shopifyItems.length);

                var taxLines = orderObj.tax_lines;
                log.debug('taxLines', taxLines);
                log.debug('Length of taxLines', taxLines.length);

                for (var i = 0; i < shopifyItems.length; i++) {
                    // objRecord.selectNewLine({
                    //     sublistId: 'item'
                    // });
                    var itemId = main.fetchItem(shopifyItems[i].sku, shopifyItems[i]);
                    objRecord.setSublistValue({
                        sublistId: 'item',
                        fieldId: 'item',
                        value: itemId,
                        line: i,
                        ignoreFieldChange: false
                    });
                    objRecord.setSublistValue({
                        sublistId: 'item',
                        fieldId: 'quantity',
                        line: i,
                        value: shopifyItems[i].quantity,
                        ignoreFieldChange: false
                    });
                    objRecord.setSublistValue({
                        sublistId: 'item',
                        fieldId: 'rate',
                        line: i,
                        value: shopifyItems[i].price,
                        ignoreFieldChange: false
                    });

                    if (taxLines.length != 0) {
                        objRecord.setSublistValue({
                            sublistId: 'item',
                            fieldId: 'istaxable',
                            value: true,
                            line: i,
                            ignoreFieldChange: false
                        });
                    }

                    // objRecord.commitLine({
                    //     sublistId: 'item'
                    // });
                }

                //tax
                // var taxLines = orderObj.tax_lines;
                // log.debug('taxLines', taxLines);
                // log.debug('Length of taxLines', taxLines.length);
                if (taxLines.length == 1) {
                    if (taxLines[0].title == 'Los Angeles County Tax') {
                        objRecord.setValue({ fieldId: 'istaxable', value: true });
                        objRecord.setValue({ fieldId: 'taxitem', value: 5734 });
                    } else if (taxLines[0].title == 'CA State Tax') {
                        objRecord.setValue({ fieldId: 'istaxable', value: true });
                        objRecord.setValue({ fieldId: 'taxitem', value: 5733 });
                    } else
                        log.debug('Test');
                } else if (taxLines.length == 2) {
                    if ((taxLines[0].title == 'Los Angeles County Tax' && taxLines[1].title == 'CA State Tax') || (taxLines[1].title == 'Los Angeles County Tax' && taxLines[0].title == 'CA State Tax')) {
                        objRecord.setValue({ fieldId: 'istaxable', value: true });
                        objRecord.setValue({ fieldId: 'taxitem', value: 5735 });
                    }
                }

                //shipping cost
                log.debug('orderObj.shipping_lines', orderObj.shipping_lines);
                if (orderObj.shipping_lines != 0) {
                    log.debug('in');
                    var shipLine = orderObj.shipping_lines;
                    var shippingMethod = shipLine[0].title;
                    var shppingCost = shipLine[0].price;
                    log.debug('shppingCost', shppingCost);
                    // objRecord.setValue({
                    //     fieldId: 'shippingcost',
                    //     value: shppingCost
                    // });


                    if (shippingMethod == 'UPS')
                        objRecord.setValue({ fieldId: 'shipcarrier', value: 'ups' });
                    else if (shippingMethod == 'Standard Shipping') {
                        objRecord.setValue({ fieldId: 'shipcarrier', value: 'nonups' });
                        objRecord.setValue({ fieldId: 'shipmethod', value: 4905 });
                    } else if (shippingMethod == 'USPS Priority Mail' || shippingMethod == 'USPS Priority International' || shippingMethod == 'USPS Priority Mail (2-3 Days)') {
                        objRecord.setValue({ fieldId: 'shipcarrier', value: 'nonups' });
                        objRecord.setValue({ fieldId: 'shipmethod', value: 5031 });
                    } else if (shippingMethod == 'Custom') {
                        objRecord.setValue({ fieldId: 'shipcarrier', value: 'nonups' });
                        objRecord.setValue({ fieldId: 'shipmethod', value: 4905 });
                    }

                    if (orderObj.shipping_lines != 0) {
                        objRecord.setValue({
                            fieldId: 'shippingcost',
                            value: shppingCost
                        });
                    }
                }

                //discount
                var discount_codes = orderObj.discount_codes;
                log.debug('discount_codes', discount_codes);
                if (discount_codes.length != 0) {
                    log.debug('in');
                    var discount = discount_codes[0].code;
                    log.debug('discount', discount);

                    var discountPrice = discount_codes[0].amount;
                    log.debug('discountPrice', discountPrice);

                    if (discount == "Custom discount") {

                        log.debug('match')
                        objRecord.setValue({
                            fieldId: 'discountitem',
                            value: 6416
                        });
                        objRecord.setValue({
                            fieldId: 'discountrate',
                            value: -discountPrice
                        });
                    } else {
                        var discountitem = main.discountSearch(discount)

                        log.debug('discountitem12', discountitem);

                        if (discountitem == false) {
                            log.debug('discountitemFalse');
                            objRecord.setValue({
                                fieldId: 'discountitem',
                                value: 6416
                            });

                        } else {

                            log.debug('discountitemElse');

                            objRecord.setValue({
                                fieldId: 'discountitem',
                                value: discountitem
                            });
                        }

                        objRecord.setValue({
                            fieldId: 'discountrate',
                            value: -discountPrice
                        });
                    }
                }

                //shopifyBilladdress
                var shopifyBilladdress = orderObj.billing_address;
                var billaddrId = main.validateaddr(customerId, shopifyBilladdress);


                //shopifyShipaddress
                var shopifyShipaddress = orderObj.shipping_address;
                var shipaddrId = main.validateaddr(customerId, shopifyShipaddress);

                objRecord.setValue("billaddress", billaddrId);
                objRecord.setValue("shipaddress", shipaddrId);
                log.debug("agatg", itemId);
                try {
                    var recordId = objRecord.save({
                        enableSourcing: false,
                        ignoreMandatoryFields: false
                    });
                    log.debug("SALES_ORDER", recordId);

                    return recordId;
                } catch (er) {
                    log.debug('er', er);
                    if (er.name == "DUP_RCRD") {
                        email.send({
                            author: -5,
                            recipients: "joe@jobinandjismi.com",
                            subject: 'Failed to Sync Shopify Order',
                            body: 'Duplicate order has been identified \n Order Details : Id ' + orderObj.id + '\n',
                        });
                    } else {
                        email.send({
                            author: -5,
                            recipients: "aleena@jobinandjismi.com",
                            subject: 'Failed to Sync Shopify Order',
                            body: er + '\n Order Details: Id ' + orderObj.id + '\n',
                        });
                    }
                }
            },
            createInvCusPmnt: function(soId, externalId) {

                try {

                    var invRec = record.transform({
                        fromType: record.Type.SALES_ORDER,
                        fromId: soId,
                        toType: record.Type.INVOICE
                    });
                    invRec.setValue({ fieldId: 'memo', value: 'Order ID in Shopify ' + externalId });
                    invRec.setValue({ fieldId: 'externalid', value: 'INV_' + externalId });
                    invRec.setValue({ fieldId: 'externalid', value: 'INV_' + externalId });
                    var invRecID = invRec.save();

                    var cusPmntRec = record.transform({
                        fromType: record.Type.INVOICE,
                        fromId: invRecID,
                        toType: record.Type.CUSTOMER_PAYMENT
                    });
                    cusPmntRec.setValue({ fieldId: 'memo', value: 'Order ID in Shopify ' + externalId });
                    cusPmntRec.setValue({ fieldId: 'account', value: '' });
                    cusPmntRec.setValue({ fieldId: 'externalid', value: 'CP_' + externalId });
                    cusPmntRec.setValue({ fieldId: 'undepfunds', value: 'T' });
                    var cusPmntRecID = cusPmntRec.save();
                } catch (er) {
                    log.debug('er', er);
                    log.debug("Error", "Cannot create invoice or customer Customer payment");
                }

            },
            fetchItem: function(itemId, itemObj) {


                //if (itemInternalId) var itemId = main.searchItem(itemInternalId);
                //  else var itemId = main.searchItem(itemObj.name);

                if (itemId) return itemId;
                //else return main.createItem(itemObj);
            },
            searchItem: function(itemInternalId) {
                var itemSearchObj = search.create({
                    type: "item",
                    filters: [
                        ["internalid", "is", itemInternalId]
                    ],
                    columns: [
                        search.createColumn({
                            name: "internalid",
                            sort: search.Sort.ASC,
                            label: "Internal ID"
                        })
                    ]
                });
                var searchResultCount = itemSearchObj.runPaged().count;
                log.debug("itemSearchObj result count", searchResultCount);
                if (searchResultCount > 0) {
                    var internalId;
                    itemSearchObj.run().each(function(result) {
                        internalId = result.getValue("internalid");
                    });
                    return internalId;
                } else {
                    return false;
                }
            },
            createItem: function(itemObj) {
                var newitem = record.create({
                    type: "lotnumberedinventoryitem",
                    isDynamic: true
                });
                log.debug("itemObj", itemObj);

                log.debug("itemObj.name", itemObj.sku);
                log.debug("itemObjtilre", itemObj.title);
                if (itemObj.sku) {
                    newitem.setValue({
                        fieldId: 'itemid',
                        value: itemObj.sku,
                        ignoreFieldChange: true
                    });
                } else {
                    newitem.setValue({
                        fieldId: 'itemid',
                        value: itemObj.name,
                        ignoreFieldChange: true
                    });
                }


                newitem.setValue({
                    fieldId: 'subsidiary',
                    value: 1,
                    ignoreFieldChange: true
                });

                var item_displayname = itemObj.title
                newitem.setValue({
                    fieldId: 'displayname',
                    value: item_displayname,
                    ignoreFieldChange: true
                });

                var itemId = newitem.save({
                    enableSourcing: false,
                    ignoreMandatoryFields: true
                });
                log.debug("itemid", itemId);
                return itemId;
            },
            fetchCustomer: function(customerObj) {
                var customerEmail = customerObj.customer.email;
                var custId = main.searchCustomer(customerEmail);

                if (custId) return custId;
                else return main.createCustomer(customerObj);
            },

            searchCustomer: function(email) {
                var customerSearchObj = search.create({
                    type: "customer",
                    filters: [
                        ["email", "is", email]
                    ],
                    columns: [
                        search.createColumn({
                            name: "internalid",
                            sort: search.Sort.ASC,
                            label: "Internal ID"
                        })
                    ]
                });
                var searchResultCount = customerSearchObj.runPaged().count;
                log.debug("customerSearchObj result count", searchResultCount);
                var internalId;
                if (searchResultCount > 0) {

                    customerSearchObj.run().each(function(result) {
                        internalId = result.getValue("internalid");
                    });

                    return internalId

                } else {
                    return false;
                }
            },
            validateaddr: function(internalId, custaddress) {
                var custLoad = record.load({
                    type: "customer",
                    id: internalId,
                    isDynamic: false
                });
                var subrecord;
                var addrsInternalId;
                var numLine = custLoad.getLineCount({ sublistId: 'addressbook' })
                for (var i = 0; numLine > 0; i++) {
                    var flag = true;
                    var subrec = custLoad.getSublistSubrecord({
                        sublistId: 'addressbook',
                        fieldId: 'addressbookaddress',
                        line: i
                    });
                    addrsInternalId = custLoad.getSublistValue({
                        sublistId: 'addressbook',
                        fieldId: 'internalid',
                        line: i
                    });
                    // Retrieve the subrecord to be checked.
                    var country = subrec.getValue('country');
                    var addr1 = subrec.getValue('addr1');
                    var addr2 = subrec.getValue('addr2');
                    var city = subrec.getValue('city');
                    var state = subrec.getValue('state');
                    var zip = subrec.getValue('zip');
                    var phone = subrec.getValue('addrphone');
                    if (addr1 != custaddress.address1 || addr2 != custaddress.address2 || city != custaddress.city || state != custaddress.state || zip != custaddress.zip || phone != custaddress.phone) {
                        var subrecord = custLoad.getSublistSubrecord({
                            sublistId: 'addressbook',
                            fieldId: 'addressbookaddress',
                            line: i
                        });
                        subrecord.setValue("country", custaddress.country_code); //Country must be set before setting the other address fields
                        subrecord.setValue("addrphone", custaddress.phone);
                        subrecord.setValue("addr1", custaddress.address1);
                        subrecord.setValue("addr2", custaddress.address2);
                        subrecord.setValue("city", custaddress.city);
                        subrecord.setValue("state", custaddress.state);
                        subrecord.setValue("zip", custaddress.zip);
                        return subrecord;
                    } else
                        return addrsInternalId;
                }
            },
            discountSearch: function(DISCOUNT_CODE) {

                var disc_itemId = null;

                var discountitemSearchObj = search.create({
                    type: "discountitem",
                    filters: [
                        ["isinactive", "is", "F"],
                        "AND",
                        ["type", "anyof", "Discount"],
                        "AND",
                        ["name", "is", DISCOUNT_CODE]
                    ],

                    columns: [search.createColumn({ name: "externalid", label: "External ID" }), search.createColumn({ name: "internalid", label: "Internal ID" }), search.createColumn({ name: "baseprice", label: "Base Price" })]
                });
                var searchResultCount = discountitemSearchObj.runPaged().count;

                discountitemSearchObj.run().each(function(result) {

                    disc_itemId = result.getValue(discountitemSearchObj.columns[1]);

                    return true;
                });
                log.debug('disc_itemId', disc_itemId);
                if (disc_itemId)
                    return disc_itemId;
                else
                    return false;


            },
            createCustomer: function(customerObj) {
                log.debug("customerObj", customerObj);
                var objRecord = record.create({
                    type: record.Type.CUSTOMER,
                    isDynamic: false,
                    ignoreMandatoryFields: true
                });

                objRecord.setValue({
                    fieldId: 'isperson',
                    value: 'T'
                });
                var firstname = customerObj.customer.first_name;
                var lastname = customerObj.customer.last_name;

                objRecord.setValue({
                    fieldId: 'firstname',
                    value: firstname
                });
                objRecord.setValue({
                    fieldId: 'lastname',
                    value: lastname
                });


                objRecord.setValue({
                    fieldId: 'subsidiary',
                    value: 1
                });
                objRecord.setValue({
                    fieldId: 'email',
                    value: customerObj.customer.email
                });
                objRecord.setValue({
                    fieldId: 'phone',
                    value: customerObj.customer.phone
                });
                // var addressLines = objRecord.getLineCount({ sublistId: 'addressbook' })
                // objRecord.selectNewLine({
                //     sublistId: 'addressbook'
                // });
                var addressObj = customerObj.customer.default_address;
                // var myaddressSubrecord = objRecord.getCurrentSublistSubrecord({
                //     sublistId: 'addressbook',
                //     fieldId: 'addressbookaddress'
                // });

                var myaddressSubrecord = objRecord.getSublistSubrecord({
                    sublistId: 'addressbook',
                    fieldId: 'addressbookaddress',
                    line: 0
                });

                myaddressSubrecord.setValue({
                    fieldId: 'addr1',
                    value: addressObj.address1
                });
                myaddressSubrecord.setValue({
                    fieldId: 'addr2',
                    value: addressObj.address2
                });
                myaddressSubrecord.setValue({
                    fieldId: 'country',
                    value: addressObj.country_code
                });
                myaddressSubrecord.setValue({
                    fieldId: 'city',
                    value: addressObj.city
                });
                myaddressSubrecord.setValue({
                    fieldId: 'state',
                    value: addressObj.province
                });

                myaddressSubrecord.setValue({
                    fieldId: 'zip',
                    value: addressObj.zip
                });
                // objRecord.commitLine({
                //     sublistId: 'addressbook'
                // });

                objRecord.setValue({
                    fieldId: 'salesrep',
                    value: 26235
                });
                objRecord.setValue({
                    fieldId: 'category',
                    value: 3
                });
                objRecord.setValue({
                    fieldId: 'custentity3',
                    value: customerObj.customer.accepts_marketing
                });

                var recordId = objRecord.save({
                    enableSourcing: 'false',
                    ignoreMandatoryFields: 'false'
                });
                log.debug("recordId", recordId);
                return recordId;
            }
        }
        for (var key in main) {
            if (typeof main[key] === 'function') {
                main[key] = trycatch(main[key], key);
            }
        }

        function trycatch(myfunction, key) {
            return function() {
                try {
                    return myfunction.apply(this, arguments);
                } catch (e) {
                    log.debug("e in  " + key, e);
                }
            }
        };
        return main;

    });

Leave a comment

Your email address will not be published. Required fields are marked *