querying the System Notes in Netsuite - netsuite

I have been looking for a way to pull the records in the System Notes in NetSuite. The lines below throw an 'INVALID_RCRD_TYPE' error:
var columns = new Array();
columns[0] = new nlobjSearchColumn('internalid').setSort();
var results = nlapiSearchRecord('systemnote', null, null, columns);
I wonder how to reference the System Notes as the first argument of nlapiSearchRecord API. Obviously, it's not called systemnote.
A similar question has been posted here but the System Notes has been incorrectly referenced there.

systemnotes aren't available as record type which is evident from the record browser link
However, you can still get system notes fields using join searches on any record type in NetSuite
eg:
x = nlapiSearchRecord('vendor', null, null,
[new nlobjSearchColumn('date', 'systemNotes'),
new nlobjSearchColumn('name', 'systemNotes'), // Set By
new nlobjSearchColumn('context', 'systemNotes'),
new nlobjSearchColumn('newvalue', 'systemNotes'),
new nlobjSearchColumn('oldvalue', 'systemNotes'),
])
x[0].getValue('name', 'systemNotes'); //gives the set by value

Thanks for your responses guys. I finally managed to query the System Notes using the code below. I thought I should share it in case someone else wants to accomplish the same job. I created a RESTlet in NetSuite using the below code that returns the list of merged customer records merged after a given date.
I created a new search with ID customsearch_mergedrecords and in Criteria tab, added a filter on 'System Notes: NewValue' where the description is 'starts with Merged with duplicates:' and in the Results tab, I added the columns I needed.
Note that you need to create the new search on Customer, not on System Notes. System Notes is hooked up in the search using join (the second argument in nlobjSearchFilter constructor).
function GetMergedRecordsAfter(input) {
var systemNotesSearch = nlapiLoadSearch('customer', 'customsearch_mergedrecords');
var filters = new Array();
filters.push(new nlobjSearchFilter('date', 'systemNotes', 'notbefore', input.fromdate));
systemNotesSearch.addFilters(filters);
var resultSet = systemNotesSearch.runSearch();
var searchResultJson = [];
resultSet.forEachResult(function (searchResult){
var searchColumns = resultSet.getColumns();
searchResultJson.push({
ID: searchResult.getValue(searchColumns[0]),
Name: searchResult.getValue(searchColumns[1]),
Context: searchResult.getValue(searchColumns[2]),
Date: searchResult.getValue(searchColumns[3]),
Field: searchResult.getValue(searchColumns[4]),
NewValue: searchResult.getValue(searchColumns[5]),
OldValue: searchResult.getValue(searchColumns[6]),
Record: searchResult.getValue(searchColumns[7]),
Setby: searchResult.getValue(searchColumns[8]),
Type: searchResult.getValue(searchColumns[9]),
InternalId: searchResult.getValue(searchColumns[10])
});
return true;
});
return searchResultJson;
}

Related

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

SuiteScript 2.0 Add filters to saved search in script

I have a custom record that has a field for an item and a field for location. I have a saved search on that record that already has the columns I want and some beginning criteria that will always be needed. I want to use this search when I am on a Sales Order. I want to store an array of all the item internal ids and location ids on the lines and then pass that as a dynamic filter to this search in SuiteScript 2.0.
According to the documentation this can be done. On the search.Filter page it says "You create a search filter object with search.createFilter(options) and add it to a search.Search object that you create with search.create(options) or load with search.load(options)." However, I do not see any parameter on search.load for this nor a code example of adding it after the load. All examples of using search.Filter are in using it in the search.create function
Thank you for any help you can give.
You can push the filter object to the filters property of the search.
searchObj.filters.push(filterObj);
I will list the steps in a simple way so that you can understand it better.
After you get the hang of it,you can edit it the way you want
STEPS :
1.Load saved search (say objSearch )
2.Copy the filters from objSearch into a new array (say defaultFilters )
3.Create a new array (say customFilters ) to store the new filter and we push it into defaultFilters
4.At last, we copy the modified defaultFilters back into objSearch and run the saved search
//Load saved search into objSearch
var objSearch = search.load({
id: 'savedsearchid'
});
//Copy the filters from objSearch into defaultFilters
var defaultFilters = objSearch.filters;
var customFilters = [];
//We will add the new filter in customFilters
customFilters = ['postingperiod', 'ANYOF', '1'];
//We will push the customFilters into defaultFilters
defaultFilters.push(customFilters);
//We will copy the modified defaultFilters back into objSearch
objSearch.filters = defaultFilters;
//Run the saved search
var objSearch_run = objSearch.run().getRange({
start: 0,
end: 10
});
var mySearch = search.load({ id: '851' });
var defaultFilters = mySearch.filters;
var customFilters = {};
customFilters = {"name":"custrecord_customer","operator":"anyof","values":["64468"],"isor":false,"isnot":false,"leftparens":0,"rightparens":0};
defaultFilters.push(customFilters);
mySearch.filters = defaultFilters;

