Ejemplo n.º 1
0
def test_get_best_selling_products():
    context = get_jinja_context()
    cache.clear()
    # No products sold
    assert len(list(general.get_best_selling_products(context,
                                                      n_products=2))) == 0

    supplier = get_default_supplier()
    shop = get_default_shop()
    product = get_default_product()
    create_order_with_product(product,
                              supplier,
                              quantity=1,
                              taxless_base_unit_price=10,
                              shop=shop)
    cache.clear()
    # One product sold
    assert len(list(general.get_best_selling_products(context,
                                                      n_products=2))) == 1

    # Make order unorderable
    shop_product = product.get_shop_instance(shop)
    shop_product.visibility = ShopProductVisibility.NOT_VISIBLE
    shop_product.save()
    assert len(list(general.get_best_selling_products(context,
                                                      n_products=2))) == 0
Ejemplo n.º 2
0
def test_refunds_for_discounted_order_lines():
    shop = get_default_shop()
    supplier = get_default_supplier()
    product = create_product(
        "test-sku",
        shop=get_default_shop(),
        default_price=10,
        stock_behavior=StockBehavior.STOCKED
    )

    order = create_order_with_product(product, supplier, 2, 200, shop=shop)
    discount_line = OrderLine(
        order_id=order.id, type=OrderLineType.DISCOUNT, quantity=1, discount_amount_value=Decimal("0.54321"))
    discount_line.save()
    order.lines.add(discount_line)

    product_line = order.lines.filter(type=OrderLineType.PRODUCT).first()
    product_line.discount_amount = TaxfulPrice(100, order.currency)
    product_line.save()
    taxful_price_with_discount = product_line.taxful_price
    order.cache_prices()
    order.save()

    assert product_line.base_price == TaxfulPrice(400, order.currency)
    assert taxful_price_with_discount == TaxfulPrice(300, order.currency)

    # try to refund only the product line - should fail since this would result in a negative total
    with pytest.raises(RefundExceedsAmountException):
        order.create_refund([{"line": product_line, "quantity": 2, "amount": taxful_price_with_discount.amount}])

    # try to refund the product line with a negative amount
    with pytest.raises(InvalidRefundAmountException):
        order.create_refund([{"line": product_line, "quantity": 1, "amount": -taxful_price_with_discount.amount}])
    # try to refund the discount line with a positive amount
    with pytest.raises(InvalidRefundAmountException):
        order.create_refund([{"line": discount_line, "quantity": 1, "amount": -discount_line.taxful_price.amount}])

    order.create_refund([
        {"line": discount_line, "quantity": 1, "amount": discount_line.taxful_price.amount},
        {"line": product_line, "quantity": 2, "amount": taxful_price_with_discount.amount}
    ])
    assert product_line.max_refundable_amount.value == 0
    assert discount_line.max_refundable_amount.value == 0
    assert order.taxful_total_price.value == 0

    order = create_order_with_product(product, supplier, 2, 200, shop=shop)
    discount_line = OrderLine(
        order_id=order.id, type=OrderLineType.DISCOUNT, quantity=1, discount_amount_value=Decimal("0.54321"))
    discount_line.save()
    order.lines.add(discount_line)
    product_line = order.lines.filter(type=OrderLineType.PRODUCT).first()
    product_line.discount_amount = TaxfulPrice(100, order.currency)
    product_line.save()
    order.cache_prices()
    order.save()

    order.create_full_refund(restock_products=False)
    assert order.taxful_total_price.value == 0
def test_computing_simple_product_relations(rf):
    shop = get_default_shop()
    supplier = get_default_supplier()
    product = create_product("simple-test-product", shop)
    related_product = create_product("simple-related-product", shop)
    quantities = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    for quantity in quantities:
        order = create_order_with_product(product,
                                          supplier,
                                          quantity=1,
                                          taxless_base_unit_price=6,
                                          shop=shop)
        add_product_to_order(order,
                             supplier,
                             related_product,
                             quantity=quantity,
                             taxless_base_unit_price=6)

    assert ProductCrossSell.objects.count() == 0
    add_bought_with_relations_for_product(product.pk)
    assert ProductCrossSell.objects.count() == 1
    cross_sell_product = ProductCrossSell.objects.filter(
        product1=product).first()
    assert cross_sell_product.product2 == related_product
    assert cross_sell_product.weight == sum(quantities)

    add_bought_with_relations_for_product(related_product.id)
    assert ProductCrossSell.objects.count() == 2
    cross_sell_product = ProductCrossSell.objects.filter(
        product1=related_product).first()
    assert cross_sell_product.product2 == product
    assert cross_sell_product.weight == len(quantities)
