mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-04-24 09:38:35 +02:00
@@ -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,
|
||||||
|
|||||||
165
app/apps/insights/utils/category_overview.py
Normal file
165
app/apps/insights/utils/category_overview.py
Normal 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
|
||||||
@@ -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"])
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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 ""
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user