Merge branch 'hotfix'
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index fd0f5c1..6ec290c 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
 from erpnext.hooks import regional_overrides
 from frappe.utils import getdate
 
-__version__ = '10.1.4'
+__version__ = '10.1.5'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index 496f412..9e3fa71 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -145,13 +145,13 @@
 			frm.doc.paid_amount : frm.doc.received_amount;
 
 		frm.toggle_display("write_off_difference_amount", (frm.doc.difference_amount && frm.doc.party &&
-			(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) &&
 			(frm.doc.total_allocated_amount > party_amount)));
 
 		frm.toggle_display("set_exchange_gain_loss",
 			(frm.doc.paid_amount && frm.doc.received_amount && frm.doc.difference_amount &&
-				(frm.doc.paid_from_account_currency != company_currency ||
-					frm.doc.paid_to_account_currency != company_currency)));
+				((frm.doc.paid_from_account_currency != company_currency ||
+					frm.doc.paid_to_account_currency != company_currency) && 
+					frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency)));
 
 		frm.refresh_fields();
 	},
@@ -300,7 +300,15 @@
 				if(frm.doc.payment_type == "Pay") {
 					frm.events.get_outstanding_documents(frm);
 				} else if (frm.doc.payment_type == "Receive") {
-					frm.events.received_amount(frm);
+					if(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) {
+						if(frm.doc.source_exchange_rate) {
+							frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate);
+						}
+						frm.set_value("received_amount", frm.doc.paid_amount);
+						
+					} else {
+						frm.events.received_amount(frm);
+					}
 				}
 			}
 		);
@@ -317,26 +325,31 @@
 				},
 				callback: function(r, rt) {
 					if(r.message) {
-						frm.set_value(currency_field, r.message['account_currency']);
-						frm.set_value(balance_field, r.message['account_balance']);
+						frappe.run_serially([
+							() => frm.set_value(currency_field, r.message['account_currency']),
+							() => {
+								frm.set_value(balance_field, r.message['account_balance']);
 
-						if(frm.doc.payment_type=="Receive" && currency_field=="paid_to_account_currency") {
-							frm.toggle_reqd(["reference_no", "reference_date"],
-								(r.message['account_type'] == "Bank" ? 1 : 0));
-							if(!frm.doc.received_amount && frm.doc.paid_amount)
-								frm.events.paid_amount(frm);
-						} else if(frm.doc.payment_type=="Pay" && currency_field=="paid_from_account_currency") {
-							frm.toggle_reqd(["reference_no", "reference_date"],
-								(r.message['account_type'] == "Bank" ? 1 : 0));
+								if(frm.doc.payment_type=="Receive" && currency_field=="paid_to_account_currency") {
+									frm.toggle_reqd(["reference_no", "reference_date"],
+										(r.message['account_type'] == "Bank" ? 1 : 0));
+									if(!frm.doc.received_amount && frm.doc.paid_amount)
+										frm.events.paid_amount(frm);
+								} else if(frm.doc.payment_type=="Pay" && currency_field=="paid_from_account_currency") {
+									frm.toggle_reqd(["reference_no", "reference_date"],
+										(r.message['account_type'] == "Bank" ? 1 : 0));
 
-							if(!frm.doc.paid_amount && frm.doc.received_amount)
-								frm.events.received_amount(frm);
-						}
+									if(!frm.doc.paid_amount && frm.doc.received_amount)
+										frm.events.received_amount(frm);
+								}
+							},
+							() => {
+								if(callback_function) callback_function(frm);
 
-						if(callback_function) callback_function(frm);
-
-						frm.events.hide_unhide_fields(frm);
-						frm.events.set_dynamic_labels(frm);
+								frm.events.hide_unhide_fields(frm);
+								frm.events.set_dynamic_labels(frm);
+							}
+						]);
 					}
 				}
 			});			
@@ -405,7 +418,7 @@
 				frm.set_value("base_received_amount", frm.doc.base_paid_amount);
 			}
 			
-			frm.events.set_difference_amount(frm);
+			frm.events.set_unallocated_amount(frm);
 		}
 
 		// Make read only if Accounts Settings doesn't allow stale rates
@@ -425,7 +438,7 @@
 				frm.set_value("base_paid_amount", frm.doc.base_received_amount);
 			}
 			
-			frm.events.set_difference_amount(frm);
+			frm.events.set_unallocated_amount(frm);
 		}
 		frm.set_paid_amount_based_on_received_amount = false;
 
@@ -456,7 +469,7 @@
 		if(frm.doc.payment_type == "Pay")
 			frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount);
 		else
-			frm.events.set_difference_amount(frm);
+			frm.events.set_unallocated_amount(frm);
 		
 		frm.set_paid_amount_based_on_received_amount = false;
 	},
@@ -476,7 +489,7 @@
 		if(frm.doc.payment_type == "Receive")
 			frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount);
 		else
-			frm.events.set_difference_amount(frm);
+			frm.events.set_unallocated_amount(frm);
 	},
 
 	get_outstanding_documents: function(frm) {
@@ -565,8 +578,11 @@
 		if(frm.doc.references.length == 0){
 			frm.events.get_outstanding_documents(frm);
 		}
-
-		frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount);
+		if(frm.doc.payment_type == 'Internal Transfer') {
+			frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount);
+		} else {
+			frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount);
+		}
 	},
 
 	allocate_party_amount_against_ref_docs: function(frm, paid_amount) {
@@ -651,10 +667,10 @@
 		frm.set_value("total_allocated_amount", Math.abs(total_allocated_amount));
 		frm.set_value("base_total_allocated_amount", Math.abs(base_total_allocated_amount));
 
-		frm.events.set_difference_amount(frm);
+		frm.events.set_unallocated_amount(frm);
 	},
 
-	set_difference_amount: function(frm) {
+	set_unallocated_amount: function(frm) {
 		var unallocated_amount = 0;
 		var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
 			function(d) { return flt(d.amount) }));
@@ -662,17 +678,34 @@
 		if(frm.doc.party) {
 			var party_amount = frm.doc.payment_type=="Receive" ?
 				frm.doc.paid_amount : frm.doc.received_amount;
+			var company_currency = frm.doc.company? frappe.get_doc(":Company", frm.doc.company).default_currency: "";
 
-			if(frm.doc.total_allocated_amount < party_amount) {
-				if(frm.doc.payment_type == "Receive") {
+			if (frm.doc.party_account_currency == company_currency) {
+				if(frm.doc.payment_type == "Receive" && frm.doc.total_allocated_amount <= party_amount + total_deductions) {
 					unallocated_amount = party_amount - (frm.doc.total_allocated_amount - total_deductions);
-				} else {
+				} else if (frm.doc.payment_type == "Pay" && frm.doc.total_allocated_amount <= party_amount - total_deductions) {
 					unallocated_amount = party_amount - (frm.doc.total_allocated_amount + total_deductions);
 				}
+			} else {
+				if(frm.doc.payment_type == "Receive"
+					&& frm.doc.base_total_allocated_amount <= frm.doc.base_received_amount + total_deductions
+					&& frm.doc.total_allocated_amount < frm.doc.paid_amount) {
+						unallocated_amount = (frm.doc.base_received_amount + total_deductions
+							- frm.doc.base_total_allocated_amount) / frm.doc.source_exchange_rate;
+				} else if (frm.doc.payment_type == "Pay"
+					&& frm.doc.base_total_allocated_amount < frm.doc.base_paid_amount - total_deductions
+					&& frm.doc.total_allocated_amount < frm.doc.received_amount) {
+						unallocated_amount = (frm.doc.base_paid_amount - (total_deductions
+							+ frm.doc.base_total_allocated_amount)) / frm.doc.target_exchange_rate;
+				}
 			}
+			
 		}
 		frm.set_value("unallocated_amount", unallocated_amount);
-
+		frm.trigger("set_difference_amount");
+	},
+	
+	set_difference_amount: function(frm) {
 		var difference_amount = 0;
 		var base_unallocated_amount = flt(frm.doc.unallocated_amount) *
 			(frm.doc.payment_type=="Receive" ? frm.doc.source_exchange_rate : frm.doc.target_exchange_rate);
@@ -687,11 +720,18 @@
 			difference_amount = flt(frm.doc.base_paid_amount) - flt(frm.doc.base_received_amount);
 		}
 
+		var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
+			function(d) { return flt(d.amount) }));
+
 		frm.set_value("difference_amount", difference_amount - total_deductions);
 
 		frm.events.hide_unhide_fields(frm);
 	},
 
