Beispiel #1
0
def test_can_create_payment():
    shop = get_default_shop()
    supplier = get_default_supplier()
    product = create_product(
        "test-sku",
        shop=get_default_shop(),
        default_price=10,
    )

    order = create_order_with_product(product, supplier, 1, 200, shop=shop)
    assert order.can_create_payment()
    order.cache_prices()

    # Partially paid orders can create payments
    payment_amount = order.taxful_total_price.amount / 2
    order.create_payment(payment_amount)
    assert order.can_create_payment()

    # But fully paid orders can't
    remaining_amount = order.taxful_total_price.amount - payment_amount
    order.create_payment(remaining_amount)
    assert not order.can_create_payment()

    order = create_order_with_product(product, supplier, 1, 200, shop=shop)
    order.cache_prices()
    assert order.can_create_payment()

    # Canceled orders can't create payments
    order.set_canceled()
    assert not order.can_create_payment()

    order = create_order_with_product(product, supplier, 2, 200, shop=shop)
    order.cache_prices()
    assert order.can_create_payment()

    # Partially refunded orders can create payments
    order.create_refund([{
        "line": order.lines.first(),
        "quantity": 1,
        "amount": Money(200, order.currency),
        "restock": False
    }])
    assert order.can_create_payment()

    # But fully refunded orders can't
    order.create_refund([{
        "line": order.lines.first(),
        "quantity": 1,
        "amount": Money(200, order.currency),
        "restock": False
    }])
    assert not order.can_create_payment()
Beispiel #2
0
def test_basic_order():
    PRODUCTS_TO_SEND = 10
    product = get_default_product()
    supplier = get_default_supplier()
    order = create_order_with_product(product,
                                      supplier=supplier,
                                      quantity=PRODUCTS_TO_SEND,
                                      taxless_base_unit_price=10,
                                      tax_rate=Decimal("0.5"))
    assert order.shop.prices_include_tax is False
    price = order.shop.create_price
    currency = order.currency

    discount_order_line = OrderLine(order=order,
                                    quantity=1,
                                    type=OrderLineType.OTHER)
    discount_order_line.discount_amount = price(30)
    assert discount_order_line.price == price(-30)
    discount_order_line.save()

    order.cache_prices()
    order.check_all_verified()
    order.save()
    assert order.taxful_total_price == TaxfulPrice(
        PRODUCTS_TO_SEND * (10 + 5) - 30, currency)
    shipment = order.create_shipment_of_all_products(supplier=supplier)
    assert shipment.total_products == PRODUCTS_TO_SEND, "All products were shipped"
    assert shipment.weight == product.gross_weight * PRODUCTS_TO_SEND, "Gravity works"
    assert not order.get_unshipped_products(
    ), "Nothing was left in the warehouse"
    order.shipping_status = ShippingStatus.FULLY_SHIPPED
    order.create_payment(order.taxful_total_price)
    assert order.payments.exists(), "A payment was created"
    with pytest.raises(NoPaymentToCreateException):
        order.create_payment(Money(6, currency))
    assert order.is_paid(), "Order got paid"
    assert order.can_set_complete(), "Finalization is possible"
    order.change_status(next_status=OrderStatus.objects.get_default_complete(),
                        save=False)
    assert order.is_complete(), "Finalization done"

    summary = order.get_tax_summary()
    assert len(summary) == 2
    assert summary[0].tax_rate * 100 == 50
    assert summary[0].based_on == Money(100, currency)
    assert summary[0].tax_amount == Money(50, currency)
    assert summary[0].taxful == summary[0].based_on + summary[0].tax_amount
    assert summary[1].tax_id is None
    assert summary[1].tax_code == ""
    assert summary[1].tax_amount == Money(0, currency)
    assert summary[1].tax_rate == 0
    assert order.get_total_tax_amount() == Money(50, currency)
