fix(task_sync): defend against silent sync_id integrity violations

The cross-instance sync silently drops tasks when x_fc_tech_sync_id is
missing on the technician, and silently collapses duplicates via dict
comprehension. Both make sync break in ways that are invisible until
someone notices a missing task on the other instance.

- _get_remote_tech_map / _get_local_syncid_to_uid: warn on duplicates
- _push_tasks_to_remote: info-log when a task is skipped because the
  tech has no sync_id or no remote counterpart
- res.users onchange: warn in the form when entering a sync_id that
  is already used by another active field staff

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-20 22:29:48 -04:00
parent d4fb1eebbf
commit 8ef57a4bb1
3 changed files with 53 additions and 8 deletions

View File

@@ -2,7 +2,7 @@
# Copyright 2024-2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from odoo import models, fields
from odoo import models, fields, api
class ResUsers(models.Model):
@@ -24,3 +24,26 @@ class ResUsers(models.Model):
'Must be the same value on all instances for the same person.',
copy=False,
)
@api.onchange('x_fc_tech_sync_id')
def _onchange_x_fc_tech_sync_id_dup_warning(self):
if not self.x_fc_tech_sync_id:
return
dup = self.env['res.users'].sudo().search([
('id', '!=', self._origin.id or self.id),
('x_fc_tech_sync_id', '=', self.x_fc_tech_sync_id),
('x_fc_is_field_staff', '=', True),
('active', '=', True),
], limit=1)
if dup:
return {
'warning': {
'title': "Duplicate Tech Sync ID",
'message': (
f"Tech Sync ID {self.x_fc_tech_sync_id!r} is already used "
f"by {dup.login} ({dup.partner_id.name}). Cross-instance "
f"task sync only routes to ONE user per sync ID — "
f"pick a unique value or only one tech's tasks will sync."
),
}
}