Ejemplo n.º 4
0
def test_tracking_codes():
    product = get_default_product()
    supplier = get_default_supplier()
    order = create_order_with_product(product,
                                      supplier=supplier,
                                      quantity=1,
                                      taxless_base_unit_price=10,
                                      tax_rate=decimal.Decimal("0.5"))
    _add_product_to_order(order, "duck-tape-1", 3, order.shop, supplier)
    _add_product_to_order(order, "water-1", 2, order.shop, supplier)

    order.cache_prices()
    order.check_all_verified()
    order.save()

    # Create shipment with tracking code for every product line.
    product_lines = order.lines.exclude(product_id=None)
    assert len(product_lines) == 3
    for line in product_lines:
        shipment = order.create_shipment({line.product: line.quantity},
                                         supplier=supplier)
        if line.quantity != 3:
            shipment.tracking_code = "123FI"
            shipment.save()

    tracking_codes = order.get_tracking_codes()
    code_count = (len(product_lines) - 1)  # We skipped that one
    assert len(tracking_codes) == code_count
    assert len([
        tracking_code for tracking_code in tracking_codes
        if tracking_code == "123FI"
    ]) == code_count
def test_custom_payment_processor_cash_service(choice_identifier, expected_payment_status):
    shop = get_default_shop()
    product = get_default_product()
    supplier = get_default_supplier()
    processor = CustomPaymentProcessor.objects.create()
    payment_method = PaymentMethod.objects.create(
        shop=shop,
        payment_processor=processor,
        choice_identifier=choice_identifier,
        tax_class=get_default_tax_class())

    order = create_order_with_product(
        product=product,
        supplier=supplier,
        quantity=1,
        taxless_base_unit_price=Decimal('5.55'),
        shop=shop)
    order.taxful_total_price = TaxfulPrice(Decimal('5.55'), u'EUR')
    order.payment_method = payment_method
    order.save()

    assert order.payment_status == PaymentStatus.NOT_PAID
    processor.process_payment_return_request(choice_identifier, order, None)
    assert order.payment_status == expected_payment_status
    processor.process_payment_return_request(choice_identifier, order, None)
    assert order.payment_status == expected_payment_status
Ejemplo n.º 6
0
def test_extending_shipment_clean_hook(rf, admin_user):
    shop = get_default_shop()
    supplier = get_default_supplier()
    product = create_product(sku="test-sku",
                             shop=shop,
                             supplier=supplier,
                             default_price=3.33)
    quantity = 1
    order = create_order_with_product(product,
                                      supplier,
                                      quantity=quantity,
                                      taxless_base_unit_price=1,
                                      shop=shop)

    extend_form_class = "wshop_tests.admin.test_shipment_creator.ShipmentFormModifierTest"
    with override_provides(ShipmentForm.form_modifier_provide_key,
                           [extend_form_class]):
        data = {
            "q_%s" % product.pk: 1,
            "supplier": supplier.pk,
            "phone": "911"
        }
        request = apply_request_middleware(rf.post("/", data=data),
                                           user=admin_user)
        view = OrderCreateShipmentView.as_view()
        response = view(request, pk=order.pk).render()
        assert response.status_code == 200
        soup = BeautifulSoup(response.content)
        assert soup.body.findAll(
            text=re.compile("Phone number should start with country code!"))
Ejemplo n.º 7
0
def test_refund_entire_order_with_restock(admin_user):
    shop = get_default_shop()
    supplier = get_simple_supplier()
    product = create_product("test-sku",
                             shop=get_default_shop(),
                             default_price=10,
                             stock_behavior=StockBehavior.STOCKED)
    supplier.adjust_stock(product.id, 5)
    _check_stock_counts(supplier, product, 5, 5)

    order = create_order_with_product(product, supplier, 2, 200, shop=shop)
    order.payment_status = PaymentStatus.DEFERRED
    order.cache_prices()
    order.save()

    _check_stock_counts(supplier, product, 5, 3)
    assert not StockAdjustment.objects.filter(created_by=admin_user).exists()

    client = _get_client(admin_user)
    refund_url = "/api/wshop/order/%s/create_full_refund/" % order.id
    data = {"restock_products": True}
    response = client.post(refund_url, data, format="json")
    assert response.status_code == status.HTTP_201_CREATED
    order.refresh_from_db()

    # restock logical count
    _check_stock_counts(supplier, product, 5, 5)
    assert StockAdjustment.objects.filter(created_by=admin_user).exists()
