Using GEE code editor to create unique values list from existing list pulled from feature - code-editor

I'm working in the Google Earth Engine code editor. I have a feature collection containing fires in multiple states and need to generate a unique list of states that will be used in a selection widget. I'm trying to write a function that takes the list of state values for all fires, creates a new list, and then adds new state values to the new unique list. I have run the code below and am not getting any error messages, but the output is still statesUnique = []. Can anyone point me in the right direction to get the new list to populate with unique values for states?
My Code:
// List of state property value for each fire
var states = fire_perim.toList(fire_perim.size()).map(function(f) {
return ee.Feature(f).get('STATE');
}).sort();
print('States: ', states);
// Create unique list function
var uniqueList = function(list) {
var newList = []
var len = list.length;
for (var i = 0; i < len; i++) {
var j = newList.contains(list[i]);
if (j === false) {
newList.add(list[i])
}
}
return newList
};
// List of unique states
var statesUnique = uniqueList(states);
print('States short list: ', statesUnique)

Okay, I did not come up with this answer, some folks at work helped me, but I wanted to post the answer so here is one solution:
var state_field = 'STATE'
var all_text = 'All states'
// Function to build states list
var build_select = function(feature_collection, field_name, all_text) {
var field_list = ee.Dictionary(feature_collection.aggregate_histogram(field_name))
.keys().insert(0, all_text);
return field_list.map(function(name) {
return ee.Dictionary({'label': name, 'value': name})
}).getInfo();
};
var states_list = build_select(fire_perim, state_field, all_text)
print(states_list)

Related

How get Lot/Serial number in Netsuite SuiteScript 2.0 for Inventory Adjustment Transaction?

I'm trying to get the serial numbers from a inventory adjustment in a user event script. The following code works very well for me when the amount to adjust is positive, but not when it is negative.
var invDet = transaction.getSublistSubrecord({sublistId:'inventory',
fieldId:'inventorydetail',
line:x});
for(var y = 0; y = invDet.getLineCount('inventoryassignment'); y++) {
var lotNumber = invDet.getSublistValue({sublistId:'inventoryassignment',
fieldId:'receiptinventorynumber',
line:y});
log.debug('lotNumber', lotNumber);
}
When adjust quantity is negative, receiptinvetorynumber is empty
I have tried using field id equal to 'issueinventorynumber' or 'binnunber' but the returned value is empty.
I found the following comment in a NetsuiteHub forum...
In 2.0 the getValue call returns the internal ID of the serial/lot number and the getText equivalent does not work. Depending on the exact logic you need to execute for the obtained numbers you might need to call a subsequent saved search to obtain the actual serial/lot numbers and not internal IDs (an 'inventorynumber' search will do the trick).
I tried this...
try{
var internalId = invdet.getSublistValue({sublistId:'inventoryassignment',fieldId:'internalid', line:y});
search.create({type:'inventorynumber', filters:[
['internalid', 'is', internalId]
], columns:['inventorynumber']}).run().each(function (result) {
binText = result.getValue('inventorynumber');
log.debug('binText', binText);
});
} catch(e) {
log.debug('Error', e.message);
throw e.message;
}
I am too inexperienced to make this work. I appreciate any help you can give me.
Thanks.
The challenge is that this area of the NetSuite API is not well documented. However, I pushed through it through trial and error and search hours.
var invDet = transaction.getSublistSubrecord({sublistId:'inventory',
fieldId:'inventorydetail',
line:x});
for(var y = 0; y = invDet.getLineCount('inventoryassignment'); y++) {
var Qty = invdet.getSublistValue({sublistId:'inventoryassignment',
fieldId:'quantity',
line:y});
var lotNumber = '';
if(Qty < 0)
{
var ivnNumId = nvdet.getSublistValue({sublistId:'inventoryassignment',
fieldId:'issueinventorynumber',
line:y});
if(ivnNumId !== '')
{
var invNum = record.load({type: 'inventorynumber',id:ivnNumId});
lotNumber = invNum.getValue({fieldId: 'inventorynumber'});
}
}
else
{
lotNumber = invdet.getSublistValue({sublistId:'inventoryassignment',
fieldId:'receiptinventorynumber',
line:y});
}
log.debug('lotNumber', lotNumber);
}
This information was very helpful in ss1.0
I hope it is useful to someone

Why is array.push() not working correctly?