+	unallocated_amount: function(frm) {
+		frm.trigger("set_difference_amount");
+	},
+
 	check_mandatory_to_fetch: function(frm) {
 		$.each(["Company", "Party Type", "Party", "payment_type"], function(i, field) {
 			if(!frm.doc[frappe.model.scrub(field)]) {
@@ -771,7 +811,7 @@
 						row.amount = flt(row.amount) + flt(frm.doc.difference_amount);
 						refresh_field("deductions");
 
-						frm.events.set_difference_amount(frm);
+						frm.events.set_unallocated_amount(frm);
 					}
 				}
 			})
@@ -818,10 +858,10 @@
 
 frappe.ui.form.on('Payment Entry Deduction', {
 	amount: function(frm) {
-		frm.events.set_difference_amount(frm);
+		frm.events.set_unallocated_amount(frm);
 	},
 
 	deductions_remove: function(frm) {
-		frm.events.set_difference_amount(frm);
+		frm.events.set_unallocated_amount(frm);
 	}
 })
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json
index abf4ac9..9e9a4f1 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.json
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json
@@ -40,6 +40,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -71,6 +72,7 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 1, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -102,6 +104,7 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -131,6 +134,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -162,6 +166,7 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -193,6 +198,7 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -224,6 +230,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -255,6 +262,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -288,6 +296,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -320,6 +329,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -349,6 +359,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -381,6 +392,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -411,6 +423,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -442,6 +455,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -474,6 +488,7 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -506,6 +521,7 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -538,6 +554,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -567,6 +584,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -599,6 +617,7 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -631,6 +650,7 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -663,6 +683,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -695,6 +716,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -727,6 +749,7 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -758,6 +781,7 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -790,6 +814,7 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -819,6 +844,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -851,6 +877,7 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -882,6 +909,7 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -914,6 +942,7 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -946,6 +975,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -978,6 +1008,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1010,6 +1041,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1041,6 +1073,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1072,6 +1105,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1104,6 +1138,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1134,6 +1169,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1163,6 +1199,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1188,12 +1225,13 @@
    "precision": "", 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
-   "read_only": 1, 
+   "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1226,6 +1264,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1257,6 +1296,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1289,6 +1329,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1320,6 +1361,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1350,6 +1392,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1381,6 +1424,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1410,6 +1454,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1441,6 +1486,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1472,6 +1518,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1504,6 +1551,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1536,6 +1584,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1566,6 +1615,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1595,6 +1645,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1626,6 +1677,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1657,6 +1709,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1687,6 +1740,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1718,6 +1772,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1748,6 +1803,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -1778,6 +1834,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }
  ], 
@@ -1791,7 +1848,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-08-31 11:20:37.578469", 
+ "modified": "2018-02-19 16:58:23.899015", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Payment Entry", 
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index e19295c..7561b35 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -286,17 +286,30 @@
 		self.base_total_allocated_amount = abs(base_total_allocated_amount)
 
 	def set_unallocated_amount(self):
-		self.unallocated_amount = 0;
+		self.unallocated_amount = 0
 		if self.party:
-			party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount
-
 			total_deductions = sum([flt(d.amount) for d in self.get("deductions")])
 
