How to compare two dates and give condition as per the selected dates on two date Fields in suitelet script? - netsuite

Here what I am doing is I have just created a simple suitelet as well as linked client script also,
The thing is here I'm getting an error page called unexpected error. I don't know why it is going there. Im providing both scripts please take a look and give me a solution.
define(['N/record','N/ui/serverWidget','N/redirect','N/runtime','N/search','N/url'],function(record,serverWidget,redirect,runtime,search,url){
function onRequest(context){
var Request = context.request;
var Response = context.response;
var name = context.fieldId;
if(Request.method == 'GET') {
var form=serverWidget.createForm({title:"Customer entry Suitelet"});
var primaryinfo=form.addFieldGroup({
label:'Primary Information',
id:'custpage_advs_primary_info',
});
var firstname=form.addField({
label:'First Name',
id:'custpage_advs_first_name',
type:serverWidget.FieldType.TEXT,
container:'custpage_advs_primary_info'
});
firstname.isMandatory=true;
var lastname=form.addField({
label:'Last Name',
id:'custpage_advs_last_name',
type:serverWidget.FieldType.TEXT,
container:'custpage_advs_primary_info'
});
Response.writePage(form);
form.clientScriptModulePath = './advs_cs_datefilter.js';
var fnameValue = Request.parameters.custparam_first_name;
if(fnameValue){
firstname.defaultValue =fnameValue;
var fnamecustomerSearch = search.create({
type:'customrecord_advs_customer_entry_form',
filters:['custrecord_advs_first_name',"startswith",fnameValue],
columns:[
search.createColumn({name: "name"}),
search.createColumn({name: "custrecord_advs_first_name"}),
search.createColumn({name: "custrecord_advs_last_name"}),
search.createColumn({name: "custrecord_advs_email"}),
search.createColumn({name: "custrecord_advs_phone"}),
search.createColumn({name: "internalid"}),
search.createColumn({name: "id"}),
search.createColumn({name:"created"})
]
});
var counter = 0;
fnamecustomerSearch.run().each(function(result) {
log.debug("my result", +result);
var oldfullname = result.getValue('name');
var InternalidVal = result.getValue('internalid');
var firstname=result.getValue('custrecord_advs_first_name');
var lastname=result.getValue('custrecord_advs_last_name');
var email=result.getValue('custrecord_advs_email');
var phone=result.getValue('custrecord_advs_phone');
var recordid=result.id;
mysublist.setSublistValue({
id: 'custpage_advs_sublist_internalid',
line: counter,
value: InternalidVal
});
mysublist.setSublistValue({
id: 'custpage_advs_sublist_fullname',
line: counter,
value:oldfullname //....and so on and whatever I'm getting on the search
}); // I'm setting those on sublist values on the line
return true;
});
}
else if(((startDateValue)&&(endDateValue)) &&((endDateValue>startDateValue))){
startdate.defaultValue =startDateValue;
enddate.defaultValue=endDateValue;
var datecustomerSearch = search.create({
type:'customrecord_advs_customer_entry_form',
filters:[
["created","onorafter",startDateValue],
'or',
["created",'onorbefore',endDateValue],
],
columns:[
search.createColumn({name: "name"}),
search.createColumn({name: "custrecord_advs_first_name"}),
search.createColumn({name: "custrecord_advs_last_name"}),
search.createColumn({name: "custrecord_advs_email"}),
search.createColumn({name: "custrecord_advs_phone"}),
search.createColumn({name: "internalid"}),
search.createColumn({name: "id"}),
search.createColumn({name:"created"})
]
});
var counter = 0;
datecustomerSearch.run().each(function(result) {
log.debug("my result", +result);
var oldfullname = result.getValue('name');
var InternalidVal = result.getValue('internalid');
var firstname=result.getValue('custrecord_advs_first_name');
var lastname=result.getValue('custrecord_advs_last_name');
var email=result.getValue('custrecord_advs_email');
var phone=result.getValue('custrecord_advs_phone');
var recordid=result.id;
const view_url = url.resolveRecord({
recordType:'customrecord_advs_customer_entry_form',
recordId: recordid,
isEditMode: false
});
mysublist.setSublistValue({
id: 'custpage_advs_sublist_internalid',
line: counter,
value: InternalidVal
});
mysublist.setSublistValue({
id: 'custpage_advs_sublist_fullname',
line: counter,
value:oldfullname
});
mysublist.setSublistValue({
id: 'custpage_advs_sublist_fname',
line: counter,
value: firstname
}); // I'm doing the same what I did on last condition
counter++;
return true;
});
}
else // POST part just I'm creating record & setting the values and saving
{
var Fname= Request.parameters.custpage_advs_first_name;
var Lname=Request.parameters.custpage_advs_last_name;
var Email=Request.parameters.custpage_advs_email;
var Phone=Request.parameters.custpage_advs_phone;
var Fullname=Fname+' '+Lname;
var customRecord=record.create({
type:'customrecord_advs_customer_entry_form',
isDynamic:true,
});
customRecord.setValue({
fieldId:'name',
value:Fullname
});
redirect.toSuitelet({
scriptId: 'customscript_advs_ss_datefilter',
deploymentId: 'customdeploy_advs_ss_datefilter',
});
}
}
return{
onRequest:onRequest
}
});
here is my client script
here only I had a doubt on how to give condition
Actually, my need is If we select both dates on as per logically that means
let me tell scenario
#1:START DATE is 09/12/2022 and END DATE is 17/12/2022{//its like Start date is less than end date search should happen as well as it
has to set the values in the sublist }
#2 END DATE IS 17/12/2022 END DATE is 09/12/2022{ // it is like reverse process absolutely there will be no condition so what I
have to do is I need to give a pop up prevent user to select date
like this }
here is my client script and also I'm proving the screenshots of error page and design of my suitelet
define(['N/currentRecord','N/search','N/record','N/url','N/format'],function(currentRecord,search,record,url,format){
function fieldChanged(context) {
var recordObj=context.currentRecord;
// var name = context.fieldId;
var startDateValue=recordObj.getValue({
fieldId:'custpage_advs_start_date'
});
var endDateValue=recordObj.getValue({
fieldId:'custpage_advs_end_date'
});
if((startDateValue)&&(endDateValue)){
var startresponseDate=format.format({
value:startDateValue,
type:format.Type.DATE
});
var endresponseDate=format.format({
value:endDateValue,
type:format.Type.DATE
});
alert("The Customer entry Records that you have entered is between the dates " +startresponseDate +" and "+endresponseDate +" Click ok to continue " );
var suiteUrl = url.resolveScript({
scriptId: 'customscript_advs_ss_editviewcolumn',
deploymentId: 'customdeploy_advs_ss_editviewcolumn',
returnExternalUrl:false,
params : {
custparam_start_date: startresponseDate,
custparam_end_date: endresponseDate //define a parameter and pass the value to it
}
});
}
else{
return true;
}
setWindowChanged(window,false);
window.location = suiteUrl;
}
return{
fieldChanged:fieldChanged
}
});
please someone help me to solve my issue

