Example #1
0
def test_set_customer_with_custom_basket_lines(rf):
    """
    Set anonymous to the basket customer
    """
    with override_settings(**CORE_BASKET_SETTINGS):
        factories.get_default_shop()
        user = factories.create_random_user()
        request = apply_request_middleware(rf.get("/"), user=user)
        basket = get_basket(request, "basket")
        shipping_method = factories.get_default_shipping_method()
        payment_method = factories.get_default_payment_method()
        customer = get_person_contact(user)
        customer_comment = "Some comment"

        base_unit_price = basket.shop.create_price("10.99")

        basket.add_line(text="Custom Line",
                        type=OrderLineType.OTHER,
                        line_id="random-you-know",
                        shop=basket.shop,
                        quantity=1,
                        base_unit_price=base_unit_price)

        basket.customer = customer
        assert basket.customer_comment is None
        basket.customer_comment = customer_comment
        assert basket.payment_method is None
        assert basket.shipping_method is None
        basket.payment_method = payment_method
        basket.shipping_method = shipping_method
        basket.refresh_lines()
        basket.save()
        assert basket.customer == get_person_contact(user)
        assert basket.customer_comment == "Some comment"
        assert basket.shipping_method == shipping_method
        assert basket.payment_method == payment_method
Example #2
0
def test_basket_with_package_product(admin_user):
    with override_settings(**REQUIRED_SETTINGS):
        shop = factories.get_default_shop()
        factories.get_default_shipping_method()
        factories.get_default_payment_method()
        OrderStatusManager().ensure_default_statuses()

        client = get_client(admin_user)
        response = client.post("/api/E-Commerce/basket/new/", format="json", data={"shop": shop.pk})
        assert response.status_code == status.HTTP_201_CREATED
        basket_uuid = response.data["uuid"]

        supplier = factories.get_supplier(SimpleSupplierModule.identifier, shop=shop, stock_managed=True)

        # base product - 1kg of sand
        base_sand_product = factories.create_product(
            "Sand",
            shop=shop,
            supplier=supplier,
            default_price="15.2",
            net_weight=Decimal(1)
        )

        # 10kg bag of sand - package made by 10kg of sand
        sand_bag_10kg_product = factories.create_product(
            "Sand-bag-10-kg",
            shop=shop,
            supplier=supplier,
            default_price="149.9",
            net_weight=Decimal(10000)
        )
        sand_bag_10kg_product.make_package({
            base_sand_product: 10
        })
        sand_bag_10kg_product.save()

        # 18.45kg bag of sand - package made by 18.45kg of sand
        sand_bag_1845kg_product = factories.create_product(
            "Sand-bag-1845-kg",
            shop=shop,
            supplier=supplier,
            default_price="179.9",
            net_weight=Decimal(18450)
        )
        sand_bag_1845kg_product.make_package({
            base_sand_product: 18.45
        })
        sand_bag_1845kg_product.save()

        # 25kg bag of sand - package made by 25kg of sand
        sand_bag_25kg_product = factories.create_product(
            "Sand-bag-25-kg",
            shop=shop,
            supplier=supplier,
            default_price="2450.25",
            net_weight=Decimal(25000)
        )
        sand_bag_25kg_product.make_package({
            base_sand_product: 25
        })
        sand_bag_25kg_product.save()

        initial_stock = 55

        # put 55 sands (55kg) in stock
        supplier.adjust_stock(base_sand_product.id, initial_stock)
        stock_status = supplier.get_stock_status(base_sand_product.id)
        assert stock_status.physical_count == initial_stock
        assert stock_status.logical_count == initial_stock

        # zero stock for packages
        assert supplier.get_stock_status(sand_bag_10kg_product.id).logical_count == 0
        assert supplier.get_stock_status(sand_bag_1845kg_product.id).logical_count == 0
        assert supplier.get_stock_status(sand_bag_25kg_product.id).logical_count == 0

        # add all the 3 packages to the basket, this will require (10 + 18.45 + 25 = 53.45 Sands)
        for product in [sand_bag_10kg_product, sand_bag_1845kg_product, sand_bag_25kg_product]:
            response = client.post("/api/E-Commerce/basket/{}/add/".format(basket_uuid), format="json", data={
                "shop": shop.pk,
                "product": product.id
            })
            assert response.status_code == status.HTTP_200_OK

        # get the basket
        response = client.get("/api/E-Commerce/basket/{}/".format(basket_uuid))
        assert response.status_code == status.HTTP_200_OK
        assert response.data["validation_errors"] == []

        # now add more 25kg and it shouldn't have enough stock
        response = client.post("/api/E-Commerce/basket/{}/add/".format(basket_uuid), format="json", data={
            "shop": shop.pk,
            "product": sand_bag_25kg_product.id
        })
        assert response.status_code == status.HTTP_400_BAD_REQUEST
        assert "Insufficient stock" in response.data["error"]

        # create order anyway
        response = client.post("/api/E-Commerce/basket/{}/create_order/".format(basket_uuid), format="json")
        assert response.status_code == status.HTTP_201_CREATED
        order = Order.objects.get(id=response.data["id"])
        line_counter = Counter()

        for line in order.lines.products():
            line_counter[line.product.id] += line.quantity

        assert bankers_round(line_counter[base_sand_product.id]) == bankers_round(
            Decimal(10) + Decimal(18.45) + Decimal(25)
        )
        assert line_counter[sand_bag_10kg_product.id] == 1
        assert line_counter[sand_bag_1845kg_product.id] == 1
        assert line_counter[sand_bag_25kg_product.id] == 1
