home · contact · privacy
Refactor what goes into balance view generations. master
authorChristian Heller <c.heller@plomlompom.de>
Sat, 3 Jan 2026 18:08:07 +0000 (19:08 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Sat, 3 Jan 2026 18:08:07 +0000 (19:08 +0100)
src/ledgplom/http.py
src/ledgplom/ledger.py
src/templates/balance.tmpl

index 4d97736f186946b147097f43645a93c1ada451f3..4efc05aabc2202cff16d08208a23d1249610fe6b 100644 (file)
@@ -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]]:
     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]] = []
             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):
                 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
                         break
-                    if already_registered:
+                    if already_listed:
                         continue
                         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)
                         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': []}
                                 '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()
             return observed_tree
 
         accounts = self.server.ledger.calc_accounts()
index 590561cfa135dceb62e936b75d8484ea70d7467b..3a07f3513b6b6214750c5d119fe6e30f40bdf861 100644 (file)
@@ -79,21 +79,24 @@ class Account:
         if self.parent:
             self.parent.children += [self]
 
         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:
         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.'
 
     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)
 
     def __init__(self, lines: list[_BookingLine]) -> None:
         super().__init__(lines)
-        changes = _Wealth()
+        diffs = _Wealth()
         sink_account = None
         self.sink_error = ''
         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]:
         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'
             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)
                     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:
         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'
 
             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.'
     @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
                 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
                 ensure_accounts(acc_name)
                 accounts[acc_name].add_wealth_diff(block.id_, wealth)
         return accounts
index 630bfbfd404913024a5b4995098eb0abbf63555a..3b2d9a943f7eba35837415469cfd6231672f1389 100644 (file)
@@ -31,12 +31,12 @@ span.indent {
     <td class="balance currency">{{ macros.currency_short(currency) }}</td>
     </tr>
 {% endmacro %}
     <td class="balance currency">{{ macros.currency_short(currency) }}</td>
     </tr>
 {% endmacro %}
-{% if account.get_wealth(block_id).moneys|length > 0 %}
+{% if account.get_wealth_at(block_id).moneys|length > 0 %}
     <tr>
     <td class="money">
     <tr>
     <td class="money">
-    {% if account.get_wealth(block_id).moneys|length == 1 %}
+    {% if account.get_wealth_at(block_id).moneys|length == 1 %}
         <table>
         <table>
-        {% 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 %}
         </table>
             {{tr_money_balance(amount, currency)}}
         {% endfor %}
         </table>
@@ -44,7 +44,7 @@ span.indent {
         <details>
         <summary>
         <table>
         <details>
         <summary>
         <table>
-        {% 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 %}
             {% if 1 == loop.index %}
                 {{tr_money_balance(amount, currency)}}
             {% endif %}
@@ -52,7 +52,7 @@ span.indent {
         </table>
         </summary>
         <table>
         </table>
         </summary>
         <table>
-        {% 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 %}
             {% if 1 < loop.index %}
                 {{tr_money_balance(amount, currency)}}
             {% endif %}