Merge pull request #18195 from deepeshgarg007/b2cs_json

fix: GSTR-1 B2CS JSON file generation and cess amount fixes
diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js
index fcbd10f..dd20632 100644
--- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js
+++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js
@@ -9,6 +9,26 @@
 				frappe.set_route("List", frm.doc.document_type);
 			});
 		}
+
+		let button = frm.doc.disabled ? "Enable" : "Disable";
+
+		frm.add_custom_button(__(button), function() {
+
+			frm.set_value('disabled', 1 - frm.doc.disabled);
+
+			frappe.call({
+				method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.disable_dimension",
+				args: {
+					doc: frm.doc
+				},
+				freeze: true,
+				callback: function(r) {
+					let message = frm.doc.disabled ? "Dimension Disabled" : "Dimension Enabled";
+					frm.save();
+					frappe.show_alert({message:__(message), indicator:'green'});
+				}
+			});
+		});
 	},
 
 	document_type: function(frm) {
@@ -21,13 +41,4 @@
 			}
 		});
 	},
-
-	disabled: function(frm) {
-		frappe.call({
-			method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.disable_dimension",
-			args: {
-				doc: frm.doc
-			}
-		});
-	}
 });
diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json
index 1e2bb92..57543a0 100644
--- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json
+++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json
@@ -38,7 +38,8 @@
    "default": "0",
    "fieldname": "disabled",
    "fieldtype": "Check",
-   "label": "Disable"
+   "label": "Disable",
+   "read_only": 1
   },
   {
    "default": "0",
@@ -53,7 +54,7 @@
    "label": "Mandatory For Profit and Loss Account"
   }
  ],
- "modified": "2019-05-27 18:18:17.792726",
+ "modified": "2019-07-07 18:56:19.517450",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Accounting Dimension",
diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
index 91d03be..15ace72 100644
--- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
+++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
@@ -121,11 +121,11 @@
 @frappe.whitelist()
 def disable_dimension(doc):
 	if frappe.flags.in_test:
-		frappe.enqueue(start_dimension_disabling, doc=doc)
+		toggle_disabling(doc=doc)
 	else:
-		start_dimension_disabling(doc=doc)
+		frappe.enqueue(toggle_disabling, doc=doc)
 
-def start_dimension_disabling(doc):
+def toggle_disabling(doc):
 	doc = json.loads(doc)
 
 	if doc.get('disabled'):
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.json b/erpnext/accounts/doctype/gl_entry/gl_entry.json
index 333d39a..a232a95 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.json
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.json
@@ -848,6 +848,39 @@
    "set_only_once": 0,
    "translatable": 0,
    "unique": 0
+  },
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_if_empty": 0,
+   "fieldname": "due_date",
+   "fieldtype": "Date",
+   "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": "Due Date",
+   "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,
+   "translatable": 0,
+   "unique": 0
   }
  ],
  "has_web_view": 0,
@@ -861,7 +894,7 @@
  "issingle": 0,
  "istable": 0,
  "max_attachments": 0,
