added stock analytics
diff --git a/erpnext/accounts/page/financial_analytics/financial_analytics.js b/erpnext/accounts/page/financial_analytics/financial_analytics.js
index 5445fc9..1f0a01d 100644
--- a/erpnext/accounts/page/financial_analytics/financial_analytics.js
+++ b/erpnext/accounts/page/financial_analytics/financial_analytics.js
@@ -15,7 +15,6 @@
 // along with this program.	If not, see <http://www.gnu.org/licenses/>.
 
 wn.require("js/app/account_tree_grid.js");
-wn.require("js/app/account_tree_grid.css");
 
 wn.pages['financial-analytics'].onload = function(wrapper) { 
 	wn.ui.make_app_page({
@@ -57,80 +56,13 @@
 			{id: "check", name: "Plot", field: "check", width: 30,
 				formatter: this.check_formatter},
 			{id: "name", name: "Account", field: "name", width: 300,
-				formatter: this.account_formatter},
+				formatter: this.tree_formatter},
 			{id: "opening", name: "Opening", field: "opening", hidden: true,
 				formatter: this.currency_formatter}
 		];
-		this.columns = [];
 		
-		var me = this;
-		var range = this.filter_inputs.range.val();
-		this.from_date = dateutil.user_to_str(this.filter_inputs.from_date.val());
-		this.to_date = dateutil.user_to_str(this.filter_inputs.to_date.val());
-		var date_diff = dateutil.get_diff(this.to_date, this.from_date);
-			
-		me.column_map = {};
-		
-		var add_column = function(date) {
-			me.columns.push({
-				id: date,
-				name: dateutil.str_to_user(date),
-				field: date,
-				formatter: me.currency_formatter,
-				width: 100
-			});
-		}
-		
-		var build_columns = function(condition) {
-			// add column for each date range
-			for(var i=0; i < date_diff; i++) {
-				var date = dateutil.add_days(me.from_date, i);
-				if(!condition) condition = function() { return true; }
-				
-				if(condition(date)) add_column(date);
-				me.last_date = date;
-				
-				if(me.columns.length) {
-					me.column_map[date] = me.columns[me.columns.length-1];
-				}
-			}
-		}
-		
-		// make columns for all date ranges
-		if(range=='Daily') {
-			build_columns();
-		} else if(range=='Weekly') {
-			build_columns(function(date) {
-				if(!me.last_date) return true;
-				return !(dateutil.get_diff(date, me.from_date) % 7)
-			});		
-		} else if(range=='Monthly') {
-			build_columns(function(date) {
-				if(!me.last_date) return true;
-				return dateutil.str_to_obj(me.last_date).getMonth() != dateutil.str_to_obj(date).getMonth()
-			});
-		} else if(range=='Quarterly') {
-			build_columns(function(date) {
-				if(!me.last_date) return true;
-				return dateutil.str_to_obj(date).getDate()==1 && in_list([0,3,6,9], dateutil.str_to_obj(date).getMonth())
-			});			
-		} else if(range=='Yearly') {
-			build_columns(function(date) {
-				if(!me.last_date) return true;
-				return $.map(wn.report_dump.data['Fiscal Year'], function(v) { 
-						return date==v.year_start_date ? true : null;
-					}).length;
-			});
-		}
-		
-		// set label as last date of period
-		$.each(this.columns, function(i, col) {
-			col.name = me.columns[i+1]
-				? dateutil.str_to_user(dateutil.add_days(me.columns[i+1].id, -1))
-				: dateutil.str_to_user(me.to_date);				
-		});
-		
-		me.columns = std_columns.concat(me.columns);
+		this.make_date_range_columns();		
+		this.columns = std_columns.concat(this.columns);
 	},
 	setup_filters: function() {
 		var me = this;
@@ -138,13 +70,7 @@
 		this.filter_inputs.pl_or_bs.change(function() {
 			me.filter_inputs.refresh.click();
 		});
-		this.wrapper.bind('make', function() {
-			me.wrapper.on("click", ".plot-check", function() {
-				var checked = $(this).attr("checked");
-				me.account_by_name[$(this).attr("data-id")].checked = checked ? true : false;
-				me.render_plot();			
-			});
-		});
+		this.setup_plot_check();
 	},
 	init_filter_values: function() {
 		this._super();
@@ -155,7 +81,7 @@
 		
 		$.each(wn.report_dump.data['GL Entry'], function(i, gl) {
 			var posting_date = dateutil.str_to_obj(gl.posting_date);
-			var account = me.account_by_name[gl.account];
+			var account = me.item_by_name[gl.account];
 			var col = me.column_map[gl.posting_date];
 			
 			if(col) {
@@ -176,7 +102,7 @@
 
 		// make balances as cumulative
 		if(me.filter_inputs.pl_or_bs.val()=='Balance Sheet') {
-			$.each(me.accounts, function(i, ac) {
+			$.each(me.data, function(i, ac) {
 				if((ac.rgt - ac.lft)==1 && ac.is_pl_account!='Yes') {
 					var opening = flt(ac.opening);
 					//if(opening) throw opening;
@@ -198,12 +124,7 @@
 	},
 	init_account: function(d) {
 		// set 0 values for all columns
-		var me = this;
-		$.each(this.columns, function(i, col) {
-			if (col.formatter==me.currency_formatter) {
-				d[col.id] = 0;
-			}
-		});
+		this.reset_item_values(d);
 		
 		// check for default graphs
 		if(!this.accounts_initialized && !d.parent_account) {
@@ -215,7 +136,7 @@
 		var data = [];
 		var me = this;
 		var pl_or_bs = this.filter_inputs.pl_or_bs.val();
-		$.each(this.accounts, function(i, account) {
+		$.each(this.data, function(i, account) {
 			var show = pl_or_bs == "Profit and Loss" ? account.is_pl_account=="Yes" : account.is_pl_account!="Yes";
 			if (show && account.checked && me.apply_filter(account, "company")) {
 				data.push({
diff --git a/erpnext/accounts/page/general_ledger/general_ledger.js b/erpnext/accounts/page/general_ledger/general_ledger.js
index 8a57b06..a47c076 100644
--- a/erpnext/accounts/page/general_ledger/general_ledger.js
+++ b/erpnext/accounts/page/general_ledger/general_ledger.js
@@ -68,13 +68,6 @@
 			{fieldtype:"Button", label: "Refresh", icon:"icon-refresh icon-white", cssClass:"btn-info"},
 			{fieldtype:"Button", label: "Reset Filters"}
 		],
-		init_filter_values: function() {
-			this.filter_inputs.company.val(sys_defaults.company);
-			this.filter_inputs.from_date.val(dateutil.str_to_user(sys_defaults.year_start_date));
-			this.filter_inputs.to_date.val(dateutil.str_to_user(sys_defaults.year_end_date));
-			this.filter_inputs.voucher_no.val("");
-			this.filter_inputs.account.get(0).selectedIndex = 0;			
-		},
 		is_child_account: function(account, item_account) {
 			account = this.account_by_name[account];
 			item_account = this.account_by_name[item_account];
@@ -148,11 +141,8 @@
 			} else {
 				var out = out.concat([totals]);
 			}
-			
-			// sanitize opening / closing
-			
+						
 			this.data = out;
-			this.prepare_data_view(out);
 		},
 		get_plot_data: function() {
 			var data = [];
diff --git a/erpnext/accounts/page/trial_balance/trial_balance.js b/erpnext/accounts/page/trial_balance/trial_balance.js
index 91ab82a..071af67 100644
--- a/erpnext/accounts/page/trial_balance/trial_balance.js
+++ b/erpnext/accounts/page/trial_balance/trial_balance.js
@@ -15,7 +15,6 @@
 // along with this program.	If not, see <http://www.gnu.org/licenses/>.
 
 wn.require("js/app/account_tree_grid.js");
-wn.require("js/app/account_tree_grid.css");
 
 wn.pages['trial-balance'].onload = function(wrapper) { 
 	wn.ui.make_app_page({
diff --git a/erpnext/startup/report_data_map.py b/erpnext/startup/report_data_map.py
index b132180..5066853 100644
--- a/erpnext/startup/report_data_map.py
+++ b/erpnext/startup/report_data_map.py
@@ -50,7 +50,7 @@
 	},
 	"Stock Ledger Entry": {
 		"columns": ["posting_date", "posting_time", "item_code", "warehouse", "actual_qty as qty",
-			"voucher_type", "voucher_no"],
+			"voucher_type", "voucher_no", "ifnull(incoming_rate,0) as incoming_rate"],
 		"conditions": ["ifnull(is_cancelled, 'No')='No'"],
 		"order_by": "posting_date, posting_time, name",
 		"links": {
@@ -61,7 +61,7 @@
 	},
 	"Item": {
 		"columns": ["name", "if(item_name=name, '', item_name) as item_name", 
-			"item_group", "stock_uom", "brand"],
+			"item_group as parent_item_group", "stock_uom", "brand"],
 		"order_by": "name"
 	},
 	"Item Group": {
diff --git a/erpnext/stock/page/stock_analytics/__init__.py b/erpnext/stock/page/stock_analytics/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/stock/page/stock_analytics/__init__.py
diff --git a/erpnext/stock/page/stock_analytics/stock_analytics.js b/erpnext/stock/page/stock_analytics/stock_analytics.js
new file mode 100644
index 0000000..2e65f5c
--- /dev/null
+++ b/erpnext/stock/page/stock_analytics/stock_analytics.js
@@ -0,0 +1,238 @@
+wn.pages['stock-analytics'].onload = function(wrapper) { 
+	wn.ui.make_app_page({
+		parent: wrapper,
+		title: 'Stock Analytics',
+		single_column: true
+	});
+	
+	new erpnext.StockAnalytics(wrapper);
+}
+
+erpnext.StockAnalytics = wn.views.GridReportWithPlot.extend({
+	init: function(wrapper) {
+		this._super({
+			title: "Stock Analytics",
+			page: wrapper,
+			parent: $(wrapper).find('.layout-main'),
+			appframe: wrapper.appframe,
+			doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry", "Fiscal Year"],
+			tree_grid: {
+				show: true, 
+				parent_field: "parent_item_group", 
+				formatter: function(item) {
+					return repl('<a href="#stock-ledger/item=%(enc_value)s">%(value)s</a>', {
+							value: item.name,
+							enc_value: encodeURIComponent(item.name)
+						});
+				}
+			}			
+		})
+	},
+	setup_columns: function() {
+		var std_columns = [
+			{id: "check", name: "Plot", field: "check", width: 30,
+				formatter: this.check_formatter},
+			{id: "name", name: "Item", field: "name", width: 300,
+				formatter: this.tree_formatter, doctype: "Item"},
+			{id: "opening", name: "Opening", field: "opening", hidden: true,
+				formatter: this.currency_formatter},
+			{id: "balance_qty", name: "Balance Qty", field: "balance_qty", hidden: true,
+				formatter: this.currency_formatter},
+			{id: "balance_value", name: "Balance Value", field: "balance_value", hidden: true,
+				formatter: this.currency_formatter}
+		];
+
+		this.make_date_range_columns();		
+		this.columns = std_columns.concat(this.columns);
+	},
+	filters: [
+		{fieldtype:"Select", label: "Value or Qty", options:["Value", "Quantity"],
+			filter: function(val, item, opts, me) {
+				return me.apply_zero_filter(val, item, opts, me);
+			}},
+		{fieldtype:"Select", label: "Warehouse", link:"Warehouse", 
+			default_value: "Select Warehouse..."},
+		{fieldtype:"Select", label: "Fiscal Year", link:"Fiscal Year", 
+			default_value: "Select Fiscal Year..."},
+		{fieldtype:"Date", label: "From Date"},
+		{fieldtype:"Label", label: "To"},
+		{fieldtype:"Date", label: "To Date"},
+		{fieldtype:"Select", label: "Range", 
+			options:["Daily", "Weekly", "Monthly", "Quarterly", "Yearly"]},
+		{fieldtype:"Button", label: "Refresh", icon:"icon-refresh icon-white", cssClass:"btn-info"},
+		{fieldtype:"Button", label: "Reset Filters"}
+	],
+	setup_filters: function() {
+		var me = this;
+		this._super();
+
+		this.filter_inputs.fiscal_year.change(function() {
+			var fy = $(this).val();
+			$.each(wn.report_dump.data["Fiscal Year"], function(i, v) {
+				if (v.name==fy) {
+					me.filter_inputs.from_date.val(dateutil.str_to_user(v.year_start_date));
+					me.filter_inputs.to_date.val(dateutil.str_to_user(v.year_end_date));
+				}
+			});
+			me.set_route();
+		});
+		
+		this.filter_inputs.value_or_qty.change(function() {
+			me.filter_inputs.refresh.click();
+		});
+
+		this.show_zero_check()		
+		this.setup_plot_check();
+	},
+	init_filter_values: function() {
+		this._super();
+		this.filter_inputs.range.val('Weekly');
+	},
+	prepare_data: function() {
+		var me = this;
+		
+		if(!this.data) {
+			var items = this.get_item_tree();
+
+			me.parent_map = {};
+			me.item_by_name = {};
+			me.data = [];
+
+			$.each(items, function(i, v) {
+				var d = copy_dict(v);
+
+				me.data.push(d);
+				me.item_by_name[d.name] = d;
+				if(d.parent_item_group) {
+					me.parent_map[d.name] = d.parent_item_group;
+				}
+				me.reset_item_values(d);
+			});
+			this.set_indent();
+		} else {
+			// otherwise, only reset values
+			$.each(this.data, function(i, d) {
+				me.reset_item_values(d);
+			});
+		}
+		
+		this.prepare_balances();
+		this.update_groups();
+		
+	},
+	get_item_tree: function() {
+		// prepare map with items in respective item group
+		var item_group_map = {};
+		$.each(wn.report_dump.data["Item"], function(i, item) {
+			var parent = item.parent_item_group
+			if(!item_group_map[parent]) item_group_map[parent] = [];
+			item_group_map[parent].push(item);
+		});
+		
+		// arrange items besides their parent item groups
+		var items = [];
+		$.each(wn.report_dump.data["Item Group"], function(i, group){
+			group.is_group = true;
+			items.push(group);
+			items = items.concat(item_group_map[group.name] || []);
+		});
+		return items;
+	},
+	prepare_balances: function() {
+		var me = this;
+		var from_date = dateutil.str_to_obj(this.from_date);
+		var to_date = dateutil.str_to_obj(this.to_date);
+		var data = wn.report_dump.data["Stock Ledger Entry"];
+		var is_value = me.value_or_qty == "Value";
+				
+		for(var i=0, j=data.length; i<j; i++) {
+			var sl = data[i];
+			sl.posting_datetime = sl.posting_date + " " + sl.posting_time;
+			var posting_datetime = dateutil.str_to_obj(sl.posting_datetime);
+			
+			if(me.is_default("warehouse") ? true : me.warehouse == sl.warehouse) {			
+				var item = me.item_by_name[sl.item_code];
+
+				// value
+				var rate = sl.qty > 0 ? sl.incoming_rate :
+					(item.balance_qty.toFixed(2) == 0.00 ? 0 : flt(item.balance_value) / flt(item.balance_qty));
+				var value_diff = (rate * sl.qty);
+								
+				// update balance
+				item.balance_qty += sl.qty;
+				item.balance_value += value_diff;
+
+				var diff = is_value ? value_diff : sl.qty;
+
+				if(posting_datetime < from_date) {
+					item.opening += diff;
+				} else if(posting_datetime <= to_date) {
+					item[me.column_map[sl.posting_date].field] += diff;
+				} else {
+					break;
+				}
+			}
+		}
+	},
+	update_groups: function() {
+		var me = this;
+
+		$.each(this.data, function(i, item) {
+			// update groups
+			if(!item.is_group) {
+				var balance = item.opening;
+				$.each(me.columns, function(i, col) {
+					if(col.formatter==me.currency_formatter && !col.hidden) {
+						item[col.field] = balance + item[col.field];
+						balance = item[col.field];
+					}
+				});
+				
+				var parent = me.parent_map[item.name];
+				while(parent) {
+					parent_group = me.item_by_name[parent];
+					$.each(me.columns, function(c, col) {
+						if (col.formatter == me.currency_formatter) {
+							parent_group[col.field] = 
+								flt(parent_group[col.field])
+								+ flt(item[col.field]);
+						}
+					});
+					parent = me.parent_map[parent];
+				}				
+			}
+		});
+	},
+	get_plot_data: function() {
+		var data = [];
+		var me = this;
+		$.each(this.data, function(i, item) {
+			if (item.checked) {
+				data.push({
+					label: item.name,
+					data: $.map(me.columns, function(col, idx) {
+						if(col.formatter==me.currency_formatter && !col.hidden) {
+							return [[dateutil.user_to_obj(col.name).getTime(), item[col.field]]]
+						}
+					}),
+					points: {show: true},
+					lines: {show: true, fill: true},
+				});
+				
+				// prepend opening 
+				data[data.length-1].data = [[dateutil.str_to_obj(me.from_date).getTime(), 
+					item.opening]].concat(data[data.length-1].data);
+			}
+		});
+	
+		return data;
+	},
+	get_plot_options: function() {
+		return {
+			grid: { hoverable: true, clickable: true },
+			xaxis: { mode: "time", 
+				min: dateutil.str_to_obj(this.from_date).getTime(),
+				max: dateutil.str_to_obj(this.to_date).getTime() }
+		}
+	}
+});
diff --git a/erpnext/stock/page/stock_analytics/stock_analytics.txt b/erpnext/stock/page/stock_analytics/stock_analytics.txt
new file mode 100644
index 0000000..3d9510d
--- /dev/null
+++ b/erpnext/stock/page/stock_analytics/stock_analytics.txt
@@ -0,0 +1,28 @@
+# Page, stock-analytics
+[
+
+	# These values are common in all dictionaries
+	{
+		u'creation': '2012-09-20 12:13:45',
+		u'docstatus': 0,
+		u'modified': '2012-09-20 12:13:45',
+		u'modified_by': u'Administrator',
+		u'owner': u'Administrator'
+	},
+
+	# These values are common for all Page
+	{
+		u'doctype': u'Page',
+		'module': u'Stock',
+		u'name': u'__common__',
+		'page_name': u'stock-analytics',
+		'standard': u'Yes',
+		'title': u'Stock Analytics'
+	},
+
+	# Page, stock-analytics
+	{
+		u'doctype': u'Page',
+		u'name': u'stock-analytics'
+	}
+]
\ No newline at end of file
diff --git a/erpnext/stock/page/stock_ledger/stock_ledger.js b/erpnext/stock/page/stock_ledger/stock_ledger.js
index 3f6d4a5..deb3743 100644
--- a/erpnext/stock/page/stock_ledger/stock_ledger.js
+++ b/erpnext/stock/page/stock_ledger/stock_ledger.js
@@ -5,183 +5,180 @@
 		single_column: true
 	});
 	
-	erpnext.stock_ledger = new wn.views.GridReport({
-		title: "Stock Ledger",
-		page: wrapper,
-		parent: $(wrapper).find('.layout-main'),
-		appframe: wrapper.appframe,
-		doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry"],
+	new erpnext.StockLedger(wrapper);
+}
 
-		setup_columns: function() {
-			this.hide_balance = (this.is_default("item_code") || this.voucher_no) ? true : false;
-			this.columns = [
-				{id: "posting_datetime", name: "Posting Date", field: "posting_datetime", width: 120,
-					formatter: this.date_formatter},
-				{id: "item_code", name: "Item Code", field: "item_code", width: 160, 	
-					link_formatter: {
-						filter_input: "item_code",
-						open_btn: true,
-						doctype: '"Item"'
-					}},
-				{id: "warehouse", name: "Warehouse", field: "warehouse", width: 100,
-					link_formatter: {filter_input: "warehouse"}},
-				{id: "qty", name: "Qty", field: "qty", width: 100,
-					formatter: this.currency_formatter},
-				{id: "balance", name: "Balance", field: "balance", width: 100,
-					formatter: this.currency_formatter,
-					hidden: this.hide_balance},
-				{id: "voucher_type", name: "Voucher Type", field: "voucher_type", width: 120},
-				{id: "voucher_no", name: "Voucher No", field: "voucher_no", width: 160,
-					link_formatter: {
-						filter_input: "voucher_no",
-						open_btn: true,
-						doctype: "dataContext.voucher_type"
-					}},
-				{id: "description", name: "Description", field: "description", width: 200,
-					formatter: this.text_formatter},
-			];
-			
-		},
-		filters: [
-			{fieldtype:"Select", label: "Warehouse", link:"Warehouse", default_value: "Select Warehouse...",
-				filter: function(val, item, opts) {
-					return item.warehouse == val || val == opts.default_value;
-				}},
-			{fieldtype:"Select", label: "Item Code", link:"Item", default_value: "Select Item...",
-				filter: function(val, item, opts) {
-					return item.item_code == val || val == opts.default_value;
-				}},
-			{fieldtype:"Data", label: "Voucher No",
-				filter: function(val, item, opts) {
-					if(!val) return true;
-					return (item.voucher_no && item.voucher_no.indexOf(val)!=-1);
-				}},
-			{fieldtype:"Date", label: "From Date", filter: function(val, item) {
-				return dateutil.str_to_obj(val) <= dateutil.str_to_obj(item.posting_date);
-			}},
-			{fieldtype:"Label", label: "To"},
-			{fieldtype:"Date", label: "To Date", filter: function(val, item) {
-				return dateutil.str_to_obj(val) >= dateutil.str_to_obj(item.posting_date);
-			}},
-			{fieldtype:"Button", label: "Refresh", icon:"icon-refresh icon-white", cssClass:"btn-info"},
-			{fieldtype:"Button", label: "Reset Filters"}
-		],
-		init_filter_values: function() {
-			this.filter_inputs.warehouse.get(0).selectedIndex = 0;
-			this.filter_inputs.item_code.get(0).selectedIndex = 0;			
-			this.filter_inputs.from_date.val(dateutil.str_to_user(sys_defaults.year_start_date));
-			this.filter_inputs.to_date.val(dateutil.str_to_user(sys_defaults.year_end_date));
-			this.filter_inputs.voucher_no.val("");
-		},
-		prepare_data: function() {
-			var me = this;
-			if(!this.item_by_name)
-				this.item_by_name = this.make_name_map(wn.report_dump.data["Item"]);
-			var data = wn.report_dump.data["Stock Ledger Entry"];
-			var out = [];
-			
-			if(this.to_date < this.from_date) {
-				msgprint("From Date must be before To Date");
-				return;
-			}
+erpnext.StockLedger = wn.views.GridReportWithPlot.extend({
+	init: function(wrapper) {
+		this._super({
+			title: "Stock Ledger",
+			page: wrapper,
+			parent: $(wrapper).find('.layout-main'),
+			appframe: wrapper.appframe,
+			doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry"]			
+		})
+	},
 
-			var opening = {
-				item_code: "On " + dateutil.str_to_user(this.from_date), qty: 0.0, balance: 0.0,
-					id:"_opening", _show: true, _style: "font-weight: bold"
-			}
-			var total_in = {
-				item_code: "Total In", qty: 0.0, balance: 0.0,
-					id:"_total_in", _show: true, _style: "font-weight: bold"
-			}
-			var total_out = {
-				item_code: "Total Out", qty: 0.0, balance: 0.0,
-					id:"_total_out", _show: true, _style: "font-weight: bold"
+	setup_columns: function() {
+		this.hide_balance = (this.is_default("item_code") || this.voucher_no) ? true : false;
+		this.columns = [
+			{id: "posting_datetime", name: "Posting Date", field: "posting_datetime", width: 120,
+				formatter: this.date_formatter},
+			{id: "item_code", name: "Item Code", field: "item_code", width: 160, 	
+				link_formatter: {
+					filter_input: "item_code",
+					open_btn: true,
+					doctype: '"Item"'
+				}},
+			{id: "warehouse", name: "Warehouse", field: "warehouse", width: 100,
+				link_formatter: {filter_input: "warehouse"}},
+			{id: "qty", name: "Qty", field: "qty", width: 100,
+				formatter: this.currency_formatter},
+			{id: "balance", name: "Balance", field: "balance", width: 100,
+				formatter: this.currency_formatter,
+				hidden: this.hide_balance},
+			{id: "voucher_type", name: "Voucher Type", field: "voucher_type", width: 120},
+			{id: "voucher_no", name: "Voucher No", field: "voucher_no", width: 160,
+				link_formatter: {
+					filter_input: "voucher_no",
+					open_btn: true,
+					doctype: "dataContext.voucher_type"
+				}},
+			{id: "description", name: "Description", field: "description", width: 200,
+				formatter: this.text_formatter},
+		];
+		
+	},
+	filters: [
+		{fieldtype:"Select", label: "Warehouse", link:"Warehouse", default_value: "Select Warehouse...",
+			filter: function(val, item, opts) {
+				return item.warehouse == val || val == opts.default_value;
+			}},
+		{fieldtype:"Select", label: "Item Code", link:"Item", default_value: "Select Item...",
+			filter: function(val, item, opts) {
+				return item.item_code == val || val == opts.default_value;
+			}},
+		{fieldtype:"Data", label: "Voucher No",
+			filter: function(val, item, opts) {
+				if(!val) return true;
+				return (item.voucher_no && item.voucher_no.indexOf(val)!=-1);
+			}},
+		{fieldtype:"Date", label: "From Date", filter: function(val, item) {
+			return dateutil.str_to_obj(val) <= dateutil.str_to_obj(item.posting_date);
+		}},
+		{fieldtype:"Label", label: "To"},
+		{fieldtype:"Date", label: "To Date", filter: function(val, item) {
+			return dateutil.str_to_obj(val) >= dateutil.str_to_obj(item.posting_date);
+		}},
+		{fieldtype:"Button", label: "Refresh", icon:"icon-refresh icon-white", cssClass:"btn-info"},
+		{fieldtype:"Button", label: "Reset Filters"}
+	],
+	init_filter_values: function() {
+		this._super();
+		this.filter_inputs.warehouse.get(0).selectedIndex = 0;
+	},
+	prepare_data: function() {
+		var me = this;
+		if(!this.item_by_name)
+			this.item_by_name = this.make_name_map(wn.report_dump.data["Item"]);
+		var data = wn.report_dump.data["Stock Ledger Entry"];
+		var out = [];
+
+		var opening = {
+			item_code: "On " + dateutil.str_to_user(this.from_date), qty: 0.0, balance: 0.0,
+				id:"_opening", _show: true, _style: "font-weight: bold"
+		}
+		var total_in = {
+			item_code: "Total In", qty: 0.0, balance: 0.0,
+				id:"_total_in", _show: true, _style: "font-weight: bold"
+		}
+		var total_out = {
+			item_code: "Total Out", qty: 0.0, balance: 0.0,
+				id:"_total_out", _show: true, _style: "font-weight: bold"
+		}
+		
+		// clear balance
+		$.each(wn.report_dump.data["Item"], function(i, item) { item.balance = 0.0; });
+		
+		// 
+		for(var i=0, j=data.length; i<j; i++) {
+			var sl = data[i];
+			sl.description = me.item_by_name[sl.item_code].description;
+			sl.posting_datetime = sl.posting_date + " " + sl.posting_time;
+			var posting_datetime = dateutil.str_to_obj(sl.posting_datetime);
+			
+			// opening, transactions, closing, total in, total out
+			var before_end = posting_datetime <= dateutil.str_to_obj(me.to_date + " 23:59:59");
+			if((!me.is_default("item_code") ? me.apply_filter(sl, "item_code") : true)
+				&& me.apply_filter(sl, "warehouse") && me.apply_filter(sl, "voucher_no")) {
+				if(posting_datetime < dateutil.str_to_obj(me.from_date)) {
+					opening.balance += sl.qty;
+				} else if(before_end) {
+					if(sl.qty > 0) total_in.qty += sl.qty;
+					else total_out.qty += (-1 * sl.qty);
+				}
 			}
 			
-			// clear balance
-			$.each(wn.report_dump.data["Item"], function(i, item) { item.balance = 0.0; });
+			if(!before_end) break;
 			
-			// 
-			for(var i=0, j=data.length; i<j; i++) {
-				var sl = data[i];
-				sl.description = me.item_by_name[sl.item_code].description;
-				sl.posting_datetime = sl.posting_date + " " + sl.posting_time;
-				var posting_datetime = dateutil.str_to_obj(sl.posting_datetime);
-				
-				// opening, transactions, closing, total in, total out
-				var before_end = posting_datetime <= dateutil.str_to_obj(me.to_date + " 23:59:59");
-				if((!me.is_default("item_code") ? me.apply_filter(sl, "item_code") : true)
-					&& me.apply_filter(sl, "warehouse") && me.apply_filter(sl, "voucher_no")) {
-					if(posting_datetime < dateutil.str_to_obj(me.from_date)) {
-						opening.balance += sl.qty;
-					} else if(before_end) {
-						if(sl.qty > 0) total_in.qty += sl.qty;
-						else total_out.qty += (-1 * sl.qty);
+			// apply filters
+			if(me.apply_filters(sl)) {
+				out.push(sl);
+			}
+			
+			// update balance
+			if((!me.is_default("warehouse") ? me.apply_filter(sl, "warehouse") : true)) {
+				sl.balance = me.item_by_name[sl.item_code].balance + sl.qty;
+				me.item_by_name[sl.item_code].balance = sl.balance;					
+			}
+		}
+					
+		if(me.item_code != me.item_code_default && !me.voucher_no) {
+			var closing = {
+				item_code: "On " + dateutil.str_to_user(this.to_date), 
+				balance: (out ? out[out.length-1].balance : 0), qty: 0,
+				id:"_closing", _show: true, _style: "font-weight: bold"
+			};
+			var out = [opening].concat(out).concat([total_in, total_out, closing]);
+		}
+		
+		this.data = out;
+	},
+	get_plot_data: function() {
+		var data = [];
+		var me = this;
+		if(me.hide_balance) return false;
+		data.push({
+			label: me.item_code,
+			data: [[dateutil.str_to_obj(me.from_date).getTime(), me.data[0].balance]]
+				.concat($.map(me.data, function(col, idx) {
+					if (col.posting_datetime) {
+						return [[dateutil.str_to_obj(col.posting_datetime).getTime(), col.balance - col.qty],
+								[dateutil.str_to_obj(col.posting_datetime).getTime(), col.balance]]
 					}
-				}
-				
-				if(!before_end) break;
-				
-				// apply filters
-				if(me.apply_filters(sl)) {
-					out.push(sl);
-				}
-				
-				// update balance
-				if((!me.is_default("warehouse") ? me.apply_filter(sl, "warehouse") : true)) {
-					sl.balance = me.item_by_name[sl.item_code].balance + sl.qty;
-					me.item_by_name[sl.item_code].balance = sl.balance;					
-				}
-			}
-						
-			if(me.item_code != me.item_code_default && !me.voucher_no) {
-				var closing = {
-					item_code: "On " + dateutil.str_to_user(this.to_date), 
-					balance: (out ? out[out.length-1].balance : 0), qty: 0,
-					id:"_closing", _show: true, _style: "font-weight: bold"
-				};
-				var out = [opening].concat(out).concat([total_in, total_out, closing]);
-			}
-			
-			this.data = out;
-			this.prepare_data_view(out);			
-		},
-		get_plot_data: function() {
-			var data = [];
-			var me = this;
-			if(me.hide_balance) return false;
-			data.push({
-				label: me.item_code,
-				data: [[dateutil.str_to_obj(me.from_date).getTime(), me.data[0].balance]]
-					.concat($.map(me.data, function(col, idx) {
-						if (col.posting_datetime) {
-							return [[dateutil.str_to_obj(col.posting_datetime).getTime(), col.balance - col.qty],
-									[dateutil.str_to_obj(col.posting_datetime).getTime(), col.balance]]
-						}
-						return null;
-					})).concat([
-						// closing
-						[dateutil.str_to_obj(me.to_date).getTime(), me.data[me.data.length - 1].balance]
-					]),
-				points: {show: true},
-				lines: {show: true, fill: true},
-			});
-			return data;
-		},
-		get_plot_options: function() {
-			return {
-				grid: { hoverable: true, clickable: true },
-				xaxis: { mode: "time", 
-					min: dateutil.str_to_obj(this.from_date).getTime(),
-					max: dateutil.str_to_obj(this.to_date).getTime(),
-				},
-			}
-		},
-		get_tooltip_text: function(label, x, y) {
-			var d = new Date(x);
-			var date = dateutil.obj_to_user(d) + " " + d.getHours() + ":" + d.getMinutes();
-		 	var value = fmt_money(y);
-			return value.bold() + " on " + date;
-		},
-	});
-}
\ No newline at end of file
+					return null;
+				})).concat([
+					// closing
+					[dateutil.str_to_obj(me.to_date).getTime(), me.data[me.data.length - 1].balance]
+				]),
+			points: {show: true},
+			lines: {show: true, fill: true},
+		});
+		return data;
+	},
+	get_plot_options: function() {
+		return {
+			grid: { hoverable: true, clickable: true },
+			xaxis: { mode: "time", 
+				min: dateutil.str_to_obj(this.from_date).getTime(),
+				max: dateutil.str_to_obj(this.to_date).getTime(),
+			},
+		}
+	},
+	get_tooltip_text: function(label, x, y) {
+		var d = new Date(x);
+		var date = dateutil.obj_to_user(d) + " " + d.getHours() + ":" + d.getMinutes();
+	 	var value = fmt_money(y);
+		return value.bold() + " on " + date;
+	}
+});
\ No newline at end of file
diff --git a/public/js/all-app.js b/public/js/all-app.js
index 68f70b5..fdd710b 100644
--- a/public/js/all-app.js
+++ b/public/js/all-app.js
@@ -1077,17 +1077,22 @@
  */
 wn.provide("wn.report_dump");$.extend(wn.report_dump,{data:{},with_data:function(doctypes,callback,progress_bar){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){$.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=row.name||doctype+"-"+i
-data.push(row);});wn.report_dump.data[doctype]=data;});$.each(r.message,function(doctype,doctype_data){if(doctype_data.links){$.each(wn.report_dump.data[doctype],function(row_idx,row){$.each(doctype_data.links,function(link_key,link){row[link_key]=wn.report_dump.data[link[0]][row[link_key]][link[1]];})})}});callback();},progress_bar:progress_bar})}else{callback();}}});wn.provide("wn.views");wn.views.GridReport=Class.extend({init:function(opts){this.filter_inputs={};this.preset_checks=[];$.extend(this,opts);this.wrapper=$('<div>').appendTo(this.parent);if(this.filters){this.make_filters();}
-this.make_waiting();this.import_slickgrid();var me=this;this.get_data();},bind_show:function(){var me=this;$(this.page).bind('show',function(){wn.cur_grid_report=me;me.apply_filters_from_route();me.refresh();});},get_data:function(){var me=this;wn.report_dump.with_data(this.doctypes,function(){me.setup_filters();me.init_filter_values();me.refresh();},this.wrapper.find(".progress .bar"));},setup_filters:function(){var me=this;$.each(me.filter_inputs,function(i,v){var opts=v.get(0).opts;if(opts.fieldtype=="Select"&&inList(me.doctypes,opts.link)){$(v).add_options($.map(wn.report_dump.data[opts.link],function(d){return d.name;}));}});this.filter_inputs.refresh&&this.filter_inputs.refresh.click(function(){me.set_route();});this.filter_inputs.reset_filters&&this.filter_inputs.reset_filters.click(function(){me.init_filter_values();me.set_route();});},make_waiting:function(){this.waiting=$('<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: 10%"></div></div>').appendTo(this.wrapper);},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,v.options||[v.default_value]);}else if(v.fieldtype=='Button'){input=me.appframe.add_button(v.label);if(v.icon){$('<i class="icon '+v.icon+'"></i>').prependTo(input);}}else if(v.fieldtype=='Date'){input=me.appframe.add_date(v.label);}else if(v.fieldtype=='Label'){input=me.appframe.add_label(v.label);}else if(v.fieldtype=='Data'){input=me.appframe.add_data(v.label);}
+data.push(row);});wn.report_dump.data[doctype]=data;});$.each(r.message,function(doctype,doctype_data){if(doctype_data.links){$.each(wn.report_dump.data[doctype],function(row_idx,row){$.each(doctype_data.links,function(link_key,link){row[link_key]=wn.report_dump.data[link[0]][row[link_key]][link[1]];})})}});callback();},progress_bar:progress_bar})}else{callback();}}});wn.provide("wn.views");wn.views.GridReport=Class.extend({init:function(opts){this.filter_inputs={};this.preset_checks=[];this.tree_grid={show:false};$.extend(this,opts);this.wrapper=$('<div>').appendTo(this.parent);if(this.filters){this.make_filters();}
+this.make_waiting();this.import_slickgrid();var me=this;this.get_data();},bind_show:function(){var me=this;$(this.page).bind('show',function(){wn.cur_grid_report=me;me.apply_filters_from_route();me.refresh();});},get_data:function(){var me=this;wn.report_dump.with_data(this.doctypes,function(){me.setup_filters();me.init_filter_values();me.refresh();},this.wrapper.find(".progress .bar"));},setup_filters:function(){var me=this;$.each(me.filter_inputs,function(i,v){var opts=v.get(0).opts;if(opts.fieldtype=="Select"&&inList(me.doctypes,opts.link)){$(v).add_options($.map(wn.report_dump.data[opts.link],function(d){return d.name;}));}});this.filter_inputs.refresh&&this.filter_inputs.refresh.click(function(){me.set_route();});this.filter_inputs.reset_filters&&this.filter_inputs.reset_filters.click(function(){me.init_filter_values();me.set_route();});},init_filter_values:function(){var me=this;$.each(this.filter_inputs,function(key,filter){var opts=filter.get(0).opts;if(sys_defaults[key]){filter.val(sys_defaults[key]);}else if(opts.fieldtype=='Select'){filter.get(0).selectedIndex=0;}else if(opts.fieldtype=='Data'){filter.val("");}})
+if(this.filter_inputs.from_date)
+this.filter_inputs.from_date.val(dateutil.str_to_user(sys_defaults.year_start_date));if(this.filter_inputs.to_date)
+this.filter_inputs.to_date.val(dateutil.str_to_user(sys_defaults.year_end_date));},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,v.options||[v.default_value]);}else if(v.fieldtype=='Button'){input=me.appframe.add_button(v.label);if(v.icon){$('<i class="icon '+v.icon+'"></i>').prependTo(input);}}else if(v.fieldtype=='Date'){input=me.appframe.add_date(v.label);}else if(v.fieldtype=='Label'){input=me.appframe.add_label(v.label);}else if(v.fieldtype=='Data'){input=me.appframe.add_data(v.label);}
 if(input){input&&(input.get(0).opts=v);if(v.cssClass){input.addClass(v.cssClass);}
 input.keypress(function(e){if(e.which==13){me.set_route();}})}
