Merge branch 'hotfix'
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 3f0838d..797f886 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.46'
+__version__ = '10.1.47'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/hr/doctype/employee_loan/employee_loan.js b/erpnext/hr/doctype/employee_loan/employee_loan.js
index 1f38105..e089e29 100644
--- a/erpnext/hr/doctype/employee_loan/employee_loan.js
+++ b/erpnext/hr/doctype/employee_loan/employee_loan.js
@@ -71,19 +71,22 @@
 			}
 		})
 	},
+
 	mode_of_payment: function (frm) {
-		frappe.call({
-			method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account",
-			args: {
-				"mode_of_payment": frm.doc.mode_of_payment,
-				"company": frm.doc.company
-			},
-			callback: function (r, rt) {
-				if (r.message) {
-					frm.set_value("payment_account", r.message.account);
+		if (frm.doc.mode_of_payment && frm.doc.company) {
+			frappe.call({
+				method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account",
+				args: {
+					"mode_of_payment": frm.doc.mode_of_payment,
+					"company": frm.doc.company
+				},
+				callback: function (r, rt) {
+					if (r.message) {
+						frm.set_value("payment_account", r.message.account);
+					}
 				}
-			}
-		});
+			});
+		}
 	},
 
 	employee_loan_application: function (frm) {
diff --git a/erpnext/hr/doctype/employee_loan_application/employee_loan_application.py b/erpnext/hr/doctype/employee_loan_application/employee_loan_application.py
index 0c29e0d..b6c6502 100644
--- a/erpnext/hr/doctype/employee_loan_application/employee_loan_application.py
+++ b/erpnext/hr/doctype/employee_loan_application/employee_loan_application.py
@@ -29,8 +29,13 @@
 		if self.repayment_method == "Repay Fixed Amount per Period":
 			monthly_interest_rate = flt(self.rate_of_interest) / (12 *100)
 			if monthly_interest_rate:
+				monthly_interest_amount = self.loan_amount * monthly_interest_rate
+				if monthly_interest_amount >= self.repayment_amount:
+					frappe.throw(_("Repayment amount {} should be greater than monthly interest amount {}").
+						format(self.repayment_amount, monthly_interest_amount))
+
 				self.repayment_periods = math.ceil((math.log(self.repayment_amount) - 
-					math.log(self.repayment_amount - (self.loan_amount*monthly_interest_rate))) /
+					math.log(self.repayment_amount - (monthly_interest_amount))) /
 					(math.log(1 + monthly_interest_rate)))
 			else:
 				self.repayment_periods = self.loan_amount / self.repayment_amount
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index cc04ea2..b1a1139 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -60,7 +60,6 @@
 		self.validate_weights()
 		self.sync_tasks()
 		self.tasks = []
-		self.load_tasks()
 		self.send_welcome_email()
 
 	def validate_project_name(self):
@@ -82,6 +81,9 @@
 
 	def sync_tasks(self):
 		"""sync tasks and remove table"""
+		if not hasattr(self, "deleted_task_list"):
+			self.set("deleted_task_list", [])
+
 		if self.flags.dont_sync_tasks: return
 		task_names = []
 
@@ -130,7 +132,7 @@
 
 		# delete
 		for t in frappe.get_all("Task", ["name"], {"project": self.name, "name": ("not in", task_names)}):
-			frappe.delete_doc("Task", t.name)
+			self.deleted_task_list.append(t.name)
 
 	def update_costing_and_percentage_complete(self):
 		self.update_percent_complete()
@@ -139,8 +141,14 @@
 	def is_row_updated(self, row, existing_task_data):
 		if self.get("__islocal") or not existing_task_data: return True
 
+		project_task_custom_fields = frappe.get_all("Custom Field", {"dt": "Project Task"}, "fieldname")
+
 		d = existing_task_data.get(row.task_id)
 
+		for field in project_task_custom_fields:
+			if row.get(field) != d.get(field):
+				return True
+
 		if (d and (row.title != d.title or row.status != d.status
 			or getdate(row.start_date) != getdate(d.start_date) or getdate(row.end_date) != getdate(d.end_date)
 			or row.description != d.description or row.task_weight != d.task_weight)):
@@ -263,9 +271,19 @@
 				user.welcome_email_sent=1
 
 	def on_update(self):
+		self.delete_task()
+		self.load_tasks()
 		self.update_costing_and_percentage_complete()
 		self.update_dependencies_on_duplicated_project()
 
+	def delete_task(self):
+		if not self.get('deleted_task_list'): return
+
+		for d in self.get('deleted_task_list'):
+			frappe.delete_doc("Task", d)
+
+		self.deleted_task_list = []
+
 	def update_dependencies_on_duplicated_project(self):
 		if self.flags.dont_sync_tasks: return
 		if not self.copied_from:
diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js
index 20ac6b4..0fd6c97 100644
--- a/erpnext/public/js/controllers/buying.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -26,7 +26,8 @@
 			};
 		});
 
-		if (this.frm.doc.__islocal) {
+		if (this.frm.doc.__islocal
+			&& frappe.meta.has_field(this.frm.doc.doctype, "disable_rounded_total")) {
 			this.frm.set_value("disable_rounded_total", cint(frappe.sys_defaults.disable_rounded_total));
 		}