Esempio n. 1
0
def test_only_cheapest_price_is_selected(rf):
    request, shop, group = initialize_test(rf, False)
    price = shop.create_price

    basket = get_basket(request)
    supplier = get_default_supplier()
     # create a basket rule that requires atleast value of 200
    rule = BasketTotalAmountCondition.objects.create(value="200")

    product_price = "200"

    discount1 = "10"
    discount2 = "20"  # should be selected
    product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=product_price)
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    basket.shipping_method = get_shipping_method(shop=shop)

    campaign1 = BasketCampaign.objects.create(shop=shop, public_name="test", name="test", active=True)
    campaign1.conditions.add(rule)
    campaign1.save()
    BasketDiscountAmount.objects.create(discount_amount=discount1, campaign=campaign1)

    campaign2 = BasketCampaign.objects.create(shop=shop, public_name="test", name="test", active=True)
    campaign2.conditions.add(rule)
    campaign2.save()
    BasketDiscountAmount.objects.create(discount_amount=discount2, campaign=campaign2)

    assert len(basket.get_final_lines()) == 3

    line_types = [l.type for l in basket.get_final_lines()]
    assert OrderLineType.DISCOUNT in line_types

    for line in basket.get_final_lines():
        if line.type == OrderLineType.DISCOUNT:
            assert line.discount_amount == price(discount2)
def test_basket_total_undiscounted_value_conditions(rf):
    request, shop, group = initialize_test(rf, False)

    basket = get_basket(request)
    supplier = get_default_supplier()

    product = create_product("Just-A-Product", shop, default_price="150", supplier=supplier)
    discounted_product = create_product("Just-A-Second-Product", shop, default_price="200", supplier=supplier)

    # CatalogCampaign
    catalog_campaign = CatalogCampaign.objects.create(active=True, shop=shop, name="test", public_name="test")
    # Limit catalog campaign to "discounted_product"
    product_filter = ProductFilter.objects.create()
    product_filter.products.add(discounted_product)
    catalog_campaign.filters.add(product_filter)

    basket.add_product(supplier=supplier, shop=shop, product=discounted_product, quantity=1)

    condition = BasketTotalUndiscountedProductAmountCondition.objects.create()
    condition.value = 1
    condition.save()
    assert not condition.matches(basket, [])

    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    assert condition.matches(basket, [])

    # Too high amount for undiscounted value
    condition.value = 151
    condition.save()

    assert not condition.matches(basket, [])
def test_product_in_basket_condition_with_variation_parent(rf):
    request, shop, group = initialize_test(rf, False)

    basket = get_basket(request)
    supplier = get_default_supplier()

    product = create_product(
        "test-product", shop, default_price="200", supplier=supplier, mode=ProductMode.SIMPLE_VARIATION_PARENT)

    child_products = []
    for x in range(0, 3):
        child_product = create_product("test-product-%s" % x, shop, default_price="10", supplier=supplier)
        child_product.link_to_parent(product)
        child_products.append(child_product)

    condition = ProductsInBasketCondition.objects.create()
    condition.values = [product]
    condition.operator = ComparisonOperator.EQUALS
    condition.quantity = 3
    condition.save()

    assert not condition.matches(basket, [])

    for child_product in child_products:
        basket.add_product(supplier=supplier, shop=shop, product=child_product, quantity=1)

    assert condition.matches(basket, [])
def test_price_cannot_be_under_zero(rf):

    activate("en")
    discount_amount = "200"
    original_price = "199.20"

    request, shop, group = initialize_test(rf, False)
    cat = Category.objects.create(name="test")
    rule1, rule2 = create_condition_and_filter(cat, request)

    campaign = CatalogCampaign.objects.create(shop=shop, name="test", active=True)
    campaign.conditions.add(rule1)
    campaign.filters.add(rule2)
    campaign.save()

    ProductDiscountAmount.objects.create(campaign=campaign, discount_amount=discount_amount)

    price = shop.create_price

    product = create_product("Just-A-Product-Too", shop, default_price=original_price)
    shop_product = product.get_shop_instance(shop)
    shop_product.categories.add(cat)
    shop_product.save()

    assert product.get_price_info(request, quantity=1).price == price("0")
def test_percentage_campaign_full_discount(rf, include_tax):
    request, shop, group = initialize_test(rf, include_tax)
    create_default_order_statuses()
    tax = get_tax("sales-tax", "Sales Tax", Decimal(0.2)) # 20%
    create_default_tax_rule(tax)

    basket = get_basket(request)
    supplier = get_default_supplier()

    product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=200)
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    basket.shipping_method = get_shipping_method(shop=shop)
    basket.status = get_initial_order_status()

    campaign = BasketCampaign.objects.create(shop=shop, public_name="test", name="test", active=True)
    # 100% of discount
    BasketDiscountPercentage.objects.create(campaign=campaign, discount_percentage=Decimal(1))

    assert len(basket.get_final_lines()) == 3
    assert basket.product_count == 1
    assert basket.total_price.value == Decimal()

    order_creator = OrderCreator()
    order = order_creator.create_order(basket)
    order.create_payment(order.taxful_total_price)
    assert order.taxful_total_price.value == Decimal()
def test_basket_total_undiscounted_value_conditions(rf):
    request, shop, group = initialize_test(rf, False)

    basket = get_basket(request)
    supplier = get_default_supplier(shop)

    product = create_product("Just-A-Product", shop, default_price="150", supplier=supplier)
    discounted_product = create_product("Just-A-Second-Product", shop, default_price="200", supplier=supplier)

    # CatalogCampaign
    catalog_campaign = CatalogCampaign.objects.create(active=True, shop=shop, name="test", public_name="test")
    # Limit catalog campaign to "discounted_product"
    product_filter = ProductFilter.objects.create()
    product_filter.products.add(discounted_product)
    catalog_campaign.filters.add(product_filter)

    basket.add_product(supplier=supplier, shop=shop, product=discounted_product, quantity=1)

    condition = BasketTotalUndiscountedProductAmountCondition.objects.create()
    condition.value = 1
    condition.save()
    assert not condition.matches(basket, [])

    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    assert condition.matches(basket, [])

    # Too high amount for undiscounted value
    condition.value = 151
    condition.save()

    assert not condition.matches(basket, [])
