示例#1
0
def test_quantize():
    price1 = TaxedMoney(Money(10, 'EUR'), Money(15, 'EUR'))
    price2 = TaxedMoney(Money(30, 'EUR'), Money(45, 'EUR'))
    price_range = TaxedMoneyRange(price1, price2)
    result = price_range.quantize()
    assert str(result.start.net.amount) == '10.00'
    assert str(result.stop.net.amount) == '30.00'
示例#2
0
def test_quantize():
    price1 = TaxedMoney(Money(10, 'EUR'), Money(15, 'EUR'))
    price2 = TaxedMoney(Money(30, 'EUR'), Money(45, 'EUR'))
    price_range = TaxedMoneyRange(price1, price2)
    result = price_range.quantize()
    assert str(result.start.net.amount) == '10.00'
    assert str(result.stop.net.amount) == '30.00'
示例#3
0
def test_construction():
    price1 = TaxedMoney(Money(10, 'EUR'), Money(15, 'EUR'))
    price2 = TaxedMoney(Money(30, 'EUR'), Money(45, 'EUR'))
    price_range = TaxedMoneyRange(price1, price2)
    assert price_range.start == price1
    assert price_range.stop == price2
    with pytest.raises(ValueError):
        TaxedMoneyRange(price1, TaxedMoney(Money(20, 'PLN'), Money(20, 'PLN')))
    with pytest.raises(ValueError):
        TaxedMoneyRange(price2, price1)
示例#4
0
 def get_price_range(self, discounts=None):
     if self.variants.exists():
         prices = [
             self.get_price_per_item(variant, discounts=discounts)
             for variant in self
         ]
         return TaxedMoneyRange(min(prices), max(prices))
     price = TaxedMoney(net=self.price, gross=self.price)
     discounted_price = calculate_discounted_price(self, price, discounts)
     return TaxedMoneyRange(start=discounted_price, stop=discounted_price)
def get_product_availability(
    *,
    product: Product,
    variants: Iterable[ProductVariant],
    collections: Iterable[Collection],
    discounts: Iterable[DiscountInfo],
    country: Optional[str] = None,
    local_currency: Optional[str] = None,
    plugins: Optional["PluginsManager"] = None,
) -> ProductAvailability:
    with opentracing.global_tracer().start_active_span(
            "get_product_availability"):
        if not plugins:
            plugins = get_plugins_manager()
        discounted_net_range = get_product_price_range(
            product=product,
            variants=variants,
            collections=collections,
            discounts=discounts,
        )
        undiscounted_net_range = get_product_price_range(
            product=product,
            variants=variants,
            collections=collections,
            discounts=[])
        discounted = TaxedMoneyRange(
            start=plugins.apply_taxes_to_product(product,
                                                 discounted_net_range.start,
                                                 country),
            stop=plugins.apply_taxes_to_product(product,
                                                discounted_net_range.stop,
                                                country),
        )
        undiscounted = TaxedMoneyRange(
            start=plugins.apply_taxes_to_product(product,
                                                 undiscounted_net_range.start,
                                                 country),
            stop=plugins.apply_taxes_to_product(product,
                                                undiscounted_net_range.stop,
                                                country),
        )

        discount = _get_total_discount_from_range(undiscounted, discounted)
        price_range_local, discount_local_currency = _get_product_price_range(
            discounted, undiscounted, local_currency)

        is_on_sale = product.is_visible and discount is not None
        return ProductAvailability(
            on_sale=is_on_sale,
            price_range=discounted,
            price_range_undiscounted=undiscounted,
            discount=discount,
            price_range_local_currency=price_range_local,
            discount_local_currency=discount_local_currency,
        )
