stock balance report and inclusion of filter on brand in all stock reports
diff --git a/public/js/stock_grid_report.js b/public/js/stock_grid_report.js
index 6f86e24..2f81999 100644
--- a/public/js/stock_grid_report.js
+++ b/public/js/stock_grid_report.js
@@ -41,12 +41,12 @@
 			var value_diff = (rate * add_qty);
 		
 			if(add_qty)
-				wh.fifo_stack.push([add_qty, sl.incoming_rate, sl.posting_date]);					
+				wh.fifo_stack.push([add_qty, sl.incoming_rate, sl.posting_date]);
 		} else {
 			// outgoing
 					
 			if(is_fifo)	{
-				var value_diff = this.get_fifo_value_diff(wh, sl);				
+				var value_diff = this.get_fifo_value_diff(wh, sl);
 			} else {
 				// average rate for weighted average
 				var rate = (wh.balance_qty.toFixed(2) == 0.00 ? 0 : 
@@ -54,7 +54,7 @@
 			
 				// no change in value if negative qty
 				if((wh.balance_qty + sl.qty).toFixed(2) >= 0.00)
-					var value_diff = (rate * sl.qty);			
+					var value_diff = (rate * sl.qty);
 				else 
 					var value_diff = -wh.balance_value;
 			}
diff --git a/setup/doctype/brand/brand.txt b/setup/doctype/brand/brand.txt
index 3535450..f3078ca 100644
--- a/setup/doctype/brand/brand.txt
+++ b/setup/doctype/brand/brand.txt
@@ -2,28 +2,25 @@
  {
   "owner": "Administrator", 
   "docstatus": 0, 
-  "creation": "2012-03-27 14:36:19", 
+  "creation": "2012-07-03 13:30:03", 
   "modified_by": "Administrator", 
-  "modified": "2012-03-27 14:36:19"
+  "modified": "2012-12-25 13:20:51"
  }, 
  {
-  "section_style": "Simple", 
-  "module": "Setup", 
-  "server_code_error": " ", 
-  "allow_trash": 1, 
-  "doctype": "DocType", 
   "autoname": "field:brand", 
-  "document_type": "Master", 
   "name": "__common__", 
-  "colour": "White:FFF", 
-  "show_in_menu": 0, 
-  "version": 5
+  "doctype": "DocType", 
+  "module": "Setup", 
+  "in_dialog": 1, 
+  "document_type": "Master"
  }, 
  {
+  "read_only": 0, 
   "name": "__common__", 
   "parent": "Brand", 
   "doctype": "DocField", 
   "parenttype": "DocType", 
+  "permlevel": 0, 
   "parentfield": "fields"
  }, 
  {
@@ -32,6 +29,7 @@
   "read": 1, 
   "doctype": "DocPerm", 
   "parenttype": "DocType", 
+  "permlevel": 0, 
   "parentfield": "permissions"
  }, 
  {
@@ -39,79 +37,13 @@
   "doctype": "DocType"
  }, 
  {
-  "create": 1, 
-  "doctype": "DocPerm", 
-  "write": 1, 
-  "role": "System Manager", 
-  "cancel": 1, 
-  "permlevel": 0
- }, 
- {
-  "create": 1, 
-  "doctype": "DocPerm", 
-  "write": 1, 
-  "role": "Material Master Manager", 
-  "cancel": 1, 
-  "permlevel": 0
- }, 
- {
-  "amend": 0, 
-  "create": 0, 
-  "doctype": "DocPerm", 
-  "submit": 0, 
-  "write": 0, 
-  "role": "Material Manager", 
-  "cancel": 0, 
-  "permlevel": 1
- }, 
- {
-  "amend": 0, 
-  "create": 0, 
-  "doctype": "DocPerm", 
-  "submit": 0, 
-  "write": 0, 
-  "role": "Material Manager", 
-  "cancel": 0, 
-  "permlevel": 0
- }, 
- {
-  "amend": 0, 
-  "create": 0, 
-  "doctype": "DocPerm", 
-  "submit": 0, 
-  "write": 0, 
-  "role": "Material User", 
-  "cancel": 0, 
-  "permlevel": 1
- }, 
- {
-  "amend": 0, 
-  "create": 0, 
-  "doctype": "DocPerm", 
-  "submit": 0, 
-  "write": 0, 
-  "role": "Material User", 
-  "cancel": 0, 
-  "permlevel": 0
- }, 
- {
-  "oldfieldtype": "Small Text", 
-  "doctype": "DocField", 
-  "label": "Trash Reason", 
-  "oldfieldname": "trash_reason", 
-  "fieldname": "trash_reason", 
-  "fieldtype": "Small Text", 
-  "permlevel": 1
- }, 
- {
   "oldfieldtype": "Data", 
   "doctype": "DocField", 
   "label": "Brand Name", 
   "oldfieldname": "brand", 
   "fieldname": "brand", 
   "fieldtype": "Data", 
-  "reqd": 1, 
-  "permlevel": 0
+  "reqd": 1
  }, 
  {
   "oldfieldtype": "Text", 
@@ -120,7 +52,22 @@
   "oldfieldname": "description", 
   "width": "300px", 
   "fieldname": "description", 
-  "fieldtype": "Text", 
-  "permlevel": 0
+  "fieldtype": "Text"
+ }, 
+ {
+  "create": 1, 
+  "doctype": "DocPerm", 
+  "write": 1, 
+  "role": "Material Master Manager", 
+  "cancel": 1
+ }, 
+ {
+  "amend": 0, 
+  "create": 0, 
+  "doctype": "DocPerm", 
+  "submit": 0, 
+  "write": 0, 
+  "role": "Material User", 
+  "cancel": 0
  }
 ]
\ No newline at end of file
diff --git a/startup/report_data_map.py b/startup/report_data_map.py
index 1ea9d13..b07ded5 100644
--- a/startup/report_data_map.py
+++ b/startup/report_data_map.py
@@ -66,6 +66,7 @@
 		"order_by": "name",
 		"links": {
 			"parent_item_group": ["Item Group", "name"],
+			"brand": ["Brand", "name"]
 		}
 	},
 	"Item Group": {
@@ -73,6 +74,11 @@
 		"conditions": ["docstatus < 2"],
 		"order_by": "lft"
 	},
