[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:
parent
66052b4747
commit
98a7d8e2d0
2 changed files with 76 additions and 9 deletions
|
|
@ -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 = []
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue