Merge pull request #9587 from prssanna/aggregate-on-group-by
feat(Reports): Allow child table fields in aggregate on
This commit is contained in:
commit
869fd37c0b
2 changed files with 48 additions and 26 deletions
|
|
@ -25,7 +25,7 @@ frappe.ui.GroupBy = class {
|
|||
this.groupby_select = this.groupby_edit_area.find('select.groupby');
|
||||
this.aggregate_function_select = this.groupby_edit_area.find('select.aggregate-function');
|
||||
this.aggregate_on_select = this.groupby_edit_area.find('select.aggregate-on');
|
||||
|
||||
this.aggregate_on_html = ``;
|
||||
// set default to count
|
||||
this.aggregate_function_select.val("count");
|
||||
this.page.wrapper.find(".frappe-list").append(
|
||||
|
|
@ -51,21 +51,32 @@ frappe.ui.GroupBy = class {
|
|||
}
|
||||
|
||||
show_hide_aggregate_on() {
|
||||
this.report_view.meta.fields.forEach((field) => {
|
||||
let fn = this.aggregate_function_select.val();
|
||||
if(fn === 'sum' || fn === 'avg') {
|
||||
// pick numeric fields for sum / avg
|
||||
if(frappe.model.is_numeric_field(field.fieldtype)) {
|
||||
this.aggregate_on_select.append(
|
||||
$('<option>', { value : field.fieldname })
|
||||
.text(field.label));
|
||||
let fn = this.aggregate_function_select.val();
|
||||
if (fn === 'sum' || fn === 'avg') {
|
||||
if (!this.aggregate_on_html.length) {
|
||||
this.aggregate_on_html = `<option value="" disabled selected>
|
||||
${__("Select Field...")}</option>`;
|
||||
|
||||
for (let doctype in this.all_fields) {
|
||||
const doctype_fields = this.all_fields[doctype];
|
||||
doctype_fields.forEach(field => {
|
||||
// pick numeric fields for sum / avg
|
||||
if (frappe.model.is_numeric_field(field.fieldtype)) {
|
||||
let option_text = doctype == this.doctype
|
||||
? field.label
|
||||
: `${field.label} (${doctype})`;
|
||||
this.aggregate_on_html+= `<option data-doctype="${doctype}"
|
||||
value="${field.fieldname}">${option_text}</option>`;
|
||||
}
|
||||
});
|
||||
}
|
||||
this.aggregate_on_select.show();
|
||||
} else {
|
||||
// count, so no aggregate function
|
||||
this.aggregate_on_select.hide();
|
||||
}
|
||||
});
|
||||
this.aggregate_on_select.html(this.aggregate_on_html);
|
||||
this.aggregate_on_select.show();
|
||||
} else {
|
||||
// count, so no aggregate function
|
||||
this.aggregate_on_select.hide();
|
||||
}
|
||||
}
|
||||
|
||||
get_settings() {
|
||||
|
|
@ -114,8 +125,10 @@ frappe.ui.GroupBy = class {
|
|||
|
||||
if (this.aggregate_function === 'count') {
|
||||
this.aggregate_on = 'name';
|
||||
this.aggregate_on_doctype = null;
|
||||
} else {
|
||||
this.aggregate_on = this.aggregate_on_select.val();
|
||||
this.aggregate_on_doctype = this.aggregate_on_select.find(':selected').attr('data-doctype');
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -143,11 +156,13 @@ frappe.ui.GroupBy = class {
|
|||
|
||||
set_args(args) {
|
||||
if (this.aggregate_function && this.group_by) {
|
||||
let aggregate_column;
|
||||
if(this.aggregate_function === 'count') {
|
||||
let aggregate_column, aggregate_on_field;
|
||||
if (this.aggregate_function === 'count') {
|
||||
aggregate_column = 'count(`tab'+ this.doctype + '`.`name`)';
|
||||
} else {
|
||||
aggregate_column = `${this.aggregate_function}(\`tab${this.doctype}\`.\`${this.aggregate_on}\`)`;
|
||||
aggregate_column =
|
||||
`${this.aggregate_function}(\`tab${this.aggregate_on_doctype}\`.\`${this.aggregate_on}\`)`;
|
||||
aggregate_on_field = '`tab' + this.aggregate_on_doctype + '`.`' + this.aggregate_on + '`';
|
||||
}
|
||||
|
||||
this.report_view.group_by = this.group_by;
|
||||
|
|
@ -166,10 +181,14 @@ frappe.ui.GroupBy = class {
|
|||
// rebuild fields for group by
|
||||
args.fields = this.report_view.get_fields();
|
||||
|
||||
// add aggregate column in both query args and report view
|
||||
this.report_view.fields.push(['_aggregate_column', this.doctype]);
|
||||
// add aggregate column in both query args and report views
|
||||
this.report_view.fields.push(['_aggregate_column', this.aggregate_on_doctype || this.doctype]);
|
||||
args.fields.push(aggregate_column + ' as _aggregate_column');
|
||||
|
||||
if (aggregate_on_field) {
|
||||
args.fields.push(aggregate_on_field);
|
||||
}
|
||||
|
||||
// setup columns in datatable
|
||||
this.report_view.setup_columns();
|
||||
|
||||
|
|
@ -195,7 +214,7 @@ frappe.ui.GroupBy = class {
|
|||
};
|
||||
} else {
|
||||
// get properties of "aggregate_on", for example Net Total
|
||||
docfield = Object.assign({}, frappe.meta.docfield_map[this.doctype][this.aggregate_on]);
|
||||
docfield = Object.assign({}, frappe.meta.docfield_map[this.aggregate_on_doctype][this.aggregate_on]);
|
||||
if (this.aggregate_function === 'sum') {
|
||||
docfield.label = __('Sum of {0}', [docfield.label]);
|
||||
} else {
|
||||
|
|
@ -230,9 +249,12 @@ frappe.ui.GroupBy = class {
|
|||
}
|
||||
|
||||
get_group_by_fields() {
|
||||
let group_by_fields = {};
|
||||
this.group_by_fields = {};
|
||||
this.all_fields = {};
|
||||
|
||||
let fields = this.report_view.meta.fields.filter(f => ["Select", "Link", "Data", "Int"].includes(f.fieldtype));
|
||||
group_by_fields[this.doctype] = fields;
|
||||
this.group_by_fields[this.doctype] = fields;
|
||||
this.all_fields[this.doctype] = this.report_view.meta.fields;
|
||||
|
||||
const standard_fields_filter = df =>
|
||||
!in_list(frappe.model.no_value_type, df.fieldtype) && !df.report_hide;
|
||||
|
|
@ -243,10 +265,10 @@ frappe.ui.GroupBy = class {
|
|||
table_fields.forEach(df => {
|
||||
const cdt = df.options;
|
||||
const child_table_fields = frappe.meta.get_docfields(cdt).filter(standard_fields_filter);
|
||||
group_by_fields[cdt] = child_table_fields;
|
||||
this.group_by_fields[cdt] = child_table_fields;
|
||||
this.all_fields[cdt] = child_table_fields;
|
||||
});
|
||||
|
||||
return group_by_fields;
|
||||
return this.group_by_fields;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1035,7 +1035,7 @@ frappe.views.ReportView = class ReportView extends frappe.views.ListView {
|
|||
return {
|
||||
name: name,
|
||||
doctype: col.docfield.parent,
|
||||
content: d[cdt_field(col.field)],
|
||||
content: d[cdt_field(col.field)] || d[col.field],
|
||||
editable: Boolean(name && this.is_editable(col.docfield, d)),
|
||||
format: value => {
|
||||
return frappe.format(value, col.docfield, { always_show_decimals: true }, d);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue