From 83047ea410d28ff850999c9841b584e04f1155a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoffer=20M=C3=BCller=20Madsen?= Date: Mon, 6 Feb 2017 16:57:06 +0100 Subject: [PATCH] add hash column containing md5 hash of pdf --- invoice.rb | 83 ++++++++++++++++++++++++++++++++++++++++----- pandoc/template.tex | 8 +++-- retrieve.rb | 17 ++++++++++ 3 files changed, 97 insertions(+), 11 deletions(-) create mode 100644 retrieve.rb diff --git a/invoice.rb b/invoice.rb index 120fb78..b911882 100644 --- a/invoice.rb +++ b/invoice.rb @@ -2,6 +2,7 @@ require 'yaml' require 'mysql2' require 'optparse' +require 'digest' load 'config.rb' @@ -18,6 +19,10 @@ OptionParser.new do |opts| Options[:silent] = true Options[:verbose] = false end + opts.on("-m", "--mobilepay", "Generate QR codes for MobilePay") do |m| + require 'rqrcode' + Options[:mobilepay] = true + end end.parse! @@ -55,7 +60,12 @@ end def load_transactions_from_db(db) transactions = Array.new db.query("SELECT * FROM Transactions").each do |row| - if date_of_prev('monday').to_time < row["time"] + if Date.today.monday? + previous_monday = Date.today.to_time + else + previous_monday = date_of_prev('monday').to_time + end + if previous_monday < row["time"] transactions << Transaction.new(row["time"], row["buyer"], row["product"], row["amount"]) end @@ -66,8 +76,13 @@ end def load_persons_from_db(db) persons = {} db.query("SELECT * FROM Persons").each do |row| - persons[row['id']] = Person.new(row['id'],row['name']) + person = Person.new(row['id'],row['name']) + persons[row['id']] = person + if Options[:verbose] + puts "Found person: #{person}" + end end + return persons end @@ -98,27 +113,42 @@ def partition_transactions(transactions,persons) return persons end -def generate_receipt(persons,products,draft) +def generate_receipt(persons,products,db,draft) counter = 0 # Iterate through persons who have purchased something in the given timeframe persons.each do |id, person| - counter += 1 + # Skip persons with no transactions + if person.purchases.empty? + if Options[:verbose] + puts "Skipping #{id} with no transactions" + end + next + end + counter += 1 + total_payment = 0 + yaml = YAML_BASE.clone yaml["to"] = person.name yaml["invoice-nr"] = Time.now.strftime('%Y%W') + "-" + counter.to_s + + # Iterate through products purchased and write data to yaml hash person.purchases.each do |id, amount| yaml["service"] = Array.new unless yaml["service"] + piece_price = products[id].price.to_i + price = piece_price.to_i*amount hash = {description: products[id].description, - pieceprice: products[id].price.to_i, - price: products[id].price.to_i*amount, amount: amount} + pieceprice: piece_price, + price: price, amount: amount} + total_payment += price # Convert Symbols to Strings to ensure compatibility with pandoc yaml["service"] << Hash[hash.map{ |k, v| [k.to_s, v] }] end + total_payment = total_payment * 0.90 # Write draft watermark on invoice if marked as draft if draft @@ -126,12 +156,37 @@ def generate_receipt(persons,products,draft) yaml["drafttext"] = "Udkast" end + # Generate QR code for MobilePay if option set + if Options[:mobilepay] + mobilepay_url = "https://mobilepay.dk/da-dk/pages/betal.aspx?phone=#{MOBILEPAY_PHONE_NUMBER}&amount=#{total_payment.round(2)}&comment=Tilbagebetaling%20-%20Faktura%20nr.%20#{yaml["invoice-nr"]}&lock=1" + if Options[:verbose] + puts "Generating QR code for #{id} with URL #{mobilepay_url}" + end + yaml["qrcode"] = true + + + qrcode = RQRCode::QRCode.new(mobilepay_url) + image = qrcode.as_png( + resize_gte_to: false, + resize_exactly_to: false, + fill: 'white', + color: 'black', + size: 480, + border_modules: 4, + module_px_size: 6, + file: nil # path to write + ) + File.open("./pandoc/qr.png","w+") do |file| + file << image + end + end + # Convert Symbols to Strings to ensure compatibility with pandoc output = Hash[yaml.map{ |k, v| [k.to_s, v] }].to_yaml output += "---\n" - + # Write output to file - File.open("./pandoc/details.yml","w") do |file| + File.open("./pandoc/details.yml","w+") do |file| file << output end @@ -139,6 +194,15 @@ def generate_receipt(persons,products,draft) `cd pandoc/; make -B` `cp pandoc/output.pdf #{OUTPUT_PATH}/#{yaml["invoice-nr"]}.pdf` + # Upload PDF to MySQL database + File.open("pandoc/output.pdf") do |file| + data = file.read + hash = Digest::MD5.new.hexdigest data + statement = db.prepare("INSERT INTO Invoices (id, person, data, hash) VALUES (?, ?, ?, ?) + ON DUPLICATE KEY UPDATE person = ?, data = ?, hash = ?") + result = statement.execute(yaml["invoice-nr"],id,data,hash,id,data,hash) + end + puts "#{person}: #{yaml["invoice-nr"]}.pdf" unless Options[:silent] end end @@ -163,4 +227,5 @@ transactions = load_transactions_from_db(db) persons = load_persons_from_db(db) products = load_products_from_db(db) -generate_receipt(partition_transactions(transactions,persons), products, Options[:draft]) +generate_receipt(partition_transactions(transactions,persons), products, db, Options[:draft]) + diff --git a/pandoc/template.tex b/pandoc/template.tex index ab3e980..3c21527 100644 --- a/pandoc/template.tex +++ b/pandoc/template.tex @@ -60,7 +60,7 @@ $endif$ \usepackage[compact]{titlesec} % For customizing title sections \titlespacing*{\section}{0pt}{3pt}{-7pt} % Remove margin bottom from the title \usepackage{arydshln} % For the dotted line on the table -\renewcommand{\arraystretch}{1.5} % Apply vertical padding to table cells +\renewcommand{\arraystretch}{1.2} % Apply vertical padding to table cells \usepackage{hhline} % For single-cell borders \usepackage{enumitem} % For customizing lists \setlist{nolistsep} % No whitespace around list items @@ -121,7 +121,7 @@ $endfor$ \vspace{1em} -\section*{\textsc{Invoice} \textsc{\#$invoice-nr$}} +\section*{\textsc{Faktura} \textsc{\#$invoice-nr$}} \footnotesize \newcounter{pos} \setcounter{pos}{0} @@ -152,4 +152,8 @@ $closingnote$ $author$ +$if(qrcode)$ +\includegraphics[width=4cm]{qr.png} +$endif$ + \end{document} diff --git a/retrieve.rb b/retrieve.rb new file mode 100644 index 0000000..711a373 --- /dev/null +++ b/retrieve.rb @@ -0,0 +1,17 @@ +require 'mysql2' + +load 'config.rb' + +db = Mysql2::Client.new(:host => DB_HOST, :username => DB_USER, :database => DB_DB) + +invoice_id = ARGV[0] +puts invoice_id +output_dir = "./output/" + +statement = db.prepare("SELECT * FROM Invoices WHERE id = ?") +result = statement.execute(invoice_id) +result.each do |row| + File.open("#{output_dir}/#{invoice_id}.pdf",'w+') do |file| + file.write(row['data']) + end +end