Beispiel #3
0
def test_refund_with_shipment(restock):
    shop = get_default_shop()
    supplier = get_simple_supplier()
    product = create_product(
        "test-sku",
        shop=get_default_shop(),
        default_price=10,
        stock_behavior=StockBehavior.STOCKED
    )
    # Start out with a supplier with quantity of 10 of a product
    supplier.adjust_stock(product.id, 10)
    check_stock_counts(supplier, product, physical=10, logical=10)

    # Order 4 products, make sure product counts are accurate
    order = create_order_with_product(product, supplier, 4, 200, shop=shop)
    order.cache_prices()
    check_stock_counts(supplier, product, physical=10, logical=6)
    product_line = order.lines.first()

    # Shipment should decrease physical count by 2, logical by none
    order.create_shipment({product_line.product: 2}, supplier=supplier)
    check_stock_counts(supplier, product, physical=8, logical=6)
    assert order.shipping_status == ShippingStatus.PARTIALLY_SHIPPED

    # Check correct refunded quantities
    assert not product_line.refunded_quantity

    # Create a refund that refunds from unshipped quantity first, then shipped quantity, check stocks
    check_stock_counts(supplier, product, physical=8, logical=6)
    order.create_refund([
        {"line": product_line, "quantity": 3, "amount": Money(600, order.currency), "restock_products": restock}])
    assert product_line.refunded_quantity == 3
    assert order.shipping_status == ShippingStatus.FULLY_SHIPPED
    if restock:
        check_stock_counts(supplier, product, physical=9, logical=9)
    else:
        check_stock_counts(supplier, product, physical=8, logical=6)

    # Create a second refund that refunds the last shipped quantity, check stocks
    order.create_refund([
        {"line": product_line, "quantity": 1, "amount": Money(200, order.currency), "restock_products": restock}])
    assert product_line.refunded_quantity == 4
    if restock:
        # Make sure we're not restocking more than maximum restockable quantity
        check_stock_counts(supplier, product, physical=10, logical=10)
    else:
        # Make sure maximum restockable quantity is not 0
        check_stock_counts(supplier, product, physical=8, logical=6)
    assert order.get_total_tax_amount() == Money(
        order.taxful_total_price_value - order.taxless_total_price_value,
        order.currency)
Beispiel #4
0
def test_create_refund_amount(prices_include_tax):
    supplier = get_simple_supplier()
    order = _get_order(prices_include_tax, True, True)

    original_order_total = order.taxful_total_price
    num_order_lines = order.lines.count()

    # refund the discount lines first
    for line in order.lines.discounts():
        order.create_refund([
            {"line": "amount", "quantity": line.quantity, "amount": line.taxful_price.amount}])

    # refund each line 1 by 1
    for line in order.lines.products():
        order.create_refund([
            {"line": "amount", "quantity": 1, "amount": line.taxful_price.amount, "restock_products": True}])

    assert order.has_refunds()
    #assert not order.can_create_refund()
    assert not order.taxful_total_price_value
    assert not order.taxless_total_price_value
    assert order.lines.refunds().count() == num_order_lines
    # we haven't refunded any quantity so the shipping status remains as-is
    assert order.shipping_status == ShippingStatus.NOT_SHIPPED
    assert order.payment_status == PaymentStatus.FULLY_PAID
    assert order.get_total_refunded_amount() == original_order_total.amount
    assert not order.get_total_unrefunded_amount().value

    for line in order.lines.products():
        order.create_refund([
            {"line": line, "quantity": line.quantity, "amount": Money(0, "EUR"), "restock_products": True}])

    assert order.shipping_status == ShippingStatus.FULLY_SHIPPED
Beispiel #5
0
def test_init_with_currency():
    m42eur = TaxlessPrice(42, "EUR")
    assert m42eur.amount == Money(42, "EUR")
    assert m42eur.value == 42
    assert m42eur.currency == "EUR"

    assert TaxlessPrice(1, "USD").currency == "USD"
Beispiel #6
0
def test_mixed_chart():
    labels = ["One", "Two", "Three"]
    locale = "pt_br"
    currency = "BRL"
    chart = MixedChart("ma biultiful xart", labels, data_type=ChartDataType.CURRENCY, locale=locale, currency=currency)

    dataset1 = OrderedDict({"type": ChartType.BAR, "label": "some bars #1", "data": [1, 2, 3]})
    dataset2 = OrderedDict({"type": ChartType.BAR, "label": "some bars #2", "data": [2, 3, 4]})
    dataset3 = OrderedDict({"type": ChartType.LINE, "label": "some lines #1", "data": [5, 6, 7]})
    dataset4 = OrderedDict({"type": ChartType.LINE, "label": "some lines #2", "data": [8, 9, 10]})
    datasets = [dataset1, dataset2, dataset3, dataset4]

    for dataset in datasets:
        chart.add_data(dataset["label"], dataset["data"], dataset["type"])

    chart_config = chart.get_config()
    assert chart_config["type"] == "mixed"
    assert chart_config["labels"] == labels

    for i in range(len(chart_config["data"])):
        for j in range(len(chart_config["data"][i]["data"])):
            assert chart_config["data"][i]["data"][j] == datasets[i]["data"][j]

            formatted_data = chart_config["data"][i]["formatted_data"][j]
            assert formatted_data == format_money(Money(datasets[i]["data"][j], currency=currency).as_rounded())
