Exemplo n.º 1
0
def test_get_by_identifier(admin_user):
    shop = get_default_shop()
    for i in range(1,10):
        order = create_empty_order(shop=shop)
        order.save()

    order = create_empty_order(shop=shop)
    order.save()
    client = _get_client(admin_user)
    response = client.get("/api/shuup/order/", data={"identifier": order.identifier})
    assert response.status_code == status.HTTP_200_OK
    order_data = json.loads(response.content.decode("utf-8"))
    assert order_data[0].get("id") == order.id
    assert order_data[0].get("identifier") == order.identifier
Exemplo n.º 2
0
def test_process_payment_return_request(rf):
    """
    Order payment with default payment method with ``CustomPaymentProcessor``
    should be deferred.

    Payment can't be processed if method doesn't have provider or provider
    is not enabled or payment method is not enabled.
    """
    pm = PaymentMethod.objects.create(
        shop=get_default_shop(), name="Test method", enabled=False, tax_class=get_default_tax_class())
    order = create_empty_order()
    order.payment_method = pm
    order.save()
    assert order.payment_status == PaymentStatus.NOT_PAID
    with pytest.raises(ValueError):  # Can't process payment with unusable method
        order.payment_method.process_payment_return_request(order, rf.get("/"))
    assert order.payment_status == PaymentStatus.NOT_PAID
    pm.payment_processor = get_custom_payment_processor()
    pm.payment_processor.enabled = False
    pm.save()

    with pytest.raises(ValueError):  # Can't process payment with unusable method
        order.payment_method.process_payment_return_request(order, rf.get("/"))
    assert order.payment_status == PaymentStatus.NOT_PAID
    pm.payment_processor.enabled = True
    pm.save()

    with pytest.raises(ValueError):  # Can't process payment with unusable method
        order.payment_method.process_payment_return_request(order, rf.get("/"))
    assert order.payment_status == PaymentStatus.NOT_PAID
    pm.enabled = True
    pm.save()

    order.payment_method.process_payment_return_request(order, rf.get("/"))
    assert order.payment_status == PaymentStatus.DEFERRED
Exemplo n.º 3
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)
Exemplo n.º 4
0
def test_order_customer_name_from_shipping_address():
    order = create_empty_order()
    assert order.customer_id is None
    assert order.orderer_id is None
    order.billing_address = None
    order.save()
    order.refresh_from_db()
    assert order.get_customer_name() == order.shipping_address.name
Exemplo n.º 5
0
def test_refno_generation(method):
    for attempt in range(10):
        with override_settings(SHUUP_REFERENCE_NUMBER_METHOD=method):
            order = create_empty_order()
            order.save()
            assert order.reference_number
        with pytest.raises(ValueError):
            get_reference_number(order)
Exemplo n.º 6
0
def test_complete_order(admin_user):
    shop = get_default_shop()
    order = create_empty_order(shop=shop)
    order.save()
    client = _get_client(admin_user)
    response = client.post("/api/shuup/order/%s/complete/" % order.pk)
    assert response.status_code == 200
    response = client.post("/api/shuup/order/%s/complete/" % order.pk)
    assert response.status_code == 400
Exemplo n.º 7
0
def test_order_customer_name_from_billing_address():
    person = create_random_person()
    order = create_empty_order()
    order.orderer = person
    order.save()
    order.refresh_from_db()
    assert order.customer_id is None
    assert order.orderer_id is not None
    assert order.get_customer_name() == order.billing_address.name
    assert order.shipping_address_id is not None
Exemplo n.º 8
0
def test_get_by_id(admin_user):
    shop = get_default_shop()
    order = create_empty_order(shop=shop)
    order.save()

    client = _get_client(admin_user)
    response = client.get("/api/shuup/order/%s/" % order.id)
    assert response.status_code == status.HTTP_200_OK
    order_data = json.loads(response.content.decode("utf-8"))
    assert order_data.get("id") == order.id
Exemplo n.º 9
0
def test_custom_refno_generation():
    methods = (
        custom_refno_gen,
        "%s.%s" % (__name__, custom_refno_gen.__name__)
    )
    for method in methods:
        with override_settings(SHUUP_REFERENCE_NUMBER_METHOD=method):
            order = create_empty_order()
            order.save()
            assert order.reference_number == custom_refno_gen(order)
        with pytest.raises(ValueError):
            get_reference_number(order)
Exemplo n.º 10
0
def test_orders_list_view(browser, admin_user, live_server):
    shop = get_default_shop()
    for i in range(0, 10):
        order = create_empty_order(shop=shop)
        order.save()

    # Set last one canceled
    Order.objects.last().set_canceled()

    initialize_admin_browser_test(browser, live_server)
    _visit_orders_list_view(browser, live_server)
    _test_status_filter(browser)  # Will set three orders from end canceled
Exemplo n.º 11
0
def test_custom_ident_generation():
    methods = (
        custom_ident_gen,
        "%s.%s" % (__name__, custom_ident_gen.__name__)
    )
    for method in methods:
        with override_settings(SHUUP_ORDER_IDENTIFIER_METHOD=method):
            order = create_empty_order()
            order.save()
            assert order.identifier == custom_ident_gen(order)
        with pytest.raises(ValueError):
            get_order_identifier(order)
Exemplo n.º 12
0
def test_get_by_status(admin_user):
    create_default_order_statuses()
    shop = get_default_shop()
    cancelled_status = OrderStatus.objects.get_default_canceled()
    for i in range(1, 10):
        order = create_empty_order(shop=shop)
        order.status = cancelled_status
        order.save()

    order = create_empty_order(shop=shop)
    order.save()
    client = _get_client(admin_user)
    response = client.get("/api/shuup/order/", data={"status": order.status.id})
    assert response.status_code == status.HTTP_200_OK
    order_data = json.loads(response.content.decode("utf-8"))

    assert len(order_data) == 1
    assert order_data[0].get("id") == order.id
    assert order_data[0].get("identifier") == order.identifier

    response = client.get("/api/shuup/order/", data={"status": cancelled_status.id})
    assert response.status_code == status.HTTP_200_OK
    order_data = json.loads(response.content.decode("utf-8"))
    assert len(order_data) == 9

    assert order.can_set_complete()
    old_status = order.status
    order.status = OrderStatus.objects.get_default_complete()
    order.save()

    assert old_status != order.status
    response = client.get("/api/shuup/order/", data={"status": old_status.id})
    assert response.status_code == status.HTTP_200_OK
    order_data = json.loads(response.content.decode("utf-8"))
    assert len(order_data) == 0

    response = client.get("/api/shuup/order/", data={"status": order.status.id})
    assert response.status_code == status.HTTP_200_OK
    order_data = json.loads(response.content.decode("utf-8"))
    assert len(order_data) == 1
Exemplo n.º 13
0
def test_editing_existing_order(rf, admin_user):
    modifier = UserFactory()
    get_initial_order_status()  # Needed for the API
    contact = create_random_person(locale="en_US", minimum_name_comp_len=5)
    state = get_frontend_order_state(contact=contact)
    shop = get_default_shop()
    order = create_empty_order(shop=shop)
    order.payment_data = {"payment_data": True}
    order.shipping_data = {"shipping_data": True}
    order.extra_data = {"external_id": "123"}
    order.save()
    assert order.lines.count() == 0
    assert order.pk is not None
    assert order.modified_by == order.creator
    request = get_frontend_request_for_command(state, "finalize", modifier)
    response = OrderEditView.as_view()(request, pk=order.pk)
    assert_contains(response, "orderIdentifier")  # this checks for status codes as a side effect
    data = json.loads(response.content.decode("utf8"))
    edited_order = Order.objects.get(pk=order.pk)  # Re fetch the initial order

    # Check that identifiers has not changed
    assert edited_order.identifier == data["orderIdentifier"] == order.identifier
    assert edited_order.pk == order.pk

    # Check that the product content is updated based on state
    assert edited_order.lines.count() == 5
    assert edited_order.customer == contact

    # Check that product line have right taxes
    for line in edited_order.lines.all():
        if line.type == OrderLineType.PRODUCT:
            assert [line_tax.tax.code for line_tax in line.taxes.all()] == ["test_code"]
            assert line.taxful_price.amount > line.taxless_price.amount

    # Make sure order modification information is correct
    assert edited_order.modified_by != order.modified_by
    assert edited_order.modified_by == modifier
    assert edited_order.modified_on > order.modified_on

    # Make sure all non handled attributes is preserved from original order
    assert edited_order.creator == order.creator
    assert edited_order.ip_address == order.ip_address
    assert edited_order.orderer == order.orderer
    assert edited_order.customer_comment == order.customer_comment
    assert edited_order.marketing_permission == order.marketing_permission
    assert edited_order.order_date == order.order_date
    assert edited_order.status == order.status
    assert edited_order.payment_data == order.payment_data
    assert edited_order.shipping_data == order.shipping_data
    assert edited_order.extra_data == order.extra_data