+	"Brand": {
+		"columns": ["name"],
+		"conditions": ["docstatus < 2"],
+		"order_by": "name"
+	},
 	"Warehouse": {
 		"columns": ["name"],
 		"conditions": ["docstatus < 2"],
@@ -89,6 +95,11 @@
 		},
 		"force_index": "posting_sort_index"		
 	},
+	"Stock Entry": {
+		"columns": ["name", "purpose"],
+		"conditions": ["docstatus=1"],
+		"order_by": "posting_date, posting_time, name",
+	},
 
 	# Sales
 	"Customer": {
diff --git a/stock/page/stock_ageing/stock_ageing.js b/stock/page/stock_ageing/stock_ageing.js
index c20fa92..7809ab9 100644
--- a/stock/page/stock_ageing/stock_ageing.js
+++ b/stock/page/stock_ageing/stock_ageing.js
@@ -38,7 +38,7 @@
 			page: wrapper,
 			parent: $(wrapper).find('.layout-main'),
 			appframe: wrapper.appframe,
-			doctypes: ["Item", "Warehouse", "Stock Ledger Entry", "Item Group"],
+			doctypes: ["Item", "Warehouse", "Stock Ledger Entry", "Item Group", "Brand"],
 		})
 	},
 	setup_columns: function() {
@@ -48,6 +48,7 @@
 					open_btn: true,
 					doctype: '"Item"'
 				}},
