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
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
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")
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
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
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")