示例#6
0
def test_replace():
    price1 = TaxedMoney(Money(10, 'EUR'), Money(15, 'EUR'))
    price2 = TaxedMoney(Money(30, 'EUR'), Money(45, 'EUR'))
    price3 = TaxedMoney(Money(20, 'EUR'), Money(30, 'EUR'))
    price_range = TaxedMoneyRange(price1, price2)
    result = price_range.replace(stop=price3)
    assert result.start == price1
    assert result.stop == price3
    result = price_range.replace(start=price3)
    assert result.start == price3
    assert result.stop == price2
示例#7
0
def test_replace():
    price1 = TaxedMoney(Money(10, 'EUR'), Money(15, 'EUR'))
    price2 = TaxedMoney(Money(30, 'EUR'), Money(45, 'EUR'))
    price3 = TaxedMoney(Money(20, 'EUR'), Money(30, 'EUR'))
    price_range = TaxedMoneyRange(price1, price2)
    result = price_range.replace(stop=price3)
    assert result.start == price1
    assert result.stop == price3
    result = price_range.replace(start=price3)
    assert result.start == price3
    assert result.stop == price2
示例#8
0
 def get_price_range(self, discounts=None, taxes=None):
     if self.variants.all():
         prices = [
             variant.get_price(discounts=discounts, taxes=taxes) for variant in self
         ]
         return TaxedMoneyRange(min(prices), max(prices))
     price = calculate_discounted_price(self, self.price, discounts)
     if not self.charge_taxes:
         taxes = None
     tax_rate = self.tax_rate or self.product_type.tax_rate
     price = apply_tax_to_price(taxes, tax_rate, price)
     return TaxedMoneyRange(start=price, stop=price)
示例#9
0
def test_addition_with_taxed_money_range():
    price1 = TaxedMoney(Money(10, 'EUR'), Money(15, 'EUR'))
    price2 = TaxedMoney(Money(30, 'EUR'), Money(45, 'EUR'))
    price_range1 = TaxedMoneyRange(price1, price2)
    price3 = TaxedMoney(Money(40, 'EUR'), Money(60, 'EUR'))
    price4 = TaxedMoney(Money(80, 'EUR'), Money(120, 'EUR'))
    price_range2 = TaxedMoneyRange(price3, price4)
    result = price_range1 + price_range2
    assert result.start == price1 + price3
    assert result.stop == price2 + price4
    with pytest.raises(ValueError):
        price_range1 + TaxedMoneyRange(
            TaxedMoney(Money(1, 'BTC'), Money(1, 'BTC')),
            TaxedMoney(Money(2, 'BTC'), Money(2, 'BTC')))
示例#10
0
def test_comparison():
    price1 = TaxedMoney(Money(10, 'EUR'), Money(15, 'EUR'))
    price2 = TaxedMoney(Money(30, 'EUR'), Money(45, 'EUR'))
    price_range1 = TaxedMoneyRange(price1, price2)
    price3 = TaxedMoney(Money(40, 'EUR'), Money(60, 'EUR'))
    price4 = TaxedMoney(Money(80, 'EUR'), Money(120, 'EUR'))
    price_range2 = TaxedMoneyRange(price3, price4)
    assert price_range1 == TaxedMoneyRange(price1, price2)
    assert price_range1 != price_range2
    assert price_range1 != TaxedMoneyRange(price1, price1)
    assert price_range1 != TaxedMoneyRange(
        TaxedMoney(Money(10, 'USD'), Money(15, 'USD')),
        TaxedMoney(Money(30, 'USD'), Money(45, 'USD')))
    assert price_range1 != price1
示例#11
0
def test_repr():
    price1 = TaxedMoney(Money(10, 'EUR'), Money(15, 'EUR'))
    price2 = TaxedMoney(Money(30, 'EUR'), Money(45, 'EUR'))
    price_range = TaxedMoneyRange(price1, price2)
    assert repr(price_range) == (
        "TaxedMoneyRange(TaxedMoney(net=Money('10', 'EUR'), gross=Money('15', 'EUR')), TaxedMoney(net=Money('30', 'EUR'), gross=Money('45', 'EUR')))"
    )
