Problem with retrieving SalesOrders by status on NetSuite using SuiteScript - javascript

So, i'm building a integration with NetSuite, and i need a SuiteScript that gets all SalesOrders based on a status filter. I was able to create scripts that retrieve based on creation date and SO Number, but for some reason, the one using the Status field does not work, seems like i'm using the wrong field for the filter or something, could you please provide me some examples on how you've done it?
Below is my script for reference:
function SearchOrdersByStatus(status){
var allSalesOrders = [];
var salesOrdersIds = [];
var start = 0;
var pageSize = 1000;
var filters = [new nlobjSearchFilter('status', null, 'is', status)];
var columns = [new nlobjSearchColumn('internalid')];
var searchResults = nlapiSearchRecord('salesorder', null, filters, columns);
do {
if (searchResults.length > 0) {
for (var i = 0; i < searchResults.length; i++) {
salesOrdersIds.push(searchResults[i].getValue('internalid'));
var salesOrder = nlapiLoadRecord('salesorder', salesOrdersIds[i]);
allSalesOrders.push(salesOrder);
}
start += pageSize;
}
} while (searchResults.length >= pageSize);
return allSalesOrders;
}

transactions search status is easiest to get by creating and saving a saved search that filters on the statuses of interest and then listing those statuses by extracting them from the saved searches in the console.
see the second script here: NetSuite Search formula for items that have no open transactions
the status values you'll use in the search will look like:'SalesOrd:A', 'SalesOrd:B' etc

Related

