Merge branch 'develop' of https://github.com/frappe/erpnext into loan_patch_fix
diff --git a/erpnext/patches/v13_0/update_old_loans.py b/erpnext/patches/v13_0/update_old_loans.py
index 7723942..caec53b 100644
--- a/erpnext/patches/v13_0/update_old_loans.py
+++ b/erpnext/patches/v13_0/update_old_loans.py
@@ -5,6 +5,8 @@
 from erpnext.accounts.doctype.account.test_account import create_account
 from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_term_loans
 from erpnext.loan_management.doctype.loan.loan import make_repayment_entry
+from erpnext.loan_management.doctype.loan_repayment.loan_repayment import get_accrued_interest_entries
+from frappe.model.naming import make_autoname
 
 def execute():
 
@@ -18,15 +20,27 @@
 	frappe.reload_doc('loan_management', 'doctype', 'loan_repayment_detail')
 	frappe.reload_doc('loan_management', 'doctype', 'loan_interest_accrual')
 	frappe.reload_doc('accounts', 'doctype', 'gl_entry')
+	frappe.reload_doc('accounts', 'doctype', 'journal_entry_account')
 
 	updated_loan_types = []
 
+	# Update old loan status as closed
+	loans_list = frappe.db.sql("""SELECT distinct parent from `tabRepayment Schedule`
+		where paid = 0 and docstatus = 1""", as_dict=1)
+
+	loans_to_close = [d.parent for d in loans_list]
+
+	if loans_to_close:
+		frappe.db.sql("UPDATE `tabLoan` set status = 'Closed' where name not in (%s)" % (', '.join(['%s'] * len(loans_to_close))), tuple(loans_to_close))
+
 	loans = frappe.get_all('Loan', fields=['name', 'loan_type', 'company', 'status', 'mode_of_payment',
-		'applicant_type', 'applicant', 'loan_account', 'payment_account', 'interest_income_account'])
+		'applicant_type', 'applicant', 'loan_account', 'payment_account', 'interest_income_account'],
+		filters={'docstatus': 1, 'status': ('!=', 'Closed')})
 
 	for loan in loans:
 		# Update details in Loan Types and Loan
 		loan_type_company = frappe.db.get_value('Loan Type', loan.loan_type, 'company')
+		loan_type = loan.loan_type
 
 		group_income_account = frappe.get_value('Account', {'company': loan.company,
 			'is_group': 1, 'root_type': 'Income', 'account_name': _('Indirect Income')})
@@ -38,7 +52,26 @@
 		penalty_account = create_account(company=loan.company, account_type='Income Account',
 			account_name='Penalty Account', parent_account=group_income_account)
 
-		if not loan_type_company:
+		# Same loan type used for multiple companies
+		if loan_type_company and loan_type_company != loan.company:
+			# get loan type for appropriate company
+			loan_type_name = frappe.get_value('Loan Type', {'company': loan.company,
+				'mode_of_payment': loan.mode_of_payment, 'loan_account': loan.loan_account,
+				'payment_account': loan.payment_account, 'interest_income_account': loan.interest_income_account,
+				'penalty_income_account': loan.penalty_income_account}, 'name')
+
+			if not loan_type_name:
+				loan_type_name = create_loan_type(loan, loan_type_name, penalty_account)
+
+			# update loan type in loan
+			frappe.db.sql("UPDATE `tabLoan` set loan_type = %s where name = %s", (loan_type_name,
+				loan.name))
+
+			loan_type = loan_type_name
+			if loan_type_name not in updated_loan_types:
+				updated_loan_types.append(loan_type_name)
+
+		elif not loan_type_company:
 			loan_type_doc = frappe.get_doc('Loan Type', loan.loan_type)
 			loan_type_doc.is_term_loan = 1
 			loan_type_doc.company = loan.company
@@ -49,8 +82,9 @@
 			loan_type_doc.penalty_income_account = penalty_account
 			loan_type_doc.submit()
 			updated_loan_types.append(loan.loan_type)
+			loan_type = loan.loan_type
 
-		if loan.loan_type in updated_loan_types:
+		if loan_type in updated_loan_types:
 			if loan.status == 'Fully Disbursed':
 				status = 'Disbursed'
 			elif loan.status == 'Repaid/Closed':
@@ -64,25 +98,48 @@
 				'status': status
 			})
 
-			process_loan_interest_accrual_for_term_loans(posting_date=nowdate(), loan_type=loan.loan_type,
+			process_loan_interest_accrual_for_term_loans(posting_date=nowdate(), loan_type=loan_type,
 				loan=loan.name)
 
-			payments = frappe.db.sql(''' SELECT j.name, a.debit, a.debit_in_account_currency, j.posting_date
-				FROM `tabJournal Entry` j, `tabJournal Entry Account` a
-				WHERE a.parent = j.name and a.reference_type='Loan' and a.reference_name = %s
-				and account = %s
-			''', (loan.name, loan.loan_account), as_dict=1)
 
-			for payment in payments:
-				repayment_entry = make_repayment_entry(loan.name, loan.loan_applicant_type, loan.applicant,
-					loan.loan_type, loan.company)
+			if frappe.db.has_column('Repayment Schedule', 'paid'):
+				total_principal, total_interest = frappe.db.get_value('Repayment Schedule', {'paid': 1, 'parent': loan.name},
+					['sum(principal_amount) as total_principal', 'sum(interest_amount) as total_interest'])
 
-				repayment_entry.amount_paid = payment.debit_in_account_currency
-				repayment_entry.posting_date = payment.posting_date
-				repayment_entry.save()
-				repayment_entry.submit()
+				accrued_entries = get_accrued_interest_entries(loan.name)
+				for entry in accrued_entries:
+					interest_paid = 0
+					principal_paid = 0
 
-				jv = frappe.get_doc('Journal Entry', payment.name)
-				jv.flags.ignore_links = True
-				jv.cancel()
+					if total_interest > entry.interest_amount:
+						interest_paid = entry.interest_amount
+					else:
+						interest_paid = total_interest
 
+					if total_principal > entry.payable_principal_amount:
+						principal_paid = entry.payable_principal_amount
+					else:
+						principal_paid = total_principal
+
+					frappe.db.sql(""" UPDATE `tabLoan Interest Accrual`
+						SET paid_principal_amount = `paid_principal_amount` + %s,
+							paid_interest_amount = `paid_interest_amount` + %s
+						WHERE name = %s""",
+						(principal_paid, interest_paid, entry.name))
+
+					total_principal -= principal_paid
+					total_interest -= interest_paid
+
+def create_loan_type(loan, loan_type_name, penalty_account):
+	loan_type_doc = frappe.new_doc('Loan Type')
+	loan_type_doc.loan_name = make_autoname("Loan Type-.####")
+	loan_type_doc.is_term_loan = 1
+	loan_type_doc.company = loan.company
+	loan_type_doc.mode_of_payment = loan.mode_of_payment
+	loan_type_doc.payment_account = loan.payment_account
+	loan_type_doc.loan_account = loan.loan_account
+	loan_type_doc.interest_income_account = loan.interest_income_account
+	loan_type_doc.penalty_income_account = penalty_account
+	loan_type_doc.submit()
+
+	return loan_type_doc.name