Ejemplo n.º 8
0
def test_extending_shipment_with_extra_fields(rf, admin_user):
    shop = get_default_shop()
    supplier = get_default_supplier()
    product = create_product(sku="test-sku",
                             shop=shop,
                             supplier=supplier,
                             default_price=3.33)
    quantity = 1
    order = create_order_with_product(product,
                                      supplier,
                                      quantity=quantity,
                                      taxless_base_unit_price=1,
                                      shop=shop)

    extend_form_class = "wshop_tests.admin.test_shipment_creator.ShipmentFormModifierTest"
    with override_provides(ShipmentForm.form_modifier_provide_key,
                           [extend_form_class]):
        request = apply_request_middleware(rf.get("/"), user=admin_user)
        view = OrderCreateShipmentView.as_view()
        response = view(request, pk=order.pk).render()
        assert response.status_code == 200

        # Should contain supplier input, input for product and input for phone
        soup = BeautifulSoup(response.content)
        assert soup.find("input", {"id": "id_q_%s" % product.pk})
        assert soup.find("select", {"id": "id_supplier"})
        assert soup.find("input", {"id": "id_phone"})
Ejemplo n.º 9
0
def initialize_report_test(product_price, product_count, tax_rate, line_count):
    shop = get_default_shop()
    product = get_default_product()
    supplier = get_default_supplier()
    expected_taxless_total = product_count * product_price
    expected_taxful_total = product_count * product_price * (1 + tax_rate)
    order = create_order_with_product(
        product=product, supplier=supplier, quantity=product_count,
        taxless_base_unit_price=product_price, tax_rate=tax_rate, n_lines=line_count, shop=shop)
    order.create_payment(order.taxful_total_price.amount)
    order2 = create_order_with_product(
        product=product, supplier=supplier, quantity=product_count,
        taxless_base_unit_price=product_price, tax_rate=tax_rate, n_lines=line_count, shop=shop)
    order2.create_payment(order2.taxful_total_price.amount)
    order2.set_canceled()  # Shouldn't affect reports
    return expected_taxful_total, expected_taxless_total, shop, order
Ejemplo n.º 10
0
def test_refund_without_shipment(restock):
    shop = get_default_shop()
    supplier = get_simple_supplier()
    product = create_product(
        "test-sku",
        shop=get_default_shop(),
        default_price=10,
        stock_behavior=StockBehavior.STOCKED
    )
    # Start out with a supplier with quantity of 10 of a product
    supplier.adjust_stock(product.id, 10)
    check_stock_counts(supplier, product, physical=10, logical=10)

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

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

    if restock:
        check_stock_counts(supplier, product, physical=10, logical=10)
    else:
        check_stock_counts(supplier, product, physical=10, logical=8)
    assert product_line.refunded_quantity == 2
    assert order.get_total_tax_amount() == Money(
        order.taxful_total_price_value - order.taxless_total_price_value,
        order.currency)
Ejemplo n.º 11
0
def test_shipment_creating_view_post(rf, admin_user):
    shop = get_default_shop()
    supplier = get_default_supplier()
    product = create_product(sku="test-sku",
                             shop=shop,
                             supplier=supplier,
                             default_price=3.33)
    order = create_order_with_product(product,
                                      supplier,
                                      quantity=1,
                                      taxless_base_unit_price=1,
                                      shop=shop)

    data = {"q_%s" % product.pk: 1, "supplier": supplier.pk}
    request = apply_request_middleware(rf.post("/", data=data),
                                       user=admin_user)
    view = OrderCreateShipmentView.as_view()
    response = view(request, pk=order.pk)
    assert response.status_code == 302

    # Order should have shipment
    assert order.shipments.count() == 1
    shipment = order.shipments.first()
    assert shipment.supplier_id == supplier.id
    assert shipment.products.count() == 1
    assert shipment.products.first().product_id == product.id
