def test_price_infos(rf):
    request, shop, group = initialize_test(rf, True)
    price = shop.create_price

    product_one = create_product("Product_1", shop, default_price=150)
    product_two = create_product("Product_2", shop, default_price=250)

    spp = CgpPrice(product=product_one, shop=shop, group=group, price_value=100)
    spp.save()

    spp = CgpPrice(product=product_two, shop=shop, group=group, price_value=200)
    spp.save()

    product_ids = [product_one.pk, product_two.pk]

    spm = get_pricing_module()
    assert isinstance(spm, CustomerGroupPricingModule)
    pricing_context = spm.get_context_from_request(request)
    price_infos = spm.get_price_infos(pricing_context, product_ids)

    assert len(price_infos) == 2
    assert product_one.pk in price_infos
    assert product_two.pk in price_infos

    assert price_infos[product_one.pk].price == price(100)
    assert price_infos[product_two.pk].price == price(200)

    assert price_infos[product_one.pk].base_price == price(100)
    assert price_infos[product_two.pk].base_price == price(200)
def test_price_info_cache_bump(rf):
    request, shop, group = initialize_test(rf, True)

    product_one = create_product("Product_1", shop, default_price=150)
    product_two = create_product("Product_2", shop, default_price=250)

    contact = create_customer()
    group2 = ContactGroup.objects.create(name="Group 2", shop=shop)

    cgp_price = CgpPrice.objects.create(product=product_one, shop=shop, group=group, price_value=100)
    cgp_discount = CgpDiscount.objects.create(product=product_two, shop=shop, group=group, discount_amount_value=200)

    spm = get_pricing_module()
    assert isinstance(spm, CustomerGroupPricingModule)
    pricing_context = spm.get_context_from_request(request)

    for function in [
        lambda: cgp_price.save(),
        lambda: cgp_discount.save(),
        lambda: group2.members.add(contact),
        lambda: cgp_price.delete(),
        lambda: cgp_discount.delete()
    ]:
        cache_price_info(pricing_context, product_one, 1, product_one.get_price_info(pricing_context))
        cache_price_info(pricing_context, product_two, 1, product_two.get_price_info(pricing_context))

        # prices are cached
        assert get_cached_price_info(pricing_context, product_one)
        assert get_cached_price_info(pricing_context, product_two)

        # caches should be bumped
        function()
        assert get_cached_price_info(pricing_context, product_one) is None
        assert get_cached_price_info(pricing_context, product_two) is None
def test_price_infos(rf):
    request, shop, group = initialize_test(rf, True)
    price = shop.create_price

    product_one = create_product("Product_1", shop, default_price=150)
    product_two = create_product("Product_2", shop, default_price=250)

    spp = CgpPrice(product=product_one,
                   shop=shop,
                   group=group,
                   price_value=100)
    spp.save()

    spp = CgpPrice(product=product_two,
                   shop=shop,
                   group=group,
                   price_value=200)
    spp.save()

    product_ids = [product_one.pk, product_two.pk]

    spm = get_pricing_module()
    assert isinstance(spm, CustomerGroupPricingModule)
    pricing_context = spm.get_context_from_request(request)
    price_infos = spm.get_price_infos(pricing_context, product_ids)

    assert len(price_infos) == 2
    assert product_one.pk in price_infos
    assert product_two.pk in price_infos

    assert price_infos[product_one.pk].price == price(100)
    assert price_infos[product_two.pk].price == price(200)

    assert price_infos[product_one.pk].base_price == price(100)
    assert price_infos[product_two.pk].base_price == price(200)
def test_price_info_cache_bump(rf):
    request, shop, group = initialize_test(rf, True)

    product_one = create_product("Product_1", shop, default_price=150)
    product_two = create_product("Product_2", shop, default_price=250)

    contact = create_customer()
    group2 = ContactGroup.objects.create(name="Group 2", shop=shop)

    cgp_price = CgpPrice.objects.create(product=product_one, shop=shop, group=group, price_value=100)
    cgp_discount = CgpDiscount.objects.create(product=product_two, shop=shop, group=group, discount_amount_value=200)

    spm = get_pricing_module()
    assert isinstance(spm, CustomerGroupPricingModule)
    pricing_context = spm.get_context_from_request(request)

    for function in [
        lambda: cgp_price.save(),
        lambda: cgp_discount.save(),
        lambda: group2.members.add(contact),
        lambda: cgp_price.delete(),
        lambda: cgp_discount.delete()
    ]:
        cache_price_info(pricing_context, product_one, 1, product_one.get_price_info(pricing_context))
        cache_price_info(pricing_context, product_two, 1, product_two.get_price_info(pricing_context))

        # prices are cached
        assert get_cached_price_info(pricing_context, product_one)
        assert get_cached_price_info(pricing_context, product_two)

        # caches should be bumped
        function()
        assert get_cached_price_info(pricing_context, product_one) is None
        assert get_cached_price_info(pricing_context, product_two) is None
