Is there a way to retrieve an array or list of specific inventory items in NetSuite with one call? I can not seem to find any documentation regarding this. I have gone through the SuiteTalk training course and it does not contain any information on retrieving a list of items without the internalID.
On page 73 of this document there is a function getInventoryItemList(itemKeysArray) that is called with an array of inventory item id's. However this function does not exist anywhere and I am assuming is a custom function but they never show the code for it.
The only two ways I can see doing this would be to pull every single inventory item out of NetSuite and import the internalID's into our local database, this seems like a lot of extra work to me. Another option I thought of is to loop over an array of the line items and perform an ItemSearchBasic for every element and get the internalID that way, this seems like a worse idea than just storing them in the local database. I am hoping someone can confirm and show me if there is a much easier way of doing what I need.
Here is a version of what I use when I need to get the a list of items (minus company specific data). I just removed our data, and set it build/return an array. This is in SuiteScript 2.0, just FYI.
require(['N/search','N/record'],function(search,record){
function buildItemArray(){
var itemArray=[];
searchItems();
itemArray=runSearch(itemArray);
deleteSearch();
log.debug(itemArray);
}
function searchItems(context){
var itemSearch=search.create({
type:search.Type.INVENTORY_ITEM,
title:'Inventory_Item_Search',
id:'customsearch_inventory_item_search',
columns:['internalid','itemid'],
filters:['isinactive','is','F']
});
itemSearch.save();
}
function runSearch(itemArray){
var mySearch=search.load({id:'customsearch_inventory_item_search'});
mySearch.run().each(function(result){
var item={};
item.itemID=result.getValue({name:'itemid'});
item.internalID=result.getValue({name:'internalid'});
itemArray.push(item);
return true;
});
return itemArray;
}
function deleteSearch(){
search.delete({id:'customsearch_inventory_item_search'});
}
buildItemArray();
});
There are a number of ways to do that but the idea of collecting the item ids from the line items is the one I normally use.
You can then use GetList to retrieve details about each item.
Related
I'm evaluating the feasibility to replace parts of our SQL database with Firestore and so far it's been a pleasure!
I'm wondering what's the best way to provide bookmarkable links to a given page in a list? I've successfully implemented paging, and found out that I need to maintain
lastVisible: firebase.firestore.DocumentSnapshot[] = []
to be able to traverse back and forth the paginated list like this:
if (this._paginator._pageIndex - 1 in this.lastVisible) {
return ref.orderBy('date', 'desc').startAfter(this.lastVisible[this._paginator._pageIndex - 1]).limit(this._paginator.pageSize)
} else {
return ref.orderBy('date', 'desc').limit(this._paginator.pageSize)
}
If I understand correctly, I can feed either the whole doc or the value used by the index to the startAfter and startAt methods. Either way, to provide a a deeplink for the list, opened at page 245, I need to pass 245 values in the URL to be able to pull this one off?
Or then I need to requery all the items from 0 to xxx page and record all the last items?
Any thoughts how to best tackle this one?
Is there any way to just use the numeric indexes, that can be calculated from the page and page size?
I have a SSJS object/function that does a custom full text search, as the results need to be in a specific order defined by my client. This function works fine in the search results view. It has a method to build the search query (add the * and the AND and all that), a property that returns the sorted results and I just added a method that returns the HTML needed for the type ahead.
My object is called SortedSearchResults. It needs to be instantiated with the search query in order to get the results and the type ahead HTML. How would I code that in the the type ahead values, so I don'T end up creating one SortedSearchResults object each time a letter is added to the type ahead field?
Would I be better off with a session managed bean? Would that make it easier? Would it make it faster? The search is limited to a maxiumum of 15 results.
Sor far, I only used SSJS code, but I am not sure how what I should do to avoid a memory hole. Here is the current code:
//TODO Memory management???
var results = new SortedSearchResults( getComponent("inputSearch").getValue());
return results.typeAheadValues;
How can I optimize this code so I don'T create unecessary "var results"? Or is it OK that way???
Thanks :)
I have a view in couchDb that is defined like this
function (doc) {
if (doc.url) {
var a = new Date(doc.postedOn);
emit([a.toLocaleDateString(), doc.count, doc.userId], {
_id: doc.userId,
postTitle: doc.postTitle,
postSummary: doc.postSummary,
url: doc.url,
count: doc.count
});
}
};
This gives me the result in a format that I want.Sorted first by date then by count and then by userID.
However I have trouble querying it.What I want is to query this view just by userId.That is leave the date and the count parameter null.
_view/viewName?limit=20&descending=true&endkey=["","","userId"]
does not give me the desired result.
Should I be using list function to filter out the results of the view.Is there any impact on performance if I do this?
This quote from the definitive guide first gave me the idea that list functions could be used to filter and aggregate results.
The powerful iterator API allows for flexibility to filter and aggregate rows on the fly, as well as output raw transformations for an easy way to make Atom feeds, HTML lists, CSV files, config files, or even just modified JSON.
List function has nothing to do with your case. From the docs you've linked to yourself:
While Show functions are used to customize document presentation, List functions are used for same purpose, but against View functions results.
Show functions are used to represent documents in various formats, commonly as HTML page with nicer formatting. They can also be used to run server-side functions without requiring a pre-existing document.
To solve your problem just change the order of the emitted keys, putting userId first, i.e.:
[ doc.userId, a.toLocaleDateString(), doc.count ]
and update your query appropriately.
If changing the order of emitted keys is not an option, just create another view.
There's a bunch of questions on here related to pagination using CouchDB, but none that quite fit what I'm wondering about.
Basically, I have a result set ranked by number of votes, and I want to page through the set in descending order.
Here's the map for reference.
function(doc) {
emit(doc.votes);
}
Now, the problem. I found out that startkey_docid doesn't work on it's own. You have to use it in combination with startkey. The thing is, for the query, I don't use a startkey parameter (I'm not looking to restrict the results, just get the most->least). I was thinking I could just use startkey={{doc.votes}}&startkey_docid={{doc._id}} instead, but the number of votes for a document could have changed by the time someone clicks the "Next Page" link.
The way to solve this seemed obvious: just set startkey=99999999 so that it will return all documents in the database and I can just use startkey_docid to start at the one where we left off last time. Oddly, when I do that, the startkey_docid stopped working and just allowed all results to be returned again. Apparently startkey needs to exactly equal the key on the document whose _id is used in startkey_docid.
What I'm asking is whether anyone knows a workaround for using startkey_docid to page when the actual startkey could have changed by the time you want to use it? Should my application just lookup the document by _id and immediately use the doc.votes value hoping it hasn't changed in the few milliseconds between requests? Even that doesn't seem very reliable.
EDIT: Ended up switching to Mongo for the speed, so this question turned out to be kinda moot.
I have never done something like this but I think I have some idea how to do it. What you can do is to take a snapshot of the ratings and refer to it in every page. You probably want your view not to consume to much space, so you should not map separate copies of the documents with votes not changed after taking the snapshot. So, you can do the following:
Add some history of ratings with timestamp to your document.
Map the ratings AND history like this.
In your app get the current time: start_time = Date.now() and query all pages.
Cleanup the history older then the oldest active sessions.
The problem is that if you emit [votes, date] and try to paginate you will never know how many document you have to fetch to get desired number per page. There can always be some older version which you will have to skip, and you will have make next get from DB. Thats why you can consider emitting: [date, votes], read the view always twice -- for start_time and current time, and merge and sort the result (like in merge-sort).
Ad.1:
{ ...,
votes: 12,
history: [
{date: 1357390271342, votes: 10},
{date: 1357390294682, votes: 11}
]
}
Ad.2:
function (doc) {
emit([{}, doc.votes], null);
doc.history && doc.history.forEach(function(h) {
emit([h.date, h.votes], null);
});
}
Ad.3:
?startkey=[start_time, votes]&limit=items_per_page_plus1
?startkey=[{}, votes]&limit=items_per_page_plus1
Merge lists, sort by votes in your app (on in a list function).
If you will have problems with using start_docid then you can emit [date, votes, id] and query with the ID explicitly. Even when this particular doc changes its votes it will still be available in the history.
Ad.4:
If you emit [date, votes] then you can just get outdated history width: ?startkey=[0]&endkey=[oldest_active_session_time]&inclusive_end=false and update them with update handler:
function(doc, req) {
if (!doc || !doc.history) return [null, 'Error'];
var history = new Array();
var oldest = +(req.query.date);
doc.history.forEach(function(h) {
if (h.date >= oldest)
history.push(h);
});
doc.history = history;
return [doc, 'OK'];
}
Note: I have not tested it, so it is expected not to run without modifications :)
As far as I know CouchDB uses b-tree shadowing to make updates and in principle is should be possible to access older revisions of the view. I am not into the CouchDB design, so it is just a guess and there seems not to be any (documented) API for this.
I can't figure out any simple solution by now, but there are options:
Replicate not-so-often your sorting list to small dedicated db so it will be much more stale than stale=ok
Modify your schema in a way that you'll be able to sort by some more stable data. Look at the banking/ledger example in CouchDb guide: http://guide.couchdb.org/draft/recipes.html#banking. Try to log every vote and reduce them hourly for example. As a bonus you'll get a history/trends :)
I'm kind of surprised this question has been left unanswered because the functionality of CouchDB Futon basically does this when you are paginating through the results of a map function. I opened up firebug to see what was happening in the javascript console as I paginated and saw that for every set of paginated results it is passing the startkey along with startkey_docid. So although the question is how do I paginate without including startkey, CouchDB specifies that the startkey is required and demonstrates how it can work. The endkey is not specified, so if there is only one result for the specified startkey, the next set of paginated results will also contain the next key of the sorted results that do not match the startkey.
So to clarify a bit, the answer to this problem is that as you are paginating and keeping track of the startkey_docid, you also need to capture the startkey of the same document that will be the start of the next set of results. When you are calling the paginated results use both the captured startkey and startkey_docid as couchdb requires. Leave endkey off so that the results will continue on to the next key of the sorted results.
The usecase scenario for wanting to be able to paginate without specifying a key is kind of odd. So let's say that the start docid of the next paginated result did change it's key value drastically from a 9 to a 3. And we are also assuming that there is only one instance of the docid existing in the map results, even though it could potentially appear multiple times (which I believe is why the startkey needs to be specified). As the user is clicking the next button, the user's paginated results will have now moved from looking at rank 9 to rank 3. But if you are including the startkey in addition to the startkey_docid, the paginated results would just start all over at the beginning of the rank 9 results which is a more logical progression than potentially jumping over a large set of results.
I had the next code inside the delegate to create fields
delegate(SPList list)
{
list.Fields.Add(...);
//I teared off the other same strings
}
I invoked this code in the next way
modifyFunction.Invoke(list);
//modifyFunction is a previous delegate, that was declared like
//delegate void ModifyList(SPList list);
So, everything was fine, when I try to update item in this list.
But I had to dynamically add fields to the list soon. So, I changed my delegate like
delegate(SPList list)
{
CheckMethod(list);
}
void CheckMethod(SPList list)
{
if (!list.Fields.ContainsField(...))
{
list.Fields.Add(...);
}
}
After this modification (there was no modification in the code anymore) while trying to update an item of this list I have the next exception
Invalid data has been used to update the list item. The field you are trying to update may be read only
Such decisions like SPWeb.AllowUnsafeUpdates or SPSecurity.RunWithElevatedPrivileges didn't give any positive results. Where is the trick? I'll appreciate any help. Thank you.
It is a little bit hard to guess what your are exactly doing by analyzing the code parts that your are providing.
But I guess that you load the item from the list
then you modifiy the list by adding a new field.
And then you update the item.
Now, the problem, I guess, is that you have still the same reference to the item after the list has changed.
To solve this problem, you have to reload the item after the modification on the list and then call update on this item.