# -*- coding: utf-8 -*- # Copyright 2024-2026 Nexa Systems Inc. # License OPL-1 (Odoo Proprietary License v1.0) import logging import requests from odoo import models, fields, api _logger = logging.getLogger(__name__) class ResPartner(models.Model): _inherit = 'res.partner' x_fc_start_address = fields.Char( string='Start Location', help='Technician daily start location (home, warehouse, etc.). ' 'Used as origin for first travel time calculation. ' 'If empty, the company default HQ address is used.', ) x_fc_start_address_lat = fields.Float( string='Start Latitude', digits=(10, 7), ) x_fc_start_address_lng = fields.Float( string='Start Longitude', digits=(10, 7), ) def _geocode_start_address(self, address): if not address or not address.strip(): return 0.0, 0.0 api_key = self.env['ir.config_parameter'].sudo().get_param( 'fusion_claims.google_maps_api_key', '') if not api_key: return 0.0, 0.0 try: resp = requests.get( 'https://maps.googleapis.com/maps/api/geocode/json', params={'address': address.strip(), 'key': api_key, 'region': 'ca'}, timeout=10, ) data = resp.json() if data.get('status') == 'OK' and data.get('results'): loc = data['results'][0]['geometry']['location'] return loc['lat'], loc['lng'] except Exception as e: _logger.warning("Start address geocoding failed for '%s': %s", address, e) return 0.0, 0.0 @api.model_create_multi def create(self, vals_list): records = super().create(vals_list) for rec, vals in zip(records, vals_list): addr = vals.get('x_fc_start_address') if addr: lat, lng = rec._geocode_start_address(addr) if lat and lng: rec.write({ 'x_fc_start_address_lat': lat, 'x_fc_start_address_lng': lng, }) return records def write(self, vals): res = super().write(vals) if 'x_fc_start_address' in vals: addr = vals['x_fc_start_address'] if addr and addr.strip(): lat, lng = self._geocode_start_address(addr) if lat and lng: super().write({ 'x_fc_start_address_lat': lat, 'x_fc_start_address_lng': lng, }) else: super().write({ 'x_fc_start_address_lat': 0.0, 'x_fc_start_address_lng': 0.0, }) return res # ========================================================================== # CONTACT TYPE # ========================================================================== x_fc_contact_type = fields.Selection( selection=[ ('adp_customer', 'ADP Customer'), ('adp_odsp_customer', 'ADP-ODSP Customer'), ('odsp_customer', 'ODSP Customer'), ('mod_customer', 'MOD Customer'), ('private_customer', 'Private Customer'), ('wsib_customer', 'WSIB Customer'), ('acsd_customer', 'ACSD Customer'), ('private_insurance', 'Private Insurance'), ('adp_agent', 'ADP Agent'), ('odsp_agent', 'ODSP Agent'), ('muscular_dystrophy', 'Muscular Dystrophy'), ('occupational_therapist', 'Occupational Therapist'), ('physiotherapist', 'Physiotherapist'), ('vendor', 'Vendor'), ('funding_agency', 'Funding Agency'), ('government_agency', 'Government Agency'), ('company_contact', 'Company Contact'), ('long_term_care_home', 'Long Term Care Home'), ('retirement_home', 'Retirement Home'), ('odsp_office', 'ODSP Office'), ('other', 'Other'), ], string='Contact Type', tracking=True, index=True, ) # ========================================================================== # ODSP FIELDS # ========================================================================== x_fc_odsp_member_id = fields.Char( string='ODSP Member ID', size=9, tracking=True, help='9-digit Ontario Disability Support Program Member ID', ) x_fc_case_worker_id = fields.Many2one( 'res.partner', string='ODSP Case Worker', tracking=True, help='ODSP Case Worker assigned to this client', ) x_fc_date_of_birth = fields.Date( string='Date of Birth', tracking=True, ) x_fc_healthcard_number = fields.Char( string='Healthcard Number', tracking=True, ) x_fc_is_odsp_office = fields.Boolean( compute='_compute_is_odsp_office', string='Is ODSP Office', store=True, ) # ========================================================================== # LTC FIELDS # ========================================================================== x_fc_ltc_facility_id = fields.Many2one( 'fusion.ltc.facility', string='LTC Home', tracking=True, help='Long-Term Care Home this resident belongs to', ) x_fc_ltc_room_number = fields.Char( string='Room Number', tracking=True, ) x_fc_ltc_family_contact_ids = fields.One2many( 'fusion.ltc.family.contact', 'partner_id', string='Family Contacts', ) @api.depends('x_fc_contact_type') def _compute_is_odsp_office(self): for partner in self: partner.x_fc_is_odsp_office = partner.x_fc_contact_type == 'odsp_office'