Ejemplo n.º 12
0
def test_refund_entire_order():
    shop = get_default_shop()
    supplier = get_simple_supplier()
    product = create_product(
        "test-sku",
        shop=get_default_shop(),
        default_price=10,
        stock_behavior=StockBehavior.STOCKED
    )
    supplier.adjust_stock(product.id, 5)
    check_stock_counts(supplier, product, 5, 5)

    order = create_order_with_product(product, supplier, 2, 200, Decimal("0.24"), shop=shop)
    order.cache_prices()

    original_total_price = order.taxful_total_price
    check_stock_counts(supplier, product, 5, 3)

    # Create a full refund with `restock_products` set to False
    order.create_full_refund(restock_products=False)

    # Confirm the refund was created with correct amount
    assert order.taxless_total_price.amount.value == 0
    assert order.taxful_total_price.amount.value == 0
    refund_line = order.lines.order_by("ordering").last()
    assert refund_line.type == OrderLineType.REFUND
    assert refund_line.taxful_price == -original_total_price

    # Make sure logical count reflects refunded products
    check_stock_counts(supplier, product, 5, 3)
def test_simple_supplier(rf):
    supplier = get_simple_supplier()
    shop = get_default_shop()
    product = create_product("simple-test-product", shop)
    ss = supplier.get_stock_status(product.pk)
    assert ss.product == product
    assert ss.logical_count == 0
    num = random.randint(100, 500)
    supplier.adjust_stock(product.pk, +num)
    assert supplier.get_stock_status(product.pk).logical_count == num

    # Create order
    order = create_order_with_product(product, supplier, 10, 3, shop=shop)
    quantities = order.get_product_ids_and_quantities()
    pss = supplier.get_stock_status(product.pk)
    assert pss.logical_count == (num - quantities[product.pk])
    assert pss.physical_count == num
    # Create shipment

    shipment = order.create_shipment_of_all_products(supplier)
    assert isinstance(shipment, Shipment)
    pss = supplier.get_stock_status(product.pk)
    assert pss.logical_count == (num - quantities[product.pk])
    assert pss.physical_count == (num - quantities[product.pk])

    # Delete shipment
    with pytest.raises(NotImplementedError):
        shipment.delete()
    shipment.soft_delete()
    assert shipment.is_deleted()
    pss = supplier.get_stock_status(product.pk)
    assert pss.logical_count == (num - quantities[product.pk])
    assert pss.physical_count == (num)
Ejemplo n.º 14
0
def _create_order(shop, customer):
    p1 = factories.create_product("test", shop=shop, supplier=factories.get_default_supplier())
    order = factories.create_order_with_product(factories.get_default_product(), factories.get_default_supplier(), 2,
                                                10, shop=shop)
    factories.add_product_to_order(order, factories.get_default_supplier(), p1, 2, 5)
    order.customer = customer
    order.save()
    return order
Ejemplo n.º 15
0
def _create_total_paid_sales(shop, day):
    product = create_product("test", shop=shop)
    supplier = get_default_supplier()
    order = create_order_with_product(product, supplier, 1, 10, shop=shop)
    order.order_date = day
    order.save()
    order.create_payment(order.taxful_total_price)
    assert order.is_paid()
Ejemplo n.º 16
0
def test_can_create_payment():
    shop = get_default_shop()
    supplier = get_default_supplier()
    product = create_product(
        "test-sku",
        shop=get_default_shop(),
        default_price=10,
        stock_behavior=StockBehavior.STOCKED
    )

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

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

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

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

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

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

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

    # But fully refunded orders can't
    order.create_refund([
        {"line": order.lines.first(), "quantity": 1, "amount": Money(200, order.currency), "restock": False}])
    assert not order.can_create_payment()
Ejemplo n.º 17
0
def test_refunds(browser, admin_user, live_server, settings):
    order = create_order_with_product(get_default_product(),
                                      get_default_supplier(),
                                      10,
                                      decimal.Decimal("10"),
                                      n_lines=10,
                                      shop=get_default_shop())
    order2 = create_order_with_product(get_default_product(),
                                       get_default_supplier(),
                                       10,
                                       decimal.Decimal("10"),
                                       n_lines=10,
                                       shop=get_default_shop())
    order2.create_payment(order2.taxful_total_price)
    initialize_admin_browser_test(browser, live_server, settings)
    _test_toolbar_visibility(browser, live_server, order)
    _test_create_full_refund(browser, live_server, order)
    _test_refund_view(browser, live_server, order2)
