def test_multivariable_variation(): parent = create_product("SuperComplexVarParent") color_var = ProductVariationVariable.objects.create(product=parent, identifier="color") size_var = ProductVariationVariable.objects.create(product=parent, identifier="size") for color in ("yellow", "blue", "brown"): ProductVariationVariableValue.objects.create(variable=color_var, identifier=color) for size in ("small", "medium", "large", "huge"): ProductVariationVariableValue.objects.create(variable=size_var, identifier=size) combinations = list(parent.get_all_available_combinations()) assert len(combinations) == (3 * 4) for combo in combinations: assert not combo["result_product_pk"] # Elide a combination (yellow/small) for testing: if combo["variable_to_value"][color_var].identifier == "yellow" and combo["variable_to_value"][size_var].identifier == "small": continue child = create_product("xyz-%s" % combo["sku_part"]) child.link_to_parent(parent, combo["variable_to_value"]) assert parent.mode == ProductMode.VARIABLE_VARIATION_PARENT # Elided product should not yield a result yellow_color_value = ProductVariationVariableValue.objects.get(variable=color_var, identifier="yellow") small_size_value = ProductVariationVariableValue.objects.get(variable=size_var, identifier="small") assert not ProductVariationResult.resolve(parent, {color_var: yellow_color_value, size_var: small_size_value}) # Anything else should brown_color_value = ProductVariationVariableValue.objects.get(variable=color_var, identifier="brown") result1 = ProductVariationResult.resolve(parent, {color_var: brown_color_value, size_var: small_size_value}) result2 = ProductVariationResult.resolve(parent, {color_var.pk: brown_color_value.pk, size_var.pk: small_size_value.pk}) assert result1 and result2 assert result1.pk == result2.pk assert len(parent.get_available_variation_results()) == (3 * 4 - 1)
def test_multivariable_variation(): parent = create_product("SuperComplexVarParent") color_var = ProductVariationVariable.objects.create(product=parent, identifier="color") size_var = ProductVariationVariable.objects.create(product=parent, identifier="size") for color in ("yellow", "blue", "brown"): ProductVariationVariableValue.objects.create(variable=color_var, identifier=color) for size in ("small", "medium", "large", "huge"): ProductVariationVariableValue.objects.create(variable=size_var, identifier=size) combinations = list(parent.get_all_available_combinations()) assert len(combinations) == (3 * 4) for combo in combinations: assert not combo["result_product_pk"] # Elide a combination (yellow/small) for testing: if combo["variable_to_value"][ color_var].identifier == "yellow" and combo[ "variable_to_value"][size_var].identifier == "small": continue child = create_product("xyz-%s" % combo["sku_part"]) child.link_to_parent(parent, combo["variable_to_value"]) assert parent.mode == ProductMode.VARIABLE_VARIATION_PARENT # Elided product should not yield a result yellow_color_value = ProductVariationVariableValue.objects.get( variable=color_var, identifier="yellow") small_size_value = ProductVariationVariableValue.objects.get( variable=size_var, identifier="small") assert not ProductVariationResult.resolve(parent, { color_var: yellow_color_value, size_var: small_size_value }) # Anything else should brown_color_value = ProductVariationVariableValue.objects.get( variable=color_var, identifier="brown") result1 = ProductVariationResult.resolve(parent, { color_var: brown_color_value, size_var: small_size_value }) result2 = ProductVariationResult.resolve(parent, { color_var.pk: brown_color_value.pk, size_var.pk: small_size_value.pk }) assert result1 and result2 assert result1.pk == result2.pk assert len(parent.get_available_variation_results()) == (3 * 4 - 1)
def test_variable_variation(): parent = create_product("ComplexVarParent") sizes_and_children = [("%sL" % ("X" * x), create_product("ComplexVarChild-%d" % x)) for x in range(4)] for size, child in sizes_and_children: child.link_to_parent(parent, variables={"size": size}) assert parent.mode == ProductMode.VARIABLE_VARIATION_PARENT assert all(child.is_variation_child() for (size, child) in sizes_and_children) # Validation tests dummy = create_product("InvalidComplexVarChild") with pytest.raises(ValueError): dummy.link_to_parent(parent) with pytest.raises(ValueError): parent.link_to_parent(dummy) with pytest.raises(ValueError): dummy.link_to_parent(sizes_and_children[0][1]) # Variable tests size_attr = parent.variation_variables.get(identifier="size") for size, child in sizes_and_children: size_val = size_attr.values.get(identifier=size) result_product = ProductVariationResult.resolve(parent, {size_attr: size_val}) assert result_product == child
def test_variable_variation(): parent = create_product("ComplexVarParent") sizes_and_children = [("%sL" % ("X" * x), create_product("ComplexVarChild-%d" % x)) for x in range(4)] for size, child in sizes_and_children: child.link_to_parent(parent, variables={"size": size}) assert parent.mode == ProductMode.VARIABLE_VARIATION_PARENT assert all(child.is_variation_child() for (size, child) in sizes_and_children) # Validation tests dummy = create_product("InvalidComplexVarChild") with pytest.raises(ValueError): dummy.link_to_parent(parent) with pytest.raises(ValueError): parent.link_to_parent(dummy) with pytest.raises(ValueError): dummy.link_to_parent(sizes_and_children[0][1]) # Variable tests size_attr = parent.variation_variables.get(identifier="size") for size, child in sizes_and_children: size_val = size_attr.values.get(identifier=size) result_product = ProductVariationResult.resolve( parent, {size_attr: size_val}) assert result_product == child
def get_context_data(self, **kwargs): context = super(ProductPriceView, self).get_context_data(**kwargs) vars = self.get_variation_variables() if vars: # complex variation variables detected context["product"] = ProductVariationResult.resolve(context["product"], vars) context["quantity"] = self.request.GET.get("quantity") if context["product"]: # Might be null from ProductVariationResult resolution context["quantity"] = context["product"].sales_unit.round(context["quantity"]) return context
def get_context_data(self, **kwargs): context = super(ProductPriceView, self).get_context_data(**kwargs) vars = self.get_variation_variables() if vars: # complex variation variables detected context["product"] = ProductVariationResult.resolve(context["product"], vars) if not context["product"]: self.template_name = "shoop/front/product/_detail_order_section_no_product.jinja" context["quantity"] = self.request.GET.get("quantity") if context["product"]: # Might be null from ProductVariationResult resolution context["quantity"] = context["product"].sales_unit.round(context["quantity"]) return context
def get_context_data(self, **kwargs): context = super(ProductPriceView, self).get_context_data(**kwargs) vars = self.get_variation_variables() if vars: # complex variation variables detected context["product"] = ProductVariationResult.resolve( context["product"], vars) if not context["product"]: self.template_name = "shoop/front/product/_detail_order_section_no_product.jinja" context["quantity"] = self.request.GET.get("quantity") if context[ "product"]: # Might be null from ProductVariationResult resolution context["quantity"] = context["product"].sales_unit.round( context["quantity"]) return context
def handle_add_var(request, basket, product_id, quantity=1, **kwargs): """ Handle adding a complex variable product into the basket by resolving the combination variables. This actually uses `kwargs`, expecting `var_XXX=YYY` to exist there, where `XXX` is the PK of a ProductVariationVariable and YYY is the PK of a ProductVariationVariableValue. Confused yet? :param quantity: Quantity of the resolved variation to add. :param kwargs: Expected to contain `var_*` values, see above. """ # Resolve the combination... vars = dict((int(k.split("_")[-1]), int(v)) for (k, v) in six.iteritems(kwargs) if k.startswith("var_")) var_product = ProductVariationResult.resolve(product_id, combination=vars) if not var_product: raise ValidationError(_(u"This variation is not available."), code="invalid_variation_combination") # and hand it off to handle_add like we're used to return handle_add(request=request, basket=basket, product_id=var_product.pk, quantity=quantity)