# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import api, fields, models class HelpdeskTicket(models.Model): _inherit = 'helpdesk.ticket' request_type_id = fields.Many2one( 'helpdesk.request.type', string='Request Type', required=True, tracking=True, help="Type of ticket (e.g., Incident, Improvement)", default=lambda self: self._default_request_type_id() ) request_type_code = fields.Char( related='request_type_id.code', string='Request Type Code', store=True, readonly=True, help="Code of the request type for conditional logic" ) affected_module_id = fields.Many2one( 'ir.module.module', string='Affected Module', required=False, # Not required at DB level to allow null if module is uninstalled domain=[('state', '=', 'installed'), ('application', '=', True)], ondelete='set null', help="Odoo module where the issue or improvement occurs" ) business_impact = fields.Selection( [ ('0', 'Critical'), ('1', 'High'), ('2', 'Normal'), ], string='Business Impact', default='2', tracking=True, help="Urgency reported by the client" ) reproduce_steps = fields.Html( string='Steps to Reproduce', help="Detailed steps to reproduce the issue (only for Incidents)" ) business_goal = fields.Html( string='Business Goal', help="Business objective for this improvement (only for Improvements)" ) client_authorization = fields.Boolean( string='Client Authorization', default=False, help="Checkbox from web form indicating client authorization" ) estimated_hours = fields.Float( string='Estimated Hours', help="Hours quoted after analysis" ) approval_status = fields.Selection( [ ('draft', 'N/A'), ('waiting', 'Waiting for Approval'), ('approved', 'Approved'), ('rejected', 'Rejected'), ], string='Approval Status', default='draft', tracking=True, help="Status of the approval workflow" ) has_template = fields.Boolean( string='Has Template', compute='_compute_has_template', help="Indicates if the team has a template assigned" ) attachment_ids = fields.One2many( 'ir.attachment', 'res_id', string='Attachments', domain=[('res_model', '=', 'helpdesk.ticket')], help="Files attached to this ticket" ) @api.depends('team_id.template_id') def _compute_has_template(self): """Compute if team has a template""" for ticket in self: ticket.has_template = bool(ticket.team_id and ticket.team_id.template_id) @api.model def _default_request_type_id(self): """Default to 'Incident' type if available""" incident_type = self.env.ref( 'helpdesk_extras.type_incident', raise_if_not_found=False ) return incident_type.id if incident_type else False def _get_template_fields(self): """Get template fields for this ticket's team""" self.ensure_one() if not self.team_id or not self.team_id.template_id: return self.env['helpdesk.template.field'] return self.team_id.template_id.field_ids.sorted('sequence')