MASS DELETE ALL RCORD FROM SAVED SEARCH DATA IN PARAMETER|| ADD SS IN THE DEPLOYMENT PARAMETER

PHOTO EMBED

Mon Jul 31 2023 06:12:00 GMT+0000 (Coordinated Universal Time)

Saved by @mdfaizi

/**
 * @NApiVersion 2.x
 * @NScriptType MapReduceScript
 * @NModuleScope public
 */

/******************************************************************************************
 * Copyright (c) 2014-2018 Techfino, LLC
 * 2020 Federal Street, Philadelphia, PA 19146, USA
 * All Rights Reserved.
 *
 * This software is the confidential and proprietary information of Techfino LLC.  
 * ("Confidential Information") - You shall not disclose such Confidential Information 
 * without prior written permission.
 *
 * Script Description: 
 *  This script deletes records based off of Saved Search inputs
 ******************************************************************************************/

define(['N/search', 'N/record', 'N/task', 'N/runtime', 'N/file', './TF_LIB_MassDeletionScript2.0'],
    function(search, record, task, runtime, file, Dlib) {
        const MAX_PAGE_SIZE = 1000;


        return {
            /**
             * Obtains the saved search used and metes out page ranges to the map stage to concurrently search. Less straight forward but
             * prevents timeout for larger searches
             */
            getInputData: function() {

                try {

                    log.audit({ title: 'START', details: '<--------------------------------START-------------------------------->' });

                    var currentScript = runtime.getCurrentScript();
                    var savedSearchId = currentScript.getParameter('custscript_tf_saved_search');
                    var input = [];

                    if (savedSearchId) {
                        var searchObj = search.load({
                            id: savedSearchId
                        });

                        searchObj = Dlib.defect474626Fix(searchObj);
                        searchObj = searchObj.runPaged({
                            pageSize: MAX_PAGE_SIZE
                        });

                        var pageCount = searchObj.pageRanges.length;
                        for (var pageIndex = 0; pageIndex < pageCount; pageIndex++) {
                            input.push({ searchId: savedSearchId, pageIndex: pageIndex });
                        }

                        log.audit({ title: '# Records to be deleted', details: searchObj.count });
                    }

                    return input;

                } catch (errorObj) {
                    log.error({ title: '(getInputData) Search Distribution Error', details: Dlib.getErrorDetails(errorObj) });
                }

            },

            /**
             * Searches for a page range of the search specified in the GetInputStage and distributes to reduce for deletion
             * @param  {[type]} context [description]
             * @return {[type]}         [description]
             */
            map: function(context) {
                try {
                    var CHUNKS_PER_SEARCH;
                    var mapValue = JSON.parse(context.value);

                    var searchLoadObj = search.load({
                        id: mapValue.searchId
                    });

                    searchObj = searchLoadObj.run();

                    /* 
                     * Governance for record types limits the number of records that can be deleted per queue. For simplicity either divide
                     * into chunks of 100 or 10 depending on if its a custom record or not 
                     */
                    if (searchLoadObj.searchType.indexOf('custrecord') !== -1) { // custom record
                        CHUNKS_PER_SEARCH = 10;
                    } else {
                        CHUNKS_PER_SEARCH = 100;
                    }

                    var start = (Number(mapValue.pageIndex) * MAX_PAGE_SIZE);
                    var end = start + 1000;

                    var deletePage = searchObj.getRange({
                        start: start,
                        end: end
                    });

                    for (var dIndex = 0; dIndex < deletePage.length; dIndex++) {
                        context.write({
                            key: mapValue.pageIndex + '-' + (dIndex % CHUNKS_PER_SEARCH),
                            value: { recordId: deletePage[dIndex].id, recordType: deletePage[dIndex].recordType }
                        });
                    }

                } catch (errorObj) {
                    log.error({ title: '(Map) Search Distribution Error', details: Dlib.getErrorDetails(errorObj) });
                    throw errorObj;
                }
            },

            /**
             * Deletes records found in the map stage. Records any errors
             */
            reduce: function(context) {
                try {

                    var recordsToDelete = context.values;
                    var errorArray = [];
                    for (var dIndex = 0; dIndex < recordsToDelete.length; dIndex++) {
                        var recordToDelete = JSON.parse(recordsToDelete[dIndex]);
                        var recordType = recordToDelete.recordType;
                        var recordId = recordToDelete.recordId;

                        try {
                            if (recordType !== 'file') {
                                record.delete({ type: recordType, id: recordId });
                            } else {
                                file.delete({
                                    id: recordId
                                });
                            }
                        } catch (errorObj) {
                            errorArray.push('(Reduce) Deletion Error for ' + recordType + ' ' + recordId + ': ' + Dlib.getErrorDetails(errorObj));
                        }

                    }

                    if (errorArray.length > 0) {
                        throw errorArray.join(',');
                    }

                } catch (errorObj) {
                    log.error({ title: '(Reduce) Deletion Error', details: Dlib.getErrorDetails(errorObj) });
                    throw errorObj;
                }
            },

            /**
             * Details summary information
             */
            summarize: function(summary) {
                try {

                    var scriptErrors = [];
                    log.audit({ title: 'summary', details: JSON.stringify(summary.inputSummary) });
                    if (summary.inputSummary.error !== null) {
                        scriptErrors.push(JSON.stringify(JSON.parse(summary.inputSummary.error).cause));
                    }

                    summary.mapSummary.errors.iterator().each(function(key, value) {
                        scriptErrors.push(JSON.stringify(JSON.parse(value).cause));
                        return true;
                    });

                    summary.reduceSummary.errors.iterator().each(function(key, value) {
                        scriptErrors.push(JSON.stringify(JSON.parse(value).cause));
                        return true;
                    });

                    if (scriptErrors.length > 0) {
                        log.error({ title: scriptErrors.length + ' error(s) occured during script execution', details: scriptErrors.join('\n') });
                    } else {
                        log.audit({ title: 'summary', details: 'Script finished execution without errors' });
                    }

                    var currentScript = runtime.getCurrentScript();
                    var savedSearchId = currentScript.getParameter('custscript_tf_saved_search');
                    var searchObj = search.load({
                        id: savedSearchId
                    });
                    searchObj = Dlib.defect474626Fix(searchObj);
                    searchObj = searchObj.runPaged({ pageSize: MAX_PAGE_SIZE });

                    log.audit({ title: '# of records that could not be deleted', details: searchObj.count });
                    log.audit({ title: 'Map Time Total (seconds)', details: summary.mapSummary.seconds });
                    log.audit({ title: 'Reduce Time Total (seconds)', details: summary.reduceSummary.seconds });
                    log.audit({ title: 'Max Concurrency Utilized ', details: summary.reduceSummary.concurrency });
                    log.audit({ title: 'END', details: '<---------------------------------END--------------------------------->' });
                } catch (errorObj) {
                    log.error({ title: '(Summary) Deletion Error', details: Dlib.getErrorDetails(errorObj) });
                }
            }
        };
    });

content_copyCOPY