Test cases for batch no
diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py
index c540ac5..4881983 100644
--- a/erpnext/stock/doctype/batch/batch.py
+++ b/erpnext/stock/doctype/batch/batch.py
@@ -257,10 +257,10 @@
 		'on (`tabBatch`.batch_id = `tabStock Ledger Entry`.batch_no )'
 		'where `tabStock Ledger Entry`.item_code = %s and  `tabStock Ledger Entry`.warehouse = %s '
 		'and (`tabBatch`.expiry_date >= CURDATE() or `tabBatch`.expiry_date IS NULL)'
-		'group by batch_id having qty > 0'
+		'group by batch_id '
 		'order by `tabBatch`.expiry_date ASC, `tabBatch`.creation ASC',
 		(item_code, warehouse),
-		as_dict=True, debug=1
+		as_dict=True
 	)
 
 	return batches
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 4ab95c7..43bc5e2 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -423,7 +423,6 @@
 				else d.stock_qty)
 
 		for sle in stock_ledger_entries:
-			print(accepted_serial_nos_updated, qty, sle.actual_qty)
 			if sle.voucher_detail_no==d.name:
 				if not accepted_serial_nos_updated and qty and abs(sle.actual_qty)==qty \
 					and sle.warehouse == warehouse and sle.serial_no != d.serial_no:
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
index a00e6e6..5ac0b09 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
@@ -153,6 +153,7 @@
 	barcode: function(frm, cdt, cdn) {
 		frm.events.set_item_code(frm, cdt, cdn);
 	},
+
 	warehouse: function(frm, cdt, cdn) {
 		var child = locals[cdt][cdn];
 		if (child.batch_no) {
@@ -161,22 +162,35 @@
 
 		frm.events.set_valuation_rate_and_qty(frm, cdt, cdn);
 	},
+
 	item_code: function(frm, cdt, cdn) {
 		var child = locals[cdt][cdn];
 		if (child.batch_no) {
-			frappe.model.set_value(child.cdt, child.cdn, "batch_no", "");
+			frappe.model.set_value(cdt, cdn, "batch_no", "");
 		}
 
 		frm.events.set_valuation_rate_and_qty(frm, cdt, cdn);
 	},
+
 	batch_no: function(frm, cdt, cdn) {
 		frm.events.set_valuation_rate_and_qty(frm, cdt, cdn);
 	},
+
 	qty: function(frm, cdt, cdn) {
 		frm.events.set_amount_quantity(frm, cdt, cdn);
 	},
+
 	valuation_rate: function(frm, cdt, cdn) {
 		frm.events.set_amount_quantity(frm, cdt, cdn);
+	},
+
+	serial_no: function(frm, cdt, cdn) {
+		var child = locals[cdt][cdn];
+
+		if (child.serial_no) {
+			const serial_nos = child.serial_no.trim().split('\n');
+			frappe.model.set_value(cdt, cdn, "qty", serial_nos.length);
+		}
 	}
 
 });
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index cdf6068..2be667c 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -32,6 +32,9 @@
 		self.validate_expense_account()
 		self.set_total_qty_and_amount()
 
+		if self._action=="submit":
+			self.make_batches('warehouse')
+
 	def on_submit(self):
 		self.update_stock_ledger()
 		self.make_gl_entries()
@@ -50,16 +53,16 @@
 			item_dict = get_stock_balance_for(item.item_code, item.warehouse,
 				self.posting_date, self.posting_time, batch_no=item.batch_no)
 
-			if ((item.qty==None or item.qty==item_dict.get("qty"))
-				and (item.valuation_rate==None or item.valuation_rate==item_dict.get("rate"))
-				and item.serial_no == item_dict.get("serial_nos")):
+			if (((item.qty is None or item.qty==item_dict.get("qty")) and
+				(item.valuation_rate is None or item.valuation_rate==item_dict.get("rate")) and not item.serial_no)
+				or (item.serial_no and item.serial_no == item_dict.get("serial_nos"))):
 				return False
 			else:
 				# set default as current rates
-				if item.qty==None:
+				if item.qty is None:
 					item.qty = item_dict.get("qty")
 
-				if item.valuation_rate==None:
+				if item.valuation_rate is None:
 					item.valuation_rate = item_dict.get("rate")
 
 				if item_dict.get("serial_nos"):
@@ -162,15 +165,12 @@
 
 			# item should not be serialized
 			if item.has_serial_no and not row.serial_no and not item.serial_no_series:
-				raise frappe.ValidationError(_("Serial nos are required for serialized item {0}").format(item_code))
+				raise frappe.ValidationError(_("Serial no(s) required for serialized item {0}").format(item_code))
 
 			# item managed batch-wise not allowed
 			if item.has_batch_no and not row.batch_no and not item.create_new_batch:
 				raise frappe.ValidationError(_("Batch no is required for batched item {0}").format(item_code))
 
-			if self._action=="submit" and item.create_new_batch:
-				self.make_batches('warehouse')
-
 			# docstatus should be < 2
 			validate_cancelled_item(item_code, item.docstatus, verbose=0)
 
@@ -203,7 +203,7 @@
 						row.valuation_rate = previous_sle.get("valuation_rate", 0)
 
 				if row.qty and not row.valuation_rate:
