SuiteScript Access Custom Field in Sublist - netsuite

I have added two fields to the contact sublist record of customers. Two boolean values. I checked the values to make sure that they would show but in code cannot access those values in SS 1 or SS 2 through a sublist line item, I am accessing like this "var statements = rec.getLineItemValue( 'contactroles', 'custentity_statements', "1" );". When I look in the object for the customer record and look in the "contactroles" sublist, I cannot see those columns. If I load the contact record in SS 1 I can see the columns. Any help with this would be great, I would like to do it in SS 2 but I am flexible, thanks

Not sure whether this helps, but you can retrieve the contact id, then load the contact record and check the field value. This is assuming the custom field showing in the contact sublist is a contact field. The documentation isn't too swift, but it looks as though not all sublist fields are supported for getFieldValue. This is in SS1, but if it does what you want we should be able to take the same idea and write it in SS2.
var rec = nlapiLoadRecord('customer','11499');
var conId = rec.getLineItemValue('contactroles', 'contact', 1);
var con = nlapiLoadRecord('contact',conId);
var statements = con.getFieldValue('custentity9');
console.log(statements); //T

Related

SuiteScript getting value from a saved search

I'm having an issue pulling the value of a column in SuiteScript v1.0. The search is looking at Cash Sales and is producing the results I want in the UI, but I am unable to get the value of one column in SuiteScript. I suspect it is because either the value comes from the 'Created From' doc, or because it is a drop down list. Any help would be greatly appreciated.
The search looks at Cash Sales where the Dept/Sales Channel (NS id department) doesn't match the Dept/Sales Channel of the Sales Order. The results are:
Type
Document Number
Created From : Dept/Sales Channel
In the UI, it is doing exactly what I hoped. However, when I loop thru the results in my v1.0 SuiteScript, I'm getting a null value for Dept/Sales Channel:
results.forEachResult(function(res){
var id = res.getId();
var docid = res.getValue('tranid');
var dept = res.getValue('channel');
nlapiLogExecution('DEBUG', 'Found result - '+docid+' ('+id+') - '+dept+'.');
docid and id are correct, but dept ends up being null. I've tried 'channel', 'deptartment' and column[3].value with no luck. What am I doing wrong?
Based on how you formatted this: "Created From : Dept/Sales Channel", I assume it is a joined column.
If it is, you need to do it this way:
var dept = res.getValue('department', "createdfrom");

How to get source list types of particular list/record field?

Here is I have two entity custom fields with list/record type,
custom_dev_j15 entity field has a custom source list (eg: one, two, three, four, etc)
custom_qa_v93 entity field has a standard source list as an object (eg: customer )
I've two vendor entity custom fields as stated in screenshots of question,
custentity473 --> customer is selected as list source
custentity474 --> custom_dev_j15_m_list as selected as list source ( which is custom list)
Here is snippet that i used to get the options of these fields,
// Snippet
var fieldDetails = {};
var record = nlapiCreateRecord("Vendor");
var field = record.getField("custentity473");
var selectoptions = field.getSelectOptions();
for ( var i in selectOptions) {
var Option = {
id : selectOptions[i].getId(),
label : selectOptions[i].getText()
}
Options.push(Option);
}
fieldDetail["options"] = Options;
But my need is to get source list information like name of the list source (customer or custom_dev_j15_m_list) via suitescript
any idea on how to get this information?
Thanks in advance
I'm not sure I understand this question for what you're trying to do.
In NetSuite almost always, you accommodate to the source list types because you know that's the type, and if you need something else (e.g. a selection which is a combination/or custom selection you'll use a scripted field)
Perhaps you can expand on your use case, and then we can help you further?

How to get contacts associated in a company if the Contact record has empty Company field in NetSuite

I am creating a script that needs to get the contacts associated to a company. The script needs to work for both Customers and Vendors.
You can attach a Contact to a Customer or Vendor from the record screen and by doing this you can attach a Contact with an empty Company field.
I can use the sublist contactroles if it is a Customer record but that sublist is not available for the Vendor record.
Is there a way to get the contact records via search? So using the screenshot above can a search get the following contacts: Aiden Somerhalder, Alex Wolfe and Gerrom Test Contact.
I'd create a saved search of Vendors/Suppliers.
Add a filter to your result: contact : name is not empty
Add a column to your result: contact : name
Add a column to your result: contact : internalId
This should give you a set that your script can iterate through.
You should be able to create a vendor or customer search and the search should return the company/name or more details. Just select as a filter or column:
Contact fields... Company
Perhaps something like this (Running from within the record):
var filters = [];
var columns = [];
filters.push(new nlobjSearchFilter('internalidnumber', null, 'equalto', [nlapiGetRecordId()]));
columns.push(new nlobjSearchColumn('entityid', 'contact', null));
var results = nlapiSearchRecord(nlapiGetRecordType(), null, filters, columns);

Updating sharepoint item multi lookup field via odata

I need some help sorting out some syntax for an update to a list item in sharepoint from an application. Here's a rundown on the situation :
There are two lists within this sp site. One list is a products list, and the second list is a pricing. The way these lists are setup however are a 1 to many scheme. One product can have many pricing records. The product then has a column against it that is a look up field that supports multiple values.
Using REST and oData I can query and get the pricing information easily enough now, but my problem is when I need to update the products record to add a price.
with regular lookup fields I normally just set the ID property for the object, then call the update and savechanges methods for that list. With the pricing column however supporting multiple records there is no ID to set, and the field is an array of sorts. Adding the pricing object (list item) and updating and savechanges doesn't actually save. No errors are thrown but the then when viewing the list it isn't actually saving.
How can I add a price lookup to my Product?
I wrote a small method to query through each price and add it's initial price to the product below for testing :
InventoryCatalogDataContext dc = new InventoryCatalogDataContext(_pushinTinSvc);
dc.Credentials = CredentialCache.DefaultCredentials;
List<PricingItem> pricing = (from q in dc.Pricing
select q).ToList<PricingItem>();
foreach (PricingItem price in pricing)
{
var query = (DataServiceQuery<ProductsItem>)
dc.Products
.Expand("Pricing")
.Where(p => p.Id.Equals(price.StockCodeId));
List<ProductsItem> prods = query.ToList<ProductsItem>();
ProductsItem product = prods[0];
product.Pricing.Add(price);
dc.UpdateObject(product);
}
try
{
dc.SaveChanges();
}
catch (Exception ex)
{
string stopHere = ex.Message;
}
I'm not sure if I'm doing something wrong or if this is a bug. If I inspect the item after the SaveChanges, the item still has the pricing item lookup attached, showing a count of 1. At the end of the code block, if I re-query for the product, at that point it even still has the pricing attached. But once the method finishes and returns to the UI, the pricing is no longer attached, the fields are empty when you look at the list in sharepoint, but the version does increment. So I'm a little lost...

What is the best way to retrieve distinct / unique values using SPQuery?

I have a list that looks like:
Movie Year
----- ----
Fight Club 1999
The Matrix 1999
Pulp Fiction 1994
Using CAML and the SPQuery object I need to get a distinct list of items from the Year column which will populate a drop down control.
Searching around there doesn't appear to be a way of doing this within the CAML query. I'm wondering how people have gone about achieving this?
Another way to do this is to use DataView.ToTable-Method - its first parameter is the one that makes the list distinct.
SPList movies = SPContext.Current.Web.Lists["Movies"];
SPQuery query = new SPQuery();
query.Query = "<OrderBy><FieldRef Name='Year' /></OrderBy>";
DataTable tempTbl = movies.GetItems(query).GetDataTable();
DataView v = new DataView(tempTbl);
String[] columns = {"Year"};
DataTable tbl = v.ToTable(true, columns);
You can then proceed using the DataTable tbl.
If you want to bind the distinct results to a DataSource of for example a Repeater and retain the actual item via the ItemDataBound events' e.Item.DataItem method, the DataTable way is not going to work. Instead, and besides also when not wanting to bind it to a DataSource, you could also use Linq to define the distinct values.
// Retrieve the list. NEVER use the Web.Lists["Movies"] option as in the other examples as this will enumerate every list in your SPWeb and may cause serious performance issues
var list = SPContext.Current.Web.Lists.TryGetList("Movies");
// Make sure the list was successfully retrieved
if(list == null) return;
// Retrieve all items in the list
var items = list.GetItems();
// Filter the items in the results to only retain distinct items in an 2D array
var distinctItems = (from SPListItem item in items select item["Year"]).Distinct().ToArray()
// Bind results to the repeater
Repeater.DataSource = distinctItems;
Repeater.DataBind();
Remember that since there is no CAML support for distinct queries, each sample provided on this page will retrieve ALL items from the SPList. This may be fine for smaller lists, but for lists with thousands of listitems, this will seriously be a performance killer. Unfortunately there is no more optimized way of achieving the same.
There is no DISTINCT in CAML to populate your dropdown try using something like:
foreach (SPListItem listItem in listItems)
{
if ( null == ddlYear.Items.FindByText(listItem["Year"].ToString()) )
{
ListItem ThisItem = new ListItem();
ThisItem.Text = listItem["Year"].ToString();
ThisItem.Value = listItem["Year"].ToString();
ddlYear.Items.Add(ThisItem);
}
}
Assumes your dropdown is called ddlYear.
Can you switch from SPQuery to SPSiteDataQuery? You should be able to, without any problems.
After that, you can use standard ado.net behaviour:
SPSiteDataQuery query = new SPSiteDataQuery();
/// ... populate your query here. Make sure you add Year to the ViewFields.
DataTable table = SPContext.Current.Web.GetSiteData(query);
//create a new dataview for our table
DataView view = new DataView(table);
//and finally create a new datatable with unique values on the columns specified
DataTable tableUnique = view.ToTable(true, "Year");
After coming across post after post about how this was impossible, I've finally found a way. This has been tested in SharePoint Online. Here's a function that will get you all unique values for a column. It just requires you to pass in the list Id, View Id, internal list name, and a callback function.
function getUniqueColumnValues(listid, viewid, column, _callback){
var uniqueVals = [];
$.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_layouts/15/filter.aspx?ListId={" + listid + "}&FieldInternalName=" + column + "&ViewId={" + viewid + "}&FilterOnly=1&Filter=1",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" }
}).then(function(response) {
$(response).find('OPTION').each(function(a,b){
if ($(b)[0].value) {
uniqueVals.push($(b)[0].value);
}
});
_callback(true,uniqueVals);
},function(){
_callback(false,"Error retrieving unique column values");
});
}
I was considering this problem earlier today, and the best solution I could think of uses the following algorithm (sorry, no code at the moment):
L is a list of known values (starts populated with the static Choice options when querying fill-in options, for example)
X is approximately the number of possible options
1. Create a query that excludes the items in L
1. Use the query to fetch X items from list (ordered as randomly as possible)
2. Add unique items to L
3. Repeat 1 - 3 until number of fetched items < X
This would reduce the total number of items returned significantly, at the cost of making more queries.
It doesn't much matter if X is entirely accurate, but the randomness is quite important. Essentially the first query is likely to include the most common options, so the second query will exclude these and is likely to include the next most common options and so on through the iterations.
In the best case, the first query includes all the options, then the second query will be empty. (X items retrieved in total, over 2 queries)
In the worst case (e.g. the query is ordered by the options we're looking for, and there are more than X items with each option) we'll make as many queries as there are options. Returning approximately X * X items in total.

Resources