feat(configurator): totals = one tax on (subtotal + charge)
This commit is contained in:
@@ -28,3 +28,19 @@ class TestChargeTaxLot(TransactionCase):
|
|||||||
self.assertEqual(ct.default_amount, 75.0)
|
self.assertEqual(ct.default_amount, 75.0)
|
||||||
cid, cname = self.env['fp.additional.charge.type'].name_create('Setup')
|
cid, cname = self.env['fp.additional.charge.type'].name_create('Setup')
|
||||||
self.assertTrue(cid)
|
self.assertTrue(cid)
|
||||||
|
|
||||||
|
# ----- Task 3: totals -----
|
||||||
|
def _make_wizard(self, **kw):
|
||||||
|
vals = {'partner_id': self.partner.id}
|
||||||
|
vals.update(kw)
|
||||||
|
return self.env['fp.direct.order.wizard'].create(vals)
|
||||||
|
|
||||||
|
def test_tax_applies_on_subtotal_plus_charge(self):
|
||||||
|
wiz = self._make_wizard(charge_amount=100.0, tax_id=self.tax13.id)
|
||||||
|
self.env['fp.direct.order.line'].create({
|
||||||
|
'wizard_id': wiz.id, 'quantity': 1, 'unit_price': 50.0,
|
||||||
|
})
|
||||||
|
wiz.invalidate_recordset()
|
||||||
|
self.assertEqual(wiz.total_subtotal, 50.0)
|
||||||
|
self.assertAlmostEqual(wiz.total_tax, 19.5, places=2)
|
||||||
|
self.assertAlmostEqual(wiz.total_amount, 169.5, places=2)
|
||||||
|
|||||||
@@ -401,65 +401,41 @@ class FpDirectOrderWizard(models.Model):
|
|||||||
|
|
||||||
# ---- Computes ----
|
# ---- Computes ----
|
||||||
@api.depends(
|
@api.depends(
|
||||||
'line_ids.line_subtotal',
|
|
||||||
'line_ids.quantity',
|
'line_ids.quantity',
|
||||||
'line_ids.unit_price',
|
'line_ids.unit_price',
|
||||||
'line_ids.tax_ids',
|
'charge_amount',
|
||||||
'tooling_charge',
|
'tooling_charge',
|
||||||
|
'tax_id',
|
||||||
'partner_id',
|
'partner_id',
|
||||||
'currency_id',
|
'currency_id',
|
||||||
)
|
)
|
||||||
def _compute_totals(self):
|
def _compute_totals(self):
|
||||||
"""Roll up subtotal / tax / grand total across lines + tooling.
|
"""Roll up subtotal / tax / grand total across lines + charge.
|
||||||
|
|
||||||
Each line's taxes are computed via account.tax.compute_all so the
|
The order-level ``tax_id`` is applied once to (subtotal + charge),
|
||||||
Express form's totals card mirrors what the eventual SO will show
|
where charge = ``charge_amount`` (legacy ``tooling_charge`` as
|
||||||
once the operator hits Confirm. The tooling charge is added at the
|
fallback). The charge is also pushed as an actual sale.order.line
|
||||||
wizard level here AND pushed as an actual sale.order.line at
|
at action_create_order time (so it carries into the invoice).
|
||||||
action_create_order time (so it carries into the invoice).
|
|
||||||
"""
|
"""
|
||||||
for rec in self:
|
for rec in self:
|
||||||
subtotal = 0.0
|
subtotal = sum(
|
||||||
|
(l.quantity or 0) * (l.unit_price or 0.0)
|
||||||
|
for l in rec.line_ids
|
||||||
|
)
|
||||||
|
charge = rec.charge_amount or rec.tooling_charge or 0.0
|
||||||
tax_total = 0.0
|
tax_total = 0.0
|
||||||
for line in rec.line_ids:
|
if rec.tax_id and (subtotal + charge):
|
||||||
line_pre_tax = (line.quantity or 0) * (line.unit_price or 0.0)
|
res = rec.tax_id.compute_all(
|
||||||
subtotal += line_pre_tax
|
subtotal + charge,
|
||||||
if line.tax_ids and line_pre_tax:
|
currency=rec.currency_id,
|
||||||
taxes_res = line.tax_ids.compute_all(
|
quantity=1,
|
||||||
line.unit_price or 0.0,
|
product=None,
|
||||||
currency=rec.currency_id,
|
partner=rec.partner_id or None,
|
||||||
quantity=line.quantity or 0,
|
|
||||||
product=None,
|
|
||||||
partner=rec.partner_id or None,
|
|
||||||
)
|
|
||||||
tax_total += (
|
|
||||||
taxes_res['total_included']
|
|
||||||
- taxes_res['total_excluded']
|
|
||||||
)
|
|
||||||
# Tooling charge: pick the tax set from the FIRST line that
|
|
||||||
# has one (best proxy for the customer's standard rate). If
|
|
||||||
# no line has taxes set yet, tooling is shown untaxed in the
|
|
||||||
# preview; the eventual SO line will apply product defaults.
|
|
||||||
tooling = rec.tooling_charge or 0.0
|
|
||||||
if tooling:
|
|
||||||
first_taxed_line = next(
|
|
||||||
(l for l in rec.line_ids if l.tax_ids), False,
|
|
||||||
)
|
)
|
||||||
if first_taxed_line:
|
tax_total = res['total_included'] - res['total_excluded']
|
||||||
tooling_res = first_taxed_line.tax_ids.compute_all(
|
|
||||||
tooling,
|
|
||||||
currency=rec.currency_id,
|
|
||||||
quantity=1,
|
|
||||||
product=None,
|
|
||||||
partner=rec.partner_id or None,
|
|
||||||
)
|
|
||||||
tax_total += (
|
|
||||||
tooling_res['total_included']
|
|
||||||
- tooling_res['total_excluded']
|
|
||||||
)
|
|
||||||
rec.total_subtotal = subtotal
|
rec.total_subtotal = subtotal
|
||||||
rec.total_tax = tax_total
|
rec.total_tax = tax_total
|
||||||
rec.total_amount = subtotal + tax_total + tooling
|
rec.total_amount = subtotal + charge + tax_total
|
||||||
rec.total_qty = sum(rec.line_ids.mapped('quantity'))
|
rec.total_qty = sum(rec.line_ids.mapped('quantity'))
|
||||||
rec.total_line_count = len(rec.line_ids)
|
rec.total_line_count = len(rec.line_ids)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user