Exemplo n.º 14
0
def test_shipment_creation_with_invalid_unsaved_shipment():
    shop = get_default_shop()
    supplier = get_default_supplier()
    order = _get_order(shop, supplier)
    second_order = create_empty_order(shop=shop)
    second_order.full_clean()
    second_order.save()
    product_lines = order.lines.exclude(product_id=None)
    for line in product_lines:
        for i in range(0, int(line.quantity)):
            with pytest.raises(AssertionError):
                unsaved_shipment = Shipment(supplier=supplier, order=second_order)
                order.create_shipment({line.product: 1}, shipment=unsaved_shipment)
    assert order.shipments.count() == 0
Exemplo n.º 15
0
def test_known_extra_data():
    order = create_empty_order()
    order.shipping_data = {"instruction": "Hello"}
    order.payment_data = {"ssn": "101010-010X"}
    order.extra_data = {"wrapping_color": "blue"}
    order.save()
    with override_settings(
        SHUUP_ORDER_KNOWN_SHIPPING_DATA_KEYS=[("instruction", "Instruction")],
        SHUUP_ORDER_KNOWN_PAYMENT_DATA_KEYS=[("ssn", "Social Security Number")],
        SHUUP_ORDER_KNOWN_EXTRA_DATA_KEYS=[("wrapping_color", "Wrapping Color")],
    ):
        known_data = dict(order.get_known_additional_data())
        assert ("Instruction" in known_data)
        assert ("Social Security Number" in known_data)
        assert ("Wrapping Color" in known_data)
Exemplo n.º 16
0
def test_get_by_order_date(admin_user):
    shop = get_default_shop()
    today = dt.today()
    yesterday = dt.today() - datetime.timedelta(days=1)
    for i in range(1, 10):
        order = create_empty_order(shop=shop)
        order.order_date = yesterday
        order.save()

    order = create_empty_order(shop=shop)
    order.save()
    client = _get_client(admin_user)
    response = client.get("/api/shuup/order/", data={"date": today})
    assert response.status_code == status.HTTP_200_OK
    order_data = json.loads(response.content.decode("utf-8"))

    assert len(order_data) == 1
    assert order_data[0].get("id") == order.id
    assert order_data[0].get("identifier") == order.identifier

    response = client.get("/api/shuup/order/", data={"date": yesterday})
    assert response.status_code == status.HTTP_200_OK
    order_data = json.loads(response.content.decode("utf-8"))
    assert len(order_data) == 9
Exemplo n.º 17
0
def test_product_detail(browser, admin_user, live_server, settings):
    activate(settings.PARLER_DEFAULT_LANGUAGE_CODE)
    shop = get_default_shop()
    order = create_empty_order(shop=shop)
    order.save()
    initialize_admin_browser_test(browser, live_server, settings)
    url = reverse("shuup_admin:order.detail", kwargs={"pk": order.pk})
    browser.visit("%s%s" % (live_server, url))
    wait_until_condition(browser, condition=lambda x: x.is_text_present("Order %s" % order.pk))

    change_addresses(live_server, browser, order)

    set_status(browser, order, OrderStatus.objects.get_default_processing())
    assert order.can_set_complete()
    set_status(browser, order, OrderStatus.objects.get_default_complete())
Exemplo n.º 18
0
def test_empty_order():
    order = create_empty_order()
    order.save()
    with pytest.raises(NoProductsToShipException):
        order.create_shipment_of_all_products()
    with pytest.raises(NoProductsToShipException):
        order.create_shipment(supplier=None, product_quantities={1: 0})
    assert order.can_edit()
    order.set_canceled()
    assert not order.can_edit(), "Can't edit canceled order"
    assert not order.can_set_complete(), "Can't process canceled order"
    order.set_canceled()  # Again! (This should be a no-op)
    order.delete()
    assert order.pk and order.deleted, "Order is soft-deleted"
    order.delete()  # Again! (This, too, should be a no-op)
Exemplo n.º 19
0
def test_delete_toolbar_button(rf, admin_user, view_cls, get_method, method_attr):
    method = get_method()
    assert method.can_delete()
    view = view_cls.as_view()
    request = apply_request_middleware(rf.get("/"), user=admin_user)
    check_for_delete(view, request, method)

    # Create order for method and test the can_delete and edit view
    order = create_empty_order()
    setattr(order, method_attr, method)
    order.save()
    assert not method.can_delete()
    check_for_delete(view, request, method)

    # Make sure that the actual delete is also blocked
    with pytest.raises(ProtectedError):
        method.delete()
Exemplo n.º 20
0
def _get_order(shop, supplier, stocked=False):
    order = create_empty_order(shop=shop)
    order.full_clean()
    order.save()
    for product_data in _get_product_data(stocked):
        quantity = product_data.pop("quantity")
        product = create_product(
            sku=product_data.pop("sku"),
            shop=shop,
            supplier=supplier,
            default_price=3.33,
            **product_data)
        add_product_to_order(order, supplier, product, quantity=quantity, taxless_base_unit_price=1)
    order.cache_prices()
    order.check_all_verified()
    order.save()
    return order
Exemplo n.º 21
0
def test_rounding_with_taxes(prices):
    shop = get_default_shop()
    supplier = get_default_supplier()

    order = create_empty_order(shop=shop)
    order.save()
    product = create_product("test_sku",  shop=shop, supplier=supplier)
    tax_rate = Decimal("0.22222")
    for x, price in enumerate(prices):
        add_product_to_order(
            order, supplier, product, quantity=Decimal("2.22"),
            taxless_base_unit_price=Decimal(price), tax_rate=tax_rate)
    order.cache_prices()
    for x, order_line in enumerate(order.lines.all().order_by("ordering")):
        # Check that total prices calculated from priceful parts still matches
        assert _get_taxless_price(order_line) == order_line.taxless_price
        assert _get_taxful_price(order_line) == order_line.taxful_price
        assert order_line.price == (order_line.base_unit_price * order_line.quantity - order_line.discount_amount)
Exemplo n.º 22
0
def test_service_methods_with_long_name(rf):
    """
    Make sure that service methods with long names (up to the max length of
    shipping or payment method names) don't cause exceptions when creating
    an order.
    """
    MAX_LENGTH = 100
    long_name = "X" * MAX_LENGTH
    assert len(long_name) == MAX_LENGTH
    sm = ShippingMethod.objects.language("en").create(
        shop=get_default_shop(), name=long_name, enabled=True, tax_class=get_default_tax_class())
    pm = PaymentMethod.objects.language("en").create(
        shop=get_default_shop(), name=long_name, enabled=True, tax_class=get_default_tax_class())
    order = create_empty_order()
    order.shipping_method = sm
    order.payment_method = pm
    order.full_clean()
    order.save()
def _get_order(shop, supplier, has_price):
    order = create_empty_order(shop=shop)
    order.full_clean()
    order.save()
    for product_data in _get_product_data(has_price):
        quantity = product_data.pop("quantity")
        tax_rate = product_data.pop("tax_rate")
        product = create_product(
            sku=product_data.pop("sku"),
            shop=shop,
            supplier=supplier,
            **product_data)
        add_product_to_order(
            order, supplier, product, quantity=quantity,
            taxless_base_unit_price=product_data["default_price"], tax_rate=tax_rate)
    order.cache_prices()
    order.check_all_verified()
    order.save()
    return order
Exemplo n.º 24
0
def test_line_discount_more():
    order = create_empty_order()
    order.save()
    ol = OrderLine(order=order, type=OrderLineType.OTHER)
    ol.quantity = 5
    ol.base_unit_price = order.shop.create_price(30)
    ol.discount_amount = order.shop.create_price(50)
    ol.save()
    currency = order.shop.currency
    assert ol.taxless_base_unit_price == TaxlessPrice(30, currency)
    assert ol.taxless_discount_amount == TaxlessPrice(50, currency)
    assert ol.taxless_price == TaxlessPrice(5 * 30 - 50, currency)
    ol.taxes.add(OrderLineTax.from_tax(
        get_default_tax(), ol.taxless_price.amount, order_line=ol))
    assert ol.taxless_discount_amount == TaxlessPrice(50, currency)
    assert ol.taxful_discount_amount == TaxfulPrice(75, currency)
    assert ol.taxless_price == TaxlessPrice(100, currency)
    assert ol.taxful_price == TaxfulPrice(150, currency)
    assert ol.taxless_base_unit_price == TaxlessPrice(30, currency)
    assert ol.taxful_base_unit_price == TaxfulPrice(45, currency)
Exemplo n.º 25
0
def test_line_discount():
    order = create_empty_order(prices_include_tax=False)
    order.save()
    currency = order.shop.currency
    ol = OrderLine(order=order,
                   type=OrderLineType.OTHER,
                   quantity=5,
                   text="Thing")
    ol.discount_amount = order.shop.create_price(50)
    ol.base_unit_price = order.shop.create_price(40)
    ol.save()
    ol.taxes.add(
        OrderLineTax.from_tax(get_default_tax(),
                              ol.taxless_price.amount,
                              order_line=ol))
    assert ol.taxless_discount_amount == order.shop.create_price(50)
    assert ol.taxful_discount_amount == TaxfulPrice(75, currency)
    assert ol.taxless_price == order.shop.create_price(150)
    assert ol.taxful_price == TaxfulPrice(150 + 75, currency)
    assert ol.taxless_base_unit_price == order.shop.create_price(40)
    assert ol.taxful_base_unit_price == TaxfulPrice(60, currency)
    assert "Thing" in six.text_type(ol)
