Merge branch 'develop' into update-stock-onboarding-fp
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index 439b1ed..d96bc27 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -533,8 +533,8 @@
 	source_exchange_rate: function(frm) {
 		if (frm.doc.paid_amount) {
 			frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate));
-			if(!frm.set_paid_amount_based_on_received_amount &&
-					(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency)) {
+			// target exchange rate should always be same as source if both account currencies is same
+			if(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) {
 				frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate);
 				frm.set_value("base_received_amount", frm.doc.base_paid_amount);
 			}
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index d2dffde..abacee9 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -55,14 +55,17 @@
 		self.validate_mandatory()
 		self.validate_reference_documents()
 		self.set_tax_withholding()
-		self.apply_taxes()
 		self.set_amounts()
+		self.validate_amounts()
+		self.apply_taxes()
+		self.set_amounts_after_tax()
 		self.clear_unallocated_reference_document_rows()
 		self.validate_payment_against_negative_invoice()
 		self.validate_transaction_reference()
 		self.set_title()
 		self.set_remarks()
 		self.validate_duplicate_entry()
+		self.validate_payment_type_with_outstanding()
 		self.validate_allocated_amount()
 		self.validate_paid_invoices()
 		self.ensure_supplier_is_not_blocked()
@@ -118,6 +121,11 @@
 			if not self.get(field):
 				self.set(field, bank_data.account)
 
+	def validate_payment_type_with_outstanding(self):
+		total_outstanding = sum(d.allocated_amount for d in self.get('references'))
+		if total_outstanding < 0 and self.party_type == 'Customer' and self.payment_type == 'Receive':
+			frappe.throw(_("Cannot receive from customer against negative outstanding"), title=_("Incorrect Payment Type"))
+
 	def validate_allocated_amount(self):
 		for d in self.get("references"):
 			if (flt(d.allocated_amount))> 0:
@@ -236,7 +244,9 @@
 						self.company_currency, self.posting_date)
 
 	def set_target_exchange_rate(self, ref_doc=None):
-		if self.paid_to and not self.target_exchange_rate:
+		if self.paid_from_account_currency == self.paid_to_account_currency:
+			self.target_exchange_rate = self.source_exchange_rate
+		elif self.paid_to and not self.target_exchange_rate:
 			if ref_doc:
 				if self.paid_to_account_currency == ref_doc.currency:
 					self.target_exchange_rate = ref_doc.get("exchange_rate")
@@ -468,13 +478,22 @@
 	def set_amounts(self):
 		self.set_received_amount()
 		self.set_amounts_in_company_currency()
-		self.set_amounts_after_tax()
 		self.set_total_allocated_amount()
 		self.set_unallocated_amount()
 		self.set_difference_amount()
 
+	def validate_amounts(self):
+		self.validate_received_amount()
+	
+	def validate_received_amount(self):
+		if self.paid_from_account_currency == self.paid_to_account_currency:
+			if self.paid_amount != self.received_amount:
+				frappe.throw(_("Received Amount cannot be greater than Paid Amount"))
+
 	def set_received_amount(self):
 		self.base_received_amount = self.base_paid_amount
+		if self.paid_from_account_currency == self.paid_to_account_currency:
+			self.received_amount = self.paid_amount
 
 	def set_amounts_after_tax(self):
 		applicable_tax = 0
diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
index 801dadc..dac927b 100644
--- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
@@ -107,7 +107,7 @@
 		pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
 		pe.reference_no = "1"
 		pe.reference_date = "2016-01-01"
-		pe.target_exchange_rate = 50
+		pe.source_exchange_rate = 50
 		pe.insert()
 		pe.submit()
 
@@ -154,7 +154,7 @@
 		pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
 		pe.reference_no = "1"
 		pe.reference_date = "2016-01-01"
-		pe.target_exchange_rate = 50
+		pe.source_exchange_rate = 50
 		pe.insert()
 		pe.submit()
 
@@ -491,7 +491,7 @@
 		pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
 		pe.reference_no = "1"
 		pe.reference_date = "2016-01-01"