Ejemplo n.º 18
0
def test_process_payment_return_request(rf, get_payment_processor,
                                        expected_final_payment_status):
    """
    Order payment with default payment method with ``CustomPaymentProcessor``
    provider should remain NOT_PAID.

    Order payment with default payment method with ``PaymentWithCheckoutPhase``
    provider should become DEFERRED.

    Payment can't be processed if method doesn't have provider or provider
    is not enabled or payment method is not enabled.
    """
    payment_processor = get_payment_processor()
    pm = PaymentMethod.objects.create(shop=get_default_shop(),
                                      name="Test method",
                                      enabled=False,
                                      tax_class=get_default_tax_class())
    product = create_product(sku="test-sku",
                             shop=get_default_shop(),
                             default_price=100)
    order = create_order_with_product(product=product,
                                      supplier=get_default_supplier(),
                                      quantity=1,
                                      taxless_base_unit_price=Decimal('5.55'),
                                      shop=get_default_shop())
    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 = 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()

    # Add payment data for checkout phase
    order.payment_data = {"input_value": True}
    order.payment_method.process_payment_return_request(order, rf.get("/"))
    assert order.payment_status == expected_final_payment_status
Ejemplo n.º 19
0
def test_order_verification():
    product = get_default_product()
    supplier = get_default_supplier()
    order = create_order_with_product(product, supplier=supplier, quantity=3, n_lines=10, taxless_base_unit_price=10)
    order.require_verification = True
    order.save()
    assert not order.check_all_verified(), "Nothing is verified by default"
    order.lines.filter(pk=order.lines.filter(verified=False).first().pk).update(verified=True)
    assert not order.check_all_verified(), "All is not verified even if something is"
    order.lines.all().update(verified=True)
    assert order.check_all_verified(), "All is now verified"
    assert not order.require_verification, "Verification complete"
Ejemplo n.º 20
0
def test_edit_view_with_anonymous_contact(rf, admin_user):
    shop = get_default_shop()
    supplier = get_default_supplier()
    product = create_product(sku=printable_gibberish(),
                             supplier=supplier,
                             shop=shop)
    order = create_order_with_product(product, supplier, 1, 10, shop=shop)
    order.save()
    assert not order.customer
    request = apply_request_middleware(rf.get("/"), user=admin_user)
    response = OrderEditView.as_view()(request=request, pk=order.pk)
    assert response.status_code == 200
Ejemplo n.º 21
0
def test_orderlinetax_tax_removal():
    #todo fix
    product = get_product()
    tax_rate = 1
    order = create_order_with_product(product=product,
                                      supplier=get_default_supplier(),
                                      quantity=1,
                                      taxless_base_unit_price=10,
                                      tax_rate=tax_rate,
                                      shop=get_default_shop())
    tax = get_test_tax(tax_rate)
    with pytest.raises(ProtectedError):
        tax.delete()
Ejemplo n.º 22
0
def test_refund_with_shipment(restock):
    shop = get_default_shop()
    supplier = get_simple_supplier()
    product = create_product(
        "test-sku",
        shop=get_default_shop(),
        default_price=10,
        stock_behavior=StockBehavior.STOCKED
    )
    # Start out with a supplier with quantity of 10 of a product
    supplier.adjust_stock(product.id, 10)
    check_stock_counts(supplier, product, physical=10, logical=10)

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

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

    # Check correct refunded quantities
    assert not product_line.refunded_quantity

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

    # Create a second refund that refunds the last shipped quantity, check stocks
    order.create_refund([
        {"line": product_line, "quantity": 1, "amount": Money(200, order.currency), "restock_products": restock}])
    assert product_line.refunded_quantity == 4
    if restock:
        # Make sure we're not restocking more than maximum restockable quantity
        check_stock_counts(supplier, product, physical=10, logical=10)
    else:
        # Make sure maximum restockable quantity is not 0
        check_stock_counts(supplier, product, physical=8, logical=6)
    assert order.get_total_tax_amount() == Money(
        order.taxful_total_price_value - order.taxless_total_price_value,
        order.currency)
Ejemplo n.º 23
0
def create_order():
    shop = get_default_shop()
    product = get_default_product()
    supplier = get_default_supplier()
    order = create_order_with_product(
        product,
        shop=shop,
        supplier=supplier,
        quantity=1,
        taxless_base_unit_price=10,
    )
    order.cache_prices()
    order.save()
    return order
Ejemplo n.º 24
0
def test_basic_order():
    PRODUCTS_TO_SEND = 10
    product = get_default_product()
    supplier = get_default_supplier()
    order = create_order_with_product(
        product,
        supplier=supplier,
        quantity=PRODUCTS_TO_SEND,
        taxless_base_unit_price=10,
        tax_rate=Decimal("0.5")
    )
    assert order.shop.prices_include_tax is False
    price = order.shop.create_price
    currency = order.currency

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

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

    summary = order.get_tax_summary()
    assert len(summary) == 2
    assert summary[0].tax_rate * 100 == 50
    assert summary[0].based_on == Money(100, currency)
    assert summary[0].tax_amount == Money(50, currency)
    assert summary[0].taxful == summary[0].based_on + summary[0].tax_amount
    assert summary[1].tax_id is None
    assert summary[1].tax_code == ''
    assert summary[1].tax_amount == Money(0, currency)
    assert summary[1].tax_rate == 0
    assert order.get_total_tax_amount() == Money(50, currency)
