Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Missing taxes for undiscounted prices when creating the order from draft #15333

Open
korycins opened this issue Jan 30, 2024 · 2 comments
Open

Comments

@korycins
Copy link
Member

korycins commented Jan 30, 2024

What are you trying to achieve?

I try to receive the taxes calculated for undiscounted prices when creating the order from draft

Steps to reproduce the problem

  1. set up the taxes (tax app/ tax plugin)
  2. create the order from draft and include some discounted products
  3. the undiscounted values will not have calculated taxes

What did you expect to happen?

When creating the order from checkout, the taxes are calculated for undiscounted prices. It doesn't work in that way when order is created from draft. The undiscounted returns the same value for gross and net field.
image

Logs

No response

Environment

Saleor version: main (it probably works that way since 3.9, when we introduced the flat rates).
OS and version: …

@teddyondieki
Copy link
Contributor

@korycins can I work on this?

@korycins
Copy link
Member Author

Hey @teddyondieki , Yes! Would be great! 😄

Just quickly test it, and the issue doesn't happen when using flat tax rates. It happens when using TaxApp or TaxPlugin.

For the TaxPlugin, the issue is in _recalculate_with_plugins. This function calls _get_undiscounted_price, but _get_undiscounted_price has missing return condition:

def _get_undiscounted_price(
    line_price: OrderTaxedPricesData,
    line_base_price: Money,
    tax_rate,
    prices_entered_with_tax,
):
    if (
        tax_rate > 0
        and line_price.undiscounted_price.net == line_price.undiscounted_price.gross
    ):
        get_taxed_undiscounted_price(  <--- Here, we calculate the undiscounted, but we don't make a return
            line_base_price,
            line_price.undiscounted_price,
            tax_rate,
            prices_entered_with_tax,
        )
    return line_price.undiscounted_price

For taxApps, the saleor.order.calculations._apply_tax_data needs to be extended by adding the same logic, as we have for undiscounted prices in logic related to the plugins:

            line.undiscounted_unit_price = _get_undiscounted_price(
                line_unit,
                line.undiscounted_base_unit_price,
                line.tax_rate,
                prices_entered_with_tax,
            )

            line.undiscounted_total_price = _get_undiscounted_price(
                line_total,
                # base_order_line_total returns equal gross and net
                base_order_line_total(line).undiscounted_price.net,
                line.tax_rate,
                prices_entered_with_tax,
            )

Tests like this one: saleor.order.tests.test_calculations.test_recalculate_with_plugins should get an additional validation for undiscounted prices. Something like:

    for line_unit, line_total, tax_rate, line in zip(
        unit_prices, total_prices, tax_rates, lines
    ):
        undiscounted_unit_gross = line_unit.undiscounted_price.net.amount * (
            tax_rate + 1
        )
        undiscounted_total_gross = line_total.undiscounted_price.net.amount * (
            tax_rate + 1
        )
        assert line.undiscounted_unit_price.gross != line.undiscounted_unit_price.net <-- this one
        assert line.undiscounted_total_price.gross != line.undiscounted_total_price.net <-- this one

(You will also need to clean up the line.undiscounted_unit_price as it already has a calculated taxes. Something like this:

def test_recalculate_with_plugins(order_with_lines, order_lines, tax_data):
    # given
    order = order_with_lines
    currency = order.currency
    lines = list(order_lines)

    total_prices = [
        get_order_priced_taxes_data(line, "total", currency) for line in tax_data.lines
    ]
    unit_prices = []
    for line, total_price in zip(lines, total_prices):
        line.undiscounted_unit_price = TaxedMoney( # <-- This line
            net=line.undiscounted_unit_price.net,
            gross=line.undiscounted_unit_price.net
        )
        unit_prices.append(
            OrderTaxedPricesData(
                undiscounted_price=line.undiscounted_unit_price, #<-- And this line, as this is used for setting up the mock for Manager
                price_with_discounts=total_price.price_with_discounts / line.quantity,
            )
        )
---
Tests for taxApps like this one: `saleor.checkout.tests.test_calculations.test_apply_tax_data` should also get a similar fields validation as above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants