Merge branch 'develop' of https://github.com/frappe/erpnext into rebrand-ui
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index c6de641..164f120 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -244,6 +244,8 @@
 
 		super(Account, self).on_trash(True)
 
+@frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_parent_account(doctype, txt, searchfield, start, page_len, filters):
 	return frappe.db.sql("""select name from tabAccount
 		where is_group = 1 and docstatus != 2 and company = %s
diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py b/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py
index 1bf9196..0e3b24c 100644
--- a/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py
@@ -225,7 +225,7 @@
 
 			account['parent_account'] = parent
 			account['expandable'] = True if identify_is_group(child) else False
-			account['value'] = (child.get('account_number') + ' - ' + account_name) \
+			account['value'] = (cstr(child.get('account_number')).strip() + ' - ' + account_name) \
 				if child.get('account_number') else account_name
 			accounts.append(account)
 			_import_accounts(child, account['value'])
diff --git a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py
index 6fec3ab..76d82e7 100644
--- a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py
+++ b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py
@@ -60,12 +60,12 @@
 		""".format(condition=condition), {"account": self.account, "from":self.from_date,
 				"to": self.to_date, "bank_account": self.bank_account}, as_dict=1)
 
-		pos_entries = []
+		pos_sales_invoices, pos_purchase_invoices = [], []
 		if self.include_pos_transactions:
-			pos_entries = frappe.db.sql("""
+			pos_sales_invoices = frappe.db.sql("""
 				select
 					"Sales Invoice Payment" as payment_document, sip.name as payment_entry, sip.amount as debit,
-					si.posting_date, si.debit_to as against_account, sip.clearance_date,
+					si.posting_date, si.customer as against_account, sip.clearance_date,
 					account.account_currency, 0 as credit
 				from `tabSales Invoice Payment` sip, `tabSales Invoice` si, `tabAccount` account
 				where
@@ -75,7 +75,20 @@
 					si.posting_date ASC, si.name DESC
 			""", {"account":self.account, "from":self.from_date, "to":self.to_date}, as_dict=1)
 
-		entries = sorted(list(payment_entries)+list(journal_entries+list(pos_entries)),
+			pos_purchase_invoices = frappe.db.sql("""
+				select
+					"Purchase Invoice" as payment_document, pi.name as payment_entry, pi.paid_amount as credit,
+					pi.posting_date, pi.supplier as against_account, pi.clearance_date,
+					account.account_currency, 0 as debit
+				from `tabPurchase Invoice` pi, `tabAccount` account
+				where
+					pi.cash_bank_account=%(account)s and pi.docstatus=1 and account.name = pi.cash_bank_account
+					and pi.posting_date >= %(from)s and pi.posting_date <= %(to)s
+				order by
+					pi.posting_date ASC, pi.name DESC
+			""", {"account": self.account, "from": self.from_date, "to": self.to_date}, as_dict=1)
+
+		entries = sorted(list(payment_entries) + list(journal_entries + list(pos_sales_invoices) + list(pos_purchase_invoices)),
 			key=lambda k: k['posting_date'] or getdate(nowdate()))
 
 		self.set('payment_entries', [])
diff --git a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py
index f28a074..88e1055 100644
--- a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py
+++ b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py
@@ -27,4 +27,4 @@
 	for col in column_list:
 		sanitize_searchfield(col) 
 	return frappe.db.sql(''' select {columns} from `tab{doctype}` where name=%s'''
-		.format(columns=", ".join(json.loads(column_list)), doctype=doctype), docname, as_dict=1)[0]
+		.format(columns=", ".join(column_list), doctype=doctype), docname, as_dict=1)[0]
diff --git a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.js b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.js
index 0b7cff3..2235298 100644
--- a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.js
+++ b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.js
@@ -135,7 +135,7 @@
 			callback: function(r) {
 				if(!r.exc) {
 					clearInterval(frm.page["interval"]);
-					frm.page.set_indicator(__('Import Successfull'), 'blue');
+					frm.page.set_indicator(__('Import Successful'), 'blue');
 					create_reset_button(frm);
 				}
 			}
diff --git a/erpnext/accounts/doctype/dunning/dunning.js b/erpnext/accounts/doctype/dunning/dunning.js
index c563368..9909c6c 100644
--- a/erpnext/accounts/doctype/dunning/dunning.js
+++ b/erpnext/accounts/doctype/dunning/dunning.js
@@ -44,6 +44,19 @@
 			);
 			frm.page.set_inner_btn_group_as_primary(__("Create"));
 		}
+
+		if(frm.doc.docstatus > 0) {
+			frm.add_custom_button(__('Ledger'), function() {
+				frappe.route_options = {
+					"voucher_no": frm.doc.name,
+					"from_date": frm.doc.posting_date,
+					"to_date": frm.doc.posting_date,
+					"company": frm.doc.company,
+					"show_cancelled_entries": frm.doc.docstatus === 2
+				};
+				frappe.set_route("query-report", "General Ledger");
+			}, __('View'));
+		}
 	},
 	overdue_days: function (frm) {
 		frappe.db.get_value(
@@ -125,9 +138,9 @@
 	},
 	calculate_interest_and_amount: function (frm) {
 		const interest_per_year = frm.doc.outstanding_amount * frm.doc.rate_of_interest / 100;
-		const interest_amount = interest_per_year / 365 * frm.doc.overdue_days || 0;
-		const dunning_amount = interest_amount + frm.doc.dunning_fee;
-		const grand_total = frm.doc.outstanding_amount + dunning_amount;
+		const interest_amount = flt((interest_per_year * cint(frm.doc.overdue_days)) / 365 || 0, precision('interest_amount'));
+		const dunning_amount = flt(interest_amount + frm.doc.dunning_fee, precision('dunning_amount'));
+		const grand_total = flt(frm.doc.outstanding_amount + dunning_amount, precision('grand_total'));
 		frm.set_value("interest_amount", interest_amount);
 		frm.set_value("dunning_amount", dunning_amount);
 		frm.set_value("grand_total", grand_total);
diff --git a/erpnext/accounts/doctype/dunning/dunning.json b/erpnext/accounts/doctype/dunning/dunning.json
index b3eddf5..d55bfd1 100644
--- a/erpnext/accounts/doctype/dunning/dunning.json
+++ b/erpnext/accounts/doctype/dunning/dunning.json
@@ -29,10 +29,10 @@
   "company_address_display",
   "section_break_6",
   "dunning_type",
-  "interest_amount",
+  "dunning_fee",
   "column_break_8",
   "rate_of_interest",
-  "dunning_fee",
+  "interest_amount",
   "section_break_12",
   "dunning_amount",
   "grand_total",
@@ -215,7 +215,7 @@
   },
   {
    "default": "0",
-   "fetch_from": "dunning_type.interest_rate",
+   "fetch_from": "dunning_type.rate_of_interest",
    "fetch_if_empty": 1,
    "fieldname": "rate_of_interest",
    "fieldtype": "Float",
@@ -315,7 +315,7 @@
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2020-07-21 18:20:23.512151",
+ "modified": "2020-08-03 18:55:43.683053",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Dunning",
diff --git a/erpnext/accounts/doctype/dunning/dunning.py b/erpnext/accounts/doctype/dunning/dunning.py
index 0be6a48..1a6dbed 100644
--- a/erpnext/accounts/doctype/dunning/dunning.py
+++ b/erpnext/accounts/doctype/dunning/dunning.py
@@ -6,7 +6,7 @@
 import frappe
 import json
 from six import string_types
-from frappe.utils import getdate, get_datetime, rounded, flt
+from frappe.utils import getdate, get_datetime, rounded, flt, cint
 from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import days_in_year
 from erpnext.accounts.general_ledger import make_gl_entries, make_reverse_gl_entries
 from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
@@ -27,11 +27,11 @@
 		amounts = calculate_interest_and_amount(
 			self.posting_date, self.outstanding_amount, self.rate_of_interest, self.dunning_fee, self.overdue_days)
 		if self.interest_amount != amounts.get('interest_amount'):
-			self.interest_amount = amounts.get('interest_amount')
+			self.interest_amount = flt(amounts.get('interest_amount'), self.precision('interest_amount'))
 		if self.dunning_amount != amounts.get('dunning_amount'):
-			self.dunning_amount = amounts.get('dunning_amount')
+			self.dunning_amount = flt(amounts.get('dunning_amount'), self.precision('dunning_amount'))
 		if self.grand_total != amounts.get('grand_total'):
-			self.grand_total = amounts.get('grand_total')
+			self.grand_total = flt(amounts.get('grand_total'), self.precision('grand_total'))
 
 	def on_submit(self):
 		self.make_gl_entries()
@@ -47,10 +47,13 @@
 		gl_entries = []
 		invoice_fields = ["project", "cost_center", "debit_to", "party_account_currency", "conversion_rate", "cost_center"]
 		inv = frappe.db.get_value("Sales Invoice", self.sales_invoice, invoice_fields, as_dict=1)
+
 		accounting_dimensions = get_accounting_dimensions()
 		invoice_fields.extend(accounting_dimensions)
+
 		dunning_in_company_currency = flt(self.dunning_amount * inv.conversion_rate)
 		default_cost_center = frappe.get_cached_value('Company',  self.company,  'cost_center')
+
 		gl_entries.append(
 			self.get_gl_dict({
 				"account": inv.debit_to,
@@ -90,10 +93,10 @@
 
 def calculate_interest_and_amount(posting_date, outstanding_amount, rate_of_interest, dunning_fee, overdue_days):
 	interest_amount = 0
+	grand_total = 0
 	if rate_of_interest:
-		interest_per_year = rounded(flt(outstanding_amount) * flt(rate_of_interest))/100
-		interest_amount = (
-            interest_per_year / days_in_year(get_datetime(posting_date).year)) * int(overdue_days)
+		interest_per_year = flt(outstanding_amount) * flt(rate_of_interest) / 100
+		interest_amount = (interest_per_year * cint(overdue_days)) / 365 
 		grand_total = flt(outstanding_amount) + flt(interest_amount) + flt(dunning_fee)
 	dunning_amount = flt(interest_amount) + flt(dunning_fee)
 	return {
diff --git a/erpnext/accounts/doctype/dunning/dunning_dashboard.py b/erpnext/accounts/doctype/dunning/dunning_dashboard.py
new file mode 100644
index 0000000..19a73dd
--- /dev/null
+++ b/erpnext/accounts/doctype/dunning/dunning_dashboard.py
@@ -0,0 +1,17 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+	return {
+		'fieldname': 'dunning',
+		'non_standard_fieldnames': {
+			'Journal Entry': 'reference_name',
+			'Payment Entry': 'reference_name'
+		},
+		'transactions': [
+			{
+				'label': _('Payment'),
+				'items': ['Payment Entry', 'Journal Entry']
+			}
+		]
+	}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year_dashboard.py b/erpnext/accounts/doctype/fiscal_year/fiscal_year_dashboard.py
index c7604ec..58480df 100644
--- a/erpnext/accounts/doctype/fiscal_year/fiscal_year_dashboard.py
+++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year_dashboard.py
@@ -13,7 +13,7 @@
 			},
 			{
 				'label': _('References'),
-				'items': ['Period Closing Voucher', 'Request for Quotation', 'Tax Withholding Category']
+				'items': ['Period Closing Voucher', 'Tax Withholding Category']
 			},
 			{
 				'label': _('Target Details'),
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index cfdae93..dda1708 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -841,13 +841,33 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_against_jv(doctype, txt, searchfield, start, page_len, filters):
-	return frappe.db.sql("""select jv.name, jv.posting_date, jv.user_remark
-		from `tabJournal Entry` jv, `tabJournal Entry Account` jv_detail
-		where jv_detail.parent = jv.name and jv_detail.account = %s and ifnull(jv_detail.party, '') = %s
-		and (jv_detail.reference_type is null or jv_detail.reference_type = '')
-		and jv.docstatus = 1 and jv.`{0}` like %s order by jv.name desc limit %s, %s""".format(searchfield),
-		(filters.get("account"), cstr(filters.get("party")), "%{0}%".format(txt), start, page_len))
+	if not frappe.db.has_column('Journal Entry', searchfield):
+		return []
+
+	return frappe.db.sql("""
+		SELECT jv.name, jv.posting_date, jv.user_remark
+		FROM `tabJournal Entry` jv, `tabJournal Entry Account` jv_detail
+		WHERE jv_detail.parent = jv.name
+			AND jv_detail.account = %(account)s
+			AND IFNULL(jv_detail.party, '') = %(party)s
+			AND (
+				jv_detail.reference_type IS NULL
+				OR jv_detail.reference_type = ''
+			)
+			AND jv.docstatus = 1
+			AND jv.`{0}` LIKE %(txt)s
+		ORDER BY jv.name DESC
+		LIMIT %(offset)s, %(limit)s
+		""".format(searchfield), dict(
+				account=filters.get("account"),
+				party=cstr(filters.get("party")),
+				txt="%{0}%".format(txt),
+				offset=start,
+				limit=page_len
+			)
+		)
 
 
 @frappe.whitelist()
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index adfaade..9fc44bc 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -42,7 +42,8 @@
 		frm.set_query("bank_account", function() {
 			return {
 				filters: {
-					is_company_account: 1
+					is_company_account: 1,
+					company: frm.doc.company
 				}
 			}
 		});
@@ -1049,4 +1050,4 @@
 			});
 		}
 	},
-})
\ No newline at end of file
+})
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 9df8655..842c64f 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -897,7 +897,7 @@
 		total_amount = ref_doc.get("grand_total")
 		exchange_rate = 1
 		outstanding_amount = ref_doc.get("outstanding_amount")
-	if reference_doctype == "Dunning":
+	elif reference_doctype == "Dunning":
 		total_amount = ref_doc.get("dunning_amount")
 		exchange_rate = 1
 		outstanding_amount = ref_doc.get("dunning_amount")
@@ -1101,7 +1101,7 @@
 					'outstanding_amount': doc.get('dunning_amount'),
 					'allocated_amount': doc.get('dunning_amount')
 				})
-			else:	
+			else:
 				pe.append("references", {
 					'reference_doctype': dt,
 					'reference_name': dn,
diff --git a/erpnext/accounts/doctype/payment_order/payment_order.py b/erpnext/accounts/doctype/payment_order/payment_order.py
index 4702e58..e5880aa 100644
--- a/erpnext/accounts/doctype/payment_order/payment_order.py
+++ b/erpnext/accounts/doctype/payment_order/payment_order.py
@@ -27,6 +27,7 @@
 			frappe.db.set_value(self.payment_order_type, d.get(frappe.scrub(self.payment_order_type)), ref_field, status)
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_mop_query(doctype, txt, searchfield, start, page_len, filters):
 	return frappe.db.sql(""" select mode_of_payment from `tabPayment Order Reference`
 		where parent = %(parent)s and mode_of_payment like %(txt)s
@@ -38,6 +39,7 @@
 		})
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_supplier_query(doctype, txt, searchfield, start, page_len, filters):
 	return frappe.db.sql(""" select supplier from `tabPayment Order Reference`
 		where parent = %(parent)s and supplier like %(txt)s and
diff --git a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py
index 8eb0a22..9899219 100644
--- a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py
+++ b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py
@@ -24,7 +24,7 @@
 		if user:
 			frappe.throw(_("POS Closing Entry {} against {} between selected period"
 				.format(frappe.bold("already exists"), frappe.bold(self.user))), title=_("Invalid Period"))
-		
+
 		if frappe.db.get_value("POS Opening Entry", self.pos_opening_entry, "status") != "Open":
 			frappe.throw(_("Selected POS Opening Entry should be open."), title=_("Invalid Opening Entry"))
 
@@ -41,6 +41,7 @@
 			{"data": self, "currency": currency})
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_cashiers(doctype, txt, searchfield, start, page_len, filters):
 	cashiers_list = frappe.get_all("POS Profile User", filters=filters, fields=['user'])
 	return [c['user'] for c in cashiers_list]
@@ -48,12 +49,12 @@
 @frappe.whitelist()
 def get_pos_invoices(start, end, user):
 	data = frappe.db.sql("""
-	select 
+	select
 		name, timestamp(posting_date, posting_time) as "timestamp"
-	from 
+	from
 		`tabPOS Invoice`
-	where 
-		owner = %s and docstatus = 1 and 
+	where
+		owner = %s and docstatus = 1 and
 		(consolidated_invoice is NULL or consolidated_invoice = '')
 	""", (user), as_dict=1)
 
@@ -101,7 +102,7 @@
 		for t in d.taxes:
 			existing_tax = [tx for tx in taxes if tx.account_head == t.account_head and tx.rate == t.rate]
 			if existing_tax:
-				existing_tax[0].amount += flt(t.tax_amount); 
+				existing_tax[0].amount += flt(t.tax_amount);
 			else:
 				taxes.append(frappe._dict({
 					'account_head': t.account_head,
diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
index 8680b71..ba68df7 100644
--- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
+++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
@@ -21,7 +21,7 @@
 class POSInvoice(SalesInvoice):
 	def __init__(self, *args, **kwargs):
 		super(POSInvoice, self).__init__(*args, **kwargs)
-	
+
 	def validate(self):
 		if not cint(self.is_pos):
 			frappe.throw(_("POS Invoice should have {} field checked.").format(frappe.bold("Include Payment")))
@@ -58,7 +58,7 @@
 		if self.redeem_loyalty_points and self.loyalty_points:
 			self.apply_loyalty_points()
 		self.set_status(update=True)
-	
+
 	def on_cancel(self):
 		# run on cancel method of selling controller
 		super(SalesInvoice, self).on_cancel()
@@ -68,10 +68,10 @@
 			against_psi_doc = frappe.get_doc("POS Invoice", self.return_against)
 			against_psi_doc.delete_loyalty_point_entry()
 			against_psi_doc.make_loyalty_point_entry()
-		
+
 	def validate_stock_availablility(self):
 		allow_negative_stock = frappe.db.get_value('Stock Settings', None, 'allow_negative_stock')
-		
+
 		for d in self.get('items'):
 			if d.serial_no:
 				filters = {
@@ -89,11 +89,11 @@
 				for s in serial_nos:
 					if s in reserved_serial_nos:
 						invalid_serial_nos.append(s)
-				
+
 				if len(invalid_serial_nos):
 					multiple_nos = 's' if len(invalid_serial_nos) > 1 else ''
 					frappe.throw(_("Row #{}: Serial No{}. {} has already been transacted into another POS Invoice. \
-						Please select valid serial no.".format(d.idx, multiple_nos, 
+						Please select valid serial no.".format(d.idx, multiple_nos,
 						frappe.bold(', '.join(invalid_serial_nos)))), title=_("Not Available"))
 			else:
 				if allow_negative_stock:
@@ -105,9 +105,9 @@
 						.format(d.idx, frappe.bold(d.item_code), frappe.bold(d.warehouse))), title=_("Not Available"))
 				elif flt(available_stock) < flt(d.qty):
 					frappe.msgprint(_('Row #{}: Stock quantity not enough for Item Code: {} under warehouse {}. \
-						Available quantity {}.'.format(d.idx, frappe.bold(d.item_code), 
+						Available quantity {}.'.format(d.idx, frappe.bold(d.item_code),
 						frappe.bold(d.warehouse), frappe.bold(d.qty))), title=_("Not Available"))
-	
+
 	def validate_serialised_or_batched_item(self):
 		for d in self.get("items"):
 			serialized = d.get("has_serial_no")
@@ -125,7 +125,7 @@
 			if batched and no_batch_selected:
 				frappe.throw(_('Row #{}: No batch selected against item: {}. Please select a batch or remove it to complete transaction.'
 						.format(d.idx, frappe.bold(d.item_code))), title=_("Invalid Item"))
-	
+
 	def validate_return_items(self):
 		if not self.get("is_return"): return
 
@@ -158,7 +158,7 @@
 				frappe.throw(_("Row #{0} (Payment Table): Amount must be positive").format(entry.idx))
 			if self.is_return and entry.amount > 0:
 				frappe.throw(_("Row #{0} (Payment Table): Amount must be negative").format(entry.idx))
-	
+
 	def validate_pos_return(self):
 		if self.is_pos and self.is_return:
 			total_amount_in_payments = 0
@@ -167,12 +167,12 @@
 			invoice_total = self.rounded_total or self.grand_total
 			if total_amount_in_payments < invoice_total:
 				frappe.throw(_("Total payments amount can't be greater than {}".format(-invoice_total)))
-	
+
 	def validate_loyalty_transaction(self):
 		if self.redeem_loyalty_points and (not self.loyalty_redemption_account or not self.loyalty_redemption_cost_center):
 			expense_account, cost_center = frappe.db.get_value('Loyalty Program', self.loyalty_program, ["expense_account", "cost_center"])
 			if not self.loyalty_redemption_account:
-				self.loyalty_redemption_account = expense_account 
+				self.loyalty_redemption_account = expense_account
 			if not self.loyalty_redemption_cost_center:
 				self.loyalty_redemption_cost_center = cost_center
 
@@ -212,7 +212,7 @@
 
 		if update:
 			self.db_set('status', self.status, update_modified = update_modified)
-	
+
 	def set_pos_fields(self, for_validate=False):
 		"""Set retail related fields from POS Profiles"""
 		from erpnext.stock.get_item_details import get_pos_profile_item_details, get_pos_profile
@@ -315,25 +315,25 @@
 
 @frappe.whitelist()
 def get_stock_availability(item_code, warehouse):
-	latest_sle = frappe.db.sql("""select qty_after_transaction 
-		from `tabStock Ledger Entry` 
+	latest_sle = frappe.db.sql("""select qty_after_transaction
+		from `tabStock Ledger Entry`
 		where item_code = %s and warehouse = %s
 		order by posting_date desc, posting_time desc
 		limit 1""", (item_code, warehouse), as_dict=1)
-	
+
 	pos_sales_qty = frappe.db.sql("""select sum(p_item.qty) as qty
 		from `tabPOS Invoice` p, `tabPOS Invoice Item` p_item
-		where p.name = p_item.parent 
-		and p.consolidated_invoice is NULL 
+		where p.name = p_item.parent
+		and p.consolidated_invoice is NULL
 		and p.docstatus = 1
 		and p_item.docstatus = 1
 		and p_item.item_code = %s
 		and p_item.warehouse = %s
 		""", (item_code, warehouse), as_dict=1)
-	
+
 	sle_qty = latest_sle[0].qty_after_transaction or 0 if latest_sle else 0
 	pos_sales_qty = pos_sales_qty[0].qty or 0 if pos_sales_qty else 0
-	
+
 	if sle_qty and pos_sales_qty and sle_qty > pos_sales_qty:
 		return sle_qty - pos_sales_qty
 	else:
@@ -360,14 +360,14 @@
 	merge_log = frappe.new_doc("POS Invoice Merge Log")
 	merge_log.posting_date = getdate(nowdate())
 	for inv in invoices:
-		inv_data = frappe.db.get_values("POS Invoice", inv.get('name'), 
+		inv_data = frappe.db.get_values("POS Invoice", inv.get('name'),
 			["customer", "posting_date", "grand_total"], as_dict=1)[0]
 		merge_log.customer = inv_data.customer
 		merge_log.append("pos_invoices", {
 			'pos_invoice': inv.get('name'),
 			'customer': inv_data.customer,
 			'posting_date': inv_data.posting_date,
-			'grand_total': inv_data.grand_total 
+			'grand_total': inv_data.grand_total
 		})
 
 	if merge_log.get('pos_invoices'):
diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.js b/erpnext/accounts/doctype/pos_profile/pos_profile.js
index ef431d7..8ec6a53 100755
--- a/erpnext/accounts/doctype/pos_profile/pos_profile.js
+++ b/erpnext/accounts/doctype/pos_profile/pos_profile.js
@@ -31,8 +31,7 @@
 		frm.set_query("print_format", function() {
 			return {
 				filters: [
-					['Print Format', 'doc_type', '=', 'Sales Invoice'],
-					['Print Format', 'print_format_type', '=', 'Jinja'],
+					['Print Format', 'doc_type', '=', 'POS Invoice']
 				]
 			};
 		});
@@ -45,10 +44,6 @@
 			};
 		});
 
-		frm.set_query("print_format", function() {
-			return { filters: { doc_type: "Sales Invoice", print_format_type: "JS"} };
-		});
-
 		frm.set_query('company_address', function(doc) {
 			if(!doc.company) {
 				frappe.throw(__('Please set Company'));
diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.json b/erpnext/accounts/doctype/pos_profile/pos_profile.json
index 454c598..d4c1791 100644
--- a/erpnext/accounts/doctype/pos_profile/pos_profile.json
+++ b/erpnext/accounts/doctype/pos_profile/pos_profile.json
@@ -302,10 +302,10 @@
    "fieldname": "warehouse",
    "fieldtype": "Link",
    "label": "Warehouse",
+   "mandatory_depends_on": "update_stock",
    "oldfieldname": "warehouse",
    "oldfieldtype": "Link",
-   "options": "Warehouse",
-   "reqd": 1
+   "options": "Warehouse"
   },
   {
    "default": "0",
@@ -350,4 +350,4 @@
  ],
  "sort_field": "modified",
  "sort_order": "DESC"
-}
\ No newline at end of file
+}
diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.py b/erpnext/accounts/doctype/pos_profile/pos_profile.py
index 8655b4b..789b4c3 100644
--- a/erpnext/accounts/doctype/pos_profile/pos_profile.py
+++ b/erpnext/accounts/doctype/pos_profile/pos_profile.py
@@ -105,6 +105,7 @@
 	return frappe.get_meta("POS Invoice").get_field("naming_series").options or "s"
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def pos_profile_query(doctype, txt, searchfield, start, page_len, filters):
 	user = frappe.session['user']
 	company = filters.get('company') or frappe.defaults.get_user_default('company')
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index d90ae28..cff7d5b 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -433,14 +433,14 @@
 	return doc
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_item_uoms(doctype, txt, searchfield, start, page_len, filters):
 	items = [filters.get('value')]
 	if filters.get('apply_on') != 'Item Code':
 		field = frappe.scrub(filters.get('apply_on'))
+		items = [d.name for d in frappe.db.get_all("Item", filters={field: filters.get('value')})]
 
-		items = frappe.db.sql_list("""select name
-			from `tabItem` where {0} = %s""".format(field), filters.get('value'))
-
-	return frappe.get_all('UOM Conversion Detail',
-		filters = {'parent': ('in', items), 'uom': ("like", "{0}%".format(txt))},
-		fields = ["distinct uom"], as_list=1)
+	return frappe.get_all('UOM Conversion Detail', filters={
+			'parent': ('in', items),
+			'uom': ("like", "{0}%".format(txt))
+		}, fields = ["distinct uom"], as_list=1)
diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/__init__.py b/erpnext/accounts/doctype/process_statement_of_accounts/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/process_statement_of_accounts/__init__.py
diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html
new file mode 100644
index 0000000..e1ddeff
--- /dev/null
+++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html
@@ -0,0 +1,89 @@
+<h1 class="text-center" style="page-break-before:always">{{ filters.party[0] }}</h1>
+<h3 class="text-center">{{ _("Statement of Accounts") }}</h3>
+
+<h5 class="text-center">
+    {{ frappe.format(filters.from_date, 'Date')}}
+	{{ _("to") }}
+	{{ frappe.format(filters.to_date, 'Date')}}
+</h5>
+
+<table class="table table-bordered">
+	<thead>
+		<tr>
+			<th style="width: 12%">{{ _("Date") }}</th>
+			<th style="width: 15%">{{ _("Ref") }}</th>
+			<th style="width: 25%">{{ _("Party") }}</th>
+			<th style="width: 15%">{{ _("Debit") }}</th>
+			<th style="width: 15%">{{ _("Credit") }}</th>
+			<th style="width: 18%">{{ _("Balance (Dr - Cr)") }}</th>
+		</tr>
+	</thead>
+	<tbody>
+        {% for row in data %}
+			<tr>
+			{% if(row.posting_date) %}
+				<td>{{ frappe.format(row.posting_date, 'Date') }}</td>
+				<td>{{ row.voucher_type }}
+					<br>{{ row.voucher_no }}</td>
+				<td>
+					{% if not (filters.party or filters.account)  %}
+						{{ row.party or row.account }}
+						<br>
+					{% endif %}
+
+					{{ _("Against") }}: {{ row.against }}
+					<br>{{ _("Remarks") }}: {{ row.remarks }}
+					{% if row.bill_no %}
+						<br>{{ _("Supplier Invoice No") }}: {{ row.bill_no }}
+					{% endif %}
+					</td>
+					<td style="text-align: right">
+						{{ frappe.utils.fmt_money(row.debit, filters.presentation_currency) }}</td>
+					<td style="text-align: right">
+						{{ frappe.utils.fmt_money(row.credit, filters.presentation_currency) }}</td>
+			{% else %}
+				<td></td>
+				<td></td>
+				<td><b>{{ frappe.format(row.account, {fieldtype: "Link"}) or "&nbsp;" }}</b></td>
+				<td style="text-align: right">
+					{{ row.account and frappe.utils.fmt_money(row.debit, filters.presentation_currency) }}
+				</td>
+				<td style="text-align: right">
+					{{ row.account and frappe.utils.fmt_money(row.credit, filters.presentation_currency) }}
+				</td>
+			{% endif %}
+				<td style="text-align: right">
+					{{ frappe.utils.fmt_money(row.balance, filters.presentation_currency) }}
+				</td>
+			</tr>
+		{% endfor %}
+		</tbody>
+</table>
+<br><br>
+{% if aging %}
+<h3 class="text-center">{{ _("Ageing Report Based On ") }} {{ aging.ageing_based_on }}</h3>
+<h5 class="text-center">
+	{{ _("Up to " ) }}  {{ frappe.format(filters.to_date, 'Date')}}
+</h5>
+<br>
+
+<table class="table table-bordered">
+	<thead>
+		<tr>
+			<th style="width: 12%">30 Days</th>
+			<th style="width: 15%">60 Days</th>
+			<th style="width: 25%">90 Days</th>
+			<th style="width: 15%">120 Days</th>
+		</tr>
+	</thead>
+	<tbody>
+		<tr>
+			<td>{{ aging.range1 }}</td>
+			<td>{{ aging.range2 }}</td>
+			<td>{{ aging.range3 }}</td>
+			<td>{{ aging.range4 }}</td>
+		</tr>
+	</tbody>
+</table>
+{% endif %}
+<p class="text-right text-muted">Printed On {{ frappe.format(frappe.utils.get_datetime(), 'Datetime') }}</p>
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js
new file mode 100644
index 0000000..7425132
--- /dev/null
+++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js
@@ -0,0 +1,132 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Process Statement Of Accounts', {
+	view_properties: function(frm) {
+		frappe.route_options = {doc_type: 'Customer'};
+		frappe.set_route("Form", "Customize Form");
+	},
+	refresh: function(frm){
+		if(!frm.doc.__islocal) {
+			frm.add_custom_button('Send Emails',function(){
+				frappe.call({
+					method: "erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.send_emails",
+					args: {
+						"document_name": frm.doc.name,
+					},
+					callback: function(r) {
+						if(r && r.message) {
+							frappe.show_alert({message: __('Emails Queued'), indicator: 'blue'});
+						}
+						else{
+							frappe.msgprint('No Records for these settings.')
+						}
+					}
+				});
+			});
+			frm.add_custom_button('Download',function(){
+				var url = frappe.urllib.get_full_url(
+					'/api/method/erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.download_statements?'
+					+ 'document_name='+encodeURIComponent(frm.doc.name))
+				$.ajax({
+					url: url,
+					type: 'GET',
+					success: function(result) {
+						if(jQuery.isEmptyObject(result)){
+							frappe.msgprint('No Records for these settings.');
+						}
+						else{
+							window.location = url;
+						}
+					}
+				});
+			});
+		}
+	},
+	onload: function(frm) {
+		frm.set_query('currency', function(){
+			return {
+				filters: {
+					'enabled': 1
+				}
+			}
+		});
+		if(frm.doc.__islocal){
+			frm.set_value('from_date', frappe.datetime.add_months(frappe.datetime.get_today(), -1));
+			frm.set_value('to_date', frappe.datetime.get_today());
+		}
+	},
+	customer_collection: function(frm){
+		frm.set_value('collection_name', '');
+		if(frm.doc.customer_collection){
+			frm.get_field('collection_name').set_label(frm.doc.customer_collection);
+		}
+	},
+	frequency: function(frm){
+		if(frm.doc.frequency != ''){
+			frm.set_value('start_date', frappe.datetime.get_today());
+		}
+		else{
+			frm.set_value('start_date', '');
+		}
+	},
+	fetch_customers: function(frm){
+		if(frm.doc.collection_name){
+			frappe.call({
+				method: "erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.fetch_customers",
+				args: {
+					'customer_collection': frm.doc.customer_collection,
+					'collection_name': frm.doc.collection_name,
+					'primary_mandatory': frm.doc.primary_mandatory
+				},
+				callback: function(r) {
+					if(!r.exc) {
+						if(r.message.length){
+							frm.clear_table('customers');
+							for (const customer of r.message){
+								var row = frm.add_child('customers');
+								row.customer = customer.name;
+								row.primary_email = customer.primary_email;
+								row.billing_email = customer.billing_email;
+							}
+							frm.refresh_field('customers');
+						}
+						else{
+							frappe.msgprint('No Customers found with selected options.');
+						}
+					}
+				}
+			});
+		}
+		else {
+			frappe.throw('Enter ' + frm.doc.customer_collection + ' name.');
+		}
+	}
+});
+
+frappe.ui.form.on('Process Statement Of Accounts Customer', {
+	customer: function(frm, cdt, cdn){
+		var row = locals[cdt][cdn];
+		if (!row.customer){
+			return;
+		}
+		frappe.call({
+			method: 'erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.get_customer_emails',
+			args: {
+				'customer_name': row.customer,
+				'primary_mandatory': frm.doc.primary_mandatory
+			},
+			callback: function(r){
+				if(!r.exe){
+					if(r.message.length){
+						frappe.model.set_value(cdt, cdn, "primary_email", r.message[0])
+						frappe.model.set_value(cdt, cdn, "billing_email", r.message[1])
+					}
+					else {
+						return
+					}
+				}
+			}
+		})
+	}
+});
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json
new file mode 100644
index 0000000..4be0e2e
--- /dev/null
+++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json
@@ -0,0 +1,310 @@
+{
+ "actions": [],
+ "allow_workflow": 1,
+ "autoname": "Prompt",
+ "creation": "2020-05-22 16:46:18.712954",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "section_break_11",
+  "from_date",
+  "company",
+  "account",
+  "group_by",
+  "cost_center",
+  "column_break_14",
+  "to_date",
+  "finance_book",
+  "currency",
+  "project",
+  "section_break_3",
+  "customer_collection",
+  "collection_name",
+  "fetch_customers",
+  "column_break_6",
+  "primary_mandatory",
+  "column_break_17",
+  "customers",
+  "preferences",
+  "orientation",
+  "section_break_14",
+  "include_ageing",
+  "ageing_based_on",
+  "section_break_1",
+  "enable_auto_email",
+  "section_break_18",
+  "frequency",
+  "filter_duration",
+  "column_break_21",
+  "start_date",
+  "section_break_33",
+  "subject",
+  "column_break_28",
+  "cc_to",
+  "section_break_30",
+  "body",
+  "help_text"
+ ],
+ "fields": [
+  {
+   "fieldname": "frequency",
+   "fieldtype": "Select",
+   "label": "Frequency",
+   "options": "Weekly\nMonthly\nQuarterly"
+  },
+  {
+   "fieldname": "company",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Company",
+   "options": "Company",
+   "reqd": 1
+  },
+  {
+   "depends_on": "eval:doc.enable_auto_email == 0;",
+   "fieldname": "from_date",
+   "fieldtype": "Date",
+   "label": "From Date",
+   "mandatory_depends_on": "eval:doc.frequency == '';"
+  },
+  {
+   "depends_on": "eval:doc.enable_auto_email == 0;",
+   "fieldname": "to_date",
+   "fieldtype": "Date",
+   "label": "To Date",
+   "mandatory_depends_on": "eval:doc.frequency == '';"
+  },
+  {
+   "fieldname": "cost_center",
+   "fieldtype": "Table MultiSelect",
+   "label": "Cost Center",
+   "options": "PSOA Cost Center"
+  },
+  {
+   "fieldname": "project",
+   "fieldtype": "Table MultiSelect",
+   "label": "Project",
+   "options": "PSOA Project"
+  },
+  {
+   "fieldname": "section_break_3",
+   "fieldtype": "Section Break",
+   "label": "Customers"
+  },
+  {
+   "fieldname": "column_break_6",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "section_break_11",
+   "fieldtype": "Section Break",
+   "label": "General Ledger Filters"
+  },
+  {
+   "fieldname": "column_break_14",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "column_break_17",
+   "fieldtype": "Section Break",
+   "hide_border": 1
+  },
+  {
+   "fieldname": "customer_collection",
+   "fieldtype": "Select",
+   "label": "Select Customers By",
+   "options": "\nCustomer Group\nTerritory\nSales Partner\nSales Person"
+  },
+  {
+   "depends_on": "eval: doc.customer_collection !== ''",
+   "fieldname": "collection_name",
+   "fieldtype": "Dynamic Link",
+   "label": "Recipient",
+   "options": "customer_collection"
+  },
+  {
+   "fieldname": "section_break_1",
+   "fieldtype": "Section Break",
+   "label": "Email Settings"
+  },
+  {
+   "fieldname": "account",
+   "fieldtype": "Link",
+   "label": "Account",
+   "options": "Account"
+  },
+  {
+   "fieldname": "finance_book",
+   "fieldtype": "Link",
+   "label": "Finance Book",
+   "options": "Finance Book"
+  },
+  {
+   "fieldname": "preferences",
+   "fieldtype": "Section Break",
+   "label": "Print Preferences"
+  },
+  {
+   "fieldname": "orientation",
+   "fieldtype": "Select",
+   "label": "Orientation",
+   "options": "Landscape\nPortrait"
+  },
+  {
+   "default": "Today",
+   "fieldname": "start_date",
+   "fieldtype": "Date",
+   "label": "Start Date"
+  },
+  {
+   "default": "Group by Voucher (Consolidated)",
+   "fieldname": "group_by",
+   "fieldtype": "Select",
+   "label": "Group By",
+   "options": "\nGroup by Voucher\nGroup by Voucher (Consolidated)"
+  },
+  {
+   "fieldname": "currency",
+   "fieldtype": "Link",
+   "label": "Currency",
+   "options": "Currency"
+  },
+  {
+   "default": "0",
+   "fieldname": "include_ageing",
+   "fieldtype": "Check",
+   "in_list_view": 1,
+   "label": "Include Ageing Summary"
+  },
+  {
+   "default": "Due Date",
+   "depends_on": "eval:doc.include_ageing === 1",
+   "fieldname": "ageing_based_on",
+   "fieldtype": "Select",
+   "label": "Ageing Based On",
+   "options": "Due Date\nPosting Date"
+  },
+  {
+   "default": "0",
+   "fieldname": "enable_auto_email",
+   "fieldtype": "Check",
+   "in_list_view": 1,
+   "label": "Enable Auto Email"
+  },
+  {
+   "fieldname": "section_break_14",
+   "fieldtype": "Column Break",
+   "hide_border": 1
+  },
+  {
+   "depends_on": "eval: doc.enable_auto_email ==1",
+   "fieldname": "section_break_18",
+   "fieldtype": "Section Break",
+   "hide_border": 1
+  },
+  {
+   "fieldname": "column_break_21",
+   "fieldtype": "Column Break"
+  },
+  {
+   "depends_on": "eval: doc.customer_collection !== ''",
+   "fieldname": "fetch_customers",
+   "fieldtype": "Button",
+   "label": "Fetch Customers",
+   "options": "fetch_customers",
+   "print_hide": 1,
+   "report_hide": 1
+  },
+  {
+   "default": "1",
+   "fieldname": "primary_mandatory",
+   "fieldtype": "Check",
+   "label": "Send To Primary Contact"
+  },
+  {
+   "fieldname": "cc_to",
+   "fieldtype": "Link",
+   "label": "CC To",
+   "options": "User"
+  },
+  {
+   "default": "1",
+   "fieldname": "filter_duration",
+   "fieldtype": "Int",
+   "label": "Filter Duration (Months)"
+  },
+  {
+   "fieldname": "customers",
+   "fieldtype": "Table",
+   "label": "Customers",
+   "options": "Process Statement Of Accounts Customer",
+   "reqd": 1
+  },
+  {
+   "fieldname": "column_break_28",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "section_break_30",
+   "fieldtype": "Section Break",
+   "hide_border": 1
+  },
+  {
+   "fieldname": "section_break_33",
+   "fieldtype": "Section Break",
+   "hide_border": 1
+  },
+  {
+   "fieldname": "help_text",
+   "fieldtype": "HTML",
+   "label": "Help Text",
+   "options": "<br>\n<h4>Note</h4>\n<ul>\n<li>\nYou can use <a href=\"https://jinja.palletsprojects.com/en/2.11.x/\" target=\"_blank\">Jinja tags</a> in <b>Subject</b> and <b>Body</b> fields for dynamic values.\n</li><li>\n    All fields in this doctype are available under the <b>doc</b> object and all fields for the customer to whom the mail will go to is available under the  <b>customer</b> object.\n</li></ul>\n<h4> Examples</h4>\n<!-- {% raw %} -->\n<ul>\n    <li><b>Subject</b>:<br><br><pre><code>Statement Of Accounts for {{ customer.name }}</code></pre><br></li>\n    <li><b>Body</b>: <br><br>\n<pre><code>Hello {{ customer.name }},<br>PFA your Statement Of Accounts from {{ doc.from_date }} to {{ doc.to_date }}.</code> </pre></li>\n</ul>\n<!-- {% endraw %} -->"
+  },
+  {
+   "fieldname": "subject",
+   "fieldtype": "Data",
+   "label": "Subject"
+  },
+  {
+   "fieldname": "body",
+   "fieldtype": "Text Editor",
+   "label": "Body"
+  }
+ ],
+ "links": [],
+ "modified": "2020-08-08 08:47:09.185728",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Process Statement Of Accounts",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Accounts User",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Accounts Manager",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py
new file mode 100644
index 0000000..d50e4a8
--- /dev/null
+++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py
@@ -0,0 +1,271 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, 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
+from erpnext.accounts.report.general_ledger.general_ledger import execute as get_soa
+from erpnext.accounts.report.accounts_receivable_summary.accounts_receivable_summary import execute as get_ageing
+from frappe.core.doctype.communication.email import make
+
+from frappe.utils.print_format import report_to_pdf
+from frappe.utils.pdf import get_pdf
+from frappe.utils import today, add_days, add_months, getdate, format_date
+from frappe.utils.jinja import validate_template
+
+import copy
+from datetime import timedelta
+from frappe.www.printview import get_print_style
+
+class ProcessStatementOfAccounts(Document):
+	def validate(self):
+		if not self.subject:
+			self.subject = 'Statement Of Accounts for {{ customer.name }}'
+		if not self.body:
+			self.body = 'Hello {{ customer.name }},<br>PFA your Statement Of Accounts from {{ doc.from_date }} to {{ doc.to_date }}.'
+
+		validate_template(self.subject)
+		validate_template(self.body)
+
+		if not self.customers:
+			frappe.throw(frappe._('Customers not selected.'))
+
+		if self.enable_auto_email:
+			self.to_date = self.start_date
+			self.from_date = add_months(self.to_date, -1 * self.filter_duration)
+
+
+def get_report_pdf(doc, consolidated=True):
+	statement_dict = {}
+	aging = ''
+	base_template_path = "frappe/www/printview.html"
+	template_path = "erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html"
+
+	for entry in doc.customers:
+		if doc.include_ageing:
+			ageing_filters = frappe._dict({
+				'company': doc.company,
+				'report_date': doc.to_date,
+				'ageing_based_on': doc.ageing_based_on,
+				'range1': 30,
+				'range2': 60,
+				'range3': 90,
+				'range4': 120,
+				'customer': entry.customer
+			})
+			col1, aging = get_ageing(ageing_filters)
+			aging[0]['ageing_based_on'] = doc.ageing_based_on
+
+		tax_id = frappe.get_doc('Customer', entry.customer).tax_id
+
+		filters= frappe._dict({
+			'from_date': doc.from_date,
+			'to_date': doc.to_date,
+			'company': doc.company,
+			'finance_book': doc.finance_book if doc.finance_book else None,
+			"account": doc.account if doc.account else None,
+			'party_type': 'Customer',
+			'party': [entry.customer],
+			'group_by': doc.group_by,
+			'currency': doc.currency,
+			'cost_center': [cc.cost_center_name for cc in doc.cost_center],
+			'project': [p.project_name for p in doc.project],
+			'show_opening_entries': 0,
+			'include_default_book_entries': 0,
+			'show_cancelled_entries': 1,
+			'tax_id': tax_id if tax_id else None
+		})
+		col, res = get_soa(filters)
+
+		for x in [0, -2, -1]:
+			res[x]['account'] = res[x]['account'].replace("'","")
+
+		if len(res) == 3:
+			continue
+		html = frappe.render_template(template_path, \
+			{"filters": filters, "data": res, "aging": aging[0] if doc.include_ageing else None})
+		html = frappe.render_template(base_template_path, {"body": html, \
+			"css": get_print_style(), "title": "Statement For " + entry.customer})
+		statement_dict[entry.customer] = html
+	if not bool(statement_dict):
+		return False
+	elif consolidated:
+		result = ''.join(list(statement_dict.values()))
+		return get_pdf(result, {'orientation': doc.orientation})
+	else:
+		for customer, statement_html in statement_dict.items():
+			statement_dict[customer]=get_pdf(statement_html, {'orientation': doc.orientation})
+		return statement_dict
+
+def get_customers_based_on_territory_or_customer_group(customer_collection, collection_name):
+	fields_dict = {
+		'Customer Group': 'customer_group',
+		'Territory': 'territory',
+	}
+	collection = frappe.get_doc(customer_collection, collection_name)
+	selected = [customer.name for customer in frappe.get_list(customer_collection, filters=[
+			['lft', '>=', collection.lft],
+			['rgt', '<=', collection.rgt]
+		],
+		fields=['name'],
+		order_by='lft asc, rgt desc'
+	)]
+	return frappe.get_list('Customer', fields=['name', 'email_id'], \
+		filters=[[fields_dict[customer_collection], 'IN', selected]])
+
+def get_customers_based_on_sales_person(sales_person):
+	lft, rgt = frappe.db.get_value("Sales Person",
+		sales_person, ["lft", "rgt"])
+	records = frappe.db.sql("""
+		select distinct parent, parenttype
+		from `tabSales Team` steam
+		where parenttype = 'Customer'
+			and exists(select name from `tabSales Person` where lft >= %s and rgt <= %s and name = steam.sales_person)
+	""", (lft, rgt), as_dict=1)
+	sales_person_records = frappe._dict()
+	for d in records:
+		sales_person_records.setdefault(d.parenttype, set()).add(d.parent)
+	customers = frappe.get_list('Customer', fields=['name', 'email_id'], \
+			filters=[['name', 'in', list(sales_person_records['Customer'])]])
+	return customers
+
+def get_recipients_and_cc(customer, doc):
+	recipients = []
+	for clist in doc.customers:
+		if clist.customer == customer:
+			recipients.append(clist.billing_email)
+			if doc.primary_mandatory and clist.primary_email:
+				recipients.append(clist.primary_email)
+	cc = []
+	if doc.cc_to != '':
+		try:
+			cc=[frappe.get_value('User', doc.cc_to, 'email')]
+		except:
+			pass
+
+	return recipients, cc
+
+def get_context(customer, doc):
+	template_doc = copy.deepcopy(doc)
+	del template_doc.customers
+	template_doc.from_date = format_date(template_doc.from_date)
+	template_doc.to_date = format_date(template_doc.to_date)
+	return {
+		'doc': template_doc,
+		'customer': frappe.get_doc('Customer', customer),
+		'frappe': frappe.utils
+	}
+
+@frappe.whitelist()
+def fetch_customers(customer_collection, collection_name, primary_mandatory):
+	customer_list = []
+	customers = []
+
+	if customer_collection == 'Sales Person':
+		customers = get_customers_based_on_sales_person(collection_name)
+		if not bool(customers):
+			frappe.throw('No Customers found with selected options.')
+	else:
+		if customer_collection == 'Sales Partner':
+			customers = frappe.get_list('Customer', fields=['name', 'email_id'], \
+				filters=[['default_sales_partner', '=', collection_name]])
+		else:
+			customers = get_customers_based_on_territory_or_customer_group(customer_collection, collection_name)
+
+	for customer in customers:
+		primary_email = customer.get('email_id') or ''
+		billing_email = get_customer_emails(customer.name, 1, billing_and_primary=False)
+
+		if billing_email == '' or (primary_email == '' and int(primary_mandatory)):
+			continue
+
+		customer_list.append({
+			'name': customer.name,
+			'primary_email': primary_email,
+			'billing_email': billing_email
+		})
+	return customer_list
+
+@frappe.whitelist()
+def get_customer_emails(customer_name, primary_mandatory, billing_and_primary=True):
+	billing_email = frappe.db.sql("""
+		SELECT c.email_id FROM `tabContact` AS c JOIN `tabDynamic Link` AS l ON c.name=l.parent \
+		WHERE l.link_doctype='Customer' and l.link_name='""" + customer_name + """' and \
+		c.is_billing_contact=1 \
+		order by c.creation desc""")
+
+	if len(billing_email) == 0 or (billing_email[0][0] is None):
+		if billing_and_primary:
+			frappe.throw('No billing email found for customer: '+ customer_name)
+		else:
+			return ''
+
+	if billing_and_primary:
+		primary_email =  frappe.get_value('Customer', customer_name, 'email_id')
+		if primary_email is None and int(primary_mandatory):
+			frappe.throw('No primary email found for customer: '+ customer_name)
+		return [primary_email or '', billing_email[0][0]]
+	else:
+		return billing_email[0][0] or ''
+
+@frappe.whitelist()
+def download_statements(document_name):
+	doc = frappe.get_doc('Process Statement Of Accounts', document_name)
+	report = get_report_pdf(doc)
+	if report:
+		frappe.local.response.filename = doc.name + '.pdf'
+		frappe.local.response.filecontent = report
+		frappe.local.response.type = "download"
+
+@frappe.whitelist()
+def send_emails(document_name, from_scheduler=False):
+	doc = frappe.get_doc('Process Statement Of Accounts', document_name)
+	report = get_report_pdf(doc, consolidated=False)
+
+	if report:
+		for customer, report_pdf in report.items():
+			attachments = [{
+				'fname': customer + '.pdf',
+				'fcontent': report_pdf
+			}]
+
+			recipients, cc = get_recipients_and_cc(customer, doc)
+			context = get_context(customer, doc)
+			subject = frappe.render_template(doc.subject, context)
+			message = frappe.render_template(doc.body, context)
+
+			frappe.enqueue(
+				queue='short',
+				method=frappe.sendmail,
+				recipients=recipients,
+				sender=frappe.session.user,
+				cc=cc,
+				subject=subject,
+				message=message,
+				now=True,
+				reference_doctype='Process Statement Of Accounts',
+				reference_name=document_name,
+				attachments=attachments
+			)
+
+		if doc.enable_auto_email and from_scheduler:
+			new_to_date = getdate(today())
+			if doc.frequency == 'Weekly':
+				new_to_date = add_days(new_to_date, 7)
+			else:
+				new_to_date = add_months(new_to_date, 1 if doc.frequency == 'Monthly' else 3)
+			new_from_date = add_months(new_to_date, -1 * doc.filter_duration)
+			doc.add_comment('Comment', 'Emails sent on: ' + frappe.utils.format_datetime(frappe.utils.now()))
+			doc.db_set('to_date', new_to_date, commit=True)
+			doc.db_set('from_date', new_from_date, commit=True)
+		return True
+	else:
+		return False
+
+@frappe.whitelist()
+def send_auto_email():
+	selected = frappe.get_list('Process Statement Of Accounts', filters={'to_date': format_date(today()), 'enable_auto_email': 1})
+	for entry in selected:
+		send_emails(entry.name, from_scheduler=True)
+	return True
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py b/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py
new file mode 100644
index 0000000..30efbb3
--- /dev/null
+++ b/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestProcessStatementOfAccounts(unittest.TestCase):
+	pass
diff --git a/erpnext/accounts/doctype/process_statement_of_accounts_customer/__init__.py b/erpnext/accounts/doctype/process_statement_of_accounts_customer/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/process_statement_of_accounts_customer/__init__.py
diff --git a/erpnext/accounts/doctype/process_statement_of_accounts_customer/process_statement_of_accounts_customer.json b/erpnext/accounts/doctype/process_statement_of_accounts_customer/process_statement_of_accounts_customer.json
new file mode 100644
index 0000000..dd04dc1
--- /dev/null
+++ b/erpnext/accounts/doctype/process_statement_of_accounts_customer/process_statement_of_accounts_customer.json
@@ -0,0 +1,47 @@
+{
+ "actions": [],
+ "allow_workflow": 1,
+ "creation": "2020-08-03 16:35:21.852178",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "customer",
+  "billing_email",
+  "primary_email"
+ ],
+ "fields": [
+  {
+   "fieldname": "customer",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Customer",
+   "options": "Customer",
+   "reqd": 1
+  },
+  {
+   "fieldname": "primary_email",
+   "fieldtype": "Read Only",
+   "in_list_view": 1,
+   "label": "Primary Contact Email"
+  },
+  {
+   "fieldname": "billing_email",
+   "fieldtype": "Read Only",
+   "in_list_view": 1,
+   "label": "Billing Email"
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-08-03 22:55:38.875601",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Process Statement Of Accounts Customer",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/process_statement_of_accounts_customer/process_statement_of_accounts_customer.py b/erpnext/accounts/doctype/process_statement_of_accounts_customer/process_statement_of_accounts_customer.py
new file mode 100644
index 0000000..1a76010
--- /dev/null
+++ b/erpnext/accounts/doctype/process_statement_of_accounts_customer/process_statement_of_accounts_customer.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, 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 ProcessStatementOfAccountsCustomer(Document):
+	pass
diff --git a/erpnext/accounts/doctype/psoa_cost_center/__init__.py b/erpnext/accounts/doctype/psoa_cost_center/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/psoa_cost_center/__init__.py
diff --git a/erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.json b/erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.json
new file mode 100644
index 0000000..e292b60
--- /dev/null
+++ b/erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.json
@@ -0,0 +1,30 @@
+{
+ "actions": [],
+ "creation": "2020-08-03 16:56:45.744905",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "cost_center_name"
+ ],
+ "fields": [
+  {
+   "fieldname": "cost_center_name",
+   "fieldtype": "Link",
+   "label": "Cost Center",
+   "options": "Cost Center"
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-08-03 16:56:45.744905",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "PSOA Cost Center",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.py b/erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.py
new file mode 100644
index 0000000..0aeef3e
--- /dev/null
+++ b/erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, 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 PSOACostCenter(Document):
+	pass
diff --git a/erpnext/accounts/doctype/psoa_project/__init__.py b/erpnext/accounts/doctype/psoa_project/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/psoa_project/__init__.py
diff --git a/erpnext/accounts/doctype/psoa_project/psoa_project.json b/erpnext/accounts/doctype/psoa_project/psoa_project.json
new file mode 100644
index 0000000..20a03ee
--- /dev/null
+++ b/erpnext/accounts/doctype/psoa_project/psoa_project.json
@@ -0,0 +1,30 @@
+{
+ "actions": [],
+ "creation": "2020-08-03 16:52:14.731978",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "project_name"
+ ],
+ "fields": [
+  {
+   "fieldname": "project_name",
+   "fieldtype": "Link",
+   "label": "Project",
+   "options": "Project"
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-08-03 16:53:39.219736",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "PSOA Project",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/psoa_project/psoa_project.py b/erpnext/accounts/doctype/psoa_project/psoa_project.py
new file mode 100644
index 0000000..f4a5dee
--- /dev/null
+++ b/erpnext/accounts/doctype/psoa_project/psoa_project.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, 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 PSOAProject(Document):
+	pass
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index df77dc8..d62e73b 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -180,7 +180,7 @@
    "no_copy": 1,
    "oldfieldname": "naming_series",
    "oldfieldtype": "Select",
-   "options": "ACC-PINV-.YYYY.-",
+   "options": "ACC-PINV-.YYYY.-\nACC-PINV-RET-.YYYY.-",
    "print_hide": 1,
    "reqd": 1,
    "set_only_once": 1
@@ -969,8 +969,10 @@
   {
    "fieldname": "clearance_date",
    "fieldtype": "Date",
-   "hidden": 1,
-   "label": "Clearance Date"
+   "label": "Clearance Date",
+   "no_copy": 1,
+   "print_hide": 1,
+   "read_only": 1
   },
   {
    "fieldname": "col_br_payments",
@@ -1332,7 +1334,7 @@
  "idx": 204,
  "is_submittable": 1,
  "links": [],
- "modified": "2020-07-24 09:46:40.405463",
+ "modified": "2020-08-03 23:20:04.466153",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice",
@@ -1394,4 +1396,4 @@
  "timeline_field": "supplier",
  "title_field": "title",
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
index 52a5be0..f6d76e5 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -1,5 +1,4 @@
 {
- "actions": [],
  "autoname": "hash",
  "creation": "2013-05-22 12:43:10",
  "doctype": "DocType",
@@ -82,6 +81,7 @@
   "item_tax_rate",
   "bom",
   "include_exploded_items",
+  "purchase_invoice_item",
   "col_break6",
   "purchase_order",
   "po_detail",
@@ -769,12 +769,21 @@
    "collapsible": 1,
    "fieldname": "col_break7",
    "fieldtype": "Column Break"
+  },
+  {
+   "depends_on": "eval:parent.update_stock == 1",
+   "fieldname": "purchase_invoice_item",
+   "fieldtype": "Data",
+   "ignore_user_permissions": 1,
+   "label": "Purchase Invoice Item",
+   "no_copy": 1,
+   "print_hide": 1,
+   "read_only": 1
   }
  ],
  "idx": 1,
  "istable": 1,
- "links": [],
- "modified": "2020-04-22 10:37:35.103176",
+ "modified": "2020-08-20 11:48:01.398356",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice Item",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index 4dc81e9..31613e5 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -1,7 +1,6 @@
 {
  "actions": [],
  "allow_import": 1,
- "allow_workflow": 1,
  "autoname": "naming_series:",
  "creation": "2013-05-24 19:29:05",
  "doctype": "DocType",
@@ -217,7 +216,7 @@
    "no_copy": 1,
    "oldfieldname": "naming_series",
    "oldfieldtype": "Select",
-   "options": "ACC-SINV-.YYYY.-",
+   "options": "ACC-SINV-.YYYY.-\nACC-SINV-RET-.YYYY.-",
    "print_hide": 1,
    "reqd": 1,
    "set_only_once": 1
@@ -1947,7 +1946,7 @@
  "idx": 181,
  "is_submittable": 1,
  "links": [],
- "modified": "2020-07-18 05:07:16.725974",
+ "modified": "2020-08-03 23:31:12.675040",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 3dab054..71f2e12 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -1619,22 +1619,23 @@
 
 	for pos_payment_method in pos_profile.get('payments'):
 		pos_payment_method = pos_payment_method.as_dict()
-		
+
 		payment_mode = get_mode_of_payment_info(pos_payment_method.mode_of_payment, doc.company)
-		payment_mode[0].default = pos_payment_method.default
-		append_payment(payment_mode[0])
+		if payment_mode:
+			payment_mode[0].default = pos_payment_method.default
+			append_payment(payment_mode[0])
 
 def get_all_mode_of_payments(doc):
 	return frappe.db.sql("""
-		select mpa.default_account, mpa.parent, mp.type as type 
-		from `tabMode of Payment Account` mpa,`tabMode of Payment` mp 
+		select mpa.default_account, mpa.parent, mp.type as type
+		from `tabMode of Payment Account` mpa,`tabMode of Payment` mp
 		where mpa.parent = mp.name and mpa.company = %(company)s and mp.enabled = 1""",
 	{'company': doc.company}, as_dict=1)
 
 def get_mode_of_payment_info(mode_of_payment, company):
 	return frappe.db.sql("""
-		select mpa.default_account, mpa.parent, mp.type as type 
-		from `tabMode of Payment Account` mpa,`tabMode of Payment` mp 
+		select mpa.default_account, mpa.parent, mp.type as type
+		from `tabMode of Payment Account` mpa,`tabMode of Payment` mp
 		where mpa.parent = mp.name and mpa.company = %s and mp.enabled = 1 and mp.name = %s""",
 	(company, mode_of_payment), as_dict=1)
 
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice_dashboard.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice_dashboard.py
index 4a8fcc0..f106928 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice_dashboard.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice_dashboard.py
@@ -18,7 +18,7 @@
 		'transactions': [
 			{
 				'label': _('Payment'),
-				'items': ['Payment Entry', 'Payment Request', 'Journal Entry', 'Invoice Discounting']
+				'items': ['Payment Entry', 'Payment Request', 'Journal Entry', 'Invoice Discounting', 'Dunning']
 			},
 			{
 				'label': _('Reference'),
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 964566a..9660c95 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -206,10 +206,19 @@
 			"rate": 14,
 			'included_in_print_rate': 1
 		})
+		si.append("taxes", {
+			"charge_type": "On Item Quantity",
+			"account_head": "_Test Account Education Cess - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "CESS",
+			"rate": 5,
+			'included_in_print_rate': 1
+		})
 		si.insert()
 
 		# with inclusive tax
-		self.assertEqual(si.net_total, 4385.96)
+		self.assertEqual(si.items[0].net_amount, 3947.368421052631)
+		self.assertEqual(si.net_total, 3947.37)
 		self.assertEqual(si.grand_total, 5000)
 
 		si.reload()
@@ -222,8 +231,8 @@
 		si.save()
 
 		# with inclusive tax and additional discount
-		self.assertEqual(si.net_total, 4285.96)
-		self.assertEqual(si.grand_total, 4885.99)
+		self.assertEqual(si.net_total, 3847.37)
+		self.assertEqual(si.grand_total, 4886)
 
 		si.reload()
 
@@ -235,7 +244,7 @@
 		si.save()
 
 		# with inclusive tax and additional discount
-		self.assertEqual(si.net_total, 4298.25)
+		self.assertEqual(si.net_total, 3859.65)
 		self.assertEqual(si.grand_total, 4900.00)
 
 	def test_sales_invoice_discount_amount(self):
diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
index 004d358..fb3dd6a 100644
--- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
+++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
@@ -1,5 +1,4 @@
 {
- "actions": [],
  "autoname": "hash",
  "creation": "2013-06-04 11:02:19",
  "doctype": "DocType",
@@ -87,6 +86,7 @@
   "edit_references",
   "sales_order",
   "so_detail",
+  "sales_invoice_item",
   "column_break_74",
   "delivery_note",
   "dn_detail",
@@ -790,12 +790,22 @@
    "fieldtype": "Link",
    "label": "Project",
    "options": "Project"
-  }
+  },
+  {
+    "depends_on": "eval:parent.update_stock == 1",
+    "fieldname": "sales_invoice_item",
+    "fieldtype": "Data",
+    "ignore_user_permissions": 1,
+    "label": "Sales Invoice Item",
+    "no_copy": 1,
+    "print_hide": 1,
+    "read_only": 1
+   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-07-18 12:24:41.749986",
+ "modified": "2020-08-20 11:24:41.749986",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice Item",
diff --git a/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json b/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json
index 2f9d381..5ab46b7 100644
--- a/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json
+++ b/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json
@@ -64,6 +64,7 @@
    "fieldname": "clearance_date",
    "fieldtype": "Date",
    "label": "Clearance Date",
+   "no_copy": 1,
    "print_hide": 1,
    "read_only": 1
   },
@@ -78,7 +79,7 @@
  ],
  "istable": 1,
  "links": [],
- "modified": "2020-05-05 16:51:20.091441",
+ "modified": "2020-08-03 12:45:39.986598",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice Payment",
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template_dashboard.py b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template_dashboard.py
index 0e9c808..d825c6f 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template_dashboard.py
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template_dashboard.py
@@ -8,7 +8,7 @@
 		'fieldname': 'taxes_and_charges',
 		'non_standard_fieldnames': {
 			'Tax Rule': 'sales_tax_template',
-			'Subscription': 'tax_template',
+			'Subscription': 'sales_tax_template',
 			'Restaurant': 'default_tax_template'
 		},
 		'transactions': [
diff --git a/erpnext/accounts/doctype/subscription/test_subscription.py b/erpnext/accounts/doctype/subscription/test_subscription.py
index f41f08a..811fc35 100644
--- a/erpnext/accounts/doctype/subscription/test_subscription.py
+++ b/erpnext/accounts/doctype/subscription/test_subscription.py
@@ -7,8 +7,8 @@
 
 import frappe
 from erpnext.accounts.doctype.subscription.subscription import get_prorata_factor
-from frappe.utils.data import nowdate, add_days, add_to_date, add_months, date_diff, flt, get_date_str
-
+from frappe.utils.data import (nowdate, add_days, add_to_date, add_months, date_diff, flt, get_date_str,
+	get_first_day, get_last_day)
 
 def create_plan():
 	if not frappe.db.exists('Subscription Plan', '_Test Plan Name'):
@@ -68,14 +68,14 @@
 		subscription.party_type = 'Customer'
 		subscription.party = '_Test Customer'
 		subscription.trial_period_start = nowdate()
-		subscription.trial_period_end = add_days(nowdate(), 30)
+		subscription.trial_period_end = add_months(nowdate(), 1)
 		subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
 		subscription.save()
 
 		self.assertEqual(subscription.trial_period_start, nowdate())
-		self.assertEqual(subscription.trial_period_end, add_days(nowdate(), 30))
+		self.assertEqual(subscription.trial_period_end, add_months(nowdate(), 1))
 		self.assertEqual(add_days(subscription.trial_period_end, 1), get_date_str(subscription.current_invoice_start))
-		self.assertEqual(add_days(subscription.current_invoice_start, 30), get_date_str(subscription.current_invoice_end))
+		self.assertEqual(add_to_date(subscription.current_invoice_start, months=1, days=-1), get_date_str(subscription.current_invoice_end))
 		self.assertEqual(subscription.invoices, [])
 		self.assertEqual(subscription.status, 'Trialling')
 
diff --git a/erpnext/accounts/page/bank_reconciliation/bank_reconciliation.py b/erpnext/accounts/page/bank_reconciliation/bank_reconciliation.py
index 7df090b..ce6baa6 100644
--- a/erpnext/accounts/page/bank_reconciliation/bank_reconciliation.py
+++ b/erpnext/accounts/page/bank_reconciliation/bank_reconciliation.py
@@ -290,6 +290,7 @@
 		return []
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def payment_entry_query(doctype, txt, searchfield, start, page_len, filters):
 	account = frappe.db.get_value("Bank Account", filters.get("bank_account"), "account")
 	if not account:
@@ -319,6 +320,7 @@
 	)
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def journal_entry_query(doctype, txt, searchfield, start, page_len, filters):
 	account = frappe.db.get_value("Bank Account", filters.get("bank_account"), "account")
 
@@ -355,6 +357,7 @@
 	)
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def sales_invoices_query(doctype, txt, searchfield, start, page_len, filters):
 	return frappe.db.sql("""
 		SELECT
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 28a6519..2f800bb 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -611,7 +611,7 @@
 			cond = "posting_date <= '{0}'".format(posting_date)
 
 	if company:
-		cond += "and company = '{0}'".format(company)
+		cond += "and company = {0}".format(frappe.db.escape(company))
 
 	data = frappe.db.sql(""" SELECT party, sum({0}) as amount
 		FROM `tabGL Entry`
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index 66aa180..59117c8 100755
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -643,8 +643,10 @@
 		account_type = "Receivable" if self.party_type == "Customer" else "Payable"
 		accounts = [d.name for d in frappe.get_all("Account",
 			filters={"account_type": account_type, "company": self.filters.company})]
-		conditions.append("account in (%s)" % ','.join(['%s'] *len(accounts)))
-		values += accounts
+
+		if accounts:
+			conditions.append("account in (%s)" % ','.join(['%s'] *len(accounts)))
+			values += accounts
 
 	def add_customer_filters(self, conditions, values):
 		if self.filters.get("customer_group"):
diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
index c2c7207..219871b 100644
--- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
+++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
@@ -378,7 +378,7 @@
 		if filters and filters.get('presentation_currency') != d.default_currency:
 			currency_info['company'] = d.name
 			currency_info['company_currency'] = d.default_currency
-			convert_to_presentation_currency(gl_entries, currency_info)
+			convert_to_presentation_currency(gl_entries, currency_info, filters.get('company'))
 
 		for entry in gl_entries:
 			key = entry.account_number or entry.account_name
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 3785ebf..1b65a31 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -14,7 +14,7 @@
 from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency
 from erpnext.accounts.utils import get_fiscal_year
 from frappe import _
-from frappe.utils import (flt, getdate, get_first_day, add_months, add_days, formatdate, cstr)
+from frappe.utils import (flt, getdate, get_first_day, add_months, add_days, formatdate, cstr, cint)
 
 from six import itervalues
 from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
@@ -46,7 +46,7 @@
 	start_date = year_start_date
 	months = get_months(year_start_date, year_end_date)
 
-	for i in range(math.ceil(months / months_to_add)):
+	for i in range(cint(math.ceil(months / months_to_add))):
 		period = frappe._dict({
 			"from_date": start_date
 		})
@@ -423,7 +423,7 @@
 				distributed_cost_center_query=distributed_cost_center_query), gl_filters, as_dict=True) #nosec
 
 		if filters and filters.get('presentation_currency'):
-			convert_to_presentation_currency(gl_entries, get_currency(filters))
+			convert_to_presentation_currency(gl_entries, get_currency(filters), filters.get('company'))
 
 		for entry in gl_entries:
 			gl_entries_by_account.setdefault(entry.account, []).append(entry)
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index fcd36e4..0a72f6a 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -180,7 +180,7 @@
 		filters, as_dict=1)
 
 	if filters.get('presentation_currency'):
-		return convert_to_presentation_currency(gl_entries, currency_map)
+		return convert_to_presentation_currency(gl_entries, currency_map, filters.get('company'))
 	else:
 		return gl_entries
 
diff --git a/erpnext/accounts/report/utils.py b/erpnext/accounts/report/utils.py
index 4a9af49..9de8d19 100644
--- a/erpnext/accounts/report/utils.py
+++ b/erpnext/accounts/report/utils.py
@@ -6,10 +6,6 @@
 from frappe.utils import cint, get_datetime_str, formatdate, flt
 
 __exchange_rates = {}
-P_OR_L_ACCOUNTS = list(
-	sum(frappe.get_list('Account', fields=['name'], or_filters=[{'root_type': 'Income'}, {'root_type': 'Expense'}], as_list=True), ())
-)
-
 
 def get_currency(filters):
 	"""
@@ -73,18 +69,7 @@
 
 	return rate
 
-
-def is_p_or_l_account(account_name):
-	"""
-	Check if the given `account name` is an `Account` with `root_type` of either 'Income'
-	or 'Expense'.
-	:param account_name:
-	:return: Boolean
-	"""
-	return account_name in P_OR_L_ACCOUNTS
-
-
-def convert_to_presentation_currency(gl_entries, currency_info):
+def convert_to_presentation_currency(gl_entries, currency_info, company):
 	"""
 	Take a list of GL Entries and change the 'debit' and 'credit' values to currencies
 	in `currency_info`.
@@ -96,6 +81,9 @@
 	presentation_currency = currency_info['presentation_currency']
 	company_currency = currency_info['company_currency']
 
+	pl_accounts = [d.name for d in frappe.get_list('Account',
+		filters={'report_type': 'Profit and Loss', 'company': company})]
+
 	for entry in gl_entries:
 		account = entry['account']
 		debit = flt(entry['debit'])
@@ -107,7 +95,7 @@
 		if account_currency != presentation_currency:
 			value = debit or credit
 
-			date = currency_info['report_date'] if not is_p_or_l_account(account) else entry['posting_date']
+			date = entry['posting_date'] if account in pl_accounts else currency_info['report_date']
 			converted_value = convert(value, presentation_currency, company_currency, date)
 
 			if entry.get('debit'):
diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
index 1869a29..60c528b 100644
--- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
+++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
@@ -106,6 +106,7 @@
 		maintenance_log.save()
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_team_members(doctype, txt, searchfield, start, page_len, filters):
 	return frappe.db.get_values('Maintenance Team Member', { 'parent': filters.get("maintenance_team") })
 
diff --git a/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log.py b/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log.py
index f169f01..34facd8 100644
--- a/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log.py
+++ b/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log.py
@@ -11,7 +11,7 @@
 
 class AssetMaintenanceLog(Document):
 	def validate(self):
-		if getdate(self.due_date) < getdate(nowdate()):
+		if getdate(self.due_date) < getdate(nowdate()) and self.maintenance_status not in ["Completed", "Cancelled"]:
 			self.maintenance_status = "Overdue"
 
 		if self.maintenance_status == "Completed" and not self.completion_date:
@@ -41,6 +41,7 @@
 		asset_maintenance_doc.save()
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_maintenance_tasks(doctype, txt, searchfield, start, page_len, filters):
 	asset_maintenance_tasks = frappe.db.get_values('Asset Maintenance Task', {'parent':filters.get("asset_maintenance")}, 'maintenance_task')
 	return asset_maintenance_tasks
diff --git a/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log_list.js b/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log_list.js
index b854413..23000e6 100644
--- a/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log_list.js
+++ b/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log_list.js
@@ -1,14 +1,15 @@
 frappe.listview_settings['Asset Maintenance Log'] = {
 	add_fields: ["maintenance_status"],
+	has_indicator_for_draft: 1,
 	get_indicator: function(doc) {
-		if(doc.maintenance_status=="Pending") {
-			return [__("Pending"), "orange"];
-		} else if(doc.maintenance_status=="Completed") {
-			return [__("Completed"), "green"];
-		} else if(doc.maintenance_status=="Cancelled") {
-			return [__("Cancelled"), "red"];
-		} else if(doc.maintenance_status=="Overdue") {
-			return [__("Overdue"), "red"];
+		if (doc.maintenance_status=="Planned") {
+			return [__(doc.maintenance_status), "orange", "status,=," + doc.maintenance_status];
+		} else if (doc.maintenance_status=="Completed") {
+			return [__(doc.maintenance_status), "green", "status,=," + doc.maintenance_status];
+		} else if (doc.maintenance_status=="Cancelled") {
+			return [__(doc.maintenance_status), "red", "status,=," + doc.maintenance_status];
+		} else if (doc.maintenance_status=="Overdue") {
+			return [__(doc.maintenance_status), "red", "status,=," + doc.maintenance_status];
 		}
 	}
 };
diff --git a/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py b/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
index 155597e..fd702c7 100644
--- a/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
+++ b/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
@@ -8,6 +8,7 @@
 from frappe.utils import flt, getdate, cint, date_diff, formatdate
 from erpnext.assets.doctype.asset.depreciation import get_depreciation_accounts
 from frappe.model.document import Document
+from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_checks_for_pl_and_bs_accounts
 
 class AssetValueAdjustment(Document):
 	def validate(self):
@@ -53,17 +54,33 @@
 		je.company = self.company
 		je.remark = "Depreciation Entry against {0} worth {1}".format(self.asset, self.difference_amount)
 
-		je.append("accounts", {
+		credit_entry = {
 			"account": accumulated_depreciation_account,
 			"credit_in_account_currency": self.difference_amount,
 			"cost_center": depreciation_cost_center or self.cost_center
-		})
+		}
 
-		je.append("accounts", {
+		debit_entry = {
 			"account": depreciation_expense_account,
 			"debit_in_account_currency": self.difference_amount,
 			"cost_center": depreciation_cost_center or self.cost_center
-		})
+		}
+
+		accounting_dimensions = get_checks_for_pl_and_bs_accounts()
+
+		for dimension in accounting_dimensions:
+			if dimension.get('mandatory_for_bs'):
+				credit_entry.update({
+					dimension['fieldname']: self.get(dimension['fieldname']) or dimension.get('default_dimension')
+				})
+
+			if dimension.get('mandatory_for_pl'):
+				debit_entry.update({
+					dimension['fieldname']: self.get(dimension['fieldname']) or dimension.get('default_dimension')
+				})
+		
+		je.append("accounts", credit_entry)
+		je.append("accounts", debit_entry)
 
 		je.flags.ignore_permissions = True
 		je.submit()
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 25065ab..9f2b971 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -94,7 +94,7 @@
 				if(this.frm.doc.status !== 'Closed' && flt(this.frm.doc.per_received) < 100 && flt(this.frm.doc.per_billed) < 100) {
 					this.frm.add_custom_button(__('Update Items'), () => {
 						erpnext.utils.update_child_items({
-							frm: frm,
+							frm: this.frm,
 							child_docname: "items",
 							child_doctype: "Purchase Order Detail",
 							cannot_add_row: false,
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
index 4b85230..b54a585 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
@@ -207,6 +207,7 @@
 	return list_context
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_supplier_contacts(doctype, txt, searchfield, start, page_len, filters):
 	return frappe.db.sql("""select `tabContact`.name from `tabContact`, `tabDynamic Link`
 		where `tabDynamic Link`.link_doctype = 'Supplier' and (`tabDynamic Link`.link_name=%(name)s
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 89c38c7..3091193 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -479,7 +479,11 @@
 			if d.against_order:
 				allocated_amount = flt(d.amount)
 			else:
-				amount = self.rounded_total or self.grand_total
+				if self.get('party_account_currency') == self.company_currency:
+					amount = self.get('base_rounded_total') or self.base_grand_total
+				else:
+					amount = self.get('rounded_total') or self.grand_total
+
 				allocated_amount = min(amount - advance_allocated, d.amount)
 			advance_allocated += flt(allocated_amount)
 
@@ -802,10 +806,22 @@
 			self.payment_terms_template = ''
 			return
 
+		party_account_currency = self.get('party_account_currency')
+		if not party_account_currency:
+			party_type, party = self.get_party()
+
+			if party_type and party:
+				party_account_currency = get_party_account_currency(party_type, party, self.company)
+
 		posting_date = self.get("bill_date") or self.get("posting_date") or self.get("transaction_date")
 		date = self.get("due_date")
 		due_date = date or posting_date
-		grand_total = self.get("rounded_total") or self.grand_total
+
+		if party_account_currency == self.company_currency:
+			grand_total = self.get("base_rounded_total") or self.base_grand_total
+		else:
+			grand_total = self.get("rounded_total") or self.grand_total
+
 		if self.doctype in ("Sales Invoice", "Purchase Invoice"):
 			grand_total = grand_total - flt(self.write_off_amount)
 
@@ -850,13 +866,25 @@
 	def validate_payment_schedule_amount(self):
 		if self.doctype == 'Sales Invoice' and self.is_pos: return
 
+		party_account_currency = self.get('party_account_currency')
+		if not party_account_currency:
+			party_type, party = self.get_party()
+
+			if party_type and party:
+				party_account_currency = get_party_account_currency(party_type, party, self.company)
+
 		if self.get("payment_schedule"):
 			total = 0
 			for d in self.get("payment_schedule"):
 				total += flt(d.payment_amount)
-			total = flt(total, self.precision("grand_total"))
 
-			grand_total = flt(self.get("rounded_total") or self.grand_total, self.precision('grand_total'))
+			if party_account_currency == self.company_currency:
+				total = flt(total, self.precision("base_grand_total"))
+				grand_total = flt(self.get("base_rounded_total") or self.base_grand_total, self.precision('base_grand_total'))
+			else:
+				total = flt(total, self.precision("grand_total"))
+				grand_total = flt(self.get("rounded_total") or self.grand_total, self.precision('grand_total'))
+
 			if self.get("total_advance"):
 				grand_total -= self.get("total_advance")
 
@@ -957,7 +985,7 @@
 			# all rows about the reffered tax should be inclusive
 			_on_previous_row_error("1 - %d" % (tax.row_id,))
 		elif tax.get("category") == "Valuation":
-			frappe.throw(_("Valuation type charges can not marked as Inclusive"))
+			frappe.throw(_("Valuation type charges can not be marked as Inclusive"))
 
 
 def set_balance_in_account_currency(gl_dict, account_currency=None, conversion_rate=None, company_currency=None):
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 89b48f0..f982700 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -559,9 +559,19 @@
 						"serial_no": cstr(d.serial_no).strip()
 					})
 					if self.is_return:
-						original_incoming_rate = frappe.db.get_value("Stock Ledger Entry",
-							{"voucher_type": "Purchase Receipt", "voucher_no": self.return_against,
-							"item_code": d.item_code}, "incoming_rate")
+						filters = {
+							"voucher_type": self.doctype,
+							"voucher_no": self.return_against,
+							"item_code": d.item_code
+						}
+
+						if (self.doctype == "Purchase Invoice" and self.update_stock
+							and d.get("purchase_invoice_item")):
+							filters["voucher_detail_no"] = d.purchase_invoice_item
+						elif self.doctype == "Purchase Receipt" and d.get("purchase_receipt_item"):
+							filters["voucher_detail_no"] = d.purchase_receipt_item
+
+						original_incoming_rate = frappe.db.get_value("Stock Ledger Entry", filters, "incoming_rate")
 
 						sle.update({
 							"outgoing_rate": original_incoming_rate
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index 31e3498..c88bf66 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -12,6 +12,7 @@
 
 # searches for active employees
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def employee_query(doctype, txt, searchfield, start, page_len, filters):
 	conditions = []
 	fields = get_fields("Employee", ["name", "employee_name"])
@@ -42,6 +43,7 @@
 
 # searches for leads which are not converted
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def lead_query(doctype, txt, searchfield, start, page_len, filters):
 	fields = get_fields("Lead", ["name", "lead_name", "company_name"])
 
@@ -72,6 +74,7 @@
 
  # searches for customer
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def customer_query(doctype, txt, searchfield, start, page_len, filters):
 	conditions = []
 	cust_master_name = frappe.defaults.get_user_default("cust_master_name")
@@ -110,8 +113,10 @@
 
 # searches for supplier
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def supplier_query(doctype, txt, searchfield, start, page_len, filters):
 	supp_master_name = frappe.defaults.get_user_default("supp_master_name")
+
 	if supp_master_name == "Supplier Name":
 		fields = ["name", "supplier_group"]
 	else:
@@ -142,32 +147,49 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def tax_account_query(doctype, txt, searchfield, start, page_len, filters):
 	company_currency = erpnext.get_company_currency(filters.get('company'))
 
-	tax_accounts = frappe.db.sql("""select name, parent_account	from tabAccount
-		where tabAccount.docstatus!=2
-			and account_type in (%s)
-			and is_group = 0
-			and company = %s
-			and account_currency = %s
-			and `%s` LIKE %s
-		order by idx desc, name
-		limit %s, %s""" %
-		(", ".join(['%s']*len(filters.get("account_type"))), "%s", "%s", searchfield, "%s", "%s", "%s"),
-		tuple(filters.get("account_type") + [filters.get("company"), company_currency, "%%%s%%" % txt,
-			start, page_len]))
+	def get_accounts(with_account_type_filter):
+		account_type_condition = ''
+		if with_account_type_filter:
+			account_type_condition = "AND account_type in %(account_types)s"
+
+		accounts = frappe.db.sql("""
+			SELECT name, parent_account
+			FROM `tabAccount`
+			WHERE `tabAccount`.docstatus!=2
+				{account_type_condition}
+				AND is_group = 0
+				AND company = %(company)s
+				AND account_currency = %(currency)s
+				AND `{searchfield}` LIKE %(txt)s
+			ORDER BY idx DESC, name
+			LIMIT %(offset)s, %(limit)s
+		""".format(account_type_condition=account_type_condition, searchfield=searchfield),
+			dict(
+				account_types=filters.get("account_type"),
+				company=filters.get("company"),
+				currency=company_currency,
+				txt="%{}%".format(txt),
+				offset=start,
+				limit=page_len
+			)
+		)
+
+		return accounts
+
+	tax_accounts = get_accounts(True)
+
 	if not tax_accounts:
-		tax_accounts = frappe.db.sql("""select name, parent_account	from tabAccount
-			where tabAccount.docstatus!=2 and is_group = 0
-				and company = %s and account_currency = %s and `%s` LIKE %s limit %s, %s""" #nosec
-			% ("%s", "%s", searchfield, "%s", "%s", "%s"),
-			(filters.get("company"), company_currency, "%%%s%%" % txt, start, page_len))
+		tax_accounts = get_accounts(False)
 
 	return tax_accounts
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=False):
 	conditions = []
 
@@ -215,7 +237,6 @@
 			idx desc,
 			name, item_name
 		limit %(start)s, %(page_len)s """.format(
-			key=searchfield,
 			columns=columns,
 			scond=searchfields,
 			fcond=get_filters_cond(doctype, filters, conditions).replace('%', '%%'),
@@ -231,6 +252,7 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def bom(doctype, txt, searchfield, start, page_len, filters):
 	conditions = []
 	fields = get_fields("BOM", ["name", "item"])
@@ -258,6 +280,7 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_project_name(doctype, txt, searchfield, start, page_len, filters):
 	cond = ''
 	if filters.get('customer'):
@@ -285,6 +308,7 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_delivery_notes_to_be_billed(doctype, txt, searchfield, start, page_len, filters, as_dict):
 	fields = get_fields("Delivery Note", ["name", "customer", "posting_date"])
 
@@ -315,6 +339,7 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
 	cond = ""
 	if filters.get("posting_date"):
@@ -373,6 +398,7 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_account_list(doctype, txt, searchfield, start, page_len, filters):
 	filter_list = []
 
@@ -395,8 +421,8 @@
 		fields = ["name", "parent_account"],
 		limit_start=start, limit_page_length=page_len, as_list=True)
 
-
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_blanket_orders(doctype, txt, searchfield, start, page_len, filters):
 	return frappe.db.sql("""select distinct bo.name, bo.blanket_order_type, bo.to_date
 		from `tabBlanket Order` bo, `tabBlanket Order Item` boi
@@ -413,6 +439,7 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_income_account(doctype, txt, searchfield, start, page_len, filters):
 	from erpnext.controllers.queries import get_match_cond
 
@@ -439,6 +466,7 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_expense_account(doctype, txt, searchfield, start, page_len, filters):
 	from erpnext.controllers.queries import get_match_cond
 
@@ -463,29 +491,24 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def warehouse_query(doctype, txt, searchfield, start, page_len, filters):
 	# Should be used when item code is passed in filters.
 	conditions, bin_conditions = [], []
 	filter_dict = get_doctype_wise_filters(filters)
 
-	sub_query = """ select round(`tabBin`.actual_qty, 2) from `tabBin`
-		where `tabBin`.warehouse = `tabWarehouse`.name
-		{bin_conditions} """.format(
-		bin_conditions=get_filters_cond(doctype, filter_dict.get("Bin"),
-			bin_conditions, ignore_permissions=True))
-
 	query = """select `tabWarehouse`.name,
-		CONCAT_WS(" : ", "Actual Qty", ifnull( ({sub_query}), 0) ) as actual_qty
-		from `tabWarehouse`
+		CONCAT_WS(" : ", "Actual Qty", ifnull(round(`tabBin`.actual_qty, 2), 0 )) actual_qty
+		from `tabWarehouse` left join `tabBin`
+		on `tabBin`.warehouse = `tabWarehouse`.name {bin_conditions}
 		where
-		   `tabWarehouse`.`{key}` like {txt}
+			`tabWarehouse`.`{key}` like {txt}
 			{fcond} {mcond}
-		order by
-			`tabWarehouse`.name desc
+		order by ifnull(`tabBin`.actual_qty, 0) desc
 		limit
 			{start}, {page_len}
 		""".format(
-			sub_query=sub_query,
+			bin_conditions=get_filters_cond(doctype, filter_dict.get("Bin"),bin_conditions, ignore_permissions=True),
 			key=searchfield,
 			fcond=get_filters_cond(doctype, filter_dict.get("Warehouse"), conditions),
 			mcond=get_match_cond(doctype),
@@ -506,6 +529,7 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_batch_numbers(doctype, txt, searchfield, start, page_len, filters):
 	query = """select batch_id from `tabBatch`
 			where disabled = 0
@@ -519,6 +543,7 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def item_manufacturer_query(doctype, txt, searchfield, start, page_len, filters):
 	item_filters = [
 		['manufacturer', 'like', '%' + txt + '%'],
@@ -537,6 +562,7 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_purchase_receipts(doctype, txt, searchfield, start, page_len, filters):
 	query = """
 		select pr.name
@@ -551,6 +577,7 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_purchase_invoices(doctype, txt, searchfield, start, page_len, filters):
 	query = """
 		select pi.name
@@ -565,6 +592,7 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_tax_template(doctype, txt, searchfield, start, page_len, filters):
 
 	item_doc = frappe.get_cached_doc('Item', filters.get('item_code'))
@@ -579,9 +607,12 @@
 	if not taxes:
 		return frappe.db.sql(""" SELECT name FROM `tabItem Tax Template` """)
 	else:
+		valid_from = filters.get('valid_from')
+		valid_from = valid_from[1] if isinstance(valid_from, list) else valid_from
+
 		args = {
 			'item_code': filters.get('item_code'),
-			'posting_date': filters.get('valid_from'),
+			'posting_date': valid_from,
 			'tax_category': filters.get('tax_category'),
 			'company': filters.get('company')
 		}
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index 3f127a2..a03dee1 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -281,6 +281,8 @@
 			target_doc.rejected_warehouse = source_doc.rejected_warehouse
 			target_doc.po_detail = source_doc.po_detail
 			target_doc.pr_detail = source_doc.pr_detail
+			target_doc.purchase_invoice_item = source_doc.name
+
 		elif doctype == "Delivery Note":
 			target_doc.against_sales_order = source_doc.against_sales_order
 			target_doc.against_sales_invoice = source_doc.against_sales_invoice
@@ -296,6 +298,7 @@
 			target_doc.so_detail = source_doc.so_detail
 			target_doc.dn_detail = source_doc.dn_detail
 			target_doc.expense_account = source_doc.expense_account
+			target_doc.sales_invoice_item = source_doc.name
 			if default_warehouse_for_sales_return:
 				target_doc.warehouse = default_warehouse_for_sales_return
 
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index b696ac3..17f3ae5 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -217,7 +217,9 @@
 							'target_warehouse': p.target_warehouse,
 							'company': self.company,
 							'voucher_type': self.doctype,
-							'allow_zero_valuation': d.allow_zero_valuation_rate
+							'allow_zero_valuation': d.allow_zero_valuation_rate,
+							'sales_invoice_item': d.get("sales_invoice_item"),
+							'delivery_note_item': d.get("dn_detail")
 						}))
 			else:
 				il.append(frappe._dict({
@@ -233,7 +235,9 @@
 					'target_warehouse': d.target_warehouse,
 					'company': self.company,
 					'voucher_type': self.doctype,
-					'allow_zero_valuation': d.allow_zero_valuation_rate
+					'allow_zero_valuation': d.allow_zero_valuation_rate,
+					'sales_invoice_item': d.get("sales_invoice_item"),
+					'delivery_note_item': d.get("dn_detail")
 				}))
 		return il
 
@@ -302,7 +306,11 @@
 					d.conversion_factor = get_conversion_factor(d.item_code, d.uom).get("conversion_factor") or 1.0
 				return_rate = 0
 				if cint(self.is_return) and self.return_against and self.docstatus==1:
-					return_rate = self.get_incoming_rate_for_return(d.item_code, self.return_against)
+					against_document_no = (d.get("sales_invoice_item")
+						if self.doctype == "Sales Invoice" else d.get("delivery_note_item"))
+
+					return_rate = self.get_incoming_rate_for_return(d.item_code,
+						self.return_against, against_document_no)
 
 				# On cancellation or if return entry submission, make stock ledger entry for
 				# target warehouse first, to update serial no values properly
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index e8483da..394883d 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -301,14 +301,19 @@
 
 		return serialized_items
 
-	def get_incoming_rate_for_return(self, item_code, against_document):
+	def get_incoming_rate_for_return(self, item_code, against_document, against_document_no=None):
 		incoming_rate = 0.0
+		cond = ''
 		if against_document and item_code:
+			if against_document_no:
+				cond = " and voucher_detail_no = %s" %(frappe.db.escape(against_document_no))
+
 			incoming_rate = frappe.db.sql("""select abs(stock_value_difference / actual_qty)
 				from `tabStock Ledger Entry`
 				where voucher_type = %s and voucher_no = %s
-					and item_code = %s limit 1""",
+					and item_code = %s {0} limit 1""".format(cond),
 				(self.doctype, against_document, item_code))
+
 			incoming_rate = incoming_rate[0][0] if incoming_rate else 0.0
 
 		return incoming_rate
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 572e1ca..2a14be8 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -161,8 +161,9 @@
 		for item in self.doc.get("items"):
 			item_tax_map = self._load_item_tax_rate(item.item_tax_rate)
 			cumulated_tax_fraction = 0
+			total_inclusive_tax_amount_per_qty = 0
 			for i, tax in enumerate(self.doc.get("taxes")):
-				tax.tax_fraction_for_current_item = self.get_current_tax_fraction(tax, item_tax_map)
+				tax.tax_fraction_for_current_item, inclusive_tax_amount_per_qty = self.get_current_tax_fraction(tax, item_tax_map)
 
 				if i==0:
 					tax.grand_total_fraction_for_current_item = 1 + tax.tax_fraction_for_current_item
@@ -172,9 +173,12 @@
 						+ tax.tax_fraction_for_current_item
 
 				cumulated_tax_fraction += tax.tax_fraction_for_current_item
+				total_inclusive_tax_amount_per_qty += inclusive_tax_amount_per_qty * flt(item.qty)
 
-			if cumulated_tax_fraction and not self.discount_amount_applied and item.qty:
-				item.net_amount = flt(item.amount / (1 + cumulated_tax_fraction))
+			if not self.discount_amount_applied and item.qty and (cumulated_tax_fraction or total_inclusive_tax_amount_per_qty):
+				amount = flt(item.amount) - total_inclusive_tax_amount_per_qty
+
+				item.net_amount = flt(amount / (1 + cumulated_tax_fraction))
 				item.net_rate = flt(item.net_amount / item.qty, item.precision("net_rate"))
 				item.discount_percentage = flt(item.discount_percentage,
 					item.precision("discount_percentage"))
@@ -190,6 +194,7 @@
 			from tax inclusive amount
 		"""
 		current_tax_fraction = 0
+		inclusive_tax_amount_per_qty = 0
 
 		if cint(tax.included_in_print_rate):
 			tax_rate = self._get_tax_rate(tax, item_tax_map)
@@ -204,10 +209,15 @@
 			elif tax.charge_type == "On Previous Row Total":
 				current_tax_fraction = (tax_rate / 100.0) * \
 					self.doc.get("taxes")[cint(tax.row_id) - 1].grand_total_fraction_for_current_item
+			
+			elif tax.charge_type == "On Item Quantity":
+				inclusive_tax_amount_per_qty = flt(tax_rate)
 
-		if getattr(tax, "add_deduct_tax", None):
-			current_tax_fraction *= -1.0 if (tax.add_deduct_tax == "Deduct") else 1.0
-		return current_tax_fraction
+		if getattr(tax, "add_deduct_tax", None) and tax.add_deduct_tax == "Deduct":
+			current_tax_fraction *= -1.0
+			inclusive_tax_amount_per_qty *= -1.0
+
+		return current_tax_fraction, inclusive_tax_amount_per_qty
 
 	def _get_tax_rate(self, tax, item_tax_map):
 		if tax.account_head in item_tax_map:
@@ -321,7 +331,7 @@
 			current_tax_amount = (tax_rate / 100.0) * \
 				self.doc.get("taxes")[cint(tax.row_id) - 1].grand_total_for_current_item
 		elif tax.charge_type == "On Item Quantity":
-			current_tax_amount = tax_rate * item.stock_qty
+			current_tax_amount = tax_rate * item.qty
 
 		self.set_item_wise_tax(item, tax, tax_rate, current_tax_amount)
 
@@ -472,7 +482,7 @@
 			actual_taxes_dict = {}
 
 			for tax in self.doc.get("taxes"):
-				if tax.charge_type == "Actual":
+				if tax.charge_type in ["Actual", "On Item Quantity"]:
 					tax_amount = self.get_tax_amount_if_for_valuation_or_deduction(tax.tax_amount, tax)
 					actual_taxes_dict.setdefault(tax.idx, tax_amount)
 				elif tax.row_id in actual_taxes_dict:
diff --git a/erpnext/crm/doctype/opportunity/opportunity.json b/erpnext/crm/doctype/opportunity/opportunity.json
index 545e232..b61cad3 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.json
+++ b/erpnext/crm/doctype/opportunity/opportunity.json
@@ -16,6 +16,7 @@
   "opportunity_from",
   "party_name",
   "customer_name",
+  "source",
   "column_break0",
   "title",
   "opportunity_type",
@@ -49,10 +50,9 @@
   "contact_email",
   "contact_mobile",
   "more_info",
-  "source",
+  "company",
   "campaign",
   "column_break1",
-  "company",
   "transaction_date",
   "amended_from",
   "lost_reasons"
@@ -344,7 +344,7 @@
    "collapsible": 1,
    "fieldname": "more_info",
    "fieldtype": "Section Break",
-   "label": "Source",
+   "label": "More Information",
    "oldfieldtype": "Section Break",
    "options": "fa fa-file-text"
   },
@@ -411,7 +411,7 @@
    "fieldname": "lost_reasons",
    "fieldtype": "Table MultiSelect",
    "label": "Lost Reasons",
-   "options": "Lost Reason Detail",
+   "options": "Opportunity Lost Reason Detail",
    "read_only": 1
   },
   {
@@ -424,7 +424,7 @@
  "icon": "fa fa-info-sign",
  "idx": 195,
  "links": [],
- "modified": "2020-07-14 16:49:15.888503",
+ "modified": "2020-08-11 17:34:35.066961",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "Opportunity",
diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py
index 1b071ea..6096053 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.py
+++ b/erpnext/crm/doctype/opportunity/opportunity.py
@@ -119,11 +119,19 @@
 				and q.status not in ('Lost', 'Closed')""", self.name)
 
 	def has_ordered_quotation(self):
-		return frappe.db.sql("""
-			select q.name
-			from `tabQuotation` q, `tabQuotation Item` qi
-			where q.name = qi.parent and q.docstatus=1 and qi.prevdoc_docname =%s
-			and q.status = 'Ordered'""", self.name)
+		if not self.with_items:
+			return frappe.get_all('Quotation',
+				{
+					'opportunity': self.name,
+					'status': 'Ordered',
+					'docstatus': 1
+				}, 'name')
+		else:
+			return frappe.db.sql("""
+				select q.name
+				from `tabQuotation` q, `tabQuotation Item` qi
+				where q.name = qi.parent and q.docstatus=1 and qi.prevdoc_docname =%s
+				and q.status = 'Ordered'""", self.name)
 
 	def has_lost_quotation(self):
 		lost_quotation = frappe.db.sql("""
@@ -317,7 +325,7 @@
 		doc.save()
 
 @frappe.whitelist()
-def make_opportunity_from_communication(communication, ignore_communication_links=False):
+def make_opportunity_from_communication(communication, company, ignore_communication_links=False):
 	from erpnext.crm.doctype.lead.lead import make_lead_from_communication
 	doc = frappe.get_doc("Communication", communication)
 
@@ -329,8 +337,9 @@
 
 	opportunity = frappe.get_doc({
 		"doctype": "Opportunity",
+		"company": company,
 		"opportunity_from": opportunity_from,
-		"lead": lead
+		"party_name": lead
 	}).insert(ignore_permissions=True)
 
 	link_communication_to_document(doc, "Opportunity", opportunity.name, ignore_communication_links)
diff --git a/erpnext/crm/doctype/opportunity_lost_reason_detail/__init__.py b/erpnext/crm/doctype/opportunity_lost_reason_detail/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/crm/doctype/opportunity_lost_reason_detail/__init__.py
diff --git a/erpnext/crm/doctype/opportunity_lost_reason_detail/opportunity_lost_reason_detail.json b/erpnext/crm/doctype/opportunity_lost_reason_detail/opportunity_lost_reason_detail.json
new file mode 100644
index 0000000..50620e2
--- /dev/null
+++ b/erpnext/crm/doctype/opportunity_lost_reason_detail/opportunity_lost_reason_detail.json
@@ -0,0 +1,31 @@
+{
+ "actions": [],
+ "creation": "2020-07-16 16:11:39.830389",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "lost_reason"
+ ],
+ "fields": [
+  {
+   "fieldname": "lost_reason",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Opportunity Lost Reason",
+   "options": "Opportunity Lost Reason"
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-07-26 17:58:26.313242",
+ "modified_by": "Administrator",
+ "module": "CRM",
+ "name": "Opportunity Lost Reason Detail",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/crm/doctype/opportunity_lost_reason_detail/opportunity_lost_reason_detail.py b/erpnext/crm/doctype/opportunity_lost_reason_detail/opportunity_lost_reason_detail.py
new file mode 100644
index 0000000..8723f1d
--- /dev/null
+++ b/erpnext/crm/doctype/opportunity_lost_reason_detail/opportunity_lost_reason_detail.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, 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 OpportunityLostReasonDetail(Document):
+	pass
diff --git a/erpnext/education/dashboard_chart/course_wise_enrollment/course_wise_enrollment.json b/erpnext/education/dashboard_chart/course_wise_enrollment/course_wise_enrollment.json
new file mode 100644
index 0000000..9c5f784
--- /dev/null
+++ b/erpnext/education/dashboard_chart/course_wise_enrollment/course_wise_enrollment.json
@@ -0,0 +1,31 @@
+{
+ "based_on": "",
+ "chart_name": "Course wise Enrollment",
+ "chart_type": "Group By",
+ "creation": "2020-07-23 18:24:38.214220",
+ "docstatus": 0,
+ "doctype": "Dashboard Chart",
+ "document_type": "Course Enrollment",
+ "dynamic_filters_json": "[]",
+ "filters_json": "[[\"Course Enrollment\",\"enrollment_date\",\"Timespan\",\"this year\",false]]",
+ "group_by_based_on": "course",
+ "group_by_type": "Count",
+ "idx": 0,
+ "is_public": 1,
+ "is_standard": 1,
+ "last_synced_on": "2020-07-27 17:50:32.490587",
+ "modified": "2020-07-27 17:54:09.829206",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Course wise Enrollment",
+ "number_of_groups": 0,
+ "owner": "Administrator",
+ "source": "",
+ "time_interval": "Yearly",
+ "timeseries": 0,
+ "timespan": "Last Year",
+ "type": "Percentage",
+ "use_report_chart": 0,
+ "value_based_on": "",
+ "y_axis": []
+}
\ No newline at end of file
diff --git a/erpnext/education/dashboard_chart/course_wise_student_count/course_wise_student_count.json b/erpnext/education/dashboard_chart/course_wise_student_count/course_wise_student_count.json
new file mode 100644
index 0000000..5441518
--- /dev/null
+++ b/erpnext/education/dashboard_chart/course_wise_student_count/course_wise_student_count.json
@@ -0,0 +1,31 @@
+{
+ "based_on": "",
+ "chart_name": "Course wise Student Count",
+ "chart_type": "Group By",
+ "creation": "2020-07-27 17:24:39.136163",
+ "docstatus": 0,
+ "doctype": "Dashboard Chart",
+ "document_type": "Course Enrollment",
+ "dynamic_filters_json": "[]",
+ "filters_json": "[[\"Course Enrollment\",\"enrollment_date\",\"Timespan\",\"this year\",false]]",
+ "group_by_based_on": "course",
+ "group_by_type": "Count",
+ "idx": 0,
+ "is_public": 1,
+ "is_standard": 1,
+ "last_synced_on": "2020-07-27 17:24:56.184236",
+ "modified": "2020-07-27 17:25:46.232846",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Course wise Student Count",
+ "number_of_groups": 0,
+ "owner": "Administrator",
+ "source": "",
+ "time_interval": "Yearly",
+ "timeseries": 0,
+ "timespan": "Last Year",
+ "type": "Donut",
+ "use_report_chart": 0,
+ "value_based_on": "",
+ "y_axis": []
+}
\ No newline at end of file
diff --git a/erpnext/education/dashboard_chart/instructor_gender_diversity_ratio/instructor_gender_diversity_ratio.json b/erpnext/education/dashboard_chart/instructor_gender_diversity_ratio/instructor_gender_diversity_ratio.json
new file mode 100644
index 0000000..b7ee509
--- /dev/null
+++ b/erpnext/education/dashboard_chart/instructor_gender_diversity_ratio/instructor_gender_diversity_ratio.json
@@ -0,0 +1,31 @@
+{
+ "based_on": "",
+ "chart_name": "Instructor Gender Diversity Ratio",
+ "chart_type": "Group By",
+ "creation": "2020-07-23 18:35:02.544019",
+ "docstatus": 0,
+ "doctype": "Dashboard Chart",
+ "document_type": "Instructor",
+ "dynamic_filters_json": "[]",
+ "filters_json": "[[\"Instructor\",\"status\",\"=\",\"Active\",false]]",
+ "group_by_based_on": "gender",
+ "group_by_type": "Count",
+ "idx": 0,
+ "is_public": 1,
+ "is_standard": 1,
+ "last_synced_on": "2020-07-27 17:50:32.783820",
+ "modified": "2020-07-27 17:55:41.595260",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Instructor Gender Diversity Ratio",
+ "number_of_groups": 0,
+ "owner": "Administrator",
+ "source": "",
+ "time_interval": "Yearly",
+ "timeseries": 0,
+ "timespan": "Last Year",
+ "type": "Donut",
+ "use_report_chart": 0,
+ "value_based_on": "",
+ "y_axis": []
+}
\ No newline at end of file
diff --git a/erpnext/education/dashboard_chart/program_enrollments/program_enrollments.json b/erpnext/education/dashboard_chart/program_enrollments/program_enrollments.json
new file mode 100644
index 0000000..2a4a4a3
--- /dev/null
+++ b/erpnext/education/dashboard_chart/program_enrollments/program_enrollments.json
@@ -0,0 +1,30 @@
+{
+ "based_on": "enrollment_date",
+ "chart_name": "Program Enrollments",
+ "chart_type": "Count",
+ "creation": "2020-07-23 18:27:53.641616",
+ "docstatus": 0,
+ "doctype": "Dashboard Chart",
+ "document_type": "Program Enrollment",
+ "dynamic_filters_json": "[]",
+ "filters_json": "[[\"Program Enrollment\",\"docstatus\",\"=\",\"1\",false]]",
+ "group_by_type": "Count",
+ "idx": 0,
+ "is_public": 1,
+ "is_standard": 1,
+ "last_synced_on": "2020-07-27 17:50:32.203069",
+ "modified": "2020-07-27 17:51:59.022909",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Program Enrollments",
+ "number_of_groups": 0,
+ "owner": "Administrator",
+ "source": "",
+ "time_interval": "Daily",
+ "timeseries": 1,
+ "timespan": "Last Month",
+ "type": "Line",
+ "use_report_chart": 0,
+ "value_based_on": "",
+ "y_axis": []
+}
\ No newline at end of file
diff --git a/erpnext/education/dashboard_chart/program_wise_enrollment/program_wise_enrollment.json b/erpnext/education/dashboard_chart/program_wise_enrollment/program_wise_enrollment.json
new file mode 100644
index 0000000..2ba138e
--- /dev/null
+++ b/erpnext/education/dashboard_chart/program_wise_enrollment/program_wise_enrollment.json
@@ -0,0 +1,31 @@
+{
+ "based_on": "",
+ "chart_name": "Program wise Enrollment",
+ "chart_type": "Group By",
+ "creation": "2020-07-23 18:23:45.192748",
+ "docstatus": 0,
+ "doctype": "Dashboard Chart",
+ "document_type": "Program Enrollment",
+ "dynamic_filters_json": "[]",
+ "filters_json": "[[\"Program Enrollment\",\"docstatus\",\"=\",\"1\",false],[\"Program Enrollment\",\"enrollment_date\",\"Timespan\",\"this year\",false]]",
+ "group_by_based_on": "program",
+ "group_by_type": "Count",
+ "idx": 0,
+ "is_public": 1,
+ "is_standard": 1,
+ "last_synced_on": "2020-07-27 17:50:32.629321",
+ "modified": "2020-07-27 17:53:36.269098",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Program wise Enrollment",
+ "number_of_groups": 0,
+ "owner": "Administrator",
+ "source": "",
+ "time_interval": "Yearly",
+ "timeseries": 0,
+ "timespan": "Last Year",
+ "type": "Percentage",
+ "use_report_chart": 0,
+ "value_based_on": "",
+ "y_axis": []
+}
\ No newline at end of file
diff --git a/erpnext/education/dashboard_chart/program_wise_fee_collection/program_wise_fee_collection.json b/erpnext/education/dashboard_chart/program_wise_fee_collection/program_wise_fee_collection.json
new file mode 100644
index 0000000..38c1b6d
--- /dev/null
+++ b/erpnext/education/dashboard_chart/program_wise_fee_collection/program_wise_fee_collection.json
@@ -0,0 +1,28 @@
+{
+ "chart_name": "Program wise Fee Collection",
+ "chart_type": "Report",
+ "creation": "2020-08-05 16:19:53.398335",
+ "custom_options": "",
+ "docstatus": 0,
+ "doctype": "Dashboard Chart",
+ "dynamic_filters_json": "{\"from_date\":\"frappe.datetime.add_months(frappe.datetime.get_today(), -1)\",\"to_date\":\"frappe.datetime.nowdate()\"}",
+ "filters_json": "{}",
+ "group_by_type": "Count",
+ "idx": 0,
+ "is_public": 1,
+ "is_standard": 1,
+ "modified": "2020-08-05 16:20:47.436847",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Program wise Fee Collection",
+ "number_of_groups": 0,
+ "owner": "Administrator",
+ "report_name": "Program wise Fee Collection",
+ "time_interval": "Yearly",
+ "timeseries": 0,
+ "timespan": "Last Year",
+ "type": "Bar",
+ "use_report_chart": 1,
+ "x_field": "",
+ "y_axis": []
+}
\ No newline at end of file
diff --git a/erpnext/education/dashboard_chart/student_category_wise_program_enrollments/student_category_wise_program_enrollments.json b/erpnext/education/dashboard_chart/student_category_wise_program_enrollments/student_category_wise_program_enrollments.json
new file mode 100644
index 0000000..8887145
--- /dev/null
+++ b/erpnext/education/dashboard_chart/student_category_wise_program_enrollments/student_category_wise_program_enrollments.json
@@ -0,0 +1,31 @@
+{
+ "based_on": "",
+ "chart_name": "Student Category wise Program Enrollments",
+ "chart_type": "Group By",
+ "creation": "2020-07-27 17:37:47.116446",
+ "docstatus": 0,
+ "doctype": "Dashboard Chart",
+ "document_type": "Program Enrollment",
+ "dynamic_filters_json": "[]",
+ "filters_json": "[[\"Program Enrollment\",\"enrollment_date\",\"Timespan\",\"this year\",false],[\"Program Enrollment\",\"docstatus\",\"=\",\"1\",false]]",
+ "group_by_based_on": "student_category",
+ "group_by_type": "Count",
+ "idx": 0,
+ "is_public": 1,
+ "is_standard": 1,
+ "last_synced_on": "2020-07-27 17:46:54.901911",
+ "modified": "2020-07-27 17:47:21.370866",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Student Category wise Program Enrollments",
+ "number_of_groups": 0,
+ "owner": "Administrator",
+ "source": "",
+ "time_interval": "Yearly",
+ "timeseries": 0,
+ "timespan": "Last Year",
+ "type": "Donut",
+ "use_report_chart": 0,
+ "value_based_on": "",
+ "y_axis": []
+}
\ No newline at end of file
diff --git a/erpnext/education/dashboard_chart/student_gender_diversity_ratio/student_gender_diversity_ratio.json b/erpnext/education/dashboard_chart/student_gender_diversity_ratio/student_gender_diversity_ratio.json
new file mode 100644
index 0000000..ce602d2
--- /dev/null
+++ b/erpnext/education/dashboard_chart/student_gender_diversity_ratio/student_gender_diversity_ratio.json
@@ -0,0 +1,30 @@
+{
+ "based_on": "",
+ "chart_name": "Student Gender Diversity Ratio",
+ "chart_type": "Group By",
+ "creation": "2020-07-23 18:12:15.972123",
+ "docstatus": 0,
+ "doctype": "Dashboard Chart",
+ "document_type": "Student",
+ "dynamic_filters_json": "[]",
+ "filters_json": "[[\"Student\",\"enabled\",\"=\",1,false]]",
+ "group_by_based_on": "gender",
+ "group_by_type": "Count",
+ "idx": 0,
+ "is_public": 1,
+ "is_standard": 1,
+ "modified": "2020-07-23 18:12:21.606772",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Student Gender Diversity Ratio",
+ "number_of_groups": 0,
+ "owner": "Administrator",
+ "source": "",
+ "time_interval": "Yearly",
+ "timeseries": 0,
+ "timespan": "Last Year",
+ "type": "Donut",
+ "use_report_chart": 0,
+ "value_based_on": "",
+ "y_axis": []
+}
\ No newline at end of file
diff --git a/erpnext/education/desk_page/education/education.json b/erpnext/education/desk_page/education/education.json
index b8f87d3..0d51048 100644
--- a/erpnext/education/desk_page/education/education.json
+++ b/erpnext/education/desk_page/education/education.json
@@ -2,18 +2,13 @@
  "cards": [
   {
    "hidden": 0,
-   "label": "Tools",
-   "links": "[\n    {\n        \"label\": \"Student Attendance Tool\",\n        \"name\": \"Student Attendance Tool\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Assessment Result Tool\",\n        \"name\": \"Assessment Result Tool\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Student Group Creation Tool\",\n        \"name\": \"Student Group Creation Tool\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Program Enrollment Tool\",\n        \"name\": \"Program Enrollment Tool\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Course Scheduling Tool\",\n        \"name\": \"Course Scheduling Tool\",\n        \"type\": \"doctype\"\n    }\n]"
+   "label": "Student and Instructor",
+   "links": "[\n    {\n        \"label\": \"Student\",\n        \"name\": \"Student\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Instructor\",\n        \"name\": \"Instructor\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Guardian\",\n        \"name\": \"Guardian\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Student Group\",\n        \"name\": \"Student Group\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Student Log\",\n        \"name\": \"Student Log\",\n        \"type\": \"doctype\"\n    }\n]"
   },
   {
    "hidden": 0,
-   "label": "Other Reports",
-   "links": "[\n    {\n        \"dependencies\": [\n            \"Program Enrollment\"\n        ],\n        \"doctype\": \"Program Enrollment\",\n        \"is_query_report\": true,\n        \"label\": \"Student and Guardian Contact Details\",\n        \"name\": \"Student and Guardian Contact Details\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Student Attendance\"\n        ],\n        \"doctype\": \"Student Attendance\",\n        \"is_query_report\": true,\n        \"label\": \"Student Monthly Attendance Sheet\",\n        \"name\": \"Student Monthly Attendance Sheet\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Fees\"\n        ],\n        \"doctype\": \"Fees\",\n        \"is_query_report\": true,\n        \"label\": \"Student Fee Collection\",\n        \"name\": \"Student Fee Collection\",\n        \"type\": \"report\"\n    }\n]"
-  },
-  {
-   "hidden": 0,
-   "label": "Settings",
-   "links": "[\n    {\n        \"label\": \"Student Category\",\n        \"name\": \"Student Category\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Student Batch Name\",\n        \"name\": \"Student Batch Name\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Grading Scale\",\n        \"name\": \"Grading Scale\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Academic Term\",\n        \"name\": \"Academic Term\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Academic Year\",\n        \"name\": \"Academic Year\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Education Settings\",\n        \"name\": \"Education Settings\",\n        \"type\": \"doctype\"\n    }\n]"
+   "label": "Masters",
+   "links": "[\n    {\n        \"label\": \"Program\",\n        \"name\": \"Program\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Course\",\n        \"name\": \"Course\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Topic\",\n        \"name\": \"Topic\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Room\",\n        \"name\": \"Room\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    }\n]"
   },
   {
    "hidden": 0,
@@ -22,33 +17,18 @@
   },
   {
    "hidden": 0,
-   "label": "Attendance",
-   "links": "[\n    {\n        \"label\": \"Student Attendance\",\n        \"name\": \"Student Attendance\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Student Leave Application\",\n        \"name\": \"Student Leave Application\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"Student Attendance\"\n        ],\n        \"doctype\": \"Student Attendance\",\n        \"is_query_report\": true,\n        \"label\": \"Absent Student Report\",\n        \"name\": \"Absent Student Report\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Student Attendance\"\n        ],\n        \"doctype\": \"Student Attendance\",\n        \"is_query_report\": true,\n        \"label\": \"Student Batch-Wise Attendance\",\n        \"name\": \"Student Batch-Wise Attendance\",\n        \"type\": \"report\"\n    }\n]"
+   "label": "Settings",
+   "links": "[\n    {\n        \"label\": \"Education Settings\",\n        \"name\": \"Education Settings\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Student Category\",\n        \"name\": \"Student Category\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Student Batch Name\",\n        \"name\": \"Student Batch Name\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Grading Scale\",\n        \"name\": \"Grading Scale\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Academic Term\",\n        \"name\": \"Academic Term\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Academic Year\",\n        \"name\": \"Academic Year\",\n        \"type\": \"doctype\"\n    }\n]"
   },
   {
    "hidden": 0,
    "label": "Admission",
-   "links": "[\n    {\n        \"label\": \"Student Applicant\",\n        \"name\": \"Student Applicant\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Student Admission\",\n        \"name\": \"Student Admission\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Program Enrollment\",\n        \"name\": \"Program Enrollment\",\n        \"type\": \"doctype\"\n    }\n]"
+   "links": "[\n    {\n        \"label\": \"Student Applicant\",\n        \"name\": \"Student Applicant\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Student Admission\",\n        \"name\": \"Student Admission\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Program Enrollment\",\n        \"name\": \"Program Enrollment\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Course Enrollment\",\n        \"name\": \"Course Enrollment\",\n        \"type\": \"doctype\"\n    }\n]"
   },
   {
    "hidden": 0,
-   "label": "Assessment",
-   "links": "[\n    {\n        \"label\": \"Assessment Plan\",\n        \"name\": \"Assessment Plan\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Assessment Group\",\n        \"link\": \"Tree/Assessment Group\",\n        \"name\": \"Assessment Group\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Assessment Result\",\n        \"name\": \"Assessment Result\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Assessment Criteria\",\n        \"name\": \"Assessment Criteria\",\n        \"type\": \"doctype\"\n    }\n]"
-  },
-  {
-   "hidden": 0,
-   "label": "Student",
-   "links": "[\n    {\n        \"label\": \"Student\",\n        \"name\": \"Student\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Guardian\",\n        \"name\": \"Guardian\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Student Log\",\n        \"name\": \"Student Log\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Student Group\",\n        \"name\": \"Student Group\",\n        \"type\": \"doctype\"\n    }\n]"
-  },
-  {
-   "hidden": 0,
-   "label": "Masters",
-   "links": "[\n    {\n        \"label\": \"Program\",\n        \"name\": \"Program\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Course\",\n        \"name\": \"Course\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Topic\",\n        \"name\": \"Topic\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Instructor\",\n        \"name\": \"Instructor\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Room\",\n        \"name\": \"Room\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    }\n]"
-  },
-  {
-   "hidden": 0,
-   "label": "LMS Activity",
-   "links": "[\n    {\n        \"label\": \"Course Enrollment\",\n        \"name\": \"Course Enrollment\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Course Activity\",\n        \"name\": \"Course Activity\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Quiz Activity\",\n        \"name\": \"Quiz Activity\",\n        \"type\": \"doctype\"\n    }\n]"
+   "label": "Fees",
+   "links": "[\n    {\n        \"label\": \"Fee Structure\",\n        \"name\": \"Fee Structure\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Fee Category\",\n        \"name\": \"Fee Category\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Fee Schedule\",\n        \"name\": \"Fee Schedule\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Fees\",\n        \"name\": \"Fees\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"Fees\"\n        ],\n        \"doctype\": \"Fees\",\n        \"is_query_report\": true,\n        \"label\": \"Student Fee Collection Report\",\n        \"name\": \"Student Fee Collection\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Fees\"\n        ],\n        \"doctype\": \"Fees\",\n        \"is_query_report\": true,\n        \"label\": \"Program wise Fee Collection Report\",\n        \"name\": \"Program wise Fee Collection\",\n        \"type\": \"report\"\n    }\n]"
   },
   {
    "hidden": 0,
@@ -57,8 +37,18 @@
   },
   {
    "hidden": 0,
-   "label": "Fees",
-   "links": "[\n    {\n        \"label\": \"Fees\",\n        \"name\": \"Fees\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Fee Schedule\",\n        \"name\": \"Fee Schedule\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Fee Structure\",\n        \"name\": \"Fee Structure\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Fee Category\",\n        \"name\": \"Fee Category\",\n        \"type\": \"doctype\"\n    }\n]"
+   "label": "Attendance",
+   "links": "[\n    {\n        \"label\": \"Student Attendance\",\n        \"name\": \"Student Attendance\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Student Leave Application\",\n        \"name\": \"Student Leave Application\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"Student Attendance\"\n        ],\n        \"doctype\": \"Student Attendance\",\n        \"is_query_report\": true,\n        \"label\": \"Student Monthly Attendance Sheet\",\n        \"name\": \"Student Monthly Attendance Sheet\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Student Attendance\"\n        ],\n        \"doctype\": \"Student Attendance\",\n        \"is_query_report\": true,\n        \"label\": \"Absent Student Report\",\n        \"name\": \"Absent Student Report\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Student Attendance\"\n        ],\n        \"doctype\": \"Student Attendance\",\n        \"is_query_report\": true,\n        \"label\": \"Student Batch-Wise Attendance\",\n        \"name\": \"Student Batch-Wise Attendance\",\n        \"type\": \"report\"\n    }\n]"
+  },
+  {
+   "hidden": 0,
+   "label": "LMS Activity",
+   "links": "[\n    {\n        \"label\": \"Course Enrollment\",\n        \"name\": \"Course Enrollment\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Course Activity\",\n        \"name\": \"Course Activity\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Quiz Activity\",\n        \"name\": \"Quiz Activity\",\n        \"type\": \"doctype\"\n    }\n]"
+  },
+  {
+   "hidden": 0,
+   "label": "Assessment",
+   "links": "[\n    {\n        \"label\": \"Assessment Plan\",\n        \"name\": \"Assessment Plan\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Assessment Group\",\n        \"link\": \"Tree/Assessment Group\",\n        \"name\": \"Assessment Group\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Assessment Result\",\n        \"name\": \"Assessment Result\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Assessment Criteria\",\n        \"name\": \"Assessment Criteria\",\n        \"type\": \"doctype\"\n    }\n]"
   },
   {
    "hidden": 0,
@@ -67,12 +57,22 @@
   },
   {
    "hidden": 0,
-   "label": "Reports",
-   "links": "[\n    {\n        \"dependencies\": [\n            \"Fees\"\n        ],\n        \"doctype\": \"Fees\",\n        \"is_query_report\": true,\n        \"label\": \"Student Fee Collection\",\n        \"name\": \"Student Fee Collection\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Student Attendance\"\n        ],\n        \"doctype\": \"Student Attendance\",\n        \"is_query_report\": true,\n        \"label\": \"Student Monthly Attendance Sheet\",\n        \"name\": \"Student Monthly Attendance Sheet\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Student Attendance\"\n        ],\n        \"doctype\": \"Student Attendance\",\n        \"is_query_report\": true,\n        \"label\": \"Absent Student Report\",\n        \"name\": \"Absent Student Report\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Program Enrollment\"\n        ],\n        \"doctype\": \"Program Enrollment\",\n        \"is_query_report\": true,\n        \"label\": \"Student and Guardian Contact Details\",\n        \"name\": \"Student and Guardian Contact Details\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Student Attendance\"\n        ],\n        \"doctype\": \"Student Attendance\",\n        \"is_query_report\": true,\n        \"label\": \"Student Batch-Wise Attendance\",\n        \"name\": \"Student Batch-Wise Attendance\",\n        \"type\": \"report\"\n    }\n]"
+   "label": "Tools",
+   "links": "[\n    {\n        \"label\": \"Student Attendance Tool\",\n        \"name\": \"Student Attendance Tool\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Assessment Result Tool\",\n        \"name\": \"Assessment Result Tool\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Student Group Creation Tool\",\n        \"name\": \"Student Group Creation Tool\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Program Enrollment Tool\",\n        \"name\": \"Program Enrollment Tool\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"label\": \"Course Scheduling Tool\",\n        \"name\": \"Course Scheduling Tool\",\n        \"type\": \"doctype\"\n    }\n]"
+  },
+  {
+   "hidden": 0,
+   "label": "Other Reports",
+   "links": "[\n    {\n        \"dependencies\": [\n            \"Program Enrollment\"\n        ],\n        \"doctype\": \"Program Enrollment\",\n        \"is_query_report\": true,\n        \"label\": \"Student and Guardian Contact Details\",\n        \"name\": \"Student and Guardian Contact Details\",\n        \"type\": \"report\"\n    }\n]"
   }
  ],
  "category": "Domains",
- "charts": [],
+ "charts": [
+  {
+   "chart_name": "Program Enrollments",
+   "label": "Program Enrollments"
+  }
+ ],
  "creation": "2020-03-02 17:22:57.066401",
  "developer_mode_only": 0,
  "disable_user_customization": 0,
@@ -84,13 +84,72 @@
  "idx": 0,
  "is_standard": 1,
  "label": "Education",
- "modified": "2020-06-30 18:36:17.013044",
+ "modified": "2020-07-27 19:35:18.832694",
  "modified_by": "Administrator",
  "module": "Education",
  "name": "Education",
+ "onboarding": "Education",
  "owner": "Administrator",
  "pin_to_bottom": 0,
  "pin_to_top": 0,
  "restrict_to_domain": "Education",
- "shortcuts": []
+ "shortcuts": [
+  {
+   "color": "#cef6d1",
+   "format": "{} Active",
+   "label": "Student",
+   "link_to": "Student",
+   "stats_filter": "{\n    \"enabled\": 1\n}",
+   "type": "DocType"
+  },
+  {
+   "color": "#cef6d1",
+   "format": "{} Active",
+   "label": "Instructor",
+   "link_to": "Instructor",
+   "stats_filter": "{\n    \"status\": \"Active\"\n}",
+   "type": "DocType"
+  },
+  {
+   "color": "",
+   "format": "",
+   "label": "Program",
+   "link_to": "Program",
+   "stats_filter": "",
+   "type": "DocType"
+  },
+  {
+   "label": "Course",
+   "link_to": "Course",
+   "type": "DocType"
+  },
+  {
+   "color": "#ffe8cd",
+   "format": "{} Unpaid",
+   "label": "Fees",
+   "link_to": "Fees",
+   "stats_filter": "{\n    \"outstanding_amount\": [\"!=\", 0.0]\n}",
+   "type": "DocType"
+  },
+  {
+   "label": "Student Monthly Attendance Sheet",
+   "link_to": "Student Monthly Attendance Sheet",
+   "type": "Report"
+  },
+  {
+   "label": "Course Scheduling Tool",
+   "link_to": "Course Scheduling Tool",
+   "type": "DocType"
+  },
+  {
+   "label": "Student Attendance Tool",
+   "link_to": "Student Attendance Tool",
+   "type": "DocType"
+  },
+  {
+   "label": "Dashboard",
+   "link_to": "Education",
+   "type": "Dashboard"
+  }
+ ]
 }
\ No newline at end of file
diff --git a/erpnext/education/doctype/assessment_result/assessment_result.js b/erpnext/education/doctype/assessment_result/assessment_result.js
index 12fdd91..63d1aee 100644
--- a/erpnext/education/doctype/assessment_result/assessment_result.js
+++ b/erpnext/education/doctype/assessment_result/assessment_result.js
@@ -6,10 +6,11 @@
 		if (!frm.doc.__islocal) {
 			frm.trigger('setup_chart');
 		}
+		frm.set_df_property('details', 'read_only', 1);
 	},
 
 	onload: function(frm) {
-		frm.set_query('assessment_plan', function(){
+		frm.set_query('assessment_plan', function() {
 			return {
 				filters: {
 					docstatus: 1
@@ -27,14 +28,14 @@
 				},
 				callback: function(r) {
 					if (r.message) {
-						frm.doc.details = [];
+						frappe.model.clear_table(frm.doc, 'details');
 						$.each(r.message, function(i, d) {
-							var row = frappe.model.add_child(frm.doc, 'Assessment Result Detail', 'details');
+							var row = frm.add_child('details');
 							row.assessment_criteria = d.assessment_criteria;
 							row.maximum_score = d.maximum_score;
 						});
+						frm.refresh_field('details');
 					}
-					refresh_field('details');
 				}
 			});
 		}
@@ -80,7 +81,7 @@
 	score: function(frm, cdt, cdn) {
 		var d  = locals[cdt][cdn];
 
-		if(!d.maximum_score || !frm.doc.grading_scale) {
+		if (!d.maximum_score || !frm.doc.grading_scale) {
 			d.score = '';
 			frappe.throw(__('Please fill in all the details to generate Assessment Result.'));
 		}
diff --git a/erpnext/education/doctype/assessment_result/assessment_result.json b/erpnext/education/doctype/assessment_result/assessment_result.json
index 212d47c..7a893aa 100644
--- a/erpnext/education/doctype/assessment_result/assessment_result.json
+++ b/erpnext/education/doctype/assessment_result/assessment_result.json
@@ -1,724 +1,182 @@
 {
- "allow_copy": 0,
- "allow_guest_to_view": 0,
+ "actions": [],
  "allow_import": 1,
- "allow_rename": 0,
  "autoname": "EDU-RES-.YYYY.-.#####",
- "beta": 0,
  "creation": "2015-11-13 17:18:06.468332",
- "custom": 0,
- "docstatus": 0,
  "doctype": "DocType",
- "document_type": "",
  "editable_grid": 1,
  "engine": "InnoDB",
+ "field_order": [
+  "assessment_plan",
+  "program",
+  "course",
+  "academic_year",
+  "academic_term",
+  "column_break_3",
+  "student",
+  "student_name",
+  "student_group",
+  "assessment_group",
+  "grading_scale",
+  "section_break_5",
+  "details",
+  "section_break_8",
+  "maximum_score",
+  "column_break_11",
+  "total_score",
+  "grade",
+  "section_break_13",
+  "comment",
+  "amended_from"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fieldname": "assessment_plan",
    "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": "Assessment Plan",
-   "length": 0,
-   "no_copy": 0,
    "options": "Assessment Plan",
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 1,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
+   "reqd": 1
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fetch_from": "assessment_plan.program",
    "fieldname": "program",
    "fieldtype": "Link",
-   "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": "Program",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Program",
-   "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
+   "options": "Program"
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fetch_from": "assessment_plan.course",
    "fieldname": "course",
    "fieldtype": "Link",
-   "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": "Course",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Course",
-   "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
+   "options": "Course"
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fetch_from": "assessment_plan.academic_year",
    "fieldname": "academic_year",
    "fieldtype": "Link",
-   "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": "Academic Year",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Academic Year",
-   "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
+   "options": "Academic Year"
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fetch_from": "assessment_plan.academic_term",
    "fieldname": "academic_term",
    "fieldtype": "Link",
-   "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": "Academic Term",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Academic Term",
-   "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
+   "options": "Academic Term"
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fieldname": "column_break_3",
-   "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,
-   "translatable": 0,
-   "unique": 0
+   "fieldtype": "Column Break"
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fieldname": "student",
    "fieldtype": "Link",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
    "in_global_search": 1,
-   "in_list_view": 0,
-   "in_standard_filter": 0,
    "label": "Student",
-   "length": 0,
-   "no_copy": 0,
    "options": "Student",
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 1,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
+   "reqd": 1
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fetch_from": "student.title",
    "fieldname": "student_name",
    "fieldtype": "Data",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
    "in_global_search": 1,
    "in_list_view": 1,
-   "in_standard_filter": 0,
    "label": "Student Name",
-   "length": 0,
-   "no_copy": 0,
-   "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,
-   "translatable": 0,
-   "unique": 0
+   "read_only": 1
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fetch_from": "assessment_plan.student_group",
    "fieldname": "student_group",
    "fieldtype": "Link",
-   "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": "Student Group",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Student Group",
-   "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
+   "options": "Student Group"
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fetch_from": "assessment_plan.assessment_group",
    "fieldname": "assessment_group",
    "fieldtype": "Link",
-   "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": "Assessment Group",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Assessment Group",
-   "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
+   "options": "Assessment Group"
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fetch_from": "assessment_plan.grading_scale",
    "fieldname": "grading_scale",
    "fieldtype": "Link",
-   "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": "Grading Scale",
-   "length": 0,
-   "no_copy": 0,
    "options": "Grading Scale",
-   "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,
-   "translatable": 0,
-   "unique": 0
+   "read_only": 1
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fieldname": "section_break_5",
    "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,
-   "label": "Result",
-   "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
+   "label": "Result"
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "depends_on": "",
    "fieldname": "details",
    "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": "Details",
-   "length": 0,
-   "no_copy": 0,
    "options": "Assessment Result Detail",
-   "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,
-   "translatable": 0,
-   "unique": 0
+   "reqd": 1
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fieldname": "section_break_8",
-   "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,
-   "translatable": 0,
-   "unique": 0
+   "fieldtype": "Section Break"
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fetch_from": "assessment_plan.maximum_assessment_score",
    "fieldname": "maximum_score",
    "fieldtype": "Float",
-   "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": "Maximum Score",
-   "length": 0,
-   "no_copy": 0,
-   "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,
-   "translatable": 0,
-   "unique": 0
+   "read_only": 1
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fetch_from": "assessment_plan.maximum_assessment_score",
    "fieldname": "column_break_11",
-   "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,
-   "translatable": 0,
-   "unique": 0
+   "fieldtype": "Column Break"
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fieldname": "total_score",
    "fieldtype": "Float",
-   "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": "Total Score",
-   "length": 0,
-   "no_copy": 0,
-   "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,
-   "translatable": 0,
-   "unique": 0
+   "read_only": 1
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fieldname": "grade",
    "fieldtype": "Data",
-   "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": "Grade",
-   "length": 0,
-   "no_copy": 0,
-   "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,
-   "translatable": 0,
-   "unique": 0
+   "read_only": 1
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fieldname": "section_break_13",
    "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,
-   "label": "Summary",
-   "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
+   "label": "Summary"
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fieldname": "comment",
    "fieldtype": "Small Text",
-   "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": "Comment",
-   "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
+   "label": "Comment"
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fieldname": "amended_from",
    "fieldtype": "Link",
-   "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": "Amended From",
-   "length": 0,
    "no_copy": 1,
    "options": "Assessment Result",
-   "permlevel": 0,
    "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,
-   "translatable": 0,
-   "unique": 0
+   "read_only": 1
   }
  ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
  "is_submittable": 1,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-08-30 02:10:36.813413",
+ "links": [],
+ "modified": "2020-08-03 11:47:54.119486",
  "modified_by": "Administrator",
  "module": "Education",
  "name": "Assessment Result",
- "name_case": "",
  "owner": "Administrator",
  "permissions": [
   {
@@ -728,28 +186,18 @@
    "delete": 1,
    "email": 1,
    "export": 1,
-   "if_owner": 0,
-   "import": 0,
-   "permlevel": 0,
    "print": 1,
    "read": 1,
    "report": 1,
    "role": "Academics User",
-   "set_user_permissions": 0,
    "share": 1,
    "submit": 1,
    "write": 1
   }
  ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
  "restrict_to_domain": "Education",
  "show_name_in_global_search": 1,
  "sort_field": "modified",
  "sort_order": "DESC",
- "title_field": "student_name",
- "track_changes": 0,
- "track_seen": 0,
- "track_views": 0
+ "title_field": "student_name"
 }
\ No newline at end of file
diff --git a/erpnext/education/doctype/assessment_result_detail/assessment_result_detail.json b/erpnext/education/doctype/assessment_result_detail/assessment_result_detail.json
index 85d943b..450f41c 100644
--- a/erpnext/education/doctype/assessment_result_detail/assessment_result_detail.json
+++ b/erpnext/education/doctype/assessment_result_detail/assessment_result_detail.json
@@ -1,194 +1,66 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "autoname": "", 
- "beta": 0, 
- "creation": "2016-12-14 17:44:35.583123", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "creation": "2016-12-14 17:44:35.583123",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "assessment_criteria",
+  "maximum_score",
+  "column_break_2",
+  "score",
+  "grade"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 4, 
-   "fieldname": "assessment_criteria", 
-   "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": "Assessment Criteria", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Assessment Criteria", 
-   "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
-  }, 
+   "columns": 4,
+   "fieldname": "assessment_criteria",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Assessment Criteria",
+   "options": "Assessment Criteria",
+   "read_only": 1,
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 2, 
-   "fieldname": "maximum_score", 
-   "fieldtype": "Float", 
-   "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": "Maximum Score", 
-   "length": 0, 
-   "no_copy": 0, 
-   "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
-  }, 
+   "columns": 2,
+   "fieldname": "maximum_score",
+   "fieldtype": "Float",
+   "in_list_view": 1,
+   "label": "Maximum Score",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_2", 
-   "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, 
-   "label": "", 
-   "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
-  }, 
+   "fieldname": "column_break_2",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 2, 
-   "fieldname": "score", 
-   "fieldtype": "Float", 
-   "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": "Score", 
-   "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": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "columns": 2,
+   "fieldname": "score",
+   "fieldtype": "Float",
+   "in_list_view": 1,
+   "label": "Score",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 2, 
-   "fieldname": "grade", 
-   "fieldtype": "Data", 
-   "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": "Grade", 
-   "length": 0, 
-   "no_copy": 0, 
-   "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
+   "columns": 2,
+   "fieldname": "grade",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Grade",
+   "read_only": 1
   }
- ], 
- "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-10 19:11:14.362410", 
- "modified_by": "Administrator", 
- "module": "Education", 
- "name": "Assessment Result Detail", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Education", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 0, 
- "track_seen": 0
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-07-31 13:27:17.699022",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Assessment Result Detail",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "restrict_to_domain": "Education",
+ "sort_field": "modified",
+ "sort_order": "DESC"
 }
\ No newline at end of file
diff --git a/erpnext/education/doctype/fees/fees.json b/erpnext/education/doctype/fees/fees.json
index 99f9f4f..0fb7672 100644
--- a/erpnext/education/doctype/fees/fees.json
+++ b/erpnext/education/doctype/fees/fees.json
@@ -160,7 +160,8 @@
    "in_list_view": 1,
    "in_standard_filter": 1,
    "label": "Program",
-   "options": "Program"
+   "options": "Program",
+   "reqd": 1
   },
   {
    "fieldname": "student_batch",
@@ -339,7 +340,7 @@
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2020-07-18 05:00:00.621010",
+ "modified": "2020-08-05 14:05:47.728409",
  "modified_by": "Administrator",
  "module": "Education",
  "name": "Fees",
diff --git a/erpnext/education/doctype/fees/test_fees.py b/erpnext/education/doctype/fees/test_fees.py
index b182992..eedc2ae 100644
--- a/erpnext/education/doctype/fees/test_fees.py
+++ b/erpnext/education/doctype/fees/test_fees.py
@@ -7,7 +7,7 @@
 import unittest
 from frappe.utils import nowdate
 from frappe.utils.make_random import get_random
-
+from erpnext.education.doctype.program.test_program import make_program_and_linked_courses
 
 # test_records = frappe.get_test_records('Fees')
 
@@ -15,6 +15,7 @@
 
 	def test_fees(self):
 		student = get_random("Student")
+		program = make_program_and_linked_courses("_Test Program 1", ["_Test Course 1", "_Test Course 2"])
 		fee = frappe.new_doc("Fees")
 		fee.posting_date = nowdate()
 		fee.due_date = nowdate()
@@ -23,6 +24,7 @@
 		fee.income_account = "Sales - _TC"
 		fee.cost_center = "_Test Cost Center - _TC"
 		fee.company = "_Test Company"
+		fee.program = program.name
 
 		fee.extend("components", [
 			{
diff --git a/erpnext/education/doctype/instructor/instructor.json b/erpnext/education/doctype/instructor/instructor.json
index 5367c0e..a417391 100644
--- a/erpnext/education/doctype/instructor/instructor.json
+++ b/erpnext/education/doctype/instructor/instructor.json
@@ -1,348 +1,125 @@
 {
- "allow_copy": 0, 
- "allow_events_in_timeline": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 0, 
- "autoname": "naming_series:", 
- "beta": 0, 
- "creation": "2015-11-04 15:56:30.004034", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "Other", 
- "editable_grid": 0, 
- "engine": "InnoDB", 
+ "actions": [],
+ "allow_import": 1,
+ "autoname": "naming_series:",
+ "creation": "2015-11-04 15:56:30.004034",
+ "doctype": "DocType",
+ "document_type": "Other",
+ "engine": "InnoDB",
+ "field_order": [
+  "instructor_name",
+  "employee",
+  "gender",
+  "column_break_5",
+  "status",
+  "naming_series",
+  "department",
+  "image",
+  "log_details",
+  "instructor_log"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "instructor_name", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 1, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Instructor Name", 
-   "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": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "instructor_name",
+   "fieldtype": "Data",
+   "in_global_search": 1,
+   "label": "Instructor Name",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "employee", 
-   "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", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Employee", 
-   "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
-  }, 
+   "fieldname": "employee",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Employee",
+   "options": "Employee"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_5", 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_5",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "default": "", 
-   "fieldname": "naming_series", 
-   "fieldtype": "Select", 
-   "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": "Naming Series", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "EDU-INS-.YYYY.-", 
-   "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": 1, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "naming_series",
+   "fieldtype": "Select",
+   "label": "Naming Series",
+   "options": "EDU-INS-.YYYY.-",
+   "set_only_once": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "employee.department", 
-   "fieldname": "department", 
-   "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": 1, 
-   "label": "Department", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Department", 
-   "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
-  }, 
+   "fetch_from": "employee.department",
+   "fieldname": "department",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
+   "label": "Department",
+   "options": "Department"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "image", 
-   "fieldtype": "Attach Image", 
-   "hidden": 1, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Image", 
-   "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
-  }, 
+   "fieldname": "image",
+   "fieldtype": "Attach Image",
+   "hidden": 1,
+   "label": "Image"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "log_details", 
-   "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, 
-   "label": "Instructor Log", 
-   "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
-  }, 
+   "fieldname": "log_details",
+   "fieldtype": "Section Break",
+   "label": "Instructor Log"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "instructor_log", 
-   "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": "Instructor Log", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Instructor Log", 
-   "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
+   "fieldname": "instructor_log",
+   "fieldtype": "Table",
+   "label": "Instructor Log",
+   "options": "Instructor Log"
+  },
+  {
+   "default": "Active",
+   "fieldname": "status",
+   "fieldtype": "Select",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
+   "label": "Status",
+   "options": "Active\nLeft"
+  },
+  {
+   "fetch_from": "employee.gender",
+   "fieldname": "gender",
+   "fieldtype": "Link",
+   "label": "Gender",
+   "options": "Gender",
+   "read_only_depends_on": "employee"
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_field": "image", 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "menu_index": 0, 
- "modified": "2019-01-30 11:28:17.571207", 
- "modified_by": "Administrator", 
- "module": "Education", 
- "name": "Instructor", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "image_field": "image",
+ "links": [],
+ "modified": "2020-07-23 18:33:57.904398",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Instructor",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 0, 
-   "delete": 0, 
-   "email": 1, 
-   "export": 0, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Instructor", 
-   "set_user_permissions": 0, 
-   "share": 0, 
-   "submit": 0, 
-   "write": 0
-  }, 
+   "email": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Instructor"
+  },
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Education Manager", 
-   "set_user_permissions": 1, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Education Manager",
+   "set_user_permissions": 1,
+   "share": 1,
    "write": 1
   }
- ], 
- "quick_entry": 0, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Education", 
- "show_name_in_global_search": 1, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "title_field": "instructor_name", 
- "track_changes": 0, 
- "track_seen": 0, 
- "track_views": 0
+ ],
+ "restrict_to_domain": "Education",
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "instructor_name"
 }
\ No newline at end of file
diff --git a/erpnext/education/doctype/program_enrollment/program_enrollment.py b/erpnext/education/doctype/program_enrollment/program_enrollment.py
index 7536172..3e27670 100644
--- a/erpnext/education/doctype/program_enrollment/program_enrollment.py
+++ b/erpnext/education/doctype/program_enrollment/program_enrollment.py
@@ -97,6 +97,7 @@
 		return quiz_progress
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_program_courses(doctype, txt, searchfield, start, page_len, filters):
 	if filters.get('program'):
 		return frappe.db.sql("""select course, course_name from `tabProgram Course`
@@ -115,6 +116,7 @@
 				})
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_students(doctype, txt, searchfield, start, page_len, filters):
 	if not filters.get("academic_term"):
 		filters["academic_term"] = frappe.defaults.get_defaults().academic_term
diff --git a/erpnext/education/doctype/student/student.json b/erpnext/education/doctype/student/student.json
index bee915e..ac65c0c 100644
--- a/erpnext/education/doctype/student/student.json
+++ b/erpnext/education/doctype/student/student.json
@@ -1,1353 +1,305 @@
 {
- "allow_copy": 0, 
- "allow_events_in_timeline": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 1, 
- "autoname": "naming_series:", 
- "beta": 0, 
- "creation": "2015-09-07 13:00:55.938280", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "Document", 
- "editable_grid": 0, 
- "engine": "InnoDB", 
+ "actions": [],
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "naming_series:",
+ "creation": "2015-09-07 13:00:55.938280",
+ "doctype": "DocType",
+ "document_type": "Document",
+ "engine": "InnoDB",
+ "field_order": [
+  "section_break_1",
+  "enabled",
+  "section_break_3",
+  "first_name",
+  "middle_name",
+  "last_name",
+  "user",
+  "column_break_4",
+  "naming_series",
+  "student_email_id",
+  "student_mobile_number",
+  "joining_date",
+  "image",
+  "section_break_7",
+  "date_of_birth",
+  "blood_group",
+  "column_break_3",
+  "gender",
+  "nationality",
+  "student_applicant",
+  "section_break_22",
+  "address_line_1",
+  "address_line_2",
+  "pincode",
+  "column_break_20",
+  "city",
+  "state",
+  "section_break_18",
+  "guardians",
+  "section_break_20",
+  "siblings",
+  "exit",
+  "date_of_leaving",
+  "leaving_certificate_number",
+  "column_break_31",
+  "reason_for_leaving",
+  "title"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "section_break_1", 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "section_break_1",
+   "fieldtype": "Section Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "default": "1", 
-   "fetch_if_empty": 0, 
-   "fieldname": "enabled", 
-   "fieldtype": "Check", 
-   "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": "Enabled", 
-   "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
-  }, 
+   "default": "1",
+   "fieldname": "enabled",
+   "fieldtype": "Check",
+   "label": "Enabled"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "section_break_3", 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "section_break_3",
+   "fieldtype": "Section Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "first_name", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 1, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "First Name", 
-   "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": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "first_name",
+   "fieldtype": "Data",
+   "in_global_search": 1,
+   "label": "First Name",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "middle_name", 
-   "fieldtype": "Data", 
-   "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": "Middle Name", 
-   "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
-  }, 
+   "fieldname": "middle_name",
+   "fieldtype": "Data",
+   "label": "Middle Name"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "last_name", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 1, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Last Name", 
-   "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
-  }, 
+   "fieldname": "last_name",
+   "fieldtype": "Data",
+   "in_global_search": 1,
+   "label": "Last Name"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "user", 
-   "fieldtype": "Link", 
-   "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": "User ID", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "User", 
-   "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
-  }, 
+   "fieldname": "user",
+   "fieldtype": "Link",
+   "label": "User ID",
+   "options": "User"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_4",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "default": "", 
-   "fetch_if_empty": 0, 
-   "fieldname": "naming_series", 
-   "fieldtype": "Select", 
-   "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": "Naming Series", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "EDU-STU-.YYYY.-", 
-   "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": 1, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "naming_series",
+   "fieldtype": "Select",
+   "label": "Naming Series",
+   "no_copy": 1,
+   "options": "EDU-STU-.YYYY.-",
+   "set_only_once": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "student_email_id", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 1, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Student Email Address", 
-   "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": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
+   "fieldname": "student_email_id",
+   "fieldtype": "Data",
+   "in_global_search": 1,
+   "label": "Student Email Address",
+   "reqd": 1,
    "unique": 1
-  }, 
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "student_mobile_number", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 1, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Student Mobile Number", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "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
-  }, 
+   "fieldname": "student_mobile_number",
+   "fieldtype": "Data",
+   "in_global_search": 1,
+   "label": "Student Mobile Number"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "default": "Today", 
-   "fetch_if_empty": 0, 
-   "fieldname": "joining_date", 
-   "fieldtype": "Date", 
-   "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": "Joining 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
-  }, 
+   "default": "Today",
+   "fieldname": "joining_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "Joining Date"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "image", 
-   "fieldtype": "Attach Image", 
-   "hidden": 1, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Image", 
-   "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, 
+   "fieldname": "image",
+   "fieldtype": "Attach Image",
+   "hidden": 1,
+   "label": "Image",
    "width": "10"
-  }, 
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "collapsible_depends_on": "", 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "section_break_7", 
-   "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, 
-   "label": "Personal Details", 
-   "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
-  }, 
+   "fieldname": "section_break_7",
+   "fieldtype": "Section Break",
+   "label": "Personal Details"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "date_of_birth", 
-   "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": "Date of Birth", 
-   "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
-  }, 
+   "fieldname": "date_of_birth",
+   "fieldtype": "Date",
+   "label": "Date of Birth"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "blood_group", 
-   "fieldtype": "Select", 
-   "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": "Blood Group", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "\nA+\nA-\nB+\nB-\nO+\nO-\nAB+\nAB-", 
-   "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
-  }, 
+   "fieldname": "blood_group",
+   "fieldtype": "Select",
+   "label": "Blood Group",
+   "options": "\nA+\nA-\nB+\nB-\nO+\nO-\nAB+\nAB-"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "column_break_3", 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "gender", 
-   "fieldtype": "Select", 
-   "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": "Gender", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "\nMale\nFemale\nOther", 
-   "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
-  }, 
+   "fieldname": "gender",
+   "fieldtype": "Link",
+   "label": "Gender",
+   "options": "Gender"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "nationality", 
-   "fieldtype": "Data", 
-   "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": "Nationality", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "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
-  }, 
+   "fieldname": "nationality",
+   "fieldtype": "Data",
+   "label": "Nationality"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "student_applicant", 
-   "fieldtype": "Link", 
-   "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": "Student Applicant", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Student Applicant", 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "student_applicant",
+   "fieldtype": "Link",
+   "label": "Student Applicant",
+   "options": "Student Applicant",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "section_break_22", 
-   "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, 
-   "label": "Home Address", 
-   "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
-  }, 
+   "fieldname": "section_break_22",
+   "fieldtype": "Section Break",
+   "label": "Home Address"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "address_line_1", 
-   "fieldtype": "Data", 
-   "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": "Address Line 1", 
-   "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
-  }, 
+   "fieldname": "address_line_1",
+   "fieldtype": "Data",
+   "label": "Address Line 1"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "address_line_2", 
-   "fieldtype": "Data", 
-   "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": "Address Line 2", 
-   "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
-  }, 
+   "fieldname": "address_line_2",
+   "fieldtype": "Data",
+   "label": "Address Line 2"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "pincode", 
-   "fieldtype": "Data", 
-   "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": "Pincode", 
-   "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
-  }, 
+   "fieldname": "pincode",
+   "fieldtype": "Data",
+   "label": "Pincode"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "column_break_20", 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_20",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "city", 
-   "fieldtype": "Data", 
-   "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": "City", 
-   "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
-  }, 
+   "fieldname": "city",
+   "fieldtype": "Data",
+   "label": "City"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "state", 
-   "fieldtype": "Data", 
-   "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": "State", 
-   "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
-  }, 
+   "fieldname": "state",
+   "fieldtype": "Data",
+   "label": "State"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "section_break_18", 
-   "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, 
-   "label": "Guardian Details", 
-   "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
-  }, 
+   "fieldname": "section_break_18",
+   "fieldtype": "Section Break",
+   "label": "Guardian Details"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "guardians", 
-   "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": "Guardians", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Student Guardian", 
-   "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
-  }, 
+   "fieldname": "guardians",
+   "fieldtype": "Table",
+   "label": "Guardians",
+   "options": "Student Guardian"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 1, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "section_break_20", 
-   "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, 
-   "label": "Sibling Details", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Country", 
-   "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
-  }, 
+   "collapsible": 1,
+   "fieldname": "section_break_20",
+   "fieldtype": "Section Break",
+   "label": "Sibling Details",
+   "options": "Country"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "siblings", 
-   "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": "Siblings", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Student Sibling", 
-   "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
-  }, 
+   "fieldname": "siblings",
+   "fieldtype": "Table",
+   "label": "Siblings",
+   "options": "Student Sibling"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 1, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "exit", 
-   "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, 
-   "label": "Exit", 
-   "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
-  }, 
+   "collapsible": 1,
+   "fieldname": "exit",
+   "fieldtype": "Section Break",
+   "label": "Exit"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "date_of_leaving", 
-   "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": "Date of Leaving", 
-   "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
-  }, 
+   "fieldname": "date_of_leaving",
+   "fieldtype": "Date",
+   "label": "Date of Leaving"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "leaving_certificate_number", 
-   "fieldtype": "Data", 
-   "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": "Leaving Certificate Number", 
-   "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
-  }, 
+   "fieldname": "leaving_certificate_number",
+   "fieldtype": "Data",
+   "label": "Leaving Certificate Number"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "column_break_31", 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_31",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "reason_for_leaving", 
-   "fieldtype": "Text", 
-   "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": "Reason For Leaving", 
-   "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
-  }, 
+   "fieldname": "reason_for_leaving",
+   "fieldtype": "Text",
+   "label": "Reason For Leaving"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "default": "", 
-   "fetch_if_empty": 0, 
-   "fieldname": "title", 
-   "fieldtype": "Data", 
-   "hidden": 1, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Title", 
-   "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
+   "fieldname": "title",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Title"
   }
- ], 
- "has_web_view": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_field": "image", 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "menu_index": 0, 
- "modified": "2019-04-10 17:46:26.893020", 
- "modified_by": "Administrator", 
- "module": "Education", 
- "name": "Student", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "image_field": "image",
+ "links": [],
+ "modified": "2020-07-23 18:14:06.366442",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Student",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 0, 
-   "delete": 0, 
-   "email": 0, 
-   "export": 0, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 0, 
-   "read": 1, 
-   "report": 0, 
-   "role": "Instructor", 
-   "set_user_permissions": 0, 
-   "share": 0, 
-   "submit": 0, 
-   "write": 0
-  }, 
+   "read": 1,
+   "role": "Instructor"
+  },
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 1, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Academics User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "import": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Academics User",
+   "share": 1,
    "write": 1
-  }, 
+  },
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 0, 
-   "delete": 0, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Student", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 0
-  }, 
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Student",
+   "share": 1
+  },
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 0, 
-   "delete": 0, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "LMS User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 0
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "LMS User",
+   "share": 1
   }
- ], 
- "quick_entry": 0, 
- "read_only": 0, 
- "restrict_to_domain": "Education", 
- "show_name_in_global_search": 1, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "title_field": "title", 
- "track_changes": 0, 
- "track_seen": 0, 
- "track_views": 0
+ ],
+ "restrict_to_domain": "Education",
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "title"
 }
\ No newline at end of file
diff --git a/erpnext/education/doctype/student_group/student_group.py b/erpnext/education/doctype/student_group/student_group.py
index 8b61c89..0260b80 100644
--- a/erpnext/education/doctype/student_group/student_group.py
+++ b/erpnext/education/doctype/student_group/student_group.py
@@ -108,6 +108,7 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def fetch_students(doctype, txt, searchfield, start, page_len, filters):
 	if filters.get("group_based_on") != "Activity":
 		enrolled_students = get_program_enrollment(filters.get('academic_year'), filters.get('academic_term'),
diff --git a/erpnext/education/education_dashboard/education/education.json b/erpnext/education/education_dashboard/education/education.json
new file mode 100644
index 0000000..41d3375
--- /dev/null
+++ b/erpnext/education/education_dashboard/education/education.json
@@ -0,0 +1,62 @@
+{
+ "cards": [
+  {
+   "card": "Total Students"
+  },
+  {
+   "card": "Total Instructors"
+  },
+  {
+   "card": "Program Enrollments"
+  },
+  {
+   "card": "Student Applicants to Review"
+  }
+ ],
+ "charts": [
+  {
+   "chart": "Program Enrollments",
+   "width": "Full"
+  },
+  {
+   "chart": "Program wise Enrollment",
+   "width": "Half"
+  },
+  {
+   "chart": "Course wise Enrollment",
+   "width": "Half"
+  },
+  {
+   "chart": "Course wise Student Count",
+   "width": "Half"
+  },
+  {
+   "chart": "Student Category wise Program Enrollments",
+   "width": "Half"
+  },
+  {
+   "chart": "Student Gender Diversity Ratio",
+   "width": "Half"
+  },
+  {
+   "chart": "Instructor Gender Diversity Ratio",
+   "width": "Half"
+  },
+  {
+   "chart": "Program wise Fee Collection",
+   "width": "Full"
+  }
+ ],
+ "creation": "2020-07-22 18:51:02.195762",
+ "dashboard_name": "Education",
+ "docstatus": 0,
+ "doctype": "Dashboard",
+ "idx": 0,
+ "is_default": 0,
+ "is_standard": 1,
+ "modified": "2020-08-05 16:22:17.428101",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Education",
+ "owner": "Administrator"
+}
\ No newline at end of file
diff --git a/erpnext/education/module_onboarding/education/education.json b/erpnext/education/module_onboarding/education/education.json
new file mode 100644
index 0000000..e5f0fec
--- /dev/null
+++ b/erpnext/education/module_onboarding/education/education.json
@@ -0,0 +1,50 @@
+{
+ "allow_roles": [
+  {
+   "role": "Education Manager"
+  }
+ ],
+ "creation": "2020-07-27 19:02:49.561391",
+ "docstatus": 0,
+ "doctype": "Module Onboarding",
+ "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/education",
+ "idx": 0,
+ "is_complete": 0,
+ "modified": "2020-07-27 21:10:46.722961",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Education",
+ "owner": "Administrator",
+ "steps": [
+  {
+   "step": "Create a Student"
+  },
+  {
+   "step": "Create an Instructor"
+  },
+  {
+   "step": "Introduction to Program and Courses"
+  },
+  {
+   "step": "Create a Topic"
+  },
+  {
+   "step": "Create a Course"
+  },
+  {
+   "step": "Create a Program"
+  },
+  {
+   "step": "Enroll a Student in a Program"
+  },
+  {
+   "step": "Introduction to Student Group"
+  },
+  {
+   "step": "Introduction to Student Attendance"
+  }
+ ],
+ "subtitle": "Students, Instructors, Programs and more.",
+ "success_message": "The Education Module is all set up!",
+ "title": "Let's Set Up the Education Module."
+}
diff --git a/erpnext/education/number_card/program_enrollments/program_enrollments.json b/erpnext/education/number_card/program_enrollments/program_enrollments.json
new file mode 100644
index 0000000..5847679
--- /dev/null
+++ b/erpnext/education/number_card/program_enrollments/program_enrollments.json
@@ -0,0 +1,23 @@
+{
+ "aggregate_function_based_on": "",
+ "creation": "2020-07-27 18:26:27.005186",
+ "docstatus": 0,
+ "doctype": "Number Card",
+ "document_type": "Program Enrollment",
+ "dynamic_filters_json": "[]",
+ "filters_json": "[[\"Program Enrollment\",\"docstatus\",\"=\",\"1\",false],[\"Program Enrollment\",\"enrollment_date\",\"Timespan\",\"this year\",false]]",
+ "function": "Count",
+ "idx": 0,
+ "is_public": 1,
+ "is_standard": 1,
+ "label": "Program Enrollments",
+ "modified": "2020-07-27 18:26:32.512624",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Program Enrollments",
+ "owner": "Administrator",
+ "report_function": "Sum",
+ "show_percentage_stats": 1,
+ "stats_time_interval": "Yearly",
+ "type": "Document Type"
+}
\ No newline at end of file
diff --git a/erpnext/education/number_card/student_applicants_to_review/student_applicants_to_review.json b/erpnext/education/number_card/student_applicants_to_review/student_applicants_to_review.json
new file mode 100644
index 0000000..258667a
--- /dev/null
+++ b/erpnext/education/number_card/student_applicants_to_review/student_applicants_to_review.json
@@ -0,0 +1,23 @@
+{
+ "aggregate_function_based_on": "",
+ "creation": "2020-07-27 18:42:33.366862",
+ "docstatus": 0,
+ "doctype": "Number Card",
+ "document_type": "Student Applicant",
+ "dynamic_filters_json": "[]",
+ "filters_json": "[[\"Student Applicant\",\"application_status\",\"=\",\"Applied\",false]]",
+ "function": "Count",
+ "idx": 0,
+ "is_public": 1,
+ "is_standard": 1,
+ "label": "Student Applicants to Review",
+ "modified": "2020-07-27 18:42:42.739710",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Student Applicants to Review",
+ "owner": "Administrator",
+ "report_function": "Sum",
+ "show_percentage_stats": 1,
+ "stats_time_interval": "Monthly",
+ "type": "Document Type"
+}
\ No newline at end of file
diff --git a/erpnext/education/number_card/total_instructors/total_instructors.json b/erpnext/education/number_card/total_instructors/total_instructors.json
new file mode 100644
index 0000000..b8d3cc0
--- /dev/null
+++ b/erpnext/education/number_card/total_instructors/total_instructors.json
@@ -0,0 +1,23 @@
+{
+ "aggregate_function_based_on": "",
+ "creation": "2020-07-23 14:19:38.423190",
+ "docstatus": 0,
+ "doctype": "Number Card",
+ "document_type": "Instructor",
+ "dynamic_filters_json": "[]",
+ "filters_json": "[[\"Instructor\",\"status\",\"=\",\"Active\",false]]",
+ "function": "Count",
+ "idx": 0,
+ "is_public": 1,
+ "is_standard": 1,
+ "label": "Total Instructors",
+ "modified": "2020-07-23 14:19:47.623306",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Total Instructors",
+ "owner": "Administrator",
+ "report_function": "Sum",
+ "show_percentage_stats": 1,
+ "stats_time_interval": "Monthly",
+ "type": "Document Type"
+}
\ No newline at end of file
diff --git a/erpnext/education/number_card/total_students/total_students.json b/erpnext/education/number_card/total_students/total_students.json
new file mode 100644
index 0000000..109c3d8
--- /dev/null
+++ b/erpnext/education/number_card/total_students/total_students.json
@@ -0,0 +1,23 @@
+{
+ "aggregate_function_based_on": "",
+ "creation": "2020-07-23 14:18:07.732298",
+ "docstatus": 0,
+ "doctype": "Number Card",
+ "document_type": "Student",
+ "dynamic_filters_json": "[]",
+ "filters_json": "[[\"Student\",\"enabled\",\"=\",1,false]]",
+ "function": "Count",
+ "idx": 0,
+ "is_public": 1,
+ "is_standard": 1,
+ "label": "Total Students",
+ "modified": "2020-07-23 14:18:40.603947",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Total Students",
+ "owner": "Administrator",
+ "report_function": "Sum",
+ "show_percentage_stats": 1,
+ "stats_time_interval": "Monthly",
+ "type": "Document Type"
+}
\ No newline at end of file
diff --git a/erpnext/education/onboarding_step/create_a_course/create_a_course.json b/erpnext/education/onboarding_step/create_a_course/create_a_course.json
new file mode 100644
index 0000000..02eee14
--- /dev/null
+++ b/erpnext/education/onboarding_step/create_a_course/create_a_course.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-07-27 19:09:04.493932",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-07-27 19:09:04.493932",
+ "modified_by": "Administrator",
+ "name": "Create a Course",
+ "owner": "Administrator",
+ "reference_document": "Course",
+ "show_full_form": 1,
+ "title": "Create a Course",
+ "validate_action": 1
+}
\ No newline at end of file
diff --git a/erpnext/education/onboarding_step/create_a_program/create_a_program.json b/erpnext/education/onboarding_step/create_a_program/create_a_program.json
new file mode 100644
index 0000000..6172630
--- /dev/null
+++ b/erpnext/education/onboarding_step/create_a_program/create_a_program.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-07-27 19:09:35.451945",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-07-27 19:09:35.451945",
+ "modified_by": "Administrator",
+ "name": "Create a Program",
+ "owner": "Administrator",
+ "reference_document": "Program",
+ "show_full_form": 1,
+ "title": "Create a Program",
+ "validate_action": 1
+}
\ No newline at end of file
diff --git a/erpnext/education/onboarding_step/create_a_student/create_a_student.json b/erpnext/education/onboarding_step/create_a_student/create_a_student.json
new file mode 100644
index 0000000..07c3f73
--- /dev/null
+++ b/erpnext/education/onboarding_step/create_a_student/create_a_student.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-07-27 19:17:20.326837",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 1,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-07-27 19:49:47.724289",
+ "modified_by": "Administrator",
+ "name": "Create a Student",
+ "owner": "Administrator",
+ "reference_document": "Student",
+ "show_full_form": 1,
+ "title": "Create a Student",
+ "validate_action": 1
+}
\ No newline at end of file
diff --git a/erpnext/education/onboarding_step/create_a_topic/create_a_topic.json b/erpnext/education/onboarding_step/create_a_topic/create_a_topic.json
new file mode 100644
index 0000000..96a5364
--- /dev/null
+++ b/erpnext/education/onboarding_step/create_a_topic/create_a_topic.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-07-27 19:08:40.754534",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-07-27 19:09:13.231995",
+ "modified_by": "Administrator",
+ "name": "Create a Topic",
+ "owner": "Administrator",
+ "reference_document": "Topic",
+ "show_full_form": 1,
+ "title": "Create a Topic",
+ "validate_action": 1
+}
\ No newline at end of file
diff --git a/erpnext/education/onboarding_step/create_an_instructor/create_an_instructor.json b/erpnext/education/onboarding_step/create_an_instructor/create_an_instructor.json
new file mode 100644
index 0000000..419d6e0
--- /dev/null
+++ b/erpnext/education/onboarding_step/create_an_instructor/create_an_instructor.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-07-27 19:17:39.158037",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 1,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-07-27 19:49:47.723494",
+ "modified_by": "Administrator",
+ "name": "Create an Instructor",
+ "owner": "Administrator",
+ "reference_document": "Instructor",
+ "show_full_form": 1,
+ "title": "Create an Instructor",
+ "validate_action": 1
+}
\ No newline at end of file
diff --git a/erpnext/education/onboarding_step/enroll_a_student_in_a_program/enroll_a_student_in_a_program.json b/erpnext/education/onboarding_step/enroll_a_student_in_a_program/enroll_a_student_in_a_program.json
new file mode 100644
index 0000000..61e48cd
--- /dev/null
+++ b/erpnext/education/onboarding_step/enroll_a_student_in_a_program/enroll_a_student_in_a_program.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-07-27 19:10:28.530226",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-07-27 19:10:28.530226",
+ "modified_by": "Administrator",
+ "name": "Enroll a Student in a Program",
+ "owner": "Administrator",
+ "reference_document": "Program Enrollment",
+ "show_full_form": 0,
+ "title": "Enroll a Student in a Program",
+ "validate_action": 1
+}
\ No newline at end of file
diff --git a/erpnext/education/onboarding_step/introduction_to_program_and_courses/introduction_to_program_and_courses.json b/erpnext/education/onboarding_step/introduction_to_program_and_courses/introduction_to_program_and_courses.json
new file mode 100644
index 0000000..a9ddfc0
--- /dev/null
+++ b/erpnext/education/onboarding_step/introduction_to_program_and_courses/introduction_to_program_and_courses.json
@@ -0,0 +1,19 @@
+{
+ "action": "Watch Video",
+ "creation": "2020-07-27 19:05:12.663987",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-07-27 20:18:11.831789",
+ "modified_by": "Administrator",
+ "name": "Introduction to Program and Courses",
+ "owner": "Administrator",
+ "show_full_form": 0,
+ "title": "Introduction to Program and Courses",
+ "validate_action": 1,
+ "video_url": "https://www.youtube.com/watch?v=1ueE4seFTp8"
+}
\ No newline at end of file
diff --git a/erpnext/education/onboarding_step/introduction_to_student_attendance/introduction_to_student_attendance.json b/erpnext/education/onboarding_step/introduction_to_student_attendance/introduction_to_student_attendance.json
new file mode 100644
index 0000000..3de9972
--- /dev/null
+++ b/erpnext/education/onboarding_step/introduction_to_student_attendance/introduction_to_student_attendance.json
@@ -0,0 +1,19 @@
+{
+ "action": "Watch Video",
+ "creation": "2020-07-27 19:14:57.176131",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-07-27 19:55:55.411032",
+ "modified_by": "Administrator",
+ "name": "Introduction to Student Attendance",
+ "owner": "Administrator",
+ "show_full_form": 0,
+ "title": "Introduction to Student Attendance",
+ "validate_action": 1,
+ "video_url": "https://youtu.be/j9pgkPuyiaI"
+}
\ No newline at end of file
diff --git a/erpnext/education/onboarding_step/introduction_to_student_group/introduction_to_student_group.json b/erpnext/education/onboarding_step/introduction_to_student_group/introduction_to_student_group.json
new file mode 100644
index 0000000..74bdcd1
--- /dev/null
+++ b/erpnext/education/onboarding_step/introduction_to_student_group/introduction_to_student_group.json
@@ -0,0 +1,20 @@
+{
+ "action": "Watch Video",
+ "creation": "2020-07-27 19:12:05.046465",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-07-27 19:42:47.286441",
+ "modified_by": "Administrator",
+ "name": "Introduction to Student Group",
+ "owner": "Administrator",
+ "reference_document": "Student Group",
+ "show_full_form": 0,
+ "title": "Introduction to Student Group",
+ "validate_action": 1,
+ "video_url": "https://youtu.be/5K_smeeE1Q4"
+}
\ No newline at end of file
diff --git a/erpnext/education/report/program_wise_fee_collection/__init__.py b/erpnext/education/report/program_wise_fee_collection/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/report/program_wise_fee_collection/__init__.py
diff --git a/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.js b/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.js
new file mode 100644
index 0000000..72e8f12
--- /dev/null
+++ b/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Program wise Fee Collection"] = {
+	"filters": [
+		{
+			"fieldname": "from_date",
+			"label": __("From Date"),
+			"fieldtype": "Date",
+			"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
+			"reqd": 1
+		},
+		{
+			"fieldname": "to_date",
+			"label": __("To Date"),
+			"fieldtype": "Date",
+			"default": frappe.datetime.get_today(),
+			"reqd": 1
+		}
+	]
+};
diff --git a/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.json b/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.json
new file mode 100644
index 0000000..ee5c0de
--- /dev/null
+++ b/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.json
@@ -0,0 +1,32 @@
+{
+ "add_total_row": 1,
+ "creation": "2020-07-27 16:05:33.263539",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "json": "{}",
+ "modified": "2020-08-05 14:14:12.410515",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Program wise Fee Collection",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "query": "SELECT \n    FeesCollected.program AS \"Program:Link/Program:200\",\n    FeesCollected.paid_amount AS \"Fees Collected:Currency:150\",\n    FeesCollected.outstanding_amount AS \"Outstanding Amount:Currency:150\",\n    FeesCollected.grand_total \"Grand Total:Currency:150\"\nFROM (\n    SELECT \n        sum(grand_total) - sum(outstanding_amount) AS paid_amount, program,\n        sum(outstanding_amount) AS outstanding_amount,\n        sum(grand_total) AS grand_total\n    FROM `tabFees`\n    WHERE docstatus = 1\n    GROUP BY program\n) AS FeesCollected\nORDER BY FeesCollected.paid_amount DESC",
+ "ref_doctype": "Fees",
+ "report_name": "Program wise Fee Collection",
+ "report_type": "Script Report",
+ "roles": [
+  {
+   "role": "Academics User"
+  },
+  {
+   "role": "Accounts User"
+  },
+  {
+   "role": "Accounts Manager"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.py b/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.py
new file mode 100644
index 0000000..c145359
--- /dev/null
+++ b/erpnext/education/report/program_wise_fee_collection/program_wise_fee_collection.py
@@ -0,0 +1,124 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+
+def execute(filters=None):
+	if not filters:
+		filters = {}
+
+	columns = get_columns(filters)
+	data = get_data(filters)
+	chart = get_chart_data(data)
+
+	return columns, data, None, chart
+
+def get_columns(filters=None):
+	return [
+		{
+			'label': _('Program'),
+			'fieldname': 'program',
+			'fieldtype': 'Link',
+			'options': 'Program',
+			'width': 300
+		},
+		{
+			'label': _('Fees Collected'),
+			'fieldname': 'fees_collected',
+			'fieldtype': 'Currency',
+			'width': 200
+		},
+		{
+			'label': _('Outstanding Amount'),
+			'fieldname': 'outstanding_amount',
+			'fieldtype': 'Currency',
+			'width': 200
+		},
+		{
+			'label': _('Grand Total'),
+			'fieldname': 'grand_total',
+			'fieldtype': 'Currency',
+			'width': 200
+		}
+	]
+
+
+def get_data(filters=None):
+	data = []
+
+	conditions = get_filter_conditions(filters)
+
+	fee_details = frappe.db.sql(
+		"""
+			SELECT
+				FeesCollected.program,
+				FeesCollected.paid_amount,
+				FeesCollected.outstanding_amount,
+				FeesCollected.grand_total
+			FROM (
+				SELECT
+					sum(grand_total) - sum(outstanding_amount) AS paid_amount, program,
+					sum(outstanding_amount) AS outstanding_amount,
+					sum(grand_total) AS grand_total
+				FROM `tabFees`
+				WHERE
+					docstatus = 1 and
+					program IS NOT NULL
+					%s
+				GROUP BY program
+			) AS FeesCollected
+			ORDER BY FeesCollected.paid_amount DESC
+		""" % (conditions)
+	, as_dict=1)
+
+	for entry in fee_details:
+		data.append({
+			'program': entry.program,
+			'fees_collected': entry.paid_amount,
+			'outstanding_amount': entry.outstanding_amount,
+			'grand_total': entry.grand_total
+		})
+
+	return data
+
+def get_filter_conditions(filters):
+	conditions = ''
+
+	if filters.get('from_date') and filters.get('to_date'):
+		conditions += " and posting_date BETWEEN '%s' and '%s'" % (filters.get('from_date'), filters.get('to_date'))
+
+	return conditions
+
+
+def get_chart_data(data):
+	if not data:
+		return
+
+	labels = []
+	fees_collected = []
+	outstanding_amount = []
+
+	for entry in data:
+		labels.append(entry.get('program'))
+		fees_collected.append(entry.get('fees_collected'))
+		outstanding_amount.append(entry.get('outstanding_amount'))
+
+	return {
+		'data': {
+			'labels': labels,
+			'datasets': [
+				{
+					'name': _('Fees Collected'),
+					'values': fees_collected
+				},
+				{
+					'name': _('Outstanding Amt'),
+					'values': outstanding_amount
+				}
+			]
+		},
+		'type': 'bar'
+	}
+
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
index 3dc7c1e..5da5a06 100644
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
@@ -71,6 +71,7 @@
 		frappe.throw(_(msg))
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_practitioner_list(doctype, txt, searchfield, start, page_len, filters=None):
 	fields = ['name', 'practitioner_name', 'mobile_phone']
 
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js
index 971e166..60f0f9d 100644
--- a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js
+++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js
@@ -134,7 +134,7 @@
 			{fieldtype: 'Link', label: 'Leave From', fieldname: 'leave_from', options: 'Healthcare Service Unit', reqd: 1, read_only:1},
 			{fieldtype: 'Link', label: 'Service Unit Type', fieldname: 'service_unit_type', options: 'Healthcare Service Unit Type'},
 			{fieldtype: 'Link', label: 'Transfer To', fieldname: 'service_unit', options: 'Healthcare Service Unit', reqd: 1},
-			{fieldtype: 'Datetime', label: 'Check In', fieldname: 'check_in', reqd: 1}
+			{fieldtype: 'Datetime', label: 'Check In', fieldname: 'check_in', reqd: 1, default: frappe.datetime.now_datetime()}
 		],
 		primary_action_label: __('Transfer'),
 		primary_action : function() {
@@ -147,7 +147,12 @@
 			if(dialog.get_value('service_unit')){
 				service_unit = dialog.get_value('service_unit');
 			}
-			if(!check_in){
+			if(check_in > frappe.datetime.now_datetime()){
+				frappe.msgprint({
+					title: __('Not Allowed'),
+					message: __('Check-in time cannot be greater than the current time'),
+					indicator: 'red'
+				});
 				return;
 			}
 			frappe.call({
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
index 69356ba..bc76970 100644
--- a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
+++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
@@ -222,6 +222,7 @@
 	inpatient_record.save(ignore_permissions = True)
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_leave_from(doctype, txt, searchfield, start, page_len, filters):
 	docname = filters['docname']
 
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 95a836f..463ad6c 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -322,7 +322,8 @@
 		"erpnext.crm.doctype.email_campaign.email_campaign.set_email_campaign_status",
 		"erpnext.selling.doctype.quotation.quotation.set_expired_status",
 		"erpnext.healthcare.doctype.patient_appointment.patient_appointment.update_appointment_status",
-		"erpnext.buying.doctype.supplier_quotation.supplier_quotation.set_expired_status"
+		"erpnext.buying.doctype.supplier_quotation.supplier_quotation.set_expired_status",
+		"erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.send_auto_email"
 	],
 	"daily_long": [
 		"erpnext.setup.doctype.email_digest.email_digest.send",
diff --git a/erpnext/hr/desk_page/hr/hr.json b/erpnext/hr/desk_page/hr/hr.json
index bcc4ac5..217b94a 100644
--- a/erpnext/hr/desk_page/hr/hr.json
+++ b/erpnext/hr/desk_page/hr/hr.json
@@ -94,7 +94,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "HR",
- "modified": "2020-06-30 18:34:39.966096",
+ "modified": "2020-08-11 17:04:38.655417",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "HR",
@@ -126,8 +126,8 @@
    "type": "DocType"
   },
   {
-   "label": "Salary Structure",
-   "link_to": "Salary Structure",
+   "label": "Job Applicant",
+   "link_to": "Job Applicant",
    "type": "DocType"
   },
   {
diff --git a/erpnext/hr/doctype/department/department.json b/erpnext/hr/doctype/department/department.json
index a54c1d1..dcb6a74 100644
--- a/erpnext/hr/doctype/department/department.json
+++ b/erpnext/hr/doctype/department/department.json
@@ -17,10 +17,10 @@
   "payroll_cost_center",
   "column_break_9",
   "leave_block_list",
-  "leave_section",
+  "approvers",
   "leave_approvers",
-  "expense_section",
   "expense_approvers",
+  "shift_request_approver",
   "lft",
   "rgt",
   "old_parent"
@@ -33,14 +33,18 @@
    "label": "Department",
    "oldfieldname": "department_name",
    "oldfieldtype": "Data",
-   "reqd": 1
+   "reqd": 1,
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "parent_department",
    "fieldtype": "Link",
    "in_list_view": 1,
    "label": "Parent Department",
-   "options": "Department"
+   "options": "Department",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "company",
@@ -48,7 +52,9 @@
    "in_standard_filter": 1,
    "label": "Company",
    "options": "Company",
-   "reqd": 1
+   "reqd": 1,
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "bold": 1,
@@ -56,17 +62,23 @@
    "fieldname": "is_group",
    "fieldtype": "Check",
    "in_list_view": 1,
-   "label": "Is Group"
+   "label": "Is Group",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "default": "0",
    "fieldname": "disabled",
    "fieldtype": "Check",
-   "label": "Disabled"
+   "label": "Disabled",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "section_break_4",
-   "fieldtype": "Section Break"
+   "fieldtype": "Section Break",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "description": "Days for which Holidays are blocked for this department.",
@@ -74,31 +86,25 @@
    "fieldtype": "Link",
    "in_list_view": 1,
    "label": "Leave Block List",
-   "options": "Leave Block List"
+   "options": "Leave Block List",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
-   "fieldname": "leave_section",
-   "fieldtype": "Section Break",
-   "label": "Leave Approvers"
-  },
-  {
-   "description": "The first Leave Approver in the list will be set as the default Leave Approver.",
    "fieldname": "leave_approvers",
    "fieldtype": "Table",
    "label": "Leave Approver",
-   "options": "Department Approver"
+   "options": "Department Approver",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
-   "fieldname": "expense_section",
-   "fieldtype": "Section Break",
-   "label": "Expense Approvers"
-  },
-  {
-   "description": "The first Expense Approver in the list will be set as the default Expense Approver.",
    "fieldname": "expense_approvers",
    "fieldtype": "Table",
    "label": "Expense Approver",
-   "options": "Department Approver"
+   "options": "Department Approver",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "lft",
@@ -106,7 +112,9 @@
    "hidden": 1,
    "label": "lft",
    "print_hide": 1,
-   "read_only": 1
+   "read_only": 1,
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "rgt",
@@ -114,7 +122,9 @@
    "hidden": 1,
    "label": "rgt",
    "print_hide": 1,
-   "read_only": 1
+   "read_only": 1,
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "old_parent",
@@ -122,28 +132,52 @@
    "hidden": 1,
    "ignore_user_permissions": 1,
    "label": "Old Parent",
-   "print_hide": 1
+   "print_hide": 1,
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "column_break_3",
-   "fieldtype": "Column Break"
+   "fieldtype": "Column Break",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "payroll_cost_center",
    "fieldtype": "Link",
    "label": "Payroll Cost Center",
-   "options": "Cost Center"
+   "options": "Cost Center",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "column_break_9",
-   "fieldtype": "Column Break"
+   "fieldtype": "Column Break",
+   "show_days": 1,
+   "show_seconds": 1
+  },
+  {
+   "description": "The first Approver in the list will be set as the default Approver.",
+   "fieldname": "approvers",
+   "fieldtype": "Section Break",
+   "label": "Approvers",
+   "show_days": 1,
+   "show_seconds": 1
+  },
+  {
+   "fieldname": "shift_request_approver",
+   "fieldtype": "Table",
+   "label": "Shift Request Approver",
+   "options": "Department Approver",
+   "show_days": 1,
+   "show_seconds": 1
   }
  ],
  "icon": "fa fa-sitemap",
  "idx": 1,
  "is_tree": 1,
  "links": [],
- "modified": "2020-05-05 18:49:28.503931",
+ "modified": "2020-06-23 15:42:00.563272",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Department",
diff --git a/erpnext/hr/doctype/department_approver/department_approver.py b/erpnext/hr/doctype/department_approver/department_approver.py
index d4c118f..9b2de0e 100644
--- a/erpnext/hr/doctype/department_approver/department_approver.py
+++ b/erpnext/hr/doctype/department_approver/department_approver.py
@@ -11,15 +11,16 @@
 	pass
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_approvers(doctype, txt, searchfield, start, page_len, filters):
 
 	if not filters.get("employee"):
-		frappe.throw(_("Please select Employee Record first."))
+		frappe.throw(_("Please select Employee first."))
 
 	approvers = []
 	department_details = {}
 	department_list = []
-	employee = frappe.get_value("Employee", filters.get("employee"), ["department", "leave_approver", "expense_approver"], as_dict=True)
+	employee = frappe.get_value("Employee", filters.get("employee"), ["department", "leave_approver", "expense_approver", "shift_request_approver"], as_dict=True)
 
 	employee_department = filters.get("department") or employee.department
 	if employee_department:
@@ -36,13 +37,18 @@
 	if filters.get("doctype") == "Expense Claim" and employee.expense_approver:
 		approvers.append(frappe.db.get_value("User", employee.expense_approver, ['name', 'first_name', 'last_name']))
 
+	if filters.get("doctype") == "Shift Request" and employee.shift_request_approver:
+		approvers.append(frappe.db.get_value("User", employee.shift_request_approver, ['name', 'first_name', 'last_name']))
 
 	if filters.get("doctype") == "Leave Application":
 		parentfield = "leave_approvers"
 		field_name = "Leave Approver"
-	else:
+	elif filters.get("doctype") == "Expense Claim":
 		parentfield = "expense_approvers"
 		field_name = "Expense Approver"
+	elif filters.get("doctype") == "Shift Request":
+		parentfield = "shift_request_approver"
+		field_name = "Shift Request Approver"
 	if department_list:
 		for d in department_list:
 			approvers += frappe.db.sql("""select user.name, user.first_name, user.last_name from
diff --git a/erpnext/hr/doctype/employee/employee.json b/erpnext/hr/doctype/employee/employee.json
index f2afe06..8c02e4f 100644
--- a/erpnext/hr/doctype/employee/employee.json
+++ b/erpnext/hr/doctype/employee/employee.json
@@ -51,10 +51,14 @@
   "column_break_31",
   "grade",
   "branch",
+  "approvers_section",
+  "expense_approver",
+  "leave_approver",
+  "column_break_45",
+  "shift_request_approver",
   "attendance_and_leave_details",
   "leave_policy",
   "attendance_device_id",
-  "leave_approver",
   "column_break_44",
   "holiday_list",
   "default_shift",
@@ -62,7 +66,6 @@
   "salary_mode",
   "payroll_cost_center",
   "column_break_52",
-  "expense_approver",
   "bank_name",
   "bank_ac_no",
   "health_insurance_section",
@@ -806,14 +809,37 @@
    "fieldname": "expense_approver",
    "fieldtype": "Link",
    "label": "Expense Approver",
-   "options": "User"
+   "options": "User",
+   "show_days": 1,
+   "show_seconds": 1
+  },
+  {
+   "fieldname": "approvers_section",
+   "fieldtype": "Section Break",
+   "label": "Approvers",
+   "show_days": 1,
+   "show_seconds": 1
+  },
+  {
+   "fieldname": "column_break_45",
+   "fieldtype": "Column Break",
+   "show_days": 1,
+   "show_seconds": 1
+  },
+  {
+   "fieldname": "shift_request_approver",
+   "fieldtype": "Link",
+   "label": "Shift Request Approver",
+   "options": "User",
+   "show_days": 1,
+   "show_seconds": 1
   }
  ],
  "icon": "fa fa-user",
  "idx": 24,
  "image_field": "image",
  "links": [],
- "modified": "2020-07-03 21:28:04.109189",
+ "modified": "2020-07-28 01:36:04.109189",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Employee",
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim_list.js b/erpnext/hr/doctype/expense_claim/expense_claim_list.js
index 6195ad4..9bafc18 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim_list.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim_list.js
@@ -1,5 +1,5 @@
 frappe.listview_settings['Expense Claim'] = {
-	add_fields: ["total_claimed_amount", "docstatus"],
+	add_fields: ["total_claimed_amount", "docstatus", "company"],
 	get_indicator: function(doc) {
 		if(doc.status == "Paid") {
 			return [__("Paid"), "green", "status,=,Paid"];
diff --git a/erpnext/hr/doctype/job_offer/job_offer.py b/erpnext/hr/doctype/job_offer/job_offer.py
index e7e1a37..c397a3f 100644
--- a/erpnext/hr/doctype/job_offer/job_offer.py
+++ b/erpnext/hr/doctype/job_offer/job_offer.py
@@ -3,6 +3,7 @@
 
 from __future__ import unicode_literals
 import frappe
+from frappe.utils import cint
 from frappe.model.document import Document
 from frappe.model.mapper import get_mapped_doc
 from frappe import _
@@ -24,8 +25,12 @@
 		check_vacancies = frappe.get_single("HR Settings").check_vacancies
 		if staffing_plan and check_vacancies:
 			job_offers = self.get_job_offer(staffing_plan.from_date, staffing_plan.to_date)
-			if staffing_plan.vacancies - len(job_offers) <= 0:
-				frappe.throw(_("There are no vacancies under staffing plan {0}").format(frappe.bold(get_link_to_form("Staffing Plan", staffing_plan.parent))))
+			if not staffing_plan.get("vacancies") or cint(staffing_plan.vacancies) - len(job_offers) <= 0:
+				error_variable = 'for ' + frappe.bold(self.designation)
+				if staffing_plan.get("parent"):
+					error_variable = frappe.bold(get_link_to_form("Staffing Plan", staffing_plan.parent))
+
+				frappe.throw(_("There are no vacancies under staffing plan {0}").format(error_variable))
 
 	def on_change(self):
 		update_job_applicant(self.status, self.job_applicant)
@@ -60,7 +65,7 @@
 			AND %s between sp.from_date and sp.to_date
 	""", (designation, company, offer_date), as_dict=1)
 
-	return frappe._dict(detail[0]) if detail else None
+	return frappe._dict(detail[0]) if (detail and detail[0].parent) else None
 
 @frappe.whitelist()
 def make_employee(source_name, target_doc=None):
diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.js b/erpnext/hr/doctype/leave_allocation/leave_allocation.js
index 210a73c..e9e129c 100755
--- a/erpnext/hr/doctype/leave_allocation/leave_allocation.js
+++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.js
@@ -5,20 +5,23 @@
 
 frappe.ui.form.on("Leave Allocation", {
 	onload: function(frm) {
+		// Ignore cancellation of doctype on cancel all.
+		frm.ignore_doctypes_on_cancel_all = ["Leave Ledger Entry"];
+
 		if(!frm.doc.from_date) frm.set_value("from_date", frappe.datetime.get_today());
 
 		frm.set_query("employee", function() {
 			return {
 				query: "erpnext.controllers.queries.employee_query"
-			}
+			};
 		});
 		frm.set_query("leave_type", function() {
 			return {
 				filters: {
 					is_lwp: 0
 				}
-			}
-		})
+			};
+		});
 	},
 
 	refresh: function(frm) {
diff --git a/erpnext/hr/doctype/leave_application/leave_application.js b/erpnext/hr/doctype/leave_application/leave_application.js
index 4001a45..d62e418 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.js
+++ b/erpnext/hr/doctype/leave_application/leave_application.js
@@ -19,6 +19,10 @@
 		frm.set_query("employee", erpnext.queries.employee);
 	},
 	onload: function(frm) {
+
+		// Ignore cancellation of doctype on cancel all.
+		frm.ignore_doctypes_on_cancel_all = ["Leave Ledger Entry"];
+
 		if (!frm.doc.posting_date) {
 			frm.set_value("posting_date", frappe.datetime.get_today());
 		}
diff --git a/erpnext/hr/doctype/leave_encashment/leave_encashment.js b/erpnext/hr/doctype/leave_encashment/leave_encashment.js
index 701c2f0..71a3422 100644
--- a/erpnext/hr/doctype/leave_encashment/leave_encashment.js
+++ b/erpnext/hr/doctype/leave_encashment/leave_encashment.js
@@ -2,6 +2,10 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on('Leave Encashment', {
+	onload: function(frm) {
+		// Ignore cancellation of doctype on cancel all.
+		frm.ignore_doctypes_on_cancel_all = ["Leave Ledger Entry"];
+	},
 	setup: function(frm) {
 		frm.set_query("leave_type", function() {
 			return {
@@ -33,7 +37,7 @@
 				doc: frm.doc,
 				callback: function(r) {
 					frm.refresh_fields();
-					}
+				}
 			});
 		}
 	}
diff --git a/erpnext/hr/doctype/shift_assignment/shift_assignment.json b/erpnext/hr/doctype/shift_assignment/shift_assignment.json
index 72cbba8..ce2a10f 100644
--- a/erpnext/hr/doctype/shift_assignment/shift_assignment.json
+++ b/erpnext/hr/doctype/shift_assignment/shift_assignment.json
@@ -10,9 +10,11 @@
   "employee",
   "employee_name",
   "shift_type",
+  "status",
   "column_break_3",
   "company",
-  "date",
+  "start_date",
+  "end_date",
   "shift_request",
   "department",
   "amended_from"
@@ -60,12 +62,6 @@
    "reqd": 1
   },
   {
-   "fieldname": "date",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "label": "Date"
-  },
-  {
    "fieldname": "shift_request",
    "fieldtype": "Link",
    "label": "Shift Request",
@@ -80,11 +76,36 @@
    "options": "Shift Assignment",
    "print_hide": 1,
    "read_only": 1
+  },
+  {
+   "fieldname": "start_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "Start Date",
+   "reqd": 1
+  },
+  {
+   "allow_on_submit": 1,
+   "fieldname": "end_date",
+   "fieldtype": "Date",
+   "label": "End Date",
+   "show_days": 1,
+   "show_seconds": 1
+  },
+  {
+   "allow_on_submit": 1,
+   "default": "Active",
+   "fieldname": "status",
+   "fieldtype": "Select",
+   "label": "Status",
+   "options": "Active\nInactive",
+   "show_days": 1,
+   "show_seconds": 1
   }
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2019-12-12 15:49:06.956901",
+ "modified": "2020-06-15 14:27:54.310773",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Shift Assignment",
diff --git a/erpnext/hr/doctype/shift_assignment/shift_assignment.py b/erpnext/hr/doctype/shift_assignment/shift_assignment.py
index 40c78cd..f8b7334 100644
--- a/erpnext/hr/doctype/shift_assignment/shift_assignment.py
+++ b/erpnext/hr/doctype/shift_assignment/shift_assignment.py
@@ -11,38 +11,63 @@
 from erpnext.hr.doctype.holiday_list.holiday_list import is_holiday
 from datetime import timedelta, datetime
 
-class OverlapError(frappe.ValidationError): pass
-
 class ShiftAssignment(Document):
 	def validate(self):
 		self.validate_overlapping_dates()
 
+		if self.end_date and self.end_date <= self.start_date:
+			frappe.throw(_("End Date must not be lesser than Start Date"))
+
 	def validate_overlapping_dates(self):
-			if not self.name:
-				self.name = "New Shift Assignment"
+		if not self.name:
+			self.name = "New Shift Assignment"
 
-			d = frappe.db.sql("""
-				select
-					name, shift_type, date
-				from `tabShift Assignment`
-				where employee = %(employee)s and docstatus < 2
-				and date = %(date)s
-				and name != %(name)s""", {
-					"employee": self.employee,
-					"shift_type": self.shift_type,
-					"date": self.date,
-					"name": self.name
-				}, as_dict = 1)
+		condition = """and (
+				end_date is null
+				or
+					%(start_date)s between start_date and end_date
+		"""
 
-			for date_overlap in d:
-				if date_overlap['name']:
-					self.throw_overlap_error(date_overlap)
+		if self.end_date:
+			condition  += """ or
+					%(end_date)s between start_date and end_date
+					or
+					start_date between %(start_date)s and %(end_date)s
+				) """
+		else:
+			condition += """ ) """
 
-	def throw_overlap_error(self, d):
-		msg = _("Employee {0} has already applied for {1} on {2} : ").format(self.employee,
-			d['shift_type'], formatdate(d['date'])) \
-			+ """ <b><a href="#Form/Shift Assignment/{0}">{0}</a></b>""".format(d["name"])
-		frappe.throw(msg, OverlapError)
+		assigned_shifts = frappe.db.sql("""
+			select name, shift_type, start_date ,end_date, docstatus, status
+			from `tabShift Assignment`
+			where
+				employee=%(employee)s and docstatus = 1
+				and name != %(name)s
+				and status = "Active"
+				{0}
+		""".format(condition), {
+			"employee": self.employee,
+			"shift_type": self.shift_type,
+			"start_date": self.start_date,
+			"end_date": self.end_date,
+			"name": self.name
+		}, as_dict = 1)
+
+		if len(assigned_shifts):
+			self.throw_overlap_error(assigned_shifts[0])
+
+	def throw_overlap_error(self, shift_details):
+		shift_details = frappe._dict(shift_details)
+		if shift_details.docstatus == 1 and shift_details.status == "Active":
+			msg = _("Employee {0} already has Active Shift {1}: {2}").format(frappe.bold(self.employee), frappe.bold(self.shift_type), frappe.bold(shift_details.name))
+		if shift_details.start_date:
+			msg += _(" from {0}").format(getdate(self.start_date).strftime("%d-%m-%Y"))
+			title = "Ongoing Shift"
+			if shift_details.end_date:
+				msg += _(" to {0}").format(getdate(self.end_date).strftime("%d-%m-%Y"))
+				title = "Active Shift"
+		if msg:
+			frappe.throw(msg, title=title)
 
 @frappe.whitelist()
 def get_events(start, end, filters=None):
@@ -62,19 +87,22 @@
 	return events
 
 def add_assignments(events, start, end, conditions=None):
-	query = """select name, date, employee_name, 
+	query = """select name, start_date, end_date, employee_name,
 		employee, docstatus
 		from `tabShift Assignment` where
-		date <= %(date)s
-		and docstatus < 2"""
+		start_date >= %(start_date)s
+		or end_date <=  %(end_date)s
+		or (%(start_date)s between start_date and end_date and %(end_date)s between start_date and end_date)
+		and docstatus = 1"""
 	if conditions:
 		query += conditions
 
-	for d in frappe.db.sql(query, {"date":start, "date":end}, as_dict=True):
+	for d in frappe.db.sql(query, {"start_date":start, "end_date":end}, as_dict=True):
 		e = {
 			"name": d.name,
 			"doctype": "Shift Assignment",
-			"date": d.date,
+			"start_date": d.start_date,
+			"end_date": d.end_date if d.end_date else nowdate(),
 			"title": cstr(d.employee_name) + \
 				cstr(d.shift_type),
 			"docstatus": d.docstatus
@@ -92,7 +120,16 @@
 	:param next_shift_direction: One of: None, 'forward', 'reverse'. Direction to look for next shift if shift not found on given date.
 	"""
 	default_shift = frappe.db.get_value('Employee', employee, 'default_shift')
-	shift_type_name = frappe.db.get_value('Shift Assignment', {'employee':employee, 'date': for_date, 'docstatus': '1'}, 'shift_type')
+	shift_type_name = None
+	shift_assignment_details = frappe.db.get_value('Shift Assignment', {'employee':employee, 'start_date':('<=', for_date), 'docstatus': '1', 'status': "Active"}, ['shift_type', 'end_date'])
+
+	if shift_assignment_details:
+		shift_type_name = shift_assignment_details[0]
+
+		# if end_date present means that shift is over after end_date else it is a ongoing shift.
+		if shift_assignment_details[1] and for_date >= shift_assignment_details[1] :
+			shift_type_name = None
+
 	if not shift_type_name and consider_default_shift:
 		shift_type_name = default_shift
 	if shift_type_name:
@@ -117,16 +154,20 @@
 			direction = '<' if next_shift_direction == 'reverse' else '>'
 			sort_order = 'desc' if next_shift_direction == 'reverse' else 'asc'
 			dates = frappe.db.get_all('Shift Assignment',
-				'date',
-				{'employee':employee, 'date':(direction, for_date), 'docstatus': '1'},
+				['start_date', 'end_date'],
+				{'employee':employee, 'start_date':(direction, for_date), 'docstatus': '1', "status": "Active"},
 				as_list=True,
-				limit=MAX_DAYS, order_by="date "+sort_order)
-			for date in dates:
-				shift_details = get_employee_shift(employee, date[0], consider_default_shift, None)
-				if shift_details:
-					shift_type_name = shift_details.shift_type.name
-					for_date = date[0]
-					break
+				limit=MAX_DAYS, order_by="start_date "+sort_order)
+
+			if dates:
+				for date in dates:
+					if date[1] and date[1] < for_date:
+						continue
+					shift_details = get_employee_shift(employee, date[0], consider_default_shift, None)
+					if shift_details:
+						shift_type_name = shift_details.shift_type.name
+						for_date = date[0]
+						break
 
 	return get_shift_details(shift_type_name, for_date)
 
@@ -134,7 +175,7 @@
 def get_employee_shift_timings(employee, for_timestamp=now_datetime(), consider_default_shift=False):
 	"""Returns previous shift, current/upcoming shift, next_shift for the given timestamp and employee
 	"""
-	# write and verify a test case for midnight shift. 
+	# write and verify a test case for midnight shift.
 	prev_shift = curr_shift = next_shift = None
 	curr_shift = get_employee_shift(employee, for_timestamp.date(), consider_default_shift, 'forward')
 	if curr_shift:
diff --git a/erpnext/hr/doctype/shift_assignment/shift_assignment_calendar.js b/erpnext/hr/doctype/shift_assignment/shift_assignment_calendar.js
index c2c9bc0..17a986d 100644
--- a/erpnext/hr/doctype/shift_assignment/shift_assignment_calendar.js
+++ b/erpnext/hr/doctype/shift_assignment/shift_assignment_calendar.js
@@ -3,8 +3,8 @@
 
 frappe.views.calendar["Shift Assignment"] = {
 	field_map: {
-		"start": "date",
-		"end": "date",
+		"start": "start_date",
+		"end": "end_date",
 		"id": "name",
 		"docstatus": 1
 	},
diff --git a/erpnext/hr/doctype/shift_assignment/test_shift_assignment.py b/erpnext/hr/doctype/shift_assignment/test_shift_assignment.py
index 7fe80a2..4c3c1ed 100644
--- a/erpnext/hr/doctype/shift_assignment/test_shift_assignment.py
+++ b/erpnext/hr/doctype/shift_assignment/test_shift_assignment.py
@@ -5,7 +5,7 @@
 
 import frappe
 import unittest
-from frappe.utils import nowdate
+from frappe.utils import nowdate, add_days
 
 test_dependencies = ["Shift Type"]
 
@@ -20,8 +20,61 @@
 			"shift_type": "Day Shift",
 			"company": "_Test Company",
 			"employee": "_T-Employee-00001",
-			"date": nowdate()
+			"start_date": nowdate()
 		}).insert()
 		shift_assignment.submit()
 
 		self.assertEqual(shift_assignment.docstatus, 1)
+
+	def test_overlapping_for_ongoing_shift(self):
+		# shift should be Ongoing if Only start_date is present and status = Active
+
+		shift_assignment_1 = frappe.get_doc({
+			"doctype": "Shift Assignment",
+			"shift_type": "Day Shift",
+			"company": "_Test Company",
+			"employee": "_T-Employee-00001",
+			"start_date": nowdate(),
+			"status": 'Active'
+		}).insert()
+		shift_assignment_1.submit()
+
+		self.assertEqual(shift_assignment_1.docstatus, 1)
+
+		shift_assignment = frappe.get_doc({
+			"doctype": "Shift Assignment",
+			"shift_type": "Day Shift",
+			"company": "_Test Company",
+			"employee": "_T-Employee-00001",
+			"start_date": add_days(nowdate(), 2)
+		})
+
+		self.assertRaises(frappe.ValidationError, shift_assignment.save)
+
+	def test_overlapping_for_fixed_period_shift(self):
+		# shift should is for Fixed period if Only start_date and end_date both are present and status = Active
+
+			shift_assignment_1 = frappe.get_doc({
+				"doctype": "Shift Assignment",
+				"shift_type": "Day Shift",
+				"company": "_Test Company",
+				"employee": "_T-Employee-00001",
+				"start_date": nowdate(),
+				"end_date": add_days(nowdate(), 30),
+				"status": 'Active'
+			}).insert()
+			shift_assignment_1.submit()
+
+
+			# it should not allowed within period of any shift.
+			shift_assignment_3 = frappe.get_doc({
+				"doctype": "Shift Assignment",
+				"shift_type": "Day Shift",
+				"company": "_Test Company",
+				"employee": "_T-Employee-00001",
+				"start_date":add_days(nowdate(), 10),
+				"end_date": add_days(nowdate(), 35),
+				"status": 'Active'
+			})
+
+			self.assertRaises(frappe.ValidationError, shift_assignment_3.save)
\ No newline at end of file
diff --git a/erpnext/hr/doctype/shift_request/shift_request.js b/erpnext/hr/doctype/shift_request/shift_request.js
index 1db7c7d..b17a6f3 100644
--- a/erpnext/hr/doctype/shift_request/shift_request.js
+++ b/erpnext/hr/doctype/shift_request/shift_request.js
@@ -2,7 +2,16 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on('Shift Request', {
-	refresh: function(frm) {
-
-	}
+	setup: function(frm) {
+		frm.set_query("approver", function() {
+			return {
+				query: "erpnext.hr.doctype.department_approver.department_approver.get_approvers",
+				filters: {
+					employee: frm.doc.employee,
+					doctype: frm.doc.doctype
+				}
+			};
+		});
+		frm.set_query("employee", erpnext.queries.employee);
+	},
 });
diff --git a/erpnext/hr/doctype/shift_request/shift_request.json b/erpnext/hr/doctype/shift_request/shift_request.json
index dd05647..64cbdff 100644
--- a/erpnext/hr/doctype/shift_request/shift_request.json
+++ b/erpnext/hr/doctype/shift_request/shift_request.json
@@ -1,396 +1,155 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 0, 
- "autoname": "HR-SHR-.YY.-.MM.-.#####", 
- "beta": 0, 
- "creation": "2018-04-13 16:32:27.974273", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "allow_import": 1,
+ "autoname": "HR-SHR-.YY.-.MM.-.#####",
+ "creation": "2018-04-13 16:32:27.974273",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "shift_type",
+  "employee",
+  "employee_name",
+  "department",
+  "status",
+  "column_break_4",
+  "company",
+  "approver",
+  "from_date",
+  "to_date",
+  "amended_from"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "shift_type", 
-   "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": "Shift Type", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Shift Type", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "shift_type",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Shift Type",
+   "options": "Shift Type",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "employee", 
-   "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", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Employee", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "employee",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Employee",
+   "options": "Employee",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "employee.employee_name", 
-   "fieldname": "employee_name", 
-   "fieldtype": "Data", 
-   "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 Name", 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "employee.employee_name",
+   "fieldname": "employee_name",
+   "fieldtype": "Data",
+   "label": "Employee Name",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "employee.department", 
-   "fieldname": "department", 
-   "fieldtype": "Link", 
-   "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": "Department", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Department", 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "employee.department",
+   "fieldname": "department",
+   "fieldtype": "Link",
+   "label": "Department",
+   "options": "Department",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_4",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "company", 
-   "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": "Company", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Company", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "company",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Company",
+   "options": "Company",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "from_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": "From 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
-  }, 
+   "fieldname": "from_date",
+   "fieldtype": "Date",
+   "label": "From Date",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "to_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": "To 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
-  }, 
+   "fieldname": "to_date",
+   "fieldtype": "Date",
+   "label": "To Date"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "amended_from", 
-   "fieldtype": "Link", 
-   "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": "Amended From", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Shift Request", 
-   "permlevel": 0, 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
+   "fieldname": "amended_from",
+   "fieldtype": "Link",
+   "label": "Amended From",
+   "no_copy": 1,
+   "options": "Shift Request",
+   "print_hide": 1,
+   "read_only": 1
+  },
+  {
+   "default": "Draft",
+   "fieldname": "status",
+   "fieldtype": "Select",
+   "label": "Status",
+   "options": "Draft\nApproved\nRejected",
+   "reqd": 1
+  },
+  {
+   "fetch_from": "employee.shift_request_approver",
+   "fetch_if_empty": 1,
+   "fieldname": "approver",
+   "fieldtype": "Link",
+   "label": "Approver",
+   "options": "User",
+   "reqd": 1
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 1, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-08-21 16:15:36.577448", 
- "modified_by": "Administrator", 
- "module": "HR", 
- "name": "Shift Request", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2020-08-10 17:59:31.550558",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Shift Request",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 0, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Employee", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 1, 
+   "create": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Employee",
+   "share": 1,
    "write": 1
-  }, 
+  },
   {
-   "amend": 1, 
-   "cancel": 1, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "HR Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 1, 
+   "amend": 1,
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "HR Manager",
+   "share": 1,
+   "submit": 1,
    "write": 1
-  }, 
+  },
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 0, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "HR User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 1, 
+   "create": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "HR User",
+   "share": 1,
+   "submit": 1,
    "write": 1
   }
- ], 
- "quick_entry": 0, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "title_field": "employee_name", 
- "track_changes": 1, 
- "track_seen": 0, 
- "track_views": 0
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "employee_name",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/hr/doctype/shift_request/shift_request.py b/erpnext/hr/doctype/shift_request/shift_request.py
index ff5de08..1c2801b 100644
--- a/erpnext/hr/doctype/shift_request/shift_request.py
+++ b/erpnext/hr/doctype/shift_request/shift_request.py
@@ -14,19 +14,26 @@
 	def validate(self):
 		self.validate_dates()
 		self.validate_shift_request_overlap_dates()
+		self.validate_approver()
+		self.validate_default_shift()
 
 	def on_submit(self):
-		date_list = self.get_working_days(self.from_date, self.to_date)
-		for date in date_list:
+		if self.status not in ["Approved", "Rejected"]:
+			frappe.throw(_("Only Shift Request with status 'Approved' and 'Rejected' can be submitted"))
+		if self.status == "Approved":
 			assignment_doc = frappe.new_doc("Shift Assignment")
 			assignment_doc.company = self.company
 			assignment_doc.shift_type = self.shift_type
 			assignment_doc.employee = self.employee
-			assignment_doc.date = date
+			assignment_doc.start_date = self.from_date
+			if self.to_date:
+				assignment_doc.end_date = self.to_date
 			assignment_doc.shift_request = self.name
 			assignment_doc.insert()
 			assignment_doc.submit()
 
+			frappe.msgprint(_("Shift Assignment: {0} created for Employee: {1}").format(frappe.bold(assignment_doc.name), frappe.bold(self.employee)))
+
 	def on_cancel(self):
 		shift_assignment_list = frappe.get_list("Shift Assignment", {'employee': self.employee, 'shift_request': self.name})
 		if shift_assignment_list:
@@ -34,6 +41,19 @@
 				shift_assignment_doc = frappe.get_doc("Shift Assignment", shift['name'])
 				shift_assignment_doc.cancel()
 
+	def validate_default_shift(self):
+		default_shift = frappe.get_value("Employee", self.employee, "default_shift")
+		if self.shift_type == default_shift:
+			frappe.throw(_("You can not request for your Default Shift: {0}").format(frappe.bold(self.shift_type)))
+
+	def validate_approver(self):
+		department = frappe.get_value("Employee", self.employee, "department")
+		shift_approver = frappe.get_value("Employee", self.employee, "shift_request_approver")
+		approvers = frappe.db.sql("""select approver from `tabDepartment Approver` where parent= %s and parentfield = 'shift_request_approver'""", (department))
+		approvers = [approver[0] for approver in approvers]
+		approvers.append(shift_approver)
+		if self.approver not in approvers:
+			frappe.throw(_("Only Approvers can Approve this Request."))
 
 	def validate_dates(self):
 		if self.from_date and self.to_date and (getdate(self.to_date) < getdate(self.from_date)):
@@ -68,28 +88,4 @@
 		msg = _("Employee {0} has already applied for {1} between {2} and {3} : ").format(self.employee,
 			d['shift_type'], formatdate(d['from_date']), formatdate(d['to_date'])) \
 			+ """ <b><a href="#Form/Shift Request/{0}">{0}</a></b>""".format(d["name"])
-		frappe.throw(msg, OverlapError)
-
-	def get_working_days(self, start_date, end_date):
-		start_date, end_date = getdate(start_date), getdate(end_date)
-
-		from datetime import timedelta
-
-		date_list = []
-		employee_holiday_list = []
-
-		employee_holidays = frappe.db.sql("""select holiday_date from `tabHoliday`
-								where parent in (select holiday_list from `tabEmployee`
-								where name = %s)""",self.employee,as_dict=1)
-
-		for d in employee_holidays:
-			employee_holiday_list.append(d.holiday_date)
-
-		reference_date = start_date
-		
-		while reference_date <= end_date:
-			if reference_date not in employee_holiday_list:
-				date_list.append(reference_date)
-			reference_date += timedelta(days=1)
-
-		return date_list
\ No newline at end of file
+		frappe.throw(msg, OverlapError)
\ No newline at end of file
diff --git a/erpnext/hr/doctype/shift_request/test_shift_request.py b/erpnext/hr/doctype/shift_request/test_shift_request.py
index 1d0cf71..3dcfcbf 100644
--- a/erpnext/hr/doctype/shift_request/test_shift_request.py
+++ b/erpnext/hr/doctype/shift_request/test_shift_request.py
@@ -5,7 +5,7 @@
 
 import frappe
 import unittest
-from frappe.utils import nowdate
+from frappe.utils import nowdate, add_days
 
 class TestShiftRequest(unittest.TestCase):
 	def setUp(self):
@@ -13,14 +13,20 @@
 			frappe.db.sql("delete from `tab{doctype}`".format(doctype=doctype))
 
 	def test_make_shift_request(self):
+		department = frappe.get_value("Employee", "_T-Employee-00001", 'department')
+		set_shift_approver(department)
+		approver = frappe.db.sql("""select approver from `tabDepartment Approver` where parent= %s and parentfield = 'shift_request_approver'""", (department))[0][0]
+
 		shift_request = frappe.get_doc({
 			"doctype": "Shift Request",
 			"shift_type": "Day Shift",
 			"company": "_Test Company",
 			"employee": "_T-Employee-00001",
 			"employee_name": "_Test Employee",
-			"start_date": nowdate(),
-			"end_date": nowdate()
+			"from_date": nowdate(),
+			"to_date": add_days(nowdate(), 10),
+			"approver": approver,
+			"status": "Approved"
 		})
 		shift_request.insert()
 		shift_request.submit()
@@ -34,4 +40,10 @@
 			self.assertEqual(shift_request.employee, employee)
 			shift_request.cancel()
 			shift_assignment_doc = frappe.get_doc("Shift Assignment", {"shift_request": d.get('shift_request')})
-			self.assertEqual(shift_assignment_doc.docstatus, 2)
\ No newline at end of file
+			self.assertEqual(shift_assignment_doc.docstatus, 2)
+
+def set_shift_approver(department):
+	department_doc = frappe.get_doc("Department", department)
+	department_doc.append('shift_request_approver',{'approver': "test1@example.com"})
+	department_doc.save()
+	department_doc.reload()
\ No newline at end of file
diff --git a/erpnext/hr/doctype/shift_type/shift_type.js b/erpnext/hr/doctype/shift_type/shift_type.js
index e633545..ba53312 100644
--- a/erpnext/hr/doctype/shift_type/shift_type.js
+++ b/erpnext/hr/doctype/shift_type/shift_type.js
@@ -4,7 +4,7 @@
 frappe.ui.form.on('Shift Type', {
 	refresh: function(frm) {
 		frm.add_custom_button(
-			'Mark Auto Attendance',
+			'Mark Attendance',
 			() => frm.call({
 				doc: frm.doc,
 				method: 'process_auto_attendance',
diff --git a/erpnext/hr/doctype/shift_type/shift_type.py b/erpnext/hr/doctype/shift_type/shift_type.py
index 1973564..054e7e3 100644
--- a/erpnext/hr/doctype/shift_type/shift_type.py
+++ b/erpnext/hr/doctype/shift_type/shift_type.py
@@ -79,9 +79,10 @@
 				mark_attendance(employee, date, 'Absent', self.name)
 
 	def get_assigned_employee(self, from_date=None, consider_default_shift=False):
-		filters = {'date':('>=', from_date), 'shift_type': self.name, 'docstatus': '1'}
+		filters = {'start_date':('>', from_date), 'shift_type': self.name, 'docstatus': '1'}
 		if not from_date:
-			del filters['date']
+			del filters["start_date"]
+
 		assigned_employees = frappe.get_all('Shift Assignment', 'employee', filters, as_list=True)
 		assigned_employees = [x[0] for x in assigned_employees]
 
diff --git a/erpnext/loan_management/desk_page/loan/loan.json b/erpnext/loan_management/desk_page/loan/loan.json
index 95fa22b..62eecbe 100644
--- a/erpnext/loan_management/desk_page/loan/loan.json
+++ b/erpnext/loan_management/desk_page/loan/loan.json
@@ -3,7 +3,7 @@
   {
    "hidden": 0,
    "label": "Loan",
-   "links": "[\n    {\n        \"description\": \"Loan Type for interest and penalty rates\",\n        \"label\": \"Loan Type\",\n        \"name\": \"Loan Type\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Loan Applications from customers and employees.\",\n        \"label\": \"Loan Application\",\n        \"name\": \"Loan Application\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Loans provided to customers and employees.\",\n        \"label\": \"Loan\",\n        \"name\": \"Loan\",\n        \"type\": \"doctype\"\n    }\n]"
+   "links": "[\n    {\n        \"description\": \"Loan Type for interest and penalty rates\",\n        \"label\": \"Loan Type\",\n        \"name\": \"Loan Type\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Loan Applications from customers and employees.\",\n        \"label\": \"Loan Application\",\n        \"name\": \"Loan Application\",\n        \"type\": \"doctype\"\n    },\n    {   \"dependencies\": [\n            \"Loan Type\"\n        ],\n        \"description\": \"Loans provided to customers and employees.\",\n        \"label\": \"Loan\",\n        \"name\": \"Loan\",\n        \"type\": \"doctype\"\n    }\n]"
   },
   {
    "hidden": 0,
diff --git a/erpnext/loan_management/doctype/loan_application/loan_application.js b/erpnext/loan_management/doctype/loan_application/loan_application.js
index 6cf47bf..b56fce1 100644
--- a/erpnext/loan_management/doctype/loan_application/loan_application.js
+++ b/erpnext/loan_management/doctype/loan_application/loan_application.js
@@ -112,16 +112,19 @@
 frappe.ui.form.on("Proposed Pledge", {
 	loan_security: function(frm, cdt, cdn) {
 		let row = locals[cdt][cdn];
-		frappe.call({
-			method: "erpnext.loan_management.doctype.loan_security_price.loan_security_price.get_loan_security_price",
-			args: {
-				loan_security: row.loan_security
-			},
-			callback: function(r) {
-				frappe.model.set_value(cdt, cdn, 'loan_security_price', r.message);
-				frm.events.calculate_amounts(frm, cdt, cdn);
-			}
-		})
+
+		if (row.loan_security) {
+			frappe.call({
+				method: "erpnext.loan_management.doctype.loan_security_price.loan_security_price.get_loan_security_price",
+				args: {
+					loan_security: row.loan_security
+				},
+				callback: function(r) {
+					frappe.model.set_value(cdt, cdn, 'loan_security_price', r.message);
+					frm.events.calculate_amounts(frm, cdt, cdn);
+				}
+			})
+		}
 	},
 
 	amount: function(frm, cdt, cdn) {
diff --git a/erpnext/loan_management/doctype/loan_application/loan_application.py b/erpnext/loan_management/doctype/loan_application/loan_application.py
index f051755..bac6e63 100644
--- a/erpnext/loan_management/doctype/loan_application/loan_application.py
+++ b/erpnext/loan_management/doctype/loan_application/loan_application.py
@@ -16,14 +16,16 @@
 
 class LoanApplication(Document):
 	def validate(self):
-
-		validate_repayment_method(self.repayment_method, self.loan_amount, self.repayment_amount,
-			self.repayment_periods, self.is_term_loan)
-
-		self.validate_loan_type()
 		self.set_pledge_amount()
 		self.set_loan_amount()
 		self.validate_loan_amount()
+
+		if self.is_term_loan:
+			validate_repayment_method(self.repayment_method, self.loan_amount, self.repayment_amount,
+				self.repayment_periods, self.is_term_loan)
+
+		self.validate_loan_type()
+
 		self.get_repayment_details()
 		self.check_sanctioned_amount_limit()
 
@@ -106,7 +108,7 @@
 		if self.is_secured_loan and self.proposed_pledges:
 			self.maximum_loan_amount = 0
 			for security in self.proposed_pledges:
-				self.maximum_loan_amount += security.post_haircut_amount
+				self.maximum_loan_amount += flt(security.post_haircut_amount)
 
 		if not self.loan_amount and self.is_secured_loan and self.proposed_pledges:
 			self.loan_amount = self.maximum_loan_amount
@@ -133,10 +135,7 @@
 			"validation": {
 				"docstatus": ["=", 1]
 			},
-			"postprocess": update_accounts,
-			"field_no_map": [
-				"is_secured_loan"
-			]
+			"postprocess": update_accounts
 		}
 	}, target_doc)
 
diff --git a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
index d44088b..6c27e12 100644
--- a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
+++ b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
@@ -10,22 +10,20 @@
 from erpnext.controllers.accounts_controller import AccountsController
 from erpnext.accounts.general_ledger import make_gl_entries
 from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_demand_loans
+from erpnext.loan_management.doctype.loan_security_unpledge.loan_security_unpledge import get_pledged_security_qty
+from frappe.utils import get_datetime
 
 class LoanDisbursement(AccountsController):
 
 	def validate(self):
 		self.set_missing_values()
 
-	def before_submit(self):
-		self.set_status_and_amounts()
-
-	def before_cancel(self):
-		self.set_status_and_amounts(cancel=1)
-
 	def on_submit(self):
+		self.set_status_and_amounts()
 		self.make_gl_entries()
 
 	def on_cancel(self):
+		self.set_status_and_amounts(cancel=1)
 		self.make_gl_entries(cancel=1)
 		self.ignore_linked_doctypes = ['GL Entry']
 
@@ -45,29 +43,69 @@
 	def set_status_and_amounts(self, cancel=0):
 
 		loan_details = frappe.get_all("Loan",
-			fields = ["loan_amount", "disbursed_amount", "total_principal_paid", "status", "is_term_loan"],
-			filters= { "name": self.against_loan }
-		)[0]
-
-		if loan_details.status == "Disbursed" and not loan_details.is_term_loan:
-			process_loan_interest_accrual_for_demand_loans(posting_date=add_days(self.disbursement_date, -1),
-				loan=self.against_loan)
+			fields = ["loan_amount", "disbursed_amount", "total_payment", "total_principal_paid", "total_interest_payable",
+				"status", "is_term_loan", "is_secured_loan"], filters= { "name": self.against_loan })[0]
 
 		if cancel:
 			disbursed_amount = loan_details.disbursed_amount - self.disbursed_amount
+			total_payment = loan_details.total_payment
+
+			if loan_details.disbursed_amount > loan_details.loan_amount:
+				topup_amount = loan_details.disbursed_amount - loan_details.loan_amount
+				if topup_amount > self.disbursed_amount:
+					topup_amount = self.disbursed_amount
+
+				total_payment = total_payment - topup_amount
+
 			if disbursed_amount == 0:
 				status = "Sanctioned"
-			elif disbursed_amount >= loan_details.disbursed_amount:
+			elif disbursed_amount >= loan_details.loan_amount:
 				status = "Disbursed"
 			else:
 				status = "Partially Disbursed"
 		else:
 			disbursed_amount = self.disbursed_amount + loan_details.disbursed_amount
+			total_payment = loan_details.total_payment
 
-			if flt(disbursed_amount) - flt(loan_details.total_principal_paid) > flt(loan_details.loan_amount):
+			if disbursed_amount > loan_details.loan_amount and loan_details.is_term_loan:
 				frappe.throw(_("Disbursed Amount cannot be greater than loan amount"))
 
-			if flt(disbursed_amount) >= loan_details.disbursed_amount:
+			if loan_details.status == 'Disbursed':
+				pending_principal_amount = flt(loan_details.total_payment) - flt(loan_details.total_interest_payable) \
+					- flt(loan_details.total_principal_paid)
+			else:
+				pending_principal_amount = loan_details.disbursed_amount
+
+			security_value = 0.0
+			if loan_details.is_secured_loan:
+				security_value = get_total_pledged_security_value(self.against_loan)
+
+			if not security_value:
+				security_value = loan_details.loan_amount
+
+			if pending_principal_amount + self.disbursed_amount > flt(security_value):
+				allowed_amount = security_value - pending_principal_amount
+				if allowed_amount < 0:
+					allowed_amount = 0
+
+				frappe.throw(_("Disbursed Amount cannot be greater than {0}").format(allowed_amount))
+
+			if loan_details.status == "Disbursed" and not loan_details.is_term_loan:
+				process_loan_interest_accrual_for_demand_loans(posting_date=add_days(self.disbursement_date, -1),
+					loan=self.against_loan)
+
+			if disbursed_amount > loan_details.loan_amount:
+				topup_amount = disbursed_amount - loan_details.loan_amount
+
+				if topup_amount < 0:
+					topup_amount = 0
+
+				if topup_amount > self.disbursed_amount:
+					topup_amount = self.disbursed_amount
+
+				total_payment = total_payment + topup_amount
+
+			if flt(disbursed_amount) >= loan_details.loan_amount:
 				status = "Disbursed"
 			else:
 				status = "Partially Disbursed"
@@ -75,7 +113,8 @@
 		frappe.db.set_value("Loan", self.against_loan, {
 			"disbursement_date": self.disbursement_date,
 			"disbursed_amount": disbursed_amount,
-			"status": status
+			"status": status,
+			"total_payment": total_payment
 		})
 
 	def make_gl_entries(self, cancel=0, adv_adj=0):
@@ -116,3 +155,24 @@
 
 		if gle_map:
 			make_gl_entries(gle_map, cancel=cancel, adv_adj=adv_adj)
+
+def get_total_pledged_security_value(loan):
+	update_time = get_datetime()
+
+	loan_security_price_map = frappe._dict(frappe.get_all("Loan Security Price",
+		fields=["loan_security", "loan_security_price"],
+		filters = {
+			"valid_from": ("<=", update_time),
+			"valid_upto": (">=", update_time)
+		}, as_list=1))
+
+	hair_cut_map = frappe._dict(frappe.get_all('Loan Security',
+		fields=["name", "haircut"], as_list=1))
+
+	security_value = 0.0
+	pledged_securities = get_pledged_security_qty(loan)
+
+	for security, qty in pledged_securities.items():
+		security_value += (loan_security_price_map.get(security) * qty * hair_cut_map.get(security))/100
+
+	return security_value
diff --git a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
index e6ceb55..c5111fd 100644
--- a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
+++ b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
@@ -19,8 +19,8 @@
 		if not self.posting_date:
 			self.posting_date = nowdate()
 
-		if not self.interest_amount:
-			frappe.throw(_("Interest Amount is mandatory"))
+		if not self.interest_amount and not self.payable_principal_amount:
+			frappe.throw(_("Interest Amount or Principal Amount is mandatory"))
 
 
 	def on_submit(self):
@@ -39,37 +39,38 @@
 	def make_gl_entries(self, cancel=0, adv_adj=0):
 		gle_map = []
 
-		gle_map.append(
-			self.get_gl_dict({
-				"account": self.loan_account,
-				"party_type": self.applicant_type,
-				"party": self.applicant,
-				"against": self.interest_income_account,
-				"debit": self.interest_amount,
-				"debit_in_account_currency": self.interest_amount,
-				"against_voucher_type": "Loan",
-				"against_voucher": self.loan,
-				"remarks": _("Against Loan:") + self.loan,
-				"cost_center": erpnext.get_default_cost_center(self.company),
-				"posting_date": self.posting_date
-			})
-		)
+		if self.interest_amount:
+			gle_map.append(
+				self.get_gl_dict({
+					"account": self.loan_account,
+					"party_type": self.applicant_type,
+					"party": self.applicant,
+					"against": self.interest_income_account,
+					"debit": self.interest_amount,
+					"debit_in_account_currency": self.interest_amount,
+					"against_voucher_type": "Loan",
+					"against_voucher": self.loan,
+					"remarks": _("Against Loan:") + self.loan,
+					"cost_center": erpnext.get_default_cost_center(self.company),
+					"posting_date": self.posting_date
+				})
+			)
 
-		gle_map.append(
-			self.get_gl_dict({
-				"account": self.interest_income_account,
-				"party_type": self.applicant_type,
-				"party": self.applicant,
-				"against": self.loan_account,
-				"credit": self.interest_amount,
-				"credit_in_account_currency":  self.interest_amount,
-				"against_voucher_type": "Loan",
-				"against_voucher": self.loan,
-				"remarks": _("Against Loan:") + self.loan,
-				"cost_center": erpnext.get_default_cost_center(self.company),
-				"posting_date": self.posting_date
-			})
-		)
+			gle_map.append(
+				self.get_gl_dict({
+					"account": self.interest_income_account,
+					"party_type": self.applicant_type,
+					"party": self.applicant,
+					"against": self.loan_account,
+					"credit": self.interest_amount,
+					"credit_in_account_currency":  self.interest_amount,
+					"against_voucher_type": "Loan",
+					"against_voucher": self.loan,
+					"remarks": _("Against Loan:") + self.loan,
+					"cost_center": erpnext.get_default_cost_center(self.company),
+					"posting_date": self.posting_date
+				})
+			)
 
 		if gle_map:
 			make_gl_entries(gle_map, cancel=cancel, adv_adj=adv_adj)
@@ -84,8 +85,8 @@
 	if no_of_days <= 0:
 		return
 
-	pending_principal_amount = loan.total_payment - loan.total_interest_payable \
-		- loan.total_amount_paid
+	pending_principal_amount = flt(loan.total_payment) - flt(loan.total_interest_payable) \
+		- flt(loan.total_principal_paid)
 
 	interest_per_day = (pending_principal_amount * loan.rate_of_interest) / (days_in_year(get_datetime(posting_date).year) * 100)
 	payable_interest = interest_per_day * no_of_days
diff --git a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.json b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.json
index 789c129..5942455 100644
--- a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.json
+++ b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.json
@@ -173,7 +173,7 @@
   {
    "fieldname": "references_section",
    "fieldtype": "Section Break",
-   "label": "References"
+   "label": "Payment References"
   },
   {
    "fieldname": "reference_number",
@@ -221,7 +221,7 @@
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2020-04-16 18:14:45.166754",
+ "modified": "2020-05-16 09:40:15.581165",
  "modified_by": "Administrator",
  "module": "Loan Management",
  "name": "Loan Repayment",
diff --git a/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.js b/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.js
index 82837b3..11c932f 100644
--- a/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.js
+++ b/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.js
@@ -22,16 +22,19 @@
 frappe.ui.form.on("Pledge", {
 	loan_security: function(frm, cdt, cdn) {
 		let row = locals[cdt][cdn];
-		frappe.call({
-			method: "erpnext.loan_management.doctype.loan_security_price.loan_security_price.get_loan_security_price",
-			args: {
-				loan_security: row.loan_security
-			},
-			callback: function(r) {
-				frappe.model.set_value(cdt, cdn, 'loan_security_price', r.message);
-				frm.events.calculate_amounts(frm, cdt, cdn);
-			}
-		});
+
+		if (row.loan_security) {
+			frappe.call({
+				method: "erpnext.loan_management.doctype.loan_security_price.loan_security_price.get_loan_security_price",
+				args: {
+					loan_security: row.loan_security
+				},
+				callback: function(r) {
+					frappe.model.set_value(cdt, cdn, 'loan_security_price', r.message);
+					frm.events.calculate_amounts(frm, cdt, cdn);
+				}
+			});
+		}
 	},
 
 	qty: function(frm, cdt, cdn) {
diff --git a/erpnext/loan_management/doctype/loan_security_type/loan_security_type.json b/erpnext/loan_management/doctype/loan_security_type/loan_security_type.json
index f46b88c..871e825 100644
--- a/erpnext/loan_management/doctype/loan_security_type/loan_security_type.json
+++ b/erpnext/loan_management/doctype/loan_security_type/loan_security_type.json
@@ -29,6 +29,7 @@
    "unique": 1
   },
   {
+   "description": "Haircut percentage is the percentage difference between market value of the Loan Security and the value ascribed to that Loan Security when used as collateral for that loan.",
    "fieldname": "haircut",
    "fieldtype": "Percent",
    "label": "Haircut %"
@@ -46,13 +47,14 @@
    "fieldtype": "Column Break"
   },
   {
+   "description": "Loan To Value Ratio expresses the ratio of the loan amount to the value of the security pledged. A loan security shortfall will be triggered if this falls below the specified value for any loan ",
    "fieldname": "loan_to_value_ratio",
    "fieldtype": "Percent",
    "label": "Loan To Value Ratio"
   }
  ],
  "links": [],
- "modified": "2020-04-28 14:06:49.046177",
+ "modified": "2020-05-16 09:38:45.988080",
  "modified_by": "Administrator",
  "module": "Loan Management",
  "name": "Loan Security Type",
diff --git a/erpnext/loan_management/doctype/loan_type/loan_type.json b/erpnext/loan_management/doctype/loan_type/loan_type.json
index 1dd3710..669490a 100644
--- a/erpnext/loan_management/doctype/loan_type/loan_type.json
+++ b/erpnext/loan_management/doctype/loan_type/loan_type.json
@@ -76,6 +76,7 @@
    "reqd": 1
   },
   {
+   "description": "This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower",
    "fieldname": "payment_account",
    "fieldtype": "Link",
    "label": "Payment Account",
@@ -83,6 +84,7 @@
    "reqd": 1
   },
   {
+   "description": "This account is capital account which is used to allocate capital for loan disbursal account ",
    "fieldname": "loan_account",
    "fieldtype": "Link",
    "label": "Loan Account",
@@ -94,6 +96,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "description": "This account will be used for booking loan interest accruals",
    "fieldname": "interest_income_account",
    "fieldtype": "Link",
    "label": "Interest Income Account",
@@ -101,6 +104,7 @@
    "reqd": 1
   },
   {
+   "description": "This account will be used for booking penalties levied due to delayed repayments",
    "fieldname": "penalty_income_account",
    "fieldtype": "Link",
    "label": "Penalty Income Account",
@@ -109,6 +113,7 @@
   },
   {
    "default": "0",
+   "description": "If this is not checked the loan by default will be considered as a Demand Loan",
    "fieldname": "is_term_loan",
    "fieldtype": "Check",
    "label": "Is Term Loan"
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 8062342..c51f655 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -911,6 +911,7 @@
 	return out
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def item_query(doctype, txt, searchfield, start, page_len, filters):
 	meta = frappe.get_meta("Item", cached=True)
 	searchfields = meta.get_search_fields()
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index f962a11..b7d968e 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -632,6 +632,7 @@
 		return bom
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_bom_operations(doctype, txt, searchfield, start, page_len, filters):
 	if txt:
 		filters['operation'] = ('like', '%%%s%%' % txt)
diff --git a/erpnext/manufacturing/report/bom_variance_report/bom_variance_report.py b/erpnext/manufacturing/report/bom_variance_report/bom_variance_report.py
index e3e440e..dc424b7 100644
--- a/erpnext/manufacturing/report/bom_variance_report/bom_variance_report.py
+++ b/erpnext/manufacturing/report/bom_variance_report/bom_variance_report.py
@@ -30,7 +30,7 @@
 				"width": 180
 			}
 		])
-	
+
 	columns.extend([
 		{
 			"label": _("Finished Good"),
@@ -73,7 +73,7 @@
 	])
 
 	return columns
-	
+
 def get_data(filters):
 	cond = "1=1"
 
@@ -95,6 +95,7 @@
 	return results
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_work_orders(doctype, txt, searchfield, start, page_len, filters):
 	cond = "1=1"
 	if filters.get('bom_no'):
diff --git a/erpnext/manufacturing/report/downtime_analysis/downtime_analysis.js b/erpnext/manufacturing/report/downtime_analysis/downtime_analysis.js
index ff32dbe..f648674 100644
--- a/erpnext/manufacturing/report/downtime_analysis/downtime_analysis.js
+++ b/erpnext/manufacturing/report/downtime_analysis/downtime_analysis.js
@@ -8,7 +8,7 @@
 			label: __("From Date"),
 			fieldname:"from_date",
 			fieldtype: "Datetime",
-			default: frappe.datetime.add_months(frappe.datetime.now_datetime(), -1),
+			default: frappe.datetime.convert_to_system_tz(frappe.datetime.add_months(frappe.datetime.now_datetime(), -1)),
 			reqd: 1
 		},
 		{
diff --git a/erpnext/manufacturing/report/production_planning_report/production_planning_report.py b/erpnext/manufacturing/report/production_planning_report/production_planning_report.py
index 5ac3923..ebc01c6 100644
--- a/erpnext/manufacturing/report/production_planning_report/production_planning_report.py
+++ b/erpnext/manufacturing/report/production_planning_report/production_planning_report.py
@@ -369,6 +369,3 @@
 			"fieldtype": "Float",
 			"width": 140
 		}])
-
-def document_query(doctype, txt, searchfield, start, page_len, filters):
-	pass
\ No newline at end of file
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 3bd4169..e17e949 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -679,7 +679,6 @@
 erpnext.patches.v12_0.update_appointment_reminder_scheduler_entry
 erpnext.patches.v12_0.rename_pos_closing_doctype
 erpnext.patches.v13_0.replace_pos_payment_mode_table
-erpnext.patches.v12_0.retain_permission_rules_for_video_doctype
 erpnext.patches.v12_0.remove_duplicate_leave_ledger_entries #2020-05-22
 erpnext.patches.v13_0.patch_to_fix_reverse_linking_in_additional_salary_encashment_and_incentive
 execute:frappe.reload_doc("HR", "doctype", "Employee Advance")
@@ -688,6 +687,7 @@
 execute:frappe.rename_doc("Desk Page", "Getting Started", "Home", force=True)
 erpnext.patches.v12_0.unset_customer_supplier_based_on_type_of_item_price
 erpnext.patches.v12_0.set_valid_till_date_in_supplier_quotation
+erpnext.patches.v13_0.update_old_loans
 erpnext.patches.v12_0.set_serial_no_status #2020-05-21
 erpnext.patches.v12_0.update_price_list_currency_in_bom
 execute:frappe.delete_doc_if_exists('Dashboard', 'Accounts')
@@ -718,3 +718,7 @@
 erpnext.patches.v12_0.update_item_tax_template_company
 erpnext.patches.v13_0.move_branch_code_to_bank_account
 erpnext.patches.v13_0.healthcare_lab_module_rename_doctypes
+erpnext.patches.v13_0.stock_entry_enhancements
+erpnext.patches.v12_0.update_state_code_for_daman_and_diu
+erpnext.patches.v12_0.rename_lost_reason_detail
+erpnext.patches.v13_0.update_start_end_date_for_old_shift_assignment
diff --git a/erpnext/patches/v12_0/rename_lost_reason_detail.py b/erpnext/patches/v12_0/rename_lost_reason_detail.py
new file mode 100644
index 0000000..044d023
--- /dev/null
+++ b/erpnext/patches/v12_0/rename_lost_reason_detail.py
@@ -0,0 +1,17 @@
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+    if frappe.db.exists("DocType", "Lost Reason Detail"):
+        frappe.reload_doc("crm", "doctype", "opportunity_lost_reason_detail")
+        frappe.reload_doc("setup", "doctype", "quotation_lost_reason_detail")
+
+        frappe.db.sql("""INSERT INTO `tabOpportunity Lost Reason Detail` SELECT * FROM `tabLost Reason Detail` WHERE `parenttype` = 'Opportunity'""")
+
+        frappe.db.sql("""INSERT INTO `tabQuotation Lost Reason Detail` SELECT * FROM `tabLost Reason Detail` WHERE `parenttype` = 'Quotation'""")
+
+        frappe.db.sql("""INSERT INTO `tabQuotation Lost Reason` (`name`, `creation`, `modified`, `modified_by`, `owner`, `docstatus`, `parent`, `parentfield`, `parenttype`, `idx`, `_comments`, `_assign`, `_user_tags`, `_liked_by`, `order_lost_reason`) 
+            SELECT o.`name`, o.`creation`, o.`modified`, o.`modified_by`, o.`owner`, o.`docstatus`, o.`parent`, o.`parentfield`, o.`parenttype`, o.`idx`, o.`_comments`, o.`_assign`, o.`_user_tags`, o.`_liked_by`, o.`lost_reason` 
+            FROM `tabOpportunity Lost Reason` o LEFT JOIN `tabQuotation Lost Reason` q ON q.name = o.name WHERE q.name IS NULL""")
+        
+        frappe.delete_doc("DocType", "Lost Reason Detail")
\ No newline at end of file
diff --git a/erpnext/patches/v12_0/retain_permission_rules_for_video_doctype.py b/erpnext/patches/v12_0/retain_permission_rules_for_video_doctype.py
deleted file mode 100644
index ca8a13b..0000000
--- a/erpnext/patches/v12_0/retain_permission_rules_for_video_doctype.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from __future__ import unicode_literals
-import frappe
-
-def execute():
-	# to retain the roles and permissions from Education Module
-	# after moving doctype to core
-	permissions = frappe.db.sql("""
-		SELECT
-			*
-		FROM
-			`tabDocPerm`
-		WHERE
-			parent='Video'
-	""", as_dict=True)
-
-	frappe.reload_doc('core', 'doctype', 'video')
-	doc = frappe.get_doc('DocType', 'Video')
-	doc.permissions = []
-	for perm in permissions:
-		doc.append('permissions', perm)
-	doc.save()
diff --git a/erpnext/patches/v12_0/stock_entry_enhancements.py b/erpnext/patches/v12_0/stock_entry_enhancements.py
index d04b3d3..847d928 100644
--- a/erpnext/patches/v12_0/stock_entry_enhancements.py
+++ b/erpnext/patches/v12_0/stock_entry_enhancements.py
@@ -19,7 +19,7 @@
 
 	for purpose in ["Material Issue", "Material Receipt", "Material Transfer",
 		"Material Transfer for Manufacture", "Material Consumption for Manufacture", "Manufacture",
-		"Repack", "Send to Subcontractor", "Send to Warehouse", "Receive at Warehouse"]:
+		"Repack", "Send to Subcontractor"]:
 
 		ste_type = frappe.get_doc({
 			'doctype': 'Stock Entry Type',
diff --git a/erpnext/patches/v12_0/update_state_code_for_daman_and_diu.py b/erpnext/patches/v12_0/update_state_code_for_daman_and_diu.py
new file mode 100644
index 0000000..7450e9c
--- /dev/null
+++ b/erpnext/patches/v12_0/update_state_code_for_daman_and_diu.py
@@ -0,0 +1,22 @@
+import frappe
+from erpnext.regional.india import states
+
+def execute():
+
+	company = frappe.get_all('Company', filters = {'country': 'India'})
+	if not company:
+		return
+
+	# Update options in gst_state custom field
+	gst_state = frappe.get_doc('Custom Field', 'Address-gst_state')
+	gst_state.options = '\n'.join(states)
+	gst_state.save()
+
+	# Update gst_state and state code in existing address
+	frappe.db.sql("""
+		UPDATE `tabAddress`
+		SET
+			gst_state = 'Dadra and Nagar Haveli and Daman and Diu',
+			gst_state_number = 26
+		WHERE gst_state = 'Daman and Diu'
+	""")
\ No newline at end of file
diff --git a/erpnext/patches/v13_0/stock_entry_enhancements.py b/erpnext/patches/v13_0/stock_entry_enhancements.py
new file mode 100644
index 0000000..dcc4f95
--- /dev/null
+++ b/erpnext/patches/v13_0/stock_entry_enhancements.py
@@ -0,0 +1,27 @@
+# Copyright(c) 2020, Frappe Technologies Pvt.Ltd.and Contributors
+# License: GNU General Public License v3.See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+    frappe.reload_doc("stock", "doctype", "stock_entry")
+    if frappe.db.has_column("Stock Entry", "add_to_transit"):
+        frappe.db.sql("""
+            UPDATE `tabStock Entry` SET 
+            stock_entry_type = 'Material Transfer',
+            purpose = 'Material Transfer',
+            add_to_transit = 1 WHERE stock_entry_type = 'Send to Warehouse'
+            """)
+
+        frappe.db.sql("""UPDATE `tabStock Entry` SET 
+            stock_entry_type = 'Material Transfer',
+            purpose = 'Material Transfer'
+            WHERE stock_entry_type = 'Receive at Warehouse'
+            """)
+        
+        frappe.reload_doc("stock", "doctype", "warehouse_type")
+        if not frappe.db.exists('Warehouse Type', 'Transit'):
+            doc = frappe.new_doc('Warehouse Type')
+            doc.name = 'Transit'
+            doc.insert()
\ No newline at end of file
diff --git a/erpnext/patches/v13_0/update_old_loans.py b/erpnext/patches/v13_0/update_old_loans.py
new file mode 100644
index 0000000..7723942
--- /dev/null
+++ b/erpnext/patches/v13_0/update_old_loans.py
@@ -0,0 +1,88 @@
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.utils import nowdate
+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
+
+def execute():
+
+	# Create a penalty account for loan types
+
+	frappe.reload_doc('loan_management', 'doctype', 'loan_type')
+	frappe.reload_doc('loan_management', 'doctype', 'loan')
+	frappe.reload_doc('loan_management', 'doctype', 'repayment_schedule')
+	frappe.reload_doc('loan_management', 'doctype', 'process_loan_interest_accrual')
+	frappe.reload_doc('loan_management', 'doctype', 'loan_repayment')
+	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')
+
+	updated_loan_types = []
+
+	loans = frappe.get_all('Loan', fields=['name', 'loan_type', 'company', 'status', 'mode_of_payment',
+		'applicant_type', 'applicant', 'loan_account', 'payment_account', 'interest_income_account'])
+
+	for loan in loans:
+		# Update details in Loan Types and Loan
+		loan_type_company = frappe.db.get_value('Loan Type', loan.loan_type, 'company')
+
+		group_income_account = frappe.get_value('Account', {'company': loan.company,
+			'is_group': 1, 'root_type': 'Income', 'account_name': _('Indirect Income')})
+
+		if not group_income_account:
+			group_income_account = frappe.get_value('Account', {'company': loan.company,
+				'is_group': 1, 'root_type': 'Income'})
+
+		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:
+			loan_type_doc = frappe.get_doc('Loan Type', loan.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()
+			updated_loan_types.append(loan.loan_type)
+
+		if loan.loan_type in updated_loan_types:
+			if loan.status == 'Fully Disbursed':
+				status = 'Disbursed'
+			elif loan.status == 'Repaid/Closed':
+				status = 'Closed'
+			else:
+				status = loan.status
+
+			frappe.db.set_value('Loan', loan.name, {
+				'is_term_loan': 1,
+				'penalty_income_account': penalty_account,
+				'status': status
+			})
+
+			process_loan_interest_accrual_for_term_loans(posting_date=nowdate(), loan_type=loan.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)
+
+				repayment_entry.amount_paid = payment.debit_in_account_currency
+				repayment_entry.posting_date = payment.posting_date
+				repayment_entry.save()
+				repayment_entry.submit()
+
+				jv = frappe.get_doc('Journal Entry', payment.name)
+				jv.flags.ignore_links = True
+				jv.cancel()
+
diff --git a/erpnext/patches/v13_0/update_start_end_date_for_old_shift_assignment.py b/erpnext/patches/v13_0/update_start_end_date_for_old_shift_assignment.py
new file mode 100644
index 0000000..7c07b98
--- /dev/null
+++ b/erpnext/patches/v13_0/update_start_end_date_for_old_shift_assignment.py
@@ -0,0 +1,10 @@
+# Copyright (c) 2019, 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', 'shift_assignment')
+    frappe.db.sql("update `tabShift Assignment` set end_date=date, start_date=date where date IS NOT NULL and start_date IS NULL and end_date IS NULL;")
diff --git a/erpnext/payroll/desk_page/payroll/payroll.json b/erpnext/payroll/desk_page/payroll/payroll.json
index cb063c1..8fe8c44 100644
--- a/erpnext/payroll/desk_page/payroll/payroll.json
+++ b/erpnext/payroll/desk_page/payroll/payroll.json
@@ -8,7 +8,7 @@
   {
    "hidden": 0,
    "label": "Taxation",
-   "links": "[\n    {\n        \"label\": \"Payroll Period\",\n        \"name\": \"Payroll Period\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n        \n    },\n    {\n        \"label\": \"Income Tax Slab\",\n        \"name\": \"Income Tax Slab\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n        \n    },\n    {\n        \"label\": \"Employee Tax Exemption Declaration\",\n        \"name\": \"Employee Tax Exemption Declaration\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n        \n    },\n    {\n        \"label\": \"Employee Tax Exemption Proof Submission\",\n        \"name\": \"Employee Tax Exemption Proof Submission\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n        \n    },\n    {\n        \"label\": \"Employee Tax Exemption Category\",\n        \"name\": \"Employee Tax Exemption Category\",\n        \"type\": \"doctype\"\n        \n    },\n    {\n        \"label\": \"Employee Tax Exemption Sub Category\",\n        \"name\": \"Employee Tax Exemption Sub Category\",\n        \"type\": \"doctype\"\n        \n    }\n]"
+   "links": "[\n    {\n        \"label\": \"Payroll Period\",\n        \"name\": \"Payroll Period\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n        \n    },\n    {\n        \"label\": \"Income Tax Slab\",\n        \"name\": \"Income Tax Slab\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n        \n    },\n    {\n        \"label\": \"Employee Other Income\",\n        \"name\": \"Employee Other Income\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n        \n    },\n    {\n        \"label\": \"Employee Tax Exemption Declaration\",\n        \"name\": \"Employee Tax Exemption Declaration\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n        \n    },\n    {\n        \"label\": \"Employee Tax Exemption Proof Submission\",\n        \"name\": \"Employee Tax Exemption Proof Submission\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n        \n    },\n    {\n        \"label\": \"Employee Tax Exemption Category\",\n        \"name\": \"Employee Tax Exemption Category\",\n        \"type\": \"doctype\"\n        \n    },\n    {\n        \"label\": \"Employee Tax Exemption Sub Category\",\n        \"name\": \"Employee Tax Exemption Sub Category\",\n        \"type\": \"doctype\"\n        \n    }\n]"
   },
   {
    "hidden": 0,
@@ -39,7 +39,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "Payroll",
- "modified": "2020-06-30 18:33:29.072946",
+ "modified": "2020-08-10 19:38:45.976209",
  "modified_by": "Administrator",
  "module": "Payroll",
  "name": "Payroll",
diff --git a/erpnext/payroll/doctype/employee_benefit_application/employee_benefit_application.py b/erpnext/payroll/doctype/employee_benefit_application/employee_benefit_application.py
index d7d00e6..ef844fb 100644
--- a/erpnext/payroll/doctype/employee_benefit_application/employee_benefit_application.py
+++ b/erpnext/payroll/doctype/employee_benefit_application/employee_benefit_application.py
@@ -223,6 +223,7 @@
 	return benefit_amount
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_earning_components(doctype, txt, searchfield, start, page_len, filters):
 	if len(filters) < 2:
 		return {}
diff --git a/erpnext/payroll/doctype/payroll_entry/payroll_entry.py b/erpnext/payroll/doctype/payroll_entry/payroll_entry.py
index ad9b6d8..30ea432 100644
--- a/erpnext/payroll/doctype/payroll_entry/payroll_entry.py
+++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.py
@@ -90,7 +90,7 @@
 		cond = ''
 		for f in ['company', 'branch', 'department', 'designation']:
 			if self.get(f):
-				cond += " and t1." + f + " = '" + self.get(f).replace("'", "\'") + "'"
+				cond += " and t1." + f + " = " + frappe.db.escape(self.get(f))
 
 		return cond
 
@@ -540,6 +540,7 @@
 		frappe.msgprint(_("Could not submit some Salary Slips"))
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_payroll_entries_for_jv(doctype, txt, searchfield, start, page_len, filters):
 	return frappe.db.sql("""
 		select name from `tabPayroll Entry`
diff --git a/erpnext/payroll/doctype/salary_detail/salary_detail.json b/erpnext/payroll/doctype/salary_detail/salary_detail.json
index adb54f2..cc87cae 100644
--- a/erpnext/payroll/doctype/salary_detail/salary_detail.json
+++ b/erpnext/payroll/doctype/salary_detail/salary_detail.json
@@ -7,27 +7,30 @@
  "field_order": [
   "salary_component",
   "abbr",
-  "statistical_component",
   "column_break_3",
-  "deduct_full_tax_on_selected_payroll_date",
+  "amount",
+  "section_break_5",
+  "additional_salary",
+  "statistical_component",
   "depends_on_payment_days",
-  "is_tax_applicable",
   "exempted_from_income_tax",
+  "is_tax_applicable",
+  "column_break_11",
   "is_flexible_benefit",
   "variable_based_on_taxable_salary",
+  "do_not_include_in_total",
+  "deduct_full_tax_on_selected_payroll_date",
   "section_break_2",
   "condition",
+  "column_break_18",
   "amount_based_on_formula",
   "formula",
-  "amount",
-  "do_not_include_in_total",
+  "section_break_19",
   "default_amount",
   "additional_amount",
+  "column_break_24",
   "tax_on_flexible_benefit",
-  "tax_on_additional_salary",
-  "section_break_11",
-  "additional_salary",
-  "condition_and_formula_help"
+  "tax_on_additional_salary"
  ],
  "fields": [
   {
@@ -110,9 +113,11 @@
    "read_only": 1
   },
   {
+   "collapsible": 1,
    "depends_on": "eval:doc.is_flexible_benefit != 1",
    "fieldname": "section_break_2",
-   "fieldtype": "Section Break"
+   "fieldtype": "Section Break",
+   "label": "Condtion and formula"
   },
   {
    "allow_on_submit": 1,
@@ -182,22 +187,11 @@
    "read_only": 1
   },
   {
-   "depends_on": "eval:doc.parenttype=='Salary Structure'",
-   "fieldname": "section_break_11",
-   "fieldtype": "Column Break"
-  },
-  {
-   "depends_on": "eval:doc.parenttype=='Salary Structure'",
-   "fieldname": "condition_and_formula_help",
-   "fieldtype": "HTML",
-   "label": "Condition and Formula Help",
-   "options": "<h3>Condition and Formula Help</h3>\n\n<p>Notes:</p>\n\n<ol>\n<li>Use field <code>base</code> for using base salary of the Employee</li>\n<li>Use Salary Component abbreviations in conditions and formulas. <code>BS = Basic Salary</code></li>\n<li>Use field name for employee details in conditions and formulas. <code>Employment Type = employment_type</code><code>Branch = branch</code></li>\n<li>Use field name from Salary Slip in conditions and formulas. <code>Payment Days = payment_days</code><code>Leave without pay = leave_without_pay</code></li>\n<li>Direct Amount can also be entered based on Condtion. See example 3</li></ol>\n\n<h4>Examples</h4>\n<ol>\n<li>Calculating Basic Salary based on <code>base</code>\n<pre><code>Condition: base &lt; 10000</code></pre>\n<pre><code>Formula: base * .2</code></pre></li>\n<li>Calculating HRA based on Basic Salary<code>BS</code> \n<pre><code>Condition: BS &gt; 2000</code></pre>\n<pre><code>Formula: BS * .1</code></pre></li>\n<li>Calculating TDS based on Employment Type<code>employment_type</code> \n<pre><code>Condition: employment_type==\"Intern\"</code></pre>\n<pre><code>Amount: 1000</code></pre></li>\n</ol>"
-  },
-  {
    "fieldname": "additional_salary",
    "fieldtype": "Link",
    "label": "Additional Salary ",
-   "options": "Additional Salary"
+   "options": "Additional Salary",
+   "read_only": 1
   },
   {
    "default": "0",
@@ -207,11 +201,43 @@
    "fieldtype": "Check",
    "label": "Exempted from Income Tax",
    "read_only": 1
+  },
+  {
+   "collapsible": 1,
+   "fieldname": "section_break_5",
+   "fieldtype": "Section Break",
+   "label": "Component properties and references ",
+   "show_days": 1,
+   "show_seconds": 1
+  },
+  {
+   "fieldname": "column_break_11",
+   "fieldtype": "Column Break",
+   "show_days": 1,
+   "show_seconds": 1
+  },
+  {
+   "fieldname": "section_break_19",
+   "fieldtype": "Section Break",
+   "show_days": 1,
+   "show_seconds": 1
+  },
+  {
+   "fieldname": "column_break_18",
+   "fieldtype": "Column Break",
+   "show_days": 1,
+   "show_seconds": 1
+  },
+  {
+   "fieldname": "column_break_24",
+   "fieldtype": "Column Break",
+   "show_days": 1,
+   "show_seconds": 1
   }
  ],
  "istable": 1,
  "links": [],
- "modified": "2020-06-22 23:21:26.300951",
+ "modified": "2020-07-01 12:13:41.956495",
  "modified_by": "Administrator",
  "module": "Payroll",
  "name": "Salary Detail",
diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.js b/erpnext/payroll/doctype/salary_slip/salary_slip.js
index 4b623e5..7b69dbe 100644
--- a/erpnext/payroll/doctype/salary_slip/salary_slip.js
+++ b/erpnext/payroll/doctype/salary_slip/salary_slip.js
@@ -123,13 +123,13 @@
 			doc: frm.doc,
 			callback: function(r, rt) {
 				frm.refresh();
-				if (frm.doc.absent_days){
+				if (r.message){
 					frm.fields_dict.absent_days.set_description("Unmarked Days is treated as "+ r.message +". You can can change this in " + frappe.utils.get_form_link("Payroll Settings", "Payroll Settings", true));
 				}
 			}
 		});
 	}
-})
+});
 
 frappe.ui.form.on('Salary Slip Timesheet', {
 	time_sheet: function(frm, dt, dn) {
diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.json b/erpnext/payroll/doctype/salary_slip/salary_slip.json
index 27a974a..619c45f 100644
--- a/erpnext/payroll/doctype/salary_slip/salary_slip.json
+++ b/erpnext/payroll/doctype/salary_slip/salary_slip.json
@@ -20,15 +20,17 @@
   "company",
   "letter_head",
   "section_break_10",
-  "salary_slip_based_on_timesheet",
   "start_date",
   "end_date",
   "salary_structure",
+  "column_break_18",
+  "salary_slip_based_on_timesheet",
   "payroll_frequency",
-  "column_break_15",
+  "section_break_20",
   "total_working_days",
   "unmarked_days",
   "leave_without_pay",
+  "column_break_24",
   "absent_days",
   "payment_days",
   "hourly_wages",
@@ -201,10 +203,6 @@
    "label": "End Date"
   },
   {
-   "fieldname": "column_break_15",
-   "fieldtype": "Column Break"
-  },
-  {
    "fieldname": "salary_structure",
    "fieldtype": "Link",
    "label": "Salary Structure",
@@ -490,13 +488,25 @@
    "fieldtype": "Float",
    "hidden": 1,
    "label": "Unmarked days"
+  },
+  {
+   "fieldname": "section_break_20",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_24",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "column_break_18",
+   "fieldtype": "Column Break"
   }
  ],
  "icon": "fa fa-file-text",
  "idx": 9,
  "is_submittable": 1,
  "links": [],
- "modified": "2020-07-22 12:41:03.659422",
+ "modified": "2020-08-11 17:37:54.274384",
  "modified_by": "Administrator",
  "module": "Payroll",
  "name": "Salary Slip",
diff --git a/erpnext/portal/product_configurator/utils.py b/erpnext/portal/product_configurator/utils.py
index f8af30a..9eef16b 100644
--- a/erpnext/portal/product_configurator/utils.py
+++ b/erpnext/portal/product_configurator/utils.py
@@ -239,7 +239,8 @@
 	if exact_match:
 		data = get_product_info_for_website(exact_match[0])
 		product_info = data.product_info
-		product_info["allow_items_not_in_stock"] = cint(data.cart_settings.allow_items_not_in_stock)
+		if product_info:
+			product_info["allow_items_not_in_stock"] = cint(data.cart_settings.allow_items_not_in_stock)
 		if not data.cart_settings.show_price:
 			product_info = None
 	else:
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index 6350f86..5bbd29c 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -239,6 +239,7 @@
 	}
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_users_for_project(doctype, txt, searchfield, start, page_len, filters):
 	conditions = []
 	return frappe.db.sql("""select name, concat_ws(' ', first_name, middle_name, last_name)
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index cf2fd26..fb84094 100755
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -193,6 +193,7 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_project(doctype, txt, searchfield, start, page_len, filters):
 	from erpnext.controllers.queries import get_match_cond
 	return frappe.db.sql(""" select name from `tabProject`
diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js
index 5de2930..607c3fd 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.js
+++ b/erpnext/projects/doctype/timesheet/timesheet.js
@@ -94,13 +94,6 @@
 		}
 	},
 
-	company: function(frm) {
-		frappe.db.get_value('Company', { 'company_name' : frm.doc.company }, 'standard_working_hours')
-			.then(({ message }) => {
-				(frappe.working_hours = message.standard_working_hours || 0);
-			});
-	},
-
 	make_invoice: function(frm) {
 		let dialog = new frappe.ui.Dialog({
 			title: __("Select Item (optional)"),
diff --git a/erpnext/projects/doctype/timesheet/timesheet.py b/erpnext/projects/doctype/timesheet/timesheet.py
index 7fe22be..9e807f7 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.py
+++ b/erpnext/projects/doctype/timesheet/timesheet.py
@@ -214,6 +214,7 @@
 			and sales_invoice is null""".format(cond), {'project': project, 'parent': parent}, as_dict=1)
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_timesheet(doctype, txt, searchfield, start, page_len, filters):
 	if not filters: filters = {}
 
diff --git a/erpnext/projects/utils.py b/erpnext/projects/utils.py
index d0d88eb..c39f908 100644
--- a/erpnext/projects/utils.py
+++ b/erpnext/projects/utils.py
@@ -7,6 +7,7 @@
 import frappe
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def query_task(doctype, txt, searchfield, start, page_len, filters):
 	from frappe.desk.reportview import build_match_conditions
 
diff --git a/erpnext/public/js/communication.js b/erpnext/public/js/communication.js
index 5316eb4..26e5ab8 100644
--- a/erpnext/public/js/communication.js
+++ b/erpnext/public/js/communication.js
@@ -7,13 +7,13 @@
 	},
 
 	setup_custom_buttons: (frm) => {
-		let confirm_msg = "Are you sure you want to create {0} from this email";
+		let confirm_msg = "Are you sure you want to create {0} from this email?";
 		if(frm.doc.reference_doctype !== "Issue") {
 			frm.add_custom_button(__("Issue"), () => {
 				frappe.confirm(__(confirm_msg, [__("Issue")]), () => {
 					frm.trigger('make_issue_from_communication');
 				})
-			}, "Make");
+			}, "Create");
 		}
 
 		if(!in_list(["Lead", "Opportunity"], frm.doc.reference_doctype)) {
@@ -62,17 +62,36 @@
 	},
 
 	make_opportunity_from_communication: (frm) => {
-		return frappe.call({
-			method: "erpnext.crm.doctype.opportunity.opportunity.make_opportunity_from_communication",
-			args: {
-				communication: frm.doc.name
-			},
-			freeze: true,
-			callback: (r) => {
-				if(r.message) {
-					frm.reload_doc()
+		const fields = [{
+			fieldtype: 'Link',
+			label: __('Select a Company'),
+			fieldname: 'company',
+			options: 'Company',
+			reqd: 1,
+			default: frappe.defaults.get_user_default("Company")
+		}];
+
+		frappe.prompt(fields, data => {
+			frappe.call({
+				method: "erpnext.crm.doctype.opportunity.opportunity.make_opportunity_from_communication",
+				args: {
+					communication: frm.doc.name,
+					company: data.company
+				},
+				freeze: true,
+				callback: (r) => {
+					if(r.message) {
+						frm.reload_doc();
+						frappe.show_alert({
+							message: __("Opportunity {0} created",
+								['<a href="#Form/Opportunity/'+r.message+'">' + r.message + '</a>']),
+							indicator: 'green'
+						});
+					}
 				}
-			}
-		})
+			});
+		},
+		'Create an Opportunity',
+		'Create');
 	}
-});
\ No newline at end of file
+});
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index 405a33c..6951539 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -163,9 +163,11 @@
 		$.each(me.frm.doc["items"] || [], function(n, item) {
 			var item_tax_map = me._load_item_tax_rate(item.item_tax_rate);
 			var cumulated_tax_fraction = 0.0;
-
+			var total_inclusive_tax_amount_per_qty = 0;
 			$.each(me.frm.doc["taxes"] || [], function(i, tax) {
-				tax.tax_fraction_for_current_item = me.get_current_tax_fraction(tax, item_tax_map);
+				var current_tax_fraction = me.get_current_tax_fraction(tax, item_tax_map);
+				tax.tax_fraction_for_current_item = current_tax_fraction[0];
+				var inclusive_tax_amount_per_qty = current_tax_fraction[1];
 
 				if(i==0) {
 					tax.grand_total_fraction_for_current_item = 1 + tax.tax_fraction_for_current_item;
@@ -176,10 +178,12 @@
 				}
 
 				cumulated_tax_fraction += tax.tax_fraction_for_current_item;
+				total_inclusive_tax_amount_per_qty += inclusive_tax_amount_per_qty * flt(item.qty);
 			});
 
-			if(cumulated_tax_fraction && !me.discount_amount_applied) {
-				item.net_amount = flt(item.amount / (1 + cumulated_tax_fraction));
+			if(!me.discount_amount_applied && item.qty && (total_inclusive_tax_amount_per_qty || cumulated_tax_fraction)) {
+				var amount = flt(item.amount) - total_inclusive_tax_amount_per_qty;
+				item.net_amount = flt(amount / (1 + cumulated_tax_fraction));
 				item.net_rate = item.qty ? flt(item.net_amount / item.qty, precision("net_rate", item)) : 0;
 
 				me.set_in_company_currency(item, ["net_rate", "net_amount"]);
@@ -191,6 +195,7 @@
 		// Get tax fraction for calculating tax exclusive amount
 		// from tax inclusive amount
 		var current_tax_fraction = 0.0;
+		var inclusive_tax_amount_per_qty = 0;
 
 		if(cint(tax.included_in_print_rate)) {
 			var tax_rate = this._get_tax_rate(tax, item_tax_map);
@@ -205,13 +210,16 @@
 			} else if(tax.charge_type == "On Previous Row Total") {
 				current_tax_fraction = (tax_rate / 100.0) *
 					this.frm.doc["taxes"][cint(tax.row_id) - 1].grand_total_fraction_for_current_item;
+			} else if (tax.charge_type == "On Item Quantity") {
+				inclusive_tax_amount_per_qty = flt(tax_rate);
 			}
 		}
 
-		if(tax.add_deduct_tax) {
-			current_tax_fraction *= (tax.add_deduct_tax == "Deduct") ? -1.0 : 1.0;
+		if(tax.add_deduct_tax && tax.add_deduct_tax == "Deduct") {
+			current_tax_fraction *= -1;
+			inclusive_tax_amount_per_qty *= -1;
 		}
-		return current_tax_fraction;
+		return [current_tax_fraction, inclusive_tax_amount_per_qty];
 	},
 
 	_get_tax_rate: function(tax, item_tax_map) {
@@ -360,8 +368,9 @@
 		} else if(tax.charge_type == "On Previous Row Total") {
 			current_tax_amount = (tax_rate / 100.0) *
 				this.frm.doc["taxes"][cint(tax.row_id) - 1].grand_total_for_current_item;
+		} else if (tax.charge_type == "On Item Quantity") {
+			current_tax_amount = tax_rate * item.qty;
 		}
-
 		this.set_item_wise_tax(item, tax, tax_rate, current_tax_amount);
 
 		return current_tax_amount;
@@ -573,7 +582,7 @@
 			var actual_taxes_dict = {};
 
 			$.each(this.frm.doc["taxes"] || [], function(i, tax) {
-				if (tax.charge_type == "Actual") {
+				if (in_list(["Actual", "On Item Quantity"], tax.charge_type)) {
 					var tax_amount = (tax.category == "Valuation") ? 0.0 : tax.tax_amount;
 					tax_amount *= (tax.add_deduct_tax == "Deduct") ? -1.0 : 1.0;
 					actual_taxes_dict[tax.idx] = tax_amount;
@@ -586,7 +595,7 @@
 			$.each(actual_taxes_dict, function(key, value) {
 				if (value) total_actual_tax += value;
 			});
-
+			
 			return flt(this.frm.doc.grand_total - total_actual_tax, precision("grand_total"));
 		}
 	},
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 4e50f3d..436a232 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -1821,7 +1821,6 @@
 	},
 
 	set_query_for_item_tax_template: function(doc, cdt, cdn) {
-
 		var item = frappe.get_doc(cdt, cdn);
 		if(!item.item_code) {
 			frappe.throw(__("Please enter Item Code to get item taxes"));
@@ -1829,7 +1828,7 @@
 
 			let filters = {
 				'item_code': item.item_code,
-				'valid_from': doc.transaction_date || doc.bill_date || doc.posting_date,
+				'valid_from': ["<=", doc.transaction_date || doc.bill_date || doc.posting_date],
 				'item_group': item.item_group,
 			}
 
diff --git a/erpnext/public/less/products.less b/erpnext/public/less/products.less
index 79f57b3..5e744ce 100644
--- a/erpnext/public/less/products.less
+++ b/erpnext/public/less/products.less
@@ -22,6 +22,8 @@
 }
 
 .filter-options {
+	margin-left: -5px;
+	padding-left: 5px;
 	max-height: 300px;
 	overflow: auto;
 }
diff --git a/erpnext/public/less/website.less b/erpnext/public/less/website.less
index 57a0a33..ac878de 100644
--- a/erpnext/public/less/website.less
+++ b/erpnext/public/less/website.less
@@ -297,6 +297,10 @@
 	margin-top: 30px;
 }
 
+.item-group-slideshow {
+	margin-bottom: 1rem;
+}
+
 .product-image-img {
 	border: 1px solid @light-border-color;
 	border-radius: 3px;
diff --git a/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py b/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py
index 2d306ba..787d557 100644
--- a/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py
+++ b/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py
@@ -234,9 +234,6 @@
 						self.report_dict[supply_type][supply_category][account_map.get(account_type)] += \
 							flt(tax_details.get((account_name, gst_category), {}).get("amount"), 2)
 
-		for k, v in iteritems(account_map):
-			txval -= self.report_dict.get(supply_type, {}).get(supply_category, {}).get(v, 0)
-
 		self.report_dict[supply_type][supply_category]["txval"] += flt(txval, 2)
 
 	def set_inter_state_supply(self, inter_state_supply):
@@ -256,7 +253,7 @@
 	def get_total_taxable_value(self, doctype, reverse_charge):
 
 		return frappe._dict(frappe.db.sql("""
-			select gst_category, sum(base_grand_total) as total
+			select gst_category, sum(net_total) as total
 			from `tab{doctype}`
 			where docstatus = 1 and month(posting_date) = %s
 			and year(posting_date) = %s and reverse_charge = %s
@@ -309,26 +306,27 @@
 			inter_state_supply_tax_mapping.setdefault(d.name, {
 				'place_of_supply': d.place_of_supply,
 				'taxable_value': d.net_total,
+				'gst_category': d.gst_category,
 				'camt': 0.0,
 				'samt': 0.0,
 				'iamt': 0.0,
 				'csamt': 0.0
 			})
 
-			if d.account_head in [d.cgst_account for d in self.account_heads]:
+			if d.account_head in [a.cgst_account for a in self.account_heads]:
 				inter_state_supply_tax_mapping[d.name]['camt'] += d.tax_amount
 
-			if d.account_head in [d.sgst_account for d in self.account_heads]:
+			if d.account_head in [a.sgst_account for a in self.account_heads]:
 				inter_state_supply_tax_mapping[d.name]['samt'] += d.tax_amount
 
-			if d.account_head in [d.igst_account for d in self.account_heads]:
+			if d.account_head in [a.igst_account for a in self.account_heads]:
 				inter_state_supply_tax_mapping[d.name]['iamt'] += d.tax_amount
 
-			if d.account_head in [d.cess_account for d in self.account_heads]:
+			if d.account_head in [a.cess_account for a in self.account_heads]:
 				inter_state_supply_tax_mapping[d.name]['csamt'] += d.tax_amount
 
 		for key, value in iteritems(inter_state_supply_tax_mapping):
-			if d.place_of_supply:
+			if value.get('place_of_supply'):
 				osup_det = self.report_dict["sup_details"]["osup_det"]
 				osup_det["txval"] = flt(osup_det["txval"] + value['taxable_value'], 2)
 				osup_det["iamt"] = flt(osup_det["iamt"] + value['iamt'], 2)
@@ -336,15 +334,15 @@
 				osup_det["samt"] = flt(osup_det["samt"] + value['samt'], 2)
 				osup_det["csamt"] = flt(osup_det["csamt"] + value['csamt'], 2)
 
-				if state_number != d.place_of_supply.split("-")[0]:
-					inter_state_supply_details.setdefault((d.gst_category, d.place_of_supply), {
+				if state_number != value.get('place_of_supply').split("-")[0]:
+					inter_state_supply_details.setdefault((value.get('gst_category'), value.get('place_of_supply')), {
 						"txval": 0.0,
-						"pos": d.place_of_supply.split("-")[0],
+						"pos": value.get('place_of_supply').split("-")[0],
 						"iamt": 0.0
 					})
 
-					inter_state_supply_details[(d.gst_category, d.place_of_supply)]['txval'] += value['taxable_value']
-					inter_state_supply_details[(d.gst_category, d.place_of_supply)]['iamt'] += value['iamt']
+					inter_state_supply_details[(value.get('gst_category'), value.get('place_of_supply'))]['txval'] += value['taxable_value']
+					inter_state_supply_details[(value.get('gst_category'), value.get('place_of_supply'))]['iamt'] += value['iamt']
 
 		return inter_state_supply_details
 
diff --git a/erpnext/regional/india/__init__.py b/erpnext/regional/india/__init__.py
index 0ed98b7..d6221a8 100644
--- a/erpnext/regional/india/__init__.py
+++ b/erpnext/regional/india/__init__.py
@@ -10,8 +10,7 @@
  'Bihar',
  'Chandigarh',
  'Chhattisgarh',
- 'Dadra and Nagar Haveli',
- 'Daman and Diu',
+ 'Dadra and Nagar Haveli and Daman and Diu',
  'Delhi',
  'Goa',
  'Gujarat',
@@ -50,8 +49,7 @@
  "Bihar": "10",
  "Chandigarh": "04",
  "Chhattisgarh": "22",
- "Dadra and Nagar Haveli": "26",
- "Daman and Diu": "25",
+ "Dadra and Nagar Haveli and Daman and Diu": "26",
  "Delhi": "07",
  "Goa": "30",
  "Gujarat": "24",
diff --git a/erpnext/regional/india/gst_state_code_data.json b/erpnext/regional/india/gst_state_code_data.json
index 6dab81d..ff88e0f 100644
--- a/erpnext/regional/india/gst_state_code_data.json
+++ b/erpnext/regional/india/gst_state_code_data.json
@@ -135,14 +135,9 @@
   "state_name": "Delhi"
  },
  {
-  "state_number": "25",
-  "state_code": "DD",
-  "state_name": "Daman and Diu"
- },
- {
   "state_number": "26",
   "state_code": "DN",
-  "state_name": "Dadra and Nagar Haveli"
+  "state_name": "Dadra and Nagar Haveli and Daman and Diu"
  },
  {
   "state_number": "22",
diff --git a/erpnext/regional/india/taxes.js b/erpnext/regional/india/taxes.js
index 4d36cff..fbccc6b 100644
--- a/erpnext/regional/india/taxes.js
+++ b/erpnext/regional/india/taxes.js
@@ -10,6 +10,8 @@
 			frm.trigger('get_tax_template');
 		},
 		get_tax_template: function(frm) {
+			if (!frm.doc.company) return;
+
 			let party_details = {
 				'shipping_address': frm.doc.shipping_address || '',
 				'shipping_address_name': frm.doc.shipping_address_name || '',
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index fe7e0c8..69e47a4 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -1,6 +1,7 @@
 from __future__ import unicode_literals
 import frappe, re, json
 from frappe import _
+import erpnext
 from frappe.utils import cstr, flt, date_diff, nowdate, round_based_on_smallest_currency_fraction, money_in_words
 from erpnext.regional.india import states, state_numbers
 from erpnext.controllers.taxes_and_totals import get_itemised_tax, get_itemised_taxable_amount
@@ -673,25 +674,34 @@
 	if country != 'India':
 		return
 
+	if not doc.total_taxes_and_charges:
+		return
+
 	if doc.reverse_charge == 'Y':
 		gst_accounts = get_gst_accounts(doc.company)
 		gst_account_list = gst_accounts.get('cgst_account') + gst_accounts.get('sgst_account') \
 			+ gst_accounts.get('igst_account')
 
+		base_gst_tax = 0
 		gst_tax = 0
+
 		for tax in doc.get('taxes'):
 			if tax.category not in ("Total", "Valuation and Total"):
 				continue
 
 			if flt(tax.base_tax_amount_after_discount_amount) and tax.account_head in gst_account_list:
-				gst_tax += tax.base_tax_amount_after_discount_amount
+				base_gst_tax += tax.base_tax_amount_after_discount_amount
+				gst_tax += tax.tax_amount_after_discount_amount
 
 		doc.taxes_and_charges_added -= gst_tax
 		doc.total_taxes_and_charges -= gst_tax
+		doc.base_taxes_and_charges_added -= base_gst_tax
+		doc.base_total_taxes_and_charges -= base_gst_tax
 
-		update_totals(gst_tax, doc)
+		update_totals(gst_tax, base_gst_tax, doc)
 
-def update_totals(gst_tax, doc):
+def update_totals(gst_tax, base_gst_tax, doc):
+	doc.base_grand_total -= base_gst_tax
 	doc.grand_total -= gst_tax
 
 	if doc.meta.get_field("rounded_total"):
@@ -707,13 +717,14 @@
 			doc.outstanding_amount = doc.rounded_total or doc.grand_total
 
 	doc.in_words = money_in_words(doc.grand_total, doc.currency)
+	doc.base_in_words = money_in_words(doc.base_grand_total, erpnext.get_company_currency(doc.company))
 	doc.set_payment_schedule()
 
 def make_regional_gl_entries(gl_entries, doc):
 	country = frappe.get_cached_value('Company', doc.company, 'country')
 
 	if country != 'India':
-		return
+		return gl_entries
 
 	if doc.reverse_charge == 'Y':
 		gst_accounts = get_gst_accounts(doc.company)
@@ -724,6 +735,7 @@
 			if tax.category not in ("Total", "Valuation and Total"):
 				continue
 
+			dr_or_cr = "credit" if tax.add_deduct_tax == "Add" else "debit"
 			if flt(tax.base_tax_amount_after_discount_amount) and tax.account_head in gst_account_list:
 				account_currency = get_account_currency(tax.account_head)
 
@@ -733,8 +745,8 @@
 						"cost_center": tax.cost_center,
 						"posting_date": doc.posting_date,
 						"against": doc.supplier,
-						"credit": tax.base_tax_amount_after_discount_amount,
-						"credits_in_account_currency": tax.base_tax_amount_after_discount_amount \
+						dr_or_cr: tax.base_tax_amount_after_discount_amount,
+						dr_or_cr + "_in_account_currency": tax.base_tax_amount_after_discount_amount \
 							if account_currency==doc.company_currency \
 							else tax.tax_amount_after_discount_amount
 					}, account_currency, item=tax)
diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py
index 8885b88..282efe4 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.py
+++ b/erpnext/regional/report/gstr_1/gstr_1.py
@@ -131,6 +131,9 @@
 					taxable_value += abs(net_amount)
 				elif tax_rate:
 					taxable_value += abs(net_amount)
+				elif not tax_rate and self.filters.get('type_of_business') == 'EXPORT' \
+					and invoice_details.get('export_type') == "Without Payment of Tax":
+					taxable_value += abs(net_amount)
 
 		row += [tax_rate or 0, taxable_value]
 
diff --git a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py
index 222dfa1..a3ed4ce 100644
--- a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py
+++ b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py
@@ -7,6 +7,8 @@
 from frappe.utils import flt
 from frappe.model.meta import get_field_precision
 from frappe.utils.xlsxutils import handle_html
+from six import iteritems
+import json
 
 def execute(filters=None):
 	return _execute(filters)
@@ -21,21 +23,24 @@
 		itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)
 
 	data = []
+	added_item = []
 	for d in item_list:
-		row = [d.gst_hsn_code, d.description, d.stock_uom, d.stock_qty]
-		total_tax = 0
-		for tax in tax_columns:
-			item_tax = itemised_tax.get(d.name, {}).get(tax, {})
-			total_tax += flt(item_tax.get("tax_amount"))
+		if (d.parent, d.item_code) not in added_item:
+			row = [d.gst_hsn_code, d.description, d.stock_uom, d.stock_qty]
+			total_tax = 0
+			for tax in tax_columns:
+				item_tax = itemised_tax.get((d.parent, d.item_code), {}).get(tax, {})
+				total_tax += flt(item_tax.get("tax_amount", 0))
 
-		row += [d.base_net_amount + total_tax]
-		row += [d.base_net_amount]
+			row += [d.base_net_amount + total_tax]
+			row += [d.base_net_amount]
 
-		for tax in tax_columns:
-			item_tax = itemised_tax.get(d.name, {}).get(tax, {})
-			row += [item_tax.get("tax_amount", 0)]
+			for tax in tax_columns:
+				item_tax = itemised_tax.get((d.parent, d.item_code), {}).get(tax, {})
+				row += [item_tax.get("tax_amount", 0)]
 
-		data.append(row)
+			data.append(row)
+			added_item.append((d.parent, d.item_code))
 	if data:
 		data = get_merged_data(columns, data) # merge same hsn code data
 	return columns, data
@@ -103,7 +108,7 @@
 		match_conditions = " and {0} ".format(match_conditions)
 
 
-	return frappe.db.sql("""
+	items = frappe.db.sql("""
 		select
 			`tabSales Invoice Item`.name, `tabSales Invoice Item`.base_price_list_rate,
 			`tabSales Invoice Item`.gst_hsn_code, `tabSales Invoice Item`.stock_qty,
@@ -118,10 +123,9 @@
 
 		""" % (conditions, match_conditions), filters, as_dict=1)
 
+	return items
 
-def get_tax_accounts(item_list, columns, company_currency,
-		doctype="Sales Invoice", tax_doctype="Sales Taxes and Charges"):
-	import json
+def get_tax_accounts(item_list, columns, company_currency, doctype="Sales Invoice", tax_doctype="Sales Taxes and Charges"):
 	item_row_map = {}
 	tax_columns = []
 	invoice_item_row = {}
@@ -171,7 +175,7 @@
 					for d in item_row_map.get(parent, {}).get(item_code, []):
 						item_tax_amount = tax_amount
 						if item_tax_amount:
-							itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
+							itemised_tax.setdefault((parent, item_code), {})[description] = frappe._dict({
 								"tax_amount": flt(item_tax_amount, tax_amount_precision)
 							})
 			except ValueError:
@@ -179,42 +183,32 @@
 
 	tax_columns.sort()
 	for desc in tax_columns:
-		columns.append(desc + " Amount:Currency/currency:160")
+		columns.append({
+			"label": desc,
+			"fieldname": frappe.scrub(desc),
+			"fieldtype": "Float",
+			"width": 110
+		})
 
-	# columns += ["Total Amount:Currency/currency:110"]
 	return itemised_tax, tax_columns
 
 def get_merged_data(columns, data):
 	merged_hsn_dict = {} # to group same hsn under one key and perform row addition
-	add_column_index = [] # store index of columns that needs to be added
-	tax_col = len(get_columns())
-	fields_to_merge = ["stock_qty", "total_amount", "taxable_amount"] # columns for which index needs to be found
-
-	for i,d in enumerate(columns):
-		# check if fieldname in to_merge list and ignore tax-columns
-		if i < tax_col and d["fieldname"] in fields_to_merge:
-			add_column_index.append(i)
+	result = []
 
 	for row in data:
-		if row[0] in merged_hsn_dict:
-			to_add_row = merged_hsn_dict.get(row[0])
+		merged_hsn_dict.setdefault(row[0], {})
+		for i, d in enumerate(columns):
+			if d['fieldtype'] not in ('Int', 'Float', 'Currency'):
+				merged_hsn_dict[row[0]][d['fieldname']] = row[i]
+			else:
+				if merged_hsn_dict.get(row[0], {}).get(d['fieldname'], ''):
+					merged_hsn_dict[row[0]][d['fieldname']] += row[i]
+				else:
+					merged_hsn_dict[row[0]][d['fieldname']] = row[i]
 
-			# add columns from the add_column_index table
-			for k in add_column_index:
-				to_add_row[k] += row[k]
+	for key, value in iteritems(merged_hsn_dict):
+		result.append(value)
 
-			# add tax columns
-			for k in range(len(columns)):
-				if tax_col <= k < len(columns):
-					to_add_row[k] += row[k]
-
-			# update hsn dict with the newly added data
-			merged_hsn_dict[row[0]] = to_add_row
-		else:
-			merged_hsn_dict[row[0]] = row
-
-	# extract data rows to be displayed in report
-	data = [merged_hsn_dict[d] for d in merged_hsn_dict]
-
-	return data
+	return result
 
diff --git a/erpnext/selling/desk_page/selling/selling.json b/erpnext/selling/desk_page/selling/selling.json
index 7dcb71f..77301fe 100644
--- a/erpnext/selling/desk_page/selling/selling.json
+++ b/erpnext/selling/desk_page/selling/selling.json
@@ -18,7 +18,7 @@
   {
    "hidden": 0,
    "label": "Key Reports",
-   "links": "[\n    {\n        \"dependencies\": [\n            \"Sales Order\"\n        ],\n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Sales Analytics\",\n        \"name\": \"Sales Analytics\",\n        \"onboard\": 1,\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Sales Order\"\n        ],\n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Sales Order Analysis\",\n        \"name\": \"Sales Order Analysis\",\n        \"onboard\": 1,\n        \"type\": \"report\"\n    },\n    {\n        \"icon\": \"fa fa-bar-chart\",\n        \"label\": \"Sales Funnel\",\n        \"name\": \"sales-funnel\",\n        \"onboard\": 1,\n        \"type\": \"page\"\n    },\n    {\n        \"dependencies\": [\n            \"Sales Order\"\n        ],\n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Sales Order Trends\",\n        \"name\": \"Sales Order Trends\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Quotation\"\n        ],\n        \"doctype\": \"Quotation\",\n        \"is_query_report\": true,\n        \"label\": \"Quotation Trends\",\n        \"name\": \"Quotation Trends\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Customer\"\n        ],\n        \"doctype\": \"Customer\",\n        \"icon\": \"fa fa-bar-chart\",\n        \"is_query_report\": true,\n        \"label\": \"Customer Acquisition and Loyalty\",\n        \"name\": \"Customer Acquisition and Loyalty\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Sales Order\"\n        ],\n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Inactive Customers\",\n        \"name\": \"Inactive Customers\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Sales Order\"\n        ],\n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Sales Person-wise Transaction Summary\",\n        \"name\": \"Sales Person-wise Transaction Summary\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Item\"\n        ],\n        \"doctype\": \"Item\",\n        \"is_query_report\": true,\n        \"label\": \"Item-wise Sales History\",\n        \"name\": \"Item-wise Sales History\",\n        \"type\": \"report\"\n    }\n]"
+   "links": "[\n    {\n     \n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Sales Analytics\",\n        \"name\": \"Sales Analytics\",\n        \"onboard\": 1,\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Sales Order\"\n        ],\n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Sales Order Analysis\",\n        \"name\": \"Sales Order Analysis\",\n        \"onboard\": 1,\n        \"type\": \"report\"\n    },\n    {\n        \"icon\": \"fa fa-bar-chart\",\n        \"label\": \"Sales Funnel\",\n        \"name\": \"sales-funnel\",\n        \"onboard\": 1,\n        \"type\": \"page\"\n    },\n    {\n        \"dependencies\": [\n            \"Sales Order\"\n        ],\n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Sales Order Trends\",\n        \"name\": \"Sales Order Trends\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Quotation\"\n        ],\n        \"doctype\": \"Quotation\",\n        \"is_query_report\": true,\n        \"label\": \"Quotation Trends\",\n        \"name\": \"Quotation Trends\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Customer\"\n        ],\n        \"doctype\": \"Customer\",\n        \"icon\": \"fa fa-bar-chart\",\n        \"is_query_report\": true,\n        \"label\": \"Customer Acquisition and Loyalty\",\n        \"name\": \"Customer Acquisition and Loyalty\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Sales Order\"\n        ],\n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Inactive Customers\",\n        \"name\": \"Inactive Customers\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Sales Order\"\n        ],\n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Sales Person-wise Transaction Summary\",\n        \"name\": \"Sales Person-wise Transaction Summary\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Item\"\n        ],\n        \"doctype\": \"Item\",\n        \"is_query_report\": true,\n        \"label\": \"Item-wise Sales History\",\n        \"name\": \"Item-wise Sales History\",\n        \"type\": \"report\"\n    }\n]"
   },
   {
    "hidden": 0,
@@ -45,7 +45,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "Selling",
- "modified": "2020-06-30 18:32:50.587478",
+ "modified": "2020-08-15 10:12:53.131621",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Selling",
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index e614acd..93d4832 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -184,6 +184,14 @@
 	def validate_credit_limit_on_change(self):
 		if self.get("__islocal") or not self.credit_limits:
 			return
+		
+		past_credit_limits = [d.credit_limit
+			for d in frappe.db.get_all("Customer Credit Limit", filters={'parent': self.name}, fields=["credit_limit"], order_by="company")]
+		
+		current_credit_limits = [d.credit_limit for d in sorted(self.credit_limits, key=lambda k: k.company)]
+
+		if past_credit_limits == current_credit_limits:
+			return
 
 		company_record = []
 		for limit in self.credit_limits:
@@ -340,6 +348,7 @@
 	return lp_details
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_customer_list(doctype, txt, searchfield, start, page_len, filters=None):
 	from erpnext.controllers.queries import get_fields
 	fields = ["name", "customer_name", "customer_group", "territory"]
@@ -542,6 +551,7 @@
 	return address
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_customer_primary_contact(doctype, txt, searchfield, start, page_len, filters):
 	customer = filters.get('customer')
 	return frappe.db.sql("""
diff --git a/erpnext/selling/doctype/customer/customer_dashboard.py b/erpnext/selling/doctype/customer/customer_dashboard.py
index 22e30e3..09e474d 100644
--- a/erpnext/selling/doctype/customer/customer_dashboard.py
+++ b/erpnext/selling/doctype/customer/customer_dashboard.py
@@ -12,7 +12,8 @@
 			'Payment Entry': 'party',
 			'Quotation': 'party_name',
 			'Opportunity': 'party_name',
-			'Bank Account': 'party'
+			'Bank Account': 'party',
+			'Subscription': 'party'
 		},
 		'dynamic_links': {
 			'party_name': ['Customer', 'quotation_to']
diff --git a/erpnext/selling/doctype/lead_source/lead_source.json b/erpnext/selling/doctype/lead_source/lead_source.json
index 868f6d1..373e83a 100644
--- a/erpnext/selling/doctype/lead_source/lead_source.json
+++ b/erpnext/selling/doctype/lead_source/lead_source.json
@@ -1,7 +1,7 @@
 {
  "allow_copy": 0, 
  "allow_import": 0, 
- "allow_rename": 0, 
+ "allow_rename": 1, 
  "autoname": "field:source_name", 
  "beta": 0, 
  "creation": "2016-09-16 01:47:47.382372", 
@@ -74,7 +74,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-09-16 02:03:01.441622", 
+ "modified": "2020-09-16 02:03:01.441622", 
  "modified_by": "Administrator", 
  "module": "Selling", 
  "name": "Lead Source", 
@@ -128,4 +128,4 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_seen": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/selling/doctype/product_bundle/product_bundle.py b/erpnext/selling/doctype/product_bundle/product_bundle.py
index 0c85a1b..d3281f7 100644
--- a/erpnext/selling/doctype/product_bundle/product_bundle.py
+++ b/erpnext/selling/doctype/product_bundle/product_bundle.py
@@ -29,6 +29,7 @@
 				frappe.throw(_("Row #{0}: Child Item should not be a Product Bundle. Please remove Item {1} and Save").format(item.idx, frappe.bold(item.item_code)))
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_new_item_code(doctype, txt, searchfield, start, page_len, filters):
 	from erpnext.controllers.queries import get_match_cond
 
diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json
index 6d34c2a..5b85187 100644
--- a/erpnext/selling/doctype/quotation/quotation.json
+++ b/erpnext/selling/doctype/quotation/quotation.json
@@ -923,7 +923,7 @@
    "fieldname": "lost_reasons",
    "fieldtype": "Table MultiSelect",
    "label": "Lost Reasons",
-   "options": "Lost Reason Detail",
+   "options": "Quotation Lost Reason Detail",
    "read_only": 1
   }
  ],
@@ -932,7 +932,7 @@
  "is_submittable": 1,
  "links": [],
  "max_attachments": 1,
- "modified": "2020-07-18 04:59:09.960118",
+ "modified": "2020-07-26 17:46:19.951223",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Quotation",
diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py
index 449a968..ab095eb 100644
--- a/erpnext/selling/doctype/quotation/quotation.py
+++ b/erpnext/selling/doctype/quotation/quotation.py
@@ -68,7 +68,7 @@
 
 	def declare_enquiry_lost(self, lost_reasons_list, detailed_reason=None):
 		if not self.has_sales_order():
-			get_lost_reasons = frappe.get_list('Opportunity Lost Reason',
+			get_lost_reasons = frappe.get_list('Quotation Lost Reason',
 			fields = ["name"])
 			lost_reasons_lst = [reason.get('name') for reason in get_lost_reasons]
 			frappe.db.set(self, 'status', 'Lost')
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index ffb6635..f882898 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -888,6 +888,7 @@
 
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_supplier(doctype, txt, searchfield, start, page_len, filters):
 	supp_master_name = frappe.defaults.get_user_default("supp_master_name")
 	if supp_master_name == "Supplier Name":
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.py b/erpnext/selling/page/point_of_sale/point_of_sale.py
index f7b7ed8..83bd71d 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.py
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.py
@@ -14,10 +14,9 @@
 def get_items(start, page_length, price_list, item_group, search_value="", pos_profile=None):
 	data = dict()
 	warehouse = ""
-	display_items_in_stock = 0
 
 	if pos_profile:
-		warehouse, display_items_in_stock = frappe.db.get_value('POS Profile', pos_profile, ['warehouse', 'display_items_in_stock'])
+		warehouse = frappe.db.get_value('POS Profile', pos_profile, ['warehouse'])
 
 	if not frappe.db.exists('Item Group', item_group):
 		item_group = get_root_of('Item Group')
@@ -85,7 +84,7 @@
 			item_price = item_prices.get(item_code) or {}
 			item_stock_qty = get_stock_availability(item_code, warehouse)
 
-			if display_items_in_stock and not item_stock_qty:
+			if not item_stock_qty:
 				pass
 			else:
 				row = {}
@@ -160,6 +159,7 @@
 	return cond % tuple(item_groups)
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def item_group_query(doctype, txt, searchfield, start, page_len, filters):
 	item_groups = []
 	cond = "1=1"
@@ -179,12 +179,12 @@
 
 @frappe.whitelist()
 def check_opening_entry(user):
-	open_vouchers = frappe.db.get_all("POS Opening Entry", 
-		filters = { 
-			"user": user, 
+	open_vouchers = frappe.db.get_all("POS Opening Entry",
+		filters = {
+			"user": user,
 			"pos_closing_entry": ["in", ["", None]],
 			"docstatus": 1
-		}, 
+		},
 		fields = ["name", "company", "pos_profile", "period_start_date"],
 		order_by = "period_start_date desc"
 	)
@@ -229,7 +229,7 @@
 		invoice_list = frappe.db.get_all('POS Invoice', filters={
 			'status': status
 		}, fields=fields)
-	
+
 	return invoice_list
 
 @frappe.whitelist()
@@ -244,7 +244,7 @@
 		if fieldname == 'email_id':
 			contact_doc.set('email_ids', [{ 'email_id': value, 'is_primary': 1}])
 			frappe.db.set_value('Customer', customer, 'email_id', value)
-		elif fieldname == 'mobile_no': 
+		elif fieldname == 'mobile_no':
 			contact_doc.set('phone_nos', [{ 'phone': value, 'is_primary_mobile_no': 1}])
 			frappe.db.set_value('Customer', customer, 'mobile_no', value)
 		contact_doc.save()
\ No newline at end of file
diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js
index 483ef78..ae5471b 100644
--- a/erpnext/selling/page/point_of_sale/pos_controller.js
+++ b/erpnext/selling/page/point_of_sale/pos_controller.js
@@ -35,7 +35,8 @@
 	create_opening_voucher() {
 		const table_fields = [
 			{ fieldname: "mode_of_payment", fieldtype: "Link", in_list_view: 1, label: "Mode of Payment", options: "Mode of Payment", reqd: 1 },
-			{ fieldname: "opening_amount", fieldtype: "Currency", in_list_view: 1, label: "Opening Amount", options: "company:company_currency", reqd: 1 }
+			{ fieldname: "opening_amount", fieldtype: "Currency", default: 0, in_list_view: 1, label: "Opening Amount", 
+				options: "company:company_currency", reqd: 1 }
 		];
 
 		const dialog = new frappe.ui.Dialog({
@@ -66,7 +67,7 @@
 							frappe.db.get_doc("POS Closing Entry", pos_closing_entry.name).then(({ payment_reconciliation }) => {
 								dialog.fields_dict.balance_details.df.data = [];
 								payment_reconciliation.forEach(pay => {
-									const { mode_of_payment, closing_amount } = pay;
+									const { mode_of_payment } = pay;
 									dialog.fields_dict.balance_details.df.data.push({
 										mode_of_payment: mode_of_payment
 									});
@@ -152,7 +153,7 @@
 			},
 			() => this.make_new_invoice(),
 			() => frappe.dom.unfreeze(),
-			() => this.page.set_title(__('Point of Sale Beta')),
+			() => this.page.set_title(__('Point of Sale')),
 		]);
 	}
 
diff --git a/erpnext/selling/page/point_of_sale/pos_past_order_summary.js b/erpnext/selling/page/point_of_sale/pos_past_order_summary.js
index 24326b2..30e0918 100644
--- a/erpnext/selling/page/point_of_sale/pos_past_order_summary.js
+++ b/erpnext/selling/page/point_of_sale/pos_past_order_summary.js
@@ -86,7 +86,7 @@
         this.$summary_container.append(
             `<div class="summary-btns flex summary-btns justify-between w-full f-shrink-0"></div>`
         )
-        
+
         this.$summary_btns = this.$summary_container.find('.summary-btns');
     }
 
@@ -110,7 +110,10 @@
                 {fieldname:'print', fieldtype:'Data', label:'Print Preview'}
             ],
             primary_action: () => {
-                this.events.get_frm().print_preview.printit(true);
+                const frm = this.events.get_frm();
+                frm.doc = this.doc;
+                frm.print_preview.lang_code = frm.doc.language;
+                frm.print_preview.printit(true);
             },
             primary_action_label: __('Print'),
         });
@@ -174,7 +177,7 @@
                     <div class="flex">
                         <div class="text-md-0 text-dark-grey text-bold w-fit">Tax Charges</div>
                         <div class="flex ml-6 text-dark-grey">
-                        ${	
+                        ${
                             doc.taxes.map((t, i) => {
                                 let margin_left = '';
                                 if (i !== 0) margin_left = 'ml-2';
@@ -271,6 +274,7 @@
             // this.print_dialog.show();
             const frm = this.events.get_frm();
             frm.doc = this.doc;
+            frm.print_preview.lang_code = frm.doc.language;
             frm.print_preview.printit(true);
         });
     }
@@ -284,9 +288,9 @@
             this.$summary_container.find('.print-btn').click();
         });
     }
-    
+
     toggle_component(show) {
-        show ? 
+        show ?
         this.$component.removeClass('d-none') :
         this.$component.addClass('d-none');
     }
@@ -372,9 +376,9 @@
     }
 
     get_condition_btn_map(after_submission) {
-        if (after_submission) 
+        if (after_submission)
             return [{ condition: true, visible_btns: ['Print Receipt', 'Email Receipt', 'New Order'] }];
-        
+
         return [
             { condition: this.doc.docstatus === 0, visible_btns: ['Edit Order'] },
             { condition: !this.doc.is_return && this.doc.docstatus === 1, visible_btns: ['Print Receipt', 'Email Receipt', 'Return']},
@@ -384,7 +388,7 @@
 
     load_summary_of(doc, after_submission=false) {
         this.$summary_wrapper.removeClass("d-none");
-        
+
         after_submission ?
             this.switch_to_post_submit_summary() : this.switch_to_recent_invoice_summary();
 
diff --git a/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py
index 7e8e6e9..f5feb95 100644
--- a/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py
+++ b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py
@@ -96,7 +96,7 @@
 		# prepare data for report view
 		row["qty_to_bill"] = flt(row["qty"]) - flt(row["billed_qty"])
 
-		row["delay"] = 0 if row["delay"] < 0 else row["delay"]
+		row["delay"] = 0 if row["delay"] and row["delay"] < 0 else row["delay"]
 		if filters.get("group_by_so"):
 			so_name = row["sales_order"]
 
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index 333a563..002cfe4 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -494,13 +494,18 @@
 		var dialog = new frappe.ui.Dialog({
 			title: __("Set as Lost"),
 			fields: [
-				{"fieldtype": "Table MultiSelect",
-				"label": __("Lost Reasons"),
-				"fieldname": "lost_reason",
-				"options": "Lost Reason Detail",
-				"reqd": 1},
-
-				{"fieldtype": "Text", "label": __("Detailed Reason"), "fieldname": "detailed_reason"},
+				{
+					"fieldtype": "Table MultiSelect",
+					"label": __("Lost Reasons"),
+					"fieldname": "lost_reason",
+					"options": frm.doctype === 'Opportunity' ? 'Opportunity Lost Reason Detail': 'Quotation Lost Reason Detail',
+					"reqd": 1
+				},
+				{
+					"fieldtype": "Text",
+					"label": __("Detailed Reason"),
+					"fieldname": "detailed_reason"
+				},
 			],
 			primary_action: function() {
 				var values = dialog.get_values();
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index 7ae5385..f882db6 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -34,6 +34,16 @@
 		frm.set_query("default_buying_terms", function() {
 			return { filters: { buying: 1 } };
 		});
+
+		frm.set_query("default_in_transit_warehouse", function() {
+			return {
+				filters:{
+					'warehouse_type' : 'Transit',
+					'is_group': 0,
+					'company': frm.doc.company
+				}
+			};
+		});
 	},
 
 	company_name: function(frm) {
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index 221044d..4a26a71 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -25,6 +25,7 @@
   "default_selling_terms",
   "default_buying_terms",
   "default_warehouse_for_sales_return",
+  "default_in_transit_warehouse",
   "column_break_10",
   "country",
   "create_chart_of_accounts_based_on",
@@ -242,7 +243,7 @@
   {
    "fieldname": "default_warehouse_for_sales_return",
    "fieldtype": "Link",
-   "label": "Default warehouse for Sales Return",
+   "label": "Default Warehouse for Sales Return",
    "options": "Warehouse"
   },
   {
@@ -733,6 +734,12 @@
    "fieldname": "enable_perpetual_inventory_for_non_stock_items",
    "fieldtype": "Check",
    "label": "Enable Perpetual Inventory For Non Stock Items"
+  },
+  {
+   "fieldname": "default_in_transit_warehouse",
+   "fieldtype": "Link",
+   "label": "Default In Transit Warehouse",
+   "options": "Warehouse"
   }
  ],
  "icon": "fa fa-building",
@@ -740,7 +747,7 @@
  "image_field": "company_logo",
  "is_tree": 1,
  "links": [],
- "modified": "2020-06-24 12:45:31.462195",
+ "modified": "2020-08-06 00:38:08.311216",
  "modified_by": "Administrator",
  "module": "Setup",
  "name": "Company",
@@ -801,4 +808,4 @@
  "sort_field": "modified",
  "sort_order": "ASC",
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 47b41a9..8e707fe 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -140,7 +140,8 @@
 			{"warehouse_name": _("All Warehouses"), "is_group": 1},
 			{"warehouse_name": _("Stores"), "is_group": 0},
 			{"warehouse_name": _("Work In Progress"), "is_group": 0},
-			{"warehouse_name": _("Finished Goods"), "is_group": 0}]:
+			{"warehouse_name": _("Finished Goods"), "is_group": 0},
+			{"warehouse_name": _("Goods In Transit"), "is_group": 0, "warehouse_type": "Transit"}]:
 
 			if not frappe.db.exists("Warehouse", "{0} - {1}".format(wh_detail["warehouse_name"], self.abbr)):
 				warehouse = frappe.get_doc({
@@ -149,7 +150,8 @@
 					"is_group": wh_detail["is_group"],
 					"company": self.name,
 					"parent_warehouse": "{0} - {1}".format(_("All Warehouses"), self.abbr) \
-						if not wh_detail["is_group"] else ""
+						if not wh_detail["is_group"] else "",
+					"warehouse_type" : wh_detail["warehouse_type"] if "warehouse_type" in wh_detail else None
 				})
 				warehouse.flags.ignore_permissions = True
 				warehouse.flags.ignore_mandatory = True
diff --git a/erpnext/setup/doctype/party_type/party_type.py b/erpnext/setup/doctype/party_type/party_type.py
index b29c305..96e6093 100644
--- a/erpnext/setup/doctype/party_type/party_type.py
+++ b/erpnext/setup/doctype/party_type/party_type.py
@@ -10,6 +10,7 @@
 	pass
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_party_type(doctype, txt, searchfield, start, page_len, filters):
 	cond = ''
 	if filters and filters.get('account'):
diff --git a/erpnext/setup/doctype/quotation_lost_reason_detail/__init__.py b/erpnext/setup/doctype/quotation_lost_reason_detail/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/setup/doctype/quotation_lost_reason_detail/__init__.py
diff --git a/erpnext/setup/doctype/quotation_lost_reason_detail/quotation_lost_reason_detail.json b/erpnext/setup/doctype/quotation_lost_reason_detail/quotation_lost_reason_detail.json
new file mode 100644
index 0000000..5432141
--- /dev/null
+++ b/erpnext/setup/doctype/quotation_lost_reason_detail/quotation_lost_reason_detail.json
@@ -0,0 +1,31 @@
+{
+ "actions": [],
+ "creation": "2020-07-14 09:21:44.057724",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "lost_reason"
+ ],
+ "fields": [
+  {
+   "fieldname": "lost_reason",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Quotation Lost Reason",
+   "options": "Quotation Lost Reason"
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-07-26 17:58:56.373775",
+ "modified_by": "Administrator",
+ "module": "Setup",
+ "name": "Quotation Lost Reason Detail",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/quotation_lost_reason_detail/quotation_lost_reason_detail.py b/erpnext/setup/doctype/quotation_lost_reason_detail/quotation_lost_reason_detail.py
new file mode 100644
index 0000000..7bb8d02
--- /dev/null
+++ b/erpnext/setup/doctype/quotation_lost_reason_detail/quotation_lost_reason_detail.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, 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 QuotationLostReasonDetail(Document):
+	pass
diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py
index aa9fbc0..50f9d84 100644
--- a/erpnext/setup/install.py
+++ b/erpnext/setup/install.py
@@ -7,6 +7,7 @@
 from erpnext.accounts.doctype.cash_flow_mapper.default_cash_flow_mapper import DEFAULT_MAPPERS
 from .default_success_action import get_default_success_action
 from frappe import _
+from frappe.utils import cint
 from frappe.desk.page.setup_wizard.setup_wizard import add_all_roles_to
 from frappe.custom.doctype.custom_field.custom_field import create_custom_field
 from erpnext.setup.default_energy_point_rules import get_default_energy_point_rules
@@ -29,8 +30,8 @@
 
 
 def check_setup_wizard_not_completed():
-	if frappe.db.get_default('desktop:home_page') != 'setup-wizard':
-		message = """ERPNext can only be installed on a fresh site where the setup wizard is not completed. 
+	if cint(frappe.db.get_single_value('System Settings', 'setup_complete') or 0):
+		message = """ERPNext can only be installed on a fresh site where the setup wizard is not completed.
 You can reinstall this site (after saving your data) using: bench --site [sitename] reinstall"""
 		frappe.throw(message)
 
diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py
index ad063cf..72ed002 100644
--- a/erpnext/setup/setup_wizard/operations/install_fixtures.py
+++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py
@@ -95,8 +95,6 @@
 		{'doctype': 'Stock Entry Type', 'name': 'Send to Subcontractor', 'purpose': 'Send to Subcontractor'},
 		{'doctype': 'Stock Entry Type', 'name': 'Material Transfer for Manufacture', 'purpose': 'Material Transfer for Manufacture'},
 		{'doctype': 'Stock Entry Type', 'name': 'Material Consumption for Manufacture', 'purpose': 'Material Consumption for Manufacture'},
-		{'doctype': 'Stock Entry Type', 'name': 'Send to Warehouse', 'purpose': 'Send to Warehouse'},
-		{'doctype': 'Stock Entry Type', 'name': 'Receive at Warehouse', 'purpose': 'Receive at Warehouse'},
 
 		# Designation
 		{'doctype': 'Designation', 'designation_name': _('CEO')},
@@ -244,7 +242,10 @@
 		{"doctype": "Sales Stage", "stage_name": _("Identifying Decision Makers")},
 		{"doctype": "Sales Stage", "stage_name": _("Perception Analysis")},
 		{"doctype": "Sales Stage", "stage_name": _("Proposal/Price Quote")},
-		{"doctype": "Sales Stage", "stage_name": _("Negotiation/Review")}
+		{"doctype": "Sales Stage", "stage_name": _("Negotiation/Review")},
+
+		# Warehouse Type
+		{'doctype': 'Warehouse Type', 'name': 'Transit'},
 	]
 
 	from erpnext.setup.setup_wizard.data.industry_type import get_industry_types
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.js b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.js
index 14500ba..21fa4c3 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.js
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.js
@@ -12,5 +12,11 @@
 		if (frm.doc.enabled === 1) {
 			frm.set_value('enable_variants', 1);
 		}
+		else {
+			frm.set_value('company', '');
+			frm.set_value('price_list', '');
+			frm.set_value('default_customer_group', '');
+			frm.set_value('quotation_series', '');
+		}
 	}
 });
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
index c574afa..32004ef 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
@@ -95,15 +95,16 @@
    "fieldtype": "Link",
    "in_list_view": 1,
    "label": "Company",
+   "mandatory_depends_on": "eval: doc.enabled === 1",
    "options": "Company",
-   "remember_last_selected_value": 1,
-   "reqd": 1
+   "remember_last_selected_value": 1
   },
   {
    "description": "Prices will not be shown if Price List is not set",
    "fieldname": "price_list",
    "fieldtype": "Link",
    "label": "Price List",
+   "mandatory_depends_on": "eval: doc.enabled === 1",
    "options": "Price List"
   },
   {
@@ -115,14 +116,14 @@
    "fieldtype": "Link",
    "ignore_user_permissions": 1,
    "label": "Default Customer Group",
-   "options": "Customer Group",
-   "reqd": 1
+   "mandatory_depends_on": "eval: doc.enabled === 1",
+   "options": "Customer Group"
   },
   {
    "fieldname": "quotation_series",
    "fieldtype": "Select",
    "label": "Quotation Series",
-   "reqd": 1
+   "mandatory_depends_on": "eval: doc.enabled === 1"
   },
   {
    "collapsible": 1,
@@ -171,7 +172,7 @@
  "idx": 1,
  "issingle": 1,
  "links": [],
- "modified": "2020-07-17 17:53:22.667228",
+ "modified": "2020-08-02 18:21:43.873303",
  "modified_by": "Administrator",
  "module": "Shopping Cart",
  "name": "Shopping Cart Settings",
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index 66efcf8..ea385c8 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -175,7 +175,7 @@
    "no_copy": 1,
    "oldfieldname": "naming_series",
    "oldfieldtype": "Select",
-   "options": "MAT-DN-.YYYY.-",
+   "options": "MAT-DN-.YYYY.-\nMAT-DN-RET-.YYYY.-",
    "print_hide": 1,
    "reqd": 1,
    "set_only_once": 1
@@ -1255,7 +1255,7 @@
  "idx": 146,
  "is_submittable": 1,
  "links": [],
- "modified": "2020-07-18 05:13:55.580420",
+ "modified": "2020-08-03 23:18:47.739997",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Delivery Note",
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index 735f35f..38e5fe5 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -117,7 +117,7 @@
 		const stock_exists = (frm.doc.__onload
 			&& frm.doc.__onload.stock_exists) ? 1 : 0;
 
-		['is_stock_item', 'has_serial_no', 'has_batch_no'].forEach((fieldname) => {
+		['is_stock_item', 'has_serial_no', 'has_batch_no', 'has_variants'].forEach((fieldname) => {
 			frm.set_df_property(fieldname, 'read_only', stock_exists);
 		});
 
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index 963c87a..d07b3dc 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -123,6 +123,7 @@
   "weightage",
   "slideshow",
   "website_image",
+  "website_image_alt",
   "thumbnail",
   "cb72",
   "website_warehouse",
@@ -473,6 +474,7 @@
   },
   {
    "default": "0",
+   "depends_on": "has_batch_no",
    "fieldname": "retain_sample",
    "fieldtype": "Check",
    "label": "Retain Sample"
@@ -499,7 +501,7 @@
    "oldfieldtype": "Select"
   },
   {
-   "depends_on": "eval:doc.is_stock_item || doc.is_fixed_asset",
+   "depends_on": "has_serial_no",
    "description": "Example: ABCD.#####\nIf series is set and Serial No is not mentioned in transactions, then automatic serial number will be created based on this series. If you always want to explicitly mention Serial Nos for this item. leave this blank.",
    "fieldname": "serial_no_series",
    "fieldtype": "Data",
@@ -1053,15 +1055,21 @@
    "fieldtype": "Data",
    "label": "Default Manufacturer Part No",
    "read_only": 1
+  },
+  {
+   "fieldname": "website_image_alt",
+   "fieldtype": "Data",
+   "label": "Image Description"
   }
  ],
  "has_web_view": 1,
  "icon": "fa fa-tag",
  "idx": 2,
  "image_field": "image",
+ "index_web_pages_for_search": 1,
  "links": [],
  "max_attachments": 1,
- "modified": "2020-06-30 12:01:07.534447",
+ "modified": "2020-08-07 14:24:58.384992",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Item",
@@ -1123,4 +1131,4 @@
  "sort_order": "DESC",
  "title_field": "item_name",
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index d7b43bf..d209f48 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -343,7 +343,7 @@
 			if variant:
 				context.variant = frappe.get_doc("Item", variant)
 
-				for fieldname in ("website_image", "web_long_description", "description",
+				for fieldname in ("website_image", "website_image_alt", "web_long_description", "description",
 										"website_specifications"):
 					if context.variant.get(fieldname):
 						value = context.variant.get(fieldname)
diff --git a/erpnext/stock/doctype/item_alternative/item_alternative.py b/erpnext/stock/doctype/item_alternative/item_alternative.py
index 522dfc6..190cb62 100644
--- a/erpnext/stock/doctype/item_alternative/item_alternative.py
+++ b/erpnext/stock/doctype/item_alternative/item_alternative.py
@@ -43,6 +43,7 @@
 			frappe.throw(_("Already record exists for the item {0}").format(self.item_code))
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_alternative_items(doctype, txt, searchfield, start, page_len, filters):
 	return frappe.db.sql(""" (select alternative_item_code from `tabItem Alternative`
 			where item_code = %(item_code)s and alternative_item_code like %(txt)s)
diff --git a/erpnext/stock/doctype/material_request/material_request.json b/erpnext/stock/doctype/material_request/material_request.json
index d1f29e3..44503d2 100644
--- a/erpnext/stock/doctype/material_request/material_request.json
+++ b/erpnext/stock/doctype/material_request/material_request.json
@@ -11,6 +11,7 @@
   "naming_series",
   "title",
   "material_request_type",
+  "transfer_status",
   "customer",
   "column_break_2",
   "schedule_date",
@@ -303,13 +304,22 @@
    "fieldtype": "Link",
    "label": "Set From Warehouse",
    "options": "Warehouse"
+  },
+  {
+   "allow_on_submit": 1,
+   "depends_on": "eval:doc.add_to_transit == 1",
+   "fieldname": "transfer_status",
+   "fieldtype": "Select",
+   "label": "Transfer Status",
+   "options": "\nNot Started\nIn Transit\nCompleted",
+   "read_only": 1
   }
  ],
  "icon": "fa fa-ticket",
  "idx": 70,
  "is_submittable": 1,
  "links": [],
- "modified": "2020-05-01 20:21:09.990867",
+ "modified": "2020-08-10 13:27:54.891058",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Material Request",
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index 25f1ed9..335175f 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -370,6 +370,7 @@
 	return supplier_items
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_material_requests_based_on_supplier(doctype, txt, searchfield, start, page_len, filters):
 	conditions = ""
 	if txt:
@@ -403,6 +404,7 @@
 	return material_requests
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_default_supplier_query(doctype, txt, searchfield, start, page_len, filters):
 	doc = frappe.get_doc("Material Request", filters.get("doc"))
 	item_list = []
diff --git a/erpnext/stock/doctype/material_request/material_request_list.js b/erpnext/stock/doctype/material_request/material_request_list.js
index 614ecb8..0d70958 100644
--- a/erpnext/stock/doctype/material_request/material_request_list.js
+++ b/erpnext/stock/doctype/material_request/material_request_list.js
@@ -1,8 +1,16 @@
 frappe.listview_settings['Material Request'] = {
-	add_fields: ["material_request_type", "status", "per_ordered", "per_received"],
+	add_fields: ["material_request_type", "status", "per_ordered", "per_received", "transfer_status"],
 	get_indicator: function(doc) {
 		if(doc.status=="Stopped") {
 			return [__("Stopped"), "red", "status,=,Stopped"];
+		} else if(doc.transfer_status && doc.docstatus != 2) {
+			if (doc.transfer_status == "Not Started") {
+				return [__("Not Started"), "orange"];
+			} else if (doc.transfer_status == "In Transit") {
+				return [__("In Transit"), "yellow"];
+			} else if (doc.transfer_status == "Completed") {
+				return [__("Completed"), "green"];
+			}
 		} else if(doc.docstatus==1 && flt(doc.per_ordered, 2) == 0) {
 			return [__("Pending"), "orange", "per_ordered,=,0"];
 		}  else if(doc.docstatus==1 && flt(doc.per_ordered, 2) < 100) {
diff --git a/erpnext/stock/doctype/packing_slip/packing_slip.py b/erpnext/stock/doctype/packing_slip/packing_slip.py
index 4f831d7..a7a29cc 100644
--- a/erpnext/stock/doctype/packing_slip/packing_slip.py
+++ b/erpnext/stock/doctype/packing_slip/packing_slip.py
@@ -176,6 +176,7 @@
 		self.update_item_details()
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def item_details(doctype, txt, searchfield, start, page_len, filters):
 	from erpnext.controllers.queries import get_match_cond
 	return frappe.db.sql("""select name, item_name, description from `tabItem`
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
index 92e33ca..ce54fc8 100755
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
@@ -1,7 +1,6 @@
 {
  "actions": [],
  "allow_import": 1,
- "allow_workflow": 1,
  "autoname": "naming_series:",
  "creation": "2013-05-21 16:16:39",
  "doctype": "DocType",
@@ -160,7 +159,7 @@
    "no_copy": 1,
    "oldfieldname": "naming_series",
    "oldfieldtype": "Select",
-   "options": "MAT-PRE-.YYYY.-",
+   "options": "MAT-PRE-.YYYY.-\nMAT-PR-RET-.YYYY.-",
    "print_hide": 1,
    "reqd": 1,
    "set_only_once": 1
@@ -1110,7 +1109,7 @@
  "idx": 261,
  "is_submittable": 1,
  "links": [],
- "modified": "2020-07-18 05:19:12.148115",
+ "modified": "2020-08-03 23:20:26.381024",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt",
diff --git a/erpnext/stock/doctype/quality_inspection/quality_inspection.py b/erpnext/stock/doctype/quality_inspection/quality_inspection.py
index 568e742..c3bb514 100644
--- a/erpnext/stock/doctype/quality_inspection/quality_inspection.py
+++ b/erpnext/stock/doctype/quality_inspection/quality_inspection.py
@@ -59,6 +59,7 @@
 				(quality_inspection, self.modified, self.reference_name, self.item_code))
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def item_query(doctype, txt, searchfield, start, page_len, filters):
 	if filters.get("from"):
 		from frappe.desk.reportview import get_match_cond
@@ -88,6 +89,7 @@
 			{'parent': filters.get('parent'), 'txt': "%%%s%%" % txt})
 
 @frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def quality_inspection_query(doctype, txt, searchfield, start, page_len, filters):
 	return frappe.get_all('Quality Inspection',
 		limit_start=start,
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 53b986c..9845bc2 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -19,7 +19,6 @@
 				filters: [
 					['Stock Entry', 'docstatus', '=', 1],
 					['Stock Entry', 'per_transferred', '<','100'],
-					['Stock Entry', 'purpose', '=', 'Send to Warehouse']
 				]
 			}
 		});
@@ -171,9 +170,9 @@
 			}
 		}
 
-		if (frm.doc.docstatus === 1 && frm.doc.purpose == 'Send to Warehouse') {
-			if (frm.doc.per_transferred < 100) {
-				frm.add_custom_button(__('Receive at Warehouse Entry'), function() {
+		if (frm.doc.docstatus === 1) {
+			if (frm.doc.add_to_transit && frm.doc.purpose=='Material Transfer' && frm.doc.per_transferred < 100) {
+				frm.add_custom_button('End Transit', function() {
 					frappe.model.open_mapped_doc({
 						method: "erpnext.stock.doctype.stock_entry.stock_entry.make_stock_in_entry",
 						frm: frm
@@ -266,6 +265,7 @@
 	stock_entry_type: function(frm){
 		frm.remove_custom_button('Bill of Materials', "Get items from");
 		frm.events.show_bom_custom_button(frm);
+		frm.trigger('add_to_transit');
 	},
 
 	purpose: function(frm) {
@@ -532,6 +532,26 @@
 
 	target_warehouse_address: function(frm) {
 		erpnext.utils.get_address_display(frm, 'target_warehouse_address', 'target_address_display', false);
+	},
+
+	add_to_transit: function(frm) {
+		if(frm.doc.add_to_transit && frm.doc.purpose=='Material Transfer') {
+			frm.set_value('stock_entry_type', 'Material Transfer');
+			frm.fields_dict.to_warehouse.get_query = function() {
+				return {
+					filters:{
+						'warehouse_type' : 'Transit',
+						'is_group': 0,
+						'company': frm.doc.company
+					}
+				};
+			};
+			frappe.db.get_value('Company', frm.doc.company, 'default_in_transit_warehouse', (r) => {
+				if (r.default_in_transit_warehouse) {
+					frm.set_value('to_warehouse', r.default_in_transit_warehouse);
+				}
+			});
+		}
 	}
 })
 
@@ -754,6 +774,7 @@
 		}
 		erpnext.hide_company();
 		erpnext.utils.add_item(this.frm);
+		this.frm.trigger('add_to_transit');
 	},
 
 	scan_barcode: function() {
@@ -919,8 +940,6 @@
 			doc.purpose!='Material Issue');
 
 		this.frm.fields_dict["items"].grid.set_column_disp("additional_cost", doc.purpose!='Material Issue');
-		this.frm.toggle_reqd("outgoing_stock_entry",
-			doc.purpose == 'Receive at Warehouse' ? 1: 0);
 	},
 
 	supplier: function(doc) {
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.json b/erpnext/stock/doctype/stock_entry/stock_entry.json
index 704ae41..61e0df6 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.json
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.json
@@ -13,6 +13,7 @@
   "stock_entry_type",
   "outgoing_stock_entry",
   "purpose",
+  "add_to_transit",
   "work_order",
   "purchase_order",
   "delivery_note_no",
@@ -116,11 +117,12 @@
    "reqd": 1
   },
   {
-   "depends_on": "eval:doc.purpose == 'Receive at Warehouse'",
+   "depends_on": "eval:doc.purpose == 'Material Transfer'",
    "fieldname": "outgoing_stock_entry",
    "fieldtype": "Link",
    "label": "Stock Entry (Outward GIT)",
-   "options": "Stock Entry"
+   "options": "Stock Entry",
+   "read_only": 1
   },
   {
    "bold": 1,
@@ -132,7 +134,7 @@
    "label": "Purpose",
    "oldfieldname": "purpose",
    "oldfieldtype": "Select",
-   "options": "Material Issue\nMaterial Receipt\nMaterial Transfer\nMaterial Transfer for Manufacture\nMaterial Consumption for Manufacture\nManufacture\nRepack\nSend to Subcontractor\nSend to Warehouse\nReceive at Warehouse",
+   "options": "Material Issue\nMaterial Receipt\nMaterial Transfer\nMaterial Transfer for Manufacture\nMaterial Consumption for Manufacture\nManufacture\nRepack\nSend to Subcontractor",
    "read_only": 1
   },
   {
@@ -630,13 +632,21 @@
   {
    "fieldname": "print_settings_col_break",
    "fieldtype": "Column Break"
+  },
+  {
+   "default": "0",
+   "depends_on": "eval: doc.purpose=='Material Transfer' && !doc.outgoing_stock_entry",
+   "fieldname": "add_to_transit",
+   "fieldtype": "Check",
+   "label": "Add to Transit",
+   "no_copy": 1
   }
  ],
  "icon": "fa fa-file-text",
  "idx": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2020-04-23 12:56:52.881752",
+ "modified": "2020-08-11 19:10:07.954981",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Entry",
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 229cf02..30bcccd 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -96,6 +96,11 @@
 		self.update_quality_inspection()
 		if self.work_order and self.purpose == "Manufacture":
 			self.update_so_in_serial_number()
+		
+		if self.purpose == 'Material Transfer' and self.add_to_transit:
+			self.set_material_request_transfer_status('In Transit')
+		if self.purpose == 'Material Transfer' and self.outgoing_stock_entry:
+			self.set_material_request_transfer_status('Completed')
 
 	def on_cancel(self):
 
@@ -116,6 +121,11 @@
 		self.update_quality_inspection()
 		self.delete_auto_created_batches()
 
+		if self.purpose == 'Material Transfer' and self.add_to_transit:
+			self.set_material_request_transfer_status('Not Started')
+		if self.purpose == 'Material Transfer' and self.outgoing_stock_entry:
+			self.set_material_request_transfer_status('In Transit')
+
 	def set_job_card_data(self):
 		if self.job_card and not self.work_order:
 			data = frappe.db.get_value('Job Card',
@@ -133,7 +143,7 @@
 	def validate_purpose(self):
 		valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer",
 			"Material Transfer for Manufacture", "Manufacture", "Repack", "Send to Subcontractor",
-			"Material Consumption for Manufacture", "Send to Warehouse", "Receive at Warehouse"]
+			"Material Consumption for Manufacture"]
 
 		if self.purpose not in valid_purposes:
 			frappe.throw(_("Purpose must be one of {0}").format(comma_or(valid_purposes)))
@@ -199,7 +209,8 @@
 						item.set(f, item_details.get(f))
 
 			if not item.transfer_qty and item.qty:
-				item.transfer_qty = item.qty * item.conversion_factor
+				item.transfer_qty = flt(flt(item.qty) * flt(item.conversion_factor),
+				self.precision("transfer_qty", item))
 
 			if (self.purpose in ("Material Transfer", "Material Transfer for Manufacture")
 				and not item.serial_no
@@ -258,10 +269,10 @@
 		"""perform various (sometimes conditional) validations on warehouse"""
 
 		source_mandatory = ["Material Issue", "Material Transfer", "Send to Subcontractor", "Material Transfer for Manufacture",
-			"Material Consumption for Manufacture", "Send to Warehouse", "Receive at Warehouse"]
+			"Material Consumption for Manufacture"]
 
 		target_mandatory = ["Material Receipt", "Material Transfer", "Send to Subcontractor",
-			"Material Transfer for Manufacture", "Send to Warehouse", "Receive at Warehouse"]
+			"Material Transfer for Manufacture"]
 
 		validate_for_manufacture = any([d.bom_no for d in self.get("items")])
 
@@ -809,7 +820,7 @@
 	def set_items_for_stock_in(self):
 		self.items = []
 
-		if self.outgoing_stock_entry and self.purpose == 'Receive at Warehouse':
+		if self.outgoing_stock_entry and self.purpose == 'Material Transfer':
 			doc = frappe.get_doc('Stock Entry', self.outgoing_stock_entry)
 
 			if doc.per_transferred == 100:
@@ -1210,13 +1221,25 @@
 
 	def validate_with_material_request(self):
 		for item in self.get("items"):
-			if item.material_request:
+			material_request = item.material_request or None
+			material_request_item = item.material_request_item or None
+			if self.purpose == 'Material Transfer' and self.outgoing_stock_entry:
+				parent_se = frappe.get_value("Stock Entry Detail", item.ste_detail, ['material_request','material_request_item'],as_dict=True)
+				if parent_se:
+					material_request = parent_se.material_request
+					material_request_item = parent_se.material_request_item
+
+			if material_request:
 				mreq_item = frappe.db.get_value("Material Request Item",
-					{"name": item.material_request_item, "parent": item.material_request},
+					{"name": material_request_item, "parent": material_request},
 					["item_code", "warehouse", "idx"], as_dict=True)
-				if mreq_item.item_code != item.item_code or \
-				mreq_item.warehouse != (item.s_warehouse if self.purpose== "Material Issue" else item.t_warehouse):
-					frappe.throw(_("Item or Warehouse for row {0} does not match Material Request").format(item.idx),
+				if mreq_item.item_code != item.item_code:
+					frappe.throw(_("Item for row {0} does not match Material Request").format(item.idx),
+						frappe.MappingMismatchError)
+				elif self.purpose == "Material Transfer" and self.add_to_transit:
+					continue
+				elif mreq_item.warehouse != (item.s_warehouse if self.purpose == "Material Issue" else item.t_warehouse):
+					frappe.throw(_("Warehouse for row {0} does not match Material Request").format(item.idx),
 						frappe.MappingMismatchError)
 
 	def validate_batch(self):
@@ -1284,7 +1307,7 @@
 						 to fullfill Sales Order {2}.").format(item.item_code, sr, sales_order))
 
 	def update_transferred_qty(self):
-		if self.purpose == 'Receive at Warehouse':
+		if self.purpose == 'Material Transfer' and self.outgoing_stock_entry:
 			stock_entries = {}
 			stock_entries_child_list = []
 			for d in self.items:
@@ -1342,6 +1365,20 @@
 						'reference_type': reference_type,
 						'reference_name': reference_name
 					})
+	def set_material_request_transfer_status(self, status):
+		material_requests = []
+		if self.outgoing_stock_entry:
+			parent_se = frappe.get_value("Stock Entry", self.outgoing_stock_entry, 'add_to_transit')
+
+		for item in self.items: 
+			material_request = item.material_request or None
+			if self.purpose == "Material Transfer" and material_request not in material_requests:
+				if self.outgoing_stock_entry and parent_se:
+					material_request = frappe.get_value("Stock Entry Detail", item.ste_detail, 'material_request')
+
+			if material_request and material_request not in material_requests:
+				material_requests.append(material_request)
+				frappe.db.set_value('Material Request', material_request, 'transfer_status', status)
 
 @frappe.whitelist()
 def move_sample_to_retention_warehouse(company, items):
@@ -1381,12 +1418,19 @@
 
 @frappe.whitelist()
 def make_stock_in_entry(source_name, target_doc=None):
+
 	def set_missing_values(source, target):
-		target.purpose = 'Receive at Warehouse'
 		target.set_stock_entry_type()
 
 	def update_item(source_doc, target_doc, source_parent):
 		target_doc.t_warehouse = ''
+
+		if source_doc.material_request_item and source_doc.material_request :
+			add_to_transit = frappe.db.get_value('Stock Entry', source_name, 'add_to_transit')
+			if add_to_transit:
+				warehouse = frappe.get_value('Material Request Item', source_doc.material_request_item, 'warehouse')
+				target_doc.t_warehouse = warehouse
+		
 		target_doc.s_warehouse = source_doc.t_warehouse
 		target_doc.qty = source_doc.qty - source_doc.transferred_qty
 
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index 8e25804..d98870d 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -737,34 +737,6 @@
 		self.assertEqual(se.get("items")[0].allow_zero_valuation_rate, 1)
 		self.assertEqual(se.get("items")[0].amount, 0)
 
-	def test_goods_in_transit(self):
-		from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
-		warehouse = "_Test Warehouse FG 1 - _TC"
-
-		if not frappe.db.exists('Warehouse', warehouse):
-			create_warehouse("_Test Warehouse FG 1")
-
-		outward_entry = make_stock_entry(item_code="_Test Item",
-			purpose="Send to Warehouse",
-			source="_Test Warehouse - _TC",
-			target="_Test Warehouse 1 - _TC", qty=50, basic_rate=100)
-
-		inward_entry1 = make_stock_in_entry(outward_entry.name)
-		inward_entry1.items[0].t_warehouse = warehouse
-		inward_entry1.items[0].qty = 25
-		inward_entry1.submit()
-
-		doc = frappe.get_doc('Stock Entry', outward_entry.name)
-		self.assertEqual(doc.per_transferred, 50)
-
-		inward_entry2 = make_stock_in_entry(outward_entry.name)
-		inward_entry2.items[0].t_warehouse = warehouse
-		inward_entry2.items[0].qty = 25
-		inward_entry2.submit()
-
-		doc = frappe.get_doc('Stock Entry', outward_entry.name)
-		self.assertEqual(doc.per_transferred, 100)
-
 	def test_gle_for_opening_stock_entry(self):
 		mr = make_stock_entry(item_code="_Test Item", target="Stores - TCP1", company="_Test Company with perpetual inventory",qty=50, basic_rate=100, expense_account="Stock Adjustment - TCP1", is_opening="Yes", do_not_save=True)
 
diff --git a/erpnext/stock/doctype/stock_entry_type/stock_entry_type.json b/erpnext/stock/doctype/stock_entry_type/stock_entry_type.json
index edee3c7..0f2b55e 100644
--- a/erpnext/stock/doctype/stock_entry_type/stock_entry_type.json
+++ b/erpnext/stock/doctype/stock_entry_type/stock_entry_type.json
@@ -1,156 +1,83 @@
 {
- "allow_copy": 0,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
+ "actions": [],
  "autoname": "Prompt",
- "beta": 0,
  "creation": "2019-03-13 16:23:46.636769",
- "custom": 0,
- "docstatus": 0,
  "doctype": "DocType",
- "document_type": "",
  "editable_grid": 1,
  "engine": "InnoDB",
+ "field_order": [
+  "purpose"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "default": "Material Issue",
-   "fetch_if_empty": 0,
    "fieldname": "purpose",
    "fieldtype": "Select",
-   "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": "Purpose",
-   "length": 0,
-   "no_copy": 0,
-   "options": "\nMaterial Issue\nMaterial Receipt\nMaterial Transfer\nMaterial Transfer for Manufacture\nMaterial Consumption for Manufacture\nManufacture\nRepack\nSend to Subcontractor\nSend to Warehouse\nReceive at Warehouse",
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
+   "options": "\nMaterial Issue\nMaterial Receipt\nMaterial Transfer\nMaterial Transfer for Manufacture\nMaterial Consumption for Manufacture\nManufacture\nRepack\nSend to Subcontractor",
    "reqd": 1,
-   "search_index": 0,
-   "set_only_once": 1,
-   "translatable": 0,
-   "unique": 0
+   "set_only_once": 1
   }
  ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2019-03-26 12:02:42.144377",
+ "links": [],
+ "modified": "2020-08-10 23:24:37.160817",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Entry Type",
- "name_case": "",
  "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0,
-   "cancel": 0,
    "create": 1,
    "delete": 1,
    "email": 1,
    "export": 1,
-   "if_owner": 0,
-   "import": 0,
-   "permlevel": 0,
    "print": 1,
    "read": 1,
    "report": 1,
    "role": "System Manager",
-   "set_user_permissions": 0,
    "share": 1,
-   "submit": 0,
    "write": 1
   },
   {
-   "amend": 0,
-   "cancel": 0,
    "create": 1,
    "delete": 1,
    "email": 1,
    "export": 1,
-   "if_owner": 0,
-   "import": 0,
-   "permlevel": 0,
    "print": 1,
    "read": 1,
    "report": 1,
    "role": "Manufacturing Manager",
-   "set_user_permissions": 0,
    "share": 1,
-   "submit": 0,
    "write": 1
   },
   {
-   "amend": 0,
-   "cancel": 0,
    "create": 1,
    "delete": 1,
    "email": 1,
    "export": 1,
-   "if_owner": 0,
-   "import": 0,
-   "permlevel": 0,
    "print": 1,
    "read": 1,
    "report": 1,
    "role": "Stock Manager",
-   "set_user_permissions": 0,
    "share": 1,
-   "submit": 0,
    "write": 1
   },
   {
-   "amend": 0,
-   "cancel": 0,
    "create": 1,
    "delete": 1,
    "email": 1,
    "export": 1,
-   "if_owner": 0,
-   "import": 0,
-   "permlevel": 0,
    "print": 1,
    "read": 1,
    "report": 1,
    "role": "Stock User",
-   "set_user_permissions": 0,
    "share": 1,
-   "submit": 0,
    "write": 1
   }
  ],
  "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
  "sort_field": "modified",
  "sort_order": "ASC",
- "track_changes": 1,
- "track_seen": 0,
- "track_views": 0
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/stock/doctype/warehouse/warehouse.json b/erpnext/stock/doctype/warehouse/warehouse.json
index 3b49c4c..1cc600b 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.json
+++ b/erpnext/stock/doctype/warehouse/warehouse.json
@@ -45,7 +45,6 @@
    "oldfieldtype": "Section Break"
   },
   {
-   "description": "If blank, parent Warehouse Account or company default will be considered",
    "fieldname": "warehouse_name",
    "fieldtype": "Data",
    "label": "Warehouse Name",
@@ -86,6 +85,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "description": "If blank, parent Warehouse Account or company default will be considered in transactions",
    "fieldname": "account",
    "fieldtype": "Link",
    "label": "Account",
@@ -236,7 +236,7 @@
  "idx": 1,
  "is_tree": 1,
  "links": [],
- "modified": "2020-07-16 15:43:50.653256",
+ "modified": "2020-08-03 18:41:52.442502",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Warehouse",
diff --git a/erpnext/templates/generators/item/item_configure.js b/erpnext/templates/generators/item/item_configure.js
index 163c955..5fd9011 100644
--- a/erpnext/templates/generators/item/item_configure.js
+++ b/erpnext/templates/generators/item/item_configure.js
@@ -193,17 +193,14 @@
 			filtered_items_count === 1 ?
 				filtered_items[0] : '';
 
-		// Allow Add to Cart if adding out of stock items enabled in Shopping Cart else check stock.
-		const in_stock = product_info.allow_items_not_in_stock ? 1 : product_info.in_stock;
-		const add_to_cart = `<a href data-action="btn_add_to_cart" data-item-code="${one_item}">${__('Add to cart')}</a>`;
-		const product_action =  in_stock ? add_to_cart : `<a style="color:#74808b;">${__('Not in Stock')}</a>`;
-
 		const item_add_to_cart = one_item ? `
 			<div class="alert alert-success d-flex justify-content-between align-items-center" role="alert">
 				<div>
 					<div>${one_item} ${product_info && product_info.price ? '(' + product_info.price.formatted_price_sales_uom + ')' : ''}</div>
 				</div>
-				${product_action}
+				<a href data-action="btn_add_to_cart" data-item-code="${one_item}">
+					${__('Add to cart')}
+				</a>
 			</div>
 		`: '';
 
diff --git a/erpnext/templates/generators/item/item_image.html b/erpnext/templates/generators/item/item_image.html
index 0dd4c35..5d46a45 100644
--- a/erpnext/templates/generators/item/item_image.html
+++ b/erpnext/templates/generators/item/item_image.html
@@ -23,7 +23,7 @@
 	})
 </script>
 {% else %}
-{{ product_image(website_image or image or 'no-image.jpg') }}
+{{ product_image(website_image or image or 'no-image.jpg', alt=website_image_alt or item_name) }}
 {% endif %}
 
 <!-- Simple image preview -->
diff --git a/erpnext/templates/generators/item_group.html b/erpnext/templates/generators/item_group.html
index 3f98453..40a064f 100644
--- a/erpnext/templates/generators/item_group.html
+++ b/erpnext/templates/generators/item_group.html
@@ -4,7 +4,7 @@
 
 {% block page_content %}
 <div class="item-group-content" itemscope itemtype="http://schema.org/Product">
-	<div>
+	<div class="item-group-slideshow">
 		{% if slideshow %}<!-- slideshow -->
 		{% include "templates/includes/slideshow.html" %}
 		{% endif %}
diff --git a/erpnext/templates/includes/macros.html b/erpnext/templates/includes/macros.html
index 3c82e90..ea6b00f 100644
--- a/erpnext/templates/includes/macros.html
+++ b/erpnext/templates/includes/macros.html
@@ -7,9 +7,9 @@
 </div>
 {% endmacro %}
 
-{% macro product_image(website_image, css_class="") %}
+{% macro product_image(website_image, css_class="", alt="") %}
     <div class="border text-center rounded h-100 {{ css_class }}" style="overflow: hidden;">
-		<img itemprop="image" class="website-image h-100 w-100" src="{{ frappe.utils.quoted(website_image or 'no-image.jpg') | abs_url }}">
+		<img itemprop="image" class="website-image h-100 w-100" alt="{{ alt }}" src="{{ frappe.utils.quoted(website_image or 'no-image.jpg') | abs_url }}">
     </div>
 {% endmacro %}
 
diff --git a/erpnext/www/support/index.html b/erpnext/www/support/index.html
index 93da503..12b4c2c 100644
--- a/erpnext/www/support/index.html
+++ b/erpnext/www/support/index.html
@@ -9,6 +9,33 @@
 			<p class="hero-subtitle">{{ greeting_subtitle }}</p>
 			{% endif %}
 		</div>
+		<div class="search-container">
+			<div class="website-search" id="search-container">
+				<div class="dropdown">
+					<div class="search-icon">
+						<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"
+							fill="none"
+							stroke="currentColor" stroke-width="2" stroke-linecap="round"
+							stroke-linejoin="round"
+							class="feather feather-search">
+							<circle cx="11" cy="11" r="8"></circle>
+							<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
+						</svg>
+					</div>
+					<input type="search" class="form-control" placeholder="Search the docs (Press ? to focus)" />
+					<div class="overflow-hidden shadow dropdown-menu w-100">
+					</div>
+				</div>
+			</div>
+			<button class="navbar-toggler" type="button"
+				data-toggle="collapse"
+				data-target="#navbarSupportedContent"
+				aria-controls="navbarSupportedContent"
+				aria-expanded="false"
+				aria-label="Toggle navigation">
+				<span class="navbar-toggler-icon"></span>
+			</button>
+		</div>
 	</div>
 </section>
 
@@ -54,5 +81,21 @@
 	</div>
 </section>
 {% endif %}
+{% endblock %}
 
-{% endblock %}
\ No newline at end of file
+{%- block script -%}
+<script>
+	frappe.ready(() => {
+		frappe.setup_search('#search-container', 'kb');
+	});
+</script>
+{%- endblock -%}
+
+{%- block style -%}
+<style>
+	.search-container {
+		margin-top: 1.2rem;
+		max-width: 500px;
+	}	
+</style>
+{%- endblock -%}
diff --git a/yarn.lock b/yarn.lock
index c5509d6..b19f566 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1084,9 +1084,9 @@
   integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=
 
 lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.7.14:
-  version "4.17.15"
-  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
-  integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
+  version "4.17.19"
+  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
+  integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
 
 lowercase-keys@^1.0.0:
   version "1.0.1"