[FIX] web: compute aggregate value with valid data
The footer of some lists may contain undesirable values (such as `NaN`) To reproduce the issue: 1. Install mrp with demo data 2. In Settings, enable "Work Orders" 3. Open the list view of MOs 4. Group by product Error: The total value for Expected Duration and Real Duration is `NaN:NaN` (The below explanation is about Expected Duration (`production_duration_expected`). This is exactly the same behavior for Real Duration) As defined on the list view, if there are several rows on the list, there must be a sum of all `production_duration_expected`: https://github.com/odoo/odoo/blob/cddbb76e02c3848819ac1f06948b4e7ab8df4bdd/addons/mrp/views/mrp_production_views.xml#L35 This is correctly working when consulting a standard list of MOs (step 3). However, this is different when using the Group-By feature. When rendering the list, at some point, `_computeColumnAggregates` is called to compute the sum of all `production_duration_expected`: https://github.com/odoo/odoo/blob/4e213f0b93f59cf377271b18eae9765ff9cfbe4f/addons/web/static/src/legacy/js/views/list/list_renderer.js#L178-L185 Here is the issue: the rows in the list `data` are not records (there are results of `read_group`) and these rows don't have any aggregate value for `production_duration_expected`, which means that `d.aggregateValues[attrs.name]` returns `undefined`. As a result, when performing the sum of `0` and `undefined`, it gives `NaN`. Some detailed explanations: `aggregateValues` is completed when processing the result of the `read_group` RPC: https://github.com/odoo/odoo/blob/bc79a329a1e1edf964f97886943c0688db2087fd/addons/web/static/src/legacy/js/views/basic/basic_model.js#L4697-L4703 However, on PY-side, `read_group` doesn't provide any value for `production_duration_expected`. For a `read_group` to provide some aggregate values, it needs the field to be stored and the `group_operator` attribute to be defined on this field: https://github.com/odoo/odoo/blob/5691b126f06c2b200ae507bd6edd8f8f7e68d5f5/odoo/models.py#L2521-L2528 Except that none of the conditions are met: https://github.com/odoo/odoo/blob/d584ad282178deb40bb036c48f971617b0a41f88/addons/mrp/models/mrp_production.py#L147 OPW-2735181 closes odoo/odoo#84035 X-original-commit: 8bc1c582b626aedb680d59f858c92db9dfe4f357 Signed-off-by: Simon Genin (ges@odoo) <ges@odoo.com>
This commit is contained in:
@@ -176,8 +176,11 @@ var ListRenderer = BasicRenderer.extend({
|
||||
aggregateValue = Infinity;
|
||||
}
|
||||
_.each(data, function (d) {
|
||||
count += 1;
|
||||
var value = (d.type === 'record') ? d.data[attrs.name] : d.aggregateValues[attrs.name];
|
||||
if (Number(value) !== value) {
|
||||
return;
|
||||
}
|
||||
count += 1;
|
||||
if (func === 'avg') {
|
||||
aggregateValue += value;
|
||||
} else if (func === 'sum') {
|
||||
@@ -191,10 +194,14 @@ var ListRenderer = BasicRenderer.extend({
|
||||
if (func === 'avg') {
|
||||
aggregateValue = count ? aggregateValue / count : aggregateValue;
|
||||
}
|
||||
column.aggregate = {
|
||||
help: attrs[func],
|
||||
value: aggregateValue,
|
||||
};
|
||||
if (count) {
|
||||
column.aggregate = {
|
||||
help: attrs[func],
|
||||
value: aggregateValue,
|
||||
};
|
||||
} else {
|
||||
delete column.aggregate;
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -2405,7 +2405,7 @@ QUnit.module('Views', {
|
||||
|
||||
// Let's update the view to dislay NO records
|
||||
await list.update({domain: ['&', ['bar', '=', false], ['int_field', '>', 0]]});
|
||||
assert.strictEqual(list.$('tfoot td:nth(2)').text(), "0", "total should have been recomputed to 0");
|
||||
assert.strictEqual(list.$('tfoot td:nth(2)').text(), "", "No records, so no total.");
|
||||
|
||||
list.destroy();
|
||||
});
|
||||
@@ -2438,6 +2438,34 @@ QUnit.module('Views', {
|
||||
list.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('hide aggregated value in grouped lists when no data provided by RPC call', async function(assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var list = await createView({
|
||||
View: ListView,
|
||||
model: 'foo',
|
||||
data: this.data,
|
||||
groupBy: ['bar'],
|
||||
arch: '<tree editable="bottom"><field name="foo"/><field name="qux" widget="float_time" sum="Sum"/></tree>',
|
||||
mockRPC: function (route, args) {
|
||||
return this._super.apply(this, arguments).then(result => {
|
||||
// On PY-side, a read_group won't provide any aggregate value
|
||||
// if the field does not have a `group_operator` attribute.
|
||||
// (see 5691b126f06/odoo/models.py#L2521-L2528)
|
||||
// Here, since `qux` does not have such an attribute, we
|
||||
// remove the value provided by `_mockReadGroup`
|
||||
_.each(result.groups, function(group) {
|
||||
delete group.qux
|
||||
})
|
||||
return Promise.resolve(result)
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(list.$('tfoot td:nth(2)').text(), "", "There isn't any aggregated value");
|
||||
list.destroy();
|
||||
})
|
||||
|
||||
QUnit.test('aggregates are updated when a line is edited', async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user