Load Email messages attached to transaction Suitescript 2.0 - netsuite

I'm trying to load up all of the emails that have been sent from a transaction via SuiteScript 2.0.
When I run
record.getSublists()
it returns the following:
["item","activeworkflows","workflowhistory","custom8","messages","contacts","activities","usernotes","systemnotes","mediaitem","links","cases","partners","events","calls","tasks"]
However, when I then try to run the following:
record.getSublist('messages');
I receive an error.
I need to be able to check the date of the last email sent so I can determine whether or not to send a follow-up email.

The approach I typically take is to use the Search API to get this type of information:
require(['N/search'], function(search) {
var result = search.create({
type: 'transaction',
filters: [
['internalid', search.Operator.ANYOF, id], 'AND',
['mainline', search.Operator.IS, 'T'], 'AND',
['messages.messagetype', search.Operator.ANYOF, 'EMAIL'], 'AND',
['messages.isincoming', search.Operator.IS, 'F']
],
columns: [
search.createColumn({name: 'internalid', summary: search.Summary.GROUP}),
search.createColumn({name: 'messagedate', join: 'messages', summary: search.Summary.MAX}),
],
}).run().getRange({ start: 0, end: 1 });
var dateOfLastEmail = result[0].getValue({ name: 'messagedate', join: 'messages', summary: search.Summary.MAX });
});

Related

NetSuite SuiteScript 2.0 - nlobjSearchColumn contains an invalid column

