# -*- 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 fields, models class ResPartner(models.Model): """Per-customer preferences for what quality documents are generated and emailed when a job ships. Some aerospace customers insist on a full CoC + thickness report; others just want the CoC; some repeat commercial accounts want neither (the PO says "no paperwork required"). Rather than hard-code the shop's policy, each customer controls their own. """ _inherit = 'res.partner' x_fc_send_coc = fields.Boolean( string='Send Certificate of Conformance', default=True, tracking=True, help='When shipping, auto-generate and email a CoC to this customer.', ) x_fc_send_thickness_report = fields.Boolean( string='Send Thickness Report', default=True, tracking=True, help='When shipping, auto-generate and email a thickness report ' 'with the Fischerscope readings for this job.', ) x_fc_send_packing_slip = fields.Boolean( string='Send Packing Slip', default=True, tracking=True, help='Attach the packing slip PDF to the shipping confirmation email.', ) x_fc_send_bol = fields.Boolean( string='Send Bill of Lading', default=False, tracking=True, help='Attach the BoL PDF to the shipping confirmation email. ' 'Usually only for customers that invoice freight separately.', ) x_fc_strict_thickness_required = fields.Boolean( string='Require Thickness Readings on CoC', default=False, tracking=True, help='Aerospace / Nadcap customers expect every CoC to carry ' 'actual Fischerscope readings (not just "meets spec"). When ' 'this is on, action_issue() blocks until at least one ' 'thickness reading has been logged for the MO. Leave off ' 'for commercial customers.', ) # Aerospace / Defence cert toggles (2026-05-27 — sub # docs/superpowers/specs/2026-05-27-recipe-cert-toggles-design.md). # Default False — opt-in for aerospace/defence customers only. # Resolver _resolve_required_cert_types reads these alongside the # existing x_fc_send_coc / x_fc_send_thickness_report. The three # cert types (nadcap_cert / mill_test / customer_specific) are # manual-attach: operator uploads the PDF, no QWeb auto-render. x_fc_send_nadcap_cert = fields.Boolean( string='Send Nadcap Certificate', default=False, tracking=True, help='Auto-spawn a Nadcap-type fp.certificate when a job for ' 'this customer reaches awaiting_cert. Operator attaches ' 'the supplier/PRI-issued PDF before clicking Issue — ' 'there is no QWeb auto-render for this type.', ) x_fc_send_mill_test = fields.Boolean( string='Send Mill Test Report (MTR)', default=False, tracking=True, help='Auto-spawn a Mill Test Report cert. Operator attaches ' "the steel supplier's MTR PDF before issuing.", ) x_fc_send_customer_specific = fields.Boolean( string='Send Customer-Specific Cert', default=False, tracking=True, help='Auto-spawn a customer-specific cert. Operator fills the ' 'customer-supplied template PDF and attaches before ' 'issuing.', ) # ---- Sub 6 — Per-contact communication routing ----------------------- # These five flags live on CHILD contacts under a company partner. # When every contact under a company leaves them blank, the resolver # falls back to the company's own `email` — matching the pre-Sub-6 # behaviour exactly. Admins opt in to per-contact routing by ticking # the relevant flag on each contact row. x_fc_receives_certs = fields.Boolean( string='Receives Certificates', default=False, tracking=True, help='This contact receives CoC PDFs, thickness reports, and ' 'other quality documents when a job ships.', ) x_fc_receives_qc = fields.Boolean( string='Receives QC Alerts', default=False, tracking=True, help='This contact receives NCR, CAPA, quality-hold, and contract-' 'review notifications.', ) x_fc_receives_quotes_so = fields.Boolean( string='Receives Quotes & SOs', default=False, tracking=True, help='This contact receives quote sends, sale order acknowledgements, ' 'and order confirmations.', ) x_fc_receives_invoices = fields.Boolean( string='Receives Invoices', default=False, tracking=True, help='This contact receives invoices, payment receipts, and ' 'dunning communications.', ) x_fc_is_global_contact = fields.Boolean( string='Global Contact', default=False, tracking=True, help='Firehose. When set, this contact receives every outbound ' 'stream regardless of the per-stream flags above. Typical ' 'use: a primary account-manager contact who wants full ' 'visibility into everything the shop sends out.', ) # ---- Sub 12c+ — Per-customer cert statement override ---------------- x_fc_cert_statement = fields.Text( string='Cert Statement Override', help='Override boilerplate text printed in the Certificate of ' 'Conformance "Certification Statement" block. When blank, ' 'falls back to the company default (res.company.' 'x_fc_default_cert_statement) and finally to a hardcoded ' 'AS9100/ISO 9001 boilerplate. Useful for aerospace customers ' 'who require specific NIST or DFARS language.', ) # ---- Default CoC contact (cert addressee + email recipient) ---------- # The single named contact printed on the CoC and used as the email # default when the cert ships. Sales sets it once per customer. # Falls back to manual selection at action_issue time if blank. x_fc_default_coc_contact_id = fields.Many2one( 'res.partner', string='Default CoC Contact', domain="[('parent_id', '=', id), ('is_company', '=', False)]", tracking=True, help='Default contact the Certificate of Conformance is addressed ' 'to and emailed to. Pre-fills cert.contact_partner_id when a ' 'job ships. Leave blank to force the manager to pick at ' 'issue time. Must be a child contact of this company.', )