- "modified": "2019-01-07 07:05:00.366399",
+ "modified": "2019-05-01 07:05:00.366399",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "GL Entry",
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 3132c93..8fbddb9 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -498,6 +498,7 @@
 					self.get_gl_dict({
 						"account": d.account,
 						"party_type": d.party_type,
+						"due_date": self.due_date,
 						"party": d.party,
 						"against": d.against_account,
 						"debit": flt(d.debit, d.precision("debit")),
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index 2c382c5..f17b2cb 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -302,7 +302,7 @@
 							},
 							() => frm.set_value("party_balance", r.message.party_balance),
 							() => frm.set_value("party_name", r.message.party_name),
-							() => frm.events.get_outstanding_documents(frm),
+							() => frm.clear_table("references"),
 							() => frm.events.hide_unhide_fields(frm),
 							() => frm.events.set_dynamic_labels(frm),
 							() => {
@@ -323,9 +323,7 @@
 
 		frm.events.set_account_currency_and_balance(frm, frm.doc.paid_from,
 			"paid_from_account_currency", "paid_from_account_balance", function(frm) {
-				if (frm.doc.payment_type == "Receive") {
-					frm.events.get_outstanding_documents(frm);
-				} else if (frm.doc.payment_type == "Pay") {
+				if (frm.doc.payment_type == "Pay") {
 					frm.events.paid_amount(frm);
 				}
 			}
@@ -337,9 +335,7 @@
 
 		frm.events.set_account_currency_and_balance(frm, frm.doc.paid_to,
 			"paid_to_account_currency", "paid_to_account_balance", function(frm) {
-				if(frm.doc.payment_type == "Pay") {
-					frm.events.get_outstanding_documents(frm);
-				} else if (frm.doc.payment_type == "Receive") {
+				if (frm.doc.payment_type == "Receive") {
 					if(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) {
 						if(frm.doc.source_exchange_rate) {
 							frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate);
@@ -533,26 +529,87 @@
 			frm.events.set_unallocated_amount(frm);
 	},
 
-	get_outstanding_documents: function(frm) {
+	get_outstanding_invoice: function(frm) {
+		const today = frappe.datetime.get_today();
+		const fields = [
+			{fieldtype:"Section Break", label: __("Posting Date")},
+			{fieldtype:"Date", label: __("From Date"),
+				fieldname:"from_posting_date", default:frappe.datetime.add_days(today, -30)},
+			{fieldtype:"Column Break"},
+			{fieldtype:"Date", label: __("To Date"), fieldname:"to_posting_date", default:today},
+			{fieldtype:"Section Break", label: __("Due Date")},
+			{fieldtype:"Date", label: __("From Date"), fieldname:"from_due_date"},
+			{fieldtype:"Column Break"},
+			{fieldtype:"Date", label: __("To Date"), fieldname:"to_due_date"},
+			{fieldtype:"Section Break", label: __("Outstanding Amount")},
+			{fieldtype:"Float", label: __("Greater Than Amount"),
+				fieldname:"outstanding_amt_greater_than", default: 0},
+			{fieldtype:"Column Break"},
+			{fieldtype:"Float", label: __("Less Than Amount"), fieldname:"outstanding_amt_less_than"},
+			{fieldtype:"Section Break"},
+			{fieldtype:"Check", label: __("Allocate Payment Amount"), fieldname:"allocate_payment_amount", default:1},
+		];
+
+		frappe.prompt(fields, function(filters){
+			frappe.flags.allocate_payment_amount = true;
+			frm.events.validate_filters_data(frm, filters);
+			frm.events.get_outstanding_documents(frm, filters);
+		}, __("Filters"), __("Get Outstanding Invoices"));
+	},
+
+	validate_filters_data: function(frm, filters) {
+		const fields = {
+			'Posting Date': ['from_posting_date', 'to_posting_date'],
+			'Due Date': ['from_posting_date', 'to_posting_date'],
+			'Advance Amount': ['from_posting_date', 'to_posting_date'],
+		};
+
+		for (let key in fields) {
+			let from_field = fields[key][0];
+			let to_field = fields[key][1];
+
+			if (filters[from_field] && !filters[to_field]) {
+				frappe.throw(__("Error: {0} is mandatory field",
+					[to_field.replace(/_/g, " ")]
+				));
+			} else if (filters[from_field] && filters[from_field] > filters[to_field]) {
+				frappe.throw(__("{0}: {1} must be less than {2}",
+					[key, from_field.replace(/_/g, " "), to_field.replace(/_/g, " ")]
+				));
+			}
+		}
+	},
+
+	get_outstanding_documents: function(frm, filters) {
 		frm.clear_table("references");
 
-		if(!frm.doc.party) return;
+		if(!frm.doc.party) {
+			return;
+		}
 
 		frm.events.check_mandatory_to_fetch(frm);
 		var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
 
+		var args = {
+			"posting_date": frm.doc.posting_date,
+			"company": frm.doc.company,
+			"party_type": frm.doc.party_type,
+			"payment_type": frm.doc.payment_type,
+			"party": frm.doc.party,
+			"party_account": frm.doc.payment_type=="Receive" ? frm.doc.paid_from : frm.doc.paid_to,
+			"cost_center": frm.doc.cost_center
+		}
+
+		for (let key in filters) {
+			args[key] = filters[key];
+		}
+
+		frappe.flags.allocate_payment_amount = filters['allocate_payment_amount'];
+
 		return  frappe.call({
 			method: 'erpnext.accounts.doctype.payment_entry.payment_entry.get_outstanding_reference_documents',
 			args: {
-				args: {
-					"posting_date": frm.doc.posting_date,
-					"company": frm.doc.company,
-					"party_type": frm.doc.party_type,
-					"payment_type": frm.doc.payment_type,
-					"party": frm.doc.party,
-					"party_account": frm.doc.payment_type=="Receive" ? frm.doc.paid_from : frm.doc.paid_to,
-					"cost_center": frm.doc.cost_center
-				}
+				args:args
 			},
 			callback: function(r, rt) {
 				if(r.message) {
@@ -608,25 +665,11 @@
 
 				frm.events.allocate_party_amount_against_ref_docs(frm,
 					(frm.doc.payment_type=="Receive" ? frm.doc.paid_amount : frm.doc.received_amount));
+
 			}
 		});
 	},
 
-	allocate_payment_amount: function(frm) {
-		if(frm.doc.payment_type == 'Internal Transfer'){
-			return
-		}
-
-		if(frm.doc.references.length == 0){
-			frm.events.get_outstanding_documents(frm);
-		}
-		if(frm.doc.payment_type == 'Internal Transfer') {
-			frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount);
-		} else {
-			frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount);
-		}
-	},
-
 	allocate_party_amount_against_ref_docs: function(frm, paid_amount) {
 		var total_positive_outstanding_including_order = 0;
 		var total_negative_outstanding = 0;
@@ -677,7 +720,7 @@
 
 		$.each(frm.doc.references || [], function(i, row) {
 			row.allocated_amount = 0 //If allocate payment amount checkbox is unchecked, set zero to allocate amount
-			if(frm.doc.allocate_payment_amount){
+			if(frappe.flags.allocate_payment_amount){
 				if(row.outstanding_amount > 0 && allocated_positive_outstanding > 0) {
 					if(row.outstanding_amount >= allocated_positive_outstanding) {
 						row.allocated_amount = allocated_positive_outstanding;
@@ -958,7 +1001,7 @@
 							},
 							() => {
 								if(frm.doc.payment_type != "Internal") {
-									frm.events.get_outstanding_documents(frm);
+									frm.clear_table("references");
 								}
 							}
 						]);
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json
index fcaa570..a85eccd 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.json
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json
@@ -40,7 +40,7 @@
   "target_exchange_rate",
   "base_received_amount",
   "section_break_14",
-  "allocate_payment_amount",
+  "get_outstanding_invoice",
   "references",
   "section_break_34",
   "total_allocated_amount",
@@ -325,19 +325,15 @@
    "reqd": 1
   },
   {
-   "collapsible": 1,
-   "collapsible_depends_on": "references",
    "depends_on": "eval:(doc.party && doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)",
    "fieldname": "section_break_14",
    "fieldtype": "Section Break",
    "label": "Reference"
   },
   {
-   "default": "1",
-   "depends_on": "eval:in_list(['Pay', 'Receive'], doc.payment_type)",
-   "fieldname": "allocate_payment_amount",
-   "fieldtype": "Check",
-   "label": "Allocate Payment Amount"
+   "fieldname": "get_outstanding_invoice",
+   "fieldtype": "Button",
+   "label": "Get Outstanding Invoice"
   },
   {
    "fieldname": "references",
@@ -570,7 +566,7 @@
   }
  ],
  "is_submittable": 1,
- "modified": "2019-05-25 22:02:40.575822",
+ "modified": "2019-05-27 15:53:21.108857",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Entry",
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index ea76126..699f046 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -574,8 +574,8 @@
 	# Get negative outstanding sales /purchase invoices
 	negative_outstanding_invoices = []
 	if args.get("party_type") not in ["Student", "Employee"] and not args.get("voucher_no"):
-		negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"),
-			args.get("party"), args.get("party_account"), party_account_currency, company_currency)
+		negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"), args.get("party"),
+			args.get("party_account"), args.get("company"), party_account_currency, company_currency)
 
 	# Get positive outstanding sales /purchase invoices/ Fees
 	condition = ""
@@ -585,10 +585,23 @@
 
 	# Add cost center condition
 	if args.get("cost_center") and get_allow_cost_center_in_entry_of_bs_account():
-			condition += " and cost_center='%s'" % args.get("cost_center")
+		condition += " and cost_center='%s'" % args.get("cost_center")
+
+	date_fields_dict = {
+		'posting_date': ['from_posting_date', 'to_posting_date'],
+		'due_date': ['from_due_date', 'to_due_date']
+	}
+
+	for fieldname, date_fields in date_fields_dict.items():
+		if args.get(date_fields[0]) and args.get(date_fields[1]):
+			condition += " and {0} between '{1}' and '{2}'".format(fieldname,
+				args.get(date_fields[0]), args.get(date_fields[1]))
+
+	if args.get("company"):
+		condition += " and company = {0}".format(frappe.db.escape(args.get("company")))
 
 	outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
-		args.get("party_account"), condition=condition)
+		args.get("party_account"), filters=args, condition=condition, limit=100)
 
 	for d in outstanding_invoices:
 		d["exchange_rate"] = 1
@@ -606,12 +619,19 @@
 	orders_to_be_billed = []
 	if (args.get("party_type") != "Student"):
 		orders_to_be_billed =  get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"),
-			args.get("party"), party_account_currency, company_currency)
+			args.get("party"), args.get("company"), party_account_currency, company_currency, filters=args)
 
-	return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
+	data = negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
+
+	if not data:
+		frappe.msgprint(_("No outstanding invoices found for the {0} <b>{1}</b>.")
+			.format(args.get("party_type").lower(), args.get("party")))
+
+	return data
 
 
-def get_orders_to_be_billed(posting_date, party_type, party, party_account_currency, company_currency, cost_center=None):
+def get_orders_to_be_billed(posting_date, party_type, party,
+	company, party_account_currency, company_currency, cost_center=None, filters=None):
 	if party_type == "Customer":
 		voucher_type = 'Sales Order'
 	elif party_type == "Supplier":
@@ -641,6 +661,7 @@
 			where
 				{party_type} = %s
 				and docstatus = 1
+				and company = %s
 				and ifnull(status, "") != "Closed"
 				and {ref_field} > advance_paid
 				and abs(100 - per_billed) > 0.01
@@ -652,10 +673,14 @@
 			"voucher_type": voucher_type,
 			"party_type": scrub(party_type),
 			"condition": condition
-		}), party, as_dict=True)
+		}), (party, company), as_dict=True)
 
 	order_list = []
 	for d in orders:
