Client needs to update the landed cost price in transaction records.
/**
* @NApiVersion 2.1
* @NScriptType MapReduceScript
*/
/*********************************************************************************************************
* ${RLPL-16} : ${Update landed cost on body level for Item Receipts using script}
*
***************************************************************************************************
***********
* Author : Jobin and Jismi IT Services
*
* Date Created : 12-May-2023
*
* Description : This script is for Update landed cost in the Item Receipts using CSV file data
*
* Revision History :
*
* ************************************************************************************************
* **********
*/
'use strict';
define(['N/email', 'N/file', 'N/record', 'N/search','/SuiteScripts/papaparse.min.js'],
/**
* @param{email} email
* @param{file} file
* @param{record} record
* @param{search} search
*/
(email, 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: 7079995});
let fileContents = csvFile.getContents();
let dataFile=papa.parse(fileContents,{
header:true,
skipEmptyLines:true
}).data;
log.debug("val",dataFile)
return dataFile;
}
catch(e){
log.debug("Error@getInputdataFunction",e);
return [];
}
}
/**
* 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) => {
function isInternalIdValid(id) {
let recordSearch;
try {
recordSearch=search.create({
type: search.Type.ITEM_RECEIPT,
columns: ['internalid','createdfrom'],
filters: [ ['internalid','is',id],'AND',
['createdfrom.type','anyof','TrnfrOrd']]
});
log.debug("search",recordSearch);
} catch (e) {
// An error occurred while loading the record, so the ID is invalid
return false;
}
if (recordSearch) {
// The record was successfully loaded, so the ID is valid
return true;
} else {
// The record was not found, so the ID is invalid
return false;
}
}
try{
let jsonObject=JSON.parse(reduceContext.values);
// Fetch individual values
let internalId = jsonObject['Internal ID'];
let documentNumber = jsonObject['Document Number'];
let costAllocationMethod = jsonObject['Cost Allocation Method'];
let freight = jsonObject['Freight'];
let customs = jsonObject['Customs'];
let others = jsonObject['Others'];
//validate the internalid
let validateID=isInternalIdValid(internalId);
//if the internalid is valid then submit the fields
if (validateID) {
record.submitFields({
type: record.Type.ITEM_RECEIPT,
id: internalId,
values: {
landedcostmethod:costAllocationMethod,
landedcostamount1: customs,
landedcostamount2: freight,
landedcostamount3: others
}
});
}
}catch(e){
log.debug("error@reduceFunction",e);
let result = reduceContext.values.map(JSON.parse);
reduceContext.write({
key: 'error',
value: {...result, '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{
let fileID = '', flag = 0;
let titleArray = ["Item Receipt ID","Internal ID", "Error Description"];
let csvFileData = titleArray.toString() + '\r\n';
log.debug("Error",csvFileData);
summaryContext.output.iterator().each(function (key, value) {
let parseSummary = JSON.parse(value);
//log.debug("Summary parse", parseSummary)
let errorField= parseSummary.error.message;
let errorMessage = errorField.replaceAll(',', " ") + '\r\n';
let jsonValue=parseSummary["0"];
// log.debug("errorMessage",errorMessage)
let itemReceiptID = jsonValue['Internal ID'];
let docNumber=jsonValue["Document Number"];
//log.debug("docnu",docNumber);
if (key === 'error') {
flag = flag + 1
csvFileData +=docNumber+','+ itemReceiptID + ',' + errorMessage
}
return true
});
if (flag > 0) {
let fileObj = file.create({
name: 'ERROR-' + Math.floor(Date.now() / 1000) + '.csv',
fileType: file.Type.CSV,
folder: 1516614,
contents: csvFileData
});
fileID = fileObj.save()
log.debug("fileID",fileID);
}
}
catch(e)
{
log.debug("error@Summarize",e);
}
}
return {getInputData, reduce, summarize}
});