Merge branch 'hotfix'
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index f7761ac..a55d0e7 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -4,7 +4,7 @@
 import frappe
 from erpnext.hooks import regional_overrides
 
-__version__ = '9.2.12'
+__version__ = '9.2.13'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index f655830..e6887ba 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -200,9 +200,6 @@
 		if (account and account_currency != existing_gle_currency) or not account:
 				account = get_party_gle_account(party_type, party, company)
 
-	if not account:
-		frappe.throw(_("Party account not specified, please setup default party account in company"))
-
 	return account
 
 def get_party_account_currency(party_type, party, company):
diff --git a/erpnext/healthcare/doctype/consultation/consultation.py b/erpnext/healthcare/doctype/consultation/consultation.py
index e16c221..69d7ecb 100755
--- a/erpnext/healthcare/doctype/consultation/consultation.py
+++ b/erpnext/healthcare/doctype/consultation/consultation.py
@@ -8,12 +8,12 @@
 from frappe.model.document import Document
 from frappe.utils import getdate
 import json
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account,get_income_account
+from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account, get_income_account
 
 class Consultation(Document):
 	def on_update(self):
 		if(self.appointment):
-			frappe.db.set_value("Patient Appointment",self.appointment,"status","Closed")
+			frappe.db.set_value("Patient Appointment", self.appointment, "status", "Closed")
 		update_consultation_to_medical_record(self)
 
 	def after_insert(self):
@@ -23,9 +23,10 @@
 		if not self.diagnosis or not self.symptoms:
 			frappe.throw("Diagnosis and Complaints cannot be left blank")
 
-		physician = frappe.get_doc("Physician",self.physician)
-		if(frappe.session.user != physician.user_id):
-			frappe.throw(_("You don't have permission to submit"))
+	def on_cancel(self):
+		if(self.appointment):
+			frappe.db.set_value("Patient Appointment", self.appointment, "status", "Open")
+		delete_medical_record(self)
 
 def set_sales_invoice_fields(company, patient):
 	sales_invoice = frappe.new_doc("Sales Invoice")
@@ -91,8 +92,8 @@
 	item_line.qty = 1
 	item_line.uom = "Nos"
 	item_line.conversion_factor = 1
-	item_line.income_account = get_income_account(physician,company)
-	op_consulting_charge = frappe.get_value("Physician",physician,"op_consulting_charge")
+	item_line.income_account = get_income_account(physician, company)
+	op_consulting_charge = frappe.get_value("Physician", physician, "op_consulting_charge")
 	if op_consulting_charge:
 		item_line.rate = op_consulting_charge
 		item_line.amount = op_consulting_charge
@@ -111,10 +112,13 @@
 	medical_record.save(ignore_permissions=True)
 
 def update_consultation_to_medical_record(consultation):
-	medical_record_id = frappe.db.sql("select name from `tabPatient Medical Record` where reference_name=%s",(consultation.name))
+	medical_record_id = frappe.db.sql("select name from `tabPatient Medical Record` where reference_name=%s", (consultation.name))
 	if(medical_record_id[0][0]):
 		subject = set_subject_field(consultation)
-		frappe.db.set_value("Patient Medical Record",medical_record_id[0][0],"subject",subject)
+		frappe.db.set_value("Patient Medical Record", medical_record_id[0][0], "subject", subject)
+
+def delete_medical_record(consultation):
+	frappe.db.sql("""delete from `tabPatient Medical Record` where reference_name = %s""", (consultation.name))
 
 def set_subject_field(consultation):
 	subject = "No Diagnosis "
diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.js b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.js
index 75b0584..8e98fee 100644
--- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.js
+++ b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.js
@@ -9,6 +9,7 @@
 				filters: {
 					'account_type': 'Receivable',
 					'company': d.company,
+					'is_group': 0
 				}
 			};
 		});
@@ -18,6 +19,7 @@
 				filters: {
 					'root_type': 'Income',
 					'company': d.company,
+					'is_group': 0
 				}
 			};
 		});