示例#12
0
def get_cart_data(cart, shipping_range, currency, discounts, taxes):
    """Return a JSON-serializable representation of the cart."""
    cart_total = None
    local_cart_total = None
    shipping_required = False
    total_with_shipping = None
    local_total_with_shipping = None
    if cart:
        cart_total = cart.get_subtotal(discounts, taxes)
        local_cart_total = to_local_currency(cart_total, currency)
        shipping_required = cart.is_shipping_required()
        total_with_shipping = TaxedMoneyRange(start=cart_total,
                                              stop=cart_total)
        if shipping_required and shipping_range:
            total_with_shipping = shipping_range + cart_total
        local_total_with_shipping = to_local_currency(total_with_shipping,
                                                      currency)

    return {
        'cart_total': cart_total,
        'local_cart_total': local_cart_total,
        'shipping_required': shipping_required,
        'total_with_shipping': total_with_shipping,
        'local_total_with_shipping': local_total_with_shipping
    }
示例#13
0
def get_product_costs_data(product):
    purchase_costs_range = TaxedMoneyRange(start=ZERO_TAXED_MONEY,
                                           stop=ZERO_TAXED_MONEY)
    gross_margin = (0, 0)

    if not product.variants.exists():
        return purchase_costs_range, gross_margin

    variants = product.variants.all()
    costs_data = get_cost_data_from_variants(variants)
    if costs_data.costs:
        purchase_costs_range = TaxedMoneyRange(min(costs_data.costs),
                                               max(costs_data.costs))
    if costs_data.margins:
        gross_margin = (costs_data.margins[0], costs_data.margins[-1])
    return purchase_costs_range, gross_margin
示例#14
0
def get_checkout_context(checkout, discounts, taxes, currency=None, shipping_range=None):
    """Data shared between views in checkout process."""
    checkout_total = checkout.get_total(discounts, taxes)
    checkout_subtotal = checkout.get_subtotal(discounts, taxes)
    shipping_required = checkout.is_shipping_required()
    checkout_subtotal = checkout.get_subtotal(discounts, taxes)
    total_with_shipping = TaxedMoneyRange(
        start=checkout_subtotal, stop=checkout_subtotal)
    if shipping_required and shipping_range:
        total_with_shipping = shipping_range + checkout_subtotal

    context = {
        'checkout': checkout,
        'checkout_are_taxes_handled': bool(taxes),
        'checkout_lines': [
            (line, line.get_total(discounts, taxes)) for line in checkout],
        'checkout_shipping_price': checkout.get_shipping_price(taxes),
        'checkout_subtotal': checkout_subtotal,
        'checkout_total': checkout_total,
        'shipping_required': checkout.is_shipping_required(),
        'total_with_shipping': total_with_shipping}

    if currency:
        context.update(
            local_checkout_total=to_local_currency(
                checkout_total, currency),
            local_checkout_subtotal=to_local_currency(
                checkout_subtotal, currency),
            local_total_with_shipping=to_local_currency(
                total_with_shipping, currency))

    return context
def test_availability(product, monkeypatch, settings):
    taxed_price = TaxedMoney(Money("10.0", "USD"), Money("12.30", "USD"))
    monkeypatch.setattr(ExtensionsManager, "apply_taxes_to_product",
                        Mock(return_value=taxed_price))
    availability = get_product_availability(product)
    taxed_price_range = TaxedMoneyRange(start=taxed_price, stop=taxed_price)
    assert availability.price_range == taxed_price_range
    assert availability.price_range_local_currency is None

    monkeypatch.setattr(
        "django_prices_openexchangerates.models.get_rates",
        lambda c: {"PLN": Mock(rate=2)},
    )
    settings.DEFAULT_COUNTRY = "PL"
    settings.OPENEXCHANGERATES_API_KEY = "fake-key"
    availability = get_product_availability(product, local_currency="PLN")
    assert availability.price_range_local_currency.start.currency == "PLN"
    assert availability.available

    availability = get_product_availability(product)
    assert availability.price_range.start.tax.amount
    assert availability.price_range.stop.tax.amount
    assert availability.price_range_undiscounted.start.tax.amount
    assert availability.price_range_undiscounted.stop.tax.amount
    assert availability.available
