changes
This commit is contained in:
@@ -20,18 +20,7 @@ class FusionADPDeviceCode(models.Model):
|
||||
_order = 'device_type, device_code'
|
||||
|
||||
def _register_hook(self):
|
||||
"""
|
||||
Called when the model is loaded.
|
||||
Re-loads device codes from packaged JSON on module upgrade.
|
||||
"""
|
||||
super()._register_hook()
|
||||
# Use with_context to check if this is a module upgrade
|
||||
# The data will be loaded via post_init_hook on install,
|
||||
# and via this hook on upgrade (when module is reloaded)
|
||||
try:
|
||||
self.sudo()._load_packaged_device_codes()
|
||||
except Exception as e:
|
||||
_logger.warning("Could not auto-load device codes: %s", str(e))
|
||||
|
||||
# ==========================================================================
|
||||
# MAIN FIELDS
|
||||
|
||||
@@ -69,7 +69,60 @@ class ResPartner(models.Model):
|
||||
store=True,
|
||||
)
|
||||
|
||||
# ==========================================================================
|
||||
# AUTHORIZER FIELDS
|
||||
# ==========================================================================
|
||||
x_fc_authorizer_number = fields.Char(
|
||||
string='ADP Authorizer Number',
|
||||
tracking=True,
|
||||
index=True,
|
||||
help='ADP Registration Number for this authorizer (e.g. OT). '
|
||||
'Used to auto-link authorizers when processing ADP XML files.',
|
||||
)
|
||||
x_fc_adp_application_count = fields.Integer(
|
||||
string='ADP Applications',
|
||||
compute='_compute_adp_application_count',
|
||||
)
|
||||
|
||||
@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'
|
||||
|
||||
def _compute_adp_application_count(self):
|
||||
AppData = self.env['fusion.adp.application.data']
|
||||
for partner in self:
|
||||
domain = self._get_authorizer_application_domain(partner)
|
||||
partner.x_fc_adp_application_count = AppData.search_count(domain) if domain else 0
|
||||
|
||||
def _get_authorizer_application_domain(self, partner):
|
||||
"""Build domain to find applications linked to this authorizer."""
|
||||
conditions = []
|
||||
if partner.x_fc_authorizer_number:
|
||||
conditions.append(('authorizer_adp_number', '=', partner.x_fc_authorizer_number))
|
||||
name = (partner.name or '').strip()
|
||||
if name:
|
||||
parts = name.replace(',', ' ').split()
|
||||
if len(parts) >= 2:
|
||||
conditions.append(
|
||||
'&',
|
||||
)
|
||||
conditions.append(('authorizer_last_name', 'ilike', parts[0]))
|
||||
conditions.append(('authorizer_first_name', 'ilike', parts[-1]))
|
||||
if not conditions:
|
||||
return []
|
||||
if len(conditions) > 3:
|
||||
return ['|'] + conditions
|
||||
return conditions
|
||||
|
||||
def action_view_adp_applications(self):
|
||||
self.ensure_one()
|
||||
domain = self._get_authorizer_application_domain(self)
|
||||
return {
|
||||
'name': 'ADP Applications',
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'fusion.adp.application.data',
|
||||
'view_mode': 'list,form',
|
||||
'domain': domain,
|
||||
'context': {'default_authorizer_adp_number': self.x_fc_authorizer_number or ''},
|
||||
}
|
||||
|
||||
@@ -66,6 +66,10 @@ class FusionXmlParser(models.AbstractModel):
|
||||
# Step 3: Create/update profile
|
||||
profile = self._find_or_create_profile(model_vals, sale_order)
|
||||
|
||||
# Step 3b: Auto-link authorizer on sale order by ADP number
|
||||
if sale_order:
|
||||
self._link_authorizer_by_adp_number(model_vals, sale_order)
|
||||
|
||||
# Step 4: Create application data record
|
||||
model_vals['profile_id'] = profile.id
|
||||
model_vals['sale_order_id'] = sale_order.id if sale_order else False
|
||||
@@ -637,6 +641,39 @@ class FusionXmlParser(models.AbstractModel):
|
||||
# ------------------------------------------------------------------
|
||||
# PROFILE MANAGEMENT
|
||||
# ------------------------------------------------------------------
|
||||
def _link_authorizer_by_adp_number(self, vals, sale_order):
|
||||
"""Auto-link the authorizer contact on the sale order using the ADP number from XML."""
|
||||
adp_number = (vals.get('authorizer_adp_number') or '').strip()
|
||||
if not adp_number or adp_number.upper() in ('NA', 'N/A', ''):
|
||||
return
|
||||
|
||||
if sale_order.x_fc_authorizer_id:
|
||||
return
|
||||
|
||||
Partner = self.env['res.partner']
|
||||
authorizer = Partner.search([
|
||||
('x_fc_authorizer_number', '=', adp_number),
|
||||
], limit=1)
|
||||
|
||||
if not authorizer:
|
||||
first = (vals.get('authorizer_first_name') or '').strip()
|
||||
last = (vals.get('authorizer_last_name') or '').strip()
|
||||
if first and last:
|
||||
authorizer = Partner.search([
|
||||
'|',
|
||||
('name', 'ilike', f'{first} {last}'),
|
||||
('name', 'ilike', f'{last}, {first}'),
|
||||
], limit=1)
|
||||
if authorizer and not authorizer.x_fc_authorizer_number:
|
||||
authorizer.write({'x_fc_authorizer_number': adp_number})
|
||||
|
||||
if authorizer:
|
||||
sale_order.write({'x_fc_authorizer_id': authorizer.id})
|
||||
_logger.info(
|
||||
'Auto-linked authorizer %s (ADP# %s) to SO %s',
|
||||
authorizer.name, adp_number, sale_order.name,
|
||||
)
|
||||
|
||||
def _find_or_create_profile(self, vals, sale_order=None):
|
||||
"""Find or create a client profile from parsed application data."""
|
||||
Profile = self.env['fusion.client.profile']
|
||||
|
||||
@@ -16,6 +16,22 @@
|
||||
<field name="x_fc_contact_type" placeholder="Select contact type..."/>
|
||||
</xpath>
|
||||
|
||||
<!-- ADP Applications smart button for authorizers -->
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<button name="action_view_adp_applications" type="object"
|
||||
class="oe_stat_button" icon="fa-file-text"
|
||||
invisible="x_fc_adp_application_count == 0">
|
||||
<field name="x_fc_adp_application_count" widget="statinfo" string="Applications"/>
|
||||
</button>
|
||||
</xpath>
|
||||
|
||||
<!-- Authorizer number for OTs/PTs/authorizer contacts -->
|
||||
<xpath expr="//field[@name='x_fc_contact_type']" position="after">
|
||||
<field name="x_fc_authorizer_number" string="ADP Reg. Number"
|
||||
invisible="x_fc_contact_type not in ('occupational_therapist', 'physiotherapist', 'adp_agent')"
|
||||
placeholder="e.g. 3000001234"/>
|
||||
</xpath>
|
||||
|
||||
<!-- ODSP section in notebook -->
|
||||
<xpath expr="//notebook" position="inside">
|
||||
<page string="ODSP" name="odsp_info"
|
||||
|
||||
Reference in New Issue
Block a user