Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Do something in 5 with gas 3-simple invoicing app

5,010 views

Published on

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

Published in: Technology
  • Follow the link, new dating source: ♥♥♥ http://bit.ly/369VOVb ♥♥♥
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Sex in your area is here: ♥♥♥ http://bit.ly/369VOVb ♥♥♥
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

Do something in 5 with gas 3-simple invoicing app

  1. 1. do something useful with Apps Script in 5 minutes 3.Simple invoicing app Bruce McPherson www.mcpher.com
  2. 2. Snippet objectives ● Use the lessons learned in ‘using a spreadsheet as a database’ ● Gets transactions and master data from database. I’m using sheets as the database here. ● Calculates and generates personalized invoice emails Libraries used ● database abstraction ● driver sheet
  3. 3. Add libraries to script create a script Open resources Add references to libraries Mrckbr9_w7PCphJtOzhzA_Cz3TLx7pV4j MHfCjPQlweartW45xYs6hFai_d-phDA33
  4. 4. Take a copy of the test data Product and Customer data https://docs.google.com/spreadsheets/d/1EhgZ1-q9tP1u9BSEQPIQiSGozdfjsHn3zB1JfQGbftw/edit?usp=sharing Transaction data https://docs.google.com/spreadsheets/d/1gmOEvILq0wygW3iN9exe4P0iu0x2wgwlX25D_QHgq10/edit?usp=sharing
  5. 5. layout what you are going to do function 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 }
  6. 6. 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
  7. 7. 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');
  8. 8. 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;
  9. 9. 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
  10. 10. 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]; Look up the master data from customers and product table and join to transactions // 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]; }); });
  11. 11. 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
  12. 12. 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
  13. 13. 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
  14. 14. Follow up materials Take a copy of this script Take a copy of these slides Join me on G+, or the G+ community More on desktop liberation More on database abstraction

×