import uuid from datetime import timedelta from django.conf import settings from django.core.exceptions import ValidationError from django.db import models from django.utils import timezone from alphabetlearning.resources.models import Resource class EmailVerification(models.Model): email = models.EmailField(unique=True) verification_token = models.UUIDField(default=uuid.uuid4, editable=False) created_at = models.DateTimeField(auto_now_add=True) is_verified = models.BooleanField(default=False) @property def is_expired(self): expiration_time = timedelta(hours=26) return timezone.now() - self.created_at > expiration_time def __str__(self): return f"Email verification for {self.email}" class EmailSignup(models.Model): email = models.EmailField(unique=True) date_added = models.DateTimeField(auto_now_add=True) def __str__(self): return self.email class Product(models.Model): name = models.CharField(max_length=255) stripe_product_id = models.CharField(max_length=100) def __str__(self): return self.name class Price(models.Model): resource = models.ForeignKey(Resource, on_delete=models.CASCADE, related_name="price_obj") price = models.IntegerField(default=0) stripe_price_id = models.CharField(max_length=100) def get_display_price(self): return "{0:.2f}".format(self.price / 100) def __str__(self): return f"{self.price} for {self.resource.name}" class ShoppingCart(models.Model): user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return f"Shopping cart for {self.user.email}" def add_resource(self, resource: Resource): if CartItem.objects.filter(cart=self, resource=resource).exists(): raise ValidationError(f"{resource.name} is already in your shopping cart.") item, created = CartItem.objects.get_or_create( cart=self, resource=resource, ) if not created: item.save() class CartItem(models.Model): cart = models.ForeignKey(ShoppingCart, on_delete=models.CASCADE, related_name="items") resource = models.ForeignKey(Resource, on_delete=models.CASCADE) added_at = models.DateTimeField(auto_now_add=True) class Meta: unique_together = ("cart", "resource") def __str__(self): return f"{self.resource.name} in {self.cart.user.username}'s cart" class SubscriptionPlan(models.Model): name = models.CharField(max_length=255) price = models.DecimalField(max_digits=6, decimal_places=2) description = models.TextField() allowed_downloads = models.PositiveIntegerField() class Subscription(models.Model): user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) plan = models.ForeignKey(SubscriptionPlan, on_delete=models.CASCADE) is_active = models.BooleanField(default=False) start_date = models.DateTimeField(null=True, blank=True) end_date = models.DateTimeField(null=True, blank=True) class Meta: constraints = [models.UniqueConstraint(fields=["user", "plan"], name="unique_user_plan")] def __str__(self): return f"Subscription for {self.user.username}"