Merge pull request #195

feat(insights): add Categories Overview
This commit is contained in:
Herculino Trotta
2025-02-27 23:33:25 -03:00
committed by GitHub
9 changed files with 338 additions and 24 deletions

View File

@@ -29,6 +29,11 @@ urlpatterns = [
views.category_sum_by_currency, views.category_sum_by_currency,
name="category_sum_by_currency", name="category_sum_by_currency",
), ),
path(
"insights/category-overview/",
views.category_overview,
name="category_overview",
),
path( path(
"insights/late-transactions/", "insights/late-transactions/",
views.late_transactions, views.late_transactions,

View File

@@ -0,0 +1,165 @@
from decimal import Decimal
from django.db import models
from django.db.models import Sum, Case, When, Value, DecimalField
from django.db.models.functions import Coalesce
from apps.transactions.models import Transaction
from apps.currencies.models import Currency
from apps.currencies.utils.convert import convert
def get_categories_totals(transactions_queryset, ignore_empty=False):
# Get metrics for each category and currency in a single query
category_currency_metrics = (
transactions_queryset.values(
"category",
"category__name",
"account__currency",
"account__currency__code",
"account__currency__name",
"account__currency__decimal_places",
"account__currency__prefix",
"account__currency__suffix",
"account__currency__exchange_currency",
)
.annotate(
expense_current=Coalesce(
Sum(
Case(
When(
type=Transaction.Type.EXPENSE, is_paid=True, then="amount"
),
default=Value(0),
output_field=models.DecimalField(),
)
),
Decimal("0"),
),
expense_projected=Coalesce(
Sum(
Case(
When(
type=Transaction.Type.EXPENSE, is_paid=False, then="amount"
),
default=Value(0),
output_field=models.DecimalField(),
)
),
Decimal("0"),
),
income_current=Coalesce(
Sum(
Case(
When(type=Transaction.Type.INCOME, is_paid=True, then="amount"),
default=Value(0),
output_field=models.DecimalField(),
)
),
Decimal("0"),
),
income_projected=Coalesce(
Sum(
Case(
When(
type=Transaction.Type.INCOME, is_paid=False, then="amount"
),
default=Value(0),
output_field=models.DecimalField(),
)
),
Decimal("0"),
),
)
.order_by("category__name")
)
# Process the results to structure by category
result = {}
for metric in category_currency_metrics:
# Skip empty categories if ignore_empty is True
if ignore_empty and all(
metric[field] == Decimal("0")
for field in [
"expense_current",
"expense_projected",
"income_current",
"income_projected",
]
):
continue
# Calculate derived totals
total_current = metric["income_current"] - metric["expense_current"]
total_projected = metric["income_projected"] - metric["expense_projected"]
total_income = metric["income_current"] + metric["income_projected"]
total_expense = metric["expense_current"] + metric["expense_projected"]
total_final = total_current + total_projected
category_id = metric["category"]
currency_id = metric["account__currency"]
if category_id not in result:
result[category_id] = {"name": metric["category__name"], "currencies": {}}
# Add currency data
currency_data = {
"currency": {
"code": metric["account__currency__code"],
"name": metric["account__currency__name"],
"decimal_places": metric["account__currency__decimal_places"],
"prefix": metric["account__currency__prefix"],
"suffix": metric["account__currency__suffix"],
},
"expense_current": metric["expense_current"],
"expense_projected": metric["expense_projected"],
"total_expense": total_expense,
"income_current": metric["income_current"],
"income_projected": metric["income_projected"],
"total_income": total_income,
"total_current": total_current,
"total_projected": total_projected,
"total_final": total_final,
}
# Add exchanged values if exchange_currency exists
if metric["account__currency__exchange_currency"]:
from_currency = Currency.objects.get(id=currency_id)
exchange_currency = Currency.objects.get(
id=metric["account__currency__exchange_currency"]
)
exchanged = {}
for field in [
"expense_current",
"expense_projected",
"income_current",
"income_projected",
"total_income",
"total_expense",
"total_current",
"total_projected",
"total_final",
]:
amount, prefix, suffix, decimal_places = convert(
amount=currency_data[field],
from_currency=from_currency,
to_currency=exchange_currency,
)
if amount is not None:
exchanged[field] = amount
if "currency" not in exchanged:
exchanged["currency"] = {
"prefix": prefix,
"suffix": suffix,
"decimal_places": decimal_places,
"code": exchange_currency.code,
"name": exchange_currency.name,
}
if exchanged:
currency_data["exchanged"] = exchanged
result[category_id]["currencies"][currency_id] = currency_data
return result

View File

@@ -1,3 +1,6 @@
import decimal
import json
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.shortcuts import render from django.shortcuts import render
@@ -23,6 +26,7 @@ from apps.insights.utils.sankey import (
) )
from apps.insights.utils.transactions import get_transactions from apps.insights.utils.transactions import get_transactions
from apps.transactions.models import TransactionCategory, Transaction from apps.transactions.models import TransactionCategory, Transaction
from apps.insights.utils.category_overview import get_categories_totals
@login_required @login_required
@@ -159,6 +163,24 @@ def category_sum_by_currency(request):
) )
@only_htmx
@login_required
@require_http_methods(["GET"])
def category_overview(request):
# Get filtered transactions
transactions = get_transactions(request, include_silent=True)
total_table = get_categories_totals(
transactions_queryset=transactions, ignore_empty=False
)
return render(
request,
"insights/fragments/category_overview/index.html",
{"total_table": total_table},
)
@only_htmx @only_htmx
@login_required @login_required
@require_http_methods(["GET"]) @require_http_methods(["GET"])

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-24 16:30-0300\n" "POT-Creation-Date: 2025-02-27 23:32-0300\n"
"PO-Revision-Date: 2025-02-24 22:33+0100\n" "PO-Revision-Date: 2025-02-24 22:33+0100\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
@@ -76,6 +76,7 @@ msgstr "Neuer Saldo"
#: apps/transactions/forms.py:299 apps/transactions/forms.py:479 #: apps/transactions/forms.py:299 apps/transactions/forms.py:479
#: apps/transactions/forms.py:724 apps/transactions/models.py:203 #: apps/transactions/forms.py:724 apps/transactions/models.py:203
#: apps/transactions/models.py:378 apps/transactions/models.py:558 #: apps/transactions/models.py:378 apps/transactions/models.py:558
#: templates/insights/fragments/category_overview/index.html:9
msgid "Category" msgid "Category"
msgstr "Kategorie" msgstr "Kategorie"
@@ -880,6 +881,7 @@ msgstr "Vorgang erfolgreich gelöscht"
#: apps/insights/forms.py:119 apps/insights/utils/sankey.py:36 #: apps/insights/forms.py:119 apps/insights/utils/sankey.py:36
#: apps/insights/utils/sankey.py:167 #: apps/insights/utils/sankey.py:167
#: templates/insights/fragments/category_overview/index.html:18
msgid "Uncategorized" msgid "Uncategorized"
msgstr "Unkategorisiert" msgstr "Unkategorisiert"
@@ -1252,6 +1254,7 @@ msgstr "Entität"
#: templates/calendar_view/fragments/list.html:52 #: templates/calendar_view/fragments/list.html:52
#: templates/calendar_view/fragments/list.html:54 #: templates/calendar_view/fragments/list.html:54
#: templates/cotton/ui/quick_transactions_buttons.html:10 #: templates/cotton/ui/quick_transactions_buttons.html:10
#: templates/insights/fragments/category_overview/index.html:10
#: templates/monthly_overview/fragments/monthly_summary.html:39 #: templates/monthly_overview/fragments/monthly_summary.html:39
msgid "Income" msgid "Income"
msgstr "Einnahme" msgstr "Einnahme"
@@ -1262,6 +1265,7 @@ msgstr "Einnahme"
#: templates/calendar_view/fragments/list.html:56 #: templates/calendar_view/fragments/list.html:56
#: templates/calendar_view/fragments/list.html:58 #: templates/calendar_view/fragments/list.html:58
#: templates/cotton/ui/quick_transactions_buttons.html:18 #: templates/cotton/ui/quick_transactions_buttons.html:18
#: templates/insights/fragments/category_overview/index.html:11
msgid "Expense" msgid "Expense"
msgstr "Ausgabe" msgstr "Ausgabe"
@@ -1888,6 +1892,7 @@ msgid "Muted"
msgstr "Ausgeblendet" msgstr "Ausgeblendet"
#: templates/categories/fragments/table.html:57 #: templates/categories/fragments/table.html:57
#: templates/insights/fragments/category_overview/index.html:67
msgid "No categories" msgid "No categories"
msgstr "Keine Kategorien" msgstr "Keine Kategorien"
@@ -2451,6 +2456,11 @@ msgstr "Einnahmen/Ausgaben nach Konto"
msgid "Income/Expense by Currency" msgid "Income/Expense by Currency"
msgstr "Einnahmen/Ausgaben nach Währung" msgstr "Einnahmen/Ausgaben nach Währung"
#: templates/insights/fragments/category_overview/index.html:12
#: templates/monthly_overview/fragments/monthly_summary.html:167
msgid "Total"
msgstr "Gesamt"
#: templates/insights/fragments/late_transactions.html:15 #: templates/insights/fragments/late_transactions.html:15
msgid "All good!" msgid "All good!"
msgstr "Alles gut!" msgstr "Alles gut!"
@@ -2506,10 +2516,16 @@ msgid "Category Explorer"
msgstr "Kategorien-Explorer" msgstr "Kategorien-Explorer"
#: templates/insights/pages/index.html:102 #: templates/insights/pages/index.html:102
#, fuzzy
#| msgid "Categories"
msgid "Categories Overview"
msgstr "Kategorien"
#: templates/insights/pages/index.html:109
msgid "Late Transactions" msgid "Late Transactions"
msgstr "Verspätete Transaktionen" msgstr "Verspätete Transaktionen"
#: templates/insights/pages/index.html:108 #: templates/insights/pages/index.html:115
msgid "Latest Transactions" msgid "Latest Transactions"
msgstr "Letzte Transaktionen" msgstr "Letzte Transaktionen"
@@ -2607,10 +2623,6 @@ msgstr "erwartet"
msgid "Expenses" msgid "Expenses"
msgstr "Ausgaben" msgstr "Ausgaben"
#: templates/monthly_overview/fragments/monthly_summary.html:167
msgid "Total"
msgstr "Gesamt"
#: templates/monthly_overview/fragments/monthly_summary.html:257 #: templates/monthly_overview/fragments/monthly_summary.html:257
msgid "Distribution" msgid "Distribution"
msgstr "Verteilung" msgstr "Verteilung"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-24 23:04-0300\n" "POT-Creation-Date: 2025-02-27 23:32-0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -75,6 +75,7 @@ msgstr ""
#: apps/transactions/forms.py:299 apps/transactions/forms.py:479 #: apps/transactions/forms.py:299 apps/transactions/forms.py:479
#: apps/transactions/forms.py:724 apps/transactions/models.py:203 #: apps/transactions/forms.py:724 apps/transactions/models.py:203
#: apps/transactions/models.py:378 apps/transactions/models.py:558 #: apps/transactions/models.py:378 apps/transactions/models.py:558
#: templates/insights/fragments/category_overview/index.html:9
msgid "Category" msgid "Category"
msgstr "" msgstr ""
@@ -862,6 +863,7 @@ msgstr ""
#: apps/insights/forms.py:119 apps/insights/utils/sankey.py:36 #: apps/insights/forms.py:119 apps/insights/utils/sankey.py:36
#: apps/insights/utils/sankey.py:167 #: apps/insights/utils/sankey.py:167
#: templates/insights/fragments/category_overview/index.html:18
msgid "Uncategorized" msgid "Uncategorized"
msgstr "" msgstr ""
@@ -1221,6 +1223,7 @@ msgstr ""
#: templates/calendar_view/fragments/list.html:52 #: templates/calendar_view/fragments/list.html:52
#: templates/calendar_view/fragments/list.html:54 #: templates/calendar_view/fragments/list.html:54
#: templates/cotton/ui/quick_transactions_buttons.html:10 #: templates/cotton/ui/quick_transactions_buttons.html:10
#: templates/insights/fragments/category_overview/index.html:10
#: templates/monthly_overview/fragments/monthly_summary.html:39 #: templates/monthly_overview/fragments/monthly_summary.html:39
msgid "Income" msgid "Income"
msgstr "" msgstr ""
@@ -1231,6 +1234,7 @@ msgstr ""
#: templates/calendar_view/fragments/list.html:56 #: templates/calendar_view/fragments/list.html:56
#: templates/calendar_view/fragments/list.html:58 #: templates/calendar_view/fragments/list.html:58
#: templates/cotton/ui/quick_transactions_buttons.html:18 #: templates/cotton/ui/quick_transactions_buttons.html:18
#: templates/insights/fragments/category_overview/index.html:11
msgid "Expense" msgid "Expense"
msgstr "" msgstr ""
@@ -1856,6 +1860,7 @@ msgid "Muted"
msgstr "" msgstr ""
#: templates/categories/fragments/table.html:57 #: templates/categories/fragments/table.html:57
#: templates/insights/fragments/category_overview/index.html:67
msgid "No categories" msgid "No categories"
msgstr "" msgstr ""
@@ -2414,6 +2419,11 @@ msgstr ""
msgid "Income/Expense by Currency" msgid "Income/Expense by Currency"
msgstr "" msgstr ""
#: templates/insights/fragments/category_overview/index.html:12
#: templates/monthly_overview/fragments/monthly_summary.html:167
msgid "Total"
msgstr ""
#: templates/insights/fragments/late_transactions.html:15 #: templates/insights/fragments/late_transactions.html:15
msgid "All good!" msgid "All good!"
msgstr "" msgstr ""
@@ -2469,10 +2479,14 @@ msgid "Category Explorer"
msgstr "" msgstr ""
#: templates/insights/pages/index.html:102 #: templates/insights/pages/index.html:102
msgid "Categories Overview"
msgstr ""
#: templates/insights/pages/index.html:109
msgid "Late Transactions" msgid "Late Transactions"
msgstr "" msgstr ""
#: templates/insights/pages/index.html:108 #: templates/insights/pages/index.html:115
msgid "Latest Transactions" msgid "Latest Transactions"
msgstr "" msgstr ""
@@ -2567,10 +2581,6 @@ msgstr ""
msgid "Expenses" msgid "Expenses"
msgstr "" msgstr ""
#: templates/monthly_overview/fragments/monthly_summary.html:167
msgid "Total"
msgstr ""
#: templates/monthly_overview/fragments/monthly_summary.html:257 #: templates/monthly_overview/fragments/monthly_summary.html:257
msgid "Distribution" msgid "Distribution"
msgstr "" msgstr ""

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-24 16:30-0300\n" "POT-Creation-Date: 2025-02-27 23:32-0300\n"
"PO-Revision-Date: 2025-02-22 15:03+0100\n" "PO-Revision-Date: 2025-02-22 15:03+0100\n"
"Last-Translator: Dimitri Decrock <dimitri@fam-decrock.eu>\n" "Last-Translator: Dimitri Decrock <dimitri@fam-decrock.eu>\n"
"Language-Team: \n" "Language-Team: \n"
@@ -76,6 +76,7 @@ msgstr "Nieuw saldo"
#: apps/transactions/forms.py:299 apps/transactions/forms.py:479 #: apps/transactions/forms.py:299 apps/transactions/forms.py:479
#: apps/transactions/forms.py:724 apps/transactions/models.py:203 #: apps/transactions/forms.py:724 apps/transactions/models.py:203
#: apps/transactions/models.py:378 apps/transactions/models.py:558 #: apps/transactions/models.py:378 apps/transactions/models.py:558
#: templates/insights/fragments/category_overview/index.html:9
msgid "Category" msgid "Category"
msgstr "Categorie" msgstr "Categorie"
@@ -880,6 +881,7 @@ msgstr "Run met succes verwijderd"
#: apps/insights/forms.py:119 apps/insights/utils/sankey.py:36 #: apps/insights/forms.py:119 apps/insights/utils/sankey.py:36
#: apps/insights/utils/sankey.py:167 #: apps/insights/utils/sankey.py:167
#: templates/insights/fragments/category_overview/index.html:18
msgid "Uncategorized" msgid "Uncategorized"
msgstr "Ongecategoriseerd" msgstr "Ongecategoriseerd"
@@ -1247,6 +1249,7 @@ msgstr "Bedrijf"
#: templates/calendar_view/fragments/list.html:52 #: templates/calendar_view/fragments/list.html:52
#: templates/calendar_view/fragments/list.html:54 #: templates/calendar_view/fragments/list.html:54
#: templates/cotton/ui/quick_transactions_buttons.html:10 #: templates/cotton/ui/quick_transactions_buttons.html:10
#: templates/insights/fragments/category_overview/index.html:10
#: templates/monthly_overview/fragments/monthly_summary.html:39 #: templates/monthly_overview/fragments/monthly_summary.html:39
msgid "Income" msgid "Income"
msgstr "Ontvangsten Transactie" msgstr "Ontvangsten Transactie"
@@ -1257,6 +1260,7 @@ msgstr "Ontvangsten Transactie"
#: templates/calendar_view/fragments/list.html:56 #: templates/calendar_view/fragments/list.html:56
#: templates/calendar_view/fragments/list.html:58 #: templates/calendar_view/fragments/list.html:58
#: templates/cotton/ui/quick_transactions_buttons.html:18 #: templates/cotton/ui/quick_transactions_buttons.html:18
#: templates/insights/fragments/category_overview/index.html:11
msgid "Expense" msgid "Expense"
msgstr "Uitgave Transactie" msgstr "Uitgave Transactie"
@@ -1882,6 +1886,7 @@ msgid "Muted"
msgstr "Gedempt" msgstr "Gedempt"
#: templates/categories/fragments/table.html:57 #: templates/categories/fragments/table.html:57
#: templates/insights/fragments/category_overview/index.html:67
msgid "No categories" msgid "No categories"
msgstr "Geen categorieën" msgstr "Geen categorieën"
@@ -2443,6 +2448,11 @@ msgstr "Inkomsten/uitgaven per rekening"
msgid "Income/Expense by Currency" msgid "Income/Expense by Currency"
msgstr "Inkomsten/uitgaven per Munteenheid" msgstr "Inkomsten/uitgaven per Munteenheid"
#: templates/insights/fragments/category_overview/index.html:12
#: templates/monthly_overview/fragments/monthly_summary.html:167
msgid "Total"
msgstr "Totaal"
#: templates/insights/fragments/late_transactions.html:15 #: templates/insights/fragments/late_transactions.html:15
msgid "All good!" msgid "All good!"
msgstr "Allemaal goed!" msgstr "Allemaal goed!"
@@ -2498,10 +2508,16 @@ msgid "Category Explorer"
msgstr "Categorie Verkenner" msgstr "Categorie Verkenner"
#: templates/insights/pages/index.html:102 #: templates/insights/pages/index.html:102
#, fuzzy
#| msgid "Categories"
msgid "Categories Overview"
msgstr "Categorieën"
#: templates/insights/pages/index.html:109
msgid "Late Transactions" msgid "Late Transactions"
msgstr "Betalingsachterstanden" msgstr "Betalingsachterstanden"
#: templates/insights/pages/index.html:108 #: templates/insights/pages/index.html:115
msgid "Latest Transactions" msgid "Latest Transactions"
msgstr "Laatste Verrichtingen" msgstr "Laatste Verrichtingen"
@@ -2598,10 +2614,6 @@ msgstr "verwacht"
msgid "Expenses" msgid "Expenses"
msgstr "Uitgaven" msgstr "Uitgaven"
#: templates/monthly_overview/fragments/monthly_summary.html:167
msgid "Total"
msgstr "Totaal"
#: templates/monthly_overview/fragments/monthly_summary.html:257 #: templates/monthly_overview/fragments/monthly_summary.html:257
msgid "Distribution" msgid "Distribution"
msgstr "Verdeling" msgstr "Verdeling"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-24 16:30-0300\n" "POT-Creation-Date: 2025-02-27 23:32-0300\n"
"PO-Revision-Date: 2025-02-19 23:06-0300\n" "PO-Revision-Date: 2025-02-19 23:06-0300\n"
"Last-Translator: Herculino Trotta\n" "Last-Translator: Herculino Trotta\n"
"Language-Team: \n" "Language-Team: \n"
@@ -76,6 +76,7 @@ msgstr "Novo saldo"
#: apps/transactions/forms.py:299 apps/transactions/forms.py:479 #: apps/transactions/forms.py:299 apps/transactions/forms.py:479
#: apps/transactions/forms.py:724 apps/transactions/models.py:203 #: apps/transactions/forms.py:724 apps/transactions/models.py:203
#: apps/transactions/models.py:378 apps/transactions/models.py:558 #: apps/transactions/models.py:378 apps/transactions/models.py:558
#: templates/insights/fragments/category_overview/index.html:9
msgid "Category" msgid "Category"
msgstr "Categoria" msgstr "Categoria"
@@ -878,6 +879,7 @@ msgstr "Importação apagada com sucesso"
#: apps/insights/forms.py:119 apps/insights/utils/sankey.py:36 #: apps/insights/forms.py:119 apps/insights/utils/sankey.py:36
#: apps/insights/utils/sankey.py:167 #: apps/insights/utils/sankey.py:167
#: templates/insights/fragments/category_overview/index.html:18
msgid "Uncategorized" msgid "Uncategorized"
msgstr "Sem categoria" msgstr "Sem categoria"
@@ -1244,6 +1246,7 @@ msgstr "Entidade"
#: templates/calendar_view/fragments/list.html:52 #: templates/calendar_view/fragments/list.html:52
#: templates/calendar_view/fragments/list.html:54 #: templates/calendar_view/fragments/list.html:54
#: templates/cotton/ui/quick_transactions_buttons.html:10 #: templates/cotton/ui/quick_transactions_buttons.html:10
#: templates/insights/fragments/category_overview/index.html:10
#: templates/monthly_overview/fragments/monthly_summary.html:39 #: templates/monthly_overview/fragments/monthly_summary.html:39
msgid "Income" msgid "Income"
msgstr "Renda" msgstr "Renda"
@@ -1254,6 +1257,7 @@ msgstr "Renda"
#: templates/calendar_view/fragments/list.html:56 #: templates/calendar_view/fragments/list.html:56
#: templates/calendar_view/fragments/list.html:58 #: templates/calendar_view/fragments/list.html:58
#: templates/cotton/ui/quick_transactions_buttons.html:18 #: templates/cotton/ui/quick_transactions_buttons.html:18
#: templates/insights/fragments/category_overview/index.html:11
msgid "Expense" msgid "Expense"
msgstr "Despesa" msgstr "Despesa"
@@ -1879,6 +1883,7 @@ msgid "Muted"
msgstr "Silenciada" msgstr "Silenciada"
#: templates/categories/fragments/table.html:57 #: templates/categories/fragments/table.html:57
#: templates/insights/fragments/category_overview/index.html:67
msgid "No categories" msgid "No categories"
msgstr "Nenhum categoria" msgstr "Nenhum categoria"
@@ -2441,6 +2446,11 @@ msgstr "Gasto/Despesa por Conta"
msgid "Income/Expense by Currency" msgid "Income/Expense by Currency"
msgstr "Gasto/Despesa por Moeda" msgstr "Gasto/Despesa por Moeda"
#: templates/insights/fragments/category_overview/index.html:12
#: templates/monthly_overview/fragments/monthly_summary.html:167
msgid "Total"
msgstr "Total"
#: templates/insights/fragments/late_transactions.html:15 #: templates/insights/fragments/late_transactions.html:15
msgid "All good!" msgid "All good!"
msgstr "Tudo certo!" msgstr "Tudo certo!"
@@ -2496,10 +2506,16 @@ msgid "Category Explorer"
msgstr "Explorador de Categoria" msgstr "Explorador de Categoria"
#: templates/insights/pages/index.html:102 #: templates/insights/pages/index.html:102
#, fuzzy
#| msgid "Categories"
msgid "Categories Overview"
msgstr "Categorias"
#: templates/insights/pages/index.html:109
msgid "Late Transactions" msgid "Late Transactions"
msgstr "Transações Atrasadas" msgstr "Transações Atrasadas"
#: templates/insights/pages/index.html:108 #: templates/insights/pages/index.html:115
msgid "Latest Transactions" msgid "Latest Transactions"
msgstr "Últimas Transações" msgstr "Últimas Transações"
@@ -2596,10 +2612,6 @@ msgstr "previsto"
msgid "Expenses" msgid "Expenses"
msgstr "Despesas" msgstr "Despesas"
#: templates/monthly_overview/fragments/monthly_summary.html:167
msgid "Total"
msgstr "Total"
#: templates/monthly_overview/fragments/monthly_summary.html:257 #: templates/monthly_overview/fragments/monthly_summary.html:257
msgid "Distribution" msgid "Distribution"
msgstr "Distribuição" msgstr "Distribuição"