As far as the dates are concerned you probably want to get the timestamps by doing something like: var startresponseDateTs = startresponseDate.getTime(); and then once you have the numbers you can just compare those. In NS you may be able to literally compare the NS Dates just (date1 > date2) but I'm not 100% about that one.
*By the way any of these could be causing the unexpected error:
(1) Your suitelet is missing a bracket above the final return.
(2) all of the "mysublist"'s seem to be undefined. The sublist needs to be created just like you created the form: var mysublist = form.addSublist({ id: 'custpage_a_sublist_id', type: serverWidget.SublistType.LIST, label: 'Hello Sublist' });
ps. adding a try {} catch(err){} block into the code could help. Not always. If its still not working you're about to get a masterclass in using the debugger :P

You need to call the client script before/ above the response of suitelet.
and try to add alert after a block of code if you don't know how to use debugger for each variable as a testing of client script execution.
like:-
alert(" startDateValue "+startDateValue);
alert(" endresponseDate"+endresponseDate);
alert("line no 110"); //for line no to get exact line with error.
so that you find the line where you are actually getting the error.
Thanks

Related

Scripted search and looping - how do I show only 1 alert if multiple results?

I have a script that is triggering a search when a field is changed. The goal is that if the search finds a result to alter the user that this may be a possible duplicate. The issue I am having is that if there are more than 1 result it will show the alert as many times as there are results. How can I have it show the result only once?
/**
*#NApiVersion 2.0
*#NScriptType ClientScript
*/
define(['N/record', 'N/search', 'N/ui/dialog'], function(r, search, u) {
function fieldChanged(context) {
var recCurrent = context.currentRecord;
var show = recCurrent.getValue({
fieldId: 'custrecord_eym_er_show'
});
var client = recCurrent.getValue({
fieldId: 'custrecord_eym_er_customer'
});
if ((context.fieldId == 'custrecord_eym_er_customer')) {
var client = recCurrent.getValue({
fieldId: 'custrecord_eym_er_customer'
});
console.log(client);
var sv = search.create({
type: "customrecord_eym_exhibit_reg",
columns: [
search.createColumn({
name: "internalid",
label: "Internal ID"
})
],
filters: [
["custrecord_eym_er_show", "anyof", show],
"AND",
["custrecord_eym_er_customer", "anyof", client]
]
});
var pagedData = sv.runPaged({
pageSize: 1000
});
// iterate the pages
for (var i = 0; i < pagedData.pageRanges.length; i++) {
// fetch the current page data
var currentPage = pagedData.fetch(i);
// and forEach() thru all results
currentPage.data.forEach(function(result) {
// you have the result row. use it like this....
var duplicate = result.getValue('internalid');
console.log(duplicate);
if (duplicate) {
alert('There is more than 1 entry for this client')
}
});
}
}
}
return {
fieldChanged: fieldChanged
};
});
You can change:
var pagedData = sv.runPaged({
pageSize: 1000
});
To
var pagedData = sv.run().getRanged({
start: 0,
end:1
});
The variable pagedData is an array contains the result, if you have many duplication you will have only the First result.
Also another way you can simply introduce a variable to print it once like this:
var printOnce = 0;
for (var i = 0; i < pagedData.pageRanges.length; i++) {
// fetch the current page data
var currentPage = pagedData.fetch(i);
// and forEach() thru all results
currentPage.data.forEach(function(result) {
// you have the result row. use it like this....
var duplicate = result.getValue('internalid');
console.log(duplicate);
if (duplicate && printOnce==0) {
printOnce++;
alert('There is more than 1 entry for this client')
}
});
}
I think the first approach is better since you don't need to retrieve all the data.
Try using a summary level grouping on the saved search results. Ex: If you're getting multiple internal ids, where 0 mean no duplicates, and 1+ means duplicates try changing
columns: [
search.createColumn({
name: "internalid",
label: "Internal ID"
})
],
to
columns: [
search.createColumn({
name: "internalid",
label: "Internal ID",
summary: 'GROUP'
})
],
And change
var duplicate = result.getValue('internalid');
to
var duplicate = result.getValue(name: 'internalid', summary: 'GROUP');
If I assumed incorrectly about the use of internal ids, add "Customer" or the desired grouped value as a column and use the summary grouping on that field.
There is a way to get the number of results returned by a search, in your case it seems you just want to show an alert of the search return at least one result so, you can use this code:
/**
*#NApiVersion 2.0
*#NScriptType ClientScript
*/
define(['N/record', 'N/search', 'N/ui/dialog'], function(r, search, u) {
function fieldChanged(context) {
var recCurrent = context.currentRecord;
var show = recCurrent.getValue({
fieldId: 'custrecord_eym_er_show'
});
var client = recCurrent.getValue({
fieldId: 'custrecord_eym_er_customer'
});
if ((context.fieldId == 'custrecord_eym_er_customer')) {
var client = recCurrent.getValue({
fieldId: 'custrecord_eym_er_customer'
});
console.log(client);
var sv = search.create({
type: "customrecord_eym_exhibit_reg",
columns: [
search.createColumn({
name: "internalid",
label: "Internal ID"
})
],
filters: [
["custrecord_eym_er_show", "anyof", show],
"AND",
["custrecord_eym_er_customer", "anyof", client]
]
});
if(sv.runPaged().count >= 1) {
alert('There is more than 1 entry for this client');
}
}
}
return {
fieldChanged: fieldChanged
};
});

