[taxes and charges] refactor
diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js
index 09f2e8d..f53581a 100644
--- a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js
+++ b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js
@@ -1,6 +1,8 @@
 // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
+cur_frm.cscript.tax_table = "Purchase Taxes and Charges";
+
 {% include "public/js/controllers/accounts.js" %}
 
 frappe.ui.form.on("Purchase Taxes and Charges", "add_deduct_tax", function(doc, cdt, cdn) {
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 4670303..220e171 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -199,8 +199,8 @@
 		this.hide_fields(this.frm.doc);
 	},
 
-	items_on_form_rendered: function(doc, grid_row) {
-		erpnext.setup_serial_no(grid_row)
+	items_on_form_rendered: function() {
+		erpnext.setup_serial_no();
 	}
 
 });
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.json b/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.json
index 2322550..67f7ab4 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.json
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.json
@@ -56,7 +56,7 @@
    "oldfieldname": "rate", 
    "oldfieldtype": "Currency", 
    "permlevel": 0, 
-   "reqd": 1
+   "reqd": 0
   }, 
   {
    "fieldname": "col_break_1", 
@@ -186,7 +186,7 @@
  "hide_heading": 1, 
  "idx": 1, 
  "istable": 1, 
- "modified": "2015-02-23 12:36:02.213508", 
+ "modified": "2015-02-25 02:50:44.152307", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Sales Taxes and Charges", 
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
index b5dc38f..3ad573a 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
@@ -1,9 +1,10 @@
 // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
+cur_frm.cscript.tax_table = "Sales Taxes and Charges";
+
 {% include "public/js/controllers/accounts.js" %}
 
-cur_frm.cscript.onload = function(doc, cdt, cdn) {
-	if(doc.doctype === "Sales Taxes and Charges Master")
-		erpnext.add_applicable_territory();
-}
+frappe.ui.form.on("Sales Taxes and Charges Master", "onload", function(frm) {
+	erpnext.add_applicable_territory();
+});
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py
index 4317f2a..907c7c6 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py
@@ -20,3 +20,4 @@
 			validate_taxes_and_charges(tax)
 			validate_inclusive_tax(tax, self)
 
+
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index bbab88f..fd17fd6 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -370,6 +370,15 @@
 		elif tax.row_id and cint(tax.row_id) >= cint(tax.idx):
 			frappe.throw(_("Cannot refer row number greater than or equal to current row number for this Charge type"))
 
+	if tax.charge_type == "Actual":
+		if not tax.tax_amount:
+			frappe.throw(_("Amount is mandatory for charge type 'Actual'"))
+		tax.rate = None
+	else:
+		if not tax.rate:
+			frappe.throw(_("Rate is mandatory for charge type '{0}'").format(tax.charge_type))
+		tax.tax_amount = None
+
 def validate_inclusive_tax(tax, doc):
 	def _on_previous_row_error(row_range):
 		throw(_("To include tax in row {0} in Item rate, taxes in rows {1} must also be included").format(tax.idx,
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 1a88177..b3745e7 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -126,3 +126,4 @@
 erpnext.patches.v5_0.update_journal_entry_title
 erpnext.patches.v5_0.taxes_and_totals_in_party_currency
 erpnext.patches.v5_0.replace_renamed_fields_in_custom_scripts_and_print_formats
+execute:frappe.db.sql("update `tabStock Entry` set from_bom = if(ifnull(bom_no, '')='', 0, 1)")
diff --git a/erpnext/public/js/controllers/accounts.js b/erpnext/public/js/controllers/accounts.js
index 35d8c66..283ec74 100644
--- a/erpnext/public/js/controllers/accounts.js
+++ b/erpnext/public/js/controllers/accounts.js
@@ -2,6 +2,10 @@
 // License: GNU General Public License v3. See license.txt
 
 // get tax rate
+frappe.provide("erpnext.taxes");
+frappe.provide("erpnext.taxes.flags");
+
+
 cur_frm.cscript.account_head = function(doc, cdt, cdn) {
 	var d = locals[cdt][cdn];
 	if(!d.charge_type && d.account_head){
@@ -82,34 +86,60 @@
 	}
 }
 
-frappe.ui.form.on(cur_frm.cscript.tax_table, "row_id", function(frm, cdt, cdn) {
-	cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
-});
+if(!erpnext.taxes.flags[cur_frm.cscript.tax_table]) {
+	erpnext.taxes.flags[cur_frm.cscript.tax_table] = true;
 
-frappe.ui.form.on(cur_frm.cscript.tax_table, "rate", function(frm, cdt, cdn) {
-	cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
-});
-
-frappe.ui.form.on(cur_frm.cscript.tax_table, "tax_amount", function(frm, cdt, cdn) {
-	cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
-});
-
-frappe.ui.form.on(cur_frm.cscript.tax_table, "charge_type", function(frm, cdt, cdn) {
-	cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
-});
-
-frappe.ui.form.on(cur_frm.cscript.tax_table, "included_in_print_rate", function(frm, cdt, cdn) {
-	var tax = frappe.get_doc(cdt, cdn);
-	try {
+	frappe.ui.form.on(cur_frm.cscript.tax_table, "row_id", function(frm, cdt, cdn) {
 		cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
-		cur_frm.cscript.validate_inclusive_tax(tax);
-	} catch(e) {
-		tax.included_in_print_rate = 0;
-		refresh_field("included_in_print_rate", tax.name, tax.parentfield);
-		throw e;
+	});
+
+	frappe.ui.form.on(cur_frm.cscript.tax_table, "rate", function(frm, cdt, cdn) {
+		cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
+	});
+
+	frappe.ui.form.on(cur_frm.cscript.tax_table, "tax_amount", function(frm, cdt, cdn) {
+		cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
+	});
+
+	frappe.ui.form.on(cur_frm.cscript.tax_table, "charge_type", function(frm, cdt, cdn) {
+		cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
+		erpnext.taxes.set_conditional_mandatory_rate_or_amount(frm);
+	});
+
+	frappe.ui.form.on(cur_frm.cscript.tax_table, "included_in_print_rate", function(frm, cdt, cdn) {
+		var tax = frappe.get_doc(cdt, cdn);
+		try {
+			cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
+			cur_frm.cscript.validate_inclusive_tax(tax);
+		} catch(e) {
+			tax.included_in_print_rate = 0;
+			refresh_field("included_in_print_rate", tax.name, tax.parentfield);
+			throw e;
+		}
+	});
+}
+
+erpnext.taxes.set_conditional_mandatory_rate_or_amount = function(frm) {
+	var grid_row = frm.open_grid_row();
+	if(grid_row.doc.charge_type==="Actual") {
+		grid_row.toggle_display("tax_amount", true);
+		grid_row.toggle_reqd("tax_amount", true);
+		grid_row.toggle_display("rate", false);
+		grid_row.toggle_reqd("rate", false);
+	} else {
+		grid_row.toggle_display("rate", true);
+		grid_row.toggle_reqd("rate", true);
+		grid_row.toggle_display("tax_amount", false);
+		grid_row.toggle_reqd("tax_amount", false);
 	}
+}
+
+// setup conditional mandatory for tax and rates
+frappe.ui.form.on(cur_frm.doctype, "taxes_on_form_rendered", function(frm) {
+	erpnext.taxes.set_conditional_mandatory_rate_or_amount(frm);
 });
 
+
 cur_frm.set_query("account_head", "taxes", function(doc) {
 	if(cur_frm.cscript.tax_table == "Sales Taxes and Charges") {
 		var account_type = ["Tax", "Chargeable", "Expense Account"];
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 67d8eaa..0d97a94 100644
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -57,13 +57,15 @@
 		}
 	},
 
-	setup_serial_no: function(grid_row) {
+	setup_serial_no: function() {
+		var grid_row = cur_frm.open_grid_row();
+
 		if(!grid_row.fields_dict.serial_no ||
 			grid_row.fields_dict.serial_no.get_status()!=="Write") return;
 
 		var $btn = $('<button class="btn btn-sm btn-default">'+__("Add Serial No")+'</button>')
 			.appendTo($("<div>")
-				.css({"margin-bottom": "10px", "margin-left": "15px"})
+				.css({"margin-bottom": "10px", "margin-top": "10px"})
 				.appendTo(grid_row.fields_dict.serial_no.$wrapper));
 
 		$btn.on("click", function() {
@@ -99,7 +101,7 @@
 			d.show();
 		});
 	},
-	
+
 	get_letter_head: function(company) {
 		frappe.call({
 			type:"GET",
@@ -112,7 +114,7 @@
 			}
 		});
 	},
-	
+
 });
 
 
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js
index 185c242..1c68339 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.js
@@ -79,7 +79,7 @@
 	},
 
 	items_on_form_rendered: function(doc, grid_row) {
-		erpnext.setup_serial_no(grid_row)
+		erpnext.setup_serial_no();
 	}
 
 });
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 8795524..716b4a8 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -274,7 +274,7 @@
 	},
 
 	items_on_form_rendered: function(doc, grid_row) {
-		erpnext.setup_serial_no(grid_row)
+		erpnext.setup_serial_no();
 	},
 
 	customer: function() {
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.json b/erpnext/stock/doctype/stock_entry/stock_entry.json
index db40708..5b1cce0 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.json
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.json
@@ -8,6 +8,14 @@
  "doctype": "DocType", 
  "fields": [
   {
+   "fieldname": "items_section", 
+   "fieldtype": "Section Break", 
+   "label": "", 
+   "oldfieldtype": "Section Break", 
+   "permlevel": 0, 
+   "read_only": 0
+  }, 
+  {
    "fieldname": "col1", 
    "fieldtype": "Column Break", 
    "oldfieldtype": "Column Break", 
@@ -74,15 +82,6 @@
    "search_index": 1
   }, 
   {
-   "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)", 
-   "fieldname": "bom_no", 
-   "fieldtype": "Link", 
-   "label": "BOM No", 
-   "options": "BOM", 
-   "permlevel": 0, 
-   "read_only": 0
-  }, 
-  {
    "allow_on_submit": 0, 
    "depends_on": "eval:doc.purpose==\"Sales Return\"", 
    "fieldname": "delivery_note_no", 
@@ -133,6 +132,13 @@
    "search_index": 1
   }, 
   {
+   "fieldname": "from_bom", 
+   "fieldtype": "Check", 
+   "label": "From BOM", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "fieldname": "col2", 
    "fieldtype": "Column Break", 
    "oldfieldtype": "Column Break", 
@@ -178,14 +184,92 @@
    "search_index": 0
   }, 
   {
-   "fieldname": "items_section", 
+   "depends_on": "eval: doc.from_bom && (doc.purpose!==\"Sales Return\" && doc.purpose!==\"Purchase Return\")", 
+   "fieldname": "sb1", 
    "fieldtype": "Section Break", 
    "label": "", 
-   "oldfieldtype": "Section Break", 
    "permlevel": 0, 
    "read_only": 0
   }, 
   {
+   "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)", 
+   "fieldname": "bom_no", 
+   "fieldtype": "Link", 
+   "label": "BOM No", 
+   "options": "BOM", 
+   "permlevel": 0, 
+   "read_only": 0
+  }, 
+  {
+   "depends_on": "eval:inList([\"Manufacture\", \"Repack\"], doc.purpose)", 
+   "fieldname": "additional_operating_cost", 
+   "fieldtype": "Currency", 
+   "label": "Additional Operating Cost", 
+   "no_copy": 1, 
+   "options": "Company:company:default_currency", 
+   "permlevel": 0, 
+   "read_only": 0
+  }, 
+  {
+   "fieldname": "cb1", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "read_only": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)", 
+   "description": "As per Stock UOM", 
+   "fieldname": "fg_completed_qty", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "in_filter": 0, 
+   "label": "Manufacturing Quantity", 
+   "no_copy": 0, 
+   "oldfieldname": "fg_completed_qty", 
+   "oldfieldtype": "Currency", 
+   "permlevel": 0, 
+   "print_hide": 1, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0
+  }, 
+  {
+   "default": "1", 
+   "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)", 
+   "description": "Including items for sub assemblies", 
+   "fieldname": "use_multi_level_bom", 
+   "fieldtype": "Check", 
+   "label": "Use Multi-Level BOM", 
+   "permlevel": 0, 
+   "print_hide": 1, 
+   "read_only": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)", 
+   "fieldname": "get_items", 
+   "fieldtype": "Button", 
+   "hidden": 0, 
+   "in_filter": 0, 
+   "label": "Get Items", 
+   "no_copy": 0, 
+   "oldfieldtype": "Button", 
+   "permlevel": 0, 
+   "print_hide": 1, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0
+  }, 
+  {
+   "fieldname": "section_break_12", 
+   "fieldtype": "Section Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "allow_on_submit": 0, 
    "fieldname": "from_warehouse", 
    "fieldtype": "Link", 
@@ -302,77 +386,6 @@
    "read_only": 1
   }, 
   {
-   "depends_on": "eval:(doc.purpose!==\"Sales Return\" && doc.purpose!==\"Purchase Return\")", 
-   "fieldname": "sb1", 
-   "fieldtype": "Section Break", 
-   "label": "From Bill of Materials", 
-   "permlevel": 0, 
-   "read_only": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)", 
-   "description": "As per Stock UOM", 
-   "fieldname": "fg_completed_qty", 
-   "fieldtype": "Float", 
-   "hidden": 0, 
-   "in_filter": 0, 
-   "label": "Manufacturing Quantity", 
-   "no_copy": 0, 
-   "oldfieldname": "fg_completed_qty", 
-   "oldfieldtype": "Currency", 
-   "permlevel": 0, 
-   "print_hide": 1, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0
-  }, 
-  {
-   "depends_on": "eval:inList([\"Manufacture\", \"Repack\"], doc.purpose)", 
-   "fieldname": "additional_operating_cost", 
-   "fieldtype": "Currency", 
-   "label": "Additional Operating Cost", 
-   "no_copy": 1, 
-   "options": "Company:company:default_currency", 
-   "permlevel": 0, 
-   "read_only": 0
-  }, 
-  {
-   "fieldname": "cb1", 
-   "fieldtype": "Column Break", 
-   "permlevel": 0, 
-   "read_only": 0
-  }, 
-  {
-   "default": "1", 
-   "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)", 
-   "description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.", 
-   "fieldname": "use_multi_level_bom", 
-   "fieldtype": "Check", 
-   "label": "Use Multi-Level BOM", 
-   "permlevel": 0, 
-   "print_hide": 1, 
-   "read_only": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)", 
-   "fieldname": "get_items", 
-   "fieldtype": "Button", 
-   "hidden": 0, 
-   "in_filter": 0, 
-   "label": "Get Items", 
-   "no_copy": 0, 
-   "oldfieldtype": "Button", 
-   "permlevel": 0, 
-   "print_hide": 1, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0
-  }, 
-  {
    "fieldname": "fold", 
    "fieldtype": "Fold", 
    "permlevel": 0
@@ -632,7 +645,7 @@
  "is_submittable": 1, 
  "issingle": 0, 
  "max_attachments": 0, 
- "modified": "2015-02-20 05:04:09.060180", 
+ "modified": "2015-02-25 01:59:14.371042", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Stock Entry", 
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 6e18a91..2d7fc2d 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -282,14 +282,15 @@
 	def add_operation_cost(self, raw_material_cost, force):
 		"""Adds operating cost if Production Order is set"""
 		# set incoming rate for fg item
-		if self.production_order:
-			number_of_fg_items = len([t.t_warehouse for t in self.get("items") if t.t_warehouse])
-			for d in self.get("items"):
-				if d.bom_no or (d.t_warehouse and number_of_fg_items == 1):
+		number_of_fg_items = len([t.t_warehouse for t in self.get("items") if t.t_warehouse])
+		for d in self.get("items"):
+			if (d.t_warehouse and number_of_fg_items == 1):
+				operation_cost_per_unit = 0.0
+				if self.production_order:
 					operation_cost_per_unit = self.get_operation_cost_per_unit(d.bom_no, d.qty)
-					d.incoming_rate = operation_cost_per_unit + (raw_material_cost / flt(d.transfer_qty))
-					d.amount = flt(flt(d.transfer_qty) * flt(d.incoming_rate), self.precision("transfer_qty", d))
-					break
+				d.incoming_rate = operation_cost_per_unit + (raw_material_cost / flt(d.transfer_qty))
+				d.amount = flt(flt(d.transfer_qty) * flt(d.incoming_rate), self.precision("transfer_qty", d))
+				break
 
 	def get_operation_cost_per_unit(self, bom_no, qty):
 		"""Returns operating cost from Production Order for given `bom_no`"""
@@ -510,10 +511,14 @@
 		self.set('items', [])
 		self.validate_production_order()
 
+		if not getattr(self, "pro_doc", None):
+			self.pro_doc = None
+
 		if self.production_order:
 			# common validations
-			if not getattr(self, "pro_doc", None):
+			if not self.pro_doc:
 				self.pro_doc = frappe.get_doc('Production Order', self.production_order)
+
 			if self.pro_doc:
 				self.bom_no = self.pro_doc.bom_no
 			else:
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 7c81d35..0845a6b 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -10,12 +10,18 @@
 from erpnext.controllers.stock_controller import StockController
 from erpnext.stock.utils import get_stock_balance
 
+class OpeningEntryAccountError(frappe.ValidationError): pass
+
 class StockReconciliation(StockController):
 	def __init__(self, arg1, arg2=None):
 		super(StockReconciliation, self).__init__(arg1, arg2)
 		self.head_row = ["Item Code", "Warehouse", "Quantity", "Valuation Rate"]
 
 	def validate(self):
+		if not self.expense_account:
+			self.expense_account = frappe.db.get_value("Company", self.company, "stock_adjustment_account")
+		if not self.cost_center:
+			self.cost_center = frappe.db.get_value("Company", self.company, "cost_center")
 		self.validate_posting_time()
 		self.remove_items_with_no_change()
 		self.validate_data()
@@ -215,7 +221,12 @@
 			msgprint(_("Please enter Expense Account"), raise_exception=1)
 		elif not frappe.db.sql("""select name from `tabStock Ledger Entry` limit 1"""):
 			if frappe.db.get_value("Account", self.expense_account, "report_type") == "Profit and Loss":
-				frappe.throw(_("Difference Account must be a 'Liability' type account, since this Stock Reconciliation is an Opening Entry"))
+				frappe.throw(_("Difference Account must be a 'Liability' type account, since this Stock Reconciliation is an Opening Entry"), OpeningEntryAccountError)
+
+	def get_items_for(self, warehouse):
+		self.items = []
+		for item in get_items(warehouse, self.posting_date, self.posting_time):
+			self.append("items", item)
 
 @frappe.whitelist()
 def get_items(warehouse, posting_date, posting_time):
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index 84743ae..d51a89b 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -150,7 +150,7 @@
 				return
 
 		if sle.serial_no:
-			self.valuation_rate = self.get_serialized_values(sle)
+			self.get_serialized_values(sle)
 			self.qty_after_transaction += flt(sle.actual_qty)
 			self.stock_value = flt(self.qty_after_transaction) * flt(self.valuation_rate)
 		else:
@@ -208,12 +208,14 @@
 		if incoming_rate < 0:
 			# wrong incoming rate
 			incoming_rate = self.valuation_rate
-		elif incoming_rate == 0 or flt(sle.actual_qty) < 0:
-			# In case of delivery/stock issue, get average purchase rate
-			# of serial nos of current entry
-			incoming_rate = flt(frappe.db.sql("""select avg(ifnull(purchase_rate, 0))
-				from `tabSerial No` where name in (%s)""" % (", ".join(["%s"]*len(serial_no))),
-				tuple(serial_no))[0][0])
+
+		elif incoming_rate == 0:
+			if flt(sle.actual_qty) < 0:
+				# In case of delivery/stock issue, get average purchase rate
+				# of serial nos of current entry
+				incoming_rate = flt(frappe.db.sql("""select avg(ifnull(purchase_rate, 0))
+					from `tabSerial No` where name in (%s)""" % (", ".join(["%s"]*len(serial_no))),
+					tuple(serial_no))[0][0])
 
 		if incoming_rate and not self.valuation_rate:
 			self.valuation_rate = incoming_rate