Know the rules The Paceline Forum Builder's Spotlight


Go Back   The Paceline Forum > General Discussion

Reply
 
Thread Tools Display Modes
  #1  
Old 10-25-2018, 11:10 AM
tuscanyswe tuscanyswe is offline
Senior Member
 
Join Date: Mar 2008
Posts: 8,971
Anyone good with javascript?

Im not, actually i dont know very much at all. I would say im on the level of someone who just bought their first dropbar equipped bike and had a few training rides.. Even tho that is the case im still thinking i can likely compete in a grand tour with a bit of practise..

And in that spirit im trying to get a google sheet to do all my invoices for me at the press on a button. Since the script i stole was not designed to be compatible with my sheets specifcly, there are concearns, most have been ironed out but for some reason the function gets stuck on a get date issue. So the script / function can only do one invoice from the sheet-list before it crash since it cant find or write the date in the specified places (or at least thats what i think is happening but the reality could be that im riding tubulars with an innertube as only means of fixing a puncture..) What do i know??.


So this is the error message i get "TypeError: Cannot find function getMonth in object"

This is the code suspected of failing me

"if (key === "date") {
// Invoice Date
invoiceDate = (values.getMonth() + 1) + "-" + values.getDate() + "-" + values.getFullYear();
replace('%date%', invoiceDate, docBody); // Write data"



So whats going wrong here?

Last edited by tuscanyswe; 10-25-2018 at 11:14 AM.
Reply With Quote
  #2  
Old 10-25-2018, 11:56 AM
Dude Dude is offline
Everyone's Favorite Droid
 
Join Date: Dec 2003
Location: Killadelphia, PA
Posts: 1,585
pulled from here: https://www.w3schools.com/jsref/jsref_getmonth.asp or if you hate w3 schools irrationally like other devs you can get it here too: https://developer.mozilla.org/en-US/.../Date/getMonth

I'm a pretty good "JV" developer, not varsity level though.

A few questions...when you console.log(values) what does it return? it should be a date object.

your code seems to work fine when 'values' is defined correctly. This works in my browser console.
Code:
var values = new Date;
invoiceDate = (values.getMonth() + 1) + "-" + values.getDate() + "-" + values.getFullYear();
//replace(param1, param2, param3) isn't defined
//console log = '10-25-2018'
Attached Images
File Type: png valuesNotDefined.png (15.9 KB, 132 views)
__________________
"I used to be with it. Then they changed what it was. Now, what I'm with isn't it, and whats it is weird and scary."
-Abe Simpson
Reply With Quote
  #3  
Old 10-25-2018, 12:47 PM
Dude Dude is offline
Everyone's Favorite Droid
 
Join Date: Dec 2003
Location: Killadelphia, PA
Posts: 1,585
ooOOOooo...i just read the first two paragraphs of your post...my response probably doesn't help all that much.
__________________
"I used to be with it. Then they changed what it was. Now, what I'm with isn't it, and whats it is weird and scary."
-Abe Simpson
Reply With Quote
  #4  
Old 10-25-2018, 12:52 PM
deechee deechee is offline
Senior Member
 
Join Date: Jul 2004
Location: Canada
Posts: 1,488
kind of hard without seeing everything, but seems like your getMonth isn't defined or accessible from the class.

Run through a debugger like intellij and it'll probably help you (ie. highlight if the function isn't recognized etc.) Intellij should be available as a trial.
Reply With Quote
  #5  
Old 10-25-2018, 01:10 PM
tuscanyswe tuscanyswe is offline
Senior Member
 
Join Date: Mar 2008
Posts: 8,971
Thank you both..

Well actually it did help, as i did not know i could get automated help with debugging the code from various sources including console..

So that will likely help me in general once im more in to this.

But i have through trial an error (perhaps wrongly) concluded that its this string of code that somehow is not perfect or perhaps not compatible with my sheet and its settings.

Thing is the sheet give me the error MONTH message when i type it like this:

invoiceDate = (values.getMonth() + 1) + "-" + values.getDate() + "-" + values.getFullYear();
replace('%date%', invoiceDate, docBody);


And sheet give me the error YEAR message when i type it like this (only thing i changed in code):

invoiceDate = (values.getFullYear() + "-" + values.getDate() + "-" + values.getMonth() + 1);


So i get 2 different errors depending on how i type that string which (for me) makes me think that the error was in the code but perhaps its in the actual document or some compatability issues since im swedish and running some formats in google sheets like date in swedish version which is YYYY-MM-DD.
I have no idea if this could be causing issues but when i switch the code around it gives me different error messages.

But i guess this could also mean that somewhere in this process its trying to name something in this Date format and it cant do so and just leaves me with the first function it fails, either month or year in this case and perhaps thats not indicative of the code beeing wrong initself just that it cant replace or name the information as requested for some reason?


This is the entire script if that helps:

/*================================================= ================================================== =============*
Invoice Generator
================================================== ================================================== ============
Version: 1.0.0
Project Page: https://github.com/Sheetgo/invoice-generator
Copyright: (c) 2018 by Sheetgo

License: GNU General Public License, version 3 (GPL-3.0)
http://www.opensource.org/licenses/gpl-3.0.html
----------------------------------------------------------------------------------------------------------------
Changelog:

1.0.0 Initial release
*================================================= ================================================== =============*/

/**
* Project Settings
* @type {JSON}
*/
SETTINGS = {

// Spreadsheet Url (template filled with your data)
spreadsheetUrl: "<https://docs.google.com/spreadsheets/d/1NBEPoO_MchUlATvX5OXvIpCZ_alaKLawPja9Qgt_Cmw/edit?usp=sharing>",

// Spreadsheet name
sheetName: "Data",

// Document Url
documentUrl: "<https://docs.google.com/document/d/1mjs7bJ2dGRthi4CwyLEVF9GoSzoqZTkHDW28fNxU2m8/edit?usp=sharing>",

// Folder id
folderUrl: "https://drive.google.com/drive/folders/0B9O67uHE5cUJMUdqYVlnQ0NIQTg"

};


/**
* This funcion will run when you open the spreadsheet. It creates a Spreadsheet menu option to run the spript
*/
function onOpen() {
// Adds a custom menu to the spreadsheet.
SpreadsheetApp.getUi()
.createMenu('Invoice Generator')
.addItem('Generate Invoices', 'sendInvoice')
.addToUi();
}