NetSuite Invoice from Case

Hoping some one may be able to help me out with this error I am receiving... I am working a custom button on the case record that will create an invoice using fields from the case. I have a custom field that is a multi select of all items that can be needed as part of a case. Not all cases require an item, so I will code in logic or workflow to prevent the button from showing up if an item isn't selected and also lock editing and mark the case status as invoiced with a stage of closed once invoice has been created from the record. My problem is that when testing the suitelet I am getting an error when trying to set the subsidiary field and also department. Here is my error: ["type":"error.SuiteScriptError"."name":"INVALID_FLD_VALUE", "message":"You have entered an Invalid Field Value 2 for the following field: subsidiary"
The customer I am testing with is assigned the subsidiary with a internal Id of 2
Below is a portion of my code, I've tried removing quotes in sub value and also trying to set the subsidiary value using the current record.getValue. both throw the same error
function onRequest(context) {
var custom_id = context.request.parameters.custom_id;
var currentRecord = record.load({
type: record.Type.SUPPORT_CASE,
id: custom_id
});
var newRecord = record.create({
type: record.Type.INVOICE,
isDynamic: true
});
newRecord.setValue({
fieldId: 'customform',
value: 122
});
newRecord.setValue({
fieldId: 'entity',
value: currentRecord.getValue('entity')
});
newRecord.setValue({
fieldId: 'otherrefnum',
value: currentRecord.getValue('casenumber')
});
newRecord.setValue({
fieldId: 'subsidiary', value: '2'
});
newRecord.setValue({
fieldId: 'department',
value: '17'
});
newRecord.selectNewLine({
sublistId: 'item'
});
newRecord.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'item',
//value: 46
value: currentRecord.getValue('custevent_multi_select_work_orders')
});
newRecord.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'quantity',
value: '1'
});
}
Any help much appreciated!
Errors I found:
There is a typo when you are loading the Support Case Record. It should be SUPPORT_CASE
var currentRecord = record.load({
type: record.Type.SUPPORT_CASE,
id: custom_id
});
There are many typos like an inverted comma here, hope you look into it
newRecord.setValue({
fieldId: 'customform',
value: 122'
});
Regarding your main Subsidiary issue, you are passing value (2) using Inverted Commas. Try passing it without those
newRecord.setValue({
fieldId: 'subsidiary',
value: 2
});
OR
newRecord.setValue({
fieldId: 'subsidiary',
value: Number(2)
});
Use inverted commas only to pass String value. For Numerical value, don't use them.
Try these changes and let me know if the problem still persist, there are many possibilities to this error!
I know this isn't exactly what you need, but it is fully functioning and you can make customizations/pick-and-choose parts to use. It's a custom function I've used in the past to create a Sales Order from a Case Record. Best of luck!
/**
* case_createSOButton.js
* #NApiVersion 2.x
* #NScriptType ClientScript
*/
define (['N/record', 'N/currentRecord'],
function (record, currentRecord){
//NetSiuite requires the existence of 1 of their functions
function pageInit(context) {
var currentRecord = context.currentRecord;
}
//Button function to create a Sales order and indicate on the Case record the new Sales Order record
//in the UI on the Script record add this function name to the "Buttons" section
function createSO(){
log.audit('function started', 'Cases - Service Case CS createSO');
var caseRecord = currentRecord.get();
//if record is in create mode than do not allow creation of a Sales Order
//mode property is not available, so base it off of id properrty. ids dont exist until record is saved
var caseId = caseRecord.id;
if (!caseId){
alert('You cannot create a Sales Order while creating a new Case.\nPlease save the Case, then try again.');
return;
}
//if sales order already exists, do not allow creation of a new SO
var associatedSO = caseRecord.getValue({fieldId: 'custevent_case_associated_sales_orde'});
if (associatedSO){
alert('Cannot create a Sales Order since "Associated Sales Order" already exists.');
return;
}
//gather info from user
var memo = prompt("What's the reason for the charge?\nThe text below will be copied onto the Sales Order \"Memo\" field.");
//if user clicks cancel, do not continue
if (memo == null){
return;
}
var description = prompt("Enter a description for the Service Work Item.");
//if user clicks cancel, do not continue
if (description == null){
return;
}
var amount = prompt("Enter an amount for the Service Work Item.\nPlease only enter #s, no letters, decimal/cents optional.");
//if user clicks cancel or there's no # value found, do not continue
var hasNumber = /\d/; //validation for confirming the amount variable is a number
hasNumber = hasNumber.test(amount);
if (amount == null){
return;
}
if(hasNumber == false){
alert('No numbers found in entry, please try again.');
return;
}
alert('Please wait for the process to complete before closing this page.');
//declare static values
var customform = 199;
var subsidiary = 2;
var status = 3;
var specialist = 62736;
var channel = 181;
var totalKW = 0;
var lenderPoints = 0;
var today = new Date();
var itemId = 3566;
var lender = 10;
var loanProduct = 37;
//load customer to gather values
var entity = caseRecord.getValue({fieldId: 'company'});
var customerRec = record.load({type: record.Type.CUSTOMER, id: entity});
var location = customerRec.getValue({fieldId: 'custentity_customer_market'})|| null;
var job = caseRecord.getValue({fieldId: 'custevent_case_associated_project'});
//load associated project to gather values
var projectRec = record.load({type: record.Type.JOB, id: job});
var projectMgr = projectRec.getValue({fieldId: 'custentity_project_manager_customer'})|| null;
var engineer = projectRec.getValue({fieldId: 'custentity31'})|| null;
var installMgr = projectRec.getValue({fieldId: 'custentity_install_manager'})|| null;
var state = projectRec.getValue({fieldId: 'custentity_csegmarke'})|| null;
var region = projectRec.getValue({fieldId: 'custentity_cseg2'})|| null;
var market = projectRec.getValue({fieldId: 'custentity_cseg3'})|| null;
//create SO record, set values
var newSORec = record.create({type: record.Type.SALES_ORDER, isDynamic: true});
newSORec.setValue({fieldId: 'customform', value: customform, ignoreFieldChange: false});
newSORec.setValue({fieldId: 'entity', value: entity});
newSORec.setValue({fieldId: 'job', value: job});
newSORec.setValue({fieldId: 'custbody_sostatus', value: status});
newSORec.setValue({fieldId: 'custbody_total', value: totalKW});
newSORec.setValue({fieldId: 'custbody13', value: lenderPoints});
newSORec.setValue({fieldId: 'custbody_fundingissues', value: memo});
newSORec.setValue({fieldId: 'subsidiary', value: subsidiary});
newSORec.setValue({fieldId: 'custbody_finance_specialist', value: specialist});
newSORec.setValue({fieldId: 'saleseffectivedate', value: today});
newSORec.setValue({fieldId: 'custbody_cseglende', value: lender});
newSORec.setValue({fieldId: 'custbody_csegloan', value: loanProduct});
newSORec.setValue({fieldId: 'custbody_project_manager', value: projectMgr});
newSORec.setValue({fieldId: 'custbody_engineer', value: engineer});
newSORec.setValue({fieldId: 'custbody_installmgr', value: installMgr});
newSORec.setValue({fieldId: 'class', value: channel, forceSyncSourcing: true});
newSORec.setValue({fieldId: 'custbody_csegmarke', value: state, forceSyncSourcing: true});
newSORec.setValue({fieldId: 'custbody_cseg2', value: region, forceSyncSourcing: true});
newSORec.setValue({fieldId: 'custbody_cseg3', value: market, forceSyncSourcing: true});
newSORec.setValue({fieldId: 'location', value: location, forceSyncSourcing: true});
//set default line item(s)
newSORec.selectLine({sublistId: 'item', line: 0});
newSORec.setCurrentSublistValue({sublistId: 'item', fieldId: 'item', value: itemId, ignoreFieldChange: false});
newSORec.setCurrentSublistValue({sublistId: 'item', fieldId: 'description', value: description, ignoreFieldChange: false});
newSORec.setCurrentSublistValue({sublistId: 'item', fieldId: 'rate', value: parseInt(amount), ignoreFieldChange: false});
newSORec.commitLine({sublistId: 'item'});
//save new SO
var newSORecId = newSORec.save({enableSourcing: true, ignoreMandatoryFields: false});
//add SO Rec to Case
record.submitFields({
type: record.Type.SUPPORT_CASE,
id: caseRecord.id,
values: {
custevent_case_associated_sales_orde: newSORecId
},
options: {
//enableSourcing: false, //default is true
ignoreMandatoryFields : true //default is false
}
});
//alert user when SO is created and open in a new tab
alert("The new Sales Order will open in a new tab. \n*Reminder - to save this record if you've made changes.");
var url = 'https://1234567.app.netsuite.com/app/accounting/transactions/salesord.nl?id='+newSORecId
window.open(url, '_blank');
log.audit('function end', 'Cases - Service Case CS createSO');
}//end of create SO funciton
return {
pageInit: pageInit,
createSO: createSO
}
}
);

