How to update custom column field on just created transaction - netsuite

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.

Related

NetSuite Mass Update script runs sucessfully, but nothing gets updated

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!)

Netsuite: "INVALID_RCRD_INITIALIZE","message":"You have entered an invalid default value for this record initialize operation."

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

SuiteScript Updating Search Result Fields

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....

How can I set the Sales Team employee on an estimate in NetSuite with a script?

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.

N/query column definition

I'm trying to get transaction data using the N/query module:
require([ 'N/query'],
function(query) {
var trxQuery = query.create({ type: query.Type.TRANSACTION });
trxQuery.columns = [
trxQuery.createColumn({ fieldId: 'externalid' }),
trxQuery.createColumn({ fieldId: 'account' }),
trxQuery.createColumn({ fieldId: 'fxamount' })
];
var results = trxQuery.run();
})
The help says next thing about setting of fieldId in creating the query column:
Obtain this value (fieldId) from the Records Browser.
1. Go to the appropriate record type.
2. Scroll until you see the Search Columns table.
3. Locate the appropriate value in the Internal ID column.
However, I get the following error:
{"type":"error.SuiteScriptError","name":"SSS_SEARCH_ERROR_OCCURRED","message":"Search error occurred: Field 'account' for record 'transaction' was not found." ...
The same thing happens for fxamount field.
How can I define query column in order to get data on Account and Amount (Foreign Currency) for transactions by using N/query module?
The N/query module allows you to use the same logic as the Analytics Workbooks feature in the UI. For some reason, these workbooks do not always have the same field names that are in the Record Browser. For my two cents, the N/search module is still the way to go. N/query appears to be much slower than N/search.
In the Workbook UI, you can click the info icon next to each field name and see the field ID needed for the query module.
In your example, fxamount for a search is probably foreigntotal in a query.
Also, there doesn't appear to be an account field at the top level transaction or transaction line level. At the Transaction Accounting Line level, there IS an account field.
I'm not sure if its the account field that you're looking for, but this code seems to work.
var trxQuery = query.create({
type: query.Type.TRANSACTION
});
trxQuery.columns = [
trxQuery.createColumn({ fieldId: 'id' }),
trxQuery.createColumn({ fieldId: 'transactionlines.accountingimpact.account' }),
trxQuery.createColumn({ fieldId: 'foreigntotal' })
];
var results = trxQuery.run();

Resources