示例#16
0
def get_cart_data(cart, delivery_range, currency, discounts, taxes):
    """Return a JSON-serializable representation of the cart."""
    cart_total = None
    local_cart_total = None
    delivery_required = False
    total_with_delivery = None
    local_total_with_delivery = None
    if cart:
        cart_total = cart.get_subtotal(discounts, taxes)
        local_cart_total = to_local_currency(cart_total, currency)
        delivery_required = cart.is_delivery_required()
        total_with_delivery = TaxedMoneyRange(start=cart_total,
                                              stop=cart_total)
        if delivery_required and delivery_range:
            total_with_delivery = delivery_range + cart_total
        local_total_with_delivery = to_local_currency(total_with_delivery,
                                                      currency)

    return {
        'cart_total': cart_total,
        'local_cart_total': local_cart_total,
        'delivery_required': delivery_required,
        'total_with_delivery': total_with_delivery,
        'local_total_with_delivery': local_total_with_delivery
    }
def test_availability(stock, monkeypatch, settings, channel_USD):
    product = stock.product_variant.product
    product_channel_listing = product.channel_listings.first()
    variants = product.variants.all()
    variants_channel_listing = models.ProductVariantChannelListing.objects.filter(
        variant__in=variants)
    taxed_price = TaxedMoney(Money("10.0", "USD"), Money("12.30", "USD"))
    monkeypatch.setattr(PluginsManager, "apply_taxes_to_product",
                        Mock(return_value=taxed_price))
    manager = get_plugins_manager()
    availability = get_product_availability(
        product=product,
        product_channel_listing=product_channel_listing,
        variants=product.variants.all(),
        variants_channel_listing=variants_channel_listing,
        channel=channel_USD,
        manager=manager,
        collections=[],
        discounts=[],
        country=Country("PL"),
    )
    taxed_price_range = TaxedMoneyRange(start=taxed_price, stop=taxed_price)
    assert availability.price_range == taxed_price_range
    assert availability.price_range_local_currency is None

    monkeypatch.setattr(
        "django_prices_openexchangerates.models.get_rates",
        lambda c: {"PLN": Mock(rate=2)},
    )
    settings.DEFAULT_COUNTRY = "PL"
    settings.OPENEXCHANGERATES_API_KEY = "fake-key"
    availability = get_product_availability(
        product=product,
        product_channel_listing=product_channel_listing,
        variants=variants,
        variants_channel_listing=variants_channel_listing,
        collections=[],
        discounts=[],
        channel=channel_USD,
        manager=manager,
        local_currency="PLN",
        country=Country("PL"),
    )
    assert availability.price_range_local_currency.start.currency == "PLN"

    availability = get_product_availability(
        product=product,
        product_channel_listing=product_channel_listing,
        variants=variants,
        variants_channel_listing=variants_channel_listing,
        collections=[],
        discounts=[],
        channel=channel_USD,
        manager=manager,
        country=Country("PL"),
    )
    assert availability.price_range.start.tax.amount
    assert availability.price_range.stop.tax.amount
    assert availability.price_range_undiscounted.start.tax.amount
    assert availability.price_range_undiscounted.stop.tax.amount
示例#18
0
 def price_range(self):
     prices = [
         country.get_total_price()
         for country in self.price_per_country.all()
     ]
     if prices:
         return TaxedMoneyRange(min(prices), max(prices))
     return None
示例#19
0
 def get_gross_price_range(self, discounts=None):
     grosses = [
         self.get_price_per_item(variant, discounts=discounts)
         for variant in self]
     if not grosses:
         return None
     grosses = sorted(grosses, key=lambda x: x.tax)
     return TaxedMoneyRange(min(grosses), max(grosses))
