Fetching the Shipping rate from the multiple UPS accounts using the UPS API Integration

A script was developed for populating package dimensions and fetching the shipping rates from the different UPS accounts  

The script will work only on the sales order create. The custom button called “Calculate Shipping Rate” was added in the Sales order edit context. While clicking the button the shipping rates will be fetched from the UPS accounts and it will update in the sale order.

The shipping rate is calculated using the UPS API integration. For fetching the shipping rate, the Negotiated rate method will be used by default.  

We will pass the following information to the UPS account for fetching the shipping rate 

  • Ship To Address – from sales order 
  • Ship from Address – from sales order’s location 
  • Package dimensions – from the Package Weight, Package Length, Package Width & Package height fields in sales order 

The shipping rate will be fetched from the 4 various UPS accounts. The 4 shipping rates will be compared and the lowest shipping rate is the best shipping rate.  

The best shipping rate and best account values will be stored in the corresponding fields in the sales order. Also, the best rate will be set as the shipping cost.

/**
 * @NApiVersion 2.1
 * @NScriptType UserEventScript
 */
/*******************************************************************************
 * Park Slope Carldani Enterprises
 ******************************************************************************
 * Date: 23 January 2023
 * Author: Jobin and Jismi
 * Script Description: The script is for fetching Shipping rate from the various UPS/FedEx accounts.
 * Created - 23/Jan/2023 - PSCL-34 - JJ0196
 * Updated - 20/Mar/2023 - PSCl-41 - JJ0196 - Script Updated for FedEx accounts
 *
 ******************************************************************************/
