@@ -137,6 +137,7 @@ | |||||
"lib/js/wn/views/doclistview.js", | "lib/js/wn/views/doclistview.js", | ||||
"lib/js/wn/views/formview.js", | "lib/js/wn/views/formview.js", | ||||
"lib/js/wn/views/reportview.js", | "lib/js/wn/views/reportview.js", | ||||
"lib/js/wn/views/grid_report.js", | |||||
"lib/js/legacy/widgets/dialog.js", | "lib/js/legacy/widgets/dialog.js", | ||||
"lib/js/legacy/widgets/layout.js", | "lib/js/legacy/widgets/layout.js", | ||||
"lib/js/legacy/widgets/tabbedpage.js", | "lib/js/legacy/widgets/tabbedpage.js", | ||||
@@ -95,7 +95,7 @@ | |||||
margin-top: 1px; | margin-top: 1px; | ||||
} | } | ||||
.btn-small { | .btn-small { | ||||
padding: 5px 9px; | |||||
padding: 4px 9px; | |||||
font-size: 11px; | font-size: 11px; | ||||
line-height: 16px; | line-height: 16px; | ||||
} | } | ||||
@@ -54,7 +54,7 @@ return cookies[c];} | |||||
wn.dom.set_box_shadow=function(ele,spread){$(ele).css('-moz-box-shadow','0px 0px '+spread+'px rgba(0,0,0,0.3);') | wn.dom.set_box_shadow=function(ele,spread){$(ele).css('-moz-box-shadow','0px 0px '+spread+'px rgba(0,0,0,0.3);') | ||||
$(ele).css('-webkit-box-shadow','0px 0px '+spread+'px rgba(0,0,0,0.3);') | $(ele).css('-webkit-box-shadow','0px 0px '+spread+'px rgba(0,0,0,0.3);') | ||||
$(ele).css('-box-shadow','0px 0px '+spread+'px rgba(0,0,0,0.3);')};(function($){$.fn.add_options=function(options_list){for(var i=0;i<options_list.length;i++){var v=options_list[i];value=v.value||v;label=v.label||v;$('<option>').html(label).attr('value',value).appendTo(this);} | $(ele).css('-box-shadow','0px 0px '+spread+'px rgba(0,0,0,0.3);')};(function($){$.fn.add_options=function(options_list){for(var i=0;i<options_list.length;i++){var v=options_list[i];value=v.value||v;label=v.label||v;$('<option>').html(label).attr('value',value).appendTo(this);} | ||||
return $(this).val(options_list[0].value||options_list[0]);} | |||||
this.selectedIndex=0;return $(this);} | |||||
$.fn.set_working=function(){var ele=this.get(0);$(ele).attr('disabled','disabled');if(ele.loading_img){$(ele.loading_img).toggle(true);}else{ele.loading_img=$('<img src="images/lib/ui/button-load.gif" \ | $.fn.set_working=function(){var ele=this.get(0);$(ele).attr('disabled','disabled');if(ele.loading_img){$(ele.loading_img).toggle(true);}else{ele.loading_img=$('<img src="images/lib/ui/button-load.gif" \ | ||||
style="margin-left: 4px; margin-bottom: -2px; display: inline;" />').insertAfter(ele);}} | style="margin-left: 4px; margin-bottom: -2px; display: inline;" />').insertAfter(ele);}} | ||||
$.fn.done_working=function(){var ele=this.get(0);$(ele).attr('disabled',null);if(ele.loading_img){$(ele.loading_img).toggle(false);};}})(jQuery); | $.fn.done_working=function(){var ele=this.get(0);$(ele).attr('disabled',null);if(ele.loading_img){$(ele.loading_img).toggle(false);};}})(jQuery); | ||||
@@ -278,4 +278,4 @@ wn.request.call({args:args,success:opts.callback,error:opts.error,btn:opts.btn,f | |||||
* lib/js/core.js | * lib/js/core.js | ||||
*/ | */ | ||||
if(!console){var console={log:function(txt){}}} | if(!console){var console={log:function(txt){}}} | ||||
window._version_number="031a31bad930de7f9e8157242afbcba4729d91ff9f957c0c897cafd6";$(document).ready(function(){wn.assets.check();wn.provide('wn.app');$.extend(wn.app,new wn.Application());}); | |||||
window._version_number="820949d75a1ddbb59843ce9171e6c532b5f5e6650784839c2a66d84a";$(document).ready(function(){wn.assets.check();wn.provide('wn.app');$.extend(wn.app,new wn.Application());}); |
@@ -139,7 +139,8 @@ wn.dom.set_box_shadow = function(ele, spread) { | |||||
$('<option>').html(label).attr('value', value).appendTo(this); | $('<option>').html(label).attr('value', value).appendTo(this); | ||||
} | } | ||||
// select the first option | // select the first option | ||||
return $(this).val(options_list[0].value || options_list[0]); | |||||
this.selectedIndex = 0; | |||||
return $(this); | |||||
} | } | ||||
$.fn.set_working = function() { | $.fn.set_working = function() { | ||||
var ele = this.get(0); | var ele = this.get(0); | ||||
@@ -39,19 +39,19 @@ wn.ui.AppFrame = Class.extend({ | |||||
this.$w.append('<div class="appframe-toolbar"></div>'); | this.$w.append('<div class="appframe-toolbar"></div>'); | ||||
this.toolbar = this.$w.find('.appframe-toolbar'); | this.toolbar = this.$w.find('.appframe-toolbar'); | ||||
}, | }, | ||||
add_label: function(label) { | |||||
return $("<span style='margin: 2px 4px;'>"+label+" </span>").appendTo(this.toolbar); | |||||
}, | |||||
add_select: function(label, options) { | add_select: function(label, options) { | ||||
this.add_toolbar(); | this.add_toolbar(); | ||||
return $("<select style='width: 160px;'>").add_options(options).appendTo(this.add_label(label)); | |||||
}, | |||||
add_label: function(label) { | |||||
return $("<span style='margin-right: 12px;'>"+label+" </span>").appendTo(this.toolbar); | |||||
return $("<select style='width: 160px; margin: 2px 4px;'>").add_options(options).appendTo(this.toolbar); | |||||
}, | }, | ||||
add_date: function(label, date) { | add_date: function(label, date) { | ||||
this.add_toolbar(); | this.add_toolbar(); | ||||
return $("<input style='width: 80px;'>").datepicker({ | |||||
return $("<input style='width: 80px; margin: 2px 4px;'>").datepicker({ | |||||
dateFormat: sys_defaults.date_format.replace("yyyy", "yy"), | dateFormat: sys_defaults.date_format.replace("yyyy", "yy"), | ||||
changeYear: true, | changeYear: true, | ||||
}).val(dateutil.str_to_user(date) || "").appendTo(this.add_label(label)); | |||||
}).val(dateutil.str_to_user(date) || "").appendTo(this.toolbar); | |||||
}, | }, | ||||
}); | }); | ||||
@@ -0,0 +1,171 @@ | |||||
// Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com) | |||||
// | |||||
// MIT License (MIT) | |||||
// | |||||
// Permission is hereby granted, free of charge, to any person obtaining a | |||||
// copy of this software and associated documentation files (the "Software"), | |||||
// to deal in the Software without restriction, including without limitation | |||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
// and/or sell copies of the Software, and to permit persons to whom the | |||||
// Software is furnished to do so, subject to the following conditions: | |||||
// | |||||
// The above copyright notice and this permission notice shall be included in | |||||
// all copies or substantial portions of the Software. | |||||
// | |||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |||||
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |||||
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | |||||
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
// | |||||
wn.provide("wn.report_dump"); | |||||
$.extend(wn.report_dump, { | |||||
data: {}, | |||||
with_data: function(doctypes, callback) { | |||||
var missing = []; | |||||
$.each(doctypes, function(i, v) { | |||||
if(!wn.report_dump.data[v]) missing.push(v); | |||||
}) | |||||
if(missing.length) { | |||||
wn.call({ | |||||
method: "webnotes.widgets.report_dump.get_data", | |||||
args: {doctypes: missing}, | |||||
callback: function(r) { | |||||
// creating map of data from a list | |||||
$.each(r.message, function(doctype, doctype_data) { | |||||
var data = []; | |||||
$.each(doctype_data.data, function(i, d) { | |||||
var row = {}; | |||||
$.each(doctype_data.columns, function(idx, col) { | |||||
row[col] = d[idx]; | |||||
}); | |||||
row.id = doctype + "-" + i; | |||||
data.push(row); | |||||
}); | |||||
wn.report_dump.data[doctype] = data; | |||||
}); | |||||
callback(); | |||||
} | |||||
}) | |||||
} else { | |||||
callback(); | |||||
} | |||||
} | |||||
}); | |||||
wn.provide("wn.views"); | |||||
wn.views.GridReport = Class.extend({ | |||||
init: function(opts) { | |||||
this.filter_inputs = {}; | |||||
$.extend(this, opts); | |||||
this.wrapper = $("<div style='height: 500px; border: 1px solid #aaa;'>").appendTo(this.parent); | |||||
this.id = wn.dom.set_unique_id(this.wrapper.get(0)); | |||||
if(this.filters) { | |||||
this.make_filters(); | |||||
} | |||||
this.make_waiting(); | |||||
this.import_slickgrid(); | |||||
var me = this; | |||||
this.get_data(); | |||||
wn.cur_grid_report = this; | |||||
}, | |||||
get_data: function() { | |||||
var me = this; | |||||
wn.report_dump.with_data(this.doctypes, function() { | |||||
// setup filters | |||||
$.each(me.filter_inputs, function(i, v) { | |||||
var opts = v.get(0).opts; | |||||
if (opts.fieldtype == "Select" && inList(me.doctypes, opts.options)) { | |||||
$(v).add_options($.map(wn.report_dump.data[opts.options], function(d) { | |||||
return d.name; | |||||
})); | |||||
} | |||||
}); | |||||
me.setup(); | |||||
me.refresh(); | |||||
}); | |||||
}, | |||||
make_waiting: function() { | |||||
$('<div class="well" style="width: 63%; margin: 30px auto;">\ | |||||
<p style="text-align: center;">Loading Report...</p>\ | |||||
<div class="progress progress-striped active">\ | |||||
<div class="bar" style="width: 100%"></div></div>') | |||||
.appendTo(this.wrapper); | |||||
}, | |||||
load_filters: function(callback) { | |||||
// override | |||||
callback(); | |||||
}, | |||||
make_filters: function() { | |||||
var me = this; | |||||
$.each(this.filters, function(i, v) { | |||||
v.fieldname = v.fieldname || v.label.replace(/ /g, '_').toLowerCase(); | |||||
var input = null; | |||||
if(v.fieldtype=='Select') { | |||||
input = me.appframe.add_select(v.label, ["Select "+v.options]); | |||||
} else if(v.fieldtype=='Button') { | |||||
input = me.appframe.add_button(v.label); | |||||
} else if(v.fieldtype=='Date') { | |||||
input = me.appframe.add_date(v.label); | |||||
} else if(v.fieldtype=='Label') { | |||||
input = me.appframe.add_label(v.label); | |||||
} | |||||
input && (input.get(0).opts = v); | |||||
me.filter_inputs[v.fieldname] = input; | |||||
}); | |||||
}, | |||||
import_slickgrid: function() { | |||||
wn.require('js/lib/slickgrid/slick.grid.css'); | |||||
wn.require('js/lib/slickgrid/slick-default-theme.css'); | |||||
wn.require('js/lib/slickgrid/jquery.event.drag.min.js'); | |||||
wn.require('js/lib/slickgrid/slick.core.js'); | |||||
wn.require('js/lib/slickgrid/slick.grid.js'); | |||||
wn.require('js/lib/slickgrid/slick.dataview.js'); | |||||
wn.dom.set_style('.slick-cell { font-size: 12px; }'); | |||||
}, | |||||
refresh: function() { | |||||
this.prepare_data(); | |||||
this.render(); | |||||
}, | |||||
render: function() { | |||||
// new slick grid | |||||
this.grid = new Slick.Grid("#"+this.id, this.dataView, this.columns, this.options); | |||||
// bind events | |||||
this.dataView.onRowsChanged.subscribe(function (e, args) { | |||||
grid.invalidateRows(args.rows); | |||||
grid.render(); | |||||
}); | |||||
this.dataView.onRowCountChanged.subscribe(function (e, args) { | |||||
grid.updateRowCount(); | |||||
grid.render(); | |||||
}); | |||||
}, | |||||
prepare_data_view: function(items) { | |||||
// initialize the model | |||||
this.dataView = new Slick.Data.DataView({ inlineFilters: true }); | |||||
this.dataView.beginUpdate(); | |||||
this.dataView.setItems(items); | |||||
this.dataView.setFilter(this.dataview_filter); | |||||
this.dataView.endUpdate(); | |||||
}, | |||||
options: { | |||||
editable: false, | |||||
enableColumnReorder: false | |||||
}, | |||||
dataview_filter: function(item) { | |||||
return true; | |||||
}, | |||||
date_formatter: function(row, cell, value, columnDef, dataContext) { | |||||
return dateutil.str_to_user(value); | |||||
}, | |||||
currency_formatter: function(row, cell, value, columnDef, dataContext) { | |||||
return "<div style='text-align: right;'>" + fmt_money(value) + "</div>"; | |||||
} | |||||
}) |
@@ -0,0 +1,45 @@ | |||||
# Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com) | |||||
# | |||||
# MIT License (MIT) | |||||
# | |||||
# Permission is hereby granted, free of charge, to any person obtaining a | |||||
# copy of this software and associated documentation files (the "Software"), | |||||
# to deal in the Software without restriction, including without limitation | |||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
# and/or sell copies of the Software, and to permit persons to whom the | |||||
# Software is furnished to do so, subject to the following conditions: | |||||
# | |||||
# The above copyright notice and this permission notice shall be included in | |||||
# all copies or substantial portions of the Software. | |||||
# | |||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |||||
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |||||
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |||||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | |||||
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
# | |||||
import webnotes | |||||
import json | |||||
@webnotes.whitelist() | |||||
def get_data(): | |||||
from startup.report_data_map import data_map | |||||
doctypes = json.loads(webnotes.form_dict.get("doctypes")) | |||||
out = {} | |||||
for d in doctypes: | |||||
args = data_map[d] | |||||
conditions = order_by = "" | |||||
if args.get("conditions"): | |||||
conditions = " where " + " and ".join(args["conditions"]) | |||||
if args.get("order by"): | |||||
order_by = " order by " + args["order_by"] | |||||
out[d] = {} | |||||
out[d]["data"] = webnotes.conn.sql("""select %s from `tab%s` %s %s""" % (",".join(args["columns"]), | |||||
d, conditions, order_by), as_list=1) | |||||
out[d]["columns"] = map(lambda c: c.split(" as ")[-1], args["columns"]) | |||||
return out |