14

Click here to load reader

Do something in 5 with gas 3-simple invoicing app

Embed Size (px)

DESCRIPTION

quick 5 minute tutorial. join multiple databases and create personalized email invoices with google apps script

Citation preview

Page 1: Do something in 5 with gas 3-simple invoicing app

do something useful with Apps Script in 5 minutes

3.Simple invoicing appBruce McPhersonwww.mcpher.com

Page 3: Do something in 5 with gas 3-simple invoicing app

Add libraries to script

create a scriptOpen resourcesAdd references to librariesMrckbr9_w7PCphJtOzhzA_Cz3TLx7pV4j

MHfCjPQlweartW45xYs6hFai_d-phDA33

Page 4: Do something in 5 with gas 3-simple invoicing app

Take a copy of the test data

Product and Customer datahttps://docs.google.com/spreadsheets/d/1EhgZ1-q9tP1u9BSEQPIQiSGozdfjsHn3zB1JfQGbftw/edit?usp=sharing

Transaction datahttps://docs.google.com/spreadsheets/d/1gmOEvILq0wygW3iN9exe4P0iu0x2wgwlX25D_QHgq10/edit?usp=sharing

Page 5: Do something in 5 with gas 3-simple invoicing app

layout what you are going to dofunction myFunction() {

// get customer handle

// get product handle

// get transactions handle

// get all the transaction data ready to be invoiced

// organize into customers/transactions

// now we have an array of customers and their associated transactions - join to masters

// produce and email invoice with multiple transactions per customer

}

Page 6: Do something in 5 with gas 3-simple invoicing app

create function for repeated patterns/**

* open a sheet as a database

* @param {string} sheetName the sheetName

* @param {string} sheetId the spreadsheet id

* @return {DbAbstraction} the handle

*/

function getHandle ( sheetName, sheetId) {

// open spreadsheet as database

var handler = new cDbAbstraction.DbAbstraction (cDriverSheet, {

siloid:sheetName,

dbid:sheetId,

});

if (!handler.isHappy()) throw 'unable to open sheet';

return handler;

}

We’ll call this function for each of the database tables we need to open

Page 7: Do something in 5 with gas 3-simple invoicing app

Get handlers for each table

// get customer handle

var customerHandle = getHandle ('customers' , '1EhgZ1-q9tP1u9BSEQPIQiSGozdfjsHn3zB1JfQGbftw');

// get product handle

var productHandle = getHandle ('products' , '1EhgZ1-q9tP1u9BSEQPIQiSGozdfjsHn3zB1JfQGbftw');

// get transactions handle

var transactionHandle = getHandle ('transactions' , '1gmOEvILq0wygW3iN9exe4P0iu0x2wgwlX25D_QHgq10');

Page 8: Do something in 5 with gas 3-simple invoicing app

Get the transaction data and sort it

// get all the transaction data ready to be invoiced

var transactionResult = transactionHandle.query ({status:'delivered'},{sort:'customer id'});

if (transactionResult.handleCode < 0) throw transactionResult.handleError;

Page 9: Do something in 5 with gas 3-simple invoicing app

Reduce transactions

// organize into customers/transactions - data is already sorted

var customerTransactions = transactionResult.data.reduce ( function (p,c) {

var t = p.length ? p[p.length-1] : null;

if (!t || c['customer id'] !== t.cid) {

// its a new customer

p.push( t = {cid:c['customer id'], transactions:[]} );

}

t.transactions.push(c);

return p;

},[]);

Reduce to one object per customer, so we can consolidate transactions to a single invoice

Page 10: Do something in 5 with gas 3-simple invoicing app

Join transactions to masters // now we have an array of customers and their associated transactions - join to masters

customerTransactions.forEach ( function (d) {

var result = customerHandle.query ({"customer id":d.cid});

// just fail if customer not found

if ( result.handleCode < 0 || result.data.length !== 1 ) throw JSON.stringify(result);

d.customer = result.data.slice()[0];

// get the product data

d.transactions.forEach (function (p){

var result = productHandle.query ({"product id":p['product id']});

if ( result.handleCode < 0 || result.data.length !== 1 ) throw JSON.stringify(result);

p.product = result.data.slice()[0];

});

});

Look up the master data from customers and product table and join to transactions

Page 11: Do something in 5 with gas 3-simple invoicing app

Function to create email content function getEmailContent (d) {

return '<div>'

+ d.customer.company + '<br>'

+ '<table><tbody><th>Product name</th><th>Quantity</th><th>Total</th>'

+ d.transactions.map(function(e) {

return '<tr><td>'+e.product['product name']

+'</td><td>'+e.quantity

+'</td><td>'+e.quantity*e.product['unit price']

+'</td></tr>';

}).join(‘’)

+ '<tr><td>Total</td><td></td><td>'

+ d.transactions.reduce(function(p,c) {

return p+c.quantity*c.product['unit price'];

},0)

+ '</td></tr>'

+ '</tbody></table>'

+ '</div>';

}

Very basic email invoice. You’d probably want to spruce up and use a proper template

Page 12: Do something in 5 with gas 3-simple invoicing app

Send email invoices

customerTransactions.forEach (function(d) {

MailApp.sendEmail({

to: d.customer.email,

subject: "Invoice from desktop liberation",

htmlBody: getEmailContent (d)

});

});

Very basic email invoice. You’d probably want to spruce up and use a proper template

Page 13: Do something in 5 with gas 3-simple invoicing app

Further homework

● Using what you learned in graduating to a database, why not migrate some of the test data to a database and redo.

● Incorporate a real email templating solution like Romain Vialard’s YAMM

● Improve error handling● Update database status when email is sent