+		if not (d.outstanding_amount >= filters.get("outstanding_amt_greater_than")
+			and d.outstanding_amount <= filters.get("outstanding_amt_less_than")):
+			continue
+
 		d["voucher_type"] = voucher_type
 		# This assumes that the exchange rate required is the one in the SO
 		d["exchange_rate"] = get_exchange_rate(party_account_currency, company_currency, posting_date)
@@ -663,7 +688,8 @@
 
 	return order_list
 
-def get_negative_outstanding_invoices(party_type, party, party_account, party_account_currency, company_currency, cost_center=None):
+def get_negative_outstanding_invoices(party_type, party, party_account,
+	company, party_account_currency, company_currency, cost_center=None):
 	voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice"
 	supplier_condition = ""
 	if voucher_type == "Purchase Invoice":
@@ -684,7 +710,8 @@
 		from
 			`tab{voucher_type}`
 		where
-			{party_type} = %s and {party_account} = %s and docstatus = 1 and outstanding_amount < 0
+			{party_type} = %s and {party_account} = %s and docstatus = 1 and
+			company = %s and outstanding_amount < 0
 			{supplier_condition}
 		order by
 			posting_date, name
@@ -696,7 +723,7 @@
 			"party_type": scrub(party_type),
 			"party_account": "debit_to" if party_type == "Customer" else "credit_to",
 			"cost_center": cost_center