示例#20
0
def get_product_availability(
    product: Product,
    discounts: Iterable[DiscountInfo] = None,
    country=None,
    local_currency=None,
    extensions=None,
) -> ProductAvailability:

    if not extensions:
        extensions = get_extensions_manager()
    discounted_net_range = product.get_price_range(discounts=discounts)
    undiscounted_net_range = product.get_price_range()
    discounted = TaxedMoneyRange(
        start=extensions.apply_taxes_to_product(
            product, discounted_net_range.start, country
        ),
        stop=extensions.apply_taxes_to_product(
            product, discounted_net_range.stop, country
        ),
    )
    undiscounted = TaxedMoneyRange(
        start=extensions.apply_taxes_to_product(
            product, undiscounted_net_range.start, country
        ),
        stop=extensions.apply_taxes_to_product(
            product, undiscounted_net_range.stop, country
        ),
    )

    discount = _get_total_discount(undiscounted, discounted)
    price_range_local, discount_local_currency = _get_product_price_range(
        discounted, undiscounted, local_currency
    )

    is_on_sale = product.is_visible and discount is not None

    return ProductAvailability(
        available=product.is_available,
        on_sale=is_on_sale,
        price_range=discounted,
        price_range_undiscounted=undiscounted,
        discount=discount,
        price_range_local_currency=price_range_local,
        discount_local_currency=discount_local_currency,
    )
示例#21
0
def test_apply_tax_to_price_no_taxes_return_taxed_money_range():
    money_range = MoneyRange(Money(100, "USD"), Money(200, "USD"))
    taxed_money_range = TaxedMoneyRange(
        TaxedMoney(net=Money(100, "USD"), gross=Money(100, "USD")),
        TaxedMoney(net=Money(200, "USD"), gross=Money(200, "USD")),
    )

    assert apply_tax_to_price(None, "standard", money_range) == taxed_money_range
    assert apply_tax_to_price(None, "standard", taxed_money_range) == taxed_money_range
示例#22
0
 def apply_taxes_to_shipping_price_range(self, prices: MoneyRange,
                                         country: Country):
     start = TaxedMoney(net=prices.start, gross=prices.start)
     stop = TaxedMoney(net=prices.stop, gross=prices.stop)
     default_value = quantize_price(TaxedMoneyRange(start=start, stop=stop),
                                    start.currency)
     return self.__run_method_on_plugins(
         "apply_taxes_to_shipping_price_range", default_value, prices,
         country)
示例#23
0
def get_product_availability(
    product: Product,
    discounts: Iterable[DiscountInfo] = None,
    country: Optional[str] = None,
    local_currency: Optional[str] = None,
    extensions: Optional["ExtensionsManager"] = None,
) -> ProductAvailability:

    if not extensions:
        extensions = get_extensions_manager()
    discounted_net_range = product.get_price_range(discounts=discounts)
    undiscounted_net_range = product.get_price_range()
    discounted = TaxedMoneyRange(
        start=extensions.apply_taxes_to_product(product,
                                                discounted_net_range.start,
                                                country),
        stop=extensions.apply_taxes_to_product(product,
                                               discounted_net_range.stop,
                                               country),
    )
    undiscounted = TaxedMoneyRange(
        start=extensions.apply_taxes_to_product(product,
                                                undiscounted_net_range.start,
                                                country),
        stop=extensions.apply_taxes_to_product(product,
                                               undiscounted_net_range.stop,
                                               country),
    )

    discount = _get_total_discount_from_range(undiscounted, discounted)
    price_range_local, discount_local_currency = _get_product_price_range(
        discounted, undiscounted, local_currency)

    is_on_sale = product.is_visible and discount is not None
    country = country if country is not None else settings.DEFAULT_COUNTRY
    is_available = product.is_visible and is_product_in_stock(product, country)
    return ProductAvailability(
        on_sale=is_on_sale,
        price_range=discounted,
        price_range_undiscounted=undiscounted,
        discount=discount,
        price_range_local_currency=price_range_local,
        discount_local_currency=discount_local_currency,
    )
