from django.utils.translation import gettext_lazy as _ from django.db import models from django.utils import timezone from datetime import timedelta from userapp.models import ParadiseUser class SubscriptionPlan(models.Model): """订阅计划""" PLAN_CHOICES = ( ('monthly', 'Monthly'), ('quarterly', 'Quarterly'), ('yearly', 'Yearly'), ) name = models.CharField(_('name'), max_length=100) price = models.DecimalField(_('price'), max_digits=10, decimal_places=2) duration = models.CharField(_('duration'), max_length=10, choices=PLAN_CHOICES) def __str__(self): return f"{self.name} ({self.get_duration_display()})" class Meta: verbose_name = _('SubscriptionPlan') verbose_name_plural = _('SubscriptionPlan') class Subscription(models.Model): """租户订阅""" user = models.ForeignKey(ParadiseUser, default=0, on_delete=models.CASCADE, verbose_name=_('user')) plan = models.ForeignKey(SubscriptionPlan, on_delete=models.CASCADE, verbose_name=_('plan')) start_date = models.DateTimeField(_('start_date'), default=timezone.now) end_date = models.DateTimeField(_('end_date')) last_billed = models.DateTimeField(_('last_billed'), null=True, blank=True) # 上次账单生成日期 def save(self, *args, **kwargs): if not self.end_date: if self.plan.duration == 'monthly': self.end_date = self.start_date + timedelta(days=30) elif self.plan.duration == 'quarterly': self.end_date = self.start_date + timedelta(days=90) elif self.plan.duration == 'yearly': self.end_date = self.start_date + timedelta(days=365) super().save(*args, **kwargs) def __str__(self): return f"Subscription for {self.tenant} ({self.plan.name})" class Meta: verbose_name = _('User Subscription') verbose_name_plural = _('User Subscription') class AddOnPackage(models.Model): """加油包""" name = models.CharField(_('name'), max_length=100) description = models.TextField(_('description')) price = models.DecimalField(_('price'), max_digits=10, decimal_places=2) class Meta: verbose_name = _('AddOnPackage') verbose_name_plural = _('AddOnPackage') class SubscriptionAddOn(models.Model): """租户订阅加油包""" subscription = models.ForeignKey(Subscription, on_delete=models.CASCADE, verbose_name=_('subscription')) add_on = models.ForeignKey(AddOnPackage, on_delete=models.CASCADE, verbose_name=_('add_on')) quantity = models.PositiveIntegerField(_('quantity'), default=1) added_on = models.DateTimeField(_('added_on'), auto_now_add=True) def total_price(self): return self.add_on.price * self.quantity def __str__(self): return f"{self.add_on.name} for {self.subscription.tenant}" class Meta: verbose_name = _('TenantSubscriptionAddOn') verbose_name_plural = _('TenantSubscriptionAddOn') class TenantBilling(models.Model): """租户账单""" user = models.ForeignKey(ParadiseUser, default=0, on_delete=models.CASCADE, verbose_name=_('user')) subscription = models.ForeignKey(Subscription, on_delete=models.CASCADE, verbose_name=_('subscription')) total_price = models.DecimalField(_('total_price'), max_digits=10, decimal_places=2, default=0) billing_date = models.DateTimeField(_('billing_date'), auto_now_add=True) def calculate_total_price(self): # 基础订阅费用 subscription_price = self.subscription.plan.price # 加油包费用 add_on_price = sum([addon.total_price() for addon in self.subscription.subscriptionaddon_set.all()]) self.total_price = subscription_price + add_on_price self.save() class Meta: verbose_name = _('TenantBilling') verbose_name_plural = _('TenantBilling')