diff --git a/addons/web/static/src/views/kanban/progress_bar_hook.js b/addons/web/static/src/views/kanban/progress_bar_hook.js
index a6d155cc876..33c53a9cde4 100644
--- a/addons/web/static/src/views/kanban/progress_bar_hook.js
+++ b/addons/web/static/src/views/kanban/progress_bar_hook.js
@@ -30,6 +30,14 @@ function _createFilterDomain(fieldName, bars, value) {
return filterDomain;
}
+function _groupsToAggregateValues(groups, groupBy, fields) {
+ const groupByFieldName = groupBy[0].split(":")[0];
+ return groups.map((g) => {
+ const groupInfo = extractInfoFromGroupData(g, groupBy, fields);
+ return Object.assign(groupInfo.aggregates, { [groupByFieldName]: groupInfo.serverValue });
+ });
+}
+
class ProgressBarState {
constructor(progressAttributes, model, aggregateFields, activeBars = {}) {
this.progressAttributes = progressAttributes;
@@ -185,22 +193,19 @@ class ProgressBarState {
bars,
activeBar.value
);
- const { context, groupBy, resModel } = this.model.root;
+ const { context, fields, groupBy, resModel } = this.model.root;
const kwargs = { context };
- const fieldNames = this._aggregateFields.map((f) => f.name);
- const fields = [...fieldNames, group.groupByField.name];
+ const fieldNames = [...this._aggregateFields.map((f) => f.name), group.groupByField.name];
const domain = filterDomain
? Domain.and([group.groupDomain, filterDomain]).toList()
: group.groupDomain;
return this.model.orm
- .webReadGroup(resModel, domain, fields, groupBy, kwargs)
+ .webReadGroup(resModel, domain, fieldNames, groupBy, kwargs)
.then((res) => {
if (res.length) {
- const resGroup = _findGroup(res.groups, group.groupByField, group.serverValue);
- activeBar.aggregates = {
- ...resGroup,
- [group.groupByField.name]: group.serverValue,
- };
+ const groupByField = group.groupByField;
+ const aggrValues = _groupsToAggregateValues(res.groups, groupBy, fields);
+ activeBar.aggregates = _findGroup(aggrValues, groupByField, group.serverValue);
}
});
}
@@ -239,10 +244,7 @@ class ProgressBarState {
groupBy,
kwargs
);
- this._aggregateValues = res.groups.map((r) => {
- const groupInfo = extractInfoFromGroupData(r, groupBy, fields);
- return { ...groupInfo.aggregates, [firstGroupByName]: groupInfo.serverValue };
- });
+ this._aggregateValues = _groupsToAggregateValues(res.groups, groupBy, fields);
}
async _updateProgressBar() {
diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js
index e22fe96064e..fe7bb8c092a 100644
--- a/addons/web/static/tests/helpers/mock_server.js
+++ b/addons/web/static/tests/helpers/mock_server.js
@@ -1327,6 +1327,9 @@ export class MockServer {
for (const group of groups) {
const records = this.getRecords(modelName, group.__domain || []);
let groupByValue = group[groupBy]; // always technical value here
+ if (Array.isArray(groupByValue)) {
+ groupByValue = groupByValue[1];
+ }
// special case for bool values: rpc call response with capitalized strings
if (!(groupByValue in data)) {
diff --git a/addons/web/static/tests/views/kanban/kanban_view_tests.js b/addons/web/static/tests/views/kanban/kanban_view_tests.js
index 194c5b49e37..206bad364c6 100644
--- a/addons/web/static/tests/views/kanban/kanban_view_tests.js
+++ b/addons/web/static/tests/views/kanban/kanban_view_tests.js
@@ -10417,6 +10417,123 @@ QUnit.module("Views", (hooks) => {
assert.verifySteps(["web_read_group", "read_progress_bar", "web_search_read"]);
});
+ QUnit.test(
+ "progress bar with aggregates: activate bars (grouped by boolean)",
+ async (assert) => {
+ serverData.models.partner.records = [
+ { foo: "yop", bar: true, int_field: 1 },
+ { foo: "yop", bar: true, int_field: 2 },
+ { foo: "blip", bar: true, int_field: 4 },
+ { foo: "gnap", bar: true, int_field: 8 },
+ ];
+
+ await makeView({
+ type: "kanban",
+ resModel: "partner",
+ serverData,
+ arch: `
+
+
+
+
+
+
+
+ `,
+ groupBy: ["bar"],
+ });
+
+ assert.deepEqual(getTooltips(target, 0), ["2 yop", "1 gnap", "1 blip"]);
+ assert.deepEqual(getCounters(target), ["15"]);
+
+ await click(getProgressBars(target, 0)[0]);
+ assert.deepEqual(getCounters(target), ["3"]);
+
+ await click(getProgressBars(target, 0)[2]);
+ assert.deepEqual(getCounters(target), ["4"]);
+
+ await click(getProgressBars(target, 0)[2]);
+ assert.deepEqual(getCounters(target), ["15"]);
+ }
+ );
+
+ QUnit.test(
+ "progress bar with aggregates: activate bars (grouped by many2one)",
+ async (assert) => {
+ serverData.models.partner.records = [
+ { foo: "yop", product_id: 3, int_field: 1 },
+ { foo: "yop", product_id: 3, int_field: 2 },
+ { foo: "blip", product_id: 3, int_field: 4 },
+ { foo: "gnap", product_id: 3, int_field: 8 },
+ ];
+
+ await makeView({
+ type: "kanban",
+ resModel: "partner",
+ serverData,
+ arch: `
+
+
+
+
+
+
+
+ `,
+ groupBy: ["product_id"],
+ });
+
+ assert.deepEqual(getTooltips(target, 0), ["2 yop", "1 gnap", "1 blip"]);
+ assert.deepEqual(getCounters(target), ["15"]);
+
+ await click(getProgressBars(target, 0)[0]);
+ assert.deepEqual(getCounters(target), ["3"]);
+
+ await click(getProgressBars(target, 0)[2]);
+ assert.deepEqual(getCounters(target), ["4"]);
+
+ await click(getProgressBars(target, 0)[2]);
+ assert.deepEqual(getCounters(target), ["15"]);
+ }
+ );
+
+ QUnit.test("progress bar with aggregates: activate bars (grouped by date)", async (assert) => {
+ serverData.models.partner.records = [
+ { foo: "yop", date: "2023-10-08", int_field: 1 },
+ { foo: "yop", date: "2023-10-08", int_field: 2 },
+ { foo: "blip", date: "2023-10-08", int_field: 4 },
+ { foo: "gnap", date: "2023-10-08", int_field: 8 },
+ ];
+
+ await makeView({
+ type: "kanban",
+ resModel: "partner",
+ serverData,
+ arch: `
+
+
+
+
+
+
+
+ `,
+ groupBy: ["date:week"],
+ });
+
+ assert.deepEqual(getTooltips(target, 0), ["2 yop", "1 gnap", "1 blip"]);
+ assert.deepEqual(getCounters(target), ["15"]);
+
+ await click(getProgressBars(target, 0)[0]);
+ assert.deepEqual(getCounters(target), ["3"]);
+
+ await click(getProgressBars(target, 0)[2]);
+ assert.deepEqual(getCounters(target), ["4"]);
+
+ await click(getProgressBars(target, 0)[2]);
+ assert.deepEqual(getCounters(target), ["15"]);
+ });
+
QUnit.test("load more should load correct records after drag&drop event", async (assert) => {
// Add a sequence number and initialize
serverData.models.partner.records.forEach((el, i) => (el.sequence = i));
@@ -13944,7 +14061,7 @@ QUnit.module("Views", (hooks) => {
});
QUnit.test("scroll on group unfold and progressbar click", async (assert) => {
- assert.expect(7);
+ assert.expect(15);
await makeView({
type: "kanban",
@@ -13959,17 +14076,21 @@ QUnit.module("Views", (hooks) => {
`,
groupBy: ["product_id"],
async mockRPC(route, args, performRPC) {
+ assert.step(args.method);
if (args.method === "web_read_group") {
const result = await performRPC(route, args);
if (result.groups.length) {
result.groups[0].__fold = false;
- result.groups[1].__fold = true;
+ if (result.groups[1]) {
+ result.groups[1].__fold = true;
+ }
}
return result;
}
},
});
+ assert.verifySteps(["get_views", "web_read_group", "read_progress_bar", "web_search_read"]);
const content = target.querySelector(".o_content");
content.scrollTo = (params) => {
assert.step("scrolled");
@@ -13977,12 +14098,12 @@ QUnit.module("Views", (hooks) => {
};
await click(getProgressBars(target, 0)[0]);
- assert.verifySteps(["scrolled"]);
+ assert.verifySteps(["web_read_group", "web_search_read", "scrolled"]);
const column1 = getColumn(target, 1);
assert.hasClass(column1, "o_column_folded");
await click(column1);
- assert.verifySteps(["scrolled"]);
+ assert.verifySteps(["web_search_read", "scrolled"]);
});
QUnit.test(