-me.filter_inputs[v.fieldname]=input;});},load_filter_values:function(){var me=this;$.each(this.filter_inputs,function(i,f){var opts=f.get(0).opts;if(opts.fieldtype!='Button'){me[opts.fieldname]=f.val();if(opts.fieldtype=="Date"){me[opts.fieldname]=dateutil.user_to_str(me[opts.fieldname]);}else if(opts.fieldtype=="Select"){me[opts.fieldname+'_default']=opts.default_value;}}});},make_name_map:function(data,key){var map={};key=key||"name";$.each(data,function(i,v){map[v[key]]=v;})
-return map;},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.waiting.toggle(false);if(!this.grid_wrapper)
-this.make();this.show_zero=$('.show-zero input:checked').length;this.load_filter_values();this.setup_columns();this.setup_dataview_columns();this.apply_link_formatters();this.prepare_data();this.render();this.render_plot();},setup_dataview_columns:function(){this.dataview_columns=$.map(this.columns,function(col){return!col.hidden?col:null;});},make:function(){$('<div class="plot" style="margin-bottom: 15px; display: none; \
+me.filter_inputs[v.fieldname]=input;});},make_waiting:function(){this.waiting=$('<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: 10%"></div></div>').appendTo(this.wrapper);},load_filter_values:function(){var me=this;$.each(this.filter_inputs,function(i,f){var opts=f.get(0).opts;if(opts.fieldtype!='Button'){me[opts.fieldname]=f.val();if(opts.fieldtype=="Date"){me[opts.fieldname]=dateutil.user_to_str(me[opts.fieldname]);}else if(opts.fieldtype=="Select"){me[opts.fieldname+'_default']=opts.default_value;}}});if(this.filter_inputs.from_date&&this.filter_inputs.to_date&&(this.to_date<this.from_date)){msgprint("From Date must be before To Date");return;}},make_name_map:function(data,key){var map={};key=key||"name";$.each(data,function(i,v){map[v[key]]=v;})
+return map;},reset_item_values:function(item){var me=this;$.each(this.columns,function(i,col){if(col.formatter==me.currency_formatter){item[col.id]=0;}});},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; }');if(this.tree_grid.show)wn.require("js/app/tree_grid.css");},refresh:function(){this.waiting.toggle(false);if(!this.grid_wrapper)
+this.make();this.show_zero=$('.show-zero input:checked').length;this.load_filter_values();this.setup_columns();this.setup_dataview_columns();this.apply_link_formatters();this.prepare_data();this.prepare_data_view();this.wrapper.find(".processing").toggle(true);this.wrapper.find(".processing").delay(2000).fadeOut(300);this.render();this.render_plot();},setup_dataview_columns:function(){this.dataview_columns=$.map(this.columns,function(col){return!col.hidden?col:null;});},make:function(){this.plot_area=$('<div class="plot" style="margin-bottom: 15px; display: none; \
    height: 300px; width: 100%;"></div>').appendTo(this.wrapper);$('<div style="text-align: right;"> \
+   <div class="processing" style="background-color: #fec; display: none; float: left; margin: 2px"> \
+    Updated! </div>\
    <a href="#" class="grid-report-print"><i class="icon icon-print"></i> Print</a> \
    <span style="color: #aaa; margin: 0px 10px;"> | </span> \
    <a href="#" class="grid-report-export"><i class="icon icon-download-alt"></i> Export</a> \
@@ -1096,27 +1101,37 @@
     <input type="checkbox"> Show rows with zero values\
    </div>').appendTo(this.wrapper);this.bind_show();wn.cur_grid_report=this;this.apply_filters_from_route();$(this.wrapper).trigger('make');},apply_filters_from_route:function(){var hash=decodeURIComponent(window.location.hash);var me=this;if(hash.indexOf('/')!=-1){$.each(hash.split('/').splice(1).join('/').split('&'),function(i,f){var f=f.split("=");if(me.filter_inputs[f[0]]){me.filter_inputs[f[0]].val(decodeURIComponent(f[1]));}else{console.log("Invalid filter: "+f[0]);}});}else{this.init_filter_values();}},set_route:function(){wn.set_route(wn.container.page.page_name,$.map(this.filter_inputs,function(v){var val=v.val();var opts=v.get(0).opts;if(val&&val!=opts.default_value)
 return encodeURIComponent(opts.fieldname)
-+'='+encodeURIComponent(val);}).join('&'))},render:function(){this.grid=new Slick.Grid("#"+this.id,this.dataView,this.dataview_columns,this.options);var me=this;this.dataView.onRowsChanged.subscribe(function(e,args){me.grid.invalidateRows(args.rows);me.grid.render();});this.dataView.onRowCountChanged.subscribe(function(e,args){me.grid.updateRowCount();me.grid.render();});this.add_grid_events&&this.add_grid_events();},prepare_data_view:function(items){this.dataView=new Slick.Data.DataView({inlineFilters:true});this.dataView.beginUpdate();this.dataView.setItems(items);if(this.dataview_filter)this.dataView.setFilter(this.dataview_filter);this.dataView.endUpdate();},export:function(){var me=this;var res=[$.map(this.columns,function(v){return v.name;})].concat(this.get_view_data());wn.require("js/lib/downloadify/downloadify.min.js");wn.require("js/lib/downloadify/swfobject.js");var id=wn.dom.set_unique_id();var msgobj=msgprint('<p id="'+id+'">You must have Flash 10 installed to download this file.</p>');Downloadify.create(id,{filename:function(){return me.title+'.csv';},data:function(){return wn.to_csv(res);},swf:'js/lib/downloadify/downloadify.swf',downloadImage:'js/lib/downloadify/download.png',onComplete:function(){msgobj.hide();},onCancel:function(){msgobj.hide();},onError:function(){msgobj.hide();},width:100,height:30,transparent:true,append:false});return false;},render_plot:function(){var plot_data=this.get_plot_data?this.get_plot_data():null;if(!plot_data){this.wrapper.find('.plot').toggle(false);return;}
-wn.require('js/lib/flot/jquery.flot.js');this.plot=$.plot(this.wrapper.find('.plot').toggle(true),plot_data,this.get_plot_options());this.setup_plot_hover();},setup_plot_hover:function(){var me=this;this.tooltip_id=wn.dom.set_unique_id();function showTooltip(x,y,contents){$('<div id="'+me.tooltip_id+'">'+contents+'</div>').css({position:'absolute',display:'none',top:y+5,left:x+5,border:'1px solid #fdd',padding:'2px','background-color':'#fee',opacity:0.80}).appendTo("body").fadeIn(200);}
++'='+encodeURIComponent(val);}).join('&'))},options:{editable:false,enableColumnReorder:false},render:function(){this.grid=new Slick.Grid("#"+this.id,this.dataView,this.dataview_columns,this.options);var me=this;this.dataView.onRowsChanged.subscribe(function(e,args){me.grid.invalidateRows(args.rows);me.grid.render();});this.dataView.onRowCountChanged.subscribe(function(e,args){me.grid.updateRowCount();me.grid.render();});this.tree_grid.show&&this.add_tree_grid_events();},prepare_data_view:function(){this.dataView=new Slick.Data.DataView({inlineFilters:true});this.dataView.beginUpdate();this.dataView.setItems(this.data);if(this.dataview_filter)this.dataView.setFilter(this.dataview_filter);if(this.tree_grid.show)this.dataView.setFilter(this.tree_dataview_filter);this.dataView.endUpdate();},export:function(){var me=this;var res=[$.map(this.columns,function(v){return v.name;})].concat(this.get_view_data());wn.require("js/lib/downloadify/downloadify.min.js");wn.require("js/lib/downloadify/swfobject.js");var id=wn.dom.set_unique_id();var msgobj=msgprint('<p id="'+id+'">You must have Flash 10 installed to download this file.</p>');Downloadify.create(id,{filename:function(){return me.title+'.csv';},data:function(){return wn.to_csv(res);},swf:'js/lib/downloadify/downloadify.swf',downloadImage:'js/lib/downloadify/download.png',onComplete:function(){msgobj.hide();},onCancel:function(){msgobj.hide();},onError:function(){msgobj.hide();},width:100,height:30,transparent:true,append:false});return false;},add_tree_grid_events:function(){var me=this;this.grid.onClick.subscribe(function(e,args){if($(e.target).hasClass("toggle")){var item=me.dataView.getItem(args.row);if(item){if(!item._collapsed){item._collapsed=true;}else{item._collapsed=false;}
+me.dataView.updateItem(item.id,item);}
+e.stopImmediatePropagation();}});},tree_formatter:function(row,cell,value,columnDef,dataContext){var me=wn.cur_grid_report;value=value.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");var data=me.data;var spacer="<span style='display:inline-block;height:1px;width:"+
+(15*dataContext["indent"])+"px'></span>";var idx=me.dataView.getIdxById(dataContext.id);var link=me.tree_grid.formatter(dataContext);if(columnDef.doctype){link+=me.get_link_open_icon(columnDef.doctype,value);}
+if(data[idx+1]&&data[idx+1].indent>data[idx].indent){if(dataContext._collapsed){return spacer+" <span class='toggle expand'></span>&nbsp;"+link;}else{return spacer+" <span class='toggle collapse'></span>&nbsp;"+link;}}else{return spacer+" <span class='toggle'></span>&nbsp;"+link;}},tree_dataview_filter:function(item){var me=wn.cur_grid_report;if(!me.apply_filters(item))return false;var parent=item[me.tree_grid.parent_field];while(parent){if(me.item_by_name[parent]._collapsed){return false;}
+parent=me.parent_map[parent];}
+return true;},set_indent:function(){var me=this;$.each(this.data,function(i,d){var indent=0;var parent=me.parent_map[d.name];if(parent){while(parent){indent++;parent=me.parent_map[parent];}}
+d.indent=indent;});},apply_filters:function(item){var filters=this.filter_inputs;if(item._show)return true;for(i in filters){if(!this.apply_filter(item,i))return false;}
+return true;},apply_filter:function(item,fieldname){var filter=this.filter_inputs[fieldname].get(0);if(filter.opts.filter){if(!filter.opts.filter(this[filter.opts.fieldname],item,filter.opts,this)){return false;}}
+return true;},apply_zero_filter:function(val,item,opts,me){if(!me.show_zero){for(var i=0,j=me.columns.length;i<j;i++){var col=me.columns[i];if(col.formatter==me.currency_formatter&&!col.hidden){if(flt(item[col.field])>0.001||flt(item[col.field])<-0.001){return true;}}}
+return false;}
+return true;},show_zero_check:function(){var me=this;this.wrapper.bind('make',function(){me.wrapper.find('.show-zero').toggle(true).find('input').click(function(){me.refresh();});});},is_default:function(fieldname){return this[fieldname]==this[fieldname+"_default"];},date_formatter:function(row,cell,value,columnDef,dataContext){return dateutil.str_to_user(value);},currency_formatter:function(row,cell,value,columnDef,dataContext){return repl('<div style="text-align: right; %(_style)s">%(value)s</div>',{_style:dataContext._style||"",value:fmt_money(value)});},text_formatter:function(row,cell,value,columnDef,dataContext){return repl('<span style="%(_style)s" title="%(esc_value)s">%(value)s</span>',{_style:dataContext._style||"",esc_value:cstr(value).replace(/"/g,'\"'),value:cstr(value)});},check_formatter:function(row,cell,value,columnDef,dataContext){return repl("<input type='checkbox' data-id='%(id)s' \
+   class='plot-check' %(checked)s>",{"id":dataContext.id,"checked":dataContext.checked?"checked":""})},apply_link_formatters:function(){var me=this;$.each(this.dataview_columns,function(i,col){if(col.link_formatter){col.formatter=function(row,cell,value,columnDef,dataContext){if(!value)return"";var me=wn.cur_grid_report;if(dataContext._show){return repl('<span style="%(_style)s">%(value)s</span>',{_style:dataContext._style||"",value:value});}
+var link_formatter=me.dataview_columns[cell].link_formatter;var html=repl('<a href="#" \
+      onclick="wn.cur_grid_report.filter_inputs.%(col_name)s.val(\'%(value)s\'); \
+       wn.cur_grid_report.set_route(); return false;">\
+      %(value)s</a>',{value:value,col_name:link_formatter.filter_input,page_name:wn.container.page.page_name})
+if(link_formatter.open_btn){html+=me.get_link_open_icon(eval(link_formatter.doctype),value);}
+return html;}}})},get_link_open_icon:function(doctype,name){return repl(' <i class="icon icon-share" style="cursor: pointer;"\
+   onclick="wn.set_route(\'Form\', \'%(doctype)s\', \'%(name)s\');">\
+  </i>',{name:name,doctype:doctype});},make_date_range_columns:function(){this.columns=[];var me=this;var range=this.filter_inputs.range.val();this.from_date=dateutil.user_to_str(this.filter_inputs.from_date.val());this.to_date=dateutil.user_to_str(this.filter_inputs.to_date.val());var date_diff=dateutil.get_diff(this.to_date,this.from_date);me.column_map={};var add_column=function(date){me.columns.push({id:date,name:dateutil.str_to_user(date),field:date,formatter:me.currency_formatter,width:100});}
+var build_columns=function(condition){for(var i=0;i<date_diff;i++){var date=dateutil.add_days(me.from_date,i);if(!condition)condition=function(){return true;}
+if(condition(date))add_column(date);me.last_date=date;if(me.columns.length){me.column_map[date]=me.columns[me.columns.length-1];}}}
+if(range=='Daily'){build_columns();}else if(range=='Weekly'){build_columns(function(date){if(!me.last_date)return true;return!(dateutil.get_diff(date,me.from_date)%7)});}else if(range=='Monthly'){build_columns(function(date){if(!me.last_date)return true;return dateutil.str_to_obj(me.last_date).getMonth()!=dateutil.str_to_obj(date).getMonth()});}else if(range=='Quarterly'){build_columns(function(date){if(!me.last_date)return true;return dateutil.str_to_obj(date).getDate()==1&&in_list([0,3,6,9],dateutil.str_to_obj(date).getMonth())});}else if(range=='Yearly'){build_columns(function(date){if(!me.last_date)return true;return $.map(wn.report_dump.data['Fiscal Year'],function(v){return date==v.year_start_date?true:null;}).length;});}
+$.each(this.columns,function(i,col){col.name=me.columns[i+1]?dateutil.str_to_user(dateutil.add_days(me.columns[i+1].id,-1)):dateutil.str_to_user(me.to_date);});}});wn.views.GridReportWithPlot=wn.views.GridReport.extend({render_plot:function(){var plot_data=this.get_plot_data?this.get_plot_data():null;if(!plot_data){this.plot_area.toggle(false);return;}
+wn.require('js/lib/flot/jquery.flot.js');this.plot=$.plot(this.plot_area.toggle(true),plot_data,this.get_plot_options());this.setup_plot_hover();},setup_plot_check:function(){var me=this;me.wrapper.bind('make',function(){me.wrapper.on("click",".plot-check",function(){var checked=$(this).attr("checked");me.item_by_name[$(this).attr("data-id")].checked=checked?true:false;me.render_plot();});});},setup_plot_hover:function(){var me=this;this.tooltip_id=wn.dom.set_unique_id();function showTooltip(x,y,contents){$('<div id="'+me.tooltip_id+'">'+contents+'</div>').css({position:'absolute',display:'none',top:y+5,left:x+5,border:'1px solid #fdd',padding:'2px','background-color':'#fee',opacity:0.80}).appendTo("body").fadeIn(200);}
 this.previousPoint=null;this.wrapper.find('.plot').bind("plothover",function(event,pos,item){if(item){if(me.previousPoint!=item.dataIndex){me.previousPoint=item.dataIndex;$("#"+me.tooltip_id).remove();showTooltip(item.pageX,item.pageY,me.get_tooltip_text(item.series.label,item.datapoint[0],item.datapoint[1]));}}
 else{$("#"+me.tooltip_id).remove();me.previousPoint=null;}});},get_tooltip_text:function(label,x,y){var date=dateutil.obj_to_user(new Date(x));var value=fmt_money(y);return value+" on "+date;},get_view_data:function(){var res=[];var col_map=$.map(this.columns,function(v){return v.field;});for(var i=0,len=this.dataView.getLength();i<len;i++){var d=this.dataView.getItem(i);var row=[];$.each(col_map,function(i,col){var val=d[col];if(val===null||val===undefined){val=""}
 row.push(val);})
 res.push(row);}
-return res;},options:{editable:false,enableColumnReorder:false},apply_filters:function(item){var filters=this.filter_inputs;if(item._show)return true;for(i in filters){if(!this.apply_filter(item,i))return false;}
-if(this.custom_dataview_filter){return this.custom_dataview_filter(item);}
-return true;},apply_filter:function(item,fieldname){var filter=this.filter_inputs[fieldname].get(0);if(filter.opts.filter){if(!filter.opts.filter(this[filter.opts.fieldname],item,filter.opts,this)){return false;}}
-return true;},apply_zero_filter:function(val,item,opts,me){if(!me.show_zero){for(var i=0,j=me.columns.length;i<j;i++){var col=me.columns[i];if(col.formatter==me.currency_formatter){if(flt(item[col.field])>0.001||flt(item[col.field])<-0.001){return true;}}}
-return false;}
-return true;},show_zero_check:function(){var me=this;this.wrapper.bind('make',function(){me.wrapper.find('.show-zero').toggle(true).find('input').click(function(){me.refresh();});});},is_default:function(fieldname){return this[fieldname]==this[fieldname+"_default"];},date_formatter:function(row,cell,value,columnDef,dataContext){return dateutil.str_to_user(value);},currency_formatter:function(row,cell,value,columnDef,dataContext){return repl('<div style="text-align: right; %(_style)s">%(value)s</div>',{_style:dataContext._style||"",value:fmt_money(value)});},text_formatter:function(row,cell,value,columnDef,dataContext){return repl('<span style="%(_style)s" title="%(esc_value)s">%(value)s</span>',{_style:dataContext._style||"",esc_value:cstr(value).replace(/"/g,'\"'),value:cstr(value)});},check_formatter:function(row,cell,value,columnDef,dataContext){return repl("<input type='checkbox' data-id='%(id)s' \
-   class='plot-check' %(checked)s>",{"id":dataContext.id,"checked":dataContext.checked?"checked":""})},apply_link_formatters:function(){var me=this;$.each(this.dataview_columns,function(i,col){if(col.link_formatter){col.formatter=function(row,cell,value,columnDef,dataContext){if(!value)return"";if(dataContext._show){return repl('<span style="%(_style)s">%(value)s</span>',{_style:dataContext._style||"",value:value});}
-var link_formatter=wn.cur_grid_report.dataview_columns[cell].link_formatter;var html=repl('<a href="#" \
-      onclick="wn.cur_grid_report.filter_inputs.%(col_name)s.val(\'%(value)s\'); \
-       wn.cur_grid_report.set_route(); return false;">\
-      %(value)s</a>',{value:value,col_name:link_formatter.filter_input,page_name:wn.container.page.page_name})
-if(link_formatter.open_btn){html+=repl(' <i class="icon icon-share" style="cursor: pointer;"\
-       onclick="wn.set_route(\'Form\', \'%(doctype)s\', \'%(value)s\');">\
-      </i>',{value:value,doctype:eval(link_formatter.doctype)});}
-return html;}}})}})
+return res;},})
 /*
  *	lib/js/legacy/widgets/dialog.js
  */