diff --git a/erpnext/healthcare/doctype/patient/patient_dashboard.py b/erpnext/healthcare/doctype/patient/patient_dashboard.py
index cb98f0d..f015b83 100644
--- a/erpnext/healthcare/doctype/patient/patient_dashboard.py
+++ b/erpnext/healthcare/doctype/patient/patient_dashboard.py
@@ -11,8 +11,8 @@
 				'items': ['Patient Appointment', 'Consultation']
 			},
 			{
-				'label': _('Lab Tests'),
-				'items': ['Lab Test']
+				'label': _('Lab Tests and Vital Signs'),
+ 				'items': ['Lab Test', 'Vital Signs']
 			}
 		]
 	}
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
index 1942b66..2237ff5 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
@@ -25,6 +25,14 @@
 			frm.add_custom_button(__('Cancel'), function() {
 				btn_update_status(frm, "Cancelled");
 			});
+
+			frm.add_custom_button(__("Consultation"),function(){
+				btn_create_consultation(frm);
+			},"Create");
+
+			frm.add_custom_button(__('Vital Signs'), function() {
+				btn_create_vital_signs(frm);
+			},"Create");
 		}
 		if(frm.doc.status == "Scheduled" && !frm.doc.__islocal){
 			frm.add_custom_button(__('Cancel'), function() {
diff --git a/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json b/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json
index 9cbcf7b..6edc0cc 100644
--- a/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json
+++ b/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json
@@ -56,7 +56,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_global_search": 0, 
-   "in_list_view": 0, 
+   "in_list_view": 1, 
    "in_standard_filter": 0, 
    "label": "Patient", 
    "length": 0, 
@@ -174,7 +174,7 @@
    "ignore_xss_filter": 1, 
    "in_filter": 0, 
    "in_global_search": 0, 
-   "in_list_view": 1, 
+   "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "Subject", 
    "length": 0, 
@@ -236,7 +236,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_global_search": 0, 
-   "in_list_view": 0, 
+   "in_list_view": 1, 
    "in_standard_filter": 0, 
    "label": "Datetime", 
    "length": 0, 
@@ -266,7 +266,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_global_search": 0, 
-   "in_list_view": 0, 
+   "in_list_view": 1, 
    "in_standard_filter": 0, 
    "label": "Reference DocType", 
    "length": 0, 
@@ -297,7 +297,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_global_search": 0, 
-   "in_list_view": 0, 
+   "in_list_view": 1, 
    "in_standard_filter": 0, 
    "label": "Reference Name", 
    "length": 0, 
@@ -389,7 +389,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-10-04 16:09:55.597866", 
+ "modified": "2017-11-15 12:48:59.945615", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Patient Medical Record", 
@@ -425,6 +425,7 @@
  "show_name_in_global_search": 1, 
  "sort_field": "modified", 
  "sort_order": "DESC", 
+ "title_field": "patient", 
  "track_changes": 1, 
  "track_seen": 1
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/physician/physician.js b/erpnext/healthcare/doctype/physician/physician.js
index 37389fe..c607f23 100755
--- a/erpnext/healthcare/doctype/physician/physician.js
+++ b/erpnext/healthcare/doctype/physician/physician.js
@@ -9,6 +9,7 @@
 				filters: {
 					'root_type': 'Income',
 					'company': d.company,
+					'is_group': 0
 				}
 			};
 		});
