I'm working on a NetSuite Saved Search using Kit/Package (Item) records that have multiple line items. For instance, each Kit/Package is comprised of two Item SKUs.
At the moment, my Saved Search is pulling in each Item SKU on its own individual line. How can I keep each Kit/Package on one line with the different Item SKUs pulled into their own columns? Can I create one column that always pulls in Item SKU #1 and another that always pulls in Item SKU #2?
The record I am looking to pull in is {memberitem}. Is there a way to tell it to pull in {memberitem}, {memberitem1}, and {memberitem2} into different columns?
First of all - the only way I see to have a search combining 2 member items on one row is to group the fields, i.e. - to create a summary search.
If you need this search to be used as a base for Advanced PDF Template, the only way is to write a script (as the summary Searches are not allowed in Advanced PDF/HTML templates).
Here I have created for you a suitelet script, that perform this PDF generation. Of course I have the xml inside the code, but you could load the pre-saved XML file from the file cabinet. Also, you could create a saved search and just load it in the script. Keep in mind that all the fields at ITEM level should be with summary type "GROUP"
/**
* #NApiVersion 2.x
* #NScriptType Suitelet
* #NModuleScope SameAccount
*/
define(['N/render','N/search'],
function(render, search) {
function onRequest(context) {
var kititemSearchObj = search.create({
type: "kititem",
filters: [
["type","anyof","Kit"]
],
columns: [
search.createColumn({
name: "itemid",
summary: "GROUP"
}),
search.createColumn({
name: "displayname",
summary: "GROUP"
}),
search.createColumn({
name: "salesdescription",
summary: "GROUP"
}),
search.createColumn({
name: "baseprice",
summary: "GROUP"
}),
search.createColumn({
name: "formulatext",
summary: "MAX",
formula: "CASE WHEN {memberline}=1 THEN {memberitem} ELSE null END"
}),
search.createColumn({
name: "formulatext",
summary: "MAX",
formula: "CASE WHEN {memberline}=2 THEN {memberitem} ELSE null END"
})
]
});
var myCustomObject = {
KitItems : []
};
kititemSearchObj.run().each(function(r){
var aRow = {
linenum : myCustomObject.KitItems.length + 1,
itemid : r.getValue({
name: "itemid",
summary: "GROUP"
}),
displayname : r.getValue({
name: "displayname",
summary: "GROUP"
}),
salesdescription : r.getValue({
name: "salesdescription",
summary: "GROUP"
}),
baseprice : r.getValue({
name: "baseprice",
summary: "GROUP"
}),
memberitem1 : r.getValue({
name: "formulatext",
summary: "MAX",
}),
memberitem2 : r.getValue({
name: "formulatext_1",
summary: "MAX",
})
};
myCustomObject.KitItems.push(aRow);
return true;
});
var renderer = render.create();
var xmlStr =
'<?xml version="1.0"?>\n'+
'<!DOCTYPE pdf PUBLIC "-//big.faceless.org//report" "report-1.1.dtd">\n' +
'<pdf>\n<body size="A4">\n'+
'<#if results.KitItems?has_content>'+
'<table><!-- start rows --><#list results.KitItems as line>'+
' <tr><td>${line.linenum}</td>'+
' <td>${line.itemid}</td>'+
' <td>${line.displayname}</td>'+
' <td>${line.salesdescription}</td>'+
' <td>${line.baseprice}</td>'+
' <td>${line.memberitem1}</td>'+
' <td>${line.memberitem2}</td>'+
' </tr>'+
' </#list>'+
'</table>'+
'</#if>'+
'</body>\n</pdf>';
renderer.templateContent = xmlStr;
renderer.addCustomDataSource({
format: render.DataSource.OBJECT,
alias: "results",
data: myCustomObject
});
var pdfResult = renderer.renderAsPdf();
pdfResult.name = 'kitItems.pdf';
context.response.writeFile({
file: pdfResult,
isInline : true
});
}
return {
onRequest: onRequest
};
});
Related
In official documentations, it's already shown how to do that. Below, an example that working fine:
Example: 1
LET documents = [
{ name: 'Doc 1', value: 111, description: 'description 111' },
{ name: 'Doc 2', value: 222, description: 'description 2' },
{ name: 'Doc 3', value: 333, description: 'description 3' }
]
FOR doc IN documents
UPSERT { name: doc.name, description: doc.description }
INSERT doc
UPDATE doc
IN MyCollection
But, I want to check different multiple keys for each document on UPSERT, like:
Example: 2
LET documents = [
{ name: 'Doc 1', value: 777, description: 'description 111' },
{ name: 'Doc 2', value: 888, description: 'description 2' },
{ name: 'Doc 3', value: 999, description: 'description 3' }
]
FOR doc IN documents
UPSERT {
{ name: doc.name, description: doc.description },
{ value: doc.value, description: doc.description },
{ name: doc.name, value: doc.value }
}
INSERT doc
UPDATE doc
IN MyCollection
Or, any other other way (using filter or something). I had tried but nothing works
If I understand your problem, you would want to update a document, if there's an existing one with at least 2 fields matching, otherwise insert it as new.
UPSERT won't be able to do that. It can only do one match. So a subquery is necessary. In the solution below, I ran a query to find the key of the first document that matches at least 2 fields. If there's no such document then it will return null.
Then the UPSERT can work by matching the _key to that.
LET documents = [
{ name: 'Doc 1', value: 777, description: 'description 111' },
{ name: 'Doc 2', value: 888, description: 'description 2' },
{ name: 'Doc 3', value: 999, description: 'description 3' }
]
FOR doc IN documents
LET matchKey= FIRST(
FOR rec IN MyCollection
FILTER (rec.name==doc.name) + (rec.value==doc.value) + (rec.description==doc.description) > 1
LIMIT 1
RETURN rec._key
)
UPSERT {_key:matchKey}
INSERT doc
UPDATE doc
IN MyCollection
Note: There's a trick with adding booleans together which works because true will be converted to 1, while false is zero. You can write it out explicitly like this: (rec.name==doc.name?1:0)
While this will work for you it's not a very effective solution. Actually there's no effective one in this case because all the existing documents need to be scoured through to find a matching one, for each document to be added/updated. I'm not sure what kind of problem you are trying to solve with this, but it might be better to re-think your design so that the matching condition could be more simple.
I have created a saved search to display serial numbers above is my saved search script but the problem while printing in sales order. it is printing all the serial numbers which are displayed in saved search but the requirement is the sales order pdf to only show the serial number for that particular sales order only
var customrecordserial_number_01SearchObj = search.create({
type: "customrecordserial_number_01",
filters:
[
["custrecord71","isnotempty",""],
"AND",
["name","isnotempty",""]
],
columns:
[
search.createColumn({name: "custrecord71", label: "Item Name"}),
search.createColumn({
name: "name",
sort: search.Sort.ASC,
label: "Name"
}),
search.createColumn({name: "custrecord70", label: "Item Fulfillment"})
]
});
var searchResultCount = customrecordserial_number_01SearchObj.runPaged().count;
log.debug("customrecordserial_number_01SearchObj result count",searchResultCount);
customrecordserial_number_01SearchObj.run().each(function(result){
// .run().each has a limit of 4,000 results
return true;
});
/*
customrecordserial_number_01SearchObj.id="customsearch1659425362410";
customrecordserial_number_01SearchObj.title=" Serial Number Record Search (copy)";
var newSearchId = customrecordserial_number_01SearchObj.save();
*/
I want to get the list of all the records(whether it may be entity record, transaction record or any other record) to which a single file is attached from the file cabinet in Netsuite. Is there any way to do so??
I believe the saved search approach is the best way. But I don't think you can do it by creating a Document saved search. I think you have to create an entity saved search, a transaction saved search, etc, and then put in the file ID into the criteria filter's "File fields..." internal ID field.
Having to create a saved search for each record type is a bit clunky, but if you have SuiteScript experience it helps if you have the "NetSuite: Search Export" chrome extension. You can create one saved search on the front-end and then use that extension to "Export as script" the one saved search and try to reproduce its criteria for each record type that you are interested in linking to the one file.
Let suppose you want to search a file for a Salesorder. You need to do it separate for entity, transaction etc, remove type and id for all records search.
Here is an example in 2.0.
var salesorderSearchObj = search.create({
type: "salesorder",
filters:
[
["type","anyof","SalesOrd"],
"AND",
["internalid","anyof",12345],
"AND",
["taxline","is","F"],
"AND",
["cogs","is","F"],
"AND",
["shipping","is","F"],
"AND",
["mainline","is","T"]
],
columns:
[
search.createColumn({
name: "trandate",
sort: search.Sort.ASC,
label: "Date"
}),
search.createColumn({
name: "internalid",
join: "file",
label: "Internal ID"
}),
search.createColumn({
name: "url",
join: "file",
label: "URL"
}),
search.createColumn({
name: "url",
join: "lineFile",
label: "URL"
})
]
});
var searchResultCount = salesorderSearchObj.runPaged().count;
salesorderSearchObj.run().each(function(result){
var fileId = result.getValue({
name: "internalid",
join: "file",
label: "Internal ID"
});
var fileObj = file.load({id: fileId});
return true;
});
I can able to search the case by company name
var mySearch = search.create({
type: search.Type.SUPPORT_CASE,
columns: [{
name: 'title'
}, {
name: 'company'
}],
filters: [{
name: 'company',
operator: 'is',
values: 'Test'
}]
});
return mySearch.run({
ld: mySearch.id
}).getRange({
start: 0,
end: 1000
});
But I am not able to search case by company id.
companyId is 115
Below are not working
i)
filters: [{
name: 'company',
operator: 'is',
values: 115
}]
ii)
filters: [{
name: 'companyid',
operator: 'is',
values: 115
}]
According to the Case schema company is a Text filter, meaning you would have to provide it with the precise Name of the company, not the internal ID.
Instead you may want to use the customer.internalid joined filter to provide the internal ID. Also, Internal ID fields are nearly always Select fields, meaning they do not accept the is operator, but instead require the anyof or noneof operator.
You can find the valid operators by field type on the Help page titled Search Operators
First, you can try this :
var supportcaseSearchObj = search.create({
type: "supportcase",
filters:
[
["company.internalid","anyof","100"]
],
columns:
[
search.createColumn({
name: "casenumber",
sort: search.Sort.ASC
}),
"title",
"company",
"contact",
"stage",
"status",
"profile",
"startdate",
"createddate",
"category",
"assigned",
"priority"
]
});
Second : how did I get this ? The answer is hint that will make your life easier :
Install the "NetSuite Saved Search Code Export" chrome plugin.
In Netsuite UI, create your saved search (it is always easier that doing it in code).
After saving the search, open it again for edition.
At the top right corner (near list, search menu in the netsuite page), you will see a link "Export as script" : click on it and you will get your code ;)
If you can not install the chrome plugin :
In Netsuite UI, create your saved search (it is always easier that doing it in code).
In your code, load your saved search
Add a log.debug to show the [loadedesearchVar].filters
You can then copy what you will see in the log to use it as your search filters.
Good luck!
Disclaimer: I'm a NetSuite newbie.
I need to return both the item and the vendor name for all items in a purchase order. I Googled around and found this search.
The search works as desired.
var purchaseorderSearchObj = search.create({
type: "purchaseorder",
filters: [
["type","anyof","PurchOrd"], 'and',
['mainline','is','F'],'and',
['tranId','is',targetTranId.toString()]
],
columns: [
search.createColumn(
{ name: "itemid", join: "item" }
)
]
});
Now I need to add the Vendor Name column to the search.
I look for the purchase order objects description, and found it here (http://www.netsuite.com/help/helpcenter/en_US/srbrowser/Browser2017_1/script/record/purchaseorder.html).
I then try to modify the search by doing something like:
columns: [
search.createColumn(
{name: "itemid",join: "item"},
{name: "vendorname", join "item"})
]
. . . with no good result. I've tried {name: "vendorname"}, { name: "vendorname", join: "vendor"}, and other permutations.
What properties should I use for the 'columns' attribute to return item and vendorname?
How do I learn which columns need joining?
You need to call search.createColumn() again to create a new column:
columns: [
search.createColumn(
{name: "itemid",join: "item"}),
search.createColumn(
{name: "vendorname", join: "item"})
]