-		}), (party, party_account), as_dict=True)
+		}), (party, party_account, company), as_dict=True)
 
 
 @frappe.whitelist()
@@ -924,7 +951,6 @@
 	pe.paid_to_account_currency = party_account_currency if payment_type=="Pay" else bank.account_currency
 	pe.paid_amount = paid_amount
 	pe.received_amount = received_amount
-	pe.allocate_payment_amount = 1
 	pe.letter_head = doc.get("letter_head")
 
 	if pe.party_type in ["Customer", "Supplier"]:
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 1b03896..219d989 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -337,7 +337,8 @@
 		if not self.is_return:
 			self.update_against_document_in_jv()
 			self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
-			self.update_billing_status_in_pr()
+
+		self.update_billing_status_in_pr()
 
 		# Updating stock ledger should always be called after updating prevdoc status,
 		# because updating ordered qty in bin depends upon updated ordered qty in PO
@@ -416,6 +417,7 @@
 					"account": self.credit_to,
 					"party_type": "Supplier",
 					"party": self.supplier,
+					"due_date": self.due_date,
 					"against": self.against_expense_account,
 					"credit": grand_total_in_company_currency,
 					"credit_in_account_currency": grand_total_in_company_currency \
@@ -773,7 +775,8 @@
 
 		if not self.is_return:
 			self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
-			self.update_billing_status_in_pr()
+
+		self.update_billing_status_in_pr()
 
 		# Updating stock ledger should always be called after updating prevdoc status,
 		# because updating ordered qty in bin depends upon updated ordered qty in PO
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 71bdc2a..f8bb971 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -734,6 +734,7 @@
 					"account": self.debit_to,
 					"party_type": "Customer",
 					"party": self.customer,
+					"due_date": self.due_date,
 					"against": self.against_income_account,
 					"debit": grand_total_in_company_currency,
 					"debit_in_account_currency": grand_total_in_company_currency \
diff --git a/erpnext/accounts/report/accounts_payable/accounts_payable.js b/erpnext/accounts/report/accounts_payable/accounts_payable.js
index 70f193e..f6a561f 100644
--- a/erpnext/accounts/report/accounts_payable/accounts_payable.js
+++ b/erpnext/accounts/report/accounts_payable/accounts_payable.js
@@ -108,3 +108,14 @@
 		});
 	}
 }