Esempio n. 7
0
def test_percentage_campaign(rf):
    request, shop, group = initialize_test(rf, False)
    price = shop.create_price

    basket = get_basket(request)
    supplier = get_default_supplier()
    # create a basket rule that requires at least value of 200
    rule = BasketTotalAmountCondition.objects.create(value="200")

    product_price = "200"

    discount_percentage = "0.1"

    expected_discounted_price = price(product_price) - (price(product_price) * Decimal(discount_percentage))

    product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=product_price)
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    basket.shipping_method = get_shipping_method(shop=shop)

    campaign = BasketCampaign.objects.create(
        shop=shop, public_name="test", name="test", active=True)
    campaign.conditions.add(rule)
    campaign.save()

    BasketDiscountPercentage.objects.create(campaign=campaign, discount_percentage=discount_percentage)

    assert len(basket.get_final_lines()) == 3
    assert basket.product_count == 1
    assert basket.total_price == expected_discounted_price
def test_category_product_in_basket_condition(rf):
    request, shop, group = initialize_test(rf, False)
    basket = get_basket(request)
    supplier = get_default_supplier()
    category = get_default_category()
    product = create_product("The Product", shop=shop, default_price="200", supplier=supplier)
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    basket.shipping_method = get_shipping_method(shop=shop)

    shop_product = product.get_shop_instance(shop)
    assert category not in shop_product.categories.all()

    condition = CategoryProductsBasketCondition.objects.create(operator=ComparisonOperator.EQUALS, quantity=1)
    condition.categories.add(category)

    # No match the product does not have the category
    assert not condition.matches(basket, [])

    shop_product.categories.add(category)
    assert condition.matches(basket, [])

    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    assert not condition.matches(basket, [])

    condition.operator = ComparisonOperator.GTE
    condition.save()

    assert condition.matches(basket, [])

    condition.excluded_categories.add(category)
    assert not condition.matches(basket, [])
def test_campaign_with_non_active_coupon(rf):
    initial_status = get_initial_order_status()
    request, shop, group = initialize_test(rf, include_tax=False)
    order = _get_order_with_coupon(request, initial_status)
    coupon = order.coupon_usages.first().coupon
    coupon.active = False
    coupon.save()

    modifier = UserFactory()
    contact = create_random_person(locale="en_US", minimum_name_comp_len=5)
    assert order.customer != contact
    state = _get_frontend_order_state(shop, contact)
    assert order.shop.id == state["shop"]["selected"]["id"]

    request = get_frontend_request_for_command(state, "finalize", modifier)
    response = OrderEditView.as_view()(request, pk=order.pk)
    assert_contains(response, "orderIdentifier")
    data = json.loads(response.content.decode("utf8"))
    edited_order = Order.objects.get(pk=order.pk)

    assert edited_order.identifier == data["orderIdentifier"] == order.identifier
    assert edited_order.pk == order.pk
    assert edited_order.lines.count() == 3
    assert OrderLineType.DISCOUNT not in [l.type for l in edited_order.lines.all()]
    assert edited_order.coupon_usages.count() == 0
def test_percentage_campaigns(rf):
    activate("en")
    discount_percentage = "0.14"
    original_price = "123.47"

    request, shop, group = initialize_test(rf, False)
    cat = Category.objects.create(name="test")
    rule1 = ContactGroupCondition.objects.create()
    rule1.contact_groups = request.customer.groups.all()
    rule1.save()

    rule2 = CategoryFilter.objects.create()
    rule2.categories.add(cat)
    rule2.save()
    campaign = CatalogCampaign.objects.create(shop=shop, name="test", active=True)
    campaign.conditions.add(rule1)
    campaign.filters.add(rule2)
    campaign.save()

    cdp = ProductDiscountPercentage.objects.create(campaign=campaign, discount_percentage=discount_percentage)

    product = create_product("Just-A-Product-Too", shop, default_price=original_price)

    price = shop.create_price
    # price should not be discounted because the request.category is faulty
    assert product.get_price_info(request, quantity=1).price == price(original_price)

    shop_product = product.get_shop_instance(shop)
    shop_product.categories.add(cat)
    shop_product.save()
    # now the category is set, so both rules match, discount should be given
    discounted_price = price(original_price) - (price(original_price) * Decimal(cdp.value))
    assert product.get_price_info(request, quantity=1).price == discounted_price
def test_product_in_basket_condition(rf):
    request, shop, group = initialize_test(rf, False)

    basket = get_basket(request)
    supplier = get_default_supplier()

    product = create_product("Just-A-Product-Too", shop, default_price="200")
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)

    condition = ProductsInBasketCondition.objects.create()
    condition.values = [product]
    condition.save()

    assert condition.values.first() == product

    assert condition.matches(basket, [])

    condition.quantity = 2
    condition.save()

    assert not condition.matches(basket, [])

    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    assert condition.matches(basket, [])

    condition.operator = ComparisonOperator.EQUALS
    condition.save()

    assert condition.matches(basket, [])

    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    assert not condition.matches(basket, [])
def test_minimum_price_is_forced(rf):
    activate("en")
    discount_amount = "20.53"
    original_price = "199.20"
    allowed_minimum_price = "190.20"

    request, shop, group = initialize_test(rf, False)
    cat = Category.objects.create(name="test")
    rule1, rule2 = create_condition_and_filter(cat, request)
    campaign = CatalogCampaign.objects.create(shop=shop, name="test", active=True)
    campaign.conditions.add(rule1)
    campaign.filters.add(rule2)
    campaign.save()

    ProductDiscountAmount.objects.create(campaign=campaign, discount_amount=discount_amount)

    price = shop.create_price

    product = create_product("Just-A-Product-Too", shop, default_price=original_price)
    shop_product = product.get_shop_instance(shop)
    shop_product.minimum_price = price(allowed_minimum_price)
    shop_product.save()

    # price should not be discounted because the request.category is faulty
    assert product.get_price_info(request, quantity=1).price == price(original_price)

    shop_product.categories.add(cat)
    shop_product.save()
    # now the category is set, so both rules match, discount should be given
    assert product.get_price_info(request, quantity=1).price == shop_product.minimum_price
