Skip to content

Commit

Permalink
[FIX] automation_oca error on record delete
Browse files Browse the repository at this point in the history
  • Loading branch information
arielbarreiros96 committed Dec 5, 2024
1 parent cbfce37 commit 2a33c2c
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 24 deletions.
9 changes: 7 additions & 2 deletions automation_oca/models/automation_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,17 @@ def _compute_record_count(self):
data = self.env["automation.record"].read_group(
[("configuration_id", "in", self.ids), ("is_test", "=", False)],
[],
["configuration_id", "state"],
["configuration_id", "state", "is_placeholder"],
lazy=False,
)
mapped_data = defaultdict(lambda: {})
for d in data:
mapped_data[d["configuration_id"][0]][d["state"]] = d["__count"]
config_id = d["configuration_id"][0]
state = d["state"]
count = d["__count"]
is_placeholder = d.get("is_placeholder", False)
if not is_placeholder:
mapped_data[config_id][state] = count
for record in self:
record.record_done_count = mapped_data[record.id].get("done", 0)
record.record_run_count = mapped_data[record.id].get("periodic", 0)
Expand Down
78 changes: 57 additions & 21 deletions automation_oca/models/automation_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ class AutomationRecord(models.Model):
)
is_test = fields.Boolean()

is_placeholder = fields.Boolean(
default=False,
help="Indicates if this record is a placeholder for a missing resource.",
readonly=True,
)
missing_res_id = fields.Integer(
help="ID of the missing referenced resource.",
readonly=True,
)

@api.model
def _selection_target_model(self):
return [
Expand Down Expand Up @@ -89,56 +99,83 @@ def _search(
count=False,
access_rights_uid=access_rights_uid,
)
if self.env.is_system():
# restrictions do not apply to group "Settings"
return len(ids) if count else ids

# TODO highlight orphaned records in UI:
# - self.model + self.res_id are set
# - self.record returns empty recordset
# Remark: self.record is @property, not field

if not ids:
return 0 if count else []

orig_ids = ids
ids = set(ids)
result = []
model_data = defaultdict(
lambda: defaultdict(set)
) # {res_model: {res_id: set(ids)}}
model_data = defaultdict(lambda: defaultdict(set))

for sub_ids in self._cr.split_for_in_conditions(ids):
self._cr.execute(
"""
SELECT id, res_id, model
SELECT id, res_id, model, configuration_id
FROM "%s"
WHERE id = ANY (%%(ids)s)"""
% self._table,
dict(ids=list(sub_ids)),
)
for eid, res_id, model in self._cr.fetchall():
model_data[model][res_id].add(eid)
for eid, res_id, model, config_id in self._cr.fetchall():
model_data[model][(res_id, config_id)].add(eid)

for model, targets in model_data.items():
if not self.env[model].check_access_rights("read", False):
continue
recs = self.env[model].browse(list(targets))
res_ids = [res_id for res_id, _ in targets]
recs = self.env[model].browse(res_ids)
missing = recs - recs.exists()
if missing:
for res_id in missing.ids:
for (res_id, config_id) in [
(res_id, config_id)
for (res_id, config_id) in targets.keys()
if res_id in missing.ids
]:
_logger.warning(
"Deleted record %s,%s is referenced by automation.record %s",
"Deleted record %s,%s is referenced by automation.record",
model,
res_id,
list(targets[res_id]),
)
recs = recs - missing

placeholder_id = None
for pid in orig_ids:
placeholder = self.env["automation.record"].browse(pid)
if (
placeholder.missing_res_id == res_id
and placeholder.configuration_id.id == config_id
):
placeholder_id = placeholder.id
break

if placeholder_id:
result.append(placeholder_id)
else:
automation_record = self.env["automation.record"].browse(
targets[(res_id, config_id)]
)
placeholder = self.create(
{
"name": "Orphan Record",
"is_placeholder": True,
"missing_res_id": res_id,
"configuration_id": config_id,
"res_id": None,
"state": automation_record.state or "done",
"model": automation_record.model or model,
"resource_ref": automation_record.resource_ref,
"is_test": automation_record.is_test or False,
}
)
result.append(placeholder.id)
recs = recs - missing
allowed = (
self.env[model]
.with_context(active_test=False)
._search([("id", "in", recs.ids)])
)
for target_id in allowed:
result += list(targets[target_id])
result += list(targets.get((target_id, config_id), []))
if len(orig_ids) == limit and len(result) < len(orig_ids):
result.extend(
self._search(
Expand All @@ -150,7 +187,6 @@ def _search(
access_rights_uid=access_rights_uid,
)[: limit - len(result)]
)
# Restore original ordering
result = [x for x in orig_ids if x in result]
return len(result) if count else list(result)

Expand Down
13 changes: 12 additions & 1 deletion automation_oca/views/automation_record.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,18 @@
/>

<div class="oe_title">
<h1><field
<div attrs="{'invisible': [('is_placeholder', '=', False)]}">
<field name="is_placeholder" invisible="1" />
<h1><span>This record is an orphan record</span></h1>
<span>Original res_id: </span>
<field name="missing_res_id" />
<span>Model: </span>
<field name="model" />
</div>

<h1
attrs="{'invisible': [('is_placeholder', '=', True)]}"
><field
name="resource_ref"
required="1"
options="{'hide_model': True}"
Expand Down

0 comments on commit 2a33c2c

Please sign in to comment.