+
+erpnext.dimension_filters.then((dimensions) => {
+	dimensions.forEach((dimension) => {
+		frappe.query_reports["Accounts Payable"].filters.splice(9, 0 ,{
+			"fieldname": dimension["fieldname"],
+			"label": __(dimension["label"]),
+			"fieldtype": "Link",
+			"options": dimension["document_type"]
+		});
+	});
+});
diff --git a/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js b/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js
index 06499ad..ec4f0c9 100644
--- a/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js
+++ b/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js
@@ -92,3 +92,14 @@
 		});
 	}
 }
+
+erpnext.dimension_filters.then((dimensions) => {
+	dimensions.forEach((dimension) => {
+		frappe.query_reports["Accounts Payable Summary"].filters.splice(9, 0 ,{
+			"fieldname": dimension["fieldname"],
+			"label": __(dimension["label"]),
+			"fieldtype": "Link",
+			"options": dimension["document_type"]
+		});
+	});
+});
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
index 3661afe..2a45454 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
@@ -172,3 +172,14 @@
 		});
 	}
 }
+
+erpnext.dimension_filters.then((dimensions) => {
+	dimensions.forEach((dimension) => {
+		frappe.query_reports["Accounts Receivable"].filters.splice(9, 0 ,{
+			"fieldname": dimension["fieldname"],
+			"label": __(dimension["label"]),
+			"fieldtype": "Link",
+			"options": dimension["document_type"]
+		});
+	});
+});
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index 2973748..0cda2c1 100755
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -5,6 +5,7 @@
 import frappe, erpnext
 from frappe import _, scrub
 from frappe.utils import getdate, nowdate, flt, cint, formatdate, cstr
+from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
 
 class ReceivablePayableReport(object):
 	def __init__(self, filters=None):
@@ -553,6 +554,14 @@
 			conditions.append("account in (%s)" % ','.join(['%s'] *len(accounts)))
 			values += accounts
 
+		accounting_dimensions = get_accounting_dimensions()
+
+		if accounting_dimensions:
+			for dimension in accounting_dimensions:
+				if self.filters.get(dimension):
+					conditions.append("{0} = %s".format(dimension))
+					values.append(self.filters.get(dimension))
+
 		return " and ".join(conditions), values
 
 	def get_gl_entries_for(self, party, party_type, against_voucher_type, against_voucher):
diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js
index f9162ad..a7c0787 100644
--- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js
+++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js
@@ -116,3 +116,14 @@
 		});
 	}
 }
+
+erpnext.dimension_filters.then((dimensions) => {
+	dimensions.forEach((dimension) => {
+		frappe.query_reports["Accounts Receivable Summary"].filters.splice(9, 0 ,{
+			"fieldname": dimension["fieldname"],
+			"label": __(dimension["label"]),
+			"fieldtype": "Link",
+			"options": dimension["document_type"]
+		});
+	});
+});
diff --git a/erpnext/accounts/report/budget_variance_report/budget_variance_report.js b/erpnext/accounts/report/budget_variance_report/budget_variance_report.js
index b2072f0..f2a33a8 100644
--- a/erpnext/accounts/report/budget_variance_report/budget_variance_report.js
+++ b/erpnext/accounts/report/budget_variance_report/budget_variance_report.js
@@ -63,9 +63,7 @@
 	]
 }
 
