def get_line_taxes_for(order_line): get_default_tax() # Creates the Tax and TaxRule tax_module = DefaultTaxModule() tax_ctx = tax_module.get_context_from_order_source(order_line.order) product = order_line.product price = order_line.price taxed_price = tax_module.get_taxed_price_for(tax_ctx, product, price) return taxed_price.taxes
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)
def _get_template_engine_and_context(product_sku='6.0745'): engine = django.template.engines['jinja2'] assert isinstance(engine, django_jinja.backend.Jinja2) shop = get_default_shop() shop.currency = 'USD' shop.prices_include_tax = False shop.save() request = RequestFactory().get('/') request.shop = shop request.customer = AnonymousContact() request.person = request.customer PriceDisplayOptions(include_taxes=False).set_for_request(request) tax = get_default_tax() create_default_tax_rule(tax) tax_class = get_default_tax_class() order, order_line = _get_order_and_order_line(request) product = create_product(sku=product_sku, shop=shop, tax_class=tax_class) context = { 'request': request, 'prod': product, # TODO: Test also with variant products 'sline': _get_source_line(request), 'bline': _get_basket_line(request), 'oline': order_line, 'order': order } return (engine, context)
def test_product_price_info(admin_user, prices_include_tax, product_price, discount, tax_rate, taxful_price, taxless_price): shop = get_default_shop() shop.prices_include_tax = prices_include_tax shop.save() customer = create_random_person() group = customer.get_default_group() customer.user = admin_user customer.groups.add(group) customer.save() tax = factories.get_default_tax() tax.rate = Decimal(tax_rate) tax.save() product = create_product("Just-A-Product", shop, default_price=product_price) CgpDiscount.objects.create(product=product, shop=shop, group=group, discount_amount_value=discount) client = _get_client(admin_user) response = client.get("/api/wshop/front/shop_products/", format="json") data = response.data[0] discounted_price = (product_price - discount) price = (discounted_price if prices_include_tax else discounted_price * (1 + tax_rate)) base_price = (product_price if prices_include_tax else (product_price * (1 + tax_rate))) discount_value = (discount if prices_include_tax else (discount * (1 + tax_rate))) price_info = data["price_info"] def money_round(value): return Money(value, shop.currency).as_rounded(2) assert money_round(data["price"]) == money_round(price) assert money_round(price_info['base_price']) == money_round(base_price) assert money_round(price_info['taxful_price']) == money_round(taxful_price) if prices_include_tax: assert 'taxless_price' not in price_info assert 'taxless_base_price' not in price_info assert 'tax_amount' not in price_info else: assert money_round(price_info['taxless_base_price']) == money_round(product_price) assert money_round(price_info['taxful_base_price']) == money_round(base_price) assert money_round(price_info['taxless_price']) == money_round(taxless_price) assert money_round(price_info['tax_amount']) == money_round((product_price - discount) * tax_rate) assert money_round(price_info['price']) == money_round(price) assert money_round(price_info['discount_amount']) == money_round(discount_value) assert money_round(price_info['discount_rate']) == money_round(discount_value / price if discount else 0) assert price_info['is_discounted'] is (True if discount else False)
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) order_line_tax = OrderLineTax.from_tax( get_default_tax(), ol.taxless_price.amount, order_line=ol) order_line_tax.save() ol.taxes.add(order_line_tax) 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)
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() order_line_tax = OrderLineTax.from_tax( get_default_tax(), ol.taxless_price.amount, order_line=ol) order_line_tax.save() ol.taxes.add(order_line_tax) 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)
def test_broken_order(admin_user): """ """ quantities = [44, 23, 65] expected = sum(quantities) * 50 expected_based_on = expected / 1.5 # Wshop is calculating taxes per line so there will be some "errors" expected_based_on = ensure_decimal_places( Decimal("%s" % (expected_based_on + 0.01))) shop = get_default_shop() supplier = get_default_supplier() product1 = create_product("simple-test-product1", shop, supplier, 50) product2 = create_product("simple-test-product2", shop, supplier, 50) product3 = create_product("simple-test-product3", shop, supplier, 50) tax = get_default_tax() source = BasketishOrderSource(get_default_shop()) billing_address = get_address(country="US") shipping_address = get_address(name="Test street", country="US") source.status = get_initial_order_status() source.billing_address = billing_address source.shipping_address = shipping_address source.customer = create_random_person() source.payment_method = get_default_payment_method() source.shipping_method = get_default_shipping_method() source.add_line( type=OrderLineType.PRODUCT, product=product1, supplier=get_default_supplier(), quantity=quantities[0], base_unit_price=source.create_price(50), ) source.add_line( type=OrderLineType.PRODUCT, product=product2, supplier=get_default_supplier(), quantity=quantities[1], base_unit_price=source.create_price(50), ) source.add_line( type=OrderLineType.PRODUCT, product=product3, supplier=get_default_supplier(), quantity=quantities[2], base_unit_price=source.create_price(50), ) currency = "EUR" summary = source.get_tax_summary() assert len(summary) == 1 summary = summary[0] assert summary.taxful == Money(expected, "EUR") assert summary.based_on == Money(expected_based_on, "EUR") # originally non-rounded value assert bankers_round(source.get_total_tax_amount()) == summary.tax_amount assert source.taxless_total_price.value == expected_based_on assert summary.taxful.value == source.taxful_total_price.value assert summary.tax_amount == Money( bankers_round(source.taxful_total_price.value - source.taxless_total_price.value), currency) assert summary.taxful == summary.raw_based_on + summary.tax_amount assert summary.tax_rate == tax.rate assert summary.taxful.value == ( summary.based_on + summary.tax_amount).value - Decimal("%s" % 0.01) # create order from basket creator = OrderCreator() order = creator.create_order(source) assert order.taxless_total_price.value == expected_based_on # originally non-rounded value assert bankers_round(order.get_total_tax_amount()) == summary.tax_amount
def test_create_order(admin_user, currency): create_default_order_statuses() shop = get_default_shop() shop.currency = currency tax = get_default_tax() Currency.objects.get_or_create(code=currency, decimal_places=2) shop.save() sm = get_default_shipping_method() pm = get_default_payment_method() contact = create_random_person(locale="en_US", minimum_name_comp_len=5) default_group = get_default_customer_group() default_group.members.add(contact) account_manager = create_random_person(locale="en_US", minimum_name_comp_len=5) contact.account_manager = account_manager contact.save() product = create_product(sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop) assert not Order.objects.count() client = _get_client(admin_user) lines = [ { "type": "product", "product": product.id, "quantity": "1", "base_unit_price_value": "5.00" }, { "type": "product", "product": product.id, "quantity": "2", "base_unit_price_value": "1.00", "discount_amount_value": "0.50" }, { "type": "other", "sku": "hello", "text": "A greeting", "quantity": 1, "base_unit_price_value": "3.5" }, { "type": "text", "text": "This was an order!", "quantity": 0 }, ] response = client.post("/api/wshop/order/", content_type="application/json", data=json.dumps({ "shop": shop.pk, "shipping_method": sm.pk, "payment_method": pm.pk, "customer": contact.pk, "lines": lines })) assert response.status_code == 201 assert Order.objects.count() == 1 order = Order.objects.first() assert order.shop == shop assert order.shipping_method == sm assert order.payment_method == pm assert order.customer == contact assert order.creator == admin_user assert order.billing_address == contact.default_billing_address.to_immutable( ) assert order.shipping_address == contact.default_shipping_address.to_immutable( ) assert order.payment_status == PaymentStatus.NOT_PAID assert order.shipping_status == ShippingStatus.NOT_SHIPPED assert order.status == OrderStatus.objects.get_default_initial() assert order.taxful_total_price_value == decimal.Decimal(10) assert order.lines.count( ) == 6 # shipping line, payment line, 2 product lines, 2 other lines assert order.currency == currency for idx, line in enumerate(order.lines.all()[:4]): assert line.quantity == decimal.Decimal(lines[idx].get("quantity")) assert line.base_unit_price_value == decimal.Decimal(lines[idx].get( "base_unit_price_value", 0)) assert line.discount_amount_value == decimal.Decimal(lines[idx].get( "discount_amount_value", 0)) # Test tax summary response_data = json.loads(response.content.decode("utf-8")) # Tax summary should not be present here assert "summary" not in response_data response = client.get('/api/wshop/order/{}/taxes/'.format(order.pk)) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert "lines" in response_data assert "summary" in response_data line_summary = response_data["lines"] summary = response_data["summary"] first_tax_summary = summary[0] assert int(first_tax_summary["tax_id"]) == tax.id assert first_tax_summary["tax_rate"] == tax.rate first_line_summary = line_summary[0] assert "tax" in first_line_summary response = client.get("/api/wshop/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 assert "available_shipping_methods" in order_data assert "available_payment_methods" in order_data assert order_data["available_payment_methods"][0]["id"] == pm.id assert order_data["available_shipping_methods"][0]["id"] == sm.id assert order.account_manager == account_manager assert order.customer_groups.count() == contact.groups.count() for group in order.customer_groups.all(): assert contact.groups.filter(id=group.id).exists() assert order.tax_group is not None assert order.tax_group == contact.tax_group