1

nlapi allows to use joins to refer to values in another record or a sublist, when searching for a record. E.g. if there is a record FOO

FOO: {
  type: 'rectype',
  field1: '111',
  sublists:
    bar: [
      {value: 1,}, {value: 2,}
    ]
}

I can search for this record with a query, provided there is a join, let's say, bar to the bar sublits:

nlapiSearchRecord('rectype', null,
  [
    ['field', 'equalto', 'bar',],
    'and',
    ['bar.value', 'equalto', '1',],
  ],
  [ new nlobjSearchColumn('anotherfield', null, null), ]
);

This works. And the question is: is there a way to find a record (the one from the example) by specifying more sublist values, like:

nlapiSearchRecord('rectype', null,
  [
    ['field', 'equalto', 'bar',],
    'and',
    ['bar.value', 'equalto', '1',],
    'and',
    ['bar.value', 'equalto', '2',],
  ],
  [ new nlobjSearchColumn('anotherfield', null, null), ]
);

I've tried numerous approaches with different expressions, but it finds nothing with such a query.

A more concrete example is to find a bomrevision, which has specific components and bomquantities (the commented code is just for demonstration purposes of some approaches with the filter expression I've tried):

nlapiSearchRecord('bomrevision', null, [
    ['isinactive', 'equalto', 'F',],
    'and',
    ['component.item', 'is', '4942',],
    'and',
    ['component.item', 'is', '4936',],
    //[
    //  'and',
    //  ['component.bomquantity', 'equalto', '38',],
    //],
    //'and',
    //[
    //  ['component.item', 'anyof', '4936',],
    //  'and',
    //  ['component.bomquantity', 'equalto', '38',],
    //],
  ],
  [ new nlobjSearchColumn('name', null, null), ]
);

Thank you

d.k
  • 4,234
  • 2
  • 26
  • 38

1 Answers1

1

I understand your question to be "How can I find items where the component list includes multiple specified items?"

The challenge here is that when you join to the component list, NetSuite returns a result for each line in the list. This means any line that contains 'Item 1' will not contain 'Item 2' and vice versa, so no result meets the criteria.

You can work around this using the following approach:

  1. Group the results by 'main' or 'parent' record ('FOO' or 'bomrevision' in your examples).
  2. Use NS_CONCAT to give a field in each result that contains values from all the sublist results. (Note that NS_CONCAT is undocumented, so use at your own risk).
  3. Use summary criteria formulae to inspect the concatenated field for each value of interest.

Example (tested with assembly items and their member items as I don't have access to an account with BOM revisions):

[
   ["type","anyof","Assembly"], 
   "AND", 
   ["min(formulatext: NS_CONCAT({memberitem.name}) )","contains","ITEM 1"], 
   "AND", 
   ["min(formulatext: NS_CONCAT({memberitem.name}))","contains","ITEM 2"]
] 

Or, for your 'bomrevision' (untested, adapted from above):

[
   ["min(formulatext: NS_CONCAT({component.item}) )","contains","4942"], 
   "AND", 
   ["min(formulatext: NS_CONCAT({component.item}))","contains","4936"]
]

Be aware that under some circumstances NetSuite will default to returning the text of a list field rather than the value. If this is the case (and the values shown in your example are internal IDs as I'm assuming), you may need to replace component.item with component.item.id, or change the search values to the text name instead.

There may be a more straightforward way of doing this so I'd be glad to hear from anyone with a better solution.


Edit in response to request in comments:

Here is the full code of a working example in my account:

var assemblyitemSearch = nlapiSearchRecord("assemblyitem",null,
[
   ["type","anyof","Assembly"], 
   "AND", 
   ["min(formulatext: NS_CONCAT({memberitem.name}) )","contains","ITEM 1"], 
   "AND", 
   ["min(formulatext: NS_CONCAT({memberitem.name}))","contains","ITEM 2"]
], 
[
   new nlobjSearchColumn("itemid",null,"GROUP").setSort(false), 
   new nlobjSearchColumn("displayname",null,"GROUP"), 
   new nlobjSearchColumn("salesdescription",null,"GROUP"), 
   new nlobjSearchColumn("formulatext",null,"MIN").setFormula("NS_CONCAT({memberitem})")
]
);

This is an Item search filtering by Member Items, as the closest thing in my account to the BOM Revisions in the example. The only change I have made is to replace the item names with "ITEM 1" and "ITEM 2". You would need to replace these with relevant items from your system.

I can go to a Sales Order page and open developer tools on my browser and add the above code to create a search, then append the following additional code to retrieve results and print out to the console:

var data = [];
assemblyitemSearch.forEach(r => {
    var vals = {};
    r.rawValues.forEach(v => {
        vals[v.name] = v.value
    });
    data.push(vals);
});
console.table(data); 

This returns a table with results exactly as expected.


Edit 2: Adding example using Sales Orders and Items as possibly more consistent between different accounts.

var salesorderSearch = nlapiSearchRecord("salesorder",null,
[
   ["type","anyof","SalesOrd"], 
   "AND", 
   ["trandate","within","thismonth"], 
   "AND", 
   ["min(formulatext: NS_CONCAT({item}))","contains","ITEM 1"], 
   "AND", 
   ["min(formulatext: NS_CONCAT({item}))","contains","ITEM 2"]
], 
[
   new nlobjSearchColumn("trandate",null,"GROUP"), 
   new nlobjSearchColumn("tranid",null,"GROUP"), 
   new nlobjSearchColumn("formulatext",null,"MIN").setFormula("NS_CONCAT({item})")
]
);
Krypton
  • 4,394
  • 2
  • 9
  • 13
  • I have that SuiteScript 1.0 api reference PDF and it contains no text `formulae`. The filter expression causes error 500 (with code: INVALID_SRCH_SUMMARY_TYP ) at least in a client script – d.k Aug 10 '22 at 17:35
  • sorry, found the text 'formula' in the PDF doc, looking into it – d.k Aug 10 '22 at 17:43
  • I guess, it won't work, because the doc (the PDF I mentioned) explicitly says: where 'customer' is the search join id used for the search field specified as filter name 'salesrep'. **The filter name in this case may not be a formula filter like “formulatext: ...**”. Which I understood as: formula filters may not be used with search joins Anyway, thank you for the suggestion about those formula and other stuff, didn't know about it – d.k Aug 10 '22 at 18:44
  • could you please provide a link to where can I read/see examples of those formula_type: formula_text, or aggregate_function(filter_identifier) ? – d.k Aug 10 '22 at 19:41
  • I have added a full working example to the answer. Working in my account, at least. It's possible that differences in settings between accounts may mean that this exact example could work in my account but not in yours. The concept is sound though. – Krypton Aug 10 '22 at 20:52
  • Thank you for the example, I'll try to figure out how to make it work in my case, **could you point me to a resource with documentation/examples on all this stuff like: min(), formulatext**? And preferrably the 'memberitem' too, I can't find anything like it in the docs at https://system.netsuite.com/help/helpcenter/en_US/srbrowser/Browser2020_1/script/record/assemblyitem.html The assembly item record seems to have no such join 'memberitem'. Possibly, it's something enabled on the per-account basis – d.k Aug 10 '22 at 21:36
  • 1
    I suspect that your account has the "Advanced Bill of Materials" setting enabled, and that that setting removes the "memberitem" sublist and replaces the functionality with "bomrevisions". I've added *another* example that may be more consistent across accounts. – Krypton Aug 11 '22 at 13:17
  • Thank you for helping. But I believe the answer to this question has to be: NOT POSSIBLE. I actually contacted NS support with an exact case, the bomrevision and components, they responded that there is no way to do it in one search. And your example with SO doesn't throw an error, but on my account, it finds nothing. I opened an SO with 2 items in it. The same one, 2 times. Then tried to run an nlapi search from the browser's console, found null. So in general, I'm sure now, it's not possible. And from my experience with NS, I know that it may work in certain, usually undocumented cases – d.k Aug 15 '22 at 09:57