Script to Remove Landed Cost in Item Receipt

The changes in the IR will reflect on G/L Impact, Balance Sheet, and related Item Fulfillment records.

The script is powered by a saved search in UI which enlists the item receipts.

/**
 * @NApiVersion 2.1
 * @NScriptType MapReduceScript
 * @NModuleScope SameAccount 
 */

define(['N/record', 'N/search', 'N/file', 'N/format', 'N/email'],
    /**
    * @param{record} record
    * @param{search} search
    * @param{file} file
    * @param{format} format
    * @param{email} email    
    */
    (record, search, file, format, email) => {
        const SEARCH_ID = "customsearch_jj_ir_clear_lc_tgus556";

        /**
         * Defines the function that is executed at the beginning of the map/reduce process and generates the input data.
         * @param {Object} inputContext
         * @param {boolean} inputContext.isRestarted - Indicates whether the current invocation of this function is the first
         *     invocation (if true, the current invocation is not the first invocation and this function has been restarted)
         * @param {Object} inputContext.ObjectRef - Object that references the input data
         * @typedef {Object} ObjectRef
         * @property {string|number} ObjectRef.id - Internal ID of the record instance that contains the input data
         * @property {string} ObjectRef.type - Type of the record instance that contains the input data
         * @returns {Array|Object|Search|ObjectRef|File|Query} The input data to use in the map/reduce process
         * @since 2015.2
         */
        const getInputData = (inputContext) => {
            try {
                let irArrayObj = searchItemReciptsIds()

                log.debug('Get Input Data - irArrayObj', irArrayObj);
                return irArrayObj;

            } catch (Err) {
                log.debug('error@getInputData', Err);
                log.error('error@getInputData', Err);
            }
        }

        /**
         * Defines the function that is executed when the reduce entry point is triggered. This entry point is triggered
         * automatically when the associated map stage is complete. This function is applied to each group in the provided context.
         * @param {Object} reduceContext - Data collection containing the groups to process in the reduce stage. This parameter is
         *     provided automatically based on the results of the map stage.
         * @param {Iterator} reduceContext.errors - Serialized errors that were thrown during previous attempts to execute the
         *     reduce function on the current group
         * @param {number} reduceContext.executionNo - Number of times the reduce function has been executed on the current group
         * @param {boolean} reduceContext.isRestarted - Indicates whether the current invocation of this function is the first
         *     invocation (if true, the current invocation is not the first invocation and this function has been restarted)
         * @param {string} reduceContext.key - Key to be processed during the reduce stage
         * @param {List<String>} reduceContext.values - All values associated with a unique key that was passed to the reduce stage
         *     for processing
         * @since 2015.2
         */
        const reduce = (reduceContext) => {
            try {
                log.debug("reduceContext", reduceContext)

                let irRecValue = JSON.parse(reduceContext.values);

                if (!isEmpty(irRecValue)) {
                    let irRecordId = irRecValue.irRecId
                    log.debug("irRecordId", irRecordId);

                    if (!isEmpty(irRecordId)) {
                        clearLandedCostforItemReceipts(irRecordId)
                    }
                }

            } catch (Err) {
                log.debug('error@reduce', Err);
                log.error('error@reduce', Err);
            }
        }

        /**
         * Defines the function that is executed when the summarize entry point is triggered. This entry point is triggered
         * automatically when the associated reduce stage is complete. This function is applied to the entire result set.
         * @param {Object} summaryContext - Statistics about the execution of a map/reduce script
         * @param {number} summaryContext.concurrency - Maximum concurrency number when executing parallel tasks for the map/reduce
         *     script
         * @param {Date} summaryContext.dateCreated - The date and time when the map/reduce script began running
         * @param {boolean} summaryContext.isRestarted - Indicates whether the current invocation of this function is the first
         *     invocation (if true, the current invocation is not the first invocation and this function has been restarted)
         * @param {Iterator} summaryContext.output - Serialized keys and values that were saved as output during the reduce stage
         * @param {number} summaryContext.seconds - Total seconds elapsed when running the map/reduce script
         * @param {number} summaryContext.usage - Total number of governance usage units consumed when running the map/reduce
         *     script
         * @param {number} summaryContext.yields - Total number of yields when running the map/reduce script
         * @param {Object} summaryContext.inputSummary - Statistics about the input stage
         * @param {Object} summaryContext.mapSummary - Statistics about the map stage
         * @param {Object} summaryContext.reduceSummary - Statistics about the reduce stage
         * @since 2015.2
         */
        const summarize = (summaryContext) => {
            // Summarize added to find the Map/Reduce script excution end time.
        }


        /**
        * Description - Perform Item Receipts Search for Clearing Landed Cost
        * @returns irRecordsArray: Array
        */
        function searchItemReciptsIds() {
            try {
                let itemReceiptSearchObj = search.load({ id: SEARCH_ID }); // SEARCH NAME: Item Receipts Search for Clearing Landed Cost JJ TGUS-556

                //Declare variables
                let irPageRanges, irRecId
                let irRecordsArray = [];
                try {
                    irPageRanges = itemReceiptSearchObj.runPaged({
                        pageSize: 1000
                    });
                } catch (err) {
                    return [];
                }
                if (irPageRanges.pageRanges.length < 1)
                    return [];
                let pageRangeLength = irPageRanges.pageRanges.length;
                for (let pageIndex = 0; pageIndex < pageRangeLength; pageIndex++)
                    irPageRanges.fetch({
                        index: pageIndex
                    }).data.forEach(function (result) {
                        irRecId = result.getValue(result.columns[0]);

                        let itemRecordsObj = {};
                        itemRecordsObj.irRecId = irRecId

                        irRecordsArray.push(itemRecordsObj);
                        return true;
                    });
                log.debug("irRecordsArray", irRecordsArray);

                return irRecordsArray;
            }
            catch (err) {
                log.debug("err@searchMerchGroup", err)
                return [];
            }
        }

        /**
         * Description - Clear landed cost values configured in line level of ir record
         * @param {integer} irRecId - internal id of the ir record
         */
        function clearLandedCostforItemReceipts(irRecId) {
            try {

                if (irRecId ) {
                    let irRecObj = record.load({
                        type: record.Type.ITEM_RECEIPT,
                        id: irRecId,
                        isDynamic: true,
                    });

                    let irLineCount = irRecObj.getLineCount({ sublistId: 'item' });
                    log.debug("irLineCount", irLineCount);

                    for (let index = 0; index < irLineCount; index++) {

                        irRecObj.selectLine({
                            sublistId: 'item',
                            line: index
                        });
                        irRecObj.removeCurrentSublistSubrecord({
                            sublistId: 'item',
                            fieldId: 'landedcost'
                        });
                        irRecObj.commitLine({
                            sublistId: 'item'
                        });
                    }
                    let recordId = irRecObj.save({
                        enableSourcing: true,
                        ignoreMandatoryFields: true
                    });
                    log.debug("recordId", recordId)
                }

            } catch (Err) {
                log.debug("Err@clearLandedCostforItemReceipts", Err)
                log.error("Err@clearLandedCostforItemReceipts", Err)
            }

        }

        function isEmpty(value) {
            let isEmptyObject = function (a) {
                if (typeof a.length === 'undefined') { // it's an Object, not an Array
                    let hasNonempty = Object.keys(a).some(function nonEmpty(element) {
                        return !isEmpty(a[element]);
                    });
                    return hasNonempty ? false : isEmptyObject(Object.keys(a));
                }
                return !a.some(function nonEmpty(element) { // check if array is really not empty as JS thinks
                    return !isEmpty(element); // at least one element should be non-empty
                });
            };
            return (
                value == false
                || typeof value === 'undefined'
                || value == null
                || (typeof value === 'object' && isEmptyObject(value))
            );
        }


        return { getInputData, reduce, summarize }
    });

Leave a comment

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