from datetime import timedelta, timezone from django.db import models from accounts.models import BaseModel, IAmPrincipal, IAmPrincipalType from django.utils.translation import gettext_lazy as _ # Create your models here. class Plan(BaseModel): title = models.CharField(max_length=255) days = models.PositiveIntegerField() class Meta: db_table = "plan" def __str__(self): return self.title class Subscription(BaseModel): title = models.CharField(max_length=255) short_description = models.CharField(max_length=255, null=True, blank=True) long_description = models.TextField(null=True, blank=True) image = models.ImageField(upload_to="subscription_img", null=True, blank=True) plan = models.ForeignKey( Plan, related_name="subscription_plan", on_delete=models.CASCADE ) high_amount = models.DecimalField(max_digits=14, decimal_places=2, default=0.00) amount = models.DecimalField(max_digits=14, decimal_places=2, default=0.00) principal_types = models.ManyToManyField( IAmPrincipalType, related_name="principal_type_subscriptions", blank=True ) referral_percentage = models.DecimalField(max_digits=5, decimal_places=2) is_free = models.BooleanField(default=False, help_text="Indicates whether this subscription is free and only accessible by administrators, not visible to regular users.") class Meta: db_table = "subscription" def __str__(self): return self.title class SubscriptionStatus(models.TextChoices): ACTIVE = "active", _("Active") EXPIRED = "expired", _("Expired") INACTIVE = "inactive", _("Inactive") class PrincipalSubscription(BaseModel): subscription = models.ForeignKey( Subscription, related_name="subscription_reference", on_delete=models.CASCADE ) principal = models.ForeignKey( IAmPrincipal, related_name="principal_subscription", on_delete=models.CASCADE ) is_paid = models.BooleanField(default=False) auto_renew = models.BooleanField(default=False) status = models.CharField( max_length=255, choices=SubscriptionStatus.choices, default=SubscriptionStatus.ACTIVE, ) start_date = models.DateField() end_date = models.DateField() order_id = models.CharField(max_length=255, null=True, blank=True) cancelled = models.BooleanField(default=False) cancelled_date_time = models.DateTimeField(null=True, blank=True) grace_period_end_date = models.DateField(null=True, blank=True) stripe_customer_id = models.CharField(max_length=255, null=True, blank=True) payment_intent_id = models.CharField(max_length=255, null=True, blank=True) payment_intent_client_secret = models.CharField( max_length=255, null=True, blank=True ) class Meta: db_table = "principal_subscription" def __str__(self): return f"{self.subscription} - {self.principal.first_name}" def generate_order_id(email): return f"order_{str(timezone.localtime().timestamp())}{str(email)}" def generate_grace_period_end_date(date): return date + timedelta(days=15) class WebhookEvent(BaseModel): event_id = models.CharField(max_length=255, unique=True, db_index=True) event_type = models.CharField(max_length=255, null=True, blank=True) received_at = models.DateTimeField(auto_now_add=True) processed_at = models.DateTimeField(null=True, blank=True) status = models.CharField( max_length=20, default="received" ) # e.g., 'received', 'processed', 'failed' error_message = models.TextField(null=True, blank=True) event_payload = models.JSONField( null=True, blank=True ) # Optional: Store the payload for debugging. def __str__(self): return f"Webhook Event {self.event_id} - Status: {self.status}" class Meta: db_table = "webhook_event"