X-Git-Url: https://plomlompom.com/repos/do_day?a=blobdiff_plain;ds=inline;f=ledger.py;h=ee6ed807ef72b4a9601acf32d25fad6ec1e0757a;hb=ebc562af576469da5f0011e10f80c7b0490ed959;hp=27675da2778e2d7cd94c0354fa7c93848b6eef05;hpb=255b10fbe4b0c688828d510868017565af50b57f;p=misc diff --git a/ledger.py b/ledger.py index 27675da..ee6ed80 100755 --- a/ledger.py +++ b/ledger.py @@ -3,6 +3,7 @@ import sys import os import html import jinja2 +import decimal from urllib.parse import parse_qs, urlparse hostName = "localhost" serverPort = 8082 @@ -27,7 +28,6 @@ def apply_booking_to_account_balances(account_sums, account, currency, amount): def add_taxes(lines): - import decimal bookings, _ = parse_lines(lines) _, account_sums = bookings_to_account_tree(bookings) expenses_so_far = -1 * account_sums['Assets']['â¬'] @@ -36,10 +36,10 @@ def add_taxes(lines): left_over = needed_income_before_krankenkasse - ESt_this_month too_low = 0 too_high = 2 * needed_income_before_krankenkasse - E0 = 10908 - E1 = 15999 - E2 = 62809 - E3 = 277825 + E0 = decimal.Decimal(10908) + E1 = decimal.Decimal(15999) + E2 = decimal.Decimal(62809) + E3 = decimal.Decimal(277825) while True: zvE = 12 * needed_income_before_krankenkasse if zvE < E0: @@ -56,27 +56,29 @@ def add_taxes(lines): ESt = decimal.Decimal(0.45) * (zvE - decimal.Decimal(277825)) + decimal.Decimal(106713.52) ESt_this_month = ESt / 12 left_over = needed_income_before_krankenkasse - ESt_this_month - if abs(left_over - expenses_so_far) < 0.1: + if abs(left_over - expenses_so_far) < 0.001: break elif left_over < expenses_so_far: too_low = needed_income_before_krankenkasse elif left_over > expenses_so_far: too_high = needed_income_before_krankenkasse needed_income_before_krankenkasse = too_low + (too_high - too_low)/2 - line_income_tax = f' Reserves:Einkommenssteuer {ESt_this_month:.2f}⬠; expenses so far: {expenses_so_far:.2f}â¬; zvE: {zvE:.2f}â¬; ESt total: {ESt:.2f}â¬; needed before Krankenkasse: {needed_income_before_krankenkasse:.2f}â¬' - kk_minimum_income = 1096.67 + ESt_this_month = ESt_this_month.quantize(decimal.Decimal('0.00')) + line_income_tax = f' Reserves:Einkommenssteuer {ESt_this_month}⬠; expenses so far: {expenses_so_far:.2f}â¬; zvE: {zvE:.2f}â¬; ESt total: {ESt:.2f}â¬; needed before Krankenkasse: {needed_income_before_krankenkasse:.2f}â¬' + kk_minimum_income = decimal.Decimal(1096.67) kk_factor = decimal.Decimal(0.189) - kk_minimum_tax = decimal.Decimal(207.27) + kk_minimum_tax = decimal.Decimal(207.27).quantize(decimal.Decimal('0.00')) # kk_minimum_income = 1131.67 # kk_factor = decimal.Decimal(0.191) # kk_minimum_tax = decimal.Decimal(216.15) # kk_factor = decimal.Decimal(0.197) # kk_minimum_tax = decimal.Decimal(222.94) kk_add = max(0, kk_factor * needed_income_before_krankenkasse - kk_minimum_tax) - line_kk_minimum = f' Reserves:Month:Krankenkassendefaultbeitrag {kk_minimum_tax:.2f}⬠; assed minimum income {kk_minimum_income:.2f}⬠* {kk_factor:.3f}' - line_kk_add = f' Reserves:Month:Krankenkassenbeitragswachstum {kk_add:.2f}⬠; max(0, {kk_factor:.3f} * {needed_income_before_krankenkasse:.2f}⬠- {kk_minimum_tax:.2f}â¬)' + kk_add = decimal.Decimal(kk_add).quantize(decimal.Decimal('0.00')) + line_kk_minimum = f' Reserves:Month:Krankenkassendefaultbeitrag {kk_minimum_tax}⬠; assumed minimum income {kk_minimum_income:.2f}⬠* {kk_factor:.3f}' + line_kk_add = f' Reserves:Month:Krankenkassenbeitragswachstum {kk_add}⬠; max(0, {kk_factor:.3f} * {needed_income_before_krankenkasse:.2f}⬠- {kk_minimum_tax}â¬)' final_minus = expenses_so_far + ESt_this_month + kk_minimum_tax + kk_add - line_finish = f' Assets -{final_minus:.2f}â¬' + line_finish = f' Assets -{ESt_this_month + kk_minimum_tax + kk_add} ⬠; -{final_minus}â¬' return [line_income_tax, line_kk_minimum, line_kk_add, line_finish] @@ -126,7 +128,6 @@ def bookings_to_account_tree(bookings): def parse_lines(lines): import datetime - import decimal inside_booking = False date_string, description = None, None booking_lines = [] @@ -254,6 +255,7 @@ class Booking: self.lines = booking_lines self.start_line = start_line self.validate_booking_lines() + self.sink = {} self.account_changes = self.parse_booking_lines_to_account_changes() def validate_booking_lines(self): @@ -275,7 +277,7 @@ class Booking: if empty_values == 0: for k, v in sums.items(): if v != 0: - raise HandledException(f"{prefix} does not sum up to zero") + raise HandledException(f"{prefix} does not add up to zero") else: sinkable = False for k, v in sums.items(): @@ -303,6 +305,7 @@ class Booking: if sink_account: for currency, amount in debt.items(): apply_booking_to_account_balances(account_changes, sink_account, currency, -amount) + self.sink[currency] = -amount return account_changes @@ -419,10 +422,11 @@ input[type=number] { text-align: right; font-family: monospace; } if 'save' in postvars.keys(): if start == end == 0: db.append(lines) + redir_url = f'/#last' else: db.replace(start, end, lines) + redir_url = f'/#{start}' self.send_response(301) - redir_url = '/' self.send_header('Location', redir_url) self.end_headers() else: @@ -458,6 +462,8 @@ input[type=number] { text-align: right; font-family: monospace; } page += self.add_free(db, start, end, copy=True) elif parsed_url.path == '/copy_structured': page += self.add_structured(db, start, end, copy=True) + elif parsed_url.path == '/ledger2': + page += self.ledger2_as_html(db) else: page += self.ledger_as_html(db) page += self.footer @@ -487,10 +493,73 @@ input[type=number] { text-align: right; font-family: monospace; } content = "\n".join(lines) return f"
{content}" + def ledger2_as_html(self, db): + single_c_tmpl = jinja2.Template('{{c|e}}
{{date}} {{desc}} {{head_comment|e}} +[edit: structured +/ free +| copy:structured +/ free] +
{{l.acc|e}} | {{l.money|e}} | {{l.balance|e}} |
{{date}} {{desc}} {{head_comment|e}} +
{{date}} {{desc}} {{head_comment|e}} [edit: structured / free | copy:structured @@ -507,6 +576,7 @@ input[type=number] { text-align: right; font-family: monospace; } """) elements_to_write = [] last_i = i = 0 + last_start = db.bookings[-1].start_line for booking in db.bookings: i = booking.start_line elements_to_write += [single_c_tmpl.render(c=c) for c in db.comments[last_i:i] if c != ''] @@ -518,23 +588,25 @@ input[type=number] { text-align: right; font-family: monospace; } if booking_line == '': booking_lines += [{'acc': None, 'money': None, 'comment': comment}] continue + account = booking_line[0] money = '' - if booking_line[1]: + if booking_line[1] is not None: money = f'{booking_line[1]} {booking_line[2]}' - account = booking_line[0] booking_lines += [{'acc': booking_line[0], 'money':money, 'comment':comment}] elements_to_write += [booking_tmpl.render( + last=booking.start_line == last_start, start=booking.start_line, end=booking_end, date=booking.date_string, desc=booking.description, head_comment=db.comments[booking.start_line], booking_lines = booking_lines)] + elements_to_write += [single_c_tmpl.render(c=c) for c in db.comments[last_i:] if c != ''] return '\n'.join(elements_to_write) def add_free(self, db, start=0, end=0, copy=False): tmpl = jinja2.Template(""" -