from django.db import models from django.conf import settings class OrderStatus(models.TextChoices): PENDING = 'PENDING', 'Pending' PAID = 'PAID', 'Paid' SHIPPED = 'SHIPPED', 'Shipped' DELIVERED = 'DELIVERED', 'Delivered' CANCELED = 'CANCELED', 'Canceled' class CutChoices(models.IntegerChoices): WOMEN = 1, 'Women' MEN = 2, 'Men' KIDS = 3, 'Kids' class Color(models.Model): name = models.CharField(max_length=40, unique=True) colorHex = models.CharField(max_length=7, default="#FFFFFF", help_text="Color in hex format (e.g. #FF0000)") secondary_hex_color = models.CharField(max_length=7, null=True, blank=True, help_text="Secondary color in hex format for split color display") def __str__(self): return self.name class Size(models.Model): name = models.CharField(max_length=20, unique=True) def __str__(self): return self.name class Product(models.Model): sku = models.CharField(max_length=50, unique=True, help_text="Product SKU (unique identifier)") title = models.CharField(max_length=200) description = models.TextField(blank=True, null=True, help_text="Product description text") image = models.CharField(max_length=200, null=True, blank=True) price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00) # Use string references to prevent circular imports colors = models.ManyToManyField("shop.Color", blank=True, related_name="products") sizes = models.ManyToManyField("shop.Size", blank=True, related_name="products") ordering_value = models.IntegerField(default=0, blank=False) cut = models.IntegerField(choices=CutChoices.choices, default=CutChoices.MEN) class Meta: ordering = ['ordering_value', 'cut'] # Add this line to sort by title def __str__(self): return f"{self.sku} - {self.title}" class CartItem(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True) product = models.ForeignKey(Product, on_delete=models.CASCADE) quantity = models.PositiveIntegerField(default=1) color = models.ForeignKey(Color, on_delete=models.SET_NULL, null=True, blank=True) size = models.ForeignKey(Size, on_delete=models.SET_NULL, null=True, blank=True) session_id = models.CharField(max_length=255, null=True, blank=True) date_added = models.DateTimeField(auto_now_add=True) class Meta: ordering = ['product__ordering_value', 'product__cut'] # Sort by product's ordering_value def __str__(self): return f"{self.quantity} x {self.product.title}" def get_total_price(self): return self.product.price * self.quantity class GuestUser(models.Model): email = models.EmailField() phone = models.CharField(max_length=20) def __str__(self): return f"{self.email}" class Order(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True) date_ordered = models.DateTimeField(auto_now_add=True) status = models.CharField(max_length=20, choices=OrderStatus.choices, default=OrderStatus.PENDING) total_price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00) guest_user = models.ForeignKey(GuestUser, on_delete=models.CASCADE, null=True, blank=True) stripe_payment_intent_id = models.CharField(max_length=255, blank=True, null=True) stripe_checkout_session_id = models.CharField(max_length=255, blank=True, null=True) payment_status = models.CharField(max_length=20, default='UNPAID', choices=[ ('UNPAID', 'Unpaid'), ('PAID', 'Paid'), ('FAILED', 'Failed'), ]) webhook_processed = models.BooleanField(default=False) stripe_mode = models.CharField(max_length=10, default='test', choices=[ ('test', 'Test Mode'), ('live', 'Live Mode'), ]) def __str__(self): return f"Order #{self.id} - {self.status}" class OrderItem(models.Model): order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='items') product = models.ForeignKey(Product, on_delete=models.CASCADE) quantity = models.PositiveIntegerField(default=1) color = models.ForeignKey(Color, on_delete=models.SET_NULL, null=True, blank=True) size = models.ForeignKey(Size, on_delete=models.SET_NULL, null=True, blank=True) price = models.DecimalField(max_digits=10, decimal_places=2) class Meta: ordering = ['product__ordering_value', 'product__cut'] # Sort by product's ordering_value def __str__(self): return f"{self.quantity} x {self.product.title}" def get_total_price(self): return self.price * self.quantity