fix: stop double tax when prices are entered inclusive of tax#222
fix: stop double tax when prices are entered inclusive of tax#222kzamanbd wants to merge 5 commits into
Conversation
WC order line totals are tax-exclusive, but the POS sent the raw (gross) product price as the line total, so WC added tax on top and inclusive-price orders were taxed twice (100 became 110). - net gross POS line totals server-side with WC_Tax::calc_inclusive_tax (Manager.php); skips legacy Vue payloads, which post no totals and are already netted by WC - fall back to the store base address for tax location when a walk-in POS order has no billing/shipping address (tax resolved to zero and the customer was charged the net price) - derive cart display prices at render time from entry-mode raw price + per-unit tax_amount so totals follow the current tax display settings instead of stale stored values; sync prices_include_tax into the cart store and persist both tax flags so first render is correct before settings load - WC-style inclusive display: no separate tax row; "Including Tax X" note on subtotal/total in cart, payment modal, and receipt - misc products: carry tax_class/tax_status through cart, payload (_wepos_pos_data) and held-order restore; never merge distinct custom lines; send placeholder SKU to pass WC product-reference validation; skip stock validation for product-less lines - restore held orders with entry-mode raw prices and per-unit tax so display and re-save stay consistent
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughPOS tax handling now shares tax-inclusion state and conversion helpers across cart calculations, checkout displays, order restoration, custom lines, and REST order creation. Missing POS tax locations and product references receive explicit fallbacks. ChangesTax-inclusive POS pricing
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant HomePage
participant RESTManager
participant WooCommerceOrder
HomePage->>RESTManager: submit POS line totals and tax metadata
RESTManager->>WooCommerceOrder: convert inclusive totals to net line totals
WooCommerceOrder-->>RESTManager: persist order items
RESTManager-->>HomePage: return saved order data
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
c64094c to
afe848f
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/frontend/components/Cart.tsx`:
- Line 41: Update the helpers import in Cart.tsx to include findTaxRate, which
is referenced by handleAddMiscProduct but currently unresolved. Preserve the
existing imports and use the exported helper so taxable miscellaneous products
can be added successfully.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 57d73e34-a164-48ae-9ab6-c32e33b175e9
📒 Files selected for processing (13)
includes/Common.phpincludes/REST/Manager.phpsrc/frontend/components/Cart.tsxsrc/frontend/components/PaymentModal.tsxsrc/frontend/components/ReceiptModal.tsxsrc/frontend/pages/Home.tsxsrc/frontend/store/cart/actions.tssrc/frontend/store/cart/reducer.tssrc/frontend/store/cart/selectors.tssrc/frontend/store/cart/store.tssrc/frontend/store/cart/types.tssrc/frontend/types/index.tssrc/frontend/utils/helpers.ts
Problem
With WooCommerce set to "Yes, I will enter prices inclusive of tax", POS orders were taxed twice: a 100.00 product (incl. 10% VAT) saved as net 100 + VAT 10 = 110.00 instead of net 90.91 + VAT 9.09 = 100.00. WC order line totals are always tax-exclusive, but the POS posted the raw (gross) price as the line total, so WC calculated tax on top of it.
Related display bugs: cart totals drifted to 109.09 when the tax display mode changed or before settings loaded, and the payment modal showed
Subtotal 100 + Tax 9.09 = Total 100, which read as broken math.Fix
Server (authoritative):
Manager.php::convert_inclusive_line_totals— nets gross POS line totals with exactWC_Tax::calc_inclusive_taxmath (base rates) before WC calculates tax. Skips payloads that post no line totals (legacy Vue frontend — WC already nets those), non-taxable products, and misc lines flaggedtax_status: nonevia_wepos_pos_data.Common.php::get_tax_location— walk-in orders with no billing/shipping address now fall back to the store base address; previously tax based on billing/shipping resolved zero rates and the customer was charged the net price.Manager.php::validate_item_stock_before_order— no longer fatals on product-less (misc) lines.Frontend:
tax_amount(cartItemDisplayPrices), so totals always follow the currentwoocommerce_tax_display_cart/woocommerce_prices_include_taxsettings instead of stale stored values. Both flags are mirrored into the cart store and persisted so the first render is correct before the settings request resolves._wepos_pos_data), and held-order restore; distinct custom lines no longer merge (all shareproduct_id0); placeholder SKU passes WC's product-reference validation on line create.Testing
Verified on VAT 10%, prices inclusive (
wp evalREST dispatch + browser E2E):tax_based_on=shipping, no customerBrowser: cart, update-to-server, qty change, cash checkout, receipt — totals match the WC cart in both
inclandexcldisplay modes, including across a display-mode change with a persisted cart.Summary by CodeRabbit
New Features
Bug Fixes