-			if self.total_allocated_amount < party_amount:
-				if self.payment_type == "Receive":
-					self.unallocated_amount = party_amount - (self.total_allocated_amount - total_deductions)
-				else:
-					self.unallocated_amount = party_amount - (self.total_allocated_amount + total_deductions)
+			if self.party_account_currency == self.company_currency:
+				if self.payment_type == "Receive" \
+					and self.total_allocated_amount <= self.paid_amount + total_deductions:
+						self.unallocated_amount = self.paid_amount - \
+							(self.total_allocated_amount - total_deductions)
+				elif self.payment_type == "Pay" \
+					and self.total_allocated_amount <= self.received_amount - total_deductions:
+						self.unallocated_amount = self.received_amount - \
+							(self.total_allocated_amount + total_deductions)
+			else:
+				if self.payment_type == "Receive" \
+					and self.base_total_allocated_amount <= self.base_received_amount + total_deductions \
+					and self.total_allocated_amount < self.paid_amount:
+						self.unallocated_amount = (self.base_received_amount + total_deductions - 
+							self.base_total_allocated_amount) / self.source_exchange_rate
+				elif self.payment_type == "Pay" \
+					and self.base_total_allocated_amount < (self.base_paid_amount - total_deductions) \
+					and self.total_allocated_amount < self.received_amount:
+						self.unallocated_amount = (self.base_paid_amount - (total_deductions + 
+							self.base_total_allocated_amount)) / self.target_exchange_rate
 
 	def set_difference_amount(self):
 		base_unallocated_amount = flt(self.unallocated_amount) * (flt(self.source_exchange_rate)
diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
index 64cd3ad..9231ace 100644
--- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
@@ -141,7 +141,6 @@
 	def test_payment_entry_retrieves_last_exchange_rate(self):
 		from erpnext.setup.doctype.currency_exchange.test_currency_exchange import test_records, save_new_records
 
-		test_records = test_records
 		save_new_records(test_records)
 
 		pe = frappe.new_doc("Payment Entry")
@@ -151,6 +150,7 @@
 		pe.paid_from = "_Test Bank USD - _TC"
 		pe.paid_to = "_Test Bank - _TC"
 		pe.paid_amount = 100
+		pe.received_amount = 100
 		pe.reference_no = "3"
 		pe.reference_date = "2016-01-10"
 		pe.party_type = "Supplier"
diff --git a/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json b/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json
index b4d63f8..10e147e 100644
--- a/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json
+++ b/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json
@@ -98,7 +98,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-07-11 03:28:03.420683", 
+ "modified": "2018-02-21 03:28:03.420683", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Payment Entry Deduction", 
diff --git a/erpnext/accounts/doctype/payment_request/test_payment_request.py b/erpnext/accounts/doctype/payment_request/test_payment_request.py
index 8d43950..9cdead8 100644
--- a/erpnext/accounts/doctype/payment_request/test_payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/test_payment_request.py
@@ -61,13 +61,11 @@
 		self.assertEquals(pr.currency, "USD")
 
 	def test_payment_entry(self):
-		frappe.db.set_value("Company", "_Test Company", 
+		frappe.db.set_value("Company", "_Test Company",
 			"exchange_gain_loss_account", "_Test Exchange Gain/Loss - _TC")
-		frappe.db.set_value("Company", "_Test Company", 
-			"write_off_account", "_Test Write Off - _TC")
-		frappe.db.set_value("Company", "_Test Company", 
-			"cost_center", "_Test Cost Center - _TC")
-		
+		frappe.db.set_value("Company", "_Test Company", "write_off_account", "_Test Write Off - _TC")
+		frappe.db.set_value("Company", "_Test Company", "cost_center", "_Test Cost Center - _TC")
+
 		so_inr = make_sales_order(currency="INR")
 		pr = make_payment_request(dt="Sales Order", dn=so_inr.name, recipient_id="saurabh@erpnext.com",
 			mute_email=1, submit_doc=1, return_doc=1)
@@ -82,15 +80,15 @@
 
 		pr = make_payment_request(dt="Sales Invoice", dn=si_usd.name, recipient_id="saurabh@erpnext.com",
 			mute_email=1, payment_gateway="_Test Gateway - USD", submit_doc=1, return_doc=1)
-		
+
 		pe = pr.set_as_paid()
-		
+
 		expected_gle = dict((d[0], d) for d in [
 			["_Test Receivable USD - _TC", 0, 5000, si_usd.name],
 			[pr.payment_account, 6290.0, 0, None],
 			["_Test Exchange Gain/Loss - _TC", 0, 1290, None]
 		])
-		
+
 		gl_entries = frappe.db.sql("""select account, debit, credit, against_voucher
 			from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
 			order by account asc""", pe.name, as_dict=1)
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 93c2206..bb2d071 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -106,7 +106,7 @@
 	on_submit: function(doc, dt, dn) {
 		var me = this;
 
-		if (frappe.get_route()[0] != 'Sales Invoice') {
+		if (frappe.get_route()[0] != 'Form') {
 			return
 		}
 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index e879f40..9e890f6 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -30,8 +30,7 @@
 			'target_parent_field': 'per_ordered',
 			'target_ref_field': 'stock_qty',
 			'source_field': 'stock_qty',
-			'percent_join_field': 'material_request',
-			'overflow_type': 'order'
+			'percent_join_field': 'material_request'
 		}]
 
 	def onload(self):
@@ -232,12 +231,16 @@
 		pass
 
 	def update_status_updater(self):
-		self.status_updater[0].update({
-			"target_parent_dt": "Sales Order",
-			"target_dt": "Sales Order Item",
+		self.status_updater.append({
+			'source_dt': 'Purchase Order Item',
+			'target_dt': 'Sales Order Item',
 			'target_field': 'ordered_qty',
-			"join_field": "sales_order_item",
-			"target_parent_field": ''
+			'target_parent_dt': 'Sales Order',
+			'target_parent_field': '',
+			'join_field': 'sales_order_item',
+			'source_dt': 'Purchase Order Item',
+			'target_ref_field': 'stock_qty',
+			'source_field': 'stock_qty'
 		})
 
 	def update_delivered_qty_in_sales_order(self):
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 472a7a3..1af2fdd 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -666,6 +666,8 @@
 			self.remove(item)
 
 	def set_payment_schedule(self):
+		if self.doctype == 'Sales Invoice' and self.is_pos: return
+
 		posting_date = self.get("bill_date") or self.get("posting_date") or self.get("transaction_date")
 		date = self.get("due_date")
 		due_date = date or posting_date
@@ -695,6 +697,8 @@
 		dates = []
 		li = []
 
+		if self.doctype == 'Sales Invoice' and self.is_pos: return
+
 		for d in self.get("payment_schedule"):
 			if self.doctype == "Sales Order" and getdate(d.due_date) < getdate(self.transaction_date):
 				frappe.throw(_("Row {0}: Due Date cannot be before posting date").format(d.idx))
@@ -708,6 +712,8 @@
 				.format(list=duplicates))
 
 	def validate_payment_schedule_amount(self):
+		if self.doctype == 'Sales Invoice' and self.is_pos: return
+
 		if self.get("payment_schedule"):
 			total = 0
 			for d in self.get("payment_schedule"):
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index d16f063..4b8bbee 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -53,8 +53,9 @@
 
 	valid_items = frappe._dict()
 
-	select_fields = "item_code, qty, rate, parenttype" if doc.doctype=="Purchase Invoice" \
-		else "item_code, qty, rate, serial_no, batch_no, parenttype"
+	select_fields = "item_code, qty, stock_qty, rate, parenttype, conversion_factor"
+	if doc.doctype != 'Purchase Invoice':
+		select_fields += ",serial_no, batch_no"
 
 	if doc.doctype in ['Purchase Invoice', 'Purchase Receipt']:
 		select_fields += ",rejected_qty, received_qty"
@@ -111,7 +112,7 @@
 		frappe.throw(_("Atleast one item should be entered with negative quantity in return document"))
 
 def validate_quantity(doc, args, ref, valid_items, already_returned_items):
-	fields = ['qty']
+	fields = ['stock_qty']
 	if doc.doctype in ['Purchase Receipt', 'Purchase Invoice']:
 		fields.extend(['received_qty', 'rejected_qty'])
 
@@ -119,16 +120,19 @@
 
 	for column in fields:
 		returned_qty = flt(already_returned_data.get(column, 0)) if len(already_returned_data) > 0 else 0
-		reference_qty = ref.get(column)
+		reference_qty = (ref.get(column) if column == 'stock_qty'
+			else ref.get(column) * ref.get("conversion_factor", 1.0))
+
 		max_returnable_qty = flt(reference_qty) - returned_qty
 		label = column.replace('_', ' ').title()
+
 		if reference_qty:	
 			if flt(args.get(column)) > 0:
 				frappe.throw(_("{0} must be negative in return document").format(label))
 			elif returned_qty >= reference_qty and args.get(column):
 				frappe.throw(_("Item {0} has already been returned")
 					.format(args.item_code), StockOverReturnError)
-			elif abs(args.get(column)) > max_returnable_qty:
+			elif (abs(args.get(column)) * args.get("conversion_factor", 1.0)) > max_returnable_qty:
 				frappe.throw(_("Row # {0}: Cannot return more than {1} for Item {2}")
 					.format(args.idx, reference_qty, args.item_code), StockOverReturnError)
 
@@ -138,6 +142,7 @@
 	valid_items.setdefault(ref_item_row.item_code, frappe._dict({
 		"qty": 0,
 		"rate": 0,
+		"stock_qty": 0,
 		"rejected_qty": 0,
 		"received_qty": 0,
 		"serial_no": [],
@@ -145,6 +150,7 @@
 	}))
 	item_dict = valid_items[ref_item_row.item_code]
 	item_dict["qty"] += ref_item_row.qty
+	item_dict["stock_qty"] += ref_item_row.get('stock_qty', 0)
 	if ref_item_row.get("rate", 0) > item_dict["rate"]:
 		item_dict["rate"] = ref_item_row.get("rate", 0)
 
@@ -161,9 +167,10 @@
 	return valid_items
 
 def get_already_returned_items(doc):
-	column = 'child.item_code, sum(abs(child.qty)) as qty'
+	column = 'child.item_code, sum(abs(child.qty)) as qty, sum(abs(child.stock_qty)) as stock_qty'
 	if doc.doctype in ['Purchase Invoice', 'Purchase Receipt']:
-		column += ', sum(abs(child.rejected_qty)) as rejected_qty, sum(abs(child.received_qty)) as received_qty'
+		column += """, sum(abs(child.rejected_qty) * child.conversion_factor) as rejected_qty,
+			sum(abs(child.received_qty) * child.conversion_factor) as received_qty"""
 
 	data = frappe.db.sql("""
 		select {0}
@@ -180,6 +187,7 @@
 	for d in data:
 		items.setdefault(d.item_code, frappe._dict({
 			"qty": d.get("qty"),
+			"stock_qty": d.get("stock_qty"),
 			"received_qty": d.get("received_qty"),
 			"rejected_qty": d.get("rejected_qty")
 		}))
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index 2f54fc0..b46c752 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -250,7 +250,7 @@
 
 			if args['detail_id']:
 				if not args.get("extra_cond"): args["extra_cond"] = ""
-
+				
 				frappe.db.sql("""update `tab%(target_dt)s`
 					set %(target_field)s = (
 						(select ifnull(sum(%(source_field)s), 0)
@@ -275,7 +275,7 @@
 		"""Update percent field in parent transaction"""
 
 		self._update_modified(args, update_modified)
-
+		
 		if args.get('target_parent_field'):
 			frappe.db.sql("""update `tab%(target_parent_dt)s`
 				set %(target_parent_field)s = round(
diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.js b/erpnext/education/doctype/fee_schedule/fee_schedule.js
index a36b9cb..c4fff77 100644
--- a/erpnext/education/doctype/fee_schedule/fee_schedule.js
+++ b/erpnext/education/doctype/fee_schedule/fee_schedule.js
@@ -38,9 +38,6 @@
 			if (data.reload && data.reload === 1) {
 				frm.reload_doc();
 			}
-			if (data.progress && data.progress === "0") {
-				frappe.msgprint(__("Fee records will be created in the background. In case of any error the error message will be updated in the Schedule."));
-			}
 			if (data.progress) {
 				let progress_bar = $(cur_frm.dashboard.progress_area).find(".progress-bar");
 				if (progress_bar) {
@@ -74,6 +71,15 @@
 				});
 			}, "fa fa-play", "btn-success");
 		}
+		if (frm.doc.fee_creation_status == "Successful") {
+			frm.add_custom_button(__("View Fees Records"), function() {
+				frappe.route_options = {
+					fee_schedule: frm.doc.name
+				};
+				frappe.set_route("List", "Fees");
+			});
+		}
+
 	},
 
 	fee_structure: function(frm) {
diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.json b/erpnext/education/doctype/fee_schedule/fee_schedule.json
index a77cc59..5aae690 100644
--- a/erpnext/education/doctype/fee_schedule/fee_schedule.json
+++ b/erpnext/education/doctype/fee_schedule/fee_schedule.json
@@ -4,7 +4,7 @@
  "allow_import": 1, 
  "allow_rename": 0, 
  "autoname": "naming_series:", 
- "beta": 1, 
+ "beta": 0, 
  "creation": "2017-07-18 15:21:21.527136", 
  "custom": 0, 
  "docstatus": 0, 
@@ -1029,7 +1029,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-12-04 13:08:27.727709", 
+ "modified": "2018-02-26 13:59:36.560780", 
  "modified_by": "Administrator", 
  "module": "Education", 
  "name": "Fee Schedule", 
diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.py b/erpnext/education/doctype/fee_schedule/fee_schedule.py
index 59acf46..b6df8c5 100644
--- a/erpnext/education/doctype/fee_schedule/fee_schedule.py
+++ b/erpnext/education/doctype/fee_schedule/fee_schedule.py
@@ -56,8 +56,15 @@
 		self.db_set("fee_creation_status", "In Process")
 		frappe.publish_realtime("fee_schedule_progress",
 			{"progress": "0", "reload": 1}, user=frappe.session.user)
-		enqueue(generate_fee, queue='default', timeout=6000, event='generate_fee',
-			fee_schedule=self.name)
+
+		total_records = sum([int(d.total_students) for d in self.student_groups])
+		if total_records > 10:
+			frappe.msgprint(_('''Fee records will be created in the background.
+				In case of any error the error message will be updated in the Schedule.'''))
+			enqueue(generate_fee, queue='default', timeout=6000, event='generate_fee',
+				fee_schedule=self.name)
+		else:
+			generate_fee(self.name)
 
 def generate_fee(fee_schedule):
 	doc = frappe.get_doc("Fee Schedule", fee_schedule)
@@ -69,10 +76,7 @@
 		frappe.throw(_("Please setup Students under Student Groups"))
 
 	for d in doc.student_groups:
-		students = frappe.db.sql(""" select sg.program, sg.batch, sgs.student, sgs.student_name
-			from `tabStudent Group` sg, `tabStudent Group Student` sgs
-			where sg.name=%s and sg.name=sgs.parent and sgs.active=1""", d.student_group, as_dict=1)
-
+		students = get_students(d.student_group, doc.academic_year, doc.academic_term, doc.student_category)
 		for student in students:
 			try:
 				fees_doc = get_mapped_doc("Fee Schedule", fee_schedule,	{
@@ -86,7 +90,7 @@
 				fees_doc.student = student.student
 				fees_doc.student_name = student.student_name
 				fees_doc.program = student.program
-				fees_doc.student_batch = student.batch
+				fees_doc.student_batch = student.student_batch_name
 				fees_doc.send_payment_request = doc.send_email
 				fees_doc.save()
 				fees_doc.submit()
@@ -110,6 +114,30 @@
 		{"progress": "100", "reload": 1}, user=frappe.session.user)
 
 
+def get_students(student_group, academic_year, academic_term=None, student_category=None):
+	conditions = ""
+	if student_category:
+		conditions = " and pe.student_category='{}'".format(frappe.db.escape(student_category))
+	if academic_term:
+		conditions = " and pe.academic_term='{}'".format(frappe.db.escape(academic_term))
+
+	students = frappe.db.sql("""
+		select pe.student, pe.student_name, pe.program, pe.student_batch_name
+		from `tabStudent Group Student` sgs, `tabProgram Enrollment` pe
+		where 
+			pe.student = sgs.student and pe.academic_year = %s
+			and sgs.parent = %s and sgs.active = 1
+			{conditions}
+		""".format(conditions=conditions), (academic_year, student_group), as_dict=1)
+	return students
+
+
+@frappe.whitelist()
+def get_total_students(student_group, academic_year, academic_term=None, student_category=None):
+	total_students = get_students(student_group, academic_year, academic_term, student_category)
+	return len(total_students)
+
+
 @frappe.whitelist()
 def get_fee_structure(source_name,target_doc=None):
 	fee_request = get_mapped_doc("Fee Structure", source_name,
@@ -117,23 +145,3 @@
 			"doctype": "Fee Schedule"
 		}}, ignore_permissions=True)
 	return fee_request
-
-@frappe.whitelist()
-def get_total_students(student_group, academic_year, academic_term=None, student_category=None):
-	conditions = ""
-	if student_category:
-		conditions = " and pe.student_category='{}'".format(frappe.db.escape(student_category))
-	if academic_term:
-		conditions = " and pe.academic_term='{}'".format(frappe.db.escape(academic_term))
-
-
-	return frappe.db.sql("""
-		select count(pe.name)
-		from `tabStudent Group Student` sgs, `tabProgram Enrollment` pe
-		where 
-			pe.student = sgs.student
-			and pe.academic_year = %s
-			and sgs.parent = %s
-			and sgs.active = 1
-			{conditions}
-	""".format(conditions=conditions), (academic_year, student_group))[0][0]
diff --git a/erpnext/hr/doctype/employee/employee.js b/erpnext/hr/doctype/employee/employee.js
index c24a6bc..5e1013d 100755
--- a/erpnext/hr/doctype/employee/employee.js
+++ b/erpnext/hr/doctype/employee/employee.js
@@ -81,7 +81,7 @@
 		}
 		frappe.call({
 			method: "erpnext.hr.doctype.employee.employee.create_user",
-			args: { employee: cur_frm.doc.name },
+			args: { employee: frm.doc.name, email: frm.doc.prefered_email },
 			callback: function(r)
 			{
 				frm.set_value("user_id", r.message)
diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py
index 9541b77..25d3ec4 100755
--- a/erpnext/hr/doctype/employee/employee.py
+++ b/erpnext/hr/doctype/employee/employee.py
@@ -263,7 +263,7 @@
 			frappe.db.set_value("Sales Person", sales_person, "enabled", 0)
 
 @frappe.whitelist()
-def create_user(employee, user = None):
+def create_user(employee, user = None, email=None):
 	emp = frappe.get_doc("Employee", employee)
 
 	employee_name = emp.employee_name.split(" ")
@@ -277,6 +277,9 @@
 
 	first_name = employee_name[0]
 
+	if email:
+		emp.prefered_email = email
+
 	user = frappe.new_doc("User")
 	user.update({
 		"name": emp.employee_name,
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py
index 9462211..d0c4a46 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.py
@@ -45,10 +45,11 @@
 		}[cstr(self.docstatus or 0)]
 
 		paid_amount = flt(self.total_amount_reimbursed) + flt(self.total_advance_amount)
-		if self.total_sanctioned_amount > 0 and self.total_sanctioned_amount ==  paid_amount\
+		if (self.is_paid or (flt(self.total_sanctioned_amount) > 0
+			and flt(self.total_sanctioned_amount) ==  paid_amount)) \
 			and self.docstatus == 1 and self.approval_status == 'Approved':
-			self.status = "Paid"
-		elif self.total_sanctioned_amount > 0 and self.docstatus == 1 and self.approval_status == 'Approved':
+				self.status = "Paid"
+		elif flt(self.total_sanctioned_amount) > 0 and self.docstatus == 1 and self.approval_status == 'Approved':
 			self.status = "Unpaid"
 		elif self.docstatus == 1 and self.approval_status == 'Rejected':
 			self.status = 'Rejected'
diff --git a/erpnext/hr/doctype/payroll_entry/payroll_entry.js b/erpnext/hr/doctype/payroll_entry/payroll_entry.js
index cf15846..4aa4141 100644
--- a/erpnext/hr/doctype/payroll_entry/payroll_entry.js
+++ b/erpnext/hr/doctype/payroll_entry/payroll_entry.js
@@ -5,7 +5,10 @@
 
 frappe.ui.form.on('Payroll Entry', {
 	onload: function (frm) {
-		frm.doc.posting_date = frappe.datetime.nowdate();
+		if (!frm.doc.posting_date) {
+			frm.doc.posting_date = frappe.datetime.nowdate();
+		}
+
 		frm.toggle_reqd(['payroll_frequency'], !frm.doc.salary_slip_based_on_timesheet);
 	},
 
diff --git a/erpnext/hr/doctype/payroll_entry/payroll_entry.py b/erpnext/hr/doctype/payroll_entry/payroll_entry.py
index 2a5b467..e53a2a6 100644
--- a/erpnext/hr/doctype/payroll_entry/payroll_entry.py
+++ b/erpnext/hr/doctype/payroll_entry/payroll_entry.py
@@ -175,7 +175,7 @@
 			Get loan details from submitted salary slip based on selected criteria
 		"""
 		cond = self.get_filter_condition()
-		return frappe.db.sql(""" select eld.employee_loan_account,
+		return frappe.db.sql(""" select eld.employee_loan_account, eld.employee_loan,
 				eld.interest_income_account, eld.principal_amount, eld.interest_amount, eld.total_payment
 			from
 				`tabSalary Slip` t1, `tabSalary Slip Loan` eld
@@ -283,7 +283,12 @@
 						"account": data.employee_loan_account,
 						"credit_in_account_currency": data.principal_amount
 					})
-				accounts.append({
+
+				if data.interest_amount and not data.interest_income_account:
+					frappe.throw(_("Select interest income account in employee loan {0}").format(data.employee_loan))
+
+				if data.interest_income_account and data.interest_amount:
+					accounts.append({
 						"account": data.interest_income_account,
 						"credit_in_account_currency": data.interest_amount,
 						"cost_center": self.cost_center,
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index a474569..b9371e3 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -156,9 +156,10 @@
 				})
 
 	def get_date_details(self):
-		date_details = get_start_end_dates(self.payroll_frequency, self.start_date or self.posting_date)
-		self.start_date = date_details.start_date
-		self.end_date = date_details.end_date
+		if not self.end_date:
+			date_details = get_start_end_dates(self.payroll_frequency, self.start_date or self.posting_date)
+			self.start_date = date_details.start_date
+			self.end_date = date_details.end_date
 
 	def check_sal_struct(self, joining_date, relieving_date):
 		cond = ''
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 8cafb91..5e1e52a 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -47,7 +47,6 @@
 		self.validate_currency()
 		self.set_conversion_rate()
 		self.validate_uom_is_interger()
-		self.update_stock_qty()
 		self.set_bom_material_details()
 		self.validate_materials()
 		self.validate_operations()
@@ -247,14 +246,12 @@
 			set_default(self, "item")
 			item = frappe.get_doc("Item", self.item)
 			if item.default_bom != self.name:
-				item.default_bom = self.name
-				item.save(ignore_permissions = True)
+				frappe.db.set_value('Item', self.item, 'default_bom', self.name)
 		else:
 			frappe.db.set(self, "is_default", 0)
 			item = frappe.get_doc("Item", self.item)
 			if item.default_bom == self.name:
-				item.default_bom = None
-				item.save(ignore_permissions = True)
+				frappe.db.set_value('Item', self.item, 'default_bom', None)
 
 	def clear_operations(self):
 		if not self.with_operations:
@@ -291,6 +288,8 @@
 				m.uom = m.stock_uom
 				m.qty = m.stock_qty
 
+			m.db_update()
+
 	def validate_uom_is_interger(self):
 		from erpnext.utilities.transaction_base import validate_uom_is_integer
 		validate_uom_is_integer(self, "uom", "qty", "BOM Item")
@@ -333,19 +332,23 @@
 
 	def check_recursion(self):
 		""" Check whether recursion occurs in any bom"""
+		bom_list = self.traverse_tree()
+		bom_nos = frappe.get_all('BOM Item', fields=["bom_no"],
+			filters={'parent': ('in', bom_list), 'parenttype': 'BOM'})
 
-		check_list = [['parent', 'bom_no', 'parent'], ['bom_no', 'parent', 'child']]
-		for d in check_list:
-			bom_list, count = [self.name], 0
-			while (len(bom_list) > count ):
-				boms = frappe.db.sql(" select %s from `tabBOM Item` where %s = %s and parenttype='BOM'" %
-					(d[0], d[1], '%s'), cstr(bom_list[count]))
-				count = count + 1
-				for b in boms:
-					if b[0] == self.name:
-						frappe.throw(_("BOM recursion: {0} cannot be parent or child of {2}").format(b[0], self.name))
-					if b[0]:
-						bom_list.append(b[0])
+		raise_exception = False
+		if bom_nos and self.name in [d.bom_no for d in bom_nos]:
+			raise_exception = True
+
+		if not raise_exception:
+			bom_nos = frappe.get_all('BOM Item', fields=["parent"],
+				filters={'bom_no': self.name, 'parenttype': 'BOM'})
+
+			if self.name in [d.parent for d in bom_nos]:
+				raise_exception = True
+
+		if raise_exception:
+			frappe.throw(_("BOM recursion: {0} cannot be parent or child of {2}").format(self.name, self.name))
 
 	def update_cost_and_exploded_items(self, bom_list=[]):
 		bom_list = self.traverse_tree(bom_list)
diff --git a/erpnext/manufacturing/doctype/bom/bom_tree.js b/erpnext/manufacturing/doctype/bom/bom_tree.js
index 4ec9bef..185b9ed 100644
--- a/erpnext/manufacturing/doctype/bom/bom_tree.js
+++ b/erpnext/manufacturing/doctype/bom/bom_tree.js
@@ -60,5 +60,14 @@
 			condition: 'frappe.boot.user.can_create.indexOf("BOM") !== -1'
 		}
 	],
+	onrender: function(node) {
+		if(node.is_root && node.data.value!="BOM") {
+			frappe.model.with_doc("BOM", node.data.value, function() {
+				var bom = frappe.model.get_doc("BOM", node.data.value);
+				node.data.image = bom.image || "";
+				node.data.description = bom.description || "";
+			});
+		}
+	},
 	view_template: 'bom_item_preview'
 }
\ No newline at end of file
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index e21da22..dd707da 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -490,3 +490,7 @@
 erpnext.patches.v10_0.update_sales_order_link_to_purchase_order
 erpnext.patches.v10_0.added_extra_gst_custom_field_in_gstr2 #2018-02-13
 erpnext.patches.v10_0.set_b2c_limit
+erpnext.patches.v10_0.update_status_for_multiple_source_in_po
+erpnext.patches.v10_0.set_auto_created_serial_no_in_stock_entry
+erpnext.patches.v10_0.update_territory_and_customer_group
+erpnext.patches.v10_0.update_warehouse_address_details
\ No newline at end of file
diff --git a/erpnext/patches/v10_0/set_auto_created_serial_no_in_stock_entry.py b/erpnext/patches/v10_0/set_auto_created_serial_no_in_stock_entry.py
new file mode 100644
index 0000000..c6470f2
--- /dev/null
+++ b/erpnext/patches/v10_0/set_auto_created_serial_no_in_stock_entry.py
@@ -0,0 +1,56 @@
+# Copyright (c) 2017, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	serialised_items = [d.name for d in frappe.get_all("Item", filters={"has_serial_no": 1})]
+
+	if not serialised_items:
+		return
+
+	for dt in ["Stock Entry Detail", "Purchase Receipt Item", "Purchase Invoice Item"]:
+		cond = ""
+		if dt=="Purchase Invoice Item":
+			cond = """ and parent in (select name from `tabPurchase Invoice`
+				where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.parent and update_stock=1)"""
+
+		item_rows = frappe.db.sql("""
+			select name
+			from `tab{0}`
+			where conversion_factor != 1
+				and docstatus = 1
+				and ifnull(serial_no, '') = ''
+				and item_code in ({1})
+				{2}
+		""".format(dt, ', '.join(['%s']*len(serialised_items)), cond), tuple(serialised_items))
+
+		if item_rows:
+			sle_serial_nos = dict(frappe.db.sql("""
+				select voucher_detail_no, serial_no
+				from `tabStock Ledger Entry`
+				where ifnull(serial_no, '') != ''
+					and voucher_detail_no in (%s)
+			""".format(', '.join(['%s']*len(item_rows))),
+				tuple([d[0] for d in item_rows])))
+
+			batch_size = 100
+			for i in range(0, len(item_rows), batch_size):
+				batch_item_rows = item_rows[i:i + batch_size]
+				when_then = []
+				for item_row in batch_item_rows:
+				
+					when_then.append('WHEN `name` = "{row_name}" THEN "{value}"'.format(
+						row_name=item_row[0],
+						value=sle_serial_nos.get(item_row[0])))
+
+				frappe.db.sql("""
+					update
+						`tab{doctype}`
+					set
+						serial_no = CASE {when_then_cond} ELSE `serial_no` END
+				""".format(
+					doctype = dt,
+					when_then_cond=" ".join(when_then)
+				))
\ No newline at end of file
diff --git a/erpnext/patches/v10_0/update_status_for_multiple_source_in_po.py b/erpnext/patches/v10_0/update_status_for_multiple_source_in_po.py
new file mode 100644
index 0000000..1de9d97
--- /dev/null
+++ b/erpnext/patches/v10_0/update_status_for_multiple_source_in_po.py
@@ -0,0 +1,38 @@
+# Copyright (c) 2017, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+
+
+	# update the sales order item in the material request
+	frappe.reload_doc('stock', 'doctype', 'material_request_item')
+	frappe.db.sql('''update `tabMaterial Request Item` mri set sales_order_item = (select name from
+		`tabSales Order Item` soi where soi.parent=mri.sales_order and soi.item_code=mri.item_code) where docstatus = 1 and
+		ifnull(mri.sales_order, "")!="" 
+	''')
+
+	# update the sales order item in the purchase order
+	frappe.db.sql('''update `tabPurchase Order Item` poi set sales_order_item = (select name from
+		`tabSales Order Item` soi where soi.parent=poi.sales_order and soi.item_code=poi.item_code) where docstatus = 1 and
+		ifnull(poi.sales_order, "")!="" 
+	''')
+
+	# Update the status in material request and sales order
+	po_list = frappe.db.sql('''
+			select parent from `tabPurchase Order Item` where ifnull(material_request, "")!="" and
+			ifnull(sales_order, "")!="" and docstatus=1
+		''',as_dict=1)
+
+	for po in list(set([d.get("parent") for d in po_list if d.get("parent")])):
+		try:
+			po_doc = frappe.get_doc("Purchase Order", po)
+
+			# update the so in the status updater
+			po_doc.update_status_updater()
+			po_doc.update_qty(update_modified=False)
+
+		except Exception:
+			pass
diff --git a/erpnext/patches/v10_0/update_territory_and_customer_group.py b/erpnext/patches/v10_0/update_territory_and_customer_group.py
new file mode 100644
index 0000000..afbbccf
--- /dev/null
+++ b/erpnext/patches/v10_0/update_territory_and_customer_group.py
@@ -0,0 +1,29 @@
+import frappe
+from frappe.model.rename_doc import get_fetch_fields
+
+def execute():
+	ignore_doctypes = ["Lead", "Opportunity", "POS Profile", "Tax Rule", "Pricing Rule"]
+	customers = frappe.get_all('Customer', fields=["name", "customer_group"])
+
+	customer_group_fetch = get_fetch_fields('Customer', 'Customer Group', ignore_doctypes)
+
+	batch_size = 1000
+	for i in range(0, len(customers), batch_size):
+		batch_customers = customers[i:i + batch_size]
+		for d in customer_group_fetch:
+			when_then = []
+			for customer in batch_customers:
+				value = frappe.db.escape(frappe.as_unicode(customer.get("customer_group")))
+
+				when_then.append('''
+					WHEN `%s` = "%s" and %s != "%s"
+					THEN "%s"
+				'''%(d["master_fieldname"], frappe.db.escape(frappe.as_unicode(customer.name)),
+					d["linked_to_fieldname"], value, value))
+
+			frappe.db.sql("""
+				update
+					`tab%s`
+				set
+					%s = CASE %s  ELSE `%s` END
+			"""%(d['doctype'], d.linked_to_fieldname, " ".join(when_then), d.linked_to_fieldname))
diff --git a/erpnext/patches/v10_0/update_warehouse_address_details.py b/erpnext/patches/v10_0/update_warehouse_address_details.py
new file mode 100644
index 0000000..b982b9a
--- /dev/null
+++ b/erpnext/patches/v10_0/update_warehouse_address_details.py
@@ -0,0 +1,37 @@
+# Copyright (c) 2017, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	warehouse = frappe.db.sql("""select name, email_id, phone_no, mobile_no, address_line_1,
+		address_line_2, city, state, pin from `tabWarehouse` where ifnull(address_line_1, '') != '' 
+		or ifnull(mobile_no, '') != '' 
+		or ifnull(email_id, '') != '' """, as_dict=1)
+
+	for d in warehouse:
+		try:
+			address = frappe.new_doc('Address')
+			address.name = d.name
+			address.address_title = d.name
+			address.address_line1 = d.address_line_1
+			address.city = d.city
+			address.state = d.state
+			address.pincode = d.pin
+			address.db_insert()
+			address.append('links',{'link_doctype':'Warehouse','link_name':d.name})
+			address.links[0].db_insert()
+			if d.name and (d.email_id or d.mobile_no or d.phone_no):
+				contact = frappe.new_doc('Contact')
+				contact.name = d.name
+				contact.first_name = d.name
+				contact.mobile_no = d.mobile_no
+				contact.email_id = d.email_id
+				contact.phone = d.phone_no
+				contact.db_insert()
+				contact.append('links',{'link_doctype':'Warehouse','link_name':d.name})
+				contact.links[0].db_insert()
+		except frappe.DuplicateEntryError:
+			pass
+	
\ No newline at end of file
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 2284f85..0ea1119 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -11,6 +11,7 @@
 from erpnext.utilities.transaction_base import TransactionBase
 from erpnext.accounts.party import validate_party_accounts, get_dashboard_info, get_timeline_data # keep this
 from frappe.contacts.address_and_contact import load_address_and_contact, delete_contact_and_address
+from frappe.model.rename_doc import update_linked_doctypes
 
 class Customer(TransactionBase):
 	def get_feed(self):
@@ -53,6 +54,14 @@
 		self.flags.old_lead = self.lead_name
 		validate_party_accounts(self)
 		self.validate_credit_limit_on_change()
+		self.check_customer_group_change()
+
+	def check_customer_group_change(self):
+		frappe.flags.customer_group_changed = False
+
+		if not self.get('__islocal'):
+			if self.customer_group != frappe.db.get_value('Customer', self.name, 'customer_group'):
+				frappe.flags.customer_group_changed = True
 
 	def on_update(self):
 		self.validate_name_with_customer_group()
@@ -65,6 +74,14 @@
 		if self.flags.is_new_doc:
 			self.create_lead_address_contact()
 
+		self.update_customer_groups()
+
+	def update_customer_groups(self):
+		ignore_doctypes = ["Lead", "Opportunity", "POS Profile", "Tax Rule", "Pricing Rule"]
+		if frappe.flags.customer_group_changed:
+			update_linked_doctypes('Customer', self.name, 'Customer Group',
+				self.customer_group, ignore_doctypes)
+
 	def create_primary_contact(self):
 		if not self.customer_primary_contact and not self.lead_name:
 			if self.mobile_no or self.email_id:
diff --git a/erpnext/selling/doctype/quotation/quotation.js b/erpnext/selling/doctype/quotation/quotation.js
index 8417642..081d4db 100644
--- a/erpnext/selling/doctype/quotation/quotation.js
+++ b/erpnext/selling/doctype/quotation/quotation.js
@@ -41,7 +41,7 @@
 
 		var me = this;
 
-		if (doc.__islocal) {
+		if (doc.__islocal && !doc.valid_till) {
 			this.frm.set_value('valid_till', frappe.datetime.add_months(doc.transaction_date, 1))
 		}
 
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index f1b56d9..2f41307 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -435,6 +435,7 @@
 		"Sales Order Item": {
 			"doctype": "Material Request Item",
 			"field_map": {
+				"name": "sales_order_item",
 				"parent": "sales_order",
 				"stock_uom": "uom",
 				"stock_qty": "qty"
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js
index d1f6b7a..0fa082f 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -257,12 +257,16 @@
 			frappe.msgprint(__("Quantity must be positive"));
 			value = item.qty;
 		} else {
-			item[field] = value;
-			if (field == "serial_no" && value) {
-				let serial_nos = value.split("\n");
-				item["qty"] = serial_nos.filter(d => {
-					return d!=="";
-				}).length;
+			if (in_list(["qty", "serial_no", "batch"], field)) {
+				item[field] = value;
+				if (field == "serial_no" && value) {
+					let serial_nos = value.split("\n");
+					item["qty"] = serial_nos.filter(d => {
+						return d!=="";
+					}).length;
+				}
+			} else {
+				return frappe.model.set_value(item.doctype, item.name, field, value);
 			}
 		}
 
@@ -1475,7 +1479,7 @@
 				fieldname: p.mode_of_payment,
 				default: p.amount,
 				onchange: () => {
-					const value = this.dialog.get_value(this.fieldname);
+					const value = this.dialog.get_value(this.fieldname) || 0;
 					me.update_payment_value(this.fieldname, value);
 				}
 			};
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index 14a478d..0ff7c2b 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -102,7 +102,7 @@
 				or I.name like %(search)s)"""
 		search = "%" + cstr(search) + "%"
 
-	query += """order by I.weightage desc, in_stock desc, I.item_name limit %s, %s""" % (start, limit)
+	query += """order by I.weightage desc, in_stock desc, I.modified desc limit %s, %s""" % (start, limit)
 
 	data = frappe.db.sql(query, {"product_group": product_group,"search": search, "today": nowdate()}, as_dict=1)
 
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index 6993187..ff01a19 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -426,7 +426,9 @@
 						filters: [
 							["parent","=", attribute]
 						],
-						fields: ["attribute_value"]
+						fields: ["attribute_value"],
+						limit_start: 0,
+						limit_page_length: 500
 					}
 				}).then((r) => {
 					if(r.message) {
diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py
index 8ebe757..7241be3 100644
--- a/erpnext/stock/doctype/item/test_item.py
+++ b/erpnext/stock/doctype/item/test_item.py
@@ -80,7 +80,6 @@
 		}
 
 		make_test_objects("Item Price")
-		print(frappe.get_all("Item Price"))
 
 		details = get_item_details({
 			"item_code": "_Test Item",
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index defce62..8f0a25d 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -241,7 +241,8 @@
 				["parent", "material_request"],
 				["uom", "stock_uom"],
 				["uom", "uom"],
-				["sales_order", "sales_order"]
+				["sales_order", "sales_order"],
+				["sales_order_item", "sales_order_item"]
 			],
 			"postprocess": update_item,
 			"condition": lambda doc: doc.ordered_qty < doc.stock_qty
diff --git a/erpnext/stock/doctype/material_request_item/material_request_item.json b/erpnext/stock/doctype/material_request_item/material_request_item.json
index ef2e7fc..4ec5ed86 100644
--- a/erpnext/stock/doctype/material_request_item/material_request_item.json
+++ b/erpnext/stock/doctype/material_request_item/material_request_item.json
@@ -676,6 +676,36 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "sales_order_item", 
+   "fieldtype": "Data", 
+   "hidden": 1, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Sales Order Item", 
+   "length": 0, 
+   "no_copy": 1, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 1, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "project", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -898,8 +928,8 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2017-12-15 16:29:18.902085", 
- "modified_by": "nabinhait@gmail.com", 
+ "modified": "2018-02-12 05:51:39.954530", 
+ "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Material Request Item", 
  "owner": "Administrator", 
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index b656c3f..29caea1 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -11,7 +11,7 @@
 from erpnext import set_perpetual_inventory
 from erpnext.stock.doctype.serial_no.serial_no import SerialNoDuplicateError
 from erpnext.accounts.doctype.account.test_account import get_inventory_account
-
+from erpnext.stock.doctype.item.test_item import make_item
 
 class TestPurchaseReceipt(unittest.TestCase):
 	def setUp(self):
@@ -203,6 +203,22 @@
 			"delivery_document_no": return_pr.name
 		})
 
+	def test_purchase_return_for_multi_uom(self):
+		item_code = "_Test Purchase Return For Multi-UOM"
+		if not frappe.db.exists('Item', item_code):
+			item = make_item(item_code, {'stock_uom': 'Box'})
+			row = item.append('uoms', {
+				'uom': 'Unit',
+				'conversion_factor': 0.1
+			})
+			row.db_update()
+
+		pr = make_purchase_receipt(item_code=item_code, qty=1, uom="Box", conversion_factor=1.0)
+		return_pr = make_purchase_receipt(item_code=item_code, qty=-10, uom="Unit",
+			stock_uom="Box", conversion_factor=0.1, is_return=1, return_against=pr.name)
+
+		self.assertEquals(abs(return_pr.items[0].stock_qty), 1.0)
+
 	def test_closed_purchase_receipt(self):
 		from erpnext.stock.doctype.purchase_receipt.purchase_receipt import update_purchase_receipt_status
 
@@ -255,7 +271,6 @@
 
 	def test_not_accept_duplicate_serial_no(self):
 		from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
-		from erpnext.stock.doctype.item.test_item import make_item
 		from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
 
 		item_code = frappe.db.get_value('Item', {'has_serial_no': 1})
@@ -307,9 +322,10 @@
 		"rejected_qty": rejected_qty,
 		"rejected_warehouse": args.rejected_warehouse or "_Test Rejected Warehouse - _TC" if rejected_qty != 0 else "",
 		"rate": args.rate or 50,
-		"conversion_factor": 1.0,
+		"conversion_factor": args.conversion_factor or 1.0,
 		"serial_no": args.serial_no,
-		"stock_uom": "_Test UOM"
+		"stock_uom": args.stock_uom or "_Test UOM",
+		"uom": args.uom or "_Test UOM"
 	})
 
 	if not args.do_not_save:
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 80c93ef..00a8a93 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -191,7 +191,7 @@
 		if sle.serial_no:
 			frappe.throw(_("Item {0} is not setup for Serial Nos. Column must be blank").format(sle.item_code),
 				SerialNoNotRequiredError)
-	else:
+	elif sle.is_cancelled == "No":
 		if sle.serial_no:
 			serial_nos = get_serial_nos(sle.serial_no)
 			if cint(sle.actual_qty) != flt(sle.actual_qty):
@@ -326,11 +326,16 @@
 		update_rejected_serial_nos = True if (controller.doctype in ("Purchase Receipt", "Purchase Invoice") 
 			and d.rejected_qty) else False
 		accepted_serial_nos_updated = False
-		warehouse = d.t_warehouse if controller.doctype == "Stock Entry" else d.warehouse
+		if controller.doctype == "Stock Entry":
+			warehouse = d.t_warehouse
+			qty = d.transfer_qty
+		else:
+			warehouse = d.warehouse
+			qty = d.stock_qty
 
 		for sle in stock_ledger_entries:
 			if sle.voucher_detail_no==d.name:
-				if not accepted_serial_nos_updated and d.qty and abs(sle.actual_qty)==d.qty \
+				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:
 						d.serial_no = sle.serial_no
 						frappe.db.set_value(d.doctype, d.name, "serial_no", sle.serial_no)
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 9093946..d4be6b4 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -278,6 +278,14 @@
 		frm.set_value("total_additional_costs",
 			flt(total_additional_costs, precision("total_additional_costs")));
 	},