/**
* Reads the spreadsheet data and creates the PDF invoice
*/
function sendInvoice() {
// Opens the spreadsheet and access the tab containing the data
var ss = SpreadsheetApp.openByUrl(SETTINGS.spreadsheetUrl);
Logger.log("apa", SETTINGS.folderUrl)
var dataSheet = ss.getSheetByName(SETTINGS.sheetName);

// Gets all values from the instanciated tab
var sheetValues = dataSheet.getDataRange().getValues();

// Gets the PDF url column index
var pdfIndex = sheetValues[0].indexOf("PDF Url");

// Gets the user's name (will be used as the PDF file name)
var clientNameIndex = sheetValues[0].indexOf("client_name");

var counter, invoiceNumCount, pdfInvoice, invoiceId, key, values, pdfName, invoiceNumber, invoiceDate;
for (var i = 1; i < sheetValues.length; i++) {

// Creates the Invoice
if (!sheetValues[i][pdfIndex]) {

// Duplicate teh template on Google Drive to manipulate the data
invoiceId = DriveApp.getFileById(SETTINGS.documentUrl.substrin g((SETTINGS.documentUrl.indexOf("/d/")+3), (SETTINGS.documentUrl.indexOf("/d/")+3+44))).makeCopy('Template Copy').getId();

// Instantiate the document
var docBody = DocumentApp.openById(invoiceId).getBody();

// Iterates over the spreadsheet columns to get the values used to write the document
for (var j = 0; j < sheetValues[i].length; j++) {

// Key and Values to be replaced
key = sheetValues[0][j];
values = sheetValues[i][j];

if (key === "date") {
// Invoice Date
invoiceDate = (values.getMonth() + 1) + "-" + values.getDate() + "-" + values.getFullYear();
replace('%date%', invoiceDate, docBody); // Write data



} else if (values) {
// Everything else appart from date values
if (key.indexOf("price") > -1 || key === "discount" || key.indexOf("total") > -1) {
replace('%' + key + '%', '' + values.toFixed(2), docBody); // Replace values
} else if (key === "tax_id") {
replace('%' + key + '%', "Org. nr. " + values, docBody); // Replace the tax_id
} else {
replace('%' + key + '%', values, docBody)
}

} else {
replace('%' + key + '%', '', docBody) // Replace empty string
}
}

// Get last invoice count from the tab 'Count'
counter = ss.getSheetByName('Count').getRange('A2');
invoiceNumCount = counter.getValue() + 1;

invoiceNumber = invoiceNumCount.padLeft(4, '0') + "-" + invoiceDate.split("-")[2];
replace('%number%', invoiceNumber, docBody);

// Rename the invoice document
pdfName = sheetValues[i][clientNameIndex] + " " + invoiceNumber;
DocumentApp.openById(invoiceId).setName(pdfName).s aveAndClose();

// Convert the Invoice Document into a PDF file
pdfInvoice = convertPDF(invoiceId);
// Set the PDF url into the spreadsheet
dataSheet.getRange(i + 1, pdfIndex + 1).setValue(pdfInvoice[0]);

// Update invoice counter
counter.setValue(invoiceNumCount);

// Delete the original document (will leave only the PDF)
Drive.Files.remove(invoiceId);
}
}
}


/**
* Convert a Google Docs into a PDF file
* @param {string} id - File Id
* @returns {*[]}
*/
function convertPDF(id) {
var doc = DocumentApp.openById(id);
var docBlob = doc.getAs('application/pdf');
docBlob.setName(doc.getName() + ".pdf"); // Add the PDF extension
var invFolder = SETTINGS.folderUrl.substring((SETTINGS.folderUrl.i ndexOf("/folders/")+9));
var file = DriveApp.getFolderById(invFolder).createFile(docBl ob);
var url = file.getUrl();
return [url, file.getId()];
}


/**
* Replace the document key/value
* @param {String} key - The document key to be replaced
* @param {String} text - The document text to be inserted
* @param {Body} body - the active document's Body.
* @returns {Element}
*/
function replace(key, text, body) {
return body.editAsText().replaceText(key, text);
}


/**
* Returns a new string that right-aligns the characters in this instance by padding them with any string on the left,
* for a specified total length.
* @param {Number} n - Number of characters to pad
* @param {String} str - The string to be padded
* @returns {string}
*/
Number.prototype.padLeft = function (n, str) {
return Array(n - String(this).length + 1).join(str || '0') + this;
};

Last edited by tuscanyswe; 10-25-2018 at 01:19 PM.
Reply With Quote
  #6  
Old 10-25-2018, 02:07 PM
Dude Dude is offline
Everyone's Favorite Droid
 
