diff options
Diffstat (limited to 'fracture/invoice.py')
-rw-r--r-- | fracture/invoice.py | 67 |
1 files changed, 47 insertions, 20 deletions
diff --git a/fracture/invoice.py b/fracture/invoice.py index 84c0f9b..b3fa6b6 100644 --- a/fracture/invoice.py +++ b/fracture/invoice.py @@ -1,6 +1,7 @@ import sqlite3 from datetime import date, datetime, timedelta from configparser import ConfigParser +from collections import OrderedDict import io class Tax: @@ -9,6 +10,7 @@ class Tax: self.ratio = ratio class Product: + VATS = () def __init__(self, description, units=1.0, price_unit=0.0, vat = 0.21): if len(description) == 0: @@ -16,7 +18,15 @@ class Product: self.description = description self.units = units self.price_unit = price_unit - self.vat = vat + if vat in self.VATS: + self.vat = vat + else: + raise ValueError("Product: No valid VAT. Valid are:"+\ + str(Product.VATS)) + def calc_base(self): + return self.price_unit * self.units + def calc_charged_vat(self): + return self.calc_base() * self.vat class Customer: def __init__(self, name, id = "", address = ""): @@ -323,26 +333,43 @@ class Invoice: pass def to_row(self): - psum = ((i.price_unit*i.units, - i.price_unit*i.units*i.vat) for i in self.products) - base = 0 - vat = 0 - for i in psum: - base += i[0] - vat += i[1] - - row = { - "type": self.type, - "series": self.series, - "id": self.format_id(), - "date": self.date.strftime("%Y-%m-%d"), - "customer_id": self.customer.id, - "customer_name": self.customer.name, - "base": round(base, self.CURRENCY_DECIMAL), - "vat": round(vat, self.CURRENCY_DECIMAL) - } + row = OrderedDict( + type = self.type, + id = self.format_id(), + date = self.date.strftime("%Y-%m-%d"), + customer_id = self.customer.id, + customer_name = self.customer.name, + ) + + total_base = 0 + total_charged = 0 + + vats = sorted(Product.VATS) + to_base_key = lambda v: "base("+str(v*100)+"%)" + to_vat_key = lambda v: "VAT("+str(v*100)+"%)" + for vat in vats: + ps = filter(lambda p: p.vat == vat, self.products) + + vat_base = 0 + charged_vat = 0 + for product in ps: + vat_base += product.calc_base() + charged_vat += product.calc_charged_vat() + row[to_base_key(vat)] = round(vat_base, self.CURRENCY_DECIMAL) + row[to_vat_key(vat)] = round(charged_vat, self.CURRENCY_DECIMAL) + + total_base += vat_base + total_charged += vat_base + charged_vat + + row["base(TOTAL)"] = round(total_base, self.CURRENCY_DECIMAL) + + to_tax_key = lambda tax: tax.name + "("+ str(tax.ratio*100) +"%)" for i in self.taxes: - row["tax-" + i.name] = round(i.ratio * base, self.CURRENCY_DECIMAL) + tax_amount = i.ratio * total_base + row[to_tax_key(i)] = round(tax_amount, self.CURRENCY_DECIMAL) + total_charged += tax_amount + + row["TOTAL"] = round(total_charged, self.CURRENCY_DECIMAL) return row |