Beispiel #7
0
def test_refund_without_shipment(restock):
    shop = get_default_shop()
    supplier = get_simple_supplier()
    product = create_product(
        "test-sku",
        shop=get_default_shop(),
        default_price=10,
        stock_behavior=StockBehavior.STOCKED
    )
    # Start out with a supplier with quantity of 10 of a product
    supplier.adjust_stock(product.id, 10)
    check_stock_counts(supplier, product, physical=10, logical=10)

    order = create_order_with_product(product, supplier, 2, 200, shop=shop)
    order.cache_prices()
    check_stock_counts(supplier, product, physical=10, logical=8)

    # Restock value shouldn't matter if we don't have any shipments
    product_line = order.lines.first()
    order.create_refund([
        {"line": product_line, "quantity": 2, "amount": Money(400, order.currency), "restock_products": restock}])

    if restock:
        check_stock_counts(supplier, product, physical=10, logical=10)
    else:
        check_stock_counts(supplier, product, physical=10, logical=8)
    assert product_line.refunded_quantity == 2
Beispiel #8
0
 def max_refundable_amount(self):
     """
     :rtype: shuup.utils.money.Money
     """
     refunds = self.child_lines.refunds().filter(parent_line=self)
     refund_total_value = sum(refund.taxful_price.amount.value for refund in refunds)
     return (self.taxful_price.amount + Money(refund_total_value, self.order.currency))
Beispiel #9
0
def test_refunds_with_quantities():
    shop = get_default_shop()
    supplier = get_default_supplier()
    product = create_product(
        "test-sku",
        shop=get_default_shop(),
        default_price=10,
        stock_behavior=StockBehavior.STOCKED
    )

    order = create_order_with_product(product, supplier, 3, 200, shop=shop)
    order.cache_prices()
    assert not order.lines.refunds()

    product_line = order.lines.first()
    refund_amount = Money(100, order.currency)
    order.create_refund([{"line": product_line, "quantity": 2, "amount": refund_amount}])
    assert len(order.lines.refunds()) == 2

    quantity_line = order.lines.refunds().filter(quantity=2).first()
    assert quantity_line
    amount_line = order.lines.refunds().filter(quantity=1).first()
    assert amount_line

    assert quantity_line.taxful_base_unit_price == -product_line.taxful_base_unit_price
    assert amount_line.taxful_price.amount == -refund_amount
Beispiel #10
0
 def create_refund():
     order.create_refund([{
         "line": product_line,
         "quantity": 1,
         "amount": Money(1, order.currency),
         "restock_products": restock
     }])
Beispiel #11
0
    def from_line_taxes(cls, line_taxes, untaxed):
        """
        Create TaxSummary from LineTaxes.

        :param line_taxes: List of line taxes to summarize
        :type line_taxes: list[LineTax]
        :param untaxed: Sum of taxless prices that have no taxes added
        :type untaxed: shuup.core.pricing.TaxlessPrice
        """
        zero_amount = Money(0, untaxed.currency)
        tax_amount_by_tax = defaultdict(lambda: zero_amount)
        raw_base_amount_by_tax = defaultdict(lambda: zero_amount)
        base_amount_by_tax = defaultdict(lambda: zero_amount)
        for line_tax in line_taxes:
            assert isinstance(line_tax, LineTax)
            tax_amount_by_tax[line_tax.tax] += line_tax.amount
            raw_base_amount_by_tax[line_tax.tax] += line_tax.base_amount
            base_amount_by_tax[
                line_tax.tax] += line_tax.base_amount.as_rounded()

        lines = [
            TaxSummaryLine.from_tax(tax, base_amount_by_tax[tax],
                                    raw_base_amount_by_tax[tax], tax_amount)
            for (tax, tax_amount) in tax_amount_by_tax.items()
        ]
        if untaxed:
            lines.append(
                TaxSummaryLine(tax_id=None,
                               tax_code='',
                               tax_name=_("Untaxed"),
                               tax_rate=Decimal(0),
                               based_on=untaxed.amount.as_rounded(),
                               raw_based_on=untaxed.amount,
                               tax_amount=zero_amount))
        return cls(sorted(lines, key=TaxSummaryLine.get_sort_key))
