[FIX] web: support force_save attribute on fields

In an x2many sub view, the attribute "force_save" on a field
indicates that the field value must be saved, even if the field is
readonly. Before this commit, this attribute was ignored by the
new views. In the BasicRelationalModal, we only needed to propagate
this attribute to the fieldsInfo given to the BasicModel. In the
RelationalModel, we needed to take the attribute into account.

closes odoo/odoo#95396

Signed-off-by: Géry Debongnie <ged@odoo.com>
This commit is contained in:
Aaron Bohy
2022-07-06 13:11:42 +02:00
parent ff82425e27
commit e7750dce2a
4 changed files with 47 additions and 1 deletions
@@ -108,6 +108,7 @@ function mapActiveFieldsToFieldsInfo(activeFields, fields, viewType) {
domain,
context: fieldDescr.context,
fieldDependencies: {}, // ??
force_save: fieldDescr.forceSave,
mode: fieldDescr.viewMode,
modifiers: fieldDescr.modifiers,
name: fieldName,
@@ -202,6 +202,7 @@ Field.parseFieldNode = function (node, models, modelName, viewType, jsClass) {
modifiers: JSON.parse(node.getAttribute("modifiers") || "{}"),
onChange: archParseBoolean(node.getAttribute("on_change")),
FieldComponent: getFieldClassFromRegistry(fields[name].type, widget, viewType, jsClass),
forceSave: archParseBoolean(node.getAttribute("force_save")),
decorations: {}, // populated below
noLabel: archParseBoolean(node.getAttribute("nolabel")),
props: {},
@@ -641,7 +641,12 @@ export class Record extends DataPoint {
getChanges(allFields = false, parentChanges = false) {
const changes = { ...(allFields ? this.data : this._changes) };
for (const fieldName in changes) {
if (!allFields && fieldName in this.activeFields && this.isReadonly(fieldName)) {
if (
!allFields &&
fieldName in this.activeFields &&
!this.activeFields[fieldName].forceSave &&
this.isReadonly(fieldName)
) {
delete changes[fieldName];
continue;
}
@@ -6119,6 +6119,45 @@ QUnit.module("Views", (hooks) => {
);
});
QUnit.test("readonly sub fields fields with force_save attribute", async function (assert) {
assert.expect(1);
serverData.models.partner.fields.foo.readonly = true;
serverData.models.partner.fields.int_field.readonly = true;
await makeView({
type: "form",
resModel: "partner",
serverData,
arch: `
<form>
<field name="p">
<tree editable="bottom">
<field name="foo" force_save="1"/>
<field name="int_field"/>
<field name="qux"/>
</tree>
</field>
</form>`,
mockRPC(route, args) {
if (args.method === "create") {
// foo should be saved because of the "force_save" attribute
// qux should be saved because it isn't readonly
// int_field should not be saved as it is readonly
assert.deepEqual(args.args[0].p, [[0, 1, { foo: "some value", qux: 6.5 }]]);
}
if (args.method === "onchange") {
return {
value: {
p: [[5], [0, 1, { foo: "some value", int_field: 44, qux: 6.5 }]],
},
};
}
},
});
await click(target.querySelector(".o_form_button_save"));
});
QUnit.test("readonly set by modifier do not break many2many_tags", async function (assert) {
serverData.models.partner.onchanges = {
bar: function (obj) {