Skip to content

Commit

Permalink
remove the variant attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
hjlarry committed Jan 4, 2024
1 parent f675e92 commit 3490ca3
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 108 deletions.
1 change: 0 additions & 1 deletion flaskshop/dashboard/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ class ProductTypeForm(FlaskForm):
lazy_gettext("Is shipping required"), default=True
)
product_attributes_ids = SelectMultipleField(lazy_gettext("Product atributes"))
variant_attr_id = SelectField(lazy_gettext("Variant Attributes"))
submit = SubmitField(lazy_gettext("Submit"))


Expand Down
6 changes: 0 additions & 6 deletions flaskshop/dashboard/views/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,18 +177,12 @@ def product_types_manage(id=None):
form.product_attributes_ids.choices = [
(p.id, p.title) for p in ProductAttribute.query.all()
]
form.variant_attr_id.choices = [
(p.id, p.title) for p in ProductAttribute.query.all()
]
if form.validate_on_submit():
tmp_pa = form.product_attributes_ids.data
tmp_va = form.variant_attr_id.data
del form.product_attributes_ids
del form.variant_attr_id
form.populate_obj(product_type)
product_type.save()
product_type.update_product_attr(tmp_pa)
product_type.update_variant_attr(tmp_va)
flash(lazy_gettext("Product type saved."), "success")
return redirect(url_for("dashboard.product_types"))
return render_template(
Expand Down
60 changes: 2 additions & 58 deletions flaskshop/product/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,14 +304,6 @@ class ProductTypeAttributes(Model):
product_attribute_id = Column(db.Integer())


class ProductTypeVariantAttributes(Model):
"""存储的产品SKU的属性是可以给用户去选择的"""

__tablename__ = "product_type_variant_attribute"
product_type_id = Column(db.Integer())
product_attribute_id = Column(db.Integer())


class ProductType(Model):
__tablename__ = "product_type"
title = Column(db.String(255), nullable=False)
Expand All @@ -338,26 +330,6 @@ def product_attributes(self):
ProductAttribute.id.in_(self.product_attributes_ids)
).all()

@property
def variant_attributes(self):
at_ids = (
ProductTypeVariantAttributes.query.with_entities(
ProductTypeVariantAttributes.product_attribute_id
)
.filter(ProductTypeVariantAttributes.product_type_id == self.id)
.all()
)
return ProductAttribute.query.filter(
ProductAttribute.id.in_(id for id, in at_ids)
).all()

@property
def variant_attr_id(self):
if self.variant_attributes:
return self.variant_attributes[0].id
else:
return None

