Coverage for apps/products/models.py: 80%
65 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-10-24 17:44 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-10-24 17:44 -0600
1import numpy as np
2import requests
3from django.core.files.uploadedfile import SimpleUploadedFile
4from django.db import models
6from apps.catalogues.choices import Step
7from base.models import RandomSlugModel
10class ProductCategory(RandomSlugModel):
11 """
12 Model for ProdcutCategory
13 """
15 size_category = models.ForeignKey(
16 "catalogues.SizeCategory", on_delete=models.PROTECT, related_name="product_categories"
17 )
19 name = models.CharField(max_length=128)
21 def __str__(self):
22 return self.name
24 class Meta:
25 ordering = ["size_category", "name"]
28class Product(RandomSlugModel):
29 """
30 Model for Product
31 """
33 product_category = models.ForeignKey("products.ProductCategory", on_delete=models.PROTECT, related_name="products")
34 material = models.ForeignKey("catalogues.Material", on_delete=models.PROTECT, related_name="products", null=True)
36 name = models.CharField(max_length=128)
37 is_active = models.BooleanField(default=True)
38 photo = models.ImageField(upload_to="products/", null=True)
39 photo_url = models.URLField(null=True, blank=True)
41 description = models.TextField(null=True, blank=True)
43 @property
44 def sizes(self):
45 size_category = self.product_category.size_category
46 return np.arange(size_category.initial, size_category.final + size_category.step, size_category.step)
48 def set_photo(self):
49 try:
50 data = requests.get(self.photo_url).content
51 photo = SimpleUploadedFile(f"{self.name}.jpg", data, content_type="application/octet-stream")
52 self.photo = photo
53 self.save()
54 except Exception as e:
55 raise e
57 def __str__(self):
58 return self.name
60 class Meta:
61 ordering = ["-is_active", "product_category", "name"]
64class ProductVariation(RandomSlugModel):
65 """
66 Model for product variation
67 """
69 product = models.ForeignKey("products.Product", on_delete=models.PROTECT, related_name="variations")
70 sole = models.ForeignKey("catalogues.Sole", on_delete=models.PROTECT, related_name="variations", null=True)
71 color = models.ForeignKey("catalogues.Color", on_delete=models.PROTECT, related_name="variations", null=True)
73 default_cost = models.DecimalField(max_digits=10, decimal_places=2, default=0)
74 is_active = models.BooleanField(default=True)
75 sku = models.CharField(max_length=32)
76 photo = models.ImageField(upload_to="product_variations/", null=True, blank=True)
77 photo_url = models.URLField(null=True, blank=True)
79 initial = models.DecimalField(decimal_places=1, max_digits=4)
80 final = models.DecimalField(decimal_places=1, max_digits=4)
82 step = models.DecimalField(decimal_places=1, max_digits=2, choices=Step.choices)
84 @property
85 def sizes(self):
86 return np.arange(self.initial, self.final + self.step, self.step)
88 def set_photo(self):
89 try:
90 data = requests.get(self.photo_url).content
91 photo = SimpleUploadedFile(f"{self.sku}.jpg", data, content_type="application/octet-stream")
92 self.photo = photo
93 self.save()
94 except Exception as e:
95 raise e
97 class Meta:
98 ordering = ["product"]
101class ProductVariationClient(RandomSlugModel):
102 """
103 Through model for M2M relation of ProductVariation and Client
104 """
106 product_variation = models.ForeignKey("products.ProductVariation", on_delete=models.PROTECT, related_name="clients")
107 client = models.ForeignKey("clients.Client", on_delete=models.PROTECT)
109 client_sku = models.CharField(max_length=128)
111 class Meta:
112 ordering = ["product_variation", "client"]
113 unique_together = ["product_variation", "client"]
115 def __str__(self):
116 return f"{self.client} - {self.client_sku}"