Ejemplo n.º 25
0
def create_fully_paid_order(shop, customer, supplier, product_sku,
                            price_value):
    product = create_product(product_sku,
                             shop=shop,
                             supplier=supplier,
                             default_price=price_value)
    order = create_order_with_product(product=product,
                                      supplier=supplier,
                                      quantity=1,
                                      taxless_base_unit_price=price_value,
                                      shop=get_default_shop())
    order.customer = customer
    order.save()
    order.cache_prices()
    return order.create_payment(order.taxful_total_price)
Ejemplo n.º 26
0
def test_can_create_shipment():
    shop = get_default_shop()
    supplier = get_simple_supplier()
    product = create_product(
        "test-sku",
        shop=get_default_shop(),
        default_price=10,
        stock_behavior=StockBehavior.STOCKED
    )
    supplier.adjust_stock(product.id, 10)

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

    # Fully shipped orders can't create shipments
    order.create_shipment_of_all_products(supplier)
    assert not order.can_create_shipment()

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

    # Canceled orders can't create shipments
    order.set_canceled()
    assert not order.can_create_shipment()
Ejemplo n.º 27
0
def test_printouts(rf):
    try:
        import weasyprint
    except ImportError:
        pytest.skip()

    shop = get_default_shop()
    supplier = get_default_supplier()
    product = create_product("simple-test-product", shop)
    order = create_order_with_product(product, supplier, 6, 6, shop=shop)
    shipment = order.create_shipment_of_all_products(supplier)
    request = rf.get("/")
    response = get_delivery_pdf(request, shipment.id)
    assert response.status_code == 200
    response = get_confirmation_pdf(request, order.id)
    assert response.status_code == 200
Ejemplo n.º 28
0
def test_refunds_rounding_multiple_partial_refund():
    shop = get_default_shop()
    supplier = get_default_supplier()
    product = create_product(
        "test-sku",
        shop=get_default_shop(),
        default_price=29.264,
    )
    order = create_order_with_product(product, supplier, 2, 29.264, shop=shop)
    order.cache_prices()
    assert len(order.lines.all()) == 1

    line = order.lines.first()
    order.create_refund([{"line": line, "quantity": 1, "amount": Money("29.26", order.currency)}])
    assert order.taxful_total_price == order.shop.create_price("29.27")
    order.create_refund([{"line": line, "quantity": 1, "amount": Money("29.27", order.currency)}])
    assert line.max_refundable_amount == Money("0", order.currency)
    assert order.taxful_total_price == order.shop.create_price(0)
Ejemplo n.º 29
0
def test_product_summary():
    shop = get_default_shop()
    supplier = get_simple_supplier()
    product = create_product(
        "test-sku",
        shop=get_default_shop(),
        default_price=10,
        stock_behavior=StockBehavior.STOCKED
    )
    supplier.adjust_stock(product.id, 5)

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

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

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

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

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

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

    product_summary = order.get_product_summary()
    assert all(product_summary.keys())
    summary = product_summary[product.id]
    assert_defaultdict_values(summary, ordered=2, shipped=1, refunded=2, unshipped=0)
Ejemplo n.º 30
0
def test_create_refund_view(rf, admin_user):
    shop = get_default_shop()
    supplier = get_default_supplier()
    product = create_product(sku="test-sku",
                             shop=shop,
                             supplier=supplier,
                             default_price=3.33)
    order = create_order_with_product(product,
                                      supplier,
                                      quantity=1,
                                      taxless_base_unit_price=1,
                                      shop=shop)
    order.cache_prices()
    order.save()

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

    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,
    }

    request = apply_request_middleware(rf.post("/", data=data),
                                       user=admin_user)
    view = OrderCreateRefundView.as_view()
    response = view(request, pk=order.pk)
    assert response.status_code == 302
    assert order.has_refunds()

    assert len(order.lines.all()) == 2
    refund_line = order.lines.filter(type=OrderLineType.REFUND).last()
    assert refund_line
    assert refund_line.taxful_price == -product_line.taxful_price