Example #3
0
def test_basket_reorder_staff_user():
    with override_settings(**REQUIRED_SETTINGS):
        set_configuration()
        shop = factories.get_default_shop()
        factories.get_default_payment_method()
        factories.get_default_shipping_method()
        staff_user = User.objects.create(username="******", is_staff=True)

        client = _get_client(staff_user)
        person = factories.create_random_person()

        # create an order for the person
        product = create_product("product", shop=shop, supplier=get_default_supplier(), default_price='12.4')
        order = create_random_order(customer=person, products=[product], completion_probability=1, shop=shop)

        # create the basket
        response = client.post("/api/E-Commerce/basket/new/", data={"shop": shop.pk, "customer": person.pk}, format="json")
        # Only stuff linked to shop can create baskets for someone else
        assert response.status_code == status.HTTP_403_FORBIDDEN

        # Can still add personal baskets
        staff_person = get_person_contact(staff_user)
        response = client.post("/api/E-Commerce/basket/new/", data={"shop": shop.pk, "customer": staff_person.pk}, format="json")
        assert response.status_code == status.HTTP_201_CREATED
        basket_data = json.loads(response.content.decode("utf-8"))
        basket = Basket.objects.filter(key=basket_data["uuid"].split("-")[1]).first()
        assert basket.shop == shop
        assert basket.creator == staff_user
        assert basket.customer.pk == staff_person.pk
        response = client.get("/api/E-Commerce/basket/{}/".format(basket_data["uuid"]))
        assert response.status_code == 200

        # Ok let's link the staff member to the shop and
        # the basket create for random person should work
        shop.staff_members.add(staff_user)
        response = client.post("/api/E-Commerce/basket/new/", data={"shop": shop.pk, "customer": person.pk}, format="json")
        assert response.status_code == status.HTTP_201_CREATED
        basket_data = json.loads(response.content.decode("utf-8"))
        basket = Basket.objects.filter(key=basket_data["uuid"].split("-")[1]).first()
        assert basket.shop == shop
        assert basket.creator == staff_user
        assert basket.customer.pk == person.pk
        response = client.get("/api/E-Commerce/basket/{}/".format(basket_data["uuid"]))
        assert response.status_code == 200
        assert basket.creator == staff_user
        assert basket.customer.pk == person.pk

        # add contents to the basket from a customer order
        response = client.post('/api/E-Commerce/basket/{}-{}/add_from_order/'.format(shop.pk, basket.key), data={"order": order.pk}, format="json")
        assert response.status_code == status.HTTP_200_OK
        basket_data = json.loads(response.content.decode("utf-8"))
        assert len(basket_data['items']) > 0
        assert Decimal(basket_data['taxful_total_price']) == order.taxful_total_price_value

        # finally create the order
        response = client.post('/api/E-Commerce/basket/{}-{}/create_order/'.format(shop.pk, basket.key))
        assert response.status_code == status.HTTP_201_CREATED
        response_data = json.loads(response.content.decode("utf-8"))
        created_order = Order.objects.get(id=response_data['id'])
        assert created_order.creator == staff_user
        assert created_order.customer == person

        # create a second customer
        person2 = factories.create_random_person()
        # create a basket for customer 2 and try to fill with contents of customer 1 order - it should not be possible
        response = client.post("/api/E-Commerce/basket/new/", data={"shop": shop.pk, "customer": person2.pk}, format="json")
        assert response.status_code == status.HTTP_201_CREATED
        basket_data = json.loads(response.content.decode("utf-8"))
        basket = Basket.objects.filter(key=basket_data["uuid"].split("-")[1]).first()
        assert basket.shop == shop
        assert basket.creator == staff_user
        assert basket.customer.pk == person2.pk

        # add contents to the basket from customer 1 order - error
        response = client.post('/api/E-Commerce/basket/{}-{}/add_from_order/'.format(shop.pk, basket.key), data={"order": order.pk}, format="json")
        assert response.status_code == status.HTTP_404_NOT_FOUND
        assert 'invalid order' in response.content.decode("utf-8")
