Compare commits

..

No commits in common. "5c5153adb6f381d9521afcd96805719f8f4808fa" and "3193cafe4b5d11e17f2cbe81582fe61e02f0654a" have entirely different histories.

3 changed files with 12 additions and 65 deletions

View file

@ -4,8 +4,6 @@ from django.conf import settings
from django.core.mail import send_mail
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils import timezone
from membership.models import Membership
from . import models
@ -21,19 +19,3 @@ def check_total_amount(sender: models.Payment, instance: models.Payment, **kwarg
settings.DEFAULT_FROM_EMAIL,
settings.ADMINS,
)
@receiver(post_save, sender=models.Payment)
def mark_order_paid(sender: models.Payment, instance: models.Payment, **kwargs: dict) -> None: # noqa: ARG001
"""Mark an order as paid when payment is received."""
instance.order.is_paid = True
instance.order.save()
@receiver(post_save, sender=models.Payment)
def activate_membership(sender: models.Order, instance: models.Order, **kwargs: dict) -> None: # noqa: ARG001
"""Mark a membership as activated when its order is marked as paid."""
if instance.is_paid:
Membership.objects.filter(order=instance, activated=False, activated_on=None).update(
activated=True, activated_on=timezone.now()
)

View file

@ -2,15 +2,10 @@
from collections.abc import Callable
from accounting.models import Account
from accounting.models import Order
from accounting.models import OrderProduct
from django.contrib import admin
from django.contrib import messages
from django.contrib.admin import ModelAdmin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from django.db import transaction
from django.db.models import QuerySet
from django.http import HttpRequest
from django.http import HttpResponse
@ -52,34 +47,12 @@ def decorate_ensure_membership_type_exists(membership_type: models.MembershipTyp
return admin_action
@transaction.atomic
def ensure_membership_type_exists(
request: HttpRequest,
queryset: QuerySet,
membership_type: models.MembershipType,
request: HttpRequest, # noqa: ARG001
queryset: QuerySet, # noqa: ARG001
membership_type: models.MembershipType, # noqa: ARG001
) -> HttpResponse:
"""Inner function that ensures that a membership exists for a given queryset of Member objects."""
for member in queryset:
if member.memberships.filter(membership_type=membership_type).current():
messages.info(request, f"{member} already has a membership {membership_type}")
else:
# Get the default account of the member. We don't really know what to do if a person owns multiple accounts.
account, __ = Account.objects.get_or_create(owner=member)
# Create an Order for the products in the membership
order = Order.objects.create(member=member, account=account)
# Add stuff to the order
for product in membership_type.products.all():
OrderProduct.objects.create(order=order, product=product, price=product.price, vat=product.vat)
# Create the Membership
models.Membership.objects.create(
membership_type=membership_type,
user=member,
period=models.SubscriptionPeriod.objects.current(),
order=order,
)
# Associate the order with that membership
messages.success(request, f"{member} has ordered a '{membership_type}' (unpaid)")
@admin.register(models.Member)
@ -92,18 +65,11 @@ class MemberAdmin(UserAdmin):
def get_actions(self, request: HttpRequest) -> dict:
"""Populate actions with dynamic data (MembershipType)."""
current_period = models.SubscriptionPeriod.objects.current()
super_dict = super().get_actions(request)
if current_period:
for i, mtype in enumerate(models.MembershipType.objects.filter(active=True)):
for mtype in models.MembershipType.objects.filter(active=True):
action_label = f"Ensure membership {mtype.name}, {current_period.period}, {mtype.total_including_vat}"
action_func = decorate_ensure_membership_type_exists(mtype, action_label)
# Django ModelAdmin uses the non-unique __name__ property, so we need to suffix it to make it unique
action_func.__name__ += f"_{i}"
self.actions.append(action_func)
return super_dict
self.actions.append(decorate_ensure_membership_type_exists(mtype, action_label))
return super().get_actions(request)
@admin.register(models.WaitingListEntry)

View file

@ -99,17 +99,16 @@ class Membership(CreatedModifiedAbstract):
"""Filter memberships for a given member."""
return self.filter(user=member)
def active(self) -> Self:
"""Get only activated, non-revoked memberships (may have expired so use also current())."""
return self.filter(activated=True, revoked=False)
def _current(self) -> Self:
"""Filter memberships for the current period."""
return self.filter(period__period__contains=timezone.now())
return self.filter(activated=True, revoked=False, period__period__contains=timezone.now())
def current(self) -> "Membership | None":
"""Get the current membership."""
return self._current().first()
try:
return self._current().get()
except self.model.DoesNotExist:
return None
def previous(self) -> list["Membership"]:
"""Get previous memberships."""
@ -120,7 +119,7 @@ class Membership(CreatedModifiedAbstract):
objects = QuerySet.as_manager()
user = models.ForeignKey("auth.User", on_delete=models.PROTECT, related_name="memberships")
user = models.ForeignKey("auth.User", on_delete=models.PROTECT)
membership_type = models.ForeignKey(
"membership.MembershipType",