Jira Code: MBS-6
Description:
Create a mass update look-alike system using MAP-REDUCE and File Buffering. The specific requirement cannot be achieved using a mass update. Specific validations and status change workflows should be applied. Hence Suitelet is not capable to process records mass in Number we use MAP-REDUCE script which is an asynchronous type. A buffer is created using the JSON file.
Map Reduce
/**
* @NApiVersion 2.x
* @NScriptType MapReduceScript
* @NModuleScope SameAccount
*
*/
/*******************************************************************************
MBS-6 Status updation of check
*************************************************************************
* Date : 01/15/2019
* Author : Jobin and Jismi IT Services LLP
* Script Description: Update the check records each from MBS - 6 SL Status update form
* Script name : MBS-6 MR Status updation of check.js
* Script id : customscript_mr_mbs_6_status_updation
* Deployment id : customdeploy_mr_mbs_6_status_updation
*
* Revision History
* MBS-6 created
******************************************************************************/
define(['N/record',"N/file","N/render","N/email","SuiteScripts/Jobin and Jismi IT Services LLP/MBS-6/package.js","N/search","N/runtime"],function(record,file,render,email,package,search,runtime){
//perform update for single Checks
function updateCheque(C)
{
try{
var CHEQUE=package.records.cheque;
var CHEQUE_TRAN=package.records.chequeTransaction;
var DEBIT_ACCOUNT=750;
var chequeValues=search.lookupFields({
type:package.records.cheque.recordType,
id:parseInt(C.key),
columns:[CHEQUE.status,CHEQUE.amount,CHEQUE.currency]
});
var values={};
var newValues=JSON.parse(C.values[0]);
if(newValues.n=="4")
values[package.records.cheque.account]=parseInt(newValues.a);
if(newValues.n=="2"||newValues.n=="3")
values[package.records.cheque.bank]=parseInt(newValues.b);
values[package.records.cheque.status]=parseInt(newValues.n);
var currency=chequeValues[CHEQUE.currency][0].value;
var amount = chequeValues[CHEQUE.amount];
var transaction=record.create({type:CHEQUE_TRAN.recordType,isDynamic:true});
transaction.setValue({fieldId:CHEQUE_TRAN.currency,value:currency});
var selectLine = transaction.selectNewLine({sublistId:CHEQUE_TRAN.sublist});
//line field Values
transaction.setCurrentSublistValue({
sublistId:CHEQUE_TRAN.sublist,
value:DEBIT_ACCOUNT,//Debit Account Id
fieldId:CHEQUE_TRAN.account
});
transaction.setCurrentSublistValue({
sublistId:CHEQUE_TRAN.sublist,
value:amount,//Amount of checque
fieldId:CHEQUE_TRAN.amount
});
transaction.commitLine({sublistId:CHEQUE_TRAN.sublist});
var tranId=transaction.save();
values["memo"]=tranId;
record.submitFields({
type:package.records.cheque.recordType,
id:parseInt(C.key),
values:values
});
}catch(err)
{
log.debug("err@updateCheque@"+C.key,err);
}
}
return {
reduce: updateCheque,
map:function(C){
var value=JSON.parse(C.value);
C.write({key:value.id,value:value});
},
getInputData:function(){
try{
//get Data from buffer file
var arrayFile=file.load({id:package.files.buffer})
var idArray=JSON.parse(arrayFile.getContents());
file.create({
name: arrayFile.name,
fileType:arrayFile.fileType,
contents: "[]",
folder: arrayFile.folder
}).save();
return idArray
}
catch(err)
{
log.debug("err@getInputData",err)
}
},
summarize:function(context){
try{
//Check for next file
var arrayFile=file.load({id:package.files.buffer})
var idArray=JSON.parse(arrayFile.getContents());
if(idArray.length>0){
try{
var mrTask = task.create(package.task).submit();
}catch(err){
log.debug("Already Running");
}
}
else{
log.debug("Task Completed",new Date().getTime());
}
}
catch(err)
{
log.debug("err@summarize",err)
}
}}
});
Client Script
/**
* @NApiVersion 2.x
* @NScriptType ClientScript
* @NModuleScope SameAccount
*/
/*******************************************************************************
MBS-6 Status updation of check
*************************************************************************
* Date : 01/15/2019
* Author : Jobin and Jismi IT Services LLP
* Script Description: Client actions for MBS - 6 SL Status update form
* Script name : MBS-6 CL Status updation of check.js
* Script id : nill
* Deployment id : nill
*
* Revision History
* MBS-6 created
******************************************************************************/
define(['N/currentRecord', "SuiteScripts/Jobin and Jismi IT Services LLP/MBS-6/package.js"], function(currentRecord, package) {
function runFilter() {
var c = currentRecord.get();
window.onbeforeunload = null;
var status = c.getValue("status")
status = status ? "&status=" + c.getValue("status") : "";
var customer = c.getValue("customer")
customer = customer ? "&customer=" + c.getValue("customer") : "";
window.location.href = package.scripts.UI + status + customer;
}
function validateEntries(c) {
try {
var status = c.currentRecord.getValue("new_satus");
if (status == 2 || status == 3) {
var bank = c.currentRecord.getValue({ fieldId: 'bank' });
if (bank == "" || bank == null) {
alert("fill the Bank Worked");
return false;
}
}
if (status == 4) {
var account = c.currentRecord.getValue({ fieldId: 'account' });
if (account == "" || account == null) {
alert("fill the Account");
return false
}
}
var lineNumber = c.currentRecord.findSublistLineWithValue({ sublistId: 'results', fieldId: 'selections', value: "T" });
if (lineNumber == -1) { alert("Choose atleast any of the cheques to update"); return false; }
} catch (err) {
alert("Error on submitting");
console.log(err);
return false;
}
return true;
}
return {
fieldChanged: function(c) {
(c.fieldId == "status" || c.fieldId == "customer") ? runFilter(): null;
},
saveRecord: validateEntries
}
})
Suitelet
/**
* @NApiVersion 2.x
* @NScriptType Suitelet
* @NModuleScope SameAccount
**/
/*******************************************************************************
MBS-6 Status updation of check
*************************************************************************
* Date : 01/15/2019
* Author : Jobin and Jismi IT Services LLP
* Script Description: Creates form for updation(GET) and update buffer for updation (POST)
* Script name : MBS - 6 SL Status update form
* Script id : customscript_mbs_6_status_updation_ui
* Deployment id : customdeploy_mbs_6_status_updation_ui
*
* Revision History
* MBS-6 created
******************************************************************************/
define(['N/task', "N/search", "N/ui/serverWidget", "N/render", "N/file", "N/encode", "SuiteScripts/Jobin and Jismi IT Services LLP/MBS-6/package.js"], function(task, search, serverWidget, render, file, encode, package) {
var CHEQUE = package.records.cheque;
var S = {
title: "Update Cheque status",
type: CHEQUE.recordType,
columns: [
{ name: "formulatext", formula: "{" + CHEQUE.type + "}", label: "Type" },
{ name: "formulatext", formula: "{" + CHEQUE.owner + "}", label: "Owner" },
{ name: CHEQUE.amount, label: "Amount" },
{ name: "formulatext", formula: "{" + CHEQUE.currency + "}", label: "Currency" },
{ name: "formulatext", formula: "{" + CHEQUE.status + "}", label: "Current status" },
{ name: CHEQUE.checkNo, label: "Check No" },
{ name: CHEQUE.id, label: "Internal ID" },
{ name: CHEQUE.id, label: "ID Hidden" },
{ name: CHEQUE.status, label: "Old Status" },
{ name: CHEQUE.bank, label: "Bank" }
]
};
var SHOW = function(r) { return r ? r : '' };
var style = {
"Type": SHOW,
"Internal ID": SHOW,
"Owner": SHOW,
"Amount": SHOW,
"Currency": SHOW,
"Check No": SHOW,
"Current status": SHOW,
"Old Status": "HIDDEN",
"ID Hidden": "HIDDEN"
};
function getResults() {
for (var i = 0; i < S.columns.length; i++)
S.columns[i] = search.createColumn(S.columns[i])
var results = [];
var pageData = search.create(S).runPaged({ pageSize: 1000 });
var page = pageData.pageRanges;
for (var k = 0; k < page.length; k++) {
var data = pageData.fetch({ index: k }).data;
for (var j = 0; j < data.length; j++) {
var R = data[j];
var obj = {};
for (var i = 0; i < S.columns.length; i++)
obj[S.columns[i].label] = R.getValue(S.columns[i]);
results.push(createLine(obj));
}
}
return results;
}
function createLine(obj) {
obj["Internal ID"] = "<a href='/app/common/custom/custrecordentry.nl?rectype=83&id=" + obj["ID Hidden"] + "'>" + obj["ID Hidden"] + "</a>";
return obj;
}
function createForm(params) {
try {
var form = serverWidget.createForm({ title: S.title });
form.clientScriptFileId = package.files.cl;
var filterGrid = form.addFieldGroup({
id: '_filter',
label: 'Filters'
});
var status = form.addField({
id: "status",
source: package.lists.status.listType,
type: serverWidget.FieldType.SELECT,
label: 'Current status',
container: '_filter'
});
var customer = form.addField({
id: "customer",
source: "customer",
type: serverWidget.FieldType.SELECT,
label: 'Customer',
container: '_filter'
});
var showSubmitButton = false;
params.customer ? customer.defaultValue = params.customer : null;
var R = getResults();
//log.debug("R",R);
if (params.status) {
if (R.length > 0) {
var sublist = form.addSublist({
id: 'results',
type: serverWidget.SublistType.LIST,
label: 'CHEQUES/DRAFTS'
});
sublist.addMarkAllButtons();
var selections = sublist.addField({
id: "selections",
type: serverWidget.FieldType.CHECKBOX,
label: 'Select',
align: serverWidget.LayoutJustification.CENTER
});
var i = 0;
for (var col in style) {
var sublistField = sublist.addField({
id: "custpage_" + i,
type: serverWidget.FieldType.TEXTAREA,
label: col
});
if (style[col] == "HIDDEN")
sublistField.updateDisplayType({ displayType: serverWidget.FieldDisplayType.HIDDEN });
i++;
}
for (var j = 0; j < R.length; j++) {
i = 0;
for (var col in style) {
var value = style[col] != "HIDDEN" ? style[col](R[j][col]) : R[j][col]
if (value)
sublist.setSublistValue({
id: "custpage_" + i,
line: j,
value: value
});
i++;
}
}
}else showSubmitButton = false;
status.defaultValue = params.status;
var validStatuses = package.lists.status.values[params.status].validStatuses;
if (validStatuses.length > 0) {
var updateFields = form.addFieldGroup({
id: '_update',
label: 'Update Fields'
});
filterGrid.isSingleColumn = true;
updateFields.isSingleColumn = true;
var newStatus = form.addField({
id: "new_satus",
type: serverWidget.FieldType.SELECT,
label: "New Status",
container: '_update'
}).updateDisplayType({ displayType: serverWidget.FieldDisplayType.ENTRY });
for (var i = 0; i < validStatuses.length; i++)
newStatus.addSelectOption({ value: validStatuses[i], text: package.lists.status.values[validStatuses[i]]["text"] });
showSubmitButton = true;
}
if (validStatuses.indexOf(2) >= 0 || validStatuses.indexOf(3) >= 0) {
var bank = form.addField({
id: "bank",
type: serverWidget.FieldType.SELECT,
label: "Bank Worked",
source: "customlist_jj_list_bank_worked",
container: '_update'
}).updateDisplayType({ displayType: serverWidget.FieldDisplayType.ENTRY });
}
if (validStatuses.indexOf(4) >= 0) {
var account = form.addField({
id: "account",
type: serverWidget.FieldType.SELECT,
label: "Account",
source: "account",
container: '_update'
}).updateDisplayType({ displayType: serverWidget.FieldDisplayType.ENTRY });
}
}
if (R.length == 0) showSubmitButton = false;
if (showSubmitButton)
{
form.addSubmitButton({ id: 'buttonid', label: 'Update' });
}
return form;
} catch (err) {
log.debug("Error@createForm", err);
}
}
function onRequest(context) {
try {
if (context.request.method == "POST") {
var newValue = context.request.parameters.new_satus;
var oldValue = context.request.parameters.status;
log.debug(newValue,oldValue);
var validStatuses = package.lists.status.values[oldValue].validStatuses;
var bank,account;
if(newValue==2 || newValue==3)bank = context.request.parameters.bank;
if(newValue==4)account = context.request.parameters.account;
var lineCount = context.request.getLineCount({ group: 'results' });
var recIds = [];
for (var i = 0; i < lineCount; i++) {
if(context.request.getSublistValue({
group: 'results',
name: "selections",
line: i
})=="T"){
var checkId = context.request.getSublistValue({
group: 'results',
name: "custpage_8",
line: i
});
if(newValue==2||newValue==3)recIds.push({id:checkId,n:newValue,o:oldValue,b:bank});
else if (newValue==4) {
recIds.push({id:checkId,n:newValue,o:oldValue,a:account});
} else recIds.push({id:checkId,n:newValue,o:oldValue});
}
}
var arrayFile = file.load({ id: package.files.buffer })
var idArray = JSON.parse(arrayFile.getContents());
idArray = idArray.concat(recIds);
file.create({
name: arrayFile.name,
fileType: arrayFile.fileType,
contents: JSON.stringify(idArray),
folder: arrayFile.folder
}).save();
try {
var mrTask = task.create(package.task).submit();
} catch (err) {
log.debug("Already Running")
}
context.response.write("<html><head><body><script>alert('Updating process started will be completed soon');window.location.href='" + package.scripts.UI + "';</script></body></head></html>");
return;
}
if (context.request.parameters.status)
S.filters = [
[CHEQUE.status, "anyof", context.request.parameters.status]
];
if (S.filters && context.request.parameters.customer)
S.filters.push("AND", [CHEQUE.owner, "anyof", parseInt(context.request.parameters.customer)]);
else if (context.request.parameters.customer)
S.filters = ([CHEQUE.owner, "anyof", parseInt(context.request.parameters.customer)]);
context.response.writePage(createForm(context.request.parameters));
} catch (err) {
log.debug("Error@onRequest", err);
}
}
return {
onRequest: onRequest
}
});
Package Module
define(["N/search"],function(search) {
var CHEQUE = {
recordType:"customrecord_jj_checkordraft",
type:"custrecord_jj_check_type",
owner:"custrecord_jj_check_owner",
id:"internalid",
status:"custrecord_jj_check_status",
checkNo:"custrecord_jj_check_checknumber",
currency:"custrecord_jj_check_currency",
amount :'custrecord_jj_check_amount',
bank:"custrecord_jj_check_bank_worked"
};
var CHEQUE_TRAN ={
recordType:"customtransaction_jj_check_transaction",
currency:"currency",
sublist:"line",
account:"account",
amount:"amount"
};
var STATUSES_VALUES={
1:{ text:"In the Portfolio",validStatuses:[2, 3, 7, 8]},
2:{ text:"At Bank",validStatuses:[3, 4, 5, 6]},
3:{ text:"At Deposit",validStatuses:[2, 4, 5, 6]},
4:{ text:"Paid",validStatuses:[]},
5:{ text:"Bank Return",validStatuses:[2, 3, 7, 8]},
6:{ text:"Bank Return (X)",validStatuses:[7]},
7:{ text:"Customer Return",validStatuses:[]},
8:{ text:"Vendor Payment",validStatuses:[9]},
9:{ text:"Vendor Return",validStatuses:[]}
};
var STATUS={
listType:"customlist_jj_list_of_check_status",
values:STATUSES_VALUES
};
var scripts = {
UI: "/app/site/hosting/scriptlet.nl?script=166&deploy=1",
MR: "",
CHECK_REC:"/app/common/custom/custrecordentry.nl?rectype=83&id="
};
var files = {
buffer:"SuiteScripts/Jobin and Jismi IT Services LLP/MBS-6/temp/buffer.js",
cl:"SuiteScripts/Jobin and Jismi IT Services LLP/MBS-6/CL/MBS-6 CL Status updation of check.js"
};
return {
records: { cheque: CHEQUE ,chequeTransaction:CHEQUE_TRAN},
lists:{status:STATUS},
scripts: scripts,
files: files,
task:{
taskType:"MAP_REDUCE",
scriptId:"customscript_mr_mbs_6_status_updation",
deploymentId:"customdeploy_mr_mbs_6_status_updation"
}
}
})
Buffer File – (JSON FILE with array of internal Id)
[internal Ids]