I have a function which returns an array of dishes from a firestore database.
With console.log I check that the dish I want to push is correctly formatted, then push it.
Finally I console.log the array to check if everything is alright.
Here is what I got:
https://image.noelshack.com/fichiers/2019/05/5/1549048418-arraypush.png
switch (type) {
case "Plats": {
this.nourritureCollection.ref.get().then(data => {
let platArray : Plat[] = [];
data.docs.forEach(doc => {
this.plat.name = doc.data().nourritureJson.name;
this.plat.price = doc.data().nourritureJson.price;
this.plat.ingredients = doc.data().nourritureJson.ingredients;
this.plat.type = doc.data().nourritureJson.type;
this.plat.availableQuantity = doc.data().nourritureJson.availableQuantity;
this.plat.isAvailableOffMenu = doc.data().nourritureJson.isAvailableOffMenu;
this.plat.imgUrl = doc.data().nourritureJson.imgUrl;
this.plat.temp = doc.data().nourritureJson.temp;
console.log(this.plat)
platArray.push(this.plat);
});
console.log(platArray)
return platArray;
});
break;
}...
plat is instantiated within my service component, I couldn't declare a new Plat() inside my function.
The expected result is that dishes should be different in my array of dishes.
You are updating this.plat in every iteration. So it will have n number of references in the array pointing to the same object, therefore, the values for all the array elements will be last updated value of this.plat
What you need is to create new Plat object for every iteration.
data.docs.forEach(doc => {
let plat: Plat = new Plat();
plat.name = doc.data().nourritureJson.name;
plat.price = doc.data().nourritureJson.price;
plat.ingredients = doc.data().nourritureJson.ingredients;
plat.type = doc.data().nourritureJson.type;
plat.availableQuantity = doc.data().nourritureJson.availableQuantity;
plat.isAvailableOffMenu = doc.data().nourritureJson.isAvailableOffMenu;
plat.imgUrl = doc.data().nourritureJson.imgUrl;
plat.temp = doc.data().nourritureJson.temp;
console.log(plat)
platArray.push(plat);
});
As pointed out in the comment, you can only use new Plat() if Plat is a class, if it is an interface, just let plat:Plat; would do.

setting context with list of objects as prameters in dialogflow

I have a list of values each having another KEY value corresponding to it, when i present this list to user, user has to select a value and agent has to call an external api with selected value's KEY. how can i achieve this in dialogflow?
I tried to send the entire key value pair in the context and access it in the next intent but for some reason when i set a list(array) to context parameters dialogflow simply ignoring the fulfillment response.
What is happening here and is there any good way to achieve this? I am trying to develop a food ordering chatbot where the category of items in menu is presented and list items in that menu will fetched when user selects a category, this menu is not static thats why i am using api calls to get the dynamic menu.
function newOrder(agent)
{
var categories = []
var cat_parameters = {}
var catarray = []
const conv = agent.conv();
//conv.ask('sure, select a category to order');
agent.add('select a category to order');
return getAllCategories().then((result)=>{
for(let i=0; i< result.restuarantMenuList.length; i++)
{
try{
var name = result.restuarantMenuList[i].Name;
var catid = result.restuarantMenuList[i].Id;
categories.push(name)
//categories.name = catid
cat_parameters['id'] = catid;
cat_parameters['name'] = name
catarray.push(cat_parameters)
}catch(ex)
{
agent.add('trouble getting the list please try again later')
}
}
agent.context.set({
name: 'categorynames',
lifespan: 5,
parameters: catarray, // if i omit this line, the reponse is the fultillment response with categories names, if i keep this line the reponse is fetching from default static console one.
})
return agent.add('\n'+categories.toString())
})
function selectedCategory(agent)
{
//agent.add('category items should be fetched and displayed here');
var cat = agent.parameters.category
const categories = agent.context.get('categorynames')
const cat_ob = categories.parameters.cat_parameters
// use the key in the catarray with the parameter cat to call the external API
agent.add('you have selected '+ cat );
}
}
The primary issue is that the context parameters must be an object, it cannot be an array.
So when you save it, you can do something like
parameters: {
"cat_parameters": catarray
}
and when you deal with it when you get the reply, you can get the array back with
let catarray = categories.parameters.cat_parameters;
(There are some other syntax and scoping issues with your code, but this seems like it is the data availability issue you're having.)

Inventory Assignment Sublist doesn't react to Suitescript

I'm currently having some trouble with Client-Side Scripting of an Inventory Detail Subrecord on an Assembly Build. As you know, Assembly Builds have two Inventory Details. The one in the top right corner works as expected, and I can access every field with Suitescript.
I'm having trouble with the bottom Inventory Detail though. I'm able to access it and use nlapiGetFieldValue() just fine. However, when I access the sublist, I am only able to look up the value of 'id'.
These are the fields that are supposed to exist, along with a less documented one called "receiptinventorynumber".
Here is my code:
//get the line items in the bottom inventory details
var bottom_line_items = [];
for(var line_index = 0; line_index < nlapiGetLineItemCount("component"); line_index++)
{
var bottom_inv_detail = nlapiViewLineItemSubrecord("component", 'componentinventorydetail', line_index+1);
if(bottom_inv_detail != null)
{
var bottom_line_count = bottom_inv_detail.getLineItemCount('inventoryassignment');
for(var index =0; index < bottom_line_count; index++)
{
bottom_inv_detail.selectLineItem('inventoryassignment', index+1);
var sn = bottom_inv_detail.getCurrentLineItemValue('inventoryassignment', 'receiptinventorynumber');
bottom_line_items.push(sn);
}
}
}
console.log(bottom_line_items);
Here is the result of executing it in the browser console:
As you can see, 'id', and 'internalid' work. 'receiptinventorynumber' does not. Neither do any of the other fields.
Because of my use case, I cannot wait for the record to be saved on the server. I have to catch this client side. Any suggestions are appreciated.
It has been a long time since I have worked with Inventory Detail subrecord, but I think there is another field called 'assigninventorynumber'. Have you tried using that?
Just was able to answer my own question, but it did end up involving a server-side search. I'm pretty sure it works as I wanted it to, but I am still involved in testing it. In essence, I grabbed the field 'issueinventorynumber', which had an id. That id was the internalid of a 'Inventory Serial Number', which I was able to perform a search for to get the actual number. Here's the resulting code:
//get the line items in the bottom inventory details
var bottom_line_ids = [];
for(var line_index = 0; line_index < nlapiGetLineItemCount("component"); line_index++)
{
var bottom_inv_detail = nlapiViewLineItemSubrecord("component", 'componentinventorydetail', line_index+1);
if(bottom_inv_detail != null)
{
var bottom_line_count = bottom_inv_detail.getLineItemCount('inventoryassignment');
for(var index =0; index < bottom_line_count; index++)
{
bottom_inv_detail.selectLineItem('inventoryassignment', index+1);
var sn = bottom_inv_detail.getCurrentLineItemValue('inventoryassignment', 'issueinventorynumber');
bottom_line_ids.push(sn);
}
}
}
//do search to identify numbers of bottom serial numbers
var columns = [new nlobjSearchColumn('inventorynumber')];
var filters = []
for(var index = 0; index < bottom_line_ids.length; index++)
{
filters.push(['internalid', 'is', bottom_line_ids[index]]);
filters.push('or');
}
//remove the last 'or'
if(filters.length > 0)
{
filters.pop();
}
var search = nlapiCreateSearch('inventorynumber', filters, columns);
var results = search.runSearch().getResults(0,1000);
bottom_line_items = []
if(results.length != bottom_line_ids.length)
{
//if you get to this point, pop an error as the 'issueinventorynumber' we pulled is associated with multiple serial numbers
//you can see which ones by doing a 'Inventory Serial Number' Saved Search
//this is a serious problem, so we'd have to figure out what to do from there
}
for(var index = 0; index < results.length; index++)
{
bottom_line_items.push(results[index].getValue('inventorynumber'));
}
console.log(bottom_line_items);

Column Value in search api

I want to get the value from a Item sublist of Sales Order record.
But unable to get it. Though I can get the value of entity fields of the SO record.
Below is the snippet of the code:
var filters = new Array();
filters[0] = new nlobjSearchFilter("mainline",null,"is","T");
var column=new Array();
column[0] = new nlobjSearchColumn("trandate");
column[1] = new nlobjSearchColumn("item");
column[2] = new nlobjSearchColumn("cust_col_1");
var result = nlapiSearchRecord('salesorder', null, filters, column);
for(var i = 0; i<result.length; i++)
{
var col = result[i].getAllColumns();
var date = result[i].getFieldValue("trandate"); //I get this
var item_id = result[i].getLineItemValue("item", "item", i+1); // I don't get this
var cust_col = result[i].getLineItemValue("item", "cust_col_1", i+1); //I don't get this
}
I think I am defining the columns wrong.
This part
var item_id = result[i].getLineItemValue("item", "item", i+1); // I don't get this
var cust_col = result[i].getLineItemValue("item", "cust_col_1", i+1); //I don't get this
is also wrong, you use this syntax if you have loaded the record but for search results you just use
result[i].getValue('cust_col_1")
By specifying the filter new nlobjSearchFilter("mainline",null,"is","T"), you're basically telling the search that you don't want any line item data. This means that you will be unable to read any column data, custom or otherwise.
The mainline filter parameter has basically three options, 'F' means you want the line item details. 'T' means you just want the header data. Leaving this filter out will return one row for the header information and one row for each line item on the transaction.

Resources