import logging from datetime import timedelta from odoo import models, fields, api try: import requests as http_requests except ImportError: http_requests = None _logger = logging.getLogger(__name__) WEBHOOK_TIMEOUT = 10 # seconds class MaintenanceEquipment(models.Model): _inherit = 'maintenance.equipment' maintenance_mode = fields.Boolean( string="Maintenance Mode", default=False, tracking=True, ) maintenance_mode_start = fields.Datetime( string="Maintenance Mode Start", readonly=True, ) maintenance_mode_end = fields.Datetime( string="Maintenance Mode End", readonly=True, help="Computed from start + configured duration", ) http_maintenance_request = fields.Many2one( 'maintenance.request', string="HTTP Maintenance Request", readonly=True, ) def action_activate_maintenance_mode(self): for rec in self: duration = int(self.env['ir.config_parameter'].sudo().get_param( 'maintenance_service_http_monitoring.maintenance_mode_duration', 4)) now = fields.Datetime.now() rec.write({ 'maintenance_mode': True, 'maintenance_mode_start': now, 'maintenance_mode_end': now + timedelta(hours=duration), }) def action_deactivate_maintenance_mode(self): for rec in self: rec.write({ 'maintenance_mode': False, 'maintenance_mode_start': False, 'maintenance_mode_end': False, }) @api.model def cron_deactivate_expired_maintenance_mode(self): now = fields.Datetime.now() expired = self.search([ ('maintenance_mode', '=', True), ('maintenance_mode_end', '<=', now), ]) expired.action_deactivate_maintenance_mode() def create_http_maintenance_request(self, ko_services): self.ensure_one() today = fields.Date.context_today(self) name = f"[HTTP KO] {self.name}" domain = [ ('name', '=', name), ('equipment_id', '=', self.id), ('maintenance_type', '=', 'corrective'), ('create_date', '>=', f"{today} 00:00:00"), ('create_date', '<=', f"{today} 23:59:59"), ] existing = self.env['maintenance.request'].search(domain, limit=1) # Check if a task with same name already exist for the day, if it’s the case : skip if existing: self.http_maintenance_request = existing.id return existing request = self.http_maintenance_request if request and not request.stage_id.done: return request vals = { 'name': name, 'equipment_id': self.id, 'priority': '2', 'maintenance_type': 'corrective', 'description': self._build_ko_services_description(ko_services), } if self.employee_id: vals['employee_id'] = self.employee_id.id if self.technician_user_id: vals['user_id'] = self.technician_user_id.id if self.maintenance_team_id: vals['maintenance_team_id'] = self.maintenance_team_id.id else: team = self.env['maintenance.team'].search([], limit=1) if team: vals['maintenance_team_id'] = team.id request = self.env['maintenance.request'].create(vals) self.http_maintenance_request = request.id self._notify_webhook(request, ko_services) return request def _notify_webhook(self, request, ko_services): """Send a webhook notification when a new maintenance request is created.""" ICP = self.env['ir.config_parameter'].sudo() webhook_url = ICP.get_param( 'maintenance_service_http_monitoring.webhook_url', '' ) if not webhook_url: return webhook_user = ICP.get_param( 'maintenance_service_http_monitoring.webhook_user', '' ) webhook_password = ICP.get_param( 'maintenance_service_http_monitoring.webhook_password', '' ) base_url = ICP.get_param('web.base.url', '') link = ( f"{base_url}/web#id={request.id}" f"&model=maintenance.request&view_type=form" ) payload = { 'id': request.id, 'name': request.name, 'description': request.description or '', 'equipment': self.name, 'link': link, } auth = None if webhook_user and webhook_password: auth = (webhook_user, webhook_password) try: http_requests.post( webhook_url, json=payload, auth=auth, timeout=WEBHOOK_TIMEOUT, ) except Exception as e: _logger.warning( "Webhook notification failed for maintenance request %s: %s", request.id, e, ) def _build_ko_services_description(self, ko_services): lines = [f"Service KO: {s.service_url or s.name}" for s in ko_services] return '\n'.join(lines)