I am trying to retrieve a specific system note below:
var noteSearch = search.create({
type: record.Type.NOTE,
columns: ['id', 'title', 'notetype', 'notedate', 'note'],
filters: [
search.createFilter({
name: 'id',
operator: search.Operator.EQUALTO,
values: 33
})
]
});
var noteSearchResultSet = noteSearch.run();
The error I'm getting:
{"type":"error.SuiteScriptError","name":"SSS_INVALID_SRCH_COL","message":"An nlobjSearchColumn contains an invalid column, or is not in proper syntax: id.","stack":["Error\n at Object.onRequest (...)"],"cause":{"type":"internal error","code":"SSS_INVALID_SRCH_COL","details":"An nlobjSearchColumn contains an invalid column, or is not in proper syntax: id.","userEvent":null,"stackTrace"
EDIT:
internalid has same error:
var noteSearch = search.create({
type: record.Type.NOTE,
columns: ['internalid', 'title', 'notetype', 'notedate', 'note'],
filters: [
search.createFilter({
name: 'internalid',
operator: search.Operator.EQUALTO,
values: 33
})
]
});
The note in question:
Try using another filter type: 'is' maybe. I guess the code below could work using either 'id' or 'internalid'.
var noteSearch = search.create({
type: record.Type.NOTE,
columns: ['internalid', 'title', 'notetype', 'notedate', 'note'],
filters: [
['internalid', 'is', 33]
]
});

Search for scheduled script instance by parameters passed to it

I want to search for a scheduled script or a map/reduce instance based on the parameters passed to it.
As in
search.create({
type: "scheduledscriptinstance",
filters: {
// What do I put here?
}
})
My goal is to stop an actively executing script if one exists for a specific user.
Per the NS Records Browser, Script Deployment Parameters aren't accessible via search joins, filters, or columns for the following record internal ids: scheduledscript, scheduledscriptinstance, scriptdeployment, and mapreducescript. I confirmed through the NS UI even if "store value" is selected for the parameter on the Script record, that there is no System Notes to refer to (to access previous parameter data) on either the Script or Script Deployment record. I think as a work around you can (from the triggering or receiving scripts) log the desired parameters. Then search the logs for the desired parameters.
//log parameter from receiving/triggered script
var script = runtime.getCurrentScript();
var paramName = 'custscript_paramName';
var paramValue = script.getParameter({name: paramName});
log.audit(paramName, paramValue);
//search for pertainent logs
var scriptexecutionlogSearchObj = search.create({
type: "scriptexecutionlog",
filters:[
["script.scripttype","anyof","SCHEDULED","MAPREDUCE"],
"AND",
["title","is", "custscript_paramName"] //paramName
],
columns:[
search.createColumn({name: "internalid", join: "script", label: "Script Internal ID"}),
search.createColumn({name: "scripttype", label: "Script Type"}),
search.createColumn({name: "name", join: "script", label: "Name"}),
search.createColumn({name: "internalid", label: "Internal ID"}),
search.createColumn({name: "type", label: "Type"}),
search.createColumn({name: "date", label: "Date"}),
search.createColumn({name: "time", label: "Time"}),
search.createColumn({name: "title", label: "Title"}),
search.createColumn({name: "detail", label: "Details"}),
search.createColumn({name: "user", label: "User"}),
search.createColumn({name: "view", label: "View"})
]
});
var searchResultCount = scriptexecutionlogSearchObj.runPaged().count;
scriptexecutionlogSearchObj.run().each(function(result){
// .run().each has a limit of 4,000 results
//Do Something
return true;
});

How to source just parent items in a select field on suitelet form (API 2.0)?

i am creating a suitelet form that will generate a pdf in POST. I need a field in my suitelet form, in which list of parent items can be selected(e.g. 1001 not 1001: 210-XL)for filtering purposes and all the items (child items) related to it can be printed in the PDF. Can anyone tell me what should i do?
It is not possible to add only Parent items in SELECT field on Suitelet.
You will need to add SELECT Field and then addSelectOption.
var select = form.addField({
id: 'selectfield',
type: serverWidget.FieldType.SELECT,
label: 'Select'
});
var itemSearchObj = search.create({
type: "item",
filters:
[
["parent.isinactive", "is", "F"],
"AND",
["formulatext: {parent}", "isnotempty", ""]
],
columns:
[
search.createColumn({
name: "parent",
summary: "GROUP",
label: "Parent"
}),
search.createColumn({
name: "internalid",
join: "parent",
summary: "GROUP",
label: "Internal ID"
})
]
});
itemSearchObj.run().each(function (result) {
select.addSelectOption({
value: result.getValue({
name: "parent",
summary: "GROUP",
label: "Parent"
}),
text: result.getValue({
name: "internalid",
join: "parent",
summary: "GROUP"
})
});
return true;
});
I hope, this will help.
You could try checking that the parent field is blank...? Not sure which record you are working with though, so that may or may not help.

Querying a result returned by mongoose in nodejs

I am relatively new to Node.js, Mongoose and MongoDB.
I want to perform filter functionality and want to filter products by criteria selected by the user.
Is it possible in Node.js to query a response returned by Mongoose?
Sample response from Mongoose as below:
[ { _id: 589860c21f9997fce3502f10,
title: 'Watch',
brand: 'PUMA2',
store: 'ZARA',
for: 'MALE',
size: '32',
colour: 'RED',
userId: '58a420cd7c77aca4b3ce34cd' },
{ _id: 5899bd33c28dbdf2b938f698,
title: 'Watch 2',
brand: 'PUMA',
store: 'ZARA',
for: 'MALE',
size: '32',
colour: 'RED',
userId: '58a420cd7c77aca4b3ce34cd' },
{ _id: 5899bd59c28dbdf2b938f69a,
title: 'Watch 4',
brand: 'PUMA',
store: 'ZARA',
for: 'MALE',
size: '32',
colour: 'RED',
userId: '5899bde3c28dbdf2b938f69e' }]
Now how can I query this response to select data based on brand.
For finding PUMA brand, then query will be
db.collection.find({'brand': 'PUMA'})
Thanks for help everyone, finally got nice plugin called array-query which helped me to achieve what I want.
https://www.npmjs.com/package/array-query

Recommended data-structure (for not querying nested data in node.js)

Mongo-DB doesn't support query with wildcards in a nested structure.
In a data-structure that looks like this:
Courses = [{
'name': 'Learning node.js in 1 day',
'roles': {
'team': { subscribed: [ 'User1' ] },
'participant': { subscribed: [ 'User1', 'User2' ] },
'host': { optional: true, subscribed: [] }
}
}]
We would need wildcard-lookup to find subscribers in different roles in order not to use a query like this:
{ $or : [
{"roles.team.subscribed": 'User1'},
{"roles.participant.subscribed": 'User1'}
{"roles.host.subscribed": 'User1'}
]}
Anyway this does not work if we have an open list of roles.
And if we change it to something like this:
'roles': ['team', 'participant', 'host'],
'subscribed': [
{'user':'User1', 'roles': ['team', 'participant']},
{'user':'User2', 'roles': ['participant']}
]
it gets similarly difficult to then find all participants of a course. Either way we have a problem to find all courses a user is subscribed to.
We think about creating a separate collection for subscriptions (back to relational):
{user_id: 'User1', course_id: '456', role: 'participant'}
{user_id: 'User1', course_id: '456', role: 'team'}
{user_id: 'User2', course_id: '456', role: 'participant'}
What is best practice?
We would like to be able to make all different sorts of queries and it seems difficult if it's buried in a nested structure...
Think this is quiet a fundamental question for data-stuctures in mongoDB.
If you don't want to change your structure I think I would do something like this using aggregation framework. In case your fields inside roles are not so many and not completely manageable by users, in that case I would suggest you to use an array in roles and unwind it.
Let's take your first structure:
Courses = [{
'name': 'Learning node.js in 1 day',
'roles': {
'team': { subscribed: [ 'User1' ] },
'participant': { subscribed: [ 'User1', 'User2' ] },
'host': { optional: true, subscribed: [] }
}
}]
Project fields in this way:
name, roles.team, roles.participant, roles.host
So you will end up with this structure
Courses = [{
'name': 'Learning node.js in 1 day',
'roles.team.subscribed': [ 'User1' ] ,
'roles.participant.subscribed': [ 'User1', 'User2' ] ,
'roles.host.subscribed': subscribed: []
}
}]
Then you can unwind subscribed field and get a cartesian product by subscribed, you need to unwind 3 times:
Courses = [
{
'name': 'Learning node.js in 1 day',
'roles.team.subscribed.values': 'User1' ,
'roles.participant.subscribed.values': 'User1',
'roles.host.subscribed.values': ''
}
},
{
'name': 'Learning node.js in 1 day',
'roles.team.subscribed.values': 'User1' ,
'roles.participant.subscribed.values': 'User2',
'roles.host.subscribed.values': ''
}
}
]
At the end you can match every role separately.
Of course you need to use aggregation framework, takes time to get use to it.

Resources