matkant_invoice/invoice.rb

166 lines
4.1 KiB
Ruby
Raw Normal View History

2017-01-30 13:06:38 +00:00
# coding: utf-8
require 'yaml'
2017-01-31 14:38:08 +00:00
require 'mysql2'
2017-02-01 10:18:38 +00:00
require 'optparse'
2017-01-30 13:06:38 +00:00
2017-01-31 14:38:08 +00:00
load 'config.rb'
2017-02-01 10:18:38 +00:00
Options = {}
OptionParser.new do |opts|
opts.banner = "Usage: invoice.rb [options]"
opts.on("-d", "--draft", "Generate invoices with 'DRAFT' watermark") do |d|
Options[:draft] = d
end
opts.on("-v", "--verbose", "Run verbosely") do |v|
Options[:verbose] = v
end
opts.on("-s", "--silent", "Run silently (overrules -v)") do |s|
Options[:silent] = true
Options[:verbose] = false
end
end.parse!
2017-02-01 11:37:43 +00:00
class Transaction
def initialize(time, person, product, amount: 1)
2017-01-30 13:06:38 +00:00
@time = time
@person = person
@product = product
@amount = amount
end
2017-02-01 11:37:43 +00:00
2017-01-30 13:06:38 +00:00
attr_accessor :time, :person, :product, :amount
end
2017-02-01 11:37:43 +00:00
class Product
def initialize(id, description, price)
@id = id
@description = description
@price = price
end
def to_s
"#{@id} => #{@description}, #{@price}"
end
attr_accessor :id, :description, :price
end
2017-01-30 13:06:38 +00:00
def read_file(file)
rows = Array.new
CSV.foreach(file, col_sep: ';', converters: :float) do |row|
2017-02-01 11:37:43 +00:00
rows << Transaction.new(row[0],row[1],row[2],amount: row[3])
2017-01-30 13:06:38 +00:00
end
rows
end
2017-01-31 14:38:08 +00:00
def read_db(db)
2017-02-01 11:37:43 +00:00
transactions = Array.new
db.query("SELECT * FROM Transactions").each do |trans|
if date_of_prev('monday').to_time < trans["time"]
transactions << Transaction.new(trans["time"], trans["buyer"],
trans["product"], amount: trans["amount"])
2017-01-31 14:38:08 +00:00
end
end
2017-02-01 11:37:43 +00:00
return transactions
2017-01-31 14:38:08 +00:00
end
2017-02-01 11:37:43 +00:00
# Partition transactions into the persons who they belong to
def partition_transactions(transactions)
persons = Hash.new
transactions.each do |trans|
# Initialize data structures if not already done
if !(persons[trans.person])
persons[trans.person] = {}
end
if !(persons[trans.person][trans.product])
persons[trans.person][trans.product] = 0
end
persons[trans.person][trans.product] += trans.amount
2017-01-30 13:06:38 +00:00
end
2017-02-01 11:37:43 +00:00
return persons
2017-01-30 13:06:38 +00:00
end
2017-02-01 11:37:43 +00:00
def generate_receipt(persons,draft)
2017-01-30 14:23:50 +00:00
counter = 0
2017-02-01 11:37:43 +00:00
# Iterate through persons who have purchased something in the given timeframe
persons.each do |person, products|
2017-01-30 14:23:50 +00:00
counter += 1
2017-02-01 11:37:43 +00:00
2017-01-30 13:06:38 +00:00
yaml = YAML_BASE.clone
2017-02-01 10:18:38 +00:00
yaml["to"] = Names[person]
2017-02-01 11:37:43 +00:00
yaml["invoice-nr"] = Time.now.strftime('%Y%W') + "-" + counter.to_s
# Iterate through products purchased and write data to yaml hash
products.each do |id, amount|
2017-01-30 13:06:38 +00:00
yaml["service"] = Array.new unless yaml["service"]
2017-02-01 11:37:43 +00:00
hash = {description: Products[id].description,
pieceprice: Products[id].price.to_i,
price: Products[id].price.to_i*amount, amount: amount}
# Convert Symbols to Strings to ensure compatibility with pandoc
2017-01-30 13:06:38 +00:00
yaml["service"] << Hash[hash.map{ |k, v| [k.to_s, v] }]
end
2017-01-31 15:13:26 +00:00
2017-02-01 11:37:43 +00:00
# Write draft watermark on invoice if marked as draft
2017-02-01 10:18:38 +00:00
if draft
2017-01-31 15:13:26 +00:00
yaml["draft"] = "true"
yaml["drafttext"] = "Udkast"
end
2017-02-01 11:37:43 +00:00
# Convert Symbols to Strings to ensure compatibility with pandoc
2017-01-30 14:23:50 +00:00
output = Hash[yaml.map{ |k, v| [k.to_s, v] }].to_yaml
output += "---\n"
2017-02-01 11:37:43 +00:00
# Write output to file
2017-02-01 10:18:38 +00:00
File.open("./pandoc/details.yml","w") do |file|
file << output
end
2017-02-01 11:37:43 +00:00
# Generate PDF using pandoc
2017-01-30 14:23:50 +00:00
`cd pandoc/; make -B`
2017-02-01 10:18:38 +00:00
`cp pandoc/output.pdf #{OUTPUT_PATH}/#{yaml["invoice-nr"]}.pdf`
2017-02-01 11:37:43 +00:00
2017-02-01 10:18:38 +00:00
puts "#{person}: #{yaml["invoice-nr"]}.pdf" unless Options[:silent]
2017-01-30 13:06:38 +00:00
end
end
2017-01-31 14:38:08 +00:00
# Utility
def date_of_next(day)
date = Date.parse(day)
delta = date > Date.today ? 0 : 7
date + delta
end
def date_of_prev(day)
date = Date.parse(day)
delta = date < Date.today ? 0 : 7
date - delta
end
2017-02-01 11:37:43 +00:00
db = Mysql2::Client.new(:host => DB_HOST, :username => DB_USER, :database => DB_DB)
# Initialize product and member hashses
Products = Hash.new
Names = Hash.new
Prices = Hash.new
db.query("SELECT * FROM Products").each do |p|
product = Product.new(p['id'], p['description'], p['price'])
Products[p['id']] = product
if Options[:verbose]
puts "Found product: #{product}"
end
end
db.query("SELECT * FROM Persons").each do |member|
Names[member['id']] = member['name']
end
partition = partition_transactions(read_db(db))
2017-02-01 10:18:38 +00:00
generate_receipt(partition,Options[:draft])