def test_complex_variation(): request = get_request_with_basket() basket = request.basket shop = get_default_shop() supplier = get_default_supplier() parent = create_product("SuperComplexVarParent", shop=shop, supplier=supplier) color_var = ProductVariationVariable.objects.create(product=parent, identifier="color") size_var = ProductVariationVariable.objects.create(product=parent, identifier="size") ProductVariationVariableValue.objects.create(variable=color_var, identifier="yellow") ProductVariationVariableValue.objects.create(variable=size_var, identifier="small") combinations = list(get_all_available_combinations(parent)) for combo in combinations: child = create_product("xyz-%s" % combo["sku_part"], shop=shop, supplier=supplier) child.link_to_parent(parent, combo["variable_to_value"]) # 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") # add to basket yellow + small kwargs = {"var_%d" % color_var.pk: yellow_color_value.pk, "var_%d" % size_var.pk: small_size_value.pk} basket_commands.handle_add_var(request, basket, 1, **kwargs) assert basket.get_product_ids_and_quantities()[child.pk] == 1 with pytest.raises(ValidationError): kwargs = {"var_%d" % color_var.pk: yellow_color_value.pk, "var_%d" % size_var.pk: small_size_value.pk + 1} basket_commands.handle_add_var(request, basket, 1, **kwargs)
def test_simple_variation(): shop = get_default_shop() parent = create_product("SimpleVarParent") children = [create_product("SimpleVarChild-%d" % x) for x in range(10)] for child in children: child.link_to_parent(parent) sp = ShopProduct.objects.create(shop=shop, product=child, listed=True) assert child.is_variation_child() assert not sp.is_list_visible() # Variation children are not list visible assert parent.mode == ProductMode.SIMPLE_VARIATION_PARENT assert not list(get_all_available_combinations(parent)) # Simple variations can't have these. # Validation tests dummy = create_product("InvalidSimpleVarChild") with pytest.raises(ValueError): dummy.link_to_parent(parent, variables={"size": "XL"}) with pytest.raises(ValueError): parent.link_to_parent(dummy) with pytest.raises(ValueError): dummy.link_to_parent(children[0]) # Unlinkage for child in children: child.unlink_from_parent() assert not child.is_variation_child() assert child.mode == ProductMode.NORMAL assert not parent.is_variation_parent() assert parent.variation_children.count() == 0
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(get_all_available_combinations(parent)) 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(get_available_variation_results(parent)) == (3 * 4 - 1)
def _build_fields(self): for combo in get_all_available_combinations(self.parent_product): field = forms.ModelChoiceField( queryset=Product.objects.all(), widget=ProductChoiceWidget(clearable=True), required=False, initial=combo["result_product_pk"] ) field.combo = combo self.fields["r_%s" % combo["hash"]] = field
def _build_fields(self): for combo in get_all_available_combinations(self.parent_product): field = forms.ModelChoiceField( queryset=Product.objects.all(), # TODO: Add a mode for ProductChoiceWidget to only allow eligible variation children to be selected widget=ProductChoiceWidget(clearable=True), required=False, initial=combo["result_product_pk"] ) field.combo = combo self.fields["r_%s" % combo["hash"]] = field
def test_complex_variation(): request = get_request_with_basket() basket = request.basket shop = get_default_shop() supplier = get_default_supplier() parent = create_product("SuperComplexVarParent", shop=shop, supplier=supplier) color_var = ProductVariationVariable.objects.create(product=parent, identifier="color") size_var = ProductVariationVariable.objects.create(product=parent, identifier="size") ProductVariationVariableValue.objects.create(variable=color_var, identifier="yellow") ProductVariationVariableValue.objects.create(variable=size_var, identifier="small") combinations = list(get_all_available_combinations(parent)) for combo in combinations: child = create_product("xyz-%s" % combo["sku_part"], shop=shop, supplier=supplier) child.link_to_parent(parent, combo["variable_to_value"]) # 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") # add to basket yellow + small kwargs = { "var_%d" % color_var.pk: yellow_color_value.pk, "var_%d" % size_var.pk: small_size_value.pk } basket_commands.handle_add_var(request, basket, 1, **kwargs) assert basket.get_product_ids_and_quantities()[child.pk] == 1 with pytest.raises(ValidationError): kwargs = { "var_%d" % color_var.pk: yellow_color_value.pk, "var_%d" % size_var.pk: small_size_value.pk + 1 } basket_commands.handle_add_var(request, basket, 1, **kwargs)
def save(self): if not self.has_changed(): # See `SimplePricingForm.save()`. return with atomic(): for combo in get_all_available_combinations(self.parent_product): self._save_combo(combo)