126 lines
5.0 KiB
Python
126 lines
5.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright 2026 Nexa Systems Inc.
|
|
# License OPL-1 (Odoo Proprietary License v1.0)
|
|
#
|
|
# Phase 3 — parallel job link on fp.certificate.
|
|
# Coexists with bridge_mrp's production_id link.
|
|
#
|
|
# v19.0.6.20.0 — surface the Fischerscope PDF on the cert form so
|
|
# operators can SEE that the thickness report will be (or has been)
|
|
# merged into the CoC. The merge logic itself lives in
|
|
# fusion_plating_certificates/models/fp_certificate.py — this file
|
|
# only adds the human-readable indicators.
|
|
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class FpCertificate(models.Model):
|
|
_inherit = 'fp.certificate'
|
|
|
|
x_fc_job_id = fields.Many2one(
|
|
'fp.job',
|
|
string='Work Order',
|
|
index=True,
|
|
help="Native fp.job link. Coexists with bridge_mrp's production_id.",
|
|
)
|
|
|
|
# ---- Fischerscope thickness-PDF visibility (S19) ---------------------
|
|
# These three fields are computed from the linked job's QC checks so
|
|
# the cert form can show the operator BEFORE issuing whether a
|
|
# Fischerscope report is on file and will be appended as page 2.
|
|
x_fc_thickness_qc_id = fields.Many2one(
|
|
'fusion.plating.quality.check',
|
|
string='Linked QC (Thickness)',
|
|
compute='_compute_fischer_visibility',
|
|
help='Quality check on the linked plating job that has a '
|
|
'Fischerscope / XDAL 600 thickness PDF uploaded. Used to '
|
|
'merge that PDF into the CoC on Issue.',
|
|
)
|
|
x_fc_thickness_pdf_id = fields.Many2one(
|
|
'ir.attachment',
|
|
string='Fischerscope PDF',
|
|
compute='_compute_fischer_visibility',
|
|
help='Thickness report PDF that will be appended as page 2 of '
|
|
'the CoC when the certificate is issued.',
|
|
)
|
|
x_fc_thickness_status = fields.Selection(
|
|
[
|
|
('none', 'No PDF Uploaded'),
|
|
('pending', 'Will Append on Issue'),
|
|
('merged', 'Merged into CoC'),
|
|
],
|
|
string='Thickness Report',
|
|
compute='_compute_fischer_visibility',
|
|
help='none = QC has no Fischerscope upload · '
|
|
'pending = will be appended when Issue is clicked · '
|
|
'merged = already in the issued CoC PDF',
|
|
)
|
|
|
|
@api.depends('x_fc_job_id', 'state', 'message_ids', 'attachment_id',
|
|
'x_fc_local_thickness_pdf')
|
|
def _compute_fischer_visibility(self):
|
|
QC = self.env.get('fusion.plating.quality.check')
|
|
empty_qc = self.env['fusion.plating.quality.check'] if QC is not None else None
|
|
empty_att = self.env['ir.attachment']
|
|
for rec in self:
|
|
qc = empty_qc
|
|
pdf = empty_att
|
|
status = 'none'
|
|
# Cert-local upload wins over QC-side PDF (matches the
|
|
# merge resolution order in fp_certificate.py).
|
|
if rec.x_fc_local_thickness_pdf:
|
|
if rec.state == 'issued' and rec.attachment_id:
|
|
status = 'merged'
|
|
else:
|
|
status = 'pending'
|
|
elif QC is not None and rec.x_fc_job_id:
|
|
# Same lookup the merge method uses — passed-first,
|
|
# then any QC with a PDF.
|
|
qc = QC.sudo().search([
|
|
('job_id', '=', rec.x_fc_job_id.id),
|
|
('state', '=', 'passed'),
|
|
('thickness_report_pdf_id', '!=', False),
|
|
], order='completed_at desc', limit=1)
|
|
if not qc:
|
|
qc = QC.sudo().search([
|
|
('job_id', '=', rec.x_fc_job_id.id),
|
|
('thickness_report_pdf_id', '!=', False),
|
|
], order='create_date desc', limit=1)
|
|
if qc and qc.thickness_report_pdf_id:
|
|
pdf = qc.thickness_report_pdf_id
|
|
if rec.state == 'issued' and rec.attachment_id:
|
|
status = 'merged'
|
|
else:
|
|
status = 'pending'
|
|
rec.x_fc_thickness_qc_id = qc or empty_qc
|
|
rec.x_fc_thickness_pdf_id = pdf or empty_att
|
|
rec.x_fc_thickness_status = status
|
|
|
|
def action_view_thickness_qc(self):
|
|
"""Smart-button target — open the linked QC for inspection."""
|
|
self.ensure_one()
|
|
if not self.x_fc_thickness_qc_id:
|
|
return False
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': self.x_fc_thickness_qc_id.name,
|
|
'res_model': 'fusion.plating.quality.check',
|
|
'res_id': self.x_fc_thickness_qc_id.id,
|
|
'view_mode': 'form',
|
|
'target': 'current',
|
|
}
|
|
|
|
def action_open_job(self):
|
|
"""Smart-button target — open the linked plating job."""
|
|
self.ensure_one()
|
|
if not self.x_fc_job_id:
|
|
return False
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': self.x_fc_job_id.name,
|
|
'res_model': 'fp.job',
|
|
'res_id': self.x_fc_job_id.id,
|
|
'view_mode': 'form',
|
|
'target': 'current',
|
|
}
|