Beispiel #12
0
def test_tax_special_cases3():
    taxless_line = Line(
        base_unit_price=TaxfulPrice(0, "EUR"),
        quantity=0,
        discount_amount=TaxfulPrice(0, "EUR"),
        tax_amount=Money(0, "EUR"),
    )
    assert taxless_line.taxful_price == TaxfulPrice(0, "EUR")
    assert taxless_line.taxless_price == TaxlessPrice(0, "EUR")

    assert taxless_line.base_unit_price == TaxfulPrice(0, "EUR")
    assert taxless_line.taxful_base_unit_price == TaxfulPrice(0, "EUR")
    assert taxless_line.taxless_base_unit_price == TaxlessPrice(0, "EUR")

    assert taxless_line.discount_amount == TaxfulPrice(0, "EUR")
    assert taxless_line.taxful_discount_amount == TaxfulPrice(0, "EUR")
    assert taxless_line.taxless_discount_amount == TaxlessPrice(0, "EUR")

    assert taxless_line.price == TaxfulPrice(0, "EUR")
    assert taxless_line.taxful_price == TaxfulPrice(0, "EUR")
    assert taxless_line.taxless_price == TaxlessPrice(0, "EUR")

    assert taxless_line.base_price == TaxfulPrice(0, "EUR")
    assert taxless_line.taxful_base_price == TaxfulPrice(0, "EUR")
    assert taxless_line.taxless_base_price == TaxlessPrice(0, "EUR")

    assert taxless_line.unit_discount_amount == TaxfulPrice(0, "EUR")
    assert taxless_line.taxful_unit_discount_amount == TaxfulPrice(0, "EUR")
    assert taxless_line.taxless_unit_discount_amount == TaxlessPrice(0, "EUR")

    assert taxless_line.discount_rate == 0
    assert taxless_line.tax_rate == 0
Beispiel #13
0
    def _get_refund_line_info(self, order, data, supplier):
        refund_line_info = {}
        amount_value = data.get("amount", 0) or 0
        line_number = data.get("line_number")
        quantity = data.get("quantity", 0) or 1
        restock_products = data.get("restock_products")

        if line_number != "amount":
            lines = order.lines.filter(ordering=line_number)
            if supplier:
                lines = lines.filter(supplier=supplier)

            line = lines.first()

            if not line:
                return None
            refund_line_info["line"] = line
            refund_line_info["quantity"] = quantity
            refund_line_info["restock_products"] = bool(restock_products)
        else:
            refund_line_info["line"] = "amount"
            refund_line_info["text"] = data.get("text")
            refund_line_info["quantity"] = 1
        refund_line_info["amount"] = Money(amount_value, order.currency)
        return refund_line_info
Beispiel #14
0
 def get_total_refunded_amount(self, supplier=None):
     refunds = self.lines.refunds()
     if supplier:
         refunds = refunds.filter(
             Q(parent_line__supplier=supplier) | Q(supplier=supplier))
     total = sum([line.taxful_price.amount.value for line in refunds])
     return Money(-total, self.currency)
Beispiel #15
0
    def amount(self):
        """
        Money amount of this price.

        :rtype: Money
        """
        return Money(self.value, self.currency)
Beispiel #16
0
def test_module(address, expected_taxes):
    """
    Test the DefaultTaxModule.
    """
    # Create a product
    shop = get_shop(prices_include_tax=False, currency='USD')
    product = create_product('PROD', shop=shop, default_price=1000)
    price = product.get_shop_instance(shop).default_price

    # Put the tax rules into database
    for ruledef in shuffled(TAX_RULE_DEFS):
        rule = ruledef.get_tax_rule()
        rule.tax.save()
        rule.tax = rule.tax  # refresh the id
        rule.save()
        rule.tax_classes.add(product.tax_class)
    assert TaxRule.objects.count() == len(TAX_RULE_DEFS)

    with override_settings(SHUUP_TAX_MODULE='default_tax'):
        module = get_tax_module()
        assert isinstance(module, DefaultTaxModule)

        context = TaxingContext(location=address)
        taxed_price = module.get_taxed_price_for(context, product, price)
        expected_codes = set(sum([x.split() for x in expected_taxes], []))
        assert set(x.tax.code for x in taxed_price.taxes) == expected_codes
        expected_tax = Money(TAX_AMOUNTS[expected_taxes], 'USD')
        assert taxed_price.taxful.amount == price.amount + expected_tax

    # Clean-up the rules
    TaxRule.objects.all().delete()
