[FIX] hr, mail: no crash on empty member.persona

Steps to reproduce:
- install `hr_homeworking`
- connect as Mitchell Admin
- make a private chat with Marc Demo
- `@mention` Marc Demo
=> crash (cannot read name of undefined (reading persona))

This happens because a spread record was inserted in model,
and in this scenario the record list in data can be the exact same
as the record list used in the model. The internal code of assigning
a many list is to `clear()` and then `push()` from data, but if the
data mutates from the `clear()`, then the `push()` does nothing and
the resulting relation is emptied.

This commit fixes the issue by keeping a copy of collection before
`clear()` so that push applies on original data that is intended by
insert.

This commit also adapt code in hr to not use spread record to insert
Persona. While it works with the fix, it's simpler to just update the
appropriate field and also more efficient, because spread a record
has to process all fields as an insert, wasting CPU time.

closes odoo/odoo#139143

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
Alexandre Kühn
2023-10-19 17:01:15 +00:00
parent 86c713117b
commit a479a0bba6
2 changed files with 7 additions and 8 deletions
@@ -26,7 +26,6 @@ threadActionsRegistry.add("open-hr-profile", {
async setup(action) {
const component = useComponent();
const orm = useService("orm");
const store = useService("mail.store");
let employeeId;
if (!component.thread?.correspondent?.employeeId && component.thread?.chatPartner) {
const employees = await orm.silent.searchRead(
@@ -35,12 +34,9 @@ threadActionsRegistry.add("open-hr-profile", {
["id"]
);
employeeId = employees[0]?.id;
}
if (employeeId) {
store.Persona.insert({
...component.thread.correspondent,
employeeId,
});
if (employeeId) {
component.thread.chatPartner.employeeId = employeeId;
}
}
},
sequence: 16,
@@ -227,8 +227,11 @@ export const storeService = {
for (const r2 of oldRecords) {
r2.__invs__.delete(r1.localId, name);
}
// l1 and collection could be same record list,
// save before clear to not push mutated recordlist that is empty
const col = [...collection];
l1.clear();
l1.push(...collection);
l1.push(...col);
} else {
// [Record.one] =
if (Record.isCommand(val)) {