Exemplo n.º 26
0
def test_line_discount_more():
    order = create_empty_order()
    order.save()
    ol = OrderLine(order=order, type=OrderLineType.OTHER)
    ol.quantity = 5
    ol.base_unit_price = order.shop.create_price(30)
    ol.discount_amount = order.shop.create_price(50)
    ol.save()
    currency = order.shop.currency
    assert ol.taxless_base_unit_price == TaxlessPrice(30, currency)
    assert ol.taxless_discount_amount == TaxlessPrice(50, currency)
    assert ol.taxless_price == TaxlessPrice(5 * 30 - 50, currency)
    ol.taxes.add(
        OrderLineTax.from_tax(get_default_tax(),
                              ol.taxless_price.amount,
                              order_line=ol))
    assert ol.taxless_discount_amount == TaxlessPrice(50, currency)
    assert ol.taxful_discount_amount == TaxfulPrice(75, currency)
    assert ol.taxless_price == TaxlessPrice(100, currency)
    assert ol.taxful_price == TaxfulPrice(150, currency)
    assert ol.taxless_base_unit_price == TaxlessPrice(30, currency)
    assert ol.taxful_base_unit_price == TaxfulPrice(45, currency)
Exemplo n.º 27
0
def test_order_with_only_unshippable_products():
    shop = get_default_shop()
    supplier = get_default_supplier()

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

    product = create_product(
        "unshippable",
        shop=shop,
        supplier=supplier,
        default_price=5.55)
    product.shipping_mode = ShippingMode.NOT_SHIPPED
    product.save()
    add_product_to_order(order, supplier, product, quantity=4, taxless_base_unit_price=3)
    order.cache_prices()
    order.check_all_verified()
    order.save()

    assert not order.can_create_shipment()
    assert order.can_set_complete()
Exemplo n.º 28
0
def _get_order(shop, supplier, has_price):
    order = create_empty_order(shop=shop)
    order.full_clean()
    order.save()
    for product_data in _get_product_data(has_price):
        quantity = product_data.pop("quantity")
        tax_rate = product_data.pop("tax_rate")
        product = create_product(sku=product_data.pop("sku"),
                                 shop=shop,
                                 supplier=supplier,
                                 **product_data)
        add_product_to_order(
            order,
            supplier,
            product,
            quantity=quantity,
            taxless_base_unit_price=product_data["default_price"],
            tax_rate=tax_rate)
    order.cache_prices()
    order.check_all_verified()
    order.save()
    return order
Exemplo n.º 29
0
def test_line_discount():
    order = create_empty_order(prices_include_tax=False)
    order.save()
    currency = order.shop.currency
    ol = OrderLine(
        order=order,
        type=OrderLineType.OTHER,
        quantity=5,
        text="Thing"
    )
    ol.discount_amount = order.shop.create_price(50)
    ol.base_unit_price = order.shop.create_price(40)
    ol.save()
    ol.taxes.add(OrderLineTax.from_tax(
        get_default_tax(), ol.taxless_price.amount, order_line=ol))
    assert ol.taxless_discount_amount == order.shop.create_price(50)
    assert ol.taxful_discount_amount == TaxfulPrice(75, currency)
    assert ol.taxless_price == order.shop.create_price(150)
    assert ol.taxful_price == TaxfulPrice(150 + 75, currency)
    assert ol.taxless_base_unit_price == order.shop.create_price(40)
    assert ol.taxful_base_unit_price == TaxfulPrice(60, currency)
    assert "Thing" in six.text_type(ol)
Exemplo n.º 30
0
def test_rounding(prices):
    expected = 0
    for p in prices:
        expected += bankers_round(p, 2)

    order = create_empty_order(prices_include_tax=False)
    order.save()
    for x, price in enumerate(prices):
        ol = OrderLine(
            order=order,
            type=OrderLineType.OTHER,
            quantity=1,
            text="Thing",
            ordering=x,
            base_unit_price=order.shop.create_price(price),
        )
        ol.save()
    order.cache_prices()
    for x, order_line in enumerate(order.lines.all().order_by("ordering")):
        price = Decimal(prices[x]).quantize(Decimal(".1")**9)

        # make sure prices are in database with original precision
        assert order_line.base_unit_price == order.shop.create_price(price)

        # make sure the line taxless price is rounded
        assert order_line.taxless_price == order.shop.create_price(
            bankers_round(price, 2))

        # Check that total prices calculated from priceful parts still matches
        assert _get_taxless_price(order_line) == order_line.taxless_price
        assert _get_taxful_price(order_line) == order_line.taxful_price

        # make sure the line price is rounded
        assert order_line.price == order.shop.create_price(price)

    # make sure order total is rounded
    assert order.taxless_total_price == order.shop.create_price(
        bankers_round(expected, 2))
Exemplo n.º 31
0
def test_rounding_with_taxes(prices):
    shop = get_default_shop()
    supplier = get_default_supplier()

    order = create_empty_order(shop=shop)
    order.save()
    product = create_product("test_sku", shop=shop, supplier=supplier)
    tax_rate = Decimal("0.22222")
    for x, price in enumerate(prices):
        add_product_to_order(order,
                             supplier,
                             product,
                             quantity=Decimal("2.22"),
                             taxless_base_unit_price=Decimal(price),
                             tax_rate=tax_rate)
    order.cache_prices()
    for x, order_line in enumerate(order.lines.all().order_by("ordering")):
        # Check that total prices calculated from priceful parts still matches
        assert _get_taxless_price(order_line) == order_line.taxless_price
        assert _get_taxful_price(order_line) == order_line.taxful_price
        assert order_line.price == (
            order_line.base_unit_price * order_line.quantity -
            order_line.discount_amount)
Exemplo n.º 32
0
def create_multi_supplier_order_to_review(shop_product, customer):
    order = factories.create_empty_order(shop=shop_product.shop)
    order.full_clean()
    order.save()

    pricing_context = factories._get_pricing_context(order.shop,
                                                     order.customer)
    for supplier in shop_product.suppliers.all():
        factories.add_product_to_order(order, supplier, shop_product.product,
                                       1, shop_product.default_price_value, 0,
                                       pricing_context)

    order.cache_prices()
    order.save()

    order.customer = customer
    order.create_payment(order.taxful_total_price)
    for supplier in shop_product.suppliers.all():
        order.create_shipment_of_all_products(supplier)
    order.status = OrderStatus.objects.get_default_complete()
    order.save()

    return order
Exemplo n.º 33
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)
Exemplo n.º 34
0
def test_service_methods_with_long_name(rf):
    """
    Make sure that service methods with long names (up to the max length of
    shipping or payment method names) don't cause exceptions when creating
    an order.
    """
    MAX_LENGTH = 100
    long_name = "X" * MAX_LENGTH
    assert len(long_name) == MAX_LENGTH
    sm = ShippingMethod.objects.language("en").create(
        shop=get_default_shop(),
        name=long_name,
        enabled=True,
        tax_class=get_default_tax_class())
    pm = PaymentMethod.objects.language("en").create(
        shop=get_default_shop(),
        name=long_name,
        enabled=True,
        tax_class=get_default_tax_class())
    order = create_empty_order()
    order.shipping_method = sm
    order.payment_method = pm
    order.full_clean()
    order.save()
Exemplo n.º 35
0
def test_rounding(prices):
    expected = 0
    for p in prices:
        expected += bankers_round(p, 2)

    order = create_empty_order(prices_include_tax=False)
    order.save()
    for x, price in enumerate(prices):
        ol = OrderLine(
            order=order,
            type=OrderLineType.OTHER,
            quantity=1,
            text="Thing",
            ordering=x,
            base_unit_price=order.shop.create_price(price)
        )
        ol.save()
    order.cache_prices()
    for x, order_line in enumerate(order.lines.all().order_by("ordering")):
        price = Decimal(prices[x]).quantize(Decimal(".1") ** 9)

        # make sure prices are in database with original precision
        assert order_line.base_unit_price == order.shop.create_price(price)

        # make sure the line taxless price is rounded
        assert order_line.taxless_price == order.shop.create_price(bankers_round(price, 2))

        # Check that total prices calculated from priceful parts still matches
        assert _get_taxless_price(order_line) == order_line.taxless_price
        assert _get_taxful_price(order_line) == order_line.taxful_price

        # make sure the line price is rounded
        assert order_line.price == order.shop.create_price(price)

    # make sure order total is rounded
    assert order.taxless_total_price == order.shop.create_price(bankers_round(expected, 2))