-let dimension_filters = erpnext.get_dimension_filters();
-
-dimension_filters.then((dimensions) => {
+erpnext.dimension_filters.then((dimensions) => {
 	dimensions.forEach((dimension) => {
 		frappe.query_reports["Budget Variance Report"].filters[4].options.push(dimension["document_type"]);
 	});
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js
index 32af644..ea82575 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.js
+++ b/erpnext/accounts/report/general_ledger/general_ledger.js
@@ -159,9 +159,7 @@
 	]
 }
 
-let dimension_filters = erpnext.get_dimension_filters();
-
-dimension_filters.then((dimensions) => {
+erpnext.dimension_filters.then((dimensions) => {
 	dimensions.forEach((dimension) => {
 		frappe.query_reports["General Ledger"].filters.splice(15, 0 ,{
 			"fieldname": dimension["fieldname"],
diff --git a/erpnext/accounts/report/profitability_analysis/profitability_analysis.js b/erpnext/accounts/report/profitability_analysis/profitability_analysis.js
index 80b50b9..d6864b5 100644
--- a/erpnext/accounts/report/profitability_analysis/profitability_analysis.js
+++ b/erpnext/accounts/report/profitability_analysis/profitability_analysis.js
@@ -16,7 +16,7 @@
 				"fieldname": "based_on",
 				"label": __("Based On"),
 				"fieldtype": "Select",
-				"options": "Cost Center\nProject",
+				"options": ["Cost Center", "Project"],
 				"default": "Cost Center",
 				"reqd": 1
 			},
@@ -104,5 +104,10 @@
 		"parent_field": "parent_account",
 		"initial_depth": 3
 	}
-});
 
+	erpnext.dimension_filters.then((dimensions) => {
+		dimensions.forEach((dimension) => {
+			frappe.query_reports["Profitability Analysis"].filters[1].options.push(dimension["document_type"]);
+		});
+	});
+});
diff --git a/erpnext/accounts/report/profitability_analysis/profitability_analysis.py b/erpnext/accounts/report/profitability_analysis/profitability_analysis.py
index a0d8c5f..6e9b31f 100644
--- a/erpnext/accounts/report/profitability_analysis/profitability_analysis.py
+++ b/erpnext/accounts/report/profitability_analysis/profitability_analysis.py
@@ -24,8 +24,17 @@
 	if based_on == 'cost_center':
 		return frappe.db.sql("""select name, parent_cost_center as parent_account, cost_center_name as account_name, lft, rgt
 			from `tabCost Center` where company=%s order by name""", company, as_dict=True)
-	else:
+	elif based_on == 'project':
 		return frappe.get_all('Project', fields = ["name"], filters = {'company': company}, order_by = 'name')
+	else:
+		filters = {}
+		doctype = frappe.unscrub(based_on)
+		has_company = frappe.db.has_column(doctype, 'company')
+
+		if has_company:
+			filters.update({'company': company})
+
+		return frappe.get_all(doctype, fields = ["name"], filters = filters, order_by = 'name')
 
 def get_data(accounts, filters, based_on):
 	if not accounts:
@@ -42,7 +51,7 @@
 	accumulate_values_into_parents(accounts, accounts_by_name)
 
 	data = prepare_data(accounts, filters, total_row, parent_children_map, based_on)
-	data = filter_out_zero_value_rows(data, parent_children_map, 
+	data = filter_out_zero_value_rows(data, parent_children_map,
 		show_zero_values=filters.get("show_zero_values"))
 
 	return data
@@ -112,14 +121,14 @@
 
 		for key in value_fields:
 			row[key] = flt(d.get(key, 0.0), 3)
-			
+
 			if abs(row[key]) >= 0.005:
 				# ignore zero values
 				has_value = True
 
 		row["has_value"] = has_value
 		data.append(row)
-		
+
 	data.extend([{},total_row])
 
 	return data
@@ -174,7 +183,7 @@
 	if from_date:
 		additional_conditions.append("and posting_date >= %(from_date)s")
 
-	gl_entries = frappe.db.sql("""select posting_date, {based_on} as based_on, debit, credit, 
+	gl_entries = frappe.db.sql("""select posting_date, {based_on} as based_on, debit, credit,
 		is_opening, (select root_type from `tabAccount` where name = account) as type
 		from `tabGL Entry` where company=%(company)s
 		{additional_conditions}
diff --git a/erpnext/accounts/report/sales_register/sales_register.js b/erpnext/accounts/report/sales_register/sales_register.js
index 0b48882c..442aa12 100644
--- a/erpnext/accounts/report/sales_register/sales_register.js
+++ b/erpnext/accounts/report/sales_register/sales_register.js
@@ -67,3 +67,14 @@
 		}
 	]
 }
+
+erpnext.dimension_filters.then((dimensions) => {
+	dimensions.forEach((dimension) => {
+		frappe.query_reports["Sales Register"].filters.splice(7, 0 ,{
+			"fieldname": dimension["fieldname"],
+			"label": __(dimension["label"]),
+			"fieldtype": "Link",
+			"options": dimension["document_type"]
+		});
+	});
+});
diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py
index de60995..d08056f 100644
--- a/erpnext/accounts/report/sales_register/sales_register.py
+++ b/erpnext/accounts/report/sales_register/sales_register.py
@@ -5,6 +5,7 @@
 import frappe
 from frappe.utils import flt
 from frappe import msgprint, _
+from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
 
 def execute(filters=None):
 	return _execute(filters)
@@ -163,6 +164,16 @@
 			 where parent=`tabSales Invoice`.name
 			 	and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s)"""
 
+	accounting_dimensions = get_accounting_dimensions()
+
+	if accounting_dimensions:
+		for dimension in accounting_dimensions:
+			if filters.get(dimension):
+				conditions += """ and exists(select name from `tabSales Invoice Item`
+					where parent=`tabSales Invoice`.name
+						and ifnull(`tabSales Invoice Item`.{0}, '') = %({0})s)""".format(dimension)
+
+
 	return conditions
 
 def get_invoices(filters, additional_query_columns):
diff --git a/erpnext/accounts/report/trial_balance/trial_balance.js b/erpnext/accounts/report/trial_balance/trial_balance.js
index 8bc7280..73d2ab3 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.js
+++ b/erpnext/accounts/report/trial_balance/trial_balance.js
@@ -96,9 +96,7 @@
 	}
 });
 
-let dimension_filters = erpnext.get_dimension_filters();
-
-dimension_filters.then((dimensions) => {
+erpnext.dimension_filters.then((dimensions) => {
 	dimensions.forEach((dimension) => {
 		frappe.query_reports["Trial Balance"].filters.splice(5, 0 ,{
 			"fieldname": dimension["fieldname"],
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 7a1f6c5..542c7e4 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -628,7 +628,7 @@
 	return held_invoices
 
 
-def get_outstanding_invoices(party_type, party, account, condition=None):
+def get_outstanding_invoices(party_type, party, account, condition=None, filters=None):
 	outstanding_invoices = []
 	precision = frappe.get_precision("Sales Invoice", "outstanding_amount") or 2
 
@@ -644,7 +644,8 @@
 
 	invoice_list = frappe.db.sql("""
 		select
-			voucher_no, voucher_type, posting_date, ifnull(sum({dr_or_cr}), 0) as invoice_amount
+			voucher_no, voucher_type, posting_date, due_date,
+			ifnull(sum({dr_or_cr}), 0) as invoice_amount
 		from
 			`tabGL Entry`
 		where
@@ -677,7 +678,7 @@
 	""".format(payment_dr_or_cr=payment_dr_or_cr), {
 		"party_type": party_type,
 		"party": party,
-		"account": account,
+		"account": account
 	}, as_dict=True)
 
 	pe_map = frappe._dict()
@@ -688,10 +689,12 @@
 		payment_amount = pe_map.get((d.voucher_type, d.voucher_no), 0)
 		outstanding_amount = flt(d.invoice_amount - payment_amount, precision)
 		if outstanding_amount > 0.5 / (10**precision):
-			if not d.voucher_type == "Purchase Invoice" or d.voucher_no not in held_invoices:
-				due_date = frappe.db.get_value(
-					d.voucher_type, d.voucher_no, "posting_date" if party_type == "Employee" else "due_date")
+			if (filters.get("outstanding_amt_greater_than") and
+				not (outstanding_amount >= filters.get("outstanding_amt_greater_than") and
+				outstanding_amount <= filters.get("outstanding_amt_less_than"))):
+				continue
 
+			if not d.voucher_type == "Purchase Invoice" or d.voucher_no not in held_invoices:
 				outstanding_invoices.append(
 					frappe._dict({
 						'voucher_no': d.voucher_no,
@@ -700,7 +703,7 @@
 						'invoice_amount': flt(d.invoice_amount),
 						'payment_amount': payment_amount,
 						'outstanding_amount': outstanding_amount,
-						'due_date': due_date
+						'due_date': d.due_date
 					})
 				)
 
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index f70870b..b193ac2 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -294,7 +294,7 @@
 			frappe.db.sql("""update `tab%(target_parent_dt)s`
 				set %(target_parent_field)s = round(
 					ifnull((select
-						ifnull(sum(if(%(target_ref_field)s > %(target_field)s, abs(%(target_field)s), abs(%(target_ref_field)s))), 0)
+						ifnull(sum(if(abs(%(target_ref_field)s) > abs(%(target_field)s), abs(%(target_field)s), abs(%(target_ref_field)s))), 0)
 						/ sum(abs(%(target_ref_field)s)) * 100
 					from `tab%(target_dt)s` where parent="%(name)s" having sum(abs(%(target_ref_field)s)) > 0), 0), 6)
 					%(update_modified)s
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index bd41c7e..0dd88e9 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -615,4 +615,5 @@
 erpnext.patches.v12_0.set_quotation_status
 erpnext.patches.v12_0.set_priority_for_support
 erpnext.patches.v12_0.delete_priority_property_setter
+erpnext.patches.v12_0.update_due_date_in_gle
 erpnext.patches.v12_0.add_default_buying_selling_terms_in_company
diff --git a/erpnext/patches/v12_0/update_due_date_in_gle.py b/erpnext/patches/v12_0/update_due_date_in_gle.py
new file mode 100644
index 0000000..4c47a82
--- /dev/null
+++ b/erpnext/patches/v12_0/update_due_date_in_gle.py
@@ -0,0 +1,17 @@
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+    frappe.reload_doc("accounts", "doctype", "gl_entry")
+
+    for doctype in ["Sales Invoice", "Purchase Invoice", "Journal Entry"]:
+        frappe.reload_doc("accounts", "doctype", frappe.scrub(doctype))
+
+        frappe.db.sql(""" UPDATE `tabGL Entry`, `tab{doctype}`
+            SET
+                `tabGL Entry`.due_date = `tab{doctype}`.due_date
+            WHERE
+                `tabGL Entry`.voucher_no = `tab{doctype}`.name and `tabGL Entry`.party is not null
+                and `tabGL Entry`.voucher_type in ('Sales Invoice', 'Purchase Invoice', 'Journal Entry')
+                and account in (select name from `tabAccount` where account_type in ('Receivable', 'Payable') )""" #nosec
+            .format(doctype=doctype))
diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js
index d1113a4..89cb13d 100644
--- a/erpnext/public/js/financial_statements.js
+++ b/erpnext/public/js/financial_statements.js
@@ -129,9 +129,7 @@
 		}
 	]
 
