Requirement :
On button click from sales order/estimate we can have a pop up listing all items with a checkbox and a field to enter the price level.When the user selects items and enter the price for it, upon submit, the selected items will get updated with the new price added.
Solution 1: Created the button in edit/create mode. This was actually take too much time to update the item price, we have changed the button to view mode only. In edit/create mode , a button created in user event script and call first client script(this is not deployed) , the item details are fetched from current record and send to suitlet. In suitlet the form will be created in GET function. as this is in create/edit mode we cannot set the details back to transcation record. so used an another client script from suitlet (not deployed), which did the field validations and also gets the entered values from the form. These values are send to next client script(this is deployed) using this format
window.opener.setFileCLGC_1050(datas to send); where "setFileCLGC_1050" function used in last client script. In the deployed script
var currentrec;
function pageInit(scriptContext) {
currentrec=scriptContext.currentRecord;
window.setFileCLGC_1050=setFile
}
function setFile(datas to send){
//process
//Function used to set back the values to transaction record.
}
Drawback of Solution 1: This should consume more time 5-10m if there are more than 10 number of items. This only applicable to fewer number of items (e.g. below 10). So we have changed the button to view mode.
Solution 2: The button seen only in view mode. This takes only less time compare to solution 1. we have checked the goovernance. Large amount of usage still left. and time taken is maximum of 20s, even there are 194 item lines.
//User event script
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
*/
define([
'N/record',
'N/error',
'N/ui/serverWidget',
'N/url',
'N/runtime',
'N/search'
],
/**
* @param{record} record
*/
(record,error,serverWidget,url,runtime,search) => {
/**
* Defines the function definition that is executed before record is loaded.
* @param {Object} scriptContext
* @param {Record} scriptContext.newRecord - New record
* @param {string} scriptContext.type - Trigger type; use values from the context.UserEventType enum
* @param {Form} scriptContext.form - Current form
* @param {ServletRequest} scriptContext.request - HTTP request information sent from the browser for a client action only.
* @since 2015.2
*/
const beforeLoad = (scriptContext) => {
if (scriptContext.type == 'view') {
try{
var newRecord = scriptContext.newRecord;
var form = scriptContext.form;
var TestUpdatePrice = form.addButton
({
id: "custpage_updateprice",
label: "Test Update price",
functionName: "onButtonClick"
});
form.clientScriptFileId = 157729;
}catch (err) {
log.error({title: "Error in Update Price", details: err.message});
}
}
}
return {beforeLoad}
});
//Client script
/**
* @NApiVersion 2.0
* @NScriptType ClientScript
*/
define(['N/currentRecord', 'N/https', 'N/ui/dialog','N/url'],
/**
* @param{currentRecord} currentRecord
* @param{https} https
* @param{dialog} dialog
* @param{serverWidget} serverWidget
*/
function(currentRecord, https, dialog, url) {
/**
* Function to be executed after page is initialized.
*
* @param {Object} scriptContext
* @param {Record} scriptContext.currentRecord - Current form record
* @param {string} scriptContext.mode - The mode in which the record is being accessed (create, copy, or edit)
*
* @since 2015.2
*/
function pageInit(scriptContext) {}
function onButtonClick() {
var so = currentRecord.get();
var recordId = Number(so.id);
var recordType = so.type;
var sizeDetails = 'height=' + 800 + ' , width=' + 1000;
var TO_SL = url.resolveScript({
scriptId: 'customscript1228', //todo Suitlet update!!!!!!
deploymentId: 'customdeploy1', //todo Suitlet update!!!!!!
returnExternalUrl: false
});
window.open(TO_SL +'&recordid='+recordId+'&recordtype='+recordType, "Item List Form", sizeDetails);
}
return {
pageInit:pageInit,
onButtonClick: onButtonClick
};
});
The index of only the selected item line’s (check box true in pop up) rate field are updated with new price added.
//suitlet
/**
* @NApiVersion 2.1
* @NScriptType Suitelet
*/
define(['N/file', 'N/https', 'N/record', 'N/render', 'N/runtime', 'N/search', 'N/ui/serverWidget','N/ui/message'],
/**
* @param{file} file
* @param{https} https
* @param{record} record
* @param{render} render
* @param{runtime} runtime
* @param{search} search
* @param{serverWidget} serverWidget
*/
(file, https, record, render, runtime, search, serverWidget,message) => {
var itemArray = [];
var rateArray = [];
var lineArray = [];
/**
* Defines the Suitelet script trigger point.
* @param {Object} scriptContext
* @param {ServerRequest} scriptContext.request - Incoming request
* @param {ServerResponse} scriptContext.response - Suitelet response
* @since 2015.2
*/
const onRequest = (scriptContext) => {
log.debug("ONREQUEST");
try {
var request = scriptContext.request;
var response = scriptContext.response;
if (scriptContext.request.method === 'GET') {
try {
var itemID =scriptContext.request.parameters.recordid;
var itemType =scriptContext.request.parameters.recordtype;
var searchForItem = createSearch(itemID,itemType);
var form = serverWidget.createForm({
title: 'Update Item Prices'
});
var newPrice= form.addField({
id : 'custpage_text',
type : serverWidget.FieldType.CURRENCY,
label : 'New Price'
});
newPrice.isMandatory = true;
var recId = form.addField({ //todo
id: 'custpage_recordid_id',
type: serverWidget.FieldType.INTEGER,
label: 'Record ID',
})
recId.updateDisplayType({
displayType : serverWidget.FieldDisplayType.HIDDEN
});
recId.defaultValue = itemID;
var rectype = form.addField({ //todo
id: 'custpage_recordtype_id',
type: serverWidget.FieldType.TEXT,
label: 'Record Type',
})
rectype.updateDisplayType({
displayType : serverWidget.FieldDisplayType.HIDDEN
});
rectype.defaultValue = itemType;
var sublist = form.addSublist({
id: 'tran_sublist',
type: serverWidget.SublistType.LIST,
label: 'Update Item list'
});
sublist.addMarkAllButtons();
sublist.addField({
id: 'custpage_check',
type: serverWidget.FieldType.CHECKBOX,
label: 'SELECT'
});
// var internalId = sublist.addField({
// id: 'custpage_id',
// label: 'InternalID',
// type: serverWidget.FieldType.INTEGER
// });
// internalId.updateDisplayType({displayType: serverWidget.FieldDisplayType.HIDDEN});
var itemIndex = sublist.addField({
id: 'custpage_index',
label: 'Index',
type: serverWidget.FieldType.INTEGER
});
itemIndex.updateDisplayType({displayType: serverWidget.FieldDisplayType.HIDDEN});
sublist.addField({
id: 'sublist_item',
type: serverWidget.FieldType.TEXT,
label: 'ITEM NAME'
});
sublist.addField({
id: 'sublist_rate',
type: serverWidget.FieldType.CURRENCY, //todo float
label: 'UNIT PRICE'
});
setValueFunction(itemArray,rateArray,lineArray);
form.addSubmitButton({
id: 'custpage_submit_button',
label: 'SUBMIT'
});
form.clientScriptFileId = 157932; //client script to used to show a message that update is in progress
scriptContext.response.writePage(form);
} catch (e) {
log.debug("error@GET", e);
}
}
else if (scriptContext.request.method=='POST'){
try{
var price = scriptContext.request.parameters.custpage_text;
var typeOfrec = scriptContext.request.parameters.custpage_recordtype_id;
var idOfrec = scriptContext.request.parameters.custpage_recordid_id;
var listItems = scriptContext.request.getLineCount("tran_sublist")
var m;
var indexArray =[];
for ( m = 0; m < listItems; m++) {
var checkBox = scriptContext.request.getSublistValue('tran_sublist','custpage_check',m);
log.debug("chkboxvalue",checkBox);
//get only the item id's if checkbox is true
if (checkBox == 'T') {
var index = scriptContext.request.getSublistValue('tran_sublist','custpage_index',m);
//console.log("**itemsinternalId in UPDATE RATE FIELD**",dataObj.itemsinternalId);
indexArray.push(index);
}
}
log.debug("indexArray",indexArray);
//Load current record
var objRecord;
if(typeOfrec=='salesorder'){
objRecord = record.load({
type: record.Type.SALES_ORDER,
id: idOfrec,
isDynamic: true,
});
}
else if(typeOfrec=='estimate'){
objRecord = record.load({
type: record.Type.ESTIMATE,
id: idOfrec,
isDynamic: true,
});
}
log.debug("objRecord",objRecord);
//set the item line values based on index value selected in pop up
log.debug("indexArray.length",indexArray.length);
for (var i = 0; i < indexArray.length;i++) {
var k=indexArray[i];
log.debug("I Loop", i);
log.debug("k Loop", k);
// var netsuiteItemId = objRecord.getSublistValue({
// fieldId: 'item',
// sublistId: 'item',
// line: i
// });
// log.debug("netsuiteItemId", netsuiteItemId);
objRecord.selectLine({
sublistId: 'item',
line: k-1
});
objRecord.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'price',
value: -1,
ignoreFieldChange: false,
forceSyncSourcing: true
});
objRecord.setCurrentSublistValue({ //Set the item_id to be used when item fulfill
sublistId: 'item',
fieldId: 'rate',
value: price,
ignoreFieldChange: false,
forceSyncSourcing: true
});
objRecord.commitLine({
sublistId: 'item'
});
}
objRecord.save({ignoreMandatoryFields:true});
var htmlCode = '<html><body><script type="text/javascript">window.opener.location.reload();window.close()</script></body></html>'
scriptContext.response.write(htmlCode);
// var usagelimit = runtime.getCurrentScript().getRemainingUsage();
// log.debug("Remaining usage limit",usagelimit);
}catch (e) {
log.debug("error@post",e);
}
}
/**
* @function setValueFunction
* @param itemNameArray
* @param itemId
* @param lengthOfArray
* @param sublist
* @param itemRate
* @param indexArray
*/
function setValueFunction(itemArray,rateArray,lineArray) {
try {
log.debug("setValueFunction ");
for (var i = 0; i < itemArray.length; i++) {
sublist.setSublistValue({
id: 'custpage_check',
line: i,
value: 'F'
});
// sublist.setSublistValue({
// id: 'custpage_id',
// line: i,
// value: itemId[i]
// });
sublist.setSublistValue({
id: 'custpage_index',
line: i,
value: Number(lineArray[i])
});
sublist.setSublistValue({
id: 'sublist_item',
line: i,
value: itemArray[i]
});
if(rateArray[i]==''){
sublist.setSublistValue({
id: 'sublist_rate',
line: i,
value:0
});
}else{
sublist.setSublistValue({
id: 'sublist_rate',
line: i,
value:Number(rateArray[i])
});
}
}
}
catch (e) {
log.debug("error@setvaluefunction",e);
}
}
}catch (e) {
log.debug("error@onrequest",e);
}
/**
* @function createSearch
* @param itemID
* @param itemType
*/
function createSearch (itemID,itemType){
try{
var type1,type2
if(itemType=='salesorder'){
type1=itemType;
type2="SalesOrd";
}else if(itemType=='estimate'){
type1=itemType;
type2="Estimate";
}
var salesorderSearchObj = search.create({
type: type1,
filters:
[
["type","anyof",type2],
"AND",
["internalid","anyof",itemID],
"AND",
["shipping","is","F"],
"AND",
["taxline","is","F"],
"AND",
["closed","is","F"],
"AND",
["cogs","is","F"],
"AND",
["mainline","is","F"]
],
columns:
[
search.createColumn({name: "item", label: "Item"}),
search.createColumn({name: "fxrate", label: "Item Rate"}),
search.createColumn({name: "line", label: "Line ID"})
]
});
var searchResultCount = salesorderSearchObj.runPaged().count;
log.debug("salesorderSearchObj result count",searchResultCount);
salesorderSearchObj.run().each(function(result){
var item = result.getText({
name: "item",
label: "Item"
})
itemArray.push(item)
var rate = result.getValue({
name: "fxrate",
label: "Item Rate"
})
rateArray.push(rate)
var line = result.getValue({
name: "line",
label: "Line ID"
})
lineArray.push(line)
return true;
});
}catch (e) {
log.debug("error@createSearch",e);
}
}
}
return {onRequest}
});
//client script
//To show message to user
/**
* @NApiVersion 2.x
* @NScriptType ClientScript
* @NModuleScope SameAccount
*/
define(['N/ui/message', 'N/url'],
/**
* @param{message} message
* @param{url} url
*/
function(message, url) {
/**
* Validation function to be executed when record is saved.
*
* @param {Object} scriptContext
* @param {Record} scriptContext.currentRecord - Current form record
* @returns {boolean} Return true if record is valid
*
* @since 2015.2
*/
function saveRecord(scriptContext) {
try{
console.log("save record");
let myMsg2 = message.create({
title: 'Message',
message: 'The price update is in progress, Please wait',
type: message.Type.INFORMATION
});
myMsg2.show();
return true;
//setTimeout(myMsg2.hide, 15000); // will disappear after 15s
}catch (e) {
log.debug("error@saverecord",e)
}
}
return {
saveRecord: saveRecord
};
});