- def add_taxes(self, lines, finish=False):
- ret = []
- bookings, _ = parse_lines(lines)
- date = bookings[0].date_string
- acc_kk_add = 'Reserves:KrankenkassenBeitragsWachstum'
- acc_kk_minimum = 'Reserves:Month:KrankenkassenDefaultBeitrag'
- acc_kk = 'Expenses:KrankenKasse'
- acc_est = 'Reserves:Einkommenssteuer'
- acc_assets = 'Assets'
- acc_buffer = 'Reserves:NeuAnfangsPuffer:Ausgaben'
- last_monthbreak_assets = 0
- last_monthbreak_est = 0
- last_monthbreak_kk_minimum = 0
- last_monthbreak_kk_add = 0
- buffer_expenses = 0
- kk_expenses = 0
- est_expenses = 0
- months_passed = -int(finish)
- for b in self.bookings:
- if date == b.date_string:
- break
- acc_keys = b.account_changes.keys()
- if acc_buffer in acc_keys:
- buffer_expenses -= b.account_changes[acc_buffer]['€']
- if acc_kk_add in acc_keys:
- kk_expenses += b.account_changes[acc_kk_add]['€']
- if acc_kk in acc_keys:
- kk_expenses += b.account_changes[acc_kk]['€']
- if acc_est in acc_keys:
- est_expenses += b.account_changes[acc_est]['€']
- if acc_kk_add in acc_keys and acc_kk_minimum in acc_keys:
- months_passed += 1
- if finish:
- last_monthbreak_kk_add = b.account_changes[acc_kk_add]['€']
- last_monthbreak_est = b.account_changes[acc_est]['€']
- last_monthbreak_kk_minimum = b.account_changes[acc_kk_minimum]['€']
- last_monthbreak_assets = b.account_changes[acc_buffer]['€']
- old_needed_income_before_anything = - last_monthbreak_assets - last_monthbreak_kk_add - last_monthbreak_kk_minimum - last_monthbreak_est
- if finish:
- ret += [f' {acc_est} {-last_monthbreak_est}€ ; for old assumption of needed income: {old_needed_income_before_anything}€']
- _, account_sums = bookings_to_account_tree(bookings)
- expenses_so_far = -1 * account_sums[acc_assets]['€'] + old_needed_income_before_anything
- needed_income_before_kk = expenses_so_far
- ESt_this_month = 0
- left_over = needed_income_before_kk - ESt_this_month
- too_low = 0
- too_high = 2 * needed_income_before_kk
- E0 = decimal.Decimal(10908)
- E1 = decimal.Decimal(15999)
- E2 = decimal.Decimal(62809)
- E3 = decimal.Decimal(277825)
- while True:
- zvE = buffer_expenses - kk_expenses + (12 - months_passed) * needed_income_before_kk
- if finish:
- zvE += last_monthbreak_assets + last_monthbreak_kk_add + last_monthbreak_kk_minimum
- if zvE < E0:
- ESt = decimal.Decimal(0)
- elif zvE < E1:
- y = (zvE - E0)/10000
- ESt = (decimal.Decimal(979.18) * y + 1400) * y
- elif zvE < E2:
- y = (zvE - E1)/10000
- ESt = (decimal.Decimal(192.59) * y + 2397) * y + decimal.Decimal(966.53)
- elif zvE < E3:
- ESt = decimal.Decimal(0.42) * (zvE - decimal.Decimal(62809)) + decimal.Decimal(16405.54)
- else:
- ESt = decimal.Decimal(0.45) * (zvE - decimal.Decimal(277825)) + decimal.Decimal(106713.52)
- ESt_this_month = (ESt + last_monthbreak_est - est_expenses) / (12 - months_passed)
- left_over = needed_income_before_kk - ESt_this_month
- if abs(left_over - expenses_so_far) < 0.001:
- break
- elif left_over < expenses_so_far:
- too_low = needed_income_before_kk
- elif left_over > expenses_so_far:
- too_high = needed_income_before_kk
- needed_income_before_kk = too_low + (too_high - too_low)/2
- ESt_this_month = ESt_this_month.quantize(decimal.Decimal('0.00'))
- ret += [f' {acc_est} {ESt_this_month}€ ; expenses so far: {expenses_so_far:.2f}€; zvE: {zvE:.2f}€; ESt total: {ESt:.2f}€; needed before Krankenkasse: {needed_income_before_kk:.2f}€']
- kk_minimum_income = 1131.67
- if date < '2023-02-01':
- kk_minimum_income = decimal.Decimal(1096.67)
- kk_factor = decimal.Decimal(0.189)
- kk_minimum_tax = decimal.Decimal(207.27).quantize(decimal.Decimal('0.00'))
- elif date < '2023-08-01':
- kk_factor = decimal.Decimal(0.191)
- kk_minimum_tax = decimal.Decimal(216.15).quantize(decimal.Decimal('0.00'))
- else:
- kk_factor = decimal.Decimal(0.197)
- kk_minimum_tax = decimal.Decimal(222.94).quantize(decimal.Decimal('0.00'))
- kk_add_so_far = account_sums[acc_kk_add]['€'] if acc_kk_add in account_sums.keys() else 0
- kk_add = needed_income_before_kk / (1 - kk_factor) - needed_income_before_kk - kk_minimum_tax
- hit_kk_minimum_income_limit = False
- if kk_add_so_far + kk_add < 0:
- hit_kk_minimum_income_limit = True
- kk_add_uncorrect = kk_add
- kk_add = -(kk_add + kk_add_so_far)
- kk_add = decimal.Decimal(kk_add).quantize(decimal.Decimal('0.00'))
- if finish:
- ret += [f' {acc_kk_add} {-last_monthbreak_kk_add}€ ; for old assumption of needed income']
- else:
- ret += [f' {acc_kk_minimum} {kk_minimum_tax}€ ; assumed minimum income {kk_minimum_income:.2f}€ * {kk_factor:.3f}']
- if hit_kk_minimum_income_limit:
- ret += [f' {acc_kk_add} {kk_add}€ ; {needed_income_before_kk:.2f}€ / (1 - {kk_factor:.3f}) - {needed_income_before_kk:.2f}€ - {kk_minimum_tax}€ = {kk_add_uncorrect:.2f}€ would reduce current {acc_kk_dd} ({kk_add_so_far:.2f}€) below 0']
- else:
- ret += [f' {acc_kk_add} {kk_add}€ ; {needed_income_before_kk:.2f}€ / (1 - {kk_factor:.3f}) - {needed_income_before_kk:.2f}€ - {kk_minimum_tax}€']
- diff = - last_monthbreak_est + ESt_this_month - last_monthbreak_kk_add + kk_add
- if not finish:
- diff += kk_minimum_tax
- final_minus = expenses_so_far - old_needed_income_before_anything + diff
- ret += [f' {acc_assets} {-diff} €']
- ret += [f' {acc_assets} {final_minus} €']
- year_needed = buffer_expenses + final_minus + (12 - months_passed - 1) * final_minus
- if finish:
- ret += [f' {acc_buffer} {-final_minus} €']
- else:
- ret += [f' {acc_buffer} {-final_minus} € ; assume as to earn in year: {acc_buffer} + {12 - months_passed - 1} * this = {year_needed}']
- return ret
-
- # def add_mirror(self, lines):
- # ret = []
- # bookings, _ = parse_lines(lines)
- # booking = bookings[0]
- # for line in booking.lines[1:]:
- # ret += [f'? {-line[1]} {line[2]}']
- # return ret
-