Merge pull request #2864 from neilLasrado/delivery-note

Delivery note - Batch Id made Link Feild
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/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 28499c1..2d5df15 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -217,7 +217,7 @@
 					tax.grand_total_for_current_item = flt(item.net_amount + current_tax_amount, tax.precision("total"))
 				else:
 					tax.grand_total_for_current_item = \
-						flt(self.doc.get("taxes")[i-1].grand_total_for_current_item + current_tax_amount, tax.precision("total_taxes_and_charges"))
+						flt(self.doc.get("taxes")[i-1].grand_total_for_current_item + current_tax_amount, tax.precision("total"))
 
 				# in tax.total, accumulate grand total of each item
 				tax.total += tax.grand_total_for_current_item
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.json b/erpnext/manufacturing/doctype/production_order/production_order.json
index 089fd38..2962c48 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.json
+++ b/erpnext/manufacturing/doctype/production_order/production_order.json
@@ -351,7 +351,7 @@
  "idx": 1, 
  "in_create": 0, 
  "is_submittable": 1, 
- "modified": "2015-02-23 07:42:05.639225", 
+ "modified": "2015-02-25 01:01:11.550217", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Production Order", 
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 1a88177..30ffd1a 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -126,3 +126,5 @@
 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
+erpnext.patches.v5_0.update_from_bom
+erpnext.patches.v5_0.update_account_types
diff --git a/erpnext/patches/v5_0/update_account_types.py b/erpnext/patches/v5_0/update_account_types.py
new file mode 100644
index 0000000..4686a5f
--- /dev/null
+++ b/erpnext/patches/v5_0/update_account_types.py
@@ -0,0 +1,20 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	for company in frappe.db.get_all("Company"):
+		company = frappe.get_doc("Company", company.name)
+
+		match_types = ("Stock Received But Not Billed", "Stock Adjustment", "Expenses Included In Valuation",
+			"Cost of Goods Sold")
+
+		for account_type in match_types:
+			account_name = "{0} - {1}".format(account_type, company.abbr)
+			current_account_type = frappe.db.get_value("Account", account_name, "account_type")
+			if current_account_type != account_type:
+				frappe.db.set_value("Account", account_name, "account_type", account_type)
+
+		company.set_default_accounts()
diff --git a/erpnext/patches/v5_0/update_from_bom.py b/erpnext/patches/v5_0/update_from_bom.py
new file mode 100644
index 0000000..660b3e4
--- /dev/null
+++ b/erpnext/patches/v5_0/update_from_bom.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	frappe.reload_doctype("Stock Entry")
+	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/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index 67e1ba8..cede702 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -188,7 +188,7 @@
    "fieldname": "default_expense_account", 
    "fieldtype": "Link", 
    "ignore_user_permissions": 1, 
-   "label": "Default Expense Account", 
+   "label": "Default Cost of Goods Sold Account", 
    "no_copy": 1, 
    "options": "Account", 
    "permlevel": 0
@@ -399,7 +399,7 @@
  ], 
  "icon": "icon-building", 
  "idx": 1, 
- "modified": "2015-02-21 10:32:38.523900", 
+ "modified": "2015-02-25 06:28:13.565128", 
  "modified_by": "Administrator", 
  "module": "Setup", 
  "name": "Company", 
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 6247afd..56e0243 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -106,28 +106,30 @@
 		account.insert()
 
 	def set_default_accounts(self):
-		def _set_default_account(fieldname, account_type):
-			if self.get(fieldname):
-				return
+		self._set_default_account("default_cash_account", "Cash")
+		self._set_default_account("default_bank_account", "Bank")
 
-			account = frappe.db.get_value("Account", {"account_type": account_type,
-				"group_or_ledger": "Ledger", "company": self.name})
-
-			if account:
-				self.db_set(fieldname, account)
-
-		_set_default_account("default_cash_account", "Cash")
-		_set_default_account("default_bank_account", "Bank")
-
-		if cint(frappe.db.get_value("Accounts Settings", None, "auto_accounting_for_stock")):
-			_set_default_account("stock_received_but_not_billed", "Stock Received But Not Billed")
-			_set_default_account("stock_adjustment_account", "Stock Adjustment")
-			_set_default_account("expenses_included_in_valuation", "Expenses Included In Valuation")
+		if cint(frappe.db.get_single_value("Accounts Settings", "auto_accounting_for_stock")):
+			self._set_default_account("stock_received_but_not_billed", "Stock Received But Not Billed")
+			self._set_default_account("stock_adjustment_account", "Stock Adjustment")
+			self._set_default_account("expenses_included_in_valuation", "Expenses Included In Valuation")
+			self._set_default_account("default_expense_account", "Cost of Goods Sold")
 
 		if not self.default_income_account:
 			self.db_set("default_income_account", frappe.db.get_value("Account",
 				{"account_name": _("Sales"), "company": self.name}))
 