Esempio n. 13
0
def test_category_filter(rf):
    request, shop, group = initialize_test(rf, False)

    cat = get_default_category()
    cat_filter = CategoryFilter.objects.create()
    cat_filter.categories.add(cat)
    cat_filter.save()

    assert cat_filter.values.first() == cat
    category = Category.objects.create(
        parent=None,
        identifier="testcat",
        name="catcat",
    )
    cat_filter.values = [cat, category]
    cat_filter.save()

    assert cat_filter.values.count() == 2

    product = create_product("Just-A-Product-Too", shop, default_price="200")
    shop_product = product.get_shop_instance(shop)
    shop_product.categories.add(cat)
    shop_product.save()

    assert cat_filter.filter_queryset(ShopProduct.objects.all()).exists()  # filter matches
def test_only_cheapest_price_is_selected(rf):
    request, shop, group = initialize_test(rf, False)
    price = shop.create_price

    basket = get_basket(request)
    supplier = get_default_supplier()
     # create a basket rule that requires atleast value of 200
    rule = BasketTotalAmountCondition.objects.create(value="200")

    product_price = "200"

    discount1 = "10"
    discount2 = "20"  # should be selected
    product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=product_price)
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)

    campaign1 = BasketCampaign.objects.create(shop=shop, public_name="test", name="test", active=True)
    campaign1.conditions.add(rule)
    campaign1.save()
    BasketDiscountAmount.objects.create(discount_amount=discount1, campaign=campaign1)

    campaign2 = BasketCampaign.objects.create(shop=shop, public_name="test", name="test", active=True)
    campaign2.conditions.add(rule)
    campaign2.save()
    BasketDiscountAmount.objects.create(discount_amount=discount2, campaign=campaign2)

    assert len(basket.get_final_lines()) == 2

    line_types = [l.type for l in basket.get_final_lines()]
    assert OrderLineType.DISCOUNT in line_types

    for line in basket.get_final_lines():
        if line.type == OrderLineType.DISCOUNT:
            assert line.discount_amount == price(discount2)
def test_category_product_in_basket_condition(rf):
    request, shop, group = initialize_test(rf, False)
    basket = get_basket(request)
    supplier = get_default_supplier()
    category = get_default_category()
    product = create_product("The Product", shop=shop, default_price="200", supplier=supplier)
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)

    shop_product = product.get_shop_instance(shop)
    assert category not in shop_product.categories.all()

    condition = CategoryProductsBasketCondition.objects.create(
        category=category, operator=ComparisonOperator.EQUALS, quantity=1)

    # No match the product does not have the category
    assert not condition.matches(basket, [])

    shop_product.categories.add(category)
    assert condition.matches(basket, [])

    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    assert not condition.matches(basket, [])

    condition.operator = ComparisonOperator.GTE
    condition.save()

    assert condition.matches(basket, [])
def test_product_in_basket_condition_with_variation_parent(rf):
    request, shop, group = initialize_test(rf, False)

    basket = get_basket(request)
    supplier = get_default_supplier()

    product = create_product(
        "test-product", shop, default_price="200", supplier=supplier, mode=ProductMode.SIMPLE_VARIATION_PARENT)

    child_products = []
    for x in range(0, 3):
        child_product = create_product("test-product-%s" % x, shop, default_price="10", supplier=supplier)
        child_product.link_to_parent(product)
        child_products.append(child_product)

    condition = ProductsInBasketCondition.objects.create()
    condition.values = [product]
    condition.operator = ComparisonOperator.EQUALS
    condition.quantity = 3
    condition.save()

    assert not condition.matches(basket, [])

    for child_product in child_products:
        basket.add_product(supplier=supplier, shop=shop, product=child_product, quantity=1)

    assert condition.matches(basket, [])
Esempio n. 17
0
def test_basket_free_product_coupon(rf):
    request, shop, _ = initialize_test(rf, False)

    basket = get_basket(request)
    supplier = get_default_supplier()

    single_product_price = "50"
    discount_amount_value = "10"

    # create basket rule that requires 2 products in basket
    product = create_product(printable_gibberish(),
                             shop=shop,
                             supplier=supplier,
                             default_price=single_product_price)
    basket.add_product(supplier=supplier,
                       shop=shop,
                       product=product,
                       quantity=1)
    basket.add_product(supplier=supplier,
                       shop=shop,
                       product=product,
                       quantity=1)
    basket.shipping_method = get_shipping_method(shop=shop)
    basket.save()

    second_product = create_product(printable_gibberish(),
                                    shop=shop,
                                    supplier=supplier,
                                    default_price=single_product_price)

    rule = BasketTotalProductAmountCondition.objects.create(value="2")
    coupon = Coupon.objects.create(code="TEST", active=True)

    campaign = BasketCampaign.objects.create(active=True,
                                             shop=shop,
                                             name="test",
                                             public_name="test",
                                             coupon=coupon)
    campaign.conditions.add(rule)

    effect = FreeProductLine.objects.create(campaign=campaign)
    effect.products.add(second_product)

    basket.add_code(coupon.code)

    basket.uncache()
    final_lines = basket.get_final_lines()

    assert len(final_lines) == 3

    line_types = [l.type for l in final_lines]
    assert OrderLineType.DISCOUNT not in line_types

    for line in basket.get_final_lines():
        assert line.type in [OrderLineType.PRODUCT, OrderLineType.SHIPPING]
        if line.type == OrderLineType.SHIPPING:
            continue

        if line.product != product:
            assert line.product == second_product
