functional clean-up

This commit is contained in:
Christoffer Müller Madsen 2017-02-01 13:43:05 +01:00
parent fa705fd813
commit 2ab0e88e25

View File

@ -8,7 +8,6 @@ load 'config.rb'
Options = {} Options = {}
OptionParser.new do |opts| OptionParser.new do |opts|
opts.banner = "Usage: invoice.rb [options]" opts.banner = "Usage: invoice.rb [options]"
opts.on("-d", "--draft", "Generate invoices with 'DRAFT' watermark") do |d| opts.on("-d", "--draft", "Generate invoices with 'DRAFT' watermark") do |d|
Options[:draft] = d Options[:draft] = d
end end
@ -21,13 +20,30 @@ OptionParser.new do |opts|
end end
end.parse! end.parse!
Transaction = Struct.new(:time, :person, :product, :amount) Transaction = Struct.new(:time, :person, :product, :amount)
Product = Struct.new(:id, :description, :price) do Product = Struct.new(:id, :description, :price) do
def to_s def to_s
"#{id} => #{description}, #{price}" "#{id} => #{description}, #{price}"
end end
end end
class Person
def initialize(id, name)
@id = id
@name = name
@purchases = {}
end
def to_s
id
end
attr_reader :id
attr_accessor :name, :purchases
end
def read_file(file) def read_file(file)
rows = Array.new rows = Array.new
CSV.foreach(file, col_sep: ';', converters: :float) do |row| CSV.foreach(file, col_sep: ';', converters: :float) do |row|
@ -36,52 +52,69 @@ def read_file(file)
rows rows
end end
def read_db(db) def load_transactions_from_db(db)
transactions = Array.new transactions = Array.new
db.query("SELECT * FROM Transactions").each do |trans| db.query("SELECT * FROM Transactions").each do |row|
if date_of_prev('monday').to_time < trans["time"] if date_of_prev('monday').to_time < row["time"]
transactions << Transaction.new(trans["time"], trans["buyer"], transactions << Transaction.new(row["time"], row["buyer"],
trans["product"], trans["amount"]) row["product"], row["amount"])
end end
end end
return transactions return transactions
end end
# Partition transactions into the persons who they belong to def load_persons_from_db(db)
def partition_transactions(transactions) persons = {}
persons = Hash.new db.query("SELECT * FROM Persons").each do |row|
transactions.each do |trans| persons[row['id']] = Person.new(row['id'],row['name'])
# Initialize data structures if not already done
if !(persons[trans.person])
persons[trans.person] = {}
end end
if !(persons[trans.person][trans.product]) return persons
persons[trans.person][trans.product] = 0
end end
persons[trans.person][trans.product] += trans.amount def load_products_from_db(db)
products = {}
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
return products
end
# Partition transactions into the persons who they belong to
def partition_transactions(transactions,persons)
transactions.each do |t|
# Initialize data structures if not already done
if !(persons[t.person].purchases[t.product])
persons[t.person].purchases[t.product] = 0
end
persons[t.person].purchases[t.product] += t.amount
end end
return persons return persons
end end
def generate_receipt(persons,draft) def generate_receipt(persons,products,draft)
counter = 0 counter = 0
# Iterate through persons who have purchased something in the given timeframe # Iterate through persons who have purchased something in the given timeframe
persons.each do |person, products| persons.each do |id, person|
counter += 1 counter += 1
yaml = YAML_BASE.clone yaml = YAML_BASE.clone
yaml["to"] = Names[person] yaml["to"] = person.name
yaml["invoice-nr"] = Time.now.strftime('%Y%W') + "-" + counter.to_s yaml["invoice-nr"] = Time.now.strftime('%Y%W') + "-" + counter.to_s
# Iterate through products purchased and write data to yaml hash # Iterate through products purchased and write data to yaml hash
products.each do |id, amount| person.purchases.each do |id, amount|
yaml["service"] = Array.new unless yaml["service"] yaml["service"] = Array.new unless yaml["service"]
hash = {description: Products[id].description, hash = {description: products[id].description,
pieceprice: Products[id].price.to_i, pieceprice: products[id].price.to_i,
price: Products[id].price.to_i*amount, amount: amount} price: products[id].price.to_i*amount, amount: amount}
# Convert Symbols to Strings to ensure compatibility with pandoc # Convert Symbols to Strings to ensure compatibility with pandoc
yaml["service"] << Hash[hash.map{ |k, v| [k.to_s, v] }] yaml["service"] << Hash[hash.map{ |k, v| [k.to_s, v] }]
@ -122,24 +155,12 @@ def date_of_prev(day)
date - delta date - delta
end end
#################
db = Mysql2::Client.new(:host => DB_HOST, :username => DB_USER, :database => DB_DB) db = Mysql2::Client.new(:host => DB_HOST, :username => DB_USER, :database => DB_DB)
# Initialize product and member hashses transactions = load_transactions_from_db(db)
Products = Hash.new persons = load_persons_from_db(db)
Names = Hash.new products = load_products_from_db(db)
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] generate_receipt(partition_transactions(transactions,persons), products, Options[:draft])
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))
generate_receipt(partition,Options[:draft])