-					frappe.throw(_("Valuation Rate required for Item in row {0}").format(row.idx))
+					frappe.throw(_("Valuation Rate required for Item {0} at row {1}").format(row.item_code, row.idx))
 
 				if ((previous_sle and row.qty == previous_sle.get("qty_after_transaction")
 					and (row.valuation_rate == previous_sle.get("valuation_rate") or row.qty == 0))
@@ -270,7 +270,7 @@
 
 				sl_entries.append(args)
 
-		if self.docstatus == 1 and not row.remove_serial_no_from_stock:
+		if self.docstatus == 1 and row.qty:
 			args = self.get_sle_for_items(row)
 
 			args.update({
@@ -332,7 +332,7 @@
 
 		sl_entries = []
 		for row in self.items:
-			if row.serial_no or row.batch_no:
+			if row.serial_no or row.batch_no or row.current_serial_no:
 				self.get_sle_for_serialized_items(row, sl_entries)
 
 		if sl_entries:
diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
index 5ee8228..f0c71cf 100644
--- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
@@ -13,7 +13,7 @@
 from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import EmptyStockReconciliationItemsError, get_items
 from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
 from erpnext.stock.doctype.item.test_item import create_item
-from erpnext.stock.utils import get_stock_balance, get_incoming_rate, get_available_serial_nos
+from erpnext.stock.utils import get_stock_balance, get_incoming_rate, get_available_serial_nos, get_stock_value_on
 from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
 
 class TestStockReconciliation(unittest.TestCase):
@@ -169,10 +169,62 @@
 			if frappe.db.exists("Serial No", d):
 				frappe.delete_doc("Serial No", d)
 
+	def test_stock_reco_for_batch_item(self):
+		set_perpetual_inventory()
+
+		to_delete_records = []
+		to_delete_serial_nos = []
+
+		# Add new serial nos
+		item_code = "Stock-Reco-batch-Item-1"
+		warehouse = "_Test Warehouse for Stock Reco2 - _TC"
+
+		sr = create_stock_reconciliation(item_code=item_code,
+			warehouse = warehouse, qty=5, rate=200, do_not_submit=1)
+		sr.save(ignore_permissions=True)
+		sr.submit()
+
+		self.assertTrue(sr.items[0].batch_no)
+		to_delete_records.append(sr.name)
+
+		sr1 = create_stock_reconciliation(item_code=item_code,
+			warehouse = warehouse, qty=6, rate=300, batch_no=sr.items[0].batch_no)
+
+		args = {
+			"item_code": item_code,
+			"warehouse": warehouse,
+			"posting_date": nowdate(),
+			"posting_time": nowtime(),
+		}
+
+		valuation_rate = get_incoming_rate(args)
+		self.assertEqual(valuation_rate, 300)
+		to_delete_records.append(sr1.name)
+
+
+		sr2 = create_stock_reconciliation(item_code=item_code,
+			warehouse = warehouse, qty=0, rate=0, batch_no=sr.items[0].batch_no)
+
+		stock_value = get_stock_value_on(warehouse, nowdate(), item_code)
+		self.assertEqual(stock_value, 0)
+		to_delete_records.append(sr2.name)
+
+		to_delete_records.reverse()
+		for d in to_delete_records:
+			stock_doc = frappe.get_doc("Stock Reconciliation", d)
+			stock_doc.cancel()
+
+		frappe.delete_doc("Batch", sr.items[0].batch_no)
+		for d in to_delete_records:
+			frappe.delete_doc("Stock Reconciliation", d)
+
 def create_batch_or_serial_no_items():
 	create_warehouse("_Test Warehouse for Stock Reco1",
 		{"is_group": 0, "parent_warehouse": "_Test Warehouse Group - _TC"})
 
+	create_warehouse("_Test Warehouse for Stock Reco2",
+		{"is_group": 0, "parent_warehouse": "_Test Warehouse Group - _TC"})
+
 	serial_item_doc = create_item("Stock-Reco-Serial-Item-1", is_stock_item=1)
 	if not serial_item_doc.has_serial_no:
 		serial_item_doc.has_serial_no = 1
@@ -202,12 +254,12 @@
 		"qty": args.qty,
 		"valuation_rate": args.rate,
 		"serial_no": args.serial_no,
-		"batch_no": args.batch_no,
-		"remove_serial_no_from_stock": args.remove_serial_no_from_stock or 0
+		"batch_no": args.batch_no
 	})
 
 	try:
-		sr.submit()
+		if not args.do_not_submit:
+			sr.submit()
 	except EmptyStockReconciliationItemsError:
 		pass
 	return sr
diff --git a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
index fa42c9c..e53db07 100644
--- a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
+++ b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
@@ -15,7 +15,6 @@
   "amount",
   "serial_no_and_batch_section",
   "serial_no",
-  "remove_serial_no_from_stock",
   "column_break_11",
   "batch_no",
   "section_break_3",
@@ -110,6 +109,7 @@
    "label": "Before reconciliation"
   },
   {
+   "default": "0",
    "fieldname": "current_qty",
    "fieldtype": "Float",
    "label": "Current Qty",
@@ -166,16 +166,10 @@
    "fieldtype": "Link",
    "label": "Batch No",
    "options": "Batch"
-  },
-  {
-   "default": "0",
-   "fieldname": "remove_serial_no_from_stock",
-   "fieldtype": "Check",
-   "label": "Remove Serial No from Stock"
   }
  ],
  "istable": 1,
- "modified": "2019-06-01 03:16:38.459307",
+ "modified": "2019-06-14 17:10:53.188305",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Reconciliation Item",