Search not working on item record - netsuite

I am not able to get the list of item.I am using a saved search and want to create a list of all the item record id from it.
But it is not working.
my code
var loadSearch=nlapiLoadSearch('item','customsearch12');
var getData = loadSearch.runSearch();
var itemCol=new Array();
for(var i=0;i<getData.length;i++)
{
itemCol.push(getData[i].getId());
}
Can somebody help me with this

try this code
var loadSearch=nlapiLoadSearch('item','customsearch12');
var getData = loadSearch.runSearch();
var itemCol=new Array();
getData.forEachResult(function (searchRow) {
itemCol.push(searchRow.getId());
return true;
});
when you use a nlapiLoadSearch, the result is nlobjSearchResultSet and not an array like in the case of nlapiSearchRecord.
if you use nlapiSearchRecord, then you can loop through the result like you were trying in your code, i.e. using index

The answer given above by Nitish is perfectly correct but you need to consider one more thing.
nlapiLoadSearch api returns 4000 records at a time.
The nlapiSearchRecord api returns only 1000 records at a time , so what if your saved search consists of more than 1000 records.
So you will miss those extra items.
so here is the code to have better results
//Searching the items
var searchResults = nlapiSearchRecord('item', 'customsearch12',null,null);
var searchedItemId;
var lastId;
var completeResults = new Array();
var arrNewFilters=[];
if (searchResults != null) {
completeResults = completeResults.concat(searchResults);
}
else {
completeResults = null;
nlapiLogExecution('Debug', 'No item found',
weight + ' Null result');
}
if (completeResults != null) {
if (searchResults.length == 1000) {
while (searchResults.length == 1000) {
//Initialize variable
lastId = "";
//Get Record Id of Last record,
//to search the item record again from that record
lastId = searchResults[999].getId();
//start after the last id searched
arrNewFilters.push(new nlobjSearchFilter("internalidnumber",
null, "greaterthan", lastId));
//Lets search again
var searchResults = nlapiSearchRecord('item', 'customsearch12',
arrNewFilters, null);
if (searchResults != null) {
//Append the search result to the result present before
completeResults = completeResults.concat(searchResults);
}
}
}
for (var result = 0; result < completeResults.length; result++) {
//Loop through the items
}
Hope you got me Nitish!!!

Here's a sample of how to fetch over 1k of results in NetSuite/NetScript.
The search "customsearch_tel_tg_by_trunk_type" is not really relevant.
Complete sample of 1k+ results fetch in NetSuite/NetScript

You could get all the results one by one using a callback function till all the records are iterated.
var search = nlapiLoadSearch('item','customsearch12');
var resultSet = loadSearch.runSearch();
var itemCol=new Array();
resultSet.forEachResult(function (iterator) {
itemCol.push(iterator.getId());
return true;
});
or you could load few records of it using the getResults of the nlobjResultSet
var search = nlapiLoadSearch('item', 'customsearch12');
var resultSet = search.runSearch();
var results = resultSet.getResults(0, 100);//get the results from 0 to 100 search results
var itemCol = new Array();
for(var i in results)
{
itemCol.push(results[i].getValue('id'));
}

Related

find returns the required data but $match doesn't in mongodb

I am trying to get required data using $match but it is returning null every time. On the other hand find returns the required data. I have to implement $lookup and $merge on the result I get but $match results null.
I have tried using a basic query in $match but it still returns null. I tried other posts too but in every post the steps that are given are not to my satisfaction.
This is my code:
var posts;
var area = "addresses."
var range = area.concat(req.body.range);
var place = req.body.place;
var reg = new RegExp(place, "i");
var query = {};
query[range] = reg;
/*Posts.find(query)*/ // this returns the result
Posts.aggregate( // inside this I get posts not found and
// the console.log prints empty value
[
{$match: {query}}
],
function(err, posts) {
if (err) {
return res.send(err).end;
} else if(posts.length > 0){
console.log("posts = "+posts);
reply[Constant.REPLY.MESSAGE] = "post by user found";
reply[Constant.REPLY.DATA] = posts;
reply[Constant.REPLY.RESULT_CODE] = 200;
reply[Constant.REPLY.TOKEN] = "";
return res.send(reply).end;
}else {
console.log("posts = "+posts); //empty value
reply[Constant.REPLY.MESSAGE] = "posts not found";
reply[Constant.REPLY.DATA] = null;
reply[Constant.REPLY.RESULT_CODE] = 200;
reply[Constant.REPLY.TOKEN] = "";
return res.send(reply).end;
}
}
);
The result of both find and $match must be same.

Xpages - Return correct documents using getDocumentByKey(unid, true)

I have a list, but I only want to narrow down my list to only documents with the current unid which appears on the browser, I did this by calling on the getDocumentByKey method of the viewEv object and pass in the unid arguement.
Strangly, this worked for only the newest document. The other documents, just shows all the list not belonging to the unid on the browser.
Any help will be appreciated.
Below is my code:
function getCalObj(){
var viewEv:NotesView = database.getView("Diary");
viewEv.setAutoUpdate(false);
var docEv:NotesDocument = viewEv.getFirstDocument();
var doc:NotesDocument = diaryDoc.getDocument();
var sUNID = doc.getUniversalID();
print("unid: " + sUNID);
docEv = viewEv.getDocumentByKey(sUNID, true);
while (docEv != null) {
........
}
}
Use getAllDocumentsByKey() to get all documents with this sUNID.
var dcEv:NotesDocumentCollection = viewEv.getAllDocumentsByKey(sUNID);
if (dcEv.getCount() > 0) {
var docEv:NotesDocument = dcEv.getFirstDocument();
while (docEv != null) {
........
}

How to get over 1000 records from a SuiteScript Saved Search?

Below is code I came up with to run a Saved Search in NetSuite using SuiteScript, create a CSV with the Saved Search results and then email the CSV. The trouble is, the results are limited to 1000 records. I've researched this issue and it appears the solution is to run a loop that slices in increments of 1000. A sample of what I believe is used to slice searches is also below.
However, I cannot seem to be able to incorporate the slicing into my code. Can anyone help me combine the slicing code with my original search code?
var search = nlapiSearchRecord('item', 'customsearch219729');
// Creating some array's that will be populated from the saved search results
var content = new Array();
var cells = new Array();
var temp = new Array();
var x = 0;
// Looping through the search Results
for (var i = 0; i < search.length; i++) {
var resultSet = search[i];
// Returns an array of column internal Ids
var columns = resultSet.getAllColumns();
// Looping through each column and assign it to the temp array
for (var y = 0; y <= columns.length; y++) {
temp[y] = resultSet.getValue(columns[y]);
}
// Taking the content of the temp array and assigning it to the Content Array.
content[x] += temp;
// Incrementing the index of the content array
x++;
}
//Inserting headers
content.splice(0, 0, "sku,qty,");
// Creating a string variable that will be used as the CSV Content
var contents;
// Looping through the content array and assigning it to the contents string variable.
for (var z = 0; z < content.length; z++) {
contents += content[z].replace('undefined', '') + '\n';
}
// Creating a csv file and passing the contents string variable.
var file = nlapiCreateFile('InventoryUpdate.csv', 'CSV', contents.replace('undefined', ''));
// Emailing the script.
function SendSSEmail()
{
nlapiSendEmail(768, 5, 'Inventory Update', 'Sending saved search via scheduled script', 'cc#email.com', null, null, file, true, null, 'cc#email.com');
}
The following code is an example of what I found that is used to return more than a 1000 records. Again, as a novice, I can't seem to incorporate the slicing into my original, functioning SuiteScript. Any help is of course greatly appreciated.
var filters = [...];
var columns = [...];
var results = [];
var savedsearch = nlapiCreateSearch( 'customrecord_mybigfatlist', filters, columns );
var resultset = savedsearch.runSearch();
var searchid = 0;
do {
var resultslice = resultset.getResults( searchid, searchid+1000 );
for (var rs in resultslice) {
results.push( resultslice[rs] );
searchid++;
}
} while (resultslice.length >= 1000);
return results;
Try out this one :
function returnCSVFile(){
function escapeCSV(val){
if(!val) return '';
if(!(/[",\s]/).test(val)) return val;
val = val.replace(/"/g, '""');
return '"'+ val + '"';
}
function makeHeader(firstLine){
var cols = firstLine.getAllColumns();
var hdr = [];
cols.forEach(function(c){
var lbl = c.getLabel(); // column must have a custom label to be included.
if(lbl){
hdr.push(escapeCSV(lbl));
}
});
return hdr.join(",");
}
function makeLine(srchRow){
var cols = srchRow.getAllColumns();
var line = [];
cols.forEach(function(c){
if(c.getLabel()){
line.push(escapeCSV(srchRow.getText(c) || srchRow.getValue(c)));
}
});
return line.join(",");
}
function getDLFileName(prefix){
function pad(v){ if(v >= 10) return v; return "0"+v;}
var now = new Date();
return prefix + '-'+ now.getFullYear() + pad(now.getMonth()+1)+ pad(now.getDate()) + pad( now.getHours()) +pad(now.getMinutes()) + ".csv";
}
var srchRows = getItems('item', 'customsearch219729'); //function that returns your saved search results
if(!srchRows) throw nlapiCreateError("SRCH_RESULT", "No results from search");
var fileLines = [makeHeader(srchRows[0])];
srchRows.forEach(function(soLine){
fileLines.push(makeLine(soLine));
});
var file = nlapiCreateFile('InventoryUpdate.csv', 'CSV', fileLines.join('\r\n'));
nlapiSendEmail(768, 5, 'Test csv Mail','csv', null, null, null, file);
}
function getItems(recordType, searchId) {
var savedSearch = nlapiLoadSearch(recordType, searchId);
var resultset = savedSearch.runSearch();
var returnSearchResults = [];
var searchid = 0;
do {
var resultslice = resultset.getResults(searchid, searchid + 1000);
for ( var rs in resultslice) {
returnSearchResults.push(resultslice[rs]);
searchid++;
}
} while (resultslice.length >= 1000);
return returnSearchResults;
}
I looked into your code but it seems you're missing the label headers in the generated CSV file. If you are bound to use your existing code then just replace
var search = nlapiSearchRecord('item', 'customsearch219729');
with
var search = getItems('item', 'customsearch219729');
and just use the mentioned helper function to get rid off the 1000 result limit.
Cheers!
I appreciate it has been a while since this was posted and replied to but for others looking for a more generic response to the original question the following code should suffice:
var search = nlapiLoadSearch('record_type', 'savedsearch_id');
var searchresults = search.runSearch();
var resultIndex = 0;
var resultStep = 1000;
var resultSet;
do {
resultSet = searchresults.getResults(resultIndex, resultIndex + resultStep); // retrieves all possible results up to the 1000 max returned
resultIndex = resultIndex + resultStep; // increment the starting point for the next batch of records
for(var i = 0; !!resultSet && i < resultSet.length; i++){ // loop through the search results
// Your code goes here to work on a the current resultSet (upto 1000 records per pass)
}
} while (resultSet.length > 0)
Also worth mentioning, if your code is going to be updating fields / records / creating records you need to bear in mind script governance.
Moving your code to a scheduled script to process large volumes of records is more efficient and allows you to handle governance.
The following line:
var savedsearch = nlapiCreateSearch( 'customrecord_mybigfatlist', filters, columns );
can be adapted to your own saved search like this:
var savedsearch = nlapiLoadSearch('item', 'customsearch219729');
Hope this helps.

Not generating expected results between google calendar and spreadsheet

So I have some code to create calendar events based on a jobs sheet for meetings but I can't seem to get it working as I would expect- I have columns 24 and 25 to keep track of if its been put in the calendar and the calendar event id, I don't want it to delete then create a new event for ones that have already been added (as this spreadsheet can get large) so thats why I keep track via on edit. But is seems to create a new event every time. If anyone can have a look over that would be great as I've been struggling for the past 3 days with this.
Many thanks
//push new events to calendar;
function pushToCalendar() {
//spreadsheet variables
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var range = sheet.getRange(2,1,lastRow,26);
var values = range.getValues();
var updateRange = sheet.getRange('Z1');
//calendar variables
var calendar = CalendarApp.getCalendarById('insert calendar code here')
//show updating message
updateRange.setFontColor('red');
var numValues = 0;
for (var i = 0; i < values.length; i++) {
//check to see if name are filled out
if ((values[i][0].length > 0) && (values[i][1].length > 0)) {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// if it has been edited delete old event
if (values[i][23] ='n') {
try{
var eventIdCell =values[i][24];
var eventId =calendar.getEventSeriesById(eventIdCell);
eventId.deleteEventSeries();
}
catch (e) {
// do nothing - we just want to delete if it has been edited and the old event if it still exists
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//check if it's been entered before
if (values[i][23] !='y') {
var newEventTitle = values[i][0] + ' - ' + values[i][1]+' - ' + 'Sample';
var newEvent = calendar.createAllDayEvent(newEventTitle, new Date(values[i][6]));
//get ID
var newEventId = newEvent.getId();
//mark as entered, enter ID
sheet.getRange(i+2,24).setValue('y');
sheet.getRange(i+2,25).setValue(newEventId);
}
}
numValues++;
}
//hide updating message
updateRange.setFontColor('white');
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//add a menu when the spreadsheet is opened
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [];
menuEntries.push({name: "Update Calendar", functionName: "pushToCalendar"});
sheet.addMenu("Jobs Calendar", menuEntries);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
function onEdit(event){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var actSht = event.source.getActiveSheet();
var actRng = event.source.getActiveRange();
var activeCell = actSht.getActiveCell();
var row = activeCell.getRow();
if(row < 2){
return; //If header row then return
}
else{
var index = actRng.getRowIndex();
var updateCalCell = actSht.getRange(index,24);
var eventIdCell = actSht.getRange(index,25);
change updated on colander status to n
updateCalCell.setValue('n');
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
You made a simple error in the condition : the EQUAL operator in comparison is == and not =, change that and it will work.
if (values[i][23] =='n') {

Need Help: Account Name on Contact Phone Call

I am new to CRM and have been able to figure out everything up to now. I have read so many post and internet post and tried them. I have watched some many videos. It seems it should be easy. The contact record has the ParentCustomerID, and ParentCustomerName that holds the account if there is one associated. Now I am just totally confused on the required steps.
Requirement: - I need Account Name to be displayed on the contact level phone call form and saved in phone call table so that it can be visible in the phone call view.
I have in Phone Call N:1 Relationship field str_companyid (lookup) primary Entity is Account with Referential behavior.
I tried a Phone Call N:1 Relationship field new_companystring (lookup) primary Entity is Contact with Referential behavior. I came to the conclusion that this is not a valid approach. Let me know if incorrect.
Do I need a N:N instead?
I have added the str_companyid field to the form. I went to the "Create a phone call for a contact" workflow process. On the "Create PhoneCall" step I have added the dynamic field {Company(Contact)}. After save and publishes; I created a phone call and it isn't populated.
I have tried different Web Resource JS. I have added the JS in the onload of the form properties.
Why doesn't something as easy as this work? I can't seem to get the retrieveRecord to work. I have also tried the xmlHttpObject object but it returns 0.
Can someone help assist me on what I am missing? What are the complete steps to accomplish this?
![I have screenshots below and the code I was running][1]
function PopulateCompanyName()
{
//get group GUID
if (Xrm.Page.getAttribute("to").getValue()[0].id != null) {
var lookup = Xrm.Page.getAttribute("to").getValue();
alert(lookup[0].id);
alert(lookup[0].typename);
alert(lookup[0].name);
alert(lookup);
SDK.JQuery.retrieveRecord(lookup[0].id,
lookup[0].typename,
"ParentCustomerID",
null,
function (lookup) {
Xrm.Page.getAttribute("Company").setValue(lookup[0].str_companyid);
});
}
else {
Xrm.Page.getAttribute("str_companyid").setValue(null);
}
}
function GetCompany()
///Get lookup ID
{
alert("I am Here");
var lookupfield = Xrm.Page.getAttribute("to").getValue();
if (lookupfield != null && lookupfield [0] != null)
{
var householdlookupvalue = lookupfield [0].id;
}
else
{
var householdlookupvalue = " ";
}
alert("I am here2");
alert(householdlookupvalue);
}
// Prepare variables for a contact to retrieve.
var authenticationHeader = Xrm.Page.context.getAuthenticationHeader();
// Prepare the SOAP message.
var xml = ""+
""+
authenticationHeader+
""+
""+
"contact"+
""+lookupfield [0].id+""+
""+
""+
"parentcustomerid"+
""+
""+
""+
""+
"";
alert(xml );
// Prepare the xmlHttpObject and send the request.
var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xHReq.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Retrieve");
xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xHReq.setRequestHeader("Content-Length", xml.length);
xHReq.send(xml);
// Capture the result.
var resultXml = xHReq.responseXML;
alert("at results");
var errorCount = resultXml.selectNodes('//error').length;
alert("errorCount " + errorCount); ////////////////////////////////////returns 0; it shouldn't
alert("After the result XML "+resultXml .toString() + " ::::");
// Check for errors.
var errorCount = resultXml.selectNodes('//error').length;
if (errorCount != 0)
{
}
// Display the retrieved value.
else
{
//Create an array to set as the DataValue for the lookup control.
var lookupData = new Array();
//Create an Object add to the array.
var lookupItem= new Object();
//Set the id, typename, and name properties to the object.
lookupItem.id = resultXml.selectSingleNode("//q1:parentcustomerid").nodeTypedValue;
lookupItem.entityType = 'account';
lookupItem.name = resultXml.selectSingleNode("//q1:parentcustomerid").getAttribute("name");
// Add the object to the array.
lookupData[0] = lookupItem;
alert(lookupitem.name)
// Set the value of the lookup field to the value of the array.
Xrm.Page.getAttribute("str_companyid").setValue(lookupData);
}
var contact = new Array();
contact = Xrm.Page.getAttribute("to").getValue();
alert("I am here");
alert(contact);
if (contact == null || contact[0].entityType != "contact" || contact.length > 1) {
return;
}
alert("inside if")
var serverUrl = Xrm.Page.context.getClientUrl();
var oDataSelect = serverUrl + "/XRMServices/2011/OrganizationData.svc/ContactSet?$select=ParentCustomerId&$filter=ContactId eq guid'" + contact[0].id + "'";
var retrieveReq = new XMLHttpRequest();
retrieveReq.open("GET", oDataSelect, false);
retrieveReq.setRequestHeader("Accept", "application/json");
retrieveReq.setRequestHeader("Content-Type", "application/json;charset=utf-8");
retrieveReq.onreadystatechange = function () {
GetContactData(this);
};
retrieveReq.send();
}
I replied in the other forum but I post here as reference and with more technical details.
The to attribute of phonecall entity is a partylist type, this means that it can handle several records from different entities. In your case you want to get the Parent Account (field parentcustomerid) if a contact is inside the to field.
Your first code contains same typo and use the msdn Retrieve example, the second code uses CRM 4.0 endpoints, they are still supported inside CRM 2011, but it's better to avoid them so you can use the REST endpoint instead of the SOAP one.
a working code in your case can be:
function setToParentAccount() {
// set only if to Field (Recipient) has 1 record and is a contact
if (Xrm.Page.getAttribute("to").getValue() != null) {
var recipient = Xrm.Page.getAttribute("to").getValue();
if (recipient.length == 1 && recipient[0].entityType == "contact") {
var contactId = recipient[0].id;
var serverUrl;
if (Xrm.Page.context.getClientUrl !== undefined) {
serverUrl = Xrm.Page.context.getClientUrl();
} else {
serverUrl = Xrm.Page.context.getServerUrl();
}
var ODataPath = serverUrl + "/XRMServices/2011/OrganizationData.svc";
var contactRequest = new XMLHttpRequest();
contactRequest.open("GET", ODataPath + "/ContactSet(guid'" + contactId + "')", false);
contactRequest.setRequestHeader("Accept", "application/json");
contactRequest.setRequestHeader("Content-Type", "application/json; charset=utf-8");
contactRequest.send();
if (contactRequest.status === 200) {
var retrievedContact = JSON.parse(contactRequest.responseText).d;
var parentAccount = retrievedContact.ParentCustomerId;
if (parentAccount.Id != null && parentAccount.LogicalName == "account") {
var newParentAccount = new Array();
newParentAccount[0] = new Object();
newParentAccount[0].id = parentAccount.Id;
newParentAccount[0].name = parentAccount.Name;
newParentAccount[0].entityType = parentAccount.LogicalName;
Xrm.Page.getAttribute("str_companyid").setValue(newParentAccount);
} else {
Xrm.Page.getAttribute("str_companyid").setValue(null);
}
} else {
alert("error");
}
} else {
Xrm.Page.getAttribute("str_companyid").setValue(null);
}
}
}
to be called inside OnLoad event and OnChange event of the to field.

Resources