[FIX] web: no_quick_create option ignored
Steps to reproduce ================== 1. Install event 2. Go to Events 3. Configuration > Event Templates 4. Click on any event 5. Click on Communication 6. Add a line, change type to SMS 7. Type anything in Template 8. Click on Create "..." 9. The operation cannot be completed Cause of the issue ================== For many2one and many2many editable fields, the server sets the can_create and can_write attributes on the field nodes. [1][2] In some cases [3], those attributes are missing even though the fields are actually editable. They are also absent for reference fields. The `canQuickCreate` props was set to the following value: `canCreate && !noQuickCreate`. When canCreate was absent, this was evaluated to undefined, thus ignoring the noQuickCreate option. Solution ======== When the permission attributes are missing, we have to assume that the user has the appropriate permissions. We also have to cast the extracted props to booleans as if you have an props with a value of undefined, it will fall back to the default value. In the test `no_quick_create option on a many2one when can_create is absent`, we set the field as readonly and then cancel the readonly on the view. This reproduces one of the bug of [3] which causes the permission attributes to be missing. ----- [1]: https://github.com/odoo/odoo/blob/fa6da3d63a3a4cce4e8ca788a49772925d318764/odoo/addons/base/models/ir_ui_view.py#L1296-L1297 [2]: https://github.com/odoo/odoo/blob/fa6da3d63a3a4cce4e8ca788a49772925d318764/odoo/addons/base/models/ir_ui_view.py#L1080-L1086 [3]: https://github.com/odoo/odoo/pull/138032 opw-3609799 closes odoo/odoo#148163 X-original-commit: efcb2a820bb57f1fae809725e799b3145fbbe599 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com> Signed-off-by: Antoine Demany (ande) <ande@odoo.com>
This commit is contained in:
@@ -222,10 +222,9 @@ export const many2ManyTagsField = {
|
||||
return relatedFields;
|
||||
},
|
||||
extractProps({ attrs, options, string }, dynamicInfo) {
|
||||
const hasCreatePermission = attrs.can_create ? evaluateBooleanExpr(attrs.can_create) : true;
|
||||
const noCreate = Boolean(options.no_create);
|
||||
const canCreate = noCreate
|
||||
? false
|
||||
: attrs.can_create && evaluateBooleanExpr(attrs.can_create);
|
||||
const canCreate = noCreate ? false : hasCreatePermission;
|
||||
const noQuickCreate = Boolean(options.no_quick_create);
|
||||
const noCreateEdit = Boolean(options.no_create_edit);
|
||||
return {
|
||||
|
||||
@@ -366,13 +366,14 @@ export const many2OneField = {
|
||||
],
|
||||
supportedTypes: ["many2one"],
|
||||
extractProps({ attrs, context, decorations, options, string }, dynamicInfo) {
|
||||
const canCreate =
|
||||
options.no_create ? false : attrs.can_create && evaluateBooleanExpr(attrs.can_create);
|
||||
const hasCreatePermission = attrs.can_create ? evaluateBooleanExpr(attrs.can_create) : true;
|
||||
const hasWritePermission = attrs.can_write ? evaluateBooleanExpr(attrs.can_write) : true;
|
||||
const canCreate = options.no_create ? false : hasCreatePermission
|
||||
return {
|
||||
placeholder: attrs.placeholder,
|
||||
canOpen: !options.no_open,
|
||||
canCreate,
|
||||
canWrite: attrs.can_write && evaluateBooleanExpr(attrs.can_write),
|
||||
canWrite: hasWritePermission,
|
||||
canQuickCreate: canCreate && !options.no_quick_create,
|
||||
canCreateEdit: canCreate && !options.no_create_edit,
|
||||
context: context,
|
||||
|
||||
@@ -1457,4 +1457,53 @@ QUnit.module("MockServer", (hooks) => {
|
||||
});
|
||||
assert.deepEqual(result.value, { foo: 0 });
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"access rights attributes are present on an editable many2one field",
|
||||
async function (assert) {
|
||||
data.views = {
|
||||
"bar,10001,form": `<form>
|
||||
<field name="partner_id"/>
|
||||
</form>`,
|
||||
"bar,10001,search": `<search></search>`,
|
||||
};
|
||||
|
||||
const expectedForm = `<form>
|
||||
<field name="partner_id" can_create="true" can_write="true"/>
|
||||
</form>`;
|
||||
const mockServer = new MockServer(data);
|
||||
const { views } = mockServer.mockGetViews("bar", {
|
||||
views: [[10001, "form"]],
|
||||
options: {},
|
||||
});
|
||||
assert.deepEqual(views.form.arch, expectedForm);
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test(
|
||||
"access rights attributes are missing on an editable many2one field",
|
||||
async function (assert) {
|
||||
// The access rights attributes should be present,
|
||||
// but are actually missing when a field definition is readonly and readonly=0 is on the view.
|
||||
// @see the commit description for more details.
|
||||
|
||||
data.models.bar.fields.partner_id.readonly = true;
|
||||
data.views = {
|
||||
"bar,10001,form": `<form>
|
||||
<field name="partner_id" readonly="0"/>
|
||||
</form>`,
|
||||
"bar,10001,search": `<search></search>`,
|
||||
};
|
||||
|
||||
const expectedForm = `<form>
|
||||
<field name="partner_id" readonly="0"/>
|
||||
</form>`;
|
||||
const mockServer = new MockServer(data);
|
||||
const { views } = mockServer.mockGetViews("bar", {
|
||||
views: [[10001, "form"]],
|
||||
options: {},
|
||||
});
|
||||
assert.deepEqual(views.form.arch, expectedForm);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -3239,6 +3239,31 @@ QUnit.module("Fields", (hooks) => {
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("no_quick_create option on a many2one when can_create is absent", async function (assert) {
|
||||
serverData.models.partner.fields.product_id.readonly = true;
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<sheet>
|
||||
<field name="product_id" options="{'no_quick_create': 1}" readonly="0" />
|
||||
</sheet>
|
||||
</form>`,
|
||||
});
|
||||
await editInput(target, ".o_field_many2one input", "new partner");
|
||||
assert.containsOnce(
|
||||
target,
|
||||
".ui-autocomplete .o_m2o_dropdown_option",
|
||||
"Dropdown should be opened and have only one item"
|
||||
);
|
||||
assert.hasClass(
|
||||
target.querySelector(".ui-autocomplete .o_m2o_dropdown_option"),
|
||||
"o_m2o_dropdown_option_create_edit"
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("can_create and can_write option on a many2one", async function (assert) {
|
||||
serverData.models.product.options = {
|
||||
can_create: "false",
|
||||
|
||||
@@ -258,6 +258,28 @@ QUnit.module("Fields", (hooks) => {
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("ReferenceField respects no_quick_create", async function (assert) {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `<form><field name="reference" options="{'no_quick_create': 1}" /></form>`,
|
||||
});
|
||||
|
||||
await editSelect(target, "select", "partner");
|
||||
await click(target, ".o_field_widget[name='reference'] input");
|
||||
await editInput(target, ".o_field_widget[name='reference'] input", "new partner");
|
||||
assert.containsOnce(
|
||||
target,
|
||||
".ui-autocomplete .o_m2o_dropdown_option",
|
||||
"Dropdown should be opened and have only one item"
|
||||
);
|
||||
assert.hasClass(
|
||||
target.querySelector(".ui-autocomplete .o_m2o_dropdown_option"),
|
||||
"o_m2o_dropdown_option_create_edit"
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("ReferenceField in modal readonly mode", async function (assert) {
|
||||
serverData.models.partner.records[0].p = [2];
|
||||
serverData.models.partner.records[1].trululu = 1;
|
||||
|
||||
Reference in New Issue
Block a user