Client needs to update missing entity names in specific lines in the journal entry record. The details was given in CSV file. We have updated using a scheduled script,
/**
* @NApiVersion 2.1
* @NScriptType MapReduceScript
*/
/************************************************************************************************
* * Scheduled Script To Update Name In Journal **
*
*
* **********************************************************************************************
*
* Author: Athul Krishna
*
* Date Created : 24-November-2023
*
* Created By: Jobin and Jismi
*
* Description : Scheduled Script To Update Name In Journal
*
* REVISION HISTORY
*
*
*
*
***********************************************************************************************/
define(['N/file', 'N/record', 'N/search','/SuiteScripts/papaparse.min.js'],
/**
* @param{file} file
* @param{record} record
* @param{search} search
*/
(file, record, search,papa) => {
/**
* 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 csvFile = file.load({id: 1069792});
let fileContents = csvFile.getContents();
let dataFile=papa.parse(fileContents,{
header:true,
skipEmptyLines:true
}).data;
log.debug("val",dataFile)
return dataFile;
}
catch(e){
log.error("error@getInput",e)
}
}
/**
* Defines the function that is executed when the map entry point is triggered. This entry point is triggered automatically
* when the associated getInputData stage is complete. This function is applied to each key-value pair in the provided
* context.
* @param {Object} mapContext - Data collection containing the key-value pairs to process in the map stage. This parameter
* is provided automatically based on the results of the getInputData stage.
* @param {Iterator} mapContext.errors - Serialized errors that were thrown during previous attempts to execute the map
* function on the current key-value pair
* @param {number} mapContext.executionNo - Number of times the map function has been executed on the current key-value
* pair
* @param {boolean} mapContext.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} mapContext.key - Key to be processed during the map stage
* @param {string} mapContext.value - Value to be processed during the map stage
* @since 2015.2
*/
const map = (mapContext) => {
try{
let searchResult= JSON.parse(mapContext.value);
//log.debug("Search Result",searchResult)
let internalId= searchResult["Internal ID"];
mapContext.write({
key: internalId,
value: searchResult
});
}catch(e){
log.error("error@map",e)
}
}
/**
* 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{
let key = reduceContext.key
let arAccounts=["1683","324","119","1684","1685","1686","1687","2095"]
//if(key == "2567177" ){
log.debug("Inside reduce Context");
let curRec= record.load({
type: record.Type.JOURNAL_ENTRY,
id: key
});
let lineCount= curRec.getLineCount({
sublistId: 'line'
});
for(let i=0;i<lineCount;i++){
let account =curRec.getSublistValue({
sublistId: 'line',
fieldId: 'account',
line: i
})
log.debug("account",account)
if(arAccounts.includes(account)){
log.debug("inside if")
curRec.setSublistValue({
sublistId: 'line',
fieldId: 'entity',
value: 18847,
line: i
});
}
}
curRec.save();
//}
}
catch(e){
log.debug("error@reduce",e)
log.debug("after error",reduceContext.values.map(JSON.parse))
let searchResult = reduceContext.values.map(JSON.parse)
log.debug("searchResult In catch",searchResult)
reduceContext.write({
key : "error",
value: {...searchResult,'error': e}
})
}
}
/**
* 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) => {
try{
var titleArray = ["Internal ID", "Error Description","Subsidiary"];
var csvFileData = titleArray.toString() + '\r\n';
let flag=0,fileID="";
summaryContext.output.iterator().each(function (key, value) {
if (key === 'error') {
let parseSummary = JSON.parse(value);
log.debug("error parse", parseSummary)
flag= flag+1;
let internalID = parseSummary['0']['Internal ID'];
csvFileData += internalID + ',' + parseSummary.error.message.replace(',', " ") + ','+parseSummary['0']['Subsidiary']+'\r\n';
}
return true
})
if(flag>0){
let fileObj = file.create({
name: 'ERROR-File Created' + '-' + Math.floor(Date.now() / 1000) + '.csv',
fileType: file.Type.CSV,
folder: 90040,
contents: csvFileData
});
fileID = fileObj.save()
}
}
catch(e){
log.error("error@Summarize",e)
}
}
return {getInputData, map, reduce, summarize}
});