Exemplo n.º 36
0
def test_order_shipments(rf, admin_user):
    shop = get_default_shop()
    supplier1 = Supplier.objects.create(identifier="1", name="supplier1")
    supplier1.shops.add(shop)
    supplier2 = Supplier.objects.create(identifier="2")
    supplier2.shops.add(shop)

    product1 = create_product("sku1", shop=shop, default_price=10)
    shop_product1 = product1.get_shop_instance(shop=shop)
    shop_product1.suppliers.set([supplier1])

    product2 = create_product("sku3",
                              shop=shop,
                              default_price=10,
                              shipping_mode=ShippingMode.NOT_SHIPPED)
    shop_product2 = product1.get_shop_instance(shop=shop)
    shop_product2.suppliers.set([supplier2])

    product_quantities = {
        supplier1.pk: {
            product1.pk: 20
        },
        supplier2.pk: {
            product2.pk: 10
        }
    }

    def get_quantity(supplier, product):
        return product_quantities[supplier.pk][product.pk]

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

    # Let's test the order shipment section for superuser
    request = apply_request_middleware(rf.get("/"), user=admin_user, shop=shop)

    # Add product 3 to order for supplier 2
    add_product_to_order(order, supplier2, product2,
                         get_quantity(supplier2, product2), 8)

    # Product is not shippable so order section should not be available
    assert not ShipmentSection.visible_for_object(order, request)

    # Add product 2 to order for supplier 1
    add_product_to_order(order, supplier1, product1,
                         get_quantity(supplier1, product1), 7)

    # Now we should see the shipment section
    assert ShipmentSection.visible_for_object(order, request)

    # Make order fully paid so we can start creting shipments and refunds
    order.cache_prices()
    order.check_all_verified()
    order.create_payment(order.taxful_total_price)
    assert order.is_paid()

    product_summary = order.get_product_summary()
    assert product_summary[product1.pk]["unshipped"] == 20
    assert product_summary[product2.pk]["unshipped"] == 0
    assert product_summary[product2.pk]["ordered"] == 10

    # Fully ship the order
    order.create_shipment({product1: 5}, supplier=supplier1)
    order.create_shipment({product1: 5}, supplier=supplier1)
    order.create_shipment({product1: 10}, supplier=supplier1)

    assert not order.get_unshipped_products()
    assert order.is_fully_shipped()

    context = ShipmentSection.get_context_data(order, request)
    assert len(context["suppliers"]) == 2
    assert len(context["create_urls"].keys()) == 2  # One for each supplier
    assert len(context["delete_urls"].keys()) == 3  # One for each shipment

    # Let's create staff user without any permissions
    staff_user = create_random_user(is_staff=True)
    group = get_default_permission_group()
    staff_user.groups.add(group)
    shop.staff_members.add(staff_user)
    request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop)
    context = ShipmentSection.get_context_data(order, request)
    assert len(context["suppliers"]) == 2
    assert len(context["create_urls"].keys()) == 0
    assert len(context["delete_urls"].keys()) == 0
    assert len(context["set_sent_urls"].keys()) == 0

    set_permissions_for_group(group, ["order.create-shipment"])
    request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop)
    context = ShipmentSection.get_context_data(order, request)
    assert len(context["suppliers"]) == 2
    assert len(context["create_urls"].keys()) == 2
    assert len(context["delete_urls"].keys()) == 0
    assert len(context["set_sent_urls"].keys()) == 0

    set_permissions_for_group(group, [
        "order.create-shipment", "order.delete-shipment",
        "order.set-shipment-sent"
    ])
    request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop)
    context = ShipmentSection.get_context_data(order, request)
    assert len(context["suppliers"]) == 2
    assert len(context["create_urls"].keys()) == 2
    assert len(context["delete_urls"].keys()) == 3
    assert len(context["set_sent_urls"].keys()) == 3

    # works fine while rendering
    rendered_content = loader.render_to_string(ShipmentSection.template,
                                               context={
                                                   ShipmentSection.identifier:
                                                   context,
                                                   "order": order,
                                               })
    all_urls = list(context["delete_urls"].values())
    all_urls.extend(list(context["set_sent_urls"].values()))
    for url in all_urls:
        assert url in rendered_content

    assert order.get_sent_shipments().count() == 0
    order.shipments.filter(status=ShipmentStatus.NOT_SENT) == 3

    client = Client()
    client.force_login(admin_user)

    # mark all shipments as sent!
    for mark_sent_url in context["set_sent_urls"].values():
        response = client.post(mark_sent_url)
        assert response.status_code == 302

    assert order.get_sent_shipments().count() == 3
    order.shipments.filter(status=ShipmentStatus.NOT_SENT) == 0

    # Make product1 unshipped
    product1.shipping_mode = ShippingMode.NOT_SHIPPED
    product1.save()

    # We still should see the order shipment section since existing shipments
    assert ShipmentSection.visible_for_object(order, request)

    # list all shipments in shipments list view
    response = client.get("{}?jq={}".format(
        reverse("shuup_admin:order.shipments.list"),
        json.dumps({
            "perPage": 10,
            "page": 1
        })))
    assert response.status_code == 200
    data = json.loads(response.content)
    assert len(data["items"]) == 3
    for item in data["items"]:
        assert item["status"] == "Sent"

    # Let's delete all shipments since both products is unshipped and we
    # don't need those.
    for shipment in order.shipments.all():
        shipment.soft_delete()

    assert not ShipmentSection.visible_for_object(order, request)
Exemplo n.º 37
0
def test_ref_lengths():
    from shuup.admin.modules.settings import consts
    from shuup.admin.modules.settings.enums import OrderReferenceNumberMethod

    # clear shop configurations
    shop = get_default_shop()

    ConfigurationItem.objects.filter(shop=shop).delete()
    order = create_empty_order(shop=shop)
    order.save()
    order.reference_number = None
    order.save()

    ref_number = get_reference_number(order)  # by default we return "unique"
    assert len(ref_number) == 17 + 1 # unique ref + checksum

    order.reference_number = None
    order.save()

    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_METHOD_FIELD, OrderReferenceNumberMethod.UNIQUE.value)
    ref_number = get_reference_number(order)
    assert len(ref_number) == 17 + 1  # unique ref + checksum

    order.reference_number = None
    order.save()

    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_LENGTH_FIELD, 25)
    ref_number = get_reference_number(order)
    assert len(ref_number) == 25 + 1  # unique ref + checksum

    order.reference_number = None
    order.save()

    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_LENGTH_FIELD, 19)
    ref_number = get_reference_number(order)
    assert len(ref_number) == 19 + 1  # Finnish case

    order.reference_number = None
    order.save()

    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_METHOD_FIELD, OrderReferenceNumberMethod.RUNNING.value)
    ref_number = get_reference_number(order)
    assert len(ref_number) == 19 + 1
    order.reference_number = None
    order.save()

    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_PREFIX_FIELD, "123")
    ref_number = get_reference_number(order)
    assert len(ref_number) == 19 + 1
    order.reference_number = None
    order.save()

    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_PREFIX_FIELD, 123)
    ref_number = get_reference_number(order)
    assert len(ref_number) == 19 + 1  # Finnish case
    order.reference_number = None
    order.save()

    # reset prefix
    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_PREFIX_FIELD, "")
    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_METHOD_FIELD, OrderReferenceNumberMethod.SHOP_RUNNING.value)
    ref_number = get_reference_number(order)
    assert len(ref_number) == 19 + 1  # Finnish case
    order.reference_number = None
    order.save()
Exemplo n.º 38
0
def test_order_refunds_with_multiple_suppliers():
    shop = get_default_shop()
    supplier1 = Supplier.objects.create(identifier="1", name="supplier1")
    supplier1.shops.add(shop)
    supplier2 = Supplier.objects.create(identifier="2")
    supplier2.shops.add(shop)
    supplier3 = Supplier.objects.create(identifier="3", name="s")
    supplier3.shops.add(shop)

    product1 = create_product("sku1", shop=shop, default_price=10)
    shop_product1 = product1.get_shop_instance(shop=shop)
    shop_product1.suppliers.set([supplier1, supplier2, supplier3])

    product2 = create_product("sku2", shop=shop, default_price=10)
    shop_product2 = product1.get_shop_instance(shop=shop)
    shop_product2.suppliers.set([supplier1, supplier2])

    product3 = create_product("sku3", shop=shop, default_price=10, shipping_mode=ShippingMode.NOT_SHIPPED)
    shop_product3 = product1.get_shop_instance(shop=shop)
    shop_product3.suppliers.set([supplier3])

    product_quantities = {
        supplier1: {product1: 5, product2: 6},
        supplier2: {product1: 3, product2: 13},
        supplier3: {product1: 1, product3: 50},
    }

    def get_quantity(supplier, product):
        return product_quantities[supplier.pk][product.pk]

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

    for supplier, product_data in six.iteritems(product_quantities):
        for product, quantity in six.iteritems(product_data):
            add_product_to_order(order, supplier, product, quantity, 5)

    # Lines without quantity shouldn't affect refunds
    other_line = OrderLine(
        order=order, type=OrderLineType.OTHER, text="This random line for textual information", quantity=0
    )
    other_line.save()
    order.lines.add(other_line)

    order.cache_prices()
    order.create_payment(order.taxful_total_price)
    assert order.is_paid()

    # All supplier should be able to refund the order
    assert order.can_create_refund()
    assert order.can_create_refund(supplier1)
    assert order.can_create_refund(supplier2)
    assert order.can_create_refund(supplier3)

    assert order.get_total_unrefunded_amount(supplier1).value == Decimal("55")  # 11 * 5
    assert order.get_total_unrefunded_quantity(supplier1) == Decimal("11")  # 5 x product1 and 6 x product2

    with pytest.raises(RefundExceedsAmountException):
        order.create_refund(
            [{"line": "amount", "quantity": 1, "amount": order.shop.create_price(60)}], supplier=supplier1
        )

    # Supplier 1 refunds the order
    order.create_refund(_get_refund_data(order, supplier1))
    assert order.get_total_refunded_amount(supplier1).value == Decimal("55")  # 11 * 5
    assert order.get_total_unrefunded_amount(supplier1).value == Decimal("0")

    assert not order.can_create_refund(supplier1)
    assert order.can_create_refund()
    assert order.can_create_refund(supplier2)
    assert order.can_create_refund(supplier3)

    assert order.get_total_unrefunded_amount(supplier2).value == Decimal("80")  # 16 * 5
    assert order.get_total_unrefunded_quantity(supplier2) == Decimal("16")  # 3 x product1 and 13 x product2

    with pytest.raises(RefundExceedsAmountException):
        order.create_refund(
            [{"line": "amount", "quantity": 1, "amount": order.shop.create_price(81)}], supplier=supplier2
        )

    # Supplier 2 refunds the order
    order.create_refund(_get_refund_data(order, supplier2))
    assert order.get_total_refunded_amount(supplier2).value == Decimal("80")  # 11 * 5
    assert order.get_total_unrefunded_amount(supplier2).value == Decimal("0")
    assert not order.can_create_refund(supplier1)
    assert not order.can_create_refund(supplier2)
    assert order.can_create_refund()
    assert order.can_create_refund(supplier3)

    assert order.get_total_unrefunded_amount(supplier3).value == Decimal("255")  # 51 * 5
    assert order.get_total_unrefunded_quantity(supplier3) == Decimal("51")  # 3 x product1 and 13 x product2

    with override_settings(SHUUP_ALLOW_ARBITRARY_REFUNDS=False):
        with pytest.raises(RefundArbitraryRefundsNotAllowedException):
            order.create_refund(
                [{"line": "amount", "quantity": 1, "amount": order.shop.create_price(200)}], supplier=supplier3
            )

    order.create_refund([{"line": "amount", "quantity": 1, "amount": order.shop.create_price(200)}], supplier=supplier3)
    assert OrderLine.objects.filter(order=order, supplier=supplier3, type=OrderLineType.REFUND).exists()

    # Supplier 3 refunds the order
    order.create_refund(_get_refund_data(order, supplier3))
    assert order.get_total_refunded_amount(supplier3).value == Decimal("255")  # 11 * 5
    assert order.get_total_unrefunded_amount(supplier3).value == Decimal("0")
    assert not order.can_create_refund(supplier1)
    assert not order.can_create_refund(supplier2)
    assert not order.can_create_refund(supplier3)
    assert not order.can_create_refund()