Example #5
0
def test_complex_order_tax(include_taxes):
    tax = get_default_tax()
    quantities = [44, 23, 65]
    product = get_default_product()
    supplier = get_default_supplier()
    shop = get_default_shop()
    shop.prices_include_tax = include_taxes
    shop.save()

    order = create_empty_order(shop=shop)
    order.full_clean()
    order.save()

    pricing_context = get_pricing_module().get_context_from_data(
        shop=shop,
        customer=order.customer or AnonymousContact(),
    )

    total_price = Decimal("0")
    price = Decimal("50")

    for quantity in quantities:
        total_price += quantity * price
        add_product_to_order(order, supplier, product, quantity, price, tax.rate, pricing_context)
    order.cache_prices()
    order.save()

    currency = "EUR"
    summary = order.get_tax_summary()[0]

    assert summary.tax_rate == tax.rate
    assert summary.based_on == Money(total_price, currency)
    assert summary.tax_amount == Money(total_price * tax.rate, currency)
    assert summary.taxful == summary.based_on + summary.tax_amount
    assert order.get_total_tax_amount() == Money(total_price * tax.rate, currency)
Example #6
0
def test_complex_order_tax(include_taxes):
    tax = get_default_tax()
    quantities = [44, 23, 65]
    product = get_default_product()
    supplier = get_default_supplier()
    shop = get_default_shop()
    shop.prices_include_tax = include_taxes
    shop.save()

    order = create_empty_order(shop=shop)
    order.full_clean()
    order.save()

    pricing_context = get_pricing_module().get_context_from_data(
        shop=shop,
        customer=order.customer or AnonymousContact(),
    )

    total_price = Decimal("0")
    price = Decimal("50")

    for quantity in quantities:
        total_price += quantity * price
        add_product_to_order(order, supplier, product, quantity, price, tax.rate, pricing_context)
    order.cache_prices()
    order.save()

    currency = "EUR"
    summary = order.get_tax_summary()[0]

    assert summary.tax_rate == tax.rate
    assert summary.based_on == Money(total_price, currency)
    assert summary.tax_amount == Money(total_price * tax.rate, currency)
    assert summary.taxful == summary.based_on + summary.tax_amount
    assert order.get_total_tax_amount() == Money(total_price * tax.rate, currency)
Example #7
0
def test_supplier_price_without_selected_supplier(rf):
    shop = factories.get_shop()

    supplier1 = Supplier.objects.create(name="Test 1")
    supplier1.shops.add(shop)
    supplier2 = Supplier.objects.create(name="Test 2")
    supplier2.shops.add(shop)

    strategy = "shuup.testing.supplier_pricing.supplier_strategy:CheapestSupplierPriceSupplierStrategy"
    with override_settings(SHUUP_PRICING_MODULE="supplier_pricing",
                           SHUUP_SHOP_PRODUCT_SUPPLIERS_STRATEGY=strategy):
        customer = AnonymousContact()
        pricing_mod = get_pricing_module()
        supplier1_ctx = pricing_mod.get_context_from_data(shop,
                                                          customer,
                                                          supplier=supplier1)
        supplier2_ctx = pricing_mod.get_context_from_data(shop,
                                                          customer,
                                                          supplier=supplier2)

        # Supplied by both suppliers
        product1_default_price = 10
        product1 = factories.create_product(
            "sku1",
            shop=shop,
            supplier=supplier1,
            default_price=product1_default_price)
        shop_product1 = product1.get_shop_instance(shop)
        shop_product1.suppliers.add(supplier2)

        # Both suppliers should get price from shop
        # product default price
        assert product1.get_price(
            supplier1_ctx).amount.value == product1_default_price
        assert product1.get_price(
            supplier2_ctx).amount.value == product1_default_price

        # Now let's add per supplier prices
        supplier1_price = 7
        supplier2_price = 8
        SupplierPrice.objects.create(shop=shop,
                                     supplier=supplier1,
                                     product=product1,
                                     amount_value=supplier1_price)
        SupplierPrice.objects.create(shop=shop,
                                     supplier=supplier2,
                                     product=product1,
                                     amount_value=supplier2_price)

        assert product1.get_price(
            supplier1_ctx).amount.value == supplier1_price
        assert product1.get_price(
            supplier2_ctx).amount.value == supplier2_price

        # Now pricing context without defined supplier
        # should return cheapest price
        context = pricing_mod.get_context_from_data(shop, customer)
        assert shop_product1.get_supplier().pk == supplier1.pk
        assert product1.get_price(context).amount.value == supplier1_price