+
+	def _set_default_account(self, fieldname, account_type):
+		if self.get(fieldname):
+			return
+
+		account = frappe.db.get_value("Account", {"account_type": account_type,
+			"group_or_ledger": "Ledger", "company": self.name})
+
+		if account:
+			self.db_set(fieldname, account)
+
 	def create_default_cost_center(self):
 		cc_list = [
 			{
diff --git a/erpnext/setup/doctype/item_group/item_group.js b/erpnext/setup/doctype/item_group/item_group.js
index 717c7d6..67e4e99 100644
--- a/erpnext/setup/doctype/item_group/item_group.js
+++ b/erpnext/setup/doctype/item_group/item_group.js
@@ -1,30 +1,36 @@
 // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-cur_frm.list_route = "Sales Browser/Item Group";
+frappe.ui.form.on("Item Group", {
+	onload: function(frm) {
+		frm.list_route = "Sales Browser/Item Group";
 
-cur_frm.cscript.refresh = function(doc, cdt, cdn) {
-	cur_frm.cscript.set_root_readonly(doc);
-	cur_frm.add_custom_button(__("Item Group Tree"), function() {
-		frappe.set_route("Sales Browser", "Item Group");
-	}, "icon-sitemap")
-}
+		//get query select item group
+		frm.fields_dict['parent_item_group'].get_query = function(doc,cdt,cdn) {
+			return{
+				filters:[
+					['Item Group', 'is_group', '=', 'Yes'],
+					['Item Group', 'name', '!=', doc.item_group_name]
+				]
+			}
+		}
+	},
 
-cur_frm.cscript.set_root_readonly = function(doc) {
-	// read-only for root item group
-	cur_frm.set_intro("");
-	if(!doc.parent_item_group) {
-		cur_frm.set_read_only();
-		cur_frm.set_intro(__("This is a root item group and cannot be edited."), true);
-	}
-}
+	refresh: function(frm) {
+		frm.trigger("set_root_readonly");
+		frm.add_custom_button(__("Item Group Tree"), function() {
+			frappe.set_route("Sales Browser", "Item Group");
+		}, "icon-sitemap");
+	},
 
-//get query select item group
-cur_frm.fields_dict['parent_item_group'].get_query = function(doc,cdt,cdn) {
-	return{
-		filters:[
-			['Item Group', 'is_group', '=', 'Yes'],
-			['Item Group', 'name', '!=', doc.item_group_name]
-		]
-	}
-}
+	set_root_readonly: function(frm) {
+		// read-only for root item group
+		frm.set_intro("");
+		if(!frm.doc.parent_item_group) {
+			frm.set_read_only();
+			frm.set_intro(__("This is a root item group and cannot be edited."), true);
+		}
+	},
+
+	page_name: frappe.utils.warn_page_name_change
+});
diff --git a/erpnext/startup/notifications.py b/erpnext/startup/notifications.py
index 66bc83d..7d6109d 100644
--- a/erpnext/startup/notifications.py
+++ b/erpnext/startup/notifications.py
@@ -5,7 +5,7 @@
 import frappe
 
 def get_notification_config():
-	return { "for_doctype": 
+	return { "for_doctype":
 		{
 			"Issue": {"status":"Open"},
 			"Warranty Claim": {"status":"Open"},
@@ -14,9 +14,9 @@
 			"Contact": {"status":"Open"},
 			"Opportunity": {"docstatus":0},
 			"Quotation": {"docstatus":0},
-			"Sales Order": {"docstatus":0},
+			"Sales Order": { "per_delivered": ("<", 100) },
 			"Journal Entry": {"docstatus":0},
-			"Sales Invoice": {"docstatus":0},
+			"Sales Invoice": { "outstanding_amount": (">", 0) },
 			"Purchase Invoice": {"docstatus":0},
 			"Leave Application": {"status":"Open"},
 			"Expense Claim": {"approval_status":"Draft"},
@@ -25,11 +25,11 @@
 			"Delivery Note": {"docstatus":0},
 			"Stock Entry": {"docstatus":0},
 			"Material Request": {"docstatus":0},
-			"Purchase Order": {"docstatus":0},
-			"Production Order": {"docstatus":0},
+			"Purchase Order": { "per_received": ("<", 100) },
+			"Production Order": { "status": "In Process" },
 			"BOM": {"docstatus":0},
 			"Timesheet": {"docstatus":0},
 			"Time Log": {"status":"Draft"},
 			"Time Log Batch": {"status":"Draft"},
 		}
-	}
\ No newline at end of file
+	}
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/item/item.js b/erpnext/stock/doctype/item/item.js
index 33b1720..eec8ec2 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -3,200 +3,207 @@
 
 frappe.provide("erpnext.item");
 
-frappe.ui.form.on("Item", "refresh", function(frm) {
-	if(frm.doc.is_stock_item) {
-		frm.add_custom_button(__("Show Balance"), function() {
-			frappe.route_options = {
-				"item_code": frm.doc.name
-			}
-			frappe.set_route("query-report", "Stock Balance");
-		});
-	}
-})
-
-cur_frm.cscript.refresh = function(doc) {
-	// make sensitive fields(has_serial_no, is_stock_item, valuation_method)
-	// read only if any stock ledger entry exists
-
-	cur_frm.cscript.make_dashboard();
-
-	if (cur_frm.doc.has_variants) {
-		cur_frm.set_intro(__("This Item is a Template and cannot be used in transactions. Item attributes will be copied over into the variants unless 'No Copy' is set"), true);
-		cur_frm.add_custom_button(__("Show Variants"), function() {
-			frappe.set_route("List", "Item", {"variant_of": cur_frm.doc.name});
-		}, "icon-list", "btn-default");
-	}
-	if (cur_frm.doc.variant_of) {
-		cur_frm.set_intro(__("This Item is a Variant of {0} (Template). Attributes will be copied over from the template unless 'No Copy' is set", [cur_frm.doc.variant_of]), true);
-	}
-
-	if (frappe.defaults.get_default("item_naming_by")!="Naming Series") {
-		cur_frm.toggle_display("naming_series", false);
-	} else {
-		erpnext.toggle_naming_series();
-	}
-
-
-	cur_frm.cscript.edit_prices_button();
-
-	if (!doc.__islocal && doc.is_stock_item == 'Yes') {
-		cur_frm.toggle_enable(['has_serial_no', 'is_stock_item', 'valuation_method', 'has_batch_no'],
-			(doc.__onload && doc.__onload.sle_exists=="exists") ? false : true);
-	}
-
-	erpnext.item.toggle_reqd(cur_frm);
-}
-
-erpnext.item.toggle_reqd = function(frm) {
-	frm.toggle_reqd("default_warehouse", frm.doc.is_stock_item==="Yes");
-};
-
-frappe.ui.form.on("Item", "onload", function(frm) {
-	var df = frappe.meta.get_docfield("Item Variant", "item_attribute_value");
-	df.on_make = function(field) {
-		field.$input.autocomplete({
-			minLength: 0,
-			minChars: 0,
-			source: function(request, response) {
-				frappe.call({
-					method:"frappe.client.get_list",
-					args:{
-						doctype:"Item Attribute Value",
-						filters: [
-							["parent","=", field.doc.item_attribute],
-							["attribute_value", "like", request.term + "%"]
-						],
-						fields: ["attribute_value"]
-					},
-					callback: function(r) {
-						response($.map(r.message, function(d) { return d.attribute_value; }));
+frappe.ui.form.on("Item", {
+	onload: function(frm) {
+		var df = frappe.meta.get_docfield("Item Variant", "item_attribute_value");
+		df.on_make = function(field) {
+			field.$input.autocomplete({
+				minLength: 0,
+				minChars: 0,
+				source: function(request, response) {
+					frappe.call({
+						method:"frappe.client.get_list",
+						args:{
+							doctype:"Item Attribute Value",
+							filters: [
+								["parent","=", field.doc.item_attribute],
+								["attribute_value", "like", request.term + "%"]
+							],
+							fields: ["attribute_value"]
+						},
+						callback: function(r) {
+							response($.map(r.message, function(d) { return d.attribute_value; }));
+						}
+					});
+				},
+				select: function(event, ui) {
+					field.$input.val(ui.item.value);
+					field.$input.trigger("change");
+				},
+				focus: function( event, ui ) {
+					if(ui.item.action) {
+						return false;
 					}
-				});
-			},
-			select: function(event, ui) {
-				field.$input.val(ui.item.value);
-				field.$input.trigger("change");
-			},
-			focus: function( event, ui ) {
-				if(ui.item.action) {
-					return false;
+				},
+			});
+		}
+
+		erpnext.item.setup_queries(frm);
+	},
+
+	refresh: function(frm) {
+		if(frm.doc.is_stock_item) {
+			frm.add_custom_button(__("Show Balance"), function() {
+				frappe.route_options = {
+					"item_code": frm.doc.name
 				}
-			},
+				frappe.set_route("query-report", "Stock Balance");
+			});
+		}
+
+		// make sensitive fields(has_serial_no, is_stock_item, valuation_method)
+		// read only if any stock ledger entry exists
+		erpnext.item.make_dashboard(frm);
+
+		if (frm.doc.has_variants) {
+			frm.set_intro(__("This Item is a Template and cannot be used in transactions. Item attributes will be copied over into the variants unless 'No Copy' is set"), true);
+			frm.add_custom_button(__("Show Variants"), function() {
+				frappe.set_route("List", "Item", {"variant_of": frm.doc.name});
+			}, "icon-list", "btn-default");
+		}
+		if (frm.doc.variant_of) {
+			frm.set_intro(__("This Item is a Variant of {0} (Template). Attributes will be copied over from the template unless 'No Copy' is set", [frm.doc.variant_of]), true);
+		}
+
+		if (frappe.defaults.get_default("item_naming_by")!="Naming Series") {
+			frm.toggle_display("naming_series", false);
+		} else {
+			erpnext.toggle_naming_series();
+		}
+
+		erpnext.item.edit_prices_button(frm);
+
+		if (!frm.doc.__islocal && frm.doc.is_stock_item == 'Yes') {
+			frm.toggle_enable(['has_serial_no', 'is_stock_item', 'valuation_method', 'has_batch_no'],
+				(frm.doc.__onload && frm.doc.__onload.sle_exists=="exists") ? false : true);
+		}
+
+		erpnext.item.toggle_reqd(frm);
+	},
+
+	validate: function(frm){
+		erpnext.item.weight_to_validate(frm);
+	},
+
+	image: function(frm) {
+		refresh_field("image_view");
+	},
+
+	page_name: frappe.utils.warn_page_name_change,
+
+	item_code: function(frm) {
+		if(!frm.doc.item_name)
+			frm.set_value("item_name", frm.doc.item_code);
+		if(!frm.doc.description)
+			frm.set_value("description", frm.doc.item_code);
+	},
+
+	tax_type: function(frm, cdt, cdn){
+		var d = locals[cdt][cdn];
+		return get_server_fields('get_tax_rate', d.tax_type, 'taxes', doc, cdt, cdn, 1);
+	},
+
+	copy_from_item_group: function(frm) {
+		return frm.call({
+			doc: frm.doc,
+			method: "copy_specification_from_item_group"
 		});
-	}
+	},
 });
 
-cur_frm.cscript.make_dashboard = function() {
-	cur_frm.dashboard.reset();
-	if(cur_frm.doc.__islocal)
-		return;
-}
-
-cur_frm.cscript.edit_prices_button = function() {
-	cur_frm.add_custom_button(__("Add / Edit Prices"), function() {
-		frappe.set_route("Report", "Item Price", {"item_code": cur_frm.doc.name});
-	}, "icon-money", "btn-default");
-}
-
-cur_frm.cscript.item_code = function(doc) {
-	if(!doc.item_name)
-		cur_frm.set_value("item_name", doc.item_code);
-	if(!doc.description)
-		cur_frm.set_value("description", doc.item_code);
-}
-
-// Expense Account
-// ---------------------------------
-cur_frm.fields_dict['expense_account'].get_query = function(doc) {
-	return {
-		filters: {
-			"report_type": "Profit and Loss",
-			"group_or_ledger": "Ledger"
+$.extend(erpnext.item, {
+	setup_queries: function(frm) {
+		// Expense Account
+		// ---------------------------------
+		frm.fields_dict['expense_account'].get_query = function(doc) {
+			return {
+				filters: {
+					"report_type": "Profit and Loss",
+					"group_or_ledger": "Ledger"
+				}
+			}
 		}
-	}
-}
 
-// Income Account
-// --------------------------------
-cur_frm.fields_dict['income_account'].get_query = function(doc) {
-	return {
-		filters: {
-			"report_type": "Profit and Loss",
-			'group_or_ledger': "Ledger",
-			'account_type': "Income Account"
+		// Income Account
+		// --------------------------------
+		frm.fields_dict['income_account'].get_query = function(doc) {
+			return {
+				filters: {
+					"report_type": "Profit and Loss",
+					'group_or_ledger': "Ledger",
+					'account_type': "Income Account"
+				}
+			}
 		}
-	}
-}
 
 
-// Purchase Cost Center
-// -----------------------------
-cur_frm.fields_dict['buying_cost_center'].get_query = function(doc) {
-	return {
-		filters:{ 'group_or_ledger': "Ledger" }
-	}
-}
+		// Purchase Cost Center
+		// -----------------------------
+		frm.fields_dict['buying_cost_center'].get_query = function(doc) {
+			return {
+				filters:{ 'group_or_ledger': "Ledger" }
+			}
+		}
 
 
-// Sales Cost Center
-// -----------------------------
-cur_frm.fields_dict['selling_cost_center'].get_query = function(doc) {
-	return {
-		filters:{ 'group_or_ledger': "Ledger" }
-	}
-}
+		// Sales Cost Center
+		// -----------------------------
+		frm.fields_dict['selling_cost_center'].get_query = function(doc) {
+			return {
+				filters:{ 'group_or_ledger': "Ledger" }
+			}
+		}
 
 
-cur_frm.fields_dict['taxes'].grid.get_field("tax_type").get_query = function(doc, cdt, cdn) {
-	return {
-		filters: [
-			['Account', 'account_type', 'in',
-				'Tax, Chargeable, Income Account, Expense Account'],
-			['Account', 'docstatus', '!=', 2]
-		]
-	}
-}
+		frm.fields_dict['taxes'].grid.get_field("tax_type").get_query = function(doc, cdt, cdn) {
+			return {
+				filters: [
+					['Account', 'account_type', 'in',
+						'Tax, Chargeable, Income Account, Expense Account'],
+					['Account', 'docstatus', '!=', 2]
+				]
+			}
+		}
 
-cur_frm.cscript.tax_type = function(doc, cdt, cdn){
-	var d = locals[cdt][cdn];
-	return get_server_fields('get_tax_rate', d.tax_type, 'taxes', doc, cdt, cdn, 1);
-}
+		frm.fields_dict['item_group'].get_query = function(doc,cdt,cdn) {
+			return {
+				filters: [
+					['Item Group', 'docstatus', '!=', 2]
+				]
+			}
+		}
 
-cur_frm.fields_dict['item_group'].get_query = function(doc,cdt,cdn) {
-	return {
-		filters: [
-			['Item Group', 'docstatus', '!=', 2]
-		]
-	}
-}
+		frm.fields_dict.customer_items.grid.get_field("customer_name").get_query = function(doc, cdt, cdn) {
+			return { query: "erpnext.controllers.queries.customer_query" }
+		}
 
-// Quotation to validation - either customer or lead mandatory
-cur_frm.cscript.weight_to_validate = function(doc, cdt, cdn){
-	if((doc.nett_weight || doc.gross_weight) && !doc.weight_uom) {
-		msgprint(__('Weight is mentioned,\nPlease mention "Weight UOM" too'));
-		validated = 0;
-	}
-}
+		frm.fields_dict.supplier_items.grid.get_field("supplier").get_query = function(doc, cdt, cdn) {
+			return { query: "erpnext.controllers.queries.supplier_query" }
+		}
 
-cur_frm.cscript.validate = function(doc, cdt, cdn){
-	cur_frm.cscript.weight_to_validate(doc, cdt, cdn);
-}
+	},
 
-cur_frm.fields_dict.customer_items.grid.get_field("customer_name").get_query = function(doc, cdt, cdn) {
-	return { query: "erpnext.controllers.queries.customer_query" }
-}
+	toggle_reqd: function(frm) {
+		frm.toggle_reqd("default_warehouse", frm.doc.is_stock_item==="Yes");
+	},
 
-cur_frm.fields_dict.supplier_items.grid.get_field("supplier").get_query = function(doc, cdt, cdn) {
-	return { query: "erpnext.controllers.queries.supplier_query" }
-}
+	make_dashboard: function(frm) {
+		frm.dashboard.reset();
+		if(frm.doc.__islocal)
+			return;
+	},
 
-cur_frm.cscript.copy_from_item_group = function(doc) {
-	return cur_frm.call({
-		doc: doc,
-		method: "copy_specification_from_item_group"
-	});
-}
+	edit_prices_button: function(frm) {
+		frm.add_custom_button(__("Add / Edit Prices"), function() {
+			frappe.set_route("Report", "Item Price", {"item_code": frm.doc.name});
+		}, "icon-money", "btn-default");
+	},
 
-cur_frm.cscript.image = function() {
-	refresh_field("image_view");
-}
+	weight_to_validate: function(frm){
+		if((frm.doc.nett_weight || frm.doc.gross_weight) && !frm.doc.weight_uom) {
+			msgprint(__('Weight is mentioned,\nPlease mention "Weight UOM" too'));
+			validated = 0;
+		}
+	},
+
+});
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index 70826fb..28bfb5a 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -772,7 +772,7 @@
    "label": "Page Name", 
    "no_copy": 1, 
    "permlevel": 0, 
-   "read_only": 1
+   "read_only": 0
   }, 
   {
    "depends_on": "show_in_website", 
@@ -876,7 +876,7 @@
  "icon": "icon-tag", 
  "idx": 1, 
  "max_attachments": 1, 
- "modified": "2015-02-24 05:19:07.382483", 
+ "modified": "2015-02-25 02:46:14.483577", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Item", 
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..16e7a89 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,75 +386,13 @@
    "read_only": 1
   }, 
   {
-   "depends_on": "eval:(doc.purpose!==\"Sales Return\" && doc.purpose!==\"Purchase Return\")", 
-   "fieldname": "sb1", 
-   "fieldtype": "Section Break", 
-   "label": "From Bill of Materials", 
+   "description": "This will override Difference Account in Item", 
+   "fieldname": "difference_account", 
+   "fieldtype": "Link", 
+   "label": "Difference Account", 
+   "options": "Account", 
    "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
+   "precision": ""
   }, 
   {
    "fieldname": "fold", 
@@ -632,7 +654,7 @@
  "is_submittable": 1, 
  "issingle": 0, 
  "max_attachments": 0, 
- "modified": "2015-02-20 05:04:09.060180", 
+ "modified": "2015-02-25 06:13:11.899840", 
  "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 a48c5f3..f4f1eec 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -45,25 +45,25 @@
 		self.get("__onload").credit_debit_note_exists = 1 if count else 0
 
 	def validate(self):
+		self.pro_doc = None
+		if self.production_order:
+			self.pro_doc = frappe.get_doc('Production Order', self.production_order)
+
 		self.validate_posting_time()
 		self.validate_purpose()
-		pro_obj = self.production_order and \
-			frappe.get_doc('Production Order', self.production_order) or None
-
 		validate_fiscal_year(self.posting_date, self.fiscal_year, self.meta.get_label("posting_date"), self)
-
 		self.validate_item()
 		self.set_transfer_qty()
 		self.validate_uom_is_integer("uom", "qty")
 		self.validate_uom_is_integer("stock_uom", "transfer_qty")
-		self.validate_warehouse(pro_obj)
+		self.validate_warehouse()
 		self.validate_production_order()
 		self.get_stock_and_rate()
 		self.validate_bom()
 		self.validate_finished_goods()
 		self.validate_return_reference_doc()
 		self.validate_with_material_request()
-		#self.validate_valuation_rate()
+		self.validate_valuation_rate()
 		self.set_total_incoming_outgoing_value()
 		self.set_total_amount()
 
@@ -86,6 +86,12 @@
 		if self.purpose not in valid_purposes:
 			frappe.throw(_("Purpose must be one of {0}").format(comma_or(valid_purposes)))
 
+		if self.purpose in ("Manufacture", "Repack", "Sales Return") and not self.difference_account:
+			self.difference_account = frappe.db.get_value("Company", self.company, "default_expense_account")
+
+		if self.purpose in ("Purchase Return") and not self.difference_account:
+			frappe.throw(_("Difference Account mandatory for purpose '{0}'").format(self.purpose))
+
 	def set_transfer_qty(self):
 		for item in self.get("items"):
 			if not flt(item.qty):
@@ -108,6 +114,9 @@
 					if f not in ["expense_account", "cost_center"] or not item.get(f):
 						item.set(f, item_details.get(f))
 
+			if self.difference_account:
+				item.expense_account = self.difference_account
+
 			if not item.transfer_qty:
 				item.transfer_qty = item.qty * item.conversion_factor
 
@@ -117,7 +126,7 @@
 				frappe.throw(_("Row #{0}: Please specify Serial No for Item {1}").format(item.idx, item.item_code),
 					frappe.MandatoryError)
 
-	def validate_warehouse(self, pro_obj):
+	def validate_warehouse(self):
 		"""perform various (sometimes conditional) validations on warehouse"""
 
 		source_mandatory = ["Material Issue", "Material Transfer", "Purchase Return", "Subcontract", "Material Transfer for Manufacture"]
@@ -156,7 +165,7 @@
 						if not d.t_warehouse:
 							frappe.throw(_("Target warehouse is mandatory for row {0}").format(d.idx))
 
-						elif pro_obj and cstr(d.t_warehouse) != pro_obj.fg_warehouse:
+						elif self.pro_doc and cstr(d.t_warehouse) != self.pro_doc.fg_warehouse:
 							frappe.throw(_("Target warehouse in row {0} must be same as Production Order").format(d.idx))
 
 					else:
@@ -272,37 +281,45 @@
 				incoming_rate = flt(self.get_incoming_rate(args), self.precision("incoming_rate", d))
 				if incoming_rate > 0:
 					d.incoming_rate = incoming_rate
+
 			d.amount = flt(d.transfer_qty) * flt(d.incoming_rate)
 			if not d.t_warehouse:
 				raw_material_cost += flt(d.amount)
 
+		self.add_operation_cost(raw_material_cost, force)
+
+	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.purpose in ("Manufacture", "Repack"):
-			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):
-					if not flt(d.incoming_rate) or force:
-						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
+		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
 
 	def get_operation_cost_per_unit(self, bom_no, qty):
+		"""Returns operating cost from Production Order for given `bom_no`"""
 		operation_cost_per_unit = 0
 
 		if self.production_order:
-			pro_order = frappe.get_doc("Production Order", self.production_order)
-			for d in pro_order.get("operations"):
+			if not getattr(self, "pro_doc", None):
+				self.pro_doc = frappe.get_doc("Production Order", self.production_order)
+			for d in self.pro_doc.get("operations"):
 				if flt(d.completed_qty):
 					operation_cost_per_unit += flt(d.actual_operating_cost) / flt(d.completed_qty)
 				else:
-					operation_cost_per_unit += flt(d.planned_operating_cost) / flt(pro_order.qty)
+					operation_cost_per_unit += flt(d.planned_operating_cost) / flt(self.pro_doc.qty)
 
+		# set operating cost from BOM if specified.
 		if not operation_cost_per_unit and bom_no:
 			bom = frappe.db.get_value("BOM", bom_no, ["operating_cost", "quantity"], as_dict=1)
 			operation_cost_per_unit = flt(bom.operating_cost) / flt(bom.quantity)
 
-		return operation_cost_per_unit + flt(self.additional_operating_cost) / flt(qty)
+		return operation_cost_per_unit + (flt(self.additional_operating_cost) / flt(qty))
 
 	def get_incoming_rate(self, args):
 		incoming_rate = 0
@@ -503,12 +520,16 @@
 		self.set('items', [])
 		self.validate_production_order()
 
-		pro_obj = None
+		if not getattr(self, "pro_doc", None):
+			self.pro_doc = None
+
 		if self.production_order:
 			# common validations
-			pro_obj = frappe.get_doc('Production Order', self.production_order)
-			if pro_obj:
-				self.bom_no = pro_obj.bom_no
+			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:
 				# invalid production order
 				self.production_order = None
@@ -517,18 +538,18 @@
 			if self.purpose in ["Material Issue", "Material Transfer", "Manufacture", "Repack",
 					"Subcontract", "Material Transfer for Manufacture"]:
 				if self.production_order and self.purpose == "Material Transfer for Manufacture":
-					item_dict = self.get_pending_raw_materials(pro_obj)
-					if self.to_warehouse and pro_obj:
+					item_dict = self.get_pending_raw_materials()
+					if self.to_warehouse and self.pro_doc:
 						for item in item_dict.values():
-							item["to_warehouse"] = pro_obj.wip_warehouse
+							item["to_warehouse"] = self.pro_doc.wip_warehouse
 				else:
 					if not self.fg_completed_qty:
 						frappe.throw(_("Manufacturing Quantity is mandatory"))
 
 					item_dict = self.get_bom_raw_materials(self.fg_completed_qty)
 					for item in item_dict.values():
-						if pro_obj:
-							item["from_warehouse"] = pro_obj.wip_warehouse
+						if self.pro_doc:
+							item["from_warehouse"] = self.pro_doc.wip_warehouse
 
 						item["to_warehouse"] = self.to_warehouse if self.purpose=="Subcontract" else ""
 
@@ -537,31 +558,34 @@
 
 			# add finished goods item
 			if self.purpose in ("Manufacture", "Repack"):
-				if self.production_order:
-					item_code = pro_obj.production_item
-					to_warehouse = pro_obj.fg_warehouse
-				else:
-					item_code = frappe.db.get_value("BOM", self.bom_no, "item")
-					to_warehouse = ""
-
-				item = frappe.db.get_value("Item", item_code, ["item_name",
-					"description", "stock_uom", "expense_account", "buying_cost_center", "name"], as_dict=1)
-
-				self.add_to_stock_entry_detail({
-					item.name: {
-						"to_warehouse": to_warehouse,
-						"from_warehouse": "",
-						"qty": self.fg_completed_qty,
-						"item_name": item.item_name,
-						"description": item.description,
-						"stock_uom": item.stock_uom,
-						"expense_account": item.expense_account,
-						"cost_center": item.buying_cost_center,
-					}
-				}, bom_no = self.bom_no)
+				self.load_items_from_bom()
 
 		self.get_stock_and_rate()
 
+	def load_items_from_bom(self):
+		if self.production_order:
+			item_code = self.pro_doc.production_item
+			to_warehouse = self.pro_doc.fg_warehouse
+		else:
+			item_code = frappe.db.get_value("BOM", self.bom_no, "item")
+			to_warehouse = ""
+
+		item = frappe.db.get_value("Item", item_code, ["item_name",
+			"description", "stock_uom", "expense_account", "buying_cost_center", "name"], as_dict=1)
+
+		self.add_to_stock_entry_detail({
+			item.name: {
+				"to_warehouse": to_warehouse,
+				"from_warehouse": "",
+				"qty": self.fg_completed_qty,
+				"item_name": item.item_name,
+				"description": item.description,
+				"stock_uom": item.stock_uom,
+				"expense_account": item.expense_account,
+				"cost_center": item.buying_cost_center,
+			}
+		}, bom_no = self.bom_no)
+
 	def get_bom_raw_materials(self, qty):
 		from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
 
@@ -573,7 +597,7 @@
 
 		return item_dict
 
-	def get_pending_raw_materials(self, pro_obj):
+	def get_pending_raw_materials(self):
 		"""
 			issue (item quantity) that is pending to issue or desire to transfer,
 			whichever is less
@@ -581,7 +605,7 @@
 		item_dict = self.get_bom_raw_materials(1)
 		issued_item_qty = self.get_issued_qty()
 
-		max_qty = flt(pro_obj.qty)
+		max_qty = flt(self.pro_doc.qty)
 		only_pending_fetched = []
 
 		for item in item_dict:
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 14a54e9..0845a6b 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -10,12 +10,19 @@
 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()
 		self.validate_expense_account()
@@ -214,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
diff --git a/erpnext/templates/form_grid/stock_entry_grid.html b/erpnext/templates/form_grid/stock_entry_grid.html
index 2527ef3..efb4ab6 100644
--- a/erpnext/templates/form_grid/stock_entry_grid.html
+++ b/erpnext/templates/form_grid/stock_entry_grid.html
@@ -15,12 +15,10 @@
 		<div class="col-sm-5 col-xs-4"><strong>{%= doc.item_code %}</strong>
 			{% if(doc.item_name != doc.item_code) { %}
 				<br>{%= doc.item_name %}{% } %}
-            <!-- {% if(doc.item_name != doc.description) { %}
-                <p>{%= doc.description %}</p>{% } %} -->
 			{% include "templates/form_grid/includes/visible_cols.html" %}
 			{% if(frm.doc.docstatus==0 && doc.s_warehouse && doc.actual_qty < doc.qty) { %}
                 <span class="text-danger small" style="margin-left: 15px;">
-                    <span class="octicon octicon-stop" style="font-size: 12px;"></span> Not in Stock
+                    Not in Stock
                 </span>
             {% } %}
 		</div>
diff --git a/test_sites/test_site/site_config.json b/test_sites/test_site/site_config.json
index 31a445b..96f3446 100644
--- a/test_sites/test_site/site_config.json
+++ b/test_sites/test_site/site_config.json
@@ -5,5 +5,6 @@
  "auto_email_id": "admin@example.com",
  "host_name": "http://localhost:8888",
  "auto_email_id": "admin@example.com",
- "mute_emails": 1
+ "mute_emails": 1,
+ "install_apps": ["erpnext"]
 }