Exemplo n.º 39
0
def test_order_arbitrary_refunds_with_multiple_suppliers():
    shop = get_default_shop()
    supplier1 = Supplier.objects.create(identifier="1", name="supplier1")
    supplier1.shops.add(shop)
    supplier2 = Supplier.objects.create(identifier="2")
    supplier2.shops.add(shop)
    supplier3 = Supplier.objects.create(identifier="3", name="s")
    supplier3.shops.add(shop)

    product1 = create_product("sku1", shop=shop, default_price=10)
    shop_product1 = product1.get_shop_instance(shop=shop)
    shop_product1.suppliers.set([supplier1, supplier2, supplier3])

    product2 = create_product("sku2", shop=shop, default_price=10)
    shop_product2 = product1.get_shop_instance(shop=shop)
    shop_product2.suppliers.set([supplier1, supplier2])

    product3 = create_product("sku3", shop=shop, default_price=10, shipping_mode=ShippingMode.NOT_SHIPPED)
    shop_product3 = product1.get_shop_instance(shop=shop)
    shop_product3.suppliers.set([supplier3])

    product_quantities = {
        supplier1: {product1: 5, product2: 6},
        supplier2: {product1: 3, product2: 13},
        supplier3: {product1: 1, product3: 50},
    }

    def get_quantity(supplier, product):
        return product_quantities[supplier.pk][product.pk]

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

    for supplier, product_data in six.iteritems(product_quantities):
        for product, quantity in six.iteritems(product_data):
            add_product_to_order(order, supplier, product, quantity, 5)

    # Lines without quantity shouldn't affect refunds
    other_line = OrderLine(
        order=order, type=OrderLineType.OTHER, text="This random line for textual information", quantity=0
    )
    other_line.save()
    order.lines.add(other_line)

    order.cache_prices()
    order.create_payment(order.taxful_total_price)
    assert order.is_paid()

    # All supplier should be able to refund the order
    assert order.can_create_refund()
    assert order.can_create_refund(supplier1)
    assert order.can_create_refund(supplier2)
    assert order.can_create_refund(supplier3)

    # Step by step refund lines for supplier1
    assert order.can_create_refund()
    assert order.get_total_unrefunded_amount(supplier1).value == Decimal("55")  # 11 * 5
    assert order.get_total_unrefunded_amount().value == Decimal("390")  # 55 + 80 + 255
    proudct1_line_for_supplier1 = order.lines.filter(supplier=supplier1, product=product1).first()
    supplier1_refund_data = [
        {
            "line": proudct1_line_for_supplier1,
            "quantity": proudct1_line_for_supplier1.quantity,
            "amount": order.shop.create_price(20).amount,  # Line total is 5 * 5 = 25
            "restock_products": True,
        }
    ]
    order.create_refund(supplier1_refund_data)
    assert order.get_total_unrefunded_amount(supplier1).value == Decimal("35")

    order.create_refund(
        [{"line": "amount", "quantity": 1, "amount": order.shop.create_price(30).amount}], supplier=supplier1
    )

    assert order.get_total_unrefunded_amount(supplier1).value == Decimal("5")

    order.create_refund(
        [{"line": "amount", "quantity": 1, "amount": order.shop.create_price(5).amount}], supplier=supplier1
    )

    assert order.get_total_unrefunded_amount(supplier1).value == Decimal("0")
    assert order.can_create_refund(supplier1)  # Some quantity still left to refund

    proudct2_line_for_supplier1 = order.lines.filter(supplier=supplier1, product=product2).first()
    supplier1_restock_refund_data = [
        {
            "line": proudct2_line_for_supplier1,
            "quantity": proudct2_line_for_supplier1.quantity,
            "amount": order.shop.create_price(0).amount,  # Line total is 5 * 5 = 25
            "restock_products": True,
        }
    ]
    order.create_refund(supplier1_restock_refund_data)
    assert not order.can_create_refund(supplier1)

    # Step by step refund lines for supplier2
    assert order.can_create_refund()
    assert order.get_total_unrefunded_amount(supplier2).value == Decimal("80")  # 16 * 5
    assert order.get_total_unrefunded_amount().value == Decimal("335")  # 80 + 255
    proudct2_line_for_supplier2 = order.lines.filter(supplier=supplier2, product=product2).first()
    supplier2_refund_data = [
        {
            "line": proudct2_line_for_supplier2,
            "quantity": 10,
            "amount": order.shop.create_price(50).amount,  # Line total is 13 * 5 = 65
            "restock_products": True,
        }
    ]
    order.create_refund(supplier2_refund_data)
    assert order.get_total_unrefunded_amount(supplier2).value == Decimal("30")

    order.create_refund(
        [{"line": "amount", "quantity": 1, "amount": order.shop.create_price(5).amount}], supplier=supplier2
    )

    assert order.get_total_unrefunded_amount(supplier2).value == Decimal("25")

    order.create_refund(
        [{"line": "amount", "quantity": 1, "amount": order.shop.create_price(25).amount}], supplier=supplier2
    )

    assert order.get_total_unrefunded_amount(supplier2).value == Decimal("0")
    assert order.can_create_refund(supplier2)  # Some quantity still left to refund

    supplier2_restock_refund_data = [
        {
            "line": proudct2_line_for_supplier2,
            "quantity": 3,
            "amount": order.shop.create_price(0).amount,  # Line total is 5 * 5 = 25
            "restock_products": True,
        }
    ]
    order.create_refund(supplier2_restock_refund_data)

    proudct1_line_for_supplier2 = order.lines.filter(supplier=supplier2, product=product1).first()
    supplier1_restock_refund_data = [
        {
            "line": proudct1_line_for_supplier2,
            "quantity": proudct1_line_for_supplier2.quantity,
            "amount": order.shop.create_price(0).amount,  # Line total is 5 * 5 = 25
            "restock_products": True,
        }
    ]
    order.create_refund(supplier1_restock_refund_data)
    assert not order.can_create_refund(supplier2)

    # Step by step refund lines for supplier3
    assert order.can_create_refund()
    assert order.get_total_unrefunded_amount(supplier3).value == Decimal("255")  # 51 * 5
    assert order.get_total_unrefunded_amount().value == Decimal("255")  # 255

    order.create_refund(
        [{"line": "amount", "quantity": 1, "amount": order.shop.create_price(55).amount}], supplier=supplier3
    )

    assert order.get_total_unrefunded_amount(supplier3).value == Decimal("200")

    proudct3_line_for_supplier3 = order.lines.filter(supplier=supplier3, product=product3).first()
    supplier3_refund_data = [
        {
            "line": proudct3_line_for_supplier3,
            "quantity": 50,
            "amount": order.shop.create_price(200).amount,  # Line total is 13 * 5 = 65
            "restock_products": True,
        }
    ]
    order.create_refund(supplier3_refund_data)
    assert order.get_total_unrefunded_amount(supplier2).value == Decimal("0")
    assert order.get_total_unrefunded_amount().value == Decimal("0")
    assert order.can_create_refund(supplier3)  # Some quantity still left to refund

    proudct1_line_for_supplier3 = order.lines.filter(supplier=supplier3, product=product1).first()
    supplier3_restock_refund_data = [
        {
            "line": proudct1_line_for_supplier3,
            "quantity": proudct1_line_for_supplier3.quantity,
            "amount": order.shop.create_price(0).amount,  # Line total is 5 * 5 = 25
            "restock_products": True,
        }
    ]
    order.create_refund(supplier3_restock_refund_data)
    assert not order.can_create_refund(supplier3)
    assert not order.can_create_refund()