def test_order_creation_adds_usage(rf, admin_user):
    request, shop, group = initialize_test(rf, False)

    source = seed_source(admin_user)
    source.add_line(
        type=OrderLineType.PRODUCT,
        product=get_default_product(),
        supplier=get_default_supplier(),
        quantity=1,
        base_unit_price=source.create_price(10),
    )
    source.add_line(
        type=OrderLineType.OTHER,
        quantity=1,
        base_unit_price=source.create_price(10),
        require_verification=True,
    )

    # add coupon
    coupon = Coupon.objects.create(active=True, code="asdf")

    campaign = BasketCampaign.objects.create(
        active=True,
        shop=shop,
        name="test",
        public_name="test",
        coupon=coupon)
    BasketDiscountPercentage.objects.create(campaign=campaign, discount_percentage="0.1")

    source.add_code(coupon.code)

    creator = OrderCreator()
    creator.create_order(source)

    assert CouponUsage.objects.count() == 1
def test_coupon_uniqueness(rf):
    request, shop, group = initialize_test(rf, False)
    first_campaign = BasketCampaign.objects.create(
        active=True,
        shop=shop,
        name="test",
        public_name="test",
        coupon=None)

    second_campaign = BasketCampaign.objects.create(
        active=True,
        shop=shop,
        name="test1",
        public_name="test1",
        coupon=None)

    BasketDiscountPercentage.objects.create(campaign=first_campaign, discount_percentage="0.1")
    BasketDiscountPercentage.objects.create(campaign=second_campaign, discount_percentage="0.1")

    coupon = Coupon.objects.create(active=True, code="test_code")
    first_campaign.coupon = coupon
    first_campaign.save()

    first_form = BasketCampaignForm(instance=first_campaign, request=request)
    assert len(first_form.fields["coupon"].choices) == 2  # coupon + empty

    second_form = BasketCampaignForm(instance=second_campaign, request=request)
    assert len(second_form.fields["coupon"].choices) == 1  # only empty

    # Can't set coupon for second campaign since coupon is unique
    with pytest.raises(IntegrityError):
        second_campaign.coupon = coupon
        second_campaign.save()
def test_basket_total_amount_conditions(rf):
    request, shop, group = initialize_test(rf, False)

    basket = get_basket(request)
    supplier = get_default_supplier()

    product = create_product("Just-A-Product-Too", shop, default_price="200")
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)

    condition = BasketTotalAmountCondition.objects.create()
    condition.value = 1
    condition.save()
    assert condition.value == 1
    assert condition.matches(basket, [])

    condition2 = BasketMaxTotalAmountCondition.objects.create()
    condition2.value = 200
    condition2.save()

    assert condition2.matches(basket, [])

    condition2.value = 199
    condition2.save()

    assert not condition2.matches(basket, [])
def test_percentage_campaign(rf):
    request, shop, group = initialize_test(rf, False)
    price = shop.create_price

    basket = get_basket(request)
    supplier = get_default_supplier()
    # create a basket rule that requires at least value of 200
    rule = BasketTotalAmountCondition.objects.create(value="200")

    product_price = "200"

    discount_percentage = "0.1"

    expected_discounted_price = price(product_price) - (price(product_price) * Decimal(discount_percentage))

    product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=product_price)
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)

    campaign = BasketCampaign.objects.create(
        shop=shop, public_name="test", name="test", active=True)
    campaign.conditions.add(rule)
    campaign.save()

    BasketDiscountPercentage.objects.create(campaign=campaign, discount_percentage=discount_percentage)

    assert len(basket.get_final_lines()) == 2
    assert basket.product_count == 1
    assert basket.total_price == expected_discounted_price
def test_category_product_in_basket_condition(rf):
    request, shop, group = initialize_test(rf, False)
    basket = get_basket(request)
    supplier = get_default_supplier()
    category = get_default_category()
    product = create_product("The Product", shop=shop, default_price="200", supplier=supplier)
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    basket.shipping_method = get_shipping_method(shop=shop)

    shop_product = product.get_shop_instance(shop)
    assert category not in shop_product.categories.all()

    condition = CategoryProductsBasketCondition.objects.create(operator=ComparisonOperator.EQUALS, quantity=1)
    condition.categories.add(category)

    # No match the product does not have the category
    assert not condition.matches(basket, [])

    category.shop_products.add(shop_product)
    assert condition.matches(basket, [])

    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    assert not condition.matches(basket, [])

    condition.operator = ComparisonOperator.GTE
    condition.save()

    assert condition.matches(basket, [])

    condition.excluded_categories.add(category)
    assert not condition.matches(basket, [])

    with pytest.raises(CampaignsInvalidInstanceForCacheUpdate):
        update_filter_cache("test", shop)
Esempio n. 23
0
def test_productfilter_works(rf):
    request, shop, group = initialize_test(rf, False)
    price = shop.create_price
    product_price = "100"
    discount_percentage = "0.30"

    supplier = get_default_supplier()
    product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=product_price)
    shop_product = product.get_shop_instance(shop)

    # create catalog campaign
    catalog_filter = ProductFilter.objects.create()
    catalog_filter.products.add(product)

    assert catalog_filter.matches(shop_product)

    catalog_campaign = CatalogCampaign.objects.create(shop=shop, active=True, name="test")
    catalog_campaign.filters.add(catalog_filter)
    cdp = ProductDiscountPercentage.objects.create(campaign=catalog_campaign, discount_percentage=discount_percentage)

    # add product to basket
    basket = get_basket(request)
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    basket.shipping_method = get_shipping_method(shop=shop)
    basket.save()

    expected_total = price(product_price) - (Decimal(discount_percentage) * price(product_price))
    assert basket.total_price == expected_total