Trying to Set a Custom Field Value on a Customer, from a Custom Record Field

I'm struggling with a script that is supposed to:
Search for a list of Customer's
Get a couple of Field Values, one of which is used in the next Search, the other is the ID
Search for a list of Custom Records, the criteria being one of the fields I just fetched
Get a field value
And use the Customer ID fetched earlier to assign the Custom Record field value to a Custom field on the Customer.
But it is dropping out on the second search, saying that it is returning "undefined" due to invalid Search Criteria. I'm assuming that the field I get from the first search is not working in the Criteria of the second search?
My code is below - is it an obvious one (as usual), or is it literally the wrong way to go about this?
/**
*#NApiVersion 2.x
*#NScriptType ScheduledScript
*/
define(['N/search'],
function getShipSuburbId(search) {
function execute() {
var customerSearchObj = search.create({
type: "customer",
filters:
[
["custentity_store_shipping_suburb","isnotempty",""]
],
columns:
[
search.createColumn({
name: "entityid"
}),
search.createColumn({name: "custentity_store_shipping_suburb"})
]
});
var custSearchResult = customerSearchObj.runPaged({pageSize: 1000});
log.debug({title: "customerSearchObj result count", details: custSearchResult.count});
var custNumPages = custSearchResult.pageRanges.length;
var custAllResults = [];
var i = 0;
while (i < custNumPages) {
custAllResults = custAllResults.concat(custSearchResult.fetch(i).data);
i++;
}
return custAllResults;
for (var j = 0; j < custAllResults.length; j++) {
var currentRecord = custAllResults[j].getValue({
name: "entityid"
});
var shipSub = custAllResults[j].getValue({
name: "custentity_store_shipping_suburb"
});
};
var shipSubIdSearch = search.create({
type: "customrecord_suburb",
filters:
[
["name","is",shipSub]
],
columns:
[
search.createColumn({
name: "internalid",
summary: "MAX",
label: "Internal ID"
})
]
});
var allSubIdResults = shipSubIdSearch.runPaged({pageSize: 1});
log.debug({title: "shipSubIdSearch result count", details: allSubIdResults.count});
var subNumPages = custSearchResult.pageRanges.length;
var subAllResults = [];
var m = 0;
while (m < subNumPages) {
subAllResults = subAllResults.concat(allSubIdResults.fetch(m).data);
m++;
}
return subAllResults;
for (var k = 0; k < subAllResults.length; k++) {
var shipSubId = subAllResults[k].getValue({
name: "internalid"
});
};
var setSuburbId = currentRecord.setValue({
fieldId: 'custentity_shipping_suburb_id',
value: shipSubId
});
return setSuburbId;
}
return {
execute : execute
};
});
NEW CODE BELOW
/**
*#NApiVersion 2.x
*#NScriptType ScheduledScript
*/
define(['N/search', 'N/record'],
function getShipSuburbId(search, record) {
function execute() {
var customerSearchObj = search.create({
type: "customer",
filters:
[
["custentity_store_shipping_suburb", "isnotempty", ""]
],
columns:
[
search.createColumn({
name: "entityid"
}),
search.createColumn({name: "custentity_store_shipping_suburb"})
]
}); // The first search, which draws a list of Customers
var custSearchResult = customerSearchObj.runPaged({pageSize: 1000}); // Run paged
log.debug({title: "customerSearchObj result count", details: custSearchResult.count});
var custNumPages = custSearchResult.pageRanges.length;
var custAllResults = [];
var i = 0;
while (i < custNumPages) {
custAllResults = custAllResults.concat(custSearchResult.fetch(i).data);
i++;
}
for (var j = 0; j < custAllResults.length; j++) {
var currentRecord = custAllResults[j].getValue({
name: "entityid"
});
var shipSub = custAllResults[j].getValue({
name: "custentity_store_shipping_suburb"
});
log.debug({title: "currentRecord", details: currentRecord});
log.debug({title: "shipSub", details: shipSub});
// I've left this "for" operation open for the next search - possible issue?
var shipSubIdSearch = search.create({
type: "customrecord_suburb",
filters:
[
["name", "is", shipSub]
],
columns:
[
search.createColumn({
name: "internalid",
summary: "MAX",
label: "Internal ID"
})
]
}); // Second search. This should only return one result each time it is run
var subIdRun = shipSubIdSearch.run();
log.debug({title: "subIdRun result count", details: subIdRun.count});
var shipSubId = subIdRun.each(
function (result) {
log.debug({
title: "Fetch ID",
details: result.getValue({name: "internalid"})
})
return true;
});
log.debug({title: "shipSubId result", details: shipSubId});
var myRecord = record.load({
type: 'customer',
id: currentRecord
}); // Load the Customer record, based on the id fetched in the first search
log.debug({title: "myRecord", details: myRecord});
myRecord.setValue({
fieldId: 'custentity_shipping_suburb_id',
value: shipSubId
}); // And set the value of the Custom field, based on value from second search
}
}
return {
execute : execute
};
});
And screenshot of Execution Log on New Script:
I tried to edit some of your code to get your closer to the answer. I've left comments explaining steps you'll need to take.
Try this and let me know how it goes!
/**
*#NApiVersion 2.1
*#NScriptType ScheduledScript
*/
define(['N/search', "N/record"], function (search, record) {
function execute() {
let customers = [];
let storeShippingSuburbIds = [];
let storeShippingSuburbId;
let searchCustomers = search.create({
type: "customer",
filters:
[
["custentity_store_shipping_suburb", "isnotempty", ""]
],
columns:
[
search.createColumn({name: "entityid"}),
search.createColumn({name: "custentity_store_shipping_suburb"})
]
});
var pagedData = searchCustomers.runPaged({pageSize: 1000});
pagedData.pageRanges.forEach(function (pageRange) {
let page = pagedData.fetch({index: pageRange.index});
page.data.forEach(function (result) {
customers.push([
result.getValue({name: "entityid"}),
result.getValue({name: "custentity_store_shipping_suburb"})
])
storeShippingSuburbIds.push(result.getValue({name: "custentity_store_shipping_suburb"}));
return true;
});
});
/*
* I think you want the search operator of anyof here.
*/
search.create({
type: "customrecord_suburb",
filters:
[
["name", "anyof", storeShippingSuburbIds]
],
columns:
[
search.createColumn({
name: "internalid",
summary: "MAX",
label: "Internal ID"
})
]
}).run().each(function (result) {
storeShippingSuburbId = result.getValue(result.columns[0]);
});
/*
* You'll need to use record.load() here or record.submitFields(), depending on a few things.
* But, it won't work as it is because it doesn't know what the "current record" is.
*/
let myRecord = record.load();
myRecord.setValue({
fieldId: 'custentity_shipping_suburb_id',
value: storeShippingSuburbId
});
myRecord.save();
}
return {
execute: execute
};
});
I have found the best way to approach multiple levels of searching, is to gather the results of each search into an array.
Once I have finished dealing with the results of one search, then process each element of the array one by one, whether that be searching, querying, editing, etc.
The advantages of this include:
If a scheduled script, this allows me to check the governance usage after the first search, and reschedule with the array of results as a parameter if necessary.
Handling other logic like sorting or formulas on the array elements, before continuing with other operations.
Potentially faster processing, particularly if you don't need to process any further operations on some results of the first search.
This is just personal preference, but it makes it easier to split elements of the script into separate functions and maintain readability and logical sequence.

