Merge pull request #17297 from netchampfaris/index-item-route

fix: Add index to Item route
diff --git a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py
index 64aa4e4..d1ede67 100644
--- a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py
+++ b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py
@@ -190,9 +190,11 @@
 			customer,
 			posting_date,
 			outstanding_amount
-		from `tabSales Invoice`
+		from `tabSales Invoice` si
 		where
 			docstatus = 1
 			and outstanding_amount > 0
 			%s
+			and not exists(select di.name from `tabDiscounted Invoice` di
+				where di.docstatus=1 and di.sales_invoice=si.name)
 	""" % where_condition, filters, as_dict=1)
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting_dashboard.py b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting_dashboard.py
new file mode 100644
index 0000000..6523cd3
--- /dev/null
+++ b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting_dashboard.py
@@ -0,0 +1,20 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+	return {
+		'fieldname': 'reference_name',
+		'internal_links': {
+			'Sales Invoice': ['invoices', 'sales_invoice']
+		},
+		'transactions': [
+			{
+				'label': _('Reference'),
+				'items': ['Sales Invoice']
+			},
+			{
+				'label': _('Payment'),
+				'items': ['Payment Entry', 'Journal Entry']
+			}
+		]
+	}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/invoice_discounting/test_invoice_discounting.py b/erpnext/accounts/doctype/invoice_discounting/test_invoice_discounting.py
index 4f93e11..dc7f462 100644
--- a/erpnext/accounts/doctype/invoice_discounting/test_invoice_discounting.py
+++ b/erpnext/accounts/doctype/invoice_discounting/test_invoice_discounting.py
@@ -122,23 +122,26 @@
 			period=60
 			)
 
-		inv_disc.create_disbursement_entry()
-		je = inv_disc.close_loan()
+		je1 = inv_disc.create_disbursement_entry()
+		je1.posting_date = nowdate()
+		je1.submit()
 
-		self.assertEqual(je.accounts[0].account, self.short_term_loan)
-		self.assertEqual(je.accounts[0].debit_in_account_currency, flt(inv_disc.total_amount))
+		je2 = inv_disc.close_loan()
 
-		self.assertEqual(je.accounts[1].account, self.bank_account)
-		self.assertEqual(je.accounts[1].credit_in_account_currency, flt(inv_disc.total_amount))
+		self.assertEqual(je2.accounts[0].account, self.short_term_loan)
+		self.assertEqual(je2.accounts[0].debit_in_account_currency, flt(inv_disc.total_amount))
 
-		self.assertEqual(je.accounts[2].account, self.ar_discounted)
-		self.assertEqual(je.accounts[2].credit_in_account_currency, flt(inv.outstanding_amount))
+		self.assertEqual(je2.accounts[1].account, self.bank_account)
+		self.assertEqual(je2.accounts[1].credit_in_account_currency, flt(inv_disc.total_amount))
 
-		self.assertEqual(je.accounts[3].account, self.ar_unpaid)
-		self.assertEqual(je.accounts[3].debit_in_account_currency, flt(inv.outstanding_amount))
+		self.assertEqual(je2.accounts[2].account, self.ar_discounted)
+		self.assertEqual(je2.accounts[2].credit_in_account_currency, flt(inv.outstanding_amount))
 
-		je.posting_date = nowdate()
-		je.submit()
+		self.assertEqual(je2.accounts[3].account, self.ar_unpaid)
+		self.assertEqual(je2.accounts[3].debit_in_account_currency, flt(inv.outstanding_amount))
+
+		je2.posting_date = nowdate()
+		je2.submit()
 		inv_disc.reload()
 
 		self.assertEqual(inv_disc.status, "Settled")
@@ -154,19 +157,21 @@
 			bank_account=self.bank_account,
 			start=add_days(nowdate(), -80),
 			period=60
-			)
+		)
 
-		inv_disc.create_disbursement_entry()
-		je = inv_disc.close_loan()
+		je1 = inv_disc.create_disbursement_entry()
+		je1.posting_date = nowdate()
+		je1.submit()
 
-		je.posting_date = nowdate()
-		je.submit()
+		je2 = inv_disc.close_loan()
+		je2.posting_date = nowdate()
+		je2.submit()
 
-		self.assertEqual(je.accounts[0].account, self.short_term_loan)
-		self.assertEqual(je.accounts[0].debit_in_account_currency, flt(inv_disc.total_amount))
+		self.assertEqual(je2.accounts[0].account, self.short_term_loan)
+		self.assertEqual(je2.accounts[0].debit_in_account_currency, flt(inv_disc.total_amount))
 
-		self.assertEqual(je.accounts[1].account, self.bank_account)
-		self.assertEqual(je.accounts[1].credit_in_account_currency, flt(inv_disc.total_amount))
+		self.assertEqual(je2.accounts[1].account, self.bank_account)
+		self.assertEqual(je2.accounts[1].credit_in_account_currency, flt(inv_disc.total_amount))
 
 		inv_disc.reload()
 
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 28869d8..08d7073 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -3,7 +3,7 @@
 
 from __future__ import unicode_literals
 import frappe, erpnext, json
-from frappe.utils import cstr, flt, fmt_money, formatdate, getdate, nowdate, cint
+from frappe.utils import cstr, flt, fmt_money, formatdate, getdate, nowdate, cint, get_link_to_form
 from frappe import msgprint, _, scrub
 from erpnext.controllers.accounts_controller import AccountsController
 from erpnext.accounts.utils import get_balance_on, get_account_currency
@@ -53,6 +53,20 @@
 		self.update_inter_company_jv()
 		self.update_invoice_discounting()
 
+	def on_cancel(self):
+		from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
+		from erpnext.hr.doctype.salary_slip.salary_slip import unlink_ref_doc_from_salary_slip
+		unlink_ref_doc_from_payment_entries(self)
+		unlink_ref_doc_from_salary_slip(self.name)
+		self.make_gl_entries(1)
+		self.update_advance_paid()
+		self.update_expense_claim()
+		self.update_loan()
+		self.unlink_advance_entry_reference()
+		self.unlink_asset_reference()
+		self.unlink_inter_company_jv()
+		self.unlink_asset_adjustment_entry()
+		self.update_invoice_discounting()
 
 	def get_title(self):
 		return self.pay_to_recd_from or self.accounts[0].account
@@ -83,31 +97,32 @@
 				"inter_company_journal_entry_reference", self.name)
 
 	def update_invoice_discounting(self):
-		invoice_discounting_list = [d.reference_name for d in self.accounts if d.reference_type=="Invoice Discounting"]
+		def _validate_invoice_discounting_status(inv_disc, id_status, expected_status, row_id):
+			id_link = get_link_to_form("Invoice Discounting", inv_disc)
+			if id_status != expected_status:
+				frappe.throw(_("Row #{0}: Status must be {1} for Invoice Discounting {2}").format(d.idx, expected_status, id_link))
+
+		invoice_discounting_list = list(set([d.reference_name for d in self.accounts if d.reference_type=="Invoice Discounting"]))
 		for inv_disc in invoice_discounting_list:
-			short_term_loan_account = frappe.db.get_value("Invoice Discounting", inv_disc, "short_term_loan")
+			short_term_loan_account, id_status = frappe.db.get_value("Invoice Discounting", inv_disc, ["short_term_loan", "status"])
 			for d in self.accounts:
 				if d.account == short_term_loan_account and d.reference_name == inv_disc:
-					if d.credit > 0:
-						status = "Disbursed"
-					elif d.debit > 0:
-						status = "Settled"
+					if self.docstatus == 1:
+						if d.credit > 0:
+							_validate_invoice_discounting_status(inv_disc, id_status, "Sanctioned", d.idx)
+							status = "Disbursed"
+						elif d.debit > 0:
+							_validate_invoice_discounting_status(inv_disc, id_status, "Disbursed", d.idx)
+							status = "Settled"
+					else:
+						if d.credit > 0:
+							_validate_invoice_discounting_status(inv_disc, id_status, "Disbursed", d.idx)
+							status = "Sanctioned"
+						elif d.debit > 0:
+							_validate_invoice_discounting_status(inv_disc, id_status, "Settled", d.idx)
+							status = "Disbursed"
 					frappe.db.set_value("Invoice Discounting", inv_disc, "status", status)
 
-	def on_cancel(self):
-		from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
-		from erpnext.hr.doctype.salary_slip.salary_slip import unlink_ref_doc_from_salary_slip
-		unlink_ref_doc_from_payment_entries(self)
-		unlink_ref_doc_from_salary_slip(self.name)
-		self.make_gl_entries(1)
-		self.update_advance_paid()
-		self.update_expense_claim()
-		self.update_loan()
-		self.unlink_advance_entry_reference()
-		self.unlink_asset_reference()
-		self.unlink_inter_company_jv()
-		self.unlink_asset_adjustment_entry()
-
 	def unlink_advance_entry_reference(self):
 		for d in self.get("accounts"):
 			if d.is_advance == "Yes" and d.reference_type in ("Sales Invoice", "Purchase Invoice"):
diff --git a/erpnext/config/accounting.py b/erpnext/config/accounting.py
index afe35f8..1b8bf27 100644
--- a/erpnext/config/accounting.py
+++ b/erpnext/config/accounting.py
@@ -234,6 +234,11 @@
 				},
 				{
 					"type": "doctype",
+					"label": _("Invoice Discounting"),
+					"name": "Invoice Discounting",
+				},
+				{
+					"type": "doctype",
 					"label": _("Bank Statement Transaction Entry List"),
 					"name": "Bank Statement Transaction Entry",
 					"route": "#List/Bank Statement Transaction Entry",