Exemplo n.º 40
0
def test_anon_disabling():
    with override_settings(SHUUP_ALLOW_ANONYMOUS_ORDERS=False):
        with pytest.raises(ValidationError):
            order = create_empty_order()
            order.save()
Exemplo n.º 41
0
def _create_order_for_day(shop, day):
    order = create_empty_order(shop)
    order.order_date = day
    order.save()
def test_get_best_selling_products(admin_user):
    shop1 = get_default_shop()
    shop2 = get_shop(True)
    person1 = create_random_person()
    person1.user = admin_user
    person1.save()

    supplier = create_simple_supplier("supplier1")
    client = _get_client(admin_user)

    # list best selling products
    response = client.get("/api/shuup/front/shop_products/best_selling/", {
        "shop": shop2.pk,
        "limit": 20
    })
    assert response.status_code == status.HTTP_200_OK
    products = json.loads(response.content.decode("utf-8"))
    assert len(products["results"]) == 0

    # THIS IS IMPORTANT!
    cache.clear()

    products = [
        create_product("Standard-%d" % x, supplier=supplier, shop=shop2)
        for x in range(10)
    ]

    # create 1 product with 4 variations
    parent_product = create_product("ParentProduct1",
                                    supplier=supplier,
                                    shop=shop2)
    children = [
        create_product("SimpleVarChild-%d" % x, supplier=supplier, shop=shop2)
        for x in range(4)
    ]
    for child in children:
        child.link_to_parent(parent_product)

    best_selling = defaultdict(int)

    # create orders with standard products
    for p_index in range(len(products)):
        order = create_empty_order(shop=shop2)
        order.save()
        qty = (len(products) - p_index)
        add_product_to_order(order, supplier, products[p_index], qty,
                             Decimal(1.0))
        order.create_shipment_of_all_products()
        order.status = OrderStatus.objects.get_default_complete()
        order.save(update_fields=("status", ))

        best_selling[products[p_index].id] = qty

    # create orders with variation products - the parent product is counted instead of its children
    for p_index in range(2):
        variation = random.choice(children)
        qty = 5
        order = create_empty_order(shop=shop2)
        order.save()
        add_product_to_order(order, supplier, variation, qty, Decimal(1.0))
        order.create_shipment_of_all_products()
        order.status = OrderStatus.objects.get_default_complete()
        order.save(update_fields=("status", ))
        best_selling[parent_product.id] = best_selling[parent_product.id] + qty

    # get the top 100 best selling products
    response = client.get("/api/shuup/front/shop_products/best_selling/", {
        "shop": shop2.pk,
        "limit": 100
    })
    assert response.status_code == status.HTTP_200_OK
    products = json.loads(response.content.decode("utf-8"))
    assert len(products["results"]) == len(
        best_selling)  # as we added less then 100, this must be true
    assert products["next"] is None

    # check the if all IDS are part of best selling
    for ix in range(len(products)):
        assert products["results"][ix]["product_id"] in best_selling.keys()

    # get the top 5 best selling products (we should get paginated results)
    response = client.get("/api/shuup/front/shop_products/best_selling/", {
        "shop": shop2.pk,
        "limit": 5
    })
    assert response.status_code == status.HTTP_200_OK
    products = json.loads(response.content.decode("utf-8"))
    assert len(products["results"]) == 5
    assert products["count"] == len(best_selling)
    assert products["next"] is not None
    sorted_best_selling_ids = [
        prod[0]
        for prod in sorted(best_selling.items(), key=lambda prod: -prod[1])
    ][:5]

    # check the if all the 5 best sellers are part of best selling
    for ix in range(len(products)):
        assert products["results"][ix]["product_id"] in sorted_best_selling_ids
Exemplo n.º 43
0
def test_get_best_selling_products(admin_user):
    shop1 = get_default_shop()
    shop2 = get_shop(True)
    person1 = create_random_person()
    person1.user = admin_user
    person1.save()

    supplier = create_simple_supplier("supplier1")
    client = _get_client(admin_user)

    # list best selling products
    response = client.get("/api/shuup/front/shop_products/best_selling/", {"shop": shop2.pk, "limit": 20})
    assert response.status_code == status.HTTP_200_OK
    products = json.loads(response.content.decode("utf-8"))
    assert len(products["results"]) == 0

    # THIS IS IMPORTANT!
    cache.clear()

    products = [create_product("Standard-%d" % x, supplier=supplier, shop=shop2) for x in range(10)]

    # create 1 product with 4 variations
    parent_product = create_product("ParentProduct1", supplier=supplier, shop=shop2)
    children = [create_product("SimpleVarChild-%d" % x, supplier=supplier, shop=shop2) for x in range(4)]
    for child in children:
        child.link_to_parent(parent_product)

    best_selling = defaultdict(int)

    # create orders with standard products
    for p_index in range(len(products)):
        order = create_empty_order(shop=shop2)
        order.save()
        qty = (len(products)-p_index)
        add_product_to_order(order, supplier, products[p_index], qty, Decimal(1.0))
        order.create_shipment_of_all_products()
        order.status = OrderStatus.objects.get_default_complete()
        order.save(update_fields=("status",))

        best_selling[products[p_index].id] = qty

    # create orders with variation products - the parent product is counted instead of its children
    for p_index in range(2):
        variation = random.choice(children)
        qty = 5
        order = create_empty_order(shop=shop2)
        order.save()
        add_product_to_order(order, supplier, variation, qty, Decimal(1.0))
        order.create_shipment_of_all_products()
        order.status = OrderStatus.objects.get_default_complete()
        order.save(update_fields=("status",))
        best_selling[parent_product.id] = best_selling[parent_product.id] + qty

    # get the top 100 best selling products
    response = client.get("/api/shuup/front/shop_products/best_selling/", {"shop": shop2.pk, "limit": 100})
    assert response.status_code == status.HTTP_200_OK
    products = json.loads(response.content.decode("utf-8"))
    assert len(products["results"]) == len(best_selling) # as we added less then 100, this must be true
    assert products["next"] is None

    # check the if all IDS are part of best selling
    for ix in range(len(products)):
        assert products["results"][ix]["product_id"] in best_selling.keys()

    # get the top 5 best selling products (we should get paginated results)
    response = client.get("/api/shuup/front/shop_products/best_selling/", {"shop": shop2.pk, "limit": 5})
    assert response.status_code == status.HTTP_200_OK
    products = json.loads(response.content.decode("utf-8"))
    assert len(products["results"]) == 5
    assert products["count"] == len(best_selling)
    assert products["next"] is not None
    sorted_best_selling_ids = [prod[0] for prod in sorted(best_selling.items(), key=lambda prod: -prod[1])][:5]

    # check the if all the 5 best sellers are part of best selling
    for ix in range(len(products)):
        assert products["results"][ix]["product_id"] in sorted_best_selling_ids