+			{id: "brand", name: "Brand", field: "brand", width: 100},
 			{id: "average_age", name: "Average Age", field: "average_age",
 				formatter: this.currency_formatter},
 			{id: "earliest", name: "Earliest", field: "earliest",
@@ -59,6 +60,10 @@
 	filters: [
 		{fieldtype:"Select", label: "Warehouse", link:"Warehouse", 
 			default_value: "Select Warehouse..."},
+		{fieldtype:"Select", label: "Brand", link:"Brand", 
+			default_value: "Select Brand...", filter: function(val, item, opts) {
+				return val == opts.default_value || item.brand == val;
+			}},
 		{fieldtype:"Select", label: "Plot By", 
 			options: ["Average Age", "Earliest", "Latest"]},
 		{fieldtype:"Date", label: "To Date"},
@@ -68,13 +73,7 @@
 	setup_filters: function() {
 		var me = this;
 		this._super();
-		
-		this.filter_inputs.warehouse.change(function() {
-			me.filter_inputs.refresh.click();
-		});
-		this.filter_inputs.plot_by.change(function() {
-			me.filter_inputs.refresh.click();
-		});
+		this.trigger_refresh_on_change(["warehouse", "plot_by", "brand"]);
 	},
 	init_filter_values: function() {
 		this._super();
@@ -84,15 +83,22 @@
 		var me = this;
 				
 		if(!this.data) {
-			me.data = wn.report_dump.data["Item"];
-			me.item_by_name = me.make_name_map(me.data);
+			me._data = wn.report_dump.data["Item"];
+			me.item_by_name = me.make_name_map(me._data);
 		}
 		
+		this.data = [].concat(this._data);
+		
 		$.each(this.data, function(i, d) {
 			me.reset_item_values(d);
 		});
 		
-		this.prepare_balances();		
+		this.prepare_balances();
+		
+		// filter out brand
+		this.data = $.map(this.data, function(d) {
+			return me.apply_filter(d, "brand") ? d : null;
+		});
 	},
 	prepare_balances: function() {
 		var me = this;
@@ -123,7 +129,7 @@
 					full_fifo_stack = full_fifo_stack.concat(wh.fifo_stack || [])
 				});
 			} else {
-				full_fifo_stack = me.get_item_warehouse(me.warehouse, item.name) || [];			
+				full_fifo_stack = me.get_item_warehouse(me.warehouse, item.name).fifo_stack || [];
 			}
 			
 			var age_qty = total_qty = 0.0;
diff --git a/stock/page/stock_analytics/stock_analytics.js b/stock/page/stock_analytics/stock_analytics.js
index 3448035..03b2c73 100644
--- a/stock/page/stock_analytics/stock_analytics.js
+++ b/stock/page/stock_analytics/stock_analytics.js
@@ -14,41 +14,55 @@
 // You should have received a copy of the GNU General Public License
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-wn.pages['stock-analytics'].onload = function(wrapper) { 
-	wn.ui.make_app_page({
-		parent: wrapper,
-		title: 'Stock Analytics',
-		single_column: true
-	});
-	
-	new erpnext.StockAnalytics(wrapper);
-	
-	wrapper.appframe.add_home_breadcrumb()
-	wrapper.appframe.add_module_breadcrumb("Stock")
-	wrapper.appframe.add_breadcrumb("icon-bar-chart")
-}
-
 wn.require("app/js/stock_grid_report.js");
 
+// done so that it doesn't throw error when inherited in stock-balance report
+if(wn.pages["stock-analytics"]) {
+	wn.pages['stock-analytics'].onload = function(wrapper) { 
+		wn.ui.make_app_page({
+			parent: wrapper,
+			title: 'Stock Analytics',
+			single_column: true
+		});
+
+		new erpnext.StockAnalytics(wrapper);
+
+		wrapper.appframe.add_home_breadcrumb()
+		wrapper.appframe.add_module_breadcrumb("Stock")
+		wrapper.appframe.add_breadcrumb("icon-bar-chart")
+	}
+}
+
 erpnext.StockAnalytics = erpnext.StockGridReport.extend({
-	init: function(wrapper) {
-		this._super({
+	init: function(wrapper, opts) {
+		var args = {
 			title: "Stock Analytics",
 			page: wrapper,
 			parent: $(wrapper).find('.layout-main'),
 			appframe: wrapper.appframe,
-			doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry", "Fiscal Year"],
+			doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry", "Brand", 
+				"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)
-						});
+					if(!item.is_group) {
+						return repl('<a href="#stock-ledger/item_code=%(enc_value)s">%(value)s</a>',
+							{
+								value: item.name,
+								enc_value: encodeURIComponent(item.name)
+							});
+					} else {
+						return item.name;
+					}
+					
 				}
-			},		
-		})
+			},
+		}
+		
+		if(opts) $.extend(args, opts);
+		
+		this._super(args);
 	},
 	setup_columns: function() {
 		var std_columns = [
@@ -56,11 +70,12 @@
 				formatter: this.check_formatter},
 			{id: "name", name: "Item", field: "name", width: 300,
 				formatter: this.tree_formatter},
+			{id: "brand", name: "Brand", field: "brand", width: 200},
 			{id: "opening", name: "Opening", field: "opening", hidden: true,
 				formatter: this.currency_formatter}
 		];
 