suitescript 2.0 : How to modify and save subrecord in clientscript

I'm trying to modify and save subrecord in clientscript, but when it is saved, I get the following error:
"Cannot read property 'invalidateCurrentSublistLineForSubrecordCache' of undefined"
Current code:
/**
* #NApiVersion 2.x
* #NModuleScope public
*/
define(['N/record','N/currentRecord','N/search'],
function(record,currentRecord,search) {
return({
stock: function(context) {
var curRec = currentRecord.get();
var ab_search = search.create({
type: search.Type.TRANSACTION,
title: 'YXZC_Assembly_Build_Search',
id: 'customsearch_yxzc_assembly_build_search',
columns: ['internalid'],
filters: [
['createdfrom', 'is', curRec.id],'and',['type','is','Build']
]
});
ab_search.save();
var searchResult = ab_search.run().getRange({
start: 0,
end: 1
})[0];
var internalid = searchResult.getValue(searchResult.columns[0]);
search.delete({
id: 'customsearch_yxzc_assembly_build_search'
});
var rec = record.load({
type: record.Type.ASSEMBLY_BUILD,
id: internalid,
// isDynamic: true,
});
var inventorydetailRec = rec.getSubrecord({
fieldId: 'inventorydetail',
});
var line = inventorydetailRec.getLineCount({
sublistId: 'inventoryassignment'
});
for (var i=0; i<line; i++){
inventorydetailRec.setSublistValue({
sublistId:'inventoryassignment',
fieldId: 'inventorystatus',
line: i,
value: '2'
});
};
var recId = rec.save({
enableSourcing: true,
ignoreMandatoryFields: true
});
}
});
});
I am not sure what invalidateCurrentSublistLineForSubrecordCache property means.
What does anyone know about why this error is occurring?
Try the record.submitFields()
See https://system.netsuite.com/app/help/helpcenter.nl?fid=section_4267283788.html
I have just stumbled upon your question since I had the same issue but found a solution by the help of #erictgrubaugh
Subrecords are read-only for client scripts. Clients scripts are able to delete a subrecord from a parent record, but they can not modify them. See Supported Deployments for Subrecord Scripting in the NetSuite help

