diff --git a/frappe/public/js/frappe/views/reports/query_report.js b/frappe/public/js/frappe/views/reports/query_report.js index d5bc9a05e5..03ccd03ecc 100644 --- a/frappe/public/js/frappe/views/reports/query_report.js +++ b/frappe/public/js/frappe/views/reports/query_report.js @@ -594,6 +594,7 @@ frappe.views.QueryReport = Class.extend({ var me = this; this.dataView.onRowCountChanged.subscribe(function (e, args) { + me.update_totals_row(e, args); me.grid.updateRowCount(); me.grid.render(); }); @@ -603,8 +604,38 @@ frappe.views.QueryReport = Class.extend({ me.grid.render(); }); }, + update_totals_row: function(e, args) { + if(!this.report_doc.add_total_row) return; + + const data_length = this.dataView.getLength(); + const last_index = data_length - 1; + + const number_fields = ['Currency', 'Float', 'Int']; + const fields = this.columns + .filter(col => number_fields.includes(col.fieldtype)) + .map(col => col.field); + + // reset numeric fields + let updated_totals = Object.assign({}, this.dataView.getItem(last_index)); + fields.map(field => { + updated_totals[field] = 0.0; + }); + + // loop all the rows except the last Total row + for (let i = 0; i < data_length - 1; i++) { + const item = this.dataView.getItem(i); + fields.map(field => { + updated_totals[field] += item[field]; + }); + } + this.dataView.updateItem(updated_totals.id, updated_totals); + }, inline_filter: function (item) { var me = frappe.container.page.query_report; + if(me.report_doc.add_total_row) { + // always show totals row + if(Object.values(item).includes("'Total'")) return true; + } for (var columnId in me.columnFilters) { if (columnId !== undefined && me.columnFilters[columnId] !== "") { var c = me.grid.getColumns()[me.grid.getColumnIndex(columnId)]; @@ -774,6 +805,16 @@ frappe.views.QueryReport = Class.extend({ var cols = args.sortCols; me.data.sort(function (dataRow1, dataRow2) { + // Totals row should always be last + if(me.report_doc.add_total_row) { + if(Object.values(dataRow1).includes("'Total'")) { + return 1; + } + if(Object.values(dataRow2).includes("'Total'")) { + return -1; + } + } + for (var i = 0, l = cols.length; i < l; i++) { var field = cols[i].sortCol.field; var sign = cols[i].sortAsc ? 1 : -1;