from odoo import api, fields, models class SaleOrder(models.Model): _inherit = "sale.order" # ClaimID warranty_claim_ids = fields.One2many( "bec.warranty.claim", "sale_order_id", string="Warranty Claims" ) compressor_tag_image = fields.Binary( string="Compressor Tag Photo", related="warranty_claim_ids.compressor_tag_image", readonly=True ) # Checkbox under customer warranty_order = fields.Boolean(string="Warranty Order") # Manufacturer (your logical “warranty manufacturer” entity) warranty_manufacturer_id = fields.Many2one( "warranty.manufacturer", string="Manufacturer", ) # Warranty type warranty_type = fields.Selection( [ ("90_day", "90 Day Warranty"), ("cabinet", "Cabinet Warranty"), ("compressor", "Compressor Warranty"), ("other", "Other"), ], string="Warranty Type", ) # “True Vendor” (actual vendor that handles warranty, may differ from manufacturer) warranty_true_vendor_id = fields.Many2one( "res.partner", string="True Vendor", related="warranty_manufacturer_id.vendor_id", store=True, readonly=True, ) # Fields manufacturer requires warranty_model = fields.Char("Model") warranty_serial = fields.Char("Serial Number") warranty_failure = fields.Text("Failure Description") # Original sales order (dropdown filtered to orders with matching part numbers) # We'll add a helper many2many for domain support. warranty_original_sale_id = fields.Many2one( "sale.order", string="Original Sales Order", domain="[('id', 'in', warranty_original_sale_ids)]", ) warranty_original_sale_ids = fields.Many2many( "sale.order", compute="_compute_warranty_original_sale_ids", string="Candidate Original Sales Orders", store=False, ) @api.depends("order_line.product_id", "partner_id") def _compute_warranty_original_sale_ids(self): """Find previous sales orders for the same customer containing any of the products on this warranty order. """ SaleOrder = self.env["sale.order"] for order in self: if not order.partner_id or not order.order_line: order.warranty_original_sale_ids = False continue product_ids = order.order_line.product_id.ids if not product_ids: order.warranty_original_sale_ids = False continue # Build domain safely domain = [ ("partner_id", "=", order.partner_id.id), ("state", "in", ["sale", "done"]), ("order_line.product_id", "in", product_ids), ] # Avoid comparing with NewId_*; use the real DB id if it exists if order._origin and order._origin.id: domain.append(("id", "!=", order._origin.id)) candidates = SaleOrder.search(domain, limit=50) order.warranty_original_sale_ids = candidates # ---------- create draft claim on SO confirm ---------- def action_confirm(self): res = super().action_confirm() for order in self: if not order.warranty_order: continue # Avoid duplicate claims if already created (button or earlier run) if order.warranty_claim_ids: continue # Build claim lines from all SO lines line_commands = [] for so_line in order.order_line: if not so_line.product_id: continue line_commands.append((0, 0, { "sale_line_id": so_line.id, "product_id": so_line.product_id.id, "quantity": so_line.product_uom_qty, # You can adjust these if later you have per-line model/serial "model": order.warranty_model, "serial_number": order.warranty_serial, "failure": order.warranty_failure, })) claim_vals = { "sale_order_id": order.id, "partner_id": order.partner_id.id, "manufacturer_id": order.warranty_manufacturer_id.id, "true_vendor_id": order.warranty_true_vendor_id.id, "model": order.warranty_model, "serial_number": order.warranty_serial, "failure": order.warranty_failure, "warranty_type": order.warranty_type, "original_sale_order_id": order.warranty_original_sale_id.id, } if line_commands: claim_vals["line_ids"] = line_commands self.env["bec.warranty.claim"].create(claim_vals) return res # ------------------------------------------------------------ def action_create_warranty_claim(self): """Button on SO warranty tab: create a warranty claim pre-filled.""" self.ensure_one() # Build claim lines from all SO lines on this order line_commands = [] for so_line in self.order_line: if not so_line.product_id: continue line_commands.append((0, 0, { "sale_line_id": so_line.id, "product_id": so_line.product_id.id, "quantity": so_line.product_uom_qty, "model": self.warranty_model, "serial_number": self.warranty_serial, "failure": self.warranty_failure, })) claim_vals = { "sale_order_id": self.id, "partner_id": self.partner_id.id, "manufacturer_id": self.warranty_manufacturer_id.id, "true_vendor_id": self.warranty_true_vendor_id.id, "model": self.warranty_model, "serial_number": self.warranty_serial, "failure": self.warranty_failure, "warranty_type": self.warranty_type, "original_sale_order_id": self.warranty_original_sale_id.id, } if line_commands: claim_vals["line_ids"] = line_commands claim = self.env["bec.warranty.claim"].create(claim_vals) action = self.env.ref("odoo_warranty_claims.action_warranty_claims").read()[0] action["res_id"] = claim.id action["views"] = [(self.env.ref("odoo_warranty_claims.view_warranty_claim_form").id, "form")] return action def _create_invoices(self, grouped=False, final=False, date=None): invoices = super()._create_invoices(grouped=grouped, final=final, date=date) for order in self: if order.warranty_order: # Link customer invoice(s) to the new claim claim = self.env["bec.warranty.claim"].create({ "sale_order_id": order.id, "partner_id": order.partner_id.id, "manufacturer_id": order.warranty_manufacturer_id.id, "true_vendor_id": order.warranty_true_vendor_id.id, "model": order.warranty_model, "serial_number": order.warranty_serial, "failure": order.warranty_failure, "warranty_type": order.warranty_type, "original_sale_order_id": order.warranty_original_sale_id.id, "invoice_customer_ids": [(6, 0, invoices.ids)], }) # you could also auto-open or email here, but usually this is backend logic return invoices