diff --git a/core/models.py b/core/models.py index 20cbeb4b..7a9d3a46 100644 --- a/core/models.py +++ b/core/models.py @@ -529,13 +529,15 @@ class User(AbstractBaseUser): return False @cached_property - def can_create_subscription(self): - from club.models import Club + def can_create_subscription(self) -> bool: + from club.models import Membership - for club in Club.objects.filter(id__in=settings.SITH_CAN_CREATE_SUBSCRIPTIONS): - if club in self.clubs_with_rights: - return True - return False + return ( + Membership.objects.board() + .ongoing() + .filter(club_id__in=settings.SITH_CAN_CREATE_SUBSCRIPTIONS) + .exists() + ) @cached_property def is_launderette_manager(self): diff --git a/core/static/bundled/htmx-index.js b/core/static/bundled/htmx-index.js index 56edea4a..e2a56605 100644 --- a/core/static/bundled/htmx-index.js +++ b/core/static/bundled/htmx-index.js @@ -1,3 +1,4 @@ +import "htmx-ext-response-targets/response-targets"; import htmx from "htmx.org"; Object.assign(window, { htmx }); diff --git a/galaxy/models.py b/galaxy/models.py index 9316aacf..4d12f832 100644 --- a/galaxy/models.py +++ b/galaxy/models.py @@ -406,7 +406,7 @@ class Galaxy(models.Model): cls.logger.debug(f"\t\t> Scaled distance: {value}") return int(value) - def rule(self, picture_count_threshold=10) -> None: + def rule(self, picture_count_threshold=-1) -> None: """Main function of the Galaxy. Iterate over all the rulable users to promote them to citizens. diff --git a/package-lock.json b/package-lock.json index 05418a69..cb6483bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "d3-force-3d": "^3.0.5", "easymde": "^2.18.0", "glob": "^11.0.0", + "htmx-ext-response-targets": "^2.0.1", "htmx.org": "^2.0.3", "jquery": "^3.7.1", "jquery-ui": "^1.14.0", @@ -4140,6 +4141,11 @@ "node": ">= 0.4" } }, + "node_modules/htmx-ext-response-targets": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/htmx-ext-response-targets/-/htmx-ext-response-targets-2.0.1.tgz", + "integrity": "sha512-uCMw098+0xcrs7UW/s8l8hqj5wfOaVnVV7286cS+TNMNguo8fQpi/PEaZuT4VUysIiRcjj4pcTkuaP6Q9iJ3XA==" + }, "node_modules/htmx.org": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-2.0.3.tgz", diff --git a/package.json b/package.json index 2ca46967..bb7a4160 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,9 @@ "keywords": [], "author": "", "license": "GPL-3.0-only", - "sideEffects": [".css"], + "sideEffects": [ + ".css" + ], "imports": { "#openapi": "./staticfiles/generated/openapi/index.ts", "#core:*": "./core/static/bundled/*", @@ -47,6 +49,7 @@ "easymde": "^2.18.0", "glob": "^11.0.0", "htmx.org": "^2.0.3", + "htmx-ext-response-targets": "^2.0.1", "jquery": "^3.7.1", "jquery-ui": "^1.14.0", "jquery.shorten": "^1.0.0", diff --git a/sas/widgets/select.py b/sas/widgets/select.py index 9f8676d3..1d124a27 100644 --- a/sas/widgets/select.py +++ b/sas/widgets/select.py @@ -1,9 +1,6 @@ from pydantic import TypeAdapter -from core.views.widgets.select import ( - AutoCompleteSelect, - AutoCompleteSelectMultiple, -) +from core.views.widgets.select import AutoCompleteSelect, AutoCompleteSelectMultiple from sas.models import Album from sas.schemas import AlbumSchema diff --git a/subscription/forms.py b/subscription/forms.py index f627a6b7..f830ad3d 100644 --- a/subscription/forms.py +++ b/subscription/forms.py @@ -5,7 +5,7 @@ from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ from core.models import User -from core.views.forms import SelectDate, SelectDateTime +from core.views.forms import SelectDateTime from core.views.widgets.select import AutoCompleteSelectUser from subscription.models import Subscription @@ -21,37 +21,15 @@ class SelectionDateForm(forms.Form): ) -class SubscriptionForm(forms.ModelForm): - class Meta: - model = Subscription - fields = ["member", "subscription_type", "payment_method", "location"] - widgets = {"member": AutoCompleteSelectUser} - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.fields["member"].required = False - self.fields |= forms.fields_for_model( - User, - fields=["first_name", "last_name", "email", "date_of_birth"], - widgets={"date_of_birth": SelectDate}, - ) - - def clean_member(self): - subscriber = self.cleaned_data.get("member") - if subscriber: - subscriber = User.objects.filter(id=subscriber.id).first() - return subscriber - +class SubscriptionNewUserForm(forms.Form): def clean(self): cleaned_data = super().clean() if ( - cleaned_data.get("member") is None - and "last_name" not in self.errors.as_data() + "last_name" not in self.errors.as_data() and "first_name" not in self.errors.as_data() and "email" not in self.errors.as_data() and "date_of_birth" not in self.errors.as_data() ): - self.errors.pop("member", None) if self.errors: return cleaned_data if User.objects.filter(email=cleaned_data.get("email")).first() is not None: @@ -70,19 +48,17 @@ class SubscriptionForm(forms.ModelForm): u.set_password(str(random.randrange(1000000, 10000000))) u.save() cleaned_data["member"] = u - elif cleaned_data.get("member") is not None: - self.errors.pop("last_name", None) - self.errors.pop("first_name", None) - self.errors.pop("email", None) - self.errors.pop("date_of_birth", None) - if cleaned_data.get("member") is None: - # This should be handled here, - # but it is done in the Subscription model's clean method - # TODO investigate why! - raise ValidationError( - _( - "You must either choose an existing " - "user or create a new one properly" - ) - ) - return cleaned_data + + +class SubscriptionForm(forms.ModelForm): + """Form to add a subscription to an existing user.""" + + template_name = "subscription/fragments/existing_user_form.html" + + class Meta: + model = Subscription + fields = ["member", "subscription_type", "payment_method", "location"] + widgets = {"member": AutoCompleteSelectUser} + + def clean_subscription_type(self): + raise ValidationError("ptdr non") diff --git a/subscription/templates/subscription/fragments/existing_user_form.html b/subscription/templates/subscription/fragments/existing_user_form.html new file mode 100644 index 00000000..fa64da9c --- /dev/null +++ b/subscription/templates/subscription/fragments/existing_user_form.html @@ -0,0 +1,12 @@ +{#
#} diff --git a/subscription/templates/subscription/fragments/new_user_form.jinja b/subscription/templates/subscription/fragments/new_user_form.jinja new file mode 100644 index 00000000..e69de29b diff --git a/subscription/templates/subscription/subscription.jinja b/subscription/templates/subscription/subscription.jinja index a26c7afc..3a47727f 100644 --- a/subscription/templates/subscription/subscription.jinja +++ b/subscription/templates/subscription/subscription.jinja @@ -4,59 +4,65 @@ {% trans %}New subscription{% endtrans %} {% endblock %} +{# The following statics are bundled with our autocomplete select. + However, if one tries to swap a form by another, then the urls in script-once + and link-once disappear. + So we give them here. + If the aforementioned bug is resolved, you can remove this. #} +{% block additional_js %} + +{% endblock %} +{% block additional_css %} + + +{% endblock %} + {% block content %}#} +{# {{ existing_user_form.first_name.errors }}#} +{# #} +{# {{ existing_user_form.first_name }}#} +{#
#} +{##} +{# {{ existing_user_form.last_name.errors }}#} +{# #} +{# {{ existing_user_form.last_name }}#} +{#
#} +{##} +{# {{ existing_user_form.email.errors }}#} +{# #} +{# {{ existing_user_form.email }}#} +{#
#} +{##} +{# {{ existing_user_form.date_of_birth.errors }}#} +{# #} +{# {{ existing_user_form.date_of_birth }}#} +{#
#} +{#