netsuite
netsuite copied to clipboard
Support non-record field results in saved search responses
TL;DR -- This exposes some additional search result information that is currently being dropped
Sometimes NS makes information available within saved search results that are not record fields. For example, you can run an InventoryItem search through the GUI that returns:
Location Available(the quantity available at the default location)Location Reorder Point(quantity at which you should reorder at the location)Location On Order(quantity on order for the location)
These aren't record fields, as you can see with a quick CTRL-f through the NS schema docs. There's no field named locationQuantityAvailable in the schema -- even though one comes back in the XML response to the saved search:
<platformCommon:locationQuantityAvailable>
<platformCore:searchValue>2.0</platformCore:searchValue>
<platformCore:customLabel>Qty - Available</platformCore:customLabel>
</platformCommon:locationQuantityAvailable>
They also aren't custom Formula results either (which NS doesn't seem to expose through Suitetalk).
Nor are they custom fields. This information is just default, standard-issue NetSuite.
For that reason, I think it's perfectly reasonable to have a search that returns them as results, and thus also reasonable to expect to be able to access them through the API.
I have a need to support them in my own projects, and think others would benefit from having access to them as well.
EDIT: tests pass for me locally

I hit a similar problem on my integration, though not via a saved search, just a basic search through the API.
Searching invoices, TransactionSearchRowBasic has a field closeDate, however Invoice doesn't, so searching via this gem essentially drops the column since it's not a field defined on the record class.
This PR seems to be a step towards making these search-only fields accessible, albeit faking them as custom fields, though I hit a few snags using it.
First, if the search is returning internalId (or probably externalId too), this PR seems to treat them as custom fields. That's likely because this gem doesn't define these as fields, so when this PR compares the returned columns to fields, it doesn't see a match, thus assuming they're "custom fields":
https://github.com/davidlaprade/netsuite/commit/bb09391509bf7ff94ae74294334fc6cf88d505f4#diff-68d7940fabf39ec307b04a06b31bc6faea22cf6405ffb43594618640c04e79dcR78
That line likely needs to check if attr_name is internal_id (or external_id) too.
Secondly, this PR seems to store the field name as internal_id of the custom field:
https://github.com/davidlaprade/netsuite/commit/bb09391509bf7ff94ae74294334fc6cf88d505f4#diff-68d7940fabf39ec307b04a06b31bc6faea22cf6405ffb43594618640c04e79dcR88
But for newer integrations (2013.2 and newer?), I believe custom fields should be referenced by script_id, based on:
https://github.com/NetSweet/netsuite/blob/438c233fc0ede0acbeb7f9fbe8c9d8004fb4654a/lib/netsuite/records/custom_field_list.rb#L103
Therefore, where I'm using 2020.2, if I try using this PR, the custom fields returned have a nil script_id but the internal_id matches the field name (:close_date), but because of my version, the CustomFieldList is assuming it'll receive custom fields with a script_id set, not internal_id:
https://github.com/NetSweet/netsuite/blob/438c233fc0ede0acbeb7f9fbe8c9d8004fb4654a/lib/netsuite/records/custom_field_list.rb#L19-L21
Perhaps this PR needs to conditionally set the field name to either script_id or internal_id based on the version used?
Alternatively, I wonder if it'd be better to model the search results as proper classes where you could define the fields each has, as opposed to an approach like this. I guess it'd come down to whether you'd expect to get instances of the record (ie. Invoice) back from a search, or instances of a search result (ie. TransactionSearchRowBasic) back. The former certainly makes it easier to then push changes back to NetSuite by manipulating the returned instance.
@cgunther if you can rebase this PR and fix it up to work with the conditions you mentioned, I can take a look at getting this merged.
Pretty sure this is handled by:
- https://github.com/NetSweet/netsuite/commit/1af5545658153d32c16615b84d269eea65b26f28
- https://github.com/NetSweet/netsuite/commit/676a618266a6bff8c89772c3b016e0404f837a25
Still need to double check and ensure there's nothing unique in this PR that needs to be included.
I'd agree, this is predominantly addressed by 676a618.