Exception: Document is missing (perhaps it was deleted, or you don't have read access?)

I'm working on a project that take "profiles" stored in a Google Sheet, makes a unique Google Doc for each profile, and then updates the unique Google Doc with any new information when you push a button on the Google Sheet.
I have some other automations built into my original code, but I simplified most of it to what's pertinent to the error I'm getting, which is this:
Exception: Document is missing (perhaps it was deleted, or you don't have read access?
It happens on Line 52 of my script in the fileUpdate funtion. Here's the appropriate line for reference:
var file = DocumentApp.openById(fileName);
And this is the rest of my code:
function manageFiles() {
//Basic setup. Defining the range and retrieving the spreadsheet to store as an array.
var date = new Date();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var array = sheet.getDataRange().getValues();
var arrayL = sheet.getLastRow();
var arrayW = sheet.getLastColumn();
for (var i = 1; i < arrayL; i++) {
if (array[i][arrayW-2] == "") {
//Collect the data from the current sheet.
//Create the document and retrieve some information from it.
var docTitle = array[i , 0]
var doc = DocumentApp.create(docTitle);
var docBody = doc.getBody();
var docLink = doc.getUrl();
//Use a for function to collect the unique data from each cell in the row.
docBody.insertParagraph(0 , "Last Updated: "+date);
for (var j = 2; j <= arrayW; j++) {
var colName = array[0][arrayW-j];
var data = array[i][arrayW-j];
if (colName !== "Filed?") {
docBody.insertParagraph(0 , colName+": "+data);
}
}
//Insert a hyperlink to the file in the cell containing the SID
sheet.getRange(i+1 , 1).setFormula('=HYPERLINK("'+docLink+'", "'+SID+'")');
//Insert a checkbox and check it.
sheet.getRange(i+1 , arrayW-1).insertCheckboxes();
sheet.getRange(i+1 , arrayW-1).setFormula('=TRUE');
}
else if (array[i][arrayW-2] !== "") {
updateFiles(i);
}
}
sheet.getRange(1 , arrayW).setValue('Last Update: '+date);
}
//Note: I hate how cluttered updateFiles is. I'm going to clean it up later.
function fileUpdate(rowNum) {
//now you do the whole thing over again from createFiles()
//Basic setup. Defining the range and retrieving the spreadsheet to store as an array.
var date = new Date();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var array = sheet.getDataRange().getValues();
var arrayL = sheet.getLastRow();
var arrayW = sheet.getLastColumn();
//Collect the data from the current sheet.
var fileName = array[rowNum][0];
var file = DocumentApp.openById(fileName);
//retrieve the body of the document and clear the text, making it blank.
file.getBody().setText("");
//Use a for function to collect the the unique date from every non-blank cell in the row.
file.getBody().insertParagraph(0 , "Last Updated: "+date);
for (var j = 2; j <= arrayW; j++) {
var colName = array[0][arrayW-j];
var data = array[rowNum][arrayW-j];
file.getBody().insertParagraph(0 , colName+": "+data);
}
}
If you'd like to take a look at my sample spreadsheet, you can see it here. I suggest you make a copy though, because you won't have permissions to the Google Docs my script created.
I've looked at some other forums with this same error and tried several of the prescribed solutions (signing out of other Google Accounts, clearing my cookies, completing the URL with a backslash, widening permissions to everyone with the link), but to no avail.
**Note to anyone offended by my janky code or formatting: I'm self-taught, so I do apologize if my work is difficult to read.
The problem (in the updated code attached to your sheet) comes from your URL
Side Note:
In your initial question, you define DocumentApp.openById(fileName);
I assume your realized that this is not correct, since you updated
your code to DocumentApp.openByUrl(docURL);, so I will discuss the
problem of the latter in the following.
The URLs in your sheet are of the form
https://docs.google.com/open?id=1pT5kr7V11TMH0pJea281VhZg_1bOt8YDRrh9thrUV0w
while DocumentApp.openByUrl expects a URL of form
https://docs.google.com/document/d/1pT5kr7V11TMH0pJea281VhZg_1bOt8YDRrh9thrUV0w/
Just adding a / is not enough!
Either create the expected URL manually, or - much easier / use the method DocumentApp.openById(id) instead.
For this, you can extract the id from your URL as following:
var id = docURL.split("https://docs.google.com/open?id=")[1];
var file = DocumentApp.openById(id)

Google script that already fetches email infos but needs attachment name

CONTEXT
I'm using a script to fetch emails that I found here (from Niclas, I think): fetching emails script
I've adapted it to my needs and it works very well!
WHAT I'VE TESTED
I saw getDescription() from the Google script Class Attachment but couldn't get it to work and I'm not even sure if that's the way to go
WHAT I WOULD WANT
In addition, I would like to fetch the attachments filenames since It's a distinctive mark on each email
Any help would me very appreciated. Thanks in advance
Modifications:
Do the following modifications to the answer of the post you mentioned in your question:
Add these lines:
var attachments = messages[maxIndex].getAttachments();
var attNames = attachments.map(att=>att.getName());
and modify this one:
ss.appendRow([from, cc, time, sub,...attNames ,'https://mail.google.com/mail/u/0/#inbox/'+mId])
Solution:
function myFunction() {
// Use sheet
var ss = SpreadsheetApp.getActiveSheet();
// Gmail query
var query = "label:support -label:trash -label:support-done -from:me";
// Search in Gmail, bind to array
var threads = GmailApp.search(query);
// Loop through query results
for (var i = 0; i < threads.length; i++)
{
// Get messages in thread, add to array
var messages = threads[i].getMessages();
// Used to find max index in array
var max = messages[0];
var maxIndex = 0;
// Loop through array to find maxIndexD = most recent mail
for (var j = 0; j < messages.length; j++) {
if (messages[j] > max) {
maxIndex = j;
max = messages[j];
}
}
// Find data
var mId = messages[maxIndex].getId() // ID used to create mail link
var from = messages[maxIndex].getFrom();
var cc = messages[maxIndex].getCc();
var time = threads[i].getLastMessageDate()
var sub = messages[maxIndex].getSubject();
var attachments = messages[maxIndex].getAttachments();
var attNames = attachments.map(att=>att.getName());
// Write data to sheet
ss.appendRow([from, cc, time, sub,...attNames ,'https://mail.google.com/mail/u/0/#inbox/'+mId])
}
}
Don't forget to change the value of query to your needs.
References:
Class GmailMessage
map()
Rest parameters
You have to enable V8 runtime to be able to use the snippet.

Running ContactsApp.getContact(email) inside a loop causes timeout

I'm creating a GAS for Gmail.
The first part of this script is collecting all recipients and senders from a thread object from the GmailApp. No problem there, except I'm just left with an array of strings with the "full name <email>" syntax.
Secondly, I want to create a card for each contact email, by first looking up the contact object inside the ContactsApp. This however causes the script to time out, even though logs show it is able to fetch the contacts.
I've tested 2 alternatives:
get all contacts with ContactsApp.getContacts() and there's no timeout.
look up a single contact with CotnactsApp.getContact(email)an no timeout either.
// TEST 1: Get All Contacts
var allContacts = ContactsApp.getContacts();
// TEST 2: Get one contact
var testContact = ContactsApp.getContact("test#email.com");
// TEST 3: Loop over and get contacts
var threadContacts = [];
for (var i = 0; i < participants.length; i++) {
var email = participants[i].split("<")[1].split(">")[0];
var contact = ContactsApp.getContact(email);
threadContacts.push(contact)
}
So I'm a bit unclear here as to the intended usage. Should I go for option 1 and load all the contacts on the client side and iterate through these? Or is it intended to look for a contact each time I need to get the data? Doesn't loading all contact risks loading a gazillion contacts (should someone have so many?). It seems cumbersome.
I couldn't see any guidelines on the documentation.
You want to retrieve the contact object by searching the emails.
You want to achieve this using Google Apps Script.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
In this answer, the contact objects are retrieved by searching the emails from ContactsApp.getContacts(). This method is also mentioned in your question.
Flow:
The flow of this sample script is as follows.
Create an array by retrieving email from "full name <email>".
Retrieve all contacts.
Retrieve the contact object by searching the emails from all contacts.
Sample script:
In this case, it supposes that participants is an array like ["full name <email1>", "full name <email2>",,,].
// Retrieve email address from "full name <tanaike#hotmail.com>" in participants and put them to an array.
var convertedParticipants = participants.map(function(e) {return e.split("<")[1].split(">")[0]});
var allContacts = ContactsApp.getContacts();
// Here, the contact objects are retrieved by searching the emails.
var results = allContacts.reduce(function(ar, c) {
var emails = c.getEmails();
if (emails.length > 0) {
// Retrieve email addresses from a contact object and put them to an array.
var addresses = emails.map(function(e) {return e.getAddress()});
// When the emails of "convertedParticipants" are included in the contact object, the object is put to an array.
if (convertedParticipants.some(function(f) {return addresses.indexOf(f) != -1})) {
ar.push(c);
}
}
return ar;
}, []);
When above script is run, you can see the searched contact objects in results as an array.
References:
getEmails()
getAddress()
reduce()
some()
If I misunderstood your question and this was not the direction you want, I apologize.
Added:
When var results = allContacts.reduce(function(ar, c) {###}, []); is modified using the for loop, it becomes as follows.
Script:
var results = [];
for (var i = 0; i < allContacts.length; i++) {
var emails = allContacts[i].getEmails();
if (emails.length > 0) {
var addresses = [];
for (var j = 0; j < emails.length; j++) {
addresses.push(emails[j].getAddress());
}
var f = false;
for (var j = 0; j < convertedParticipants.length; j++) {
if (addresses.indexOf(convertedParticipants[j]) != -1) {
f = true;
break;
}
}
if (f) {
results.push(allContacts[i]);
}
}
}

Script in google sheet to clear, but not remove filter

I am completely new in writing scripts for google sheets, so I was hoping some of you could help/guide me a little bit.
So Ideally, I want a script to clear (not remove) ALL filters in my sheet. This is, however, complicated for me to do (If some of you have such a script, I would LOVE to see it :) )
Instead, I made this one (Used recorder):
function Clear_Filter() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A5').activate();
spreadsheet.getActiveSheet().getFilter().removeColumnFilterCriteria(1);
spreadsheet.getRange('B5').activate();
spreadsheet.getActiveSheet().getFilter().removeColumnFilterCriteria(2);
spreadsheet.getRange('C5').activate();
spreadsheet.getActiveSheet().getFilter().removeColumnFilterCriteria(3);
spreadsheet.getRange('G5').activate();
spreadsheet.getActiveSheet().getFilter().removeColumnFilterCriteria(7);
spreadsheet.getRange('J5').activate();
spreadsheet.getActiveSheet().getFilter().removeColumnFilterCriteria(10);
spreadsheet.getRange('M5').activate();
spreadsheet.getActiveSheet().getFilter().removeColumnFilterCriteria(13);
};
So my filter is set in Row 5. First I made the above for all columns (I had 20), but the problem is, that the code is very slow :( So now I am using the columns, that I use the most, when filtering, but the code is still slow. Well the worst thing is, that the code is running one column at a time (which we see in the code), and when the code is finish, I end up in the last column.
Can I do something? I dont want my sheet window keep turning right, when I run the code, and then end up in column M.
I will appreciate any help!
Thanks
Here is mine. The function does not remove filters. Instead, it clears them as requested.
function clearFilter(sheet) {
sheet = SpreadsheetApp.getActiveSheet(); //for testing purpose only
var filter = sheet.getFilter();
if (filter !== null) { // tests if there is a filter applied
var range = filter.getRange(); // prevents exception in case the filter is not applied to all columns
var firstColumn = range.getColumn();
var lastColumn = range.getLastColumn();
for (var i = firstColumn; i < lastColumn; i++) {
filter.removeColumnFilterCriteria(i);
}
Logger.log('All filters cleared')
}
else {Logger.log('There is no filter')}
}
Reset filters criterea + sort by first column (as default state).
And add this action to main menu.
/** #OnlyCurrentDoc */
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [
{name: "Reset filters", functionName: "ResetFilters"},
];
ss.addMenu("Custom actions", menuEntries); // add to main menu
}
function ResetFilters() {
var spreadsheet = SpreadsheetApp.getActive();
var lastColumn = spreadsheet.getActiveSheet().getLastColumn();
var filter = spreadsheet.getActiveSheet().getFilter();
var criteria = SpreadsheetApp.newFilterCriteria().build();
for (var i = 1; i <= lastColumn; i++) {
filter.setColumnFilterCriteria(i, criteria);
}
filter.sort(1, true); // remove this line for disable setting of sorting order
};
To clear all
`function turnOffFilter(sheet) {
for (var index = 1; index < sheet.getLastColumn(); index++) {
if (sheet.getFilter().getColumnFilterCriteria(index)) {
sheet.getFilter().removeColumnFilterCriteria(index);
}
}
}`
It seems that the answers (e.g. proposed by Birmin) work fine but the script is painfully slow. I find it much faster to reapply the filter:
function clearFilter(sheet) {
sheet = SpreadsheetApp.getActiveSheet(); //for testing purpose only
var filter = sheet.getFilter();
if (filter !== null) { // tests if there is a filter applied
var range = filter.getRange();
filter.remove();
range.createFilter();
Logger.log('All filters cleared')
}
else {Logger.log('There is no filter')}
}
I, have you tried :
function Clear_Filter() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getFilter().remove();
}

Get more than 1 value from JDBC connection using Google Apps Script

I have a JDBC connection to MSSQL using GAS, the database I am using has class names and dates that are associated with the specific class.
I'm trying to retrieve all of the dates associated with the class Advanced Ventilator Skills Review. When I run the below code all I see in the log is the last date added to the database that is associated with the class above. Can anyone help me out? I want to get all of the dates associated with the class and what would be optimal is to display those dates in a drop down menu.
//Read from Database
function read(e) {
var app = UiApp.getActiveApplication();
var conn = Jdbc.getConnection("jdbc:sqlserver://IPAddress:1433;" +
"databaseName=databaseName;user=User;password=Password;");
var stmt = conn.createStatement();
var rs = stmt.executeQuery("SELECT * from dbo.tbl_ClassDetail WHERE className = 'Advanced Ventilator Skills Review'");
while(rs.next()) {
var class = rs.getString('className');
var date = rs.getString('classDate');
var time = rs.getString('classTime');
}
Logger.log(date);
rs.close();
stmt.close();
conn.close();
}
collect the results into array results.push(class,date,time) in while loop. return results from this function
Using example from https://developers.google.com/apps-script/class_listbox, and in your show or UiApp - take the results array returned and add them in a for or while loop
var results = read(e);
for (i=0; i < results.length; i++)
{
lb.addItem [i][1];
}

Categories

Resources