Example #8
0
    def index_shop_product(cls, shop_product: Union[Product, int], **kwargs):
        """
        Index the prices for the given `shop_product`
        which can be either a ShopProduct instance or a shop product ID.

        This method will forward the indexing for the default pricing module
        and then trigger a signal for other apps to do their job if they need.
        """
        pricing_module = get_pricing_module()
        pricing_module.index_shop_product(shop_product)
        for discount_module in get_discount_modules():
            discount_module.index_shop_product(shop_product)
        index_catalog_shop_product.send(sender=cls, shop_product=shop_product)
Example #9
0
def get_price_info(shop, customer, product, quantity):
    """
    Get price info of given product for given context parameters.

    :type shop: shuup.core.models.Shop
    :type customer: shuup.core.models.Contact
    :type product: shuup.core.models.Product
    :type quantity: numbers.Number
    """
    pricing_mod = get_pricing_module()
    pricing_ctx = pricing_mod.get_context_from_data(
        shop=shop,
        customer=(customer or AnonymousContact()),
    )
    return product.get_price_info(pricing_ctx, quantity=quantity)
def _get_custom_order(regular_user, **kwargs):
    prices_include_tax = kwargs.pop("prices_include_tax", False)
    include_basket_campaign = kwargs.pop("include_basket_campaign", False)
    include_catalog_campaign = kwargs.pop("include_catalog_campaign", False)

    shop = get_shop(prices_include_tax=prices_include_tax)
    supplier = get_simple_supplier()

    if include_basket_campaign:
        _add_basket_campaign(shop)

    if include_catalog_campaign:
        _add_catalog_campaign(shop)
    _add_taxes()

    contact = get_person_contact(regular_user)
    source = BasketishOrderSource(shop)
    source.status = get_initial_order_status()
    source.customer = contact

    ctx = get_pricing_module().get_context_from_data(shop, contact)
    for product_data in _get_product_data():
        quantity = product_data.pop("quantity")
        product = create_product(
            sku=product_data.pop("sku"),
            shop=shop,
            supplier=supplier,
            stock_behavior=StockBehavior.STOCKED,
            tax_class=get_default_tax_class(),
            **product_data)
        shop_product = product.get_shop_instance(shop)
        shop_product.categories.add(get_default_category())
        shop_product.save()
        supplier.adjust_stock(product.id, INITIAL_PRODUCT_QUANTITY)
        pi = product.get_price_info(ctx)
        source.add_line(
            type=OrderLineType.PRODUCT,
            product=product,
            supplier=supplier,
            quantity=quantity,
            base_unit_price=pi.base_unit_price,
            discount_amount=pi.discount_amount
        )

    oc = OrderCreator()
    order = oc.create_order(source)
    return order