def test_campaign_all_rules_must_match1(rf):
    activate("en")
    discount_amount = "20.53"
    original_price = "199.20"

    request, shop, group = initialize_test(rf, False)
    cat = Category.objects.create(name="test")
    rule1 = ContactGroupCondition.objects.create()
    rule1.contact_groups = request.customer.groups.all()
    rule1.save()

    rule2 = CategoryFilter.objects.create()
    rule2.categories.add(cat)
    rule2.save()

    campaign = CatalogCampaign.objects.create(shop=shop, name="test", active=True)
    campaign.conditions.add(rule1)
    campaign.filters.add(rule2)
    campaign.save()

    ProductDiscountAmount.objects.create(campaign=campaign, discount_amount=discount_amount)


    product = create_product("Just-A-Product-Too", shop, default_price=original_price)

    price = shop.create_price
    # price should not be discounted because the request.category is faulty
    assert product.get_price_info(request, quantity=1).price == price(original_price)

    shop_product = product.get_shop_instance(shop)
    shop_product.categories.add(cat)
    shop_product.save()
    # now the category is set, so both rules match, disconut should be given
    assert product.get_price_info(request, quantity=1).price == (price(original_price) - price(discount_amount))
Esempio n. 25
0
def test_campaign_creation(rf):
    activate("en")
    request, shop, group = initialize_test(rf, False)
    cat = Category.objects.create(name="test")
    condition = ContactGroupCondition.objects.create()
    condition.contact_groups = request.customer.groups.all()
    condition.save()

    assert condition.values.first() == request.customer.groups.first()

    condition.values = request.customer.groups.all()
    condition.save()
    assert condition.values.first() == request.customer.groups.first()

    category_filter = CategoryFilter.objects.create()
    category_filter.categories.add(cat)
    category_filter.save()

    campaign = CatalogCampaign.objects.create(shop=shop, name="test", active=True)
    campaign.conditions.add(condition)
    campaign.filters.add(category_filter)
    campaign.save()
    ProductDiscountAmount.objects.create(campaign=campaign, discount_amount=20)

    # Make sure disabling campaign disables it filters and conditions
    assert campaign.filters.filter(active=True).exists()
    assert campaign.conditions.filter(active=True).exists()
    campaign.active = False
    campaign.save()
    assert not campaign.filters.filter(active=True).exists()
    assert not campaign.conditions.filter(active=True).exists()
Esempio n. 26
0
def test_basket_campaign_with_multiple_supppliers(rf):
    request, shop, group = initialize_test(rf, False)
    supplier1 = Supplier.objects.create(identifier="1")
    supplier2 = Supplier.objects.create(identifier="2")

    price = shop.create_price
    basket = get_basket(request)
    
    single_product_price = "50"
    discount_amount_supplier1 = "10"
    discount_amount_supplier2 = "40"

    product1 = create_product("product1", shop=shop, supplier=supplier1, default_price=single_product_price)
    product2 = create_product("product2", shop=shop, supplier=supplier2, default_price=single_product_price)

    basket.add_product(supplier=supplier1, shop=shop, product=product1, quantity=1)
    basket.add_product(supplier=supplier2, shop=shop, product=product2, quantity=1)
    basket.shipping_method = get_shipping_method(shop=shop)
    basket.save()

    assert basket.product_count == 2
    assert basket.total_price.value == 100

    # Create campaign for supplier one
    basket_rule1 = ProductsInBasketCondition.objects.create(quantity=1)
    basket_rule1.products.add(product1)

    campaign = BasketCampaign.objects.create(
        shop=shop, public_name="test", name="test", active=True, supplier=supplier1)
    campaign.conditions.add(basket_rule1)
    campaign.save()
    BasketDiscountAmount.objects.create(
        campaign=campaign, discount_amount=discount_amount_supplier1)

    basket.uncache()
    lines = basket.get_final_lines()
    assert len(lines) == 4
    assert basket.total_price.value == 90  # 10d discount from the supplier1 product
    line = _get_discount_line(lines, 10)
    assert line.supplier == supplier1


    # Create campaign for supplier two
    basket_rule2 = ProductsInBasketCondition.objects.create(quantity=1)
    basket_rule2.products.add(product2)

    campaign = BasketCampaign.objects.create(
        shop=shop, public_name="test", name="test", active=True, supplier=supplier2)
    campaign.conditions.add(basket_rule2)
    campaign.save()
    BasketDiscountAmount.objects.create(
        campaign=campaign, discount_amount=discount_amount_supplier2)

    basket.uncache()
    lines = basket.get_final_lines()
    assert len(lines) == 5
    assert basket.total_price.value == 50  # -10d - 40d from 100d
    line = _get_discount_line(lines, 40)
    assert line.supplier == supplier2
Esempio n. 27
0
def test_basket_campaign_with_multiple_supppliers(rf):
    request, shop, group = initialize_test(rf, False)
    supplier1 = Supplier.objects.create(identifier="1")
    supplier2 = Supplier.objects.create(identifier="2")

    price = shop.create_price
    basket = get_basket(request)
    
    single_product_price = "50"
    discount_amount_supplier1 = "10"
    discount_amount_supplier2 = "40"

    product1 = create_product("product1", shop=shop, supplier=supplier1, default_price=single_product_price)
    product2 = create_product("product2", shop=shop, supplier=supplier2, default_price=single_product_price)

    basket.add_product(supplier=supplier1, shop=shop, product=product1, quantity=1)
    basket.add_product(supplier=supplier2, shop=shop, product=product2, quantity=1)
    basket.shipping_method = get_shipping_method(shop=shop)
    basket.save()

    assert basket.product_count == 2
    assert basket.total_price.value == 100

    # Create campaign for supplier one
    basket_rule1 = ProductsInBasketCondition.objects.create(quantity=1)
    basket_rule1.products.add(product1)

    campaign = BasketCampaign.objects.create(
        shop=shop, public_name="test", name="test", active=True, supplier=supplier1)
    campaign.conditions.add(basket_rule1)
    campaign.save()
    BasketDiscountAmount.objects.create(
        campaign=campaign, discount_amount=discount_amount_supplier1)

    basket.uncache()
    lines = basket.get_final_lines()
    assert len(lines) == 4
    assert basket.total_price.value == 90  # 10d discount from the supplier1 product
    line = _get_discount_line(lines, 10)
    assert line.supplier == supplier1


    # Create campaign for supplier two
    basket_rule2 = ProductsInBasketCondition.objects.create(quantity=1)
    basket_rule2.products.add(product2)

    campaign = BasketCampaign.objects.create(
        shop=shop, public_name="test", name="test", active=True, supplier=supplier2)
    campaign.conditions.add(basket_rule2)
    campaign.save()
    BasketDiscountAmount.objects.create(
        campaign=campaign, discount_amount=discount_amount_supplier2)

    basket.uncache()
    lines = basket.get_final_lines()
    assert len(lines) == 5
    assert basket.total_price.value == 50  # -10d - 40d from 100d
    line = _get_discount_line(lines, 40)
    assert line.supplier == supplier2
