[FIX] web: handle field sorting should include id
Since commit 7d2baaa0c7 ("Unity read"), we are able to
pass a full specification to subfields in a view and retrive records directly according to that
specification. This could include "order".
In the case of a list view that has a `widget="handle"`, this order is automatically set to "[handle_field] ASC".
Before the unity read feature, it did not cause problems for one2manys because the ids of records were retrieved in python
using the "natural order" of the model (the `model._order` slot), which usually had the right parameters.
(see `sale.order.line` for example). When fetching the ids of the one2many, those were already sorted in natural order.
In unity read, the natural order is overriden by the specification and became only "[handle_field] ASC". This was insufficient
as more often than not, sequences on model are set up with a default. So eventually, all records couls have the same sequence.
The sorting in SQL becomes undeterminate.
After this commit, we had the sorting key "id ASC" to avoid any unwanted results.
opw-3790378
see discord https://discord.com/channels/678381219515465750/687338039717920792/1231977078564585555 for a detailed discussion.
closes odoo/odoo#162933
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
This commit is contained in:
@@ -226,7 +226,8 @@ export class ListArchParser {
|
||||
});
|
||||
|
||||
if (!treeAttr.defaultOrder.length && handleField) {
|
||||
treeAttr.defaultOrder = stringToOrderBy(handleField);
|
||||
const handleFieldSort = `${handleField}, id`;
|
||||
treeAttr.defaultOrder = stringToOrderBy(handleFieldSort);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -2678,6 +2678,31 @@ QUnit.module("Fields", (hooks) => {
|
||||
]);
|
||||
});
|
||||
|
||||
QUnit.test("one2many list order with handle widget", async (assert) => {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="p">
|
||||
<tree editable="top">
|
||||
<field name="int_field" widget="handle"/>
|
||||
<field name="foo"/>
|
||||
</tree>
|
||||
</field>
|
||||
</form>`,
|
||||
resId: 1,
|
||||
mockRPC(route, args) {
|
||||
if (args.method === "web_read") {
|
||||
assert.step(`web_read`);
|
||||
assert.strictEqual(args.kwargs.specification.p.order, "int_field ASC, id ASC");
|
||||
}
|
||||
},
|
||||
});
|
||||
assert.verifySteps(["web_read"]);
|
||||
});
|
||||
|
||||
QUnit.test("one2many field when using the pager", async function (assert) {
|
||||
const ids = [];
|
||||
for (let i = 0; i < 45; i++) {
|
||||
|
||||
@@ -10824,7 +10824,7 @@ QUnit.module("Views", (hooks) => {
|
||||
});
|
||||
|
||||
QUnit.test("list with handle widget", async function (assert) {
|
||||
assert.expect(11);
|
||||
assert.expect(13);
|
||||
|
||||
await makeView({
|
||||
type: "list",
|
||||
@@ -10836,6 +10836,9 @@ QUnit.module("Views", (hooks) => {
|
||||
<field name="amount" widget="float" digits="[5,0]"/>
|
||||
</tree>`,
|
||||
mockRPC(route, args) {
|
||||
if (args.method === "web_search_read") {
|
||||
assert.step(`web_search_read: order: ${args.kwargs.order}`);
|
||||
}
|
||||
if (route === "/web/dataset/resequence") {
|
||||
assert.strictEqual(
|
||||
args.offset,
|
||||
@@ -10857,6 +10860,7 @@ QUnit.module("Views", (hooks) => {
|
||||
},
|
||||
});
|
||||
|
||||
assert.verifySteps(["web_search_read: order: int_field ASC, id ASC"]);
|
||||
let rows = target.querySelectorAll(".o_data_row");
|
||||
assert.strictEqual(
|
||||
rows[0].querySelector("[name='amount']").textContent,
|
||||
|
||||
Reference in New Issue
Block a user