Merge pull request #1789 from nabinhait/v4-hotfix

V4 hotfix
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 8755837..02c651f 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -58,3 +58,4 @@
 erpnext.patches.v4_0.create_custom_fields_for_india_specific_fields
 erpnext.patches.v4_0.save_default_letterhead
 erpnext.patches.v4_0.update_custom_print_formats_for_renamed_fields
+erpnext.patches.v4_0.update_other_charges_in_custom_purchase_print_formats
diff --git a/erpnext/patches/v4_0/update_other_charges_in_custom_purchase_print_formats.py b/erpnext/patches/v4_0/update_other_charges_in_custom_purchase_print_formats.py
new file mode 100644
index 0000000..c0f9ee0
--- /dev/null
+++ b/erpnext/patches/v4_0/update_other_charges_in_custom_purchase_print_formats.py
@@ -0,0 +1,12 @@
+# 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
+import re
+
+def execute():
+	for name, html in frappe.db.sql("""select name, html from `tabPrint Format`
+		where standard = 'No' and html like '%%purchase\\_tax\\_details%%'"""):
+			html = re.sub(r"\bpurchase_tax_details\b", "other_charges", html)
+			frappe.db.set_value("Print Format", name, "html", html)
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index ac81f88..d8164f7 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -70,6 +70,9 @@
 
 	def set_transfer_qty(self):
 		for item in self.get("mtn_details"):
+			if not flt(item.qty):
+				frappe.throw(_("Row {0}: Qty is mandatory").format(item.idx))
+
 			item.transfer_qty = flt(item.qty * item.conversion_factor, self.precision("transfer_qty", item))
 
 	def validate_item(self):
@@ -191,6 +194,11 @@
 
 		raw_material_cost = 0.0
 
+		if not self.posting_date or not self.posting_time:
+			frappe.throw(_("Posting date and posting time is mandatory"))
+
+		allow_negative_stock = frappe.db.get_value("Stock Settings", None, "allow_negative_stock")
+
 		for d in self.get('mtn_details'):
 			args = frappe._dict({
 				"item_code": d.item_code,
@@ -200,13 +208,21 @@
 				"qty": d.s_warehouse and -1*d.transfer_qty or d.transfer_qty,
 				"serial_no": d.serial_no
 			})
+
 			# get actual stock at source warehouse
 			d.actual_qty = get_previous_sle(args).get("qty_after_transaction") or 0
 
+			if d.s_warehouse and not allow_negative_stock and d.actual_qty <= d.transfer_qty:
+				frappe.throw(_("""Row {0}: Qty not avalable in warehouse {1} on {2} {3}.
+					Available Qty: {4}, Transfer Qty: {5}""").format(d.idx, d.s_warehouse,
+					self.posting_date, self.posting_time, d.actual_qty, d.transfer_qty))
+
 			# get incoming rate
 			if not d.bom_no:
-				if not flt(d.incoming_rate):
-					d.incoming_rate = self.get_incoming_rate(args)
+				if not flt(d.incoming_rate) or d.s_warehouse or self.purpose == "Sales Return":
+					incoming_rate = self.get_incoming_rate(args)
+					if incoming_rate:
+						d.incoming_rate = incoming_rate
 
 				d.amount = flt(d.transfer_qty) * flt(d.incoming_rate)
 				raw_material_cost += flt(d.amount)