-		pe.target_exchange_rate = 55
+		pe.source_exchange_rate = 55
 
 		pe.append("deductions", {
 			"account": "_Test Exchange Gain/Loss - _TC",
diff --git a/erpnext/accounts/doctype/pos_closing_entry/test_pos_closing_entry.py b/erpnext/accounts/doctype/pos_closing_entry/test_pos_closing_entry.py
index b596c0c..5b18ebb 100644
--- a/erpnext/accounts/doctype/pos_closing_entry/test_pos_closing_entry.py
+++ b/erpnext/accounts/doctype/pos_closing_entry/test_pos_closing_entry.py
@@ -85,9 +85,15 @@
 
 		pcv_doc.load_from_db()
 		pcv_doc.cancel()
-		si_doc.load_from_db()
+
+		cancelled_invoice = frappe.db.get_value(
+			'POS Invoice Merge Log', {'pos_closing_entry': pcv_doc.name},
+			'consolidated_invoice'
+		)
+		docstatus = frappe.db.get_value("Sales Invoice", cancelled_invoice, 'docstatus')
+		self.assertEqual(docstatus, 2)
+
 		pos_inv1.load_from_db()
-		self.assertEqual(si_doc.docstatus, 2)
 		self.assertEqual(pos_inv1.status, 'Paid')
 
 
diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.js b/erpnext/accounts/doctype/pos_invoice/pos_invoice.js
index 181e9f8..15c2922 100644
--- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.js
+++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.js
@@ -16,7 +16,7 @@
 
 	onload(doc) {
 		super.onload();
-		this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice Merge Log'];
+		this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice Merge Log', 'POS Closing Entry'];
 		if(doc.__islocal && doc.is_pos && frappe.get_route_str() !== 'point-of-sale') {
 			this.frm.script_manager.trigger("is_pos");
 			this.frm.refresh_fields();
@@ -111,16 +111,12 @@
 	}
 
 	write_off_outstanding_amount_automatically() {
-		if(cint(this.frm.doc.write_off_outstanding_amount_automatically)) {
+		if (cint(this.frm.doc.write_off_outstanding_amount_automatically)) {
 			frappe.model.round_floats_in(this.frm.doc, ["grand_total", "paid_amount"]);
 			// this will make outstanding amount 0
 			this.frm.set_value("write_off_amount",
 				flt(this.frm.doc.grand_total - this.frm.doc.paid_amount - this.frm.doc.total_advance, precision("write_off_amount"))
 			);
-			this.frm.toggle_enable("write_off_amount", false);
-
-		} else {
-			this.frm.toggle_enable("write_off_amount", true);
 		}
 
 		this.calculate_outstanding_amount(false);
diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.json b/erpnext/accounts/doctype/pos_invoice/pos_invoice.json
index 33c3e04..b819537 100644
--- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.json
+++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.json
@@ -99,6 +99,7 @@
   "loyalty_redemption_account",
   "loyalty_redemption_cost_center",
   "section_break_49",
+  "coupon_code",
   "apply_discount_on",
   "base_discount_amount",
   "column_break_51",
@@ -595,7 +596,8 @@
   {
    "fieldname": "scan_barcode",
    "fieldtype": "Data",
-   "label": "Scan Barcode"
+   "label": "Scan Barcode",
+   "options": "Barcode"
   },
   {
    "allow_bulk_edit": 1,
@@ -1182,7 +1184,8 @@
    "label": "Write Off Amount",
    "no_copy": 1,
    "options": "currency",
-   "print_hide": 1
+   "print_hide": 1,
+   "read_only_depends_on": "eval: doc.write_off_outstanding_amount_automatically"
   },
   {
    "fieldname": "base_write_off_amount",
@@ -1548,12 +1551,20 @@
    "no_copy": 1,
    "options": "Sales Invoice",
    "read_only": 1
+  },
+  {
+   "depends_on": "coupon_code",
+   "fieldname": "coupon_code",
+   "fieldtype": "Link",
+   "label": "Coupon Code",
+   "options": "Coupon Code",
+   "print_hide": 1
   }
  ],
  "icon": "fa fa-file-text",
  "is_submittable": 1,
  "links": [],
- "modified": "2021-07-29 13:37:20.636171",
+ "modified": "2021-08-18 16:13:52.080543",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "POS Invoice",
diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
index 8ec4ef2..759cad5 100644
--- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
+++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
@@ -44,6 +44,9 @@
 		self.validate_pos()
 		self.validate_payment_amount()
 		self.validate_loyalty_transaction()
+		if self.coupon_code:
+			from erpnext.accounts.doctype.pricing_rule.utils import validate_coupon_code
+			validate_coupon_code(self.coupon_code)
 
 	def on_submit(self):
 		# create the loyalty point ledger entry if the customer is enrolled in any loyalty program
@@ -58,6 +61,10 @@
 		self.check_phone_payments()
 		self.set_status(update=True)
 
+		if self.coupon_code:
+			from erpnext.accounts.doctype.pricing_rule.utils import update_coupon_code_count
+			update_coupon_code_count(self.coupon_code,'used')
+
 	def before_cancel(self):
 		if self.consolidated_invoice and frappe.db.get_value('Sales Invoice', self.consolidated_invoice, 'docstatus') == 1:
 			pos_closing_entry = frappe.get_all(
@@ -84,6 +91,10 @@
 			against_psi_doc.delete_loyalty_point_entry()
 			against_psi_doc.make_loyalty_point_entry()
 
+		if self.coupon_code:
+			from erpnext.accounts.doctype.pricing_rule.utils import update_coupon_code_count
+			update_coupon_code_count(self.coupon_code,'cancelled')
+
 	def check_phone_payments(self):
 		for pay in self.payments:
 			if pay.type == "Phone" and pay.amount >= 0:
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index 556f49d..4903c50 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -198,12 +198,19 @@
 	set_serial_nos_based_on_fifo = frappe.db.get_single_value("Stock Settings",
 		"automatically_set_serial_nos_based_on_fifo")
 
+	item_code_list = tuple(item.get('item_code') for item in item_list)
+	query_items = frappe.get_all('Item', fields=['item_code','has_serial_no'], filters=[['item_code','in',item_code_list]],as_list=1)
+	serialized_items = dict()
+	for item_code, val in query_items:
+		serialized_items.setdefault(item_code, val)
+	
 	for item in item_list:
 		args_copy = copy.deepcopy(args)
 		args_copy.update(item)
 		data = get_pricing_rule_for_item(args_copy, item.get('price_list_rate'), doc=doc)
 		out.append(data)
-		if not item.get("serial_no") and set_serial_nos_based_on_fifo and not args.get('is_return'):
+		
+		if serialized_items.get(item.get('item_code')) and not item.get("serial_no") and set_serial_nos_based_on_fifo and not args.get('is_return'):
 			out[0].update(get_serial_no_for_item(args_copy))
 
 	return out
diff --git a/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.json b/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.json
index 795fb1c..a70d5c9 100644
--- a/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.json
+++ b/erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.json
@@ -106,7 +106,6 @@
    "depends_on": "eval:doc.rate_or_discount==\"Rate\"",
    "fieldname": "rate",
    "fieldtype": "Currency",
-   "in_list_view": 1,
    "label": "Rate"
   },
   {
@@ -170,7 +169,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-03-07 11:56:23.424137",
+ "modified": "2021-08-19 15:49:29.598727",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Promotional Scheme Price Discount",
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index 7025dd9..7822f74 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -668,8 +668,7 @@
    "fieldname": "scan_barcode",
    "fieldtype": "Data",
    "label": "Scan Barcode",
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "Barcode"
   },
   {
    "allow_bulk_edit": 1,
@@ -1715,7 +1714,7 @@
  "idx": 204,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-08-07 17:53:14.351439",
+ "modified": "2021-08-17 20:16:12.737743",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice",
diff --git a/erpnext/accounts/doctype/sales_invoice/regional/india.js b/erpnext/accounts/doctype/sales_invoice/regional/india.js
index f54bce8..6336db1 100644
--- a/erpnext/accounts/doctype/sales_invoice/regional/india.js
+++ b/erpnext/accounts/doctype/sales_invoice/regional/india.js
@@ -1,8 +1,6 @@
 {% include "erpnext/regional/india/taxes.js" %}
-{% include "erpnext/regional/india/e_invoice/einvoice.js" %}
 
 erpnext.setup_auto_gst_taxation('Sales Invoice');
-erpnext.setup_einvoice_actions('Sales Invoice')
 
 frappe.ui.form.on("Sales Invoice", {
 	setup: function(frm) {
diff --git a/erpnext/accounts/doctype/sales_invoice/regional/india_list.js b/erpnext/accounts/doctype/sales_invoice/regional/india_list.js
index f01325d..d9d6634 100644
--- a/erpnext/accounts/doctype/sales_invoice/regional/india_list.js
+++ b/erpnext/accounts/doctype/sales_invoice/regional/india_list.js
@@ -36,139 +36,4 @@
 	};
 
 	list_view.page.add_actions_menu_item(__('Generate E-Way Bill JSON'), action, false);
-
-	const generate_irns = () => {
-		const docnames = list_view.get_checked_items(true);
-		if (docnames && docnames.length) {
-			frappe.call({
-				method: 'erpnext.regional.india.e_invoice.utils.generate_einvoices',
-				args: { docnames },
-				freeze: true,
-				freeze_message: __('Generating E-Invoices...')
-			});
-		} else {
-			frappe.msgprint({
-				message: __('Please select at least one sales invoice to generate IRN'),
-				title: __('No Invoice Selected'),
-				indicator: 'red'
-			});
-		}
-	};
-
-	const cancel_irns = () => {
-		const docnames = list_view.get_checked_items(true);
-
-		const fields = [
-			{
-				"label": "Reason",
-				"fieldname": "reason",
-				"fieldtype": "Select",
-				"reqd": 1,
-				"default": "1-Duplicate",
-				"options": ["1-Duplicate", "2-Data Entry Error", "3-Order Cancelled", "4-Other"]
-			},
-			{
-				"label": "Remark",
-				"fieldname": "remark",
-				"fieldtype": "Data",
-				"reqd": 1
-			}
-		];
-
-		const d = new frappe.ui.Dialog({
-			title: __("Cancel IRN"),
-			fields: fields,
-			primary_action: function() {
-				const data = d.get_values();
-				frappe.call({
-					method: 'erpnext.regional.india.e_invoice.utils.cancel_irns',
-					args: {
-						doctype: list_view.doctype,
-						docnames,
-						reason: data.reason.split('-')[0],
-						remark: data.remark
-					},
-					freeze: true,
-					freeze_message: __('Cancelling E-Invoices...'),
-				});
-				d.hide();
-			},
-			primary_action_label: __('Submit')
-		});
-		d.show();
-	};
-
-	let einvoicing_enabled = false;
-	frappe.db.get_single_value("E Invoice Settings", "enable").then(enabled => {
-		einvoicing_enabled = enabled;
-	});
-
-	list_view.$result.on("change", "input[type=checkbox]", () => {
-		if (einvoicing_enabled) {
-			const docnames = list_view.get_checked_items(true);
-			// show/hide e-invoicing actions when no sales invoices are checked
-			if (docnames && docnames.length) {
-				// prevent adding actions twice if e-invoicing action group already exists
-				if (list_view.page.get_inner_group_button(__('E-Invoicing')).length == 0) {
-					list_view.page.add_inner_button(__('Generate IRNs'), generate_irns, __('E-Invoicing'));
-					list_view.page.add_inner_button(__('Cancel IRNs'), cancel_irns, __('E-Invoicing'));
-				}
-			} else {
-				list_view.page.remove_inner_button(__('Generate IRNs'), __('E-Invoicing'));
-				list_view.page.remove_inner_button(__('Cancel IRNs'), __('E-Invoicing'));
-			}
-		}
-	});
-
-	frappe.realtime.on("bulk_einvoice_generation_complete", (data) => {
-		const { failures, user, invoices } = data;
-
-		if (invoices.length != failures.length) {
-			frappe.msgprint({
-				message: __('{0} e-invoices generated successfully', [invoices.length]),
-				title: __('Bulk E-Invoice Generation Complete'),
-				indicator: 'orange'
-			});
-		}
-
-		if (failures && failures.length && user == frappe.session.user) {
-			let message = `
-				Failed to generate IRNs for following ${failures.length} sales invoices:
-				<ul style="padding-left: 20px; padding-top: 5px;">
-					${failures.map(d => `<li>${d.docname}</li>`).join('')}
-				</ul>
-			`;
-			frappe.msgprint({
-				message: message,
-				title: __('Bulk E-Invoice Generation Complete'),
-				indicator: 'orange'
-			});
-		}
-	});
-
-	frappe.realtime.on("bulk_einvoice_cancellation_complete", (data) => {
-		const { failures, user, invoices } = data;
-
-		if (invoices.length != failures.length) {
-			frappe.msgprint({
-				message: __('{0} e-invoices cancelled successfully', [invoices.length]),
-				title: __('Bulk E-Invoice Cancellation Complete'),
-				indicator: 'orange'
-			});
-		}
-
-		if (failures && failures.length && user == frappe.session.user) {
-			let message = `
-				Failed to cancel IRNs for following ${failures.length} sales invoices:
-				<ul style="padding-left: 20px; padding-top: 5px;">
-					${failures.map(d => `<li>${d.docname}</li>`).join('')}
-				</ul>
-			`;
-			frappe.msgprint({
-				message: message,
-				title: __('Bulk E-Invoice Cancellation Complete'),
-				indicator: 'orange'
-			});
-		}
-	});
 };
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 8d65101..2071827 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -324,16 +324,12 @@
 	}
 
 	write_off_outstanding_amount_automatically() {
-		if(cint(this.frm.doc.write_off_outstanding_amount_automatically)) {
+		if (cint(this.frm.doc.write_off_outstanding_amount_automatically)) {
 			frappe.model.round_floats_in(this.frm.doc, ["grand_total", "paid_amount"]);
 			// this will make outstanding amount 0
 			this.frm.set_value("write_off_amount",
 				flt(this.frm.doc.grand_total - this.frm.doc.paid_amount - this.frm.doc.total_advance, precision("write_off_amount"))
 			);
-			this.frm.toggle_enable("write_off_amount", false);
-
-		} else {
-			this.frm.toggle_enable("write_off_amount", true);
 		}
 
 		this.calculate_outstanding_amount(false);
@@ -787,8 +783,6 @@
 		if (frappe.boot.sysdefaults.country == 'India') unhide_field(['c_form_applicable', 'c_form_no']);
 		else hide_field(['c_form_applicable', 'c_form_no']);
 
-		frm.toggle_enable("write_off_amount", !!!cint(doc.write_off_outstanding_amount_automatically));
-
 		frm.refresh_fields();
 	},
 
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index b65b101..5023c9c 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -692,6 +692,7 @@
   {
    "fieldname": "scan_barcode",
    "fieldtype": "Data",
+   "options": "Barcode",
    "hide_days": 1,
    "hide_seconds": 1,
    "label": "Scan Barcode"
@@ -1443,7 +1444,8 @@
    "label": "Write Off Amount",
    "no_copy": 1,
    "options": "currency",
-   "print_hide": 1
+   "print_hide": 1,
+   "read_only_depends_on": "eval:doc.write_off_outstanding_amount_automatically"
   },
   {
    "fieldname": "base_write_off_amount",
@@ -2013,7 +2015,7 @@
    "link_fieldname": "consolidated_invoice"
   }
  ],
- "modified": "2021-08-17 19:00:32.230701",
+ "modified": "2021-08-18 16:07:45.122570",
  "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 5fa6228..1cf0df0 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -285,8 +285,6 @@
 
 	def before_cancel(self):
 		self.check_if_consolidated_invoice()
-
-		super(SalesInvoice, self).before_cancel()
 		self.update_time_sheet(None)
 
 	def on_cancel(self):
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 4d1e0c3..c3d83c7 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -26,6 +26,7 @@
 from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
 from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
 from erpnext.stock.utils import get_incoming_rate
+from erpnext.accounts.utils import PaymentEntryUnlinkError
 
 class TestSalesInvoice(unittest.TestCase):
 	def make(self):
@@ -136,7 +137,7 @@
 		pe.paid_to_account_currency = si.currency
 		pe.source_exchange_rate = 1
 		pe.target_exchange_rate = 1
-		pe.paid_amount = si.grand_total
+		pe.paid_amount = si.outstanding_amount
 		pe.insert()
 		pe.submit()
 
@@ -145,6 +146,42 @@
 		self.assertRaises(frappe.LinkExistsError, si.cancel)
 		unlink_payment_on_cancel_of_invoice()
 
+	def test_payment_entry_unlink_against_standalone_credit_note(self):
+		from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
+		si1 = create_sales_invoice(rate=1000)
+		si2 = create_sales_invoice(rate=300)
+		si3 = create_sales_invoice(qty=-1, rate=300, is_return=1)
+		
+
+		pe = get_payment_entry("Sales Invoice", si1.name, bank_account="_Test Bank - _TC")
+		pe.append('references', {
+			'reference_doctype': 'Sales Invoice',
+			'reference_name': si2.name,
+			'total_amount': si2.grand_total,
+			'outstanding_amount': si2.outstanding_amount,
+			'allocated_amount': si2.outstanding_amount
+		})
+
+		pe.append('references', {
+			'reference_doctype': 'Sales Invoice',
+			'reference_name': si3.name,
+			'total_amount': si3.grand_total,
+			'outstanding_amount': si3.outstanding_amount,
+			'allocated_amount': si3.outstanding_amount
+		})
+
+		pe.reference_no = 'Test001'
+		pe.reference_date = nowdate()
+		pe.save()
+		pe.submit()
+
+		si2.load_from_db()
+		si2.cancel()
+
+		si1.load_from_db()
+		self.assertRaises(PaymentEntryUnlinkError, si1.cancel)
+
+
 	def test_sales_invoice_calculation_export_currency(self):
 		si = frappe.copy_doc(test_records[2])
 		si.currency = "USD"
@@ -2014,7 +2051,7 @@
 
 		data = get_ewb_data("Sales Invoice", [si.name])
 
-		self.assertEqual(data['version'], '1.0.1118')
+		self.assertEqual(data['version'], '1.0.0421')
 		self.assertEqual(data['billLists'][0]['fromGstin'], '27AAECE4835E1ZR')
 		self.assertEqual(data['billLists'][0]['fromTrdName'], '_Test Company')
 		self.assertEqual(data['billLists'][0]['toTrdName'], '_Test Customer')
@@ -2027,54 +2064,6 @@
 		self.assertEqual(data['billLists'][0]['actualFromStateCode'],7)
 		self.assertEqual(data['billLists'][0]['fromStateCode'],27)
 
-	def test_einvoice_submission_without_irn(self):
-		# init
-		einvoice_settings = frappe.get_doc('E Invoice Settings')
-		einvoice_settings.enable = 1
-		einvoice_settings.applicable_from = nowdate()
-		einvoice_settings.append('credentials', {
-			'company': '_Test Company',
-			'gstin': '27AAECE4835E1ZR',
-			'username': 'test',
-			'password': 'test'
-		})
-		einvoice_settings.save()
-
-		country = frappe.flags.country
-		frappe.flags.country = 'India'
-
-		si = make_sales_invoice_for_ewaybill()
-		self.assertRaises(frappe.ValidationError, si.submit)
-
-		si.irn = 'test_irn'
-		si.submit()
-
-		# reset
-		einvoice_settings = frappe.get_doc('E Invoice Settings')
-		einvoice_settings.enable = 0
-		frappe.flags.country = country
-
-	def test_einvoice_json(self):
-		from erpnext.regional.india.e_invoice.utils import make_einvoice, validate_totals
-
-		si = get_sales_invoice_for_e_invoice()
-		si.discount_amount = 100
-		si.save()
-
-		einvoice = make_einvoice(si)
-		self.assertTrue(einvoice['EwbDtls'])
-		validate_totals(einvoice)
-
-		si.apply_discount_on = 'Net Total'
-		si.save()
-		einvoice = make_einvoice(si)
-		validate_totals(einvoice)
-
-		[d.set('included_in_print_rate', 1) for d in si.taxes]
-		si.save()
-		einvoice = make_einvoice(si)
-		validate_totals(einvoice)
-
 	def test_item_tax_net_range(self):
 		item = create_item("T Shirt")
 
diff --git a/erpnext/accounts/print_format/gst_e_invoice/__init__.py b/erpnext/accounts/print_format/gst_e_invoice/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/accounts/print_format/gst_e_invoice/__init__.py
+++ /dev/null
diff --git a/erpnext/accounts/print_format/gst_e_invoice/gst_e_invoice.html b/erpnext/accounts/print_format/gst_e_invoice/gst_e_invoice.html
deleted file mode 100644
index 7643eca..0000000
--- a/erpnext/accounts/print_format/gst_e_invoice/gst_e_invoice.html
+++ /dev/null
@@ -1,162 +0,0 @@
-{%- from "templates/print_formats/standard_macros.html" import add_header, render_field, print_value -%}
-{%- set einvoice = json.loads(doc.signed_einvoice) -%}
-
-<div class="page-break">
-	<div {% if print_settings.repeat_header_footer %} id="header-html" class="hidden-pdf" {% endif %}>
-		{% if letter_head and not no_letterhead %}
-			<div class="letter-head">{{ letter_head }}</div>
-		{% endif %}
-		<div class="print-heading">
-			<h2>E Invoice<br><small>{{ doc.name }}</small></h2>
-		</div>
-	</div>
-	{% if print_settings.repeat_header_footer %}
-	<div id="footer-html" class="visible-pdf">
-		{% if not no_letterhead and footer %}
-		<div class="letter-head-footer">
-			{{ footer }}
-		</div>
-		{% endif %}
-		<p class="text-center small page-number visible-pdf">
-			{{ _("Page {0} of {1}").format('<span class="page"></span>', '<span class="topage"></span>') }}
-		</p>
-	</div>
-	{% endif %}
-	<h5 class="font-bold" style="margin-top: 0px;">1. Transaction Details</h5>
-	<div class="row section-break" style="border-bottom: 1px solid #d1d8dd; padding-bottom: 10px;">
-		<div class="col-xs-8 column-break">
-			<div class="row data-field">
-				<div class="col-xs-4"><label>IRN</label></div>
-				<div class="col-xs-8 value">{{ einvoice.Irn }}</div>
-			</div>
-			<div class="row data-field">
-				<div class="col-xs-4"><label>Ack. No</label></div>
-				<div class="col-xs-8 value">{{ einvoice.AckNo }}</div>
-			</div>
-			<div class="row data-field">
-				<div class="col-xs-4"><label>Ack. Date</label></div>
-				<div class="col-xs-8 value">{{ frappe.utils.format_datetime(einvoice.AckDt, "dd/MM/yyyy hh:mm:ss") }}</div>
-			</div>
-			<div class="row data-field">
-				<div class="col-xs-4"><label>Category</label></div>
-				<div class="col-xs-8 value">{{ einvoice.TranDtls.SupTyp }}</div>
-			</div>
-			<div class="row data-field">
-				<div class="col-xs-4"><label>Document Type</label></div>
-				<div class="col-xs-8 value">{{ einvoice.DocDtls.Typ }}</div>
-			</div>
-			<div class="row data-field">
-				<div class="col-xs-4"><label>Document No</label></div>
-				<div class="col-xs-8 value">{{ einvoice.DocDtls.No }}</div>
-			</div>
-		</div>
-		<div class="col-xs-4 column-break">
-			<img src="{{ doc.qrcode_image }}" width="175px" style="float: right;">
-		</div>
-	</div>
-	<h5 class="font-bold" style="margin-top: 15px; margin-bottom: 10px;">2. Party Details</h5>
-	<div class="row section-break" style="border-bottom: 1px solid #d1d8dd; padding-bottom: 10px;">
-		{%- set seller = einvoice.SellerDtls -%}
-		<div class="col-xs-6 column-break">
-			<h5 style="margin-bottom: 5px;">Seller</h5>
-			<p>{{ seller.Gstin }}</p>
-			<p>{{ seller.LglNm }}</p>
-			<p>{{ seller.Addr1 }}</p>
-			{%- if seller.Addr2 -%} <p>{{ seller.Addr2 }}</p> {% endif %}
-			<p>{{ seller.Loc }}</p>
-			<p>{{ frappe.db.get_value("Address", doc.company_address, "gst_state") }} - {{ seller.Pin }}</p>
-
-			{%- if einvoice.ShipDtls -%}
-				{%- set shipping = einvoice.ShipDtls -%}
-				<h5 style="margin-bottom: 5px;">Shipping</h5>
-				<p>{{ shipping.Gstin }}</p>
-				<p>{{ shipping.LglNm }}</p>
-				<p>{{ shipping.Addr1 }}</p>
-				{%- if shipping.Addr2 -%} <p>{{ shipping.Addr2 }}</p> {% endif %}
-				<p>{{ shipping.Loc }}</p>
-				<p>{{ frappe.db.get_value("Address", doc.shipping_address_name, "gst_state") }} - {{ shipping.Pin }}</p>
-			{% endif %}
-		</div>
-		{%- set buyer = einvoice.BuyerDtls -%}
-		<div class="col-xs-6 column-break">
-			<h5 style="margin-bottom: 5px;">Buyer</h5>
-			<p>{{ buyer.Gstin }}</p>
-			<p>{{ buyer.LglNm }}</p>
-			<p>{{ buyer.Addr1 }}</p>
-			{%- if buyer.Addr2 -%} <p>{{ buyer.Addr2 }}</p> {% endif %}
-			<p>{{ buyer.Loc }}</p>
-			<p>{{ frappe.db.get_value("Address", doc.customer_address, "gst_state") }} - {{ buyer.Pin }}</p>
-		</div>
-	</div>
-	<div style="overflow-x: auto;">
-		<h5 class="font-bold" style="margin-top: 15px; margin-bottom: 10px;">3. Item Details</h5>
-		<table class="table table-bordered">
-			<thead>
-				<tr>
-					<th class="text-left" style="width: 3%;">Sr. No.</th>
-					<th class="text-left">Item</th>
-					<th class="text-left" style="width: 10%;">HSN Code</th>
-					<th class="text-left" style="width: 5%;">Qty</th>
-					<th class="text-left" style="width: 5%;">UOM</th>
-					<th class="text-left">Rate</th>
-					<th class="text-left" style="width: 5%;">Discount</th>
-					<th class="text-left">Taxable Amount</th>
-					<th class="text-left" style="width: 7%;">Tax Rate</th>
-					<th class="text-left" style="width: 5%;">Other Charges</th>
-					<th class="text-left">Total</th>
-				</tr>
-			</thead>
-			<tbody>
-				{% for item in einvoice.ItemList %}
-					<tr>
-						<td class="text-left" style="width: 3%;">{{ item.SlNo }}</td>
-						<td class="text-left">{{ item.PrdDesc }}</td>
-						<td class="text-left" style="width: 10%;">{{ item.HsnCd }}</td>
-						<td class="text-right" style="width: 5%;">{{ item.Qty }}</td>
-						<td class="text-left" style="width: 5%;">{{ item.Unit }}</td>
-						<td class="text-right">{{ frappe.utils.fmt_money(item.UnitPrice, None, "INR") }}</td>
-						<td class="text-right" style="width: 5%;">{{ frappe.utils.fmt_money(item.Discount, None, "INR") }}</td>
-						<td class="text-right">{{ frappe.utils.fmt_money(item.AssAmt, None, "INR") }}</td>
-						<td class="text-right" style="width: 7%;">{{ item.GstRt + item.CesRt }} %</td>
-						<td class="text-right" style="width: 5%;">{{ frappe.utils.fmt_money(0, None, "INR") }}</td>
-						<td class="text-right">{{ frappe.utils.fmt_money(item.TotItemVal, None, "INR") }}</td>
-					</tr>
-				{% endfor %}
-			</tbody>
-		</table>
-	</div>
-	<div style="overflow-x: auto;">
-		<h5 class="font-bold" style="margin-bottom: 0px;">4. Value Details</h5>
-		<table class="table table-bordered">
-			<thead>
-				<tr>
-					<th class="text-left">Taxable Amount</th>
-					<th class="text-left">CGST</th>
-					<th class="text-left"">SGST</th>
-					<th class="text-left">IGST</th>
-					<th class="text-left">CESS</th>
-					<th class="text-left" style="width: 10%;">State CESS</th>
-					<th class="text-left">Discount</th>
-					<th class="text-left" style="width: 10%;">Other Charges</th>
-					<th class="text-left" style="width: 10%;">Round Off</th>
-					<th class="text-left">Total Value</th>
-				</tr>
-			</thead>
-			<tbody>
-				{%- set value_details = einvoice.ValDtls -%}
-				<tr>
-					<td class="text-right">{{ frappe.utils.fmt_money(value_details.AssVal, None, "INR") }}</td>
-					<td class="text-right">{{ frappe.utils.fmt_money(value_details.CgstVal, None, "INR") }}</td>
-					<td class="text-right">{{ frappe.utils.fmt_money(value_details.SgstVal, None, "INR") }}</td>
-					<td class="text-right">{{ frappe.utils.fmt_money(value_details.IgstVal, None, "INR") }}</td>
-					<td class="text-right">{{ frappe.utils.fmt_money(value_details.CesVal, None, "INR") }}</td>
-					<td class="text-right">{{ frappe.utils.fmt_money(0, None, "INR") }}</td>
-					<td class="text-right">{{ frappe.utils.fmt_money(value_details.Discount, None, "INR") }}</td>
-					<td class="text-right">{{ frappe.utils.fmt_money(value_details.OthChrg, None, "INR") }}</td>
-					<td class="text-right">{{ frappe.utils.fmt_money(value_details.RndOffAmt, None, "INR") }}</td>
-					<td class="text-right">{{ frappe.utils.fmt_money(value_details.TotInvVal, None, "INR") }}</td>
-				</tr>
-			</tbody>
-		</table>
-	</div>
-</div>
diff --git a/erpnext/accounts/print_format/gst_e_invoice/gst_e_invoice.json b/erpnext/accounts/print_format/gst_e_invoice/gst_e_invoice.json
deleted file mode 100644
index 1001199..0000000
--- a/erpnext/accounts/print_format/gst_e_invoice/gst_e_invoice.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "align_labels_right": 1,
- "creation": "2020-10-10 18:01:21.032914",
- "custom_format": 0,
- "default_print_language": "en-US",
- "disabled": 1,
- "doc_type": "Sales Invoice",
- "docstatus": 0,
- "doctype": "Print Format",
- "font": "Default",
- "html": "",
- "idx": 0,
- "line_breaks": 1,
- "modified": "2020-10-23 19:54:40.634936",
- "modified_by": "Administrator",
- "module": "Accounts",
- "name": "GST E-Invoice",
- "owner": "Administrator",
- "print_format_builder": 0,
- "print_format_type": "Jinja",
- "raw_printing": 0,
- "show_section_headings": 1,
- "standard": "Yes"
-}
\ No newline at end of file
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index b54646f..cedfc0f 100755
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -535,6 +535,8 @@
 		if getdate(entry_date) > getdate(self.filters.report_date):
 			row.range1 = row.range2 = row.range3 = row.range4 = row.range5 = 0.0
 
+		row.total_due = row.range1 + row.range2 + row.range3 + row.range4 + row.range5
+
 	def get_ageing_data(self, entry_date, row):
 		# [0-30, 30-60, 60-90, 90-120, 120-above]
 		row.range1 = row.range2 = row.range3 = row.range4 = row.range5 = 0.0
diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
index e94b309..4bfb022 100644
--- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
+++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
@@ -82,6 +82,7 @@
 			"range3": 0.0,
 			"range4": 0.0,
 			"range5": 0.0,
+			"total_due": 0.0,
 			"sales_person": []
 		}))
 
@@ -135,3 +136,6 @@
 			"{range3}-{range4}".format(range3=cint(self.filters["range3"])+ 1, range4=self.filters["range4"]),
 			"{range4}-{above}".format(range4=cint(self.filters["range4"])+ 1, above=_("Above"))]):
 				self.add_column(label=label, fieldname='range' + str(i+1))
+
+		# Add column for total due amount
+		self.add_column(label="Total Amount Due", fieldname='total_due')
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 56a67bb..fc42127 100644
--- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
+++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
@@ -210,10 +210,10 @@
 	company_currency = get_company_currency(filters)
 
 	if filters.filter_based_on == 'Fiscal Year':
-		start_date = fiscal_year.year_start_date
+		start_date = fiscal_year.year_start_date if filters.report != 'Balance Sheet' else None
 		end_date = fiscal_year.year_end_date
 	else:
-		start_date = filters.period_start_date
+		start_date = filters.period_start_date if filters.report != 'Balance Sheet' else None
 		end_date = filters.period_end_date
 
 	gl_entries_by_account = {}
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index eca1e26..118f628 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -19,6 +19,7 @@
 
 class StockValueAndAccountBalanceOutOfSync(frappe.ValidationError): pass
 class FiscalYearError(frappe.ValidationError): pass
+class PaymentEntryUnlinkError(frappe.ValidationError): pass
 
 @frappe.whitelist()
 def get_fiscal_year(date=None, fiscal_year=None, label="Date", verbose=1, company=None, as_dict=False):
