feat(configurator): SO-create applies one tax to all lines + typed charge line

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-29 21:40:52 -04:00
parent a2ac804238
commit 6dde3ec2b1
2 changed files with 20 additions and 20 deletions

View File

@@ -326,6 +326,9 @@ class SaleOrderLine(models.Model):
'pair, falling back to the part\'s default range. Prints '
'verbatim on the cert, packing slip, and invoice.',
)
x_fc_is_lot_priced = fields.Boolean(string='Lot Priced')
x_fc_lot_total = fields.Monetary(
string='Lot Total', currency_field='currency_id')
# ---- Express Orders per-line flags (2026-05-26) ----
# Mirror fp.direct.order.line.{customer_line_ref, masking_enabled, bake_instructions}

View File

@@ -813,7 +813,7 @@ class FpDirectOrderWizard(models.Model):
'x_fc_internal_notes': self.internal_notes or False,
# material_process is a Many2One since 19.0.22.1.0 — pass .id
'x_fc_material_process': self.material_process.id if self.material_process else False,
'x_fc_tooling_charge': self.tooling_charge or 0.0,
'x_fc_tooling_charge': self.charge_amount or self.tooling_charge or 0.0,
'pricelist_id': self.pricelist_id.id if self.pricelist_id else False,
'validity_date': self.validity_date or False,
'order_line': [],
@@ -895,32 +895,29 @@ class FpDirectOrderWizard(models.Model):
# When blank, Odoo will compute taxes from the product
# defaults at SO-line save time (the standard behaviour).
# NB. Odoo 19 renamed the SO line field to tax_ids.
'tax_ids': ([(6, 0, line.tax_ids.ids)]
if line.tax_ids else False),
'tax_ids': ([(6, 0, self.tax_id.ids)]
if self.tax_id else False),
'x_fc_is_lot_priced': line.is_lot_priced,
'x_fc_lot_total': line.lot_total or 0.0,
}))
# 4b. Tooling charge — surface as a real sale.order.line so it
# carries through SO.amount_total + invoice naturally, instead of
# sitting orphaned on the SO header. Tax: inherit from the first
# part line that has taxes set (best proxy for "the customer's
# standard tax rate"); falls back to product defaults if no line
# has taxes yet.
if self.tooling_charge:
tooling_taxes = False
first_taxed = next(
(l for l in self.line_ids if l.tax_ids), False,
)
if first_taxed:
tooling_taxes = [(6, 0, first_taxed.tax_ids.ids)]
# 4b. Additional charge — one typed line, taxed by the order-level
# tax. The charge type's name labels the line; charge_amount with
# legacy tooling_charge fallback for in-flight drafts.
charge_amt = self.charge_amount or self.tooling_charge or 0.0
if charge_amt:
charge_name = (self.charge_type_id.name
if self.charge_type_id else _('Additional Charge'))
so_vals['order_line'].append((0, 0, {
'product_id': product.id,
'name': _('Tooling Charge'),
'name': charge_name,
'product_uom_qty': 1.0,
'price_unit': self.tooling_charge,
'price_unit': charge_amt,
'x_fc_internal_description': _(
'One-time tooling fee added via Express Orders.'
'Additional charge added via Express Orders.'
),
'tax_ids': tooling_taxes,
'tax_ids': ([(6, 0, self.tax_id.ids)]
if self.tax_id else False),
}))
# 5. Create — stays in draft / quotation. Sub 1: user reviews