Add conflict-of-interest check engine; gate stage advancement at Intake
- New fl.conflict.check model: screens petitioner/respondent/party_ids names against parties on other open cases (exact partner match + difflib fuzzy match at 0.85 threshold); skips folded/closed stages - Runs automatically as the first action in fl.case.create; logs conflicts to chatter with matched-case detail and never silently passes - fl.case gains conflict_check_passed/conflict_check_id/conflict_check_ids; write() blocks advancing stage_id past Intake until the check passes - Admin-only action_override requires a written justification, stamps user/date, and flips conflict_check_passed True with a chatter audit entry - Add conflict check form/tree/search views, action, Cases sub-menu item, case form banner + Run Conflict Check button, and Kanban conflict badge - ACL entries for fl.conflict.check (admin full, paralegal no-delete) - Finish Claude migration cleanup in fl_analysis.py (model_used default, docstring/help text) - Add .gitignore for Python artifacts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
|
||||
@@ -86,6 +87,23 @@ class FlCase(models.Model):
|
||||
)
|
||||
active = fields.Boolean(default=True)
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
# CONFLICT OF INTEREST
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
|
||||
conflict_check_passed = fields.Boolean(
|
||||
string='Conflict Check Passed',
|
||||
default=False, tracking=True,
|
||||
help='Case cannot advance past Intake until the conflict-of-interest '
|
||||
'check passes (or is overridden by an administrator).'
|
||||
)
|
||||
conflict_check_id = fields.Many2one(
|
||||
'fl.conflict.check', string='Latest Conflict Check', readonly=True
|
||||
)
|
||||
conflict_check_ids = fields.One2many(
|
||||
'fl.conflict.check', 'case_id', string='Conflict Checks'
|
||||
)
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
# PARTIES
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
@@ -794,6 +812,8 @@ class FlCase(models.Model):
|
||||
) or _('New')
|
||||
records = super().create(vals_list)
|
||||
for record in records:
|
||||
# 0. Conflict-of-interest screen — runs before any other action
|
||||
self.env['fl.conflict.check'].run_check(record)
|
||||
# 1. Create Odoo project for task management
|
||||
record._create_case_project()
|
||||
# 2. Generate deadlines if filing date already set
|
||||
@@ -807,6 +827,20 @@ class FlCase(models.Model):
|
||||
return records
|
||||
|
||||
def write(self, vals):
|
||||
# Block advancing past Intake until conflict check has passed
|
||||
if vals.get('stage_id'):
|
||||
new_stage = self.env['fl.case.stage'].browse(vals['stage_id'])
|
||||
intake = self.env.ref(
|
||||
'activeblue_familylaw.fl_stage_intake', raise_if_not_found=False
|
||||
)
|
||||
if intake and new_stage.sequence > intake.sequence:
|
||||
for rec in self:
|
||||
if not rec.conflict_check_passed:
|
||||
raise UserError(_(
|
||||
"Cannot advance case %s past Intake: the "
|
||||
"conflict-of-interest check has not passed. Resolve or "
|
||||
"override the conflict before changing the stage."
|
||||
) % rec.name)
|
||||
result = super().write(vals)
|
||||
# Recalculate service-anchored deadlines when service_date is set/changed
|
||||
if 'service_date' in vals:
|
||||
@@ -1090,3 +1124,15 @@ class FlCase(models.Model):
|
||||
'target': 'new',
|
||||
'context': {'default_case_id': self.id},
|
||||
}
|
||||
|
||||
def action_run_conflict_check(self):
|
||||
self.ensure_one()
|
||||
check = self.env['fl.conflict.check'].run_check(self)
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Conflict Check Result',
|
||||
'res_model': 'fl.conflict.check',
|
||||
'res_id': check.id,
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user