-		this.make_date_range_columns();		
+		this.make_date_range_columns();
 		this.columns = std_columns.concat(this.columns);
 	},
 	filters: [
@@ -69,10 +84,12 @@
 			filter: function(val, item, opts, me) {
 				return me.apply_zero_filter(val, item, opts, me);
 			}},
+		{fieldtype:"Select", label: "Brand", link:"Brand", 
+			default_value: "Select Brand...", filter: function(val, item, opts) {
+				return val == opts.default_value || item.brand == val || item._show;
+			}},
 		{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"},
@@ -84,28 +101,15 @@
 	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.trigger_refresh_on_change(["value_or_qty", "brand", "warehouse", "range"]);
 
-		this.show_zero_check()		
+		this.show_zero_check();
 		this.setup_plot_check();
 	},
 	init_filter_values: function() {
 		this._super();
-		this.filter_inputs.range.val('Monthly');
+		this.filter_inputs.range && this.filter_inputs.range.val('Monthly');
 	},
 	prepare_data: function() {
 		var me = this;
@@ -153,7 +157,7 @@
 			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) {			
+			if(me.is_default("warehouse") ? true : me.warehouse == sl.warehouse) {
 				var item = me.item_by_name[sl.item_code];
 				
 				if(me.value_or_qty!="Quantity") {
@@ -179,7 +183,7 @@
 
 		$.each(this.data, function(i, item) {
 			// update groups
-			if(!item.is_group) {
+			if(!item.is_group && me.apply_filter(item, "brand")) {
 				var balance = item.opening;
 				$.each(me.columns, function(i, col) {
 					if(col.formatter==me.currency_formatter && !col.hidden) {
@@ -199,7 +203,7 @@
 						}
 					});
 					parent = me.parent_map[parent];
-				}				
+				}
 			}
 		});
 	},
diff --git a/stock/page/stock_balance/__init__.py b/stock/page/stock_balance/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/stock/page/stock_balance/__init__.py
diff --git a/stock/page/stock_balance/stock_balance.js b/stock/page/stock_balance/stock_balance.js
new file mode 100644
index 0000000..7268aca
--- /dev/null
+++ b/stock/page/stock_balance/stock_balance.js
@@ -0,0 +1,162 @@
+// ERPNext - web based ERP (http://erpnext.com)
+// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
+// 
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+wn.require("../app/stock/page/stock_analytics/stock_analytics.js");
+
+wn.pages['stock-balance'].onload = function(wrapper) { 
+	wn.ui.make_app_page({
+		parent: wrapper,
+		title: 'Stock Balance',
+		single_column: true
+	});
+	
+	new erpnext.StockBalance(wrapper);
+	
+	wrapper.appframe.add_home_breadcrumb()
+	wrapper.appframe.add_module_breadcrumb("Stock")
+	wrapper.appframe.add_breadcrumb("icon-bar-chart")
+}
+
+erpnext.StockBalance = erpnext.StockAnalytics.extend({
+	init: function(wrapper) {
+		this._super(wrapper, {
+			title: "Stock Balance",
+			doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry", "Brand",
+				"Stock Entry"],
+		});
+	},
+	setup_columns: function() {
+		this.columns = [
+			{id: "name", name: "Item", field: "name", width: 300,
+				formatter: this.tree_formatter},
+			{id: "brand", name: "Brand", field: "brand", width: 100},
+			{id: "opening", name: "Opening", field: "opening",
+				formatter: this.currency_formatter},
+			{id: "inflow", name: "In", field: "inflow",
+				formatter: this.currency_formatter},
+			{id: "outflow", name: "Out", field: "outflow",
+				formatter: this.currency_formatter},
+			{id: "closing", name: "Closing", field: "closing",
+				formatter: this.currency_formatter},
+		];
+	},
+	
+	filters: [
+		{fieldtype:"Select", label: "Value or Qty", options:["Value (Weighted Average)", 
+			"Value (FIFO)", "Quantity"],
+			filter: function(val, item, opts, me) {
+				return me.apply_zero_filter(val, item, opts, me);
+			}},
+		{fieldtype:"Select", label: "Brand", link:"Brand", 
+			default_value: "Select Brand...", filter: function(val, item, opts) {
+				return val == opts.default_value || item.brand == val || item._show;
+			}},
+		{fieldtype:"Select", label: "Warehouse", link:"Warehouse", 
+			default_value: "Select Warehouse..."},
+		{fieldtype:"Date", label: "From Date"},
+		{fieldtype:"Label", label: "To"},
+		{fieldtype:"Date", label: "To Date"},
+		{fieldtype:"Button", label: "Refresh", icon:"icon-refresh icon-white", cssClass:"btn-info"},
+		{fieldtype:"Button", label: "Reset Filters"}
+	],
+	
+	setup_plot_check: function() {
+		return;
+	},
+	
+	prepare_data: function() {
+		this.stock_entry_map = this.make_name_map(wn.report_dump.data["Stock Entry"], "name");
+		this._super();
+	},
+	
+	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"];
+
+		this.item_warehouse = {};
+
+		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];
+				
+				if(me.value_or_qty!="Quantity") {
+					var wh = me.get_item_warehouse(sl.warehouse, sl.item_code);
+					var is_fifo = this.value_or_qty== "Value (FIFO)";
+					var diff = me.get_value_diff(wh, sl, is_fifo);
+				} else {
+					var diff = sl.qty;
+				}
+
+				if(posting_datetime < from_date) {
+					item.opening += diff;
+				} else if(posting_datetime <= to_date) {
+					var ignore_inflow_outflow = this.is_default("warehouse")
+						&& item.voucher_type=="Stock Entry" 
+						&& this.stock_entry_map[item.voucher_no].purpose=="Material Transfer";
+					
+					if(!ignore_inflow_outflow) {
+						if(diff < 0) {
+							item.outflow += Math.abs(diff);
+						} else {
+							item.inflow += diff;
+						}
+					}
+					
+					item.closing += diff;
+				} else {
+					break;
+				}
+			}
+		}
+	},
+	
+	update_groups: function() {
+		var me = this;
+
+		$.each(this.data, function(i, item) {
+			// update groups
+			if(!item.is_group && me.apply_filter(item, "brand")) {
+				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]);
+						}
+					});
+					
+					// show parent if filtered by brand
+					if(item.brand == me.brand)
+						parent_group._show = true;
+					
+					parent = me.parent_map[parent];
+				}
+			}
+		});
+	},
+	
+	get_plot_data: function() {
+		return;
+	}
+});
\ No newline at end of file
diff --git a/stock/page/stock_balance/stock_balance.txt b/stock/page/stock_balance/stock_balance.txt
new file mode 100644
index 0000000..0f8e7fa
--- /dev/null
+++ b/stock/page/stock_balance/stock_balance.txt
@@ -0,0 +1,21 @@
+[
+ {
+  "owner": "Administrator", 
+  "docstatus": 0, 
+  "creation": "2012-12-25 13:02:32", 
+  "modified_by": "Administrator", 
+  "modified": "2012-12-25 13:02:32"
+ }, 
+ {
+  "name": "__common__", 
+  "title": "Stock Balance", 
+  "doctype": "Page", 
+  "module": "Stock", 
+  "standard": "Yes", 
+  "page_name": "stock-balance"
+ }, 
+ {
+  "name": "stock-balance", 
+  "doctype": "Page"
+ }
+]
\ No newline at end of file
diff --git a/stock/page/stock_home/stock_home.html b/stock/page/stock_home/stock_home.html
index b89b0d0..7e43e99 100644
--- a/stock/page/stock_home/stock_home.html
+++ b/stock/page/stock_home/stock_home.html
@@ -29,6 +29,11 @@
 			</h5>
 			<p class="help">Log of stock movements</p>
 			<br>