@@ -555,10 +556,16 @@
 			and docstatus < 2""", (now(), frappe.session.user, ref_type, ref_no))
 
 		for pe in linked_pe:
-			pe_doc = frappe.get_doc("Payment Entry", pe)
-			pe_doc.set_total_allocated_amount()
-			pe_doc.set_unallocated_amount()
-			pe_doc.clear_unallocated_reference_document_rows()
+			try:
+				pe_doc = frappe.get_doc("Payment Entry", pe)
+				pe_doc.set_amounts()
+				pe_doc.clear_unallocated_reference_document_rows()
+				pe_doc.validate_payment_type_with_outstanding()
+			except Exception as e:
+				msg = _("There were issues unlinking payment entry {0}.").format(pe_doc.name)
+				msg += '<br>'
+				msg += _("Please cancel payment entry manually first")
+				frappe.throw(msg, exc=PaymentEntryUnlinkError, title=_("Payment Unlink Error"))
 
 			frappe.db.sql("""update `tabPayment Entry` set total_allocated_amount=%s,
 				base_total_allocated_amount=%s, unallocated_amount=%s, modified=%s, modified_by=%s
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index bb0ad60..a55a0b7 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -565,6 +565,7 @@
    "fieldname": "scan_barcode",
    "fieldtype": "Data",
    "label": "Scan Barcode",
+   "options": "Barcode",
    "show_days": 1,
    "show_seconds": 1
   },
@@ -1378,7 +1379,7 @@
  "idx": 105,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-05-30 15:17:53.663648",
+ "modified": "2021-08-17 20:16:12.737743",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order",
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 4c243d0..01d354d 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -135,14 +135,9 @@
 
 		validate_regional(self)
 
-		validate_einvoice_fields(self)
-
 		if self.doctype != 'Material Request':
 			apply_pricing_rule_on_transaction(self)
 
-	def before_cancel(self):
-		validate_einvoice_fields(self)
-
 	def on_trash(self):
 		# delete sl and gl entries on deletion of transaction
 		if frappe.db.get_single_value('Accounts Settings', 'delete_linked_ledger_entries'):
@@ -1841,6 +1836,11 @@
 
 	for d in data:
 		new_child_flag = False
+
+		if not d.get("item_code"):
+			# ignore empty rows
+			continue
+
 		if not d.get("docname"):
 			new_child_flag = True
 			check_doc_permissions(parent, 'create')
@@ -1975,7 +1975,3 @@
 @erpnext.allow_regional
 def validate_regional(doc):
 	pass
-
-@erpnext.allow_regional
-def validate_einvoice_fields(doc):
-	pass
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 05edb25..7c6d355 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -595,7 +595,8 @@
 				self.doc.precision("outstanding_amount"))
 
 			if self.doc.doctype == 'Sales Invoice' and self.doc.get('is_pos') and self.doc.get('is_return'):
-			 	self.update_paid_amount_for_return(total_amount_to_pay)
+				self.set_total_amount_to_default_mop(total_amount_to_pay)
+				self.calculate_paid_amount()
 
 	def calculate_paid_amount(self):
 
@@ -675,7 +676,7 @@
 	def set_item_wise_tax_breakup(self):
 		self.doc.other_charges_calculation = get_itemised_tax_breakup_html(self.doc)
 
-	def update_paid_amount_for_return(self, total_amount_to_pay):
+	def set_total_amount_to_default_mop(self, total_amount_to_pay):
 		default_mode_of_payment = frappe.db.get_value('POS Payment Method',
 			{'parent': self.doc.pos_profile, 'default': 1}, ['mode_of_payment'], as_dict=1)
 
@@ -685,9 +686,7 @@
 				'mode_of_payment': default_mode_of_payment.mode_of_payment,
 				'amount': total_amount_to_pay,
 				'default': 1
-			})
-
-		self.calculate_paid_amount()
+			})	
 
 def get_itemised_tax_breakup_html(doc):
 	if not doc.taxes:
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 8f7c7db..74977cd 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -251,7 +251,7 @@
 			"erpnext.support.doctype.issue.issue.set_first_response_time"
 		]
 	},
-	("Sales Taxes and Charges Template", 'Price List'): {
+	"Sales Taxes and Charges Template": {
 		"on_update": "erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings.validate_cart_settings"
 	},
 	"Website Settings": {
@@ -308,6 +308,9 @@
 	},
 	('Quotation', 'Sales Order', 'Sales Invoice'): {
 		'validate': ["erpnext.erpnext_integrations.taxjar_integration.set_sales_tax"]
+	},
+	"Company": {
+		"on_trash": "erpnext.regional.india.utils.delete_gst_settings_for_company"
 	}
 }
 
@@ -436,7 +439,6 @@
 		'erpnext.controllers.taxes_and_totals.get_regional_round_off_accounts': 'erpnext.regional.india.utils.get_regional_round_off_accounts',
 		'erpnext.hr.utils.calculate_annual_eligible_hra_exemption': 'erpnext.regional.india.utils.calculate_annual_eligible_hra_exemption',
 		'erpnext.hr.utils.calculate_hra_exemption_for_period': 'erpnext.regional.india.utils.calculate_hra_exemption_for_period',
