From 2ab0e88e2541391d372b940b53c922463b9c71a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoffer=20M=C3=BCller=20Madsen?= Date: Wed, 1 Feb 2017 13:43:05 +0100 Subject: [PATCH] functional clean-up --- invoice.rb | 103 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 41 deletions(-) diff --git a/invoice.rb b/invoice.rb index 345d5ab..120fb78 100644 --- a/invoice.rb +++ b/invoice.rb @@ -8,7 +8,6 @@ load 'config.rb' 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 @@ -21,13 +20,30 @@ OptionParser.new do |opts| end end.parse! + Transaction = Struct.new(:time, :person, :product, :amount) + Product = Struct.new(:id, :description, :price) do def to_s "#{id} => #{description}, #{price}" 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) rows = Array.new CSV.foreach(file, col_sep: ';', converters: :float) do |row| @@ -36,52 +52,69 @@ def read_file(file) rows end -def read_db(db) +def load_transactions_from_db(db) 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"], trans["amount"]) + db.query("SELECT * FROM Transactions").each do |row| + if date_of_prev('monday').to_time < row["time"] + transactions << Transaction.new(row["time"], row["buyer"], + row["product"], row["amount"]) end end return transactions end -# 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] = {} +def load_persons_from_db(db) + persons = {} + db.query("SELECT * FROM Persons").each do |row| + persons[row['id']] = Person.new(row['id'],row['name']) + end + return persons +end + +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 - if !(persons[trans.person][trans.product]) - persons[trans.person][trans.product] = 0 + 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[trans.person][trans.product] += trans.amount + persons[t.person].purchases[t.product] += t.amount end return persons end -def generate_receipt(persons,draft) +def generate_receipt(persons,products,draft) counter = 0 # Iterate through persons who have purchased something in the given timeframe - persons.each do |person, products| + persons.each do |id, person| counter += 1 yaml = YAML_BASE.clone - yaml["to"] = Names[person] + 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 - products.each do |id, amount| + person.purchases.each do |id, amount| yaml["service"] = Array.new unless yaml["service"] - hash = {description: Products[id].description, - pieceprice: Products[id].price.to_i, - price: Products[id].price.to_i*amount, amount: amount} + 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 yaml["service"] << Hash[hash.map{ |k, v| [k.to_s, v] }] @@ -122,24 +155,12 @@ def date_of_prev(day) date - delta end +################# + 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 +transactions = load_transactions_from_db(db) +persons = load_persons_from_db(db) +products = load_products_from_db(db) -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]) +generate_receipt(partition_transactions(transactions,persons), products, Options[:draft])