[FIX] web: Date{Time,}Field formatting empty values

Steps to reproduce
==================

- Install mrp_product_expiry
- Go to Inventory > Products > Lots/Serial Numbers
- Add the column "Expiration date"
- Remove the groupby if any
- Select 2 records, set an expiration date
- Confirm
- Select the same records, remove the expiration date
-> TypeError: value.setZone is not a function

Cause of the issue
==================

When entering the readonly mode after changing the date, the function
`formattedValue` is called. But `this.props.value` is equal to `""`.
`formatDateTime` only handles `DateTime | false`

The field is rendered from this template https://github.com/odoo/odoo/blob/1d8f6359bbf55983a9582282d12a187c67cdf509/addons/web/static/src/views/list/list_renderer.xml#L233-L236

When `canUseFormatter` returns true, formatDateTime is called with
false, coming from `record.data[fieldName]`

opw-3111869

closes odoo/odoo#109436

X-original-commit: 5b26a080ae28fab2a78e92a838472578591eef17
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Hubert Van de Walle (huvw)
2023-01-09 15:29:07 +01:00
parent 65c23b4bc7
commit c7208ecaee
3 changed files with 77 additions and 2 deletions
@@ -217,7 +217,7 @@ export class DatePicker extends Component {
onDateChange({ useStatic } = {}) {
const { value } = this.inputRef.el;
const options = this.getOptions(useStatic);
const parsedDate = value && this.parseValue(value, options)[0];
const parsedDate = this.parseValue(value, options)[0];
this.state.warning = parsedDate && parsedDate > DateTime.local();
if (value && !parsedDate) {
// Reset to default (= given) date.
@@ -5,6 +5,7 @@ import {
click,
clickCreate,
clickSave,
editInput,
getFixture,
patchTimeZone,
patchWithCleanup,
@@ -517,6 +518,43 @@ QUnit.module("Fields", (hooks) => {
);
});
QUnit.test(
"multi edition of DateField in list view: clear date in input",
async function (assert) {
serverData.models.partner.records[1].date = "2017-02-03";
await makeView({
serverData,
type: "list",
resModel: "partner",
arch: '<tree multi_edit="1"><field name="date"/></tree>',
});
const rows = target.querySelectorAll(".o_data_row");
// select two records and edit them
await click(rows[0], ".o_list_record_selector input");
await click(rows[1], ".o_list_record_selector input");
await click(rows[0], ".o_data_cell");
assert.containsOnce(target, "input.o_datepicker_input");
await editInput(target, ".o_datepicker_input", "");
assert.containsOnce(document.body, ".modal");
await click(target, ".modal .modal-footer .btn-primary");
assert.strictEqual(
target.querySelector(".o_data_row:first-child .o_data_cell").textContent,
""
);
assert.strictEqual(
target.querySelector(".o_data_row:nth-child(2) .o_data_cell").textContent,
""
);
}
);
QUnit.test("DateField remove value", async function (assert) {
await makeView({
type: "form",
@@ -359,12 +359,49 @@ QUnit.module("Fields", (hooks) => {
"10/02/2019 09:00:00"
);
assert.strictEqual(
target.querySelector(".o_data_row:nth-child(1) .o_data_cell").textContent,
target.querySelector(".o_data_row:nth-child(2) .o_data_cell").textContent,
"10/02/2019 09:00:00"
);
}
);
QUnit.test(
"multi edition of DatetimeField in list view: clear date in input",
async function (assert) {
serverData.models.partner.records[1].datetime = "2017-02-08 10:00:00";
await makeView({
serverData,
type: "list",
resModel: "partner",
arch: '<tree multi_edit="1"><field name="datetime"/></tree>',
});
const rows = target.querySelectorAll(".o_data_row");
// select two records and edit them
await click(rows[0], ".o_list_record_selector input");
await click(rows[1], ".o_list_record_selector input");
await click(rows[0], ".o_data_cell");
assert.containsOnce(target, "input.o_datepicker_input");
await editInput(target, ".o_datepicker_input", "");
assert.containsOnce(document.body, ".modal");
await click(target, ".modal .modal-footer .btn-primary");
assert.strictEqual(
target.querySelector(".o_data_row:first-child .o_data_cell").textContent,
""
);
assert.strictEqual(
target.querySelector(".o_data_row:nth-child(2) .o_data_cell").textContent,
""
);
}
);
QUnit.test("DatetimeField remove value", async function (assert) {
assert.expect(4);