Example #4
0
def test_create_order(admin_user, target_customer):
    with override_settings(**REQUIRED_SETTINGS):
        set_configuration()
        factories.create_default_order_statuses()
        shop = factories.get_default_shop()
        client = _get_client(admin_user)

        # Create basket for target customer
        payload = {"shop": shop.pk}
        target = orderer = get_person_contact(admin_user)
        if target_customer == "other_person":
            target = orderer = factories.create_random_person()
            payload["customer"] = target.pk
        elif target_customer == "company":
            target = factories.create_random_company()
            orderer = factories.create_random_person()
            payload.update({
                "customer": target.pk,
                "orderer": orderer.pk
            })
            target.members.add(orderer)

        response = client.post("/api/E-Commerce/basket/new/", payload)
        assert response.status_code == status.HTTP_201_CREATED
        basket_data = json.loads(response.content.decode("utf-8"))
        basket = Basket.objects.first()
        assert basket.key == basket_data["uuid"].split("-")[1]
        assert basket.customer == target
        assert basket.orderer == orderer

        shop_product = factories.get_default_shop_product()
        shop_product.default_price = TaxfulPrice(1, shop.currency)
        shop_product.save()

        # Add shop product to basket
        payload = {"shop_product": shop_product.id}
        response = client.post("/api/E-Commerce/basket/{}-{}/add/".format(shop.pk, basket.key), payload)
        assert response.status_code == status.HTTP_200_OK
        response_data = json.loads(response.content.decode("utf-8"))
        assert len(response_data["items"]) == 1

        # Create order from basket
        response = client.post("/api/E-Commerce/basket/{}-{}/create_order/".format(shop.pk, basket.key), payload)
        assert response.status_code == status.HTTP_400_BAD_REQUEST
        response_data = json.loads(response.content.decode("utf-8"))
        assert "errors" in response_data

        factories.get_default_payment_method()
        factories.get_default_shipping_method()
        response = client.post("/api/E-Commerce/basket/{}-{}/create_order/".format(shop.pk, basket.key), payload)
        assert response.status_code == status.HTTP_201_CREATED
        response_data = json.loads(response.content.decode("utf-8"))
        basket.refresh_from_db()
        assert basket.finished
        order = Order.objects.get(reference_number=response_data["reference_number"])
        assert order.status == OrderStatus.objects.get_default_initial()
        assert order.payment_status == PaymentStatus.NOT_PAID
        assert order.shipping_status == ShippingStatus.NOT_SHIPPED
        assert not order.payment_method
        assert not order.shipping_method
        assert float(order.taxful_total_price_value) == 1
        assert order.customer == target
        assert order.orderer == orderer
        assert order.creator == admin_user
        assert not order.billing_address
        assert not order.shipping_address
Example #5
0
def test_reorder_view():
    shop = factories.get_default_shop()
    factories.get_default_shipping_method()
    factories.get_default_payment_method()

    supplier1 = factories.get_supplier(SimpleSupplierModule.identifier, shop=shop)
    supplier2 = factories.get_supplier(SimpleSupplierModule.identifier, shop=shop)
    assert supplier1.pk != supplier2.pk

    product_supplier1 = factories.create_product(
        "product_supplier1",
        shop=shop,
        supplier=supplier1,
        default_price=10,
        shipping_mode=ShippingMode.NOT_SHIPPED
    )
    product_supplier2 = factories.create_product(
        "product_supplier2",
        shop=shop,
        supplier=supplier2,
        default_price=20,
        shipping_mode=ShippingMode.NOT_SHIPPED
    )

    user = factories.create_random_user("en")
    user.set_password("user")
    user.save()

    customer = factories.create_random_person("en")
    customer.user = user
    customer.save()

    order = factories.create_random_order(
        customer=customer,
        shop=shop,
        products=[product_supplier1, product_supplier2],
        completion_probability=0,
        random_products=False
    )
    suppliers = [line.supplier for line in order.lines.products()]
    assert supplier1 in suppliers
    assert supplier2 in suppliers

    client = Client()
    client.login(username=user.username, password="******")

    # list orders
    response = client.get(reverse("E-Commerce:personal-orders"))
    assert response.status_code == 200
    content = response.content.decode("utf-8")
    assert "<td>%d</td>" % order.id in content
    assert "<td>Received</td>" in content

    # go to order detail
    response = client.get(reverse("E-Commerce:show-order", kwargs=dict(pk=order.pk)))
    assert response.status_code == 200
    content = response.content.decode("utf-8")
    assert "Add all products to cart" in content
    reorder_url = reverse("E-Commerce:reorder-order", kwargs=dict(pk=order.pk))
    assert reorder_url in content

    # reorder products
    response = client.get(reorder_url)
    assert response.status_code == 302
    assert response.url.endswith(reverse("E-Commerce:basket"))

    # go to basket
    response = client.get(response.url)
    assert response.status_code == 200
    content = response.content.decode("utf-8")

    # ensure the basket contain those products and suppliers
    basket_key = client.session["basket_basket_key"]["key"]
    from E-Commerce.front.models import StoredBasket
    basket = StoredBasket.objects.get(key=basket_key)
    lines = basket.data["lines"]
    product_supplier = [(line["product_id"], line["supplier_id"]) for line in lines]
    assert (product_supplier1.pk, supplier1.pk) in product_supplier
    assert (product_supplier2.pk, supplier2.pk) in product_supplier

    assert product_supplier1.name in content
    assert product_supplier2.name in content
    assert "You are unable to proceed to checkout!" not in content
