Files
Warranty-Claim-Odoo/models/warranty_claim.py
T
greg f2364cf10f Working
vendor payment and email
2025-12-03 09:47:06 -06:00

253 lines
8.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from odoo import api, fields, models, _
from odoo.exceptions import UserError
class WarrantyClaim(models.Model):
_name = "bec.warranty.claim"
_description = "Warranty Claim"
_inherit = ["mail.thread", "mail.activity.mixin"]
_order = "create_date desc"
name = fields.Char("Claim Reference", required=True, copy=False, default="New", tracking=True)
install_date = fields.Date("Date of Install")
failure_date = fields.Date("Date of Failure")
resolution_type = fields.Selection(
[
("credit", "Credit"),
("replacement", "Replacement"),
],
string="Requested Resolution",
)
# Link to the customer and various parties
partner_id = fields.Many2one("res.partner", string="Customer", tracking=True)
manufacturer_id = fields.Many2one("warranty.manufacturer", string="Manufacturer")
true_vendor_id = fields.Many2one(
"res.partner",
string="True Vendor",
domain="[('supplier_rank', '>', 0)]",
tracking=True,
)
extra_recipient_ids = fields.Many2many(
"res.partner",
string="Additional Email Recipients",
help="Separate recipients you want CC'd on the warranty email.",
)
# Link to sales and invoices
sale_order_id = fields.Many2one("sale.order", string="Sales Order", tracking=True)
original_sale_order_id = fields.Many2one("sale.order", string="Original Sales Order")
# Customer invoices to attach
invoice_customer_ids = fields.Many2many(
"account.move",
"warranty_claim_customer_invoice_rel",
"claim_id", "move_id",
string="Customer Invoices",
domain="[('move_type', 'in', ('out_invoice', 'out_refund'))]",
)
# Vendor invoices to attach
invoice_vendor_ids = fields.Many2many(
"account.move",
"warranty_claim_vendor_invoice_rel",
"claim_id", "move_id",
string="Vendor Invoices",
domain="[('move_type', 'in', ('in_invoice', 'in_refund'))]",
)
# Technical / product fields
line_ids = fields.One2many(
"bec.warranty.claim.line",
"claim_id",
string="Claim Lines",
)
# customer credit (customer credit note / refund)
# customer_credit_id = fields.Many2one(
# 'account.move',
# string="Customer Credit",
# domain=[('move_type', '=', 'out_refund')],
# tracking=True,
# )
product_id = fields.Many2one("product.product", string="Product")
model = fields.Char("Model")
serial_number = fields.Char("Serial Number")
failure = fields.Text("Failure Description")
warranty_type = fields.Selection(
[
("90_day", "90 Day Warranty"),
("cabinet", "Cabinet Warranty"),
("compressor", "Compressor Warranty"),
("other", "Other"),
],
string="Warranty Type",
)
claim_date = fields.Date("Claim Date", default=fields.Date.context_today)
state = fields.Selection(
[
("draft", "Draft"),
("sent", "Sent to Vendor"),
("approved", "Approved"),
("rejected", "Rejected"),
("done", "Done"),
],
string="Status",
default="draft",
tracking=True,
)
company_id = fields.Many2one(
"res.company",
string="Company",
default=lambda self: self.env.company,
required=True,
)
compressor_tag_image = fields.Binary(
string="Compressor Tag Photo",
attachment=True,
help="Photo of the compressor nameplate/tag required for compressor warranty claims.",
)
@api.constrains("warranty_type", "compressor_tag_image")
def _check_compressor_tag_image_required(self):
for claim in self:
# adjust 'compressor' to your actual selection key
if claim.warranty_type == "compressor" and not claim.compressor_tag_image:
raise ValidationError(
_("A compressor tag photo is required for compressor warranty claims.")
)
currency_id = fields.Many2one(
"res.currency",
string="Currency",
related="company_id.currency_id",
store=True,
readonly=True,
)
vendor_move_id = fields.Many2one(
"account.move",
string="Vendor Credit / Invoice",
help="Vendor credit note or invoice used to reimburse this warranty claim.",
)
vendor_move_amount = fields.Monetary(
string="Vendor Amount",
currency_field="currency_id",
compute="_compute_vendor_move_amount",
store=False,
)
vendor_move_state = fields.Selection(
related="vendor_move_id.state",
string="Vendor Doc State",
readonly=True,
)
@api.depends("vendor_move_id")
def _compute_vendor_move_amount(self):
for claim in self:
claim.vendor_move_amount = claim.vendor_move_id.amount_total if claim.vendor_move_id else 0.0
@api.model
def create(self, vals):
if vals.get("name", "New") == "New":
seq = self.env.ref(
"odoo_warranty_claims.seq_warranty_claim",
raise_if_not_found=False
)
if seq:
vals["name"] = seq.next_by_id()
return super().create(vals)
def action_send_to_vendor(self):
"""Open email wizard prefilled with the warranty template."""
self.ensure_one()
# get template (adjust the XML ID if your template id is different)
template = self.env.ref(
"warranty_claim.mail_template_warranty_claim_90day",
raise_if_not_found=False,
)
compose_form = self.env.ref(
"mail.email_compose_message_wizard_form",
raise_if_not_found=False,
)
# move to Sent state right away (optional comment this out if you prefer manual)
self.state = "sent"
ctx = {
"default_model": self._name,
"default_res_ids": [self.id],
"default_use_template": bool(template),
"default_template_id": template.id if template else False,
"default_composition_mode": "comment",
"force_email": True,
}
return {
"name": _("Send Warranty Email"),
"type": "ir.actions.act_window",
"res_model": "mail.compose.message",
"view_mode": "form",
"views": [(compose_form.id, "form")],
"target": "new",
"context": ctx,
}
def action_create_vendor_credit(self):
self.ensure_one()
move = self.env["account.move"].create({
"move_type": "in_refund",
"partner_id": self.true_vendor_id.id,
"invoice_date": fields.Date.today(),
"invoice_line_ids": [
(0, 0, {
"name": f"Warranty Claim {self.name}",
"quantity": 1,
"price_unit": self.product_id.standard_price * -1, # or reimburse amount
"account_id": self.env.company.warranty_expense_account_id.id if hasattr(self.env.company, 'warranty_expense_account_id') else None,
})
],
})
self.vendor_credit_id = move.id
return {
"name": "Vendor Credit Note",
"type": "ir.actions.act_window",
"res_model": "account.move",
"view_mode": "form",
"res_id": move.id,
"target": "current",
}
class WarrantyClaimLine(models.Model):
_name = "bec.warranty.claim.line"
_description = "Warranty Claim Line"
claim_id = fields.Many2one(
"bec.warranty.claim",
string="Warranty Claim",
required=True,
ondelete="cascade",
)
sale_line_id = fields.Many2one(
"sale.order.line",
string="Sales Order Line",
)
product_id = fields.Many2one(
"product.product",
string="Product",
required=True,
)
quantity = fields.Float(
string="Quantity",
default=1.0,
)
model = fields.Char("Model")
serial_number = fields.Char("Serial Number")
failure = fields.Text("Failure Description")