def test_condition_doesnt_match(rf):
    activate("en")
    request, shop, group = initialize_test(rf, False)
    condition = ContactGroupCondition.objects.create()
    condition.contact_groups = [get_default_customer_group()]
    condition.save()

    request.customer = None

    assert not condition.matches(request)
Esempio n. 29
0
def test_basket_free_product(rf):
    request, shop, _ = initialize_test(rf, False)

    basket = get_basket(request)
    supplier = get_default_supplier()

    single_product_price = "50"
    original_quantity = 2
    # create basket rule that requires 2 products in basket
    product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=single_product_price)
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=2)
    basket.shipping_method = get_shipping_method(shop=shop)
    basket.save()

    second_product = create_product(printable_gibberish(),
                                    shop=shop,
                                    supplier=supplier,
                                    default_price=single_product_price)

    # no shop
    third_product = create_product(printable_gibberish(), supplier=supplier)

    rule = BasketTotalProductAmountCondition.objects.create(value="2")

    campaign = BasketCampaign.objects.create(active=True, shop=shop, name="test", public_name="test")
    campaign.conditions.add(rule)

    effect = FreeProductLine.objects.create(campaign=campaign, quantity=2)
    effect.products.add(second_product)
    discount_lines_count = len(effect.get_discount_lines(basket, [], supplier))
    assert discount_lines_count == 1

    # do not affect as there is no shop product for the product
    effect.products.add(third_product)
    assert len(effect.get_discount_lines(basket, [], supplier)) == discount_lines_count

    basket.uncache()
    final_lines = basket.get_final_lines()

    assert len(final_lines) == 3

    line_types = [l.type for l in final_lines]
    assert OrderLineType.DISCOUNT not in line_types

    for line in basket.get_final_lines():
        assert line.type in [OrderLineType.PRODUCT, OrderLineType.SHIPPING]
        if line.type == OrderLineType.SHIPPING:
            continue
        if line.product != product:
            assert line.product == second_product
            assert line.line_source == LineSource.DISCOUNT_MODULE
            assert line.quantity == original_quantity
        else:
            assert line.line_source == LineSource.CUSTOMER
def test_start_end_dates(rf):
    activate("en")
    original_price = "180"
    discounted_price = "160"
    request, shop, group = initialize_test(rf, False)
    cat = Category.objects.create(name="test")
    rule1, rule2 = create_condition_and_filter(cat, request)

    discount_amount = 20

    campaign = CatalogCampaign.objects.create(shop=shop, name="test", active=True)
    campaign.conditions.add(rule1)
    campaign.save()

    ProductDiscountAmount.objects.create(discount_amount=discount_amount, campaign=campaign)

    price = shop.create_price

    product = create_product("Just-A-Product-Too", shop, default_price=original_price)

    today = now()

    # starts in future
    campaign.start_datetime = (today + datetime.timedelta(days=2))
    campaign.save()
    assert not campaign.is_available()
    assert product.get_price_info(request, quantity=1).price == price(original_price)

    # has already started
    campaign.start_datetime = (today - datetime.timedelta(days=2))
    campaign.save()
    assert product.get_price_info(request, quantity=1).price == price(discounted_price)

    # already ended
    campaign.end_datetime = (today - datetime.timedelta(days=1))
    campaign.save()
    assert not campaign.is_available()
    assert product.get_price_info(request, quantity=1).price == price(original_price)

    # not ended yet
    campaign.end_datetime = (today + datetime.timedelta(days=1))
    campaign.save()
    assert product.get_price_info(request, quantity=1).price == price(discounted_price)

    # no start datetime
    campaign.start_datetime = None
    campaign.save()
    assert product.get_price_info(request, quantity=1).price == price(discounted_price)

    # no start datetime but ended
    campaign.end_datetime = (today - datetime.timedelta(days=1))
    campaign.save()
    assert not campaign.is_available()
    assert product.get_price_info(request, quantity=1).price == price(original_price)