Beispiel #17
0
def test_init_with_currency():
    m42eur = TaxlessPrice(42, 'EUR')
    assert m42eur.amount == Money(42, 'EUR')
    assert m42eur.value == 42
    assert m42eur.currency == 'EUR'

    assert TaxlessPrice(1, 'USD').currency == 'USD'
Beispiel #18
0
def add_product_to_order(order,
                         supplier,
                         product,
                         quantity,
                         taxless_base_unit_price,
                         tax_rate=0,
                         pricing_context=None):
    if not pricing_context:
        pricing_context = _get_pricing_context(order.shop, order.customer)
    product_order_line = OrderLine(order=order)
    update_order_line_from_product(pricing_context,
                                   order_line=product_order_line,
                                   product=product,
                                   quantity=quantity,
                                   supplier=supplier)
    base_unit_price = order.shop.create_price(taxless_base_unit_price)
    if order.prices_include_tax:
        base_unit_price *= (1 + tax_rate)
    product_order_line.base_unit_price = order.shop.create_price(
        base_unit_price)
    product_order_line.save()

    order_line_tax = OrderLineTax.from_tax(
        get_test_tax(tax_rate),
        Money(quantity * taxless_base_unit_price, order.currency),
        order_line=product_order_line,
    )
    order_line_tax.save(
    )  # Save order line tax before linking to order_line.taxes
    product_order_line.taxes.add(order_line_tax)
Beispiel #19
0
def test_product_purchasable_media():
    shop = get_default_shop()
    supplier = get_simple_supplier()
    product = create_product(
        "test-sku",
        shop=get_default_shop(),
        default_price=10,
    )
    medias = add_product_image(product, True)
    supplier.adjust_stock(product.id, 5)

    # Order with 2 unshipped, non-refunded items and a shipping cost
    order = create_order_with_product(product, supplier, 2, 200, shop=shop)

    order.create_shipment_of_all_products(supplier=supplier)
    order.shipping_status = ShippingStatus.FULLY_SHIPPED
    order.create_payment(order.taxful_total_price)
    currency = order.currency
    assert order.payments.exists(), "A payment was created"
    with pytest.raises(NoPaymentToCreateException):
        order.create_payment(Money(6, currency))

    order.save()
    assert order.is_paid()
    assert order.get_purchased_attachments().count() == len(medias)
Beispiel #20
0
 def get_total_unrefunded_amount(self, supplier=None):
     if supplier:
         total_refund_amount = sum([
             line.max_refundable_amount.value for line in self.lines.filter(
                 supplier=supplier).exclude(type=OrderLineType.REFUND)
         ])
         arbitrary_refunds = abs(
             sum([
                 refund_line.taxful_price.value for refund_line in
                 self.lines.filter(supplier=supplier,
                                   parent_line__isnull=True,
                                   type=OrderLineType.REFUND)
             ]))
         return (Money(max(total_refund_amount -
                           arbitrary_refunds, 0), self.currency)
                 if total_refund_amount else Money(0, self.currency))
     return max(self.taxful_total_price.amount, Money(0, self.currency))
Beispiel #21
0
def test_money_formatter_fi():
    with translation.override("fi-FI"):
        assert money(Money("29.99", "USD")) == nbsp("29,99 $")
        assert money(Money("29.99", "EUR")) == nbsp("29,99 €")
        assert money(Money("29.99", "GBP")) == nbsp("29,99 £")
        assert money(Money("29.99", "CAD")) == nbsp("29,99 CAD")
        assert money(Money("29.99", "JPY")) == nbsp("30 ¥")  # No such thing as a decimal yen!
        assert money(Money("29.99", "CNY")) == nbsp("29,99 CNY")
        assert money(Money("29.99", "KRW")) == nbsp("30 KRW")  # the 1/100 subunit "jeon" is theoretical and not in use
        assert money(Money("29.99", "SEK")) == nbsp("29,99 SEK")
