[feature] Add totals row in report (#2249)

* Fixes issues with old branch

* [fixes] remember totals row option and calculate in the browser if possible
This commit is contained in:
Rushabh Mehta 2016-11-04 13:33:08 +05:30 committed by GitHub
parent 66052b4747
commit 98a7d8e2d0
2 changed files with 76 additions and 9 deletions

View file

@ -13,8 +13,8 @@ from frappe import _
def get():
args = get_form_params()
args.save_list_settings = True
data = compress(execute(**args))
data = compress(execute(**args))
return data
def execute(doctype, *args, **kwargs):
@ -33,6 +33,7 @@ def get_form_params():
if isinstance(data.get("docstatus"), basestring):
data["docstatus"] = json.loads(data["docstatus"])
# queries must always be server side
data.query = None
@ -54,7 +55,6 @@ def compress(data):
"values": values
}
@frappe.whitelist()
def save_report():
"""save report"""
@ -80,13 +80,22 @@ def export_query():
form_params["limit_page_length"] = None
form_params["as_list"] = True
doctype = form_params.doctype
add_totals_row = None
del form_params["doctype"]
if 'add_totals_row' in form_params and form_params['add_totals_row']=='1':
add_totals_row = 1
del form_params["add_totals_row"]
frappe.permissions.can_export(doctype, raise_exception=True)
db_query = DatabaseQuery(doctype)
ret = db_query.execute(**form_params)
if add_totals_row:
ret = append_totals_row(ret)
data = [['Sr'] + get_labels(db_query.fields, doctype)]
for i, row in enumerate(ret):
data.append([i+1] + list(row))
@ -106,6 +115,21 @@ def export_query():
frappe.response['type'] = 'csv'
frappe.response['doctype'] = doctype
def append_totals_row(data):
if not data:
return data
data = list(data)
totals = []
totals.extend([""]*len(data[0]))
for row in data:
for i in xrange(len(row)):
if isinstance(row[i], (float, int)):
totals[i] = (totals[i] or 0) + row[i]
data.append(totals)
return data
def get_labels(fields, doctype):
"""get column labels based on column names"""
labels = []

View file

@ -23,6 +23,7 @@ frappe.views.ReportViewPage = Class.extend({
frappe.model.with_doctype(this.doctype, function() {
me.make_report_view();
if(me.docname) {
frappe.model.with_doc('Report', me.docname, function(r) {
me.parent.reportview.set_columns_and_filters(
JSON.parse(frappe.get_doc("Report", me.docname).json));
@ -87,7 +88,10 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
setup: function() {
var me = this;
this.add_totals_row = 0;
this.page = this.parent.page;
this._body = $('<div>').appendTo(this.page.main);
this.page_title = __('Report')+ ': ' + __(this.docname ? (this.doctype + ' - ' + this.docname) : this.doctype);
this.page.set_title(this.page_title);
this.init_list_settings();
@ -96,15 +100,17 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
method: 'frappe.desk.reportview.get',
save_list_settings: true,
get_args: this.get_args,
parent: this.page.main,
parent: this._body,
start: 0,
show_filters: true,
allow_delete: true,
});
this.make_new_and_refresh();
this.make_delete();
this.make_column_picker();
this.make_sorter();
this.make_totals_row_button();
this.setup_print();
this.make_export();
this.setup_auto_email();
@ -195,6 +201,8 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
// second sort
if(opts.sort_by_next) this.sort_by_next_select.val(opts.sort_by_next);
if(opts.sort_order_next) this.sort_order_next_select.val(opts.sort_order_next);
this.add_totals_row = opts.add_totals_row;
},
set_route_filters: function(first_load) {
@ -233,7 +241,7 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
order_by: this.get_order_by(),
filters: this.filter_list.get_filters(),
save_list_settings_fields: 1,
with_childnames: 1
with_childnames: 1,
}
},
@ -331,6 +339,8 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
var me = this;
var columns = this.get_columns();
this.set_totals_row();
// add sr in data
$.each(this.data, function(i, v) {
// add index
@ -497,9 +507,39 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
make_column_picker: function() {
var me = this;
this.column_picker = new frappe.ui.ColumnPicker(this);
this.page.add_menu_item(__('Pick Columns'), function() {
this.page.add_inner_button(__('Pick Columns'), function() {
me.column_picker.show(me.columns);
}, true);
});
},
make_totals_row_button: function() {
var me = this;
this.page.add_inner_button(__('Show Totals'), function() {
me.add_totals_row = 1 - me.add_totals_row;
me.render_list();
});
},
set_totals_row: function() {
// remove existing totals row
if(this.data.length && this.data[this.data.length-1]._totals_row) {
this.data.pop();
}
if(this.add_totals_row) {
var totals_row = {_totals_row: 1};
if(this.data.length) {
this.data.forEach(function(row, ri) {
$.each(row, function(key, value) {
if($.isNumeric(value)) {
totals_row[key] = (totals_row[key] || 0) + value;
}
});
});
}
this.data.push(totals_row);
}
},
set_tag_and_status_filter: function() {
@ -560,9 +600,9 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
this.sort_order_next_select.val('desc');
// button actions
this.page.add_menu_item(__('Sort By'), function() {
this.page.add_inner_button(__('Set Sort'), function() {
me.sort_dialog.show();
}, true);
});
$(this.sort_dialog.body).find('.btn-primary').click(function() {
me.sort_dialog.hide();
@ -579,6 +619,9 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
var export_btn = this.page.add_menu_item(__('Export'), function() {
var args = me.get_args();
args.cmd = 'frappe.desk.reportview.export_query'
if(me.add_totals_row) {
args.add_totals_row = 1;
}
open_url_post(frappe.request.url, args);
}, true);
},
@ -609,7 +652,7 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
sort_by: me.sort_by_select.val(),
sort_order: me.sort_order_select.val(),
sort_by_next: me.sort_by_next_select.val(),
sort_order_next: me.sort_order_next_select.val()
sort_order_next: me.sort_order_next_select.val(),
})
},
callback: function(r) {