165 lines
5.8 KiB
Python
165 lines
5.8 KiB
Python
# -*- 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'
|