-		'erpnext.controllers.accounts_controller.validate_einvoice_fields': 'erpnext.regional.india.e_invoice.utils.validate_einvoice_fields',
 		'erpnext.assets.doctype.asset.asset.get_depreciation_amount': 'erpnext.regional.india.utils.get_depreciation_amount',
 		'erpnext.stock.doctype.item.item.set_item_tax_from_hsn_code': 'erpnext.regional.india.utils.set_item_tax_from_hsn_code'
 	},
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index 3f50b41..e72c8eb 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -235,7 +235,7 @@
 						reqd: 1,
 					},
 					{
-						fieldname: "varint_item_code",
+						fieldname: "variant_item_code",
 						options: "Item",
 						label: __("Variant Item"),
 						fieldtype: "Link",
@@ -287,7 +287,7 @@
 			let variant_items = data.items || [];
 
 			variant_items.forEach(d => {
-				if (!d.varint_item_code) {
+				if (!d.variant_item_code) {
 					frappe.throw(__("Select variant item code for the template item {0}", [d.item_code]));
 				}
 			})
@@ -299,7 +299,7 @@
 		has_template_rm.forEach(d => {
 			dialog.fields_dict.items.df.data.push({
 				"item_code": d.item_code,
-				"varint_item_code": "",
+				"variant_item_code": "",
 				"qty": d.qty,
 				"source_warehouse": d.source_warehouse,
 				"operation": d.operation
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index 8c27d6c..b4c6635 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -297,7 +297,7 @@
 
 		if self.total_produced_qty > 0:
 			self.status = "In Process"
-			if self.total_produced_qty == self.total_planned_qty:
+			if self.total_produced_qty >= self.total_planned_qty:
 				self.status = "Completed"
 
 		if self.status != 'Completed':
@@ -346,6 +346,7 @@
 				"production_plan"       : self.name,
 				"production_plan_item"  : d.name,
 				"product_bundle_item"	: d.product_bundle_item,
+				"planned_start_date"    : d.planned_start_date,
 				"make_work_order_for_sub_assembly_items": d.get("make_work_order_for_sub_assembly_items", 0)
 			}
 
diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
index af8de8e..a5b9ff8 100644
--- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
@@ -5,7 +5,7 @@
 
 import frappe
 import unittest
-from frappe.utils import nowdate, now_datetime, flt
+from frappe.utils import nowdate, now_datetime, flt, add_to_date
 from erpnext.stock.doctype.item.test_item import create_item
 from erpnext.manufacturing.doctype.production_plan.production_plan import get_sales_orders
 from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation
@@ -61,6 +61,21 @@
 		pln = frappe.get_doc('Production Plan', pln.name)
 		pln.cancel()
 
+	def test_production_plan_start_date(self):
+		planned_date = add_to_date(date=None, days=3)
+		plan = create_production_plan(item_code='Test Production Item 1', planned_start_date=planned_date)
+		plan.make_work_order()
+
+		work_orders = frappe.get_all('Work Order', fields = ['name', 'planned_start_date'],
+			filters = {'production_plan': plan.name})
+
+		self.assertEqual(work_orders[0].planned_start_date, planned_date)
+
+		for wo in work_orders:
+			frappe.delete_doc('Work Order', wo.name)
+
+		frappe.get_doc('Production Plan', plan.name).cancel()
+
 	def test_production_plan_for_existing_ordered_qty(self):
 		sr1 = create_stock_reconciliation(item_code="Raw Material Item 1",
 			target="_Test Warehouse - _TC", qty=1, rate=110)
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index 282b5d0..5fe9fec 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -602,7 +602,7 @@
 
 		if self.docstatus==1:
 			# calculate transferred qty based on submitted stock entries
-			self.update_transaferred_qty_for_required_items()
+			self.update_transferred_qty_for_required_items()
 
 			# update in bin
 			self.update_reserved_qty_for_production()
@@ -671,7 +671,7 @@
 
 			self.set_available_qty()
 
-	def update_transaferred_qty_for_required_items(self):
+	def update_transferred_qty_for_required_items(self):
 		'''update transferred qty from submitted stock entries for that item against
 			the work order'''
 
@@ -838,7 +838,7 @@
 
 	for item in variant_items:
 		args = frappe._dict({
-			"item_code": item.get("varint_item_code"),
+			"item_code": item.get("variant_item_code"),
 			"required_qty": item.get("qty"),
 			"qty": item.get("qty"), # for bom
 			"source_warehouse": item.get("source_warehouse"),
@@ -859,7 +859,7 @@
 		}, bom_doc)
 
 		if not args.source_warehouse:
-			args["source_warehouse"] = get_item_defaults(item.get("varint_item_code"),
+			args["source_warehouse"] = get_item_defaults(item.get("variant_item_code"),
 				wo_doc.company).default_warehouse
 
 		args["amount"] = flt(args.get("required_qty")) * flt(args.get("rate"))
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 776b41d..b86c236 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -214,7 +214,6 @@
 execute:frappe.delete_doc_if_exists("DocType", "Bank Reconciliation")
 erpnext.patches.v13_0.move_doctype_reports_and_notification_from_hr_to_payroll #22-06-2020
 erpnext.patches.v13_0.move_payroll_setting_separately_from_hr_settings #22-06-2020
-execute:frappe.reload_doc("regional", "doctype", "e_invoice_settings")
 erpnext.patches.v13_0.check_is_income_tax_component #22-06-2020
 erpnext.patches.v13_0.loyalty_points_entry_for_pos_invoice #22-07-2020
 erpnext.patches.v12_0.add_taxjar_integration_field
@@ -237,7 +236,6 @@
 erpnext.patches.v13_0.print_uom_after_quantity_patch
 erpnext.patches.v13_0.set_payment_channel_in_payment_gateway_account
 erpnext.patches.v13_0.create_healthcare_custom_fields_in_stock_entry_detail
-erpnext.patches.v12_0.setup_einvoice_fields #2020-12-02
 erpnext.patches.v13_0.updates_for_multi_currency_payroll
 erpnext.patches.v13_0.update_reason_for_resignation_in_employee
 execute:frappe.delete_doc("Report", "Quoted Item Comparison")
@@ -259,14 +257,11 @@
 erpnext.patches.v13_0.item_reposting_for_incorrect_sl_and_gl
 erpnext.patches.v13_0.delete_old_bank_reconciliation_doctypes
 erpnext.patches.v12_0.update_vehicle_no_reqd_condition
-erpnext.patches.v12_0.add_einvoice_status_field #2021-03-17
-erpnext.patches.v12_0.add_einvoice_summary_report_permissions
 erpnext.patches.v13_0.setup_fields_for_80g_certificate_and_donation
 erpnext.patches.v13_0.rename_membership_settings_to_non_profit_settings
 erpnext.patches.v13_0.setup_gratuity_rule_for_india_and_uae
 erpnext.patches.v13_0.setup_uae_vat_fields
 execute:frappe.db.set_value('System Settings', None, 'app_name', 'ERPNext')
-erpnext.patches.v12_0.add_company_link_to_einvoice_settings
 erpnext.patches.v13_0.rename_discharge_date_in_ip_record
 erpnext.patches.v12_0.create_taxable_value_field
 erpnext.patches.v12_0.add_gst_category_in_delivery_note
@@ -277,7 +272,6 @@
 erpnext.patches.v13_0.make_non_standard_user_type #13-04-2021
 erpnext.patches.v13_0.update_shipment_status
 erpnext.patches.v13_0.remove_attribute_field_from_item_variant_setting
-erpnext.patches.v12_0.add_ewaybill_validity_field
 erpnext.patches.v13_0.germany_make_custom_fields
 erpnext.patches.v13_0.germany_fill_debtor_creditor_number
 erpnext.patches.v13_0.set_pos_closing_as_failed
@@ -294,10 +288,11 @@
 erpnext.patches.v13_0.add_missing_fg_item_for_stock_entry
 erpnext.patches.v13_0.update_subscription_status_in_memberships
 erpnext.patches.v13_0.update_amt_in_work_order_required_items
-erpnext.patches.v12_0.show_einvoice_irn_cancelled_field
 erpnext.patches.v13_0.delete_orphaned_tables
 erpnext.patches.v13_0.update_export_type_for_gst #2021-08-16
 erpnext.patches.v13_0.update_tds_check_field #3
 erpnext.patches.v13_0.add_custom_field_for_south_africa #2
 erpnext.patches.v13_0.update_recipient_email_digest
 erpnext.patches.v13_0.shopify_deprecation_warning
+erpnext.patches.v13_0.einvoicing_deprecation_warning
+erpnext.patches.v14_0.delete_einvoicing_doctypes
diff --git a/erpnext/patches/v12_0/add_company_link_to_einvoice_settings.py b/erpnext/patches/v12_0/add_company_link_to_einvoice_settings.py
deleted file mode 100644
index c2ed6c2..0000000
--- a/erpnext/patches/v12_0/add_company_link_to_einvoice_settings.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from __future__ import unicode_literals
-import frappe
-
-def execute():
-	company = frappe.get_all('Company', filters = {'country': 'India'})
-	if not company or not frappe.db.count('E Invoice User'):
-		return
-
-	frappe.reload_doc("regional", "doctype", "e_invoice_user")
-	for creds in frappe.db.get_all('E Invoice User', fields=['name', 'gstin']):
-		company_name = frappe.db.sql("""
-			select dl.link_name from `tabAddress` a, `tabDynamic Link` dl
-			where a.gstin = %s and dl.parent = a.name and dl.link_doctype = 'Company'
-		""", (creds.get('gstin')))
-		if company_name and len(company_name) > 0:
-			frappe.db.set_value('E Invoice User', creds.get('name'), 'company', company_name[0][0])
diff --git a/erpnext/patches/v12_0/add_einvoice_status_field.py b/erpnext/patches/v12_0/add_einvoice_status_field.py
deleted file mode 100644
index 2dfd307..0000000
--- a/erpnext/patches/v12_0/add_einvoice_status_field.py
+++ /dev/null
@@ -1,69 +0,0 @@
-from __future__ import unicode_literals
-import json
-import frappe
-from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
-
-def execute():
-	company = frappe.get_all('Company', filters = {'country': 'India'})
-	if not company:
-		return
-
-	# move hidden einvoice fields to a different section
-	custom_fields = {
-		'Sales Invoice': [
-			dict(fieldname='einvoice_section', label='E-Invoice Fields', fieldtype='Section Break', insert_after='gst_vehicle_type',
-			print_hide=1, hidden=1),
-
-			dict(fieldname='ack_no', label='Ack. No.', fieldtype='Data', read_only=1, hidden=1, insert_after='einvoice_section',
-				no_copy=1, print_hide=1),
-
-			dict(fieldname='ack_date', label='Ack. Date', fieldtype='Data', read_only=1, hidden=1, insert_after='ack_no', no_copy=1, print_hide=1),
-
-			dict(fieldname='irn_cancel_date', label='Cancel Date', fieldtype='Data', read_only=1, hidden=1, insert_after='ack_date',
-				no_copy=1, print_hide=1),
-
-			dict(fieldname='signed_einvoice', label='Signed E-Invoice', fieldtype='Code', options='JSON', hidden=1, insert_after='irn_cancel_date',
-				no_copy=1, print_hide=1, read_only=1),
-
-			dict(fieldname='signed_qr_code', label='Signed QRCode', fieldtype='Code', options='JSON', hidden=1, insert_after='signed_einvoice',
-				no_copy=1, print_hide=1, read_only=1),
-
-			dict(fieldname='qrcode_image', label='QRCode', fieldtype='Attach Image', hidden=1, insert_after='signed_qr_code',
-				no_copy=1, print_hide=1, read_only=1),
-
-			dict(fieldname='einvoice_status', label='E-Invoice Status', fieldtype='Select', insert_after='qrcode_image',
-				options='\nPending\nGenerated\nCancelled\nFailed', default=None, hidden=1, no_copy=1, print_hide=1, read_only=1),
-
-			dict(fieldname='failure_description', label='E-Invoice Failure Description', fieldtype='Code', options='JSON',
-				hidden=1, insert_after='einvoice_status', no_copy=1, print_hide=1, read_only=1)
-		]
-	}
-	create_custom_fields(custom_fields, update=True)
-
-	if frappe.db.exists('E Invoice Settings') and frappe.db.get_single_value('E Invoice Settings', 'enable'):
-		frappe.db.sql('''
-			UPDATE `tabSales Invoice` SET einvoice_status = 'Pending'
-			WHERE
-				posting_date >= '2021-04-01'
-				AND ifnull(irn, '') = ''
-				AND ifnull(`billing_address_gstin`, '') != ifnull(`company_gstin`, '')
-				AND ifnull(gst_category, '') in ('Registered Regular', 'SEZ', 'Overseas', 'Deemed Export')
-		''')
-
-		# set appropriate statuses
-		frappe.db.sql('''UPDATE `tabSales Invoice` SET einvoice_status = 'Generated'
-			WHERE ifnull(irn, '') != '' AND ifnull(irn_cancelled, 0) = 0''')
-
-		frappe.db.sql('''UPDATE `tabSales Invoice` SET einvoice_status = 'Cancelled'
-			WHERE ifnull(irn_cancelled, 0) = 1''')
-
-	# set correct acknowledgement in e-invoices
-	einvoices = frappe.get_all('Sales Invoice', {'irn': ['is', 'set']}, ['name', 'signed_einvoice'])
-
-	if einvoices:
-		for inv in einvoices:
-			signed_einvoice = inv.get('signed_einvoice')
-			if signed_einvoice:
-				signed_einvoice = json.loads(signed_einvoice)
-				frappe.db.set_value('Sales Invoice', inv.get('name'), 'ack_no', signed_einvoice.get('AckNo'), update_modified=False)
-				frappe.db.set_value('Sales Invoice', inv.get('name'), 'ack_date', signed_einvoice.get('AckDt'), update_modified=False)
diff --git a/erpnext/patches/v12_0/add_einvoice_summary_report_permissions.py b/erpnext/patches/v12_0/add_einvoice_summary_report_permissions.py
deleted file mode 100644
index c1c11e2..0000000
--- a/erpnext/patches/v12_0/add_einvoice_summary_report_permissions.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from __future__ import unicode_literals
-import frappe
-
-def execute():
-	company = frappe.get_all('Company', filters = {'country': 'India'})
-	if not company:
-		return
-
-	if frappe.db.exists('Report', 'E-Invoice Summary') and \
-		not frappe.db.get_value('Custom Role', dict(report='E-Invoice Summary')):
-		frappe.get_doc(dict(
-			doctype='Custom Role',
-			report='E-Invoice Summary',
-			roles= [
-				dict(role='Accounts User'),
-				dict(role='Accounts Manager')
-			]
-		)).insert()
diff --git a/erpnext/patches/v12_0/add_ewaybill_validity_field.py b/erpnext/patches/v12_0/add_ewaybill_validity_field.py
deleted file mode 100644
index f29b714..0000000
--- a/erpnext/patches/v12_0/add_ewaybill_validity_field.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from __future__ import unicode_literals
-import frappe
-from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
-
-def execute():
-	company = frappe.get_all('Company', filters = {'country': 'India'})
-	if not company:
-		return
-
-	custom_fields = {
-		'Sales Invoice': [
-			dict(fieldname='eway_bill_validity', label='E-Way Bill Validity', fieldtype='Data', no_copy=1, print_hide=1,
-				depends_on='ewaybill', read_only=1, allow_on_submit=1, insert_after='ewaybill')
-		]
-	}
-	create_custom_fields(custom_fields, update=True)
diff --git a/erpnext/patches/v12_0/setup_einvoice_fields.py b/erpnext/patches/v12_0/setup_einvoice_fields.py
deleted file mode 100644
index 82b14fc..0000000
--- a/erpnext/patches/v12_0/setup_einvoice_fields.py
+++ /dev/null
@@ -1,56 +0,0 @@
-from __future__ import unicode_literals
-import frappe
-from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
-from erpnext.regional.india.setup import add_permissions, add_print_formats
-
-def execute():
-	company = frappe.get_all('Company', filters = {'country': 'India'})
-	if not company:
-		return
-
-	frappe.reload_doc("custom", "doctype", "custom_field")
-	frappe.reload_doc("regional", "doctype", "e_invoice_settings")
-	custom_fields = {
-		'Sales Invoice': [
-			dict(fieldname='irn', label='IRN', fieldtype='Data', read_only=1, insert_after='customer', no_copy=1, print_hide=1,
-				depends_on='eval:in_list(["Registered Regular", "SEZ", "Overseas", "Deemed Export"], doc.gst_category) && doc.irn_cancelled === 0'),
-
-			dict(fieldname='ack_no', label='Ack. No.', fieldtype='Data', read_only=1, hidden=1, insert_after='irn', no_copy=1, print_hide=1),
-
-			dict(fieldname='ack_date', label='Ack. Date', fieldtype='Data', read_only=1, hidden=1, insert_after='ack_no', no_copy=1, print_hide=1),
-
-			dict(fieldname='irn_cancelled', label='IRN Cancelled', fieldtype='Check', no_copy=1, print_hide=1,
-				depends_on='eval:(doc.irn_cancelled === 1)', read_only=1, allow_on_submit=1, insert_after='customer'),
-
-			dict(fieldname='eway_bill_cancelled', label='E-Way Bill Cancelled', fieldtype='Check', no_copy=1, print_hide=1,
-				depends_on='eval:(doc.eway_bill_cancelled === 1)', read_only=1, allow_on_submit=1, insert_after='customer'),
-
-			dict(fieldname='signed_einvoice', fieldtype='Code', options='JSON', hidden=1, no_copy=1, print_hide=1, read_only=1),
-
-			dict(fieldname='signed_qr_code', fieldtype='Code', options='JSON', hidden=1, no_copy=1, print_hide=1, read_only=1),
-
-			dict(fieldname='qrcode_image', label='QRCode', fieldtype='Attach Image', hidden=1, no_copy=1, print_hide=1, read_only=1)
-		]
-	}
-	create_custom_fields(custom_fields, update=True)
-	add_permissions()
-	add_print_formats()
-
-	einvoice_cond = 'in_list(["Registered Regular", "SEZ", "Overseas", "Deemed Export"], doc.gst_category)'
-	t = {
-		'mode_of_transport': [{'default': None}],
-		'distance': [{'mandatory_depends_on': f'eval:{einvoice_cond} && doc.transporter'}],
-		'gst_vehicle_type': [{'mandatory_depends_on': f'eval:{einvoice_cond} && doc.mode_of_transport == "Road"'}],
-		'lr_date': [{'mandatory_depends_on': f'eval:{einvoice_cond} && in_list(["Air", "Ship", "Rail"], doc.mode_of_transport)'}],
-		'lr_no': [{'mandatory_depends_on': f'eval:{einvoice_cond} && in_list(["Air", "Ship", "Rail"], doc.mode_of_transport)'}],
-		'vehicle_no': [{'mandatory_depends_on': f'eval:{einvoice_cond} && doc.mode_of_transport == "Road"'}],
-		'ewaybill': [
-			{'read_only_depends_on': 'eval:doc.irn && doc.ewaybill'},
-			{'depends_on': 'eval:((doc.docstatus === 1 || doc.ewaybill) && doc.eway_bill_cancelled === 0)'}
-		]
-	}
-
-	for field, conditions in t.items():
-		for c in conditions:
-			[(prop, value)] = c.items()
-			frappe.db.set_value('Custom Field', { 'fieldname': field }, prop, value)
diff --git a/erpnext/patches/v12_0/show_einvoice_irn_cancelled_field.py b/erpnext/patches/v12_0/show_einvoice_irn_cancelled_field.py
deleted file mode 100644
index 2319c17..0000000
--- a/erpnext/patches/v12_0/show_einvoice_irn_cancelled_field.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from __future__ import unicode_literals
-import frappe
-
-def execute():
-	company = frappe.get_all('Company', filters = {'country': 'India'})
-	if not company:
-		return
-
-	irn_cancelled_field = frappe.db.exists('Custom Field', {'dt': 'Sales Invoice', 'fieldname': 'irn_cancelled'})
-	if irn_cancelled_field:
-		frappe.db.set_value('Custom Field', irn_cancelled_field, 'depends_on', 'eval: doc.irn')
-		frappe.db.set_value('Custom Field', irn_cancelled_field, 'read_only', 0)
diff --git a/erpnext/patches/v13_0/einvoicing_deprecation_warning.py b/erpnext/patches/v13_0/einvoicing_deprecation_warning.py
new file mode 100644
index 0000000..e123a55
--- /dev/null
+++ b/erpnext/patches/v13_0/einvoicing_deprecation_warning.py
@@ -0,0 +1,9 @@
+import click
+
+
+def execute():
+	click.secho(
+		"Indian E-Invoicing integration is moved to a separate app and will be removed from ERPNext in version-14.\n"
+		"Please install the app to continue using the integration: https://github.com/frappe/erpnext_gst_compliance",
+		fg="yellow",
+	)
diff --git a/erpnext/regional/india/e_invoice/__init__.py b/erpnext/patches/v14_0/__init__.py
similarity index 100%
rename from erpnext/regional/india/e_invoice/__init__.py
rename to erpnext/patches/v14_0/__init__.py
diff --git a/erpnext/patches/v14_0/delete_einvoicing_doctypes.py b/erpnext/patches/v14_0/delete_einvoicing_doctypes.py
new file mode 100644
index 0000000..b77d244
--- /dev/null
+++ b/erpnext/patches/v14_0/delete_einvoicing_doctypes.py
@@ -0,0 +1,9 @@
+import frappe
+
+def execute():
+	frappe.delete_doc('DocType', 'E Invoice Settings', ignore_missing=True)
+	frappe.delete_doc('DocType', 'E Invoice User', ignore_missing=True)
+	frappe.delete_doc('Report', 'E-Invoice Summary', ignore_missing=True)
+	frappe.delete_doc('Print Format', 'GST E-Invoice', ignore_missing=True)
+	frappe.delete_doc('Custom Field', 'Sales Invoice-eway_bill_cancelled', ignore_missing=True)
+	frappe.delete_doc('Custom Field', 'Sales Invoice-irn_cancelled', ignore_missing=True)
\ No newline at end of file
diff --git a/erpnext/payroll/doctype/salary_component/salary_component.js b/erpnext/payroll/doctype/salary_component/salary_component.js
index e9e6f81..dbf7514 100644
--- a/erpnext/payroll/doctype/salary_component/salary_component.js
+++ b/erpnext/payroll/doctype/salary_component/salary_component.js
@@ -4,18 +4,11 @@
 frappe.ui.form.on('Salary Component', {
 	setup: function(frm) {
 		frm.set_query("account", "accounts", function(doc, cdt, cdn) {
-			let d = frappe.get_doc(cdt, cdn);
-
-			let root_type = "Liability";
-			if (frm.doc.type == "Deduction") {
-				root_type = "Expense";
-			}
-
+			var d = locals[cdt][cdn];
 			return {
 				filters: {
 					"is_group": 0,
-					"company": d.company,
-					"root_type": root_type
+					"company": d.company
 				}
 			};
 		});
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index e8f3122..702064f 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -754,8 +754,6 @@
 			}
 		});
 		this.frm.refresh_fields();
-
-		this.calculate_paid_amount();
 	}
 
 	set_default_payment(total_amount_to_pay, update_paid_amount) {
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 3c6c347..2538852 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -342,30 +342,6 @@
 		this.set_dynamic_labels();
 		this.setup_sms();
 		this.setup_quality_inspection();
-		let scan_barcode_field = this.frm.get_field('scan_barcode');
-		if (scan_barcode_field && scan_barcode_field.get_value()) {
-			scan_barcode_field.set_value("");
-			scan_barcode_field.set_new_description("");
-
-			if (frappe.is_mobile()) {
-				if (scan_barcode_field.$input_wrapper.find('.input-group').length) return;
-
-				let $input_group = $('<div class="input-group">');
-				scan_barcode_field.$input_wrapper.find('.control-input').append($input_group);
-				$input_group.append(scan_barcode_field.$input);
-				$(`<span class="input-group-btn" style="vertical-align: top">
-						<button class="btn btn-default border" type="button">
-							<i class="fa fa-camera text-muted"></i>
-						</button>
-					</span>`)
-					.on('click', '.btn', () => {
-						frappe.barcode.scan_barcode().then(barcode => {
-							scan_barcode_field.set_value(barcode);
-						});
-					})
-					.appendTo($input_group);
-			}
-		}
 	}
 
 	scan_barcode() {
@@ -2266,12 +2242,19 @@
 
 	coupon_code() {
 		var me = this;
-		frappe.run_serially([
-			() => this.frm.doc.ignore_pricing_rule=1,
-			() => me.ignore_pricing_rule(),
-			() => this.frm.doc.ignore_pricing_rule=0,
-			() => me.apply_pricing_rule()
-		]);
+		if (this.frm.doc.coupon_code) {
+			frappe.run_serially([
+				() => this.frm.doc.ignore_pricing_rule=1,
+				() => me.ignore_pricing_rule(),
+				() => this.frm.doc.ignore_pricing_rule=0,
+				() => me.apply_pricing_rule()
+			]);
+		} else {
+			frappe.run_serially([
+				() => this.frm.doc.ignore_pricing_rule=1,
+				() => me.ignore_pricing_rule()
+			]);
+		}
 	}
 };
 
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index f1b9235..f240b8c 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -563,7 +563,7 @@
 			},
 		],
 		primary_action: function() {
-			const trans_items = this.get_values()["trans_items"];
+			const trans_items = this.get_values()["trans_items"].filter((item) => !!item.item_code);
 			frappe.call({
 				method: 'erpnext.controllers.accounts_controller.update_child_qty_rate',
 				freeze: true,
diff --git a/erpnext/public/scss/point-of-sale.scss b/erpnext/public/scss/point-of-sale.scss
index c77b2ce..1677e9b 100644
--- a/erpnext/public/scss/point-of-sale.scss
+++ b/erpnext/public/scss/point-of-sale.scss
@@ -860,6 +860,8 @@
 
 				.invoice-fields {
 					overflow-y: scroll;
+					height: 100%;
+					padding-right: var(--padding-sm);
 				}
 			}
 
diff --git a/erpnext/regional/doctype/e_invoice_request_log/__init__.py b/erpnext/regional/doctype/e_invoice_request_log/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/regional/doctype/e_invoice_request_log/__init__.py
+++ /dev/null
diff --git a/erpnext/regional/doctype/e_invoice_request_log/e_invoice_request_log.js b/erpnext/regional/doctype/e_invoice_request_log/e_invoice_request_log.js
deleted file mode 100644
index 7b7ba96..0000000
--- a/erpnext/regional/doctype/e_invoice_request_log/e_invoice_request_log.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('E Invoice Request Log', {
-	// refresh: function(frm) {
-
-	// }
-});
diff --git a/erpnext/regional/doctype/e_invoice_request_log/e_invoice_request_log.json b/erpnext/regional/doctype/e_invoice_request_log/e_invoice_request_log.json
deleted file mode 100644
index 3034370..0000000
--- a/erpnext/regional/doctype/e_invoice_request_log/e_invoice_request_log.json
+++ /dev/null
@@ -1,102 +0,0 @@
-{
- "actions": [],
- "autoname": "EINV-REQ-.#####",
- "creation": "2020-12-08 12:54:08.175992",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "user",
-  "url",
-  "headers",
-  "response",
-  "column_break_7",
-  "timestamp",
-  "reference_invoice",
-  "data"
- ],
- "fields": [
-  {
-   "fieldname": "user",
-   "fieldtype": "Link",
-   "label": "User",
-   "options": "User"
-  },
-  {
-   "fieldname": "reference_invoice",
-   "fieldtype": "Data",
-   "label": "Reference Invoice"
-  },
-  {
-   "fieldname": "headers",
-   "fieldtype": "Code",
-   "label": "Headers",
-   "options": "JSON"
-  },
-  {
-   "fieldname": "data",
-   "fieldtype": "Code",
-   "label": "Data",
-   "options": "JSON"
-  },
-  {
-   "default": "Now",
-   "fieldname": "timestamp",
-   "fieldtype": "Datetime",
-   "label": "Timestamp"
-  },
-  {
-   "fieldname": "response",
-   "fieldtype": "Code",
-   "label": "Response",
-   "options": "JSON"
-  },
-  {
-   "fieldname": "url",
-   "fieldtype": "Data",
-   "label": "URL"
-  },
-  {
-   "fieldname": "column_break_7",
-   "fieldtype": "Column Break"
-  }
- ],
- "index_web_pages_for_search": 1,
- "links": [],
- "modified": "2021-01-13 12:06:57.253111",
- "modified_by": "Administrator",
- "module": "Regional",
- "name": "E Invoice Request Log",
- "owner": "Administrator",
- "permissions": [
-  {
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1
-  },
-  {
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Accounts User",
-   "share": 1
-  },
-  {
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Accounts Manager",
-   "share": 1
-  }
- ],
- "sort_field": "modified",
- "sort_order": "DESC"
-}
\ No newline at end of file
diff --git a/erpnext/regional/doctype/e_invoice_request_log/e_invoice_request_log.py b/erpnext/regional/doctype/e_invoice_request_log/e_invoice_request_log.py
deleted file mode 100644
index 9150bdd..0000000
--- a/erpnext/regional/doctype/e_invoice_request_log/e_invoice_request_log.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- 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 EInvoiceRequestLog(Document):
-	pass
diff --git a/erpnext/regional/doctype/e_invoice_request_log/test_e_invoice_request_log.py b/erpnext/regional/doctype/e_invoice_request_log/test_e_invoice_request_log.py
deleted file mode 100644
index c84e9a2..0000000
--- a/erpnext/regional/doctype/e_invoice_request_log/test_e_invoice_request_log.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- 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 TestEInvoiceRequestLog(unittest.TestCase):
-	pass
diff --git a/erpnext/regional/doctype/e_invoice_settings/__init__.py b/erpnext/regional/doctype/e_invoice_settings/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/regional/doctype/e_invoice_settings/__init__.py
+++ /dev/null
diff --git a/erpnext/regional/doctype/e_invoice_settings/e_invoice_settings.js b/erpnext/regional/doctype/e_invoice_settings/e_invoice_settings.js
deleted file mode 100644
index 54e4886..0000000
--- a/erpnext/regional/doctype/e_invoice_settings/e_invoice_settings.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('E Invoice Settings', {
-	refresh(frm) {
-		const docs_link = 'https://docs.erpnext.com/docs/v13/user/manual/en/regional/india/setup-e-invoicing';
-		frm.dashboard.set_headline(
-			__("Read {0} for more information on E Invoicing features.", [`<a href='${docs_link}'>documentation</a>`])
-		);
-	}
-});
diff --git a/erpnext/regional/doctype/e_invoice_settings/e_invoice_settings.json b/erpnext/regional/doctype/e_invoice_settings/e_invoice_settings.json
deleted file mode 100644
index 68ed339..0000000
--- a/erpnext/regional/doctype/e_invoice_settings/e_invoice_settings.json
+++ /dev/null
@@ -1,73 +0,0 @@
-{
- "actions": [],
- "creation": "2020-09-24 16:23:16.235722",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "enable",
-  "section_break_2",
-  "sandbox_mode",
-  "applicable_from",
-  "credentials",
-  "auth_token",
-  "token_expiry"
- ],
- "fields": [
-  {
-   "default": "0",
-   "fieldname": "enable",
-   "fieldtype": "Check",
-   "label": "Enable"
-  },
-  {
-   "depends_on": "enable",
-   "fieldname": "section_break_2",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "auth_token",
-   "fieldtype": "Data",
-   "hidden": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "token_expiry",
-   "fieldtype": "Datetime",
-   "hidden": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "credentials",
-   "fieldtype": "Table",
-   "label": "Credentials",
-   "mandatory_depends_on": "enable",
-   "options": "E Invoice User"
-  },
-  {
-   "default": "0",
-   "fieldname": "sandbox_mode",
-   "fieldtype": "Check",
-   "label": "Sandbox Mode"
-  },
-  {
-   "fieldname": "applicable_from",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "label": "Applicable From",
-   "reqd": 1
-  }
- ],
- "index_web_pages_for_search": 1,
- "issingle": 1,
- "links": [],
- "modified": "2021-03-30 12:26:25.538294",
- "modified_by": "Administrator",
- "module": "Regional",
- "name": "E Invoice Settings",
- "owner": "Administrator",
- "permissions": [],
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/regional/doctype/e_invoice_settings/e_invoice_settings.py b/erpnext/regional/doctype/e_invoice_settings/e_invoice_settings.py
deleted file mode 100644
index 4f6b3ec..0000000
--- a/erpnext/regional/doctype/e_invoice_settings/e_invoice_settings.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# -*- 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 import _
-from frappe.model.document import Document
-
-class EInvoiceSettings(Document):
-	def validate(self):
-		if self.enable and not self.credentials:
-			frappe.throw(_('You must add atleast one credentials to be able to use E Invoicing.'))
diff --git a/erpnext/regional/doctype/e_invoice_settings/test_e_invoice_settings.py b/erpnext/regional/doctype/e_invoice_settings/test_e_invoice_settings.py
deleted file mode 100644
index a11ce63..0000000
--- a/erpnext/regional/doctype/e_invoice_settings/test_e_invoice_settings.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- 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 TestEInvoiceSettings(unittest.TestCase):
-	pass
diff --git a/erpnext/regional/doctype/e_invoice_user/__init__.py b/erpnext/regional/doctype/e_invoice_user/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/regional/doctype/e_invoice_user/__init__.py
+++ /dev/null
diff --git a/erpnext/regional/doctype/e_invoice_user/e_invoice_user.json b/erpnext/regional/doctype/e_invoice_user/e_invoice_user.json
deleted file mode 100644
index a65b1ca..0000000
--- a/erpnext/regional/doctype/e_invoice_user/e_invoice_user.json
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- "actions": [],
- "creation": "2020-12-22 15:02:46.229474",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "company",
-  "gstin",
-  "username",
-  "password"
- ],
- "fields": [
-  {
-   "fieldname": "gstin",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "GSTIN",
-   "reqd": 1
-  },
-  {
-   "fieldname": "username",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Username",
-   "reqd": 1
-  },
-  {
-   "fieldname": "password",
-   "fieldtype": "Password",
-   "in_list_view": 1,
-   "label": "Password",
-   "reqd": 1
-  },
-  {
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Company",
-   "options": "Company",
-   "reqd": 1
-  }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2021-03-22 12:16:56.365616",
- "modified_by": "Administrator",
- "module": "Regional",
- "name": "E Invoice User",
- "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/regional/doctype/e_invoice_user/e_invoice_user.py b/erpnext/regional/doctype/e_invoice_user/e_invoice_user.py
deleted file mode 100644
index 056c54f..0000000
--- a/erpnext/regional/doctype/e_invoice_user/e_invoice_user.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- 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 EInvoiceUser(Document):
-	pass
diff --git a/erpnext/regional/india/e_invoice/einv_item_template.json b/erpnext/regional/india/e_invoice/einv_item_template.json
deleted file mode 100644
index 78e5651..0000000
--- a/erpnext/regional/india/e_invoice/einv_item_template.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{{
-    "SlNo": "{item.sr_no}",
-    "PrdDesc": "{item.description}",
-    "IsServc": "{item.is_service_item}",
-    "HsnCd": "{item.gst_hsn_code}",
-    "Barcde": "{item.barcode}",
-    "Unit": "{item.uom}",
-    "Qty": "{item.qty}",
-    "FreeQty": "{item.free_qty}",
-    "UnitPrice": "{item.unit_rate}",
-    "TotAmt": "{item.gross_amount}",
-    "Discount": "{item.discount_amount}",
-    "AssAmt": "{item.taxable_value}",
-    "PrdSlNo": "{item.serial_no}",
-    "GstRt": "{item.tax_rate}",
-    "IgstAmt": "{item.igst_amount}",
-    "CgstAmt": "{item.cgst_amount}",
-    "SgstAmt": "{item.sgst_amount}",
-    "CesRt": "{item.cess_rate}",
-    "CesAmt": "{item.cess_amount}",
-    "CesNonAdvlAmt": "{item.cess_nadv_amount}",
-    "StateCesRt": "{item.state_cess_rate}",
-    "StateCesAmt": "{item.state_cess_amount}",
-    "StateCesNonAdvlAmt": "{item.state_cess_nadv_amount}",
-    "OthChrg": "{item.other_charges}",
-    "TotItemVal": "{item.total_value}",
-    "BchDtls": {{
-        "Nm": "{item.batch_no}",
-        "ExpDt": "{item.batch_expiry_date}"
-    }}
-}}
\ No newline at end of file
diff --git a/erpnext/regional/india/e_invoice/einv_template.json b/erpnext/regional/india/e_invoice/einv_template.json
deleted file mode 100644
index 60f490d..0000000
--- a/erpnext/regional/india/e_invoice/einv_template.json
+++ /dev/null
@@ -1,110 +0,0 @@
-{{
-    "Version": "1.1",
-    "TranDtls": {{
-        "TaxSch": "{transaction_details.tax_scheme}",
-        "SupTyp": "{transaction_details.supply_type}",
-        "RegRev": "{transaction_details.reverse_charge}",
-        "EcmGstin": "{transaction_details.ecom_gstin}",
-        "IgstOnIntra": "{transaction_details.igst_on_intra}"
-    }},
-    "DocDtls": {{
-        "Typ": "{doc_details.invoice_type}",
-        "No": "{doc_details.invoice_name}",
-        "Dt": "{doc_details.invoice_date}"
-    }},
-    "SellerDtls": {{
-        "Gstin": "{seller_details.gstin}",
-        "LglNm": "{seller_details.legal_name}",
-        "TrdNm": "{seller_details.trade_name}",
-        "Loc": "{seller_details.location}",
-        "Pin": "{seller_details.pincode}",
-        "Stcd": "{seller_details.state_code}",
-        "Addr1": "{seller_details.address_line1}",
-        "Addr2": "{seller_details.address_line2}",
-        "Ph": "{seller_details.phone}",
-        "Em": "{seller_details.email}"
-    }},
-    "BuyerDtls": {{
-        "Gstin": "{buyer_details.gstin}",
-        "LglNm": "{buyer_details.legal_name}",
-        "TrdNm": "{buyer_details.trade_name}",
-        "Addr1": "{buyer_details.address_line1}",
-        "Addr2": "{buyer_details.address_line2}",
-        "Loc": "{buyer_details.location}",
-        "Pin": "{buyer_details.pincode}",
-        "Stcd": "{buyer_details.state_code}",
-        "Ph": "{buyer_details.phone}",
-        "Em": "{buyer_details.email}",
-        "Pos": "{buyer_details.place_of_supply}"
-    }},
-    "DispDtls": {{
-        "Nm": "{dispatch_details.company_name}",
-        "Addr1": "{dispatch_details.address_line1}",
-        "Addr2": "{dispatch_details.address_line2}",
-        "Loc": "{dispatch_details.location}",
-        "Pin": "{dispatch_details.pincode}",
-        "Stcd": "{dispatch_details.state_code}"
-    }},
-    "ShipDtls": {{
-        "Gstin": "{shipping_details.gstin}",
-        "LglNm": "{shipping_details.legal_name}",
-        "TrdNm": "{shipping_details.trader_name}",
-        "Addr1": "{shipping_details.address_line1}",
-        "Addr2": "{shipping_details.address_line2}",
-        "Loc": "{shipping_details.location}",
-        "Pin": "{shipping_details.pincode}",
-        "Stcd": "{shipping_details.state_code}"
-    }},
-    "ItemList": [
-        {item_list}
-    ],
-    "ValDtls": {{
-        "AssVal": "{invoice_value_details.base_total}",
-        "CgstVal": "{invoice_value_details.total_cgst_amt}",
-        "SgstVal": "{invoice_value_details.total_sgst_amt}",
-        "IgstVal": "{invoice_value_details.total_igst_amt}",
-        "CesVal": "{invoice_value_details.total_cess_amt}",
-        "Discount": "{invoice_value_details.invoice_discount_amt}",
-        "RndOffAmt": "{invoice_value_details.round_off}",
-        "OthChrg": "{invoice_value_details.total_other_charges}",
-        "TotInvVal": "{invoice_value_details.base_grand_total}",
-        "TotInvValFc": "{invoice_value_details.grand_total}"
-    }},
-    "PayDtls": {{
-        "Nm": "{payment_details.payee_name}",
-        "AccDet": "{payment_details.account_no}",
-        "Mode": "{payment_details.mode_of_payment}",
-        "FinInsBr": "{payment_details.ifsc_code}",
-        "PayTerm": "{payment_details.terms}",
-        "PaidAmt": "{payment_details.paid_amount}",
-        "PaymtDue": "{payment_details.outstanding_amount}"
-    }},
-    "RefDtls": {{
-        "DocPerdDtls": {{
-            "InvStDt": "{period_details.start_date}",
-            "InvEndDt": "{period_details.end_date}"
-        }},
-        "PrecDocDtls": [{{
-            "InvNo": "{prev_doc_details.invoice_name}",
-            "InvDt": "{prev_doc_details.invoice_date}"
-        }}]
-    }},
-    "ExpDtls": {{
-        "ShipBNo": "{export_details.bill_no}",
-        "ShipBDt": "{export_details.bill_date}",
-        "Port": "{export_details.port}",
-        "ForCur": "{export_details.foreign_curr_code}",
-        "CntCode": "{export_details.country_code}",
-        "ExpDuty": "{export_details.export_duty}"
-    }},
-    "EwbDtls": {{
-        "TransId": "{eway_bill_details.gstin}",
-        "TransName": "{eway_bill_details.name}",
-        "TransMode": "{eway_bill_details.mode_of_transport}",
-        "Distance": "{eway_bill_details.distance}",
-        "TransDocNo": "{eway_bill_details.document_name}",
-        "TransDocDt": "{eway_bill_details.document_date}",
-        "VehNo": "{eway_bill_details.vehicle_no}",
-        "VehType": "{eway_bill_details.vehicle_type}"
-    }}
-}}
\ No newline at end of file
diff --git a/erpnext/regional/india/e_invoice/einv_validation.json b/erpnext/regional/india/e_invoice/einv_validation.json
deleted file mode 100644
index f4a3542..0000000
--- a/erpnext/regional/india/e_invoice/einv_validation.json
+++ /dev/null
@@ -1,957 +0,0 @@
-{
-  "Version": {
-    "type": "string",
-    "minLength": 1,
-    "maxLength": 6,
-    "description": "Version of the schema"
-  },
-  "Irn": {
-    "type": "string",
-    "minLength": 64,
-    "maxLength": 64,
-    "description": "Invoice Reference Number"
-  },
-  "TranDtls": {
-    "type": "object",
-    "properties": {
-      "TaxSch": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 10,
-        "enum": ["GST"],
-        "description": "GST- Goods and Services Tax Scheme"
-      },
-      "SupTyp": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 10,
-        "enum": ["B2B", "SEZWP", "SEZWOP", "EXPWP", "EXPWOP", "DEXP"],
-        "description": "Type of Supply: B2B-Business to Business, SEZWP - SEZ with payment, SEZWOP - SEZ without payment, EXPWP - Export with Payment, EXPWOP - Export without payment,DEXP - Deemed Export"
-      },
-      "RegRev": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 1,
-        "enum": ["Y", "N"],
-        "description": "Y- whether the tax liability is payable under reverse charge"
-      },
-      "EcmGstin": {
-        "type": "string",
-        "minLength": 15,
-        "maxLength": 15,
-        "pattern": "([0-9]{2}[0-9A-Z]{13})",
-        "description": "E-Commerce GSTIN",
-        "validationMsg": "E-Commerce GSTIN is invalid"
-      },
-      "IgstOnIntra": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 1,
-        "enum": ["Y", "N"],
-        "description": "Y- indicates the supply is intra state but chargeable to IGST"
-      }
-    },
-    "required": ["TaxSch", "SupTyp"]
-  },
-  "DocDtls": {
-    "type": "object",
-    "properties": {
-      "Typ": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 3,
-        "enum": ["INV", "CRN", "DBN"],
-        "description": "Document Type"
-      },
-      "No": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 16,
-        "pattern": "^([A-Z1-9]{1}[A-Z0-9/-]{0,15})$",
-        "description": "Document Number",
-        "validationMsg": "Document Number should not be starting with 0, / and -"
-      },
-      "Dt": {
-        "type": "string",
-        "minLength": 10,
-        "maxLength": 10,
-        "pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
-        "description": "Document Date"
-      }
-    },
-    "required": ["Typ", "No", "Dt"]
-  },
-  "SellerDtls": {
-    "type": "object",
-    "properties": {
-      "Gstin": {
-        "type": "string",
-        "minLength": 15,
-        "maxLength": 15,
-        "pattern": "([0-9]{2}[0-9A-Z]{13})",
-        "description": "Supplier GSTIN",
-        "validationMsg": "Company GSTIN is invalid"
-      },
-      "LglNm": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Legal Name"
-      },
-      "TrdNm": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Tradename"
-      },
-      "Addr1": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 100,
-        "description": "Address Line 1"
-      },
-      "Addr2": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Address Line 2"
-      },
-      "Loc": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 50,
-        "description": "Location"
-      },
-      "Pin": {
-        "type": "number",
-        "minimum": 100000,
-        "maximum": 999999,
-        "description": "Pincode"
-      },
-      "Stcd": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 2,
-        "description": "Supplier State Code"
-      },
-      "Ph": {
-        "type": "string",
-        "minLength": 6,
-        "maxLength": 12,
-        "description": "Phone"
-      },
-      "Em": {
-        "type": "string",
-        "minLength": 6,
-        "maxLength": 100,
-        "description": "Email-Id"
-      }
-    },
-    "required": ["Gstin", "LglNm", "Addr1", "Loc", "Pin", "Stcd"]
-  },
-  "BuyerDtls": {
-    "type": "object",
-    "properties": {
-      "Gstin": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 15,
-        "pattern": "^(([0-9]{2}[0-9A-Z]{13})|URP)$",
-        "description": "Buyer GSTIN",
-        "validationMsg": "Customer GSTIN is invalid"
-      },
-      "LglNm": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Legal Name"
-      },
-      "TrdNm": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Trade Name"
-      },
-      "Pos": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 2,
-        "description": "Place of Supply State code"
-      },
-      "Addr1": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 100,
-        "description": "Address Line 1"
-      },
-      "Addr2": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Address Line 2"
-      },
-      "Loc": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Location"
-      },
-      "Pin": {
-        "type": "number",
-        "minimum": 100000,
-        "maximum": 999999,
-        "description": "Pincode"
-      },
-      "Stcd": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 2,
-        "description": "Buyer State Code"
-      },
-      "Ph": {
-        "type": "string",
-        "minLength": 6,
-        "maxLength": 12,
-        "description": "Phone"
-      },
-      "Em": {
-        "type": "string",
-        "minLength": 6,
-        "maxLength": 100,
-        "description": "Email-Id"
-      }
-    },
-    "required": ["Gstin", "LglNm", "Pos", "Addr1", "Loc", "Stcd"]
-  },
-  "DispDtls": {
-    "type": "object",
-    "properties": {
-      "Nm": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Dispatch Address Name"
-      },
-      "Addr1": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 100,
-        "description": "Address Line 1"
-      },
-      "Addr2": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Address Line 2"
-      },
-      "Loc": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Location"
-      },
-      "Pin": {
-        "type": "number",
-        "minimum": 100000,
-        "maximum": 999999,
-        "description": "Pincode"
-      },
-      "Stcd": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 2,
-        "description": "State Code"
-      }
-    },
-    "required": ["Nm", "Addr1", "Loc", "Pin", "Stcd"]
-  },
-  "ShipDtls": {
-    "type": "object",
-    "properties": {
-      "Gstin": {
-        "type": "string",
-        "maxLength": 15,
-        "minLength": 3,
-        "pattern": "^(([0-9]{2}[0-9A-Z]{13})|URP)$",
-        "description": "Shipping Address GSTIN",
-        "validationMsg": "Shipping Address GSTIN is invalid"
-      },
-      "LglNm": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Legal Name"
-      },
-      "TrdNm": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Trade Name"
-      },
-      "Addr1": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 100,
-        "description": "Address Line 1"
-      },
-      "Addr2": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Address Line 2"
-      },
-      "Loc": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Location"
-      },
-      "Pin": {
-        "type": "number",
-        "minimum": 100000,
-        "maximum": 999999,
-        "description": "Pincode"
-      },
-      "Stcd": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 2,
-        "description": "State Code"
-      }
-    },
-    "required": ["LglNm", "Addr1", "Loc", "Pin", "Stcd"]
-  },
-  "ItemList": {
-    "type": "Array",
-    "properties": {
-      "SlNo": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 6,
-        "description": "Serial No. of Item"
-      },
-      "PrdDesc": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 300,
-        "description": "Item Name"
-      },
-      "IsServc": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 1,
-        "enum": ["Y", "N"],
-        "description": "Is Service Item"
-      },
-      "HsnCd": {
-        "type": "string",
-        "minLength": 4,
-        "maxLength": 8,
-        "description": "HSN Code"
-      },
-      "Barcde": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 30,
-        "description": "Barcode"
-      },
-      "Qty": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 9999999999.999,
-        "description": "Quantity"
-      },
-      "FreeQty": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 9999999999.999,
-        "description": "Free Quantity"
-      },
-      "Unit": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 8,
-        "description": "UOM"
-      },
-      "UnitPrice": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999999999999.999,
-        "description": "Rate"
-      },
-      "TotAmt": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999999999999.99,
-        "description": "Gross Amount"
-      },
-      "Discount": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999999999999.99,
-        "description": "Discount"
-      },
-      "PreTaxVal": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999999999999.99,
-        "description": "Pre tax value"
-      },
-      "AssAmt": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999999999999.99,
-        "description": "Taxable Value"
-      },
-      "GstRt": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999.999,
-        "description": "GST Rate"
-      },
-      "IgstAmt": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999999999999.99,
-        "description": "IGST Amount"
-      },
-      "CgstAmt": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999999999999.99,
-        "description": "CGST Amount"
-      },
-      "SgstAmt": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999999999999.99,
-        "description": "SGST Amount"
-      },
-      "CesRt": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999.999,
-        "description": "Cess Rate"
-      },
-      "CesAmt": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999999999999.99,
-        "description": "Cess Amount (Advalorem)"
-      },
-      "CesNonAdvlAmt": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999999999999.99,
-        "description": "Cess Amount (Non-Advalorem)"
-      },
-      "StateCesRt": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999.999,
-        "description": "State CESS Rate"
-      },
-      "StateCesAmt": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999999999999.99,
-        "description": "State CESS Amount"
-      },
-      "StateCesNonAdvlAmt": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999999999999.99,
-        "description": "State CESS Amount (Non Advalorem)"
-      },
-      "OthChrg": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999999999999.99,
-        "description": "Other Charges"
-      },
-      "TotItemVal": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999999999999.99,
-        "description": "Total Item Value"
-      },
-      "OrdLineRef": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 50,
-        "description": "Order line reference"
-      },
-      "OrgCntry": {
-        "type": "string",
-        "minLength": 2,
-        "maxLength": 2,
-        "description": "Origin Country"
-      },
-      "PrdSlNo": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 20,
-        "description": "Serial number"
-      },
-      "BchDtls": {
-        "type": "object",
-        "properties": {
-          "Nm": {
-            "type": "string",
-            "minLength": 3,
-            "maxLength": 20,
-            "description": "Batch number"
-          },
-          "ExpDt": {
-            "type": "string",
-            "maxLength": 10,
-            "minLength": 10,
-            "pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
-            "description": "Batch Expiry Date"
-          },
-          "WrDt": {
-            "type": "string",
-            "maxLength": 10,
-            "minLength": 10,
-            "pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
-            "description": "Warranty Date"
-          }
-        },
-        "required": ["Nm"]
-      },
-      "AttribDtls": {
-        "type": "Array",
-        "Attribute": {
-          "type": "object",
-          "properties": {
-            "Nm": {
-              "type": "string",
-              "minLength": 1,
-              "maxLength": 100,
-              "description": "Attribute name of the item"
-            },
-            "Val": {
-              "type": "string",
-              "minLength": 1,
-              "maxLength": 100,
-              "description": "Attribute value of the item"
-            }
-          }
-        }
-      }
-    },
-    "required": [
-      "SlNo",
-      "IsServc",
-      "HsnCd",
-      "UnitPrice",
-      "TotAmt",
-      "AssAmt",
-      "GstRt",
-      "TotItemVal"
-    ]
-  },
-  "ValDtls": {
-    "type": "object",
-    "properties": {
-      "AssVal": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 99999999999999.99,
-        "description": "Total Assessable value of all items"
-      },
-      "CgstVal": {
-        "type": "number",
-        "maximum": 99999999999999.99,
-        "minimum": 0,
-        "description": "Total CGST value of all items"
-      },
-      "SgstVal": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 99999999999999.99,
-        "description": "Total SGST value of all items"
-      },
-      "IgstVal": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 99999999999999.99,
-        "description": "Total IGST value of all items"
-      },
-      "CesVal": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 99999999999999.99,
-        "description": "Total CESS value of all items"
-      },
-      "StCesVal": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 99999999999999.99,
-        "description": "Total State CESS value of all items"
-      },
-      "Discount": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 99999999999999.99,
-        "description": "Invoice Discount"
-      },
-      "OthChrg": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 99999999999999.99,
-        "description": "Other Charges"
-      },
-      "RndOffAmt": {
-        "type": "number",
-        "minimum": -99.99,
-        "maximum": 99.99,
-        "description": "Rounded off Amount"
-      },
-      "TotInvVal": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 99999999999999.99,
-        "description": "Final Invoice Value "
-      },
-      "TotInvValFc": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 99999999999999.99,
-        "description": "Final Invoice value in Foreign Currency"
-      }
-    },
-    "required": ["AssVal", "TotInvVal"]
-  },
-  "PayDtls": {
-    "type": "object",
-    "properties": {
-      "Nm": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 100,
-        "description": "Payee Name"
-      },
-      "AccDet": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 18,
-        "description": "Bank Account Number of Payee"
-      },
-      "Mode": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 18,
-        "description": "Mode of Payment"
-      },
-      "FinInsBr": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 11,
-        "description": "Branch or IFSC code"
-      },
-      "PayTerm": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 100,
-        "description": "Terms of Payment"
-      },
-      "PayInstr": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 100,
-        "description": "Payment Instruction"
-      },
-      "CrTrn": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 100,
-        "description": "Credit Transfer"
-      },
-      "DirDr": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 100,
-        "description": "Direct Debit"
-      },
-      "CrDay": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 9999,
-        "description": "Credit Days"
-      },
-      "PaidAmt": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 99999999999999.99,
-        "description": "Advance Amount"
-      },
-      "PaymtDue": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 99999999999999.99,
-        "description": "Outstanding Amount"
-      }
-    }
-  },
-  "RefDtls": {
-    "type": "object",
-    "properties": {
-      "InvRm": {
-        "type": "string",
-        "maxLength": 100,
-        "minLength": 3,
-        "pattern": "^[0-9A-Za-z/-]{3,100}$",
-        "description": "Remarks/Note"
-      },
-      "DocPerdDtls": {
-        "type": "object",
-        "properties": {
-          "InvStDt": {
-            "type": "string",
-            "maxLength": 10,
-            "minLength": 10,
-            "pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
-            "description": "Invoice Period Start Date"
-          },
-          "InvEndDt": {
-            "type": "string",
-            "maxLength": 10,
-            "minLength": 10,
-            "pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
-            "description": "Invoice Period End Date"
-          }
-        },
-        "required": ["InvStDt ", "InvEndDt "]
-      },
-      "PrecDocDtls": {
-        "type": "object",
-        "properties": {
-          "InvNo": {
-            "type": "string",
-            "minLength": 1,
-            "maxLength": 16,
-            "pattern": "^[1-9A-Z]{1}[0-9A-Z/-]{1,15}$",
-            "description": "Reference of Original Invoice"
-          },
-          "InvDt": {
-            "type": "string",
-            "maxLength": 10,
-            "minLength": 10,
-            "pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
-            "description": "Date of Orginal Invoice"
-          },
-          "OthRefNo": {
-            "type": "string",
-            "minLength": 1,
-            "maxLength": 20,
-            "description": "Other Reference"
-          }
-        }
-      },
-      "required": ["InvNo", "InvDt"],
-      "ContrDtls": {
-        "type": "object",
-        "properties": {
-          "RecAdvRefr": {
-            "type": "string",
-            "minLength": 1,
-            "maxLength": 20,
-            "pattern": "^([0-9A-Za-z/-]){1,20}$",
-            "description": "Receipt Advice No."
-          },
-          "RecAdvDt": {
-            "type": "string",
-            "minLength": 10,
-            "maxLength": 10,
-            "pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
-            "description": "Date of receipt advice"
-          },
-          "TendRefr": {
-            "type": "string",
-            "minLength": 1,
-            "maxLength": 20,
-            "pattern": "^([0-9A-Za-z/-]){1,20}$",
-            "description": "Lot/Batch Reference No."
-          },
-          "ContrRefr": {
-            "type": "string",
-            "minLength": 1,
-            "maxLength": 20,
-            "pattern": "^([0-9A-Za-z/-]){1,20}$",
-            "description": "Contract Reference Number"
-          },
-          "ExtRefr": {
-            "type": "string",
-            "minLength": 1,
-            "maxLength": 20,
-            "pattern": "^([0-9A-Za-z/-]){1,20}$",
-            "description": "Any other reference"
-          },
-          "ProjRefr": {
-            "type": "string",
-            "minLength": 1,
-            "maxLength": 20,
-            "pattern": "^([0-9A-Za-z/-]){1,20}$",
-            "description": "Project Reference Number"
-          },
-          "PORefr": {
-            "type": "string",
-            "minLength": 1,
-            "maxLength": 16,
-            "pattern": "^([0-9A-Za-z/-]){1,16}$",
-            "description": "PO Reference Number"
-          },
-          "PORefDt": {
-            "type": "string",
-            "minLength": 10,
-            "maxLength": 10,
-            "pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
-            "description": "PO Reference date"
-          }
-        }
-      }
-    }
-  },
-  "AddlDocDtls": {
-    "type": "Array",
-    "properties": {
-      "Url": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Supporting document URL"
-      },
-      "Docs": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 1000,
-        "description": "Supporting document in Base64 Format"
-      },
-      "Info": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 1000,
-        "description": "Any additional information"
-      }
-    }
-  },
-
-  "ExpDtls": {
-    "type": "object",
-    "properties": {
-      "ShipBNo": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 20,
-        "description": "Shipping Bill No."
-      },
-      "ShipBDt": {
-        "type": "string",
-        "minLength": 10,
-        "maxLength": 10,
-        "pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
-        "description": "Shipping Bill Date"
-      },
-      "Port": {
-        "type": "string",
-        "minLength": 2,
-        "maxLength": 10,
-        "pattern": "^[0-9A-Za-z]{2,10}$",
-        "description": "Port Code. Refer the master"
-      },
-      "RefClm": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 1,
-        "description": "Claiming Refund. Y/N"
-      },
-      "ForCur": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 16,
-        "description": "Additional Currency Code. Refer the master"
-      },
-      "CntCode": {
-        "type": "string",
-        "minLength": 2,
-        "maxLength": 2,
-        "description": "Country Code. Refer the master"
-      },
-      "ExpDuty": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 999999999999.99,
-        "description": "Export Duty"
-      }
-    }
-  },
-  "EwbDtls": {
-    "type": "object",
-    "properties": {
-      "TransId": {
-        "type": "string",
-        "minLength": 15,
-        "maxLength": 15,
-        "description": "Transporter GSTIN"
-      },
-      "TransName": {
-        "type": "string",
-        "minLength": 3,
-        "maxLength": 100,
-        "description": "Transporter Name"
-      },
-      "TransMode": {
-        "type": "string",
-        "maxLength": 1,
-        "minLength": 1,
-        "enum": ["1", "2", "3", "4"],
-        "description": "Mode of Transport"
-      },
-      "Distance": {
-        "type": "number",
-        "minimum": 1,
-        "maximum": 9999,
-        "description": "Distance"
-      },
-      "TransDocNo": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 15,
-        "pattern": "^([0-9A-Z/-]){1,15}$",
-        "description": "Tranport Document Number",
-        "validationMsg": "Transport Receipt No is invalid"
-      },
-      "TransDocDt": {
-        "type": "string",
-        "minLength": 10,
-        "maxLength": 10,
-        "pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
-        "description": "Transport Document Date"
-      },
-      "VehNo": {
-        "type": "string",
-        "minLength": 4,
-        "maxLength": 20,
-        "description": "Vehicle Number"
-      },
-      "VehType": {
-        "type": "string",
-        "minLength": 1,
-        "maxLength": 1,
-        "enum": ["O", "R"],
-        "description": "Vehicle Type"
-      }
-    },
-    "required": ["Distance"]
-  },
-  "required": [
-    "Version",
-    "TranDtls",
-    "DocDtls",
-    "SellerDtls",
-    "BuyerDtls",
-    "ItemList",
-    "ValDtls"
-  ]
-}
diff --git a/erpnext/regional/india/e_invoice/einvoice.js b/erpnext/regional/india/e_invoice/einvoice.js
deleted file mode 100644
index 348f0c6..0000000
--- a/erpnext/regional/india/e_invoice/einvoice.js
+++ /dev/null
@@ -1,292 +0,0 @@
-erpnext.setup_einvoice_actions = (doctype) => {
-	frappe.ui.form.on(doctype, {
-		async refresh(frm) {
-			if (frm.doc.docstatus == 2) return;
-
-			const res = await frappe.call({
-				method: 'erpnext.regional.india.e_invoice.utils.validate_eligibility',
-				args: { doc: frm.doc }
-			});
-			const invoice_eligible = res.message;
-
-			if (!invoice_eligible) return;
-
-			const { doctype, irn, irn_cancelled, ewaybill, eway_bill_cancelled, name, __unsaved } = frm.doc;
-
-			const add_custom_button = (label, action) => {
-				if (!frm.custom_buttons[label]) {
-					frm.add_custom_button(label, action, __('E Invoicing'));
-				}
-			};
-
-			if (!irn && !__unsaved) {
-				const action = () => {
-					if (frm.doc.__unsaved) {
-						frappe.throw(__('Please save the document to generate IRN.'));
-					}
-					frappe.call({
-						method: 'erpnext.regional.india.e_invoice.utils.get_einvoice',
-						args: { doctype, docname: name },
-						freeze: true,
-						callback: (res) => {
-							const einvoice = res.message;
-							show_einvoice_preview(frm, einvoice);
-						}
-					});
-				};
-
-				add_custom_button(__("Generate IRN"), action);
-			}
-
-			if (irn && !irn_cancelled && !ewaybill) {
-				const fields = [
-					{
-						"label": "Reason",
-						"fieldname": "reason",
-						"fieldtype": "Select",
-						"reqd": 1,
-						"default": "1-Duplicate",
-						"options": ["1-Duplicate", "2-Data Entry Error", "3-Order Cancelled", "4-Other"]
-					},
-					{
-						"label": "Remark",
-						"fieldname": "remark",
-						"fieldtype": "Data",
-						"reqd": 1
-					}
-				];
-				const action = () => {
-					const d = new frappe.ui.Dialog({
-						title: __("Cancel IRN"),
-						fields: fields,
-						primary_action: function() {
-							const data = d.get_values();
-							frappe.call({
-								method: 'erpnext.regional.india.e_invoice.utils.cancel_irn',
-								args: {
-									doctype,
-									docname: name,
-									irn: irn,
-									reason: data.reason.split('-')[0],
-									remark: data.remark
-								},
-								freeze: true,
-								callback: () => frm.reload_doc() || d.hide(),
-								error: () => d.hide()
-							});
-						},
-						primary_action_label: __('Submit')
-					});
-					d.show();
-				};
-				add_custom_button(__("Cancel IRN"), action);
-			}
-
-			if (irn && !irn_cancelled && !ewaybill) {
-				const action = () => {
-					const d = new frappe.ui.Dialog({
-						title: __('Generate E-Way Bill'),
-						size: "large",
-						fields: get_ewaybill_fields(frm),
-						primary_action: function() {
-							const data = d.get_values();
-							frappe.call({
-								method: 'erpnext.regional.india.e_invoice.utils.generate_eway_bill',
-								args: {
-									doctype,
-									docname: name,
-									irn,
-									...data
-								},
-								freeze: true,
-								callback: () => frm.reload_doc() || d.hide(),
-								error: () => d.hide()
-							});
-						},
-						primary_action_label: __('Submit')
-					});
-					d.show();
-				};
-
-				add_custom_button(__("Generate E-Way Bill"), action);
-			}
-
-			if (irn && ewaybill && !irn_cancelled && !eway_bill_cancelled) {
-				const action = () => {
-					let message = __('Cancellation of e-way bill is currently not supported.') + ' ';
-					message += '<br><br>';
-					message += __('You must first use the portal to cancel the e-way bill and then update the cancelled status in the ERPNext system.');
-
-					const dialog = frappe.msgprint({
-						title: __('Update E-Way Bill Cancelled Status?'),
-						message: message,
-						indicator: 'orange',
-						primary_action: {
-							action: function() {
-								frappe.call({
-									method: 'erpnext.regional.india.e_invoice.utils.cancel_eway_bill',
-									args: { doctype, docname: name },
-									freeze: true,
-									callback: () => frm.reload_doc() || dialog.hide()
-								});
-							}
-						},
-						primary_action_label: __('Yes')
-					});
-				};
-				add_custom_button(__("Cancel E-Way Bill"), action);
-			}
-		}
-	});
-};
-
-const get_ewaybill_fields = (frm) => {
-	return [
-		{
-			'fieldname': 'transporter',
-			'label': 'Transporter',
-			'fieldtype': 'Link',
-			'options': 'Supplier',
-			'default': frm.doc.transporter
-		},
-		{
-			'fieldname': 'gst_transporter_id',
-			'label': 'GST Transporter ID',
-			'fieldtype': 'Data',
-			'fetch_from': 'transporter.gst_transporter_id',
-			'default': frm.doc.gst_transporter_id
-		},
-		{
-			'fieldname': 'driver',
-			'label': 'Driver',
-			'fieldtype': 'Link',
-			'options': 'Driver',
-			'default': frm.doc.driver
-		},
-		{
-			'fieldname': 'lr_no',
-			'label': 'Transport Receipt No',
-			'fieldtype': 'Data',
-			'default': frm.doc.lr_no
-		},
-		{
-			'fieldname': 'vehicle_no',
-			'label': 'Vehicle No',
-			'fieldtype': 'Data',
-			'default': frm.doc.vehicle_no
-		},
-		{
-			'fieldname': 'distance',
-			'label': 'Distance (in km)',
-			'fieldtype': 'Float',
-			'default': frm.doc.distance
-		},
-		{
-			'fieldname': 'transporter_col_break',
-			'fieldtype': 'Column Break',
-		},
-		{
-			'fieldname': 'transporter_name',
-			'label': 'Transporter Name',
-			'fieldtype': 'Data',
-			'fetch_from': 'transporter.name',
-			'read_only': 1,
-			'default': frm.doc.transporter_name
-		},
-		{
-			'fieldname': 'mode_of_transport',
-			'label': 'Mode of Transport',
-			'fieldtype': 'Select',
-			'options': `\nRoad\nAir\nRail\nShip`,
-			'default': frm.doc.mode_of_transport
-		},
-		{
-			'fieldname': 'driver_name',
-			'label': 'Driver Name',
-			'fieldtype': 'Data',
-			'fetch_from': 'driver.full_name',
-			'read_only': 1,
-			'default': frm.doc.driver_name
-		},
-		{
-			'fieldname': 'lr_date',
-			'label': 'Transport Receipt Date',
-			'fieldtype': 'Date',
-			'default': frm.doc.lr_date
-		},
-		{
-			'fieldname': 'gst_vehicle_type',
-			'label': 'GST Vehicle Type',
-			'fieldtype': 'Select',
-			'options': `Regular\nOver Dimensional Cargo (ODC)`,
-			'depends_on': 'eval:(doc.mode_of_transport === "Road")',
-			'default': frm.doc.gst_vehicle_type
-		}
-	];
-};
-
-const request_irn_generation = (frm) => {
-	frappe.call({
-		method: 'erpnext.regional.india.e_invoice.utils.generate_irn',
-		args: { doctype: frm.doc.doctype, docname: frm.doc.name },
-		freeze: true,
-		callback: () => frm.reload_doc()
-	});
-};
-
-const get_preview_dialog = (frm, action) => {
-	const dialog = new frappe.ui.Dialog({
-		title: __("Preview"),
-		size: "large",
-		fields: [
-			{
-				"label": "Preview",
-				"fieldname": "preview_html",
-				"fieldtype": "HTML"
-			}
-		],
-		primary_action: () => action(frm) || dialog.hide(),
-		primary_action_label: __('Generate IRN')
-	});
-	return dialog;
-};
-
-const show_einvoice_preview = (frm, einvoice) => {
-	const preview_dialog = get_preview_dialog(frm, request_irn_generation);
-
-	// initialize e-invoice fields
-	einvoice["Irn"] = einvoice["AckNo"] = ''; einvoice["AckDt"] = frappe.datetime.nowdate();
-	frm.doc.signed_einvoice = JSON.stringify(einvoice);
-
-	// initialize preview wrapper
-	const $preview_wrapper = preview_dialog.get_field("preview_html").$wrapper;
-	$preview_wrapper.html(
-		`<div>
-			<div class="print-preview">
-				<div class="print-format"></div>
-			</div>
-			<div class="page-break-message text-muted text-center text-medium margin-top"></div>
-		</div>`
-	);
-
-	frappe.call({
-		method: "frappe.www.printview.get_html_and_style",
-		args: {
-			doc: frm.doc,
-			print_format: "GST E-Invoice",
-			no_letterhead: 1
-		},
-		callback: function (r) {
-			if (!r.exc) {
-				$preview_wrapper.find(".print-format").html(r.message.html);
-				const style = `
-					.print-format { box-shadow: 0px 0px 5px rgba(0,0,0,0.2); padding: 0.30in; min-height: 80vh; }
-					.print-preview { min-height: 0px; }
-					.modal-dialog { width: 720px; }`;
-
-				frappe.dom.set_style(style, "custom-print-style");
-				preview_dialog.show();
-			}
-		}
-	});
-};
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index 2d6b913..a6ab6ab 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -61,7 +61,7 @@
 
 def add_custom_roles_for_reports():
 	for report_name in ('GST Sales Register', 'GST Purchase Register',
-		'GST Itemised Sales Register', 'GST Itemised Purchase Register', 'Eway Bill', 'E-Invoice Summary'):
+		'GST Itemised Sales Register', 'GST Itemised Purchase Register', 'Eway Bill'):
 
 		if not frappe.db.get_value('Custom Role', dict(report=report_name)):
 			frappe.get_doc(dict(
@@ -100,7 +100,7 @@
 			)).insert()
 
 def add_permissions():
