Google Form Search and Pull Spreadsheet Data - search

Hi I have google spreadsheet that contains customers' ID and their shipping status. I want to create google form where customers are able to input each of their own ID, with the return that the google form shows their shipping status.
I tried to look for solutions in internet but there was no luck. I am not really good in programming, i hope there is answer to this problem without having me to do some hard programming.
The sample case can be seen in here: https://docs.google.com/spreadsheets/d/14vSAeZxEJTzbNLLYEiref6qt-CMqiVi8alheLcIBugM/edit?usp=sharing
Google form should show something a little bit like is shown in cell D1:E3.
Where customers can fill the form with their own customer id, and the google form shows the status.

Consideration
There is no way to respond back in a Google Form directly. You can't show custom validation messages after From submission either.
Proposed solution
What about using email addresses additionally to the customerID to retrieve the shipping status? In this way you can easily build a notification system that will send an email if a matching customer ID is found in your spreadsheet.
To build such system you will have to build a Form with a Trigger.
It is required a bit of programming but I will try to cover the most important parts the best I can:
Adapt your Database structure
Add the customers email addresses in the column C in order to be able to retrieve it using the same customer ID.
| A | B | C |
|----+--------+-------|
| ID | STATUS | EMAIL |
Build the Form Trigger
In the Form you are using click on the 3 dots from the top menu and select Script Editor. Here you will write the code that will power your notification system.
function installTrigger() {
// This function instructs the program to trigger the checkID function whenever a form response is submitted
ScriptApp.newTrigger('checkID')
.forForm(FormApp.getActiveForm())
.onFormSubmit()
.create();
}
function checkID(e) {
// This function will parse the response to use the customer ID to retrieve email address and shipping status from the Spreadsheet Database
var responses = e.response.getItemResponses(); // Gets the form responses
var id = responses[0].getResponse(); // Assuming the first answer (index 0) is the customer ID)
var found = SpreadsheetApp.openById('spreadsheet_id')
.getRange('Sheet1!A1:C8') // The spreadsheet cells range in A1 Notation
.getValues() // Retrieve their values in rows
.filter((row) => row[0] == id); // Filter the rows for the provided customer ID
if (found) {
var status = found[0][1]; //Column B
var email = found[0][2]; //Column C
var subject = "Shipping Status";
var message =
`Hello!
The status of the order number ${id} is: ${status}.`
MailApp.sendEmail(email, subject, message);
}
}
Install the trigger
From the Script Editor top menu run the installTrigger() function: Run>Run function>installTrigger.
You are done
Following these steps you have successfully set up the notification system. Now you can start sharing the Form link and accept responses.
References
Installable Triggers
Mail App

Related

(Google Documents) Way to create custom documents based on certain input variables?

Is there a way to have a paragraph of text get spit out when you have a certain input, from say a google questionnaire?
And make it so you could have say 5 inputs, and it would spit out 5 paragraphs of information, into one document?
For example:
If someone fills out a questionnaire where the first question is year of birth, the tool would spit out the first paragraph with a description of what the year they were born was like.
Second question would be their birth country, the tool would place a paragraph of text about their birth country into the document.
etc etc
Many thanks in advance for any help
It is possible to create documents using a specific criteria based in form responses. I created the following sample script using Google Apps Script so you can get the idea:
function docCreation() {
var ss = SpreadsheetApp.getActive().getSheetByName("Form Responses 1");
var range = ss.getDataRange();
var values = range.getValues().reverse(); //reverses the array to get the last value in the first position
var doc = DocumentApp.create("Testing doc"); // You can change the name to match a username or any other variable instead
switch (getMonth(values[0][1].toString())) {
case 'Aug':
doc.getBody().appendParagraph("This is a sample body for August");
break;
case 'Jul':
doc.getBody().appendParagraph("This is a sample body for July");
break;
}
}
// Second function that returns the month value of the date introduced by the user
// I separated it because it is not that relevant to the main goal
function getMonth(val){
var month = val.split(" ");
return month[1];
}
It is a very simple script that checks if the month of the date introduced by the user is August or July, and if so, it creates a doc with a simple text as paragraph.
The script is bounded to the Google Sheet of the form responses and you can create a trigger so that every time a user fills out the form, the script starts running to create the needed documents. Now as I mentioned, this is just a sample, and the logic and docs format would depend on your specific needs and usage.
References:
Class Body
Create document

Creating a Unique ID for each record on Form Submission