示例#24
0
def get_checkout_context(
    checkout: Checkout,
    discounts: "DiscountsListType",
    currency: Optional[str] = None,
    shipping_range=None,
) -> dict:
    """Retrieve the data shared between views in checkout process."""
    cards_balance = checkout.get_total_gift_cards_balance()

    # FIXME: We are having here parts of checkout total calculation logic
    checkout_total = calculations.checkout_total(checkout=checkout,
                                                 discounts=discounts)
    checkout_total.gross -= cards_balance
    checkout_total.net -= cards_balance
    checkout_total = max(checkout_total,
                         zero_taxed_money(checkout_total.currency))
    checkout_subtotal = calculations.checkout_subtotal(checkout, discounts)
    shipping_price = calculations.checkout_shipping_price(checkout, discounts)

    shipping_required = checkout.is_shipping_required()
    total_with_shipping = TaxedMoneyRange(start=checkout_subtotal,
                                          stop=checkout_subtotal)
    if shipping_required and shipping_range:
        total_with_shipping = shipping_range + checkout_subtotal

    manager = get_extensions_manager()
    context = {
        "checkout":
        checkout,
        "checkout_are_taxes_handled":
        manager.taxes_are_enabled(),
        "checkout_lines":
        [(line, calculations.checkout_line_total(line, discounts))
         for line in checkout],
        "checkout_shipping_price":
        shipping_price,
        "checkout_subtotal":
        checkout_subtotal,
        "checkout_total":
        checkout_total,
        "shipping_required":
        checkout.is_shipping_required(),
        "total_with_shipping":
        total_with_shipping,
    }

    if currency:
        context.update(
            local_checkout_total=to_local_currency(checkout_total, currency),
            local_checkout_subtotal=to_local_currency(checkout_subtotal,
                                                      currency),
            local_total_with_shipping=to_local_currency(
                total_with_shipping, currency),
        )

    return context
示例#25
0
def test_apply_tax_to_price_no_taxes_return_taxed_money_range():
    money_range = MoneyRange(Money(100, 'USD'), Money(200, 'USD'))
    taxed_money_range = TaxedMoneyRange(
        TaxedMoney(net=Money(100, 'USD'), gross=Money(100, 'USD')),
        TaxedMoney(net=Money(200, 'USD'), gross=Money(200, 'USD')))

    assert (apply_tax_to_price(None, 'standard',
                               money_range) == taxed_money_range)
    assert (apply_tax_to_price(None, 'standard',
                               taxed_money_range) == taxed_money_range)
示例#26
0
def test_membership():
    price1 = TaxedMoney(Money(10, 'EUR'), Money(15, 'EUR'))
    price2 = TaxedMoney(Money(30, 'EUR'), Money(45, 'EUR'))
    price_range = TaxedMoneyRange(price1, price2)
    assert price1 in price_range
    assert price2 in price_range
    assert (price1 + price2) / 2 in price_range
    assert price1 + price2 not in price_range
    with pytest.raises(TypeError):
        15 in price_range
示例#27
0
def test_subtraction_with_money():
    price1 = TaxedMoney(Money(40, 'EUR'), Money(60, 'EUR'))
    price2 = TaxedMoney(Money(80, 'EUR'), Money(120, 'EUR'))
    price_range = TaxedMoneyRange(price1, price2)
    price3 = Money(10, 'EUR')
    result = price_range - price3
    assert result.start == price1 - price3
    assert result.stop == price2 - price3
    with pytest.raises(ValueError):
        price_range - Money(1, 'BTC')
