From 7fe446e510974ca306fb097e6518d08a38ce8089 Mon Sep 17 00:00:00 2001 From: Herculino Trotta Date: Mon, 27 Jan 2025 13:18:57 -0300 Subject: [PATCH 1/8] refactor: remove custom_date filter --- app/apps/common/templatetags/date.py | 32 ---------------------------- 1 file changed, 32 deletions(-) delete mode 100644 app/apps/common/templatetags/date.py diff --git a/app/apps/common/templatetags/date.py b/app/apps/common/templatetags/date.py deleted file mode 100644 index f57d685..0000000 --- a/app/apps/common/templatetags/date.py +++ /dev/null @@ -1,32 +0,0 @@ -from django import template -from django.template.defaultfilters import date as date_filter -from django.utils import formats, timezone - -register = template.Library() - - -@register.filter -def custom_date(value, user=None): - if not value: - return "" - - # Determine if the value is a datetime or just a date - is_datetime = hasattr(value, "hour") - - # Convert to current timezone if it's a datetime - if is_datetime and timezone.is_aware(value): - value = timezone.localtime(value) - - if user and user.is_authenticated: - user_settings = user.settings - - if is_datetime: - format_setting = user_settings.datetime_format - else: - format_setting = user_settings.date_format - - return formats.date_format(value, format_setting, use_l10n=True) - - return date_filter( - value, "SHORT_DATE_FORMAT" if not is_datetime else "SHORT_DATETIME_FORMAT" - ) From a08548bb136f22031d536cbabd4552731e0a0cfc Mon Sep 17 00:00:00 2001 From: Herculino Trotta Date: Mon, 27 Jan 2025 13:19:28 -0300 Subject: [PATCH 2/8] feat: add local access to user and request from anywhere --- app/WYGIWYH/settings.py | 1 + app/apps/common/middleware/thread_local.py | 73 ++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 app/apps/common/middleware/thread_local.py diff --git a/app/WYGIWYH/settings.py b/app/WYGIWYH/settings.py index 71caa47..636956b 100644 --- a/app/WYGIWYH/settings.py +++ b/app/WYGIWYH/settings.py @@ -77,6 +77,7 @@ INSTALLED_APPS = [ ] MIDDLEWARE = [ + "apps.common.middleware.thread_local.ThreadLocalMiddleware", "debug_toolbar.middleware.DebugToolbarMiddleware", "django.middleware.security.SecurityMiddleware", "whitenoise.middleware.WhiteNoiseMiddleware", diff --git a/app/apps/common/middleware/thread_local.py b/app/apps/common/middleware/thread_local.py new file mode 100644 index 0000000..9eaf55f --- /dev/null +++ b/app/apps/common/middleware/thread_local.py @@ -0,0 +1,73 @@ +""" + threadlocals middleware + ~~~~~~~~~~~~~~~~~~~~~~~ + + make the request object everywhere available (e.g. in model instance). + + based on: http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser + + Put this into your settings: + -------------------------------------------------------------------------- + MIDDLEWARE_CLASSES = ( + ... + 'django_tools.middlewares.ThreadLocal.ThreadLocalMiddleware', + ... + ) + -------------------------------------------------------------------------- + + + Usage: + -------------------------------------------------------------------------- + from django_tools.middlewares import ThreadLocal + + # Get the current request object: + request = ThreadLocal.get_current_request() + + # You can get the current user directly with: + user = ThreadLocal.get_current_user() + -------------------------------------------------------------------------- + + :copyleft: 2009-2017 by the django-tools team, see AUTHORS for more details. + :license: GNU GPL v3 or above, see LICENSE for more details. +""" + +try: + from threading import local +except ImportError: + from django.utils._threading_local import local + +try: + from django.utils.deprecation import MiddlewareMixin +except ImportError: + MiddlewareMixin = object # fallback for Django < 1.10 + + +_thread_locals = local() + + +def get_current_request(): + """returns the request object for this thread""" + return getattr(_thread_locals, "request", None) + + +def get_current_user(): + """returns the current user, if exist, otherwise returns None""" + request = get_current_request() + if request: + return getattr(request, "user", None) + + +class ThreadLocalMiddleware(MiddlewareMixin): + """Simple middleware that adds the request object in thread local storage.""" + + def process_request(self, request): + _thread_locals.request = request + + def process_response(self, request, response): + if hasattr(_thread_locals, "request"): + del _thread_locals.request + return response + + def process_exception(self, request, exception): + if hasattr(_thread_locals, "request"): + del _thread_locals.request From 958940089ad0b05254be6470223c7cab95b22269 Mon Sep 17 00:00:00 2001 From: Herculino Trotta Date: Mon, 27 Jan 2025 13:20:12 -0300 Subject: [PATCH 3/8] feat: add number_format user setting --- .../0017_usersettings_number_format.py | 18 ++++++++++++++++++ app/apps/users/models.py | 8 +++++++- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 app/apps/users/migrations/0017_usersettings_number_format.py diff --git a/app/apps/users/migrations/0017_usersettings_number_format.py b/app/apps/users/migrations/0017_usersettings_number_format.py new file mode 100644 index 0000000..04d77ac --- /dev/null +++ b/app/apps/users/migrations/0017_usersettings_number_format.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.5 on 2025-01-27 12:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0016_alter_usersettings_language'), + ] + + operations = [ + migrations.AddField( + model_name='usersettings', + name='number_format', + field=models.CharField(default='AA', max_length=2, verbose_name='Number Format'), + ), + ] diff --git a/app/apps/users/models.py b/app/apps/users/models.py index 77761cd..ede8201 100644 --- a/app/apps/users/models.py +++ b/app/apps/users/models.py @@ -1,8 +1,8 @@ import pytz from django.conf import settings from django.contrib.auth import get_user_model -from django.db import models from django.contrib.auth.models import AbstractUser, Group +from django.db import models from django.utils.translation import gettext_lazy as _ from apps.users.managers import UserManager @@ -44,6 +44,9 @@ class UserSettings(models.Model): default="SHORT_DATETIME_FORMAT", verbose_name=_("Datetime Format"), ) + number_format = models.CharField( + max_length=2, default="AA", verbose_name=_("Number Format") + ) language = models.CharField( max_length=10, @@ -66,3 +69,6 @@ class UserSettings(models.Model): def __str__(self): return f"{self.user.email}'s settings" + + def clean(self): + super().clean() From 3796112d77a2421e3142c3483ecf047eb56b7e7b Mon Sep 17 00:00:00 2001 From: Herculino Trotta Date: Mon, 27 Jan 2025 13:22:21 -0300 Subject: [PATCH 4/8] feat: monkey patch get_format to return usersettings --- app/apps/common/functions/format.py | 31 ++++++++++++++++++++++ app/apps/common/middleware/localization.py | 14 +++++++--- app/apps/common/templatetags/formats.py | 2 +- app/apps/common/widgets/datepicker.py | 14 +--------- app/apps/common/widgets/decimal.py | 4 ++- 5 files changed, 47 insertions(+), 18 deletions(-) create mode 100644 app/apps/common/functions/format.py diff --git a/app/apps/common/functions/format.py b/app/apps/common/functions/format.py new file mode 100644 index 0000000..b0cfb65 --- /dev/null +++ b/app/apps/common/functions/format.py @@ -0,0 +1,31 @@ +from apps.common.middleware.thread_local import get_current_user +from django.utils.formats import get_format as original_get_format + + +def get_format(format_type=None, lang=None, use_l10n=None): + user = get_current_user() + + if user and user.is_authenticated and hasattr(user, "settings"): + user_settings = user.settings + if format_type == "THOUSAND_SEPARATOR": + number_format = getattr(user_settings, "number_format", None) + if number_format == "DC": + return "." + elif number_format == "CD": + return "," + elif format_type == "DECIMAL_SEPARATOR": + number_format = getattr(user_settings, "number_format", None) + if number_format == "DC": + return "," + elif number_format == "CD": + return "." + elif format_type == "SHORT_DATE_FORMAT": + date_format = getattr(user_settings, "date_format", None) + if date_format and date_format != "SHORT_DATE_FORMAT": + return date_format + elif format_type == "SHORT_DATETIME_FORMAT": + datetime_format = getattr(user_settings, "datetime_format", None) + if datetime_format and datetime_format != "SHORT_DATETIME_FORMAT": + return datetime_format + + return original_get_format(format_type, lang, use_l10n) diff --git a/app/apps/common/middleware/localization.py b/app/apps/common/middleware/localization.py index 79596e4..a78f627 100644 --- a/app/apps/common/middleware/localization.py +++ b/app/apps/common/middleware/localization.py @@ -1,14 +1,17 @@ import zoneinfo +from django.utils import formats from django.utils import timezone, translation -from django.utils.translation import activate +from django.utils.functional import lazy +from apps.common.functions.format import get_format as custom_get_format from apps.users.models import UserSettings class LocalizationMiddleware: def __init__(self, get_response): self.get_response = get_response + self.patch_get_format() def __call__(self, request): tz = request.COOKIES.get("mytz") @@ -33,9 +36,14 @@ class LocalizationMiddleware: timezone.activate(zoneinfo.ZoneInfo("UTC")) if user_language and user_language != "auto": - activate(user_language) + translation.activate(user_language) else: detected_language = translation.get_language_from_request(request) - activate(detected_language) + translation.activate(detected_language) return self.get_response(request) + + @staticmethod + def patch_get_format(): + formats.get_format = custom_get_format + formats.get_format_lazy = lazy(custom_get_format, str, list, tuple) diff --git a/app/apps/common/templatetags/formats.py b/app/apps/common/templatetags/formats.py index 34d8e60..705d429 100644 --- a/app/apps/common/templatetags/formats.py +++ b/app/apps/common/templatetags/formats.py @@ -1,6 +1,6 @@ from django import template -from django.utils.formats import get_format +from apps.common.functions.format import get_format register = template.Library() diff --git a/app/apps/common/widgets/datepicker.py b/app/apps/common/widgets/datepicker.py index 1ddd871..a110620 100644 --- a/app/apps/common/widgets/datepicker.py +++ b/app/apps/common/widgets/datepicker.py @@ -2,7 +2,6 @@ import datetime from django.forms import widgets from django.utils import formats, translation, dates -from django.utils.formats import get_format from django.utils.translation import gettext_lazy as _ from apps.common.utils.django import ( @@ -10,6 +9,7 @@ from apps.common.utils.django import ( django_to_airdatepicker_datetime, django_to_airdatepicker_datetime_separated, ) +from apps.common.functions.format import get_format class AirDatePickerInput(widgets.DateInput): @@ -41,12 +41,6 @@ class AirDatePickerInput(widgets.DateInput): if self.format: return self.format - if self.user and hasattr(self.user, "settings"): - user_format = self.user.settings.date_format - if user_format == "SHORT_DATE_FORMAT": - return get_format("SHORT_DATE_FORMAT", use_l10n=True) - return user_format - return get_format("SHORT_DATE_FORMAT", use_l10n=True) def build_attrs(self, base_attrs, extra_attrs=None): @@ -120,12 +114,6 @@ class AirDateTimePickerInput(widgets.DateTimeInput): if self.format: return self.format - if self.user and hasattr(self.user, "settings"): - user_format = self.user.settings.datetime_format - if user_format == "SHORT_DATETIME_FORMAT": - return get_format("SHORT_DATETIME_FORMAT", use_l10n=True) - return user_format - return get_format("SHORT_DATETIME_FORMAT", use_l10n=True) def build_attrs(self, base_attrs, extra_attrs=None): diff --git a/app/apps/common/widgets/decimal.py b/app/apps/common/widgets/decimal.py index 3ec1cd3..8b1bce6 100644 --- a/app/apps/common/widgets/decimal.py +++ b/app/apps/common/widgets/decimal.py @@ -1,7 +1,9 @@ from decimal import Decimal, InvalidOperation from django import forms -from django.utils.formats import get_format, number_format +from django.utils.formats import number_format + +from apps.common.functions.format import get_format def convert_to_decimal(value: str): From 187c56c96cbd165e927ec402018e0312f5a95858 Mon Sep 17 00:00:00 2001 From: Herculino Trotta Date: Mon, 27 Jan 2025 13:25:06 -0300 Subject: [PATCH 5/8] refactor: remove user attr from datepicker since monkey patched get_format already does what we want --- app/apps/common/widgets/datepicker.py | 4 --- app/apps/currencies/forms.py | 6 ++--- app/apps/currencies/views/exchange_rates.py | 8 +++--- app/apps/dca/forms.py | 4 +-- app/apps/dca/views.py | 8 +++--- app/apps/monthly_overview/views.py | 4 +-- app/apps/transactions/filters.py | 6 ++--- app/apps/transactions/forms.py | 22 +++++++--------- .../transactions/views/installment_plans.py | 10 +++---- .../views/recurring_transactions.py | 12 +++------ app/apps/transactions/views/transactions.py | 26 +++++++------------ 11 files changed, 44 insertions(+), 66 deletions(-) diff --git a/app/apps/common/widgets/datepicker.py b/app/apps/common/widgets/datepicker.py index a110620..a9ee922 100644 --- a/app/apps/common/widgets/datepicker.py +++ b/app/apps/common/widgets/datepicker.py @@ -19,12 +19,10 @@ class AirDatePickerInput(widgets.DateInput): format=None, clear_button=True, auto_close=True, - user=None, *args, **kwargs, ): attrs = attrs or {} - self.user = user super().__init__(attrs=attrs, format=format, *args, **kwargs) self.clear_button = clear_button self.auto_close = auto_close @@ -91,12 +89,10 @@ class AirDateTimePickerInput(widgets.DateTimeInput): timepicker=True, clear_button=True, auto_close=True, - user=None, *args, **kwargs, ): attrs = attrs or {} - self.user = user super().__init__(attrs=attrs, format=format, *args, **kwargs) self.timepicker = timepicker self.clear_button = clear_button diff --git a/app/apps/currencies/forms.py b/app/apps/currencies/forms.py index fb5e745..22fa04f 100644 --- a/app/apps/currencies/forms.py +++ b/app/apps/currencies/forms.py @@ -72,7 +72,7 @@ class ExchangeRateForm(forms.ModelForm): model = ExchangeRate fields = ["from_currency", "to_currency", "rate", "date"] - def __init__(self, *args, user=None, **kwargs): + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.helper = FormHelper() @@ -81,9 +81,7 @@ class ExchangeRateForm(forms.ModelForm): self.helper.layout = Layout("date", "from_currency", "to_currency", "rate") self.fields["rate"].widget = ArbitraryDecimalDisplayNumberInput() - self.fields["date"].widget = AirDateTimePickerInput( - clear_button=False, user=user - ) + self.fields["date"].widget = AirDateTimePickerInput(clear_button=False) if self.instance and self.instance.pk: self.helper.layout.append( diff --git a/app/apps/currencies/views/exchange_rates.py b/app/apps/currencies/views/exchange_rates.py index f7e9ed4..dc43de5 100644 --- a/app/apps/currencies/views/exchange_rates.py +++ b/app/apps/currencies/views/exchange_rates.py @@ -83,7 +83,7 @@ def exchange_rates_list_pair(request): @require_http_methods(["GET", "POST"]) def exchange_rate_add(request): if request.method == "POST": - form = ExchangeRateForm(request.POST, user=request.user) + form = ExchangeRateForm(request.POST) if form.is_valid(): form.save() messages.success(request, _("Exchange rate added successfully")) @@ -95,7 +95,7 @@ def exchange_rate_add(request): }, ) else: - form = ExchangeRateForm(user=request.user) + form = ExchangeRateForm() return render( request, @@ -111,7 +111,7 @@ def exchange_rate_edit(request, pk): exchange_rate = get_object_or_404(ExchangeRate, id=pk) if request.method == "POST": - form = ExchangeRateForm(request.POST, instance=exchange_rate, user=request.user) + form = ExchangeRateForm(request.POST, instance=exchange_rate) if form.is_valid(): form.save() messages.success(request, _("Exchange rate updated successfully")) @@ -123,7 +123,7 @@ def exchange_rate_edit(request, pk): }, ) else: - form = ExchangeRateForm(instance=exchange_rate, user=request.user) + form = ExchangeRateForm(instance=exchange_rate) return render( request, diff --git a/app/apps/dca/forms.py b/app/apps/dca/forms.py index 2158704..a4e052e 100644 --- a/app/apps/dca/forms.py +++ b/app/apps/dca/forms.py @@ -65,7 +65,7 @@ class DCAEntryForm(forms.ModelForm): "notes": forms.Textarea(attrs={"rows": 3}), } - def __init__(self, *args, user=None, **kwargs): + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.helper = FormHelper() self.helper.form_tag = False @@ -106,4 +106,4 @@ class DCAEntryForm(forms.ModelForm): self.fields["amount_paid"].widget = ArbitraryDecimalDisplayNumberInput() self.fields["amount_received"].widget = ArbitraryDecimalDisplayNumberInput() - self.fields["date"].widget = AirDatePickerInput(clear_button=False, user=user) + self.fields["date"].widget = AirDatePickerInput(clear_button=False) diff --git a/app/apps/dca/views.py b/app/apps/dca/views.py index 547b9ef..22f718d 100644 --- a/app/apps/dca/views.py +++ b/app/apps/dca/views.py @@ -155,7 +155,7 @@ def strategy_detail(request, strategy_id): def strategy_entry_add(request, strategy_id): strategy = get_object_or_404(DCAStrategy, id=strategy_id) if request.method == "POST": - form = DCAEntryForm(request.POST, user=request.user) + form = DCAEntryForm(request.POST) if form.is_valid(): entry = form.save(commit=False) entry.strategy = strategy @@ -169,7 +169,7 @@ def strategy_entry_add(request, strategy_id): }, ) else: - form = DCAEntryForm(user=request.user) + form = DCAEntryForm() return render( request, @@ -184,7 +184,7 @@ def strategy_entry_edit(request, strategy_id, entry_id): dca_entry = get_object_or_404(DCAEntry, id=entry_id, strategy__id=strategy_id) if request.method == "POST": - form = DCAEntryForm(request.POST, instance=dca_entry, user=request.user) + form = DCAEntryForm(request.POST, instance=dca_entry) if form.is_valid(): form.save() messages.success(request, _("Entry updated successfully")) @@ -196,7 +196,7 @@ def strategy_entry_edit(request, strategy_id, entry_id): }, ) else: - form = DCAEntryForm(instance=dca_entry, user=request.user) + form = DCAEntryForm(instance=dca_entry) return render( request, diff --git a/app/apps/monthly_overview/views.py b/app/apps/monthly_overview/views.py index 814bce5..0289a4d 100644 --- a/app/apps/monthly_overview/views.py +++ b/app/apps/monthly_overview/views.py @@ -41,7 +41,7 @@ def monthly_overview(request, month: int, year: int): previous_month = 12 if month == 1 else month - 1 previous_year = year - 1 if previous_month == 12 and month == 1 else year - f = TransactionsFilter(request.GET, user=request.user) + f = TransactionsFilter(request.GET) return render( request, @@ -64,7 +64,7 @@ def monthly_overview(request, month: int, year: int): def transactions_list(request, month: int, year: int): order = request.GET.get("order") - f = TransactionsFilter(request.GET, user=request.user) + f = TransactionsFilter(request.GET) transactions_filtered = ( f.qs.filter() .filter( diff --git a/app/apps/transactions/filters.py b/app/apps/transactions/filters.py index 81d9ef5..ccbb58f 100644 --- a/app/apps/transactions/filters.py +++ b/app/apps/transactions/filters.py @@ -133,7 +133,7 @@ class TransactionsFilter(django_filters.FilterSet): "to_amount", ] - def __init__(self, data=None, user=None, *args, **kwargs): + def __init__(self, data=None, *args, **kwargs): # if filterset is bound, use initial values as defaults if data is not None: # get a mutable copy of the QueryDict @@ -182,5 +182,5 @@ class TransactionsFilter(django_filters.FilterSet): self.form.fields["to_amount"].widget = ArbitraryDecimalDisplayNumberInput() self.form.fields["from_amount"].widget = ArbitraryDecimalDisplayNumberInput() - self.form.fields["date_start"].widget = AirDatePickerInput(user=user) - self.form.fields["date_end"].widget = AirDatePickerInput(user=user) + self.form.fields["date_start"].widget = AirDatePickerInput() + self.form.fields["date_end"].widget = AirDatePickerInput() diff --git a/app/apps/transactions/forms.py b/app/apps/transactions/forms.py index 27842a9..2878755 100644 --- a/app/apps/transactions/forms.py +++ b/app/apps/transactions/forms.py @@ -86,7 +86,7 @@ class TransactionForm(forms.ModelForm): "account": TomSelect(clear_button=False, group_by="group"), } - def __init__(self, *args, user=None, **kwargs): + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # if editing a transaction display non-archived items and it's own item even if it's archived @@ -177,7 +177,7 @@ class TransactionForm(forms.ModelForm): ) self.fields["reference_date"].required = False - self.fields["date"].widget = AirDatePickerInput(clear_button=False, user=user) + self.fields["date"].widget = AirDatePickerInput(clear_button=False) if self.instance and self.instance.pk: decimal_places = self.instance.account.currency.decimal_places @@ -333,7 +333,7 @@ class TransferForm(forms.Form): label=_("Notes"), ) - def __init__(self, *args, user=None, **kwargs): + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.helper = FormHelper() @@ -402,7 +402,7 @@ class TransferForm(forms.Form): self.fields["from_amount"].widget = ArbitraryDecimalDisplayNumberInput() self.fields["to_amount"].widget = ArbitraryDecimalDisplayNumberInput() - self.fields["date"].widget = AirDatePickerInput(clear_button=False, user=user) + self.fields["date"].widget = AirDatePickerInput(clear_button=False) def clean(self): cleaned_data = super().clean() @@ -515,7 +515,7 @@ class InstallmentPlanForm(forms.ModelForm): "notes": forms.Textarea(attrs={"rows": 3}), } - def __init__(self, *args, user=None, **kwargs): + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # if editing display non-archived items and it's own item even if it's archived @@ -572,9 +572,7 @@ class InstallmentPlanForm(forms.ModelForm): ) self.fields["installment_amount"].widget = ArbitraryDecimalDisplayNumberInput() - self.fields["start_date"].widget = AirDatePickerInput( - clear_button=False, user=user - ) + self.fields["start_date"].widget = AirDatePickerInput(clear_button=False) if self.instance and self.instance.pk: self.helper.layout.append( @@ -762,7 +760,7 @@ class RecurringTransactionForm(forms.ModelForm): ), } - def __init__(self, *args, user=None, **kwargs): + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # if editing display non-archived items and it's own item even if it's archived @@ -819,10 +817,8 @@ class RecurringTransactionForm(forms.ModelForm): ) self.fields["amount"].widget = ArbitraryDecimalDisplayNumberInput() - self.fields["start_date"].widget = AirDatePickerInput( - clear_button=False, user=user - ) - self.fields["end_date"].widget = AirDatePickerInput(user=user) + self.fields["start_date"].widget = AirDatePickerInput(clear_button=False) + self.fields["end_date"].widget = AirDatePickerInput() if self.instance and self.instance.pk: self.helper.layout.append( diff --git a/app/apps/transactions/views/installment_plans.py b/app/apps/transactions/views/installment_plans.py index c437a05..f292759 100644 --- a/app/apps/transactions/views/installment_plans.py +++ b/app/apps/transactions/views/installment_plans.py @@ -81,7 +81,7 @@ def installment_plan_transactions(request, installment_plan_id): @require_http_methods(["GET", "POST"]) def installment_plan_add(request): if request.method == "POST": - form = InstallmentPlanForm(request.POST, user=request.user) + form = InstallmentPlanForm(request.POST) if form.is_valid(): form.save() messages.success(request, _("Installment Plan added successfully")) @@ -93,7 +93,7 @@ def installment_plan_add(request): }, ) else: - form = InstallmentPlanForm(user=request.user) + form = InstallmentPlanForm() return render( request, @@ -109,9 +109,7 @@ def installment_plan_edit(request, installment_plan_id): installment_plan = get_object_or_404(InstallmentPlan, id=installment_plan_id) if request.method == "POST": - form = InstallmentPlanForm( - request.POST, instance=installment_plan, user=request.user - ) + form = InstallmentPlanForm(request.POST, instance=installment_plan) if form.is_valid(): form.save() messages.success(request, _("Installment Plan updated successfully")) @@ -123,7 +121,7 @@ def installment_plan_edit(request, installment_plan_id): }, ) else: - form = InstallmentPlanForm(instance=installment_plan, user=request.user) + form = InstallmentPlanForm(instance=installment_plan) return render( request, diff --git a/app/apps/transactions/views/recurring_transactions.py b/app/apps/transactions/views/recurring_transactions.py index 7b59fe3..f3a4338 100644 --- a/app/apps/transactions/views/recurring_transactions.py +++ b/app/apps/transactions/views/recurring_transactions.py @@ -106,7 +106,7 @@ def recurring_transaction_transactions(request, recurring_transaction_id): @require_http_methods(["GET", "POST"]) def recurring_transaction_add(request): if request.method == "POST": - form = RecurringTransactionForm(request.POST, user=request.user) + form = RecurringTransactionForm(request.POST) if form.is_valid(): form.save() messages.success(request, _("Recurring Transaction added successfully")) @@ -118,7 +118,7 @@ def recurring_transaction_add(request): }, ) else: - form = RecurringTransactionForm(user=request.user) + form = RecurringTransactionForm() return render( request, @@ -136,9 +136,7 @@ def recurring_transaction_edit(request, recurring_transaction_id): ) if request.method == "POST": - form = RecurringTransactionForm( - request.POST, instance=recurring_transaction, user=request.user - ) + form = RecurringTransactionForm(request.POST, instance=recurring_transaction) if form.is_valid(): form.save() messages.success(request, _("Recurring Transaction updated successfully")) @@ -150,9 +148,7 @@ def recurring_transaction_edit(request, recurring_transaction_id): }, ) else: - form = RecurringTransactionForm( - instance=recurring_transaction, user=request.user - ) + form = RecurringTransactionForm(instance=recurring_transaction) return render( request, diff --git a/app/apps/transactions/views/transactions.py b/app/apps/transactions/views/transactions.py index f1d1cb7..33156de 100644 --- a/app/apps/transactions/views/transactions.py +++ b/app/apps/transactions/views/transactions.py @@ -44,7 +44,7 @@ def transaction_add(request): ).date() if request.method == "POST": - form = TransactionForm(request.POST, user=request.user) + form = TransactionForm(request.POST) if form.is_valid(): form.save() messages.success(request, _("Transaction added successfully")) @@ -55,7 +55,6 @@ def transaction_add(request): ) else: form = TransactionForm( - user=request.user, initial={ "date": expected_date, "type": transaction_type, @@ -84,13 +83,12 @@ def transaction_simple_add(request): ).date() if request.method == "POST": - form = TransactionForm(request.POST, user=request.user) + form = TransactionForm(request.POST) if form.is_valid(): form.save() messages.success(request, _("Transaction added successfully")) form = TransactionForm( - user=request.user, initial={ "date": expected_date, "type": transaction_type, @@ -99,7 +97,6 @@ def transaction_simple_add(request): else: form = TransactionForm( - user=request.user, initial={ "date": expected_date, "type": transaction_type, @@ -120,7 +117,7 @@ def transaction_edit(request, transaction_id, **kwargs): transaction = get_object_or_404(Transaction, id=transaction_id) if request.method == "POST": - form = TransactionForm(request.POST, user=request.user, instance=transaction) + form = TransactionForm(request.POST, instance=transaction) if form.is_valid(): form.save() messages.success(request, _("Transaction updated successfully")) @@ -130,7 +127,7 @@ def transaction_edit(request, transaction_id, **kwargs): headers={"HX-Trigger": "updated, hide_offcanvas"}, ) else: - form = TransactionForm(instance=transaction, user=request.user) + form = TransactionForm(instance=transaction) return render( request, @@ -152,7 +149,7 @@ def transactions_bulk_edit(request): count = transactions.count() if request.method == "POST": - form = BulkEditTransactionForm(request.POST, user=request.user) + form = BulkEditTransactionForm(request.POST) if form.is_valid(): # Apply changes from the form to all selected transactions for transaction in transactions: @@ -184,9 +181,7 @@ def transactions_bulk_edit(request): headers={"HX-Trigger": "updated, hide_offcanvas"}, ) else: - form = BulkEditTransactionForm( - initial={"is_paid": None, "type": None}, user=request.user - ) + form = BulkEditTransactionForm(initial={"is_paid": None, "type": None}) context = { "form": form, @@ -276,7 +271,7 @@ def transactions_transfer(request): ).date() if request.method == "POST": - form = TransferForm(request.POST, user=request.user) + form = TransferForm(request.POST) if form.is_valid(): form.save() messages.success(request, _("Transfer added successfully")) @@ -290,7 +285,6 @@ def transactions_transfer(request): "reference_date": expected_date, "date": expected_date, }, - user=request.user, ) return render(request, "transactions/fragments/transfer.html", {"form": form}) @@ -319,7 +313,7 @@ def transaction_pay(request, transaction_id): @login_required @require_http_methods(["GET"]) def transaction_all_index(request): - f = TransactionsFilter(request.GET, user=request.user) + f = TransactionsFilter(request.GET) return render(request, "transactions/pages/transactions.html", {"filter": f}) @@ -341,7 +335,7 @@ def transaction_all_list(request): transactions = default_order(transactions, order=order) - f = TransactionsFilter(request.GET, user=request.user, queryset=transactions) + f = TransactionsFilter(request.GET, queryset=transactions) page_number = request.GET.get("page", 1) paginator = Paginator(f.qs, 100) @@ -371,7 +365,7 @@ def transaction_all_summary(request): "installment_plan", ).all() - f = TransactionsFilter(request.GET, user=request.user, queryset=transactions) + f = TransactionsFilter(request.GET, queryset=transactions) currency_data = calculate_currency_totals(f.qs.all(), ignore_empty=True) currency_percentages = calculate_percentage_distribution(currency_data) From 80bad240e72a73207c0723c149e787cfc29d8874 Mon Sep 17 00:00:00 2001 From: Herculino Trotta Date: Mon, 27 Jan 2025 13:25:47 -0300 Subject: [PATCH 6/8] refactor: remove custom_date filter --- .../calendar_view/fragments/list_transactions.html | 3 +-- app/templates/cotton/transaction/item.html | 3 +-- app/templates/dca/fragments/strategy/details.html | 7 +++---- app/templates/exchange_rates/fragments/table.html | 3 +-- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/app/templates/calendar_view/fragments/list_transactions.html b/app/templates/calendar_view/fragments/list_transactions.html index 669e3d6..ba1bd65 100644 --- a/app/templates/calendar_view/fragments/list_transactions.html +++ b/app/templates/calendar_view/fragments/list_transactions.html @@ -1,9 +1,8 @@ {% extends 'extends/offcanvas.html' %} -{% load date %} {% load i18n %} {% load crispy_forms_tags %} -{% block title %}{% translate 'Transactions on' %} {{ date|custom_date:request.user }}{% endblock %} +{% block title %}{% translate 'Transactions on' %} {{ date|date:"SHORT_DATE_FORMAT" }}{% endblock %} {% block body %}
diff --git a/app/templates/cotton/transaction/item.html b/app/templates/cotton/transaction/item.html index db12eb5..02ba143 100644 --- a/app/templates/cotton/transaction/item.html +++ b/app/templates/cotton/transaction/item.html @@ -1,4 +1,3 @@ -{% load date %} {% load i18n %}
{% if not disable_selection %} @@ -27,7 +26,7 @@ {# Date#}
-
{{ transaction.date|custom_date:request.user }} • {{ transaction.reference_date|date:"b/Y" }}
+
{{ transaction.date|date:"SHORT_DATE_FORMAT" }} • {{ transaction.reference_date|date:"b/Y" }}
{# Description#}
diff --git a/app/templates/dca/fragments/strategy/details.html b/app/templates/dca/fragments/strategy/details.html index 3e2a6dd..0db0e7c 100644 --- a/app/templates/dca/fragments/strategy/details.html +++ b/app/templates/dca/fragments/strategy/details.html @@ -1,4 +1,3 @@ -{% load date %} {% load currency_display %} {% load i18n %}
@@ -17,7 +16,7 @@ :prefix="strategy.payment_currency.prefix" :suffix="strategy.payment_currency.suffix" :decimal_places="strategy.payment_currency.decimal_places"> - • {{ strategy.current_price.1|custom_date:request.user }} + • {{ strategy.current_price.1|date:"SHORT_DATETIME_FORMAT" }} {% else %}
{% trans "No exchange rate available" %}
@@ -84,7 +83,7 @@ _="install prompt_swal">
- {{ entry.date|custom_date:request.user }} + {{ entry.date|date:"SHORT_DATE_FORMAT" }} @@ -40,7 +39,7 @@ _="install prompt_swal">
- {{ exchange_rate.date|custom_date:request.user }} + {{ exchange_rate.date|date:"SHORT_DATETIME_FORMAT" }} {{ exchange_rate.from_currency.code }} x {{ exchange_rate.to_currency.code }} 1 {{ exchange_rate.from_currency.code }} ≅ {% currency_display amount=exchange_rate.rate prefix=exchange_rate.to_currency.prefix suffix=exchange_rate.to_currency.suffix decimal_places=exchange_rate.to_currency.decimal_places%} From 81b8da30d622c2585fcf455c069d877cf37802a3 Mon Sep 17 00:00:00 2001 From: Herculino Trotta Date: Mon, 27 Jan 2025 13:26:08 -0300 Subject: [PATCH 7/8] feat: add number_format to user_settings form --- app/apps/users/forms.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/apps/users/forms.py b/app/apps/users/forms.py index a9fca3a..2132033 100644 --- a/app/apps/users/forms.py +++ b/app/apps/users/forms.py @@ -81,6 +81,12 @@ class UserSettingsForm(forms.ModelForm): ("Y.m.d h:i A", "2025.01.20 03:30 PM"), ] + NUMBER_FORMAT_CHOICES = [ + ("AA", _("Default")), + ("DC", "1.234,50"), + ("CD", "1,234.50"), + ] + date_format = forms.ChoiceField( choices=DATE_FORMAT_CHOICES, initial="SHORT_DATE_FORMAT", label=_("Date Format") ) @@ -90,6 +96,12 @@ class UserSettingsForm(forms.ModelForm): label=_("Datetime Format"), ) + number_format = forms.ChoiceField( + choices=NUMBER_FORMAT_CHOICES, + initial="AA", + label=_("Number Format"), + ) + class Meta: model = UserSettings fields = [ @@ -98,6 +110,7 @@ class UserSettingsForm(forms.ModelForm): "start_page", "date_format", "datetime_format", + "number_format", ] def __init__(self, *args, **kwargs): @@ -111,6 +124,7 @@ class UserSettingsForm(forms.ModelForm): "timezone", "date_format", "datetime_format", + "number_format", "start_page", FormActions( NoClassSubmit( From 331a7d5b1847953b14056f12c40560da038b6925 Mon Sep 17 00:00:00 2001 From: Herculino Trotta Date: Mon, 27 Jan 2025 13:30:06 -0300 Subject: [PATCH 8/8] locale: update translations --- app/locale/nl/LC_MESSAGES/django.po | 246 +++++++++++++------------ app/locale/pt_BR/LC_MESSAGES/django.po | 246 +++++++++++++------------ 2 files changed, 250 insertions(+), 242 deletions(-) diff --git a/app/locale/nl/LC_MESSAGES/django.po b/app/locale/nl/LC_MESSAGES/django.po index 6371327..4a6c264 100644 --- a/app/locale/nl/LC_MESSAGES/django.po +++ b/app/locale/nl/LC_MESSAGES/django.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-25 18:49+0000\n" -"PO-Revision-Date: 2025-01-26 12:50+0100\n" -"Last-Translator: Dimitri Decrock \n" +"POT-Creation-Date: 2025-01-27 16:26+0000\n" +"PO-Revision-Date: 2025-01-27 13:27-0300\n" +"Last-Translator: Herculino Trotta\n" "Language-Team: \n" "Language: nl\n" "MIME-Version: 1.0\n" @@ -24,28 +24,28 @@ msgid "Group name" msgstr "Groepsnaam" #: apps/accounts/forms.py:40 apps/accounts/forms.py:96 -#: apps/currencies/forms.py:52 apps/currencies/forms.py:92 apps/dca/forms.py:41 +#: apps/currencies/forms.py:52 apps/currencies/forms.py:90 apps/dca/forms.py:41 #: apps/dca/forms.py:93 apps/import_app/forms.py:34 apps/rules/forms.py:45 #: apps/rules/forms.py:87 apps/transactions/forms.py:190 -#: apps/transactions/forms.py:257 apps/transactions/forms.py:583 -#: apps/transactions/forms.py:626 apps/transactions/forms.py:658 -#: apps/transactions/forms.py:693 apps/transactions/forms.py:831 +#: apps/transactions/forms.py:257 apps/transactions/forms.py:581 +#: apps/transactions/forms.py:624 apps/transactions/forms.py:656 +#: apps/transactions/forms.py:691 apps/transactions/forms.py:827 msgid "Update" msgstr "Bijwerken" #: apps/accounts/forms.py:48 apps/accounts/forms.py:104 #: apps/common/widgets/tom_select.py:12 apps/currencies/forms.py:60 -#: apps/currencies/forms.py:100 apps/dca/forms.py:49 apps/dca/forms.py:102 +#: apps/currencies/forms.py:98 apps/dca/forms.py:49 apps/dca/forms.py:102 #: apps/import_app/forms.py:42 apps/rules/forms.py:53 apps/rules/forms.py:95 #: apps/transactions/forms.py:174 apps/transactions/forms.py:199 -#: apps/transactions/forms.py:591 apps/transactions/forms.py:634 -#: apps/transactions/forms.py:666 apps/transactions/forms.py:701 -#: apps/transactions/forms.py:839 +#: apps/transactions/forms.py:589 apps/transactions/forms.py:632 +#: apps/transactions/forms.py:664 apps/transactions/forms.py:699 +#: apps/transactions/forms.py:835 #: templates/account_groups/fragments/list.html:9 #: templates/accounts/fragments/list.html:9 #: templates/categories/fragments/list.html:9 #: templates/currencies/fragments/list.html:9 -#: templates/dca/fragments/strategy/details.html:38 +#: templates/dca/fragments/strategy/details.html:37 #: templates/dca/fragments/strategy/list.html:9 #: templates/entities/fragments/list.html:9 #: templates/exchange_rates/fragments/list.html:10 @@ -69,7 +69,7 @@ msgstr "Nieuw saldo" #: apps/accounts/forms.py:119 apps/rules/models.py:27 #: apps/transactions/forms.py:39 apps/transactions/forms.py:291 #: apps/transactions/forms.py:298 apps/transactions/forms.py:478 -#: apps/transactions/forms.py:725 apps/transactions/models.py:159 +#: apps/transactions/forms.py:723 apps/transactions/models.py:159 #: apps/transactions/models.py:311 apps/transactions/models.py:491 msgid "Category" msgstr "Categorie" @@ -77,7 +77,7 @@ msgstr "Categorie" #: apps/accounts/forms.py:126 apps/rules/models.py:28 #: apps/transactions/filters.py:74 apps/transactions/forms.py:47 #: apps/transactions/forms.py:307 apps/transactions/forms.py:315 -#: apps/transactions/forms.py:471 apps/transactions/forms.py:718 +#: apps/transactions/forms.py:471 apps/transactions/forms.py:716 #: apps/transactions/models.py:165 apps/transactions/models.py:313 #: apps/transactions/models.py:495 templates/includes/navbar.html:98 #: templates/tags/fragments/list.html:5 templates/tags/pages/index.html:4 @@ -151,7 +151,7 @@ msgstr "" #: apps/accounts/models.py:59 apps/rules/models.py:19 #: apps/transactions/forms.py:59 apps/transactions/forms.py:463 -#: apps/transactions/forms.py:710 apps/transactions/models.py:132 +#: apps/transactions/forms.py:708 apps/transactions/models.py:132 #: apps/transactions/models.py:271 apps/transactions/models.py:473 msgid "Account" msgstr "Rekening" @@ -322,11 +322,11 @@ msgstr "Fout" msgid "Info" msgstr "Info" -#: apps/common/widgets/datepicker.py:55 apps/common/widgets/datepicker.py:197 +#: apps/common/widgets/datepicker.py:47 apps/common/widgets/datepicker.py:186 msgid "Today" msgstr "Vandaag" -#: apps/common/widgets/datepicker.py:139 +#: apps/common/widgets/datepicker.py:123 msgid "Now" msgstr "Nu" @@ -356,8 +356,8 @@ msgstr "Achtervoegsel" #: apps/currencies/forms.py:68 apps/dca/models.py:156 apps/rules/models.py:22 #: apps/transactions/forms.py:63 apps/transactions/forms.py:319 #: apps/transactions/models.py:142 -#: templates/dca/fragments/strategy/details.html:53 -#: templates/exchange_rates/fragments/table.html:11 +#: templates/dca/fragments/strategy/details.html:52 +#: templates/exchange_rates/fragments/table.html:10 msgid "Date" msgstr "Datum" @@ -407,7 +407,7 @@ msgstr "Datum en Tijd" msgid "Exchange Rates" msgstr "Wisselkoersen" -#: apps/currencies/models.py:77 +#: apps/currencies/models.py:79 msgid "From and To currencies cannot be the same." msgstr "Van en Naar munteenheid kunnen niet dezelfde zijn." @@ -461,11 +461,11 @@ msgstr "DCA Strategieën" msgid "Strategy" msgstr "Strategie" -#: apps/dca/models.py:158 templates/dca/fragments/strategy/details.html:55 +#: apps/dca/models.py:158 templates/dca/fragments/strategy/details.html:54 msgid "Amount Paid" msgstr "Betaald bedrag" -#: apps/dca/models.py:161 templates/dca/fragments/strategy/details.html:54 +#: apps/dca/models.py:161 templates/dca/fragments/strategy/details.html:53 msgid "Amount Received" msgstr "Ontvangen bedrag" @@ -643,7 +643,7 @@ msgstr "Bedrag" #: apps/rules/models.py:29 apps/transactions/filters.py:81 #: apps/transactions/forms.py:55 apps/transactions/forms.py:486 -#: apps/transactions/forms.py:733 apps/transactions/models.py:117 +#: apps/transactions/forms.py:731 apps/transactions/models.py:117 #: apps/transactions/models.py:170 apps/transactions/models.py:316 #: apps/transactions/models.py:498 templates/entities/fragments/list.html:5 #: templates/entities/pages/index.html:4 templates/includes/navbar.html:100 @@ -761,23 +761,23 @@ msgstr "Overschrijving" msgid "From and To accounts must be different." msgstr "Van en Naar rekening moeten verschillend zijn." -#: apps/transactions/forms.py:612 +#: apps/transactions/forms.py:610 msgid "Tag name" msgstr "Labelnaam" -#: apps/transactions/forms.py:644 +#: apps/transactions/forms.py:642 msgid "Entity name" msgstr "Naam van bedrijf" -#: apps/transactions/forms.py:676 +#: apps/transactions/forms.py:674 msgid "Category name" msgstr "Naam van categorie" -#: apps/transactions/forms.py:678 +#: apps/transactions/forms.py:676 msgid "Muted categories won't count towards your monthly total" msgstr "Gedempte categorieën tellen niet mee voor je maandtotaal" -#: apps/transactions/forms.py:850 +#: apps/transactions/forms.py:846 msgid "End date should be after the start date" msgstr "De einddatum moet na de begindatum vallen" @@ -1046,15 +1046,15 @@ msgstr "Bedrijf succesvol verwijderd" msgid "Installment Plan added successfully" msgstr "Afbetalingsplan succesvol toegevoegd" -#: apps/transactions/views/installment_plans.py:117 +#: apps/transactions/views/installment_plans.py:115 msgid "Installment Plan updated successfully" msgstr "Afbetalingsplan succesvol bijgewerkt" -#: apps/transactions/views/installment_plans.py:142 +#: apps/transactions/views/installment_plans.py:140 msgid "Installment Plan refreshed successfully" msgstr "Afbetalingsplan succesvol vernieuwd" -#: apps/transactions/views/installment_plans.py:160 +#: apps/transactions/views/installment_plans.py:158 msgid "Installment Plan deleted successfully" msgstr "Afbetalingsplan succesvol verwijderd" @@ -1062,23 +1062,23 @@ msgstr "Afbetalingsplan succesvol verwijderd" msgid "Recurring Transaction added successfully" msgstr "Terugkerende Verrichting succesvol toegevoegd" -#: apps/transactions/views/recurring_transactions.py:144 +#: apps/transactions/views/recurring_transactions.py:142 msgid "Recurring Transaction updated successfully" msgstr "Terugkerende Verrichting succesvol bijgewerkt" -#: apps/transactions/views/recurring_transactions.py:190 +#: apps/transactions/views/recurring_transactions.py:186 msgid "Recurring transaction unpaused successfully" msgstr "Terugkerende Verrichting succesvol hervat" -#: apps/transactions/views/recurring_transactions.py:193 +#: apps/transactions/views/recurring_transactions.py:189 msgid "Recurring transaction paused successfully" msgstr "Terugkerende Verrichting succesvol onderbroken" -#: apps/transactions/views/recurring_transactions.py:219 +#: apps/transactions/views/recurring_transactions.py:215 msgid "Recurring transaction finished successfully" msgstr "Terugkerende Verrichting succesvol voltooid" -#: apps/transactions/views/recurring_transactions.py:239 +#: apps/transactions/views/recurring_transactions.py:235 msgid "Recurring Transaction deleted successfully" msgstr "Terugkerende Verrichting succesvol verwijderd" @@ -1095,30 +1095,30 @@ msgid "Tag deleted successfully" msgstr "Label succesvol verwijderd" #: apps/transactions/views/transactions.py:50 -#: apps/transactions/views/transactions.py:90 +#: apps/transactions/views/transactions.py:89 msgid "Transaction added successfully" msgstr "Verrichting succesvol toegevoegd" -#: apps/transactions/views/transactions.py:126 +#: apps/transactions/views/transactions.py:123 msgid "Transaction updated successfully" msgstr "Verrichting succesvol bijgewerkt" -#: apps/transactions/views/transactions.py:176 +#: apps/transactions/views/transactions.py:173 #, python-format msgid "%(count)s transaction updated successfully" msgid_plural "%(count)s transactions updated successfully" msgstr[0] "%(count)s verrichting succesvol bijgewerkt" msgstr[1] "%(count)s verrichtingen succesvol bijgewerkt" -#: apps/transactions/views/transactions.py:214 +#: apps/transactions/views/transactions.py:209 msgid "Transaction duplicated successfully" msgstr "Verrichting succesvol gedupliceerd" -#: apps/transactions/views/transactions.py:256 +#: apps/transactions/views/transactions.py:251 msgid "Transaction deleted successfully" msgstr "Verrichting succesvol verwijderd" -#: apps/transactions/views/transactions.py:282 +#: apps/transactions/views/transactions.py:277 msgid "Transfer added successfully" msgstr "Transactie succesvol toegevoegd" @@ -1158,21 +1158,25 @@ msgstr "Ongeldig e-mailadres of wachtwoord" msgid "This account is deactivated" msgstr "Deze gebruiker is gedeactiveerd" -#: apps/users/forms.py:50 apps/users/forms.py:63 +#: apps/users/forms.py:50 apps/users/forms.py:63 apps/users/forms.py:85 #: templates/monthly_overview/pages/overview.html:116 #: templates/transactions/pages/transactions.html:35 msgid "Default" msgstr "Standaard" -#: apps/users/forms.py:85 apps/users/models.py:40 +#: apps/users/forms.py:91 apps/users/models.py:40 msgid "Date Format" msgstr "Datumnotatie" -#: apps/users/forms.py:90 apps/users/models.py:45 +#: apps/users/forms.py:96 apps/users/models.py:45 msgid "Datetime Format" msgstr "Tijdsnotatie" -#: apps/users/forms.py:117 +#: apps/users/forms.py:102 apps/users/models.py:48 +msgid "Number Format" +msgstr "Nummerformat" + +#: apps/users/forms.py:131 msgid "Save" msgstr "Opslaan" @@ -1196,19 +1200,19 @@ msgstr "Alle Verrichtingen" msgid "Calendar" msgstr "Kalender" -#: apps/users/models.py:50 apps/users/models.py:56 +#: apps/users/models.py:53 apps/users/models.py:59 msgid "Auto" msgstr "Automatisch" -#: apps/users/models.py:52 +#: apps/users/models.py:55 msgid "Language" msgstr "Taal" -#: apps/users/models.py:58 +#: apps/users/models.py:61 msgid "Time Zone" msgstr "Tijdszone" -#: apps/users/models.py:64 +#: apps/users/models.py:67 msgid "Start page" msgstr "Startpagina" @@ -1244,9 +1248,9 @@ msgstr "Rekeningsgroep bewerken" #: templates/accounts/fragments/list.html:37 #: templates/categories/fragments/table.html:24 #: templates/currencies/fragments/list.html:33 -#: templates/dca/fragments/strategy/details.html:64 +#: templates/dca/fragments/strategy/details.html:63 #: templates/entities/fragments/table.html:23 -#: templates/exchange_rates/fragments/table.html:20 +#: templates/exchange_rates/fragments/table.html:19 #: templates/import_app/fragments/profiles/list.html:44 #: templates/installment_plans/fragments/table.html:23 #: templates/recurring_transactions/fragments/table.html:25 @@ -1258,13 +1262,13 @@ msgstr "Acties" #: templates/account_groups/fragments/list.html:36 #: templates/accounts/fragments/list.html:41 #: templates/categories/fragments/table.html:29 -#: templates/cotton/transaction/item.html:110 -#: templates/cotton/ui/transactions_action_bar.html:43 +#: templates/cotton/transaction/item.html:109 +#: templates/cotton/ui/transactions_action_bar.html:47 #: templates/currencies/fragments/list.html:37 -#: templates/dca/fragments/strategy/details.html:68 +#: templates/dca/fragments/strategy/details.html:67 #: templates/dca/fragments/strategy/list.html:34 #: templates/entities/fragments/table.html:28 -#: templates/exchange_rates/fragments/table.html:24 +#: templates/exchange_rates/fragments/table.html:23 #: templates/import_app/fragments/profiles/list.html:48 #: templates/installment_plans/fragments/table.html:27 #: templates/recurring_transactions/fragments/table.html:29 @@ -1277,13 +1281,13 @@ msgstr "Bijwerken" #: templates/account_groups/fragments/list.html:43 #: templates/accounts/fragments/list.html:48 #: templates/categories/fragments/table.html:36 -#: templates/cotton/transaction/item.html:125 -#: templates/cotton/ui/transactions_action_bar.html:80 +#: templates/cotton/transaction/item.html:124 +#: templates/cotton/ui/transactions_action_bar.html:84 #: templates/currencies/fragments/list.html:44 -#: templates/dca/fragments/strategy/details.html:76 +#: templates/dca/fragments/strategy/details.html:75 #: templates/dca/fragments/strategy/list.html:42 #: templates/entities/fragments/table.html:36 -#: templates/exchange_rates/fragments/table.html:32 +#: templates/exchange_rates/fragments/table.html:31 #: templates/import_app/fragments/profiles/list.html:69 #: templates/import_app/fragments/runs/list.html:102 #: templates/installment_plans/fragments/table.html:56 @@ -1298,13 +1302,13 @@ msgstr "Verwijderen" #: templates/account_groups/fragments/list.html:47 #: templates/accounts/fragments/list.html:52 #: templates/categories/fragments/table.html:41 -#: templates/cotton/transaction/item.html:129 -#: templates/cotton/ui/transactions_action_bar.html:82 +#: templates/cotton/transaction/item.html:128 +#: templates/cotton/ui/transactions_action_bar.html:86 #: templates/currencies/fragments/list.html:48 -#: templates/dca/fragments/strategy/details.html:81 +#: templates/dca/fragments/strategy/details.html:80 #: templates/dca/fragments/strategy/list.html:46 #: templates/entities/fragments/table.html:40 -#: templates/exchange_rates/fragments/table.html:37 +#: templates/exchange_rates/fragments/table.html:36 #: templates/import_app/fragments/profiles/list.html:73 #: templates/import_app/fragments/runs/list.html:106 #: templates/installment_plans/fragments/table.html:48 @@ -1322,13 +1326,13 @@ msgstr "Weet je het zeker?" #: templates/account_groups/fragments/list.html:48 #: templates/accounts/fragments/list.html:53 #: templates/categories/fragments/table.html:42 -#: templates/cotton/transaction/item.html:130 -#: templates/cotton/ui/transactions_action_bar.html:83 +#: templates/cotton/transaction/item.html:129 +#: templates/cotton/ui/transactions_action_bar.html:87 #: templates/currencies/fragments/list.html:49 -#: templates/dca/fragments/strategy/details.html:82 +#: templates/dca/fragments/strategy/details.html:81 #: templates/dca/fragments/strategy/list.html:47 #: templates/entities/fragments/table.html:41 -#: templates/exchange_rates/fragments/table.html:38 +#: templates/exchange_rates/fragments/table.html:37 #: templates/import_app/fragments/profiles/list.html:74 #: templates/rules/fragments/list.html:49 #: templates/rules/fragments/transaction_rule/view.html:61 @@ -1339,12 +1343,12 @@ msgstr "Je kunt dit niet meer terugdraaien!" #: templates/account_groups/fragments/list.html:49 #: templates/accounts/fragments/list.html:54 #: templates/categories/fragments/table.html:43 -#: templates/cotton/transaction/item.html:131 +#: templates/cotton/transaction/item.html:130 #: templates/currencies/fragments/list.html:50 -#: templates/dca/fragments/strategy/details.html:83 +#: templates/dca/fragments/strategy/details.html:82 #: templates/dca/fragments/strategy/list.html:48 #: templates/entities/fragments/table.html:42 -#: templates/exchange_rates/fragments/table.html:39 +#: templates/exchange_rates/fragments/table.html:38 #: templates/import_app/fragments/profiles/list.html:75 #: templates/import_app/fragments/runs/list.html:108 #: templates/installment_plans/fragments/table.html:62 @@ -1419,11 +1423,11 @@ msgstr "ZAT" msgid "SUN" msgstr "ZON" -#: templates/calendar_view/fragments/list_transactions.html:6 +#: templates/calendar_view/fragments/list_transactions.html:5 msgid "Transactions on" msgstr "Verrichtingen op" -#: templates/calendar_view/fragments/list_transactions.html:16 +#: templates/calendar_view/fragments/list_transactions.html:15 msgid "No transactions on this date" msgstr "Geen verrichtingen op deze datum" @@ -1482,12 +1486,12 @@ msgstr "Sluiten" msgid "Search" msgstr "Zoeken" -#: templates/cotton/transaction/item.html:6 +#: templates/cotton/transaction/item.html:5 msgid "Select" msgstr "Selecteer" -#: templates/cotton/transaction/item.html:117 -#: templates/cotton/ui/transactions_action_bar.html:72 +#: templates/cotton/transaction/item.html:116 +#: templates/cotton/ui/transactions_action_bar.html:76 msgid "Duplicate" msgstr "Dupliceren" @@ -1511,62 +1515,62 @@ msgstr "Verwachte uitgaven" msgid "Current Expenses" msgstr "Huidige uitgaven" -#: templates/cotton/ui/transactions_action_bar.html:25 +#: templates/cotton/ui/transactions_action_bar.html:29 msgid "Select All" msgstr "Alles selecteren" -#: templates/cotton/ui/transactions_action_bar.html:31 +#: templates/cotton/ui/transactions_action_bar.html:35 msgid "Unselect All" msgstr "Alles deselecteren" -#: templates/cotton/ui/transactions_action_bar.html:48 -#: templates/cotton/ui/transactions_action_bar.html:139 +#: templates/cotton/ui/transactions_action_bar.html:52 +#: templates/cotton/ui/transactions_action_bar.html:143 msgid "Toggle Dropdown" msgstr "In- Uitklapbaar" -#: templates/cotton/ui/transactions_action_bar.html:56 +#: templates/cotton/ui/transactions_action_bar.html:60 msgid "Mark as unpaid" msgstr "Markeren als niet betaald" -#: templates/cotton/ui/transactions_action_bar.html:63 +#: templates/cotton/ui/transactions_action_bar.html:67 msgid "Mark as paid" msgstr "Markeren als betaald" -#: templates/cotton/ui/transactions_action_bar.html:84 +#: templates/cotton/ui/transactions_action_bar.html:88 msgid "Yes, delete them!" msgstr "Ja, verwijder ze!" -#: templates/cotton/ui/transactions_action_bar.html:130 -#: templates/cotton/ui/transactions_action_bar.html:154 -#: templates/cotton/ui/transactions_action_bar.html:174 -#: templates/cotton/ui/transactions_action_bar.html:194 -#: templates/cotton/ui/transactions_action_bar.html:214 -#: templates/cotton/ui/transactions_action_bar.html:234 -#: templates/cotton/ui/transactions_action_bar.html:254 +#: templates/cotton/ui/transactions_action_bar.html:134 +#: templates/cotton/ui/transactions_action_bar.html:158 +#: templates/cotton/ui/transactions_action_bar.html:178 +#: templates/cotton/ui/transactions_action_bar.html:198 +#: templates/cotton/ui/transactions_action_bar.html:218 +#: templates/cotton/ui/transactions_action_bar.html:238 +#: templates/cotton/ui/transactions_action_bar.html:258 msgid "copied!" msgstr "gekopieerd!" -#: templates/cotton/ui/transactions_action_bar.html:147 +#: templates/cotton/ui/transactions_action_bar.html:151 msgid "Flat Total" msgstr "Vast Totaal" -#: templates/cotton/ui/transactions_action_bar.html:167 +#: templates/cotton/ui/transactions_action_bar.html:171 msgid "Real Total" msgstr "Werkelijk Totaal" -#: templates/cotton/ui/transactions_action_bar.html:187 +#: templates/cotton/ui/transactions_action_bar.html:191 msgid "Mean" msgstr "Gemiddelde" -#: templates/cotton/ui/transactions_action_bar.html:207 +#: templates/cotton/ui/transactions_action_bar.html:211 msgid "Max" msgstr "Maximaal" -#: templates/cotton/ui/transactions_action_bar.html:227 +#: templates/cotton/ui/transactions_action_bar.html:231 msgid "Min" msgstr "Minimaal" -#: templates/cotton/ui/transactions_action_bar.html:247 +#: templates/cotton/ui/transactions_action_bar.html:251 msgid "Count" msgstr "Rekenen" @@ -1598,91 +1602,91 @@ msgstr "DCA-item bewerken" msgid "Add DCA strategy" msgstr "DCA-strategie toevoegen" -#: templates/dca/fragments/strategy/details.html:23 +#: templates/dca/fragments/strategy/details.html:22 msgid "No exchange rate available" msgstr "Geen wisselkoers beschikbaar" -#: templates/dca/fragments/strategy/details.html:34 +#: templates/dca/fragments/strategy/details.html:33 msgid "Entries" msgstr "Idems" -#: templates/dca/fragments/strategy/details.html:56 +#: templates/dca/fragments/strategy/details.html:55 msgid "Current Value" msgstr "Actuele waarde" -#: templates/dca/fragments/strategy/details.html:57 +#: templates/dca/fragments/strategy/details.html:56 msgid "P/L" msgstr "W&V" -#: templates/dca/fragments/strategy/details.html:125 +#: templates/dca/fragments/strategy/details.html:124 msgid "No entries for this DCA" msgstr "Geen idems in deze DCA" -#: templates/dca/fragments/strategy/details.html:126 +#: templates/dca/fragments/strategy/details.html:125 #: templates/monthly_overview/fragments/list.html:41 #: templates/transactions/fragments/list_all.html:40 msgid "Try adding one" msgstr "Probeer er een toe te voegen" -#: templates/dca/fragments/strategy/details.html:136 +#: templates/dca/fragments/strategy/details.html:135 msgid "Total Invested" msgstr "Totaal Geïnvesteerd" -#: templates/dca/fragments/strategy/details.html:150 +#: templates/dca/fragments/strategy/details.html:149 msgid "Total Received" msgstr "Totaal Ontvangen" -#: templates/dca/fragments/strategy/details.html:164 +#: templates/dca/fragments/strategy/details.html:163 msgid "Current Total Value" msgstr "Huidige Totaalwaarde" -#: templates/dca/fragments/strategy/details.html:178 +#: templates/dca/fragments/strategy/details.html:177 msgid "Average Entry Price" msgstr "Gemiddelde Instapprijs" -#: templates/dca/fragments/strategy/details.html:192 +#: templates/dca/fragments/strategy/details.html:191 msgid "Total P/L" msgstr "Totaal W&V" -#: templates/dca/fragments/strategy/details.html:208 +#: templates/dca/fragments/strategy/details.html:207 #, python-format msgid "Total %% P/L" msgstr "Totaal %% W&V" -#: templates/dca/fragments/strategy/details.html:227 +#: templates/dca/fragments/strategy/details.html:226 #, python-format msgid "P/L %%" msgstr "W&V %%" -#: templates/dca/fragments/strategy/details.html:289 +#: templates/dca/fragments/strategy/details.html:288 msgid "Performance Over Time" msgstr "Prestaties Na Verloop Van Tijd" -#: templates/dca/fragments/strategy/details.html:307 +#: templates/dca/fragments/strategy/details.html:306 msgid "Entry Price" msgstr "Ingangsprijs" -#: templates/dca/fragments/strategy/details.html:315 +#: templates/dca/fragments/strategy/details.html:314 msgid "Current Price" msgstr "Actuele Prijs" -#: templates/dca/fragments/strategy/details.html:323 +#: templates/dca/fragments/strategy/details.html:322 msgid "Amount Bought" msgstr "Gekocht Bedrag" -#: templates/dca/fragments/strategy/details.html:391 +#: templates/dca/fragments/strategy/details.html:390 msgid "Entry Price vs Current Price" msgstr "Instapprijs vs Huidige Prijs" -#: templates/dca/fragments/strategy/details.html:407 +#: templates/dca/fragments/strategy/details.html:406 msgid "Days Between Investments" msgstr "Dagen Tussen Investeringen" -#: templates/dca/fragments/strategy/details.html:454 +#: templates/dca/fragments/strategy/details.html:453 msgid "Investment Frequency" msgstr "Investeringsfrequentie" -#: templates/dca/fragments/strategy/details.html:456 +#: templates/dca/fragments/strategy/details.html:455 msgid "The straighter the blue line, the more consistent your DCA strategy is." msgstr "Hoe rechter de blauwe lijn, hoe consistenter je DCA-strategie is." @@ -1727,19 +1731,19 @@ msgstr "Wisselkoers bewerken" msgid "All" msgstr "Allemaal" -#: templates/exchange_rates/fragments/table.html:12 +#: templates/exchange_rates/fragments/table.html:11 msgid "Pairing" msgstr "Koppelen" -#: templates/exchange_rates/fragments/table.html:13 +#: templates/exchange_rates/fragments/table.html:12 msgid "Rate" msgstr "Tarief" -#: templates/exchange_rates/fragments/table.html:52 +#: templates/exchange_rates/fragments/table.html:51 msgid "No exchange rates" msgstr "Geen wisselkoersen" -#: templates/exchange_rates/fragments/table.html:59 +#: templates/exchange_rates/fragments/table.html:58 #: templates/transactions/fragments/list_all.html:47 msgid "Page navigation" msgstr "Paginanavigatie" diff --git a/app/locale/pt_BR/LC_MESSAGES/django.po b/app/locale/pt_BR/LC_MESSAGES/django.po index f84229d..842b1de 100644 --- a/app/locale/pt_BR/LC_MESSAGES/django.po +++ b/app/locale/pt_BR/LC_MESSAGES/django.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-25 16:51+0000\n" -"PO-Revision-Date: 2025-01-25 13:53-0300\n" -"Last-Translator: \n" +"POT-Creation-Date: 2025-01-27 16:26+0000\n" +"PO-Revision-Date: 2025-01-27 13:27-0300\n" +"Last-Translator: Herculino Trotta\n" "Language-Team: \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" @@ -24,28 +24,28 @@ msgid "Group name" msgstr "Nome do grupo" #: apps/accounts/forms.py:40 apps/accounts/forms.py:96 -#: apps/currencies/forms.py:52 apps/currencies/forms.py:92 apps/dca/forms.py:41 +#: apps/currencies/forms.py:52 apps/currencies/forms.py:90 apps/dca/forms.py:41 #: apps/dca/forms.py:93 apps/import_app/forms.py:34 apps/rules/forms.py:45 #: apps/rules/forms.py:87 apps/transactions/forms.py:190 -#: apps/transactions/forms.py:257 apps/transactions/forms.py:583 -#: apps/transactions/forms.py:626 apps/transactions/forms.py:658 -#: apps/transactions/forms.py:693 apps/transactions/forms.py:831 +#: apps/transactions/forms.py:257 apps/transactions/forms.py:581 +#: apps/transactions/forms.py:624 apps/transactions/forms.py:656 +#: apps/transactions/forms.py:691 apps/transactions/forms.py:827 msgid "Update" msgstr "Atualizar" #: apps/accounts/forms.py:48 apps/accounts/forms.py:104 #: apps/common/widgets/tom_select.py:12 apps/currencies/forms.py:60 -#: apps/currencies/forms.py:100 apps/dca/forms.py:49 apps/dca/forms.py:102 +#: apps/currencies/forms.py:98 apps/dca/forms.py:49 apps/dca/forms.py:102 #: apps/import_app/forms.py:42 apps/rules/forms.py:53 apps/rules/forms.py:95 #: apps/transactions/forms.py:174 apps/transactions/forms.py:199 -#: apps/transactions/forms.py:591 apps/transactions/forms.py:634 -#: apps/transactions/forms.py:666 apps/transactions/forms.py:701 -#: apps/transactions/forms.py:839 +#: apps/transactions/forms.py:589 apps/transactions/forms.py:632 +#: apps/transactions/forms.py:664 apps/transactions/forms.py:699 +#: apps/transactions/forms.py:835 #: templates/account_groups/fragments/list.html:9 #: templates/accounts/fragments/list.html:9 #: templates/categories/fragments/list.html:9 #: templates/currencies/fragments/list.html:9 -#: templates/dca/fragments/strategy/details.html:38 +#: templates/dca/fragments/strategy/details.html:37 #: templates/dca/fragments/strategy/list.html:9 #: templates/entities/fragments/list.html:9 #: templates/exchange_rates/fragments/list.html:10 @@ -69,7 +69,7 @@ msgstr "Novo saldo" #: apps/accounts/forms.py:119 apps/rules/models.py:27 #: apps/transactions/forms.py:39 apps/transactions/forms.py:291 #: apps/transactions/forms.py:298 apps/transactions/forms.py:478 -#: apps/transactions/forms.py:725 apps/transactions/models.py:159 +#: apps/transactions/forms.py:723 apps/transactions/models.py:159 #: apps/transactions/models.py:311 apps/transactions/models.py:491 msgid "Category" msgstr "Categoria" @@ -77,7 +77,7 @@ msgstr "Categoria" #: apps/accounts/forms.py:126 apps/rules/models.py:28 #: apps/transactions/filters.py:74 apps/transactions/forms.py:47 #: apps/transactions/forms.py:307 apps/transactions/forms.py:315 -#: apps/transactions/forms.py:471 apps/transactions/forms.py:718 +#: apps/transactions/forms.py:471 apps/transactions/forms.py:716 #: apps/transactions/models.py:165 apps/transactions/models.py:313 #: apps/transactions/models.py:495 templates/includes/navbar.html:98 #: templates/tags/fragments/list.html:5 templates/tags/pages/index.html:4 @@ -150,7 +150,7 @@ msgstr "" #: apps/accounts/models.py:59 apps/rules/models.py:19 #: apps/transactions/forms.py:59 apps/transactions/forms.py:463 -#: apps/transactions/forms.py:710 apps/transactions/models.py:132 +#: apps/transactions/forms.py:708 apps/transactions/models.py:132 #: apps/transactions/models.py:271 apps/transactions/models.py:473 msgid "Account" msgstr "Conta" @@ -320,11 +320,11 @@ msgstr "Erro" msgid "Info" msgstr "Informação" -#: apps/common/widgets/datepicker.py:55 apps/common/widgets/datepicker.py:197 +#: apps/common/widgets/datepicker.py:47 apps/common/widgets/datepicker.py:186 msgid "Today" msgstr "Hoje" -#: apps/common/widgets/datepicker.py:139 +#: apps/common/widgets/datepicker.py:123 msgid "Now" msgstr "Agora" @@ -354,8 +354,8 @@ msgstr "Sufixo" #: apps/currencies/forms.py:68 apps/dca/models.py:156 apps/rules/models.py:22 #: apps/transactions/forms.py:63 apps/transactions/forms.py:319 #: apps/transactions/models.py:142 -#: templates/dca/fragments/strategy/details.html:53 -#: templates/exchange_rates/fragments/table.html:11 +#: templates/dca/fragments/strategy/details.html:52 +#: templates/exchange_rates/fragments/table.html:10 msgid "Date" msgstr "Data" @@ -405,7 +405,7 @@ msgstr "Data e Tempo" msgid "Exchange Rates" msgstr "Taxas de Câmbio" -#: apps/currencies/models.py:77 +#: apps/currencies/models.py:79 msgid "From and To currencies cannot be the same." msgstr "As moedas De e Para não podem ser as mesmas." @@ -459,11 +459,11 @@ msgstr "Estratégias CMP" msgid "Strategy" msgstr "Estratégia" -#: apps/dca/models.py:158 templates/dca/fragments/strategy/details.html:55 +#: apps/dca/models.py:158 templates/dca/fragments/strategy/details.html:54 msgid "Amount Paid" msgstr "Quantia paga" -#: apps/dca/models.py:161 templates/dca/fragments/strategy/details.html:54 +#: apps/dca/models.py:161 templates/dca/fragments/strategy/details.html:53 msgid "Amount Received" msgstr "Quantia recebida" @@ -641,7 +641,7 @@ msgstr "Quantia" #: apps/rules/models.py:29 apps/transactions/filters.py:81 #: apps/transactions/forms.py:55 apps/transactions/forms.py:486 -#: apps/transactions/forms.py:733 apps/transactions/models.py:117 +#: apps/transactions/forms.py:731 apps/transactions/models.py:117 #: apps/transactions/models.py:170 apps/transactions/models.py:316 #: apps/transactions/models.py:498 templates/entities/fragments/list.html:5 #: templates/entities/pages/index.html:4 templates/includes/navbar.html:100 @@ -759,23 +759,23 @@ msgstr "Transferir" msgid "From and To accounts must be different." msgstr "As contas De e Para devem ser diferentes." -#: apps/transactions/forms.py:612 +#: apps/transactions/forms.py:610 msgid "Tag name" msgstr "Nome da Tag" -#: apps/transactions/forms.py:644 +#: apps/transactions/forms.py:642 msgid "Entity name" msgstr "Nome da entidade" -#: apps/transactions/forms.py:676 +#: apps/transactions/forms.py:674 msgid "Category name" msgstr "Nome da Categoria" -#: apps/transactions/forms.py:678 +#: apps/transactions/forms.py:676 msgid "Muted categories won't count towards your monthly total" msgstr "As categorias silenciadas não serão contabilizadas em seu total mensal" -#: apps/transactions/forms.py:850 +#: apps/transactions/forms.py:846 msgid "End date should be after the start date" msgstr "Data final deve ser após data inicial" @@ -1043,15 +1043,15 @@ msgstr "Entidade apagada com sucesso" msgid "Installment Plan added successfully" msgstr "Parcelamento adicionado com sucesso" -#: apps/transactions/views/installment_plans.py:117 +#: apps/transactions/views/installment_plans.py:115 msgid "Installment Plan updated successfully" msgstr "Parcelamento atualizado com sucesso" -#: apps/transactions/views/installment_plans.py:142 +#: apps/transactions/views/installment_plans.py:140 msgid "Installment Plan refreshed successfully" msgstr "Parcelamento atualizado com sucesso" -#: apps/transactions/views/installment_plans.py:160 +#: apps/transactions/views/installment_plans.py:158 msgid "Installment Plan deleted successfully" msgstr "Parcelamento apagado com sucesso" @@ -1059,23 +1059,23 @@ msgstr "Parcelamento apagado com sucesso" msgid "Recurring Transaction added successfully" msgstr "Transação Recorrente adicionada com sucesso" -#: apps/transactions/views/recurring_transactions.py:144 +#: apps/transactions/views/recurring_transactions.py:142 msgid "Recurring Transaction updated successfully" msgstr "Transação Recorrente atualizada com sucesso" -#: apps/transactions/views/recurring_transactions.py:190 +#: apps/transactions/views/recurring_transactions.py:186 msgid "Recurring transaction unpaused successfully" msgstr "Transação Recorrente despausada com sucesso" -#: apps/transactions/views/recurring_transactions.py:193 +#: apps/transactions/views/recurring_transactions.py:189 msgid "Recurring transaction paused successfully" msgstr "Transação Recorrente pausada com sucesso" -#: apps/transactions/views/recurring_transactions.py:219 +#: apps/transactions/views/recurring_transactions.py:215 msgid "Recurring transaction finished successfully" msgstr "Transação Recorrente finalizada com sucesso" -#: apps/transactions/views/recurring_transactions.py:239 +#: apps/transactions/views/recurring_transactions.py:235 msgid "Recurring Transaction deleted successfully" msgstr "Transação Recorrente apagada com sucesso" @@ -1092,30 +1092,30 @@ msgid "Tag deleted successfully" msgstr "Tag apagada com sucesso" #: apps/transactions/views/transactions.py:50 -#: apps/transactions/views/transactions.py:90 +#: apps/transactions/views/transactions.py:89 msgid "Transaction added successfully" msgstr "Transação adicionada com sucesso" -#: apps/transactions/views/transactions.py:126 +#: apps/transactions/views/transactions.py:123 msgid "Transaction updated successfully" msgstr "Transação atualizada com sucesso" -#: apps/transactions/views/transactions.py:176 +#: apps/transactions/views/transactions.py:173 #, python-format msgid "%(count)s transaction updated successfully" msgid_plural "%(count)s transactions updated successfully" msgstr[0] "%(count)s transação atualizada com sucesso" msgstr[1] "%(count)s transações atualizadas com sucesso" -#: apps/transactions/views/transactions.py:214 +#: apps/transactions/views/transactions.py:209 msgid "Transaction duplicated successfully" msgstr "Transação duplicada com sucesso" -#: apps/transactions/views/transactions.py:256 +#: apps/transactions/views/transactions.py:251 msgid "Transaction deleted successfully" msgstr "Transação apagada com sucesso" -#: apps/transactions/views/transactions.py:282 +#: apps/transactions/views/transactions.py:277 msgid "Transfer added successfully" msgstr "Transferência adicionada com sucesso" @@ -1155,21 +1155,25 @@ msgstr "E-mail ou senha inválidos" msgid "This account is deactivated" msgstr "Essa conta está desativada" -#: apps/users/forms.py:50 apps/users/forms.py:63 +#: apps/users/forms.py:50 apps/users/forms.py:63 apps/users/forms.py:85 #: templates/monthly_overview/pages/overview.html:116 #: templates/transactions/pages/transactions.html:35 msgid "Default" msgstr "Padrão" -#: apps/users/forms.py:85 apps/users/models.py:40 +#: apps/users/forms.py:91 apps/users/models.py:40 msgid "Date Format" msgstr "Formato de Data" -#: apps/users/forms.py:90 apps/users/models.py:45 +#: apps/users/forms.py:96 apps/users/models.py:45 msgid "Datetime Format" msgstr "Formato de Data e Hora" -#: apps/users/forms.py:117 +#: apps/users/forms.py:102 apps/users/models.py:48 +msgid "Number Format" +msgstr "Formato de Número" + +#: apps/users/forms.py:131 msgid "Save" msgstr "Salvar" @@ -1193,19 +1197,19 @@ msgstr "Todas as transações" msgid "Calendar" msgstr "Calendário" -#: apps/users/models.py:50 apps/users/models.py:56 +#: apps/users/models.py:53 apps/users/models.py:59 msgid "Auto" msgstr "Automático" -#: apps/users/models.py:52 +#: apps/users/models.py:55 msgid "Language" msgstr "Linguagem" -#: apps/users/models.py:58 +#: apps/users/models.py:61 msgid "Time Zone" msgstr "Fuso horário" -#: apps/users/models.py:64 +#: apps/users/models.py:67 msgid "Start page" msgstr "Página inicial" @@ -1241,9 +1245,9 @@ msgstr "Editar grupo de conta" #: templates/accounts/fragments/list.html:37 #: templates/categories/fragments/table.html:24 #: templates/currencies/fragments/list.html:33 -#: templates/dca/fragments/strategy/details.html:64 +#: templates/dca/fragments/strategy/details.html:63 #: templates/entities/fragments/table.html:23 -#: templates/exchange_rates/fragments/table.html:20 +#: templates/exchange_rates/fragments/table.html:19 #: templates/import_app/fragments/profiles/list.html:44 #: templates/installment_plans/fragments/table.html:23 #: templates/recurring_transactions/fragments/table.html:25 @@ -1255,13 +1259,13 @@ msgstr "Ações" #: templates/account_groups/fragments/list.html:36 #: templates/accounts/fragments/list.html:41 #: templates/categories/fragments/table.html:29 -#: templates/cotton/transaction/item.html:110 -#: templates/cotton/ui/transactions_action_bar.html:43 +#: templates/cotton/transaction/item.html:109 +#: templates/cotton/ui/transactions_action_bar.html:47 #: templates/currencies/fragments/list.html:37 -#: templates/dca/fragments/strategy/details.html:68 +#: templates/dca/fragments/strategy/details.html:67 #: templates/dca/fragments/strategy/list.html:34 #: templates/entities/fragments/table.html:28 -#: templates/exchange_rates/fragments/table.html:24 +#: templates/exchange_rates/fragments/table.html:23 #: templates/import_app/fragments/profiles/list.html:48 #: templates/installment_plans/fragments/table.html:27 #: templates/recurring_transactions/fragments/table.html:29 @@ -1274,13 +1278,13 @@ msgstr "Editar" #: templates/account_groups/fragments/list.html:43 #: templates/accounts/fragments/list.html:48 #: templates/categories/fragments/table.html:36 -#: templates/cotton/transaction/item.html:125 -#: templates/cotton/ui/transactions_action_bar.html:80 +#: templates/cotton/transaction/item.html:124 +#: templates/cotton/ui/transactions_action_bar.html:84 #: templates/currencies/fragments/list.html:44 -#: templates/dca/fragments/strategy/details.html:76 +#: templates/dca/fragments/strategy/details.html:75 #: templates/dca/fragments/strategy/list.html:42 #: templates/entities/fragments/table.html:36 -#: templates/exchange_rates/fragments/table.html:32 +#: templates/exchange_rates/fragments/table.html:31 #: templates/import_app/fragments/profiles/list.html:69 #: templates/import_app/fragments/runs/list.html:102 #: templates/installment_plans/fragments/table.html:56 @@ -1295,13 +1299,13 @@ msgstr "Apagar" #: templates/account_groups/fragments/list.html:47 #: templates/accounts/fragments/list.html:52 #: templates/categories/fragments/table.html:41 -#: templates/cotton/transaction/item.html:129 -#: templates/cotton/ui/transactions_action_bar.html:82 +#: templates/cotton/transaction/item.html:128 +#: templates/cotton/ui/transactions_action_bar.html:86 #: templates/currencies/fragments/list.html:48 -#: templates/dca/fragments/strategy/details.html:81 +#: templates/dca/fragments/strategy/details.html:80 #: templates/dca/fragments/strategy/list.html:46 #: templates/entities/fragments/table.html:40 -#: templates/exchange_rates/fragments/table.html:37 +#: templates/exchange_rates/fragments/table.html:36 #: templates/import_app/fragments/profiles/list.html:73 #: templates/import_app/fragments/runs/list.html:106 #: templates/installment_plans/fragments/table.html:48 @@ -1319,13 +1323,13 @@ msgstr "Tem certeza?" #: templates/account_groups/fragments/list.html:48 #: templates/accounts/fragments/list.html:53 #: templates/categories/fragments/table.html:42 -#: templates/cotton/transaction/item.html:130 -#: templates/cotton/ui/transactions_action_bar.html:83 +#: templates/cotton/transaction/item.html:129 +#: templates/cotton/ui/transactions_action_bar.html:87 #: templates/currencies/fragments/list.html:49 -#: templates/dca/fragments/strategy/details.html:82 +#: templates/dca/fragments/strategy/details.html:81 #: templates/dca/fragments/strategy/list.html:47 #: templates/entities/fragments/table.html:41 -#: templates/exchange_rates/fragments/table.html:38 +#: templates/exchange_rates/fragments/table.html:37 #: templates/import_app/fragments/profiles/list.html:74 #: templates/rules/fragments/list.html:49 #: templates/rules/fragments/transaction_rule/view.html:61 @@ -1336,12 +1340,12 @@ msgstr "Você não será capaz de reverter isso!" #: templates/account_groups/fragments/list.html:49 #: templates/accounts/fragments/list.html:54 #: templates/categories/fragments/table.html:43 -#: templates/cotton/transaction/item.html:131 +#: templates/cotton/transaction/item.html:130 #: templates/currencies/fragments/list.html:50 -#: templates/dca/fragments/strategy/details.html:83 +#: templates/dca/fragments/strategy/details.html:82 #: templates/dca/fragments/strategy/list.html:48 #: templates/entities/fragments/table.html:42 -#: templates/exchange_rates/fragments/table.html:39 +#: templates/exchange_rates/fragments/table.html:38 #: templates/import_app/fragments/profiles/list.html:75 #: templates/import_app/fragments/runs/list.html:108 #: templates/installment_plans/fragments/table.html:62 @@ -1416,11 +1420,11 @@ msgstr "SÁB" msgid "SUN" msgstr "DOM" -#: templates/calendar_view/fragments/list_transactions.html:6 +#: templates/calendar_view/fragments/list_transactions.html:5 msgid "Transactions on" msgstr "Transações em" -#: templates/calendar_view/fragments/list_transactions.html:16 +#: templates/calendar_view/fragments/list_transactions.html:15 msgid "No transactions on this date" msgstr "Nenhuma transação nesta data" @@ -1479,12 +1483,12 @@ msgstr "Fechar" msgid "Search" msgstr "Buscar" -#: templates/cotton/transaction/item.html:6 +#: templates/cotton/transaction/item.html:5 msgid "Select" msgstr "Selecionar" -#: templates/cotton/transaction/item.html:117 -#: templates/cotton/ui/transactions_action_bar.html:72 +#: templates/cotton/transaction/item.html:116 +#: templates/cotton/ui/transactions_action_bar.html:76 msgid "Duplicate" msgstr "Duplicar" @@ -1508,62 +1512,62 @@ msgstr "Despesas Previstas" msgid "Current Expenses" msgstr "Despesas Atuais" -#: templates/cotton/ui/transactions_action_bar.html:25 +#: templates/cotton/ui/transactions_action_bar.html:29 msgid "Select All" msgstr "Selecionar todos" -#: templates/cotton/ui/transactions_action_bar.html:31 +#: templates/cotton/ui/transactions_action_bar.html:35 msgid "Unselect All" msgstr "Desmarcar todos" -#: templates/cotton/ui/transactions_action_bar.html:48 -#: templates/cotton/ui/transactions_action_bar.html:139 +#: templates/cotton/ui/transactions_action_bar.html:52 +#: templates/cotton/ui/transactions_action_bar.html:143 msgid "Toggle Dropdown" msgstr "Alternar menu suspenso" -#: templates/cotton/ui/transactions_action_bar.html:56 +#: templates/cotton/ui/transactions_action_bar.html:60 msgid "Mark as unpaid" msgstr "Marcar como não pago" -#: templates/cotton/ui/transactions_action_bar.html:63 +#: templates/cotton/ui/transactions_action_bar.html:67 msgid "Mark as paid" msgstr "Marcar como pago" -#: templates/cotton/ui/transactions_action_bar.html:84 +#: templates/cotton/ui/transactions_action_bar.html:88 msgid "Yes, delete them!" msgstr "Sim, apague!" -#: templates/cotton/ui/transactions_action_bar.html:130 -#: templates/cotton/ui/transactions_action_bar.html:154 -#: templates/cotton/ui/transactions_action_bar.html:174 -#: templates/cotton/ui/transactions_action_bar.html:194 -#: templates/cotton/ui/transactions_action_bar.html:214 -#: templates/cotton/ui/transactions_action_bar.html:234 -#: templates/cotton/ui/transactions_action_bar.html:254 +#: templates/cotton/ui/transactions_action_bar.html:134 +#: templates/cotton/ui/transactions_action_bar.html:158 +#: templates/cotton/ui/transactions_action_bar.html:178 +#: templates/cotton/ui/transactions_action_bar.html:198 +#: templates/cotton/ui/transactions_action_bar.html:218 +#: templates/cotton/ui/transactions_action_bar.html:238 +#: templates/cotton/ui/transactions_action_bar.html:258 msgid "copied!" msgstr "copiado!" -#: templates/cotton/ui/transactions_action_bar.html:147 +#: templates/cotton/ui/transactions_action_bar.html:151 msgid "Flat Total" msgstr "Total Fixo" -#: templates/cotton/ui/transactions_action_bar.html:167 +#: templates/cotton/ui/transactions_action_bar.html:171 msgid "Real Total" msgstr "Total Real" -#: templates/cotton/ui/transactions_action_bar.html:187 +#: templates/cotton/ui/transactions_action_bar.html:191 msgid "Mean" msgstr "Média" -#: templates/cotton/ui/transactions_action_bar.html:207 +#: templates/cotton/ui/transactions_action_bar.html:211 msgid "Max" msgstr "Máximo" -#: templates/cotton/ui/transactions_action_bar.html:227 +#: templates/cotton/ui/transactions_action_bar.html:231 msgid "Min" msgstr "Minímo" -#: templates/cotton/ui/transactions_action_bar.html:247 +#: templates/cotton/ui/transactions_action_bar.html:251 msgid "Count" msgstr "Contagem" @@ -1595,91 +1599,91 @@ msgstr "Editar entrada CMP" msgid "Add DCA strategy" msgstr "Adicionar estratégia CMP" -#: templates/dca/fragments/strategy/details.html:23 +#: templates/dca/fragments/strategy/details.html:22 msgid "No exchange rate available" msgstr "Nenhuma taxa de câmbio disponível" -#: templates/dca/fragments/strategy/details.html:34 +#: templates/dca/fragments/strategy/details.html:33 msgid "Entries" msgstr "Entradas" -#: templates/dca/fragments/strategy/details.html:56 +#: templates/dca/fragments/strategy/details.html:55 msgid "Current Value" msgstr "Valor atual" -#: templates/dca/fragments/strategy/details.html:57 +#: templates/dca/fragments/strategy/details.html:56 msgid "P/L" msgstr "P/L" -#: templates/dca/fragments/strategy/details.html:125 +#: templates/dca/fragments/strategy/details.html:124 msgid "No entries for this DCA" msgstr "Nenhuma entrada neste CMP" -#: templates/dca/fragments/strategy/details.html:126 +#: templates/dca/fragments/strategy/details.html:125 #: templates/monthly_overview/fragments/list.html:41 #: templates/transactions/fragments/list_all.html:40 msgid "Try adding one" msgstr "Tente adicionar uma" -#: templates/dca/fragments/strategy/details.html:136 +#: templates/dca/fragments/strategy/details.html:135 msgid "Total Invested" msgstr "Total investido" -#: templates/dca/fragments/strategy/details.html:150 +#: templates/dca/fragments/strategy/details.html:149 msgid "Total Received" msgstr "Total recebido" -#: templates/dca/fragments/strategy/details.html:164 +#: templates/dca/fragments/strategy/details.html:163 msgid "Current Total Value" msgstr "Valor total atual" -#: templates/dca/fragments/strategy/details.html:178 +#: templates/dca/fragments/strategy/details.html:177 msgid "Average Entry Price" msgstr "Preço médio de entrada" -#: templates/dca/fragments/strategy/details.html:192 +#: templates/dca/fragments/strategy/details.html:191 msgid "Total P/L" msgstr "P/L total" -#: templates/dca/fragments/strategy/details.html:208 +#: templates/dca/fragments/strategy/details.html:207 #, python-format msgid "Total %% P/L" msgstr "P/L%% Total" -#: templates/dca/fragments/strategy/details.html:227 +#: templates/dca/fragments/strategy/details.html:226 #, python-format msgid "P/L %%" msgstr "P/L %%" -#: templates/dca/fragments/strategy/details.html:289 +#: templates/dca/fragments/strategy/details.html:288 msgid "Performance Over Time" msgstr "Desempenho ao longo do tempo" -#: templates/dca/fragments/strategy/details.html:307 +#: templates/dca/fragments/strategy/details.html:306 msgid "Entry Price" msgstr "Preço de Entrada" -#: templates/dca/fragments/strategy/details.html:315 +#: templates/dca/fragments/strategy/details.html:314 msgid "Current Price" msgstr "Preço atual" -#: templates/dca/fragments/strategy/details.html:323 +#: templates/dca/fragments/strategy/details.html:322 msgid "Amount Bought" msgstr "Quantia comprada" -#: templates/dca/fragments/strategy/details.html:391 +#: templates/dca/fragments/strategy/details.html:390 msgid "Entry Price vs Current Price" msgstr "Preço de Entrada vs Preço Atual" -#: templates/dca/fragments/strategy/details.html:407 +#: templates/dca/fragments/strategy/details.html:406 msgid "Days Between Investments" msgstr "Dias entre investimentos" -#: templates/dca/fragments/strategy/details.html:454 +#: templates/dca/fragments/strategy/details.html:453 msgid "Investment Frequency" msgstr "Frequência de Investimento" -#: templates/dca/fragments/strategy/details.html:456 +#: templates/dca/fragments/strategy/details.html:455 msgid "The straighter the blue line, the more consistent your DCA strategy is." msgstr "" "Quanto mais reta for a linha azul, mais consistente é sua estratégia de CMP." @@ -1725,19 +1729,19 @@ msgstr "Editar taxa de câmbio" msgid "All" msgstr "Todas" -#: templates/exchange_rates/fragments/table.html:12 +#: templates/exchange_rates/fragments/table.html:11 msgid "Pairing" msgstr "Pares" -#: templates/exchange_rates/fragments/table.html:13 +#: templates/exchange_rates/fragments/table.html:12 msgid "Rate" msgstr "Taxa de Câmbio" -#: templates/exchange_rates/fragments/table.html:52 +#: templates/exchange_rates/fragments/table.html:51 msgid "No exchange rates" msgstr "Nenhuma taxa de câmbio" -#: templates/exchange_rates/fragments/table.html:59 +#: templates/exchange_rates/fragments/table.html:58 #: templates/transactions/fragments/list_all.html:47 msgid "Page navigation" msgstr "Navegação por página"