# -*- coding: utf-8 -*- # Copyright 2026 Nexa Systems Inc. # License OPL-1 (Odoo Proprietary License v1.0) # Part of the Fusion Plating product family. from odoo import _, api, fields, models class FpFair(models.Model): """Bridge-level extension of FAIR: link to an Odoo EE sign.request. Installs only when the Enterprise ``sign`` module and ``fusion_plating_quality`` are both present. Adds a header button to send a FAIR for customer e-signature, stores the back-reference to the generated sign.request, and preserves the final signed PDF. """ _inherit = 'fusion.plating.fair' x_fc_sign_request_id = fields.Many2one( 'sign.request', string='Sign Request', copy=False, readonly=True, help='Odoo EE Sign request created when this FAIR was sent for ' 'customer acceptance. One sign.request per FAIR.', ) x_fc_sign_request_state = fields.Selection( related='x_fc_sign_request_id.state', string='Signature State', readonly=True, ) x_fc_signed_date = fields.Datetime( string='Signed On', copy=False, readonly=True, help='Datetime when the customer completed signing.', ) x_fc_signed_by = fields.Char( string='Signed By', copy=False, readonly=True, ) x_fc_signed_pdf_id = fields.Many2one( 'ir.attachment', string='Signed PDF', copy=False, readonly=True, help='Final signed PDF stored as an attachment on this FAIR.', ) # ========================================================================== # Actions # ========================================================================== def action_send_for_signature(self): """Open the EE sign.send.request wizard pre-filled with this FAIR. The wizard expects a ``default_attachment_ids`` context with the PDF to sign. We pass the FAIR's existing attachments (e.g. an AS9102 Form 3 if fusion_plating_aerospace is installed) or let the user upload one inside the wizard. """ self.ensure_one() if self.state != 'approved': return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'title': _('FAIR not approved'), 'message': _( 'Only approved FAIRs can be sent for customer ' 'signature. Mark the FAIR as Approved first.' ), 'type': 'warning', 'sticky': False, }, } # Gather attachments linked to this FAIR via chatter attachment_ids = self.env['ir.attachment'].search([ ('res_model', '=', self._name), ('res_id', '=', self.id), ]).ids ctx = dict(self.env.context, default_attachment_ids=attachment_ids) if self.customer_id: ctx['default_signer_ids'] = [(0, 0, {'partner_id': self.customer_id.id})] return { 'name': _('Send %s for Customer Signature') % self.name, 'type': 'ir.actions.act_window', 'res_model': 'sign.send.request', 'view_mode': 'form', 'target': 'new', 'context': ctx, } def action_view_signed_document(self): """Open the signed PDF attachment in a new browser tab.""" self.ensure_one() if not self.x_fc_signed_pdf_id: return False return { 'type': 'ir.actions.act_url', 'url': '/web/content/%s?download=true' % self.x_fc_signed_pdf_id.id, 'target': 'new', } def action_view_sign_request(self): """Open the underlying sign.request record.""" self.ensure_one() if not self.x_fc_sign_request_id: return False return { 'type': 'ir.actions.act_window', 'res_model': 'sign.request', 'res_id': self.x_fc_sign_request_id.id, 'view_mode': 'form', 'target': 'current', }