Fetching UPS package delivery status multiple tracking numbers

Scenario:

Fetch delivery status for each tracking number in an Item Fulfillment

Solution

/**
 * @NApiVersion 2.x
 * @NScriptType MapReduceScript
 * @NModuleScope SameAccount
 */
/**
 * Script Description
 * This Map Reduce to create file to store the Details of UPS by making API call .
 *
 /*******************************************************************************
 * APC-100 SS UPS Delivery Status
 * *******************************************************************************
 * $Author: Jobin & Jismi IT Services LLP $
 *
 * Date: 19 - 12 - 2019
 * Revision History*
 *
 * Date: 27 - May - 2022
 * Updated the script logic for considering multple tracking numbers in an IF forexecution
 *
 * DESCRIPTION
 * This Map Reduce to create file to store the Details of UPS by making API call and
 * create pdf file in the file cabinent that linked with the respective IF.
 *
 ******************************************************************************/
define(['N/record', 'N/file', 'N/render', 'N/runtime', 'N/search', 'N/email', 'N/encode', 'N/task', 'N/https'],
    function (record, file, render, runtime, search, email, encode, task, https) {
        var main = {
            /*Get inputData for Processing */
            getInputData: function () {
                try {
                    var itemfulfillmentSearchObj = search.create({
                        type: "itemfulfillment",
                        filters: [
                            [["type", "anyof", "ItemShip"]],
                            "AND",
                            [["shipmentpackage.trackingnumber", "isnotempty", ""]],
                            "AND",
                            [["mainline", "is", "T"]],
                            // "AND",
                            // [["custbody_jj_ups_pdf_create", "is", "F"]],
                            "AND",
                            [[[["tranpickeddate", "onorafter", "daysago30"]], "AND", [["createdfrom.type", "anyof", "SalesOrd"]]], "OR", [[["createdfrom.type", "anyof", "VendAuth"]], "AND", [["trandate", "onorafter", "daysago30"]]]]
                        ],
                        columns: [
                            search.createColumn({
                                name: "trackingnumber",
                                join: "shipmentPackage",
                                label: "Tracking Number"
                            }),
                            search.createColumn({name: "internalid", label: "Internal ID"})
                        ]
                    });

                    var array = [], trackingNum;
                    var searchResultCount = itemfulfillmentSearchObj.runPaged().count;

                    if (searchResultCount > 0) {
                        itemfulfillmentSearchObj.run().each(function (result) {
                            var obj = {};
                            obj.id = result.getValue({name: "internalid", label: "Internal ID"})
                            trackingNum = result.getValue({
                                name: "trackingnumber",
                                join: "shipmentPackage",
                                label: "Tracking Number"
                            });
                            obj.tranNum = result.getValue({
                                name: "trackingnumber",
                                join: "shipmentPackage",
                                label: "Tracking Number"
                            });

                            if (checkForParameter(obj.tranNum))
                                array.push(obj)
                            return true;
                        });

                        return array;
                    } else
                        return []
                }catch (e) {
                    log.debug("Error@getInput", e)
                    return []
                }
            },
            /*map Function of map Reduce */
            map: function (context){
                try{
                    var resultObject=JSON.parse(context.value);
                    var IFid= resultObject.id;

                    context.write({
                        key:IFid,
                        value:resultObject
                    })
                }catch (e) {
                    log.debug("Error@map", e)
                    return []
                }
            },

            /*Reduce Function of map Reduce */
            reduce: function (context){
                try {
                    var dataIF =  context.values.map(JSON.parse);
                    log.debug("dataIF",dataIF)


                    // var contextData= JSON.parse(context.values[0]) //.values[0].values["GROUP(internalid)"].value)
                    // log.debug('contextData', contextData)contextData.values["GROUP(internalid)"].value;

                    var internalid = dataIF[0].id;

                    //var internalid = context.key

                    //load IF record
                    var ifRec = record.load({
                        type: record.Type.ITEM_FULFILLMENT,
                        id: internalid,
                        isDynamic: true
                    });
                    var trackingCount = dataIF.length;
                    log.debug("trackingCount", trackingCount)

                    for (var j=0; j<dataIF.length; j++){

                        var trackingNum = dataIF[j].tranNum;
                        log.debug("trackingNum", trackingNum)


                        //check whether a custom record entry for this tracking number already exists or not
                        var recEntryID = searchForCustomrecordEntry(trackingNum, internalid)

                        if (recEntryID){
                            var recEntry = record.load({
                                type: 'customrecord_jj_trackingnum_setup_apc381',
                                id: recEntryID,
                                isDynamic: true
                            });
                            var delivered = recEntry.getValue({fieldId: 'custrecord_jj_delivered'})
                            if (delivered == false)
                                fetchDeliveryStatus(trackingNum, internalid, recEntry)

                        }
                        else {
                            //create custom record entry
                            var recEntry = record.create({
                                type: 'customrecord_jj_trackingnum_setup_apc381',
                                isDynamic: true
                            });
                            recEntry.setValue({fieldId: 'name', value: trackingNum})
                            recEntry.setValue({fieldId: 'custrecord_jj_corresponding_if', value: internalid})
                            recEntry.setValue({fieldId: 'custrecord_jj_trackingnumber', value: trackingNum})
                            recEntry.setValue({fieldId: 'custrecord_jj_externalid', value: internalid+'_'+trackingNum})
                            fetchDeliveryStatus(trackingNum, internalid, recEntry)
                        }
                    }
                } catch (err) {
                    log.debug('error@reduce', err.message);
                }
            },
            summarize: function (context) {
                try {

                } catch (err) {
                    log.debug("error@summarize", err)
                }

            },
            findfile: function () {

            }

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

        /**
         * Function that fetches the UPS shipping status
         * @param trackingNum
         * @param internalid
         * @param recEntry
         */
        function fetchDeliveryStatus(trackingNum, internalid, recEntry) {
            try {

                //Call the API to determine UPS shipping status
                var jsonBody = {
                    "UPSSecurity": {
                        "UsernameToken": {
                            "Username": "alliedtradinginc",
                            "Password": "Allied10555"
                        },
                        "ServiceAccessToken": {
                            "AccessLicenseNumber": "7D724FC3C0E4F732"
                        }
                    },
                    "TrackRequest": {
                        "Request": {
                            "RequestOption": "1",
                            "TransactionReference": {
                                "CustomerContext": "Your Test Case Summary Description"
                            }
                        },
                        "InquiryNumber": trackingNum
                    }
                }
                var headerObj = {
                    "Content-Type": 'application/json',
                    "Accept": 'application/json'
                };
                var response = https.post({
                    url: 'https://onlinetools.ups.com/rest/Track',
                    headers: headerObj,
                    body: JSON.stringify(jsonBody),
                    json: true
                });
                log.debug('response1111', response)
                if (response.code == 200) {
                    response = JSON.parse(response.body)
                    log.debug('response1111', response)

                    if (response.Fault) {
                    } else {
                        log.debug("test", 'test')
                        var ShipmentAddress = response["TrackResponse"]["Shipment"]["ShipmentAddress"]
                        var deliverToAddress = "";
                        if (ShipmentAddress[1]) {
                            var deliverTo = ShipmentAddress[1]["Address"]
                            for (var key in deliverTo) {
                                deliverToAddress += deliverTo[key] + "<br/>"
                            }
                        }
                        var service = response["TrackResponse"]["Shipment"]["Service"]["Description"]
                        var pickupDate = response["TrackResponse"]["Shipment"]["PickupDate"]
                        if (pickupDate) {
                            pickupDate = pickupDate.substring(4, 6) + "/" + pickupDate.substring(6, 8) + "/" + pickupDate.substring(0, 4)
                        }
                        try {
                            var activity = response["TrackResponse"]["Shipment"]["Package"]["Activity"]
                            if (!activity) {
                                var datatoProcess = response["TrackResponse"]["Shipment"]["Package"]
                                for (var m = 0; m < datatoProcess.length; m++) {
                                    var activity = datatoProcess[m]["Activity"]
                                    trackingNum = datatoProcess[m]["TrackingNumber"]
                                    var TABLE = " "
                                    /* log.debug("activity", activity) */
                                    for (var i = 0; i < activity.length; i++) {
                                        var ShipmentWeight = datatoProcess["PackageWeight"]
                                        if (ShipmentWeight) {
                                            var unitMeasure = ShipmentWeight["UnitOfMeasurement"]["Code"]
                                            var weight = ShipmentWeight["Weight"] + " " + unitMeasure
                                        }
                                        var address = activity[i]["ActivityLocation"]["Address"]
                                        var finalAddress = "";
                                        for (var key in address) {
                                            finalAddress += address[key] + "<br/>"
                                        }
                                        var dateValue = activity[i]["Date"].substring(4, 6) + "/" + activity[i]["Date"].substring(6, 8) + "/" + activity[i]["Date"].substring(0, 4)
                                        var timeValue = activity[i]["Time"].substring(0, 2) + ":" + activity[i]["Time"].substring(2, 4)
                                        var signedValue = " "
                                        if (activity[i]["ActivityLocation"]["SignedForByName"]) {
                                            signedValue = activity[i]["ActivityLocation"]["SignedForByName"]
                                        } else {
                                            signedValue = " - "
                                        }
                                        var statusStings = activity[i]["Status"]["Description"]
                                        var statusStingsLength = statusStings.length;
                                        if (statusStingsLength > 32) {
                                            var array = statusStings.split(" ");
                                            var statusData = " ";
                                            for (var l = 0; l < array.length; l++) {
                                                if (l % 5 == 0) {
                                                    statusData += array[l] + "<br />"
                                                } else {
                                                    statusData += array[l] + " "
                                                }
                                            }
                                            statusStings = statusData
                                        }
                                        var strVar = "";
                                        strVar += "<tr>";
                                        strVar += "<td >" + finalAddress + "<\/td>";
                                        strVar += "<td >" + activity[i]["ActivityLocation"]["Description"] + "<\/td>";
                                        strVar += "<td >" + statusStings + "<\/td>";
                                        strVar += "<td >" + dateValue + " " + timeValue + "<\/td>";
                                        // strVar += "<td >" + timeValue + "<\/td>";
                                        strVar += "<td >" + signedValue + "<\/td>";
                                        strVar += "<\/tr>";
                                        strVar = strVar + '\n';
                                        TABLE = TABLE + strVar;
                                        if (activity[i]["Status"]["Description"] == "Delivered") {
                                            var SignedByName = signedValue
                                            var DeliveredOn = dateValue + " " + timeValue
                                            var LeftAt = activity[i]["ActivityLocation"]["Description"]
                                            // var id = record.submitFields({
                                            //     type: 'itemfulfillment',
                                            //     id: internalid,
                                            //     values: {
                                            //         custbody_jj_ups_pdf_create: true
                                            //     }
                                            // });
                                            recEntry.setValue({fieldId: 'custrecord_jj_delivered', value: true})

                                            if (!deliverToAddress) {
                                                deliverToAddress = finalAddress
                                            }
                                        }
                                    }
                                    recEntry.save();
                                    var myXMLFile = file.load({
                                        id: '176569'
                                    });
                                    var xmlStr = myXMLFile.getContents();
                                    xmlStr = xmlStr.replace('<!-- REPLACEWITHTABLEBODY -->', TABLE);
                                    xmlStr = xmlStr.replace(/<!--REPLACEPACKAGEID-->/g, trackingNum);
                                    xmlStr = xmlStr.replace('<!-- REPLACEWITHDELIVERTO -->', deliverToAddress);
                                    if (weight) {
                                        xmlStr = xmlStr.replace('<!-- REPLACEWITHWEIGHT -->', weight);
                                        xmlStr = xmlStr.replace('<!-- REPLACEWITHWEIGHTWORD -->', "Weight");
                                    }
                                    xmlStr = xmlStr.replace('<!-- REPLACEWITHSERVICE -->', service);
                                    xmlStr = xmlStr.replace('<!-- REPLACEWITHSIGNEDBY -->', SignedByName);
                                    xmlStr = xmlStr.replace('<!-- REPLACEWITHDELIVERON -->', DeliveredOn);
                                    xmlStr = xmlStr.replace('<!-- REPLACEWITHLEFTAT -->', LeftAt);
                                    if (pickupDate) {
                                        xmlStr = xmlStr.replace('<!-- REPLACEWITHPICKUPDATE-->', pickupDate);
                                        xmlStr = xmlStr.replace('<!-- REPLACEWITHPICKUPWORD-->', "Shipped / Billed On");
                                    }
                                    var pdfFile = render.xmlToPdf({
                                        xmlString: xmlStr
                                    });
                                    pdfFile.name = trackingNum + '.pdf'
                                    pdfFile.folder = 131249

                                    var fileID = pdfFile.save();
                                    var attachid = record.attach({
                                        record: {
                                            type: 'file',
                                            id: fileID
                                        },
                                        to: {
                                            type: 'itemfulfillment',
                                            id: internalid
                                        }
                                    });

                                }
                            } else {
                                var datatoProcess = response["TrackResponse"]["Shipment"]["Package"]
                                var ShipmentWeight = datatoProcess["PackageWeight"]
                                if (ShipmentWeight) {
                                    var unitMeasure = ShipmentWeight["UnitOfMeasurement"]["Code"]
                                    var weight = ShipmentWeight["Weight"] + " " + unitMeasure
                                }
                                for (var i = 0; i < activity.length; i++) {
                                    var address = activity[i]["ActivityLocation"]["Address"]
                                    var finalAddress = "";
                                    for (var key in address)
                                        finalAddress += address[key] + "<br/>"

                                    var dateValue = activity[i]["Date"].substring(4, 6) + "/" + activity[i]["Date"].substring(6, 8) + "/" + activity[i]["Date"].substring(0, 4)
                                    var timeValue = activity[i]["Time"].substring(0, 2) + ":" + activity[i]["Time"].substring(2, 4)
                                    var signedValue = " "
                                    if (activity[i]["ActivityLocation"]["SignedForByName"]) {
                                        signedValue = activity[i]["ActivityLocation"]["SignedForByName"]
                                    } else {
                                        signedValue = " - "
                                    }
                                    var statusStings = activity[i]["Status"]["Description"]
                                    var statusStingsLength = statusStings.length;
                                    if (statusStingsLength > 32) {
                                        var array = statusStings.split(" ");
                                        var statusData = " ";
                                        for (var l = 0; l < array.length; l++) {
                                            if (l % 5 == 0) {
                                                statusData += array[l] + "<br />"
                                            } else {
                                                statusData += array[l] + " "
                                            }
                                        }
                                        statusStings = statusData
                                    }

                                    var strVar = "";
                                    strVar += "<tr>";
                                    strVar += "<td >" + finalAddress + "<\/td>";
                                    strVar += "<td >" + activity[i]["ActivityLocation"]["Description"] + "<\/td>";
                                    strVar += "<td >" + statusStings + "<\/td>";
                                    strVar += "<td >" + dateValue + " " + timeValue + "<\/td>";
                                    // strVar += "<td >" + timeValue + "<\/td>";
                                    strVar += "<td >" + signedValue + "<\/td>";
                                    strVar += "<\/tr>";
                                    strVar = strVar + '\n';
                                    TABLE = TABLE + strVar;
                                    if (activity[i]["Status"]["Description"] == "Delivered") {
                                        var SignedByName = signedValue
                                        var DeliveredOn = dateValue + " " + timeValue
                                        var LeftAt = activity[i]["ActivityLocation"]["Description"]

                                        // var custId = record.submitFields({
                                        //     type: 'customrecord_jj_trackingnum_setup_apc381',
                                        //     id: internalid,
                                        //     values: {
                                        //         custbody_jj_ups_pdf_create: true
                                        //     }
                                        // });

                                        recEntry.setValue({fieldId: 'custrecord_jj_delivered', value: true})



                                        if (!deliverToAddress) {
                                            deliverToAddress = finalAddress
                                        }
                                    }

                                }
                                recEntry.save();

                                var myXMLFile = file.load({
                                    id: '176569'
                                });
                                var xmlStr = myXMLFile.getContents();
                                xmlStr = xmlStr.replace('<!-- REPLACEWITHTABLEBODY -->', TABLE);
                                xmlStr = xmlStr.replace(/<!--REPLACEPACKAGEID-->/g, trackingNum);
                                xmlStr = xmlStr.replace('<!-- REPLACEWITHDELIVERTO -->', deliverToAddress);
                                if (weight) {
                                    xmlStr = xmlStr.replace('<!-- REPLACEWITHWEIGHT -->', weight);
                                    xmlStr = xmlStr.replace('<!-- REPLACEWITHWEIGHTWORD -->', "Weight");
                                }
                                xmlStr = xmlStr.replace('<!-- REPLACEWITHSERVICE -->', service);
                                xmlStr = xmlStr.replace('<!-- REPLACEWITHSIGNEDBY -->', SignedByName);
                                xmlStr = xmlStr.replace('<!-- REPLACEWITHDELIVERON -->', DeliveredOn);
                                xmlStr = xmlStr.replace('<!-- REPLACEWITHLEFTAT -->', LeftAt);
                                if (pickupDate) {
                                    xmlStr = xmlStr.replace('<!-- REPLACEWITHPICKUPDATE-->', pickupDate);
                                    xmlStr = xmlStr.replace('<!-- REPLACEWITHPICKUPWORD-->', "Shipped / Billed On");
                                }
                                var pdfFile = render.xmlToPdf({
                                    xmlString: xmlStr
                                });
                                pdfFile.name = trackingNum + '.pdf'
                                pdfFile.folder = 131249

                                var fileID = pdfFile.save();
                                var attachid = record.attach({
                                    record: {
                                        type: 'file',
                                        id: fileID
                                    },
                                    to: {
                                        type: 'itemfulfillment',
                                        id: internalid
                                    }
                                });
                            }
                        } catch (er) {
                            log.debug("er", er)
                        }
                    }
                }

            } catch (e) {
                log.debug("Error@fetch delivery status", e)
            }
        }

        function searchForCustomrecordEntry(trackingNum, itemFulfillment) {
            try {
                var uniqueKey = itemFulfillment+'_'+trackingNum;
                var customrecordSearchObj = search.create({
                    type: "customrecord_jj_trackingnum_setup_apc381",
                    filters:
                        [
                            ["custrecord_jj_externalid", "is", uniqueKey],
                        ],
                    columns:
                        [
                            search.createColumn({name: "internalid", label: "Internal ID"})
                        ]
                });
                var searchResultCount = customrecordSearchObj.runPaged().count;
                log.debug("customrecord_jj_trackingnum_setup_apc381SearchObj result count", searchResultCount);

                if (searchResultCount > 0) {
                    var recId;
                    customrecordSearchObj.run().each(function (result) {
                        recId = result.getValue({name: "internalid", label: "Internal ID"})
                        return true;
                    });
                    return recId;
                } else
                    return false;

            } catch (e) {
                log.debug("Error@searchForCustomrecordEntry", e)
                return false;
            }
        }

        /**
         * @description Check whether the given parameter argument has value on it or is it empty.
         * ie, To check whether a value exists in parameter
         * @author Manu Antony
         * @param {*} parameter parameter which contains/references some values
         * @param {*} parameterName name of the parameter, not mandatory
         * @returns {Boolean} true if there exist a value else false
         */
        function checkForParameter(parameter, parameterName) {
            if (parameter !== "" && parameter !== null && parameter !== undefined && parameter !== false && parameter !== "null" && parameter !== "undefined" && parameter !== " " && parameter !== 'false') {
                return true;
            } else {
                if (parameterName)
                    log.debug('Empty Value found', 'Empty Value for parameter ' + parameterName);
                return false;
            }
        }


        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 *