Example #6
0
def test_order_flow_with_multiple_suppliers():
    cache.clear()

    shop = factories.get_default_shop()
    factories.create_default_order_statuses()
    factories.get_default_payment_method()
    factories.get_default_shipping_method()

    n_orders_pre = Order.objects.count()
    product = factories.create_product("sku", shop=shop, default_price=30)
    shop_product = product.get_shop_instance(shop)

    # Activate show supplier info for front
    assert ThemeSettings.objects.count() == 1
    theme_settings = ThemeSettings.objects.first()
    theme_settings.update_settings({"show_supplier_info": True})

    supplier_data = [
        ("Johnny Inc", 30),
        ("Mike Inc", 10),
        ("Simon Inc", 20),
    ]
    for name, product_price in supplier_data:
        supplier = Supplier.objects.create(name=name)
        shop_product.suppliers.add(supplier)
        SupplierPrice.objects.create(supplier=supplier, shop=shop, product=product, amount_value=product_price)

    strategy = "E-Commerce.testing.supplier_pricing.supplier_strategy:CheapestSupplierPriceSupplierStrategy"
    with override_settings(E-Commerce_PRICING_MODULE="supplier_pricing", E-Commerce_SHOP_PRODUCT_SUPPLIERS_STRATEGY=strategy):

        # Ok so cheapest price should be default supplier
        expected_supplier = shop_product.get_supplier()
        assert expected_supplier.name == "Mike Inc"
        with override_current_theme_class(ClassicGrayTheme, shop):  # Ensure settings is refreshed from DB
            c = SmartClient()

            # Case 1: use default supplier
            _add_to_basket(c, product.pk, 2)
            order = _complete_checkout(c, n_orders_pre + 1)
            assert order
            product_lines = order.lines.products()
            assert len(product_lines) == 1
            assert product_lines[0].supplier.pk == expected_supplier.pk
            assert product_lines[0].base_unit_price_value == decimal.Decimal("10")

            # Case 2: force supplier to Johnny Inc
            johnny_supplier = Supplier.objects.filter(name="Johnny Inc").first()
            _add_to_basket(c, product.pk, 3, johnny_supplier)
            order = _complete_checkout(c, n_orders_pre + 2)
            assert order
            product_lines = order.lines.products()
            assert len(product_lines) == 1
            assert product_lines[0].supplier.pk == johnny_supplier.pk
            assert product_lines[0].base_unit_price_value == decimal.Decimal("30")

            # Case 3: order 2 pcs from Mike and 3 pcs from Simon Inc
            mike_supplier = Supplier.objects.filter(name="Mike Inc").first()
            _add_to_basket(c, product.pk, 2, mike_supplier)

            simon_supplier = Supplier.objects.filter(name="Simon Inc").first()
            _add_to_basket(c, product.pk, 3, simon_supplier)

            order = _complete_checkout(c, n_orders_pre + 3)
            assert order
            assert order.taxful_total_price_value == decimal.Decimal("80")  # Math: 2x10e + 3x20e

            product_lines = order.lines.products()
            assert len(product_lines) == 2

            mikes_line = [line for line in product_lines if line.supplier.pk == mike_supplier.pk][0]
            assert mikes_line
            assert mikes_line.quantity == 2
            assert mikes_line.base_unit_price_value == decimal.Decimal("10")

            simon_line = [line for line in product_lines if line.supplier.pk == simon_supplier.pk][0]
            assert simon_line
            assert simon_line.quantity == 3
            assert simon_line.base_unit_price_value == decimal.Decimal("20")