[refacator] added dashboard in item
diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index 16e7488..ab0f673 100644
--- a/erpnext/public/build.json
+++ b/erpnext/public/build.json
@@ -19,8 +19,11 @@
 		"public/js/pos/pos_item.html",
 		"public/js/pos/pos_tax_row.html",
 		"public/js/pos/pos.js",
-		"public/js/utils/item_selector.js",
-		"public/js/utils/inventory.js",
 		"public/js/templates/item_selector.html"
+	],
+	"js/item-dashboard.min.js": [
+		"stock/dashboard/item_dashboard.html",
+		"stock/dashboard/item_dashboard_list.html",
+		"stock/dashboard/item_dashboard.js"
 	]
 }
diff --git a/erpnext/public/css/erpnext.css b/erpnext/public/css/erpnext.css
index 75fab56..6777e1e 100644
--- a/erpnext/public/css/erpnext.css
+++ b/erpnext/public/css/erpnext.css
@@ -107,7 +107,7 @@
 }
 .erpnext-icon {
   width: 24px;
-  margin-right: 0px;
+  ackmargin-right: 0px;
   margin-top: -3px;
 }
 .pos .discount-amount-area .discount-field-col {
@@ -116,3 +116,11 @@
 .pos .discount-amount-area .input-group {
   margin-top: 2px;
 }
+.dashboard-list-item {
+  background-color: inherit;
+  padding: 7px 15px;
+  border-bottom: 1px solid #d1d8dd;
+}
+.dashboard-list-item:last-child {
+  border-bottom: none;
+}
diff --git a/erpnext/public/js/utils/inventory.js b/erpnext/public/js/utils/inventory.js
deleted file mode 100644
index 80cd6a5..0000000
--- a/erpnext/public/js/utils/inventory.js
+++ /dev/null
@@ -1,77 +0,0 @@
-erpnext.get_item_dashboard_data = function(data, max_count, show_item) {
-	if(!max_count) max_count = 0;
-	data.forEach(function(d) {
-		d.actual_or_pending = d.projected_qty + d.reserved_qty + d.reserved_qty_for_production;
-		d.pending_qty = 0;
-		d.total_reserved = d.reserved_qty + d.reserved_qty_for_production;
-		if(d.actual_or_pending > d.actual_qty) {
-			d.pending_qty = d.actual_or_pending - d.actual_qty;
-		}
-
-		max_count = Math.max(d.actual_or_pending, d.actual_qty,
-			d.total_reserved, max_count);
-	});
-	return {
-		data: data,
-		max_count: max_count,
-		show_item: show_item || false
-	}
-}
-
-frappe.provide('erpnext.inventory');
-
-erpnext.inventory.move_item = function(item, source, target, actual_qty, callback) {
-	var dialog = new frappe.ui.Dialog({
-		title: target ? __('Add Item') : __('Move Item'),
-		fields: [
-			{fieldname: 'item_code', label: __('Item'),
-				fieldtype: 'Link', options: 'Item', read_only: 1},
-			{fieldname: 'source', label: __('Source Warehouse'),
-				fieldtype: 'Link', options: 'Warehouse', read_only: 1},
-			{fieldname: 'target', label: __('Target Warehouse'),
-				fieldtype: 'Link', options: 'Warehouse', reqd: 1},
-			{fieldname: 'qty', label: __('Quantity'), reqd: 1,
-				fieldtype: 'Float', description: __('Available {0}', [actual_qty]) },
-		],
-	})
-	dialog.show();
-	dialog.get_field('item_code').set_input(item);
-
-	if(source) {
-		dialog.get_field('source').set_input(source);
-	} else {
-		dialog.get_field('source').df.hidden = 1;
-		dialog.get_field('source').refresh();
-	}
-
-	if(target) {
-		dialog.get_field('target').df.read_only = 1;
-		dialog.get_field('target').value = target;
-		dialog.get_field('target').refresh();
-	}
-
-	dialog.set_primary_action(__('Submit'), function() {
-		values = dialog.get_values();
-		if(!values) {
-			return;
-		}
-		if(source && values.qty > actual_qty) {
-			frappe.msgprint(__('Quantity must be less than or equal to {0}', [actual_qty]));
-			return;
-		}
-		if(values.source === values.target) {
-			frappe.msgprint(__('Source and target warehouse must be different'));
-		}
-
-		frappe.call({
-			method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
-			args: values,
-			callback: function(r) {
-				frappe.show_alert(__('Stock Entry {0} created',
-					['<a href="#Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
-				dialog.hide();
-				callback(r);
-			},
-		});
-	});
-}
\ No newline at end of file
diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less
index 23ee841..58e8e62 100644
--- a/erpnext/public/less/erpnext.less
+++ b/erpnext/public/less/erpnext.less
@@ -132,7 +132,7 @@
 }
 
 .erpnext-icon {
-	width: 24px;
+	width: 24px;ack
 	margin-right: 0px;
 	margin-top: -3px;
 }
@@ -145,4 +145,14 @@
 	.input-group {
 		margin-top: 2px;
 	}
-}
\ No newline at end of file
+}
+
+.dashboard-list-item {
+	background-color: inherit;
+	padding: 7px 15px;
+	border-bottom: 1px solid @border-color;
+}
+
+.dashboard-list-item:last-child {
+	border-bottom: none;
+}
diff --git a/erpnext/stock/dashboard/__init__.py b/erpnext/stock/dashboard/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/stock/dashboard/__init__.py
diff --git a/erpnext/stock/dashboard/item_dashboard.html b/erpnext/stock/dashboard/item_dashboard.html
new file mode 100644
index 0000000..1e18969
--- /dev/null
+++ b/erpnext/stock/dashboard/item_dashboard.html
@@ -0,0 +1,7 @@
+<div>
+	<div class="result">
+	</div>
+	<div class="more hidden" style="padding: 15px;">
+		<a class="btn btn-default btn-xs btn-more">More</a>
+	</div>
+</div>
\ No newline at end of file
diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js
new file mode 100644
index 0000000..86cc0f2
--- /dev/null
+++ b/erpnext/stock/dashboard/item_dashboard.js
@@ -0,0 +1,162 @@
+frappe.provide('erpnext.stock');
+
+erpnext.stock.ItemDashboard = Class.extend({
+	init: function(opts) {
+		$.extend(this, opts);
+		this.make();
+	},
+	make: function() {
+		var me = this;
+		this.start = 0;
+		if(!this.sort_by) {
+			this.sort_by = 'projected_qty';
+			this.sort_order = 'asc';
+		}
+
+		this.content = $(frappe.render_template('item_dashboard')).appendTo(this.parent);
+		this.result = this.content.find('.result');
+
+		// move
+		this.content.on('click', '.btn-move', function() {
+			erpnext.stock.move_item($(this).attr('data-item'), $(this).attr('data-warehouse'),
+				null, $(this).attr('data-actual_qty'), null, function() { me.refresh(); });
+		});
+
+		this.content.on('click', '.btn-add', function() {
+			erpnext.stock.move_item($(this).attr('data-item'), null, $(this).attr('data-warehouse'),
+				$(this).attr('data-actual_qty'), $(this).attr('data-rate'),
+				function() { me.refresh(); });
+		});
+
+		// more
+		this.content.find('.btn-more').on('click', function() {
+			me.start += 20;
+			me.refresh();
+		});
+
+	},
+	refresh: function() {
+		if(this.before_refresh) {
+			this.before_refresh();
+		}
+
+		var me = this;
+		frappe.call({
+			method: 'erpnext.stock.dashboard.item_dashboard.get_data',
+			args: {
+				item_code: this.item_code,
+				warehouse: this.warehouse,
+				start: this.start,
+				sort_by: this.sort_by,
+				sort_order: this.sort_order,
+			},
+			callback: function(r) {
+				me.render(r.message);
+			}
+		});
+	},
+	render: function(data) {
+		if(this.start===0) {
+			this.max_count = 0;
+			this.result.empty();
+		}
+
+		var context = this.get_item_dashboard_data(data, this.max_count, true);
+		this.max_count = this.max_count;
+
+		// show more button
+		if(data.length===21) {
+			this.content.find('.more').removeClass('hidden');
+
+			// remove the last element
+			data.splice(-1);
+		} else {
+			this.content.find('.more').addClass('hidden');
+		}
+
+		$(frappe.render_template('item_dashboard_list', context)).appendTo(this.result);
+
+	},
+	get_item_dashboard_data: function(data, max_count, show_item) {
+		if(!max_count) max_count = 0;
+		data.forEach(function(d) {
+			d.actual_or_pending = d.projected_qty + d.reserved_qty + d.reserved_qty_for_production;
+			d.pending_qty = 0;
+			d.total_reserved = d.reserved_qty + d.reserved_qty_for_production;
+			if(d.actual_or_pending > d.actual_qty) {
+				d.pending_qty = d.actual_or_pending - d.actual_qty;
+			}
+
+			max_count = Math.max(d.actual_or_pending, d.actual_qty,
+				d.total_reserved, max_count);
+		});
+		return {
+			data: data,
+			max_count: max_count,
+			show_item: show_item || false
+		}
+	}
+})
+
+erpnext.stock.move_item = function(item, source, target, actual_qty, rate, callback) {
+	var dialog = new frappe.ui.Dialog({
+		title: target ? __('Add Item') : __('Move Item'),
+		fields: [
+			{fieldname: 'item_code', label: __('Item'),
+				fieldtype: 'Link', options: 'Item', read_only: 1},
+			{fieldname: 'source', label: __('Source Warehouse'),
+				fieldtype: 'Link', options: 'Warehouse', read_only: 1},
+			{fieldname: 'target', label: __('Target Warehouse'),
+				fieldtype: 'Link', options: 'Warehouse', reqd: 1},
+			{fieldname: 'qty', label: __('Quantity'), reqd: 1,
+				fieldtype: 'Float', description: __('Available {0}', [actual_qty]) },
+			{fieldname: 'rate', label: __('Rate'), fieldtype: 'Currency', hidden: 1 },
+		],
+	})
+	dialog.show();
+	dialog.get_field('item_code').set_input(item);
+
+	if(source) {
+		dialog.get_field('source').set_input(source);
+	} else {
+		dialog.get_field('source').df.hidden = 1;
+		dialog.get_field('source').refresh();
+	}
+
+	if(rate) {
+		dialog.get_field('rate').set_value('rate');
+		dialog.get_field('rate').df.hidden = 0;
+		dialog.get_field('rate').refresh();
+	}
+
+	if(target) {
+		dialog.get_field('target').df.read_only = 1;
+		dialog.get_field('target').value = target;
+		dialog.get_field('target').refresh();
+	}
+
+	dialog.set_primary_action(__('Submit'), function() {
+		values = dialog.get_values();
+		if(!values) {
+			return;
+		}
+		if(source && values.qty > actual_qty) {
+			frappe.msgprint(__('Quantity must be less than or equal to {0}', [actual_qty]));
+			return;
+		}
+		if(values.source === values.target) {
+			frappe.msgprint(__('Source and target warehouse must be different'));
+		}
+
+		frappe.call({
+			method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
+			args: values,
+			callback: function(r) {
+				frappe.show_alert(__('Stock Entry {0} created',
+					['<a href="#Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
+				dialog.hide();
+				callback(r);
+			},
+		});
+	});
+}
\ No newline at end of file
diff --git a/erpnext/stock/page/stock_balance/stock_balance.py b/erpnext/stock/dashboard/item_dashboard.py
similarity index 92%
rename from erpnext/stock/page/stock_balance/stock_balance.py
rename to erpnext/stock/dashboard/item_dashboard.py
index e96f925..5a00b3d 100644
--- a/erpnext/stock/page/stock_balance/stock_balance.py
+++ b/erpnext/stock/dashboard/item_dashboard.py
@@ -10,5 +10,5 @@
 	if warehouse:
 		filters['warehouse'] = warehouse
 	return frappe.get_list("Bin", filters=filters, fields=['item_code', 'warehouse',
-		'projected_qty', 'reserved_qty', 'reserved_qty_for_production', 'actual_qty'],
+		'projected_qty', 'reserved_qty', 'reserved_qty_for_production', 'actual_qty', 'valuation_rate'],
 		order_by='{0} {1}'.format(sort_by, sort_order), start=start, page_length = 21)
\ No newline at end of file
diff --git a/erpnext/stock/doctype/item/item_dashboard.html b/erpnext/stock/dashboard/item_dashboard_list.html
similarity index 92%
rename from erpnext/stock/doctype/item/item_dashboard.html
rename to erpnext/stock/dashboard/item_dashboard_list.html
index 813aef3..f9ffbb3 100644
--- a/erpnext/stock/doctype/item/item_dashboard.html
+++ b/erpnext/stock/dashboard/item_dashboard_list.html
@@ -1,5 +1,5 @@
 {% for d in data %}
-	<li class="list-group-item" style="background-color: inherit;">
+	<div class="dashboard-list-item">
 		<div class="row">
 			<div class="col-sm-3 small" style="margin-top: 8px;">
 				<a data-type="warehouse" data-name="{{ d.warehouse }}">{{ d.warehouse }}</a>
@@ -47,8 +47,9 @@
 				<button style="margin-left: 7px;" class="btn btn-default btn-xs btn-add"
 					data-warehouse="{{ d.warehouse }}"
 					data-actual_qty="{{ d.actual_qty }}"
-					data-item="{{ d.item_code }}">{{ __("Add") }}</a>
+					data-item="{{ d.item_code }}"
+					data-rate="{{ d.valuation_rate }}">{{ __("Add") }}</a>
 			</div>
 		</div>
-	</li>
+	</div>
 {% endfor %}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index 2cde790..050f583 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -2,6 +2,7 @@
 // License: GNU General Public License v3. See license.txt
 
 frappe.provide("erpnext.item");
+frappe.require('assets/js/item-dashboard.min.js');
 
 frappe.ui.form.on("Item", {
 	onload: function(frm) {
@@ -41,6 +42,7 @@
 
 		// make sensitive fields(has_serial_no, is_stock_item, valuation_method)
 		// read only if any stock ledger entry exists
+
 		erpnext.item.make_dashboard(frm);
 
 		// clear intro
@@ -80,15 +82,14 @@
 		frm.dashboard.heatmap_message = __('This is based on stock movement. See {0} for details',
 			['<a href="#query-report/Stock Ledger">' + __('Stock Ledger') + '</a>']);
 		frm.dashboard.show_dashboard();
-	},
 
-	dashboard_update: function(frm) {
-		if(frm.dashboard_data.stock_data && frm.dashboard_data.stock_data.length) {
-			var context = erpnext.get_item_dashboard_data(frm.dashboard_data.stock_data, 0);
-			frm.dashboard.add_section('<h5 style="margin-top: 0px;">Stock Levels</h5>\
-				<ul class="list-group">' + frappe.render_template('item_dashboard', context), true)
-				+ '</ul>';
-		}
+		var section = frm.dashboard.add_section('<h5 style="margin-top: 0px;">Stock Levels</h5>');
+		erpnext.item.item_dashboard = new erpnext.stock.ItemDashboard({
+			parent: section,
+			item_code: frm.doc.name
+		});
+		erpnext.item.item_dashboard.refresh();
+
 	},
 
 	validate: function(frm){
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 114bbab..aa5f330 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -617,7 +617,6 @@
 	return {
 		'count': get_open_count('Item', name),
 		'timeline_data': get_timeline_data(name),
-		'stock_data': get_stock_data(name)
 	}
 
 def get_timeline_data(name):
@@ -627,11 +626,6 @@
 			and posting_date > date_sub(curdate(), interval 1 year)
 			group by posting_date''', name))
 
-def get_stock_data(name):
-	return frappe.get_all('Bin', fields=['warehouse', 'actual_qty', 'projected_qty',
-		'reserved_qty', 'reserved_qty_for_production'],
-		filters={'item_code': name}, order_by = 'warehouse asc')
-
 def validate_end_of_life(item_code, end_of_life=None, disabled=None, verbose=1):
 	if (not end_of_life) or (disabled is None):
 		end_of_life, disabled = frappe.db.get_value("Item", item_code, ["end_of_life", "disabled"])
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry_utils.py b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py
index 4cb0d90..0ac9410 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry_utils.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py
@@ -67,7 +67,7 @@
 		"s_warehouse": args.source,
 		"t_warehouse": args.target,
 		"qty": args.qty,
-		"basic_rate": args.basic_rate,
+		"basic_rate": args.rate or args.basic_rate,
 		"conversion_factor": 1.0,
 		"serial_no": args.serial_no,
 		'cost_center': args.cost_center
diff --git a/erpnext/stock/page/stock_balance/stock_balance.html b/erpnext/stock/page/stock_balance/stock_balance.html
deleted file mode 100644
index 560f843..0000000
--- a/erpnext/stock/page/stock_balance/stock_balance.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<div class="padding">
-	<div class="result list-group">
-	</div>
-	<div class="more hidden" style="padding-top: 15px;">
-		<a class="btn btn-default btn-xs btn-more">More</a>
-	</div>
-</div>
\ No newline at end of file
diff --git a/erpnext/stock/page/stock_balance/stock_balance.js b/erpnext/stock/page/stock_balance/stock_balance.js
index 0fc8984..7bf4792 100644
--- a/erpnext/stock/page/stock_balance/stock_balance.js
+++ b/erpnext/stock/page/stock_balance/stock_balance.js
@@ -1,4 +1,4 @@
-{% include 'erpnext/stock/doctype/item/item_dashboard.html' %}
+frappe.require('assets/js/item-dashboard.min.js');
 
 frappe.pages['stock-balance'].on_page_load = function(wrapper) {
 	var page = frappe.ui.make_app_page({
@@ -6,6 +6,7 @@
 		title: 'Stock Balance',
 		single_column: true
 	});
+	page.start = 0;
 
 	page.warehouse_field = page.add_field({
 		fieldname: 'wareshouse',
@@ -13,8 +14,8 @@
 		fieldtype:'Link',
 		options:'Warehouse',
 		change: function() {
-			page.start = 0;
-			refresh()
+			page.item_dashboard.start = 0;
+			page.item_dashboard.refresh();
 		}
 	});
 
@@ -24,35 +25,11 @@
 		fieldtype:'Link',
 		options:'Item',
 		change: function() {
-			page.start = 0;
-			refresh()
+			page.item_dashboard.start = 0;
+			page.item_dashboard.refresh();
 		}
 	});
 
-	page.start = 0;
-	page.sort_by = 'projected_qty';
-	page.sort_order = 'asc';
-
-	page.content = $(frappe.render_template('stock_balance')).appendTo(page.main);
-	page.result = page.content.find('.result');
-
-	// more
-	page.content.find('.btn-more').on('click', function() {
-			page.start += 20;
-			refresh();
-		});
-
-	// move
-	page.content.on('click', '.btn-move', function() {
-		erpnext.inventory.move_item($(this).attr('data-item'), $(this).attr('data-warehouse'),
-			null, $(this).attr('data-actual_qty'), function() { refresh(); });
-	});
-
-	page.content.on('click', '.btn-add', function() {
-		erpnext.inventory.move_item($(this).attr('data-item'), null, $(this).attr('data-warehouse'),
-			$(this).attr('data-actual_qty'), function() { refresh(); });
-	});
-
 	page.sort_selector = new frappe.ui.SortSelector({
 		parent: page.wrapper.find('.page-form'),
 		args: {
@@ -66,68 +43,36 @@
 			]
 		},
 		change: function(sort_by, sort_order) {
-			page.sort_by = sort_by;
-			page.sort_order = sort_order;
-			page.start = 0;
-			refresh();
+			page.item_dashboard.sort_by = sort_by;
+			page.item_dashboard.sort_order = sort_order;
+			page.item_dashboard.start = 0;
+			page.item_dashboard.refresh();
 		}
 	});
 
 	page.sort_selector.wrapper.css({'margin-right': '15px', 'margin-top': '4px'});
 
-	var refresh = function() {
-		var item_code = page.item_field.get_value();
-		var warehouse = page.warehouse_field.get_value();
-		frappe.call({
-			method: 'erpnext.stock.page.stock_balance.stock_balance.get_data',
-			args: {
-				item_code: item_code,
-				warehouse: warehouse,
-				start: page.start,
-				sort_by: page.sort_by,
-				sort_order: page.sort_order,
-			},
-			callback: function(r) {
-				render(r.message);
-			}
-		});
+	page.item_dashboard = new erpnext.stock.ItemDashboard({
+		parent: page.main,
+	})
+
+	page.item_dashboard.before_refresh = function() {
+		this.item_code = page.item_field.get_value();
+		this.warehouse = page.warehouse_field.get_value();
 	}
 
-	var render = function(data) {
-		if(page.start===0) {
-			page.max_count = 0;
-			page.result.empty();
-		}
-
-		var context = erpnext.get_item_dashboard_data(data, page.max_count, true);
-		page.max_count = context.max_count;
-
-		// show more button
-		if(data.length===21) {
-			page.content.find('.more').removeClass('hidden');
-
-			// remove the last element
-			data.splice(-1);
-		} else {
-			page.content.find('.more').addClass('hidden');
-		}
-
-		$(frappe.render_template('item_dashboard', context)).appendTo(page.result);
-
-	}
-
-	refresh();
+	page.item_dashboard.refresh();
 
 	// item click
 	var setup_click = function(doctype) {
-		page.result.on('click', 'a[data-type="'+ doctype.toLowerCase() +'"]', function() {
+		page.main.on('click', 'a[data-type="'+ doctype.toLowerCase() +'"]', function() {
 			var name = $(this).attr('data-name');
 			var field = page[doctype.toLowerCase() + '_field'];
 			if(field.get_value()===name) {
 				frappe.set_route('Form', doctype, name)
 			} else {
 				field.set_input(name);
-				refresh();
+				page.item_dashboard.refresh();
 			}
 		});
 	}