+			<h5><a href="#stock-balance" data-role="Analytics, Material Manager">
+					Stock Balance</a>
+			</h5>
+			<p class="help">Inflow, outflow and balance of stock</p>
+			<br>
 			<h5><a href="#stock-analytics" data-role="Analytics, Material Manager">
 					Stock Analytics</a>
 			</h5>
diff --git a/stock/page/stock_ledger/stock_ledger.js b/stock/page/stock_ledger/stock_ledger.js
index 3287bb0..e0cfd02 100644
--- a/stock/page/stock_ledger/stock_ledger.js
+++ b/stock/page/stock_ledger/stock_ledger.js
@@ -37,7 +37,7 @@
 			page: wrapper,
 			parent: $(wrapper).find('.layout-main'),
 			appframe: wrapper.appframe,
-			doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry"]			
+			doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry", "Brand"],
 		})
 	},
 
@@ -54,6 +54,7 @@
 				}},
 			{id: "warehouse", name: "Warehouse", field: "warehouse", width: 100,
 				link_formatter: {filter_input: "warehouse"}},
+			{id: "brand", name: "Brand", field: "brand", width: 100},
 			{id: "qty", name: "Qty", field: "qty", width: 100,
 				formatter: this.currency_formatter},
 			{id: "balance", name: "Balance Qty", field: "balance", width: 100,
@@ -74,14 +75,18 @@
 		
 	},
 	filters: [
-		{fieldtype:"Select", label: "Warehouse", link:"Warehouse", default_value: "Select Warehouse...",
-			filter: function(val, item, opts) {
+		{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:"Select", label: "Brand", link:"Brand", 
+			default_value: "Select Brand...", filter: function(val, item, opts) {
+				return val == opts.default_value || item.brand == val || item._show;
+			}},
 		{fieldtype:"Data", label: "Voucher No",
 			filter: function(val, item, opts) {
 				if(!val) return true;
@@ -97,6 +102,28 @@
 		{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.wrapper.bind("apply_filters_from_route", function() { me.toggle_enable_brand(); });
+		this.filter_inputs.item_code.change(function() { me.toggle_enable_brand(); });
+		
+		this.trigger_refresh_on_change(["item_code", "warehouse", "brand"]);
+	},
+	
+	toggle_enable_brand: function() {
+		if(this.filter_inputs.item_code.val() ==
+				this.filter_inputs.item_code.get(0).opts.default_value) {
+			this.filter_inputs.brand.removeAttr("disabled");
+		} else {
+			this.filter_inputs.brand
+				.val(this.filter_inputs.brand.get(0).opts.default_value)
+				.attr("disabled", "disabled");
+		}
+	},
+	
 	init_filter_values: function() {
 		this._super();
 		this.filter_inputs.warehouse.get(0).selectedIndex = 0;
@@ -136,6 +163,7 @@
 			var wh = me.get_item_warehouse(sl.warehouse, sl.item_code);
 			sl.description = item.description;
 			sl.posting_datetime = sl.posting_date + " " + sl.posting_time;
+			sl.brand = item.brand;
 			var posting_datetime = dateutil.str_to_obj(sl.posting_datetime);
 			
 			var is_fifo = item.valuation_method ? item.valuation_method=="FIFO" 
@@ -145,7 +173,8 @@
 			// 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")) {
+				&& me.apply_filter(sl, "warehouse") && me.apply_filter(sl, "voucher_no")
+				&& me.apply_filter(sl, "brand")) {
 				if(posting_datetime < dateutil.str_to_obj(me.from_date)) {
 					opening.balance += sl.qty;
 					opening.balance_value += value_diff;