diff --git a/tapir/accounts/forms.py b/tapir/accounts/forms.py index 6e631916c..ab8019f02 100644 --- a/tapir/accounts/forms.py +++ b/tapir/accounts/forms.py @@ -5,7 +5,7 @@ from django.utils.translation import gettext_lazy as _ from tapir import settings -from tapir.accounts.models import TapirUser +from tapir.accounts.models import TapirUser, CoPurchaser from tapir.core.mail_option import MailOption from tapir.core.services.mail_classes_service import MailClassesService from tapir.core.services.optional_mail_choices_service import OptionalMailChoicesService @@ -50,10 +50,6 @@ class Meta(TapirUserSelfUpdateForm.Meta): "postcode", "city", "preferred_language", - "co_purchaser", - "co_purchaser_mail", - "co_purchaser_2", - "co_purchaser_2_mail", ] + TapirUserSelfUpdateForm.Meta.fields widgets = TapirUserSelfUpdateForm.Meta.widgets | { @@ -61,33 +57,6 @@ class Meta(TapirUserSelfUpdateForm.Meta): "username": TextInput(attrs={"readonly": True}), } - def clean(self): - cleaned_data = super().clean() - - if ( - cleaned_data.get("co_purchaser_mail", "") != "" - and cleaned_data.get("co_purchaser", "") == "" - ): - raise ValidationError( - { - "co_purchaser_mail": _( - "If there is not co-purchaser then the co-purchaser-mail field must also be empty" - ) - } - ) - - if ( - cleaned_data.get("co_purchaser_2_mail", "") != "" - and cleaned_data.get("co_purchaser_2", "") == "" - ): - raise ValidationError( - { - "co_purchaser_2_mail": _( - "If there is not co-purchaser 2 then the co-purchaser-mail 2 field must also be empty" - ) - } - ) - class PasswordResetForm(auth_forms.PasswordResetForm): def get_users(self, email): @@ -176,3 +145,10 @@ def __init__(self, *args, **kwargs): tapir_user ) ) + + +class CoPurchaserForm(forms.ModelForm): + class Meta: + model = CoPurchaser + fields = ["first_name", "last_name", "email"] + widgets = {} diff --git a/tapir/accounts/migrations/0024_copurchaser.py b/tapir/accounts/migrations/0024_copurchaser.py new file mode 100644 index 000000000..da566d0f2 --- /dev/null +++ b/tapir/accounts/migrations/0024_copurchaser.py @@ -0,0 +1,49 @@ +# Generated by Django 5.2.13 on 2026-04-26 17:01 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ( + "accounts", + "0023_updatetapiruserlogentry_accounts_up_old_val_25b95f_gin_and_more", + ), + ] + + operations = [ + migrations.CreateModel( + name="CoPurchaser", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("first_name", models.CharField(blank=True, max_length=255)), + ("last_name", models.CharField(blank=True, max_length=255)), + ("email", models.EmailField(blank=True, max_length=254)), + ("order", models.PositiveIntegerField(default=0)), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="copurchaser", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "verbose_name": "Co-Purchaser", + "verbose_name_plural": "Co-Purchasers", + "ordering": ["order"], + }, + ), + ] diff --git a/tapir/accounts/migrations/0025_co_purchaser_model.py b/tapir/accounts/migrations/0025_co_purchaser_model.py new file mode 100644 index 000000000..edcb442b1 --- /dev/null +++ b/tapir/accounts/migrations/0025_co_purchaser_model.py @@ -0,0 +1,50 @@ +# Generated by Django 5.2.13 on 2026-04-26 17:02 + +from django.db import migrations + + +def split_name(full_name): + if not full_name: + return "", "" + parts = full_name.strip().split() + if len(parts) == 1: + return parts[0], "" + else: + return " ".join(parts[:-1]), parts[-1] + + +def migrate_co_purchasers(apps, schema_editor): + TapirUser = apps.get_model("accounts", "TapirUser") + CoPurchaser = apps.get_model("accounts", "CoPurchaser") + + for user in TapirUser.objects.all(): + + if user.co_purchaser: + first_name, last_name = split_name(user.co_purchaser) + CoPurchaser.objects.create( + user=user, + first_name=first_name, + last_name=last_name, + email=user.co_purchaser_mail, + order=0, + ) + if user.co_purchaser_2: + first_name, last_name = split_name(user.co_purchaser_2) + CoPurchaser.objects.create( + user=user, + first_name=first_name, + last_name=last_name, + email=user.co_purchaser_2_mail, + order=1, + ) + + +class Migration(migrations.Migration): + + dependencies = [ + ("accounts", "0024_copurchaser"), + ] + + operations = [ + migrations.RunPython(migrate_co_purchasers), + ] diff --git a/tapir/accounts/models.py b/tapir/accounts/models.py index 6a07900f2..1d08b87f0 100644 --- a/tapir/accounts/models.py +++ b/tapir/accounts/models.py @@ -305,3 +305,21 @@ class Meta: fields=["user", "mail_id"], name="user-mail-constraint" ) ] + + +class CoPurchaser(models.Model): + user = models.ForeignKey( + "TapirUser", on_delete=models.CASCADE, related_name="copurchaser" + ) + first_name = models.CharField(blank=True, max_length=255) + last_name = models.CharField(blank=True, max_length=255) + email = models.EmailField(blank=True, max_length=254) + order = models.PositiveIntegerField(default=0) + + class Meta: + verbose_name_plural = _("Co-Purchasers") + verbose_name = _("Co-Purchaser") + ordering = ["order"] + + def get_full_name(self): + return f"{self.first_name} {self.last_name}" diff --git a/tapir/accounts/templates/accounts/user_detail.html b/tapir/accounts/templates/accounts/user_detail.html index 27602e3fb..222104f94 100644 --- a/tapir/accounts/templates/accounts/user_detail.html +++ b/tapir/accounts/templates/accounts/user_detail.html @@ -153,7 +153,49 @@
{% translate "No co-purchasers registered." %}
+ {% endif %} + {% endwith %} +