[wip] inventory tool
diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index b3da719..16e7488 100644
--- a/erpnext/public/build.json
+++ b/erpnext/public/build.json
@@ -20,6 +20,7 @@
 		"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"
 	]
 }
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index f08cf42..8bca282 100644
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -131,23 +131,4 @@
 			});
 		});
 	}
-});
-
-erpnext.get_item_dashboard_data = function(data, max_count) {
-	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
-	}
-}
+});
\ No newline at end of file
diff --git a/erpnext/public/js/utils/inventory.js b/erpnext/public/js/utils/inventory.js
new file mode 100644
index 0000000..80cd6a5
--- /dev/null
+++ b/erpnext/public/js/utils/inventory.js
@@ -0,0 +1,77 @@
+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/stock/doctype/item/item_dashboard.html b/erpnext/stock/doctype/item/item_dashboard.html
index ac78e79..813aef3 100644
--- a/erpnext/stock/doctype/item/item_dashboard.html
+++ b/erpnext/stock/doctype/item/item_dashboard.html
@@ -1,11 +1,11 @@
 {% for d in data %}
 	<li class="list-group-item" style="background-color: inherit;">
 		<div class="row">
-			<div class="col-sm-4 small" style="margin-top: 8px;">
+			<div class="col-sm-3 small" style="margin-top: 8px;">
 				<a data-type="warehouse" data-name="{{ d.warehouse }}">{{ d.warehouse }}</a>
 			</div>
-			<div class="col-sm-4 small" style="margin-top: 8px;">
-				{% if d.item_code %}
+			<div class="col-sm-3 small" style="margin-top: 8px;">
+				{% if show_item %}
 					<a data-type="item"
 						data-name="{{ d.item_code }}">{{ d.item_code }}</a>
 				{% endif %}
@@ -37,6 +37,18 @@
 					</span>
 				</span>
 			</div>
+			<div class="col-sm-2 text-right" style="margin-top: 8px;">
+				{% if d.actual_qty %}
+				<button class="btn btn-default btn-xs btn-move"
+					data-warehouse="{{ d.warehouse }}"
+					data-actual_qty="{{ d.actual_qty }}"
+					data-item="{{ d.item_code }}">{{ __("Move") }}</a>
+				{% endif %}
+				<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>
+			</div>
 		</div>
 	</li>
 {% endfor %}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry_utils.py b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py
index dcfc304..c32c99b 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry_utils.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py
@@ -1,16 +1,34 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # See license.txt
 
-import frappe
+import frappe, erpnext
+from frappe.utils import cint, flt
 
+@frappe.whitelist()
 def make_stock_entry(**args):
 	s = frappe.new_doc("Stock Entry")
 	args = frappe._dict(args)
+
 	if args.posting_date:
 		s.posting_date = args.posting_date
 	if args.posting_time:
 		s.posting_time = args.posting_time
 
+	# map names
+	if args.from_warehouse:
+		args.source = args.from_warehouse
+	if args.to_warehouse:
+		args.target = args.to_warehouse
+	if args.item_code:
+		args.item = args.item_code
+
+	if isinstance(args.qty, basestring):
+		if '.' in args.qty:
+			args.qty = flt(args.qty)
+		else:
+			args.qty = cint(args.qty)
+
+	# purpose
 	if not args.purpose:
 		if args.source and args.target:
 			s.purpose = "Material Transfer"
@@ -21,21 +39,34 @@
 	else:
 		s.purpose = args.purpose
 
-	s.company = args.company or "_Test Company"
+	# company
+	if not args.company:
+		if args.source:
+			args.company = frappe.db.get_value('Warehouse', args.source, 'company')
+		elif args.target:
+			args.company = frappe.db.get_value('Warehouse', args.target, 'company')
+
+	# set vales from test
+	if frappe.flags.in_test:
+		if not args.company:
+			args.company = '_Test Company'
+		if not args.item:
+			args.item = '_Test Item'
+
+	s.company = args.company or erpnext.get_default_company()
 	s.purchase_receipt_no = args.purchase_receipt_no
 	s.delivery_note_no = args.delivery_note_no
 	s.sales_invoice_no = args.sales_invoice_no