def _get_custom_order(regular_user, **kwargs):
    prices_include_tax = kwargs.pop("prices_include_tax", False)
    include_basket_campaign = kwargs.pop("include_basket_campaign", False)
    include_catalog_campaign = kwargs.pop("include_catalog_campaign", False)

    shop = get_shop(prices_include_tax=prices_include_tax)
    supplier = get_simple_supplier()

    if include_basket_campaign:
        _add_basket_campaign(shop)

    if include_catalog_campaign:
        _add_catalog_campaign(shop)
    _add_taxes()

    contact = get_person_contact(regular_user)
    source = BasketishOrderSource(shop)
    source.status = get_initial_order_status()
    source.customer = contact

    ctx = get_pricing_module().get_context_from_data(shop, contact)
    for product_data in _get_product_data():
        quantity = product_data.pop("quantity")
        product = create_product(
            sku=product_data.pop("sku"),
            shop=shop,
            supplier=supplier,
            stock_behavior=StockBehavior.STOCKED,
            tax_class=get_default_tax_class(),
            **product_data)
        shop_product = product.get_shop_instance(shop)
        shop_product.categories.add(get_default_category())
        shop_product.save()
        supplier.adjust_stock(product.id, INITIAL_PRODUCT_QUANTITY)
        pi = product.get_price_info(ctx)
        source.add_line(
            type=OrderLineType.PRODUCT,
            product=product,
            supplier=supplier,
            quantity=quantity,
            base_unit_price=pi.base_unit_price,
            discount_amount=pi.discount_amount
        )

    oc = OrderCreator()
    order = oc.create_order(source)
    return order
Example #12
0
def _get_order(prices_include_tax=False,
               include_basket_campaign=False,
               include_catalog_campaign=False):
    shop = get_shop(prices_include_tax=prices_include_tax)
    supplier = get_simple_supplier()

    if "shuup.campaigns" in settings.INSTALLED_APPS:
        from shuup.campaigns.models.basket_conditions import BasketTotalProductAmountCondition
        from shuup.campaigns.models.basket_effects import BasketDiscountAmount
        from shuup.campaigns.models.campaigns import BasketCampaign, CatalogCampaign
        from shuup.campaigns.models.catalog_filters import CategoryFilter
        from shuup.campaigns.models.product_effects import ProductDiscountAmount

        if include_basket_campaign:
            _add_basket_campaign(shop)

        if include_catalog_campaign:
            _add_catalog_campaign(shop)
    _add_taxes()

    source = BasketishOrderSource(shop)
    source.status = get_initial_order_status()
    ctx = get_pricing_module().get_context_from_data(shop, AnonymousContact())
    for product_data in _get_product_data():
        quantity = product_data.pop("quantity")
        product = create_product(sku=product_data.pop("sku"),
                                 shop=shop,
                                 supplier=supplier,
                                 stock_behavior=StockBehavior.STOCKED,
                                 tax_class=get_default_tax_class(),
                                 **product_data)
        shop_product = product.get_shop_instance(shop)
        shop_product.categories.add(get_default_category())
        shop_product.save()
        supplier.adjust_stock(product.id, INITIAL_PRODUCT_QUANTITY)
        pi = product.get_price_info(ctx)
        source.add_line(type=OrderLineType.PRODUCT,
                        product=product,
                        supplier=supplier,
                        quantity=quantity,
                        base_unit_price=pi.base_unit_price,
                        discount_amount=pi.discount_amount)
    oc = OrderCreator()
    order = oc.create_order(source)
    return order
Example #13
0
def _get_order(prices_include_tax=False, include_basket_campaign=False, include_catalog_campaign=False):
    shop = get_shop(prices_include_tax=prices_include_tax)
    supplier = get_simple_supplier()

    if include_basket_campaign:
        _add_basket_campaign(shop)

    if include_catalog_campaign:
        _add_catalog_campaign(shop)
    _add_taxes()

    source = BasketishOrderSource(shop)
    source.status = get_initial_order_status()
    ctx = get_pricing_module().get_context_from_data(shop, AnonymousContact())
    for product_data in _get_product_data():
        quantity = product_data.pop("quantity")
        product = create_product(
            sku=product_data.pop("sku"),
            shop=shop,
            supplier=supplier,
            stock_behavior=StockBehavior.STOCKED,
            tax_class=get_default_tax_class(),
            **product_data)
        shop_product = product.get_shop_instance(shop)
        shop_product.categories.add(get_default_category())
        shop_product.save()
        supplier.adjust_stock(product.id, INITIAL_PRODUCT_QUANTITY)
        pi = product.get_price_info(ctx)
        source.add_line(
            type=OrderLineType.PRODUCT,
            product=product,
            supplier=supplier,
            quantity=quantity,
            base_unit_price=pi.base_unit_price,
            discount_amount=pi.discount_amount
        )
    oc = OrderCreator()
    order = oc.create_order(source)
    order.create_payment(Money("1", "EUR"))
    assert not order.has_refunds()
    assert order.can_create_refund()
    assert order.shipping_status == ShippingStatus.NOT_SHIPPED
    assert order.payment_status == PaymentStatus.PARTIALLY_PAID
    return order