+
+	source_warehouse_address: function(frm) {
+		erpnext.utils.get_address_display(frm, 'source_warehouse_address', 'source_address_display', false);
+	},
+
+	target_warehouse_address: function(frm) {
+		erpnext.utils.get_address_display(frm, 'target_warehouse_address', 'target_address_display', false);
+	},
 })
 
 frappe.ui.form.on('Stock Entry Detail', {
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.json b/erpnext/stock/doctype/stock_entry/stock_entry.json
index f68690c..f6709ba 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.json
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.json
@@ -743,6 +743,68 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "depends_on": "from_warehouse", 
+   "fieldname": "source_warehouse_address", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Source Warehouse Address", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Address", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "source_address_display", 
+   "fieldtype": "Small Text", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Source Warehouse Address", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "cb0", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -803,6 +865,68 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "depends_on": "to_warehouse", 
+   "fieldname": "target_warehouse_address", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Target Warehouse Name", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Address", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "target_address_display", 
+   "fieldtype": "Small Text", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Target Warehouse Address", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "sb0", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -1739,7 +1863,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-06-13 14:28:47.818067", 
+ "modified": "2018-03-01 12:27:12.884611", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Stock Entry", 
diff --git a/erpnext/stock/doctype/warehouse/warehouse.js b/erpnext/stock/doctype/warehouse/warehouse.js
index 5c23a97..1bfa416 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.js
+++ b/erpnext/stock/doctype/warehouse/warehouse.js
@@ -5,6 +5,15 @@
 frappe.ui.form.on("Warehouse", {
 	refresh: function(frm) {
 		frm.toggle_display('warehouse_name', frm.doc.__islocal);
+		frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
+
+
+		if(!frm.doc.__islocal) {
+			frappe.contacts.render_address_and_contact(frm);
+
+		} else {
+			frappe.contacts.clear_address_and_contact(frm);
+		}
 
 		frm.add_custom_button(__("Stock Balance"), function() {
 			frappe.set_route("query-report", "Stock Balance", {"warehouse": frm.doc.name});
diff --git a/erpnext/stock/doctype/warehouse/warehouse.json b/erpnext/stock/doctype/warehouse/warehouse.json
index b6307a4..82d0d0c 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.json
+++ b/erpnext/stock/doctype/warehouse/warehouse.json
@@ -230,6 +230,125 @@
    "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "address_and_contact", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Address and Contact", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "address_html", 
+   "fieldtype": "HTML", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Address HTML", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "column_break_10", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "contact_html", 
+   "fieldtype": "HTML", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Contact HTML", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
    "collapsible": 1, 
    "columns": 0, 
    "description": "", 
@@ -699,7 +818,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-01-23 16:45:45.546649", 
+ "modified": "2018-02-28 09:15:33.463838", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Warehouse", 
diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py
index 5186408..0eee6ba 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.py
+++ b/erpnext/stock/doctype/warehouse/warehouse.py
@@ -7,6 +7,7 @@
 from frappe import throw, _
 from frappe.utils.nestedset import NestedSet
 from erpnext.stock import get_warehouse_account
+from frappe.contacts.address_and_contact import load_address_and_contact
 
 class Warehouse(NestedSet):
 	nsm_parent_field = 'parent_warehouse'
@@ -25,10 +26,8 @@
 
 		if account:
 			self.set_onload('account', account)
+		load_address_and_contact(self)
 
-	def validate(self):
-		if self.email_id:
-			validate_email_add(self.email_id, True)
 
 	def on_update(self):
 		self.update_nsm_model()
diff --git a/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py b/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py
index fdf4442..e1249ea 100644
--- a/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py
+++ b/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py
@@ -24,9 +24,8 @@
 
 	data = []
 	for item in items:
-
-		total_outgoing = consumed_item_map.get(item.name, 0)+delivered_item_map.get(item.name,0)
-		avg_daily_outgoing = flt(total_outgoing/diff, float_preceision)
+		total_outgoing = consumed_item_map.get(item.name, 0) + delivered_item_map.get(item.name,0)
+		avg_daily_outgoing = flt(total_outgoing / diff, float_preceision)
 		reorder_level = (avg_daily_outgoing * flt(item.lead_time_days)) + flt(item.safety_stock)
 
 		data.append([item.name, item.item_name, item.description, item.safety_stock, item.lead_time_days,
@@ -45,12 +44,11 @@
 
 def get_item_info():
 	return frappe.db.sql("""select name, item_name, description, safety_stock,
-		lead_time_days	from tabItem""", as_dict=1)
+		lead_time_days from tabItem""", as_dict=1)
 
 def get_consumed_items(condition):
-
 	cn_items = frappe.db.sql("""select se_item.item_code,
-				sum(se_item.actual_qty) as 'consume_qty'
+			sum(se_item.transfer_qty) as 'consume_qty'
 		from `tabStock Entry` se, `tabStock Entry Detail` se_item
 		where se.name = se_item.parent and se.docstatus = 1
 		and ifnull(se_item.t_warehouse, '') = '' %s
@@ -63,17 +61,16 @@
 	return cn_items_map
 
 def get_delivered_items(condition):
-
-	dn_items = frappe.db.sql("""select dn_item.item_code, sum(dn_item.qty) as dn_qty
+	dn_items = frappe.db.sql("""select dn_item.item_code, sum(dn_item.stock_qty) as dn_qty
 		from `tabDelivery Note` dn, `tabDelivery Note Item` dn_item
 		where dn.name = dn_item.parent and dn.docstatus = 1 %s
 		group by dn_item.item_code""" % (condition), as_dict=1)
 
-	si_items = frappe.db.sql("""select si_item.item_name, sum(si_item.qty) as si_qty
+	si_items = frappe.db.sql("""select si_item.item_code, sum(si_item.stock_qty) as si_qty
 		from `tabSales Invoice` si, `tabSales Invoice Item` si_item
 		where si.name = si_item.parent and si.docstatus = 1 and
-		si.update_stock = 1 and si.is_pos = 1 %s
-		group by si_item.item_name""" % (condition), as_dict=1)
+		si.update_stock = 1 %s
+		group by si_item.item_code""" % (condition), as_dict=1)
 
 	dn_item_map = {}
 	for item in dn_items:
diff --git a/erpnext/stock/report/stock_ageing/stock_ageing.py b/erpnext/stock/report/stock_ageing/stock_ageing.py
index 86e1029..e93957d 100644
--- a/erpnext/stock/report/stock_ageing/stock_ageing.py
+++ b/erpnext/stock/report/stock_ageing/stock_ageing.py
@@ -96,6 +96,8 @@
 def get_sle_conditions(filters):
 	conditions = []
 	if filters.get("warehouse"):
-		conditions.append("warehouse=%(warehouse)s")
+		lft, rgt = frappe.db.get_value('Warehouse', filters.get("warehouse"), ['lft', 'rgt'])
+		conditions.append("""warehouse in (select wh.name from `tabWarehouse` wh
+			where wh.lft >= {0} and rgt <= {1})""".format(lft, rgt))
 
 	return "and {}".format(" and ".join(conditions)) if conditions else ""
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index 874a382..db9c2a6 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -452,22 +452,22 @@
 			where item_code = %s and valuation_rate > 0
 			order by posting_date desc, posting_time desc, name desc limit 1""", item_code)
 
-	valuation_rate = flt(last_valuation_rate[0][0]) if last_valuation_rate else 0
+	if last_valuation_rate:
+		return flt(last_valuation_rate[0][0]) # as there is previous records, it might come with zero rate
+
+	# If negative stock allowed, and item delivered without any incoming entry,
+	# system does not found any SLE, then take valuation rate from Item
+	valuation_rate = frappe.db.get_value("Item", item_code, "valuation_rate")
 
 	if not valuation_rate:
-		# If negative stock allowed, and item delivered without any incoming entry,
-		# syste does not found any SLE, then take valuation rate from Item
-		valuation_rate = frappe.db.get_value("Item", item_code, "valuation_rate")
+		# try Item Standard rate
+		valuation_rate = frappe.db.get_value("Item", item_code, "standard_rate")
 
 		if not valuation_rate:
-			# try Item Standard rate
-			valuation_rate = frappe.db.get_value("Item", item_code, "standard_rate")
-
-			if not valuation_rate:
-				# try in price list
-				valuation_rate = frappe.db.get_value('Item Price',
-					dict(item_code=item_code, buying=1, currency=currency),
-					'price_list_rate')
+			# try in price list
+			valuation_rate = frappe.db.get_value('Item Price',
+				dict(item_code=item_code, buying=1, currency=currency),
+				'price_list_rate')
 
 	if not allow_zero_rate and not valuation_rate \
 			and cint(erpnext.is_perpetual_inventory_enabled(company)):
diff --git a/erpnext/templates/emails/reorder_item.html b/erpnext/templates/emails/reorder_item.html
index c1aa897..05af316 100644
--- a/erpnext/templates/emails/reorder_item.html
+++ b/erpnext/templates/emails/reorder_item.html
@@ -9,7 +9,7 @@
 				<th style="border: 1px solid #d1d8dd; width: 35%; text-align: left; padding: 5px;">{{ _("Warehouse") }}</th>
 				<th style="border: 1px solid #d1d8dd; width: 10%; text-align: right; padding: 5px;">{{ _("Quantity") }}</th>
 				<th style="border: 1px solid #d1d8dd; width: 10%; text-align: left; padding: 5px;">{{ _("UOM") }}</th>
-				<th style="border: 1px solid #d1d8dd; width: 10%; text-align: left; padding: 5px;">{{ _("Balance Qty") }}</th>
+				<th style="border: 1px solid #d1d8dd; width: 10%; text-align: left; padding: 5px;">{{ _("Projected Qty") }}</th>
 			</tr>
 		</thead>
 		<tbody>
@@ -22,7 +22,7 @@
 				<td style="border: 1px solid #d1d8dd; text-align: left; padding: 5px;">{{ item.warehouse }}</td>
 				<td style="border: 1px solid #d1d8dd; text-align: right; padding: 5px;">{{ item.qty }}</td>
 				<td style="border: 1px solid #d1d8dd; text-align: left; padding: 5px;">{{ item.uom }}</td>
-				<td style="border: 1px solid #d1d8dd; text-align: left; padding: 5px;">{{ item.balance_qty }}</td>
+				<td style="border: 1px solid #d1d8dd; text-align: left; padding: 5px;">{{ frappe.utils.flt(item.projected_qty) + frappe.utils.flt(item.qty) }}</td>
 			</tr>
 			{%- endfor %}
 		</tbody>
diff --git a/erpnext/templates/pages/product_search.py b/erpnext/templates/pages/product_search.py
index a872f19..f2fd600 100644
--- a/erpnext/templates/pages/product_search.py
+++ b/erpnext/templates/pages/product_search.py
@@ -35,7 +35,7 @@
 		search = "%" + cstr(search) + "%"
 
 	# order by
-	query += """ order by I.weightage desc, in_stock desc, I.item_name limit %s, %s""" % (cint(start), cint(limit))
+	query += """ order by I.weightage desc, in_stock desc, I.modified desc limit %s, %s""" % (cint(start), cint(limit))
 
 	data = frappe.db.sql(query, {
 		"search": search,
diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py
index 0032e80..77ba694 100644
--- a/erpnext/utilities/transaction_base.py
+++ b/erpnext/utilities/transaction_base.py
@@ -43,7 +43,7 @@
 		events = frappe.db.sql_list("""select name from `tabEvent`
 			where ref_type=%s and ref_name=%s""", (self.doctype, self.name))
 		if events:
-			frappe.db.sql("delete from `tabEvent` where name in (%s)"
+			frappe.db.sql("delete from `tabEvent` where name in ({0})"
 				.format(", ".join(['%s']*len(events))), tuple(events))
 
 	def _add_calendar_event(self, opts):
@@ -71,6 +71,8 @@
 		validate_uom_is_integer(self, uom_field, qty_fields)
 
 	def validate_with_previous_doc(self, ref):
+		self.exclude_fields = ["conversion_factor", "uom"] if self.get('is_return') else []
+
 		for key, val in ref.items():
 			is_child = val.get("is_child_table")
 			ref_doc = {}
@@ -101,7 +103,7 @@
 					frappe.throw(_("Invalid reference {0} {1}").format(reference_doctype, reference_name))
 
 				for field, condition in fields:
-					if prevdoc_values[field] is not None:
+					if prevdoc_values[field] is not None and field not in self.exclude_fields:
 						self.validate_value(field, condition, prevdoc_values[field], doc)