diff --git a/app/apps/common/models.py b/app/apps/common/models.py index 7d33dc5..d446921 100644 --- a/app/apps/common/models.py +++ b/app/apps/common/models.py @@ -65,6 +65,18 @@ class SharedObject(models.Model): super().save(*args, **kwargs) +class OwnedObjectManager(models.Manager): + def get_queryset(self): + """Return only objects the user can access""" + user = get_current_user() + base_qs = super().get_queryset() + + if user and user.is_authenticated: + return base_qs.filter(Q(owner=user) | Q(owner=None)).distinct() + + return base_qs + + class OwnedObject(models.Model): owner = models.ForeignKey( settings.AUTH_USER_MODEL, diff --git a/app/apps/transactions/forms.py b/app/apps/transactions/forms.py index 456cd3a..5299901 100644 --- a/app/apps/transactions/forms.py +++ b/app/apps/transactions/forms.py @@ -7,6 +7,7 @@ from crispy_forms.layout import ( Column, Field, Div, + HTML, ) from django import forms from django.db.models import Q @@ -29,8 +30,8 @@ from apps.transactions.models import ( InstallmentPlan, RecurringTransaction, TransactionEntity, + QuickTransaction, ) -from apps.common.middleware.thread_local import get_current_user class TransactionForm(forms.ModelForm): @@ -247,6 +248,140 @@ class TransactionForm(forms.ModelForm): return instance +class QuickTransactionForm(forms.ModelForm): + category = DynamicModelChoiceField( + create_field="name", + model=TransactionCategory, + required=False, + label=_("Category"), + queryset=TransactionCategory.objects.filter(active=True), + ) + tags = DynamicModelMultipleChoiceField( + model=TransactionTag, + to_field_name="name", + create_field="name", + required=False, + label=_("Tags"), + queryset=TransactionTag.objects.filter(active=True), + ) + entities = DynamicModelMultipleChoiceField( + model=TransactionEntity, + to_field_name="name", + create_field="name", + required=False, + label=_("Entities"), + ) + account = forms.ModelChoiceField( + queryset=Account.objects.filter(is_archived=False), + label=_("Account"), + widget=TomSelect(clear_button=False, group_by="group"), + ) + + class Meta: + model = QuickTransaction + fields = [ + "name", + "account", + "type", + "is_paid", + "amount", + "description", + "notes", + "category", + "tags", + "entities", + ] + widgets = { + "notes": forms.Textarea(attrs={"rows": 3}), + "account": TomSelect(clear_button=False, group_by="group"), + } + + 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 + if self.instance.id: + self.fields["account"].queryset = Account.objects.filter( + Q(is_archived=False) | Q(transactions=self.instance.id), + ) + + self.fields["category"].queryset = TransactionCategory.objects.filter( + Q(active=True) | Q(transaction=self.instance.id) + ) + + self.fields["tags"].queryset = TransactionTag.objects.filter( + Q(active=True) | Q(transaction=self.instance.id) + ) + + self.fields["entities"].queryset = TransactionEntity.objects.filter( + Q(active=True) | Q(transactions=self.instance.id) + ) + else: + self.fields["account"].queryset = Account.objects.filter( + is_archived=False, + ) + + self.fields["category"].queryset = TransactionCategory.objects.filter( + active=True + ) + self.fields["tags"].queryset = TransactionTag.objects.filter(active=True) + self.fields["entities"].queryset = TransactionEntity.objects.all() + + self.helper = FormHelper() + self.helper.form_tag = False + self.helper.form_method = "post" + self.helper.layout = Layout( + Field( + "type", + template="transactions/widgets/income_expense_toggle_buttons.html", + ), + Field("is_paid", template="transactions/widgets/paid_toggle_button.html"), + "name", + HTML("
"), + Row( + Column("account", css_class="form-group col-md-6 mb-0"), + Column("entities", css_class="form-group col-md-6 mb-0"), + css_class="form-row", + ), + Row( + Column(Field("date"), css_class="form-group col-md-6 mb-0"), + Column(Field("reference_date"), css_class="form-group col-md-6 mb-0"), + css_class="form-row", + ), + "description", + Field("amount", inputmode="decimal"), + Row( + Column("category", css_class="form-group col-md-6 mb-0"), + Column("tags", css_class="form-group col-md-6 mb-0"), + css_class="form-row", + ), + "notes", + ) + + if self.instance and self.instance.pk: + decimal_places = self.instance.account.currency.decimal_places + self.fields["amount"].widget = ArbitraryDecimalDisplayNumberInput( + decimal_places=decimal_places + ) + self.helper.layout.append( + FormActions( + NoClassSubmit( + "submit", _("Update"), css_class="btn btn-outline-primary w-100" + ), + ), + ) + else: + self.fields["amount"].widget = ArbitraryDecimalDisplayNumberInput() + self.helper.layout.append( + Div( + NoClassSubmit( + "submit", _("Add"), css_class="btn btn-outline-primary" + ), + css_class="d-grid gap-2", + ), + ) + + class BulkEditTransactionForm(TransactionForm): is_paid = forms.NullBooleanField(required=False) diff --git a/app/apps/transactions/migrations/0043_quicktransaction.py b/app/apps/transactions/migrations/0043_quicktransaction.py new file mode 100644 index 0000000..275d854 --- /dev/null +++ b/app/apps/transactions/migrations/0043_quicktransaction.py @@ -0,0 +1,45 @@ +# Generated by Django 5.1.11 on 2025-06-20 03:57 + +import apps.transactions.validators +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0014_alter_account_options_alter_accountgroup_options'), + ('transactions', '0042_alter_transactioncategory_options_and_more'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='QuickTransaction', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100, verbose_name='Name')), + ('type', models.CharField(choices=[('IN', 'Income'), ('EX', 'Expense')], default='EX', max_length=2, verbose_name='Type')), + ('is_paid', models.BooleanField(default=True, verbose_name='Paid')), + ('amount', models.DecimalField(decimal_places=30, max_digits=42, validators=[apps.transactions.validators.validate_non_negative, apps.transactions.validators.validate_decimal_places], verbose_name='Amount')), + ('description', models.CharField(blank=True, max_length=500, verbose_name='Description')), + ('notes', models.TextField(blank=True, verbose_name='Notes')), + ('internal_note', models.TextField(blank=True, verbose_name='Internal Note')), + ('internal_id', models.TextField(blank=True, null=True, unique=True, verbose_name='Internal ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='quick_transactions', to='accounts.account', verbose_name='Account')), + ('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='transactions.transactioncategory', verbose_name='Category')), + ('entities', models.ManyToManyField(blank=True, related_name='quick_transactions', to='transactions.transactionentity', verbose_name='Entities')), + ('owner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_owned', to=settings.AUTH_USER_MODEL)), + ('tags', models.ManyToManyField(blank=True, to='transactions.transactiontag', verbose_name='Tags')), + ], + options={ + 'verbose_name': 'Quick Transaction', + 'verbose_name_plural': 'Quick Transactions', + 'db_table': 'quick_transactions', + 'default_manager_name': 'objects', + }, + ), + ] diff --git a/app/apps/transactions/migrations/0044_alter_quicktransaction_unique_together.py b/app/apps/transactions/migrations/0044_alter_quicktransaction_unique_together.py new file mode 100644 index 0000000..fa07fb1 --- /dev/null +++ b/app/apps/transactions/migrations/0044_alter_quicktransaction_unique_together.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.11 on 2025-06-20 04:02 + +from django.conf import settings +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('transactions', '0043_quicktransaction'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='quicktransaction', + unique_together={('name', 'owner')}, + ), + ] diff --git a/app/apps/transactions/models.py b/app/apps/transactions/models.py index 6fd6d36..82cfe90 100644 --- a/app/apps/transactions/models.py +++ b/app/apps/transactions/models.py @@ -16,7 +16,12 @@ from apps.common.templatetags.decimal import localize_number, drop_trailing_zero from apps.currencies.utils.convert import convert from apps.transactions.validators import validate_decimal_places, validate_non_negative from apps.common.middleware.thread_local import get_current_user -from apps.common.models import SharedObject, SharedObjectManager, OwnedObject +from apps.common.models import ( + SharedObject, + SharedObjectManager, + OwnedObject, + OwnedObjectManager, +) logger = logging.getLogger() @@ -886,3 +891,86 @@ class RecurringTransaction(models.Model): """ today = timezone.localdate(timezone.now()) self.transactions.filter(is_paid=False, date__gt=today).delete() + + +class QuickTransaction(OwnedObject): + class Type(models.TextChoices): + INCOME = "IN", _("Income") + EXPENSE = "EX", _("Expense") + + name = models.CharField( + max_length=100, + null=False, + blank=False, + verbose_name=_("Name"), + ) + + account = models.ForeignKey( + "accounts.Account", + on_delete=models.CASCADE, + verbose_name=_("Account"), + related_name="quick_transactions", + ) + type = models.CharField( + max_length=2, + choices=Type, + default=Type.EXPENSE, + verbose_name=_("Type"), + ) + is_paid = models.BooleanField(default=True, verbose_name=_("Paid")) + + amount = models.DecimalField( + max_digits=42, + decimal_places=30, + verbose_name=_("Amount"), + validators=[validate_non_negative, validate_decimal_places], + ) + + description = models.CharField( + max_length=500, verbose_name=_("Description"), blank=True + ) + notes = models.TextField(blank=True, verbose_name=_("Notes")) + category = models.ForeignKey( + TransactionCategory, + on_delete=models.SET_NULL, + verbose_name=_("Category"), + blank=True, + null=True, + ) + tags = models.ManyToManyField( + TransactionTag, + verbose_name=_("Tags"), + blank=True, + ) + entities = models.ManyToManyField( + TransactionEntity, + verbose_name=_("Entities"), + blank=True, + related_name="quick_transactions", + ) + + internal_note = models.TextField(blank=True, verbose_name=_("Internal Note")) + internal_id = models.TextField( + blank=True, null=True, unique=True, verbose_name=_("Internal ID") + ) + + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + objects = OwnedObjectManager() + all_objects = models.Manager() # Unfiltered manager + + class Meta: + verbose_name = _("Quick Transaction") + verbose_name_plural = _("Quick Transactions") + unique_together = ("name", "owner") + db_table = "quick_transactions" + default_manager_name = "objects" + + def save(self, *args, **kwargs): + self.amount = truncate_decimal( + value=self.amount, decimal_places=self.account.currency.decimal_places + ) + + self.full_clean() + super().save(*args, **kwargs) diff --git a/app/apps/transactions/urls.py b/app/apps/transactions/urls.py index d1a8fac..b808872 100644 --- a/app/apps/transactions/urls.py +++ b/app/apps/transactions/urls.py @@ -307,4 +307,39 @@ urlpatterns = [ views.recurring_transaction_finish, name="recurring_transaction_finish", ), + path( + "quick-transactions/", + views.quick_transactions_index, + name="quick_transactions_index", + ), + path( + "quick-transactions/list/", + views.quick_transactions_list, + name="quick_transactions_list", + ), + path( + "quick-transactions/add/", + views.quick_transaction_add, + name="quick_transaction_add", + ), + path( + "quick-transactions//edit/", + views.quick_transaction_edit, + name="quick_transaction_edit", + ), + path( + "quick-transactions//delete/", + views.quick_transaction_delete, + name="quick_transaction_delete", + ), + path( + "quick-transactions/create-menu/", + views.quick_transactions_create_menu, + name="quick_transactions_create_menu", + ), + path( + "quick-transactions//create/", + views.quick_transaction_add_as_transaction, + name="quick_transaction_add_as_transaction", + ), ] diff --git a/app/apps/transactions/views/__init__.py b/app/apps/transactions/views/__init__.py index fa20bc8..b784666 100644 --- a/app/apps/transactions/views/__init__.py +++ b/app/apps/transactions/views/__init__.py @@ -5,3 +5,4 @@ from .categories import * from .actions import * from .installment_plans import * from .recurring_transactions import * +from .quick_transactions import * diff --git a/app/apps/transactions/views/quick_transactions.py b/app/apps/transactions/views/quick_transactions.py new file mode 100644 index 0000000..26deec7 --- /dev/null +++ b/app/apps/transactions/views/quick_transactions.py @@ -0,0 +1,152 @@ +from django.contrib import messages +from django.contrib.auth.decorators import login_required +from django.forms import model_to_dict +from django.http import HttpResponse +from django.shortcuts import render, get_object_or_404 +from django.utils import timezone +from django.utils.translation import gettext_lazy as _ +from django.views.decorators.http import require_http_methods + +from apps.common.decorators.htmx import only_htmx +from apps.transactions.forms import QuickTransactionForm +from apps.transactions.models import QuickTransaction +from apps.transactions.models import Transaction + + +@login_required +@require_http_methods(["GET"]) +def quick_transactions_index(request): + return render( + request, + "quick_transactions/pages/index.html", + ) + + +@only_htmx +@login_required +@require_http_methods(["GET"]) +def quick_transactions_list(request): + quick_transactions = QuickTransaction.objects.all().order_by("name") + return render( + request, + "quick_transactions/fragments/list.html", + context={"quick_transactions": quick_transactions}, + ) + + +@only_htmx +@login_required +@require_http_methods(["GET", "POST"]) +def quick_transaction_add(request): + if request.method == "POST": + form = QuickTransactionForm(request.POST) + if form.is_valid(): + form.save() + messages.success(request, _("Item added successfully")) + + return HttpResponse( + status=204, + headers={ + "HX-Trigger": "updated, hide_offcanvas", + }, + ) + else: + form = QuickTransactionForm() + + return render( + request, + "quick_transactions/fragments/add.html", + {"form": form}, + ) + + +@only_htmx +@login_required +@require_http_methods(["GET", "POST"]) +def quick_transaction_edit(request, quick_transaction_id): + quick_transaction = get_object_or_404(QuickTransaction, id=quick_transaction_id) + + if request.method == "POST": + form = QuickTransactionForm(request.POST, instance=quick_transaction) + if form.is_valid(): + form.save() + messages.success(request, _("Item updated successfully")) + + return HttpResponse( + status=204, + headers={ + "HX-Trigger": "updated, hide_offcanvas", + }, + ) + else: + form = QuickTransactionForm(instance=quick_transaction) + + return render( + request, + "quick_transactions/fragments/edit.html", + {"form": form, "quick_transaction": quick_transaction}, + ) + + +@only_htmx +@login_required +@require_http_methods(["DELETE"]) +def quick_transaction_delete(request, quick_transaction_id): + quick_transaction = get_object_or_404(QuickTransaction, id=quick_transaction_id) + + quick_transaction.delete() + + messages.success(request, _("Item deleted successfully")) + + return HttpResponse( + status=204, + headers={ + "HX-Trigger": "updated, hide_offcanvas", + }, + ) + + +@only_htmx +@login_required +@require_http_methods(["GET"]) +def quick_transactions_create_menu(request): + quick_transactions = QuickTransaction.objects.all().order_by("name") + return render( + request, + "quick_transactions/fragments/create_menu.html", + context={"quick_transactions": quick_transactions}, + ) + + +@only_htmx +@login_required +@require_http_methods(["GET"]) +def quick_transaction_add_as_transaction(request, quick_transaction_id): + quick_transaction: QuickTransaction = get_object_or_404( + QuickTransaction, id=quick_transaction_id + ) + today = timezone.localdate(timezone.now()) + + quick_transaction_data = model_to_dict( + quick_transaction, + exclude=["id", "name", "owner", "account", "category", "tags", "entities"], + ) + + new_transaction = Transaction(**quick_transaction_data) + new_transaction.account = quick_transaction.account + new_transaction.category = quick_transaction.category + + new_transaction.date = today + new_transaction.reference_date = today.replace(day=1) + new_transaction.save() + new_transaction.tags.set(quick_transaction.tags.all()) + new_transaction.entities.set(quick_transaction.entities.all()) + + messages.success(request, _("Transaction added successfully")) + + return HttpResponse( + status=204, + headers={ + "HX-Trigger": "updated, hide_offcanvas", + }, + ) diff --git a/app/apps/users/migrations/0021_alter_usersettings_timezone.py b/app/apps/users/migrations/0021_alter_usersettings_timezone.py index 7a764d9..d8c1dc2 100644 --- a/app/apps/users/migrations/0021_alter_usersettings_timezone.py +++ b/app/apps/users/migrations/0021_alter_usersettings_timezone.py @@ -1,4 +1,5 @@ -# Generated by Django 5.1.11 on 2025-06-16 02:28 +# Generated by Django 5.1.11 on 2025-06-20 03:57 + from django.db import migrations, models diff --git a/app/locale/de/LC_MESSAGES/django.po b/app/locale/de/LC_MESSAGES/django.po index fef1cf8..42ad18d 100644 --- a/app/locale/de/LC_MESSAGES/django.po +++ b/app/locale/de/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-05-11 15:47+0000\n" +"POT-Creation-Date: 2025-06-20 05:02+0000\n" "PO-Revision-Date: 2025-05-23 17:16+0000\n" "Last-Translator: JHoh \n" "Language-Team: German \n" "Language-Team: LANGUAGE \n" @@ -26,11 +26,12 @@ msgstr "" #: apps/currencies/forms.py:53 apps/currencies/forms.py:91 #: apps/currencies/forms.py:142 apps/dca/forms.py:49 apps/dca/forms.py:224 #: apps/import_app/forms.py:34 apps/rules/forms.py:51 apps/rules/forms.py:93 -#: apps/rules/forms.py:365 apps/transactions/forms.py:203 -#: apps/transactions/forms.py:281 apps/transactions/forms.py:641 -#: apps/transactions/forms.py:684 apps/transactions/forms.py:716 -#: apps/transactions/forms.py:751 apps/transactions/forms.py:903 -#: apps/users/forms.py:210 apps/users/forms.py:372 +#: apps/rules/forms.py:365 apps/transactions/forms.py:204 +#: apps/transactions/forms.py:369 apps/transactions/forms.py:416 +#: apps/transactions/forms.py:776 apps/transactions/forms.py:819 +#: apps/transactions/forms.py:851 apps/transactions/forms.py:886 +#: apps/transactions/forms.py:1038 apps/users/forms.py:210 +#: apps/users/forms.py:372 msgid "Update" msgstr "" @@ -39,11 +40,12 @@ msgstr "" #: apps/currencies/forms.py:99 apps/currencies/forms.py:150 #: apps/dca/forms.py:57 apps/dca/forms.py:232 apps/import_app/forms.py:42 #: apps/rules/forms.py:59 apps/rules/forms.py:101 apps/rules/forms.py:373 -#: apps/transactions/forms.py:188 apps/transactions/forms.py:212 -#: apps/transactions/forms.py:649 apps/transactions/forms.py:692 -#: apps/transactions/forms.py:724 apps/transactions/forms.py:759 -#: apps/transactions/forms.py:911 apps/users/forms.py:218 -#: apps/users/forms.py:380 templates/account_groups/fragments/list.html:9 +#: apps/transactions/forms.py:189 apps/transactions/forms.py:213 +#: apps/transactions/forms.py:378 apps/transactions/forms.py:784 +#: apps/transactions/forms.py:827 apps/transactions/forms.py:859 +#: apps/transactions/forms.py:894 apps/transactions/forms.py:1046 +#: apps/users/forms.py:218 apps/users/forms.py:380 +#: 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 @@ -56,6 +58,7 @@ msgstr "" #: templates/import_app/fragments/profiles/list.html:10 #: templates/installment_plans/fragments/list.html:9 #: templates/mini_tools/unit_price_calculator.html:162 +#: templates/quick_transactions/pages/index.html:15 #: templates/recurring_transactions/fragments/list.html:9 #: templates/rules/fragments/list.html:9 templates/tags/fragments/list.html:9 #: templates/users/fragments/list.html:10 @@ -73,10 +76,11 @@ msgstr "" #: apps/accounts/forms.py:121 apps/dca/forms.py:85 apps/dca/forms.py:92 #: apps/insights/forms.py:118 apps/rules/forms.py:174 apps/rules/forms.py:189 #: apps/rules/models.py:38 apps/rules/models.py:286 -#: apps/transactions/forms.py:41 apps/transactions/forms.py:315 -#: apps/transactions/forms.py:322 apps/transactions/forms.py:522 -#: apps/transactions/forms.py:783 apps/transactions/models.py:312 -#: apps/transactions/models.py:495 apps/transactions/models.py:695 +#: apps/transactions/forms.py:42 apps/transactions/forms.py:256 +#: apps/transactions/forms.py:450 apps/transactions/forms.py:457 +#: apps/transactions/forms.py:657 apps/transactions/forms.py:918 +#: apps/transactions/models.py:317 apps/transactions/models.py:500 +#: apps/transactions/models.py:700 apps/transactions/models.py:936 #: templates/insights/fragments/category_overview/index.html:63 #: templates/insights/fragments/category_overview/index.html:420 msgid "Category" @@ -86,11 +90,12 @@ msgstr "" #: apps/export_app/forms.py:44 apps/export_app/forms.py:135 #: apps/rules/forms.py:177 apps/rules/forms.py:186 apps/rules/models.py:39 #: apps/rules/models.py:290 apps/transactions/filters.py:74 -#: apps/transactions/forms.py:49 apps/transactions/forms.py:331 -#: apps/transactions/forms.py:339 apps/transactions/forms.py:515 -#: apps/transactions/forms.py:776 apps/transactions/models.py:318 -#: apps/transactions/models.py:497 apps/transactions/models.py:699 -#: templates/includes/navbar.html:108 +#: apps/transactions/forms.py:50 apps/transactions/forms.py:264 +#: apps/transactions/forms.py:466 apps/transactions/forms.py:474 +#: apps/transactions/forms.py:650 apps/transactions/forms.py:911 +#: apps/transactions/models.py:323 apps/transactions/models.py:502 +#: apps/transactions/models.py:704 apps/transactions/models.py:942 +#: templates/includes/navbar.html:110 #: templates/insights/fragments/category_overview/index.html:35 #: templates/tags/fragments/list.html:5 templates/tags/pages/index.html:4 msgid "Tags" @@ -98,8 +103,8 @@ msgstr "" #: apps/accounts/models.py:12 apps/accounts/models.py:29 apps/dca/models.py:13 #: apps/import_app/models.py:14 apps/rules/models.py:13 -#: apps/transactions/models.py:205 apps/transactions/models.py:230 -#: apps/transactions/models.py:254 +#: apps/transactions/models.py:210 apps/transactions/models.py:235 +#: apps/transactions/models.py:259 apps/transactions/models.py:905 #: templates/account_groups/fragments/list.html:25 #: templates/accounts/fragments/list.html:25 #: templates/categories/fragments/table.html:16 @@ -108,6 +113,7 @@ msgstr "" #: templates/exchange_rates_services/fragments/list.html:32 #: templates/import_app/fragments/profiles/list.html:36 #: templates/installment_plans/fragments/table.html:16 +#: templates/quick_transactions/fragments/list.html:13 #: templates/recurring_transactions/fragments/table.html:18 #: templates/rules/fragments/list.html:26 #: templates/tags/fragments/table.html:16 @@ -121,7 +127,7 @@ msgstr "" #: apps/accounts/models.py:19 templates/account_groups/fragments/list.html:5 #: templates/account_groups/pages/index.html:4 -#: templates/includes/navbar.html:118 +#: templates/includes/navbar.html:120 msgid "Account Groups" msgstr "" @@ -161,17 +167,18 @@ msgstr "" #: apps/accounts/models.py:70 apps/rules/forms.py:166 apps/rules/forms.py:179 #: apps/rules/models.py:30 apps/rules/models.py:242 -#: apps/transactions/forms.py:61 apps/transactions/forms.py:507 -#: apps/transactions/forms.py:768 apps/transactions/models.py:285 -#: apps/transactions/models.py:455 apps/transactions/models.py:677 +#: apps/transactions/forms.py:62 apps/transactions/forms.py:276 +#: apps/transactions/forms.py:642 apps/transactions/forms.py:903 +#: apps/transactions/models.py:290 apps/transactions/models.py:460 +#: apps/transactions/models.py:682 apps/transactions/models.py:911 msgid "Account" msgstr "" #: apps/accounts/models.py:71 apps/export_app/forms.py:20 #: apps/export_app/forms.py:132 apps/transactions/filters.py:53 #: templates/accounts/fragments/list.html:5 -#: templates/accounts/pages/index.html:4 templates/includes/navbar.html:114 -#: templates/includes/navbar.html:116 +#: templates/accounts/pages/index.html:4 templates/includes/navbar.html:116 +#: templates/includes/navbar.html:118 #: templates/monthly_overview/pages/overview.html:94 #: templates/transactions/fragments/summary.html:12 #: templates/transactions/pages/transactions.html:72 @@ -454,8 +461,8 @@ msgstr "" #: apps/currencies/forms.py:69 apps/dca/models.py:158 apps/rules/forms.py:169 #: apps/rules/forms.py:182 apps/rules/models.py:33 apps/rules/models.py:254 -#: apps/transactions/forms.py:65 apps/transactions/forms.py:343 -#: apps/transactions/models.py:295 +#: apps/transactions/forms.py:66 apps/transactions/forms.py:478 +#: apps/transactions/models.py:300 #: templates/dca/fragments/strategy/details.html:52 #: templates/exchange_rates/fragments/table.html:10 #: templates/exchange_rates_services/fragments/table.html:10 @@ -477,8 +484,8 @@ msgstr "" #: apps/currencies/models.py:40 apps/export_app/forms.py:26 #: apps/export_app/forms.py:133 apps/transactions/filters.py:60 #: templates/currencies/fragments/list.html:5 -#: templates/currencies/pages/index.html:4 templates/includes/navbar.html:122 -#: templates/includes/navbar.html:124 +#: templates/currencies/pages/index.html:4 templates/includes/navbar.html:124 +#: templates/includes/navbar.html:126 #: templates/monthly_overview/pages/overview.html:81 #: templates/transactions/fragments/summary.html:8 #: templates/transactions/pages/transactions.html:59 @@ -508,7 +515,7 @@ msgstr "" #: apps/currencies/models.py:75 apps/export_app/forms.py:68 #: apps/export_app/forms.py:145 templates/exchange_rates/fragments/list.html:6 #: templates/exchange_rates/pages/index.html:4 -#: templates/includes/navbar.html:126 +#: templates/includes/navbar.html:128 msgid "Exchange Rates" msgstr "" @@ -536,8 +543,8 @@ msgstr "" msgid "Service Type" msgstr "" -#: apps/currencies/models.py:110 apps/transactions/models.py:209 -#: apps/transactions/models.py:233 apps/transactions/models.py:257 +#: apps/currencies/models.py:110 apps/transactions/models.py:214 +#: apps/transactions/models.py:238 apps/transactions/models.py:262 #: templates/categories/fragments/list.html:21 #: templates/entities/fragments/list.html:21 #: templates/recurring_transactions/fragments/list.html:21 @@ -657,11 +664,11 @@ msgstr "" msgid "Create transaction" msgstr "" -#: apps/dca/forms.py:70 apps/transactions/forms.py:290 +#: apps/dca/forms.py:70 apps/transactions/forms.py:425 msgid "From Account" msgstr "" -#: apps/dca/forms.py:76 apps/transactions/forms.py:295 +#: apps/dca/forms.py:76 apps/transactions/forms.py:430 msgid "To Account" msgstr "" @@ -686,7 +693,7 @@ msgstr "" msgid "You must provide an account." msgstr "" -#: apps/dca/forms.py:312 apps/transactions/forms.py:457 +#: apps/dca/forms.py:312 apps/transactions/forms.py:592 msgid "From and To accounts must be different." msgstr "" @@ -705,8 +712,9 @@ msgstr "" #: apps/dca/models.py:26 apps/dca/models.py:181 apps/rules/forms.py:173 #: apps/rules/forms.py:188 apps/rules/models.py:37 apps/rules/models.py:270 -#: apps/transactions/forms.py:359 apps/transactions/models.py:308 -#: apps/transactions/models.py:504 apps/transactions/models.py:705 +#: apps/transactions/forms.py:494 apps/transactions/models.py:313 +#: apps/transactions/models.py:509 apps/transactions/models.py:710 +#: apps/transactions/models.py:932 msgid "Notes" msgstr "" @@ -763,14 +771,14 @@ msgid "Entry deleted successfully" msgstr "" #: apps/export_app/forms.py:14 apps/export_app/forms.py:131 -#: templates/includes/navbar.html:147 templates/users/fragments/list.html:6 +#: templates/includes/navbar.html:149 templates/users/fragments/list.html:6 #: templates/users/pages/index.html:4 msgid "Users" msgstr "" #: apps/export_app/forms.py:32 apps/export_app/forms.py:137 -#: apps/transactions/models.py:369 templates/includes/navbar.html:57 -#: templates/includes/navbar.html:104 +#: apps/transactions/models.py:374 templates/includes/navbar.html:57 +#: templates/includes/navbar.html:106 #: templates/recurring_transactions/fragments/list_transactions.html:5 #: templates/recurring_transactions/fragments/table.html:37 #: templates/transactions/pages/transactions.html:5 @@ -779,30 +787,31 @@ msgstr "" #: apps/export_app/forms.py:38 apps/export_app/forms.py:134 #: apps/transactions/filters.py:67 templates/categories/fragments/list.html:5 -#: templates/categories/pages/index.html:4 templates/includes/navbar.html:106 +#: templates/categories/pages/index.html:4 templates/includes/navbar.html:108 msgid "Categories" msgstr "" #: apps/export_app/forms.py:50 apps/export_app/forms.py:136 #: apps/rules/forms.py:178 apps/rules/forms.py:187 apps/rules/models.py:40 #: apps/rules/models.py:282 apps/transactions/filters.py:81 -#: apps/transactions/forms.py:57 apps/transactions/forms.py:530 -#: apps/transactions/forms.py:791 apps/transactions/models.py:268 -#: apps/transactions/models.py:323 apps/transactions/models.py:500 -#: apps/transactions/models.py:702 templates/entities/fragments/list.html:5 -#: templates/entities/pages/index.html:4 templates/includes/navbar.html:110 +#: apps/transactions/forms.py:58 apps/transactions/forms.py:272 +#: apps/transactions/forms.py:665 apps/transactions/forms.py:926 +#: apps/transactions/models.py:273 apps/transactions/models.py:328 +#: apps/transactions/models.py:505 apps/transactions/models.py:707 +#: apps/transactions/models.py:947 templates/entities/fragments/list.html:5 +#: templates/entities/pages/index.html:4 templates/includes/navbar.html:112 msgid "Entities" msgstr "" #: apps/export_app/forms.py:56 apps/export_app/forms.py:140 -#: apps/transactions/models.py:739 templates/includes/navbar.html:74 +#: apps/transactions/models.py:744 templates/includes/navbar.html:76 #: templates/recurring_transactions/fragments/list.html:5 #: templates/recurring_transactions/pages/index.html:4 msgid "Recurring Transactions" msgstr "" #: apps/export_app/forms.py:62 apps/export_app/forms.py:138 -#: apps/transactions/models.py:518 templates/includes/navbar.html:72 +#: apps/transactions/models.py:523 templates/includes/navbar.html:74 #: templates/installment_plans/fragments/list.html:5 #: templates/installment_plans/pages/index.html:4 msgid "Installment Plans" @@ -811,16 +820,16 @@ msgstr "" #: apps/export_app/forms.py:74 apps/export_app/forms.py:143 #: templates/exchange_rates_services/fragments/list.html:6 #: templates/exchange_rates_services/pages/index.html:4 -#: templates/includes/navbar.html:140 +#: templates/includes/navbar.html:142 msgid "Automatic Exchange Rates" msgstr "" -#: apps/export_app/forms.py:80 templates/includes/navbar.html:132 +#: apps/export_app/forms.py:80 templates/includes/navbar.html:134 #: templates/rules/fragments/list.html:5 templates/rules/pages/index.html:4 msgid "Rules" msgstr "" -#: apps/export_app/forms.py:86 templates/cotton/transaction/item.html:56 +#: apps/export_app/forms.py:86 templates/cotton/transaction/item.html:57 msgid "DCA" msgstr "" @@ -855,7 +864,7 @@ msgstr "" msgid "Update or create transaction actions" msgstr "" -#: apps/export_app/forms.py:185 templates/cotton/transaction/item.html:158 +#: apps/export_app/forms.py:185 templates/cotton/transaction/item.html:159 #: templates/cotton/ui/deleted_transactions_action_bar.html:47 #: templates/export_app/fragments/restore.html:5 #: templates/export_app/pages/index.html:24 @@ -885,7 +894,7 @@ msgstr "" #: apps/import_app/forms.py:61 #: templates/import_app/fragments/profiles/list.html:62 -#: templates/includes/navbar.html:134 +#: templates/includes/navbar.html:136 msgid "Import" msgstr "" @@ -1039,48 +1048,52 @@ msgid "Operator" msgstr "" #: apps/rules/forms.py:167 apps/rules/forms.py:180 apps/rules/models.py:31 -#: apps/rules/models.py:246 apps/transactions/models.py:292 -#: apps/transactions/models.py:460 apps/transactions/models.py:683 +#: apps/rules/models.py:246 apps/transactions/models.py:297 +#: apps/transactions/models.py:465 apps/transactions/models.py:688 +#: apps/transactions/models.py:918 msgid "Type" msgstr "" #: apps/rules/forms.py:168 apps/rules/forms.py:181 apps/rules/models.py:32 #: apps/rules/models.py:250 apps/transactions/filters.py:23 -#: apps/transactions/models.py:294 templates/cotton/transaction/item.html:21 -#: templates/cotton/transaction/item.html:31 +#: apps/transactions/models.py:299 apps/transactions/models.py:920 +#: templates/cotton/transaction/item.html:22 +#: templates/cotton/transaction/item.html:32 #: templates/transactions/widgets/paid_toggle_button.html:12 #: templates/transactions/widgets/unselectable_paid_toggle_button.html:16 msgid "Paid" msgstr "" #: apps/rules/forms.py:170 apps/rules/forms.py:183 apps/rules/models.py:34 -#: apps/rules/models.py:258 apps/transactions/forms.py:69 -#: apps/transactions/forms.py:346 apps/transactions/forms.py:536 -#: apps/transactions/models.py:296 apps/transactions/models.py:478 -#: apps/transactions/models.py:707 +#: apps/rules/models.py:258 apps/transactions/forms.py:70 +#: apps/transactions/forms.py:481 apps/transactions/forms.py:671 +#: apps/transactions/models.py:301 apps/transactions/models.py:483 +#: apps/transactions/models.py:712 msgid "Reference Date" msgstr "" #: apps/rules/forms.py:171 apps/rules/forms.py:184 apps/rules/models.py:35 -#: apps/rules/models.py:262 apps/transactions/models.py:301 -#: apps/transactions/models.py:688 templates/insights/fragments/sankey.html:95 +#: apps/rules/models.py:262 apps/transactions/models.py:306 +#: apps/transactions/models.py:693 apps/transactions/models.py:925 +#: templates/insights/fragments/sankey.html:95 msgid "Amount" msgstr "" #: apps/rules/forms.py:172 apps/rules/forms.py:185 apps/rules/models.py:14 #: apps/rules/models.py:36 apps/rules/models.py:266 -#: apps/transactions/forms.py:350 apps/transactions/models.py:306 -#: apps/transactions/models.py:462 apps/transactions/models.py:691 +#: apps/transactions/forms.py:485 apps/transactions/models.py:311 +#: apps/transactions/models.py:467 apps/transactions/models.py:696 +#: apps/transactions/models.py:930 msgid "Description" msgstr "" #: apps/rules/forms.py:175 apps/rules/forms.py:190 apps/rules/models.py:274 -#: apps/transactions/models.py:345 +#: apps/transactions/models.py:350 apps/transactions/models.py:952 msgid "Internal Note" msgstr "" #: apps/rules/forms.py:176 apps/rules/forms.py:191 apps/rules/models.py:278 -#: apps/transactions/models.py:347 +#: apps/transactions/models.py:352 apps/transactions/models.py:954 msgid "Internal ID" msgstr "" @@ -1206,8 +1219,8 @@ msgstr "" msgid "Update or Create Transaction action deleted successfully" msgstr "" -#: apps/transactions/filters.py:24 templates/cotton/transaction/item.html:21 -#: templates/cotton/transaction/item.html:31 templates/includes/navbar.html:46 +#: apps/transactions/filters.py:24 templates/cotton/transaction/item.html:22 +#: templates/cotton/transaction/item.html:32 templates/includes/navbar.html:46 #: templates/insights/fragments/category_overview/index.html:46 #: templates/transactions/widgets/paid_toggle_button.html:8 #: templates/transactions/widgets/unselectable_paid_toggle_button.html:12 @@ -1242,231 +1255,244 @@ msgstr "" msgid "Amount max" msgstr "" -#: apps/transactions/forms.py:172 +#: apps/transactions/forms.py:173 msgid "More" msgstr "" -#: apps/transactions/forms.py:216 +#: apps/transactions/forms.py:217 msgid "Save and add similar" msgstr "" -#: apps/transactions/forms.py:221 +#: apps/transactions/forms.py:222 msgid "Save and add another" msgstr "" -#: apps/transactions/forms.py:302 +#: apps/transactions/forms.py:437 msgid "From Amount" msgstr "" -#: apps/transactions/forms.py:307 +#: apps/transactions/forms.py:442 msgid "To Amount" msgstr "" -#: apps/transactions/forms.py:424 +#: apps/transactions/forms.py:559 #: templates/cotton/ui/quick_transactions_buttons.html:40 +#: templates/cotton/ui/transactions_fab.html:44 msgid "Transfer" msgstr "" -#: apps/transactions/forms.py:670 +#: apps/transactions/forms.py:805 msgid "Tag name" msgstr "" -#: apps/transactions/forms.py:702 +#: apps/transactions/forms.py:837 msgid "Entity name" msgstr "" -#: apps/transactions/forms.py:734 +#: apps/transactions/forms.py:869 msgid "Category name" msgstr "" -#: apps/transactions/forms.py:736 +#: apps/transactions/forms.py:871 msgid "Muted categories won't count towards your monthly total" msgstr "" -#: apps/transactions/forms.py:922 +#: apps/transactions/forms.py:1057 msgid "End date should be after the start date" msgstr "" -#: apps/transactions/models.py:206 +#: apps/transactions/models.py:211 msgid "Mute" msgstr "" -#: apps/transactions/models.py:211 +#: apps/transactions/models.py:216 msgid "" "Deactivated categories won't be able to be selected when creating new " "transactions" msgstr "" -#: apps/transactions/models.py:219 +#: apps/transactions/models.py:224 msgid "Transaction Category" msgstr "" -#: apps/transactions/models.py:220 +#: apps/transactions/models.py:225 msgid "Transaction Categories" msgstr "" -#: apps/transactions/models.py:235 +#: apps/transactions/models.py:240 msgid "" "Deactivated tags won't be able to be selected when creating new transactions" msgstr "" -#: apps/transactions/models.py:243 apps/transactions/models.py:244 +#: apps/transactions/models.py:248 apps/transactions/models.py:249 msgid "Transaction Tags" msgstr "" -#: apps/transactions/models.py:259 +#: apps/transactions/models.py:264 msgid "" "Deactivated entities won't be able to be selected when creating new " "transactions" msgstr "" -#: apps/transactions/models.py:267 +#: apps/transactions/models.py:272 msgid "Entity" msgstr "" -#: apps/transactions/models.py:279 +#: apps/transactions/models.py:284 apps/transactions/models.py:898 #: templates/calendar_view/fragments/list.html:42 #: templates/calendar_view/fragments/list.html:44 #: templates/calendar_view/fragments/list.html:52 #: templates/calendar_view/fragments/list.html:54 #: templates/cotton/ui/quick_transactions_buttons.html:10 +#: templates/cotton/ui/transactions_fab.html:10 #: templates/insights/fragments/category_overview/index.html:64 #: templates/monthly_overview/fragments/monthly_summary.html:39 msgid "Income" msgstr "" -#: apps/transactions/models.py:280 +#: apps/transactions/models.py:285 apps/transactions/models.py:899 #: templates/calendar_view/fragments/list.html:46 #: templates/calendar_view/fragments/list.html:48 #: templates/calendar_view/fragments/list.html:56 #: templates/calendar_view/fragments/list.html:58 #: templates/cotton/ui/quick_transactions_buttons.html:18 +#: templates/cotton/ui/transactions_fab.html:19 #: templates/insights/fragments/category_overview/index.html:65 msgid "Expense" msgstr "" -#: apps/transactions/models.py:334 apps/transactions/models.py:517 +#: apps/transactions/models.py:339 apps/transactions/models.py:522 msgid "Installment Plan" msgstr "" -#: apps/transactions/models.py:343 apps/transactions/models.py:738 +#: apps/transactions/models.py:348 apps/transactions/models.py:743 msgid "Recurring Transaction" msgstr "" -#: apps/transactions/models.py:351 +#: apps/transactions/models.py:356 msgid "Deleted" msgstr "" -#: apps/transactions/models.py:356 +#: apps/transactions/models.py:361 msgid "Deleted At" msgstr "" -#: apps/transactions/models.py:368 +#: apps/transactions/models.py:373 msgid "Transaction" msgstr "" -#: apps/transactions/models.py:440 templates/tags/fragments/table.html:71 +#: apps/transactions/models.py:445 templates/tags/fragments/table.html:71 msgid "No tags" msgstr "" -#: apps/transactions/models.py:441 +#: apps/transactions/models.py:446 msgid "No category" msgstr "" -#: apps/transactions/models.py:443 +#: apps/transactions/models.py:448 msgid "No description" msgstr "" -#: apps/transactions/models.py:449 +#: apps/transactions/models.py:454 msgid "Yearly" msgstr "" -#: apps/transactions/models.py:450 apps/users/models.py:26 +#: apps/transactions/models.py:455 apps/users/models.py:26 #: templates/includes/navbar.html:26 msgid "Monthly" msgstr "" -#: apps/transactions/models.py:451 +#: apps/transactions/models.py:456 msgid "Weekly" msgstr "" -#: apps/transactions/models.py:452 +#: apps/transactions/models.py:457 msgid "Daily" msgstr "" -#: apps/transactions/models.py:465 +#: apps/transactions/models.py:470 msgid "Number of Installments" msgstr "" -#: apps/transactions/models.py:470 +#: apps/transactions/models.py:475 msgid "Installment Start" msgstr "" -#: apps/transactions/models.py:471 +#: apps/transactions/models.py:476 msgid "The installment number to start counting from" msgstr "" -#: apps/transactions/models.py:476 apps/transactions/models.py:711 +#: apps/transactions/models.py:481 apps/transactions/models.py:716 msgid "Start Date" msgstr "" -#: apps/transactions/models.py:480 apps/transactions/models.py:712 +#: apps/transactions/models.py:485 apps/transactions/models.py:717 msgid "End Date" msgstr "" -#: apps/transactions/models.py:485 +#: apps/transactions/models.py:490 msgid "Recurrence" msgstr "" -#: apps/transactions/models.py:488 +#: apps/transactions/models.py:493 msgid "Installment Amount" msgstr "" -#: apps/transactions/models.py:507 apps/transactions/models.py:728 +#: apps/transactions/models.py:512 apps/transactions/models.py:733 msgid "Add description to transactions" msgstr "" -#: apps/transactions/models.py:510 apps/transactions/models.py:731 +#: apps/transactions/models.py:515 apps/transactions/models.py:736 msgid "Add notes to transactions" msgstr "" -#: apps/transactions/models.py:670 +#: apps/transactions/models.py:675 msgid "day(s)" msgstr "" -#: apps/transactions/models.py:671 +#: apps/transactions/models.py:676 msgid "week(s)" msgstr "" -#: apps/transactions/models.py:672 +#: apps/transactions/models.py:677 msgid "month(s)" msgstr "" -#: apps/transactions/models.py:673 +#: apps/transactions/models.py:678 msgid "year(s)" msgstr "" -#: apps/transactions/models.py:675 +#: apps/transactions/models.py:680 #: templates/recurring_transactions/fragments/list.html:24 msgid "Paused" msgstr "" -#: apps/transactions/models.py:714 +#: apps/transactions/models.py:719 msgid "Recurrence Type" msgstr "" -#: apps/transactions/models.py:717 +#: apps/transactions/models.py:722 msgid "Recurrence Interval" msgstr "" -#: apps/transactions/models.py:721 +#: apps/transactions/models.py:726 msgid "Last Generated Date" msgstr "" -#: apps/transactions/models.py:724 +#: apps/transactions/models.py:729 msgid "Last Generated Reference Date" msgstr "" +#: apps/transactions/models.py:964 templates/cotton/ui/transactions_fab.html:59 +msgid "Quick Transaction" +msgstr "" + +#: apps/transactions/models.py:965 templates/includes/navbar.html:72 +#: templates/quick_transactions/pages/index.html:5 +#: templates/quick_transactions/pages/index.html:11 +msgid "Quick Transactions" +msgstr "" + #: apps/transactions/validators.py:8 #, python-format msgid "%(value)s has too many decimal places. Maximum is 30." @@ -1552,6 +1578,24 @@ msgstr "" msgid "Installment Plan deleted successfully" msgstr "" +#: apps/transactions/views/quick_transactions.py:45 apps/users/views.py:152 +msgid "Item added successfully" +msgstr "" + +#: apps/transactions/views/quick_transactions.py:73 apps/users/views.py:184 +msgid "Item updated successfully" +msgstr "" + +#: apps/transactions/views/quick_transactions.py:99 +msgid "Item deleted successfully" +msgstr "" + +#: apps/transactions/views/quick_transactions.py:145 +#: apps/transactions/views/transactions.py:52 +#: apps/transactions/views/transactions.py:148 +msgid "Transaction added successfully" +msgstr "" + #: apps/transactions/views/recurring_transactions.py:112 msgid "Recurring Transaction added successfully" msgstr "" @@ -1588,11 +1632,6 @@ msgstr "" msgid "Tag deleted successfully" msgstr "" -#: apps/transactions/views/transactions.py:52 -#: apps/transactions/views/transactions.py:148 -msgid "Transaction added successfully" -msgstr "" - #: apps/transactions/views/transactions.py:182 msgid "Transaction updated successfully" msgstr "" @@ -1798,14 +1837,6 @@ msgstr "" msgid "Your settings have been updated" msgstr "" -#: apps/users/views.py:152 -msgid "Item added successfully" -msgstr "" - -#: apps/users/views.py:184 -msgid "Item updated successfully" -msgstr "" - #: templates/account_groups/fragments/add.html:5 msgid "Add account group" msgstr "" @@ -1825,6 +1856,7 @@ msgstr "" #: templates/exchange_rates_services/fragments/table.html:19 #: templates/import_app/fragments/profiles/list.html:44 #: templates/installment_plans/fragments/table.html:23 +#: templates/quick_transactions/fragments/list.html:20 #: templates/recurring_transactions/fragments/table.html:25 #: templates/rules/fragments/list.html:33 #: templates/tags/fragments/table.html:23 @@ -1835,7 +1867,7 @@ msgstr "" #: templates/account_groups/fragments/list.html:36 #: templates/accounts/fragments/list.html:41 #: templates/categories/fragments/table.html:29 -#: templates/cotton/transaction/item.html:130 +#: templates/cotton/transaction/item.html:131 #: templates/cotton/ui/transactions_action_bar.html:49 #: templates/currencies/fragments/list.html:37 #: templates/dca/fragments/strategy/details.html:67 @@ -1846,6 +1878,7 @@ msgstr "" #: templates/exchange_rates_services/fragments/table.html:23 #: templates/import_app/fragments/profiles/list.html:48 #: templates/installment_plans/fragments/table.html:27 +#: templates/quick_transactions/fragments/list.html:24 #: templates/recurring_transactions/fragments/table.html:29 #: templates/rules/fragments/transaction_rule/view.html:23 #: templates/rules/fragments/transaction_rule/view.html:47 @@ -1858,8 +1891,8 @@ msgstr "" #: templates/account_groups/fragments/list.html:43 #: templates/accounts/fragments/list.html:48 #: templates/categories/fragments/table.html:36 -#: templates/cotton/transaction/item.html:145 -#: templates/cotton/transaction/item.html:164 +#: templates/cotton/transaction/item.html:146 +#: templates/cotton/transaction/item.html:165 #: templates/cotton/ui/deleted_transactions_action_bar.html:55 #: templates/cotton/ui/transactions_action_bar.html:86 #: templates/currencies/fragments/list.html:44 @@ -1873,6 +1906,7 @@ msgstr "" #: templates/import_app/fragments/runs/list.html:102 #: templates/installment_plans/fragments/table.html:56 #: templates/mini_tools/unit_price_calculator.html:18 +#: templates/quick_transactions/fragments/list.html:32 #: templates/recurring_transactions/fragments/table.html:91 #: templates/rules/fragments/list.html:44 #: templates/rules/fragments/transaction_rule/view.html:55 @@ -1884,8 +1918,8 @@ msgstr "" #: templates/account_groups/fragments/list.html:47 #: templates/accounts/fragments/list.html:52 #: templates/categories/fragments/table.html:41 -#: templates/cotton/transaction/item.html:149 -#: templates/cotton/transaction/item.html:168 +#: templates/cotton/transaction/item.html:150 +#: templates/cotton/transaction/item.html:169 #: templates/cotton/ui/deleted_transactions_action_bar.html:57 #: templates/cotton/ui/transactions_action_bar.html:88 #: templates/currencies/fragments/list.html:48 @@ -1899,6 +1933,7 @@ msgstr "" #: templates/import_app/fragments/runs/list.html:106 #: templates/installment_plans/fragments/table.html:48 #: templates/installment_plans/fragments/table.html:60 +#: templates/quick_transactions/fragments/list.html:37 #: templates/recurring_transactions/fragments/table.html:53 #: templates/recurring_transactions/fragments/table.html:67 #: templates/recurring_transactions/fragments/table.html:82 @@ -1913,8 +1948,8 @@ msgstr "" #: templates/account_groups/fragments/list.html:48 #: templates/accounts/fragments/list.html:53 #: templates/categories/fragments/table.html:42 -#: templates/cotton/transaction/item.html:150 -#: templates/cotton/transaction/item.html:169 +#: templates/cotton/transaction/item.html:151 +#: templates/cotton/transaction/item.html:170 #: templates/cotton/ui/deleted_transactions_action_bar.html:58 #: templates/cotton/ui/transactions_action_bar.html:89 #: templates/currencies/fragments/list.html:49 @@ -1935,8 +1970,8 @@ msgstr "" #: templates/account_groups/fragments/list.html:49 #: templates/accounts/fragments/list.html:54 #: templates/categories/fragments/table.html:43 -#: templates/cotton/transaction/item.html:151 -#: templates/cotton/transaction/item.html:170 +#: templates/cotton/transaction/item.html:152 +#: templates/cotton/transaction/item.html:171 #: templates/currencies/fragments/list.html:50 #: templates/dca/fragments/strategy/details.html:82 #: templates/dca/fragments/strategy/list.html:50 @@ -1947,6 +1982,7 @@ msgstr "" #: templates/import_app/fragments/profiles/list.html:75 #: templates/import_app/fragments/runs/list.html:108 #: templates/installment_plans/fragments/table.html:62 +#: templates/quick_transactions/fragments/list.html:39 #: templates/recurring_transactions/fragments/table.html:98 #: templates/rules/fragments/list.html:50 #: templates/rules/fragments/transaction_rule/view.html:61 @@ -2096,7 +2132,7 @@ msgstr "" msgid "Select" msgstr "" -#: templates/cotton/transaction/item.html:137 +#: templates/cotton/transaction/item.html:138 #: templates/cotton/ui/transactions_action_bar.html:78 msgid "Duplicate" msgstr "" @@ -2205,14 +2241,17 @@ msgid "Count" msgstr "" #: templates/cotton/ui/quick_transactions_buttons.html:25 +#: templates/cotton/ui/transactions_fab.html:27 msgid "Installment" msgstr "" #: templates/cotton/ui/quick_transactions_buttons.html:32 +#: templates/cotton/ui/transactions_fab.html:35 msgid "Recurring" msgstr "" #: templates/cotton/ui/quick_transactions_buttons.html:47 +#: templates/cotton/ui/transactions_fab.html:52 msgid "Balance" msgstr "" @@ -2378,8 +2417,8 @@ msgstr "" #: templates/exchange_rates/fragments/list.html:25 #: templates/includes/navbar.html:61 #: templates/installment_plans/fragments/list.html:21 -#: templates/yearly_overview/pages/overview_by_account.html:92 -#: templates/yearly_overview/pages/overview_by_currency.html:94 +#: templates/yearly_overview/pages/overview_by_account.html:94 +#: templates/yearly_overview/pages/overview_by_currency.html:96 msgid "All" msgstr "" @@ -2432,7 +2471,7 @@ msgstr "" msgid "No services configured" msgstr "" -#: templates/export_app/pages/index.html:4 templates/includes/navbar.html:137 +#: templates/export_app/pages/index.html:4 templates/includes/navbar.html:139 msgid "Export and Restore" msgstr "" @@ -2545,47 +2584,47 @@ msgstr "" msgid "Trash Can" msgstr "" -#: templates/includes/navbar.html:82 +#: templates/includes/navbar.html:84 msgid "Tools" msgstr "" -#: templates/includes/navbar.html:86 +#: templates/includes/navbar.html:88 msgid "Dollar Cost Average Tracker" msgstr "" -#: templates/includes/navbar.html:89 +#: templates/includes/navbar.html:91 #: templates/mini_tools/unit_price_calculator.html:5 #: templates/mini_tools/unit_price_calculator.html:10 msgid "Unit Price Calculator" msgstr "" -#: templates/includes/navbar.html:92 +#: templates/includes/navbar.html:94 #: templates/mini_tools/currency_converter/currency_converter.html:8 #: templates/mini_tools/currency_converter/currency_converter.html:15 msgid "Currency Converter" msgstr "" -#: templates/includes/navbar.html:101 +#: templates/includes/navbar.html:103 msgid "Management" msgstr "" -#: templates/includes/navbar.html:130 +#: templates/includes/navbar.html:132 msgid "Automation" msgstr "" -#: templates/includes/navbar.html:145 +#: templates/includes/navbar.html:147 msgid "Admin" msgstr "" -#: templates/includes/navbar.html:154 +#: templates/includes/navbar.html:156 msgid "Only use this if you know what you're doing" msgstr "" -#: templates/includes/navbar.html:155 +#: templates/includes/navbar.html:157 msgid "Django Admin" msgstr "" -#: templates/includes/navbar.html:165 +#: templates/includes/navbar.html:167 msgid "Calculator" msgstr "" @@ -2731,8 +2770,8 @@ msgid "Month" msgstr "" #: templates/insights/pages/index.html:40 -#: templates/yearly_overview/pages/overview_by_account.html:61 -#: templates/yearly_overview/pages/overview_by_currency.html:63 +#: templates/yearly_overview/pages/overview_by_account.html:62 +#: templates/yearly_overview/pages/overview_by_currency.html:64 msgid "Year" msgstr "" @@ -2924,6 +2963,24 @@ msgstr "" msgid "Evolution by account" msgstr "" +#: templates/quick_transactions/fragments/add.html:5 +#: templates/quick_transactions/fragments/create_menu.html:5 +msgid "Add quick transaction" +msgstr "" + +#: templates/quick_transactions/fragments/create_menu.html:13 +#: templates/quick_transactions/fragments/list.html:55 +msgid "Nothing to see here..." +msgstr "" + +#: templates/quick_transactions/fragments/edit.html:5 +msgid "Edit quick transaction" +msgstr "" + +#: templates/quick_transactions/fragments/list.html:38 +msgid "This will delete this item" +msgstr "" + #: templates/recurring_transactions/fragments/add.html:5 msgid "Add recurring transaction" msgstr "" diff --git a/app/locale/es/LC_MESSAGES/django.po b/app/locale/es/LC_MESSAGES/django.po index 9a609f2..61f2528 100644 --- a/app/locale/es/LC_MESSAGES/django.po +++ b/app/locale/es/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-05-11 15:47+0000\n" +"POT-Creation-Date: 2025-06-20 05:02+0000\n" "PO-Revision-Date: 2025-04-13 02:40+0000\n" "Last-Translator: Prefill add-on \n" "Language-Team: Spanish \n" "Language-Team: French \n" "Language-Team: Dutch \n" "Language-Team: Portuguese \n" "Language-Team: Portuguese (Brazil) \n" "Language-Team: Swedish \n" "Language-Team: Ukrainian -
-{# Date picker#} -
-
- +
+
+ {# Date picker#} +
+
+ +
+
+ {{ month|month_name }} {{ year }} +
+
+ + + +
-
- {{ month|month_name }} {{ year }} -
-
- - - + {# Action buttons#} +
+ {# #}
-{# Action buttons#} -
- +
+
-
-
-
-
+ {% endblock %} diff --git a/app/templates/cotton/components/fab.html b/app/templates/cotton/components/fab.html new file mode 100644 index 0000000..e25c177 --- /dev/null +++ b/app/templates/cotton/components/fab.html @@ -0,0 +1,33 @@ +
+
+ + + +
+
diff --git a/app/templates/cotton/components/fab_menu_button.html b/app/templates/cotton/components/fab_menu_button.html new file mode 100644 index 0000000..26e496b --- /dev/null +++ b/app/templates/cotton/components/fab_menu_button.html @@ -0,0 +1,11 @@ +{% load i18n %} +
+ +
diff --git a/app/templates/cotton/transaction/item.html b/app/templates/cotton/transaction/item.html index 7df49bd..3f9df66 100644 --- a/app/templates/cotton/transaction/item.html +++ b/app/templates/cotton/transaction/item.html @@ -15,7 +15,8 @@ _="on mouseover remove .tw-invisible from the first .transaction-actions in me end on mouseout add .tw-invisible to the first .transaction-actions in me end"> {# Monthly summary#}
@@ -174,8 +174,9 @@