[FIX] web: SampleServer: many2many in mockReadGroup

closes odoo/odoo#119350

X-original-commit: e63f8206e9658c517743966bb9e24d110fa43508
Signed-off-by: Mathieu Duckerts-Antoine <dam@odoo.com>
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Mathieu Duckerts-Antoine
2023-04-22 05:52:16 +02:00
parent cec7436b8e
commit bf2cc8d7d1
2 changed files with 66 additions and 22 deletions
+50 -22
View File
@@ -9,7 +9,7 @@ import {
} from "@web/core/l10n/dates";
import { ORM } from "@web/core/orm_service";
import { registry } from "@web/core/registry";
import { groupBy as arrayGroupBy, sortBy as arraySortBy } from "@web/core/utils/arrays";
import { cartesian, sortBy as arraySortBy } from "@web/core/utils/arrays";
class UnimplementedRouteError extends Error {}
@@ -207,7 +207,7 @@ export class SampleServer {
if (["date", "datetime"].includes(type)) {
const fmt = SampleServer.FORMATS[interval];
return parseDate(value).toFormat(fmt);
} else if (type === "many2one") {
} else if (["many2one", "many2many"].includes(type)) {
const rec = this.data[relation].records.find(({ id }) => id === value);
return [value, rec.display_name];
} else {
@@ -450,20 +450,42 @@ export class SampleServer {
normalizedGroupBys.push(gb);
}
}
const groups = arrayGroupBy(records, (record) => {
const vals = {};
const groupsFromRecord = (record) => {
const values = [];
for (const gb of normalizedGroupBys) {
const { fieldName, type } = gb;
let value;
let fieldVals;
if (["date", "datetime"].includes(type)) {
value = this._formatValue(record[fieldName], gb);
fieldVals = [this._formatValue(record[fieldName], gb)];
} else if (type === "many2many") {
fieldVals = record[fieldName].length ? record[fieldName] : [false];
} else {
value = record[fieldName];
fieldVals = [record[fieldName]];
}
vals[fieldName] = value;
values.push(fieldVals.map((val) => ({ [fieldName]: val })));
}
return JSON.stringify(vals);
});
const cart = cartesian(...values);
return cart.map((tuple) => {
if (!Array.isArray(tuple)) {
tuple = [tuple];
}
return Object.assign({}, ...tuple);
});
};
const groups = {};
for (const record of records) {
const recordGroups = groupsFromRecord(record);
for (const group of recordGroups) {
const groupId = JSON.stringify(group);
if (!(groupId in groups)) {
groups[groupId] = [];
}
groups[groupId].push(record);
}
}
const measures = [];
for (const measureSpec of params.fields || Object.keys(fields)) {
const matches = measureSpec.match(MEASURE_SPEC_REGEX);
@@ -496,20 +518,26 @@ export class SampleServer {
}
group[countKey] = records.length;
const firstElem = records[0];
const parsedId = JSON.parse(id);
for (const gb of normalizedGroupBys) {
const { alias, fieldName, type } = gb;
group[alias] = this._formatValue(firstElem[fieldName], gb);
if (["date", "datetime"].includes(type)) {
group.__range = {};
const val = firstElem[fieldName];
if (val) {
const deserialize = type === "date" ? deserializeDate : deserializeDateTime;
const serialize = type === "date" ? serializeDate : serializeDateTime;
const from = deserialize(val).startOf(gb.interval);
const to = SampleServer.INTERVALS[gb.interval](from);
group.__range[alias] = { from: serialize(from), to: serialize(to) };
} else {
group.__range[alias] = false;
if (type === "many2many") {
group[alias] = this._formatValue(parsedId[fieldName], gb);
} else {
group[alias] = this._formatValue(firstElem[fieldName], gb);
if (["date", "datetime"].includes(type)) {
group.__range = {};
const val = firstElem[fieldName];
if (val) {
const deserialize =
type === "date" ? deserializeDate : deserializeDateTime;
const serialize = type === "date" ? serializeDate : serializeDateTime;
const from = deserialize(val).startOf(gb.interval);
const to = SampleServer.INTERVALS[gb.interval](from);
group.__range[alias] = { from: serialize(from), to: serialize(to) };
} else {
group.__range[alias] = false;
}
}
}
}
@@ -466,6 +466,22 @@ QUnit.module(
}
);
QUnit.test(
"Send 'read_group' RPC: multiple groupBys among which a many2many",
async function (assert) {
const server = new DeterministicSampleServer("res.users", fields["res.users"]);
const result = await server.mockRpc({
method: "read_group",
model: "res.users",
fields: [],
groupBy: ["height", "tag_ids"],
lazy: false,
});
assert.ok(typeof result[0].tag_ids[0] === "number");
assert.ok(typeof result[0].tag_ids[1] === "string");
}
);
QUnit.test("Send 'read' RPC: no id", async function (assert) {
assert.expect(1);