fix: tax Indiana seller-billed shipping#650
Conversation
Co-authored-by: Codex <Codex@anthropic.com> Agent-Session: codex-taxable-shipping-policy-20260606-001
|
Complex PR? Review this PR in Change Stack to move by importance, not file order. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (3)
WalkthroughAdds a provider-neutral tax calculation service and integrates it into quote and sales order flows to compute state-aware taxable bases and tax amounts (including Indiana shipping rules), and updates tests to validate the new behavior. ChangesTax Calculation and Service Integration
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 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 `@backend/app/services/quote_service.py`:
- Around line 286-292: The tax calculation uses request.shipping_state via
_calculate_quote_tax_amount but create_quote never persists that destination;
update the create_quote implementation to assign the incoming shipping state to
the Quote (e.g., set quote.shipping_state = getattr(request, "shipping_state",
None) or the equivalent request field) before saving so subsequent tax
recalculations and order conversion read the true destination; modify
create_quote (and any save/commit path for the Quote) to persist this value
whenever you call _calculate_quote_tax_amount with a request shipping_state.
- Around line 548-559: The single-item apply_tax=True branch bypasses the shared
resolver and can drop or stale tax fields; update that branch in the quote
update flow to call the existing _resolve_tax(...) (the same used by
create_quote/create/update paths) to obtain the resolved tax_rate, tax_amount,
tax_name and tax_rate_id using company_settings and any incoming tax_rate_id,
then set quote.tax_rate, quote.tax_amount, quote.tax_name, quote.tax_rate_id
accordingly and recompute quote.total_price (subtotal + tax_amount + shipping);
this ensures consistency with create_quote() and respects get_default_tax_rate()
fallback.
- Around line 436-442: The recalculation gate (should_recalculate) misses
changes to the shipping state so tax and totals stay stale; detect when the
quote's shipping_state is changed (e.g., compute shipping_state_updated by
comparing request.shipping_state to the existing quote.shipping_state or the
current shipping_state var) and include that flag in the should_recalculate
condition (or fold it into shipping_cost_updated) so changes to shipping_state
trigger tax and total recomputation (affecting tax_amount and total_price).
In `@backend/app/services/sales_order_service.py`:
- Around line 768-780: The header recompute path currently uses a naive
line_total * order.tax_rate in _recalculate_order_totals which ignores taxable
shipping and diverges from calculate_sales_tax used at creation; update
_recalculate_order_totals to call the same helper used during creation
(calculate_sales_tax, with company settings from
get_company_tax_settings/CompanySettings) and use the returned
tax_result.tax_amount (taking shipping_cost and ship_to_state into account)
instead of multiplying by order.tax_rate so persisted totals remain consistent
after edits/removals.
- Around line 768-779: The tax call uses shipping_state too early; before
calling calculate_sales_tax resolve ship_to_state by backfilling shipping_state
from the customer's saved shipping address (the same logic currently applied
later when populating the order from the customer record) so that shipping_state
is not None when passed in. Update the code around
company_settings/get_company_tax_settings/calculate_sales_tax to first set
shipping_state = shipping_state or customer.saved_shipping_state (or the
existing helper that loads the customer's saved address), then call
calculate_sales_tax with that resolved ship_to_state (keeping
seller_state=company_settings.company_state fallback).
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 2e5662b3-8614-4c64-9863-773aa19f8d50
📒 Files selected for processing (6)
backend/app/services/quote_service.pybackend/app/services/sales_order_service.pybackend/app/services/tax_calculation_service.pybackend/tests/services/test_quote_service.pybackend/tests/services/test_sales_order_service.pybackend/tests/services/test_tax_calculation_service.py
Co-authored-by: Codex <Codex@anthropic.com> Agent-Session: codex-pr650-coderabbit-20260606-001
Summary
Validation
DB_NAME=filaops_test,DATABASE_URLcleared before DB-backed testspython -m pytest backend/tests/services/test_tax_calculation_service.py backend/tests/services/test_sales_order_service.py backend/tests/services/test_quote_service.py -q-> 210 passed, 1 skippedpython -m ruff check backend/app/services/tax_calculation_service.py backend/app/services/sales_order_service.py backend/app/services/quote_service.py backend/tests/services/test_tax_calculation_service.py backend/tests/services/test_sales_order_service.py backend/tests/services/test_quote_service.py-> All checks passedpython -m compileall backend/app/services/tax_calculation_service.py backend/app/services/sales_order_service.py backend/app/services/quote_service.py backend/tests/services/test_tax_calculation_service.py backend/tests/services/test_sales_order_service.py backend/tests/services/test_quote_service.pygit diff --checkNotes
This does not add a QuickBooks/Avalara/TaxJar dependency. It gives Core a conservative built-in policy point so a later provider can replace or enrich the calculation without coupling Core to PRO.
AI attribution
Co-authored-by: Codex Codex@anthropic.com
Agent-Session: codex-taxable-shipping-policy-20260606-001
Summary by CodeRabbit
New Features
Bug Fixes
Tests