# -*- coding: utf-8 -*- # Copyright 2024-2026 Nexa Systems Inc. # License OPL-1 (Odoo Proprietary License v1.0) """ Fusion Technician Location GPS location logging for field technicians. """ from odoo import models, fields, api, _ import logging _logger = logging.getLogger(__name__) class FusionTechnicianLocation(models.Model): _name = 'fusion.technician.location' _description = 'Technician Location Log' _order = 'logged_at desc' user_id = fields.Many2one( 'res.users', string='Technician', required=True, index=True, ondelete='cascade', ) latitude = fields.Float( string='Latitude', digits=(10, 7), required=True, ) longitude = fields.Float( string='Longitude', digits=(10, 7), required=True, ) accuracy = fields.Float( string='Accuracy (m)', help='GPS accuracy in meters', ) logged_at = fields.Datetime( string='Logged At', default=fields.Datetime.now, required=True, index=True, ) source = fields.Selection([ ('portal', 'Portal'), ('app', 'Mobile App'), ], string='Source', default='portal') @api.model def log_location(self, latitude, longitude, accuracy=None): """Log the current user's location. Called from portal JS.""" return self.sudo().create({ 'user_id': self.env.user.id, 'latitude': latitude, 'longitude': longitude, 'accuracy': accuracy or 0, 'source': 'portal', }) @api.model def get_latest_locations(self): """Get the most recent location for each technician (for map view).""" self.env.cr.execute(""" SELECT DISTINCT ON (user_id) user_id, latitude, longitude, accuracy, logged_at FROM fusion_technician_location WHERE logged_at > NOW() - INTERVAL '24 hours' ORDER BY user_id, logged_at DESC """) rows = self.env.cr.dictfetchall() result = [] for row in rows: user = self.env['res.users'].sudo().browse(row['user_id']) result.append({ 'user_id': row['user_id'], 'name': user.name, 'latitude': row['latitude'], 'longitude': row['longitude'], 'accuracy': row['accuracy'], 'logged_at': str(row['logged_at']), }) return result @api.model def _cron_cleanup_old_locations(self): """Remove location logs based on configurable retention setting. Setting (fusion_claims.location_retention_days): - Empty / not set => keep 30 days (default) - "0" => delete at end of day (keep today only) - "1" .. "N" => keep for N days """ ICP = self.env['ir.config_parameter'].sudo() raw = (ICP.get_param('fusion_claims.location_retention_days') or '').strip() if raw == '': retention_days = 30 # default: 1 month else: try: retention_days = max(int(raw), 0) except (ValueError, TypeError): retention_days = 30 cutoff = fields.Datetime.subtract(fields.Datetime.now(), days=retention_days) old_records = self.search([('logged_at', '<', cutoff)]) count = len(old_records) if count: old_records.unlink() _logger.info( "Cleaned up %d technician location records (retention=%d days)", count, retention_days, )