feat: added product variants
This commit is contained in:
+18
-1
@@ -2,7 +2,7 @@ from decimal import Decimal
|
||||
|
||||
from django.utils.timezone import now
|
||||
|
||||
from shop.models import Product, ProductPrice, Tax
|
||||
from shop.models import Product, ProductAttribute, ProductAttributeValue, ProductPrice, ProductVariant, Tax
|
||||
|
||||
|
||||
class CreateProductsMixin:
|
||||
@@ -13,3 +13,20 @@ class CreateProductsMixin:
|
||||
product = Product.objects.create(sku=sku, name=name, description=description, is_shipping_method=is_shipping)
|
||||
ProductPrice.objects.create(price=price, product=product, date=now(), tax=tax, current=True)
|
||||
return product
|
||||
|
||||
def create_attribute_value(self, attribute_name='Talla', value='M') -> ProductAttributeValue:
|
||||
attribute, created = ProductAttribute.objects.get_or_create(name=attribute_name)
|
||||
attribute_value, created = ProductAttributeValue.objects.get_or_create(attribute=attribute, value=value)
|
||||
return attribute_value
|
||||
|
||||
def create_product_variant(
|
||||
self, product: Product, sku='000001-V1', price=Decimal('10.00'), stock=Decimal('10'), attribute_values=None
|
||||
) -> ProductVariant:
|
||||
tax, created = Tax.objects.get_or_create(code='IVA', value=21)
|
||||
variant = ProductVariant.objects.create(product=product, sku=sku, stock=stock)
|
||||
|
||||
if attribute_values:
|
||||
variant.attribute_values.set(attribute_values)
|
||||
|
||||
ProductPrice.objects.create(price=price, variant=variant, date=now(), tax=tax, current=True)
|
||||
return variant
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
from decimal import Decimal
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.test import TestCase
|
||||
|
||||
from shop.models import ProductVariant
|
||||
from shop.tests.mixins import CreateProductsMixin
|
||||
|
||||
|
||||
class TestProductVariants(TestCase, CreateProductsMixin):
|
||||
def setUp(self):
|
||||
self.product = self.create_product()
|
||||
self.size_m = self.create_attribute_value('Talla', 'M')
|
||||
self.size_l = self.create_attribute_value('Talla', 'L')
|
||||
|
||||
def test_product_without_variants_has_variants_false(self):
|
||||
assert self.product.has_variants is False
|
||||
|
||||
def test_product_with_variants_has_variants_true(self):
|
||||
self.create_product_variant(self.product, sku='V1', attribute_values=[self.size_m])
|
||||
|
||||
assert self.product.has_variants is True
|
||||
|
||||
def test_variant_price_returns_current_price(self):
|
||||
variant = self.create_product_variant(self.product, sku='V1', price=Decimal('15.00'), attribute_values=[self.size_m])
|
||||
|
||||
assert variant.price.price == Decimal('15.00')
|
||||
|
||||
def test_variant_str_includes_attribute_values(self):
|
||||
variant = self.create_product_variant(self.product, sku='V1', attribute_values=[self.size_m])
|
||||
|
||||
assert 'Talla: M' in str(variant)
|
||||
|
||||
def test_min_variant_price_returns_lowest_current_price(self):
|
||||
self.create_product_variant(self.product, sku='V1', price=Decimal('20.00'), attribute_values=[self.size_m])
|
||||
self.create_product_variant(self.product, sku='V2', price=Decimal('12.00'), attribute_values=[self.size_l])
|
||||
|
||||
assert self.product.min_variant_price.price == Decimal('12.00')
|
||||
|
||||
def test_duplicated_attribute_combination_is_invalid(self):
|
||||
self.create_product_variant(self.product, sku='V1', attribute_values=[self.size_m])
|
||||
duplicated = self.create_product_variant(self.product, sku='V2', attribute_values=[self.size_m])
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
duplicated.full_clean()
|
||||
|
||||
def test_different_attribute_combination_is_valid(self):
|
||||
self.create_product_variant(self.product, sku='V1', attribute_values=[self.size_m])
|
||||
other = self.create_product_variant(self.product, sku='V2', attribute_values=[self.size_l])
|
||||
|
||||
other.full_clean()
|
||||
Reference in New Issue
Block a user