changes
This commit is contained in:
@@ -25,6 +25,14 @@ class SaleOrder(models.Model):
|
||||
string='Plating Jobs',
|
||||
compute='_compute_fp_job_count',
|
||||
)
|
||||
x_fc_fp_certificate_count = fields.Integer(
|
||||
string='Certificates',
|
||||
compute='_compute_fp_certificate_count',
|
||||
help='Number of fp.certificate records issued (or draft) against '
|
||||
'this sale order. Surfaced as a smart button so Sarah/Tom '
|
||||
'can jump straight from the SO to the cert without having '
|
||||
'to drill through the linked Plating Job first.',
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Phase 4 (Sub 11) — workflow-stage field + assigned-manager field
|
||||
@@ -66,6 +74,13 @@ class SaleOrder(models.Model):
|
||||
[('sale_order_id', '=', so.id)]
|
||||
)
|
||||
|
||||
def _compute_fp_certificate_count(self):
|
||||
Cert = self.env['fp.certificate'].sudo()
|
||||
for so in self:
|
||||
so.x_fc_fp_certificate_count = Cert.search_count(
|
||||
[('sale_order_id', '=', so.id)]
|
||||
)
|
||||
|
||||
def _compute_workflow_stage(self):
|
||||
"""Native-jobs override — walks fp.job state instead of mrp.production.
|
||||
|
||||
@@ -162,6 +177,28 @@ class SaleOrder(models.Model):
|
||||
})
|
||||
return action
|
||||
|
||||
def action_view_fp_certificates(self):
|
||||
"""Smart-button target — open the certificate(s) linked to this
|
||||
SO. One cert → form view; many → list view filtered to this SO."""
|
||||
self.ensure_one()
|
||||
certs = self.env['fp.certificate'].search([
|
||||
('sale_order_id', '=', self.id),
|
||||
])
|
||||
action = {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': _('Certificates'),
|
||||
'res_model': 'fp.certificate',
|
||||
'view_mode': 'list,form',
|
||||
'domain': [('sale_order_id', '=', self.id)],
|
||||
'context': {
|
||||
'default_sale_order_id': self.id,
|
||||
'default_partner_id': self.partner_id.id,
|
||||
},
|
||||
}
|
||||
if len(certs) == 1:
|
||||
action.update({'view_mode': 'form', 'res_id': certs.id})
|
||||
return action
|
||||
|
||||
def action_confirm(self):
|
||||
result = super().action_confirm()
|
||||
# Only run when the native flag is on
|
||||
@@ -209,6 +246,18 @@ class SaleOrder(models.Model):
|
||||
or ('x_fc_coating_config_id' in l._fields and l.x_fc_coating_config_id)
|
||||
)
|
||||
)
|
||||
# Fallback: legacy/configurator SOs that carry part+coating on the
|
||||
# header but not on the line. Treat the entire order as one
|
||||
# plating line so the planner gets an fp.job to work against.
|
||||
if not plating_lines and self.order_line and (
|
||||
('x_fc_part_catalog_id' in self._fields and self.x_fc_part_catalog_id)
|
||||
or ('x_fc_coating_config_id' in self._fields and self.x_fc_coating_config_id)
|
||||
):
|
||||
_logger.info(
|
||||
'SO %s: no line-level part/coating but header carries one — '
|
||||
'treating all lines as a single plating job.', self.name,
|
||||
)
|
||||
plating_lines = self.order_line
|
||||
if not plating_lines:
|
||||
_logger.info('SO %s: no plating lines, skipping job creation.', self.name)
|
||||
return
|
||||
@@ -239,13 +288,38 @@ class SaleOrder(models.Model):
|
||||
and first_line.x_fc_coating_config_id
|
||||
or False
|
||||
)
|
||||
# Recipe lookup: from coating, fallback to part
|
||||
# Header fallback for legacy/configurator SOs that put part +
|
||||
# coating on the SO header instead of the line.
|
||||
if not part and 'x_fc_part_catalog_id' in self._fields:
|
||||
part = self.x_fc_part_catalog_id or False
|
||||
if not coating and 'x_fc_coating_config_id' in self._fields:
|
||||
coating = self.x_fc_coating_config_id or False
|
||||
# Recipe lookup priority:
|
||||
# 1. line.x_fc_process_variant_id — Sarah explicitly picked
|
||||
# a part-scoped variant on this order line. Always wins.
|
||||
# 2. coating.recipe_id — coating-config recipe.
|
||||
# 3. part.default_process_id — part's flagged default.
|
||||
# 4. part.recipe_id — legacy fallback.
|
||||
#
|
||||
# If multiple lines in the same WO group have different
|
||||
# variants we use the FIRST line's variant (consistent with
|
||||
# everything else in this loop using `first_line`).
|
||||
recipe = False
|
||||
if coating and 'recipe_id' in coating._fields and coating.recipe_id:
|
||||
picked_variant = (
|
||||
'x_fc_process_variant_id' in first_line._fields
|
||||
and first_line.x_fc_process_variant_id
|
||||
or False
|
||||
)
|
||||
if picked_variant:
|
||||
recipe = picked_variant
|
||||
if not recipe and coating and 'recipe_id' in coating._fields \
|
||||
and coating.recipe_id:
|
||||
recipe = coating.recipe_id
|
||||
if not recipe and part and 'default_process_id' in part._fields and part.default_process_id:
|
||||
if not recipe and part and 'default_process_id' in part._fields \
|
||||
and part.default_process_id:
|
||||
recipe = part.default_process_id
|
||||
if not recipe and part and 'recipe_id' in part._fields and part.recipe_id:
|
||||
if not recipe and part and 'recipe_id' in part._fields \
|
||||
and part.recipe_id:
|
||||
recipe = part.recipe_id
|
||||
|
||||
vals = {
|
||||
|
||||
Reference in New Issue
Block a user