from django.contrib.postgres.fields import DateTimeRangeField from django.db import models from django.utils.translation import gettext as _ from djmoney.models.fields import MoneyField class CreatedModifiedAbstract(models.Model): modified = models.DateTimeField(auto_now=True, verbose_name=_("modified")) created = models.DateTimeField(auto_now_add=True, verbose_name=_("created")) class Meta: abstract = True class Membership(CreatedModifiedAbstract): """ A user remains a member of an organization even though the subscription is unpaid or renewed. This just changes the status/permissions etc. of the membership, thus we need to track subscription creation, expiry, renewals etc. and ensure that the membership is modified accordingly. """ user = models.OneToOneField("auth.User", on_delete=models.PROTECT) def __str__(self): return _(f"{self.user.get_full_name()} is a member") class Meta: verbose_name = _("membership") verbose_name_plural = _("memberships") class SubscriptionType(CreatedModifiedAbstract): """ Properties of subscriptions are stored here. Should of course not be edited after subscriptions are created. """ name = models.CharField(verbose_name=_("name"), max_length=64) fee = MoneyField(max_digits=16, decimal_places=2) fee_vat = MoneyField(max_digits=16, decimal_places=2, default=0) class Meta: verbose_name = _("subscription type") verbose_name_plural = _("subscription types") class Subscription(CreatedModifiedAbstract): """ To not confuse other types of subscriptions, one can be a *subscribed* member, meaning that they are paying etc. A subscription does not track payment, this is done in the accounting app. """ subscription_type = models.ForeignKey( SubscriptionType, related_name="memberships", verbose_name=_("subscription type"), on_delete=models.PROTECT, ) user = models.ForeignKey("auth.User", on_delete=models.PROTECT) active = models.BooleanField( default=False, verbose_name=_("active"), help_text=_("Automatically set by payment system."), ) duration = DateTimeRangeField(help_text=_("The duration this subscription is for. ")) class Meta: verbose_name = _("subscription") verbose_name_plural = _("subscriptions")