View File

@@ -0,0 +1,69 @@
{% load i18n %}
<div hx-get="{% url 'category_overview' %}" hx-trigger="updated from:window" class="show-loading" hx-swap="outerHTML" hx-include="#picker-form, #picker-type">
{% if total_table %}
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th scope="col">{% trans 'Category' %}</th>
<th scope="col">{% trans 'Income' %}</th>
<th scope="col">{% trans 'Expense' %}</th>
<th scope="col">{% trans 'Total' %}</th>
</tr>
</thead>
<tbody>
{% for category in total_table.values %}
<tr>
<th>{% if category.name %}{{ category.name }}{% else %}{% trans 'Uncategorized' %}{% endif %}</th>
<td>
{% for currency in category.currencies.values %}
{% if currency.total_income != 0 %}
<c-amount.display
:amount="currency.total_income"
:prefix="currency.currency.prefix"
:suffix="currency.currency.suffix"
:decimal_places="currency.currency.decimal_places"
color="green"></c-amount.display>
{% else %}
<div>-</div>
{% endif %}
{% endfor %}
</td>
<td>
{% for currency in category.currencies.values %}
{% if currency.total_expense != 0 %}
<c-amount.display
:amount="currency.total_expense"
:prefix="currency.currency.prefix"
:suffix="currency.currency.suffix"
:decimal_places="currency.currency.decimal_places"
color="red"></c-amount.display>
{% else %}
<div>-</div>
{% endif %}
{% endfor %}
</td>
<td>
{% for currency in category.currencies.values %}
{% if currency.total_final != 0 %}
<c-amount.display
:amount="currency.total_final"
:prefix="currency.currency.prefix"
:suffix="currency.currency.suffix"
:decimal_places="currency.currency.decimal_places"
color="{% if currency.total_final < 0 %}red{% else %}green{% endif %}"></c-amount.display>
{% else %}
<div>-</div>
{% endif %}
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<c-msg.empty title="{% translate "No categories" %}"></c-msg.empty>
{% endif %}
</div>

View File

@@ -94,6 +94,13 @@
hx-indicator="#tab-content" hx-indicator="#tab-content"
hx-target="#tab-content">{% trans 'Category Explorer' %} hx-target="#tab-content">{% trans 'Category Explorer' %}
</button> </button>
<button class="nav-link" id="v-pills-tab" data-bs-toggle="pill" data-bs-target="#v-pills-content"
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
hx-get="{% url 'category_overview' %}"
hx-include="#picker-form, #picker-type"
hx-indicator="#tab-content"
hx-target="#tab-content">{% trans 'Categories Overview' %}
</button>
<hr> <hr>
<button class="nav-link" id="v-pills-tab" data-bs-toggle="pill" data-bs-target="#v-pills-content" <button class="nav-link" id="v-pills-tab" data-bs-toggle="pill" data-bs-target="#v-pills-content"
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false" type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"