[FIX] web: keep unchanged values in datetime fields

To reproduce:
============
- on Planning create new shift
- select a template
- change the end date
-> the end date is reset to the template value

Problem:
========
- `end_datetime` and `start_datetime` have the same compute method
- `template_id` depends on `start_datetime` and `end_datetime`
- so changing `end_datetime` triggers the compute method of `template_id`
that will read `start_datetime`
- reading `start_datetime` triggers the compute method of `end_datetime`,
that will check if `template_id` is set and if so, will take its values
-------
 why the compute method of `end_datetime` is triggered ? :

-------
- `start_datetime` is not protected from recomputing, at this
line : https://github.com/odoo/odoo/blob/saas-16.3/odoo/models.py#L6746
we only protect the fields sent by frontend (only `end_datetime`)
- frontend doesn't send `start_datetime` as it was not changed

Solution
========
as ORM fix can't be made in stable, we send `start_datetime` in the `onchange`
query even if it's unchanged to make sure both fields are protected

opw-3693206

closes odoo/odoo#155705

X-original-commit: 7081372e721387da983621b3dd2986ae0872e4c8
Signed-off-by: Julien Mougenot (jum) <jum@odoo.com>
Signed-off-by: Abdelouahab Laaroussi (abla) <abla@odoo.com>
This commit is contained in:
Abdelouahab (abla)
2024-02-29 08:57:57 +00:00
parent c85efc0473
commit d7da674803
3 changed files with 23 additions and 7 deletions
@@ -115,12 +115,25 @@ export class DateTimeField extends Component {
} else {
toUpdate[this.props.name] = this.state.value;
}
// Remove values that did not change
for (const fieldName in toUpdate) {
if (areDatesEqual(toUpdate[fieldName], this.props.record.data[fieldName])) {
delete toUpdate[fieldName];
// when startDateField and endDateField are set, and one of them has changed, we keep
// the unchanged one to make sure ORM protects both fields from being recomputed by the
// server, ORM team will handle this properly on master, then we can remove unchanged values
if (!this.startDateField || !this.endDateField) {
// If startDateField or endDateField are not set, delete unchanged fields
for (const fieldName in toUpdate) {
if (areDatesEqual(toUpdate[fieldName], this.props.record.data[fieldName])) {
delete toUpdate[fieldName];
}
}
} else {
// If both startDateField and endDateField are set, check if they haven't changed
if (areDatesEqual(toUpdate[this.startDateField], this.props.record.data[this.startDateField]) &&
areDatesEqual(toUpdate[this.endDateField], this.props.record.data[this.endDateField])) {
delete toUpdate[this.startDateField];
delete toUpdate[this.endDateField];
}
}
if (Object.keys(toUpdate).length) {
this.props.record.update(toUpdate);
}
@@ -376,7 +376,10 @@ QUnit.module("Fields", (hooks) => {
resId: 1,
mockRPC(route, args) {
if (args.method === "web_save") {
assert.deepEqual(args.args[1], { datetime: "2017-02-08 06:00:00" });
assert.deepEqual(args.args[1], {
datetime: "2017-02-08 06:00:00",
datetime_end: "2017-03-13 00:00:00",
});
}
},
});
@@ -11509,7 +11509,7 @@ QUnit.module("Views", (hooks) => {
</tree>`,
mockRPC(route, args) {
if (args.method === "write") {
assert.deepEqual(args.args, [[1, 2], { date_start: "2021-04-01" }]);
assert.deepEqual(args.args, [[1, 2], { date_start: "2021-04-01", date_end: "2017-01-26"}]);
}
},
});
@@ -11535,7 +11535,7 @@ QUnit.module("Views", (hooks) => {
const changesTable = target.querySelector(".modal-body .o_modal_changes");
assert.strictEqual(
changesTable.innerText.replaceAll("\n", "").replaceAll("\t", ""),
"Field:Date StartUpdate to:04/01/202101/26/2017"
"Field:Date StartUpdate to:04/01/202101/26/2017Field:Date EndUpdate to:01/26/2017"
);
// Valid the confirm dialog