-	s.difference_account = args.difference_account or "Stock Adjustment - _TC"
+	if args.difference_account:
+		s.difference_account = args.difference_account
 
 	s.append("items", {
-		"item_code": args.item or args.item_code or "_Test Item",
-		"s_warehouse": args.from_warehouse or args.source,
-		"t_warehouse": args.to_warehouse or args.target,
+		"item_code": args.item,
+		"s_warehouse": args.source,
+		"t_warehouse": args.target,
 		"qty": args.qty,
 		"basic_rate": args.basic_rate,
-		"expense_account": args.expense_account or "Stock Adjustment - _TC",
 		"conversion_factor": 1.0,
-		"cost_center": "_Test Cost Center - _TC",
 		"serial_no": args.serial_no
 	})
 
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index d8c4382..c42350a 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -48,7 +48,7 @@
 	if frappe.db.exists("Product Bundle", args.item_code):
 		valuation_rate = 0.0
 		bundled_items = frappe.get_doc("Product Bundle", args.item_code)
-		
+
 		for bundle_item in bundled_items.items:
 			valuation_rate += \
 				flt(get_valuation_rate(bundle_item.item_code, out.get("warehouse")).get("valuation_rate") \
@@ -83,7 +83,7 @@
 
 	if args.get("is_subcontracted") == "Yes":
 		out.bom = get_default_bom(args.item_code)
-		
+
 	get_gross_profit(out)
 
 	return out
@@ -101,7 +101,7 @@
 		args.item_code = get_item_code(barcode=args.barcode)
 	elif not args.item_code and args.serial_no:
 		args.item_code = get_item_code(serial_no=args.serial_no)
-	
+
 	set_transaction_type(args)
 	return args
 
@@ -127,7 +127,7 @@
 
 	if args.transaction_type=="selling" and cint(item.has_variants):
 		throw(_("Item {0} is a template, please select one of its variants").format(item.name))
-		
+
 	elif args.transaction_type=="buying" and args.doctype != "Material Request":
 		if args.get("is_subcontracted") == "Yes" and item.is_sub_contracted_item != 1:
 			throw(_("Item {0} must be a Sub-contracted Item").format(item.name))
@@ -143,7 +143,7 @@
 	user_default_warehouse_list = get_user_default_as_list('Warehouse')
 	user_default_warehouse = user_default_warehouse_list[0] \
 		if len(user_default_warehouse_list)==1 else ""
-	
+
 	warehouse = user_default_warehouse or args.warehouse or item.default_warehouse
 
 	out = frappe._dict({
@@ -177,8 +177,8 @@
 	})
 
 	# if default specified in item is for another company, fetch from company
-	for d in [["Account", "income_account", "default_income_account"], 
-		["Account", "expense_account", "default_expense_account"], 
+	for d in [["Account", "income_account", "default_income_account"],
+		["Account", "expense_account", "default_expense_account"],
 		["Cost Center", "cost_center", "cost_center"], ["Warehouse", "warehouse", ""]]:
 			company = frappe.db.get_value(d[0], out.get(d[1]), "company")
 			if not out[d[1]] or (company and args.company != company):
@@ -365,7 +365,7 @@
 def get_bin_details(item_code, warehouse):
 	return frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse},
 		["projected_qty", "actual_qty"], as_dict=True) \
-		or {"projected_qty": 0, "actual_qty": 0, "valuation_rate": 0}
+		or {"projected_qty": 0, "actual_qty": 0}
 
 @frappe.whitelist()
 def get_batch_qty(batch_no,warehouse,item_code):
@@ -473,31 +473,31 @@
 			return bom
 		else:
 			frappe.throw(_("No default BOM exists for Item {0}").format(item_code))
-			
+
 def get_valuation_rate(item_code, warehouse=None):
 	item = frappe.get_doc("Item", item_code)
 	if item.is_stock_item:
 		if not warehouse:
 			warehouse = item.default_warehouse
-			
-		return frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse}, 
+
+		return frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse},
 			["valuation_rate"], as_dict=True) or {"valuation_rate": 0}
-			
+
 	elif not item.is_stock_item:
-		valuation_rate =frappe.db.sql("""select sum(base_net_amount) / sum(qty) 
-			from `tabPurchase Invoice Item` 
+		valuation_rate =frappe.db.sql("""select sum(base_net_amount) / sum(qty)
+			from `tabPurchase Invoice Item`
 			where item_code = %s and docstatus=1""", item_code)
-		
+
 		if valuation_rate:
 			return {"valuation_rate": valuation_rate[0][0] or 0.0}
 	else:
 		return {"valuation_rate": 0.0}
-		
+
 def get_gross_profit(out):
 	if out.valuation_rate:
 		out.update({
 			"gross_profit": ((out.base_rate - out.valuation_rate) * out.qty)
 		})
-	
+
 	return out
 
diff --git a/erpnext/stock/page/stock_balance/stock_balance.html b/erpnext/stock/page/stock_balance/stock_balance.html
index a76252e..560f843 100644
--- a/erpnext/stock/page/stock_balance/stock_balance.html
+++ b/erpnext/stock/page/stock_balance/stock_balance.html
@@ -1,11 +1,5 @@
 <div class="padding">
-	<div class="row" style="margin-bottom: 15px;">
-		<div class="col-sm-8"></div>
-		<div class="col-sm-4 sort-selector-area">
-		</div>
-	</div>
 	<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>
diff --git a/erpnext/stock/page/stock_balance/stock_balance.js b/erpnext/stock/page/stock_balance/stock_balance.js
index f19154b..0fc8984 100644
--- a/erpnext/stock/page/stock_balance/stock_balance.js
+++ b/erpnext/stock/page/stock_balance/stock_balance.js
@@ -7,7 +7,7 @@
 		single_column: true
 	});
 
-	var warehouse_field = page.add_field({
+	page.warehouse_field = page.add_field({
 		fieldname: 'wareshouse',
 		label: __('Warehouse'),
 		fieldtype:'Link',
@@ -18,7 +18,7 @@
 		}
 	});
 
-	var item_field = page.add_field({
+	page.item_field = page.add_field({
 		fieldname: 'item_code',
 		label: __('Item'),
 		fieldtype:'Link',
@@ -30,8 +30,8 @@
 	});
 
 	page.start = 0;
-	page.sort_by = 'actual_qty';
-	page.sort_order = 'desc';
+	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');
@@ -42,8 +42,19 @@
 			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.content.find('.sort-selector-area'),
+		parent: page.wrapper.find('.page-form'),
 		args: {
 			sort_by: 'projected_qty',
 			sort_order: 'asc',
@@ -60,11 +71,13 @@
 			page.start = 0;
 			refresh();
 		}
-	})
+	});
+
+	page.sort_selector.wrapper.css({'margin-right': '15px', 'margin-top': '4px'});
 
 	var refresh = function() {
-		var item_code = item_field.get_value();
-		var warehouse = warehouse_field.get_value();
+		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: {
@@ -86,7 +99,7 @@
 			page.result.empty();
 		}
 
-		var context = erpnext.get_item_dashboard_data(data, page.max_count);
+		var context = erpnext.get_item_dashboard_data(data, page.max_count, true);
 		page.max_count = context.max_count;
 
 		// show more button
@@ -105,4 +118,21 @@
 
 	refresh();
 
+	// item click
+	var setup_click = function(doctype) {
+		page.result.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();
+			}
+		});
+	}
+
+	setup_click('Item');
+	setup_click('Warehouse');
+
 }
\ No newline at end of file
diff --git a/erpnext/stock/page/stock_balance/stock_balance.py b/erpnext/stock/page/stock_balance/stock_balance.py
index 1f67401..e96f925 100644
--- a/erpnext/stock/page/stock_balance/stock_balance.py
+++ b/erpnext/stock/page/stock_balance/stock_balance.py
@@ -6,9 +6,9 @@
 def get_data(item_code=None, warehouse=None, start=0, sort_by='actual_qty', sort_order='desc'):
 	filters = {}
 	if item_code:
-		filters = {'item_code': item_code }
+		filters['item_code'] = item_code
 	if warehouse:
-		filters = {'warehouse': 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'],
 		order_by='{0} {1}'.format(sort_by, sort_order), start=start, page_length = 21)
\ No newline at end of file