[FIX] web: Correctly unpack groups data in kanban
Before this commit, the groups returned by `web_read_group` were unpacked using the current 'group by' field name, and not the entire 'group by' value (potentially including a granularity for date/datetime fields). This caused mismatches in some cases and the value couldn't be retrieved. Also, a needless 'sum_field' parameter was passed to the 'read_progres_bar' calls, which does not exist in the request API. This commit fixes the first issue and removed the excess parameter. closes odoo/odoo#100149 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
@@ -336,6 +336,18 @@ export class KanbanDynamicGroupList extends DynamicGroupList {
|
||||
});
|
||||
}
|
||||
|
||||
get sumFields() {
|
||||
const { sumField } = this.model.progressAttributes;
|
||||
return sumField ? [sumField.name] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
get fieldNames() {
|
||||
return [...super.fieldNames, ...this.sumFields];
|
||||
}
|
||||
|
||||
/**
|
||||
* After a reload, empty groups are expcted to disappear from the web_read_group.
|
||||
* However, if the parameters are the same (domain + groupBy), we want to
|
||||
@@ -357,24 +369,20 @@ export class KanbanDynamicGroupList extends DynamicGroupList {
|
||||
return;
|
||||
}
|
||||
|
||||
const { fieldName, sumField } = this.model.progressAttributes;
|
||||
const fieldNames = [];
|
||||
const gbFieldName = this.groupByField.name;
|
||||
const promises = {};
|
||||
|
||||
if (withProgressBars) {
|
||||
const domain = Domain.or(groups.map((g) => g.groupDomain)).toList();
|
||||
fieldNames.push(fieldName);
|
||||
promises.readProgressBar = this._fetchProgressData(domain);
|
||||
}
|
||||
// If we have a sumField, the aggregates must be re-fetched
|
||||
if (sumField) {
|
||||
if (this.sumFields.length) {
|
||||
const domain = Domain.or(groups.map((g) => g.getProgressBarDomain())).toList();
|
||||
fieldNames.push(sumField.name);
|
||||
promises.webReadGroup = this.model.orm.webReadGroup(
|
||||
this.resModel,
|
||||
domain,
|
||||
fieldNames,
|
||||
this.sumFields,
|
||||
this.groupBy,
|
||||
{ lazy: true }
|
||||
);
|
||||
@@ -387,9 +395,7 @@ export class KanbanDynamicGroupList extends DynamicGroupList {
|
||||
const result = await promises.webReadGroup;
|
||||
const groupData = result.groups.map((group) => ({
|
||||
...group,
|
||||
[gbFieldName]: Array.isArray(group[gbFieldName])
|
||||
? group[gbFieldName][0]
|
||||
: group[gbFieldName],
|
||||
[gbFieldName]: this._getValueFromGroupData(group, this.firstGroupBy),
|
||||
}));
|
||||
for (const group of groups) {
|
||||
group.updateAggregates(groupData);
|
||||
@@ -485,16 +491,11 @@ export class KanbanDynamicGroupList extends DynamicGroupList {
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
async _fetchProgressData(domain) {
|
||||
const { colors, fieldName, help, sumField } = this.model.progressAttributes;
|
||||
const { colors, fieldName, help } = this.model.progressAttributes;
|
||||
return this.model.orm.call(this.resModel, "read_progress_bar", [], {
|
||||
domain,
|
||||
group_by: this.firstGroupBy,
|
||||
progress_bar: {
|
||||
colors,
|
||||
field: fieldName,
|
||||
help,
|
||||
sum_field: sumField && sumField.name,
|
||||
},
|
||||
progress_bar: { colors, field: fieldName, help },
|
||||
context: this.context,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2297,6 +2297,26 @@ export class DynamicGroupList extends DynamicList {
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} groupData
|
||||
* @param {string} fieldName
|
||||
* @returns {any}
|
||||
*/
|
||||
_getValueFromGroupData(groupData, fieldName) {
|
||||
const field = this.fields[fieldName.split(":")[0]];
|
||||
if (["date", "datetime"].includes(field.type)) {
|
||||
const range = groupData.__range[fieldName];
|
||||
if (!range) {
|
||||
return false;
|
||||
}
|
||||
const dateValue = this._parseServerValue(field, range.to);
|
||||
return dateValue.minus({ [field.type === "date" ? "day" : "second"]: 1 });
|
||||
} else {
|
||||
const value = this._parseServerValue(field, groupData[fieldName]);
|
||||
return Array.isArray(value) ? value[0] : value;
|
||||
}
|
||||
}
|
||||
|
||||
async _loadGroups() {
|
||||
const firstGroupByName = this.firstGroupBy.split(":")[0];
|
||||
const _orderBy = this.orderBy.filter(
|
||||
@@ -2332,14 +2352,7 @@ export class DynamicGroupList extends DynamicList {
|
||||
const value = data[key];
|
||||
switch (key) {
|
||||
case this.firstGroupBy: {
|
||||
if (value && ["date", "datetime"].includes(groupByField.type)) {
|
||||
const dateString = data.__range[this.firstGroupBy].to;
|
||||
const dateValue = this._parseServerValue(groupByField, dateString);
|
||||
const granularity = groupByField.type === "date" ? "day" : "second";
|
||||
groupParams.value = dateValue.minus({ [granularity]: 1 });
|
||||
} else {
|
||||
groupParams.value = Array.isArray(value) ? value[0] : value;
|
||||
}
|
||||
groupParams.value = this._getValueFromGroupData(data, key);
|
||||
if (groupByField.type === "selection") {
|
||||
groupParams.displayName = Object.fromEntries(groupByField.selection)[
|
||||
groupParams.value
|
||||
|
||||
@@ -4666,6 +4666,82 @@ QUnit.module("Views", (hooks) => {
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test("Move record in grouped by date, progress bars and sum field", async (assert) => {
|
||||
serverData.models.partner.records[0].date = "2017-01-08";
|
||||
serverData.models.partner.records[1].date = "2017-01-09";
|
||||
serverData.models.partner.records[2].date = "2017-02-08";
|
||||
serverData.models.partner.records[3].date = "2017-02-10";
|
||||
|
||||
await makeView({
|
||||
type: "kanban",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: /* xml */ `
|
||||
<kanban>
|
||||
<field name="date" allow_group_range_value="true" />
|
||||
<progressbar field="foo" colors='{"yop": "success", "gnap": "warning", "blip": "danger"}' sum_field="int_field" />
|
||||
<templates>
|
||||
<div t-name="kanban-box">
|
||||
<field name="id" />
|
||||
</div>
|
||||
</templates>
|
||||
</kanban>
|
||||
`,
|
||||
groupBy: ["date:month"],
|
||||
});
|
||||
|
||||
assert.containsN(target, ".o_kanban_group", 2);
|
||||
assert.containsN(
|
||||
target,
|
||||
".o_kanban_group:first-child .o_kanban_record",
|
||||
2,
|
||||
"1st column should contain 2 records of January month"
|
||||
);
|
||||
assert.containsN(
|
||||
target,
|
||||
".o_kanban_group:nth-child(2) .o_kanban_record",
|
||||
2,
|
||||
"2nd column should contain 2 records of February month"
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
getProgressBars(0).map((pb) => pb.style.width),
|
||||
["50%", "50%"]
|
||||
);
|
||||
assert.deepEqual(
|
||||
getProgressBars(1).map((pb) => pb.style.width),
|
||||
["50%", "50%"]
|
||||
);
|
||||
assert.deepEqual(getCounters(), ["19", "13"]);
|
||||
|
||||
await dragAndDrop(
|
||||
".o_kanban_group:first-child .o_kanban_record",
|
||||
".o_kanban_group:nth-child(2)"
|
||||
);
|
||||
|
||||
assert.containsOnce(
|
||||
target,
|
||||
".o_kanban_group:first-child .o_kanban_record",
|
||||
"Should only have one record remaining"
|
||||
);
|
||||
assert.containsN(
|
||||
target,
|
||||
".o_kanban_group:nth-child(2) .o_kanban_record",
|
||||
3,
|
||||
"Should now have 3 records"
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
getProgressBars(0).map((pb) => pb.style.width),
|
||||
["100%"]
|
||||
);
|
||||
assert.deepEqual(
|
||||
getProgressBars(1).map((pb) => pb.style.width),
|
||||
["33.3333%", "33.3333%", "33.3333%"] // abridged to e-4
|
||||
);
|
||||
assert.deepEqual(getCounters(), ["9", "23"]);
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"completely prevent drag and drop if records_draggable set to false",
|
||||
async (assert) => {
|
||||
|
||||
Reference in New Issue
Block a user