-	let dimension_filters = erpnext.get_dimension_filters();
-
-	dimension_filters.then((dimensions) => {
+	erpnext.dimension_filters.then((dimensions) => {
 		dimensions.forEach((dimension) => {
 			filters.push({
 				"fieldname": dimension["fieldname"],
diff --git a/erpnext/public/js/utils/dimension_tree_filter.js b/erpnext/public/js/utils/dimension_tree_filter.js
index fef4507..a9122d8 100644
--- a/erpnext/public/js/utils/dimension_tree_filter.js
+++ b/erpnext/public/js/utils/dimension_tree_filter.js
@@ -7,7 +7,7 @@
 	"Landed Cost Item", "Asset Value Adjustment", "Loyalty Program", "Fee Schedule", "Fee Structure", "Stock Reconciliation",
 	"Travel Request", "Fees", "POS Profile"];
 
-let dimension_filters = erpnext.get_dimension_filters();
+erpnext.dimension_filters = erpnext.get_dimension_filters();
 
 erpnext.doctypes_with_dimensions.forEach((doctype) => {
 	frappe.ui.form.on(doctype, {
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js
index 6bcdc2b..569a03a 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.js
@@ -77,8 +77,34 @@
 
 
 	},
+
 	print_without_amount: function(frm) {
 		erpnext.stock.delivery_note.set_print_hide(frm.doc);
+	},
+
+	refresh: function(frm) {
+		if (frm.doc.docstatus === 1 && frm.doc.is_return === 1 && frm.doc.per_billed !== 100) {
+			frm.add_custom_button(__('Credit Note'), function() {
+				frappe.confirm(__("Are you sure you want to make credit note?"),
+					function() {
+						frm.trigger("make_credit_note");
+					}
+				);
+			}, __('Create'));
+
+			frm.page.set_inner_btn_group_as_primary(__('Create'));
+		}
+	},
+
+	make_credit_note: function(frm) {
+		frm.call({
+			method: "make_return_invoice",
+			doc: frm.doc,
+			freeze: true,
+			callback: function() {
+				frm.reload_doc();
+			}
+		});
 	}
 });
 
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 1e522b8..ec7df2d 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -333,7 +333,10 @@
 			return_invoice.is_return = True
 			return_invoice.save()
 			return_invoice.submit()
-			frappe.msgprint(_("Credit Note {0} has been created automatically").format(return_invoice.name))
+
+			credit_note_link = frappe.utils.get_link_to_form('Sales Invoice', return_invoice.name)
+
+			frappe.msgprint(_("Credit Note {0} has been created automatically").format(credit_note_link))
 		except:
 			frappe.throw(_("Could not create Credit Note automatically, please uncheck 'Issue Credit Note' and submit again"))
 
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index e82aa2c..a2d3e75 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -38,6 +38,29 @@
 		if(frm.doc.company) {
 			frm.trigger("toggle_display_account_head");
 		}
+
+		if (frm.doc.docstatus === 1 && frm.doc.is_return === 1 && frm.doc.per_billed !== 100) {
+			frm.add_custom_button(__('Debit Note'), function() {
+				frappe.confirm(__("Are you sure you want to make debit note?"),
+					function() {
+						frm.trigger("make_debit_note");
+					}
+				);
+			}, __('Create'));
+
+			frm.page.set_inner_btn_group_as_primary(__('Create'));
+		}
+	},
+
+	make_debit_note: function(frm) {
+		frm.call({
+			method: "make_return_invoice",
+			doc: frm.doc,
+			freeze: true,
+			callback: function() {
+				frm.reload_doc();
+			}
+		});
 	},
 
 	company: function(frm) {
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 67cd7f8..df28bec 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -387,6 +387,16 @@
 
 		self.load_from_db()
 
+	def make_return_invoice(self):
+		return_invoice = make_purchase_invoice(self.name)
+		return_invoice.is_return = True
+		return_invoice.save()
+		return_invoice.submit()
+
+		debit_note_link = frappe.utils.get_link_to_form('Purchase Invoice', return_invoice.name)
+
+		frappe.msgprint(_("Debit Note {0} has been created automatically").format(debit_note_link))
+
 def update_billed_amount_based_on_po(po_detail, update_modified=True):
 	# Billed against Sales Order directly
 	billed_against_po = frappe.db.sql("""select sum(amount) from `tabPurchase Invoice Item`