Beispiel #22
0
def test_money_formatter_en():
    with translation.override("en-US"):
        assert money(Money("29.99", "USD")) == "$29.99"
        assert money(Money("29.99", "EUR")) == "€29.99"
        assert money(Money("29.99", "GBP")) == "£29.99"
        assert money(Money("29.99", "CAD")) == "CA$29.99"
        assert money(Money("29.99", "JPY")) == "¥30"  # No such thing as a decimal yen!
        assert money(Money("29.99", "CNY")) == "CN¥29.99"
        assert money(Money("29.99", "KRW")) == "₩30"  # the 1/100 subunit "jeon" is theoretical and not in use
        assert money(Money("29.99", "SEK")) == "kr29.99"
Beispiel #23
0
def test_as_rounded_rounding_mode():
    set_precision_provider(babel_precision_provider.get_precision)

    prec2 = Decimal("0.01")
    m1 = Money("2.345", "EUR")
    m2 = Money("2.344", "EUR")

    assert m1.as_rounded(2).value == Decimal("2.34")
    assert m2.as_rounded(2).value == Decimal("2.34")

    from decimal import ROUND_FLOOR, ROUND_HALF_DOWN, ROUND_HALF_UP

    assert m1.as_rounded(2, rounding=ROUND_HALF_DOWN).value == Decimal("2.34")
    assert m2.as_rounded(2, rounding=ROUND_HALF_DOWN).value == Decimal("2.34")
    assert m1.as_rounded(2, rounding=ROUND_HALF_UP).value == Decimal("2.35")
    assert m2.as_rounded(2, rounding=ROUND_HALF_UP).value == Decimal("2.34")
    assert m1.as_rounded(2, rounding=ROUND_FLOOR).value == Decimal("2.34")
    assert m2.as_rounded(2, rounding=ROUND_FLOOR).value == Decimal("2.34")
Beispiel #24
0
def test_refunds_rounding_multiple_partial_refund():
    shop = get_default_shop()
    supplier = get_default_supplier()
    product = create_product(
        "test-sku",
        shop=get_default_shop(),
        default_price=29.264,
    )
    order = create_order_with_product(product, supplier, 2, 29.264, shop=shop)
    order.cache_prices()
    assert len(order.lines.all()) == 1

    line = order.lines.first()
    order.create_refund([{"line": line, "quantity": 1, "amount": Money("29.26", order.currency)}])
    assert order.taxful_total_price == order.shop.create_price("29.27")
    order.create_refund([{"line": line, "quantity": 1, "amount": Money("29.27", order.currency)}])
    assert line.max_refundable_amount == Money("0", order.currency)
    assert order.taxful_total_price == order.shop.create_price(0)
Beispiel #25
0
def test_as_rounded_rounding_mode():
    set_precision_provider(babel_precision_provider.get_precision)

    prec2 = Decimal('0.01')
    m1 = Money('2.345', 'EUR')
    m2 = Money('2.344', 'EUR')

    assert m1.as_rounded(2).value == Decimal('2.34')
    assert m2.as_rounded(2).value == Decimal('2.34')

    from decimal import ROUND_HALF_DOWN, ROUND_HALF_UP, ROUND_FLOOR

    assert m1.as_rounded(2, rounding=ROUND_HALF_DOWN).value == Decimal('2.34')
    assert m2.as_rounded(2, rounding=ROUND_HALF_DOWN).value == Decimal('2.34')
    assert m1.as_rounded(2, rounding=ROUND_HALF_UP).value == Decimal('2.35')
    assert m2.as_rounded(2, rounding=ROUND_HALF_UP).value == Decimal('2.34')
    assert m1.as_rounded(2, rounding=ROUND_FLOOR).value == Decimal('2.34')
    assert m2.as_rounded(2, rounding=ROUND_FLOOR).value == Decimal('2.34')
Beispiel #26
0
def _handle_payment_creation(request, order):
    serializer = PaymentSerializer(data=request.data)
    serializer.is_valid(raise_exception=True)

    data = serializer.validated_data
    order.create_payment(
        Money(data["amount_value"], order.currency), data["payment_identifier"], data.get("description", "")
    )
    return Response({"success": _("Payment created")}, status=status.HTTP_201_CREATED)