-	for doctype in ('GST HSN Code', 'GST Settings', 'GSTR 3B Report', 'Lower Deduction Certificate', 'E Invoice Settings'):
+	for doctype in ('GST HSN Code', 'GST Settings', 'GSTR 3B Report', 'Lower Deduction Certificate'):
 		add_permission(doctype, 'All', 0)
 		for role in ('Accounts Manager', 'Accounts User', 'System Manager'):
 			add_permission(doctype, role, 0)
@@ -116,11 +116,9 @@
 def add_print_formats():
 	frappe.reload_doc("regional", "print_format", "gst_tax_invoice")
 	frappe.reload_doc("accounts", "print_format", "gst_pos_invoice")
-	frappe.reload_doc("accounts", "print_format", "GST E-Invoice")
 
 	frappe.db.set_value("Print Format", "GST POS Invoice", "disabled", 0)
 	frappe.db.set_value("Print Format", "GST Tax Invoice", "disabled", 0)
-	frappe.db.set_value("Print Format", "GST E-Invoice", "disabled", 0)
 
 def make_property_setters(patch=False):
 	# GST rules do not allow for an invoice no. bigger than 16 characters
@@ -445,53 +443,13 @@
 			'fieldname': 'ewaybill',
 			'label': 'E-Way Bill No.',
 			'fieldtype': 'Data',