Esempio n. 31
0
def test_undiscounted_effects(rf, include_tax):
    request, shop, _ = initialize_test(rf, include_tax)

    basket = get_basket(request)
    supplier = get_default_supplier()

    single_product_price = Decimal(50)
    discounted_product_quantity = 4
    normal_priced_product_quantity = 2
    discount_percentage = Decimal(0.2)  # 20%
    discount_amount = basket.create_price(single_product_price * normal_priced_product_quantity * discount_percentage)

    category = CategoryFactory()

    discounted_product = create_product(
        printable_gibberish(), shop=shop, supplier=supplier, default_price=single_product_price)
    second_product = create_product(
        printable_gibberish(), shop=shop, supplier=supplier, default_price=single_product_price)

    ShopProduct.objects.get(shop=shop, product=discounted_product).categories.add(category)
    ShopProduct.objects.get(shop=shop, product=second_product).categories.add(category)
    basket.add_product(supplier=supplier, shop=shop, product=discounted_product, quantity=discounted_product_quantity)
    basket.add_product(supplier=supplier, shop=shop, product=second_product, quantity=normal_priced_product_quantity)
    basket.shipping_method = get_shipping_method(shop=shop)
    basket.save()

    # Store basket price before any campaigns exists
    original_price = basket.total_price

    # CatalogCampaign
    catalog_campaign = CatalogCampaign.objects.create(active=True, shop=shop, name="test", public_name="test")
    # Limit catalog campaign to "discounted_product"
    product_filter = ProductFilter.objects.create()
    product_filter.products.add(discounted_product)
    catalog_campaign.filters.add(product_filter)

    # BasketCampaign
    campaign = BasketCampaign.objects.create(
        active=True, shop=shop, name="test2", public_name="test2")

    final_lines = basket.get_final_lines()
    assert len(final_lines) == 3

    # Discount based on undiscounted product values
    DiscountPercentageFromUndiscounted.objects.create(campaign=campaign, discount_percentage=discount_percentage)

    basket.uncache()
    final_lines = basket.get_final_lines()
    assert len(final_lines) == 4

    discounted_basket_price = original_price - discount_amount
    assert basket.total_price.as_rounded() == discounted_basket_price.as_rounded()
Esempio n. 32
0
def test_multiple_campaigns_match_with_coupon(rf):
    request, shop, group = initialize_test(rf, False)
    price = shop.create_price

    basket = get_basket(request)
    supplier = get_default_supplier()
    # create a basket rule that requires atleast value of 200
    rule = BasketTotalAmountCondition.objects.create(value="200")

    product_price = "200"

    discount1 = "10"
    discount2 = "20"
    product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=product_price)
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    basket.shipping_method = get_shipping_method(shop=shop)

    campaign = BasketCampaign.objects.create(shop=shop, public_name="test", name="test", active=True)
    campaign.conditions.add(rule)
    campaign.save()

    BasketDiscountAmount.objects.create(discount_amount=discount1, campaign=campaign)

    dc = Coupon.objects.create(code="TEST", active=True)
    campaign2 = BasketCampaign.objects.create(
        shop=shop, public_name="test",
        name="test",
        coupon=dc,
        active=True
    )

    BasketDiscountAmount.objects.create(discount_amount=discount2, campaign=campaign2)
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)

    resp = handle_add_campaign_code(request, basket, dc.code)
    assert resp.get("ok")

    discount_lines_values = [line.discount_amount for line in basket.get_final_lines() if line.type == OrderLineType.DISCOUNT]
    assert price(discount1) in discount_lines_values
    assert price(discount2) in discount_lines_values
    assert basket.total_price == (price(product_price) * basket.product_count - price(discount1) - price(discount2))

    assert basket.codes == [dc.code]

    # test code removal
    resp = handle_remove_campaign_code(request, basket, dc.code)
    assert resp.get("ok")

    assert basket.codes == []
    discount_lines_values = [line.discount_amount for line in basket.get_final_lines() if line.type == OrderLineType.DISCOUNT]
    assert price(discount1) in discount_lines_values
    assert not price(discount2) in discount_lines_values
def test_availability(rf):
    activate("en")
    request, shop, group = initialize_test(rf, False)
    cat = Category.objects.create(name="test")
    rule1, rule2 = create_condition_and_filter(cat, request)
    discount_amount = "20"
    campaign = CatalogCampaign.objects.create(shop=shop, name="test", active=False)
    campaign.conditions.add(rule1)
    campaign.save()

    ProductDiscountAmount.objects.create(discount_amount=discount_amount, campaign=campaign)


    assert not campaign.is_available()
Esempio n. 34
0
def test_filter_caching(rf):
    request, shop, group = initialize_test(rf, False)
    price = shop.create_price
    product_price = "100"
    discount_percentage = "0.30"

    supplier = get_default_supplier()
    product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=product_price)
    product2 = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=product_price)

    assert product.pk != product2.pk  # ensure they're different

    # create catalog campaign
    catalog_filter = ProductFilter.objects.create()
    catalog_filter.products.add(product)


    catalog_campaign = CatalogCampaign.objects.create(shop=shop, active=True, name="test")
    catalog_campaign.filters.add(catalog_filter)
    assert CatalogFilterCachedShopProduct.objects.count() == 1
    catalog_campaign.save()
    assert CatalogFilterCachedShopProduct.objects.count() == 1

    entry = CatalogFilterCachedShopProduct.objects.first()
    assert entry.pk == get_matching_catalog_filters(product.get_shop_instance(shop))[0]

    # create another campaign
    catalog_filter2 = ProductFilter.objects.create()
    catalog_filter2.products.add(product2)
    catalog_campaign2 = CatalogCampaign.objects.create(shop=shop, active=True, name="test")
    catalog_campaign2.filters.add(catalog_filter2)
    assert CatalogFilterCachedShopProduct.objects.count() == 2
    catalog_campaign2.save()
    assert CatalogFilterCachedShopProduct.objects.count() == 2  # new cache for this product was created

    entry = CatalogFilterCachedShopProduct.objects.last()
    assert entry.pk == get_matching_catalog_filters(product2.get_shop_instance(shop))[0]

    # third campaign
    catalog_filter3 = ProductFilter.objects.create()
    catalog_filter3.products.add(product2)
    catalog_campaign3 = CatalogCampaign.objects.create(shop=shop, active=True, name="test")
    catalog_campaign3.filters.add(catalog_filter3)
    assert CatalogFilterCachedShopProduct.objects.count() == 3
    catalog_campaign3.save()
    assert CatalogFilterCachedShopProduct.objects.count() == 3  # new one for this filter again

    expected = get_matching_catalog_filters(product2.get_shop_instance(shop))
    for id in expected:
        assert id in [catalog_filter2.pk, catalog_filter3.pk]