Beispiel #27
0
def test_product_summary():
    shop = get_default_shop()
    supplier = get_simple_supplier()
    product = create_product(
        "test-sku",
        shop=get_default_shop(),
        default_price=10,
        stock_behavior=StockBehavior.STOCKED
    )
    supplier.adjust_stock(product.id, 5)

    # Order with 2 unshipped, non-refunded items and a shipping cost
    order = create_order_with_product(product, supplier, 2, 200, shop=shop)
    order.cache_prices()
    product_line = order.lines.first()
    shipping_line = order.lines.create(type=OrderLineType.SHIPPING, base_unit_price_value=5, quantity=1)

    # Make sure no invalid entries and check product quantities
    product_summary = order.get_product_summary()
    assert all(product_summary.keys())
    summary = product_summary[product.id]
    assert_defaultdict_values(summary, ordered=2, shipped=0, refunded=0, unshipped=2)

    # Create a shipment for the other item, make sure status changes
    assert order.shipping_status == ShippingStatus.NOT_SHIPPED
    assert order.can_create_shipment()
    order.create_shipment(supplier=supplier, product_quantities={product: 1})
    assert order.shipping_status == ShippingStatus.PARTIALLY_SHIPPED

    order.create_refund([{"line": shipping_line, "quantity": 1, "amount": Money(5, order.currency), "restock": False}])

    product_summary = order.get_product_summary()
    assert all(product_summary.keys())
    summary = product_summary[product.id]
    assert_defaultdict_values(summary, ordered=2, shipped=1, refunded=0, unshipped=1)

    # Create a refund for 2 items, we should get no negative values
    order.create_refund([{"line": product_line, "quantity": 2, "amount": Money(200, order.currency), "restock": False}])

    product_summary = order.get_product_summary()
    assert all(product_summary.keys())
    summary = product_summary[product.id]
    assert_defaultdict_values(summary, ordered=2, shipped=1, refunded=2, unshipped=0)
Beispiel #28
0
def create_tax_from_string(string):
    if ' ' in string:
        (spec, name) = string.split(' ', 1)
    else:
        name = spec = string
    if spec.startswith('$'):
        return create_tax(name, amount=Money(spec[1:], 'USD'))
    elif spec.endswith('%'):
        return create_tax(name, rate=(Decimal(spec[:-1]) / 100))
    raise ValueError('Error! Unknown tax string: %r.' % (string, ))
Beispiel #29
0
def test_as_rounded_values(currency, digits):
    set_precision_provider(babel_precision_provider.get_precision)

    amounts = [
        "1",
        "2",
        "3",
        "4",
        "1.23223",
        "12.24442",
        "42.26233",
        "1223.46636",
        "13.24655",
        "411.234554",
        "101.74363",
        "12.99346",
        "4222.57422",
        "112.93549",
        "199.2446",
        "422.29234",
        "1994.49654",
        "940.23452",
        "425.24566",
        "1994.496541234566",
        "940.2345298765",
        "425.2456612334",
    ]

    for amount in amounts:
        precision = Decimal("0.1")**digits

        rounded = Decimal(amount).quantize(precision)
        rounded2 = Decimal(amount).quantize(Decimal("0.01"))
        rounded3 = Decimal(amount).quantize(Decimal("0.001"))

        # test using the currency
        assert Money(amount, currency).as_rounded().value == rounded

        # test using digits
        assert Money(amount, currency).as_rounded(3).value == rounded3

        # test using not existent currency code
        assert Money(amount, "XTS").as_rounded().value == rounded2
Beispiel #30
0
def test_as_rounded_values(currency, digits):
    set_precision_provider(babel_precision_provider.get_precision)

    amounts = [
        '1',
        '2',
        '3',
        '4',
        '1.23223',
        '12.24442',
        '42.26233',
        '1223.46636',
        '13.24655',
        '411.234554',
        '101.74363',
        '12.99346',
        '4222.57422',
        '112.93549',
        '199.2446',
        '422.29234',
        '1994.49654',
        '940.23452',
        '425.24566',
        '1994.496541234566',
        '940.2345298765',
        '425.2456612334',
    ]

    for amount in amounts:
        precision = Decimal('0.1')**digits

        rounded = Decimal(amount).quantize(precision)
        rounded2 = Decimal(amount).quantize(Decimal('0.01'))
        rounded3 = Decimal(amount).quantize(Decimal('0.001'))

        # test using the currency
        assert Money(amount, currency).as_rounded().value == rounded

        # test using digits
        assert Money(amount, currency).as_rounded(3).value == rounded3

        # test using not existent currency code
        assert Money(amount, "XTS").as_rounded().value == rounded2