示例#28
0
def test_discount():
    price = TaxedMoney(Money(100, 'BTC'), Money(100, 'BTC'))
    discount = partial(percentage_discount, percentage=10)
    result = discount(price)
    assert result.net == Money(90, 'BTC')
    assert result.gross == Money(90, 'BTC')
    price_range = TaxedMoneyRange(price, price)
    result = discount(price_range)
    assert result.start == TaxedMoney(Money(90, 'BTC'), Money(90, 'BTC'))
    assert result.stop == TaxedMoney(Money(90, 'BTC'), Money(90, 'BTC'))
示例#29
0
def test_addition_with_money():
    price1 = TaxedMoney(Money(10, 'EUR'), Money(15, 'EUR'))
    price2 = TaxedMoney(Money(30, 'EUR'), Money(45, 'EUR'))
    price_range = TaxedMoneyRange(price1, price2)
    price3 = Money(40, 'EUR')
    result = price_range + price3
    assert result.start == price1 + price3
    assert result.stop == price2 + price3
    with pytest.raises(ValueError):
        price_range + Money(1, 'BTC')
示例#30
0
def test_range():
    price_range = MoneyRange(Money(10, 'BTC'), Money(20, 'BTC'))
    result = flat_tax(price_range, 1)
    assert result.start == TaxedMoney(Money(10, 'BTC'), Money(20, 'BTC'))
    assert result.stop == TaxedMoney(Money(20, 'BTC'), Money(40, 'BTC'))
    price_range = TaxedMoneyRange(
        TaxedMoney(Money(10, 'BTC'), Money(10, 'BTC')),
        TaxedMoney(Money(20, 'BTC'), Money(20, 'BTC')))
    result = flat_tax(price_range, 1)
    assert result.start == TaxedMoney(Money(10, 'BTC'), Money(20, 'BTC'))
    assert result.stop == TaxedMoney(Money(20, 'BTC'), Money(40, 'BTC'))
示例#31
0
def get_product_availability(
    product: Product,
    discounts: Iterable[DiscountInfo] = None,
    country: Optional[str] = None,
    local_currency: Optional[str] = None,
    plugins: Optional["PluginsManager"] = None,
) -> ProductAvailability:

    if not plugins:
        plugins = get_plugins_manager()
    discounted_net_range = product.get_price_range(discounts=discounts)
    undiscounted_net_range = product.get_price_range()
    discounted = TaxedMoneyRange(
        start=plugins.apply_taxes_to_product(product,
                                             discounted_net_range.start,
                                             country),
        stop=plugins.apply_taxes_to_product(product, discounted_net_range.stop,
                                            country),
    )
    undiscounted = TaxedMoneyRange(
        start=plugins.apply_taxes_to_product(product,
                                             undiscounted_net_range.start,
                                             country),
        stop=plugins.apply_taxes_to_product(product,
                                            undiscounted_net_range.stop,
                                            country),
    )

    discount = _get_total_discount_from_range(undiscounted, discounted)
    price_range_local, discount_local_currency = _get_product_price_range(
        discounted, undiscounted, local_currency)

    is_on_sale = product.is_visible and discount is not None
    return ProductAvailability(
        on_sale=is_on_sale,
        price_range=discounted,
        price_range_undiscounted=undiscounted,
        discount=discount,
        price_range_local_currency=price_range_local,
        discount_local_currency=discount_local_currency,
    )
示例#32
0
def test_subtraction_with_money_range():
    price1 = Money(10, 'EUR')
    price2 = Money(30, 'EUR')
    price_range1 = MoneyRange(price1, price2)
    price3 = TaxedMoney(Money(40, 'EUR'), Money(60, 'EUR'))
    price4 = TaxedMoney(Money(80, 'EUR'), Money(120, 'EUR'))
    price_range2 = TaxedMoneyRange(price3, price4)
    result = price_range2 - price_range1
    assert result.start == price3 - price1
    assert result.stop == price4 - price2
    with pytest.raises(ValueError):
        price_range2 - MoneyRange(Money(1, 'BTC'), Money(2, 'BTC'))