示例#1
0
def test_quantize():
    price1 = Money(10, 'EUR')
    price2 = Money(30, 'EUR')
    price_range = MoneyRange(price1, price2)
    result = price_range.quantize()
    assert str(result.start.amount) == '10.00'
    assert str(result.stop.amount) == '30.00'
示例#2
0
 def get_price_range(self,
                     discounts: Iterable[DiscountInfo] = None
                     ) -> MoneyRange:
     if self.variants.all():
         prices = [variant.get_price(discounts) for variant in self]
         return MoneyRange(min(prices), max(prices))
     price = calculate_discounted_price(self, self.price, discounts)
     return MoneyRange(start=price, stop=price)
示例#3
0
def test_construction():
    price1 = Money(10, 'EUR')
    price2 = Money(30, 'EUR')
    price_range = MoneyRange(price1, price2)
    assert price_range.start == price1
    assert price_range.stop == price2
    with pytest.raises(ValueError):
        MoneyRange(price1, Money(20, 'PLN'))
    with pytest.raises(ValueError):
        MoneyRange(price2, price1)
示例#4
0
def test_replace():
    price1 = Money(10, 'EUR')
    price2 = Money(30, 'EUR')
    price3 = Money(20, 'EUR')
    price_range = MoneyRange(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
示例#5
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'))
示例#6
0
def test_addition_with_money_range():
    price1 = TaxedMoney(Money(10, 'EUR'), Money(15, 'EUR'))
    price2 = TaxedMoney(Money(30, 'EUR'), Money(45, 'EUR'))
    price_range1 = TaxedMoneyRange(price1, price2)
    price3 = Money(40, 'EUR')
    price4 = Money(80, 'EUR')
    price_range2 = MoneyRange(price3, price4)
    result = price_range1 + price_range2
    assert result.start == price1 + price3
    assert result.stop == price2 + price4
    with pytest.raises(ValueError):
        price_range1 + MoneyRange(Money(1, 'BTC'), Money(2, 'BTC'))
示例#7
0
def test_comparison():
    price1 = Money(10, 'EUR')
    price2 = Money(30, 'EUR')
    price_range1 = MoneyRange(price1, price2)
    price3 = Money(40, 'EUR')
    price4 = Money(80, 'EUR')
    price_range2 = MoneyRange(price3, price4)
    assert price_range1 == MoneyRange(price1, price2)
    assert price_range1 != price_range2
    assert price_range1 != MoneyRange(price1, price1)
    assert price_range1 != MoneyRange(
        Money(10, 'USD'), Money(30, 'USD'))
    assert price_range1 != price1
示例#8
0
def get_display_price(base: Union[TaxedMoney, TaxedMoneyRange],
                      display_gross: bool = False) -> Money:
    """Return the price amount that should be displayed based on settings."""
    if not display_gross:
        display_gross = display_gross_prices()
    if isinstance(base, TaxedMoneyRange):
        if display_gross:
            base = MoneyRange(start=base.start.gross, stop=base.stop.gross)
        else:
            base = MoneyRange(start=base.start.net, stop=base.stop.net)

    if isinstance(base, TaxedMoney):
        base = base.gross if display_gross else base.net
    return base
示例#9
0
文件: costs.py 项目: tinyfood/farmers
def get_product_costs_data(product):
    purchase_costs_range = MoneyRange(start=ZERO_MONEY, stop=ZERO_MONEY)
    margin = (0, 0)

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

    variants = product.variants.all()
    costs_data = get_cost_data_from_variants(variants)
    if costs_data.costs:
        purchase_costs_range = MoneyRange(min(costs_data.costs),
                                          max(costs_data.costs))
    if costs_data.margins:
        margin = (costs_data.margins[0], costs_data.margins[-1])
    return purchase_costs_range, margin
示例#10
0
def price(context, base, display_gross=None, html=True):
    if isinstance(base, (TaxedMoney, TaxedMoneyRange)):
        if display_gross is None:
            display_gross = context["site"].settings.display_gross_prices

        if isinstance(base, TaxedMoneyRange):
            if display_gross:
                base = MoneyRange(start=base.start.gross, stop=base.stop.gross)
            else:
                base = MoneyRange(start=base.start.net, stop=base.stop.net)

        if isinstance(base, TaxedMoney):
            base = base.gross if display_gross else base.net

    is_range = isinstance(base, MoneyRange)
    return {"price": base, "is_range": is_range, "html": html}
示例#11
0
def get_product_price_range(
    *,
    product: Product,
    variants: Iterable[ProductVariant],
    variants_channel_listing: List[ProductVariantChannelListing],
    collections: Iterable[Collection],
    discounts: Iterable[DiscountInfo],
    channel: Channel,
) -> Optional[MoneyRange]:
    with opentracing.global_tracer().start_active_span(
            "get_product_price_range"):
        if variants:
            prices = [
                get_variant_price(
                    variant=variant,
                    variant_channel_listing=variants_channel_listing[i],
                    product=product,
                    collections=collections,
                    discounts=discounts,
                    channel=channel,
                ) for i, variant in enumerate(variants)
            ]
            return MoneyRange(min(prices), max(prices))

        return None
示例#12
0
 def price_range(self):
     prices = [
         shipping_method.get_total()
         for shipping_method in self.shipping_methods.all()]
     if prices:
         return MoneyRange(min(prices).net, max(prices).net)
     return None
示例#13
0
def resolve_price_range(channel_slug):
    # TODO: Add dataloader.
    channel_listing = models.ShippingMethodChannelListing.objects.filter(
        channel__slug=str(channel_slug))
    prices = [shipping.get_total() for shipping in channel_listing]

    return MoneyRange(min(prices), max(prices)) if prices else None
示例#14
0
    def get_price_range(
        self, discounts: Optional[Iterable[DiscountInfo]] = None
    ) -> MoneyRange:
        import opentracing

        with opentracing.global_tracer().start_active_span("get_price_range"):
            if self.variants.all():
                prices = [variant.get_price(discounts) for variant in self]
                return MoneyRange(min(prices), max(prices))
            price = calculate_discounted_price(
                product=self,
                price=self.price,
                collections=self.collections.all(),
                discounts=discounts,
            )
            return MoneyRange(start=price, stop=price)
示例#15
0
def price(context, base, display_gross=None, html=True):
    if isinstance(base, (TaxedMoney, TaxedMoneyRange)):
        if display_gross is None:
            display_gross = True

        if isinstance(base, TaxedMoneyRange):
            if display_gross:
                base = MoneyRange(start=base.start.gross, stop=base.stop.gross)
            else:
                base = MoneyRange(start=base.start.net, stop=base.stop.net)

        if isinstance(base, TaxedMoney):
            base = base.gross if display_gross else base.net

    is_range = isinstance(base, MoneyRange)
    return {'price': base, 'is_range': is_range, 'html': html}
示例#16
0
def get_product_price_range(
    *,
    product: Product,
    variants: Iterable[ProductVariant],
    variants_channel_listing: List[ProductVariantChannelListing],
    collections: Iterable[Collection],
    discounts: Iterable[DiscountInfo],
    channel: Channel,
) -> Optional[MoneyRange]:
    with opentracing.global_tracer().start_active_span("get_product_price_range"):
        if variants:
            variants_channel_listing_dict = {
                channel_listing.variant_id: channel_listing
                for channel_listing in variants_channel_listing
                if channel_listing
            }
            prices = []
            for variant in variants:
                variant_channel_listing = variants_channel_listing_dict.get(variant.id)
                if variant_channel_listing:
                    price = get_variant_price(
                        variant=variant,
                        variant_channel_listing=variant_channel_listing,
                        product=product,
                        collections=collections,
                        discounts=discounts,
                        channel=channel,
                    )
                    prices.append(price)
            if prices:
                return MoneyRange(min(prices), max(prices))

        return None
示例#17
0
 def price_range(self):
     prices = [
         country.get_total_price()
         for country in self.price_per_country.all()]
     if prices:
         return MoneyRange(min(prices).net, max(prices).net)
     return None
示例#18
0
def test_exchange_currency_for_money_range():
    value = MoneyRange(Money(10, 'USD'), Money(15, 'USD'))

    value_converted = exchange_currency(value, 'GBP')
    assert value_converted.currency == 'GBP'
    assert value_converted.start == Money(40, currency='GBP')
    assert value_converted.stop == Money(60, currency='GBP')
示例#19
0
文件: utils.py 项目: zdlm/saleor
def get_shipping_price_estimate(
    checkout: Checkout,
    lines: Iterable[CheckoutLine],
    discounts: Iterable[DiscountInfo],
    country_code: str,
) -> Optional[TaxedMoneyRange]:
    """Return the estimated price range for shipping for given order."""

    shipping_methods = get_valid_shipping_methods_for_checkout(
        checkout, lines, discounts, country_code=country_code)

    if shipping_methods is None:
        return None

    # TODO: extension manager should be able to have impact on shipping price estimates
    min_price_amount, max_price_amount = shipping_methods.aggregate(
        price_amount_min=Min("price_amount"),
        price_amount_max=Max("price_amount")).values()

    if min_price_amount is None:
        return None

    manager = get_plugins_manager()
    prices = MoneyRange(
        start=Money(min_price_amount, checkout.currency),
        stop=Money(max_price_amount, checkout.currency),
    )
    return manager.apply_taxes_to_shipping_price_range(prices, country_code)
示例#20
0
def get_product_costs_data(
    product: "Product", ) -> Tuple[MoneyRange, Tuple[float, float]]:

    purchase_costs_range = MoneyRange(start=zero_money(), stop=zero_money())
    margin = (0, 0)

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

    variants = product.variants.all()
    costs_data = get_cost_data_from_variants(variants)
    if costs_data.costs:
        purchase_costs_range = MoneyRange(min(costs_data.costs),
                                          max(costs_data.costs))
    if costs_data.margins:
        margin = (costs_data.margins[0], costs_data.margins[-1])
    return purchase_costs_range, margin
示例#21
0
 def price_range(self):
     prices = [
         delivery_method.get_total()
         for delivery_method in self.delivery_methods.all()
     ]
     if prices:
         return MoneyRange(min(prices).net, max(prices).net)
     return None
示例#22
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
示例#23
0
def test_product_get_price_range_no_variants(product_type, category):
    product = models.Product.objects.create(product_type=product_type,
                                            category=category,
                                            price=Money("10.00", "MXN"))

    price = product.get_price_range()

    expected_price = Money("10.00", "MXN")
    assert price == MoneyRange(start=expected_price, stop=expected_price)
示例#24
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)
示例#25
0
def test_membership():
    price1 = Money(10, 'EUR')
    price2 = Money(30, 'EUR')
    price_range = MoneyRange(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
示例#26
0
def test_addition_with_money():
    price1 = Money(10, 'EUR')
    price2 = Money(30, 'EUR')
    price_range = MoneyRange(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')
示例#27
0
def test_exchange_currency_for_money_range_uses_passed_conversion_rate():
    value = MoneyRange(Money(10, 'USD'), Money(15, 'USD'))
    custom_rate = Decimal(2)

    value_converted = exchange_currency(value,
                                        'GBP',
                                        conversion_rate=custom_rate)
    assert value_converted.currency == 'GBP'
    assert value_converted.start == Money(20, currency='GBP')
    assert value_converted.stop == Money(30, currency='GBP')
示例#28
0
def test_subtraction_with_money():
    price1 = Money(40, 'EUR')
    price2 = Money(80, 'EUR')
    price_range = MoneyRange(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')
示例#29
0
def get_product_costs_data(
    variant_channel_listings: Iterable[ProductVariantChannelListing],
    has_variants: bool,
    currency: str,
) -> Tuple[MoneyRange, Tuple[float, float]]:

    purchase_costs_range = MoneyRange(
        start=zero_money(currency), stop=zero_money(currency)
    )
    margin = (0.0, 0.0)

    if not has_variants:
        return purchase_costs_range, margin

    costs_data = get_cost_data_from_variant_channel_listing(variant_channel_listings)
    if costs_data.costs:
        purchase_costs_range = MoneyRange(min(costs_data.costs), max(costs_data.costs))
    if costs_data.margins:
        margin = (costs_data.margins[0], costs_data.margins[-1])
    return purchase_costs_range, margin
示例#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'))