Join Date: Dec 2003
Location: Killadelphia, PA
Posts: 1,585
I'm assuming you're using this invoice generator (https://blog.sheetgo.com/google-clou...ice-generator/). If so, i think your spreadsheet isn't setup correctly OR something about the tab it's pulling data from isn't set up correctly.
__________________
"I used to be with it. Then they changed what it was. Now, what I'm with isn't it, and whats it is weird and scary."
-Abe Simpson
Reply With Quote
  #7  
Old 10-25-2018, 02:13 PM
tuscanyswe tuscanyswe is offline
Senior Member
 
Join Date: Mar 2008
Posts: 8,971
Quote:
Originally Posted by Dude View Post
I'm assuming you're using this invoice generator (https://blog.sheetgo.com/google-clou...ice-generator/). If so, i think your spreadsheet isn't setup correctly OR something about the tab it's pulling data from isn't set up correctly.
Yes that is correct.

Thank for the suggestion. Yeah that quite possibly could be it considering the date format changes depending on if doc saved as us or swedish version for instance.

hmm Yeah well, it wont be easy to find the actual problem. The function is actually working now it just gives me the error code after the last invoice but it can still do them all (around 30). It does however not clean up the last documents from which it creates the last in line pdf-invoice. I guess that could be indicative of where the problem lies. Il start to look there.

I could spend a lot of time debugging this before i accidently find issue but i can also use it as is so thats good

Last edited by tuscanyswe; 10-25-2018 at 02:24 PM.
Reply With Quote
  #8  
Old 10-25-2018, 04:13 PM
OtayBW OtayBW is offline
Senior Member
 
Join Date: Feb 2008
Location: NoBaltoCo
Posts: 6,164
Quote:
Originally Posted by tuscanyswe View Post
Well actually it did help, as i did not know i could get automated help with debugging the code from various sources including console..

So that will likely help me in general once im more in to this.

But i have through trial an error (perhaps wrongly) concluded that its this string of code that somehow is not perfect or perhaps not compatible with my sheet and its settings.

Thing is the sheet give me the error MONTH message when i type it like this:

invoiceDate = (values.getMonth() + 1) + "-" + values.getDate() + "-" + values.getFullYear();
replace('%date%', invoiceDate, docBody);


And sheet give me the error YEAR message when i type it like this (only thing i changed in code):

invoiceDate = (values.getFullYear() + "-" + values.getDate() + "-" + values.getMonth() + 1);


So i get 2 different errors depending on how i type that string which (for me) makes me think that the error was in the code but perhaps its in the actual document or some compatability issues since im swedish and running some formats in google sheets like date in swedish version which is YYYY-MM-DD.
I have no idea if this could be causing issues but when i switch the code around it gives me different error messages.

But i guess this could also mean that somewhere in this process its trying to name something in this Date format and it cant do so and just leaves me with the first function it fails, either month or year in this case and perhaps thats not indicative of the code beeing wrong initself just that it cant replace or name the information as requested for some reason?


This is the entire script if that helps:

/*================================================= ================================================== =============*
Invoice Generator
================================================== ================================================== ============
Version: 1.0.0
Project Page: https://github.com/Sheetgo/invoice-generator
Copyright: (c) 2018 by Sheetgo

License: GNU General Public License, version 3 (GPL-3.0)
http://www.opensource.org/licenses/gpl-3.0.html
----------------------------------------------------------------------------------------------------------------
Changelog:

1.0.0 Initial release
*================================================= ================================================== =============*/

/**
* Project Settings
* @type {JSON}
*/
SETTINGS = {

// Spreadsheet Url (template filled with your data)
spreadsheetUrl: "<https://docs.google.com/spreadsheets/d/1NBEPoO_MchUlATvX5OXvIpCZ_alaKLawPja9Qgt_Cmw/edit?usp=sharing>",

// Spreadsheet name
sheetName: "Data",

// Document Url
documentUrl: "<https://docs.google.com/document/d/1mjs7bJ2dGRthi4CwyLEVF9GoSzoqZTkHDW28fNxU2m8/edit?usp=sharing>",

// Folder id
folderUrl: "https://drive.google.com/drive/folders/0B9O67uHE5cUJMUdqYVlnQ0NIQTg"

};


/**
* This funcion will run when you open the spreadsheet. It creates a Spreadsheet menu option to run the spript
*/
function onOpen() {
// Adds a custom menu to the spreadsheet.
SpreadsheetApp.getUi()
.createMenu('Invoice Generator')
.addItem('Generate Invoices', 'sendInvoice')
.addToUi();
}


/**
* Reads the spreadsheet data and creates the PDF invoice
*/
function sendInvoice() {
// Opens the spreadsheet and access the tab containing the data
var ss = SpreadsheetApp.openByUrl(SETTINGS.spreadsheetUrl);
Logger.log("apa", SETTINGS.folderUrl)
var dataSheet = ss.getSheetByName(SETTINGS.sheetName);

// Gets all values from the instanciated tab
var sheetValues = dataSheet.getDataRange().getValues();

// Gets the PDF url column index
var pdfIndex = sheetValues[0].indexOf("PDF Url");

// Gets the user's name (will be used as the PDF file name)
var clientNameIndex = sheetValues[0].indexOf("client_name");

var counter, invoiceNumCount, pdfInvoice, invoiceId, key, values, pdfName, invoiceNumber, invoiceDate;
for (var i = 1; i < sheetValues.length; i++) {

// Creates the Invoice
if (!sheetValues[i][pdfIndex]) {

// Duplicate teh template on Google Drive to manipulate the data
invoiceId = DriveApp.getFileById(SETTINGS.documentUrl.substrin g((SETTINGS.documentUrl.indexOf("/d/")+3), (SETTINGS.documentUrl.indexOf("/d/")+3+44))).makeCopy('Template Copy').getId();

// Instantiate the document
var docBody = DocumentApp.openById(invoiceId).getBody();

// Iterates over the spreadsheet columns to get the values used to write the document
for (var j = 0; j < sheetValues[i].length; j++) {

// Key and Values to be replaced
key = sheetValues[0][j];
values = sheetValues[i][j];

if (key === "date") {
// Invoice Date
invoiceDate = (values.getMonth() + 1) + "-" + values.getDate() + "-" + values.getFullYear();
replace('%date%', invoiceDate, docBody); // Write data



} else if (values) {
// Everything else appart from date values
if (key.indexOf("price") > -1 || key === "discount" || key.indexOf("total") > -1) {
replace('%' + key + '%', '' + values.toFixed(2), docBody); // Replace values
} else if (key === "tax_id") {
replace('%' + key + '%', "Org. nr. " + values, docBody); // Replace the tax_id
} else {
replace('%' + key + '%', values, docBody)
}

} else {
replace('%' + key + '%', '', docBody) // Replace empty string
}
}

// Get last invoice count from the tab 'Count'
counter = ss.getSheetByName('Count').getRange('A2');
invoiceNumCount = counter.getValue() + 1;

invoiceNumber = invoiceNumCount.padLeft(4, '0') + "-" + invoiceDate.split("-")[2];
replace('%number%', invoiceNumber, docBody);

// Rename the invoice document
pdfName = sheetValues[i][clientNameIndex] + " " + invoiceNumber;
DocumentApp.openById(invoiceId).setName(pdfName).s aveAndClose();

// Convert the Invoice Document into a PDF file
pdfInvoice = convertPDF(invoiceId);
// Set the PDF url into the spreadsheet
dataSheet.getRange(i + 1, pdfIndex + 1).setValue(pdfInvoice[0]);

// Update invoice counter
counter.setValue(invoiceNumCount);

// Delete the original document (will leave only the PDF)
Drive.Files.remove(invoiceId);
}
}
}


/**
* Convert a Google Docs into a PDF file
* @param {string} id - File Id
* @returns {*[]}
*/
function convertPDF(id) {
var doc = DocumentApp.openById(id);
var docBlob = doc.getAs('application/pdf');
docBlob.setName(doc.getName() + ".pdf"); // Add the PDF extension
var invFolder = SETTINGS.folderUrl.substring((SETTINGS.folderUrl.i ndexOf("/folders/")+9));
var file = DriveApp.getFolderById(invFolder).createFile(docBl ob);
var url = file.getUrl();
return [url, file.getId()];
}


/**
* Replace the document key/value
* @param {String} key - The document key to be replaced
* @param {String} text - The document text to be inserted
* @param {Body} body - the active document's Body.
* @returns {Element}
*/
function replace(key, text, body) {
return body.editAsText().replaceText(key, text);
}


/**
* Returns a new string that right-aligns the characters in this instance by padding them with any string on the left,
* for a specified total length.
* @param {Number} n - Number of characters to pad
* @param {String} str - The string to be padded
* @returns {string}
*/
Number.prototype.padLeft = function (n, str) {
return Array(n - String(this).length + 1).join(str || '0') + this;
};
OW - MY EYES!!!
__________________
“A bicycle is not a sofa”
-- Dario Pegoretti
Reply With Quote
  #9  
Old 10-25-2018, 07:33 PM
Dude Dude is offline
Everyone's Favorite Droid
 
Join Date: Dec 2003
Location: Killadelphia, PA
Posts: 1,585
It's giving you 2 different errors because js will stop executing as soon as it throws an error. When it's year first, it errors that the year is the problem, when month is first it errors that the month is the problem.

If you want more help, you can dm me. Even people who LIKE js don't like js, normal people probably don't want to see it. I believe the data is the culprit.
__________________
"I used to be with it. Then they changed what it was. Now, what I'm with isn't it, and whats it is weird and scary."
-Abe Simpson
Reply With Quote
  #10  
Old 10-25-2018, 07:51 PM
d_douglas d_douglas is offline
Senior Member
 
Join Date: Nov 2004
Location: Victoria, BC
Posts: 9,835
Oh, this is just gross. Looking at code makes me kinda queasy.
Reply With Quote
  #11  
Old 10-26-2018, 07:18 AM
palincss palincss is offline
Senior Member
 
Join Date: Dec 2004
Location: Alexandria VA
Posts: 5,839
Quote:
Originally Posted by tuscanyswe View Post

Thing is the sheet give me the error MONTH message when i type it like this:

invoiceDate = (values.getMonth() + 1) + "-" + values.getDate() + "-" + values.getFullYear();
replace('%date%', invoiceDate, docBody);


And sheet give me the error YEAR message when i type it like this (only thing i changed in code):

invoiceDate = (values.getFullYear() + "-" + values.getDate() + "-" + values.getMonth() + 1);


So i get 2 different errors depending on how i type that string which (for me) makes me think that the error was in the code but perhaps its in the actual document or some compatability issues since im swedish and running some formats in google sheets like date in swedish version which is YYYY-MM-DD.
I have no idea if this could be causing issues but when i switch the code around it gives me different error messages.
Is it possible it's throwing an error on the first method it encounters? If you've got the year method first, it croaks on that; if you've got the month method first, that's where it croaks. Not inconsistent with the notion that the object itself has not been properly set up.
Reply With Quote
  #12  
Old 10-26-2018, 07:44 AM
redir's Avatar
redir redir is offline
Senior Member
 
Join Date: Jan 2007
Location: Mountains of Virginia
Posts: 6,848
Quote:
Originally Posted by deechee View Post
kind of hard without seeing everything, but seems like your getMonth isn't defined or accessible from the class.

Run through a debugger like intellij and it'll probably help you (ie. highlight if the function isn't recognized etc.) Intellij should be available as a trial.
That's exactly what it is saying.

What is the object and where is it defined? Look in there for a function called getMonth and you will probably not find it. If that function is inherent in JS then you are probably missing that library.

Not a JS developer but I understand OOP.
Reply With Quote
  #13  
Old 10-26-2018, 11:21 AM
tuscanyswe tuscanyswe is offline
Senior Member
 
Join Date: Mar 2008
Posts: 8,971
Thanks everyone!

Dude i may take you up on that offer down the line, much appreciated!

For now i think its something i dont have enough time to dwell on as i have other more pressing matters atm. And the script works now.. Only on the last qued invoice do i get the error message, so it can function properly even with that fault as i can easily bypass it by just adding a bogus invoice in the end for the script to fail on. Not ideal but when i have more time to figure it out i shall revisit .)

Cheers
Björn

Last edited by tuscanyswe; 10-26-2018 at 11:24 AM.
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -5. The time now is 12:46 PM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.