summaryrefslogtreecommitdiff
path: root/lasku.py
diff options
context:
space:
mode:
Diffstat (limited to 'lasku.py')
-rwxr-xr-xlasku.py129
1 files changed, 87 insertions, 42 deletions
diff --git a/lasku.py b/lasku.py
index 6ee3b6f..110c636 100755
--- a/lasku.py
+++ b/lasku.py
@@ -9,6 +9,9 @@ import yaml
def debug(*args):
sys.stderr.write('{}\n'.format(' '.join(str(x) for x in args)))
+def round(f):
+ return int(f + 0.5)
+
def euros(cents):
return '%.02f' % (cents / 100.0)
@@ -18,51 +21,93 @@ class Item:
def __init__(self, itemdict):
self.dict = dict(itemdict)
- count = itemdict['count']
- if count == "":
- return
+ bignum = 99999999
+ self.dict.update({
+ 'unit_net_cents': bignum,
+ 'unit_vat_cents': bignum,
+ 'unit_cents': bignum,
+ 'total_net_cents': bignum,
+ 'total_vat_cents': bignum,
+ 'total_cents': bignum,
+ })
+
+ self.compute()
+ self.check()
+
+ self.dict.update({
+ 'unit_net_euros': euros(self['unit_net_cents']),
+ 'unit_vat_euros': euros(self['unit_vat_cents']),
+ 'unit_euros': euros(self['unit_cents']),
+ 'total_net_euros': euros(self['total_net_cents']),
+ 'total_vat_euros': euros(self['total_vat_cents']),
+ 'total_euros': euros(self['total_cents']),
+ })
+
+ def __getitem__(self, key):
+ return self.dict[key]
+
+ def __setitem__(self, key, value):
+ self.dict[key] = value
- unit_cents = int(itemdict['unit'] * 100.0)
- vatpc = float(itemdict['vatpc']) / 100.0
+ def items(self):
+ return self.dict.items()
- self.total_cents = count * unit_cents
+ def check(self):
+ count = self['count']
+ vatpc = int(self['vatpc'] / 100.0)
+ unit_net_cents = self['unit_net_cents']
+ unit_vat_cents = self['unit_vat_cents']
+ unit_cents = self['unit_cents']
+ total_net_cents = self['total_net_cents']
+ total_vat_cents = self['total_vat_cents']
+ total_cents = self['total_cents']
+
+ debug(self.dict)
+
+ assert unit_net_cents * count == total_net_cents, \
+ '{} * {} != {}'.format(unit_net_cents, count, total_net_cents)
+
+ assert unit_net_cents + unit_vat_cents == unit_cents, \
+ '{} + {} != {}'.format(unit_net_cents, unit_vat_cents, unit_cents)
+
+ assert total_cents == count * (unit_net_cents + unit_vat_cents), \
+ '{} != {} * ({} + {})'.format(
+ total_net_cents, count, unit_net_cents, unit_vat_cents)
- self.vat_cents = 0
if vatpc > 0:
- unit_cents_with_vat = int(unit_cents / (1.0 - vatpc))
- unit_vat_cents = unit_cents_with_vat - unit_cents
- debug('dict', self.dict)
- debug('total_cents', self.total_cents)
- debug('vatpc', vatpc)
- debug('unit_cents_with_vat', unit_cents_with_vat)
- debug('unit_vat_cents', unit_vat_cents)
- debug('calc', int(vatpc * unit_cents_with_vat))
- assert int(unit_cents_with_vat * vatpc) == unit_vat_cents
- assert unit_cents_with_vat == unit_cents + unit_vat_cents
- self.vat_cents = unit_vat_cents * count
+ assert unit_cents == unit_net_cents + unit_vat_cents, \
+ '{} != {} + {}'.format(unit_cents, unit_net_cents, unit_vat_cents)
- self.dict.update({
- 'unit_euros': euros(unit_cents),
- 'total_cents': self.total_cents,
- 'total': euros(self.total_cents),
- 'unitwithvat': euros(unit_cents + self.vat_cents),
- 'vat_cents': self.vat_cents,
- 'vat': euros(self.vat_cents),
- 'vatsum': euros(self.vat_cents * count),
- 'totalwithvat': euros(count * (unit_cents + self.vat_cents)),
- })
+ assert total_vat_cents == count * unit_vat_cents, \
+ '{} != {} * {}'.format(total_vat_cents, count, unit_net_cents)
+
+ assert round(total_cents * vatpc) == total_vat_cents, \
+ '{} * {} != {}'.format(
+ total_cents, vatpc, total_vat_cents)
+
+ def compute(self):
+ count = self['count']
+ vatpc = float(self['vatpc']) / 100.0
+
+ unit_net_cents = self['unit_net_cents'] = round(self['unit'] * 100.0)
+ unit_vat_cents = self['unit_vat_cents'] = round(
+ unit_net_cents * vatpc / (1 - vatpc))
+ unit_cents = self['unit_cents'] = unit_net_cents + unit_vat_cents
+ self['total_net_cents'] = unit_net_cents * count
+ self['total_vat_cents'] = unit_vat_cents * count
+ self['total_cents'] = count * unit_cents
item_template = (
r'\raggedbottom #number# & '
r'\parbox[t]{5.5cm}{#desc#\\#date#} & '
r'\raggedbottom #count# & '
+ r'\raggedbottom #unit_net_euros# & '
r'\raggedbottom #unit_euros# & '
- r'\raggedbottom #unitwithvat# & '
r'\raggedbottom #vatpc#\% & '
- r'\raggedbottom #total# & '
- r'\raggedbottom #vatsum# & '
- r'\raggedbottom #totalwithvat# \\[2.2ex]'
+ r'\raggedbottom #total_net_euros# & '
+ r'\raggedbottom #total_vat_euros# & '
+ r'\raggedbottom #total_euros# \\[2.2ex]'
)
@@ -90,21 +135,21 @@ values = dict(company)
values.update(invoice)
itemtext = ''
-total_cents = 0
-total_vat = 0
-total_sum = 0
+sum_net_cents = 0
+sum_vat_cents = 0
+sum_cents = 0
for item in items:
it = Item(item)
- itemtext += substitute_all(item_template, it.dict)
- total_cents += it.total_cents
- total_vat += it.vat_cents
- total_sum += it.total_cents + it.vat_cents
+ itemtext += substitute_all(item_template, it)
+ sum_net_cents += it['total_net_cents']
+ sum_vat_cents += it['total_vat_cents']
+ sum_cents += it['total_cents']
values['itemtext'] = itemtext
-values['totalraw'] = euros(total_cents)
-values['totalvat'] = euros(total_vat)
-values['totalsum'] = euros(total_sum)
+values['totalraw'] = euros(sum_net_cents)
+values['totalvat'] = euros(sum_vat_cents)
+values['totalsum'] = euros(sum_cents)
values['amount'] = values['totalsum']