[FIX] web: introduce parser for many2one_reference field

ISSUE: When in debug mode, user have access to the "External
Identifiers" view. The search bar allows searching using "Record
ID" which is a `many2one_reference` field. When user inputs
a search query that can't be converted to number, "Record ID"
option is still available to the user. It results to traceback
when it's selected because the UI is creating an invalid "domain"
which makes the server search for a string on an integer
(many2one_reference) field.

Check the video for illustration: https://youtu.be/XEPUXHcjeRI

SOLUTION: We make sure that many2one_reference field is properly
converted when generating the domain from the search_bar by
using the integer parser. This basically excludes many2one_reference
field from the search options when the input query is not a valid
integer. See it in action: https://youtu.be/NQ-YrK6tDH0

closes odoo/odoo#104183

Task-id: 3005837
X-original-commit: bc9e8709309379bdd9191323cb015c89be7da1f9
Signed-off-by: Mathieu Duckerts-Antoine <dam@odoo.com>
Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com>
This commit is contained in:
Joseph Caburnay
2022-10-27 11:38:47 +02:00
parent c2536e1f0b
commit bcf2cf7d65
2 changed files with 50 additions and 0 deletions
@@ -199,5 +199,6 @@ registry
.add("float", parseFloat)
.add("float_time", parseFloatTime)
.add("integer", parseInteger)
.add("many2one_reference", parseInteger)
.add("monetary", parseMonetary)
.add("percentage", parsePercentage);
@@ -898,4 +898,53 @@ QUnit.module("Search", (hooks) => {
await triggerEvent(searchInput, null, "keydown", { key: "ArrowUp" });
assert.containsOnce(target, ".focus");
});
QUnit.test("many2one_reference fields are supported in search view", async function (assert) {
serverData.models.partner.fields.res_id = {
string: "Resource ID",
type: "many2one_reference",
};
const controlPanel = await makeWithSearch({
serverData,
resModel: "partner",
Component: ControlPanel,
searchMenuTypes: [],
searchViewId: false,
searchViewArch: /*xml*/ `
<search>
<field name="foo" />
<field name="res_id" />
</search>
`,
});
assert.deepEqual(getDomain(controlPanel), []);
await editSearch(target, "12");
assert.deepEqual(
[...target.querySelectorAll(".o_searchview ul li.dropdown-item")].map(
(el) => el.innerText
),
["Search Foo for: 12", "Search Resource ID for: 12"]
);
await triggerEvent(target.querySelector(".o_searchview input"), null, "keydown", {
key: "ArrowDown",
});
await validateSearch(target);
assert.deepEqual(getDomain(controlPanel), [["res_id", "=", 12]]);
await removeFacet(target);
assert.deepEqual(getDomain(controlPanel), []);
await editSearch(target, "1a");
assert.deepEqual(
[...target.querySelectorAll(".o_searchview ul li.dropdown-item")].map(
(el) => el.innerText
),
["Search Foo for: 1a"]
);
await validateSearch(target);
assert.deepEqual(getDomain(controlPanel), [["foo", "ilike", "1a"]]);
});
});