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)
'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()
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.'
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'
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.'
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
<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">
- {% if account.get_wealth(block_id).moneys|length == 1 %}
+ {% if account.get_wealth_at(block_id).moneys|length == 1 %}
<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>
<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 %}
</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 %}