Esempio n. 35
0
def test_basket_category_discount(rf):
    """
    Test that discounting based on product category works.
    """

    request, shop, group = initialize_test(rf, False)
    price = shop.create_price

    basket = get_basket(request)
    supplier = get_default_supplier()

    category = CategoryFactory()

    discount_amount_value = 6
    single_product_price = 10

    def create_category_product(category):
        product = create_product(printable_gibberish(), shop, supplier, single_product_price)
        product.primary_category = category

        sp = ShopProduct.objects.get(product=product, shop=shop)
        sp.primary_category = category
        sp.categories.add(category)

        return product

    basket_condition = CategoryProductsBasketCondition.objects.create(quantity=2)
    basket_condition.categories.add(category)

    campaign = BasketCampaign.objects.create(
        shop=shop, public_name="test", name="test", active=True
    )
    campaign.conditions.add(basket_condition)
    campaign.save()

    DiscountFromCategoryProducts.objects.create(
        campaign=campaign, discount_amount=discount_amount_value, category=category
    )
    basket.save()

    products = [create_category_product(category) for i in range(2)]
    for product in products:
        basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
        basket.shipping_method = get_shipping_method(shop=shop)
    basket.save()

    assert basket.product_count == 2
    assert basket_condition.matches(basket=basket, lines=basket.get_lines())
    assert campaign.rules_match(basket, basket.get_lines())
    assert basket.total_price == price(single_product_price * 2) - price(discount_amount_value * 2)
Esempio n. 36
0
def test_product_category_discount_amount_with_minimum_price(rf):
    # Buy X amount of Y get Z discount from Y
    request, shop, _ = initialize_test(rf, False)

    basket = get_basket(request)
    supplier = get_default_supplier()

    single_product_price = Decimal("50")
    single_product_min_price = Decimal("40")
    discount_amount_value = Decimal("200") # will exceed the minimum price
    quantity = 2

    # the expected discount amount should not be greater than the products
    expected_discount_amount = basket.create_price(single_product_price) * quantity

    category = CategoryFactory()

     # create basket rule that requires 2 products in basket
    product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=single_product_price)
    shop_product = ShopProduct.objects.get(shop=shop, product=product)
    shop_product.minimum_price_value = single_product_min_price
    shop_product.save()
    shop_product.categories.add(category)

    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=quantity)
    basket.shipping_method = get_shipping_method(shop=shop)
    basket.save()

    rule = ProductsInBasketCondition.objects.create(quantity=2)
    rule.products.add(product)
    rule.save()

    campaign = BasketCampaign.objects.create(active=True, shop=shop, name="test", public_name="test")
    campaign.conditions.add(rule)

    DiscountFromCategoryProducts.objects.create(campaign=campaign,
                                                discount_amount=discount_amount_value,
                                                category=category)
    assert rule.matches(basket, [])
    basket.uncache()

    # the discount amount should not exceed the minimum price. as the configued discount
    # will exceed, it should limit the discount amount
    final_lines = basket.get_final_lines()
    expected_discount_amount = basket.create_price((single_product_price - single_product_min_price) * quantity)
    original_price = basket.create_price(single_product_price) * quantity
    line = final_lines[0]
    assert line.discount_amount == expected_discount_amount
    assert basket.total_price == original_price - expected_discount_amount
Esempio n. 37
0
def test_basket_free_product_coupon(rf):
    request, shop, _ = initialize_test(rf, False)

    basket = get_basket(request)
    supplier = get_default_supplier()

    single_product_price = "50"
    discount_amount_value = "10"

     # create basket rule that requires 2 products in basket
    product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=single_product_price)
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    basket.shipping_method = get_shipping_method(shop=shop)
    basket.save()

    second_product = create_product(printable_gibberish(),
                                    shop=shop,
                                    supplier=supplier,
                                    default_price=single_product_price)

    rule = BasketTotalProductAmountCondition.objects.create(value="2")
    coupon = Coupon.objects.create(code="TEST", active=True)

    campaign = BasketCampaign.objects.create(active=True, shop=shop, name="test", public_name="test", coupon=coupon)
    campaign.conditions.add(rule)

    effect = FreeProductLine.objects.create(campaign=campaign)
    effect.products.add(second_product)

    basket.add_code(coupon.code)

    basket.uncache()
    final_lines = basket.get_final_lines()

    assert len(final_lines) == 3

    line_types = [l.type for l in final_lines]
    assert OrderLineType.DISCOUNT not in line_types

    for line in basket.get_final_lines():
        assert line.type in [OrderLineType.PRODUCT, OrderLineType.SHIPPING]
        if line.type == OrderLineType.SHIPPING:
            continue

        if line.product != product:
            assert line.product == second_product
def test_basket_campaign_case2(rf):
    request, shop, group = initialize_test(rf, False)
    price = shop.create_price

    basket = get_basket(request)
    supplier = get_default_supplier()
     # create a basket rule that requires at least value of 200
    rule = BasketTotalAmountCondition.objects.create(value="200")

    single_product_price = "50"
    discount_amount_value = "10"

    unique_shipping_method = get_shipping_method(shop, price=50)

    for x in range(3):
        product = create_product(
            printable_gibberish(), shop=shop, supplier=supplier, default_price=single_product_price)
        basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)

    assert basket.product_count == 3

    campaign = BasketCampaign.objects.create(
        shop=shop, public_name="test", name="test", active=True)
    campaign.conditions.add(rule)
    campaign.save()

    BasketDiscountAmount.objects.create(discount_amount=discount_amount_value, campaign=campaign)

    assert len(basket.get_final_lines()) == 3
    assert basket.total_price == price(single_product_price) * basket.product_count

    # check that shipping method affects campaign
    basket.shipping_method = unique_shipping_method
    basket.save()
    basket.uncache()
    assert len(basket.get_final_lines()) == 4  # Shipping should not affect the rule being triggered

    line_types = [l.type for l in basket.get_final_lines()]
    assert OrderLineType.DISCOUNT not in line_types

    product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=single_product_price)
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)

    assert len(basket.get_final_lines()) == 6  # Discount included
    assert OrderLineType.DISCOUNT in [l.type for l in basket.get_final_lines()]