def test_order_shipment_section(rf, admin_user):
    shop = get_default_shop()
    supplier1 = Supplier.objects.create(identifier="1", name="supplier1")
    supplier1.shops.add(shop)
    supplier2 = Supplier.objects.create(identifier="2")
    supplier2.shops.add(shop)

    product1 = create_product("sku1", shop=shop, default_price=10)
    shop_product1 = product1.get_shop_instance(shop=shop)
    shop_product1.suppliers.set([supplier1])

    product2 = create_product("sku3", shop=shop, default_price=10, shipping_mode=ShippingMode.NOT_SHIPPED)
    shop_product2 = product1.get_shop_instance(shop=shop)
    shop_product2.suppliers.set([supplier2])

    product_quantities = {
        supplier1.pk: {
            product1.pk: 20
        },
        supplier2.pk: {
            product2.pk: 10
        }
    }

    def get_quantity(supplier, product):
        return product_quantities[supplier.pk][product.pk]

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

    # Let's test the order shipment section for superuser
    request = apply_request_middleware(rf.get("/"), user=admin_user, shop=shop)

    # Add product 3 to order for supplier 2
    add_product_to_order(order, supplier2, product2, get_quantity(supplier2, product2), 8)

    # Product is not shippable so order section should not be available
    assert not ShipmentSection.visible_for_object(order, request)

    # Add product 2 to order for supplier 1
    add_product_to_order(order, supplier1, product1, get_quantity(supplier1, product1), 7)

    # Now we should see the shipment section
    assert ShipmentSection.visible_for_object(order, request)

    # Make order fully paid so we can start creting shipments and refunds
    order.cache_prices()
    order.check_all_verified()
    order.create_payment(order.taxful_total_price)
    assert order.is_paid()

    product_summary = order.get_product_summary()
    assert product_summary[product1.pk]["unshipped"] == 20
    assert product_summary[product2.pk]["unshipped"] == 0
    assert product_summary[product2.pk]["ordered"] == 10

    # Fully ship the order
    order.create_shipment({product1: 5}, supplier=supplier1)
    order.create_shipment({product1: 5}, supplier=supplier1)
    order.create_shipment({product1: 10}, supplier=supplier1)

    assert not order.get_unshipped_products()
    assert order.is_fully_shipped()

    context = ShipmentSection.get_context_data(order, request)
    assert len(context["suppliers"]) == 2
    assert len(context["create_urls"].keys()) == 2  # One for each supplier
    assert len(context["delete_urls"].keys()) == 3  # One for each shipment

    # Let's create staff user without any permissions
    staff_user = create_random_user(is_staff=True)
    group = get_default_permission_group()
    staff_user.groups.add(group)
    shop.staff_members.add(staff_user)
    request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop)
    context = ShipmentSection.get_context_data(order, request)
    assert len(context["suppliers"]) == 2
    assert len(context["create_urls"].keys()) == 0
    assert len(context["delete_urls"].keys()) == 0

    set_permissions_for_group(group, ["order.create-shipment"])
    request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop)
    context = ShipmentSection.get_context_data(order, request)
    assert len(context["suppliers"]) == 2
    assert len(context["create_urls"].keys()) == 2
    assert len(context["delete_urls"].keys()) == 0

    set_permissions_for_group(group, ["order.create-shipment", "order.delete-shipment"])
    request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop)
    context = ShipmentSection.get_context_data(order, request)
    assert len(context["suppliers"]) == 2
    assert len(context["create_urls"].keys()) == 2
    assert len(context["delete_urls"].keys()) == 3

    # Make product1 unshipped
    product1.shipping_mode = ShippingMode.NOT_SHIPPED
    product1.save()

    # We still should see the order shipment section since existing shipments
    assert ShipmentSection.visible_for_object(order, request)

    # Let's delete all shipments since both products is unshipped and we
    # don't need those.
    for shipment in order.shipments.all():
        shipment.soft_delete()
    
    assert not ShipmentSection.visible_for_object(order, request)
Exemplo n.º 45
0
def test_ref_lengths():
    from shuup.admin.modules.settings import consts
    from shuup.admin.modules.settings.enums import OrderReferenceNumberMethod

    # clear shop configurations
    shop = get_default_shop()

    ConfigurationItem.objects.filter(shop=shop).delete()
    order = create_empty_order(shop=shop)
    order.save()
    order.reference_number = None
    order.save()

    ref_number = get_reference_number(order)  # by default we return "unique"
    assert len(ref_number) == 17 + 1  # unique ref + checksum

    order.reference_number = None
    order.save()

    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_METHOD_FIELD,
                      OrderReferenceNumberMethod.UNIQUE.value)
    ref_number = get_reference_number(order)
    assert len(ref_number) == 17 + 1  # unique ref + checksum

    order.reference_number = None
    order.save()

    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_LENGTH_FIELD, 25)
    ref_number = get_reference_number(order)
    assert len(ref_number) == 25 + 1  # unique ref + checksum

    order.reference_number = None
    order.save()

    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_LENGTH_FIELD, 19)
    ref_number = get_reference_number(order)
    assert len(ref_number) == 19 + 1  # Finnish case

    order.reference_number = None
    order.save()

    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_METHOD_FIELD,
                      OrderReferenceNumberMethod.RUNNING.value)
    ref_number = get_reference_number(order)
    assert len(ref_number) == 19 + 1
    order.reference_number = None
    order.save()

    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_PREFIX_FIELD, "123")
    ref_number = get_reference_number(order)
    assert len(ref_number) == 19 + 1
    order.reference_number = None
    order.save()

    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_PREFIX_FIELD, 123)
    ref_number = get_reference_number(order)
    assert len(ref_number) == 19 + 1  # Finnish case
    order.reference_number = None
    order.save()

    # reset prefix
    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_PREFIX_FIELD, "")
    configuration.set(shop, consts.ORDER_REFERENCE_NUMBER_METHOD_FIELD,
                      OrderReferenceNumberMethod.SHOP_RUNNING.value)
    ref_number = get_reference_number(order)
    assert len(ref_number) == 19 + 1  # Finnish case
    order.reference_number = None
    order.save()
Exemplo n.º 46
0
def test_order_product_summary_with_multiple_suppliers():
    shop = get_default_shop()
    supplier1 = Supplier.objects.create(identifier="1", name="supplier1")
    supplier1.shops.add(shop)
    supplier2 = Supplier.objects.create(identifier="2")
    supplier2.shops.add(shop)
    supplier3 = Supplier.objects.create(identifier="3", name="s")
    supplier3.shops.add(shop)

    product1 = create_product("sku1", shop=shop, default_price=10)
    shop_product1 = product1.get_shop_instance(shop=shop)
    shop_product1.suppliers = [supplier1, supplier2, supplier3]

    product2 = create_product("sku2", shop=shop, default_price=10)
    shop_product2 = product1.get_shop_instance(shop=shop)
    shop_product2.suppliers = [supplier1, supplier2]

    product3 = create_product("sku3",
                              shop=shop,
                              default_price=10,
                              shipping_mode=ShippingMode.NOT_SHIPPED)
    shop_product3 = product1.get_shop_instance(shop=shop)
    shop_product3.suppliers = [supplier3]

    product_quantities = {
        supplier1.pk: {
            product1.pk: 5,
            product2.pk: 6
        },
        supplier2.pk: {
            product1.pk: 3,
            product2.pk: 13
        },
        supplier3.pk: {
            product1.pk: 1,
            product3.pk: 50
        }
    }

    def get_quantity(supplier, product):
        return product_quantities[supplier.pk][product.pk]

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

    # Add product 3 to order for supplier 3
    add_product_to_order(order, supplier3, product3,
                         get_quantity(supplier3, product3), 8)
    assert order.get_product_ids_and_quantities()[product3.pk] == 50
    assert not order.has_products_requiring_shipment()
    assert not order.has_products_requiring_shipment(supplier3)

    # Add product 2 to order for supplier 1
    add_product_to_order(order, supplier1, product2,
                         get_quantity(supplier1, product2), 7)
    assert order.get_product_ids_and_quantities()[product2.pk] == 6
    assert order.has_products_requiring_shipment()
    assert order.has_products_requiring_shipment(supplier1)
    assert not order.has_products_requiring_shipment(supplier3)

    # Add product 2 to order for supplier 2
    add_product_to_order(order, supplier2, product2,
                         get_quantity(supplier2, product2), 6)
    assert order.get_product_ids_and_quantities()[product2.pk] == 19
    assert order.has_products_requiring_shipment()
    assert order.has_products_requiring_shipment(supplier1)
    assert order.has_products_requiring_shipment(supplier2)
    assert not order.has_products_requiring_shipment(supplier3)

    # Add product 1 to order for supplier 3
    add_product_to_order(order, supplier3, product1,
                         get_quantity(supplier3, product1), 5)
    assert order.get_product_ids_and_quantities()[product1.pk] == 1
    assert order.has_products_requiring_shipment()
    assert order.has_products_requiring_shipment(supplier1)
    assert order.has_products_requiring_shipment(supplier2)
    assert order.has_products_requiring_shipment(supplier3)

    # Add product 1 for supplier 1 and 3
    add_product_to_order(order, supplier1, product1,
                         get_quantity(supplier1, product1), 4)
    add_product_to_order(order, supplier2, product1,
                         get_quantity(supplier2, product1), 3)
    assert order.get_product_ids_and_quantities()[product1.pk] == 9

    product_summary = order.get_product_summary()
    _assert_product_summary(product_summary, product1.pk, 9, 9, 0, 0)
    _assert_product_summary(product_summary, product2.pk, 19, 19, 0, 0)
    _assert_product_summary(product_summary, product3.pk, 50, 0, 0, 0)

    # Test product summary per supplier
    product_summary = order.get_product_summary(supplier1)
    _assert_product_summary(product_summary, product1.pk, 5, 5, 0, 0)
    _assert_product_summary(product_summary, product2.pk, 6, 6, 0, 0)
    _assert_product_summary(product_summary, product3.pk, 0, 0, 0, 0)

    product_summary = order.get_product_summary(supplier2.pk)
    _assert_product_summary(product_summary, product1.pk, 3, 3, 0, 0)
    _assert_product_summary(product_summary, product2.pk, 13, 13, 0, 0)
    _assert_product_summary(product_summary, product3.pk, 0, 0, 0, 0)

    product_summary = order.get_product_summary(supplier3.pk)
    _assert_product_summary(product_summary, product1.pk, 1, 1, 0, 0)
    _assert_product_summary(product_summary, product2.pk, 0, 0, 0, 0)
    _assert_product_summary(product_summary, product3.pk, 50, 0, 0, 0)

    # Make order fully paid so we can start creting shipments and refunds
    order.cache_prices()
    order.check_all_verified()
    order.create_payment(order.taxful_total_price)
    assert order.is_paid()

    # Let's make suer all good with unshipped products
    unshipped_products = order.get_unshipped_products()
    assert unshipped_products[product1.pk]["unshipped"] == 9
    assert unshipped_products[product2.pk]["unshipped"] == 19
    assert unshipped_products.get(product3.pk) is None

    unshipped_products = order.get_unshipped_products(supplier1)
    assert unshipped_products[product1.pk]["unshipped"] == 5
    assert unshipped_products[product2.pk]["unshipped"] == 6

    unshipped_products = order.get_unshipped_products(supplier2)
    assert unshipped_products[product1.pk]["unshipped"] == 3
    assert unshipped_products[product2.pk]["unshipped"] == 13

    unshipped_products = order.get_unshipped_products(supplier3)
    assert unshipped_products[product1.pk]["unshipped"] == 1
    assert unshipped_products.get(product2.pk) is None
    assert unshipped_products.get(product3.pk) is None

    # Refund product3
    line_to_refund = order.lines.filter(product_id=product3.pk).first()
    order.create_refund([{
        "line": line_to_refund,
        "quantity": 10,
        "amount": shop.create_price("10").amount
    }])
    product_summary = order.get_product_summary()
    _assert_product_summary(product_summary, product3.pk, 50, 0, 0, 10)
    product_summary = order.get_product_summary(supplier3.pk)
    _assert_product_summary(product_summary, product3.pk, 50, 0, 0, 10)

    order.create_refund([{
        "line": line_to_refund,
        "quantity": 40,
        "amount": shop.create_price("20").amount
    }])
    product_summary = order.get_product_summary()
    _assert_product_summary(product_summary, product3.pk, 50, 0, 0, 50)
    product_summary = order.get_product_summary(supplier3.pk)
    _assert_product_summary(product_summary, product3.pk, 50, 0, 0, 50)

    # Then ship product 1 for all suppliers one by one
    order.create_shipment({product1: 1}, supplier=supplier3)
    unshipped_products = order.get_unshipped_products(supplier3)
    assert unshipped_products.get(product1.pk) is None
    unshipped_products = order.get_unshipped_products()
    assert unshipped_products[product1.pk]["unshipped"] == 8

    order.create_shipment({product1: 3}, supplier=supplier2)
    unshipped_products = order.get_unshipped_products(supplier2)
    assert unshipped_products.get(product1.pk) is None
    unshipped_products = order.get_unshipped_products()
    assert unshipped_products[product1.pk]["unshipped"] == 5

    order.create_shipment({product1: 5}, supplier=supplier1)
    unshipped_products = order.get_unshipped_products(supplier1)
    assert unshipped_products.get(product1.pk) is None
    unshipped_products = order.get_unshipped_products()
    assert unshipped_products.get(product1.pk) is None

    # Then ship product 2 for all suppliers with a twist
    order.create_shipment({product2: 13}, supplier=supplier2)
    unshipped_products = order.get_unshipped_products(supplier2)
    assert unshipped_products.get(product2.pk) is None
    unshipped_products = order.get_unshipped_products()
    assert unshipped_products[product2.pk]["unshipped"] == 6

    order.create_shipment({product2: 5}, supplier=supplier1)
    unshipped_products = order.get_unshipped_products(supplier1)
    assert unshipped_products[product2.pk]["unshipped"] == 1
    unshipped_products = order.get_unshipped_products()
    assert unshipped_products[product2.pk]["unshipped"] == 1
    product_summary = order.get_product_summary()
    _assert_product_summary(product_summary, product2.pk, 19, 1, 18, 0)

    # Refund the last product and see all falling in place
    line_to_refund = order.lines.filter(product_id=product2.pk,
                                        supplier=supplier1).first()
    order.create_refund([{
        "line": line_to_refund,
        "quantity": 1,
        "amount": shop.create_price("1").amount
    }])

    assert not order.get_unshipped_products()
    assert order.is_fully_shipped()

    # Verify product summary
    product_summary = order.get_product_summary()
    _assert_product_summary(product_summary,
                            product1.pk,
                            9,
                            0,
                            9,
                            0,
                            suppliers=[supplier1, supplier2, supplier3])
    _assert_product_summary(product_summary,
                            product2.pk,
                            19,
                            0,
                            18,
                            1,
                            suppliers=[supplier1, supplier2])
    _assert_product_summary(product_summary,
                            product3.pk,
                            50,
                            0,
                            0,
                            50,
                            suppliers=[supplier3])

    # Order prodcuts and quantities still match, right?
    order_products_and_quantities = order.get_product_ids_and_quantities()
    assert order_products_and_quantities[product1.pk] == 9
    assert order_products_and_quantities[product2.pk] == 19
    assert order_products_and_quantities[product3.pk] == 50

    # Order still has products requiring shipments, right?
    assert order.has_products_requiring_shipment()
    assert order.has_products_requiring_shipment(supplier1)
    assert order.has_products_requiring_shipment(supplier2)
    assert order.has_products_requiring_shipment(supplier3)