define(['N/https', 'N/record', 'N/search','N/url'],
    /**
 * @param{https} https
 * @param{record} record
 * @param{search} search
 * @param{url} url
 */
    (https, record, search,url) => {
        const afterSubmit = (scriptContext) => {
            try{
                let newRecord = scriptContext.newRecord;
                let soID = newRecord.id;
                log.debug({title:'soID',details:soID});
                let soObj = salesOrderSearch(soID);
                log.debug({title:'soObj',details:soObj});
                const validStatuses = ["Pending Approval", "Pending Fulfillment", "Partially Fulfilled", "Pending Billing", "Pending Billing/Partially Fulfilled"];
                if (validStatuses.includes(soObj.status)) {
                    if(checkForParameter(soObj.itemLen) && checkForParameter(soObj.itemWidth) && checkForParameter(soObj.itemHigh)) {
                        if(checkForParameter(soObj.itemWeight)) {
                            //Fetching Rate from the UPS654E80 account.
                            let rate1 = fetchingRateUPS654E80(soObj);
                            //log.debug({title:'UPS654E80',details:rate1});

                            //Fetching Rate from the UPS98722Y account.
                            let rate2 = fetchingRateUPS98722Y(soObj);
                            //log.debug({title:'UPS98722Y',details:rate2});

                            //Fetching Rate from the UPS98723A account.
                            let rate3 = fetchingRateUPS98723A(soObj);
                            //log.debug({title:'UPS98723A',details:rate3});

                            //Fetching Rate from the UPS16050X account.
                            let rate4 = fetchingRateUPS16050X(soObj);
                            rate4 = rate4 + (rate4 * 0.15); //Extra fee of 15% of the UPS16050X account
                            rate4 = parseFloat(rate4.toFixed(2));
                            //log.debug({title:'UPS16050X',details:rate4});

                            //Fetching Rate from the UPS09F185 account.
                            let rate5 = fetchingRateUPS09F185(soObj);
                            //log.debug({title:'UPS09F185',details:rate5});

                            //Fetching Rate from the FEDEX182790583 account.
                            let rate6 = fetchingRateFEDEX182790583(soObj);
                            //log.debug({title:'FEDEX182790583',details:rate6});

                            //Fetching Rate from the FEDEX572540600 account.
                            let rate7 = fetchingRateFEDEX572540600(soObj);

                            let rateArray = [rate1,rate2,rate3,rate4,rate5,rate6,rate7];
                            let accountArray = ["UPS654E80","UPS98722Y","UPS98723A","UPS16050X","UPS09F185","FEDEX182790583","FEDEX572540600"];
                            let bestRate = rateArray.filter(Boolean).length ? Math.min(...rateArray.filter(Boolean)) : 0;
                            //let bestRate = Math.min.apply(null, rateArray.filter(Boolean));   //Find minimum rate without zero
                            log.debug({title:'bestRate',details:bestRate});
                            let i = rateArray.indexOf(bestRate);
                            let bestAccount = accountArray[i];
                            log.debug({title:'bestAccount',details:bestAccount});

                            if (soObj.itemWeight < 1){
                                bestAccount = "USPS1C";     //Weight is LESS THAN 1LB ,"Best Rate Acct" should have a value of USPS1C
                            }

                            let upsRatesArray = [rate1,rate2,rate3,rate4,rate5];
                            let upsAccountArray = ["UPS654E80","UPS98722Y","UPS98723A","UPS16050X","UPS09F185"];
                            let bestUPSRate = upsRatesArray.filter(Boolean).length ? Math.min(...upsRatesArray.filter(Boolean)) : 0;
                            //let bestUPSRate = Math.min.apply(null, upsRatesArray.filter(Boolean));
                            let j = upsRatesArray.indexOf(bestUPSRate);
                            let upsBestAccount = upsAccountArray[j];
                            let fedexRatesArray =[rate6,rate7];
                            let fedExAccountArray = ["FEDEX182790583","FEDEX572540600"];
                            let bestFedExRate = fedexRatesArray.filter(Boolean).length ? Math.min(...fedexRatesArray.filter(Boolean)) : 0;
                            //let bestFedExRate = Math.min.apply(null, fedexRatesArray.filter(Boolean));
                            let k = fedexRatesArray.indexOf(bestFedExRate);
                            let fedExBestAccount = fedExAccountArray[k];

                            record.submitFields({
                                type: record.Type.SALES_ORDER,
                                id: soID,
                                values: {
                                    custbodypackweight: soObj.itemWeight,
                                    custbodypacklength: soObj.itemLen,
                                    custbodypackwidth: soObj.itemWidth,
                                    custbodypackheight: soObj.itemHigh,
                                    custbody_jj_dimensions_error: "",
                                    custbodyupsrate1: rate1,
                                    custbodyupsrate6: rate2,
                                    custbodyupsrate7: rate3,
                                    custbodyupsrate5: rate4,
                                    custbodyupsrate8: rate5,
                                    custbodyfedexrate1: rate6,
                                    custbodyfedexrate2: rate7,
                                    custbodybestrate1: bestRate,
                                    custbodybestrate2: bestAccount,
                                    custbodybestrateups: upsBestAccount,
                                    custbodybestratefedex: fedExBestAccount,
                                    shippingcost: bestRate,
                                },
                                options: {
                                    ignoreMandatoryFields : true
                                }
                            });
                        } else {
                            record.submitFields({
                                type: record.Type.SALES_ORDER,
                                id: soID,
                                values: {custbody_jj_dimensions_error: "Actual Shipment weight field has null value"},
                                options: {ignoreMandatoryFields : true}
                            });
                        }
                    } else {
                        record.submitFields({
                            type: record.Type.SALES_ORDER,
                            id: soID,
                            values: {custbody_jj_dimensions_error: "Item package field has invalid value"},
                            options: {ignoreMandatoryFields : true}
                        });
                    }
                }
            }catch (e) {
                log.error({title:'error@afterSubmit',details:e});
            }
        }

        /**
         *
         * @param soID
         * @returns {{}}
         */
        function salesOrderSearch(soID) {
            try {
                let salesOrderSearchObj = search.create({
                    type: "salesorder",
                    filters:
                        [
                            ["type","anyof","SalesOrd"], "AND",
                            ["internalid","anyof",soID], "AND",
                            ["taxline","is","F"], "AND",
                            ["cogs","is","F"], "AND",
                            ["shipping","is","F"]
                        ],
                    columns:
                        [
                            search.createColumn({name: "internalid", label: "Internal ID"}),
                            search.createColumn({name: "statusref", label: "Status"}),
                            search.createColumn({name: "shipcountrycode", label: "Shipping Country Code"}),
                            search.createColumn({name: "shipzip", label: "Shipping Zip"}),
                            search.createColumn({name: "shipstate", label: "Shipping State/Province"}),
                            search.createColumn({name: "shipcity", label: "Shipping City"}),
                            search.createColumn({name: "shipaddress2", label: "Shipping Address 2"}),
                            search.createColumn({name: "shipaddress1", label: "Shipping Address 1"}),
                            search.createColumn({name: "shipaddressee", label: "Shipping Addressee"}),
                            search.createColumn({name: "shippingattention", label: "Shipping Attention"}),
                            search.createColumn({name: "custbodyitemqty", label: "Item Qty"}),
                            search.createColumn({name: "custbodyorderitempackage", label: "Item Package"}),
                            search.createColumn({name: "location", label: "Location"}),
                            search.createColumn({name: "type", join: "item", label: "Type"}),
                            search.createColumn({name: "custcolbillweightline", label: "Billable weight item"}),
                            search.createColumn({name: "custcol_individual_weight", label: "Unit Weight"})
                        ]
                });

                let status,shipCountry,shipZip,shipState,shipCity,shippingAdd2,shippingAdd1,shippingAddressee,shippingAttention,itemTotalQty,itemPackage,location,itemLineBillWeight,itemLineWeight;
                salesOrderSearchObj.run().each(function(result){
                     status = result.getText(result.columns[1]);
                     shipCountry = result.getValue(result.columns[2]);
                     shipZip = result.getValue(result.columns[3]);
                     shipState = result.getValue(result.columns[4]);
                     shipCity = result.getValue(result.columns[5]);
                     shippingAdd2 = result.getValue(result.columns[6]);
                     shippingAdd1 = result.getValue(result.columns[7]);
                     shippingAddressee = result.getValue(result.columns[8]);
                     shippingAttention = result.getValue(result.columns[9]);
                     itemTotalQty = parseInt(result.getValue(result.columns[10]));
                     itemPackage = result.getValue(result.columns[11]).toString();
                    if (!checkForParameter(location)) {
                         location = result.getValue(result.columns[12]);
                    }
                    let itemType = result.getValue(result.columns[13]);
                    if ( itemType === 'InvtPart' && !checkForParameter(itemLineBillWeight) && !checkForParameter(itemLineWeight)) {
                        itemLineBillWeight = result.getValue(result.columns[14]);
                        itemLineWeight = result.getValue(result.columns[15]);
                    }
                    return true;
                });
                let actualShipWeight;
                let transactionBillWeight = itemTotalQty * parseFloat(itemLineBillWeight);
                if (transactionBillWeight >= 0.1){
                    actualShipWeight = (itemTotalQty * itemLineWeight).toFixed(2);
                }
                let itemLen, itemWidth, itemHigh;
                if(checkForParameter(itemPackage)) {
                    let itemPackageArr1 = itemPackage.split('(');
                    itemPackageArr1 = itemPackageArr1[1].split(')');
                    itemPackageArr1 = itemPackageArr1[0].split('x');
                    itemLen = itemPackageArr1[0];
                    itemWidth = itemPackageArr1[1];
                    itemHigh = itemPackageArr1[2];
                } else {
                    record.submitFields({
                        type: record.Type.SALES_ORDER,
                        id: soID,
                        values: {custbody_jj_dimensions_error: "Item package field has null value"},
                        options: {ignoreMandatoryFields : true}
                    });
                }
                let fieldLookUp = search.lookupFields({
                    type: "location",
                    id: location,
                    columns: ['address.address1','address.address2','address.attention','address.city','address.state','address.zip','address.countrycode']
                });
                let locCountry =fieldLookUp['address.countrycode'];
                let locZip =fieldLookUp['address.zip'];
                let locState =fieldLookUp['address.state'];
                let locCity =fieldLookUp['address.city'];
                let locAttention =fieldLookUp['address.attention'];
                let locAdd1 =fieldLookUp['address.address1'];
                let locAdd2 =fieldLookUp['address.address2'];

                let soObj = {}
                soObj.status =status;
                soObj.shipCountry =shipCountry;
                soObj.shipZip =shipZip;
                soObj.shipState =shipState;
                soObj.shipCity =shipCity;
                soObj.shippingAdd2 =shippingAdd2;
                soObj.shippingAdd1 =shippingAdd1;
                soObj.shippingAddressee =shippingAddressee;
                soObj.itemTotalQty =itemTotalQty;
                soObj.itemPackage =itemPackage;
                //soObj.actualShipWeight =actualShipWeight;
                soObj.itemLen = itemLen;
                soObj.itemWidth = itemWidth;
                soObj.itemHigh = itemHigh;
                soObj.itemWeight = actualShipWeight;
                soObj.location =location;
                soObj.locCountry =locCountry;
                soObj.locZip =locZip;
                soObj.locState =locState;
                soObj.locCity =locCity;
                soObj.locAttention =locAttention;
                soObj.locAdd1 =locAdd1;
                soObj.locAdd2 =locAdd2;
                return soObj;
            } catch (e) {
                log.error({title:'error@salesOrderSearch',details:e});
            }
        }

        /**
         * The function is fetching the shipping rate from the 654E80 UPS account.
         * @param soObj
         * @returns {number}
         */
        function fetchingRateUPS654E80(soObj) {
            try {
                let accessToken;
                let accountNo = "654E80";
                let customRecordID = 1; // 1 is internal id of the custom record UPS654E80
                let authorization ='Q2xoRk1WV2NKMWxsS5dnlEtIakNvRE9JYnU='
                let bodyObj = requestUPSBodyData(soObj,accountNo);

                //Getting access Token from the Custom record
                let fieldLookUp = search.lookupFields({
                    type:"customrecord_jj_ups_integration_details",
                    id: customRecordID,
                    columns: ['custrecord_jj_ups_access_token']
                });

                if (fieldLookUp.custrecord_jj_ups_access_token.length > 0) {
                    accessToken = fieldLookUp.custrecord_jj_ups_access_token;
                }
                return upsShippingRateRequest(accessToken,bodyObj,customRecordID,authorization);
            } catch (e) {
                log.error({title:'error@fetchingRateUPS654E80',details:e});
            }
        }

        /**
         * The function is fetching the shipping rate from the 98722Y UPS account.
         * @param soObj
         * @returns {number}
         */
        function fetchingRateUPS98722Y(soObj) {
            try {
                let accessToken;
                let accountNo = "98722Y";
                let customRecordID = 2; // 2 is internal id of the custom record UPS98722Y
                let authorization ='RWR4YlJQQTllT2xtOFRnUkhVT2sNDhRTk1uZnY='
                let bodyObj = requestUPSBodyData(soObj,accountNo);

                //Getting access Token from the Custom record
                let fieldLookUp = search.lookupFields({
                    type:"customrecord_jj_ups_integration_details",
                    id: customRecordID,
                    columns: ['custrecord_jj_ups_access_token']
                });

                if (fieldLookUp.custrecord_jj_ups_access_token.length > 0) {
                    accessToken = fieldLookUp.custrecord_jj_ups_access_token;
                }
                return upsShippingRateRequest(accessToken,bodyObj,customRecordID,authorization);
            } catch (e) {
                log.error({title:'error@fetchingRateUPS98722Y',details:e});
            }
        }

        /**
         * The function is fetching the shipping rate from the 98723A UPS account.
         * @param soObj
         * @returns {number}
         */
        function fetchingRateUPS98723A(soObj) {
            try {
                let accessToken;
                let accountNo = "98723A";
                let customRecordID = 3; // 3 is internal id of the custom record UPS98722Y
                let authorization ='a09JeWtqSFNieW5oMkcySzhKT1lsOUhSnpUWkI='
                let bodyObj = requestUPSBodyData(soObj,accountNo);

                //Getting access Token from the Custom record
                let fieldLookUp = search.lookupFields({
                    type:"customrecord_jj_ups_integration_details",
                    id: customRecordID,
                    columns: ['custrecord_jj_ups_access_token']
                });

                if (fieldLookUp.custrecord_jj_ups_access_token.length > 0) {
                    accessToken = fieldLookUp.custrecord_jj_ups_access_token;
                }
                return upsShippingRateRequest(accessToken,bodyObj,customRecordID,authorization);
            } catch (e) {
                log.error({title:'error@fetchingRateUPS98723A',details:e});
            }
        }

        /**
         * The function is fetching the shipping rate from the 16050X UPS account.
         * @param soObj
         * @returns {number}
         */
        function fetchingRateUPS16050X(soObj) {
            try {
                let accessToken;
                let accountNo = "16050X";
                let customRecordID = 4; // 4 is internal id of the custom record UPS98722Y
                let authorization ='QUFEaDVPTnhJbFh0WmRU1alRM'
                let bodyObj = requestUPSBodyData(soObj,accountNo);

                //Getting access Token from the Custom record
                let fieldLookUp = search.lookupFields({
                    type:"customrecord_jj_ups_integration_details",
                    id: customRecordID,
                    columns: ['custrecord_jj_ups_access_token']
                });

                if (fieldLookUp.custrecord_jj_ups_access_token.length > 0) {
                    accessToken = fieldLookUp.custrecord_jj_ups_access_token;
                }
                return upsShippingRateRequest(accessToken,bodyObj,customRecordID,authorization);
            } catch (e) {
                log.error({title:'error@fetchingRateUPS16050X',details:e});
            }
        }

        /**
         * The function is fetching the shipping rate from the 09F185 UPS account.
         * @param soObj
         * @returns {number}
         */
        function fetchingRateUPS09F185(soObj) {
            try {
                let accessToken;
                let accountNo = "09F185";
                let customRecordID = 6; // 6 is internal id of the custom record UPS09F185
                let authorization ='OEs3c1NzU0k5MFBSSVlXbThHeTFJB'
                let bodyObj = requestUPSBodyData(soObj,accountNo);
                //Getting access Token from the Custom record
                let fieldLookUp = search.lookupFields({
                    type:"customrecord_jj_ups_integration_details",
                    id: customRecordID,
                    columns: ['custrecord_jj_ups_access_token']
                });

                if (fieldLookUp.custrecord_jj_ups_access_token.length > 0) {
                    accessToken = fieldLookUp.custrecord_jj_ups_access_token;
                }
                return upsShippingRateRequest(accessToken,bodyObj,customRecordID,authorization);
            } catch (e) {
                log.error({title:'error@fetchingRateUPS09F185',details:e});
            }
        }

      
        function requestUPSBodyData(soObj,accountNo) {
            try {
                let bodyObj = {
                    "RateRequest": {
                        "Request": {
                            "TransactionReference": {
                                "CustomerContext": "CustomerContext",
                                "TransactionIdentifier": "TransactionIdentifier"
                            }
                        },
                        "Shipment": {
                            "Shipper": {
                                "Name": soObj.locAttention,
                                "ShipperNumber": accountNo,
                                "Address": {
                                    "AddressLine": [
                                        soObj.locAttention,
                                        soObj.locAdd1,
                                        soObj.locAdd2
                                    ],
                                    "City": soObj.locCity,
                                    "StateProvinceCode": soObj.locState,
                                    "PostalCode": soObj.locZip,
                                    "CountryCode":soObj.locCountry
                                }
                            },
                            "ShipTo": {
                                "Name": soObj.shippingAddressee,
                                "Address": {
                                    "AddressLine": [
                                        soObj.shippingAddressee,
                                        soObj.shippingAdd1,
                                        soObj.shippingAdd2
                                    ],
                                    "City": soObj.shipCity,
                                    "StateProvinceCode": soObj.shipState,
                                    "PostalCode": soObj.shipZip,
                                    "CountryCode": soObj.shipCountry
                                }
                            },
                            "ShipFrom": {
                                "Name": soObj.locAttention,
                                "Address": {
                                    "AddressLine": [
                                        soObj.locAttention,
                                        soObj.locAdd1,
                                        soObj.locAdd2
                                    ],
                                    "City": soObj.locCity,
                                    "StateProvinceCode": soObj.locState,
                                    "PostalCode": soObj.locZip,
                                    "CountryCode":soObj.locCountry
                                }
                            },
                            "ShipmentRatingOptions": {
                                "TPFCNegotiatedRatesIndicator": "Y",
                                "NegotiatedRatesIndicator": "Y"
                            },
                            "Service": {
                                "Code": "03",
                                "Description": "UPS Worldwide Economy DDU"
                            },
                            "NumOfPieces": "1",
                            "Package": {
                                "PackagingType": {
                                    "Code": "02",
                                    "Description": "Packaging"
                                },
                                "Dimensions": {
                                    "UnitOfMeasurement": {
                                        "Code": "IN",
                                        "Description": "Inches"
                                    },
                                    "Length": soObj.itemLen.toString(),
                                    "Width":soObj.itemWidth.toString(),
                                    "Height": soObj.itemHigh.toString()
                                },
                                "PackageWeight": {
                                    "UnitOfMeasurement": {
                                        "Code": "LBS",
                                        "Description": "Pounds"
                                    },
                                    "Weight": soObj.itemWeight.toString()
                                }
                            }
                        }
                    }
                }
                return bodyObj;
            } catch (e) {
                log.error({title:'error@requestUPSBodyData',details:e});
            }
        }

    
        function upsShippingRateRequest(accessToken,bodyObj,customRecordID,authorization) {
            try{
                let rate = 0
                let headerObj = {
                    Authorization: 'Bearer '+accessToken,
                    'Content-Type': 'application/raw'
                };
                let response = https.post({
                    url: 'https://onlinetools.ups.com/api/rating/v1/Rate',
                    headers: headerObj,
                    body: JSON.stringify(bodyObj)
                });
                //log.debug(({title:'responseRate',details:response}));
                if(response.code === 200 ) { //200 is Request success
                    let responseBody = JSON.parse(response.body);
                    let NegotiatedRateCharges = responseBody.RateResponse.RatedShipment.NegotiatedRateCharges;
                    if (checkForParameter(NegotiatedRateCharges)){
                        rate = NegotiatedRateCharges.TotalCharge.MonetaryValue;
                    } else {
                        rate = responseBody.RateResponse.RatedShipment.TotalCharges.MonetaryValue;
                    }

                } else if (response.code === 401 ) {   // 401 is Request is Unauthorized. We need to renew the access token.

                    let accessHeader = {
                        Authorization: 'Basic '+authorization,
                        'Content-Type': 'application/x-www-form-urlencoded'
                    };
                    let accessBody = {
                        'grant_type': 'client_credentials',
                    }
                    let responseAccessToken = https.post({
                        url: 'https://onlinetools.ups.com/security/v1/oauth/token',
                        headers: accessHeader,
                        body: accessBody
                    });
                    let responseAccessBody = JSON.parse(responseAccessToken.body);
                    if(responseAccessToken.code === 200 ) {
                        accessToken = responseAccessBody.access_token;
                        let headerObj = {
                            Authorization: 'Bearer '+accessToken,
                            'Content-Type': 'application/raw'
                        };
                        let response = https.post({
                            url: 'https://onlinetools.ups.com/api/rating/v1/Rate',
                            headers: headerObj,
                            body: JSON.stringify(bodyObj)
                        });
                        //log.debug(({title:'responseRate',details:response}));
                        if(response.code === 200 ) {
                            let responseBody = JSON.parse(response.body);
                            let NegotiatedRateCharges = responseBody.RateResponse.RatedShipment.NegotiatedRateCharges;
                            if (checkForParameter(NegotiatedRateCharges)){
                                rate = NegotiatedRateCharges.TotalCharge.MonetaryValue;
                            } else {
                                rate = responseBody.RateResponse.RatedShipment.TotalCharges.MonetaryValue;
                            }
                        }
                        // Set new access token value to custom record
                        record.submitFields({
                            type:"customrecord_jj_ups_integration_details",
                            id:customRecordID,
                            values:{
                                custrecord_jj_ups_access_token:accessToken.toString(),
                            }
                        });
                    }
                }
                return parseFloat(rate);
            }
            catch (e) {
                log.error({title:'error@upsShippingRateRequest',details:e});
            }
        }

        
        function fetchingRateFEDEX182790583(soObj) {
            try {
                let accountNo = "182790583";
                let bodyObj = requestFEDEXBodyData(soObj,accountNo);
                return fedExShippingRateRequest(bodyObj,soObj);
            } catch (e) {
                log.error({title:'error@fetchingRateFEDEX182790583',details:e});
            }
        }

        
        function fetchingRateFEDEX572540600(soObj) {
            try {
                let accountNo = "572540600";
                let bodyObj = requestFEDEXBodyData(soObj,accountNo);
                return fedExShippingRateRequest(bodyObj,soObj);
            } catch (e) {
                log.error({title:'error@fetchingRateFEDEX572540600',details:e});
            }
        }

       
        function requestFEDEXBodyData(soObj,accountNo) {
            try {
                let bodyObj = {
                    "accountNumber": {
                        "value": accountNo
                    },
                    "requestedShipment": {
                        "shipper": {
                            "address": {
                                "streetLines": [
                                    soObj.locAttention,
                                    soObj.locAdd1,
                                ],
                                "city": soObj.locCity,
                                "stateOrProvinceCode": soObj.locState,
                                "postalCode": soObj.locZip,
                                "countryCode": soObj.locCountry,
                                "residential": false
                            }
                        },
                        "recipient": {
                            "address": {
                                "streetLines": [
                                    soObj.shippingAddressee,
                                    soObj.shippingAdd1,
                                ],
                                "city": soObj.shipCity,
                                "stateOrProvinceCode": soObj.shipState,
                                "postalCode":  soObj.shipZip,
                                "countryCode": soObj.shipCountry,
                                "residential": true
                            }
                        },
                        "pickupType": "USE_SCHEDULED_PICKUP",
                        "rateRequestType": [
                            "ACCOUNT"
                        ],
                        "requestedPackageLineItems": [
                            {
                                "weight": {
                                    "units": "LB",
                                    "value": parseFloat(soObj.itemWeight)
                                },
                                "dimensions": {
                                    "length": parseFloat(soObj.itemLen),
                                    "width": parseFloat(soObj.itemWidth),
                                    "height": parseFloat(soObj.itemHigh),
                                    "units": "IN"
                                }
                            }
                        ]
                    }
                }
                //log.debug({title:'bodyObj',details:bodyObj});
                return bodyObj;
            } catch (e) {
                log.error({title:'error@requestFEDEXBodyData',details:e});
            }
        }

      
        function fedExShippingRateRequest(bodyObj,soObj) {
            try{
                let rate = 0
                let accessToken,clientID,clientSecret;
                let customRecordID = 5; // 5 is internal id of the custom record FEDEX 182790583 & 572540600
                //Getting access Token from the Custom record
                let fieldLookUp = search.lookupFields({
                    type:"customrecord_jj_ups_integration_details",
                    id: customRecordID,
                    columns: ['custrecord_jj_ups_access_token','custrecord_jj_ups_client_id','custrecord_jj_ups_client_secret']
                });
                if (fieldLookUp.custrecord_jj_ups_access_token.length > 0) {
                    accessToken = fieldLookUp.custrecord_jj_ups_access_token;
                }
                let headerObj = {
                    "Authorization": 'Bearer '+accessToken,
                    "Content-Type": "application/json",
                    "Accept" : "*/*"
                };
                let response = https.post({
                    url: 'https://apis.fedex.com/rate/v1/rates/quotes',
                    headers: headerObj,
                    body: JSON.stringify(bodyObj)
                });
                //log.debug({title:'responseRate',details:response});
                if(response.code === 200) { //200 is Request success
                    let responseBody = JSON.parse(response.body);
                    let rateReplyDetails = responseBody.output.rateReplyDetails;
                    for (let i=0 ; i< rateReplyDetails.length; i++){
                        let serviceType = rateReplyDetails[i].serviceType
                        if(serviceType === "GROUND_HOME_DELIVERY"){
                            rate = rateReplyDetails[i].ratedShipmentDetails[0].totalNetFedExCharge;
                            break;
                        }
                    }
                    if (rate === 0 && soObj.countryCode !== "US"){
                        for (let i=0 ; i< rateReplyDetails.length; i++){
                            let serviceType = rateReplyDetails[i].serviceType
                            if (serviceType === "INTERNATIONAL_ECONOMY"){
                                rate = rateReplyDetails[i].ratedShipmentDetails[0].totalNetFedExCharge;
                                break;
                            }
                        }
                    }
                } else if (response.code === 401) {   // 401 is Request is Unauthorized. We need to renew the access token.

                    if (fieldLookUp.custrecord_jj_ups_client_id.length > 0) {
                        clientID = fieldLookUp.custrecord_jj_ups_client_id;
                    }
                    if (fieldLookUp.custrecord_jj_ups_client_secret.length > 0) {
                        clientSecret = fieldLookUp.custrecord_jj_ups_client_secret;
                    }
                    let accessHeader = {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    };
                    let accessBody = {
                        'grant_type': 'client_credentials',
                        'client_id': clientID,
                        'client_secret' : clientSecret
                    }
                    let responseAccessToken = https.post({
                        url: 'https://apis.fedex.com/oauth/token',
                        headers: accessHeader,
                        body: accessBody
                    });
                    //log.debug({title:'responseAccessToken',details:responseAccessToken});
                    let responseAccessBody = JSON.parse(responseAccessToken.body);
                    if(responseAccessToken.code === 200) {
                        accessToken = responseAccessBody.access_token;
                        let headerObj = {
                            "Authorization": 'Bearer '+accessToken,
                            "Content-Type": "application/json",
                            "Accept" : "*/*"
                        };
                        let response = https.post({
                            url: 'https://apis.fedex.com/rate/v1/rates/quotes',
                            headers: headerObj,
                            body: JSON.stringify(bodyObj)
                        });
                        //log.debug({title:'responseRate',details:response});
                        if(response.code === 200) {
                            let responseBody = JSON.parse(response.body);
                            let rateReplyDetails = responseBody.output.rateReplyDetails;
                            for (let i=0 ; i< rateReplyDetails.length; i++){
                                let serviceType = rateReplyDetails[i].serviceType
                                if(serviceType === "GROUND_HOME_DELIVERY"){
                                    rate = rateReplyDetails[i].ratedShipmentDetails[0].totalNetFedExCharge;
                                    break;
                                }
                            }
                            if (rate === 0 && soObj.countryCode !== "US"){
                                for (let i=0 ; i< rateReplyDetails.length; i++){
                                    let serviceType = rateReplyDetails[i].serviceType
                                    if (serviceType === "INTERNATIONAL_ECONOMY"){
                                        rate = rateReplyDetails[i].ratedShipmentDetails[0].totalNetFedExCharge;
                                        break;
                                    }
                                }
                            }
                        }
                        // Set new access token value to custom record
                        record.submitFields({
                            type:"customrecord_jj_ups_integration_details",
                            id:customRecordID,
                            values:{
                                custrecord_jj_ups_access_token:accessToken.toString(),
                            }
                        });
                    }
                }
                return parseFloat(rate);
            }
            catch (e) {
                log.error({title:'error@fedExShippingRateRequest',details:e});
            }
        }

     
        function checkForParameter(parameter) {
            if (parameter !== "" && parameter !== null && parameter !== undefined && parameter !== false && parameter !== "null" && parameter !== "undefined" && parameter !== " " && parameter !== 'false') {
                return true;
            } else {
                return false;
            }
        }
        
        return {beforeLoad,afterSubmit}
    });

Leave a comment

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