Example #14
0
def _get_order(prices_include_tax=False, include_basket_campaign=False, include_catalog_campaign=False):
    shop = get_shop(prices_include_tax=prices_include_tax)
    supplier = get_simple_supplier()

    if include_basket_campaign:
        _add_basket_campaign(shop)

    if include_catalog_campaign:
        _add_catalog_campaign(shop)
    _add_taxes()

    source = BasketishOrderSource(shop)
    source.status = get_initial_order_status()
    ctx = get_pricing_module().get_context_from_data(shop, AnonymousContact())
    for product_data in _get_product_data():
        quantity = product_data.pop("quantity")
        product = create_product(
            sku=product_data.pop("sku"),
            shop=shop,
            supplier=supplier,
            stock_behavior=StockBehavior.STOCKED,
            tax_class=get_default_tax_class(),
            **product_data)
        shop_product = product.get_shop_instance(shop)
        shop_product.categories.add(get_default_category())
        shop_product.save()
        supplier.adjust_stock(product.id, INITIAL_PRODUCT_QUANTITY)
        pi = product.get_price_info(ctx)
        source.add_line(
            type=OrderLineType.PRODUCT,
            product=product,
            supplier=supplier,
            quantity=quantity,
            base_unit_price=pi.base_unit_price,
            discount_amount=pi.discount_amount
        )
    oc = OrderCreator()
    order = oc.create_order(source)
    order.create_payment(Money("1", "EUR"))
    assert not order.has_refunds()
    assert order.can_create_refund()
    assert order.shipping_status == ShippingStatus.NOT_SHIPPED
    assert order.payment_status == PaymentStatus.PARTIALLY_PAID
    return order
Example #15
0
def test_pricing_module_is_active():
    """
    Make sure that our custom pricing module is active.
    """
    shop = Shop(currency="USD", prices_include_tax=False)
    customer = AnonymousContact()
    product = Product(sku="6.0745")

    pricing_mod = get_pricing_module()
    pricing_ctx = pricing_mod.get_context_from_data(shop, customer)

    pi = product.get_price_info(pricing_ctx, quantity=2)

    price = shop.create_price
    assert pi.price == price("12.149")
    assert pi.base_price == price("48.596")
    assert pi.quantity == 2
    assert pi.discounted_unit_price == price("6.0745")
    assert pi.base_unit_price == price("24.298")
    assert pi.discount_rate == Decimal("0.75")
Example #16
0
def test_pricing_module_is_active():
    """
    Make sure that our custom pricing module is active.
    """
    shop = Shop(currency='USD', prices_include_tax=False)
    customer = AnonymousContact()
    product = Product(sku='6.0745')

    pricing_mod = get_pricing_module()
    pricing_ctx = pricing_mod.get_context_from_data(shop, customer)

    pi = product.get_price_info(pricing_ctx, quantity=2)

    price = shop.create_price
    assert pi.price == price('12.149')
    assert pi.base_price == price('48.596')
    assert pi.quantity == 2
    assert pi.discounted_unit_price == price('6.0745')
    assert pi.base_unit_price == price('24.298')
    assert pi.discount_rate == Decimal('0.75')
Example #17
0
def _get_pricing_context(shop, customer=None):
    return get_pricing_module().get_context_from_data(
        shop=shop,
        customer=(customer or AnonymousContact()),
    )
Example #18
0
def _get_pricing_context(shop, customer=None):
    return get_pricing_module().get_context_from_data(
        shop=shop,
        customer=(customer or AnonymousContact()),
    )
def test_module_is_active():
    """
    Check that CustomerGroupPricingModule is active.
    """
    module = get_pricing_module()
    assert isinstance(module, CustomerGroupPricingModule)
Example #20
0
def test_module_is_active():  # this test is because we want to make sure `CustomerGroupPricing` is active
    module = get_pricing_module()
    assert isinstance(module, DefaultPricingModule)
def test_module_is_active():
    """
    Check that CustomerGroupPricingModule is active.
    """
    module = get_pricing_module()
    assert isinstance(module, CustomerGroupPricingModule)
Example #22
0
def test_module_is_active(
):  # this test is because we want to make sure `CustomerGroupPricing` is active
    module = get_pricing_module()
    assert isinstance(module, DefaultPricingModule)