diff --git a/public/js/app/account_tree_grid.js b/public/js/app/account_tree_grid.js
index b1e7fb5..56d1c09 100644
--- a/public/js/app/account_tree_grid.js
+++ b/public/js/app/account_tree_grid.js
@@ -11,20 +11,30 @@
 // You should have received a copy of the GNU General Public License
 // along with this program.	If not, see <http://www.gnu.org/licenses/>.
 
-erpnext.AccountTreeGrid = wn.views.GridReport.extend({
+erpnext.AccountTreeGrid = wn.views.GridReportWithPlot.extend({
 	init: function(wrapper, title) {
 		this._super({
 			title: title,
 			page: wrapper,
 			parent: $(wrapper).find('.layout-main'),
 			appframe: wrapper.appframe,
-			doctypes: ["Company", "Fiscal Year", "Account", "GL Entry"]
+			doctypes: ["Company", "Fiscal Year", "Account", "GL Entry"],
+			tree_grid: {
+				show: true, 
+				parent_field: "parent_account", 
+				formatter: function(item) {
+					return repl('<a href="#general-ledger/account=%(enc_value)s">%(value)s</a>', {
+							value: item.name,
+							enc_value: encodeURIComponent(item.name)
+						});
+				}
+			},
 		});
 	},
 	setup_columns: function() {
 		this.columns = [
 			{id: "name", name: "Account", field: "name", width: 300, cssClass: "cell-title", 
-				formatter: this.account_formatter},
+				formatter: this.tree_formatter},
 			{id: "opening_debit", name: "Opening (Dr)", field: "opening_debit", width: 100,
 				formatter: this.currency_formatter},
 			{id: "opening_credit", name: "Opening (Cr)", field: "opening_credit", width: 100,
@@ -72,31 +82,24 @@
 		});
 		me.show_zero_check()
 	},
-	init_filter_values: function() {
-		this.filter_inputs.company.val(sys_defaults.company);
-		this.filter_inputs.fiscal_year.val(sys_defaults.fiscal_year);
-		this.filter_inputs.from_date.val(dateutil.str_to_user(sys_defaults.year_start_date));
-		this.filter_inputs.to_date.val(dateutil.str_to_user(sys_defaults.year_end_date));
-	},
 	prepare_data: function() {
 		var me = this;
-		this.data = []			
-		if(this.accounts) {
+		if(this.data) {
 			// refresh -- only initialize
-			$.each(this.accounts, function(i, d) {
+			$.each(this.data, function(i, d) {
 				me.init_account(d);
 			})
 		} else {
 			// make accounts list
-			me.accounts = [];
+			me.data = [];
 			me.parent_map = {};
-			me.account_by_name = {};
+			me.item_by_name = {};
 
 			$.each(wn.report_dump.data["Account"], function(i, v) {
 				var d = copy_dict(v);
 
-				me.accounts.push(d);
-				me.account_by_name[d.name] = d;
+				me.data.push(d);
+				me.item_by_name[d.name] = d;
 				if(d.parent_account) {
 					me.parent_map[d.name] = d.parent_account;
 				}
@@ -106,18 +109,9 @@
 		}
 		this.set_indent();
 		this.prepare_balances();
-		this.prepare_data_view(this.accounts);
+		
 	},
-	init_account: function(d) {
-		$.extend(d, {
-			"opening_debit": 0,
-			"opening_credit": 0,
-			"debit": 0,
-			"credit": 0,
-			"closing_debit": 0,
-			"closing_credit": 0				
-		});
-	},
+
 	prepare_balances: function() {
 		var gl = wn.report_dump.data['GL Entry'];
 		var me = this;
@@ -127,14 +121,14 @@
 		this.set_fiscal_year();
 		if (!this.fiscal_year) return;
 
-		$.each(this.accounts, function(i, v) {
+		$.each(this.data, function(i, v) {
 			v.opening_debit = v.opening_credit = v.debit 
 				= v.credit = v.closing_debit = v.closing_credit = 0;
 		});
 
 		$.each(gl, function(i, v) {
 			var posting_date = dateutil.str_to_obj(v.posting_date);
-			var account = me.account_by_name[v.account];
+			var account = me.item_by_name[v.account];
 			me.update_balances(account, posting_date, v)
 		});
 
@@ -169,12 +163,12 @@
 	update_groups: function() {
 		// update groups
 		var me= this;
-		$.each(this.accounts, function(i, account) {
+		$.each(this.data, function(i, account) {
 			// update groups
 			if(account.rgt - account.lft == 1) {
 				var parent = me.parent_map[account.name];
 				while(parent) {
-					parent_account = me.account_by_name[parent];
+					parent_account = me.item_by_name[parent];
 					$.each(me.columns, function(c, col) {
 						if (col.formatter == me.currency_formatter) {
 							parent_account[col.field] = 
@@ -208,71 +202,4 @@
 			return;
 		}
 	},
-	set_indent: function() {
-		var me = this;
-		$.each(this.accounts, function(i, d) {
-			var indent = 0;
-			var parent = me.parent_map[d.name];
-			if(parent) {
-				while(parent) {
-					indent++;
-					parent = me.parent_map[parent];
-				}				
-			}
-			d.indent = indent;
-		});
-	},
-	account_formatter: function (row, cell, value, columnDef, dataContext) {
-		value = value.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
-		var data = wn.cur_grid_report.accounts;
-		var spacer = "<span style='display:inline-block;height:1px;width:" + 
-			(15 * dataContext["indent"]) + "px'></span>";
-		var idx = wn.cur_grid_report.dataView.getIdxById(dataContext.id);
-		var account_link = repl('<a href="#general-ledger/account=%(enc_value)s">%(value)s</a>', {
-				value: value,
-				enc_value: encodeURIComponent(value)
-			});
-			
-		if (data[idx + 1] && data[idx + 1].indent > data[idx].indent) {
-			if (dataContext._collapsed) {
-				return spacer + " <span class='toggle expand'></span>&nbsp;" + account_link;
-			} else {
-				return spacer + " <span class='toggle collapse'></span>&nbsp;" + account_link;
-			}
-		} else {
-			return spacer + " <span class='toggle'></span>&nbsp;" + account_link;
-		}
-	},
-	add_grid_events: function() {
-		var me = this;
-		this.grid.onClick.subscribe(function (e, args) {
-			if ($(e.target).hasClass("toggle")) {
-				var item = me.dataView.getItem(args.row);
-				if (item) {
-					if (!item._collapsed) {
-						item._collapsed = true;
-					} else {
-						item._collapsed = false;
-					}
-
-					me.dataView.updateItem(item.id, item);
-				}
-				e.stopImmediatePropagation();
-			}
-		});
-	},
-	dataview_filter: function(item) {
-		if(!wn.cur_grid_report.apply_filters(item)) return false;
-		
-		if (item.parent_account) {
-			var parent = item.parent_account;
-			while (parent) {
-				if (wn.cur_grid_report.account_by_name[parent]._collapsed) {
-					return false;
-				}
-				parent = wn.cur_grid_report.parent_map[parent];
-			}
-		}
-		return true;
-	}		
 });
\ No newline at end of file
diff --git a/public/js/app/account_tree_grid.css b/public/js/app/tree_grid.css
similarity index 100%
rename from public/js/app/account_tree_grid.css
rename to public/js/app/tree_grid.css