SuiteScript - Search joining "Term" from "Vendor" - netsuite

I am doing a search of vendors and want to join in the Term to have the Term's name. The vendor has a field called terms which has the internalid of the Term. Term has a field called name which contains what I'm looking for.
I've tried just about every combination of building the column but I always get an error:
An nlobjSearchColumn contains an invalid column join ID, or is not in proper syntax: name.
Example of how I'm building the column:
search.createColumn({
name: "name",
join: "terms", // or Term, or Terms, none of it works
label: "termname" // or leave this out or Term or Terms or anything else nothing works
}
What is the right way to create a search for vendor that also includes the term's name?

If you'll look at the Records Browser, terms is not listed as a join on the vendor record. Just get terms as a column (name: 'terms') then when you retrieve the result, use getText instead of getValue.
searchResults[i].getText({
name: 'terms'
});

Related

How do I do a joined lookup with search.lookupFields()?

I'm trying to get some information about an item, including the item's subsidiary's logo, which naturally requires joining the item to the subsidiary.
The documentation for search.lookupFields says:
You can use joined-field lookups with this method, with the following syntax:
join_id.field_name
So, I duly request the fields I want, including a join on subsidiary:
require(['N/search'], function(search) {
var item = search.lookupFields({
type: search.Type.ITEM,
id: 2086,
columns: ['itemid', 'displayname', 'subsidiary.logo'],
});
log.debug(item);
});
itemid and displayname are fine, but when I try to join another record I get this error:
{
"type":"error.SuiteScriptError",
"name":"SSS_INVALID_SRCH_COLUMN_JOIN",
"message":"An nlobjSearchColumn contains an invalid column join ID, or is not in proper syntax: logo.",
"stack":["doLookupFields(N/search/searchUtil.js)","<anonymous>(adhoc$-1$debugger.user:2)","<anonymous>(adhoc$-1$debugger.user:1)"],
"cause":{
"type":"internal error",
"code":"SSS_INVALID_SRCH_COLUMN_JOIN",
"details":"An nlobjSearchColumn contains an invalid column join ID, or is not in proper syntax: logo.",
"userEvent":null,
"stackTrace":["doLookupFields(N/search/searchUtil.js)","<anonymous>(adhoc$-1$debugger.user:2)","<anonymous>(adhoc$-1$debugger.user:1)"],
"notifyOff":false
},
"id":"",
"notifyOff":false,
"userFacing":false
}
This seems to happen no matter which record and field I try to join. What am I missing?
Although you can return results from multi-select fields, you cannot join to fields on records referenced by multi-select fields (which the subsidiary field on the item record is). Also, you cannot search the logo field on the subsidiary record (not listed in Search Columns under Subsidiary in the NetSuite Records Browser).
This means you have to load the Subsidiary record to get the logo field. In other words:
require(['N/record', 'N/search'], function(record, search) {
var item = search.lookupFields({
type: search.Type.ITEM,
id: 2086,
columns: ['itemid', 'displayname', 'subsidiary'],
});
var subID = item.subsidiary[0].value; //internal id of *first* subsidiary
var subRec = record.load({
type: record.Type.SUBSIDIARY,
id: subID
});
var logo = subRec.getText('logo'); //gets the file name - use getValue to get its ID instead
});
Note that if multiple subsidiaries are set on the item, this only gets the values for the first one. You could iterate through the item.subsidiary result to handle values for multiple subsidiaries if required.
I believe you can't access to the subsidiary record from a lookupfield, you should do a proper search.
https://system.netsuite.com/help/helpcenter/en_US/srbrowser/Browser2018_2/script/record/item.html
You can only join to tables allowed in the Item search object. Try looking for "Subsidiary..." in the Search Results tab within the UI. It's not there. Use the Schema Browser to determine what fields and joins are available.
You cannot think of a NetSuite search as you would any regular SQL search. You have to be cognizant of which fields and which joins can be utilized via the search object.
As people have mentioned, the subsidiary is not a join field available from the item record, one way to achieve what you are trying to do is:
Make a lookup to get the internal id of the subsidiary belonging to the desired item.
Then make a lookup to get the internal id of the logo image (file cabinet image) belonging to the previous subsidiary.
Make another lookup/load the image file to get the URL of the image/logo
You can try to combine the above steps in a single saved search but I think you might need to load the image file to get the URL.
This won't answer your question, but this may help out in the future. The records browser shows everything that you can search and join on, columns and filters, and field IDs. Very useful when building out searches.
NetSuite Records Browser - 2018.2

Suitescript 2 list.addRows from search results that have a join

I have a Suitescript search that is returning the following columns.
{"columns":[{"name":"trandate","label":"Date","type":"date","sortdir":"ASC"},{"name":"refnumber","label":"Reference Number","type":"integer","sortdir":"NONE"},{"name":"closedate","label":"Date Closed","type":"date","sortdir":"NONE"},{"name":"custbody_eft_bill_payment","join":"payingTransaction","label":"EFT Bill Payment","type":"checkbox","sortdir":"NONE"},{"name":"tranid","join":"payingTransaction","label":"Check Number","type":"text","sortdir":"NONE"},{"name":"amount","label":"Amount","type":"currency","sortdir":"NONE"}]}
And I am using the list.addRows() method to display the results in a suitelet list where I have defined the columns using the list.addColumns() method but I have not been able to successfully get the columns that are created from a join. I also can find no documentation on how to include them. I have tried the following
list.addColumn({
id: 'payingTransaction.tranid',
label: 'Payment#',
type: ui.FieldType.TEXT,
})
list.addColumn({
id: 'tranid',
label: 'Payment#',
type: ui.FieldType.TEXT,
})
Any help would be appreciated!
Not sure if this will help, but when running through your results you can use one of two methods to get the resulting data:
Use the join in the getValue() call
results.getValue({name:"tranid",join:"payingTransaction"});
Grab the data by Columns
var columns=result.columns;
var tranid=result.getValue(columns[0]);
The first option will need to be told whether it is a join, group, etc...
The second option will just grab the resulting column, no matter whether it is a join, group, or anything else.

How to filter a view by id field in CouchDB?

I have a view which outputs the following JSON:
{"total_rows":26,"offset":0,"rows":[
{"id":"SIP-13","key":[1506146852518,"SIP-13"],"value":{"clientId":"CLIENT-2","orderCount":2}},
{"id":"SIP-12","key":[1506147024308,"SIP-12"],"value":{"orderCount":1}},
{"id":"SIP-14","key":[1506159901457,"SIP-14"],"value":{"orderCount":1}},
{"id":"SIP-15","key":[1506161053712,"SIP-15"],"value":{"clientId":"CLIENT-2","orderCount":2}},
{"id":"SIP-16","key":[1506448298050,"SIP-16"],"value":{"clientId":"CLIENT-3","orderCount":1}}
]}
...and I want to get the row with id: "SIP-15" here. How can I do that?
You have to use complex keys. The first field indexed can be anything and the second must be SIP-15.
Query :
?startkey=[null,"SIP-15"]&endkey=[{},"SIP-15"]

Dynamodb querying for list count

I have a dynamodb table which has following columns,
id,name,events, deadline
events is a list which contain number of events.
I want to scan/query for all the rows with following items as the result,
id, name, number of events.
I tried following way but didn't receive any value for number of events. Can someone show me where am I wrong.
var params = {
TableName: 'table_name',
ExpressionAttributeNames: {"#name": "name",
"#even": "events.length"
},
ProjectionExpression: 'id, #name, #even'
}
You cannot achieve what you want in this way. The entries in "ExpressionAttributeNames" are not evaluated as expressions.
The definition of "#even": "events.length" in "ExpressionAttributeNames" does not evaluate the expression event.length and assign it to the variable "#even". Instead it specifies "#even" as referring to a column named "events.length" or a table where "events" is an object that has a "length" attribute. Since your table has neither, you get nothing back.
From the DynamoDB documentation:
In an expression, a dot (".") is interpreted as a separator character in a document path. However, DynamoDB also allows you to use a dot character as part of an attribute name.
To achieve what you want, you will have to return the "events" column and calculate the length outside of the query, or define a new "eventsLength" column and populate and maintain that value yourself if you are concerned about returning "events" in each query.

loopback relational database hasManyThrough pivot table

I seem to be stuck on a classic ORM issue and don't know really how to handle it, so at this point any help is welcome.
Is there a way to get the pivot table on a hasManyThrough query? Better yet, apply some filter or sort to it. A typical example
Table products
id,title
Table categories
id,title
table products_categories
productsId, categoriesId, orderBy, main
So, in the above scenario, say you want to get all categories of product X that are (main = true) or you want to sort the the product categories by orderBy.
What happens now is a first SELECT on products to get the product data, a second SELECT on products_categories to get the categoriesId and a final SELECT on categories to get the actual categories. Ideally, filters and sort should be applied to the 2nd SELECT like
SELECT `id`,`productsId`,`categoriesId`,`orderBy`,`main` FROM `products_categories` WHERE `productsId` IN (180) WHERE main = 1 ORDER BY `orderBy` DESC
Another typical example would be wanting to order the product images based on the order the user wants them to
so you would have a products_images table
id,image,productsID,orderBy
and you would want to
SELECT from products_images WHERE productsId In (180) ORDER BY orderBy ASC
Is that even possible?
EDIT : Here is the relationship needed for an intermediate table to get what I need based on my schema.
Products.hasMany(Images,
{
as: "Images",
"foreignKey": "productsId",
"through": ProductsImagesItems,
scope: function (inst, filter) {
return {active: 1};
}
});
Thing is the scope function is giving me access to the final result and not to the intermediate table.
I am not sure to fully understand your problem(s), but for sure you need to move away from the table concept and express your problem in terms of Models and Relations.
The way I see it, you have two models Product(properties: title) and Category (properties: main).
Then, you can have relations between the two, potentially
Product belongsTo Category
Category hasMany Product
This means a product will belong to a single category, while a category may contain many products. There are other relations available
Then, using the generated REST API, you can filter GET requests to get items in function of their properties (like main in your case), or use custom GET requests (automatically generated when you add relations) to get for instance all products belonging to a specific category.
Does this helps ?
Based on what you have here I'd probably recommend using the scope option when defining the relationship. The LoopBack docs show a very similar example of the "product - category" scenario:
Product.hasMany(Category, {
as: 'categories',
scope: function(instance, filter) {
return { type: instance.type };
}
});
In the example above, instance is a category that is being matched, and each product would have a new categories property that would contain the matching Category entities for that Product. Note that this does not follow your exact data scheme, so you may need to play around with it. Also, I think your API query would have to specify that you want the categories related data loaded (those are not included by default):
/api/Products/13?filter{"include":["categories"]}
I suggest you define a custom / remote method in Product.js that does the work for you.
Product.getCategories(_productId){
// if you are taking product title as param instead of _productId,
// you will first need to find product ID
// then execute a find query on products_categories with
// 1. where filter to get only main categoris and productId = _productId
// 2. include filter to include product and category objects
// 3. orderBy filter to sort items based on orderBy column
// now you will get an array of products_categories.
// Each item / object in the array will have nested objects of Product and Category.
}

Resources