-			'depends_on': 'eval:((doc.docstatus === 1 || doc.ewaybill) && doc.eway_bill_cancelled === 0)',
+			'depends_on': 'eval:(doc.docstatus === 1)',
 			'allow_on_submit': 1,
 			'insert_after': 'tax_id',
 			'translatable': 0
 		}
 	]
 
-	si_einvoice_fields = [
-		dict(fieldname='irn', label='IRN', fieldtype='Data', read_only=1, insert_after='customer', no_copy=1, print_hide=1,
-			depends_on='eval:in_list(["Registered Regular", "SEZ", "Overseas", "Deemed Export"], doc.gst_category) && doc.irn_cancelled === 0'),
-
-		dict(fieldname='irn_cancelled', label='IRN Cancelled', fieldtype='Check', no_copy=1, print_hide=1,
-			depends_on='eval: doc.irn', allow_on_submit=1, insert_after='customer'),
-
-		dict(fieldname='eway_bill_validity', label='E-Way Bill Validity', fieldtype='Data', no_copy=1, print_hide=1,
-			depends_on='ewaybill', read_only=1, allow_on_submit=1, insert_after='ewaybill'),
-
-		dict(fieldname='eway_bill_cancelled', label='E-Way Bill Cancelled', fieldtype='Check', no_copy=1, print_hide=1,
-			depends_on='eval:(doc.eway_bill_cancelled === 1)', read_only=1, allow_on_submit=1, insert_after='customer'),
-
-		dict(fieldname='einvoice_section', label='E-Invoice Fields', fieldtype='Section Break', insert_after='gst_vehicle_type',
-			print_hide=1, hidden=1),
-
-		dict(fieldname='ack_no', label='Ack. No.', fieldtype='Data', read_only=1, hidden=1, insert_after='einvoice_section',
-			no_copy=1, print_hide=1),
-
-		dict(fieldname='ack_date', label='Ack. Date', fieldtype='Data', read_only=1, hidden=1, insert_after='ack_no', no_copy=1, print_hide=1),
-
-		dict(fieldname='irn_cancel_date', label='Cancel Date', fieldtype='Data', read_only=1, hidden=1, insert_after='ack_date',
-			no_copy=1, print_hide=1),
-
-		dict(fieldname='signed_einvoice', label='Signed E-Invoice', fieldtype='Code', options='JSON', hidden=1, insert_after='irn_cancel_date',
-			no_copy=1, print_hide=1, read_only=1),
-
-		dict(fieldname='signed_qr_code', label='Signed QRCode', fieldtype='Code', options='JSON', hidden=1, insert_after='signed_einvoice',
-			no_copy=1, print_hide=1, read_only=1),
-
-		dict(fieldname='qrcode_image', label='QRCode', fieldtype='Attach Image', hidden=1, insert_after='signed_qr_code',
-			no_copy=1, print_hide=1, read_only=1),
-
-		dict(fieldname='einvoice_status', label='E-Invoice Status', fieldtype='Select', insert_after='qrcode_image',
-			options='\nPending\nGenerated\nCancelled\nFailed', default=None, hidden=1, no_copy=1, print_hide=1, read_only=1),
-
-		dict(fieldname='failure_description', label='E-Invoice Failure Description', fieldtype='Code', options='JSON',
-			hidden=1, insert_after='einvoice_status', no_copy=1, print_hide=1, read_only=1)
-	]
-
 	custom_fields = {
 		'Address': [
 			dict(fieldname='gstin', label='Party GSTIN', fieldtype='Data',
@@ -504,7 +462,7 @@
 		'Purchase Invoice': purchase_invoice_gst_category + invoice_gst_fields + purchase_invoice_itc_fields + purchase_invoice_gst_fields,
 		'Purchase Order': purchase_invoice_gst_fields,
 		'Purchase Receipt': purchase_invoice_gst_fields,
-		'Sales Invoice': sales_invoice_gst_category + invoice_gst_fields + sales_invoice_shipping_fields + sales_invoice_gst_fields + si_ewaybill_fields + si_einvoice_fields,
+		'Sales Invoice': sales_invoice_gst_category + invoice_gst_fields + sales_invoice_shipping_fields + sales_invoice_gst_fields + si_ewaybill_fields,
 		'Delivery Note': sales_invoice_gst_fields + ewaybill_fields + sales_invoice_shipping_fields + delivery_note_gst_category,
 		'Journal Entry': journal_entry_fields,
 		'Sales Order': sales_invoice_gst_fields,
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index 949733e..ce5aa10 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -475,7 +475,7 @@
 		ewaybills.append(data)
 
 	data = {
-		'version': '1.0.1118',
+		'version': '1.0.0421',
 		'billLists': ewaybills
 	}
 
@@ -871,3 +871,20 @@
 				'tax_category': tax.tax_category,
 				'valid_from': tax.valid_from
 			})
+
+def delete_gst_settings_for_company(doc, method):
+	if doc.country != 'India':
+		return
+
+	gst_settings = frappe.get_doc("GST Settings")
+	records_to_delete = []
+
+	for d in reversed(gst_settings.get('gst_accounts')):
+		if d.company == doc.name:
+			records_to_delete.append(d)
+
+	for d in records_to_delete:
+		gst_settings.remove(d)
+
+	gst_settings.save()
+
diff --git a/erpnext/regional/italy/utils.py b/erpnext/regional/italy/utils.py
index ba1aeaf..56f609e 100644
--- a/erpnext/regional/italy/utils.py
+++ b/erpnext/regional/italy/utils.py
@@ -6,9 +6,8 @@
 from frappe.utils import flt, cstr
 from erpnext.controllers.taxes_and_totals import get_itemised_tax
 from frappe import _
-from frappe.core.doctype.file.file import remove_file
+from frappe.utils.file_manager import remove_file
 from six import string_types
-from frappe.desk.form.load import get_attachments
 from erpnext.regional.italy import state_codes
 
 
diff --git a/erpnext/regional/report/e_invoice_summary/__init__.py b/erpnext/regional/report/e_invoice_summary/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/regional/report/e_invoice_summary/__init__.py
+++ /dev/null
diff --git a/erpnext/regional/report/e_invoice_summary/e_invoice_summary.js b/erpnext/regional/report/e_invoice_summary/e_invoice_summary.js
deleted file mode 100644
index 4713217..0000000
--- a/erpnext/regional/report/e_invoice_summary/e_invoice_summary.js
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-/* eslint-disable */
-
-frappe.query_reports["E-Invoice Summary"] = {
-	"filters": [
-		{
-			"fieldtype": "Link",
-			"options": "Company",
-			"reqd": 1,
-			"fieldname": "company",
-			"label": __("Company"),
-			"default": frappe.defaults.get_user_default("Company"),
-		},
-		{
-			"fieldtype": "Link",
-			"options": "Customer",
-			"fieldname": "customer",
-			"label": __("Customer")
-		},
-		{
-			"fieldtype": "Date",
-			"reqd": 1,
-			"fieldname": "from_date",
-			"label": __("From Date"),
-			"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
-		},
-		{
-			"fieldtype": "Date",
-			"reqd": 1,
-			"fieldname": "to_date",
-			"label": __("To Date"),
-			"default": frappe.datetime.get_today(),
-		},
-		{
-			"fieldtype": "Select",
-			"fieldname": "status",
-			"label": __("Status"),
-			"options": "\nPending\nGenerated\nCancelled\nFailed"
-		}
-	],
-
-	"formatter": function (value, row, column, data, default_formatter) {
-		value = default_formatter(value, row, column, data);
-
-		if (column.fieldname == "einvoice_status" && value) {
-			if (value == 'Pending') value = `<span class="bold" style="color: var(--text-on-orange)">${value}</span>`;
-			else if (value == 'Generated') value = `<span class="bold" style="color: var(--text-on-green)">${value}</span>`;
-			else if (value == 'Cancelled') value = `<span class="bold" style="color: var(--text-on-red)">${value}</span>`;
-			else if (value == 'Failed') value = `<span class="bold"  style="color: var(--text-on-red)">${value}</span>`;
-		}
-
-		return value;
-	}
-};
diff --git a/erpnext/regional/report/e_invoice_summary/e_invoice_summary.json b/erpnext/regional/report/e_invoice_summary/e_invoice_summary.json
deleted file mode 100644
index d0000ad..0000000
--- a/erpnext/regional/report/e_invoice_summary/e_invoice_summary.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "add_total_row": 0,
- "columns": [],
- "creation": "2021-03-12 11:23:37.312294",
- "disable_prepared_report": 0,
- "disabled": 0,
- "docstatus": 0,
- "doctype": "Report",
- "filters": [],
- "idx": 0,
- "is_standard": "Yes",
- "json": "{}",
- "letter_head": "Logo",
- "modified": "2021-03-13 12:36:48.689413",
- "modified_by": "Administrator",
- "module": "Regional",
- "name": "E-Invoice Summary",
- "owner": "Administrator",
- "prepared_report": 0,
- "ref_doctype": "Sales Invoice",
- "report_name": "E-Invoice Summary",
- "report_type": "Script Report",
- "roles": [
-  {
-   "role": "Administrator"
-  }
- ]
-}
\ No newline at end of file
diff --git a/erpnext/regional/report/e_invoice_summary/e_invoice_summary.py b/erpnext/regional/report/e_invoice_summary/e_invoice_summary.py
deleted file mode 100644
index 66ffcea..0000000
--- a/erpnext/regional/report/e_invoice_summary/e_invoice_summary.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# 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):
-	validate_filters(filters)
-
-	columns = get_columns()
-	data = get_data(filters)
-
-	return columns, data
-
-def validate_filters(filters={}):
-	filters = frappe._dict(filters)
-
-	if not filters.company:
-		frappe.throw(_('{} is mandatory for generating E-Invoice Summary Report').format(_('Company')), title=_('Invalid Filter'))
-	if filters.company:
-		# validate if company has e-invoicing enabled
-		pass
-	if not filters.from_date or not filters.to_date:
-		frappe.throw(_('From Date & To Date is mandatory for generating E-Invoice Summary Report'), title=_('Invalid Filter'))
-	if filters.from_date > filters.to_date:
-		frappe.throw(_('From Date must be before To Date'), title=_('Invalid Filter'))
-
-def get_data(filters={}):
-	query_filters = {
-		'posting_date': ['between', [filters.from_date, filters.to_date]],
-		'einvoice_status': ['is', 'set'],
-		'company': filters.company
-	}
-	if filters.customer:
-		query_filters['customer'] = filters.customer
-	if filters.status:
-		query_filters['einvoice_status'] = filters.status
-
-	data = frappe.get_all(
-		'Sales Invoice',
-		filters=query_filters,
-		fields=[d.get('fieldname') for d in get_columns()]
-	)
-
-	return data
-
-def get_columns():
-	return [
-		{
-			"fieldtype": "Date",
-			"fieldname": "posting_date",
-			"label": _("Posting Date"),
-			"width": 0
-		},
-		{
-			"fieldtype": "Link",
-			"fieldname": "name",
-			"label": _("Sales Invoice"),
-			"options": "Sales Invoice",
-			"width": 140
-		},
-		{
-			"fieldtype": "Data",
-			"fieldname": "einvoice_status",
-			"label": _("Status"),
-			"width": 100
-		},
-		{
-			"fieldtype": "Link",
-			"fieldname": "customer",
-			"options": "Customer",
-			"label": _("Customer")
-		},
-		{
-			"fieldtype": "Check",
-			"fieldname": "is_return",
-			"label": _("Is Return"),
-			"width": 85
-		},
-		{
-			"fieldtype": "Data",
-			"fieldname": "ack_no",
-			"label": "Ack. No.",
-			"width": 145
-		},
-		{
-			"fieldtype": "Data",
-			"fieldname": "ack_date",
-			"label": "Ack. Date",
-			"width": 165
-		},
-		{
-			"fieldtype": "Data",
-			"fieldname": "irn",
-			"label": _("IRN No."),
-			"width": 250
-		},
-		{
-			"fieldtype": "Currency",
-			"options": "Company:company:default_currency",
-			"fieldname": "base_grand_total",
-			"label": _("Grand Total"),
-			"width": 120
-		}
-	]
diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json
index d31db82..38ea5c8 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.json
+++ b/erpnext/selling/doctype/sales_order/sales_order.json
@@ -571,7 +571,8 @@
    "fieldtype": "Data",
    "hide_days": 1,
    "hide_seconds": 1,
