diff --git a/app/apps/transactions/forms.py b/app/apps/transactions/forms.py index f6f9b70..04fafe8 100644 --- a/app/apps/transactions/forms.py +++ b/app/apps/transactions/forms.py @@ -5,6 +5,7 @@ from apps.common.fields.forms.dynamic_select import ( DynamicModelChoiceField, DynamicModelMultipleChoiceField, ) +from apps.common.middleware.thread_local import get_current_user from apps.common.widgets.crispy.daisyui import Switch from apps.common.widgets.crispy.submit import NoClassSubmit from apps.common.widgets.datepicker import AirDatePickerInput, AirMonthYearPickerInput @@ -116,6 +117,9 @@ class TransactionForm(forms.ModelForm): self.fields["account"].queryset = Account.objects.filter( is_archived=False, ) + user_settings = get_current_user().settings + if user_settings.default_account: + self.fields["account"].initial = user_settings.default_account self.fields["category"].queryset = TransactionCategory.objects.filter( active=True @@ -768,6 +772,9 @@ class InstallmentPlanForm(forms.ModelForm): ).distinct() else: self.fields["account"].queryset = Account.objects.filter(is_archived=False) + user_settings = get_current_user().settings + if user_settings.default_account: + self.fields["account"].initial = user_settings.default_account self.fields["category"].queryset = TransactionCategory.objects.filter( active=True @@ -1010,6 +1017,10 @@ class RecurringTransactionForm(forms.ModelForm): ).distinct() else: self.fields["account"].queryset = Account.objects.filter(is_archived=False) + + user_settings = get_current_user().settings + if user_settings.default_account: + self.fields["account"].initial = user_settings.default_account self.fields["category"].queryset = TransactionCategory.objects.filter( active=True diff --git a/app/apps/users/forms.py b/app/apps/users/forms.py index e48aaac..a2b06e9 100644 --- a/app/apps/users/forms.py +++ b/app/apps/users/forms.py @@ -1,6 +1,8 @@ from apps.common.middleware.thread_local import get_current_user from apps.common.widgets.crispy.submit import NoClassSubmit +from apps.common.widgets.tom_select import TomSelect from apps.users.models import UserSettings +from apps.accounts.models import Account from crispy_forms.bootstrap import ( FormActions, ) @@ -116,6 +118,15 @@ class UserSettingsForm(forms.ModelForm): label=_("Number Format"), ) + default_account = forms.ModelChoiceField( + queryset=Account.objects.filter( + is_archived=False, + ), + label=_("Default Account"), + widget=TomSelect(clear_button=False, group_by="group"), + required=False, + ) + class Meta: model = UserSettings fields = [ @@ -126,11 +137,19 @@ class UserSettingsForm(forms.ModelForm): "datetime_format", "number_format", "volume", + "default_account", ] + widgets = { + "default_account": TomSelect(clear_button=False, group_by="group"), + } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self.fields["default_account"].queryset = Account.objects.filter( + is_archived=False, + ) + self.helper = FormHelper() self.helper.form_tag = False self.helper.form_method = "post" @@ -143,6 +162,7 @@ class UserSettingsForm(forms.ModelForm): "number_format", HTML('
'), "start_page", + "default_account", HTML('
'), "volume", FormActions( diff --git a/app/apps/users/migrations/0024_usersettings_default_account.py b/app/apps/users/migrations/0024_usersettings_default_account.py new file mode 100644 index 0000000..0523c80 --- /dev/null +++ b/app/apps/users/migrations/0024_usersettings_default_account.py @@ -0,0 +1,25 @@ +# Generated by Django 5.2.9 on 2026-02-15 21:35 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("accounts", "0016_account_untracked_by"), + ("users", "0023_alter_usersettings_timezone"), + ] + + operations = [ + migrations.AddField( + model_name="usersettings", + name="default_account", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="accounts.account", + verbose_name="Default account", + ), + ), + ] diff --git a/app/apps/users/migrations/0025_alter_usersettings_default_account.py b/app/apps/users/migrations/0025_alter_usersettings_default_account.py new file mode 100644 index 0000000..d10bef2 --- /dev/null +++ b/app/apps/users/migrations/0025_alter_usersettings_default_account.py @@ -0,0 +1,20 @@ +# Generated by Django 5.2.9 on 2026-02-16 01:32 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0016_account_untracked_by'), + ('users', '0024_usersettings_default_account'), + ] + + operations = [ + migrations.AlterField( + model_name='usersettings', + name='default_account', + field=models.ForeignKey(blank=True, help_text='Selects the account by default when creating new transactions', null=True, on_delete=django.db.models.deletion.SET_NULL, to='accounts.account', verbose_name='Default account'), + ), + ] diff --git a/app/apps/users/models.py b/app/apps/users/models.py index 6f286c7..d1e4b32 100644 --- a/app/apps/users/models.py +++ b/app/apps/users/models.py @@ -510,6 +510,14 @@ class UserSettings(models.Model): default=StartPage.MONTHLY, verbose_name=_("Start page"), ) + default_account = models.ForeignKey( + "accounts.Account", + on_delete=models.SET_NULL, + verbose_name=_("Default account"), + help_text=_("Selects the account by default when creating new transactions"), + blank=True, + null=True, + ) def __str__(self): return f"{self.user.email}'s settings"