NetSuite Suite script - all columns for object

Is there a function in Suitescript using which we would get all the fields or columns belonging to the object (i.e. location, account, transaction etc.)
You can use the function getAllFields() of the record to retrieve all the fields for that record.
var fields = nlapiGetNewRecord().getAllFields()
// loop through the returned fields
fields.forEach(function(fieldName){
var field = record.getField(fieldName);
var fieldlabel = field.getLabel();
if(fieldlabel=='something'){
//do something here
return;
}
}
you can also get the list of available fields for a record here

Meteor: copy document to another collection and delete from original collection after 'expirationDate'

I am looking for an efficient way to publish blog posts if the expirationDate (which is a field in the blog document) has not passed the the current date.
The following is a simple working solution but please read below what I am aiming to do.
Meteor.publish('nonExpiredBlogs', function() {
var blogIds = []
var currentDate = new Date()
Blogs.find().forEach(function(doc) {
var expirationDate = doc.expirationDate
var hasExpDatePassed = (expirationDate - currenDate) < 0
if (hasExpDatePassed === false) { // expiration date is Not passed, get the doc _id
blogIds.push(doc._id)
}
});
return Blog.find({_id: {$in: {_id: blogIds}}});
}
I am wondering if there is an alternative where I dont need a 'forEach' function that may be quicker to compute.
For example, can I implement npm node-cron-jobs to check if the expirationDate has not passed servers current date, if so, simply copy the document to an 'Archive' collection and remove it from the Blogs collection.
I could use MongoDb's time to live for the delete operation, however, I dont know if or how the document can be copied to another collection first - This would be the ideal solution.
Just create query criteria which uses the $gt operator to compare documents that have the expirationDate field greater than the current date i.e. those documents that haven't yet expired:
Meteor.publish('nonExpiredBlogs', function() {
var currentDate = new Date();
return Blog.find({"expirationDate": {"$gt": currentDate}});
}

NetSuite: Create WorkOrder and Sublist with SuiteScript

NetSuite newbie here.
I have a SuiteScript that loads the results of a sales order query and then creates a work order for each of those results.
Is it possible to also create sublist items in the same stroke or will I have to load each new workorder and then create it that way? If so, any code samples for that? My little script is below.
I have attempted things with insertLineItem and nlapiSelectNewLineItem but no luck so far.
Thanks!
function example1() {
var arrSearchResults = nlapiSearchRecord(null, 'searchID', null,
null);
for ( var i in arrSearchResults) {
var searchResult = arrSearchResults[i];
// create work order records
var recWorkOrder = nlapiCreateRecord('workorder');
recWorkOrder.setFieldValue('quantity', '8');
recWorkOrder.setFieldValue('assemblyitem', itemInternalId);
// recWorkOrder.setFieldValue('options', internalId);
nlapiSubmitRecord(recWorkOrder);
//Create sublist items here?
}
var kilroy = 'was here';
}
Your approach is pretty good and there is no way to update everything in one shot analogous to a SQL statement or something.
The only thing I see about your SuiteScript is that two parts would be in a different order. You'd create your sublist records then you have to submit the sublist. After submitting the sublist then you submit the work order.
So like this:
... snipped above no changes
// recWorkOrder.setFieldValue('options', internalId);
//Create sublist items here?
//Submit the sublist records
//Submit the work order last to finalize the transaction
nlapiSubmitRecord(recWorkOrder);
}
var kilroy = 'was here';
}

Resources