Have been a developer for years, but just getting into NetSuite scripting. I wanted to start simple and create a script that would update the COMMENT field for all items on a purchase order. I started off by following the tutorial found here.
My modified script is below - it should update the MEMO field at the PO header and then every line's COMMENT field. I followed the steps in the article to save the script, create a Mass Update and then run it. In my criteria I set: "Transaction Number/ID" and "has keyword 90999" (just so it would only run on one specific purchase order). I confirmed my criteria was correct by clicking "Preview" and it only returns that one PO.
When I run the Mass Update, it runs fine and says it has been run successfully on 1 record (which is good). The MEMO field at the PO header DOES get updated, but the COMMENT field for each line does not. Am I doing something wrong or missing something simple? Is the getLineCount call not the correct one to use?
Note that I was doing all this in our Sandbox environment in case that makes any difference
UPDATE:
I know the getLineCount call is returning the correct number because if I move the poRec.setValue call inside the for loop, it gets run. So something must be wrong with my poRec.setSublistValue call?
/**
*#NApiVersion 2.0
*#NScriptType MassUpdateScript
*/
define(['N/record'],
function (record) {
function each(params) {
// Need to LOAD each record and SAVE it for changes to take effect
// LOAD the PO
var poRec = record.load({
type: params.type,
id: params.id
});
//var mainDepartment = poRec.getValue('department');
var mainDepartment = 'Hello World';
poRec.setValue({
fieldId: 'memo',
value: mainDepartment
});
// get a count of the line items
var lineCount = poRec.getLineCount({
sublistId: 'item'
});
// go through each of the line items and set the department to the main level department
for (var i = 0; i < lineCount; i++) {
poRec.setSublistValue({
sublistId: 'item',
fieldId: 'comment',
line: i,
value: mainDepartment
});
}
// SAVE the PO
poRec.save();
}
return {
each: each
};
});
There is no 'comment' field on the item sublist. The field you probably mean is 'description' (which expresses on searches as the line level 'memo' field - Netsuite for the win!)
Related
I am new to suitescript and trying to migrate our "units of measure" over to netsuite via suitescript.
I believe the best way to setup an on-demand script execution is 'AfterSubmit' on a user event script, is that accurate? I looked into a scheduled script, but that doesn't really run on demand since it waits for the scheduler.
My 'After Submit' function currently looks like this. I'm trying to create a record under Lists > Accounting > Units of Measure (Unit Type)
const afterSubmit = (scriptContext) => {
var unittype = record.create({ type: 'unitstype', defaultValues: { name: 'Weights' } }); }
When I run the script I get this error:
{"type":"error.SuiteScriptError","name":"INVALID_RCRD_INITIALIZE","message":"You have entered an invalid default value for this record initialize operation."
Is that because I need at least one item in the sublist? Can anyone help point me to the syntax needed to create the sublist item?
I think the use case determines "the best way to setup an on-demand script".
Personally I would make a Scheduled or Map/Reduce script and trigger it to run that on demand by using the "Save & Execute" feature on the script deployment in the UI, or task.create (to trigger it from another script). Scripts can also be executed using the Browser Console.
To resolve the error you received, the defaultValues parameter only works with specific records and fields, can reference Suite Answer Id 45152. Units Type is not a support record. So you need to create the record, set all required values, then save the record.
To create a new Unit of Measure the following should work
//create record
var newRec = record.create({
type: 'unitstype',
isDynamic: //optional
});
//set all desired main line/area values
newRec.setValue({
fieldId: 'name',
value: 'Weights',
ignoreFieldChange: true //Optional, if set to true, the field change and the secondary event is ignored. default is false
});
//set sublist values, if in standard mode
newRec.setSublistValue({
sublistId: 'uom', //Units in the UI
fieldId: '', //will need to set all the required sublist fields
line: 0,
value:
});
//set sublist values, if in dynamic mode
newRec.selectLine({
sublistId: 'item',
line: 3
});
newRec.setCurrentSublistValue({
sublistId: 'uom',
fieldId: '',
value: ,
ignoreFieldChange: true
});
newRec.commitLine({
sublistId: 'uom'
});
//save record for either mode
var newRecId = newRec.save({
enableSourcing: true, //Optional, if set to true, sources dependent field information for empty fields. default is false
ignoreMandatoryFields: true //Optional, if set to true, all standard and custom fields that were made mandatory through customization are ignored. default is false
});
For more information about dynamic and standard record, can reference Suite Answer Id 73792
I have a search in SuiteScript 2.0 that's working fine. But for each record the search brings back, I want to update a particular field (I use it elsewhere to determine that the record has been examined). It's potentially a very large result set, so I have to page it. Here's my code:
var sResult = mySearch.runPaged({pageSize: 10});
for (var pageIndex = 0; pageIndex < sResult.pageRanges.length; pageIndex++)
{
var searchPage = sResult.fetch({ index: pageRange.index });
searchPage.data.forEach(function (result)
{
var name = result.getValue({ name: "altname"})
result.setValue({
name: 'tracker',
value: new Date()
})
});
}
You can see where I have a call to result.setValue(), which is a non-existent function. But it shows where I want to update the 'tracker' field and what data I want to use.
Am I barking up the wrong tree entirely here? How do I update the field for each result returned?
As Simon says you can't directly update a search result, but you can use submitFields method.
This example is from NetSuite documentation:
var otherId = record.submitFields({
type: 'customrecord_book', //record Type
id: '4', // record Id
values: {
'custrecord_rating': '2'
}
});
This approach will save more governance than load and save the record.
AFAIK You can't directly update a search result and write the value back to the record, the record needs to be loaded first. The snippet doesn't say what the type of record it is you're searching for or want to load, but the general idea is (in place of your result.setValue line):
var loadedRecord = Record.load({type:'myrecordtype', id:result.id});
loadedRecord.setValue( {fieldId:'tracker', value: new Date() });
loadedRecord.save();
Keep in mind SuiteScript governance and the number of records your modifying. Load & Save too many and your script will terminate earlier than you expect.
Bad design: instead of using result.setValue inside the iteration, push those to an "update" array then after the data.forEach have another function that loops thru the update array and processes them there with record.submitFields()
Be careful of governance....
I'm working in NetSuite and I have a custom field on an estimate for the outside sales rep. When the record is submitted, I want the employee field under the Sales Team subtab to be set to the same value as the custom outside sales rep field. However, when I try to do this with a user event script, nothing happens. I am using the after submit function. Any suggestions? Here is what my code looks like:
function afterSubmit(scriptContext){
var record = scriptContext.newRecord;
var outsideSalesRep = record.getValue({
fieldId: 'custbody_bs_salesrep_outside'
});
record.setSublistValue({
sublistId: 'salesteam',
fieldId: 'employee',
line: 0,
value: outsideSalesRep
});
}
You have to do this in beforesubmit, not after (unless you're explicitly reloading the record and saving it again in your script). The record has already been written to the database in aftersubmit & the object returned by scriptContext.newRecord is essentialy readonly, that's why it's discarding the changes.
I try to create a copy of existing customer via script. To add it as a sub customer for other subsidiary. (eg US customer bought form amazon.CA)... anyway ...
I tried:
require('N/record', function (record) {
var customer = {
id: XXXXXX,
type: record.Type.CUSTOMER,
isDynamic: true /* I tried false too */
}
var new_customer = record.copy(customer);
var new_customer_data = {
subsidiary: XX,
parent: XXXXXX,
currency: XX
};
for (var key in new_customer_data) {
new_customer.setValue({
fieldId: key,
value: new_customer_data[key]
});
}
new_customer.save() /* ! this throws the exception "Please enter value(s) for: Customer ID" */
});
I checked the NS docs. but I found nothing related.
I could get the necessary fields (.getValue ... & and record.create ... ) but... record.copy is nicer :) and addresses remains attached to the new customer (when a copy is created trough UI).
thx!
update
After few hours of more researches I found that the issue is related to auto-generate numbers. More precisely, is related to 'Allow Override' option of order numbers for the customers. If it's set to false : the script works perfectly(I tested in sandbox). But if it's set to true it throws an exception. I did more tests. When the customer is copied (via script) the entityId is affect with the original customer entityId, that blocks the .save() action. If I set entityID to null it doesn't work either. When I set the entityId with any unique value .save() action works fine (but this is not a solution for me.. not yet :) ).
Maybe there is a record/context field that I should used to auto-generate a
new number e.g. "clone_rec.generate_new_CUSTOMER_ID = true " !? Some how Netsuite overrides that when a copy of customer is created via UI.
The name of the customer is unique and is also wiped out by the copy operation.
You need to enter the new company name (or first and last names for an individual). Something like:
var new_customer_data = {
subsidiary: XX,
parent: XXXXXX,
currency: XX,
companyname: 'some new company name',
autoname:true // this may not make a difference. Depends on how your account is configured.
};
I have a SS2 user event script which runs on after submit when an Item Fulfillment record is created.
There is a custom column field, custcol_sp_itf_cost with data type Currency, on the Item Fulfillment record. The field has Store Value checked.
The following code produces logging to show that it runs through the lines but doesn't set the value of the field. Does someone know why?
(I've removed the logging code here for brevity.)
function afterSubmit(context)
{
var lineCount = context.newRecord.getLineCount({ sublistId: 'item' });
for (var i = 0; i < lineCount; i++) {
context.newRecord.setSublistValue({
sublistId: 'item',
fieldId: 'custcol_sp_itf_cost',
line: i,
value: 1234
});
}
}
When running code in an afterSubmit event, the record has already been submitted to the database, so any attempt to update newRecord directly will not work. You've got two options:
Move your code to the beforeSubmit event, in which case, setSublistValue will work just like you're trying to do. This would be the recommended approach.
Load the newly created record with record.load() then call setSublistValue(), then call record.save(). You can get the record id from context.newRecord in the afterSubmit event.
The second option would NOT be the recommended approach since re-loading the record and saving it again is much slower than just updating your value in beforeSubmit and letting NetSuite save the record for you one time.