From 1f9ba8eba8e60fde26cc8b66d90fe0901fe1e259 Mon Sep 17 00:00:00 2001 From: Herculino Trotta Date: Sat, 7 Nov 2026 01:30:23 -0300 Subject: [PATCH] feat(investments): break converted totals down by currency Replace the note on converted totals with a collapsible per currency, and drop the uppercase labels from the summary cards. --- app/apps/investments/services.py | 11 +++++++++ .../investments/fragments/_totals.html | 23 +++++++++++++++---- .../investments/fragments/detail.html | 1 - 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/app/apps/investments/services.py b/app/apps/investments/services.py index 45d411b4..e2dbca10 100644 --- a/app/apps/investments/services.py +++ b/app/apps/investments/services.py @@ -373,8 +373,10 @@ def summarize(performances, convert=False): "has_rate_history": True, "flows": [], "as_of": perf.as_of, + "holdings": [], }, ) + total["holdings"].append(perf) for key in ("cost_basis", "total_return", "income", "currency_effect"): total[key] += figures[key] total["has_rate_history"] &= figures.get("has_rate_history", True) @@ -388,4 +390,13 @@ def summarize(performances, convert=False): total["money_weighted"] = money_weighted_return( total["flows"], total["market_value"], total["as_of"] ) + # The same holdings in their own currencies, for a converted total + total["breakdown"] = ( + sorted( + summarize(total["holdings"]), + key=lambda part: part["currency"] != total["currency"], + ) + if total["converted_from"] + else [] + ) return list(totals.values()) diff --git a/app/templates/investments/fragments/_totals.html b/app/templates/investments/fragments/_totals.html index 4592309c..8dbdbfa1 100644 --- a/app/templates/investments/fragments/_totals.html +++ b/app/templates/investments/fragments/_totals.html @@ -4,16 +4,15 @@
-
{% translate 'Market value' %} ยท {{ c.name }}
-
{% translate 'Total return' %}
{% include 'investments/fragments/_mwr.html' with mw=total.money_weighted %} + {% translate 'total return' %}
@@ -28,9 +27,23 @@ {% endif %} {% endif %}
- {% if total.converted_from %} -
- {% translate 'Includes holdings in' %} {% for currency in total.converted_from %}{{ currency.name }}{% if not forloop.last %}, {% endif %}{% endfor %}, {% translate 'converted at the rate of each date' %} + {% if total.breakdown %} +
+ {% for part in total.breakdown %} + {% with p=part.currency %} +
+ + {{ p.name }} + + +
+
{% translate 'Return' %} {% include 'investments/fragments/_mwr.html' with mw=part.money_weighted %}
+
{% translate 'Invested' %}
+
{% translate 'Income' %}
+
+
+ {% endwith %} + {% endfor %}
{% endif %}
diff --git a/app/templates/investments/fragments/detail.html b/app/templates/investments/fragments/detail.html index 1861d10c..3adbeb74 100644 --- a/app/templates/investments/fragments/detail.html +++ b/app/templates/investments/fragments/detail.html @@ -54,7 +54,6 @@
-
{% translate 'Market value' %}
{% if perf.market_value is not None %}{% else %}-{% endif %}