diff --git a/erpnext/healthcare/doctype/physician_schedule/physician_schedule.js b/erpnext/healthcare/doctype/physician_schedule/physician_schedule.js
index e198d35..74ba66f 100644
--- a/erpnext/healthcare/doctype/physician_schedule/physician_schedule.js
+++ b/erpnext/healthcare/doctype/physician_schedule/physician_schedule.js
@@ -33,7 +33,7 @@
 
 						while(cur_time < end_time) {
 							let to_time = cur_time.clone().add(values.duration, 'minutes');
-							if(to_time < end_time) {
+							if(to_time <= end_time) {
 
 								// add a new timeslot
 								frm.add_child('time_slots', {
diff --git a/erpnext/hr/doctype/employee_loan/test_employee_loan.py b/erpnext/hr/doctype/employee_loan/test_employee_loan.py
index 8671baa..c32e85e 100644
--- a/erpnext/hr/doctype/employee_loan/test_employee_loan.py
+++ b/erpnext/hr/doctype/employee_loan/test_employee_loan.py
@@ -38,9 +38,8 @@
 		self.assertEquals(employee_loan.total_interest_payable, 22712)
 		self.assertEquals(employee_loan.total_payment, 302712)
 
-
 def create_loan_type(loan_name, maximum_loan_amount, rate_of_interest):
-	if not frappe.db.get_value("Loan Type", loan_name):
+	if not frappe.db.exists("Loan Type", loan_name):
 		frappe.get_doc({
 			"doctype": "Loan Type",
 			"loan_name": loan_name,
@@ -49,6 +48,7 @@
 		}).insert()
 
 def	create_employee_loan(employee, loan_type, loan_amount, repayment_method, repayment_periods):
+	create_loan_type(loan_type, 500000, 8.4)
 	if not frappe.db.get_value("Employee Loan", {"employee":employee}):
 		employee_loan = frappe.new_doc("Employee Loan")
 		employee_loan.update({
diff --git a/erpnext/hr/doctype/process_payroll/process_payroll.py b/erpnext/hr/doctype/process_payroll/process_payroll.py
index 0e329a7..f8ac044 100644
--- a/erpnext/hr/doctype/process_payroll/process_payroll.py
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.py
@@ -190,23 +190,28 @@
 	def format_as_links(self, salary_slip):
 		return ['<a href="#Form/Salary Slip/{0}">{0}</a>'.format(salary_slip)]
 
-	def get_total_salary_and_loan_amounts(self):
+	def get_loan_details(self):
 		"""
-			Get total loan principal, loan interest and salary amount from submitted salary slip based on selected criteria
+			Get loan details from submitted salary slip based on selected criteria
 		"""
 		cond = self.get_filter_condition()
-		totals = frappe.db.sql("""
-			select sum(principal_amount) as total_principal_amount, sum(interest_amount) as total_interest_amount, 
-			sum(total_loan_repayment) as total_loan_repayment, sum(rounded_total) as rounded_total from `tabSalary Slip` t1
+		return frappe.db.sql(""" select eld.employee_loan_account,
+				eld.interest_income_account, eld.principal_amount, eld.interest_amount, eld.total_payment
+			from
+				`tabSalary Slip` t1, `tabSalary Slip Loan` eld
+			where
+				t1.docstatus = 1 and t1.name = eld.parent and start_date >= %s and end_date <= %s %s
+			""" % ('%s', '%s', cond), (self.start_date, self.end_date), as_dict=True) or []
+
+	def get_total_salary_amount(self):
+		"""
+			Get total salary amount from submitted salary slip based on selected criteria
+		"""
+		cond = self.get_filter_condition()
+		totals = frappe.db.sql(""" select sum(rounded_total) as rounded_total from `tabSalary Slip` t1
 			where t1.docstatus = 1 and start_date >= %s and end_date <= %s %s
 			""" % ('%s', '%s', cond), (self.start_date, self.end_date), as_dict=True)
-		return totals[0]
-	
-	def get_loan_accounts(self):
-		loan_accounts = frappe.get_all("Employee Loan", fields=["employee_loan_account", "interest_income_account"], 
-						filters = {"company": self.company, "docstatus":1})
-		if loan_accounts:
-			return loan_accounts[0]
+		return totals and totals[0] or None
 
 	def get_salary_component_account(self, salary_component):
 		account = frappe.db.get_value("Salary Component Account",
@@ -257,8 +262,7 @@
 		earnings = self.get_salary_component_total(component_type = "earnings") or {}
 		deductions = self.get_salary_component_total(component_type = "deductions") or {}
 		default_payroll_payable_account = self.get_default_payroll_payable_account()
-		loan_amounts = self.get_total_salary_and_loan_amounts()
-		loan_accounts = self.get_loan_accounts()
+		loan_details = self.get_loan_details()
 		jv_name = ""
 		precision = frappe.get_precision("Journal Entry Account", "debit_in_account_currency")
 
@@ -294,18 +298,18 @@
 					})
 
 			# Employee loan
-			if loan_amounts.total_loan_repayment:
+			for data in loan_details:
 				accounts.append({
-						"account": loan_accounts.employee_loan_account,
-						"credit_in_account_currency": loan_amounts.total_principal_amount
+						"account": data.employee_loan_account,
+						"credit_in_account_currency": data.principal_amount
 					})
 				accounts.append({
-						"account": loan_accounts.interest_income_account,
-						"credit_in_account_currency": loan_amounts.total_interest_amount,
+						"account": data.interest_income_account,
+						"credit_in_account_currency": data.interest_amount,
 						"cost_center": self.cost_center,
 						"project": self.project
 					})
-				payable_amount -= flt(loan_amounts.total_loan_repayment, precision)
+				payable_amount -= flt(data.total_payment, precision)
 
 			# Payable amount
 			accounts.append({
@@ -327,11 +331,11 @@
 
 	def make_payment_entry(self):
 		self.check_permission('write')
-		total_salary_amount = self.get_total_salary_and_loan_amounts()
+		total_salary_amount = self.get_total_salary_amount()
 		default_payroll_payable_account = self.get_default_payroll_payable_account()
 		precision = frappe.get_precision("Journal Entry Account", "debit_in_account_currency")
 
-		if total_salary_amount.rounded_total:
+		if total_salary_amount and total_salary_amount.rounded_total:
 			journal_entry = frappe.new_doc('Journal Entry')
 			journal_entry.voucher_type = 'Bank Entry'
 			journal_entry.user_remark = _('Payment of salary from {0} to {1}')\
diff --git a/erpnext/hr/doctype/process_payroll/test_process_payroll.py b/erpnext/hr/doctype/process_payroll/test_process_payroll.py
index cac43c4..91b60b4 100644
--- a/erpnext/hr/doctype/process_payroll/test_process_payroll.py
+++ b/erpnext/hr/doctype/process_payroll/test_process_payroll.py
@@ -6,9 +6,9 @@
 
 import erpnext
 import frappe
-from frappe.utils import nowdate
-from erpnext.hr.doctype.process_payroll.process_payroll import get_end_date
-
+from dateutil.relativedelta import relativedelta
+from erpnext.accounts.utils import get_fiscal_year, getdate, nowdate
+from erpnext.hr.doctype.process_payroll.process_payroll import get_start_end_dates, get_end_date
 
 class TestProcessPayroll(unittest.TestCase):
 	def test_process_payroll(self):
@@ -19,22 +19,9 @@
 			if not frappe.db.get_value('Salary Component Account',
 				{'parent': data.name, 'company': erpnext.get_default_company()}, 'name'):
 				get_salary_component_account(data.name)
-				
-		payment_account = frappe.get_value('Account',
-			{'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
 
 		if not frappe.db.get_value("Salary Slip", {"start_date": "2016-11-01", "end_date": "2016-11-30"}):
-			process_payroll = frappe.get_doc("Process Payroll", "Process Payroll")
-			process_payroll.company = erpnext.get_default_company()
-			process_payroll.start_date = "2016-11-01"
-			process_payroll.end_date = "2016-11-30"
-			process_payroll.payment_account = payment_account
-			process_payroll.posting_date = nowdate()
-			process_payroll.payroll_frequency = "Monthly"
-			process_payroll.create_salary_slips()
-			process_payroll.submit_salary_slips()
-			if process_payroll.get_sal_slip_list(ss_status = 1):
-				r = process_payroll.make_payment_entry()
+			make_process_payroll()
 
 	def test_get_end_date(self):
 		self.assertEqual(get_end_date('2017-01-01', 'monthly'), {'end_date': '2017-01-31'})
@@ -45,7 +32,99 @@
 		self.assertEqual(get_end_date('2020-02-15', 'bimonthly'), {'end_date': ''})
 		self.assertEqual(get_end_date('2017-02-15', 'monthly'), {'end_date': '2017-03-14'})
 		self.assertEqual(get_end_date('2017-02-15', 'daily'), {'end_date': '2017-02-15'})
-	
+
+	def test_employee_loan(self):
+		from erpnext.hr.doctype.salary_structure.test_salary_structure import (make_employee,
+			make_salary_structure)
+		from erpnext.hr.doctype.employee_loan.test_employee_loan import create_employee_loan
+
+		branch = "Test Employee Branch"
+		employee = make_employee("test_employee@loan.com")
+		company = erpnext.get_default_company()
+		holiday_list = make_holiday("test holiday for loan")
+
+		if not frappe.db.exists('Salary Component', 'Basic Salary'):
+			frappe.get_doc({
+				'doctype': 'Salary Component',
+				'salary_component': 'Basic Salary',
+				'salary_component_abbr': 'BS',
+				'type': 'Earning',
+				'accounts': [{
+					'company': company,
+					'default_account': frappe.db.get_value('Account',
+						{'company': company, 'root_type': 'Expense', 'account_type': ''}, 'name')
+				}]
+			}).insert()
+
+		if not frappe.db.get_value('Salary Component Account',
+			{'parent': 'Basic Salary', 'company': company}):
+			salary_component = frappe.get_doc('Salary Component', 'Basic Salary')
+			salary_component.append('accounts', {
+				'company': company,
+				'default_account': 'Salary - WP'
+			})
+
+		company_doc = frappe.get_doc('Company', company)
+		if not company_doc.default_payroll_payable_account:
+			company_doc.default_payroll_payable_account = frappe.db.get_value('Account',
+				{'company': company, 'root_type': 'Liability', 'account_type': ''}, 'name')
+			company_doc.save()
+
+		if not frappe.db.exists('Branch', branch):
+			frappe.get_doc({
+				'doctype': 'Branch',
+				'branch': branch
+			}).insert()
+
+		employee_doc = frappe.get_doc('Employee', employee)
+		employee_doc.branch = branch
+		employee_doc.holiday_list = holiday_list
+		employee_doc.save()
+
+		employee_loan = create_employee_loan(employee,
+			"Personal Loan", 280000, "Repay Over Number of Periods", 20)
+		employee_loan.repay_from_salary = 1
+		employee_loan.submit()
+
+		salary_strcture = "Test Salary Structure for Loan"
+		if not frappe.db.exists('Salary Structure', salary_strcture):
+			salary_strcture = make_salary_structure(salary_strcture, [{
+				'employee': employee,
+				'from_date': '2017-01-01',
+				'base': 30000
+			}])
+
+			salary_strcture = frappe.get_doc('Salary Structure', salary_strcture)
+			salary_strcture.set('earnings', [{
+				'salary_component': 'Basic Salary',
+				'abbr': 'BS',
+				'amount_based_on_formula':1,
+				'formula': 'base*.5'
+			}])
+			salary_strcture.save()
+
+		dates = get_start_end_dates('Monthly', nowdate())
+		make_process_payroll(start_date=dates.start_date,
+			end_date=dates.end_date, branch=branch)
+
+		name = frappe.db.get_value('Salary Slip',
+			{'posting_date': nowdate(), 'employee': employee}, 'name')
+
+		salary_slip = frappe.get_doc('Salary Slip', name)
+		for row in salary_slip.loans:
+			if row.employee_loan == employee_loan.name:
+				interest_amount = (280000 * 8.4)/(12*100)
+				principal_amount = employee_loan.monthly_repayment_amount - interest_amount
+				self.assertEqual(row.interest_amount, interest_amount)
+				self.assertEqual(row.principal_amount, principal_amount)
+				self.assertEqual(row.total_payment,
+					interest_amount + principal_amount)
+
+		if salary_slip.docstatus == 0:
+			frappe.delete_doc('Salary Slip', name)
+
+		employee_loan.cancel()
+		frappe.delete_doc('Employee Loan', employee_loan.name)
 
 def get_salary_component_account(sal_comp):
 	company = erpnext.get_default_company()
@@ -63,4 +142,54 @@
 		"parent_account": "Indirect Expenses - " + frappe.db.get_value('Company', company, 'abbr'),
 		"company": company
 		}).insert()
-	return salary_account
\ No newline at end of file
+	return salary_account
+
+def make_process_payroll(**args):
+	args = frappe._dict(args)
+
+	process_payroll = frappe.get_doc("Process Payroll", "Process Payroll")
+	process_payroll.company = erpnext.get_default_company()
+	process_payroll.start_date = args.start_date or "2016-11-01"
+	process_payroll.end_date = args.end_date or "2016-11-30"
+	process_payroll.payment_account = get_payment_account()
+	process_payroll.posting_date = nowdate()
+	process_payroll.payroll_frequency = "Monthly"
+	process_payroll.branch = args.branch or None
+	process_payroll.create_salary_slips()
+	process_payroll.submit_salary_slips()
+	if process_payroll.get_sal_slip_list(ss_status = 1):
+		r = process_payroll.make_payment_entry()
+
+	return process_payroll
+
+def get_payment_account():
+	return frappe.get_value('Account',
+		{'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
+
+def make_holiday(holiday_list_name):
+	if not frappe.db.exists('Holiday List', holiday_list_name):
+		current_fiscal_year = get_fiscal_year(nowdate(), as_dict=True)
+		dt = getdate(nowdate())
+
+		new_year = dt + relativedelta(month=01, day=01, year=dt.year)
+		republic_day = dt + relativedelta(month=01, day=26, year=dt.year)
+		test_holiday = dt + relativedelta(month=02, day=02, year=dt.year)
+
+		frappe.get_doc({
+			'doctype': 'Holiday List',
+			'from_date': current_fiscal_year.year_start_date,
+			'to_date': current_fiscal_year.year_end_date,
+			'holiday_list_name': holiday_list_name,
+			'holidays': [{
+				'holiday_date': new_year,
+				'description': 'New Year'
+			}, {
+				'holiday_date': republic_day,
+				'description': 'Republic Day'
+			}, {
+				'holiday_date': test_holiday,
+				'description': 'Test Holiday'
+			}]
+		}).insert()
+
+	return holiday_list_name
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.json b/erpnext/hr/doctype/salary_slip/salary_slip.json
index 6a52f2d..6cc62eb 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.json
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.json
@@ -1293,7 +1293,68 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "principal_amount", 
+   "fieldname": "loans", 
+   "fieldtype": "Table", 
+   "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": "Employee Loan", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Salary Slip Loan", 
+   "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": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "section_break_43", 
+   "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, 
+   "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, 
+   "default": "0", 
+   "fieldname": "total_principal_amount", 
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
@@ -1302,7 +1363,7 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Principal Amount", 
+   "label": "Total Principal Amount", 
    "length": 0, 
    "no_copy": 0, 
    "options": "Company:company:default_currency", 
@@ -1324,7 +1385,8 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "interest_amount", 
+   "default": "0", 
+   "fieldname": "total_interest_amount", 
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
@@ -1333,7 +1395,7 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Interest Amount", 
+   "label": "Total Interest Amount", 
    "length": 0, 
    "no_copy": 0, 
    "options": "Company:company:default_currency", 
@@ -1355,7 +1417,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "column_break_48", 
+   "fieldname": "column_break_45", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
@@ -1384,6 +1446,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "default": "0", 
    "fieldname": "total_loan_repayment", 
    "fieldtype": "Currency", 
    "hidden": 0, 
@@ -1604,7 +1667,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-11-10 18:40:33.817074", 
+ "modified": "2017-11-13 23:55:37.504856", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Salary Slip", 
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 1f9c192..ea5f35b 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -375,15 +375,34 @@
 			self.precision("net_pay") if disable_rounded_total else 0)
 
 	def set_loan_repayment(self):
-		employee_loan = frappe.db.sql("""select sum(principal_amount) as principal_amount, sum(interest_amount) as interest_amount,
-						sum(total_payment) as total_loan_repayment from `tabRepayment Schedule`
-						where payment_date between %s and %s and parent in (select name from `tabEmployee Loan`
-						where employee = %s and repay_from_salary = 1 and docstatus = 1)""",
-						(self.start_date, self.end_date, self.employee), as_dict=True)
-		if employee_loan:
-			self.principal_amount = employee_loan[0].principal_amount
-			self.interest_amount = employee_loan[0].interest_amount
-			self.total_loan_repayment = employee_loan[0].total_loan_repayment
+		self.set('loans', [])
+		self.total_loan_repayment = 0
+		self.total_interest_amount = 0
+		self.total_principal_amount = 0
+
+		for loan in self.get_employee_loan_details():
+			self.append('loans', {
+				'employee_loan': loan.name,
+				'total_payment': loan.total_payment,
+				'interest_amount': loan.interest_amount,
+				'principal_amount': loan.principal_amount,
+				'employee_loan_account': loan.employee_loan_account,
+				'interest_income_account': loan.interest_income_account
+			})
+
+			self.total_loan_repayment += loan.total_payment
+			self.total_interest_amount += loan.interest_amount
+			self.total_principal_amount += loan.principal_amount
+
+	def get_employee_loan_details(self):
+		return frappe.db.sql("""select rps.principal_amount, rps.interest_amount, el.name,
+				rps.total_payment, el.employee_loan_account, el.interest_income_account
+			from
+				`tabRepayment Schedule` as rps, `tabEmployee Loan` as el
+			where
+				el.name = rps.parent and rps.payment_date between %s and %s and
+				el.repay_from_salary = 1 and el.docstatus = 1 and el.employee = %s""",
+			(self.start_date, self.end_date, self.employee), as_dict=True) or []
 
 	def on_submit(self):
 		if self.net_pay < 0:
diff --git a/erpnext/hr/doctype/salary_slip_loan/__init__.py b/erpnext/hr/doctype/salary_slip_loan/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hr/doctype/salary_slip_loan/__init__.py
diff --git a/erpnext/hr/doctype/salary_slip_loan/salary_slip_loan.json b/erpnext/hr/doctype/salary_slip_loan/salary_slip_loan.json
new file mode 100644
index 0000000..445c2f4
--- /dev/null
+++ b/erpnext/hr/doctype/salary_slip_loan/salary_slip_loan.json
@@ -0,0 +1,256 @@
+{
+ "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2017-11-08 12:51:12.834479", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "editable_grid": 1, 
+ "engine": "InnoDB", 
+ "fields": [
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "employee_loan", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Employee Loan", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Employee Loan", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "employee_loan_account", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Employee Loan Account", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Account", 
+   "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": "interest_income_account", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Interest Income Account", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Account", 
+   "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": "column_break_4", 
+   "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": "principal_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Principal Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "", 
+   "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": "interest_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Interest Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "", 
+   "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": "total_payment", 
+   "fieldtype": "Currency", 
+   "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": "Total Payment", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "", 
+   "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
+  }
+ ], 
+ "has_web_view": 0, 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 1, 
+ "max_attachments": 0, 
+ "modified": "2017-11-13 23:59:47.237689", 
+ "modified_by": "Administrator", 
+ "module": "HR", 
+ "name": "Salary Slip Loan", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_changes": 1, 
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_slip_loan/salary_slip_loan.py b/erpnext/hr/doctype/salary_slip_loan/salary_slip_loan.py
new file mode 100644
index 0000000..83908ce
--- /dev/null
+++ b/erpnext/hr/doctype/salary_slip_loan/salary_slip_loan.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class SalarySlipLoan(Document):
+	pass
diff --git a/erpnext/hr/doctype/salary_structure/test_salary_structure.py b/erpnext/hr/doctype/salary_structure/test_salary_structure.py
index 6b1404c..2382a81 100644
--- a/erpnext/hr/doctype/salary_structure/test_salary_structure.py
+++ b/erpnext/hr/doctype/salary_structure/test_salary_structure.py
@@ -17,11 +17,9 @@
 	def setUp(self):
 		self.make_holiday_list()
 		frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", "Salary Structure Test Holiday List")
-		make_earning_salary_component(["Basic Salary", "Special Allowance", "HRA"])
-		make_deduction_salary_component(["Professional Tax", "TDS"])
 		make_employee("test_employee@salary.com")
 		make_employee("test_employee_2@salary.com")
-		
+
 	def make_holiday_list(self):
 		if not frappe.db.get_value("Holiday List", "Salary Structure Test Holiday List"):
 			holiday_list = frappe.get_doc({
@@ -33,7 +31,7 @@
 			}).insert()	
 			holiday_list.get_weekly_off_dates()
 			holiday_list.save()
-		
+
 	def test_amount_totals(self):
 		sal_slip = frappe.get_value("Salary Slip", {"employee_name":"test_employee@salary.com"})
 		if not sal_slip:
@@ -64,7 +62,7 @@
 
 		for row in salary_structure.deductions:
 			self.assertFalse(("\n" in row.formula) or ("\n" in row.condition))
-			
+
 def make_employee(user):
 	if not frappe.db.get_value("User", user):
 		frappe.get_doc({
@@ -74,7 +72,6 @@
 			"new_password": "password",
 			"roles": [{"doctype": "Has Role", "role": "Employee"}]
 		}).insert()
-		
 
 	if not frappe.db.get_value("Employee", {"user_id": user}):
 		emp = frappe.get_doc({
@@ -95,7 +92,7 @@
 		return emp.name
 	else:
 		return frappe.get_value("Employee", {"employee_name":user}, "name")			
-		
+
 def make_salary_slip_from_salary_structure(employee):
 	sal_struct = make_salary_structure('Salary Structure Sample')
 	sal_slip = make_salary_slip(sal_struct, employee = employee)
@@ -106,22 +103,21 @@
 	sal_slip.insert()
 	sal_slip.submit()
 	return sal_slip	
-	
-def make_salary_structure(sal_struct):
+
+def make_salary_structure(sal_struct, employees=None):
 	if not frappe.db.exists('Salary Structure', sal_struct):
 		frappe.get_doc({
 			"doctype": "Salary Structure",
 			"name": sal_struct,
 			"company": erpnext.get_default_company(),
-			"employees": get_employee_details(),
+			"employees": employees or get_employee_details(),
 			"earnings": get_earnings_component(),
 			"deductions": get_deductions_component(),
 			"payroll_frequency": "Monthly",
 			"payment_account": frappe.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
 		}).insert()
-	return sal_struct
-			
-			
+	return sal_struct	
+
 def get_employee_details():
 	return [{"employee": frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"),
 			"base": 25000,
@@ -136,8 +132,11 @@
 			 "idx": 2
 			}
 		]
-			
-def get_earnings_component():	
+
+def get_earnings_component():
+	make_earning_salary_component(["Basic Salary", "Special Allowance", "HRA"])
+	make_deduction_salary_component(["Professional Tax", "TDS"])
+
 	return [
 				{
 					"salary_component": 'Basic Salary',
@@ -167,7 +166,7 @@
 					"idx": 4
 				},
 			]
-			
+
 def get_deductions_component():	
 	return [
 				{
@@ -191,5 +190,4 @@
 					"formula": 'base*.1',
 					"idx": 3
 				}
-			]			
-			
\ No newline at end of file
+			]		
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index ca8b0ec..1ae99a3 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -458,4 +458,5 @@
 erpnext.patches.v9_0.set_pos_profile_name
 erpnext.patches.v9_0.remove_non_existing_warehouse_from_stock_settings
 execute:frappe.delete_doc_if_exists("DocType", "Program Fee")
-erpnext.patches.v9_2.delete_healthcare_domain_default_items
\ No newline at end of file
+erpnext.patches.v9_0.update_employee_loan_details
+erpnext.patches.v9_2.delete_healthcare_domain_default_items
diff --git a/erpnext/patches/v9_0/update_employee_loan_details.py b/erpnext/patches/v9_0/update_employee_loan_details.py
new file mode 100644
index 0000000..86690fc
--- /dev/null
+++ b/erpnext/patches/v9_0/update_employee_loan_details.py
@@ -0,0 +1,24 @@
+# Copyright (c) 2017, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	frappe.reload_doc('hr', 'doctype', 'salary_slip_loan')
+	frappe.reload_doc('hr', 'doctype', 'salary_slip')
+
+	for data in frappe.db.sql(""" select name,
+			start_date, end_date, total_loan_repayment
+		from
+			`tabSalary Slip`
+		where
+			docstatus < 2 and ifnull(total_loan_repayment, 0) > 0""", as_dict=1):
+		salary_slip = frappe.get_doc('Salary Slip', data.name)
+		salary_slip.set_loan_repayment()
+
+		if salary_slip.total_loan_repayment == data.total_loan_repayment:
+			for row in salary_slip.loans:
+				row.db_update()
+
+			salary_slip.db_update()
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 6a6af3d..6790176 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -157,7 +157,7 @@
 	def make_route(self):
 		if not self.route:
 			return cstr(frappe.db.get_value('Item Group', self.item_group,
-				'route')) + '/' + self.scrub(self.item_name + '-' + random_string(5))
+				'route')) + '/' + self.scrub((self.item_name if self.item_name else self.item_code) + '-' + random_string(5))
 
 	def validate_website_image(self):
 		"""Validate if the website image is a public file"""