def update_product_attr(self, new_attrs):
origin_ids = (
ProductTypeAttributes.query.with_entities(
Expand All @@ -381,27 +353,11 @@ def update_product_attr(self, new_attrs):
db.session.add(new)
db.session.commit()

def update_variant_attr(self, variant_attr):
origin_attr = ProductTypeVariantAttributes.query.filter_by(
product_type_id=self.id
).first()
if origin_attr:
origin_attr.product_attribute_id = variant_attr
origin_attr.save()
else:
ProductTypeVariantAttributes.create(
product_type_id=self.id, product_attribute_id=variant_attr
)

def delete(self):
need_del_product_attrs = ProductTypeAttributes.query.filter_by(
product_type_id=self.id
).all()
need_del_variant_attrs = ProductTypeVariantAttributes.query.filter_by(
product_type_id=self.id
).all()

for item in itertools.chain(need_del_product_attrs, need_del_variant_attrs):
for item in need_del_product_attrs:
item.delete(commit=False)
need_update_products = Product.query.filter_by(product_type_id=self.id).all()
for product in need_update_products:
Expand All @@ -419,7 +375,6 @@ class ProductVariant(Model):
quantity = Column(db.Integer(), default=0)
quantity_allocated = Column(db.Integer(), default=0)
product_id = Column(db.Integer(), default=0)
attributes = Column(MutableDict.as_mutable(db.JSON()))

def __str__(self):
return self.title or self.sku
Expand Down Expand Up @@ -462,14 +417,6 @@ def product(self):
def get_absolute_url(self):
return url_for("product.show", id=self.product.id)

@property
def attribute_map(self):
items = {
ProductAttribute.get_by_id(k): AttributeChoiceValue.get_by_id(v)
for k, v in self.attributes.items()
}
return items

def check_enough_stock(self, quantity):
if self.stock < quantity:
return False, f"{self.display_product()} has not enough stock"
Expand Down Expand Up @@ -578,11 +525,8 @@ def delete(self):
need_del_product_attrs = ProductTypeAttributes.query.filter_by(
product_attribute_id=self.id
).all()
need_del_variant_attrs = ProductTypeVariantAttributes.query.filter_by(
product_attribute_id=self.id
).all()
for item in itertools.chain(
need_del_product_attrs, need_del_variant_attrs, self.values
need_del_product_attrs, self.values
):
item.delete(commit=False)
db.session.delete(self)
Expand Down
56 changes: 13 additions & 43 deletions flaskshop/random_data.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import itertools
import random
import itertools
import unicodedata
from uuid import uuid4

Expand Down Expand Up @@ -29,7 +29,6 @@
ProductImage,
ProductType,
ProductTypeAttributes,
ProductTypeVariantAttributes,
ProductVariant,
)
from flaskshop.public.models import MenuItem, Page
Expand Down Expand Up @@ -58,14 +57,14 @@ def shipping_method(self):
"Collar": ["Round", "V-Neck", "Polo"],
"Brand": ["Saleor"],
},
"variant_attributes": {"Size": ["XS", "S", "M", "L", "XL", "XXL"]},
"variant_titles": ["XS", "S", "M", "L", "XL", "XXL"],
"images_dir": "t-shirts/",
"is_shipping_required": True,
},
"Mugs": {
"category": {"name": "Accessories", "image_name": "accessories.jpg"},
"product_attributes": {"Brand": ["Saleor"]},
"variant_attributes": {},
"variant_titles": [],
"images_dir": "mugs/",
"is_shipping_required": True,
},
Expand All @@ -79,7 +78,7 @@ def shipping_method(self):
"Coffee Genre": ["Arabica", "Robusta"],
"Brand": ["Saleor"],
},
"variant_attributes": {"Box Size": ["100g", "250g", "500g", "1kg"]},
"variant_titles": ["100g", "250g", "500g", "1kg"],
"different_variant_prices": True,
"images_dir": "coffee/",
"is_shipping_required": True,
Expand All @@ -91,7 +90,7 @@ def shipping_method(self):
"parent": GROCERIES_CATEGORY,
},
"product_attributes": {"Flavor": ["Sour", "Sweet"], "Brand": ["Saleor"]},
"variant_attributes": {"Candy Box Size": ["100g", "250g", "500g"]},
"variant_titles": ["100g", "250g", "500g"],
"images_dir": "candy/",
"is_shipping_required": True,
},
Expand All @@ -102,7 +101,7 @@ def shipping_method(self):
"Publisher": ["Mirumee Press", "Saleor Publishing"],
"Language": ["English", "Pirate"],
},
"variant_attributes": {},
"variant_titles": [],
"images_dir": "books/",
"is_shipping_required": False,
},
Expand All @@ -113,7 +112,7 @@ def shipping_method(self):
"Publisher": ["Mirumee Press", "Saleor Publishing"],
"Language": ["English", "Pirate"],
},
"variant_attributes": {"Cover": ["Soft", "Hard"]},
"variant_titles": ["Soft", "Hard"],
"images_dir": "books/",
"is_shipping_required": True,
},
Expand Down Expand Up @@ -141,24 +140,6 @@ def shipping_method(self):
"""


def get_variant_combinations(product):
# Returns all possible variant combinations
# For example: product type has two variant attributes: Size, Color
# Size has available values: [S, M], Color has values [Red, Green]
# All combinations will be generated (S, Red), (S, Green), (M, Red),
# (M, Green)
# Output is list of dicts, where key is product attribute id and value is
# attribute value id. Casted to string.
variant_attr_map = {
attr: attr.values for attr in product.product_type.variant_attributes
}
all_combinations = itertools.product(*variant_attr_map.values())
return [
{str(attr_value.attribute.id): str(attr_value.id) for attr_value in combination}
for combination in all_combinations
]


def get_price_override(schema, combinations_num, current_price):
prices = []
if schema.get("different_variant_prices"):
Expand Down Expand Up @@ -196,7 +177,7 @@ def get_email(first_name, last_name):

# step1
def create_products_by_schema(
placeholder_dir, how_many, create_images, schema=DEFAULT_SCHEMA
placeholder_dir, how_many, create_images, schema=DEFAULT_SCHEMA
):
for product_type, type_schema in create_product_types_by_schema(schema):
create_products_by_type(
Expand All @@ -220,21 +201,15 @@ def create_product_types_by_schema(root_schema):
# step3
def create_product_type_with_attributes(name, schema):
product_attributes_schema = schema.get("product_attributes", {})
variant_attributes_schema = schema.get("variant_attributes", {})
is_shipping_required = schema.get("is_shipping_required", True)
product_type = ProductType.get_or_create(
title=name, is_shipping_required=is_shipping_required
)[0]
product_attributes = create_attributes_and_values(product_attributes_schema)
variant_attributes = create_attributes_and_values(variant_attributes_schema)
for attr in product_attributes:
ProductTypeAttributes.get_or_create(
product_type_id=product_type.id, product_attribute_id=attr.id
)
for attr in variant_attributes:
ProductTypeVariantAttributes.get_or_create(
product_type_id=product_type.id, product_attribute_id=attr.id
)
return product_type


Expand All @@ -252,7 +227,7 @@ def create_attributes_and_values(attribute_data):

# step5
def create_products_by_type(
product_type, schema, placeholder_dir, how_many=10, create_images=True, stdout=None
product_type, schema, placeholder_dir, how_many=10, create_images=True, stdout=None
):
category = get_or_create_category(schema["category"], placeholder_dir)

Expand All @@ -264,16 +239,16 @@ def create_products_by_type(
if create_images:
type_placeholders = placeholder_dir / schema["images_dir"]
create_product_images(product, random.randrange(1, 5), type_placeholders)
variant_combinations = get_variant_combinations(product)
variant_combinations = schema["variant_titles"]

prices = get_price_override(schema, len(variant_combinations), product.price)
variants_with_prices = itertools.zip_longest(variant_combinations, prices)

for i, variant_price in enumerate(variants_with_prices, start=1337):
attr_combination, price = variant_price
title, price = variant_price
sku = f"{product.id}-{i}"
create_variant(
product, attributes=attr_combination, sku=sku, price_override=price
product, sku=sku, title=title, price_override=price
)

if not variant_combinations:
Expand Down Expand Up @@ -337,12 +312,7 @@ def create_product_images(product, how_many, placeholder_dir):
def create_variant(product, **kwargs):
defaults = {"product_id": product.id, "quantity": fake.random_int(1, 50)}
defaults.update(kwargs)
attributes = defaults.pop("attributes")
variant = ProductVariant(**defaults)
variant.attributes = attributes

if variant.attributes:
variant.title = get_name_from_attributes(variant)
variant.save()
return variant

Expand Down Expand Up @@ -444,7 +414,7 @@ def create_page():
<h2 align="center">AN OPENSOURCE STOREFRONT PLATFORM FOR PERFECTIONISTS</h2>
<h3 align="center">WRITTEN IN PYTHON, BEST SERVED AS A BESPOKE, HIGH-PERFORMANCE E-COMMERCE SOLUTION</h3>
<p><br></p>
<p><img src="http://getsaleor.com/images/main-pic.svg"></p>
<p><img src="https://getsaleor.com/images/main-pic.svg"></p>
<p style="text-align: center;">
<a href="https://github.com/mirumee/saleor/">Get Saleor</a> today!
</p>
Expand Down

0 comments on commit 3490ca3

Please sign in to comment.