Exemplo n.º 47
0
def test_anon_disabling():
    with override_settings(SHUUP_ALLOW_ANONYMOUS_ORDERS=False):
        with pytest.raises(ValidationError):
            order = create_empty_order()
            order.save()
Exemplo n.º 48
0
def test_refunds_with_multiple_suppliers(rf, admin_user):
    shop = get_default_shop()
    supplier1 = Supplier.objects.create(identifier="1", name="supplier1")
    supplier1.shops.add(shop)

    supplier2 = Supplier.objects.create(identifier="2")
    supplier2.shops.add(shop)

    supplier3 = Supplier.objects.create(identifier="3", name="s")
    supplier3.shops.add(shop)

    product1 = create_product("sku1", shop=shop, default_price=10)
    shop_product1 = product1.get_shop_instance(shop=shop)
    shop_product1.suppliers = [supplier1, supplier2, supplier3]

    product2 = create_product("sku2", shop=shop, default_price=10)
    shop_product2 = product1.get_shop_instance(shop=shop)
    shop_product2.suppliers = [supplier1, supplier2]

    product3 = create_product("sku3",
                              shop=shop,
                              default_price=10,
                              shipping_mode=ShippingMode.NOT_SHIPPED)
    shop_product3 = product1.get_shop_instance(shop=shop)
    shop_product3.suppliers = [supplier3]

    product_quantities = {
        supplier1: {
            product1: 5,
            product2: 6
        },
        supplier2: {
            product1: 3,
            product2: 13
        },
        supplier3: {
            product1: 1,
            product3: 50
        }
    }

    def get_quantity(supplier, product):
        return product_quantities[supplier.pk][product.pk]

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

    for supplier, product_data in six.iteritems(product_quantities):
        for product, quantity in six.iteritems(product_data):
            add_product_to_order(order, supplier, product, quantity, 5)

    order.cache_prices()
    order.create_payment(order.taxful_total_price)
    assert order.is_paid()

    # All supplier should be able to refund the order
    assert order.can_create_refund()
    assert order.can_create_refund(supplier1)
    assert order.can_create_refund(supplier2)
    assert order.can_create_refund(supplier3)

    assert not order.has_refunds()
    assert len(order.lines.all()) == 6

    product_line = order.lines.first()
    data = {
        "form-0-line_number": 0,
        "form-0-quantity": 1,
        "form-0-amount": 1,
        "form-0-restock_products": False,
        "form-INITIAL_FORMS": 0,
        "form-MAX_NUM_FORMS": 1000,
        "form-TOTAL_FORMS": 1,
        "form-MIN_NUM_FORMS": 0,
    }

    supplier_provider = "shuup.testing.supplier_provider.RequestSupplierProvider"
    with override_settings(
            SHUUP_ADMIN_SUPPLIER_PROVIDER_SPEC=supplier_provider):
        # Test refund view content as superuser
        request = apply_request_middleware(rf.get("/", data=data),
                                           user=admin_user)
        view = OrderCreateRefundView.as_view()
        response = view(request, pk=order.pk)
        assert response.status_code == 200
        if hasattr(response, "render"):
            response.render()

        soup = BeautifulSoup(response.content)
        _assert_order_table_row_count(soup, 6)
        _assert_order_mobile_list_row_count(soup, 6)
        assert _get_create_full_refund_button(soup) is not None

        # Test refund view content as supplier 1
        request = apply_request_middleware(rf.get("/", data=data),
                                           user=admin_user)
        request.supplier = supplier1
        assert get_supplier(request) == supplier1

        view = OrderCreateRefundView.as_view()
        response = view(request, pk=order.pk)
        assert response.status_code == 200
        if hasattr(response, "render"):
            response.render()

        soup = BeautifulSoup(response.content)
        _assert_order_table_row_count(soup, 2)
        _assert_order_mobile_list_row_count(soup, 2)
        assert _get_create_full_refund_button(soup) is None

        # Test refund view content as supplier 2 user
        request = apply_request_middleware(rf.get("/", data=data),
                                           user=admin_user)
        request.supplier = supplier2
        assert get_supplier(request) == supplier2

        view = OrderCreateRefundView.as_view()
        response = view(request, pk=order.pk)
        assert response.status_code == 200
        if hasattr(response, "render"):
            response.render()

        soup = BeautifulSoup(response.content)
        _assert_order_table_row_count(soup, 2)
        _assert_order_mobile_list_row_count(soup, 2)
        assert _get_create_full_refund_button(soup) is None