Make Journal entry from Invoice based on Payment Terms (due date) #11989 (#12019)

* don"t summarise due_dates query

* reference_due_date to fetch outstanding based on due date

* use if else so that no need to do useless checks

* clear debit and credit fields before fetching outstanding

* grid keeps forgetting drop down so add to options

* clear debit and credit fields before fetching outstanding properly
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js
index 41000f3..e25abfb 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.js
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js
@@ -221,6 +221,7 @@
 						input.empty();
 						input.add_options(options);
 						frappe.model.set_value(cdt, cdn, "reference_due_date", options[0]);
+						me.frm.cur_grid.get_field("reference_due_date").df.options = options.join('\n');
 						me.due_date_options_cache[d.reference_name] = options;
 					}
 				});
@@ -230,20 +231,42 @@
 		if(d.reference_name) {
 			if (d.reference_type==="Purchase Invoice" && !flt(d.debit)) {
 				this.get_outstanding('Purchase Invoice', d.reference_name, doc.company, d);
-			}
-			if (d.reference_type==="Sales Invoice" && !flt(d.credit)) {
+			} else if (d.reference_type==="Sales Invoice" && !flt(d.credit)) {
 				this.get_outstanding('Sales Invoice', d.reference_name, doc.company, d);
-			}
-			if (d.reference_type==="Journal Entry" && !flt(d.credit) && !flt(d.debit)) {
+			} else if (d.reference_type==="Journal Entry" && !flt(d.credit) && !flt(d.debit)) {
 				this.get_outstanding('Journal Entry', d.reference_name, doc.company, d);
 			}
+
 			if( in_list(["Sales Invoice", "Purchase Invoice"]), d.reference_type) {
 				get_invoice_due_dates(d.reference_name);
 			}
 		}
 	},
 
-	get_outstanding: function(doctype, docname, company, child) {
+	reference_due_date: function(doc, cdt, cdn) {
+		const d = frappe.get_doc(cdt, cdn);
+
+		if (d.reference_type && d.reference_name && d.reference_due_date) {
+			if (in_list(["Sales Invoice", "Purchase Invoice"], d.reference_type)) {
+				console.log('cdt:', cdt, cdn);
+				frappe.model.set_value(cdt, cdn, 'debit_in_account_currency', '');
+				frappe.model.set_value(cdt, cdn, 'credit_in_account_currency', '');
+			}
+			if (d.reference_type==="Purchase Invoice") {
+				this.get_outstanding(
+					'Purchase Invoice', d.reference_name, doc.company, d, d.reference_due_date
+				);
+			} else if (d.reference_type==="Sales Invoice") {
+				this.get_outstanding(
+					'Sales Invoice', d.reference_name, doc.company, d, d.reference_due_date
+				);
+			}
+
+			frappe.model.set_value(cdt, cdn, 'reference_due_date', d.reference_due_date);
+		}
+	},
+
+	get_outstanding: function(doctype, docname, company, child, due_date) {
 		var me = this;
 		var args = {
 			"doctype": doctype,
@@ -254,6 +277,8 @@
 			"company": company
 		}
 
+		if (due_date) args.due_date = due_date;
+
 		return frappe.call({
 			method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_outstanding",
 			args: { args: args},
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 0977037..a298ae3 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
+from frappe.utils import cstr, flt, fmt_money, formatdate, getdate
 from frappe import msgprint, _, scrub
 from erpnext.controllers.accounts_controller import AccountsController
 from erpnext.accounts.utils import get_balance_on, get_account_currency
@@ -782,8 +782,7 @@
 		}
 	elif args.get("doctype") in ("Sales Invoice", "Purchase Invoice"):
 		party_type = "Customer" if args.get("doctype") == "Sales Invoice" else "Supplier"
-		invoice = frappe.db.get_value(args["doctype"], args["docname"],
-			["outstanding_amount", "conversion_rate", scrub(party_type)], as_dict=1)
+		invoice = frappe.get_doc(args['doctype'], args['docname']).as_dict()
 
 		exchange_rate = invoice.conversion_rate if (args.get("account_currency") != company_currency) else 1
 
@@ -794,8 +793,17 @@
 			amount_field = "debit_in_account_currency" \
 				if flt(invoice.outstanding_amount) > 0 else "credit_in_account_currency"
 
+		if args.get('due_date'):
+			outstanding = ''
+			for d in invoice.payment_schedule:
+				if d.due_date == getdate(args['due_date']):
+					outstanding = abs(flt(d.payment_amount))
+					break
+		else:
+			outstanding = abs(flt(invoice.outstanding_amount))
+
 		return {
-			amount_field: abs(flt(invoice.outstanding_amount)),
+			amount_field: outstanding,
 			"exchange_rate": exchange_rate,
 			"party_type": party_type,
 			"party": invoice.get(scrub(party_type))
@@ -902,7 +910,7 @@
 @frappe.whitelist()
 def get_invoice_due_dates(name):
 	result = frappe.get_list(
-		doctype='GL Entry', group_by='name, due_date',
+		doctype='GL Entry',
 		filters={'voucher_no': name, "ifnull(due_date, '')": ('!=', '')},
 		fields=['due_date'], distinct=True
 	)