I am new to Google Apps Script and have just begun to understand its working. A team member wrote out a simple simple script for some work i was doing. The script, in essence, triggered when any of a permitted set of users (could vary) submits inputs to a 'Form Responses 1' spreadsheet via a Google Form.
Basically, I have a form that users complete and then submit. Upon submission, the script checks for the active row, The code adds 1 to the number of the cell W2 (which is a 'do not edit' cell, and replaces W2 with the new number, then checks if the Unique ID field on the Active Row is null and then replaces it with a concatenated ID thats alphanumeric. ie, it prefixes a set alphabetical prefix and takes the numerical input from the cell W2 on the same form to create a new Unique ID.
The script was working perfectly until the team member left and I removed her access from the Google sheets with no change to the script at all. I've been scrambling trying to figure out what happened after that, because since access was removed, when I haven't made any changes to my code. I have searched many different places and cannot seem to find what is wrong.
If i post it on a new google sheet, it's working fine .. but not on this sheet which already has around 900 critical entries.
Any guidance is welcome. the Script is as below. HELP!
//Logger.log(SpreadsheetApp.getActiveSpreadsheet().getUrl());
//Logger.log(SpreadsheetApp.getActive().getUrl());
// Get the active sheet
var sheet = SpreadsheetApp.getActiveSheet();
// Get the active row
var row = sheet.getActiveCell().getRowIndex();
// Get the next ID value. NOTE: This cell should be set to the last record counter value
var id = sheet.getRange("X2").getValue()+1;
Logger.log("HKG0"+id);
// Check if ID column is empty
if (sheet.getRange(row, 1).getValue() == "") {
// Set new ID value
sheet.getRange(2, 24).setValue(id);
sheet.getRange(row, 1).setValue("HKG0"+id);
}
}
If your code is running off of a form submit trigger then this should work for you.
function formsubit(e) {
Logger.log(JSON.stringify(e));
var sheet = e.range.getSheet();
var id = sheet.getRange("X2").getValue() + 1;
if (sheet.getRange(e.range.rowStart, 1).getValue() == "") {
sheet.getRange(2, 24).setValue(id);
sheet.getRange(e.range.rowStart, 1).setValue("HKG0" + id);
}
}
The Logger.log will help you to learn more about the event object. You can learn more about event objects here
If you're looking for a unique id for each submission try: const id = new Date(e.values[0]).valueOf(); it's the number of milliseconds since Jan 1, 1970

email spreadsheet rows if a cell contains a certain word - Google Spreadsheet + app script

