[FIX] web: handle float fields with digits=0
According to the orm documentation, the `digits` attribute of float fields must be either a tuple (int, int) or a string. However, people set `digits=0` on a bunch of float fields (some are there for a while now). Historically, the webclient handled this as "there's no digits attribute set", so it fallbacked on 2 digits precision. With the new views, and owl props validation, we assert that the `digits` props, when given, is an array. In the above situations, we have a props validation error. This commit fixes the error by filtering out the `digits` props when it is not an array, s.t. it keeps working as before (i.e. fallbacks on 2 digits). In master, we'll remove the fallback. opw 3083100 closes odoo/odoo#107418 X-original-commit: 36407a9837ba3bf90670ae763751dc631309867b Signed-off-by: Michaël Mattiello <mcm@odoo.com>
This commit is contained in:
@@ -49,12 +49,20 @@ FloatField.supportedTypes = ["float"];
|
||||
|
||||
FloatField.isEmpty = () => false;
|
||||
FloatField.extractProps = ({ attrs, field }) => {
|
||||
// Sadly, digits param was available as an option and an attr.
|
||||
// The option version could be removed with some xml refactoring.
|
||||
let digits;
|
||||
if (attrs.digits) {
|
||||
digits = JSON.parse(attrs.digits);
|
||||
} else if (attrs.options.digits) {
|
||||
digits = attrs.options.digits;
|
||||
} else if (Array.isArray(field.digits)) {
|
||||
digits = field.digits;
|
||||
}
|
||||
return {
|
||||
inputType: attrs.options.type,
|
||||
step: attrs.options.step,
|
||||
// Sadly, digits param was available as an option and an attr.
|
||||
// The option version could be removed with some xml refactoring.
|
||||
digits: (attrs.digits ? JSON.parse(attrs.digits) : attrs.options.digits) || field.digits,
|
||||
digits,
|
||||
placeholder: attrs.placeholder,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -48,8 +48,16 @@ FloatToggleField.supportedTypes = ["float"];
|
||||
|
||||
FloatToggleField.isEmpty = () => false;
|
||||
FloatToggleField.extractProps = ({ attrs, field }) => {
|
||||
let digits;
|
||||
if (attrs.digits) {
|
||||
digits = JSON.parse(attrs.digits);
|
||||
} else if (attrs.options.digits) {
|
||||
digits = attrs.options.digits;
|
||||
} else if (Array.isArray(field.digits)) {
|
||||
digits = field.digits;
|
||||
}
|
||||
return {
|
||||
digits: (attrs.digits ? JSON.parse(attrs.digits) : attrs.options.digits) || field.digits,
|
||||
digits,
|
||||
range: attrs.options.range,
|
||||
factor: attrs.options.factor,
|
||||
disableReadOnly: attrs.options.force_button || false,
|
||||
|
||||
@@ -42,8 +42,16 @@ PercentageField.displayName = _lt("Percentage");
|
||||
PercentageField.supportedTypes = ["integer", "float"];
|
||||
|
||||
PercentageField.extractProps = ({ attrs, field }) => {
|
||||
let digits;
|
||||
if (attrs.digits) {
|
||||
digits = JSON.parse(attrs.digits);
|
||||
} else if (attrs.options.digits) {
|
||||
digits = attrs.options.digits;
|
||||
} else if (Array.isArray(field.digits)) {
|
||||
digits = field.digits;
|
||||
}
|
||||
return {
|
||||
digits: (attrs.digits ? JSON.parse(attrs.digits) : attrs.options.digits) || field.digits,
|
||||
digits,
|
||||
placeholder: attrs.placeholder,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -33,10 +33,18 @@ StatInfoField.supportedTypes = ["float", "integer", "monetary"];
|
||||
|
||||
StatInfoField.isEmpty = () => false;
|
||||
StatInfoField.extractProps = ({ attrs, field }) => {
|
||||
let digits;
|
||||
if (attrs.digits) {
|
||||
digits = JSON.parse(attrs.digits);
|
||||
} else if (attrs.options.digits) {
|
||||
digits = attrs.options.digits;
|
||||
} else if (Array.isArray(field.digits)) {
|
||||
digits = field.digits;
|
||||
}
|
||||
return {
|
||||
labelField: attrs.options.label_field,
|
||||
noLabel: archParseBoolean(attrs.nolabel),
|
||||
digits: (attrs.digits ? JSON.parse(attrs.digits) : attrs.options.digits) || field.digits,
|
||||
digits,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -453,4 +453,27 @@ QUnit.module("Fields", (hooks) => {
|
||||
target.querySelectorAll(".o_field_widget[name=float_field] input")[1].value
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("float field with digits=0", async function (assert) {
|
||||
// This isn't in the orm documentation, so it shouldn't be supported, but
|
||||
// people do it and thus now we need to support it.
|
||||
// Historically, it behaves like "no digits attribute defined", so it
|
||||
// fallbacks on a precision of 2 digits.
|
||||
// We will change that in master s.t. we do not round anymore in that case.
|
||||
serverData.models.partner.fields.float_field.digits = 0;
|
||||
|
||||
await makeView({
|
||||
type: "form",
|
||||
serverData,
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
arch: '<form><field name="float_field"/></form>',
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
target.querySelector(".o_field_float input").value,
|
||||
"0.36",
|
||||
"should contain a number rounded to 1 decimal"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user