96 lines
3.8 KiB
Python
96 lines
3.8 KiB
Python
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')
|
|
|
|
|