NodeJS / Express 4 - Sqlite3 - Storing rowset into variable

I'm trying to store the rowset from the query below into a variable so I can play it into the view and loop through it.
I'm getting results from the DB, and can console.log them in the db.each block, and I thought I could generate my JSON object below and then store it - but it's not setting it for some reason and var data = "" just returns an empty string.
I am a bit baffled as to why - does anyone know where I am going wrong please?
Thank you for taking the time to read.
var express = require('express');
var router = express.Router();
var db = require('../lib/db.js');
/* GET contacts listing. */
router.get('/', function(req, res) {
var data = "";
db.serialize(function() {
var rowset = db.each("SELECT b.forename, b.surname FROM contacts a, contact_attributes b WHERE a.contact_id = b.contact_id", function(err, row) {
data = ' { "'+row.contact_id+'" : [ { "forename" : "'+row.forename+'", "surname" : "'+row.surname+'" } ] } ';
});
});
res.render('contacts', {
title: "Contacts",
active: "contacts",
contacts: JSON.stringify(data)
});
});
module.exports = router;
The database query runs asynchronously, executing the callback function once the query returns. Therefore, res.render is called after data gets set to empty string, but before it gets set to the result set.
Also, there is no need to JSON.stringify a string that you have already built as JSON.
The code executes as follows:
var data = "";
db.serialize
var rowset = db.each
res.render
DB query returns.
db.each callback function executes, which sets data based on the result set.
Try this:
db.serialize(function() {
var rowset = db.each("SELECT forename, surname FROM contacts a, contact_attributes b WHERE a.contact_id = b.contact_id", function(err, row) {
var data = ' { "'+row.contact_id+'" : [ { "forename" : "'+row.forename+'", "surname" : "'+row.surname+'" } ] } ';
res.render('contacts', {
title: "Contacts",
active: "contacts",
contacts: data
});
});
});
});
or, avoid the manual JSON stringification:
db.serialize(function() {
var rowset = db.each("SELECT forename, surname FROM contacts a, contact_attributes b WHERE a.contact_id = b.contact_id", function(err, row) {
var data = {};
data[row.contact_id] = [
{
forename: row.forname,
surname: row.surname
}
];
res.render('contacts', {
title: "Contacts",
active: "contacts",
contacts: data
});
});
});
});

Resources