mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-02-26 01:14:50 +01:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
992c518dab | ||
|
|
29aa1c9d2b | ||
|
|
1b3b7a583d | ||
|
|
2d22f961ad | ||
|
|
71551d7651 | ||
|
|
62d58d1be3 | ||
|
|
21917437f2 | ||
|
|
59acb14d05 | ||
|
|
050f794f2b | ||
|
|
a5958c0937 | ||
|
|
ee73ada5ae | ||
|
|
736a116685 |
@@ -117,13 +117,15 @@ class CategoryForm(forms.Form):
|
||||
required=False,
|
||||
label=_("Category"),
|
||||
empty_label=_("Uncategorized"),
|
||||
queryset=TransactionCategory.objects.filter(active=True),
|
||||
queryset=TransactionCategory.objects.all(),
|
||||
widget=TomSelect(clear_button=True),
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.fields["category"].queryset = TransactionCategory.objects.all()
|
||||
|
||||
self.helper = FormHelper()
|
||||
self.helper.form_tag = False
|
||||
self.helper.disable_csrf = True
|
||||
|
||||
@@ -40,7 +40,7 @@ def get_currency_exchange_map(date=None) -> Dict[str, dict]:
|
||||
date_diff=Func(Extract(F("date") - Value(date), "epoch"), function="ABS"),
|
||||
effective_rate=F("rate"),
|
||||
)
|
||||
.order_by("from_currency", "to_currency", "date_diff")
|
||||
.order_by("from_currency", "to_currency", "-date_diff")
|
||||
.distinct()
|
||||
)
|
||||
|
||||
|
||||
@@ -2,25 +2,38 @@ from collections import OrderedDict, defaultdict
|
||||
from decimal import Decimal
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from django.db.models import Sum, Min, Max, Case, When, F, Value, DecimalField
|
||||
from django.db.models import Sum, Min, Max, Case, When, F, Value, DecimalField, Q
|
||||
from django.db.models.functions import TruncMonth
|
||||
from django.template.defaultfilters import date as date_filter
|
||||
from django.utils import timezone
|
||||
|
||||
from apps.accounts.models import Account
|
||||
from apps.common.middleware.thread_local import get_current_user
|
||||
from apps.currencies.models import Currency
|
||||
from apps.transactions.models import Transaction
|
||||
|
||||
|
||||
def calculate_historical_currency_net_worth(is_paid=True):
|
||||
transactions_params = {**{k: v for k, v in [("is_paid", True)] if is_paid}}
|
||||
|
||||
def calculate_historical_currency_net_worth(queryset):
|
||||
# Get all currencies and date range in a single query
|
||||
aggregates = Transaction.objects.aggregate(
|
||||
aggregates = queryset.aggregate(
|
||||
min_date=Min("reference_date"),
|
||||
max_date=Max("reference_date"),
|
||||
)
|
||||
currencies = list(Currency.objects.values_list("name", flat=True))
|
||||
|
||||
user = get_current_user()
|
||||
|
||||
currencies = list(
|
||||
Currency.objects.filter(
|
||||
Q(accounts__visibility="public")
|
||||
| Q(accounts__owner=user)
|
||||
| Q(accounts__shared_with=user)
|
||||
| Q(accounts__visibility="private", accounts__owner=None),
|
||||
accounts__is_archived=False,
|
||||
accounts__isnull=False,
|
||||
)
|
||||
.values_list("name", flat=True)
|
||||
.distinct()
|
||||
)
|
||||
|
||||
if not aggregates.get("min_date"):
|
||||
start_date = timezone.localdate(timezone.now())
|
||||
@@ -34,8 +47,7 @@ def calculate_historical_currency_net_worth(is_paid=True):
|
||||
|
||||
# Calculate cumulative balances for each account, currency, and month
|
||||
cumulative_balances = (
|
||||
Transaction.objects.filter(**transactions_params)
|
||||
.annotate(month=TruncMonth("reference_date"))
|
||||
queryset.annotate(month=TruncMonth("reference_date"))
|
||||
.values("account__currency__name", "month")
|
||||
.annotate(
|
||||
balance=Sum(
|
||||
@@ -94,15 +106,14 @@ def calculate_historical_currency_net_worth(is_paid=True):
|
||||
return historical_net_worth
|
||||
|
||||
|
||||
def calculate_historical_account_balance(is_paid=True):
|
||||
transactions_params = {**{k: v for k, v in [("is_paid", True)] if is_paid}}
|
||||
def calculate_historical_account_balance(queryset):
|
||||
# Get all accounts
|
||||
accounts = Account.objects.filter(
|
||||
is_archived=False,
|
||||
)
|
||||
|
||||
# Get the date range
|
||||
date_range = Transaction.objects.filter(**transactions_params).aggregate(
|
||||
date_range = queryset.aggregate(
|
||||
min_date=Min("reference_date"), max_date=Max("reference_date")
|
||||
)
|
||||
|
||||
@@ -118,8 +129,7 @@ def calculate_historical_account_balance(is_paid=True):
|
||||
|
||||
# Calculate balances for each account and month
|
||||
balances = (
|
||||
Transaction.objects.filter(**transactions_params)
|
||||
.annotate(month=TruncMonth("reference_date"))
|
||||
queryset.annotate(month=TruncMonth("reference_date"))
|
||||
.values("account", "month")
|
||||
.annotate(
|
||||
balance=Sum(
|
||||
|
||||
@@ -38,7 +38,9 @@ def net_worth_current(request):
|
||||
transactions_queryset=transactions_account_queryset
|
||||
)
|
||||
|
||||
historical_currency_net_worth = calculate_historical_currency_net_worth()
|
||||
historical_currency_net_worth = calculate_historical_currency_net_worth(
|
||||
queryset=transactions_currency_queryset
|
||||
)
|
||||
|
||||
labels = (
|
||||
list(historical_currency_net_worth.keys())
|
||||
@@ -71,7 +73,9 @@ def net_worth_current(request):
|
||||
|
||||
chart_data_currency_json = json.dumps(chart_data_currency, cls=DjangoJSONEncoder)
|
||||
|
||||
historical_account_balance = calculate_historical_account_balance()
|
||||
historical_account_balance = calculate_historical_account_balance(
|
||||
queryset=transactions_account_queryset
|
||||
)
|
||||
|
||||
labels = (
|
||||
list(historical_account_balance.keys()) if historical_account_balance else []
|
||||
@@ -140,7 +144,7 @@ def net_worth_projected(request):
|
||||
)
|
||||
|
||||
historical_currency_net_worth = calculate_historical_currency_net_worth(
|
||||
is_paid=False
|
||||
queryset=transactions_currency_queryset
|
||||
)
|
||||
|
||||
labels = (
|
||||
@@ -174,7 +178,9 @@ def net_worth_projected(request):
|
||||
|
||||
chart_data_currency_json = json.dumps(chart_data_currency, cls=DjangoJSONEncoder)
|
||||
|
||||
historical_account_balance = calculate_historical_account_balance(is_paid=False)
|
||||
historical_account_balance = calculate_historical_account_balance(
|
||||
queryset=transactions_account_queryset
|
||||
)
|
||||
|
||||
labels = (
|
||||
list(historical_account_balance.keys()) if historical_account_balance else []
|
||||
|
||||
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-03-09 21:56+0000\n"
|
||||
"PO-Revision-Date: 2025-03-02 02:08+0000\n"
|
||||
"Last-Translator: Herculino Trotta <netotrotta@gmail.com>\n"
|
||||
"PO-Revision-Date: 2025-03-10 09:05+0000\n"
|
||||
"Last-Translator: Schmitz Schmitz <stefanschmitz@t-online.de>\n"
|
||||
"Language-Team: German <https://translations.herculino.com/projects/wygiwyh/"
|
||||
"app/de/>\n"
|
||||
"Language: de\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.10.1\n"
|
||||
"X-Generator: Weblate 5.10.2\n"
|
||||
|
||||
#: apps/accounts/forms.py:24
|
||||
msgid "Group name"
|
||||
@@ -197,7 +197,7 @@ msgstr "Kontengruppe erfolgreich hinzugefügt"
|
||||
#: apps/transactions/views/entities.py:171 apps/transactions/views/tags.py:91
|
||||
#: apps/transactions/views/tags.py:171
|
||||
msgid "Only the owner can edit this"
|
||||
msgstr ""
|
||||
msgstr "Nur der Besitzer kann dies bearbeiten"
|
||||
|
||||
#: apps/accounts/views/account_groups.py:82
|
||||
msgid "Account Group updated successfully"
|
||||
@@ -208,7 +208,7 @@ msgstr "Kontengruppe erfolgreich aktualisiert"
|
||||
#: apps/rules/views.py:154 apps/transactions/views/categories.py:168
|
||||
#: apps/transactions/views/entities.py:130 apps/transactions/views/tags.py:130
|
||||
msgid "Item no longer shared with you"
|
||||
msgstr ""
|
||||
msgstr "Einheit wird nicht länger mit dir geteilt"
|
||||
|
||||
#: apps/accounts/views/account_groups.py:114
|
||||
msgid "Account Group deleted successfully"
|
||||
@@ -218,19 +218,15 @@ msgstr "Kontengruppe erfolgreich gelöscht"
|
||||
#: apps/accounts/views/accounts.py:169 apps/dca/views.py:129
|
||||
#: apps/rules/views.py:178 apps/transactions/views/categories.py:192
|
||||
#: apps/transactions/views/entities.py:154 apps/transactions/views/tags.py:154
|
||||
#, fuzzy
|
||||
#| msgid "Service added successfully"
|
||||
msgid "Ownership taken successfully"
|
||||
msgstr "Dienst erfolgreich hinzugefügt"
|
||||
msgstr "Besitzeigenschaft erfolgreich übernommen"
|
||||
|
||||
#: apps/accounts/views/account_groups.py:165
|
||||
#: apps/accounts/views/accounts.py:119 apps/dca/views.py:159
|
||||
#: apps/rules/views.py:208 apps/transactions/views/categories.py:142
|
||||
#: apps/transactions/views/entities.py:184 apps/transactions/views/tags.py:184
|
||||
#, fuzzy
|
||||
#| msgid "Transaction added successfully"
|
||||
msgid "Configuration saved successfully"
|
||||
msgstr "Transaktion erfolgreich hinzugefügt"
|
||||
msgstr "Konfiguration erfolgreich gespeichert"
|
||||
|
||||
#: apps/accounts/views/accounts.py:44
|
||||
msgid "Account added successfully"
|
||||
@@ -296,45 +292,47 @@ msgstr "Ungültiges Datumsformat. Nutze JJJJ-MM."
|
||||
|
||||
#: apps/common/forms.py:24
|
||||
msgid "Owner"
|
||||
msgstr ""
|
||||
msgstr "Besitzer"
|
||||
|
||||
#: apps/common/forms.py:27
|
||||
msgid ""
|
||||
"The owner of this object, if empty all users can see, edit and take "
|
||||
"ownership."
|
||||
msgstr ""
|
||||
"Der Besitzer dieses Objekts, falls leer können alle Nutzer es sehen, "
|
||||
"bearbeiten und die Besitzeigenschaft übernehmen."
|
||||
|
||||
#: apps/common/forms.py:34
|
||||
msgid "Shared with users"
|
||||
msgstr ""
|
||||
msgstr "Mit Nutzern geteilt"
|
||||
|
||||
#: apps/common/forms.py:35
|
||||
msgid "Select users to share this object with"
|
||||
msgstr ""
|
||||
msgstr "Nutzer auswählen, mit dem das Objekt geteilt werden soll"
|
||||
|
||||
#: apps/common/forms.py:40
|
||||
msgid "Visibility"
|
||||
msgstr ""
|
||||
msgstr "Sichtbarkeit"
|
||||
|
||||
#: apps/common/forms.py:42
|
||||
msgid ""
|
||||
"Private: Only shown for the owner and shared users. Only editable by the "
|
||||
"owner.<br/>Public: Shown for all users. Only editable by the owner."
|
||||
msgstr ""
|
||||
"Privat: Nur für den Besitzer und geteilte Nutzer sichtbar.<br/>Öffentlich: "
|
||||
"Sichtbar für alle Nutzer. Nur bearbeitbar durch Besitzer."
|
||||
|
||||
#: apps/common/forms.py:79 apps/users/forms.py:131
|
||||
msgid "Save"
|
||||
msgstr "Speichern"
|
||||
|
||||
#: apps/common/models.py:29
|
||||
#, fuzzy
|
||||
#| msgid "Activate"
|
||||
msgid "Private"
|
||||
msgstr "Aktivieren"
|
||||
msgstr "Privat"
|
||||
|
||||
#: apps/common/models.py:30
|
||||
msgid "Public"
|
||||
msgstr ""
|
||||
msgstr "Öffentlich"
|
||||
|
||||
#: apps/common/templatetags/natural.py:20
|
||||
#: templates/monthly_overview/fragments/monthly_summary.html:9
|
||||
@@ -773,7 +771,7 @@ msgstr "Eintrag erfolgreich gelöscht"
|
||||
|
||||
#: apps/export_app/forms.py:14 apps/export_app/forms.py:131
|
||||
msgid "Users"
|
||||
msgstr ""
|
||||
msgstr "Nutzer"
|
||||
|
||||
#: apps/export_app/forms.py:32 apps/export_app/forms.py:137
|
||||
#: apps/transactions/models.py:362 templates/includes/navbar.html:57
|
||||
@@ -1018,10 +1016,8 @@ msgid "Run on update"
|
||||
msgstr "Starten bei Aktualisierung"
|
||||
|
||||
#: apps/rules/forms.py:23
|
||||
#, fuzzy
|
||||
#| msgid "Run on update"
|
||||
msgid "Run on delete"
|
||||
msgstr "Starten bei Aktualisierung"
|
||||
msgstr "Starten bei Löschen"
|
||||
|
||||
#: apps/rules/forms.py:24
|
||||
msgid "If..."
|
||||
@@ -1437,16 +1433,12 @@ msgid "Installment Amount"
|
||||
msgstr "Ratenzahlungs-Wert"
|
||||
|
||||
#: apps/transactions/models.py:500 apps/transactions/models.py:719
|
||||
#, fuzzy
|
||||
#| msgid "Add action to transaction rule"
|
||||
msgid "Add description to transactions"
|
||||
msgstr "Aktion zu Transaktions-Regeln hinzufügen"
|
||||
msgstr "Beschreibung zu Transaktionen hinzufügen"
|
||||
|
||||
#: apps/transactions/models.py:503 apps/transactions/models.py:722
|
||||
#, fuzzy
|
||||
#| msgid "Add action to transaction rule"
|
||||
msgid "Add notes to transactions"
|
||||
msgstr "Aktion zu Transaktions-Regeln hinzufügen"
|
||||
msgstr "Notizen zu Transaktionen hinzufügen"
|
||||
|
||||
#: apps/transactions/models.py:661
|
||||
msgid "day(s)"
|
||||
@@ -1907,7 +1899,7 @@ msgstr "Ja, löschen!"
|
||||
#: templates/rules/fragments/list.html:56
|
||||
#: templates/tags/fragments/table.html:48
|
||||
msgid "Take ownership"
|
||||
msgstr ""
|
||||
msgstr "Besitzeigenschaft übernehmen"
|
||||
|
||||
#: templates/account_groups/fragments/list.html:65
|
||||
#: templates/accounts/fragments/list.html:70
|
||||
@@ -1917,7 +1909,7 @@ msgstr ""
|
||||
#: templates/rules/fragments/list.html:66
|
||||
#: templates/tags/fragments/table.html:58
|
||||
msgid "Share"
|
||||
msgstr ""
|
||||
msgstr "Teilen"
|
||||
|
||||
#: templates/account_groups/fragments/list.html:77
|
||||
msgid "No account groups"
|
||||
@@ -1929,10 +1921,8 @@ msgstr "Keine Kontrogruppen"
|
||||
#: templates/dca/fragments/strategy/share.html:5
|
||||
#: templates/entities/fragments/share.html:5
|
||||
#: templates/rules/fragments/share.html:5 templates/tags/fragments/share.html:5
|
||||
#, fuzzy
|
||||
#| msgid "Settings"
|
||||
msgid "Share settings"
|
||||
msgstr "Einstellungen"
|
||||
msgstr "Einstellungen teilen"
|
||||
|
||||
#: templates/accounts/fragments/account_reconciliation.html:6
|
||||
msgid "Account Reconciliation"
|
||||
@@ -2591,7 +2581,7 @@ msgstr "Gesamt"
|
||||
|
||||
#: templates/insights/fragments/emergency_fund.html:15
|
||||
msgid "You've spent an average of"
|
||||
msgstr ""
|
||||
msgstr "Deine Ausgaben liegen im Durchschnitt bei"
|
||||
|
||||
#: templates/insights/fragments/emergency_fund.html:23
|
||||
msgid "on the last 12 months, at this rate you could go by"
|
||||
@@ -2599,13 +2589,11 @@ msgstr ""
|
||||
|
||||
#: templates/insights/fragments/emergency_fund.html:25
|
||||
msgid "months without any income."
|
||||
msgstr ""
|
||||
msgstr "Monate ohne Einnahmen."
|
||||
|
||||
#: templates/insights/fragments/emergency_fund.html:34
|
||||
#, fuzzy
|
||||
#| msgid "current expenses"
|
||||
msgid "average expenses"
|
||||
msgstr "aktuelle Ausgaben"
|
||||
msgstr "durchschnittliche Ausgaben"
|
||||
|
||||
#: templates/insights/fragments/emergency_fund.html:48
|
||||
#, fuzzy
|
||||
@@ -2614,10 +2602,8 @@ msgid "liquid total"
|
||||
msgstr "Gesamtbilanz"
|
||||
|
||||
#: templates/insights/fragments/emergency_fund.html:62
|
||||
#, fuzzy
|
||||
#| msgid "month(s)"
|
||||
msgid "months left"
|
||||
msgstr "Monat(e)"
|
||||
msgstr "verbleibende Monate"
|
||||
|
||||
#: templates/insights/fragments/late_transactions.html:15
|
||||
msgid "All good!"
|
||||
@@ -2687,7 +2673,7 @@ msgstr "Letzte Transaktionen"
|
||||
|
||||
#: templates/insights/pages/index.html:121
|
||||
msgid "Emergency Fund"
|
||||
msgstr ""
|
||||
msgstr "Notfall-Budget"
|
||||
|
||||
#: templates/installment_plans/fragments/add.html:5
|
||||
msgid "Add installment plan"
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-03-09 21:56+0000\n"
|
||||
"PO-Revision-Date: 2025-03-09 12:05+0000\n"
|
||||
"PO-Revision-Date: 2025-03-13 07:05+0000\n"
|
||||
"Last-Translator: Dimitri Decrock <dj.flashpower@gmail.com>\n"
|
||||
"Language-Team: Dutch <https://translations.herculino.com/projects/wygiwyh/"
|
||||
"app/nl/>\n"
|
||||
@@ -1428,16 +1428,12 @@ msgid "Installment Amount"
|
||||
msgstr "Termijnbedrag"
|
||||
|
||||
#: apps/transactions/models.py:500 apps/transactions/models.py:719
|
||||
#, fuzzy
|
||||
#| msgid "Add action to transaction rule"
|
||||
msgid "Add description to transactions"
|
||||
msgstr "Actie toevoegen aan verrichtingsregel"
|
||||
msgstr "Beschrijving toevoegen aan verrichting"
|
||||
|
||||
#: apps/transactions/models.py:503 apps/transactions/models.py:722
|
||||
#, fuzzy
|
||||
#| msgid "Add action to transaction rule"
|
||||
msgid "Add notes to transactions"
|
||||
msgstr "Actie toevoegen aan verrichtingsregel"
|
||||
msgstr "Notities toevoegen aan verrichting"
|
||||
|
||||
#: apps/transactions/models.py:661
|
||||
msgid "day(s)"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{% block title %}{% translate 'Transactions on' %} {{ date|date:"SHORT_DATE_FORMAT" }}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div hx-get="{% url 'calendar_transactions_list' day=date.day month=date.month year=date.year %}" hx-trigger="updated from:window" hx-vals='{"disable_selection": true}' hx-target="closest .offcanvas" class="show-loading" id="transactions-list">
|
||||
<div hx-get="{% url 'calendar_transactions_list' day=date.day month=date.month year=date.year %}" hx-trigger="updated from:window" hx-target="closest .offcanvas" class="show-loading" id="transactions-list">
|
||||
{% for transaction in transactions %}
|
||||
<c-transaction.item :transaction="transaction"></c-transaction.item>
|
||||
{% empty %}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{% block title %}{% translate 'Installments' %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div hx-get="{% url 'installment_plan_transactions' installment_plan_id=installment_plan.id %}" hx-trigger="updated from:window" hx-vals='{"disable_selection": true}' hx-target="closest .offcanvas" class="show-loading" id="transactions-list">
|
||||
<div hx-get="{% url 'installment_plan_transactions' installment_plan_id=installment_plan.id %}" hx-trigger="updated from:window" hx-target="closest .offcanvas" class="show-loading" id="transactions-list">
|
||||
{% for transaction in transactions %}
|
||||
<c-transaction.item :transaction="transaction"></c-transaction.item>
|
||||
{% endfor %}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{% block title %}{% translate 'Transactions' %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div hx-get="{% url 'recurring_transaction_transactions' recurring_transaction_id=recurring_transaction.id %}" hx-trigger="updated from:window" hx-vals='{"disable_selection": true}' hx-target="closest .offcanvas" class="show-loading" id="transactions-list">
|
||||
<div hx-get="{% url 'recurring_transaction_transactions' recurring_transaction_id=recurring_transaction.id %}" hx-trigger="updated from:window" hx-target="closest .offcanvas" class="show-loading" id="transactions-list">
|
||||
{% for transaction in transactions %}
|
||||
<c-transaction.item :transaction="transaction"></c-transaction.item>
|
||||
{% endfor %}
|
||||
|
||||
@@ -14,7 +14,7 @@ djangorestframework~=3.15.2
|
||||
drf-spectacular~=0.27.2
|
||||
django-import-export~=4.3.5
|
||||
|
||||
gunicorn==22.0.0
|
||||
gunicorn==23.0.0
|
||||
whitenoise[brotli]==6.6.0
|
||||
|
||||
watchfiles==0.24.0 # https://github.com/samuelcolvin/watchfiles
|
||||
|
||||
Reference in New Issue
Block a user