I'm creating a "deadline reminder system" using a google spreadsheet to manage contracts and projects deadlines, here's the file: https://docs.google.com/spreadsheets/d/1CEk67cXN9NrDy_-ueOxcdwmo2dyyaX47OYIQXi5bHpA/edit#gid=1331412473
I'm trying to use Google app script to create a script that every day check every row of each sheet and send me an email with rows where last column says "in scadenza" (about to expire) or "scaduto" (expired).
For the email template I would like to revve rows as an html table or as a pdf file (what do you think is better?)
I would also find a way to avoid sending duplicates (for example adding a "reminder sent" text in stato (state) column or near this column and colour that cells.
As you can see some tables have a slightly different layout so I think I have to write down a function for each sheet since the colun range that I have to scan is different.
I'm absolutely a beginner with google script, I've found a lot of examples about how to send emails from google sheets but I can't find the correct way to put all together and write down a script that works...
I would really aprecciate if you can take a look to my spreadsheet and help me to write down the script.
Many thanks to all!
Just for reference, here some resources that I've found:
https://www.groovypost.com/howto/google-sheets-send-email-based-on-cell-value/#:~:text=Step%201%3A%20Sending%20an%20Email,that%20contains%20an%20email%20address.
How to send several rows of google sheet table via email if cell match today's date ( this example uses date as filter, I have to use the cell text content)
https://www.labnol.org/code/19869-email-google-spreadsheets-pdf
Solution
You can use a Clock trigger to run a function that filters your Sheets rows in the desired Spreadsheet according to the Stato row value.
Code
First you will need to build the filtering functions:
This function takes some rows as input ad builds a table body HTML with the filtered rows:
function getSheetValuesAsTable(values) {
var states = ['in scadenza', 'scaduto']; // Here you can add new watched statuses
return values.filter(row => states.includes(row[row.length -1]))
.map(row => "<tr>"+row.map(x => "<td>"+x+"</td>").join('')+"</tr>");
}
While the Sheet structure has the Stato column as the last column you will be able to build different tables for each one of your Sheets.
So you will need another function to build the table headers:
function getSheetHeadersAsTable(values) {
var headers = values[0];
Logger.log(values);
var tabHeaders = headers.map(header => `<th>${header}</th>`);
return `<table><tr>${tabHeaders.join('')}</tr>`;
}
Now you can wrap up the table headers and body in a HTML string and send it with the GmailApp.sendEmail() method:
function emailSpreadsheetAsHTMLTable() {
var ss = SpreadsheetApp.openById('spreadsheet-id');
var body = buildMessage(ss.getSheets());
var subject = `Scadenze Contratti/Domini/Progetti`;
var email = 'esposito.luca94#gmail.com';
if (MailApp.getRemainingDailyQuota() > 0)
GmailApp.sendEmail(email, subject,body, {
htmlBody: body
});
}
function buildMessage(sheets) {
return sheets.map(sheet => {
var values = sheet.getDataRange().getValues();
return `<h2>${sheet.getName()}</h2>${buildSheetTable(values)}</table>`; // Here I add the Sheet name for each table
}).join('');
}
function buildSheetTable(values) {
var tabHeaders = getSheetHeadersAsTable(values);
var tabBody = getSheetValuesAsTable(values);
return tabHeaders + tabBody;
}
Now you can install the Clock trigger which will call the emailSpreadsheetAsHTMLTable():
function buildClockTrigger() {
ScriptApp.newTrigger('emailSpreadsheetAsHTMLTable').timeBased().everyDays(1).create();
}
Reference
Clock Triggers
JS filter
JS map

Acumatica Web API Apply Discounts

I am trying to get a way to obtain the discount code from the web service API, i.e would there be a function call that could tell me which discount code to apply?
I am otherwise attempting to retrieve the discount codes but they can be by Item or By Item Price Class and Customer etc etc which is making the code longer than expected.
Hopeing there is a "GetBestDiscount" facility in the API that could help me?
Thanks,
G
At this moment Acumatica Discount Engine is deactivated for any Web Service call. Due to this fact, entering an order line without any discount will not populate the discount code.
However, at Acumatica University there is the GetSalesPrice.zip customization package made specifically to retrieving the price of an Item for a Customer (attached to the I200 Screen-Based Web Services 5.3 and the I210 Contract-Based Web Services 5.3 sources).
Sample call for Screen-Based API:
Content getSalesPriceSchema = context.GetSchema();
var commands = new Command[]
{
new Value
{
Value = customer,
LinkedCommand =getSalesPriceSchema.RequiredInputParameters.Customer
},
new Value
{
Value = inventoryID,
LinkedCommand =getSalesPriceSchema.RequiredInputParameters.InventoryID
},
getSalesPriceSchema.OutputPrice.Price
};
Content price = context.Submit(commands)[0];
Sample call for Contract-Based API:
GetSalesPriceInquiry priceToBeGet = new GetSalesPriceInquiry
{
Customer = new StringValue { Value = customer },
InventoryID = new StringValue { Value = inventoryID }
};
GetSalesPriceInquiry stockItemPrice = (GetSalesPriceInquiry)soapClient.Put(priceToBeGet);
I tried creating a temporary Sales order line via API Order Entry Screen without saving it as Gabriel suggestion.
I can retrieve the set price no problems but the Discount Percentage and Discount Code is not returned.
The discount percentage returned is zero and the discount Code is blank.
This is because the Acumatica Discount Engine is deactivated for any Web Service call I guess.
Any reason why the Acumatica Discount Engine is deactivated for any Web Service calls?
There is no such API, however you could use the sales order entry screen API to create a temporary sales order, add one line to it and retrieve the set price or discount without saving the order. This will be the most accurate information, since discounts and price can also depend on the date, quantity and also on other products being ordered at the same time.

SharePoint Online Access Request Status Codes

I am using CSOM to retrieve items from the "Access Requests" list.
(https://sharepointSite.sharepoint.com/sites/siteName/Access%20Requests/pendingreq.aspx)
I am trying to figure out all the possible values of the "Status" field.
I have found the following values (just from looking at the access requests page and comparing to the data retrieved from my code)
0 = Pending
2 = Accepted
5 = Withdrawn
I have been unable to find any reference to these codes online.
Can anyone point me to a reference for these values or let me know what you figured our on your own?
OK whilst "_ModerationStatus" values are 0..4 (where 0=Approved), this is not the same as the "Status" field of an Access Request, which has values I have obtained from the Microsoft.SharePoint.SPAccessRequestsUtility (public enum StatusToInt), as well as accessrequestsviewtemplate.debug.js file (located in 15 hive, Layouts folder):
0=Pending (which could also trigger expired is an invitation)
1=Approved
2=Accepted
3=Denied
4=Expired
5=Revoked
I obtained this from powershell hitting the field and obtaining the SchemaXml property, reverse-engineering code as well as this MS link:
https://msdn.microsoft.com/en-us/library/jj675013(v=office.12).aspx
Also look at these links depending upon your need:
https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spaccessrequests.changerequeststatus.aspx
https://msdn.microsoft.com/en-us/library/jj674880(v=office.12).aspx
Statuses are stored in Approval Status field (Internal Name: _ModerationStatus) for the specified Access Requests list
How to retrieve values of _ModerationStatus field via CSOM
var listTitle = "Access Requests";
var fieldName = "_ModerationStatus";
var list = ctx.Web.Lists.GetByTitle(listTitle);
var field = list.Fields.GetByInternalNameOrTitle(fieldName);
ctx.Load(field);
ctx.ExecuteQuery();
var fieldChoice = ctx.CastTo<FieldChoice>(field);
var values = fieldChoice.Choices;
foreach (var value in values)
{
Console.WriteLine(value);
}
About Moderation Status field
According to 2.2.1.2.13 Moderation Status the following are all possible valid values for Moderation Status:
0 - The list item is approved.
1 - The list item has been denied approval.
2 - The list item is pending approval.
3 - The list item is in the draft or checked out state.
4 - The list item is scheduled for automatic approval at a future date.

Resources