-   "label": "Scan Barcode"
+   "label": "Scan Barcode",
+   "options": "Barcode"
   },
   {
    "allow_bulk_edit": 1,
@@ -1510,7 +1511,7 @@
  "idx": 105,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-07-08 21:37:44.177493",
+ "modified": "2021-08-17 20:15:26.531553",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Sales Order",
diff --git a/erpnext/selling/report/sales_partner_target_variance_based_on_item_group/item_group_wise_sales_target_variance.py b/erpnext/selling/report/sales_partner_target_variance_based_on_item_group/item_group_wise_sales_target_variance.py
index 89cfa16..24ca666 100644
--- a/erpnext/selling/report/sales_partner_target_variance_based_on_item_group/item_group_wise_sales_target_variance.py
+++ b/erpnext/selling/report/sales_partner_target_variance_based_on_item_group/item_group_wise_sales_target_variance.py
@@ -44,6 +44,18 @@
 		if d.item_group not in item_groups:
 			item_groups.append(d.item_group)
 
+	if item_groups:
+		child_items = []
+		for item_group in item_groups:
+			if frappe.db.get_value("Item Group", {"name":item_group}, "is_group"):
+				for child_item_group in frappe.get_all("Item Group", {"parent_item_group":item_group}):
+					if child_item_group['name'] not in child_items:
+						child_items.append(child_item_group['name'])
+
+		for item in child_items:
+			if item not in item_groups:
+				item_groups.append(item)
+
 	date_field = ("transaction_date"
 		if filters.get('doctype') == "Sales Order" else "posting_date")
 
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index 22bf3fc..2de57c8 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -394,6 +394,10 @@
 	}
 
 	_set_batch_number(doc) {
+		if (doc.batch_no) {
+			return
+		}
+
 		let args = {'item_code': doc.item_code, 'warehouse': doc.warehouse, 'qty': flt(doc.qty) * flt(doc.conversion_factor)};
 		if (doc.has_serial_no && doc.serial_no) {
 			args['serial_no'] = doc.serial_no
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 54c6753..45d5ce0 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -393,6 +393,10 @@
 		frappe.db.sql("delete from `tabPurchase Taxes and Charges Template` where company=%s", self.name)
 		frappe.db.sql("delete from `tabItem Tax Template` where company=%s", self.name)
 
+		# delete Process Deferred Accounts if no GL Entry found
+		if not frappe.db.get_value('GL Entry', {'company': self.name}):
+			frappe.db.sql("delete from `tabProcess Deferred Accounting` where company=%s", self.name)
+
 @frappe.whitelist()
 def enqueue_replace_abbr(company, old, new):
 	kwargs = dict(queue="long", company=company, old=old, new=new)
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index 56afe95..e9f4bd5 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -308,7 +308,7 @@
 	party = get_party()
 
 	party.customer_name = company_name or fullname
-	party.customer_type == "Company" if company_name else "Individual"
+	party.customer_type = "Company" if company_name else "Individual"
 
 	contact_name = frappe.db.get_value("Contact", {"email_id": frappe.session.user})
 	contact = frappe.get_doc("Contact", contact_name)
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
index 2a49722..efed196 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
@@ -6,7 +6,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe import _, msgprint
-from frappe.utils import comma_and
+from frappe.utils import flt
 from frappe.model.document import Document
 from frappe.utils import get_datetime, get_datetime_str, now_datetime
 
@@ -18,46 +18,35 @@
 
 	def validate(self):
 		if self.enabled:
-			self.validate_exchange_rates_exist()
+			self.validate_price_list_exchange_rate()
 
-	def validate_exchange_rates_exist(self):
-		"""check if exchange rates exist for all Price List currencies (to company's currency)"""
-		company_currency = frappe.get_cached_value('Company',  self.company,  "default_currency")
+	def validate_price_list_exchange_rate(self):
+		"Check if exchange rate exists for Price List currency (to Company's currency)."
+		from erpnext.setup.utils import get_exchange_rate
+
+		if not self.enabled or not self.company or not self.price_list:
+			return # this function is also called from hooks, check values again
+
+		company_currency = frappe.get_cached_value("Company", self.company, "default_currency")
+		price_list_currency = frappe.db.get_value("Price List", self.price_list, "currency")
+
 		if not company_currency:
-			msgprint(_("Please specify currency in Company") + ": " + self.company,
-				raise_exception=ShoppingCartSetupError)
+			msg = f"Please specify currency in Company {self.company}"
+			frappe.throw(_(msg), title=_("Missing Currency"), exc=ShoppingCartSetupError)
 
-		price_list_currency_map = frappe.db.get_values("Price List",
-			[self.price_list], "currency")
+		if not price_list_currency:
+			msg = f"Please specify currency in Price List {frappe.bold(self.price_list)}"
+			frappe.throw(_(msg), title=_("Missing Currency"), exc=ShoppingCartSetupError)
 
-		price_list_currency_map = dict(price_list_currency_map)
+		if price_list_currency != company_currency:
+			from_currency, to_currency = price_list_currency, company_currency
 
-		# check if all price lists have a currency
-		for price_list, currency in price_list_currency_map.items():
-			if not currency:
-				frappe.throw(_("Currency is required for Price List {0}").format(price_list))
+			# Get exchange rate checks Currency Exchange Records too
+			exchange_rate = get_exchange_rate(from_currency, to_currency, args="for_selling")
 
-		expected_to_exist = [currency + "-" + company_currency
-			for currency in price_list_currency_map.values()
-			if currency != company_currency]
-
-		# manqala 20/09/2016: set up selection parameters for query from tabCurrency Exchange
-		from_currency = [currency for currency in price_list_currency_map.values() if currency != company_currency]
-		to_currency = company_currency
-		# manqala end
-
-		if expected_to_exist:
-			# manqala 20/09/2016: modify query so that it uses date in the selection from Currency Exchange.
-			# exchange rates defined with date less than the date on which this document is being saved will be selected
-			exists = frappe.db.sql_list("""select CONCAT(from_currency,'-',to_currency) from `tabCurrency Exchange`
-				where from_currency in (%s) and to_currency = "%s" and date <= curdate()""" % (", ".join(["%s"]*len(from_currency)), to_currency), tuple(from_currency))
-			# manqala end
-
-			missing = list(set(expected_to_exist).difference(exists))
-
-			if missing:
-				msgprint(_("Missing Currency Exchange Rates for {0}").format(comma_and(missing)),
-					raise_exception=ShoppingCartSetupError)
+			if not flt(exchange_rate):
+				msg = f"Missing Currency Exchange Rates for {from_currency}-{to_currency}"
+				frappe.throw(_(msg), title=_("Missing"), exc=ShoppingCartSetupError)
 
 	def validate_tax_rule(self):
 		if not frappe.db.get_value("Tax Rule", {"use_for_shopping_cart" : 1}, "name"):
@@ -71,7 +60,7 @@
 	def get_shipping_rules(self, shipping_territory):
 		return self.get_name_from_territory(shipping_territory, "shipping_rules", "shipping_rule")
 
-def validate_cart_settings(doc, method):
+def validate_cart_settings(doc=None, method=None):
 	frappe.get_doc("Shopping Cart Settings", "Shopping Cart Settings").run_method("validate")
 
 def get_shopping_cart_settings():
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py b/erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py
index 008751e..9965e1a 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py
@@ -16,17 +16,25 @@
 		return frappe.get_doc({"doctype": "Shopping Cart Settings",
 			"company": "_Test Company"})
 
-	def test_exchange_rate_exists(self):
-		frappe.db.sql("""delete from `tabCurrency Exchange`""")
+	# NOTE: Exchangrate API has all enabled currencies that ERPNext supports.
+	# We aren't checking just currency exchange record anymore
+	# while validating price list currency exchange rate to that of company.
+	# The API is being used to fetch the rate which again almost always
+	# gives back a valid value (for valid currencies).
+	# This makes the test obsolete.
+	# Commenting because im not sure if there's a better test we can write
 
-		cart_settings = self.get_cart_settings()
-		cart_settings.price_list = "_Test Price List Rest of the World"
-		self.assertRaises(ShoppingCartSetupError, cart_settings.validate_exchange_rates_exist)
+	# def test_exchange_rate_exists(self):
+	# 	frappe.db.sql("""delete from `tabCurrency Exchange`""")
 
-		from erpnext.setup.doctype.currency_exchange.test_currency_exchange import test_records as \
-			currency_exchange_records
-		frappe.get_doc(currency_exchange_records[0]).insert()
-		cart_settings.validate_exchange_rates_exist()
+	# 	cart_settings = self.get_cart_settings()
+	# 	cart_settings.price_list = "_Test Price List Rest of the World"
+	# 	self.assertRaises(ShoppingCartSetupError, cart_settings.validate_price_list_exchange_rate)
+
+	# 	from erpnext.setup.doctype.currency_exchange.test_currency_exchange import test_records as \
+	# 		currency_exchange_records
+	# 	frappe.get_doc(currency_exchange_records[0]).insert()
+	# 	cart_settings.validate_price_list_exchange_rate()
 
 	def test_tax_rule_validation(self):
 		frappe.db.sql("update `tabTax Rule` set use_for_shopping_cart = 0")
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index dbfeb4a..9581896 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -515,7 +515,8 @@
   {
    "fieldname": "scan_barcode",
    "fieldtype": "Data",
-   "label": "Scan Barcode"
+   "label": "Scan Barcode",
+   "options": "Barcode"
   },
   {
    "allow_bulk_edit": 1,
@@ -1305,7 +1306,7 @@
  "idx": 146,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-07-08 21:37:20.802652",
+ "modified": "2021-08-17 20:15:50.574966",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Delivery Note",
diff --git a/erpnext/stock/doctype/material_request/material_request.json b/erpnext/stock/doctype/material_request/material_request.json
index 4e2d9e6..cb46a6c 100644
--- a/erpnext/stock/doctype/material_request/material_request.json
+++ b/erpnext/stock/doctype/material_request/material_request.json
@@ -133,7 +133,8 @@
   {
    "fieldname": "scan_barcode",
    "fieldtype": "Data",
-   "label": "Scan Barcode"
+   "label": "Scan Barcode",
+   "options": "Barcode"
   },
   {
    "allow_bulk_edit": 1,
@@ -181,7 +182,7 @@
    "no_copy": 1,
    "oldfieldname": "status",
    "oldfieldtype": "Select",
-   "options": "\nDraft\nSubmitted\nStopped\nCancelled\nPending\nPartially Ordered\nPartially Received\nOrdered\nIssued\nTransferred\nReceived",
+   "options": "\nDraft\nSubmitted\nStopped\nCancelled\nPending\nPartially Ordered\nOrdered\nIssued\nTransferred\nReceived",
    "print_hide": 1,
    "print_width": "100px",
    "read_only": 1,
@@ -314,7 +315,7 @@
  "idx": 70,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-03-31 23:52:55.392512",
+ "modified": "2021-08-17 20:16:12.737743",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Material Request",
diff --git a/erpnext/stock/doctype/price_list/price_list.py b/erpnext/stock/doctype/price_list/price_list.py
index 10abde1..002d3d8 100644
--- a/erpnext/stock/doctype/price_list/price_list.py
+++ b/erpnext/stock/doctype/price_list/price_list.py
@@ -13,6 +13,9 @@
 		if not cint(self.buying) and not cint(self.selling):
 			throw(_("Price List must be applicable for Buying or Selling"))
 
+		if not self.is_new():
+			self.check_impact_on_shopping_cart()
+
 	def on_update(self):
 		self.set_default_if_missing()
 		self.update_item_price()
@@ -32,6 +35,17 @@
 			buying=%s, selling=%s, modified=NOW() where price_list=%s""",
 			(self.currency, cint(self.buying), cint(self.selling), self.name))
 
+	def check_impact_on_shopping_cart(self):
+		"Check if Price List currency change impacts Shopping Cart."
+		from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings import validate_cart_settings
+
+		doc_before_save = self.get_doc_before_save()
+		currency_changed = self.currency != doc_before_save.currency
+		affects_cart = self.name == frappe.get_cached_value("Shopping Cart Settings", None, "price_list")
+
+		if currency_changed and affects_cart:
+			validate_cart_settings()
+
 	def on_trash(self):
 		self.delete_price_list_details_key()
 
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
index 44fb736..1a59734 100755
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
@@ -1098,7 +1098,8 @@
   {
    "fieldname": "scan_barcode",
    "fieldtype": "Data",
-   "label": "Scan Barcode"
+   "label": "Scan Barcode",
+   "options": "Barcode"
   },
   {
    "fieldname": "billing_address",
@@ -1148,7 +1149,7 @@
  "idx": 261,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-05-25 00:15:12.239017",
+ "modified": "2021-08-17 20:16:40.849885",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt",
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.json b/erpnext/stock/doctype/stock_entry/stock_entry.json
index 523d332..2f37778 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.json
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.json
@@ -84,8 +84,6 @@
    "oldfieldtype": "Section Break"
   },
   {
-   "allow_on_submit": 1,
-   "default": "{purpose}",
    "fieldname": "title",
    "fieldtype": "Data",
    "hidden": 1,
@@ -355,6 +353,7 @@
   },
   {
    "fieldname": "scan_barcode",
+   "options": "Barcode",
    "fieldtype": "Data",
    "label": "Scan Barcode"
   },
@@ -629,7 +628,7 @@
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-05-26 17:07:58.015737",
+ "modified": "2021-08-20 19:19:31.514846",
  "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 7b31d2f..0b4592c 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -58,6 +58,7 @@
 
 		self.validate_posting_time()
 		self.validate_purpose()
+		self.set_title()
 		self.validate_item()
 		self.validate_customer_provided_item()
 		self.validate_qty()
@@ -317,9 +318,6 @@
 				d.s_warehouse = self.from_warehouse
 				d.t_warehouse = self.to_warehouse
 
-			if not (d.s_warehouse or d.t_warehouse):
-				frappe.throw(_("Atleast one warehouse is mandatory"))
-
 			if self.purpose in source_mandatory and not d.s_warehouse:
 				if self.from_warehouse:
 					d.s_warehouse = self.from_warehouse
@@ -332,6 +330,7 @@
 				else:
 					frappe.throw(_("Target warehouse is mandatory for row {0}").format(d.idx))
 
+
 			if self.purpose == "Manufacture":
 				if validate_for_manufacture:
 					if d.is_finished_item or d.is_scrap_item:
@@ -346,6 +345,9 @@
 			if cstr(d.s_warehouse) == cstr(d.t_warehouse) and not self.purpose == "Material Transfer for Manufacture":
 				frappe.throw(_("Source and target warehouse cannot be same for row {0}").format(d.idx))
 
+			if not (d.s_warehouse or d.t_warehouse):
+				frappe.throw(_("Atleast one warehouse is mandatory"))
+
 	def validate_work_order(self):
 		if self.purpose in ("Manufacture", "Material Transfer for Manufacture", "Material Consumption for Manufacture"):
 			# check if work order is entered
@@ -1607,6 +1609,14 @@
 
 		return sorted(list(set(get_serial_nos(self.pro_doc.serial_no)) - set(used_serial_nos)))
 
+	def set_title(self):
+		if frappe.flags.in_import and self.title:
+			# Allow updating title during data import/update
+			return
+
+		self.title = self.purpose
+
+
 @frappe.whitelist()
 def move_sample_to_retention_warehouse(company, items):
 	if isinstance(items, string_types):
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index a0fbcec..c72073c 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -278,6 +278,10 @@
 		else:
 			args.uom = item.stock_uom
 
+	if (args.get("batch_no") and
+		item.name != frappe.get_cached_value('Batch', args.get("batch_no"), 'item')):
+		args['batch_no'] = ''
+
 	out = frappe._dict({
 		"item_code": item.name,
 		"item_name": item.item_name,
diff --git a/erpnext/stock/report/stock_analytics/stock_analytics.js b/erpnext/stock/report/stock_analytics/stock_analytics.js
index 6b384e2..78afe6d 100644
--- a/erpnext/stock/report/stock_analytics/stock_analytics.js
+++ b/erpnext/stock/report/stock_analytics/stock_analytics.js
@@ -37,11 +37,25 @@
 			default: "",
 		},
 		{
+			fieldname: "company",
+			label: __("Company"),
+			fieldtype: "Link",
+			options: "Company",
+			default: frappe.defaults.get_user_default("Company"),
+			reqd: 1,
+		},
+		{
 			fieldname: "warehouse",
 			label: __("Warehouse"),
 			fieldtype: "Link",
-			options:"Warehouse",
+			options: "Warehouse",
 			default: "",
+			get_query: function() {
+				const company = frappe.query_report.get_filter_value('company');
+				return {
+					filters: { 'company': company }
+				}
+			}
 		},
 		{
 			fieldname: "from_date",
diff --git a/erpnext/stock/report/stock_analytics/stock_analytics.py b/erpnext/stock/report/stock_analytics/stock_analytics.py
index d62abed..a1e1e7f 100644
--- a/erpnext/stock/report/stock_analytics/stock_analytics.py
+++ b/erpnext/stock/report/stock_analytics/stock_analytics.py
@@ -1,14 +1,15 @@
 # Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
 # For license information, please see license.txt
+import datetime
 
-from __future__ import unicode_literals
 import frappe
 from frappe import _, scrub
-from frappe.utils import getdate, flt
+from frappe.utils import getdate, get_quarter_start, get_first_day_of_week
+from frappe.utils import get_first_day as get_first_day_of_month
+
 from erpnext.stock.report.stock_balance.stock_balance import (get_items, get_stock_ledger_entries, get_item_details)
 from erpnext.accounts.utils import get_fiscal_year
 from erpnext.stock.utils import is_reposting_item_valuation_in_progress
-from six import iteritems
 
 def execute(filters=None):
 	is_reposting_item_valuation_in_progress()
@@ -71,7 +72,8 @@
 
 def get_period_date_ranges(filters):
 		from dateutil.relativedelta import relativedelta
-		from_date, to_date = getdate(filters.from_date), getdate(filters.to_date)
+		from_date = round_down_to_nearest_frequency(filters.from_date, filters.range)
+		to_date = getdate(filters.to_date)
 
 		increment = {
 			"Monthly": 1,
@@ -97,6 +99,31 @@
 
 		return periodic_daterange
 
+
+def round_down_to_nearest_frequency(date: str, frequency: str) -> datetime.datetime:
+	"""Rounds down the date to nearest frequency unit.
+	example:
+
+	>>> round_down_to_nearest_frequency("2021-02-21", "Monthly")
+	datetime.datetime(2021, 2, 1)
+
+	>>> round_down_to_nearest_frequency("2021-08-21", "Yearly")
+	datetime.datetime(2021, 1, 1)
+	"""
+
+	def _get_first_day_of_fiscal_year(date):
+		fiscal_year = get_fiscal_year(date)
+		return fiscal_year and fiscal_year[1] or date
+
+	round_down_function = {
+		"Monthly": get_first_day_of_month,
+		"Quarterly": get_quarter_start,
+		"Weekly": get_first_day_of_week,
+		"Yearly": _get_first_day_of_fiscal_year,
+	}.get(frequency, getdate)
+	return round_down_function(date)
+
+
 def get_period(posting_date, filters):
 	months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
 
@@ -177,7 +204,7 @@
 	periodic_data = get_periodic_data(sle, filters)
 	ranges = get_period_date_ranges(filters)
 
-	for dummy, item_data in iteritems(item_details):
+	for dummy, item_data in item_details.items():
 		row = {
 			"name": item_data.name,
 			"item_name": item_data.item_name,
diff --git a/erpnext/stock/report/stock_analytics/test_stock_analytics.py b/erpnext/stock/report/stock_analytics/test_stock_analytics.py
new file mode 100644
index 0000000..00e268b
--- /dev/null
+++ b/erpnext/stock/report/stock_analytics/test_stock_analytics.py
@@ -0,0 +1,35 @@
+import datetime
+import unittest
+
+from frappe import _dict
+from erpnext.accounts.utils import get_fiscal_year
+
+from erpnext.stock.report.stock_analytics.stock_analytics import get_period_date_ranges
+
+
+class TestStockAnalyticsReport(unittest.TestCase):
+	def test_get_period_date_ranges(self):
+
+		filters = _dict(range="Monthly", from_date="2020-12-28", to_date="2021-02-06")
+
+		ranges = get_period_date_ranges(filters)
+
+		expected_ranges = [
+			[datetime.date(2020, 12, 1), datetime.date(2020, 12, 31)],
+			[datetime.date(2021, 1, 1), datetime.date(2021, 1, 31)],
+			[datetime.date(2021, 2, 1), datetime.date(2021, 2, 6)],
+		]
+
+		self.assertEqual(ranges, expected_ranges)
+
+	def test_get_period_date_ranges_yearly(self):
+
+		filters = _dict(range="Yearly", from_date="2021-01-28", to_date="2021-02-06")
+
+		ranges = get_period_date_ranges(filters)
+		first_date = get_fiscal_year("2021-01-28")[1]
+		expected_ranges = [
+			[first_date, datetime.date(2021, 2, 6)],
+		]
+
+		self.assertEqual(ranges, expected_ranges)
diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py
index 8909f21..b6923e9 100644
--- a/erpnext/stock/report/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/report/stock_ledger/stock_ledger.py
@@ -23,6 +23,7 @@
 	conversion_factors = []
 	if opening_row:
 		data.append(opening_row)
+		conversion_factors.append(0)
 
 	actual_qty = stock_value = 0
 
diff --git a/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py b/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py
index a81516e..d9c671e 100644
--- a/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py
+++ b/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py
@@ -267,11 +267,15 @@
 		)
 		creation = datetime.datetime(2019, 3, 4, 12, 0)
 		lead = make_lead(creation=creation, index=4)
-		self.assertFalse(lead.service_level_agreement)
+		applied_sla = frappe.db.get_value('Lead', lead.name, 'service_level_agreement')
+		self.assertFalse(applied_sla)
 
+		source = frappe.get_doc(doctype='Lead Source', source_name='Test Source')
+		source.insert(ignore_if_duplicate=True)
 		lead.source = "Test Source"
 		lead.save()
-		self.assertEqual(lead.service_level_agreement, lead_sla.name)
+		applied_sla = frappe.db.get_value('Lead', lead.name, 'service_level_agreement')
+		self.assertEqual(applied_sla, lead_sla.name)
 
 	def tearDown(self):
 		for d in frappe.get_all("Service Level Agreement"):