# -*- 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 SaleOrder(models.Model): _inherit = 'sale.order' x_fc_configurator_id = fields.Many2one('fp.quote.configurator', string='Configurator', copy=False) x_fc_part_catalog_id = fields.Many2one('fp.part.catalog', string='Part') x_fc_coating_config_id = fields.Many2one('fp.coating.config', string='Coating Configuration') x_fc_po_number = fields.Char(string='Customer PO #', tracking=True) x_fc_po_attachment_id = fields.Many2one( 'ir.attachment', string='PO Document', tracking=True, ) x_fc_po_received = fields.Boolean(string='PO Received', tracking=True) x_fc_rfq_attachment_id = fields.Many2one( 'ir.attachment', string='RFQ Document', tracking=True, help="Customer's original Request for Quote document.", ) upload_rfq_file = fields.Binary(string='Upload RFQ', attachment=False) upload_rfq_filename = fields.Char(string='RFQ Filename') upload_po_file = fields.Binary(string='Upload PO', attachment=False) upload_po_filename = fields.Char(string='PO Filename') x_fc_po_override = fields.Boolean(string='PO Override', help='Manager override — proceed without formal PO (handshake deal).') x_fc_po_override_reason = fields.Text(string='Override Reason') x_fc_invoice_strategy = fields.Selection( [('deposit', 'Deposit'), ('progress', 'Progress Billing'), ('net_terms', 'Net Terms'), ('cod_prepay', 'COD / Prepay')], string='Invoice Strategy', tracking=True, ) x_fc_deposit_percent = fields.Float(string='Deposit %', help='Deposit percentage if strategy is Deposit.') x_fc_rush_order = fields.Boolean(string='Rush Order', tracking=True) x_fc_delivery_method = fields.Selection( [('local_delivery', 'Local Delivery'), ('shipping_partner', 'Shipping Partner'), ('customer_pickup', 'Customer Pickup')], string='Delivery Method', tracking=True, ) x_fc_receiving_status = fields.Selection( [('not_received', 'Not Received'), ('partial', 'Partial'), ('received', 'Received'), ('inspected', 'Inspected')], string='Receiving Status', default='not_received', tracking=True, ) @api.onchange('upload_rfq_file') def _onchange_upload_rfq_file(self): """Create attachment from uploaded binary and link it.""" if not self.upload_rfq_file: return fname = self.upload_rfq_filename or 'rfq.pdf' att = self.env['ir.attachment'].create({ 'name': fname, 'datas': self.upload_rfq_file, 'mimetype': 'application/pdf', }) self.x_fc_rfq_attachment_id = att.id self.upload_rfq_file = False self.upload_rfq_filename = False @api.onchange('upload_po_file') def _onchange_upload_po_file(self): """Create attachment from uploaded binary, link it, and mark PO received.""" if not self.upload_po_file: return fname = self.upload_po_filename or 'po.pdf' att = self.env['ir.attachment'].create({ 'name': fname, 'datas': self.upload_po_file, 'mimetype': 'application/pdf', }) self.x_fc_po_attachment_id = att.id if not self.x_fc_po_received: self.x_fc_po_received = True self.upload_po_file = False self.upload_po_filename = False def action_view_rfq(self): self.ensure_one() if not self.x_fc_rfq_attachment_id: return return { 'type': 'ir.actions.client', 'tag': 'fp_pdf_preview_open', 'params': { 'attachment_id': self.x_fc_rfq_attachment_id.id, 'title': 'RFQ — %s' % (self.x_fc_rfq_attachment_id.name or ''), }, } def action_view_po(self): self.ensure_one() if not self.x_fc_po_attachment_id: return return { 'type': 'ir.actions.client', 'tag': 'fp_pdf_preview_open', 'params': { 'attachment_id': self.x_fc_po_attachment_id.id, 'title': 'PO — %s' % (self.x_fc_po_attachment_id.name or ''), }, }