From: Christian Heller Date: Sat, 3 Jan 2026 18:08:07 +0000 (+0100) Subject: Refactor what goes into balance view generations. X-Git-Url: https://plomlompom.com/repos/booking/%7B%7B%20web_path%20%7D%7D/decks/%7B%7Bprefix%7D%7D/%7B%7Bdb.prefix%7D%7D/task?a=commitdiff_plain;p=ledgplom Refactor what goes into balance view generations. --- diff --git a/src/ledgplom/http.py b/src/ledgplom/http.py index 4d97736..4efc05a 100644 --- a/src/ledgplom/http.py +++ b/src/ledgplom/http.py @@ -132,27 +132,22 @@ class _Handler(PlomHttpHandler): def get_edit(self, ctx, raw: bool) -> None: 'Display edit form for individual Booking.' def make_balance_roots(b: DatBlock) -> list[dict[str, Any]]: - acc_changes = b.booking.account_changes if b.booking else {} + if not b.booking: + return [] observed_tree: list[dict[str, Any]] = [] - for full_path in sorted(acc_changes.keys()): - parent_children: list[dict[str, Any]] = observed_tree + for full_path in sorted(b.booking.diffs_targeted.keys()): + node_children: list[dict[str, Any]] = observed_tree for path, _ in Account.path_to_steps(full_path): - already_registered = False - for child in [n for n in parent_children - if path == n['name']]: - parent_children = child['children'] - already_registered = True + already_listed = False + for n in [n for n in node_children if path == n['name']]: + node_children = n['children'] + already_listed = True break - if already_registered: + if already_listed: continue - pre = accounts[path].get_wealth(id_ - 1) - post = accounts[path].get_wealth(id_) - targeted = full_path == path - diff = { - cur: amt for cur, amt in (post - pre).moneys.items() - if amt != 0 - or (targeted and cur in acc_changes[full_path].moneys)} - if diff or targeted: + diff = b.booking.diffs_inheriting[path].moneys + if (targeted := full_path == path) or diff: + pre, post = accounts[path].get_wealth_at_excl_incl(id_) displayed_currs = set(diff.keys()) for wealth in pre, post: wealth.ensure_currencies(displayed_currs) @@ -164,8 +159,8 @@ class _Handler(PlomHttpHandler): 'wealth_diff': diff, 'wealth_after': post.moneys, 'children': []} - parent_children += [node] - parent_children = node['children'] + node_children += [node] + node_children = node['children'] return observed_tree accounts = self.server.ledger.calc_accounts() diff --git a/src/ledgplom/ledger.py b/src/ledgplom/ledger.py index 590561c..3a07f35 100644 --- a/src/ledgplom/ledger.py +++ b/src/ledgplom/ledger.py @@ -79,21 +79,24 @@ class Account: if self.parent: self.parent.children += [self] - def _get_local_wealth(self, up_incl: int) -> _Wealth: - 'Calculate by summing all recorded wealth diffs up+incl. _Booking.' - wealth = _Wealth() - for wealth_diff in [wd for id_, wd in self._wealth_diffs.items() - if id_ <= up_incl]: - wealth += wealth_diff - return wealth - - def get_wealth(self, up_incl: int) -> _Wealth: - 'Total of .local_wealth with that of .children up+incl. _Booking.' - total = _Wealth() - total += self._get_local_wealth(up_incl) + def get_wealth_at_excl_incl(self, up_incl: int) -> tuple[_Wealth, _Wealth]: + 'Total, with .children wealths, of wealth until Bookings of up_incl.' + total_excl = _Wealth() + total_incl = _Wealth() + for idx, wealth_diff in [(i, w) for i, w in self._wealth_diffs.items() + if i <= up_incl]: + if idx != up_incl: + total_excl += wealth_diff + total_incl += wealth_diff for child in self.children: - total += child.get_wealth(up_incl) - return total + totals_excl_incl = child.get_wealth_at_excl_incl(up_incl) + total_excl += totals_excl_incl[0] + total_incl += totals_excl_incl[1] + return total_excl, total_incl + + def get_wealth_at(self, up_incl: int) -> _Wealth: + 'Variant of .get_wealth_at_excl_incl only returning incl result.' + return self.get_wealth_at_excl_incl(up_incl)[1] def add_wealth_diff(self, booking_id: int, wealth_diff: _Wealth) -> None: 'Add knowledge that _Booking of booking_id added wealth_diff.' @@ -369,13 +372,13 @@ class _Booking(_LinesBlock[_BookingLine]): def __init__(self, lines: list[_BookingLine]) -> None: super().__init__(lines) - changes = _Wealth() + diffs = _Wealth() sink_account = None self.sink_error = '' - self.account_changes: dict[str, _Wealth] = {} + self.diffs_targeted: dict[str, _Wealth] = {} for tf_line in [tl for tl in self.transfer_lines if not tl.errors]: - if tf_line.account not in self.account_changes: - self.account_changes[tf_line.account] = _Wealth() + if tf_line.account not in self.diffs_targeted: + self.diffs_targeted[tf_line.account] = _Wealth() if tf_line.amount is None: if sink_account: self.sink_error = 'too many sinks' @@ -383,14 +386,25 @@ class _Booking(_LinesBlock[_BookingLine]): sink_account = tf_line.account continue assert isinstance(tf_line.amount, Decimal) - change = _Wealth({tf_line.currency: tf_line.amount}) - self.account_changes[tf_line.account] += change - changes += change + diff = _Wealth({tf_line.currency: tf_line.amount}) + self.diffs_targeted[tf_line.account] += diff + diffs += diff if sink_account: - self.account_changes[sink_account] += changes.as_sink - elif not changes.sink_empty: + self.diffs_targeted[sink_account] += diffs.as_sink + elif not diffs.sink_empty: self.sink_error = 'needed sink missing' + @property + def diffs_inheriting(self) -> dict[str, _Wealth]: + 'All accounts affected by .diffs_targeted with calculated totals.' + acc_diffs: dict[str, _Wealth] = {} + for full_path, moneys in self.diffs_targeted.items(): + for path, _ in Account.path_to_steps(full_path): + if path not in acc_diffs: + acc_diffs[path] = _Wealth() + acc_diffs[path] += moneys + return acc_diffs + @property def intro_line(self) -> _IntroLine: 'Return collected _IntroLine.' @@ -626,7 +640,7 @@ class Ledger: accounts[acc_name].desc = desc for block in [b for b in self.blocks if b.booking]: assert block.booking is not None - for acc_name, wealth in block.booking.account_changes.items(): + for acc_name, wealth in block.booking.diffs_targeted.items(): ensure_accounts(acc_name) accounts[acc_name].add_wealth_diff(block.id_, wealth) return accounts diff --git a/src/templates/balance.tmpl b/src/templates/balance.tmpl index 630bfbf..3b2d9a9 100644 --- a/src/templates/balance.tmpl +++ b/src/templates/balance.tmpl @@ -31,12 +31,12 @@ span.indent { {{ macros.currency_short(currency) }} {% endmacro %} -{% if account.get_wealth(block_id).moneys|length > 0 %} +{% if account.get_wealth_at(block_id).moneys|length > 0 %} - {% if account.get_wealth(block_id).moneys|length == 1 %} + {% if account.get_wealth_at(block_id).moneys|length == 1 %} - {% for currency, amount in account.get_wealth(block_id).moneys.items() %} + {% for currency, amount in account.get_wealth_at(block_id).moneys.items() %} {{tr_money_balance(amount, currency)}} {% endfor %}
@@ -44,7 +44,7 @@ span.indent {
- {% for currency, amount in account.get_wealth(block_id).moneys.items() %} + {% for currency, amount in account.get_wealth_at(block_id).moneys.items() %} {% if 1 == loop.index %} {{tr_money_balance(amount, currency)}} {% endif %} @@ -52,7 +52,7 @@ span.indent {
- {% for currency, amount in account.get_wealth(block_id).moneys.items() %} + {% for currency, amount in account.get_wealth_at(block_id).moneys.items() %} {% if 1 < loop.index %} {{tr_money_balance(amount, currency)}} {% endif %}