Merge pull request #27369 from Havenir/ksa-vat

feat(regional): KSA E-Invoicing and VAT Report
diff --git a/.github/helper/.flake8_strict b/.github/helper/.flake8_strict
index 4c7f5f8..a79137d 100644
--- a/.github/helper/.flake8_strict
+++ b/.github/helper/.flake8_strict
@@ -1,6 +1,8 @@
 [flake8]
 ignore =
     B007,
+    B009,
+    B010,
     B950,
     E101,
     E111,
diff --git a/.github/helper/documentation.py b/.github/helper/documentation.py
index 91983d3..378983e 100644
--- a/.github/helper/documentation.py
+++ b/.github/helper/documentation.py
@@ -24,6 +24,8 @@
 					parts = parsed_url.path.split('/')
 					if len(parts) == 5 and parts[1] == "frappe" and parts[2] in docs_repos:
 						return True
+				elif parsed_url.netloc == "docs.erpnext.com":
+					return True
 
 
 if __name__ == "__main__":
diff --git a/.github/helper/semgrep_rules/report.yml b/.github/helper/semgrep_rules/report.yml
index 7f3dd01..f2a9b16 100644
--- a/.github/helper/semgrep_rules/report.yml
+++ b/.github/helper/semgrep_rules/report.yml
@@ -19,3 +19,16 @@
   languages: [python]
   severity: ERROR
 
+- id: frappe-translated-values-in-business-logic
+  paths:
+    include:
+    - "**/report"
+  patterns:
+    - pattern-inside: |
+        {..., filters: [...], ...}
+    - pattern: |
+        {..., options: [..., __("..."), ...], ...}
+  message: |
+      Using translated values in options field will require you to translate the values while comparing in business logic. Instead of passing translated labels provide objects that contain both label and value. e.g. { label: __("Option value"), value: "Option value"}
+  languages: [javascript]
+  severity: ERROR
diff --git a/.github/workflows/server-tests.yml b/.github/workflows/server-tests.yml
index 71e9c2c..4f84b86 100644
--- a/.github/workflows/server-tests.yml
+++ b/.github/workflows/server-tests.yml
@@ -99,34 +99,10 @@
           CI_BUILD_ID: ${{ github.run_id }}
           ORCHESTRATOR_URL: http://test-orchestrator.frappe.io
 
-      - name: Upload Coverage Data
-        run: |
-          cp ~/frappe-bench/sites/.coverage ${GITHUB_WORKSPACE}
-          cd ${GITHUB_WORKSPACE}
-          pip3 install coverage==5.5
-          pip3 install coveralls==3.0.1
-          coveralls
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-          COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }}
-          COVERALLS_FLAG_NAME: run-${{ matrix.container }}
-          COVERALLS_SERVICE_NAME: ${{ github.event_name == 'pull_request' && 'github' || 'github-actions' }}
-          COVERALLS_PARALLEL: true
-
-  coveralls:
-    name: Coverage Wrap Up
-    needs: test
-    container: python:3-slim
-    runs-on: ubuntu-latest
-    steps:
-      - name: Clone
-        uses: actions/checkout@v2
-
-      - name: Coveralls Finished
-        run: |
-          cd ${GITHUB_WORKSPACE}
-          pip3 install coverage==5.5
-          pip3 install coveralls==3.0.1
-          coveralls --finish
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      - name: Upload coverage data
+        uses: codecov/codecov-action@v2
+        with:
+          name: MariaDB
+          fail_ci_if_error: true
+          files: /home/runner/frappe-bench/sites/coverage.xml
+          verbose: true
diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml
index 658892c..d765f04 100644
--- a/.github/workflows/ui-tests.yml
+++ b/.github/workflows/ui-tests.yml
@@ -104,6 +104,8 @@
 
       - name: Build Assets
         run: cd ~/frappe-bench/ && bench build
+        env:
+          CI: Yes
 
       - name: UI Tests
         run: cd ~/frappe-bench/ && bench --site test_site run-ui-tests erpnext --headless
diff --git a/.mergify.yml b/.mergify.yml
new file mode 100644
index 0000000..f3d0409
--- /dev/null
+++ b/.mergify.yml
@@ -0,0 +1,58 @@
+pull_request_rules:
+  - name: Auto-close PRs on stable branch
+    conditions:
+      - and:
+        - and:
+          - author!=surajshetty3416
+          - author!=gavindsouza
+          - author!=rohitwaghchaure
+          - author!=nabinhait
+        - or:
+          - base=version-13
+          - base=version-12
+    actions:
+      close:
+      comment:
+          message: |
+            @{{author}}, thanks for the contribution, but we do not accept pull requests on a stable branch. Please raise PR on an appropriate hotfix branch. 
+            https://github.com/frappe/erpnext/wiki/Pull-Request-Checklist#which-branch
+
+  - name: backport to version-13-hotfix
+    conditions:
+      - label="backport version-13-hotfix"
+    actions:
+      backport:
+        branches:
+          - version-13-hotfix
+        assignees:
+          - "{{ author }}"
+
+  - name: backport to version-13-pre-release
+    conditions:
+      - label="backport version-13-pre-release"
+    actions:
+      backport:
+        branches:
+          - version-13-pre-release
+        assignees:
+          - "{{ author }}"
+
+  - name: backport to version-12-hotfix
+    conditions:
+      - label="backport version-12-hotfix"
+    actions:
+      backport:
+        branches:
+          - version-12-hotfix
+        assignees:
+          - "{{ author }}"
+
+  - name: backport to version-12-pre-release
+    conditions:
+      - label="backport version-12-pre-release"
+    actions:
+      backport:
+        branches:
+          - version-12-pre-release
+        assignees:
+          - "{{ author }}"
\ No newline at end of file
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 2b3a471..b74d9a6 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -20,6 +20,9 @@
     rev: 3.9.2
     hooks:
       - id: flake8
+        additional_dependencies: [
+          'flake8-bugbear',
+        ]
         args: ['--config', '.github/helper/.flake8_strict']
         exclude: ".*setup.py$"
 
diff --git a/.snyk b/.snyk
deleted file mode 100644
index 140f3ed..0000000
--- a/.snyk
+++ /dev/null
@@ -1,8 +0,0 @@
-# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
-version: v1.14.0
-ignore: {}
-# patches apply the minimum changes required to fix a vulnerability
-patch:
-  SNYK-JS-LODASH-450202:
-    - cypress > getos > async > lodash:
-        patched: '2020-01-31T01:35:12.802Z'
diff --git a/README.md b/README.md
index c6fc251..87d7d73 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
 
 [![CI](https://github.com/frappe/erpnext/actions/workflows/server-tests.yml/badge.svg?branch=develop)](https://github.com/frappe/erpnext/actions/workflows/server-tests.yml)
 [![Open Source Helpers](https://www.codetriage.com/frappe/erpnext/badges/users.svg)](https://www.codetriage.com/frappe/erpnext)
-[![Coverage Status](https://coveralls.io/repos/github/frappe/erpnext/badge.svg?branch=develop)](https://coveralls.io/github/frappe/erpnext?branch=develop)
+[![codecov](https://codecov.io/gh/frappe/erpnext/branch/develop/graph/badge.svg?token=0TwvyUg3I5)](https://codecov.io/gh/frappe/erpnext)
 
 [https://erpnext.com](https://erpnext.com)
 
@@ -77,6 +77,12 @@
 
 ---
 
+## Learning
+
+1. [Frappe School](https://frappe.school) - Learn Frappe Framework and ERPNext from the various courses by the maintainers or from the community.
+
+---
+
 ## Logo and Trademark
 
 The brand name ERPNext and the logo are trademarks of Frappe Technologies Pvt. Ltd.
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 0000000..67bd445
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1,17 @@
+codecov:
+  require_ci_to_pass: yes
+
+coverage:
+  status:
+    project:
+      default:
+        target: auto
+        threshold: 0.5%
+
+comment:
+  layout: "diff, files"
+  require_changes: true
+  after_n_builds: 3
+
+ignore:
+  - "erpnext/demo"
diff --git a/cypress/integration/test_organizational_chart_desktop.js b/cypress/integration/test_organizational_chart_desktop.js
index 39b00d3..79e08b3 100644
--- a/cypress/integration/test_organizational_chart_desktop.js
+++ b/cypress/integration/test_organizational_chart_desktop.js
@@ -6,7 +6,7 @@
 
 	it('navigates to org chart', () => {
 		cy.visit('/app');
-		cy.awesomebar('Organizational Chart');
+		cy.visit('/app/organizational-chart');
 		cy.url().should('include', '/organizational-chart');
 
 		cy.window().its('frappe.csrf_token').then(csrf_token => {
diff --git a/cypress/integration/test_organizational_chart_mobile.js b/cypress/integration/test_organizational_chart_mobile.js
index 6e75151..161fae0 100644
--- a/cypress/integration/test_organizational_chart_mobile.js
+++ b/cypress/integration/test_organizational_chart_mobile.js
@@ -7,7 +7,7 @@
 	it('navigates to org chart', () => {
 		cy.viewport(375, 667);
 		cy.visit('/app');
-		cy.awesomebar('Organizational Chart');
+		cy.visit('/app/organizational-chart');
 		cy.url().should('include', '/organizational-chart');
 
 		cy.window().its('frappe.csrf_token').then(csrf_token => {
diff --git a/erpnext/accounts/deferred_revenue.py b/erpnext/accounts/deferred_revenue.py
index bcd0771..71957e6 100644
--- a/erpnext/accounts/deferred_revenue.py
+++ b/erpnext/accounts/deferred_revenue.py
@@ -374,12 +374,15 @@
 		try:
 			make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
 			frappe.db.commit()
-		except Exception:
-			frappe.db.rollback()
-			traceback = frappe.get_traceback()
-			frappe.log_error(message=traceback)
+		except Exception as e:
+			if frappe.flags.in_test:
+				raise e
+			else:
+				frappe.db.rollback()
+				traceback = frappe.get_traceback()
+				frappe.log_error(message=traceback)
 
-			frappe.flags.deferred_accounting_error = True
+				frappe.flags.deferred_accounting_error = True
 
 def send_mail(deferred_process):
 	title = _("Error while processing deferred accounting for {0}").format(deferred_process)
diff --git a/erpnext/accounts/doctype/account/account_tree.js b/erpnext/accounts/doctype/account/account_tree.js
index 7516134..a4b6e0b 100644
--- a/erpnext/accounts/doctype/account/account_tree.js
+++ b/erpnext/accounts/doctype/account/account_tree.js
@@ -45,6 +45,49 @@
 	],
 	root_label: "Accounts",
 	get_tree_nodes: 'erpnext.accounts.utils.get_children',
+	on_get_node: function(nodes, deep=false) {
+		if (frappe.boot.user.can_read.indexOf("GL Entry") == -1) return;
+
+		let accounts = [];
+		if (deep) {
+			// in case of `get_all_nodes`
+			accounts = nodes.reduce((acc, node) => [...acc, ...node.data], []);
+		} else {
+			accounts = nodes;
+		}
+
+		const get_balances = frappe.call({
+			method: 'erpnext.accounts.utils.get_account_balances',
+			args: {
+				accounts: accounts,
+				company: cur_tree.args.company
+			},
+		});
+
+		get_balances.then(r => {
+			if (!r.message || r.message.length == 0) return;
+
+			for (let account of r.message) {
+
+				const node = cur_tree.nodes && cur_tree.nodes[account.value];
+				if (!node || node.is_root) continue;
+
+				// show Dr if positive since balance is calculated as debit - credit else show Cr
+				const balance = account.balance_in_account_currency || account.balance;
+				const dr_or_cr = balance > 0 ? "Dr": "Cr";
+				const format = (value, currency) => format_currency(Math.abs(value), currency);
+
+				if (account.balance!==undefined) {
+					$('<span class="balance-area pull-right">'
+						+ (account.balance_in_account_currency ?
+							(format(account.balance_in_account_currency, account.account_currency) + " / ") : "")
+						+ format(account.balance, account.company_currency)
+						+ " " + dr_or_cr
+						+ '</span>').insertBefore(node.$ul);
+				}
+			}
+		});
+	},
 	add_tree_node: 'erpnext.accounts.utils.add_ac',
 	menu_items:[
 		{
@@ -122,24 +165,6 @@
 			}
 		}, "add");
 	},
-	onrender: function(node) {
-		if (frappe.boot.user.can_read.indexOf("GL Entry") !== -1) {
-
-			// show Dr if positive since balance is calculated as debit - credit else show Cr
-			let balance = node.data.balance_in_account_currency || node.data.balance;
-			let dr_or_cr = balance > 0 ? "Dr": "Cr";
-
-			if (node.data && node.data.balance!==undefined) {
-				$('<span class="balance-area pull-right">'
-					+ (node.data.balance_in_account_currency ?
-						(format_currency(Math.abs(node.data.balance_in_account_currency),
-							node.data.account_currency) + " / ") : "")
-					+ format_currency(Math.abs(node.data.balance), node.data.company_currency)
-					+ " " + dr_or_cr
-					+ '</span>').insertBefore(node.$ul);
-			}
-		}
-	},
 	toolbar: [
 		{
 			label:__("Add Child"),
diff --git a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.js b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.js
index f795dfa..d61f8a6 100644
--- a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.js
+++ b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.js
@@ -10,13 +10,17 @@
 		// make company mandatory
 		frm.set_df_property('company', 'reqd', frm.doc.company ? 0 : 1);
 		frm.set_df_property('import_file_section', 'hidden', frm.doc.company ? 0 : 1);
+
+		if (frm.doc.import_file) {
+			frappe.run_serially([
+				() => generate_tree_preview(frm),
+				() => create_import_button(frm),
+				() => frm.set_df_property('chart_preview', 'hidden', 0)
+			]);
+		}
+
 		frm.set_df_property('chart_preview', 'hidden',
 			$(frm.fields_dict['chart_tree'].wrapper).html()!="" ? 0 : 1);
-
-		// Show import button when file is successfully attached
-		if (frm.page && frm.page.show_import_button) {
-			create_import_button(frm);
-		}
 	},
 
 	download_template: function(frm) {
@@ -77,9 +81,6 @@
 		if (!frm.doc.import_file) {
 			frm.page.set_indicator("");
 			$(frm.fields_dict['chart_tree'].wrapper).empty(); // empty wrapper on removing file
-		} else {
-			generate_tree_preview(frm);
-			validate_csv_data(frm);
 		}
 	},
 
@@ -104,26 +105,9 @@
 	}
 });
 
-var validate_csv_data = function(frm) {
-	frappe.call({
-		method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.validate_accounts",
-		args: {file_name: frm.doc.import_file},
-		callback: function(r) {
-			if(r.message && r.message[0]===true) {
-				frm.page["show_import_button"] = true;
-				frm.page["total_accounts"] = r.message[1];
-				frm.trigger("refresh");
-			} else {
-				frm.page.set_indicator(__('Resolve error and upload again.'), 'orange');
-				frappe.throw(__(r.message));
-			}
-		}
-	});
-};
-
 var create_import_button = function(frm) {
 	frm.page.set_primary_action(__("Import"), function () {
-		frappe.call({
+		return frappe.call({
 			method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.import_coa",
 			args: {
 				file_name: frm.doc.import_file,
@@ -132,7 +116,7 @@
 			freeze: true,
 			freeze_message: __("Creating Accounts..."),
 			callback: function(r) {
-				if(!r.exc) {
+				if (!r.exc) {
 					clearInterval(frm.page["interval"]);
 					frm.page.set_indicator(__('Import Successful'), 'blue');
 					create_reset_button(frm);
@@ -150,12 +134,33 @@
 	}).addClass('btn btn-primary');
 };
 
+var validate_coa = function(frm) {
+	if (frm.doc.import_file) {
+		let parent = __('All Accounts');
+		return frappe.call({
+			'method': 'erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.get_coa',
+			'args': {
+				file_name: frm.doc.import_file,
+				parent: parent,
+				doctype: 'Chart of Accounts Importer',
+				file_type: frm.doc.file_type,
+				for_validate: 1
+			},
+			callback: function(r) {
+				if (r.message['show_import_button']) {
+					frm.page['show_import_button'] = Boolean(r.message['show_import_button']);
+				}
+			}
+		});
+	}
+};
+
 var generate_tree_preview = function(frm) {
 	let parent = __('All Accounts');
 	$(frm.fields_dict['chart_tree'].wrapper).empty(); // empty wrapper to load new data
 
 	// generate tree structure based on the csv data
-	new frappe.ui.Tree({
+	return new frappe.ui.Tree({
 		parent: $(frm.fields_dict['chart_tree'].wrapper),
 		label: parent,
 		expandable: true,
diff --git a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
index 61968cf..5e596f8 100644
--- a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
+++ b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
@@ -26,7 +26,18 @@
 
 class ChartofAccountsImporter(Document):
 	def validate(self):
-		validate_accounts(self.import_file)
+		if self.import_file:
+			get_coa('Chart of Accounts Importer', 'All Accounts', file_name=self.import_file, for_validate=1)
+
+def validate_columns(data):
+	if not data:
+		frappe.throw(_('No data found. Seems like you uploaded a blank file'))
+
+	no_of_columns = max([len(d) for d in data])
+
+	if no_of_columns > 7:
+		frappe.throw(_('More columns found than expected. Please compare the uploaded file with standard template'),
+			title=(_("Wrong Template")))
 
 @frappe.whitelist()
 def validate_company(company):
@@ -56,6 +67,7 @@
 	else:
 		data = generate_data_from_excel(file_doc, extension)
 
+	frappe.local.flags.ignore_root_company_validation = True
 	forest = build_forest(data)
 	create_charts(company, custom_chart=forest)
 
@@ -120,7 +132,7 @@
 	return data
 
 @frappe.whitelist()
-def get_coa(doctype, parent, is_root=False, file_name=None):
+def get_coa(doctype, parent, is_root=False, file_name=None, for_validate=0):
 	''' called by tree view (to fetch node's children) '''
 
 	file_doc, extension = get_file(file_name)
@@ -131,13 +143,21 @@
 	else:
 		data = generate_data_from_excel(file_doc, extension)
 
-	forest = build_forest(data)
-	accounts = build_tree_from_json("", chart_data=forest) # returns alist of dict in a tree render-able form
+	validate_columns(data)
+	validate_accounts(file_doc, extension)
 
-	# filter out to show data for the selected node only
-	accounts = [d for d in accounts if d['parent_account']==parent]
+	if not for_validate:
+		forest = build_forest(data)
+		accounts = build_tree_from_json("", chart_data=forest) # returns a list of dict in a tree render-able form
 
-	return accounts
+		# filter out to show data for the selected node only
+		accounts = [d for d in accounts if d['parent_account']==parent]
+
+		return accounts
+	else:
+		return {
+			'show_import_button': 1
+		}
 
 def build_forest(data):
 	'''
@@ -294,10 +314,7 @@
 
 
 @frappe.whitelist()
-def validate_accounts(file_name):
-
-	file_doc, extension = get_file(file_name)
-
+def validate_accounts(file_doc, extension):
 	if extension  == 'csv':
 		accounts = generate_data_from_csv(file_doc, as_dict=True)
 	else:
@@ -316,15 +333,10 @@
 
 	validate_root(accounts_dict)
 
-	validate_account_types(accounts_dict)
-
 	return [True, len(accounts)]
 
 def validate_root(accounts):
 	roots = [accounts[d] for d in accounts if not accounts[d].get('parent_account')]
-	if len(roots) < 4:
-		frappe.throw(_("Number of root accounts cannot be less than 4"))
-
 	error_messages = []
 
 	for account in roots:
@@ -333,9 +345,19 @@
 		elif account.get("root_type") not in get_root_types() and account.get("account_name"):
 			error_messages.append(_("Root Type for {0} must be one of the Asset, Liability, Income, Expense and Equity").format(account.get("account_name")))
 
+	validate_missing_roots(roots)
+
 	if error_messages:
 		frappe.throw("<br>".join(error_messages))
 
+def validate_missing_roots(roots):
+	root_types_added = set(d.get('root_type') for d in roots)
+
+	missing = list(set(get_root_types()) - root_types_added)
+
+	if missing:
+		frappe.throw(_("Please add Root Account for - {0}").format(' , '.join(missing)))
+
 def get_root_types():
 	return ('Asset', 'Liability', 'Expense', 'Income', 'Equity')
 
@@ -361,23 +383,6 @@
 		{'account_type': 'Stock', 'root_type': 'Asset'}
 	]
 
-
-def validate_account_types(accounts):
-	account_types_for_ledger = ["Cost of Goods Sold", "Depreciation", "Fixed Asset", "Payable", "Receivable", "Stock Adjustment"]
-	account_types = [accounts[d]["account_type"] for d in accounts if not accounts[d]['is_group'] == 1]
-
-	missing = list(set(account_types_for_ledger) - set(account_types))
-	if missing:
-		frappe.throw(_("Please identify/create Account (Ledger) for type - {0}").format(' , '.join(missing)))
-
-	account_types_for_group = ["Bank", "Cash", "Stock"]
-	# fix logic bug
-	account_groups = [accounts[d]["account_type"] for d in accounts if accounts[d]['is_group'] == 1]
-
-	missing = list(set(account_types_for_group) - set(account_groups))
-	if missing:
-		frappe.throw(_("Please identify/create Account (Group) for type - {0}").format(' , '.join(missing)))
-
 def unset_existing_data(company):
 	linked = frappe.db.sql('''select fieldname from tabDocField
 		where fieldtype="Link" and options="Account" and parent="Company"''', as_dict=True)
diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year_dashboard.py b/erpnext/accounts/doctype/fiscal_year/fiscal_year_dashboard.py
index 58480df..92e8a42 100644
--- a/erpnext/accounts/doctype/fiscal_year/fiscal_year_dashboard.py
+++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year_dashboard.py
@@ -13,7 +13,7 @@
 			},
 			{
 				'label': _('References'),
-				'items': ['Period Closing Voucher', 'Tax Withholding Category']
+				'items': ['Period Closing Voucher']
 			},
 			{
 				'label': _('Target Details'),
diff --git a/erpnext/accounts/doctype/fiscal_year_company/fiscal_year_company.json b/erpnext/accounts/doctype/fiscal_year_company/fiscal_year_company.json
index 3eb0d74..67acb26 100644
--- a/erpnext/accounts/doctype/fiscal_year_company/fiscal_year_company.json
+++ b/erpnext/accounts/doctype/fiscal_year_company/fiscal_year_company.json
@@ -1,63 +1,33 @@
 {
- "allow_copy": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "beta": 0, 
- "creation": "2014-10-02 13:35:44.155278", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "Setup", 
- "editable_grid": 1, 
+ "actions": [],
+ "creation": "2014-10-02 13:35:44.155278",
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "company"
+ ],
  "fields": [
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "company", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 1, 
-   "label": "Company", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Company", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
+   "fieldname": "company",
+   "fieldtype": "Link",
+   "ignore_user_permissions": 1,
+   "in_list_view": 1,
+   "label": "Company",
+   "options": "Company"
   }
- ], 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
-
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 1, 
- "max_attachments": 0, 
- "modified": "2016-07-11 03:28:00.505946", 
- "modified_by": "Administrator", 
- "module": "Accounts", 
- "name": "Fiscal Year Company", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [], 
- "quick_entry": 0, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_seen": 0
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2021-09-28 18:01:53.495929",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Fiscal Year Company",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.json b/erpnext/accounts/doctype/journal_entry/journal_entry.json
index b7bbb74..20678d7 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.json
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.json
@@ -13,10 +13,12 @@
   "voucher_type",
   "naming_series",
   "finance_book",
+  "tax_withholding_category",
   "column_break1",
   "from_template",
   "company",
   "posting_date",
+  "apply_tds",
   "2_add_edit_gl_entries",
   "accounts",
   "section_break99",
@@ -498,16 +500,32 @@
    "options": "Journal Entry Template",
    "print_hide": 1,
    "report_hide": 1
+  },
+  {
+   "depends_on": "eval:doc.apply_tds",
+   "fieldname": "tax_withholding_category",
+   "fieldtype": "Link",
+   "label": "Tax Withholding Category",
+   "mandatory_depends_on": "eval:doc.apply_tds",
+   "options": "Tax Withholding Category"
+  },
+  {
+   "default": "0",
+   "depends_on": "eval:['Credit Note', 'Debit Note'].includes(doc.voucher_type)",
+   "fieldname": "apply_tds",
+   "fieldtype": "Check",
+   "label": "Apply Tax Withholding Amount "
   }
  ],
  "icon": "fa fa-file-text",
  "idx": 176,
  "is_submittable": 1,
  "links": [],
- "modified": "2020-10-30 13:56:01.121995",
+ "modified": "2021-09-09 15:31:14.484029",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Journal Entry",
+ "naming_rule": "By \"Naming Series\" field",
  "owner": "Administrator",
  "permissions": [
   {
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 24368f0..e568a82 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -15,6 +15,9 @@
 from erpnext.accounts.doctype.invoice_discounting.invoice_discounting import (
 	get_party_account_based_on_invoice_discounting,
 )
+from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import (
+	get_party_tax_withholding_details,
+)
 from erpnext.accounts.party import get_party_account
 from erpnext.accounts.utils import (
 	check_if_stock_and_account_balance_synced,
@@ -57,7 +60,8 @@
 
 		self.validate_against_jv()
 		self.validate_reference_doc()
-		self.set_against_account()
+		if self.docstatus == 0:
+			self.set_against_account()
 		self.create_remarks()
 		self.set_print_format_fields()
 		self.validate_expense_claim()
@@ -66,6 +70,10 @@
 		self.set_account_and_party_balance()
 		self.validate_inter_company_accounts()
 		self.validate_stock_accounts()
+
+		if self.docstatus == 0:
+			self.apply_tax_withholding()
+
 		if not self.title:
 			self.title = self.get_title()
 
@@ -139,6 +147,72 @@
 				frappe.throw(_("Account: {0} can only be updated via Stock Transactions")
 					.format(account), StockAccountInvalidTransaction)
 
+	def apply_tax_withholding(self):
+		from erpnext.accounts.report.general_ledger.general_ledger import get_account_type_map
+
+		if not self.apply_tds or self.voucher_type not in ('Debit Note', 'Credit Note'):
+			return
+
+		parties = [d.party for d in self.get('accounts') if d.party]
+		parties = list(set(parties))
+
+		if len(parties) > 1:
+			frappe.throw(_("Cannot apply TDS against multiple parties in one entry"))
+
+		account_type_map = get_account_type_map(self.company)
+		party_type = 'supplier' if self.voucher_type == 'Credit Note' else 'customer'
+		doctype = 'Purchase Invoice' if self.voucher_type == 'Credit Note' else 'Sales Invoice'
+		debit_or_credit = 'debit_in_account_currency' if self.voucher_type == 'Credit Note' else 'credit_in_account_currency'
+		rev_debit_or_credit = 'credit_in_account_currency' if debit_or_credit == 'debit_in_account_currency' else 'debit_in_account_currency'
+
+		party_account = get_party_account(party_type.title(), parties[0], self.company)
+
+		net_total = sum(d.get(debit_or_credit) for d in self.get('accounts') if account_type_map.get(d.account)
+			not in ('Tax', 'Chargeable'))
+
+		party_amount = sum(d.get(rev_debit_or_credit) for d in self.get('accounts') if d.account == party_account)
+
+		inv = frappe._dict({
+			party_type: parties[0],
+			'doctype': doctype,
+			'company': self.company,
+			'posting_date': self.posting_date,
+			'net_total': net_total
+		})
+
+		tax_withholding_details = get_party_tax_withholding_details(inv, self.tax_withholding_category)
+
+		if not tax_withholding_details:
+			return
+
+		accounts = []
+		for d in self.get('accounts'):
+			if d.get('account') == tax_withholding_details.get("account_head"):
+				d.update({
+					'account': tax_withholding_details.get("account_head"),
+					debit_or_credit: tax_withholding_details.get('tax_amount')
+				})
+
+			accounts.append(d.get('account'))
+
+			if d.get('account') == party_account:
+				d.update({
+					rev_debit_or_credit: party_amount - tax_withholding_details.get('tax_amount')
+				})
+
+		if not accounts or tax_withholding_details.get("account_head") not in accounts:
+			self.append("accounts", {
+				'account': tax_withholding_details.get("account_head"),
+				rev_debit_or_credit: tax_withholding_details.get('tax_amount'),
+				'against_account': parties[0]
+			})
+
+		to_remove = [d for d in self.get('accounts')
+			if not d.get(rev_debit_or_credit) and d.account == tax_withholding_details.get("account_head")]
+
+		for d in to_remove:
+			self.remove(d)
+
 	def update_inter_company_jv(self):
 		if self.voucher_type == "Inter Company Journal Entry" and self.inter_company_journal_entry_reference:
 			frappe.db.set_value("Journal Entry", self.inter_company_journal_entry_reference,\
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index a530321..8037ca1 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -390,6 +390,9 @@
 						invoice_paid_amount_map[invoice_key]['discounted_amt'] = ref.total_amount * (term.discount / 100)
 
 		for key, allocated_amount in iteritems(invoice_payment_amount_map):
+			if not invoice_paid_amount_map.get(key):
+				frappe.throw(_('Payment term {0} not used in {1}').format(key[0], key[1]))
+
 			outstanding = flt(invoice_paid_amount_map.get(key, {}).get('outstanding'))
 			discounted_amt = flt(invoice_paid_amount_map.get(key, {}).get('discounted_amt'))
 
diff --git a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
index 43eb0b6..8961167 100644
--- a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
+++ b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
@@ -93,6 +93,7 @@
    "options": "Payment Term"
   },
   {
+   "depends_on": "exchange_gain_loss",
    "fieldname": "exchange_gain_loss",
    "fieldtype": "Currency",
    "label": "Exchange Gain/Loss",
@@ -103,7 +104,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-04-21 13:30:11.605388",
+ "modified": "2021-09-26 17:06:55.597389",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Entry Reference",
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
index b1f3e6f..412833b 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
@@ -52,21 +52,35 @@
 
 	refresh() {
 		this.frm.disable_save();
+		this.frm.set_df_property('invoices', 'cannot_delete_rows', true);
+		this.frm.set_df_property('payments', 'cannot_delete_rows', true);
+		this.frm.set_df_property('allocation', 'cannot_delete_rows', true);
+
+		this.frm.set_df_property('invoices', 'cannot_add_rows', true);
+		this.frm.set_df_property('payments', 'cannot_add_rows', true);
+		this.frm.set_df_property('allocation', 'cannot_add_rows', true);
+
 
 		if (this.frm.doc.receivable_payable_account) {
 			this.frm.add_custom_button(__('Get Unreconciled Entries'), () =>
 				this.frm.trigger("get_unreconciled_entries")
 			);
+			this.frm.change_custom_button_type('Get Unreconciled Entries', null, 'primary');
 		}
 		if (this.frm.doc.invoices.length && this.frm.doc.payments.length) {
 			this.frm.add_custom_button(__('Allocate'), () =>
 				this.frm.trigger("allocate")
 			);
+			this.frm.change_custom_button_type('Allocate', null, 'primary');
+			this.frm.change_custom_button_type('Get Unreconciled Entries', null, 'default');
 		}
 		if (this.frm.doc.allocation.length) {
 			this.frm.add_custom_button(__('Reconcile'), () =>
 				this.frm.trigger("reconcile")
 			);
+			this.frm.change_custom_button_type('Reconcile', null, 'primary');
+			this.frm.change_custom_button_type('Get Unreconciled Entries', null, 'default');
+			this.frm.change_custom_button_type('Allocate', null, 'default');
 		}
 	}
 
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
index 9023b36..eb0c20f 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
@@ -12,15 +12,16 @@
   "receivable_payable_account",
   "col_break1",
   "from_invoice_date",
-  "to_invoice_date",
-  "minimum_invoice_amount",
-  "maximum_invoice_amount",
-  "invoice_limit",
-  "column_break_13",
   "from_payment_date",
-  "to_payment_date",
+  "minimum_invoice_amount",
   "minimum_payment_amount",
+  "column_break_11",
+  "to_invoice_date",
+  "to_payment_date",
+  "maximum_invoice_amount",
   "maximum_payment_amount",
+  "column_break_13",
+  "invoice_limit",
   "payment_limit",
   "bank_cash_account",
   "sec_break1",
@@ -79,6 +80,7 @@
   },
   {
    "depends_on": "eval:(doc.payments).length || (doc.invoices).length",
+   "description": "If you need to reconcile particular transactions against each other, then please select accordingly. If not, all the transactions will be allocated in FIFO order.",
    "fieldname": "sec_break1",
    "fieldtype": "Section Break",
    "label": "Unreconciled Entries"
@@ -163,6 +165,7 @@
    "label": "Maximum Payment Amount"
   },
   {
+   "description": "System will fetch all the entries if limit value is zero.",
    "fieldname": "payment_limit",
    "fieldtype": "Int",
    "label": "Payment Limit"
@@ -171,13 +174,17 @@
    "fieldname": "maximum_invoice_amount",
    "fieldtype": "Currency",
    "label": "Maximum Invoice Amount"
+  },
+  {
+   "fieldname": "column_break_11",
+   "fieldtype": "Column Break"
   }
  ],
  "hide_toolbar": 1,
  "icon": "icon-resize-horizontal",
  "issingle": 1,
  "links": [],
- "modified": "2021-08-30 13:05:51.977861",
+ "modified": "2021-10-04 20:27:11.114194",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Reconciliation",
diff --git a/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json b/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json
index 3653501..6a21692 100644
--- a/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json
+++ b/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json
@@ -7,14 +7,15 @@
  "field_order": [
   "reference_type",
   "reference_name",
+  "reference_row",
   "column_break_3",
   "invoice_type",
   "invoice_number",
   "section_break_6",
   "allocated_amount",
   "unreconciled_amount",
-  "amount",
   "column_break_8",
+  "amount",
   "is_advance",
   "section_break_5",
   "difference_amount",
@@ -121,11 +122,18 @@
    "label": "Amount",
    "options": "Currency",
    "read_only": 1
+  },
+  {
+   "fieldname": "reference_row",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Reference Row",
+   "read_only": 1
   }
  ],
  "istable": 1,
  "links": [],
- "modified": "2021-08-30 10:58:42.665107",
+ "modified": "2021-10-06 11:48:59.616562",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Reconciliation Allocation",
diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
index d6e41e6..27d678b 100644
--- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
+++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
@@ -40,6 +40,7 @@
 		self.validate_change_amount()
 		self.validate_change_account()
 		self.validate_item_cost_centers()
+		self.validate_warehouse()
 		self.validate_serialised_or_batched_item()
 		self.validate_stock_availablility()
 		self.validate_return_items_qty()
diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.js b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.js
index 2f8081b..73c6290 100644
--- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.js
+++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.js
@@ -4,7 +4,7 @@
 frappe.ui.form.on('POS Invoice Merge Log', {
 	setup: function(frm) {
 		frm.set_query("pos_invoice", "pos_invoices", doc => {
-			return{
+			return {
 				filters: {
 					'docstatus': 1,
 					'customer': doc.customer,
@@ -12,5 +12,10 @@
 				}
 			}
 		});
+	},
+
+	merge_invoices_based_on: function(frm) {
+		frm.set_value('customer', '');
+		frm.set_value('customer_group', '');
 	}
 });
diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.json b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.json
index da2984f..d762087 100644
--- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.json
+++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.json
@@ -6,9 +6,11 @@
  "engine": "InnoDB",
  "field_order": [
   "posting_date",
-  "customer",
+  "merge_invoices_based_on",
   "column_break_3",
   "pos_closing_entry",
+  "customer",
+  "customer_group",
   "section_break_3",
   "pos_invoices",
   "references_section",
@@ -88,12 +90,27 @@
    "fieldtype": "Link",
    "label": "POS Closing Entry",
    "options": "POS Closing Entry"
+  },
+  {
+   "fieldname": "merge_invoices_based_on",
+   "fieldtype": "Select",
+   "label": "Merge Invoices Based On",
+   "options": "Customer\nCustomer Group",
+   "reqd": 1
+  },
+  {
+   "depends_on": "eval:doc.merge_invoices_based_on == 'Customer Group'",
+   "fieldname": "customer_group",
+   "fieldtype": "Link",
+   "label": "Customer Group",
+   "mandatory_depends_on": "eval:doc.merge_invoices_based_on == 'Customer Group'",
+   "options": "Customer Group"
   }
  ],
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2020-12-01 11:53:57.267579",
+ "modified": "2021-09-14 11:17:19.001142",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "POS Invoice Merge Log",
diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
index 0be8ca7..9dae3a7 100644
--- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
+++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
@@ -23,6 +23,9 @@
 		self.validate_pos_invoice_status()
 
 	def validate_customer(self):
+		if self.merge_invoices_based_on == 'Customer Group':
+			return
+
 		for d in self.pos_invoices:
 			if d.customer != self.customer:
 				frappe.throw(_("Row #{}: POS Invoice {} is not against customer {}").format(d.idx, d.pos_invoice, self.customer))
@@ -124,7 +127,7 @@
 				found = False
 				for i in items:
 					if (i.item_code == item.item_code and not i.serial_no and not i.batch_no and
-						i.uom == item.uom and i.net_rate == item.net_rate):
+						i.uom == item.uom and i.net_rate == item.net_rate and i.warehouse == item.warehouse):
 						found = True
 						i.qty = i.qty + item.qty
 
@@ -172,6 +175,11 @@
 		invoice.discount_amount = 0.0
 		invoice.taxes_and_charges = None
 		invoice.ignore_pricing_rule = 1
+		invoice.customer = self.customer
+
+		if self.merge_invoices_based_on == 'Customer Group':
+			invoice.flags.ignore_pos_profile = True
+			invoice.pos_profile = ''
 
 		return invoice
 
@@ -228,7 +236,7 @@
 	return pos_invoices
 
 def get_invoice_customer_map(pos_invoices):
-	# pos_invoice_customer_map = { 'Customer 1': [{}, {}, {}], 'Custoemr 2' : [{}] }
+	# pos_invoice_customer_map = { 'Customer 1': [{}, {}, {}], 'Customer 2' : [{}] }
 	pos_invoice_customer_map = {}
 	for invoice in pos_invoices:
 		customer = invoice.get('customer')
diff --git a/erpnext/accounts/doctype/pos_profile/test_pos_profile.py b/erpnext/accounts/doctype/pos_profile/test_pos_profile.py
index 83ecfb4..7c53f4a 100644
--- a/erpnext/accounts/doctype/pos_profile/test_pos_profile.py
+++ b/erpnext/accounts/doctype/pos_profile/test_pos_profile.py
@@ -33,7 +33,9 @@
 
 		frappe.db.sql("delete from `tabPOS Profile`")
 
-def get_customers_list(pos_profile={}):
+def get_customers_list(pos_profile=None):
+	if pos_profile is None:
+		pos_profile = {}
 	cond = "1=1"
 	customer_groups = []
 	if pos_profile.get('customer_groups'):
diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
index 2e2d425..23ce4e4 100644
--- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
@@ -7,10 +7,8 @@
 import unittest
 
 import frappe
-from frappe import MandatoryError
 
 from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
-from erpnext.healthcare.doctype.lab_test_template.lab_test_template import make_item_price
 from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
 from erpnext.stock.doctype.item.test_item import make_item
 from erpnext.stock.get_item_details import get_item_details
@@ -623,3 +621,12 @@
 		"Pricing Rule Item Group", "Pricing Rule Brand"]:
 
 		frappe.db.sql("delete from `tab{0}`".format(doctype))
+
+
+def make_item_price(item, price_list_name, item_price):
+	frappe.get_doc({
+		'doctype': 'Item Price',
+		'price_list': price_list_name,
+		'item_code': item,
+		'price_list_rate': item_price
+	}).insert(ignore_permissions=True, ignore_mandatory=True)
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 12b486e..0637fda 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -398,7 +398,9 @@
 				pricing_rules[0].apply_rule_on_other_items = items
 				return pricing_rules
 
-def get_qty_amount_data_for_cumulative(pr_doc, doc, items=[]):
+def get_qty_amount_data_for_cumulative(pr_doc, doc, items=None):
+	if items is None:
+		items = []
 	sum_qty, sum_amt = [0, 0]
 	doctype = doc.get('parenttype') or doc.doctype
 
diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json
index 295a3b8..a26267b 100644
--- a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json
+++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json
@@ -219,6 +219,7 @@
   },
   {
    "default": "1",
+   "description": "A customer must have primary contact email.",
    "fieldname": "primary_mandatory",
    "fieldtype": "Check",
    "label": "Send To Primary Contact"
@@ -286,10 +287,11 @@
   }
  ],
  "links": [],
- "modified": "2021-05-21 11:14:22.426672",
+ "modified": "2021-09-06 21:00:45.732505",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Process Statement Of Accounts",
+ "naming_rule": "Set by user",
  "owner": "Administrator",
  "permissions": [
   {
diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py
index 73f3038..503fd0d 100644
--- a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py
+++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py
@@ -196,7 +196,10 @@
 		primary_email = customer.get('email_id') or ''
 		billing_email = get_customer_emails(customer.name, 1, billing_and_primary=False)
 
-		if billing_email == '' or (primary_email == '' and int(primary_mandatory)):
+		if int(primary_mandatory):
+			if (primary_email == ''):
+				continue
+		elif (billing_email == '') and (primary_email == ''):
 			continue
 
 		customer_list.append({
@@ -208,10 +211,29 @@
 
 @frappe.whitelist()
 def get_customer_emails(customer_name, primary_mandatory, billing_and_primary=True):
+	""" Returns first email from Contact Email table as a Billing email
+		when Is Billing Contact checked
+		and Primary email- email with Is Primary checked """
+
 	billing_email = frappe.db.sql("""
-		SELECT c.email_id FROM `tabContact` AS c JOIN `tabDynamic Link` AS l ON c.name=l.parent
-		WHERE l.link_doctype='Customer' and l.link_name=%s and c.is_billing_contact=1
-		order by c.creation desc""", customer_name)
+		SELECT
+			email.email_id
+		FROM
+			`tabContact Email` AS email
+		JOIN
+			`tabDynamic Link` AS link
+		ON
+			email.parent=link.parent
+		JOIN
+			`tabContact` AS contact
+		ON
+			contact.name=link.parent
+		WHERE
+			link.link_doctype='Customer'
+			and link.link_name=%s
+			and contact.is_billing_contact=1
+		ORDER BY
+			contact.creation desc""", customer_name)
 
 	if len(billing_email) == 0 or (billing_email[0][0] is None):
 		if billing_and_primary:
diff --git a/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py b/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py
index d09f7dc..f5391ca 100644
--- a/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py
+++ b/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py
@@ -69,7 +69,9 @@
 			{'promotional_scheme': self.name}):
 			frappe.delete_doc('Pricing Rule', rule.name)
 
-def get_pricing_rules(doc, rules = {}):
+def get_pricing_rules(doc, rules=None):
+	if rules is None:
+		rules = {}
 	new_doc = []
 	for child_doc, fields in {'price_discount_slabs': price_discount_fields,
 		'product_discount_slabs': product_discount_fields}.items():
@@ -78,7 +80,9 @@
 
 	return new_doc
 
-def _get_pricing_rules(doc, child_doc, discount_fields, rules = {}):
+def _get_pricing_rules(doc, child_doc, discount_fields, rules=None):
+	if rules is None:
+		rules = {}
 	new_doc = []
 	args = get_args_for_pricing_rule(doc)
 	applicable_for = frappe.scrub(doc.get('applicable_for'))
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index 7822f74..55e288e 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -177,9 +177,7 @@
    "hidden": 1,
    "label": "Title",
    "no_copy": 1,
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "naming_series",
@@ -191,9 +189,7 @@
    "options": "ACC-PINV-.YYYY.-\nACC-PINV-RET-.YYYY.-",
    "print_hide": 1,
    "reqd": 1,
-   "set_only_once": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "set_only_once": 1
   },
   {
    "fieldname": "supplier",
@@ -205,9 +201,7 @@
    "options": "Supplier",
    "print_hide": 1,
    "reqd": 1,
-   "search_index": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "search_index": 1
   },
   {
    "bold": 1,
@@ -219,9 +213,7 @@
    "label": "Supplier Name",
    "oldfieldname": "supplier_name",
    "oldfieldtype": "Data",
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fetch_from": "supplier.tax_id",
@@ -229,27 +221,21 @@
    "fieldtype": "Read Only",
    "label": "Tax Id",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "due_date",
    "fieldtype": "Date",
    "label": "Due Date",
    "oldfieldname": "due_date",
-   "oldfieldtype": "Date",
-   "show_days": 1,
-   "show_seconds": 1
+   "oldfieldtype": "Date"
   },
   {
    "default": "0",
    "fieldname": "is_paid",
    "fieldtype": "Check",
    "label": "Is Paid",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "default": "0",
@@ -257,25 +243,19 @@
    "fieldtype": "Check",
    "label": "Is Return (Debit Note)",
    "no_copy": 1,
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "default": "0",
    "fieldname": "apply_tds",
    "fieldtype": "Check",
    "label": "Apply Tax Withholding Amount",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "column_break1",
    "fieldtype": "Column Break",
    "oldfieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1,
    "width": "50%"
   },
   {
@@ -285,17 +265,13 @@
    "label": "Company",
    "options": "Company",
    "print_hide": 1,
-   "remember_last_selected_value": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "remember_last_selected_value": 1
   },
   {
    "fieldname": "cost_center",
    "fieldtype": "Link",
    "label": "Cost Center",
-   "options": "Cost Center",
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "Cost Center"
   },
   {
    "default": "Today",
@@ -307,9 +283,7 @@
    "oldfieldtype": "Date",
    "print_hide": 1,
    "reqd": 1,
-   "search_index": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "search_index": 1
   },
   {
    "fieldname": "posting_time",
@@ -318,8 +292,6 @@
    "no_copy": 1,
    "print_hide": 1,
    "print_width": "100px",
-   "show_days": 1,
-   "show_seconds": 1,
    "width": "100px"
   },
   {
@@ -328,9 +300,7 @@
    "fieldname": "set_posting_time",
    "fieldtype": "Check",
    "label": "Edit Posting Date and Time",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "amended_from",
@@ -342,58 +312,44 @@
    "oldfieldtype": "Link",
    "options": "Purchase Invoice",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "collapsible": 1,
    "collapsible_depends_on": "eval:doc.on_hold",
    "fieldname": "sb_14",
    "fieldtype": "Section Break",
-   "label": "Hold Invoice",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Hold Invoice"
   },
   {
    "default": "0",
    "fieldname": "on_hold",
    "fieldtype": "Check",
-   "label": "Hold Invoice",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Hold Invoice"
   },
   {
    "depends_on": "eval:doc.on_hold",
    "description": "Once set, this invoice will be on hold till the set date",
    "fieldname": "release_date",
    "fieldtype": "Date",
-   "label": "Release Date",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Release Date"
   },
   {
    "fieldname": "cb_17",
-   "fieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Column Break"
   },
   {
    "depends_on": "eval:doc.on_hold",
    "fieldname": "hold_comment",
    "fieldtype": "Small Text",
-   "label": "Reason For Putting On Hold",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Reason For Putting On Hold"
   },
   {
    "collapsible": 1,
    "collapsible_depends_on": "bill_no",
    "fieldname": "supplier_invoice_details",
    "fieldtype": "Section Break",
-   "label": "Supplier Invoice Details",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Supplier Invoice Details"
   },
   {
    "fieldname": "bill_no",
@@ -401,15 +357,11 @@
    "label": "Supplier Invoice No",
    "oldfieldname": "bill_no",
    "oldfieldtype": "Data",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "column_break_15",
-   "fieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Column Break"
   },
   {
    "fieldname": "bill_date",
@@ -418,17 +370,13 @@
    "no_copy": 1,
    "oldfieldname": "bill_date",
    "oldfieldtype": "Date",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "depends_on": "return_against",
    "fieldname": "returns",
    "fieldtype": "Section Break",
-   "label": "Returns",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Returns"
   },
   {
    "depends_on": "return_against",
@@ -438,34 +386,26 @@
    "no_copy": 1,
    "options": "Purchase Invoice",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "collapsible": 1,
    "fieldname": "section_addresses",
    "fieldtype": "Section Break",
-   "label": "Address and Contact",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Address and Contact"
   },
   {
    "fieldname": "supplier_address",
    "fieldtype": "Link",
    "label": "Select Supplier Address",
    "options": "Address",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "address_display",
    "fieldtype": "Small Text",
    "label": "Address",
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "contact_person",
@@ -473,67 +413,51 @@
    "in_global_search": 1,
    "label": "Contact Person",
    "options": "Contact",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "contact_display",
    "fieldtype": "Small Text",
    "label": "Contact",
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "contact_mobile",
    "fieldtype": "Small Text",
    "label": "Mobile No",
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "contact_email",
    "fieldtype": "Small Text",
    "label": "Contact Email",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "col_break_address",
-   "fieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Column Break"
   },
   {
    "fieldname": "shipping_address",
    "fieldtype": "Link",
    "label": "Select Shipping Address",
    "options": "Address",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "shipping_address_display",
    "fieldtype": "Small Text",
    "label": "Shipping Address",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "collapsible": 1,
    "fieldname": "currency_and_price_list",
    "fieldtype": "Section Break",
    "label": "Currency and Price List",
-   "options": "fa fa-tag",
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "fa fa-tag"
   },
   {
    "fieldname": "currency",
@@ -542,9 +466,7 @@
    "oldfieldname": "currency",
    "oldfieldtype": "Select",
    "options": "Currency",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "conversion_rate",
@@ -553,24 +475,18 @@
    "oldfieldname": "conversion_rate",
    "oldfieldtype": "Currency",
    "precision": "9",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "column_break2",
-   "fieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Column Break"
   },
   {
    "fieldname": "buying_price_list",
    "fieldtype": "Link",
    "label": "Price List",
    "options": "Price List",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "price_list_currency",
@@ -578,18 +494,14 @@
    "label": "Price List Currency",
    "options": "Currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "plc_conversion_rate",
    "fieldtype": "Float",
    "label": "Price List Exchange Rate",
    "precision": "9",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "default": "0",
@@ -598,15 +510,11 @@
    "label": "Ignore Pricing Rule",
    "no_copy": 1,
    "permlevel": 1,
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "sec_warehouse",
-   "fieldtype": "Section Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Section Break"
   },
   {
    "depends_on": "update_stock",
@@ -615,9 +523,7 @@
    "fieldtype": "Link",
    "label": "Set Accepted Warehouse",
    "options": "Warehouse",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "depends_on": "update_stock",
@@ -627,15 +533,11 @@
    "label": "Rejected Warehouse",
    "no_copy": 1,
    "options": "Warehouse",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "col_break_warehouse",
-   "fieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Column Break"
   },
   {
    "default": "No",
@@ -643,26 +545,20 @@
    "fieldtype": "Select",
    "label": "Raw Materials Supplied",
    "options": "No\nYes",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "items_section",
    "fieldtype": "Section Break",
    "oldfieldtype": "Section Break",
-   "options": "fa fa-shopping-cart",
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "fa fa-shopping-cart"
   },
   {
    "default": "0",
    "fieldname": "update_stock",
    "fieldtype": "Check",
    "label": "Update Stock",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "scan_barcode",
@@ -678,33 +574,25 @@
    "oldfieldname": "entries",
    "oldfieldtype": "Table",
    "options": "Purchase Invoice Item",
-   "reqd": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "reqd": 1
   },
   {
    "fieldname": "pricing_rule_details",
    "fieldtype": "Section Break",
-   "label": "Pricing Rules",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Pricing Rules"
   },
   {
    "fieldname": "pricing_rules",
    "fieldtype": "Table",
    "label": "Pricing Rule Detail",
    "options": "Pricing Rule Detail",
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "collapsible_depends_on": "supplied_items",
    "fieldname": "raw_materials_supplied",
    "fieldtype": "Section Break",
-   "label": "Raw Materials Supplied",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Raw Materials Supplied"
   },
   {
    "depends_on": "update_stock",
@@ -712,23 +600,17 @@
    "fieldtype": "Table",
    "label": "Supplied Items",
    "no_copy": 1,
-   "options": "Purchase Receipt Item Supplied",
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "Purchase Receipt Item Supplied"
   },
   {
    "fieldname": "section_break_26",
-   "fieldtype": "Section Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Section Break"
   },
   {
    "fieldname": "total_qty",
    "fieldtype": "Float",
    "label": "Total Quantity",
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "base_total",
@@ -736,9 +618,7 @@
    "label": "Total (Company Currency)",
    "options": "Company:company:default_currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "base_net_total",
@@ -748,24 +628,18 @@
    "oldfieldtype": "Currency",
    "options": "Company:company:default_currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "column_break_28",
-   "fieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Column Break"
   },
   {
    "fieldname": "total",
    "fieldtype": "Currency",
    "label": "Total",
    "options": "currency",
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "net_total",
@@ -775,56 +649,42 @@
    "oldfieldtype": "Currency",
    "options": "currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "total_net_weight",
    "fieldtype": "Float",
    "label": "Total Net Weight",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "taxes_section",
    "fieldtype": "Section Break",
    "oldfieldtype": "Section Break",
-   "options": "fa fa-money",
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "fa fa-money"
   },
   {
    "fieldname": "tax_category",
    "fieldtype": "Link",
    "label": "Tax Category",
    "options": "Tax Category",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "column_break_49",
-   "fieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Column Break"
   },
   {
    "fieldname": "shipping_rule",
    "fieldtype": "Link",
    "label": "Shipping Rule",
    "options": "Shipping Rule",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "section_break_51",
-   "fieldtype": "Section Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Section Break"
   },
   {
    "fieldname": "taxes_and_charges",
@@ -833,9 +693,7 @@
    "oldfieldname": "purchase_other_charges",
    "oldfieldtype": "Link",
    "options": "Purchase Taxes and Charges Template",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "taxes",
@@ -843,17 +701,13 @@
    "label": "Purchase Taxes and Charges",
    "oldfieldname": "purchase_tax_details",
    "oldfieldtype": "Table",
-   "options": "Purchase Taxes and Charges",
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "Purchase Taxes and Charges"
   },
   {
    "collapsible": 1,
    "fieldname": "sec_tax_breakup",
    "fieldtype": "Section Break",
-   "label": "Tax Breakup",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Tax Breakup"
   },
   {
    "fieldname": "other_charges_calculation",
@@ -862,17 +716,13 @@
    "no_copy": 1,
    "oldfieldtype": "HTML",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "totals",
    "fieldtype": "Section Break",
    "oldfieldtype": "Section Break",
-   "options": "fa fa-money",
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "fa fa-money"
   },
   {
    "fieldname": "base_taxes_and_charges_added",
@@ -882,9 +732,7 @@
    "oldfieldtype": "Currency",
    "options": "Company:company:default_currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "base_taxes_and_charges_deducted",
@@ -894,9 +742,7 @@
    "oldfieldtype": "Currency",
    "options": "Company:company:default_currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "base_total_taxes_and_charges",
@@ -906,15 +752,11 @@
    "oldfieldtype": "Currency",
    "options": "Company:company:default_currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "column_break_40",
-   "fieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Column Break"
   },
   {
    "fieldname": "taxes_and_charges_added",
@@ -924,9 +766,7 @@
    "oldfieldtype": "Currency",
    "options": "currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "taxes_and_charges_deducted",
@@ -936,9 +776,7 @@
    "oldfieldtype": "Currency",
    "options": "currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "total_taxes_and_charges",
@@ -946,18 +784,14 @@
    "label": "Total Taxes and Charges",
    "options": "currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "collapsible": 1,
    "collapsible_depends_on": "discount_amount",
    "fieldname": "section_break_44",
    "fieldtype": "Section Break",
-   "label": "Additional Discount",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Additional Discount"
   },
   {
    "default": "Grand Total",
@@ -965,9 +799,7 @@
    "fieldtype": "Select",
    "label": "Apply Additional Discount On",
    "options": "\nGrand Total\nNet Total",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "base_discount_amount",
@@ -975,38 +807,28 @@
    "label": "Additional Discount Amount (Company Currency)",
    "options": "Company:company:default_currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "column_break_46",
-   "fieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Column Break"
   },
   {
    "fieldname": "additional_discount_percentage",
    "fieldtype": "Float",
    "label": "Additional Discount Percentage",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "discount_amount",
    "fieldtype": "Currency",
    "label": "Additional Discount Amount",
    "options": "currency",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "section_break_49",
-   "fieldtype": "Section Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Section Break"
   },
   {
    "fieldname": "base_grand_total",
@@ -1016,9 +838,7 @@
    "oldfieldtype": "Currency",
    "options": "Company:company:default_currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "depends_on": "eval:!doc.disable_rounded_total",
@@ -1028,9 +848,7 @@
    "no_copy": 1,
    "options": "Company:company:default_currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "depends_on": "eval:!doc.disable_rounded_total",
@@ -1040,9 +858,7 @@
    "no_copy": 1,
    "options": "Company:company:default_currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "base_in_words",
@@ -1052,17 +868,13 @@
    "oldfieldname": "in_words",
    "oldfieldtype": "Data",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "column_break8",
    "fieldtype": "Column Break",
    "oldfieldtype": "Column Break",
    "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1,
    "width": "50%"
   },
   {
@@ -1073,9 +885,7 @@
    "oldfieldname": "grand_total_import",
    "oldfieldtype": "Currency",
    "options": "currency",
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "depends_on": "eval:!doc.disable_rounded_total",
@@ -1085,9 +895,7 @@
    "no_copy": 1,
    "options": "currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "depends_on": "eval:!doc.disable_rounded_total",
@@ -1097,9 +905,7 @@
    "no_copy": 1,
    "options": "currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "in_words",
@@ -1109,9 +915,7 @@
    "oldfieldname": "in_words_import",
    "oldfieldtype": "Data",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "total_advance",
@@ -1122,9 +926,7 @@
    "oldfieldtype": "Currency",
    "options": "party_account_currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "outstanding_amount",
@@ -1135,18 +937,14 @@
    "oldfieldtype": "Currency",
    "options": "party_account_currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "default": "0",
    "depends_on": "grand_total",
    "fieldname": "disable_rounded_total",
    "fieldtype": "Check",
-   "label": "Disable Rounded Total",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Disable Rounded Total"
   },
   {
    "collapsible": 1,
@@ -1154,26 +952,20 @@
    "depends_on": "eval:doc.is_paid===1||(doc.advances && doc.advances.length>0)",
    "fieldname": "payments_section",
    "fieldtype": "Section Break",
-   "label": "Payments",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Payments"
   },
   {
    "fieldname": "mode_of_payment",
    "fieldtype": "Link",
    "label": "Mode of Payment",
    "options": "Mode of Payment",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "cash_bank_account",
    "fieldtype": "Link",
    "label": "Cash/Bank Account",
-   "options": "Account",
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "Account"
   },
   {
    "fieldname": "clearance_date",
@@ -1181,15 +973,11 @@
    "label": "Clearance Date",
    "no_copy": 1,
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "col_br_payments",
-   "fieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Column Break"
   },
   {
    "depends_on": "is_paid",
@@ -1198,9 +986,7 @@
    "label": "Paid Amount",
    "no_copy": 1,
    "options": "currency",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "base_paid_amount",
@@ -1209,9 +995,7 @@
    "no_copy": 1,
    "options": "Company:company:default_currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "collapsible": 1,
@@ -1219,9 +1003,7 @@
    "depends_on": "grand_total",
    "fieldname": "write_off",
    "fieldtype": "Section Break",
-   "label": "Write Off",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Write Off"
   },
   {
    "fieldname": "write_off_amount",
@@ -1229,9 +1011,7 @@
    "label": "Write Off Amount",
    "no_copy": 1,
    "options": "currency",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "base_write_off_amount",
@@ -1240,15 +1020,11 @@
    "no_copy": 1,
    "options": "Company:company:default_currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "column_break_61",
-   "fieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Column Break"
   },
   {
    "depends_on": "eval:flt(doc.write_off_amount)!=0",
@@ -1256,9 +1032,7 @@
    "fieldtype": "Link",
    "label": "Write Off Account",
    "options": "Account",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "depends_on": "eval:flt(doc.write_off_amount)!=0",
@@ -1266,9 +1040,7 @@
    "fieldtype": "Link",
    "label": "Write Off Cost Center",
    "options": "Cost Center",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "collapsible": 1,
@@ -1278,17 +1050,13 @@
    "label": "Advance Payments",
    "oldfieldtype": "Section Break",
    "options": "fa fa-money",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "default": "0",
    "fieldname": "allocate_advances_automatically",
    "fieldtype": "Check",
-   "label": "Set Advances and Allocate (FIFO)",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Set Advances and Allocate (FIFO)"
   },
   {
    "depends_on": "eval:!doc.allocate_advances_automatically",
@@ -1296,9 +1064,7 @@
    "fieldtype": "Button",
    "label": "Get Advances Paid",
    "oldfieldtype": "Button",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "advances",
@@ -1308,26 +1074,20 @@
    "oldfieldname": "advance_allocation_details",
    "oldfieldtype": "Table",
    "options": "Purchase Invoice Advance",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "collapsible": 1,
    "collapsible_depends_on": "eval:(!doc.is_return)",
    "fieldname": "payment_schedule_section",
    "fieldtype": "Section Break",
-   "label": "Payment Terms",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Payment Terms"
   },
   {
    "fieldname": "payment_terms_template",
    "fieldtype": "Link",
    "label": "Payment Terms Template",
-   "options": "Payment Terms Template",
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "Payment Terms Template"
   },
   {
    "fieldname": "payment_schedule",
@@ -1335,9 +1095,7 @@
    "label": "Payment Schedule",
    "no_copy": 1,
    "options": "Payment Schedule",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "collapsible": 1,
@@ -1345,33 +1103,25 @@
    "fieldname": "terms_section_break",
    "fieldtype": "Section Break",
    "label": "Terms and Conditions",
-   "options": "fa fa-legal",
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "fa fa-legal"
   },
   {
    "fieldname": "tc_name",
    "fieldtype": "Link",
    "label": "Terms",
    "options": "Terms and Conditions",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "terms",
    "fieldtype": "Text Editor",
-   "label": "Terms and Conditions1",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Terms and Conditions1"
   },
   {
    "collapsible": 1,
    "fieldname": "printing_settings",
    "fieldtype": "Section Break",
-   "label": "Printing Settings",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Printing Settings"
   },
   {
    "allow_on_submit": 1,
@@ -1379,9 +1129,7 @@
    "fieldtype": "Link",
    "label": "Letter Head",
    "options": "Letter Head",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "allow_on_submit": 1,
@@ -1389,15 +1137,11 @@
    "fieldname": "group_same_items",
    "fieldtype": "Check",
    "label": "Group same items",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "column_break_112",
-   "fieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Column Break"
   },
   {
    "allow_on_submit": 1,
@@ -1409,18 +1153,14 @@
    "oldfieldtype": "Link",
    "options": "Print Heading",
    "print_hide": 1,
-   "report_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "report_hide": 1
   },
   {
    "fieldname": "language",
    "fieldtype": "Data",
    "label": "Print Language",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "collapsible": 1,
@@ -1429,9 +1169,7 @@
    "label": "More Information",
    "oldfieldtype": "Section Break",
    "options": "fa fa-file-text",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "credit_to",
@@ -1442,9 +1180,7 @@
    "options": "Account",
    "print_hide": 1,
    "reqd": 1,
-   "search_index": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "search_index": 1
   },
   {
    "fieldname": "party_account_currency",
@@ -1454,9 +1190,7 @@
    "no_copy": 1,
    "options": "Currency",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "default": "No",
@@ -1466,9 +1200,7 @@
    "oldfieldname": "is_opening",
    "oldfieldtype": "Select",
    "options": "No\nYes",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "against_expense_account",
@@ -1478,15 +1210,11 @@
    "no_copy": 1,
    "oldfieldname": "against_expense_account",
    "oldfieldtype": "Small Text",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "column_break_63",
-   "fieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Column Break"
   },
   {
    "default": "Draft",
@@ -1494,10 +1222,8 @@
    "fieldtype": "Select",
    "in_standard_filter": 1,
    "label": "Status",
-   "options": "\nDraft\nReturn\nDebit Note Issued\nSubmitted\nPaid\nUnpaid\nOverdue\nCancelled\nInternal Transfer",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "\nDraft\nReturn\nDebit Note Issued\nSubmitted\nPaid\nPartly Paid\nUnpaid\nOverdue\nCancelled\nInternal Transfer",
+   "print_hide": 1
   },
   {
    "fieldname": "inter_company_invoice_reference",
@@ -1506,9 +1232,7 @@
    "no_copy": 1,
    "options": "Sales Invoice",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "remarks",
@@ -1517,18 +1241,14 @@
    "no_copy": 1,
    "oldfieldname": "remarks",
    "oldfieldtype": "Text",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "collapsible": 1,
    "fieldname": "subscription_section",
    "fieldtype": "Section Break",
    "label": "Subscription Section",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "allow_on_submit": 1,
@@ -1537,9 +1257,7 @@
    "fieldtype": "Date",
    "label": "From Date",
    "no_copy": 1,
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "allow_on_submit": 1,
@@ -1548,15 +1266,11 @@
    "fieldtype": "Date",
    "label": "To Date",
    "no_copy": 1,
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "column_break_114",
-   "fieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Column Break"
   },
   {
    "fieldname": "auto_repeat",
@@ -1565,42 +1279,33 @@
    "no_copy": 1,
    "options": "Auto Repeat",
    "print_hide": 1,
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "allow_on_submit": 1,
    "depends_on": "eval: doc.auto_repeat",
    "fieldname": "update_auto_repeat_reference",
    "fieldtype": "Button",
-   "label": "Update Auto Repeat Reference",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Update Auto Repeat Reference"
   },
   {
    "collapsible": 1,
    "fieldname": "accounting_dimensions_section",
    "fieldtype": "Section Break",
-   "label": "Accounting Dimensions ",
-   "show_days": 1,
-   "show_seconds": 1
+   "label": "Accounting Dimensions "
   },
   {
    "fieldname": "dimension_col_break",
-   "fieldtype": "Column Break",
-   "show_days": 1,
-   "show_seconds": 1
+   "fieldtype": "Column Break"
   },
   {
    "default": "0",
    "fetch_from": "supplier.is_internal_supplier",
    "fieldname": "is_internal_supplier",
    "fieldtype": "Check",
+   "ignore_user_permissions": 1,
    "label": "Is Internal Supplier",
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "tax_withholding_category",
@@ -1608,33 +1313,25 @@
    "hidden": 1,
    "label": "Tax Withholding Category",
    "options": "Tax Withholding Category",
-   "print_hide": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "print_hide": 1
   },
   {
    "fieldname": "billing_address",
    "fieldtype": "Link",
    "label": "Select Billing Address",
-   "options": "Address",
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "Address"
   },
   {
    "fieldname": "billing_address_display",
    "fieldtype": "Small Text",
    "label": "Billing Address",
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   },
   {
    "fieldname": "project",
    "fieldtype": "Link",
    "label": "Project",
-   "options": "Project",
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "Project"
   },
   {
    "depends_on": "eval:doc.is_internal_supplier",
@@ -1642,9 +1339,7 @@
    "fieldname": "unrealized_profit_loss_account",
    "fieldtype": "Link",
    "label": "Unrealized Profit / Loss Account",
-   "options": "Account",
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "Account"
   },
   {
    "depends_on": "eval:doc.is_internal_supplier",
@@ -1653,9 +1348,7 @@
    "fieldname": "represents_company",
    "fieldtype": "Link",
    "label": "Represents Company",
-   "options": "Company",
-   "show_days": 1,
-   "show_seconds": 1
+   "options": "Company"
   },
   {
    "depends_on": "eval:doc.update_stock && doc.is_internal_supplier",
@@ -1667,8 +1360,6 @@
    "options": "Warehouse",
    "print_hide": 1,
    "print_width": "50px",
-   "show_days": 1,
-   "show_seconds": 1,
    "width": "50px"
   },
   {
@@ -1680,8 +1371,6 @@
    "options": "Warehouse",
    "print_hide": 1,
    "print_width": "50px",
-   "show_days": 1,
-   "show_seconds": 1,
    "width": "50px"
   },
   {
@@ -1705,20 +1394,19 @@
    "fieldtype": "Check",
    "hidden": 1,
    "label": "Ignore Default Payment Terms Template",
-   "read_only": 1,
-   "show_days": 1,
-   "show_seconds": 1
+   "read_only": 1
   }
  ],
  "icon": "fa fa-file-text",
  "idx": 204,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-08-17 20:16:12.737743",
+ "modified": "2021-09-28 13:10:28.351810",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice",
  "name_case": "Title Case",
+ "naming_rule": "By \"Naming Series\" field",
  "owner": "Administrator",
  "permissions": [
   {
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 62cd90e..1c9943f 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -15,6 +15,7 @@
 from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
 from erpnext.accounts.doctype.sales_invoice.sales_invoice import (
 	check_if_return_invoice_linked_with_payment_entry,
+	is_overdue,
 	unlink_inter_company_doc,
 	update_linked_doc,
 	validate_inter_company_party,
@@ -1145,6 +1146,12 @@
 		if not self.apply_tds:
 			return
 
+		if self.apply_tds and not self.get('tax_withholding_category'):
+			self.tax_withholding_category = frappe.db.get_value('Supplier', self.supplier, 'tax_withholding_category')
+
+		if not self.tax_withholding_category:
+			return
+
 		tax_withholding_details = get_party_tax_withholding_details(self, self.tax_withholding_category)
 
 		if not tax_withholding_details:
@@ -1175,10 +1182,7 @@
 				self.status = 'Draft'
 			return
 
-		precision = self.precision("outstanding_amount")
-		outstanding_amount = flt(self.outstanding_amount, precision)
-		due_date = getdate(self.due_date)
-		nowdate = getdate()
+		outstanding_amount = flt(self.outstanding_amount, self.precision("outstanding_amount"))
 
 		if not status:
 			if self.docstatus == 2:
@@ -1186,9 +1190,11 @@
 			elif self.docstatus == 1:
 				if self.is_internal_transfer():
 					self.status = 'Internal Transfer'
-				elif outstanding_amount > 0 and due_date < nowdate:
+				elif is_overdue(self):
 					self.status = "Overdue"
-				elif outstanding_amount > 0 and due_date >= nowdate:
+				elif 0 < outstanding_amount < flt(self.grand_total, self.precision("grand_total")):
+					self.status = "Partly Paid"
+				elif outstanding_amount > 0 and getdate(self.due_date) >= getdate():
 					self.status = "Unpaid"
 				#Check if outstanding amount is 0 due to debit note issued against invoice
 				elif outstanding_amount <= 0 and self.is_return == 0 and frappe.db.get_value('Purchase Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1}):
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js
index 771b49a..f6ff83a 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js
@@ -2,28 +2,58 @@
 // License: GNU General Public License v3. See license.txt
 
 // render
-frappe.listview_settings['Purchase Invoice'] = {
-	add_fields: ["supplier", "supplier_name", "base_grand_total", "outstanding_amount", "due_date", "company",
-		"currency", "is_return", "release_date", "on_hold", "represents_company", "is_internal_supplier"],
-	get_indicator: function(doc) {
-		if ((flt(doc.outstanding_amount) <= 0) && doc.docstatus == 1 &&  doc.status == 'Debit Note Issued') {
-			return [__("Debit Note Issued"), "darkgrey", "outstanding_amount,<=,0"];
-		} else if (flt(doc.outstanding_amount) > 0 && doc.docstatus==1) {
-			if(cint(doc.on_hold) && !doc.release_date) {
-				return [__("On Hold"), "darkgrey"];
-			} else if (cint(doc.on_hold) && doc.release_date && frappe.datetime.get_diff(doc.release_date, frappe.datetime.nowdate()) > 0) {
-				return [__("Temporarily on Hold"), "darkgrey"];
-			} else if (frappe.datetime.get_diff(doc.due_date) < 0) {
-				return [__("Overdue"), "red", "outstanding_amount,>,0|due_date,<,Today"];
-			} else {
-				return [__("Unpaid"), "orange", "outstanding_amount,>,0|due_date,>=,Today"];
-			}
-		} else if (cint(doc.is_return)) {
-			return [__("Return"), "gray", "is_return,=,Yes"];
-		} else if (doc.company == doc.represents_company && doc.is_internal_supplier) {
-			return [__("Internal Transfer"), "darkgrey", "outstanding_amount,=,0"];
-		} else if (flt(doc.outstanding_amount)==0 && doc.docstatus==1) {
-			return [__("Paid"), "green", "outstanding_amount,=,0"];
+frappe.listview_settings["Purchase Invoice"] = {
+	add_fields: [
+		"supplier",
+		"supplier_name",
+		"base_grand_total",
+		"outstanding_amount",
+		"due_date",
+		"company",
+		"currency",
+		"is_return",
+		"release_date",
+		"on_hold",
+		"represents_company",
+		"is_internal_supplier",
+	],
+	get_indicator(doc) {
+		if (doc.status == "Debit Note Issued") {
+			return [__(doc.status), "darkgrey", "status,=," + doc.status];
 		}
-	}
+
+		if (
+			flt(doc.outstanding_amount) > 0 &&
+			doc.docstatus == 1 &&
+			cint(doc.on_hold)
+		) {
+			if (!doc.release_date) {
+				return [__("On Hold"), "darkgrey"];
+			} else if (
+				frappe.datetime.get_diff(
+					doc.release_date,
+					frappe.datetime.nowdate()
+				) > 0
+			) {
+				return [__("Temporarily on Hold"), "darkgrey"];
+			}
+		}
+
+		const status_colors = {
+			"Unpaid": "orange",
+			"Paid": "green",
+			"Return": "gray",
+			"Overdue": "red",
+			"Partly Paid": "yellow",
+			"Internal Transfer": "darkgrey",
+		};
+
+		if (status_colors[doc.status]) {
+			return [
+				__(doc.status),
+				status_colors[doc.status],
+				"status,=," + doc.status,
+			];
+		}
+	},
 };
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index 20d6c46..5cbeb56 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -1151,10 +1151,11 @@
 			tax_withholding_category = 'TDS - 194 - Dividends - Individual')
 
 		# Update tax withholding category with current fiscal year and rate details
-		update_tax_witholding_category('_Test Company', 'TDS Payable - _TC', nowdate())
+		update_tax_witholding_category('_Test Company', 'TDS Payable - _TC')
 
 		# Create Purchase Order with TDS applied
-		po = create_purchase_order(do_not_save=1, supplier=supplier.name, rate=3000, item='_Test Non Stock Item')
+		po = create_purchase_order(do_not_save=1, supplier=supplier.name, rate=3000, item='_Test Non Stock Item',
+			posting_date='2021-09-15')
 		po.apply_tds = 1
 		po.tax_withholding_category = 'TDS - 194 - Dividends - Individual'
 		po.save()
@@ -1226,16 +1227,20 @@
 		doc.assertEqual(expected_gle[i][2], gle.credit)
 		doc.assertEqual(getdate(expected_gle[i][3]), gle.posting_date)
 
-def update_tax_witholding_category(company, account, date):
+def update_tax_witholding_category(company, account):
 	from erpnext.accounts.utils import get_fiscal_year
 
-	fiscal_year = get_fiscal_year(date=date, company=company)
+	fiscal_year = get_fiscal_year(fiscal_year='2021')
 
 	if not frappe.db.get_value('Tax Withholding Rate',
-		{'parent': 'TDS - 194 - Dividends - Individual', 'fiscal_year': fiscal_year[0]}):
+		{'parent': 'TDS - 194 - Dividends - Individual', 'from_date': ('>=', fiscal_year[1]),
+			'to_date': ('<=', fiscal_year[2])}):
 		tds_category = frappe.get_doc('Tax Withholding Category', 'TDS - 194 - Dividends - Individual')
+		tds_category.set('rates', [])
+
 		tds_category.append('rates', {
-			'fiscal_year': fiscal_year[0],
+			'from_date': fiscal_year[1],
+			'to_date': fiscal_year[2],
 			'tax_withholding_rate': 10,
 			'single_threshold': 2500,
 			'cumulative_threshold': 0
diff --git a/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json b/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json
index 63dfff8..9fcbf5c 100644
--- a/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json
+++ b/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json
@@ -97,6 +97,7 @@
    "width": "100px"
   },
   {
+   "depends_on": "exchange_gain_loss",
    "fieldname": "exchange_gain_loss",
    "fieldtype": "Currency",
    "label": "Exchange Gain/Loss",
@@ -104,6 +105,7 @@
    "read_only": 1
   },
   {
+   "depends_on": "exchange_gain_loss",
    "fieldname": "ref_exchange_rate",
    "fieldtype": "Float",
    "label": "Reference Exchange Rate",
@@ -115,7 +117,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-04-20 16:26:53.820530",
+ "modified": "2021-09-26 15:47:28.167371",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice Advance",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 2cb9acf..73e1284 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -446,15 +446,6 @@
 	}
 
 	currency() {
-		this._super();
-		$.each(cur_frm.doc.timesheets, function(i, d) {
-			let row = frappe.get_doc(d.doctype, d.name)
-			set_timesheet_detail_rate(row.doctype, row.name, cur_frm.doc.currency, row.timesheet_detail)
-		});
-		calculate_total_billing_amount(cur_frm)
-	}
-
-	currency() {
 		var me = this;
 		super.currency();
 		if (this.frm.doc.timesheets) {
@@ -462,7 +453,7 @@
 				let row = frappe.get_doc(d.doctype, d.name)
 				set_timesheet_detail_rate(row.doctype, row.name, me.frm.doc.currency, row.timesheet_detail)
 			});
-			calculate_total_billing_amount(this.frm);
+			frm.trigger("calculate_timesheet_totals");
 		}
 	}
 };
@@ -734,19 +725,6 @@
 		}
 	},
 
-	project: function(frm){
-		if (!frm.doc.is_return) {
-			frm.call({
-				method: "add_timesheet_data",
-				doc: frm.doc,
-				callback: function(r, rt) {
-					refresh_field(['timesheets'])
-				}
-			})
-			frm.refresh();
-		}
-	},
-
 	onload: function(frm) {
 		frm.redemption_conversion_factor = null;
 	},
@@ -857,25 +835,92 @@
 		}
 	},
 
-	add_timesheet_row: function(frm, row, exchange_rate) {
-		frm.add_child('timesheets', {
-			'activity_type': row.activity_type,
-			'description': row.description,
-			'time_sheet': row.parent,
-			'billing_hours': row.billing_hours,
-			'billing_amount': flt(row.billing_amount) * flt(exchange_rate),
-			'timesheet_detail': row.name,
-			'project_name': row.project_name
+	project: function(frm) {
+		if (frm.doc.project) {
+			frm.events.add_timesheet_data(frm, {
+				project: frm.doc.project
+			});
+		}
+	},
+
+	async add_timesheet_data(frm, kwargs) {
+		if (kwargs === "Sales Invoice") {
+			// called via frm.trigger()
+			kwargs = Object();
+		}
+
+		if (!kwargs.hasOwnProperty("project") && frm.doc.project) {
+			kwargs.project = frm.doc.project;
+		}
+
+		const timesheets = await frm.events.get_timesheet_data(frm, kwargs);
+		return frm.events.set_timesheet_data(frm, timesheets);
+	},
+
+	async get_timesheet_data(frm, kwargs) {
+		return frappe.call({
+			method: "erpnext.projects.doctype.timesheet.timesheet.get_projectwise_timesheet_data",
+			args: kwargs
+		}).then(r => {
+			if (!r.exc && r.message.length > 0) {
+				return r.message
+			} else {
+				return []
+			}
 		});
-		frm.refresh_field('timesheets');
-		calculate_total_billing_amount(frm);
+	},
+
+	set_timesheet_data: function(frm, timesheets) {
+		frm.clear_table("timesheets")
+		timesheets.forEach(timesheet => {
+			if (frm.doc.currency != timesheet.currency) {
+				frappe.call({
+					method: "erpnext.setup.utils.get_exchange_rate",
+					args: {
+						from_currency: timesheet.currency,
+						to_currency: frm.doc.currency
+					},
+					callback: function(r) {
+						if (r.message) {
+							exchange_rate = r.message;
+							frm.events.append_time_log(frm, timesheet, exchange_rate);
+						}
+					}
+				});
+			} else {
+				frm.events.append_time_log(frm, timesheet, 1.0);
+			}
+		});
+	},
+
+	append_time_log: function(frm, time_log, exchange_rate) {
+		const row = frm.add_child("timesheets");
+		row.activity_type = time_log.activity_type;
+		row.description = time_log.description;
+		row.time_sheet = time_log.time_sheet;
+		row.from_time = time_log.from_time;
+		row.to_time = time_log.to_time;
+		row.billing_hours = time_log.billing_hours;
+		row.billing_amount = flt(time_log.billing_amount) * flt(exchange_rate);
+		row.timesheet_detail = time_log.name;
+    row.project_name = time_log.project_name;
+
+		frm.refresh_field("timesheets");
+		frm.trigger("calculate_timesheet_totals");
+	},
+
+	calculate_timesheet_totals: function(frm) {
+		frm.set_value("total_billing_amount",
+			frm.doc.timesheets.reduce((a, b) => a + (b["billing_amount"] || 0.0), 0.0));
+		frm.set_value("total_billing_hours",
+			frm.doc.timesheets.reduce((a, b) => a + (b["billing_hours"] || 0.0), 0.0));
 	},
 
 	refresh: function(frm) {
 		if (frm.doc.docstatus===0 && !frm.doc.is_return) {
-			frm.add_custom_button(__('Fetch Timesheet'), function() {
+			frm.add_custom_button(__("Fetch Timesheet"), function() {
 				let d = new frappe.ui.Dialog({
-					title: __('Fetch Timesheet'),
+					title: __("Fetch Timesheet"),
 					fields: [
 						{
 							"label" : __("From"),
@@ -884,8 +929,8 @@
 							"reqd": 1,
 						},
 						{
-							fieldtype: 'Column Break',
-							fieldname: 'col_break_1',
+							fieldtype: "Column Break",
+							fieldname: "col_break_1",
 						},
 						{
 							"label" : __("To"),
@@ -902,48 +947,18 @@
 						},
 					],
 					primary_action: function() {
-						let data = d.get_values();
-						frappe.call({
-							method: "erpnext.projects.doctype.timesheet.timesheet.get_projectwise_timesheet_data",
-							args: {
-								from_time: data.from_time,
-								to_time: data.to_time,
-								project: data.project
-							},
-							callback: function(r) {
-								if (!r.exc && r.message.length > 0) {
-									frm.clear_table('timesheets')
-									r.message.forEach((d) => {
-										let exchange_rate = 1.0;
-										if (frm.doc.currency != d.currency) {
-											frappe.call({
-												method: 'erpnext.setup.utils.get_exchange_rate',
-												args: {
-													from_currency: d.currency,
-													to_currency: frm.doc.currency
-												},
-												callback: function(r) {
-													if (r.message) {
-														exchange_rate = r.message;
-														frm.events.add_timesheet_row(frm, d, exchange_rate);
-													}
-												}
-											});
-										} else {
-											frm.events.add_timesheet_row(frm, d, exchange_rate);
-										}
-									});
-								} else {
-									frappe.msgprint(__('No Timesheets found with the selected filters.'))
-								}
-								d.hide();
-							}
+						const data = d.get_values();
+						frm.events.add_timesheet_data(frm, {
+							from_time: data.from_time,
+							to_time: data.to_time,
+							project: data.project
 						});
+						d.hide();
 					},
-					primary_action_label: __('Get Timesheets')
+					primary_action_label: __("Get Timesheets")
 				});
 				d.show();
-			})
+			});
 		}
 
 		if (frm.doc.is_debit_note) {
@@ -976,26 +991,20 @@
 			frm: frm
 		});
 	},
+
 	create_dunning: function(frm) {
 		frappe.model.open_mapped_doc({
 			method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.create_dunning",
 			frm: frm
 		});
 	}
-})
+});
 
-var calculate_total_billing_amount =  function(frm) {
-	var doc = frm.doc;
-
-	doc.total_billing_amount = 0.0
-	if (doc.timesheets) {
-		doc.timesheets.forEach((d) => {
-			doc.total_billing_amount += flt(d.billing_amount)
-		});
+frappe.ui.form.on("Sales Invoice Timesheet", {
+	timesheets_remove(frm) {
+		frm.trigger("calculate_timesheet_totals");
 	}
-
-	refresh_field('total_billing_amount')
-}
+});
 
 var set_timesheet_detail_rate = function(cdt, cdn, currency, timelog) {
 	frappe.call({
@@ -1042,276 +1051,3 @@
 
 	dialog.show();
 }
-
-// Healthcare
-var get_healthcare_services_to_invoice = function(frm) {
-	var me = this;
-	let selected_patient = '';
-	var dialog = new frappe.ui.Dialog({
-		title: __("Get Items from Healthcare Services"),
-		fields:[
-			{
-				fieldtype: 'Link',
-				options: 'Patient',
-				label: 'Patient',
-				fieldname: "patient",
-				reqd: true
-			},
-			{ fieldtype: 'Section Break'	},
-			{ fieldtype: 'HTML', fieldname: 'results_area' }
-		]
-	});
-	var $wrapper;
-	var $results;
-	var $placeholder;
-	dialog.set_values({
-		'patient': frm.doc.patient
-	});
-	dialog.fields_dict["patient"].df.onchange = () => {
-		var patient = dialog.fields_dict.patient.input.value;
-		if(patient && patient!=selected_patient){
-			selected_patient = patient;
-			var method = "erpnext.healthcare.utils.get_healthcare_services_to_invoice";
-			var args = {patient: patient, company: frm.doc.company};
-			var columns = (["service", "reference_name", "reference_type"]);
-			get_healthcare_items(frm, true, $results, $placeholder, method, args, columns);
-		}
-		else if(!patient){
-			selected_patient = '';
-			$results.empty();
-			$results.append($placeholder);
-		}
-	}
-	$wrapper = dialog.fields_dict.results_area.$wrapper.append(`<div class="results"
-		style="border: 1px solid #d1d8dd; border-radius: 3px; height: 300px; overflow: auto;"></div>`);
-	$results = $wrapper.find('.results');
-	$placeholder = $(`<div class="multiselect-empty-state">
-				<span class="text-center" style="margin-top: -40px;">
-					<i class="fa fa-2x fa-heartbeat text-extra-muted"></i>
-					<p class="text-extra-muted">No billable Healthcare Services found</p>
-				</span>
-			</div>`);
-	$results.on('click', '.list-item--head :checkbox', (e) => {
-		$results.find('.list-item-container .list-row-check')
-			.prop("checked", ($(e.target).is(':checked')));
-	});
-	set_primary_action(frm, dialog, $results, true);
-	dialog.show();
-};
-
-var get_healthcare_items = function(frm, invoice_healthcare_services, $results, $placeholder, method, args, columns) {
-	var me = this;
-	$results.empty();
-	frappe.call({
-		method: method,
-		args: args,
-		callback: function(data) {
-			if(data.message){
-				$results.append(make_list_row(columns, invoice_healthcare_services));
-				for(let i=0; i<data.message.length; i++){
-					$results.append(make_list_row(columns, invoice_healthcare_services, data.message[i]));
-				}
-			}else {
-				$results.append($placeholder);
-			}
-		}
-	});
-}
-
-var make_list_row= function(columns, invoice_healthcare_services, result={}) {
-	var me = this;
-	// Make a head row by default (if result not passed)
-	let head = Object.keys(result).length === 0;
-	let contents = ``;
-	columns.forEach(function(column) {
-		contents += `<div class="list-item__content ellipsis">
-			${
-				head ? `<span class="ellipsis">${__(frappe.model.unscrub(column))}</span>`
-
-				:(column !== "name" ? `<span class="ellipsis">${__(result[column])}</span>`
-					: `<a class="list-id ellipsis">
-						${__(result[column])}</a>`)
-			}
-		</div>`;
-	})
-
-	let $row = $(`<div class="list-item">
-		<div class="list-item__content" style="flex: 0 0 10px;">
-			<input type="checkbox" class="list-row-check" ${result.checked ? 'checked' : ''}>
-		</div>
-		${contents}
-	</div>`);
-
-	$row = list_row_data_items(head, $row, result, invoice_healthcare_services);
-	return $row;
-};
-
-var set_primary_action= function(frm, dialog, $results, invoice_healthcare_services) {
-	var me = this;
-	dialog.set_primary_action(__('Add'), function() {
-		let checked_values = get_checked_values($results);
-		if(checked_values.length > 0){
-			if(invoice_healthcare_services) {
-				frm.set_value("patient", dialog.fields_dict.patient.input.value);
-			}
-			frm.set_value("items", []);
-			add_to_item_line(frm, checked_values, invoice_healthcare_services);
-			dialog.hide();
-		}
-		else{
-			if(invoice_healthcare_services){
-				frappe.msgprint(__("Please select Healthcare Service"));
-			}
-			else{
-				frappe.msgprint(__("Please select Drug"));
-			}
-		}
-	});
-};
-
-var get_checked_values= function($results) {
-	return $results.find('.list-item-container').map(function() {
-		let checked_values = {};
-		if ($(this).find('.list-row-check:checkbox:checked').length > 0 ) {
-			checked_values['dn'] = $(this).attr('data-dn');
-			checked_values['dt'] = $(this).attr('data-dt');
-			checked_values['item'] = $(this).attr('data-item');
-			if($(this).attr('data-rate') != 'undefined'){
-				checked_values['rate'] = $(this).attr('data-rate');
-			}
-			else{
-				checked_values['rate'] = false;
-			}
-			if($(this).attr('data-income-account') != 'undefined'){
-				checked_values['income_account'] = $(this).attr('data-income-account');
-			}
-			else{
-				checked_values['income_account'] = false;
-			}
-			if($(this).attr('data-qty') != 'undefined'){
-				checked_values['qty'] = $(this).attr('data-qty');
-			}
-			else{
-				checked_values['qty'] = false;
-			}
-			if($(this).attr('data-description') != 'undefined'){
-				checked_values['description'] = $(this).attr('data-description');
-			}
-			else{
-				checked_values['description'] = false;
-			}
-			return checked_values;
-		}
-	}).get();
-};
-
-var get_drugs_to_invoice = function(frm) {
-	var me = this;
-	let selected_encounter = '';
-	var dialog = new frappe.ui.Dialog({
-		title: __("Get Items from Prescriptions"),
-		fields:[
-			{ fieldtype: 'Link', options: 'Patient', label: 'Patient', fieldname: "patient", reqd: true },
-			{ fieldtype: 'Link', options: 'Patient Encounter', label: 'Patient Encounter', fieldname: "encounter", reqd: true,
-				description:'Quantity will be calculated only for items which has "Nos" as UoM. You may change as required for each invoice item.',
-				get_query: function(doc) {
-					return {
-						filters: {
-							patient: dialog.get_value("patient"),
-							company: frm.doc.company,
-							docstatus: 1
-						}
-					};
-				}
-			},
-			{ fieldtype: 'Section Break' },
-			{ fieldtype: 'HTML', fieldname: 'results_area' }
-		]
-	});
-	var $wrapper;
-	var $results;
-	var $placeholder;
-	dialog.set_values({
-		'patient': frm.doc.patient,
-		'encounter': ""
-	});
-	dialog.fields_dict["encounter"].df.onchange = () => {
-		var encounter = dialog.fields_dict.encounter.input.value;
-		if(encounter && encounter!=selected_encounter){
-			selected_encounter = encounter;
-			var method = "erpnext.healthcare.utils.get_drugs_to_invoice";
-			var args = {encounter: encounter};
-			var columns = (["drug_code", "quantity", "description"]);
-			get_healthcare_items(frm, false, $results, $placeholder, method, args, columns);
-		}
-		else if(!encounter){
-			selected_encounter = '';
-			$results.empty();
-			$results.append($placeholder);
-		}
-	}
-	$wrapper = dialog.fields_dict.results_area.$wrapper.append(`<div class="results"
-		style="border: 1px solid #d1d8dd; border-radius: 3px; height: 300px; overflow: auto;"></div>`);
-	$results = $wrapper.find('.results');
-	$placeholder = $(`<div class="multiselect-empty-state">
-				<span class="text-center" style="margin-top: -40px;">
-					<i class="fa fa-2x fa-heartbeat text-extra-muted"></i>
-					<p class="text-extra-muted">No Drug Prescription found</p>
-				</span>
-			</div>`);
-	$results.on('click', '.list-item--head :checkbox', (e) => {
-		$results.find('.list-item-container .list-row-check')
-			.prop("checked", ($(e.target).is(':checked')));
-	});
-	set_primary_action(frm, dialog, $results, false);
-	dialog.show();
-};
-
-var list_row_data_items = function(head, $row, result, invoice_healthcare_services) {
-	if(invoice_healthcare_services){
-		head ? $row.addClass('list-item--head')
-			: $row = $(`<div class="list-item-container"
-				data-dn= "${result.reference_name}" data-dt= "${result.reference_type}" data-item= "${result.service}"
-				data-rate = ${result.rate}
-				data-income-account = "${result.income_account}"
-				data-qty = ${result.qty}
-				data-description = "${result.description}">
-				</div>`).append($row);
-	}
-	else{
-		head ? $row.addClass('list-item--head')
-			: $row = $(`<div class="list-item-container"
-				data-item= "${result.drug_code}"
-				data-qty = ${result.quantity}
-				data-description = "${result.description}">
-				</div>`).append($row);
-	}
-	return $row
-};
-
-var add_to_item_line = function(frm, checked_values, invoice_healthcare_services){
-	if(invoice_healthcare_services){
-		frappe.call({
-			doc: frm.doc,
-			method: "set_healthcare_services",
-			args:{
-				checked_values: checked_values
-			},
-			callback: function() {
-				frm.trigger("validate");
-				frm.refresh_fields();
-			}
-		});
-	}
-	else{
-		for(let i=0; i<checked_values.length; i++){
-			var si_item = frappe.model.add_child(frm.doc, 'Sales Invoice Item', 'items');
-			frappe.model.set_value(si_item.doctype, si_item.name, 'item_code', checked_values[i]['item']);
-			frappe.model.set_value(si_item.doctype, si_item.name, 'qty', 1);
-			if(checked_values[i]['qty'] > 1){
-				frappe.model.set_value(si_item.doctype, si_item.name, 'qty', parseFloat(checked_values[i]['qty']));
-			}
-		}
-		frm.refresh_fields();
-	}
-};
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index b5620ae..f3adb89 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -74,6 +74,7 @@
   "time_sheet_list",
   "timesheets",
   "total_billing_amount",
+  "total_billing_hours",
   "section_break_30",
   "total_qty",
   "base_total",
@@ -247,7 +248,7 @@
    "depends_on": "customer",
    "fetch_from": "customer.customer_name",
    "fieldname": "customer_name",
-   "fieldtype": "Data",
+   "fieldtype": "Small Text",
    "hide_days": 1,
    "hide_seconds": 1,
    "in_global_search": 1,
@@ -1061,6 +1062,7 @@
    "hide_days": 1,
    "hide_seconds": 1,
    "label": "Apply Additional Discount On",
+   "length": 15,
    "options": "\nGrand Total\nNet Total",
    "print_hide": 1
   },
@@ -1147,7 +1149,7 @@
   {
    "description": "In Words will be visible once you save the Sales Invoice.",
    "fieldname": "base_in_words",
-   "fieldtype": "Data",
+   "fieldtype": "Small Text",
    "hide_days": 1,
    "hide_seconds": 1,
    "label": "In Words (Company Currency)",
@@ -1207,7 +1209,7 @@
   },
   {
    "fieldname": "in_words",
-   "fieldtype": "Data",
+   "fieldtype": "Small Text",
    "hide_days": 1,
    "hide_seconds": 1,
    "label": "In Words",
@@ -1560,6 +1562,7 @@
    "hide_days": 1,
    "hide_seconds": 1,
    "label": "Print Language",
+   "length": 6,
    "print_hide": 1,
    "read_only": 1
   },
@@ -1647,8 +1650,9 @@
    "hide_seconds": 1,
    "in_standard_filter": 1,
    "label": "Status",
+   "length": 30,
    "no_copy": 1,
-   "options": "\nDraft\nReturn\nCredit Note Issued\nSubmitted\nPaid\nUnpaid\nUnpaid and Discounted\nOverdue and Discounted\nOverdue\nCancelled\nInternal Transfer",
+   "options": "\nDraft\nReturn\nCredit Note Issued\nSubmitted\nPaid\nPartly Paid\nUnpaid\nUnpaid and Discounted\nPartly Paid and Discounted\nOverdue and Discounted\nOverdue\nCancelled\nInternal Transfer",
    "print_hide": 1,
    "read_only": 1
   },
@@ -1706,6 +1710,7 @@
    "hide_days": 1,
    "hide_seconds": 1,
    "label": "Is Opening Entry",
+   "length": 4,
    "oldfieldname": "is_opening",
    "oldfieldtype": "Select",
    "options": "No\nYes",
@@ -1717,6 +1722,7 @@
    "hide_days": 1,
    "hide_seconds": 1,
    "label": "C-Form Applicable",
+   "length": 4,
    "no_copy": 1,
    "options": "No\nYes",
    "print_hide": 1
@@ -1948,6 +1954,7 @@
    "fetch_from": "customer.represents_company",
    "fieldname": "represents_company",
    "fieldtype": "Link",
+   "ignore_user_permissions": 1,
    "label": "Represents Company",
    "options": "Company",
    "read_only": 1
@@ -2005,6 +2012,13 @@
    "hidden": 1,
    "label": "Ignore Default Payment Terms Template",
    "read_only": 1
+  },
+  {
+   "fieldname": "total_billing_hours",
+   "fieldtype": "Float",
+   "label": "Total Billing Hours",
+   "print_hide": 1,
+   "read_only": 1
   }
  ],
  "icon": "fa fa-file-text",
@@ -2017,11 +2031,12 @@
    "link_fieldname": "consolidated_invoice"
   }
  ],
- "modified": "2021-08-27 20:13:40.456462",
+ "modified": "2021-10-02 03:36:10.251715",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice",
  "name_case": "Title Case",
+ "naming_rule": "By \"Naming Series\" field",
  "owner": "Administrator",
  "permissions": [
   {
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index ec249c2..d909814 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -40,7 +40,6 @@
 	post_depreciation_entries,
 )
 from erpnext.controllers.selling_controller import SellingController
-from erpnext.healthcare.utils import manage_invoice_submit_cancel
 from erpnext.projects.doctype.timesheet.timesheet import get_projectwise_timesheet_data
 from erpnext.setup.doctype.company.company import update_company_current_month_sales
 from erpnext.stock.doctype.batch.batch import set_batch_nos
@@ -233,9 +232,6 @@
 		if self.update_stock == 1:
 			self.repost_future_sle_and_gle()
 
-		if self.update_stock == 1:
-			self.repost_future_sle_and_gle()
-
 		if not self.is_return:
 			self.update_billing_status_for_zero_amount_refdoc("Delivery Note")
 			self.update_billing_status_for_zero_amount_refdoc("Sales Order")
@@ -263,13 +259,6 @@
 		if self.redeem_loyalty_points and not self.is_consolidated and self.loyalty_points:
 			self.apply_loyalty_points()
 
-		# Healthcare Service Invoice.
-		domain_settings = frappe.get_doc('Domain Settings')
-		active_domains = [d.domain for d in domain_settings.active_domains]
-
-		if "Healthcare" in active_domains:
-			manage_invoice_submit_cancel(self, "on_submit")
-
 		self.process_common_party_accounting()
 
 	def validate_pos_return(self):
@@ -352,12 +341,6 @@
 
 		unlink_inter_company_doc(self.doctype, self.name, self.inter_company_invoice_reference)
 
-		# Healthcare Service Invoice.
-		domain_settings = frappe.get_doc('Domain Settings')
-		active_domains = [d.domain for d in domain_settings.active_domains]
-
-		if "Healthcare" in active_domains:
-			manage_invoice_submit_cancel(self, "on_cancel")
 		self.unlink_sales_invoice_from_timesheets()
 		self.ignore_linked_doctypes = ('GL Entry', 'Stock Ledger Entry', 'Repost Item Valuation')
 
@@ -499,7 +482,7 @@
 			self.account_for_change_amount = frappe.get_cached_value('Company',  self.company,  'default_cash_account')
 
 		from erpnext.stock.get_item_details import get_pos_profile, get_pos_profile_item_details
-		if not self.pos_profile:
+		if not self.pos_profile and not self.flags.ignore_pos_profile:
 			pos_profile = get_pos_profile(self.company) or {}
 			if not pos_profile:
 				return
@@ -772,7 +755,7 @@
 		if self.project:
 			for data in get_projectwise_timesheet_data(self.project):
 				self.append('timesheets', {
-						'time_sheet': data.parent,
+						'time_sheet': data.time_sheet,
 						'billing_hours': data.billing_hours,
 						'billing_amount': data.billing_amount,
 						'timesheet_detail': data.name,
@@ -783,12 +766,11 @@
 			self.calculate_billing_amount_for_timesheet()
 
 	def calculate_billing_amount_for_timesheet(self):
-		total_billing_amount = 0.0
-		for data in self.timesheets:
-			if data.billing_amount:
-				total_billing_amount += data.billing_amount
+		def timesheet_sum(field):
+			return sum((ts.get(field) or 0.0) for ts in self.timesheets)
 
-		self.total_billing_amount = total_billing_amount
+		self.total_billing_amount = timesheet_sum("billing_amount")
+		self.total_billing_hours = timesheet_sum("billing_hours")
 
 	def get_warehouse(self):
 		user_pos_profile = frappe.db.sql("""select name, warehouse from `tabPOS Profile`
@@ -1430,59 +1412,13 @@
 			if points_to_redeem < 1: # since points_to_redeem is integer
 				break
 
-	# Healthcare
-	@frappe.whitelist()
-	def set_healthcare_services(self, checked_values):
-		self.set("items", [])
-		from erpnext.stock.get_item_details import get_item_details
-		for checked_item in checked_values:
-			item_line = self.append("items", {})
-			price_list, price_list_currency = frappe.db.get_values("Price List", {"selling": 1}, ['name', 'currency'])[0]
-			args = {
-				'doctype': "Sales Invoice",
-				'item_code': checked_item['item'],
-				'company': self.company,
-				'customer': frappe.db.get_value("Patient", self.patient, "customer"),
-				'selling_price_list': price_list,
-				'price_list_currency': price_list_currency,
-				'plc_conversion_rate': 1.0,
-				'conversion_rate': 1.0
-			}
-			item_details = get_item_details(args)
-			item_line.item_code = checked_item['item']
-			item_line.qty = 1
-			if checked_item['qty']:
-				item_line.qty = checked_item['qty']
-			if checked_item['rate']:
-				item_line.rate = checked_item['rate']
-			else:
-				item_line.rate = item_details.price_list_rate
-			item_line.amount = float(item_line.rate) * float(item_line.qty)
-			if checked_item['income_account']:
-				item_line.income_account = checked_item['income_account']
-			if checked_item['dt']:
-				item_line.reference_dt = checked_item['dt']
-			if checked_item['dn']:
-				item_line.reference_dn = checked_item['dn']
-			if checked_item['description']:
-				item_line.description = checked_item['description']
-
-		self.set_missing_values(for_validate = True)
-
 	def set_status(self, update=False, status=None, update_modified=True):
 		if self.is_new():
 			if self.get('amended_from'):
 				self.status = 'Draft'
 			return
 
-		precision = self.precision("outstanding_amount")
-		outstanding_amount = flt(self.outstanding_amount, precision)
-		due_date = getdate(self.due_date)
-		nowdate = getdate()
-
-		discounting_status = None
-		if self.is_discounted:
-			discounting_status = get_discounting_status(self.name)
+		outstanding_amount = flt(self.outstanding_amount, self.precision("outstanding_amount"))
 
 		if not status:
 			if self.docstatus == 2:
@@ -1490,15 +1426,13 @@
 			elif self.docstatus == 1:
 				if self.is_internal_transfer():
 					self.status = 'Internal Transfer'
-				elif outstanding_amount > 0 and due_date < nowdate and self.is_discounted and discounting_status=='Disbursed':
-					self.status = "Overdue and Discounted"
-				elif outstanding_amount > 0 and due_date < nowdate:
+				elif is_overdue(self):
 					self.status = "Overdue"
-				elif outstanding_amount > 0 and due_date >= nowdate and self.is_discounted and discounting_status=='Disbursed':
-					self.status = "Unpaid and Discounted"
-				elif outstanding_amount > 0 and due_date >= nowdate:
+				elif 0 < outstanding_amount < flt(self.grand_total, self.precision("grand_total")):
+					self.status = "Partly Paid"
+				elif outstanding_amount > 0 and getdate(self.due_date) >= getdate():
 					self.status = "Unpaid"
-				#Check if outstanding amount is 0 due to credit note issued against invoice
+				# Check if outstanding amount is 0 due to credit note issued against invoice
 				elif outstanding_amount <= 0 and self.is_return == 0 and frappe.db.get_value('Sales Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1}):
 					self.status = "Credit Note Issued"
 				elif self.is_return == 1:
@@ -1507,12 +1441,42 @@
 					self.status = "Paid"
 				else:
 					self.status = "Submitted"
+
+				if (
+					self.status in ("Unpaid", "Partly Paid", "Overdue")
+					and self.is_discounted
+					and get_discounting_status(self.name) == "Disbursed"
+				):
+					self.status += " and Discounted"
+
 			else:
 				self.status = "Draft"
 
 		if update:
 			self.db_set('status', self.status, update_modified = update_modified)
 
+def is_overdue(doc):
+	outstanding_amount = flt(doc.outstanding_amount, doc.precision("outstanding_amount"))
+
+	if outstanding_amount <= 0:
+		return
+
+	grand_total = flt(doc.grand_total, doc.precision("grand_total"))
+	nowdate = getdate()
+	if doc.payment_schedule:
+		# calculate payable amount till date
+		payable_amount = sum(
+			payment.payment_amount
+			for payment in doc.payment_schedule
+			if getdate(payment.due_date) < nowdate
+		)
+
+		if (grand_total - outstanding_amount) < payable_amount:
+			return True
+
+	elif getdate(doc.due_date) < nowdate:
+		return True
+
 def get_discounting_status(sales_invoice):
 	status = None
 
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js
index 1a01cb5..06e6f51 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js
@@ -6,18 +6,20 @@
 	add_fields: ["customer", "customer_name", "base_grand_total", "outstanding_amount", "due_date", "company",
 		"currency", "is_return"],
 	get_indicator: function(doc) {
-		var status_color = {
+		const status_colors = {
 			"Draft": "grey",
 			"Unpaid": "orange",
 			"Paid": "green",
 			"Return": "gray",
 			"Credit Note Issued": "gray",
 			"Unpaid and Discounted": "orange",
+			"Partly Paid and Discounted": "yellow",
 			"Overdue and Discounted": "red",
 			"Overdue": "red",
+			"Partly Paid": "yellow",
 			"Internal Transfer": "darkgrey"
 		};
-		return [__(doc.status), status_color[doc.status], "status,=,"+doc.status];
+		return [__(doc.status), status_colors[doc.status], "status,=,"+doc.status];
 	},
 	right_column: "grand_total"
 };
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index da0c315..f492a03 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -133,6 +133,7 @@
 
 	def test_payment_entry_unlink_against_invoice(self):
 		from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
+
 		si = frappe.copy_doc(test_records[0])
 		si.is_pos = 0
 		si.insert()
@@ -156,6 +157,7 @@
 
 	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)
@@ -1420,15 +1422,22 @@
 		itemised_tax, itemised_taxable_amount = get_itemised_tax_breakup_data(si)
 
 		expected_itemised_tax = {
-			"999800": {
+			"_Test Item": {
 				"Service Tax": {
 					"tax_rate": 10.0,
-					"tax_amount": 1500.0
+					"tax_amount": 1000.0
+				}
+			},
+			"_Test Item 2": {
+				"Service Tax": {
+					"tax_rate": 10.0,
+					"tax_amount": 500.0
 				}
 			}
 		}
 		expected_itemised_taxable_amount = {
-			"999800": 15000.0
+			"_Test Item": 10000.0,
+			"_Test Item 2": 5000.0
 		}
 
 		self.assertEqual(itemised_tax, expected_itemised_tax)
@@ -1639,6 +1648,7 @@
 
 	def test_credit_note(self):
 		from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
+
 		si = create_sales_invoice(item_code = "_Test Item", qty = (5 * -1), rate=500, is_return = 1)
 
 		outstanding_amount = get_outstanding_amount(si.doctype,
@@ -1790,6 +1800,47 @@
 
 		check_gl_entries(self, si.name, expected_gle, "2019-01-30")
 
+	def test_deferred_revenue_post_account_freeze_upto_by_admin(self):
+		frappe.set_user("Administrator")
+
+		frappe.db.set_value('Accounts Settings', None, 'acc_frozen_upto', None)
+		frappe.db.set_value('Accounts Settings', None, 'frozen_accounts_modifier', None)
+
+		deferred_account = create_account(account_name="Deferred Revenue",
+			parent_account="Current Liabilities - _TC", company="_Test Company")
+
+		item = create_item("_Test Item for Deferred Accounting")
+		item.enable_deferred_revenue = 1
+		item.deferred_revenue_account = deferred_account
+		item.no_of_months = 12
+		item.save()
+
+		si = create_sales_invoice(item=item.name, posting_date="2019-01-10", do_not_save=True)
+		si.items[0].enable_deferred_revenue = 1
+		si.items[0].service_start_date = "2019-01-10"
+		si.items[0].service_end_date = "2019-03-15"
+		si.items[0].deferred_revenue_account = deferred_account
+		si.save()
+		si.submit()
+
+		frappe.db.set_value('Accounts Settings', None, 'acc_frozen_upto', getdate('2019-01-31'))
+		frappe.db.set_value('Accounts Settings', None, 'frozen_accounts_modifier', 'System Manager')
+
+		pda1 = frappe.get_doc(dict(
+			doctype='Process Deferred Accounting',
+			posting_date=nowdate(),
+			start_date="2019-01-01",
+			end_date="2019-03-31",
+			type="Income",
+			company="_Test Company"
+		))
+
+		pda1.insert()
+		self.assertRaises(frappe.ValidationError, pda1.submit)
+
+		frappe.db.set_value('Accounts Settings', None, 'acc_frozen_upto', None)
+		frappe.db.set_value('Accounts Settings', None, 'frozen_accounts_modifier', None)
+
 	def test_fixed_deferred_revenue(self):
 		deferred_account = create_account(account_name="Deferred Revenue",
 			parent_account="Current Liabilities - _TC", company="_Test Company")
@@ -1972,11 +2023,7 @@
 		frappe.local.enable_perpetual_inventory['_Test Company 1'] = old_perpetual_inventory
 		frappe.db.set_value("Stock Settings", None, "allow_negative_stock", old_negative_stock)
 
-	def test_sle_if_target_warehouse_exists_accidentally(self):
-		"""
-			Check if inward entry exists if Target Warehouse accidentally exists
-			but Customer is not an internal customer.
-		"""
+	def test_sle_for_target_warehouse(self):
 		se = make_stock_entry(
 			item_code="138-CMS Shoe",
 			target="Finished Goods - _TC",
@@ -1997,9 +2044,9 @@
 		sles = frappe.get_all("Stock Ledger Entry", filters={"voucher_no": si.name},
 			fields=["name", "actual_qty"])
 
-		# check if only one SLE for outward entry is created
-		self.assertEqual(len(sles), 1)
-		self.assertEqual(sles[0].actual_qty, -1)
+		# check if both SLEs are created
+		self.assertEqual(len(sles), 2)
+		self.assertEqual(sum(d.actual_qty for d in sles), 0.0)
 
 		# tear down
 		si.cancel()
@@ -2262,6 +2309,54 @@
 		party_link.delete()
 		frappe.db.set_value('Accounts Settings', None, 'enable_common_party_accounting', 0)
 
+	def test_payment_statuses(self):
+		from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
+
+		today = nowdate()
+
+		# Test Overdue
+		si = create_sales_invoice(do_not_submit=True)
+		si.payment_schedule = []
+		si.append("payment_schedule", {
+			"due_date": add_days(today, -5),
+			"invoice_portion": 50,
+			"payment_amount": si.grand_total / 2
+		})
+		si.append("payment_schedule", {
+			"due_date": add_days(today, 5),
+			"invoice_portion": 50,
+			"payment_amount": si.grand_total / 2
+		})
+		si.submit()
+		self.assertEqual(si.status, "Overdue")
+
+		# Test payment less than due amount
+		pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
+		pe.reference_no = "1"
+		pe.reference_date = nowdate()
+		pe.paid_amount = 1
+		pe.references[0].allocated_amount = pe.paid_amount
+		pe.submit()
+		si.reload()
+		self.assertEqual(si.status, "Overdue")
+
+		# Test Partly Paid
+		pe = frappe.copy_doc(pe)
+		pe.paid_amount = si.grand_total / 2
+		pe.references[0].allocated_amount = pe.paid_amount
+		pe.submit()
+		si.reload()
+		self.assertEqual(si.status, "Partly Paid")
+
+		# Test Paid
+		pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
+		pe.reference_no = "1"
+		pe.reference_date = nowdate()
+		pe.paid_amount = si.outstanding_amount
+		pe.submit()
+		si.reload()
+		self.assertEqual(si.status, "Paid")
+
 def get_sales_invoice_for_e_invoice():
 	si = make_sales_invoice_for_ewaybill()
 	si.naming_series = 'INV-2020-.#####'
@@ -2294,6 +2389,7 @@
 	if not frappe.db.exists('Address', '_Test Address for Eway bill-Billing'):
 		address = frappe.get_doc({
 			"address_line1": "_Test Address Line 1",
+			"address_line2": "_Test Address Line 2",
 			"address_title": "_Test Address for Eway bill",
 			"address_type": "Billing",
 			"city": "_Test City",
@@ -2315,11 +2411,12 @@
 
 		address.save()
 
-	if not frappe.db.exists('Address', '_Test Customer-Address for Eway bill-Shipping'):
+	if not frappe.db.exists('Address', '_Test Customer-Address for Eway bill-Billing'):
 		address = frappe.get_doc({
 			"address_line1": "_Test Address Line 1",
+			"address_line2": "_Test Address Line 2",
 			"address_title": "_Test Customer-Address for Eway bill",
-			"address_type": "Shipping",
+			"address_type": "Billing",
 			"city": "_Test City",
 			"state": "Test State",
 			"country": "India",
@@ -2339,9 +2436,34 @@
 
 		address.save()
 
+	if not frappe.db.exists('Address', '_Test Customer-Address for Eway bill-Shipping'):
+		address = frappe.get_doc({
+			"address_line1": "_Test Address Line 1",
+			"address_line2": "_Test Address Line 2",
+			"address_title": "_Test Customer-Address for Eway bill",
+			"address_type": "Shipping",
+			"city": "_Test City",
+			"state": "Test State",
+			"country": "India",
+			"doctype": "Address",
+			"is_primary_address": 1,
+			"phone": "+910000000000",
+			"gst_state": "Maharashtra",
+			"gst_state_number": "27",
+			"pincode": "410098"
+		}).insert()
+
+		address.append("links", {
+			"link_doctype": "Customer",
+			"link_name": "_Test Customer"
+		})
+
+		address.save()
+
 	if not frappe.db.exists('Address', '_Test Dispatch-Address for Eway bill-Shipping'):
 		address = frappe.get_doc({
 			"address_line1": "_Test Dispatch Address Line 1",
+			"address_line2": "_Test Dispatch Address Line 2",
 			"address_title": "_Test Dispatch-Address for Eway bill",
 			"address_type": "Shipping",
 			"city": "_Test City",
@@ -2356,11 +2478,6 @@
 			"pincode": "1100101"
 		}).insert()
 
-		address.append("links", {
-			"link_doctype": "Company",
-			"link_name": "_Test Company"
-		})
-
 		address.save()
 
 def make_test_transporter_for_ewaybill():
@@ -2400,7 +2517,8 @@
 
 	si.distance = 2000
 	si.company_address = "_Test Address for Eway bill-Billing"
-	si.customer_address = "_Test Customer-Address for Eway bill-Shipping"
+	si.customer_address = "_Test Customer-Address for Eway bill-Billing"
+	si.shipping_address_name = "_Test Customer-Address for Eway bill-Shipping"
 	si.dispatch_address_name = "_Test Dispatch-Address for Eway bill-Shipping"
 	si.vehicle_no = "KA12KA1234"
 	si.gst_category = "Registered Regular"
diff --git a/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json b/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json
index 29422d6..f92b57a 100644
--- a/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json
+++ b/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json
@@ -98,6 +98,7 @@
    "width": "120px"
   },
   {
+   "depends_on": "exchange_gain_loss",
    "fieldname": "exchange_gain_loss",
    "fieldtype": "Currency",
    "label": "Exchange Gain/Loss",
@@ -105,6 +106,7 @@
    "read_only": 1
   },
   {
+   "depends_on": "exchange_gain_loss",
    "fieldname": "ref_exchange_rate",
    "fieldtype": "Float",
    "label": "Reference Exchange Rate",
@@ -116,7 +118,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-06-04 20:25:49.832052",
+ "modified": "2021-09-26 15:47:46.911595",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice Advance",
diff --git a/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.json b/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.json
index c902973..69b7c12 100644
--- a/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.json
+++ b/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.json
@@ -7,12 +7,19 @@
  "field_order": [
   "activity_type",
   "description",
-  "billing_hours",
-  "billing_amount",
+  "section_break_3",
+  "from_time",
   "column_break_5",
+  "to_time",
+  "section_break_7",
+  "billing_hours",
+  "column_break_9",
+  "billing_amount",
+  "section_break_11",
   "time_sheet",
-  "project_name",
-  "timesheet_detail"
+  "timesheet_detail",
+  "column_break_13",
+  "project_name"
  ],
  "fields": [
   {
@@ -65,19 +72,52 @@
    "read_only": 1
   },
   {
+   "fieldname": "from_time",
+   "fieldtype": "Datetime",
+   "label": "From Time"
+  },
+  {
+   "fieldname": "to_time",
+   "fieldtype": "Datetime",
+   "label": "To Time"
+  },
+  {
+   "fieldname": "section_break_3",
+   "fieldtype": "Section Break",
+   "label": "Time"
+  },
+  {
    "fieldname": "column_break_5",
    "fieldtype": "Column Break"
   },
   {
+   "fieldname": "section_break_7",
+   "fieldtype": "Section Break",
+   "label": "Totals"
+  },
+  {
+   "fieldname": "column_break_9",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "section_break_11",
+   "fieldtype": "Section Break",
+   "label": "Reference"
+  },
+  {
    "fieldname": "project_name",
    "fieldtype": "Data",
    "label": "Project Name",
    "read_only": 1
+  },
+  {
+   "fieldname": "column_break_13",
+   "fieldtype": "Column Break"
   }
  ],
  "istable": 1,
  "links": [],
- "modified": "2021-06-08 14:43:02.748981",
+ "modified": "2021-10-02 03:48:44.979777",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice Timesheet",
diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py
index 445eb3c..8171b3b 100644
--- a/erpnext/accounts/doctype/subscription/subscription.py
+++ b/erpnext/accounts/doctype/subscription/subscription.py
@@ -400,6 +400,7 @@
 
 		invoice.flags.ignore_mandatory = True
 
+		invoice.set_missing_values()
 		invoice.save()
 
 		if self.submit_invoice:
diff --git a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
index b4bdd73..16ef5fc 100644
--- a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
+++ b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
@@ -9,11 +9,26 @@
 from frappe.model.document import Document
 from frappe.utils import cint, getdate
 
-from erpnext.accounts.utils import get_fiscal_year
-
 
 class TaxWithholdingCategory(Document):
-	pass
+	def validate(self):
+		self.validate_dates()
+		self.validate_thresholds()
+
+	def validate_dates(self):
+		last_date = None
+		for d in self.get('rates'):
+			if getdate(d.from_date) >= getdate(d.to_date):
+				frappe.throw(_("Row #{0}: From Date cannot be before To Date").format(d.idx))
+
+			# validate overlapping of dates
+			if last_date and getdate(d.to_date) < getdate(last_date):
+				frappe.throw(_("Row #{0}: Dates overlapping with other row").format(d.idx))
+
+	def validate_thresholds(self):
+		for d in self.get('rates'):
+			if d.cumulative_threshold and d.cumulative_threshold < d.single_threshold:
+				frappe.throw(_("Row #{0}: Cumulative threshold cannot be less than Single Transaction threshold").format(d.idx))
 
 def get_party_details(inv):
 	party_type, party = '', ''
@@ -52,8 +67,8 @@
 	if not parties:
 		parties.append(party)
 
-	fiscal_year = get_fiscal_year(inv.get('posting_date') or inv.get('transaction_date'), company=inv.company)
-	tax_details = get_tax_withholding_details(tax_withholding_category, fiscal_year[0], inv.company)
+	posting_date = inv.get('posting_date') or inv.get('transaction_date')
+	tax_details = get_tax_withholding_details(tax_withholding_category, posting_date, inv.company)
 
 	if not tax_details:
 		frappe.throw(_('Please set associated account in Tax Withholding Category {0} against Company {1}')
@@ -67,7 +82,7 @@
 	tax_amount, tax_deducted = get_tax_amount(
 		party_type, parties,
 		inv, tax_details,
-		fiscal_year, pan_no
+		posting_date, pan_no
 	)
 
 	if party_type == 'Supplier':
@@ -77,16 +92,19 @@
 
 	return tax_row
 
-def get_tax_withholding_details(tax_withholding_category, fiscal_year, company):
+def get_tax_withholding_details(tax_withholding_category, posting_date, company):
 	tax_withholding = frappe.get_doc("Tax Withholding Category", tax_withholding_category)
 
-	tax_rate_detail = get_tax_withholding_rates(tax_withholding, fiscal_year)
+	tax_rate_detail = get_tax_withholding_rates(tax_withholding, posting_date)
 
 	for account_detail in tax_withholding.accounts:
 		if company == account_detail.company:
 			return frappe._dict({
+				"tax_withholding_category": tax_withholding_category,
 				"account_head": account_detail.account,
 				"rate": tax_rate_detail.tax_withholding_rate,
+				"from_date": tax_rate_detail.from_date,
+				"to_date": tax_rate_detail.to_date,
 				"threshold": tax_rate_detail.single_threshold,
 				"cumulative_threshold": tax_rate_detail.cumulative_threshold,
 				"description": tax_withholding.category_name if tax_withholding.category_name else tax_withholding_category,
@@ -95,13 +113,13 @@
 				"round_off_tax_amount": tax_withholding.round_off_tax_amount
 			})
 
-def get_tax_withholding_rates(tax_withholding, fiscal_year):
+def get_tax_withholding_rates(tax_withholding, posting_date):
 	# returns the row that matches with the fiscal year from posting date
 	for rate in tax_withholding.rates:
-		if rate.fiscal_year == fiscal_year:
+		if getdate(rate.from_date) <= getdate(posting_date) <= getdate(rate.to_date):
 			return rate
 
-	frappe.throw(_("No Tax Withholding data found for the current Fiscal Year."))
+	frappe.throw(_("No Tax Withholding data found for the current posting date."))
 
 def get_tax_row_for_tcs(inv, tax_details, tax_amount, tax_deducted):
 	row = {
@@ -143,38 +161,38 @@
 		"account_head": tax_details.account_head
 	}
 
-def get_lower_deduction_certificate(fiscal_year, pan_no):
-	ldc_name = frappe.db.get_value('Lower Deduction Certificate', { 'pan_no': pan_no, 'fiscal_year': fiscal_year }, 'name')
+def get_lower_deduction_certificate(tax_details, pan_no):
+	ldc_name = frappe.db.get_value('Lower Deduction Certificate',
+		{
+			'pan_no': pan_no,
+			'valid_from': ('>=', tax_details.from_date),
+			'valid_upto': ('<=', tax_details.to_date)
+		}, 'name')
+
 	if ldc_name:
 		return frappe.get_doc('Lower Deduction Certificate', ldc_name)
 
-def get_tax_amount(party_type, parties, inv, tax_details, fiscal_year_details, pan_no=None):
-	fiscal_year = fiscal_year_details[0]
-
-
-	vouchers = get_invoice_vouchers(parties, fiscal_year, inv.company, party_type=party_type)
-	advance_vouchers = get_advance_vouchers(parties, fiscal_year, inv.company, party_type=party_type)
+def get_tax_amount(party_type, parties, inv, tax_details, posting_date, pan_no=None):
+	vouchers = get_invoice_vouchers(parties, tax_details, inv.company, party_type=party_type)
+	advance_vouchers = get_advance_vouchers(parties, company=inv.company, from_date=tax_details.from_date,
+		to_date=tax_details.to_date, party_type=party_type)
 	taxable_vouchers = vouchers + advance_vouchers
 
 	tax_deducted = 0
 	if taxable_vouchers:
-		tax_deducted = get_deducted_tax(taxable_vouchers, fiscal_year, tax_details)
+		tax_deducted = get_deducted_tax(taxable_vouchers, tax_details)
 
 	tax_amount = 0
-	posting_date = inv.get('posting_date') or inv.get('transaction_date')
 	if party_type == 'Supplier':
-		ldc = get_lower_deduction_certificate(fiscal_year, pan_no)
+		ldc = get_lower_deduction_certificate(tax_details, pan_no)
 		if tax_deducted:
 			net_total = inv.net_total
 			if ldc:
-				tax_amount = get_tds_amount_from_ldc(ldc, parties, fiscal_year, pan_no, tax_details, posting_date, net_total)
+				tax_amount = get_tds_amount_from_ldc(ldc, parties, pan_no, tax_details, posting_date, net_total)
 			else:
 				tax_amount = net_total * tax_details.rate / 100 if net_total > 0 else 0
 		else:
-			tax_amount = get_tds_amount(
-				ldc, parties, inv, tax_details,
-				fiscal_year_details, tax_deducted, vouchers
-			)
+			tax_amount = get_tds_amount(ldc, parties, inv, tax_details, tax_deducted, vouchers)
 
 	elif party_type == 'Customer':
 		if tax_deducted:
@@ -183,29 +201,47 @@
 		else:
 			#  if no TCS has been charged in FY,
 			# then chargeable value is "prev invoices + advances" value which cross the threshold
-			tax_amount = get_tcs_amount(
-				parties, inv, tax_details,
-				fiscal_year_details, vouchers, advance_vouchers
-			)
+			tax_amount = get_tcs_amount(parties, inv, tax_details, vouchers, advance_vouchers)
 
 	return tax_amount, tax_deducted
 
-def get_invoice_vouchers(parties, fiscal_year, company, party_type='Supplier'):
+def get_invoice_vouchers(parties, tax_details, company, party_type='Supplier'):
 	dr_or_cr = 'credit' if party_type == 'Supplier' else 'debit'
+	doctype = 'Purchase Invoice' if party_type == 'Supplier' else 'Sales Invoice'
 
 	filters = {
-		dr_or_cr: ['>', 0],
 		'company': company,
-		'party_type': party_type,
-		'party': ['in', parties],
-		'fiscal_year': fiscal_year,
+		frappe.scrub(party_type): ['in', parties],
+		'posting_date': ['between', (tax_details.from_date, tax_details.to_date)],
 		'is_opening': 'No',
-		'is_cancelled': 0
+		'docstatus': 1
 	}
 
-	return frappe.get_all('GL Entry', filters=filters, distinct=1, pluck="voucher_no") or [""]
+	if not tax_details.get('consider_party_ledger_amount') and doctype != "Sales Invoice":
+		filters.update({
+			'apply_tds': 1,
+			'tax_withholding_category': tax_details.get('tax_withholding_category')
+		})
 
-def get_advance_vouchers(parties, fiscal_year=None, company=None, from_date=None, to_date=None, party_type='Supplier'):
+	invoices = frappe.get_all(doctype, filters=filters, pluck="name") or [""]
+
+	journal_entries = frappe.db.sql("""
+		SELECT j.name
+			FROM `tabJournal Entry` j, `tabJournal Entry Account` ja
+		WHERE
+			j.docstatus = 1
+			AND j.is_opening = 'No'
+			AND j.posting_date between %s and %s
+			AND ja.{dr_or_cr} > 0
+			AND ja.party in %s
+	""".format(dr_or_cr=dr_or_cr), (tax_details.from_date, tax_details.to_date, tuple(parties)), as_list=1)
+
+	if journal_entries:
+		journal_entries = journal_entries[0]
+
+	return invoices + journal_entries
+
+def get_advance_vouchers(parties, company=None, from_date=None, to_date=None, party_type='Supplier'):
 	# for advance vouchers, debit and credit is reversed
 	dr_or_cr = 'debit' if party_type == 'Supplier' else 'credit'
 
@@ -218,8 +254,6 @@
 		'against_voucher': ['is', 'not set']
 	}
 
-	if fiscal_year:
-		filters['fiscal_year'] = fiscal_year
 	if company:
 		filters['company'] = company
 	if from_date and to_date:
@@ -227,20 +261,21 @@
 
 	return frappe.get_all('GL Entry', filters=filters, distinct=1, pluck='voucher_no') or [""]
 
-def get_deducted_tax(taxable_vouchers, fiscal_year, tax_details):
+def get_deducted_tax(taxable_vouchers, tax_details):
 	# check if TDS / TCS account is already charged on taxable vouchers
 	filters = {
 		'is_cancelled': 0,
 		'credit': ['>', 0],
-		'fiscal_year': fiscal_year,
+		'posting_date': ['between', (tax_details.from_date, tax_details.to_date)],
 		'account': tax_details.account_head,
 		'voucher_no': ['in', taxable_vouchers],
 	}
-	field = "sum(credit)"
+	field = "credit"
 
-	return frappe.db.get_value('GL Entry', filters, field) or 0.0
+	entries = frappe.db.get_all('GL Entry', filters, pluck=field)
+	return sum(entries)
 
-def get_tds_amount(ldc, parties, inv, tax_details, fiscal_year_details, tax_deducted, vouchers):
+def get_tds_amount(ldc, parties, inv, tax_details, tax_deducted, vouchers):
 	tds_amount = 0
 	invoice_filters = {
 		'name': ('in', vouchers),
@@ -264,7 +299,7 @@
 	supp_credit_amt += supp_jv_credit_amt
 	supp_credit_amt += inv.net_total
 
-	debit_note_amount = get_debit_note_amount(parties, fiscal_year_details, inv.company)
+	debit_note_amount = get_debit_note_amount(parties, tax_details.from_date, tax_details.to_date, inv.company)
 	supp_credit_amt -= debit_note_amount
 
 	threshold = tax_details.get('threshold', 0)
@@ -292,9 +327,8 @@
 
 	return tds_amount
 
-def get_tcs_amount(parties, inv, tax_details, fiscal_year_details, vouchers, adv_vouchers):
+def get_tcs_amount(parties, inv, tax_details, vouchers, adv_vouchers):
 	tcs_amount = 0
-	fiscal_year, _, _ = fiscal_year_details
 
 	# sum of debit entries made from sales invoices
 	invoiced_amt = frappe.db.get_value('GL Entry', {
@@ -313,14 +347,14 @@
 	}, 'sum(credit)') or 0.0
 
 	# sum of credit entries made from sales invoice
-	credit_note_amt = frappe.db.get_value('GL Entry', {
+	credit_note_amt = sum(frappe.db.get_all('GL Entry', {
 		'is_cancelled': 0,
 		'credit': ['>', 0],
 		'party': ['in', parties],
-		'fiscal_year': fiscal_year,
+		'posting_date': ['between', (tax_details.from_date, tax_details.to_date)],
 		'company': inv.company,
 		'voucher_type': 'Sales Invoice',
-	}, 'sum(credit)') or 0.0
+	}, pluck='credit'))
 
 	cumulative_threshold = tax_details.get('cumulative_threshold', 0)
 
@@ -339,7 +373,7 @@
 
 	return inv.grand_total - tcs_tax_row_amount
 
-def get_tds_amount_from_ldc(ldc, parties, fiscal_year, pan_no, tax_details, posting_date, net_total):
+def get_tds_amount_from_ldc(ldc, parties, pan_no, tax_details, posting_date, net_total):
 	tds_amount = 0
 	limit_consumed = frappe.db.get_value('Purchase Invoice', {
 		'supplier': ('in', parties),
@@ -356,14 +390,13 @@
 
 	return tds_amount
 
-def get_debit_note_amount(suppliers, fiscal_year_details, company=None):
-	_, year_start_date, year_end_date = fiscal_year_details
+def get_debit_note_amount(suppliers, from_date, to_date, company=None):
 
 	filters = {
 		'supplier': ['in', suppliers],
 		'is_return': 1,
 		'docstatus': 1,
-		'posting_date': ['between', (year_start_date, year_end_date)]
+		'posting_date': ['between', (from_date, to_date)]
 	}
 	fields = ['abs(sum(net_total)) as net_total']
 
diff --git a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py
index c4a5ba5..84b364b 100644
--- a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py
+++ b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py
@@ -176,6 +176,29 @@
 		for d in invoices:
 			d.cancel()
 
+	def test_multi_category_single_supplier(self):
+		frappe.db.set_value("Supplier", "Test TDS Supplier5", "tax_withholding_category", "Test Service Category")
+		invoices = []
+
+		pi = create_purchase_invoice(supplier = "Test TDS Supplier5", rate = 500, do_not_save=True)
+		pi.tax_withholding_category = "Test Service Category"
+		pi.save()
+		pi.submit()
+		invoices.append(pi)
+
+		# Second Invoice will apply TDS checked
+		pi1 = create_purchase_invoice(supplier = "Test TDS Supplier5", rate = 2500, do_not_save=True)
+		pi1.tax_withholding_category = "Test Goods Category"
+		pi1.save()
+		pi1.submit()
+		invoices.append(pi1)
+
+		self.assertEqual(pi1.taxes[0].tax_amount, 250)
+
+		#delete invoices to avoid clashing
+		for d in invoices:
+			d.cancel()
+
 def cancel_invoices():
 	purchase_invoices = frappe.get_all("Purchase Invoice", {
 		'supplier': ['in', ['Test TDS Supplier', 'Test TDS Supplier1', 'Test TDS Supplier2']],
@@ -251,7 +274,8 @@
 
 def create_records():
 	# create a new suppliers
-	for name in ['Test TDS Supplier', 'Test TDS Supplier1', 'Test TDS Supplier2', 'Test TDS Supplier3', 'Test TDS Supplier4']:
+	for name in ['Test TDS Supplier', 'Test TDS Supplier1', 'Test TDS Supplier2', 'Test TDS Supplier3',
+		'Test TDS Supplier4', 'Test TDS Supplier5']:
 		if frappe.db.exists('Supplier', name):
 			continue
 
@@ -313,16 +337,16 @@
 		}).insert()
 
 def create_tax_with_holding_category():
-	fiscal_year = get_fiscal_year(today(), company="_Test Company")[0]
-
-	# Cummulative thresold
+	fiscal_year = get_fiscal_year(today(), company="_Test Company")
+	# Cumulative threshold
 	if not frappe.db.exists("Tax Withholding Category", "Cumulative Threshold TDS"):
 		frappe.get_doc({
 			"doctype": "Tax Withholding Category",
 			"name": "Cumulative Threshold TDS",
 			"category_name": "10% TDS",
 			"rates": [{
-				'fiscal_year': fiscal_year,
+				'from_date': fiscal_year[1],
+				'to_date': fiscal_year[2],
 				'tax_withholding_rate': 10,
 				'single_threshold': 0,
 				'cumulative_threshold': 30000.00
@@ -339,7 +363,8 @@
 			"name": "Cumulative Threshold TCS",
 			"category_name": "10% TCS",
 			"rates": [{
-				'fiscal_year': fiscal_year,
+				'from_date': fiscal_year[1],
+				'to_date': fiscal_year[2],
 				'tax_withholding_rate': 10,
 				'single_threshold': 0,
 				'cumulative_threshold': 30000.00
@@ -357,7 +382,8 @@
 			"name": "Single Threshold TDS",
 			"category_name": "10% TDS",
 			"rates": [{
-				'fiscal_year': fiscal_year,
+				'from_date': fiscal_year[1],
+				'to_date': fiscal_year[2],
 				'tax_withholding_rate': 10,
 				'single_threshold': 20000.00,
 				'cumulative_threshold': 0
@@ -377,7 +403,8 @@
 			"consider_party_ledger_amount": 1,
 			"tax_on_excess_amount": 1,
 			"rates": [{
-				'fiscal_year': fiscal_year,
+				'from_date': fiscal_year[1],
+				'to_date': fiscal_year[2],
 				'tax_withholding_rate': 10,
 				'single_threshold': 0,
 				'cumulative_threshold': 30000
@@ -387,3 +414,39 @@
 				'account': 'TDS - _TC'
 			}]
 		}).insert()
+
+	if not frappe.db.exists("Tax Withholding Category", "Test Service Category"):
+		frappe.get_doc({
+			"doctype": "Tax Withholding Category",
+			"name": "Test Service Category",
+			"category_name": "Test Service Category",
+			"rates": [{
+				'from_date': fiscal_year[1],
+				'to_date': fiscal_year[2],
+				'tax_withholding_rate': 10,
+				'single_threshold': 2000,
+				'cumulative_threshold': 2000
+			}],
+			"accounts": [{
+				'company': '_Test Company',
+				'account': 'TDS - _TC'
+			}]
+		}).insert()
+
+	if not frappe.db.exists("Tax Withholding Category", "Test Goods Category"):
+		frappe.get_doc({
+			"doctype": "Tax Withholding Category",
+			"name": "Test Goods Category",
+			"category_name": "Test Goods Category",
+			"rates": [{
+				'from_date': fiscal_year[1],
+				'to_date': fiscal_year[2],
+				'tax_withholding_rate': 10,
+				'single_threshold': 2000,
+				'cumulative_threshold': 2000
+			}],
+			"accounts": [{
+				'company': '_Test Company',
+				'account': 'TDS - _TC'
+			}]
+		}).insert()
diff --git a/erpnext/accounts/doctype/tax_withholding_rate/tax_withholding_rate.json b/erpnext/accounts/doctype/tax_withholding_rate/tax_withholding_rate.json
index 1e8194a..d2c505c 100644
--- a/erpnext/accounts/doctype/tax_withholding_rate/tax_withholding_rate.json
+++ b/erpnext/accounts/doctype/tax_withholding_rate/tax_withholding_rate.json
@@ -1,202 +1,72 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "beta": 0, 
- "creation": "2018-07-17 16:53:13.716665", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "creation": "2018-07-17 16:53:13.716665",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "from_date",
+  "to_date",
+  "tax_withholding_rate",
+  "column_break_3",
+  "single_threshold",
+  "cumulative_threshold"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 2, 
-   "fieldname": "fiscal_year", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Fiscal Year", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Fiscal Year", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "columns": 1,
+   "fieldname": "tax_withholding_rate",
+   "fieldtype": "Float",
+   "in_list_view": 1,
+   "label": "Tax Withholding Rate",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 2, 
-   "fieldname": "tax_withholding_rate", 
-   "fieldtype": "Float", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Tax Withholding Rate", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_3", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "columns": 2,
+   "fieldname": "single_threshold",
+   "fieldtype": "Currency",
+   "in_list_view": 1,
+   "label": "Single Transaction Threshold"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 3, 
-   "fieldname": "single_threshold", 
-   "fieldtype": "Currency", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Single Transaction Threshold", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "columns": 3,
+   "fieldname": "cumulative_threshold",
+   "fieldtype": "Currency",
+   "in_list_view": 1,
+   "label": "Cumulative Transaction Threshold"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 3, 
-   "fieldname": "cumulative_threshold", 
-   "fieldtype": "Currency", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Cumulative Transaction Threshold", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
+   "columns": 2,
+   "fieldname": "from_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "From Date",
+   "reqd": 1
+  },
+  {
+   "columns": 2,
+   "fieldname": "to_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "To Date",
+   "reqd": 1
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 1, 
- "max_attachments": 0, 
- "modified": "2018-07-17 17:13:09.819580", 
- "modified_by": "Administrator", 
- "module": "Accounts", 
- "name": "Tax Withholding Rate", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0, 
- "track_views": 0
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2021-08-31 11:42:12.213977",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Tax Withholding Rate",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index 4bf2b82..0cee6f5 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -284,13 +284,16 @@
 	"""
 		Nobody can do GL Entries where posting date is before freezing date
 		except authorized person
+
+		Administrator has all the roles so this check will be bypassed if any role is allowed to post
+		Hence stop admin to bypass if accounts are freezed
 	"""
 	if not adv_adj:
 		acc_frozen_upto = frappe.db.get_value('Accounts Settings', None, 'acc_frozen_upto')
 		if acc_frozen_upto:
 			frozen_accounts_modifier = frappe.db.get_value( 'Accounts Settings', None,'frozen_accounts_modifier')
 			if getdate(posting_date) <= getdate(acc_frozen_upto) \
-					and not frozen_accounts_modifier in frappe.get_roles():
+					and not frozen_accounts_modifier in frappe.get_roles() or frappe.session.user == 'Administrator':
 				frappe.throw(_("You are not authorized to add or update entries before {0}").format(formatdate(acc_frozen_upto)))
 
 def set_as_cancel(voucher_type, voucher_no):
diff --git a/erpnext/accounts/report/accounts_payable/accounts_payable.js b/erpnext/accounts/report/accounts_payable/accounts_payable.js
index b6c6689..81c60bb 100644
--- a/erpnext/accounts/report/accounts_payable/accounts_payable.js
+++ b/erpnext/accounts/report/accounts_payable/accounts_payable.js
@@ -4,7 +4,7 @@
 frappe.query_reports["Accounts Payable"] = {
 	"filters": [
 		{
-			"fieldname":"company",
+			"fieldname": "company",
 			"label": __("Company"),
 			"fieldtype": "Link",
 			"options": "Company",
@@ -12,19 +12,19 @@
 			"default": frappe.defaults.get_user_default("Company")
 		},
 		{
-			"fieldname":"report_date",
+			"fieldname": "report_date",
 			"label": __("Posting Date"),
 			"fieldtype": "Date",
 			"default": frappe.datetime.get_today()
 		},
 		{
-			"fieldname":"finance_book",
+			"fieldname": "finance_book",
 			"label": __("Finance Book"),
 			"fieldtype": "Link",
 			"options": "Finance Book"
 		},
 		{
-			"fieldname":"cost_center",
+			"fieldname": "cost_center",
 			"label": __("Cost Center"),
 			"fieldtype": "Link",
 			"options": "Cost Center",
@@ -38,7 +38,7 @@
 			}
 		},
 		{
-			"fieldname":"supplier",
+			"fieldname": "supplier",
 			"label": __("Supplier"),
 			"fieldtype": "Link",
 			"options": "Supplier",
@@ -54,48 +54,48 @@
 			}
 		},
 		{
-			"fieldname":"ageing_based_on",
+			"fieldname": "ageing_based_on",
 			"label": __("Ageing Based On"),
 			"fieldtype": "Select",
 			"options": 'Posting Date\nDue Date\nSupplier Invoice Date',
 			"default": "Due Date"
 		},
 		{
-			"fieldname":"range1",
+			"fieldname": "range1",
 			"label": __("Ageing Range 1"),
 			"fieldtype": "Int",
 			"default": "30",
 			"reqd": 1
 		},
 		{
-			"fieldname":"range2",
+			"fieldname": "range2",
 			"label": __("Ageing Range 2"),
 			"fieldtype": "Int",
 			"default": "60",
 			"reqd": 1
 		},
 		{
-			"fieldname":"range3",
+			"fieldname": "range3",
 			"label": __("Ageing Range 3"),
 			"fieldtype": "Int",
 			"default": "90",
 			"reqd": 1
 		},
 		{
-			"fieldname":"range4",
+			"fieldname": "range4",
 			"label": __("Ageing Range 4"),
 			"fieldtype": "Int",
 			"default": "120",
 			"reqd": 1
 		},
 		{
-			"fieldname":"payment_terms_template",
+			"fieldname": "payment_terms_template",
 			"label": __("Payment Terms Template"),
 			"fieldtype": "Link",
 			"options": "Payment Terms Template"
 		},
 		{
-			"fieldname":"supplier_group",
+			"fieldname": "supplier_group",
 			"label": __("Supplier Group"),
 			"fieldtype": "Link",
 			"options": "Supplier Group"
@@ -106,12 +106,17 @@
 			"fieldtype": "Check"
 		},
 		{
-			"fieldname":"based_on_payment_terms",
+			"fieldname": "based_on_payment_terms",
 			"label": __("Based On Payment Terms"),
 			"fieldtype": "Check",
 		},
 		{
-			"fieldname":"tax_id",
+			"fieldname": "show_remarks",
+			"label": __("Show Remarks"),
+			"fieldtype": "Check",
+		},
+		{
+			"fieldname": "tax_id",
 			"label": __("Tax Id"),
 			"fieldtype": "Data",
 			"hidden": 1
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
index 1a32e2a..5700298 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
@@ -4,7 +4,7 @@
 frappe.query_reports["Accounts Receivable"] = {
 	"filters": [
 		{
-			"fieldname":"company",
+			"fieldname": "company",
 			"label": __("Company"),
 			"fieldtype": "Link",
 			"options": "Company",
@@ -12,19 +12,19 @@
 			"default": frappe.defaults.get_user_default("Company")
 		},
 		{
-			"fieldname":"report_date",
+			"fieldname": "report_date",
 			"label": __("Posting Date"),
 			"fieldtype": "Date",
 			"default": frappe.datetime.get_today()
 		},
 		{
-			"fieldname":"finance_book",
+			"fieldname": "finance_book",
 			"label": __("Finance Book"),
 			"fieldtype": "Link",
 			"options": "Finance Book"
 		},
 		{
-			"fieldname":"cost_center",
+			"fieldname": "cost_center",
 			"label": __("Cost Center"),
 			"fieldtype": "Link",
 			"options": "Cost Center",
@@ -38,7 +38,7 @@
 			}
 		},
 		{
-			"fieldname":"customer",
+			"fieldname": "customer",
 			"label": __("Customer"),
 			"fieldtype": "Link",
 			"options": "Customer",
@@ -67,66 +67,66 @@
 			}
 		},
 		{
-			"fieldname":"ageing_based_on",
+			"fieldname": "ageing_based_on",
 			"label": __("Ageing Based On"),
 			"fieldtype": "Select",
 			"options": 'Posting Date\nDue Date',
 			"default": "Due Date"
 		},
 		{
-			"fieldname":"range1",
+			"fieldname": "range1",
 			"label": __("Ageing Range 1"),
 			"fieldtype": "Int",
 			"default": "30",
 			"reqd": 1
 		},
 		{
-			"fieldname":"range2",
+			"fieldname": "range2",
 			"label": __("Ageing Range 2"),
 			"fieldtype": "Int",
 			"default": "60",
 			"reqd": 1
 		},
 		{
-			"fieldname":"range3",
+			"fieldname": "range3",
 			"label": __("Ageing Range 3"),
 			"fieldtype": "Int",
 			"default": "90",
 			"reqd": 1
 		},
 		{
-			"fieldname":"range4",
+			"fieldname": "range4",
 			"label": __("Ageing Range 4"),
 			"fieldtype": "Int",
 			"default": "120",
 			"reqd": 1
 		},
 		{
-			"fieldname":"customer_group",
+			"fieldname": "customer_group",
 			"label": __("Customer Group"),
 			"fieldtype": "Link",
 			"options": "Customer Group"
 		},
 		{
-			"fieldname":"payment_terms_template",
+			"fieldname": "payment_terms_template",
 			"label": __("Payment Terms Template"),
 			"fieldtype": "Link",
 			"options": "Payment Terms Template"
 		},
 		{
-			"fieldname":"sales_partner",
+			"fieldname": "sales_partner",
 			"label": __("Sales Partner"),
 			"fieldtype": "Link",
 			"options": "Sales Partner"
 		},
 		{
-			"fieldname":"sales_person",
+			"fieldname": "sales_person",
 			"label": __("Sales Person"),
 			"fieldtype": "Link",
 			"options": "Sales Person"
 		},
 		{
-			"fieldname":"territory",
+			"fieldname": "territory",
 			"label": __("Territory"),
 			"fieldtype": "Link",
 			"options": "Territory"
@@ -137,45 +137,50 @@
 			"fieldtype": "Check"
 		},
 		{
-			"fieldname":"based_on_payment_terms",
+			"fieldname": "based_on_payment_terms",
 			"label": __("Based On Payment Terms"),
 			"fieldtype": "Check",
 		},
 		{
-			"fieldname":"show_future_payments",
+			"fieldname": "show_future_payments",
 			"label": __("Show Future Payments"),
 			"fieldtype": "Check",
 		},
 		{
-			"fieldname":"show_delivery_notes",
+			"fieldname": "show_delivery_notes",
 			"label": __("Show Linked Delivery Notes"),
 			"fieldtype": "Check",
 		},
 		{
-			"fieldname":"show_sales_person",
+			"fieldname": "show_sales_person",
 			"label": __("Show Sales Person"),
 			"fieldtype": "Check",
 		},
 		{
-			"fieldname":"tax_id",
+			"fieldname": "show_remarks",
+			"label": __("Show Remarks"),
+			"fieldtype": "Check",
+		},
+		{
+			"fieldname": "tax_id",
 			"label": __("Tax Id"),
 			"fieldtype": "Data",
 			"hidden": 1
 		},
 		{
-			"fieldname":"customer_name",
+			"fieldname": "customer_name",
 			"label": __("Customer Name"),
 			"fieldtype": "Data",
 			"hidden": 1
 		},
 		{
-			"fieldname":"payment_terms",
+			"fieldname": "payment_terms",
 			"label": __("Payment Tems"),
 			"fieldtype": "Data",
 			"hidden": 1
 		},
 		{
-			"fieldname":"credit_limit",
+			"fieldname": "credit_limit",
 			"label": __("Credit Limit"),
 			"fieldtype": "Currency",
 			"hidden": 1
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index e91fdf2..7f8eade 100755
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -106,6 +106,7 @@
 					party = gle.party,
 					posting_date = gle.posting_date,
 					account_currency = gle.account_currency,
+					remarks = gle.remarks if self.filters.get("show_remarks") else None,
 					invoiced = 0.0,
 					paid = 0.0,
 					credit_note = 0.0,
@@ -583,10 +584,12 @@
 		else:
 			select_fields = "debit, credit"
 
+		remarks = ", remarks" if self.filters.get("show_remarks") else ""
+
 		self.gl_entries = frappe.db.sql("""
 			select
 				name, posting_date, account, party_type, party, voucher_type, voucher_no, cost_center,
-				against_voucher_type, against_voucher, account_currency, {0}
+				against_voucher_type, against_voucher, account_currency, {0} {remarks}
 			from
 				`tabGL Entry`
 			where
@@ -595,7 +598,7 @@
 				and party_type=%s
 				and (party is not null and party != '')
 				{1} {2} {3}"""
-			.format(select_fields, date_condition, conditions, order_by), values, as_dict=True)
+			.format(select_fields, date_condition, conditions, order_by, remarks=remarks), values, as_dict=True)
 
 	def get_sales_invoices_or_customers_based_on_sales_person(self):
 		if self.filters.get("sales_person"):
@@ -754,6 +757,10 @@
 		self.add_column(label=_('Voucher Type'), fieldname='voucher_type', fieldtype='Data')
 		self.add_column(label=_('Voucher No'), fieldname='voucher_no', fieldtype='Dynamic Link',
 			options='voucher_type', width=180)
+
+		if self.filters.show_remarks:
+			self.add_column(label=_('Remarks'), fieldname='remarks', fieldtype='Text', width=200),
+
 		self.add_column(label='Due Date', fieldtype='Date')
 
 		if self.party_type == "Supplier":
diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py
index d527188..bb8138b 100644
--- a/erpnext/accounts/report/cash_flow/cash_flow.py
+++ b/erpnext/accounts/report/cash_flow/cash_flow.py
@@ -139,9 +139,9 @@
 	data["total"] = total
 	return data
 
-def get_account_type_based_gl_data(company, start_date, end_date, account_type, filters={}):
+def get_account_type_based_gl_data(company, start_date, end_date, account_type, filters=None):
 	cond = ""
-	filters = frappe._dict(filters)
+	filters = frappe._dict(filters or {})
 
 	if filters.include_default_book_entries:
 		company_fb = frappe.db.get_value("Company", company, 'default_finance_book')
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 e419727..b0cfbac 100644
--- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
+++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
@@ -260,7 +260,12 @@
 def calculate_values(accounts_by_name, gl_entries_by_account, companies, start_date, filters):
 	for entries in gl_entries_by_account.values():
 		for entry in entries:
-			d = accounts_by_name.get(entry.account_name)
+			if entry.account_number:
+				account_name = entry.account_number + ' - ' + entry.account_name
+			else:
+				account_name =  entry.account_name
+
+			d = accounts_by_name.get(account_name)
 			if d:
 				for company in companies:
 					# check if posting date is within the period
@@ -307,7 +312,14 @@
 		of account_number and suffix of company abbr. This function adds key called
 		`parent_account_name` which does not have such prefix/suffix.
 	"""
-	name_to_account_map = { d.name : d.account_name for d in accounts }
+	name_to_account_map = {}
+
+	for d in accounts:
+		if d.account_number:
+			account_name = d.account_number + ' - ' + d.account_name
+		else:
+			account_name =  d.account_name
+		name_to_account_map[d.name] = account_name
 
 	for account in accounts:
 		if account.parent_account:
@@ -420,7 +432,11 @@
 			convert_to_presentation_currency(gl_entries, currency_info, filters.get('company'))
 
 		for entry in gl_entries:
-			account_name =  entry.account_name
+			if entry.account_number:
+				account_name = entry.account_number + ' - ' + entry.account_name
+			else:
+				account_name =  entry.account_name
+
 			validate_entries(account_name, entry, accounts_by_name, accounts)
 			gl_entries_by_account.setdefault(account_name, []).append(entry)
 
@@ -491,7 +507,12 @@
 	parent_children_map = {}
 	accounts_by_name = {}
 	for d in accounts:
-		accounts_by_name[d.account_name] = d
+		if d.account_number:
+			account_name = d.account_number + ' - ' + d.account_name
+		else:
+			account_name =  d.account_name
+		accounts_by_name[account_name] = d
+
 		parent_children_map.setdefault(d.parent_account or None, []).append(d)
 
 	filtered_accounts = []
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js
index 095f5ed..b296876 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.js
+++ b/erpnext/accounts/report/general_ledger/general_ledger.js
@@ -110,9 +110,26 @@
 			"fieldname":"group_by",
 			"label": __("Group by"),
 			"fieldtype": "Select",
-			"options": ["", __("Group by Voucher"), __("Group by Voucher (Consolidated)"),
-				__("Group by Account"), __("Group by Party")],
-			"default": __("Group by Voucher (Consolidated)")
+			"options": [
+				"",
+				{
+					label: __("Group by Voucher"),
+					value: "Group by Voucher",
+				},
+				{
+					label: __("Group by Voucher (Consolidated)"),
+					value: "Group by Voucher (Consolidated)",
+				},
+				{
+					label: __("Group by Account"),
+					value: "Group by Account",
+				},
+				{
+					label: __("Group by Party"),
+					value: "Group by Party",
+				},
+			],
+			"default": "Group by Voucher (Consolidated)"
 		},
 		{
 			"fieldname":"tax_id",
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index a044518..5bd6e58 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -62,14 +62,14 @@
 			if not account_details.get(account):
 				frappe.throw(_("Account {0} does not exists").format(account))
 
-	if (filters.get("account") and filters.get("group_by") == _('Group by Account')):
+	if (filters.get("account") and filters.get("group_by") == 'Group by Account'):
 		filters.account = frappe.parse_json(filters.get('account'))
 		for account in filters.account:
 			if account_details[account].is_group == 0:
 				frappe.throw(_("Can not filter based on Child Account, if grouped by Account"))
 
 	if (filters.get("voucher_no")
-		and filters.get("group_by") in [_('Group by Voucher')]):
+		and filters.get("group_by") in ['Group by Voucher']):
 		frappe.throw(_("Can not filter based on Voucher No, if grouped by Voucher"))
 
 	if filters.from_date > filters.to_date:
@@ -153,7 +153,7 @@
 	if filters.get("include_dimensions"):
 		order_by_statement = "order by posting_date, creation"
 
-	if filters.get("group_by") == _("Group by Voucher"):
+	if filters.get("group_by") == "Group by Voucher":
 		order_by_statement = "order by posting_date, voucher_type, voucher_no"
 
 	if filters.get("include_default_book_entries"):
@@ -312,13 +312,13 @@
 	# Opening for filtered account
 	data.append(totals.opening)
 
-	if filters.get("group_by") != _('Group by Voucher (Consolidated)'):
+	if filters.get("group_by") != 'Group by Voucher (Consolidated)':
 		for acc, acc_dict in iteritems(gle_map):
 			# acc
 			if acc_dict.entries:
 				# opening
 				data.append({})
-				if filters.get("group_by") != _("Group by Voucher"):
+				if filters.get("group_by") != "Group by Voucher":
 					data.append(acc_dict.totals.opening)
 
 				data += acc_dict.entries
@@ -327,7 +327,7 @@
 				data.append(acc_dict.totals.total)
 
 				# closing
-				if filters.get("group_by") != _("Group by Voucher"):
+				if filters.get("group_by") != "Group by Voucher":
 					data.append(acc_dict.totals.closing)
 		data.append({})
 	else:
@@ -357,9 +357,9 @@
 	)
 
 def group_by_field(group_by):
-	if group_by == _('Group by Party'):
+	if group_by == 'Group by Party':
 		return 'party'
-	elif group_by in [_('Group by Voucher (Consolidated)'), _('Group by Account')]:
+	elif group_by in ['Group by Voucher (Consolidated)', 'Group by Account']:
 		return 'account'
 	else:
 		return 'voucher_no'
@@ -423,9 +423,9 @@
 		elif gle.posting_date <= to_date:
 			update_value_in_dict(gle_map[gle.get(group_by)].totals, 'total', gle)
 			update_value_in_dict(totals, 'total', gle)
-			if filters.get("group_by") != _('Group by Voucher (Consolidated)'):
+			if filters.get("group_by") != 'Group by Voucher (Consolidated)':
 				gle_map[gle.get(group_by)].entries.append(gle)
-			elif filters.get("group_by") == _('Group by Voucher (Consolidated)'):
+			elif filters.get("group_by") == 'Group by Voucher (Consolidated)':
 				keylist = [gle.get("voucher_type"), gle.get("voucher_no"), gle.get("account")]
 				for dim in accounting_dimensions:
 					keylist.append(gle.get(dim))
diff --git a/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.json b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.json
index dfc4b18..91f0798 100644
--- a/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.json
+++ b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.json
@@ -1,12 +1,15 @@
 {
- "add_total_row": 0,
+ "add_total_row": 1,
+ "columns": [],
  "creation": "2018-08-21 11:25:00.551823",
+ "disable_prepared_report": 0,
  "disabled": 0,
  "docstatus": 0,
  "doctype": "Report",
+ "filters": [],
  "idx": 0,
  "is_standard": "Yes",
- "modified": "2018-09-21 11:25:00.551823",
+ "modified": "2021-09-20 17:43:39.518851",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "TDS Computation Summary",
diff --git a/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py
index c4a8c7a..536df1f 100644
--- a/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py
+++ b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py
@@ -2,11 +2,10 @@
 
 import frappe
 from frappe import _
-from frappe.utils import flt
 
-from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import (
-	get_advance_vouchers,
-	get_debit_note_amount,
+from erpnext.accounts.report.tds_payable_monthly.tds_payable_monthly import (
+	get_result,
+	get_tds_docs,
 )
 from erpnext.accounts.utils import get_fiscal_year
 
@@ -17,9 +16,12 @@
 	filters.naming_series = frappe.db.get_single_value('Buying Settings', 'supp_master_name')
 
 	columns = get_columns(filters)
-	res = get_result(filters)
+	tds_docs, tds_accounts, tax_category_map = get_tds_docs(filters)
 
-	return columns, res
+	res = get_result(filters, tds_docs, tds_accounts, tax_category_map)
+	final_result = group_by_supplier_and_category(res)
+
+	return columns, final_result
 
 def validate_filters(filters):
 	''' Validate if dates are properly set and lie in the same fiscal year'''
@@ -33,81 +35,39 @@
 
 	filters["fiscal_year"] = from_year
 
-def get_result(filters):
-	# if no supplier selected, fetch data for all tds applicable supplier
-	# else fetch relevant data for selected supplier
-	pan = "pan" if frappe.db.has_column("Supplier", "pan") else "tax_id"
-	fields = ["name", pan+" as pan", "tax_withholding_category", "supplier_type", "supplier_name"]
+def group_by_supplier_and_category(data):
+	supplier_category_wise_map = {}
 
-	if filters.supplier:
-		filters.supplier = frappe.db.get_list('Supplier',
-			{"name": filters.supplier}, fields)
-	else:
-		filters.supplier = frappe.db.get_list('Supplier',
-			{"tax_withholding_category": ["!=", ""]}, fields)
+	for row in data:
+		supplier_category_wise_map.setdefault((row.get('supplier'), row.get('section_code')), {
+			'pan': row.get('pan'),
+			'supplier': row.get('supplier'),
+			'supplier_name': row.get('supplier_name'),
+			'section_code': row.get('section_code'),
+			'entity_type': row.get('entity_type'),
+			'tds_rate': row.get('tds_rate'),
+			'total_amount_credited': 0.0,
+			'tds_deducted': 0.0
+		})
 
+		supplier_category_wise_map.get((row.get('supplier'), row.get('section_code')))['total_amount_credited'] += \
+			row.get('total_amount_credited', 0.0)
+
+		supplier_category_wise_map.get((row.get('supplier'), row.get('section_code')))['tds_deducted'] += \
+			row.get('tds_deducted', 0.0)
+
+	final_result = get_final_result(supplier_category_wise_map)
+
+	return final_result
+
+
+def get_final_result(supplier_category_wise_map):
 	out = []
-	for supplier in filters.supplier:
-		tds = frappe.get_doc("Tax Withholding Category", supplier.tax_withholding_category)
-		rate = [d.tax_withholding_rate for d in tds.rates if d.fiscal_year == filters.fiscal_year]
-
-		if rate:
-			rate = rate[0]
-
-		try:
-			account = [d.account for d in tds.accounts if d.company == filters.company][0]
-
-		except IndexError:
-			account = []
-		total_invoiced_amount, tds_deducted = get_invoice_and_tds_amount(supplier.name, account,
-			filters.company, filters.from_date, filters.to_date, filters.fiscal_year)
-
-		if total_invoiced_amount or tds_deducted:
-			row = [supplier.pan, supplier.name]
-
-			if filters.naming_series == 'Naming Series':
-				row.append(supplier.supplier_name)
-
-			row.extend([tds.name, supplier.supplier_type, rate, total_invoiced_amount, tds_deducted])
-			out.append(row)
+	for key, value in supplier_category_wise_map.items():
+		out.append(value)
 
 	return out
 
-def get_invoice_and_tds_amount(supplier, account, company, from_date, to_date, fiscal_year):
-	''' calculate total invoice amount and total tds deducted for given supplier  '''
-
-	entries = frappe.db.sql("""
-		select voucher_no, credit
-		from `tabGL Entry`
-		where party in (%s) and credit > 0
-			and company=%s and is_cancelled = 0
-			and posting_date between %s and %s
-	""", (supplier, company, from_date, to_date), as_dict=1)
-
-	supplier_credit_amount = flt(sum(d.credit for d in entries))
-
-	vouchers = [d.voucher_no for d in entries]
-	vouchers += get_advance_vouchers([supplier], company=company,
-		from_date=from_date, to_date=to_date)
-
-	tds_deducted = 0
-	if vouchers:
-		tds_deducted = flt(frappe.db.sql("""
-			select sum(credit)
-			from `tabGL Entry`
-			where account=%s and posting_date between %s and %s
-				and company=%s and credit > 0 and voucher_no in ({0})
-		""".format(', '.join("'%s'" % d for d in vouchers)),
-			(account, from_date, to_date, company))[0][0])
-
-	date_range_filter = [fiscal_year, from_date, to_date]
-
-	debit_note_amount = get_debit_note_amount([supplier], date_range_filter, company=company)
-
-	total_invoiced_amount = supplier_credit_amount + tds_deducted - debit_note_amount
-
-	return total_invoiced_amount, tds_deducted
-
 def get_columns(filters):
 	columns = [
 		{
@@ -149,7 +109,7 @@
 		{
 			"label": _("TDS Rate %"),
 			"fieldname": "tds_rate",
-			"fieldtype": "Float",
+			"fieldtype": "Percent",
 			"width": 90
 		},
 		{
diff --git a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.js b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.js
index 72de318..ff2aa30 100644
--- a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.js
+++ b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.js
@@ -16,69 +16,6 @@
 			"label": __("Supplier"),
 			"fieldtype": "Link",
 			"options": "Supplier",
-			"get_query": function() {
-				return {
-					"filters": {
-						"tax_withholding_category": ["!=", ""],
-					}
-				}
-			},
-			on_change: function() {
-				frappe.query_report.set_filter_value("purchase_invoice", "");
-				frappe.query_report.refresh();
-			}
-		},
-		{
-			"fieldname":"purchase_invoice",
-			"label": __("Purchase Invoice"),
-			"fieldtype": "Link",
-			"options": "Purchase Invoice",
-			"get_query": function() {
-				return {
-					"filters": {
-						"name": ["in", frappe.query_report.invoices]
-					}
-				}
-			},
-			on_change: function() {
-				let supplier = frappe.query_report.get_filter_value('supplier');
-				if(!supplier) return; // return if no supplier selected
-
-				// filter invoices based on selected supplier
-				let invoices = [];
-				frappe.query_report.invoice_data.map(d => {
-					if(d.supplier==supplier)
-						invoices.push(d.name)
-				});
-				frappe.query_report.invoices = invoices;
-				frappe.query_report.refresh();
-			}
-		},
-		{
-			"fieldname":"purchase_order",
-			"label": __("Purchase Order"),
-			"fieldtype": "Link",
-			"options": "Purchase Order",
-			"get_query": function() {
-				return {
-					"filters": {
-						"name": ["in", frappe.query_report.invoices]
-					}
-				}
-			},
-			on_change: function() {
-				let supplier = frappe.query_report.get_filter_value('supplier');
-				if(!supplier) return; // return if no supplier selected
-
-				// filter invoices based on selected supplier
-				let invoices = [];
-				frappe.query_report.invoice_data.map(d => {
-					if(d.supplier==supplier)
-						invoices.push(d.name)
-				});
-				frappe.query_report.invoices = invoices;
-				frappe.query_report.refresh();
-			}
 		},
 		{
 			"fieldname":"from_date",
@@ -96,23 +33,5 @@
 			"reqd": 1,
 			"width": "60px"
 		}
-	],
-
-	onload: function(report) {
-		// fetch all tds applied invoices
-		frappe.call({
-			"method": "erpnext.accounts.report.tds_payable_monthly.tds_payable_monthly.get_tds_invoices_and_orders",
-			callback: function(r) {
-				let invoices = [];
-
-				r.message.map(d => {
-					invoices.push(d.name);
-				});
-
-				report["invoice_data"] = r.message.invoices;
-				report["invoices"] = invoices;
-
-			}
-		});
-	}
+	]
 }
diff --git a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.json b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.json
index 557a62d..4d555bd 100644
--- a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.json
+++ b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.json
@@ -1,13 +1,15 @@
 {
  "add_total_row": 1,
+ "columns": [],
  "creation": "2018-08-21 11:32:30.874923",
  "disable_prepared_report": 0,
  "disabled": 0,
  "docstatus": 0,
  "doctype": "Report",
+ "filters": [],
  "idx": 0,
  "is_standard": "Yes",
- "modified": "2019-09-24 13:46:16.473711",
+ "modified": "2021-09-20 12:05:50.387572",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "TDS Payable Monthly",
diff --git a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py
index 9e1382b..621b697 100644
--- a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py
+++ b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py
@@ -8,19 +8,12 @@
 
 
 def execute(filters=None):
-	filters["invoices"] = frappe.cache().hget("invoices", frappe.session.user)
 	validate_filters(filters)
-	set_filters(filters)
-
-	# TDS payment entries
-	payment_entries = get_payment_entires(filters)
+	tds_docs, tds_accounts, tax_category_map = get_tds_docs(filters)
 
 	columns = get_columns(filters)
-	if not filters.get("invoices"):
-		return columns, []
 
-	res = get_result(filters, payment_entries)
-
+	res = get_result(filters, tds_docs, tds_accounts, tax_category_map)
 	return columns, res
 
 def validate_filters(filters):
@@ -28,109 +21,59 @@
 	if filters.from_date > filters.to_date:
 		frappe.throw(_("From Date must be before To Date"))
 
-def set_filters(filters):
-	invoices = []
-
-	if not filters.get("invoices"):
-		filters["invoices"] = get_tds_invoices_and_orders()
-
-	if filters.supplier and filters.purchase_invoice:
-		for d in filters["invoices"]:
-			if d.name == filters.purchase_invoice and d.supplier == filters.supplier:
-				invoices.append(d)
-	elif filters.supplier and not filters.purchase_invoice:
-		for d in filters["invoices"]:
-			if d.supplier == filters.supplier:
-				invoices.append(d)
-	elif filters.purchase_invoice and not filters.supplier:
-		for d in filters["invoices"]:
-			if d.name == filters.purchase_invoice:
-				invoices.append(d)
-	elif filters.supplier and filters.purchase_order:
-		for d in filters.get("invoices"):
-			if d.name == filters.purchase_order and d.supplier == filters.supplier:
-				invoices.append(d)
-	elif filters.supplier and not filters.purchase_order:
-		for d in filters.get("invoices"):
-			if d.supplier == filters.supplier:
-				invoices.append(d)
-	elif filters.purchase_order and not filters.supplier:
-		for d in filters.get("invoices"):
-			if d.name == filters.purchase_order:
-				invoices.append(d)
-
-	filters["invoices"] = invoices if invoices else filters["invoices"]
-	filters.naming_series = frappe.db.get_single_value('Buying Settings', 'supp_master_name')
-
-	#print(filters.get('invoices'))
-
-def get_result(filters, payment_entries):
-	supplier_map, tds_docs = get_supplier_map(filters, payment_entries)
-	documents = [d.get('name') for d in filters.get('invoices')] + [d.get('name') for d in payment_entries]
-
-	gle_map = get_gle_map(filters, documents)
+def get_result(filters, tds_docs, tds_accounts, tax_category_map):
+	supplier_map = get_supplier_pan_map()
+	tax_rate_map = get_tax_rate_map(filters)
+	gle_map = get_gle_map(filters, tds_docs)
 
 	out = []
-	for d in gle_map:
+	for name, details in gle_map.items():
 		tds_deducted, total_amount_credited = 0, 0
-		supplier = supplier_map[d]
+		tax_withholding_category = tax_category_map.get(name)
+		rate = tax_rate_map.get(tax_withholding_category)
 
-		tds_doc = tds_docs[supplier.tax_withholding_category]
-		account_list = [i.account for i in tds_doc.accounts if i.company == filters.company]
+		for entry in details:
+			supplier = entry.party or entry.against
+			posting_date = entry.posting_date
+			voucher_type = entry.voucher_type
 
-		if account_list:
-			account = account_list[0]
+			if entry.account in tds_accounts:
+				tds_deducted += (entry.credit - entry.debit)
 
-		for k in gle_map[d]:
-			if k.party == supplier_map[d] and k.credit > 0:
-				total_amount_credited += (k.credit - k.debit)
-			elif account_list and k.account == account and (k.credit - k.debit) > 0:
-				tds_deducted = (k.credit - k.debit)
-				total_amount_credited += (k.credit - k.debit)
-			voucher_type = k.voucher_type
+			total_amount_credited += (entry.credit - entry.debit)
 
-		rate = [i.tax_withholding_rate for i in tds_doc.rates
-			if i.fiscal_year == gle_map[d][0].fiscal_year]
-
-		if rate and len(rate) > 0 and tds_deducted:
-			rate = rate[0]
-
-			row = [supplier.pan, supplier.name]
+		if rate and tds_deducted:
+			row = {
+				'pan' if frappe.db.has_column('Supplier', 'pan') else 'tax_id': supplier_map.get(supplier).pan,
+				'supplier': supplier_map.get(supplier).name
+			}
 
 			if filters.naming_series == 'Naming Series':
-				row.append(supplier.supplier_name)
+				row.update({'supplier_name': supplier_map.get(supplier).supplier_name})
 
-			row.extend([tds_doc.name, supplier.supplier_type, rate, total_amount_credited,
-				tds_deducted, gle_map[d][0].posting_date, voucher_type, d])
+			row.update({
+				'section_code': tax_withholding_category,
+				'entity_type': supplier_map.get(supplier).supplier_type,
+				'tds_rate': rate,
+				'total_amount_credited': total_amount_credited,
+				'tds_deducted': tds_deducted,
+				'transaction_date': posting_date,
+				'transaction_type': voucher_type,
+				'ref_no': name
+			})
+
 			out.append(row)
 
 	return out
 
-def get_supplier_map(filters, payment_entries):
-	# create a supplier_map of the form {"purchase_invoice": {supplier_name, pan, tds_name}}
-	# pre-fetch all distinct applicable tds docs
-	supplier_map, tds_docs = {}, {}
-	pan = "pan" if frappe.db.has_column("Supplier", "pan") else "tax_id"
-	supplier_list = [d.supplier for d in filters["invoices"]]
+def get_supplier_pan_map():
+	supplier_map = frappe._dict()
+	suppliers = frappe.db.get_all('Supplier', fields=['name', 'pan', 'supplier_type', 'supplier_name'])
 
-	supplier_detail = frappe.db.get_all('Supplier',
-		{"name": ["in", supplier_list]},
-		["tax_withholding_category", "name", pan+" as pan", "supplier_type", "supplier_name"])
+	for d in suppliers:
+		supplier_map[d.name] = d
 
-	for d in filters["invoices"]:
-		supplier_map[d.get("name")] = [k for k in supplier_detail
-			if k.name == d.get("supplier")][0]
-
-	for d in payment_entries:
-		supplier_map[d.get("name")] = [k for k in supplier_detail
-			if k.name == d.get("supplier")][0]
-
-	for d in supplier_detail:
-		if d.get("tax_withholding_category") not in tds_docs:
-			tds_docs[d.get("tax_withholding_category")] = \
-				frappe.get_doc("Tax Withholding Category", d.get("tax_withholding_category"))
-
-	return supplier_map, tds_docs
+	return supplier_map
 
 def get_gle_map(filters, documents):
 	# create gle_map of the form
@@ -140,10 +83,9 @@
 	gle = frappe.db.get_all('GL Entry',
 		{
 			"voucher_no": ["in", documents],
-			'is_cancelled': 0,
-			'posting_date': ("between", [filters.get('from_date'), filters.get('to_date')]),
+			"credit": (">", 0)
 		},
-		["fiscal_year", "credit", "debit", "account", "voucher_no", "posting_date", "voucher_type"],
+		["credit", "debit", "account", "voucher_no", "posting_date", "voucher_type", "against", "party"],
 	)
 
 	for d in gle:
@@ -233,39 +175,57 @@
 
 	return columns
 
-def get_payment_entires(filters):
-	filter_dict = {
-		'posting_date': ("between", [filters.get('from_date'), filters.get('to_date')]),
-		'party_type': 'Supplier',
-		'apply_tax_withholding_amount': 1
+def get_tds_docs(filters):
+	tds_documents = []
+	purchase_invoices = []
+	payment_entries = []
+	journal_entries = []
+	tax_category_map = {}
+
+	tds_accounts = frappe.get_all("Tax Withholding Account", {'company': filters.get('company')},
+		pluck="account")
+
+	query_filters = {
+		"credit": ('>', 0),
+		"account": ("in", tds_accounts),
+		"posting_date": ("between", [filters.get("from_date"), filters.get("to_date")]),
+		"is_cancelled": 0
 	}
 
-	if filters.get('purchase_invoice') or filters.get('purchase_order'):
-		parent = frappe.db.get_all('Payment Entry Reference',
-			{'reference_name': ('in', [d.get('name') for d in filters.get('invoices')])}, ['parent'])
+	if filters.get('supplier'):
+		query_filters.update({'against': filters.get('supplier')})
 
-		filter_dict.update({'name': ('in', [d.get('parent') for d in parent])})
+	tds_docs = frappe.get_all("GL Entry", query_filters, ["voucher_no", "voucher_type", "against", "party"])
 
-	payment_entries = frappe.get_all('Payment Entry', fields=['name', 'party_name as supplier'],
-		filters=filter_dict)
+	for d in tds_docs:
+		if d.voucher_type == "Purchase Invoice":
+			purchase_invoices.append(d.voucher_no)
+		elif d.voucher_type == "Payment Entry":
+			payment_entries.append(d.voucher_no)
+		elif d.voucher_type == "Journal Entry":
+			journal_entries.append(d.voucher_no)
 
-	return payment_entries
+		tds_documents.append(d.voucher_no)
 
-@frappe.whitelist()
-def get_tds_invoices_and_orders():
-	# fetch tds applicable supplier and fetch invoices for these suppliers
-	suppliers = [d.name for d in frappe.db.get_list("Supplier",
-		{"tax_withholding_category": ["!=", ""]}, ["name"])]
+	if purchase_invoices:
+		get_tax_category_map(purchase_invoices, 'Purchase Invoice', tax_category_map)
 
-	invoices = frappe.db.get_list("Purchase Invoice",
-		{"supplier": ["in", suppliers]}, ["name", "supplier"])
+	if payment_entries:
+		get_tax_category_map(payment_entries, 'Payment Entry', tax_category_map)
 
-	orders = frappe.db.get_list("Purchase Order",
-		{"supplier": ["in", suppliers]}, ["name", "supplier"])
+	if journal_entries:
+		get_tax_category_map(journal_entries, 'Journal Entry', tax_category_map)
 
-	invoices = invoices + orders
-	invoices = [d for d in invoices if d.supplier]
+	return tds_documents, tds_accounts, tax_category_map
 
-	frappe.cache().hset("invoices", frappe.session.user, invoices)
+def get_tax_category_map(vouchers, doctype, tax_category_map):
+	tax_category_map.update(frappe._dict(frappe.get_all(doctype,
+		filters = {'name': ('in', vouchers)}, fields=['name', 'tax_withholding_category'], as_list=1)))
 
-	return invoices
+def get_tax_rate_map(filters):
+	rate_map = frappe.get_all('Tax Withholding Rate', filters={
+		'from_date': ('<=', filters.get('from_date')),
+		'to_date': ('>=', filters.get('to_date'))
+	}, fields=['parent', 'tax_withholding_rate'], as_list=1)
+
+	return frappe._dict(rate_map)
\ No newline at end of file
diff --git a/erpnext/accounts/report/unpaid_expense_claim/unpaid_expense_claim.js b/erpnext/accounts/report/unpaid_expense_claim/unpaid_expense_claim.js
index 811414a..f0ba78c 100644
--- a/erpnext/accounts/report/unpaid_expense_claim/unpaid_expense_claim.js
+++ b/erpnext/accounts/report/unpaid_expense_claim/unpaid_expense_claim.js
@@ -4,9 +4,10 @@
 frappe.query_reports["Unpaid Expense Claim"] = {
 	"filters": [
 		{
-			"fieldname":"employee",
+			"fieldname": "employee",
 			"label": __("Employee"),
-			"fieldtype": "Link"
+			"fieldtype": "Link",
+			"options": "Employee"
 		}
 	]
 }
diff --git a/erpnext/accounts/test/test_utils.py b/erpnext/accounts/test/test_utils.py
index d7b60da..c3f6d27 100644
--- a/erpnext/accounts/test/test_utils.py
+++ b/erpnext/accounts/test/test_utils.py
@@ -5,21 +5,48 @@
 from frappe.test_runner import make_test_objects
 
 from erpnext.accounts.party import get_party_shipping_address
+from erpnext.accounts.utils import get_future_stock_vouchers, get_voucherwise_gl_entries
+from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
 
 
 class TestUtils(unittest.TestCase):
 	@classmethod
 	def setUpClass(cls):
 		super(TestUtils, cls).setUpClass()
-		make_test_objects('Address', ADDRESS_RECORDS)
+		make_test_objects("Address", ADDRESS_RECORDS)
 
 	def test_get_party_shipping_address(self):
-		address = get_party_shipping_address('Customer', '_Test Customer 1')
-		self.assertEqual(address, '_Test Billing Address 2 Title-Billing')
+		address = get_party_shipping_address("Customer", "_Test Customer 1")
+		self.assertEqual(address, "_Test Billing Address 2 Title-Billing")
 
 	def test_get_party_shipping_address2(self):
-		address = get_party_shipping_address('Customer', '_Test Customer 2')
-		self.assertEqual(address, '_Test Shipping Address 2 Title-Shipping')
+		address = get_party_shipping_address("Customer", "_Test Customer 2")
+		self.assertEqual(address, "_Test Shipping Address 2 Title-Shipping")
+
+	def test_get_voucher_wise_gl_entry(self):
+
+		pr = make_purchase_receipt(
+			item_code="_Test Item",
+			posting_date="2021-02-01",
+			rate=100,
+			qty=1,
+			warehouse="Stores - TCP1",
+			company="_Test Company with perpetual inventory",
+		)
+
+		future_vouchers = get_future_stock_vouchers("2021-01-01", "00:00:00", for_items=["_Test Item"])
+
+		voucher_type_and_no = ("Purchase Receipt", pr.name)
+		self.assertTrue(
+			voucher_type_and_no in future_vouchers,
+			msg="get_future_stock_vouchers not returning correct value",
+		)
+
+		posting_date = "2021-01-01"
+		gl_entries = get_voucherwise_gl_entries(future_vouchers, posting_date)
+		self.assertTrue(
+			voucher_type_and_no in gl_entries, msg="get_voucherwise_gl_entries not returning expected GLes",
+		)
 
 
 ADDRESS_RECORDS = [
@@ -31,12 +58,8 @@
 		"city": "Lagos",
 		"country": "Nigeria",
 		"links": [
-			{
-				"link_doctype": "Customer",
-				"link_name": "_Test Customer 2",
-				"doctype": "Dynamic Link"
-			}
-		]
+			{"link_doctype": "Customer", "link_name": "_Test Customer 2", "doctype": "Dynamic Link"}
+		],
 	},
 	{
 		"doctype": "Address",
@@ -46,12 +69,8 @@
 		"city": "Lagos",
 		"country": "Nigeria",
 		"links": [
-			{
-				"link_doctype": "Customer",
-				"link_name": "_Test Customer 2",
-				"doctype": "Dynamic Link"
-			}
-		]
+			{"link_doctype": "Customer", "link_name": "_Test Customer 2", "doctype": "Dynamic Link"}
+		],
 	},
 	{
 		"doctype": "Address",
@@ -62,12 +81,8 @@
 		"country": "Nigeria",
 		"is_shipping_address": "1",
 		"links": [
-			{
-				"link_doctype": "Customer",
-				"link_name": "_Test Customer 2",
-				"doctype": "Dynamic Link"
-			}
-		]
+			{"link_doctype": "Customer", "link_name": "_Test Customer 2", "doctype": "Dynamic Link"}
+		],
 	},
 	{
 		"doctype": "Address",
@@ -78,11 +93,7 @@
 		"country": "Nigeria",
 		"is_shipping_address": "1",
 		"links": [
-			{
-				"link_doctype": "Customer",
-				"link_name": "_Test Customer 1",
-				"doctype": "Dynamic Link"
-			}
-		]
-	}
+			{"link_doctype": "Customer", "link_name": "_Test Customer 1", "doctype": "Dynamic Link"}
+		],
+	},
 ]
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 4692869..fdd8d09 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -4,11 +4,14 @@
 
 from __future__ import unicode_literals
 
+from json import loads
+
 import frappe
 import frappe.defaults
 from frappe import _, throw
 from frappe.model.meta import get_field_precision
 from frappe.utils import cint, cstr, flt, formatdate, get_number_format_info, getdate, now, nowdate
+from six import string_types
 
 import erpnext
 
@@ -787,16 +790,28 @@
 
 	if doctype == 'Account':
 		sort_accounts(acc, is_root, key="value")
-		company_currency = frappe.get_cached_value('Company',  company,  "default_currency")
-		for each in acc:
-			each["company_currency"] = company_currency
-			each["balance"] = flt(get_balance_on(each.get("value"), in_account_currency=False, company=company))
-
-			if each.account_currency != company_currency:
-				each["balance_in_account_currency"] = flt(get_balance_on(each.get("value"), company=company))
 
 	return acc
 
+@frappe.whitelist()
+def get_account_balances(accounts, company):
+
+	if isinstance(accounts, string_types):
+		accounts = loads(accounts)
+
+	if not accounts:
+		return []
+
+	company_currency = frappe.get_cached_value("Company",  company,  "default_currency")
+
+	for account in accounts:
+		account["company_currency"] = company_currency
+		account["balance"] = flt(get_balance_on(account["value"], in_account_currency=False, company=company))
+		if account["account_currency"] and account["account_currency"] != company_currency:
+			account["balance_in_account_currency"] = flt(get_balance_on(account["value"], company=company))
+
+	return accounts
+
 def create_payment_gateway_account(gateway, payment_channel="Email"):
 	from erpnext.setup.setup_wizard.operations.install_fixtures import create_bank_account
 
@@ -963,6 +978,9 @@
 
 	Only fetches GLE fields required for comparing with new GLE.
 	Check compare_existing_and_expected_gle function below.
+
+	returns:
+		Dict[Tuple[voucher_type, voucher_no], List[GL Entries]]
 	"""
 	gl_entries = {}
 	if not future_stock_vouchers:
@@ -971,7 +989,7 @@
 	voucher_nos = [d[1] for d in future_stock_vouchers]
 
 	gles = frappe.db.sql("""
-		select name, account, credit, debit, cost_center, project
+		select name, account, credit, debit, cost_center, project, voucher_type, voucher_no
 			from `tabGL Entry`
 		where
 			posting_date >= %s and voucher_no in (%s)""" %
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 8ff4f97..7e135be 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -140,11 +140,6 @@
 		if self.is_existing_asset:
 			return
 
-		docname = self.purchase_receipt or self.purchase_invoice
-		if docname:
-			doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice'
-			date = frappe.db.get_value(doctype, docname, 'posting_date')
-
 		if self.available_for_use_date and getdate(self.available_for_use_date) < getdate(self.purchase_date):
 			frappe.throw(_("Available-for-use Date should be after purchase date"))
 
@@ -394,10 +389,6 @@
 			if cint(self.number_of_depreciations_booked) > cint(row.total_number_of_depreciations):
 				frappe.throw(_("Number of Depreciations Booked cannot be greater than Total Number of Depreciations"))
 
-		if row.depreciation_start_date and getdate(row.depreciation_start_date) < getdate(nowdate()):
-			frappe.msgprint(_("Depreciation Row {0}: Depreciation Start Date is entered as past date")
-				.format(row.idx), title=_('Warning'), indicator='red')
-
 		if row.depreciation_start_date and getdate(row.depreciation_start_date) < getdate(self.purchase_date):
 			frappe.throw(_("Depreciation Row {0}: Next Depreciation Date cannot be before Purchase Date")
 				.format(row.idx))
@@ -444,9 +435,10 @@
 			if accumulated_depreciation_after_full_schedule:
 				accumulated_depreciation_after_full_schedule = max(accumulated_depreciation_after_full_schedule)
 
-				asset_value_after_full_schedule = flt(flt(self.gross_purchase_amount) -
-					flt(accumulated_depreciation_after_full_schedule),
-					self.precision('gross_purchase_amount'))
+				asset_value_after_full_schedule = flt(
+					flt(self.gross_purchase_amount) -
+					flt(self.opening_accumulated_depreciation) -
+					flt(accumulated_depreciation_after_full_schedule), self.precision('gross_purchase_amount'))
 
 				if (row.expected_value_after_useful_life and
 					row.expected_value_after_useful_life < asset_value_after_full_schedule):
diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py
index 4cc9be5..7183ee7 100644
--- a/erpnext/assets/doctype/asset/test_asset.py
+++ b/erpnext/assets/doctype/asset/test_asset.py
@@ -645,12 +645,18 @@
 		pr = make_purchase_receipt(item_code="Macbook Pro",
 			qty=1, rate=8000.0, location="Test Location")
 
+		finance_book = frappe.new_doc('Finance Book')
+		finance_book.finance_book_name = 'Income Tax'
+		finance_book.for_income_tax = 1
+		finance_book.insert(ignore_if_duplicate=1)
+
 		asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
 		asset = frappe.get_doc('Asset', asset_name)
 		asset.calculate_depreciation = 1
 		asset.available_for_use_date = '2030-07-12'
 		asset.purchase_date = '2030-01-01'
 		asset.append("finance_books", {
+			"finance_book": finance_book.name,
 			"expected_value_after_useful_life": 1000,
 			"depreciation_method": "Written Down Value",
 			"total_number_of_depreciations": 3,
diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.json b/erpnext/buying/doctype/buying_settings/buying_settings.json
index b9c77d5..b828a43 100644
--- a/erpnext/buying/doctype/buying_settings/buying_settings.json
+++ b/erpnext/buying/doctype/buying_settings/buying_settings.json
@@ -28,7 +28,7 @@
    "fieldname": "supp_master_name",
    "fieldtype": "Select",
    "label": "Supplier Naming By",
-   "options": "Supplier Name\nNaming Series"
+   "options": "Supplier Name\nNaming Series\nAuto Name"
   },
   {
    "fieldname": "supplier_group",
@@ -123,7 +123,7 @@
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2021-06-24 10:38:28.934525",
+ "modified": "2021-09-08 19:26:23.548837",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Buying Settings",
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 521432d..2005dac 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -425,7 +425,10 @@
 						status: ["!=", "Stopped"],
 						per_ordered: ["<", 100],
 						company: me.frm.doc.company
-					}
+					},
+					allow_child_item_selection: true,
+					child_fielname: "items",
+					child_columns: ["item_code", "qty"]
 				})
 			}, __("Get Items From"));
 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index ef54538..896208f 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -1121,6 +1121,7 @@
    "fetch_from": "supplier.represents_company",
    "fieldname": "represents_company",
    "fieldtype": "Link",
+   "ignore_user_permissions": 1,
    "label": "Represents Company",
    "options": "Company",
    "read_only": 1
@@ -1143,7 +1144,7 @@
  "idx": 105,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-08-30 20:03:14.008804",
+ "modified": "2021-09-28 13:10:47.955401",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order",
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
index af1a9a9..5aa2d13 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
@@ -394,12 +394,10 @@
 
 @frappe.whitelist()
 def get_supplier_tag():
-	if not frappe.cache().hget("Supplier", "Tags"):
-		filters = {"document_type": "Supplier"}
-		tags = list(set(tag.tag for tag in frappe.get_all("Tag Link", filters=filters, fields=["tag"]) if tag))
-		frappe.cache().hset("Supplier", "Tags", tags)
+	filters = {"document_type": "Supplier"}
+	tags = list(set(tag.tag for tag in frappe.get_all("Tag Link", filters=filters, fields=["tag"]) if tag))
 
-	return frappe.cache().hget("Supplier", "Tags")
+	return tags
 
 @frappe.whitelist()
 @frappe.validate_and_sanitize_search_inputs
diff --git a/erpnext/buying/doctype/supplier/supplier.json b/erpnext/buying/doctype/supplier/supplier.json
index c7a5db5..12a09cd 100644
--- a/erpnext/buying/doctype/supplier/supplier.json
+++ b/erpnext/buying/doctype/supplier/supplier.json
@@ -433,12 +433,12 @@
  "image_field": "image",
  "links": [
   {
-   "group": "Item Group",
-   "link_doctype": "Supplier Item Group",
-   "link_fieldname": "supplier"
+   "group": "Allowed Items",
+   "link_doctype": "Party Specific Item",
+   "link_fieldname": "party"
   }
  ],
- "modified": "2021-08-27 18:02:44.314077",
+ "modified": "2021-09-06 17:37:56.522233",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Supplier",
diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py
index 2a9f784..0ab0171 100644
--- a/erpnext/buying/doctype/supplier/supplier.py
+++ b/erpnext/buying/doctype/supplier/supplier.py
@@ -10,7 +10,7 @@
 	delete_contact_and_address,
 	load_address_and_contact,
 )
-from frappe.model.naming import set_name_by_naming_series
+from frappe.model.naming import set_name_by_naming_series, set_name_from_naming_options
 
 from erpnext.accounts.party import get_dashboard_info, validate_party_accounts
 from erpnext.utilities.transaction_base import TransactionBase
@@ -40,8 +40,10 @@
 		supp_master_name = frappe.defaults.get_global_default('supp_master_name')
 		if supp_master_name == 'Supplier Name':
 			self.name = self.supplier_name
-		else:
+		elif supp_master_name == 'Naming Series':
 			set_name_by_naming_series(self)
+		else:
+			self.name = set_name_from_naming_options(frappe.get_meta(self.doctype).autoname, self)
 
 	def on_update(self):
 		if not self.naming_series:
diff --git a/erpnext/buying/doctype/supplier_item_group/__init__.py b/erpnext/buying/doctype/supplier_item_group/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/buying/doctype/supplier_item_group/__init__.py
+++ /dev/null
diff --git a/erpnext/buying/doctype/supplier_item_group/supplier_item_group.js b/erpnext/buying/doctype/supplier_item_group/supplier_item_group.js
deleted file mode 100644
index f7da90d..0000000
--- a/erpnext/buying/doctype/supplier_item_group/supplier_item_group.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Supplier Item Group', {
-	// refresh: function(frm) {
-
-	// }
-});
diff --git a/erpnext/buying/doctype/supplier_item_group/supplier_item_group.json b/erpnext/buying/doctype/supplier_item_group/supplier_item_group.json
deleted file mode 100644
index 1971458..0000000
--- a/erpnext/buying/doctype/supplier_item_group/supplier_item_group.json
+++ /dev/null
@@ -1,77 +0,0 @@
-{
- "actions": [],
- "creation": "2021-05-07 18:16:40.621421",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "supplier",
-  "item_group"
- ],
- "fields": [
-  {
-   "fieldname": "supplier",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Supplier",
-   "options": "Supplier",
-   "reqd": 1
-  },
-  {
-   "fieldname": "item_group",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Item Group",
-   "options": "Item Group",
-   "reqd": 1
-  }
- ],
- "index_web_pages_for_search": 1,
- "links": [],
- "modified": "2021-05-19 13:48:16.742303",
- "modified_by": "Administrator",
- "module": "Buying",
- "name": "Supplier Item Group",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Purchase User",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Purchase Manager",
-   "share": 1,
-   "write": 1
-  }
- ],
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/buying/doctype/supplier_item_group/supplier_item_group.py b/erpnext/buying/doctype/supplier_item_group/supplier_item_group.py
deleted file mode 100644
index 6d71f7d..0000000
--- a/erpnext/buying/doctype/supplier_item_group/supplier_item_group.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2021, 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 SupplierItemGroup(Document):
-	def validate(self):
-		exists = frappe.db.exists({
-			'doctype': 'Supplier Item Group',
-			'supplier': self.supplier,
-			'item_group': self.item_group
-		})
-		if exists:
-			frappe.throw(_("Item Group has already been linked to this supplier."))
diff --git a/erpnext/buying/doctype/supplier_item_group/test_supplier_item_group.py b/erpnext/buying/doctype/supplier_item_group/test_supplier_item_group.py
deleted file mode 100644
index 55ba85e..0000000
--- a/erpnext/buying/doctype/supplier_item_group/test_supplier_item_group.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-# import frappe
-import unittest
-
-
-class TestSupplierItemGroup(unittest.TestCase):
-	pass
diff --git a/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.js b/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.js
index 701da43..ca3be03 100644
--- a/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.js
+++ b/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.js
@@ -30,7 +30,14 @@
 			"default": frappe.datetime.get_today()
 		},
 		{
-			"fieldname": "purchase_order",
+			"fieldname":"project",
+			"label": __("Project"),
+			"fieldtype": "Link",
+			"width": "80",
+			"options": "Project"
+		},
+		{
+			"fieldname": "name",
 			"label": __("Purchase Order"),
 			"fieldtype": "Link",
 			"width": "80",
diff --git a/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py b/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py
index 5d59456..1b25dd4 100644
--- a/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py
+++ b/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py
@@ -41,14 +41,12 @@
 	if filters.get("from_date") and filters.get("to_date"):
 		conditions += " and po.transaction_date between %(from_date)s and %(to_date)s"
 
-	if filters.get("company"):
-		conditions += " and po.company = %(company)s"
+	for field in ['company', 'name', 'status']:
+		if filters.get(field):
+			conditions += f" and po.{field} = %({field})s"
 
-	if filters.get("purchase_order"):
-		conditions += " and po.name = %(purchase_order)s"
-
-	if filters.get("status"):
-		conditions += " and po.status in %(status)s"
+	if filters.get('project'):
+		conditions += " and poi.project = %(project)s"
 
 	return conditions
 
@@ -57,6 +55,7 @@
 		SELECT
 			po.transaction_date as date,
 			poi.schedule_date as required_date,
+			poi.project,
 			po.name as purchase_order,
 			po.status, po.supplier, poi.item_code,
 			poi.qty, poi.received_qty,
@@ -175,6 +174,12 @@
 			"fieldtype": "Link",
 			"options": "Supplier",
 			"width": 130
+		},{
+			"label": _("Project"),
+			"fieldname": "project",
+			"fieldtype": "Link",
+			"options": "Project",
+			"width": 130
 		}]
 
 	if not filters.get("group_by_po"):
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index b90db05..e9b531e 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -685,13 +685,17 @@
 							.format(d.reference_name, d.against_order))
 
 	def set_advance_gain_or_loss(self):
-		if not self.get("advances"):
+		if self.get('conversion_rate') == 1 or not self.get("advances"):
+			return
+
+		is_purchase_invoice = self.doctype == 'Purchase Invoice'
+		party_account = self.credit_to if is_purchase_invoice else self.debit_to
+		if get_account_currency(party_account) != self.currency:
 			return
 
 		for d in self.get("advances"):
 			advance_exchange_rate = d.ref_exchange_rate
-			if (d.allocated_amount and self.conversion_rate != 1
-				and self.conversion_rate != advance_exchange_rate):
+			if (d.allocated_amount and self.conversion_rate != advance_exchange_rate):
 
 				base_allocated_amount_in_ref_rate = advance_exchange_rate * d.allocated_amount
 				base_allocated_amount_in_inv_rate = self.conversion_rate * d.allocated_amount
@@ -710,7 +714,7 @@
 
 					gain_loss_account = frappe.db.get_value('Company', self.company, 'exchange_gain_loss_account')
 					if not gain_loss_account:
-						frappe.throw(_("Please set Default Exchange Gain/Loss Account in Company {}")
+						frappe.throw(_("Please set default Exchange Gain/Loss Account in Company {}")
 							.format(self.get('company')))
 					account_currency = get_account_currency(gain_loss_account)
 					if account_currency != self.company_currency:
@@ -729,7 +733,7 @@
 							"against": party,
 							dr_or_cr + "_in_account_currency": abs(d.exchange_gain_loss),
 							dr_or_cr: abs(d.exchange_gain_loss),
-							"cost_center": self.cost_center,
+							"cost_center": self.cost_center or erpnext.get_default_cost_center(self.company),
 							"project": self.project
 						}, item=d)
 					)
@@ -980,42 +984,55 @@
 		item_allowance = {}
 		global_qty_allowance, global_amount_allowance = None, None
 
+		role_allowed_to_over_bill = frappe.db.get_single_value('Accounts Settings', 'role_allowed_to_over_bill')
+		user_roles = frappe.get_roles()
+
+		total_overbilled_amt = 0.0
+
 		for item in self.get("items"):
-			if item.get(item_ref_dn):
-				ref_amt = flt(frappe.db.get_value(ref_dt + " Item",
-					item.get(item_ref_dn), based_on), self.precision(based_on, item))
-				if not ref_amt:
-					frappe.msgprint(
-						_("Warning: System will not check overbilling since amount for Item {0} in {1} is zero")
-							.format(item.item_code, ref_dt))
-				else:
-					already_billed = frappe.db.sql("""
-						select sum(%s)
-						from `tab%s`
-						where %s=%s and docstatus=1 and parent != %s
-					""" % (based_on, self.doctype + " Item", item_ref_dn, '%s', '%s'),
-					   (item.get(item_ref_dn), self.name))[0][0]
+			if not item.get(item_ref_dn):
+				continue
 
-					total_billed_amt = flt(flt(already_billed) + flt(item.get(based_on)),
-						self.precision(based_on, item))
+			ref_amt = flt(frappe.db.get_value(ref_dt + " Item",
+				item.get(item_ref_dn), based_on), self.precision(based_on, item))
+			if not ref_amt:
+				frappe.msgprint(
+					_("System will not check overbilling since amount for Item {0} in {1} is zero")
+						.format(item.item_code, ref_dt), title=_("Warning"), indicator="orange")
+				continue
 
-					allowance, item_allowance, global_qty_allowance, global_amount_allowance = \
-						get_allowance_for(item.item_code, item_allowance, global_qty_allowance, global_amount_allowance, "amount")
+			already_billed = frappe.db.sql("""
+				select sum(%s)
+				from `tab%s`
+				where %s=%s and docstatus=1 and parent != %s
+			""" % (based_on, self.doctype + " Item", item_ref_dn, '%s', '%s'),
+				(item.get(item_ref_dn), self.name))[0][0]
 
-					max_allowed_amt = flt(ref_amt * (100 + allowance) / 100)
+			total_billed_amt = flt(flt(already_billed) + flt(item.get(based_on)),
+				self.precision(based_on, item))
 
-					if total_billed_amt < 0 and max_allowed_amt < 0:
-						# while making debit note against purchase return entry(purchase receipt) getting overbill error
-						total_billed_amt = abs(total_billed_amt)
-						max_allowed_amt = abs(max_allowed_amt)
+			allowance, item_allowance, global_qty_allowance, global_amount_allowance = \
+				get_allowance_for(item.item_code, item_allowance, global_qty_allowance, global_amount_allowance, "amount")
 
-					role_allowed_to_over_bill = frappe.db.get_single_value('Accounts Settings', 'role_allowed_to_over_bill')
+			max_allowed_amt = flt(ref_amt * (100 + allowance) / 100)
 
-					if total_billed_amt - max_allowed_amt > 0.01 and role_allowed_to_over_bill not in frappe.get_roles():
-						if self.doctype != "Purchase Invoice":
-							self.throw_overbill_exception(item, max_allowed_amt)
-						elif not cint(frappe.db.get_single_value("Buying Settings", "bill_for_rejected_quantity_in_purchase_invoice")):
-							self.throw_overbill_exception(item, max_allowed_amt)
+			if total_billed_amt < 0 and max_allowed_amt < 0:
+				# while making debit note against purchase return entry(purchase receipt) getting overbill error
+				total_billed_amt = abs(total_billed_amt)
+				max_allowed_amt = abs(max_allowed_amt)
+
+			overbill_amt = total_billed_amt - max_allowed_amt
+			total_overbilled_amt += overbill_amt
+
+			if overbill_amt > 0.01 and role_allowed_to_over_bill not in user_roles:
+				if self.doctype != "Purchase Invoice":
+					self.throw_overbill_exception(item, max_allowed_amt)
+				elif not cint(frappe.db.get_single_value("Buying Settings", "bill_for_rejected_quantity_in_purchase_invoice")):
+					self.throw_overbill_exception(item, max_allowed_amt)
+
+		if role_allowed_to_over_bill in user_roles and total_overbilled_amt > 0.1:
+			frappe.msgprint(_("Overbilling of {} ignored because you have {} role.")
+					.format(total_overbilled_amt, role_allowed_to_over_bill), title=_("Warning"), indicator="orange")
 
 	def throw_overbill_exception(self, item, max_allowed_amt):
 		frappe.throw(_("Cannot overbill for Item {0} in row {1} more than {2}. To allow over-billing, please set allowance in Accounts Settings")
@@ -1668,14 +1685,18 @@
 	return list(payment_entries_against_order) + list(unallocated_payment_entries)
 
 def update_invoice_status():
-	# Daily update the status of the invoices
+	"""Updates status as Overdue for applicable invoices. Runs daily."""
 
-	frappe.db.sql(""" update `tabSales Invoice` set status = 'Overdue'
-		where due_date < CURDATE() and docstatus = 1 and outstanding_amount > 0""")
-
-	frappe.db.sql(""" update `tabPurchase Invoice` set status = 'Overdue'
-		where due_date < CURDATE() and docstatus = 1 and outstanding_amount > 0""")
-
+	for doctype in ("Sales Invoice", "Purchase Invoice"):
+		frappe.db.sql("""
+			update `tab{}` as dt set dt.status = 'Overdue'
+			where dt.docstatus = 1
+				and dt.status != 'Overdue'
+				and dt.outstanding_amount > 0
+				and (dt.grand_total - dt.outstanding_amount) <
+					(select sum(payment_amount) from `tabPayment Schedule` as ps
+						where ps.parent = dt.name and ps.due_date < %s)
+		""".format(doctype), getdate())
 
 @frappe.whitelist()
 def get_payment_terms(terms_template, posting_date=None, grand_total=None, base_grand_total=None, bill_date=None):
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index aafaf5b..7b4566a 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -7,6 +7,7 @@
 from collections import defaultdict
 
 import frappe
+from frappe import scrub
 from frappe.desk.reportview import get_filters_cond, get_match_cond
 from frappe.utils import nowdate, unique
 
@@ -223,18 +224,29 @@
 		if not field in searchfields]
 	searchfields = " or ".join([field + " like %(txt)s" for field in searchfields])
 
-	if filters and isinstance(filters, dict) and filters.get('supplier'):
-		item_group_list = frappe.get_all('Supplier Item Group',
-			filters = {'supplier': filters.get('supplier')}, fields = ['item_group'])
+	if filters and isinstance(filters, dict):
+		if filters.get('customer') or filters.get('supplier'):
+			party = filters.get('customer') or filters.get('supplier')
+			item_rules_list = frappe.get_all('Party Specific Item',
+				filters = {'party': party}, fields = ['restrict_based_on', 'based_on_value'])
 
-		item_groups = []
-		for i in item_group_list:
-			item_groups.append(i.item_group)
+			filters_dict = {}
+			for rule in item_rules_list:
+				if rule['restrict_based_on'] == 'Item':
+					rule['restrict_based_on'] = 'name'
+				filters_dict[rule.restrict_based_on] = []
 
-		del filters['supplier']
+			for rule in item_rules_list:
+				filters_dict[rule.restrict_based_on].append(rule.based_on_value)
 
-		if item_groups:
-			filters['item_group'] = ['in', item_groups]
+			for filter in filters_dict:
+				filters[scrub(filter)] = ['in', filters_dict[filter]]
+
+			if filters.get('customer'):
+				del filters['customer']
+			else:
+				del filters['supplier']
+
 
 	description_cond = ''
 	if frappe.db.count('Item', cache=True) < 50000:
@@ -307,7 +319,7 @@
 @frappe.validate_and_sanitize_search_inputs
 def get_project_name(doctype, txt, searchfield, start, page_len, filters):
 	cond = ''
-	if filters.get('customer'):
+	if filters and filters.get('customer'):
 		cond = """(`tabProject`.customer = %s or
 			ifnull(`tabProject`.customer,"")="") and""" %(frappe.db.escape(filters.get("customer")))
 
@@ -686,36 +698,6 @@
 
 @frappe.whitelist()
 @frappe.validate_and_sanitize_search_inputs
-def get_healthcare_service_units(doctype, txt, searchfield, start, page_len, filters):
-	query = """
-		select name
-		from `tabHealthcare Service Unit`
-		where
-			is_group = 0
-			and company = {company}
-			and name like {txt}""".format(
-				company = frappe.db.escape(filters.get('company')), txt = frappe.db.escape('%{0}%'.format(txt)))
-
-	if filters and filters.get('inpatient_record'):
-		from erpnext.healthcare.doctype.inpatient_medication_entry.inpatient_medication_entry import (
-			get_current_healthcare_service_unit,
-		)
-		service_unit = get_current_healthcare_service_unit(filters.get('inpatient_record'))
-
-		# if the patient is admitted, then appointments should be allowed against the admission service unit,
-		# inspite of it being an Inpatient Occupancy service unit
-		if service_unit:
-			query += " and (allow_appointments = 1 or name = {service_unit})".format(service_unit = frappe.db.escape(service_unit))
-		else:
-			query += " and allow_appointments = 1"
-	else:
-		query += " and allow_appointments = 1"
-
-	return frappe.db.sql(query, filters)
-
-
-@frappe.whitelist()
-@frappe.validate_and_sanitize_search_inputs
 def get_tax_template(doctype, txt, searchfield, start, page_len, filters):
 
 	item_doc = frappe.get_cached_doc('Item', filters.get('item_code'))
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 0158a11..bb269f3 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -424,7 +424,7 @@
 					or (cint(self.is_return) and self.docstatus==2)):
 						sl_entries.append(self.get_sle_for_source_warehouse(d))
 
-				if d.target_warehouse and self.get("is_internal_customer"):
+				if d.target_warehouse:
 					sl_entries.append(self.get_sle_for_target_warehouse(d))
 
 				if d.warehouse and ((not cint(self.is_return) and self.docstatus==2)
@@ -559,6 +559,12 @@
 				frappe.throw(_("Row {0}: Delivery Warehouse ({1}) and Customer Warehouse ({2}) can not be same")
 					.format(d.idx, warehouse, warehouse))
 
+		if not self.get("is_internal_customer") and any(d.get("target_warehouse") for d in items):
+			msg = _("Target Warehouse is set for some items but the customer is not an internal customer.")
+			msg += " " + _("This {} will be treated as material transfer.").format(_(self.doctype))
+			frappe.msgprint(msg, title="Internal Transfer", alert=True)
+
+
 	def validate_items(self):
 		# validate items to see if they have is_sales_item enabled
 		from erpnext.controllers.buying_controller import validate_item_type
diff --git a/erpnext/controllers/tests/test_queries.py b/erpnext/controllers/tests/test_queries.py
new file mode 100644
index 0000000..05541d1
--- /dev/null
+++ b/erpnext/controllers/tests/test_queries.py
@@ -0,0 +1,87 @@
+import unittest
+from functools import partial
+
+from erpnext.controllers import queries
+
+
+def add_default_params(func, doctype):
+	return partial(
+		func, doctype=doctype, txt="", searchfield="name", start=0, page_len=20, filters=None
+	)
+
+
+class TestQueries(unittest.TestCase):
+
+	# All tests are based on doctype/test_records.json
+
+	def assert_nested_in(self, item, container):
+		self.assertIn(item, [vals for tuples in container for vals in tuples])
+
+	def test_employee_query(self):
+		query = add_default_params(queries.employee_query, "Employee")
+
+		self.assertGreaterEqual(len(query(txt="_Test Employee")), 3)
+		self.assertGreaterEqual(len(query(txt="_Test Employee 1")), 1)
+
+	def test_lead_query(self):
+		query = add_default_params(queries.lead_query, "Lead")
+
+		self.assertGreaterEqual(len(query(txt="_Test Lead")), 4)
+		self.assertEqual(len(query(txt="_Test Lead 4")), 1)
+
+	def test_customer_query(self):
+		query = add_default_params(queries.customer_query, "Customer")
+
+		self.assertGreaterEqual(len(query(txt="_Test Customer")), 7)
+		self.assertGreaterEqual(len(query(txt="_Test Customer USD")), 1)
+
+	def test_supplier_query(self):
+		query = add_default_params(queries.supplier_query, "Supplier")
+
+		self.assertGreaterEqual(len(query(txt="_Test Supplier")), 7)
+		self.assertGreaterEqual(len(query(txt="_Test Supplier USD")), 1)
+
+	def test_item_query(self):
+		query = add_default_params(queries.item_query, "Item")
+
+		self.assertGreaterEqual(len(query(txt="_Test Item")), 7)
+		self.assertEqual(len(query(txt="_Test Item Home Desktop 100 3")), 1)
+
+		fg_item = "_Test FG Item"
+		stock_items = query(txt=fg_item, filters={"is_stock_item": 1})
+		self.assert_nested_in("_Test FG Item", stock_items)
+
+		bundled_stock_items = query(txt="_test product bundle item 5", filters={"is_stock_item": 1})
+		self.assertEqual(len(bundled_stock_items), 0)
+
+	def test_bom_qury(self):
+		query = add_default_params(queries.bom, "BOM")
+
+		self.assertGreaterEqual(len(query(txt="_Test Item Home Desktop Manufactured")), 1)
+
+	def test_project_query(self):
+		query = add_default_params(queries.get_project_name, "BOM")
+
+		self.assertGreaterEqual(len(query(txt="_Test Project")), 1)
+
+	def test_account_query(self):
+		query = add_default_params(queries.get_account_list, "Account")
+
+		debtor_accounts = query(txt="Debtors", filters={"company": "_Test Company"})
+		self.assert_nested_in("Debtors - _TC", debtor_accounts)
+
+	def test_income_account_query(self):
+		query = add_default_params(queries.get_income_account, "Account")
+
+		self.assertGreaterEqual(len(query(filters={"company": "_Test Company"})), 1)
+
+	def test_expense_account_query(self):
+		query = add_default_params(queries.get_expense_account, "Account")
+
+		self.assertGreaterEqual(len(query(filters={"company": "_Test Company"})), 1)
+
+	def test_warehouse_query(self):
+		query = add_default_params(queries.warehouse_query, "Account")
+
+		wh = query(filters=[["Bin", "item_code", "=", "_Test Item"]])
+		self.assertGreaterEqual(len(wh), 1)
diff --git a/erpnext/controllers/website_list_for_contact.py b/erpnext/controllers/website_list_for_contact.py
index ff2ed45..8e5952c 100644
--- a/erpnext/controllers/website_list_for_contact.py
+++ b/erpnext/controllers/website_list_for_contact.py
@@ -7,6 +7,7 @@
 
 import frappe
 from frappe import _
+from frappe.modules.utils import get_module_app
 from frappe.utils import flt, has_common
 from frappe.utils.user import is_website_user
 
@@ -21,8 +22,32 @@
 		"get_list": get_transaction_list
 	}
 
+def get_webform_list_context(module):
+	if get_module_app(module) != 'erpnext':
+		return
+	return {
+		"get_list": get_webform_transaction_list
+	}
 
-def get_transaction_list(doctype, txt=None, filters=None, limit_start=0, limit_page_length=20, order_by="modified"):
+def get_webform_transaction_list(doctype, txt=None, filters=None, limit_start=0, limit_page_length=20, order_by="modified"):
+	""" Get List of transactions for custom doctypes """
+	from frappe.www.list import get_list
+
+	if not filters:
+		filters = []
+
+	meta = frappe.get_meta(doctype)
+
+	for d in meta.fields:
+		if d.fieldtype == 'Link' and d.fieldname != 'amended_from':
+			allowed_docs = [d.name for d in get_transaction_list(doctype=d.options, custom=True)]
+			allowed_docs.append('')
+			filters.append((d.fieldname, 'in', allowed_docs))
+
+	return get_list(doctype, txt, filters, limit_start, limit_page_length, ignore_permissions=False,
+		fields=None, order_by="modified")
+
+def get_transaction_list(doctype, txt=None, filters=None, limit_start=0, limit_page_length=20, order_by="modified", custom=False):
 	user = frappe.session.user
 	ignore_permissions = False
 
@@ -46,7 +71,7 @@
 				filters.append(('customer', 'in', customers))
 		elif suppliers:
 			filters.append(('supplier', 'in', suppliers))
-		else:
+		elif not custom:
 			return []
 
 		if doctype == 'Request for Quotation':
@@ -56,9 +81,16 @@
 		# Since customers and supplier do not have direct access to internal doctypes
 		ignore_permissions = True
 
+		if not customers and not suppliers and custom:
+			ignore_permissions = False
+			filters = []
+
 	transactions = get_list_for_transactions(doctype, txt, filters, limit_start, limit_page_length,
 		fields='name', ignore_permissions=ignore_permissions, order_by='modified desc')
 
+	if custom:
+		return transactions
+
 	return post_process(doctype, transactions)
 
 def get_list_for_transactions(doctype, txt, filters, limit_start, limit_page_length=20,
diff --git a/erpnext/crm/doctype/lead/lead.js b/erpnext/crm/doctype/lead/lead.js
index 95cf032..999599c 100644
--- a/erpnext/crm/doctype/lead/lead.js
+++ b/erpnext/crm/doctype/lead/lead.js
@@ -51,7 +51,7 @@
 		}
 	}
 
-	add_lead_to_prospect (frm) {
+	add_lead_to_prospect () {
 		frappe.prompt([
 			{
 				fieldname: 'prospect',
@@ -65,7 +65,7 @@
 			frappe.call({
 				method: 'erpnext.crm.doctype.lead.lead.add_lead_to_prospect',
 				args: {
-					'lead': frm.doc.name,
+					'lead': cur_frm.doc.name,
 					'prospect': data.prospect
 				},
 				callback: function(r) {
@@ -79,41 +79,41 @@
 		}, __('Add Lead to Prospect'), __('Add'));
 	}
 
-	make_customer (frm) {
+	make_customer () {
 		frappe.model.open_mapped_doc({
 			method: "erpnext.crm.doctype.lead.lead.make_customer",
-			frm: frm
+			frm: cur_frm
 		})
 	}
 
-	make_opportunity (frm) {
+	make_opportunity () {
 		frappe.model.open_mapped_doc({
 			method: "erpnext.crm.doctype.lead.lead.make_opportunity",
-			frm: frm
+			frm: cur_frm
 		})
 	}
 
-	make_quotation (frm) {
+	make_quotation () {
 		frappe.model.open_mapped_doc({
 			method: "erpnext.crm.doctype.lead.lead.make_quotation",
-			frm: frm
+			frm: cur_frm
 		})
 	}
 
-	make_prospect (frm) {
+	make_prospect () {
 		frappe.model.with_doctype("Prospect", function() {
 			let prospect = frappe.model.get_new_doc("Prospect");
-			prospect.company_name = frm.doc.company_name;
-			prospect.no_of_employees = frm.doc.no_of_employees;
-			prospect.industry = frm.doc.industry;
-			prospect.market_segment = frm.doc.market_segment;
-			prospect.territory = frm.doc.territory;
-			prospect.fax = frm.doc.fax;
-			prospect.website = frm.doc.website;
-			prospect.prospect_owner = frm.doc.lead_owner;
+			prospect.company_name = cur_frm.doc.company_name;
+			prospect.no_of_employees = cur_frm.doc.no_of_employees;
+			prospect.industry = cur_frm.doc.industry;
+			prospect.market_segment = cur_frm.doc.market_segment;
+			prospect.territory = cur_frm.doc.territory;
+			prospect.fax = cur_frm.doc.fax;
+			prospect.website = cur_frm.doc.website;
+			prospect.prospect_owner = cur_frm.doc.lead_owner;
 
 			let lead_prospect_row = frappe.model.add_child(prospect, 'prospect_lead');
-			lead_prospect_row.lead = frm.doc.name;
+			lead_prospect_row.lead = cur_frm.doc.name;
 
 			frappe.set_route("Form", "Prospect", prospect.name);
 		});
diff --git a/erpnext/healthcare/doctype/prescription_dosage/__init__.py b/erpnext/crm/report/opportunity_summary_by_sales_stage/__init__.py
similarity index 100%
rename from erpnext/healthcare/doctype/prescription_dosage/__init__.py
rename to erpnext/crm/report/opportunity_summary_by_sales_stage/__init__.py
diff --git a/erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.js b/erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.js
new file mode 100644
index 0000000..116db2f
--- /dev/null
+++ b/erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.js
@@ -0,0 +1,65 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Opportunity Summary by Sales Stage"] = {
+	"filters": [
+		{
+			fieldname: "based_on",
+			label: __("Based On"),
+			fieldtype: "Select",
+			options: "Opportunity Owner\nSource\nOpportunity Type",
+			default: "Opportunity Owner"
+		},
+		{
+			fieldname: "data_based_on",
+			label: __("Data Based On"),
+			fieldtype: "Select",
+			options: "Number\nAmount",
+			default: "Number"
+		},
+		{
+			fieldname: "from_date",
+			label: __("From Date"),
+			fieldtype: "Date",
+
+		},
+		{
+			fieldname: "to_date",
+			label: __("To Date"),
+			fieldtype: "Date",
+		},
+		{
+			fieldname: "status",
+			label: __("Status"),
+			fieldtype: "MultiSelectList",
+			get_data: function() {
+				return [
+					{value: "Open", description: "Status"},
+					{value: "Converted", description: "Status"},
+					{value: "Quotation", description: "Status"},
+					{value: "Replied", description: "Status"}
+				]
+			}
+		},
+		{
+			fieldname: "opportunity_source",
+			label: __("Oppoturnity Source"),
+			fieldtype: "Link",
+			options: "Lead Source",
+		},
+		{
+			fieldname: "opportunity_type",
+			label: __("Opportunity Type"),
+			fieldtype: "Link",
+			options: "Opportunity Type",
+		},
+		{
+			fieldname: "company",
+			label: __("Company"),
+			fieldtype: "Link",
+			options: "Company",
+			default: frappe.defaults.get_user_default("Company")
+		}
+	]
+};
\ No newline at end of file
diff --git a/erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.json b/erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.json
new file mode 100644
index 0000000..3605aec
--- /dev/null
+++ b/erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.json
@@ -0,0 +1,29 @@
+{
+ "add_total_row": 0,
+ "columns": [],
+ "creation": "2021-07-28 12:18:24.028737",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "filters": [],
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2021-07-28 12:18:24.028737",
+ "modified_by": "Administrator",
+ "module": "CRM",
+ "name": "Opportunity Summary by Sales Stage",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Opportunity",
+ "report_name": "Opportunity Summary by Sales Stage ",
+ "report_type": "Script Report",
+ "roles": [
+  {
+   "role": "Sales User"
+  },
+  {
+   "role": "Sales Manager"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.py b/erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.py
new file mode 100644
index 0000000..4cff13f
--- /dev/null
+++ b/erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.py
@@ -0,0 +1,254 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+import json
+
+import frappe
+import pandas
+from frappe import _
+from frappe.utils import flt
+from six import iteritems
+
+from erpnext.setup.utils import get_exchange_rate
+
+
+def execute(filters=None):
+	return OpportunitySummaryBySalesStage(filters).run()
+
+class OpportunitySummaryBySalesStage(object):
+	def __init__(self,filters=None):
+		self.filters = frappe._dict(filters or {})
+
+	def run(self):
+		self.get_columns()
+		self.get_data()
+		self.get_chart_data()
+		return self.columns, self.data, None, self.chart
+
+	def get_columns(self):
+		self.columns = []
+
+		if self.filters.get('based_on') == 'Opportunity Owner':
+			self.columns.append({
+				'label': _('Opportunity Owner'),
+				'fieldname': 'opportunity_owner',
+				'width': 200
+			})
+
+		if self.filters.get('based_on') == 'Source':
+			self.columns.append({
+				'label': _('Source'),
+				'fieldname': 'source',
+				'fieldtype': 'Link',
+				'options': 'Lead Source',
+				'width': 200
+			})
+
+		if self.filters.get('based_on') == 'Opportunity Type':
+			self.columns.append({
+				'label': _('Opportunity Type'),
+				'fieldname': 'opportunity_type',
+				'width': 200
+			})
+
+		self.set_sales_stage_columns()
+
+	def set_sales_stage_columns(self):
+		self.sales_stage_list = frappe.db.get_list('Sales Stage', pluck='name')
+
+		for sales_stage in self.sales_stage_list:
+			if self.filters.get('data_based_on') == 'Number':
+				self.columns.append({
+					'label': _(sales_stage),
+					'fieldname': sales_stage,
+					'fieldtype': 'Int',
+					'width': 150
+				})
+
+			elif self.filters.get('data_based_on') == 'Amount':
+				self.columns.append({
+					'label': _(sales_stage),
+					'fieldname': sales_stage,
+					'fieldtype': 'Currency',
+					'width': 150
+				})
+
+	def get_data(self):
+		self.data = []
+
+		based_on = {
+			'Opportunity Owner': '_assign',
+			'Source': 'source',
+			'Opportunity Type': 'opportunity_type'
+		}[self.filters.get('based_on')]
+
+		data_based_on = {
+			'Number': 'count(name) as count',
+			'Amount': 'opportunity_amount as amount',
+		}[self.filters.get('data_based_on')]
+
+		self.get_data_query(based_on, data_based_on)
+
+		self.get_rows()
+
+	def get_data_query(self, based_on, data_based_on):
+		if self.filters.get('data_based_on') == 'Number':
+			group_by = '{},{}'.format('sales_stage', based_on)
+			self.query_result = frappe.db.get_list('Opportunity',
+				filters=self.get_conditions(),
+				fields=['sales_stage', data_based_on, based_on],
+				group_by=group_by
+			)
+
+		elif self.filters.get('data_based_on') == 'Amount':
+			self.query_result = frappe.db.get_list('Opportunity',
+				filters=self.get_conditions(),
+				fields=['sales_stage', based_on, data_based_on, 'currency']
+			)
+
+			self.convert_to_base_currency()
+
+			dataframe = pandas.DataFrame.from_records(self.query_result)
+			dataframe.replace(to_replace=[None], value='Not Assigned', inplace=True)
+			result = dataframe.groupby(['sales_stage', based_on], as_index=False)['amount'].sum()
+
+			self.grouped_data = []
+
+			for i in range(len(result['amount'])):
+				self.grouped_data.append({
+					'sales_stage': result['sales_stage'][i],
+					based_on : result[based_on][i],
+					'amount': result['amount'][i]
+				})
+
+			self.query_result = self.grouped_data
+
+	def get_rows(self):
+		self.data = []
+		self.get_formatted_data()
+
+		for based_on,data in iteritems(self.formatted_data):
+			row_based_on={
+				'Opportunity Owner': 'opportunity_owner',
+				'Source': 'source',
+				'Opportunity Type': 'opportunity_type'
+			}[self.filters.get('based_on')]
+
+			row = {row_based_on: based_on}
+
+			for d in self.query_result:
+				sales_stage = d.get('sales_stage')
+				row[sales_stage] = data.get(sales_stage)
+
+			self.data.append(row)
+
+	def get_formatted_data(self):
+		self.formatted_data = frappe._dict()
+
+		for d in self.query_result:
+			data_based_on ={
+				'Number': 'count',
+				'Amount': 'amount'
+			}[self.filters.get('data_based_on')]
+
+			based_on ={
+				'Opportunity Owner': '_assign',
+				'Source': 'source',
+				'Opportunity Type': 'opportunity_type'
+			}[self.filters.get('based_on')]
+
+			if self.filters.get('based_on') == 'Opportunity Owner':
+				if d.get(based_on) == '[]' or d.get(based_on) is None or d.get(based_on) == 'Not Assigned':
+					assignments = ['Not Assigned']
+				else:
+					assignments = json.loads(d.get(based_on))
+
+				sales_stage = d.get('sales_stage')
+				count = d.get(data_based_on)
+
+				if assignments:
+					if len(assignments) > 1:
+						for assigned_to in assignments:
+							self.set_formatted_data_based_on_sales_stage(assigned_to, sales_stage, count)
+					else:
+						assigned_to = assignments[0]
+						self.set_formatted_data_based_on_sales_stage(assigned_to, sales_stage, count)
+			else:
+				value = d.get(based_on)
+				sales_stage = d.get('sales_stage')
+				count = d.get(data_based_on)
+				self.set_formatted_data_based_on_sales_stage(value, sales_stage, count)
+
+	def set_formatted_data_based_on_sales_stage(self, based_on, sales_stage, count):
+		self.formatted_data.setdefault(based_on, frappe._dict()).setdefault(sales_stage, 0)
+		self.formatted_data[based_on][sales_stage] += count
+
+	def get_conditions(self):
+		filters = []
+
+		if self.filters.get('company'):
+			filters.append({'company': self.filters.get('company')})
+
+		if self.filters.get('opportunity_type'):
+			filters.append({'opportunity_type': self.filters.get('opportunity_type')})
+
+		if self.filters.get('opportunity_source'):
+			filters.append({'source': self.filters.get('opportunity_source')})
+
+		if self.filters.get('status'):
+			filters.append({'status': ('in',self.filters.get('status'))})
+
+		if self.filters.get('from_date') and self.filters.get('to_date'):
+			filters.append(['transaction_date', 'between', [self.filters.get('from_date'), self.filters.get('to_date')]])
+
+		return filters
+
+	def get_chart_data(self):
+		labels = []
+		datasets = []
+		values = [0] * 8
+
+		for sales_stage in self.sales_stage_list:
+			labels.append(sales_stage)
+
+		options = {
+			'Number': 'count',
+			'Amount': 'amount'
+		}[self.filters.get('data_based_on')]
+
+		for data in self.query_result:
+			for count in range(len(values)):
+				if data['sales_stage'] == labels[count]:
+					values[count] = values[count] + data[options]
+
+		datasets.append({'name':options, 'values':values})
+
+		self.chart = {
+			'data':{
+				'labels': labels,
+				'datasets': datasets
+			},
+			'type':'line'
+		}
+
+	def currency_conversion(self,from_currency,to_currency):
+		cacheobj = frappe.cache()
+
+		if cacheobj.get(from_currency):
+			return flt(str(cacheobj.get(from_currency),'UTF-8'))
+
+		else:
+			value = get_exchange_rate(from_currency,to_currency)
+			cacheobj.set(from_currency,value)
+			return flt(str(cacheobj.get(from_currency),'UTF-8'))
+
+	def get_default_currency(self):
+		company = self.filters.get('company')
+		return frappe.db.get_value('Company', company, 'default_currency')
+
+	def convert_to_base_currency(self):
+		default_currency = self.get_default_currency()
+		for data in self.query_result:
+			if data.get('currency') != default_currency:
+				opportunity_currency = data.get('currency')
+				value = self.currency_conversion(opportunity_currency,default_currency)
+				data['amount'] = data['amount'] * value
\ No newline at end of file
diff --git a/erpnext/crm/report/opportunity_summary_by_sales_stage/test_opportunity_summary_by_sales_stage.py b/erpnext/crm/report/opportunity_summary_by_sales_stage/test_opportunity_summary_by_sales_stage.py
new file mode 100644
index 0000000..13859d9
--- /dev/null
+++ b/erpnext/crm/report/opportunity_summary_by_sales_stage/test_opportunity_summary_by_sales_stage.py
@@ -0,0 +1,94 @@
+import unittest
+
+import frappe
+
+from erpnext.crm.report.opportunity_summary_by_sales_stage.opportunity_summary_by_sales_stage import (
+	execute,
+)
+from erpnext.crm.report.sales_pipeline_analytics.test_sales_pipeline_analytics import (
+	create_company,
+	create_customer,
+	create_opportunity,
+)
+
+
+class TestOpportunitySummaryBySalesStage(unittest.TestCase):
+	@classmethod
+	def setUpClass(self):
+		frappe.db.delete("Opportunity")
+		create_company()
+		create_customer()
+		create_opportunity()
+
+	def test_opportunity_summary_by_sales_stage(self):
+		self.check_for_opportunity_owner()
+		self.check_for_source()
+		self.check_for_opportunity_type()
+		self.check_all_filters()
+
+	def check_for_opportunity_owner(self):
+		filters = {
+			'based_on': "Opportunity Owner",
+			'data_based_on': "Number",
+			'company': "Best Test"
+		}
+
+		report = execute(filters)
+
+		expected_data = [{
+			'opportunity_owner': "Not Assigned",
+			'Prospecting': 1
+		}]
+
+		self.assertEqual(expected_data, report[1])
+
+	def check_for_source(self):
+		filters = {
+			'based_on': "Source",
+			'data_based_on': "Number",
+			'company': "Best Test"
+		}
+
+		report = execute(filters)
+
+		expected_data = [{
+			'source': 'Cold Calling',
+			'Prospecting': 1
+		}]
+
+		self.assertEqual(expected_data, report[1])
+
+	def check_for_opportunity_type(self):
+		filters = {
+			'based_on': "Opportunity Type",
+			'data_based_on': "Number",
+			'company': "Best Test"
+		}
+
+		report = execute(filters)
+
+		expected_data = [{
+			'opportunity_type': 'Sales',
+			'Prospecting': 1
+		}]
+
+		self.assertEqual(expected_data, report[1])
+
+	def check_all_filters(self):
+		filters = {
+			'based_on': "Opportunity Type",
+			'data_based_on': "Number",
+			'company': "Best Test",
+			'opportunity_source': "Cold Calling",
+			'opportunity_type': "Sales",
+			'status': ["Open"]
+		}
+
+		report = execute(filters)
+
+		expected_data = [{
+			'opportunity_type': 'Sales',
+			'Prospecting': 1
+		}]
+
+		self.assertEqual(expected_data, report[1])
\ No newline at end of file
diff --git a/erpnext/healthcare/report/patient_appointment_analytics/__init__.py b/erpnext/crm/report/sales_pipeline_analytics/__init__.py
similarity index 100%
rename from erpnext/healthcare/report/patient_appointment_analytics/__init__.py
rename to erpnext/crm/report/sales_pipeline_analytics/__init__.py
diff --git a/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.js b/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.js
new file mode 100644
index 0000000..1426f4b
--- /dev/null
+++ b/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.js
@@ -0,0 +1,70 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Sales Pipeline Analytics"] = {
+	"filters": [
+		{
+			fieldname: "pipeline_by",
+			label: __("Pipeline By"),
+			fieldtype: "Select",
+			options: "Owner\nSales Stage",
+			default: "Owner"
+		},
+		{
+			fieldname: "from_date",
+			label: __("From Date"),
+			fieldtype: "Date"
+		},
+		{
+			fieldname: "to_date",
+			label: __("To Date"),
+			fieldtype: "Date"
+		},
+		{
+			fieldname: "range",
+			label: __("Range"),
+			fieldtype: "Select",
+			options: "Monthly\nQuarterly",
+			default: "Monthly"
+		},
+		{
+			fieldname: "assigned_to",
+			label: __("Assigned To"),
+			fieldtype: "Link",
+			options: "User"
+		},
+		{
+			fieldname: "status",
+			label: __("Status"),
+			fieldtype: "Select",
+			options: "Open\nQuotation\nConverted\nReplied"
+		},
+		{
+			fieldname: "based_on",
+			label: __("Based On"),
+			fieldtype: "Select",
+			options: "Number\nAmount",
+			default: "Number"
+		},
+		{
+			fieldname: "company",
+			label: __("Company"),
+			fieldtype: "Link",
+			options: "Company",
+			default: frappe.defaults.get_user_default("Company")
+		},
+		{
+			fieldname: "opportunity_source",
+			label: __("Opportunity Source"),
+			fieldtype: "Link",
+			options: "Lead Source"
+		},
+		{
+			fieldname: "opportunity_type",
+			label: __("Opportunity Type"),
+			fieldtype: "Link",
+			options: "Opportunity Type"
+		},
+	]
+};
diff --git a/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.json b/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.json
new file mode 100644
index 0000000..cffdddf
--- /dev/null
+++ b/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.json
@@ -0,0 +1,29 @@
+{
+ "add_total_row": 0,
+ "columns": [],
+ "creation": "2021-07-01 17:29:09.530787",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "filters": [],
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2021-07-01 17:45:17.612861",
+ "modified_by": "Administrator",
+ "module": "CRM",
+ "name": "Sales Pipeline Analytics",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Opportunity",
+ "report_name": "Sales Pipeline Analytics",
+ "report_type": "Script Report",
+ "roles": [
+  {
+   "role": "Sales User"
+  },
+  {
+   "role": "Sales Manager"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py b/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py
new file mode 100644
index 0000000..7466982
--- /dev/null
+++ b/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py
@@ -0,0 +1,333 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+import json
+from datetime import date
+
+import frappe
+import pandas
+from dateutil.relativedelta import relativedelta
+from frappe import _
+from frappe.utils import cint, flt
+from six import iteritems
+
+from erpnext.setup.utils import get_exchange_rate
+
+
+def execute(filters=None):
+	return SalesPipelineAnalytics(filters).run()
+
+class SalesPipelineAnalytics(object):
+	def __init__(self, filters=None):
+		self.filters = frappe._dict(filters or {})
+
+	def run(self):
+		self.get_columns()
+		self.get_data()
+		self.get_chart_data()
+
+		return self.columns, self.data, None, self.chart
+
+	def get_columns(self):
+		self.columns = []
+
+		self.set_range_columns()
+		self.set_pipeline_based_on_column()
+
+	def set_range_columns(self):
+		based_on = {
+			'Number': 'Int',
+			'Amount': 'Currency'
+		}[self.filters.get('based_on')]
+
+		if self.filters.get('range') == 'Monthly':
+			month_list = self.get_month_list()
+
+			for month in month_list:
+				self.columns.append({
+					'fieldname': month,
+					'fieldtype': based_on,
+					'label': month,
+					'width': 200
+				})
+
+		elif self.filters.get('range') == 'Quarterly':
+			for quarter in range(1, 5):
+				self.columns.append({
+					'fieldname': f'Q{quarter}',
+					'fieldtype': based_on,
+					'label': f'Q{quarter}',
+					'width': 200
+				})
+
+	def set_pipeline_based_on_column(self):
+		if self.filters.get('pipeline_by') == 'Owner':
+			self.columns.insert(0, {
+				'fieldname': 'opportunity_owner',
+				'label': _('Opportunity Owner'),
+				'width': 200
+			})
+
+		elif self.filters.get('pipeline_by') == 'Sales Stage':
+			self.columns.insert(0, {
+				'fieldname': 'sales_stage',
+				'label': _('Sales Stage'),
+				'width': 200
+			})
+
+	def get_fields(self):
+		self.based_on ={
+			'Owner': '_assign as opportunity_owner',
+			'Sales Stage': 'sales_stage'
+		}[self.filters.get('pipeline_by')]
+
+		self.data_based_on ={
+			'Number': 'count(name) as count',
+			'Amount': 'opportunity_amount as amount'
+		}[self.filters.get('based_on')]
+
+		self.group_by_based_on = {
+			'Owner': '_assign',
+			'Sales Stage': 'sales_stage'
+		}[self.filters.get('pipeline_by')]
+
+		self.group_by_period = {
+			'Monthly': 'month(expected_closing)',
+			'Quarterly': 'QUARTER(expected_closing)'
+		}[self.filters.get('range')]
+
+		self.pipeline_by = {
+			'Owner': 'opportunity_owner',
+			'Sales Stage': 'sales_stage'
+		}[self.filters.get('pipeline_by')]
+
+		self.duration = {
+			'Monthly': 'monthname(expected_closing) as month',
+			'Quarterly': 'QUARTER(expected_closing) as quarter'
+		}[self.filters.get('range')]
+
+		self.period_by = {
+			'Monthly': 'month',
+			'Quarterly': 'quarter'
+		}[self.filters.get('range')]
+
+	def get_data(self):
+		self.get_fields()
+
+		if self.filters.get('based_on') == 'Number':
+			self.query_result = frappe.db.get_list('Opportunity',
+				filters=self.get_conditions(),
+				fields=[self.based_on, self.data_based_on, self.duration],
+				group_by='{},{}'.format(self.group_by_based_on, self.group_by_period),
+				order_by=self.group_by_period
+			)
+
+		if self.filters.get('based_on') == 'Amount':
+			self.query_result = frappe.db.get_list('Opportunity',
+				filters=self.get_conditions(),
+				fields=[self.based_on, self.data_based_on, self.duration, 'currency']
+			)
+
+			self.convert_to_base_currency()
+
+			dataframe = pandas.DataFrame.from_records(self.query_result)
+			dataframe.replace(to_replace=[None], value='Not Assigned', inplace=True)
+			result = dataframe.groupby([self.pipeline_by, self.period_by], as_index=False)['amount'].sum()
+
+			self.grouped_data = []
+
+			for i in range(len(result['amount'])):
+				self.grouped_data.append({
+					self.pipeline_by : result[self.pipeline_by][i],
+					self.period_by : result[self.period_by][i],
+					'amount': result['amount'][i]
+				})
+
+			self.query_result = self.grouped_data
+
+		self.get_periodic_data()
+		self.append_data(self.pipeline_by, self.period_by)
+
+	def get_conditions(self):
+		conditions = []
+
+		if self.filters.get('opportunity_source'):
+			conditions.append({'source': self.filters.get('opportunity_source')})
+
+		if self.filters.get('opportunity_type'):
+			conditions.append({'opportunity_type': self.filters.get('opportunity_type')})
+
+		if self.filters.get('status'):
+			conditions.append({'status': self.filters.get('status')})
+
+		if self.filters.get('company'):
+			conditions.append({'company': self.filters.get('company')})
+
+		if self.filters.get('from_date') and self.filters.get('to_date'):
+			conditions.append(['expected_closing', 'between',
+				[self.filters.get('from_date'), self.filters.get('to_date')]])
+
+		return conditions
+
+	def get_chart_data(self):
+		labels = []
+		datasets = []
+
+		self.append_to_dataset(datasets)
+
+		for column in self.columns:
+			if column['fieldname'] != 'opportunity_owner' and column['fieldname'] != 'sales_stage':
+				labels.append(column['fieldname'])
+
+		self.chart = {
+			'data':{
+				'labels': labels,
+				'datasets': datasets
+			},
+			'type':'line'
+		}
+
+		return self.chart
+
+	def get_periodic_data(self):
+		self.periodic_data = frappe._dict()
+
+		based_on = {
+			'Number': 'count',
+			'Amount': 'amount'
+		}[self.filters.get('based_on')]
+
+		pipeline_by = {
+			'Owner': 'opportunity_owner',
+			'Sales Stage': 'sales_stage'
+		}[self.filters.get('pipeline_by')]
+
+		frequency = {
+			'Monthly': 'month',
+			'Quarterly': 'quarter'
+		}[self.filters.get('range')]
+
+		for info in self.query_result:
+			if self.filters.get('range') == 'Monthly':
+				period = info.get(frequency)
+			if self.filters.get('range') == 'Quarterly':
+				period = f'Q{cint(info.get("quarter"))}'
+
+			value = info.get(pipeline_by)
+			count_or_amount = info.get(based_on)
+
+			if self.filters.get('pipeline_by') == 'Owner':
+				if value == 'Not Assigned' or value == '[]' or value is None:
+					assigned_to = ['Not Assigned']
+				else:
+					assigned_to = json.loads(value)
+				self.check_for_assigned_to(period, value, count_or_amount, assigned_to, info)
+
+			else:
+				self.set_formatted_data(period, value, count_or_amount, None)
+
+	def set_formatted_data(self, period, value, count_or_amount, assigned_to):
+		if assigned_to:
+			if len(assigned_to) > 1:
+				if self.filters.get('assigned_to'):
+					for user in assigned_to:
+						if self.filters.get('assigned_to') == user:
+							value = user
+							self.periodic_data.setdefault(value, frappe._dict()).setdefault(period, 0)
+							self.periodic_data[value][period] += count_or_amount
+				else:
+					for user in assigned_to:
+						value = user
+						self.periodic_data.setdefault(value, frappe._dict()).setdefault(period, 0)
+						self.periodic_data[value][period] += count_or_amount
+			else:
+				value = assigned_to[0]
+				self.periodic_data.setdefault(value, frappe._dict()).setdefault(period, 0)
+				self.periodic_data[value][period] += count_or_amount
+
+		else:
+			self.periodic_data.setdefault(value, frappe._dict()).setdefault(period, 0)
+			self.periodic_data[value][period] += count_or_amount
+
+	def check_for_assigned_to(self, period, value, count_or_amount, assigned_to, info):
+		if self.filters.get('assigned_to'):
+			for data in json.loads(info.get('opportunity_owner')):
+				if data == self.filters.get('assigned_to'):
+					self.set_formatted_data(period, data, count_or_amount, assigned_to)
+		else:
+			self.set_formatted_data(period, value, count_or_amount, assigned_to)
+
+	def get_month_list(self):
+		month_list= []
+		current_date = date.today()
+		month_number = date.today().month
+
+		for month in range(month_number,13):
+			month_list.append(current_date.strftime('%B'))
+			current_date = current_date + relativedelta(months=1)
+
+		return month_list
+
+	def append_to_dataset(self, datasets):
+		range_by = {
+			'Monthly': 'month',
+			'Quarterly': 'quarter'
+		}[self.filters.get('range')]
+
+		based_on = {
+			'Amount': 'amount',
+			'Number': 'count'
+		}[self.filters.get('based_on')]
+
+		if self.filters.get('range') == 'Quarterly':
+			frequency_list = [1,2,3,4]
+			count = [0] * 4
+
+		if self.filters.get('range') == 'Monthly':
+			frequency_list = self.get_month_list()
+			count = [0] * 12
+
+		for info in self.query_result:
+			for i in range(len(frequency_list)):
+				if info[range_by] == frequency_list[i]:
+					count[i] = count[i] + info[based_on]
+		datasets.append({'name': based_on, 'values': count})
+
+	def append_data(self, pipeline_by, period_by):
+		self.data = []
+		for pipeline,period_data in iteritems(self.periodic_data):
+			row = {pipeline_by : pipeline}
+			for info in self.query_result:
+				if self.filters.get('range') == 'Monthly':
+					period = info.get(period_by)
+
+				if self.filters.get('range') == 'Quarterly':
+					period = f'Q{cint(info.get(period_by))}'
+
+				count = period_data.get(period,0.0)
+				row[period] = count
+
+			self.data.append(row)
+
+	def get_default_currency(self):
+		company = self.filters.get('company')
+		return frappe.db.get_value('Company',company,['default_currency'])
+
+	def get_currency_rate(self, from_currency, to_currency):
+		cacheobj = frappe.cache()
+
+		if cacheobj.get(from_currency):
+			return flt(str(cacheobj.get(from_currency),'UTF-8'))
+
+		else:
+			value = get_exchange_rate(from_currency, to_currency)
+			cacheobj.set(from_currency, value)
+			return flt(str(cacheobj.get(from_currency),'UTF-8'))
+
+	def convert_to_base_currency(self):
+		default_currency = self.get_default_currency()
+		for data in self.query_result:
+			if data.get('currency') != default_currency:
+				opportunity_currency = data.get('currency')
+				value = self.get_currency_rate(opportunity_currency,default_currency)
+				data['amount'] = data['amount'] * value
\ No newline at end of file
diff --git a/erpnext/crm/report/sales_pipeline_analytics/test_sales_pipeline_analytics.py b/erpnext/crm/report/sales_pipeline_analytics/test_sales_pipeline_analytics.py
new file mode 100644
index 0000000..24c3839
--- /dev/null
+++ b/erpnext/crm/report/sales_pipeline_analytics/test_sales_pipeline_analytics.py
@@ -0,0 +1,238 @@
+import unittest
+
+import frappe
+
+from erpnext.crm.report.sales_pipeline_analytics.sales_pipeline_analytics import execute
+
+
+class TestSalesPipelineAnalytics(unittest.TestCase):
+	@classmethod
+	def setUpClass(self):
+		frappe.db.delete("Opportunity")
+		create_company()
+		create_customer()
+		create_opportunity()
+
+	def test_sales_pipeline_analytics(self):
+		self.check_for_monthly_and_number()
+		self.check_for_monthly_and_amount()
+		self.check_for_quarterly_and_number()
+		self.check_for_quarterly_and_amount()
+		self.check_for_all_filters()
+
+	def check_for_monthly_and_number(self):
+		filters = {
+			'pipeline_by':"Owner",
+			'range':"Monthly",
+			'based_on':"Number",
+			'status':"Open",
+			'opportunity_type':"Sales",
+			'company':"Best Test"
+		}
+
+		report = execute(filters)
+
+		expected_data = [
+			{
+				'opportunity_owner':'Not Assigned',
+				'August':1
+			}
+		]
+
+		self.assertEqual(expected_data,report[1])
+
+		filters = {
+			'pipeline_by':"Sales Stage",
+			'range':"Monthly",
+			'based_on':"Number",
+			'status':"Open",
+			'opportunity_type':"Sales",
+			'company':"Best Test"
+		}
+
+		report = execute(filters)
+
+		expected_data = [
+			{
+				'sales_stage':'Prospecting',
+				'August':1
+			}
+		]
+
+		self.assertEqual(expected_data,report[1])
+
+	def check_for_monthly_and_amount(self):
+		filters = {
+			'pipeline_by':"Owner",
+			'range':"Monthly",
+			'based_on':"Amount",
+			'status':"Open",
+			'opportunity_type':"Sales",
+			'company':"Best Test"
+		}
+
+		report = execute(filters)
+
+		expected_data = [
+			{
+				'opportunity_owner':'Not Assigned',
+				'August':150000
+			}
+		]
+
+		self.assertEqual(expected_data,report[1])
+
+		filters = {
+			'pipeline_by':"Sales Stage",
+			'range':"Monthly",
+			'based_on':"Amount",
+			'status':"Open",
+			'opportunity_type':"Sales",
+			'company':"Best Test"
+		}
+
+		report = execute(filters)
+
+		expected_data = [
+			{
+				'sales_stage':'Prospecting',
+				'August':150000
+			}
+		]
+
+		self.assertEqual(expected_data,report[1])
+
+	def check_for_quarterly_and_number(self):
+		filters = {
+			'pipeline_by':"Owner",
+			'range':"Quarterly",
+			'based_on':"Number",
+			'status':"Open",
+			'opportunity_type':"Sales",
+			'company':"Best Test"
+		}
+
+		report = execute(filters)
+
+		expected_data = [
+			{
+				'opportunity_owner':'Not Assigned',
+				'Q3':1
+			}
+		]
+
+		self.assertEqual(expected_data,report[1])
+
+		filters = {
+			'pipeline_by':"Sales Stage",
+			'range':"Quarterly",
+			'based_on':"Number",
+			'status':"Open",
+			'opportunity_type':"Sales",
+			'company':"Best Test"
+		}
+
+		report = execute(filters)
+
+		expected_data = [
+			{
+				'sales_stage':'Prospecting',
+				'Q3':1
+			}
+		]
+
+		self.assertEqual(expected_data,report[1])
+
+	def check_for_quarterly_and_amount(self):
+		filters = {
+			'pipeline_by':"Owner",
+			'range':"Quarterly",
+			'based_on':"Amount",
+			'status':"Open",
+			'opportunity_type':"Sales",
+			'company':"Best Test"
+		}
+
+		report = execute(filters)
+
+		expected_data = [
+			{
+				'opportunity_owner':'Not Assigned',
+				'Q3':150000
+			}
+		]
+
+		self.assertEqual(expected_data,report[1])
+
+		filters = {
+			'pipeline_by':"Sales Stage",
+			'range':"Quarterly",
+			'based_on':"Amount",
+			'status':"Open",
+			'opportunity_type':"Sales",
+			'company':"Best Test"
+		}
+
+		report = execute(filters)
+
+		expected_data = [
+			{
+				'sales_stage':'Prospecting',
+				'Q3':150000
+			}
+		]
+
+		self.assertEqual(expected_data,report[1])
+
+	def check_for_all_filters(self):
+		filters = {
+			'pipeline_by':"Owner",
+			'range':"Monthly",
+			'based_on':"Number",
+			'status':"Open",
+			'opportunity_type':"Sales",
+			'company':"Best Test",
+			'opportunity_source':'Cold Calling',
+			'from_date': '2021-08-01',
+			'to_date':'2021-08-31'
+		}
+
+		report = execute(filters)
+
+		expected_data = [
+			{
+				'opportunity_owner':'Not Assigned',
+				'August': 1
+			}
+		]
+
+		self.assertEqual(expected_data,report[1])
+
+def create_company():
+	doc = frappe.db.exists('Company','Best Test')
+	if not doc:
+		doc = frappe.new_doc('Company')
+		doc.company_name = 'Best Test'
+		doc.default_currency = "INR"
+		doc.insert()
+
+def create_customer():
+	doc = frappe.db.exists("Customer","_Test NC")
+	if not doc:
+		doc = frappe.new_doc("Customer")
+		doc.customer_name = '_Test NC'
+		doc.insert()
+
+def create_opportunity():
+	doc = frappe.db.exists({"doctype":"Opportunity","party_name":"_Test NC"})
+	if not doc:
+		doc = frappe.new_doc("Opportunity")
+		doc.opportunity_from = "Customer"
+		customer_name = frappe.db.get_value("Customer",{"customer_name":'_Test NC'},['customer_name'])
+		doc.party_name = customer_name
+		doc.opportunity_amount = 150000
+		doc.source = "Cold Calling"
+		doc.currency = "INR"
+		doc.expected_closing = "2021-08-31"
+		doc.company = 'Best Test'
+		doc.insert()
\ No newline at end of file
diff --git a/erpnext/crm/workspace/crm/crm.json b/erpnext/crm/workspace/crm/crm.json
index c363395..a661b62 100644
--- a/erpnext/crm/workspace/crm/crm.json
+++ b/erpnext/crm/workspace/crm/crm.json
@@ -148,6 +148,24 @@
    "type": "Link"
   },
   {
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Sales Pipeline Analytics",
+   "link_to": "Sales Pipeline Analytics",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Opportunity Summary by Sales Stage",
+   "link_to": "Opportunity Summary by Sales Stage",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
    "dependencies": "",
    "hidden": 0,
    "is_query_report": 0,
@@ -403,7 +421,7 @@
    "type": "Link"
   }
  ],
- "modified": "2021-08-05 12:15:56.913091",
+ "modified": "2021-08-19 19:08:08.728876",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "CRM",
diff --git a/erpnext/demo/demo.py b/erpnext/demo/demo.py
index 5be2420..bd744b2 100644
--- a/erpnext/demo/demo.py
+++ b/erpnext/demo/demo.py
@@ -6,7 +6,7 @@
 import frappe.utils
 
 import erpnext
-from erpnext.demo.setup import education, healthcare, manufacture, retail, setup_data
+from erpnext.demo.setup import education, manufacture, retail, setup_data
 from erpnext.demo.user import accounts
 from erpnext.demo.user import education as edu
 from erpnext.demo.user import fixed_asset, hr, manufacturing, projects, purchase, sales, stock
@@ -38,8 +38,6 @@
 		retail.setup_data()
 	elif domain== 'Education':
 		education.setup_data()
-	elif domain== 'Healthcare':
-		healthcare.setup_data()
 
 	site = frappe.local.site
 	frappe.destroy()
diff --git a/erpnext/demo/domains.py b/erpnext/demo/domains.py
index b1db7b5..7f48b92 100644
--- a/erpnext/demo/domains.py
+++ b/erpnext/demo/domains.py
@@ -16,9 +16,6 @@
 	'Education': {
 		'company_name': 'Whitmore College'
 	},
-	'Healthcare': {
-		'company_name': 'ABC Hospital Ltd.'
-	},
 	'Agriculture': {
 		'company_name': 'Schrute Farms'
   },
diff --git a/erpnext/demo/setup/healthcare.py b/erpnext/demo/setup/healthcare.py
deleted file mode 100644
index 5d5707f..0000000
--- a/erpnext/demo/setup/healthcare.py
+++ /dev/null
@@ -1,171 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
-
-import datetime
-import json
-
-import frappe
-from frappe.utils import getdate
-from frappe.utils.make_random import get_random
-
-from erpnext.demo.setup.setup_data import import_json
-from erpnext.healthcare.doctype.lab_test.lab_test import create_test_from_template
-
-
-def setup_data():
-	frappe.flags.mute_emails = True
-	make_masters()
-	make_patient()
-	make_lab_test()
-	make_consulation()
-	make_appointment()
-	consulation_on_appointment()
-	lab_test_on_encounter()
-	frappe.db.commit()
-	frappe.clear_cache()
-
-def make_masters():
-	import_json("Healthcare Practitioner")
-	import_drug()
-	frappe.db.commit()
-
-def make_patient():
-	file_path = get_json_path("Patient")
-	with open(file_path, "r") as open_file:
-		patient_data = json.loads(open_file.read())
-		count = 1
-
-		for d in enumerate(patient_data):
-			patient = frappe.new_doc("Patient")
-			patient.patient_name = d[1]['patient_name'].title()
-			patient.sex = d[1]['gender']
-			patient.blood_group = "A Positive"
-			patient.date_of_birth = datetime.datetime(1990, 3, 25)
-			patient.email_id = d[1]['patient_name'] + "_" + patient.date_of_birth.strftime('%m/%d/%Y') + "@example.com"
-			if count <5:
-				patient.insert()
-				frappe.db.commit()
-			count+=1
-
-def make_appointment():
-	i = 1
-	while i <= 4:
-		practitioner = get_random("Healthcare Practitioner")
-		department = frappe.get_value("Healthcare Practitioner", practitioner, "department")
-		patient = get_random("Patient")
-		patient_sex = frappe.get_value("Patient", patient, "sex")
-		appointment = frappe.new_doc("Patient Appointment")
-		startDate = datetime.datetime.now()
-		for x in random_date(startDate,0):
-			appointment_datetime = x
-		appointment.appointment_datetime = appointment_datetime
-		appointment.appointment_time = appointment_datetime
-		appointment.appointment_date = appointment_datetime
-		appointment.patient = patient
-		appointment.patient_sex = patient_sex
-		appointment.practitioner = practitioner
-		appointment.department = department
-		appointment.save(ignore_permissions = True)
-		i += 1
-
-def make_consulation():
-	for i in range(3):
-		practitioner = get_random("Healthcare Practitioner")
-		department = frappe.get_value("Healthcare Practitioner", practitioner, "department")
-		patient = get_random("Patient")
-		patient_sex = frappe.get_value("Patient", patient, "sex")
-		encounter = set_encounter(patient, patient_sex, practitioner, department, getdate(), i)
-		encounter.save(ignore_permissions=True)
-
-def consulation_on_appointment():
-	for i in range(3):
-		appointment = get_random("Patient Appointment")
-		appointment = frappe.get_doc("Patient Appointment",appointment)
-		encounter = set_encounter(appointment.patient, appointment.patient_sex, appointment.practitioner, appointment.department, appointment.appointment_date, i)
-		encounter.appointment = appointment.name
-		encounter.save(ignore_permissions=True)
-
-def set_encounter(patient, patient_sex, practitioner, department, encounter_date, i):
-	encounter = frappe.new_doc("Patient Encounter")
-	encounter.patient = patient
-	encounter.patient_sex = patient_sex
-	encounter.practitioner = practitioner
-	encounter.visit_department = department
-	encounter.encounter_date = encounter_date
-	if i > 2 and patient_sex=='Female':
-		encounter.symptoms = "Having chest pains for the last week."
-		encounter.diagnosis = """This patient's description of dull, aching,
-		exertion related substernal chest pain is suggestive of ischemic
-		cardiac origin. Her findings of a FH of early ASCVD, hypertension,
-		and early surgical menopause are pertinent risk factors for development
-		of coronary artery disease. """
-	else:
-		encounter = append_drug_rx(encounter)
-		encounter = append_test_rx(encounter)
-	return encounter
-
-def make_lab_test():
-	practitioner = get_random("Healthcare Practitioner")
-	patient = get_random("Patient")
-	patient_sex = frappe.get_value("Patient", patient, "sex")
-	template = get_random("Lab Test Template")
-	set_lab_test(patient, patient_sex, practitioner, template)
-
-def lab_test_on_encounter():
-	i = 1
-	while i <= 2:
-		test_rx = get_random("Lab Prescription", filters={'test_created': 0})
-		test_rx = frappe.get_doc("Lab Prescription", test_rx)
-		encounter = frappe.get_doc("Patient Encounter", test_rx.parent)
-		set_lab_test(encounter.patient, encounter.patient_sex, encounter.practitioner, test_rx.test_code, test_rx.name)
-		i += 1
-
-def set_lab_test(patient, patient_sex, practitioner, template, rx=None):
-	lab_test = frappe.new_doc("Lab Test")
-	lab_test.practitioner = practitioner
-	lab_test.patient = patient
-	lab_test.patient_sex = patient_sex
-	lab_test.template = template
-	lab_test.prescription = rx
-	create_test_from_template(lab_test)
-
-def append_test_rx(encounter):
-	i = 1
-	while i <= 2:
-		test_rx = encounter.append("test_prescription")
-		test_rx.test_code = get_random("Lab Test Template")
-		i += 1
-	return encounter
-
-def append_drug_rx(encounter):
-	i = 1
-	while i <= 3:
-		drug = get_random("Item", filters={"item_group":"Drug"})
-		drug = frappe.get_doc("Item", drug)
-		drug_rx = encounter.append("drug_prescription")
-		drug_rx.drug_code = drug.item_code
-		drug_rx.drug_name = drug.item_name
-		drug_rx.dosage = get_random("Prescription Dosage")
-		drug_rx.period = get_random("Prescription Duration")
-		i += 1
-	return encounter
-
-def random_date(start,l):
-   current = start
-   while l >= 0:
-      curr = current + datetime.timedelta(minutes=60)
-      yield curr
-      l-=1
-
-def import_drug():
-	frappe.flags.in_import = True
-	data = json.loads(open(frappe.get_app_path('erpnext', 'demo', 'data', 'drug_list.json')).read())
-	for d in data:
-		doc = frappe.new_doc("Item")
-		doc.update(d)
-		doc.insert()
-	frappe.flags.in_import = False
-
-def get_json_path(doctype):
-		return frappe.get_app_path('erpnext', 'demo', 'data', frappe.scrub(doctype) + '.json')
diff --git a/erpnext/demo/setup/setup_data.py b/erpnext/demo/setup/setup_data.py
index 42f83a3..af53043 100644
--- a/erpnext/demo/setup/setup_data.py
+++ b/erpnext/demo/setup/setup_data.py
@@ -196,10 +196,6 @@
 		'Purchase Manager', 'Projects User', 'Manufacturing User', 'Manufacturing Manager',
 		'Support Team')
 
-	if domain == "Healthcare":
-		user.add_roles('Physician', 'Healthcare Administrator', 'Laboratory User',
-			'Nursing User', 'Patient')
-
 	if domain == "Education":
 		user.add_roles('Academics User')
 
diff --git a/erpnext/domains/healthcare.py b/erpnext/domains/healthcare.py
deleted file mode 100644
index bbeb2c6..0000000
--- a/erpnext/domains/healthcare.py
+++ /dev/null
@@ -1,71 +0,0 @@
-from __future__ import unicode_literals
-
-data = {
-	'desktop_icons': [
-		'Patient',
-		'Patient Appointment',
-		'Patient Encounter',
-		'Lab Test',
-		'Healthcare',
-		'Vital Signs',
-		'Clinical Procedure',
-		'Inpatient Record',
-		'Accounts',
-		'Buying',
-		'Stock',
-		'HR',
-		'ToDo'
-	],
-	'default_portal_role': 'Patient',
-	'restricted_roles': [
-		'Healthcare Administrator',
-		'LabTest Approver',
-		'Laboratory User',
-		'Nursing User',
-		'Physician',
-		'Patient'
-	],
-	'custom_fields': {
-		'Sales Invoice': [
-			{
-				'fieldname': 'patient', 'label': 'Patient', 'fieldtype': 'Link', 'options': 'Patient',
-				'insert_after': 'naming_series'
-			},
-			{
-				'fieldname': 'patient_name', 'label': 'Patient Name', 'fieldtype': 'Data', 'fetch_from': 'patient.patient_name',
-				'insert_after': 'patient', 'read_only': True
-			},
-			{
-				'fieldname': 'ref_practitioner', 'label': 'Referring Practitioner', 'fieldtype': 'Link', 'options': 'Healthcare Practitioner',
-				'insert_after': 'customer'
-			}
-		],
-		'Sales Invoice Item': [
-			{
-				'fieldname': 'reference_dt', 'label': 'Reference DocType', 'fieldtype': 'Link', 'options': 'DocType',
-				'insert_after': 'edit_references'
-			},
-			{
-				'fieldname': 'reference_dn', 'label': 'Reference Name', 'fieldtype': 'Dynamic Link', 'options': 'reference_dt',
-				'insert_after': 'reference_dt'
-			}
-		],
-		'Stock Entry': [
-			{
-				'fieldname': 'inpatient_medication_entry', 'label': 'Inpatient Medication Entry', 'fieldtype': 'Link', 'options': 'Inpatient Medication Entry',
-				'insert_after': 'credit_note', 'read_only': True
-			}
-		],
-		'Stock Entry Detail': [
-			{
-				'fieldname': 'patient', 'label': 'Patient', 'fieldtype': 'Link', 'options': 'Patient',
-				'insert_after': 'po_detail', 'read_only': True
-			},
-			{
-				'fieldname': 'inpatient_medication_entry_child', 'label': 'Inpatient Medication Entry Child', 'fieldtype': 'Data',
-				'insert_after': 'patient', 'read_only': True
-			}
-		]
-	},
-	'on_setup': 'erpnext.healthcare.setup.setup_healthcare'
-}
diff --git a/erpnext/education/doctype/student/student.py b/erpnext/education/doctype/student/student.py
index ae498ba..be4ee56 100644
--- a/erpnext/education/doctype/student/student.py
+++ b/erpnext/education/doctype/student/student.py
@@ -138,7 +138,9 @@
 			enrollment.submit()
 			return enrollment
 
-	def enroll_in_course(self, course_name, program_enrollment, enrollment_date=frappe.utils.datetime.datetime.now()):
+	def enroll_in_course(self, course_name, program_enrollment, enrollment_date=None):
+		if enrollment_date is None:
+			enrollment_date = frappe.utils.datetime.datetime.now()
 		try:
 			enrollment = frappe.get_doc({
 					"doctype": "Course Enrollment",
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
index d2748c2..310afed 100644
--- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
@@ -85,10 +85,8 @@
 		if not acc_subtype:
 			add_account_subtype(account["subtype"])
 
-		existing_bank_account = frappe.db.exists("Bank Account", {
-			'account_name': account["name"],
-			'bank': bank["bank_name"]
-		})
+		bank_account_name = "{} - {}".format(account["name"], bank["bank_name"])
+		existing_bank_account = frappe.db.exists("Bank Account", bank_account_name)
 
 		if not existing_bank_account:
 			try:
@@ -197,6 +195,7 @@
 
 	plaid = PlaidConnector(access_token)
 
+	transactions = []
 	try:
 		transactions = plaid.get_transactions(start_date=start_date, end_date=end_date, account_id=account_id)
 	except ItemError as e:
@@ -205,7 +204,7 @@
 			msg += _("Please refresh or reset the Plaid linking of the Bank {}.").format(bank) + " "
 			frappe.log_error(msg, title=_("Plaid Link Refresh Required"))
 
-	return transactions or []
+	return transactions
 
 
 def new_bank_transaction(transaction):
diff --git a/erpnext/healthcare/dashboard_chart/clinical_procedures/clinical_procedures.json b/erpnext/healthcare/dashboard_chart/clinical_procedures/clinical_procedures.json
deleted file mode 100644
index 6803528..0000000
--- a/erpnext/healthcare/dashboard_chart/clinical_procedures/clinical_procedures.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "chart_name": "Clinical Procedures",
- "chart_type": "Group By",
- "creation": "2020-07-14 18:17:54.601236",
- "docstatus": 0,
- "doctype": "Dashboard Chart",
- "document_type": "Clinical Procedure",
- "dynamic_filters_json": "[[\"Clinical Procedure\",\"company\",\"=\",\"frappe.defaults.get_user_default(\\\"Company\\\")\"]]",
- "filters_json": "[[\"Clinical Procedure\",\"docstatus\",\"=\",\"1\",false]]",
- "group_by_based_on": "procedure_template",
- "group_by_type": "Count",
- "idx": 0,
- "is_public": 1,
- "is_standard": 1,
- "last_synced_on": "2021-01-30 21:03:30.086891",
- "modified": "2021-02-01 13:36:04.469863",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Clinical Procedures",
- "number_of_groups": 0,
- "owner": "Administrator",
- "timeseries": 0,
- "type": "Bar",
- "use_report_chart": 0,
- "y_axis": []
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/dashboard_chart/clinical_procedures_status/clinical_procedures_status.json b/erpnext/healthcare/dashboard_chart/clinical_procedures_status/clinical_procedures_status.json
deleted file mode 100644
index dae9db1..0000000
--- a/erpnext/healthcare/dashboard_chart/clinical_procedures_status/clinical_procedures_status.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "chart_name": "Clinical Procedure Status",
- "chart_type": "Group By",
- "creation": "2020-07-14 18:17:54.654325",
- "docstatus": 0,
- "doctype": "Dashboard Chart",
- "document_type": "Clinical Procedure",
- "dynamic_filters_json": "[[\"Clinical Procedure\",\"company\",\"=\",\"frappe.defaults.get_user_default(\\\"Company\\\")\"]]",
- "filters_json": "[[\"Clinical Procedure\",\"docstatus\",\"=\",\"1\",false]]",
- "group_by_based_on": "status",
- "group_by_type": "Count",
- "idx": 0,
- "is_public": 1,
- "is_standard": 1,
- "last_synced_on": "2021-02-01 13:36:38.787783",
- "modified": "2021-02-01 13:37:18.718275",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Clinical Procedures Status",
- "number_of_groups": 0,
- "owner": "Administrator",
- "timeseries": 0,
- "type": "Bar",
- "use_report_chart": 0,
- "y_axis": []
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/dashboard_chart/department_wise_patient_appointments/department_wise_patient_appointments.json b/erpnext/healthcare/dashboard_chart/department_wise_patient_appointments/department_wise_patient_appointments.json
deleted file mode 100644
index b24bb34..0000000
--- a/erpnext/healthcare/dashboard_chart/department_wise_patient_appointments/department_wise_patient_appointments.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "chart_name": "Department wise Patient Appointments",
- "chart_type": "Custom",
- "creation": "2020-07-17 11:25:37.190130",
- "custom_options": "{\"colors\": [\"#7CD5FA\", \"#5F62F6\", \"#7544E2\", \"#EE5555\"], \"barOptions\": {\"stacked\": 1}, \"height\": 300}",
- "docstatus": 0,
- "doctype": "Dashboard Chart",
- "dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\"}",
- "filters_json": "{}",
- "idx": 0,
- "is_public": 1,
- "is_standard": 1,
- "last_synced_on": "2020-07-22 15:32:05.827566",
- "modified": "2020-07-22 15:35:12.798035",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Department wise Patient Appointments",
- "number_of_groups": 0,
- "owner": "Administrator",
- "source": "Department wise Patient Appointments",
- "timeseries": 0,
- "type": "Bar",
- "use_report_chart": 0,
- "y_axis": []
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/dashboard_chart/diagnoses/diagnoses.json b/erpnext/healthcare/dashboard_chart/diagnoses/diagnoses.json
deleted file mode 100644
index 82145d6..0000000
--- a/erpnext/healthcare/dashboard_chart/diagnoses/diagnoses.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "chart_name": "Diagnoses",
- "chart_type": "Group By",
- "creation": "2020-07-14 18:17:54.705698",
- "docstatus": 0,
- "doctype": "Dashboard Chart",
- "document_type": "Patient Encounter Diagnosis",
- "dynamic_filters_json": "",
- "filters_json": "[]",
- "group_by_based_on": "diagnosis",
- "group_by_type": "Count",
- "idx": 0,
- "is_public": 1,
- "is_standard": 1,
- "last_synced_on": "2021-01-30 21:03:33.729487",
- "modified": "2021-02-01 13:34:57.385335",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Diagnoses",
- "number_of_groups": 0,
- "owner": "Administrator",
- "timeseries": 0,
- "type": "Bar",
- "use_report_chart": 0,
- "y_axis": []
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/dashboard_chart/in_patient_status/in_patient_status.json b/erpnext/healthcare/dashboard_chart/in_patient_status/in_patient_status.json
deleted file mode 100644
index 77b47c9..0000000
--- a/erpnext/healthcare/dashboard_chart/in_patient_status/in_patient_status.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "chart_name": "In-Patient Status",
- "chart_type": "Group By",
- "creation": "2020-07-14 18:17:54.629199",
- "docstatus": 0,
- "doctype": "Dashboard Chart",
- "document_type": "Inpatient Record",
- "dynamic_filters_json": "[[\"Inpatient Record\",\"company\",\"=\",\"frappe.defaults.get_user_default(\\\"Company\\\")\"]]",
- "filters_json": "[]",
- "group_by_based_on": "status",
- "group_by_type": "Count",
- "idx": 0,
- "is_public": 1,
- "is_standard": 1,
- "last_synced_on": "2020-07-22 13:22:46.792131",
- "modified": "2020-07-22 13:33:16.008150",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "In-Patient Status",
- "number_of_groups": 0,
- "owner": "Administrator",
- "timeseries": 0,
- "type": "Bar",
- "use_report_chart": 0,
- "y_axis": []
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/dashboard_chart/lab_tests/lab_tests.json b/erpnext/healthcare/dashboard_chart/lab_tests/lab_tests.json
deleted file mode 100644
index 70293b1..0000000
--- a/erpnext/healthcare/dashboard_chart/lab_tests/lab_tests.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "chart_name": "Lab Tests",
- "chart_type": "Group By",
- "creation": "2020-07-14 18:17:54.574903",
- "docstatus": 0,
- "doctype": "Dashboard Chart",
- "document_type": "Lab Test",
- "dynamic_filters_json": "[[\"Lab Test\",\"company\",\"=\",\"frappe.defaults.get_user_default(\\\"Company\\\")\"]]",
- "filters_json": "[[\"Lab Test\",\"docstatus\",\"=\",\"1\",false]]",
- "group_by_based_on": "template",
- "group_by_type": "Count",
- "idx": 0,
- "is_public": 1,
- "is_standard": 1,
- "last_synced_on": "2021-01-30 21:03:28.272914",
- "modified": "2021-02-01 13:36:08.391433",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Lab Tests",
- "number_of_groups": 0,
- "owner": "Administrator",
- "timeseries": 0,
- "type": "Bar",
- "use_report_chart": 0,
- "y_axis": []
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/dashboard_chart/patient_appointments/patient_appointments.json b/erpnext/healthcare/dashboard_chart/patient_appointments/patient_appointments.json
deleted file mode 100644
index 19bfb72..0000000
--- a/erpnext/healthcare/dashboard_chart/patient_appointments/patient_appointments.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "based_on": "appointment_datetime",
- "chart_name": "Patient Appointments",
- "chart_type": "Count",
- "creation": "2020-07-14 18:17:54.525082",
- "docstatus": 0,
- "doctype": "Dashboard Chart",
- "document_type": "Patient Appointment",
- "dynamic_filters_json": "[[\"Patient Appointment\",\"company\",\"=\",\"frappe.defaults.get_user_default(\\\"Company\\\")\"]]",
- "filters_json": "[[\"Patient Appointment\",\"status\",\"!=\",\"Cancelled\",false]]",
- "idx": 0,
- "is_public": 0,
- "is_standard": 1,
- "last_synced_on": "2020-07-22 13:22:46.830491",
- "modified": "2020-07-22 13:38:02.254190",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Appointments",
- "number_of_groups": 0,
- "owner": "Administrator",
- "time_interval": "Daily",
- "timeseries": 1,
- "timespan": "Last Month",
- "type": "Line",
- "use_report_chart": 0,
- "y_axis": []
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/dashboard_chart/symptoms/symptoms.json b/erpnext/healthcare/dashboard_chart/symptoms/symptoms.json
deleted file mode 100644
index 65e5472..0000000
--- a/erpnext/healthcare/dashboard_chart/symptoms/symptoms.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "chart_name": "Symptoms",
- "chart_type": "Group By",
- "creation": "2020-07-14 18:17:54.680852",
- "docstatus": 0,
- "doctype": "Dashboard Chart",
- "document_type": "Patient Encounter Symptom",
- "dynamic_filters_json": "",
- "filters_json": "[]",
- "group_by_based_on": "complaint",
- "group_by_type": "Count",
- "idx": 0,
- "is_public": 1,
- "is_standard": 1,
- "last_synced_on": "2021-01-30 21:03:32.067473",
- "modified": "2021-02-01 13:35:30.953718",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Symptoms",
- "number_of_groups": 0,
- "owner": "Administrator",
- "timeseries": 0,
- "type": "Bar",
- "use_report_chart": 0,
- "y_axis": []
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/dashboard_chart_source/__init__.py b/erpnext/healthcare/dashboard_chart_source/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/dashboard_chart_source/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/dashboard_chart_source/department_wise_patient_appointments/__init__.py b/erpnext/healthcare/dashboard_chart_source/department_wise_patient_appointments/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/dashboard_chart_source/department_wise_patient_appointments/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/dashboard_chart_source/department_wise_patient_appointments/department_wise_patient_appointments.js b/erpnext/healthcare/dashboard_chart_source/department_wise_patient_appointments/department_wise_patient_appointments.js
deleted file mode 100644
index e494489..0000000
--- a/erpnext/healthcare/dashboard_chart_source/department_wise_patient_appointments/department_wise_patient_appointments.js
+++ /dev/null
@@ -1,14 +0,0 @@
-frappe.provide('frappe.dashboards.chart_sources');
-
-frappe.dashboards.chart_sources["Department wise Patient Appointments"] = {
-	method: "erpnext.healthcare.dashboard_chart_source.department_wise_patient_appointments.department_wise_patient_appointments.get",
-	filters: [
-		{
-			fieldname: "company",
-			label: __("Company"),
-			fieldtype: "Link",
-			options: "Company",
-			default: frappe.defaults.get_user_default("Company")
-		}
-	]
-};
diff --git a/erpnext/healthcare/dashboard_chart_source/department_wise_patient_appointments/department_wise_patient_appointments.json b/erpnext/healthcare/dashboard_chart_source/department_wise_patient_appointments/department_wise_patient_appointments.json
deleted file mode 100644
index 00301ef..0000000
--- a/erpnext/healthcare/dashboard_chart_source/department_wise_patient_appointments/department_wise_patient_appointments.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "creation": "2020-05-18 19:18:42.571045",
- "docstatus": 0,
- "doctype": "Dashboard Chart Source",
- "idx": 0,
- "modified": "2020-05-18 19:18:42.571045",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Department wise Patient Appointments",
- "owner": "Administrator",
- "source_name": "Department wise Patient Appointments",
- "timeseries": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/dashboard_chart_source/department_wise_patient_appointments/department_wise_patient_appointments.py b/erpnext/healthcare/dashboard_chart_source/department_wise_patient_appointments/department_wise_patient_appointments.py
deleted file mode 100644
index 9c71ce8..0000000
--- a/erpnext/healthcare/dashboard_chart_source/department_wise_patient_appointments/department_wise_patient_appointments.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-
-import frappe
-from frappe.utils.dashboard import cache_source
-
-
-@frappe.whitelist()
-@cache_source
-def get(chart_name = None, chart = None, no_cache = None, filters = None, from_date = None,
-	to_date = None, timespan = None, time_interval = None, heatmap_year = None):
-	if chart_name:
-		chart = frappe.get_doc('Dashboard Chart', chart_name)
-	else:
-		chart = frappe._dict(frappe.parse_json(chart))
-
-	filters = frappe.parse_json(filters)
-
-	data = frappe.db.get_list('Medical Department', fields=['name'])
-	if not filters:
-		filters = {}
-
-	status = ['Open', 'Scheduled', 'Closed', 'Cancelled']
-	for department in data:
-		filters['department'] = department.name
-		department['total_appointments'] = frappe.db.count('Patient Appointment', filters=filters)
-
-		for entry in status:
-			filters['status'] = entry
-			department[frappe.scrub(entry)] = frappe.db.count('Patient Appointment', filters=filters)
-		filters.pop('status')
-
-	sorted_department_map = sorted(data, key = lambda i: i['total_appointments'], reverse=True)
-
-	if len(sorted_department_map) > 10:
-		sorted_department_map = sorted_department_map[:10]
-
-	labels = []
-	open_appointments = []
-	scheduled = []
-	closed = []
-	cancelled = []
-
-	for department in sorted_department_map:
-		labels.append(department.name)
-		open_appointments.append(department.open)
-		scheduled.append(department.scheduled)
-		closed.append(department.closed)
-		cancelled.append(department.cancelled)
-
-	return {
-		'labels': labels,
-		'datasets': [
-			{
-				'name': 'Open',
-				'values': open_appointments
-			},
-			{
-				'name': 'Scheduled',
-				'values': scheduled
-			},
-			{
-				'name': 'Closed',
-				'values': closed
-			},
-			{
-				'name': 'Cancelled',
-				'values': cancelled
-			}
-		],
-		'type': 'bar'
-	}
diff --git a/erpnext/healthcare/desk_page/healthcare/healthcare.json b/erpnext/healthcare/desk_page/healthcare/healthcare.json
deleted file mode 100644
index af601f3..0000000
--- a/erpnext/healthcare/desk_page/healthcare/healthcare.json
+++ /dev/null
@@ -1,122 +0,0 @@
-{
- "cards": [
-  {
-   "hidden": 0,
-   "label": "Masters",
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient\",\n\t\t\"label\": \"Patient\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Practitioner\",\n\t\t\"label\":\"Healthcare Practitioner\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Practitioner Schedule\",\n\t\t\"label\": \"Practitioner Schedule\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Department\",\n\t\t\"label\": \"Medical Department\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit Type\",\n\t\t\"label\": \"Healthcare Service Unit Type\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit\",\n\t\t\"label\": \"Healthcare Service Unit\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code Standard\",\n\t\t\"label\": \"Medical Code Standard\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code\",\n\t\t\"label\": \"Medical Code\"\n\t}\n]"
-  },
-  {
-   "hidden": 0,
-   "label": "Consultation Setup",
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Appointment Type\",\n\t\t\"label\": \"Appointment Type\"\n    },\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure Template\",\n\t\t\"label\": \"Clinical Procedure Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Dosage\",\n\t\t\"label\": \"Prescription Dosage\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Duration\",\n\t\t\"label\": \"Prescription Duration\"\n\t},\n\t{\n\t    \"type\": \"doctype\",\n\t\t\"name\": \"Antibiotic\",\n\t\t\"label\": \"Antibiotic\"\n\t}\n]"
-  },
-  {
-   "hidden": 0,
-   "label": "Consultation",
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Appointment\",\n\t\t\"label\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure\",\n\t\t\"label\": \"Clinical Procedure\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Encounter\",\n\t\t\"label\": \"Patient Encounter\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Vital Signs\",\n\t\t\"label\": \"Vital Signs\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Complaint\",\n\t\t\"label\": \"Complaint\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Diagnosis\",\n\t\t\"label\": \"Diagnosis\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Fee Validity\",\n\t\t\"label\": \"Fee Validity\"\n\t}\n]"
-  },
-  {
-   "hidden": 0,
-   "label": "Settings",
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Settings\",\n\t\t\"label\": \"Healthcare Settings\",\n\t\t\"onboard\": 1\n\t}\n]"
-  },
-  {
-   "hidden": 0,
-   "label": "Laboratory Setup",
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Template\",\n\t\t\"label\": \"Lab Test Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Sample\",\n\t\t\"label\": \"Lab Test Sample\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test UOM\",\n\t\t\"label\": \"Lab Test UOM\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sensitivity\",\n\t\t\"label\": \"Sensitivity\"\n\t}\n]"
-  },
-  {
-   "hidden": 0,
-   "label": "Laboratory",
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test\",\n\t\t\"label\": \"Lab Test\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sample Collection\",\n\t\t\"label\": \"Sample Collection\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Dosage Form\",\n\t\t\"label\": \"Dosage Form\"\n\t}\n]"
-  },
-  {
-   "hidden": 0,
-   "label": "Inpatient",
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Inpatient Record\",\n\t\t\"label\": \"Inpatient Record\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Inpatient Medication Order\",\n\t\t\"label\": \"Inpatient Medication Order\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Inpatient Medication Entry\",\n\t\t\"label\": \"Inpatient Medication Entry\"\n\t}\n]"
-  },
-  {
-   "hidden": 0,
-   "label": "Rehabilitation and Physiotherapy",
-   "links": "[\n    {\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Exercise Type\",\n\t\t\"label\": \"Exercise Type\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Therapy Type\",\n\t\t\"label\": \"Therapy Type\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Therapy Plan\",\n\t\t\"label\": \"Therapy Plan\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Therapy Session\",\n\t\t\"label\": \"Therapy Session\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Assessment Template\",\n\t\t\"label\": \"Patient Assessment Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Assessment\",\n\t\t\"label\": \"Patient Assessment\"\n\t}\n]"
-  },
-  {
-   "hidden": 0,
-   "label": "Records and History",
-   "links": "[\n\t{\n\t\t\"type\": \"page\",\n\t\t\"name\": \"patient_history\",\n\t\t\"label\": \"Patient History\"\n\t},\n\t{\n\t\t\"type\": \"page\",\n\t\t\"name\": \"patient-progress\",\n\t\t\"label\": \"Patient Progress\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Medical Record\",\n\t\t\"label\": \"Patient Medical Record\"\n\t}\n]"
-  },
-  {
-   "hidden": 0,
-   "label": "Reports",
-   "links": "[\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Patient Appointment Analytics\",\n\t\t\"doctype\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Lab Test Report\",\n\t\t\"doctype\": \"Lab Test\",\n\t\t\"label\": \"Lab Test Report\"\n\t},\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Inpatient Medication Orders\",\n\t\t\"doctype\": \"Inpatient Medication Order\",\n\t\t\"label\": \"Inpatient Medication Orders\"\n\t}\n]"
-  }
- ],
- "category": "Domains",
- "charts": [
-  {
-   "chart_name": "Patient Appointments",
-   "label": "Patient Appointments"
-  }
- ],
- "charts_label": "",
- "creation": "2020-03-02 17:23:17.919682",
- "developer_mode_only": 0,
- "disable_user_customization": 0,
- "docstatus": 0,
- "doctype": "Desk Page",
- "extends_another_page": 0,
- "hide_custom": 0,
- "idx": 0,
- "is_standard": 1,
- "label": "Healthcare",
- "modified": "2020-11-26 22:09:09.164584",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Healthcare",
- "onboarding": "Healthcare",
- "owner": "Administrator",
- "pin_to_bottom": 0,
- "pin_to_top": 0,
- "restrict_to_domain": "Healthcare",
- "shortcuts": [
-  {
-   "color": "#ffe8cd",
-   "format": "{} Open",
-   "label": "Patient Appointment",
-   "link_to": "Patient Appointment",
-   "stats_filter": "{\n    \"status\": \"Open\",\n    \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%']\n}",
-   "type": "DocType"
-  },
-  {
-   "color": "#ffe8cd",
-   "format": "{} Active",
-   "label": "Patient",
-   "link_to": "Patient",
-   "stats_filter": "{\n    \"status\": \"Active\"\n}",
-   "type": "DocType"
-  },
-  {
-   "color": "#cef6d1",
-   "format": "{} Vacant",
-   "label": "Healthcare Service Unit",
-   "link_to": "Healthcare Service Unit",
-   "stats_filter": "{\n    \"occupancy_status\": \"Vacant\",\n    \"is_group\": 0,\n    \"company\": [\"like\", \"%\" + frappe.defaults.get_global_default(\"company\") + \"%\"]\n}",
-   "type": "DocType"
-  },
-  {
-   "label": "Healthcare Practitioner",
-   "link_to": "Healthcare Practitioner",
-   "type": "DocType"
-  },
-  {
-   "label": "Patient History",
-   "link_to": "patient_history",
-   "type": "Page"
-  },
-  {
-   "label": "Dashboard",
-   "link_to": "Healthcare",
-   "type": "Dashboard"
-  }
- ]
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/antibiotic/__init__.py b/erpnext/healthcare/doctype/antibiotic/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/antibiotic/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/antibiotic/antibiotic.js b/erpnext/healthcare/doctype/antibiotic/antibiotic.js
deleted file mode 100644
index 42e6adb..0000000
--- a/erpnext/healthcare/doctype/antibiotic/antibiotic.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Antibiotic', {
-});
diff --git a/erpnext/healthcare/doctype/antibiotic/antibiotic.json b/erpnext/healthcare/doctype/antibiotic/antibiotic.json
deleted file mode 100644
index 41a3e31..0000000
--- a/erpnext/healthcare/doctype/antibiotic/antibiotic.json
+++ /dev/null
@@ -1,151 +0,0 @@
-{
- "allow_copy": 1,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:antibiotic_name",
- "beta": 1,
- "creation": "2016-02-23 11:11:30.749731",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 0,
- "fields": [
-  {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "antibiotic_name",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 1,
-   "in_standard_filter": 0,
-   "label": "Antibiotic Name",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 1,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 1
-  },
-  {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "abbr",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 0,
-   "in_standard_filter": 0,
-   "label": "Abbr",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 1
-  }
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2019-10-01 17:58:23.136498",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Antibiotic",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [
-  {
-   "amend": 0,
-   "cancel": 0,
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "if_owner": 0,
-   "import": 0,
-   "permlevel": 0,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "set_user_permissions": 0,
-   "share": 1,
-   "submit": 0,
-   "write": 1
-  },
-  {
-   "amend": 0,
-   "cancel": 0,
-   "create": 0,
-   "delete": 0,
-   "email": 1,
-   "export": 1,
-   "if_owner": 0,
-   "import": 0,
-   "permlevel": 0,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Laboratory User",
-   "set_user_permissions": 0,
-   "share": 1,
-   "submit": 0,
-   "write": 0
-  }
- ],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "search_fields": "antibiotic_name",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "antibiotic_name",
- "track_changes": 0,
- "track_seen": 0,
- "track_views": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/antibiotic/antibiotic.py b/erpnext/healthcare/doctype/antibiotic/antibiotic.py
deleted file mode 100644
index 6a4b764..0000000
--- a/erpnext/healthcare/doctype/antibiotic/antibiotic.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class Antibiotic(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/antibiotic/test_antibiotic.py b/erpnext/healthcare/doctype/antibiotic/test_antibiotic.py
deleted file mode 100644
index b6ec79f..0000000
--- a/erpnext/healthcare/doctype/antibiotic/test_antibiotic.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-
-class TestAntibiotic(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/appointment_type/__init__.py b/erpnext/healthcare/doctype/appointment_type/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/appointment_type/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/appointment_type/appointment_type.js b/erpnext/healthcare/doctype/appointment_type/appointment_type.js
deleted file mode 100644
index 99b7cb2..0000000
--- a/erpnext/healthcare/doctype/appointment_type/appointment_type.js
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2016, ESS LLP and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Appointment Type', {
-	refresh: function(frm) {
-		frm.set_query('price_list', function() {
-			return {
-				filters: {'selling': 1}
-			};
-		});
-
-		frm.set_query('medical_department', 'items', function(doc) {
-			let item_list = doc.items.map(({medical_department}) => medical_department);
-			return {
-				filters: [
-					['Medical Department', 'name', 'not in', item_list]
-				]
-			};
-		});
-
-		frm.set_query('op_consulting_charge_item', 'items', function() {
-			return {
-				filters: {
-					is_stock_item: 0
-				}
-			};
-		});
-
-		frm.set_query('inpatient_visit_charge_item', 'items', function() {
-			return {
-				filters: {
-					is_stock_item: 0
-				}
-			};
-		});
-	}
-});
-
-frappe.ui.form.on('Appointment Type Service Item', {
-	op_consulting_charge_item: function(frm, cdt, cdn) {
-		let d = locals[cdt][cdn];
-		if (frm.doc.price_list && d.op_consulting_charge_item) {
-			frappe.call({
-				'method': 'frappe.client.get_value',
-				args: {
-					'doctype': 'Item Price',
-					'filters': {
-						'item_code': d.op_consulting_charge_item,
-						'price_list': frm.doc.price_list
-					},
-					'fieldname': ['price_list_rate']
-				},
-				callback: function(data) {
-					if (data.message.price_list_rate) {
-						frappe.model.set_value(cdt, cdn, 'op_consulting_charge', data.message.price_list_rate);
-					}
-				}
-			});
-		}
-	},
-
-	inpatient_visit_charge_item: function(frm, cdt, cdn) {
-		let d = locals[cdt][cdn];
-		if (frm.doc.price_list && d.inpatient_visit_charge_item) {
-			frappe.call({
-				'method': 'frappe.client.get_value',
-				args: {
-					'doctype': 'Item Price',
-					'filters': {
-						'item_code': d.inpatient_visit_charge_item,
-						'price_list': frm.doc.price_list
-					},
-					'fieldname': ['price_list_rate']
-				},
-				callback: function (data) {
-					if (data.message.price_list_rate) {
-						frappe.model.set_value(cdt, cdn, 'inpatient_visit_charge', data.message.price_list_rate);
-					}
-				}
-			});
-		}
-	}
-});
diff --git a/erpnext/healthcare/doctype/appointment_type/appointment_type.json b/erpnext/healthcare/doctype/appointment_type/appointment_type.json
deleted file mode 100644
index 3872318..0000000
--- a/erpnext/healthcare/doctype/appointment_type/appointment_type.json
+++ /dev/null
@@ -1,114 +0,0 @@
-{
- "actions": [],
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:appointment_type",
- "beta": 1,
- "creation": "2016-07-22 11:52:34.953019",
- "doctype": "DocType",
- "document_type": "Setup",
- "engine": "InnoDB",
- "field_order": [
-  "appointment_type",
-  "ip",
-  "default_duration",
-  "color",
-  "billing_section",
-  "price_list",
-  "items"
- ],
- "fields": [
-  {
-   "allow_in_quick_entry": 1,
-   "fieldname": "appointment_type",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Type",
-   "reqd": 1,
-   "translatable": 1,
-   "unique": 1
-  },
-  {
-   "bold": 1,
-   "default": "0",
-   "fieldname": "ip",
-   "fieldtype": "Check",
-   "label": "Is Inpatient",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "allow_in_quick_entry": 1,
-   "bold": 1,
-   "fieldname": "default_duration",
-   "fieldtype": "Int",
-   "in_filter": 1,
-   "in_list_view": 1,
-   "label": "Default Duration (In Minutes)"
-  },
-  {
-   "allow_in_quick_entry": 1,
-   "fieldname": "color",
-   "fieldtype": "Color",
-   "in_list_view": 1,
-   "label": "Color",
-   "no_copy": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "billing_section",
-   "fieldtype": "Section Break",
-   "label": "Billing"
-  },
-  {
-   "fieldname": "price_list",
-   "fieldtype": "Link",
-   "label": "Price List",
-   "options": "Price List"
-  },
-  {
-   "fieldname": "items",
-   "fieldtype": "Table",
-   "label": "Appointment Type Service Items",
-   "options": "Appointment Type Service Item"
-  }
- ],
- "links": [],
- "modified": "2021-01-22 09:41:05.010524",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Appointment Type",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "restrict_to_domain": "Healthcare",
- "search_fields": "appointment_type",
- "sort_field": "modified",
- "sort_order": "DESC"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/appointment_type/appointment_type.py b/erpnext/healthcare/doctype/appointment_type/appointment_type.py
deleted file mode 100644
index 94d023f..0000000
--- a/erpnext/healthcare/doctype/appointment_type/appointment_type.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-import frappe
-from frappe.model.document import Document
-
-
-class AppointmentType(Document):
-	def validate(self):
-		if self.items and self.price_list:
-			for item in self.items:
-				existing_op_item_price = frappe.db.exists('Item Price', {
-					'item_code': item.op_consulting_charge_item,
-					'price_list': self.price_list
-				})
-
-				if not existing_op_item_price and item.op_consulting_charge_item and item.op_consulting_charge:
-					make_item_price(self.price_list, item.op_consulting_charge_item, item.op_consulting_charge)
-
-				existing_ip_item_price = frappe.db.exists('Item Price', {
-					'item_code': item.inpatient_visit_charge_item,
-					'price_list': self.price_list
-				})
-
-				if not existing_ip_item_price and item.inpatient_visit_charge_item and item.inpatient_visit_charge:
-					make_item_price(self.price_list, item.inpatient_visit_charge_item, item.inpatient_visit_charge)
-
-@frappe.whitelist()
-def get_service_item_based_on_department(appointment_type, department):
-	item_list = frappe.db.get_value('Appointment Type Service Item',
-		filters = {'medical_department': department, 'parent': appointment_type},
-		fieldname = ['op_consulting_charge_item',
-			'inpatient_visit_charge_item', 'op_consulting_charge', 'inpatient_visit_charge'],
-		as_dict = 1
-	)
-
-	# if department wise items are not set up
-	# use the generic items
-	if not item_list:
-		item_list = frappe.db.get_value('Appointment Type Service Item',
-			filters = {'parent': appointment_type},
-			fieldname = ['op_consulting_charge_item',
-				'inpatient_visit_charge_item', 'op_consulting_charge', 'inpatient_visit_charge'],
-			as_dict = 1
-		)
-
-	return item_list
-
-def make_item_price(price_list, item, item_price):
-	frappe.get_doc({
-		'doctype': 'Item Price',
-		'price_list': price_list,
-		'item_code': item,
-		'price_list_rate': item_price
-	}).insert(ignore_permissions=True, ignore_mandatory=True)
diff --git a/erpnext/healthcare/doctype/appointment_type/appointment_type_dashboard.py b/erpnext/healthcare/doctype/appointment_type/appointment_type_dashboard.py
deleted file mode 100644
index b9c6edb..0000000
--- a/erpnext/healthcare/doctype/appointment_type/appointment_type_dashboard.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from __future__ import unicode_literals
-
-from frappe import _
-
-
-def get_data():
-	return {
-		'fieldname': 'appointment_type',
-		'transactions': [
-			{
-				'label': _('Patient Appointments'),
-				'items': ['Patient Appointment']
-			},
-		]
-	}
diff --git a/erpnext/healthcare/doctype/appointment_type/test_appointment_type.py b/erpnext/healthcare/doctype/appointment_type/test_appointment_type.py
deleted file mode 100644
index 04452e4..0000000
--- a/erpnext/healthcare/doctype/appointment_type/test_appointment_type.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-# test_records = frappe.get_test_records('Appointment Type')
-
-class TestAppointmentType(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/appointment_type_service_item/__init__.py b/erpnext/healthcare/doctype/appointment_type_service_item/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/appointment_type_service_item/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/appointment_type_service_item/appointment_type_service_item.json b/erpnext/healthcare/doctype/appointment_type_service_item/appointment_type_service_item.json
deleted file mode 100644
index ccae129..0000000
--- a/erpnext/healthcare/doctype/appointment_type_service_item/appointment_type_service_item.json
+++ /dev/null
@@ -1,67 +0,0 @@
-{
- "actions": [],
- "creation": "2021-01-22 09:34:53.373105",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "medical_department",
-  "op_consulting_charge_item",
-  "op_consulting_charge",
-  "column_break_4",
-  "inpatient_visit_charge_item",
-  "inpatient_visit_charge"
- ],
- "fields": [
-  {
-   "fieldname": "medical_department",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Medical Department",
-   "options": "Medical Department"
-  },
-  {
-   "fieldname": "op_consulting_charge_item",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Out Patient Consulting Charge Item",
-   "options": "Item"
-  },
-  {
-   "fieldname": "op_consulting_charge",
-   "fieldtype": "Currency",
-   "in_list_view": 1,
-   "label": "Out Patient Consulting Charge"
-  },
-  {
-   "fieldname": "column_break_4",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "inpatient_visit_charge_item",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Inpatient Visit Charge Item",
-   "options": "Item"
-  },
-  {
-   "fieldname": "inpatient_visit_charge",
-   "fieldtype": "Currency",
-   "in_list_view": 1,
-   "label": "Inpatient Visit Charge"
-  }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2021-08-17 06:05:02.240812",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Appointment Type Service Item",
- "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/healthcare/doctype/appointment_type_service_item/appointment_type_service_item.py b/erpnext/healthcare/doctype/appointment_type_service_item/appointment_type_service_item.py
deleted file mode 100644
index 026d5d7..0000000
--- a/erpnext/healthcare/doctype/appointment_type_service_item/appointment_type_service_item.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2021, 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 AppointmentTypeServiceItem(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/body_part/body_part.js b/erpnext/healthcare/doctype/body_part/body_part.js
deleted file mode 100644
index d2f9d09..0000000
--- a/erpnext/healthcare/doctype/body_part/body_part.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('Body Part', {
-	// refresh: function(frm) {
-
-	// }
-});
diff --git a/erpnext/healthcare/doctype/body_part/body_part.json b/erpnext/healthcare/doctype/body_part/body_part.json
deleted file mode 100644
index 6e3d1d4..0000000
--- a/erpnext/healthcare/doctype/body_part/body_part.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
- "actions": [],
- "autoname": "field:body_part",
- "creation": "2020-04-10 12:21:55.036402",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "body_part"
- ],
- "fields": [
-  {
-   "fieldname": "body_part",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Body Part",
-   "reqd": 1,
-   "unique": 1
-  }
- ],
- "links": [],
- "modified": "2020-04-10 12:26:44.087985",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Body Part",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/body_part/body_part.py b/erpnext/healthcare/doctype/body_part/body_part.py
deleted file mode 100644
index 77e8dd9..0000000
--- a/erpnext/healthcare/doctype/body_part/body_part.py
+++ /dev/null
@@ -1,12 +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 BodyPart(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/body_part/test_body_part.py b/erpnext/healthcare/doctype/body_part/test_body_part.py
deleted file mode 100644
index a81ba17..0000000
--- a/erpnext/healthcare/doctype/body_part/test_body_part.py
+++ /dev/null
@@ -1,11 +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 TestBodyPart(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/body_part_link/__init__.py b/erpnext/healthcare/doctype/body_part_link/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/body_part_link/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/body_part_link/body_part_link.json b/erpnext/healthcare/doctype/body_part_link/body_part_link.json
deleted file mode 100644
index 400b7c6..0000000
--- a/erpnext/healthcare/doctype/body_part_link/body_part_link.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "actions": [],
- "creation": "2020-04-10 12:23:15.259816",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "body_part"
- ],
- "fields": [
-  {
-   "fieldname": "body_part",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Body Part",
-   "options": "Body Part",
-   "reqd": 1
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-04-10 12:25:23.101749",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Body Part Link",
- "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/healthcare/doctype/body_part_link/body_part_link.py b/erpnext/healthcare/doctype/body_part_link/body_part_link.py
deleted file mode 100644
index 07488f0..0000000
--- a/erpnext/healthcare/doctype/body_part_link/body_part_link.py
+++ /dev/null
@@ -1,12 +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 BodyPartLink(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/clinical_procedure/__init__.py b/erpnext/healthcare/doctype/clinical_procedure/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/clinical_procedure/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
deleted file mode 100644
index b55d5d6..0000000
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
+++ /dev/null
@@ -1,377 +0,0 @@
-// Copyright (c) 2017, ESS LLP and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Clinical Procedure', {
-	setup: function(frm) {
-		frm.set_query('batch_no', 'items', function(doc, cdt, cdn) {
-			let item = locals[cdt][cdn];
-			if (!item.item_code) {
-				frappe.throw(__('Please enter Item Code to get Batch Number'));
-			} else {
-				let filters = {'item_code': item.item_code};
-
-				if (frm.doc.status == 'In Progress') {
-					filters['posting_date'] = frm.doc.start_date || frappe.datetime.nowdate();
-					if (frm.doc.warehouse) filters['warehouse'] = frm.doc.warehouse;
-				}
-
-				return {
-					query : 'erpnext.controllers.queries.get_batch_no',
-					filters: filters
-				};
-			}
-		});
-	},
-
-	refresh: function(frm) {
-		frm.set_query('patient', function () {
-			return {
-				filters: {'status': ['!=', 'Disabled']}
-			};
-		});
-
-		frm.set_query('appointment', function () {
-			return {
-				filters: {
-					'procedure_template': ['not in', null],
-					'status': ['in', 'Open, Scheduled']
-				}
-			};
-		});
-
-		frm.set_query('service_unit', function() {
-			return {
-				filters: {
-					'is_group': false,
-					'allow_appointments': true,
-					'company': frm.doc.company
-				}
-			};
-		});
-
-		frm.set_query('practitioner', function() {
-			return {
-				filters: {
-					'department': frm.doc.medical_department
-				}
-			};
-		});
-
-		if (frm.doc.consume_stock) {
-			frm.set_indicator_formatter('item_code',
-				function(doc) { return (doc.qty<=doc.actual_qty) ? 'green' : 'orange' ; });
-		}
-
-		if (frm.doc.docstatus == 1) {
-			if (frm.doc.status == 'In Progress') {
-				let btn_label = '';
-				let msg = '';
-				if (frm.doc.consume_stock) {
-					btn_label = __('Complete and Consume');
-					msg = __('Complete {0} and Consume Stock?', [frm.doc.name]);
-				} else {
-					btn_label = 'Complete';
-					msg = __('Complete {0}?', [frm.doc.name]);
-				}
-
-				frm.add_custom_button(__(btn_label), function () {
-					frappe.confirm(
-						msg,
-						function() {
-							frappe.call({
-								method: 'complete_procedure',
-								doc: frm.doc,
-								freeze: true,
-								callback: function(r) {
-									if (r.message) {
-										frappe.show_alert({
-											message: __('Stock Entry {0} created', ['<a class="bold" href="/app/stock-entry/'+ r.message + '">' + r.message + '</a>']),
-											indicator: 'green'
-										});
-									}
-									frm.reload_doc();
-								}
-							});
-						}
-					);
-				}).addClass("btn-primary");
-
-			} else if (frm.doc.status == 'Pending') {
-				frm.add_custom_button(__('Start'), function() {
-					frappe.call({
-						doc: frm.doc,
-						method: 'start_procedure',
-						callback: function(r) {
-							if (!r.exc) {
-								if (r.message == 'insufficient stock') {
-									let msg = __('Stock quantity to start the Procedure is not available in the Warehouse {0}. Do you want to record a Stock Entry?', [frm.doc.warehouse.bold()]);
-									frappe.confirm(
-										msg,
-										function() {
-											frappe.call({
-												doc: frm.doc,
-												method: 'make_material_receipt',
-												freeze: true,
-												callback: function(r) {
-													if (!r.exc) {
-														frm.reload_doc();
-														let doclist = frappe.model.sync(r.message);
-														frappe.set_route('Form', doclist[0].doctype, doclist[0].name);
-													}
-												}
-											});
-										}
-									);
-								} else {
-									frm.reload_doc();
-								}
-							}
-						}
-					});
-				}).addClass("btn-primary");
-			}
-		}
-	},
-
-	onload: function(frm) {
-		if (frm.is_new()) {
-			frm.add_fetch('procedure_template', 'medical_department', 'medical_department');
-			frm.set_value('start_time', null);
-		}
-	},
-
-	patient: function(frm) {
-		if (frm.doc.patient) {
-			frappe.call({
-				'method': 'erpnext.healthcare.doctype.patient.patient.get_patient_detail',
-				args: {
-					patient: frm.doc.patient
-				},
-				callback: function (data) {
-					let age = '';
-					if (data.message.dob) {
-						age = calculate_age(data.message.dob);
-					} else if (data.message.age) {
-						age = data.message.age;
-						if (data.message.age_as_on) {
-							age = __('{0} as on {1}', [age, data.message.age_as_on]);
-						}
-					}
-					frm.set_value('patient_name', data.message.patient_name);
-					frm.set_value('patient_age', age);
-					frm.set_value('patient_sex', data.message.sex);
-				}
-			});
-		} else {
-			frm.set_value('patient_name', '');
-			frm.set_value('patient_age', '');
-			frm.set_value('patient_sex', '');
-		}
-	},
-
-	appointment: function(frm) {
-		if (frm.doc.appointment) {
-			frappe.call({
-				'method': 'frappe.client.get',
-				args: {
-					doctype: 'Patient Appointment',
-					name: frm.doc.appointment
-				},
-				callback: function(data) {
-					let values = {
-						'patient':data.message.patient,
-						'procedure_template': data.message.procedure_template,
-						'medical_department': data.message.department,
-						'practitioner': data.message.practitioner,
-						'start_date': data.message.appointment_date,
-						'start_time': data.message.appointment_time,
-						'notes': data.message.notes,
-						'service_unit': data.message.service_unit,
-						'company': data.message.company
-					};
-					frm.set_value(values);
-				}
-			});
-		} else {
-			let values = {
-				'patient': '',
-				'patient_name': '',
-				'patient_sex': '',
-				'patient_age': '',
-				'medical_department': '',
-				'procedure_template': '',
-				'start_date': '',
-				'start_time': '',
-				'notes': '',
-				'service_unit': '',
-				'inpatient_record': ''
-			};
-			frm.set_value(values);
-		}
-	},
-
-	procedure_template: function(frm) {
-		if (frm.doc.procedure_template) {
-			frappe.call({
-				'method': 'frappe.client.get',
-				args: {
-					doctype: 'Clinical Procedure Template',
-					name: frm.doc.procedure_template
-				},
-				callback: function (data) {
-					frm.set_value('medical_department', data.message.medical_department);
-					frm.set_value('consume_stock', data.message.consume_stock);
-					frm.events.set_warehouse(frm);
-					frm.events.set_procedure_consumables(frm);
-				}
-			});
-		}
-	},
-
-	service_unit: function(frm) {
-		if (frm.doc.service_unit) {
-			frappe.call({
-				method: 'frappe.client.get_value',
-				args:{
-					fieldname: 'warehouse',
-					doctype: 'Healthcare Service Unit',
-					filters:{name: frm.doc.service_unit},
-				},
-				callback: function(data) {
-					if (data.message) {
-						frm.set_value('warehouse', data.message.warehouse);
-					}
-				}
-			});
-		}
-	},
-
-	practitioner: function(frm) {
-		if (frm.doc.practitioner) {
-			frappe.call({
-				'method': 'frappe.client.get',
-				args: {
-					doctype: 'Healthcare Practitioner',
-					name: frm.doc.practitioner
-				},
-				callback: function (data) {
-					frappe.model.set_value(frm.doctype,frm.docname, 'practitioner_name', data.message.practitioner_name);
-				}
-			});
-		} else {
-			frappe.model.set_value(frm.doctype,frm.docname, 'practitioner_name', '');
-		}
-	},
-
-	set_warehouse: function(frm) {
-		if (!frm.doc.warehouse) {
-			frappe.call({
-				method: 'frappe.client.get_value',
-				args: {
-					doctype: 'Stock Settings',
-					fieldname: 'default_warehouse'
-				},
-				callback: function (data) {
-					frm.set_value('warehouse', data.message.default_warehouse);
-				}
-			});
-		}
-	},
-
-	set_procedure_consumables: function(frm) {
-		frappe.call({
-			method: 'erpnext.healthcare.doctype.clinical_procedure.clinical_procedure.get_procedure_consumables',
-			args: {
-				procedure_template: frm.doc.procedure_template
-			},
-			callback: function(data) {
-				if (data.message) {
-					frm.doc.items = [];
-					$.each(data.message, function(i, v) {
-						let item = frm.add_child('items');
-						item.item_code = v.item_code;
-						item.item_name = v.item_name;
-						item.uom = v.uom;
-						item.stock_uom = v.stock_uom;
-						item.qty = flt(v.qty);
-						item.transfer_qty = v.transfer_qty;
-						item.conversion_factor = v.conversion_factor;
-						item.invoice_separately_as_consumables = v.invoice_separately_as_consumables;
-						item.batch_no = v.batch_no;
-					});
-					refresh_field('items');
-				}
-			}
-		});
-	}
-
-});
-
-frappe.ui.form.on('Clinical Procedure Item', {
-	qty: function(frm, cdt, cdn) {
-		let d = locals[cdt][cdn];
-		frappe.model.set_value(cdt, cdn, 'transfer_qty', d.qty*d.conversion_factor);
-	},
-
-	uom: function(doc, cdt, cdn) {
-		let d = locals[cdt][cdn];
-		if (d.uom && d.item_code) {
-			return frappe.call({
-				method: 'erpnext.stock.doctype.stock_entry.stock_entry.get_uom_details',
-				args: {
-					item_code: d.item_code,
-					uom: d.uom,
-					qty: d.qty
-				},
-				callback: function(r) {
-					if (r.message) {
-						frappe.model.set_value(cdt, cdn, r.message);
-					}
-				}
-			});
-		}
-	},
-
-	item_code: function(frm, cdt, cdn) {
-		let d = locals[cdt][cdn];
-		let args = null;
-		if (d.item_code) {
-			args = {
-				'doctype' : 'Clinical Procedure',
-				'item_code' : d.item_code,
-				'company' : frm.doc.company,
-				'warehouse': frm.doc.warehouse
-			};
-			return frappe.call({
-				method: 'erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.get_item_details',
-				args: {args: args},
-				callback: function(r) {
-					if (r.message) {
-						let d = locals[cdt][cdn];
-						$.each(r.message, function(k, v) {
-							d[k] = v;
-						});
-						refresh_field('items');
-					}
-				}
-			});
-		}
-	}
-});
-
-let calculate_age = function(birth) {
-	let ageMS = Date.parse(Date()) - Date.parse(birth);
-	let age = new Date();
-	age.setTime(ageMS);
-	let years =  age.getFullYear() - 1970;
-	return `${years} ${__('Years(s)')} ${age.getMonth()} ${__('Month(s)')} ${age.getDate()} ${__('Day(s)')}`;
-};
-
-// List Stock items
-cur_frm.set_query('item_code', 'items', function() {
-	return {
-		filters: {
-			is_stock_item:1
-		}
-	};
-});
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
deleted file mode 100644
index b1d62da..0000000
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
+++ /dev/null
@@ -1,345 +0,0 @@
-{
- "actions": [],
- "autoname": "naming_series:",
- "beta": 1,
- "creation": "2017-04-07 12:52:43.542429",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "naming_series",
-  "title",
-  "appointment",
-  "procedure_template",
-  "medical_code",
-  "column_break_30",
-  "company",
-  "invoiced",
-  "section_break_6",
-  "patient",
-  "patient_name",
-  "patient_sex",
-  "patient_age",
-  "inpatient_record",
-  "notes",
-  "column_break_7",
-  "status",
-  "practitioner",
-  "practitioner_name",
-  "medical_department",
-  "service_unit",
-  "start_date",
-  "start_time",
-  "sample",
-  "consumables_section",
-  "consume_stock",
-  "warehouse",
-  "items",
-  "section_break_24",
-  "invoice_separately_as_consumables",
-  "consumption_invoiced",
-  "consumable_total_amount",
-  "column_break_27",
-  "consumption_details",
-  "sb_refs",
-  "column_break_34",
-  "prescription",
-  "amended_from"
- ],
- "fields": [
-  {
-   "fetch_from": "patient.inpatient_record",
-   "fieldname": "inpatient_record",
-   "fieldtype": "Link",
-   "label": "Inpatient Record",
-   "options": "Inpatient Record",
-   "read_only": 1
-  },
-  {
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "label": "Series",
-   "options": "HLC-CPR-.YYYY.-"
-  },
-  {
-   "fieldname": "appointment",
-   "fieldtype": "Link",
-   "in_standard_filter": 1,
-   "label": "Appointment",
-   "options": "Patient Appointment",
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "in_standard_filter": 1,
-   "label": "Patient",
-   "options": "Patient",
-   "reqd": 1
-  },
-  {
-   "fieldname": "patient_age",
-   "fieldtype": "Data",
-   "label": "Age",
-   "read_only": 1
-  },
-  {
-   "fieldname": "patient_sex",
-   "fieldtype": "Link",
-   "label": "Gender",
-   "options": "Gender",
-   "read_only": 1,
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "prescription",
-   "fieldtype": "Link",
-   "hidden": 1,
-   "label": "Procedure Prescription",
-   "options": "Procedure Prescription",
-   "read_only": 1
-  },
-  {
-   "fieldname": "medical_department",
-   "fieldtype": "Link",
-   "in_standard_filter": 1,
-   "label": "Medical Department",
-   "options": "Medical Department"
-  },
-  {
-   "fieldname": "practitioner",
-   "fieldtype": "Link",
-   "in_standard_filter": 1,
-   "label": "Healthcare Practitioner",
-   "options": "Healthcare Practitioner"
-  },
-  {
-   "fieldname": "column_break_7",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "procedure_template",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Procedure Template",
-   "options": "Clinical Procedure Template",
-   "reqd": 1
-  },
-  {
-   "fieldname": "service_unit",
-   "fieldtype": "Link",
-   "label": "Service Unit",
-   "options": "Healthcare Service Unit",
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "warehouse",
-   "fieldtype": "Link",
-   "label": "Warehouse",
-   "mandatory_depends_on": "eval: doc.consume_stock == 1",
-   "options": "Warehouse"
-  },
-  {
-   "default": "Today",
-   "fieldname": "start_date",
-   "fieldtype": "Date",
-   "label": "Start Date"
-  },
-  {
-   "fieldname": "start_time",
-   "fieldtype": "Time",
-   "label": "Start Time"
-  },
-  {
-   "fieldname": "sample",
-   "fieldtype": "Link",
-   "label": "Sample",
-   "options": "Sample Collection"
-  },
-  {
-   "default": "0",
-   "fieldname": "invoiced",
-   "fieldtype": "Check",
-   "label": "Invoiced",
-   "no_copy": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "notes",
-   "fieldtype": "Small Text",
-   "label": "Notes",
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "label": "Company",
-   "options": "Company"
-  },
-  {
-   "default": "0",
-   "fieldname": "consume_stock",
-   "fieldtype": "Check",
-   "label": "Consume Stock"
-  },
-  {
-   "fieldname": "items",
-   "fieldtype": "Table",
-   "label": "Consumables",
-   "options": "Clinical Procedure Item"
-  },
-  {
-   "default": "0",
-   "fieldname": "invoice_separately_as_consumables",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "label": "Invoice Consumables Separately",
-   "read_only": 1
-  },
-  {
-   "depends_on": "invoice_separately_as_consumables",
-   "fieldname": "consumable_total_amount",
-   "fieldtype": "Currency",
-   "label": "Consumable Total Amount",
-   "read_only": 1
-  },
-  {
-   "depends_on": "invoice_separately_as_consumables",
-   "fieldname": "consumption_details",
-   "fieldtype": "Small Text",
-   "label": "Consumption Details"
-  },
-  {
-   "default": "0",
-   "depends_on": "invoice_separately_as_consumables",
-   "fieldname": "consumption_invoiced",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "label": "Consumption Invoiced",
-   "read_only": 1
-  },
-  {
-   "depends_on": "eval:!doc.__islocal",
-   "fieldname": "status",
-   "fieldtype": "Select",
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Status",
-   "options": "Draft\nSubmitted\nCancelled\nIn Progress\nCompleted\nPending",
-   "read_only": 1
-  },
-  {
-   "fieldname": "amended_from",
-   "fieldtype": "Link",
-   "label": "Amended From",
-   "no_copy": 1,
-   "options": "Clinical Procedure",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "collapsible": 1,
-   "collapsible_depends_on": "consume_stock",
-   "fieldname": "consumables_section",
-   "fieldtype": "Section Break",
-   "label": "Consumables"
-  },
-  {
-   "fieldname": "column_break_27",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "section_break_24",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "column_break_30",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "section_break_6",
-   "fieldtype": "Section Break"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "sb_refs",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "patient_name",
-   "fieldtype": "Data",
-   "label": "Patient Name",
-   "read_only": 1
-  },
-  {
-   "fieldname": "practitioner_name",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Practitioner Name",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_34",
-   "fieldtype": "Column Break"
-  },
-  {
-   "allow_on_submit": 1,
-   "fieldname": "title",
-   "fieldtype": "Data",
-   "hidden": 1,
-   "label": "Title",
-   "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "fetch_from": "procedure_template.medical_code",
-   "fieldname": "medical_code",
-   "fieldtype": "Link",
-   "label": "Medical Code",
-   "options": "Medical Code",
-   "read_only": 1
-  }
- ],
- "is_submittable": 1,
- "links": [],
- "modified": "2020-06-29 14:28:11.779815",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Clinical Procedure",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Nursing User",
-   "share": 1,
-   "submit": 1,
-   "write": 1
-  },
-  {
-   "cancel": 1,
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "submit": 1,
-   "write": 1
-  }
- ],
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "title",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
deleted file mode 100644
index df4c2ef..0000000
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
+++ /dev/null
@@ -1,255 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, ESS LLP 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
-from frappe.model.mapper import get_mapped_doc
-from frappe.utils import flt, nowdate, nowtime
-
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_account
-from erpnext.healthcare.doctype.lab_test.lab_test import create_sample_doc
-from erpnext.stock.get_item_details import get_item_details
-from erpnext.stock.stock_ledger import get_previous_sle
-
-
-class ClinicalProcedure(Document):
-	def validate(self):
-		self.set_status()
-		self.set_title()
-		if self.consume_stock:
-			self.set_actual_qty()
-
-		if self.items:
-			self.invoice_separately_as_consumables = False
-			for item in self.items:
-				if item.invoice_separately_as_consumables:
-					self.invoice_separately_as_consumables = True
-
-	def before_insert(self):
-		if self.consume_stock:
-			self.set_actual_qty()
-
-	def after_insert(self):
-		if self.prescription:
-			frappe.db.set_value('Procedure Prescription', self.prescription, 'procedure_created', 1)
-		if self.appointment:
-			frappe.db.set_value('Patient Appointment', self.appointment, 'status', 'Closed')
-		template = frappe.get_doc('Clinical Procedure Template', self.procedure_template)
-		if template.sample:
-			patient = frappe.get_doc('Patient', self.patient)
-			sample_collection = create_sample_doc(template, patient, None, self.company)
-			frappe.db.set_value('Clinical Procedure', self.name, 'sample', sample_collection.name)
-		self.reload()
-
-	def set_status(self):
-		if self.docstatus == 0:
-			self.status = 'Draft'
-		elif self.docstatus == 1:
-			if self.status not in ['In Progress', 'Completed']:
-				self.status = 'Pending'
-		elif self.docstatus == 2:
-			self.status = 'Cancelled'
-
-	def set_title(self):
-		self.title = _('{0} - {1}').format(self.patient_name or self.patient, self.procedure_template)[:100]
-
-	@frappe.whitelist()
-	def complete_procedure(self):
-		if self.consume_stock and self.items:
-			stock_entry = make_stock_entry(self)
-
-		if self.items:
-			consumable_total_amount = 0
-			consumption_details = False
-			customer = frappe.db.get_value('Patient', self.patient, 'customer')
-			if customer:
-				for item in self.items:
-					if item.invoice_separately_as_consumables:
-						price_list, price_list_currency = frappe.db.get_values('Price List', {'selling': 1}, ['name', 'currency'])[0]
-						args = {
-							'doctype': 'Sales Invoice',
-							'item_code': item.item_code,
-							'company': self.company,
-							'warehouse': self.warehouse,
-							'customer': customer,
-							'selling_price_list': price_list,
-							'price_list_currency': price_list_currency,
-							'plc_conversion_rate': 1.0,
-							'conversion_rate': 1.0
-						}
-						item_details = get_item_details(args)
-						item_price = item_details.price_list_rate * item.qty
-						item_consumption_details = item_details.item_name + ' ' + str(item.qty) + ' ' + item.uom + ' ' + str(item_price)
-						consumable_total_amount += item_price
-						if not consumption_details:
-							consumption_details = _('Clinical Procedure ({0}):').format(self.name)
-						consumption_details += '\n\t' + item_consumption_details
-
-				if consumable_total_amount > 0:
-					frappe.db.set_value('Clinical Procedure', self.name, 'consumable_total_amount', consumable_total_amount)
-					frappe.db.set_value('Clinical Procedure', self.name, 'consumption_details', consumption_details)
-			else:
-				frappe.throw(_('Please set Customer in Patient {0}').format(frappe.bold(self.patient)), title=_('Customer Not Found'))
-
-		self.db_set('status', 'Completed')
-
-		if self.consume_stock and self.items:
-			return stock_entry
-
-	@frappe.whitelist()
-	def start_procedure(self):
-		allow_start = self.set_actual_qty()
-		if allow_start:
-			self.db_set('status', 'In Progress')
-			return 'success'
-		return 'insufficient stock'
-
-	def set_actual_qty(self):
-		allow_negative_stock = frappe.db.get_single_value('Stock Settings', 'allow_negative_stock')
-
-		allow_start = True
-		for d in self.get('items'):
-			d.actual_qty = get_stock_qty(d.item_code, self.warehouse)
-			# validate qty
-			if not allow_negative_stock and d.actual_qty < d.qty:
-				allow_start = False
-				break
-
-		return allow_start
-
-	@frappe.whitelist()
-	def make_material_receipt(self, submit=False):
-		stock_entry = frappe.new_doc('Stock Entry')
-
-		stock_entry.stock_entry_type = 'Material Receipt'
-		stock_entry.to_warehouse = self.warehouse
-		stock_entry.company = self.company
-		expense_account = get_account(None, 'expense_account', 'Healthcare Settings', self.company)
-		for item in self.items:
-			if item.qty > item.actual_qty:
-				se_child = stock_entry.append('items')
-				se_child.item_code = item.item_code
-				se_child.item_name = item.item_name
-				se_child.uom = item.uom
-				se_child.stock_uom = item.stock_uom
-				se_child.qty = flt(item.qty - item.actual_qty)
-				se_child.t_warehouse = self.warehouse
-				# in stock uom
-				se_child.transfer_qty = flt(item.transfer_qty)
-				se_child.conversion_factor = flt(item.conversion_factor)
-				cost_center = frappe.get_cached_value('Company',  self.company,  'cost_center')
-				se_child.cost_center = cost_center
-				se_child.expense_account = expense_account
-		if submit:
-			stock_entry.submit()
-			return stock_entry
-		return stock_entry.as_dict()
-
-
-def get_stock_qty(item_code, warehouse):
-	return get_previous_sle({
-		'item_code': item_code,
-		'warehouse': warehouse,
-		'posting_date': nowdate(),
-		'posting_time': nowtime()
-	}).get('qty_after_transaction') or 0
-
-
-@frappe.whitelist()
-def get_procedure_consumables(procedure_template):
-	return get_items('Clinical Procedure Item', procedure_template, 'Clinical Procedure Template')
-
-
-@frappe.whitelist()
-def set_stock_items(doc, stock_detail_parent, parenttype):
-	items = get_items('Clinical Procedure Item', stock_detail_parent, parenttype)
-
-	for item in items:
-		se_child = doc.append('items')
-		se_child.item_code = item.item_code
-		se_child.item_name = item.item_name
-		se_child.uom = item.uom
-		se_child.stock_uom = item.stock_uom
-		se_child.qty = flt(item.qty)
-		# in stock uom
-		se_child.transfer_qty = flt(item.transfer_qty)
-		se_child.conversion_factor = flt(item.conversion_factor)
-		if item.batch_no:
-			se_child.batch_no = item.batch_no
-		if parenttype == 'Clinical Procedure Template':
-			se_child.invoice_separately_as_consumables = item.invoice_separately_as_consumables
-
-	return doc
-
-
-def get_items(table, parent, parenttype):
-	items = frappe.db.get_all(table, filters={
-		'parent': parent,
-		'parenttype': parenttype
-	}, fields=['*'])
-
-	return items
-
-
-@frappe.whitelist()
-def make_stock_entry(doc):
-	stock_entry = frappe.new_doc('Stock Entry')
-	stock_entry = set_stock_items(stock_entry, doc.name, 'Clinical Procedure')
-	stock_entry.stock_entry_type = 'Material Issue'
-	stock_entry.from_warehouse = doc.warehouse
-	stock_entry.company = doc.company
-	expense_account = get_account(None, 'expense_account', 'Healthcare Settings', doc.company)
-
-	for item_line in stock_entry.items:
-		cost_center = frappe.get_cached_value('Company',  doc.company,  'cost_center')
-		item_line.cost_center = cost_center
-		item_line.expense_account = expense_account
-
-	stock_entry.save(ignore_permissions=True)
-	stock_entry.submit()
-	return stock_entry.name
-
-
-@frappe.whitelist()
-def make_procedure(source_name, target_doc=None):
-	def set_missing_values(source, target):
-		consume_stock = frappe.db.get_value('Clinical Procedure Template', source.procedure_template, 'consume_stock')
-		if consume_stock:
-			target.consume_stock = 1
-			warehouse = None
-			if source.service_unit:
-				warehouse = frappe.db.get_value('Healthcare Service Unit', source.service_unit, 'warehouse')
-			if not warehouse:
-				warehouse = frappe.db.get_value('Stock Settings', None, 'default_warehouse')
-			if warehouse:
-				target.warehouse = warehouse
-
-			set_stock_items(target, source.procedure_template, 'Clinical Procedure Template')
-
-	doc = get_mapped_doc('Patient Appointment', source_name, {
-			'Patient Appointment': {
-				'doctype': 'Clinical Procedure',
-				'field_map': [
-					['appointment', 'name'],
-					['patient', 'patient'],
-					['patient_age', 'patient_age'],
-					['patient_sex', 'patient_sex'],
-					['procedure_template', 'procedure_template'],
-					['prescription', 'procedure_prescription'],
-					['practitioner', 'practitioner'],
-					['medical_department', 'department'],
-					['start_date', 'appointment_date'],
-					['start_time', 'appointment_time'],
-					['notes', 'notes'],
-					['service_unit', 'service_unit'],
-					['company', 'company'],
-					['invoiced', 'invoiced']
-				]
-			}
-		}, target_doc, set_missing_values)
-
-	return doc
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure_list.js b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure_list.js
deleted file mode 100644
index c8601f9..0000000
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure_list.js
+++ /dev/null
@@ -1,11 +0,0 @@
-frappe.listview_settings['Clinical Procedure'] = {
-	get_indicator: function(doc) {
-		var colors = {
-			'Completed': 'green',
-			'In Progress': 'orange',
-			'Pending': 'orange',
-			'Cancelled': 'grey'
-		};
-		return [__(doc.status), colors[doc.status], 'status,=,' + doc.status];
-	}
-};
diff --git a/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py
deleted file mode 100644
index b5c3744..0000000
--- a/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py
+++ /dev/null
@@ -1,71 +0,0 @@
-	# -*- coding: utf-8 -*-
-# Copyright (c) 2017, ESS LLP and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-import frappe
-
-from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import (
-	create_clinical_procedure_template,
-	create_healthcare_docs,
-)
-
-test_dependencies = ['Item']
-
-class TestClinicalProcedure(unittest.TestCase):
-	def test_procedure_template_item(self):
-		patient, practitioner = create_healthcare_docs()
-		procedure_template = create_clinical_procedure_template()
-		self.assertTrue(frappe.db.exists('Item', procedure_template.item))
-
-		procedure_template.disabled = 1
-		procedure_template.save()
-		self.assertEqual(frappe.db.get_value('Item', procedure_template.item, 'disabled'), 1)
-
-	def test_consumables(self):
-		patient, practitioner = create_healthcare_docs()
-		procedure_template = create_clinical_procedure_template()
-		procedure_template.allow_stock_consumption = 1
-		consumable = create_consumable()
-		procedure_template.append('items', {
-			'item_code': consumable.item_code,
-			'qty': 1,
-			'uom': consumable.stock_uom,
-			'stock_uom': consumable.stock_uom
-		})
-		procedure_template.save()
-		procedure = create_procedure(procedure_template, patient, practitioner)
-		result = procedure.start_procedure()
-		if result == 'insufficient stock':
-			procedure.make_material_receipt(submit=True)
-			result = procedure.start_procedure()
-		self.assertEqual(procedure.status, 'In Progress')
-		result = procedure.complete_procedure()
-		# check consumption
-		self.assertTrue(frappe.db.exists('Stock Entry', result))
-
-
-def create_consumable():
-	if frappe.db.exists('Item', 'Syringe'):
-		return frappe.get_doc('Item', 'Syringe')
-	consumable = frappe.new_doc('Item')
-	consumable.item_code = 'Syringe'
-	consumable.item_group = '_Test Item Group'
-	consumable.stock_uom = 'Nos'
-	consumable.valuation_rate = 5.00
-	consumable.save()
-	return consumable
-
-def create_procedure(procedure_template, patient, practitioner):
-	procedure = frappe.new_doc('Clinical Procedure')
-	procedure.procedure_template = procedure_template.name
-	procedure.patient = patient
-	procedure.practitioner = practitioner
-	procedure.consume_stock = procedure_template.allow_stock_consumption
-	procedure.items = procedure_template.items
-	procedure.company = "_Test Company"
-	procedure.warehouse = "_Test Warehouse - _TC"
-	procedure.submit()
-	return procedure
diff --git a/erpnext/healthcare/doctype/clinical_procedure_item/__init__.py b/erpnext/healthcare/doctype/clinical_procedure_item/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/clinical_procedure_item/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json b/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
deleted file mode 100644
index a7dde0b..0000000
--- a/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
+++ /dev/null
@@ -1,123 +0,0 @@
-{
- "actions": [],
- "beta": 1,
- "creation": "2017-10-05 16:15:10.876952",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "item_code",
-  "item_name",
-  "qty",
-  "barcode",
-  "uom",
-  "invoice_separately_as_consumables",
-  "column_break_5",
-  "batch_no",
-  "conversion_factor",
-  "stock_uom",
-  "transfer_qty",
-  "actual_qty"
- ],
- "fields": [
-  {
-   "bold": 1,
-   "columns": 3,
-   "fieldname": "item_code",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_global_search": 1,
-   "in_list_view": 1,
-   "label": "Item",
-   "options": "Item",
-   "reqd": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "barcode",
-   "fieldtype": "Data",
-   "label": "Barcode"
-  },
-  {
-   "fieldname": "item_name",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Item Name",
-   "read_only": 1
-  },
-  {
-   "fieldname": "qty",
-   "fieldtype": "Float",
-   "in_list_view": 1,
-   "label": "Quantity",
-   "reqd": 1
-  },
-  {
-   "fieldname": "uom",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "UOM",
-   "options": "UOM",
-   "reqd": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "invoice_separately_as_consumables",
-   "fieldtype": "Check",
-   "in_list_view": 1,
-   "label": "Invoice Separately as Consumables"
-  },
-  {
-   "fieldname": "column_break_5",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "batch_no",
-   "fieldtype": "Link",
-   "label": "Batch",
-   "options": "Batch"
-  },
-  {
-   "fieldname": "conversion_factor",
-   "fieldtype": "Float",
-   "label": "Conversion Factor",
-   "read_only": 1
-  },
-  {
-   "fieldname": "stock_uom",
-   "fieldtype": "Link",
-   "label": "Stock UOM",
-   "options": "UOM",
-   "read_only": 1,
-   "reqd": 1
-  },
-  {
-   "fieldname": "transfer_qty",
-   "fieldtype": "Float",
-   "label": "Transfer Qty",
-   "read_only": 1
-  },
-  {
-   "fieldname": "actual_qty",
-   "fieldtype": "Float",
-   "label": "Actual Qty (at source/target)",
-   "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1,
-   "search_index": 1
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-03-01 15:34:54.226722",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Clinical Procedure Item",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.py b/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.py
deleted file mode 100644
index 16c5369..0000000
--- a/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, earthians and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class ClinicalProcedureItem(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/__init__.py b/erpnext/healthcare/doctype/clinical_procedure_template/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/clinical_procedure_template/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js
deleted file mode 100644
index ae6b39b..0000000
--- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright (c) 2017, earthians and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Clinical Procedure Template', {
-	template: function(frm) {
-		if (!frm.doc.item_code)
-			frm.set_value('item_code', frm.doc.template);
-		if (!frm.doc.description)
-			frm.set_value('description', frm.doc.template);
-		mark_change_in_item(frm);
-	},
-
-	rate: function(frm) {
-		mark_change_in_item(frm);
-	},
-
-	is_billable: function (frm) {
-		mark_change_in_item(frm);
-	},
-
-	item_group: function(frm) {
-		mark_change_in_item(frm);
-	},
-
-	description: function(frm) {
-		mark_change_in_item(frm);
-	},
-
-	medical_department: function(frm) {
-		mark_change_in_item(frm);
-	},
-
-	medical_code: function(frm) {
-		frm.set_query("medical_code", function() {
-			return {
-				filters: {
-					medical_code_standard: frm.doc.medical_code_standard
-				}
-			};
-		});
-	},
-
-	refresh: function(frm) {
-		frm.fields_dict['items'].grid.set_column_disp('barcode', false);
-		frm.fields_dict['items'].grid.set_column_disp('batch_no', false);
-
-		if (!frm.doc.__islocal) {
-			cur_frm.add_custom_button(__('Change Item Code'), function() {
-				change_template_code(frm.doc);
-			});
-		}
-	}
-});
-
-let mark_change_in_item = function(frm) {
-	if (!frm.doc.__islocal) {
-		frm.doc.change_in_item = 1;
-	}
-};
-
-let change_template_code = function(doc) {
-	let d = new frappe.ui.Dialog({
-		title:__('Change Item Code'),
-		fields:[
-			{
-				'fieldtype': 'Data',
-				'label': 'Item Code',
-				'fieldname': 'item_code',
-				reqd: 1
-			}
-		],
-		primary_action: function() {
-			let values = d.get_values();
-
-			if (values) {
-				frappe.call({
-					'method': 'erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.change_item_code_from_template',
-					'args': {item_code: values.item_code, doc: doc},
-					callback: function () {
-						cur_frm.reload_doc();
-						frappe.show_alert({
-							message: 'Item Code renamed successfully',
-							indicator: 'green'
-						});
-					}
-				});
-			}
-			d.hide();
-		},
-		primary_action_label: __('Change Item Code')
-	});
-	d.show();
-
-	d.set_values({
-		'item_code': doc.item_code
-	});
-};
-
-frappe.ui.form.on('Clinical Procedure Item', {
-	qty: function(frm, cdt, cdn) {
-		let d = locals[cdt][cdn];
-		frappe.model.set_value(cdt, cdn, 'transfer_qty', d.qty * d.conversion_factor);
-	},
-
-	uom: function(doc, cdt, cdn){
-		let d = locals[cdt][cdn];
-		if (d.uom && d.item_code) {
-			return frappe.call({
-				method: 'erpnext.stock.doctype.stock_entry.stock_entry.get_uom_details',
-				args: {
-					item_code: d.item_code,
-					uom: d.uom,
-					qty: d.qty
-				},
-				callback: function(r) {
-					if (r.message) {
-						frappe.model.set_value(cdt, cdn, r.message);
-					}
-				}
-			});
-		}
-	},
-
-	item_code: function(frm, cdt, cdn) {
-		let d = locals[cdt][cdn];
-		if (d.item_code) {
-			let args = {
-				'item_code'			: d.item_code,
-				'transfer_qty'		: d.transfer_qty,
-				'quantity'			: d.qty
-			};
-			return frappe.call({
-				method: 'erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.get_item_details',
-				args: {args: args},
-				callback: function(r) {
-					if (r.message) {
-						let d = locals[cdt][cdn];
-						$.each(r.message, function(k, v) {
-							d[k] = v;
-						});
-						refresh_field('items');
-					}
-				}
-			});
-		}
-	}
-});
-
-// List Stock items
-cur_frm.set_query('item_code', 'items', function() {
-	return {
-		filters: {
-			is_stock_item:1
-		}
-	};
-});
-
-frappe.tour['Clinical Procedure Template'] = [
-	{
-		fieldname: 'template',
-		title: __('Template Name'),
-		description: __('Enter a name for the Clinical Procedure Template')
-	},
-	{
-		fieldname: 'item_code',
-		title: __('Item Code'),
-		description: __('Set the Item Code which will be used for billing the Clinical Procedure.')
-	},
-	{
-		fieldname: 'item_group',
-		title: __('Item Group'),
-		description: __('Select an Item Group for the Clinical Procedure Item.')
-	},
-	{
-		fieldname: 'is_billable',
-		title: __('Clinical Procedure Rate'),
-		description: __('Check this if the Clinical Procedure is billable and also set the rate.')
-	},
-	{
-		fieldname: 'consume_stock',
-		title: __('Allow Stock Consumption'),
-		description: __('Check this if the Clinical Procedure utilises consumables. Click ') + "<a href='https://docs.erpnext.com/docs/user/manual/en/healthcare/clinical_procedure_template#22-manage-procedure-consumables' target='_blank'>here</a>" + __(' to know more')
-
-	},
-	{
-		fieldname: 'medical_department',
-		title: __('Medical Department'),
-		description: __('You can also set the Medical Department for the template. After saving the document, an Item will automatically be created for billing this Clinical Procedure. You can then use this template while creating Clinical Procedures for Patients. Templates save you from filling up redundant data every single time. You can also create templates for other operations like Lab Tests, Therapy Sessions, etc.')
-	}
-];
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
deleted file mode 100644
index 17ac7eb..0000000
--- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
+++ /dev/null
@@ -1,257 +0,0 @@
-{
- "actions": [],
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:template",
- "beta": 1,
- "creation": "2017-10-05 14:59:55.438359",
- "description": "Procedure Template",
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "template",
-  "item",
-  "item_code",
-  "item_group",
-  "description",
-  "column_break_5",
-  "disabled",
-  "is_billable",
-  "rate",
-  "medical_department",
-  "medical_coding_section",
-  "medical_code_standard",
-  "medical_code",
-  "consumables",
-  "consume_stock",
-  "items",
-  "sample_collection",
-  "sample",
-  "sample_uom",
-  "sample_qty",
-  "column_break_21",
-  "sample_details",
-  "change_in_item"
- ],
- "fields": [
-  {
-   "fieldname": "template",
-   "fieldtype": "Data",
-   "in_global_search": 1,
-   "in_list_view": 1,
-   "label": "Template Name",
-   "reqd": 1,
-   "unique": 1
-  },
-  {
-   "fieldname": "item_code",
-   "fieldtype": "Data",
-   "label": "Item Code",
-   "read_only_depends_on": "eval: !doc.__islocal ",
-   "reqd": 1
-  },
-  {
-   "fieldname": "item_group",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Item Group",
-   "options": "Item Group",
-   "reqd": 1
-  },
-  {
-   "fieldname": "medical_department",
-   "fieldtype": "Link",
-   "label": "Medical Department",
-   "options": "Medical Department"
-  },
-  {
-   "fieldname": "column_break_5",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "0",
-   "fieldname": "is_billable",
-   "fieldtype": "Check",
-   "label": "Is Billable"
-  },
-  {
-   "depends_on": "is_billable",
-   "fieldname": "rate",
-   "fieldtype": "Float",
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Rate",
-   "mandatory_depends_on": "is_billable"
-  },
-  {
-   "fieldname": "description",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Description",
-   "no_copy": 1,
-   "reqd": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "consume_stock",
-   "fieldtype": "Check",
-   "label": "Allow Stock Consumption",
-   "search_index": 1
-  },
-  {
-   "fieldname": "consumables",
-   "fieldtype": "Section Break",
-   "label": "Consumables"
-  },
-  {
-   "depends_on": "eval:doc.consume_stock == 1",
-   "fieldname": "items",
-   "fieldtype": "Table",
-   "ignore_user_permissions": 1,
-   "label": "Items",
-   "options": "Clinical Procedure Item"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "sample_collection",
-   "fieldtype": "Section Break",
-   "label": "Sample Collection"
-  },
-  {
-   "fieldname": "sample",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "label": "Sample",
-   "options": "Lab Test Sample"
-  },
-  {
-   "fetch_from": "sample.sample_uom",
-   "fieldname": "sample_uom",
-   "fieldtype": "Data",
-   "label": "Sample UOM",
-   "read_only": 1
-  },
-  {
-   "fieldname": "sample_qty",
-   "fieldtype": "Float",
-   "label": "Quantity"
-  },
-  {
-   "fieldname": "column_break_21",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "sample_details",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Collection Details"
-  },
-  {
-   "default": "0",
-   "fieldname": "change_in_item",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "label": "Change In Item",
-   "no_copy": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "disabled",
-   "fieldtype": "Check",
-   "label": "Disabled"
-  },
-  {
-   "fieldname": "item",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Item",
-   "no_copy": 1,
-   "options": "Item",
-   "read_only": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "medical_coding_section",
-   "fieldtype": "Section Break",
-   "label": "Medical Coding"
-  },
-  {
-   "fieldname": "medical_code_standard",
-   "fieldtype": "Link",
-   "label": "Medical Code Standard",
-   "options": "Medical Code Standard"
-  },
-  {
-   "depends_on": "medical_code_standard",
-   "fieldname": "medical_code",
-   "fieldtype": "Link",
-   "label": "Medical Code",
-   "options": "Medical Code"
-  }
- ],
- "links": [],
- "modified": "2020-06-29 14:12:27.158130",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Clinical Procedure Template",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Nursing User",
-   "share": 1
-  },
-  {
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "write": 1
-  }
- ],
- "restrict_to_domain": "Healthcare",
- "search_fields": "template",
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "template",
- "track_changes": 1,
- "track_seen": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
deleted file mode 100644
index 16e0969..0000000
--- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, earthians and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-import json
-
-import frappe
-from frappe import _
-from frappe.model.document import Document
-from frappe.model.rename_doc import rename_doc
-
-
-class ClinicalProcedureTemplate(Document):
-	def validate(self):
-		self.enable_disable_item()
-
-	def after_insert(self):
-		create_item_from_template(self)
-
-	def on_update(self):
-		if self.change_in_item:
-			self.update_item_and_item_price()
-
-	def enable_disable_item(self):
-		if self.is_billable:
-			if self.disabled:
-				frappe.db.set_value('Item', self.item, 'disabled', 1)
-			else:
-				frappe.db.set_value('Item', self.item, 'disabled', 0)
-
-	def update_item_and_item_price(self):
-		if self.is_billable and self.item:
-			item_doc = frappe.get_doc('Item', {'item_code': self.item})
-			item_doc.item_name = self.template
-			item_doc.item_group = self.item_group
-			item_doc.description = self.description
-			item_doc.disabled = 0
-			item_doc.save(ignore_permissions=True)
-
-			if self.rate:
-				item_price = frappe.get_doc('Item Price', {'item_code': self.item})
-				item_price.item_name = self.template
-				item_price.price_list_rate = self.rate
-				item_price.save()
-
-		elif not self.is_billable and self.item:
-			frappe.db.set_value('Item', self.item, 'disabled', 1)
-
-		self.db_set('change_in_item', 0)
-
-
-@frappe.whitelist()
-def get_item_details(args=None):
-	if not isinstance(args, dict):
-		args = json.loads(args)
-
-	item = frappe.db.get_all('Item',
-		filters={
-			'disabled': 0,
-			'name': args.get('item_code')
-		},
-		fields=['stock_uom', 'item_name']
-	)
-
-	if not item:
-		frappe.throw(_('Item {0} is not active').format(args.get('item_code')))
-
-	item = item[0]
-	ret = {
-		'uom': item.stock_uom,
-		'stock_uom': item.stock_uom,
-		'item_name': item.item_name,
-		'qty': 1,
-		'transfer_qty': 0,
-		'conversion_factor': 1
-	}
-	return ret
-
-def create_item_from_template(doc):
-	disabled = doc.disabled
-	if doc.is_billable and not doc.disabled:
-		disabled = 0
-
-	uom = frappe.db.exists('UOM', 'Unit') or frappe.db.get_single_value('Stock Settings', 'stock_uom')
-	item = frappe.get_doc({
-		'doctype': 'Item',
-		'item_code': doc.template,
-		'item_name':doc.template,
-		'item_group': doc.item_group,
-		'description':doc.description,
-		'is_sales_item': 1,
-		'is_service_item': 1,
-		'is_purchase_item': 0,
-		'is_stock_item': 0,
-		'show_in_website': 0,
-		'is_pro_applicable': 0,
-		'disabled': disabled,
-		'stock_uom': uom
-	}).insert(ignore_permissions=True, ignore_mandatory=True)
-
-	make_item_price(item.name, doc.rate)
-	doc.db_set('item', item.name)
-
-def make_item_price(item, item_price):
-	price_list_name = frappe.db.get_value('Price List', {'selling': 1})
-	frappe.get_doc({
-		'doctype': 'Item Price',
-		'price_list': price_list_name,
-		'item_code': item,
-		'price_list_rate': item_price
-	}).insert(ignore_permissions=True, ignore_mandatory=True)
-
-@frappe.whitelist()
-def change_item_code_from_template(item_code, doc):
-	doc = frappe._dict(json.loads(doc))
-
-	if frappe.db.exists('Item', {'item_code': item_code}):
-		frappe.throw(_('Item with Item Code {0} already exists').format(item_code))
-	else:
-		rename_doc('Item', doc.item_code, item_code, ignore_permissions=True)
-		frappe.db.set_value('Clinical Procedure Template', doc.name, 'item_code', item_code)
-	return
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template_dashboard.py b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template_dashboard.py
deleted file mode 100644
index a69899d..0000000
--- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template_dashboard.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from __future__ import unicode_literals
-
-from frappe import _
-
-
-def get_data():
-	return {
-		'fieldname': 'procedure_template',
-		'transactions': [
-			{
-				'label': _('Consultations'),
-				'items': ['Clinical Procedure']
-			}
-		]
-	}
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/test_clinical_procedure_template.py b/erpnext/healthcare/doctype/clinical_procedure_template/test_clinical_procedure_template.py
deleted file mode 100644
index f754c76..0000000
--- a/erpnext/healthcare/doctype/clinical_procedure_template/test_clinical_procedure_template.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, earthians and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-
-class TestClinicalProcedureTemplate(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/codification_table/__init__.py b/erpnext/healthcare/doctype/codification_table/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/codification_table/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/codification_table/codification_table.json b/erpnext/healthcare/doctype/codification_table/codification_table.json
deleted file mode 100644
index 9a917b4..0000000
--- a/erpnext/healthcare/doctype/codification_table/codification_table.json
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "beta": 1,
- "creation": "2017-06-22 13:09:23.159579",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "medical_code",
-  "code",
-  "description"
- ],
- "fields": [
-  {
-   "fieldname": "medical_code",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "label": "Medical Code",
-   "options": "Medical Code",
-   "reqd": 1
-  },
-  {
-   "fetch_from": "medical_code.code",
-   "fieldname": "code",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Code",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "medical_code.description",
-   "fieldname": "description",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Description",
-   "read_only": 1
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-02-26 13:17:49.016293",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Codification Table",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/codification_table/codification_table.py b/erpnext/healthcare/doctype/codification_table/codification_table.py
deleted file mode 100644
index 232d92c..0000000
--- a/erpnext/healthcare/doctype/codification_table/codification_table.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class CodificationTable(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/complaint/__init__.py b/erpnext/healthcare/doctype/complaint/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/complaint/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/complaint/complaint.js b/erpnext/healthcare/doctype/complaint/complaint.js
deleted file mode 100644
index 5a2d219..0000000
--- a/erpnext/healthcare/doctype/complaint/complaint.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Complaint', {
-});
diff --git a/erpnext/healthcare/doctype/complaint/complaint.json b/erpnext/healthcare/doctype/complaint/complaint.json
deleted file mode 100644
index f600838..0000000
--- a/erpnext/healthcare/doctype/complaint/complaint.json
+++ /dev/null
@@ -1,116 +0,0 @@
-{
- "allow_copy": 1, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 1, 
- "autoname": "field:complaints", 
- "beta": 1, 
- "creation": "2017-02-15 12:25:28.045267", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
- "fields": [
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "complaints", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 1, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Complaints", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2017-10-05 11:18:42.017864", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "Complaint", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Healthcare Administrator", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Physician", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Healthcare", 
- "search_fields": "complaints", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "title_field": "complaints", 
- "track_changes": 0, 
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/complaint/complaint.py b/erpnext/healthcare/doctype/complaint/complaint.py
deleted file mode 100644
index 20e00f6..0000000
--- a/erpnext/healthcare/doctype/complaint/complaint.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class Complaint(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/complaint/test_complaint.py b/erpnext/healthcare/doctype/complaint/test_complaint.py
deleted file mode 100644
index d3e1069..0000000
--- a/erpnext/healthcare/doctype/complaint/test_complaint.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-
-class TestComplaint(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/descriptive_test_result/__init__.py b/erpnext/healthcare/doctype/descriptive_test_result/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/descriptive_test_result/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/descriptive_test_result/descriptive_test_result.json b/erpnext/healthcare/doctype/descriptive_test_result/descriptive_test_result.json
deleted file mode 100644
index fcd3828..0000000
--- a/erpnext/healthcare/doctype/descriptive_test_result/descriptive_test_result.json
+++ /dev/null
@@ -1,74 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "beta": 1,
- "creation": "2016-02-22 15:12:36.202380",
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "lab_test_particulars",
-  "result_value",
-  "allow_blank",
-  "template",
-  "require_result_value"
- ],
- "fields": [
-  {
-   "fieldname": "lab_test_particulars",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Particulars",
-   "read_only": 1
-  },
-  {
-   "depends_on": "eval:doc.require_result_value == 1",
-   "fieldname": "result_value",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Value"
-  },
-  {
-   "fieldname": "template",
-   "fieldtype": "Link",
-   "hidden": 1,
-   "label": "Template",
-   "options": "Lab Test Template",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "require_result_value",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "label": "Require Result Value",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "default": "1",
-   "fieldname": "allow_blank",
-   "fieldtype": "Check",
-   "label": "Allow Blank",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-07-23 12:33:47.693065",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Descriptive Test Result",
- "owner": "Administrator",
- "permissions": [],
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/descriptive_test_result/descriptive_test_result.py b/erpnext/healthcare/doctype/descriptive_test_result/descriptive_test_result.py
deleted file mode 100644
index c086046..0000000
--- a/erpnext/healthcare/doctype/descriptive_test_result/descriptive_test_result.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class DescriptiveTestResult(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/descriptive_test_template/__init__.py b/erpnext/healthcare/doctype/descriptive_test_template/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/descriptive_test_template/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/descriptive_test_template/descriptive_test_template.json b/erpnext/healthcare/doctype/descriptive_test_template/descriptive_test_template.json
deleted file mode 100644
index 9ee8f4f..0000000
--- a/erpnext/healthcare/doctype/descriptive_test_template/descriptive_test_template.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "beta": 1,
- "creation": "2016-02-22 16:12:12.394200",
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "particulars",
-  "allow_blank"
- ],
- "fields": [
-  {
-   "fieldname": "particulars",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Result Component"
-  },
-  {
-   "default": "0",
-   "fieldname": "allow_blank",
-   "fieldtype": "Check",
-   "in_list_view": 1,
-   "label": "Allow Blank"
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-06-24 14:03:51.728863",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Descriptive Test Template",
- "owner": "Administrator",
- "permissions": [],
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/descriptive_test_template/descriptive_test_template.py b/erpnext/healthcare/doctype/descriptive_test_template/descriptive_test_template.py
deleted file mode 100644
index 84184fb..0000000
--- a/erpnext/healthcare/doctype/descriptive_test_template/descriptive_test_template.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class DescriptiveTestTemplate(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/diagnosis/__init__.py b/erpnext/healthcare/doctype/diagnosis/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/diagnosis/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/diagnosis/diagnosis.js b/erpnext/healthcare/doctype/diagnosis/diagnosis.js
deleted file mode 100644
index fb2557f..0000000
--- a/erpnext/healthcare/doctype/diagnosis/diagnosis.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2016, ESS LLP and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Diagnosis', {
-});
diff --git a/erpnext/healthcare/doctype/diagnosis/diagnosis.json b/erpnext/healthcare/doctype/diagnosis/diagnosis.json
deleted file mode 100644
index 936c2c5..0000000
--- a/erpnext/healthcare/doctype/diagnosis/diagnosis.json
+++ /dev/null
@@ -1,116 +0,0 @@
-{
- "allow_copy": 1, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 1, 
- "autoname": "field:diagnosis", 
- "beta": 1, 
- "creation": "2017-02-15 12:23:59.341108", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
- "fields": [
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "diagnosis", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 1, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Diagnosis", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2017-10-05 11:25:46.107435", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "Diagnosis", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Healthcare Administrator", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Physician", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Healthcare", 
- "search_fields": "diagnosis", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "title_field": "diagnosis", 
- "track_changes": 1, 
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/diagnosis/diagnosis.py b/erpnext/healthcare/doctype/diagnosis/diagnosis.py
deleted file mode 100644
index 05add1b..0000000
--- a/erpnext/healthcare/doctype/diagnosis/diagnosis.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class Diagnosis(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/diagnosis/test_diagnosis.py b/erpnext/healthcare/doctype/diagnosis/test_diagnosis.py
deleted file mode 100644
index c79164d..0000000
--- a/erpnext/healthcare/doctype/diagnosis/test_diagnosis.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-# test_records = frappe.get_test_records('Diagnosis')
-
-class TestDiagnosis(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/dosage_form/__init__.py b/erpnext/healthcare/doctype/dosage_form/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/dosage_form/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/dosage_form/dosage_form.js b/erpnext/healthcare/doctype/dosage_form/dosage_form.js
deleted file mode 100644
index 60e9696..0000000
--- a/erpnext/healthcare/doctype/dosage_form/dosage_form.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2017, ESS LLP and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Dosage Form', {
-});
diff --git a/erpnext/healthcare/doctype/dosage_form/dosage_form.json b/erpnext/healthcare/doctype/dosage_form/dosage_form.json
deleted file mode 100644
index 350aaed..0000000
--- a/erpnext/healthcare/doctype/dosage_form/dosage_form.json
+++ /dev/null
@@ -1,114 +0,0 @@
-{
- "allow_copy": 1, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 1, 
- "autoname": "field:dosage_form", 
- "beta": 1, 
- "creation": "2017-04-08 12:04:33.987972", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
- "fields": [
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "dosage_form", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 1, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Dosage Form", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2017-10-05 11:24:57.888091", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "Dosage Form", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Physician", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Healthcare Administrator", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Healthcare", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/dosage_form/dosage_form.py b/erpnext/healthcare/doctype/dosage_form/dosage_form.py
deleted file mode 100644
index 6b2d88b..0000000
--- a/erpnext/healthcare/doctype/dosage_form/dosage_form.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class DosageForm(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/dosage_form/test_dosage_form.py b/erpnext/healthcare/doctype/dosage_form/test_dosage_form.py
deleted file mode 100644
index 0161b82..0000000
--- a/erpnext/healthcare/doctype/dosage_form/test_dosage_form.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, ESS LLP and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-
-class TestDosageForm(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/dosage_strength/__init__.py b/erpnext/healthcare/doctype/dosage_strength/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/dosage_strength/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/dosage_strength/dosage_strength.json b/erpnext/healthcare/doctype/dosage_strength/dosage_strength.json
deleted file mode 100644
index da4f1a7..0000000
--- a/erpnext/healthcare/doctype/dosage_strength/dosage_strength.json
+++ /dev/null
@@ -1,102 +0,0 @@
-{
- "allow_copy": 1, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "beta": 1, 
- "creation": "2017-02-14 15:40:14.385707", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
- "fields": [
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "strength", 
-   "fieldtype": "Float", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Strength", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "strength_time", 
-   "fieldtype": "Time", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Time", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 1, 
- "max_attachments": 0, 
- "modified": "2017-08-31 14:11:59.874645", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "Dosage Strength", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Healthcare", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 0, 
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/dosage_strength/dosage_strength.py b/erpnext/healthcare/doctype/dosage_strength/dosage_strength.py
deleted file mode 100644
index 9e74743..0000000
--- a/erpnext/healthcare/doctype/dosage_strength/dosage_strength.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class DosageStrength(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/drug_prescription/__init__.py b/erpnext/healthcare/doctype/drug_prescription/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/drug_prescription/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/drug_prescription/drug_prescription.json b/erpnext/healthcare/doctype/drug_prescription/drug_prescription.json
deleted file mode 100644
index a65c566..0000000
--- a/erpnext/healthcare/doctype/drug_prescription/drug_prescription.json
+++ /dev/null
@@ -1,122 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "beta": 1,
- "creation": "2016-09-16 16:41:45.533374",
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "drug_code",
-  "drug_name",
-  "dosage",
-  "period",
-  "dosage_form",
-  "column_break_7",
-  "comment",
-  "usage_interval",
-  "interval",
-  "interval_uom",
-  "update_schedule"
- ],
- "fields": [
-  {
-   "fieldname": "drug_code",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "label": "Drug",
-   "options": "Item",
-   "reqd": 1
-  },
-  {
-   "fetch_from": "drug_code.item_name",
-   "fieldname": "drug_name",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Drug Name / Description"
-  },
-  {
-   "fieldname": "dosage",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "label": "Dosage",
-   "options": "Prescription Dosage",
-   "reqd": 1
-  },
-  {
-   "fieldname": "period",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "label": "Period",
-   "options": "Prescription Duration",
-   "reqd": 1
-  },
-  {
-   "allow_in_quick_entry": 1,
-   "fieldname": "dosage_form",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "label": "Dosage Form",
-   "options": "Dosage Form",
-   "reqd": 1
-  },
-  {
-   "fieldname": "column_break_7",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "comment",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Comment"
-  },
-  {
-   "depends_on": "usage_interval",
-   "fieldname": "interval",
-   "fieldtype": "Int",
-   "in_list_view": 1,
-   "label": "Interval"
-  },
-  {
-   "default": "1",
-   "depends_on": "usage_interval",
-   "fieldname": "update_schedule",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "label": "Update Schedule",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "depends_on": "use_interval",
-   "fieldname": "interval_uom",
-   "fieldtype": "Select",
-   "in_list_view": 1,
-   "label": "Interval UOM",
-   "options": "\nHour\nDay"
-  },
-  {
-   "default": "0",
-   "fieldname": "usage_interval",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "label": "Dosage by Time Interval"
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2021-06-11 11:53:06.343704",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Drug Prescription",
- "owner": "Administrator",
- "permissions": [],
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/drug_prescription/drug_prescription.py b/erpnext/healthcare/doctype/drug_prescription/drug_prescription.py
deleted file mode 100755
index 744bdb0..0000000
--- a/erpnext/healthcare/doctype/drug_prescription/drug_prescription.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-import frappe
-from frappe.model.document import Document
-
-
-class DrugPrescription(Document):
-	def get_quantity(self):
-		quantity = 0
-		dosage = None
-		period = None
-
-		if self.dosage:
-			dosage = frappe.get_doc('Prescription Dosage', self.dosage)
-			for item in dosage.dosage_strength:
-				quantity += item.strength
-			if self.period and self.interval:
-				period = frappe.get_doc('Prescription Duration', self.period)
-				if self.interval < period.get_days():
-					quantity = quantity * (period.get_days()/self.interval)
-
-		elif self.interval and self.interval_uom and self.period:
-			period = frappe.get_doc('Prescription Duration', self.period)
-			interval_in = self.interval_uom
-			if interval_in == 'Day' and self.interval < period.get_days():
-				quantity = period.get_days()/self.interval
-			elif interval_in == 'Hour' and self.interval < period.get_hours():
-				quantity = period.get_hours()/self.interval
-		if quantity > 0:
-			return quantity
-		else:
-			return 1
diff --git a/erpnext/healthcare/doctype/exercise/__init__.py b/erpnext/healthcare/doctype/exercise/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/exercise/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/exercise/exercise.json b/erpnext/healthcare/doctype/exercise/exercise.json
deleted file mode 100644
index 683cc6d..0000000
--- a/erpnext/healthcare/doctype/exercise/exercise.json
+++ /dev/null
@@ -1,62 +0,0 @@
-{
- "actions": [],
- "creation": "2020-03-11 09:25:00.968572",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "exercise_type",
-  "difficulty_level",
-  "counts_target",
-  "counts_completed",
-  "assistance_level"
- ],
- "fields": [
-  {
-   "fieldname": "exercise_type",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Exercise Type",
-   "options": "Exercise Type",
-   "reqd": 1
-  },
-  {
-   "fetch_from": "exercise_type.difficulty_level",
-   "fieldname": "difficulty_level",
-   "fieldtype": "Link",
-   "label": "Difficulty Level",
-   "options": "Exercise Difficulty Level"
-  },
-  {
-   "fieldname": "counts_target",
-   "fieldtype": "Int",
-   "in_list_view": 1,
-   "label": "Counts Target"
-  },
-  {
-   "depends_on": "eval:doc.parenttype==\"Therapy\";",
-   "fieldname": "counts_completed",
-   "fieldtype": "Int",
-   "label": "Counts Completed",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "assistance_level",
-   "fieldtype": "Select",
-   "label": "Assistance Level",
-   "options": "\nPassive\nActive Assist\nActive"
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-11-04 18:20:25.583491",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Exercise",
- "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/healthcare/doctype/exercise/exercise.py b/erpnext/healthcare/doctype/exercise/exercise.py
deleted file mode 100644
index 5d2b1f1..0000000
--- a/erpnext/healthcare/doctype/exercise/exercise.py
+++ /dev/null
@@ -1,12 +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 Exercise(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/exercise_difficulty_level/__init__.py b/erpnext/healthcare/doctype/exercise_difficulty_level/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/exercise_difficulty_level/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.js b/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.js
deleted file mode 100644
index ff51c34..0000000
--- a/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.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('Exercise Difficulty Level', {
-	// refresh: function(frm) {
-
-	// }
-});
diff --git a/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.json b/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.json
deleted file mode 100644
index a6aed75..0000000
--- a/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
- "actions": [],
- "autoname": "field:difficulty_level",
- "creation": "2020-03-29 21:12:55.835941",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "difficulty_level"
- ],
- "fields": [
-  {
-   "fieldname": "difficulty_level",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Difficulty Level",
-   "reqd": 1,
-   "unique": 1
-  }
- ],
- "links": [],
- "modified": "2020-03-31 23:14:33.554066",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Exercise Difficulty Level",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.py b/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.py
deleted file mode 100644
index bbb2972..0000000
--- a/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.py
+++ /dev/null
@@ -1,12 +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 ExerciseDifficultyLevel(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/exercise_difficulty_level/test_exercise_difficulty_level.py b/erpnext/healthcare/doctype/exercise_difficulty_level/test_exercise_difficulty_level.py
deleted file mode 100644
index dcaea08..0000000
--- a/erpnext/healthcare/doctype/exercise_difficulty_level/test_exercise_difficulty_level.py
+++ /dev/null
@@ -1,11 +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 TestExerciseDifficultyLevel(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/exercise_type/__init__.py b/erpnext/healthcare/doctype/exercise_type/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/exercise_type/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/exercise_type/exercise_type.js b/erpnext/healthcare/doctype/exercise_type/exercise_type.js
deleted file mode 100644
index 0614604..0000000
--- a/erpnext/healthcare/doctype/exercise_type/exercise_type.js
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Exercise Type', {
-	refresh: function(frm) {
-		let wrapper = frm.fields_dict.steps_html.wrapper;
-
-		frm.ExerciseEditor = new erpnext.ExerciseEditor(frm, wrapper);
-	}
-});
-
-erpnext.ExerciseEditor = class ExerciseEditor {
-	constructor(frm, wrapper) {
-		this.wrapper = wrapper;
-		this.frm = frm;
-		this.make(frm, wrapper);
-	}
-
-	make(frm, wrapper) {
-		$(this.wrapper).empty();
-
-		this.exercise_toolbar = $('<p>\
-		<button class="btn btn-default btn-add btn-xs" style="margin-left: 10px;"></button>').appendTo(this.wrapper);
-
-		this.exercise_cards = $('<div class="exercise-cards"></div>').appendTo(this.wrapper);
-
-		this.row = $('<div class="exercise-row"></div>').appendTo(this.wrapper);
-
-		let me = this;
-
-		this.exercise_toolbar.find(".btn-add")
-			.html(__('Add'))
-			.on("click", function() {
-				me.show_add_card_dialog(frm);
-			});
-
-		if (frm.doc.steps_table && frm.doc.steps_table.length > 0) {
-			this.make_cards(frm);
-			this.make_buttons(frm);
-		}
-	}
-
-	make_cards(frm) {
-		var me = this;
-		$(me.exercise_cards).empty();
-
-		$.each(frm.doc.steps_table, function(i, step) {
-			$(repl(`
-				<div class="exercise-col col-sm-4" id="%(col_id)s">
-					<div class="card h-100 exercise-card" id="%(card_id)s">
-						<div class="card-body exercise-card-body">
-							<img src=%(image_src)s class="card-img-top" alt="...">
-							<h4 class="card-title">%(title)s</h4>
-							<p class="card-text text-truncate">%(description)s</p>
-						</div>
-						<div class="card-footer">
-							<button class="btn btn-default btn-xs btn-edit" data-id="%(id)s"><i class="fa fa-pencil" aria-hidden="true"></i></button>
-							<button class="btn btn-default btn-xs btn-del" data-id="%(id)s"><i class="fa fa-trash" aria-hidden="true"></i></button>
-						</div>
-					</div>
-			</div>`, {image_src: step.image, title: step.title, description: step.description, col_id: "col-"+i, card_id: "card-"+i, id: i})).appendTo(me.row);
-		});
-	}
-
-	make_buttons(frm) {
-		let me = this;
-		$('.btn-edit').on('click', function() {
-			let id = $(this).attr('data-id');
-			me.show_edit_card_dialog(frm, id);
-		});
-
-		$('.btn-del').on('click', function() {
-			let id = $(this).attr('data-id');
-			$('#card-'+id).addClass("zoom-out");
-
-			setTimeout(() => {
-				// not using grid_rows[id].remove because
-				// grid_rows is not defined when the table is hidden
-				frm.doc.steps_table.pop(id);
-				frm.refresh_field('steps_table');
-				$('#col-'+id).remove();
-				frm.dirty();
-			}, 300);
-		});
-	}
-
-	show_add_card_dialog(frm) {
-		let me = this;
-		let d = new frappe.ui.Dialog({
-			title: __('Add Exercise Step'),
-			fields: [
-				{
-					"label": "Title",
-					"fieldname": "title",
-					"fieldtype": "Data",
-					"reqd": 1
-				},
-				{
-					"label": "Attach Image",
-					"fieldname": "image",
-					"fieldtype": "Attach Image"
-				},
-				{
-					"label": "Step Description",
-					"fieldname": "step_description",
-					"fieldtype": "Long Text"
-				}
-			],
-			primary_action: function() {
-				let data = d.get_values();
-				let i = 0;
-				if (frm.doc.steps_table) {
-					i = frm.doc.steps_table.length;
-				}
-				$(repl(`
-					<div class="exercise-col col-sm-4" id="%(col_id)s">
-						<div class="card h-100 exercise-card" id="%(card_id)s">
-							<div class="card-body exercise-card-body">
-								<img src=%(image_src)s class="card-img-top" alt="...">
-								<h4 class="card-title">%(title)s</h4>
-								<p class="card-text text-truncate">%(description)s</p>
-							</div>
-							<div class="card-footer">
-								<button class="btn btn-default btn-xs btn-edit" data-id="%(id)s"><i class="fa fa-pencil" aria-hidden="true"></i></button>
-								<button class="btn btn-default btn-xs btn-del" data-id="%(id)s"><i class="fa fa-trash" aria-hidden="true"></i></button>
-							</div>
-						</div>
-					</div>`, {image_src: data.image, title: data.title, description: data.step_description, col_id: "col-"+i, card_id: "card-"+i, id: i})).appendTo(me.row);
-				let step = frappe.model.add_child(frm.doc, 'Exercise Type Step', 'steps_table');
-				step.title = data.title;
-				step.image = data.image;
-				step.description = data.step_description;
-				me.make_buttons(frm);
-				frm.refresh_field('steps_table');
-				d.hide();
-			},
-			primary_action_label: __('Add')
-		});
-		d.show();
-	}
-
-	show_edit_card_dialog(frm, id) {
-		let new_dialog = new frappe.ui.Dialog({
-			title: __("Edit Exercise Step"),
-			fields: [
-				{
-					"label": "Title",
-					"fieldname": "title",
-					"fieldtype": "Data",
-					"reqd": 1
-				},
-				{
-					"label": "Attach Image",
-					"fieldname": "image",
-					"fieldtype": "Attach Image"
-				},
-				{
-					"label": "Step Description",
-					"fieldname": "step_description",
-					"fieldtype": "Long Text"
-				}
-			],
-			primary_action: () => {
-				let data = new_dialog.get_values();
-				$('#card-'+id).find('.card-title').html(data.title);
-				$('#card-'+id).find('img').attr('src', data.image);
-				$('#card-'+id).find('.card-text').html(data.step_description);
-
-				frm.doc.steps_table[id].title = data.title;
-				frm.doc.steps_table[id].image = data.image;
-				frm.doc.steps_table[id].description = data.step_description;
-				refresh_field('steps_table');
-				frm.dirty();
-				new_dialog.hide();
-			},
-			primary_action_label: __("Edit"),
-		});
-
-		new_dialog.set_values({
-			title: frm.doc.steps_table[id].title,
-			image: frm.doc.steps_table[id].image,
-			step_description: frm.doc.steps_table[id].description
-		});
-		new_dialog.show();
-	}
-};
diff --git a/erpnext/healthcare/doctype/exercise_type/exercise_type.json b/erpnext/healthcare/doctype/exercise_type/exercise_type.json
deleted file mode 100644
index 0db9c6e..0000000
--- a/erpnext/healthcare/doctype/exercise_type/exercise_type.json
+++ /dev/null
@@ -1,144 +0,0 @@
-{
- "actions": [],
- "creation": "2020-03-29 21:37:03.366344",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "exercise_name",
-  "body_parts",
-  "column_break_3",
-  "difficulty_level",
-  "section_break_5",
-  "description",
-  "section_break_7",
-  "exercise_steps",
-  "column_break_9",
-  "exercise_video",
-  "section_break_11",
-  "steps_html",
-  "section_break_13",
-  "steps_table"
- ],
- "fields": [
-  {
-   "fieldname": "exercise_name",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Exercise Name",
-   "reqd": 1
-  },
-  {
-   "fieldname": "difficulty_level",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Difficulty Level",
-   "options": "Exercise Difficulty Level"
-  },
-  {
-   "fieldname": "column_break_3",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "section_break_5",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "description",
-   "fieldtype": "Long Text",
-   "label": "Description"
-  },
-  {
-   "fieldname": "section_break_7",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "exercise_steps",
-   "fieldtype": "Attach",
-   "label": "Exercise Instructions"
-  },
-  {
-   "fieldname": "exercise_video",
-   "fieldtype": "Link",
-   "label": "Exercise Video",
-   "options": "Video"
-  },
-  {
-   "fieldname": "column_break_9",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "steps_html",
-   "fieldtype": "HTML",
-   "label": "Steps"
-  },
-  {
-   "fieldname": "steps_table",
-   "fieldtype": "Table",
-   "hidden": 1,
-   "label": "Steps Table",
-   "options": "Exercise Type Step"
-  },
-  {
-   "fieldname": "section_break_11",
-   "fieldtype": "Section Break",
-   "label": "Exercise Steps"
-  },
-  {
-   "fieldname": "section_break_13",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "body_parts",
-   "fieldtype": "Table MultiSelect",
-   "label": "Body Parts",
-   "options": "Body Part Link"
-  }
- ],
- "links": [],
- "modified": "2020-04-21 13:05:36.555060",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Exercise Type",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/exercise_type/exercise_type.py b/erpnext/healthcare/doctype/exercise_type/exercise_type.py
deleted file mode 100644
index 48eb6ba2..0000000
--- a/erpnext/healthcare/doctype/exercise_type/exercise_type.py
+++ /dev/null
@@ -1,16 +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 ExerciseType(Document):
-	def autoname(self):
-		if self.difficulty_level:
-			self.name = ' - '.join(filter(None, [self.exercise_name, self.difficulty_level]))
-		else:
-			self.name = self.exercise_name
diff --git a/erpnext/healthcare/doctype/exercise_type/test_exercise_type.py b/erpnext/healthcare/doctype/exercise_type/test_exercise_type.py
deleted file mode 100644
index 583aea9..0000000
--- a/erpnext/healthcare/doctype/exercise_type/test_exercise_type.py
+++ /dev/null
@@ -1,11 +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 TestExerciseType(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/exercise_type_step/__init__.py b/erpnext/healthcare/doctype/exercise_type_step/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/exercise_type_step/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.json b/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.json
deleted file mode 100644
index b37ff00..0000000
--- a/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- "actions": [],
- "creation": "2020-03-31 23:01:18.761967",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "title",
-  "image",
-  "description"
- ],
- "fields": [
-  {
-   "fieldname": "title",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Title",
-   "reqd": 1
-  },
-  {
-   "fieldname": "image",
-   "fieldtype": "Attach Image",
-   "label": "Image"
-  },
-  {
-   "fieldname": "description",
-   "fieldtype": "Long Text",
-   "in_list_view": 1,
-   "label": "Description"
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-04-02 20:39:34.258512",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Exercise Type Step",
- "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/healthcare/doctype/exercise_type_step/exercise_type_step.py b/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.py
deleted file mode 100644
index 412ef32..0000000
--- a/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.py
+++ /dev/null
@@ -1,12 +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 ExerciseTypeStep(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/fee_validity/__init__.py b/erpnext/healthcare/doctype/fee_validity/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/fee_validity/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/fee_validity/fee_validity.js b/erpnext/healthcare/doctype/fee_validity/fee_validity.js
deleted file mode 100644
index 7ea2213..0000000
--- a/erpnext/healthcare/doctype/fee_validity/fee_validity.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2016, ESS LLP and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Fee Validity', {
-});
diff --git a/erpnext/healthcare/doctype/fee_validity/fee_validity.json b/erpnext/healthcare/doctype/fee_validity/fee_validity.json
deleted file mode 100644
index d76b42e..0000000
--- a/erpnext/healthcare/doctype/fee_validity/fee_validity.json
+++ /dev/null
@@ -1,134 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "allow_import": 1,
- "beta": 1,
- "creation": "2017-01-05 10:56:29.564806",
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "practitioner",
-  "patient",
-  "column_break_3",
-  "status",
-  "section_break_5",
-  "section_break_3",
-  "max_visits",
-  "visited",
-  "ref_appointments",
-  "column_break_6",
-  "start_date",
-  "valid_till"
- ],
- "fields": [
-  {
-   "fieldname": "practitioner",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Healthcare Practitioner",
-   "options": "Healthcare Practitioner",
-   "read_only": 1,
-   "reqd": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Patient",
-   "options": "Patient",
-   "read_only": 1,
-   "reqd": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "visited",
-   "fieldtype": "Int",
-   "label": "Visits Completed",
-   "read_only": 1
-  },
-  {
-   "fieldname": "valid_till",
-   "fieldtype": "Date",
-   "label": "Valid Till",
-   "read_only": 1
-  },
-  {
-   "fieldname": "section_break_3",
-   "fieldtype": "Section Break",
-   "label": "Validity",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_6",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "max_visits",
-   "fieldtype": "Int",
-   "label": "Max number of visit",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_3",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "status",
-   "fieldtype": "Select",
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Status",
-   "options": "Completed\nPending",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "ref_appointment.appointment_date",
-   "fieldname": "start_date",
-   "fieldtype": "Date",
-   "label": "Start Date",
-   "read_only": 1
-  },
-  {
-   "fieldname": "ref_appointments",
-   "fieldtype": "Table MultiSelect",
-   "label": "Reference Appointments",
-   "options": "Fee Validity Reference",
-   "read_only": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "section_break_5",
-   "fieldtype": "Section Break"
-  }
- ],
- "in_create": 1,
- "links": [],
- "modified": "2021-08-26 10:51:05.609349",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Fee Validity",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "restrict_to_domain": "Healthcare",
- "search_fields": "practitioner, patient",
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "practitioner"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/fee_validity/fee_validity.py b/erpnext/healthcare/doctype/fee_validity/fee_validity.py
deleted file mode 100644
index aa30bec..0000000
--- a/erpnext/healthcare/doctype/fee_validity/fee_validity.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-import datetime
-
-import frappe
-from frappe.model.document import Document
-from frappe.utils import getdate
-
-
-class FeeValidity(Document):
-	def validate(self):
-		self.update_status()
-
-	def update_status(self):
-		if self.visited >= self.max_visits:
-			self.status = 'Completed'
-		else:
-			self.status = 'Pending'
-
-
-def create_fee_validity(appointment):
-	if not check_is_new_patient(appointment):
-		return
-
-	fee_validity = frappe.new_doc('Fee Validity')
-	fee_validity.practitioner = appointment.practitioner
-	fee_validity.patient = appointment.patient
-	fee_validity.max_visits = frappe.db.get_single_value('Healthcare Settings', 'max_visits') or 1
-	valid_days = frappe.db.get_single_value('Healthcare Settings', 'valid_days') or 1
-	fee_validity.visited = 0
-	fee_validity.start_date = getdate(appointment.appointment_date)
-	fee_validity.valid_till = getdate(appointment.appointment_date) + datetime.timedelta(days=int(valid_days))
-	fee_validity.save(ignore_permissions=True)
-	return fee_validity
-
-def check_is_new_patient(appointment):
-	validity_exists = frappe.db.exists('Fee Validity', {
-		'practitioner': appointment.practitioner,
-		'patient': appointment.patient
-	})
-	if validity_exists:
-		return False
-
-	appointment_exists = frappe.db.get_all('Patient Appointment', {
-		'name': ('!=', appointment.name),
-		'status': ('!=', 'Cancelled'),
-		'patient': appointment.patient,
-		'practitioner': appointment.practitioner
-	})
-	if len(appointment_exists) and appointment_exists[0]:
-		return False
-	return True
diff --git a/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py b/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py
deleted file mode 100644
index ce1947f..0000000
--- a/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-import frappe
-from frappe.utils import add_days, nowdate
-
-from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
-from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import (
-	create_appointment,
-	create_healthcare_docs,
-	create_healthcare_service_items,
-)
-
-test_dependencies = ["Company"]
-
-class TestFeeValidity(unittest.TestCase):
-	def setUp(self):
-		frappe.db.sql("""delete from `tabPatient Appointment`""")
-		frappe.db.sql("""delete from `tabFee Validity`""")
-		frappe.db.sql("""delete from `tabPatient`""")
-		make_pos_profile()
-
-	def test_fee_validity(self):
-		item = create_healthcare_service_items()
-		healthcare_settings = frappe.get_single("Healthcare Settings")
-		healthcare_settings.enable_free_follow_ups = 1
-		healthcare_settings.max_visits = 1
-		healthcare_settings.valid_days = 7
-		healthcare_settings.automate_appointment_invoicing = 1
-		healthcare_settings.op_consulting_charge_item = item
-		healthcare_settings.save(ignore_permissions=True)
-		patient, practitioner = create_healthcare_docs()
-
-		# For first appointment, invoice is generated. First appointment not considered in fee validity
-		appointment = create_appointment(patient, practitioner, nowdate())
-		invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
-		self.assertEqual(invoiced, 1)
-
-		# appointment should not be invoiced as it is within fee validity
-		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 4))
-		invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
-		self.assertEqual(invoiced, 0)
-
-		# appointment should be invoiced as it is within fee validity but the max_visits are exceeded
-		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 5), invoice=1)
-		invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
-		self.assertEqual(invoiced, 1)
-
-		# appointment should be invoiced as it is not within fee validity and the max_visits are exceeded
-		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 10), invoice=1)
-		invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
-		self.assertEqual(invoiced, 1)
diff --git a/erpnext/healthcare/doctype/fee_validity_reference/__init__.py b/erpnext/healthcare/doctype/fee_validity_reference/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/fee_validity_reference/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/fee_validity_reference/fee_validity_reference.json b/erpnext/healthcare/doctype/fee_validity_reference/fee_validity_reference.json
deleted file mode 100644
index 40f128e..0000000
--- a/erpnext/healthcare/doctype/fee_validity_reference/fee_validity_reference.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "actions": [],
- "creation": "2020-03-13 16:08:42.859996",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "appointment"
- ],
- "fields": [
-  {
-   "fieldname": "appointment",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Patient Appointment",
-   "options": "Patient Appointment",
-   "reqd": 1
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-03-15 00:27:02.076470",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Fee Validity Reference",
- "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/healthcare/doctype/fee_validity_reference/fee_validity_reference.py b/erpnext/healthcare/doctype/fee_validity_reference/fee_validity_reference.py
deleted file mode 100644
index c03978a..0000000
--- a/erpnext/healthcare/doctype/fee_validity_reference/fee_validity_reference.py
+++ /dev/null
@@ -1,12 +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 FeeValidityReference(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/healthcare.py b/erpnext/healthcare/doctype/healthcare.py
deleted file mode 100644
index f8e008e..0000000
--- a/erpnext/healthcare/doctype/healthcare.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from __future__ import unicode_literals
-
-
-def get_data():
-
-	return []
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/__init__.py b/erpnext/healthcare/doctype/healthcare_practitioner/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/healthcare_practitioner/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js
deleted file mode 100644
index 44c3998..0000000
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright (c) 2016, ESS LLP and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Healthcare Practitioner', {
-	setup: function(frm) {
-		frm.set_query('account', 'accounts', function(doc, cdt, cdn) {
-			let d = locals[cdt][cdn];
-			return {
-				filters: {
-					'root_type': 'Income',
-					'company': d.company,
-					'is_group': 0
-				}
-			};
-		});
-	},
-	refresh: function(frm) {
-		frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Healthcare Practitioner'};
-
-		if (!frm.is_new()) {
-			frappe.contacts.render_address_and_contact(frm);
-		} else {
-			frappe.contacts.clear_address_and_contact(frm);
-		}
-
-		frm.set_query('service_unit', 'practitioner_schedules', function(){
-			return {
-				filters: {
-					'is_group': false,
-					'allow_appointments': true
-				}
-			};
-		});
-
-		set_query_service_item(frm, 'inpatient_visit_charge_item');
-		set_query_service_item(frm, 'op_consulting_charge_item');
-	}
-});
-
-let set_query_service_item = function(frm, service_item_field) {
-	frm.set_query(service_item_field, function() {
-		return {
-			filters: {
-				'is_sales_item': 1,
-				'is_stock_item': 0
-			}
-		};
-	});
-};
-
-frappe.ui.form.on('Healthcare Practitioner', 'user_id',function(frm) {
-	if (frm.doc.user_id) {
-		frappe.call({
-			'method': 'frappe.client.get',
-			args: {
-				doctype: 'User',
-				name: frm.doc.user_id
-			},
-			callback: function (data) {
-
-				frappe.model.get_value('Employee', {'user_id': frm.doc.user_id}, 'name',
-					function(data) {
-						if (data) {
-							if (!frm.doc.employee || frm.doc.employee != data.name)
-								frappe.model.set_value(frm.doctype, frm.docname, 'employee', data.name);
-						} else {
-							frappe.model.set_value(frm.doctype, frm.docname, 'employee', '');
-						}
-					}
-				);
-
-				if (!frm.doc.first_name || frm.doc.first_name != data.message.first_name)
-					frappe.model.set_value(frm.doctype,frm.docname, 'first_name', data.message.first_name);
-				if (!frm.doc.middle_name || frm.doc.middle_name != data.message.middle_name)
-					frappe.model.set_value(frm.doctype,frm.docname, 'middle_name', data.message.middle_name);
-				if (!frm.doc.last_name || frm.doc.last_name != data.message.last_name)
-					frappe.model.set_value(frm.doctype,frm.docname, 'last_name', data.message.last_name);
-				if (!frm.doc.mobile_phone || frm.doc.mobile_phone != data.message.mobile_no)
-					frappe.model.set_value(frm.doctype,frm.docname, 'mobile_phone', data.message.mobile_no);
-			}
-		});
-	}
-});
-
-frappe.ui.form.on('Healthcare Practitioner', 'employee', function(frm) {
-	if (frm.doc.employee){
-		frappe.call({
-			'method': 'frappe.client.get',
-			args: {
-				doctype: 'Employee',
-				name: frm.doc.employee
-			},
-			callback: function (data) {
-				if (!frm.doc.user_id || frm.doc.user_id != data.message.user_id)
-					frm.set_value('user_id', data.message.user_id);
-				if (!frm.doc.designation || frm.doc.designation != data.message.designation)
-					frappe.model.set_value(frm.doctype,frm.docname, 'designation', data.message.designation);
-				if (!frm.doc.first_name || !frm.doc.user_id){
-					frappe.model.set_value(frm.doctype,frm.docname, 'first_name', data.message.first_name);
-					frappe.model.set_value(frm.doctype,frm.docname, 'middle_name', '');
-					frappe.model.set_value(frm.doctype,frm.docname, 'last_name', data.message.last_name);
-				}
-				if (!frm.doc.mobile_phone || !frm.doc.user_id)
-					frappe.model.set_value(frm.doctype,frm.docname, 'mobile_phone', data.message.cell_number);
-				if (!frm.doc.address || frm.doc.address != data.message.current_address)
-					frappe.model.set_value(frm.doctype,frm.docname, 'address', data.message.current_address);
-			}
-		});
-	}
-});
-
-frappe.tour['Healthcare Practitioner'] = [
-	{
-		fieldname: 'employee',
-		title: __('Employee'),
-		description: __('If you want to track Payroll and other HRMS operations for a Practitoner, create an Employee and link it here.')
-	},
-	{
-		fieldname: 'practitioner_schedules',
-		title: __('Practitioner Schedules'),
-		description: __('Set the Practitioner Schedule you just created. This will be used while booking appointments.')
-	},
-	{
-		fieldname: 'op_consulting_charge_item',
-		title: __('Out Patient Consulting Charge Item'),
-		description: __('Create a service item for Out Patient Consulting.')
-	},
-	{
-		fieldname: 'inpatient_visit_charge_item',
-		title: __('Inpatient Visit Charge Item'),
-		description: __('If this Healthcare Practitioner works for the In-Patient Department, create a service item for Inpatient Visits.')
-	},
-	{
-		fieldname: 'op_consulting_charge',
-		title: __('Out Patient Consulting Charge'),
-		description: __('Set the Out Patient Consulting Charge for this Practitioner.')
-
-	},
-	{
-		fieldname: 'inpatient_visit_charge',
-		title: __('Inpatient Visit Charge'),
-		description: __('If this Healthcare Practitioner also works for the In-Patient Department, set the inpatient visit charge for this Practitioner.')
-	}
-];
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json
deleted file mode 100644
index cb455eb..0000000
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json
+++ /dev/null
@@ -1,336 +0,0 @@
-{
- "actions": [],
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "naming_series:",
- "beta": 1,
- "creation": "2016-02-23 11:20:53.565119",
- "doctype": "DocType",
- "document_type": "Setup",
- "engine": "InnoDB",
- "field_order": [
-  "basic_details_section",
-  "naming_series",
-  "first_name",
-  "middle_name",
-  "last_name",
-  "practitioner_name",
-  "gender",
-  "image",
-  "column_break_7",
-  "status",
-  "mobile_phone",
-  "residence_phone",
-  "office_phone",
-  "employee_and_user_details_section",
-  "employee",
-  "department",
-  "designation",
-  "column_break_17",
-  "user_id",
-  "hospital",
-  "appointments",
-  "practitioner_schedules",
-  "charges",
-  "op_consulting_charge_item",
-  "op_consulting_charge",
-  "column_break_18",
-  "inpatient_visit_charge_item",
-  "inpatient_visit_charge",
-  "account_details",
-  "default_currency",
-  "accounts",
-  "address_and_contacts_section",
-  "address_html",
-  "column_break_19",
-  "contact_html"
- ],
- "fields": [
-  {
-   "fieldname": "first_name",
-   "fieldtype": "Data",
-   "label": "First Name",
-   "no_copy": 1,
-   "reqd": 1
-  },
-  {
-   "fieldname": "middle_name",
-   "fieldtype": "Data",
-   "label": "Middle Name (Optional)",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "last_name",
-   "fieldtype": "Data",
-   "label": "Last Name",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "image",
-   "fieldtype": "Attach Image",
-   "hidden": 1,
-   "label": "Image",
-   "no_copy": 1,
-   "print_hide": 1
-  },
-  {
-   "fieldname": "employee",
-   "fieldtype": "Link",
-   "label": "Employee",
-   "options": "Employee"
-  },
-  {
-   "fieldname": "user_id",
-   "fieldtype": "Link",
-   "label": "User",
-   "options": "User",
-   "search_index": 1
-  },
-  {
-   "fetch_from": "employee",
-   "fieldname": "designation",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Designation",
-   "options": "Designation",
-   "read_only": 1
-  },
-  {
-   "fieldname": "department",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_standard_filter": 1,
-   "label": "Medical Department",
-   "options": "Medical Department"
-  },
-  {
-   "fieldname": "column_break_7",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "hospital",
-   "fieldtype": "Data",
-   "label": "Hospital"
-  },
-  {
-   "fieldname": "mobile_phone",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Mobile"
-  },
-  {
-   "fieldname": "residence_phone",
-   "fieldtype": "Data",
-   "label": "Phone (R)"
-  },
-  {
-   "fieldname": "office_phone",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Phone (Office)"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "appointments",
-   "fieldtype": "Section Break",
-   "label": "Appointments"
-  },
-  {
-   "fieldname": "practitioner_schedules",
-   "fieldtype": "Table",
-   "label": "Practitioner Schedules",
-   "options": "Practitioner Service Unit Schedule"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "charges",
-   "fieldtype": "Section Break",
-   "label": "Charges"
-  },
-  {
-   "fieldname": "op_consulting_charge_item",
-   "fieldtype": "Link",
-   "label": "Out Patient Consulting Charge Item",
-   "options": "Item"
-  },
-  {
-   "fieldname": "op_consulting_charge",
-   "fieldtype": "Currency",
-   "label": "Out Patient Consulting Charge",
-   "mandatory_depends_on": "op_consulting_charge_item",
-   "options": "Currency"
-  },
-  {
-   "fieldname": "column_break_18",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "inpatient_visit_charge_item",
-   "fieldtype": "Link",
-   "label": "Inpatient Visit Charge Item",
-   "options": "Item"
-  },
-  {
-   "fieldname": "inpatient_visit_charge",
-   "fieldtype": "Currency",
-   "label": "Inpatient Visit Charge",
-   "mandatory_depends_on": "inpatient_visit_charge_item"
-  },
-  {
-   "depends_on": "eval: !doc.__islocal",
-   "fieldname": "address_html",
-   "fieldtype": "HTML",
-   "label": "Address HTML",
-   "no_copy": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "column_break_19",
-   "fieldtype": "Column Break"
-  },
-  {
-   "depends_on": "eval: !doc.__islocal",
-   "fieldname": "contact_html",
-   "fieldtype": "HTML",
-   "label": "Contact HTML",
-   "no_copy": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "account_details",
-   "fieldtype": "Section Break",
-   "label": "Account Details"
-  },
-  {
-   "fieldname": "accounts",
-   "fieldtype": "Table",
-   "label": "Income Account",
-   "options": "Party Account"
-  },
-  {
-   "fieldname": "default_currency",
-   "fieldtype": "Link",
-   "hidden": 1,
-   "label": "Default Currency",
-   "no_copy": 1,
-   "options": "Currency",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "bold": 1,
-   "fieldname": "practitioner_name",
-   "fieldtype": "Data",
-   "in_global_search": 1,
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Full Name",
-   "no_copy": 1,
-   "read_only": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "label": "Series",
-   "no_copy": 1,
-   "options": "HLC-PRAC-.YYYY.-",
-   "report_hide": 1,
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "gender",
-   "fieldtype": "Link",
-   "label": "Gender",
-   "options": "Gender"
-  },
-  {
-   "fieldname": "employee_and_user_details_section",
-   "fieldtype": "Section Break",
-   "label": "Employee and User Details"
-  },
-  {
-   "fieldname": "column_break_17",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "Active",
-   "fieldname": "status",
-   "fieldtype": "Select",
-   "in_list_view": 1,
-   "label": "Status",
-   "options": "\nActive\nDisabled",
-   "reqd": 1
-  },
-  {
-   "fieldname": "basic_details_section",
-   "fieldtype": "Section Break",
-   "label": "Basic Details"
-  },
-  {
-   "collapsible": 1,
-   "depends_on": "eval: !doc.__islocal",
-   "fieldname": "address_and_contacts_section",
-   "fieldtype": "Section Break",
-   "label": "Address and Contacts"
-  }
- ],
- "image_field": "image",
- "links": [],
- "modified": "2021-08-24 10:42:08.513054",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Healthcare Practitioner",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "email": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Laboratory User",
-   "select": 1,
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "select": 1,
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Nursing User",
-   "select": 1,
-   "share": 1,
-   "write": 1
-  }
- ],
- "restrict_to_domain": "Healthcare",
- "search_fields": "practitioner_name, mobile_phone, office_phone",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "practitioner_name",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
deleted file mode 100644
index 4550e7a..0000000
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-import frappe
-from frappe import _
-from frappe.contacts.address_and_contact import (
-	delete_contact_and_address,
-	load_address_and_contact,
-)
-from frappe.model.document import Document
-from frappe.model.naming import append_number_if_name_exists
-
-from erpnext.accounts.party import validate_party_accounts
-
-
-class HealthcarePractitioner(Document):
-	def onload(self):
-		load_address_and_contact(self)
-
-	def autoname(self):
-		# concat first and last name
-		self.name = self.practitioner_name
-
-		if frappe.db.exists('Healthcare Practitioner', self.name):
-			self.name = append_number_if_name_exists('Contact', self.name)
-
-	def validate(self):
-		self.set_full_name()
-		validate_party_accounts(self)
-		if self.inpatient_visit_charge_item:
-			validate_service_item(self.inpatient_visit_charge_item, 'Configure a service Item for Inpatient Consulting Charge Item')
-		if self.op_consulting_charge_item:
-			validate_service_item(self.op_consulting_charge_item, 'Configure a service Item for Out Patient Consulting Charge Item')
-
-		if self.user_id:
-			self.validate_user_id()
-		else:
-			existing_user_id = frappe.db.get_value('Healthcare Practitioner', self.name, 'user_id')
-			if existing_user_id:
-				frappe.permissions.remove_user_permission(
-					'Healthcare Practitioner', self.name, existing_user_id)
-
-	def on_update(self):
-		if self.user_id:
-			frappe.permissions.add_user_permission('Healthcare Practitioner', self.name, self.user_id)
-
-	def set_full_name(self):
-		if self.last_name:
-			self.practitioner_name = ' '.join(filter(None, [self.first_name, self.last_name]))
-		else:
-			self.practitioner_name = self.first_name
-
-	def validate_user_id(self):
-		if not frappe.db.exists('User', self.user_id):
-			frappe.throw(_('User {0} does not exist').format(self.user_id))
-		elif not frappe.db.exists('User', self.user_id, 'enabled'):
-			frappe.throw(_('User {0} is disabled').format(self.user_id))
-
-		# check duplicate
-		practitioner = frappe.db.exists('Healthcare Practitioner', {
-			'user_id': self.user_id,
-			'name': ('!=', self.name)
-		})
-		if practitioner:
-			frappe.throw(_('User {0} is already assigned to Healthcare Practitioner {1}').format(
-				self.user_id, practitioner))
-
-	def on_trash(self):
-		delete_contact_and_address('Healthcare Practitioner', self.name)
-
-def validate_service_item(item, msg):
-	if frappe.db.get_value('Item', item, 'is_stock_item'):
-		frappe.throw(_(msg))
-
-@frappe.whitelist()
-@frappe.validate_and_sanitize_search_inputs
-def get_practitioner_list(doctype, txt, searchfield, start, page_len, filters=None):
-	fields = ['name', 'practitioner_name', 'mobile_phone']
-
-	filters = {
-		'name': ('like', '%%%s%%' % txt)
-	}
-
-	return frappe.get_all('Healthcare Practitioner', fields = fields,
-		filters = filters, start=start, page_length=page_len, order_by='name, practitioner_name', as_list=1)
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py
deleted file mode 100644
index 8e0292e..0000000
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from __future__ import unicode_literals
-
-from frappe import _
-
-
-def get_data():
-	return {
-		'heatmap': True,
-		'heatmap_message': _('This is based on transactions against this Healthcare Practitioner.'),
-		'fieldname': 'practitioner',
-		'transactions': [
-			{
-				'label': _('Appointments and Patient Encounters'),
-				'items': ['Patient Appointment', 'Patient Encounter', 'Fee Validity']
-			},
-			{
-				'label': _('Consultation'),
-				'items': ['Clinical Procedure', 'Lab Test']
-			}
-		]
-	}
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/test_healthcare_practitioner.py b/erpnext/healthcare/doctype/healthcare_practitioner/test_healthcare_practitioner.py
deleted file mode 100644
index 214bcd2..0000000
--- a/erpnext/healthcare/doctype/healthcare_practitioner/test_healthcare_practitioner.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-
-class TestHealthcarePractitioner(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/healthcare_schedule_time_slot/__init__.py b/erpnext/healthcare/doctype/healthcare_schedule_time_slot/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/healthcare_schedule_time_slot/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.json b/erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.json
deleted file mode 100644
index cf54e82..0000000
--- a/erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.json
+++ /dev/null
@@ -1,136 +0,0 @@
-{
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "beta": 1, 
- "creation": "2017-05-03 17:27:07.466088", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
- "fields": [
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "day", 
-   "fieldtype": "Select", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Day", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Sunday\nMonday\nTuesday\nWednesday\nThursday\nFriday\nSaturday", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "from_time", 
-   "fieldtype": "Time", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "From Time", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "to_time", 
-   "fieldtype": "Time", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "To Time", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 1, 
- "max_attachments": 0, 
- "modified": "2020-09-18 17:26:09.703215", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "Healthcare Schedule Time Slot", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Healthcare", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.py b/erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.py
deleted file mode 100644
index 721da24..0000000
--- a/erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class HealthcareScheduleTimeSlot(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/__init__.py b/erpnext/healthcare/doctype/healthcare_service_unit/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/healthcare_service_unit/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.js b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.js
deleted file mode 100644
index 2d1caf7..0000000
--- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.js
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Healthcare Service Unit', {
-	onload: function(frm) {
-		frm.list_route = 'Tree/Healthcare Service Unit';
-
-		// get query select healthcare service unit
-		frm.fields_dict['parent_healthcare_service_unit'].get_query = function(doc) {
-			return {
-				filters: [
-					['Healthcare Service Unit', 'is_group', '=', 1],
-					['Healthcare Service Unit', 'name', '!=', doc.healthcare_service_unit_name]
-				]
-			};
-		};
-	},
-	refresh: function(frm) {
-		frm.trigger('set_root_readonly');
-		frm.set_df_property('service_unit_type', 'reqd', 1);
-		frm.add_custom_button(__('Healthcare Service Unit Tree'), function() {
-			frappe.set_route('Tree', 'Healthcare Service Unit');
-		});
-
-		frm.set_query('warehouse', function() {
-			return {
-				filters: {
-					'company': frm.doc.company
-				}
-			};
-		});
-	},
-	set_root_readonly: function(frm) {
-		// read-only for root healthcare service unit
-		frm.set_intro('');
-		if (!frm.doc.parent_healthcare_service_unit) {
-			frm.set_read_only();
-			frm.set_intro(__('This is a root healthcare service unit and cannot be edited.'), true);
-		}
-	},
-	allow_appointments: function(frm) {
-		if (!frm.doc.allow_appointments) {
-			frm.set_value('overlap_appointments', false);
-		}
-	},
-	is_group: function(frm) {
-		if (frm.doc.is_group == 1) {
-			frm.set_value('allow_appointments', false);
-			frm.set_df_property('service_unit_type', 'reqd', 0);
-		}
-		else {
-			frm.set_df_property('service_unit_type', 'reqd', 1);
-		}
-	},
-	overlap_appointments: function(frm) {
-		if (frm.doc.overlap_appointments == 0) {
-			frm.set_value('service_unit_capacity', '');
-		}
-	}
-});
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
deleted file mode 100644
index 8935ec7..0000000
--- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
+++ /dev/null
@@ -1,257 +0,0 @@
-{
- "actions": [],
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:healthcare_service_unit_name",
- "beta": 1,
- "creation": "2016-09-21 13:48:14.731437",
- "description": "Healthcare Service Unit",
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "healthcare_service_unit_name",
-  "is_group",
-  "service_unit_type",
-  "allow_appointments",
-  "overlap_appointments",
-  "service_unit_capacity",
-  "inpatient_occupancy",
-  "occupancy_status",
-  "column_break_9",
-  "company",
-  "warehouse",
-  "tree_details_section",
-  "parent_healthcare_service_unit",
-  "lft",
-  "rgt",
-  "old_parent"
- ],
- "fields": [
-  {
-   "fieldname": "healthcare_service_unit_name",
-   "fieldtype": "Data",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "in_global_search": 1,
-   "in_list_view": 1,
-   "label": "Service Unit",
-   "reqd": 1,
-   "unique": 1
-  },
-  {
-   "bold": 1,
-   "fieldname": "parent_healthcare_service_unit",
-   "fieldtype": "Link",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "label": "Parent Service Unit",
-   "options": "Healthcare Service Unit"
-  },
-  {
-   "bold": 1,
-   "default": "0",
-   "depends_on": "eval:doc.inpatient_occupancy != 1 && doc.allow_appointments != 1",
-   "fieldname": "is_group",
-   "fieldtype": "Check",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Is Group"
-  },
-  {
-   "bold": 1,
-   "depends_on": "eval:doc.is_group != 1",
-   "fieldname": "service_unit_type",
-   "fieldtype": "Link",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Service Unit Type",
-   "options": "Healthcare Service Unit Type"
-  },
-  {
-   "default": "0",
-   "depends_on": "eval:doc.is_group != 1 && doc.inpatient_occupancy != 1",
-   "fetch_from": "service_unit_type.allow_appointments",
-   "fieldname": "allow_appointments",
-   "fieldtype": "Check",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "in_list_view": 1,
-   "label": "Allow Appointments",
-   "no_copy": 1,
-   "read_only": 1
-  },
-  {
-   "default": "0",
-   "depends_on": "eval:doc.is_group != 1 && doc.allow_appointments == 1 && doc.inpatient_occupany != 1",
-   "fetch_from": "service_unit_type.overlap_appointments",
-   "fieldname": "overlap_appointments",
-   "fieldtype": "Check",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Allow Overlap",
-   "no_copy": 1,
-   "read_only": 1
-  },
-  {
-   "bold": 1,
-   "default": "0",
-   "depends_on": "eval:doc.allow_appointments != 1 && doc.is_group != 1",
-   "fetch_from": "service_unit_type.inpatient_occupancy",
-   "fieldname": "inpatient_occupancy",
-   "fieldtype": "Check",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "in_list_view": 1,
-   "label": "Inpatient Occupancy",
-   "no_copy": 1,
-   "read_only": 1,
-   "search_index": 1
-  },
-  {
-   "depends_on": "eval:doc.inpatient_occupancy == 1",
-   "fieldname": "occupancy_status",
-   "fieldtype": "Select",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Occupancy Status",
-   "no_copy": 1,
-   "options": "Vacant\nOccupied",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_9",
-   "fieldtype": "Column Break",
-   "hide_days": 1,
-   "hide_seconds": 1
-  },
-  {
-   "bold": 1,
-   "depends_on": "eval:doc.is_group != 1",
-   "fieldname": "warehouse",
-   "fieldtype": "Link",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Warehouse",
-   "no_copy": 1,
-   "options": "Warehouse"
-  },
-  {
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Company",
-   "options": "Company",
-   "remember_last_selected_value": 1,
-   "reqd": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "lft",
-   "fieldtype": "Int",
-   "hidden": 1,
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "lft",
-   "no_copy": 1,
-   "print_hide": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "rgt",
-   "fieldtype": "Int",
-   "hidden": 1,
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "rgt",
-   "no_copy": 1,
-   "print_hide": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "old_parent",
-   "fieldtype": "Link",
-   "hidden": 1,
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "ignore_user_permissions": 1,
-   "label": "Old Parent",
-   "no_copy": 1,
-   "options": "Healthcare Service Unit",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "tree_details_section",
-   "fieldtype": "Section Break",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Tree Details"
-  },
-  {
-   "depends_on": "eval:doc.overlap_appointments == 1",
-   "fieldname": "service_unit_capacity",
-   "fieldtype": "Int",
-   "label": "Service Unit Capacity",
-   "mandatory_depends_on": "eval:doc.overlap_appointments == 1",
-   "non_negative": 1
-  }
- ],
- "is_tree": 1,
- "links": [],
- "modified": "2021-08-19 14:09:11.643464",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Healthcare Service Unit",
- "nsm_parent_field": "parent_healthcare_service_unit",
- "owner": "Administrator",
- "permissions": [
-  {
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Nursing User",
-   "share": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "restrict_to_domain": "Healthcare",
- "search_fields": "healthcare_service_unit_name",
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "healthcare_service_unit_name",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.py b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.py
deleted file mode 100644
index 550b9fb..0000000
--- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-import json
-
-import frappe
-from frappe import _
-from frappe.utils import cint, cstr
-from frappe.utils.nestedset import NestedSet
-
-
-class HealthcareServiceUnit(NestedSet):
-	nsm_parent_field = 'parent_healthcare_service_unit'
-
-	def validate(self):
-		self.set_service_unit_properties()
-
-	def autoname(self):
-		if self.company:
-			suffix = " - " + frappe.get_cached_value('Company', self.company, 'abbr')
-			if not self.healthcare_service_unit_name.endswith(suffix):
-				self.name = self.healthcare_service_unit_name + suffix
-		else:
-			self.name = self.healthcare_service_unit_name
-
-	def on_update(self):
-		super(HealthcareServiceUnit, self).on_update()
-		self.validate_one_root()
-
-	def set_service_unit_properties(self):
-		if cint(self.is_group):
-			self.allow_appointments = False
-			self.overlap_appointments = False
-			self.inpatient_occupancy = False
-			self.service_unit_capacity = 0
-			self.occupancy_status = ''
-			self.service_unit_type = ''
-		elif self.service_unit_type != '':
-			service_unit_type = frappe.get_doc('Healthcare Service Unit Type', self.service_unit_type)
-			self.allow_appointments = service_unit_type.allow_appointments
-			self.inpatient_occupancy = service_unit_type.inpatient_occupancy
-
-			if self.inpatient_occupancy and self.occupancy_status != '':
-				self.occupancy_status = 'Vacant'
-
-			if service_unit_type.overlap_appointments:
-				self.overlap_appointments = True
-			else:
-				self.overlap_appointments = False
-				self.service_unit_capacity = 0
-
-		if self.overlap_appointments:
-			if not self.service_unit_capacity:
-				frappe.throw(_('Please set a valid Service Unit Capacity to enable Overlapping Appointments'),
-					title=_('Mandatory'))
-
-
-@frappe.whitelist()
-def add_multiple_service_units(parent, data):
-	'''
-	parent - parent service unit under which the service units are to be created
-	data (dict) - company, healthcare_service_unit_name, count, service_unit_type, warehouse, service_unit_capacity
-	'''
-	if not parent or not data:
-		return
-
-	data = json.loads(data)
-	company = data.get('company') or \
-		frappe.defaults.get_defaults().get('company') or \
-		frappe.db.get_single_value('Global Defaults', 'default_company')
-
-	if not data.get('healthcare_service_unit_name') or not company:
-		frappe.throw(_('Service Unit Name and Company are mandatory to create Healthcare Service Units'),
-			title=_('Missing Required Fields'))
-
-	count = cint(data.get('count') or 0)
-	if count <= 0:
-		frappe.throw(_('Number of Service Units to be created should at least be 1'),
-			title=_('Invalid Number of Service Units'))
-
-	capacity = cint(data.get('service_unit_capacity') or 1)
-
-	service_unit = {
-		'doctype': 'Healthcare Service Unit',
-		'parent_healthcare_service_unit': parent,
-		'service_unit_type': data.get('service_unit_type') or None,
-		'service_unit_capacity': capacity if capacity > 0 else 1,
-		'warehouse': data.get('warehouse') or None,
-		'company': company
-	}
-
-	service_unit_name = '{}'.format(data.get('healthcare_service_unit_name').strip(' -'))
-
-	last_suffix = frappe.db.sql("""SELECT
-		IFNULL(MAX(CAST(SUBSTRING(name FROM %(start)s FOR 4) AS UNSIGNED)), 0)
-		FROM `tabHealthcare Service Unit`
-		WHERE name like %(prefix)s AND company=%(company)s""",
-		{'start': len(service_unit_name)+2, 'prefix': '{}-%'.format(service_unit_name), 'company': company},
-		as_list=1)[0][0]
-	start_suffix = cint(last_suffix) + 1
-
-	failed_list = []
-	for i in range(start_suffix, count + start_suffix):
-		# name to be in the form WARD-####
-		service_unit['healthcare_service_unit_name'] = '{}-{}'.format(service_unit_name, cstr('%0*d' % (4, i)))
-		service_unit_doc = frappe.get_doc(service_unit)
-		try:
-			service_unit_doc.insert()
-		except Exception:
-			failed_list.append(service_unit['healthcare_service_unit_name'])
-
-	return failed_list
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js
deleted file mode 100644
index ea3fea6..0000000
--- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js
+++ /dev/null
@@ -1,185 +0,0 @@
-frappe.provide("frappe.treeview_settings");
-
-frappe.treeview_settings['Healthcare Service Unit'] = {
-	breadcrumbs: 'Healthcare Service Unit',
-	title: __('Service Unit Tree'),
-	get_tree_root: false,
-	get_tree_nodes: 'erpnext.healthcare.utils.get_children',
-	filters: [{
-		fieldname: 'company',
-		fieldtype: 'Select',
-		options: erpnext.utils.get_tree_options('company'),
-		label: __('Company'),
-		default: erpnext.utils.get_tree_default('company')
-	}],
-	fields: [
-		{
-			fieldtype: 'Data', fieldname: 'healthcare_service_unit_name', label: __('New Service Unit Name'),
-			reqd: true
-		},
-		{
-			fieldtype: 'Check', fieldname: 'is_group', label: __('Is Group'),
-			description: __("Child nodes can be only created under 'Group' type nodes")
-		},
-		{
-			fieldtype: 'Link', fieldname: 'service_unit_type', label: __('Service Unit Type'),
-			options: 'Healthcare Service Unit Type', description: __('Type of the new Service Unit'),
-			depends_on: 'eval:!doc.is_group', default: '',
-			onchange: () => {
-				if (cur_dialog) {
-					if (cur_dialog.fields_dict.service_unit_type.value) {
-						frappe.db.get_value('Healthcare Service Unit Type',
-							cur_dialog.fields_dict.service_unit_type.value, 'overlap_appointments')
-							.then(r => {
-								if (r.message.overlap_appointments) {
-									cur_dialog.set_df_property('service_unit_capacity', 'hidden', false);
-									cur_dialog.set_df_property('service_unit_capacity', 'reqd', true);
-								} else {
-									cur_dialog.set_df_property('service_unit_capacity', 'hidden', true);
-									cur_dialog.set_df_property('service_unit_capacity', 'reqd', false);
-								}
-							});
-					} else {
-						cur_dialog.set_df_property('service_unit_capacity', 'hidden', true);
-						cur_dialog.set_df_property('service_unit_capacity', 'reqd', false);
-					}
-				}
-			}
-		},
-		{
-			fieldtype: 'Int', fieldname: 'service_unit_capacity', label: __('Service Unit Capacity'),
-			description: __('Sets the number of concurrent appointments allowed'), reqd: false,
-			depends_on: "eval:!doc.is_group && doc.service_unit_type != ''", hidden: true
-		},
-		{
-			fieldtype: 'Link', fieldname: 'warehouse', label: __('Warehouse'), options: 'Warehouse',
-			description: __('Optional, if you want to manage stock separately for this Service Unit'),
-			depends_on: 'eval:!doc.is_group'
-		},
-		{
-			fieldtype: 'Link', fieldname: 'company', label: __('Company'), options: 'Company', reqd: true,
-			default: () => {
-				return cur_page.page.page.fields_dict.company.value;
-			}
-		}
-	],
-	ignore_fields: ['parent_healthcare_service_unit'],
-	onrender: function (node) {
-		if (node.data.occupied_of_available !== undefined) {
-			$("<span class='balance-area pull-right text-muted small'>"
-				+ ' ' + node.data.occupied_of_available
-				+ '</span>').insertBefore(node.$ul);
-		}
-		if (node.data && node.data.inpatient_occupancy !== undefined) {
-			if (node.data.inpatient_occupancy == 1) {
-				if (node.data.occupancy_status == 'Occupied') {
-					$("<span class='balance-area pull-right small'>"
-						+ ' ' + node.data.occupancy_status
-						+ '</span>').insertBefore(node.$ul);
-				}
-				if (node.data.occupancy_status == 'Vacant') {
-					$("<span class='balance-area pull-right text-muted small'>"
-						+ ' ' + node.data.occupancy_status
-						+ '</span>').insertBefore(node.$ul);
-				}
-			}
-		}
-	},
-	post_render: function (treeview) {
-		frappe.treeview_settings['Healthcare Service Unit'].treeview = {};
-		$.extend(frappe.treeview_settings['Healthcare Service Unit'].treeview, treeview);
-	},
-	toolbar: [
-		{
-			label: __('Add Multiple'),
-			condition: function (node) {
-				return node.expandable;
-			},
-			click: function (node) {
-				const dialog = new frappe.ui.Dialog({
-					title: __('Add Multiple Service Units'),
-					fields: [
-						{
-							fieldtype: 'Data', fieldname: 'healthcare_service_unit_name', label: __('Service Unit Name'),
-							reqd: true, description: __("Will be serially suffixed to maintain uniquness. Example: 'Ward' will be named as 'Ward-####'"),
-						},
-						{
-							fieldtype: 'Int', fieldname: 'count', label: __('Number of Service Units'),
-							reqd: true
-						},
-						{
-							fieldtype: 'Link', fieldname: 'service_unit_type', label: __('Service Unit Type'),
-							options: 'Healthcare Service Unit Type', description: __('Type of the new Service Unit'),
-							depends_on: 'eval:!doc.is_group', default: '', reqd: true,
-							onchange: () => {
-								if (cur_dialog) {
-									if (cur_dialog.fields_dict.service_unit_type.value) {
-										frappe.db.get_value('Healthcare Service Unit Type',
-											cur_dialog.fields_dict.service_unit_type.value, 'overlap_appointments')
-											.then(r => {
-												if (r.message.overlap_appointments) {
-													cur_dialog.set_df_property('service_unit_capacity', 'hidden', false);
-													cur_dialog.set_df_property('service_unit_capacity', 'reqd', true);
-												} else {
-													cur_dialog.set_df_property('service_unit_capacity', 'hidden', true);
-													cur_dialog.set_df_property('service_unit_capacity', 'reqd', false);
-												}
-											});
-									} else {
-										cur_dialog.set_df_property('service_unit_capacity', 'hidden', true);
-										cur_dialog.set_df_property('service_unit_capacity', 'reqd', false);
-									}
-								}
-							}
-						},
-						{
-							fieldtype: 'Int', fieldname: 'service_unit_capacity', label: __('Service Unit Capacity'),
-							description: __('Sets the number of concurrent appointments allowed'), reqd: false,
-							depends_on: "eval:!doc.is_group && doc.service_unit_type != ''", hidden: true
-						},
-						{
-							fieldtype: 'Link', fieldname: 'warehouse', label: __('Warehouse'), options: 'Warehouse',
-							description: __('Optional, if you want to manage stock separately for this Service Unit'),
-						},
-						{
-							fieldtype: 'Link', fieldname: 'company', label: __('Company'), options: 'Company', reqd: true,
-							default: () => {
-								return cur_page.page.page.fields_dict.company.get_value();
-							}
-						}
-					],
-					primary_action: () => {
-						dialog.hide();
-						let vals = dialog.get_values();
-						if (!vals) return;
-
-						return frappe.call({
-							method: 'erpnext.healthcare.doctype.healthcare_service_unit.healthcare_service_unit.add_multiple_service_units',
-							args: {
-								parent: node.data.value,
-								data: vals
-							},
-							callback: function (r) {
-								if (!r.exc && r.message) {
-									frappe.treeview_settings['Healthcare Service Unit'].treeview.tree.load_children(node, true);
-
-									frappe.show_alert({
-										message: __('{0} Service Units created', [vals.count - r.message.length]),
-										indicator: 'green'
-									});
-								} else {
-									frappe.msgprint(__('Could not create Service Units'));
-								}
-							},
-							freeze: true,
-							freeze_message: __('Creating {0} Service Units', [vals.count])
-						});
-					},
-					primary_action_label: __('Create')
-				});
-				dialog.show();
-			}
-		}
-	],
-	extend_toolbar: true
-};
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/test_healthcare_service_unit.py b/erpnext/healthcare/doctype/healthcare_service_unit/test_healthcare_service_unit.py
deleted file mode 100644
index 84197e5..0000000
--- a/erpnext/healthcare/doctype/healthcare_service_unit/test_healthcare_service_unit.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-
-class TestHealthcareServiceUnit(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/__init__.py b/erpnext/healthcare/doctype/healthcare_service_unit_type/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js
deleted file mode 100644
index ecf4aa1..0000000
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Healthcare Service Unit Type', {
-	refresh: function(frm) {
-		frm.set_df_property('item_code', 'read_only', frm.doc.__islocal ? 0 : 1);
-		if (!frm.doc.__islocal && frm.doc.is_billable) {
-			frm.add_custom_button(__('Change Item Code'), function() {
-				change_item_code(cur_frm, frm.doc);
-			});
-		}
-	},
-
-	service_unit_type: function(frm) {
-		set_item_details(frm);
-
-		if (!frm.doc.__islocal) {
-			frm.doc.change_in_item = 1;
-		}
-	},
-
-	is_billable: function(frm) {
-		set_item_details(frm);
-	},
-
-	rate: function(frm) {
-		if (!frm.doc.__islocal) {
-			frm.doc.change_in_item = 1;
-		}
-	},
-	item_group: function(frm) {
-		if (!frm.doc.__islocal) {
-			frm.doc.change_in_item = 1;
-		}
-	},
-	description: function(frm) {
-		if (!frm.doc.__islocal) {
-			frm.doc.change_in_item = 1;
-		}
-	}
-});
-
-let set_item_details = function(frm) {
-	if (frm.doc.service_unit_type && frm.doc.is_billable) {
-		if (!frm.doc.item_code)
-			frm.set_value('item_code', frm.doc.service_unit_type);
-		if (!frm.doc.description)
-			frm.set_value('description', frm.doc.service_unit_type);
-		if (!frm.doc.item_group)
-			frm.set_value('item_group', 'Services');
-	}
-};
-
-let change_item_code = function(frm, doc) {
-	let d = new frappe.ui.Dialog({
-		title: __('Change Item Code'),
-		fields: [
-			{
-				'fieldtype': 'Data',
-				'label': 'Item Code',
-				'fieldname': 'item_code',
-				'default': doc.item_code,
-				reqd: 1,
-			}
-		],
-		primary_action: function() {
-			let values = d.get_values();
-			if (values) {
-				frappe.call({
-					"method": "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.change_item_code",
-					"args": { item: doc.item, item_code: values['item_code'], doc_name: doc.name },
-					callback: function() {
-						frm.reload_doc();
-					}
-				});
-			}
-			d.hide();
-		},
-		primary_action_label: __("Change Template Code")
-	});
-
-	d.show();
-	d.set_values({
-		'Item Code': frm.doc.item_code
-	});
-};
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json
deleted file mode 100644
index 9c81c65..0000000
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json
+++ /dev/null
@@ -1,196 +0,0 @@
-{
- "actions": [],
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:service_unit_type",
- "creation": "2018-07-11 16:47:51.414675",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "disabled",
-  "service_unit_type",
-  "allow_appointments",
-  "overlap_appointments",
-  "inpatient_occupancy",
-  "is_billable",
-  "item_details",
-  "item",
-  "item_code",
-  "item_group",
-  "uom",
-  "no_of_hours",
-  "column_break_11",
-  "rate",
-  "description",
-  "change_in_item"
- ],
- "fields": [
-  {
-   "fieldname": "service_unit_type",
-   "fieldtype": "Data",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "in_list_view": 1,
-   "label": "Service Unit Type",
-   "no_copy": 1,
-   "reqd": 1,
-   "unique": 1
-  },
-  {
-   "bold": 1,
-   "default": "0",
-   "depends_on": "eval:doc.inpatient_occupancy != 1",
-   "fieldname": "allow_appointments",
-   "fieldtype": "Check",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Allow Appointments"
-  },
-  {
-   "bold": 1,
-   "default": "0",
-   "depends_on": "eval:doc.allow_appointments == 1 && doc.inpatient_occupany != 1",
-   "fieldname": "overlap_appointments",
-   "fieldtype": "Check",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Allow Overlap"
-  },
-  {
-   "bold": 1,
-   "default": "0",
-   "depends_on": "eval:doc.allow_appointments != 1",
-   "fieldname": "inpatient_occupancy",
-   "fieldtype": "Check",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Inpatient Occupancy"
-  },
-  {
-   "bold": 1,
-   "default": "0",
-   "depends_on": "eval:doc.inpatient_occupancy == 1 && doc.allow_appointments != 1",
-   "fieldname": "is_billable",
-   "fieldtype": "Check",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Is Billable"
-  },
-  {
-   "depends_on": "is_billable",
-   "fieldname": "item_details",
-   "fieldtype": "Section Break",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Item Details"
-  },
-  {
-   "fieldname": "item",
-   "fieldtype": "Link",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Item",
-   "no_copy": 1,
-   "options": "Item",
-   "read_only": 1
-  },
-  {
-   "fieldname": "item_code",
-   "fieldtype": "Data",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Item Code",
-   "mandatory_depends_on": "eval: doc.is_billable == 1",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "item_group",
-   "fieldtype": "Link",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Item Group",
-   "mandatory_depends_on": "eval: doc.is_billable == 1",
-   "options": "Item Group"
-  },
-  {
-   "fieldname": "uom",
-   "fieldtype": "Link",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "UOM",
-   "mandatory_depends_on": "eval: doc.is_billable == 1",
-   "options": "UOM"
-  },
-  {
-   "fieldname": "no_of_hours",
-   "fieldtype": "Int",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "UOM Conversion in Hours",
-   "mandatory_depends_on": "eval: doc.is_billable == 1"
-  },
-  {
-   "fieldname": "column_break_11",
-   "fieldtype": "Column Break",
-   "hide_days": 1,
-   "hide_seconds": 1
-  },
-  {
-   "fieldname": "rate",
-   "fieldtype": "Currency",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Rate / UOM"
-  },
-  {
-   "default": "0",
-   "fieldname": "disabled",
-   "fieldtype": "Check",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Disabled",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "description",
-   "fieldtype": "Small Text",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Description"
-  },
-  {
-   "default": "0",
-   "fieldname": "change_in_item",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Change in Item"
-  }
- ],
- "links": [],
- "modified": "2021-08-19 17:52:30.266667",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Healthcare Service Unit Type",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  }
- ],
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "service_unit_type"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
deleted file mode 100644
index 181cb52..0000000
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, 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
-from frappe.model.rename_doc import rename_doc
-
-
-class HealthcareServiceUnitType(Document):
-	def validate(self):
-		if self.allow_appointments and self.inpatient_occupancy:
-			frappe.msgprint(
-				_('Healthcare Service Unit Type cannot have both {0} and {1}').format(
-					frappe.bold('Allow Appointments'), frappe.bold('Inpatient Occupancy')),
-				raise_exception=1, title=_('Validation Error'), indicator='red'
-			)
-		elif not self.allow_appointments and not self.inpatient_occupancy:
-			frappe.msgprint(
-				_('Healthcare Service Unit Type must allow atleast one among {0} and {1}').format(
-					frappe.bold('Allow Appointments'), frappe.bold('Inpatient Occupancy')),
-				raise_exception=1, title=_('Validation Error'), indicator='red'
-			)
-
-		if not self.allow_appointments:
-			self.overlap_appointments = 0
-
-		if self.is_billable:
-			if self.disabled:
-				frappe.db.set_value('Item', self.item, 'disabled', 1)
-			else:
-				frappe.db.set_value('Item', self.item, 'disabled', 0)
-
-	def after_insert(self):
-		if self.inpatient_occupancy and self.is_billable:
-			create_item(self)
-
-	def on_trash(self):
-		if self.item:
-			try:
-				item = self.item
-				self.db_set('item', '')
-				frappe.delete_doc('Item', item)
-			except Exception:
-				frappe.throw(_('Not permitted. Please disable the Service Unit Type'))
-
-	def on_update(self):
-		if self.change_in_item and self.is_billable and self.item:
-			update_item(self)
-
-			item_price = item_price_exists(self)
-
-			if not item_price:
-				price_list_name = frappe.db.get_value('Price List', {'selling': 1})
-				if self.rate:
-					make_item_price(self.item_code, price_list_name, self.rate)
-				else:
-					make_item_price(self.item_code, price_list_name, 0.0)
-			else:
-				frappe.db.set_value('Item Price', item_price, 'price_list_rate', self.rate)
-
-			frappe.db.set_value(self.doctype, self.name, 'change_in_item',0)
-		elif not self.is_billable and self.item:
-			frappe.db.set_value('Item', self.item, 'disabled', 1)
-		self.reload()
-
-
-def item_price_exists(doc):
-	item_price = frappe.db.exists({'doctype': 'Item Price', 'item_code': doc.item_code})
-	if len(item_price):
-		return item_price[0][0]
-	return False
-
-def create_item(doc):
-	# insert item
-	item =  frappe.get_doc({
-		'doctype': 'Item',
-		'item_code': doc.item_code,
-		'item_name': doc.service_unit_type,
-		'item_group': doc.item_group,
-		'description': doc.description or doc.item_code,
-		'is_sales_item': 1,
-		'is_service_item': 1,
-		'is_purchase_item': 0,
-		'is_stock_item': 0,
-		'show_in_website': 0,
-		'is_pro_applicable': 0,
-		'disabled': 0,
-		'stock_uom': doc.uom
-	}).insert(ignore_permissions=True, ignore_mandatory=True)
-
-	# insert item price
-	# get item price list to insert item price
-	price_list_name = frappe.db.get_value('Price List', {'selling': 1})
-	if doc.rate:
-		make_item_price(item.name, price_list_name, doc.rate)
-		item.standard_rate = doc.rate
-	else:
-		make_item_price(item.name, price_list_name, 0.0)
-		item.standard_rate = 0.0
-
-	item.save(ignore_permissions=True)
-
-	# Set item in the doc
-	doc.db_set('item', item.name)
-
-def make_item_price(item, price_list_name, item_price):
-	frappe.get_doc({
-		'doctype': 'Item Price',
-		'price_list': price_list_name,
-		'item_code': item,
-		'price_list_rate': item_price
-	}).insert(ignore_permissions=True, ignore_mandatory=True)
-
-def update_item(doc):
-	item = frappe.get_doc("Item", doc.item)
-	if item:
-		item.update({
-			"item_name": doc.service_unit_type,
-			"item_group": doc.item_group,
-			"disabled": 0,
-			"standard_rate": doc.rate,
-			"description": doc.description
-		})
-		item.db_update()
-
-@frappe.whitelist()
-def change_item_code(item, item_code, doc_name):
-	if frappe.db.exists({'doctype': 'Item', 'item_code': item_code}):
-		frappe.throw(_('Item with Item Code {0} already exists').format(item_code))
-	else:
-		rename_doc('Item', item, item_code, ignore_permissions=True)
-		frappe.db.set_value('Healthcare Service Unit Type', doc_name, 'item_code', item_code)
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type_dashboard.py b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type_dashboard.py
deleted file mode 100644
index 7421ec3..0000000
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type_dashboard.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from __future__ import unicode_literals
-
-from frappe import _
-
-
-def get_data():
-	return {
-		'fieldname': 'service_unit_type',
-		'transactions': [
-			{
-				'label': _('Healthcare Service Units'),
-				'items': ['Healthcare Service Unit']
-			},
-		]
-	}
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.py b/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.py
deleted file mode 100644
index 839e1d6..0000000
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-import frappe
-
-
-class TestHealthcareServiceUnitType(unittest.TestCase):
-	def test_item_creation(self):
-		unit_type = get_unit_type()
-		self.assertTrue(frappe.db.exists('Item', unit_type.item))
-
-		# check item disabled
-		unit_type.disabled = 1
-		unit_type.save()
-		self.assertEqual(frappe.db.get_value('Item', unit_type.item, 'disabled'), 1)
-
-
-def get_unit_type():
-	if frappe.db.exists('Healthcare Service Unit Type', 'Inpatient Rooms'):
-		return frappe.get_doc('Healthcare Service Unit Type', 'Inpatient Rooms')
-
-	unit_type = frappe.new_doc('Healthcare Service Unit Type')
-	unit_type.service_unit_type = 'Inpatient Rooms'
-	unit_type.inpatient_occupancy = 1
-	unit_type.is_billable = 1
-	unit_type.item_code = 'Inpatient Rooms'
-	unit_type.item_group = 'Services'
-	unit_type.uom = 'Hour'
-	unit_type.no_of_hours = 1
-	unit_type.rate = 4000
-	unit_type.save()
-	return unit_type
diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.js b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.js
deleted file mode 100644
index cf2276f..0000000
--- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.js
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Healthcare Settings', {
-	setup: function(frm) {
-		frm.set_query('account', 'receivable_account', function(doc, cdt, cdn) {
-			var d  = locals[cdt][cdn];
-			return {
-				filters: {
-					'account_type': 'Receivable',
-					'company': d.company,
-					'is_group': 0
-				}
-			};
-		});
-		frm.set_query('account', 'income_account', function(doc, cdt, cdn) {
-			var d  = locals[cdt][cdn];
-			return {
-				filters: {
-					'root_type': 'Income',
-					'company': d.company,
-					'is_group': 0
-				}
-			};
-		});
-		set_query_service_item(frm, 'inpatient_visit_charge_item');
-		set_query_service_item(frm, 'op_consulting_charge_item');
-		set_query_service_item(frm, 'clinical_procedure_consumable_item');
-	}
-});
-
-var set_query_service_item = function(frm, service_item_field) {
-	frm.set_query(service_item_field, function() {
-		return {
-			filters: {
-				'is_sales_item': 1,
-				'is_stock_item': 0
-			}
-		};
-	});
-};
-
-frappe.tour['Healthcare Settings'] = [
-	{
-		fieldname: 'link_customer_to_patient',
-		title: __('Link Customer to Patient'),
-		description: __('If checked, a customer will be created for every Patient. Patient Invoices will be created against this Customer. You can also select existing Customer while creating a Patient. This field is checked by default.')
-	},
-	{
-		fieldname: 'collect_registration_fee',
-		title: __('Collect Registration Fee'),
-		description: __('If your Healthcare facility bills registrations of Patients, you can check this and set the Registration Fee in the field below. Checking this will create new Patients with a Disabled status by default and will only be enabled after invoicing the Registration Fee.')
-	},
-	{
-		fieldname: 'automate_appointment_invoicing',
-		title: __('Automate Appointment Invoicing'),
-		description: __('Checking this will automatically create a Sales Invoice whenever an appointment is booked for a Patient.')
-	},
-	{
-		fieldname: 'inpatient_visit_charge_item',
-		title: __('Healthcare Service Items'),
-		description: __('You can create a service item for Inpatient Visit Charge and set it here. Similarly, you can set up other Healthcare Service Items for billing in this section. Click ') + "<a href='https://docs.erpnext.com/docs/user/manual/en/healthcare/healthcare_settings#2-default-healthcare-service-items' target='_blank'>here</a>" + __(' to know more')
-	},
-	{
-		fieldname: 'income_account',
-		title: __('Set up default Accounts for the Healthcare Facility'),
-		description: __('If you wish to override default accounts settings and configure the Income and Receivable accounts for Healthcare, you can do so here.')
-
-	},
-	{
-		fieldname: 'send_registration_msg',
-		title: __('Out Patient SMS alerts'),
-		description: __('If you want to send SMS alert on Patient Registration, you can enable this option. Similary, you can set up Out Patient SMS alerts for other functionalities in this section. Click ') + "<a href='https://docs.erpnext.com/docs/user/manual/en/healthcare/healthcare_settings#4-out-patient-sms-alerts' target='_blank'>here</a>" + __(' to know more')
-	}
-];
diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
deleted file mode 100644
index ddf1bce..0000000
--- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
+++ /dev/null
@@ -1,351 +0,0 @@
-{
- "actions": [],
- "beta": 1,
- "creation": "2017-05-09 11:26:22.337760",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "sb_op_settings",
-  "patient_name_by",
-  "link_customer_to_patient",
-  "default_medical_code_standard",
-  "column_break_9",
-  "collect_registration_fee",
-  "registration_fee",
-  "automate_appointment_invoicing",
-  "enable_free_follow_ups",
-  "max_visits",
-  "valid_days",
-  "inpatient_settings_section",
-  "allow_discharge_despite_unbilled_services",
-  "do_not_bill_inpatient_encounters",
-  "healthcare_service_items",
-  "inpatient_visit_charge_item",
-  "op_consulting_charge_item",
-  "column_break_13",
-  "clinical_procedure_consumable_item",
-  "sb_in_ac",
-  "income_account",
-  "receivable_account",
-  "out_patient_sms_alerts",
-  "send_registration_msg",
-  "registration_msg",
-  "send_appointment_confirmation",
-  "appointment_confirmation_msg",
-  "avoid_confirmation",
-  "column_break_16",
-  "send_appointment_reminder",
-  "appointment_reminder_msg",
-  "remind_before",
-  "sb_lab_settings",
-  "create_lab_test_on_si_submit",
-  "create_sample_collection_for_lab_test",
-  "column_break_34",
-  "lab_test_approval_required",
-  "employee_name_and_designation_in_print",
-  "custom_signature_in_print",
-  "laboratory_sms_alerts",
-  "sms_printed",
-  "column_break_28",
-  "sms_emailed"
- ],
- "fields": [
-  {
-   "fieldname": "sb_op_settings",
-   "fieldtype": "Section Break",
-   "label": "Out Patient Settings"
-  },
-  {
-   "fieldname": "default_medical_code_standard",
-   "fieldtype": "Link",
-   "label": "Default Medical Code Standard",
-   "options": "Medical Code Standard"
-  },
-  {
-   "fieldname": "column_break_9",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "0",
-   "description": "Checking this will create new Patients with a Disabled status by default and will only be enabled after invoicing the Registration Fee.",
-   "fieldname": "collect_registration_fee",
-   "fieldtype": "Check",
-   "label": "Collect Fee for Patient Registration"
-  },
-  {
-   "depends_on": "collect_registration_fee",
-   "fieldname": "registration_fee",
-   "fieldtype": "Currency",
-   "label": "Registration Fee",
-   "mandatory_depends_on": "eval:doc.collect_registration_fee == 1",
-   "options": "Currency"
-  },
-  {
-   "depends_on": "eval:doc.enable_free_follow_ups == 1",
-   "description": "Time period (Valid number of days) for free consultations",
-   "fieldname": "valid_days",
-   "fieldtype": "Int",
-   "label": "Valid Number of Days",
-   "mandatory_depends_on": "eval:doc.enable_free_follow_ups == 1"
-  },
-  {
-   "collapsible": 1,
-   "description": "You can configure default Items for billing consultation charges, procedure consumption items and inpatient visits",
-   "fieldname": "healthcare_service_items",
-   "fieldtype": "Section Break",
-   "label": "Default Healthcare Service Items"
-  },
-  {
-   "fieldname": "inpatient_visit_charge_item",
-   "fieldtype": "Link",
-   "label": "Inpatient Visit Charge Item",
-   "options": "Item"
-  },
-  {
-   "fieldname": "op_consulting_charge_item",
-   "fieldtype": "Link",
-   "label": "Out Patient Consulting Charge Item",
-   "options": "Item"
-  },
-  {
-   "fieldname": "column_break_13",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "clinical_procedure_consumable_item",
-   "fieldtype": "Link",
-   "label": "Clinical Procedure Consumable Item",
-   "options": "Item"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "out_patient_sms_alerts",
-   "fieldtype": "Section Break",
-   "label": "Out Patient SMS Alerts"
-  },
-  {
-   "fieldname": "column_break_16",
-   "fieldtype": "Column Break"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "sb_in_ac",
-   "fieldtype": "Section Break",
-   "label": "Default Accounts"
-  },
-  {
-   "description": "Default income accounts to be used if not set in Healthcare Practitioner to book Appointment charges.",
-   "fieldname": "income_account",
-   "fieldtype": "Table",
-   "label": "Income Account",
-   "options": "Party Account"
-  },
-  {
-   "description": "Default receivable accounts to be used to book Appointment charges.",
-   "fieldname": "receivable_account",
-   "fieldtype": "Table",
-   "label": "Receivable Account",
-   "options": "Party Account"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "sb_lab_settings",
-   "fieldtype": "Section Break",
-   "label": "Laboratory Settings"
-  },
-  {
-   "fieldname": "column_break_34",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "1",
-   "description": "Check this if you want the Name and Designation of the Employee associated with the User who submits the document to be printed in the Lab Test Report.",
-   "fieldname": "employee_name_and_designation_in_print",
-   "fieldtype": "Check",
-   "label": "Employee name and designation in print"
-  },
-  {
-   "depends_on": "eval:doc.employee_name_and_designation_in_print == '0'\n",
-   "fieldname": "custom_signature_in_print",
-   "fieldtype": "Small Text",
-   "label": "Custom Signature in Print"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "laboratory_sms_alerts",
-   "fieldtype": "Section Break",
-   "label": "Laboratory SMS Alerts"
-  },
-  {
-   "default": "Hello {{doc.patient}}, Your {{doc.lab_test_name}} result is ready with {{doc.company }}. \nThank You, Good day!",
-   "fieldname": "sms_printed",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Result Printed Message"
-  },
-  {
-   "fieldname": "column_break_28",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "Hello {{doc.patient}}, Your {{doc.lab_test_name}} result has been emailed to {{doc.email}}. \n{{doc.company }}. \nThank You, Good day!",
-   "fieldname": "sms_emailed",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Result Emailed Message"
-  },
-  {
-   "default": "0",
-   "description": "Checking this will restrict printing and emailing of Lab Test documents unless they have the status as Approved.",
-   "fieldname": "lab_test_approval_required",
-   "fieldtype": "Check",
-   "label": "Do not print or email Lab Tests without Approval"
-  },
-  {
-   "default": "1",
-   "description": "If checked, a customer will be created, mapped to Patient.\nPatient Invoices will be created against this Customer. You can also select existing Customer while creating Patient.",
-   "fieldname": "link_customer_to_patient",
-   "fieldtype": "Check",
-   "label": "Link Customer to Patient"
-  },
-  {
-   "default": "0",
-   "description": "Checking this will create Lab Test(s) specified in the Sales Invoice on submission.",
-   "fieldname": "create_lab_test_on_si_submit",
-   "fieldtype": "Check",
-   "label": "Create Lab Test(s) on Sales Invoice Submission"
-  },
-  {
-   "default": "0",
-   "description": "Checking this will create a Sample Collection document  every time you create a Lab Test",
-   "fieldname": "create_sample_collection_for_lab_test",
-   "fieldtype": "Check",
-   "label": "Create Sample Collection document for Lab Test"
-  },
-  {
-   "fieldname": "patient_name_by",
-   "fieldtype": "Select",
-   "label": "Patient Name By",
-   "options": "Patient Name\nNaming Series"
-  },
-  {
-   "default": "0",
-   "description": "Manage Appointment Invoice submit and cancel automatically for Patient Encounter",
-   "fieldname": "automate_appointment_invoicing",
-   "fieldtype": "Check",
-   "label": "Automate Appointment Invoicing"
-  },
-  {
-   "default": "0",
-   "fieldname": "send_registration_msg",
-   "fieldtype": "Check",
-   "label": "Patient Registration"
-  },
-  {
-   "default": "Hello {{doc.patient}}, Thank you for registering with  {{doc.company}}. Your ID is {{doc.name}} . Please note this ID for future reference. \nThank You!",
-   "depends_on": "send_registration_msg",
-   "fieldname": "registration_msg",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Registration Message"
-  },
-  {
-   "default": "0",
-   "fieldname": "send_appointment_confirmation",
-   "fieldtype": "Check",
-   "label": "Appointment Confirmation"
-  },
-  {
-   "default": "Hello {{doc.patient}}, You have scheduled an appointment with {{doc.practitioner}} on {{doc.appointment_datetime}} at  {{doc.company}}.\nThank you, Good day!",
-   "depends_on": "send_appointment_confirmation",
-   "fieldname": "appointment_confirmation_msg",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Confirmation Message"
-  },
-  {
-   "default": "0",
-   "depends_on": "send_appointment_confirmation",
-   "description": "Do not confirm if appointment is created for the same day",
-   "fieldname": "avoid_confirmation",
-   "fieldtype": "Check",
-   "label": "Avoid Confirmation"
-  },
-  {
-   "default": "0",
-   "fieldname": "send_appointment_reminder",
-   "fieldtype": "Check",
-   "label": "Appointment Reminder"
-  },
-  {
-   "default": "Hello {{doc.patient}}, You have an appointment with {{doc.practitioner}} by {{doc.appointment_datetime}} at  {{doc.company}}.\nThank you, Good day!\n",
-   "depends_on": "send_appointment_reminder",
-   "fieldname": "appointment_reminder_msg",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Reminder Message"
-  },
-  {
-   "depends_on": "send_appointment_reminder",
-   "fieldname": "remind_before",
-   "fieldtype": "Time",
-   "label": "Remind Before"
-  },
-  {
-   "depends_on": "eval:doc.enable_free_follow_ups == 1",
-   "description": "The number of free follow ups (Patient Encounters in valid days) allowed",
-   "fieldname": "max_visits",
-   "fieldtype": "Int",
-   "label": "Number of Patient Encounters in Valid Days",
-   "mandatory_depends_on": "eval:doc.enable_free_follow_ups == 1"
-  },
-  {
-   "default": "0",
-   "fieldname": "enable_free_follow_ups",
-   "fieldtype": "Check",
-   "label": "Enable Free Follow-ups"
-  },
-  {
-   "fieldname": "inpatient_settings_section",
-   "fieldtype": "Section Break",
-   "label": "Inpatient Settings"
-  },
-  {
-   "default": "0",
-   "fieldname": "allow_discharge_despite_unbilled_services",
-   "fieldtype": "Check",
-   "label": "Allow Discharge Despite Unbilled Healthcare Services"
-  },
-  {
-   "default": "0",
-   "fieldname": "do_not_bill_inpatient_encounters",
-   "fieldtype": "Check",
-   "label": "Do Not Bill Patient Encounters for Inpatients"
-  }
- ],
- "issingle": 1,
- "links": [],
- "modified": "2021-01-13 09:04:35.877700",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Healthcare Settings",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "print": 1,
-   "read": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py
deleted file mode 100644
index 9ab8881..0000000
--- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-import json
-
-import frappe
-from frappe import _
-from frappe.core.doctype.sms_settings.sms_settings import send_sms
-from frappe.model.document import Document
-
-
-class HealthcareSettings(Document):
-	def validate(self):
-		for key in ['collect_registration_fee', 'link_customer_to_patient', 'patient_name_by',
-		'lab_test_approval_required', 'create_sample_collection_for_lab_test', 'default_medical_code_standard']:
-			frappe.db.set_default(key, self.get(key, ""))
-
-		if self.collect_registration_fee:
-			if self.registration_fee <= 0:
-				frappe.throw(_('Registration Fee cannot be negative or zero'))
-
-		if self.inpatient_visit_charge_item:
-			validate_service_item(self.inpatient_visit_charge_item)
-		if self.op_consulting_charge_item:
-			validate_service_item(self.op_consulting_charge_item)
-		if self.clinical_procedure_consumable_item:
-			validate_service_item(self.clinical_procedure_consumable_item)
-
-
-def validate_service_item(item):
-	if frappe.db.get_value('Item', item, 'is_stock_item'):
-		frappe.throw(_('Configure a service Item for {0}').format(item))
-
-@frappe.whitelist()
-def get_sms_text(doc):
-	sms_text = {}
-	doc = frappe.get_doc('Lab Test', doc)
-	context = {'doc': doc, 'alert': doc, 'comments': None}
-
-	emailed = frappe.db.get_value('Healthcare Settings', None, 'sms_emailed')
-	sms_text['emailed'] = frappe.render_template(emailed, context)
-
-	printed = frappe.db.get_value('Healthcare Settings', None, 'sms_printed')
-	sms_text['printed'] = frappe.render_template(printed, context)
-
-	return sms_text
-
-def send_registration_sms(doc):
-	if frappe.db.get_single_value('Healthcare Settings', 'send_registration_msg'):
-		if doc.mobile:
-			context = {'doc': doc, 'alert': doc, 'comments': None}
-			if doc.get('_comments'):
-				context['comments'] = json.loads(doc.get('_comments'))
-			messages = frappe.db.get_single_value('Healthcare Settings', 'registration_msg')
-			messages = frappe.render_template(messages, context)
-			number = [doc.mobile]
-			send_sms(number,messages)
-		else:
-			frappe.msgprint(doc.name + ' has no mobile number to send registration SMS', alert=True)
-
-def get_receivable_account(company):
-	receivable_account = get_account(None, 'receivable_account', 'Healthcare Settings', company)
-	if receivable_account:
-		return receivable_account
-
-	return frappe.get_cached_value('Company', company, 'default_receivable_account')
-
-def get_income_account(practitioner, company):
-	# check income account in Healthcare Practitioner
-	if practitioner:
-		income_account = get_account('Healthcare Practitioner', None, practitioner, company)
-		if income_account:
-			return income_account
-
-	# else check income account in Healthcare Settings
-	income_account = get_account(None, 'income_account', 'Healthcare Settings', company)
-	if income_account:
-		return income_account
-
-	# else return default income account of company
-	return frappe.get_cached_value('Company', company, 'default_income_account')
-
-def get_account(parent_type, parent_field, parent, company):
-	if parent_type:
-		return frappe.db.get_value('Party Account',
-			{'parenttype': parent_type, 'parent': parent, 'company': company}, 'account')
-
-	if parent_field:
-		return frappe.db.get_value('Party Account',
-			{'parentfield': parent_field, 'parent': parent, 'company': company}, 'account')
diff --git a/erpnext/healthcare/doctype/healthcare_settings/test_healthcare_settings.py b/erpnext/healthcare/doctype/healthcare_settings/test_healthcare_settings.py
deleted file mode 100644
index af2f2b4..0000000
--- a/erpnext/healthcare/doctype/healthcare_settings/test_healthcare_settings.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-
-class TestHealthcareSettings(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/inpatient_medication_entry/__init__.py b/erpnext/healthcare/doctype/inpatient_medication_entry/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_entry/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.js b/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.js
deleted file mode 100644
index a7b06b1..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.js
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Inpatient Medication Entry', {
-	refresh: function(frm) {
-		// Ignore cancellation of doctype on cancel all
-		frm.ignore_doctypes_on_cancel_all = ['Stock Entry'];
-		frm.fields_dict['medication_orders'].grid.wrapper.find('.grid-add-row').hide();
-
-		frm.set_query('item_code', () => {
-			return {
-				filters: {
-					is_stock_item: 1
-				}
-			};
-		});
-
-		frm.set_query('drug_code', 'medication_orders', () => {
-			return {
-				filters: {
-					is_stock_item: 1
-				}
-			};
-		});
-
-		frm.set_query('warehouse', () => {
-			return {
-				filters: {
-					company: frm.doc.company
-				}
-			};
-		});
-
-		if (frm.doc.__islocal || frm.doc.docstatus !== 0 || !frm.doc.update_stock)
-			return;
-
-		frm.add_custom_button(__('Make Stock Entry'), function() {
-			frappe.call({
-				method: 'erpnext.healthcare.doctype.inpatient_medication_entry.inpatient_medication_entry.make_difference_stock_entry',
-				args: {	docname: frm.doc.name },
-				freeze: true,
-				callback: function(r) {
-					if (r.message) {
-						var doclist = frappe.model.sync(r.message);
-						frappe.set_route('Form', doclist[0].doctype, doclist[0].name);
-					} else {
-						frappe.msgprint({
-							title: __('No Drug Shortage'),
-							message: __('All the drugs are available with sufficient qty to process this Inpatient Medication Entry.'),
-							indicator: 'green'
-						});
-					}
-				}
-			});
-		});
-	},
-
-	patient: function(frm) {
-		if (frm.doc.patient)
-			frm.set_value('service_unit', '');
-	},
-
-	get_medication_orders: function(frm) {
-		frappe.call({
-			method: 'get_medication_orders',
-			doc: frm.doc,
-			freeze: true,
-			freeze_message: __('Fetching Pending Medication Orders'),
-			callback: function() {
-				refresh_field('medication_orders');
-			}
-		});
-	}
-});
diff --git a/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.json b/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.json
deleted file mode 100644
index b1a6ee4..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.json
+++ /dev/null
@@ -1,204 +0,0 @@
-{
- "actions": [],
- "autoname": "naming_series:",
- "creation": "2020-09-25 14:13:20.111906",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "naming_series",
-  "company",
-  "column_break_3",
-  "posting_date",
-  "status",
-  "filters_section",
-  "item_code",
-  "assigned_to_practitioner",
-  "patient",
-  "practitioner",
-  "service_unit",
-  "column_break_11",
-  "from_date",
-  "to_date",
-  "from_time",
-  "to_time",
-  "select_medication_orders_section",
-  "get_medication_orders",
-  "medication_orders",
-  "section_break_18",
-  "update_stock",
-  "warehouse",
-  "amended_from"
- ],
- "fields": [
-  {
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "label": "Naming Series",
-   "options": "HLC-IME-.YYYY.-"
-  },
-  {
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Company",
-   "options": "Company",
-   "reqd": 1
-  },
-  {
-   "fieldname": "column_break_3",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "posting_date",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Posting Date",
-   "reqd": 1
-  },
-  {
-   "fieldname": "status",
-   "fieldtype": "Select",
-   "label": "Status",
-   "options": "\nDraft\nSubmitted\nPending\nIn Process\nCompleted\nCancelled",
-   "read_only": 1
-  },
-  {
-   "collapsible": 1,
-   "collapsible_depends_on": "eval: doc.__islocal",
-   "fieldname": "filters_section",
-   "fieldtype": "Section Break",
-   "label": "Filters"
-  },
-  {
-   "fieldname": "item_code",
-   "fieldtype": "Link",
-   "label": "Item Code (Drug)",
-   "options": "Item"
-  },
-  {
-   "depends_on": "update_stock",
-   "description": "Warehouse from where medication stock should be consumed",
-   "fieldname": "warehouse",
-   "fieldtype": "Link",
-   "label": "Medication Warehouse",
-   "mandatory_depends_on": "update_stock",
-   "options": "Warehouse"
-  },
-  {
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "label": "Patient",
-   "options": "Patient"
-  },
-  {
-   "depends_on": "eval:!doc.patient",
-   "fieldname": "service_unit",
-   "fieldtype": "Link",
-   "label": "Healthcare Service Unit",
-   "options": "Healthcare Service Unit"
-  },
-  {
-   "fieldname": "column_break_11",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "from_date",
-   "fieldtype": "Date",
-   "label": "From Date"
-  },
-  {
-   "fieldname": "to_date",
-   "fieldtype": "Date",
-   "label": "To Date"
-  },
-  {
-   "fieldname": "amended_from",
-   "fieldtype": "Link",
-   "label": "Amended From",
-   "no_copy": 1,
-   "options": "Inpatient Medication Entry",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "practitioner",
-   "fieldtype": "Link",
-   "label": "Healthcare Practitioner",
-   "options": "Healthcare Practitioner"
-  },
-  {
-   "fieldname": "select_medication_orders_section",
-   "fieldtype": "Section Break",
-   "label": "Medication Orders"
-  },
-  {
-   "fieldname": "medication_orders",
-   "fieldtype": "Table",
-   "label": "Inpatient Medication Orders",
-   "options": "Inpatient Medication Entry Detail",
-   "reqd": 1
-  },
-  {
-   "depends_on": "eval:doc.docstatus!==1",
-   "fieldname": "get_medication_orders",
-   "fieldtype": "Button",
-   "label": "Get Pending Medication Orders",
-   "print_hide": 1
-  },
-  {
-   "fieldname": "assigned_to_practitioner",
-   "fieldtype": "Link",
-   "label": "Assigned To",
-   "options": "User"
-  },
-  {
-   "fieldname": "section_break_18",
-   "fieldtype": "Section Break",
-   "label": "Stock Details"
-  },
-  {
-   "default": "1",
-   "fieldname": "update_stock",
-   "fieldtype": "Check",
-   "label": "Update Stock"
-  },
-  {
-   "fieldname": "from_time",
-   "fieldtype": "Time",
-   "label": "From Time"
-  },
-  {
-   "fieldname": "to_time",
-   "fieldtype": "Time",
-   "label": "To Time"
-  }
- ],
- "index_web_pages_for_search": 1,
- "is_submittable": 1,
- "links": [],
- "modified": "2021-01-11 12:37:46.749659",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Inpatient Medication Entry",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  }
- ],
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.py b/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.py
deleted file mode 100644
index b28e37a..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.py
+++ /dev/null
@@ -1,324 +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
-from frappe.utils import flt, get_link_to_form
-
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_account
-from erpnext.stock.utils import get_latest_stock_qty
-
-
-class InpatientMedicationEntry(Document):
-	def validate(self):
-		self.validate_medication_orders()
-
-	@frappe.whitelist()
-	def get_medication_orders(self):
-		# pull inpatient medication orders based on selected filters
-		orders = get_pending_medication_orders(self)
-
-		if orders:
-			self.add_mo_to_table(orders)
-			return self
-		else:
-			self.set('medication_orders', [])
-			frappe.msgprint(_('No pending medication orders found for selected criteria'))
-
-	def add_mo_to_table(self, orders):
-		# Add medication orders in the child table
-		self.set('medication_orders', [])
-
-		for data in orders:
-			self.append('medication_orders', {
-				'patient': data.patient,
-				'patient_name': data.patient_name,
-				'inpatient_record': data.inpatient_record,
-				'service_unit': data.service_unit,
-				'datetime': "%s %s" % (data.date, data.time or "00:00:00"),
-				'drug_code': data.drug,
-				'drug_name': data.drug_name,
-				'dosage': data.dosage,
-				'dosage_form': data.dosage_form,
-				'against_imo': data.parent,
-				'against_imoe': data.name
-			})
-
-	def on_submit(self):
-		self.validate_medication_orders()
-		success_msg = ""
-		if self.update_stock:
-			stock_entry = self.process_stock()
-			success_msg += _('Stock Entry {0} created and ').format(
-				frappe.bold(get_link_to_form('Stock Entry', stock_entry)))
-
-		self.update_medication_orders()
-		success_msg += _('Inpatient Medication Orders updated successfully')
-		frappe.msgprint(success_msg, title=_('Success'), indicator='green')
-
-	def validate_medication_orders(self):
-		for entry in self.medication_orders:
-			docstatus, is_completed = frappe.db.get_value('Inpatient Medication Order Entry', entry.against_imoe,
-				['docstatus', 'is_completed'])
-
-			if docstatus == 2:
-				frappe.throw(_('Row {0}: Cannot create Inpatient Medication Entry against cancelled Inpatient Medication Order {1}').format(
-					entry.idx, get_link_to_form(entry.against_imo)))
-
-			if is_completed:
-				frappe.throw(_('Row {0}: This Medication Order is already marked as completed').format(
-					entry.idx))
-
-	def on_cancel(self):
-		self.cancel_stock_entries()
-		self.update_medication_orders(on_cancel=True)
-
-	def process_stock(self):
-		allow_negative_stock = frappe.db.get_single_value('Stock Settings', 'allow_negative_stock')
-		if not allow_negative_stock:
-			self.check_stock_qty()
-
-		return self.make_stock_entry()
-
-	def update_medication_orders(self, on_cancel=False):
-		orders, order_entry_map = self.get_order_entry_map()
-		# mark completion status
-		is_completed = 1
-		if on_cancel:
-			is_completed = 0
-
-		frappe.db.sql("""
-			UPDATE `tabInpatient Medication Order Entry`
-			SET is_completed = %(is_completed)s
-			WHERE name IN %(orders)s
-		""", {'orders': orders, 'is_completed': is_completed})
-
-		# update status and completed orders count
-		for order, count in order_entry_map.items():
-			medication_order = frappe.get_doc('Inpatient Medication Order', order)
-			completed_orders = flt(count)
-			current_value = frappe.db.get_value('Inpatient Medication Order', order, 'completed_orders')
-
-			if on_cancel:
-				completed_orders = flt(current_value) - flt(count)
-			else:
-				completed_orders = flt(current_value) + flt(count)
-
-			medication_order.db_set('completed_orders', completed_orders)
-			medication_order.set_status()
-
-	def get_order_entry_map(self):
-		# for marking order completion status
-		orders = []
-		# orders mapped
-		order_entry_map = dict()
-
-		for entry in self.medication_orders:
-			orders.append(entry.against_imoe)
-			parent = entry.against_imo
-			if not order_entry_map.get(parent):
-				order_entry_map[parent] = 0
-
-			order_entry_map[parent] += 1
-
-		return orders, order_entry_map
-
-	def check_stock_qty(self):
-		drug_shortage = get_drug_shortage_map(self.medication_orders, self.warehouse)
-
-		if drug_shortage:
-			message = _('Quantity not available for the following items in warehouse {0}. ').format(frappe.bold(self.warehouse))
-			message += _('Please enable Allow Negative Stock in Stock Settings or create Stock Entry to proceed.')
-
-			formatted_item_rows = ''
-
-			for drug, shortage_qty in drug_shortage.items():
-				item_link = get_link_to_form('Item', drug)
-				formatted_item_rows += """
-					<td>{0}</td>
-					<td>{1}</td>
-				</tr>""".format(item_link, frappe.bold(shortage_qty))
-
-			message += """
-				<table class='table'>
-					<thead>
-						<th>{0}</th>
-						<th>{1}</th>
-					</thead>
-					{2}
-				</table>
-			""".format(_('Drug Code'), _('Shortage Qty'), formatted_item_rows)
-
-			frappe.throw(message, title=_('Insufficient Stock'), is_minimizable=True, wide=True)
-
-	def make_stock_entry(self):
-		stock_entry = frappe.new_doc('Stock Entry')
-		stock_entry.purpose = 'Material Issue'
-		stock_entry.set_stock_entry_type()
-		stock_entry.from_warehouse = self.warehouse
-		stock_entry.company = self.company
-		stock_entry.inpatient_medication_entry = self.name
-		cost_center = frappe.get_cached_value('Company',  self.company,  'cost_center')
-		expense_account = get_account(None, 'expense_account', 'Healthcare Settings', self.company)
-
-		for entry in self.medication_orders:
-			se_child = stock_entry.append('items')
-			se_child.item_code = entry.drug_code
-			se_child.item_name = entry.drug_name
-			se_child.uom = frappe.db.get_value('Item', entry.drug_code, 'stock_uom')
-			se_child.stock_uom = se_child.uom
-			se_child.qty = flt(entry.dosage)
-			# in stock uom
-			se_child.conversion_factor = 1
-			se_child.cost_center = cost_center
-			se_child.expense_account = expense_account
-			# references
-			se_child.patient = entry.patient
-			se_child.inpatient_medication_entry_child = entry.name
-
-		stock_entry.submit()
-		return stock_entry.name
-
-	def cancel_stock_entries(self):
-		stock_entries = frappe.get_all('Stock Entry', {'inpatient_medication_entry': self.name})
-		for entry in stock_entries:
-			doc = frappe.get_doc('Stock Entry', entry.name)
-			doc.cancel()
-
-
-def get_pending_medication_orders(entry):
-	filters, values = get_filters(entry)
-	to_remove = []
-
-	data = frappe.db.sql("""
-		SELECT
-			ip.inpatient_record, ip.patient, ip.patient_name,
-			entry.name, entry.parent, entry.drug, entry.drug_name,
-			entry.dosage, entry.dosage_form, entry.date, entry.time, entry.instructions
-		FROM
-			`tabInpatient Medication Order` ip
-		INNER JOIN
-			`tabInpatient Medication Order Entry` entry
-		ON
-			ip.name = entry.parent
-		WHERE
-			ip.docstatus = 1 and
-			ip.company = %(company)s and
-			entry.is_completed = 0
-			{0}
-		ORDER BY
-			entry.date, entry.time
-		""".format(filters), values, as_dict=1)
-
-	for doc in data:
-		inpatient_record = doc.inpatient_record
-		if inpatient_record:
-			doc['service_unit'] = get_current_healthcare_service_unit(inpatient_record)
-
-		if entry.service_unit and doc.service_unit != entry.service_unit:
-			to_remove.append(doc)
-
-	for doc in to_remove:
-		data.remove(doc)
-
-	return data
-
-
-def get_filters(entry):
-	filters = ''
-	values = dict(company=entry.company)
-	if entry.from_date:
-		filters += ' and entry.date >= %(from_date)s'
-		values['from_date'] = entry.from_date
-
-	if entry.to_date:
-		filters += ' and entry.date <= %(to_date)s'
-		values['to_date'] = entry.to_date
-
-	if entry.from_time:
-		filters += ' and entry.time >= %(from_time)s'
-		values['from_time'] = entry.from_time
-
-	if entry.to_time:
-		filters += ' and entry.time <= %(to_time)s'
-		values['to_time'] = entry.to_time
-
-	if entry.patient:
-		filters += ' and ip.patient = %(patient)s'
-		values['patient'] = entry.patient
-
-	if entry.practitioner:
-		filters += ' and ip.practitioner = %(practitioner)s'
-		values['practitioner'] = entry.practitioner
-
-	if entry.item_code:
-		filters += ' and entry.drug = %(item_code)s'
-		values['item_code'] = entry.item_code
-
-	if entry.assigned_to_practitioner:
-		filters += ' and ip._assign LIKE %(assigned_to)s'
-		values['assigned_to'] = '%' + entry.assigned_to_practitioner + '%'
-
-	return filters, values
-
-
-def get_current_healthcare_service_unit(inpatient_record):
-	ip_record = frappe.get_doc('Inpatient Record', inpatient_record)
-	if ip_record.status in ['Admitted', 'Discharge Scheduled'] and ip_record.inpatient_occupancies:
-		return ip_record.inpatient_occupancies[-1].service_unit
-	return
-
-
-def get_drug_shortage_map(medication_orders, warehouse):
-	"""
-		Returns a dict like { drug_code: shortage_qty }
-	"""
-	drug_requirement = dict()
-	for d in medication_orders:
-		if not drug_requirement.get(d.drug_code):
-			drug_requirement[d.drug_code] = 0
-		drug_requirement[d.drug_code] += flt(d.dosage)
-
-	drug_shortage = dict()
-	for drug, required_qty in drug_requirement.items():
-		available_qty = get_latest_stock_qty(drug, warehouse)
-		if flt(required_qty) > flt(available_qty):
-			drug_shortage[drug] = flt(flt(required_qty) - flt(available_qty))
-
-	return drug_shortage
-
-
-@frappe.whitelist()
-def make_difference_stock_entry(docname):
-	doc = frappe.get_doc('Inpatient Medication Entry', docname)
-	drug_shortage = get_drug_shortage_map(doc.medication_orders, doc.warehouse)
-
-	if not drug_shortage:
-		return None
-
-	stock_entry = frappe.new_doc('Stock Entry')
-	stock_entry.purpose = 'Material Transfer'
-	stock_entry.set_stock_entry_type()
-	stock_entry.to_warehouse = doc.warehouse
-	stock_entry.company = doc.company
-	cost_center = frappe.get_cached_value('Company',  doc.company,  'cost_center')
-	expense_account = get_account(None, 'expense_account', 'Healthcare Settings', doc.company)
-
-	for drug, shortage_qty in drug_shortage.items():
-		se_child = stock_entry.append('items')
-		se_child.item_code = drug
-		se_child.item_name = frappe.db.get_value('Item', drug, 'stock_uom')
-		se_child.uom = frappe.db.get_value('Item', drug, 'stock_uom')
-		se_child.stock_uom = se_child.uom
-		se_child.qty = flt(shortage_qty)
-		se_child.t_warehouse = doc.warehouse
-		# in stock uom
-		se_child.conversion_factor = 1
-		se_child.cost_center = cost_center
-		se_child.expense_account = expense_account
-
-	return stock_entry
diff --git a/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry_dashboard.py b/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry_dashboard.py
deleted file mode 100644
index ca9364d..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry_dashboard.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from __future__ import unicode_literals
-
-from frappe import _
-
-
-def get_data():
-	return {
-		'fieldname': 'against_imoe',
-		'internal_links': {
-			'Inpatient Medication Order': ['medication_orders', 'against_imo']
-		},
-		'transactions': [
-			{
-				'label': _('Reference'),
-				'items': ['Inpatient Medication Order']
-			}
-		]
-	}
diff --git a/erpnext/healthcare/doctype/inpatient_medication_entry/test_inpatient_medication_entry.py b/erpnext/healthcare/doctype/inpatient_medication_entry/test_inpatient_medication_entry.py
deleted file mode 100644
index dde7739..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_entry/test_inpatient_medication_entry.py
+++ /dev/null
@@ -1,174 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-import frappe
-from frappe.utils import add_days, getdate, now_datetime
-
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_account
-from erpnext.healthcare.doctype.inpatient_medication_entry.inpatient_medication_entry import (
-	get_drug_shortage_map,
-	make_difference_stock_entry,
-)
-from erpnext.healthcare.doctype.inpatient_medication_order.test_inpatient_medication_order import (
-	create_ipme,
-	create_ipmo,
-)
-from erpnext.healthcare.doctype.inpatient_record.inpatient_record import (
-	admit_patient,
-	discharge_patient,
-	schedule_discharge,
-)
-from erpnext.healthcare.doctype.inpatient_record.test_inpatient_record import (
-	create_inpatient,
-	create_patient,
-	get_healthcare_service_unit,
-	mark_invoiced_inpatient_occupancy,
-)
-
-
-class TestInpatientMedicationEntry(unittest.TestCase):
-	def setUp(self):
-		frappe.db.sql("""delete from `tabInpatient Record`""")
-		frappe.db.sql("""delete from `tabInpatient Medication Order`""")
-		frappe.db.sql("""delete from `tabInpatient Medication Entry`""")
-		self.patient = create_patient()
-
-		# Admit
-		ip_record = create_inpatient(self.patient)
-		ip_record.expected_length_of_stay = 0
-		ip_record.save()
-		ip_record.reload()
-		service_unit = get_healthcare_service_unit()
-		admit_patient(ip_record, service_unit, now_datetime())
-		self.ip_record = ip_record
-
-	def test_filters_for_fetching_pending_mo(self):
-		ipmo = create_ipmo(self.patient)
-		ipmo.submit()
-		ipmo.reload()
-
-		date = add_days(getdate(), -1)
-		filters = frappe._dict(
-			from_date=date,
-			to_date=date,
-			from_time='',
-			to_time='',
-			item_code='Dextromethorphan',
-			patient=self.patient
-		)
-
-		ipme = create_ipme(filters, update_stock=0)
-
-		# 3 dosages per day
-		self.assertEqual(len(ipme.medication_orders), 3)
-		self.assertEqual(getdate(ipme.medication_orders[0].datetime), date)
-
-	def test_ipme_with_stock_update(self):
-		ipmo = create_ipmo(self.patient)
-		ipmo.submit()
-		ipmo.reload()
-
-		date = add_days(getdate(), -1)
-		filters = frappe._dict(
-			from_date=date,
-			to_date=date,
-			from_time='',
-			to_time='',
-			item_code='Dextromethorphan',
-			patient=self.patient
-		)
-
-		make_stock_entry()
-		ipme = create_ipme(filters, update_stock=1)
-		ipme.submit()
-		ipme.reload()
-
-		# test order completed
-		is_order_completed = frappe.db.get_value('Inpatient Medication Order Entry',
-			ipme.medication_orders[0].against_imoe, 'is_completed')
-		self.assertEqual(is_order_completed, 1)
-
-		# test stock entry
-		stock_entry = frappe.db.exists('Stock Entry', {'inpatient_medication_entry': ipme.name})
-		self.assertTrue(stock_entry)
-
-		# check references
-		stock_entry = frappe.get_doc('Stock Entry', stock_entry)
-		self.assertEqual(stock_entry.items[0].patient, self.patient)
-		self.assertEqual(stock_entry.items[0].inpatient_medication_entry_child, ipme.medication_orders[0].name)
-
-	def test_drug_shortage_stock_entry(self):
-		ipmo = create_ipmo(self.patient)
-		ipmo.submit()
-		ipmo.reload()
-
-		date = add_days(getdate(), -1)
-		filters = frappe._dict(
-			from_date=date,
-			to_date=date,
-			from_time='',
-			to_time='',
-			item_code='Dextromethorphan',
-			patient=self.patient
-		)
-
-		# check drug shortage
-		ipme = create_ipme(filters, update_stock=1)
-		ipme.warehouse = 'Finished Goods - _TC'
-		ipme.save()
-		drug_shortage = get_drug_shortage_map(ipme.medication_orders, ipme.warehouse)
-		self.assertEqual(drug_shortage.get('Dextromethorphan'), 3)
-
-		# check material transfer for drug shortage
-		make_stock_entry()
-		stock_entry = make_difference_stock_entry(ipme.name)
-		self.assertEqual(stock_entry.items[0].item_code, 'Dextromethorphan')
-		self.assertEqual(stock_entry.items[0].qty, 3)
-		stock_entry.from_warehouse = 'Stores - _TC'
-		stock_entry.submit()
-
-		ipme.reload()
-		ipme.submit()
-
-	def tearDown(self):
-		# cleanup - Discharge
-		schedule_discharge(frappe.as_json({'patient': self.patient}))
-		self.ip_record.reload()
-		mark_invoiced_inpatient_occupancy(self.ip_record)
-
-		self.ip_record.reload()
-		discharge_patient(self.ip_record)
-
-		for entry in frappe.get_all('Inpatient Medication Entry'):
-			doc = frappe.get_doc('Inpatient Medication Entry', entry.name)
-			doc.cancel()
-
-		for entry in frappe.get_all('Inpatient Medication Order'):
-			doc = frappe.get_doc('Inpatient Medication Order', entry.name)
-			doc.cancel()
-
-def make_stock_entry(warehouse=None):
-	frappe.db.set_value('Company', '_Test Company', {
-		'stock_adjustment_account': 'Stock Adjustment - _TC',
-		'default_inventory_account': 'Stock In Hand - _TC'
-	})
-	stock_entry = frappe.new_doc('Stock Entry')
-	stock_entry.stock_entry_type = 'Material Receipt'
-	stock_entry.company = '_Test Company'
-	stock_entry.to_warehouse = warehouse or 'Stores - _TC'
-	expense_account = get_account(None, 'expense_account', 'Healthcare Settings', '_Test Company')
-	se_child = stock_entry.append('items')
-	se_child.item_code = 'Dextromethorphan'
-	se_child.item_name = 'Dextromethorphan'
-	se_child.uom = 'Nos'
-	se_child.stock_uom = 'Nos'
-	se_child.qty = 6
-	se_child.t_warehouse = 'Stores - _TC'
-	# in stock uom
-	se_child.conversion_factor = 1.0
-	se_child.expense_account = expense_account
-	stock_entry.submit()
diff --git a/erpnext/healthcare/doctype/inpatient_medication_entry_detail/__init__.py b/erpnext/healthcare/doctype/inpatient_medication_entry_detail/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_entry_detail/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/inpatient_medication_entry_detail/inpatient_medication_entry_detail.json b/erpnext/healthcare/doctype/inpatient_medication_entry_detail/inpatient_medication_entry_detail.json
deleted file mode 100644
index e3d7212..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_entry_detail/inpatient_medication_entry_detail.json
+++ /dev/null
@@ -1,163 +0,0 @@
-{
- "actions": [],
- "creation": "2020-09-25 14:56:32.636569",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "patient",
-  "patient_name",
-  "inpatient_record",
-  "column_break_4",
-  "service_unit",
-  "datetime",
-  "medication_details_section",
-  "drug_code",
-  "drug_name",
-  "dosage",
-  "available_qty",
-  "dosage_form",
-  "column_break_10",
-  "instructions",
-  "references_section",
-  "against_imo",
-  "against_imoe"
- ],
- "fields": [
-  {
-   "columns": 2,
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Patient",
-   "options": "Patient",
-   "reqd": 1
-  },
-  {
-   "fetch_from": "patient.patient_name",
-   "fieldname": "patient_name",
-   "fieldtype": "Data",
-   "label": "Patient Name",
-   "read_only": 1
-  },
-  {
-   "columns": 2,
-   "fieldname": "drug_code",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Drug Code",
-   "options": "Item",
-   "reqd": 1
-  },
-  {
-   "fetch_from": "drug_code.item_name",
-   "fieldname": "drug_name",
-   "fieldtype": "Data",
-   "label": "Drug Name",
-   "read_only": 1
-  },
-  {
-   "columns": 1,
-   "fieldname": "dosage",
-   "fieldtype": "Float",
-   "in_list_view": 1,
-   "label": "Dosage",
-   "reqd": 1
-  },
-  {
-   "fieldname": "dosage_form",
-   "fieldtype": "Link",
-   "label": "Dosage Form",
-   "options": "Dosage Form"
-  },
-  {
-   "fetch_from": "patient.inpatient_record",
-   "fieldname": "inpatient_record",
-   "fieldtype": "Link",
-   "label": "Inpatient Record",
-   "options": "Inpatient Record",
-   "read_only": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "references_section",
-   "fieldtype": "Section Break",
-   "label": "References"
-  },
-  {
-   "fieldname": "column_break_4",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "medication_details_section",
-   "fieldtype": "Section Break",
-   "label": "Medication Details"
-  },
-  {
-   "fieldname": "column_break_10",
-   "fieldtype": "Column Break"
-  },
-  {
-   "columns": 3,
-   "fieldname": "datetime",
-   "fieldtype": "Datetime",
-   "in_list_view": 1,
-   "label": "Datetime",
-   "reqd": 1
-  },
-  {
-   "fieldname": "instructions",
-   "fieldtype": "Small Text",
-   "label": "Instructions"
-  },
-  {
-   "columns": 2,
-   "fieldname": "service_unit",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Service Unit",
-   "options": "Healthcare Service Unit",
-   "read_only": 1,
-   "reqd": 1
-  },
-  {
-   "fieldname": "against_imo",
-   "fieldtype": "Link",
-   "label": "Against Inpatient Medication Order",
-   "no_copy": 1,
-   "options": "Inpatient Medication Order",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "against_imoe",
-   "fieldtype": "Data",
-   "label": "Against Inpatient Medication Order Entry",
-   "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "available_qty",
-   "fieldtype": "Float",
-   "hidden": 1,
-   "label": "Available Qty",
-   "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1
-  }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2020-09-30 14:48:23.648223",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Inpatient Medication Entry Detail",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/inpatient_medication_entry_detail/inpatient_medication_entry_detail.py b/erpnext/healthcare/doctype/inpatient_medication_entry_detail/inpatient_medication_entry_detail.py
deleted file mode 100644
index 9173431..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_entry_detail/inpatient_medication_entry_detail.py
+++ /dev/null
@@ -1,12 +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 InpatientMedicationEntryDetail(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/inpatient_medication_order/__init__.py b/erpnext/healthcare/doctype/inpatient_medication_order/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_order/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order.js b/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order.js
deleted file mode 100644
index 690e2e7..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order.js
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Inpatient Medication Order', {
-	refresh: function(frm) {
-		if (frm.doc.docstatus === 1) {
-			frm.trigger("show_progress");
-		}
-
-		frm.events.show_medication_order_button(frm);
-
-		frm.set_query('patient', () => {
-			return {
-				filters: {
-					'inpatient_record': ['!=', ''],
-					'inpatient_status': 'Admitted'
-				}
-			};
-		});
-	},
-
-	show_medication_order_button: function(frm) {
-		frm.fields_dict['medication_orders'].grid.wrapper.find('.grid-add-row').hide();
-		frm.fields_dict['medication_orders'].grid.add_custom_button(__('Add Medication Orders'), () => {
-			let d = new frappe.ui.Dialog({
-				title: __('Add Medication Orders'),
-				fields: [
-					{
-						fieldname: 'drug_code',
-						label: __('Drug'),
-						fieldtype: 'Link',
-						options: 'Item',
-						reqd: 1,
-						"get_query": function () {
-							return {
-								filters: {'is_stock_item': 1}
-							};
-						}
-					},
-					{
-						fieldname: 'dosage',
-						label: __('Dosage'),
-						fieldtype: 'Link',
-						options: 'Prescription Dosage',
-						reqd: 1
-					},
-					{
-						fieldname: 'period',
-						label: __('Period'),
-						fieldtype: 'Link',
-						options: 'Prescription Duration',
-						reqd: 1
-					},
-					{
-						fieldname: 'dosage_form',
-						label: __('Dosage Form'),
-						fieldtype: 'Link',
-						options: 'Dosage Form',
-						reqd: 1
-					}
-				],
-				primary_action_label: __('Add'),
-				primary_action: () => {
-					let values = d.get_values();
-					if (values) {
-						frm.call({
-							doc: frm.doc,
-							method: 'add_order_entries',
-							args: {
-								order: values
-							},
-							freeze: true,
-							freeze_message: __('Adding Order Entries'),
-							callback: function() {
-								frm.refresh_field('medication_orders');
-							}
-						});
-					}
-				},
-			});
-			d.show();
-		});
-	},
-
-	show_progress: function(frm) {
-		let bars = [];
-		let message = '';
-
-		// completed sessions
-		let title = __('{0} medication orders completed', [frm.doc.completed_orders]);
-		if (frm.doc.completed_orders === 1) {
-			title = __('{0} medication order completed', [frm.doc.completed_orders]);
-		}
-		title += __(' out of {0}', [frm.doc.total_orders]);
-
-		bars.push({
-			'title': title,
-			'width': (frm.doc.completed_orders / frm.doc.total_orders * 100) + '%',
-			'progress_class': 'progress-bar-success'
-		});
-		if (bars[0].width == '0%') {
-			bars[0].width = '0.5%';
-		}
-		message = title;
-		frm.dashboard.add_progress(__('Status'), bars, message);
-	}
-});
diff --git a/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order.json b/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order.json
deleted file mode 100644
index e31d2e3..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order.json
+++ /dev/null
@@ -1,196 +0,0 @@
-{
- "actions": [],
- "autoname": "naming_series:",
- "creation": "2020-09-14 18:33:56.715736",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "patient_details_section",
-  "naming_series",
-  "patient_encounter",
-  "patient",
-  "patient_name",
-  "patient_age",
-  "inpatient_record",
-  "column_break_6",
-  "company",
-  "status",
-  "practitioner",
-  "start_date",
-  "end_date",
-  "medication_orders_section",
-  "medication_orders",
-  "section_break_16",
-  "total_orders",
-  "column_break_18",
-  "completed_orders",
-  "amended_from"
- ],
- "fields": [
-  {
-   "fieldname": "patient_details_section",
-   "fieldtype": "Section Break",
-   "label": "Patient Details"
-  },
-  {
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "label": "Naming Series",
-   "options": "HLC-IMO-.YYYY.-"
-  },
-  {
-   "fieldname": "patient_encounter",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Patient Encounter",
-   "options": "Patient Encounter"
-  },
-  {
-   "fetch_from": "patient_encounter.patient",
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "label": "Patient",
-   "options": "Patient",
-   "read_only_depends_on": "patient_encounter",
-   "reqd": 1
-  },
-  {
-   "fetch_from": "patient.patient_name",
-   "fieldname": "patient_name",
-   "fieldtype": "Data",
-   "label": "Patient Name",
-   "read_only": 1
-  },
-  {
-   "fieldname": "patient_age",
-   "fieldtype": "Data",
-   "label": "Patient Age",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_6",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fetch_from": "patient.inpatient_record",
-   "fieldname": "inpatient_record",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Inpatient Record",
-   "options": "Inpatient Record",
-   "read_only": 1,
-   "reqd": 1
-  },
-  {
-   "fetch_from": "patient_encounter.practitioner",
-   "fieldname": "practitioner",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Healthcare Practitioner",
-   "options": "Healthcare Practitioner",
-   "read_only_depends_on": "patient_encounter"
-  },
-  {
-   "fieldname": "start_date",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "label": "Start Date",
-   "reqd": 1
-  },
-  {
-   "fieldname": "end_date",
-   "fieldtype": "Date",
-   "label": "End Date",
-   "read_only": 1
-  },
-  {
-   "depends_on": "eval: doc.patient && doc.start_date",
-   "fieldname": "medication_orders_section",
-   "fieldtype": "Section Break",
-   "label": "Medication Orders"
-  },
-  {
-   "fieldname": "medication_orders",
-   "fieldtype": "Table",
-   "label": "Medication Orders",
-   "options": "Inpatient Medication Order Entry"
-  },
-  {
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "label": "Company",
-   "options": "Company",
-   "reqd": 1
-  },
-  {
-   "fieldname": "amended_from",
-   "fieldtype": "Link",
-   "label": "Amended From",
-   "no_copy": 1,
-   "options": "Inpatient Medication Order",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "status",
-   "fieldtype": "Select",
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Status",
-   "options": "\nDraft\nSubmitted\nPending\nIn Process\nCompleted\nCancelled",
-   "read_only": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "section_break_16",
-   "fieldtype": "Section Break",
-   "label": "Other Details"
-  },
-  {
-   "fieldname": "total_orders",
-   "fieldtype": "Float",
-   "label": "Total Orders",
-   "no_copy": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_18",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "completed_orders",
-   "fieldtype": "Float",
-   "label": "Completed Orders",
-   "no_copy": 1,
-   "read_only": 1
-  }
- ],
- "index_web_pages_for_search": 1,
- "is_submittable": 1,
- "links": [],
- "modified": "2020-09-30 21:53:27.128591",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Inpatient Medication Order",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  }
- ],
- "search_fields": "patient_encounter, patient",
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "patient",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order.py b/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order.py
deleted file mode 100644
index 2e6d732..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order.py
+++ /dev/null
@@ -1,78 +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
-from frappe.utils import cstr
-
-from erpnext.healthcare.doctype.patient_encounter.patient_encounter import get_prescription_dates
-
-
-class InpatientMedicationOrder(Document):
-	def validate(self):
-		self.validate_inpatient()
-		self.validate_duplicate()
-		self.set_total_orders()
-		self.set_status()
-
-	def on_submit(self):
-		self.validate_inpatient()
-		self.set_status()
-
-	def on_cancel(self):
-		self.set_status()
-
-	def validate_inpatient(self):
-		if not self.inpatient_record:
-			frappe.throw(_('No Inpatient Record found against patient {0}').format(self.patient))
-
-	def validate_duplicate(self):
-		existing_mo = frappe.db.exists('Inpatient Medication Order', {
-			'patient_encounter': self.patient_encounter,
-			'docstatus': ('!=', 2),
-			'name': ('!=', self.name)
-		})
-		if existing_mo:
-			frappe.throw(_('An Inpatient Medication Order {0} against Patient Encounter {1} already exists.').format(
-				existing_mo, self.patient_encounter), frappe.DuplicateEntryError)
-
-	def set_total_orders(self):
-		self.db_set('total_orders', len(self.medication_orders))
-
-	def set_status(self):
-		status = {
-			"0": "Draft",
-			"1": "Submitted",
-			"2": "Cancelled"
-		}[cstr(self.docstatus or 0)]
-
-		if self.docstatus == 1:
-			if not self.completed_orders:
-				status = 'Pending'
-			elif self.completed_orders < self.total_orders:
-				status = 'In Process'
-			else:
-				status = 'Completed'
-
-		self.db_set('status', status)
-
-	@frappe.whitelist()
-	def add_order_entries(self, order):
-		if order.get('drug_code'):
-			dosage = frappe.get_doc('Prescription Dosage', order.get('dosage'))
-			dates = get_prescription_dates(order.get('period'), self.start_date)
-			for date in dates:
-				for dose in dosage.dosage_strength:
-					entry = self.append('medication_orders')
-					entry.drug = order.get('drug_code')
-					entry.drug_name = frappe.db.get_value('Item', order.get('drug_code'), 'item_name')
-					entry.dosage = dose.strength
-					entry.dosage_form = order.get('dosage_form')
-					entry.date = date
-					entry.time = dose.strength_time
-			self.end_date = dates[-1]
-		return
diff --git a/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order_list.js b/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order_list.js
deleted file mode 100644
index 1c31876..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order_list.js
+++ /dev/null
@@ -1,16 +0,0 @@
-frappe.listview_settings['Inpatient Medication Order'] = {
-	add_fields: ["status"],
-	filters: [["status", "!=", "Cancelled"]],
-	get_indicator: function(doc) {
-		if (doc.status === "Pending") {
-			return [__("Pending"), "orange", "status,=,Pending"];
-
-		} else if (doc.status === "In Process") {
-			return [__("In Process"), "blue", "status,=,In Process"];
-
-		} else if (doc.status === "Completed") {
-			return [__("Completed"), "green", "status,=,Completed"];
-
-		}
-	}
-};
diff --git a/erpnext/healthcare/doctype/inpatient_medication_order/test_inpatient_medication_order.py b/erpnext/healthcare/doctype/inpatient_medication_order/test_inpatient_medication_order.py
deleted file mode 100644
index 477f8c9..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_order/test_inpatient_medication_order.py
+++ /dev/null
@@ -1,154 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-import frappe
-from frappe.utils import add_days, getdate, now_datetime
-
-from erpnext.healthcare.doctype.inpatient_record.inpatient_record import (
-	admit_patient,
-	discharge_patient,
-	schedule_discharge,
-)
-from erpnext.healthcare.doctype.inpatient_record.test_inpatient_record import (
-	create_inpatient,
-	create_patient,
-	get_healthcare_service_unit,
-	mark_invoiced_inpatient_occupancy,
-)
-
-
-class TestInpatientMedicationOrder(unittest.TestCase):
-	def setUp(self):
-		frappe.db.sql("""delete from `tabInpatient Record`""")
-		self.patient = create_patient()
-
-		# Admit
-		ip_record = create_inpatient(self.patient)
-		ip_record.expected_length_of_stay = 0
-		ip_record.save()
-		ip_record.reload()
-		service_unit = get_healthcare_service_unit()
-		admit_patient(ip_record, service_unit, now_datetime())
-		self.ip_record = ip_record
-
-	def test_order_creation(self):
-		ipmo = create_ipmo(self.patient)
-		ipmo.submit()
-		ipmo.reload()
-
-		# 3 dosages per day for 2 days
-		self.assertEqual(len(ipmo.medication_orders), 6)
-		self.assertEqual(ipmo.medication_orders[0].date, add_days(getdate(), -1))
-
-		prescription_dosage = frappe.get_doc('Prescription Dosage', '1-1-1')
-		for i in range(len(prescription_dosage.dosage_strength)):
-			self.assertEqual(ipmo.medication_orders[i].time, prescription_dosage.dosage_strength[i].strength_time)
-
-		self.assertEqual(ipmo.medication_orders[3].date, getdate())
-
-	def test_inpatient_validation(self):
-		# Discharge
-		schedule_discharge(frappe.as_json({'patient': self.patient}))
-
-		self.ip_record.reload()
-		mark_invoiced_inpatient_occupancy(self.ip_record)
-
-		self.ip_record.reload()
-		discharge_patient(self.ip_record)
-
-		ipmo = create_ipmo(self.patient)
-		# inpatient validation
-		self.assertRaises(frappe.ValidationError, ipmo.insert)
-
-	def test_status(self):
-		ipmo = create_ipmo(self.patient)
-		ipmo.submit()
-		ipmo.reload()
-
-		self.assertEqual(ipmo.status, 'Pending')
-
-		filters = frappe._dict(from_date=add_days(getdate(), -1), to_date=add_days(getdate(), -1), from_time='', to_time='')
-		ipme = create_ipme(filters)
-		ipme.submit()
-		ipmo.reload()
-		self.assertEqual(ipmo.status, 'In Process')
-
-		filters = frappe._dict(from_date=getdate(), to_date=getdate(), from_time='', to_time='')
-		ipme = create_ipme(filters)
-		ipme.submit()
-		ipmo.reload()
-		self.assertEqual(ipmo.status, 'Completed')
-
-	def tearDown(self):
-		if frappe.db.get_value('Patient', self.patient, 'inpatient_record'):
-			# cleanup - Discharge
-			schedule_discharge(frappe.as_json({'patient': self.patient}))
-			self.ip_record.reload()
-			mark_invoiced_inpatient_occupancy(self.ip_record)
-
-			self.ip_record.reload()
-			discharge_patient(self.ip_record)
-
-		for doctype in ["Inpatient Medication Entry", "Inpatient Medication Order"]:
-			frappe.db.sql("delete from `tab{doctype}`".format(doctype=doctype))
-
-def create_dosage_form():
-	if not frappe.db.exists('Dosage Form', 'Tablet'):
-		frappe.get_doc({
-			'doctype': 'Dosage Form',
-			'dosage_form': 'Tablet'
-		}).insert()
-
-def create_drug(item=None):
-	if not item:
-		item = 'Dextromethorphan'
-	drug = frappe.db.exists('Item', {'item_code': 'Dextromethorphan'})
-	if not drug:
-		drug = frappe.get_doc({
-			'doctype': 'Item',
-			'item_code': 'Dextromethorphan',
-			'item_name': 'Dextromethorphan',
-			'item_group': 'Products',
-			'stock_uom': 'Nos',
-			'is_stock_item': 1,
-			'valuation_rate': 50,
-			'opening_stock': 20
-		}).insert()
-
-def get_orders():
-	create_dosage_form()
-	create_drug()
-	return {
-		'drug_code': 'Dextromethorphan',
-		'drug_name': 'Dextromethorphan',
-		'dosage': '1-1-1',
-		'dosage_form': 'Tablet',
-		'period': '2 Day'
-	}
-
-def create_ipmo(patient):
-	orders = get_orders()
-	ipmo = frappe.new_doc('Inpatient Medication Order')
-	ipmo.patient = patient
-	ipmo.company = '_Test Company'
-	ipmo.start_date = add_days(getdate(), -1)
-	ipmo.add_order_entries(orders)
-
-	return ipmo
-
-def create_ipme(filters, update_stock=0):
-	ipme = frappe.new_doc('Inpatient Medication Entry')
-	ipme.company = '_Test Company'
-	ipme.posting_date = getdate()
-	ipme.update_stock = update_stock
-	if update_stock:
-		ipme.warehouse = 'Stores - _TC'
-	for key, value in filters.items():
-		ipme.set(key, value)
-	ipme = ipme.get_medication_orders()
-
-	return ipme
diff --git a/erpnext/healthcare/doctype/inpatient_medication_order_entry/__init__.py b/erpnext/healthcare/doctype/inpatient_medication_order_entry/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_order_entry/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/inpatient_medication_order_entry/inpatient_medication_order_entry.json b/erpnext/healthcare/doctype/inpatient_medication_order_entry/inpatient_medication_order_entry.json
deleted file mode 100644
index 72999a9..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_order_entry/inpatient_medication_order_entry.json
+++ /dev/null
@@ -1,94 +0,0 @@
-{
- "actions": [],
- "creation": "2020-09-14 21:51:30.259164",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "drug",
-  "drug_name",
-  "dosage",
-  "dosage_form",
-  "instructions",
-  "column_break_4",
-  "date",
-  "time",
-  "is_completed"
- ],
- "fields": [
-  {
-   "fieldname": "drug",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Drug",
-   "options": "Item",
-   "reqd": 1
-  },
-  {
-   "fetch_from": "drug.item_name",
-   "fieldname": "drug_name",
-   "fieldtype": "Data",
-   "label": "Drug Name",
-   "read_only": 1
-  },
-  {
-   "fieldname": "dosage",
-   "fieldtype": "Float",
-   "in_list_view": 1,
-   "label": "Dosage",
-   "reqd": 1
-  },
-  {
-   "fieldname": "dosage_form",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Dosage Form",
-   "options": "Dosage Form",
-   "reqd": 1
-  },
-  {
-   "fieldname": "column_break_4",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "date",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "label": "Date",
-   "reqd": 1
-  },
-  {
-   "fieldname": "time",
-   "fieldtype": "Time",
-   "in_list_view": 1,
-   "label": "Time",
-   "reqd": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "is_completed",
-   "fieldtype": "Check",
-   "label": "Is Order Completed",
-   "no_copy": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "instructions",
-   "fieldtype": "Small Text",
-   "label": "Instructions"
-  }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2020-09-30 14:03:26.755925",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Inpatient Medication Order Entry",
- "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/healthcare/doctype/inpatient_medication_order_entry/inpatient_medication_order_entry.py b/erpnext/healthcare/doctype/inpatient_medication_order_entry/inpatient_medication_order_entry.py
deleted file mode 100644
index 15800ad..0000000
--- a/erpnext/healthcare/doctype/inpatient_medication_order_entry/inpatient_medication_order_entry.py
+++ /dev/null
@@ -1,12 +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 InpatientMedicationOrderEntry(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/inpatient_occupancy/__init__.py b/erpnext/healthcare/doctype/inpatient_occupancy/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/inpatient_occupancy/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json b/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json
deleted file mode 100644
index 3fa98b6..0000000
--- a/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json
+++ /dev/null
@@ -1,64 +0,0 @@
-{
- "actions": [],
- "creation": "2018-07-12 12:07:36.932333",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "service_unit",
-  "check_in",
-  "left",
-  "check_out",
-  "invoiced"
- ],
- "fields": [
-  {
-   "fieldname": "service_unit",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Healthcare Service Unit",
-   "options": "Healthcare Service Unit",
-   "reqd": 1
-  },
-  {
-   "fieldname": "check_in",
-   "fieldtype": "Datetime",
-   "in_list_view": 1,
-   "label": "Check In"
-  },
-  {
-   "default": "0",
-   "fieldname": "left",
-   "fieldtype": "Check",
-   "label": "Left",
-   "read_only": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "check_out",
-   "fieldtype": "Datetime",
-   "label": "Check Out"
-  },
-  {
-   "default": "0",
-   "fieldname": "invoiced",
-   "fieldtype": "Check",
-   "label": "Invoiced",
-   "read_only": 1
-  }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2021-03-18 15:08:54.634132",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Inpatient Occupancy",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.py b/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.py
deleted file mode 100644
index c8f3296..0000000
--- a/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class InpatientOccupancy(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/inpatient_record/__init__.py b/erpnext/healthcare/doctype/inpatient_record/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/inpatient_record/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js
deleted file mode 100644
index 60f0f9d..0000000
--- a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Inpatient Record', {
-	setup: function(frm) {
-		frm.get_field('drug_prescription').grid.editable_fields = [
-			{fieldname: 'drug_code', columns: 2},
-			{fieldname: 'drug_name', columns: 2},
-			{fieldname: 'dosage', columns: 2},
-			{fieldname: 'period', columns: 2}
-		];
-	},
-	refresh: function(frm) {
-		if (!frm.doc.__islocal && (frm.doc.status == 'Admission Scheduled' || frm.doc.status == 'Admitted')) {
-			frm.enable_save();
-		} else {
-			frm.disable_save();
-		}
-
-		if (!frm.doc.__islocal && frm.doc.status == 'Admission Scheduled') {
-			frm.add_custom_button(__('Admit'), function() {
-				admit_patient_dialog(frm);
-			} );
-		}
-
-		if (!frm.doc.__islocal && frm.doc.status == 'Discharge Scheduled') {
-			frm.add_custom_button(__('Discharge'), function() {
-				discharge_patient(frm);
-			} );
-		}
-		if (!frm.doc.__islocal && frm.doc.status != 'Admitted') {
-			frm.disable_save();
-			frm.set_df_property('btn_transfer', 'hidden', 1);
-		} else {
-			frm.set_df_property('btn_transfer', 'hidden', 0);
-		}
-	},
-	btn_transfer: function(frm) {
-		transfer_patient_dialog(frm);
-	}
-});
-
-let discharge_patient = function(frm) {
-	frappe.call({
-		doc: frm.doc,
-		method: 'discharge',
-		callback: function(data) {
-			if (!data.exc) {
-				frm.reload_doc();
-			}
-		},
-		freeze: true,
-		freeze_message: __('Processing Inpatient Discharge')
-	});
-};
-
-let admit_patient_dialog = function(frm) {
-	let dialog = new frappe.ui.Dialog({
-		title: 'Admit Patient',
-		width: 100,
-		fields: [
-			{fieldtype: 'Link', label: 'Service Unit Type', fieldname: 'service_unit_type',
-				options: 'Healthcare Service Unit Type', default: frm.doc.admission_service_unit_type
-			},
-			{fieldtype: 'Link', label: 'Service Unit', fieldname: 'service_unit',
-				options: 'Healthcare Service Unit', reqd: 1
-			},
-			{fieldtype: 'Datetime', label: 'Admission Datetime', fieldname: 'check_in',
-				reqd: 1, default: frappe.datetime.now_datetime()
-			},
-			{fieldtype: 'Date', label: 'Expected Discharge', fieldname: 'expected_discharge',
-				default: frm.doc.expected_length_of_stay ? frappe.datetime.add_days(frappe.datetime.now_datetime(), frm.doc.expected_length_of_stay) : ''
-			}
-		],
-		primary_action_label: __('Admit'),
-		primary_action : function(){
-			let service_unit = dialog.get_value('service_unit');
-			let check_in = dialog.get_value('check_in');
-			let expected_discharge = null;
-			if (dialog.get_value('expected_discharge')) {
-				expected_discharge = dialog.get_value('expected_discharge');
-			}
-			if (!service_unit && !check_in) {
-				return;
-			}
-			frappe.call({
-				doc: frm.doc,
-				method: 'admit',
-				args:{
-					'service_unit': service_unit,
-					'check_in': check_in,
-					'expected_discharge': expected_discharge
-				},
-				callback: function(data) {
-					if (!data.exc) {
-						frm.reload_doc();
-					}
-				},
-				freeze: true,
-				freeze_message: __('Processing Patient Admission')
-			});
-			frm.refresh_fields();
-			dialog.hide();
-		}
-	});
-
-	dialog.fields_dict['service_unit_type'].get_query = function() {
-		return {
-			filters: {
-				'inpatient_occupancy': 1,
-				'allow_appointments': 0
-			}
-		};
-	};
-	dialog.fields_dict['service_unit'].get_query = function() {
-		return {
-			filters: {
-				'is_group': 0,
-				'company': frm.doc.company,
-				'service_unit_type': dialog.get_value('service_unit_type'),
-				'occupancy_status' : 'Vacant'
-			}
-		};
-	};
-
-	dialog.show();
-};
-
-let transfer_patient_dialog = function(frm) {
-	let dialog = new frappe.ui.Dialog({
-		title: 'Transfer Patient',
-		width: 100,
-		fields: [
-			{fieldtype: 'Link', label: 'Leave From', fieldname: 'leave_from', options: 'Healthcare Service Unit', reqd: 1, read_only:1},
-			{fieldtype: 'Link', label: 'Service Unit Type', fieldname: 'service_unit_type', options: 'Healthcare Service Unit Type'},
-			{fieldtype: 'Link', label: 'Transfer To', fieldname: 'service_unit', options: 'Healthcare Service Unit', reqd: 1},
-			{fieldtype: 'Datetime', label: 'Check In', fieldname: 'check_in', reqd: 1, default: frappe.datetime.now_datetime()}
-		],
-		primary_action_label: __('Transfer'),
-		primary_action : function() {
-			let service_unit = null;
-			let check_in = dialog.get_value('check_in');
-			let leave_from = null;
-			if(dialog.get_value('leave_from')){
-				leave_from = dialog.get_value('leave_from');
-			}
-			if(dialog.get_value('service_unit')){
-				service_unit = dialog.get_value('service_unit');
-			}
-			if(check_in > frappe.datetime.now_datetime()){
-				frappe.msgprint({
-					title: __('Not Allowed'),
-					message: __('Check-in time cannot be greater than the current time'),
-					indicator: 'red'
-				});
-				return;
-			}
-			frappe.call({
-				doc: frm.doc,
-				method: 'transfer',
-				args:{
-					'service_unit': service_unit,
-					'check_in': check_in,
-					'leave_from': leave_from
-				},
-				callback: function(data) {
-					if (!data.exc) {
-						frm.reload_doc();
-					}
-				},
-				freeze: true,
-				freeze_message: __('Process Transfer')
-			});
-			frm.refresh_fields();
-			dialog.hide();
-		}
-	});
-
-	dialog.fields_dict['leave_from'].get_query = function(){
-		return {
-			query : 'erpnext.healthcare.doctype.inpatient_record.inpatient_record.get_leave_from',
-			filters: {docname:frm.doc.name}
-		};
-	};
-	dialog.fields_dict['service_unit_type'].get_query = function(){
-		return {
-			filters: {
-				'inpatient_occupancy': 1,
-				'allow_appointments': 0
-			}
-		};
-	};
-	dialog.fields_dict['service_unit'].get_query = function(){
-		return {
-			filters: {
-				'is_group': 0,
-				'service_unit_type': dialog.get_value('service_unit_type'),
-				'occupancy_status' : 'Vacant'
-			}
-		};
-	};
-
-	dialog.show();
-
-	let not_left_service_unit = null;
-	for (let inpatient_occupancy in frm.doc.inpatient_occupancies) {
-		if (frm.doc.inpatient_occupancies[inpatient_occupancy].left != 1) {
-			not_left_service_unit = frm.doc.inpatient_occupancies[inpatient_occupancy].service_unit;
-		}
-	}
-	dialog.set_values({
-		'leave_from': not_left_service_unit
-	});
-};
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.json b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.json
deleted file mode 100644
index 0e1c2ba..0000000
--- a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.json
+++ /dev/null
@@ -1,507 +0,0 @@
-{
- "actions": [],
- "autoname": "naming_series:",
- "creation": "2018-07-11 17:48:51.404139",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "section_break_1",
-  "naming_series",
-  "patient",
-  "patient_name",
-  "gender",
-  "blood_group",
-  "dob",
-  "mobile",
-  "email",
-  "phone",
-  "column_break_8",
-  "company",
-  "status",
-  "scheduled_date",
-  "admitted_datetime",
-  "expected_discharge",
-  "references",
-  "admission_encounter",
-  "admission_practitioner",
-  "medical_department",
-  "admission_ordered_for",
-  "expected_length_of_stay",
-  "admission_service_unit_type",
-  "cb_admission",
-  "primary_practitioner",
-  "secondary_practitioner",
-  "admission_instruction",
-  "encounter_details_section",
-  "chief_complaint",
-  "column_break_29",
-  "diagnosis",
-  "medication_section",
-  "drug_prescription",
-  "investigations_section",
-  "lab_test_prescription",
-  "procedures_section",
-  "procedure_prescription",
-  "rehabilitation_section",
-  "therapy_plan",
-  "therapies",
-  "sb_inpatient_occupancy",
-  "inpatient_occupancies",
-  "btn_transfer",
-  "sb_discharge_details",
-  "discharge_ordered_date",
-  "discharge_practitioner",
-  "discharge_encounter",
-  "discharge_datetime",
-  "cb_discharge",
-  "discharge_instructions",
-  "followup_date",
-  "sb_discharge_note",
-  "discharge_note"
- ],
- "fields": [
-  {
-   "fieldname": "section_break_1",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "hidden": 1,
-   "label": "Series",
-   "options": "HLC-INP-.YYYY.-"
-  },
-  {
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Patient",
-   "options": "Patient",
-   "reqd": 1,
-   "set_only_once": 1
-  },
-  {
-   "fetch_from": "patient.patient_name",
-   "fieldname": "patient_name",
-   "fieldtype": "Data",
-   "label": "Patient Name",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "patient.sex",
-   "fieldname": "gender",
-   "fieldtype": "Link",
-   "label": "Gender",
-   "options": "Gender",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "patient.blood_group",
-   "fieldname": "blood_group",
-   "fieldtype": "Select",
-   "label": "Blood Group",
-   "options": "\nA Positive\nA Negative\nAB Positive\nAB Negative\nB Positive\nB Negative\nO Positive\nO Negative",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "patient.dob",
-   "fieldname": "dob",
-   "fieldtype": "Date",
-   "label": "Date of birth",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "patient.mobile",
-   "fieldname": "mobile",
-   "fieldtype": "Data",
-   "label": "Mobile",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "patient.email",
-   "fieldname": "email",
-   "fieldtype": "Data",
-   "label": "Email",
-   "options": "Email",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "patient.phone",
-   "fieldname": "phone",
-   "fieldtype": "Data",
-   "label": "Phone",
-   "read_only": 1
-  },
-  {
-   "fieldname": "medical_department",
-   "fieldtype": "Link",
-   "label": "Medical Department",
-   "options": "Medical Department",
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "primary_practitioner",
-   "fieldtype": "Link",
-   "label": "Healthcare Practitioner (Primary)",
-   "options": "Healthcare Practitioner"
-  },
-  {
-   "fieldname": "secondary_practitioner",
-   "fieldtype": "Link",
-   "label": "Healthcare Practitioner (Secondary)",
-   "options": "Healthcare Practitioner"
-  },
-  {
-   "fieldname": "column_break_8",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "Admission Scheduled",
-   "fieldname": "status",
-   "fieldtype": "Select",
-   "in_list_view": 1,
-   "label": "Status",
-   "options": "Admission Scheduled\nAdmitted\nDischarge Scheduled\nDischarged",
-   "read_only": 1
-  },
-  {
-   "default": "Today",
-   "fieldname": "scheduled_date",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "label": "Admission Schedule Date",
-   "read_only": 1,
-   "reqd": 1
-  },
-  {
-   "fieldname": "admission_ordered_for",
-   "fieldtype": "Date",
-   "label": "Admission Ordered For",
-   "read_only": 1
-  },
-  {
-   "fieldname": "admitted_datetime",
-   "fieldtype": "Datetime",
-   "in_list_view": 1,
-   "label": "Admitted Datetime",
-   "permlevel": 2
-  },
-  {
-   "depends_on": "eval:(doc.expected_length_of_stay > 0)",
-   "fieldname": "expected_length_of_stay",
-   "fieldtype": "Int",
-   "label": "Expected Length of Stay",
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "expected_discharge",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "label": "Expected Discharge",
-   "read_only": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "references",
-   "fieldtype": "Section Break",
-   "label": "Admission Order Details"
-  },
-  {
-   "fieldname": "cb_admission",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "admission_practitioner",
-   "fieldtype": "Link",
-   "label": "Healthcare Practitioner",
-   "options": "Healthcare Practitioner",
-   "read_only": 1
-  },
-  {
-   "fieldname": "admission_encounter",
-   "fieldtype": "Link",
-   "label": "Patient Encounter",
-   "options": "Patient Encounter",
-   "read_only": 1
-  },
-  {
-   "fieldname": "chief_complaint",
-   "fieldtype": "Table MultiSelect",
-   "label": "Chief Complaint",
-   "options": "Patient Encounter Symptom",
-   "permlevel": 1
-  },
-  {
-   "fieldname": "admission_instruction",
-   "fieldtype": "Small Text",
-   "label": "Admission Instruction",
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "cb_discharge",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "discharge_practitioner",
-   "fieldtype": "Link",
-   "label": "Healthcare Practitioner",
-   "options": "Healthcare Practitioner",
-   "read_only": 1
-  },
-  {
-   "fieldname": "discharge_encounter",
-   "fieldtype": "Link",
-   "label": "Patient Encounter",
-   "options": "Patient Encounter",
-   "read_only": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "medication_section",
-   "fieldtype": "Section Break",
-   "label": "Medications",
-   "permlevel": 1
-  },
-  {
-   "fieldname": "drug_prescription",
-   "fieldtype": "Table",
-   "options": "Drug Prescription",
-   "permlevel": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "investigations_section",
-   "fieldtype": "Section Break",
-   "label": "Investigations",
-   "permlevel": 1
-  },
-  {
-   "fieldname": "lab_test_prescription",
-   "fieldtype": "Table",
-   "options": "Lab Prescription",
-   "permlevel": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "procedures_section",
-   "fieldtype": "Section Break",
-   "label": "Procedures",
-   "permlevel": 1
-  },
-  {
-   "fieldname": "procedure_prescription",
-   "fieldtype": "Table",
-   "options": "Procedure Prescription",
-   "permlevel": 1
-  },
-  {
-   "depends_on": "eval:(doc.status != \"Admission Scheduled\")",
-   "fieldname": "sb_inpatient_occupancy",
-   "fieldtype": "Section Break",
-   "label": "Inpatient Occupancy"
-  },
-  {
-   "fieldname": "admission_service_unit_type",
-   "fieldtype": "Link",
-   "label": "Admission Service Unit Type",
-   "options": "Healthcare Service Unit Type",
-   "read_only": 1
-  },
-  {
-   "fieldname": "inpatient_occupancies",
-   "fieldtype": "Table",
-   "options": "Inpatient Occupancy",
-   "permlevel": 2
-  },
-  {
-   "fieldname": "btn_transfer",
-   "fieldtype": "Button",
-   "label": "Transfer"
-  },
-  {
-   "depends_on": "eval:(doc.status == \"Discharge Scheduled\" || doc.status == \"Discharged\")",
-   "fieldname": "sb_discharge_note",
-   "fieldtype": "Section Break",
-   "label": "Discharge Notes"
-  },
-  {
-   "fieldname": "discharge_note",
-   "fieldtype": "Text Editor",
-   "permlevel": 1
-  },
-  {
-   "fetch_from": "admission_encounter.company",
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "in_standard_filter": 1,
-   "label": "Company",
-   "options": "Company"
-  },
-  {
-   "collapsible": 1,
-   "collapsible_depends_on": "eval:(doc.status == \"Admitted\")",
-   "fieldname": "encounter_details_section",
-   "fieldtype": "Section Break",
-   "label": "Encounter Impression",
-   "permlevel": 1
-  },
-  {
-   "fieldname": "column_break_29",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "diagnosis",
-   "fieldtype": "Table MultiSelect",
-   "label": "Diagnosis",
-   "options": "Patient Encounter Diagnosis",
-   "permlevel": 1
-  },
-  {
-   "fieldname": "followup_date",
-   "fieldtype": "Date",
-   "label": "Follow Up Date"
-  },
-  {
-   "collapsible": 1,
-   "depends_on": "eval:(doc.status == \"Discharge Scheduled\" || doc.status == \"Discharged\")",
-   "fieldname": "sb_discharge_details",
-   "fieldtype": "Section Break",
-   "label": "Discharge Detials"
-  },
-  {
-   "fieldname": "discharge_instructions",
-   "fieldtype": "Small Text",
-   "label": "Discharge Instructions"
-  },
-  {
-   "fieldname": "discharge_ordered_date",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "label": "Discharge Ordered Date",
-   "read_only": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "rehabilitation_section",
-   "fieldtype": "Section Break",
-   "label": "Rehabilitation",
-   "permlevel": 1
-  },
-  {
-   "fieldname": "therapy_plan",
-   "fieldtype": "Link",
-   "hidden": 1,
-   "label": "Therapy Plan",
-   "options": "Therapy Plan",
-   "permlevel": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "therapies",
-   "fieldtype": "Table",
-   "options": "Therapy Plan Detail",
-   "permlevel": 1
-  },
-  {
-   "fieldname": "discharge_datetime",
-   "fieldtype": "Datetime",
-   "label": "Discharge Date",
-   "permlevel": 2
-  }
- ],
- "index_web_pages_for_search": 1,
- "links": [],
- "modified": "2021-03-18 15:59:17.318988",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Inpatient Record",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Nursing User",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "permlevel": 1,
-   "read": 1,
-   "role": "Physician",
-   "write": 1
-  },
-  {
-   "permlevel": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Nursing User"
-  },
-  {
-   "email": 1,
-   "export": 1,
-   "permlevel": 2,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "email": 1,
-   "export": 1,
-   "permlevel": 2,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1
-  },
-  {
-   "email": 1,
-   "export": 1,
-   "permlevel": 2,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Nursing User",
-   "share": 1
-  }
- ],
- "restrict_to_domain": "Healthcare",
- "search_fields": "patient",
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "patient",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
deleted file mode 100644
index 2e26677..0000000
--- a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
+++ /dev/null
@@ -1,291 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-import json
-
-import frappe
-from frappe import _
-from frappe.desk.reportview import get_match_cond
-from frappe.model.document import Document
-from frappe.utils import get_datetime, get_link_to_form, getdate, now_datetime, today
-
-
-class InpatientRecord(Document):
-	def after_insert(self):
-		frappe.db.set_value('Patient', self.patient, 'inpatient_record', self.name)
-		frappe.db.set_value('Patient', self.patient, 'inpatient_status', self.status)
-
-		if self.admission_encounter: # Update encounter
-			frappe.db.set_value('Patient Encounter', self.admission_encounter, 'inpatient_record', self.name)
-			frappe.db.set_value('Patient Encounter', self.admission_encounter, 'inpatient_status', self.status)
-
-	def validate(self):
-		self.validate_dates()
-		self.validate_already_scheduled_or_admitted()
-		if self.status == "Discharged":
-			frappe.db.set_value("Patient", self.patient, "inpatient_status", None)
-			frappe.db.set_value("Patient", self.patient, "inpatient_record", None)
-
-	def validate_dates(self):
-		if (getdate(self.expected_discharge) < getdate(self.scheduled_date)) or \
-			(getdate(self.discharge_ordered_date) < getdate(self.scheduled_date)):
-			frappe.throw(_('Expected and Discharge dates cannot be less than Admission Schedule date'))
-
-		for entry in self.inpatient_occupancies:
-			if entry.check_in and entry.check_out and \
-				get_datetime(entry.check_in) > get_datetime(entry.check_out):
-				frappe.throw(_('Row #{0}: Check Out datetime cannot be less than Check In datetime').format(entry.idx))
-
-	def validate_already_scheduled_or_admitted(self):
-		query = """
-			select name, status
-			from `tabInpatient Record`
-			where (status = 'Admitted' or status = 'Admission Scheduled')
-			and name != %(name)s and patient = %(patient)s
-			"""
-
-		ip_record = frappe.db.sql(query,{
-				"name": self.name,
-				"patient": self.patient
-			}, as_dict = 1)
-
-		if ip_record:
-			msg = _(("Already {0} Patient {1} with Inpatient Record ").format(ip_record[0].status, self.patient) \
-				+ """ <b><a href="/app/Form/Inpatient Record/{0}">{0}</a></b>""".format(ip_record[0].name))
-			frappe.throw(msg)
-
-	@frappe.whitelist()
-	def admit(self, service_unit, check_in, expected_discharge=None):
-		admit_patient(self, service_unit, check_in, expected_discharge)
-
-	@frappe.whitelist()
-	def discharge(self):
-		discharge_patient(self)
-
-	@frappe.whitelist()
-	def transfer(self, service_unit, check_in, leave_from):
-		if leave_from:
-			patient_leave_service_unit(self, check_in, leave_from)
-		if service_unit:
-			transfer_patient(self, service_unit, check_in)
-
-
-@frappe.whitelist()
-def schedule_inpatient(args):
-	admission_order = json.loads(args) # admission order via Encounter
-	if not admission_order or not admission_order['patient'] or not admission_order['admission_encounter']:
-		frappe.throw(_('Missing required details, did not create Inpatient Record'))
-
-	inpatient_record = frappe.new_doc('Inpatient Record')
-
-	# Admission order details
-	set_details_from_ip_order(inpatient_record, admission_order)
-
-	# Patient details
-	patient = frappe.get_doc('Patient', admission_order['patient'])
-	inpatient_record.patient = patient.name
-	inpatient_record.patient_name = patient.patient_name
-	inpatient_record.gender = patient.sex
-	inpatient_record.blood_group = patient.blood_group
-	inpatient_record.dob = patient.dob
-	inpatient_record.mobile = patient.mobile
-	inpatient_record.email = patient.email
-	inpatient_record.phone = patient.phone
-	inpatient_record.scheduled_date = today()
-
-	# Set encounter detials
-	encounter = frappe.get_doc('Patient Encounter', admission_order['admission_encounter'])
-	if encounter and encounter.symptoms: # Symptoms
-		set_ip_child_records(inpatient_record, 'chief_complaint', encounter.symptoms)
-
-	if encounter and encounter.diagnosis: # Diagnosis
-		set_ip_child_records(inpatient_record, 'diagnosis', encounter.diagnosis)
-
-	if encounter and encounter.drug_prescription: # Medication
-		set_ip_child_records(inpatient_record, 'drug_prescription', encounter.drug_prescription)
-
-	if encounter and encounter.lab_test_prescription: # Lab Tests
-		set_ip_child_records(inpatient_record, 'lab_test_prescription', encounter.lab_test_prescription)
-
-	if encounter and encounter.procedure_prescription: # Procedure Prescription
-		set_ip_child_records(inpatient_record, 'procedure_prescription', encounter.procedure_prescription)
-
-	if encounter and encounter.therapies: # Therapies
-		inpatient_record.therapy_plan = encounter.therapy_plan
-		set_ip_child_records(inpatient_record, 'therapies', encounter.therapies)
-
-	inpatient_record.status = 'Admission Scheduled'
-	inpatient_record.save(ignore_permissions = True)
-
-
-@frappe.whitelist()
-def schedule_discharge(args):
-	discharge_order = json.loads(args)
-	inpatient_record_id = frappe.db.get_value('Patient', discharge_order['patient'], 'inpatient_record')
-	if inpatient_record_id:
-		inpatient_record = frappe.get_doc('Inpatient Record', inpatient_record_id)
-		check_out_inpatient(inpatient_record)
-		set_details_from_ip_order(inpatient_record, discharge_order)
-		inpatient_record.status = 'Discharge Scheduled'
-		inpatient_record.save(ignore_permissions = True)
-		frappe.db.set_value('Patient', discharge_order['patient'], 'inpatient_status', inpatient_record.status)
-		frappe.db.set_value('Patient Encounter', inpatient_record.discharge_encounter, 'inpatient_status', inpatient_record.status)
-
-
-def set_details_from_ip_order(inpatient_record, ip_order):
-	for key in ip_order:
-		inpatient_record.set(key, ip_order[key])
-
-
-def set_ip_child_records(inpatient_record, inpatient_record_child, encounter_child):
-	for item in encounter_child:
-		table = inpatient_record.append(inpatient_record_child)
-		for df in table.meta.get('fields'):
-			table.set(df.fieldname, item.get(df.fieldname))
-
-
-def check_out_inpatient(inpatient_record):
-	if inpatient_record.inpatient_occupancies:
-		for inpatient_occupancy in inpatient_record.inpatient_occupancies:
-			if inpatient_occupancy.left != 1:
-				inpatient_occupancy.left = True
-				inpatient_occupancy.check_out = now_datetime()
-				frappe.db.set_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "occupancy_status", "Vacant")
-
-
-def discharge_patient(inpatient_record):
-	validate_inpatient_invoicing(inpatient_record)
-	inpatient_record.discharge_datetime = now_datetime()
-	inpatient_record.status = "Discharged"
-
-	inpatient_record.save(ignore_permissions = True)
-
-
-def validate_inpatient_invoicing(inpatient_record):
-	if frappe.db.get_single_value("Healthcare Settings", "allow_discharge_despite_unbilled_services"):
-		return
-
-	pending_invoices = get_pending_invoices(inpatient_record)
-
-	if pending_invoices:
-		message = _("Cannot mark Inpatient Record as Discharged since there are unbilled services. ")
-
-		formatted_doc_rows = ''
-
-		for doctype, docnames in pending_invoices.items():
-			formatted_doc_rows += """
-				<td>{0}</td>
-				<td>{1}</td>
-			</tr>""".format(doctype, docnames)
-
-		message += """
-			<table class='table'>
-				<thead>
-					<th>{0}</th>
-					<th>{1}</th>
-				</thead>
-				{2}
-			</table>
-		""".format(_("Healthcare Service"), _("Documents"), formatted_doc_rows)
-
-		frappe.throw(message, title=_("Unbilled Services"), is_minimizable=True, wide=True)
-
-
-def get_pending_invoices(inpatient_record):
-	pending_invoices = {}
-	if inpatient_record.inpatient_occupancies:
-		service_unit_names = False
-		for inpatient_occupancy in inpatient_record.inpatient_occupancies:
-			if not inpatient_occupancy.invoiced:
-				if service_unit_names:
-					service_unit_names += ", " + inpatient_occupancy.service_unit
-				else:
-					service_unit_names = inpatient_occupancy.service_unit
-		if service_unit_names:
-			pending_invoices["Inpatient Occupancy"] = service_unit_names
-
-	docs = ["Patient Appointment", "Patient Encounter", "Lab Test", "Clinical Procedure"]
-
-	for doc in docs:
-		doc_name_list = get_unbilled_inpatient_docs(doc, inpatient_record)
-		if doc_name_list:
-			pending_invoices = get_pending_doc(doc, doc_name_list, pending_invoices)
-
-	return pending_invoices
-
-
-def get_pending_doc(doc, doc_name_list, pending_invoices):
-	if doc_name_list:
-		doc_ids = False
-		for doc_name in doc_name_list:
-			doc_link = get_link_to_form(doc, doc_name.name)
-			if doc_ids:
-				doc_ids += ", " + doc_link
-			else:
-				doc_ids = doc_link
-		if doc_ids:
-			pending_invoices[doc] =  doc_ids
-
-	return pending_invoices
-
-
-def get_unbilled_inpatient_docs(doc, inpatient_record):
-	return frappe.db.get_list(doc, filters = {'patient': inpatient_record.patient,
-					'inpatient_record': inpatient_record.name, 'docstatus': 1, 'invoiced': 0})
-
-
-def admit_patient(inpatient_record, service_unit, check_in, expected_discharge=None):
-	inpatient_record.admitted_datetime = check_in
-	inpatient_record.status = 'Admitted'
-	inpatient_record.expected_discharge = expected_discharge
-
-	inpatient_record.set('inpatient_occupancies', [])
-	transfer_patient(inpatient_record, service_unit, check_in)
-
-	frappe.db.set_value('Patient', inpatient_record.patient, 'inpatient_status', 'Admitted')
-	frappe.db.set_value('Patient', inpatient_record.patient, 'inpatient_record', inpatient_record.name)
-
-
-def transfer_patient(inpatient_record, service_unit, check_in):
-	item_line = inpatient_record.append('inpatient_occupancies', {})
-	item_line.service_unit = service_unit
-	item_line.check_in = check_in
-
-	inpatient_record.save(ignore_permissions = True)
-
-	frappe.db.set_value("Healthcare Service Unit", service_unit, "occupancy_status", "Occupied")
-
-
-def patient_leave_service_unit(inpatient_record, check_out, leave_from):
-	if inpatient_record.inpatient_occupancies:
-		for inpatient_occupancy in inpatient_record.inpatient_occupancies:
-			if inpatient_occupancy.left != 1 and inpatient_occupancy.service_unit == leave_from:
-				inpatient_occupancy.left = True
-				inpatient_occupancy.check_out = check_out
-				frappe.db.set_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "occupancy_status", "Vacant")
-	inpatient_record.save(ignore_permissions = True)
-
-
-@frappe.whitelist()
-@frappe.validate_and_sanitize_search_inputs
-def get_leave_from(doctype, txt, searchfield, start, page_len, filters):
-	docname = filters['docname']
-
-	query = '''select io.service_unit
-		from `tabInpatient Occupancy` io, `tabInpatient Record` ir
-		where io.parent = '{docname}' and io.parentfield = 'inpatient_occupancies'
-		and io.left!=1 and io.parent = ir.name'''
-
-	return frappe.db.sql(query.format(**{
-		"docname":	docname,
-		"searchfield":	searchfield,
-		"mcond":	get_match_cond(doctype)
-	}), {
-		'txt': "%%%s%%" % txt,
-		'_txt': txt.replace("%", ""),
-		'start': start,
-		'page_len': page_len
-	})
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record_dashboard.py b/erpnext/healthcare/doctype/inpatient_record/inpatient_record_dashboard.py
deleted file mode 100644
index 0f4adce..0000000
--- a/erpnext/healthcare/doctype/inpatient_record/inpatient_record_dashboard.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from __future__ import unicode_literals
-
-from frappe import _
-
-
-def get_data():
-	return {
-		'fieldname': 'inpatient_record',
-		'transactions': [
-			{
-				'label': _('Appointments and Encounters'),
-				'items': ['Patient Appointment', 'Patient Encounter']
-			},
-			{
-				'label': _('Lab Tests and Vital Signs'),
- 				'items': ['Lab Test', 'Clinical Procedure', 'Sample Collection', 'Vital Signs']
-			}
-		]
-	}
diff --git a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
deleted file mode 100644
index 58934e6..0000000
--- a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
+++ /dev/null
@@ -1,205 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-import frappe
-from frappe.utils import now_datetime, today
-from frappe.utils.make_random import get_random
-
-from erpnext.healthcare.doctype.inpatient_record.inpatient_record import (
-	admit_patient,
-	discharge_patient,
-	schedule_discharge,
-)
-from erpnext.healthcare.doctype.lab_test.test_lab_test import create_patient_encounter
-from erpnext.healthcare.utils import get_encounters_to_invoice
-
-
-class TestInpatientRecord(unittest.TestCase):
-	def test_admit_and_discharge(self):
-		frappe.db.sql("""delete from `tabInpatient Record`""")
-		patient = create_patient()
-		# Schedule Admission
-		ip_record = create_inpatient(patient)
-		ip_record.expected_length_of_stay = 0
-		ip_record.save(ignore_permissions = True)
-		self.assertEqual(ip_record.name, frappe.db.get_value("Patient", patient, "inpatient_record"))
-		self.assertEqual(ip_record.status, frappe.db.get_value("Patient", patient, "inpatient_status"))
-
-		# Admit
-		service_unit = get_healthcare_service_unit()
-		admit_patient(ip_record, service_unit, now_datetime())
-		self.assertEqual("Admitted", frappe.db.get_value("Patient", patient, "inpatient_status"))
-		self.assertEqual("Occupied", frappe.db.get_value("Healthcare Service Unit", service_unit, "occupancy_status"))
-
-		# Discharge
-		schedule_discharge(frappe.as_json({'patient': patient}))
-		self.assertEqual("Vacant", frappe.db.get_value("Healthcare Service Unit", service_unit, "occupancy_status"))
-
-		ip_record1 = frappe.get_doc("Inpatient Record", ip_record.name)
-		# Validate Pending Invoices
-		self.assertRaises(frappe.ValidationError, ip_record.discharge)
-		mark_invoiced_inpatient_occupancy(ip_record1)
-
-		discharge_patient(ip_record1)
-
-		self.assertEqual(None, frappe.db.get_value("Patient", patient, "inpatient_record"))
-		self.assertEqual(None, frappe.db.get_value("Patient", patient, "inpatient_status"))
-
-	def test_allow_discharge_despite_unbilled_services(self):
-		frappe.db.sql("""delete from `tabInpatient Record`""")
-		setup_inpatient_settings(key="allow_discharge_despite_unbilled_services", value=1)
-		patient = create_patient()
-		# Schedule Admission
-		ip_record = create_inpatient(patient)
-		ip_record.expected_length_of_stay = 0
-		ip_record.save(ignore_permissions = True)
-
-		# Admit
-		service_unit = get_healthcare_service_unit()
-		admit_patient(ip_record, service_unit, now_datetime())
-
-		# Discharge
-		schedule_discharge(frappe.as_json({"patient": patient}))
-		self.assertEqual("Vacant", frappe.db.get_value("Healthcare Service Unit", service_unit, "occupancy_status"))
-
-		ip_record = frappe.get_doc("Inpatient Record", ip_record.name)
-		# Should not validate Pending Invoices
-		ip_record.discharge()
-
-		self.assertEqual(None, frappe.db.get_value("Patient", patient, "inpatient_record"))
-		self.assertEqual(None, frappe.db.get_value("Patient", patient, "inpatient_status"))
-
-		setup_inpatient_settings(key="allow_discharge_despite_unbilled_services", value=0)
-
-	def test_do_not_bill_patient_encounters_for_inpatients(self):
-		frappe.db.sql("""delete from `tabInpatient Record`""")
-		setup_inpatient_settings(key="do_not_bill_inpatient_encounters", value=1)
-		patient = create_patient()
-		# Schedule Admission
-		ip_record = create_inpatient(patient)
-		ip_record.expected_length_of_stay = 0
-		ip_record.save(ignore_permissions = True)
-
-		# Admit
-		service_unit = get_healthcare_service_unit()
-		admit_patient(ip_record, service_unit, now_datetime())
-
-		# Patient Encounter
-		patient_encounter = create_patient_encounter()
-		encounters = get_encounters_to_invoice(patient, "_Test Company")
-		encounter_ids = [entry.reference_name for entry in encounters]
-		self.assertFalse(patient_encounter.name in encounter_ids)
-
-		# Discharge
-		schedule_discharge(frappe.as_json({"patient": patient}))
-		self.assertEqual("Vacant", frappe.db.get_value("Healthcare Service Unit", service_unit, "occupancy_status"))
-
-		ip_record = frappe.get_doc("Inpatient Record", ip_record.name)
-		mark_invoiced_inpatient_occupancy(ip_record)
-		discharge_patient(ip_record)
-		setup_inpatient_settings(key="do_not_bill_inpatient_encounters", value=0)
-
-	def test_validate_overlap_admission(self):
-		frappe.db.sql("""delete from `tabInpatient Record`""")
-		patient = create_patient()
-
-		ip_record = create_inpatient(patient)
-		ip_record.expected_length_of_stay = 0
-		ip_record.save(ignore_permissions = True)
-		ip_record_new = create_inpatient(patient)
-		ip_record_new.expected_length_of_stay = 0
-		self.assertRaises(frappe.ValidationError, ip_record_new.save)
-
-		service_unit = get_healthcare_service_unit()
-		admit_patient(ip_record, service_unit, now_datetime())
-		ip_record_new = create_inpatient(patient)
-		self.assertRaises(frappe.ValidationError, ip_record_new.save)
-		frappe.db.sql("""delete from `tabInpatient Record`""")
-
-def mark_invoiced_inpatient_occupancy(ip_record):
-	if ip_record.inpatient_occupancies:
-		for inpatient_occupancy in ip_record.inpatient_occupancies:
-			inpatient_occupancy.invoiced = 1
-		ip_record.save(ignore_permissions = True)
-
-
-def setup_inpatient_settings(key, value):
-	settings = frappe.get_single("Healthcare Settings")
-	settings.set(key, value)
-	settings.save()
-
-
-def create_inpatient(patient):
-	patient_obj = frappe.get_doc('Patient', patient)
-	inpatient_record = frappe.new_doc('Inpatient Record')
-	inpatient_record.patient = patient
-	inpatient_record.patient_name = patient_obj.patient_name
-	inpatient_record.gender = patient_obj.sex
-	inpatient_record.blood_group = patient_obj.blood_group
-	inpatient_record.dob = patient_obj.dob
-	inpatient_record.mobile = patient_obj.mobile
-	inpatient_record.email = patient_obj.email
-	inpatient_record.phone = patient_obj.phone
-	inpatient_record.inpatient = "Scheduled"
-	inpatient_record.scheduled_date = today()
-	inpatient_record.company = "_Test Company"
-	return inpatient_record
-
-
-def get_healthcare_service_unit(unit_name=None):
-	if not unit_name:
-		service_unit = get_random("Healthcare Service Unit", filters={"inpatient_occupancy": 1, "company": "_Test Company"})
-	else:
-		service_unit = frappe.db.exists("Healthcare Service Unit", {"healthcare_service_unit_name": unit_name})
-
-	if not service_unit:
-		service_unit = frappe.new_doc("Healthcare Service Unit")
-		service_unit.healthcare_service_unit_name = unit_name or "_Test Service Unit Ip Occupancy"
-		service_unit.company = "_Test Company"
-		service_unit.service_unit_type = get_service_unit_type()
-		service_unit.inpatient_occupancy = 1
-		service_unit.occupancy_status = "Vacant"
-		service_unit.is_group = 0
-		service_unit_parent_name = frappe.db.exists({
-				"doctype": "Healthcare Service Unit",
-				"healthcare_service_unit_name": "_Test All Healthcare Service Units",
-				"is_group": 1
-				})
-		if not service_unit_parent_name:
-			parent_service_unit = frappe.new_doc("Healthcare Service Unit")
-			parent_service_unit.healthcare_service_unit_name = "_Test All Healthcare Service Units"
-			parent_service_unit.is_group = 1
-			parent_service_unit.save(ignore_permissions = True)
-			service_unit.parent_healthcare_service_unit = parent_service_unit.name
-		else:
-			service_unit.parent_healthcare_service_unit = service_unit_parent_name[0][0]
-		service_unit.save(ignore_permissions = True)
-		return service_unit.name
-	return service_unit
-
-
-def get_service_unit_type():
-	service_unit_type = get_random("Healthcare Service Unit Type", filters={"inpatient_occupancy": 1})
-
-	if not service_unit_type:
-		service_unit_type = frappe.new_doc("Healthcare Service Unit Type")
-		service_unit_type.service_unit_type = "_Test Service Unit Type Ip Occupancy"
-		service_unit_type.inpatient_occupancy = 1
-		service_unit_type.save(ignore_permissions = True)
-		return service_unit_type.name
-	return service_unit_type
-
-
-def create_patient():
-	patient = frappe.db.exists('Patient', '_Test IPD Patient')
-	if not patient:
-		patient = frappe.new_doc('Patient')
-		patient.first_name = '_Test IPD Patient'
-		patient.sex = 'Female'
-		patient.save(ignore_permissions=True)
-		patient = patient.name
-	return patient
diff --git a/erpnext/healthcare/doctype/lab_prescription/__init__.py b/erpnext/healthcare/doctype/lab_prescription/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/lab_prescription/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/lab_prescription/lab_prescription.json b/erpnext/healthcare/doctype/lab_prescription/lab_prescription.json
deleted file mode 100644
index 0720bb4..0000000
--- a/erpnext/healthcare/doctype/lab_prescription/lab_prescription.json
+++ /dev/null
@@ -1,78 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "beta": 1,
- "creation": "2016-09-16 16:53:06.882970",
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "lab_test_code",
-  "lab_test_name",
-  "invoiced",
-  "column_break_4",
-  "lab_test_comment",
-  "lab_test_created"
- ],
- "fields": [
-  {
-   "fieldname": "lab_test_code",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "label": "Lab Test",
-   "options": "Lab Test Template",
-   "reqd": 1
-  },
-  {
-   "fetch_from": "lab_test_code.lab_test_name",
-   "fieldname": "lab_test_name",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Lab Test Name"
-  },
-  {
-   "default": "0",
-   "fieldname": "invoiced",
-   "fieldtype": "Check",
-   "label": "Invoiced",
-   "no_copy": 1,
-   "read_only": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "column_break_4",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "lab_test_comment",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Comments"
-  },
-  {
-   "default": "0",
-   "fieldname": "lab_test_created",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "label": "Test Created",
-   "no_copy": 1,
-   "print_hide": 1,
-   "report_hide": 1,
-   "search_index": 1
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-02-26 17:03:00.255560",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Lab Prescription",
- "owner": "Administrator",
- "permissions": [],
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/lab_prescription/lab_prescription.py b/erpnext/healthcare/doctype/lab_prescription/lab_prescription.py
deleted file mode 100644
index a3f9aa2..0000000
--- a/erpnext/healthcare/doctype/lab_prescription/lab_prescription.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class LabPrescription(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/lab_test/__init__.py b/erpnext/healthcare/doctype/lab_test/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/lab_test/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.js b/erpnext/healthcare/doctype/lab_test/lab_test.js
deleted file mode 100644
index bb7976c..0000000
--- a/erpnext/healthcare/doctype/lab_test/lab_test.js
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright (c) 2016, ESS and contributors
-// For license information, please see license.txt
-
-cur_frm.cscript.custom_refresh = function (doc) {
-	cur_frm.toggle_display('sb_sensitivity', doc.sensitivity_toggle);
-	cur_frm.toggle_display('organisms_section', doc.descriptive_toggle);
-	cur_frm.toggle_display('sb_descriptive', doc.descriptive_toggle);
-	cur_frm.toggle_display('sb_normal', doc.normal_toggle);
-};
-
-frappe.ui.form.on('Lab Test', {
-	setup: function (frm) {
-		frm.get_field('normal_test_items').grid.editable_fields = [
-			{ fieldname: 'lab_test_name', columns: 3 },
-			{ fieldname: 'lab_test_event', columns: 2 },
-			{ fieldname: 'result_value', columns: 2 },
-			{ fieldname: 'lab_test_uom', columns: 1 },
-			{ fieldname: 'normal_range', columns: 2 }
-		];
-		frm.get_field('descriptive_test_items').grid.editable_fields = [
-			{ fieldname: 'lab_test_particulars', columns: 3 },
-			{ fieldname: 'result_value', columns: 7 }
-		];
-	},
-	refresh: function (frm) {
-		refresh_field('normal_test_items');
-		refresh_field('descriptive_test_items');
-		if (frm.doc.__islocal) {
-			frm.add_custom_button(__('Get from Patient Encounter'), function () {
-				get_lab_test_prescribed(frm);
-			});
-		}
-		if (frappe.defaults.get_default('lab_test_approval_required') && frappe.user.has_role('LabTest Approver')) {
-			if (frm.doc.docstatus === 1 && frm.doc.status !== 'Approved' && frm.doc.status !== 'Rejected') {
-				frm.add_custom_button(__('Approve'), function () {
-					status_update(1, frm);
-				}, __('Actions'));
-				frm.add_custom_button(__('Reject'), function () {
-					status_update(0, frm);
-				}, __('Actions'));
-			}
-		}
-
-		if (frm.doc.docstatus === 1 && frm.doc.sms_sent === 0 && frm.doc.status !== 'Rejected' ) {
-			frm.add_custom_button(__('Send SMS'), function () {
-				frappe.call({
-					method: 'erpnext.healthcare.doctype.healthcare_settings.healthcare_settings.get_sms_text',
-					args: { doc: frm.doc.name },
-					callback: function (r) {
-						if (!r.exc) {
-							var emailed = r.message.emailed;
-							var printed = r.message.printed;
-							make_dialog(frm, emailed, printed);
-						}
-					}
-				});
-			});
-		}
-
-	}
-});
-
-frappe.ui.form.on('Lab Test', 'patient', function (frm) {
-	if (frm.doc.patient) {
-		frappe.call({
-			'method': 'erpnext.healthcare.doctype.patient.patient.get_patient_detail',
-			args: { patient: frm.doc.patient },
-			callback: function (data) {
-				var age = null;
-				if (data.message.dob) {
-					age = calculate_age(data.message.dob);
-				}
-				let values = {
-					'patient_age': age,
-					'patient_sex': data.message.sex,
-					'email': data.message.email,
-					'mobile': data.message.mobile,
-					'report_preference': data.message.report_preference
-				};
-				frm.set_value(values);
-			}
-		});
-	}
-});
-
-frappe.ui.form.on('Normal Test Result', {
-	normal_test_items_remove: function () {
-		frappe.msgprint(__('Not permitted, configure Lab Test Template as required'));
-		cur_frm.reload_doc();
-	}
-});
-
-frappe.ui.form.on('Descriptive Test Result', {
-	descriptive_test_items_remove: function () {
-		frappe.msgprint(__('Not permitted, configure Lab Test Template as required'));
-		cur_frm.reload_doc();
-	}
-});
-
-var status_update = function (approve, frm) {
-	var doc = frm.doc;
-	var status = null;
-	if (approve == 1) {
-		status = 'Approved';
-	}
-	else {
-		status = 'Rejected';
-	}
-	frappe.call({
-		method: 'erpnext.healthcare.doctype.lab_test.lab_test.update_status',
-		args: { status: status, name: doc.name },
-		callback: function () {
-			cur_frm.reload_doc();
-		}
-	});
-};
-
-var get_lab_test_prescribed = function (frm) {
-	if (frm.doc.patient) {
-		frappe.call({
-			method: 'erpnext.healthcare.doctype.lab_test.lab_test.get_lab_test_prescribed',
-			args: { patient: frm.doc.patient },
-			callback: function (r) {
-				show_lab_tests(frm, r.message);
-			}
-		});
-	}
-	else {
-		frappe.msgprint(__('Please select Patient to get Lab Tests'));
-	}
-};
-
-var show_lab_tests = function (frm, lab_test_list) {
-	var d = new frappe.ui.Dialog({
-		title: __('Lab Tests'),
-		fields: [{
-			fieldtype: 'HTML', fieldname: 'lab_test'
-		}]
-	});
-	var html_field = d.fields_dict.lab_test.$wrapper;
-	html_field.empty();
-	$.each(lab_test_list, function (x, y) {
-		var row = $(repl(
-			'<div class="col-xs-12" style="padding-top:12px;">\
-				<div class="col-xs-3"> %(lab_test)s </div>\
-				<div class="col-xs-4"> %(practitioner_name)s<br>%(encounter)s</div>\
-				<div class="col-xs-3"> %(date)s </div>\
-				<div class="col-xs-1">\
-					<a data-name="%(name)s" data-lab-test="%(lab_test)s"\
-					data-encounter="%(encounter)s" data-practitioner="%(practitioner)s"\
-					data-invoiced="%(invoiced)s" href="#"><button class="btn btn-default btn-xs">Get</button></a>\
-				</div>\
-			</div><hr>',
-			{ name: y[0], lab_test: y[1], encounter: y[2], invoiced: y[3], practitioner: y[4], practitioner_name: y[5], date: y[6] })
-		).appendTo(html_field);
-
-		row.find("a").click(function () {
-			frm.doc.template = $(this).attr('data-lab-test');
-			frm.doc.prescription = $(this).attr('data-name');
-			frm.doc.practitioner = $(this).attr('data-practitioner');
-			frm.set_df_property('template', 'read_only', 1);
-			frm.set_df_property('patient', 'read_only', 1);
-			frm.set_df_property('practitioner', 'read_only', 1);
-			frm.doc.invoiced = 0;
-			if ($(this).attr('data-invoiced') === 1) {
-				frm.doc.invoiced = 1;
-			}
-			refresh_field('invoiced');
-			refresh_field('template');
-			d.hide();
-			return false;
-		});
-	});
-	if (!lab_test_list.length) {
-		var msg = __('No Lab Tests found for the Patient {0}', [frm.doc.patient_name.bold()]);
-		html_field.empty();
-		$(repl('<div class="col-xs-12" style="padding-top:0px;" >%(msg)s</div>', { msg: msg })).appendTo(html_field);
-	}
-	d.show();
-};
-
-var make_dialog = function (frm, emailed, printed) {
-	var number = frm.doc.mobile;
-
-	var dialog = new frappe.ui.Dialog({
-		title: 'Send SMS',
-		width: 400,
-		fields: [
-			{ fieldname: 'result_format', fieldtype: 'Select', label: 'Result Format', options: ['Emailed', 'Printed'] },
-			{ fieldname: 'number', fieldtype: 'Data', label: 'Mobile Number', reqd: 1 },
-			{ fieldname: 'message', fieldtype: 'Small Text', label: 'Message', reqd: 1 }
-		],
-		primary_action_label: __('Send'),
-		primary_action: function () {
-			var values = dialog.fields_dict;
-			if (!values) {
-				return;
-			}
-			send_sms(values, frm);
-			dialog.hide();
-		}
-	});
-	if (frm.doc.report_preference === 'Print') {
-		dialog.set_values({
-			'result_format': 'Printed',
-			'number': number,
-			'message': printed
-		});
-	} else {
-		dialog.set_values({
-			'result_format': 'Emailed',
-			'number': number,
-			'message': emailed
-		});
-	}
-	var fd = dialog.fields_dict;
-	$(fd.result_format.input).change(function () {
-		if (dialog.get_value('result_format') === 'Emailed') {
-			dialog.set_values({
-				'number': number,
-				'message': emailed
-			});
-		} else {
-			dialog.set_values({
-				'number': number,
-				'message': printed
-			});
-		}
-	});
-	dialog.show();
-};
-
-var send_sms = function (vals, frm) {
-	var number = vals.number.value;
-	var message = vals.message.last_value;
-
-	if (!number || !message) {
-		frappe.throw(__('Did not send SMS, missing patient mobile number or message content.'));
-	}
-	frappe.call({
-		method: 'frappe.core.doctype.sms_settings.sms_settings.send_sms',
-		args: {
-			receiver_list: [number],
-			msg: message
-		},
-		callback: function (r) {
-			if (r.exc) {
-				frappe.msgprint(r.exc);
-			} else {
-				frm.reload_doc();
-			}
-		}
-	});
-};
-
-var calculate_age = function (dob) {
-	var ageMS = Date.parse(Date()) - Date.parse(dob);
-	var age = new Date();
-	age.setTime(ageMS);
-	var years = age.getFullYear() - 1970;
-	return `${years} ${__('Years(s)')} ${age.getMonth()} ${__('Month(s)')} ${age.getDate()} ${__('Day(s)')}`;
-};
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.json b/erpnext/healthcare/doctype/lab_test/lab_test.json
deleted file mode 100644
index ac61fea..0000000
--- a/erpnext/healthcare/doctype/lab_test/lab_test.json
+++ /dev/null
@@ -1,610 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "allow_import": 1,
- "autoname": "naming_series:",
- "beta": 1,
- "creation": "2016-03-29 17:34:47.509094",
- "doctype": "DocType",
- "document_type": "Document",
- "engine": "InnoDB",
- "field_order": [
-  "naming_series",
-  "template",
-  "lab_test_name",
-  "lab_test_group",
-  "medical_code",
-  "department",
-  "column_break_26",
-  "company",
-  "status",
-  "submitted_date",
-  "result_date",
-  "approved_date",
-  "expected_result_date",
-  "expected_result_time",
-  "printed_on",
-  "invoiced",
-  "sb_first",
-  "patient",
-  "patient_name",
-  "patient_age",
-  "patient_sex",
-  "inpatient_record",
-  "report_preference",
-  "email",
-  "mobile",
-  "c_b",
-  "practitioner",
-  "practitioner_name",
-  "requesting_department",
-  "employee",
-  "employee_name",
-  "employee_designation",
-  "user",
-  "sample",
-  "sb_normal",
-  "lab_test_html",
-  "normal_test_items",
-  "sb_descriptive",
-  "descriptive_test_items",
-  "organisms_section",
-  "organism_test_items",
-  "sb_sensitivity",
-  "sensitivity_test_items",
-  "sb_comments",
-  "lab_test_comment",
-  "sb_customresult",
-  "custom_result",
-  "worksheet_section",
-  "worksheet_instructions",
-  "result_legend_section",
-  "legend_print_position",
-  "result_legend",
-  "section_break_50",
-  "email_sent",
-  "sms_sent",
-  "printed",
-  "normal_toggle",
-  "descriptive_toggle",
-  "sensitivity_toggle",
-  "amended_from",
-  "prescription"
- ],
- "fields": [
-  {
-   "fetch_from": "patient.inpatient_record",
-   "fieldname": "inpatient_record",
-   "fieldtype": "Link",
-   "label": "Inpatient Record",
-   "options": "Inpatient Record",
-   "read_only": 1
-  },
-  {
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "label": "Series",
-   "options": "HLC-LAB-.YYYY.-",
-   "print_hide": 1,
-   "report_hide": 1,
-   "reqd": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "invoiced",
-   "fieldtype": "Check",
-   "label": "Invoiced",
-   "no_copy": 1,
-   "read_only": 1,
-   "search_index": 1
-  },
-  {
-   "fetch_from": "inpatient_record.patient",
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_standard_filter": 1,
-   "label": "Patient",
-   "options": "Patient",
-   "reqd": 1,
-   "search_index": 1,
-   "set_only_once": 1
-  },
-  {
-   "fetch_from": "patient.patient_name",
-   "fieldname": "patient_name",
-   "fieldtype": "Data",
-   "label": "Patient Name",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "patient_age",
-   "fieldtype": "Data",
-   "label": "Age",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "patient_sex",
-   "fieldtype": "Link",
-   "label": "Gender",
-   "options": "Gender",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1,
-   "reqd": 1,
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "practitioner",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "label": "Requesting Practitioner",
-   "no_copy": 1,
-   "options": "Healthcare Practitioner",
-   "search_index": 1
-  },
-  {
-   "fetch_from": "patient.email",
-   "fieldname": "email",
-   "fieldtype": "Data",
-   "hidden": 1,
-   "label": "Email",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "fetch_from": "patient.mobile",
-   "fieldname": "mobile",
-   "fieldtype": "Data",
-   "hidden": 1,
-   "label": "Mobile",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "in_standard_filter": 1,
-   "label": "Company",
-   "options": "Company",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "c_b",
-   "fieldtype": "Column Break",
-   "print_hide": 1
-  },
-  {
-   "fetch_from": "template.department",
-   "fieldname": "department",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_standard_filter": 1,
-   "label": "Department",
-   "options": "Medical Department",
-   "read_only": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "status",
-   "fieldtype": "Select",
-   "in_list_view": 1,
-   "label": "Status",
-   "options": "Draft\nCompleted\nApproved\nRejected\nCancelled",
-   "read_only": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "submitted_date",
-   "fieldtype": "Datetime",
-   "hidden": 1,
-   "label": "Submitted Date",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "approved_date",
-   "fieldtype": "Datetime",
-   "hidden": 1,
-   "label": "Approved Date",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "sample",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_filter": 1,
-   "label": "Sample ID",
-   "options": "Sample Collection",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "default": "Today",
-   "fieldname": "expected_result_date",
-   "fieldtype": "Date",
-   "hidden": 1,
-   "label": "Expected Result Date",
-   "read_only": 1
-  },
-  {
-   "fieldname": "expected_result_time",
-   "fieldtype": "Time",
-   "hidden": 1,
-   "label": "Expected Result Time",
-   "read_only": 1
-  },
-  {
-   "fieldname": "result_date",
-   "fieldtype": "Date",
-   "label": "Result Date",
-   "read_only": 1,
-   "search_index": 1
-  },
-  {
-   "allow_on_submit": 1,
-   "fieldname": "printed_on",
-   "fieldtype": "Datetime",
-   "label": "Printed on",
-   "read_only": 1
-  },
-  {
-   "fieldname": "employee",
-   "fieldtype": "Link",
-   "label": "Employee (Lab Technician)",
-   "no_copy": 1,
-   "options": "Employee",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "fetch_from": "employee.employee_name",
-   "fieldname": "employee_name",
-   "fieldtype": "Data",
-   "label": "Lab Technician Name",
-   "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "fetch_from": "employee.designation",
-   "fieldname": "employee_designation",
-   "fieldtype": "Data",
-   "label": "Lab Technician Designation",
-   "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "user",
-   "fieldtype": "Link",
-   "hidden": 1,
-   "label": "User",
-   "no_copy": 1,
-   "options": "User",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "fetch_from": "patient.report_preference",
-   "fieldname": "report_preference",
-   "fieldtype": "Data",
-   "label": "Report Preference",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "sb_first",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "lab_test_name",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Test Name",
-   "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "template",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_standard_filter": 1,
-   "label": "Test Template",
-   "options": "Lab Test Template",
-   "print_hide": 1,
-   "report_hide": 1,
-   "reqd": 1,
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "lab_test_group",
-   "fieldtype": "Link",
-   "hidden": 1,
-   "label": "Test Group",
-   "options": "Item Group",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "fetch_from": "template.medical_code",
-   "fieldname": "medical_code",
-   "fieldtype": "Link",
-   "label": "Medical Code",
-   "options": "Medical Code",
-   "read_only": 1
-  },
-  {
-   "fieldname": "sb_normal",
-   "fieldtype": "Section Break",
-   "label": "Compound Test Result"
-  },
-  {
-   "fieldname": "normal_test_items",
-   "fieldtype": "Table",
-   "label": "Normal Test Result",
-   "options": "Normal Test Result",
-   "print_hide": 1
-  },
-  {
-   "fieldname": "lab_test_html",
-   "fieldtype": "HTML"
-  },
-  {
-   "depends_on": "descriptive_toggle",
-   "fieldname": "organisms_section",
-   "fieldtype": "Section Break",
-   "label": "Organism Test Result"
-  },
-  {
-   "fieldname": "sb_sensitivity",
-   "fieldtype": "Section Break",
-   "label": "Sensitivity Test Result"
-  },
-  {
-   "fieldname": "sensitivity_test_items",
-   "fieldtype": "Table",
-   "label": "Sensitivity Test Result",
-   "options": "Sensitivity Test Result",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "sb_comments",
-   "fieldtype": "Section Break",
-   "label": "Comments"
-  },
-  {
-   "fieldname": "lab_test_comment",
-   "fieldtype": "Text",
-   "ignore_xss_filter": 1,
-   "label": "Comments",
-   "print_hide": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "sb_customresult",
-   "fieldtype": "Section Break",
-   "label": "Custom Result"
-  },
-  {
-   "fieldname": "custom_result",
-   "fieldtype": "Text Editor",
-   "ignore_xss_filter": 1,
-   "label": "Custom Result",
-   "print_hide": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "email_sent",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "sms_sent",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "printed",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "normal_toggle",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "sensitivity_toggle",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "amended_from",
-   "fieldtype": "Link",
-   "label": "Amended From",
-   "no_copy": 1,
-   "options": "Lab Test",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "prescription",
-   "fieldtype": "Link",
-   "hidden": 1,
-   "label": "Prescription",
-   "no_copy": 1,
-   "options": "Lab Prescription",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "column_break_26",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fetch_from": "practitioner.department",
-   "fieldname": "requesting_department",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Requesting Department",
-   "options": "Medical Department",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "practitioner.practitioner_name",
-   "fieldname": "practitioner_name",
-   "fieldtype": "Data",
-   "label": "Requesting Practitioner",
-   "read_only": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "result_legend_section",
-   "fieldtype": "Section Break",
-   "label": "Result Legend Print"
-  },
-  {
-   "fieldname": "legend_print_position",
-   "fieldtype": "Select",
-   "label": "Print Position",
-   "options": "\nBottom\nTop\nBoth",
-   "print_hide": 1
-  },
-  {
-   "fieldname": "result_legend",
-   "fieldtype": "Text Editor",
-   "label": "Result Legend",
-   "print_hide": 1
-  },
-  {
-   "fieldname": "section_break_50",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "worksheet_instructions",
-   "fieldtype": "Text Editor",
-   "label": "Worksheet Instructions",
-   "print_hide": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "worksheet_section",
-   "fieldtype": "Section Break",
-   "label": "Worksheet Print"
-  },
-  {
-   "fieldname": "descriptive_test_items",
-   "fieldtype": "Table",
-   "label": "Descriptive Test Result",
-   "options": "Descriptive Test Result",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "sb_descriptive",
-   "fieldtype": "Section Break",
-   "label": "Descriptive Test Result"
-  },
-  {
-   "default": "0",
-   "fieldname": "descriptive_toggle",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "organism_test_items",
-   "fieldtype": "Table",
-   "label": "Organism Test Result",
-   "options": "Organism Test Result",
-   "print_hide": 1
-  }
- ],
- "is_submittable": 1,
- "links": [],
- "modified": "2020-11-30 11:04:17.195848",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Lab Test",
- "owner": "Administrator",
- "permissions": [
-  {
-   "amend": 1,
-   "cancel": 1,
-   "create": 1,
-   "email": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Laboratory User",
-   "share": 1,
-   "submit": 1,
-   "write": 1
-  },
-  {
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "LabTest Approver",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "write": 1
-  }
- ],
- "restrict_to_domain": "Healthcare",
- "search_fields": "patient,practitioner,lab_test_name,sample",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "patient",
- "track_changes": 1,
- "track_seen": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.py b/erpnext/healthcare/doctype/lab_test/lab_test.py
deleted file mode 100644
index 7db497c..0000000
--- a/erpnext/healthcare/doctype/lab_test/lab_test.py
+++ /dev/null
@@ -1,352 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS 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
-from frappe.utils import get_link_to_form, getdate
-
-
-class LabTest(Document):
-	def validate(self):
-		if not self.is_new():
-			self.set_secondary_uom_result()
-
-	def on_submit(self):
-		self.validate_result_values()
-		self.db_set('submitted_date', getdate())
-		self.db_set('status', 'Completed')
-
-	def on_cancel(self):
-		self.db_set('status', 'Cancelled')
-		self.reload()
-
-	def on_update(self):
-		if self.sensitivity_test_items:
-			sensitivity = sorted(self.sensitivity_test_items, key=lambda x: x.antibiotic_sensitivity)
-			for i, item in enumerate(sensitivity):
-				item.idx = i + 1
-			self.sensitivity_test_items = sensitivity
-
-	def after_insert(self):
-		if self.prescription:
-			frappe.db.set_value('Lab Prescription', self.prescription, 'lab_test_created', 1)
-			if frappe.db.get_value('Lab Prescription', self.prescription, 'invoiced'):
-				self.invoiced = True
-		if self.template:
-			self.load_test_from_template()
-			self.reload()
-
-	def load_test_from_template(self):
-		lab_test = self
-		create_test_from_template(lab_test)
-		self.reload()
-
-	def set_secondary_uom_result(self):
-		for item in self.normal_test_items:
-			if item.result_value and item.secondary_uom and item.conversion_factor:
-				try:
-					item.secondary_uom_result = float(item.result_value) * float(item.conversion_factor)
-				except Exception:
-					item.secondary_uom_result = ''
-					frappe.msgprint(_('Row #{0}: Result for Secondary UOM not calculated').format(item.idx), title = _('Warning'))
-
-	def validate_result_values(self):
-		if self.normal_test_items:
-			for item in self.normal_test_items:
-				if not item.result_value and not item.allow_blank and item.require_result_value:
-					frappe.throw(_('Row #{0}: Please enter the result value for {1}').format(
-						item.idx, frappe.bold(item.lab_test_name)), title=_('Mandatory Results'))
-
-		if self.descriptive_test_items:
-			for item in self.descriptive_test_items:
-				if not item.result_value and not item.allow_blank and item.require_result_value:
-					frappe.throw(_('Row #{0}: Please enter the result value for {1}').format(
-						item.idx, frappe.bold(item.lab_test_particulars)), title=_('Mandatory Results'))
-
-
-def create_test_from_template(lab_test):
-	template = frappe.get_doc('Lab Test Template', lab_test.template)
-	patient = frappe.get_doc('Patient', lab_test.patient)
-
-	lab_test.lab_test_name = template.lab_test_name
-	lab_test.result_date = getdate()
-	lab_test.department = template.department
-	lab_test.lab_test_group = template.lab_test_group
-	lab_test.legend_print_position = template.legend_print_position
-	lab_test.result_legend = template.result_legend
-	lab_test.worksheet_instructions = template.worksheet_instructions
-
-	lab_test = create_sample_collection(lab_test, template, patient, None)
-	lab_test = load_result_format(lab_test, template, None, None)
-
-@frappe.whitelist()
-def update_status(status, name):
-	if name and status:
-		frappe.db.set_value('Lab Test', name, {
-			'status': status,
-			'approved_date': getdate()
-		})
-
-@frappe.whitelist()
-def create_multiple(doctype, docname):
-	if not doctype or not docname:
-		frappe.throw(_('Sales Invoice or Patient Encounter is required to create Lab Tests'), title=_('Insufficient Data'))
-
-	lab_test_created = False
-	if doctype == 'Sales Invoice':
-		lab_test_created = create_lab_test_from_invoice(docname)
-	elif doctype == 'Patient Encounter':
-		lab_test_created = create_lab_test_from_encounter(docname)
-
-	if lab_test_created:
-		frappe.msgprint(_('Lab Test(s) {0} created successfully').format(lab_test_created), indicator='green')
-	else:
-		frappe.msgprint(_('No Lab Tests created'))
-
-def create_lab_test_from_encounter(encounter):
-	lab_test_created = False
-	encounter = frappe.get_doc('Patient Encounter', encounter)
-
-	if encounter and encounter.lab_test_prescription:
-		patient = frappe.get_doc('Patient', encounter.patient)
-		for item in encounter.lab_test_prescription:
-			if not item.lab_test_created:
-				template = get_lab_test_template(item.lab_test_code)
-				if template:
-					lab_test = create_lab_test_doc(item.invoiced, encounter.practitioner, patient, template, encounter.company)
-					lab_test.save(ignore_permissions = True)
-					frappe.db.set_value('Lab Prescription', item.name, 'lab_test_created', 1)
-					if not lab_test_created:
-						lab_test_created = lab_test.name
-					else:
-						lab_test_created += ', ' + lab_test.name
-	return lab_test_created
-
-
-def create_lab_test_from_invoice(sales_invoice):
-	lab_tests_created = False
-	invoice = frappe.get_doc('Sales Invoice', sales_invoice)
-	if invoice and invoice.patient:
-		patient = frappe.get_doc('Patient', invoice.patient)
-		for item in invoice.items:
-			lab_test_created = 0
-			if item.reference_dt == 'Lab Prescription':
-				lab_test_created = frappe.db.get_value('Lab Prescription', item.reference_dn, 'lab_test_created')
-			elif item.reference_dt == 'Lab Test':
-				lab_test_created = 1
-			if lab_test_created != 1:
-				template = get_lab_test_template(item.item_code)
-				if template:
-					lab_test = create_lab_test_doc(True, invoice.ref_practitioner, patient, template, invoice.company)
-					if item.reference_dt == 'Lab Prescription':
-						lab_test.prescription = item.reference_dn
-					lab_test.save(ignore_permissions = True)
-					if item.reference_dt != 'Lab Prescription':
-						frappe.db.set_value('Sales Invoice Item', item.name, 'reference_dt', 'Lab Test')
-						frappe.db.set_value('Sales Invoice Item', item.name, 'reference_dn', lab_test.name)
-					if not lab_tests_created:
-						lab_tests_created = lab_test.name
-					else:
-						lab_tests_created += ', ' + lab_test.name
-	return lab_tests_created
-
-def get_lab_test_template(item):
-	template_id = frappe.db.exists('Lab Test Template', {'item': item})
-	if template_id:
-		return frappe.get_doc('Lab Test Template', template_id)
-	return False
-
-def create_lab_test_doc(invoiced, practitioner, patient, template, company):
-	lab_test = frappe.new_doc('Lab Test')
-	lab_test.invoiced = invoiced
-	lab_test.practitioner = practitioner
-	lab_test.patient = patient.name
-	lab_test.patient_age = patient.get_age()
-	lab_test.patient_sex = patient.sex
-	lab_test.email = patient.email
-	lab_test.mobile = patient.mobile
-	lab_test.report_preference = patient.report_preference
-	lab_test.department = template.department
-	lab_test.template = template.name
-	lab_test.lab_test_group = template.lab_test_group
-	lab_test.result_date = getdate()
-	lab_test.company = company
-	return lab_test
-
-def create_normals(template, lab_test):
-	lab_test.normal_toggle = 1
-	normal = lab_test.append('normal_test_items')
-	normal.lab_test_name = template.lab_test_name
-	normal.lab_test_uom = template.lab_test_uom
-	normal.secondary_uom = template.secondary_uom
-	normal.conversion_factor = template.conversion_factor
-	normal.normal_range = template.lab_test_normal_range
-	normal.require_result_value = 1
-	normal.allow_blank = 0
-	normal.template = template.name
-
-def create_compounds(template, lab_test, is_group):
-	lab_test.normal_toggle = 1
-	for normal_test_template in template.normal_test_templates:
-		normal = lab_test.append('normal_test_items')
-		if is_group:
-			normal.lab_test_event = normal_test_template.lab_test_event
-		else:
-			normal.lab_test_name = normal_test_template.lab_test_event
-
-		normal.lab_test_uom = normal_test_template.lab_test_uom
-		normal.secondary_uom = normal_test_template.secondary_uom
-		normal.conversion_factor = normal_test_template.conversion_factor
-		normal.normal_range = normal_test_template.normal_range
-		normal.require_result_value = 1
-		normal.allow_blank = normal_test_template.allow_blank
-		normal.template = template.name
-
-def create_descriptives(template, lab_test):
-	lab_test.descriptive_toggle = 1
-	if template.sensitivity:
-		lab_test.sensitivity_toggle = 1
-	for descriptive_test_template in template.descriptive_test_templates:
-		descriptive = lab_test.append('descriptive_test_items')
-		descriptive.lab_test_particulars = descriptive_test_template.particulars
-		descriptive.require_result_value = 1
-		descriptive.allow_blank = descriptive_test_template.allow_blank
-		descriptive.template = template.name
-
-def create_sample_doc(template, patient, invoice, company = None):
-	if template.sample:
-		sample_exists = frappe.db.exists({
-			'doctype': 'Sample Collection',
-			'patient': patient.name,
-			'docstatus': 0,
-			'sample': template.sample
-		})
-
-		if sample_exists:
-			# update sample collection by adding quantity
-			sample_collection = frappe.get_doc('Sample Collection', sample_exists[0][0])
-			quantity = int(sample_collection.sample_qty) + int(template.sample_qty)
-			if template.sample_details:
-				sample_details = sample_collection.sample_details + '\n-\n' + _('Test :')
-				sample_details += (template.get('lab_test_name') or template.get('template')) +	'\n'
-				sample_details += _('Collection Details:') + '\n\t' + template.sample_details
-				frappe.db.set_value('Sample Collection', sample_collection.name, 'sample_details', sample_details)
-
-			frappe.db.set_value('Sample Collection', sample_collection.name, 'sample_qty', quantity)
-
-		else:
-			# Create Sample Collection for template, copy vals from Invoice
-			sample_collection = frappe.new_doc('Sample Collection')
-			if invoice:
-				sample_collection.invoiced = True
-
-			sample_collection.patient = patient.name
-			sample_collection.patient_age = patient.get_age()
-			sample_collection.patient_sex = patient.sex
-			sample_collection.sample = template.sample
-			sample_collection.sample_uom = template.sample_uom
-			sample_collection.sample_qty = template.sample_qty
-			sample_collection.company = company
-
-			if template.sample_details:
-				sample_collection.sample_details = _('Test :') + (template.get('lab_test_name') or template.get('template')) + '\n' + 'Collection Detials:\n\t' + template.sample_details
-			sample_collection.save(ignore_permissions=True)
-
-		return sample_collection
-
-def create_sample_collection(lab_test, template, patient, invoice):
-	if frappe.get_cached_value('Healthcare Settings', None, 'create_sample_collection_for_lab_test'):
-		sample_collection = create_sample_doc(template, patient, invoice, lab_test.company)
-		if sample_collection:
-			lab_test.sample = sample_collection.name
-			sample_collection_doc = get_link_to_form('Sample Collection', sample_collection.name)
-			frappe.msgprint(_('Sample Collection {0} has been created').format(sample_collection_doc),
-				title=_('Sample Collection'), indicator='green')
-	return lab_test
-
-def load_result_format(lab_test, template, prescription, invoice):
-	if template.lab_test_template_type == 'Single':
-		create_normals(template, lab_test)
-
-	elif template.lab_test_template_type == 'Compound':
-		create_compounds(template, lab_test, False)
-
-	elif template.lab_test_template_type == 'Descriptive':
-		create_descriptives(template, lab_test)
-
-	elif template.lab_test_template_type == 'Grouped':
-		# Iterate for each template in the group and create one result for all.
-		for lab_test_group in template.lab_test_groups:
-			# Template_in_group = None
-			if lab_test_group.lab_test_template:
-				template_in_group = frappe.get_doc('Lab Test Template', lab_test_group.lab_test_template)
-				if template_in_group:
-					if template_in_group.lab_test_template_type == 'Single':
-						create_normals(template_in_group, lab_test)
-
-					elif template_in_group.lab_test_template_type == 'Compound':
-						normal_heading = lab_test.append('normal_test_items')
-						normal_heading.lab_test_name = template_in_group.lab_test_name
-						normal_heading.require_result_value = 0
-						normal_heading.allow_blank = 1
-						normal_heading.template = template_in_group.name
-						create_compounds(template_in_group, lab_test, True)
-
-					elif template_in_group.lab_test_template_type == 'Descriptive':
-						descriptive_heading = lab_test.append('descriptive_test_items')
-						descriptive_heading.lab_test_name = template_in_group.lab_test_name
-						descriptive_heading.require_result_value = 0
-						descriptive_heading.allow_blank = 1
-						descriptive_heading.template = template_in_group.name
-						create_descriptives(template_in_group, lab_test)
-
-			else: # Lab Test Group - Add New Line
-				normal = lab_test.append('normal_test_items')
-				normal.lab_test_name = lab_test_group.group_event
-				normal.lab_test_uom = lab_test_group.group_test_uom
-				normal.secondary_uom = lab_test_group.secondary_uom
-				normal.conversion_factor = lab_test_group.conversion_factor
-				normal.normal_range = lab_test_group.group_test_normal_range
-				normal.allow_blank = lab_test_group.allow_blank
-				normal.require_result_value = 1
-				normal.template = template.name
-
-	if template.lab_test_template_type != 'No Result':
-		if prescription:
-			lab_test.prescription = prescription
-			if invoice:
-				frappe.db.set_value('Lab Prescription', prescription, 'invoiced', True)
-		lab_test.save(ignore_permissions=True) # Insert the result
-		return lab_test
-
-@frappe.whitelist()
-def get_employee_by_user_id(user_id):
-	emp_id = frappe.db.exists('Employee', { 'user_id': user_id })
-	if emp_id:
-		return frappe.get_doc('Employee', emp_id)
-	return None
-
-
-@frappe.whitelist()
-def get_lab_test_prescribed(patient):
-	return frappe.db.sql(
-		'''
-			select
-				lp.name,
-				lp.lab_test_code,
-				lp.parent,
-				lp.invoiced,
-				pe.practitioner,
-				pe.practitioner_name,
-				pe.encounter_date
-			from
-				`tabPatient Encounter` pe, `tabLab Prescription` lp
-			where
-				pe.patient=%s
-				and lp.parent=pe.name
-				and lp.lab_test_created=0
-		''', (patient))
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test_list.js b/erpnext/healthcare/doctype/lab_test/lab_test_list.js
deleted file mode 100644
index 7b5b9d9..0000000
--- a/erpnext/healthcare/doctype/lab_test/lab_test_list.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-(c) ESS 2015-16
-*/
-frappe.listview_settings['Lab Test'] = {
-	add_fields: ['name', 'status', 'invoiced'],
-	filters: [['docstatus', '=', '1']],
-	get_indicator: function (doc) {
-		if (doc.status === 'Approved') {
-			return [__('Approved'), 'green', 'status, =, Approved'];
-		} else if (doc.status === 'Rejected') {
-			return [__('Rejected'), 'orange', 'status, =, Rejected'];
-		} else if (doc.status === 'Completed') {
-			return [__('Completed'), 'green', 'status, =, Completed'];
-		} else if (doc.status === 'Cancelled') {
-			return [__('Cancelled'), 'red', 'status, =, Cancelled'];
-		}
-	},
-	onload: function (listview) {
-		listview.page.add_menu_item(__('Create Multiple'), function () {
-			create_multiple_dialog(listview);
-		});
-	}
-};
-
-var create_multiple_dialog = function (listview) {
-	var dialog = new frappe.ui.Dialog({
-		title: 'Create Multiple Lab Tests',
-		width: 100,
-		fields: [
-			{ fieldtype: 'Link', label: 'Patient', fieldname: 'patient', options: 'Patient', reqd: 1 },
-			{
-				fieldtype: 'Select', label: 'Invoice / Patient Encounter', fieldname: 'doctype',
-				options: '\nSales Invoice\nPatient Encounter', reqd: 1
-			},
-			{
-				fieldtype: 'Dynamic Link', fieldname: 'docname', options: 'doctype', reqd: 1,
-				get_query: function () {
-					return {
-						filters: {
-							'patient': dialog.get_value('patient'),
-							'docstatus': 1
-						}
-					};
-				}
-			}
-		],
-		primary_action_label: __('Create'),
-		primary_action: function () {
-			frappe.call({
-				method: 'erpnext.healthcare.doctype.lab_test.lab_test.create_multiple',
-				args: {
-					'doctype': dialog.get_value('doctype'),
-					'docname': dialog.get_value('docname')
-				},
-				callback: function (data) {
-					if (!data.exc) {
-						if (!data.message) {
-							frappe.msgprint(__('No Lab Tests created'));
-						}
-						listview.refresh();
-					}
-				},
-				freeze: true,
-				freeze_message: __('Creating Lab Tests...')
-			});
-			dialog.hide();
-		}
-	});
-
-	dialog.show();
-};
diff --git a/erpnext/healthcare/doctype/lab_test/test_lab_test.py b/erpnext/healthcare/doctype/lab_test/test_lab_test.py
deleted file mode 100644
index da10bd8..0000000
--- a/erpnext/healthcare/doctype/lab_test/test_lab_test.py
+++ /dev/null
@@ -1,215 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-import frappe
-from frappe.utils import getdate, nowtime
-
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import (
-	get_income_account,
-	get_receivable_account,
-)
-from erpnext.healthcare.doctype.lab_test.lab_test import create_multiple
-from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_patient
-from erpnext.healthcare.doctype.patient_medical_record.test_patient_medical_record import (
-	create_lab_test_template as create_blood_test_template,
-)
-
-
-class TestLabTest(unittest.TestCase):
-	def test_lab_test_item(self):
-		lab_template = create_lab_test_template()
-		self.assertTrue(frappe.db.exists('Item', lab_template.item))
-		self.assertEqual(frappe.db.get_value('Item Price', {'item_code':lab_template.item}, 'price_list_rate'), lab_template.lab_test_rate)
-
-		lab_template.disabled = 1
-		lab_template.save()
-		self.assertEqual(frappe.db.get_value('Item', lab_template.item, 'disabled'), 1)
-
-		lab_template.reload()
-
-		lab_template.disabled = 0
-		lab_template.save()
-
-	def test_descriptive_lab_test(self):
-		lab_template = create_lab_test_template()
-
-		# blank result value not allowed as per template
-		lab_test = create_lab_test(lab_template)
-		lab_test.descriptive_test_items[0].result_value = 12
-		lab_test.descriptive_test_items[2].result_value = 1
-		lab_test.save()
-		self.assertRaises(frappe.ValidationError, lab_test.submit)
-
-	def test_sample_collection(self):
-		frappe.db.set_value('Healthcare Settings', 'Healthcare Settings', 'create_sample_collection_for_lab_test', 1)
-		lab_template = create_lab_test_template()
-
-		lab_test = create_lab_test(lab_template)
-		lab_test.descriptive_test_items[0].result_value = 12
-		lab_test.descriptive_test_items[1].result_value = 1
-		lab_test.descriptive_test_items[2].result_value = 2.3
-		lab_test.save()
-
-		# check sample collection created
-		self.assertTrue(frappe.db.exists('Sample Collection', {'sample': lab_template.sample}))
-
-		frappe.db.set_value('Healthcare Settings', 'Healthcare Settings', 'create_sample_collection_for_lab_test', 0)
-		lab_test = create_lab_test(lab_template)
-		lab_test.descriptive_test_items[0].result_value = 12
-		lab_test.descriptive_test_items[1].result_value = 1
-		lab_test.descriptive_test_items[2].result_value = 2.3
-		lab_test.save()
-
-		# sample collection should not be created
-		lab_test.reload()
-		self.assertEqual(lab_test.sample, None)
-
-	def test_create_lab_tests_from_sales_invoice(self):
-		sales_invoice = create_sales_invoice()
-		create_multiple('Sales Invoice', sales_invoice.name)
-		sales_invoice.reload()
-		self.assertIsNotNone(sales_invoice.items[0].reference_dn)
-		self.assertIsNotNone(sales_invoice.items[1].reference_dn)
-
-	def test_create_lab_tests_from_patient_encounter(self):
-		patient_encounter = create_patient_encounter()
-		create_multiple('Patient Encounter', patient_encounter.name)
-		patient_encounter.reload()
-		self.assertTrue(patient_encounter.lab_test_prescription[0].lab_test_created)
-		self.assertTrue(patient_encounter.lab_test_prescription[0].lab_test_created)
-
-
-def create_lab_test_template(test_sensitivity=0, sample_collection=1):
-	medical_department = create_medical_department()
-	if frappe.db.exists('Lab Test Template', 'Insulin Resistance'):
-		return frappe.get_doc('Lab Test Template', 'Insulin Resistance')
-	template = frappe.new_doc('Lab Test Template')
-	template.lab_test_name = 'Insulin Resistance'
-	template.lab_test_template_type = 'Descriptive'
-	template.lab_test_code = 'Insulin Resistance'
-	template.lab_test_group = 'Services'
-	template.department = medical_department
-	template.is_billable = 1
-	template.lab_test_description = 'Insulin Resistance'
-	template.lab_test_rate = 2000
-
-	for entry in ['FBS', 'Insulin', 'IR']:
-		template.append('descriptive_test_templates', {
-			'particulars': entry,
-			'allow_blank': 1 if entry=='IR' else 0
-		})
-
-	if test_sensitivity:
-		template.sensitivity = 1
-
-	if sample_collection:
-		template.sample = create_lab_test_sample()
-		template.sample_qty = 5.0
-
-	template.save()
-	return template
-
-def create_medical_department():
-	medical_department = frappe.db.exists('Medical Department', '_Test Medical Department')
-	if not medical_department:
-		medical_department = frappe.new_doc('Medical Department')
-		medical_department.department = '_Test Medical Department'
-		medical_department.save()
-		medical_department = medical_department.name
-
-	return medical_department
-
-def create_lab_test(lab_template):
-	patient = create_patient()
-	lab_test = frappe.new_doc('Lab Test')
-	lab_test.template = lab_template.name
-	lab_test.patient = patient
-	lab_test.patient_sex = 'Female'
-	lab_test.save()
-
-	return lab_test
-
-def create_lab_test_sample():
-	blood_sample = frappe.db.exists('Lab Test Sample', 'Blood Sample')
-	if blood_sample:
-		return blood_sample
-
-	sample = frappe.new_doc('Lab Test Sample')
-	sample.sample = 'Blood Sample'
-	sample.sample_uom = 'U/ml'
-	sample.save()
-
-	return sample.name
-
-def create_sales_invoice():
-	patient = create_patient()
-	medical_department = create_medical_department()
-	insulin_resistance_template = create_lab_test_template()
-	blood_test_template = create_blood_test_template(medical_department)
-
-	sales_invoice = frappe.new_doc('Sales Invoice')
-	sales_invoice.patient = patient
-	sales_invoice.customer = frappe.db.get_value('Patient', patient, 'customer')
-	sales_invoice.due_date = getdate()
-	sales_invoice.company = '_Test Company'
-	sales_invoice.debit_to = get_receivable_account('_Test Company')
-
-	tests = [insulin_resistance_template, blood_test_template]
-	for entry in tests:
-		sales_invoice.append('items', {
-			'item_code': entry.item,
-			'item_name': entry.lab_test_name,
-			'description': entry.lab_test_description,
-			'qty': 1,
-			'uom': 'Nos',
-			'conversion_factor': 1,
-			'income_account': get_income_account(None, '_Test Company'),
-			'rate': entry.lab_test_rate,
-			'amount': entry.lab_test_rate
-		})
-
-	sales_invoice.set_missing_values()
-
-	sales_invoice.submit()
-	return sales_invoice
-
-def create_patient_encounter():
-	patient = create_patient()
-	medical_department = create_medical_department()
-	insulin_resistance_template = create_lab_test_template()
-	blood_test_template = create_blood_test_template(medical_department)
-
-	patient_encounter = frappe.new_doc('Patient Encounter')
-	patient_encounter.patient = patient
-	patient_encounter.practitioner = create_practitioner()
-	patient_encounter.encounter_date = getdate()
-	patient_encounter.encounter_time = nowtime()
-
-	tests = [insulin_resistance_template, blood_test_template]
-	for entry in tests:
-		patient_encounter.append('lab_test_prescription', {
-			'lab_test_code': entry.item,
-			'lab_test_name': entry.lab_test_name
-		})
-
-	patient_encounter.submit()
-	return patient_encounter
-
-
-def create_practitioner():
-	practitioner = frappe.db.exists('Healthcare Practitioner', '_Test Healthcare Practitioner')
-
-	if not practitioner:
-		practitioner = frappe.new_doc('Healthcare Practitioner')
-		practitioner.first_name = '_Test Healthcare Practitioner'
-		practitioner.gender = 'Female'
-		practitioner.op_consulting_charge = 500
-		practitioner.inpatient_visit_charge = 500
-		practitioner.save(ignore_permissions=True)
-		practitioner = practitioner.name
-
-	return practitioner
diff --git a/erpnext/healthcare/doctype/lab_test_group_template/__init__.py b/erpnext/healthcare/doctype/lab_test_group_template/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/lab_test_group_template/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/lab_test_group_template/lab_test_group_template.json b/erpnext/healthcare/doctype/lab_test_group_template/lab_test_group_template.json
deleted file mode 100644
index 2767f7e..0000000
--- a/erpnext/healthcare/doctype/lab_test_group_template/lab_test_group_template.json
+++ /dev/null
@@ -1,119 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "beta": 1,
- "creation": "2016-03-29 17:37:29.913583",
- "doctype": "DocType",
- "document_type": "Setup",
- "engine": "InnoDB",
- "field_order": [
-  "template_or_new_line",
-  "lab_test_template",
-  "lab_test_rate",
-  "lab_test_description",
-  "group_event",
-  "group_test_uom",
-  "secondary_uom",
-  "conversion_factor",
-  "allow_blank",
-  "column_break_8",
-  "group_test_normal_range"
- ],
- "fields": [
-  {
-   "default": "Add Test",
-   "fieldname": "template_or_new_line",
-   "fieldtype": "Select",
-   "options": "Add Test\nAdd New Line",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "depends_on": "eval:doc.template_or_new_line == 'Add Test'",
-   "fieldname": "lab_test_template",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "label": "Test Name",
-   "options": "Lab Test Template"
-  },
-  {
-   "fetch_from": "lab_test_template.lab_test_rate",
-   "fieldname": "lab_test_rate",
-   "fieldtype": "Currency",
-   "label": "Rate",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "fetch_from": "lab_test_template.lab_test_description",
-   "fieldname": "lab_test_description",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Description",
-   "read_only": 1
-  },
-  {
-   "depends_on": "eval:doc.template_or_new_line == 'Add New Line'",
-   "fieldname": "group_event",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Event"
-  },
-  {
-   "depends_on": "eval:doc.template_or_new_line =='Add New Line'",
-   "fieldname": "group_test_uom",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "label": "UOM",
-   "options": "Lab Test UOM"
-  },
-  {
-   "depends_on": "eval:doc.template_or_new_line == 'Add New Line'",
-   "fieldname": "group_test_normal_range",
-   "fieldtype": "Long Text",
-   "ignore_xss_filter": 1,
-   "label": "Normal Range"
-  },
-  {
-   "fieldname": "column_break_8",
-   "fieldtype": "Column Break"
-  },
-  {
-   "depends_on": "eval:doc.template_or_new_line =='Add New Line'",
-   "fieldname": "secondary_uom",
-   "fieldtype": "Link",
-   "label": "Secondary UOM",
-   "options": "Lab Test UOM"
-  },
-  {
-   "depends_on": "secondary_uom",
-   "fieldname": "conversion_factor",
-   "fieldtype": "Float",
-   "label": "Conversion Factor",
-   "mandatory_depends_on": "secondary_uom"
-  },
-  {
-   "default": "0",
-   "depends_on": "eval:doc.template_or_new_line == 'Add New Line'",
-   "fieldname": "allow_blank",
-   "fieldtype": "Check",
-   "in_list_view": 1,
-   "label": "Allow Blank"
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-07-30 12:36:03.082391",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Lab Test Group Template",
- "owner": "Administrator",
- "permissions": [],
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/lab_test_group_template/lab_test_group_template.py b/erpnext/healthcare/doctype/lab_test_group_template/lab_test_group_template.py
deleted file mode 100644
index 2e3c409..0000000
--- a/erpnext/healthcare/doctype/lab_test_group_template/lab_test_group_template.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class LabTestGroupTemplate(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/lab_test_sample/__init__.py b/erpnext/healthcare/doctype/lab_test_sample/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/lab_test_sample/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/lab_test_sample/lab_test_sample.js b/erpnext/healthcare/doctype/lab_test_sample/lab_test_sample.js
deleted file mode 100644
index a5f4b4d..0000000
--- a/erpnext/healthcare/doctype/lab_test_sample/lab_test_sample.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Lab Test Sample', {
-});
diff --git a/erpnext/healthcare/doctype/lab_test_sample/lab_test_sample.json b/erpnext/healthcare/doctype/lab_test_sample/lab_test_sample.json
deleted file mode 100644
index 2830038..0000000
--- a/erpnext/healthcare/doctype/lab_test_sample/lab_test_sample.json
+++ /dev/null
@@ -1,68 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:sample",
- "beta": 1,
- "creation": "2016-04-04 17:35:44.823951",
- "doctype": "DocType",
- "document_type": "Setup",
- "engine": "InnoDB",
- "field_order": [
-  "sample",
-  "sample_uom"
- ],
- "fields": [
-  {
-   "fieldname": "sample",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Sample",
-   "reqd": 1,
-   "unique": 1
-  },
-  {
-   "bold": 1,
-   "fieldname": "sample_uom",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "UOM",
-   "options": "Lab Test UOM"
-  }
- ],
- "links": [],
- "modified": "2020-01-29 23:02:02.249839",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Lab Test Sample",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Laboratory User",
-   "share": 1
-  }
- ],
- "quick_entry": 1,
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "sample",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/lab_test_sample/lab_test_sample.py b/erpnext/healthcare/doctype/lab_test_sample/lab_test_sample.py
deleted file mode 100644
index 3a765fe..0000000
--- a/erpnext/healthcare/doctype/lab_test_sample/lab_test_sample.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class LabTestSample(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/lab_test_sample/test_lab_test_sample.py b/erpnext/healthcare/doctype/lab_test_sample/test_lab_test_sample.py
deleted file mode 100644
index 8896572..0000000
--- a/erpnext/healthcare/doctype/lab_test_sample/test_lab_test_sample.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-
-class TestLabTestSample(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/lab_test_template/__init__.py b/erpnext/healthcare/doctype/lab_test_template/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/lab_test_template/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.js b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.js
deleted file mode 100644
index 2e41f51..0000000
--- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.js
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2016, ESS
-// License: ESS license.txt
-
-frappe.ui.form.on('Lab Test Template', {
-	lab_test_name: function(frm) {
-		if (!frm.doc.lab_test_code)
-			frm.set_value('lab_test_code', frm.doc.lab_test_name);
-		if (!frm.doc.lab_test_description)
-			frm.set_value('lab_test_description', frm.doc.lab_test_name);
-	},
-	refresh : function(frm) {
-		// Restrict Special, Grouped type templates in Child Test Groups
-		frm.set_query('lab_test_template', 'lab_test_groups', function() {
-			return {
-				filters: {
-					lab_test_template_type: ['in', ['Single','Compound']]
-				}
-			};
-		});
-	},
-	medical_code: function(frm) {
-		frm.set_query('medical_code', function() {
-			return {
-				filters: {
-					medical_code_standard: frm.doc.medical_code_standard
-				}
-			};
-		});
-	}
-});
-
-cur_frm.cscript.custom_refresh = function(doc) {
-	cur_frm.set_df_property('lab_test_code', 'read_only', doc.__islocal ? 0 : 1);
-
-	if (!doc.__islocal) {
-		cur_frm.add_custom_button(__('Change Template Code'), function() {
-			change_template_code(doc);
-		});
-	}
-};
-
-let change_template_code = function(doc) {
-	let d = new frappe.ui.Dialog({
-		title:__('Change Template Code'),
-		fields:[
-			{
-				'fieldtype': 'Data',
-				'label': 'Lab Test Template Code',
-				'fieldname': 'lab_test_code',
-				reqd: 1
-			}
-		],
-		primary_action: function() {
-			let values = d.get_values();
-			if (values) {
-				frappe.call({
-					'method': 'erpnext.healthcare.doctype.lab_test_template.lab_test_template.change_test_code_from_template',
-					'args': {lab_test_code: values.lab_test_code, doc: doc},
-					callback: function (data) {
-						frappe.set_route('Form', 'Lab Test Template', data.message);
-					}
-				});
-			}
-			d.hide();
-		},
-		primary_action_label: __('Change Template Code')
-	});
-	d.show();
-
-	d.set_values({
-		'lab_test_code': doc.lab_test_code
-	});
-};
-
-frappe.ui.form.on('Lab Test Template', 'lab_test_name', function(frm) {
-	frm.doc.change_in_item = 1;
-});
-
-frappe.ui.form.on('Lab Test Template', 'lab_test_rate', function(frm) {
-	frm.doc.change_in_item = 1;
-});
-
-frappe.ui.form.on('Lab Test Template', 'lab_test_group', function(frm) {
-	frm.doc.change_in_item = 1;
-});
-
-frappe.ui.form.on('Lab Test Template', 'lab_test_description', function(frm) {
-	frm.doc.change_in_item = 1;
-});
-
-frappe.ui.form.on('Lab Test Groups', 'template_or_new_line', function (frm, cdt, cdn) {
-	let child = locals[cdt][cdn];
-	if (child.template_or_new_line == 'Add New Line') {
-		frappe.model.set_value(cdt, cdn, 'lab_test_template', '');
-		frappe.model.set_value(cdt, cdn, 'lab_test_description', '');
-	}
-});
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json
deleted file mode 100644
index c3fc842..0000000
--- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json
+++ /dev/null
@@ -1,356 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:lab_test_code",
- "beta": 1,
- "creation": "2016-03-29 17:35:36.761223",
- "doctype": "DocType",
- "engine": "InnoDB",
- "field_order": [
-  "lab_test_name",
-  "item",
-  "lab_test_code",
-  "lab_test_group",
-  "department",
-  "column_break_3",
-  "disabled",
-  "lab_test_template_type",
-  "is_billable",
-  "lab_test_rate",
-  "section_break_description",
-  "lab_test_description",
-  "section_break_normal",
-  "lab_test_uom",
-  "secondary_uom",
-  "conversion_factor",
-  "column_break_10",
-  "lab_test_normal_range",
-  "section_break_compound",
-  "normal_test_templates",
-  "section_break_special",
-  "sensitivity",
-  "descriptive_test_templates",
-  "section_break_group",
-  "lab_test_groups",
-  "sb_sample_collection",
-  "sample",
-  "sample_uom",
-  "sample_qty",
-  "column_break_33",
-  "sample_details",
-  "medical_coding_section",
-  "medical_code",
-  "medical_code_standard",
-  "worksheet_section",
-  "worksheet_instructions",
-  "result_legend_section",
-  "legend_print_position",
-  "result_legend",
-  "change_in_item"
- ],
- "fields": [
-  {
-   "fieldname": "lab_test_name",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Test Name",
-   "no_copy": 1,
-   "reqd": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "item",
-   "fieldtype": "Link",
-   "label": "Item",
-   "no_copy": 1,
-   "options": "Item",
-   "read_only": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "lab_test_code",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Item Code",
-   "no_copy": 1,
-   "reqd": 1,
-   "unique": 1
-  },
-  {
-   "fieldname": "lab_test_group",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_standard_filter": 1,
-   "label": "Item Group",
-   "options": "Item Group",
-   "reqd": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "department",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_standard_filter": 1,
-   "label": "Department",
-   "options": "Medical Department",
-   "reqd": 1
-  },
-  {
-   "fieldname": "column_break_3",
-   "fieldtype": "Column Break"
-  },
-  {
-   "description": "<b>Single</b>: Results which require only a single input.\n<br>\n<b>Compound</b>: Results which require multiple event inputs.\n<br>\n<b>Descriptive</b>: Tests which have multiple result components with manual result entry.\n<br>\n<b>Grouped</b>: Test templates which are a group of other test templates.\n<br>\n<b>No Result</b>: Tests with no results, can be ordered and billed but no Lab Test will be created. e.g.. Sub Tests for Grouped results",
-   "fieldname": "lab_test_template_type",
-   "fieldtype": "Select",
-   "in_standard_filter": 1,
-   "label": "Result Format",
-   "options": "\nSingle\nCompound\nDescriptive\nGrouped\nNo Result"
-  },
-  {
-   "default": "1",
-   "depends_on": "eval:doc.lab_test_template_type != 'Grouped'",
-   "description": "If unchecked, the item will not be available in Sales Invoices for billing but can be used in group test creation. ",
-   "fieldname": "is_billable",
-   "fieldtype": "Check",
-   "label": "Is Billable",
-   "search_index": 1
-  },
-  {
-   "depends_on": "eval:doc.is_billable == 1",
-   "description": "This value is updated in the Default Sales Price List.",
-   "fieldname": "lab_test_rate",
-   "fieldtype": "Currency",
-   "in_list_view": 1,
-   "label": "Rate",
-   "mandatory_depends_on": "eval:doc.is_billable == 1"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "medical_coding_section",
-   "fieldtype": "Section Break",
-   "label": "Medical Coding"
-  },
-  {
-   "depends_on": "medical_code_standard",
-   "fieldname": "medical_code",
-   "fieldtype": "Link",
-   "label": "Medical Code",
-   "options": "Medical Code"
-  },
-  {
-   "fieldname": "medical_code_standard",
-   "fieldtype": "Link",
-   "label": "Medical Code Standard",
-   "options": "Medical Code Standard"
-  },
-  {
-   "depends_on": "eval:doc.lab_test_template_type == 'Single'",
-   "fieldname": "section_break_normal",
-   "fieldtype": "Section Break",
-   "label": "Lab Routine"
-  },
-  {
-   "fieldname": "lab_test_uom",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "label": "UOM",
-   "options": "Lab Test UOM"
-  },
-  {
-   "fieldname": "lab_test_normal_range",
-   "fieldtype": "Long Text",
-   "ignore_xss_filter": 1,
-   "label": "Normal Range"
-  },
-  {
-   "fieldname": "column_break_10",
-   "fieldtype": "Column Break"
-  },
-  {
-   "depends_on": "eval:doc.lab_test_template_type == 'Compound'",
-   "fieldname": "section_break_compound",
-   "fieldtype": "Section Break",
-   "label": "Compound"
-  },
-  {
-   "fieldname": "normal_test_templates",
-   "fieldtype": "Table",
-   "options": "Normal Test Template"
-  },
-  {
-   "depends_on": "eval:doc.lab_test_template_type == 'Descriptive'",
-   "fieldname": "section_break_special",
-   "fieldtype": "Section Break",
-   "label": "Descriptive Test"
-  },
-  {
-   "default": "0",
-   "fieldname": "sensitivity",
-   "fieldtype": "Check",
-   "label": "Sensitivity"
-  },
-  {
-   "depends_on": "eval:doc.lab_test_template_type == 'Grouped'",
-   "fieldname": "section_break_group",
-   "fieldtype": "Section Break",
-   "label": "Group Tests"
-  },
-  {
-   "fieldname": "lab_test_groups",
-   "fieldtype": "Table",
-   "options": "Lab Test Group Template"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "section_break_description",
-   "fieldtype": "Section Break",
-   "label": "Description "
-  },
-  {
-   "fieldname": "lab_test_description",
-   "fieldtype": "Text Editor",
-   "ignore_xss_filter": 1,
-   "label": "Description",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "sb_sample_collection",
-   "fieldtype": "Section Break",
-   "label": "Sample Collection"
-  },
-  {
-   "fieldname": "sample",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "label": "Sample",
-   "options": "Lab Test Sample"
-  },
-  {
-   "fetch_from": "sample.sample_uom",
-   "fieldname": "sample_uom",
-   "fieldtype": "Data",
-   "label": "UOM",
-   "read_only": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "change_in_item",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "label": "Change In Item",
-   "no_copy": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "disabled",
-   "fieldtype": "Check",
-   "label": "Disabled"
-  },
-  {
-   "default": "0",
-   "fieldname": "sample_qty",
-   "fieldtype": "Float",
-   "label": "Quantity"
-  },
-  {
-   "fieldname": "sample_details",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Collection Details"
-  },
-  {
-   "collapsible": 1,
-   "description": "Information to help easily interpret the test report, will be printed as part of the Lab Test result.",
-   "fieldname": "result_legend_section",
-   "fieldtype": "Section Break",
-   "label": "Result Legend Print"
-  },
-  {
-   "fieldname": "result_legend",
-   "fieldtype": "Text Editor",
-   "label": "Result Legend"
-  },
-  {
-   "fieldname": "legend_print_position",
-   "fieldtype": "Select",
-   "label": "Print Position",
-   "options": "Bottom\nTop\nBoth"
-  },
-  {
-   "fieldname": "secondary_uom",
-   "fieldtype": "Link",
-   "label": "Secondary UOM",
-   "options": "Lab Test UOM"
-  },
-  {
-   "depends_on": "secondary_uom",
-   "fieldname": "conversion_factor",
-   "fieldtype": "Float",
-   "label": "Conversion Factor",
-   "mandatory_depends_on": "secondary_uom"
-  },
-  {
-   "description": "Instructions to be printed on the worksheet",
-   "fieldname": "worksheet_instructions",
-   "fieldtype": "Text Editor",
-   "label": "Worksheet Instructions"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "worksheet_section",
-   "fieldtype": "Section Break",
-   "label": "Worksheet Print"
-  },
-  {
-   "fieldname": "descriptive_test_templates",
-   "fieldtype": "Table",
-   "options": "Descriptive Test Template"
-  },
-  {
-   "fieldname": "column_break_33",
-   "fieldtype": "Column Break"
-  }
- ],
- "links": [],
- "modified": "2020-07-30 14:32:40.449818",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Lab Test Template",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Laboratory User",
-   "share": 1
-  }
- ],
- "restrict_to_domain": "Healthcare",
- "search_fields": "lab_test_code,lab_test_name,lab_test_template_type",
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "lab_test_name",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
deleted file mode 100644
index c052693..0000000
--- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-import json
-
-import frappe
-from frappe import _
-from frappe.model.document import Document
-from frappe.model.rename_doc import rename_doc
-
-
-class LabTestTemplate(Document):
-	def after_insert(self):
-		if not self.item:
-			create_item_from_template(self)
-
-	def validate(self):
-		if self.is_billable and (not self.lab_test_rate or self.lab_test_rate <= 0.0):
-			frappe.throw(_('Standard Selling Rate should be greater than zero.'))
-
-		self.validate_conversion_factor()
-		self.enable_disable_item()
-
-	def on_update(self):
-		# If change_in_item update Item and Price List
-		if self.change_in_item and self.is_billable and self.item:
-			self.update_item()
-			item_price = self.item_price_exists()
-			if not item_price:
-				if self.lab_test_rate and self.lab_test_rate > 0.0:
-					price_list_name = frappe.db.get_value('Price List', {'selling': 1})
-					make_item_price(self.lab_test_code, price_list_name, self.lab_test_rate)
-			else:
-				frappe.db.set_value('Item Price', item_price, 'price_list_rate', self.lab_test_rate)
-
-			self.db_set('change_in_item', 0)
-
-		elif not self.is_billable and self.item:
-			frappe.db.set_value('Item', self.item, 'disabled', 1)
-
-		self.reload()
-
-	def on_trash(self):
-		# Remove template reference from item and disable item
-		if self.item:
-			try:
-				item = self.item
-				self.db_set('item', '')
-				frappe.delete_doc('Item', item)
-			except Exception:
-				frappe.throw(_('Not permitted. Please disable the Lab Test Template'))
-
-	def enable_disable_item(self):
-		if self.is_billable:
-			if self.disabled:
-				frappe.db.set_value('Item', self.item, 'disabled', 1)
-			else:
-				frappe.db.set_value('Item', self.item, 'disabled', 0)
-
-	def update_item(self):
-		item = frappe.get_doc('Item', self.item)
-		if item:
-			item.update({
-				'item_name': self.lab_test_name,
-				'item_group': self.lab_test_group,
-				'disabled': 0,
-				'standard_rate': self.lab_test_rate,
-				'description': self.lab_test_description
-			})
-			item.flags.ignore_mandatory = True
-			item.save(ignore_permissions=True)
-
-	def item_price_exists(self):
-		item_price = frappe.db.exists({'doctype': 'Item Price', 'item_code': self.lab_test_code})
-		if item_price:
-			return item_price[0][0]
-		return False
-
-	def validate_conversion_factor(self):
-		if self.lab_test_template_type == 'Single' and self.secondary_uom and not self.conversion_factor:
-			frappe.throw(_('Conversion Factor is mandatory'))
-		if self.lab_test_template_type == 'Compound':
-			for item in self.normal_test_templates:
-				if item.secondary_uom and not item.conversion_factor:
-					frappe.throw(_('Row #{0}: Conversion Factor is mandatory').format(item.idx))
-		if self.lab_test_template_type == 'Grouped':
-			for group in self.lab_test_groups:
-				if group.template_or_new_line == 'Add New Line' and group.secondary_uom and not group.conversion_factor:
-					frappe.throw(_('Row #{0}: Conversion Factor is mandatory').format(group.idx))
-
-
-def create_item_from_template(doc):
-	uom = frappe.db.exists('UOM', 'Unit') or frappe.db.get_single_value('Stock Settings', 'stock_uom')
-	# Insert item
-	item =  frappe.get_doc({
-		'doctype': 'Item',
-		'item_code': doc.lab_test_code,
-		'item_name':doc.lab_test_name,
-		'item_group': doc.lab_test_group,
-		'description':doc.lab_test_description,
-		'is_sales_item': 1,
-		'is_service_item': 1,
-		'is_purchase_item': 0,
-		'is_stock_item': 0,
-		'include_item_in_manufacturing': 0,
-		'show_in_website': 0,
-		'is_pro_applicable': 0,
-		'disabled': 0 if doc.is_billable and not doc.disabled else doc.disabled,
-		'stock_uom': uom
-	}).insert(ignore_permissions=True, ignore_mandatory=True)
-
-	# Insert item price
-	if doc.is_billable and doc.lab_test_rate != 0.0:
-		price_list_name = frappe.db.get_value('Price List', {'selling': 1})
-		if doc.lab_test_rate:
-			make_item_price(item.name, price_list_name, doc.lab_test_rate)
-		else:
-			make_item_price(item.name, price_list_name, 0.0)
-	# Set item in the template
-	frappe.db.set_value('Lab Test Template', doc.name, 'item', item.name)
-
-	doc.reload()
-
-def make_item_price(item, price_list_name, item_price):
-	frappe.get_doc({
-		'doctype': 'Item Price',
-		'price_list': price_list_name,
-		'item_code': item,
-		'price_list_rate': item_price
-	}).insert(ignore_permissions=True, ignore_mandatory=True)
-
-@frappe.whitelist()
-def change_test_code_from_template(lab_test_code, doc):
-	doc = frappe._dict(json.loads(doc))
-
-	if frappe.db.exists({'doctype': 'Item', 'item_code': lab_test_code}):
-		frappe.throw(_('Lab Test Item {0} already exist').format(lab_test_code))
-	else:
-		rename_doc('Item', doc.name, lab_test_code, ignore_permissions=True)
-		frappe.db.set_value('Lab Test Template', doc.name, 'lab_test_code', lab_test_code)
-		frappe.db.set_value('Lab Test Template', doc.name, 'lab_test_name', lab_test_code)
-		rename_doc('Lab Test Template', doc.name, lab_test_code, ignore_permissions=True)
-	return lab_test_code
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template_dashboard.py b/erpnext/healthcare/doctype/lab_test_template/lab_test_template_dashboard.py
deleted file mode 100644
index a4f9d4b..0000000
--- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template_dashboard.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from __future__ import unicode_literals
-
-from frappe import _
-
-
-def get_data():
-	return {
-		'fieldname': 'template',
-		'transactions': [
-			{
-				'label': _('Lab Tests'),
-				'items': ['Lab Test']
-			}
-		]
-	}
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template_list.js b/erpnext/healthcare/doctype/lab_test_template/lab_test_template_list.js
deleted file mode 100644
index 08fc2cd..0000000
--- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template_list.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
-(c) ESS 2015-16
-*/
-frappe.listview_settings['Lab Test Template'] = {
-	add_fields: ['lab_test_name', 'lab_test_code', 'lab_test_rate'],
-	filters: [['disabled', '=', 'No']]
-};
diff --git a/erpnext/healthcare/doctype/lab_test_template/test_lab_test_template.py b/erpnext/healthcare/doctype/lab_test_template/test_lab_test_template.py
deleted file mode 100644
index 8d8ac64..0000000
--- a/erpnext/healthcare/doctype/lab_test_template/test_lab_test_template.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-# test_records = frappe.get_test_records('Lab Test Template')
-
-class TestLabTestTemplate(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/lab_test_uom/__init__.py b/erpnext/healthcare/doctype/lab_test_uom/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/lab_test_uom/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/lab_test_uom/lab_test_uom.js b/erpnext/healthcare/doctype/lab_test_uom/lab_test_uom.js
deleted file mode 100644
index 2107e79..0000000
--- a/erpnext/healthcare/doctype/lab_test_uom/lab_test_uom.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2016, ESS and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Lab Test UOM', {
-});
diff --git a/erpnext/healthcare/doctype/lab_test_uom/lab_test_uom.json b/erpnext/healthcare/doctype/lab_test_uom/lab_test_uom.json
deleted file mode 100644
index a6d5224..0000000
--- a/erpnext/healthcare/doctype/lab_test_uom/lab_test_uom.json
+++ /dev/null
@@ -1,148 +0,0 @@
-{
- "allow_copy": 1, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 1, 
- "autoname": "field:lab_test_uom", 
- "beta": 1, 
- "creation": "2016-03-29 17:28:08.630148", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "Setup", 
- "editable_grid": 0, 
- "fields": [
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "lab_test_uom", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 1, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Lab Test UOM", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 1
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "uom_description", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 1, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Description", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-09-04 11:02:53.202718", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "Lab Test UOM", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Healthcare Administrator", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 0, 
-   "delete": 0, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Laboratory User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 0
-  }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Healthcare", 
- "search_fields": "lab_test_uom", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "title_field": "lab_test_uom", 
- "track_changes": 1, 
- "track_seen": 0, 
- "track_views": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/lab_test_uom/lab_test_uom.py b/erpnext/healthcare/doctype/lab_test_uom/lab_test_uom.py
deleted file mode 100644
index ce11c0f..0000000
--- a/erpnext/healthcare/doctype/lab_test_uom/lab_test_uom.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class LabTestUOM(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/lab_test_uom/test_lab_test_uom.py b/erpnext/healthcare/doctype/lab_test_uom/test_lab_test_uom.py
deleted file mode 100644
index 9fe2de5..0000000
--- a/erpnext/healthcare/doctype/lab_test_uom/test_lab_test_uom.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-# test_records = frappe.get_test_records('Lab Test UOM')
-
-class TestLabTestUOM(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/medical_code/__init__.py b/erpnext/healthcare/doctype/medical_code/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/medical_code/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/medical_code/medical_code.js b/erpnext/healthcare/doctype/medical_code/medical_code.js
deleted file mode 100644
index 0422d77..0000000
--- a/erpnext/healthcare/doctype/medical_code/medical_code.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Medical Code', {
-});
diff --git a/erpnext/healthcare/doctype/medical_code/medical_code.json b/erpnext/healthcare/doctype/medical_code/medical_code.json
deleted file mode 100644
index 5d69830..0000000
--- a/erpnext/healthcare/doctype/medical_code/medical_code.json
+++ /dev/null
@@ -1,69 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "allow_import": 1,
- "allow_rename": 1,
- "beta": 1,
- "creation": "2017-06-21 13:02:56.122897",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "medical_code_standard",
-  "code",
-  "description"
- ],
- "fields": [
-  {
-   "fieldname": "medical_code_standard",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "label": "Medical Code Standard",
-   "options": "Medical Code Standard",
-   "reqd": 1
-  },
-  {
-   "fieldname": "code",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Code",
-   "reqd": 1,
-   "unique": 1
-  },
-  {
-   "bold": 1,
-   "fieldname": "description",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Description"
-  }
- ],
- "links": [],
- "modified": "2020-06-29 14:02:30.980032",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Medical Code",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "restrict_to_domain": "Healthcare",
- "search_fields": "code, description",
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/medical_code/medical_code.py b/erpnext/healthcare/doctype/medical_code/medical_code.py
deleted file mode 100644
index 4ed3d31..0000000
--- a/erpnext/healthcare/doctype/medical_code/medical_code.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class MedicalCode(Document):
-	def autoname(self):
-		self.name = self.medical_code_standard+" "+self.code
diff --git a/erpnext/healthcare/doctype/medical_code/test_medical_code.py b/erpnext/healthcare/doctype/medical_code/test_medical_code.py
deleted file mode 100644
index 7584b05..0000000
--- a/erpnext/healthcare/doctype/medical_code/test_medical_code.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-
-class TestMedicalCode(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/medical_code_standard/__init__.py b/erpnext/healthcare/doctype/medical_code_standard/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/medical_code_standard/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/medical_code_standard/medical_code_standard.js b/erpnext/healthcare/doctype/medical_code_standard/medical_code_standard.js
deleted file mode 100644
index 4bf6d3e..0000000
--- a/erpnext/healthcare/doctype/medical_code_standard/medical_code_standard.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Medical Code Standard', {
-});
diff --git a/erpnext/healthcare/doctype/medical_code_standard/medical_code_standard.json b/erpnext/healthcare/doctype/medical_code_standard/medical_code_standard.json
deleted file mode 100644
index 886938d..0000000
--- a/erpnext/healthcare/doctype/medical_code_standard/medical_code_standard.json
+++ /dev/null
@@ -1,94 +0,0 @@
-{
- "allow_copy": 1, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 1, 
- "autoname": "field:medical_code", 
- "beta": 1, 
- "creation": "2017-06-21 13:07:00.463176", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
- "fields": [
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "medical_code", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Medical Code", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2017-08-31 14:15:40.820693", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "Medical Code Standard", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Physician", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Healthcare", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/medical_code_standard/medical_code_standard.py b/erpnext/healthcare/doctype/medical_code_standard/medical_code_standard.py
deleted file mode 100644
index be0ea89..0000000
--- a/erpnext/healthcare/doctype/medical_code_standard/medical_code_standard.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class MedicalCodeStandard(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/medical_code_standard/test_medical_code_standard.py b/erpnext/healthcare/doctype/medical_code_standard/test_medical_code_standard.py
deleted file mode 100644
index 3b046e3..0000000
--- a/erpnext/healthcare/doctype/medical_code_standard/test_medical_code_standard.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-
-class TestMedicalCodeStandard(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/medical_department/__init__.py b/erpnext/healthcare/doctype/medical_department/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/medical_department/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/medical_department/medical_department.js b/erpnext/healthcare/doctype/medical_department/medical_department.js
deleted file mode 100644
index 25aeeb8..0000000
--- a/erpnext/healthcare/doctype/medical_department/medical_department.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2016, ESS LLP and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Medical Department', {
-});
diff --git a/erpnext/healthcare/doctype/medical_department/medical_department.json b/erpnext/healthcare/doctype/medical_department/medical_department.json
deleted file mode 100644
index 40f14ca..0000000
--- a/erpnext/healthcare/doctype/medical_department/medical_department.json
+++ /dev/null
@@ -1,156 +0,0 @@
-{
- "allow_copy": 1, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 1, 
- "autoname": "field:department", 
- "beta": 1, 
- "creation": "2017-02-27 13:38:30.806362", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
- "fields": [
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "department", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Department", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2017-08-31 13:41:59.611698", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "Medical Department", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 0, 
-   "delete": 0, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Physician", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 0, 
-   "delete": 0, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Nursing User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 0, 
-   "delete": 0, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Laboratory User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Healthcare Administrator", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Healthcare", 
- "search_fields": "department", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "title_field": "department", 
- "track_changes": 1, 
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/medical_department/medical_department.py b/erpnext/healthcare/doctype/medical_department/medical_department.py
deleted file mode 100644
index 7be5a1a..0000000
--- a/erpnext/healthcare/doctype/medical_department/medical_department.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class MedicalDepartment(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/medical_department/test_medical_department.py b/erpnext/healthcare/doctype/medical_department/test_medical_department.py
deleted file mode 100644
index 6435a23..0000000
--- a/erpnext/healthcare/doctype/medical_department/test_medical_department.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-# test_records = frappe.get_test_records('Medical Department')
-
-class TestMedicalDepartment(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/normal_test_result/__init__.py b/erpnext/healthcare/doctype/normal_test_result/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/normal_test_result/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/normal_test_result/normal_test_result.json b/erpnext/healthcare/doctype/normal_test_result/normal_test_result.json
deleted file mode 100644
index c8f43d3..0000000
--- a/erpnext/healthcare/doctype/normal_test_result/normal_test_result.json
+++ /dev/null
@@ -1,186 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "beta": 1,
- "creation": "2016-02-22 15:06:08.295224",
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "lab_test_name",
-  "lab_test_event",
-  "result_value",
-  "lab_test_uom",
-  "secondary_uom_result",
-  "secondary_uom",
-  "conversion_factor",
-  "column_break_10",
-  "allow_blank",
-  "normal_range",
-  "lab_test_comment",
-  "bold",
-  "italic",
-  "underline",
-  "template",
-  "require_result_value"
- ],
- "fields": [
-  {
-   "fieldname": "lab_test_name",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Test Name",
-   "read_only": 1
-  },
-  {
-   "fieldname": "lab_test_event",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Event",
-   "read_only": 1
-  },
-  {
-   "depends_on": "eval:doc.require_result_value",
-   "fieldname": "result_value",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Result Value"
-  },
-  {
-   "depends_on": "eval:doc.require_result_value",
-   "fieldname": "lab_test_uom",
-   "fieldtype": "Link",
-   "label": "UOM",
-   "options": "Lab Test UOM",
-   "read_only": 1
-  },
-  {
-   "depends_on": "eval:doc.require_result_value",
-   "fieldname": "normal_range",
-   "fieldtype": "Long Text",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Normal Range",
-   "read_only": 1
-  },
-  {
-   "depends_on": "eval:doc.require_result_value",
-   "fieldname": "lab_test_comment",
-   "fieldtype": "Data",
-   "hidden": 1,
-   "in_list_view": 1,
-   "label": "Comment",
-   "no_copy": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "template",
-   "fieldtype": "Link",
-   "hidden": 1,
-   "label": "Template",
-   "options": "Lab Test Template",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "depends_on": "eval:doc.require_result_value",
-   "fieldname": "secondary_uom",
-   "fieldtype": "Link",
-   "label": "Secondary UOM",
-   "options": "Lab Test UOM",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "depends_on": "secondary_uom",
-   "fieldname": "conversion_factor",
-   "fieldtype": "Float",
-   "label": "Conversion Factor",
-   "mandatory_depends_on": "secondary_uom",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "depends_on": "eval:doc.require_result_value && doc.result_value",
-   "fieldname": "secondary_uom_result",
-   "fieldtype": "Data",
-   "label": "Secondary UOM Result",
-   "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "allow_on_submit": 1,
-   "default": "0",
-   "depends_on": "eval:doc.require_result_value",
-   "fieldname": "bold",
-   "fieldtype": "Check",
-   "label": "Bold",
-   "no_copy": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "allow_on_submit": 1,
-   "default": "0",
-   "depends_on": "eval:doc.require_result_value",
-   "fieldname": "italic",
-   "fieldtype": "Check",
-   "label": "Italic",
-   "no_copy": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "allow_on_submit": 1,
-   "default": "0",
-   "depends_on": "eval:doc.require_result_value",
-   "fieldname": "underline",
-   "fieldtype": "Check",
-   "label": "Underline",
-   "no_copy": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "column_break_10",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "0",
-   "fieldname": "require_result_value",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "label": "Require Result Value",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "default": "1",
-   "depends_on": "eval:doc.require_result_value",
-   "fieldname": "allow_blank",
-   "fieldtype": "Check",
-   "label": "Allow Blank",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-07-08 16:03:17.522893",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Normal Test Result",
- "owner": "Administrator",
- "permissions": [],
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/normal_test_result/normal_test_result.py b/erpnext/healthcare/doctype/normal_test_result/normal_test_result.py
deleted file mode 100644
index e72f726..0000000
--- a/erpnext/healthcare/doctype/normal_test_result/normal_test_result.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class NormalTestResult(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/normal_test_template/__init__.py b/erpnext/healthcare/doctype/normal_test_template/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/normal_test_template/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/normal_test_template/normal_test_template.json b/erpnext/healthcare/doctype/normal_test_template/normal_test_template.json
deleted file mode 100644
index 8dd6476..0000000
--- a/erpnext/healthcare/doctype/normal_test_template/normal_test_template.json
+++ /dev/null
@@ -1,84 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "beta": 1,
- "creation": "2016-02-22 16:09:54.310628",
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "heading_text",
-  "lab_test_event",
-  "allow_blank",
-  "lab_test_uom",
-  "secondary_uom",
-  "conversion_factor",
-  "column_break_5",
-  "normal_range"
- ],
- "fields": [
-  {
-   "fieldname": "heading_text",
-   "fieldtype": "Heading",
-   "ignore_xss_filter": 1,
-   "label": "Test"
-  },
-  {
-   "fieldname": "lab_test_event",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Event"
-  },
-  {
-   "fieldname": "lab_test_uom",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "label": "UOM",
-   "options": "Lab Test UOM"
-  },
-  {
-   "fieldname": "normal_range",
-   "fieldtype": "Long Text",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Normal Range"
-  },
-  {
-   "fieldname": "column_break_5",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "secondary_uom",
-   "fieldtype": "Link",
-   "label": "Secondary UOM",
-   "options": "Lab Test UOM"
-  },
-  {
-   "depends_on": "secondary_uom",
-   "fieldname": "conversion_factor",
-   "fieldtype": "Float",
-   "label": "Conversion Factor",
-   "mandatory_depends_on": "secondary_uom"
-  },
-  {
-   "default": "0",
-   "fieldname": "allow_blank",
-   "fieldtype": "Check",
-   "label": "Allow Blank"
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-06-23 13:28:40.156224",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Normal Test Template",
- "owner": "Administrator",
- "permissions": [],
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/normal_test_template/normal_test_template.py b/erpnext/healthcare/doctype/normal_test_template/normal_test_template.py
deleted file mode 100644
index 9df4855..0000000
--- a/erpnext/healthcare/doctype/normal_test_template/normal_test_template.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class NormalTestTemplate(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/organism/__init__.py b/erpnext/healthcare/doctype/organism/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/organism/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/organism/organism.js b/erpnext/healthcare/doctype/organism/organism.js
deleted file mode 100644
index fbcb094..0000000
--- a/erpnext/healthcare/doctype/organism/organism.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Organism', {
-});
diff --git a/erpnext/healthcare/doctype/organism/organism.json b/erpnext/healthcare/doctype/organism/organism.json
deleted file mode 100644
index 88a7686..0000000
--- a/erpnext/healthcare/doctype/organism/organism.json
+++ /dev/null
@@ -1,152 +0,0 @@
-{
- "allow_copy": 0,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "field:organism",
- "beta": 1,
- "creation": "2019-09-06 16:29:07.797960",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
- "fields": [
-  {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "organism",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 1,
-   "in_standard_filter": 0,
-   "label": "Organism",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 1,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 1
-  },
-  {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "abbr",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 0,
-   "in_standard_filter": 0,
-   "label": "Abbr",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 1
-  }
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2019-10-04 19:45:33.353753",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Organism",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [
-  {
-   "amend": 0,
-   "cancel": 0,
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "if_owner": 0,
-   "import": 0,
-   "permlevel": 0,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "set_user_permissions": 0,
-   "share": 1,
-   "submit": 0,
-   "write": 1
-  },
-  {
-   "amend": 0,
-   "cancel": 0,
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "if_owner": 0,
-   "import": 0,
-   "permlevel": 0,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "set_user_permissions": 0,
-   "share": 1,
-   "submit": 0,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "search_fields": "organism, abbr",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "organism",
- "track_changes": 0,
- "track_seen": 0,
- "track_views": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/organism/organism.py b/erpnext/healthcare/doctype/organism/organism.py
deleted file mode 100644
index dfb9c0d..0000000
--- a/erpnext/healthcare/doctype/organism/organism.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class Organism(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/organism/test_organism.py b/erpnext/healthcare/doctype/organism/test_organism.py
deleted file mode 100644
index 9d7ea0b..0000000
--- a/erpnext/healthcare/doctype/organism/test_organism.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-
-class TestOrganism(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/organism_test_item/organism_test_item.json b/erpnext/healthcare/doctype/organism_test_item/organism_test_item.json
deleted file mode 100644
index 56d0a4d..0000000
--- a/erpnext/healthcare/doctype/organism_test_item/organism_test_item.json
+++ /dev/null
@@ -1,144 +0,0 @@
-{
- "allow_copy": 0,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 1,
- "creation": "2019-09-06 16:37:59.698996",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
- "fields": [
-  {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "organism",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 1,
-   "in_standard_filter": 0,
-   "label": "Organism",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Organism",
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 1,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
-  },
-  {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "colony_population",
-   "fieldtype": "Small Text",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 1,
-   "in_standard_filter": 0,
-   "label": "Colony Population",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
-  },
-  {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "colony_uom",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 1,
-   "in_standard_filter": 0,
-   "label": "Colony UOM",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Lab Test UOM",
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
-  }
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 1,
- "max_attachments": 0,
- "modified": "2019-10-04 19:48:04.104234",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Organism Test Item",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 0,
- "track_seen": 0,
- "track_views": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/organism_test_item/organism_test_item.py b/erpnext/healthcare/doctype/organism_test_item/organism_test_item.py
deleted file mode 100644
index 6bb8e8f..0000000
--- a/erpnext/healthcare/doctype/organism_test_item/organism_test_item.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class OrganismTestItem(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/organism_test_result/__init__.py b/erpnext/healthcare/doctype/organism_test_result/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/organism_test_result/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/organism_test_result/organism_test_result.json b/erpnext/healthcare/doctype/organism_test_result/organism_test_result.json
deleted file mode 100644
index 8b238de..0000000
--- a/erpnext/healthcare/doctype/organism_test_result/organism_test_result.json
+++ /dev/null
@@ -1,144 +0,0 @@
-{
- "allow_copy": 0,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 1,
- "creation": "2019-09-06 16:37:59.698996",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
- "fields": [
-  {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "organism",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 1,
-   "in_standard_filter": 0,
-   "label": "Organism",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Organism",
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 1,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
-  },
-  {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "colony_population",
-   "fieldtype": "Small Text",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 1,
-   "in_standard_filter": 0,
-   "label": "Colony Population",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
-  },
-  {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "colony_uom",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 1,
-   "in_standard_filter": 0,
-   "label": "Colony UOM",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Lab Test UOM",
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
-  }
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 1,
- "max_attachments": 0,
- "modified": "2019-10-04 19:48:04.104234",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Organism Test Result",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 0,
- "track_seen": 0,
- "track_views": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/organism_test_result/organism_test_result.py b/erpnext/healthcare/doctype/organism_test_result/organism_test_result.py
deleted file mode 100644
index 3428403..0000000
--- a/erpnext/healthcare/doctype/organism_test_result/organism_test_result.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class OrganismTestResult(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/patient/__init__.py b/erpnext/healthcare/doctype/patient/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/patient/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/patient/patient.js b/erpnext/healthcare/doctype/patient/patient.js
deleted file mode 100644
index 9266467..0000000
--- a/erpnext/healthcare/doctype/patient/patient.js
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright (c) 2016, ESS LLP and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Patient', {
-	refresh: function (frm) {
-		frm.set_query('patient', 'patient_relation', function () {
-			return {
-				filters: [
-					['Patient', 'name', '!=', frm.doc.name]
-				]
-			};
-		});
-		frm.set_query('customer_group', {'is_group': 0});
-		frm.set_query('default_price_list', { 'selling': 1});
-
-		if (frappe.defaults.get_default('patient_name_by') != 'Naming Series') {
-			frm.toggle_display('naming_series', false);
-		} else {
-			erpnext.toggle_naming_series();
-		}
-
-		if (frappe.defaults.get_default('collect_registration_fee') && frm.doc.status == 'Disabled') {
-			frm.add_custom_button(__('Invoice Patient Registration'), function () {
-				invoice_registration(frm);
-			});
-		}
-
-		if (frm.doc.patient_name && frappe.user.has_role('Physician')) {
-			frm.add_custom_button(__('Patient Progress'), function() {
-				frappe.route_options = {'patient': frm.doc.name};
-				frappe.set_route('patient-progress');
-			}, __('View'));
-
-			frm.add_custom_button(__('Patient History'), function() {
-				frappe.route_options = {'patient': frm.doc.name};
-				frappe.set_route('patient_history');
-			}, __('View'));
-		}
-
-		frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Patient'};
-		frm.toggle_display(['address_html', 'contact_html'], !frm.is_new());
-
-		if (!frm.is_new()) {
-			if ((frappe.user.has_role('Nursing User') || frappe.user.has_role('Physician'))) {
-				frm.add_custom_button(__('Medical Record'), function () {
-					create_medical_record(frm);
-				}, 'Create');
-				frm.toggle_enable(['customer'], 0);
-			}
-			frappe.contacts.render_address_and_contact(frm);
-			erpnext.utils.set_party_dashboard_indicators(frm);
-		} else {
-			frappe.contacts.clear_address_and_contact(frm);
-		}
-	},
-
-	onload: function (frm) {
-		if (frm.doc.dob) {
-			$(frm.fields_dict['age_html'].wrapper).html(`${__('AGE')} : ${get_age(frm.doc.dob)}`);
-		} else {
-			$(frm.fields_dict['age_html'].wrapper).html('');
-		}
-	}
-});
-
-frappe.ui.form.on('Patient', 'dob', function(frm) {
-	if (frm.doc.dob) {
-		let today = new Date();
-		let birthDate = new Date(frm.doc.dob);
-		if (today < birthDate) {
-			frappe.msgprint(__('Please select a valid Date'));
-			frappe.model.set_value(frm.doctype,frm.docname, 'dob', '');
-		} else {
-			let age_str = get_age(frm.doc.dob);
-			$(frm.fields_dict['age_html'].wrapper).html(`${__('AGE')} : ${age_str}`);
-		}
-	} else {
-		$(frm.fields_dict['age_html'].wrapper).html('');
-	}
-});
-
-frappe.ui.form.on('Patient Relation', {
-	patient_relation_add: function(frm){
-		frm.fields_dict['patient_relation'].grid.get_field('patient').get_query = function(doc){
-			let patient_list = [];
-			if(!doc.__islocal) patient_list.push(doc.name);
-			$.each(doc.patient_relation, function(idx, val){
-				if (val.patient) patient_list.push(val.patient);
-			});
-			return { filters: [['Patient', 'name', 'not in', patient_list]] };
-		};
-	}
-});
-
-let create_medical_record = function (frm) {
-	frappe.route_options = {
-		'patient': frm.doc.name,
-		'status': 'Open',
-		'reference_doctype': 'Patient Medical Record',
-		'reference_owner': frm.doc.owner
-	};
-	frappe.new_doc('Patient Medical Record');
-};
-
-let get_age = function (birth) {
-	let ageMS = Date.parse(Date()) - Date.parse(birth);
-	let age = new Date();
-	age.setTime(ageMS);
-	let years = age.getFullYear() - 1970;
-	return years + ' Year(s) ' + age.getMonth() + ' Month(s) ' + age.getDate() + ' Day(s)';
-};
-
-let create_vital_signs = function (frm) {
-	if (!frm.doc.name) {
-		frappe.throw(__('Please save the patient first'));
-	}
-	frappe.route_options = {
-		'patient': frm.doc.name,
-	};
-	frappe.new_doc('Vital Signs');
-};
-
-let create_encounter = function (frm) {
-	if (!frm.doc.name) {
-		frappe.throw(__('Please save the patient first'));
-	}
-	frappe.route_options = {
-		'patient': frm.doc.name,
-	};
-	frappe.new_doc('Patient Encounter');
-};
-
-let invoice_registration = function (frm) {
-	frappe.call({
-		doc: frm.doc,
-		method: 'invoice_patient_registration',
-		callback: function(data) {
-			if (!data.exc) {
-				if (data.message.invoice) {
-					frappe.set_route('Form', 'Sales Invoice', data.message.invoice);
-				}
-				cur_frm.reload_doc();
-			}
-		}
-	});
-};
diff --git a/erpnext/healthcare/doctype/patient/patient.json b/erpnext/healthcare/doctype/patient/patient.json
deleted file mode 100644
index 4092a6a..0000000
--- a/erpnext/healthcare/doctype/patient/patient.json
+++ /dev/null
@@ -1,542 +0,0 @@
-{
- "actions": [],
- "allow_events_in_timeline": 1,
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "naming_series:",
- "beta": 1,
- "creation": "2017-01-23 14:03:49.084370",
- "description": "Patient",
- "doctype": "DocType",
- "document_type": "Document",
- "engine": "InnoDB",
- "field_order": [
-  "basic_info",
-  "naming_series",
-  "first_name",
-  "middle_name",
-  "last_name",
-  "patient_name",
-  "sex",
-  "blood_group",
-  "dob",
-  "age_html",
-  "image",
-  "column_break_14",
-  "status",
-  "uid",
-  "inpatient_record",
-  "inpatient_status",
-  "report_preference",
-  "mobile",
-  "phone",
-  "email",
-  "invite_user",
-  "user_id",
-  "address_contacts",
-  "address_html",
-  "column_break_22",
-  "contact_html",
-  "customer_details_section",
-  "customer",
-  "customer_group",
-  "territory",
-  "column_break_24",
-  "default_currency",
-  "default_price_list",
-  "language",
-  "personal_and_social_history",
-  "occupation",
-  "column_break_25",
-  "marital_status",
-  "sb_relation",
-  "patient_relation",
-  "allergy_medical_and_surgical_history",
-  "allergies",
-  "medication",
-  "column_break_20",
-  "medical_history",
-  "surgical_history",
-  "risk_factors",
-  "tobacco_past_use",
-  "tobacco_current_use",
-  "alcohol_past_use",
-  "alcohol_current_use",
-  "column_break_32",
-  "surrounding_factors",
-  "other_risk_factors",
-  "more_info",
-  "patient_details"
- ],
- "fields": [
-  {
-   "fieldname": "basic_info",
-   "fieldtype": "Section Break",
-   "label": "Patient Demographics",
-   "oldfieldtype": "Section Break",
-   "options": "fa fa-user"
-  },
-  {
-   "fieldname": "inpatient_status",
-   "fieldtype": "Select",
-   "in_preview": 1,
-   "label": "Inpatient Status",
-   "no_copy": 1,
-   "options": "\nAdmission Scheduled\nAdmitted\nDischarge Scheduled",
-   "read_only": 1
-  },
-  {
-   "fieldname": "inpatient_record",
-   "fieldtype": "Link",
-   "label": "Inpatient Record",
-   "no_copy": 1,
-   "options": "Inpatient Record",
-   "read_only": 1
-  },
-  {
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "label": "Series",
-   "options": "HLC-PAT-.YYYY.-",
-   "print_hide": 1,
-   "report_hide": 1,
-   "set_only_once": 1
-  },
-  {
-   "bold": 1,
-   "fieldname": "patient_name",
-   "fieldtype": "Data",
-   "in_global_search": 1,
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Full Name",
-   "no_copy": 1,
-   "read_only": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "sex",
-   "fieldtype": "Link",
-   "in_preview": 1,
-   "label": "Gender",
-   "options": "Gender",
-   "reqd": 1
-  },
-  {
-   "bold": 1,
-   "fieldname": "blood_group",
-   "fieldtype": "Select",
-   "in_preview": 1,
-   "label": "Blood Group",
-   "no_copy": 1,
-   "options": "\nA Positive\nA Negative\nAB Positive\nAB Negative\nB Positive\nB Negative\nO Positive\nO Negative"
-  },
-  {
-   "bold": 1,
-   "fieldname": "dob",
-   "fieldtype": "Date",
-   "in_preview": 1,
-   "label": "Date of birth",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "age_html",
-   "fieldtype": "HTML",
-   "label": "Age",
-   "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "status",
-   "fieldtype": "Select",
-   "in_filter": 1,
-   "in_list_view": 1,
-   "label": "Status",
-   "no_copy": 1,
-   "options": "Active\nDisabled",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "image",
-   "fieldtype": "Attach Image",
-   "hidden": 1,
-   "in_preview": 1,
-   "label": "Image",
-   "no_copy": 1,
-   "print_hide": 1,
-   "width": "50%"
-  },
-  {
-   "fieldname": "column_break_14",
-   "fieldtype": "Column Break"
-  },
-  {
-   "description": "If \"Link Customer to Patient\" is checked in Healthcare Settings and an existing Customer is not selected then, a Customer will be created for this Patient for recording transactions in Accounts module.",
-   "fieldname": "customer",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "label": "Customer",
-   "no_copy": 1,
-   "options": "Customer",
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "report_preference",
-   "fieldtype": "Select",
-   "label": "Report Preference",
-   "options": "\nEmail\nPrint"
-  },
-  {
-   "bold": 1,
-   "fieldname": "mobile",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Mobile",
-   "no_copy": 1,
-   "options": "Phone"
-  },
-  {
-   "bold": 1,
-   "fieldname": "email",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Email",
-   "no_copy": 1,
-   "options": "Email"
-  },
-  {
-   "fieldname": "phone",
-   "fieldtype": "Data",
-   "in_filter": 1,
-   "label": "Phone",
-   "no_copy": 1,
-   "options": "Phone"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "sb_relation",
-   "fieldtype": "Section Break",
-   "label": "Patient Relation"
-  },
-  {
-   "fieldname": "patient_relation",
-   "fieldtype": "Table",
-   "label": "Patient Relation",
-   "options": "Patient Relation"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "allergy_medical_and_surgical_history",
-   "fieldtype": "Section Break",
-   "label": "Allergies, Medical and Surgical History"
-  },
-  {
-   "fieldname": "allergies",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Allergies",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "medication",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Medication",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "column_break_20",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "medical_history",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Medical History",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "surgical_history",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Surgical History",
-   "no_copy": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "personal_and_social_history",
-   "fieldtype": "Section Break",
-   "label": "Personal and Social History"
-  },
-  {
-   "fieldname": "occupation",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "label": "Occupation",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "column_break_25",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "marital_status",
-   "fieldtype": "Select",
-   "label": "Marital Status",
-   "no_copy": 1,
-   "options": "\nSingle\nMarried\nDivorced\nWidow"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "risk_factors",
-   "fieldtype": "Section Break",
-   "label": "Risk Factors"
-  },
-  {
-   "fieldname": "tobacco_past_use",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "label": "Tobacco Consumption (Past)",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "tobacco_current_use",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "label": "Tobacco Consumption (Present)",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "alcohol_past_use",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "label": "Alcohol Consumption (Past)",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "alcohol_current_use",
-   "fieldtype": "Data",
-   "ignore_user_permissions": 1,
-   "label": "Alcohol Consumption (Present)",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "column_break_32",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "surrounding_factors",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Occupational Hazards and Environmental Factors",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "other_risk_factors",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Other Risk Factors",
-   "no_copy": 1
-  },
-  {
-   "collapsible": 1,
-   "collapsible_depends_on": "patient_details",
-   "fieldname": "more_info",
-   "fieldtype": "Section Break",
-   "label": "More Information",
-   "oldfieldtype": "Section Break",
-   "options": "fa fa-file-text"
-  },
-  {
-   "description": "Additional information regarding the patient",
-   "fieldname": "patient_details",
-   "fieldtype": "Text",
-   "ignore_xss_filter": 1,
-   "label": "Patient Details",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "default_currency",
-   "fieldtype": "Link",
-   "label": "Billing Currency",
-   "options": "Currency"
-  },
-  {
-   "fieldname": "last_name",
-   "fieldtype": "Data",
-   "label": "Last Name",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "first_name",
-   "fieldtype": "Data",
-   "label": "First Name",
-   "no_copy": 1,
-   "oldfieldtype": "Data",
-   "reqd": 1
-  },
-  {
-   "fieldname": "middle_name",
-   "fieldtype": "Data",
-   "label": "Middle Name (optional)",
-   "no_copy": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "customer_details_section",
-   "fieldtype": "Section Break",
-   "label": "Customer Details"
-  },
-  {
-   "fieldname": "customer_group",
-   "fieldtype": "Link",
-   "label": "Customer Group",
-   "options": "Customer Group"
-  },
-  {
-   "fieldname": "territory",
-   "fieldtype": "Link",
-   "label": "Territory",
-   "options": "Territory"
-  },
-  {
-   "fieldname": "column_break_24",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "default_price_list",
-   "fieldtype": "Link",
-   "label": "Default Price List",
-   "options": "Price List"
-  },
-  {
-   "fieldname": "language",
-   "fieldtype": "Link",
-   "label": "Print Language",
-   "options": "Language"
-  },
-  {
-   "depends_on": "eval:!doc.__islocal",
-   "fieldname": "address_contacts",
-   "fieldtype": "Section Break",
-   "label": "Address and Contact",
-   "options": "fa fa-map-marker"
-  },
-  {
-   "fieldname": "address_html",
-   "fieldtype": "HTML",
-   "label": "Address HTML",
-   "no_copy": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_22",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "contact_html",
-   "fieldtype": "HTML",
-   "label": "Contact HTML",
-   "no_copy": 1,
-   "read_only": 1
-  },
-  {
-   "allow_in_quick_entry": 1,
-   "default": "1",
-   "fieldname": "invite_user",
-   "fieldtype": "Check",
-   "label": "Invite as User",
-   "no_copy": 1,
-   "read_only_depends_on": "eval: doc.user_id"
-  },
-  {
-   "fieldname": "user_id",
-   "fieldtype": "Read Only",
-   "label": "User ID",
-   "no_copy": 1,
-   "options": "User"
-  },
-  {
-   "allow_in_quick_entry": 1,
-   "bold": 1,
-   "fieldname": "uid",
-   "fieldtype": "Data",
-   "in_standard_filter": 1,
-   "label": "Identification Number (UID)",
-   "unique": 1
-  }
- ],
- "icon": "fa fa-user",
- "image_field": "image",
- "links": [],
- "max_attachments": 50,
- "modified": "2021-03-14 13:21:09.759906",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient",
- "name_case": "Title Case",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Laboratory User",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Nursing User",
-   "share": 1,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "restrict_to_domain": "Healthcare",
- "search_fields": "patient_name,mobile,email,phone,uid",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "ASC",
- "title_field": "patient_name",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient/patient.py b/erpnext/healthcare/doctype/patient/patient.py
deleted file mode 100644
index 970c000..0000000
--- a/erpnext/healthcare/doctype/patient/patient.py
+++ /dev/null
@@ -1,282 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-import dateutil
-import frappe
-from frappe import _
-from frappe.contacts.address_and_contact import load_address_and_contact
-from frappe.contacts.doctype.contact.contact import get_default_contact
-from frappe.model.document import Document
-from frappe.model.naming import set_name_by_naming_series
-from frappe.utils import cint, cstr, getdate
-from frappe.utils.nestedset import get_root_of
-
-from erpnext import get_default_currency
-from erpnext.accounts.party import get_dashboard_info
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import (
-	get_income_account,
-	get_receivable_account,
-	send_registration_sms,
-)
-
-
-class Patient(Document):
-	def onload(self):
-		'''Load address and contacts in `__onload`'''
-		load_address_and_contact(self)
-		self.load_dashboard_info()
-
-	def validate(self):
-		self.set_full_name()
-
-	def before_insert(self):
-		self.set_missing_customer_details()
-
-	def after_insert(self):
-		if frappe.db.get_single_value('Healthcare Settings', 'collect_registration_fee'):
-			frappe.db.set_value('Patient', self.name, 'status', 'Disabled')
-		else:
-			send_registration_sms(self)
-		self.reload() # self.notify_update()
-
-	def on_update(self):
-		if frappe.db.get_single_value('Healthcare Settings', 'link_customer_to_patient'):
-			if self.customer:
-				customer = frappe.get_doc('Customer', self.customer)
-				if self.customer_group:
-					customer.customer_group = self.customer_group
-				if self.territory:
-					customer.territory = self.territory
-				customer.customer_name = self.patient_name
-				customer.default_price_list = self.default_price_list
-				customer.default_currency = self.default_currency
-				customer.language = self.language
-				customer.ignore_mandatory = True
-				customer.save(ignore_permissions=True)
-			else:
-				create_customer(self)
-
-		self.set_contact() # add or update contact
-
-		if not self.user_id and self.email and self.invite_user:
-			self.create_website_user()
-
-	def load_dashboard_info(self):
-		if self.customer:
-			info = get_dashboard_info('Customer', self.customer, None)
-			self.set_onload('dashboard_info', info)
-
-	def set_full_name(self):
-		if self.last_name:
-			self.patient_name = ' '.join(filter(None, [self.first_name, self.last_name]))
-		else:
-			self.patient_name = self.first_name
-
-	def set_missing_customer_details(self):
-		if not self.customer_group:
-			self.customer_group = frappe.db.get_single_value('Selling Settings', 'customer_group') or get_root_of('Customer Group')
-		if not self.territory:
-			self.territory = frappe.db.get_single_value('Selling Settings', 'territory') or get_root_of('Territory')
-		if not self.default_price_list:
-			self.default_price_list = frappe.db.get_single_value('Selling Settings', 'selling_price_list')
-
-		if not self.customer_group or not self.territory or not self.default_price_list:
-			frappe.msgprint(_('Please set defaults for Customer Group, Territory and Selling Price List in Selling Settings'), alert=True)
-
-		if not self.default_currency:
-			self.default_currency = get_default_currency()
-		if not self.language:
-			self.language = frappe.db.get_single_value('System Settings', 'language')
-
-	def create_website_user(self):
-		if self.email and not frappe.db.exists('User', self.email):
-			user = frappe.get_doc({
-				'doctype': 'User',
-				'first_name': self.first_name,
-				'last_name': self.last_name,
-				'email': self.email,
-				'user_type': 'Website User',
-				'gender': self.sex,
-				'phone': self.phone,
-				'mobile_no': self.mobile,
-				'birth_date': self.dob
-			})
-			user.flags.ignore_permissions = True
-			user.enabled = True
-			user.send_welcome_email = True
-			user.add_roles('Patient')
-			frappe.db.set_value(self.doctype, self.name, 'user_id', user.name)
-
-	def autoname(self):
-		patient_name_by = frappe.db.get_single_value('Healthcare Settings', 'patient_name_by')
-		if patient_name_by == 'Patient Name':
-			self.name = self.get_patient_name()
-		else:
-			set_name_by_naming_series(self)
-
-	def get_patient_name(self):
-		self.set_full_name()
-		name = self.patient_name
-		if frappe.db.get_value('Patient', name):
-			count = frappe.db.sql("""select ifnull(MAX(CAST(SUBSTRING_INDEX(name, ' ', -1) AS UNSIGNED)), 0) from tabPatient
-				 where name like %s""", "%{0} - %".format(name), as_list=1)[0][0]
-			count = cint(count) + 1
-			return "{0} - {1}".format(name, cstr(count))
-
-		return name
-
-	@property
-	def age(self):
-		if not self.dob:
-			return
-		dob = getdate(self.dob)
-		age = dateutil.relativedelta.relativedelta(getdate(), dob)
-		return age
-
-	def get_age(self):
-		age = self.age
-		if not age:
-			return
-		age_str = f'{str(age.years)} {_("Years(s)")} {str(age.months)} {_("Month(s)")} {str(age.days)} {_("Day(s)")}'
-		return age_str
-
-	@frappe.whitelist()
-	def invoice_patient_registration(self):
-		if frappe.db.get_single_value('Healthcare Settings', 'registration_fee'):
-			company = frappe.defaults.get_user_default('company')
-			if not company:
-				company = frappe.db.get_single_value('Global Defaults', 'default_company')
-
-			sales_invoice = make_invoice(self.name, company)
-			sales_invoice.save(ignore_permissions=True)
-			frappe.db.set_value('Patient', self.name, 'status', 'Active')
-			send_registration_sms(self)
-
-			return {'invoice': sales_invoice.name}
-
-	def set_contact(self):
-		if frappe.db.exists('Dynamic Link', {'parenttype':'Contact', 'link_doctype':'Patient', 'link_name':self.name}):
-			old_doc = self.get_doc_before_save()
-			if old_doc.email != self.email or old_doc.mobile != self.mobile or old_doc.phone != self.phone:
-				self.update_contact()
-		else:
-			self.reload()
-			if self.email or self.mobile or self.phone:
-				contact = frappe.get_doc({
-					'doctype': 'Contact',
-					'first_name': self.first_name,
-					'middle_name': self.middle_name,
-					'last_name': self.last_name,
-					'gender': self.sex,
-					'is_primary_contact': 1
-				})
-				contact.append('links', dict(link_doctype='Patient', link_name=self.name))
-				if self.customer:
-					contact.append('links', dict(link_doctype='Customer', link_name=self.customer))
-
-				contact.insert(ignore_permissions=True)
-				self.update_contact(contact) # update email, mobile and phone
-
-	def update_contact(self, contact=None):
-		if not contact:
-			contact_name = get_default_contact(self.doctype, self.name)
-			if contact_name:
-				contact = frappe.get_doc('Contact', contact_name)
-
-		if contact:
-			if self.email and self.email != contact.email_id:
-				for email in contact.email_ids:
-					email.is_primary = True if email.email_id == self.email else False
-				contact.add_email(self.email, is_primary=True)
-				contact.set_primary_email()
-
-			if self.mobile and self.mobile != contact.mobile_no:
-				for mobile in contact.phone_nos:
-					mobile.is_primary_mobile_no = True if mobile.phone == self.mobile else False
-				contact.add_phone(self.mobile, is_primary_mobile_no=True)
-				contact.set_primary('mobile_no')
-
-			if self.phone and self.phone != contact.phone:
-				for phone in contact.phone_nos:
-					phone.is_primary_phone = True if phone.phone == self.phone else False
-				contact.add_phone(self.phone, is_primary_phone=True)
-				contact.set_primary('phone')
-
-		contact.flags.ignore_validate = True # disable hook TODO: safe?
-		contact.save(ignore_permissions=True)
-
-
-def create_customer(doc):
-	customer = frappe.get_doc({
-		'doctype': 'Customer',
-		'customer_name': doc.patient_name,
-		'customer_group': doc.customer_group or frappe.db.get_single_value('Selling Settings', 'customer_group'),
-		'territory' : doc.territory or frappe.db.get_single_value('Selling Settings', 'territory'),
-		'customer_type': 'Individual',
-		'default_currency': doc.default_currency,
-		'default_price_list': doc.default_price_list,
-		'language': doc.language
-	}).insert(ignore_permissions=True, ignore_mandatory=True)
-
-	frappe.db.set_value('Patient', doc.name, 'customer', customer.name)
-	frappe.msgprint(_('Customer {0} is created.').format(customer.name), alert=True)
-
-def make_invoice(patient, company):
-	uom = frappe.db.exists('UOM', 'Nos') or frappe.db.get_single_value('Stock Settings', 'stock_uom')
-	sales_invoice = frappe.new_doc('Sales Invoice')
-	sales_invoice.customer = frappe.db.get_value('Patient', patient, 'customer')
-	sales_invoice.due_date = getdate()
-	sales_invoice.company = company
-	sales_invoice.is_pos = 0
-	sales_invoice.debit_to = get_receivable_account(company)
-
-	item_line = sales_invoice.append('items')
-	item_line.item_name = 'Registration Fee'
-	item_line.description = 'Registration Fee'
-	item_line.qty = 1
-	item_line.uom = uom
-	item_line.conversion_factor = 1
-	item_line.income_account = get_income_account(None, company)
-	item_line.rate = frappe.db.get_single_value('Healthcare Settings', 'registration_fee')
-	item_line.amount = item_line.rate
-	sales_invoice.set_missing_values()
-	return sales_invoice
-
-@frappe.whitelist()
-def get_patient_detail(patient):
-	patient_dict = frappe.db.sql("""select * from tabPatient where name=%s""", (patient), as_dict=1)
-	if not patient_dict:
-		frappe.throw(_('Patient not found'))
-	vital_sign = frappe.db.sql("""select * from `tabVital Signs` where patient=%s
-		order by signs_date desc limit 1""", (patient), as_dict=1)
-
-	details = patient_dict[0]
-	if vital_sign:
-		details.update(vital_sign[0])
-	return details
-
-def get_timeline_data(doctype, name):
-	'''
-	Return Patient's timeline data from medical records
-	Also include the associated Customer timeline data
-	'''
-	patient_timeline_data = dict(frappe.db.sql('''
-		SELECT
-			unix_timestamp(communication_date), count(*)
-		FROM
-			`tabPatient Medical Record`
-		WHERE
-			patient=%s
-			and `communication_date` > date_sub(curdate(), interval 1 year)
-		GROUP BY communication_date''', name))
-
-	customer = frappe.db.get_value(doctype, name, 'customer')
-	if customer:
-		from erpnext.accounts.party import get_timeline_data
-		customer_timeline_data = get_timeline_data('Customer', customer)
-		patient_timeline_data.update(customer_timeline_data)
-
-	return patient_timeline_data
diff --git a/erpnext/healthcare/doctype/patient/patient_dashboard.py b/erpnext/healthcare/doctype/patient/patient_dashboard.py
deleted file mode 100644
index a388b74..0000000
--- a/erpnext/healthcare/doctype/patient/patient_dashboard.py
+++ /dev/null
@@ -1,40 +0,0 @@
-from __future__ import unicode_literals
-
-from frappe import _
-
-
-def get_data():
-	return {
-		'heatmap': True,
-		'heatmap_message': _('This is based on transactions against this Patient. See timeline below for details'),
-		'fieldname': 'patient',
-		'non_standard_fieldnames': {
-			'Payment Entry': 'party'
-		},
-		'transactions': [
-			{
-				'label': _('Appointments and Encounters'),
-				'items': ['Patient Appointment', 'Vital Signs', 'Patient Encounter']
-			},
-			{
-				'label': _('Lab Tests and Vital Signs'),
-				'items': ['Lab Test', 'Sample Collection']
-			},
-			{
-				'label': _('Rehab and Physiotherapy'),
-				'items': ['Patient Assessment', 'Therapy Session', 'Therapy Plan']
-			},
-			{
-				'label': _('Surgery'),
-				'items': ['Clinical Procedure']
-			},
-			{
-				'label': _('Admissions'),
-				'items': ['Inpatient Record', 'Inpatient Medication Order']
-			},
-			{
-				'label': _('Billing and Payments'),
-				'items': ['Sales Invoice', 'Payment Entry']
-			}
-		]
-	}
diff --git a/erpnext/healthcare/doctype/patient/test_patient.py b/erpnext/healthcare/doctype/patient/test_patient.py
deleted file mode 100644
index 4b8c732..0000000
--- a/erpnext/healthcare/doctype/patient/test_patient.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-import frappe
-
-from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_patient
-
-
-class TestPatient(unittest.TestCase):
-	def test_customer_created(self):
-		frappe.db.sql("""delete from `tabPatient`""")
-		frappe.db.set_value('Healthcare Settings', None, 'link_customer_to_patient', 1)
-		patient = create_patient()
-		self.assertTrue(frappe.db.get_value('Patient', patient, 'customer'))
-
-	def test_patient_registration(self):
-		frappe.db.sql("""delete from `tabPatient`""")
-		settings = frappe.get_single('Healthcare Settings')
-		settings.collect_registration_fee = 1
-		settings.registration_fee = 500
-		settings.save()
-
-		patient = create_patient()
-		patient = frappe.get_doc('Patient', patient)
-		self.assertEqual(patient.status, 'Disabled')
-
-		# check sales invoice and patient status
-		result = patient.invoice_patient_registration()
-		self.assertTrue(frappe.db.exists('Sales Invoice', result.get('invoice')))
-		self.assertTrue(patient.status, 'Active')
-
-		settings.collect_registration_fee = 0
-		settings.save()
diff --git a/erpnext/healthcare/doctype/patient_appointment/__init__.py b/erpnext/healthcare/doctype/patient_appointment/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/patient_appointment/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
deleted file mode 100644
index 49847d5..0000000
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ /dev/null
@@ -1,657 +0,0 @@
-// Copyright (c) 2016, ESS LLP and contributors
-// For license information, please see license.txt
-frappe.provide('erpnext.queries');
-frappe.ui.form.on('Patient Appointment', {
-	setup: function(frm) {
-		frm.custom_make_buttons = {
-			'Vital Signs': 'Vital Signs',
-			'Patient Encounter': 'Patient Encounter'
-		};
-	},
-
-	onload: function(frm) {
-		if (frm.is_new()) {
-			frm.set_value('appointment_time', null);
-			frm.disable_save();
-		}
-	},
-
-	refresh: function(frm) {
-		frm.set_query('patient', function() {
-			return {
-				filters: { 'status': 'Active' }
-			};
-		});
-
-		frm.set_query('practitioner', function() {
-			if (frm.doc.department) {
-				return {
-					filters: {
-						'department': frm.doc.department
-					}
-				};
-			}
-		});
-
-		frm.set_query('service_unit', function() {
-			return {
-				query: 'erpnext.controllers.queries.get_healthcare_service_units',
-				filters: {
-					company: frm.doc.company,
-					inpatient_record: frm.doc.inpatient_record
-				}
-			};
-		});
-
-		frm.set_query('therapy_plan', function() {
-			return {
-				filters: {
-					'patient': frm.doc.patient
-				}
-			};
-		});
-
-		frm.trigger('set_therapy_type_filter');
-
-		if (frm.is_new()) {
-			frm.page.set_primary_action(__('Check Availability'), function() {
-				if (!frm.doc.patient) {
-					frappe.msgprint({
-						title: __('Not Allowed'),
-						message: __('Please select Patient first'),
-						indicator: 'red'
-					});
-				} else {
-					frappe.call({
-						method: 'erpnext.healthcare.doctype.patient_appointment.patient_appointment.check_payment_fields_reqd',
-						args: { 'patient': frm.doc.patient },
-						callback: function(data) {
-							if (data.message == true) {
-								if (frm.doc.mode_of_payment && frm.doc.paid_amount) {
-									check_and_set_availability(frm);
-								}
-								if (!frm.doc.mode_of_payment) {
-									frappe.msgprint({
-										title: __('Not Allowed'),
-										message: __('Please select a Mode of Payment first'),
-										indicator: 'red'
-									});
-								}
-								if (!frm.doc.paid_amount) {
-									frappe.msgprint({
-										title: __('Not Allowed'),
-										message: __('Please set the Paid Amount first'),
-										indicator: 'red'
-									});
-								}
-							} else {
-								check_and_set_availability(frm);
-							}
-						}
-					});
-				}
-			});
-		} else {
-			frm.page.set_primary_action(__('Save'), () => frm.save());
-		}
-
-		if (frm.doc.patient) {
-			frm.add_custom_button(__('Patient History'), function() {
-				frappe.route_options = { 'patient': frm.doc.patient };
-				frappe.set_route('patient_history');
-			}, __('View'));
-		}
-
-		if (frm.doc.status == 'Open' || (frm.doc.status == 'Scheduled' && !frm.doc.__islocal)) {
-			frm.add_custom_button(__('Cancel'), function() {
-				update_status(frm, 'Cancelled');
-			});
-			frm.add_custom_button(__('Reschedule'), function() {
-				check_and_set_availability(frm);
-			});
-
-			if (frm.doc.procedure_template) {
-				frm.add_custom_button(__('Clinical Procedure'), function() {
-					frappe.model.open_mapped_doc({
-						method: 'erpnext.healthcare.doctype.clinical_procedure.clinical_procedure.make_procedure',
-						frm: frm,
-					});
-				}, __('Create'));
-			} else if (frm.doc.therapy_type) {
-				frm.add_custom_button(__('Therapy Session'), function() {
-					frappe.model.open_mapped_doc({
-						method: 'erpnext.healthcare.doctype.therapy_session.therapy_session.create_therapy_session',
-						frm: frm,
-					})
-				}, 'Create');
-			} else {
-				frm.add_custom_button(__('Patient Encounter'), function() {
-					frappe.model.open_mapped_doc({
-						method: 'erpnext.healthcare.doctype.patient_appointment.patient_appointment.make_encounter',
-						frm: frm,
-					});
-				}, __('Create'));
-			}
-
-			frm.add_custom_button(__('Vital Signs'), function() {
-				create_vital_signs(frm);
-			}, __('Create'));
-		}
-	},
-
-	patient: function(frm) {
-		if (frm.doc.patient) {
-			frm.trigger('toggle_payment_fields');
-			frappe.call({
-				method: 'frappe.client.get',
-				args: {
-					doctype: 'Patient',
-					name: frm.doc.patient
-				},
-				callback: function(data) {
-					let age = null;
-					if (data.message.dob) {
-						age = calculate_age(data.message.dob);
-					}
-					frappe.model.set_value(frm.doctype, frm.docname, 'patient_age', age);
-				}
-			});
-		} else {
-			frm.set_value('patient_name', '');
-			frm.set_value('patient_sex', '');
-			frm.set_value('patient_age', '');
-			frm.set_value('inpatient_record', '');
-		}
-	},
-
-	practitioner: function(frm) {
-		if (frm.doc.practitioner) {
-			frm.events.set_payment_details(frm);
-		}
-	},
-
-	appointment_type: function(frm) {
-		if (frm.doc.appointment_type) {
-			frm.events.set_payment_details(frm);
-		}
-	},
-
-	set_payment_details: function(frm) {
-		frappe.db.get_single_value('Healthcare Settings', 'automate_appointment_invoicing').then(val => {
-			if (val) {
-				frappe.call({
-					method: 'erpnext.healthcare.utils.get_service_item_and_practitioner_charge',
-					args: {
-						doc: frm.doc
-					},
-					callback: function(data) {
-						if (data.message) {
-							frappe.model.set_value(frm.doctype, frm.docname, 'paid_amount', data.message.practitioner_charge);
-							frappe.model.set_value(frm.doctype, frm.docname, 'billing_item', data.message.service_item);
-						}
-					}
-				});
-			}
-		});
-	},
-
-	therapy_plan: function(frm) {
-		frm.trigger('set_therapy_type_filter');
-	},
-
-	set_therapy_type_filter: function(frm) {
-		if (frm.doc.therapy_plan) {
-			frm.call('get_therapy_types').then(r => {
-				frm.set_query('therapy_type', function() {
-					return {
-						filters: {
-							'name': ['in', r.message]
-						}
-					};
-				});
-			});
-		}
-	},
-
-	therapy_type: function(frm) {
-		if (frm.doc.therapy_type) {
-			frappe.db.get_value('Therapy Type', frm.doc.therapy_type, 'default_duration', (r) => {
-				if (r.default_duration) {
-					frm.set_value('duration', r.default_duration)
-				}
-			});
-		}
-	},
-
-	get_procedure_from_encounter: function(frm) {
-		get_prescribed_procedure(frm);
-	},
-
-	toggle_payment_fields: function(frm) {
-		frappe.call({
-			method: 'erpnext.healthcare.doctype.patient_appointment.patient_appointment.check_payment_fields_reqd',
-			args: { 'patient': frm.doc.patient },
-			callback: function(data) {
-				if (data.message.fee_validity) {
-					// if fee validity exists and automated appointment invoicing is enabled,
-					// show payment fields as non-mandatory
-					frm.toggle_display('mode_of_payment', 0);
-					frm.toggle_display('paid_amount', 0);
-					frm.toggle_display('billing_item', 0);
-					frm.toggle_reqd('mode_of_payment', 0);
-					frm.toggle_reqd('paid_amount', 0);
-					frm.toggle_reqd('billing_item', 0);
-				} else if (data.message) {
-					frm.toggle_display('mode_of_payment', 1);
-					frm.toggle_display('paid_amount', 1);
-					frm.toggle_display('billing_item', 1);
-					frm.toggle_reqd('mode_of_payment', 1);
-					frm.toggle_reqd('paid_amount', 1);
-					frm.toggle_reqd('billing_item', 1);
-				} else {
-					// if automated appointment invoicing is disabled, hide fields
-					frm.toggle_display('mode_of_payment', data.message ? 1 : 0);
-					frm.toggle_display('paid_amount', data.message ? 1 : 0);
-					frm.toggle_display('billing_item', data.message ? 1 : 0);
-					frm.toggle_reqd('mode_of_payment', data.message ? 1 : 0);
-					frm.toggle_reqd('paid_amount', data.message ? 1 : 0);
-					frm.toggle_reqd('billing_item', data.message ? 1 : 0);
-				}
-			}
-		});
-	},
-
-	get_prescribed_therapies: function(frm) {
-		if (frm.doc.patient) {
-			frappe.call({
-				method: "erpnext.healthcare.doctype.patient_appointment.patient_appointment.get_prescribed_therapies",
-				args: { patient: frm.doc.patient },
-				callback: function(r) {
-					if (r.message) {
-						show_therapy_types(frm, r.message);
-					} else {
-						frappe.msgprint({
-							title: __('Not Therapies Prescribed'),
-							message: __('There are no Therapies prescribed for Patient {0}', [frm.doc.patient.bold()]),
-							indicator: 'blue'
-						});
-					}
-				}
-			});
-		}
-	}
-});
-
-let check_and_set_availability = function(frm) {
-	let selected_slot = null;
-	let service_unit = null;
-	let duration = null;
-
-	show_availability();
-
-	function show_empty_state(practitioner, appointment_date) {
-		frappe.msgprint({
-			title: __('Not Available'),
-			message: __('Healthcare Practitioner {0} not available on {1}', [practitioner.bold(), appointment_date.bold()]),
-			indicator: 'red'
-		});
-	}
-
-	function show_availability() {
-		let selected_practitioner = '';
-		let d = new frappe.ui.Dialog({
-			title: __('Available slots'),
-			fields: [
-				{ fieldtype: 'Link', options: 'Medical Department', reqd: 1, fieldname: 'department', label: 'Medical Department' },
-				{ fieldtype: 'Column Break' },
-				{ fieldtype: 'Link', options: 'Healthcare Practitioner', reqd: 1, fieldname: 'practitioner', label: 'Healthcare Practitioner' },
-				{ fieldtype: 'Column Break' },
-				{ fieldtype: 'Date', reqd: 1, fieldname: 'appointment_date', label: 'Date' },
-				{ fieldtype: 'Section Break' },
-				{ fieldtype: 'HTML', fieldname: 'available_slots' }
-
-			],
-			primary_action_label: __('Book'),
-			primary_action: function() {
-				frm.set_value('appointment_time', selected_slot);
-				if (!frm.doc.duration) {
-					frm.set_value('duration', duration);
-				}
-				frm.set_value('practitioner', d.get_value('practitioner'));
-				frm.set_value('department', d.get_value('department'));
-				frm.set_value('appointment_date', d.get_value('appointment_date'));
-				if (service_unit) {
-					frm.set_value('service_unit', service_unit);
-				}
-				d.hide();
-				frm.enable_save();
-				frm.save();
-				d.get_primary_btn().attr('disabled', true);
-			}
-		});
-
-		d.set_values({
-			'department': frm.doc.department,
-			'practitioner': frm.doc.practitioner,
-			'appointment_date': frm.doc.appointment_date
-		});
-
-		d.fields_dict['department'].df.onchange = () => {
-			d.set_values({
-				'practitioner': ''
-			});
-			let department = d.get_value('department');
-			if (department) {
-				d.fields_dict.practitioner.get_query = function() {
-					return {
-						filters: {
-							'department': department
-						}
-					};
-				};
-			}
-		};
-
-		// disable dialog action initially
-		d.get_primary_btn().attr('disabled', true);
-
-		// Field Change Handler
-
-		let fd = d.fields_dict;
-
-		d.fields_dict['appointment_date'].df.onchange = () => {
-			show_slots(d, fd);
-		};
-		d.fields_dict['practitioner'].df.onchange = () => {
-			if (d.get_value('practitioner') && d.get_value('practitioner') != selected_practitioner) {
-				selected_practitioner = d.get_value('practitioner');
-				show_slots(d, fd);
-			}
-		};
-		d.show();
-	}
-
-	function show_slots(d, fd) {
-		if (d.get_value('appointment_date') && d.get_value('practitioner')) {
-			fd.available_slots.html('');
-			frappe.call({
-				method: 'erpnext.healthcare.doctype.patient_appointment.patient_appointment.get_availability_data',
-				args: {
-					practitioner: d.get_value('practitioner'),
-					date: d.get_value('appointment_date')
-				},
-				callback: (r) => {
-					let data = r.message;
-					if (data.slot_details.length > 0) {
-						let $wrapper = d.fields_dict.available_slots.$wrapper;
-
-						// make buttons for each slot
-						let slot_html = get_slots(data.slot_details);
-
-						$wrapper
-							.css('margin-bottom', 0)
-							.addClass('text-center')
-							.html(slot_html);
-
-						// highlight button when clicked
-						$wrapper.on('click', 'button', function() {
-							let $btn = $(this);
-							$wrapper.find('button').removeClass('btn-outline-primary');
-							$btn.addClass('btn-outline-primary');
-							selected_slot = $btn.attr('data-name');
-							service_unit = $btn.attr('data-service-unit');
-							duration = $btn.attr('data-duration');
-							// enable primary action 'Book'
-							d.get_primary_btn().attr('disabled', null);
-						});
-
-					} else {
-						//	fd.available_slots.html('Please select a valid date.'.bold())
-						show_empty_state(d.get_value('practitioner'), d.get_value('appointment_date'));
-					}
-				},
-				freeze: true,
-				freeze_message: __('Fetching Schedule...')
-			});
-		} else {
-			fd.available_slots.html(__('Appointment date and Healthcare Practitioner are Mandatory').bold());
-		}
-	}
-
-	function get_slots(slot_details) {
-		let slot_html = '';
-		let appointment_count = 0;
-		let disabled = false;
-		let start_str, slot_start_time, slot_end_time, interval, count, count_class, tool_tip, available_slots;
-
-		slot_details.forEach((slot_info) => {
-			slot_html += `<div class="slot-info">
-				<span> <b> ${__('Practitioner Schedule:')} </b> ${slot_info.slot_name} </span><br>
-				<span> <b> ${__('Service Unit:')} </b> ${slot_info.service_unit} </span>`;
-
-			if (slot_info.service_unit_capacity) {
-				slot_html += `<br><span> <b> ${__('Maximum Capacity:')} </b> ${slot_info.service_unit_capacity} </span>`;
-			}
-
-			slot_html += '</div><br><br>';
-
-			slot_html += slot_info.avail_slot.map(slot => {
-				appointment_count = 0;
-				disabled = false;
-				start_str = slot.from_time;
-				slot_start_time = moment(slot.from_time, 'HH:mm:ss');
-				slot_end_time = moment(slot.to_time, 'HH:mm:ss');
-				interval = (slot_end_time - slot_start_time) / 60000 | 0;
-
-				// iterate in all booked appointments, update the start time and duration
-				slot_info.appointments.forEach((booked) => {
-					let booked_moment = moment(booked.appointment_time, 'HH:mm:ss');
-					let end_time = booked_moment.clone().add(booked.duration, 'minutes');
-
-					// Deal with 0 duration appointments
-					if (booked_moment.isSame(slot_start_time) || booked_moment.isBetween(slot_start_time, slot_end_time)) {
-						if (booked.duration == 0) {
-							disabled = true;
-							return false;
-						}
-					}
-
-					// Check for overlaps considering appointment duration
-					if (slot_info.allow_overlap != 1) {
-						if (slot_start_time.isBefore(end_time) && slot_end_time.isAfter(booked_moment)) {
-							// There is an overlap
-							disabled = true;
-							return false;
-						}
-					} else {
-						if (slot_start_time.isBefore(end_time) && slot_end_time.isAfter(booked_moment)) {
-							appointment_count++;
-						}
-						if (appointment_count >= slot_info.service_unit_capacity) {
-							// There is an overlap
-							disabled = true;
-							return false;
-						}
-					}
-				});
-
-				if (slot_info.allow_overlap == 1 && slot_info.service_unit_capacity > 1) {
-					available_slots = slot_info.service_unit_capacity - appointment_count;
-					count = `${(available_slots > 0 ? available_slots : __('Full'))}`;
-					count_class = `${(available_slots > 0 ? 'badge-success' : 'badge-danger')}`;
-					tool_tip =`${available_slots} ${__('slots available for booking')}`;
-				}
-				return `
-					<button class="btn btn-secondary" data-name=${start_str}
-						data-duration=${interval}
-						data-service-unit="${slot_info.service_unit || ''}"
-						style="margin: 0 10px 10px 0; width: auto;" ${disabled ? 'disabled="disabled"' : ""}
-						data-toggle="tooltip" title="${tool_tip}">
-						${start_str.substring(0, start_str.length - 3)}<br>
-						<span class='badge ${count_class}'> ${count} </span>
-					</button>`;
-			}).join("");
-
-			if (slot_info.service_unit_capacity) {
-				slot_html += `<br/><small>${__('Each slot indicates the capacity currently available for booking')}</small>`;
-			}
-			slot_html += `<br/><br/>`;
-		});
-
-		return slot_html;
-	}
-};
-
-let get_prescribed_procedure = function(frm) {
-	if (frm.doc.patient) {
-		frappe.call({
-			method: 'erpnext.healthcare.doctype.patient_appointment.patient_appointment.get_procedure_prescribed',
-			args: { patient: frm.doc.patient },
-			callback: function(r) {
-				if (r.message && r.message.length) {
-					show_procedure_templates(frm, r.message);
-				} else {
-					frappe.msgprint({
-						title: __('Not Found'),
-						message: __('No Prescribed Procedures found for the selected Patient')
-					});
-				}
-			}
-		});
-	} else {
-		frappe.msgprint({
-			title: __('Not Allowed'),
-			message: __('Please select a Patient first')
-		});
-	}
-};
-
-let show_procedure_templates = function(frm, result) {
-	let d = new frappe.ui.Dialog({
-		title: __('Prescribed Procedures'),
-		fields: [
-			{
-				fieldtype: 'HTML', fieldname: 'procedure_template'
-			}
-		]
-	});
-	let html_field = d.fields_dict.procedure_template.$wrapper;
-	html_field.empty();
-	$.each(result, function(x, y) {
-		let row = $(repl('<div class="col-xs-12" style="padding-top:12px; text-align:center;" >\
-		<div class="col-xs-5"> %(encounter)s <br> %(consulting_practitioner)s <br> %(encounter_date)s </div>\
-		<div class="col-xs-5"> %(procedure_template)s <br>%(practitioner)s  <br> %(date)s</div>\
-		<div class="col-xs-2">\
-		<a data-name="%(name)s" data-procedure-template="%(procedure_template)s"\
-		data-encounter="%(encounter)s" data-practitioner="%(practitioner)s"\
-		data-date="%(date)s"  data-department="%(department)s">\
-		<button class="btn btn-default btn-xs">Add\
-		</button></a></div></div><div class="col-xs-12"><hr/><div/>', {
-			name: y[0], procedure_template: y[1],
-			encounter: y[2], consulting_practitioner: y[3], encounter_date: y[4],
-			practitioner: y[5] ? y[5] : '', date: y[6] ? y[6] : '', department: y[7] ? y[7] : ''
-		})).appendTo(html_field);
-		row.find("a").click(function() {
-			frm.doc.procedure_template = $(this).attr('data-procedure-template');
-			frm.doc.procedure_prescription = $(this).attr('data-name');
-			frm.doc.practitioner = $(this).attr('data-practitioner');
-			frm.doc.appointment_date = $(this).attr('data-date');
-			frm.doc.department = $(this).attr('data-department');
-			refresh_field('procedure_template');
-			refresh_field('procedure_prescription');
-			refresh_field('appointment_date');
-			refresh_field('practitioner');
-			refresh_field('department');
-			d.hide();
-			return false;
-		});
-	});
-	if (!result) {
-		let msg = __('There are no procedure prescribed for ') + frm.doc.patient;
-		$(repl('<div class="col-xs-12" style="padding-top:20px;" >%(msg)s</div></div>', { msg: msg })).appendTo(html_field);
-	}
-	d.show();
-};
-
-let show_therapy_types = function(frm, result) {
-	var d = new frappe.ui.Dialog({
-		title: __('Prescribed Therapies'),
-		fields: [
-			{
-				fieldtype: 'HTML', fieldname: 'therapy_type'
-			}
-		]
-	});
-	var html_field = d.fields_dict.therapy_type.$wrapper;
-	$.each(result, function(x, y) {
-		var row = $(repl('<div class="col-xs-12" style="padding-top:12px; text-align:center;" >\
-		<div class="col-xs-5"> %(encounter)s <br> %(practitioner)s <br> %(date)s </div>\
-		<div class="col-xs-5"> %(therapy)s </div>\
-		<div class="col-xs-2">\
-		<a data-therapy="%(therapy)s" data-therapy-plan="%(therapy_plan)s" data-name="%(name)s"\
-		data-encounter="%(encounter)s" data-practitioner="%(practitioner)s"\
-		data-date="%(date)s"  data-department="%(department)s">\
-		<button class="btn btn-default btn-xs">Add\
-		</button></a></div></div><div class="col-xs-12"><hr/><div/>', {
-			therapy: y[0],
-			name: y[1], encounter: y[2], practitioner: y[3], date: y[4],
-			department: y[6] ? y[6] : '', therapy_plan: y[5]
-		})).appendTo(html_field);
-
-		row.find("a").click(function() {
-			frm.doc.therapy_type = $(this).attr("data-therapy");
-			frm.doc.practitioner = $(this).attr("data-practitioner");
-			frm.doc.department = $(this).attr("data-department");
-			frm.doc.therapy_plan = $(this).attr("data-therapy-plan");
-			frm.refresh_field("therapy_type");
-			frm.refresh_field("practitioner");
-			frm.refresh_field("department");
-			frm.refresh_field("therapy-plan");
-			frappe.db.get_value('Therapy Type', frm.doc.therapy_type, 'default_duration', (r) => {
-				if (r.default_duration) {
-					frm.set_value('duration', r.default_duration)
-				}
-			});
-			d.hide();
-			return false;
-		});
-	});
-	d.show();
-};
-
-let create_vital_signs = function(frm) {
-	if (!frm.doc.patient) {
-		frappe.throw(__('Please select patient'));
-	}
-	frappe.route_options = {
-		'patient': frm.doc.patient,
-		'appointment': frm.doc.name,
-		'company': frm.doc.company
-	};
-	frappe.new_doc('Vital Signs');
-};
-
-let update_status = function(frm, status) {
-	let doc = frm.doc;
-	frappe.confirm(__('Are you sure you want to cancel this appointment?'),
-		function() {
-			frappe.call({
-				method: 'erpnext.healthcare.doctype.patient_appointment.patient_appointment.update_status',
-				args: { appointment_id: doc.name, status: status },
-				callback: function(data) {
-					if (!data.exc) {
-						frm.reload_doc();
-					}
-				}
-			});
-		}
-	);
-};
-
-let calculate_age = function(birth) {
-	let ageMS = Date.parse(Date()) - Date.parse(birth);
-	let age = new Date();
-	age.setTime(ageMS);
-	let years =  age.getFullYear() - 1970;
-	return `${years} ${__('Years(s)')} ${age.getMonth()} ${__('Month(s)')} ${age.getDate()} ${__('Day(s)')}`;
-};
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
deleted file mode 100644
index 28d3a6d..0000000
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
+++ /dev/null
@@ -1,403 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "allow_import": 1,
- "autoname": "naming_series:",
- "beta": 1,
- "creation": "2017-05-04 11:52:40.941507",
- "doctype": "DocType",
- "document_type": "Document",
- "engine": "InnoDB",
- "field_order": [
-  "naming_series",
-  "title",
-  "status",
-  "patient",
-  "patient_name",
-  "patient_sex",
-  "patient_age",
-  "inpatient_record",
-  "column_break_1",
-  "company",
-  "practitioner",
-  "practitioner_name",
-  "department",
-  "service_unit",
-  "section_break_12",
-  "appointment_type",
-  "duration",
-  "procedure_template",
-  "get_procedure_from_encounter",
-  "procedure_prescription",
-  "therapy_plan",
-  "therapy_type",
-  "get_prescribed_therapies",
-  "column_break_17",
-  "appointment_date",
-  "appointment_time",
-  "appointment_datetime",
-  "section_break_16",
-  "mode_of_payment",
-  "billing_item",
-  "invoiced",
-  "column_break_2",
-  "paid_amount",
-  "ref_sales_invoice",
-  "section_break_3",
-  "referring_practitioner",
-  "reminded",
-  "column_break_36",
-  "notes"
- ],
- "fields": [
-  {
-   "fetch_from": "patient.inpatient_record",
-   "fieldname": "inpatient_record",
-   "fieldtype": "Link",
-   "label": "Inpatient Record",
-   "options": "Inpatient Record",
-   "read_only": 1
-  },
-  {
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Patient",
-   "options": "Patient",
-   "reqd": 1,
-   "search_index": 1,
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "appointment_type",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "label": "Appointment Type",
-   "options": "Appointment Type",
-   "set_only_once": 1
-  },
-  {
-   "fetch_from": "appointment_type.default_duration",
-   "fieldname": "duration",
-   "fieldtype": "Int",
-   "in_filter": 1,
-   "label": "Duration (In Minutes)",
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "column_break_1",
-   "fieldtype": "Column Break",
-   "read_only": 1
-  },
-  {
-   "depends_on": "eval:!doc.__islocal",
-   "fieldname": "status",
-   "fieldtype": "Select",
-   "in_filter": 1,
-   "in_list_view": 1,
-   "label": "Status",
-   "options": "\nScheduled\nOpen\nClosed\nCancelled",
-   "read_only": 1,
-   "search_index": 1
-  },
-  {
-   "depends_on": "eval:doc.patient;",
-   "fieldname": "procedure_template",
-   "fieldtype": "Link",
-   "label": "Clinical Procedure Template",
-   "options": "Clinical Procedure Template",
-   "set_only_once": 1
-  },
-  {
-   "depends_on": "eval:doc.__islocal && doc.patient",
-   "fieldname": "get_procedure_from_encounter",
-   "fieldtype": "Button",
-   "label": "Get Prescribed Clinical Procedures"
-  },
-  {
-   "fieldname": "procedure_prescription",
-   "fieldtype": "Link",
-   "hidden": 1,
-   "label": "Procedure Prescription",
-   "no_copy": 1,
-   "options": "Procedure Prescription",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "service_unit",
-   "fieldtype": "Link",
-   "label": "Service Unit",
-   "options": "Healthcare Service Unit",
-   "read_only": 1
-  },
-  {
-   "depends_on": "eval:doc.practitioner;",
-   "fieldname": "section_break_12",
-   "fieldtype": "Section Break",
-   "label": "Appointment Details"
-  },
-  {
-   "fieldname": "practitioner",
-   "fieldtype": "Link",
-   "in_standard_filter": 1,
-   "label": "Healthcare Practitioner",
-   "options": "Healthcare Practitioner",
-   "reqd": 1,
-   "search_index": 1,
-   "set_only_once": 1
-  },
-  {
-   "fetch_from": "practitioner.department",
-   "fieldname": "department",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Department",
-   "options": "Medical Department",
-   "search_index": 1,
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "column_break_17",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "appointment_date",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Date",
-   "read_only": 1,
-   "reqd": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "appointment_time",
-   "fieldtype": "Time",
-   "in_list_view": 1,
-   "label": "Time",
-   "read_only": 1,
-   "reqd": 1
-  },
-  {
-   "fieldname": "section_break_16",
-   "fieldtype": "Section Break",
-   "label": "Payments"
-  },
-  {
-   "fetch_from": "patient.patient_name",
-   "fieldname": "patient_name",
-   "fieldtype": "Data",
-   "label": "Patient Name",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "patient.sex",
-   "fieldname": "patient_sex",
-   "fieldtype": "Link",
-   "label": "Gender",
-   "no_copy": 1,
-   "options": "Gender",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "patient_age",
-   "fieldtype": "Data",
-   "label": "Patient Age",
-   "read_only": 1
-  },
-  {
-   "fieldname": "appointment_datetime",
-   "fieldtype": "Datetime",
-   "hidden": 1,
-   "label": "Appointment Datetime",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "mode_of_payment",
-   "fieldtype": "Link",
-   "label": "Mode of Payment",
-   "options": "Mode of Payment",
-   "read_only_depends_on": "invoiced"
-  },
-  {
-   "fieldname": "paid_amount",
-   "fieldtype": "Currency",
-   "label": "Paid Amount",
-   "read_only_depends_on": "invoiced"
-  },
-  {
-   "fieldname": "column_break_2",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "0",
-   "fieldname": "invoiced",
-   "fieldtype": "Check",
-   "label": "Invoiced",
-   "read_only": 1
-  },
-  {
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "in_standard_filter": 1,
-   "label": "Company",
-   "no_copy": 1,
-   "options": "Company",
-   "reqd": 1,
-   "set_only_once": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "section_break_3",
-   "fieldtype": "Section Break",
-   "label": "More Info"
-  },
-  {
-   "fieldname": "notes",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Notes"
-  },
-  {
-   "fieldname": "referring_practitioner",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "label": "Referring Practitioner",
-   "options": "Healthcare Practitioner"
-  },
-  {
-   "default": "0",
-   "fieldname": "reminded",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "label": "Reminded",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "depends_on": "eval:doc.patient && doc.therapy_plan;",
-   "fieldname": "therapy_type",
-   "fieldtype": "Link",
-   "label": "Therapy",
-   "options": "Therapy Type",
-   "set_only_once": 1
-  },
-  {
-   "depends_on": "eval:doc.patient && doc.therapy_plan && doc.__islocal;",
-   "fieldname": "get_prescribed_therapies",
-   "fieldtype": "Button",
-   "label": "Get Prescribed Therapies"
-  },
-  {
-   "depends_on": "eval: doc.patient;",
-   "fieldname": "therapy_plan",
-   "fieldtype": "Link",
-   "label": "Therapy Plan",
-   "options": "Therapy Plan",
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "ref_sales_invoice",
-   "fieldtype": "Link",
-   "label": "Reference Sales Invoice",
-   "options": "Sales Invoice",
-   "read_only": 1
-  },
-  {
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "label": "Series",
-   "options": "HLC-APP-.YYYY.-",
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "billing_item",
-   "fieldtype": "Link",
-   "label": "Billing Item",
-   "options": "Item",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_36",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "title",
-   "fieldtype": "Data",
-   "hidden": 1,
-   "label": "Title",
-   "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "fetch_from": "practitioner.practitioner_name",
-   "fieldname": "practitioner_name",
-   "fieldtype": "Data",
-   "label": "Practitioner Name",
-   "read_only": 1
-  }
- ],
- "links": [],
- "modified": "2021-08-30 09:00:41.329387",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Appointment",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Nursing User",
-   "share": 1,
-   "write": 1
-  }
- ],
- "restrict_to_domain": "Healthcare",
- "search_fields": "patient, practitioner, department, appointment_date, appointment_time",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "title",
- "track_changes": 1,
- "track_seen": 1
-}
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
deleted file mode 100755
index dcbcda0..0000000
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
+++ /dev/null
@@ -1,559 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-import datetime
-import json
-
-import frappe
-from frappe import _
-from frappe.core.doctype.sms_settings.sms_settings import send_sms
-from frappe.model.document import Document
-from frappe.model.mapper import get_mapped_doc
-from frappe.utils import flt, get_link_to_form, get_time, getdate
-
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import (
-	get_income_account,
-	get_receivable_account,
-)
-from erpnext.healthcare.utils import (
-	check_fee_validity,
-	get_service_item_and_practitioner_charge,
-	manage_fee_validity,
-)
-from erpnext.hr.doctype.employee.employee import is_holiday
-
-
-class MaximumCapacityError(frappe.ValidationError):
-	pass
-class OverlapError(frappe.ValidationError):
-	pass
-
-class PatientAppointment(Document):
-	def validate(self):
-		self.validate_overlaps()
-		self.validate_service_unit()
-		self.set_appointment_datetime()
-		self.validate_customer_created()
-		self.set_status()
-		self.set_title()
-
-	def after_insert(self):
-		self.update_prescription_details()
-		self.set_payment_details()
-		invoice_appointment(self)
-		self.update_fee_validity()
-		send_confirmation_msg(self)
-
-	def set_title(self):
-		self.title = _('{0} with {1}').format(self.patient_name or self.patient,
-			self.practitioner_name or self.practitioner)
-
-	def set_status(self):
-		today = getdate()
-		appointment_date = getdate(self.appointment_date)
-
-		# If appointment is created for today set status as Open else Scheduled
-		if appointment_date == today:
-			self.status = 'Open'
-		elif appointment_date > today:
-			self.status = 'Scheduled'
-
-	def validate_overlaps(self):
-		end_time = datetime.datetime.combine(getdate(self.appointment_date), get_time(self.appointment_time)) \
-			 + datetime.timedelta(minutes=flt(self.duration))
-
-		# all appointments for both patient and practitioner overlapping the duration of this appointment
-		overlapping_appointments = frappe.db.sql("""
-			SELECT
-				name, practitioner, patient, appointment_time, duration, service_unit
-			FROM
-				`tabPatient Appointment`
-			WHERE
-				appointment_date=%(appointment_date)s AND name!=%(name)s AND status NOT IN ("Closed", "Cancelled") AND
-				(practitioner=%(practitioner)s OR patient=%(patient)s) AND
-				((appointment_time<%(appointment_time)s AND appointment_time + INTERVAL duration MINUTE>%(appointment_time)s) OR
-				(appointment_time>%(appointment_time)s AND appointment_time<%(end_time)s) OR
-				(appointment_time=%(appointment_time)s))
-			""",
-			{
-				'appointment_date': self.appointment_date,
-				'name': self.name,
-				'practitioner': self.practitioner,
-				'patient': self.patient,
-				'appointment_time': self.appointment_time,
-				'end_time':end_time.time()
-			},
-			as_dict = True
-		)
-
-		if not overlapping_appointments:
-			return # No overlaps, nothing to validate!
-
-		if self.service_unit: # validate service unit capacity if overlap enabled
-			allow_overlap, service_unit_capacity = frappe.get_value('Healthcare Service Unit', self.service_unit,
-				['overlap_appointments', 'service_unit_capacity'])
-			if allow_overlap:
-				service_unit_appointments = list(filter(lambda appointment: appointment['service_unit'] == self.service_unit and
-					appointment['patient'] != self.patient, overlapping_appointments)) # if same patient already booked, it should be an overlap
-				if len(service_unit_appointments) >= (service_unit_capacity or 1):
-					frappe.throw(_("Not allowed, {} cannot exceed maximum capacity {}")
-						.format(frappe.bold(self.service_unit), frappe.bold(service_unit_capacity or 1)), MaximumCapacityError)
-				else: # service_unit_appointments within capacity, remove from overlapping_appointments
-					overlapping_appointments = [appointment for appointment in overlapping_appointments if appointment not in service_unit_appointments]
-
-		if overlapping_appointments:
-			frappe.throw(_("Not allowed, cannot overlap appointment {}")
-				.format(frappe.bold(', '.join([appointment['name'] for appointment in overlapping_appointments]))), OverlapError)
-
-
-	def validate_service_unit(self):
-		if self.inpatient_record and self.service_unit:
-			from erpnext.healthcare.doctype.inpatient_medication_entry.inpatient_medication_entry import (
-				get_current_healthcare_service_unit,
-			)
-
-			is_inpatient_occupancy_unit = frappe.db.get_value('Healthcare Service Unit', self.service_unit,
-				'inpatient_occupancy')
-			service_unit = get_current_healthcare_service_unit(self.inpatient_record)
-			if is_inpatient_occupancy_unit and service_unit != self.service_unit:
-				msg = _('Patient {0} is not admitted in the service unit {1}').format(frappe.bold(self.patient), frappe.bold(self.service_unit)) + '<br>'
-				msg += _('Appointment for service units with Inpatient Occupancy can only be created against the unit where patient has been admitted.')
-				frappe.throw(msg, title=_('Invalid Healthcare Service Unit'))
-
-
-	def set_appointment_datetime(self):
-		self.appointment_datetime = "%s %s" % (self.appointment_date, self.appointment_time or "00:00:00")
-
-	def set_payment_details(self):
-		if frappe.db.get_single_value('Healthcare Settings', 'automate_appointment_invoicing'):
-			details = get_service_item_and_practitioner_charge(self)
-			self.db_set('billing_item', details.get('service_item'))
-			if not self.paid_amount:
-				self.db_set('paid_amount', details.get('practitioner_charge'))
-
-	def validate_customer_created(self):
-		if frappe.db.get_single_value('Healthcare Settings', 'automate_appointment_invoicing'):
-			if not frappe.db.get_value('Patient', self.patient, 'customer'):
-				msg = _("Please set a Customer linked to the Patient")
-				msg +=  " <b><a href='/app/Form/Patient/{0}'>{0}</a></b>".format(self.patient)
-				frappe.throw(msg, title=_('Customer Not Found'))
-
-	def update_prescription_details(self):
-		if self.procedure_prescription:
-			frappe.db.set_value('Procedure Prescription', self.procedure_prescription, 'appointment_booked', 1)
-			if self.procedure_template:
-				comments = frappe.db.get_value('Procedure Prescription', self.procedure_prescription, 'comments')
-				if comments:
-					frappe.db.set_value('Patient Appointment', self.name, 'notes', comments)
-
-	def update_fee_validity(self):
-		if not frappe.db.get_single_value('Healthcare Settings', 'enable_free_follow_ups'):
-			return
-
-		fee_validity = manage_fee_validity(self)
-		if fee_validity:
-			frappe.msgprint(_('{0}: {1} has fee validity till {2}').format(self.patient,
-				frappe.bold(self.patient_name), fee_validity.valid_till))
-
-	@frappe.whitelist()
-	def get_therapy_types(self):
-		if not self.therapy_plan:
-			return
-
-		therapy_types = []
-		doc = frappe.get_doc('Therapy Plan', self.therapy_plan)
-		for entry in doc.therapy_plan_details:
-			therapy_types.append(entry.therapy_type)
-
-		return therapy_types
-
-
-@frappe.whitelist()
-def check_payment_fields_reqd(patient):
-	automate_invoicing = frappe.db.get_single_value('Healthcare Settings', 'automate_appointment_invoicing')
-	free_follow_ups = frappe.db.get_single_value('Healthcare Settings', 'enable_free_follow_ups')
-	if automate_invoicing:
-		if free_follow_ups:
-			fee_validity = frappe.db.exists('Fee Validity', {'patient': patient, 'status': 'Pending'})
-			if fee_validity:
-				return {'fee_validity': fee_validity}
-		return True
-	return False
-
-def invoice_appointment(appointment_doc):
-	automate_invoicing = frappe.db.get_single_value('Healthcare Settings', 'automate_appointment_invoicing')
-	appointment_invoiced = frappe.db.get_value('Patient Appointment', appointment_doc.name, 'invoiced')
-	enable_free_follow_ups = frappe.db.get_single_value('Healthcare Settings', 'enable_free_follow_ups')
-	if enable_free_follow_ups:
-		fee_validity = check_fee_validity(appointment_doc)
-		if fee_validity and fee_validity.status == 'Completed':
-			fee_validity = None
-		elif not fee_validity:
-			if frappe.db.exists('Fee Validity Reference', {'appointment': appointment_doc.name}):
-				return
-	else:
-		fee_validity = None
-
-	if automate_invoicing and not appointment_invoiced and not fee_validity:
-		create_sales_invoice(appointment_doc)
-
-
-def create_sales_invoice(appointment_doc):
-	sales_invoice = frappe.new_doc('Sales Invoice')
-	sales_invoice.patient = appointment_doc.patient
-	sales_invoice.customer = frappe.get_value('Patient', appointment_doc.patient, 'customer')
-	sales_invoice.appointment = appointment_doc.name
-	sales_invoice.due_date = getdate()
-	sales_invoice.company = appointment_doc.company
-	sales_invoice.debit_to = get_receivable_account(appointment_doc.company)
-
-	item = sales_invoice.append('items', {})
-	item = get_appointment_item(appointment_doc, item)
-
-	# Add payments if payment details are supplied else proceed to create invoice as Unpaid
-	if appointment_doc.mode_of_payment and appointment_doc.paid_amount:
-		sales_invoice.is_pos = 1
-		payment = sales_invoice.append('payments', {})
-		payment.mode_of_payment = appointment_doc.mode_of_payment
-		payment.amount = appointment_doc.paid_amount
-
-	sales_invoice.set_missing_values(for_validate=True)
-	sales_invoice.flags.ignore_mandatory = True
-	sales_invoice.save(ignore_permissions=True)
-	sales_invoice.submit()
-	frappe.msgprint(_('Sales Invoice {0} created').format(sales_invoice.name), alert=True)
-	frappe.db.set_value('Patient Appointment', appointment_doc.name, {
-		'invoiced': 1,
-		'ref_sales_invoice': sales_invoice.name
-	})
-
-
-def check_is_new_patient(patient, name=None):
-	filters = {'patient': patient, 'status': ('!=','Cancelled')}
-	if name:
-		filters['name'] = ('!=', name)
-
-	has_previous_appointment = frappe.db.exists('Patient Appointment', filters)
-	return not has_previous_appointment
-
-
-def get_appointment_item(appointment_doc, item):
-	details = get_service_item_and_practitioner_charge(appointment_doc)
-	charge = appointment_doc.paid_amount or details.get('practitioner_charge')
-	item.item_code = details.get('service_item')
-	item.description = _('Consulting Charges: {0}').format(appointment_doc.practitioner)
-	item.income_account = get_income_account(appointment_doc.practitioner, appointment_doc.company)
-	item.cost_center = frappe.get_cached_value('Company', appointment_doc.company, 'cost_center')
-	item.rate = charge
-	item.amount = charge
-	item.qty = 1
-	item.reference_dt = 'Patient Appointment'
-	item.reference_dn = appointment_doc.name
-	return item
-
-
-def cancel_appointment(appointment_id):
-	appointment = frappe.get_doc('Patient Appointment', appointment_id)
-	if appointment.invoiced:
-		sales_invoice = check_sales_invoice_exists(appointment)
-		if sales_invoice and cancel_sales_invoice(sales_invoice):
-			msg = _('Appointment {0} and Sales Invoice {1} cancelled').format(appointment.name, sales_invoice.name)
-		else:
-			msg = _('Appointment Cancelled. Please review and cancel the invoice {0}').format(sales_invoice.name)
-	else:
-		fee_validity = manage_fee_validity(appointment)
-		msg = _('Appointment Cancelled.')
-		if fee_validity:
-			msg += _('Fee Validity {0} updated.').format(fee_validity.name)
-
-	frappe.msgprint(msg)
-
-
-def cancel_sales_invoice(sales_invoice):
-	if frappe.db.get_single_value('Healthcare Settings', 'automate_appointment_invoicing'):
-		if len(sales_invoice.items) == 1:
-			sales_invoice.cancel()
-			return True
-	return False
-
-
-def check_sales_invoice_exists(appointment):
-	sales_invoice = frappe.db.get_value('Sales Invoice Item', {
-		'reference_dt': 'Patient Appointment',
-		'reference_dn': appointment.name
-	}, 'parent')
-
-	if sales_invoice:
-		sales_invoice = frappe.get_doc('Sales Invoice', sales_invoice)
-		return sales_invoice
-	return False
-
-
-@frappe.whitelist()
-def get_availability_data(date, practitioner):
-	"""
-	Get availability data of 'practitioner' on 'date'
-	:param date: Date to check in schedule
-	:param practitioner: Name of the practitioner
-	:return: dict containing a list of available slots, list of appointments and time of appointments
-	"""
-
-	date = getdate(date)
-	weekday = date.strftime('%A')
-
-	practitioner_doc = frappe.get_doc('Healthcare Practitioner', practitioner)
-
-	check_employee_wise_availability(date, practitioner_doc)
-
-	if practitioner_doc.practitioner_schedules:
-		slot_details = get_available_slots(practitioner_doc, date)
-	else:
-		frappe.throw(_('{0} does not have a Healthcare Practitioner Schedule. Add it in Healthcare Practitioner master').format(
-			practitioner), title=_('Practitioner Schedule Not Found'))
-
-
-	if not slot_details:
-		# TODO: return available slots in nearby dates
-		frappe.throw(_('Healthcare Practitioner not available on {0}').format(weekday), title=_('Not Available'))
-
-	return {'slot_details': slot_details}
-
-
-def check_employee_wise_availability(date, practitioner_doc):
-	employee = None
-	if practitioner_doc.employee:
-		employee = practitioner_doc.employee
-	elif practitioner_doc.user_id:
-		employee = frappe.db.get_value('Employee', {'user_id': practitioner_doc.user_id}, 'name')
-
-	if employee:
-		# check holiday
-		if is_holiday(employee, date):
-			frappe.throw(_('{0} is a holiday'.format(date)), title=_('Not Available'))
-
-		# check leave status
-		leave_record = frappe.db.sql("""select half_day from `tabLeave Application`
-			where employee = %s and %s between from_date and to_date
-			and docstatus = 1""", (employee, date), as_dict=True)
-		if leave_record:
-			if leave_record[0].half_day:
-				frappe.throw(_('{0} is on a Half day Leave on {1}').format(practitioner_doc.name, date), title=_('Not Available'))
-			else:
-				frappe.throw(_('{0} is on Leave on {1}').format(practitioner_doc.name, date), title=_('Not Available'))
-
-
-def get_available_slots(practitioner_doc, date):
-	available_slots = slot_details = []
-	weekday = date.strftime('%A')
-	practitioner = practitioner_doc.name
-
-	for schedule_entry in practitioner_doc.practitioner_schedules:
-		validate_practitioner_schedules(schedule_entry, practitioner)
-		practitioner_schedule = frappe.get_doc('Practitioner Schedule', schedule_entry.schedule)
-
-		if practitioner_schedule:
-			available_slots = []
-			for time_slot in practitioner_schedule.time_slots:
-				if weekday == time_slot.day:
-					available_slots.append(time_slot)
-
-			if available_slots:
-				appointments = []
-				allow_overlap = 0
-				service_unit_capacity = 0
-				# fetch all appointments to practitioner by service unit
-				filters = {
-					'practitioner': practitioner,
-					'service_unit': schedule_entry.service_unit,
-					'appointment_date': date,
-					'status': ['not in',['Cancelled']]
-				}
-
-				if schedule_entry.service_unit:
-					slot_name = f'{schedule_entry.schedule}'
-					allow_overlap, service_unit_capacity = frappe.get_value('Healthcare Service Unit', schedule_entry.service_unit, ['overlap_appointments', 'service_unit_capacity'])
-					if not allow_overlap:
-						# fetch all appointments to service unit
-						filters.pop('practitioner')
-				else:
-					slot_name = schedule_entry.schedule
-					# fetch all appointments to practitioner without service unit
-					filters['practitioner'] = practitioner
-					filters.pop('service_unit')
-
-				appointments = frappe.get_all(
-					'Patient Appointment',
-					filters=filters,
-					fields=['name', 'appointment_time', 'duration', 'status'])
-
-				slot_details.append({'slot_name': slot_name, 'service_unit': schedule_entry.service_unit, 'avail_slot': available_slots,
-					'appointments': appointments,  'allow_overlap': allow_overlap, 'service_unit_capacity': service_unit_capacity})
-
-	return slot_details
-
-
-def validate_practitioner_schedules(schedule_entry, practitioner):
-	if schedule_entry.schedule:
-		if not schedule_entry.service_unit:
-			frappe.throw(_('Practitioner {0} does not have a Service Unit set against the Practitioner Schedule {1}.').format(
-				get_link_to_form('Healthcare Practitioner', practitioner), frappe.bold(schedule_entry.schedule)),
-				title=_('Service Unit Not Found'))
-
-	else:
-		frappe.throw(_('Practitioner {0} does not have a Practitioner Schedule assigned.').format(
-			get_link_to_form('Healthcare Practitioner', practitioner)),
-			title=_('Practitioner Schedule Not Found'))
-
-
-@frappe.whitelist()
-def update_status(appointment_id, status):
-	frappe.db.set_value('Patient Appointment', appointment_id, 'status', status)
-	appointment_booked = True
-	if status == 'Cancelled':
-		appointment_booked = False
-		cancel_appointment(appointment_id)
-
-	procedure_prescription = frappe.db.get_value('Patient Appointment', appointment_id, 'procedure_prescription')
-	if procedure_prescription:
-		frappe.db.set_value('Procedure Prescription', procedure_prescription, 'appointment_booked', appointment_booked)
-
-
-def send_confirmation_msg(doc):
-	if frappe.db.get_single_value('Healthcare Settings', 'send_appointment_confirmation'):
-		message = frappe.db.get_single_value('Healthcare Settings', 'appointment_confirmation_msg')
-		try:
-			send_message(doc, message)
-		except Exception:
-			frappe.log_error(frappe.get_traceback(), _('Appointment Confirmation Message Not Sent'))
-			frappe.msgprint(_('Appointment Confirmation Message Not Sent'), indicator='orange')
-
-
-@frappe.whitelist()
-def make_encounter(source_name, target_doc=None):
-	doc = get_mapped_doc('Patient Appointment', source_name, {
-		'Patient Appointment': {
-			'doctype': 'Patient Encounter',
-			'field_map': [
-				['appointment', 'name'],
-				['patient', 'patient'],
-				['practitioner', 'practitioner'],
-				['medical_department', 'department'],
-				['patient_sex', 'patient_sex'],
-				['invoiced', 'invoiced'],
-				['company', 'company']
-			]
-		}
-	}, target_doc)
-	return doc
-
-
-def send_appointment_reminder():
-	if frappe.db.get_single_value('Healthcare Settings', 'send_appointment_reminder'):
-		remind_before = datetime.datetime.strptime(frappe.db.get_single_value('Healthcare Settings', 'remind_before'), '%H:%M:%S')
-		reminder_dt = datetime.datetime.now() + datetime.timedelta(
-			hours=remind_before.hour, minutes=remind_before.minute, seconds=remind_before.second)
-
-		appointment_list = frappe.db.get_all('Patient Appointment', {
-			'appointment_datetime': ['between', (datetime.datetime.now(), reminder_dt)],
-			'reminded': 0,
-			'status': ['!=', 'Cancelled']
-		})
-
-		for appointment in appointment_list:
-			doc = frappe.get_doc('Patient Appointment', appointment.name)
-			message = frappe.db.get_single_value('Healthcare Settings', 'appointment_reminder_msg')
-			send_message(doc, message)
-			frappe.db.set_value('Patient Appointment', doc.name, 'reminded', 1)
-
-def send_message(doc, message):
-	patient_mobile = frappe.db.get_value('Patient', doc.patient, 'mobile')
-	if patient_mobile:
-		context = {'doc': doc, 'alert': doc, 'comments': None}
-		if doc.get('_comments'):
-			context['comments'] = json.loads(doc.get('_comments'))
-
-		# jinja to string convertion happens here
-		message = frappe.render_template(message, context)
-		number = [patient_mobile]
-		try:
-			send_sms(number, message)
-		except Exception as e:
-			frappe.msgprint(_('SMS not sent, please check SMS Settings'), alert=True)
-
-@frappe.whitelist()
-def get_events(start, end, filters=None):
-	"""Returns events for Gantt / Calendar view rendering.
-
-	:param start: Start date-time.
-	:param end: End date-time.
-	:param filters: Filters (JSON).
-	"""
-	from frappe.desk.calendar import get_event_conditions
-	conditions = get_event_conditions('Patient Appointment', filters)
-
-	data = frappe.db.sql("""
-		select
-		`tabPatient Appointment`.name, `tabPatient Appointment`.patient,
-		`tabPatient Appointment`.practitioner, `tabPatient Appointment`.status,
-		`tabPatient Appointment`.duration,
-		timestamp(`tabPatient Appointment`.appointment_date, `tabPatient Appointment`.appointment_time) as 'start',
-		`tabAppointment Type`.color
-		from
-		`tabPatient Appointment`
-		left join `tabAppointment Type` on `tabPatient Appointment`.appointment_type=`tabAppointment Type`.name
-		where
-		(`tabPatient Appointment`.appointment_date between %(start)s and %(end)s)
-		and `tabPatient Appointment`.status != 'Cancelled' and `tabPatient Appointment`.docstatus < 2 {conditions}""".format(conditions=conditions),
-		{"start": start, "end": end}, as_dict=True, update={"allDay": 0})
-
-	for item in data:
-		item.end = item.start + datetime.timedelta(minutes = item.duration)
-
-	return data
-
-
-@frappe.whitelist()
-def get_procedure_prescribed(patient):
-	return frappe.db.sql(
-		"""
-			SELECT
-				pp.name, pp.procedure, pp.parent, ct.practitioner,
-				ct.encounter_date, pp.practitioner, pp.date, pp.department
-			FROM
-				`tabPatient Encounter` ct, `tabProcedure Prescription` pp
-			WHERE
-				ct.patient=%(patient)s and pp.parent=ct.name and pp.appointment_booked=0
-			ORDER BY
-				ct.creation desc
-		""", {'patient': patient}
-	)
-
-
-@frappe.whitelist()
-def get_prescribed_therapies(patient):
-	return frappe.db.sql(
-		"""
-			SELECT
-				t.therapy_type, t.name, t.parent, e.practitioner,
-				e.encounter_date, e.therapy_plan, e.medical_department
-			FROM
-				`tabPatient Encounter` e, `tabTherapy Plan Detail` t
-			WHERE
-				e.patient=%(patient)s and t.parent=e.name
-			ORDER BY
-				e.creation desc
-		""", {'patient': patient}
-	)
-
-
-def update_appointment_status():
-	# update the status of appointments daily
-	appointments = frappe.get_all('Patient Appointment', {
-		'status': ('not in', ['Closed', 'Cancelled'])
-	}, as_dict=1)
-
-	for appointment in appointments:
-		frappe.get_doc('Patient Appointment', appointment.name).set_status()
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_calendar.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment_calendar.js
deleted file mode 100644
index 2249d2a..0000000
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_calendar.js
+++ /dev/null
@@ -1,14 +0,0 @@
-
-frappe.views.calendar["Patient Appointment"] = {
-	field_map: {
-		"start": "start",
-		"end": "end",
-		"id": "name",
-		"title": "patient",
-		"allDay": "allDay",
-		"eventColor": "color"
-	},
-	order_by: "appointment_date",
-	gantt: true,
-	get_events_method: "erpnext.healthcare.doctype.patient_appointment.patient_appointment.get_events"
-};
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_dashboard.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment_dashboard.py
deleted file mode 100644
index 43c63c9..0000000
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_dashboard.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from __future__ import unicode_literals
-
-from frappe import _
-
-
-def get_data():
-	return {
-		'fieldname': 'appointment',
-		'non_standard_fieldnames': {
-			'Patient Medical Record': 'reference_name'
-		},
-		'transactions': [
-			{
-				'label': _('Consultations'),
-				'items': ['Patient Encounter', 'Vital Signs', 'Patient Medical Record']
-			}
-		]
-	}
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_list.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment_list.js
deleted file mode 100644
index 721887b..0000000
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_list.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
-(c) ESS 2015-16
-*/
-frappe.listview_settings['Patient Appointment'] = {
-	filters: [["status", "=", "Open"]],
-	get_indicator: function(doc) {
-		var colors = {
-			"Open": "orange",
-			"Scheduled": "yellow",
-			"Closed": "green",
-			"Cancelled": "red",
-			"Expired": "grey"
-		};
-		return [__(doc.status), colors[doc.status], "status,=," + doc.status];
-	}
-};
diff --git a/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py
deleted file mode 100644
index 8ca30b8..0000000
--- a/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py
+++ /dev/null
@@ -1,487 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-import frappe
-from frappe.utils import add_days, now_datetime, nowdate
-
-from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
-from erpnext.healthcare.doctype.patient_appointment.patient_appointment import (
-	check_is_new_patient,
-	check_payment_fields_reqd,
-	make_encounter,
-	update_status,
-)
-
-
-class TestPatientAppointment(unittest.TestCase):
-	def setUp(self):
-		frappe.db.sql("""delete from `tabPatient Appointment`""")
-		frappe.db.sql("""delete from `tabFee Validity`""")
-		frappe.db.sql("""delete from `tabPatient Encounter`""")
-		make_pos_profile()
-		frappe.db.sql("""delete from `tabHealthcare Service Unit` where name like '_Test %'""")
-		frappe.db.sql("""delete from `tabHealthcare Service Unit` where name like '_Test Service Unit Type%'""")
-
-	def test_status(self):
-		patient, practitioner = create_healthcare_docs()
-		frappe.db.set_value('Healthcare Settings', None, 'automate_appointment_invoicing', 0)
-		appointment = create_appointment(patient, practitioner, nowdate())
-		self.assertEqual(appointment.status, 'Open')
-		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 2))
-		self.assertEqual(appointment.status, 'Scheduled')
-		encounter = create_encounter(appointment)
-		self.assertEqual(frappe.db.get_value('Patient Appointment', appointment.name, 'status'), 'Closed')
-		encounter.cancel()
-		self.assertEqual(frappe.db.get_value('Patient Appointment', appointment.name, 'status'), 'Open')
-
-	def test_start_encounter(self):
-		patient, practitioner = create_healthcare_docs()
-		frappe.db.set_value('Healthcare Settings', None, 'automate_appointment_invoicing', 1)
-		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 4), invoice = 1)
-		appointment.reload()
-		self.assertEqual(appointment.invoiced, 1)
-		encounter = make_encounter(appointment.name)
-		self.assertTrue(encounter)
-		self.assertEqual(encounter.company, appointment.company)
-		self.assertEqual(encounter.practitioner, appointment.practitioner)
-		self.assertEqual(encounter.patient, appointment.patient)
-		# invoiced flag mapped from appointment
-		self.assertEqual(encounter.invoiced, frappe.db.get_value('Patient Appointment', appointment.name, 'invoiced'))
-
-	def test_auto_invoicing(self):
-		patient, practitioner = create_healthcare_docs()
-		frappe.db.set_value('Healthcare Settings', None, 'enable_free_follow_ups', 0)
-		frappe.db.set_value('Healthcare Settings', None, 'automate_appointment_invoicing', 0)
-		appointment = create_appointment(patient, practitioner, nowdate())
-		self.assertEqual(frappe.db.get_value('Patient Appointment', appointment.name, 'invoiced'), 0)
-
-		frappe.db.set_value('Healthcare Settings', None, 'automate_appointment_invoicing', 1)
-		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 2), invoice=1)
-		self.assertEqual(frappe.db.get_value('Patient Appointment', appointment.name, 'invoiced'), 1)
-		sales_invoice_name = frappe.db.get_value('Sales Invoice Item', {'reference_dn': appointment.name}, 'parent')
-		self.assertTrue(sales_invoice_name)
-		self.assertEqual(frappe.db.get_value('Sales Invoice', sales_invoice_name, 'company'), appointment.company)
-		self.assertEqual(frappe.db.get_value('Sales Invoice', sales_invoice_name, 'patient'), appointment.patient)
-		self.assertEqual(frappe.db.get_value('Sales Invoice', sales_invoice_name, 'paid_amount'), appointment.paid_amount)
-
-	def test_auto_invoicing_based_on_department(self):
-		patient, practitioner = create_healthcare_docs()
-		medical_department = create_medical_department()
-		frappe.db.set_value('Healthcare Settings', None, 'enable_free_follow_ups', 0)
-		frappe.db.set_value('Healthcare Settings', None, 'automate_appointment_invoicing', 1)
-		appointment_type = create_appointment_type({'medical_department': medical_department})
-
-		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 2),
-			invoice=1, appointment_type=appointment_type.name, department=medical_department)
-		appointment.reload()
-
-		self.assertEqual(appointment.invoiced, 1)
-		self.assertEqual(appointment.billing_item, 'HLC-SI-001')
-		self.assertEqual(appointment.paid_amount, 200)
-
-		sales_invoice_name = frappe.db.get_value('Sales Invoice Item', {'reference_dn': appointment.name}, 'parent')
-		self.assertTrue(sales_invoice_name)
-		self.assertEqual(frappe.db.get_value('Sales Invoice', sales_invoice_name, 'paid_amount'), appointment.paid_amount)
-
-	def test_auto_invoicing_according_to_appointment_type_charge(self):
-		patient, practitioner = create_healthcare_docs()
-		frappe.db.set_value('Healthcare Settings', None, 'enable_free_follow_ups', 0)
-		frappe.db.set_value('Healthcare Settings', None, 'automate_appointment_invoicing', 1)
-
-		item = create_healthcare_service_items()
-		items = [{
-				'op_consulting_charge_item': item,
-				'op_consulting_charge': 300
-		}]
-		appointment_type = create_appointment_type(args={
-			'name': 'Generic Appointment Type charge',
-			'items': items
-		})
-
-		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 2),
-			invoice=1, appointment_type=appointment_type.name)
-		appointment.reload()
-
-		self.assertEqual(appointment.invoiced, 1)
-		self.assertEqual(appointment.billing_item, item)
-		self.assertEqual(appointment.paid_amount, 300)
-
-		sales_invoice_name = frappe.db.get_value('Sales Invoice Item', {'reference_dn': appointment.name}, 'parent')
-		self.assertTrue(sales_invoice_name)
-
-	def test_appointment_cancel(self):
-		patient, practitioner = create_healthcare_docs()
-		frappe.db.set_value('Healthcare Settings', None, 'enable_free_follow_ups', 1)
-		appointment = create_appointment(patient, practitioner, nowdate())
-		fee_validity = frappe.db.get_value('Fee Validity', {'patient': patient, 'practitioner': practitioner})
-		# fee validity created
-		self.assertTrue(fee_validity)
-
-		# first follow up appointment
-		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 1))
-		self.assertEqual(frappe.db.get_value('Fee Validity', fee_validity, 'visited'), 1)
-
-		update_status(appointment.name, 'Cancelled')
-		# check fee validity updated
-		self.assertEqual(frappe.db.get_value('Fee Validity', fee_validity, 'visited'), 0)
-
-		frappe.db.set_value('Healthcare Settings', None, 'enable_free_follow_ups', 0)
-		frappe.db.set_value('Healthcare Settings', None, 'automate_appointment_invoicing', 1)
-		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 1), invoice=1)
-		update_status(appointment.name, 'Cancelled')
-		# check invoice cancelled
-		sales_invoice_name = frappe.db.get_value('Sales Invoice Item', {'reference_dn': appointment.name}, 'parent')
-		self.assertEqual(frappe.db.get_value('Sales Invoice', sales_invoice_name, 'status'), 'Cancelled')
-
-	def test_appointment_booking_for_admission_service_unit(self):
-		from erpnext.healthcare.doctype.inpatient_record.inpatient_record import (
-			admit_patient,
-			discharge_patient,
-			schedule_discharge,
-		)
-		from erpnext.healthcare.doctype.inpatient_record.test_inpatient_record import (
-			create_inpatient,
-			get_healthcare_service_unit,
-			mark_invoiced_inpatient_occupancy,
-		)
-
-		frappe.db.sql("""delete from `tabInpatient Record`""")
-		patient, practitioner = create_healthcare_docs()
-		patient = create_patient()
-		# Schedule Admission
-		ip_record = create_inpatient(patient)
-		ip_record.expected_length_of_stay = 0
-		ip_record.save(ignore_permissions = True)
-
-		# Admit
-		service_unit = get_healthcare_service_unit('_Test Service Unit Ip Occupancy')
-		admit_patient(ip_record, service_unit, now_datetime())
-
-		appointment = create_appointment(patient, practitioner, nowdate(), service_unit=service_unit)
-		self.assertEqual(appointment.service_unit, service_unit)
-
-		# Discharge
-		schedule_discharge(frappe.as_json({'patient': patient}))
-		ip_record1 = frappe.get_doc("Inpatient Record", ip_record.name)
-		mark_invoiced_inpatient_occupancy(ip_record1)
-		discharge_patient(ip_record1)
-
-	def test_invalid_healthcare_service_unit_validation(self):
-		from erpnext.healthcare.doctype.inpatient_record.inpatient_record import (
-			admit_patient,
-			discharge_patient,
-			schedule_discharge,
-		)
-		from erpnext.healthcare.doctype.inpatient_record.test_inpatient_record import (
-			create_inpatient,
-			get_healthcare_service_unit,
-			mark_invoiced_inpatient_occupancy,
-		)
-
-		frappe.db.sql("""delete from `tabInpatient Record`""")
-		patient, practitioner = create_healthcare_docs()
-		patient = create_patient()
-		# Schedule Admission
-		ip_record = create_inpatient(patient)
-		ip_record.expected_length_of_stay = 0
-		ip_record.save(ignore_permissions = True)
-
-		# Admit
-		service_unit = get_healthcare_service_unit('_Test Service Unit Ip Occupancy')
-		admit_patient(ip_record, service_unit, now_datetime())
-
-		appointment_service_unit = get_healthcare_service_unit('_Test Service Unit Ip Occupancy for Appointment')
-		appointment = create_appointment(patient, practitioner, nowdate(), service_unit=appointment_service_unit, save=0)
-		self.assertRaises(frappe.exceptions.ValidationError, appointment.save)
-
-		# Discharge
-		schedule_discharge(frappe.as_json({'patient': patient}))
-		ip_record1 = frappe.get_doc("Inpatient Record", ip_record.name)
-		mark_invoiced_inpatient_occupancy(ip_record1)
-		discharge_patient(ip_record1)
-
-	def test_payment_should_be_mandatory_for_new_patient_appointment(self):
-		frappe.db.set_value('Healthcare Settings', None, 'enable_free_follow_ups', 1)
-		frappe.db.set_value('Healthcare Settings', None, 'automate_appointment_invoicing', 1)
-		frappe.db.set_value('Healthcare Settings', None, 'max_visits', 3)
-		frappe.db.set_value('Healthcare Settings', None, 'valid_days', 30)
-
-		patient = create_patient()
-		assert check_is_new_patient(patient)
-		payment_required = check_payment_fields_reqd(patient)
-		assert payment_required is True
-
-	def test_sales_invoice_should_be_generated_for_new_patient_appointment(self):
-		patient, practitioner = create_healthcare_docs()
-		frappe.db.set_value('Healthcare Settings', None, 'automate_appointment_invoicing', 1)
-		invoice_count = frappe.db.count('Sales Invoice')
-
-		assert check_is_new_patient(patient)
-		create_appointment(patient, practitioner, nowdate())
-		new_invoice_count = frappe.db.count('Sales Invoice')
-
-		assert new_invoice_count == invoice_count + 1
-
-	def test_patient_appointment_should_consider_permissions_while_fetching_appointments(self):
-		patient, practitioner = create_healthcare_docs()
-		create_appointment(patient, practitioner, nowdate())
-
-		patient, new_practitioner = create_healthcare_docs(id=5)
-		create_appointment(patient, new_practitioner, nowdate())
-
-		roles = [{"doctype": "Has Role", "role": "Physician"}]
-		user = create_user(roles=roles)
-		new_practitioner = frappe.get_doc('Healthcare Practitioner', new_practitioner)
-		new_practitioner.user_id = user.email
-		new_practitioner.save()
-
-		frappe.set_user(user.name)
-		appointments = frappe.get_list('Patient Appointment')
-		assert len(appointments) == 1
-
-		frappe.set_user("Administrator")
-		appointments = frappe.get_list('Patient Appointment')
-		assert len(appointments) == 2
-
-	def test_overlap_appointment(self):
-		from erpnext.healthcare.doctype.patient_appointment.patient_appointment import OverlapError
-		patient, practitioner = create_healthcare_docs(id=1)
-		patient_1, practitioner_1 = create_healthcare_docs(id=2)
-		service_unit = create_service_unit(id=0)
-		service_unit_1 = create_service_unit(id=1)
-		appointment = create_appointment(patient, practitioner, nowdate(), service_unit=service_unit) # valid
-
-		# patient and practitioner cannot have overlapping appointments
-		appointment = create_appointment(patient, practitioner, nowdate(), service_unit=service_unit, save=0)
-		self.assertRaises(OverlapError, appointment.save)
-		appointment = create_appointment(patient, practitioner, nowdate(), service_unit=service_unit_1, save=0) # diff service unit
-		self.assertRaises(OverlapError, appointment.save)
-		appointment = create_appointment(patient, practitioner, nowdate(), save=0) # with no service unit link
-		self.assertRaises(OverlapError, appointment.save)
-
-		# patient cannot have overlapping appointments with other practitioners
-		appointment = create_appointment(patient, practitioner_1, nowdate(), service_unit=service_unit, save=0)
-		self.assertRaises(OverlapError, appointment.save)
-		appointment = create_appointment(patient, practitioner_1, nowdate(), service_unit=service_unit_1, save=0)
-		self.assertRaises(OverlapError, appointment.save)
-		appointment = create_appointment(patient, practitioner_1, nowdate(), save=0)
-		self.assertRaises(OverlapError, appointment.save)
-
-		# practitioner cannot have overlapping appointments with other patients
-		appointment = create_appointment(patient_1, practitioner, nowdate(), service_unit=service_unit, save=0)
-		self.assertRaises(OverlapError, appointment.save)
-		appointment = create_appointment(patient_1, practitioner, nowdate(), service_unit=service_unit_1, save=0)
-		self.assertRaises(OverlapError, appointment.save)
-		appointment = create_appointment(patient_1, practitioner, nowdate(), save=0)
-		self.assertRaises(OverlapError, appointment.save)
-
-	def test_service_unit_capacity(self):
-		from erpnext.healthcare.doctype.patient_appointment.patient_appointment import (
-			MaximumCapacityError,
-			OverlapError,
-		)
-		practitioner = create_practitioner()
-		capacity = 3
-		overlap_service_unit_type = create_service_unit_type(id=10, allow_appointments=1, overlap_appointments=1)
-		overlap_service_unit = create_service_unit(id=100, service_unit_type=overlap_service_unit_type, service_unit_capacity=capacity)
-
-		for i in range(0, capacity):
-			patient = create_patient(id=i)
-			create_appointment(patient, practitioner, nowdate(), service_unit=overlap_service_unit) # valid
-			appointment = create_appointment(patient, practitioner, nowdate(), service_unit=overlap_service_unit, save=0) # overlap
-			self.assertRaises(OverlapError, appointment.save)
-
-		patient = create_patient(id=capacity)
-		appointment = create_appointment(patient, practitioner, nowdate(), service_unit=overlap_service_unit, save=0)
-		self.assertRaises(MaximumCapacityError, appointment.save)
-
-
-def create_healthcare_docs(id=0):
-	patient = create_patient(id)
-	practitioner = create_practitioner(id)
-
-	return patient, practitioner
-
-
-def create_patient(id=0):
-	if frappe.db.exists('Patient', {'firstname':f'_Test Patient {str(id)}'}):
-		patient = frappe.db.get_value('Patient', {'first_name': f'_Test Patient {str(id)}'}, ['name'])
-		return patient
-
-	patient = frappe.new_doc('Patient')
-	patient.first_name = f'_Test Patient {str(id)}'
-	patient.sex = 'Female'
-	patient.save(ignore_permissions=True)
-
-	return patient.name
-
-
-def create_medical_department(id=0):
-	if frappe.db.exists('Medical Department', f'_Test Medical Department {str(id)}'):
-		return f'_Test Medical Department {str(id)}'
-
-	medical_department = frappe.new_doc('Medical Department')
-	medical_department.department = f'_Test Medical Department {str(id)}'
-	medical_department.save(ignore_permissions=True)
-
-	return medical_department.name
-
-
-def create_practitioner(id=0, medical_department=None):
-	if frappe.db.exists('Healthcare Practitioner', {'firstname':f'_Test Healthcare Practitioner {str(id)}'}):
-		practitioner = frappe.db.get_value('Healthcare Practitioner', {'firstname':f'_Test Healthcare Practitioner {str(id)}'}, ['name'])
-		return practitioner
-
-	practitioner = frappe.new_doc('Healthcare Practitioner')
-	practitioner.first_name = f'_Test Healthcare Practitioner {str(id)}'
-	practitioner.gender = 'Female'
-	practitioner.department = medical_department or create_medical_department(id)
-	practitioner.op_consulting_charge = 500
-	practitioner.inpatient_visit_charge = 500
-	practitioner.save(ignore_permissions=True)
-
-	return practitioner.name
-
-
-def create_encounter(appointment):
-	if appointment:
-		encounter = frappe.new_doc('Patient Encounter')
-		encounter.appointment = appointment.name
-		encounter.patient = appointment.patient
-		encounter.practitioner = appointment.practitioner
-		encounter.encounter_date = appointment.appointment_date
-		encounter.encounter_time = appointment.appointment_time
-		encounter.company = appointment.company
-		encounter.save()
-		encounter.submit()
-
-		return encounter
-
-
-def create_appointment(patient, practitioner, appointment_date, invoice=0, procedure_template=0,
-	service_unit=None, appointment_type=None, save=1, department=None):
-	item = create_healthcare_service_items()
-	frappe.db.set_value('Healthcare Settings', None, 'inpatient_visit_charge_item', item)
-	frappe.db.set_value('Healthcare Settings', None, 'op_consulting_charge_item', item)
-	appointment = frappe.new_doc('Patient Appointment')
-	appointment.patient = patient
-	appointment.practitioner = practitioner
-	appointment.department = department or '_Test Medical Department'
-	appointment.appointment_date = appointment_date
-	appointment.company = '_Test Company'
-	appointment.duration = 15
-
-	if service_unit:
-		appointment.service_unit = service_unit
-	if invoice:
-		appointment.mode_of_payment = 'Cash'
-	if appointment_type:
-		appointment.appointment_type = appointment_type
-	if procedure_template:
-		appointment.procedure_template = create_clinical_procedure_template().get('name')
-	if save:
-		appointment.save(ignore_permissions=True)
-
-	return appointment
-
-
-def create_healthcare_service_items():
-	if frappe.db.exists('Item', 'HLC-SI-001'):
-		return 'HLC-SI-001'
-
-	item = frappe.new_doc('Item')
-	item.item_code = 'HLC-SI-001'
-	item.item_name = 'Consulting Charges'
-	item.item_group = 'Services'
-	item.is_stock_item = 0
-	item.stock_uom = 'Nos'
-	item.save()
-
-	return item.name
-
-
-def create_clinical_procedure_template():
-	if frappe.db.exists('Clinical Procedure Template', 'Knee Surgery and Rehab'):
-		return frappe.get_doc('Clinical Procedure Template', 'Knee Surgery and Rehab')
-
-	template = frappe.new_doc('Clinical Procedure Template')
-	template.template = 'Knee Surgery and Rehab'
-	template.item_code = 'Knee Surgery and Rehab'
-	template.item_group = 'Services'
-	template.is_billable = 1
-	template.description = 'Knee Surgery and Rehab'
-	template.rate = 50000
-	template.save()
-
-	return template
-
-
-def create_appointment_type(args=None):
-	if not args:
-		args =  frappe.local.form_dict
-
-	name = args.get('name') or 'Test Appointment Type wise Charge'
-
-	if frappe.db.exists('Appointment Type', name):
-		return frappe.get_doc('Appointment Type', name)
-
-	else:
-		item = create_healthcare_service_items()
-		items = [{
-			'medical_department': args.get('medical_department') or '_Test Medical Department',
-			'op_consulting_charge_item': item,
-			'op_consulting_charge': 200
-		}]
-		return frappe.get_doc({
-			'doctype': 'Appointment Type',
-			'appointment_type': args.get('name') or 'Test Appointment Type wise Charge',
-			'default_duration': args.get('default_duration') or 20,
-			'color': args.get('color') or '#7575ff',
-			'price_list': args.get('price_list') or frappe.db.get_value("Price List", {"selling": 1}),
-			'items': args.get('items') or items
-		}).insert()
-
-def create_user(email=None, roles=None):
-	if not email:
-		email = '{}@frappe.com'.format(frappe.utils.random_string(10))
-	user = frappe.db.exists('User', email)
-	if not user:
-		user = frappe.get_doc({
-			"doctype": "User",
-			"email": email,
-			"first_name": "test_user",
-			"password": "password",
-			"roles": roles,
-		}).insert()
-	return user
-
-
-def create_service_unit_type(id=0, allow_appointments=1, overlap_appointments=0):
-	if frappe.db.exists('Healthcare Service Unit Type', f'_Test Service Unit Type {str(id)}'):
-		return f'_Test Service Unit Type {str(id)}'
-
-	service_unit_type = frappe.new_doc('Healthcare Service Unit Type')
-	service_unit_type.service_unit_type = f'_Test Service Unit Type {str(id)}'
-	service_unit_type.allow_appointments = allow_appointments
-	service_unit_type.overlap_appointments = overlap_appointments
-	service_unit_type.save(ignore_permissions=True)
-
-	return service_unit_type.name
-
-
-def create_service_unit(id=0, service_unit_type=None, service_unit_capacity=0):
-	if frappe.db.exists('Healthcare Service Unit', f'_Test Service Unit {str(id)}'):
-		return f'_Test service_unit {str(id)}'
-
-	service_unit = frappe.new_doc('Healthcare Service Unit')
-	service_unit.is_group = 0
-	service_unit.healthcare_service_unit_name= f'_Test Service Unit {str(id)}'
-	service_unit.service_unit_type = service_unit_type or create_service_unit_type(id)
-	service_unit.service_unit_capacity = service_unit_capacity
-	service_unit.save(ignore_permissions=True)
-
-	return service_unit.name
diff --git a/erpnext/healthcare/doctype/patient_assessment/patient_assessment.js b/erpnext/healthcare/doctype/patient_assessment/patient_assessment.js
deleted file mode 100644
index f28d32c..0000000
--- a/erpnext/healthcare/doctype/patient_assessment/patient_assessment.js
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Patient Assessment', {
-	refresh: function(frm) {
-		if (frm.doc.assessment_template) {
-			frm.trigger('set_score_range');
-		}
-
-		if (!frm.doc.__islocal) {
-			frm.trigger('show_patient_progress');
-		}
-	},
-
-	assessment_template: function(frm) {
-		if (frm.doc.assessment_template) {
-			frappe.call({
-				'method': 'frappe.client.get',
-				args: {
-					doctype: 'Patient Assessment Template',
-					name: frm.doc.assessment_template
-				},
-				callback: function(data) {
-					frm.doc.assessment_sheet = [];
-					$.each(data.message.parameters, function(_i, e) {
-						let entry = frm.add_child('assessment_sheet');
-						entry.parameter = e.assessment_parameter;
-					});
-
-					frm.set_value('scale_min', data.message.scale_min);
-					frm.set_value('scale_max', data.message.scale_max);
-					frm.set_value('assessment_description', data.message.assessment_description);
-					frm.set_value('total_score', data.message.scale_max * data.message.parameters.length);
-					frm.trigger('set_score_range');
-					refresh_field('assessment_sheet');
-				}
-			});
-		}
-	},
-
-	set_score_range: function(frm) {
-		let options = [''];
-		for(let i = frm.doc.scale_min; i <= frm.doc.scale_max; i++) {
-			options.push(i);
-		}
-		frm.fields_dict.assessment_sheet.grid.update_docfield_property(
-			'score', 'options', options
-		);
-	},
-
-	calculate_total_score: function(frm, cdt, cdn) {
-		let row = locals[cdt][cdn];
-		let total_score = 0;
-		$.each(frm.doc.assessment_sheet || [], function(_i, item) {
-			if (item.score) {
-				total_score += parseInt(item.score);
-			}
-		});
-
-		frm.set_value('total_score_obtained', total_score);
-	},
-
-	show_patient_progress: function(frm) {
-		let bars = [];
-		let message = '';
-		let added_min = false;
-
-		let title = __('{0} out of {1}', [frm.doc.total_score_obtained, frm.doc.total_score]);
-
-		bars.push({
-			'title': title,
-			'width': (frm.doc.total_score_obtained / frm.doc.total_score * 100) + '%',
-			'progress_class': 'progress-bar-success'
-		});
-		if (bars[0].width == '0%') {
-			bars[0].width = '0.5%';
-			added_min = 0.5;
-		}
-		message = title;
-		frm.dashboard.add_progress(__('Status'), bars, message);
-	},
-});
-
-frappe.ui.form.on('Patient Assessment Sheet', {
-	score: function(frm, cdt, cdn) {
-		frm.events.calculate_total_score(frm, cdt, cdn);
-	}
-});
diff --git a/erpnext/healthcare/doctype/patient_assessment/patient_assessment.json b/erpnext/healthcare/doctype/patient_assessment/patient_assessment.json
deleted file mode 100644
index eb0021f..0000000
--- a/erpnext/healthcare/doctype/patient_assessment/patient_assessment.json
+++ /dev/null
@@ -1,181 +0,0 @@
-{
- "actions": [],
- "autoname": "naming_series:",
- "creation": "2020-04-19 22:45:12.356209",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "naming_series",
-  "therapy_session",
-  "patient",
-  "assessment_template",
-  "column_break_4",
-  "company",
-  "healthcare_practitioner",
-  "assessment_datetime",
-  "assessment_description",
-  "section_break_7",
-  "assessment_sheet",
-  "section_break_9",
-  "total_score_obtained",
-  "column_break_11",
-  "total_score",
-  "scale_min",
-  "scale_max",
-  "amended_from"
- ],
- "fields": [
-  {
-   "fetch_from": "therapy_session.patient",
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Patient",
-   "options": "Patient",
-   "reqd": 1
-  },
-  {
-   "fieldname": "assessment_template",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Assessment Template",
-   "options": "Patient Assessment Template",
-   "reqd": 1
-  },
-  {
-   "fieldname": "therapy_session",
-   "fieldtype": "Link",
-   "label": "Therapy Session",
-   "options": "Therapy Session"
-  },
-  {
-   "fieldname": "column_break_4",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fetch_from": "therapy_session.practitioner",
-   "fieldname": "healthcare_practitioner",
-   "fieldtype": "Link",
-   "label": "Healthcare Practitioner",
-   "options": "Healthcare Practitioner"
-  },
-  {
-   "fieldname": "assessment_datetime",
-   "fieldtype": "Datetime",
-   "label": "Assessment Datetime",
-   "reqd": 1
-  },
-  {
-   "fieldname": "section_break_7",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "assessment_sheet",
-   "fieldtype": "Table",
-   "label": "Assessment Sheet",
-   "options": "Patient Assessment Sheet"
-  },
-  {
-   "fieldname": "section_break_9",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "total_score",
-   "fieldtype": "Int",
-   "label": "Total Score",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_11",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "total_score_obtained",
-   "fieldtype": "Int",
-   "label": "Total Score Obtained",
-   "read_only": 1
-  },
-  {
-   "fieldname": "scale_min",
-   "fieldtype": "Int",
-   "hidden": 1,
-   "label": "Scale Min",
-   "read_only": 1
-  },
-  {
-   "fieldname": "scale_max",
-   "fieldtype": "Int",
-   "hidden": 1,
-   "label": "Scale Max",
-   "read_only": 1
-  },
-  {
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "label": "Naming Series",
-   "options": "HLC-PA-.YYYY.-"
-  },
-  {
-   "fieldname": "amended_from",
-   "fieldtype": "Link",
-   "label": "Amended From",
-   "no_copy": 1,
-   "options": "Patient Assessment",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "assessment_description",
-   "fieldtype": "Small Text",
-   "label": "Assessment Description"
-  },
-  {
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "in_standard_filter": 1,
-   "label": "Company",
-   "options": "Company"
-  }
- ],
- "is_submittable": 1,
- "links": [],
- "modified": "2020-06-25 00:25:13.208400",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Assessment",
- "owner": "Administrator",
- "permissions": [
-  {
-   "cancel": 1,
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "submit": 1,
-   "write": 1
-  },
-  {
-   "cancel": 1,
-   "create": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "submit": 1,
-   "write": 1
-  }
- ],
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "patient",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment/patient_assessment.py b/erpnext/healthcare/doctype/patient_assessment/patient_assessment.py
deleted file mode 100644
index 90cb300..0000000
--- a/erpnext/healthcare/doctype/patient_assessment/patient_assessment.py
+++ /dev/null
@@ -1,35 +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
-from frappe.model.mapper import get_mapped_doc
-
-
-class PatientAssessment(Document):
-	def validate(self):
-		self.set_total_score()
-
-	def set_total_score(self):
-		total_score = 0
-		for entry in self.assessment_sheet:
-			total_score += int(entry.score)
-		self.total_score_obtained = total_score
-
-@frappe.whitelist()
-def create_patient_assessment(source_name, target_doc=None):
-	doc = get_mapped_doc('Therapy Session', source_name, {
-			'Therapy Session': {
-				'doctype': 'Patient Assessment',
-				'field_map': [
-					['therapy_session', 'name'],
-					['patient', 'patient'],
-					['practitioner', 'practitioner']
-				]
-			}
-		}, target_doc)
-
-	return doc
diff --git a/erpnext/healthcare/doctype/patient_assessment/test_patient_assessment.py b/erpnext/healthcare/doctype/patient_assessment/test_patient_assessment.py
deleted file mode 100644
index 0ffbd1f..0000000
--- a/erpnext/healthcare/doctype/patient_assessment/test_patient_assessment.py
+++ /dev/null
@@ -1,11 +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 TestPatientAssessment(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/patient_assessment_detail/__init__.py b/erpnext/healthcare/doctype/patient_assessment_detail/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_detail/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.json b/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.json
deleted file mode 100644
index 179f441..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "actions": [],
- "creation": "2020-04-19 19:33:00.115395",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "assessment_parameter"
- ],
- "fields": [
-  {
-   "fieldname": "assessment_parameter",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Assessment Parameter",
-   "options": "Patient Assessment Parameter",
-   "reqd": 1
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-04-19 19:33:00.115395",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Assessment Detail",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.py b/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.py
deleted file mode 100644
index 4da679b..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.py
+++ /dev/null
@@ -1,12 +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 PatientAssessmentDetail(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/patient_assessment_parameter/__init__.py b/erpnext/healthcare/doctype/patient_assessment_parameter/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_parameter/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.js b/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.js
deleted file mode 100644
index 2c5d270..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.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('Patient Assessment Parameter', {
-	// refresh: function(frm) {
-
-	// }
-});
diff --git a/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.json b/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.json
deleted file mode 100644
index 098bdef..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
- "actions": [],
- "autoname": "field:assessment_parameter",
- "creation": "2020-04-15 14:34:46.551042",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "assessment_parameter"
- ],
- "fields": [
-  {
-   "fieldname": "assessment_parameter",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Assessment Parameter",
-   "reqd": 1,
-   "unique": 1
-  }
- ],
- "links": [],
- "modified": "2020-04-20 09:22:19.135196",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Assessment Parameter",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.py b/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.py
deleted file mode 100644
index 783c537..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.py
+++ /dev/null
@@ -1,12 +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 PatientAssessmentParameter(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/patient_assessment_parameter/test_patient_assessment_parameter.py b/erpnext/healthcare/doctype/patient_assessment_parameter/test_patient_assessment_parameter.py
deleted file mode 100644
index f06fffb..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_parameter/test_patient_assessment_parameter.py
+++ /dev/null
@@ -1,11 +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 TestPatientAssessmentParameter(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/patient_assessment_sheet/__init__.py b/erpnext/healthcare/doctype/patient_assessment_sheet/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_sheet/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.json b/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.json
deleted file mode 100644
index 64e4aef..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.json
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- "actions": [],
- "creation": "2020-04-19 23:07:02.220244",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "parameter",
-  "score",
-  "time",
-  "column_break_4",
-  "comments"
- ],
- "fields": [
-  {
-   "fieldname": "parameter",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Parameter",
-   "options": "Patient Assessment Parameter",
-   "reqd": 1
-  },
-  {
-   "fieldname": "score",
-   "fieldtype": "Select",
-   "in_list_view": 1,
-   "label": "Score",
-   "reqd": 1
-  },
-  {
-   "fieldname": "time",
-   "fieldtype": "Time",
-   "label": "Time"
-  },
-  {
-   "fieldname": "column_break_4",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "comments",
-   "fieldtype": "Small Text",
-   "label": "Comments"
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-04-20 09:56:28.746619",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Assessment Sheet",
- "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/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.py b/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.py
deleted file mode 100644
index 4686e9e..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.py
+++ /dev/null
@@ -1,12 +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 PatientAssessmentSheet(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/patient_assessment_template/__init__.py b/erpnext/healthcare/doctype/patient_assessment_template/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_template/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.js b/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.js
deleted file mode 100644
index 4041936..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.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('Patient Assessment Template', {
-	// refresh: function(frm) {
-
-	// }
-});
diff --git a/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.json b/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.json
deleted file mode 100644
index de006b1..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.json
+++ /dev/null
@@ -1,109 +0,0 @@
-{
- "actions": [],
- "autoname": "field:assessment_name",
- "creation": "2020-04-19 19:33:13.204707",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "assessment_name",
-  "section_break_2",
-  "parameters",
-  "assessment_scale_details_section",
-  "scale_min",
-  "scale_max",
-  "column_break_8",
-  "assessment_description"
- ],
- "fields": [
-  {
-   "fieldname": "parameters",
-   "fieldtype": "Table",
-   "label": "Parameters",
-   "options": "Patient Assessment Detail"
-  },
-  {
-   "fieldname": "assessment_name",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Assessment Name",
-   "reqd": 1,
-   "unique": 1
-  },
-  {
-   "fieldname": "section_break_2",
-   "fieldtype": "Section Break",
-   "label": "Assessment Parameters"
-  },
-  {
-   "fieldname": "assessment_scale_details_section",
-   "fieldtype": "Section Break",
-   "label": "Assessment Scale"
-  },
-  {
-   "fieldname": "scale_min",
-   "fieldtype": "Int",
-   "label": "Scale Minimum"
-  },
-  {
-   "fieldname": "scale_max",
-   "fieldtype": "Int",
-   "label": "Scale Maximum"
-  },
-  {
-   "fieldname": "column_break_8",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "assessment_description",
-   "fieldtype": "Small Text",
-   "label": "Assessment Description"
-  }
- ],
- "links": [],
- "modified": "2020-04-21 13:14:19.075167",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Assessment Template",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "write": 1
-  }
- ],
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.py b/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.py
deleted file mode 100644
index e0d8fca..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.py
+++ /dev/null
@@ -1,12 +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 PatientAssessmentTemplate(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/patient_assessment_template/test_patient_assessment_template.py b/erpnext/healthcare/doctype/patient_assessment_template/test_patient_assessment_template.py
deleted file mode 100644
index 7d639cb..0000000
--- a/erpnext/healthcare/doctype/patient_assessment_template/test_patient_assessment_template.py
+++ /dev/null
@@ -1,11 +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 TestPatientAssessmentTemplate(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/patient_encounter/__init__.py b/erpnext/healthcare/doctype/patient_encounter/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/patient_encounter/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
deleted file mode 100644
index c346626..0000000
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
+++ /dev/null
@@ -1,397 +0,0 @@
-// Copyright (c) 2016, ESS LLP and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Patient Encounter', {
-	setup: function(frm) {
-		frm.get_field('therapies').grid.editable_fields = [
-			{fieldname: 'therapy_type', columns: 8},
-			{fieldname: 'no_of_sessions', columns: 2}
-		];
-		frm.get_field('drug_prescription').grid.editable_fields = [
-			{fieldname: 'drug_code', columns: 2},
-			{fieldname: 'drug_name', columns: 2},
-			{fieldname: 'dosage', columns: 2},
-			{fieldname: 'period', columns: 2}
-		];
-		frm.get_field('lab_test_prescription').grid.editable_fields = [
-			{fieldname: 'lab_test_code', columns: 2},
-			{fieldname: 'lab_test_name', columns: 4},
-			{fieldname: 'lab_test_comment', columns: 4}
-		];
-	},
-
-	refresh: function(frm) {
-		refresh_field('drug_prescription');
-		refresh_field('lab_test_prescription');
-
-		if (!frm.doc.__islocal) {
-			if (frm.doc.docstatus === 1) {
-				if (frm.doc.inpatient_status == 'Admission Scheduled' || frm.doc.inpatient_status == 'Admitted') {
-					frm.add_custom_button(__('Schedule Discharge'), function() {
-						schedule_discharge(frm);
-					});
-				} else if (frm.doc.inpatient_status != 'Discharge Scheduled') {
-					frm.add_custom_button(__('Schedule Admission'), function() {
-						schedule_inpatient(frm);
-					});
-				}
-			}
-
-			frm.add_custom_button(__('Patient History'), function() {
-				if (frm.doc.patient) {
-					frappe.route_options = {'patient': frm.doc.patient};
-					frappe.set_route('patient_history');
-				} else {
-					frappe.msgprint(__('Please select Patient'));
-				}
-			},'View');
-
-			frm.add_custom_button(__('Vital Signs'), function() {
-				create_vital_signs(frm);
-			},'Create');
-
-			frm.add_custom_button(__('Medical Record'), function() {
-				create_medical_record(frm);
-			},'Create');
-
-			frm.add_custom_button(__('Clinical Procedure'), function() {
-				create_procedure(frm);
-			},'Create');
-
-			if (frm.doc.drug_prescription && frm.doc.inpatient_record && frm.doc.inpatient_status === "Admitted") {
-				frm.add_custom_button(__('Inpatient Medication Order'), function() {
-					frappe.model.open_mapped_doc({
-						method: 'erpnext.healthcare.doctype.patient_encounter.patient_encounter.make_ip_medication_order',
-						frm: frm
-					});
-				}, 'Create');
-			}
-		}
-
-		frm.set_query('patient', function() {
-			return {
-				filters: {'status': 'Active'}
-			};
-		});
-
-		frm.set_query('drug_code', 'drug_prescription', function() {
-			return {
-				filters: {
-					is_stock_item: 1
-				}
-			};
-		});
-
-		frm.set_query('lab_test_code', 'lab_test_prescription', function() {
-			return {
-				filters: {
-					is_billable: 1
-				}
-			};
-		});
-
-		frm.set_query('appointment', function() {
-			return {
-				filters: {
-					//	Scheduled filter for demo ...
-					status:['in',['Open','Scheduled']]
-				}
-			};
-		});
-
-		frm.set_df_property('patient', 'read_only', frm.doc.appointment ? 1 : 0);
-	},
-
-	appointment: function(frm) {
-		frm.events.set_appointment_fields(frm);
-	},
-
-	patient: function(frm) {
-		frm.events.set_patient_info(frm);
-	},
-
-	practitioner: function(frm) {
-		if (!frm.doc.practitioner) {
-			frm.set_value('practitioner_name', '');
-		}
-	},
-	set_appointment_fields: function(frm) {
-		if (frm.doc.appointment) {
-			frappe.call({
-				method: 'frappe.client.get',
-				args: {
-					doctype: 'Patient Appointment',
-					name: frm.doc.appointment
-				},
-				callback: function(data) {
-					let values = {
-						'patient':data.message.patient,
-						'type': data.message.appointment_type,
-						'practitioner': data.message.practitioner,
-						'invoiced': data.message.invoiced,
-						'company': data.message.company
-					};
-					frm.set_value(values);
-					frm.set_df_property('patient', 'read_only', 1);
-				}
-			});
-		}
-		else {
-			let values = {
-				'patient': '',
-				'patient_name': '',
-				'type': '',
-				'practitioner': '',
-				'invoiced': 0,
-				'patient_sex': '',
-				'patient_age': '',
-				'inpatient_record': '',
-				'inpatient_status': ''
-			};
-			frm.set_value(values);
-			frm.set_df_property('patient', 'read_only', 0);
-		}
-	},
-
-	set_patient_info: function(frm) {
-		if (frm.doc.patient) {
-			frappe.call({
-				method: 'erpnext.healthcare.doctype.patient.patient.get_patient_detail',
-				args: {
-					patient: frm.doc.patient
-				},
-				callback: function(data) {
-					let age = '';
-					if (data.message.dob) {
-						age = calculate_age(data.message.dob);
-					}
-					let values = {
-						'patient_age': age,
-						'patient_name':data.message.patient_name,
-						'patient_sex': data.message.sex,
-						'inpatient_record': data.message.inpatient_record,
-						'inpatient_status': data.message.inpatient_status
-					};
-					frm.set_value(values);
-				}
-			});
-		} else {
-			let values = {
-				'patient_age': '',
-				'patient_name':'',
-				'patient_sex': '',
-				'inpatient_record': '',
-				'inpatient_status': ''
-			};
-			frm.set_value(values);
-		}
-	},
-
-	get_applicable_treatment_plans: function(frm) {
-		frappe.call({
-			method: 'get_applicable_treatment_plans',
-			doc: frm.doc,
-			args: {'encounter': frm.doc},
-			freeze: true,
-			freeze_message: __('Fetching Treatment Plans'),
-			callback: function() {
-				new frappe.ui.form.MultiSelectDialog({
-					doctype: "Treatment Plan Template",
-					target: this.cur_frm,
-					setters: {
-						medical_department: "",
-					},
-					action(selections) {
-						frappe.call({
-							method: 'set_treatment_plans',
-							doc: frm.doc,
-							args: selections,
-						}).then(() => {
-							frm.refresh_field('drug_prescription');
-							frm.refresh_field('procedure_prescription');
-							frm.refresh_field('lab_test_prescription');
-							frm.refresh_field('therapies');
-						});
-						cur_dialog.hide();
-					}
-				});
-
-
-			}
-		});
-	},
-
-});
-
-var schedule_inpatient = function(frm) {
-	var dialog = new frappe.ui.Dialog({
-		title: 'Patient Admission',
-		fields: [
-			{fieldtype: 'Link', label: 'Medical Department', fieldname: 'medical_department', options: 'Medical Department', reqd: 1},
-			{fieldtype: 'Link', label: 'Healthcare Practitioner (Primary)', fieldname: 'primary_practitioner', options: 'Healthcare Practitioner', reqd: 1},
-			{fieldtype: 'Link', label: 'Healthcare Practitioner (Secondary)', fieldname: 'secondary_practitioner', options: 'Healthcare Practitioner'},
-			{fieldtype: 'Column Break'},
-			{fieldtype: 'Date', label: 'Admission Ordered For', fieldname: 'admission_ordered_for', default: 'Today'},
-			{fieldtype: 'Link', label: 'Service Unit Type', fieldname: 'service_unit_type', options: 'Healthcare Service Unit Type'},
-			{fieldtype: 'Int', label: 'Expected Length of Stay', fieldname: 'expected_length_of_stay'},
-			{fieldtype: 'Section Break'},
-			{fieldtype: 'Long Text', label: 'Admission Instructions', fieldname: 'admission_instruction'}
-		],
-		primary_action_label: __('Order Admission'),
-		primary_action : function() {
-			var args = {
-				patient: frm.doc.patient,
-				admission_encounter: frm.doc.name,
-				referring_practitioner: frm.doc.practitioner,
-				company: frm.doc.company,
-				medical_department: dialog.get_value('medical_department'),
-				primary_practitioner: dialog.get_value('primary_practitioner'),
-				secondary_practitioner: dialog.get_value('secondary_practitioner'),
-				admission_ordered_for: dialog.get_value('admission_ordered_for'),
-				admission_service_unit_type: dialog.get_value('service_unit_type'),
-				expected_length_of_stay: dialog.get_value('expected_length_of_stay'),
-				admission_instruction: dialog.get_value('admission_instruction')
-			}
-			frappe.call({
-				method: 'erpnext.healthcare.doctype.inpatient_record.inpatient_record.schedule_inpatient',
-				args: {
-					args: args
-				},
-				callback: function(data) {
-					if (!data.exc) {
-						frm.reload_doc();
-					}
-				},
-				freeze: true,
-				freeze_message: __('Scheduling Patient Admission')
-			});
-			frm.refresh_fields();
-			dialog.hide();
-		}
-	});
-
-	dialog.set_values({
-		'medical_department': frm.doc.medical_department,
-		'primary_practitioner': frm.doc.practitioner,
-	});
-
-	dialog.fields_dict['service_unit_type'].get_query = function() {
-		return {
-			filters: {
-				'inpatient_occupancy': 1,
-				'allow_appointments': 0
-			}
-		};
-	};
-
-	dialog.show();
-	dialog.$wrapper.find('.modal-dialog').css('width', '800px');
-};
-
-var schedule_discharge = function(frm) {
-	var dialog = new frappe.ui.Dialog ({
-		title: 'Inpatient Discharge',
-		fields: [
-			{fieldtype: 'Date', label: 'Discharge Ordered Date', fieldname: 'discharge_ordered_date', default: 'Today', read_only: 1},
-			{fieldtype: 'Date', label: 'Followup Date', fieldname: 'followup_date'},
-			{fieldtype: 'Column Break'},
-			{fieldtype: 'Small Text', label: 'Discharge Instructions', fieldname: 'discharge_instructions'},
-			{fieldtype: 'Section Break', label:'Discharge Summary'},
-			{fieldtype: 'Long Text', label: 'Discharge Note', fieldname: 'discharge_note'}
-		],
-		primary_action_label: __('Order Discharge'),
-		primary_action : function() {
-			var args = {
-				patient: frm.doc.patient,
-				discharge_encounter: frm.doc.name,
-				discharge_practitioner: frm.doc.practitioner,
-				discharge_ordered_date: dialog.get_value('discharge_ordered_date'),
-				followup_date: dialog.get_value('followup_date'),
-				discharge_instructions: dialog.get_value('discharge_instructions'),
-				discharge_note: dialog.get_value('discharge_note')
-			}
-			frappe.call ({
-				method: 'erpnext.healthcare.doctype.inpatient_record.inpatient_record.schedule_discharge',
-				args: {args},
-				callback: function(data) {
-					if(!data.exc){
-						frm.reload_doc();
-					}
-				},
-				freeze: true,
-				freeze_message: 'Scheduling Inpatient Discharge'
-			});
-			frm.refresh_fields();
-			dialog.hide();
-		}
-	});
-
-	dialog.show();
-	dialog.$wrapper.find('.modal-dialog').css('width', '800px');
-};
-
-let create_medical_record = function(frm) {
-	if (!frm.doc.patient) {
-		frappe.throw(__('Please select patient'));
-	}
-	frappe.route_options = {
-		'patient': frm.doc.patient,
-		'status': 'Open',
-		'reference_doctype': 'Patient Medical Record',
-		'reference_owner': frm.doc.owner
-	};
-	frappe.new_doc('Patient Medical Record');
-};
-
-let create_vital_signs = function(frm) {
-	if (!frm.doc.patient) {
-		frappe.throw(__('Please select patient'));
-	}
-	frappe.route_options = {
-		'patient': frm.doc.patient,
-		'encounter': frm.doc.name,
-		'company': frm.doc.company
-	};
-	frappe.new_doc('Vital Signs');
-};
-
-let create_procedure = function(frm) {
-	if (!frm.doc.patient) {
-		frappe.throw(__('Please select patient'));
-	}
-	frappe.route_options = {
-		'patient': frm.doc.patient,
-		'medical_department': frm.doc.medical_department,
-		'company': frm.doc.company
-	};
-	frappe.new_doc('Clinical Procedure');
-};
-
-frappe.ui.form.on('Drug Prescription', {
-	dosage: function(frm, cdt, cdn){
-		frappe.model.set_value(cdt, cdn, 'update_schedule', 1);
-		let child = locals[cdt][cdn];
-		if (child.dosage) {
-			frappe.model.set_value(cdt, cdn, 'interval_uom', 'Day');
-			frappe.model.set_value(cdt, cdn, 'interval', 1);
-		}
-	},
-	period: function(frm, cdt, cdn) {
-		frappe.model.set_value(cdt, cdn, 'update_schedule', 1);
-	},
-	interval_uom: function(frm, cdt, cdn) {
-		frappe.model.set_value(cdt, cdn, 'update_schedule', 1);
-		let child = locals[cdt][cdn];
-		if (child.interval_uom == 'Hour') {
-			frappe.model.set_value(cdt, cdn, 'dosage', null);
-		}
-	}
-});
-
-let calculate_age = function(birth) {
-	let ageMS = Date.parse(Date()) - Date.parse(birth);
-	let age = new Date();
-	age.setTime(ageMS);
-	let years =  age.getFullYear() - 1970;
-	return `${years} ${__('Years(s)')} ${age.getMonth()} ${__('Month(s)')} ${age.getDate()} ${__('Day(s)')}`;
-};
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
deleted file mode 100644
index 994597d..0000000
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
+++ /dev/null
@@ -1,368 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "allow_import": 1,
- "autoname": "naming_series:",
- "beta": 1,
- "creation": "2016-04-21 10:53:44.637684",
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "naming_series",
-  "title",
-  "appointment",
-  "appointment_type",
-  "patient",
-  "patient_name",
-  "patient_sex",
-  "patient_age",
-  "inpatient_record",
-  "inpatient_status",
-  "column_break_6",
-  "company",
-  "encounter_date",
-  "encounter_time",
-  "practitioner",
-  "practitioner_name",
-  "medical_department",
-  "invoiced",
-  "sb_symptoms",
-  "symptoms",
-  "symptoms_in_print",
-  "get_applicable_treatment_plans",
-  "physical_examination",
-  "diagnosis",
-  "diagnosis_in_print",
-  "codification",
-  "codification_table",
-  "sb_drug_prescription",
-  "drug_prescription",
-  "sb_test_prescription",
-  "lab_test_prescription",
-  "sb_procedures",
-  "procedure_prescription",
-  "rehabilitation_section",
-  "therapy_plan",
-  "therapies",
-  "section_break_33",
-  "encounter_comment",
-  "sb_refs",
-  "amended_from"
- ],
- "fields": [
-  {
-   "allow_on_submit": 1,
-   "fieldname": "inpatient_record",
-   "fieldtype": "Link",
-   "label": "Inpatient Record",
-   "options": "Inpatient Record",
-   "read_only": 1
-  },
-  {
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "label": "Series",
-   "no_copy": 1,
-   "options": "HLC-ENC-.YYYY.-",
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "appointment",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "label": "Appointment",
-   "options": "Patient Appointment",
-   "search_index": 1,
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_standard_filter": 1,
-   "label": "Patient",
-   "options": "Patient",
-   "reqd": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "patient_name",
-   "fieldtype": "Data",
-   "label": "Patient Name",
-   "read_only": 1
-  },
-  {
-   "fieldname": "patient_age",
-   "fieldtype": "Data",
-   "label": "Age",
-   "read_only": 1
-  },
-  {
-   "fieldname": "patient_sex",
-   "fieldtype": "Link",
-   "label": "Gender",
-   "options": "Gender",
-   "read_only": 1
-  },
-  {
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "label": "Company",
-   "options": "Company"
-  },
-  {
-   "fieldname": "column_break_6",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "practitioner",
-   "fieldtype": "Link",
-   "in_standard_filter": 1,
-   "label": "Healthcare Practitioner",
-   "options": "Healthcare Practitioner",
-   "reqd": 1
-  },
-  {
-   "default": "Today",
-   "fieldname": "encounter_date",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "label": "Encounter Date",
-   "reqd": 1
-  },
-  {
-   "fieldname": "encounter_time",
-   "fieldtype": "Time",
-   "label": "Encounter Time",
-   "reqd": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "invoiced",
-   "fieldtype": "Check",
-   "label": "Invoiced",
-   "no_copy": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "sb_symptoms",
-   "fieldtype": "Section Break",
-   "label": "Encounter Impression"
-  },
-  {
-   "fieldname": "symptoms",
-   "fieldtype": "Table MultiSelect",
-   "ignore_xss_filter": 1,
-   "label": "Symptoms",
-   "no_copy": 1,
-   "options": "Patient Encounter Symptom"
-  },
-  {
-   "default": "0",
-   "depends_on": "eval: doc.symptoms != ''",
-   "fieldname": "symptoms_in_print",
-   "fieldtype": "Check",
-   "label": "In print",
-   "no_copy": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "physical_examination",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "diagnosis",
-   "fieldtype": "Table MultiSelect",
-   "ignore_xss_filter": 1,
-   "label": "Diagnosis",
-   "no_copy": 1,
-   "options": "Patient Encounter Diagnosis"
-  },
-  {
-   "default": "1",
-   "depends_on": "eval: doc.diagnosis != ''",
-   "fieldname": "diagnosis_in_print",
-   "fieldtype": "Check",
-   "label": "In print",
-   "no_copy": 1,
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "codification",
-   "fieldtype": "Section Break",
-   "label": "Medical Coding"
-  },
-  {
-   "fieldname": "codification_table",
-   "fieldtype": "Table",
-   "label": "Medical Codes",
-   "options": "Codification Table"
-  },
-  {
-   "fieldname": "sb_drug_prescription",
-   "fieldtype": "Section Break",
-   "label": "Medications"
-  },
-  {
-   "fieldname": "drug_prescription",
-   "fieldtype": "Table",
-   "label": "Drug Prescription",
-   "options": "Drug Prescription"
-  },
-  {
-   "fieldname": "sb_test_prescription",
-   "fieldtype": "Section Break",
-   "label": "Investigations"
-  },
-  {
-   "fieldname": "lab_test_prescription",
-   "fieldtype": "Table",
-   "label": "Lab Tests",
-   "options": "Lab Prescription"
-  },
-  {
-   "fieldname": "sb_procedures",
-   "fieldtype": "Section Break",
-   "label": "Procedures"
-  },
-  {
-   "fieldname": "procedure_prescription",
-   "fieldtype": "Table",
-   "label": "Clinical Procedures",
-   "no_copy": 1,
-   "options": "Procedure Prescription"
-  },
-  {
-   "fieldname": "encounter_comment",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Review Details",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "amended_from",
-   "fieldtype": "Link",
-   "label": "Amended From",
-   "no_copy": 1,
-   "options": "Patient Encounter",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "rehabilitation_section",
-   "fieldtype": "Section Break",
-   "label": "Rehabilitation"
-  },
-  {
-   "fieldname": "therapies",
-   "fieldtype": "Table",
-   "label": "Therapies",
-   "options": "Therapy Plan Detail"
-  },
-  {
-   "fieldname": "section_break_33",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "therapy_plan",
-   "fieldtype": "Link",
-   "hidden": 1,
-   "label": "Therapy Plan",
-   "options": "Therapy Plan",
-   "read_only": 1
-  },
-  {
-   "fieldname": "appointment_type",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "label": "Appointment Type",
-   "no_copy": 1,
-   "options": "Appointment Type",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "fetch_from": "practitioner.department",
-   "fieldname": "medical_department",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_standard_filter": 1,
-   "label": "Department",
-   "options": "Medical Department",
-   "read_only": 1
-  },
-  {
-   "allow_on_submit": 1,
-   "fieldname": "inpatient_status",
-   "fieldtype": "Data",
-   "label": "Inpatient Status",
-   "read_only": 1
-  },
-  {
-   "fieldname": "sb_refs",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fetch_from": "practitioner.practitioner_name",
-   "fieldname": "practitioner_name",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Practitioner Name",
-   "read_only": 1
-  },
-  {
-   "allow_on_submit": 1,
-   "fieldname": "title",
-   "fieldtype": "Data",
-   "hidden": 1,
-   "label": "Title",
-   "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "depends_on": "eval:doc.patient",
-   "fieldname": "get_applicable_treatment_plans",
-   "fieldtype": "Button",
-   "label": "Get Applicable Treatment Plans"
-  }
- ],
- "is_submittable": 1,
- "links": [],
- "modified": "2021-07-27 11:39:12.347704",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Encounter",
- "owner": "Administrator",
- "permissions": [
-  {
-   "amend": 1,
-   "cancel": 1,
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "submit": 1,
-   "write": 1
-  }
- ],
- "restrict_to_domain": "Healthcare",
- "search_fields": "patient, practitioner, medical_department, encounter_date, encounter_time",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "title",
- "track_changes": 1,
- "track_seen": 1
-}
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
deleted file mode 100644
index 2daa6c1..0000000
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP 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
-from frappe.model.mapper import get_mapped_doc
-from frappe.utils import add_days, getdate
-
-
-class PatientEncounter(Document):
-	def validate(self):
-		self.set_title()
-
-	def on_update(self):
-		if self.appointment:
-			frappe.db.set_value('Patient Appointment', self.appointment, 'status', 'Closed')
-
-	def on_submit(self):
-		if self.therapies:
-			create_therapy_plan(self)
-
-	def on_cancel(self):
-		if self.appointment:
-			frappe.db.set_value('Patient Appointment', self.appointment, 'status', 'Open')
-
-		if self.inpatient_record and self.drug_prescription:
-			delete_ip_medication_order(self)
-
-	def set_title(self):
-		self.title = _('{0} with {1}').format(self.patient_name or self.patient,
-			self.practitioner_name or self.practitioner)[:100]
-
-	@frappe.whitelist()
-	@staticmethod
-	def get_applicable_treatment_plans(encounter):
-		patient = frappe.get_doc('Patient', encounter['patient'])
-
-		plan_filters = {}
-		plan_filters['name'] = ['in', []]
-
-		age = patient.age
-		if age:
-			plan_filters['patient_age_from'] = ['<=', age.years]
-			plan_filters['patient_age_to'] = ['>=', age.years]
-
-		gender = patient.sex
-		if gender:
-			plan_filters['gender'] = ['in', [gender, None]]
-
-		diagnosis = encounter.get('diagnosis')
-		if diagnosis:
-			diagnosis = [_diagnosis['diagnosis'] for _diagnosis in encounter['diagnosis']]
-			filters = [
-				['diagnosis', 'in', diagnosis],
-				['parenttype', '=', 'Treatment Plan Template'],
-			]
-			diagnosis = frappe.get_list('Patient Encounter Diagnosis', filters=filters, fields='*')
-			plan_names = [_diagnosis['parent'] for _diagnosis in diagnosis]
-			plan_filters['name'][1].extend(plan_names)
-
-		symptoms = encounter.get('symptoms')
-		if symptoms:
-			symptoms = [symptom['complaint'] for symptom in encounter['symptoms']]
-			filters = [
-				['complaint', 'in', symptoms],
-				['parenttype', '=', 'Treatment Plan Template'],
-			]
-			symptoms = frappe.get_list('Patient Encounter Symptom', filters=filters, fields='*')
-			plan_names = [symptom['parent'] for symptom in symptoms]
-			plan_filters['name'][1].extend(plan_names)
-
-		if not plan_filters['name'][1]:
-			plan_filters.pop('name')
-
-		plans = frappe.get_list('Treatment Plan Template', fields='*', filters=plan_filters)
-
-		return plans
-
-	@frappe.whitelist()
-	def set_treatment_plans(self, treatment_plans=None):
-		for treatment_plan in treatment_plans:
-			self.set_treatment_plan(treatment_plan)
-
-	def set_treatment_plan(self, plan):
-		plan_items = frappe.get_list('Treatment Plan Template Item', filters={'parent': plan}, fields='*')
-		for plan_item in plan_items:
-			self.set_treatment_plan_item(plan_item)
-
-		drugs = frappe.get_list('Drug Prescription', filters={'parent': plan}, fields='*')
-		for drug in drugs:
-			self.append('drug_prescription', drug)
-
-		self.save()
-
-	def set_treatment_plan_item(self, plan_item):
-		if plan_item.type == 'Clinical Procedure Template':
-			self.append('procedure_prescription', {
-				'procedure': plan_item.template
-			})
-
-		if plan_item.type == 'Lab Test Template':
-			self.append('lab_test_prescription', {
-				'lab_test_code': plan_item.template
-			})
-
-		if plan_item.type == 'Therapy Type':
-			self.append('therapies', {
-				'therapy_type': plan_item.template
-			})
-
-
-@frappe.whitelist()
-def make_ip_medication_order(source_name, target_doc=None):
-	def set_missing_values(source, target):
-		target.start_date = source.encounter_date
-		for entry in source.drug_prescription:
-			if entry.drug_code:
-				dosage = frappe.get_doc('Prescription Dosage', entry.dosage)
-				dates = get_prescription_dates(entry.period, target.start_date)
-				for date in dates:
-					for dose in dosage.dosage_strength:
-						order = target.append('medication_orders')
-						order.drug = entry.drug_code
-						order.drug_name = entry.drug_name
-						order.dosage = dose.strength
-						order.instructions = entry.comment
-						order.dosage_form = entry.dosage_form
-						order.date = date
-						order.time = dose.strength_time
-				target.end_date = dates[-1]
-
-	doc = get_mapped_doc('Patient Encounter', source_name, {
-			'Patient Encounter': {
-				'doctype': 'Inpatient Medication Order',
-				'field_map': {
-					'name': 'patient_encounter',
-					'patient': 'patient',
-					'patient_name': 'patient_name',
-					'patient_age': 'patient_age',
-					'inpatient_record': 'inpatient_record',
-					'practitioner': 'practitioner',
-					'start_date': 'encounter_date'
-				},
-			}
-		}, target_doc, set_missing_values)
-
-	return doc
-
-
-def get_prescription_dates(period, start_date):
-	prescription_duration = frappe.get_doc('Prescription Duration', period)
-	days = prescription_duration.get_days()
-	dates = [start_date]
-	for i in range(1, days):
-		dates.append(add_days(getdate(start_date), i))
-	return dates
-
-
-def create_therapy_plan(encounter):
-	if len(encounter.therapies):
-		doc = frappe.new_doc('Therapy Plan')
-		doc.patient = encounter.patient
-		doc.start_date = encounter.encounter_date
-		for entry in encounter.therapies:
-			doc.append('therapy_plan_details', {
-				'therapy_type': entry.therapy_type,
-				'no_of_sessions': entry.no_of_sessions
-			})
-		doc.save(ignore_permissions=True)
-		if doc.get('name'):
-			encounter.db_set('therapy_plan', doc.name)
-			frappe.msgprint(_('Therapy Plan {0} created successfully.').format(frappe.bold(doc.name)), alert=True)
-
-
-def delete_ip_medication_order(encounter):
-	record = frappe.db.exists('Inpatient Medication Order', {'patient_encounter': encounter.name})
-	if record:
-		frappe.delete_doc('Inpatient Medication Order', record, force=1)
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter_dashboard.py b/erpnext/healthcare/doctype/patient_encounter/patient_encounter_dashboard.py
deleted file mode 100644
index 3b64d98..0000000
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter_dashboard.py
+++ /dev/null
@@ -1,24 +0,0 @@
-from __future__ import unicode_literals
-
-from frappe import _
-
-
-def get_data():
-	return {
-		'fieldname': 'encounter',
-		'non_standard_fieldnames': {
-			'Patient Medical Record': 'reference_name',
-			'Inpatient Medication Order': 'patient_encounter'
-		},
-		'transactions': [
-			{
-				'label': _('Records'),
-				'items': ['Vital Signs', 'Patient Medical Record']
-			},
-			{
-				'label': _('Orders'),
-				'items': ['Inpatient Medication Order']
-			}
-		],
-		'disable_create_buttons': ['Inpatient Medication Order']
-	}
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter_list.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter_list.js
deleted file mode 100644
index d8f63bd..0000000
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter_list.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
-(c) ESS 2015-16
-*/
-frappe.listview_settings['Patient Encounter'] = {
-	filters:[["docstatus","!=","2"]]
-};
diff --git a/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.py b/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.py
deleted file mode 100644
index fa643a3..0000000
--- a/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-import frappe
-
-from erpnext.healthcare.doctype.patient_encounter.patient_encounter import PatientEncounter
-
-
-class TestPatientEncounter(unittest.TestCase):
-	def setUp(self):
-		try:
-			gender_m = frappe.get_doc({
-				'doctype': 'Gender',
-				'gender': 'MALE'
-			}).insert()
-			gender_f = frappe.get_doc({
-				'doctype': 'Gender',
-				'gender': 'FEMALE'
-			}).insert()
-		except frappe.exceptions.DuplicateEntryError:
-			gender_m = frappe.get_doc({
-				'doctype': 'Gender',
-				'gender': 'MALE'
-			})
-			gender_f = frappe.get_doc({
-				'doctype': 'Gender',
-				'gender': 'FEMALE'
-			})
-
-		self.patient_male = frappe.get_doc({
-			'doctype': 'Patient',
-			'first_name': 'John',
-			'sex': gender_m.gender,
-		}).insert()
-		self.patient_female = frappe.get_doc({
-			'doctype': 'Patient',
-			'first_name': 'Curie',
-			'sex': gender_f.gender,
-		}).insert()
-		self.practitioner = frappe.get_doc({
-			'doctype': 'Healthcare Practitioner',
-			'first_name': 'Doc',
-			'sex': 'MALE',
-		}).insert()
-		try:
-			self.care_plan_male = frappe.get_doc({
-				'doctype': 'Treatment Plan Template',
-				'template_name': 'test plan - m',
-				'gender': gender_m.gender,
-			}).insert()
-			self.care_plan_female = frappe.get_doc({
-				'doctype': 'Treatment Plan Template',
-				'template_name': 'test plan - f',
-				'gender': gender_f.gender,
-			}).insert()
-		except frappe.exceptions.DuplicateEntryError:
-			self.care_plan_male = frappe.get_doc({
-				'doctype': 'Treatment Plan Template',
-				'template_name': 'test plan - m',
-				'gender': gender_m.gender,
-			})
-			self.care_plan_female = frappe.get_doc({
-				'doctype': 'Treatment Plan Template',
-				'template_name': 'test plan - f',
-				'gender': gender_f.gender,
-			})
-
-	def test_treatment_plan_template_filter(self):
-		encounter = frappe.get_doc({
-			'doctype': 'Patient Encounter',
-			'patient': self.patient_male.name,
-			'practitioner': self.practitioner.name,
-		}).insert()
-		plans = PatientEncounter.get_applicable_treatment_plans(encounter.as_dict())
-		self.assertEqual(plans[0]['name'], self.care_plan_male.template_name)
-
-		encounter = frappe.get_doc({
-			'doctype': 'Patient Encounter',
-			'patient': self.patient_female.name,
-			'practitioner': self.practitioner.name,
-		}).insert()
-		plans = PatientEncounter.get_applicable_treatment_plans(encounter.as_dict())
-		self.assertEqual(plans[0]['name'], self.care_plan_female.template_name)
diff --git a/erpnext/healthcare/doctype/patient_encounter_diagnosis/__init__.py b/erpnext/healthcare/doctype/patient_encounter_diagnosis/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/patient_encounter_diagnosis/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/patient_encounter_diagnosis/patient_encounter_diagnosis.json b/erpnext/healthcare/doctype/patient_encounter_diagnosis/patient_encounter_diagnosis.json
deleted file mode 100644
index 00ca309..0000000
--- a/erpnext/healthcare/doctype/patient_encounter_diagnosis/patient_encounter_diagnosis.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "actions": [],
- "beta": 1,
- "creation": "2020-02-26 16:48:16.835105",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "diagnosis"
- ],
- "fields": [
-  {
-   "fieldname": "diagnosis",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Diagnosis",
-   "options": "Diagnosis",
-   "reqd": 1
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-02-26 16:58:16.480583",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Encounter Diagnosis",
- "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/healthcare/doctype/patient_encounter_diagnosis/patient_encounter_diagnosis.py b/erpnext/healthcare/doctype/patient_encounter_diagnosis/patient_encounter_diagnosis.py
deleted file mode 100644
index e4d2069..0000000
--- a/erpnext/healthcare/doctype/patient_encounter_diagnosis/patient_encounter_diagnosis.py
+++ /dev/null
@@ -1,12 +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 PatientEncounterDiagnosis(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/patient_encounter_symptom/__init__.py b/erpnext/healthcare/doctype/patient_encounter_symptom/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/patient_encounter_symptom/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/patient_encounter_symptom/patient_encounter_symptom.json b/erpnext/healthcare/doctype/patient_encounter_symptom/patient_encounter_symptom.json
deleted file mode 100644
index bc92145..0000000
--- a/erpnext/healthcare/doctype/patient_encounter_symptom/patient_encounter_symptom.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "actions": [],
- "beta": 1,
- "creation": "2020-02-26 16:47:00.525657",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "complaint"
- ],
- "fields": [
-  {
-   "fieldname": "complaint",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Complaint",
-   "options": "Complaint",
-   "reqd": 1
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-02-26 16:57:37.997481",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Encounter Symptom",
- "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/healthcare/doctype/patient_encounter_symptom/patient_encounter_symptom.py b/erpnext/healthcare/doctype/patient_encounter_symptom/patient_encounter_symptom.py
deleted file mode 100644
index 47f2a2b..0000000
--- a/erpnext/healthcare/doctype/patient_encounter_symptom/patient_encounter_symptom.py
+++ /dev/null
@@ -1,12 +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 PatientEncounterSymptom(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/patient_history_custom_document_type/__init__.py b/erpnext/healthcare/doctype/patient_history_custom_document_type/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/patient_history_custom_document_type/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json b/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json
deleted file mode 100644
index 3025c7b..0000000
--- a/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json
+++ /dev/null
@@ -1,55 +0,0 @@
-{
- "actions": [],
- "creation": "2020-11-25 13:40:23.054469",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "document_type",
-  "date_fieldname",
-  "add_edit_fields",
-  "selected_fields"
- ],
- "fields": [
-  {
-   "fieldname": "document_type",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Document Type",
-   "options": "DocType",
-   "reqd": 1
-  },
-  {
-   "fieldname": "selected_fields",
-   "fieldtype": "Code",
-   "label": "Selected Fields",
-   "read_only": 1
-  },
-  {
-   "fieldname": "add_edit_fields",
-   "fieldtype": "Button",
-   "in_list_view": 1,
-   "label": "Add / Edit Fields"
-  },
-  {
-   "fieldname": "date_fieldname",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Date Fieldname",
-   "reqd": 1
-  }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2020-11-30 13:54:37.474671",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient History Custom Document Type",
- "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/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.py b/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.py
deleted file mode 100644
index 34e15dc..0000000
--- a/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.py
+++ /dev/null
@@ -1,12 +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 PatientHistoryCustomDocumentType(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/patient_history_settings/__init__.py b/erpnext/healthcare/doctype/patient_history_settings/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/patient_history_settings/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js
deleted file mode 100644
index 453da6a..0000000
--- a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Patient History Settings', {
-	refresh: function(frm) {
-		frm.set_query('document_type', 'custom_doctypes', () => {
-			return {
-				filters: {
-					custom: 1,
-					is_submittable: 1,
-					module: 'Healthcare',
-				}
-			};
-		});
-	},
-
-	field_selector: function(frm, doc, standard=1) {
-		let document_fields = [];
-		if (doc.selected_fields)
-			document_fields = (JSON.parse(doc.selected_fields)).map(f => f.fieldname);
-
-		frm.call({
-			method: 'get_doctype_fields',
-			doc: frm.doc,
-			args: {
-				document_type: doc.document_type,
-				fields: document_fields
-			},
-			freeze: true,
-			callback: function(r) {
-				if (r.message) {
-					let doctype = 'Patient History Custom Document Type';
-					if (standard)
-						doctype = 'Patient History Standard Document Type';
-
-					frm.events.show_field_selector_dialog(frm, doc, doctype, r.message);
-				}
-			}
-		});
-	},
-
-	show_field_selector_dialog: function(frm, doc, doctype, doc_fields) {
-		let d = new frappe.ui.Dialog({
-			title: __('{0} Fields', [__(doc.document_type)]),
-			fields: [
-				{
-					label: __('Select Fields'),
-					fieldtype: 'MultiCheck',
-					fieldname: 'fields',
-					options: doc_fields,
-					columns: 2
-				}
-			]
-		});
-
-		d.$body.prepend(`
-			<div class="columns-search">
-				<input type="text" placeholder="${__('Search')}" data-element="search" class="form-control input-xs">
-			</div>`
-		);
-
-		frappe.utils.setup_search(d.$body, '.unit-checkbox', '.label-area');
-
-		d.set_primary_action(__('Save'), () => {
-			let values = d.get_values().fields;
-
-			let selected_fields = [];
-
-			frappe.model.with_doctype(doc.document_type, function() {
-				for (let idx in values) {
-					let value = values[idx];
-
-					let field = frappe.get_meta(doc.document_type).fields.filter((df) => df.fieldname == value)[0];
-					if (field) {
-						selected_fields.push({
-							label: field.label,
-							fieldname: field.fieldname,
-							fieldtype: field.fieldtype
-						});
-					}
-				}
-
-				d.refresh();
-				frappe.model.set_value(doctype, doc.name, 'selected_fields', JSON.stringify(selected_fields));
-			});
-
-			d.hide();
-		});
-
-		d.show();
-	},
-
-	get_date_field_for_dt: function(frm, row) {
-		frm.call({
-			method: 'get_date_field_for_dt',
-			doc: frm.doc,
-			args: {
-				document_type: row.document_type
-			},
-			callback: function(data) {
-				if (data.message) {
-					frappe.model.set_value('Patient History Custom Document Type',
-						row.name, 'date_fieldname', data.message);
-				}
-			}
-		});
-	}
-});
-
-frappe.ui.form.on('Patient History Custom Document Type', {
-	document_type: function(frm, cdt, cdn) {
-		let row = locals[cdt][cdn];
-		if (row.document_type) {
-			frm.events.get_date_field_for_dt(frm, row);
-		}
-	},
-
-	add_edit_fields: function(frm, cdt, cdn) {
-		let row = locals[cdt][cdn];
-		if (row.document_type) {
-			frm.events.field_selector(frm, row, 0);
-		}
-	}
-});
-
-frappe.ui.form.on('Patient History Standard Document Type', {
-	add_edit_fields: function(frm, cdt, cdn) {
-		let row = locals[cdt][cdn];
-		if (row.document_type) {
-			frm.events.field_selector(frm, row);
-		}
-	}
-});
diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.json b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.json
deleted file mode 100644
index 143e2c9..0000000
--- a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.json
+++ /dev/null
@@ -1,55 +0,0 @@
-{
- "actions": [],
- "creation": "2020-11-25 13:41:37.675518",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "standard_doctypes",
-  "section_break_2",
-  "custom_doctypes"
- ],
- "fields": [
-  {
-   "fieldname": "section_break_2",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "custom_doctypes",
-   "fieldtype": "Table",
-   "label": "Custom Document Types",
-   "options": "Patient History Custom Document Type"
-  },
-  {
-   "fieldname": "standard_doctypes",
-   "fieldtype": "Table",
-   "label": "Standard Document Types",
-   "options": "Patient History Standard Document Type",
-   "read_only": 1
-  }
- ],
- "index_web_pages_for_search": 1,
- "issingle": 1,
- "links": [],
- "modified": "2020-11-25 13:43:38.511771",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient History Settings",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "print": 1,
-   "read": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py
deleted file mode 100644
index b763591..0000000
--- a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py
+++ /dev/null
@@ -1,194 +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 json
-
-import frappe
-from frappe import _
-from frappe.model.document import Document
-from frappe.utils import cint, cstr
-
-from erpnext.healthcare.page.patient_history.patient_history import get_patient_history_doctypes
-
-
-class PatientHistorySettings(Document):
-	def validate(self):
-		self.validate_submittable_doctypes()
-		self.validate_date_fieldnames()
-
-	def validate_submittable_doctypes(self):
-		for entry in self.custom_doctypes:
-			if not cint(frappe.db.get_value('DocType', entry.document_type, 'is_submittable')):
-				msg = _('Row #{0}: Document Type {1} is not submittable.').format(
-					entry.idx, frappe.bold(entry.document_type))
-				msg += _('Patient Medical Record can only be created for submittable document types.')
-				frappe.throw(msg)
-
-	def validate_date_fieldnames(self):
-		for entry in self.custom_doctypes:
-			field = frappe.get_meta(entry.document_type).get_field(entry.date_fieldname)
-			if not field:
-				frappe.throw(_('Row #{0}: No such Field named {1} found in the Document Type {2}.').format(
-					entry.idx, frappe.bold(entry.date_fieldname), frappe.bold(entry.document_type)))
-
-			if field.fieldtype not in ['Date', 'Datetime']:
-				frappe.throw(_('Row #{0}: Field {1} in Document Type {2} is not a Date / Datetime field.').format(
-					entry.idx, frappe.bold(entry.date_fieldname), frappe.bold(entry.document_type)))
-
-	@frappe.whitelist()
-	def get_doctype_fields(self, document_type, fields):
-		multicheck_fields = []
-		doc_fields = frappe.get_meta(document_type).fields
-
-		for field in doc_fields:
-			if field.fieldtype not in frappe.model.no_value_fields or \
-				field.fieldtype in frappe.model.table_fields and not field.hidden:
-				multicheck_fields.append({
-					'label': field.label,
-					'value': field.fieldname,
-					'checked': 1 if field.fieldname in fields else 0
-				})
-
-		return multicheck_fields
-
-	@frappe.whitelist()
-	def get_date_field_for_dt(self, document_type):
-		meta = frappe.get_meta(document_type)
-		date_fields = meta.get('fields', {
-			'fieldtype': ['in', ['Date', 'Datetime']]
-		})
-
-		if date_fields:
-			return date_fields[0].get('fieldname')
-
-def create_medical_record(doc, method=None):
-	medical_record_required = validate_medical_record_required(doc)
-	if not medical_record_required:
-		return
-
-	if frappe.db.exists('Patient Medical Record', { 'reference_name': doc.name }):
-		return
-
-	subject = set_subject_field(doc)
-	date_field = get_date_field(doc.doctype)
-	medical_record = frappe.new_doc('Patient Medical Record')
-	medical_record.patient = doc.patient
-	medical_record.subject = subject
-	medical_record.status = 'Open'
-	medical_record.communication_date = doc.get(date_field)
-	medical_record.reference_doctype = doc.doctype
-	medical_record.reference_name = doc.name
-	medical_record.reference_owner = doc.owner
-	medical_record.save(ignore_permissions=True)
-
-
-def update_medical_record(doc, method=None):
-	medical_record_required = validate_medical_record_required(doc)
-	if not medical_record_required:
-		return
-
-	medical_record_id = frappe.db.exists('Patient Medical Record', { 'reference_name': doc.name })
-
-	if medical_record_id:
-		subject = set_subject_field(doc)
-		frappe.db.set_value('Patient Medical Record', medical_record_id[0][0], 'subject', subject)
-	else:
-		create_medical_record(doc)
-
-
-def delete_medical_record(doc, method=None):
-	medical_record_required = validate_medical_record_required(doc)
-	if not medical_record_required:
-		return
-
-	record = frappe.db.exists('Patient Medical Record', { 'reference_name': doc.name })
-	if record:
-		frappe.delete_doc('Patient Medical Record', record, force=1)
-
-
-def set_subject_field(doc):
-	from frappe.utils.formatters import format_value
-
-	meta = frappe.get_meta(doc.doctype)
-	subject = ''
-	patient_history_fields = get_patient_history_fields(doc)
-
-	for entry in patient_history_fields:
-		fieldname = entry.get('fieldname')
-		if entry.get('fieldtype') == 'Table' and doc.get(fieldname):
-			formatted_value = get_formatted_value_for_table_field(doc.get(fieldname), meta.get_field(fieldname))
-			subject += frappe.bold(_(entry.get('label')) + ':') + '<br>' + cstr(formatted_value) + '<br>'
-
-		else:
-			if doc.get(fieldname):
-				formatted_value = format_value(doc.get(fieldname), meta.get_field(fieldname), doc)
-				subject += frappe.bold(_(entry.get('label')) + ':') + cstr(formatted_value) + '<br>'
-
-	return subject
-
-
-def get_date_field(doctype):
-	dt = get_patient_history_config_dt(doctype)
-
-	return frappe.db.get_value(dt, { 'document_type': doctype }, 'date_fieldname')
-
-
-def get_patient_history_fields(doc):
-	dt = get_patient_history_config_dt(doc.doctype)
-	patient_history_fields = frappe.db.get_value(dt, { 'document_type': doc.doctype }, 'selected_fields')
-
-	if patient_history_fields:
-		return json.loads(patient_history_fields)
-
-
-def get_formatted_value_for_table_field(items, df):
-	child_meta = frappe.get_meta(df.options)
-
-	table_head = ''
-	table_row = ''
-	html = ''
-	create_head = True
-	for item in items:
-		table_row += '<tr>'
-		for cdf in child_meta.fields:
-			if cdf.in_list_view:
-				if create_head:
-					table_head += '<td>' + cdf.label + '</td>'
-				if item.get(cdf.fieldname):
-					table_row += '<td>' + str(item.get(cdf.fieldname)) + '</td>'
-				else:
-					table_row += '<td></td>'
-		create_head = False
-		table_row += '</tr>'
-
-	html += "<table class='table table-condensed table-bordered'>" + table_head +  table_row + "</table>"
-
-	return html
-
-
-def get_patient_history_config_dt(doctype):
-	if frappe.db.get_value('DocType', doctype, 'custom'):
-		return 'Patient History Custom Document Type'
-	else:
-		return 'Patient History Standard Document Type'
-
-
-def validate_medical_record_required(doc):
-	if frappe.flags.in_patch or frappe.flags.in_install or frappe.flags.in_setup_wizard \
-		or get_module(doc) != 'Healthcare':
-		return False
-
-	if doc.doctype not in get_patient_history_doctypes():
-		return False
-
-	return True
-
-def get_module(doc):
-	module = doc.meta.module
-	if not module:
-		module = frappe.db.get_value('DocType', doc.doctype, 'module')
-
-	return module
diff --git a/erpnext/healthcare/doctype/patient_history_settings/test_patient_history_settings.py b/erpnext/healthcare/doctype/patient_history_settings/test_patient_history_settings.py
deleted file mode 100644
index c37a2ad..0000000
--- a/erpnext/healthcare/doctype/patient_history_settings/test_patient_history_settings.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import json
-import unittest
-
-import frappe
-from frappe.utils import getdate, strip_html
-
-from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_patient
-
-
-class TestPatientHistorySettings(unittest.TestCase):
-	def setUp(self):
-		dt = create_custom_doctype()
-		settings = frappe.get_single("Patient History Settings")
-		settings.append("custom_doctypes", {
-			"document_type": dt.name,
-			"date_fieldname": "date",
-			"selected_fields": json.dumps([{
-				"label": "Date",
-				"fieldname": "date",
-				"fieldtype": "Date"
-			},
-			{
-				"label": "Rating",
-				"fieldname": "rating",
-				"fieldtype": "Rating"
-			},
-			{
-				"label": "Feedback",
-				"fieldname": "feedback",
-				"fieldtype": "Small Text"
-			}])
-		})
-		settings.save()
-
-	def test_custom_doctype_medical_record(self):
-		# tests for medical record creation of standard doctypes in test_patient_medical_record.py
-		patient = create_patient()
-		doc = create_doc(patient)
-		# check for medical record
-		medical_rec = frappe.db.exists("Patient Medical Record", {"status": "Open", "reference_name": doc.name})
-		self.assertTrue(medical_rec)
-
-		medical_rec = frappe.get_doc("Patient Medical Record", medical_rec)
-		expected_subject = "Date:{0}Rating:3Feedback:Test Patient History Settings".format(
-			frappe.utils.format_date(getdate()))
-		self.assertEqual(strip_html(medical_rec.subject), expected_subject)
-		self.assertEqual(medical_rec.patient, patient)
-		self.assertEqual(medical_rec.communication_date, getdate())
-
-
-def create_custom_doctype():
-	if not frappe.db.exists("DocType", "Test Patient Feedback"):
-		doc = frappe.get_doc({
-				"doctype": "DocType",
-				"module": "Healthcare",
-				"custom": 1,
-				"is_submittable": 1,
-				"fields": [{
-					"label": "Date",
-					"fieldname": "date",
-					"fieldtype": "Date"
-				},
-				{
-					"label": "Patient",
-					"fieldname": "patient",
-					"fieldtype": "Link",
-					"options": "Patient"
-				},
-				{
-					"label": "Rating",
-					"fieldname": "rating",
-					"fieldtype": "Rating"
-				},
-				{
-					"label": "Feedback",
-					"fieldname": "feedback",
-					"fieldtype": "Small Text"
-				}],
-				"permissions": [{
-					"role": "System Manager",
-					"read": 1
-				}],
-				"name": "Test Patient Feedback",
-			})
-		doc.insert()
-		return doc
-	else:
-		return frappe.get_doc("DocType", "Test Patient Feedback")
-
-
-def create_doc(patient):
-	doc = frappe.get_doc({
-		"doctype": "Test Patient Feedback",
-		"patient": patient,
-		"date": getdate(),
-		"rating": 3,
-		"feedback": "Test Patient History Settings"
-	}).insert()
-	doc.submit()
-
-	return doc
diff --git a/erpnext/healthcare/doctype/patient_history_standard_document_type/__init__.py b/erpnext/healthcare/doctype/patient_history_standard_document_type/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/patient_history_standard_document_type/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json
deleted file mode 100644
index b43099c..0000000
--- a/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- "actions": [],
- "creation": "2020-11-25 13:39:36.014814",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "document_type",
-  "date_fieldname",
-  "add_edit_fields",
-  "selected_fields"
- ],
- "fields": [
-  {
-   "fieldname": "document_type",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Document Type",
-   "options": "DocType",
-   "read_only": 1,
-   "reqd": 1
-  },
-  {
-   "fieldname": "selected_fields",
-   "fieldtype": "Code",
-   "label": "Selected Fields",
-   "read_only": 1
-  },
-  {
-   "fieldname": "add_edit_fields",
-   "fieldtype": "Button",
-   "in_list_view": 1,
-   "label": "Add / Edit Fields"
-  },
-  {
-   "fieldname": "date_fieldname",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Date Fieldname",
-   "read_only": 1,
-   "reqd": 1
-  }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2020-11-30 13:54:56.773325",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient History Standard Document Type",
- "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/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.py b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.py
deleted file mode 100644
index b7dd09b..0000000
--- a/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.py
+++ /dev/null
@@ -1,12 +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 PatientHistoryStandardDocumentType(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/patient_medical_record/__init__.py b/erpnext/healthcare/doctype/patient_medical_record/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/patient_medical_record/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.js b/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.js
deleted file mode 100644
index 93ff70e..0000000
--- a/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2016, ESS LLP and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Patient Medical Record', {
-});
diff --git a/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json b/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json
deleted file mode 100644
index ed82355..0000000
--- a/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json
+++ /dev/null
@@ -1,155 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "allow_import": 1,
- "autoname": "naming_series:",
- "beta": 1,
- "creation": "2016-06-09 11:30:44.972056",
- "doctype": "DocType",
- "document_type": "Setup",
- "engine": "InnoDB",
- "field_order": [
-  "naming_series",
-  "patient",
-  "status",
-  "column_break_2",
-  "attach",
-  "section_break_4",
-  "subject",
-  "section_break_8",
-  "communication_date",
-  "reference_doctype",
-  "reference_name",
-  "column_break_9",
-  "reference_owner",
-  "user"
- ],
- "fields": [
-  {
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "label": "Series",
-   "options": "HLC-PMR-.YYYY.-",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "label": "Patient",
-   "options": "Patient",
-   "search_index": 1
-  },
-  {
-   "fieldname": "column_break_2",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "attach",
-   "fieldtype": "Attach",
-   "label": "Attach Medical Record"
-  },
-  {
-   "fieldname": "section_break_4",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "subject",
-   "fieldtype": "Text Editor",
-   "ignore_xss_filter": 1,
-   "label": "Subject"
-  },
-  {
-   "fieldname": "status",
-   "fieldtype": "Select",
-   "label": "Status",
-   "options": "Open\nClose",
-   "read_only": 1
-  },
-  {
-   "default": "Today",
-   "fieldname": "communication_date",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "label": "Datetime",
-   "read_only": 1
-  },
-  {
-   "fieldname": "reference_doctype",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Reference DocType",
-   "options": "DocType",
-   "read_only": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "reference_name",
-   "fieldtype": "Dynamic Link",
-   "in_list_view": 1,
-   "label": "Reference Name",
-   "options": "reference_doctype",
-   "read_only": 1,
-   "search_index": 1
-  },
-  {
-   "fetch_from": "reference_name.owner",
-   "fieldname": "reference_owner",
-   "fieldtype": "Data",
-   "label": "Reference Owner",
-   "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "default": "__user",
-   "fieldname": "user",
-   "fieldtype": "Link",
-   "label": "User",
-   "options": "User",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "column_break_9",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "section_break_8",
-   "fieldtype": "Section Break"
-  }
- ],
- "in_create": 1,
- "links": [],
- "modified": "2020-04-29 12:26:57.679402",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Medical Record",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "write": 1
-  }
- ],
- "restrict_to_domain": "Healthcare",
- "search_fields": "patient, subject, communication_date, reference_doctype, reference_name",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "patient",
- "track_changes": 1,
- "track_seen": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.py b/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.py
deleted file mode 100644
index ac2cffa..0000000
--- a/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-import frappe
-from frappe.model.document import Document
-
-
-class PatientMedicalRecord(Document):
-	def after_insert(self):
-		if self.reference_doctype == "Patient Medical Record" :
-			frappe.db.set_value("Patient Medical Record", self.name, "reference_name", self.name)
diff --git a/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.py b/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.py
deleted file mode 100644
index 099146c..0000000
--- a/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-import frappe
-from frappe.utils import nowdate
-
-from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
-from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import (
-	create_appointment,
-	create_encounter,
-	create_healthcare_docs,
-	create_medical_department,
-)
-
-
-class TestPatientMedicalRecord(unittest.TestCase):
-	def setUp(self):
-		frappe.db.set_value('Healthcare Settings', None, 'enable_free_follow_ups', 0)
-		frappe.db.set_value('Healthcare Settings', None, 'automate_appointment_invoicing', 1)
-		make_pos_profile()
-
-	def test_medical_record(self):
-		patient, practitioner = create_healthcare_docs()
-		medical_department = create_medical_department()
-		appointment = create_appointment(patient, practitioner, nowdate(), invoice=1)
-		encounter = create_encounter(appointment)
-
-		# check for encounter
-		medical_rec = frappe.db.exists('Patient Medical Record', {'status': 'Open', 'reference_name': encounter.name})
-		self.assertTrue(medical_rec)
-
-		vital_signs = create_vital_signs(appointment)
-		# check for vital signs
-		medical_rec = frappe.db.exists('Patient Medical Record', {'status': 'Open', 'reference_name': vital_signs.name})
-		self.assertTrue(medical_rec)
-
-		appointment = create_appointment(patient, practitioner, nowdate(), invoice=1, procedure_template=1)
-		procedure = create_procedure(appointment)
-		procedure.start_procedure()
-		procedure.complete_procedure()
-		# check for clinical procedure
-		medical_rec = frappe.db.exists('Patient Medical Record', {'status': 'Open', 'reference_name': procedure.name})
-		self.assertTrue(medical_rec)
-
-		template = create_lab_test_template(medical_department)
-		lab_test = create_lab_test(template.name, patient)
-		# check for lab test
-		medical_rec = frappe.db.exists('Patient Medical Record', {'status': 'Open', 'reference_name': lab_test.name})
-		self.assertTrue(medical_rec)
-
-
-def create_procedure(appointment):
-	if appointment:
-		procedure = frappe.new_doc('Clinical Procedure')
-		procedure.procedure_template = appointment.procedure_template
-		procedure.appointment = appointment.name
-		procedure.patient = appointment.patient
-		procedure.practitioner = appointment.practitioner
-		procedure.medical_department = appointment.department
-		procedure.start_dt = appointment.appointment_date
-		procedure.start_time = appointment.appointment_time
-		procedure.save()
-		procedure.submit()
-		return procedure
-
-def create_vital_signs(appointment):
-	vital_signs = frappe.new_doc('Vital Signs')
-	vital_signs.patient = appointment.patient
-	vital_signs.signs_date = appointment.appointment_date
-	vital_signs.signs_time = appointment.appointment_time
-	vital_signs.temperature = 38.5
-	vital_signs.save()
-	vital_signs.submit()
-	return vital_signs
-
-def create_lab_test_template(medical_department):
-	if frappe.db.exists('Lab Test Template', 'Blood Test'):
-		return frappe.get_doc('Lab Test Template', 'Blood Test')
-
-	template = frappe.new_doc('Lab Test Template')
-	template.lab_test_name = 'Blood Test'
-	template.lab_test_code = 'Blood Test'
-	template.lab_test_group = 'Services'
-	template.department = medical_department
-	template.is_billable = 1
-	template.lab_test_rate = 2000
-	template.save()
-	return template
-
-def create_lab_test(template, patient):
-	lab_test = frappe.new_doc('Lab Test')
-	lab_test.patient = patient
-	lab_test.patient_sex = frappe.db.get_value('Patient', patient, 'sex')
-	lab_test.template = template
-	lab_test.save()
-	lab_test.submit()
-	return lab_test
diff --git a/erpnext/healthcare/doctype/patient_relation/__init__.py b/erpnext/healthcare/doctype/patient_relation/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/patient_relation/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/patient_relation/patient_relation.json b/erpnext/healthcare/doctype/patient_relation/patient_relation.json
deleted file mode 100644
index 376f7f7..0000000
--- a/erpnext/healthcare/doctype/patient_relation/patient_relation.json
+++ /dev/null
@@ -1,52 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "beta": 1,
- "creation": "2017-04-26 15:40:11.561855",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "patient",
-  "relation",
-  "description"
- ],
- "fields": [
-  {
-   "fieldname": "relation",
-   "fieldtype": "Select",
-   "in_list_view": 1,
-   "label": "Relation",
-   "options": "\nFather\nMother\nSpouse\nSiblings\nFamily\nOther",
-   "search_index": 1
-  },
-  {
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "label": "Patient",
-   "options": "Patient",
-   "reqd": 1
-  },
-  {
-   "fieldname": "description",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Description"
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-01-29 12:45:40.081899",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Relation",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_relation/patient_relation.py b/erpnext/healthcare/doctype/patient_relation/patient_relation.py
deleted file mode 100644
index 17bc209..0000000
--- a/erpnext/healthcare/doctype/patient_relation/patient_relation.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class PatientRelation(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/practitioner_schedule/__init__.py b/erpnext/healthcare/doctype/practitioner_schedule/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/practitioner_schedule/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.js b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.js
deleted file mode 100644
index 7cb7c4b..0000000
--- a/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.js
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Practitioner Schedule', {
-	refresh: function(frm) {
-		cur_frm.fields_dict["time_slots"].grid.wrapper.find('.grid-add-row').hide();
-		cur_frm.fields_dict["time_slots"].grid.add_custom_button(__('Add Time Slots'), () => {
-			let d = new frappe.ui.Dialog({
-				fields: [
-					{fieldname: 'days', label: __('Select Days'), fieldtype: 'MultiSelect',
-						options:[
-							{value:'Sunday', label:__('Sunday')},
-							{value:'Monday', label:__('Monday')},
-							{value:'Tuesday', label:__('Tuesday')},
-							{value:'Wednesday', label:__('Wednesday')},
-							{value:'Thursday', label:__('Thursday')},
-							{value:'Friday', label:__('Friday')},
-							{value:'Saturday', label:__('Saturday')},
-						], reqd: 1},
-					{fieldname: 'from_time', label: __('From'), fieldtype: 'Time',
-						'default': '09:00:00', reqd: 1},
-					{fieldname: 'to_time', label: __('To'), fieldtype: 'Time',
-						'default': '12:00:00', reqd: 1},
-					{fieldname: 'duration', label: __('Appointment Duration (mins)'),
-						fieldtype:'Int', 'default': 15, reqd: 1},
-				],
-				primary_action_label: __('Add Timeslots'),
-				primary_action: () => {
-					let values = d.get_values();
-					if (values) {
-						let slot_added = false;
-						values.days.split(',').forEach(function(day){
-							day = $.trim(day);
-							if (['Sunday', 'Monday', 'Tuesday', 'Wednesday',
-							'Thursday', 'Friday', 'Saturday'].includes(day)){
-								add_slots(day);
-							}
-						});
-
-						function check_overlap_or_add_slot(week_day, cur_time, end_time, add_slots_to_child){
-							let overlap = false;
-							while (cur_time < end_time) {
-								let add_to_child = true;
-								let to_time = cur_time.clone().add(values.duration, 'minutes');
-								if (to_time <= end_time) {
-									if (frm.doc.time_slots){
-										frm.doc.time_slots.forEach(function(slot) {
-											if (slot.day == week_day){
-												let slot_from_moment = moment(slot.from_time, 'HH:mm:ss');
-												let slot_to_moment = moment(slot.to_time, 'HH:mm:ss');
-												if (cur_time.isSame(slot_from_moment)	||	cur_time.isBetween(slot_from_moment, slot_to_moment)	||
-												to_time.isSame(slot_to_moment)	||	to_time.isBetween(slot_from_moment, slot_to_moment)) {
-													overlap = true;
-													if (add_slots_to_child) {
-														frappe.show_alert({
-															message:__('Time slot skiped, the slot {0} to {1} overlap exisiting slot {2} to {3}',
-																[cur_time.format('HH:mm:ss'),	to_time.format('HH:mm:ss'),	slot.from_time,	slot.to_time]),
-															indicator:'orange'
-														});
-														add_to_child = false;
-													}
-												}
-											}
-										});
-									}
-									// add a new timeslot
-									if (add_to_child && add_slots_to_child) {
-										frm.add_child('time_slots', {
-											from_time: cur_time.format('HH:mm:ss'),
-											to_time: to_time.format('HH:mm:ss'),
-											day: week_day
-										});
-										slot_added = true;
-									}
-								}
-								cur_time = to_time;
-							}
-							return overlap;
-						}
-
-						function add_slots(week_day) {
-							let cur_time = moment(values.from_time, 'HH:mm:ss');
-							let end_time = moment(values.to_time, 'HH:mm:ss');
-							if (check_overlap_or_add_slot(week_day, cur_time, end_time, false)) {
-								frappe.confirm(__('Schedules for {0} overlaps, do you want to proceed after skiping overlaped slots ?',	[week_day]),
-									function() {
-										// if Yes
-										check_overlap_or_add_slot(week_day, cur_time, end_time, true);
-									},
-									function() {
-										// if No
-										frappe.show_alert({
-											message: __('Slots for {0} are not added to the schedule',	[week_day]),
-											indicator: 'red'
-										});
-									}
-								);
-							} else {
-								check_overlap_or_add_slot(week_day, cur_time, end_time, true);
-							}
-						}
-
-						frm.refresh_field('time_slots');
-
-						if (slot_added) {
-							frappe.show_alert({
-								message: __('Time slots added'),
-								indicator: 'green'
-							});
-						}
-					}
-				},
-			});
-			d.show();
-		});
-	}
-});
diff --git a/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json
deleted file mode 100644
index a21825e..0000000
--- a/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json
+++ /dev/null
@@ -1,71 +0,0 @@
-{
- "actions": [],
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:schedule_name",
- "beta": 1,
- "creation": "2017-05-03 17:28:03.926787",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "disabled",
-  "schedule_details_section",
-  "schedule_name",
-  "time_slots"
- ],
- "fields": [
-  {
-   "fieldname": "schedule_name",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Schedule Name",
-   "reqd": 1,
-   "unique": 1
-  },
-  {
-   "fieldname": "time_slots",
-   "fieldtype": "Table",
-   "label": "Time Slots",
-   "options": "Healthcare Schedule Time Slot"
-  },
-  {
-   "default": "0",
-   "fieldname": "disabled",
-   "fieldtype": "Check",
-   "label": "Disabled",
-   "print_hide": 1
-  },
-  {
-   "fieldname": "schedule_details_section",
-   "fieldtype": "Section Break",
-   "label": "Schedule Details"
-  }
- ],
- "links": [],
- "modified": "2020-09-18 17:26:09.703215",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Practitioner Schedule",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  }
- ],
- "restrict_to_domain": "Healthcare",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.py b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.py
deleted file mode 100644
index 7fa31e5..0000000
--- a/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class PractitionerSchedule(Document):
-	def autoname(self):
-		self.name = self.schedule_name
diff --git a/erpnext/healthcare/doctype/practitioner_schedule/test_practitioner_schedule.py b/erpnext/healthcare/doctype/practitioner_schedule/test_practitioner_schedule.py
deleted file mode 100644
index 1ecaa47..0000000
--- a/erpnext/healthcare/doctype/practitioner_schedule/test_practitioner_schedule.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-
-class TestPractitionerSchedule(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/practitioner_service_unit_schedule/__init__.py b/erpnext/healthcare/doctype/practitioner_service_unit_schedule/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/practitioner_service_unit_schedule/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/practitioner_service_unit_schedule/practitioner_service_unit_schedule.json b/erpnext/healthcare/doctype/practitioner_service_unit_schedule/practitioner_service_unit_schedule.json
deleted file mode 100644
index 4c283aa..0000000
--- a/erpnext/healthcare/doctype/practitioner_service_unit_schedule/practitioner_service_unit_schedule.json
+++ /dev/null
@@ -1,110 +0,0 @@
-{
- "allow_copy": 0, 
- "allow_events_in_timeline": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "beta": 1, 
- "creation": "2017-11-16 12:19:17.163786", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
- "fields": [
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "schedule", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Schedule", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Practitioner Schedule", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "service_unit", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Service Unit", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Healthcare Service Unit", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 1, 
- "max_attachments": 0, 
- "modified": "2018-11-04 03:33:07.936958", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "Practitioner Service Unit Schedule", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Healthcare", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0, 
- "track_views": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/practitioner_service_unit_schedule/practitioner_service_unit_schedule.py b/erpnext/healthcare/doctype/practitioner_service_unit_schedule/practitioner_service_unit_schedule.py
deleted file mode 100644
index 4eba1fb..0000000
--- a/erpnext/healthcare/doctype/practitioner_service_unit_schedule/practitioner_service_unit_schedule.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class PractitionerServiceUnitSchedule(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/prescription_dosage/prescription_dosage.js b/erpnext/healthcare/doctype/prescription_dosage/prescription_dosage.js
deleted file mode 100644
index 94b444c..0000000
--- a/erpnext/healthcare/doctype/prescription_dosage/prescription_dosage.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Prescription Dosage', {
-});
diff --git a/erpnext/healthcare/doctype/prescription_dosage/prescription_dosage.json b/erpnext/healthcare/doctype/prescription_dosage/prescription_dosage.json
deleted file mode 100644
index 9fb0dbc..0000000
--- a/erpnext/healthcare/doctype/prescription_dosage/prescription_dosage.json
+++ /dev/null
@@ -1,145 +0,0 @@
-{
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 1, 
- "autoname": "field:dosage", 
- "beta": 1, 
- "creation": "2016-09-16 15:49:25.327610", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "Document", 
- "editable_grid": 0, 
- "fields": [
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "dosage", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 1, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Dosage", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "dosage_strength", 
-   "fieldtype": "Table", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Dosage Strength", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2017-10-05 11:20:47.558464", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "Prescription Dosage", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Healthcare Administrator", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Physician", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }
- ], 
- "quick_entry": 0, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Healthcare", 
- "search_fields": "dosage", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "title_field": "", 
- "track_changes": 1, 
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/prescription_dosage/prescription_dosage.py b/erpnext/healthcare/doctype/prescription_dosage/prescription_dosage.py
deleted file mode 100644
index 19f9b70..0000000
--- a/erpnext/healthcare/doctype/prescription_dosage/prescription_dosage.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class PrescriptionDosage(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/prescription_dosage/test_prescription_dosage.py b/erpnext/healthcare/doctype/prescription_dosage/test_prescription_dosage.py
deleted file mode 100644
index cabfd35..0000000
--- a/erpnext/healthcare/doctype/prescription_dosage/test_prescription_dosage.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-
-class TestPrescriptionDosage(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/prescription_duration/__init__.py b/erpnext/healthcare/doctype/prescription_duration/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/prescription_duration/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/prescription_duration/prescription_duration.js b/erpnext/healthcare/doctype/prescription_duration/prescription_duration.js
deleted file mode 100644
index dd5887c..0000000
--- a/erpnext/healthcare/doctype/prescription_duration/prescription_duration.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Prescription Duration', {
-});
diff --git a/erpnext/healthcare/doctype/prescription_duration/prescription_duration.json b/erpnext/healthcare/doctype/prescription_duration/prescription_duration.json
deleted file mode 100644
index c4f6c5f..0000000
--- a/erpnext/healthcare/doctype/prescription_duration/prescription_duration.json
+++ /dev/null
@@ -1,145 +0,0 @@
-{
- "allow_copy": 1, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 1, 
- "autoname": "", 
- "beta": 1, 
- "creation": "2016-09-16 15:50:28.895789", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "Document", 
- "editable_grid": 0, 
- "fields": [
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "number", 
-   "fieldtype": "Int", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Number", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "period", 
-   "fieldtype": "Select", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Period", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Hour\nDay\nWeek\nMonth", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2017-08-31 13:42:51.325725", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "Prescription Duration", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Healthcare Administrator", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Physician", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Healthcare", 
- "search_fields": "", 
- "show_name_in_global_search": 0, 
- "sort_field": "", 
- "sort_order": "ASC", 
- "track_changes": 1, 
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/prescription_duration/prescription_duration.py b/erpnext/healthcare/doctype/prescription_duration/prescription_duration.py
deleted file mode 100644
index 988276d..0000000
--- a/erpnext/healthcare/doctype/prescription_duration/prescription_duration.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-from frappe.utils import cstr
-
-
-class PrescriptionDuration(Document):
-	def autoname(self):
-		self.name = " ".join(filter(None,
-			[cstr(self.get(f)).strip() for f in ["number", "period"]]))
-	def get_days(self):
-		days = 0
-		duration = self
-		if(duration.period == 'Day'):
-			days = duration.number
-		if(duration.period == 'Hour'):
-			days = (duration.number)/24
-		if(duration.period == 'Week'):
-			days = (duration.number*7)
-		if(duration.period == 'Month'):
-			days = (duration.number*30)
-		return days
-	def get_weeks(self):
-		weeks = 0
-		duration = self
-		if(duration.period == 'Day'):
-			weeks = (duration.number)/7
-		#if(duration.period == 'Hour'):
-		#	weeks = (duration.number)/x
-		if(duration.period == 'Week'):
-			weeks = duration.number
-		if(duration.period == 'Month'):
-			weeks = duration.number*4
-		return weeks
-	def get_months(self):
-		months = 0
-		duration = self
-		if(duration.period == 'Day'):
-			months = (duration.number)/30
-		#if(duration.period == 'Hour'):
-		#	months = (duration.number)/x
-		if(duration.period == 'Week'):
-			months = (duration.number)/4
-		if(duration.period == 'Month'):
-			months = duration.number
-		return months
-	def get_hours(self):
-		hours = 0
-		duration = self
-		if(duration.period == 'Day'):
-			hours = (duration.number*24)
-		if(duration.period == 'Hour'):
-			hours = duration.number
-		if(duration.period == 'Week'):
-			hours = (duration.number*24)*7
-		if(duration.period == 'Month'):
-			hours = (duration.number*24)*30
-		return hours
-	def get_minutes(self):
-		minutes = 0
-		duration = self
-		if(duration.period == 'Day'):
-			minutes = (duration.number*1440)
-		if(duration.period == 'Hour'):
-			minutes = (duration.number*60)
-		if(duration.period == 'Week'):
-			minutes = (duration.number*10080)
-		if(duration.period == 'Month'):
-			minutes = (duration.number*43800)
-		return minutes
diff --git a/erpnext/healthcare/doctype/prescription_duration/test_prescription_duration.py b/erpnext/healthcare/doctype/prescription_duration/test_prescription_duration.py
deleted file mode 100644
index 197bb3e..0000000
--- a/erpnext/healthcare/doctype/prescription_duration/test_prescription_duration.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-
-class TestPrescriptionDuration(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/procedure_prescription/__init__.py b/erpnext/healthcare/doctype/procedure_prescription/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/procedure_prescription/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json b/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
deleted file mode 100644
index e4c01d7..0000000
--- a/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
+++ /dev/null
@@ -1,99 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "beta": 1,
- "creation": "2017-11-17 15:52:48.324157",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "procedure",
-  "procedure_name",
-  "department",
-  "practitioner",
-  "date",
-  "comments",
-  "appointment_booked",
-  "procedure_created",
-  "invoiced"
- ],
- "fields": [
-  {
-   "fieldname": "procedure",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Clinical Procedure",
-   "options": "Clinical Procedure Template",
-   "reqd": 1
-  },
-  {
-   "fetch_from": "procedure.template",
-   "fieldname": "procedure_name",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Procedure Name"
-  },
-  {
-   "fetch_from": "procedure.medical_department",
-   "fieldname": "department",
-   "fieldtype": "Link",
-   "label": "Department",
-   "options": "Medical Department"
-  },
-  {
-   "fieldname": "practitioner",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Referring Practitioner",
-   "options": "Healthcare Practitioner"
-  },
-  {
-   "fieldname": "date",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "label": "Date"
-  },
-  {
-   "fieldname": "comments",
-   "fieldtype": "Data",
-   "label": "Comments"
-  },
-  {
-   "default": "0",
-   "fieldname": "appointment_booked",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "label": "Appointment Booked",
-   "search_index": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "procedure_created",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "label": "Procedure Created",
-   "no_copy": 1,
-   "search_index": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "invoiced",
-   "fieldtype": "Check",
-   "label": "Invoiced",
-   "read_only": 1,
-   "search_index": 1
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-02-26 15:42:33.988081",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Procedure Prescription",
- "owner": "Administrator",
- "permissions": [],
- "restrict_to_domain": "Healthcare",
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.py b/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.py
deleted file mode 100644
index f4d29fa..0000000
--- a/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class ProcedurePrescription(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/sample_collection/__init__.py b/erpnext/healthcare/doctype/sample_collection/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/sample_collection/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/sample_collection/sample_collection.js b/erpnext/healthcare/doctype/sample_collection/sample_collection.js
deleted file mode 100644
index ddf8285..0000000
--- a/erpnext/healthcare/doctype/sample_collection/sample_collection.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2016, ESS and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Sample Collection', {
-	refresh: function(frm) {
-		if (frappe.defaults.get_default('create_sample_collection_for_lab_test')) {
-			frm.add_custom_button(__('View Lab Tests'), function() {
-				frappe.route_options = {'sample': frm.doc.name};
-				frappe.set_route('List', 'Lab Test');
-			});
-		}
-	}
-});
-
-frappe.ui.form.on('Sample Collection', 'patient', function(frm) {
-	if(frm.doc.patient){
-		frappe.call({
-			'method': 'erpnext.healthcare.doctype.patient.patient.get_patient_detail',
-			args: {
-				patient: frm.doc.patient
-			},
-			callback: function (data) {
-				var age = null;
-				if (data.message.dob){
-					age = calculate_age(data.message.dob);
-				}
-				frappe.model.set_value(frm.doctype,frm.docname, 'patient_age', age);
-				frappe.model.set_value(frm.doctype,frm.docname, 'patient_sex', data.message.sex);
-			}
-		});
-	}
-});
-
-var calculate_age = function(birth) {
-	var	ageMS = Date.parse(Date()) - Date.parse(birth);
-	var	age = new Date();
-	age.setTime(ageMS);
-	var	years =  age.getFullYear() - 1970;
-	return `${years} ${__('Years(s)')} ${age.getMonth()} ${__('Month(s)')} ${age.getDate()} ${__('Day(s)')}`;
-};
diff --git a/erpnext/healthcare/doctype/sample_collection/sample_collection.json b/erpnext/healthcare/doctype/sample_collection/sample_collection.json
deleted file mode 100644
index 83383e3..0000000
--- a/erpnext/healthcare/doctype/sample_collection/sample_collection.json
+++ /dev/null
@@ -1,256 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "allow_import": 1,
- "autoname": "naming_series:",
- "beta": 1,
- "creation": "2016-04-05 15:58:18.076977",
- "doctype": "DocType",
- "document_type": "Document",
- "engine": "InnoDB",
- "field_order": [
-  "patient_details_section",
-  "naming_series",
-  "patient",
-  "patient_name",
-  "patient_age",
-  "patient_sex",
-  "column_break_4",
-  "inpatient_record",
-  "company",
-  "invoiced",
-  "section_break_6",
-  "sample",
-  "sample_uom",
-  "sample_qty",
-  "column_break_10",
-  "collected_by",
-  "collected_time",
-  "num_print",
-  "section_break_15",
-  "sample_details",
-  "amended_from"
- ],
- "fields": [
-  {
-   "fetch_from": "patient.inpatient_record",
-   "fieldname": "inpatient_record",
-   "fieldtype": "Link",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Inpatient Record",
-   "options": "Inpatient Record",
-   "read_only": 1
-  },
-  {
-   "bold": 1,
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Series",
-   "no_copy": 1,
-   "options": "HLC-SC-.YYYY.-",
-   "print_hide": 1,
-   "reqd": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "invoiced",
-   "fieldtype": "Check",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Invoiced",
-   "no_copy": 1,
-   "read_only": 1,
-   "search_index": 1
-  },
-  {
-   "fetch_from": "inpatient_record.patient",
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "ignore_user_permissions": 1,
-   "in_standard_filter": 1,
-   "label": "Patient",
-   "options": "Patient",
-   "reqd": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "column_break_4",
-   "fieldtype": "Column Break",
-   "hide_days": 1,
-   "hide_seconds": 1
-  },
-  {
-   "fieldname": "patient_age",
-   "fieldtype": "Data",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Age",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "patient.sex",
-   "fieldname": "patient_sex",
-   "fieldtype": "Link",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Gender",
-   "options": "Gender",
-   "read_only": 1
-  },
-  {
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "in_standard_filter": 1,
-   "label": "Company",
-   "options": "Company"
-  },
-  {
-   "fieldname": "section_break_6",
-   "fieldtype": "Section Break",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Sample Details"
-  },
-  {
-   "fieldname": "sample",
-   "fieldtype": "Link",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Sample",
-   "options": "Lab Test Sample",
-   "reqd": 1,
-   "search_index": 1
-  },
-  {
-   "fetch_from": "sample.sample_uom",
-   "fieldname": "sample_uom",
-   "fieldtype": "Data",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "in_list_view": 1,
-   "label": "UOM",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_10",
-   "fieldtype": "Column Break",
-   "hide_days": 1,
-   "hide_seconds": 1
-  },
-  {
-   "fieldname": "collected_by",
-   "fieldtype": "Link",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "ignore_user_permissions": 1,
-   "label": "Collected By",
-   "options": "User"
-  },
-  {
-   "fieldname": "collected_time",
-   "fieldtype": "Datetime",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Collected On"
-  },
-  {
-   "allow_on_submit": 1,
-   "default": "1",
-   "description": "Number of prints required for labelling the samples",
-   "fieldname": "num_print",
-   "fieldtype": "Int",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "No. of prints",
-   "print_hide": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "amended_from",
-   "fieldtype": "Link",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "label": "Amended From",
-   "no_copy": 1,
-   "options": "Sample Collection",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "section_break_15",
-   "fieldtype": "Section Break",
-   "hide_days": 1,
-   "hide_seconds": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "sample_qty",
-   "fieldtype": "Float",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "in_list_view": 1,
-   "label": "Quantity"
-  },
-  {
-   "fieldname": "sample_details",
-   "fieldtype": "Long Text",
-   "hide_days": 1,
-   "hide_seconds": 1,
-   "ignore_xss_filter": 1,
-   "label": "Collection Details"
-  },
-  {
-   "fieldname": "patient_details_section",
-   "fieldtype": "Section Break",
-   "label": "Patient Details"
-  },
-  {
-   "fetch_from": "patient.patient_name",
-   "fieldname": "patient_name",
-   "fieldtype": "Data",
-   "label": "Patient Name",
-   "read_only": 1
-  }
- ],
- "is_submittable": 1,
- "links": [],
- "modified": "2020-07-30 16:53:13.076104",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Sample Collection",
- "owner": "Administrator",
- "permissions": [
-  {
-   "amend": 1,
-   "cancel": 1,
-   "create": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Laboratory User",
-   "share": 1,
-   "submit": 1,
-   "write": 1
-  }
- ],
- "restrict_to_domain": "Healthcare",
- "search_fields": "patient, sample",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "patient",
- "track_changes": 1,
- "track_seen": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/sample_collection/sample_collection.py b/erpnext/healthcare/doctype/sample_collection/sample_collection.py
deleted file mode 100644
index 7de6ac0..0000000
--- a/erpnext/healthcare/doctype/sample_collection/sample_collection.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS 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
-from frappe.utils import flt
-
-
-class SampleCollection(Document):
-	def validate(self):
-		if flt(self.sample_qty) <= 0:
-			frappe.throw(_('Sample Quantity cannot be negative or 0'), title=_('Invalid Quantity'))
diff --git a/erpnext/healthcare/doctype/sample_collection/test_sample_collection.py b/erpnext/healthcare/doctype/sample_collection/test_sample_collection.py
deleted file mode 100644
index 0b16173..0000000
--- a/erpnext/healthcare/doctype/sample_collection/test_sample_collection.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-# test_records = frappe.get_test_records('Sample Collection')
-
-class TestSampleCollection(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/sensitivity/__init__.py b/erpnext/healthcare/doctype/sensitivity/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/sensitivity/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/sensitivity/sensitivity.js b/erpnext/healthcare/doctype/sensitivity/sensitivity.js
deleted file mode 100644
index f9c9002..0000000
--- a/erpnext/healthcare/doctype/sensitivity/sensitivity.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2016, ESS LLP and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Sensitivity', {
-});
diff --git a/erpnext/healthcare/doctype/sensitivity/sensitivity.json b/erpnext/healthcare/doctype/sensitivity/sensitivity.json
deleted file mode 100644
index eddfda9..0000000
--- a/erpnext/healthcare/doctype/sensitivity/sensitivity.json
+++ /dev/null
@@ -1,115 +0,0 @@
-{
- "allow_copy": 1, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 1, 
- "autoname": "field:sensitivity", 
- "beta": 1, 
- "creation": "2016-02-23 11:12:54.623249", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "Setup", 
- "editable_grid": 0, 
- "fields": [
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "sensitivity", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 1, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Sensitivity", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2017-10-05 11:19:12.110308", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "Sensitivity", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 0, 
-   "delete": 0, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Laboratory User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 0
-  }, 
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Healthcare Administrator", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Healthcare", 
- "search_fields": "sensitivity", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "title_field": "sensitivity", 
- "track_changes": 1, 
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/sensitivity/sensitivity.py b/erpnext/healthcare/doctype/sensitivity/sensitivity.py
deleted file mode 100644
index f61781d..0000000
--- a/erpnext/healthcare/doctype/sensitivity/sensitivity.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class Sensitivity(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/sensitivity/test_sensitivity.py b/erpnext/healthcare/doctype/sensitivity/test_sensitivity.py
deleted file mode 100644
index c772c72..0000000
--- a/erpnext/healthcare/doctype/sensitivity/test_sensitivity.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-# test_records = frappe.get_test_records('Sensitivity')
-
-class TestSensitivity(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/sensitivity_test_result/__init__.py b/erpnext/healthcare/doctype/sensitivity_test_result/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/sensitivity_test_result/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/sensitivity_test_result/sensitivity_test_result.json b/erpnext/healthcare/doctype/sensitivity_test_result/sensitivity_test_result.json
deleted file mode 100644
index 768c177..0000000
--- a/erpnext/healthcare/doctype/sensitivity_test_result/sensitivity_test_result.json
+++ /dev/null
@@ -1,103 +0,0 @@
-{
- "allow_copy": 1,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 1,
- "creation": "2016-02-22 15:18:01.769903",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 1,
- "fields": [
-  {
-   "allow_bulk_edit": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fieldname": "antibiotic",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "ignore_user_permissions": 1,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 1,
-   "in_standard_filter": 0,
-   "label": "Antibiotic",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Antibiotic",
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "unique": 0
-  },
-  {
-   "allow_bulk_edit": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fieldname": "antibiotic_sensitivity",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "ignore_user_permissions": 1,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 1,
-   "in_standard_filter": 0,
-   "label": "Sensitivity",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Sensitivity",
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "unique": 0
-  }
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 1,
- "max_attachments": 0,
- "modified": "2017-10-05 11:08:06.327972",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Sensitivity Test Result",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 0,
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/sensitivity_test_result/sensitivity_test_result.py b/erpnext/healthcare/doctype/sensitivity_test_result/sensitivity_test_result.py
deleted file mode 100644
index 53f7acc..0000000
--- a/erpnext/healthcare/doctype/sensitivity_test_result/sensitivity_test_result.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-from frappe.model.document import Document
-
-
-class SensitivityTestResult(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/therapy_plan/__init__.py b/erpnext/healthcare/doctype/therapy_plan/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/therapy_plan/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py b/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py
deleted file mode 100644
index 4f96f6a..0000000
--- a/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-import frappe
-from frappe.utils import flt, getdate, nowdate
-
-from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import (
-	create_appointment,
-	create_healthcare_docs,
-	create_medical_department,
-	create_patient,
-)
-from erpnext.healthcare.doctype.therapy_plan.therapy_plan import (
-	make_sales_invoice,
-	make_therapy_session,
-)
-from erpnext.healthcare.doctype.therapy_type.test_therapy_type import create_therapy_type
-
-
-class TestTherapyPlan(unittest.TestCase):
-	def test_creation_on_encounter_submission(self):
-		patient, practitioner = create_healthcare_docs()
-		medical_department = create_medical_department()
-		encounter = create_encounter(patient, medical_department, practitioner)
-		self.assertTrue(frappe.db.exists('Therapy Plan', encounter.therapy_plan))
-
-	def test_status(self):
-		plan = create_therapy_plan()
-		self.assertEqual(plan.status, 'Not Started')
-
-		session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab', '_Test Company')
-		frappe.get_doc(session).submit()
-		self.assertEqual(frappe.db.get_value('Therapy Plan', plan.name, 'status'), 'In Progress')
-
-		session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab', '_Test Company')
-		frappe.get_doc(session).submit()
-		self.assertEqual(frappe.db.get_value('Therapy Plan', plan.name, 'status'), 'Completed')
-
-		patient, practitioner = create_healthcare_docs()
-		appointment = create_appointment(patient, practitioner, nowdate())
-
-		session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab', '_Test Company', appointment.name)
-		session = frappe.get_doc(session)
-		session.submit()
-		self.assertEqual(frappe.db.get_value('Patient Appointment', appointment.name, 'status'), 'Closed')
-		session.cancel()
-		self.assertEqual(frappe.db.get_value('Patient Appointment', appointment.name, 'status'), 'Open')
-
-	def test_therapy_plan_from_template(self):
-		patient = create_patient()
-		template = create_therapy_plan_template()
-		# check linked item
-		self.assertTrue(frappe.db.exists('Therapy Plan Template', {'linked_item': 'Complete Rehab'}))
-
-		plan = create_therapy_plan(template)
-		# invoice
-		si = make_sales_invoice(plan.name, patient, '_Test Company', template)
-		si.save()
-
-		therapy_plan_template_amt = frappe.db.get_value('Therapy Plan Template', template, 'total_amount')
-		self.assertEqual(si.items[0].amount, therapy_plan_template_amt)
-
-
-def create_therapy_plan(template=None):
-	patient = create_patient()
-	therapy_type = create_therapy_type()
-	plan = frappe.new_doc('Therapy Plan')
-	plan.patient = patient
-	plan.start_date = getdate()
-
-	if template:
-		plan.therapy_plan_template = template
-		plan = plan.set_therapy_details_from_template()
-	else:
-		plan.append('therapy_plan_details', {
-			'therapy_type': therapy_type.name,
-			'no_of_sessions': 2
-		})
-
-	plan.save()
-	return plan
-
-def create_encounter(patient, medical_department, practitioner):
-	encounter = frappe.new_doc('Patient Encounter')
-	encounter.patient = patient
-	encounter.practitioner = practitioner
-	encounter.medical_department = medical_department
-	therapy_type = create_therapy_type()
-	encounter.append('therapies', {
-		'therapy_type': therapy_type.name,
-		'no_of_sessions': 2
-	})
-	encounter.save()
-	encounter.submit()
-	return encounter
-
-def create_therapy_plan_template():
-	template_name = frappe.db.exists('Therapy Plan Template', 'Complete Rehab')
-	if not template_name:
-		therapy_type = create_therapy_type()
-		template = frappe.new_doc('Therapy Plan Template')
-		template.plan_name = template.item_code = template.item_name = 'Complete Rehab'
-		template.item_group = 'Services'
-		rate = frappe.db.get_value('Therapy Type', therapy_type.name, 'rate')
-		template.append('therapy_types', {
-			'therapy_type': therapy_type.name,
-			'no_of_sessions': 2,
-			'rate': rate,
-			'amount': 2 * flt(rate)
-		})
-		template.save()
-		template_name = template.name
-
-	return template_name
diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan.js b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.js
deleted file mode 100644
index 42e231d..0000000
--- a/erpnext/healthcare/doctype/therapy_plan/therapy_plan.js
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Therapy Plan', {
-	setup: function(frm) {
-		frm.get_field('therapy_plan_details').grid.editable_fields = [
-			{fieldname: 'therapy_type', columns: 6},
-			{fieldname: 'no_of_sessions', columns: 2},
-			{fieldname: 'sessions_completed', columns: 2}
-		];
-	},
-
-	refresh: function(frm) {
-		if (!frm.doc.__islocal) {
-			frm.trigger('show_progress_for_therapies');
-			if (frm.doc.status != 'Completed') {
-				let therapy_types = (frm.doc.therapy_plan_details || []).map(function(d){ return d.therapy_type; });
-				const fields = [{
-					fieldtype: 'Link',
-					label: __('Therapy Type'),
-					fieldname: 'therapy_type',
-					options: 'Therapy Type',
-					reqd: 1,
-					get_query: function() {
-						return {
-							filters: { 'therapy_type': ['in', therapy_types]}
-						};
-					}
-				}];
-
-				frm.add_custom_button(__('Therapy Session'), function() {
-					frappe.prompt(fields, data => {
-						frappe.call({
-							method: 'erpnext.healthcare.doctype.therapy_plan.therapy_plan.make_therapy_session',
-							args: {
-								therapy_plan: frm.doc.name,
-								patient: frm.doc.patient,
-								therapy_type: data.therapy_type,
-								company: frm.doc.company
-							},
-							freeze: true,
-							callback: function(r) {
-								if (r.message) {
-									frappe.model.sync(r.message);
-									frappe.set_route('Form', r.message.doctype, r.message.name);
-								}
-							}
-						});
-					}, __('Select Therapy Type'), __('Create'));
-				}, __('Create'));
-			}
-
-			if (frm.doc.therapy_plan_template && !frm.doc.invoiced) {
-				frm.add_custom_button(__('Sales Invoice'), function() {
-					frm.trigger('make_sales_invoice');
-				}, __('Create'));
-			}
-		}
-
-		if (frm.doc.therapy_plan_template) {
-			frm.fields_dict.therapy_plan_details.grid.update_docfield_property(
-				'therapy_type', 'read_only', 1
-			);
-			frm.fields_dict.therapy_plan_details.grid.update_docfield_property(
-				'no_of_sessions', 'read_only', 1
-			);
-		}
-	},
-
-	make_sales_invoice: function(frm) {
-		frappe.call({
-			args: {
-				'reference_name': frm.doc.name,
-				'patient': frm.doc.patient,
-				'company': frm.doc.company,
-				'therapy_plan_template': frm.doc.therapy_plan_template
-			},
-			method: 'erpnext.healthcare.doctype.therapy_plan.therapy_plan.make_sales_invoice',
-			callback: function(r) {
-				var doclist = frappe.model.sync(r.message);
-				frappe.set_route('Form', doclist[0].doctype, doclist[0].name);
-			}
-		});
-	},
-
-	therapy_plan_template: function(frm) {
-		if (frm.doc.therapy_plan_template) {
-			frappe.call({
-				method: 'set_therapy_details_from_template',
-				doc: frm.doc,
-				freeze: true,
-				freeze_message: __('Fetching Template Details'),
-				callback: function() {
-					refresh_field('therapy_plan_details');
-				}
-			});
-		}
-	},
-
-	show_progress_for_therapies: function(frm) {
-		let bars = [];
-		let message = '';
-
-		// completed sessions
-		let title = __('{0} sessions completed', [frm.doc.total_sessions_completed]);
-		if (frm.doc.total_sessions_completed === 1) {
-			title = __('{0} session completed', [frm.doc.total_sessions_completed]);
-		}
-		title += __(' out of {0}', [frm.doc.total_sessions]);
-
-		bars.push({
-			'title': title,
-			'width': (frm.doc.total_sessions_completed / frm.doc.total_sessions * 100) + '%',
-			'progress_class': 'progress-bar-success'
-		});
-		if (bars[0].width == '0%') {
-			bars[0].width = '0.5%';
-		}
-		message = title;
-		frm.dashboard.add_progress(__('Status'), bars, message);
-	},
-});
-
-frappe.ui.form.on('Therapy Plan Detail', {
-	no_of_sessions: function(frm) {
-		let total = 0;
-		$.each(frm.doc.therapy_plan_details, function(_i, e) {
-			total += e.no_of_sessions;
-		});
-		frm.set_value('total_sessions', total);
-		refresh_field('total_sessions');
-	}
-});
diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan.json b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.json
deleted file mode 100644
index c03e9de..0000000
--- a/erpnext/healthcare/doctype/therapy_plan/therapy_plan.json
+++ /dev/null
@@ -1,179 +0,0 @@
-{
- "actions": [],
- "autoname": "naming_series:",
- "creation": "2020-03-29 20:56:49.758602",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "naming_series",
-  "patient",
-  "patient_name",
-  "invoiced",
-  "column_break_4",
-  "company",
-  "status",
-  "start_date",
-  "section_break_3",
-  "therapy_plan_template",
-  "therapy_plan_details",
-  "title",
-  "section_break_9",
-  "total_sessions",
-  "column_break_11",
-  "total_sessions_completed"
- ],
- "fields": [
-  {
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Patient",
-   "options": "Patient",
-   "reqd": 1
-  },
-  {
-   "fieldname": "start_date",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "label": "Start Date",
-   "reqd": 1
-  },
-  {
-   "fieldname": "section_break_3",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "therapy_plan_details",
-   "fieldtype": "Table",
-   "label": "Therapy Plan Details",
-   "options": "Therapy Plan Detail",
-   "read_only_depends_on": "therapy_plan_template",
-   "reqd": 1
-  },
-  {
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "label": "Naming Series",
-   "options": "HLC-THP-.YYYY.-"
-  },
-  {
-   "fetch_from": "patient.patient_name",
-   "fieldname": "patient_name",
-   "fieldtype": "Data",
-   "label": "Patient Name",
-   "read_only": 1
-  },
-  {
-   "default": "{patient_name}",
-   "fieldname": "title",
-   "fieldtype": "Data",
-   "hidden": 1,
-   "label": "Title",
-   "no_copy": 1
-  },
-  {
-   "fieldname": "column_break_4",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "section_break_9",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "total_sessions",
-   "fieldtype": "Int",
-   "label": "Total Sessions",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_11",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "total_sessions_completed",
-   "fieldtype": "Int",
-   "label": "Total Sessions Completed",
-   "read_only": 1
-  },
-  {
-   "fieldname": "status",
-   "fieldtype": "Select",
-   "label": "Status",
-   "options": "Not Started\nIn Progress\nCompleted\nCancelled",
-   "read_only": 1
-  },
-  {
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "in_standard_filter": 1,
-   "label": "Company",
-   "options": "Company",
-   "reqd": 1
-  },
-  {
-   "fieldname": "therapy_plan_template",
-   "fieldtype": "Link",
-   "label": "Therapy Plan Template",
-   "options": "Therapy Plan Template",
-   "set_only_once": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "invoiced",
-   "fieldtype": "Check",
-   "label": "Invoiced",
-   "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1
-  }
- ],
- "links": [],
- "modified": "2020-11-04 18:13:13.564999",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Therapy Plan",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "search_fields": "patient",
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "patient",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan.py b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.py
deleted file mode 100644
index 6d63f39..0000000
--- a/erpnext/healthcare/doctype/therapy_plan/therapy_plan.py
+++ /dev/null
@@ -1,103 +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
-from frappe.utils import flt, today
-
-
-class TherapyPlan(Document):
-	def validate(self):
-		self.set_totals()
-		self.set_status()
-
-	def set_status(self):
-		if not self.total_sessions_completed:
-			self.status = 'Not Started'
-		else:
-			if self.total_sessions_completed < self.total_sessions:
-				self.status = 'In Progress'
-			elif self.total_sessions_completed == self.total_sessions:
-				self.status = 'Completed'
-
-	def set_totals(self):
-		total_sessions = 0
-		total_sessions_completed = 0
-		for entry in self.therapy_plan_details:
-			if entry.no_of_sessions:
-				total_sessions += entry.no_of_sessions
-			if entry.sessions_completed:
-				total_sessions_completed += entry.sessions_completed
-
-		self.db_set('total_sessions', total_sessions)
-		self.db_set('total_sessions_completed', total_sessions_completed)
-
-	@frappe.whitelist()
-	def set_therapy_details_from_template(self):
-		# Add therapy types in the child table
-		self.set('therapy_plan_details', [])
-		therapy_plan_template = frappe.get_doc('Therapy Plan Template', self.therapy_plan_template)
-
-		for data in therapy_plan_template.therapy_types:
-			self.append('therapy_plan_details', {
-				'therapy_type': data.therapy_type,
-				'no_of_sessions': data.no_of_sessions
-			})
-		return self
-
-
-@frappe.whitelist()
-def make_therapy_session(therapy_plan, patient, therapy_type, company, appointment=None):
-	therapy_type = frappe.get_doc('Therapy Type', therapy_type)
-
-	therapy_session = frappe.new_doc('Therapy Session')
-	therapy_session.therapy_plan = therapy_plan
-	therapy_session.company = company
-	therapy_session.patient = patient
-	therapy_session.therapy_type = therapy_type.name
-	therapy_session.duration = therapy_type.default_duration
-	therapy_session.rate = therapy_type.rate
-	therapy_session.exercises = therapy_type.exercises
-	therapy_session.appointment = appointment
-
-	if frappe.flags.in_test:
-		therapy_session.start_date = today()
-	return therapy_session.as_dict()
-
-
-@frappe.whitelist()
-def make_sales_invoice(reference_name, patient, company, therapy_plan_template):
-	from erpnext.stock.get_item_details import get_item_details
-	si = frappe.new_doc('Sales Invoice')
-	si.company = company
-	si.patient = patient
-	si.customer = frappe.db.get_value('Patient', patient, 'customer')
-
-	item = frappe.db.get_value('Therapy Plan Template', therapy_plan_template, 'linked_item')
-	price_list, price_list_currency = frappe.db.get_values('Price List', {'selling': 1}, ['name', 'currency'])[0]
-	args = {
-		'doctype': 'Sales Invoice',
-		'item_code': item,
-		'company': company,
-		'customer': si.customer,
-		'selling_price_list': price_list,
-		'price_list_currency': price_list_currency,
-		'plc_conversion_rate': 1.0,
-		'conversion_rate': 1.0
-	}
-
-	item_line = si.append('items', {})
-	item_details = get_item_details(args)
-	item_line.item_code = item
-	item_line.qty = 1
-	item_line.rate = item_details.price_list_rate
-	item_line.amount = flt(item_line.rate) * flt(item_line.qty)
-	item_line.reference_dt = 'Therapy Plan'
-	item_line.reference_dn = reference_name
-	item_line.description = item_details.description
-
-	si.set_missing_values(for_validate = True)
-	return si
diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan_dashboard.py b/erpnext/healthcare/doctype/therapy_plan/therapy_plan_dashboard.py
deleted file mode 100644
index 25c8df1..0000000
--- a/erpnext/healthcare/doctype/therapy_plan/therapy_plan_dashboard.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from __future__ import unicode_literals
-
-from frappe import _
-
-
-def get_data():
-	return {
-		'fieldname': 'therapy_plan',
-		'non_standard_fieldnames': {
-			'Sales Invoice': 'reference_dn'
-		},
-		'transactions': [
-			{
-				'label': _('Therapy Sessions'),
-				'items': ['Therapy Session']
-			},
-			{
-				'label': _('Billing'),
-				'items': ['Sales Invoice']
-			}
-		],
-		'disable_create_buttons': ['Sales Invoice']
-	}
diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan_list.js b/erpnext/healthcare/doctype/therapy_plan/therapy_plan_list.js
deleted file mode 100644
index 63967af..0000000
--- a/erpnext/healthcare/doctype/therapy_plan/therapy_plan_list.js
+++ /dev/null
@@ -1,11 +0,0 @@
-frappe.listview_settings['Therapy Plan'] = {
-	get_indicator: function(doc) {
-		var colors = {
-			'Completed': 'green',
-			'In Progress': 'orange',
-			'Not Started': 'red',
-			'Cancelled': 'grey'
-		};
-		return [__(doc.status), colors[doc.status], 'status,=,' + doc.status];
-	}
-};
diff --git a/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.json b/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.json
deleted file mode 100644
index 77f08af..0000000
--- a/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "actions": [],
- "creation": "2020-03-29 20:52:57.068731",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "therapy_type",
-  "no_of_sessions",
-  "sessions_completed"
- ],
- "fields": [
-  {
-   "fieldname": "therapy_type",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Therapy Type",
-   "options": "Therapy Type",
-   "reqd": 1
-  },
-  {
-   "fieldname": "no_of_sessions",
-   "fieldtype": "Int",
-   "in_list_view": 1,
-   "label": "No of Sessions"
-  },
-  {
-   "default": "0",
-   "depends_on": "eval:doc.parenttype=='Therapy Plan';",
-   "fieldname": "sessions_completed",
-   "fieldtype": "Int",
-   "label": "Sessions Completed",
-   "no_copy": 1,
-   "read_only": 1
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-11-04 18:15:52.173450",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Therapy Plan Detail",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.py b/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.py
deleted file mode 100644
index 1842fc2..0000000
--- a/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.py
+++ /dev/null
@@ -1,12 +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 TherapyPlanDetail(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/therapy_plan_template/__init__.py b/erpnext/healthcare/doctype/therapy_plan_template/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/therapy_plan_template/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/therapy_plan_template/test_therapy_plan_template.py b/erpnext/healthcare/doctype/therapy_plan_template/test_therapy_plan_template.py
deleted file mode 100644
index cd3d568..0000000
--- a/erpnext/healthcare/doctype/therapy_plan_template/test_therapy_plan_template.py
+++ /dev/null
@@ -1,11 +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 TestTherapyPlanTemplate(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/therapy_plan_template/therapy_plan_template.js b/erpnext/healthcare/doctype/therapy_plan_template/therapy_plan_template.js
deleted file mode 100644
index 86de192..0000000
--- a/erpnext/healthcare/doctype/therapy_plan_template/therapy_plan_template.js
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Therapy Plan Template', {
-	refresh: function(frm) {
-		frm.set_query('therapy_type', 'therapy_types', () => {
-			return {
-				filters: {
-					'is_billable': 1
-				}
-			};
-		});
-	},
-
-	set_totals: function(frm) {
-		let total_sessions = 0;
-		let total_amount = 0.0;
-		frm.doc.therapy_types.forEach((d) => {
-			if (d.no_of_sessions) total_sessions += cint(d.no_of_sessions);
-			if (d.amount) total_amount += flt(d.amount);
-		});
-		frm.set_value('total_sessions', total_sessions);
-		frm.set_value('total_amount', total_amount);
-		frm.refresh_fields();
-	}
-});
-
-frappe.ui.form.on('Therapy Plan Template Detail', {
-	therapy_type: function(frm, cdt, cdn) {
-		let row = locals[cdt][cdn];
-		frappe.call('frappe.client.get', {
-			doctype: 'Therapy Type',
-			name: row.therapy_type
-		}).then((res) => {
-			row.rate = res.message.rate;
-			if (!row.no_of_sessions)
-				row.no_of_sessions = 1;
-			row.amount = flt(row.rate) * cint(row.no_of_sessions);
-			frm.refresh_field('therapy_types');
-			frm.trigger('set_totals');
-		});
-	},
-
-	no_of_sessions: function(frm, cdt, cdn) {
-		let row = locals[cdt][cdn];
-		row.amount = flt(row.rate) * cint(row.no_of_sessions);
-		frm.refresh_field('therapy_types');
-		frm.trigger('set_totals');
-	},
-
-	rate: function(frm, cdt, cdn) {
-		let row = locals[cdt][cdn];
-		row.amount = flt(row.rate) * cint(row.no_of_sessions);
-		frm.refresh_field('therapy_types');
-		frm.trigger('set_totals');
-	}
-});
diff --git a/erpnext/healthcare/doctype/therapy_plan_template/therapy_plan_template.json b/erpnext/healthcare/doctype/therapy_plan_template/therapy_plan_template.json
deleted file mode 100644
index 48fc896..0000000
--- a/erpnext/healthcare/doctype/therapy_plan_template/therapy_plan_template.json
+++ /dev/null
@@ -1,132 +0,0 @@
-{
- "actions": [],
- "autoname": "field:plan_name",
- "creation": "2020-09-22 17:51:38.861055",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "plan_name",
-  "linked_item_details_section",
-  "item_code",
-  "item_name",
-  "item_group",
-  "column_break_6",
-  "description",
-  "linked_item",
-  "therapy_types_section",
-  "therapy_types",
-  "section_break_11",
-  "total_sessions",
-  "column_break_13",
-  "total_amount"
- ],
- "fields": [
-  {
-   "fieldname": "plan_name",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Plan Name",
-   "reqd": 1,
-   "unique": 1
-  },
-  {
-   "fieldname": "therapy_types_section",
-   "fieldtype": "Section Break",
-   "label": "Therapy Types"
-  },
-  {
-   "fieldname": "therapy_types",
-   "fieldtype": "Table",
-   "label": "Therapy Types",
-   "options": "Therapy Plan Template Detail",
-   "reqd": 1
-  },
-  {
-   "fieldname": "linked_item",
-   "fieldtype": "Link",
-   "label": "Linked Item",
-   "options": "Item",
-   "read_only": 1
-  },
-  {
-   "fieldname": "linked_item_details_section",
-   "fieldtype": "Section Break",
-   "label": "Linked Item Details"
-  },
-  {
-   "fieldname": "item_code",
-   "fieldtype": "Data",
-   "label": "Item Code",
-   "reqd": 1,
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "item_name",
-   "fieldtype": "Data",
-   "label": "Item Name",
-   "reqd": 1
-  },
-  {
-   "fieldname": "item_group",
-   "fieldtype": "Link",
-   "label": "Item Group",
-   "options": "Item Group",
-   "reqd": 1
-  },
-  {
-   "fieldname": "column_break_6",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "description",
-   "fieldtype": "Small Text",
-   "label": "Item Description"
-  },
-  {
-   "fieldname": "total_amount",
-   "fieldtype": "Currency",
-   "label": "Total Amount",
-   "read_only": 1
-  },
-  {
-   "fieldname": "section_break_11",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "total_sessions",
-   "fieldtype": "Int",
-   "label": "Total Sessions",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_13",
-   "fieldtype": "Column Break"
-  }
- ],
- "index_web_pages_for_search": 1,
- "links": [],
- "modified": "2020-10-08 00:56:58.062105",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Therapy Plan Template",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_plan_template/therapy_plan_template.py b/erpnext/healthcare/doctype/therapy_plan_template/therapy_plan_template.py
deleted file mode 100644
index f5512be..0000000
--- a/erpnext/healthcare/doctype/therapy_plan_template/therapy_plan_template.py
+++ /dev/null
@@ -1,76 +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
-from frappe.utils import cint, flt
-
-from erpnext.healthcare.doctype.therapy_type.therapy_type import make_item_price
-
-
-class TherapyPlanTemplate(Document):
-	def after_insert(self):
-		self.create_item_from_template()
-
-	def validate(self):
-		self.set_totals()
-
-	def on_update(self):
-		doc_before_save = self.get_doc_before_save()
-		if not doc_before_save: return
-		if doc_before_save.item_name != self.item_name or doc_before_save.item_group != self.item_group \
-			or doc_before_save.description != self.description:
-			self.update_item()
-
-		if doc_before_save.therapy_types != self.therapy_types:
-			self.update_item_price()
-
-	def set_totals(self):
-		total_sessions = 0
-		total_amount = 0
-
-		for entry in self.therapy_types:
-			total_sessions += cint(entry.no_of_sessions)
-			total_amount += flt(entry.amount)
-
-		self.total_sessions = total_sessions
-		self.total_amount = total_amount
-
-	def create_item_from_template(self):
-		uom = frappe.db.exists('UOM', 'Nos') or frappe.db.get_single_value('Stock Settings', 'stock_uom')
-
-		item = frappe.get_doc({
-			'doctype': 'Item',
-			'item_code': self.item_code,
-			'item_name': self.item_name,
-			'item_group': self.item_group,
-			'description': self.description,
-			'is_sales_item': 1,
-			'is_service_item': 1,
-			'is_purchase_item': 0,
-			'is_stock_item': 0,
-			'show_in_website': 0,
-			'is_pro_applicable': 0,
-			'stock_uom': uom
-		}).insert(ignore_permissions=True, ignore_mandatory=True)
-
-		make_item_price(item.name, self.total_amount)
-		self.db_set('linked_item', item.name)
-
-	def update_item(self):
-		item_doc = frappe.get_doc('Item', {'item_code': self.linked_item})
-		item_doc.item_name = self.item_name
-		item_doc.item_group = self.item_group
-		item_doc.description = self.description
-		item_doc.ignore_mandatory = True
-		item_doc.save(ignore_permissions=True)
-
-	def update_item_price(self):
-		item_price = frappe.get_doc('Item Price', {'item_code': self.linked_item})
-		item_price.item_name = self.item_name
-		item_price.price_list_rate = self.total_amount
-		item_price.ignore_mandatory = True
-		item_price.save(ignore_permissions=True)
diff --git a/erpnext/healthcare/doctype/therapy_plan_template/therapy_plan_template_dashboard.py b/erpnext/healthcare/doctype/therapy_plan_template/therapy_plan_template_dashboard.py
deleted file mode 100644
index def5c48..0000000
--- a/erpnext/healthcare/doctype/therapy_plan_template/therapy_plan_template_dashboard.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from __future__ import unicode_literals
-
-from frappe import _
-
-
-def get_data():
-	return {
-		'fieldname': 'therapy_plan_template',
-		'transactions': [
-			{
-				'label': _('Therapy Plans'),
-				'items': ['Therapy Plan']
-			}
-		]
-	}
diff --git a/erpnext/healthcare/doctype/therapy_plan_template_detail/__init__.py b/erpnext/healthcare/doctype/therapy_plan_template_detail/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/therapy_plan_template_detail/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/therapy_plan_template_detail/therapy_plan_template_detail.json b/erpnext/healthcare/doctype/therapy_plan_template_detail/therapy_plan_template_detail.json
deleted file mode 100644
index 5553a11..0000000
--- a/erpnext/healthcare/doctype/therapy_plan_template_detail/therapy_plan_template_detail.json
+++ /dev/null
@@ -1,54 +0,0 @@
-{
- "actions": [],
- "creation": "2020-10-07 23:04:44.373381",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "therapy_type",
-  "no_of_sessions",
-  "rate",
-  "amount"
- ],
- "fields": [
-  {
-   "fieldname": "therapy_type",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Therapy Type",
-   "options": "Therapy Type",
-   "reqd": 1
-  },
-  {
-   "fieldname": "no_of_sessions",
-   "fieldtype": "Int",
-   "in_list_view": 1,
-   "label": "No of Sessions"
-  },
-  {
-   "fieldname": "rate",
-   "fieldtype": "Currency",
-   "in_list_view": 1,
-   "label": "Rate"
-  },
-  {
-   "fieldname": "amount",
-   "fieldtype": "Currency",
-   "in_list_view": 1,
-   "label": "Amount",
-   "read_only": 1
-  }
- ],
- "istable": 1,
- "links": [],
- "modified": "2020-10-07 23:46:54.296322",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Therapy Plan Template Detail",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_plan_template_detail/therapy_plan_template_detail.py b/erpnext/healthcare/doctype/therapy_plan_template_detail/therapy_plan_template_detail.py
deleted file mode 100644
index 104c1bf..0000000
--- a/erpnext/healthcare/doctype/therapy_plan_template_detail/therapy_plan_template_detail.py
+++ /dev/null
@@ -1,12 +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 TherapyPlanTemplateDetail(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/therapy_session/__init__.py b/erpnext/healthcare/doctype/therapy_session/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/therapy_session/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/therapy_session/test_therapy_session.py b/erpnext/healthcare/doctype/therapy_session/test_therapy_session.py
deleted file mode 100644
index e4afacf..0000000
--- a/erpnext/healthcare/doctype/therapy_session/test_therapy_session.py
+++ /dev/null
@@ -1,11 +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 TestTherapySession(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session.js b/erpnext/healthcare/doctype/therapy_session/therapy_session.js
deleted file mode 100644
index fbfa774..0000000
--- a/erpnext/healthcare/doctype/therapy_session/therapy_session.js
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Therapy Session', {
-	setup: function(frm) {
-		frm.get_field('exercises').grid.editable_fields = [
-			{fieldname: 'exercise_type', columns: 7},
-			{fieldname: 'counts_target', columns: 1},
-			{fieldname: 'counts_completed', columns: 1},
-			{fieldname: 'assistance_level', columns: 1}
-		];
-
-		frm.set_query('service_unit', function() {
-			return {
-				filters: {
-					'is_group': false,
-					'allow_appointments': true,
-					'company': frm.doc.company
-				}
-			};
-		});
-
-		frm.set_query('appointment', function() {
-
-			return {
-				filters: {
-					'status': ['in', ['Open', 'Scheduled']]
-				}
-			};
-		});
-	},
-
-	refresh: function(frm) {
-		if (frm.doc.therapy_plan) {
-			frm.trigger('filter_therapy_types');
-		}
-
-		if (!frm.doc.__islocal) {
-			frm.dashboard.add_indicator(__('Counts Targeted: {0}', [frm.doc.total_counts_targeted]), 'blue');
-			frm.dashboard.add_indicator(__('Counts Completed: {0}', [frm.doc.total_counts_completed]),
-				(frm.doc.total_counts_completed < frm.doc.total_counts_targeted) ? 'orange' : 'green');
-		}
-
-		if (frm.doc.docstatus === 1) {
-			frm.add_custom_button(__('Patient Assessment'), function() {
-				frappe.model.open_mapped_doc({
-					method: 'erpnext.healthcare.doctype.patient_assessment.patient_assessment.create_patient_assessment',
-					frm: frm,
-				})
-			}, 'Create');
-
-			frappe.db.get_value('Therapy Plan', {'name': frm.doc.therapy_plan}, 'therapy_plan_template', (r) => {
-				if (r && !r.therapy_plan_template) {
-					frm.add_custom_button(__('Sales Invoice'), function() {
-						frappe.model.open_mapped_doc({
-							method: 'erpnext.healthcare.doctype.therapy_session.therapy_session.invoice_therapy_session',
-							frm: frm,
-						});
-					}, 'Create');
-				}
-			});
-		}
-	},
-
-	therapy_plan: function(frm) {
-		if (frm.doc.therapy_plan) {
-			frm.trigger('filter_therapy_types');
-		}
-	},
-
-	filter_therapy_types: function(frm) {
-		frappe.call({
-			'method': 'frappe.client.get',
-			args: {
-				doctype: 'Therapy Plan',
-				name: frm.doc.therapy_plan
-			},
-			callback: function(data) {
-				let therapy_types = (data.message.therapy_plan_details || []).map(function(d){ return d.therapy_type; });
-				frm.set_query('therapy_type', function() {
-					return {
-						filters: { 'therapy_type': ['in', therapy_types]}
-					};
-				});
-			}
-		});
-	},
-
-	patient: function(frm) {
-		if (frm.doc.patient) {
-			frappe.call({
-				'method': 'erpnext.healthcare.doctype.patient.patient.get_patient_detail',
-				args: {
-					patient: frm.doc.patient
-				},
-				callback: function (data) {
-					let age = '';
-					if (data.message.dob) {
-						age = calculate_age(data.message.dob);
-					} else if (data.message.age) {
-						age = data.message.age;
-						if (data.message.age_as_on) {
-							age = __('{0} as on {1}', [age, data.message.age_as_on]);
-						}
-					}
-					frm.set_value('patient_age', age);
-					frm.set_value('gender', data.message.sex);
-					frm.set_value('patient_name', data.message.patient_name);
-				}
-			});
-		} else {
-			frm.set_value('patient_age', '');
-			frm.set_value('gender', '');
-			frm.set_value('patient_name', '');
-		}
-	},
-
-	appointment: function(frm) {
-		if (frm.doc.appointment) {
-			frappe.call({
-				'method': 'frappe.client.get',
-				args: {
-					doctype: 'Patient Appointment',
-					name: frm.doc.appointment
-				},
-				callback: function(data) {
-					let values = {
-						'patient':data.message.patient,
-						'therapy_type': data.message.therapy_type,
-						'therapy_plan': data.message.therapy_plan,
-						'practitioner': data.message.practitioner,
-						'department': data.message.department,
-						'start_date': data.message.appointment_date,
-						'start_time': data.message.appointment_time,
-						'service_unit': data.message.service_unit,
-						'company': data.message.company,
-						'duration': data.message.duration
-					};
-					frm.set_value(values);
-				}
-			});
-		}
-	},
-
-	therapy_type: function(frm) {
-		if (frm.doc.therapy_type) {
-			frappe.call({
-				'method': 'frappe.client.get',
-				args: {
-					doctype: 'Therapy Type',
-					name: frm.doc.therapy_type
-				},
-				callback: function(data) {
-					frm.set_value('duration', data.message.default_duration);
-					frm.set_value('rate', data.message.rate);
-					frm.set_value('service_unit', data.message.healthcare_service_unit);
-					frm.set_value('department', data.message.medical_department);
-					frm.doc.exercises = [];
-					$.each(data.message.exercises, function(_i, e) {
-						let exercise = frm.add_child('exercises');
-						exercise.exercise_type = e.exercise_type;
-						exercise.difficulty_level = e.difficulty_level;
-						exercise.counts_target = e.counts_target;
-						exercise.assistance_level = e.assistance_level;
-					});
-					refresh_field('exercises');
-				}
-			});
-		}
-	}
-});
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session.json b/erpnext/healthcare/doctype/therapy_session/therapy_session.json
deleted file mode 100644
index 0bb2b0e..0000000
--- a/erpnext/healthcare/doctype/therapy_session/therapy_session.json
+++ /dev/null
@@ -1,264 +0,0 @@
-{
- "actions": [],
- "autoname": "naming_series:",
- "creation": "2020-03-11 08:57:40.669857",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "naming_series",
-  "appointment",
-  "patient",
-  "patient_name",
-  "patient_age",
-  "gender",
-  "column_break_5",
-  "company",
-  "therapy_plan",
-  "therapy_type",
-  "practitioner",
-  "department",
-  "details_section",
-  "medical_code",
-  "duration",
-  "rate",
-  "location",
-  "column_break_12",
-  "service_unit",
-  "start_date",
-  "start_time",
-  "invoiced",
-  "exercises_section",
-  "exercises",
-  "section_break_23",
-  "total_counts_targeted",
-  "column_break_25",
-  "total_counts_completed",
-  "amended_from"
- ],
- "fields": [
-  {
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "label": "Series",
-   "options": "HLC-THP-.YYYY.-"
-  },
-  {
-   "fieldname": "appointment",
-   "fieldtype": "Link",
-   "label": "Appointment",
-   "options": "Patient Appointment",
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Patient",
-   "options": "Patient",
-   "reqd": 1
-  },
-  {
-   "fetch_from": "patient.sex",
-   "fieldname": "gender",
-   "fieldtype": "Link",
-   "label": "Gender",
-   "options": "Gender",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_5",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "practitioner",
-   "fieldtype": "Link",
-   "label": "Healthcare Practitioner",
-   "options": "Healthcare Practitioner"
-  },
-  {
-   "fieldname": "department",
-   "fieldtype": "Link",
-   "label": "Medical Department",
-   "options": "Medical Department"
-  },
-  {
-   "fieldname": "details_section",
-   "fieldtype": "Section Break",
-   "label": "Details"
-  },
-  {
-   "fetch_from": "therapy_template.default_duration",
-   "fieldname": "duration",
-   "fieldtype": "Int",
-   "label": "Duration",
-   "reqd": 1
-  },
-  {
-   "fieldname": "location",
-   "fieldtype": "Select",
-   "label": "Location",
-   "options": "\nCenter\nHome\nTele"
-  },
-  {
-   "fieldname": "column_break_12",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fetch_from": "therapy_template.rate",
-   "fieldname": "rate",
-   "fieldtype": "Currency",
-   "label": "Rate"
-  },
-  {
-   "fieldname": "exercises_section",
-   "fieldtype": "Section Break",
-   "label": "Exercises"
-  },
-  {
-   "fieldname": "exercises",
-   "fieldtype": "Table",
-   "label": "Exercises",
-   "options": "Exercise"
-  },
-  {
-   "depends_on": "eval: doc.therapy_plan",
-   "fieldname": "therapy_type",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Therapy Type",
-   "options": "Therapy Type",
-   "reqd": 1
-  },
-  {
-   "fieldname": "therapy_plan",
-   "fieldtype": "Link",
-   "label": "Therapy Plan",
-   "options": "Therapy Plan",
-   "reqd": 1,
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "amended_from",
-   "fieldtype": "Link",
-   "label": "Amended From",
-   "no_copy": 1,
-   "options": "Therapy Session",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "service_unit",
-   "fieldtype": "Link",
-   "label": "Healthcare Service Unit",
-   "options": "Healthcare Service Unit"
-  },
-  {
-   "fieldname": "start_date",
-   "fieldtype": "Date",
-   "label": "Start Date",
-   "reqd": 1
-  },
-  {
-   "fieldname": "start_time",
-   "fieldtype": "Time",
-   "label": "Start Time"
-  },
-  {
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "label": "Company",
-   "options": "Company",
-   "reqd": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "invoiced",
-   "fieldtype": "Check",
-   "label": "Invoiced",
-   "read_only": 1
-  },
-  {
-   "fieldname": "patient_age",
-   "fieldtype": "Data",
-   "label": "Patient Age",
-   "read_only": 1
-  },
-  {
-   "fieldname": "total_counts_targeted",
-   "fieldtype": "Int",
-   "label": "Total Counts Targeted",
-   "read_only": 1
-  },
-  {
-   "fieldname": "total_counts_completed",
-   "fieldtype": "Int",
-   "label": "Total Counts Completed",
-   "no_copy": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "section_break_23",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "column_break_25",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fetch_from": "patient.patient_name",
-   "fieldname": "patient_name",
-   "fieldtype": "Data",
-   "label": "Patient Name",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "therapy_type.medical_code",
-   "fieldname": "medical_code",
-   "fieldtype": "Link",
-   "label": "Medical Code",
-   "options": "Medical Code",
-   "read_only": 1
-  }
- ],
- "is_submittable": 1,
- "links": [],
- "modified": "2020-11-04 18:14:25.999939",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Therapy Session",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "cancel": 1,
-   "create": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "submit": 1,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "search_fields": "patient,appointment,therapy_plan,therapy_type",
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "patient",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session.py b/erpnext/healthcare/doctype/therapy_session/therapy_session.py
deleted file mode 100644
index 915e6e4..0000000
--- a/erpnext/healthcare/doctype/therapy_session/therapy_session.py
+++ /dev/null
@@ -1,149 +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 datetime
-
-import frappe
-from frappe import _
-from frappe.model.document import Document
-from frappe.model.mapper import get_mapped_doc
-from frappe.utils import flt, get_link_to_form, get_time, getdate
-
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import (
-	get_income_account,
-	get_receivable_account,
-)
-
-
-class TherapySession(Document):
-	def validate(self):
-		self.validate_duplicate()
-		self.set_total_counts()
-
-	def validate_duplicate(self):
-		end_time = datetime.datetime.combine(getdate(self.start_date), get_time(self.start_time)) \
-			 + datetime.timedelta(minutes=flt(self.duration))
-
-		overlaps = frappe.db.sql("""
-		select
-			name
-		from
-			`tabTherapy Session`
-		where
-			start_date=%s and name!=%s and docstatus!=2
-			and (practitioner=%s or patient=%s) and
-			((start_time<%s and start_time + INTERVAL duration MINUTE>%s) or
-			(start_time>%s and start_time<%s) or
-			(start_time=%s))
-		""", (self.start_date, self.name, self.practitioner, self.patient,
-		self.start_time, end_time.time(), self.start_time, end_time.time(), self.start_time))
-
-		if overlaps:
-			overlapping_details = _('Therapy Session overlaps with {0}').format(get_link_to_form('Therapy Session', overlaps[0][0]))
-			frappe.throw(overlapping_details, title=_('Therapy Sessions Overlapping'))
-
-	def on_submit(self):
-		self.update_sessions_count_in_therapy_plan()
-
-	def on_update(self):
-		if self.appointment:
-			frappe.db.set_value('Patient Appointment', self.appointment, 'status', 'Closed')
-
-	def on_cancel(self):
-		if self.appointment:
-			frappe.db.set_value('Patient Appointment', self.appointment, 'status', 'Open')
-
-		self.update_sessions_count_in_therapy_plan(on_cancel=True)
-
-	def update_sessions_count_in_therapy_plan(self, on_cancel=False):
-		therapy_plan = frappe.get_doc('Therapy Plan', self.therapy_plan)
-		for entry in therapy_plan.therapy_plan_details:
-			if entry.therapy_type == self.therapy_type:
-				if on_cancel:
-					entry.sessions_completed -= 1
-				else:
-					entry.sessions_completed += 1
-		therapy_plan.save()
-
-	def set_total_counts(self):
-		target_total = 0
-		counts_completed = 0
-		for entry in self.exercises:
-			if entry.counts_target:
-				target_total += entry.counts_target
-			if entry.counts_completed:
-				counts_completed += entry.counts_completed
-
-		self.db_set('total_counts_targeted', target_total)
-		self.db_set('total_counts_completed', counts_completed)
-
-
-@frappe.whitelist()
-def create_therapy_session(source_name, target_doc=None):
-	def set_missing_values(source, target):
-		therapy_type = frappe.get_doc('Therapy Type', source.therapy_type)
-		target.exercises = therapy_type.exercises
-
-	doc = get_mapped_doc('Patient Appointment', source_name, {
-			'Patient Appointment': {
-				'doctype': 'Therapy Session',
-				'field_map': [
-					['appointment', 'name'],
-					['patient', 'patient'],
-					['patient_age', 'patient_age'],
-					['gender', 'patient_sex'],
-					['therapy_type', 'therapy_type'],
-					['therapy_plan', 'therapy_plan'],
-					['practitioner', 'practitioner'],
-					['department', 'department'],
-					['start_date', 'appointment_date'],
-					['start_time', 'appointment_time'],
-					['service_unit', 'service_unit'],
-					['company', 'company'],
-					['invoiced', 'invoiced']
-				]
-			}
-		}, target_doc, set_missing_values)
-
-	return doc
-
-
-@frappe.whitelist()
-def invoice_therapy_session(source_name, target_doc=None):
-	def set_missing_values(source, target):
-		target.customer = frappe.db.get_value('Patient', source.patient, 'customer')
-		target.due_date = getdate()
-		target.debit_to = get_receivable_account(source.company)
-		item = target.append('items', {})
-		item = get_therapy_item(source, item)
-		target.set_missing_values(for_validate=True)
-
-	doc = get_mapped_doc('Therapy Session', source_name, {
-			'Therapy Session': {
-				'doctype': 'Sales Invoice',
-				'field_map': [
-					['patient', 'patient'],
-					['referring_practitioner', 'practitioner'],
-					['company', 'company'],
-					['due_date', 'start_date']
-				]
-			}
-		}, target_doc, set_missing_values)
-
-	return doc
-
-
-def get_therapy_item(therapy, item):
-	item.item_code = frappe.db.get_value('Therapy Type', therapy.therapy_type, 'item')
-	item.description = _('Therapy Session Charges: {0}').format(therapy.practitioner)
-	item.income_account = get_income_account(therapy.practitioner, therapy.company)
-	item.cost_center = frappe.get_cached_value('Company', therapy.company, 'cost_center')
-	item.rate = therapy.rate
-	item.amount = therapy.rate
-	item.qty = 1
-	item.reference_dt = 'Therapy Session'
-	item.reference_dn = therapy.name
-	return item
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session_dashboard.py b/erpnext/healthcare/doctype/therapy_session/therapy_session_dashboard.py
deleted file mode 100644
index b8a3782..0000000
--- a/erpnext/healthcare/doctype/therapy_session/therapy_session_dashboard.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from __future__ import unicode_literals
-
-from frappe import _
-
-
-def get_data():
-	return {
-		'fieldname': 'therapy_session',
-		'transactions': [
-			{
-				'label': _('Assessments'),
-				'items': ['Patient Assessment']
-			}
-		]
-	}
diff --git a/erpnext/healthcare/doctype/therapy_type/__init__.py b/erpnext/healthcare/doctype/therapy_type/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/therapy_type/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/therapy_type/test_therapy_type.py b/erpnext/healthcare/doctype/therapy_type/test_therapy_type.py
deleted file mode 100644
index 23d5422..0000000
--- a/erpnext/healthcare/doctype/therapy_type/test_therapy_type.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-import frappe
-
-
-class TestTherapyType(unittest.TestCase):
-	def test_therapy_type_item(self):
-		therapy_type = create_therapy_type()
-		self.assertTrue(frappe.db.exists('Item', therapy_type.item))
-
-		therapy_type.disabled = 1
-		therapy_type.save()
-		self.assertEqual(frappe.db.get_value('Item', therapy_type.item, 'disabled'), 1)
-
-def create_therapy_type():
-	exercise = create_exercise_type()
-	therapy_type = frappe.db.exists('Therapy Type', 'Basic Rehab')
-	if not therapy_type:
-		therapy_type = frappe.new_doc('Therapy Type')
-		therapy_type.therapy_type = 'Basic Rehab'
-		therapy_type.default_duration = 30
-		therapy_type.is_billable = 1
-		therapy_type.rate = 5000
-		therapy_type.item_code = 'Basic Rehab'
-		therapy_type.item_name = 'Basic Rehab'
-		therapy_type.item_group = 'Services'
-		therapy_type.append('exercises', {
-			'exercise_type': exercise.name,
-			'counts_target': 10,
-			'assistance_level': 'Passive'
-		})
-		therapy_type.save()
-	else:
-		therapy_type = frappe.get_doc('Therapy Type', therapy_type)
-
-	return therapy_type
-
-def create_exercise_type():
-	exercise_type = frappe.db.exists('Exercise Type', 'Sit to Stand')
-	if not exercise_type:
-		exercise_type = frappe.new_doc('Exercise Type')
-		exercise_type.exercise_name = 'Sit to Stand'
-		exercise_type.append('steps_table', {
-			'title': 'Step 1',
-			'description': 'Squat and Rise'
-		})
-		exercise_type.save()
-	else:
-		exercise_type = frappe.get_doc('Exercise Type', exercise_type)
-
-	return exercise_type
diff --git a/erpnext/healthcare/doctype/therapy_type/therapy_type.js b/erpnext/healthcare/doctype/therapy_type/therapy_type.js
deleted file mode 100644
index 6e155dc..0000000
--- a/erpnext/healthcare/doctype/therapy_type/therapy_type.js
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Therapy Type', {
-	setup: function(frm) {
-		frm.get_field('exercises').grid.editable_fields = [
-			{fieldname: 'exercise_type', columns: 7},
-			{fieldname: 'difficulty_level', columns: 1},
-			{fieldname: 'counts_target', columns: 1},
-			{fieldname: 'assistance_level', columns: 1}
-		];
-	},
-
-	refresh: function(frm) {
-		if (!frm.doc.__islocal) {
-			cur_frm.add_custom_button(__('Change Item Code'), function() {
-				change_template_code(frm.doc);
-			});
-		}
-	},
-
-	therapy_type: function(frm) {
-		if (!frm.doc.item_code)
-			frm.set_value('item_code', frm.doc.therapy_type);
-		if (!frm.doc.description)
-			frm.set_value('description', frm.doc.therapy_type);
-		mark_change_in_item(frm);
-	},
-
-	rate: function(frm) {
-		mark_change_in_item(frm);
-	},
-
-	is_billable: function (frm) {
-		mark_change_in_item(frm);
-	},
-
-	item_group: function(frm) {
-		mark_change_in_item(frm);
-	},
-
-	description: function(frm) {
-		mark_change_in_item(frm);
-	},
-
-	medical_department: function(frm) {
-		mark_change_in_item(frm);
-	},
-
-	medical_code: function(frm) {
-		frm.set_query("medical_code", function() {
-			return {
-				filters: {
-					medical_code_standard: frm.doc.medical_code_standard
-				}
-			};
-		});
-	}
-});
-
-let mark_change_in_item = function(frm) {
-	if (!frm.doc.__islocal) {
-		frm.doc.change_in_item = 1;
-	}
-};
-
-let change_template_code = function(doc) {
-	let d = new frappe.ui.Dialog({
-		title:__('Change Item Code'),
-		fields:[
-			{
-				'fieldtype': 'Data',
-				'label': 'Item Code',
-				'fieldname': 'item_code',
-				reqd: 1
-			}
-		],
-		primary_action: function() {
-			let values = d.get_values();
-
-			if (values) {
-				frappe.call({
-					'method': 'erpnext.healthcare.doctype.therapy_type.therapy_type.change_item_code_from_therapy',
-					'args': {item_code: values.item_code, doc: doc},
-					callback: function () {
-						cur_frm.reload_doc();
-						frappe.show_alert({
-							message: 'Item Code renamed successfully',
-							indicator: 'green'
-						});
-					}
-				});
-			}
-			d.hide();
-		},
-		primary_action_label: __('Change Item Code')
-	});
-	d.show();
-
-	d.set_values({
-		'item_code': doc.item_code
-	});
-};
diff --git a/erpnext/healthcare/doctype/therapy_type/therapy_type.json b/erpnext/healthcare/doctype/therapy_type/therapy_type.json
deleted file mode 100644
index f365b1d..0000000
--- a/erpnext/healthcare/doctype/therapy_type/therapy_type.json
+++ /dev/null
@@ -1,234 +0,0 @@
-{
- "actions": [],
- "autoname": "field:therapy_type",
- "creation": "2020-03-29 20:48:31.715063",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "disabled",
-  "section_break_2",
-  "therapy_type",
-  "default_duration",
-  "medical_department",
-  "column_break_3",
-  "is_billable",
-  "rate",
-  "healthcare_service_unit",
-  "item_details_section",
-  "item",
-  "item_code",
-  "item_name",
-  "item_group",
-  "column_break_12",
-  "description",
-  "medical_coding_section",
-  "medical_code_standard",
-  "medical_code",
-  "section_break_18",
-  "therapy_for",
-  "add_exercises",
-  "section_break_6",
-  "exercises",
-  "change_in_item"
- ],
- "fields": [
-  {
-   "fieldname": "therapy_type",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Therapy Type",
-   "reqd": 1,
-   "unique": 1
-  },
-  {
-   "fieldname": "column_break_3",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "0",
-   "fieldname": "is_billable",
-   "fieldtype": "Check",
-   "label": "Is Billable"
-  },
-  {
-   "depends_on": "eval:doc.is_billable;",
-   "fieldname": "rate",
-   "fieldtype": "Currency",
-   "label": "Rate",
-   "mandatory_depends_on": "eval:doc.is_billable;"
-  },
-  {
-   "fieldname": "section_break_6",
-   "fieldtype": "Section Break",
-   "label": "Exercises"
-  },
-  {
-   "fieldname": "exercises",
-   "fieldtype": "Table",
-   "label": "Exercises",
-   "options": "Exercise"
-  },
-  {
-   "fieldname": "default_duration",
-   "fieldtype": "Int",
-   "label": "Default Duration (In Minutes)"
-  },
-  {
-   "default": "0",
-   "fieldname": "disabled",
-   "fieldtype": "Check",
-   "label": "Disabled"
-  },
-  {
-   "fieldname": "item_details_section",
-   "fieldtype": "Section Break",
-   "label": "Item Details"
-  },
-  {
-   "fieldname": "item",
-   "fieldtype": "Link",
-   "label": "Item",
-   "options": "Item",
-   "read_only": 1
-  },
-  {
-   "fieldname": "item_code",
-   "fieldtype": "Data",
-   "label": "Item Code",
-   "reqd": 1,
-   "set_only_once": 1
-  },
-  {
-   "fieldname": "item_group",
-   "fieldtype": "Link",
-   "label": "Item Group",
-   "options": "Item Group",
-   "reqd": 1
-  },
-  {
-   "fieldname": "item_name",
-   "fieldtype": "Data",
-   "label": "Item Name",
-   "reqd": 1
-  },
-  {
-   "fieldname": "column_break_12",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "description",
-   "fieldtype": "Small Text",
-   "label": "Description"
-  },
-  {
-   "fieldname": "section_break_2",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "medical_department",
-   "fieldtype": "Link",
-   "label": "Medical Department",
-   "options": "Medical Department"
-  },
-  {
-   "default": "0",
-   "fieldname": "change_in_item",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "label": "Change In Item",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
-   "fieldname": "therapy_for",
-   "fieldtype": "Table MultiSelect",
-   "label": "Therapy For",
-   "options": "Body Part Link"
-  },
-  {
-   "fieldname": "healthcare_service_unit",
-   "fieldtype": "Link",
-   "label": "Healthcare Service Unit",
-   "options": "Healthcare Service Unit"
-  },
-  {
-   "depends_on": "eval: doc.therapy_for",
-   "fieldname": "add_exercises",
-   "fieldtype": "Button",
-   "label": "Add Exercises",
-   "options": "add_exercises"
-  },
-  {
-   "fieldname": "section_break_18",
-   "fieldtype": "Section Break"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "medical_coding_section",
-   "fieldtype": "Section Break",
-   "label": "Medical Coding",
-   "options": "Medical Coding"
-  },
-  {
-   "fieldname": "medical_code_standard",
-   "fieldtype": "Link",
-   "label": "Medical Code Standard",
-   "options": "Medical Code Standard"
-  },
-  {
-   "depends_on": "medical_code_standard",
-   "fieldname": "medical_code",
-   "fieldtype": "Link",
-   "label": "Medical Code",
-   "options": "Medical Code"
-  }
- ],
- "links": [],
- "modified": "2020-06-29 14:18:50.669951",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Therapy Type",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_type/therapy_type.py b/erpnext/healthcare/doctype/therapy_type/therapy_type.py
deleted file mode 100644
index 3517ef2..0000000
--- a/erpnext/healthcare/doctype/therapy_type/therapy_type.py
+++ /dev/null
@@ -1,126 +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 json
-
-import frappe
-from frappe import _
-from frappe.model.document import Document
-from frappe.model.rename_doc import rename_doc
-from frappe.utils import cint
-
-
-class TherapyType(Document):
-	def validate(self):
-		self.enable_disable_item()
-
-	def after_insert(self):
-		create_item_from_therapy(self)
-
-	def on_update(self):
-		if self.change_in_item:
-			self.update_item_and_item_price()
-
-	def enable_disable_item(self):
-		if self.is_billable:
-			if self.disabled:
-				frappe.db.set_value('Item', self.item, 'disabled', 1)
-			else:
-				frappe.db.set_value('Item', self.item, 'disabled', 0)
-
-	def update_item_and_item_price(self):
-		if self.is_billable and self.item:
-			item_doc = frappe.get_doc('Item', {'item_code': self.item})
-			item_doc.item_name = self.item_name
-			item_doc.item_group = self.item_group
-			item_doc.description = self.description
-			item_doc.disabled = 0
-			item_doc.ignore_mandatory = True
-			item_doc.save(ignore_permissions=True)
-
-			if self.rate:
-				item_price = frappe.get_doc('Item Price', {'item_code': self.item})
-				item_price.item_name = self.item_name
-				item_price.price_list_rate = self.rate
-				item_price.ignore_mandatory = True
-				item_price.save()
-
-		elif not self.is_billable and self.item:
-			frappe.db.set_value('Item', self.item, 'disabled', 1)
-
-		self.db_set('change_in_item', 0)
-
-	@frappe.whitelist()
-	def add_exercises(self):
-		exercises = self.get_exercises_for_body_parts()
-		last_idx = max([cint(d.idx) for d in self.get('exercises')] or [0,])
-		for i, d in enumerate(exercises):
-			ch = self.append('exercises', {})
-			ch.exercise_type = d.parent
-			ch.idx = last_idx + i + 1
-
-	def get_exercises_for_body_parts(self):
-		body_parts = [entry.body_part for entry in self.therapy_for]
-
-		exercises = frappe.db.sql(
-			"""
-				SELECT DISTINCT
-					b.parent, e.name, e.difficulty_level
-				FROM
-				 	`tabExercise Type` e, `tabBody Part Link` b
-				WHERE
-					b.body_part IN %(body_parts)s AND b.parent=e.name
-			""", {'body_parts': body_parts}, as_dict=1)
-
-		return exercises
-
-
-def create_item_from_therapy(doc):
-	disabled = doc.disabled
-	if doc.is_billable and not doc.disabled:
-		disabled = 0
-
-	uom = frappe.db.exists('UOM', 'Unit') or frappe.db.get_single_value('Stock Settings', 'stock_uom')
-
-	item = frappe.get_doc({
-		'doctype': 'Item',
-		'item_code': doc.item_code,
-		'item_name': doc.item_name,
-		'item_group': doc.item_group,
-		'description': doc.description,
-		'is_sales_item': 1,
-		'is_service_item': 1,
-		'is_purchase_item': 0,
-		'is_stock_item': 0,
-		'show_in_website': 0,
-		'is_pro_applicable': 0,
-		'disabled': disabled,
-		'stock_uom': uom
-	}).insert(ignore_permissions=True, ignore_mandatory=True)
-
-	make_item_price(item.name, doc.rate)
-	doc.db_set('item', item.name)
-
-
-def make_item_price(item, item_price):
-	price_list_name = frappe.db.get_value('Price List', {'selling': 1})
-	frappe.get_doc({
-		'doctype': 'Item Price',
-		'price_list': price_list_name,
-		'item_code': item,
-		'price_list_rate': item_price
-	}).insert(ignore_permissions=True, ignore_mandatory=True)
-
-@frappe.whitelist()
-def change_item_code_from_therapy(item_code, doc):
-	doc = frappe._dict(json.loads(doc))
-
-	if frappe.db.exists('Item', {'item_code': item_code}):
-		frappe.throw(_('Item with Item Code {0} already exists').format(item_code))
-	else:
-		rename_doc('Item', doc.item, item_code, ignore_permissions=True)
-		frappe.db.set_value('Therapy Type', doc.name, 'item_code', item_code)
-	return
diff --git a/erpnext/healthcare/doctype/treatment_plan_template/__init__.py b/erpnext/healthcare/doctype/treatment_plan_template/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/treatment_plan_template/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/treatment_plan_template/test_records.json b/erpnext/healthcare/doctype/treatment_plan_template/test_records.json
deleted file mode 100644
index d661b43..0000000
--- a/erpnext/healthcare/doctype/treatment_plan_template/test_records.json
+++ /dev/null
@@ -1,7 +0,0 @@
-[
-  {
-    "doctype": "Treatment Plan Template",
-    "template_name": "Chemo",
-    "patient_age_from": 21
-  }
-]
diff --git a/erpnext/healthcare/doctype/treatment_plan_template/test_treatment_plan_template.py b/erpnext/healthcare/doctype/treatment_plan_template/test_treatment_plan_template.py
deleted file mode 100644
index b8a1dd7..0000000
--- a/erpnext/healthcare/doctype/treatment_plan_template/test_treatment_plan_template.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-
-# import frappe
-import unittest
-
-
-class TestTreatmentPlanTemplate(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.js b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.js
deleted file mode 100644
index 986c3cb..0000000
--- a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Treatment Plan Template', {
-	refresh: function (frm) {
-		frm.set_query('type', 'items', function () {
-			return {
-				filters: {
-					'name': ['in', ['Lab Test Template', 'Clinical Procedure Template', 'Therapy Type']],
-				}
-			};
-		});
-	},
-});
diff --git a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.json b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.json
deleted file mode 100644
index 85a312f..0000000
--- a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.json
+++ /dev/null
@@ -1,189 +0,0 @@
-{
- "actions": [],
- "autoname": "field:template_name",
- "creation": "2021-06-10 10:14:17.901273",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "section_break_1",
-  "template_name",
-  "description",
-  "practitioners",
-  "disabled",
-  "column_break_1",
-  "medical_department",
-  "goal",
-  "order_group",
-  "section_break_8",
-  "patient_age_from",
-  "complaints",
-  "gender",
-  "column_break_12",
-  "patient_age_to",
-  "diagnosis",
-  "plan_items_section",
-  "items",
-  "drugs"
- ],
- "fields": [
-  {
-   "fieldname": "section_break_1",
-   "fieldtype": "Section Break",
-   "label": "Plan Details"
-  },
-  {
-   "fieldname": "medical_department",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Medical Department",
-   "options": "Medical Department"
-  },
-  {
-   "fieldname": "description",
-   "fieldtype": "Small Text",
-   "label": "Description"
-  },
-  {
-   "fieldname": "goal",
-   "fieldtype": "Small Text",
-   "label": "Goal"
-  },
-  {
-   "fieldname": "practitioners",
-   "fieldtype": "Table MultiSelect",
-   "label": "Practitioners",
-   "options": "Treatment Plan Template Practitioner"
-  },
-  {
-   "fieldname": "order_group",
-   "fieldtype": "Link",
-   "label": "Order Group",
-   "options": "Patient Encounter",
-   "read_only": 1
-  },
-  {
-   "fieldname": "section_break_8",
-   "fieldtype": "Section Break",
-   "label": "Plan Conditions"
-  },
-  {
-   "fieldname": "template_name",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Template Name",
-   "reqd": 1,
-   "unique": 1
-  },
-  {
-   "fieldname": "patient_age_from",
-   "fieldtype": "Int",
-   "label": "Patient Age From",
-   "non_negative": 1
-  },
-  {
-   "fieldname": "column_break_12",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "patient_age_to",
-   "fieldtype": "Int",
-   "label": "Patient Age To",
-   "non_negative": 1
-  },
-  {
-   "fieldname": "gender",
-   "fieldtype": "Link",
-   "label": "Gender",
-   "options": "Gender"
-  },
-  {
-   "fieldname": "complaints",
-   "fieldtype": "Table MultiSelect",
-   "label": "Complaints",
-   "options": "Patient Encounter Symptom"
-  },
-  {
-   "fieldname": "diagnosis",
-   "fieldtype": "Table MultiSelect",
-   "label": "Diagnosis",
-   "options": "Patient Encounter Diagnosis"
-  },
-  {
-   "fieldname": "plan_items_section",
-   "fieldtype": "Section Break",
-   "label": "Plan Items"
-  },
-  {
-   "fieldname": "items",
-   "fieldtype": "Table",
-   "label": "Items",
-   "options": "Treatment Plan Template Item"
-  },
-  {
-   "fieldname": "drugs",
-   "fieldtype": "Table",
-   "label": "Drugs",
-   "options": "Drug Prescription"
-  },
-  {
-   "default": "0",
-   "fieldname": "disabled",
-   "fieldtype": "Check",
-   "label": "Disabled"
-  },
-  {
-   "fieldname": "column_break_1",
-   "fieldtype": "Column Break"
-  }
- ],
- "index_web_pages_for_search": 1,
- "links": [],
- "modified": "2021-08-18 02:41:58.354296",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Treatment Plan Template",
- "owner": "Administrator",
- "permissions": [
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Healthcare Administrator",
-   "share": 1,
-   "write": 1
-  }
- ],
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "template_name",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.py b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.py
deleted file mode 100644
index dbe0e9a..0000000
--- a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-import frappe
-from frappe import _
-from frappe.model.document import Document
-
-
-class TreatmentPlanTemplate(Document):
-	def validate(self):
-		self.validate_age()
-
-	def validate_age(self):
-		if self.patient_age_from and self.patient_age_from < 0:
-			frappe.throw(_('Patient Age From cannot be less than 0'))
-		if self.patient_age_to and self.patient_age_to < 0:
-			frappe.throw(_('Patient Age To cannot be less than 0'))
-		if self.patient_age_to and self.patient_age_from and \
-			self.patient_age_to < self.patient_age_from:
-			frappe.throw(_('Patient Age To cannot be less than Patient Age From'))
diff --git a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template_list.js b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template_list.js
deleted file mode 100644
index 7ab31df..0000000
--- a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template_list.js
+++ /dev/null
@@ -1,10 +0,0 @@
-frappe.listview_settings['Treatment Plan Template'] = {
-	get_indicator: function(doc) {
-		var colors = {
-			1: 'gray',
-			0: 'blue',
-		};
-		let label  = doc.disabled == 1 ? 'Disabled' : 'Enabled';
-		return [__(label), colors[doc.disabled], 'disable,=,' + doc.disabled];
-	}
-};
diff --git a/erpnext/healthcare/doctype/treatment_plan_template_item/__init__.py b/erpnext/healthcare/doctype/treatment_plan_template_item/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/treatment_plan_template_item/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.json b/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.json
deleted file mode 100644
index 20a9d67..0000000
--- a/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.json
+++ /dev/null
@@ -1,55 +0,0 @@
-{
- "actions": [],
- "creation": "2021-06-10 11:47:29.194795",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "type",
-  "template",
-  "qty",
-  "instructions"
- ],
- "fields": [
-  {
-   "fieldname": "type",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Type",
-   "options": "DocType",
-   "reqd": 1
-  },
-  {
-   "fieldname": "template",
-   "fieldtype": "Dynamic Link",
-   "in_list_view": 1,
-   "label": "Template",
-   "options": "type",
-   "reqd": 1
-  },
-  {
-   "default": "1",
-   "fieldname": "qty",
-   "fieldtype": "Int",
-   "label": "Qty"
-  },
-  {
-   "fieldname": "instructions",
-   "fieldtype": "Small Text",
-   "in_list_view": 1,
-   "label": "Instructions"
-  }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2021-08-17 11:19:03.515441",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Treatment Plan Template Item",
- "owner": "Administrator",
- "permissions": [],
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.py b/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.py
deleted file mode 100644
index 8b8d89f..0000000
--- a/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-# import frappe
-from frappe.model.document import Document
-
-
-class TreatmentPlanTemplateItem(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/treatment_plan_template_practitioner/__init__.py b/erpnext/healthcare/doctype/treatment_plan_template_practitioner/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/treatment_plan_template_practitioner/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.json b/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.json
deleted file mode 100644
index 04da387..0000000
--- a/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "actions": [],
- "creation": "2021-06-10 10:37:56.669416",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "practitioner"
- ],
- "fields": [
-  {
-   "fieldname": "practitioner",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Practitioner",
-   "options": "Healthcare Practitioner",
-   "reqd": 1
-  }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2021-06-11 16:05:06.733299",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Treatment Plan Template Practitioner",
- "owner": "Administrator",
- "permissions": [],
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.py b/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.py
deleted file mode 100644
index c2d08bc..0000000
--- a/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-# import frappe
-from frappe.model.document import Document
-
-
-class TreatmentPlanTemplatePractitioner(Document):
-	pass
diff --git a/erpnext/healthcare/doctype/vital_signs/__init__.py b/erpnext/healthcare/doctype/vital_signs/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/doctype/vital_signs/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/doctype/vital_signs/test_vital_signs.py b/erpnext/healthcare/doctype/vital_signs/test_vital_signs.py
deleted file mode 100644
index 22b52fb..0000000
--- a/erpnext/healthcare/doctype/vital_signs/test_vital_signs.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-# test_records = frappe.get_test_records('Vital Signs')
-
-class TestVitalSigns(unittest.TestCase):
-	pass
diff --git a/erpnext/healthcare/doctype/vital_signs/vital_signs.js b/erpnext/healthcare/doctype/vital_signs/vital_signs.js
deleted file mode 100644
index 78509e0..0000000
--- a/erpnext/healthcare/doctype/vital_signs/vital_signs.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2016, ESS LLP and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Vital Signs', {
-	height: function(frm) {
-		if (frm.doc.height && frm.doc.weight) {
-			calculate_bmi(frm);
-		}
-	},
-
-	weight: function(frm) {
-		if (frm.doc.height && frm.doc.weight) {
-			calculate_bmi(frm);
-		}
-	},
-
-	bp_systolic: function(frm) {
-		if (frm.doc.bp_systolic && frm.doc.bp_diastolic) {
-			set_bp(frm);
-		}
-	},
-
-	bp_diastolic: function(frm) {
-		if (frm.doc.bp_systolic && frm.doc.bp_diastolic) {
-			set_bp(frm);
-		}
-	}
-});
-
-let calculate_bmi = function(frm){
-	// Reference https://en.wikipedia.org/wiki/Body_mass_index
-	// bmi = weight (in Kg) / height * height (in Meter)
-	let bmi = (frm.doc.weight / (frm.doc.height * frm.doc.height)).toFixed(2);
-	let bmi_note = null;
-
-	if (bmi<18.5) {
-		bmi_note = 'Underweight';
-	} else if (bmi>=18.5 && bmi<25) {
-		bmi_note = 'Normal';
-	} else if (bmi>=25 && bmi<30) {
-		bmi_note = 'Overweight';
-	} else if (bmi>=30) {
-		bmi_note = 'Obese';
-	}
-	frappe.model.set_value(frm.doctype,frm.docname, 'bmi', bmi);
-	frappe.model.set_value(frm.doctype,frm.docname, 'nutrition_note', bmi_note);
-};
-
-let set_bp = function(frm){
-	let bp = frm.doc.bp_systolic+ '/' + frm.doc.bp_diastolic + ' mmHg';
-	frappe.model.set_value(frm.doctype,frm.docname, 'bp', bp);
-};
diff --git a/erpnext/healthcare/doctype/vital_signs/vital_signs.json b/erpnext/healthcare/doctype/vital_signs/vital_signs.json
deleted file mode 100644
index 15ab504..0000000
--- a/erpnext/healthcare/doctype/vital_signs/vital_signs.json
+++ /dev/null
@@ -1,305 +0,0 @@
-{
- "actions": [],
- "allow_copy": 1,
- "allow_import": 1,
- "autoname": "naming_series:",
- "beta": 1,
- "creation": "2017-02-02 11:00:24.853005",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "naming_series",
-  "title",
-  "patient",
-  "patient_name",
-  "inpatient_record",
-  "appointment",
-  "encounter",
-  "column_break_2",
-  "company",
-  "signs_date",
-  "signs_time",
-  "sb_vs",
-  "temperature",
-  "pulse",
-  "respiratory_rate",
-  "tongue",
-  "abdomen",
-  "column_break_8",
-  "reflexes",
-  "bp_systolic",
-  "bp_diastolic",
-  "bp",
-  "vital_signs_note",
-  "sb_nutrition_values",
-  "height",
-  "weight",
-  "bmi",
-  "column_break_14",
-  "nutrition_note",
-  "sb_references",
-  "amended_from"
- ],
- "fields": [
-  {
-   "fetch_from": "patient.inpatient_record",
-   "fieldname": "inpatient_record",
-   "fieldtype": "Link",
-   "label": "Inpatient Record",
-   "options": "Inpatient Record",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "inpatient_record.patient",
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_list_view": 1,
-   "in_standard_filter": 1,
-   "label": "Patient",
-   "options": "Patient",
-   "reqd": 1
-  },
-  {
-   "fetch_from": "patient.patient_name",
-   "fieldname": "patient_name",
-   "fieldtype": "Data",
-   "label": "Patient Name",
-   "read_only": 1
-  },
-  {
-   "fieldname": "appointment",
-   "fieldtype": "Link",
-   "in_filter": 1,
-   "label": "Patient Appointment",
-   "no_copy": 1,
-   "options": "Patient Appointment",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "encounter",
-   "fieldtype": "Link",
-   "in_filter": 1,
-   "label": "Patient Encounter",
-   "no_copy": 1,
-   "options": "Patient Encounter",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_2",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "Today",
-   "fieldname": "signs_date",
-   "fieldtype": "Date",
-   "label": "Date",
-   "reqd": 1
-  },
-  {
-   "fieldname": "signs_time",
-   "fieldtype": "Time",
-   "label": "Time",
-   "reqd": 1
-  },
-  {
-   "fieldname": "sb_vs",
-   "fieldtype": "Section Break",
-   "label": "Vital Signs"
-  },
-  {
-   "description": "Presence of a fever (temp &gt; 38.5 \u00b0C/101.3 \u00b0F or sustained temp &gt; 38 \u00b0C/100.4 \u00b0F)",
-   "fieldname": "temperature",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Body Temperature"
-  },
-  {
-   "description": "Adults' pulse rate is anywhere between 50 and 80 beats per minute.",
-   "fieldname": "pulse",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Heart Rate / Pulse"
-  },
-  {
-   "description": "Normal reference range for an adult is 16\u201320 breaths/minute (RCP 2012)",
-   "fieldname": "respiratory_rate",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Respiratory rate"
-  },
-  {
-   "fieldname": "tongue",
-   "fieldtype": "Select",
-   "label": "Tongue",
-   "options": "\nCoated\nVery Coated\nNormal\nFurry\nCuts"
-  },
-  {
-   "fieldname": "abdomen",
-   "fieldtype": "Select",
-   "label": "Abdomen",
-   "options": "\nNormal\nBloated\nFull\nFluid\nConstipated"
-  },
-  {
-   "fieldname": "column_break_8",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "reflexes",
-   "fieldtype": "Select",
-   "label": "Reflexes",
-   "options": "\nNormal\nHyper\nVery Hyper\nOne Sided"
-  },
-  {
-   "fieldname": "bp_systolic",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Blood Pressure (systolic)"
-  },
-  {
-   "fieldname": "bp_diastolic",
-   "fieldtype": "Data",
-   "ignore_xss_filter": 1,
-   "in_list_view": 1,
-   "label": "Blood Pressure (diastolic)"
-  },
-  {
-   "description": "Normal resting blood pressure in an adult is approximately 120 mmHg systolic, and 80 mmHg diastolic, abbreviated \"120/80 mmHg\"",
-   "fieldname": "bp",
-   "fieldtype": "Data",
-   "label": "Blood Pressure",
-   "read_only": 1
-  },
-  {
-   "fieldname": "vital_signs_note",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Notes"
-  },
-  {
-   "fieldname": "sb_nutrition_values",
-   "fieldtype": "Section Break",
-   "label": "Nutrition Values"
-  },
-  {
-   "fieldname": "height",
-   "fieldtype": "Float",
-   "in_list_view": 1,
-   "label": "Height (In Meter)"
-  },
-  {
-   "fieldname": "weight",
-   "fieldtype": "Float",
-   "in_list_view": 1,
-   "label": "Weight (In Kilogram)"
-  },
-  {
-   "default": "0.00",
-   "fieldname": "bmi",
-   "fieldtype": "Float",
-   "in_list_view": 1,
-   "label": "BMI",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_14",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "nutrition_note",
-   "fieldtype": "Small Text",
-   "ignore_xss_filter": 1,
-   "label": "Notes"
-  },
-  {
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "label": "Company",
-   "options": "Company"
-  },
-  {
-   "fieldname": "amended_from",
-   "fieldtype": "Link",
-   "label": "Amended From",
-   "no_copy": 1,
-   "options": "Vital Signs",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "sb_references",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "label": "Series",
-   "options": "HLC-VTS-.YYYY.-",
-   "reqd": 1
-  },
-  {
-   "allow_on_submit": 1,
-   "columns": 5,
-   "fieldname": "title",
-   "fieldtype": "Data",
-   "hidden": 1,
-   "label": "Title",
-   "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1
-  }
- ],
- "is_submittable": 1,
- "links": [],
- "modified": "2020-05-17 22:23:24.632286",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Vital Signs",
- "owner": "Administrator",
- "permissions": [
-  {
-   "cancel": 1,
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Physician",
-   "share": 1,
-   "submit": 1,
-   "write": 1
-  },
-  {
-   "cancel": 1,
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Nursing User",
-   "share": 1,
-   "submit": 1,
-   "write": 1
-  }
- ],
- "restrict_to_domain": "Healthcare",
- "search_fields": "patient, signs_date",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "title",
- "track_changes": 1,
- "track_seen": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/vital_signs/vital_signs.py b/erpnext/healthcare/doctype/vital_signs/vital_signs.py
deleted file mode 100644
index 29dbeb4..0000000
--- a/erpnext/healthcare/doctype/vital_signs/vital_signs.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP 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 VitalSigns(Document):
-	def validate(self):
-		self.set_title()
-
-	def set_title(self):
-		self.title = _('{0} on {1}').format(self.patient_name or self.patient,
-			frappe.utils.format_date(self.signs_date))[:100]
diff --git a/erpnext/healthcare/healthcare_dashboard/healthcare/healthcare.json b/erpnext/healthcare/healthcare_dashboard/healthcare/healthcare.json
deleted file mode 100644
index 2fea668..0000000
--- a/erpnext/healthcare/healthcare_dashboard/healthcare/healthcare.json
+++ /dev/null
@@ -1,62 +0,0 @@
-{
- "cards": [
-  {
-   "card": "Total Patients"
-  },
-  {
-   "card": "Total Patients Admitted"
-  },
-  {
-   "card": "Open Appointments"
-  },
-  {
-   "card": "Appointments to Bill"
-  }
- ],
- "charts": [
-  {
-   "chart": "Patient Appointments",
-   "width": "Full"
-  },
-  {
-   "chart": "In-Patient Status",
-   "width": "Half"
-  },
-  {
-   "chart": "Clinical Procedures Status",
-   "width": "Half"
-  },
-  {
-   "chart": "Lab Tests",
-   "width": "Half"
-  },
-  {
-   "chart": "Clinical Procedures",
-   "width": "Half"
-  },
-  {
-   "chart": "Symptoms",
-   "width": "Half"
-  },
-  {
-   "chart": "Diagnoses",
-   "width": "Half"
-  },
-  {
-   "chart": "Department wise Patient Appointments",
-   "width": "Full"
-  }
- ],
- "creation": "2020-07-14 18:17:54.823311",
- "dashboard_name": "Healthcare",
- "docstatus": 0,
- "doctype": "Dashboard",
- "idx": 0,
- "is_default": 0,
- "is_standard": 1,
- "modified": "2020-07-22 15:36:34.220387",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Healthcare",
- "owner": "Administrator"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/module_onboarding/healthcare/healthcare.json b/erpnext/healthcare/module_onboarding/healthcare/healthcare.json
deleted file mode 100644
index 0aa8f9a..0000000
--- a/erpnext/healthcare/module_onboarding/healthcare/healthcare.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
- "allow_roles": [
-  {
-   "role": "Healthcare Administrator"
-  }
- ],
- "creation": "2020-05-19 10:32:43.025852",
- "docstatus": 0,
- "doctype": "Module Onboarding",
- "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/healthcare",
- "idx": 0,
- "is_complete": 0,
- "modified": "2021-01-30 19:22:20.273766",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Healthcare",
- "owner": "Administrator",
- "steps": [
-  {
-   "step": "Create Patient"
-  },
-  {
-   "step": "Create Practitioner Schedule"
-  },
-  {
-   "step": "Introduction to Healthcare Practitioner"
-  },
-  {
-   "step": "Create Healthcare Practitioner"
-  },
-  {
-   "step": "Explore Healthcare Settings"
-  },
-  {
-   "step": "Explore Clinical Procedure Templates"
-  }
- ],
- "subtitle": "Patients, Practitioner Schedules, Settings, and more.",
- "success_message": "The Healthcare Module is all set up!",
- "title": "Let's Set Up the Healthcare Module."
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/number_card/appointments_to_bill/appointments_to_bill.json b/erpnext/healthcare/number_card/appointments_to_bill/appointments_to_bill.json
deleted file mode 100644
index 3e4d4e2..0000000
--- a/erpnext/healthcare/number_card/appointments_to_bill/appointments_to_bill.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "creation": "2020-07-14 18:17:54.792773",
- "docstatus": 0,
- "doctype": "Number Card",
- "document_type": "Patient Appointment",
- "dynamic_filters_json": "[[\"Patient Appointment\",\"company\",\"=\",\"frappe.defaults.get_user_default(\\\"Company\\\")\"]]",
- "filters_json": "[[\"Patient Appointment\",\"invoiced\",\"=\",0,false]]",
- "function": "Count",
- "idx": 0,
- "is_public": 1,
- "is_standard": 1,
- "label": "Appointments To Bill",
- "modified": "2020-07-22 13:27:58.038577",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Appointments to Bill",
- "owner": "Administrator",
- "show_percentage_stats": 1,
- "stats_time_interval": "Daily",
- "type": "Document Type"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/number_card/open_appointments/open_appointments.json b/erpnext/healthcare/number_card/open_appointments/open_appointments.json
deleted file mode 100644
index 8d121cc..0000000
--- a/erpnext/healthcare/number_card/open_appointments/open_appointments.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "creation": "2020-07-14 18:17:54.771092",
- "docstatus": 0,
- "doctype": "Number Card",
- "document_type": "Patient Appointment",
- "dynamic_filters_json": "[[\"Patient Appointment\",\"company\",\"=\",\"frappe.defaults.get_user_default(\\\"Company\\\")\"]]",
- "filters_json": "[[\"Patient Appointment\",\"status\",\"=\",\"Open\",false]]",
- "function": "Count",
- "idx": 0,
- "is_public": 1,
- "is_standard": 1,
- "label": "Open Appointments",
- "modified": "2020-07-22 13:27:09.542122",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Open Appointments",
- "owner": "Administrator",
- "show_percentage_stats": 1,
- "stats_time_interval": "Daily",
- "type": "Document Type"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/number_card/total_patients/total_patients.json b/erpnext/healthcare/number_card/total_patients/total_patients.json
deleted file mode 100644
index 75441a6..0000000
--- a/erpnext/healthcare/number_card/total_patients/total_patients.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "creation": "2020-07-14 18:17:54.727946",
- "docstatus": 0,
- "doctype": "Number Card",
- "document_type": "Patient",
- "filters_json": "[[\"Patient\",\"status\",\"=\",\"Active\",false]]",
- "function": "Count",
- "idx": 0,
- "is_public": 1,
- "is_standard": 1,
- "label": "Total Patients",
- "modified": "2020-07-22 13:26:02.643534",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Total Patients",
- "owner": "Administrator",
- "show_percentage_stats": 1,
- "stats_time_interval": "Daily",
- "type": "Document Type"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/number_card/total_patients_admitted/total_patients_admitted.json b/erpnext/healthcare/number_card/total_patients_admitted/total_patients_admitted.json
deleted file mode 100644
index 69a967d..0000000
--- a/erpnext/healthcare/number_card/total_patients_admitted/total_patients_admitted.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "creation": "2020-07-14 18:17:54.749754",
- "docstatus": 0,
- "doctype": "Number Card",
- "document_type": "Patient",
- "filters_json": "[[\"Patient\",\"inpatient_status\",\"=\",\"Admitted\",false]]",
- "function": "Count",
- "idx": 0,
- "is_public": 1,
- "is_standard": 1,
- "label": "Total Patients Admitted",
- "modified": "2020-07-22 13:26:20.027788",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Total Patients Admitted",
- "owner": "Administrator",
- "show_percentage_stats": 1,
- "stats_time_interval": "Daily",
- "type": "Document Type"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/onboarding_step/create_healthcare_practitioner/create_healthcare_practitioner.json b/erpnext/healthcare/onboarding_step/create_healthcare_practitioner/create_healthcare_practitioner.json
deleted file mode 100644
index 3f25a9d..0000000
--- a/erpnext/healthcare/onboarding_step/create_healthcare_practitioner/create_healthcare_practitioner.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "action": "Create Entry",
- "creation": "2020-05-19 10:39:55.728058",
- "docstatus": 0,
- "doctype": "Onboarding Step",
- "idx": 0,
- "is_complete": 0,
- "is_single": 0,
- "is_skipped": 0,
- "modified": "2021-01-30 12:02:22.849260",
- "modified_by": "Administrator",
- "name": "Create Healthcare Practitioner",
- "owner": "Administrator",
- "reference_document": "Healthcare Practitioner",
- "show_form_tour": 0,
- "show_full_form": 1,
- "title": "Create Healthcare Practitioner",
- "validate_action": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/onboarding_step/create_patient/create_patient.json b/erpnext/healthcare/onboarding_step/create_patient/create_patient.json
deleted file mode 100644
index b46bb15..0000000
--- a/erpnext/healthcare/onboarding_step/create_patient/create_patient.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "action": "Create Entry",
- "creation": "2020-05-19 10:32:27.648902",
- "docstatus": 0,
- "doctype": "Onboarding Step",
- "idx": 0,
- "is_complete": 0,
- "is_single": 0,
- "is_skipped": 0,
- "modified": "2021-01-30 00:09:28.786428",
- "modified_by": "ruchamahabal2@gmail.com",
- "name": "Create Patient",
- "owner": "Administrator",
- "reference_document": "Patient",
- "show_form_tour": 0,
- "show_full_form": 1,
- "title": "Create Patient",
- "validate_action": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/onboarding_step/create_practitioner_schedule/create_practitioner_schedule.json b/erpnext/healthcare/onboarding_step/create_practitioner_schedule/create_practitioner_schedule.json
deleted file mode 100644
index 7ce122d..0000000
--- a/erpnext/healthcare/onboarding_step/create_practitioner_schedule/create_practitioner_schedule.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "action": "Create Entry",
- "creation": "2020-05-19 10:41:19.065753",
- "docstatus": 0,
- "doctype": "Onboarding Step",
- "idx": 0,
- "is_complete": 0,
- "is_single": 0,
- "is_skipped": 0,
- "modified": "2021-01-30 00:09:28.794602",
- "modified_by": "ruchamahabal2@gmail.com",
- "name": "Create Practitioner Schedule",
- "owner": "Administrator",
- "reference_document": "Practitioner Schedule",
- "show_form_tour": 0,
- "show_full_form": 1,
- "title": "Create Practitioner Schedule",
- "validate_action": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/onboarding_step/explore_clinical_procedure_templates/explore_clinical_procedure_templates.json b/erpnext/healthcare/onboarding_step/explore_clinical_procedure_templates/explore_clinical_procedure_templates.json
deleted file mode 100644
index dfe9f71..0000000
--- a/erpnext/healthcare/onboarding_step/explore_clinical_procedure_templates/explore_clinical_procedure_templates.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "action": "Show Form Tour",
- "creation": "2020-05-19 11:40:51.963741",
- "docstatus": 0,
- "doctype": "Onboarding Step",
- "idx": 0,
- "is_complete": 0,
- "is_single": 0,
- "is_skipped": 0,
- "modified": "2021-01-30 19:22:08.257160",
- "modified_by": "Administrator",
- "name": "Explore Clinical Procedure Templates",
- "owner": "Administrator",
- "reference_document": "Clinical Procedure Template",
- "show_form_tour": 0,
- "show_full_form": 0,
- "title": "Explore Clinical Procedure Templates",
- "validate_action": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/onboarding_step/explore_healthcare_settings/explore_healthcare_settings.json b/erpnext/healthcare/onboarding_step/explore_healthcare_settings/explore_healthcare_settings.json
deleted file mode 100644
index 2d952f3..0000000
--- a/erpnext/healthcare/onboarding_step/explore_healthcare_settings/explore_healthcare_settings.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "action": "Show Form Tour",
- "creation": "2020-05-19 11:14:33.044989",
- "docstatus": 0,
- "doctype": "Onboarding Step",
- "idx": 0,
- "is_complete": 0,
- "is_single": 1,
- "is_skipped": 0,
- "modified": "2021-01-30 19:22:07.275735",
- "modified_by": "Administrator",
- "name": "Explore Healthcare Settings",
- "owner": "Administrator",
- "reference_document": "Healthcare Settings",
- "show_form_tour": 0,
- "show_full_form": 0,
- "title": "Explore Healthcare Settings",
- "validate_action": 1
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/onboarding_step/introduction_to_healthcare_practitioner/introduction_to_healthcare_practitioner.json b/erpnext/healthcare/onboarding_step/introduction_to_healthcare_practitioner/introduction_to_healthcare_practitioner.json
deleted file mode 100644
index baa8358..0000000
--- a/erpnext/healthcare/onboarding_step/introduction_to_healthcare_practitioner/introduction_to_healthcare_practitioner.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "action": "Show Form Tour",
- "creation": "2020-05-19 10:43:56.231679",
- "docstatus": 0,
- "doctype": "Onboarding Step",
- "field": "schedule",
- "idx": 0,
- "is_complete": 0,
- "is_single": 0,
- "is_skipped": 0,
- "modified": "2021-01-30 00:09:28.807129",
- "modified_by": "ruchamahabal2@gmail.com",
- "name": "Introduction to Healthcare Practitioner",
- "owner": "Administrator",
- "reference_document": "Healthcare Practitioner",
- "show_form_tour": 0,
- "show_full_form": 0,
- "title": "Introduction to Healthcare Practitioner",
- "validate_action": 0
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/page/__init__.py b/erpnext/healthcare/page/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/erpnext/healthcare/page/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/erpnext/healthcare/page/patient_history/__init__.py b/erpnext/healthcare/page/patient_history/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/page/patient_history/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/page/patient_history/patient_history.css b/erpnext/healthcare/page/patient_history/patient_history.css
deleted file mode 100644
index 74b5e7e..0000000
--- a/erpnext/healthcare/page/patient_history/patient_history.css
+++ /dev/null
@@ -1,151 +0,0 @@
-#page-medical_record .label {
-	display: inline-block;
-	margin-right: 7px;
-}
-
-#page-medical_record .list-row {
-	border: none;
-	padding: 0px;
-	cursor: pointer;
-}
-
-.patient-image-container {
-	margin-top: 17px;
-  }
-
-.patient-image {
-	display: inline-block;
-	width: 100%;
-	height: 0;
-	padding: 50% 0px;
-	background-size: cover;
-	background-repeat: no-repeat;
-	background-position: center center;
-	border-radius: 4px;
-}
-
-.patient-name {
-	font-size: 20px;
-	margin-top: 25px;
-}
-
-.medical_record-label {
-	max-width: 100px;
-	margin-bottom: -4px;
-}
-
-.medical_record-row > * {
-	z-index: -999;
-}
-
-.date-indicator {
-	background:none;
-	font-size:12px;
-	vertical-align:middle;
-	font-weight:bold;
-	color:#6c7680;
-}
-.date-indicator::after {
-	margin:0 -4px 0 12px;
-	content:'';
-	display:inline-block;
-	height:8px;
-	width:8px;
-	border-radius:8px;
-	background: #d1d8dd;
-}
-
-.date-indicator.blue {
-	color: #5e64ff;
-}
-
-.div-bg-color {
-	background: #fafbfc;
-}
-
-.bg-color-white {
-	background: #FFFFFF;
-}
-
-.d-flex {
-	display: flex;
-}
-
-.width-full {
-	width: 100%;
-}
-
-.p-3 {
-	padding: 16px;
-}
-
-.mt-2 {
-	margin-top: 8px;
-}
-
-.mr-3 {
-	margin-right: 16px;
-}
-
-.Box {
-	background-color: #fff;
-	border: 1px solid #d1d5da;
-	border-radius: 3px;
-}
-
-.flex-column {
-	flex-direction: column;
-}
-
-.avatar {
-	display: inline-block;
-	overflow: hidden;
-	line-height: 1;
-	vertical-align: middle;
-	border-radius: 3px;
-}
-
-.py-3 {
-	padding-top: 16px;
-	padding-bottom: 16px;
-}
-
-.border-bottom {
-	border-bottom: 1px #e1e4e8 solid;
-}
-
-.date-indicator.blue::after {
-	background: #5e64ff;
-}
-
-.medical_record-message {
-	border-left: 1px solid #d1d8dd;
-	padding: 15px;
-	padding-right: 30px;
-}
-
-.medical_record-date {
-	padding: 15px;
-	padding-right: 0px;
-}
-
-.patient-history-filter {
-	margin-left: 35px;
-	width: 25%;
-}
-
-#page-medical_record .plot-wrapper {
-	padding: 20px 15px;
-	border-bottom: 1px solid #d1d8dd;
-	text-align: center;
-}
-
-#page-medical_record .plot {
-	height: 140px ;
-	width: 97% ;
-	margin: auto;
-}
-
-#page-medical_record .list-filters {
-	display: none ;
-}
diff --git a/erpnext/healthcare/page/patient_history/patient_history.html b/erpnext/healthcare/page/patient_history/patient_history.html
deleted file mode 100644
index d16b386..0000000
--- a/erpnext/healthcare/page/patient_history/patient_history.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<div class="row patient-documents">
-	<div class="col-sm-12">
-		<div class="col-sm-12 show_chart_btns" align="center">
-		</div>
-		<div id="chart" class="col-sm-12 patient_vital_charts">
-		</div>
-	</div>
-	<div class="header-separator col-sm-12 d-flex border-bottom py-3" style="display:none"></div>
-	<div class="col-sm-12 d-flex">
-		<div class="patient-history-filter doctype-filter"></div>
-		<div class="patient-history-filter date-filter"></div>
-	</div>
-	<div class="col-sm-12 patient_documents_list">
-	</div>
-	<div class="col-sm-12 text-center py-3">
-		<a class="btn btn-sm btn-default btn-get-records" style="display:none">More..</a>
-	</div>
-</div>
diff --git a/erpnext/healthcare/page/patient_history/patient_history.js b/erpnext/healthcare/page/patient_history/patient_history.js
deleted file mode 100644
index ed2dc52..0000000
--- a/erpnext/healthcare/page/patient_history/patient_history.js
+++ /dev/null
@@ -1,455 +0,0 @@
-frappe.provide('frappe.patient_history');
-frappe.pages['patient_history'].on_page_load = function(wrapper) {
-	frappe.ui.make_app_page({
-		parent: wrapper,
-		title: __('Patient History')
-	});
-
-	let patient_history = new PatientHistory(wrapper);
-	$(wrapper).bind('show', ()=> {
-		patient_history.show();
-	});
-};
-
-class PatientHistory {
-	constructor(wrapper) {
-		this.wrapper = $(wrapper);
-		this.page = wrapper.page;
-		this.sidebar = this.wrapper.find('.layout-side-section');
-		this.main_section = this.wrapper.find('.layout-main-section');
-		this.start = 0;
-	}
-
-	show() {
-		frappe.breadcrumbs.add('Healthcare');
-		this.sidebar.empty();
-
-		let me = this;
-		let patient = frappe.ui.form.make_control({
-			parent: me.sidebar,
-			df: {
-				fieldtype: 'Link',
-				options: 'Patient',
-				fieldname: 'patient',
-				placeholder: __('Select Patient'),
-				only_select: true,
-				change: () => {
-					me.patient_id = '';
-					if (me.patient_id != patient.get_value() && patient.get_value()) {
-						me.start = 0;
-						me.patient_id = patient.get_value();
-						me.make_patient_profile();
-					}
-				}
-			}
-		});
-		patient.refresh();
-
-		if (frappe.route_options && !this.patient_id) {
-			patient.set_value(frappe.route_options.patient);
-			this.patient_id = frappe.route_options.patient;
-		}
-
-		this.sidebar.find('[data-fieldname="patient"]').append('<div class="patient-info"></div>');
-	}
-
-	make_patient_profile() {
-		this.page.set_title(__('Patient History'));
-		this.main_section.empty().append(frappe.render_template('patient_history'));
-		this.setup_filters();
-		this.setup_documents();
-		this.show_patient_info();
-		this.setup_buttons();
-		this.show_patient_vital_charts('bp', 'mmHg', 'Blood Pressure');
-	}
-
-	setup_filters() {
-		$('.doctype-filter').empty();
-		let me = this;
-
-		frappe.xcall(
-			'erpnext.healthcare.page.patient_history.patient_history.get_patient_history_doctypes'
-		).then(document_types => {
-			let doctype_filter = frappe.ui.form.make_control({
-				parent: $('.doctype-filter'),
-				df: {
-					fieldtype: 'MultiSelectList',
-					fieldname: 'document_type',
-					placeholder: __('Select Document Type'),
-					change: () => {
-						me.start = 0;
-						me.page.main.find('.patient_documents_list').html('');
-						this.setup_documents(doctype_filter.get_value(), date_range_field.get_value());
-					},
-					get_data: () => {
-						return document_types.map(document_type => {
-							return {
-								description: document_type,
-								value: document_type
-							};
-						});
-					},
-				}
-			});
-			doctype_filter.refresh();
-
-			$('.date-filter').empty();
-			let date_range_field = frappe.ui.form.make_control({
-				df: {
-					fieldtype: 'DateRange',
-					fieldname: 'date_range',
-					placeholder: __('Date Range'),
-					input_class: 'input-xs',
-					change: () => {
-						let selected_date_range = date_range_field.get_value();
-						if (selected_date_range && selected_date_range.length === 2) {
-							me.start = 0;
-							me.page.main.find('.patient_documents_list').html('');
-							this.setup_documents(doctype_filter.get_value(), date_range_field.get_value());
-						}
-					}
-				},
-				parent: $('.date-filter')
-			});
-			date_range_field.refresh();
-		});
-	}
-
-	setup_documents(document_types="", selected_date_range="") {
-		let filters = {
-			name: this.patient_id,
-			start: this.start,
-			page_length: 20
-		};
-		if (document_types)
-			filters['document_types'] = document_types;
-		if (selected_date_range)
-			filters['date_range'] = selected_date_range;
-
-		let me = this;
-		frappe.call({
-			'method': 'erpnext.healthcare.page.patient_history.patient_history.get_feed',
-			args: filters,
-			callback: function(r) {
-				let data = r.message;
-				if (data.length) {
-					me.add_to_records(data);
-				} else {
-					me.page.main.find('.patient_documents_list').append(`
-						<div class='text-muted' align='center'>
-							<br><br>${__('No more records..')}<br><br>
-						</div>`);
-					me.page.main.find('.btn-get-records').hide();
-				}
-			}
-		});
-	}
-
-	add_to_records(data) {
-		let details = "";
-		let i;
-		for (i=0; i<data.length; i++) {
-			if (data[i].reference_doctype) {
-				let label = '';
-				if (data[i].subject) {
-					label += "<br/>" + data[i].subject;
-				}
-				data[i] = this.add_date_separator(data[i]);
-
-				if (frappe.user_info(data[i].owner).image) {
-					data[i].imgsrc = frappe.utils.get_file_link(frappe.user_info(data[i].owner).image);
-				} else {
-					data[i].imgsrc = false;
-				}
-
-				let time_line_heading = data[i].practitioner ? `${data[i].practitioner} ` : ``;
-				time_line_heading += data[i].reference_doctype + " - " +
-					`<a onclick="frappe.set_route('Form', '${data[i].reference_doctype}', '${data[i].reference_name}');">
-						${data[i].reference_name}
-					</a>`;
-
-				details += `
-					<div data-toggle='pill' class='patient_doc_menu'
-						data-doctype='${data[i].reference_doctype}' data-docname='${data[i].reference_name}'>
-						<div class='col-sm-12 d-flex border-bottom py-3'>`;
-
-				if (data[i].imgsrc) {
-					details += `<span class='mr-3 avatar avatar-small' style='width:32px; height:32px;'>
-							<img class='avatar-frame' src='${data[i].imgsrc}' width='32' height='32'></img>
-						</span>`;
-				} else {
-					details += `<span class='mr-3 avatar avatar-small' style='width:32px; height:32px;'>
-						<div align='center' class='avatar-frame' style='background-color: #fafbfc;'>
-							${data[i].practitioner ? data[i].practitioner.charAt(0) : 'U'}
-						</div>
-					</span>`;
-				}
-
-				details += `<div class='d-flex flex-column width-full'>
-						<div>
-							`+time_line_heading+`
-								<span>
-									${data[i].date_sep}
-								</span>
-						</div>
-						<div class='frappe-card p-5 mt-3'>
-							<span class='${data[i].reference_name} document-id'>${label}
-							<br>
-								<div align='center'>
-									<a class='btn octicon octicon-chevron-down btn-default btn-xs btn-more'
-										data-doctype='${data[i].reference_doctype}' data-docname='${data[i].reference_name}'>
-									</a>
-								</div>
-							</span>
-
-							<span class='document-html' hidden data-fetched='0'>
-							</span>
-						</div>
-					</div>
-				</div>
-				</div>`;
-			}
-		}
-
-		this.page.main.find('.patient_documents_list').append(details);
-		this.start += data.length;
-
-		if (data.length === 20) {
-			this.page.main.find(".btn-get-records").show();
-		} else {
-			this.page.main.find(".btn-get-records").hide();
-			this.page.main.find(".patient_documents_list").append(`
-				<div class='text-muted' align='center'>
-					<br><br>${__('No more records..')}<br><br>
-				</div>`);
-		}
-	}
-
-	add_date_separator(data) {
-		let date = frappe.datetime.str_to_obj(data.communication_date);
-		let pdate = '';
-		let diff = frappe.datetime.get_day_diff(frappe.datetime.get_today(),
-			frappe.datetime.obj_to_str(date));
-
-		if (diff < 1) {
-			pdate = __('Today');
-		} else if (diff < 2) {
-			pdate = __('Yesterday');
-		} else {
-			pdate = __('on {0}', [frappe.datetime.global_date_format(date)]);
-		}
-		data.date_sep = pdate;
-		return data;
-	}
-
-	show_patient_info() {
-		this.get_patient_info().then(() => {
-			$('.patient-info').empty().append(frappe.render_template('patient_history_sidebar', {
-				patient_image: this.patient.image,
-				patient_name: this.patient.patient_name,
-				patient_gender: this.patient.sex,
-				patient_mobile: this.patient.mobile
-			}));
-			this.show_patient_details();
-		});
-	}
-
-	show_patient_details() {
-		let me = this;
-		frappe.call({
-			'method': 'erpnext.healthcare.doctype.patient.patient.get_patient_detail',
-			args: {
-				patient: me.patient_id
-			},
-			callback: function(r) {
-				let data = r.message;
-				let details = ``;
-
-				if (data.occupation) details += `<br><br><b> ${__('Occupation')} : </b> ${data.occupation}`;
-				if (data.blood_group) details += `<br><b> ${__('Blood Group')} : </b> ${data.blood_group}`;
-				if (data.allergies) details +=  `<br><br><b> ${__('Allerigies')} : </b> ${data.allergies.replace("\n", ", ")}`;
-				if (data.medication) details +=  `<br><b> ${__('Medication')} : </b> ${data.medication.replace("\n", ", ")}`;
-				if (data.alcohol_current_use) details +=  `<br><br><b> ${__('Alcohol use')} : </b> ${data.alcohol_current_use}`;
-				if (data.alcohol_past_use) details +=  `<br><b> ${__('Alcohol past use')} : </b> ${data.alcohol_past_use}`;
-				if (data.tobacco_current_use) details +=  `<br><b> ${__('Tobacco use')} : </b> ${data.tobacco_current_use}`;
-				if (data.tobacco_past_use) details +=  `<br><b> ${__('Tobacco past use')} : </b> ${data.tobacco_past_use}`;
-				if (data.medical_history) details +=  `<br><br><b> ${__('Medical history')} : </b> ${data.medical_history.replace("\n", ", ")}`;
-				if (data.surgical_history) details +=  `<br><b> ${__('Surgical history')} : </b> ${data.surgical_history.replace("\n", ", ")}`;
-				if (data.surrounding_factors) details +=  `<br><br><b> ${__('Occupational hazards')} : </b> ${data.surrounding_factors.replace("\n", ", ")}`;
-				if (data.other_risk_factors) details += `<br><b> ${__('Other risk factors')} : </b> ${data.other_risk_factors.replace("\n", ", ")}`;
-				if (data.patient_details) details += `<br><br><b> ${__('More info')} : </b> ${data.patient_details.replace("\n", ", ")}`;
-
-				if (details) {
-					details = `<div style='font-size:13px;' align='left'>` + details + `</div>`;
-				}
-
-				me.sidebar.find('.patient-details').html(details);
-			}
-		});
-	}
-
-	get_patient_info() {
-		return frappe.xcall('frappe.client.get', {
-			doctype: 'Patient',
-			name: this.patient_id,
-		}).then((patient) => {
-			if (patient) {
-				this.patient = patient;
-			}
-		});
-	}
-
-	setup_buttons() {
-		let me = this;
-		this.page.main.on("click", ".btn-show-chart", function() {
-			let btn_id = $(this).attr("data-show-chart-id"), scale_unit = $(this).attr("data-pts");
-			let title = $(this).attr("data-title");
-			me.show_patient_vital_charts(btn_id, scale_unit, title);
-		});
-
-		this.page.main.on('click', '.btn-more', function() {
-			let	doctype = $(this).attr('data-doctype'), docname = $(this).attr('data-docname');
-			if (me.page.main.find('.'+docname).parent().find('.document-html').attr('data-fetched') == '1') {
-				me.page.main.find('.'+docname).hide();
-				me.page.main.find('.'+docname).parent().find('.document-html').show();
-			} else {
-				if (doctype && docname) {
-					let exclude = ['patient', 'patient_name', 'patient_sex', 'encounter_date', 'naming_series'];
-					frappe.call({
-						method: 'erpnext.healthcare.utils.render_doc_as_html',
-						args: {
-							doctype: doctype,
-							docname: docname,
-							exclude_fields: exclude
-						},
-						freeze: true,
-						callback: function(r) {
-							if (r.message) {
-								me.page.main.find('.' + docname).hide();
-
-								me.page.main.find('.' + docname).parent().find('.document-html').html(
-									`${r.message.html}
-									<br>
-										<div align='center'>
-											<a class='btn octicon octicon-chevron-up btn-default btn-xs btn-less'
-												data-doctype='${doctype}'
-												data-docname='${docname}'>
-											</a>
-										</div>
-									`);
-
-								me.page.main.find('.' + docname).parent().find('.document-html').attr('hidden', false);
-								me.page.main.find('.' + docname).parent().find('.document-html').attr('data-fetched', '1');
-							}
-						}
-					});
-				}
-			}
-		});
-
-		this.page.main.on('click', '.btn-less', function() {
-			let docname = $(this).attr('data-docname');
-			me.page.main.find('.' + docname).parent().find('.document-id').show();
-			me.page.main.find('.' + docname).parent().find('.document-html').hide();
-		});
-
-		me.page.main.on('click', '.btn-get-records', function() {
-			this.setup_documents();
-		});
-	}
-
-	show_patient_vital_charts(btn_id, scale_unit, title) {
-		let me = this;
-
-		frappe.call({
-			method: 'erpnext.healthcare.utils.get_patient_vitals',
-			args: {
-				patient: me.patient_id
-			},
-			callback: function(r) {
-				if (r.message) {
-					let show_chart_btns_html = `
-						<div style='padding-top:10px;'>
-							<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='bp' data-pts='mmHg' data-title='Blood Pressure'>
-								${__('Blood Pressure')}
-							</a>
-							<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='pulse_rate' data-pts='per Minutes' data-title='Respiratory/Pulse Rate'>
-								${__('Respiratory/Pulse Rate')}
-							</a>
-							<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='temperature' data-pts='°C or °F' data-title='Temperature'>
-								${__('Temperature')}
-							</a>
-							<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='bmi' data-pts='' data-title='BMI'>
-								${__('BMI')}
-							</a>
-						</div>`;
-
-					me.page.main.find('.show_chart_btns').html(show_chart_btns_html);
-					let data = r.message;
-					let labels = [], datasets = [];
-					let bp_systolic = [], bp_diastolic = [], temperature = [];
-					let pulse = [], respiratory_rate = [], bmi = [], height = [], weight = [];
-
-					for (let i=0; i<data.length; i++) {
-						labels.push(data[i].signs_date+' | '+data[i].signs_time);
-
-						if (btn_id === 'bp') {
-							bp_systolic.push(data[i].bp_systolic);
-							bp_diastolic.push(data[i].bp_diastolic);
-						}
-						if (btn_id === 'temperature') {
-							temperature.push(data[i].temperature);
-						}
-						if (btn_id === 'pulse_rate') {
-							pulse.push(data[i].pulse);
-							respiratory_rate.push(data[i].respiratory_rate);
-						}
-						if (btn_id === 'bmi') {
-							bmi.push(data[i].bmi);
-							height.push(data[i].height);
-							weight.push(data[i].weight);
-						}
-					}
-					if (btn_id === 'temperature') {
-						datasets.push({name: 'Temperature', values: temperature, chartType: 'line'});
-					}
-					if (btn_id === 'bmi') {
-						datasets.push({name: 'BMI', values: bmi, chartType: 'line'});
-						datasets.push({name: 'Height', values: height, chartType: 'line'});
-						datasets.push({name: 'Weight', values: weight, chartType: 'line'});
-					}
-					if (btn_id === 'bp') {
-						datasets.push({name: 'BP Systolic', values: bp_systolic, chartType: 'line'});
-						datasets.push({name: 'BP Diastolic', values: bp_diastolic, chartType: 'line'});
-					}
-					if (btn_id === 'pulse_rate') {
-						datasets.push({name: 'Heart Rate / Pulse', values: pulse, chartType: 'line'});
-						datasets.push({name: 'Respiratory Rate', values: respiratory_rate, chartType: 'line'});
-					}
-
-					new frappe.Chart('.patient_vital_charts', {
-						data: {
-							labels: labels,
-							datasets: datasets
-						},
-
-						title: title,
-						type: 'axis-mixed',
-						height: 200,
-						colors: ['purple', '#ffa3ef', 'light-blue'],
-
-						tooltipOptions: {
-							formatTooltipX: d => (d + '').toUpperCase(),
-							formatTooltipY: d => d + ' ' + scale_unit,
-						}
-					});
-					me.page.main.find('.header-separator').show();
-				} else {
-					me.page.main.find('.patient_vital_charts').html('');
-					me.page.main.find('.show_chart_btns').html('');
-					me.page.main.find('.header-separator').hide();
-				}
-			}
-		});
-	}
-}
diff --git a/erpnext/healthcare/page/patient_history/patient_history.json b/erpnext/healthcare/page/patient_history/patient_history.json
deleted file mode 100644
index b3892a4..0000000
--- a/erpnext/healthcare/page/patient_history/patient_history.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "content": null, 
- "creation": "2018-08-08 17:09:13.816199", 
- "docstatus": 0, 
- "doctype": "Page", 
- "icon": "", 
- "idx": 0, 
- "modified": "2018-08-08 17:09:55.969424", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "patient_history", 
- "owner": "Administrator", 
- "page_name": "patient_history", 
- "restrict_to_domain": "Healthcare", 
- "roles": [
-  {
-   "role": "Healthcare Administrator"
-  }, 
-  {
-   "role": "Physician"
-  }
- ], 
- "script": null, 
- "standard": "Yes", 
- "style": null, 
- "system_page": 0, 
- "title": "Patient History"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/page/patient_history/patient_history.py b/erpnext/healthcare/page/patient_history/patient_history.py
deleted file mode 100644
index 77d8846..0000000
--- a/erpnext/healthcare/page/patient_history/patient_history.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-import json
-
-import frappe
-from frappe.utils import cint
-
-
-@frappe.whitelist()
-def get_feed(name, document_types=None, date_range=None, start=0, page_length=20):
-	"""get feed"""
-	filters = get_filters(name, document_types, date_range)
-
-	result = frappe.db.get_all('Patient Medical Record',
-		fields=['name', 'owner', 'communication_date',
-			'reference_doctype', 'reference_name', 'subject'],
-		filters=filters,
-		order_by='communication_date DESC',
-		limit=cint(page_length),
-		start=cint(start)
-	)
-
-	return result
-
-
-def get_filters(name, document_types=None, date_range=None):
-	filters = {'patient': name}
-	if document_types:
-		document_types = json.loads(document_types)
-		if len(document_types):
-			filters['reference_doctype'] = ['IN', document_types]
-
-	if date_range:
-		try:
-			date_range = json.loads(date_range)
-			if date_range:
-				filters['communication_date'] = ['between', [date_range[0], date_range[1]]]
-		except json.decoder.JSONDecodeError:
-			pass
-
-	return filters
-
-
-@frappe.whitelist()
-def get_feed_for_dt(doctype, docname):
-	"""get feed"""
-	result = frappe.db.get_all('Patient Medical Record',
-		fields=['name', 'owner', 'communication_date',
-			'reference_doctype', 'reference_name', 'subject'],
-		filters={
-			'reference_doctype': doctype,
-			'reference_name': docname
-		},
-		order_by='communication_date DESC'
-	)
-
-	return result
-
-
-@frappe.whitelist()
-def get_patient_history_doctypes():
-	document_types = []
-	settings = frappe.get_single("Patient History Settings")
-
-	for entry in settings.standard_doctypes:
-		document_types.append(entry.document_type)
-
-	for entry in settings.custom_doctypes:
-		document_types.append(entry.document_type)
-
-	return document_types
diff --git a/erpnext/healthcare/page/patient_history/patient_history_sidebar.html b/erpnext/healthcare/page/patient_history/patient_history_sidebar.html
deleted file mode 100644
index fc7eab0..0000000
--- a/erpnext/healthcare/page/patient_history/patient_history_sidebar.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<div class="patient-history-sidebar">
-    <div class="patient-image-container">
-		{% if patient_image %}
-			<div class="patient-image" src={{patient_image}} style="background-image: url(\'{%= patient_image %}\')"></div>
-		{% endif %}
-    </div>
-    <div class="patient-intro">
-		{% if patient_name %}
-		<p class="patient-name bold">{{patient_name}}</p>
-		{% endif %}
-		{% if patient_gender %}
-		<p class="patient-gender text-muted">{%=__("Gender: ") %} {{patient_gender}}</p>
-		{% endif %}
-		{% if patient_mobile %}
-		<p class="patient-mobile text-muted">{%=__("Contact: ") %} {{patient_mobile}}</p>
-		{% endif %}
-	</div>
-    <div class="patient-details">
-    </div>
-</div>
diff --git a/erpnext/healthcare/page/patient_progress/__init__.py b/erpnext/healthcare/page/patient_progress/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/page/patient_progress/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/page/patient_progress/patient_progress.css b/erpnext/healthcare/page/patient_progress/patient_progress.css
deleted file mode 100644
index 737b2e0..0000000
--- a/erpnext/healthcare/page/patient_progress/patient_progress.css
+++ /dev/null
@@ -1,171 +0,0 @@
-/* sidebar */
-
-.layout-side-section .frappe-control[data-fieldname='patient'] {
-  max-width: 300px;
-}
-
-.patient-image-container {
-  margin-top: 17px;
-}
-
-.patient-image {
-  display: inline-block;
-  width: 100%;
-  height: 0;
-  padding: 50% 0px;
-  background-size: cover;
-  background-repeat: no-repeat;
-  background-position: center center;
-  border-radius: 4px;
-}
-
-.patient-details {
-  margin: -5px 5px;
-}
-
-.important-links {
-  margin: 30px 5px;
-}
-
-.patient-name {
-  font-size: 20px;
-  margin-top: 25px;
-}
-
-/* heatmap */
-
-.heatmap-container {
-  height: 170px;
-}
-
-.patient-heatmap {
-  width: 80%;
-  display: inline-block;
-}
-
-.patient-heatmap .chart-container {
-  margin-left: 30px;
-}
-
-.patient-heatmap .frappe-chart {
-  margin-top: 5px;
-}
-
-.patient-heatmap .frappe-chart .chart-legend {
-  display: none;
-}
-
-.heatmap-container .chart-filter {
-  z-index: 1;
-  position: relative;
-  top: 5px;
-  margin-right: 10px;
-}
-
-/* percentage chart */
-
-.percentage-chart-container {
-  height: 130px;
-}
-
-.percentage-chart-container .chart-filter {
-  position: relative;
-  top: 5px;
-  margin-right: 10px;
-}
-
-.therapy-session-percentage-chart .frappe-chart {
-  position: absolute;
-  top: 5px;
-}
-
-/* line charts */
-
-.date-field .clearfix {
-  display: none;
-}
-
-.date-field .help-box {
-  display: none;
-}
-
-.date-field .frappe-control {
-  margin-bottom: 0px !important;
-}
-
-.date-field .form-group {
-  margin-bottom: 0px !important;
-}
-
-/* common */
-
-text.title {
-  text-transform: uppercase;
-  font-size: 11px;
-  margin-left: 20px;
-  margin-top: 20px;
-  display: block;
-}
-
-.chart-filter-search {
-  margin-left: 35px;
-  width: 25%;
-}
-
-.chart-column-container {
-  margin: 5px 0;
-}
-
-.progress-graphs .progress-container {
-  margin-bottom: var(--margin-xl);
-}
-
-.line-chart-container .frappe-chart {
-  margin-top: -20px;
-}
-
-.line-chart-container {
-  margin-bottom: 20px;
-}
-
-.chart-control {
-  align-self: center;
-  display: flex;
-  flex-direction: row-reverse;
-  margin-top: -25px;
-}
-
-.chart-control > * {
-  margin-right: 10px;
-}
-
-/* mobile */
-
-@media (max-width: 991px) {
-  .patient-progress-sidebar {
-    display: flex;
-  }
-
-  .percentage-chart-container {
-    border-top: 1px solid #d1d8dd;
-  }
-
-  .percentage-chart-container .chart-filter {
-    z-index: 1;
-    position: relative;
-    top: 12px;
-    margin-right: 10px;
-  }
-
-  .patient-progress-sidebar .important-links {
-    margin: 0;
-  }
-
-  .patient-progress-sidebar .patient-details {
-    width: 50%;
-  }
-
-  .chart-filter-search {
-    width: 40%;
-  }
-}
diff --git a/erpnext/healthcare/page/patient_progress/patient_progress.html b/erpnext/healthcare/page/patient_progress/patient_progress.html
deleted file mode 100644
index ee60065..0000000
--- a/erpnext/healthcare/page/patient_progress/patient_progress.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<div class="row patient-progress">
-	<div class="col-md-12">
-		<div class="progress-graphs">
-			<div class="progress-container chart-column-container heatmap-container hidden-xs hidden-sm frappe-card">
-				<div class="patient-heatmap"></div>
-			</div>
-
-			<div class="progress-container chart-column-container percentage-chart-container frappe-card">
-				<div class="therapy-session-percentage-chart"></div>
-			</div>
-
-			<div class="progress-container therapy-progress frappe-card">
-				<div class="chart-head">
-					<text class="title" text-anchor="start">Therapy Progress</text>
-					<div class="chart-control pull-right"></div>
-				</div>
-				<div class="row">
-					<div class="chart-filter-search therapy-type-search"></div>
-				</div>
-				<div class="col-md-12 chart-column-container line-chart-container">
-					<div class="therapy-progress-line-chart">
-					</div>
-				</div>
-			</div>
-
-			<div class="progress-container assessment-results frappe-card">
-				<div class="chart-head">
-					<text class="title" text-anchor="start">Assessment Results</text>
-					<div class="chart-control pull-right"></div>
-				</div>
-				<div class="row">
-					<div class="chart-filter-search assessment-template-search"></div>
-				</div>
-				<div class="col-md-12 chart-column-container line-chart-container">
-					<div class="assessment-results-line-chart">
-					</div>
-				</div>
-			</div>
-
-			<div class="progress-container therapy-assessment-correlation progress-line-chart frappe-card">
-				<div class="chart-head">
-					<text class="title" text-anchor="start">Therapy Type and Assessment Correlation</text>
-					<div class="chart-control pull-right"></div>
-				</div>
-				<div class="row">
-					<div class="chart-filter-search assessment-correlation-template-search"></div>
-				</div>
-				<div class="col-md-12 chart-column-container line-chart-container">
-					<div class="therapy-assessment-correlation-chart">
-					</div>
-				</div>
-			</div>
-
-			<div class="progress-container assessment-parameter-progress progress-line-chart frappe-card">
-				<div class="chart-head">
-					<text class="title" text-anchor="start">Assessment Parameter Wise Progress</text>
-					<div class="chart-control pull-right"></div>
-				</div>
-				<div class="row">
-					<div class="chart-filter-search assessment-parameter-search"></div>
-				</div>
-				<div class="col-md-12 line-chart-container">
-					<div class="assessment-parameter-progress-chart">
-					</div>
-				</div>
-			</div>
-		</div>
-	</div>
-</div>
diff --git a/erpnext/healthcare/page/patient_progress/patient_progress.js b/erpnext/healthcare/page/patient_progress/patient_progress.js
deleted file mode 100644
index 3f06f1f..0000000
--- a/erpnext/healthcare/page/patient_progress/patient_progress.js
+++ /dev/null
@@ -1,536 +0,0 @@
-frappe.pages['patient-progress'].on_page_load = function(wrapper) {
-
-	frappe.ui.make_app_page({
-		parent: wrapper,
-		title: __('Patient Progress')
-	});
-
-	let patient_progress = new PatientProgress(wrapper);
-	$(wrapper).bind('show', ()=> {
-		patient_progress.show();
-	});
-};
-
-class PatientProgress {
-
-	constructor(wrapper) {
-		this.wrapper = $(wrapper);
-		this.page = wrapper.page;
-		this.sidebar = this.wrapper.find('.layout-side-section');
-		this.main_section = this.wrapper.find('.layout-main-section');
-	}
-
-	show() {
-		frappe.breadcrumbs.add('Healthcare');
-		this.sidebar.empty();
-
-		let me = this;
-		let patient = frappe.ui.form.make_control({
-			parent: me.sidebar,
-			df: {
-				fieldtype: 'Link',
-				options: 'Patient',
-				fieldname: 'patient',
-				placeholder: __('Select Patient'),
-				only_select: true,
-				change: () => {
-					me.patient_id = '';
-					if (me.patient_id != patient.get_value() && patient.get_value()) {
-						me.start = 0;
-						me.patient_id = patient.get_value();
-						me.make_patient_profile();
-					}
-				}
-			}
-		});
-		patient.refresh();
-
-		if (frappe.route_options && !this.patient) {
-			patient.set_value(frappe.route_options.patient);
-			this.patient_id = frappe.route_options.patient;
-		}
-
-		this.sidebar.find('[data-fieldname="patient"]').append('<div class="patient-info"></div>');
-	}
-
-	make_patient_profile() {
-		this.page.set_title(__('Patient Progress'));
-		this.main_section.empty().append(frappe.render_template('patient_progress'));
-		this.render_patient_details();
-		this.render_heatmap();
-		this.render_percentage_chart('therapy_type', 'Therapy Type Distribution');
-		this.create_percentage_chart_filters();
-		this.show_therapy_progress();
-		this.show_assessment_results();
-		this.show_therapy_assessment_correlation();
-		this.show_assessment_parameter_progress();
-	}
-
-	get_patient_info() {
-		return frappe.xcall('frappe.client.get', {
-			doctype: 'Patient',
-			name: this.patient_id
-		}).then((patient) => {
-			if (patient) {
-				this.patient = patient;
-			}
-		});
-	}
-
-	get_therapy_sessions_count() {
-		return frappe.xcall(
-			'erpnext.healthcare.page.patient_progress.patient_progress.get_therapy_sessions_count', {
-				patient: this.patient_id,
-			}
-		).then(data => {
-			if (data) {
-				this.total_therapy_sessions = data.total_therapy_sessions;
-				this.therapy_sessions_this_month = data.therapy_sessions_this_month;
-			}
-		});
-	}
-
-	render_patient_details() {
-		this.get_patient_info().then(() => {
-			this.get_therapy_sessions_count().then(() => {
-				$('.patient-info').empty().append(frappe.render_template('patient_progress_sidebar', {
-					patient_image: this.patient.image,
-					patient_name: this.patient.patient_name,
-					patient_gender: this.patient.sex,
-					patient_mobile: this.patient.mobile,
-					total_therapy_sessions: this.total_therapy_sessions,
-					therapy_sessions_this_month: this.therapy_sessions_this_month
-				}));
-
-				this.setup_patient_profile_links();
-			});
-		});
-	}
-
-	setup_patient_profile_links() {
-		this.wrapper.find('.patient-profile-link').on('click', () => {
-			frappe.set_route('Form', 'Patient', this.patient_id);
-		});
-
-		this.wrapper.find('.therapy-plan-link').on('click', () => {
-			frappe.route_options = {
-				'patient': this.patient_id,
-				'docstatus': 1
-			};
-			frappe.set_route('List', 'Therapy Plan');
-		});
-
-		this.wrapper.find('.patient-history').on('click', () => {
-			frappe.route_options = {
-				'patient': this.patient_id
-			};
-			frappe.set_route('patient_history');
-		});
-	}
-
-	render_heatmap() {
-		this.heatmap = new frappe.Chart('.patient-heatmap', {
-			type: 'heatmap',
-			countLabel: 'Interactions',
-			data: {},
-			discreteDomains: 1,
-			radius: 3,
-			height: 150
-		});
-
-		this.update_heatmap_data();
-		this.create_heatmap_chart_filters();
-	}
-
-	update_heatmap_data(date_from) {
-		frappe.xcall('erpnext.healthcare.page.patient_progress.patient_progress.get_patient_heatmap_data', {
-			patient: this.patient_id,
-			date: date_from || frappe.datetime.year_start(),
-		}).then((data) => {
-			this.heatmap.update( {dataPoints: data} );
-		});
-	}
-
-	create_heatmap_chart_filters() {
-		this.get_patient_info().then(() => {
-			let filters = [
-				{
-					label: frappe.dashboard_utils.get_year(frappe.datetime.now_date()),
-					options: frappe.dashboard_utils.get_years_since_creation(this.patient.creation),
-					action: (selected_item) => {
-						this.update_heatmap_data(frappe.datetime.obj_to_str(selected_item));
-					}
-				},
-			];
-			frappe.dashboard_utils.render_chart_filters(filters, 'chart-filter', '.heatmap-container');
-		});
-	}
-
-	render_percentage_chart(field, title) {
-		// REDESIGN-TODO: chart seems to be broken. Enable this once fixed.
-		this.wrapper.find('.percentage-chart-container').hide();
-		// frappe.xcall(
-		// 	'erpnext.healthcare.page.patient_progress.patient_progress.get_therapy_sessions_distribution_data', {
-		// 		patient: this.patient_id,
-		// 		field: field
-		// 	}
-		// ).then(chart => {
-		// 	if (chart.labels.length) {
-		// 		this.percentage_chart = new frappe.Chart('.therapy-session-percentage-chart', {
-		// 			title: title,
-		// 			type: 'percentage',
-		// 			data: {
-		// 				labels: chart.labels,
-		// 				datasets: chart.datasets
-		// 			},
-		// 			truncateLegends: 1,
-		// 			barOptions: {
-		// 				height: 11,
-		// 				depth: 1
-		// 			},
-		// 			height: 160,
-		// 			maxSlices: 8,
-		// 			colors: ['#5e64ff', '#743ee2', '#ff5858', '#ffa00a', '#feef72', '#28a745', '#98d85b', '#a9a7ac'],
-		// 		});
-		// 	} else {
-		// 		this.wrapper.find('.percentage-chart-container').hide();
-		// 	}
-		// });
-	}
-
-	create_percentage_chart_filters() {
-		let filters = [
-			{
-				label: 'Therapy Type',
-				options: ['Therapy Type', 'Exercise Type'],
-				fieldnames: ['therapy_type', 'exercise_type'],
-				action: (selected_item, fieldname) => {
-					let title = selected_item + ' Distribution';
-					this.render_percentage_chart(fieldname, title);
-				}
-			},
-		];
-		frappe.dashboard_utils.render_chart_filters(filters, 'chart-filter', '.percentage-chart-container');
-	}
-
-	create_time_span_filters(action_method, parent) {
-		let chart_control = $(parent).find('.chart-control');
-		let filters = [
-			{
-				label: 'Last Month',
-				options: ['Select Date Range', 'Last Week', 'Last Month', 'Last Quarter', 'Last Year'],
-				action: (selected_item) => {
-					if (selected_item === 'Select Date Range') {
-						this.render_date_range_fields(action_method, chart_control);
-					} else {
-						// hide date range field if visible
-						let date_field = $(parent).find('.date-field');
-						if (date_field.is(':visible')) {
-							date_field.hide();
-						}
-						this[action_method](selected_item);
-					}
-				}
-			}
-		];
-		frappe.dashboard_utils.render_chart_filters(filters, 'chart-filter', chart_control, 1);
-	}
-
-	render_date_range_fields(action_method, parent) {
-		let date_field = $(parent).find('.date-field');
-
-		if (!date_field.length) {
-			let date_field_wrapper = $(
-				`<div class="date-field pull-right"></div>`
-			).appendTo(parent);
-
-			let date_range_field = frappe.ui.form.make_control({
-				df: {
-					fieldtype: 'DateRange',
-					fieldname: 'from_date',
-					placeholder: 'Date Range',
-					input_class: 'input-xs',
-					reqd: 1,
-					change: () => {
-						let selected_date_range = date_range_field.get_value();
-						if (selected_date_range && selected_date_range.length === 2) {
-							this[action_method](selected_date_range);
-						}
-					}
-				},
-				parent: date_field_wrapper,
-				render_input: 1
-			});
-		} else if (!date_field.is(':visible')) {
-			date_field.show();
-		}
-	}
-
-	show_therapy_progress() {
-		let me = this;
-		let therapy_type = frappe.ui.form.make_control({
-			parent: $('.therapy-type-search'),
-			df: {
-				fieldtype: 'Link',
-				options: 'Therapy Type',
-				fieldname: 'therapy_type',
-				placeholder: __('Select Therapy Type'),
-				only_select: true,
-				change: () => {
-					if (me.therapy_type != therapy_type.get_value() && therapy_type.get_value()) {
-						me.therapy_type = therapy_type.get_value();
-						me.render_therapy_progress_chart();
-					}
-				}
-			}
-		});
-		therapy_type.refresh();
-		this.create_time_span_filters('render_therapy_progress_chart', '.therapy-progress');
-	}
-
-	render_therapy_progress_chart(time_span='Last Month') {
-		if (!this.therapy_type) return;
-
-		frappe.xcall(
-			'erpnext.healthcare.page.patient_progress.patient_progress.get_therapy_progress_data', {
-				patient: this.patient_id,
-				therapy_type: this.therapy_type,
-				time_span: time_span
-			}
-		).then(chart => {
-			let data = {
-				labels: chart.labels,
-				datasets: chart.datasets
-			}
-			let parent = '.therapy-progress-line-chart';
-			if (!chart.labels.length) {
-				this.show_null_state(parent);
-			} else {
-				if (!this.therapy_line_chart) {
-					this.therapy_line_chart = new frappe.Chart(parent, {
-						type: 'axis-mixed',
-						height: 250,
-						data: data,
-						lineOptions: {
-							regionFill: 1
-						},
-						axisOptions: {
-							xIsSeries: 1
-						}
-					});
-				} else {
-					$(parent).find('.chart-container').show();
-					$(parent).find('.chart-empty-state').hide();
-					this.therapy_line_chart.update(data);
-				}
-			}
-		});
-	}
-
-	show_assessment_results() {
-		let me = this;
-		let assessment_template = frappe.ui.form.make_control({
-			parent: $('.assessment-template-search'),
-			df: {
-				fieldtype: 'Link',
-				options: 'Patient Assessment Template',
-				fieldname: 'assessment_template',
-				placeholder: __('Select Assessment Template'),
-				only_select: true,
-				change: () => {
-					if (me.assessment_template != assessment_template.get_value() && assessment_template.get_value()) {
-						me.assessment_template = assessment_template.get_value();
-						me.render_assessment_result_chart();
-					}
-				}
-			}
-		});
-		assessment_template.refresh();
-		this.create_time_span_filters('render_assessment_result_chart', '.assessment-results');
-	}
-
-	render_assessment_result_chart(time_span='Last Month') {
-		if (!this.assessment_template) return;
-
-		frappe.xcall(
-			'erpnext.healthcare.page.patient_progress.patient_progress.get_patient_assessment_data', {
-				patient: this.patient_id,
-				assessment_template: this.assessment_template,
-				time_span: time_span
-			}
-		).then(chart => {
-			let data = {
-				labels: chart.labels,
-				datasets: chart.datasets,
-				yMarkers: [
-					{ label: 'Max Score', value: chart.max_score }
-				],
-			}
-			let parent = '.assessment-results-line-chart';
-			if (!chart.labels.length) {
-				this.show_null_state(parent);
-			} else {
-				if (!this.assessment_line_chart) {
-					this.assessment_line_chart = new frappe.Chart(parent, {
-						type: 'axis-mixed',
-						height: 250,
-						data: data,
-						lineOptions: {
-							regionFill: 1
-						},
-						axisOptions: {
-							xIsSeries: 1
-						},
-						tooltipOptions: {
-							formatTooltipY: d => __('{0} out of {1}', [d, chart.max_score])
-						}
-					});
-				} else {
-					$(parent).find('.chart-container').show();
-					$(parent).find('.chart-empty-state').hide();
-					this.assessment_line_chart.update(data);
-				}
-			}
-		});
-	}
-
-	show_therapy_assessment_correlation() {
-		let me = this;
-		let assessment = frappe.ui.form.make_control({
-			parent: $('.assessment-correlation-template-search'),
-			df: {
-				fieldtype: 'Link',
-				options: 'Patient Assessment Template',
-				fieldname: 'assessment',
-				placeholder: __('Select Assessment Template'),
-				only_select: true,
-				change: () => {
-					if (me.assessment != assessment.get_value() && assessment.get_value()) {
-						me.assessment = assessment.get_value();
-						me.render_therapy_assessment_correlation_chart();
-					}
-				}
-			}
-		});
-		assessment.refresh();
-		this.create_time_span_filters('render_therapy_assessment_correlation_chart', '.therapy-assessment-correlation');
-	}
-
-	render_therapy_assessment_correlation_chart(time_span='Last Month') {
-		if (!this.assessment) return;
-
-		frappe.xcall(
-			'erpnext.healthcare.page.patient_progress.patient_progress.get_therapy_assessment_correlation_data', {
-				patient: this.patient_id,
-				assessment_template: this.assessment,
-				time_span: time_span
-			}
-		).then(chart => {
-			let data = {
-				labels: chart.labels,
-				datasets: chart.datasets,
-				yMarkers: [
-					{ label: 'Max Score', value: chart.max_score }
-				],
-			}
-			let parent = '.therapy-assessment-correlation-chart';
-			if (!chart.labels.length) {
-				this.show_null_state(parent);
-			} else {
-				if (!this.correlation_chart) {
-					this.correlation_chart = new frappe.Chart(parent, {
-						type: 'axis-mixed',
-						height: 300,
-						data: data,
-						axisOptions: {
-							xIsSeries: 1
-						}
-					});
-				} else {
-					$(parent).find('.chart-container').show();
-					$(parent).find('.chart-empty-state').hide();
-					this.correlation_chart.update(data);
-				}
-			}
-		});
-	}
-
-	show_assessment_parameter_progress() {
-		let me = this;
-		let parameter = frappe.ui.form.make_control({
-			parent: $('.assessment-parameter-search'),
-			df: {
-				fieldtype: 'Link',
-				options: 'Patient Assessment Parameter',
-				fieldname: 'assessment',
-				placeholder: __('Select Assessment Parameter'),
-				only_select: true,
-				change: () => {
-					if (me.parameter != parameter.get_value() && parameter.get_value()) {
-						me.parameter = parameter.get_value();
-						me.render_assessment_parameter_progress_chart();
-					}
-				}
-			}
-		});
-		parameter.refresh();
-		this.create_time_span_filters('render_assessment_parameter_progress_chart', '.assessment-parameter-progress');
-	}
-
-	render_assessment_parameter_progress_chart(time_span='Last Month') {
-		if (!this.parameter) return;
-
-		frappe.xcall(
-			'erpnext.healthcare.page.patient_progress.patient_progress.get_assessment_parameter_data', {
-				patient: this.patient_id,
-				parameter: this.parameter,
-				time_span: time_span
-			}
-		).then(chart => {
-			let data = {
-				labels: chart.labels,
-				datasets: chart.datasets
-			}
-			let parent = '.assessment-parameter-progress-chart';
-			if (!chart.labels.length) {
-				this.show_null_state(parent);
-			} else {
-				if (!this.parameter_chart) {
-					this.parameter_chart = new frappe.Chart(parent, {
-						type: 'line',
-						height: 250,
-						data: data,
-						lineOptions: {
-							regionFill: 1
-						},
-						axisOptions: {
-							xIsSeries: 1
-						},
-						tooltipOptions: {
-							formatTooltipY: d => d + '%'
-						}
-					});
-				} else {
-					$(parent).find('.chart-container').show();
-					$(parent).find('.chart-empty-state').hide();
-					this.parameter_chart.update(data);
-				}
-			}
-		});
-	}
-
-	show_null_state(parent) {
-		let null_state = $(parent).find('.chart-empty-state');
-		if (null_state.length) {
-			$(null_state).show();
-		} else {
-			null_state = $(
-				`<div class="chart-empty-state text-muted text-center" style="margin-bottom: 20px;">${__(
-					"No Data..."
-				)}</div>`
-			);
-			$(parent).append(null_state);
-		}
-		$(parent).find('.chart-container').hide();
-	}
-}
diff --git a/erpnext/healthcare/page/patient_progress/patient_progress.json b/erpnext/healthcare/page/patient_progress/patient_progress.json
deleted file mode 100644
index 0175cb9..0000000
--- a/erpnext/healthcare/page/patient_progress/patient_progress.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "content": null,
- "creation": "2020-06-12 15:46:23.111928",
- "docstatus": 0,
- "doctype": "Page",
- "idx": 0,
- "modified": "2020-07-23 21:45:45.540055",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "patient-progress",
- "owner": "Administrator",
- "page_name": "patient-progress",
- "restrict_to_domain": "Healthcare",
- "roles": [
-  {
-   "role": "Healthcare Administrator"
-  },
-  {
-   "role": "Physician"
-  },
-  {
-   "role": "Patient"
-  },
-  {
-   "role": "System Manager"
-  }
- ],
- "script": null,
- "standard": "Yes",
- "style": null,
- "system_page": 0,
- "title": "Patient Progress"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/page/patient_progress/patient_progress.py b/erpnext/healthcare/page/patient_progress/patient_progress.py
deleted file mode 100644
index c17f105..0000000
--- a/erpnext/healthcare/page/patient_progress/patient_progress.py
+++ /dev/null
@@ -1,198 +0,0 @@
-import json
-from datetime import datetime
-
-import frappe
-from frappe import _
-from frappe.utils import get_timespan_date_range, getdate
-
-
-@frappe.whitelist()
-def get_therapy_sessions_count(patient):
-	total = frappe.db.count('Therapy Session', filters={
-		'docstatus': 1,
-		'patient': patient
-	})
-
-	month_start = datetime.today().replace(day=1)
-	this_month = frappe.db.count('Therapy Session', filters={
-		'creation': ['>', month_start],
-		'docstatus': 1,
-		'patient': patient
-	})
-
-	return {
-		'total_therapy_sessions': total,
-		'therapy_sessions_this_month': this_month
-	}
-
-
-@frappe.whitelist()
-def get_patient_heatmap_data(patient, date):
-	return dict(frappe.db.sql("""
-		SELECT
-			unix_timestamp(communication_date), count(*)
-		FROM
-			`tabPatient Medical Record`
-		WHERE
-			communication_date > subdate(%(date)s, interval 1 year) and
-			communication_date < subdate(%(date)s, interval -1 year) and
-			patient = %(patient)s
-		GROUP BY communication_date
-		ORDER BY communication_date asc""", {'date': date, 'patient': patient}))
-
-
-@frappe.whitelist()
-def get_therapy_sessions_distribution_data(patient, field):
-	if field == 'therapy_type':
-		result = frappe.db.get_all('Therapy Session',
-			filters = {'patient': patient, 'docstatus': 1},
-			group_by = field,
-			order_by = field,
-			fields = [field, 'count(*)'],
-			as_list = True)
-
-	elif field == 'exercise_type':
-		data = frappe.db.get_all('Therapy Session',  filters={
-			'docstatus': 1,
-			'patient': patient
-		}, as_list=True)
-		therapy_sessions = [entry[0] for entry in data]
-
-		result = frappe.db.get_all('Exercise',
-			filters = {
-				'parenttype': 'Therapy Session',
-				'parent': ['in', therapy_sessions],
-				'docstatus': 1
-			},
-			group_by = field,
-			order_by = field,
-			fields = [field, 'count(*)'],
-			as_list = True)
-
-	return {
-		'labels': [r[0] for r in result if r[0] != None],
-		'datasets': [{
-			'values': [r[1] for r in result]
-		}]
-	}
-
-
-@frappe.whitelist()
-def get_therapy_progress_data(patient, therapy_type, time_span):
-	date_range = get_date_range(time_span)
-	query_values = {'from_date': date_range[0], 'to_date': date_range[1], 'therapy_type': therapy_type, 'patient': patient}
-	result = frappe.db.sql("""
-		SELECT
-			start_date, total_counts_targeted, total_counts_completed
-		FROM
-			`tabTherapy Session`
-		WHERE
-			start_date BETWEEN %(from_date)s AND %(to_date)s and
-			docstatus = 1 and
-			therapy_type = %(therapy_type)s and
-			patient = %(patient)s
-		ORDER BY start_date""", query_values, as_list=1)
-
-	return {
-		'labels': [r[0] for r in result if r[0] != None],
-		'datasets': [
-			{ 'name': _('Targetted'), 'values': [r[1] for r in result if r[0] != None] },
-			{ 'name': _('Completed'), 'values': [r[2] for r in result if r[0] != None] }
-		]
-	}
-
-@frappe.whitelist()
-def get_patient_assessment_data(patient, assessment_template, time_span):
-	date_range = get_date_range(time_span)
-	query_values = {'from_date': date_range[0], 'to_date': date_range[1], 'assessment_template': assessment_template, 'patient': patient}
-	result = frappe.db.sql("""
-		SELECT
-			assessment_datetime, total_score, total_score_obtained
-		FROM
-			`tabPatient Assessment`
-		WHERE
-			DATE(assessment_datetime) BETWEEN %(from_date)s AND %(to_date)s and
-			docstatus = 1 and
-			assessment_template = %(assessment_template)s and
-			patient = %(patient)s
-		ORDER BY assessment_datetime""", query_values, as_list=1)
-
-	return {
-		'labels': [getdate(r[0]) for r in result if r[0] != None],
-		'datasets': [
-			{ 'name': _('Score Obtained'), 'values': [r[2] for r in result if r[0] != None] }
-		],
-		'max_score': result[0][1] if result else None
-	}
-
-@frappe.whitelist()
-def get_therapy_assessment_correlation_data(patient, assessment_template, time_span):
-	date_range = get_date_range(time_span)
-	query_values = {'from_date': date_range[0], 'to_date': date_range[1], 'assessment': assessment_template, 'patient': patient}
-	result = frappe.db.sql("""
-		SELECT
-			therapy.therapy_type, count(*), avg(assessment.total_score_obtained), total_score
-		FROM
-			`tabPatient Assessment` assessment INNER JOIN `tabTherapy Session` therapy
-		ON
-			assessment.therapy_session = therapy.name
-		WHERE
-			DATE(assessment.assessment_datetime) BETWEEN %(from_date)s AND %(to_date)s and
-			assessment.docstatus = 1 and
-			assessment.patient = %(patient)s and
-			assessment.assessment_template = %(assessment)s
-		GROUP BY therapy.therapy_type
-	""", query_values, as_list=1)
-
-	return {
-		'labels': [r[0] for r in result if r[0] != None],
-		'datasets': [
-			{ 'name': _('Sessions'), 'chartType': 'bar', 'values': [r[1] for r in result if r[0] != None] },
-			{ 'name': _('Average Score'), 'chartType': 'line', 'values': [round(r[2], 2) for r in result if r[0] != None] }
-		],
-		'max_score': result[0][1] if result else None
-	}
-
-@frappe.whitelist()
-def get_assessment_parameter_data(patient, parameter, time_span):
-	date_range = get_date_range(time_span)
-	query_values = {'from_date': date_range[0], 'to_date': date_range[1], 'parameter': parameter, 'patient': patient}
-	results = frappe.db.sql("""
-		SELECT
-			assessment.assessment_datetime,
-			sheet.score,
-			template.scale_max
-		FROM
-			`tabPatient Assessment Sheet` sheet
-		INNER JOIN `tabPatient Assessment` assessment
-			ON sheet.parent = assessment.name
-		INNER JOIN `tabPatient Assessment Template` template
-			ON template.name = assessment.assessment_template
-		WHERE
-			DATE(assessment.assessment_datetime) BETWEEN %(from_date)s AND %(to_date)s and
-			assessment.docstatus = 1 and
-			sheet.parameter = %(parameter)s and
-			assessment.patient = %(patient)s
-		ORDER BY
-			assessment.assessment_datetime asc
-	""", query_values, as_list=1)
-
-	score_percentages = []
-	for r in results:
-		if r[2] != 0 and r[0] != None:
-			score = round((int(r[1]) / int(r[2])) * 100, 2)
-			score_percentages.append(score)
-
-	return {
-		'labels': [getdate(r[0]) for r in results if r[0] != None],
-		'datasets': [
-			{ 'name': _('Score'), 'values': score_percentages }
-		]
-	}
-
-def get_date_range(time_span):
-	try:
-		time_span = json.loads(time_span)
-		return time_span
-	except json.decoder.JSONDecodeError:
-		return get_timespan_date_range(time_span.lower())
diff --git a/erpnext/healthcare/page/patient_progress/patient_progress_sidebar.html b/erpnext/healthcare/page/patient_progress/patient_progress_sidebar.html
deleted file mode 100644
index 4ee6573..0000000
--- a/erpnext/healthcare/page/patient_progress/patient_progress_sidebar.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<div class="patient-progress-sidebar">
-	<div class="patient-image-container">
-		{% if patient_image %}
-			<div class="patient-image" src={{patient_image}} style="background-image: url(\'{%= patient_image %}\')"></div>
-		{% endif %}
-	</div>
-	<div class="patient-details">
-		{% if patient_name %}
-		<p class="patient-name bold">{{patient_name}}</p>
-		{% endif %}
-		{% if patient_gender %}
-		<p class="patient-gender text-muted">{%=__("Gender: ") %} {{patient_gender}}</p>
-		{% endif %}
-		{% if patient_mobile %}
-		<p class="patient-mobile text-muted">{%=__("Contact: ") %} {{patient_mobile}}</p>
-		{% endif %}
-		{% if total_therapy_sessions %}
-		<p class="patient-sessions text-muted">{%=__("Total Therapy Sessions: ") %} {{total_therapy_sessions}}</p>
-		{% endif %}
-		{% if therapy_sessions_this_month %}
-		<p class="patient-sessions text-muted">{%=__("Monthly Therapy Sessions: ") %} {{therapy_sessions_this_month}}</p>
-		{% endif %}
-	</div>
-	<div class="important-links">
-		<p><a class="patient-profile-link">{%=__("Patient Profile") %}</a></p>
-		<p><a class="therapy-plan-link">{%=__("Therapy Plan") %}</a></p>
-		<p><a class="patient-history">{%=__("Patient History") %}</a></p>
-	</div>
-</div>
diff --git a/erpnext/healthcare/print_format/__init__.py b/erpnext/healthcare/print_format/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/print_format/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/print_format/encounter_print/__init__.py b/erpnext/healthcare/print_format/encounter_print/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/print_format/encounter_print/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/print_format/encounter_print/encounter_print.json b/erpnext/healthcare/print_format/encounter_print/encounter_print.json
deleted file mode 100644
index 3c90adb..0000000
--- a/erpnext/healthcare/print_format/encounter_print/encounter_print.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "align_labels_right": 0,
- "creation": "2017-04-10 14:05:53.355863",
- "custom_format": 1,
- "disabled": 0,
- "doc_type": "Patient Encounter",
- "docstatus": 0,
- "doctype": "Print Format",
- "font": "Default",
- "html": "<div >\n    {% if letter_head and not no_letterhead -%}\n    <div class=\"letter-head\">{{ letter_head }}</div>\n    <hr>\n    {% else %}\n    <div align=\"right\">\n      <h1>{{doc.name}}</h1>\n    </div>\n    {%- endif %}\n    <div class=\"row section-break\">\n        <div class=\"col-xs-6 column-break\">\n                {% if doc.appointment %}\n\t        <div class=\"row\">\n\t\t\t<div class=\"col-xs-4 text-left\">\n\t\t\t<label>Appointment</label>\n\t\t\t</div>\n\t\t\t<div class=\"col-xs-7  value\">\n\t\t\t<strong>: </strong>{{doc.appointment}}\n\t\t\t</div>\n\t\t</div>\n\t\t{%- endif -%}\n\n                <div class=\"row\">\n\t\t      <div class=\"col-xs-4 text-left\">\n\t\t\t <label>Patient</label>\n\t\t      </div>\n                     {% if doc.patient %}\n\t\t      <div class=\"col-xs-7  value\">\n\t\t\t  <strong>: </strong>{{doc.patient}}\n\t\t      </div>\n                     {% else %}\n                     <div class=\"col-xs-7  value\">\n\t\t\t <strong>: </strong><em>Patient Name</em>\n\t\t     </div>\n                     {%- endif -%}\n\t\t</div>\n\t        <div class=\"row\">\n\t\t\t<div class=\"col-xs-4 text-left\">\n\t\t\t\t<label>Age</label>\n\t\t\t</div>\n\t\t\t<div class=\"col-xs-7  value\">\n\t\t\t     <strong>: </strong> {{doc.patient_age}}\n\t\t\t</div>\n\t\t</div>\n\n                <div class=\"row\">\n                        <div class=\"col-xs-4 text-left\">\n\t\t\t\t<label>Gender</label>\n\t\t\t</div>\n\t\t\t<div class=\"col-xs-7  value\">\n\t\t\t     <strong>: </strong> {{doc.patient_sex}}\n\t\t\t</div>\n                </div>\n\n        </div>\n        <div class=\"col-xs-6 column-break\">\n\n          <div class=\"row\">\n\t      <div class=\"col-xs-4 text-left\">\n\t\t    <label>Healthcare Practitioner</label>\n\t      </div>\n              {% if doc.practitioner %}\n\t      <div class=\"col-xs-7  text-left value\">\n\t\t\t<strong>: </strong>{{doc.practitioner}}\n\t      </div>\n              {%- endif -%}\n\t</div>\n\n          {% if doc.encounter_date %}\n\t  <div class=\"row\">\n\t\t<div class=\"col-xs-4 text-left\">\n\t\t<label>Date</label>\n\t\t</div>\n\t\t<div class=\"col-xs-7 text-left value\">\n\t\t<strong>: </strong>{{doc.encounter_date}}\n\t\t</div>\n          </div>\n\t  {%- endif -%}\n          {% if doc.encounter_time %}\n\t  <div class=\"row\">\n\t\t<div class=\"col-xs-4 text-left\">\n\t\t<label>Time</label>\n\t\t</div>\n\t\t<div class=\"col-xs-7 text-left value\">\n\t\t<strong>: </strong>{{doc.encounter_time}}\n\t\t</div>\n          </div>\n\t  {%- endif -%}\n          {% if doc.medical_department %}\n\t  <div class=\"row\">\n\t\t<div class=\"col-xs-4 text-left\">\n\t\t<label>Department</label>\n\t\t</div>\n\t\t<div class=\"col-xs-7 text-left value\">\n\t\t<strong>: </strong>{{doc.visit_department}}\n\t\t</div>\n          </div>\n          {%- endif -%}\n        </div>\n\n   </div>\n\n</div>\n<div>\n     <hr>\n     {% if doc.symptoms_in_print%}\n       {% if doc.symptoms %}\n         Complaints:\n         <strong>{{doc.symptoms}}</strong>\n  \t   <br>\n       {%- endif -%}\n     {%- endif -%}\n\n     {% if doc.diagnosis_in_print%}\n       {% if doc.diagnosis %}\n  \t     Diagnosis:\n         <strong>{{doc.diagnosis}}</strong>\n         <br>\n       {%- endif -%}\n     {%- endif -%}\n\n</div>\n\n<div>\n      {% if doc.drug_prescription %}\n      <br>\n      Rx,\n      <table class=\"table\">\n        <tbody>\n            <!--<tr>\n                <th>Drug</th>\n                <th class=\"text-left\">Dosage</th>\n                <th class=\"text-left\">Period</th>\n                <th>Remark</th>\n            </tr>-->\n\n            {%- for row in doc.drug_prescription -%}\n            <tr>\n              <td style=\"width: 30%;border:none;\">\n                {%- if row.drug_name -%}<b>{{ row.drug_name }}</b>{%- endif -%}\n              </td>\n            \t<td style=\"width: 20%;text-align: left;border:none;\">\n                {%- if row.dosage -%}{{ row.dosage }}{%- endif -%}\n              </td>\n            \t<td style=\"width: 20%;text-align: left;border:none;\">\n                {%- if row.period -%}{{ row.period }}{%- endif -%}\n\t\t          </td>\n              <td style=\"width: 30%;text-align: left;border:none;\">\n\t\t\t             <div style=\"border: 0px;\">\n                      {%- if row.comment -%}{{ row.comment }}{%- endif -%}\n                   </div>\n\t\t           </td>\n            </tr>\n\t          {%- endfor -%}\n       </tbody>\n      </table>\n\n\n      {%- endif -%}\n</div>\n\n\n<div>\n      {% if doc.lab_test_prescription %}\n      Investigations,\n      <table class=\"table\">\n        <tbody>\n            <!--<tr>\n                <th>Test</th>\n                <th>Remark</th>\n            </tr>-->\n\n            {%- for row in doc.lab_test_prescription -%}\n            <tr>\n              <td style=\"width: 30%;border:none;\">\n                {%- if row.lab_test_name -%}<b>{{ row.lab_test_name }}</b>{%- endif -%}\n              </td>\n              <td style=\"width: 30%;text-align: left;border:none;\">\n\t\t\t           <div style=\"border: 0px;\">\n                   {%- if row.lab_test_comment -%}{{ row.lab_test_comment }}{%- endif -%}\n                 </div>\n\t\t          </td>\n             </tr>\n\n\t           {%- endfor -%}\n       </tbody>\n      </table>\n\n\n      {%- endif -%}\n</div>\n<div>\n    {% if doc.encounter_comment %}\n      <br>\n      {{doc.encounter_comment}}\n     {%- endif -%}\n</div>\n",
- "idx": 0,
- "line_breaks": 0,
- "modified": "2018-09-04 11:52:54.473702",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Encounter Print",
- "owner": "Administrator",
- "print_format_builder": 0,
- "print_format_type": "Jinja",
- "show_section_headings": 0,
- "standard": "Yes"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/print_format/lab_test_print/__init__.py b/erpnext/healthcare/print_format/lab_test_print/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/print_format/lab_test_print/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json b/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json
deleted file mode 100644
index f7d1676..0000000
--- a/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "align_labels_right": 0,
- "creation": "2017-04-24 15:38:45.332473",
- "custom_format": 1,
- "disabled": 0,
- "doc_type": "Lab Test",
- "docstatus": 0,
- "doctype": "Print Format",
- "font": "Default",
- "html": "<div >\n  {% if letter_head and not no_letterhead -%}\n    <div class=\"letter-head\">{{ letter_head }}</div>\n    <hr>\n  {%- endif %}\n\n  {% if (doc.docstatus != 1) %}\n  <div><h2 class=\"text-uppercase text-center\"><b>WORKSHEET</b></h2></div>\n\t<br/>\n\t<div class=\"row section-break\">\n    <div class=\"col-xs-6 column-break\">\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Patient</label>\n        </div>\n        {% if doc.patient_name %}\n        <div class=\"col-xs-7  value\">\n          {{ doc.patient_name }}\n        </div>\n        {% else %}\n        <div class=\"col-xs-7  value\">\n          {{ doc.patient }}\n        </div>\n        {%- endif -%}\n      </div>\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Age</label>\n        </div>\n        <div class=\"col-xs-7  value\">\n          {{ doc.patient_age or '' }}\n        </div>\n      </div>\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Gender</label>\n        </div>\n        <div class=\"col-xs-7  value\">\n          {{ doc.patient_sex or '' }}\n        </div>\n      </div>\n\n    </div>\n\n    <div class=\"col-xs-6 column-break\">\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Practitioner</label>\n        </div>\n        {% if doc.practitioner_name %}\n        <div class=\"col-xs-7  text-left value\">\n          {{ doc.practitioner_name }}\n        </div>\n        {% else %}\n\t\t\t{% if doc.referring_practitioner_name %}\n            <div class=\"col-xs-7  text-left value\">\n            {{ doc.referring_practitioner_name }}\n            </div>\n\t\t    {% endif %}\n        {%- endif -%}\n      </div>\n\n      {% if doc.sample_date %}\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Sample Date</label>\n        </div>\n        <div class=\"col-xs-7 text-left value\">\n        {{ doc.sample_date }}\n        </div>\n      </div>\n      {%- endif -%}\n    </div>\n  </div>\n\n\t<div>\n    <hr><h4 class=\"text-uppercase text-center\"><b><u>Department of {{ doc.department }}</u></b></h4>\n  </div>\n\n\t<table class=\"table\">\n    <tbody>\n      {%- if doc.normal_test_items -%}\n      <tr>\n        <th>Name of Test</th>\n        <th class=\"text-left\">Result</th>\n        <th class=\"text-right\">Normal Range</th>\n      </tr>\n\n      {%- if doc.normal_test_items|length > 1 %}\n      <tr><td style=\"width: 40%;\"> <b>{{ doc.lab_test_name }}</b> </td><td></td></tr>\n      {%- endif -%}\n\n      {%- for row in doc.normal_test_items -%}\n      <tr>\n        <td style=\"width: 40%;border:none;\">\n          {%- if doc.normal_test_items|length > 1 %}&emsp;&emsp;{%- endif -%}\n          {%- if row.lab_test_name -%}<b>{{ row.lab_test_name }}</b>\n          {%- else -%}&emsp;&emsp;&emsp;{%- endif -%}\n          {%- if row.lab_test_event -%} &emsp;&emsp;{{ row.lab_test_event }}{%- endif -%}\n        </td>\n\n        <td style=\"width: 20%;text-align: right;border:none;\">\n          {%- if row.lab_test_uom -%}&nbsp;{{ row.lab_test_uom }}{%- endif -%}\n        </td>\n\n        <td style=\"width: 30%;text-align: right;border:none;\">\n          <div style=\"border: 0px;\">\n            {%- if row.normal_range -%}{{ row.normal_range }}{%- endif -%}\n          </div>\n        </td>\n      </tr>\n\n      {%- endfor -%}\n      {%- endif -%}\n    </tbody>\n  </table>\n\n\t<table class=\"table\">\n    <tbody>\n      {%- if doc.descriptive_test_items -%}\n      <tr>\n        <th>Name of Test</th>\n        <th class=\"text-left\">Result</th>\n      </tr>\n      <tr><td style=\"width: 30%;border:none;\"> <b>{{ doc.lab_test_name }}</b> </td><td></td></tr>\n\t\t\t{% set gr_lab_test_name = {'ltname': ''} %}\n      {%- for row in doc.descriptive_test_items -%}\n\t\t\t{%- if row.lab_test_name -%}\n\t\t\t{%- if row.lab_test_name != gr_lab_test_name.ltname -%}\n\t\t\t<tr>\n\t\t\t\t<td style=\"width: 30%;border:none;\"> &emsp;{{ row.lab_test_name }} </td>\n\t\t\t\t<td style=\"width: 70%;text-align: left;border:none;\"></td>\n\t\t\t</tr>\n\t\t\t{% if gr_lab_test_name.update({'ltname': row.lab_test_name}) %} {% endif %}\n\t\t\t{%- endif -%}\n\t\t\t{%- endif -%}\n      <tr>\n        <td style=\"width: 30%;border:none;\"> &emsp;&emsp;{{ row.lab_test_particulars }} </td>\n        <td style=\"width: 70%;text-align: left;border:none;\"></td>\n      </tr>\n      {%- endfor -%}\n      {%- endif -%}\n    </tbody>\n  </table>\n  <div>\n    {% if doc.worksheet_instructions %}\n    <hr>\n    <b>Instructions</b>\n    {{ doc.worksheet_instructions }}\n    {%- endif -%}\n</div>\n  {% elif (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"require_test_result_approval\") == '1' and doc.status != \"Approved\") %}\n  <b>Lab Tests have to be Approved for Print .. !</b>\n  {%- else -%}\n  <div class=\"row section-break\">\n    <div class=\"col-xs-6 column-break\">\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Patient</label>\n        </div>\n        {% if doc.patient_name %}\n        <div class=\"col-xs-7  value\">\n          {{ doc.patient_name }}\n        </div>\n        {% else %}\n        <div class=\"col-xs-7  value\">\n            {{ doc.patient }}\n        </div>\n        {%- endif -%}\n      </div>\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Age</label>\n        </div>\n        <div class=\"col-xs-7  value\">\n        {{ doc.patient_age or '' }}\n        </div>\n      </div>\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Gender</label>\n        </div>\n        <div class=\"col-xs-7  value\">\n          {{ doc.patient_sex or '' }}\n        </div>\n      </div>\n\n    </div>\n\n    <div class=\"col-xs-6 column-break\">\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Practitioner</label>\n        </div>\n        {% if doc.practitioner_name %}\n        <div class=\"col-xs-7  text-left value\">\n          {{ doc.practitioner_name }}\n        </div>\n\t\t{% else %}\n\t\t    {% if doc.referring_practitioner_name %}\n                <div class=\"col-xs-7  text-left value\">\n                {{ doc.referring_practitioner_name }}\n                </div>\n\t\t\t{% endif %}\n        {%- endif -%}\n      </div>\n\n      {% if doc.sample_date %}\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Sample Date</label>\n        </div>\n        <div class=\"col-xs-7 text-left value\">\n          {{ doc.sample_date }}\n        </div>\n      </div>\n      {%- endif -%}\n\n      {% if doc.result_date %}\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Result Date</label>\n        </div>\n        <div class=\"col-xs-7 text-left value\">\n          {{ doc.result_date }}\n        </div>\n      </div>\n      {%- endif -%}\n\n    </div>\n\n  </div>\n\n  <div>\n    <hr><h4 class=\"text-uppercase text-center\"><b><u>Department of {{ doc.department }}</u></b></h4>\n  </div>\n\n\t<div>\n\t\t{% if doc.result_legend and  (doc.legend_print_position == \"Top\" or doc.legend_print_position == \"Both\")%}\n\t\t<b>Result Legend:</b>\n\t\t{{ doc.result_legend }}\n\t\t{%- endif -%}\n\t</div>\n\n  <table class=\"table\">\n    <tbody>\n      {%- if doc.normal_test_items -%}\n      <tr>\n        <th>Name of Test</th>\n        <th class=\"text-left\">Result</th>\n        <th class=\"text-right\">Normal Range</th>\n      </tr>\n\n      {%- if doc.normal_test_items|length > 1 %}\n      <tr><td style=\"width: 40%;\"> <b>{{ doc.lab_test_name }}</b> </td><td></td></tr>\n      {%- endif -%}\n\n      {%- for row in doc.normal_test_items -%}\n      <tr>\n        <td style=\"width: 40%;border:none;\">\n          {%- if doc.normal_test_items|length > 1 %}&emsp;&emsp;{%- endif -%}\n          {%- if row.lab_test_name -%}<b>{{ row.lab_test_name }}</b>\n          {%- else -%}&emsp;&emsp;&emsp;{%- endif -%}\n          {%- if row.lab_test_event -%} &emsp;&emsp;{{ row.lab_test_event }}{%- endif -%}\n        </td>\n\n        <td style=\"width: 20%;text-align: left;border:none;\">\n\t\t\t\t\t{%- if row.result_value -%}\n\t\t\t\t\t\t{%- if row.bold -%}<b>{% endif %}\n\t\t\t\t\t\t{%- if row.underline -%}<u>{% endif %}\n\t\t\t\t\t\t{%- if row.italic -%}<i>{% endif %}\n                        {{ row.result_value }}\n                        {%- if row.lab_test_uom -%}&emsp;{{ row.lab_test_uom }}{%- endif -%}\n\t\t\t\t\t\t{%- if row.italic -%}</i>{% endif %}\n\t\t\t\t\t\t{%- if row.underline -%}</u>{% endif %}\n\t\t\t\t\t\t{%- if row.bold -%}</b>{% endif %}\n\t\t\t\t\t{%- endif -%}\n          \n\t\t\t\t\t{%- if row.secondary_uom and row.conversion_factor and row.secondary_uom_result -%}\n\t\t\t\t\t\t<br/>\n\t\t\t\t\t\t{%- if row.bold -%}<b>{% endif %}\n\t\t\t\t\t\t{%- if row.underline -%}<u>{% endif %}\n\t\t\t\t\t\t{%- if row.italic -%}<i>{% endif %}\n                        {{ row.secondary_uom_result }}\n                        &emsp;{{ row.secondary_uom }}\n\t\t\t\t\t\t{%- if row.italic -%}</i>{% endif %}\n\t\t\t\t\t\t{%- if row.underline -%}</u>{% endif %}\n\t\t\t\t\t\t{%- if row.bold -%}</b>{% endif %}\n\t\t\t\t\t\t&emsp;\n\t\t\t\t\t{%- endif -%}\n        </td>\n\n        <td style=\"width: 30%;text-align: right;border:none;\">\n          <div style=\"border: 0px;\">\n            {%- if row.normal_range -%}{{ row.normal_range }}{%- endif -%}\n          </div>\n        </td>\n      </tr>\n\n      {%- endfor -%}\n      {%- endif -%}\n    </tbody>\n  </table>\n\n  <table class=\"table\">\n    <tbody>\n      {%- if doc.descriptive_test_items -%}\n      <tr>\n        <th>Name of Test</th>\n        <th class=\"text-left\">Result</th>\n      </tr>\n      <tr><td style=\"width: 30%;border:none;\"> <b>{{ doc.lab_test_name }}</b> </td><td></td></tr>\n\t\t\t{% set gr_lab_test_name = {'ltname': ''} %}\n      {%- for row in doc.descriptive_test_items -%}\n\t\t\t{%- if row.lab_test_name -%}\n\t\t\t{%- if row.lab_test_name != gr_lab_test_name.ltname -%}\n\t\t\t<tr>\n\t\t\t\t<td style=\"width: 30%;border:none;\"> &emsp;{{ row.lab_test_name }} </td>\n\t\t\t\t<td style=\"width: 70%;text-align: left;border:none;\"></td>\n\t\t\t</tr>\n\t\t\t{% if gr_lab_test_name.update({'ltname': row.lab_test_name}) %} {% endif %}\n\t\t\t{%- endif -%}\n\t\t\t{%- endif -%}\n      <tr>\n        <td style=\"width: 30%;border:none;\"> &emsp;&emsp;{{ row.lab_test_particulars }} </td>\n        <td style=\"width: 70%;text-align: left;border:none;\">\n          {%- if row.result_value -%}{{ row.result_value }}{%- endif -%}\n        </td>\n      </tr>\n      {%- endfor -%}\n      {%- endif -%}\n\n\t\t\t{%- if doc.organisms -%}\n\t\t\t<tr>\n\t\t\t\t<th>Organism</th>\n\t\t\t\t<th class=\"text-left\">Colony Population</th>\n\t\t\t</tr>\n\t\t\t{%- for row in doc.organisms -%}\n\t\t\t<tr>\n\t\t\t\t<td style=\"width: 30%;border:none;\"> {{ row.organism }} </td>\n\t\t\t\t<td style=\"width: 60%;text-align: left;border:none;\">\n\t\t\t\t\t{{ row.colony_population }}\n\t\t\t\t\t{% if row.colony_uom %}\n\t\t\t\t\t\t{{ row.colony_uom }}\n\t\t\t\t\t{% endif %}\n\t\t\t\t</td>\n\t\t\t</tr>\n\t\t\t{%- endfor -%}\n\t\t\t{%- endif -%}\n\n\t\t\t{%- if doc.sensitivity_test_items -%}\n\t\t\t<tr>\n\t\t\t\t<th>Antibiotic</th>\n\t\t\t\t<th class=\"text-left\">Sensitivity</th>\n\t\t\t</tr>\n\t\t\t{%- for row in doc.sensitivity_test_items -%}\n\t\t\t<tr>\n\t\t\t\t<td style=\"width: 30%;border:none;\"> {{ row.antibiotic }} </td>\n\t\t\t\t<td style=\"width: 70%;text-align: left;border:none;\">{{ row.antibiotic_sensitivity }}</td>\n\t\t\t</tr>\n\t\t\t{%- endfor -%}\n\t\t\t{%- endif -%}\n\n    </tbody>\n  </table>\n  <div>\n    {% if doc.custom_result %}\n        <br/>\n        <div> {{ doc.custom_result }} </div>\n    {%- endif -%}\n    </div>\n\n    <div>\n        {% if doc.lab_test_comment %}\n        <br/>\n        <b>Comments</b>\n        {{ doc.lab_test_comment }}\n        {%- endif -%}\n    </div>\n\n    <div class=\"text-right\">\n        {%- if (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"employee_name_and_designation_in_print\") == '1') -%}\n            {%- if doc.employee_name -%}\n            <h6 class=\"text-uppercase\"><b>{{ doc.employee_name }}</b></h6>\n            {%- endif -%}\n            {%- if doc.employee_designation -%}\n            <h6 class=\"text-uppercase\"><b>{{ doc.employee_designation }}</b></h6>\n            {%- endif -%}\n        {%- else -%}\n            {%- if frappe.db.get_value(\"Healthcare Settings\", \"None\", \"custom_signature_in_print\") -%}\n            <h6 ><b>{{ frappe.db.get_value(\"Healthcare Settings\", \"None\", \"custom_signature_in_print\") }}</b></h6>\n            {%- endif -%}\n        {%- endif -%}\n    </div>\n\n    <div>\n        {% if doc.result_legend and  (doc.legend_print_position == \"Bottom\" or doc.legend_print_position == \"Both\" or doc.legend_print_position == \"\")%}\n        <hr>\n        <b>Result Legend</b>\n        {{ doc.result_legend }}\n        {%- endif -%}\n    </div>\n  {%- endif -%}\n</div>",
- "idx": 0,
- "line_breaks": 0,
- "modified": "2020-07-08 15:34:28.866798",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Lab Test Print",
- "owner": "Administrator",
- "print_format_builder": 0,
- "print_format_type": "Jinja",
- "raw_printing": 0,
- "show_section_headings": 0,
- "standard": "Yes"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/print_format/sample_id_print/__init__.py b/erpnext/healthcare/print_format/sample_id_print/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/print_format/sample_id_print/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/print_format/sample_id_print/sample_id_print.json b/erpnext/healthcare/print_format/sample_id_print/sample_id_print.json
deleted file mode 100644
index 4819e6d..0000000
--- a/erpnext/healthcare/print_format/sample_id_print/sample_id_print.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "align_labels_left": 0,
- "creation": "2017-02-17 17:40:52.967840",
- "custom_format": 1,
- "disabled": 0,
- "doc_type": "Sample Collection",
- "docstatus": 0,
- "doctype": "Print Format",
- "font": "Default",
- "html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 170%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 6in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 2in;\n\t\t}\n\t}\n</style>\n{% set column = 0 %}\n<table>\n{% for _ in range(0, doc.num_print) %}\n{% if column == 0 -%}<tr>{% endif %}\n\t<td style=\"width: 2in; height: 1.8in;\">{{doc.name}}<br>{{doc.patient}}<br>\n{% if doc.patient_age %}{{doc.patient_age}}, {% endif %} {% if doc.patient_sex %}{{doc.patient_sex}}{% endif %}<br> {% if doc.collected_time %}{{doc.collected_time}} {% endif %}<br>{% if doc.collected_by %} {{doc.collected_by}} {% endif %}</td>\n{% if column == 0 %}{% set column = column+1 %}\n{% elif column == 2%} </tr>{%- set column = 0 %}\n{% else %}{%- set column = column+1 -%}{%- endif %}\n\t\n{% endfor %}\n</table>",
- "idx": 0,
- "line_breaks": 0,
- "modified": "2017-03-30 18:09:39.537609",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Sample ID Print", 
- "owner": "Administrator",
- "print_format_builder": 0,
- "print_format_type": "Jinja",
- "show_section_headings": 0,
- "standard": "Yes"
-}
diff --git a/erpnext/healthcare/report/__init__.py b/erpnext/healthcare/report/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/report/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/report/inpatient_medication_orders/__init__.py b/erpnext/healthcare/report/inpatient_medication_orders/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/report/inpatient_medication_orders/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/report/inpatient_medication_orders/inpatient_medication_orders.js b/erpnext/healthcare/report/inpatient_medication_orders/inpatient_medication_orders.js
deleted file mode 100644
index a10f837..0000000
--- a/erpnext/healthcare/report/inpatient_medication_orders/inpatient_medication_orders.js
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-/* eslint-disable */
-
-frappe.query_reports["Inpatient Medication Orders"] = {
-	"filters": [
-		{
-			fieldname: "company",
-			label: __("Company"),
-			fieldtype: "Link",
-			options: "Company",
-			default: frappe.defaults.get_user_default("Company"),
-			reqd: 1
-		},
-		{
-			fieldname: "from_date",
-			label: __("From Date"),
-			fieldtype: "Date",
-			default: frappe.datetime.add_months(frappe.datetime.get_today(), -1),
-			reqd: 1
-		},
-		{
-			fieldname: "to_date",
-			label: __("To Date"),
-			fieldtype: "Date",
-			default: frappe.datetime.now_date(),
-			reqd: 1
-		},
-		{
-			fieldname: "patient",
-			label: __("Patient"),
-			fieldtype: "Link",
-			options: "Patient"
-		},
-		{
-			fieldname: "service_unit",
-			label: __("Healthcare Service Unit"),
-			fieldtype: "Link",
-			options: "Healthcare Service Unit",
-			get_query: () => {
-				var company = frappe.query_report.get_filter_value('company');
-				return {
-					filters: {
-						'company': company,
-						'is_group': 0
-					}
-				}
-			}
-		},
-		{
-			fieldname: "show_completed_orders",
-			label: __("Show Completed Orders"),
-			fieldtype: "Check",
-			default: 1
-		}
-	]
-};
diff --git a/erpnext/healthcare/report/inpatient_medication_orders/inpatient_medication_orders.json b/erpnext/healthcare/report/inpatient_medication_orders/inpatient_medication_orders.json
deleted file mode 100644
index 9217fa1..0000000
--- a/erpnext/healthcare/report/inpatient_medication_orders/inpatient_medication_orders.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "add_total_row": 0,
- "columns": [],
- "creation": "2020-11-23 17:25:58.802949",
- "disable_prepared_report": 0,
- "disabled": 0,
- "docstatus": 0,
- "doctype": "Report",
- "filters": [],
- "idx": 0,
- "is_standard": "Yes",
- "json": "{}",
- "modified": "2020-11-23 19:40:20.227591",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Inpatient Medication Orders",
- "owner": "Administrator",
- "prepared_report": 0,
- "ref_doctype": "Inpatient Medication Order",
- "report_name": "Inpatient Medication Orders",
- "report_type": "Script Report",
- "roles": [
-  {
-   "role": "System Manager"
-  },
-  {
-   "role": "Healthcare Administrator"
-  },
-  {
-   "role": "Nursing User"
-  },
-  {
-   "role": "Physician"
-  }
- ]
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/report/inpatient_medication_orders/inpatient_medication_orders.py b/erpnext/healthcare/report/inpatient_medication_orders/inpatient_medication_orders.py
deleted file mode 100644
index 2e809fb..0000000
--- a/erpnext/healthcare/report/inpatient_medication_orders/inpatient_medication_orders.py
+++ /dev/null
@@ -1,203 +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 erpnext.healthcare.doctype.inpatient_medication_entry.inpatient_medication_entry import (
-	get_current_healthcare_service_unit,
-)
-
-
-def execute(filters=None):
-	columns = get_columns()
-	data = get_data(filters)
-	chart = get_chart_data(data)
-
-	return columns, data, None, chart
-
-def get_columns():
-	return [
-		{
-			"fieldname": "patient",
-			"fieldtype": "Link",
-			"label": "Patient",
-			"options": "Patient",
-			"width": 200
-		},
-		{
-			"fieldname": "healthcare_service_unit",
-			"fieldtype": "Link",
-			"label": "Healthcare Service Unit",
-			"options": "Healthcare Service Unit",
-			"width": 150
-		},
-		{
-			"fieldname": "drug",
-			"fieldtype": "Link",
-			"label": "Drug Code",
-			"options": "Item",
-			"width": 150
-		},
-		{
-			"fieldname": "drug_name",
-			"fieldtype": "Data",
-			"label": "Drug Name",
-			"width": 150
-		},
-		{
-			"fieldname": "dosage",
-			"fieldtype": "Link",
-			"label": "Dosage",
-			"options": "Prescription Dosage",
-			"width": 80
-		},
-		{
-			"fieldname": "dosage_form",
-			"fieldtype": "Link",
-			"label": "Dosage Form",
-			"options": "Dosage Form",
-			"width": 100
-		},
-		{
-			"fieldname": "date",
-			"fieldtype": "Date",
-			"label": "Date",
-			"width": 100
-		},
-		{
-			"fieldname": "time",
-			"fieldtype": "Time",
-			"label": "Time",
-			"width": 100
-		},
-		{
-			"fieldname": "is_completed",
-			"fieldtype": "Check",
-			"label": "Is Order Completed",
-			"width": 100
-		},
-		{
-			"fieldname": "healthcare_practitioner",
-			"fieldtype": "Link",
-			"label": "Healthcare Practitioner",
-			"options": "Healthcare Practitioner",
-			"width": 200
-		},
-		{
-			"fieldname": "inpatient_medication_entry",
-			"fieldtype": "Link",
-			"label": "Inpatient Medication Entry",
-			"options": "Inpatient Medication Entry",
-			"width": 200
-		},
-		{
-			"fieldname": "inpatient_record",
-			"fieldtype": "Link",
-			"label": "Inpatient Record",
-			"options": "Inpatient Record",
-			"width": 200
-		}
-	]
-
-def get_data(filters):
-	conditions, values = get_conditions(filters)
-
-	data = frappe.db.sql("""
-		SELECT
-			parent.patient, parent.inpatient_record, parent.practitioner,
-			child.drug, child.drug_name, child.dosage, child.dosage_form,
-			child.date, child.time, child.is_completed, child.name
-		FROM `tabInpatient Medication Order` parent
-		INNER JOIN `tabInpatient Medication Order Entry` child
-		ON child.parent = parent.name
-		WHERE
-			parent.docstatus = 1
-			{conditions}
-		ORDER BY date, time
-	""".format(conditions=conditions), values, as_dict=1)
-
-	data = get_inpatient_details(data, filters.get("service_unit"))
-
-	return data
-
-def get_conditions(filters):
-	conditions = ""
-	values = dict()
-
-	if filters.get("company"):
-		conditions += " AND parent.company = %(company)s"
-		values["company"] = filters.get("company")
-
-	if filters.get("from_date") and filters.get("to_date"):
-		conditions += " AND child.date BETWEEN %(from_date)s and %(to_date)s"
-		values["from_date"] = filters.get("from_date")
-		values["to_date"] = filters.get("to_date")
-
-	if filters.get("patient"):
-		conditions += " AND parent.patient = %(patient)s"
-		values["patient"] = filters.get("patient")
-
-	if not filters.get("show_completed_orders"):
-		conditions += " AND child.is_completed = 0"
-
-	return conditions, values
-
-
-def get_inpatient_details(data, service_unit):
-	service_unit_filtered_data = []
-
-	for entry in data:
-		entry["healthcare_service_unit"] = get_current_healthcare_service_unit(entry.inpatient_record)
-		if entry.is_completed:
-			entry["inpatient_medication_entry"] = get_inpatient_medication_entry(entry.name)
-
-		if service_unit and entry.healthcare_service_unit and service_unit != entry.healthcare_service_unit:
-			service_unit_filtered_data.append(entry)
-
-		entry.pop("name", None)
-
-	for entry in service_unit_filtered_data:
-		data.remove(entry)
-
-	return data
-
-def get_inpatient_medication_entry(order_entry):
-	return frappe.db.get_value("Inpatient Medication Entry Detail", {"against_imoe": order_entry}, "parent")
-
-def get_chart_data(data):
-	if not data:
-		return None
-
-	labels = ["Pending", "Completed"]
-	datasets = []
-
-	status_wise_data = {
-		"Pending": 0,
-		"Completed": 0
-	}
-
-	for d in data:
-		if d.is_completed:
-			status_wise_data["Completed"] += 1
-		else:
-			status_wise_data["Pending"] += 1
-
-	datasets.append({
-		"name": "Inpatient Medication Order Status",
-		"values": [status_wise_data.get("Pending"), status_wise_data.get("Completed")]
-	})
-
-	chart = {
-		"data": {
-			"labels": labels,
-			"datasets": datasets
-		},
-		"type": "donut",
-		"height": 300
-	}
-
-	chart["fieldtype"] = "Data"
-
-	return chart
diff --git a/erpnext/healthcare/report/inpatient_medication_orders/test_inpatient_medication_orders.py b/erpnext/healthcare/report/inpatient_medication_orders/test_inpatient_medication_orders.py
deleted file mode 100644
index 7f7bebf..0000000
--- a/erpnext/healthcare/report/inpatient_medication_orders/test_inpatient_medication_orders.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-
-import datetime
-import unittest
-
-import frappe
-from frappe.utils import getdate, now_datetime
-
-from erpnext.healthcare.doctype.inpatient_medication_order.test_inpatient_medication_order import (
-	create_ipme,
-	create_ipmo,
-)
-from erpnext.healthcare.doctype.inpatient_record.inpatient_record import (
-	admit_patient,
-	discharge_patient,
-	schedule_discharge,
-)
-from erpnext.healthcare.doctype.inpatient_record.test_inpatient_record import (
-	create_inpatient,
-	create_patient,
-	get_healthcare_service_unit,
-	mark_invoiced_inpatient_occupancy,
-)
-from erpnext.healthcare.report.inpatient_medication_orders.inpatient_medication_orders import (
-	execute,
-)
-
-
-class TestInpatientMedicationOrders(unittest.TestCase):
-	@classmethod
-	def setUpClass(self):
-		frappe.db.sql("delete from `tabInpatient Medication Order` where company='_Test Company'")
-		frappe.db.sql("delete from `tabInpatient Medication Entry` where company='_Test Company'")
-		self.patient = create_patient()
-		self.ip_record = create_records(self.patient)
-
-	def test_inpatient_medication_orders_report(self):
-		filters = {
-			'company': '_Test Company',
-			'from_date': getdate(),
-			'to_date': getdate(),
-			'patient': '_Test IPD Patient',
-			'service_unit': '_Test Service Unit Ip Occupancy - _TC'
-		}
-
-		report = execute(filters)
-
-		expected_data = [
-			{
-				'patient': '_Test IPD Patient',
-				'inpatient_record': self.ip_record.name,
-				'practitioner': None,
-				'drug': 'Dextromethorphan',
-				'drug_name': 'Dextromethorphan',
-				'dosage': 1.0,
-				'dosage_form': 'Tablet',
-				'date': getdate(),
-				'time': datetime.timedelta(seconds=32400),
-				'is_completed': 0,
-				'healthcare_service_unit': '_Test Service Unit Ip Occupancy - _TC'
-			},
-			{
-				'patient': '_Test IPD Patient',
-				'inpatient_record': self.ip_record.name,
-				'practitioner': None,
-				'drug': 'Dextromethorphan',
-				'drug_name': 'Dextromethorphan',
-				'dosage': 1.0,
-				'dosage_form': 'Tablet',
-				'date': getdate(),
-				'time': datetime.timedelta(seconds=50400),
-				'is_completed': 0,
-				'healthcare_service_unit': '_Test Service Unit Ip Occupancy - _TC'
-			},
-			{
-				'patient': '_Test IPD Patient',
-				'inpatient_record': self.ip_record.name,
-				'practitioner': None,
-				'drug': 'Dextromethorphan',
-				'drug_name': 'Dextromethorphan',
-				'dosage': 1.0,
-				'dosage_form': 'Tablet',
-				'date': getdate(),
-				'time': datetime.timedelta(seconds=75600),
-				'is_completed': 0,
-				'healthcare_service_unit': '_Test Service Unit Ip Occupancy - _TC'
-			}
-		]
-
-		self.assertEqual(expected_data, report[1])
-
-		filters = frappe._dict(from_date=getdate(), to_date=getdate(), from_time='', to_time='')
-		ipme = create_ipme(filters)
-		ipme.submit()
-
-		filters = {
-			'company': '_Test Company',
-			'from_date': getdate(),
-			'to_date': getdate(),
-			'patient': '_Test IPD Patient',
-			'service_unit': '_Test Service Unit Ip Occupancy - _TC',
-			'show_completed_orders': 0
-		}
-
-		report = execute(filters)
-		self.assertEqual(len(report[1]), 0)
-
-	def tearDown(self):
-		if frappe.db.get_value('Patient', self.patient, 'inpatient_record'):
-			# cleanup - Discharge
-			schedule_discharge(frappe.as_json({'patient': self.patient}))
-			self.ip_record.reload()
-			mark_invoiced_inpatient_occupancy(self.ip_record)
-
-			self.ip_record.reload()
-			discharge_patient(self.ip_record)
-
-		for entry in frappe.get_all('Inpatient Medication Entry'):
-			doc = frappe.get_doc('Inpatient Medication Entry', entry.name)
-			doc.cancel()
-			doc.delete()
-
-		for entry in frappe.get_all('Inpatient Medication Order'):
-			doc = frappe.get_doc('Inpatient Medication Order', entry.name)
-			doc.cancel()
-			doc.delete()
-
-
-def create_records(patient):
-	frappe.db.sql("""delete from `tabInpatient Record`""")
-
-	# Admit
-	ip_record = create_inpatient(patient)
-	ip_record.expected_length_of_stay = 0
-	ip_record.save()
-	ip_record.reload()
-	service_unit = get_healthcare_service_unit('_Test Service Unit Ip Occupancy')
-	admit_patient(ip_record, service_unit, now_datetime())
-
-	ipmo = create_ipmo(patient)
-	ipmo.submit()
-
-	return ip_record
diff --git a/erpnext/healthcare/report/lab_test_report/__init__.py b/erpnext/healthcare/report/lab_test_report/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/report/lab_test_report/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/report/lab_test_report/lab_test_report.js b/erpnext/healthcare/report/lab_test_report/lab_test_report.js
deleted file mode 100644
index 7754e2e..0000000
--- a/erpnext/healthcare/report/lab_test_report/lab_test_report.js
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2016, ESS
-// License: See license.txt
-
-frappe.query_reports["Lab Test Report"] = {
-	"filters": [
-		{
-			"fieldname": "from_date",
-			"label": __("From Date"),
-			"fieldtype": "Date",
-			"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
-			"reqd": 1
-		},
-		{
-			"fieldname": "to_date",
-			"label": __("To Date"),
-			"fieldtype": "Date",
-			"default": frappe.datetime.now_date(),
-			"reqd": 1
-		},
-		{
-			"fieldname": "company",
-			"label": __("Company"),
-			"fieldtype": "Link",
-			"default": frappe.defaults.get_default("Company"),
-			"options": "Company"
-		},
-		{
-			"fieldname": "template",
-			"label": __("Lab Test Template"),
-			"fieldtype": "Link",
-			"options": "Lab Test Template"
-		},
-		{
-			"fieldname": "patient",
-			"label": __("Patient"),
-			"fieldtype": "Link",
-			"options": "Patient"
-		},
-		{
-			"fieldname": "department",
-			"label": __("Medical Department"),
-			"fieldtype": "Link",
-			"options": "Medical Department"
-		},
-		{
-			"fieldname": "status",
-			"label": __("Status"),
-			"fieldtype": "Select",
-			"options": "\nCompleted\nApproved\nRejected"
-		},
-		{
-			"fieldname": "invoiced",
-			"label": __("Invoiced"),
-			"fieldtype": "Check"
-		}
-	]
-};
diff --git a/erpnext/healthcare/report/lab_test_report/lab_test_report.json b/erpnext/healthcare/report/lab_test_report/lab_test_report.json
deleted file mode 100644
index aeb4289..0000000
--- a/erpnext/healthcare/report/lab_test_report/lab_test_report.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "add_total_row": 0,
- "creation": "2013-04-23 18:15:29",
- "disable_prepared_report": 0,
- "disabled": 0,
- "docstatus": 0,
- "doctype": "Report",
- "idx": 1,
- "is_standard": "Yes",
- "modified": "2020-07-30 18:53:20.102873",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Lab Test Report",
- "owner": "Administrator",
- "prepared_report": 0,
- "ref_doctype": "Lab Test",
- "report_name": "Lab Test Report",
- "report_type": "Script Report",
- "roles": [
-  {
-   "role": "Laboratory User"
-  },
-  {
-   "role": "Nursing User"
-  },
-  {
-   "role": "LabTest Approver"
-  },
-  {
-   "role": "Healthcare Administrator"
-  }
- ]
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/report/lab_test_report/lab_test_report.py b/erpnext/healthcare/report/lab_test_report/lab_test_report.py
deleted file mode 100644
index e2a53bb..0000000
--- a/erpnext/healthcare/report/lab_test_report/lab_test_report.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# Copyright (c) 2016, ESS
-# License: See license.txt
-
-from __future__ import unicode_literals
-
-import frappe
-from frappe import _, msgprint
-
-
-def execute(filters=None):
-	if not filters: filters = {}
-
-	data, columns = [], []
-
-	columns = get_columns()
-	lab_test_list = get_lab_tests(filters)
-
-	if not lab_test_list:
-		msgprint(_('No records found'))
-		return columns, lab_test_list
-
-	data = []
-	for lab_test in lab_test_list:
-		row = frappe._dict({
-				'test': lab_test.name,
-				'template': lab_test.template,
-				'company': lab_test.company,
-				'patient': lab_test.patient,
-				'patient_name': lab_test.patient_name,
-				'practitioner': lab_test.practitioner,
-				'employee': lab_test.employee,
-				'status': lab_test.status,
-				'invoiced': lab_test.invoiced,
-				'result_date': lab_test.result_date,
-				'department': lab_test.department
-			})
-		data.append(row)
-
-	chart = get_chart_data(data)
-	report_summary = get_report_summary(data)
-	return columns, data, None, chart, report_summary
-
-
-def get_columns():
-	return [
-		{
-			'fieldname': 'test',
-			'label': _('Lab Test'),
-			'fieldtype': 'Link',
-			'options': 'Lab Test',
-			'width': '120'
-		},
-		{
-			'fieldname': 'template',
-			'label': _('Lab Test Template'),
-			'fieldtype': 'Link',
-			'options': 'Lab Test Template',
-			'width': '120'
-		},
-		{
-			'fieldname': 'company',
-			'label': _('Company'),
-			'fieldtype': 'Link',
-			'options': 'Company',
-			'width': '120'
-		},
-		{
-			'fieldname': 'patient',
-			'label': _('Patient'),
-			'fieldtype': 'Link',
-			'options': 'Patient',
-			'width': '120'
-		},
-		{
-			'fieldname': 'patient_name',
-			'label': _('Patient Name'),
-			'fieldtype': 'Data',
-			'width': '120'
-		},
-		{
-			'fieldname': 'employee',
-			'label': _('Lab Technician'),
-			'fieldtype': 'Link',
-			'options': 'Employee',
-			'width': '120'
-		},
-		{
-			'fieldname': 'status',
-			'label': _('Status'),
-			'fieldtype': 'Data',
-			'width': '100'
-		},
-		{
-			'fieldname': 'invoiced',
-			'label': _('Invoiced'),
-			'fieldtype': 'Check',
-			'width': '100'
-		},
-		{
-			'fieldname': 'result_date',
-			'label': _('Result Date'),
-			'fieldtype': 'Date',
-			'width': '100'
-		},
-		{
-			'fieldname': 'practitioner',
-			'label': _('Requesting Practitioner'),
-			'fieldtype': 'Link',
-			'options': 'Healthcare Practitioner',
-			'width': '120'
-		},
-		{
-			'fieldname': 'department',
-			'label': _('Medical Department'),
-			'fieldtype': 'Link',
-			'options': 'Medical Department',
-			'width': '100'
-		}
-	]
-
-def get_lab_tests(filters):
-	conditions = get_conditions(filters)
-	data = frappe.get_all(
-		doctype='Lab Test',
-		fields=['name', 'template', 'company', 'patient', 'patient_name', 'practitioner', 'employee', 'status', 'invoiced', 'result_date', 'department'],
-		filters=conditions,
-		order_by='submitted_date desc'
-	)
-	return data
-
-def get_conditions(filters):
-	conditions = {
-		'docstatus': ('=', 1)
-	}
-
-	if filters.get('from_date') and filters.get('to_date'):
-		conditions['result_date'] = ('between', (filters.get('from_date'), filters.get('to_date')))
-		filters.pop('from_date')
-		filters.pop('to_date')
-
-	for key, value in filters.items():
-		if filters.get(key):
-			conditions[key] = value
-
-	return conditions
-
-def get_chart_data(data):
-	if not data:
-		return None
-
-	labels = ['Completed', 'Approved', 'Rejected']
-
-	status_wise_data = {
-		'Completed': 0,
-		'Approved': 0,
-		'Rejected': 0
-	}
-
-	datasets = []
-
-	for entry in data:
-		status_wise_data[entry.status] += 1
-
-	datasets.append({
-		'name': 'Lab Test Status',
-		'values': [status_wise_data.get('Completed'), status_wise_data.get('Approved'), status_wise_data.get('Rejected')]
-	})
-
-	chart = {
-		'data': {
-			'labels': labels,
-			'datasets': datasets
-		},
-		'type': 'bar',
-		'height': 300,
-	}
-
-	return chart
-
-
-def get_report_summary(data):
-	if not data:
-		return None
-
-	total_lab_tests = len(data)
-	invoiced_lab_tests, unbilled_lab_tests = 0, 0
-
-	for entry in data:
-		if entry.invoiced:
-			invoiced_lab_tests += 1
-		else:
-			unbilled_lab_tests += 1
-
-	return [
-		{
-			'value': total_lab_tests,
-			'indicator': 'Blue',
-			'label': 'Total Lab Tests',
-			'datatype': 'Int',
-		},
-		{
-			'value': invoiced_lab_tests,
-			'indicator': 'Green',
-			'label': 'Invoiced Lab Tests',
-			'datatype': 'Int',
-		},
-		{
-			'value': unbilled_lab_tests,
-			'indicator': 'Red',
-			'label': 'Unbilled Lab Tests',
-			'datatype': 'Int',
-		}
-	]
diff --git a/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.js b/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.js
deleted file mode 100644
index 18d252e..0000000
--- a/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.js
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-/* eslint-disable */
-
-frappe.query_reports['Patient Appointment Analytics'] = {
-	"filters": [
-		{
-			fieldname: 'tree_type',
-			label: __('Tree Type'),
-			fieldtype: 'Select',
-			options: ['Healthcare Practitioner', 'Medical Department'],
-			default: 'Healthcare Practitioner',
-			reqd: 1
-		},
-		{
-			fieldname: 'status',
-			label: __('Appointment Status'),
-			fieldtype: 'Select',
-			options:[
-				{label: __('Scheduled'), value: 'Scheduled'},
-				{label: __('Open'), value: 'Open'},
-				{label: __('Closed'), value: 'Closed'},
-				{label: __('Expired'), value: 'Expired'},
-				{label: __('Cancelled'), value: 'Cancelled'}
-			]
-		},
-		{
-			fieldname: 'appointment_type',
-			label: __('Appointment Type'),
-			fieldtype: 'Link',
-			options: 'Appointment Type'
-		},
-		{
-			fieldname: 'practitioner',
-			label: __('Healthcare Practitioner'),
-			fieldtype: 'Link',
-			options: 'Healthcare Practitioner'
-		},
-		{
-			fieldname: 'department',
-			label: __('Medical Department'),
-			fieldtype: 'Link',
-			options: 'Medical Department'
-		},
-		{
-			fieldname: 'from_date',
-			label: __('From Date'),
-			fieldtype: 'Date',
-			default: frappe.defaults.get_user_default('year_start_date'),
-			reqd: 1
-		},
-		{
-			fieldname: 'to_date',
-			label: __('To Date'),
-			fieldtype: 'Date',
-			default: frappe.defaults.get_user_default('year_end_date'),
-			reqd: 1
-		},
-		{
-			fieldname: 'range',
-			label: __('Range'),
-			fieldtype: 'Select',
-			options:[
-				{label: __('Weekly'), value: 'Weekly'},
-				{label: __('Monthly'), value: 'Monthly'},
-				{label: __('Quarterly'), value: 'Quarterly'},
-				{label: __('Yearly'), value: 'Yearly'}
-			],
-			default: 'Monthly',
-			reqd: 1
-		}
-	],
-	after_datatable_render: function(datatable_obj) {
-		$(datatable_obj.wrapper).find(".dt-row-0").find('input[type=checkbox]').click();
-	},
-	get_datatable_options(options) {
-		return Object.assign(options, {
-			checkboxColumn: true,
-			events: {
-				onCheckRow: function(data) {
-					row_name = data[2].content;
-					length = data.length;
-
-					row_values = data.slice(3,length-1).map(function (column) {
-						return column.content;
-					})
-
-					entry = {
-						'name': row_name,
-						'values': row_values
-					}
-
-					let raw_data = frappe.query_report.chart.data;
-					let new_datasets = raw_data.datasets;
-
-					let found = false;
-					for (let i=0; i < new_datasets.length;i++) {
-						if (new_datasets[i].name == row_name) {
-							found = true;
-							new_datasets.splice(i,1);
-							break;
-						}
-					}
-
-					if (!found) {
-						new_datasets.push(entry);
-					}
-
-					let new_data = {
-						labels: raw_data.labels,
-						datasets: new_datasets
-					}
-
-					setTimeout(() => {
-						frappe.query_report.chart.update(new_data)
-					}, 500)
-
-
-					setTimeout(() => {
-						frappe.query_report.chart.draw(true);
-					}, 1000)
-
-					frappe.query_report.raw_chart_data = new_data;
-				},
-			}
-		})
-	},
-};
diff --git a/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.json b/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.json
deleted file mode 100644
index 64750c0..0000000
--- a/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "add_total_row": 1,
- "creation": "2020-03-02 15:13:16.273493",
- "disable_prepared_report": 0,
- "disabled": 0,
- "docstatus": 0,
- "doctype": "Report",
- "idx": 0,
- "is_standard": "Yes",
- "modified": "2020-03-02 15:13:16.273493",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Appointment Analytics",
- "owner": "Administrator",
- "prepared_report": 0,
- "ref_doctype": "Patient Appointment",
- "report_name": "Patient Appointment Analytics",
- "report_type": "Script Report",
- "roles": [
-  {
-   "role": "Healthcare Administrator"
-  },
-  {
-   "role": "LabTest Approver"
-  },
-  {
-   "role": "Physician"
-  },
-  {
-   "role": "Nursing User"
-  },
-  {
-   "role": "Laboratory User"
-  }
- ]
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.py b/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.py
deleted file mode 100644
index 1afb5da..0000000
--- a/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.py
+++ /dev/null
@@ -1,197 +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 _, scrub
-from frappe.utils import add_days, add_to_date, flt, getdate
-from six import iteritems
-
-from erpnext.accounts.utils import get_fiscal_year
-
-
-def execute(filters=None):
-	return Analytics(filters).run()
-
-class Analytics(object):
-	def __init__(self, filters=None):
-		"""Patient Appointment Analytics Report."""
-		self.filters = frappe._dict(filters or {})
-		self.months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
-		self.get_period_date_ranges()
-
-	def run(self):
-		self.get_columns()
-		self.get_data()
-		self.get_chart_data()
-
-		return self.columns, self.data, None, self.chart
-
-	def get_period_date_ranges(self):
-		from dateutil.relativedelta import MO, relativedelta
-		from_date, to_date = getdate(self.filters.from_date), getdate(self.filters.to_date)
-
-		increment = {
-			'Monthly': 1,
-			'Quarterly': 3,
-			'Half-Yearly': 6,
-			'Yearly': 12
-		}.get(self.filters.range, 1)
-
-		if self.filters.range in ['Monthly', 'Quarterly']:
-			from_date = from_date.replace(day=1)
-		elif self.filters.range == 'Yearly':
-			from_date = get_fiscal_year(from_date)[1]
-		else:
-			from_date = from_date + relativedelta(from_date, weekday=MO(-1))
-
-		self.periodic_daterange = []
-		for dummy in range(1, 53):
-			if self.filters.range == 'Weekly':
-				period_end_date = add_days(from_date, 6)
-			else:
-				period_end_date = add_to_date(from_date, months=increment, days=-1)
-
-			if period_end_date > to_date:
-				period_end_date = to_date
-
-			self.periodic_daterange.append(period_end_date)
-
-			from_date = add_days(period_end_date, 1)
-			if period_end_date == to_date:
-				break
-
-	def get_columns(self):
-		self.columns = []
-
-		if self.filters.tree_type == 'Healthcare Practitioner':
-			self.columns.append({
-				'label': _('Healthcare Practitioner'),
-				'options': 'Healthcare Practitioner',
-				'fieldname': 'practitioner',
-				'fieldtype': 'Link',
-				'width': 200
-			})
-
-		elif self.filters.tree_type == 'Medical Department':
-			self.columns.append({
-				'label': _('Medical Department'),
-				'fieldname': 'department',
-				'fieldtype': 'Link',
-				'options': 'Medical Department',
-				'width': 150
-			})
-
-		for end_date in self.periodic_daterange:
-			period = self.get_period(end_date)
-			self.columns.append({
-				'label': _(period),
-				'fieldname': scrub(period),
-				'fieldtype': 'Int',
-				'width': 120
-			})
-
-		self.columns.append({
-			'label': _('Total'),
-			'fieldname': 'total',
-			'fieldtype': 'Int',
-			'width': 120
-		})
-
-	def get_data(self):
-		if self.filters.tree_type == 'Healthcare Practitioner':
-			self.get_appointments_based_on_healthcare_practitioner()
-			self.get_rows()
-
-		elif self.filters.tree_type == 'Medical Department':
-			self.get_appointments_based_on_medical_department()
-			self.get_rows()
-
-	def get_period(self, appointment_date):
-		if self.filters.range == 'Weekly':
-			period = 'Week ' + str(appointment_date.isocalendar()[1])
-		elif self.filters.range == 'Monthly':
-			period = str(self.months[appointment_date.month - 1])
-		elif self.filters.range == 'Quarterly':
-			period = 'Quarter ' + str(((appointment_date.month - 1) // 3) + 1)
-		else:
-			year = get_fiscal_year(appointment_date, company=self.filters.company)
-			period = str(year[0])
-
-		if getdate(self.filters.from_date).year != getdate(self.filters.to_date).year:
-			period += ' ' + str(appointment_date.year)
-
-		return period
-
-	def get_appointments_based_on_healthcare_practitioner(self):
-		filters = self.get_common_filters()
-
-		self.entries = frappe.db.get_all('Patient Appointment',
-			fields=['appointment_date', 'name', 'patient', 'practitioner'],
-			filters=filters
-		)
-
-	def get_appointments_based_on_medical_department(self):
-		filters = self.get_common_filters()
-		if not filters.get('department'):
-			filters['department'] = ('!=', '')
-
-		self.entries = frappe.db.get_all('Patient Appointment',
-			fields=['appointment_date', 'name', 'patient', 'practitioner', 'department'],
-			filters=filters
-		)
-
-	def get_common_filters(self):
-		filters = {}
-		filters['appointment_date'] = ('between', [self.filters.from_date, self.filters.to_date])
-		for entry in ['appointment_type', 'practitioner', 'department', 'status']:
-			if self.filters.get(entry):
-				filters[entry] = self.filters.get(entry)
-
-		return filters
-
-	def get_rows(self):
-		self.data = []
-		self.get_periodic_data()
-
-		for entity, period_data in iteritems(self.appointment_periodic_data):
-			if self.filters.tree_type == 'Healthcare Practitioner':
-				row = {'practitioner': entity}
-			elif self.filters.tree_type == 'Medical Department':
-				row = {'department': entity}
-
-			total = 0
-			for end_date in self.periodic_daterange:
-				period = self.get_period(end_date)
-				amount = flt(period_data.get(period, 0.0))
-				row[scrub(period)] = amount
-				total += amount
-
-			row['total'] = total
-
-			self.data.append(row)
-
-	def get_periodic_data(self):
-		self.appointment_periodic_data = frappe._dict()
-
-		for d in self.entries:
-			period = self.get_period(d.get('appointment_date'))
-			if self.filters.tree_type == 'Healthcare Practitioner':
-				self.appointment_periodic_data.setdefault(d.practitioner, frappe._dict()).setdefault(period, 0.0)
-				self.appointment_periodic_data[d.practitioner][period] += 1
-
-			elif self.filters.tree_type == 'Medical Department':
-				self.appointment_periodic_data.setdefault(d.department, frappe._dict()).setdefault(period, 0.0)
-				self.appointment_periodic_data[d.department][period] += 1
-
-	def get_chart_data(self):
-		length = len(self.columns)
-		labels = [d.get("label") for d in self.columns[1:length - 1]]
-		self.chart = {
-			"data": {
-				'labels': labels,
-				'datasets': []
-			},
-			"type": "line"
-		}
diff --git a/erpnext/healthcare/setup.py b/erpnext/healthcare/setup.py
deleted file mode 100644
index 891272d..0000000
--- a/erpnext/healthcare/setup.py
+++ /dev/null
@@ -1,295 +0,0 @@
-from __future__ import unicode_literals
-import frappe
-
-from frappe import _
-from erpnext.setup.utils import insert_record
-
-def setup_healthcare():
-	if frappe.db.exists('Medical Department', 'Cardiology'):
-		# already setup
-		return
-	create_medical_departments()
-	create_antibiotics()
-	create_lab_test_uom()
-	create_duration()
-	create_dosage()
-	create_healthcare_item_groups()
-	create_sensitivity()
-	add_healthcare_service_unit_tree_root()
-	setup_patient_history_settings()
-
-def create_medical_departments():
-	departments = [
-		"Accident And Emergency Care" ,"Anaesthetics", "Biochemistry", "Cardiology", "Dermatology",
-		"Diagnostic Imaging", "ENT", "Gastroenterology", "General Surgery", "Gynaecology",
-		"Haematology", "Maternity", "Microbiology", "Nephrology", "Neurology", "Oncology",
-		"Orthopaedics", "Pathology", "Physiotherapy", "Rheumatology", "Serology", "Urology"
-	]
-	for department in departments:
-		mediacal_department = frappe.new_doc("Medical Department")
-		mediacal_department.department = _(department)
-		try:
-			mediacal_department.save()
-		except frappe.DuplicateEntryError:
-			pass
-
-def create_antibiotics():
-	abt = [
-		"Amoxicillin", "Ampicillin", "Bacampicillin", "Carbenicillin", "Cloxacillin", "Dicloxacillin",
-		"Flucloxacillin", "Mezlocillin", "Nafcillin", "Oxacillin", "Penicillin G", "Penicillin V",
-		"Piperacillin", "Pivampicillin", "Pivmecillinam", "Ticarcillin", "Cefacetrile (cephacetrile)",
-		"Cefadroxil (cefadroxyl)", "Cefalexin (cephalexin)", "Cefaloglycin (cephaloglycin)",
-		"Cefalonium (cephalonium)", "Cefaloridine (cephaloradine)", "Cefalotin (cephalothin)",
-		"Cefapirin (cephapirin)", "Cefatrizine", "Cefazaflur", "Cefazedone", "Cefazolin (cephazolin)",
-		"Cefradine (cephradine)", "Cefroxadine", "Ceftezole", "Cefaclor", "Cefamandole", "Cefmetazole",
-		"Cefonicid", "Cefotetan", "Cefoxitin", "Cefprozil (cefproxil)", "Cefuroxime", "Cefuzonam",
-		"Cefcapene", "Cefdaloxime", "Cefdinir", "Cefditoren", "Cefetamet", "Cefixime", "Cefmenoxime",
-		"Cefodizime", "Cefotaxime", "Cefpimizole", "Cefpodoxime", "Cefteram", "Ceftibuten", "Ceftiofur",
-		"Ceftiolene", "Ceftizoxime", "Ceftriaxone", "Cefoperazone", "Ceftazidime", "Cefclidine", "Cefepime",
-		"Cefluprenam", "Cefoselis", "Cefozopran", "Cefpirome", "Cefquinome", "Ceftobiprole", "Ceftaroline",
-		"Cefaclomezine","Cefaloram", "Cefaparole", "Cefcanel", "Cefedrolor", "Cefempidone", "Cefetrizole",
-		"Cefivitril", "Cefmatilen", "Cefmepidium", "Cefovecin", "Cefoxazole", "Cefrotil", "Cefsumide",
-		"Cefuracetime", "Ceftioxide", "Ceftazidime/Avibactam", "Ceftolozane/Tazobactam", "Aztreonam",
-		"Imipenem", "Imipenem/cilastatin", "Doripenem", "Meropenem", "Ertapenem", "Azithromycin",
-		"Erythromycin", "Clarithromycin", "Dirithromycin", "Roxithromycin", "Telithromycin", "Clindamycin",
-		"Lincomycin", "Pristinamycin", "Quinupristin/dalfopristin", "Amikacin", "Gentamicin", "Kanamycin",
-		"Neomycin", "Netilmicin", "Paromomycin", "Streptomycin", "Tobramycin", "Flumequine", "Nalidixic acid",
-		"Oxolinic acid", "Piromidic acid", "Pipemidic acid", "Rosoxacin", "Ciprofloxacin", "Enoxacin",
-		"Lomefloxacin", "Nadifloxacin", "Norfloxacin", "Ofloxacin", "Pefloxacin", "Rufloxacin", "Balofloxacin",
-		"Gatifloxacin", "Grepafloxacin", "Levofloxacin", "Moxifloxacin", "Pazufloxacin", "Sparfloxacin",
-		"Temafloxacin", "Tosufloxacin", "Besifloxacin", "Clinafloxacin", "Gemifloxacin",
-		"Sitafloxacin", "Trovafloxacin", "Prulifloxacin", "Sulfamethizole", "Sulfamethoxazole",
-		"Sulfisoxazole", "Trimethoprim-Sulfamethoxazole", "Demeclocycline", "Doxycycline", "Minocycline",
-		"Oxytetracycline", "Tetracycline", "Tigecycline", "Chloramphenicol", "Metronidazole",
-		"Tinidazole", "Nitrofurantoin", "Vancomycin", "Teicoplanin", "Telavancin", "Linezolid",
-		"Cycloserine 2", "Rifampin", "Rifabutin", "Rifapentine", "Rifalazil", "Bacitracin", "Polymyxin B",
-		"Viomycin", "Capreomycin"
-	]
-
-	for a in abt:
-		antibiotic = frappe.new_doc("Antibiotic")
-		antibiotic.antibiotic_name = a
-		try:
-			antibiotic.save()
-		except frappe.DuplicateEntryError:
-			pass
-
-def create_lab_test_uom():
-	records = [
-		{"doctype": "Lab Test UOM", "name": "umol/L", "lab_test_uom": "umol/L", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "mg/L", "lab_test_uom": "mg/L", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "mg / dl", "lab_test_uom": "mg / dl", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "pg / ml", "lab_test_uom": "pg / ml", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "U/ml", "lab_test_uom": "U/ml", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "/HPF", "lab_test_uom": "/HPF", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "Million Cells / cumm", "lab_test_uom": "Million Cells / cumm", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "Lakhs Cells / cumm", "lab_test_uom": "Lakhs Cells / cumm", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "U / L", "lab_test_uom": "U / L", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "g / L", "lab_test_uom": "g / L", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "IU / ml", "lab_test_uom": "IU / ml", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "gm %", "lab_test_uom": "gm %", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "Microgram", "lab_test_uom": "Microgram", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "Micron", "lab_test_uom": "Micron", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "Cells / cumm", "lab_test_uom": "Cells / cumm", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "%", "lab_test_uom": "%", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "mm / dl", "lab_test_uom": "mm / dl", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "mm / hr", "lab_test_uom": "mm / hr", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "ulU / ml", "lab_test_uom": "ulU / ml", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "ng / ml", "lab_test_uom": "ng / ml", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "ng / dl", "lab_test_uom": "ng / dl", "uom_description": None },
-		{"doctype": "Lab Test UOM", "name": "ug / dl", "lab_test_uom": "ug / dl", "uom_description": None }
-	]
-
-	insert_record(records)
-
-def create_duration():
-	records = [
-		{"doctype": "Prescription Duration", "name": "3 Month", "number": "3", "period": "Month" },
-		{"doctype": "Prescription Duration", "name": "2 Month", "number": "2", "period": "Month" },
-		{"doctype": "Prescription Duration", "name": "1 Month", "number": "1", "period": "Month" },
-		{"doctype": "Prescription Duration", "name": "12 Hour", "number": "12", "period": "Hour" },
-		{"doctype": "Prescription Duration", "name": "11 Hour", "number": "11", "period": "Hour" },
-		{"doctype": "Prescription Duration", "name": "10 Hour", "number": "10", "period": "Hour" },
-		{"doctype": "Prescription Duration", "name": "9 Hour", "number": "9", "period": "Hour" },
-		{"doctype": "Prescription Duration", "name": "8 Hour", "number": "8", "period": "Hour" },
-		{"doctype": "Prescription Duration", "name": "7 Hour", "number": "7", "period": "Hour" },
-		{"doctype": "Prescription Duration", "name": "6 Hour", "number": "6", "period": "Hour" },
-		{"doctype": "Prescription Duration", "name": "5 Hour", "number": "5", "period": "Hour" },
-		{"doctype": "Prescription Duration", "name": "4 Hour", "number": "4", "period": "Hour" },
-		{"doctype": "Prescription Duration", "name": "3 Hour", "number": "3", "period": "Hour" },
-		{"doctype": "Prescription Duration", "name": "2 Hour", "number": "2", "period": "Hour" },
-		{"doctype": "Prescription Duration", "name": "1 Hour", "number": "1", "period": "Hour" },
-		{"doctype": "Prescription Duration", "name": "5 Week", "number": "5", "period": "Week" },
-		{"doctype": "Prescription Duration", "name": "4 Week", "number": "4", "period": "Week" },
-		{"doctype": "Prescription Duration", "name": "3 Week", "number": "3", "period": "Week" },
-		{"doctype": "Prescription Duration", "name": "2 Week", "number": "2", "period": "Week" },
-		{"doctype": "Prescription Duration", "name": "1 Week", "number": "1", "period": "Week" },
-		{"doctype": "Prescription Duration", "name": "6 Day", "number": "6", "period": "Day" },
-		{"doctype": "Prescription Duration", "name": "5 Day", "number": "5", "period": "Day" },
-		{"doctype": "Prescription Duration", "name": "4 Day", "number": "4", "period": "Day" },
-		{"doctype": "Prescription Duration", "name": "3 Day", "number": "3", "period": "Day" },
-		{"doctype": "Prescription Duration", "name": "2 Day", "number": "2", "period": "Day" },
-		{"doctype": "Prescription Duration", "name": "1 Day", "number": "1", "period": "Day" }
-	]
-	insert_record(records)
-
-def create_dosage():
-	records = [
-		{"doctype": "Prescription Dosage", "name": "1-1-1-1", "dosage": "1-1-1-1","dosage_strength":
-		[{"strength": "1.0","strength_time": "9:00:00"}, {"strength": "1.0","strength_time": "13:00:00"},{"strength": "1.0","strength_time": "17:00:00"},{"strength": "1.0","strength_time": "21:00:00"}]
-		},
-		{"doctype": "Prescription Dosage", "name": "0-0-1", "dosage": "0-0-1","dosage_strength":
-		[{"strength": "1.0","strength_time": "21:00:00"}]
-		},
-		{"doctype": "Prescription Dosage", "name": "1-0-0", "dosage": "1-0-0","dosage_strength":
-		[{"strength": "1.0","strength_time": "9:00:00"}]
-		},
-		{"doctype": "Prescription Dosage", "name": "0-1-0", "dosage": "0-1-0","dosage_strength":
-		[{"strength": "1.0","strength_time": "14:00:00"}]
-		},
-		{"doctype": "Prescription Dosage", "name": "1-1-1", "dosage": "1-1-1","dosage_strength":
-		[{"strength": "1.0","strength_time": "9:00:00"}, {"strength": "1.0","strength_time": "14:00:00"},{"strength": "1.0","strength_time": "21:00:00"}]
-		},
-		{"doctype": "Prescription Dosage", "name": "1-0-1", "dosage": "1-0-1","dosage_strength":
-		[{"strength": "1.0","strength_time": "9:00:00"}, {"strength": "1.0","strength_time": "21:00:00"}]
-		},
-		{"doctype": "Prescription Dosage", "name": "Once Bedtime", "dosage": "Once Bedtime","dosage_strength":
-		[{"strength": "1.0","strength_time": "21:00:00"}]
-		},
-		{"doctype": "Prescription Dosage", "name": "5 times a day", "dosage": "5 times a day","dosage_strength":
-		[{"strength": "1.0","strength_time": "5:00:00"}, {"strength": "1.0","strength_time": "9:00:00"}, {"strength": "1.0","strength_time": "13:00:00"},{"strength": "1.0","strength_time": "17:00:00"},{"strength": "1.0","strength_time": "21:00:00"}]
-		},
-		{"doctype": "Prescription Dosage", "name": "QID", "dosage": "QID","dosage_strength":
-		[{"strength": "1.0","strength_time": "9:00:00"}, {"strength": "1.0","strength_time": "13:00:00"},{"strength": "1.0","strength_time": "17:00:00"},{"strength": "1.0","strength_time": "21:00:00"}]
-		},
-		{"doctype": "Prescription Dosage", "name": "TID", "dosage": "TID","dosage_strength":
-		[{"strength": "1.0","strength_time": "9:00:00"}, {"strength": "1.0","strength_time": "14:00:00"},{"strength": "1.0","strength_time": "21:00:00"}]
-		},
-		{"doctype": "Prescription Dosage", "name": "BID", "dosage": "BID","dosage_strength":
-		[{"strength": "1.0","strength_time": "9:00:00"}, {"strength": "1.0","strength_time": "21:00:00"}]
-		},
-		{"doctype": "Prescription Dosage", "name": "Once Daily", "dosage": "Once Daily","dosage_strength":
-		[{"strength": "1.0","strength_time": "9:00:00"}]
-		}
-	]
-	insert_record(records)
-
-def create_healthcare_item_groups():
-	records = [
-		{'doctype': 'Item Group', 'item_group_name': _('Laboratory'),
-			'is_group': 0, 'parent_item_group': _('All Item Groups') },
-		{'doctype': 'Item Group', 'item_group_name': _('Drug'),
-			'is_group': 0, 'parent_item_group': _('All Item Groups') }
-	]
-	insert_record(records)
-
-def create_sensitivity():
-	records = [
-		{"doctype": "Sensitivity", "sensitivity": _("Low Sensitivity")},
-		{"doctype": "Sensitivity", "sensitivity": _("High Sensitivity")},
-		{"doctype": "Sensitivity", "sensitivity": _("Moderate Sensitivity")},
-		{"doctype": "Sensitivity", "sensitivity": _("Susceptible")},
-		{"doctype": "Sensitivity", "sensitivity": _("Resistant")},
-		{"doctype": "Sensitivity", "sensitivity": _("Intermediate")}
-	]
-	insert_record(records)
-
-def add_healthcare_service_unit_tree_root():
-	record = [
-		{
-			"doctype": "Healthcare Service Unit",
-			"healthcare_service_unit_name": "All Healthcare Service Units",
-			"is_group": 1,
-			"company": get_company()
-	 	}
-	]
-	insert_record(record)
-
-def get_company():
-	company = frappe.defaults.get_defaults().company
-	if company:
-		return company
-	else:
-		company = frappe.get_list("Company", limit=1)
-		if company:
-			return company[0].name
-	return None
-
-def setup_patient_history_settings():
-	import json
-
-	settings = frappe.get_single('Patient History Settings')
-	configuration = get_patient_history_config()
-	for dt, config in configuration.items():
-		settings.append("standard_doctypes", {
-			"document_type": dt,
-			"date_fieldname": config[0],
-			"selected_fields": json.dumps(config[1])
-		})
-	settings.save()
-
-def get_patient_history_config():
-	return {
-		"Patient Encounter": ("encounter_date", [
-			{"label": "Healthcare Practitioner", "fieldname": "practitioner", "fieldtype": "Link"},
-			{"label": "Symptoms", "fieldname": "symptoms", "fieldtype": "Table Multiselect"},
-			{"label": "Diagnosis", "fieldname": "diagnosis", "fieldtype": "Table Multiselect"},
-			{"label": "Drug Prescription", "fieldname": "drug_prescription", "fieldtype": "Table"},
-			{"label": "Lab Tests", "fieldname": "lab_test_prescription", "fieldtype": "Table"},
-			{"label": "Clinical Procedures", "fieldname": "procedure_prescription", "fieldtype": "Table"},
-			{"label": "Therapies", "fieldname": "therapies", "fieldtype": "Table"},
-			{"label": "Review Details", "fieldname": "encounter_comment", "fieldtype": "Small Text"}
-		]),
-		"Clinical Procedure": ("start_date", [
-			{"label": "Procedure Template", "fieldname": "procedure_template", "fieldtype": "Link"},
-			{"label": "Healthcare Practitioner", "fieldname": "practitioner", "fieldtype": "Link"},
-			{"label": "Notes", "fieldname": "notes", "fieldtype": "Small Text"},
-			{"label": "Service Unit", "fieldname": "service_unit", "fieldtype": "Healthcare Service Unit"},
-			{"label": "Start Time", "fieldname": "start_time", "fieldtype": "Time"},
-			{"label": "Sample", "fieldname": "sample", "fieldtype": "Link"}
-		]),
-		"Lab Test": ("result_date", [
-			{"label": "Test Template", "fieldname": "template", "fieldtype": "Link"},
-			{"label": "Healthcare Practitioner", "fieldname": "practitioner", "fieldtype": "Link"},
-			{"label": "Test Name", "fieldname": "lab_test_name", "fieldtype": "Data"},
-			{"label": "Lab Technician Name", "fieldname": "employee_name", "fieldtype": "Data"},
-			{"label": "Sample ID", "fieldname": "sample", "fieldtype": "Link"},
-			{"label": "Normal Test Result", "fieldname": "normal_test_items", "fieldtype": "Table"},
-			{"label": "Descriptive Test Result", "fieldname": "descriptive_test_items", "fieldtype": "Table"},
-			{"label": "Organism Test Result", "fieldname": "organism_test_items", "fieldtype": "Table"},
-			{"label": "Sensitivity Test Result", "fieldname": "sensitivity_test_items", "fieldtype": "Table"},
-			{"label": "Comments", "fieldname": "lab_test_comment", "fieldtype": "Table"}
-		]),
-		"Therapy Session": ("start_date", [
-			{"label": "Therapy Type", "fieldname": "therapy_type", "fieldtype": "Link"},
-			{"label": "Healthcare Practitioner", "fieldname": "practitioner", "fieldtype": "Link"},
-			{"label": "Therapy Plan", "fieldname": "therapy_plan", "fieldtype": "Link"},
-			{"label": "Duration", "fieldname": "duration", "fieldtype": "Int"},
-			{"label": "Location", "fieldname": "location", "fieldtype": "Link"},
-			{"label": "Healthcare Service Unit", "fieldname": "service_unit", "fieldtype": "Link"},
-			{"label": "Start Time", "fieldname": "start_time", "fieldtype": "Time"},
-			{"label": "Exercises", "fieldname": "exercises", "fieldtype": "Table"},
-			{"label": "Total Counts Targeted", "fieldname": "total_counts_targeted", "fieldtype": "Int"},
-			{"label": "Total Counts Completed", "fieldname": "total_counts_completed", "fieldtype": "Int"}
-		]),
-		"Vital Signs": ("signs_date", [
-			{"label": "Body Temperature", "fieldname": "temperature", "fieldtype": "Data"},
-			{"label": "Heart Rate / Pulse", "fieldname": "pulse", "fieldtype": "Data"},
-			{"label": "Respiratory rate", "fieldname": "respiratory_rate", "fieldtype": "Data"},
-			{"label": "Tongue", "fieldname": "tongue", "fieldtype": "Select"},
-			{"label": "Abdomen", "fieldname": "abdomen", "fieldtype": "Select"},
-			{"label": "Reflexes", "fieldname": "reflexes", "fieldtype": "Select"},
-			{"label": "Blood Pressure", "fieldname": "bp", "fieldtype": "Data"},
-			{"label": "Notes", "fieldname": "vital_signs_note", "fieldtype": "Small Text"},
-			{"label": "Height (In Meter)", "fieldname": "height", "fieldtype": "Float"},
-			{"label": "Weight (In Kilogram)", "fieldname": "weight", "fieldtype": "Float"},
-			{"label": "BMI", "fieldname": "bmi", "fieldtype": "Float"}
-		]),
-		"Inpatient Medication Order": ("start_date", [
-			{"label": "Healthcare Practitioner", "fieldname": "practitioner", "fieldtype": "Link"},
-			{"label": "Start Date", "fieldname": "start_date", "fieldtype": "Date"},
-			{"label": "End Date", "fieldname": "end_date", "fieldtype": "Date"},
-			{"label": "Medication Orders", "fieldname": "medication_orders", "fieldtype": "Table"},
-			{"label": "Total Orders", "fieldname": "total_orders", "fieldtype": "Float"}
-		])
-	}
diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py
deleted file mode 100644
index cae3008..0000000
--- a/erpnext/healthcare/utils.py
+++ /dev/null
@@ -1,792 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, earthians and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-
-import json
-import math
-
-import frappe
-from frappe import _
-from frappe.utils import cstr, rounded, time_diff_in_hours
-from frappe.utils.formatters import format_value
-
-from erpnext.healthcare.doctype.fee_validity.fee_validity import create_fee_validity
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_income_account
-from erpnext.healthcare.doctype.lab_test.lab_test import create_multiple
-
-
-@frappe.whitelist()
-def get_healthcare_services_to_invoice(patient, company):
-	patient = frappe.get_doc('Patient', patient)
-	items_to_invoice = []
-	if patient:
-		validate_customer_created(patient)
-		# Customer validated, build a list of billable services
-		items_to_invoice += get_appointments_to_invoice(patient, company)
-		items_to_invoice += get_encounters_to_invoice(patient, company)
-		items_to_invoice += get_lab_tests_to_invoice(patient, company)
-		items_to_invoice += get_clinical_procedures_to_invoice(patient, company)
-		items_to_invoice += get_inpatient_services_to_invoice(patient, company)
-		items_to_invoice += get_therapy_plans_to_invoice(patient, company)
-		items_to_invoice += get_therapy_sessions_to_invoice(patient, company)
-
-		return items_to_invoice
-
-
-def validate_customer_created(patient):
-	if not frappe.db.get_value('Patient', patient.name, 'customer'):
-		msg = _("Please set a Customer linked to the Patient")
-		msg +=  " <b><a href='/app/Form/Patient/{0}'>{0}</a></b>".format(patient.name)
-		frappe.throw(msg, title=_('Customer Not Found'))
-
-
-def get_appointments_to_invoice(patient, company):
-	appointments_to_invoice = []
-	patient_appointments = frappe.get_list(
-			'Patient Appointment',
-			fields = '*',
-			filters = {'patient': patient.name, 'company': company, 'invoiced': 0, 'status': ['not in', 'Cancelled']},
-			order_by = 'appointment_date'
-		)
-
-	for appointment in patient_appointments:
-		# Procedure Appointments
-		if appointment.procedure_template:
-			if frappe.db.get_value('Clinical Procedure Template', appointment.procedure_template, 'is_billable'):
-				appointments_to_invoice.append({
-					'reference_type': 'Patient Appointment',
-					'reference_name': appointment.name,
-					'service': appointment.procedure_template
-				})
-		# Consultation Appointments, should check fee validity
-		else:
-			if frappe.db.get_single_value('Healthcare Settings', 'enable_free_follow_ups') and \
-				frappe.db.exists('Fee Validity Reference', {'appointment': appointment.name}):
-					continue # Skip invoicing, fee validty present
-			practitioner_charge = 0
-			income_account = None
-			service_item = None
-			if appointment.practitioner:
-				details = get_service_item_and_practitioner_charge(appointment)
-				service_item = details.get('service_item')
-				practitioner_charge = details.get('practitioner_charge')
-				income_account = get_income_account(appointment.practitioner, appointment.company)
-			appointments_to_invoice.append({
-				'reference_type': 'Patient Appointment',
-				'reference_name': appointment.name,
-				'service': service_item,
-				'rate': practitioner_charge,
-				'income_account': income_account
-			})
-
-	return appointments_to_invoice
-
-
-def get_encounters_to_invoice(patient, company):
-	if not isinstance(patient, str):
-		patient = patient.name
-	encounters_to_invoice = []
-	encounters = frappe.get_list(
-		'Patient Encounter',
-		fields=['*'],
-		filters={'patient': patient, 'company': company, 'invoiced': False, 'docstatus': 1}
-	)
-	if encounters:
-		for encounter in encounters:
-			if not encounter.appointment:
-				practitioner_charge = 0
-				income_account = None
-				service_item = None
-				if encounter.practitioner:
-					if encounter.inpatient_record and \
-						frappe.db.get_single_value('Healthcare Settings', 'do_not_bill_inpatient_encounters'):
-						continue
-
-					details = get_service_item_and_practitioner_charge(encounter)
-					service_item = details.get('service_item')
-					practitioner_charge = details.get('practitioner_charge')
-					income_account = get_income_account(encounter.practitioner, encounter.company)
-
-				encounters_to_invoice.append({
-					'reference_type': 'Patient Encounter',
-					'reference_name': encounter.name,
-					'service': service_item,
-					'rate': practitioner_charge,
-					'income_account': income_account
-				})
-
-	return encounters_to_invoice
-
-
-def get_lab_tests_to_invoice(patient, company):
-	lab_tests_to_invoice = []
-	lab_tests = frappe.get_list(
-		'Lab Test',
-		fields=['name', 'template'],
-		filters={'patient': patient.name, 'company': company, 'invoiced': False, 'docstatus': 1}
-	)
-	for lab_test in lab_tests:
-		item, is_billable = frappe.get_cached_value('Lab Test Template', lab_test.template, ['item', 'is_billable'])
-		if is_billable:
-			lab_tests_to_invoice.append({
-				'reference_type': 'Lab Test',
-				'reference_name': lab_test.name,
-				'service': item
-			})
-
-	lab_prescriptions = frappe.db.sql(
-		'''
-			SELECT
-				lp.name, lp.lab_test_code
-			FROM
-				`tabPatient Encounter` et, `tabLab Prescription` lp
-			WHERE
-				et.patient=%s
-				and lp.parent=et.name
-				and lp.lab_test_created=0
-				and lp.invoiced=0
-		''', (patient.name), as_dict=1)
-
-	for prescription in lab_prescriptions:
-		item, is_billable = frappe.get_cached_value('Lab Test Template', prescription.lab_test_code, ['item', 'is_billable'])
-		if prescription.lab_test_code and is_billable:
-			lab_tests_to_invoice.append({
-				'reference_type': 'Lab Prescription',
-				'reference_name': prescription.name,
-				'service': item
-			})
-
-	return lab_tests_to_invoice
-
-
-def get_clinical_procedures_to_invoice(patient, company):
-	clinical_procedures_to_invoice = []
-	procedures = frappe.get_list(
-		'Clinical Procedure',
-		fields='*',
-		filters={'patient': patient.name, 'company': company, 'invoiced': False}
-	)
-	for procedure in procedures:
-		if not procedure.appointment:
-			item, is_billable = frappe.get_cached_value('Clinical Procedure Template', procedure.procedure_template, ['item', 'is_billable'])
-			if procedure.procedure_template and is_billable:
-				clinical_procedures_to_invoice.append({
-					'reference_type': 'Clinical Procedure',
-					'reference_name': procedure.name,
-					'service': item
-				})
-
-		# consumables
-		if procedure.invoice_separately_as_consumables and procedure.consume_stock \
-			and procedure.status == 'Completed' and not procedure.consumption_invoiced:
-
-			service_item = frappe.db.get_single_value('Healthcare Settings', 'clinical_procedure_consumable_item')
-			if not service_item:
-				frappe.throw(_('Please configure Clinical Procedure Consumable Item in {0}').format(
-					frappe.utils.get_link_to_form('Healthcare Settings', 'Healthcare Settings')),
-					title=_('Missing Configuration'))
-
-			clinical_procedures_to_invoice.append({
-				'reference_type': 'Clinical Procedure',
-				'reference_name': procedure.name,
-				'service': service_item,
-				'rate': procedure.consumable_total_amount,
-				'description': procedure.consumption_details
-			})
-
-	procedure_prescriptions = frappe.db.sql(
-		'''
-			SELECT
-				pp.name, pp.procedure
-			FROM
-				`tabPatient Encounter` et, `tabProcedure Prescription` pp
-			WHERE
-				et.patient=%s
-				and pp.parent=et.name
-				and pp.procedure_created=0
-				and pp.invoiced=0
-				and pp.appointment_booked=0
-		''', (patient.name), as_dict=1)
-
-	for prescription in procedure_prescriptions:
-		item, is_billable = frappe.get_cached_value('Clinical Procedure Template', prescription.procedure, ['item', 'is_billable'])
-		if is_billable:
-			clinical_procedures_to_invoice.append({
-				'reference_type': 'Procedure Prescription',
-				'reference_name': prescription.name,
-				'service': item
-			})
-
-	return clinical_procedures_to_invoice
-
-
-def get_inpatient_services_to_invoice(patient, company):
-	services_to_invoice = []
-	inpatient_services = frappe.db.sql(
-		'''
-			SELECT
-				io.*
-			FROM
-				`tabInpatient Record` ip, `tabInpatient Occupancy` io
-			WHERE
-				ip.patient=%s
-				and ip.company=%s
-				and io.parent=ip.name
-				and io.left=1
-				and io.invoiced=0
-		''', (patient.name, company), as_dict=1)
-
-	for inpatient_occupancy in inpatient_services:
-		service_unit_type = frappe.db.get_value('Healthcare Service Unit', inpatient_occupancy.service_unit, 'service_unit_type')
-		service_unit_type = frappe.get_cached_doc('Healthcare Service Unit Type', service_unit_type)
-		if service_unit_type and service_unit_type.is_billable:
-			hours_occupied = time_diff_in_hours(inpatient_occupancy.check_out, inpatient_occupancy.check_in)
-			qty = 0.5
-			if hours_occupied > 0:
-				actual_qty = hours_occupied / service_unit_type.no_of_hours
-				floor = math.floor(actual_qty)
-				decimal_part = actual_qty - floor
-				if decimal_part > 0.5:
-					qty = rounded(floor + 1, 1)
-				elif decimal_part < 0.5 and decimal_part > 0:
-					qty = rounded(floor + 0.5, 1)
-				if qty <= 0:
-					qty = 0.5
-			services_to_invoice.append({
-				'reference_type': 'Inpatient Occupancy',
-				'reference_name': inpatient_occupancy.name,
-				'service': service_unit_type.item, 'qty': qty
-			})
-
-	return services_to_invoice
-
-
-def get_therapy_plans_to_invoice(patient, company):
-	therapy_plans_to_invoice = []
-	therapy_plans = frappe.get_list(
-		'Therapy Plan',
-		fields=['therapy_plan_template', 'name'],
-		filters={
-			'patient': patient.name,
-			'invoiced': 0,
-			'company': company,
-			'therapy_plan_template': ('!=', '')
-		}
-	)
-	for plan in therapy_plans:
-		therapy_plans_to_invoice.append({
-			'reference_type': 'Therapy Plan',
-			'reference_name': plan.name,
-			'service': frappe.db.get_value('Therapy Plan Template', plan.therapy_plan_template, 'linked_item')
-		})
-
-	return therapy_plans_to_invoice
-
-
-def get_therapy_sessions_to_invoice(patient, company):
-	therapy_sessions_to_invoice = []
-	therapy_plans = frappe.db.get_all('Therapy Plan', {'therapy_plan_template': ('!=', '')})
-	therapy_plans_created_from_template = []
-	for entry in therapy_plans:
-		therapy_plans_created_from_template.append(entry.name)
-
-	therapy_sessions = frappe.get_list(
-		'Therapy Session',
-		fields='*',
-		filters={
-			'patient': patient.name,
-			'invoiced': 0,
-			'company': company,
-			'therapy_plan': ('not in', therapy_plans_created_from_template)
-		}
-	)
-	for therapy in therapy_sessions:
-		if not therapy.appointment:
-			if therapy.therapy_type and frappe.db.get_value('Therapy Type', therapy.therapy_type, 'is_billable'):
-				therapy_sessions_to_invoice.append({
-					'reference_type': 'Therapy Session',
-					'reference_name': therapy.name,
-					'service': frappe.db.get_value('Therapy Type', therapy.therapy_type, 'item')
-				})
-
-	return therapy_sessions_to_invoice
-
-@frappe.whitelist()
-def get_service_item_and_practitioner_charge(doc):
-	if isinstance(doc, str):
-		doc = json.loads(doc)
-		doc = frappe.get_doc(doc)
-
-	service_item = None
-	practitioner_charge = None
-	department = doc.medical_department if doc.doctype == 'Patient Encounter' else doc.department
-
-	is_inpatient = doc.inpatient_record
-
-	if doc.get('appointment_type'):
-		service_item, practitioner_charge = get_appointment_type_service_item(doc.appointment_type, department, is_inpatient)
-
-	if not service_item and not practitioner_charge:
-		service_item, practitioner_charge = get_practitioner_service_item(doc.practitioner, is_inpatient)
-		if not service_item:
-			service_item = get_healthcare_service_item(is_inpatient)
-
-	if not service_item:
-		throw_config_service_item(is_inpatient)
-
-	if not practitioner_charge:
-		throw_config_practitioner_charge(is_inpatient, doc.practitioner)
-
-	return {'service_item': service_item, 'practitioner_charge': practitioner_charge}
-
-
-def get_appointment_type_service_item(appointment_type, department, is_inpatient):
-	from erpnext.healthcare.doctype.appointment_type.appointment_type import (
-		get_service_item_based_on_department,
-	)
-
-	item_list = get_service_item_based_on_department(appointment_type, department)
-	service_item = None
-	practitioner_charge = None
-
-	if item_list:
-		if is_inpatient:
-			service_item = item_list.get('inpatient_visit_charge_item')
-			practitioner_charge = item_list.get('inpatient_visit_charge')
-		else:
-			service_item = item_list.get('op_consulting_charge_item')
-			practitioner_charge = item_list.get('op_consulting_charge')
-
-	return service_item, practitioner_charge
-
-
-def throw_config_service_item(is_inpatient):
-	service_item_label = _('Out Patient Consulting Charge Item')
-	if is_inpatient:
-		service_item_label = _('Inpatient Visit Charge Item')
-
-	msg = _(('Please Configure {0} in ').format(service_item_label) \
-		+ '''<b><a href='/app/Form/Healthcare Settings'>Healthcare Settings</a></b>''')
-	frappe.throw(msg, title=_('Missing Configuration'))
-
-
-def throw_config_practitioner_charge(is_inpatient, practitioner):
-	charge_name = _('OP Consulting Charge')
-	if is_inpatient:
-		charge_name = _('Inpatient Visit Charge')
-
-	msg = _(('Please Configure {0} for Healthcare Practitioner').format(charge_name) \
-		+ ''' <b><a href='/app/Form/Healthcare Practitioner/{0}'>{0}</a></b>'''.format(practitioner))
-	frappe.throw(msg, title=_('Missing Configuration'))
-
-
-def get_practitioner_service_item(practitioner, is_inpatient):
-	service_item = None
-	practitioner_charge = None
-
-	if is_inpatient:
-		service_item, practitioner_charge = frappe.db.get_value('Healthcare Practitioner', practitioner, ['inpatient_visit_charge_item', 'inpatient_visit_charge'])
-	else:
-		service_item, practitioner_charge = frappe.db.get_value('Healthcare Practitioner', practitioner, ['op_consulting_charge_item', 'op_consulting_charge'])
-
-	return service_item, practitioner_charge
-
-
-def get_healthcare_service_item(is_inpatient):
-	service_item = None
-
-	if is_inpatient:
-		service_item = frappe.db.get_single_value('Healthcare Settings', 'inpatient_visit_charge_item')
-	else:
-		service_item = frappe.db.get_single_value('Healthcare Settings', 'op_consulting_charge_item')
-
-	return service_item
-
-
-def get_practitioner_charge(practitioner, is_inpatient):
-	if is_inpatient:
-		practitioner_charge = frappe.db.get_value('Healthcare Practitioner', practitioner, 'inpatient_visit_charge')
-	else:
-		practitioner_charge = frappe.db.get_value('Healthcare Practitioner', practitioner, 'op_consulting_charge')
-	if practitioner_charge:
-		return practitioner_charge
-	return False
-
-
-def manage_invoice_submit_cancel(doc, method):
-	if doc.items:
-		for item in doc.items:
-			if item.get('reference_dt') and item.get('reference_dn'):
-				if frappe.get_meta(item.reference_dt).has_field('invoiced'):
-					set_invoiced(item, method, doc.name)
-
-	if method=='on_submit' and frappe.db.get_single_value('Healthcare Settings', 'create_lab_test_on_si_submit'):
-		create_multiple('Sales Invoice', doc.name)
-
-
-def set_invoiced(item, method, ref_invoice=None):
-	invoiced = False
-	if method=='on_submit':
-		validate_invoiced_on_submit(item)
-		invoiced = True
-
-	if item.reference_dt == 'Clinical Procedure':
-		service_item = frappe.db.get_single_value('Healthcare Settings', 'clinical_procedure_consumable_item')
-		if service_item == item.item_code:
-			frappe.db.set_value(item.reference_dt, item.reference_dn, 'consumption_invoiced', invoiced)
-		else:
-			frappe.db.set_value(item.reference_dt, item.reference_dn, 'invoiced', invoiced)
-	else:
-		frappe.db.set_value(item.reference_dt, item.reference_dn, 'invoiced', invoiced)
-
-	if item.reference_dt == 'Patient Appointment':
-		if frappe.db.get_value('Patient Appointment', item.reference_dn, 'procedure_template'):
-			dt_from_appointment = 'Clinical Procedure'
-		else:
-			dt_from_appointment = 'Patient Encounter'
-		manage_doc_for_appointment(dt_from_appointment, item.reference_dn, invoiced)
-
-	elif item.reference_dt == 'Lab Prescription':
-		manage_prescriptions(invoiced, item.reference_dt, item.reference_dn, 'Lab Test', 'lab_test_created')
-
-	elif item.reference_dt == 'Procedure Prescription':
-		manage_prescriptions(invoiced, item.reference_dt, item.reference_dn, 'Clinical Procedure', 'procedure_created')
-
-
-def validate_invoiced_on_submit(item):
-	if item.reference_dt == 'Clinical Procedure' and \
-		frappe.db.get_single_value('Healthcare Settings', 'clinical_procedure_consumable_item') == item.item_code:
-		is_invoiced = frappe.db.get_value(item.reference_dt, item.reference_dn, 'consumption_invoiced')
-	else:
-		is_invoiced = frappe.db.get_value(item.reference_dt, item.reference_dn, 'invoiced')
-	if is_invoiced:
-		frappe.throw(_('The item referenced by {0} - {1} is already invoiced').format(
-			item.reference_dt, item.reference_dn))
-
-
-def manage_prescriptions(invoiced, ref_dt, ref_dn, dt, created_check_field):
-	created = frappe.db.get_value(ref_dt, ref_dn, created_check_field)
-	if created:
-		# Fetch the doc created for the prescription
-		doc_created = frappe.db.get_value(dt, {'prescription': ref_dn})
-		frappe.db.set_value(dt, doc_created, 'invoiced', invoiced)
-
-
-def check_fee_validity(appointment):
-	if not frappe.db.get_single_value('Healthcare Settings', 'enable_free_follow_ups'):
-		return
-
-	validity = frappe.db.exists('Fee Validity', {
-		'practitioner': appointment.practitioner,
-		'patient': appointment.patient,
-		'valid_till': ('>=', appointment.appointment_date)
-	})
-	if not validity:
-		return
-
-	validity = frappe.get_doc('Fee Validity', validity)
-	return validity
-
-
-def manage_fee_validity(appointment):
-	fee_validity = check_fee_validity(appointment)
-
-	if fee_validity:
-		if appointment.status == 'Cancelled' and fee_validity.visited > 0:
-			fee_validity.visited -= 1
-			frappe.db.delete('Fee Validity Reference', {'appointment': appointment.name})
-		elif fee_validity.status == 'Completed':
-			return
-		else:
-			fee_validity.visited += 1
-			fee_validity.append('ref_appointments', {
-				'appointment': appointment.name
-			})
-		fee_validity.save(ignore_permissions=True)
-	else:
-		fee_validity = create_fee_validity(appointment)
-	return fee_validity
-
-
-def manage_doc_for_appointment(dt_from_appointment, appointment, invoiced):
-	dn_from_appointment = frappe.db.get_value(
-		dt_from_appointment,
-		filters={'appointment': appointment}
-	)
-	if dn_from_appointment:
-		frappe.db.set_value(dt_from_appointment, dn_from_appointment, 'invoiced', invoiced)
-
-
-@frappe.whitelist()
-def get_drugs_to_invoice(encounter):
-	encounter = frappe.get_doc('Patient Encounter', encounter)
-	if encounter:
-		patient = frappe.get_doc('Patient', encounter.patient)
-		if patient:
-			if patient.customer:
-				items_to_invoice = []
-				for drug_line in encounter.drug_prescription:
-					if drug_line.drug_code:
-						qty = 1
-						if frappe.db.get_value('Item', drug_line.drug_code, 'stock_uom') == 'Nos':
-							qty = drug_line.get_quantity()
-
-						description = ''
-						if drug_line.dosage and drug_line.period:
-							description = _('{0} for {1}').format(drug_line.dosage, drug_line.period)
-
-						items_to_invoice.append({
-							'drug_code': drug_line.drug_code,
-							'quantity': qty,
-							'description': description
-						})
-				return items_to_invoice
-			else:
-				validate_customer_created(patient)
-
-
-@frappe.whitelist()
-def get_children(doctype, parent=None, company=None, is_root=False):
-	parent_fieldname = 'parent_' + doctype.lower().replace(' ', '_')
-	fields = [
-		'name as value',
-		'is_group as expandable',
-		'lft',
-		'rgt'
-	]
-
-	filters = [["ifnull(`{0}`,'')".format(parent_fieldname),
-		'=', '' if is_root else parent]]
-
-	if is_root:
-		fields += ['service_unit_type'] if doctype == 'Healthcare Service Unit' else []
-		filters.append(['company', '=', company])
-	else:
-		fields += ['service_unit_type', 'allow_appointments', 'inpatient_occupancy',
-			'occupancy_status'] if doctype == 'Healthcare Service Unit' else []
-		fields += [parent_fieldname + ' as parent']
-
-	service_units = frappe.get_list(doctype, fields=fields, filters=filters)
-	for each in service_units:
-		if each['expandable'] == 1:  # group node
-			available_count = frappe.db.count('Healthcare Service Unit',  filters={
-				'parent_healthcare_service_unit': each['value'],
-				'inpatient_occupancy': 1})
-
-			if available_count > 0:
-				occupied_count = frappe.db.count('Healthcare Service Unit',  {
-					'parent_healthcare_service_unit': each['value'],
-					'inpatient_occupancy': 1,
-					'occupancy_status': 'Occupied'})
-				# set occupancy status of group node
-				each['occupied_of_available'] = str(
-					occupied_count) + ' Occupied of ' + str(available_count)
-
-	return service_units
-
-
-@frappe.whitelist()
-def get_patient_vitals(patient, from_date=None, to_date=None):
-	if not patient: return
-
-	vitals = frappe.db.get_all('Vital Signs', filters={
-			'docstatus': 1,
-			'patient': patient
-		}, order_by='signs_date, signs_time', fields=['*'])
-
-	if len(vitals):
-		return vitals
-	return False
-
-
-@frappe.whitelist()
-def render_docs_as_html(docs):
-	# docs key value pair {doctype: docname}
-	docs_html = "<div class='col-md-12 col-sm-12 text-muted'>"
-	for doc in docs:
-		docs_html += render_doc_as_html(doc['doctype'], doc['docname'])['html'] + '<br/>'
-		return {'html': docs_html}
-
-
-@frappe.whitelist()
-def render_doc_as_html(doctype, docname, exclude_fields = []):
-	"""
-		Render document as HTML
-	"""
-
-	doc = frappe.get_doc(doctype, docname)
-	meta = frappe.get_meta(doctype)
-	doc_html = section_html = section_label = html = ""
-	sec_on = has_data = False
-	col_on = 0
-
-	for df in meta.fields:
-		# on section break append previous section and html to doc html
-		if df.fieldtype == "Section Break":
-			if has_data and col_on and sec_on:
-				doc_html += section_html + html + "</div>"
-
-			elif has_data and not col_on and sec_on:
-				doc_html += """
-					<br>
-					<div class='row'>
-						<div class='col-md-12 col-sm-12'>
-							<b>{0}</b>
-						</div>
-					</div>
-					<div class='row'>
-						<div class='col-md-12 col-sm-12'>
-							{1} {2}
-						</div>
-					</div>
-				""".format(section_label, section_html, html)
-
-			# close divs for columns
-			while col_on:
-				doc_html += "</div>"
-				col_on -= 1
-
-			sec_on = True
-			has_data = False
-			col_on = 0
-			section_html = html = ""
-
-			if df.label:
-				section_label = df.label
-			continue
-
-		# on column break append html to section html or doc html
-		if df.fieldtype == "Column Break":
-			if sec_on and not col_on and has_data:
-				section_html += """
-					<br>
-					<div class='row'>
-						<div class='col-md-12 col-sm-12'>
-							<b>{0}</b>
-						</div>
-					</div>
-					<div class='row'>
-						<div class='col-md-4 col-sm-4'>
-							{1}
-						</div>
-				""".format(section_label, html)
-			elif col_on == 1 and has_data:
-				section_html += "<div class='col-md-4 col-sm-4'>" + html + "</div>"
-			elif col_on > 1 and has_data:
-				doc_html += "<div class='col-md-4 col-sm-4'>" + html + "</div>"
-			else:
-				doc_html += """
-					<div class='row'>
-						<div class='col-md-12 col-sm-12'>
-							{0}
-						</div>
-					</div>
-				""".format(html)
-
-			html = ""
-			col_on += 1
-
-			if df.label:
-				html += "<br>" + df.label
-			continue
-
-		# on table iterate through items and create table
-		# based on the in_list_view property
-		# append to section html or doc html
-		if df.fieldtype == "Table":
-			items = doc.get(df.fieldname)
-			if not items:
-				continue
-			child_meta = frappe.get_meta(df.options)
-
-			if not has_data:
-				has_data = True
-			table_head = table_row = ""
-			create_head = True
-
-			for item in items:
-				table_row += "<tr>"
-				for cdf in child_meta.fields:
-					if cdf.in_list_view:
-						if create_head:
-							table_head += "<th class='text-muted'>" + cdf.label + "</th>"
-						if item.get(cdf.fieldname):
-							table_row += "<td>" + cstr(item.get(cdf.fieldname)) + "</td>"
-						else:
-							table_row += "<td></td>"
-
-				create_head = False
-				table_row += "</tr>"
-
-			if sec_on:
-				section_html += """
-					<table class='table table-condensed bordered'>
-						{0} {1}
-					</table>
-				""".format(table_head, table_row)
-			else:
-				html += """
-					<table class='table table-condensed table-bordered'>
-						{0} {1}
-					</table>
-				""".format(table_head, table_row)
-			continue
-
-		# on any other field type add label and value to html
-		if not df.hidden and not df.print_hide and doc.get(df.fieldname) and df.fieldname not in exclude_fields:
-			formatted_value = format_value(doc.get(df.fieldname), meta.get_field(df.fieldname), doc)
-			html += "<br>{0} : {1}".format(df.label or df.fieldname, formatted_value)
-
-			if not has_data : has_data = True
-
-	if sec_on and col_on and has_data:
-		doc_html += section_html + html + "</div></div>"
-	elif sec_on and not col_on and has_data:
-		doc_html += """
-			<div class='col-md-12 col-sm-12'>
-				<div class='col-md-12 col-sm-12'>
-					{0} {1}
-				</div>
-			</div>
-		""".format(section_html, html)
-
-	return {"html": doc_html}
-
-
-def update_address_links(address, method):
-	'''
-	Hook validate Address
-	If Patient is linked in Address, also link the associated Customer
-	'''
-	if 'Healthcare' not in frappe.get_active_domains():
-		return
-
-	patient_links = list(filter(lambda link: link.get('link_doctype') == 'Patient', address.links))
-
-	for link in patient_links:
-		customer = frappe.db.get_value('Patient', link.get('link_name'), 'customer')
-		if customer and not address.has_link('Customer', customer):
-			address.append('links', dict(link_doctype = 'Customer', link_name = customer))
-
-
-def update_patient_email_and_phone_numbers(contact, method):
-	'''
-	Hook validate Contact
-	Update linked Patients' primary mobile and phone numbers
-	'''
-	if 'Healthcare' not in frappe.get_active_domains():
-		return
-
-	if contact.is_primary_contact and (contact.email_id or contact.mobile_no or contact.phone):
-		patient_links = list(filter(lambda link: link.get('link_doctype') == 'Patient', contact.links))
-
-		for link in patient_links:
-			contact_details = frappe.db.get_value('Patient', link.get('link_name'), ['email', 'mobile', 'phone'], as_dict=1)
-			if contact.email_id and contact.email_id != contact_details.get('email'):
-				frappe.db.set_value('Patient', link.get('link_name'), 'email', contact.email_id)
-			if contact.mobile_no and contact.mobile_no != contact_details.get('mobile'):
-				frappe.db.set_value('Patient', link.get('link_name'), 'mobile', contact.mobile_no)
-			if contact.phone and contact.phone != contact_details.get('phone'):
-				frappe.db.set_value('Patient', link.get('link_name'), 'phone', contact.phone)
diff --git a/erpnext/healthcare/web_form/__init__.py b/erpnext/healthcare/web_form/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/web_form/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/web_form/lab_test/__init__.py b/erpnext/healthcare/web_form/lab_test/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/web_form/lab_test/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/web_form/lab_test/lab_test.js b/erpnext/healthcare/web_form/lab_test/lab_test.js
deleted file mode 100644
index efcd8ab..0000000
--- a/erpnext/healthcare/web_form/lab_test/lab_test.js
+++ /dev/null
@@ -1,34 +0,0 @@
-frappe.ready(function() {
-	//	bind events here
-	var normal_test_items = $('div[data-fieldname = "normal_test_items"]');
-	var normal_test_items_add_btn = $('button[data-fieldname = "normal_test_items"]');
-	var special_test_items = $('div[data-fieldname = "special_test_items"]');
-	var special_test_items_add_btn = $('button[data-fieldname = "special_test_items"]');
-	var sensitivity_test_items = $('div[data-fieldname = "sensitivity_test_items"]');
-	var sensitivity_test_items_add_btn = $('button[data-fieldname = "sensitivity_test_items"]');
-	var sensitivity_toggle = $('input[name = "sensitivity_toggle"]');
-	var special_toggle = $('input[name = "special_toggle"]');
-	var normal_toggle = $('input[name = "normal_toggle"]');
-	if(normal_toggle.val() == 1){
-		//	normal_test_items[0].style.display = "none";
-		//	normal_test_items[0].setAttribute("hidden", true);
-		//	normal_test_items_add_btn[0].style.visibility = "hidden";
-		special_test_items[0].style.display = "none";
-		special_test_items_add_btn[0].style.display = "none";
-		sensitivity_test_items[0].style.display = "none";
-		sensitivity_test_items_add_btn[0].style.display = "none";
-		normal_test_items_add_btn[0].style.display = "none";
-	}else if(sensitivity_toggle.val() == 1){
-		special_test_items[0].style.display = "none";
-		special_test_items_add_btn[0].style.display = "none";
-		normal_test_items[0].style.display = "none";
-		normal_test_items_add_btn[0].style.display = "none";
-		sensitivity_test_items_add_btn[0].style.display = "none";
-	}else if(special_toggle.val() == 1){
-		normal_test_items[0].style.display = "none";
-		normal_test_items_add_btn[0].style.display = "none";
-		sensitivity_test_items[0].style.display = "none";
-		sensitivity_test_items_add_btn[0].style.display = "none";
-		special_test_items_add_btn[0].style.display = "none";
-	}
-});
diff --git a/erpnext/healthcare/web_form/lab_test/lab_test.json b/erpnext/healthcare/web_form/lab_test/lab_test.json
deleted file mode 100644
index 3509917..0000000
--- a/erpnext/healthcare/web_form/lab_test/lab_test.json
+++ /dev/null
@@ -1,460 +0,0 @@
-{
- "accept_payment": 0,
- "allow_comments": 1,
- "allow_delete": 0,
- "allow_edit": 1,
- "allow_incomplete": 0,
- "allow_multiple": 1,
- "allow_print": 1,
- "amount": 0.0,
- "amount_based_on_field": 0,
- "creation": "2017-06-06 16:12:33.052258",
- "currency": "INR",
- "doc_type": "Lab Test",
- "docstatus": 0,
- "doctype": "Web Form",
- "idx": 0,
- "introduction_text": "Lab Test",
- "is_standard": 1,
- "login_required": 1,
- "max_attachment_size": 0,
- "modified": "2020-06-22 12:59:49.126398",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "lab-test",
- "owner": "Administrator",
- "payment_button_label": "Buy Now",
- "print_format": "Lab Test Print",
- "published": 1,
- "route": "lab-test",
- "route_to_success_link": 0,
- "show_attachments": 0,
- "show_in_grid": 0,
- "show_sidebar": 1,
- "sidebar_items": [],
- "success_url": "/lab-test",
- "title": "Lab Test",
- "web_form_fields": [
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "lab_test_name",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "label": "Test Name",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 1,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "department",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "label": "Department",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "Medical Department",
-   "read_only": 1,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "column_break_26",
-   "fieldtype": "Column Break",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "label": "Company",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "Company",
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "status",
-   "fieldtype": "Select",
-   "hidden": 0,
-   "label": "Status",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "Draft\nCompleted\nApproved\nRejected\nCancelled",
-   "read_only": 1,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "submitted_date",
-   "fieldtype": "Datetime",
-   "hidden": 0,
-   "label": "Submitted Date",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "sb_first",
-   "fieldtype": "Section Break",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "patient",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "label": "Patient",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "Patient",
-   "read_only": 0,
-   "reqd": 1,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "patient_name",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "label": "Patient Name",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 1,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "patient_age",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "label": "Age",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 1,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "patient_sex",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "label": "Gender",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "Gender",
-   "read_only": 0,
-   "reqd": 1,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "inpatient_record",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "label": "Inpatient Record",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "Inpatient Record",
-   "read_only": 1,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "report_preference",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "label": "Report Preference",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 1,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "email",
-   "fieldtype": "Data",
-   "hidden": 1,
-   "label": "Email",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 1,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "mobile",
-   "fieldtype": "Data",
-   "hidden": 1,
-   "label": "Mobile",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 1,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "c_b",
-   "fieldtype": "Column Break",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "practitioner",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "label": "Requesting Practitioner",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "Healthcare Practitioner",
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "practitioner_name",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "label": "Requesting Practitioner",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 1,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "requesting_department",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "label": "Requesting Department",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "Medical Department",
-   "read_only": 1,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "employee",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "label": "Employee (Lab Technician)",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "Employee",
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "employee_name",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "label": "Lab Technician Name",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 1,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "employee_designation",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "label": "Lab Technician Designation",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 1,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "sb_normal",
-   "fieldtype": "Section Break",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "lab_test_html",
-   "fieldtype": "HTML",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "normal_test_items",
-   "fieldtype": "Table",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "options": "Normal Test Result",
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "sb_descriptive",
-   "fieldtype": "Section Break",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "descriptive_test_items",
-   "fieldtype": "Table",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "options": "Descriptive Test Result",
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "depends_on": "special_toggle",
-   "fieldname": "organisms_section",
-   "fieldtype": "Section Break",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "organisms",
-   "fieldtype": "Table",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "options": "Organism Test Result",
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "sb_sensitivity",
-   "fieldtype": "Section Break",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "sensitivity_test_items",
-   "fieldtype": "Table",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "options": "Sensitivity Test Result",
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "sb_comments",
-   "fieldtype": "Section Break",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "lab_test_comment",
-   "fieldtype": "Text",
-   "hidden": 0,
-   "label": "Comments",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "sb_customresult",
-   "fieldtype": "Section Break",
-   "hidden": 0,
-   "label": "Custom Result",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "custom_result",
-   "fieldtype": "Text Editor",
-   "hidden": 0,
-   "label": "Custom Result",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  }
- ]
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/web_form/lab_test/lab_test.py b/erpnext/healthcare/web_form/lab_test/lab_test.py
deleted file mode 100644
index ec08985..0000000
--- a/erpnext/healthcare/web_form/lab_test/lab_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from __future__ import unicode_literals
-
-import frappe
-
-
-def get_context(context):
-	context.read_only = 1
-
-def get_list_context(context):
-	context.row_template = "erpnext/templates/includes/healthcare/lab_test_row_template.html"
-	context.get_list = get_lab_test_list
-
-def get_lab_test_list(doctype, txt, filters, limit_start, limit_page_length = 20, order_by='modified desc'):
-	patient = get_patient()
-	lab_tests = frappe.db.sql("""select * from `tabLab Test`
-		where patient = %s order by result_date""", patient, as_dict = True)
-	return lab_tests
-
-def get_patient():
-	return frappe.get_value("Patient",{"email": frappe.session.user}, "name")
-
-def has_website_permission(doc, ptype, user, verbose=False):
-	if doc.patient == get_patient():
-		return True
-	else:
-		return False
diff --git a/erpnext/healthcare/web_form/patient_appointments/__init__.py b/erpnext/healthcare/web_form/patient_appointments/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/web_form/patient_appointments/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/web_form/patient_appointments/patient_appointments.js b/erpnext/healthcare/web_form/patient_appointments/patient_appointments.js
deleted file mode 100644
index f09e540..0000000
--- a/erpnext/healthcare/web_form/patient_appointments/patient_appointments.js
+++ /dev/null
@@ -1,3 +0,0 @@
-frappe.ready(function() {
-	// bind events here
-});
diff --git a/erpnext/healthcare/web_form/patient_appointments/patient_appointments.json b/erpnext/healthcare/web_form/patient_appointments/patient_appointments.json
deleted file mode 100644
index e9cf7a8..0000000
--- a/erpnext/healthcare/web_form/patient_appointments/patient_appointments.json
+++ /dev/null
@@ -1,111 +0,0 @@
-{
- "accept_payment": 0, 
- "allow_comments": 0, 
- "allow_delete": 0, 
- "allow_edit": 1, 
- "allow_incomplete": 0, 
- "allow_multiple": 1, 
- "allow_print": 1, 
- "amount": 0.0, 
- "amount_based_on_field": 0, 
- "creation": "2017-06-07 15:30:44.984832", 
- "currency": "INR", 
- "doc_type": "Patient Appointment", 
- "docstatus": 0, 
- "doctype": "Web Form", 
- "idx": 0, 
- "introduction_text": "Patient Appointments", 
- "is_standard": 1, 
- "login_required": 1, 
- "max_attachment_size": 0, 
- "modified": "2018-07-16 13:11:08.626316", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "patient-appointments", 
- "owner": "Administrator", 
- "payment_button_label": "Buy Now", 
- "published": 1, 
- "route": "patient-appointments", 
- "show_sidebar": 1, 
- "sidebar_items": [], 
- "success_url": "/patient-appointments", 
- "title": "Patient Appointments", 
- "web_form_fields": [
-  {
-   "fieldname": "patient", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "label": "Patient", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "options": "Patient", 
-   "read_only": 0, 
-   "reqd": 1
-  }, 
-  {
-   "fieldname": "practitioner", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "label": "Healthcare Practitioner", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "options": "Healthcare Practitioner", 
-   "read_only": 0, 
-   "reqd": 1
-  }, 
-  {
-   "fieldname": "appointment_date", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "label": "Date", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "read_only": 0, 
-   "reqd": 1
-  }, 
-  {
-   "fieldname": "appointment_time", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "label": "Time", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "read_only": 0, 
-   "reqd": 0
-  }, 
-  {
-   "fieldname": "department", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "label": "Department", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "options": "Medical Department", 
-   "read_only": 0, 
-   "reqd": 0
-  }, 
-  {
-   "fieldname": "appointment_type", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "label": "Type", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "options": "Appointment Type", 
-   "read_only": 0, 
-   "reqd": 0
-  }, 
-  {
-   "default": "Scheduled", 
-   "fieldname": "status", 
-   "fieldtype": "Select", 
-   "hidden": 0, 
-   "label": "Status", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "options": "\nScheduled\nOpen\nClosed\nPending\nCancelled", 
-   "read_only": 1, 
-   "reqd": 0
-  }
- ]
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/web_form/patient_appointments/patient_appointments.py b/erpnext/healthcare/web_form/patient_appointments/patient_appointments.py
deleted file mode 100644
index 80c12fd..0000000
--- a/erpnext/healthcare/web_form/patient_appointments/patient_appointments.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from __future__ import unicode_literals
-
-import frappe
-
-
-def get_context(context):
-	context.read_only = 1
-
-def get_list_context(context):
-	context.row_template = "erpnext/templates/includes/healthcare/appointment_row_template.html"
-	context.get_list = get_appointment_list
-
-def get_appointment_list(doctype, txt, filters, limit_start, limit_page_length = 20, order_by='modified desc'):
-	patient = get_patient()
-	lab_tests = frappe.db.sql("""select * from `tabPatient Appointment`
-		where patient = %s and (status = 'Open' or status = 'Scheduled') order by appointment_date""", patient, as_dict = True)
-	return lab_tests
-
-def get_patient():
-	return frappe.get_value("Patient",{"email": frappe.session.user}, "name")
-
-def has_website_permission(doc, ptype, user, verbose=False):
-	if doc.patient == get_patient():
-		return True
-	else:
-		return False
diff --git a/erpnext/healthcare/web_form/patient_registration/__init__.py b/erpnext/healthcare/web_form/patient_registration/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/web_form/patient_registration/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/web_form/patient_registration/patient_registration.js b/erpnext/healthcare/web_form/patient_registration/patient_registration.js
deleted file mode 100644
index f09e540..0000000
--- a/erpnext/healthcare/web_form/patient_registration/patient_registration.js
+++ /dev/null
@@ -1,3 +0,0 @@
-frappe.ready(function() {
-	// bind events here
-});
diff --git a/erpnext/healthcare/web_form/patient_registration/patient_registration.json b/erpnext/healthcare/web_form/patient_registration/patient_registration.json
deleted file mode 100644
index 9ed92de..0000000
--- a/erpnext/healthcare/web_form/patient_registration/patient_registration.json
+++ /dev/null
@@ -1,397 +0,0 @@
-{
- "accept_payment": 0,
- "allow_comments": 0,
- "allow_delete": 0,
- "allow_edit": 1,
- "allow_incomplete": 0,
- "allow_multiple": 0,
- "allow_print": 0,
- "amount": 0.0,
- "amount_based_on_field": 0,
- "button_label": "Register",
- "creation": "2020-03-03 01:01:16.250607",
- "currency": "INR",
- "doc_type": "Patient",
- "docstatus": 0,
- "doctype": "Web Form",
- "idx": 0,
- "introduction_text": "",
- "is_standard": 1,
- "login_required": 0,
- "max_attachment_size": 0,
- "modified": "2020-03-26 17:25:15.361918",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "patient-registration",
- "owner": "Administrator",
- "payment_button_label": "Buy Now",
- "published": 1,
- "route": "patient-registration",
- "route_to_success_link": 0,
- "show_attachments": 0,
- "show_in_grid": 0,
- "show_sidebar": 1,
- "sidebar_items": [],
- "success_message": "Registration Successfully. Thank You!",
- "success_url": "/patient-registration",
- "title": "Patient Registration",
- "web_form_fields": [
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "basic_info",
-   "fieldtype": "Section Break",
-   "hidden": 0,
-   "label": "Patient Demographics",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "fa fa-user",
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "first_name",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "label": "First Name",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 1,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "middle_name",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "label": "Middle Name (optional)",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "last_name",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "label": "Last Name",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 1,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "sex",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "label": "Gender",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "Gender",
-   "read_only": 0,
-   "reqd": 1,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "blood_group",
-   "fieldtype": "Select",
-   "hidden": 0,
-   "label": "Blood Group",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "\nA Positive\nA Negative\nAB Positive\nAB Negative\nB Positive\nB Negative\nO Positive\nO Negative",
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "",
-   "fieldtype": "Column Break",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "dob",
-   "fieldtype": "Date",
-   "hidden": 0,
-   "label": "Date of birth",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "mobile",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "label": "Mobile",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "email",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "label": "Email",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "Email",
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "phone",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "label": "Phone",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "",
-   "fieldtype": "Section Break",
-   "hidden": 0,
-   "label": "Personal Details",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "occupation",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "label": "Occupation",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "",
-   "fieldtype": "Column Break",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "marital_status",
-   "fieldtype": "Select",
-   "hidden": 0,
-   "label": "Marital Status",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "\nSingle\nMarried\nDivorced\nWidow",
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "allergy_medical_and_surgical_history",
-   "fieldtype": "Section Break",
-   "hidden": 0,
-   "label": "Allergies, Medical and Surgical History",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "allergies",
-   "fieldtype": "Small Text",
-   "hidden": 0,
-   "label": "Allergies",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "medication",
-   "fieldtype": "Small Text",
-   "hidden": 0,
-   "label": "Medication",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "column_break_20",
-   "fieldtype": "Column Break",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "medical_history",
-   "fieldtype": "Small Text",
-   "hidden": 0,
-   "label": "Medical History",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "surgical_history",
-   "fieldtype": "Small Text",
-   "hidden": 0,
-   "label": "Surgical History",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "risk_factors",
-   "fieldtype": "Section Break",
-   "hidden": 0,
-   "label": "Risk Factors",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "default": "0",
-   "fieldname": "tobacco_past_use",
-   "fieldtype": "Check",
-   "hidden": 0,
-   "label": "Check if you have a history of Tobacco Consumption",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "",
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "default": "0",
-   "fieldname": "tobacco_current_use",
-   "fieldtype": "Check",
-   "hidden": 0,
-   "label": "Check if you consume Tobacco",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "",
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "default": "0",
-   "fieldname": "alcohol_past_use",
-   "fieldtype": "Check",
-   "hidden": 0,
-   "label": "Check if you have a history of Alcohol Consumption",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "",
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "default": "0",
-   "fieldname": "alcohol_current_use",
-   "fieldtype": "Check",
-   "hidden": 0,
-   "label": "Check if you consume Alcohol",
-   "max_length": 0,
-   "max_value": 0,
-   "options": "",
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "column_break_32",
-   "fieldtype": "Column Break",
-   "hidden": 0,
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "surrounding_factors",
-   "fieldtype": "Small Text",
-   "hidden": 0,
-   "label": "Occupational Hazards and Environmental Factors",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  },
-  {
-   "allow_read_on_all_link_options": 0,
-   "fieldname": "other_risk_factors",
-   "fieldtype": "Small Text",
-   "hidden": 0,
-   "label": "Other Risk Factors",
-   "max_length": 0,
-   "max_value": 0,
-   "read_only": 0,
-   "reqd": 0,
-   "show_in_filter": 0
-  }
- ]
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/web_form/patient_registration/patient_registration.py b/erpnext/healthcare/web_form/patient_registration/patient_registration.py
deleted file mode 100644
index f57de91..0000000
--- a/erpnext/healthcare/web_form/patient_registration/patient_registration.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from __future__ import unicode_literals
-
-
-def get_context(context):
-	# do your magic here
-	pass
diff --git a/erpnext/healthcare/web_form/personal_details/__init__.py b/erpnext/healthcare/web_form/personal_details/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/web_form/personal_details/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/web_form/personal_details/personal_details.js b/erpnext/healthcare/web_form/personal_details/personal_details.js
deleted file mode 100644
index f09e540..0000000
--- a/erpnext/healthcare/web_form/personal_details/personal_details.js
+++ /dev/null
@@ -1,3 +0,0 @@
-frappe.ready(function() {
-	// bind events here
-});
diff --git a/erpnext/healthcare/web_form/personal_details/personal_details.json b/erpnext/healthcare/web_form/personal_details/personal_details.json
deleted file mode 100644
index aad987a..0000000
--- a/erpnext/healthcare/web_form/personal_details/personal_details.json
+++ /dev/null
@@ -1,87 +0,0 @@
-{
- "accept_payment": 0, 
- "allow_comments": 0, 
- "allow_delete": 0, 
- "allow_edit": 1, 
- "allow_incomplete": 0, 
- "allow_multiple": 0, 
- "allow_print": 0, 
- "amount": 0.0, 
- "amount_based_on_field": 0, 
- "creation": "2018-07-03 19:33:23.332661", 
- "currency": "INR", 
- "doc_type": "Patient", 
- "docstatus": 0, 
- "doctype": "Web Form", 
- "idx": 0, 
- "introduction_text": "", 
- "is_standard": 1, 
- "login_required": 1, 
- "max_attachment_size": 0, 
- "modified": "2018-07-04 17:22:28.936442", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "personal-details", 
- "owner": "Administrator", 
- "payment_button_label": "Buy Now", 
- "published": 1, 
- "route": "personal-details", 
- "show_sidebar": 1, 
- "sidebar_items": [], 
- "success_url": "/personal-details", 
- "title": "Personal Details", 
- "web_form_fields": [
-  {
-   "fieldname": "patient_name", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "label": "Full Name", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "read_only": 0, 
-   "reqd": 1
-  }, 
-  {
-   "fieldname": "sex", 
-   "fieldtype": "Select", 
-   "hidden": 0, 
-   "label": "Gender", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "options": "\nMale\nFemale\nOther", 
-   "read_only": 0, 
-   "reqd": 1
-  }, 
-  {
-   "fieldname": "dob", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "label": "Date of birth", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "read_only": 0, 
-   "reqd": 1
-  }, 
-  {
-   "fieldname": "mobile", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "label": "Mobile", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "read_only": 0, 
-   "reqd": 0
-  }, 
-  {
-   "fieldname": "email", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "label": "Email", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "options": "Email", 
-   "read_only": 1, 
-   "reqd": 0
-  }
- ]
-}
diff --git a/erpnext/healthcare/web_form/personal_details/personal_details.py b/erpnext/healthcare/web_form/personal_details/personal_details.py
deleted file mode 100644
index fe46d7b..0000000
--- a/erpnext/healthcare/web_form/personal_details/personal_details.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from __future__ import unicode_literals
-
-import frappe
-from frappe import _
-
-no_cache = 1
-
-def get_context(context):
-	if frappe.session.user=='Guest':
-		frappe.throw(_("You need to be logged in to access this page"), frappe.PermissionError)
-
-	context.show_sidebar=True
-
-	if frappe.db.exists("Patient", {'email': frappe.session.user}):
-		patient = frappe.get_doc("Patient", {'email': frappe.session.user})
-		context.doc = patient
-		frappe.form_dict.new = 0
-		frappe.form_dict.name = patient.name
-
-def get_patient():
-	return frappe.get_value("Patient",{"email": frappe.session.user}, "name")
-
-def has_website_permission(doc, ptype, user, verbose=False):
-	if doc.name == get_patient():
-		return True
-	else:
-		return False
diff --git a/erpnext/healthcare/web_form/prescription/__init__.py b/erpnext/healthcare/web_form/prescription/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/healthcare/web_form/prescription/__init__.py
+++ /dev/null
diff --git a/erpnext/healthcare/web_form/prescription/prescription.js b/erpnext/healthcare/web_form/prescription/prescription.js
deleted file mode 100644
index f09e540..0000000
--- a/erpnext/healthcare/web_form/prescription/prescription.js
+++ /dev/null
@@ -1,3 +0,0 @@
-frappe.ready(function() {
-	// bind events here
-});
diff --git a/erpnext/healthcare/web_form/prescription/prescription.json b/erpnext/healthcare/web_form/prescription/prescription.json
deleted file mode 100644
index 8e19e32..0000000
--- a/erpnext/healthcare/web_form/prescription/prescription.json
+++ /dev/null
@@ -1,120 +0,0 @@
-{
- "accept_payment": 0, 
- "allow_comments": 0, 
- "allow_delete": 0, 
- "allow_edit": 1, 
- "allow_incomplete": 0, 
- "allow_multiple": 1, 
- "allow_print": 1, 
- "amount": 0.0, 
- "amount_based_on_field": 0, 
- "creation": "2017-06-06 17:13:19.101374", 
- "currency": "INR", 
- "doc_type": "Patient Encounter", 
- "docstatus": 0, 
- "doctype": "Web Form", 
- "idx": 0, 
- "introduction_text": "Patient Prescriptions", 
- "is_standard": 1, 
- "login_required": 1, 
- "max_attachment_size": 0, 
- "modified": "2018-09-04 11:53:40.954517", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "prescription", 
- "owner": "Administrator", 
- "payment_button_label": "Buy Now", 
- "print_format": "Encounter Print", 
- "published": 1, 
- "route": "prescription", 
- "show_in_grid": 0, 
- "show_sidebar": 1, 
- "sidebar_items": [], 
- "success_url": "/prescription", 
- "title": "Prescription", 
- "web_form_fields": [
-  {
-   "fieldname": "practitioner", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "label": "Healthcare Practitioner", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "options": "Healthcare Practitioner", 
-   "read_only": 0, 
-   "reqd": 1, 
-   "show_in_filter": 0
-  }, 
-  {
-   "fieldname": "visit_department", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "label": "Department", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "options": "Medical Department", 
-   "read_only": 0, 
-   "reqd": 0, 
-   "show_in_filter": 0
-  }, 
-  {
-   "default": "Today", 
-   "fieldname": "encounter_date", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "label": "Encounter Date", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "read_only": 0, 
-   "reqd": 1, 
-   "show_in_filter": 0
-  }, 
-  {
-   "default": "", 
-   "fieldname": "encounter_time", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "label": "Encounter Time", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "read_only": 0, 
-   "reqd": 1, 
-   "show_in_filter": 0
-  }, 
-  {
-   "fieldname": "drug_prescription", 
-   "fieldtype": "Table", 
-   "hidden": 0, 
-   "label": "Drug Prescription", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "options": "Drug Prescription", 
-   "read_only": 0, 
-   "reqd": 0, 
-   "show_in_filter": 0
-  }, 
-  {
-   "fieldname": "lab_test_prescription", 
-   "fieldtype": "Table", 
-   "hidden": 0, 
-   "label": "Investigations", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "options": "Lab Prescription", 
-   "read_only": 0, 
-   "reqd": 0, 
-   "show_in_filter": 0
-  }, 
-  {
-   "fieldname": "encounter_comment", 
-   "fieldtype": "Small Text", 
-   "hidden": 0, 
-   "label": "Review Details", 
-   "max_length": 0, 
-   "max_value": 0, 
-   "read_only": 0, 
-   "reqd": 0, 
-   "show_in_filter": 0
-  }
- ]
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/web_form/prescription/prescription.py b/erpnext/healthcare/web_form/prescription/prescription.py
deleted file mode 100644
index f6f273a..0000000
--- a/erpnext/healthcare/web_form/prescription/prescription.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from __future__ import unicode_literals
-
-import frappe
-
-
-def get_context(context):
-	context.read_only = 1
-
-def get_list_context(context):
-	context.row_template = "erpnext/templates/includes/healthcare/prescription_row_template.html"
-	context.get_list = get_encounter_list
-
-def get_encounter_list(doctype, txt, filters, limit_start, limit_page_length = 20, order_by='modified desc'):
-	patient = get_patient()
-	encounters = frappe.db.sql("""select * from `tabPatient Encounter`
-		where patient = %s order by creation desc""", patient, as_dict = True)
-	return encounters
-
-def get_patient():
-	return frappe.get_value("Patient",{"email": frappe.session.user}, "name")
-
-def has_website_permission(doc, ptype, user, verbose=False):
-	if doc.patient == get_patient():
-		return True
-	else:
-		return False
diff --git a/erpnext/healthcare/workspace/healthcare/healthcare.json b/erpnext/healthcare/workspace/healthcare/healthcare.json
deleted file mode 100644
index f69604c..0000000
--- a/erpnext/healthcare/workspace/healthcare/healthcare.json
+++ /dev/null
@@ -1,626 +0,0 @@
-{
- "category": "",
- "charts": [
-  {
-   "chart_name": "Patient Appointments",
-   "label": "Patient Appointments"
-  }
- ],
- "charts_label": "",
- "content": "[{\"type\": \"onboarding\", \"data\": {\"onboarding_name\":\"Healthcare\", \"col\": 12}}, {\"type\": \"chart\", \"data\": {\"chart_name\": \"Patient Appointments\", \"col\": 12}}, {\"type\": \"spacer\", \"data\": {\"col\": 12}}, {\"type\": \"header\", \"data\": {\"text\": \"Your Shortcuts\", \"level\": 4, \"col\": 12}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Patient Appointment\", \"col\": 4}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Patient\", \"col\": 4}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Healthcare Service Unit\", \"col\": 4}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Healthcare Practitioner\", \"col\": 4}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Patient History\", \"col\": 4}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Dashboard\", \"col\": 4}}, {\"type\": \"spacer\", \"data\": {\"col\": 12}}, {\"type\": \"header\", \"data\": {\"text\": \"Reports & Masters\", \"level\": 4, \"col\": 12}}, {\"type\": \"card\", \"data\": {\"card_name\": \"Masters\", \"col\": 4}}, {\"type\": \"card\", \"data\": {\"card_name\": \"Consultation Setup\", \"col\": 4}}, {\"type\": \"card\", \"data\": {\"card_name\": \"Consultation\", \"col\": 4}}, {\"type\": \"card\", \"data\": {\"card_name\": \"Facility Management\", \"col\": 4}}, {\"type\": \"card\", \"data\": {\"card_name\": \"Settings\", \"col\": 4}}, {\"type\": \"card\", \"data\": {\"card_name\": \"Inpatient\", \"col\": 4}}, {\"type\": \"card\", \"data\": {\"card_name\": \"Laboratory Setup\", \"col\": 4}}, {\"type\": \"card\", \"data\": {\"card_name\": \"Laboratory\", \"col\": 4}}, {\"type\": \"card\", \"data\": {\"card_name\": \"Rehabilitation and Physiotherapy\", \"col\": 4}}, {\"type\": \"card\", \"data\": {\"card_name\": \"Records and History\", \"col\": 4}}, {\"type\": \"card\", \"data\": {\"card_name\": \"Reports\", \"col\": 4}}]",
- "creation": "2020-03-02 17:23:17.919682",
- "developer_mode_only": 0,
- "disable_user_customization": 0,
- "docstatus": 0,
- "doctype": "Workspace",
- "extends": "",
- "extends_another_page": 0,
- "for_user": "",
- "hide_custom": 0,
- "icon": "healthcare",
- "idx": 0,
- "is_default": 0,
- "is_standard": 0,
- "label": "Healthcare",
- "links": [
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Masters",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Patient",
-   "link_count": 0,
-   "link_to": "Patient",
-   "link_type": "DocType",
-   "onboard": 1,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Healthcare Practitioner",
-   "link_count": 0,
-   "link_to": "Healthcare Practitioner",
-   "link_type": "DocType",
-   "onboard": 1,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Practitioner Schedule",
-   "link_count": 0,
-   "link_to": "Practitioner Schedule",
-   "link_type": "DocType",
-   "onboard": 1,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Medical Department",
-   "link_count": 0,
-   "link_to": "Medical Department",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Consultation Setup",
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Appointment Type",
-   "link_to": "Appointment Type",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Clinical Procedure Template",
-   "link_to": "Clinical Procedure Template",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Prescription Dosage",
-   "link_to": "Prescription Dosage",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Prescription Duration",
-   "link_to": "Prescription Duration",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Antibiotic",
-   "link_to": "Antibiotic",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Complaint",
-   "link_to": "Complaint",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Diagnosis",
-   "link_to": "Diagnosis",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Consultation",
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Patient Appointment",
-   "link_to": "Patient Appointment",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Clinical Procedure",
-   "link_to": "Clinical Procedure",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Patient Encounter",
-   "link_to": "Patient Encounter",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Vital Signs",
-   "link_to": "Vital Signs",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Fee Validity",
-   "link_to": "Fee Validity",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Facility Management",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Healthcare Service Unit Type",
-   "link_to": "Healthcare Service Unit Type",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Healthcare Service Unit",
-   "link_to": "Healthcare Service Unit",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Medical Coding",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Medical Code Standard",
-   "link_to": "Medical Code Standard",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Medical Code",
-   "link_to": "Medical Code",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Settings",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Healthcare Settings",
-   "link_count": 0,
-   "link_to": "Healthcare Settings",
-   "link_type": "DocType",
-   "onboard": 1,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Laboratory Setup",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Lab Test Template",
-   "link_count": 0,
-   "link_to": "Lab Test Template",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Lab Test Sample",
-   "link_count": 0,
-   "link_to": "Lab Test Sample",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Lab Test UOM",
-   "link_count": 0,
-   "link_to": "Lab Test UOM",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Sensitivity",
-   "link_count": 0,
-   "link_to": "Sensitivity",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Dosage Form",
-   "link_to": "Dosage Form",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Laboratory",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Lab Test",
-   "link_count": 0,
-   "link_to": "Lab Test",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Sample Collection",
-   "link_count": 0,
-   "link_to": "Sample Collection",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Inpatient",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Inpatient Medication Order",
-   "link_to": "Inpatient Medication Order",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Inpatient Record",
-   "link_to": "Inpatient Record",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Inpatient Medication Entry",
-   "link_to": "Inpatient Medication Entry",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Rehabilitation and Physiotherapy",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Exercise Type",
-   "link_count": 0,
-   "link_to": "Exercise Type",
-   "link_type": "DocType",
-   "onboard": 1,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Therapy Type",
-   "link_count": 0,
-   "link_to": "Therapy Type",
-   "link_type": "DocType",
-   "onboard": 1,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Therapy Plan",
-   "link_count": 0,
-   "link_to": "Therapy Plan",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Therapy Session",
-   "link_count": 0,
-   "link_to": "Therapy Session",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Patient Assessment Template",
-   "link_count": 0,
-   "link_to": "Patient Assessment Template",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Patient Assessment",
-   "link_count": 0,
-   "link_to": "Patient Assessment",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Records and History",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Patient History",
-   "link_count": 0,
-   "link_to": "patient_history",
-   "link_type": "Page",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Patient Progress",
-   "link_count": 0,
-   "link_to": "patient-progress",
-   "link_type": "Page",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Patient Medical Record",
-   "link_count": 0,
-   "link_to": "Patient Medical Record",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Inpatient Record",
-   "link_count": 0,
-   "link_to": "Inpatient Record",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Reports",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Patient Appointment Analytics",
-   "link_count": 0,
-   "link_to": "Patient Appointment Analytics",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Lab Test Report",
-   "link_count": 0,
-   "link_to": "Lab Test Report",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  }
- ],
- "modified": "2021-08-30 17:37:45.316999",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Healthcare",
- "onboarding": "Healthcare",
- "owner": "Administrator",
- "parent_page": "",
- "pin_to_bottom": 0,
- "pin_to_top": 0,
- "public": 1,
- "restrict_to_domain": "Healthcare",
- "roles": [],
- "sequence_id": 13,
- "shortcuts": [
-  {
-   "color": "Orange",
-   "format": "{} Open",
-   "label": "Patient Appointment",
-   "link_to": "Patient Appointment",
-   "stats_filter": "{\n    \"status\": \"Open\",\n    \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%']\n}",
-   "type": "DocType"
-  },
-  {
-   "color": "Orange",
-   "format": "{} Active",
-   "label": "Patient",
-   "link_to": "Patient",
-   "stats_filter": "{\n    \"status\": \"Active\"\n}",
-   "type": "DocType"
-  },
-  {
-   "color": "Green",
-   "format": "{} Vacant",
-   "label": "Healthcare Service Unit",
-   "link_to": "Healthcare Service Unit",
-   "stats_filter": "{\n    \"occupancy_status\": \"Vacant\",\n    \"is_group\": 0,\n    \"company\": [\"like\", \"%\" + frappe.defaults.get_global_default(\"company\") + \"%\"]\n}",
-   "type": "DocType"
-  },
-  {
-   "label": "Healthcare Practitioner",
-   "link_to": "Healthcare Practitioner",
-   "type": "DocType"
-  },
-  {
-   "label": "Patient History",
-   "link_to": "patient_history",
-   "type": "Page"
-  },
-  {
-   "label": "Dashboard",
-   "link_to": "Healthcare",
-   "type": "Dashboard"
-  }
- ],
- "title": "Healthcare"
-}
\ No newline at end of file
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 1e3ad8e..05f07f5 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -62,6 +62,7 @@
 # website
 update_website_context = ["erpnext.shopping_cart.utils.update_website_context", "erpnext.education.doctype.education_settings.education_settings.update_website_context"]
 my_account_context = "erpnext.shopping_cart.utils.update_my_account_context"
+webform_list_context = "erpnext.controllers.website_list_for_contact.get_webform_list_context"
 
 calendars = ["Task", "Work Order", "Leave Application", "Sales Order", "Holiday List", "Course Schedule"]
 
@@ -69,7 +70,6 @@
 	'Agriculture': 'erpnext.domains.agriculture',
 	'Distribution': 'erpnext.domains.distribution',
 	'Education': 'erpnext.domains.education',
-	'Healthcare': 'erpnext.domains.healthcare',
 	'Hospitality': 'erpnext.domains.hospitality',
 	'Manufacturing': 'erpnext.domains.manufacturing',
 	'Non Profit': 'erpnext.domains.non_profit',
@@ -81,7 +81,7 @@
 	"Job Opening", "Student Admission"]
 
 website_context = {
-	"favicon": 	"/assets/erpnext/images/erpnext-favicon.svg",
+	"favicon": "/assets/erpnext/images/erpnext-favicon.svg",
 	"splash_image": "/assets/erpnext/images/erpnext-logo.svg"
 }
 
@@ -164,7 +164,6 @@
 ]
 
 standard_portal_menu_items = [
-	{"title": _("Personal Details"), "route": "/personal-details", "reference_doctype": "Patient", "role": "Patient"},
 	{"title": _("Projects"), "route": "/project", "reference_doctype": "Project"},
 	{"title": _("Request for Quotations"), "route": "/rfq", "reference_doctype": "Request for Quotation", "role": "Supplier"},
 	{"title": _("Supplier Quotation"), "route": "/supplier-quotations", "reference_doctype": "Supplier Quotation", "role": "Supplier"},
@@ -177,9 +176,6 @@
 	{"title": _("Issues"), "route": "/issues", "reference_doctype": "Issue", "role":"Customer"},
 	{"title": _("Addresses"), "route": "/addresses", "reference_doctype": "Address"},
 	{"title": _("Timesheets"), "route": "/timesheets", "reference_doctype": "Timesheet", "role":"Customer"},
-	{"title": _("Lab Test"), "route": "/lab-test", "reference_doctype": "Lab Test", "role":"Patient"},
-	{"title": _("Prescription"), "route": "/prescription", "reference_doctype": "Patient Encounter", "role":"Patient"},
-	{"title": _("Patient Appointment"), "route": "/patient-appointments", "reference_doctype": "Patient Appointment", "role":"Patient"},
 	{"title": _("Fees"), "route": "/fees", "reference_doctype": "Fees", "role":"Student"},
 	{"title": _("Newsletter"), "route": "/newsletters", "reference_doctype": "Newsletter"},
 	{"title": _("Admission"), "route": "/admissions", "reference_doctype": "Student Admission", "role": "Student"},
@@ -214,10 +210,6 @@
 	"Delivery Note": "erpnext.controllers.website_list_for_contact.has_website_permission",
 	"Issue": "erpnext.support.doctype.issue.issue.has_website_permission",
 	"Timesheet": "erpnext.controllers.website_list_for_contact.has_website_permission",
-	"Lab Test": "erpnext.healthcare.web_form.lab_test.lab_test.has_website_permission",
-	"Patient Encounter": "erpnext.healthcare.web_form.prescription.prescription.has_website_permission",
-	"Patient Appointment": "erpnext.healthcare.web_form.patient_appointments.patient_appointments.has_website_permission",
-	"Patient": "erpnext.healthcare.web_form.personal_details.personal_details.has_website_permission"
 }
 
 dump_report_map = "erpnext.startup.report_data_map.data_map"
@@ -226,15 +218,11 @@
 
 standard_queries = {
 	"Customer": "erpnext.selling.doctype.customer.customer.get_customer_list",
-	"Healthcare Practitioner": "erpnext.healthcare.doctype.healthcare_practitioner.healthcare_practitioner.get_practitioner_list"
 }
 
 doc_events = {
 	"*": {
 		"validate": "erpnext.support.doctype.service_level_agreement.service_level_agreement.apply",
-		"on_submit": "erpnext.healthcare.doctype.patient_history_settings.patient_history_settings.create_medical_record",
-		"on_update_after_submit": "erpnext.healthcare.doctype.patient_history_settings.patient_history_settings.update_medical_record",
-		"on_cancel": "erpnext.healthcare.doctype.patient_history_settings.patient_history_settings.delete_medical_record"
 	},
 	"Stock Entry": {
 		"on_submit": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty",
@@ -300,7 +288,6 @@
 			'erpnext.regional.india.utils.validate_gstin_for_india',
 			'erpnext.regional.italy.utils.set_state_code',
 			'erpnext.regional.india.utils.update_gst_category',
-			'erpnext.healthcare.utils.update_address_links'
 		],
 	},
 	'Supplier': {
@@ -312,7 +299,7 @@
 	"Contact": {
 		"on_trash": "erpnext.support.doctype.issue.issue.update_issue",
 		"after_insert": "erpnext.telephony.doctype.call_log.call_log.link_existing_conversations",
-		"validate": ["erpnext.crm.utils.update_lead_phone_numbers", "erpnext.healthcare.utils.update_patient_email_and_phone_numbers"]
+		"validate": ["erpnext.crm.utils.update_lead_phone_numbers"]
 	},
 	"Email Unsubscribe": {
 		"after_insert": "erpnext.crm.doctype.email_campaign.email_campaign.unsubscribe_recipient"
@@ -333,7 +320,6 @@
 # if payment entry not in auto cancel exempted doctypes it will cancel payment entry.
 auto_cancel_exempted_doctypes= [
 	"Payment Entry",
-	"Inpatient Medication Entry"
 ]
 
 after_migrate = ["erpnext.setup.install.update_select_perm_after_install"]
@@ -346,7 +332,7 @@
 	},
 	"all": [
 		"erpnext.projects.doctype.project.project.project_status_update_reminder",
-		"erpnext.healthcare.doctype.patient_appointment.patient_appointment.send_appointment_reminder",
+		"erpnext.hr.doctype.interview.interview.send_interview_reminder",
 		"erpnext.crm.doctype.social_media_post.social_media_post.process_scheduled_social_media_posts"
 	],
 	"hourly": [
@@ -387,10 +373,10 @@
 		"erpnext.crm.doctype.email_campaign.email_campaign.send_email_to_leads_or_contacts",
 		"erpnext.crm.doctype.email_campaign.email_campaign.set_email_campaign_status",
 		"erpnext.selling.doctype.quotation.quotation.set_expired_status",
-		"erpnext.healthcare.doctype.patient_appointment.patient_appointment.update_appointment_status",
 		"erpnext.buying.doctype.supplier_quotation.supplier_quotation.set_expired_status",
 		"erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.send_auto_email",
 		"erpnext.non_profit.doctype.membership.membership.set_expired_status"
+		"erpnext.hr.doctype.interview.interview.send_daily_feedback_reminder"
 	],
 	"daily_long": [
 		"erpnext.setup.doctype.email_digest.email_digest.send",
@@ -445,7 +431,7 @@
 	"Purchase Receipt Item", "Stock Entry Detail", "Payment Entry Deduction", "Sales Taxes and Charges", "Purchase Taxes and Charges", "Shipping Rule",
 	"Landed Cost Item", "Asset Value Adjustment", "Loyalty Program", "Fee Schedule", "Fee Structure", "Stock Reconciliation",
 	"Travel Request", "Fees", "POS Profile", "Opening Invoice Creation Tool", "Opening Invoice Creation Tool Item", "Subscription",
-	"Subscription Plan"
+	"Subscription Plan", "POS Invoice", "POS Invoice Item"
 ]
 
 regional_overrides = {
@@ -540,32 +526,6 @@
 		{"doctype": "Maintenance Visit", "index": 46},
 		{"doctype": "Warranty Claim", "index": 47},
 	],
-	"Healthcare": [
-		{'doctype': 'Patient', 'index': 1},
-		{'doctype': 'Medical Department', 'index': 2},
-		{'doctype': 'Vital Signs', 'index': 3},
-		{'doctype': 'Healthcare Practitioner', 'index': 4},
-		{'doctype': 'Patient Appointment', 'index': 5},
-		{'doctype': 'Healthcare Service Unit', 'index': 6},
-		{'doctype': 'Patient Encounter', 'index': 7},
-		{'doctype': 'Antibiotic', 'index': 8},
-		{'doctype': 'Diagnosis', 'index': 9},
-		{'doctype': 'Lab Test', 'index': 10},
-		{'doctype': 'Clinical Procedure', 'index': 11},
-		{'doctype': 'Inpatient Record', 'index': 12},
-		{'doctype': 'Sample Collection', 'index': 13},
-		{'doctype': 'Patient Medical Record', 'index': 14},
-		{'doctype': 'Appointment Type', 'index': 15},
-		{'doctype': 'Fee Validity', 'index': 16},
-		{'doctype': 'Practitioner Schedule', 'index': 17},
-		{'doctype': 'Dosage Form', 'index': 18},
-		{'doctype': 'Lab Test Sample', 'index': 19},
-		{'doctype': 'Prescription Duration', 'index': 20},
-		{'doctype': 'Prescription Dosage', 'index': 21},
-		{'doctype': 'Sensitivity', 'index': 22},
-		{'doctype': 'Complaint', 'index': 23},
-		{'doctype': 'Medical Code', 'index': 24},
-	],
 	"Education": [
 		{'doctype': 'Article', 'index': 1},
 		{'doctype': 'Video', 'index': 2},
diff --git a/erpnext/hr/doctype/attendance/attendance_list.js b/erpnext/hr/doctype/attendance/attendance_list.js
index 9a3bac0..6b3c29a 100644
--- a/erpnext/hr/doctype/attendance/attendance_list.js
+++ b/erpnext/hr/doctype/attendance/attendance_list.js
@@ -9,83 +9,86 @@
 			return [__(doc.status), "orange", "status,=," + doc.status];
 		}
 	},
+
 	onload: function(list_view) {
 		let me = this;
-		const months = moment.months()
-		list_view.page.add_inner_button( __("Mark Attendance"), function() {
+		const months = moment.months();
+		list_view.page.add_inner_button(__("Mark Attendance"), function() {
 			let dialog = new frappe.ui.Dialog({
 				title: __("Mark Attendance"),
-				fields: [
-					{
-						fieldname: 'employee',
-						label: __('For Employee'),
-						fieldtype: 'Link',
-						options: 'Employee',
-						get_query: () => {
-							return {query: "erpnext.controllers.queries.employee_query"}
-						},
-						reqd: 1,
-						onchange: function() {
-							dialog.set_df_property("unmarked_days", "hidden", 1);
-							dialog.set_df_property("status", "hidden", 1);
-							dialog.set_df_property("month", "value", '');
+				fields: [{
+					fieldname: 'employee',
+					label: __('For Employee'),
+					fieldtype: 'Link',
+					options: 'Employee',
+					get_query: () => {
+						return {query: "erpnext.controllers.queries.employee_query"};
+					},
+					reqd: 1,
+					onchange: function() {
+						dialog.set_df_property("unmarked_days", "hidden", 1);
+						dialog.set_df_property("status", "hidden", 1);
+						dialog.set_df_property("month", "value", '');
+						dialog.set_df_property("unmarked_days", "options", []);
+						dialog.no_unmarked_days_left = false;
+					}
+				},
+				{
+					label: __("For Month"),
+					fieldtype: "Select",
+					fieldname: "month",
+					options: months,
+					reqd: 1,
+					onchange: function() {
+						if (dialog.fields_dict.employee.value && dialog.fields_dict.month.value) {
+							dialog.set_df_property("status", "hidden", 0);
 							dialog.set_df_property("unmarked_days", "options", []);
 							dialog.no_unmarked_days_left = false;
+							me.get_multi_select_options(dialog.fields_dict.employee.value, dialog.fields_dict.month.value).then(options => {
+								if (options.length > 0) {
+									dialog.set_df_property("unmarked_days", "hidden", 0);
+									dialog.set_df_property("unmarked_days", "options", options);
+								} else {
+									dialog.no_unmarked_days_left = true;
+								}
+							});
 						}
-					},
-					{
-						label: __("For Month"),
-						fieldtype: "Select",
-						fieldname: "month",
-						options: months,
-						reqd: 1,
-						onchange: function() {
-							if(dialog.fields_dict.employee.value && dialog.fields_dict.month.value) {
-								dialog.set_df_property("status", "hidden", 0);
-								dialog.set_df_property("unmarked_days", "options", []);
-								dialog.no_unmarked_days_left = false;
-								me.get_multi_select_options(dialog.fields_dict.employee.value, dialog.fields_dict.month.value).then(options =>{
-									if (options.length > 0) {
-										dialog.set_df_property("unmarked_days", "hidden", 0);
-										dialog.set_df_property("unmarked_days", "options", options);
-									} else {
-										dialog.no_unmarked_days_left = true;
-									}
-								});
-							}
-						}
-					},
-					{
-						label: __("Status"),
-						fieldtype: "Select",
-						fieldname: "status",
-						options: ["Present", "Absent", "Half Day", "Work From Home"],
-						hidden:1,
-						reqd: 1,
+					}
+				},
+				{
+					label: __("Status"),
+					fieldtype: "Select",
+					fieldname: "status",
+					options: ["Present", "Absent", "Half Day", "Work From Home"],
+					hidden: 1,
+					reqd: 1,
 
-					},
-					{
-						label: __("Unmarked Attendance for days"),
-						fieldname: "unmarked_days",
-						fieldtype: "MultiCheck",
-						options: [],
-						columns: 2,
-						hidden: 1
-					},
-				],
-				primary_action(data)  {
+				},
+				{
+					label: __("Unmarked Attendance for days"),
+					fieldname: "unmarked_days",
+					fieldtype: "MultiCheck",
+					options: [],
+					columns: 2,
+					hidden: 1
+				}],
+				primary_action(data) {
 					if (cur_dialog.no_unmarked_days_left) {
-						frappe.msgprint(__("Attendance for the month of {0} , has already been marked for the Employee {1}",[dialog.fields_dict.month.value, dialog.fields_dict.employee.value]));
+						frappe.msgprint(__("Attendance for the month of {0} , has already been marked for the Employee {1}",
+							[dialog.fields_dict.month.value, dialog.fields_dict.employee.value]));
 					} else {
-						frappe.confirm(__('Mark attendance as {0} for {1} on selected dates?', [data.status,data.month]), () => {
+						frappe.confirm(__('Mark attendance as {0} for {1} on selected dates?', [data.status, data.month]), () => {
 							frappe.call({
 								method: "erpnext.hr.doctype.attendance.attendance.mark_bulk_attendance",
 								args: {
 									data: data
 								},
-								callback: function(r) {
+								callback: function (r) {
 									if (r.message === 1) {
-										frappe.show_alert({message: __("Attendance Marked"), indicator: 'blue'});
+										frappe.show_alert({
+											message: __("Attendance Marked"),
+											indicator: 'blue'
+										});
 										cur_dialog.hide();
 									}
 								}
@@ -101,21 +104,26 @@
 			dialog.show();
 		});
 	},
-	get_multi_select_options: function(employee, month){
+
+	get_multi_select_options: function(employee, month) {
 		return new Promise(resolve => {
 			frappe.call({
 				method: 'erpnext.hr.doctype.attendance.attendance.get_unmarked_days',
 				async: false,
-				args:{
+				args: {
 					employee: employee,
 					month: month,
 				}
 			}).then(r => {
 				var options = [];
-				for(var d in r.message){
+				for (var d in r.message) {
 					var momentObj = moment(r.message[d], 'YYYY-MM-DD');
 					var date = momentObj.format('DD-MM-YYYY');
-					options.push({ "label":date, "value": r.message[d] , "checked": 1});
+					options.push({
+						"label": date,
+						"value": r.message[d],
+						"checked": 1
+					});
 				}
 				resolve(options);
 			});
diff --git a/erpnext/hr/doctype/employee/employee.js b/erpnext/hr/doctype/employee/employee.js
index 5639cc9..13b33e2 100755
--- a/erpnext/hr/doctype/employee/employee.js
+++ b/erpnext/hr/doctype/employee/employee.js
@@ -15,19 +15,20 @@
 	}
 
 	refresh() {
-		var me = this;
 		erpnext.toggle_naming_series();
 	}
 
 	date_of_birth() {
 		return cur_frm.call({
 			method: "get_retirement_date",
-			args: {date_of_birth: this.frm.doc.date_of_birth}
+			args: {
+				date_of_birth: this.frm.doc.date_of_birth
+			}
 		});
 	}
 
 	salutation() {
-		if(this.frm.doc.salutation) {
+		if (this.frm.doc.salutation) {
 			this.frm.set_value("gender", {
 				"Mr": "Male",
 				"Ms": "Female"
@@ -36,8 +37,9 @@
 	}
 
 };
-frappe.ui.form.on('Employee',{
-	setup: function(frm) {
+
+frappe.ui.form.on('Employee', {
+	setup: function (frm) {
 		frm.set_query("leave_policy", function() {
 			return {
 				"filters": {
@@ -46,7 +48,7 @@
 			};
 		});
 	},
-	onload:function(frm) {
+	onload: function (frm) {
 		frm.set_query("department", function() {
 			return {
 				"filters": {
@@ -55,23 +57,28 @@
 			};
 		});
 	},
-	prefered_contact_email:function(frm){
-		frm.events.update_contact(frm)
+	prefered_contact_email: function(frm) {
+		frm.events.update_contact(frm);
 	},
-	personal_email:function(frm){
-		frm.events.update_contact(frm)
+
+	personal_email: function(frm) {
+		frm.events.update_contact(frm);
 	},
-	company_email:function(frm){
-		frm.events.update_contact(frm)
+
+	company_email: function(frm) {
+		frm.events.update_contact(frm);
 	},
-	user_id:function(frm){
-		frm.events.update_contact(frm)
+
+	user_id: function(frm) {
+		frm.events.update_contact(frm);
 	},
-	update_contact:function(frm){
+
+	update_contact: function(frm) {
 		var prefered_email_fieldname = frappe.model.scrub(frm.doc.prefered_contact_email) || 'user_id';
 		frm.set_value("prefered_email",
-			frm.fields_dict[prefered_email_fieldname].value)
+			frm.fields_dict[prefered_email_fieldname].value);
 	},
+
 	status: function(frm) {
 		return frm.call({
 			method: "deactivate_sales_person",
@@ -81,19 +88,63 @@
 			}
 		});
 	},
+
 	create_user: function(frm) {
-		if (!frm.doc.prefered_email)
-		{
-			frappe.throw(__("Please enter Preferred Contact Email"))
+		if (!frm.doc.prefered_email) {
+			frappe.throw(__("Please enter Preferred Contact Email"));
 		}
 		frappe.call({
 			method: "erpnext.hr.doctype.employee.employee.create_user",
-			args: { employee: frm.doc.name, email: frm.doc.prefered_email },
-			callback: function(r)
-			{
-				frm.set_value("user_id", r.message)
+			args: {
+				employee: frm.doc.name,
+				email: frm.doc.prefered_email
+			},
+			callback: function (r) {
+				frm.set_value("user_id", r.message);
 			}
 		});
 	}
 });
-cur_frm.cscript = new erpnext.hr.EmployeeController({frm: cur_frm});
+
+cur_frm.cscript = new erpnext.hr.EmployeeController({
+	frm: cur_frm
+});
+
+
+frappe.tour['Employee'] = [
+	{
+		fieldname: "first_name",
+		title: "First Name",
+		description: __("Enter First and Last name of Employee, based on Which Full Name will be updated. IN transactions, it will be Full Name which will be fetched.")
+	},
+	{
+		fieldname: "company",
+		title: "Company",
+		description: __("Select a Company this Employee belongs to. Other HR features like Payroll. Expense Claims and Leaves for this Employee will be created for a given company only.")
+	},
+	{
+		fieldname: "date_of_birth",
+		title: "Date of Birth",
+		description: __("Select Date of Birth. This will validate Employees age and prevent hiring of under-age staff.")
+	},
+	{
+		fieldname: "date_of_joining",
+		title: "Date of Joining",
+		description: __("Select Date of joining. It will have impact on the first salary calculation, Leave allocation on pro-rata bases.")
+	},
+	{
+		fieldname: "holiday_list",
+		title: "Holiday List",
+		description: __("Select a default Holiday List for this Employee. The days listed in Holiday List will not be counted in Leave Application.")
+	},
+	{
+		fieldname: "reports_to",
+		title: "Reports To",
+		description: __("Here, you can select a senior of this Employee. Based on this, Organization Chart will be populated.")
+	},
+	{
+		fieldname: "leave_approver",
+		title: "Leave Approver",
+		description: __("Select  Leave Approver for an employee. The user one who will look after his/her Leave application")
+	},
+];
diff --git a/erpnext/hr/doctype/employee/employee_reminders.py b/erpnext/hr/doctype/employee/employee_reminders.py
index ba086dc..216d8f6 100644
--- a/erpnext/hr/doctype/employee/employee_reminders.py
+++ b/erpnext/hr/doctype/employee/employee_reminders.py
@@ -184,7 +184,7 @@
 # --------------------------
 def send_work_anniversary_reminders():
 	"""Send Employee Work Anniversary Reminders if 'Send Work Anniversary Reminders' is checked"""
-	to_send = int(frappe.db.get_single_value("HR Settings", "send_work_anniversary_reminders") or 1)
+	to_send = int(frappe.db.get_single_value("HR Settings", "send_work_anniversary_reminders"))
 	if not to_send:
 		return
 
diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.js b/erpnext/hr/doctype/employee_advance/employee_advance.js
index fa4b06a..7d1c7cb 100644
--- a/erpnext/hr/doctype/employee_advance/employee_advance.js
+++ b/erpnext/hr/doctype/employee_advance/employee_advance.js
@@ -73,7 +73,7 @@
 					frm.trigger('make_return_entry');
 				}, __('Create'));
 			} else if (frm.doc.repay_unclaimed_amount_from_salary == 1 && frappe.model.can_create("Additional Salary")) {
-				frm.add_custom_button(__("Deduction from salary"), function() {
+				frm.add_custom_button(__("Deduction from Salary"), function() {
 					frm.events.make_deduction_via_additional_salary(frm);
 				}, __('Create'));
 			}
diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.json b/erpnext/hr/doctype/employee_advance/employee_advance.json
index ea25aa7..0475453 100644
--- a/erpnext/hr/doctype/employee_advance/employee_advance.json
+++ b/erpnext/hr/doctype/employee_advance/employee_advance.json
@@ -170,7 +170,7 @@
    "default": "0",
    "fieldname": "repay_unclaimed_amount_from_salary",
    "fieldtype": "Check",
-   "label": "Repay unclaimed amount from salary"
+   "label": "Repay Unclaimed Amount from Salary"
   },
   {
    "depends_on": "eval:cur_frm.doc.employee",
@@ -200,10 +200,11 @@
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2021-03-31 22:31:53.746659",
+ "modified": "2021-09-11 18:38:38.617478",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Employee Advance",
+ "naming_rule": "By \"Naming Series\" field",
  "owner": "Administrator",
  "permissions": [
   {
diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.py b/erpnext/hr/doctype/employee_advance/employee_advance.py
index 87d42d3..8d90bcc 100644
--- a/erpnext/hr/doctype/employee_advance/employee_advance.py
+++ b/erpnext/hr/doctype/employee_advance/employee_advance.py
@@ -172,7 +172,10 @@
 @frappe.whitelist()
 def create_return_through_additional_salary(doc):
 	import json
-	doc = frappe._dict(json.loads(doc))
+
+	if isinstance(doc, str):
+		doc = frappe._dict(json.loads(doc))
+
 	additional_salary = frappe.new_doc('Additional Salary')
 	additional_salary.employee = doc.employee
 	additional_salary.currency = doc.currency
diff --git a/erpnext/hr/doctype/employee_advance/test_employee_advance.py b/erpnext/hr/doctype/employee_advance/test_employee_advance.py
index f8e5f53..c439d45 100644
--- a/erpnext/hr/doctype/employee_advance/test_employee_advance.py
+++ b/erpnext/hr/doctype/employee_advance/test_employee_advance.py
@@ -12,8 +12,11 @@
 from erpnext.hr.doctype.employee.test_employee import make_employee
 from erpnext.hr.doctype.employee_advance.employee_advance import (
 	EmployeeAdvanceOverPayment,
+	create_return_through_additional_salary,
 	make_bank_entry,
 )
+from erpnext.payroll.doctype.salary_component.test_salary_component import create_salary_component
+from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure
 
 
 class TestEmployeeAdvance(unittest.TestCase):
@@ -33,6 +36,46 @@
 		journal_entry1 = make_payment_entry(advance)
 		self.assertRaises(EmployeeAdvanceOverPayment, journal_entry1.submit)
 
+	def test_repay_unclaimed_amount_from_salary(self):
+		employee_name = make_employee("_T@employe.advance")
+		advance = make_employee_advance(employee_name, {"repay_unclaimed_amount_from_salary": 1})
+
+		args = {"type": "Deduction"}
+		create_salary_component("Advance Salary - Deduction", **args)
+		make_salary_structure("Test Additional Salary for Advance Return", "Monthly", employee=employee_name)
+
+		# additional salary for 700 first
+		advance.reload()
+		additional_salary = create_return_through_additional_salary(advance)
+		additional_salary.salary_component = "Advance Salary - Deduction"
+		additional_salary.payroll_date = nowdate()
+		additional_salary.amount = 700
+		additional_salary.insert()
+		additional_salary.submit()
+
+		advance.reload()
+		self.assertEqual(advance.return_amount, 700)
+
+		# additional salary for remaining 300
+		additional_salary = create_return_through_additional_salary(advance)
+		additional_salary.salary_component = "Advance Salary - Deduction"
+		additional_salary.payroll_date = nowdate()
+		additional_salary.amount = 300
+		additional_salary.insert()
+		additional_salary.submit()
+
+		advance.reload()
+		self.assertEqual(advance.return_amount, 1000)
+
+		# update advance return amount on additional salary cancellation
+		additional_salary.cancel()
+		advance.reload()
+		self.assertEqual(advance.return_amount, 700)
+
+	def tearDown(self):
+		frappe.db.rollback()
+
+
 def make_payment_entry(advance):
 	journal_entry = frappe.get_doc(make_bank_entry("Employee Advance", advance.name))
 	journal_entry.cheque_no = "123123"
@@ -41,7 +84,7 @@
 
 	return journal_entry
 
-def make_employee_advance(employee_name):
+def make_employee_advance(employee_name, args=None):
 	doc = frappe.new_doc("Employee Advance")
 	doc.employee = employee_name
 	doc.company  = "_Test company"
@@ -51,6 +94,10 @@
 	doc.advance_amount = 1000
 	doc.posting_date = nowdate()
 	doc.advance_account = "_Test Employee Advance - _TC"
+
+	if args:
+		doc.update(args)
+
 	doc.insert()
 	doc.submit()
 
diff --git a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py
index 7c751a4..1a1bcb2 100644
--- a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py
+++ b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py
@@ -55,8 +55,7 @@
 		else:
 			leave_type = None
 
-		if not company:
-			company = frappe.db.get_value("Employee", employee['employee'], "Company")
+		company = frappe.db.get_value("Employee", employee['employee'], "Company", cache=True)
 
 		attendance=frappe.get_doc(dict(
 			doctype='Attendance',
@@ -68,4 +67,4 @@
 			company=company
 		))
 		attendance.insert()
-		attendance.submit()
+		attendance.submit()
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py b/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py
index eae600d..1e3b9cb 100644
--- a/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py
+++ b/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py
@@ -71,6 +71,7 @@
 	applicant = frappe.new_doc('Job Applicant')
 	applicant.applicant_name = 'Test Researcher'
 	applicant.email_id = 'test@researcher.com'
+	applicant.designation = 'Researcher'
 	applicant.status = 'Open'
 	applicant.cover_letter = 'I am a great Researcher.'
 	applicant.insert()
diff --git a/erpnext/hr/doctype/employee_referral/employee_referral.py b/erpnext/hr/doctype/employee_referral/employee_referral.py
index 5cb5bb5..db356bf 100644
--- a/erpnext/hr/doctype/employee_referral/employee_referral.py
+++ b/erpnext/hr/doctype/employee_referral/employee_referral.py
@@ -38,8 +38,10 @@
 		status = "Open"
 
 	job_applicant = frappe.new_doc("Job Applicant")
+	job_applicant.source = "Employee Referral"
 	job_applicant.employee_referral = emp_ref.name
 	job_applicant.status = status
+	job_applicant.designation = emp_ref.for_designation
 	job_applicant.applicant_name = emp_ref.full_name
 	job_applicant.email_id = emp_ref.email
 	job_applicant.phone_number = emp_ref.contact_no
diff --git a/erpnext/hr/doctype/employee_referral/test_employee_referral.py b/erpnext/hr/doctype/employee_referral/test_employee_referral.py
index d0ee2fc..1340f62 100644
--- a/erpnext/hr/doctype/employee_referral/test_employee_referral.py
+++ b/erpnext/hr/doctype/employee_referral/test_employee_referral.py
@@ -17,6 +17,11 @@
 
 
 class TestEmployeeReferral(unittest.TestCase):
+
+	def setUp(self):
+		frappe.db.sql("DELETE FROM `tabJob Applicant`")
+		frappe.db.sql("DELETE FROM `tabEmployee Referral`")
+
 	def test_workflow_and_status_sync(self):
 		emp_ref = create_employee_referral()
 
@@ -50,6 +55,10 @@
 		add_sal = create_additional_salary(emp_ref)
 		self.assertTrue(add_sal.ref_docname, emp_ref.name)
 
+	def tearDown(self):
+		frappe.db.sql("DELETE FROM `tabJob Applicant`")
+		frappe.db.sql("DELETE FROM `tabEmployee Referral`")
+
 
 def create_employee_referral():
 	emp_ref = frappe.new_doc("Employee Referral")
diff --git a/erpnext/healthcare/doctype/body_part/__init__.py b/erpnext/hr/doctype/expected_skill_set/__init__.py
similarity index 100%
rename from erpnext/healthcare/doctype/body_part/__init__.py
rename to erpnext/hr/doctype/expected_skill_set/__init__.py
diff --git a/erpnext/hr/doctype/expected_skill_set/expected_skill_set.json b/erpnext/hr/doctype/expected_skill_set/expected_skill_set.json
new file mode 100644
index 0000000..899f5bd
--- /dev/null
+++ b/erpnext/hr/doctype/expected_skill_set/expected_skill_set.json
@@ -0,0 +1,40 @@
+{
+ "actions": [],
+ "creation": "2021-04-12 13:05:06.741330",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "skill",
+  "description"
+ ],
+ "fields": [
+  {
+   "fieldname": "skill",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Skill",
+   "options": "Skill",
+   "reqd": 1
+  },
+  {
+   "fetch_from": "skill.description",
+   "fieldname": "description",
+   "fieldtype": "Small Text",
+   "in_list_view": 1,
+   "label": "Description"
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2021-04-12 14:26:33.062549",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Expected Skill Set",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/expected_skill_set/expected_skill_set.py b/erpnext/hr/doctype/expected_skill_set/expected_skill_set.py
new file mode 100644
index 0000000..27120c1
--- /dev/null
+++ b/erpnext/hr/doctype/expected_skill_set/expected_skill_set.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, 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 ExpectedSkillSet(Document):
+	pass
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index 3c4c672..218e97d 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -10,6 +10,26 @@
 	},
 	company: function(frm) {
 		erpnext.accounts.dimensions.update_dimension(frm, frm.doctype);
+		var expenses = frm.doc.expenses;
+		for (var i = 0; i < expenses.length; i++) {
+			var expense = expenses[i];
+			if (!expense.expense_type) {
+				continue;
+			}
+			frappe.call({
+				method: "erpnext.hr.doctype.expense_claim.expense_claim.get_expense_claim_account_and_cost_center",
+				args: {
+					"expense_claim_type": expense.expense_type,
+					"company": frm.doc.company
+				},
+				callback: function(r) {
+					if (r.message) {
+						expense.default_account = r.message.account;
+						expense.cost_center = r.message.cost_center;
+					}
+				}
+			});
+		}
 	},
 });
 
diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
index 9cb65f7..941fd58 100644
--- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
@@ -176,7 +176,7 @@
 	account = create_account(company=company_name, account_name="Output Tax CGST", account_type="Tax", parent_account=parent_account)
 	return {'taxes':[{
 		"account_head": account,
-		"rate": 0,
+		"rate": 9,
 		"description": "CGST",
 		"tax_amount": 10,
 		"total": 210
diff --git a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
index 020457d..4a1064b 100644
--- a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
+++ b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
@@ -56,8 +56,6 @@
   },
   {
    "columns": 2,
-   "fetch_from": "account_head.tax_rate",
-   "fetch_if_empty": 1,
    "fieldname": "rate",
    "fieldtype": "Float",
    "in_list_view": 1,
@@ -111,4 +109,4 @@
  "sort_field": "modified",
  "sort_order": "ASC",
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/hr/doctype/holiday_list/holiday_list.js b/erpnext/hr/doctype/holiday_list/holiday_list.js
index 462bd8b..ea033c7 100644
--- a/erpnext/hr/doctype/holiday_list/holiday_list.js
+++ b/erpnext/hr/doctype/holiday_list/holiday_list.js
@@ -1,10 +1,10 @@
 // Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
 // For license information, please see license.txt
 
-frappe.ui.form.on('Holiday List', {
+frappe.ui.form.on("Holiday List", {
 	refresh: function(frm) {
 		if (frm.doc.holidays) {
-			frm.set_value('total_holidays', frm.doc.holidays.length);
+			frm.set_value("total_holidays", frm.doc.holidays.length);
 		}
 	},
 	from_date: function(frm) {
@@ -14,3 +14,36 @@
 		}
 	}
 });
+
+frappe.tour["Holiday List"] = [
+	{
+		fieldname: "holiday_list_name",
+		title: "Holiday List Name",
+		description: __("Enter a name for this Holiday List."),
+	},
+	{
+		fieldname: "from_date",
+		title: "From Date",
+		description: __("Based on your HR Policy, select your leave allocation period's start date"),
+	},
+	{
+		fieldname: "to_date",
+		title: "To Date",
+		description: __("Based on your HR Policy, select your leave allocation period's end date"),
+	},
+	{
+		fieldname: "weekly_off",
+		title: "Weekly Off",
+		description: __("Select your weekly off day"),
+	},
+	{
+		fieldname: "get_weekly_off_dates",
+		title: "Add Holidays",
+		description: __("Click on Add to Holidays. This will populate the holidays table with all the dates that fall on the selected weekly off. Repeat the process for populating the dates for all your weekly holidays"),
+	},
+	{
+		fieldname: "holidays",
+		title: "Holidays",
+		description: __("Here, your weekly offs are pre-populated based on the previous selections. You can add more rows to also add public and national holidays individually.")
+	},
+];
diff --git a/erpnext/hr/doctype/holiday_list/holiday_list.py b/erpnext/hr/doctype/holiday_list/holiday_list.py
index f46f14d..7d1b991 100644
--- a/erpnext/hr/doctype/holiday_list/holiday_list.py
+++ b/erpnext/hr/doctype/holiday_list/holiday_list.py
@@ -1,4 +1,3 @@
-
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
@@ -94,9 +93,11 @@
 		update={"allDay": 1})
 
 
-def is_holiday(holiday_list, date=today()):
+def is_holiday(holiday_list, date=None):
 	"""Returns true if the given date is a holiday in the given holiday list
 	"""
+	if date is None:
+		date = today()
 	if holiday_list:
 		return bool(frappe.get_all('Holiday List',
 			dict(name=holiday_list, holiday_date=date)))
diff --git a/erpnext/hr/doctype/hr_settings/hr_settings.js b/erpnext/hr/doctype/hr_settings/hr_settings.js
index ec99472..6e26a1f 100644
--- a/erpnext/hr/doctype/hr_settings/hr_settings.js
+++ b/erpnext/hr/doctype/hr_settings/hr_settings.js
@@ -2,7 +2,22 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on('HR Settings', {
-	restrict_backdated_leave_application: function(frm) {
-		frm.toggle_reqd("role_allowed_to_create_backdated_leave_application", frm.doc.restrict_backdated_leave_application);
-	}
 });
+
+frappe.tour['HR Settings'] = [
+	{
+		fieldname: 'emp_created_by',
+		title: 'Employee Naming By',
+		description: __('Employee can be named by Employee ID if you assign one, or via Naming Series. Select your preference here.'),
+	},
+	{
+		fieldname: 'standard_working_hours',
+		title: 'Standard Working Hours',
+		description: __('Enter the Standard Working Hours for a normal work day. These hours will be used in calculations of reports such as Employee Hours Utilization and Project Profitability analysis.'),
+	},
+	{
+		fieldname: 'leave_and_expense_claim_settings',
+		title: 'Leave and Expense Clain Settings',
+		description: __('Review various other settings related to Employee Leaves and Expense Claim')
+	}
+];
diff --git a/erpnext/hr/doctype/hr_settings/hr_settings.json b/erpnext/hr/doctype/hr_settings/hr_settings.json
index 8aa3c0c..5148435 100644
--- a/erpnext/hr/doctype/hr_settings/hr_settings.json
+++ b/erpnext/hr/doctype/hr_settings/hr_settings.json
@@ -7,30 +7,36 @@
  "engine": "InnoDB",
  "field_order": [
   "employee_settings",
-  "retirement_age",
   "emp_created_by",
-  "column_break_4",
   "standard_working_hours",
-  "expense_approver_mandatory_in_expense_claim",
+  "column_break_9",
+  "retirement_age",
   "reminders_section",
   "send_birthday_reminders",
-  "column_break_9",
-  "send_work_anniversary_reminders",
   "column_break_11",
+  "send_work_anniversary_reminders",
+  "column_break_18",
   "send_holiday_reminders",
   "frequency",
-  "leave_settings",
+  "leave_and_expense_claim_settings",
   "send_leave_notification",
   "leave_approval_notification_template",
   "leave_status_notification_template",
-  "role_allowed_to_create_backdated_leave_application",
-  "column_break_18",
   "leave_approver_mandatory_in_leave_application",
+  "restrict_backdated_leave_application",
+  "role_allowed_to_create_backdated_leave_application",
+  "column_break_29",
+  "expense_approver_mandatory_in_expense_claim",
   "show_leaves_of_all_department_members_in_calendar",
   "auto_leave_encashment",
-  "restrict_backdated_leave_application",
-  "hiring_settings",
-  "check_vacancies"
+  "hiring_settings_section",
+  "check_vacancies",
+  "send_interview_reminder",
+  "interview_reminder_template",
+  "remind_before",
+  "column_break_4",
+  "send_interview_feedback_reminder",
+  "feedback_reminder_notification_template"
  ],
  "fields": [
   {
@@ -39,17 +45,16 @@
    "label": "Employee Settings"
   },
   {
-   "description": "Enter retirement age in years",
    "fieldname": "retirement_age",
    "fieldtype": "Data",
-   "label": "Retirement Age"
+   "label": "Retirement Age (In Years)"
   },
   {
    "default": "Naming Series",
-   "description": "Employee records are created using the selected field",
+   "description": "Employee records are created using the selected option",
    "fieldname": "emp_created_by",
    "fieldtype": "Select",
-   "label": "Employee Records to be created by",
+   "label": "Employee Naming By",
    "options": "Naming Series\nEmployee Number\nFull Name"
   },
   {
@@ -63,28 +68,6 @@
    "label": "Expense Approver Mandatory In Expense Claim"
   },
   {
-   "collapsible": 1,
-   "fieldname": "leave_settings",
-   "fieldtype": "Section Break",
-   "label": "Leave Settings"
-  },
-  {
-   "depends_on": "eval: doc.send_leave_notification == 1",
-   "fieldname": "leave_approval_notification_template",
-   "fieldtype": "Link",
-   "label": "Leave Approval Notification Template",
-   "mandatory_depends_on": "eval: doc.send_leave_notification == 1",
-   "options": "Email Template"
-  },
-  {
-   "depends_on": "eval: doc.send_leave_notification == 1",
-   "fieldname": "leave_status_notification_template",
-   "fieldtype": "Link",
-   "label": "Leave Status Notification Template",
-   "mandatory_depends_on": "eval: doc.send_leave_notification == 1",
-   "options": "Email Template"
-  },
-  {
    "fieldname": "column_break_18",
    "fieldtype": "Column Break"
   },
@@ -101,34 +84,17 @@
    "label": "Show Leaves Of All Department Members In Calendar"
   },
   {
-   "collapsible": 1,
-   "fieldname": "hiring_settings",
-   "fieldtype": "Section Break",
-   "label": "Hiring Settings"
-  },
-  {
-   "default": "0",
-   "fieldname": "check_vacancies",
-   "fieldtype": "Check",
-   "label": "Check Vacancies On Job Offer Creation"
-  },
-  {
    "default": "0",
    "fieldname": "auto_leave_encashment",
    "fieldtype": "Check",
    "label": "Auto Leave Encashment"
   },
   {
-   "default": "0",
-   "fieldname": "restrict_backdated_leave_application",
-   "fieldtype": "Check",
-   "label": "Restrict Backdated Leave Application"
-  },
-  {
    "depends_on": "eval:doc.restrict_backdated_leave_application == 1",
    "fieldname": "role_allowed_to_create_backdated_leave_application",
    "fieldtype": "Link",
    "label": "Role Allowed to Create Backdated Leave Application",
+   "mandatory_depends_on": "eval:doc.restrict_backdated_leave_application == 1",
    "options": "Role"
   },
   {
@@ -138,12 +104,41 @@
    "label": "Send Leave Notification"
   },
   {
+   "depends_on": "eval: doc.send_leave_notification == 1",
+   "fieldname": "leave_approval_notification_template",
+   "fieldtype": "Link",
+   "label": "Leave Approval Notification Template",
+   "mandatory_depends_on": "eval: doc.send_leave_notification == 1",
+   "options": "Email Template"
+  },
+  {
+   "depends_on": "eval: doc.send_leave_notification == 1",
+   "fieldname": "leave_status_notification_template",
+   "fieldtype": "Link",
+   "label": "Leave Status Notification Template",
+   "mandatory_depends_on": "eval: doc.send_leave_notification == 1",
+   "options": "Email Template"
+  },
+  {
    "fieldname": "standard_working_hours",
    "fieldtype": "Int",
    "label": "Standard Working Hours"
   },
   {
    "collapsible": 1,
+   "fieldname": "leave_and_expense_claim_settings",
+   "fieldtype": "Section Break",
+   "label": "Leave and Expense Claim Settings"
+  },
+  {
+   "default": "00:15:00",
+   "depends_on": "send_interview_reminder",
+   "fieldname": "remind_before",
+   "fieldtype": "Time",
+   "label": "Remind Before"
+  },
+  {
+   "collapsible": 1,
    "fieldname": "reminders_section",
    "fieldtype": "Section Break",
    "label": "Reminders"
@@ -166,6 +161,7 @@
    "fieldname": "frequency",
    "fieldtype": "Select",
    "label": "Set the frequency for holiday reminders",
+   "mandatory_depends_on": "send_holiday_reminders",
    "options": "Weekly\nMonthly"
   },
   {
@@ -181,13 +177,62 @@
   {
    "fieldname": "column_break_11",
    "fieldtype": "Column Break"
+  },
+  {
+   "default": "0",
+   "fieldname": "send_interview_reminder",
+   "fieldtype": "Check",
+   "label": "Send Interview Reminder"
+  },
+  {
+   "default": "0",
+   "fieldname": "send_interview_feedback_reminder",
+   "fieldtype": "Check",
+   "label": "Send Interview Feedback Reminder"
+  },
+  {
+   "fieldname": "column_break_29",
+   "fieldtype": "Column Break"
+  },
+  {
+   "depends_on": "send_interview_feedback_reminder",
+   "fieldname": "feedback_reminder_notification_template",
+   "fieldtype": "Link",
+   "label": "Feedback Reminder Notification Template",
+   "mandatory_depends_on": "send_interview_feedback_reminder",
+   "options": "Email Template"
+  },
+  {
+   "depends_on": "send_interview_reminder",
+   "fieldname": "interview_reminder_template",
+   "fieldtype": "Link",
+   "label": "Interview Reminder Notification Template",
+   "mandatory_depends_on": "send_interview_reminder",
+   "options": "Email Template"
+  },
+  {
+   "default": "0",
+   "fieldname": "restrict_backdated_leave_application",
+   "fieldtype": "Check",
+   "label": "Restrict Backdated Leave Application"
+  },
+  {
+   "fieldname": "hiring_settings_section",
+   "fieldtype": "Section Break",
+   "label": "Hiring Settings"
+  },
+  {
+   "default": "0",
+   "fieldname": "check_vacancies",
+   "fieldtype": "Check",
+   "label": "Check Vacancies On Job Offer Creation"
   }
  ],
  "icon": "fa fa-cog",
  "idx": 1,
  "issingle": 1,
  "links": [],
- "modified": "2021-08-24 14:54:12.834162",
+ "modified": "2021-10-01 23:46:11.098236",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "HR Settings",
diff --git a/erpnext/healthcare/__init__.py b/erpnext/hr/doctype/interview/__init__.py
similarity index 100%
rename from erpnext/healthcare/__init__.py
rename to erpnext/hr/doctype/interview/__init__.py
diff --git a/erpnext/hr/doctype/interview/interview.js b/erpnext/hr/doctype/interview/interview.js
new file mode 100644
index 0000000..6341e3a
--- /dev/null
+++ b/erpnext/hr/doctype/interview/interview.js
@@ -0,0 +1,237 @@
+// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Interview', {
+	onload: function (frm) {
+		frm.events.set_job_applicant_query(frm);
+
+		frm.set_query('interviewer', 'interview_details', function () {
+			return {
+				query: 'erpnext.hr.doctype.interview.interview.get_interviewer_list'
+			};
+		});
+	},
+
+	refresh: function (frm) {
+		if (frm.doc.docstatus != 2 && !frm.doc.__islocal) {
+			if (frm.doc.status === 'Pending') {
+				frm.add_custom_button(__('Reschedule Interview'), function() {
+					frm.events.show_reschedule_dialog(frm);
+					frm.refresh();
+				});
+			}
+
+			let allowed_interviewers = [];
+			frm.doc.interview_details.forEach(values => {
+				allowed_interviewers.push(values.interviewer);
+			});
+
+			if ((allowed_interviewers.includes(frappe.session.user))) {
+				frappe.db.get_value('Interview Feedback', {'interviewer': frappe.session.user, 'interview': frm.doc.name, 'docstatus': 1}, 'name', (r) => {
+					if (Object.keys(r).length === 0) {
+						frm.add_custom_button(__('Submit Feedback'), function () {
+							frappe.call({
+								method: 'erpnext.hr.doctype.interview.interview.get_expected_skill_set',
+								args: {
+									interview_round: frm.doc.interview_round
+								},
+								callback: function (r) {
+									frm.events.show_feedback_dialog(frm, r.message);
+									frm.refresh();
+								}
+							});
+						}).addClass('btn-primary');
+					}
+				});
+			}
+		}
+	},
+
+	show_reschedule_dialog: function (frm) {
+		let d = new frappe.ui.Dialog({
+			title: 'Reschedule Interview',
+			fields: [
+				{
+					label: 'Schedule On',
+					fieldname: 'scheduled_on',
+					fieldtype: 'Date',
+					reqd: 1
+				},
+				{
+					label: 'From Time',
+					fieldname: 'from_time',
+					fieldtype: 'Time',
+					reqd: 1
+				},
+				{
+					label: 'To Time',
+					fieldname: 'to_time',
+					fieldtype: 'Time',
+					reqd: 1
+				}
+			],
+			primary_action_label: 'Reschedule',
+			primary_action(values) {
+				frm.call({
+					method: 'reschedule_interview',
+					doc: frm.doc,
+					args: {
+						scheduled_on: values.scheduled_on,
+						from_time: values.from_time,
+						to_time: values.to_time
+					}
+				}).then(() => {
+					frm.refresh();
+					d.hide();
+				});
+			}
+		});
+		d.show();
+	},
+
+	show_feedback_dialog: function (frm, data) {
+		let fields = frm.events.get_fields_for_feedback();
+
+		let d = new frappe.ui.Dialog({
+			title: __('Submit Feedback'),
+			fields: [
+				{
+					fieldname: 'skill_set',
+					fieldtype: 'Table',
+					label: __('Skill Assessment'),
+					cannot_add_rows: false,
+					in_editable_grid: true,
+					reqd: 1,
+					fields: fields,
+					data: data
+				},
+				{
+					fieldname: 'result',
+					fieldtype: 'Select',
+					options: ['', 'Cleared', 'Rejected'],
+					label: __('Result')
+				},
+				{
+					fieldname: 'feedback',
+					fieldtype: 'Small Text',
+					label: __('Feedback')
+				}
+			],
+			size: 'large',
+			minimizable: true,
+			primary_action: function(values) {
+				frappe.call({
+					method: 'erpnext.hr.doctype.interview.interview.create_interview_feedback',
+					args: {
+						data: values,
+						interview_name: frm.doc.name,
+						interviewer: frappe.session.user,
+						job_applicant: frm.doc.job_applicant
+					}
+				}).then(() => {
+					frm.refresh();
+				});
+				d.hide();
+			}
+		});
+		d.show();
+	},
+
+	get_fields_for_feedback: function () {
+		return [{
+			fieldtype: 'Link',
+			fieldname: 'skill',
+			options: 'Skill',
+			in_list_view: 1,
+			label: __('Skill')
+		}, {
+			fieldtype: 'Rating',
+			fieldname: 'rating',
+			label: __('Rating'),
+			in_list_view: 1,
+			reqd: 1,
+		}];
+	},
+
+	set_job_applicant_query: function (frm) {
+		frm.set_query('job_applicant', function () {
+			let job_applicant_filters = {
+				status: ['!=', 'Rejected']
+			};
+			if (frm.doc.designation) {
+				job_applicant_filters.designation = frm.doc.designation;
+			}
+			return {
+				filters: job_applicant_filters
+			};
+		});
+	},
+
+	interview_round: async function (frm) {
+		frm.events.reset_values(frm);
+		frm.set_value('job_applicant', '');
+
+		let round_data = (await frappe.db.get_value('Interview Round', frm.doc.interview_round, 'designation')).message;
+		frm.set_value('designation', round_data.designation);
+		frm.events.set_job_applicant_query(frm);
+
+		if (frm.doc.interview_round) {
+			frm.events.set_interview_details(frm);
+		} else {
+			frm.set_value('interview_details', []);
+		}
+	},
+
+	set_interview_details: function (frm) {
+		frappe.call({
+			method: 'erpnext.hr.doctype.interview.interview.get_interviewers',
+			args: {
+				interview_round: frm.doc.interview_round
+			},
+			callback: function (data) {
+				let interview_details = data.message;
+				frm.set_value('interview_details', []);
+				if (data.message.length) {
+					frm.set_value('interview_details', interview_details);
+				}
+			}
+		});
+	},
+
+	job_applicant: function (frm) {
+		if (!frm.doc.interview_round) {
+			frm.doc.job_applicant = '';
+			frm.refresh();
+			frappe.throw(__('Select Interview Round First'));
+		}
+
+		if (frm.doc.job_applicant) {
+			frm.events.set_designation_and_job_opening(frm);
+		} else {
+			frm.events.reset_values(frm);
+		}
+	},
+
+	set_designation_and_job_opening: async function (frm) {
+		let round_data = (await frappe.db.get_value('Interview Round', frm.doc.interview_round, 'designation')).message;
+		frm.set_value('designation', round_data.designation);
+		frm.events.set_job_applicant_query(frm);
+
+		let job_applicant_data = (await frappe.db.get_value(
+			'Job Applicant', frm.doc.job_applicant, ['designation', 'job_title', 'resume_link'],
+		)).message;
+
+		if (!round_data.designation) {
+			frm.set_value('designation', job_applicant_data.designation);
+		}
+
+		frm.set_value('job_opening', job_applicant_data.job_title);
+		frm.set_value('resume_link', job_applicant_data.resume_link);
+	},
+
+	reset_values: function (frm) {
+		frm.set_value('designation', '');
+		frm.set_value('job_opening', '');
+		frm.set_value('resume_link', '');
+	}
+});
diff --git a/erpnext/hr/doctype/interview/interview.json b/erpnext/hr/doctype/interview/interview.json
new file mode 100644
index 0000000..0d393e7
--- /dev/null
+++ b/erpnext/hr/doctype/interview/interview.json
@@ -0,0 +1,254 @@
+{
+ "actions": [],
+ "autoname": "HR-INT-.YYYY.-.####",
+ "creation": "2021-04-12 15:03:11.524090",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "interview_details_section",
+  "interview_round",
+  "job_applicant",
+  "job_opening",
+  "designation",
+  "resume_link",
+  "column_break_4",
+  "status",
+  "scheduled_on",
+  "from_time",
+  "to_time",
+  "interview_feedback_section",
+  "interview_details",
+  "ratings_section",
+  "expected_average_rating",
+  "column_break_12",
+  "average_rating",
+  "section_break_13",
+  "interview_summary",
+  "reminded",
+  "amended_from"
+ ],
+ "fields": [
+  {
+   "fieldname": "job_applicant",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
+   "label": "Job Applicant",
+   "options": "Job Applicant",
+   "reqd": 1
+  },
+  {
+   "fieldname": "job_opening",
+   "fieldtype": "Link",
+   "label": "Job Opening",
+   "options": "Job Opening",
+   "read_only": 1
+  },
+  {
+   "fieldname": "interview_round",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
+   "label": "Interview Round",
+   "options": "Interview Round",
+   "reqd": 1
+  },
+  {
+   "default": "Pending",
+   "fieldname": "status",
+   "fieldtype": "Select",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
+   "label": "Status",
+   "options": "Pending\nUnder Review\nCleared\nRejected",
+   "reqd": 1
+  },
+  {
+   "fieldname": "ratings_section",
+   "fieldtype": "Section Break",
+   "label": "Ratings"
+  },
+  {
+   "allow_on_submit": 1,
+   "fieldname": "average_rating",
+   "fieldtype": "Rating",
+   "in_list_view": 1,
+   "label": "Obtained Average Rating",
+   "read_only": 1
+  },
+  {
+   "allow_on_submit": 1,
+   "fieldname": "interview_summary",
+   "fieldtype": "Text"
+  },
+  {
+   "fieldname": "column_break_4",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "resume_link",
+   "fieldtype": "Data",
+   "label": "Resume link"
+  },
+  {
+   "fieldname": "interview_details_section",
+   "fieldtype": "Section Break",
+   "label": "Details"
+  },
+  {
+   "fetch_from": "interview_round.expected_average_rating",
+   "fieldname": "expected_average_rating",
+   "fieldtype": "Rating",
+   "label": "Expected Average Rating",
+   "read_only": 1
+  },
+  {
+   "collapsible": 1,
+   "fieldname": "section_break_13",
+   "fieldtype": "Section Break",
+   "label": "Interview Summary"
+  },
+  {
+   "fieldname": "column_break_12",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fetch_from": "interview_round.designation",
+   "fieldname": "designation",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
+   "label": "Designation",
+   "options": "Designation",
+   "read_only": 1
+  },
+  {
+   "fieldname": "amended_from",
+   "fieldtype": "Link",
+   "label": "Amended From",
+   "no_copy": 1,
+   "options": "Interview",
+   "print_hide": 1,
+   "read_only": 1
+  },
+  {
+   "fieldname": "scheduled_on",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
+   "label": "Scheduled On",
+   "reqd": 1,
+   "set_only_once": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "reminded",
+   "fieldtype": "Check",
+   "hidden": 1,
+   "label": "Reminded"
+  },
+  {
+   "allow_on_submit": 1,
+   "fieldname": "interview_details",
+   "fieldtype": "Table",
+   "options": "Interview Detail"
+  },
+  {
+   "fieldname": "interview_feedback_section",
+   "fieldtype": "Section Break",
+   "label": "Feedback"
+  },
+  {
+   "fieldname": "from_time",
+   "fieldtype": "Time",
+   "in_list_view": 1,
+   "label": "From Time",
+   "reqd": 1,
+   "set_only_once": 1
+  },
+  {
+   "fieldname": "to_time",
+   "fieldtype": "Time",
+   "in_list_view": 1,
+   "label": "To Time",
+   "reqd": 1,
+   "set_only_once": 1
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "is_submittable": 1,
+ "links": [
+  {
+   "link_doctype": "Interview Feedback",
+   "link_fieldname": "interview"
+  }
+ ],
+ "modified": "2021-09-30 13:30:05.421035",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Interview",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  },
+  {
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "HR Manager",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  },
+  {
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Interviewer",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  },
+  {
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "HR User",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "job_applicant",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/interview/interview.py b/erpnext/hr/doctype/interview/interview.py
new file mode 100644
index 0000000..955acca
--- /dev/null
+++ b/erpnext/hr/doctype/interview/interview.py
@@ -0,0 +1,293 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+
+import datetime
+
+import frappe
+from frappe import _
+from frappe.model.document import Document
+from frappe.utils import cstr, get_datetime, get_link_to_form
+
+
+class DuplicateInterviewRoundError(frappe.ValidationError):
+	pass
+
+class Interview(Document):
+	def validate(self):
+		self.validate_duplicate_interview()
+		self.validate_designation()
+		self.validate_overlap()
+
+	def on_submit(self):
+		if self.status not in ['Cleared', 'Rejected']:
+			frappe.throw(_('Only Interviews with Cleared or Rejected status can be submitted.'), title=_('Not Allowed'))
+
+	def validate_duplicate_interview(self):
+		duplicate_interview = frappe.db.exists('Interview', {
+				'job_applicant': self.job_applicant,
+				'interview_round': self.interview_round,
+				'docstatus': 1
+			}
+		)
+
+		if duplicate_interview:
+			frappe.throw(_('Job Applicants are not allowed to appear twice for the same Interview round. Interview {0} already scheduled for Job Applicant {1}').format(
+				frappe.bold(get_link_to_form('Interview', duplicate_interview)),
+				frappe.bold(self.job_applicant)
+			))
+
+	def validate_designation(self):
+		applicant_designation = frappe.db.get_value('Job Applicant', self.job_applicant, 'designation')
+		if self.designation :
+			if self.designation != applicant_designation:
+				frappe.throw(_('Interview Round {0} is only for Designation {1}. Job Applicant has applied for the role {2}').format(
+					self.interview_round, frappe.bold(self.designation), applicant_designation),
+					exc=DuplicateInterviewRoundError)
+		else:
+			self.designation = applicant_designation
+
+	def validate_overlap(self):
+		interviewers = [entry.interviewer for entry in self.interview_details] or ['']
+
+		overlaps = frappe.db.sql("""
+			SELECT interview.name
+			FROM `tabInterview` as interview
+			INNER JOIN `tabInterview Detail` as detail
+			WHERE
+				interview.scheduled_on = %s and interview.name != %s and interview.docstatus != 2
+				and (interview.job_applicant = %s or detail.interviewer IN %s) and
+				((from_time < %s and to_time > %s) or
+				(from_time > %s and to_time < %s) or
+				(from_time = %s))
+			""", (self.scheduled_on, self.name, self.job_applicant, interviewers,
+			self.from_time, self.to_time, self.from_time, self.to_time, self.from_time))
+
+		if overlaps:
+			overlapping_details = _('Interview overlaps with {0}').format(get_link_to_form('Interview', overlaps[0][0]))
+			frappe.throw(overlapping_details, title=_('Overlap'))
+
+
+	@frappe.whitelist()
+	def reschedule_interview(self, scheduled_on, from_time, to_time):
+		original_date = self.scheduled_on
+		from_time = self.from_time
+		to_time = self.to_time
+
+		self.db_set({
+			'scheduled_on': scheduled_on,
+			'from_time': from_time,
+			'to_time': to_time
+		})
+		self.notify_update()
+
+		recipients = get_recipients(self.name)
+
+		try:
+			frappe.sendmail(
+				recipients= recipients,
+				subject=_('Interview: {0} Rescheduled').format(self.name),
+				message=_('Your Interview session is rescheduled from {0} {1} - {2} to {3} {4} - {5}').format(
+					original_date, from_time, to_time, self.scheduled_on, self.from_time, self.to_time),
+				reference_doctype=self.doctype,
+				reference_name=self.name
+			)
+		except Exception:
+			frappe.msgprint(_('Failed to send the Interview Reschedule notification. Please configure your email account.'))
+
+		frappe.msgprint(_('Interview Rescheduled successfully'), indicator='green')
+
+
+def get_recipients(name, for_feedback=0):
+	interview = frappe.get_doc('Interview', name)
+
+	if for_feedback:
+		recipients = [d.interviewer for d in interview.interview_details if not d.interview_feedback]
+	else:
+		recipients = [d.interviewer for d in interview.interview_details]
+		recipients.append(frappe.db.get_value('Job Applicant', interview.job_applicant, 'email_id'))
+
+	return recipients
+
+
+@frappe.whitelist()
+def get_interviewers(interview_round):
+	return frappe.get_all('Interviewer', filters={'parent': interview_round}, fields=['user as interviewer'])
+
+
+def send_interview_reminder():
+	reminder_settings = frappe.db.get_value('HR Settings', 'HR Settings',
+		['send_interview_reminder', 'interview_reminder_template'], as_dict=True)
+
+	if not reminder_settings.send_interview_reminder:
+		return
+
+	remind_before = cstr(frappe.db.get_single_value('HR Settings', 'remind_before')) or '01:00:00'
+	remind_before = datetime.datetime.strptime(remind_before, '%H:%M:%S')
+	reminder_date_time = datetime.datetime.now() + datetime.timedelta(
+		hours=remind_before.hour, minutes=remind_before.minute, seconds=remind_before.second)
+
+	interviews = frappe.get_all('Interview', filters={
+		'scheduled_on': ['between', (datetime.datetime.now(), reminder_date_time)],
+		'status': 'Pending',
+		'reminded': 0,
+		'docstatus': ['!=', 2]
+	})
+
+	interview_template = frappe.get_doc('Email Template', reminder_settings.interview_reminder_template)
+
+	for d in interviews:
+		doc = frappe.get_doc('Interview', d.name)
+		context = doc.as_dict()
+		message = frappe.render_template(interview_template.response, context)
+		recipients = get_recipients(doc.name)
+
+		frappe.sendmail(
+			recipients= recipients,
+			subject=interview_template.subject,
+			message=message,
+			reference_doctype=doc.doctype,
+			reference_name=doc.name
+		)
+
+		doc.db_set('reminded', 1)
+
+
+def send_daily_feedback_reminder():
+	reminder_settings = frappe.db.get_value('HR Settings', 'HR Settings',
+		['send_interview_feedback_reminder', 'feedback_reminder_notification_template'], as_dict=True)
+
+	if not reminder_settings.send_interview_feedback_reminder:
+		return
+
+	interview_feedback_template = frappe.get_doc('Email Template', reminder_settings.feedback_reminder_notification_template)
+	interviews = frappe.get_all('Interview', filters={'status': ['in', ['Under Review', 'Pending']], 'docstatus': ['!=', 2]})
+
+	for entry in interviews:
+		recipients = get_recipients(entry.name, for_feedback=1)
+
+		doc = frappe.get_doc('Interview', entry.name)
+		context = doc.as_dict()
+
+		message = frappe.render_template(interview_feedback_template.response, context)
+
+		if len(recipients):
+			frappe.sendmail(
+				recipients= recipients,
+				subject=interview_feedback_template.subject,
+				message=message,
+				reference_doctype='Interview',
+				reference_name=entry.name
+			)
+
+
+@frappe.whitelist()
+def get_expected_skill_set(interview_round):
+	return frappe.get_all('Expected Skill Set', filters ={'parent': interview_round}, fields=['skill'])
+
+
+@frappe.whitelist()
+def create_interview_feedback(data, interview_name, interviewer, job_applicant):
+	import json
+
+	from six import string_types
+
+	if isinstance(data, string_types):
+		data = frappe._dict(json.loads(data))
+
+	if frappe.session.user != interviewer:
+		frappe.throw(_('Only Interviewer Are allowed to submit Interview Feedback'))
+
+	interview_feedback = frappe.new_doc('Interview Feedback')
+	interview_feedback.interview = interview_name
+	interview_feedback.interviewer = interviewer
+	interview_feedback.job_applicant = job_applicant
+
+	for d in data.skill_set:
+		d = frappe._dict(d)
+		interview_feedback.append('skill_assessment', {'skill': d.skill, 'rating': d.rating})
+
+	interview_feedback.feedback = data.feedback
+	interview_feedback.result = data.result
+
+	interview_feedback.save()
+	interview_feedback.submit()
+
+	frappe.msgprint(_('Interview Feedback {0} submitted successfully').format(
+		get_link_to_form('Interview Feedback', interview_feedback.name)))
+
+
+@frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
+def get_interviewer_list(doctype, txt, searchfield, start, page_len, filters):
+	filters = [
+		['Has Role', 'parent', 'like', '%{}%'.format(txt)],
+		['Has Role', 'role', '=', 'interviewer'],
+		['Has Role', 'parenttype', '=', 'User']
+	]
+
+	if filters and isinstance(filters, list):
+		filters.extend(filters)
+
+	return frappe.get_all('Has Role', limit_start=start, limit_page_length=page_len,
+		filters=filters, fields = ['parent'], as_list=1)
+
+
+@frappe.whitelist()
+def get_events(start, end, filters=None):
+	"""Returns events for Gantt / Calendar view rendering.
+
+	:param start: Start date-time.
+	:param end: End date-time.
+	:param filters: Filters (JSON).
+	"""
+	from frappe.desk.calendar import get_event_conditions
+
+	events = []
+
+	event_color = {
+		"Pending": "#fff4f0",
+		"Under Review": "#d3e8fc",
+		"Cleared": "#eaf5ed",
+		"Rejected": "#fce7e7"
+	}
+
+	conditions = get_event_conditions('Interview', filters)
+
+	interviews = frappe.db.sql("""
+			SELECT DISTINCT
+				`tabInterview`.name, `tabInterview`.job_applicant, `tabInterview`.interview_round,
+				`tabInterview`.scheduled_on, `tabInterview`.status, `tabInterview`.from_time as from_time,
+				`tabInterview`.to_time as to_time
+			from
+				`tabInterview`
+			where
+				(`tabInterview`.scheduled_on between %(start)s and %(end)s)
+				and docstatus != 2
+				{conditions}
+			""".format(conditions=conditions), {
+				"start": start,
+				"end": end
+			}, as_dict=True, update={"allDay": 0})
+
+	for d in interviews:
+		subject_data = []
+		for field in ["name", "job_applicant", "interview_round"]:
+			if not d.get(field):
+				continue
+			subject_data.append(d.get(field))
+
+		color = event_color.get(d.status)
+		interview_data = {
+			'from': get_datetime('%s %s' % (d.scheduled_on, d.from_time or '00:00:00')),
+			'to': get_datetime('%s %s' % (d.scheduled_on, d.to_time or '00:00:00')),
+			'name': d.name,
+			'subject': '\n'.join(subject_data),
+			'color': color if color else "#89bcde"
+		}
+
+		events.append(interview_data)
+
+	return events
\ No newline at end of file
diff --git a/erpnext/hr/doctype/interview/interview_calendar.js b/erpnext/hr/doctype/interview/interview_calendar.js
new file mode 100644
index 0000000..b46b72e
--- /dev/null
+++ b/erpnext/hr/doctype/interview/interview_calendar.js
@@ -0,0 +1,14 @@
+
+frappe.views.calendar['Interview'] = {
+	field_map: {
+		'start': 'from',
+		'end': 'to',
+		'id': 'name',
+		'title': 'subject',
+		'allDay': 'allDay',
+		'color': 'color'
+	},
+	order_by: 'scheduled_on',
+	gantt: true,
+	get_events_method: 'erpnext.hr.doctype.interview.interview.get_events'
+};
diff --git a/erpnext/hr/doctype/interview/interview_feedback_reminder_template.html b/erpnext/hr/doctype/interview/interview_feedback_reminder_template.html
new file mode 100644
index 0000000..8d39fb5
--- /dev/null
+++ b/erpnext/hr/doctype/interview/interview_feedback_reminder_template.html
@@ -0,0 +1,5 @@
+<h1>Interview Feedback Reminder</h1>
+
+<p>
+	Interview Feedback for Interview {{ name }} is not submitted yet. Please submit your feedback. Thank you, good day!
+</p>
diff --git a/erpnext/hr/doctype/interview/interview_list.js b/erpnext/hr/doctype/interview/interview_list.js
new file mode 100644
index 0000000..b1f072f
--- /dev/null
+++ b/erpnext/hr/doctype/interview/interview_list.js
@@ -0,0 +1,12 @@
+frappe.listview_settings['Interview'] = {
+	has_indicator_for_draft: 1,
+	get_indicator: function(doc) {
+		let status_color = {
+			'Pending': 'orange',
+			'Under Review': 'blue',
+			'Cleared': 'green',
+			'Rejected': 'red',
+		};
+		return [__(doc.status), status_color[doc.status], 'status,=,'+doc.status];
+	}
+};
diff --git a/erpnext/hr/doctype/interview/interview_reminder_notification_template.html b/erpnext/hr/doctype/interview/interview_reminder_notification_template.html
new file mode 100644
index 0000000..76de46e
--- /dev/null
+++ b/erpnext/hr/doctype/interview/interview_reminder_notification_template.html
@@ -0,0 +1,5 @@
+<h1>Interview Reminder</h1>
+
+<p>
+	Interview: {{name}} is scheduled on {{scheduled_on}} from {{from_time}} to {{to_time}}
+</p>
diff --git a/erpnext/hr/doctype/interview/test_interview.py b/erpnext/hr/doctype/interview/test_interview.py
new file mode 100644
index 0000000..4612e17
--- /dev/null
+++ b/erpnext/hr/doctype/interview/test_interview.py
@@ -0,0 +1,174 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import datetime
+import os
+import unittest
+
+import frappe
+from frappe import _
+from frappe.core.doctype.user_permission.test_user_permission import create_user
+from frappe.utils import add_days, getdate, nowtime
+
+from erpnext.hr.doctype.designation.test_designation import create_designation
+from erpnext.hr.doctype.interview.interview import DuplicateInterviewRoundError
+from erpnext.hr.doctype.job_applicant.test_job_applicant import create_job_applicant
+
+
+class TestInterview(unittest.TestCase):
+	def test_validations_for_designation(self):
+		job_applicant = create_job_applicant()
+		interview = create_interview_and_dependencies(job_applicant.name, designation='_Test_Sales_manager', save=0)
+		self.assertRaises(DuplicateInterviewRoundError, interview.save)
+
+	def test_notification_on_rescheduling(self):
+		job_applicant = create_job_applicant()
+		interview = create_interview_and_dependencies(job_applicant.name, scheduled_on=add_days(getdate(), -4))
+
+		previous_scheduled_date = interview.scheduled_on
+		frappe.db.sql("DELETE FROM `tabEmail Queue`")
+
+		interview.reschedule_interview(add_days(getdate(previous_scheduled_date), 2),
+			from_time=nowtime(), to_time=nowtime())
+		interview.reload()
+
+		self.assertEqual(interview.scheduled_on, add_days(getdate(previous_scheduled_date), 2))
+
+		notification = frappe.get_all("Email Queue", filters={"message": ("like", "%Your Interview session is rescheduled from%")})
+		self.assertIsNotNone(notification)
+
+	def test_notification_for_scheduling(self):
+		from erpnext.hr.doctype.interview.interview import send_interview_reminder
+
+		setup_reminder_settings()
+
+		job_applicant = create_job_applicant()
+		scheduled_on = datetime.datetime.now() + datetime.timedelta(minutes=10)
+
+		interview = create_interview_and_dependencies(job_applicant.name, scheduled_on=scheduled_on)
+
+		frappe.db.sql("DELETE FROM `tabEmail Queue`")
+		send_interview_reminder()
+
+		interview.reload()
+
+		email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True)
+		self.assertTrue("Subject: Interview Reminder" in email_queue[0].message)
+
+	def test_notification_for_feedback_submission(self):
+		from erpnext.hr.doctype.interview.interview import send_daily_feedback_reminder
+
+		setup_reminder_settings()
+
+		job_applicant = create_job_applicant()
+		scheduled_on = add_days(getdate(), -4)
+		create_interview_and_dependencies(job_applicant.name, scheduled_on=scheduled_on)
+
+		frappe.db.sql("DELETE FROM `tabEmail Queue`")
+		send_daily_feedback_reminder()
+
+		email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True)
+		self.assertTrue("Subject: Interview Feedback Reminder" in email_queue[0].message)
+
+	def tearDown(self):
+		frappe.db.rollback()
+
+
+def create_interview_and_dependencies(job_applicant, scheduled_on=None, from_time=None, to_time=None, designation=None, save=1):
+	if designation:
+		designation=create_designation(designation_name = "_Test_Sales_manager").name
+
+	interviewer_1 = create_user("test_interviewer1@example.com", "Interviewer")
+	interviewer_2 = create_user("test_interviewer2@example.com", "Interviewer")
+
+	interview_round = create_interview_round(
+		"Technical Round", ["Python", "JS"],
+		designation=designation, save=True
+	)
+
+	interview = frappe.new_doc("Interview")
+	interview.interview_round = interview_round.name
+	interview.job_applicant = job_applicant
+	interview.scheduled_on = scheduled_on or getdate()
+	interview.from_time = from_time or nowtime()
+	interview.to_time = to_time or nowtime()
+
+	interview.append("interview_details", {"interviewer": interviewer_1.name})
+	interview.append("interview_details", {"interviewer": interviewer_2.name})
+
+	if save:
+		interview.save()
+
+	return interview
+
+def create_interview_round(name, skill_set, interviewers=[], designation=None, save=True):
+	create_skill_set(skill_set)
+	interview_round = frappe.new_doc("Interview Round")
+	interview_round.round_name = name
+	interview_round.interview_type = create_interview_type()
+	interview_round.expected_average_rating = 4
+	if designation:
+		interview_round.designation = designation
+
+	for skill in skill_set:
+		interview_round.append("expected_skill_set", {"skill": skill})
+
+	for interviewer in interviewers:
+		interview_round.append("interviewer", {
+			"user": interviewer
+		})
+
+	if save:
+		interview_round.save()
+
+	return interview_round
+
+def create_skill_set(skill_set):
+	for skill in skill_set:
+		if not frappe.db.exists("Skill", skill):
+			doc = frappe.new_doc("Skill")
+			doc.skill_name = skill
+			doc.save()
+
+def create_interview_type(name="test_interview_type"):
+	if frappe.db.exists("Interview Type", name):
+		return frappe.get_doc("Interview Type", name).name
+	else:
+		doc = frappe.new_doc("Interview Type")
+		doc.name = name
+		doc.description = "_Test_Description"
+		doc.save()
+
+		return doc.name
+
+def setup_reminder_settings():
+	if not frappe.db.exists('Email Template', _('Interview Reminder')):
+		base_path = frappe.get_app_path('erpnext', 'hr', 'doctype')
+		response = frappe.read_file(os.path.join(base_path, 'interview/interview_reminder_notification_template.html'))
+
+		frappe.get_doc({
+			'doctype': 'Email Template',
+			'name': _('Interview Reminder'),
+			'response': response,
+			'subject': _('Interview Reminder'),
+			'owner': frappe.session.user,
+		}).insert(ignore_permissions=True)
+
+	if not frappe.db.exists('Email Template', _('Interview Feedback Reminder')):
+		base_path = frappe.get_app_path('erpnext', 'hr', 'doctype')
+		response = frappe.read_file(os.path.join(base_path, 'interview/interview_feedback_reminder_template.html'))
+
+		frappe.get_doc({
+			'doctype': 'Email Template',
+			'name': _('Interview Feedback Reminder'),
+			'response': response,
+			'subject': _('Interview Feedback Reminder'),
+			'owner': frappe.session.user,
+		}).insert(ignore_permissions=True)
+
+	hr_settings = frappe.get_doc('HR Settings')
+	hr_settings.interview_reminder_template = _('Interview Reminder')
+	hr_settings.feedback_reminder_notification_template = _('Interview Feedback Reminder')
+	hr_settings.save()
diff --git a/erpnext/healthcare/doctype/therapy_plan_detail/__init__.py b/erpnext/hr/doctype/interview_detail/__init__.py
similarity index 100%
rename from erpnext/healthcare/doctype/therapy_plan_detail/__init__.py
rename to erpnext/hr/doctype/interview_detail/__init__.py
diff --git a/erpnext/hr/doctype/interview_detail/interview_detail.js b/erpnext/hr/doctype/interview_detail/interview_detail.js
new file mode 100644
index 0000000..88518ca
--- /dev/null
+++ b/erpnext/hr/doctype/interview_detail/interview_detail.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Interview Detail', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/hr/doctype/interview_detail/interview_detail.json b/erpnext/hr/doctype/interview_detail/interview_detail.json
new file mode 100644
index 0000000..b5b49c0
--- /dev/null
+++ b/erpnext/hr/doctype/interview_detail/interview_detail.json
@@ -0,0 +1,74 @@
+{
+ "actions": [],
+ "creation": "2021-04-12 16:24:10.382863",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "interviewer",
+  "interview_feedback",
+  "average_rating",
+  "result",
+  "column_break_4",
+  "comments"
+ ],
+ "fields": [
+  {
+   "fieldname": "interviewer",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Interviewer",
+   "options": "User"
+  },
+  {
+   "allow_on_submit": 1,
+   "fieldname": "interview_feedback",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Interview Feedback",
+   "options": "Interview Feedback",
+   "read_only": 1
+  },
+  {
+   "allow_on_submit": 1,
+   "fieldname": "average_rating",
+   "fieldtype": "Rating",
+   "in_list_view": 1,
+   "label": "Average Rating",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_4",
+   "fieldtype": "Column Break"
+  },
+  {
+   "allow_on_submit": 1,
+   "fetch_from": "interview_feedback.feedback",
+   "fieldname": "comments",
+   "fieldtype": "Text",
+   "label": "Comments",
+   "read_only": 1
+  },
+  {
+   "allow_on_submit": 1,
+   "fieldname": "result",
+   "fieldtype": "Select",
+   "in_list_view": 1,
+   "label": "Result",
+   "options": "\nCleared\nRejected",
+   "read_only": 1
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2021-09-29 13:13:25.865063",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Interview Detail",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/interview_detail/interview_detail.py b/erpnext/hr/doctype/interview_detail/interview_detail.py
new file mode 100644
index 0000000..8be3d34
--- /dev/null
+++ b/erpnext/hr/doctype/interview_detail/interview_detail.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, 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 InterviewDetail(Document):
+	pass
diff --git a/erpnext/hr/doctype/interview_detail/test_interview_detail.py b/erpnext/hr/doctype/interview_detail/test_interview_detail.py
new file mode 100644
index 0000000..a29dfff
--- /dev/null
+++ b/erpnext/hr/doctype/interview_detail/test_interview_detail.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+
+class TestInterviewDetail(unittest.TestCase):
+	pass
diff --git a/erpnext/healthcare/__init__.py b/erpnext/hr/doctype/interview_feedback/__init__.py
similarity index 100%
copy from erpnext/healthcare/__init__.py
copy to erpnext/hr/doctype/interview_feedback/__init__.py
diff --git a/erpnext/hr/doctype/interview_feedback/interview_feedback.js b/erpnext/hr/doctype/interview_feedback/interview_feedback.js
new file mode 100644
index 0000000..dec559f
--- /dev/null
+++ b/erpnext/hr/doctype/interview_feedback/interview_feedback.js
@@ -0,0 +1,54 @@
+// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Interview Feedback', {
+	onload: function(frm) {
+		frm.ignore_doctypes_on_cancel_all = ['Interview'];
+
+		frm.set_query('interview', function() {
+			return {
+				filters: {
+					docstatus: ['!=', 2]
+				}
+			};
+		});
+	},
+
+	interview_round: function(frm) {
+		frappe.call({
+			method: 'erpnext.hr.doctype.interview.interview.get_expected_skill_set',
+			args: {
+				interview_round: frm.doc.interview_round
+			},
+			callback: function(r) {
+				frm.set_value('skill_assessment', r.message);
+			}
+		});
+	},
+
+	interview: function(frm) {
+		frappe.call({
+			method: 'erpnext.hr.doctype.interview_feedback.interview_feedback.get_applicable_interviewers',
+			args: {
+				interview: frm.doc.interview || ''
+			},
+			callback: function(r) {
+				frm.set_query('interviewer', function() {
+					return {
+						filters: {
+							name: ['in', r.message]
+						}
+					};
+				});
+			}
+		});
+
+	},
+
+	interviewer: function(frm) {
+		if (!frm.doc.interview) {
+			frappe.throw(__('Select Interview first'));
+			frm.set_value('interviewer', '');
+		}
+	}
+});
diff --git a/erpnext/hr/doctype/interview_feedback/interview_feedback.json b/erpnext/hr/doctype/interview_feedback/interview_feedback.json
new file mode 100644
index 0000000..6a2f7e8
--- /dev/null
+++ b/erpnext/hr/doctype/interview_feedback/interview_feedback.json
@@ -0,0 +1,171 @@
+{
+ "actions": [],
+ "autoname": "HR-INT-FEED-.####",
+ "creation": "2021-04-12 17:03:13.833285",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "details_section",
+  "interview",
+  "interview_round",
+  "job_applicant",
+  "column_break_3",
+  "interviewer",
+  "result",
+  "section_break_4",
+  "skill_assessment",
+  "average_rating",
+  "section_break_7",
+  "feedback",
+  "amended_from"
+ ],
+ "fields": [
+  {
+   "allow_in_quick_entry": 1,
+   "fieldname": "interview",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
+   "label": "Interview",
+   "options": "Interview",
+   "reqd": 1
+  },
+  {
+   "allow_in_quick_entry": 1,
+   "fetch_from": "interview.interview_round",
+   "fieldname": "interview_round",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
+   "label": "Interview Round",
+   "options": "Interview Round",
+   "read_only": 1,
+   "reqd": 1
+  },
+  {
+   "allow_in_quick_entry": 1,
+   "fieldname": "interviewer",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
+   "label": "Interviewer",
+   "options": "User",
+   "reqd": 1
+  },
+  {
+   "fieldname": "section_break_4",
+   "fieldtype": "Section Break",
+   "label": "Skill Assessment"
+  },
+  {
+   "allow_in_quick_entry": 1,
+   "fieldname": "skill_assessment",
+   "fieldtype": "Table",
+   "options": "Skill Assessment",
+   "reqd": 1
+  },
+  {
+   "allow_in_quick_entry": 1,
+   "fieldname": "average_rating",
+   "fieldtype": "Rating",
+   "in_list_view": 1,
+   "label": "Average Rating",
+   "read_only": 1
+  },
+  {
+   "fieldname": "section_break_7",
+   "fieldtype": "Section Break",
+   "label": "Feedback"
+  },
+  {
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "amended_from",
+   "fieldtype": "Link",
+   "label": "Amended From",
+   "no_copy": 1,
+   "options": "Interview Feedback",
+   "print_hide": 1,
+   "read_only": 1
+  },
+  {
+   "allow_in_quick_entry": 1,
+   "fieldname": "feedback",
+   "fieldtype": "Text"
+  },
+  {
+   "fieldname": "result",
+   "fieldtype": "Select",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
+   "label": "Result",
+   "options": "\nCleared\nRejected",
+   "reqd": 1
+  },
+  {
+   "fieldname": "details_section",
+   "fieldtype": "Section Break",
+   "label": "Details"
+  },
+  {
+   "fetch_from": "interview.job_applicant",
+   "fieldname": "job_applicant",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
+   "label": "Job Applicant",
+   "options": "Job Applicant",
+   "read_only": 1
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2021-09-30 13:30:49.955352",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Interview Feedback",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "HR Manager",
+   "share": 1
+  },
+  {
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Interviewer",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  },
+  {
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "HR User",
+   "share": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "interviewer",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/interview_feedback/interview_feedback.py b/erpnext/hr/doctype/interview_feedback/interview_feedback.py
new file mode 100644
index 0000000..1c5a494
--- /dev/null
+++ b/erpnext/hr/doctype/interview_feedback/interview_feedback.py
@@ -0,0 +1,88 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, 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
+from frappe.utils import flt, get_link_to_form, getdate
+
+
+class InterviewFeedback(Document):
+	def validate(self):
+		self.validate_interviewer()
+		self.validate_interview_date()
+		self.validate_duplicate()
+		self.calculate_average_rating()
+
+	def on_submit(self):
+		self.update_interview_details()
+
+	def on_cancel(self):
+		self.update_interview_details()
+
+	def validate_interviewer(self):
+		applicable_interviewers = get_applicable_interviewers(self.interview)
+		if self.interviewer not in applicable_interviewers:
+			frappe.throw(_('{0} is not allowed to submit Interview Feedback for the Interview: {1}').format(
+				frappe.bold(self.interviewer), frappe.bold(self.interview)))
+
+	def validate_interview_date(self):
+		scheduled_date = frappe.db.get_value('Interview', self.interview, 'scheduled_on')
+
+		if getdate() < getdate(scheduled_date) and self.docstatus == 1:
+			frappe.throw(_('{0} submission before {1} is not allowed').format(
+				frappe.bold('Interview Feedback'),
+				frappe.bold('Interview Scheduled Date')
+			))
+
+	def validate_duplicate(self):
+		duplicate_feedback = frappe.db.exists('Interview Feedback', {
+			'interviewer': self.interviewer,
+			'interview': self.interview,
+			'docstatus': 1
+		})
+
+		if duplicate_feedback:
+			frappe.throw(_('Feedback already submitted for the Interview {0}. Please cancel the previous Interview Feedback {1} to continue.').format(
+				self.interview, get_link_to_form('Interview Feedback', duplicate_feedback)))
+
+	def calculate_average_rating(self):
+		total_rating = 0
+		for d in self.skill_assessment:
+			if d.rating:
+				total_rating += d.rating
+
+		self.average_rating = flt(total_rating / len(self.skill_assessment) if len(self.skill_assessment) else 0)
+
+	def update_interview_details(self):
+		doc = frappe.get_doc('Interview', self.interview)
+		total_rating = 0
+
+		if self.docstatus == 2:
+			for entry in doc.interview_details:
+				if entry.interview_feedback == self.name:
+					entry.average_rating = entry.interview_feedback = entry.comments = entry.result = None
+					break
+		else:
+			for entry in doc.interview_details:
+				if entry.interviewer == self.interviewer:
+					entry.average_rating = self.average_rating
+					entry.interview_feedback = self.name
+					entry.comments = self.feedback
+					entry.result = self.result
+
+				if entry.average_rating:
+					total_rating += entry.average_rating
+
+		doc.average_rating = flt(total_rating / len(doc.interview_details) if len(doc.interview_details) else 0)
+		doc.save()
+		doc.notify_update()
+
+
+@frappe.whitelist()
+def get_applicable_interviewers(interview):
+	data = frappe.get_all('Interview Detail', filters={'parent': interview}, fields=['interviewer'])
+	return [d.interviewer for d in data]
diff --git a/erpnext/hr/doctype/interview_feedback/test_interview_feedback.py b/erpnext/hr/doctype/interview_feedback/test_interview_feedback.py
new file mode 100644
index 0000000..c4b7981
--- /dev/null
+++ b/erpnext/hr/doctype/interview_feedback/test_interview_feedback.py
@@ -0,0 +1,103 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+import frappe
+from frappe.utils import add_days, flt, getdate
+
+from erpnext.hr.doctype.interview.test_interview import (
+	create_interview_and_dependencies,
+	create_skill_set,
+)
+from erpnext.hr.doctype.job_applicant.test_job_applicant import create_job_applicant
+
+
+class TestInterviewFeedback(unittest.TestCase):
+	def test_validation_for_skill_set(self):
+		frappe.set_user("Administrator")
+		job_applicant = create_job_applicant()
+		interview = create_interview_and_dependencies(job_applicant.name, scheduled_on=add_days(getdate(), -1))
+		skill_ratings = get_skills_rating(interview.interview_round)
+
+		interviewer = interview.interview_details[0].interviewer
+		create_skill_set(['Leadership'])
+
+		interview_feedback = create_interview_feedback(interview.name, interviewer, skill_ratings)
+		interview_feedback.append("skill_assessment", {"skill": 'Leadership', 'rating': 4})
+		frappe.set_user(interviewer)
+
+		self.assertRaises(frappe.ValidationError, interview_feedback.save)
+
+		frappe.set_user("Administrator")
+
+	def test_average_ratings_on_feedback_submission_and_cancellation(self):
+		job_applicant = create_job_applicant()
+		interview = create_interview_and_dependencies(job_applicant.name, scheduled_on=add_days(getdate(), -1))
+		skill_ratings = get_skills_rating(interview.interview_round)
+
+		# For First Interviewer Feedback
+		interviewer = interview.interview_details[0].interviewer
+		frappe.set_user(interviewer)
+
+		# calculating Average
+		feedback_1 = create_interview_feedback(interview.name, interviewer, skill_ratings)
+
+		total_rating = 0
+		for d in feedback_1.skill_assessment:
+			if d.rating:
+				total_rating += d.rating
+
+		avg_rating = flt(total_rating / len(feedback_1.skill_assessment) if len(feedback_1.skill_assessment) else 0)
+
+		self.assertEqual(flt(avg_rating, 3), feedback_1.average_rating)
+
+		avg_on_interview_detail = frappe.db.get_value('Interview Detail', {
+			'parent': feedback_1.interview,
+			'interviewer': feedback_1.interviewer,
+			'interview_feedback': feedback_1.name
+		}, 'average_rating')
+
+		# 1. average should be reflected in Interview Detail.
+		self.assertEqual(avg_on_interview_detail, round(feedback_1.average_rating))
+
+		'''For Second Interviewer Feedback'''
+		interviewer = interview.interview_details[1].interviewer
+		frappe.set_user(interviewer)
+
+		feedback_2 = create_interview_feedback(interview.name, interviewer, skill_ratings)
+		interview.reload()
+
+		feedback_2.cancel()
+		interview.reload()
+
+		frappe.set_user("Administrator")
+
+	def tearDown(self):
+		frappe.db.rollback()
+
+
+def create_interview_feedback(interview, interviewer, skills_ratings):
+	interview_feedback = frappe.new_doc("Interview Feedback")
+	interview_feedback.interview = interview
+	interview_feedback.interviewer = interviewer
+	interview_feedback.result = "Cleared"
+
+	for rating in skills_ratings:
+		interview_feedback.append("skill_assessment", rating)
+
+	interview_feedback.save()
+	interview_feedback.submit()
+
+	return interview_feedback
+
+
+def get_skills_rating(interview_round):
+	import random
+
+	skills = frappe.get_all("Expected Skill Set", filters={"parent": interview_round}, fields = ["skill"])
+	for d in skills:
+		d["rating"] = random.randint(1, 5)
+	return skills
diff --git a/erpnext/healthcare/__init__.py b/erpnext/hr/doctype/interview_round/__init__.py
similarity index 100%
copy from erpnext/healthcare/__init__.py
copy to erpnext/hr/doctype/interview_round/__init__.py
diff --git a/erpnext/hr/doctype/interview_round/interview_round.js b/erpnext/hr/doctype/interview_round/interview_round.js
new file mode 100644
index 0000000..6a608b0
--- /dev/null
+++ b/erpnext/hr/doctype/interview_round/interview_round.js
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on("Interview Round", {
+	refresh: function(frm) {
+		if (!frm.doc.__islocal) {
+			frm.add_custom_button(__("Create Interview"), function() {
+				frm.events.create_interview(frm);
+			});
+		}
+	},
+	create_interview: function(frm) {
+		frappe.call({
+			method: "erpnext.hr.doctype.interview_round.interview_round.create_interview",
+			args: {
+				doc: frm.doc
+			},
+			callback: function (r) {
+				var doclist = frappe.model.sync(r.message);
+				frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
+			}
+		});
+	}
+});
diff --git a/erpnext/hr/doctype/interview_round/interview_round.json b/erpnext/hr/doctype/interview_round/interview_round.json
new file mode 100644
index 0000000..9c95185
--- /dev/null
+++ b/erpnext/hr/doctype/interview_round/interview_round.json
@@ -0,0 +1,118 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "field:round_name",
+ "creation": "2021-04-12 12:57:19.902866",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "round_name",
+  "interview_type",
+  "interviewers",
+  "column_break_3",
+  "designation",
+  "expected_average_rating",
+  "expected_skills_section",
+  "expected_skill_set"
+ ],
+ "fields": [
+  {
+   "fieldname": "round_name",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Round Name",
+   "reqd": 1,
+   "unique": 1
+  },
+  {
+   "fieldname": "designation",
+   "fieldtype": "Link",
+   "label": "Designation",
+   "options": "Designation"
+  },
+  {
+   "fieldname": "expected_skills_section",
+   "fieldtype": "Section Break",
+   "label": "Expected Skillset"
+  },
+  {
+   "fieldname": "expected_skill_set",
+   "fieldtype": "Table",
+   "options": "Expected Skill Set",
+   "reqd": 1
+  },
+  {
+   "fieldname": "expected_average_rating",
+   "fieldtype": "Rating",
+   "label": "Expected Average Rating",
+   "reqd": 1
+  },
+  {
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "interview_type",
+   "fieldtype": "Link",
+   "label": "Interview Type",
+   "options": "Interview Type",
+   "reqd": 1
+  },
+  {
+   "fieldname": "interviewers",
+   "fieldtype": "Table MultiSelect",
+   "label": "Interviewers",
+   "options": "Interviewer"
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "links": [],
+ "modified": "2021-09-30 13:01:25.666660",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Interview Round",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "HR User",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "HR Manager",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Interviewer",
+   "select": 1,
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/interview_round/interview_round.py b/erpnext/hr/doctype/interview_round/interview_round.py
new file mode 100644
index 0000000..8230c78
--- /dev/null
+++ b/erpnext/hr/doctype/interview_round/interview_round.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+
+import json
+
+import frappe
+from frappe.model.document import Document
+
+
+class InterviewRound(Document):
+	pass
+
+@frappe.whitelist()
+def create_interview(doc):
+	if isinstance(doc, str):
+		doc = json.loads(doc)
+		doc = frappe.get_doc(doc)
+
+	interview = frappe.new_doc("Interview")
+	interview.interview_round = doc.name
+	interview.designation = doc.designation
+
+	if doc.interviewers:
+		interview.interview_details = []
+		for data in doc.interviewers:
+			interview.append("interview_details", {
+				"interviewer": data.user
+			})
+	return interview
+
+
+
diff --git a/erpnext/hr/doctype/interview_round/test_interview_round.py b/erpnext/hr/doctype/interview_round/test_interview_round.py
new file mode 100644
index 0000000..932d3de
--- /dev/null
+++ b/erpnext/hr/doctype/interview_round/test_interview_round.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+# import frappe
+
+
+class TestInterviewRound(unittest.TestCase):
+	pass
+
diff --git a/erpnext/healthcare/doctype/__init__.py b/erpnext/hr/doctype/interview_type/__init__.py
similarity index 100%
rename from erpnext/healthcare/doctype/__init__.py
rename to erpnext/hr/doctype/interview_type/__init__.py
diff --git a/erpnext/hr/doctype/interview_type/interview_type.js b/erpnext/hr/doctype/interview_type/interview_type.js
new file mode 100644
index 0000000..af77b52
--- /dev/null
+++ b/erpnext/hr/doctype/interview_type/interview_type.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Interview Type', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/hr/doctype/interview_type/interview_type.json b/erpnext/hr/doctype/interview_type/interview_type.json
new file mode 100644
index 0000000..14636a1
--- /dev/null
+++ b/erpnext/hr/doctype/interview_type/interview_type.json
@@ -0,0 +1,73 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "Prompt",
+ "creation": "2021-04-12 14:44:40.664034",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "description"
+ ],
+ "fields": [
+  {
+   "fieldname": "description",
+   "fieldtype": "Text",
+   "in_list_view": 1,
+   "label": "Description"
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "links": [
+  {
+   "link_doctype": "Interview Round",
+   "link_fieldname": "interview_type"
+  }
+ ],
+ "modified": "2021-09-30 13:00:16.471518",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Interview Type",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "HR Manager",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "HR User",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/interview_type/interview_type.py b/erpnext/hr/doctype/interview_type/interview_type.py
new file mode 100644
index 0000000..ee5be54
--- /dev/null
+++ b/erpnext/hr/doctype/interview_type/interview_type.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, 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 InterviewType(Document):
+	pass
diff --git a/erpnext/hr/doctype/interview_type/test_interview_type.py b/erpnext/hr/doctype/interview_type/test_interview_type.py
new file mode 100644
index 0000000..a5d3cf9
--- /dev/null
+++ b/erpnext/hr/doctype/interview_type/test_interview_type.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+
+class TestInterviewType(unittest.TestCase):
+	pass
diff --git a/erpnext/healthcare/__init__.py b/erpnext/hr/doctype/interviewer/__init__.py
similarity index 100%
copy from erpnext/healthcare/__init__.py
copy to erpnext/hr/doctype/interviewer/__init__.py
diff --git a/erpnext/hr/doctype/interviewer/interviewer.json b/erpnext/hr/doctype/interviewer/interviewer.json
new file mode 100644
index 0000000..a37b8b0
--- /dev/null
+++ b/erpnext/hr/doctype/interviewer/interviewer.json
@@ -0,0 +1,31 @@
+{
+ "actions": [],
+ "creation": "2021-04-12 17:38:19.354734",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "user"
+ ],
+ "fields": [
+  {
+   "fieldname": "user",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "User",
+   "options": "User"
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2021-04-13 13:41:35.817568",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Interviewer",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/interviewer/interviewer.py b/erpnext/hr/doctype/interviewer/interviewer.py
new file mode 100644
index 0000000..1c8dbbe
--- /dev/null
+++ b/erpnext/hr/doctype/interviewer/interviewer.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, 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 Interviewer(Document):
+	pass
diff --git a/erpnext/hr/doctype/job_applicant/job_applicant.js b/erpnext/hr/doctype/job_applicant/job_applicant.js
index 7658bc9..d7b1c6c 100644
--- a/erpnext/hr/doctype/job_applicant/job_applicant.js
+++ b/erpnext/hr/doctype/job_applicant/job_applicant.js
@@ -8,6 +8,24 @@
 
 frappe.ui.form.on("Job Applicant", {
 	refresh: function(frm) {
+		frm.set_query("job_title", function() {
+			return {
+				filters: {
+					'status': 'Open'
+				}
+			};
+		});
+		frm.events.create_custom_buttons(frm);
+		frm.events.make_dashboard(frm);
+	},
+
+	create_custom_buttons: function(frm) {
+		if (!frm.doc.__islocal && frm.doc.status !== "Rejected" && frm.doc.status !== "Accepted") {
+			frm.add_custom_button(__("Create Interview"), function() {
+				frm.events.create_dialog(frm);
+			});
+		}
+
 		if (!frm.doc.__islocal) {
 			if (frm.doc.__onload && frm.doc.__onload.job_offer) {
 				$('[data-doctype="Employee Onboarding"]').find("button").show();
@@ -28,14 +46,57 @@
 				});
 			}
 		}
+	},
 
-		frm.set_query("job_title", function() {
-			return {
-				filters: {
-					'status': 'Open'
-				}
-			};
+	make_dashboard: function(frm) {
+		frappe.call({
+			method: "erpnext.hr.doctype.job_applicant.job_applicant.get_interview_details",
+			args: {
+				job_applicant: frm.doc.name
+			},
+			callback: function(r) {
+				$("div").remove(".form-dashboard-section.custom");
+				frm.dashboard.add_section(
+					frappe.render_template('job_applicant_dashboard', {
+						data: r.message
+					}),
+					__("Interview Summary")
+				);
+			}
 		});
+	},
 
+	create_dialog: function(frm) {
+		let d = new frappe.ui.Dialog({
+			title: 'Enter Interview Round',
+			fields: [
+				{
+					label: 'Interview Round',
+					fieldname: 'interview_round',
+					fieldtype: 'Link',
+					options: 'Interview Round'
+				},
+			],
+			primary_action_label: 'Create Interview',
+			primary_action(values) {
+				frm.events.create_interview(frm, values);
+				d.hide();
+			}
+		});
+		d.show();
+	},
+
+	create_interview: function (frm, values) {
+		frappe.call({
+			method: "erpnext.hr.doctype.job_applicant.job_applicant.create_interview",
+			args: {
+				doc: frm.doc,
+				interview_round: values.interview_round
+			},
+			callback: function (r) {
+				var doclist = frappe.model.sync(r.message);
+				frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
+			}
+		});
 	}
 });
diff --git a/erpnext/hr/doctype/job_applicant/job_applicant.json b/erpnext/hr/doctype/job_applicant/job_applicant.json
index bcea5f5..200f675 100644
--- a/erpnext/hr/doctype/job_applicant/job_applicant.json
+++ b/erpnext/hr/doctype/job_applicant/job_applicant.json
@@ -9,16 +9,20 @@
  "email_append_to": 1,
  "engine": "InnoDB",
  "field_order": [
+  "details_section",
   "applicant_name",
   "email_id",
   "phone_number",
   "country",
-  "status",
   "column_break_3",
   "job_title",
+  "designation",
+  "status",
+  "source_and_rating_section",
   "source",
   "source_name",
   "employee_referral",
+  "column_break_13",
   "applicant_rating",
   "section_break_6",
   "notes",
@@ -84,7 +88,8 @@
   },
   {
    "fieldname": "section_break_6",
-   "fieldtype": "Section Break"
+   "fieldtype": "Section Break",
+   "label": "Resume"
   },
   {
    "fieldname": "cover_letter",
@@ -160,13 +165,34 @@
    "label": "Employee Referral",
    "options": "Employee Referral",
    "read_only": 1
+  },
+  {
+   "fieldname": "details_section",
+   "fieldtype": "Section Break",
+   "label": "Details"
+  },
+  {
+   "fieldname": "source_and_rating_section",
+   "fieldtype": "Section Break",
+   "label": "Source and Rating"
+  },
+  {
+   "fieldname": "column_break_13",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fetch_from": "job_opening.designation",
+   "fieldname": "designation",
+   "fieldtype": "Link",
+   "label": "Designation",
+   "options": "Designation"
   }
  ],
  "icon": "fa fa-user",
  "idx": 1,
  "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2021-03-24 15:51:11.117517",
+ "modified": "2021-09-29 23:06:10.904260",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Job Applicant",
diff --git a/erpnext/hr/doctype/job_applicant/job_applicant.py b/erpnext/hr/doctype/job_applicant/job_applicant.py
index 6971e5b..151f492 100644
--- a/erpnext/hr/doctype/job_applicant/job_applicant.py
+++ b/erpnext/hr/doctype/job_applicant/job_applicant.py
@@ -8,7 +8,9 @@
 import frappe
 from frappe import _
 from frappe.model.document import Document
-from frappe.utils import comma_and, validate_email_address
+from frappe.utils import validate_email_address
+
+from erpnext.hr.doctype.interview.interview import get_interviewers
 
 
 class DuplicationError(frappe.ValidationError): pass
@@ -26,7 +28,6 @@
 		self.name = " - ".join(keys)
 
 	def validate(self):
-		self.check_email_id_is_unique()
 		if self.email_id:
 			validate_email_address(self.email_id, True)
 
@@ -44,11 +45,44 @@
 		elif self.status in ["Accepted", "Rejected"]:
 			emp_ref.db_set("status", self.status)
 
+@frappe.whitelist()
+def create_interview(doc, interview_round):
+	import json
 
-	def check_email_id_is_unique(self):
-		if self.email_id:
-			names = frappe.db.sql_list("""select name from `tabJob Applicant`
-				where email_id=%s and name!=%s and job_title=%s""", (self.email_id, self.name, self.job_title))
+	from six import string_types
 
-			if names:
-				frappe.throw(_("Email Address must be unique, already exists for {0}").format(comma_and(names)), frappe.DuplicateEntryError)
+	if isinstance(doc, string_types):
+		doc = json.loads(doc)
+		doc = frappe.get_doc(doc)
+
+	round_designation = frappe.db.get_value("Interview Round", interview_round, "designation")
+
+	if round_designation and doc.designation and round_designation != doc.designation:
+		frappe.throw(_("Interview Round {0} is only applicable for the Designation {1}").format(interview_round, round_designation))
+
+	interview = frappe.new_doc("Interview")
+	interview.interview_round = interview_round
+	interview.job_applicant = doc.name
+	interview.designation = doc.designation
+	interview.resume_link = doc.resume_link
+	interview.job_opening = doc.job_title
+	interviewer_detail = get_interviewers(interview_round)
+
+	for d in interviewer_detail:
+		interview.append("interview_details", {
+			"interviewer": d.interviewer
+		})
+	return interview
+
+@frappe.whitelist()
+def get_interview_details(job_applicant):
+	interview_details = frappe.db.get_all("Interview",
+		filters={"job_applicant":job_applicant, "docstatus": ["!=", 2]},
+		fields=["name", "interview_round", "expected_average_rating", "average_rating", "status"]
+	)
+	interview_detail_map = {}
+
+	for detail in interview_details:
+		interview_detail_map[detail.name] = detail
+
+	return interview_detail_map
diff --git a/erpnext/hr/doctype/job_applicant/job_applicant_dashboard.html b/erpnext/hr/doctype/job_applicant/job_applicant_dashboard.html
new file mode 100644
index 0000000..c286787
--- /dev/null
+++ b/erpnext/hr/doctype/job_applicant/job_applicant_dashboard.html
@@ -0,0 +1,44 @@
+
+{% if not jQuery.isEmptyObject(data) %}
+
+<table class="table table-bordered small">
+	<thead>
+		<tr>
+			<th style="width: 16%" class="text-left">{{ __("Interview") }}</th>
+			<th style="width: 16%" class="text-left">{{ __("Interview Round") }}</th>
+			<th style="width: 12%" class="text-left">{{ __("Status") }}</th>
+			<th style="width: 14%" class="text-left">{{ __("Expected Rating") }}</th>
+			<th style="width: 10%" class="text-left">{{ __("Rating") }}</th>
+		</tr>
+	</thead>
+	<tbody>
+		{% for(const [key, value] of Object.entries(data)) { %}
+			<tr>
+				<td class="text-left"> {%= key %} </td>
+				<td class="text-left"> {%= value["interview_round"] %} </td>
+				<td class="text-left"> {%= value["status"] %} </td>
+				<td class="text-left">
+					{% for (i = 0; i < value["expected_average_rating"]; i++) { %}
+						<span class="fa fa-star " style="color: #F6C35E;"></span>
+					{% } %}
+					{% for (i = 0; i < (5-value["expected_average_rating"]); i++) { %}
+					<span class="fa fa-star " style="color: #E7E9EB;"></span>
+					{% } %}
+				</td>
+				<td class="text-left">
+					{% if(value["average_rating"]){ %}
+						{% for (i = 0; i < value["average_rating"]; i++) { %}
+							<span class="fa fa-star " style="color: #F6C35E;"></span>
+						{% } %}
+						{% for (i = 0; i < (5-value["average_rating"]); i++) { %}
+						<span class="fa fa-star " style="color: #E7E9EB;"></span>
+						{% } %}
+					{% } %}
+				</td>
+			</tr>
+		{% } %}
+	</tbody>
+</table>
+{% else %}
+<p style="margin-top: 30px;"> No Interview has been scheduled.</p>
+{% endif %}
diff --git a/erpnext/hr/doctype/job_applicant/job_applicant_dashboard.py b/erpnext/hr/doctype/job_applicant/job_applicant_dashboard.py
index c005943..2f7795f 100644
--- a/erpnext/hr/doctype/job_applicant/job_applicant_dashboard.py
+++ b/erpnext/hr/doctype/job_applicant/job_applicant_dashboard.py
@@ -2,14 +2,17 @@
 
 
 def get_data():
-     return {
-        'fieldname': 'job_applicant',
-        'transactions': [
-            {
-                'items': ['Employee', 'Employee Onboarding']
-            },
-            {
-                'items': ['Job Offer']
-            },
-        ],
-    }
+	return {
+		'fieldname': 'job_applicant',
+		'transactions': [
+			{
+				'items': ['Employee', 'Employee Onboarding']
+			},
+			{
+				'items': ['Job Offer', 'Appointment Letter']
+			},
+			{
+				'items': ['Interview']
+			}
+		],
+	}
diff --git a/erpnext/hr/doctype/job_applicant/test_job_applicant.py b/erpnext/hr/doctype/job_applicant/test_job_applicant.py
index e583e25..8fc1290 100644
--- a/erpnext/hr/doctype/job_applicant/test_job_applicant.py
+++ b/erpnext/hr/doctype/job_applicant/test_job_applicant.py
@@ -7,7 +7,8 @@
 
 import frappe
 
-# test_records = frappe.get_test_records('Job Applicant')
+from erpnext.hr.doctype.designation.test_designation import create_designation
+
 
 class TestJobApplicant(unittest.TestCase):
 	pass
@@ -25,7 +26,8 @@
 
 	job_applicant = frappe.get_doc({
 		"doctype": "Job Applicant",
-		"status": args.status or "Open"
+		"status": args.status or "Open",
+		"designation":  create_designation().name
 	})
 
 	job_applicant.update(filters)
diff --git a/erpnext/hr/doctype/job_offer/test_job_offer.py b/erpnext/hr/doctype/job_offer/test_job_offer.py
index 3f3eca1..162b245 100644
--- a/erpnext/hr/doctype/job_offer/test_job_offer.py
+++ b/erpnext/hr/doctype/job_offer/test_job_offer.py
@@ -32,6 +32,7 @@
 		self.assertTrue(frappe.db.exists("Job Offer", job_offer.name))
 
 	def test_job_applicant_update(self):
+		frappe.db.set_value("HR Settings", None, "check_vacancies", 0)
 		create_staffing_plan()
 		job_applicant = create_job_applicant(email_id="test_job_applicants@example.com")
 		job_offer = create_job_offer(job_applicant=job_applicant.name)
@@ -43,7 +44,11 @@
 		job_offer.status = "Rejected"
 		job_offer.submit()
 		job_applicant.reload()
-		self.assertEqual(job_applicant.status, "Rejected")
+		self.assertEquals(job_applicant.status, "Rejected")
+		frappe.db.set_value("HR Settings", None, "check_vacancies", 1)
+
+	def tearDown(self):
+		frappe.db.sql("DELETE FROM `tabJob Offer` WHERE 1")
 
 def create_job_offer(**args):
 	args = frappe._dict(args)
diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.js b/erpnext/hr/doctype/leave_allocation/leave_allocation.js
index d947641..9742387 100755
--- a/erpnext/hr/doctype/leave_allocation/leave_allocation.js
+++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.js
@@ -1,14 +1,14 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-cur_frm.add_fetch('employee','employee_name','employee_name');
+cur_frm.add_fetch('employee', 'employee_name', 'employee_name');
 
 frappe.ui.form.on("Leave Allocation", {
 	onload: function(frm) {
 		// Ignore cancellation of doctype on cancel all.
 		frm.ignore_doctypes_on_cancel_all = ["Leave Ledger Entry"];
 
-		if(!frm.doc.from_date) frm.set_value("from_date", frappe.datetime.get_today());
+		if (!frm.doc.from_date) frm.set_value("from_date", frappe.datetime.get_today());
 
 		frm.set_query("employee", function() {
 			return {
@@ -25,9 +25,9 @@
 	},
 
 	refresh: function(frm) {
-		if(frm.doc.docstatus === 1 && frm.doc.expired) {
+		if (frm.doc.docstatus === 1 && frm.doc.expired) {
 			var valid_expiry = moment(frappe.datetime.get_today()).isBetween(frm.doc.from_date, frm.doc.to_date);
-			if(valid_expiry) {
+			if (valid_expiry) {
 				// expire current allocation
 				frm.add_custom_button(__('Expire Allocation'), function() {
 					frm.trigger("expire_allocation");
@@ -44,8 +44,8 @@
 				'expiry_date': frappe.datetime.get_today()
 			},
 			freeze: true,
-			callback: function(r){
-				if(!r.exc){
+			callback: function(r) {
+				if (!r.exc) {
 					frappe.msgprint(__("Allocation Expired!"));
 				}
 				frm.refresh();
@@ -77,8 +77,8 @@
 	},
 
 	leave_policy: function(frm) {
-		if(frm.doc.leave_policy && frm.doc.leave_type) {
-			frappe.db.get_value("Leave Policy Detail",{
+		if (frm.doc.leave_policy && frm.doc.leave_type) {
+			frappe.db.get_value("Leave Policy Detail", {
 				'parent': frm.doc.leave_policy,
 				'leave_type': frm.doc.leave_type
 			}, 'annual_allocation', (r) => {
@@ -91,13 +91,41 @@
 			return frappe.call({
 				method: "set_total_leaves_allocated",
 				doc: frm.doc,
-				callback: function(r) {
+				callback: function() {
 					frm.refresh_fields();
 				}
-			})
+			});
 		} else if (cint(frm.doc.carry_forward) == 0) {
 			frm.set_value("unused_leaves", 0);
 			frm.set_value("total_leaves_allocated", flt(frm.doc.new_leaves_allocated));
 		}
 	}
 });
+
+frappe.tour["Leave Allocation"] = [
+	{
+		fieldname: "employee",
+		title: "Employee",
+		description: __("Select the Employee for which you want to allocate leaves.")
+	},
+	{
+		fieldname: "leave_type",
+		title: "Leave Type",
+		description: __("Select the Leave Type like Sick leave, Privilege Leave, Casual Leave, etc.")
+	},
+	{
+		fieldname: "from_date",
+		title: "From Date",
+		description: __("Select the date from which this Leave Allocation will be valid.")
+	},
+	{
+		fieldname: "to_date",
+		title: "To Date",
+		description: __("Select the date after which this Leave Allocation will expire.")
+	},
+	{
+		fieldname: "new_leaves_allocated",
+		title: "New Leaves Allocated",
+		description: __("Enter the number of leaves you want to allocate for the period.")
+	}
+];
diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.json b/erpnext/hr/doctype/leave_allocation/leave_allocation.json
index 3a6539e..52ee463 100644
--- a/erpnext/hr/doctype/leave_allocation/leave_allocation.json
+++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.json
@@ -219,7 +219,8 @@
    "fieldname": "leave_policy_assignment",
    "fieldtype": "Link",
    "label": "Leave Policy Assignment",
-   "options": "Leave Policy Assignment"
+   "options": "Leave Policy Assignment",
+   "read_only": 1
   },
   {
    "fetch_from": "employee.company",
@@ -236,7 +237,7 @@
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-06-03 15:28:26.335104",
+ "modified": "2021-10-01 15:28:26.335104",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Leave Allocation",
diff --git a/erpnext/hr/doctype/leave_application/leave_application.js b/erpnext/hr/doctype/leave_application/leave_application.js
index 9ccb915..9e8cb55 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.js
+++ b/erpnext/hr/doctype/leave_application/leave_application.js
@@ -1,8 +1,8 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-cur_frm.add_fetch('employee','employee_name','employee_name');
-cur_frm.add_fetch('employee','company','company');
+cur_frm.add_fetch('employee', 'employee_name', 'employee_name');
+cur_frm.add_fetch('employee', 'company', 'company');
 
 frappe.ui.form.on("Leave Application", {
 	setup: function(frm) {
@@ -19,7 +19,6 @@
 		frm.set_query("employee", erpnext.queries.employee);
 	},
 	onload: function(frm) {
-
 		// Ignore cancellation of doctype on cancel all.
 		frm.ignore_doctypes_on_cancel_all = ["Leave Ledger Entry"];
 
@@ -42,9 +41,9 @@
 	},
 
 	validate: function(frm) {
-		if (frm.doc.from_date == frm.doc.to_date && frm.doc.half_day == 1){
+		if (frm.doc.from_date == frm.doc.to_date && frm.doc.half_day == 1) {
 			frm.doc.half_day_date = frm.doc.from_date;
-		}else if (frm.doc.half_day == 0){
+		} else if (frm.doc.half_day == 0) {
 			frm.doc.half_day_date = "";
 		}
 		frm.toggle_reqd("half_day_date", frm.doc.half_day == 1);
@@ -79,14 +78,14 @@
 				__("Allocated Leaves")
 			);
 			frm.dashboard.show();
-			let allowed_leave_types =  Object.keys(leave_details);
+			let allowed_leave_types = Object.keys(leave_details);
 
 			// lwps should be allowed, lwps don't have any allocation
 			allowed_leave_types = allowed_leave_types.concat(lwps);
 
-			frm.set_query('leave_type', function(){
+			frm.set_query('leave_type', function() {
 				return {
-					filters : [
+					filters: [
 						['leave_type_name', 'in', allowed_leave_types]
 					]
 				};
@@ -99,7 +98,7 @@
 			frm.trigger("calculate_total_days");
 		}
 		cur_frm.set_intro("");
-		if(frm.doc.__islocal && !in_list(frappe.user_roles, "Employee")) {
+		if (frm.doc.__islocal && !in_list(frappe.user_roles, "Employee")) {
 			frm.set_intro(__("Fill the form and save it"));
 		}
 
@@ -118,7 +117,7 @@
 	},
 
 	leave_approver: function(frm) {
-		if(frm.doc.leave_approver){
+		if (frm.doc.leave_approver) {
 			frm.set_value("leave_approver_name", frappe.user.full_name(frm.doc.leave_approver));
 		}
 	},
@@ -131,12 +130,10 @@
 		if (frm.doc.half_day) {
 			if (frm.doc.from_date == frm.doc.to_date) {
 				frm.set_value("half_day_date", frm.doc.from_date);
-			}
-			else {
+			} else {
 				frm.trigger("half_day_datepicker");
 			}
-		}
-		else {
+		} else {
 			frm.set_value("half_day_date", "");
 		}
 		frm.trigger("calculate_total_days");
@@ -163,11 +160,11 @@
 		half_day_datepicker.update({
 			minDate: frappe.datetime.str_to_obj(frm.doc.from_date),
 			maxDate: frappe.datetime.str_to_obj(frm.doc.to_date)
-		})
+		});
 	},
 
 	get_leave_balance: function(frm) {
-		if(frm.doc.docstatus==0 && frm.doc.employee && frm.doc.leave_type && frm.doc.from_date && frm.doc.to_date) {
+		if (frm.doc.docstatus === 0 && frm.doc.employee && frm.doc.leave_type && frm.doc.from_date && frm.doc.to_date) {
 			return frappe.call({
 				method: "erpnext.hr.doctype.leave_application.leave_application.get_leave_balance_on",
 				args: {
@@ -177,11 +174,10 @@
 					leave_type: frm.doc.leave_type,
 					consider_all_leaves_in_the_allocation_period: true
 				},
-				callback: function(r) {
+				callback: function (r) {
 					if (!r.exc && r.message) {
 						frm.set_value('leave_balance', r.message);
-					}
-					else {
+					} else {
 						frm.set_value('leave_balance', "0");
 					}
 				}
@@ -190,12 +186,12 @@
 	},
 
 	calculate_total_days: function(frm) {
-		if(frm.doc.from_date && frm.doc.to_date && frm.doc.employee && frm.doc.leave_type) {
+		if (frm.doc.from_date && frm.doc.to_date && frm.doc.employee && frm.doc.leave_type) {
 
 			var from_date = Date.parse(frm.doc.from_date);
 			var to_date = Date.parse(frm.doc.to_date);
 
-			if(to_date < from_date){
+			if (to_date < from_date) {
 				frappe.msgprint(__("To Date cannot be less than From Date"));
 				frm.set_value('to_date', '');
 				return;
@@ -222,7 +218,7 @@
 	},
 
 	set_leave_approver: function(frm) {
-		if(frm.doc.employee) {
+		if (frm.doc.employee) {
 			// server call is done to include holidays in leave days calculations
 			return frappe.call({
 				method: 'erpnext.hr.doctype.leave_application.leave_application.get_leave_approver',
@@ -238,3 +234,36 @@
 		}
 	}
 });
+
+frappe.tour["Leave Application"] = [
+	{
+		fieldname: "employee",
+		title: "Employee",
+		description: __("Select the Employee.")
+	},
+	{
+		fieldname: "leave_type",
+		title: "Leave Type",
+		description: __("Select type of leave the employee wants to apply for, like Sick Leave, Privilege Leave, Casual Leave, etc.")
+	},
+	{
+		fieldname: "from_date",
+		title: "From Date",
+		description: __("Select the start date for your Leave Application.")
+	},
+	{
+		fieldname: "to_date",
+		title: "To Date",
+		description: __("Select the end date for your Leave Application.")
+	},
+	{
+		fieldname: "half_day",
+		title: "Half Day",
+		description: __("To apply for a Half Day check 'Half Day' and select the Half Day Date")
+	},
+	{
+		fieldname: "leave_approver",
+		title: "Leave Approver",
+		description: __("Select your Leave Approver i.e. the person who approves or rejects your leaves.")
+	}
+];
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index 9e6fc6d..349ed7a 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -76,6 +76,7 @@
 		# notify leave applier about approval
 		if frappe.db.get_single_value("HR Settings", "send_leave_notification"):
 			self.notify_employee()
+
 		self.create_leave_ledger_entry()
 		self.reload()
 
@@ -108,7 +109,13 @@
 		if frappe.db.get_single_value("HR Settings", "restrict_backdated_leave_application"):
 			if self.from_date and getdate(self.from_date) < getdate():
 				allowed_role = frappe.db.get_single_value("HR Settings", "role_allowed_to_create_backdated_leave_application")
-				if allowed_role not in frappe.get_roles():
+				user = frappe.get_doc("User", frappe.session.user)
+				user_roles = [d.role for d in user.roles]
+				if not allowed_role:
+					frappe.throw(_("Backdated Leave Application is restricted. Please set the {} in {}").format(
+						frappe.bold("Role Allowed to Create Backdated Leave Application"), get_link_to_form("HR Settings", "HR Settings")))
+
+				if (allowed_role and allowed_role not in user_roles):
 					frappe.throw(_("Only users with the {0} role can create backdated leave applications").format(allowed_role))
 
 		if self.from_date and self.to_date and (getdate(self.to_date) < getdate(self.from_date)):
diff --git a/erpnext/hr/doctype/leave_application/test_leave_application.py b/erpnext/hr/doctype/leave_application/test_leave_application.py
index b9c785a..629b20e 100644
--- a/erpnext/hr/doctype/leave_application/test_leave_application.py
+++ b/erpnext/hr/doctype/leave_application/test_leave_application.py
@@ -121,6 +121,7 @@
 
 		application = self.get_application(_test_records[0])
 		application.insert()
+		application.reload()
 		application.status = "Approved"
 		self.assertRaises(LeaveDayBlockedError, application.submit)
 
diff --git a/erpnext/hr/doctype/leave_type/leave_type.js b/erpnext/hr/doctype/leave_type/leave_type.js
index 8622309..b930ded 100644
--- a/erpnext/hr/doctype/leave_type/leave_type.js
+++ b/erpnext/hr/doctype/leave_type/leave_type.js
@@ -2,3 +2,37 @@
 	refresh: function(frm) {
 	}
 });
+
+
+frappe.tour["Leave Type"] = [
+	{
+		fieldname: "max_leaves_allowed",
+		title: "Maximum Leave Allocation Allowed",
+		description: __("This field allows you to set the maximum number of leaves that can be allocated annually for this Leave Type while creating the Leave Policy")
+	},
+	{
+		fieldname: "max_continuous_days_allowed",
+		title: "Maximum Consecutive Leaves Allowed",
+		description: __("This field allows you to set the maximum number of consecutive leaves an Employee can apply for.")
+	},
+	{
+		fieldname: "is_optional_leave",
+		title: "Is Optional Leave",
+		description: __("Optional Leaves are holidays that Employees can choose to avail from a list of holidays published by the company.")
+	},
+	{
+		fieldname: "is_compensatory",
+		title: "Is Compensatory Leave",
+		description: __("Leaves you can avail against a holiday you worked on. You can claim Compensatory Off Leave using Compensatory Leave request. Click") + " <a href='https://docs.erpnext.com/docs/v13/user/manual/en/human-resources/compensatory-leave-request' target='_blank'>here</a> " + __('to know more')
+	},
+	{
+		fieldname: "allow_encashment",
+		title: "Allow Encashment",
+		description: __("From here, you can enable encashment for the balance leaves.")
+	},
+	{
+		fieldname: "is_earned_leave",
+		title: "Is Earned Leaves",
+		description: __("Earned Leaves are leaves earned by an Employee after working with the company for a certain amount of time. Enabling this will allocate leaves on pro-rata basis by automatically updating Leave Allocation for leaves of this type at intervals set by 'Earned Leave Frequency.")
+	}
+];
\ No newline at end of file
diff --git a/erpnext/hr/doctype/leave_type/leave_type.json b/erpnext/hr/doctype/leave_type/leave_type.json
index 8f2ae6e..06ca4cd 100644
--- a/erpnext/hr/doctype/leave_type/leave_type.json
+++ b/erpnext/hr/doctype/leave_type/leave_type.json
@@ -50,7 +50,7 @@
   {
    "fieldname": "max_leaves_allowed",
    "fieldtype": "Int",
-   "label": "Max Leaves Allowed"
+   "label": "Maximum Leave Allocation Allowed"
   },
   {
    "fieldname": "applicable_after",
@@ -61,7 +61,7 @@
    "fieldname": "max_continuous_days_allowed",
    "fieldtype": "Int",
    "in_list_view": 1,
-   "label": "Maximum Continuous Days Applicable",
+   "label": "Maximum Consecutive Leaves Allowed",
    "oldfieldname": "max_days_allowed",
    "oldfieldtype": "Data"
   },
@@ -87,6 +87,7 @@
   },
   {
    "default": "0",
+   "description": "These leaves are holidays permitted by the company however, availing it is optional for an Employee.",
    "fieldname": "is_optional_leave",
    "fieldtype": "Check",
    "label": "Is Optional Leave"
@@ -205,6 +206,7 @@
   },
   {
    "depends_on": "eval:doc.is_ppl == 1",
+   "description": "For a day of leave taken, if you still pay (say) 50% of the daily salary, then enter 0.50 in this field.",
    "fieldname": "fraction_of_daily_salary_per_leave",
    "fieldtype": "Float",
    "label": "Fraction of Daily Salary per Leave",
@@ -214,7 +216,7 @@
  "icon": "fa fa-flag",
  "idx": 1,
  "links": [],
- "modified": "2021-08-12 16:10:36.464690",
+ "modified": "2021-10-02 11:59:40.503359",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Leave Type",
diff --git a/erpnext/hr/doctype/shift_assignment/shift_assignment.py b/erpnext/hr/doctype/shift_assignment/shift_assignment.py
index 69af5c5..05b74a0 100644
--- a/erpnext/hr/doctype/shift_assignment/shift_assignment.py
+++ b/erpnext/hr/doctype/shift_assignment/shift_assignment.py
@@ -139,7 +139,7 @@
 	return shift_timing_map
 
 
-def get_employee_shift(employee, for_date=nowdate(), consider_default_shift=False, next_shift_direction=None):
+def get_employee_shift(employee, for_date=None, consider_default_shift=False, next_shift_direction=None):
 	"""Returns a Shift Type for the given employee on the given date. (excluding the holidays)
 
 	:param employee: Employee for which shift is required.
@@ -147,6 +147,8 @@
 	:param consider_default_shift: If set to true, default shift is taken when no shift assignment is found.
 	:param next_shift_direction: One of: None, 'forward', 'reverse'. Direction to look for next shift if shift not found on given date.
 	"""
+	if for_date is None:
+		for_date = nowdate()
 	default_shift = frappe.db.get_value('Employee', employee, 'default_shift')
 	shift_type_name = None
 	shift_assignment_details = frappe.db.get_value('Shift Assignment', {'employee':employee, 'start_date':('<=', for_date), 'docstatus': '1', 'status': "Active"}, ['shift_type', 'end_date'])
@@ -200,9 +202,11 @@
 	return get_shift_details(shift_type_name, for_date)
 
 
-def get_employee_shift_timings(employee, for_timestamp=now_datetime(), consider_default_shift=False):
+def get_employee_shift_timings(employee, for_timestamp=None, consider_default_shift=False):
 	"""Returns previous shift, current/upcoming shift, next_shift for the given timestamp and employee
 	"""
+	if for_timestamp is None:
+		for_timestamp = now_datetime()
 	# write and verify a test case for midnight shift.
 	prev_shift = curr_shift = next_shift = None
 	curr_shift = get_employee_shift(employee, for_timestamp.date(), consider_default_shift, 'forward')
@@ -220,7 +224,7 @@
 	return prev_shift, curr_shift, next_shift
 
 
-def get_shift_details(shift_type_name, for_date=nowdate()):
+def get_shift_details(shift_type_name, for_date=None):
 	"""Returns Shift Details which contain some additional information as described below.
 	'shift_details' contains the following keys:
 		'shift_type' - Object of DocType Shift Type,
@@ -234,6 +238,8 @@
 	"""
 	if not shift_type_name:
 		return None
+	if not for_date:
+		for_date = nowdate()
 	shift_type = frappe.get_doc('Shift Type', shift_type_name)
 	start_datetime = datetime.combine(for_date, datetime.min.time()) + shift_type.start_time
 	for_date = for_date + timedelta(days=1) if shift_type.start_time > shift_type.end_time else for_date
diff --git a/erpnext/healthcare/doctype/patient_assessment/__init__.py b/erpnext/hr/doctype/skill_assessment/__init__.py
similarity index 100%
rename from erpnext/healthcare/doctype/patient_assessment/__init__.py
rename to erpnext/hr/doctype/skill_assessment/__init__.py
diff --git a/erpnext/hr/doctype/skill_assessment/skill_assessment.json b/erpnext/hr/doctype/skill_assessment/skill_assessment.json
new file mode 100644
index 0000000..8b935c4
--- /dev/null
+++ b/erpnext/hr/doctype/skill_assessment/skill_assessment.json
@@ -0,0 +1,41 @@
+{
+ "actions": [],
+ "creation": "2021-04-12 17:07:39.656289",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "skill",
+  "rating"
+ ],
+ "fields": [
+  {
+   "fieldname": "skill",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Skill",
+   "options": "Skill",
+   "read_only": 1,
+   "reqd": 1
+  },
+  {
+   "fieldname": "rating",
+   "fieldtype": "Rating",
+   "in_list_view": 1,
+   "label": "Rating",
+   "reqd": 1
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2021-04-12 17:18:14.032298",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Skill Assessment",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/skill_assessment/skill_assessment.py b/erpnext/hr/doctype/skill_assessment/skill_assessment.py
new file mode 100644
index 0000000..3b74c4e
--- /dev/null
+++ b/erpnext/hr/doctype/skill_assessment/skill_assessment.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, 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 SkillAssessment(Document):
+	pass
diff --git a/erpnext/hr/doctype/staffing_plan/staffing_plan.py b/erpnext/hr/doctype/staffing_plan/staffing_plan.py
index 57a92b0..93cd4e1 100644
--- a/erpnext/hr/doctype/staffing_plan/staffing_plan.py
+++ b/erpnext/hr/doctype/staffing_plan/staffing_plan.py
@@ -155,7 +155,11 @@
 	return employee_counts
 
 @frappe.whitelist()
-def get_active_staffing_plan_details(company, designation, from_date=getdate(nowdate()), to_date=getdate(nowdate())):
+def get_active_staffing_plan_details(company, designation, from_date=None, to_date=None):
+	if from_date is None:
+		from_date = getdate(nowdate())
+	if to_date is None:
+		to_date = getdate(nowdate())
 	if not company or not designation:
 		frappe.throw(_("Please select Company and Designation"))
 
diff --git a/erpnext/hr/doctype/training_result/training_result.js b/erpnext/hr/doctype/training_result/training_result.js
index 5cdbcad..718b383 100644
--- a/erpnext/hr/doctype/training_result/training_result.js
+++ b/erpnext/hr/doctype/training_result/training_result.js
@@ -21,7 +21,7 @@
 					frm.set_value("employees" ,"");
 					if (r.message) {
 						$.each(r.message, function(i, d) {
-							var row = frappe.model.add_child(cur_frm.doc, "Training Result Employee", "employees");
+							var row = frappe.model.add_child(frm.doc, "Training Result Employee", "employees");
 							row.employee = d.employee;
 							row.employee_name = d.employee_name;
 						});
diff --git a/erpnext/hr/module_onboarding/human_resource/human_resource.json b/erpnext/hr/module_onboarding/human_resource/human_resource.json
index 518c002..cd11bd1 100644
--- a/erpnext/hr/module_onboarding/human_resource/human_resource.json
+++ b/erpnext/hr/module_onboarding/human_resource/human_resource.json
@@ -13,17 +13,14 @@
  "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/human-resources",
  "idx": 0,
  "is_complete": 0,
- "modified": "2020-07-08 14:05:47.018799",
+ "modified": "2021-05-19 05:32:01.794628",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Human Resource",
  "owner": "Administrator",
  "steps": [
   {
-   "step": "Create Department"
-  },
-  {
-   "step": "Create Designation"
+   "step": "HR Settings"
   },
   {
    "step": "Create Holiday list"
@@ -32,6 +29,9 @@
    "step": "Create Employee"
   },
   {
+   "step": "Data import"
+  },
+  {
    "step": "Create Leave Type"
   },
   {
@@ -39,9 +39,6 @@
   },
   {
    "step": "Create Leave Application"
-  },
-  {
-   "step": "HR Settings"
   }
  ],
  "subtitle": "Employee, Leaves, and more.",
diff --git a/erpnext/hr/onboarding_step/create_employee/create_employee.json b/erpnext/hr/onboarding_step/create_employee/create_employee.json
index 3aa33c6..4782818 100644
--- a/erpnext/hr/onboarding_step/create_employee/create_employee.json
+++ b/erpnext/hr/onboarding_step/create_employee/create_employee.json
@@ -1,18 +1,20 @@
 {
- "action": "Create Entry",
+ "action": "Show Form Tour",
+ "action_label": "Show Tour",
  "creation": "2020-05-14 11:43:25.561152",
+ "description": "<h3>Employee</h3>\n\nAn individual who works and is recognized for his rights and duties in your company is your Employee. You can manage the Employee master. It captures the demographic, personal and professional details, joining and leave details, etc.",
  "docstatus": 0,
  "doctype": "Onboarding Step",
  "idx": 0,
  "is_complete": 0,
- "is_mandatory": 1,
  "is_single": 0,
  "is_skipped": 0,
- "modified": "2020-05-14 12:26:28.629074",
+ "modified": "2021-05-19 04:50:02.240321",
  "modified_by": "Administrator",
  "name": "Create Employee",
  "owner": "Administrator",
  "reference_document": "Employee",
+ "show_form_tour": 0,
  "show_full_form": 0,
  "title": "Create Employee",
  "validate_action": 0
diff --git a/erpnext/hr/onboarding_step/create_holiday_list/create_holiday_list.json b/erpnext/hr/onboarding_step/create_holiday_list/create_holiday_list.json
index 32472b4..a08e85f 100644
--- a/erpnext/hr/onboarding_step/create_holiday_list/create_holiday_list.json
+++ b/erpnext/hr/onboarding_step/create_holiday_list/create_holiday_list.json
@@ -1,18 +1,20 @@
 {
- "action": "Create Entry",
+ "action": "Show Form Tour",
+ "action_label": "Show Tour",
  "creation": "2020-05-28 11:47:34.700174",
+ "description": "<h3>Holiday List.</h3>\n\nHoliday List is a list which contains the dates of holidays. Most organizations have a standard Holiday List for their employees. However, some of them may have different holiday lists based on different Locations or Departments. In ERPNext, you can configure multiple Holiday Lists.",
  "docstatus": 0,
  "doctype": "Onboarding Step",
  "idx": 0,
  "is_complete": 0,
- "is_mandatory": 1,
  "is_single": 0,
  "is_skipped": 0,
- "modified": "2020-05-14 12:25:38.068582",
+ "modified": "2021-05-19 04:19:52.305199",
  "modified_by": "Administrator",
  "name": "Create Holiday list",
  "owner": "Administrator",
  "reference_document": "Holiday List",
+ "show_form_tour": 0,
  "show_full_form": 1,
  "title": "Create Holiday List",
  "validate_action": 0
diff --git a/erpnext/hr/onboarding_step/create_leave_allocation/create_leave_allocation.json b/erpnext/hr/onboarding_step/create_leave_allocation/create_leave_allocation.json
index fa9941e..0b0ce3f 100644
--- a/erpnext/hr/onboarding_step/create_leave_allocation/create_leave_allocation.json
+++ b/erpnext/hr/onboarding_step/create_leave_allocation/create_leave_allocation.json
@@ -1,18 +1,20 @@
 {
- "action": "Create Entry",
+ "action": "Show Form Tour",
+ "action_label": "Show Tour",
  "creation": "2020-05-14 11:48:56.123718",
+ "description": "<h3>Leave Allocation</h3>\n\nLeave Allocation enables you to allocate a specific number of leaves of a particular type to an Employee so that, an employee will be able to create a Leave Application only if Leaves are allocated. ",
  "docstatus": 0,
  "doctype": "Onboarding Step",
  "idx": 0,
  "is_complete": 0,
- "is_mandatory": 1,
  "is_single": 0,
  "is_skipped": 0,
- "modified": "2020-05-14 11:48:56.123718",
+ "modified": "2021-05-19 04:22:34.220238",
  "modified_by": "Administrator",
  "name": "Create Leave Allocation",
  "owner": "Administrator",
  "reference_document": "Leave Allocation",
+ "show_form_tour": 0,
  "show_full_form": 0,
  "title": "Create Leave Allocation",
  "validate_action": 0
diff --git a/erpnext/hr/onboarding_step/create_leave_application/create_leave_application.json b/erpnext/hr/onboarding_step/create_leave_application/create_leave_application.json
index 1ed074e..af63aa5 100644
--- a/erpnext/hr/onboarding_step/create_leave_application/create_leave_application.json
+++ b/erpnext/hr/onboarding_step/create_leave_application/create_leave_application.json
@@ -1,18 +1,20 @@
 {
- "action": "Create Entry",
+ "action": "Show Form Tour",
+ "action_label": "Show Tour",
  "creation": "2020-05-14 11:49:45.400764",
+ "description": "<h3>Leave Application</h3>\n\nLeave Application is a formal document created by an Employee to apply for Leaves for a particular time period based on there leave allocation and leave type according to there need.",
  "docstatus": 0,
  "doctype": "Onboarding Step",
  "idx": 0,
  "is_complete": 0,
- "is_mandatory": 1,
  "is_single": 0,
  "is_skipped": 0,
- "modified": "2020-05-14 11:49:45.400764",
+ "modified": "2021-05-19 04:39:09.893474",
  "modified_by": "Administrator",
  "name": "Create Leave Application",
  "owner": "Administrator",
  "reference_document": "Leave Application",
+ "show_form_tour": 0,
  "show_full_form": 0,
  "title": "Create Leave Application",
  "validate_action": 0
diff --git a/erpnext/hr/onboarding_step/create_leave_type/create_leave_type.json b/erpnext/hr/onboarding_step/create_leave_type/create_leave_type.json
index 8cbfc5c..397f5cd 100644
--- a/erpnext/hr/onboarding_step/create_leave_type/create_leave_type.json
+++ b/erpnext/hr/onboarding_step/create_leave_type/create_leave_type.json
@@ -1,18 +1,20 @@
 {
- "action": "Create Entry",
+ "action": "Show Form Tour",
+ "action_label": "Show Tour",
  "creation": "2020-05-27 11:17:31.119312",
+ "description": "<h3>Leave Type</h3>\n\nLeave type is defined based on many factors and features like encashment, earned leaves, partially paid, without pay and, a lot more. To check other options and to define your leave type click on Show Tour.",
  "docstatus": 0,
  "doctype": "Onboarding Step",
  "idx": 0,
  "is_complete": 0,
- "is_mandatory": 1,
  "is_single": 0,
  "is_skipped": 0,
- "modified": "2020-05-20 11:17:31.119312",
+ "modified": "2021-05-19 04:32:48.135406",
  "modified_by": "Administrator",
  "name": "Create Leave Type",
  "owner": "Administrator",
  "reference_document": "Leave Type",
+ "show_form_tour": 0,
  "show_full_form": 1,
  "title": "Create Leave Type",
  "validate_action": 0
diff --git a/erpnext/hr/onboarding_step/data_import/data_import.json b/erpnext/hr/onboarding_step/data_import/data_import.json
new file mode 100644
index 0000000..ac343c6
--- /dev/null
+++ b/erpnext/hr/onboarding_step/data_import/data_import.json
@@ -0,0 +1,21 @@
+{
+ "action": "Watch Video",
+ "action_label": "",
+ "creation": "2021-05-19 05:29:16.809610",
+ "description": "<h3>Data Import</h3>\n\nData import is the tool to migrate your existing data like Employee, Customer, Supplier, and a lot more to our ERPNext system.\nGo through the video for a detailed explanation of this tool.",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2021-05-19 05:29:16.809610",
+ "modified_by": "Administrator",
+ "name": "Data import",
+ "owner": "Administrator",
+ "show_form_tour": 0,
+ "show_full_form": 0,
+ "title": "Data Import",
+ "validate_action": 1,
+ "video_url": "https://www.youtube.com/watch?v=DQyqeurPI64"
+}
\ No newline at end of file
diff --git a/erpnext/hr/onboarding_step/hr_settings/hr_settings.json b/erpnext/hr/onboarding_step/hr_settings/hr_settings.json
index 0a1d0ba..355664f 100644
--- a/erpnext/hr/onboarding_step/hr_settings/hr_settings.json
+++ b/erpnext/hr/onboarding_step/hr_settings/hr_settings.json
@@ -1,18 +1,20 @@
 {
- "action": "Update Settings",
+ "action": "Show Form Tour",
+ "action_label": "Explore",
  "creation": "2020-05-28 13:13:52.427711",
+ "description": "<h3>HR Settings</h3>\n\nHr Settings consists of major settings related to Employee Lifecycle, Leave Management, etc. Click on Explore, to explore Hr Settings.",
  "docstatus": 0,
  "doctype": "Onboarding Step",
  "idx": 0,
  "is_complete": 0,
- "is_mandatory": 0,
  "is_single": 1,
  "is_skipped": 0,
- "modified": "2020-05-20 11:16:42.430974",
+ "modified": "2021-05-18 07:02:05.747548",
  "modified_by": "Administrator",
  "name": "HR Settings",
  "owner": "Administrator",
  "reference_document": "HR Settings",
+ "show_form_tour": 0,
  "show_full_form": 0,
  "title": "HR Settings",
  "validate_action": 0
diff --git a/erpnext/hr/utils.py b/erpnext/hr/utils.py
index deec644..b6f4cad 100644
--- a/erpnext/hr/utils.py
+++ b/erpnext/hr/utils.py
@@ -32,7 +32,10 @@
 def update_employee(employee, details, date=None, cancel=False):
 	internal_work_history = {}
 	for item in details:
-		fieldtype = frappe.get_meta("Employee").get_field(item.fieldname).fieldtype
+		field = frappe.get_meta("Employee").get_field(item.fieldname)
+		if not field:
+			continue
+		fieldtype = field.fieldtype
 		new_data = item.new if not cancel else item.current
 		if fieldtype == "Date" and new_data:
 			new_data = getdate(new_data)
diff --git a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js
index d1a8c8d..035290d 100644
--- a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js
+++ b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js
@@ -18,7 +18,7 @@
 	},
 	refresh: function (frm) {
 		setTimeout(() => {
-			frm.toggle_display('generate_schedule', !(frm.is_new()));
+			frm.toggle_display('generate_schedule', !(frm.is_new() || frm.doc.docstatus));
 			frm.toggle_display('schedule', !(frm.is_new()));
 		}, 10);
 	},
diff --git a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py
index 52e41c5..a1df9cf 100644
--- a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py
+++ b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py
@@ -16,9 +16,9 @@
 class MaintenanceSchedule(TransactionBase):
 	@frappe.whitelist()
 	def generate_schedule(self):
+		if self.docstatus != 0:
+			return
 		self.set('schedules', [])
-		frappe.db.sql("""delete from `tabMaintenance Schedule Detail`
-			where parent=%s""", (self.name))
 		count = 1
 		for d in self.get('items'):
 			self.validate_maintenance_detail()
@@ -47,7 +47,7 @@
 			"Yearly": 365
 		}
 		for item in self.items:
-			if item.periodicity and item.start_date:
+			if item.periodicity and item.periodicity != "Random" and item.start_date:
 				if not item.end_date:
 					if item.no_of_visits:
 						item.end_date = add_days(item.start_date, item.no_of_visits * days_in_period[item.periodicity])
diff --git a/erpnext/maintenance/doctype/maintenance_schedule_detail/maintenance_schedule_detail.json b/erpnext/maintenance/doctype/maintenance_schedule_detail/maintenance_schedule_detail.json
index 8ccef6a..afe273f 100644
--- a/erpnext/maintenance/doctype/maintenance_schedule_detail/maintenance_schedule_detail.json
+++ b/erpnext/maintenance/doctype/maintenance_schedule_detail/maintenance_schedule_detail.json
@@ -89,13 +89,14 @@
    "width": "160px"
   },
   {
+   "allow_on_submit": 1,
    "columns": 2,
+   "default": "Pending",
    "fieldname": "completion_status",
    "fieldtype": "Select",
    "in_list_view": 1,
    "label": "Completion Status",
-   "options": "Pending\nPartially Completed\nFully Completed",
-   "read_only": 1
+   "options": "Pending\nPartially Completed\nFully Completed"
   },
   {
    "fieldname": "column_break_3",
@@ -125,10 +126,11 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-05-27 16:07:25.905015",
+ "modified": "2021-09-16 21:25:22.506485",
  "modified_by": "Administrator",
  "module": "Maintenance",
  "name": "Maintenance Schedule Detail",
+ "naming_rule": "Random",
  "owner": "Administrator",
  "permissions": [],
  "sort_field": "modified",
diff --git a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js
index 6b3f184..7f98354 100644
--- a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js
+++ b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js
@@ -31,8 +31,8 @@
 	},
 	onload: function (frm, cdt, cdn) {
 		let item = locals[cdt][cdn];
-		if (frm.maintenance_type == 'Scheduled') {
-			let schedule_id = item.purposes[0].prevdoc_detail_docname;
+		if (frm.doc.maintenance_type === "Scheduled") {
+			const schedule_id = item.purposes[0].prevdoc_detail_docname || frm.doc.maintenance_schedule_detail;
 			frappe.call({
 				method: "erpnext.maintenance.doctype.maintenance_schedule.maintenance_schedule.update_serial_nos",
 				args: {
@@ -43,6 +43,9 @@
 				}
 			});
 		}
+		else {
+			frm.clear_table("purposes");
+		}
 
 		if (!frm.doc.status) {
 			frm.set_value({ status: 'Draft' });
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index 8a92413..5f5c20a 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -215,7 +215,32 @@
 				label: __('Qty To Manufacture'),
 				fieldname: 'qty',
 				reqd: 1,
-				default: 1
+				default: 1,
+				onchange: () => {
+					const { quantity, items: rm } = frm.doc;
+					const variant_items_map = rm.reduce((acc, item) => {
+						acc[item.item_code] = item.qty;
+						return acc;
+					}, {});
+					const mf_qty = cur_dialog.fields_list.filter(
+						(f) => f.df.fieldname === "qty"
+					)[0]?.value;
+					const items = cur_dialog.fields.filter(
+						(f) => f.fieldname === "items"
+					)[0]?.data;
+
+					if (!items) {
+						return;
+					}
+
+					items.forEach((item) => {
+						item.qty =
+							(variant_items_map[item.item_code] * mf_qty) /
+							quantity;
+					});
+
+					cur_dialog.refresh();
+				}
 			});
 		}
 
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 28a84b2..232e3a0 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -510,8 +510,14 @@
 			if d.workstation:
 				self.update_rate_and_time(d, update_hour_rate)
 
-			self.operating_cost += flt(d.operating_cost)
-			self.base_operating_cost += flt(d.base_operating_cost)
+			operating_cost = d.operating_cost
+			base_operating_cost = d.base_operating_cost
+			if d.set_cost_based_on_bom_qty:
+				operating_cost = flt(d.cost_per_unit) * flt(self.quantity)
+				base_operating_cost = flt(d.base_cost_per_unit) * flt(self.quantity)
+
+			self.operating_cost += flt(operating_cost)
+			self.base_operating_cost += flt(base_operating_cost)
 
 	def update_rate_and_time(self, row, update_hour_rate = False):
 		if not row.hour_rate or update_hour_rate:
@@ -535,6 +541,8 @@
 			row.base_hour_rate = flt(row.hour_rate) * flt(self.conversion_rate)
 			row.operating_cost = flt(row.hour_rate) * flt(row.time_in_mins) / 60.0
 			row.base_operating_cost = flt(row.operating_cost) * flt(self.conversion_rate)
+			row.cost_per_unit = row.operating_cost / (row.batch_size or 1.0)
+			row.base_cost_per_unit = row.base_operating_cost / (row.batch_size or 1.0)
 
 		if update_hour_rate:
 			row.db_update()
diff --git a/erpnext/manufacturing/doctype/bom/test_bom.py b/erpnext/manufacturing/doctype/bom/test_bom.py
index 7950dd9..4c03230 100644
--- a/erpnext/manufacturing/doctype/bom/test_bom.py
+++ b/erpnext/manufacturing/doctype/bom/test_bom.py
@@ -4,13 +4,14 @@
 
 import unittest
 from collections import deque
+from functools import partial
 
 import frappe
 from frappe.test_runner import make_test_records
 from frappe.utils import cstr, flt
 
 from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
-from erpnext.manufacturing.doctype.bom.bom import make_variant_bom
+from erpnext.manufacturing.doctype.bom.bom import item_query, make_variant_bom
 from erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool import update_cost
 from erpnext.stock.doctype.item.test_item import make_item
 from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import (
@@ -108,6 +109,24 @@
 		self.assertAlmostEqual(bom.base_raw_material_cost, base_raw_material_cost)
 		self.assertAlmostEqual(bom.base_total_cost, base_raw_material_cost + base_op_cost)
 
+	def test_bom_cost_with_batch_size(self):
+		bom = frappe.copy_doc(test_records[2])
+		bom.docstatus = 0
+		op_cost = 0.0
+		for op_row in bom.operations:
+			op_row.docstatus = 0
+			op_row.batch_size = 2
+			op_row.set_cost_based_on_bom_qty = 1
+			op_cost += op_row.operating_cost
+
+		bom.save()
+
+		for op_row in bom.operations:
+			self.assertAlmostEqual(op_row.cost_per_unit, op_row.operating_cost / 2)
+
+		self.assertAlmostEqual(bom.operating_cost, op_cost/2)
+		bom.delete()
+
 	def test_bom_cost_multi_uom_multi_currency_based_on_price_list(self):
 		frappe.db.set_value("Price List", "_Test Price List", "price_not_uom_dependent", 1)
 		for item_code, rate in (("_Test Item", 3600), ("_Test Item Home Desktop Manufactured", 3000)):
@@ -357,6 +376,16 @@
 		# FG Items in Scrap/Loss Table should have Is Process Loss set
 		self.assertRaises(frappe.ValidationError, bom_doc.submit)
 
+	def test_bom_item_query(self):
+		query = partial(item_query, doctype="Item", txt="", searchfield="name", start=0, page_len=20, filters={"is_stock_item": 1})
+
+		test_items = query(txt="_Test")
+		filtered = query(txt="_Test Item 2")
+
+		self.assertNotEqual(len(test_items), len(filtered), msg="Item filtering showing excessive results")
+		self.assertTrue(0 < len(filtered) <= 3, msg="Item filtering showing excessive results")
+
+
 def get_default_bom(item_code="_Test FG Item 2"):
 	return frappe.db.get_value("BOM", {"item": item_code, "is_active": 1, "is_default": 1})
 
diff --git a/erpnext/manufacturing/doctype/bom_operation/bom_operation.json b/erpnext/manufacturing/doctype/bom_operation/bom_operation.json
index 4458e6d..ec617f3 100644
--- a/erpnext/manufacturing/doctype/bom_operation/bom_operation.json
+++ b/erpnext/manufacturing/doctype/bom_operation/bom_operation.json
@@ -8,15 +8,23 @@
  "field_order": [
   "sequence_id",
   "operation",
-  "workstation",
-  "description",
   "col_break1",
-  "hour_rate",
+  "workstation",
   "time_in_mins",
-  "operating_cost",
+  "costing_section",
+  "hour_rate",
   "base_hour_rate",
+  "column_break_9",
+  "operating_cost",
   "base_operating_cost",
+  "column_break_11",
   "batch_size",
+  "set_cost_based_on_bom_qty",
+  "cost_per_unit",
+  "base_cost_per_unit",
+  "more_information_section",
+  "description",
+  "column_break_18",
   "image"
  ],
  "fields": [
@@ -117,13 +125,59 @@
    "fieldname": "sequence_id",
    "fieldtype": "Int",
    "label": "Sequence ID"
+  },
+  {
+   "depends_on": "eval:doc.batch_size > 0 && doc.set_cost_based_on_bom_qty",
+   "fieldname": "cost_per_unit",
+   "fieldtype": "Float",
+   "label": "Cost Per Unit",
+   "no_copy": 1,
+   "print_hide": 1,
+   "read_only": 1
+  },
+  {
+   "fieldname": "base_cost_per_unit",
+   "fieldtype": "Float",
+   "hidden": 1,
+   "label": "Base Cost Per Unit",
+   "no_copy": 1,
+   "print_hide": 1,
+   "read_only": 1
+  },
+  {
+   "fieldname": "costing_section",
+   "fieldtype": "Section Break",
+   "label": "Costing"
+  },
+  {
+   "fieldname": "column_break_11",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "more_information_section",
+   "fieldtype": "Section Break",
+   "label": "More Information"
+  },
+  {
+   "fieldname": "column_break_18",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "column_break_9",
+   "fieldtype": "Column Break"
+  },
+  {
+   "default": "0",
+   "fieldname": "set_cost_based_on_bom_qty",
+   "fieldtype": "Check",
+   "label": "Set Operating Cost Based On BOM Quantity"
   }
  ],
  "idx": 1,
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-01-12 14:48:09.596843",
+ "modified": "2021-09-13 16:45:01.092868",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "BOM Operation",
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.js b/erpnext/manufacturing/doctype/job_card/job_card.js
index 91eb4a0..35be388 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.js
+++ b/erpnext/manufacturing/doctype/job_card/job_card.js
@@ -26,15 +26,23 @@
 	refresh: function(frm) {
 		frappe.flags.pause_job = 0;
 		frappe.flags.resume_job = 0;
+		let has_items = frm.doc.items && frm.doc.items.length;
 
-		if(!frm.doc.__islocal && frm.doc.items && frm.doc.items.length) {
-			if (frm.doc.for_quantity != frm.doc.transferred_qty) {
+		if (!frm.doc.__islocal && has_items && frm.doc.docstatus < 2) {
+			let to_request = frm.doc.for_quantity > frm.doc.transferred_qty;
+			let excess_transfer_allowed = frm.doc.__onload.job_card_excess_transfer;
+
+			if (to_request || excess_transfer_allowed) {
 				frm.add_custom_button(__("Material Request"), () => {
 					frm.trigger("make_material_request");
 				});
 			}
 
-			if (frm.doc.for_quantity != frm.doc.transferred_qty) {
+			// check if any row has untransferred materials
+			// in case of multiple items in JC
+			let to_transfer = frm.doc.items.some((row) => row.transferred_qty < row.required_qty);
+
+			if (to_transfer || excess_transfer_allowed) {
 				frm.add_custom_button(__("Material Transfer"), () => {
 					frm.trigger("make_stock_entry");
 				}).addClass("btn-primary");
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.json b/erpnext/manufacturing/doctype/job_card/job_card.json
index 046e2fd..7dd38f4 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.json
+++ b/erpnext/manufacturing/doctype/job_card/job_card.json
@@ -38,6 +38,8 @@
   "total_time_in_mins",
   "section_break_8",
   "items",
+  "scrap_items_section",
+  "scrap_items",
   "corrective_operation_section",
   "for_job_card",
   "is_corrective_job_card",
@@ -185,7 +187,7 @@
    "default": "0",
    "fieldname": "transferred_qty",
    "fieldtype": "Float",
-   "label": "Transferred Qty",
+   "label": "FG Qty from Transferred Raw Materials",
    "read_only": 1
   },
   {
@@ -392,14 +394,28 @@
    "fieldtype": "Link",
    "label": "Batch No",
    "options": "Batch"
+  },
+  {
+   "fieldname": "scrap_items_section",
+   "fieldtype": "Section Break",
+   "label": "Scrap Items"
+  },
+  {
+   "fieldname": "scrap_items",
+   "fieldtype": "Table",
+   "label": "Scrap Items",
+   "no_copy": 1,
+   "options": "Job Card Scrap Item",
+   "print_hide": 1
   }
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2021-03-16 15:59:32.766484",
+ "modified": "2021-09-14 00:38:46.873105",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Job Card",
+ "naming_rule": "By \"Naming Series\" field",
  "owner": "Administrator",
  "permissions": [
   {
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py
index 3bf9de2..e1d79be 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.py
+++ b/erpnext/manufacturing/doctype/job_card/job_card.py
@@ -1,9 +1,6 @@
 # -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
 # For license information, please see license.txt
-
-from __future__ import unicode_literals
-
 import datetime
 import json
 
@@ -37,6 +34,10 @@
 class JobCardCancelError(frappe.ValidationError): pass
 
 class JobCard(Document):
+	def onload(self):
+		excess_transfer = frappe.db.get_single_value("Manufacturing Settings", "job_card_excess_transfer")
+		self.set_onload("job_card_excess_transfer", excess_transfer)
+
 	def validate(self):
 		self.validate_time_logs()
 		self.set_status()
@@ -91,7 +92,7 @@
 		if args.get("employee"):
 			# override capacity for employee
 			production_capacity = 1
-			validate_overlap_for = " and jc.employee = %(employee)s "
+			validate_overlap_for = " and jctl.employee = %(employee)s "
 
 		extra_cond = ''
 		if check_next_available_slot:
@@ -449,6 +450,7 @@
 			frappe.db.set_value('Job Card Item', row.job_card_item, 'transferred_qty', flt(qty))
 
 	def set_transferred_qty(self, update_status=False):
+		"Set total FG Qty for which RM was transferred."
 		if not self.items:
 			self.transferred_qty = self.for_quantity if self.docstatus == 1 else 0
 
@@ -457,6 +459,7 @@
 			return
 
 		if self.items:
+			# sum of 'For Quantity' of Stock Entries against JC
 			self.transferred_qty = frappe.db.get_value('Stock Entry', {
 				'job_card': self.name,
 				'work_order': self.work_order,
@@ -500,7 +503,9 @@
 			self.status = 'Work In Progress'
 
 		if (self.docstatus == 1 and
-			(self.for_quantity == self.transferred_qty or not self.items)):
+			(self.for_quantity <= self.transferred_qty or not self.items)):
+			# consider excess transfer
+			# completed qty is checked via separate validation
 			self.status = 'Completed'
 
 		if self.status != 'Completed':
@@ -618,7 +623,11 @@
 	def set_missing_values(source, target):
 		target.purpose = "Material Transfer for Manufacture"
 		target.from_bom = 1
-		target.fg_completed_qty = source.get('for_quantity', 0) - source.get('transferred_qty', 0)
+
+		# avoid negative 'For Quantity'
+		pending_fg_qty = source.get('for_quantity', 0) - source.get('transferred_qty', 0)
+		target.fg_completed_qty = pending_fg_qty if pending_fg_qty > 0 else 0
+
 		target.set_transfer_qty()
 		target.calculate_rate_and_amount()
 		target.set_missing_values()
@@ -668,7 +677,7 @@
 	conditions = get_filters_cond("Job Card", filters, [])
 
 	job_cards = frappe.db.sql(""" SELECT `tabJob Card`.name, `tabJob Card`.work_order,
-			`tabJob Card`.employee_name, `tabJob Card`.status, ifnull(`tabJob Card`.remarks, ''),
+			`tabJob Card`.status, ifnull(`tabJob Card`.remarks, ''),
 			min(`tabJob Card Time Log`.from_time) as from_time,
 			max(`tabJob Card Time Log`.to_time) as to_time
 		FROM `tabJob Card` , `tabJob Card Time Log`
@@ -678,7 +687,7 @@
 
 	for d in job_cards:
 			subject_data = []
-			for field in ["name", "work_order", "remarks", "employee_name"]:
+			for field in ["name", "work_order", "remarks"]:
 				if not d.get(field): continue
 
 				subject_data.append(d.get(field))
diff --git a/erpnext/manufacturing/doctype/job_card/test_job_card.py b/erpnext/manufacturing/doctype/job_card/test_job_card.py
index db0e08f..ea5d364 100644
--- a/erpnext/manufacturing/doctype/job_card/test_job_card.py
+++ b/erpnext/manufacturing/doctype/job_card/test_job_card.py
@@ -1,78 +1,194 @@
 # -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
 # See license.txt
-from __future__ import unicode_literals
-
 import unittest
 
 import frappe
 from frappe.utils import random_string
 
-from erpnext.manufacturing.doctype.job_card.job_card import OperationMismatchError
+from erpnext.manufacturing.doctype.job_card.job_card import OperationMismatchError, OverlapError
+from erpnext.manufacturing.doctype.job_card.job_card import (
+	make_stock_entry as make_stock_entry_from_jc,
+)
 from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record
 from erpnext.manufacturing.doctype.workstation.test_workstation import make_workstation
+from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
 
 
 class TestJobCard(unittest.TestCase):
+
+	def setUp(self):
+		transfer_material_against, source_warehouse = None, None
+		tests_that_transfer_against_jc = ("test_job_card_multiple_materials_transfer",
+			"test_job_card_excess_material_transfer")
+
+		if self._testMethodName in tests_that_transfer_against_jc:
+			transfer_material_against = "Job Card"
+			source_warehouse = "Stores - _TC"
+
+		self.work_order = make_wo_order_test_record(
+			item="_Test FG Item 2",
+			qty=2,
+			transfer_material_against=transfer_material_against,
+			source_warehouse=source_warehouse
+		)
+
+	def tearDown(self):
+		frappe.db.rollback()
+
 	def test_job_card(self):
-		data = frappe.get_cached_value('BOM',
-			{'docstatus': 1, 'with_operations': 1, 'company': '_Test Company'}, ['name', 'item'])
 
-		if data:
-			bom, bom_item = data
+		job_cards = frappe.get_all('Job Card',
+			filters = {'work_order': self.work_order.name}, fields = ["operation_id", "name"])
 
-			work_order = make_wo_order_test_record(item=bom_item, qty=1, bom_no=bom)
+		if job_cards:
+			job_card = job_cards[0]
+			frappe.db.set_value("Job Card", job_card.name, "operation_row_number", job_card.operation_id)
 
-			job_cards = frappe.get_all('Job Card',
-				filters = {'work_order': work_order.name}, fields = ["operation_id", "name"])
+			doc = frappe.get_doc("Job Card", job_card.name)
+			doc.operation_id = "Test Data"
+			self.assertRaises(OperationMismatchError, doc.save)
 
-			if job_cards:
-				job_card = job_cards[0]
-				frappe.db.set_value("Job Card", job_card.name, "operation_row_number", job_card.operation_id)
-
-				doc = frappe.get_doc("Job Card", job_card.name)
-				doc.operation_id = "Test Data"
-				self.assertRaises(OperationMismatchError, doc.save)
-
-			for d in job_cards:
-				frappe.delete_doc("Job Card", d.name)
+		for d in job_cards:
+			frappe.delete_doc("Job Card", d.name)
 
 	def test_job_card_with_different_work_station(self):
-		data = frappe.get_cached_value('BOM',
-			{'docstatus': 1, 'with_operations': 1, 'company': '_Test Company'}, ['name', 'item'])
+		job_cards = frappe.get_all('Job Card',
+			filters = {'work_order': self.work_order.name},
+			fields = ["operation_id", "workstation", "name", "for_quantity"])
 
-		if data:
-			bom, bom_item = data
+		job_card = job_cards[0]
 
-			work_order = make_wo_order_test_record(item=bom_item, qty=1, bom_no=bom)
+		if job_card:
+			workstation = frappe.db.get_value("Workstation",
+				{"name": ("not in", [job_card.workstation])}, "name")
 
-			job_cards = frappe.get_all('Job Card',
-				filters = {'work_order': work_order.name},
-				fields = ["operation_id", "workstation", "name", "for_quantity"])
+			if not workstation or job_card.workstation == workstation:
+				workstation = make_workstation(workstation_name=random_string(5)).name
 
-			job_card = job_cards[0]
+			doc = frappe.get_doc("Job Card", job_card.name)
+			doc.workstation = workstation
+			doc.append("time_logs", {
+				"from_time": "2009-01-01 12:06:25",
+				"to_time": "2009-01-01 12:37:25",
+				"time_in_mins": "31.00002",
+				"completed_qty": job_card.for_quantity
+			})
+			doc.submit()
 
-			if job_card:
-				workstation = frappe.db.get_value("Workstation",
-					{"name": ("not in", [job_card.workstation])}, "name")
+			completed_qty = frappe.db.get_value("Work Order Operation", job_card.operation_id, "completed_qty")
+			self.assertEqual(completed_qty, job_card.for_quantity)
 
-				if not workstation or job_card.workstation == workstation:
-					workstation = make_workstation(workstation_name=random_string(5)).name
-
-				doc = frappe.get_doc("Job Card", job_card.name)
-				doc.workstation = workstation
-				doc.append("time_logs", {
-					"from_time": "2009-01-01 12:06:25",
-					"to_time": "2009-01-01 12:37:25",
-					"time_in_mins": "31.00002",
-					"completed_qty": job_card.for_quantity
-				})
-				doc.submit()
-
-				completed_qty = frappe.db.get_value("Work Order Operation", job_card.operation_id, "completed_qty")
-				self.assertEqual(completed_qty, job_card.for_quantity)
-
-				doc.cancel()
+			doc.cancel()
 
 			for d in job_cards:
 				frappe.delete_doc("Job Card", d.name)
+
+	def test_job_card_overlap(self):
+		wo2 = make_wo_order_test_record(item="_Test FG Item 2", qty=2)
+
+		jc1_name = frappe.db.get_value("Job Card", {'work_order': self.work_order.name})
+		jc2_name = frappe.db.get_value("Job Card", {'work_order': wo2.name})
+
+		jc1 = frappe.get_doc("Job Card", jc1_name)
+		jc2 = frappe.get_doc("Job Card", jc2_name)
+
+		employee = "_T-Employee-00001" # from test records
+
+		jc1.append("time_logs", {
+			"from_time": "2021-01-01 00:00:00",
+			"to_time": "2021-01-01 08:00:00",
+			"completed_qty": 1,
+			"employee": employee,
+		})
+		jc1.save()
+
+		# add a new entry in same time slice
+		jc2.append("time_logs", {
+			"from_time": "2021-01-01 00:01:00",
+			"to_time": "2021-01-01 06:00:00",
+			"completed_qty": 1,
+			"employee": employee,
+		})
+		self.assertRaises(OverlapError, jc2.save)
+
+	def test_job_card_multiple_materials_transfer(self):
+		"Test transferring RMs separately against Job Card with multiple RMs."
+		make_stock_entry(
+			item_code="_Test Item",
+			target="Stores - _TC",
+			qty=10,
+			basic_rate=100
+		)
+		make_stock_entry(
+			item_code="_Test Item Home Desktop Manufactured",
+			target="Stores - _TC",
+			qty=6,
+			basic_rate=100
+		)
+
+		job_card_name = frappe.db.get_value("Job Card", {'work_order': self.work_order.name})
+		job_card = frappe.get_doc("Job Card", job_card_name)
+
+		transfer_entry_1 = make_stock_entry_from_jc(job_card_name)
+		del transfer_entry_1.items[1] # transfer only 1 of 2 RMs
+		transfer_entry_1.insert()
+		transfer_entry_1.submit()
+
+		job_card.reload()
+
+		self.assertEqual(transfer_entry_1.fg_completed_qty, 2)
+		self.assertEqual(job_card.transferred_qty, 2)
+
+		# transfer second RM
+		transfer_entry_2 = make_stock_entry_from_jc(job_card_name)
+		del transfer_entry_2.items[0]
+		transfer_entry_2.insert()
+		transfer_entry_2.submit()
+
+		# 'For Quantity' here will be 0 since
+		# transfer was made for 2 fg qty in first transfer Stock Entry
+		self.assertEqual(transfer_entry_2.fg_completed_qty, 0)
+
+	def test_job_card_excess_material_transfer(self):
+		"Test transferring more than required RM against Job Card."
+		make_stock_entry(item_code="_Test Item", target="Stores - _TC",
+			qty=25, basic_rate=100)
+		make_stock_entry(item_code="_Test Item Home Desktop Manufactured",
+			target="Stores - _TC", qty=15, basic_rate=100)
+
+		job_card_name = frappe.db.get_value("Job Card", {'work_order': self.work_order.name})
+		job_card = frappe.get_doc("Job Card", job_card_name)
+
+		# fully transfer both RMs
+		transfer_entry_1 = make_stock_entry_from_jc(job_card_name)
+		transfer_entry_1.insert()
+		transfer_entry_1.submit()
+
+		# transfer extra qty of both RM due to previously damaged RM
+		transfer_entry_2 = make_stock_entry_from_jc(job_card_name)
+		# deliberately change 'For Quantity'
+		transfer_entry_2.fg_completed_qty = 1
+		transfer_entry_2.items[0].qty = 5
+		transfer_entry_2.items[1].qty = 3
+		transfer_entry_2.insert()
+		transfer_entry_2.submit()
+
+		job_card.reload()
+		self.assertGreater(job_card.transferred_qty, job_card.for_quantity)
+
+		# Check if 'For Quantity' is negative
+		# as 'transferred_qty' > Qty to Manufacture
+		transfer_entry_3 = make_stock_entry_from_jc(job_card_name)
+		self.assertEqual(transfer_entry_3.fg_completed_qty, 0)
+
+		job_card.append("time_logs", {
+			"from_time": "2021-01-01 00:01:00",
+			"to_time": "2021-01-01 06:00:00",
+			"completed_qty": 2
+		})
+		job_card.save()
+		job_card.submit()
+
+		# JC is Completed with excess transfer
+		self.assertEqual(job_card.status, "Completed")
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/organism_test_item/__init__.py b/erpnext/manufacturing/doctype/job_card_scrap_item/__init__.py
similarity index 100%
rename from erpnext/healthcare/doctype/organism_test_item/__init__.py
rename to erpnext/manufacturing/doctype/job_card_scrap_item/__init__.py
diff --git a/erpnext/manufacturing/doctype/job_card_scrap_item/job_card_scrap_item.json b/erpnext/manufacturing/doctype/job_card_scrap_item/job_card_scrap_item.json
new file mode 100644
index 0000000..9e9f1c4
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card_scrap_item/job_card_scrap_item.json
@@ -0,0 +1,82 @@
+{
+ "actions": [],
+ "creation": "2021-09-14 00:30:28.533884",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "item_code",
+  "item_name",
+  "column_break_3",
+  "description",
+  "quantity_and_rate",
+  "stock_qty",
+  "column_break_6",
+  "stock_uom"
+ ],
+ "fields": [
+  {
+   "fieldname": "item_code",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Scrap Item Code",
+   "options": "Item",
+   "reqd": 1
+  },
+  {
+   "fetch_from": "item_code.item_name",
+   "fieldname": "item_name",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Scrap Item Name"
+  },
+  {
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fetch_from": "item_code.description",
+   "fieldname": "description",
+   "fieldtype": "Small Text",
+   "label": "Description",
+   "read_only": 1
+  },
+  {
+   "fieldname": "quantity_and_rate",
+   "fieldtype": "Section Break",
+   "label": "Quantity and Rate"
+  },
+  {
+   "fieldname": "stock_qty",
+   "fieldtype": "Float",
+   "in_list_view": 1,
+   "label": "Qty",
+   "reqd": 1
+  },
+  {
+   "fieldname": "column_break_6",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fetch_from": "item_code.stock_uom",
+   "fieldname": "stock_uom",
+   "fieldtype": "Link",
+   "label": "Stock UOM",
+   "options": "UOM",
+   "read_only": 1
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2021-09-14 01:20:48.588052",
+ "modified_by": "Administrator",
+ "module": "Manufacturing",
+ "name": "Job Card Scrap Item",
+ "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/manufacturing/doctype/job_card_scrap_item/job_card_scrap_item.py b/erpnext/manufacturing/doctype/job_card_scrap_item/job_card_scrap_item.py
new file mode 100644
index 0000000..372df1b
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card_scrap_item/job_card_scrap_item.py
@@ -0,0 +1,8 @@
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from frappe.model.document import Document
+
+
+class JobCardScrapItem(Document):
+	pass
diff --git a/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json b/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json
index 024f784..01647d5 100644
--- a/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json
+++ b/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json
@@ -25,9 +25,12 @@
   "overproduction_percentage_for_sales_order",
   "column_break_16",
   "overproduction_percentage_for_work_order",
+  "job_card_section",
+  "add_corrective_operation_cost_in_finished_good_valuation",
+  "column_break_24",
+  "job_card_excess_transfer",
   "other_settings_section",
   "update_bom_costs_automatically",
-  "add_corrective_operation_cost_in_finished_good_valuation",
   "column_break_23",
   "make_serial_no_batch_from_work_order"
  ],
@@ -96,10 +99,10 @@
   },
   {
    "default": "0",
-   "description": "Allow multiple material consumptions against a Work Order",
+   "description": "Allow material consumptions without immediately manufacturing finished goods against a Work Order",
    "fieldname": "material_consumption",
    "fieldtype": "Check",
-   "label": "Allow Multiple Material Consumption"
+   "label": "Allow Continuous Material Consumption"
   },
   {
    "default": "0",
@@ -175,13 +178,29 @@
    "fieldname": "add_corrective_operation_cost_in_finished_good_valuation",
    "fieldtype": "Check",
    "label": "Add Corrective Operation Cost in Finished Good Valuation"
+  },
+  {
+   "fieldname": "job_card_section",
+   "fieldtype": "Section Break",
+   "label": "Job Card"
+  },
+  {
+   "fieldname": "column_break_24",
+   "fieldtype": "Column Break"
+  },
+  {
+   "default": "0",
+   "description": "Allow transferring raw materials even after the Required Quantity is fulfilled",
+   "fieldname": "job_card_excess_transfer",
+   "fieldtype": "Check",
+   "label": "Allow Excess Material Transfer"
   }
  ],
  "icon": "icon-wrench",
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2021-03-16 15:54:38.967341",
+ "modified": "2021-09-13 22:09:09.401559",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Manufacturing Settings",
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js
index 7b4b7c3..2bd02da 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.js
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js
@@ -242,6 +242,8 @@
 	},
 
 	get_sub_assembly_items: function(frm) {
+		frm.dirty();
+
 		frappe.call({
 			method: "get_sub_assembly_items",
 			freeze: true,
@@ -434,6 +436,25 @@
 	}
 });
 
+frappe.ui.form.on("Production Plan Sales Order", {
+	sales_order(frm, cdt, cdn) {
+		const { sales_order } = locals[cdt][cdn];
+		if (!sales_order) {
+			return;
+		}
+		frappe.call({
+			method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_so_details",
+			args: { sales_order },
+			callback(r) {
+				const {transaction_date, customer, grand_total} = r.message;
+				frappe.model.set_value(cdt, cdn, 'sales_order_date', transaction_date);
+				frappe.model.set_value(cdt, cdn, 'customer', customer);
+				frappe.model.set_value(cdt, cdn, 'grand_total', grand_total);
+			}
+		});
+	}
+});
+
 cur_frm.fields_dict['sales_orders'].grid.get_field("sales_order").get_query = function() {
 	return{
 		filters: [
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.json b/erpnext/manufacturing/doctype/production_plan/production_plan.json
index b5ed288..56cf2b4 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.json
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.json
@@ -16,10 +16,12 @@
   "customer",
   "warehouse",
   "project",
+  "sales_order_status",
   "column_break2",
   "from_date",
   "to_date",
-  "sales_order_status",
+  "from_delivery_date",
+  "to_delivery_date",
   "sales_orders_detail",
   "get_sales_orders",
   "sales_orders",
@@ -358,13 +360,23 @@
    "fieldname": "get_sub_assembly_items",
    "fieldtype": "Button",
    "label": "Get Sub Assembly Items"
+  },
+  {
+   "fieldname": "from_delivery_date",
+   "fieldtype": "Date",
+   "label": "From Delivery Date"
+  },
+  {
+   "fieldname": "to_delivery_date",
+   "fieldtype": "Date",
+   "label": "To Delivery Date"
   }
  ],
  "icon": "fa fa-calendar",
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-08-23 17:26:03.799876",
+ "modified": "2021-09-06 18:35:59.642232",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Production Plan",
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index 91e5748..b9efe9b 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -457,7 +457,8 @@
 
 	def prepare_args_for_sub_assembly_items(self, row, args):
 		for field in ["production_item", "item_name", "qty", "fg_warehouse",
-			"description", "bom_no", "stock_uom", "bom_level", "production_plan_item"]:
+			"description", "bom_no", "stock_uom", "bom_level",
+			"production_plan_item", "schedule_date"]:
 			args[field] = row.get(field)
 
 		args.update({
@@ -561,8 +562,6 @@
 			get_sub_assembly_items(row.bom_no, bom_data, row.planned_qty)
 			self.set_sub_assembly_items_based_on_level(row, bom_data, manufacturing_type)
 
-		self.save()
-
 	def set_sub_assembly_items_based_on_level(self, row, bom_data, manufacturing_type=None):
 		bom_data = sorted(bom_data, key = lambda i: i.bom_level)
 
@@ -735,43 +734,42 @@
 def get_sales_orders(self):
 	so_filter = item_filter = ""
 	bom_item = "bom.item = so_item.item_code"
-	if self.from_date:
-		so_filter += " and so.transaction_date >= %(from_date)s"
-	if self.to_date:
-		so_filter += " and so.transaction_date <= %(to_date)s"
-	if self.customer:
-		so_filter += " and so.customer = %(customer)s"
-	if self.project:
-		so_filter += " and so.project = %(project)s"
-	if self.sales_order_status:
-		so_filter += "and so.status = %(sales_order_status)s"
+
+	date_field_mapper = {
+		'from_date': ('>=', 'so.transaction_date'),
+		'to_date': ('<=', 'so.transaction_date'),
+		'from_delivery_date': ('>=', 'so_item.delivery_date'),
+		'to_delivery_date': ('<=', 'so_item.delivery_date')
+	}
+
+	for field, value in date_field_mapper.items():
+		if self.get(field):
+			so_filter += f" and {value[1]} {value[0]} %({field})s"
+
+	for field in ['customer', 'project', 'sales_order_status']:
+		if self.get(field):
+			so_field = 'status' if field == 'sales_order_status' else field
+			so_filter += f" and so.{so_field} = %({field})s"
 
 	if self.item_code and frappe.db.exists('Item', self.item_code):
 		bom_item = self.get_bom_item() or bom_item
-		item_filter += " and so_item.item_code = %(item)s"
+		item_filter += " and so_item.item_code = %(item_code)s"
 
-	open_so = frappe.db.sql("""
+	open_so = frappe.db.sql(f"""
 		select distinct so.name, so.transaction_date, so.customer, so.base_grand_total
 		from `tabSales Order` so, `tabSales Order Item` so_item
 		where so_item.parent = so.name
 			and so.docstatus = 1 and so.status not in ("Stopped", "Closed")
 			and so.company = %(company)s
-			and so_item.qty > so_item.work_order_qty {0} {1}
-			and (exists (select name from `tabBOM` bom where {2}
+			and so_item.qty > so_item.work_order_qty {so_filter} {item_filter}
+			and (exists (select name from `tabBOM` bom where {bom_item}
 					and bom.is_active = 1)
 				or exists (select name from `tabPacked Item` pi
 					where pi.parent = so.name and pi.parent_item = so_item.item_code
 						and exists (select name from `tabBOM` bom where bom.item=pi.item_code
 							and bom.is_active = 1)))
-		""".format(so_filter, item_filter, bom_item), {
-			"from_date": self.from_date,
-			"to_date": self.to_date,
-			"customer": self.customer,
-			"project": self.project,
-			"item": self.item_code,
-			"company": self.company,
-			"sales_order_status": self.sales_order_status
-		}, as_dict=1)
+		""", self.as_dict(), as_dict=1)
+
 	return open_so
 
 @frappe.whitelist()
@@ -800,6 +798,12 @@
 		group by item_code, warehouse
 	""".format(conditions=conditions), { "item_code": row['item_code'] }, as_dict=1)
 
+@frappe.whitelist()
+def get_so_details(sales_order):
+	return frappe.db.get_value("Sales Order", sales_order,
+		['transaction_date', 'customer', 'grand_total'], as_dict=1
+	)
+
 def get_warehouse_list(warehouses):
 	warehouse_list = []
 
diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
index 6a942d5..707b3f6 100644
--- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
@@ -404,6 +404,7 @@
 			'uom': item_doc.stock_uom,
 			'stock_uom': item_doc.stock_uom,
 			'rate': item_doc.valuation_rate or args.rate,
+			'source_warehouse': args.source_warehouse
 		})
 
 	if not args.do_not_save:
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index bb43149..85b5bfb 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -1,9 +1,5 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
-
-
-from __future__ import unicode_literals
-
 import unittest
 
 import frappe
@@ -20,7 +16,7 @@
 	stop_unstop,
 )
 from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
-from erpnext.stock.doctype.item.test_item import make_item
+from erpnext.stock.doctype.item.test_item import create_item, make_item
 from erpnext.stock.doctype.stock_entry import test_stock_entry
 from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
 from erpnext.stock.utils import get_bin
@@ -772,6 +768,60 @@
 			total_pl_qty
 		)
 
+	def test_job_card_scrap_item(self):
+		items = ['Test FG Item for Scrap Item Test', 'Test RM Item 1 for Scrap Item Test',
+			'Test RM Item 2 for Scrap Item Test']
+
+		company = '_Test Company with perpetual inventory'
+		for item_code in items:
+			create_item(item_code = item_code, is_stock_item = 1,
+				is_purchase_item=1, opening_stock=100, valuation_rate=10, company=company, warehouse='Stores - TCP1')
+
+		item = 'Test FG Item for Scrap Item Test'
+		raw_materials = ['Test RM Item 1 for Scrap Item Test', 'Test RM Item 2 for Scrap Item Test']
+		if not frappe.db.get_value('BOM', {'item': item}):
+			bom = make_bom(item=item, source_warehouse='Stores - TCP1', raw_materials=raw_materials, do_not_save=True)
+			bom.with_operations = 1
+			bom.append('operations', {
+				'operation': '_Test Operation 1',
+				'workstation': '_Test Workstation 1',
+				'hour_rate': 20,
+				'time_in_mins': 60
+			})
+
+			bom.submit()
+
+		wo_order = make_wo_order_test_record(item=item, company=company, planned_start_date=now(), qty=20, skip_transfer=1)
+		job_card = frappe.db.get_value('Job Card', {'work_order': wo_order.name}, 'name')
+		update_job_card(job_card)
+
+		stock_entry = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 10))
+		for row in stock_entry.items:
+			if row.is_scrap_item:
+				self.assertEqual(row.qty, 1)
+
+def update_job_card(job_card):
+	job_card_doc = frappe.get_doc('Job Card', job_card)
+	job_card_doc.set('scrap_items', [
+		{
+			'item_code': 'Test RM Item 1 for Scrap Item Test',
+			'stock_qty': 2
+		},
+		{
+			'item_code': 'Test RM Item 2 for Scrap Item Test',
+			'stock_qty': 2
+		},
+	])
+
+	job_card_doc.append('time_logs', {
+		'from_time': now(),
+		'time_in_mins': 60,
+		'completed_qty': job_card_doc.for_quantity
+	})
+
+	job_card_doc.submit()
+
+
 def get_scrap_item_details(bom_no):
 	scrap_items = {}
 	for item in frappe.db.sql("""select item_code, stock_qty from `tabBOM Scrap Item`
@@ -814,6 +864,7 @@
 	wo_order.get_items_and_operations_from_bom()
 	wo_order.sales_order = args.sales_order or None
 	wo_order.planned_start_date = args.planned_start_date or now()
+	wo_order.transfer_material_against = args.transfer_material_against or "Work Order"
 
 	if args.source_warehouse:
 		for item in wo_order.get("required_items"):
diff --git a/erpnext/modules.txt b/erpnext/modules.txt
index 62f5dce..a9f94ce 100644
--- a/erpnext/modules.txt
+++ b/erpnext/modules.txt
@@ -15,7 +15,6 @@
 Maintenance
 Education
 Regional
-Healthcare
 Restaurant
 Agriculture
 ERPNext Integrations
@@ -26,4 +25,4 @@
 Communication
 Loan Management
 Payroll
-Telephony
\ No newline at end of file
+Telephony
diff --git a/erpnext/non_profit/doctype/donation/donation.py b/erpnext/non_profit/doctype/donation/donation.py
index e4e2b4e..efbe496 100644
--- a/erpnext/non_profit/doctype/donation/donation.py
+++ b/erpnext/non_profit/doctype/donation/donation.py
@@ -171,7 +171,7 @@
 def get_company_for_donations():
 	company = frappe.db.get_single_value('Non Profit Settings', 'donation_company')
 	if not company:
-		from erpnext.healthcare.setup import get_company
+		from erpnext.non_profit.utils import get_company
 		company = get_company()
 	return company
 
diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py
index b65dc8e..8522d66 100644
--- a/erpnext/non_profit/doctype/membership/membership.py
+++ b/erpnext/non_profit/doctype/membership/membership.py
@@ -355,7 +355,7 @@
 def get_company_for_memberships():
 	company = frappe.db.get_single_value("Non Profit Settings", "company")
 	if not company:
-		from erpnext.healthcare.setup import get_company
+		from erpnext.non_profit.utils import get_company
 		company = get_company()
 	return company
 
diff --git a/erpnext/non_profit/utils.py b/erpnext/non_profit/utils.py
new file mode 100644
index 0000000..47ea5f5
--- /dev/null
+++ b/erpnext/non_profit/utils.py
@@ -0,0 +1,12 @@
+import frappe
+
+
+def get_company():
+	company = frappe.defaults.get_defaults().company
+	if company:
+		return company
+	else:
+		company = frappe.get_list("Company", limit=1)
+		if company:
+			return company[0].name
+	return None
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 0f57b50..22a6313 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -30,15 +30,12 @@
 erpnext.patches.v11_0.set_default_email_template_in_hr #08-06-2018
 erpnext.patches.v11_0.uom_conversion_data #30-06-2018
 erpnext.patches.v11_0.update_account_type_in_party_type
-erpnext.patches.v11_0.rename_healthcare_doctype_and_fields
 erpnext.patches.v11_0.rename_supplier_type_to_supplier_group
 erpnext.patches.v10_1.transfer_subscription_to_auto_repeat
 erpnext.patches.v11_0.update_brand_in_item_price
 erpnext.patches.v11_0.create_default_success_action
-erpnext.patches.v11_0.add_healthcare_service_unit_tree_root
 erpnext.patches.v11_0.rename_field_max_days_allowed
 erpnext.patches.v11_0.create_salary_structure_assignments
-erpnext.patches.v11_0.rename_health_insurance
 erpnext.patches.v11_0.rebuild_tree_for_company
 erpnext.patches.v11_0.create_department_records_for_each_company
 erpnext.patches.v11_0.make_location_from_warehouse
@@ -65,9 +62,7 @@
 erpnext.patches.v11_0.reset_publish_in_hub_for_all_items
 erpnext.patches.v11_0.update_hub_url # 2018-08-31  # 2018-09-03
 erpnext.patches.v11_0.make_job_card
-erpnext.patches.v11_0.redesign_healthcare_billing_work_flow
 erpnext.patches.v10_0.delete_hub_documents # 12-08-2018
-erpnext.patches.v11_0.rename_healthcare_fields
 erpnext.patches.v11_0.add_default_dispatch_notification_template
 erpnext.patches.v11_0.add_market_segments
 erpnext.patches.v11_0.add_sales_stages
@@ -169,7 +164,6 @@
 erpnext.patches.v12_0.set_received_qty_in_material_request_as_per_stock_uom
 erpnext.patches.v12_0.rename_account_type_doctype
 erpnext.patches.v12_0.recalculate_requested_qty_in_bin
-erpnext.patches.v12_0.update_healthcare_refactored_changes
 erpnext.patches.v12_0.set_total_batch_quantity
 erpnext.patches.v12_0.rename_mws_settings_fields
 erpnext.patches.v12_0.set_updated_purpose_in_pick_list
@@ -178,7 +172,6 @@
 erpnext.patches.v12_0.update_end_date_and_status_in_email_campaign
 erpnext.patches.v13_0.move_tax_slabs_from_payroll_period_to_income_tax_slab #123
 erpnext.patches.v12_0.fix_quotation_expired_status
-erpnext.patches.v12_0.update_appointment_reminder_scheduler_entry
 erpnext.patches.v12_0.rename_pos_closing_doctype
 erpnext.patches.v13_0.replace_pos_payment_mode_table #2020-12-29
 erpnext.patches.v12_0.remove_duplicate_leave_ledger_entries #2020-05-22
@@ -196,7 +189,6 @@
 execute:frappe.reload_doc('desk', 'doctype', 'number_card_link')
 execute:frappe.delete_doc_if_exists('Dashboard', 'Accounts')
 erpnext.patches.v13_0.update_actual_start_and_end_date_in_wo
-erpnext.patches.v13_0.set_company_field_in_healthcare_doctypes #2021-04-16
 erpnext.patches.v12_0.update_bom_in_so_mr
 execute:frappe.delete_doc("Report", "Department Analytics")
 execute:frappe.rename_doc("Desk Page", "Loan Management", "Loan", force=True)
@@ -222,7 +214,6 @@
 erpnext.patches.v13_0.delete_report_requested_items_to_order
 erpnext.patches.v12_0.update_item_tax_template_company
 erpnext.patches.v13_0.move_branch_code_to_bank_account
-erpnext.patches.v13_0.healthcare_lab_module_rename_doctypes
 erpnext.patches.v13_0.add_standard_navbar_items #2021-03-24
 erpnext.patches.v13_0.stock_entry_enhancements
 erpnext.patches.v12_0.update_state_code_for_daman_and_diu
@@ -236,7 +227,6 @@
 erpnext.patches.v13_0.set_app_name
 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.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")
@@ -251,7 +241,6 @@
 erpnext.patches.v13_0.update_project_template_tasks
 erpnext.patches.v13_0.set_company_in_leave_ledger_entry
 erpnext.patches.v13_0.convert_qi_parameter_to_link_field
-erpnext.patches.v13_0.setup_patient_history_settings_for_standard_doctypes
 erpnext.patches.v13_0.add_naming_series_to_old_projects # 1-02-2021
 erpnext.patches.v13_0.update_payment_terms_outstanding
 erpnext.patches.v12_0.add_state_code_for_ladakh
@@ -263,7 +252,6 @@
 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.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
 erpnext.patches.v12_0.purchase_receipt_status
@@ -304,4 +292,14 @@
 erpnext.patches.v13_0.validate_options_for_data_field
 erpnext.patches.v13_0.create_gst_payment_entry_fields
 erpnext.patches.v14_0.delete_shopify_doctypes
-erpnext.patches.v14_0.update_opportunity_currency_fields
\ No newline at end of file
+erpnext.patches.v13_0.replace_supplier_item_group_with_party_specific_item
+erpnext.patches.v13_0.update_dates_in_tax_withholding_category
+erpnext.patches.v14_0.update_opportunity_currency_fields
+erpnext.patches.v13_0.gst_fields_for_pos_invoice
+erpnext.patches.v13_0.create_accounting_dimensions_in_pos_doctypes
+erpnext.patches.v13_0.trim_sales_invoice_custom_field_length
+erpnext.patches.v13_0.create_custom_field_for_finance_book
+erpnext.patches.v13_0.modify_invalid_gain_loss_gl_entries
+erpnext.patches.v13_0.fix_additional_cost_in_mfg_stock_entry
+erpnext.patches.v13_0.set_status_in_maintenance_schedule_table
+erpnext.patches.v13_0.add_default_interview_notification_templates
\ No newline at end of file
diff --git a/erpnext/patches/v11_0/add_healthcare_service_unit_tree_root.py b/erpnext/patches/v11_0/add_healthcare_service_unit_tree_root.py
deleted file mode 100644
index 9bb91dc..0000000
--- a/erpnext/patches/v11_0/add_healthcare_service_unit_tree_root.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from __future__ import unicode_literals
-
-import frappe
-from frappe import _
-
-
-def execute():
-	""" assign lft and rgt appropriately """
-	if "Healthcare" not in frappe.get_active_domains():
-		return
-
-	frappe.reload_doc("healthcare", "doctype", "healthcare_service_unit")
-	frappe.reload_doc("healthcare", "doctype", "healthcare_service_unit_type")
-	company = frappe.get_value("Company", {"domain": "Healthcare"}, "name")
-
-	if company:
-		frappe.get_doc({
-			'doctype': 'Healthcare Service Unit',
-			'healthcare_service_unit_name': _('All Healthcare Service Units'),
-			'is_group': 1,
-			'company': company
-		}).insert(ignore_permissions=True)
diff --git a/erpnext/patches/v11_0/redesign_healthcare_billing_work_flow.py b/erpnext/patches/v11_0/redesign_healthcare_billing_work_flow.py
deleted file mode 100644
index b1ed0f5..0000000
--- a/erpnext/patches/v11_0/redesign_healthcare_billing_work_flow.py
+++ /dev/null
@@ -1,69 +0,0 @@
-from __future__ import unicode_literals
-
-import frappe
-from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
-from frappe.modules import get_doctype_module, scrub
-
-from erpnext.domains.healthcare import data
-
-sales_invoice_referenced_doc = {
-	"Patient Appointment": "sales_invoice",
-	"Patient Encounter": "invoice",
-	"Lab Test": "invoice",
-	"Lab Prescription": "invoice",
-	"Sample Collection": "invoice"
-}
-
-def execute():
-	frappe.reload_doc('accounts', 'doctype', 'loyalty_program')
-	frappe.reload_doc('accounts', 'doctype', 'sales_invoice_item')
-
-	if "Healthcare" not in frappe.get_active_domains():
-		return
-
-	healthcare_custom_field_in_sales_invoice()
-	for si_ref_doc in sales_invoice_referenced_doc:
-		if frappe.db.exists('DocType', si_ref_doc):
-			frappe.reload_doc(get_doctype_module(si_ref_doc), 'doctype', scrub(si_ref_doc))
-
-			if frappe.db.has_column(si_ref_doc, sales_invoice_referenced_doc[si_ref_doc]) \
-			and frappe.db.has_column(si_ref_doc, 'invoiced'):
-				# Set Reference DocType and Reference Docname
-				doc_list = frappe.db.sql("""
-							select name from `tab{0}`
-							where {1} is not null
-						""".format(si_ref_doc, sales_invoice_referenced_doc[si_ref_doc]))
-				if doc_list:
-					frappe.reload_doc(get_doctype_module("Sales Invoice"), 'doctype', 'sales_invoice')
-					for doc_id in doc_list:
-						invoice_id = frappe.db.get_value(si_ref_doc, doc_id[0], sales_invoice_referenced_doc[si_ref_doc])
-						if frappe.db.exists("Sales Invoice", invoice_id):
-							if si_ref_doc == "Lab Test":
-								template = frappe.db.get_value("Lab Test", doc_id[0], "template")
-								if template:
-									item = frappe.db.get_value("Lab Test Template", template, "item")
-									if item:
-										frappe.db.sql("""update `tabSales Invoice Item` set reference_dt = '{0}',
-										reference_dn = '{1}' where parent = '{2}' and item_code='{3}'""".format\
-										(si_ref_doc, doc_id[0], invoice_id, item))
-							else:
-								invoice = frappe.get_doc("Sales Invoice", invoice_id)
-								for item_line in invoice.items:
-									if not item_line.reference_dn:
-										item_line.db_set({"reference_dt":si_ref_doc, "reference_dn": doc_id[0]})
-										break
-				# Documents mark invoiced for submitted sales invoice
-				frappe.db.sql("""update `tab{0}` doc, `tabSales Invoice` si
-					set doc.invoiced = 1 where si.docstatus = 1 and doc.{1} = si.name
-					""".format(si_ref_doc, sales_invoice_referenced_doc[si_ref_doc]))
-
-def healthcare_custom_field_in_sales_invoice():
-	frappe.reload_doc('healthcare', 'doctype', 'patient')
-	frappe.reload_doc('healthcare', 'doctype', 'healthcare_practitioner')
-	if data['custom_fields']:
-		create_custom_fields(data['custom_fields'])
-
-	frappe.db.sql("""
-				delete from `tabCustom Field`
-				where fieldname = 'appointment' and options = 'Patient Appointment'
-			""")
diff --git a/erpnext/patches/v11_0/refactor_naming_series.py b/erpnext/patches/v11_0/refactor_naming_series.py
index 9f231ed..fd4dbdc 100644
--- a/erpnext/patches/v11_0/refactor_naming_series.py
+++ b/erpnext/patches/v11_0/refactor_naming_series.py
@@ -15,7 +15,6 @@
 	'Blanket Order': 'MFG-BLR-.YYYY.-',
 	'C-Form': 'ACC-CF-.YYYY.-',
 	'Campaign': 'SAL-CAM-.YYYY.-',
-	'Clinical Procedure': 'HLC-CPR-.YYYY.-',
 	'Course Schedule': 'EDU-CSH-.YYYY.-',
 	'Customer': 'CUST-.YYYY.-',
 	'Delivery Note': 'MAT-DN-.YYYY.-',
@@ -27,12 +26,10 @@
 	'Fee Schedule': 'EDU-FSH-.YYYY.-',
 	'Fee Structure': 'EDU-FST-.YYYY.-',
 	'Fees': 'EDU-FEE-.YYYY.-',
-	'Inpatient Record': 'HLC-INP-.YYYY.-',
 	'Installation Note': 'MAT-INS-.YYYY.-',
 	'Instructor': 'EDU-INS-.YYYY.-',
 	'Issue': 'ISS-.YYYY.-',
 	'Journal Entry': 'ACC-JV-.YYYY.-',
-	'Lab Test': 'HLC-LT-.YYYY.-',
 	'Landed Cost Voucher': 'MAT-LCV-.YYYY.-',
 	'Lead': 'CRM-LEAD-.YYYY.-',
 	'Leave Allocation': 'HR-LAL-.YYYY.-',
@@ -43,9 +40,6 @@
 	'Member': 'NPO-MEM-.YYYY.-',
 	'Opportunity': 'CRM-OPP-.YYYY.-',
 	'Packing Slip': 'MAT-PAC-.YYYY.-',
-	'Patient': 'HLC-PAT-.YYYY.-',
-	'Patient Encounter': 'HLC-ENC-.YYYY.-',
-	'Patient Medical Record': 'HLC-PMR-.YYYY.-',
 	'Payment Entry': 'ACC-PAY-.YYYY.-',
 	'Payment Request': 'ACC-PRQ-.YYYY.-',
 	'Production Plan': 'MFG-PP-.YYYY.-',
diff --git a/erpnext/patches/v11_0/rename_health_insurance.py b/erpnext/patches/v11_0/rename_health_insurance.py
deleted file mode 100644
index a4f53b0..0000000
--- a/erpnext/patches/v11_0/rename_health_insurance.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright (c) 2018, Frappe and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-
-import frappe
-
-
-def execute():
-	frappe.rename_doc('DocType', 'Health Insurance', 'Employee Health Insurance', force=True)
-	frappe.reload_doc('hr', 'doctype', 'employee_health_insurance')
diff --git a/erpnext/patches/v11_0/rename_healthcare_doctype_and_fields.py b/erpnext/patches/v11_0/rename_healthcare_doctype_and_fields.py
deleted file mode 100644
index 7a8c52f..0000000
--- a/erpnext/patches/v11_0/rename_healthcare_doctype_and_fields.py
+++ /dev/null
@@ -1,67 +0,0 @@
-from __future__ import unicode_literals
-
-import frappe
-from frappe.model.utils.rename_field import rename_field
-from frappe.modules import get_doctype_module, scrub
-
-field_rename_map = {
-	"Patient Encounter": [
-		["consultation_time", "encounter_time"],
-		["consultation_date", "encounter_date"],
-		["consultation_comment", "encounter_comment"],
-		["physician", "practitioner"]
-	],
-	"Fee Validity": [
-		["physician", "practitioner"]
-	],
-	"Lab Test": [
-		["physician", "practitioner"]
-	],
-	"Patient Appointment": [
-		["physician", "practitioner"],
-		["referring_physician", "referring_practitioner"]
-	],
-	"Procedure Prescription": [
-		["physician", "practitioner"]
-	]
-}
-
-doc_rename_map = {
-	"Physician Schedule Time Slot": "Healthcare Schedule Time Slot",
-	"Physician Schedule": "Practitioner Schedule",
-	"Physician Service Unit Schedule": "Practitioner Service Unit Schedule",
-	"Consultation": "Patient Encounter",
-	"Physician": "Healthcare Practitioner"
-}
-
-def execute():
-	for dt in doc_rename_map:
-		if frappe.db.exists('DocType', dt):
-			frappe.rename_doc('DocType', dt, doc_rename_map[dt], force=True)
-
-	for dn in field_rename_map:
-		if frappe.db.exists('DocType', dn):
-			frappe.reload_doc(get_doctype_module(dn), "doctype", scrub(dn))
-
-	for dt, field_list in field_rename_map.items():
-		if frappe.db.exists('DocType', dt):
-			for field in field_list:
-				if frappe.db.has_column(dt, field[0]):
-					rename_field(dt, field[0], field[1])
-
-	if frappe.db.exists('DocType', 'Practitioner Service Unit Schedule'):
-		if frappe.db.has_column('Practitioner Service Unit Schedule', 'parentfield'):
-			frappe.db.sql("""
-				update `tabPractitioner Service Unit Schedule` set parentfield = 'practitioner_schedules'
-				where parentfield = 'physician_schedules' and parenttype = 'Healthcare Practitioner'
-			""")
-
-	if frappe.db.exists("DocType", "Healthcare Practitioner"):
-		frappe.reload_doc("healthcare", "doctype", "healthcare_practitioner")
-		frappe.reload_doc("healthcare", "doctype", "practitioner_service_unit_schedule")
-		if frappe.db.has_column('Healthcare Practitioner', 'physician_schedule'):
-			for doc in frappe.get_all('Healthcare Practitioner'):
-				_doc = frappe.get_doc('Healthcare Practitioner', doc.name)
-				if _doc.physician_schedule:
-					_doc.append('practitioner_schedules', {'schedule': _doc.physician_schedule})
-					_doc.save()
diff --git a/erpnext/patches/v11_0/rename_healthcare_fields.py b/erpnext/patches/v11_0/rename_healthcare_fields.py
deleted file mode 100644
index 5c96367..0000000
--- a/erpnext/patches/v11_0/rename_healthcare_fields.py
+++ /dev/null
@@ -1,54 +0,0 @@
-from __future__ import unicode_literals
-
-import frappe
-from frappe.model.utils.rename_field import rename_field
-from frappe.modules import get_doctype_module, scrub
-
-lab_test_name = ["test_name", "lab_test_name"]
-lab_test_code = ["test_code", "lab_test_code"]
-lab_test_comment = ["test_comment", "lab_test_comment"]
-lab_test_created = ["test_created", "lab_test_created"]
-lab_test_template = ["test_template", "lab_test_template"]
-lab_test_rate = ["test_rate", "lab_test_rate"]
-lab_test_description = ["test_description", "lab_test_description"]
-lab_test_group = ["test_group", "lab_test_group"]
-lab_test_template_type = ["test_template_type", "lab_test_template_type"]
-lab_test_uom = ["test_uom", "lab_test_uom"]
-lab_test_normal_range = ["test_normal_range", "lab_test_normal_range"]
-lab_test_event = ["test_event", "lab_test_event"]
-lab_test_particulars = ["test_particulars", "lab_test_particulars"]
-
-field_rename_map = {
-	"Lab Test Template": [lab_test_name, lab_test_code, lab_test_rate, lab_test_description,
-		lab_test_group, lab_test_template_type, lab_test_uom, lab_test_normal_range],
-	"Normal Test Items": [lab_test_name, lab_test_comment, lab_test_uom, lab_test_event],
-	"Lab Test": [lab_test_name, lab_test_comment, lab_test_group],
-	"Lab Prescription": [lab_test_name, lab_test_code, lab_test_comment, lab_test_created],
-	"Lab Test Groups": [lab_test_template, lab_test_rate, lab_test_description],
-	"Lab Test UOM": [lab_test_uom],
-	"Normal Test Template": [lab_test_uom, lab_test_event],
-	"Special Test Items": [lab_test_particulars]
-}
-
-
-def execute():
-	for dt, field_list in field_rename_map.items():
-		if frappe.db.exists('DocType', dt):
-			frappe.reload_doc(get_doctype_module(dt), "doctype", scrub(dt))
-			for field in field_list:
-				if frappe.db.has_column(dt, field[0]):
-					rename_field(dt, field[0], field[1])
-
-	if frappe.db.exists('DocType', 'Lab Prescription'):
-		if frappe.db.has_column('Lab Prescription', 'parentfield'):
-			frappe.db.sql("""
-				update `tabLab Prescription` set parentfield = 'lab_test_prescription'
-				where parentfield = 'test_prescription'
-			""")
-
-	if frappe.db.exists('DocType', 'Lab Test Groups'):
-		if frappe.db.has_column('Lab Test Groups', 'parentfield'):
-			frappe.db.sql("""
-				update `tabLab Test Groups` set parentfield = 'lab_test_groups'
-				where parentfield = 'test_groups'
-			""")
diff --git a/erpnext/patches/v12_0/update_appointment_reminder_scheduler_entry.py b/erpnext/patches/v12_0/update_appointment_reminder_scheduler_entry.py
deleted file mode 100644
index 024cb2b..0000000
--- a/erpnext/patches/v12_0/update_appointment_reminder_scheduler_entry.py
+++ /dev/null
@@ -1,8 +0,0 @@
-import frappe
-
-
-def execute():
-	job = frappe.db.exists('Scheduled Job Type', 'patient_appointment.send_appointment_reminder')
-	if job:
-		method = 'erpnext.healthcare.doctype.patient_appointment.patient_appointment.send_appointment_reminder'
-		frappe.db.set_value('Scheduled Job Type', job, 'method', method)
diff --git a/erpnext/patches/v13_0/add_default_interview_notification_templates.py b/erpnext/patches/v13_0/add_default_interview_notification_templates.py
new file mode 100644
index 0000000..5e8a27f
--- /dev/null
+++ b/erpnext/patches/v13_0/add_default_interview_notification_templates.py
@@ -0,0 +1,37 @@
+from __future__ import unicode_literals
+
+import os
+
+import frappe
+from frappe import _
+
+
+def execute():
+	if not frappe.db.exists('Email Template', _('Interview Reminder')):
+		base_path = frappe.get_app_path('erpnext', 'hr', 'doctype')
+		response = frappe.read_file(os.path.join(base_path, 'interview/interview_reminder_notification_template.html'))
+
+		frappe.get_doc({
+			'doctype': 'Email Template',
+			'name': _('Interview Reminder'),
+			'response': response,
+			'subject': _('Interview Reminder'),
+			'owner': frappe.session.user,
+		}).insert(ignore_permissions=True)
+
+	if not frappe.db.exists('Email Template', _('Interview Feedback Reminder')):
+		base_path = frappe.get_app_path('erpnext', 'hr', 'doctype')
+		response = frappe.read_file(os.path.join(base_path, 'interview/interview_feedback_reminder_template.html'))
+
+		frappe.get_doc({
+			'doctype': 'Email Template',
+			'name': _('Interview Feedback Reminder'),
+			'response': response,
+			'subject': _('Interview Feedback Reminder'),
+			'owner': frappe.session.user,
+		}).insert(ignore_permissions=True)
+
+	hr_settings = frappe.get_doc('HR Settings')
+	hr_settings.interview_reminder_template = _('Interview Reminder')
+	hr_settings.feedback_reminder_notification_template = _('Interview Feedback Reminder')
+	hr_settings.save()
diff --git a/erpnext/patches/v13_0/create_accounting_dimensions_in_pos_doctypes.py b/erpnext/patches/v13_0/create_accounting_dimensions_in_pos_doctypes.py
new file mode 100644
index 0000000..4450108
--- /dev/null
+++ b/erpnext/patches/v13_0/create_accounting_dimensions_in_pos_doctypes.py
@@ -0,0 +1,42 @@
+import frappe
+from frappe.custom.doctype.custom_field.custom_field import create_custom_field
+
+
+def execute():
+	frappe.reload_doc('accounts', 'doctype', 'accounting_dimension')
+	accounting_dimensions = frappe.db.sql("""select fieldname, label, document_type, disabled from
+		`tabAccounting Dimension`""", as_dict=1)
+
+	if not accounting_dimensions:
+		return
+
+	count = 1
+	for d in accounting_dimensions:
+
+		if count % 2 == 0:
+			insert_after_field = 'dimension_col_break'
+		else:
+			insert_after_field = 'accounting_dimensions_section'
+
+		for doctype in ["POS Invoice", "POS Invoice Item"]:
+
+			field = frappe.db.get_value("Custom Field", {"dt": doctype, "fieldname": d.fieldname})
+
+			if field:
+				continue
+			meta = frappe.get_meta(doctype, cached=False)
+			fieldnames = [d.fieldname for d in meta.get("fields")]
+
+			df = {
+				"fieldname": d.fieldname,
+				"label": d.label,
+				"fieldtype": "Link",
+				"options": d.document_type,
+				"insert_after": insert_after_field
+			}
+
+			if df['fieldname'] not in fieldnames:
+				create_custom_field(doctype, df)
+				frappe.clear_cache(doctype=doctype)
+
+		count += 1
diff --git a/erpnext/patches/v13_0/create_custom_field_for_finance_book.py b/erpnext/patches/v13_0/create_custom_field_for_finance_book.py
new file mode 100644
index 0000000..313b0e9
--- /dev/null
+++ b/erpnext/patches/v13_0/create_custom_field_for_finance_book.py
@@ -0,0 +1,21 @@
+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_field = {
+		'Finance Book': [
+			{
+				'fieldname': 'for_income_tax',
+				'label': 'For Income Tax',
+				'fieldtype': 'Check',
+				'insert_after': 'finance_book_name',
+				'description': 'If the asset is put to use for less than 180 days, the first Depreciation Rate will be reduced by 50%.'
+			}
+		]
+	}
+	create_custom_fields(custom_field, update=1)
diff --git a/erpnext/patches/v13_0/create_healthcare_custom_fields_in_stock_entry_detail.py b/erpnext/patches/v13_0/create_healthcare_custom_fields_in_stock_entry_detail.py
deleted file mode 100644
index 543faeb..0000000
--- a/erpnext/patches/v13_0/create_healthcare_custom_fields_in_stock_entry_detail.py
+++ /dev/null
@@ -1,12 +0,0 @@
-import frappe
-from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
-
-from erpnext.domains.healthcare import data
-
-
-def execute():
-	if 'Healthcare' not in frappe.get_active_domains():
-		return
-
-	if data['custom_fields']:
-		create_custom_fields(data['custom_fields'])
diff --git a/erpnext/patches/v13_0/fix_additional_cost_in_mfg_stock_entry.py b/erpnext/patches/v13_0/fix_additional_cost_in_mfg_stock_entry.py
new file mode 100644
index 0000000..aeb8d8e
--- /dev/null
+++ b/erpnext/patches/v13_0/fix_additional_cost_in_mfg_stock_entry.py
@@ -0,0 +1,76 @@
+from typing import List, NewType
+
+import frappe
+
+StockEntryCode = NewType("StockEntryCode", str)
+
+
+def execute():
+	stock_entry_codes = find_broken_stock_entries()
+
+	for stock_entry_code in stock_entry_codes:
+		patched_stock_entry = patch_additional_cost(stock_entry_code)
+		create_repost_item_valuation(patched_stock_entry)
+
+
+def find_broken_stock_entries() -> List[StockEntryCode]:
+	period_closing_date = frappe.db.get_value(
+		"Period Closing Voucher", {"docstatus": 1}, "posting_date", order_by="posting_date desc"
+	)
+
+	stock_entries_to_patch = frappe.db.sql(
+		"""
+		select se.name, sum(sed.additional_cost) as item_additional_cost, se.total_additional_costs
+		from `tabStock Entry` se
+		join `tabStock Entry Detail` sed
+			on sed.parent = se.name
+		where
+			se.docstatus = 1 and
+			se.posting_date > %s
+		group by
+			sed.parent
+		having
+			item_additional_cost != se.total_additional_costs
+	""",
+		period_closing_date,
+		as_dict=True,
+	)
+
+	return [d.name for d in stock_entries_to_patch]
+
+
+def patch_additional_cost(code: StockEntryCode):
+	stock_entry = frappe.get_doc("Stock Entry", code)
+	stock_entry.distribute_additional_costs()
+	stock_entry.update_valuation_rate()
+	stock_entry.set_total_incoming_outgoing_value()
+	stock_entry.set_total_amount()
+	stock_entry.db_update()
+	for item in stock_entry.items:
+		item.db_update()
+	return stock_entry
+
+
+def create_repost_item_valuation(stock_entry):
+	from erpnext.controllers.stock_controller import create_repost_item_valuation_entry
+
+	# turn on recalculate flag so reposting corrects the incoming/outgoing rates.
+	frappe.db.set_value(
+		"Stock Ledger Entry",
+		{"voucher_no": stock_entry.name, "actual_qty": (">", 0)},
+		"recalculate_rate",
+		1,
+		update_modified=False,
+	)
+
+	create_repost_item_valuation_entry(
+		args=frappe._dict(
+			{
+				"posting_date": stock_entry.posting_date,
+				"posting_time": stock_entry.posting_time,
+				"voucher_type": stock_entry.doctype,
+				"voucher_no": stock_entry.name,
+				"company": stock_entry.company,
+			}
+		)
+	)
diff --git a/erpnext/patches/v13_0/gst_fields_for_pos_invoice.py b/erpnext/patches/v13_0/gst_fields_for_pos_invoice.py
new file mode 100644
index 0000000..5b790d9
--- /dev/null
+++ b/erpnext/patches/v13_0/gst_fields_for_pos_invoice.py
@@ -0,0 +1,44 @@
+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'}, fields=['name'])
+	if not company:
+		return
+
+	hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC',
+		fieldtype='Data', fetch_from='item_code.gst_hsn_code', insert_after='description',
+		allow_on_submit=1, print_hide=1, fetch_if_empty=1)
+	nil_rated_exempt = dict(fieldname='is_nil_exempt', label='Is Nil Rated or Exempted',
+		fieldtype='Check', fetch_from='item_code.is_nil_exempt', insert_after='gst_hsn_code',
+		print_hide=1)
+	is_non_gst = dict(fieldname='is_non_gst', label='Is Non GST',
+		fieldtype='Check', fetch_from='item_code.is_non_gst', insert_after='is_nil_exempt',
+		print_hide=1)
+	taxable_value = dict(fieldname='taxable_value', label='Taxable Value',
+		fieldtype='Currency', insert_after='base_net_amount', hidden=1, options="Company:company:default_currency",
+		print_hide=1)
+	sales_invoice_gst_fields = [
+			dict(fieldname='billing_address_gstin', label='Billing Address GSTIN',
+				fieldtype='Data', insert_after='customer_address', read_only=1,
+				fetch_from='customer_address.gstin', print_hide=1),
+			dict(fieldname='customer_gstin', label='Customer GSTIN',
+				fieldtype='Data', insert_after='shipping_address_name',
+				fetch_from='shipping_address_name.gstin', print_hide=1),
+			dict(fieldname='place_of_supply', label='Place of Supply',
+				fieldtype='Data', insert_after='customer_gstin',
+				print_hide=1, read_only=1),
+			dict(fieldname='company_gstin', label='Company GSTIN',
+				fieldtype='Data', insert_after='company_address',
+				fetch_from='company_address.gstin', print_hide=1, read_only=1),
+		]
+
+	custom_fields = {
+		'POS Invoice': sales_invoice_gst_fields,
+		'POS Invoice Item': [hsn_sac_field, nil_rated_exempt, is_non_gst, taxable_value],
+	}
+
+	create_custom_fields(custom_fields, update=True)
\ No newline at end of file
diff --git a/erpnext/patches/v13_0/healthcare_deprecation_warning.py b/erpnext/patches/v13_0/healthcare_deprecation_warning.py
new file mode 100644
index 0000000..c6fba59
--- /dev/null
+++ b/erpnext/patches/v13_0/healthcare_deprecation_warning.py
@@ -0,0 +1,10 @@
+import click
+
+
+def execute():
+
+	click.secho(
+		"Healthcare Module is moved to a separate app and will be removed from ERPNext in version-14.\n"
+		"Please install the app to continue using the module: https://github.com/frappe/healthcare",
+		fg="yellow",
+	)
diff --git a/erpnext/patches/v13_0/modify_invalid_gain_loss_gl_entries.py b/erpnext/patches/v13_0/modify_invalid_gain_loss_gl_entries.py
new file mode 100644
index 0000000..fa8a864
--- /dev/null
+++ b/erpnext/patches/v13_0/modify_invalid_gain_loss_gl_entries.py
@@ -0,0 +1,49 @@
+from __future__ import unicode_literals
+
+import json
+
+import frappe
+
+
+def execute():
+	frappe.reload_doc('accounts', 'doctype', 'purchase_invoice_advance')
+	frappe.reload_doc('accounts', 'doctype', 'sales_invoice_advance')
+
+	purchase_invoices = frappe.db.sql("""
+		select
+			parenttype as type, parent as name
+		from
+			`tabPurchase Invoice Advance`
+		where
+			ref_exchange_rate = 1
+			and docstatus = 1
+			and ifnull(exchange_gain_loss, '') != ''
+		group by
+			parent
+	""", as_dict=1)
+
+	sales_invoices = frappe.db.sql("""
+		select
+			parenttype as type, parent as name
+		from
+			`tabSales Invoice Advance`
+		where
+			ref_exchange_rate = 1
+			and docstatus = 1
+			and ifnull(exchange_gain_loss, '') != ''
+		group by
+			parent
+	""", as_dict=1)
+
+	if purchase_invoices + sales_invoices:
+		frappe.log_error(json.dumps(purchase_invoices + sales_invoices, indent=2), title="Patch Log")
+
+	for invoice in purchase_invoices + sales_invoices:
+		doc = frappe.get_doc(invoice.type, invoice.name)
+		doc.docstatus = 2
+		doc.make_gl_entries()
+		for advance in doc.advances:
+			if advance.ref_exchange_rate == 1:
+				advance.db_set('exchange_gain_loss', 0, False)
+		doc.docstatus = 1
+		doc.make_gl_entries()
\ No newline at end of file
diff --git a/erpnext/patches/v13_0/replace_supplier_item_group_with_party_specific_item.py b/erpnext/patches/v13_0/replace_supplier_item_group_with_party_specific_item.py
new file mode 100644
index 0000000..ba96fdd
--- /dev/null
+++ b/erpnext/patches/v13_0/replace_supplier_item_group_with_party_specific_item.py
@@ -0,0 +1,17 @@
+# Copyright (c) 2019, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+import frappe
+
+
+def execute():
+	if frappe.db.table_exists('Supplier Item Group'):
+		frappe.reload_doc("selling", "doctype", "party_specific_item")
+		sig = frappe.db.get_all("Supplier Item Group", fields=["name", "supplier", "item_group"])
+		for item in sig:
+			psi = frappe.new_doc("Party Specific Item")
+			psi.party_type = "Supplier"
+			psi.party = item.supplier
+			psi.restrict_based_on = "Item Group"
+			psi.based_on_value = item.item_group
+			psi.insert()
diff --git a/erpnext/patches/v13_0/set_status_in_maintenance_schedule_table.py b/erpnext/patches/v13_0/set_status_in_maintenance_schedule_table.py
new file mode 100644
index 0000000..9887ad9
--- /dev/null
+++ b/erpnext/patches/v13_0/set_status_in_maintenance_schedule_table.py
@@ -0,0 +1,10 @@
+import frappe
+
+
+def execute():
+	frappe.reload_doc("maintenance", "doctype", "Maintenance Schedule Detail")
+	frappe.db.sql("""
+		UPDATE `tabMaintenance Schedule Detail`
+		SET completion_status = 'Pending'
+		WHERE docstatus < 2
+	""")
diff --git a/erpnext/patches/v13_0/setup_patient_history_settings_for_standard_doctypes.py b/erpnext/patches/v13_0/setup_patient_history_settings_for_standard_doctypes.py
deleted file mode 100644
index 80622d4..0000000
--- a/erpnext/patches/v13_0/setup_patient_history_settings_for_standard_doctypes.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from __future__ import unicode_literals
-
-import frappe
-
-from erpnext.healthcare.setup import setup_patient_history_settings
-
-
-def execute():
-	if "Healthcare" not in frappe.get_active_domains():
-		return
-
-	frappe.reload_doc("healthcare", "doctype", "Inpatient Medication Order")
-	frappe.reload_doc("healthcare", "doctype", "Therapy Session")
-	frappe.reload_doc("healthcare", "doctype", "Clinical Procedure")
-	frappe.reload_doc("healthcare", "doctype", "Patient History Settings")
-	frappe.reload_doc("healthcare", "doctype", "Patient History Standard Document Type")
-	frappe.reload_doc("healthcare", "doctype", "Patient History Custom Document Type")
-
-	setup_patient_history_settings()
diff --git a/erpnext/patches/v13_0/trim_sales_invoice_custom_field_length.py b/erpnext/patches/v13_0/trim_sales_invoice_custom_field_length.py
new file mode 100644
index 0000000..fd48c0d
--- /dev/null
+++ b/erpnext/patches/v13_0/trim_sales_invoice_custom_field_length.py
@@ -0,0 +1,18 @@
+# Copyright (c) 2020, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+import frappe
+
+from erpnext.regional.india.setup import create_custom_fields, get_custom_fields
+
+
+def execute():
+	company = frappe.get_all('Company', filters = {'country': 'India'})
+	if not company:
+		return
+
+	custom_fields = {
+		'Sales Invoice': get_custom_fields().get('Sales Invoice')
+	}
+
+	create_custom_fields(custom_fields, update=True)
diff --git a/erpnext/patches/v13_0/update_dates_in_tax_withholding_category.py b/erpnext/patches/v13_0/update_dates_in_tax_withholding_category.py
new file mode 100644
index 0000000..90fb50f
--- /dev/null
+++ b/erpnext/patches/v13_0/update_dates_in_tax_withholding_category.py
@@ -0,0 +1,26 @@
+# Copyright (c) 2021, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+import frappe
+
+
+def execute():
+	frappe.reload_doc('accounts', 'doctype', 'Tax Withholding Rate')
+
+	if frappe.db.has_column('Tax Withholding Rate', 'fiscal_year'):
+		tds_category_rates = frappe.get_all('Tax Withholding Rate', fields=['name', 'fiscal_year'])
+
+		fiscal_year_map = {}
+		fiscal_year_details = frappe.get_all('Fiscal Year', fields=['name', 'year_start_date', 'year_end_date'])
+
+		for d in fiscal_year_details:
+			fiscal_year_map.setdefault(d.name, d)
+
+		for rate in tds_category_rates:
+			from_date = fiscal_year_map.get(rate.fiscal_year).get('year_start_date')
+			to_date = fiscal_year_map.get(rate.fiscal_year).get('year_end_date')
+
+			frappe.db.set_value('Tax Withholding Rate', rate.name, {
+				'from_date': from_date,
+				'to_date': to_date
+			})
\ No newline at end of file
diff --git a/erpnext/patches/v13_0/update_returned_qty_in_pr_dn.py b/erpnext/patches/v13_0/update_returned_qty_in_pr_dn.py
index efb3a59..dd64e05 100644
--- a/erpnext/patches/v13_0/update_returned_qty_in_pr_dn.py
+++ b/erpnext/patches/v13_0/update_returned_qty_in_pr_dn.py
@@ -13,7 +13,7 @@
 	frappe.reload_doc('stock', 'doctype', 'stock_settings')
 
 	def update_from_return_docs(doctype):
-		for return_doc in frappe.get_all(doctype, filters={'is_return' : 1, 'docstatus' : 1}):
+		for return_doc in frappe.get_all(doctype, filters={'is_return' : 1, 'docstatus' : 1, 'return_against': ('!=', '')}):
 			# Update original receipt/delivery document from return
 			return_doc = frappe.get_cached_doc(doctype, return_doc.name)
 			try:
diff --git a/erpnext/payroll/doctype/additional_salary/additional_salary.py b/erpnext/payroll/doctype/additional_salary/additional_salary.py
index ed10f2b..7c0a8ea 100644
--- a/erpnext/payroll/doctype/additional_salary/additional_salary.py
+++ b/erpnext/payroll/doctype/additional_salary/additional_salary.py
@@ -14,12 +14,11 @@
 
 class AdditionalSalary(Document):
 	def on_submit(self):
-		if self.ref_doctype == "Employee Advance" and self.ref_docname:
-			frappe.db.set_value("Employee Advance", self.ref_docname, "return_amount", self.amount)
-
+		self.update_return_amount_in_employee_advance()
 		self.update_employee_referral()
 
 	def on_cancel(self):
+		self.update_return_amount_in_employee_advance()
 		self.update_employee_referral(cancel=True)
 
 	def validate(self):
@@ -98,6 +97,17 @@
 				frappe.throw(_("Additional Salary for referral bonus can only be created against Employee Referral with status {0}").format(
 					frappe.bold("Accepted")))
 
+	def update_return_amount_in_employee_advance(self):
+		if self.ref_doctype == "Employee Advance" and self.ref_docname:
+			return_amount = frappe.db.get_value("Employee Advance", self.ref_docname, "return_amount")
+
+			if self.docstatus == 2:
+				return_amount -= self.amount
+			else:
+				return_amount += self.amount
+
+			frappe.db.set_value("Employee Advance", self.ref_docname, "return_amount", return_amount)
+
 	def update_employee_referral(self, cancel=False):
 		if self.ref_doctype == "Employee Referral":
 			status = "Unpaid" if cancel else "Paid"
diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.json b/erpnext/payroll/doctype/salary_slip/salary_slip.json
index 1974403..7a80e69 100644
--- a/erpnext/payroll/doctype/salary_slip/salary_slip.json
+++ b/erpnext/payroll/doctype/salary_slip/salary_slip.json
@@ -329,7 +329,7 @@
   {
    "fieldname": "earning_deduction",
    "fieldtype": "Section Break",
-   "label": "Earning & Deduction",
+   "label": "Earnings & Deductions",
    "oldfieldtype": "Section Break"
   },
   {
@@ -380,7 +380,7 @@
    "depends_on": "total_loan_repayment",
    "fieldname": "loan_repayment",
    "fieldtype": "Section Break",
-   "label": "Loan repayment"
+   "label": "Loan Repayment"
   },
   {
    "fieldname": "loans",
@@ -425,7 +425,7 @@
   {
    "fieldname": "net_pay_info",
    "fieldtype": "Section Break",
-   "label": "net pay info"
+   "label": "Net Pay Info"
   },
   {
    "fieldname": "net_pay",
@@ -647,7 +647,7 @@
  "idx": 9,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-09-01 10:35:52.374549",
+ "modified": "2021-10-08 11:47:47.098248",
  "modified_by": "Administrator",
  "module": "Payroll",
  "name": "Salary Slip",
diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.py b/erpnext/payroll/doctype/salary_slip/salary_slip.py
index 8c48345..d113e7e 100644
--- a/erpnext/payroll/doctype/salary_slip/salary_slip.py
+++ b/erpnext/payroll/doctype/salary_slip/salary_slip.py
@@ -487,7 +487,7 @@
 			self.calculate_component_amounts("deductions")
 
 		self.set_loan_repayment()
-		self.set_component_amounts_based_on_payment_days()
+		self.set_precision_for_component_amounts()
 		self.set_net_pay()
 
 	def set_net_pay(self):
@@ -709,6 +709,17 @@
 
 		component_row.amount = amount
 
+		self.update_component_amount_based_on_payment_days(component_row)
+
+	def update_component_amount_based_on_payment_days(self, component_row):
+		joining_date, relieving_date = self.get_joining_and_relieving_dates()
+		component_row.amount = self.get_amount_based_on_payment_days(component_row, joining_date, relieving_date)[0]
+
+	def set_precision_for_component_amounts(self):
+		for component_type in ("earnings", "deductions"):
+			for component_row in self.get(component_type):
+				component_row.amount = flt(component_row.amount, component_row.precision("amount"))
+
 	def calculate_variable_based_on_taxable_salary(self, tax_component, payroll_period):
 		if not payroll_period:
 			frappe.msgprint(_("Start and end dates not in a valid Payroll Period, cannot calculate {0}.")
@@ -866,14 +877,7 @@
 		return total_tax_paid
 
 	def get_taxable_earnings(self, allow_tax_exemption=False, based_on_payment_days=0):
-		joining_date, relieving_date = frappe.get_cached_value("Employee", self.employee,
-			["date_of_joining", "relieving_date"])
-
-		if not relieving_date:
-			relieving_date = getdate(self.end_date)
-
-		if not joining_date:
-			frappe.throw(_("Please set the Date Of Joining for employee {0}").format(frappe.bold(self.employee_name)))
+		joining_date, relieving_date = self.get_joining_and_relieving_dates()
 
 		taxable_earnings = 0
 		additional_income = 0
@@ -884,7 +888,10 @@
 			if based_on_payment_days:
 				amount, additional_amount = self.get_amount_based_on_payment_days(earning, joining_date, relieving_date)
 			else:
-				amount, additional_amount = earning.amount, earning.additional_amount
+				if earning.additional_amount:
+					amount, additional_amount = earning.amount, earning.additional_amount
+				else:
+					amount, additional_amount = earning.default_amount, earning.additional_amount
 
 			if earning.is_tax_applicable:
 				if additional_amount:
@@ -1055,7 +1062,7 @@
 				total += amount
 		return total
 
-	def set_component_amounts_based_on_payment_days(self):
+	def get_joining_and_relieving_dates(self):
 		joining_date, relieving_date = frappe.get_cached_value("Employee", self.employee,
 			["date_of_joining", "relieving_date"])
 
@@ -1065,9 +1072,7 @@
 		if not joining_date:
 			frappe.throw(_("Please set the Date Of Joining for employee {0}").format(frappe.bold(self.employee_name)))
 
-		for component_type in ("earnings", "deductions"):
-			for d in self.get(component_type):
-				d.amount = flt(self.get_amount_based_on_payment_days(d, joining_date, relieving_date)[0], d.precision("amount"))
+		return joining_date, relieving_date
 
 	def set_loan_repayment(self):
 		self.total_loan_repayment = 0
diff --git a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
index 480daa2..178cd5c 100644
--- a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
@@ -17,6 +17,7 @@
 	getdate,
 	nowdate,
 )
+from frappe.utils.make_random import get_random
 
 import erpnext
 from erpnext.accounts.utils import get_fiscal_year
@@ -134,6 +135,59 @@
 
 		frappe.db.set_value("Payroll Settings", None, "payroll_based_on", "Leave")
 
+	def test_component_amount_dependent_on_another_payment_days_based_component(self):
+		from erpnext.hr.doctype.attendance.attendance import mark_attendance
+		from erpnext.payroll.doctype.salary_structure.test_salary_structure import (
+			create_salary_structure_assignment,
+		)
+
+		# Payroll based on attendance
+		frappe.db.set_value("Payroll Settings", None, "payroll_based_on", "Attendance")
+
+		salary_structure = make_salary_structure_for_payment_days_based_component_dependency()
+		employee = make_employee("test_payment_days_based_component@salary.com", company="_Test Company")
+
+		# base = 50000
+		create_salary_structure_assignment(employee, salary_structure.name, company="_Test Company", currency="INR")
+
+		# mark employee absent for a day since this case works fine if payment days are equal to working days
+		month_start_date = get_first_day(nowdate())
+		month_end_date = get_last_day(nowdate())
+
+		first_sunday = frappe.db.sql("""
+			select holiday_date from `tabHoliday`
+			where parent = 'Salary Slip Test Holiday List'
+				and holiday_date between %s and %s
+			order by holiday_date
+		""", (month_start_date, month_end_date))[0][0]
+
+		mark_attendance(employee, add_days(first_sunday, 1), 'Absent', ignore_validate=True) # counted as absent
+
+		# make salary slip and assert payment days
+		ss = make_salary_slip_for_payment_days_dependency_test("test_payment_days_based_component@salary.com", salary_structure.name)
+		self.assertEqual(ss.absent_days, 1)
+
+		ss.reload()
+		payment_days_based_comp_amount = 0
+		for component in ss.earnings:
+			if component.salary_component == "HRA - Payment Days":
+				payment_days_based_comp_amount = flt(component.amount, component.precision("amount"))
+				break
+
+		# check if the dependent component is calculated using the amount updated after payment days
+		actual_amount = 0
+		precision = 0
+		for component in ss.deductions:
+			if component.salary_component == "P - Employee Provident Fund":
+				precision = component.precision("amount")
+				actual_amount = flt(component.amount, precision)
+				break
+
+		expected_amount = flt((flt(ss.gross_pay) - payment_days_based_comp_amount) * 0.12, precision)
+
+		self.assertEqual(actual_amount, expected_amount)
+		frappe.db.set_value("Payroll Settings", None, "payroll_based_on", "Leave")
+
 	def test_salary_slip_with_holidays_included(self):
 		no_of_days = self.get_no_of_days()
 		frappe.db.set_value("Payroll Settings", None, "include_holidays_in_total_working_days", 1)
@@ -864,3 +918,92 @@
 		holiday_list = holiday_list.name
 
 	return holiday_list
+
+def make_salary_structure_for_payment_days_based_component_dependency():
+	earnings = [
+		{
+			"salary_component": "Basic Salary - Payment Days",
+			"abbr": "P_BS",
+			"type": "Earning",
+			"formula": "base",
+			"amount_based_on_formula": 1
+		},
+		{
+			"salary_component": "HRA - Payment Days",
+			"abbr": "P_HRA",
+			"type": "Earning",
+			"depends_on_payment_days": 1,
+			"amount_based_on_formula": 1,
+			"formula": "base * 0.20"
+		}
+	]
+
+	make_salary_component(earnings, False, company_list=["_Test Company"])
+
+	deductions = [
+		{
+			"salary_component": "P - Professional Tax",
+			"abbr": "P_PT",
+			"type": "Deduction",
+			"depends_on_payment_days": 1,
+			"amount": 200.00
+		},
+		{
+			"salary_component": "P - Employee Provident Fund",
+			"abbr": "P_EPF",
+			"type": "Deduction",
+			"exempted_from_income_tax": 1,
+			"amount_based_on_formula": 1,
+			"depends_on_payment_days": 0,
+			"formula": "(gross_pay - P_HRA) * 0.12"
+		}
+	]
+
+	make_salary_component(deductions, False, company_list=["_Test Company"])
+
+	salary_structure = "Salary Structure with PF"
+	if frappe.db.exists("Salary Structure", salary_structure):
+		frappe.db.delete("Salary Structure", salary_structure)
+
+	details = {
+		"doctype": "Salary Structure",
+		"name": salary_structure,
+		"company": "_Test Company",
+		"payroll_frequency": "Monthly",
+		"payment_account": get_random("Account", filters={"account_currency": "INR"}),
+		"currency": "INR"
+	}
+
+	salary_structure_doc = frappe.get_doc(details)
+
+	for entry in earnings:
+		salary_structure_doc.append("earnings", entry)
+
+	for entry in deductions:
+		salary_structure_doc.append("deductions", entry)
+
+	salary_structure_doc.insert()
+	salary_structure_doc.submit()
+
+	return salary_structure_doc
+
+def make_salary_slip_for_payment_days_dependency_test(employee, salary_structure):
+	employee = frappe.db.get_value(
+		"Employee",
+		{"user_id": employee},
+		["name", "company", "employee_name"],
+		as_dict=True
+	)
+
+	salary_slip_name = frappe.db.get_value("Salary Slip", {"employee": employee.name})
+
+	if not salary_slip_name:
+		salary_slip = make_salary_slip(salary_structure, employee=employee.name)
+		salary_slip.employee_name = employee.employee_name
+		salary_slip.payroll_frequency = "Monthly"
+		salary_slip.posting_date = nowdate()
+		salary_slip.insert()
+	else:
+		salary_slip = frappe.get_doc("Salary Slip", salary_slip_name)
+
+	return salary_slip
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index 2a8870b..df970f3 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -144,6 +144,9 @@
 		if self.sales_order:
 			frappe.db.set_value("Sales Order", self.sales_order, "project", self.name)
 
+	def on_trash(self):
+		frappe.db.set_value("Sales Order", {"project": self.name}, "project", "")
+
 	def update_percent_complete(self):
 		if self.percent_complete_method == "Manual":
 			if self.status == "Completed":
diff --git a/erpnext/projects/doctype/project/test_project.py b/erpnext/projects/doctype/project/test_project.py
index ebc1326..c64ac8d 100644
--- a/erpnext/projects/doctype/project/test_project.py
+++ b/erpnext/projects/doctype/project/test_project.py
@@ -9,6 +9,8 @@
 
 from erpnext.projects.doctype.project_template.test_project_template import make_project_template
 from erpnext.projects.doctype.task.test_task import create_task
+from erpnext.selling.doctype.sales_order.sales_order import make_project as make_project_from_so
+from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
 
 test_records = frappe.get_test_records('Project')
 test_ignore = ["Sales Order"]
@@ -96,6 +98,21 @@
 
 		self.assertEqual(len(tasks), 2)
 
+	def test_project_linking_with_sales_order(self):
+		so = make_sales_order()
+		project = make_project_from_so(so.name)
+
+		project.save()
+		self.assertEqual(project.sales_order, so.name)
+
+		so.reload()
+		self.assertEqual(so.project, project.name)
+
+		project.delete()
+
+		so.reload()
+		self.assertFalse(so.project)
+
 def get_project(name, template):
 
 	project = frappe.get_doc(dict(
diff --git a/erpnext/projects/doctype/timesheet/timesheet.py b/erpnext/projects/doctype/timesheet/timesheet.py
index e144e82..363c3b6 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.py
+++ b/erpnext/projects/doctype/timesheet/timesheet.py
@@ -215,25 +215,47 @@
 
 @frappe.whitelist()
 def get_projectwise_timesheet_data(project=None, parent=None, from_time=None, to_time=None):
-	condition = ''
+	condition = ""
 	if project:
-		condition += "and tsd.project = %(project)s"
+		condition += "AND tsd.project = %(project)s "
 	if parent:
-		condition += "AND tsd.parent = %(parent)s"
+		condition += "AND tsd.parent = %(parent)s "
 	if from_time and to_time:
 		condition += "AND CAST(tsd.from_time as DATE) BETWEEN %(from_time)s AND %(to_time)s"
 
-	return frappe.db.sql("""SELECT tsd.name as name,
-				tsd.parent as parent, tsd.billing_hours as billing_hours,
-				tsd.billing_amount as billing_amount, tsd.activity_type as activity_type,
-				tsd.description as description, ts.currency as currency,
-				tsd.project_name as project_name
-			FROM `tabTimesheet Detail` tsd
-			INNER JOIN `tabTimesheet` ts ON ts.name = tsd.parent
-			WHERE tsd.parenttype = 'Timesheet'
-				and tsd.docstatus=1 {0}
-				and tsd.is_billable = 1
-				and tsd.sales_invoice is null""".format(condition), {'project': project, 'parent': parent, 'from_time': from_time, 'to_time': to_time}, as_dict=1)
+	query = f"""
+		SELECT
+			tsd.name as name,
+			tsd.parent as time_sheet,
+			tsd.from_time as from_time,
+			tsd.to_time as to_time,
+			tsd.billing_hours as billing_hours,
+			tsd.billing_amount as billing_amount,
+			tsd.activity_type as activity_type,
+			tsd.description as description,
+			ts.currency as currency,
+			tsd.project_name as project_name
+		FROM `tabTimesheet Detail` tsd
+			INNER JOIN `tabTimesheet` ts
+			ON ts.name = tsd.parent
+		WHERE
+			tsd.parenttype = 'Timesheet'
+			AND tsd.docstatus = 1
+			AND tsd.is_billable = 1
+			AND tsd.sales_invoice is NULL
+			{condition}
+		ORDER BY tsd.from_time ASC
+	"""
+
+	filters = {
+		"project": project,
+		"parent": parent,
+		"from_time": from_time,
+		"to_time": to_time
+	}
+
+	return frappe.db.sql(query, filters, as_dict=1)
+
 
 @frappe.whitelist()
 def get_timesheet_detail_rate(timelog, currency):
diff --git a/erpnext/public/js/bank_reconciliation_tool/dialog_manager.js b/erpnext/public/js/bank_reconciliation_tool/dialog_manager.js
index 239fbb9..ca73393 100644
--- a/erpnext/public/js/bank_reconciliation_tool/dialog_manager.js
+++ b/erpnext/public/js/bank_reconciliation_tool/dialog_manager.js
@@ -227,7 +227,7 @@
 			{
 				fieldtype: "HTML",
 				fieldname: "no_matching_vouchers",
-				options: "<div class='text-muted text-center'>No Matching Vouchers Found</div>"
+				options: "<div class=\"text-muted text-center\">No Matching Vouchers Found</div>"
 			},
 			{
 				fieldtype: "Section Break",
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index fd3d472..63fd8a1 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -345,26 +345,14 @@
 	}
 
 	scan_barcode() {
-		let scan_barcode_field = this.frm.fields_dict["scan_barcode"];
-
-		let show_description = function(idx, exist = null) {
-			if (exist) {
-				frappe.show_alert({
-					message: __('Row #{0}: Qty increased by 1', [idx]),
-					indicator: 'green'
-				});
-			} else {
-				frappe.show_alert({
-					message: __('Row #{0}: Item added', [idx]),
-					indicator: 'green'
-				});
-			}
-		}
+		let me = this;
 
 		if(this.frm.doc.scan_barcode) {
 			frappe.call({
 				method: "erpnext.selling.page.point_of_sale.point_of_sale.search_for_serial_or_batch_or_barcode_number",
-				args: { search_value: this.frm.doc.scan_barcode }
+				args: {
+					search_value: this.frm.doc.scan_barcode
+				}
 			}).then(r => {
 				const data = r && r.message;
 				if (!data || Object.keys(data).length === 0) {
@@ -375,49 +363,96 @@
 					return;
 				}
 
-				let cur_grid = this.frm.fields_dict.items.grid;
-
-				let row_to_modify = null;
-				const existing_item_row = this.frm.doc.items.find(d => d.item_code === data.item_code);
-				const blank_item_row = this.frm.doc.items.find(d => !d.item_code);
-
-				if (existing_item_row) {
-					row_to_modify = existing_item_row;
-				} else if (blank_item_row) {
-					row_to_modify = blank_item_row;
-				}
-
-				if (!row_to_modify) {
-					// add new row
-					row_to_modify = frappe.model.add_child(this.frm.doc, cur_grid.doctype, 'items');
-				}
-
-				show_description(row_to_modify.idx, row_to_modify.item_code);
-
-				this.frm.from_barcode = this.frm.from_barcode ? this.frm.from_barcode + 1 : 1;
-				frappe.model.set_value(row_to_modify.doctype, row_to_modify.name, {
-					item_code: data.item_code,
-					qty: (row_to_modify.qty || 0) + 1
-				});
-
-				['serial_no', 'batch_no', 'barcode'].forEach(field => {
-					if (data[field] && frappe.meta.has_field(row_to_modify.doctype, field)) {
-
-						let value = (row_to_modify[field] && field === "serial_no")
-							? row_to_modify[field] + '\n' + data[field] : data[field];
-
-						frappe.model.set_value(row_to_modify.doctype,
-							row_to_modify.name, field, value);
-					}
-				});
-
-				scan_barcode_field.set_value('');
-				refresh_field("items");
+				me.modify_table_after_scan(data);
 			});
 		}
 		return false;
 	}
 
+	modify_table_after_scan(data) {
+		let scan_barcode_field = this.frm.fields_dict["scan_barcode"];
+		let cur_grid = this.frm.fields_dict.items.grid;
+		let row_to_modify = null;
+
+		// Check if batch is scanned and table has batch no field
+		let batch_no_scan = Boolean(data.batch_no) && frappe.meta.has_field(cur_grid.doctype, "batch_no");
+
+		if (batch_no_scan) {
+			row_to_modify = this.get_batch_row_to_modify(data.batch_no);
+		} else {
+			// serial or barcode scan
+			row_to_modify = this.get_row_to_modify_on_scan(row_to_modify, data);
+		}
+
+		if (!row_to_modify) {
+			// add new row if new item/batch is scanned
+			row_to_modify = frappe.model.add_child(this.frm.doc, cur_grid.doctype, 'items');
+		}
+
+		this.show_scan_message(row_to_modify.idx, row_to_modify.item_code);
+		this.set_scanned_values(row_to_modify, data, scan_barcode_field);
+	}
+
+	set_scanned_values(row_to_modify, data, scan_barcode_field) {
+		// increase qty and set scanned value and item in row
+		this.frm.from_barcode = this.frm.from_barcode ? this.frm.from_barcode + 1 : 1;
+		frappe.model.set_value(row_to_modify.doctype, row_to_modify.name, {
+			item_code: data.item_code,
+			qty: (row_to_modify.qty || 0) + 1
+		});
+
+		['serial_no', 'batch_no', 'barcode'].forEach(field => {
+			if (data[field] && frappe.meta.has_field(row_to_modify.doctype, field)) {
+				let is_serial_no = row_to_modify[field] && field === "serial_no";
+				let value = data[field];
+
+				if (is_serial_no) {
+					value = row_to_modify[field] + '\n' + data[field];
+				}
+
+				frappe.model.set_value(row_to_modify.doctype, row_to_modify.name, field, value);
+			}
+		});
+
+		scan_barcode_field.set_value('');
+		refresh_field("items");
+	}
+
+	get_row_to_modify_on_scan(row_to_modify, data) {
+		// get an existing item row to increment or blank row to modify
+		const existing_item_row = this.frm.doc.items.find(d => d.item_code === data.item_code);
+		const blank_item_row = this.frm.doc.items.find(d => !d.item_code);
+
+		if (existing_item_row) {
+			row_to_modify = existing_item_row;
+		} else if (blank_item_row) {
+			row_to_modify = blank_item_row;
+		}
+
+		return row_to_modify;
+	}
+
+	get_batch_row_to_modify(batch_no) {
+		// get row if batch already exists in table
+		const existing_batch_row = this.frm.doc.items.find(d => d.batch_no === batch_no);
+		return existing_batch_row || null;
+	}
+
+	show_scan_message (idx, exist = null) {
+		// show new row or qty increase toast
+		if (exist) {
+			frappe.show_alert({
+				message: __('Row #{0}: Qty increased by 1', [idx]),
+				indicator: 'green'
+			});
+		} else {
+			frappe.show_alert({
+				message: __('Row #{0}: Item added', [idx]),
+				indicator: 'green'
+			});
+		}
+	}
+
 	apply_default_taxes() {
 		var me = this;
 		var taxes_and_charges_field = frappe.meta.get_docfield(me.frm.doc.doctype, "taxes_and_charges",
@@ -617,6 +652,7 @@
 											me.frm.script_manager.trigger('qty', item.doctype, item.name);
 											if (!me.frm.doc.set_warehouse)
 												me.frm.script_manager.trigger('warehouse', item.doctype, item.name);
+											me.apply_price_list(item, true);
 										}, undefined, !frappe.flags.hide_serial_batch_dialog);
 									}
 								},
@@ -884,7 +920,9 @@
 						if (r.message) {
 							me.frm.set_value("billing_address", r.message);
 						} else {
-							me.frm.set_value("company_address", "");
+							if (frappe.meta.get_docfield(me.frm.doctype, 'company_address')) {
+								me.frm.set_value("company_address", "");
+							}
 						}
 					}
 				});
diff --git a/erpnext/public/js/help_links.js b/erpnext/public/js/help_links.js
index d0c935f..b643cca 100644
--- a/erpnext/public/js/help_links.js
+++ b/erpnext/public/js/help_links.js
@@ -5,7 +5,7 @@
 frappe.help.help_links["Form/Rename Tool"] = [
 	{
 		label: "Bulk Rename",
-		url: docsUrl + "user/manual/en/setting-up/data/bulk-rename",
+		url: docsUrl + "user/manual/en/using-erpnext/articles/bulk-rename",
 	},
 ];
 
@@ -59,10 +59,23 @@
 	},
 ];
 
-frappe.help.help_links["data-import-tool"] = [
+frappe.help.help_links["Form/Data Import"] = [
 	{
 		label: "Importing and Exporting Data",
-		url: docsUrl + "user/manual/en/setting-up/data/data-import-tool",
+		url: docsUrl + "user/manual/en/setting-up/data/data-import",
+	},
+	{
+		label: "Overwriting Data from Data Import Tool",
+		url:
+			docsUrl +
+			"user/manual/en/setting-up/articles/overwriting-data-from-data-import-tool",
+	},
+];
+
+frappe.help.help_links["List/Data Import"] = [
+	{
+		label: "Importing and Exporting Data",
+		url: docsUrl + "user/manual/en/setting-up/data/data-import",
 	},
 	{
 		label: "Overwriting Data from Data Import Tool",
@@ -101,14 +114,14 @@
 	},
 ];
 
-frappe.help.help_links["Form/Email Digest"] = [
+frappe.help.help_links["List/Print Heading"] = [
 	{
-		label: "Email Digest",
-		url: docsUrl + "user/manual/en/setting-up/email/email-digest",
+		label: "Print Heading",
+		url: docsUrl + "user/manual/en/setting-up/print/print-headings",
 	},
 ];
 
-frappe.help.help_links["List/Print Heading"] = [
+frappe.help.help_links["Form/Print Heading"] = [
 	{
 		label: "Print Heading",
 		url: docsUrl + "user/manual/en/setting-up/print/print-headings",
@@ -153,18 +166,25 @@
 frappe.help.help_links["List/Notification"] = [
 	{
 		label: "Notification",
-		url: docsUrl + "user/manual/en/setting-up/email/notifications",
+		url: docsUrl + "user/manual/en/setting-up/notifications",
 	},
 ];
 
 frappe.help.help_links["Form/Notification"] = [
 	{
 		label: "Notification",
-		url: docsUrl + "user/manual/en/setting-up/email/notifications",
+		url: docsUrl + "user/manual/en/setting-up/notifications",
 	},
 ];
 
-frappe.help.help_links["List/Email Digest"] = [
+frappe.help.help_links["Form/Email Digest"] = [
+	{
+		label: "Email Digest",
+		url: docsUrl + "user/manual/en/setting-up/email/email-digest",
+	},
+];
+
+frappe.help.help_links["Form/Email Digest"] = [
 	{
 		label: "Email Digest",
 		url: docsUrl + "user/manual/en/setting-up/email/email-digest",
@@ -174,7 +194,7 @@
 frappe.help.help_links["List/Auto Email Report"] = [
 	{
 		label: "Auto Email Reports",
-		url: docsUrl + "user/manual/en/setting-up/email/email-reports",
+		url: docsUrl + "user/manual/en/setting-up/email/auto-email-reports",
 	},
 ];
 
@@ -188,14 +208,7 @@
 frappe.help.help_links["print-format-builder"] = [
 	{
 		label: "Print Format Builder",
-		url: docsUrl + "user/manual/en/setting-up/print/print-settings",
-	},
-];
-
-frappe.help.help_links["List/Print Heading"] = [
-	{
-		label: "Print Heading",
-		url: docsUrl + "user/manual/en/setting-up/print/print-headings",
+		url: docsUrl + "user/manual/en/setting-up/print/print-format-builder",
 	},
 ];
 
@@ -300,7 +313,7 @@
 	},
 	{
 		label: "Recurring Sales Order",
-		url: docsUrl + "user/manual/en/accounts/recurring-orders-and-invoices",
+		url: docsUrl + "user/manual/en/accounts/articles/recurring-orders-and-invoices",
 	},
 	{
 		label: "Applying Discount",
@@ -315,7 +328,7 @@
 	},
 	{
 		label: "Recurring Sales Order",
-		url: docsUrl + "user/manual/en/accounts/recurring-orders-and-invoices",
+		url: docsUrl + "user/manual/en/accounts/articles/recurring-orders-and-invoices",
 	},
 	{
 		label: "Applying Discount",
@@ -344,14 +357,14 @@
 frappe.help.help_links["Form/Product Bundle"] = [
 	{
 		label: "Product Bundle",
-		url: docsUrl + "user/manual/en/selling/setup/product-bundle",
+		url: docsUrl + "user/manual/en/selling/product-bundle",
 	},
 ];
 
 frappe.help.help_links["Form/Selling Settings"] = [
 	{
 		label: "Selling Settings",
-		url: docsUrl + "user/manual/en/selling/setup/selling-settings",
+		url: docsUrl + "user/manual/en/selling/selling-settings",
 	},
 ];
 
@@ -397,7 +410,7 @@
 	},
 	{
 		label: "Recurring Purchase Order",
-		url: docsUrl + "user/manual/en/accounts/recurring-orders-and-invoices",
+		url: docsUrl + "user/manual/en/accounts/articles/recurring-orders-and-invoices",
 	},
 ];
 
@@ -420,7 +433,7 @@
 	},
 	{
 		label: "Recurring Purchase Order",
-		url: docsUrl + "user/manual/en/accounts/recurring-orders-and-invoices",
+		url: docsUrl + "user/manual/en/accounts/articles/recurring-orders-and-invoices",
 	},
 	{
 		label: "Subcontracting",
@@ -435,24 +448,17 @@
 	},
 ];
 
-frappe.help.help_links["List/POS Profile"] = [
-	{
-		label: "POS Profile",
-		url: docsUrl + "user/manual/en/setting-up/pos-setting",
-	},
-];
-
 frappe.help.help_links["List/Price List"] = [
 	{
 		label: "Price List",
-		url: docsUrl + "user/manual/en/setting-up/price-lists",
+		url: docsUrl + "user/manual/en/stock/price-lists",
 	},
 ];
 
 frappe.help.help_links["List/Authorization Rule"] = [
 	{
 		label: "Authorization Rule",
-		url: docsUrl + "user/manual/en/setting-up/authorization-rule",
+		url: docsUrl + "user/manual/en/customize-erpnext/authorization-rule",
 	},
 ];
 
@@ -468,27 +474,14 @@
 		label: "Stock Reconciliation",
 		url:
 			docsUrl +
-			"user/manual/en/setting-up/stock-reconciliation-for-non-serialized-item",
+			"user/manual/en/stock/stock-reconciliation",
 	},
 ];
 
 frappe.help.help_links["Tree/Territory"] = [
 	{
 		label: "Territory",
-		url: docsUrl + "user/manual/en/setting-up/territory",
-	},
-];
-
-frappe.help.help_links["Form/Dropbox Backup"] = [
-	{
-		label: "Dropbox Backup",
-		url: docsUrl + "user/manual/en/setting-up/third-party-backups",
-	},
-	{
-		label: "Setting Up Dropbox Backup",
-		url:
-			docsUrl +
-			"user/manual/en/setting-up/articles/setting-up-dropbox-backups",
+		url: docsUrl + "user/manual/en/selling/territory",
 	},
 ];
 
@@ -502,12 +495,6 @@
 		url: docsUrl + "user/manual/en/setting-up/company-setup",
 	},
 	{
-		label: "Managing Multiple Companies",
-		url:
-			docsUrl +
-			"user/manual/en/setting-up/articles/managing-multiple-companies",
-	},
-	{
 		label: "Delete All Related Transactions for a Company",
 		url:
 			docsUrl +
@@ -517,21 +504,6 @@
 
 //Accounts
 
-frappe.help.help_links["modules/Accounts"] = [
-	{
-		label: "Introduction to Accounts",
-		url: docsUrl + "user/manual/en/accounts/",
-	},
-	{
-		label: "Chart of Accounts",
-		url: docsUrl + "user/manual/en/accounts/chart-of-accounts.html",
-	},
-	{
-		label: "Multi Currency Accounting",
-		url: docsUrl + "user/manual/en/accounts/multi-currency-accounting",
-	},
-];
-
 frappe.help.help_links["Tree/Account"] = [
 	{
 		label: "Chart of Accounts",
@@ -552,7 +524,7 @@
 	},
 	{
 		label: "Accounts Opening Balance",
-		url: docsUrl + "user/manual/en/accounts/opening-accounts",
+		url: docsUrl + "user/manual/en/accounts/opening-balance",
 	},
 	{
 		label: "Sales Return",
@@ -560,7 +532,7 @@
 	},
 	{
 		label: "Recurring Sales Invoice",
-		url: docsUrl + "user/manual/en/accounts/recurring-orders-and-invoices",
+		url: docsUrl + "user/manual/en/accounts/articles/recurring-orders-and-invoices",
 	},
 ];
 
@@ -571,7 +543,7 @@
 	},
 	{
 		label: "Accounts Opening Balance",
-		url: docsUrl + "user/manual/en/accounts/opening-accounts",
+		url: docsUrl + "user/manual/en/accounts/opening-balances",
 	},
 	{
 		label: "Sales Return",
@@ -579,21 +551,28 @@
 	},
 	{
 		label: "Recurring Sales Invoice",
-		url: docsUrl + "user/manual/en/accounts/recurring-orders-and-invoices",
+		url: docsUrl + "user/manual/en/accounts/articles/recurring-orders-and-invoices",
 	},
 ];
 
-frappe.help.help_links["pos"] = [
+frappe.help.help_links["point-of-sale"] = [
 	{
 		label: "Point of Sale Invoice",
-		url: docsUrl + "user/manual/en/accounts/point-of-sale-pos-invoice",
+		url: docsUrl + "user/manual/en/accounts/point-of-sales",
 	},
 ];
 
 frappe.help.help_links["List/POS Profile"] = [
 	{
 		label: "Point of Sale Profile",
-		url: docsUrl + "user/manual/en/setting-up/pos-setting",
+		url: docsUrl + "user/manual/en/accounts/pos-profile",
+	},
+];
+
+frappe.help.help_links["Form/POS Profile"] = [
+	{
+		label: "POS Profile",
+		url: docsUrl + "user/manual/en/accounts/pos-profile",
 	},
 ];
 
@@ -604,11 +583,11 @@
 	},
 	{
 		label: "Accounts Opening Balance",
-		url: docsUrl + "user/manual/en/accounts/opening-accounts",
+		url: docsUrl + "user/manual/en/accounts/opening-balance",
 	},
 	{
 		label: "Recurring Purchase Invoice",
-		url: docsUrl + "user/manual/en/accounts/recurring-orders-and-invoices",
+		url: docsUrl + "user/manual/en/accounts/articles/recurring-orders-and-invoices",
 	},
 ];
 
@@ -623,7 +602,7 @@
 	},
 	{
 		label: "Accounts Opening Balance",
-		url: docsUrl + "user/manual/en/accounts/opening-accounts",
+		url: docsUrl + "user/manual/en/accounts/opening-balance",
 	},
 ];
 
@@ -644,7 +623,7 @@
 frappe.help.help_links["List/Asset"] = [
 	{
 		label: "Managing Fixed Assets",
-		url: docsUrl + "user/manual/en/accounts/opening-balance/fixed_assets",
+		url: docsUrl + "user/manual/en/asset",
 	},
 ];
 
@@ -659,6 +638,8 @@
 	{ label: "Budgeting", url: docsUrl + "user/manual/en/accounts/budgeting" },
 ];
 
+//Stock
+
 frappe.help.help_links["List/Item"] = [
 	{ label: "Item", url: docsUrl + "user/manual/en/stock/item" },
 	{
@@ -676,7 +657,7 @@
 	},
 	{
 		label: "Managing Fixed Assets",
-		url: docsUrl + "user/manual/en/accounts/opening-balance/fixed_assets",
+		url: docsUrl + "user/manual/en/asset",
 	},
 	{
 		label: "Item Codification",
@@ -711,7 +692,7 @@
 	},
 	{
 		label: "Managing Fixed Assets",
-		url: docsUrl + "user/manual/en/accounts/opening-balance/fixed_assets",
+		url: docsUrl + "user/manual/en/asset",
 	},
 	{
 		label: "Item Codification",
@@ -771,10 +752,6 @@
 		url:
 			docsUrl + "user/manual/en/stock/articles/track-items-using-barcode",
 	},
-	{
-		label: "Subcontracting",
-		url: docsUrl + "user/manual/en/manufacturing/subcontracting",
-	},
 ];
 
 frappe.help.help_links["List/Installation Note"] = [
@@ -784,21 +761,10 @@
 	},
 ];
 
-frappe.help.help_links["Tree"] = [
-	{
-		label: "Managing Tree Structure Masters",
-		url:
-			docsUrl +
-			"user/manual/en/setting-up/articles/managing-tree-structure-masters",
-	},
-];
-
 frappe.help.help_links["List/Budget"] = [
 	{ label: "Budgeting", url: docsUrl + "user/manual/en/accounts/budgeting" },
 ];
 
-//Stock
-
 frappe.help.help_links["List/Material Request"] = [
 	{
 		label: "Material Request",
@@ -861,6 +827,10 @@
 	{ label: "Serial No", url: docsUrl + "user/manual/en/stock/serial-no" },
 ];
 
+frappe.help.help_links["List/Batch"] = [
+	{ label: "Batch", url: docsUrl + "user/manual/en/stock/batch" },
+];
+
 frappe.help.help_links["Form/Batch"] = [
 	{ label: "Batch", url: docsUrl + "user/manual/en/stock/batch" },
 ];
@@ -868,35 +838,35 @@
 frappe.help.help_links["Form/Packing Slip"] = [
 	{
 		label: "Packing Slip",
-		url: docsUrl + "user/manual/en/stock/tools/packing-slip",
+		url: docsUrl + "user/manual/en/stock/packing-slip",
 	},
 ];
 
 frappe.help.help_links["Form/Quality Inspection"] = [
 	{
 		label: "Quality Inspection",
-		url: docsUrl + "user/manual/en/stock/tools/quality-inspection",
+		url: docsUrl + "user/manual/en/stock/quality-inspection",
 	},
 ];
 
 frappe.help.help_links["Form/Landed Cost Voucher"] = [
 	{
 		label: "Landed Cost Voucher",
-		url: docsUrl + "user/manual/en/stock/tools/landed-cost-voucher",
+		url: docsUrl + "user/manual/en/stock/landed-cost-voucher",
 	},
 ];
 
 frappe.help.help_links["Tree/Item Group"] = [
 	{
 		label: "Item Group",
-		url: docsUrl + "user/manual/en/stock/setup/item-group",
+		url: docsUrl + "user/manual/en/stock/item-group",
 	},
 ];
 
 frappe.help.help_links["Form/Item Attribute"] = [
 	{
 		label: "Item Attribute",
-		url: docsUrl + "user/manual/en/stock/setup/item-attribute",
+		url: docsUrl + "user/manual/en/stock/item-attribute",
 	},
 ];
 
@@ -911,7 +881,7 @@
 frappe.help.help_links["Form/Stock Reconciliation"] = [
 	{
 		label: "Opening Stock Entry",
-		url: docsUrl + "user/manual/en/stock/opening-stock",
+		url: docsUrl + "user/manual/en/stock/stock-reconciliation",
 	},
 ];
 
@@ -938,13 +908,13 @@
 ];
 
 frappe.help.help_links["Form/Campaign"] = [
-	{ label: "Campaign", url: docsUrl + "user/manual/en/CRM/setup/campaign" },
+	{ label: "Campaign", url: docsUrl + "user/manual/en/CRM/campaign" },
 ];
 
 frappe.help.help_links["Tree/Sales Person"] = [
 	{
 		label: "Sales Person",
-		url: docsUrl + "user/manual/en/CRM/setup/sales-person",
+		url: docsUrl + "user/manual/en/CRM/sales-person",
 	},
 ];
 
@@ -953,30 +923,13 @@
 		label: "Sales Person Target",
 		url:
 			docsUrl +
-			"user/manual/en/selling/setup/sales-person-target-allocation",
+			"user/manual/en/selling/sales-person-target-allocation",
 	},
-];
-
-//Support
-
-frappe.help.help_links["List/Feedback Trigger"] = [
 	{
-		label: "Feedback Trigger",
-		url: docsUrl + "user/manual/en/setting-up/feedback/setting-up-feedback",
-	},
-];
-
-frappe.help.help_links["List/Feedback Request"] = [
-	{
-		label: "Feedback Request",
-		url: docsUrl + "user/manual/en/setting-up/feedback/submit-feedback",
-	},
-];
-
-frappe.help.help_links["List/Feedback Request"] = [
-	{
-		label: "Feedback Request",
-		url: docsUrl + "user/manual/en/setting-up/feedback/submit-feedback",
+		label: "Sales Person in Transactions",
+		url:
+			docsUrl +
+			"user/manual/en/selling/articles/sales-persons-in-the-sales-transactions",
 	},
 ];
 
@@ -1019,7 +972,7 @@
 frappe.help.help_links["Form/BOM Update Tool"] = [
 	{
 		label: "BOM Update Tool",
-		url: docsUrl + "user/manual/en/manufacturing/tools/bom-update-tool",
+		url: docsUrl + "user/manual/en/manufacturing/bom-update-tool",
 	},
 ];
 
@@ -1036,7 +989,7 @@
 	},
 ];
 
-frappe.help.help_links["Form/Custom Field"] = [
+frappe.help.help_links["List/Custom Field"] = [
 	{
 		label: "Custom Field",
 		url: docsUrl + "user/manual/en/customize-erpnext/custom-field",
diff --git a/erpnext/public/js/hierarchy_chart/hierarchy_chart_desktop.js b/erpnext/public/js/hierarchy_chart/hierarchy_chart_desktop.js
index 6286732..7b35819 100644
--- a/erpnext/public/js/hierarchy_chart/hierarchy_chart_desktop.js
+++ b/erpnext/public/js/hierarchy_chart/hierarchy_chart_desktop.js
@@ -63,7 +63,7 @@
 		});
 
 		node.parent.append(node_card);
-		node.$link = $(`#${node.id}`);
+		node.$link = $(`[id="${node.id}"]`);
 	}
 
 	show() {
@@ -223,7 +223,7 @@
 				let node = undefined;
 
 				$.each(r.message, (_i, data) => {
-					if ($(`#${data.id}`).length)
+					if ($(`[id="${data.id}"]`).length)
 						return;
 
 					node = new me.Node({
@@ -263,7 +263,7 @@
 			this.refresh_connectors(node.parent_id);
 
 			// rebuild incoming connections
-			let grandparent = $(`#${node.parent_id}`).attr('data-parent');
+			let grandparent = $(`[id="${node.parent_id}"]`).attr('data-parent');
 			this.refresh_connectors(grandparent);
 		}
 
@@ -282,7 +282,7 @@
 
 	show_active_path(node) {
 		// mark node parent on active path
-		$(`#${node.parent_id}`).addClass('active-path');
+		$(`[id="${node.parent_id}"]`).addClass('active-path');
 	}
 
 	load_children(node, deep=false) {
@@ -317,7 +317,7 @@
 
 	render_child_nodes(node, child_nodes) {
 		const last_level = this.$hierarchy.find('.level:last').index();
-		const current_level = $(`#${node.id}`).parent().parent().parent().index();
+		const current_level = $(`[id="${node.id}"]`).parent().parent().parent().index();
 
 		if (last_level === current_level) {
 			this.$hierarchy.append(`
@@ -382,7 +382,7 @@
 		node.$children = $('<ul class="node-children"></ul>');
 
 		const last_level = this.$hierarchy.find('.level:last').index();
-		const node_level = $(`#${node.id}`).parent().parent().parent().index();
+		const node_level = $(`[id="${node.id}"]`).parent().parent().parent().index();
 
 		if (last_level === node_level) {
 			this.$hierarchy.append(`
@@ -489,7 +489,7 @@
 	set_path_attributes(path, parent_id, child_id) {
 		path.setAttribute("data-parent", parent_id);
 		path.setAttribute("data-child", child_id);
-		const parent = $(`#${parent_id}`);
+		const parent = $(`[id="${parent_id}"]`);
 
 		if (parent.hasClass('active')) {
 			path.setAttribute("class", "active-connector");
@@ -513,7 +513,7 @@
 	}
 
 	collapse_previous_level_nodes(node) {
-		let node_parent = $(`#${node.parent_id}`);
+		let node_parent = $(`[id="${node.parent_id}"]`);
 		let previous_level_nodes = node_parent.parent().parent().children('li');
 		let node_card = undefined;
 
@@ -545,7 +545,7 @@
 
 	setup_node_click_action(node) {
 		let me = this;
-		let node_element = $(`#${node.id}`);
+		let node_element = $(`[id="${node.id}"]`);
 
 		node_element.click(function() {
 			const is_sibling = me.selected_node.parent_id === node.parent_id;
@@ -563,7 +563,7 @@
 	}
 
 	setup_edit_node_action(node) {
-		let node_element = $(`#${node.id}`);
+		let node_element = $(`[id="${node.id}"]`);
 		let me = this;
 
 		node_element.find('.btn-edit-node').click(function() {
@@ -572,7 +572,7 @@
 	}
 
 	remove_levels_after_node(node) {
-		let level = $(`#${node.id}`).parent().parent().parent().index();
+		let level = $(`[id="${node.id}"]`).parent().parent().parent().index();
 
 		level = $('.hierarchy > li:eq('+ level + ')');
 		level.nextAll('li').remove();
@@ -595,7 +595,7 @@
 			const parent = $(path).data('parent');
 			const child = $(path).data('child');
 
-			if ($(`#${parent}`).length && $(`#${child}`).length)
+			if ($(`[id="${parent}"]`).length && $(`[id="${child}"]`).length)
 				return;
 
 			$(path).remove();
diff --git a/erpnext/public/js/hierarchy_chart/hierarchy_chart_mobile.js b/erpnext/public/js/hierarchy_chart/hierarchy_chart_mobile.js
index b1a8879..0a8ba78 100644
--- a/erpnext/public/js/hierarchy_chart/hierarchy_chart_mobile.js
+++ b/erpnext/public/js/hierarchy_chart/hierarchy_chart_mobile.js
@@ -54,7 +54,7 @@
 		});
 
 		node.parent.append(node_card);
-		node.$link = $(`#${node.id}`);
+		node.$link = $(`[id="${node.id}"]`);
 		node.$link.addClass('mobile-node');
 	}
 
@@ -184,7 +184,7 @@
 			this.refresh_connectors(node.parent_id, node.id);
 
 			// rebuild incoming connections of parent
-			let grandparent = $(`#${node.parent_id}`).attr('data-parent');
+			let grandparent = $(`[id="${node.parent_id}"]`).attr('data-parent');
 			this.refresh_connectors(grandparent, node.parent_id);
 		}
 
@@ -221,7 +221,7 @@
 
 	show_active_path(node) {
 		// mark node parent on active path
-		$(`#${node.parent_id}`).addClass('active-path');
+		$(`[id="${node.parent_id}"]`).addClass('active-path');
 	}
 
 	load_children(node) {
@@ -256,7 +256,7 @@
 			if (child_nodes) {
 				$.each(child_nodes, (_i, data) => {
 					this.add_node(node, data);
-					$(`#${data.id}`).addClass('active-child');
+					$(`[id="${data.id}"]`).addClass('active-child');
 
 					setTimeout(() => {
 						this.add_connector(node.id, data.id);
@@ -293,9 +293,9 @@
 
 		let connector = undefined;
 
-		if ($(`#${parent_id}`).hasClass('active')) {
+		if ($(`[id="${parent_id}"]`).hasClass('active')) {
 			connector = this.get_connector_for_active_node(parent_node, child_node);
-		} else if ($(`#${parent_id}`).hasClass('active-path')) {
+		} else if ($(`[id="${parent_id}"]`).hasClass('active-path')) {
 			connector = this.get_connector_for_collapsed_node(parent_node, child_node);
 		}
 
@@ -351,7 +351,7 @@
 	set_path_attributes(path, parent_id, child_id) {
 		path.setAttribute("data-parent", parent_id);
 		path.setAttribute("data-child", child_id);
-		const parent = $(`#${parent_id}`);
+		const parent = $(`[id="${parent_id}"]`);
 
 		if (parent.hasClass('active')) {
 			path.setAttribute("class", "active-connector");
@@ -374,7 +374,7 @@
 
 	setup_node_click_action(node) {
 		let me = this;
-		let node_element = $(`#${node.id}`);
+		let node_element = $(`[id="${node.id}"]`);
 
 		node_element.click(function() {
 			let el = undefined;
@@ -398,7 +398,7 @@
 	}
 
 	setup_edit_node_action(node) {
-		let node_element = $(`#${node.id}`);
+		let node_element = $(`[id="${node.id}"]`);
 		let me = this;
 
 		node_element.find('.btn-edit-node').click(function() {
@@ -512,7 +512,7 @@
 	}
 
 	remove_levels_after_node(node) {
-		let level = $(`#${node.id}`).parent().parent().index();
+		let level = $(`[id="${node.id}"]`).parent().parent().index();
 
 		level = $('.hierarchy-mobile > li:eq('+ level + ')');
 		level.nextAll('li').remove();
@@ -533,7 +533,7 @@
 			const parent = $(path).data('parent');
 			const child = $(path).data('child');
 
-			if ($(`#${parent}`).length && $(`#${child}`).length)
+			if ($(`[id="${parent}"]`).length && $(`[id="${child}"]`).length)
 				return;
 
 			$(path).remove();
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index e0610eb..0323a42 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -709,14 +709,21 @@
 			setters: opts.setters,
 			get_query: opts.get_query,
 			add_filters_group: 1,
+			allow_child_item_selection: opts.allow_child_item_selection,
+			child_fieldname: opts.child_fielname,
+			child_columns: opts.child_columns,
+			size: opts.size,
 			action: function(selections, args) {
 				let values = selections;
-				if(values.length === 0){
+				if (values.length === 0) {
 					frappe.msgprint(__("Please select {0}", [opts.source_doctype]))
 					return;
 				}
 				opts.source_name = values;
-				opts.setters = args;
+				if (opts.allow_child_item_selection) {
+					// args contains filtered child docnames
+					opts.args = args;
+				}
 				d.dialog.hide();
 				_map();
 			},
diff --git a/erpnext/public/scss/shopping_cart.scss b/erpnext/public/scss/shopping_cart.scss
index 490a7c4..fef1e76 100644
--- a/erpnext/public/scss/shopping_cart.scss
+++ b/erpnext/public/scss/shopping_cart.scss
@@ -31,6 +31,14 @@
 .carousel-control-prev,
 .carousel-control-next {
 	opacity: 1;
+	width: 8%;
+
+	@media (max-width: 1200px) {
+		width: 10%;
+	}
+	@media (max-width: 768px) {
+		width: 15%;
+	}
 }
 
 .carousel-body {
@@ -43,6 +51,8 @@
 
 .carousel-content {
 	max-width: 400px;
+	margin-left: 5rem;
+	margin-right: 5rem;
 }
 
 .card {
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index 963c407..afb1b07 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -132,6 +132,10 @@
 		make_property_setter('Journal Entry', 'voucher_type', 'options', '\n'.join(journal_entry_types), '')
 
 def make_custom_fields(update=True):
+	custom_fields = get_custom_fields()
+	create_custom_fields(custom_fields, update=update)
+
+def get_custom_fields():
 	hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC',
 		fieldtype='Data', fetch_from='item_code.gst_hsn_code', insert_after='description',
 		allow_on_submit=1, print_hide=1, fetch_if_empty=1)
@@ -165,12 +169,12 @@
 		dict(fieldname='gst_category', label='GST Category',
 			fieldtype='Select', insert_after='gst_section', print_hide=1,
 			options='\nRegistered Regular\nRegistered Composition\nUnregistered\nSEZ\nOverseas\nConsumer\nDeemed Export\nUIN Holders',
-			fetch_from='customer.gst_category', fetch_if_empty=1),
+			fetch_from='customer.gst_category', fetch_if_empty=1, length=25),
 		dict(fieldname='export_type', label='Export Type',
 			fieldtype='Select', insert_after='gst_category', print_hide=1,
 			depends_on='eval:in_list(["SEZ", "Overseas", "Deemed Export"], doc.gst_category)',
 			options='\nWith Payment of Tax\nWithout Payment of Tax', fetch_from='customer.export_type',
-			fetch_if_empty=1),
+			fetch_if_empty=1, length=25),
 	]
 
 	delivery_note_gst_category = [
@@ -181,18 +185,18 @@
 	]
 
 	invoice_gst_fields = [
-		dict(fieldname='invoice_copy', label='Invoice Copy',
+		dict(fieldname='invoice_copy', label='Invoice Copy', length=30,
 			fieldtype='Select', insert_after='export_type', print_hide=1, allow_on_submit=1,
 			options='Original for Recipient\nDuplicate for Transporter\nDuplicate for Supplier\nTriplicate for Supplier'),
-		dict(fieldname='reverse_charge', label='Reverse Charge',
+		dict(fieldname='reverse_charge', label='Reverse Charge', length=2,
 			fieldtype='Select', insert_after='invoice_copy', print_hide=1,
 			options='Y\nN', default='N'),
-		dict(fieldname='ecommerce_gstin', label='E-commerce GSTIN',
+		dict(fieldname='ecommerce_gstin', label='E-commerce GSTIN', length=15,
 			fieldtype='Data', insert_after='export_type', print_hide=1),
 		dict(fieldname='gst_col_break', fieldtype='Column Break', insert_after='ecommerce_gstin'),
 		dict(fieldname='reason_for_issuing_document', label='Reason For Issuing document',
 			fieldtype='Select', insert_after='gst_col_break', print_hide=1,
-			depends_on='eval:doc.is_return==1',
+			depends_on='eval:doc.is_return==1', length=45,
 			options='\n01-Sales Return\n02-Post Sale Discount\n03-Deficiency in services\n04-Correction in Invoice\n05-Change in POS\n06-Finalization of Provisional assessment\n07-Others')
 	]
 
@@ -230,25 +234,25 @@
 	sales_invoice_gst_fields = [
 			dict(fieldname='billing_address_gstin', label='Billing Address GSTIN',
 				fieldtype='Data', insert_after='customer_address', read_only=1,
-				fetch_from='customer_address.gstin', print_hide=1),
+				fetch_from='customer_address.gstin', print_hide=1, length=15),
 			dict(fieldname='customer_gstin', label='Customer GSTIN',
 				fieldtype='Data', insert_after='shipping_address_name',
-				fetch_from='shipping_address_name.gstin', print_hide=1),
+				fetch_from='shipping_address_name.gstin', print_hide=1, length=15),
 			dict(fieldname='place_of_supply', label='Place of Supply',
 				fieldtype='Data', insert_after='customer_gstin',
-				print_hide=1, read_only=1),
+				print_hide=1, read_only=1, length=50),
 			dict(fieldname='company_gstin', label='Company GSTIN',
 				fieldtype='Data', insert_after='company_address',
-				fetch_from='company_address.gstin', print_hide=1, read_only=1),
+				fetch_from='company_address.gstin', print_hide=1, read_only=1, length=15),
 		]
 
 	sales_invoice_shipping_fields = [
 			dict(fieldname='port_code', label='Port Code',
 				fieldtype='Data', insert_after='reason_for_issuing_document', print_hide=1,
-				depends_on="eval:doc.gst_category=='Overseas' "),
+				depends_on="eval:doc.gst_category=='Overseas' ", length=15),
 			dict(fieldname='shipping_bill_number', label=' Shipping Bill Number',
 				fieldtype='Data', insert_after='port_code', print_hide=1,
-				depends_on="eval:doc.gst_category=='Overseas' "),
+				depends_on="eval:doc.gst_category=='Overseas' ", length=50),
 			dict(fieldname='shipping_bill_date', label='Shipping Bill Date',
 				fieldtype='Date', insert_after='shipping_bill_number', print_hide=1,
 				depends_on="eval:doc.gst_category=='Overseas' "),
@@ -354,7 +358,8 @@
 			'insert_after': 'transporter',
 			'fetch_from': 'transporter.gst_transporter_id',
 			'print_hide': 1,
-			'translatable': 0
+			'translatable': 0,
+			'length': 20
 		},
 		{
 			'fieldname': 'driver',
@@ -370,7 +375,8 @@
 			'fieldtype': 'Data',
 			'insert_after': 'driver',
 			'print_hide': 1,
-			'translatable': 0
+			'translatable': 0,
+			'length': 30
 		},
 		{
 			'fieldname': 'vehicle_no',
@@ -378,7 +384,8 @@
 			'fieldtype': 'Data',
 			'insert_after': 'lr_no',
 			'print_hide': 1,
-			'translatable': 0
+			'translatable': 0,
+			'length': 10
 		},
 		{
 			'fieldname': 'distance',
@@ -395,7 +402,7 @@
 		{
 			'fieldname': 'transporter_name',
 			'label': 'Transporter Name',
-			'fieldtype': 'Data',
+			'fieldtype': 'Small Text',
 			'insert_after': 'transporter_col_break',
 			'fetch_from': 'transporter.name',
 			'read_only': 1,
@@ -409,12 +416,13 @@
 			'options': '\nRoad\nAir\nRail\nShip',
 			'insert_after': 'transporter_name',
 			'print_hide': 1,
-			'translatable': 0
+			'translatable': 0,
+			'length': 5
 		},
 		{
 			'fieldname': 'driver_name',
 			'label': 'Driver Name',
-			'fieldtype': 'Data',
+			'fieldtype': 'Small Text',
 			'insert_after': 'mode_of_transport',
 			'fetch_from': 'driver.full_name',
 			'print_hide': 1,
@@ -437,7 +445,8 @@
 			'default': 'Regular',
 			'insert_after': 'lr_date',
 			'print_hide': 1,
-			'translatable': 0
+			'translatable': 0,
+			'length': 30
 		},
 		{
 			'fieldname': 'ewaybill',
@@ -446,7 +455,8 @@
 			'depends_on': 'eval:(doc.docstatus === 1)',
 			'allow_on_submit': 1,
 			'insert_after': 'tax_id',
-			'translatable': 0
+			'translatable': 0,
+			'length': 20
 		}
 	]
 
@@ -483,6 +493,7 @@
 		'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,
+		'POS Invoice': sales_invoice_gst_fields,
 		'Delivery Note': sales_invoice_gst_fields + ewaybill_fields + sales_invoice_shipping_fields + delivery_note_gst_category,
 		'Payment Entry': payment_entry_fields,
 		'Journal Entry': journal_entry_fields,
@@ -501,6 +512,7 @@
 		'Sales Order Item': [hsn_sac_field, nil_rated_exempt, is_non_gst],
 		'Delivery Note Item': [hsn_sac_field, nil_rated_exempt, is_non_gst],
 		'Sales Invoice Item': [hsn_sac_field, nil_rated_exempt, is_non_gst, taxable_value],
+		'POS Invoice Item': [hsn_sac_field, nil_rated_exempt, is_non_gst, taxable_value],
 		'Purchase Order Item': [hsn_sac_field, nil_rated_exempt, is_non_gst],
 		'Purchase Receipt Item': [hsn_sac_field, nil_rated_exempt, is_non_gst],
 		'Purchase Invoice Item': [hsn_sac_field, nil_rated_exempt, is_non_gst, taxable_value],
@@ -661,9 +673,19 @@
 				'fieldtype': 'Data',
 				'insert_after': 'email'
 			}
+		],
+		'Finance Book': [
+			{
+				'fieldname': 'for_income_tax',
+				'label': 'For Income Tax',
+				'fieldtype': 'Check',
+				'insert_after': 'finance_book_name',
+				'description': 'If the asset is put to use for less than 180 days, the first Depreciation Rate will be reduced by 50%.'
+			}
 		]
 	}
-	create_custom_fields(custom_fields, update=update)
+
+	return custom_fields
 
 def make_fixtures(company=None):
 	docs = []
@@ -750,7 +772,7 @@
 
 def set_tax_withholding_category(company):
 	accounts = []
-	fiscal_year = None
+	fiscal_year_details = None
 	abbr = frappe.get_value("Company", company, "abbr")
 	tds_account = frappe.get_value("Account", 'TDS Payable - {0}'.format(abbr), 'name')
 
@@ -758,11 +780,11 @@
 		accounts = [dict(company=company, account=tds_account)]
 
 	try:
-		fiscal_year = get_fiscal_year(today(), verbose=0, company=company)[0]
+		fiscal_year_details = get_fiscal_year(today(), verbose=0, company=company)
 	except FiscalYearError:
 		pass
 
-	docs = get_tds_details(accounts, fiscal_year)
+	docs = get_tds_details(accounts, fiscal_year_details)
 
 	for d in docs:
 		if not frappe.db.exists("Tax Withholding Category", d.get("name")):
@@ -777,9 +799,10 @@
 			if accounts:
 				doc.append("accounts", accounts[0])
 
-			if fiscal_year:
+			if fiscal_year_details:
 				# if fiscal year don't match with any of the already entered data, append rate row
-				fy_exist = [k for k in doc.get('rates') if k.get('fiscal_year')==fiscal_year]
+				fy_exist = [k for k in doc.get('rates') if k.get('from_date') <= fiscal_year_details[1] \
+					and k.get('to_date') >= fiscal_year_details[2]]
 				if not fy_exist:
 					doc.append("rates", d.get('rates')[0])
 
@@ -802,149 +825,149 @@
 			}
 		])
 
-def get_tds_details(accounts, fiscal_year):
+def get_tds_details(accounts, fiscal_year_details):
 	# bootstrap default tax withholding sections
 	return [
 		dict(name="TDS - 194C - Company",
 			category_name="Payment to Contractors (Single / Aggregate)",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 2,
-			"single_threshold": 30000, "cumulative_threshold": 100000}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 2, "single_threshold": 30000, "cumulative_threshold": 100000}]),
 		dict(name="TDS - 194C - Individual",
 			category_name="Payment to Contractors (Single / Aggregate)",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 1,
-			"single_threshold": 30000, "cumulative_threshold": 100000}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 1, "single_threshold": 30000, "cumulative_threshold": 100000}]),
 		dict(name="TDS - 194C - No PAN / Invalid PAN",
 			category_name="Payment to Contractors (Single / Aggregate)",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 20,
-			"single_threshold": 30000, "cumulative_threshold": 100000}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 20, "single_threshold": 30000, "cumulative_threshold": 100000}]),
 		dict(name="TDS - 194D - Company",
 			category_name="Insurance Commission",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 5,
-			"single_threshold": 15000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 5, "single_threshold": 15000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194D - Company Assessee",
 			category_name="Insurance Commission",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 10,
-			"single_threshold": 15000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 10, "single_threshold": 15000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194D - Individual",
 			category_name="Insurance Commission",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 5,
-			"single_threshold": 15000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 5, "single_threshold": 15000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194D - No PAN / Invalid PAN",
 			category_name="Insurance Commission",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 20,
-			"single_threshold": 15000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 20, "single_threshold": 15000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194DA - Company",
 			category_name="Non-exempt payments made under a life insurance policy",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 1,
-			"single_threshold": 100000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 1, "single_threshold": 100000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194DA - Individual",
 			category_name="Non-exempt payments made under a life insurance policy",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 1,
-			"single_threshold": 100000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 1, "single_threshold": 100000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194DA - No PAN / Invalid PAN",
 			category_name="Non-exempt payments made under a life insurance policy",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 20,
-			"single_threshold": 100000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 20, "single_threshold": 100000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194H - Company",
 			category_name="Commission / Brokerage",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 5,
-			"single_threshold": 15000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 5, "single_threshold": 15000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194H - Individual",
 			category_name="Commission / Brokerage",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 5,
-			"single_threshold": 15000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 5, "single_threshold": 15000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194H - No PAN / Invalid PAN",
 			category_name="Commission / Brokerage",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 20,
-			"single_threshold": 15000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 20, "single_threshold": 15000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194I - Rent - Company",
 			category_name="Rent",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 10,
-			"single_threshold": 180000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 10, "single_threshold": 180000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194I - Rent - Individual",
 			category_name="Rent",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 10,
-			"single_threshold": 180000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 10, "single_threshold": 180000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194I - Rent - No PAN / Invalid PAN",
 			category_name="Rent",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 20,
-			"single_threshold": 180000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 20, "single_threshold": 180000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194I - Rent/Machinery - Company",
 			category_name="Rent-Plant / Machinery",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 2,
-			"single_threshold": 180000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 2, "single_threshold": 180000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194I - Rent/Machinery - Individual",
 			category_name="Rent-Plant / Machinery",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 2,
-			"single_threshold": 180000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 2, "single_threshold": 180000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194I - Rent/Machinery - No PAN / Invalid PAN",
 			category_name="Rent-Plant / Machinery",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 20,
-			"single_threshold": 180000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 20, "single_threshold": 180000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194J - Professional Fees - Company",
 			category_name="Professional Fees",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 10,
-			"single_threshold": 30000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 10, "single_threshold": 30000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194J - Professional Fees - Individual",
 			category_name="Professional Fees",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 10,
-			"single_threshold": 30000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 10, "single_threshold": 30000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194J - Professional Fees - No PAN / Invalid PAN",
 			category_name="Professional Fees",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 20,
-			"single_threshold": 30000, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 20, "single_threshold": 30000, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194J - Director Fees - Company",
 			category_name="Director Fees",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 10,
-			"single_threshold": 0, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 10, "single_threshold": 0, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194J - Director Fees - Individual",
 			category_name="Director Fees",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 10,
-			"single_threshold": 0, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 10, "single_threshold": 0, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194J - Director Fees - No PAN / Invalid PAN",
 			category_name="Director Fees",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 20,
-			"single_threshold": 0, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 20, "single_threshold": 0, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194 - Dividends - Company",
 			category_name="Dividends",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 10,
-			"single_threshold": 2500, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 10, "single_threshold": 2500, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194 - Dividends - Individual",
 			category_name="Dividends",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 10,
-			"single_threshold": 2500, "cumulative_threshold": 0}]),
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 10, "single_threshold": 2500, "cumulative_threshold": 0}]),
 		dict(name="TDS - 194 - Dividends - No PAN / Invalid PAN",
 			category_name="Dividends",
 			doctype="Tax Withholding Category", accounts=accounts,
-			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 20,
-			"single_threshold": 2500, "cumulative_threshold": 0}])
+			rates=[{"from_date": fiscal_year_details[1], "to_date": fiscal_year_details[2],
+			"tax_withholding_rate": 20, "single_threshold": 2500, "cumulative_threshold": 0}])
 	]
 
 def create_gratuity_rule():
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index bf06d4a..9493614 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -112,12 +112,9 @@
 		frappe.throw(_("""Invalid {0}! The check digit validation has failed. Please ensure you've typed the {0} correctly.""").format(label))
 
 def get_itemised_tax_breakup_header(item_doctype, tax_accounts):
-	if frappe.get_meta(item_doctype).has_field('gst_hsn_code'):
-		return [_("HSN/SAC"), _("Taxable Amount")] + tax_accounts
-	else:
-		return [_("Item"), _("Taxable Amount")] + tax_accounts
+	return [_("Item"), _("Taxable Amount")] + tax_accounts
 
-def get_itemised_tax_breakup_data(doc, account_wise=False):
+def get_itemised_tax_breakup_data(doc, account_wise=False, hsn_wise=False):
 	itemised_tax = get_itemised_tax(doc.taxes, with_tax_account=account_wise)
 
 	itemised_taxable_amount = get_itemised_taxable_amount(doc.items)
@@ -125,28 +122,29 @@
 	if not frappe.get_meta(doc.doctype + " Item").has_field('gst_hsn_code'):
 		return itemised_tax, itemised_taxable_amount
 
-	item_hsn_map = frappe._dict()
-	for d in doc.items:
-		item_hsn_map.setdefault(d.item_code or d.item_name, d.get("gst_hsn_code"))
+	if hsn_wise:
+		item_hsn_map = frappe._dict()
+		for d in doc.items:
+			item_hsn_map.setdefault(d.item_code or d.item_name, d.get("gst_hsn_code"))
 
 	hsn_tax = {}
 	for item, taxes in itemised_tax.items():
-		hsn_code = item_hsn_map.get(item)
-		hsn_tax.setdefault(hsn_code, frappe._dict())
+		item_or_hsn = item if not hsn_wise else item_hsn_map.get(item)
+		hsn_tax.setdefault(item_or_hsn, frappe._dict())
 		for tax_desc, tax_detail in taxes.items():
 			key = tax_desc
 			if account_wise:
 				key = tax_detail.get('tax_account')
-			hsn_tax[hsn_code].setdefault(key, {"tax_rate": 0, "tax_amount": 0})
-			hsn_tax[hsn_code][key]["tax_rate"] = tax_detail.get("tax_rate")
-			hsn_tax[hsn_code][key]["tax_amount"] += tax_detail.get("tax_amount")
+			hsn_tax[item_or_hsn].setdefault(key, {"tax_rate": 0, "tax_amount": 0})
+			hsn_tax[item_or_hsn][key]["tax_rate"] = tax_detail.get("tax_rate")
+			hsn_tax[item_or_hsn][key]["tax_amount"] += tax_detail.get("tax_amount")
 
 	# set taxable amount
 	hsn_taxable_amount = frappe._dict()
 	for item in itemised_taxable_amount:
-		hsn_code = item_hsn_map.get(item)
-		hsn_taxable_amount.setdefault(hsn_code, 0)
-		hsn_taxable_amount[hsn_code] += itemised_taxable_amount.get(item)
+		item_or_hsn = item if not hsn_wise else item_hsn_map.get(item)
+		hsn_taxable_amount.setdefault(item_or_hsn, 0)
+		hsn_taxable_amount[item_or_hsn] += itemised_taxable_amount.get(item)
 
 	return hsn_tax, hsn_taxable_amount
 
@@ -251,6 +249,9 @@
 	elif doctype in ("Purchase Invoice", "Purchase Order", "Purchase Receipt"):
 		destination_gstin = party_details.supplier_gstin
 
+	if not destination_gstin or party_details.gstin:
+		return False
+
 	if party_details.gstin == destination_gstin:
 		return True
 	else:
@@ -440,7 +441,7 @@
 		data.itemList = []
 		data.totalValue = doc.total
 
-		data = get_item_list(data, doc)
+		data = get_item_list(data, doc, hsn_wise=True)
 
 		disable_rounded = frappe.db.get_single_value('Global Defaults', 'disable_rounded_total')
 		data.totInvValue = doc.grand_total if disable_rounded else doc.rounded_total
@@ -551,7 +552,7 @@
 
 	return data
 
-def get_item_list(data, doc):
+def get_item_list(data, doc, hsn_wise=False):
 	for attr in ['cgstValue', 'sgstValue', 'igstValue', 'cessValue', 'OthValue']:
 		data[attr] = 0
 
@@ -563,7 +564,7 @@
 		'cess_account': ['cessRate', 'cessValue']
 	}
 	item_data_attrs = ['sgstRate', 'cgstRate', 'igstRate', 'cessRate', 'cessNonAdvol']
-	hsn_wise_charges, hsn_taxable_amount = get_itemised_tax_breakup_data(doc, account_wise=True)
+	hsn_wise_charges, hsn_taxable_amount = get_itemised_tax_breakup_data(doc, account_wise=True, hsn_wise=hsn_wise)
 	for hsn_code, taxable_amount in hsn_taxable_amount.items():
 		item_data = frappe._dict()
 		if not hsn_code:
@@ -859,12 +860,13 @@
 		rate_of_depreciation = row.rate_of_depreciation
 		# if its the first depreciation
 		if depreciable_value == asset.gross_purchase_amount:
-			# as per IT act, if the asset is purchased in the 2nd half of fiscal year, then rate is divided by 2
-			diff = date_diff(row.depreciation_start_date, asset.available_for_use_date)
-			if diff <= 180:
-				rate_of_depreciation = rate_of_depreciation / 2
-				frappe.msgprint(
-					_('As per IT Act, the rate of depreciation for the first depreciation entry is reduced by 50%.'))
+			if row.finance_book and frappe.db.get_value('Finance Book', row.finance_book, 'for_income_tax'):
+				# as per IT act, if the asset is purchased in the 2nd half of fiscal year, then rate is divided by 2
+				diff = date_diff(row.depreciation_start_date, asset.available_for_use_date)
+				if diff <= 180:
+					rate_of_depreciation = rate_of_depreciation / 2
+					frappe.msgprint(
+						_('As per IT Act, the rate of depreciation for the first depreciation entry is reduced by 50%.'))
 
 		depreciation_amount = flt(depreciable_value * (flt(rate_of_depreciation) / 100))
 
diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py
index ca0defa..23924c5 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.py
+++ b/erpnext/regional/report/gstr_1/gstr_1.py
@@ -96,35 +96,36 @@
 	def get_b2c_data(self):
 		b2cs_output = {}
 
-		for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
-			invoice_details = self.invoices.get(inv)
-			for rate, items in items_based_on_rate.items():
-				place_of_supply = invoice_details.get("place_of_supply")
-				ecommerce_gstin =  invoice_details.get("ecommerce_gstin")
+		if self.invoices:
+			for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
+				invoice_details = self.invoices.get(inv)
+				for rate, items in items_based_on_rate.items():
+					place_of_supply = invoice_details.get("place_of_supply")
+					ecommerce_gstin =  invoice_details.get("ecommerce_gstin")
 
-				b2cs_output.setdefault((rate, place_of_supply, ecommerce_gstin),{
-					"place_of_supply": "",
-					"ecommerce_gstin": "",
-					"rate": "",
-					"taxable_value": 0,
-					"cess_amount": 0,
-					"type": "",
-					"invoice_number": invoice_details.get("invoice_number"),
-					"posting_date": invoice_details.get("posting_date"),
-					"invoice_value": invoice_details.get("base_grand_total"),
-				})
+					b2cs_output.setdefault((rate, place_of_supply, ecommerce_gstin), {
+						"place_of_supply": "",
+						"ecommerce_gstin": "",
+						"rate": "",
+						"taxable_value": 0,
+						"cess_amount": 0,
+						"type": "",
+						"invoice_number": invoice_details.get("invoice_number"),
+						"posting_date": invoice_details.get("posting_date"),
+						"invoice_value": invoice_details.get("base_grand_total"),
+					})
 
-				row = b2cs_output.get((rate, place_of_supply, ecommerce_gstin))
-				row["place_of_supply"] = place_of_supply
-				row["ecommerce_gstin"] = ecommerce_gstin
-				row["rate"] = rate
-				row["taxable_value"] += sum([abs(net_amount)
-					for item_code, net_amount in self.invoice_items.get(inv).items() if item_code in items])
-				row["cess_amount"] += flt(self.invoice_cess.get(inv), 2)
-				row["type"] = "E" if ecommerce_gstin else "OE"
+					row = b2cs_output.get((rate, place_of_supply, ecommerce_gstin))
+					row["place_of_supply"] = place_of_supply
+					row["ecommerce_gstin"] = ecommerce_gstin
+					row["rate"] = rate
+					row["taxable_value"] += sum([abs(net_amount)
+						for item_code, net_amount in self.invoice_items.get(inv).items() if item_code in items])
+					row["cess_amount"] += flt(self.invoice_cess.get(inv), 2)
+					row["type"] = "E" if ecommerce_gstin else "OE"
 
-		for key, value in iteritems(b2cs_output):
-			self.data.append(value)
+			for key, value in iteritems(b2cs_output):
+				self.data.append(value)
 
 	def get_row_data_for_invoice(self, invoice, invoice_details, tax_rate, items):
 		row = []
@@ -173,9 +174,10 @@
 
 		company_gstins = get_company_gstin_number(self.filters.get('company'), all_gstins=True)
 
-		self.filters.update({
-			'company_gstins': company_gstins
-		})
+		if company_gstins:
+			self.filters.update({
+				'company_gstins': company_gstins
+			})
 
 		invoice_data = frappe.db.sql("""
 			select
@@ -212,7 +214,7 @@
 
 
 		if self.filters.get("type_of_business") ==  "B2B":
-			conditions += "AND IFNULL(gst_category, '') in ('Registered Regular', 'Deemed Export', 'SEZ') AND is_return != 1"
+			conditions += "AND IFNULL(gst_category, '') in ('Registered Regular', 'Deemed Export', 'SEZ') AND is_return != 1 AND is_debit_note !=1"
 
 		if self.filters.get("type_of_business") in ("B2C Large", "B2C Small"):
 			b2c_limit = frappe.db.get_single_value('GST Settings', 'b2c_limit')
@@ -221,7 +223,7 @@
 
 		if self.filters.get("type_of_business") ==  "B2C Large":
 			conditions += """ AND ifnull(SUBSTR(place_of_supply, 1, 2),'') != ifnull(SUBSTR(company_gstin, 1, 2),'')
-				AND grand_total > {0} AND is_return != 1 and gst_category ='Unregistered' """.format(flt(b2c_limit))
+				AND grand_total > {0} AND is_return != 1 AND is_debit_note !=1 AND gst_category ='Unregistered' """.format(flt(b2c_limit))
 
 		elif self.filters.get("type_of_business") ==  "B2C Small":
 			conditions += """ AND (
@@ -234,8 +236,8 @@
 		elif self.filters.get("type_of_business") == "CDNR-UNREG":
 			b2c_limit = frappe.db.get_single_value('GST Settings', 'b2c_limit')
 			conditions += """ AND ifnull(SUBSTR(place_of_supply, 1, 2),'') != ifnull(SUBSTR(company_gstin, 1, 2),'')
-				AND ABS(grand_total) > {0} AND (is_return = 1 OR is_debit_note = 1)
-				AND IFNULL(gst_category, '') in ('Unregistered', 'Overseas')""".format(flt(b2c_limit))
+				AND (is_return = 1 OR is_debit_note = 1)
+				AND IFNULL(gst_category, '') in ('Unregistered', 'Overseas')"""
 
 		elif self.filters.get("type_of_business") ==  "EXPORT":
 			conditions += """ AND is_return !=1 and gst_category = 'Overseas' """
@@ -1050,6 +1052,7 @@
 			["Dynamic Link", "link_doctype", "=", "Company"],
 			["Dynamic Link", "link_name", "=", company],
 			["Dynamic Link", "parenttype", "=", "Address"],
+			["gstin", "!=", '']
 		]
 		gstin = frappe.get_all("Address", filters=filters, pluck="gstin", order_by="is_primary_address desc")
 		if gstin and not all_gstins:
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index cb00019..4b0bbd5 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -116,14 +116,15 @@
 			frappe.contacts.render_address_and_contact(frm);
 
 			// custom buttons
-			frm.add_custom_button(__('Accounting Ledger'), function() {
-				frappe.set_route('query-report', 'General Ledger',
-					{party_type:'Customer', party:frm.doc.name});
-			});
 
-			frm.add_custom_button(__('Accounts Receivable'), function() {
+			frm.add_custom_button(__('Accounts Receivable'), function () {
 				frappe.set_route('query-report', 'Accounts Receivable', {customer:frm.doc.name});
-			});
+			}, __('View'));
+
+			frm.add_custom_button(__('Accounting Ledger'), function () {
+				frappe.set_route('query-report', 'General Ledger',
+					{party_type: 'Customer', party: frm.doc.name});
+			}, __('View'));
 
 			frm.add_custom_button(__('Pricing Rule'), function () {
 				erpnext.utils.make_pricing_rule(frm.doc.doctype, frm.doc.name);
diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json
index 5913b84..e811435 100644
--- a/erpnext/selling/doctype/customer/customer.json
+++ b/erpnext/selling/doctype/customer/customer.json
@@ -20,7 +20,6 @@
   "tax_withholding_category",
   "default_bank_account",
   "lead_name",
-  "prospect",
   "opportunity_name",
   "image",
   "column_break0",
@@ -214,7 +213,8 @@
    "fieldtype": "Link",
    "ignore_user_permissions": 1,
    "label": "Represents Company",
-   "options": "Company"
+   "options": "Company",
+   "unique": 1
   },
   {
    "depends_on": "represents_company",
@@ -498,14 +498,6 @@
    "options": "Tax Withholding Category"
   },
   {
-   "fieldname": "prospect",
-   "fieldtype": "Link",
-   "label": "Prospect",
-   "no_copy": 1,
-   "options": "Prospect",
-   "print_hide": 1
-  },
-  {
    "fieldname": "opportunity_name",
    "fieldtype": "Link",
    "label": "From Opportunity",
@@ -518,8 +510,14 @@
  "idx": 363,
  "image_field": "image",
  "index_web_pages_for_search": 1,
- "links": [],
- "modified": "2021-08-25 18:56:09.929905",
+ "links": [
+  {
+   "group": "Allowed Items",
+   "link_doctype": "Party Specific Item",
+   "link_fieldname": "party"
+  }
+ ],
+ "modified": "2021-09-06 17:38:54.196663",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Customer",
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 4be8139..7adf2cd 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -14,7 +14,7 @@
 )
 from frappe.desk.reportview import build_match_conditions, get_filters_cond
 from frappe.model.mapper import get_mapped_doc
-from frappe.model.naming import set_name_by_naming_series
+from frappe.model.naming import set_name_by_naming_series, set_name_from_naming_options
 from frappe.model.rename_doc import update_linked_doctypes
 from frappe.utils import cint, cstr, flt, get_formatted_email, today
 from frappe.utils.user import get_users_with_role
@@ -40,8 +40,10 @@
 		cust_master_name = frappe.defaults.get_global_default('cust_master_name')
 		if cust_master_name == 'Customer Name':
 			self.name = self.get_customer_name()
-		else:
+		elif cust_master_name == 'Naming Series':
 			set_name_by_naming_series(self)
+		else:
+			self.name = set_name_from_naming_options(frappe.get_meta(self.doctype).autoname, self)
 
 	def get_customer_name(self):
 
diff --git a/erpnext/healthcare/doctype/organism_test_item/__init__.py b/erpnext/selling/doctype/party_specific_item/__init__.py
similarity index 100%
copy from erpnext/healthcare/doctype/organism_test_item/__init__.py
copy to erpnext/selling/doctype/party_specific_item/__init__.py
diff --git a/erpnext/selling/doctype/party_specific_item/party_specific_item.js b/erpnext/selling/doctype/party_specific_item/party_specific_item.js
new file mode 100644
index 0000000..077b936
--- /dev/null
+++ b/erpnext/selling/doctype/party_specific_item/party_specific_item.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Party Specific Item', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/selling/doctype/party_specific_item/party_specific_item.json b/erpnext/selling/doctype/party_specific_item/party_specific_item.json
new file mode 100644
index 0000000..32b5d47
--- /dev/null
+++ b/erpnext/selling/doctype/party_specific_item/party_specific_item.json
@@ -0,0 +1,77 @@
+{
+ "actions": [],
+ "creation": "2021-08-27 19:28:07.559978",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "party_type",
+  "party",
+  "column_break_3",
+  "restrict_based_on",
+  "based_on_value"
+ ],
+ "fields": [
+  {
+   "fieldname": "party_type",
+   "fieldtype": "Select",
+   "in_list_view": 1,
+   "label": "Party Type",
+   "options": "Customer\nSupplier",
+   "reqd": 1
+  },
+  {
+   "fieldname": "party",
+   "fieldtype": "Dynamic Link",
+   "in_list_view": 1,
+   "label": "Party Name",
+   "options": "party_type",
+   "reqd": 1
+  },
+  {
+   "fieldname": "restrict_based_on",
+   "fieldtype": "Select",
+   "in_list_view": 1,
+   "label": "Restrict Items Based On",
+   "options": "Item\nItem Group\nBrand",
+   "reqd": 1
+  },
+  {
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "based_on_value",
+   "fieldtype": "Dynamic Link",
+   "in_list_view": 1,
+   "label": "Based On Value",
+   "options": "restrict_based_on",
+   "reqd": 1
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "links": [],
+ "modified": "2021-09-14 13:27:58.612334",
+ "modified_by": "Administrator",
+ "module": "Selling",
+ "name": "Party Specific Item",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "party",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/selling/doctype/party_specific_item/party_specific_item.py b/erpnext/selling/doctype/party_specific_item/party_specific_item.py
new file mode 100644
index 0000000..a408af5
--- /dev/null
+++ b/erpnext/selling/doctype/party_specific_item/party_specific_item.py
@@ -0,0 +1,19 @@
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+import frappe
+from frappe import _
+from frappe.model.document import Document
+
+
+class PartySpecificItem(Document):
+	def validate(self):
+		exists = frappe.db.exists({
+			'doctype': 'Party Specific Item',
+			'party_type': self.party_type,
+			'party': self.party,
+			'restrict_based_on': self.restrict_based_on,
+			'based_on': self.based_on_value,
+		})
+		if exists:
+			frappe.throw(_("This item filter has already been applied for the {0}").format(self.party_type))
diff --git a/erpnext/selling/doctype/party_specific_item/test_party_specific_item.py b/erpnext/selling/doctype/party_specific_item/test_party_specific_item.py
new file mode 100644
index 0000000..874a364
--- /dev/null
+++ b/erpnext/selling/doctype/party_specific_item/test_party_specific_item.py
@@ -0,0 +1,38 @@
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+
+import unittest
+
+import frappe
+
+from erpnext.controllers.queries import item_query
+
+test_dependencies = ['Item', 'Customer', 'Supplier']
+
+def create_party_specific_item(**args):
+	psi = frappe.new_doc("Party Specific Item")
+	psi.party_type = args.get('party_type')
+	psi.party = args.get('party')
+	psi.restrict_based_on = args.get('restrict_based_on')
+	psi.based_on_value = args.get('based_on_value')
+	psi.insert()
+
+class TestPartySpecificItem(unittest.TestCase):
+	def setUp(self):
+		self.customer = frappe.get_last_doc("Customer")
+		self.supplier = frappe.get_last_doc("Supplier")
+		self.item = frappe.get_last_doc("Item")
+
+	def test_item_query_for_customer(self):
+		create_party_specific_item(party_type='Customer', party=self.customer.name, restrict_based_on='Item', based_on_value=self.item.name)
+		filters = {'is_sales_item': 1, 'customer': self.customer.name}
+		items = item_query(doctype= 'Item', txt= '', searchfield= 'name', start= 0, page_len= 20,filters=filters, as_dict= False)
+		for item in items:
+			self.assertEqual(item[0], self.item.name)
+
+	def test_item_query_for_supplier(self):
+		create_party_specific_item(party_type='Supplier', party=self.supplier.name, restrict_based_on='Item Group', based_on_value=self.item.item_group)
+		filters = {'supplier': self.supplier.name, 'is_purchase_item': 1}
+		items = item_query(doctype= 'Item', txt= '', searchfield= 'name', start= 0, page_len= 20,filters=filters, as_dict= False)
+		for item in items:
+			self.assertEqual(item[2], self.item.item_group)
diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json
index 85282ca..7c7ed9a 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.json
+++ b/erpnext/selling/doctype/sales_order/sales_order.json
@@ -1480,6 +1480,7 @@
    "fetch_from": "customer.represents_company",
    "fieldname": "represents_company",
    "fieldtype": "Link",
+   "ignore_user_permissions": 1,
    "label": "Represents Company",
    "options": "Company",
    "read_only": 1
@@ -1512,7 +1513,7 @@
  "idx": 105,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-09-01 15:12:24.115483",
+ "modified": "2021-09-28 13:09:51.515542",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Sales Order",
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 9367609..dcf478b 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -110,7 +110,7 @@
 		if self.order_type == 'Sales' and not self.skip_delivery_note:
 			delivery_date_list = [d.delivery_date for d in self.get("items") if d.delivery_date]
 			max_delivery_date = max(delivery_date_list) if delivery_date_list else None
-			if not self.delivery_date:
+			if (max_delivery_date and not self.delivery_date) or (max_delivery_date and getdate(self.delivery_date) != getdate(max_delivery_date)):
 				self.delivery_date = max_delivery_date
 			if self.delivery_date:
 				for d in self.get("items"):
@@ -119,8 +119,6 @@
 					if getdate(self.transaction_date) > getdate(d.delivery_date):
 						frappe.msgprint(_("Expected Delivery Date should be after Sales Order Date"),
 							indicator='orange', title=_('Warning'))
-				if getdate(self.delivery_date) != getdate(max_delivery_date):
-					self.delivery_date = max_delivery_date
 			else:
 				frappe.throw(_("Please enter Delivery Date"))
 
diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.json b/erpnext/selling/doctype/selling_settings/selling_settings.json
index 59fcb98..c27f1ea 100644
--- a/erpnext/selling/doctype/selling_settings/selling_settings.json
+++ b/erpnext/selling/doctype/selling_settings/selling_settings.json
@@ -41,14 +41,14 @@
    "fieldtype": "Select",
    "in_list_view": 1,
    "label": "Customer Naming By",
-   "options": "Customer Name\nNaming Series"
+   "options": "Customer Name\nNaming Series\nAuto Name"
   },
   {
    "fieldname": "campaign_naming_by",
    "fieldtype": "Select",
    "in_list_view": 1,
    "label": "Campaign Naming By",
-   "options": "Campaign Name\nNaming Series"
+   "options": "Campaign Name\nNaming Series\nAuto Name"
   },
   {
    "fieldname": "customer_group",
@@ -204,7 +204,7 @@
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2021-09-01 22:55:33.803624",
+ "modified": "2021-09-08 19:38:10.175989",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Selling Settings",
@@ -223,4 +223,4 @@
  "sort_field": "modified",
  "sort_order": "DESC",
  "track_changes": 1
-}
+}
\ No newline at end of file
diff --git a/erpnext/selling/page/point_of_sale/pos_item_details.js b/erpnext/selling/page/point_of_sale/pos_item_details.js
index d899c5c..ec861d7 100644
--- a/erpnext/selling/page/point_of_sale/pos_item_details.js
+++ b/erpnext/selling/page/point_of_sale/pos_item_details.js
@@ -236,7 +236,7 @@
 				if (this.value) {
 					me.events.form_updated(me.current_item, 'warehouse', this.value).then(() => {
 						me.item_stock_map = me.events.get_item_stock_map();
-						const available_qty = me.item_stock_map[me.item_row.item_code][this.value];
+						const available_qty = me.item_stock_map[me.item_row.item_code] && me.item_stock_map[me.item_row.item_code][this.value];
 						if (available_qty === undefined) {
 							me.events.get_available_stock(me.item_row.item_code, this.value).then(() => {
 								// item stock map is updated now reset warehouse
diff --git a/erpnext/selling/page/point_of_sale/pos_payment.js b/erpnext/selling/page/point_of_sale/pos_payment.js
index 8e69851..7ddbf45 100644
--- a/erpnext/selling/page/point_of_sale/pos_payment.js
+++ b/erpnext/selling/page/point_of_sale/pos_payment.js
@@ -297,6 +297,7 @@
 		this.render_payment_mode_dom();
 		this.make_invoice_fields_control();
 		this.update_totals_section();
+		this.focus_on_default_mop();
 	}
 
 	edit_cart() {
@@ -378,17 +379,24 @@
 			});
 			this[`${mode}_control`].toggle_label(false);
 			this[`${mode}_control`].set_value(p.amount);
+		});
 
+		this.render_loyalty_points_payment_mode();
+
+		this.attach_cash_shortcuts(doc);
+	}
+
+	focus_on_default_mop() {
+		const doc = this.events.get_frm().doc;
+		const payments = doc.payments;
+		payments.forEach(p => {
+			const mode = p.mode_of_payment.replace(/ +/g, "_").toLowerCase();
 			if (p.default) {
 				setTimeout(() => {
 					this.$payment_modes.find(`.${mode}.mode-of-payment-control`).parent().click();
 				}, 500);
 			}
 		});
-
-		this.render_loyalty_points_payment_mode();
-
-		this.attach_cash_shortcuts(doc);
 	}
 
 	attach_cash_shortcuts(doc) {
diff --git a/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py
index 805c3d8..5c4d8b6 100644
--- a/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py
+++ b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py
@@ -73,7 +73,7 @@
 			`tabSales Order` so,
 			`tabSales Order Item` soi
 		LEFT JOIN `tabSales Invoice Item` sii
-			ON sii.so_detail = soi.name
+			ON sii.so_detail = soi.name and sii.docstatus = 1
 		WHERE
 			soi.parent = so.name
 			and so.status not in ('Stopped', 'Closed', 'On Hold')
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index 955ef5e..ddd4c4e 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -63,7 +63,7 @@
 			this.frm.set_query("item_code", "items", function() {
 				return {
 					query: "erpnext.controllers.queries.item_query",
-					filters: {'is_sales_item': 1}
+					filters: {'is_sales_item': 1, 'customer': cur_frm.doc.customer}
 				}
 			});
 		}
@@ -247,7 +247,12 @@
 		var editable_price_list_rate = cint(frappe.defaults.get_default("editable_price_list_rate"));
 
 		if(df && editable_price_list_rate) {
-			df.read_only = 0;
+			const parent_field = frappe.meta.get_parentfield(this.frm.doc.doctype, this.frm.doc.doctype + " Item");
+			if (!this.frm.fields_dict[parent_field]) return;
+
+			this.frm.fields_dict[parent_field].grid.update_docfield_property(
+				'price_list_rate', 'read_only', 0
+			);
 		}
 	}
 
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index 8403193..95ca386 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -46,43 +46,6 @@
 		});
 	},
 
-	change_abbreviation(frm) {
-		var dialog = new frappe.ui.Dialog({
-			title: "Replace Abbr",
-			fields: [
-				{"fieldtype": "Data", "label": "New Abbreviation", "fieldname": "new_abbr",
-					"reqd": 1 },
-				{"fieldtype": "Button", "label": "Update", "fieldname": "update"},
-			]
-		});
-
-		dialog.fields_dict.update.$input.click(function() {
-			var args = dialog.get_values();
-			if (!args) return;
-			frappe.show_alert(__("Update in progress. It might take a while."));
-			return frappe.call({
-				method: "erpnext.setup.doctype.company.company.enqueue_replace_abbr",
-				args: {
-					"company": frm.doc.name,
-					"old": frm.doc.abbr,
-					"new": args.new_abbr
-				},
-				callback: function(r) {
-					if (r.exc) {
-						frappe.msgprint(__("There were errors."));
-						return;
-					} else {
-						frm.set_value("abbr", args.new_abbr);
-					}
-					dialog.hide();
-					frm.refresh();
-				},
-				btn: this
-			});
-		});
-		dialog.show();
-	},
-
 	company_name: function(frm) {
 		if(frm.doc.__islocal) {
 			// add missing " " arg in split method
@@ -164,10 +127,6 @@
 					}, __('Manage'));
 				}
 			}
-
-			frm.add_custom_button(__('Change Abbreviation'), () => {
-				frm.trigger('change_abbreviation');
-			}, __('Manage'));
 		}
 
 		erpnext.company.set_chart_of_accounts_options(frm.doc);
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index 58cb52c..63d96bf 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -125,7 +125,8 @@
    "label": "Abbr",
    "oldfieldname": "abbr",
    "oldfieldtype": "Data",
-   "reqd": 1
+   "reqd": 1,
+   "set_only_once": 1
   },
   {
    "bold": 1,
@@ -747,10 +748,11 @@
  "image_field": "company_logo",
  "is_tree": 1,
  "links": [],
- "modified": "2021-07-12 11:27:06.353860",
+ "modified": "2021-10-04 12:09:25.833133",
  "modified_by": "Administrator",
  "module": "Setup",
  "name": "Company",
+ "naming_rule": "By fieldname",
  "nsm_parent_field": "parent_company",
  "owner": "Administrator",
  "permissions": [
@@ -808,4 +810,4 @@
  "sort_field": "modified",
  "sort_order": "ASC",
  "track_changes": 1
-}
+}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 6257d56..0b1b4a1 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -388,6 +388,7 @@
 		frappe.db.sql("delete from tabEmployee where company=%s", self.name)
 		frappe.db.sql("delete from tabDepartment where company=%s", self.name)
 		frappe.db.sql("delete from `tabTax Withholding Account` where company=%s", self.name)
+		frappe.db.sql("delete from `tabTransaction Deletion Record` where company=%s", self.name)
 
 		# delete tax templates
 		frappe.db.sql("delete from `tabSales Taxes and Charges Template` where company=%s", self.name)
@@ -398,44 +399,6 @@
 		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)
-	frappe.enqueue('erpnext.setup.doctype.company.company.replace_abbr', **kwargs)
-
-
-@frappe.whitelist()
-def replace_abbr(company, old, new):
-	new = new.strip()
-	if not new:
-		frappe.throw(_("Abbr can not be blank or space"))
-
-	frappe.only_for("System Manager")
-
-	def _rename_record(doc):
-		parts = doc[0].rsplit(" - ", 1)
-		if len(parts) == 1 or parts[1].lower() == old.lower():
-			frappe.rename_doc(dt, doc[0], parts[0] + " - " + new, force=True)
-
-	def _rename_records(dt):
-		# rename is expensive so let's be economical with memory usage
-		doc = (d for d in frappe.db.sql("select name from `tab%s` where company=%s" % (dt, '%s'), company))
-		for d in doc:
-			_rename_record(d)
-	try:
-		frappe.db.auto_commit_on_many_writes = 1
-		for dt in ["Warehouse", "Account", "Cost Center", "Department",
-				"Sales Taxes and Charges Template", "Purchase Taxes and Charges Template"]:
-			_rename_records(dt)
-			frappe.db.commit()
-		frappe.db.set_value("Company", company, "abbr", new)
-
-	except Exception:
-		frappe.log_error(title=_('Abbreviation Rename Error'))
-	finally:
-		frappe.db.auto_commit_on_many_writes = 0
-
-
 def get_name_with_abbr(name, company):
 	company_abbr = frappe.get_cached_value('Company',  company,  "abbr")
 	parts = name.split(" - ")
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index ddf3e66..ab50a58 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -39,6 +39,7 @@
 				self.parent_item_group = _('All Item Groups')
 
 		self.make_route()
+		self.validate_item_group_defaults()
 
 	def on_update(self):
 		NestedSet.on_update(self)
@@ -99,7 +100,7 @@
 		filter_engine = ProductFiltersBuilder(self.name)
 
 		context.field_filters = filter_engine.get_field_filters()
-		context.attribute_filters = filter_engine.get_attribute_fitlers()
+		context.attribute_filters = filter_engine.get_attribute_filters()
 
 		context.update({
 			"parents": get_parent_item_groups(self.parent_item_group),
@@ -134,6 +135,10 @@
 	def delete_child_item_groups_key(self):
 		frappe.cache().hdel("child_item_groups", self.name)
 
+	def validate_item_group_defaults(self):
+		from erpnext.stock.doctype.item.item import validate_item_default_company_links
+		validate_item_default_company_links(self.item_group_defaults)
+
 @frappe.whitelist(allow_guest=True)
 def get_product_list_for_group(product_group=None, start=0, limit=10, search=None):
 	if product_group:
diff --git a/erpnext/setup/doctype/item_group/test_records.json b/erpnext/setup/doctype/item_group/test_records.json
index 146da87..ce1d718 100644
--- a/erpnext/setup/doctype/item_group/test_records.json
+++ b/erpnext/setup/doctype/item_group/test_records.json
@@ -1,73 +1,74 @@
 [
  {
-  "doctype": "Item Group", 
-  "is_group": 0, 
-  "item_group_name": "_Test Item Group", 
+  "doctype": "Item Group",
+  "is_group": 0,
+  "item_group_name": "_Test Item Group",
   "parent_item_group": "All Item Groups",
   "item_group_defaults": [{
 		"company": "_Test Company",
 		"buying_cost_center": "_Test Cost Center 2 - _TC",
-		"selling_cost_center": "_Test Cost Center 2 - _TC"
+		"selling_cost_center": "_Test Cost Center 2 - _TC",
+		"default_warehouse": "_Test Warehouse - _TC"
 	}]
- }, 
+ },
  {
-  "doctype": "Item Group", 
-  "is_group": 0, 
-  "item_group_name": "_Test Item Group Desktops", 
+  "doctype": "Item Group",
+  "is_group": 0,
+  "item_group_name": "_Test Item Group Desktops",
   "parent_item_group": "All Item Groups"
- }, 
+ },
  {
-  "doctype": "Item Group", 
-  "is_group": 1, 
-  "item_group_name": "_Test Item Group A", 
+  "doctype": "Item Group",
+  "is_group": 1,
+  "item_group_name": "_Test Item Group A",
   "parent_item_group": "All Item Groups"
- }, 
+ },
  {
-  "doctype": "Item Group", 
-  "is_group": 1, 
-  "item_group_name": "_Test Item Group B", 
+  "doctype": "Item Group",
+  "is_group": 1,
+  "item_group_name": "_Test Item Group B",
   "parent_item_group": "All Item Groups"
- }, 
+ },
  {
-  "doctype": "Item Group", 
-  "is_group": 1, 
-  "item_group_name": "_Test Item Group B - 1", 
+  "doctype": "Item Group",
+  "is_group": 1,
+  "item_group_name": "_Test Item Group B - 1",
   "parent_item_group": "_Test Item Group B"
- }, 
+ },
  {
-  "doctype": "Item Group", 
-  "is_group": 1, 
-  "item_group_name": "_Test Item Group B - 2", 
+  "doctype": "Item Group",
+  "is_group": 1,
+  "item_group_name": "_Test Item Group B - 2",
   "parent_item_group": "_Test Item Group B"
- }, 
+ },
  {
-  "doctype": "Item Group", 
-  "is_group": 0, 
-  "item_group_name": "_Test Item Group B - 3", 
+  "doctype": "Item Group",
+  "is_group": 0,
+  "item_group_name": "_Test Item Group B - 3",
   "parent_item_group": "_Test Item Group B"
- }, 
+ },
  {
-  "doctype": "Item Group", 
-  "is_group": 1, 
-  "item_group_name": "_Test Item Group C", 
+  "doctype": "Item Group",
+  "is_group": 1,
+  "item_group_name": "_Test Item Group C",
   "parent_item_group": "All Item Groups"
- }, 
+ },
  {
-  "doctype": "Item Group", 
-  "is_group": 1, 
-  "item_group_name": "_Test Item Group C - 1", 
+  "doctype": "Item Group",
+  "is_group": 1,
+  "item_group_name": "_Test Item Group C - 1",
   "parent_item_group": "_Test Item Group C"
- }, 
+ },
  {
-  "doctype": "Item Group", 
-  "is_group": 1, 
-  "item_group_name": "_Test Item Group C - 2", 
+  "doctype": "Item Group",
+  "is_group": 1,
+  "item_group_name": "_Test Item Group C - 2",
   "parent_item_group": "_Test Item Group C"
- }, 
+ },
  {
-  "doctype": "Item Group", 
-  "is_group": 1, 
-  "item_group_name": "_Test Item Group D", 
+  "doctype": "Item Group",
+  "is_group": 1,
+  "item_group_name": "_Test Item Group D",
   "parent_item_group": "All Item Groups"
  },
  {
@@ -104,4 +105,4 @@
    }
   ]
  }
-]
\ No newline at end of file
+]
diff --git a/erpnext/setup/setup_wizard/data/country_wise_tax.json b/erpnext/setup/setup_wizard/data/country_wise_tax.json
index 34af093..b7e895d 100644
--- a/erpnext/setup/setup_wizard/data/country_wise_tax.json
+++ b/erpnext/setup/setup_wizard/data/country_wise_tax.json
@@ -2116,9 +2116,9 @@
 	},
 
 	"Saudi Arabia": {
-		"KSA VAT 5%": {
-			"account_name": "VAT 5%",
-			"tax_rate": 5.00
+		"KSA VAT 15%": {
+			"account_name": "VAT 15%",
+			"tax_rate": 15.00
 		},
 		"KSA VAT Zero": {
 			"account_name": "VAT Zero",
diff --git a/erpnext/setup/setup_wizard/operations/defaults_setup.py b/erpnext/setup/setup_wizard/operations/defaults_setup.py
index 6dd0fb1..55d5ec8 100644
--- a/erpnext/setup/setup_wizard/operations/defaults_setup.py
+++ b/erpnext/setup/setup_wizard/operations/defaults_setup.py
@@ -62,6 +62,13 @@
 	hr_settings.emp_created_by = "Naming Series"
 	hr_settings.leave_approval_notification_template = _("Leave Approval Notification")
 	hr_settings.leave_status_notification_template = _("Leave Status Notification")
+
+	hr_settings.send_interview_reminder = 1
+	hr_settings.interview_reminder_template = _("Interview Reminder")
+	hr_settings.remind_before = "00:15:00"
+
+	hr_settings.send_interview_feedback_reminder = 1
+	hr_settings.feedback_reminder_notification_template = _("Interview Feedback Reminder")
 	hr_settings.save()
 
 def set_no_copy_fields_in_variant_settings():
diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py
index 907967c..c473395 100644
--- a/erpnext/setup/setup_wizard/operations/install_fixtures.py
+++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py
@@ -264,16 +264,26 @@
 	base_path = frappe.get_app_path("erpnext", "hr", "doctype")
 	response = frappe.read_file(os.path.join(base_path, "leave_application/leave_application_email_template.html"))
 
-	records += [{'doctype': 'Email Template', 'name': _("Leave Approval Notification"), 'response': response,\
+	records += [{'doctype': 'Email Template', 'name': _("Leave Approval Notification"), 'response': response,
 		'subject': _("Leave Approval Notification"), 'owner': frappe.session.user}]
 
-	records += [{'doctype': 'Email Template', 'name': _("Leave Status Notification"), 'response': response,\
+	records += [{'doctype': 'Email Template', 'name': _("Leave Status Notification"), 'response': response,
 		'subject': _("Leave Status Notification"), 'owner': frappe.session.user}]
 
+	response = frappe.read_file(os.path.join(base_path, "interview/interview_reminder_notification_template.html"))
+
+	records += [{'doctype': 'Email Template', 'name': _('Interview Reminder'), 'response': response,
+		'subject': _('Interview Reminder'), 'owner': frappe.session.user}]
+
+	response = frappe.read_file(os.path.join(base_path, "interview/interview_feedback_reminder_template.html"))
+
+	records += [{'doctype': 'Email Template', 'name': _('Interview Feedback Reminder'), 'response': response,
+		'subject': _('Interview Feedback Reminder'), 'owner': frappe.session.user}]
+
 	base_path = frappe.get_app_path("erpnext", "stock", "doctype")
 	response = frappe.read_file(os.path.join(base_path, "delivery_trip/dispatch_notification_template.html"))
 
-	records += [{'doctype': 'Email Template', 'name': _("Dispatch Notification"), 'response': response,\
+	records += [{'doctype': 'Email Template', 'name': _("Dispatch Notification"), 'response': response,
 		'subject': _("Your order is out for delivery!"), 'owner': frappe.session.user}]
 
 	# Records for the Supplier Scorecard
@@ -317,6 +327,14 @@
 	hr_settings.emp_created_by = "Naming Series"
 	hr_settings.leave_approval_notification_template = _("Leave Approval Notification")
 	hr_settings.leave_status_notification_template = _("Leave Status Notification")
+
+	hr_settings.send_interview_reminder = 1
+	hr_settings.interview_reminder_template = _("Interview Reminder")
+	hr_settings.remind_before = "00:15:00"
+
+	hr_settings.send_interview_feedback_reminder = 1
+	hr_settings.feedback_reminder_notification_template = _("Interview Feedback Reminder")
+
 	hr_settings.save()
 
 def update_item_variant_settings():
diff --git a/erpnext/setup/setup_wizard/operations/taxes_setup.py b/erpnext/setup/setup_wizard/operations/taxes_setup.py
index faa25df..58a14d2 100644
--- a/erpnext/setup/setup_wizard/operations/taxes_setup.py
+++ b/erpnext/setup/setup_wizard/operations/taxes_setup.py
@@ -192,7 +192,7 @@
 	default_root_type = 'Liability'
 	root_type = account.get('root_type', default_root_type)
 
-	existing_accounts = frappe.get_list('Account',
+	existing_accounts = frappe.get_all('Account',
 		filters={
 			'company': company_name,
 			'root_type': root_type
@@ -247,7 +247,7 @@
 
 	# Create a new group account named 'Duties and Taxes' or 'Tax Assets' just
 	# below the root account
-	root_account = frappe.get_list('Account', {
+	root_account = frappe.get_all('Account', {
 		'is_group': 1,
 		'root_type': root_type,
 		'company': company_name,
diff --git a/erpnext/shopping_cart/filters.py b/erpnext/shopping_cart/filters.py
index aaeff0f..4787ae5 100644
--- a/erpnext/shopping_cart/filters.py
+++ b/erpnext/shopping_cart/filters.py
@@ -4,7 +4,6 @@
 from __future__ import unicode_literals
 
 import frappe
-from frappe import _dict
 
 
 class ProductFiltersBuilder:
@@ -57,37 +56,31 @@
 
 		return filter_data
 
-	def get_attribute_fitlers(self):
+	def get_attribute_filters(self):
 		attributes = [row.attribute for row in self.doc.filter_attributes]
-		attribute_docs = [
-			frappe.get_doc('Item Attribute', attribute) for attribute in attributes
-		]
 
-		valid_attributes = []
+		if not attributes:
+			return []
 
-		for attr_doc in attribute_docs:
-			selected_attributes = []
-			for attr in attr_doc.item_attribute_values:
-				or_filters = []
-				filters= [
-					["Item Variant Attribute", "attribute", "=", attr.parent],
-					["Item Variant Attribute", "attribute_value", "=", attr.attribute_value]
-				]
-				if self.item_group:
-					or_filters.extend([
-						["item_group", "=", self.item_group],
-						["Website Item Group", "item_group", "=", self.item_group]
-					])
+		result = frappe.db.sql(
+			"""
+			select
+				distinct attribute, attribute_value
+			from
+				`tabItem Variant Attribute`
+			where
+				attribute in %(attributes)s
+				and attribute_value is not null
+		""",
+			{"attributes": attributes},
+			as_dict=1,
+		)
 
-				if frappe.db.get_all("Item", filters, or_filters=or_filters, limit=1):
-					selected_attributes.append(attr)
+		attribute_value_map = {}
+		for d in result:
+			attribute_value_map.setdefault(d.attribute, []).append(d.attribute_value)
 
-			if selected_attributes:
-				valid_attributes.append(
-					_dict(
-						item_attribute_values=selected_attributes,
-						name=attr_doc.name
-					)
-				)
-
-		return valid_attributes
+		out = []
+		for name, values in attribute_value_map.items():
+			out.append(frappe._dict(name=name, item_attribute_values=values))
+		return out
diff --git a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html
index 1e3d0d0..e560f4a 100644
--- a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html
+++ b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html
@@ -1,7 +1,7 @@
 {%- macro slide(image, title, subtitle, action, label, index, align="Left", theme="Dark") -%}
 {%- set align_class = resolve_class({
 	'text-right': align == 'Right',
-	'text-centre': align == 'Center',
+	'text-centre': align == 'Centre',
 	'text-left': align == 'Left',
 }) -%}
 
@@ -15,7 +15,7 @@
 	<div class="carousel-body container d-flex {{ align_class }}">
 		<div class="carousel-content align-self-center">
 			{%- if title -%}<h1 class="{{ heading_class }}">{{ title }}</h1>{%- endif -%}
-			{%- if subtitle -%}<p class="text-muted mt-2">{{ subtitle }}</p>{%- endif -%}
+			{%- if subtitle -%}<p class="{{ heading_class }} mt-2">{{ subtitle }}</p>{%- endif -%}
 			{%- if action -%}
 			<a href="{{ action }}" class="btn btn-primary mt-3">
 				{{ label }}
@@ -27,12 +27,14 @@
 </div>
 {%- endmacro -%}
 
-<div id="{{ slider_name }}" class="section-carousel carousel slide" data-ride="carousel">
+{%- set hero_slider_id = 'id-' + frappe.utils.generate_hash('HeroSlider', 12) -%}
+
+<div id="{{ hero_slider_id }}" class="section-carousel carousel slide" data-ride="carousel">
 	{%- if show_indicators -%}
 	<ol class="carousel-indicators">
 		{%- for index in ['1', '2', '3', '4', '5'] -%}
 		{%- if values['slide_' + index + '_image'] -%}
-			<li data-target="#{{ slider_name }}" data-slide-to="{{ frappe.utils.cint(index) - 1 }}" class="{{ 'active' if index=='1' else ''}}"></li>
+			<li data-target="#{{ hero_slider_id }}" data-slide-to="{{ frappe.utils.cint(index) - 1 }}" class="{{ 'active' if index=='1' else ''}}"></li>
 		{%- endif -%}
 		{%- endfor -%}
 	</ol>
@@ -54,7 +56,7 @@
 		{%- endfor -%}
 	</div>
 	{%- if show_controls -%}
-	<a class="carousel-control-prev" href="#{{ slider_name }}" role="button" data-slide="prev">
+	<a class="carousel-control-prev" href="#{{ hero_slider_id }}" role="button" data-slide="prev">
 		<div class="carousel-control">
 			<svg class="mr-1" width="20" height="20" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
 				<path d="M11.625 3.75L6.375 9L11.625 14.25" stroke="#4C5A67" stroke-linecap="round" stroke-linejoin="round"/>
@@ -62,7 +64,7 @@
 		</div>
 		<span class="sr-only">Previous</span>
 	</a>
-	<a class="carousel-control-next" href="#{{ slider_name }}" role="button" data-slide="next">
+	<a class="carousel-control-next" href="#{{ hero_slider_id }}" role="button" data-slide="next">
 		<div class="carousel-control">
 			<svg class="ml-1" width="20" height="20" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
 				<path d="M6.375 14.25L11.625 9L6.375 3.75" stroke="#4C5A67" stroke-linecap="round" stroke-linejoin="round"/>
@@ -73,13 +75,12 @@
 	{%- endif -%}
 </div>
 
-<script type="text/javascript">
-	$('.carousel').carousel({
-		interval: false,
-		pause: "hover",
-		wrap: true
-	})
+<script>
+	frappe.ready(function () {
+		$('.carousel').carousel({
+			interval: false,
+			pause: "hover",
+			wrap: true
+		})
+	});
 </script>
-
-<style>
-</style>
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index fdc8763..ad1b3b4 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -395,8 +395,7 @@
    "fieldtype": "Link",
    "label": "Billing Address Name",
    "options": "Address",
-   "print_hide": 1,
-   "read_only": 1
+   "print_hide": 1
   },
   {
    "fieldname": "tax_id",
@@ -1277,6 +1276,7 @@
    "fetch_from": "customer.represents_company",
    "fieldname": "represents_company",
    "fieldtype": "Link",
+   "ignore_user_permissions": 1,
    "label": "Represents Company",
    "options": "Company",
    "read_only": 1
@@ -1308,7 +1308,7 @@
  "idx": 146,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-08-27 20:14:40.215231",
+ "modified": "2021-10-08 14:29:13.428984",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Delivery Note",
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 5542cd0..f75b52c 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -185,7 +185,6 @@
 			if not d['warehouse'] and frappe.db.get_value("Item", d['item_code'], "is_stock_item") == 1:
 				frappe.throw(_("Warehouse required for stock Item {0}").format(d["item_code"]))
 
-
 	def update_current_stock(self):
 		if self.get("_action") and self._action != "update_after_submit":
 			for d in self.get('items'):
diff --git a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
index b05090a..a96c299 100644
--- a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
+++ b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
@@ -468,7 +468,7 @@
    "width": "100px"
   },
   {
-   "depends_on": "eval:parent.is_internal_customer",
+   "depends_on": "eval:parent.is_internal_customer || doc.target_warehouse",
    "fieldname": "target_warehouse",
    "fieldtype": "Link",
    "hidden": 1,
@@ -759,7 +759,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-02-23 01:04:08.588104",
+ "modified": "2021-10-05 12:12:44.018872",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Delivery Note Item",
@@ -767,4 +767,4 @@
  "permissions": [],
  "sort_field": "modified",
  "sort_order": "DESC"
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 50fdd38..8cc9f74 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -4,6 +4,7 @@
 import copy
 import itertools
 import json
+from typing import List
 
 import frappe
 from frappe import _
@@ -36,6 +37,7 @@
 	get_parent_item_groups,
 	invalidate_cache_for,
 )
+from erpnext.stock.doctype.item_default.item_default import ItemDefault
 
 
 class DuplicateReorderRows(frappe.ValidationError):
@@ -134,9 +136,9 @@
 		self.validate_fixed_asset()
 		self.validate_retain_sample()
 		self.validate_uom_conversion_factor()
-		self.validate_item_defaults()
 		self.validate_customer_provided_part()
 		self.update_defaults_from_item_group()
+		self.validate_item_defaults()
 		self.validate_auto_reorder_enabled_in_stock_settings()
 		self.cant_change()
 		self.update_show_in_website()
@@ -179,6 +181,8 @@
 				"doctype": "Item Price",
 				"price_list": price_list,
 				"item_code": self.name,
+				"uom": self.stock_uom,
+				"brand": self.brand,
 				"currency": erpnext.get_default_currency(),
 				"price_list_rate": self.standard_rate
 			})
@@ -561,8 +565,12 @@
 					_("Default BOM ({0}) must be active for this item or its template").format(bom_item))
 
 	def fill_customer_code(self):
-		""" Append all the customer codes and insert into "customer_code" field of item table """
-		self.customer_code = ','.join(d.ref_code for d in self.get("customer_items", []))
+		"""
+			Append all the customer codes and insert into "customer_code" field of item table.
+			Used to search Item by customer code.
+		"""
+		customer_codes = set(d.ref_code for d in self.get("customer_items", []))
+		self.customer_code = ','.join(customer_codes)
 
 	def check_item_tax(self):
 		"""Check whether Tax Rate is not entered twice for same Tax Type"""
@@ -628,9 +636,21 @@
 				_("An Item Group exists with same name, please change the item name or rename the item group"))
 
 	def update_item_price(self):
-		frappe.db.sql("""update `tabItem Price` set item_name=%s,
-			item_description=%s, brand=%s where item_code=%s""",
-					(self.item_name, self.description, self.brand, self.name))
+		frappe.db.sql("""
+				UPDATE `tabItem Price`
+				SET
+					item_name=%(item_name)s,
+					item_description=%(item_description)s,
+					brand=%(brand)s
+				WHERE item_code=%(item_code)s
+			""",
+			dict(
+				item_name=self.item_name,
+				item_description=self.description,
+				brand=self.brand,
+				item_code=self.name
+			)
+		)
 
 	def on_trash(self):
 		super(Item, self).on_trash()
@@ -782,35 +802,39 @@
 		if len(companies) != len(self.item_defaults):
 			frappe.throw(_("Cannot set multiple Item Defaults for a company."))
 
+		validate_item_default_company_links(self.item_defaults)
+
+
 	def update_defaults_from_item_group(self):
 		"""Get defaults from Item Group"""
-		if self.item_group and not self.item_defaults:
-			item_defaults = frappe.db.get_values("Item Default", {"parent": self.item_group},
-				['company', 'default_warehouse','default_price_list','buying_cost_center','default_supplier',
-				'expense_account','selling_cost_center','income_account'], as_dict = 1)
-			if item_defaults:
-				for item in item_defaults:
-					self.append('item_defaults', {
-						'company': item.company,
-						'default_warehouse': item.default_warehouse,
-						'default_price_list': item.default_price_list,
-						'buying_cost_center': item.buying_cost_center,
-						'default_supplier': item.default_supplier,
-						'expense_account': item.expense_account,
-						'selling_cost_center': item.selling_cost_center,
-						'income_account': item.income_account
-					})
-			else:
-				warehouse = ''
-				defaults = frappe.defaults.get_defaults() or {}
+		if self.item_defaults or not self.item_group:
+			return
 
-				# To check default warehouse is belong to the default company
-				if defaults.get("default_warehouse") and defaults.company and frappe.db.exists("Warehouse",
-					{'name': defaults.default_warehouse, 'company': defaults.company}):
-						self.append("item_defaults", {
-							"company": defaults.get("company"),
-							"default_warehouse": defaults.default_warehouse
-						})
+		item_defaults = frappe.db.get_values("Item Default", {"parent": self.item_group},
+			['company', 'default_warehouse','default_price_list','buying_cost_center','default_supplier',
+			'expense_account','selling_cost_center','income_account'], as_dict = 1)
+		if item_defaults:
+			for item in item_defaults:
+				self.append('item_defaults', {
+					'company': item.company,
+					'default_warehouse': item.default_warehouse,
+					'default_price_list': item.default_price_list,
+					'buying_cost_center': item.buying_cost_center,
+					'default_supplier': item.default_supplier,
+					'expense_account': item.expense_account,
+					'selling_cost_center': item.selling_cost_center,
+					'income_account': item.income_account
+				})
+		else:
+			defaults = frappe.defaults.get_defaults() or {}
+
+			# To check default warehouse is belong to the default company
+			if defaults.get("default_warehouse") and defaults.company and frappe.db.exists("Warehouse",
+				{'name': defaults.default_warehouse, 'company': defaults.company}):
+					self.append("item_defaults", {
+						"company": defaults.get("company"),
+						"default_warehouse": defaults.default_warehouse
+					})
 
 	def update_variants(self):
 		if self.flags.dont_update_variants or \
@@ -1328,3 +1352,25 @@
 @erpnext.allow_regional
 def set_item_tax_from_hsn_code(item):
 	pass
+
+
+def validate_item_default_company_links(item_defaults: List[ItemDefault]) -> None:
+	for item_default in item_defaults:
+		for doctype, field in [
+			['Warehouse', 'default_warehouse'],
+			['Cost Center', 'buying_cost_center'],
+			['Cost Center', 'selling_cost_center'],
+			['Account', 'expense_account'],
+			['Account', 'income_account']
+		]:
+			if item_default.get(field):
+				company = frappe.db.get_value(doctype, item_default.get(field), 'company', cache=True)
+				if company and company != item_default.company:
+					frappe.throw(_("Row #{}: {} {} doesn't belong to Company {}. Please select valid {}.")
+						.format(
+							item_default.idx,
+							doctype,
+							frappe.bold(item_default.get(field)),
+							frappe.bold(item_default.company),
+							frappe.bold(frappe.unscrub(field))
+						), title=_("Invalid Item Defaults"))
diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py
index 0ed2761..e911d35 100644
--- a/erpnext/stock/doctype/item/test_item.py
+++ b/erpnext/stock/doctype/item/test_item.py
@@ -232,6 +232,23 @@
 		for key, value in purchase_item_check.items():
 			self.assertEqual(value, purchase_item_details.get(key))
 
+	def test_item_default_validations(self):
+
+		with self.assertRaises(frappe.ValidationError) as ve:
+			make_item("Bad Item defaults", {
+				"item_group": "_Test Item Group",
+				"item_defaults": [{
+					"company": "_Test Company 1",
+					"default_warehouse": "_Test Warehouse - _TC",
+					"expense_account": "Stock In Hand - _TC",
+					"buying_cost_center": "_Test Cost Center - _TC",
+					"selling_cost_center": "_Test Cost Center - _TC",
+				}]
+			})
+
+		self.assertTrue("belong to company" in str(ve.exception).lower(),
+				msg="Mismatching company entities in item defaults should not be allowed.")
+
 	def test_item_attribute_change_after_variant(self):
 		frappe.delete_doc_if_exists("Item", "_Test Variant Item-L", force=1)
 
diff --git a/erpnext/stock/doctype/item_variant_settings/item_variant_settings.js b/erpnext/stock/doctype/item_variant_settings/item_variant_settings.js
index e8fb347..488920a 100644
--- a/erpnext/stock/doctype/item_variant_settings/item_variant_settings.js
+++ b/erpnext/stock/doctype/item_variant_settings/item_variant_settings.js
@@ -2,19 +2,32 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on('Item Variant Settings', {
-	setup: function(frm) {
+	refresh: function(frm) {
 		const allow_fields = [];
-		const exclude_fields = ["naming_series", "item_code", "item_name", "show_in_website",
-		"show_variant_in_website", "opening_stock", "variant_of", "valuation_rate"];
+
+		const existing_fields = frm.doc.fields.map(row => row.field_name);
+		const exclude_fields = [...existing_fields, "naming_series", "item_code", "item_name",
+			"show_in_website", "show_variant_in_website", "standard_rate", "opening_stock", "image",
+			"variant_of", "valuation_rate", "barcodes", "website_image", "thumbnail",
+			"website_specifiations", "web_long_description", "has_variants", "attributes"];
+
+		const exclude_field_types = ['HTML', 'Section Break', 'Column Break', 'Button', 'Read Only'];
 
 		frappe.model.with_doctype('Item', () => {
 			frappe.get_meta('Item').fields.forEach(d => {
-				if(!in_list(['HTML', 'Section Break', 'Column Break', 'Button', 'Read Only'], d.fieldtype)
+				if (!in_list(exclude_field_types, d.fieldtype)
 					&& !d.no_copy && !in_list(exclude_fields, d.fieldname)) {
 					allow_fields.push(d.fieldname);
 				}
 			});
 
+			if (allow_fields.length == 0) {
+				allow_fields.push({
+					label: __("No additional fields available"),
+					value: "",
+				});
+			}
+
 			frm.fields_dict.fields.grid.update_docfield_property(
 				'field_name', 'options', allow_fields
 			);
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index 9eb4721..17df977 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -6,10 +6,13 @@
 
 from __future__ import unicode_literals
 
+import json
+
 import frappe
 from frappe import _, msgprint
 from frappe.model.mapper import get_mapped_doc
 from frappe.utils import cstr, flt, get_link_to_form, getdate, new_line_sep, nowdate
+from six import string_types
 
 from erpnext.buying.utils import check_on_hold_or_closed_status, validate_for_items
 from erpnext.controllers.buying_controller import BuyingController
@@ -269,7 +272,11 @@
 	material_request.update_status(status)
 
 @frappe.whitelist()
-def make_purchase_order(source_name, target_doc=None):
+def make_purchase_order(source_name, target_doc=None, args=None):
+	if args is None:
+		args = {}
+	if isinstance(args, string_types):
+		args = json.loads(args)
 
 	def postprocess(source, target_doc):
 		if frappe.flags.args and frappe.flags.args.default_supplier:
@@ -284,9 +291,12 @@
 		set_missing_values(source, target_doc)
 
 	def select_item(d):
-		return d.ordered_qty < d.stock_qty
+		filtered_items = args.get('filtered_children', [])
+		child_filter = d.name in filtered_items if filtered_items else True
 
-	doclist = get_mapped_doc("Material Request", source_name, 	{
+		return d.ordered_qty < d.stock_qty and child_filter
+
+	doclist = get_mapped_doc("Material Request", source_name, {
 		"Material Request": {
 			"doctype": "Purchase Order",
 			"validation": {
@@ -313,7 +323,7 @@
 
 @frappe.whitelist()
 def make_request_for_quotation(source_name, target_doc=None):
-	doclist = get_mapped_doc("Material Request", source_name, 	{
+	doclist = get_mapped_doc("Material Request", source_name, {
 		"Material Request": {
 			"doctype": "Request for Quotation",
 			"validation": {
diff --git a/erpnext/stock/doctype/pick_list_item/pick_list_item.json b/erpnext/stock/doctype/pick_list_item/pick_list_item.json
index 8665986..805286d 100644
--- a/erpnext/stock/doctype/pick_list_item/pick_list_item.json
+++ b/erpnext/stock/doctype/pick_list_item/pick_list_item.json
@@ -36,7 +36,8 @@
    "fieldname": "qty",
    "fieldtype": "Float",
    "in_list_view": 1,
-   "label": "Qty"
+   "label": "Qty",
+   "reqd": 1
   },
   {
    "fieldname": "picked_qty",
@@ -180,7 +181,7 @@
  ],
  "istable": 1,
  "links": [],
- "modified": "2020-06-24 17:18:57.357120",
+ "modified": "2021-09-28 12:02:16.923056",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Pick List Item",
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
index 1a59734..112dded 100755
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
@@ -1140,6 +1140,7 @@
    "fetch_from": "supplier.represents_company",
    "fieldname": "represents_company",
    "fieldtype": "Link",
+   "ignore_user_permissions": 1,
    "label": "Represents Company",
    "options": "Company",
    "read_only": 1
@@ -1149,7 +1150,7 @@
  "idx": 261,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-08-17 20:16:40.849885",
+ "modified": "2021-09-28 13:11:10.181328",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt",
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 07a568d..47c8df9 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -842,7 +842,8 @@
 			"doctype": "Stock Entry Detail",
 			"field_map": {
 				"warehouse": "s_warehouse",
-				"parent": "reference_purchase_receipt"
+				"parent": "reference_purchase_receipt",
+				"batch_no": "batch_no"
 			},
 		},
 	}, target_doc, set_missing_values)
diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
index 62b3a6a..d86e52f 100644
--- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
+++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
@@ -7,7 +7,7 @@
 import frappe
 from frappe import _
 from frappe.model.document import Document
-from frappe.utils import cint, get_link_to_form, now, today
+from frappe.utils import cint, get_link_to_form, get_weekday, now, nowtime, today
 from frappe.utils.user import get_users_with_role
 from rq.timeouts import JobTimeoutException
 
@@ -126,6 +126,9 @@
 	frappe.sendmail(recipients=recipients, subject=subject, message=message)
 
 def repost_entries():
+	if not in_configured_timeslot():
+		return
+
 	riv_entries = get_repost_item_valuation_entries()
 
 	for row in riv_entries:
@@ -144,3 +147,26 @@
 		WHERE status in ('Queued', 'In Progress') and creation <= %s and docstatus = 1
 		ORDER BY timestamp(posting_date, posting_time) asc, creation asc
 	""", now(), as_dict=1)
+
+
+def in_configured_timeslot(repost_settings=None, current_time=None):
+	"""Check if current time is in configured timeslot for reposting."""
+
+	if repost_settings is None:
+		repost_settings = frappe.get_cached_doc("Stock Reposting Settings")
+
+	if not repost_settings.limit_reposting_timeslot:
+		return True
+
+	if get_weekday() == repost_settings.limits_dont_apply_on:
+		return True
+
+	start_time = repost_settings.start_time
+	end_time = repost_settings.end_time
+
+	now_time = current_time or nowtime()
+
+	if start_time < end_time:
+		return end_time >= now_time >= start_time
+	else:
+		return now_time >= start_time or now_time <= end_time
diff --git a/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
index c70a9ec..c086f93 100644
--- a/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
+++ b/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
@@ -1,11 +1,72 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
 # See license.txt
-from __future__ import unicode_literals
 
-# import frappe
 import unittest
 
+import frappe
+
+from erpnext.stock.doctype.repost_item_valuation.repost_item_valuation import (
+	in_configured_timeslot,
+)
+
 
 class TestRepostItemValuation(unittest.TestCase):
-	pass
+	def test_repost_time_slot(self):
+		repost_settings = frappe.get_doc("Stock Reposting Settings")
+
+		positive_cases = [
+			{"limit_reposting_timeslot": 0},
+			{
+				"limit_reposting_timeslot": 1,
+				"start_time": "18:00:00",
+				"end_time": "09:00:00",
+				"current_time": "20:00:00",
+			},
+			{
+				"limit_reposting_timeslot": 1,
+				"start_time": "09:00:00",
+				"end_time": "18:00:00",
+				"current_time": "12:00:00",
+			},
+			{
+				"limit_reposting_timeslot": 1,
+				"start_time": "23:00:00",
+				"end_time": "09:00:00",
+				"current_time": "2:00:00",
+			},
+		]
+
+		for case in positive_cases:
+			repost_settings.update(case)
+			self.assertTrue(
+				in_configured_timeslot(repost_settings, case.get("current_time")),
+				msg=f"Exepcted true from : {case}",
+			)
+
+		negative_cases = [
+			{
+				"limit_reposting_timeslot": 1,
+				"start_time": "18:00:00",
+				"end_time": "09:00:00",
+				"current_time": "09:01:00",
+			},
+			{
+				"limit_reposting_timeslot": 1,
+				"start_time": "09:00:00",
+				"end_time": "18:00:00",
+				"current_time": "19:00:00",
+			},
+			{
+				"limit_reposting_timeslot": 1,
+				"start_time": "23:00:00",
+				"end_time": "09:00:00",
+				"current_time": "22:00:00",
+			},
+		]
+
+		for case in negative_cases:
+			repost_settings.update(case)
+			self.assertFalse(
+				in_configured_timeslot(repost_settings, case.get("current_time")),
+				msg=f"Exepcted false from : {case}",
+			)
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 82d8aae..a9254fb 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -611,7 +611,9 @@
 
 	return reserved_sr_nos
 
-def fetch_serial_numbers(filters, qty, do_not_include=[]):
+def fetch_serial_numbers(filters, qty, do_not_include=None):
+	if do_not_include is None:
+		do_not_include = []
 	batch_join_selection = ""
 	batch_no_condition = ""
 	batch_nos = filters.get("batch_no")
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index c819d49..ac8303e 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -323,6 +323,12 @@
 		attach_bom_items(frm.doc.bom_no)
 	},
 
+	before_save: function(frm) {
+		frm.doc.items.forEach((item) => {
+			item.uom = item.uom || item.stock_uom;
+		})
+	},
+
 	stock_entry_type: function(frm){
 		frm.remove_custom_button('Bill of Materials', "Get Items From");
 		frm.events.show_bom_custom_button(frm);
@@ -548,44 +554,7 @@
 	calculate_basic_amount: function(frm, item) {
 		item.basic_amount = flt(flt(item.transfer_qty) * flt(item.basic_rate),
 			precision("basic_amount", item));
-
-		frm.events.calculate_amount(frm);
-	},
-
-	calculate_amount: function(frm) {
 		frm.events.calculate_total_additional_costs(frm);
-		let total_basic_amount = 0;
-		if (in_list(["Repack", "Manufacture"], frm.doc.purpose)) {
-			total_basic_amount = frappe.utils.sum(
-				(frm.doc.items || []).map(function(i) {
-					return i.is_finished_item ? flt(i.basic_amount) : 0;
-				})
-			);
-		} else {
-			total_basic_amount = frappe.utils.sum(
-				(frm.doc.items || []).map(function(i) {
-					return i.t_warehouse ? flt(i.basic_amount) : 0;
-				})
-			);
-		}
-		for (let i in frm.doc.items) {
-			let item = frm.doc.items[i];
-
-			if (((in_list(["Repack", "Manufacture"], frm.doc.purpose) && item.is_finished_item) || item.t_warehouse) && total_basic_amount) {
-				item.additional_cost = (flt(item.basic_amount) / total_basic_amount) * frm.doc.total_additional_costs;
-			} else {
-				item.additional_cost = 0;
-			}
-
-			item.amount = flt(item.basic_amount + flt(item.additional_cost), precision("amount", item));
-
-			if (flt(item.transfer_qty)) {
-				item.valuation_rate = flt(flt(item.basic_rate) + (flt(item.additional_cost) / flt(item.transfer_qty)),
-					precision("valuation_rate", item));
-			}
-		}
-
-		refresh_field('items');
 	},
 
 	calculate_total_additional_costs: function(frm) {
@@ -781,11 +750,6 @@
 	amount: function(frm, cdt, cdn) {
 		frm.events.set_base_amount(frm, cdt, cdn);
 
-		// Adding this check because same table in used in LCV
-		// This causes an error if you try to post an LCV immediately after a Stock Entry
-		if (frm.doc.doctype == 'Stock Entry') {
-			frm.events.calculate_amount(frm);
-		}
 	},
 
 	expense_account: function(frm, cdt, cdn) {
@@ -1100,4 +1064,4 @@
   );
 }
 
-$.extend(cur_frm.cscript, new erpnext.stock.StockEntry({frm: cur_frm}));
+extend_cscript(cur_frm.cscript, new erpnext.stock.StockEntry({frm: cur_frm}));
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 41ca830..bd7d22b 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -4,6 +4,7 @@
 from __future__ import unicode_literals
 
 import json
+from collections import defaultdict
 
 import frappe
 from frappe import _
@@ -554,22 +555,27 @@
 
 	def distribute_additional_costs(self):
 		# If no incoming items, set additional costs blank
-		if not any([d.item_code for d in self.items if d.t_warehouse]):
+		if not any(d.item_code for d in self.items if d.t_warehouse):
 			self.additional_costs = []
 
-		self.total_additional_costs = sum([flt(t.base_amount) for t in self.get("additional_costs")])
+		self.total_additional_costs = sum(flt(t.base_amount) for t in self.get("additional_costs"))
 
 		if self.purpose in ("Repack", "Manufacture"):
-			incoming_items_cost = sum([flt(t.basic_amount) for t in self.get("items") if t.is_finished_item])
+			incoming_items_cost = sum(flt(t.basic_amount) for t in self.get("items") if t.is_finished_item)
 		else:
-			incoming_items_cost = sum([flt(t.basic_amount) for t in self.get("items") if t.t_warehouse])
+			incoming_items_cost = sum(flt(t.basic_amount) for t in self.get("items") if t.t_warehouse)
 
-		if incoming_items_cost:
-			for d in self.get("items"):
-				if (self.purpose in ("Repack", "Manufacture") and d.is_finished_item) or d.t_warehouse:
-					d.additional_cost = (flt(d.basic_amount) / incoming_items_cost) * self.total_additional_costs
-				else:
-					d.additional_cost = 0
+		if not incoming_items_cost:
+			return
+
+		for d in self.get("items"):
+			if self.purpose in ("Repack", "Manufacture") and not d.is_finished_item:
+				d.additional_cost = 0
+				continue
+			elif not d.t_warehouse:
+				d.additional_cost = 0
+				continue
+			d.additional_cost = (flt(d.basic_amount) / incoming_items_cost) * self.total_additional_costs
 
 	def update_valuation_rate(self):
 		for d in self.get("items"):
@@ -684,7 +690,7 @@
 
 	def validate_bom(self):
 		for d in self.get('items'):
-			if d.bom_no and (d.t_warehouse != getattr(self, "pro_doc", frappe._dict()).scrap_warehouse):
+			if d.bom_no and d.is_finished_item:
 				item_code = d.original_item or d.item_code
 				validate_bom_no(item_code, d.bom_no)
 
@@ -804,7 +810,11 @@
 	def get_gl_entries(self, warehouse_account):
 		gl_entries = super(StockEntry, self).get_gl_entries(warehouse_account)
 
-		total_basic_amount = sum([flt(t.basic_amount) for t in self.get("items") if t.t_warehouse])
+		if self.purpose in ("Repack", "Manufacture"):
+			total_basic_amount = sum(flt(t.basic_amount) for t in self.get("items") if t.is_finished_item)
+		else:
+			total_basic_amount = sum(flt(t.basic_amount) for t in self.get("items") if t.t_warehouse)
+
 		divide_based_on = total_basic_amount
 
 		if self.get("additional_costs") and not total_basic_amount:
@@ -815,20 +825,24 @@
 
 		for t in self.get("additional_costs"):
 			for d in self.get("items"):
-				if d.t_warehouse:
-					item_account_wise_additional_cost.setdefault((d.item_code, d.name), {})
-					item_account_wise_additional_cost[(d.item_code, d.name)].setdefault(t.expense_account, {
-						"amount": 0.0,
-						"base_amount": 0.0
-					})
+				if self.purpose in ("Repack", "Manufacture") and not d.is_finished_item:
+					continue
+				elif not d.t_warehouse:
+					continue
 
-					multiply_based_on = d.basic_amount if total_basic_amount else d.qty
+				item_account_wise_additional_cost.setdefault((d.item_code, d.name), {})
+				item_account_wise_additional_cost[(d.item_code, d.name)].setdefault(t.expense_account, {
+					"amount": 0.0,
+					"base_amount": 0.0
+				})
 
-					item_account_wise_additional_cost[(d.item_code, d.name)][t.expense_account]["amount"] += \
-						flt(t.amount * multiply_based_on) / divide_based_on
+				multiply_based_on = d.basic_amount if total_basic_amount else d.qty
 
-					item_account_wise_additional_cost[(d.item_code, d.name)][t.expense_account]["base_amount"] += \
-						flt(t.base_amount * multiply_based_on) / divide_based_on
+				item_account_wise_additional_cost[(d.item_code, d.name)][t.expense_account]["amount"] += \
+					flt(t.amount * multiply_based_on) / divide_based_on
+
+				item_account_wise_additional_cost[(d.item_code, d.name)][t.expense_account]["base_amount"] += \
+					flt(t.base_amount * multiply_based_on) / divide_based_on
 
 		if item_account_wise_additional_cost:
 			for d in self.get("items"):
@@ -1191,13 +1205,88 @@
 
 		# item dict = { item_code: {qty, description, stock_uom} }
 		item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=qty,
-			fetch_exploded = 0, fetch_scrap_items = 1)
+			fetch_exploded = 0, fetch_scrap_items = 1) or {}
 
 		for item in itervalues(item_dict):
 			item.from_warehouse = ""
 			item.is_scrap_item = 1
+
+		for row in self.get_scrap_items_from_job_card():
+			if row.stock_qty <= 0:
+				continue
+
+			item_row = item_dict.get(row.item_code)
+			if not item_row:
+				item_row = frappe._dict({})
+
+			item_row.update({
+				'uom': row.stock_uom,
+				'from_warehouse': '',
+				'qty': row.stock_qty + flt(item_row.stock_qty),
+				'converison_factor': 1,
+				'is_scrap_item': 1,
+				'item_name': row.item_name,
+				'description': row.description,
+				'allow_zero_valuation_rate': 1
+			})
+
+			item_dict[row.item_code] = item_row
+
 		return item_dict
 
+	def get_scrap_items_from_job_card(self):
+		if not self.pro_doc:
+			self.set_work_order_details()
+
+		scrap_items = frappe.db.sql('''
+			SELECT
+				JCSI.item_code, JCSI.item_name, SUM(JCSI.stock_qty) as stock_qty, JCSI.stock_uom, JCSI.description
+			FROM
+				`tabJob Card` JC, `tabJob Card Scrap Item` JCSI
+			WHERE
+				JCSI.parent = JC.name AND JC.docstatus = 1
+				AND JCSI.item_code IS NOT NULL AND JC.work_order = %s
+			GROUP BY
+				JCSI.item_code
+		''', self.work_order, as_dict=1)
+
+		pending_qty = flt(self.pro_doc.qty) - flt(self.pro_doc.produced_qty)
+		if pending_qty <=0:
+			return []
+
+		used_scrap_items = self.get_used_scrap_items()
+		for row in scrap_items:
+			row.stock_qty -= flt(used_scrap_items.get(row.item_code))
+			row.stock_qty = (row.stock_qty) * flt(self.fg_completed_qty) / flt(pending_qty)
+
+			if used_scrap_items.get(row.item_code):
+				used_scrap_items[row.item_code] -= row.stock_qty
+
+			if cint(frappe.get_cached_value('UOM', row.stock_uom, 'must_be_whole_number')):
+				row.stock_qty = frappe.utils.ceil(row.stock_qty)
+
+		return scrap_items
+
+	def get_used_scrap_items(self):
+		used_scrap_items = defaultdict(float)
+		data = frappe.get_all(
+			'Stock Entry',
+			fields = [
+				'`tabStock Entry Detail`.`item_code`', '`tabStock Entry Detail`.`qty`'
+			],
+			filters = [
+				['Stock Entry', 'work_order', '=', self.work_order],
+				['Stock Entry Detail', 'is_scrap_item', '=', 1],
+				['Stock Entry', 'docstatus', '=', 1],
+				['Stock Entry', 'purpose', 'in', ['Repack', 'Manufacture']]
+			]
+		)
+
+		for row in data:
+			used_scrap_items[row.item_code] += row.qty
+
+		return used_scrap_items
+
 	def get_unconsumed_raw_materials(self):
 		wo = frappe.get_doc("Work Order", self.work_order)
 		wo_items = frappe.get_all('Work Order Item',
@@ -1264,9 +1353,9 @@
 		po_qty = frappe.db.sql("""select qty, produced_qty, material_transferred_for_manufacturing from
 			`tabWork Order` where name=%s""", self.work_order, as_dict=1)[0]
 
-		manufacturing_qty = flt(po_qty.qty)
+		manufacturing_qty = flt(po_qty.qty) or 1
 		produced_qty = flt(po_qty.produced_qty)
-		trans_qty = flt(po_qty.material_transferred_for_manufacturing)
+		trans_qty = flt(po_qty.material_transferred_for_manufacturing) or 1
 
 		for item in transferred_materials:
 			qty= item.qty
@@ -1417,8 +1506,8 @@
 			se_child.is_scrap_item = item_dict[d].get("is_scrap_item", 0)
 			se_child.is_process_loss = item_dict[d].get("is_process_loss", 0)
 
-			for field in ["idx", "po_detail", "original_item",
-				"expense_account", "description", "item_name", "serial_no", "batch_no"]:
+			for field in ["idx", "po_detail", "original_item", "expense_account",
+				"description", "item_name", "serial_no", "batch_no", "allow_zero_valuation_rate"]:
 				if item_dict[d].get(field):
 					se_child.set(field, item_dict[d].get(field))
 
@@ -1503,7 +1592,8 @@
 					qty_to_reserve -= reserved_qty[0][0]
 				if qty_to_reserve > 0:
 					for item in self.items:
-						if item.item_code == item_code:
+						has_serial_no = frappe.get_cached_value("Item", item.item_code, "has_serial_no")
+						if item.item_code == item_code and has_serial_no:
 							serial_nos = (item.serial_no).split("\n")
 							for serial_no in serial_nos:
 								if qty_to_reserve > 0:
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index 46619eb..c9d0af5 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -837,6 +837,39 @@
 
 		frappe.db.set_default("allow_negative_stock", 0)
 
+	def test_additional_cost_distribution_manufacture(self):
+		se = frappe.get_doc(
+				doctype="Stock Entry",
+				purpose="Manufacture",
+				additional_costs=[frappe._dict(base_amount=100)],
+				items=[
+					frappe._dict(item_code="RM", basic_amount=10),
+					frappe._dict(item_code="FG", basic_amount=20, t_warehouse="X", is_finished_item=1),
+					frappe._dict(item_code="scrap", basic_amount=30, t_warehouse="X")
+				],
+			)
+
+		se.distribute_additional_costs()
+
+		distributed_costs = [d.additional_cost for d in se.items]
+		self.assertEqual([0.0, 100.0, 0.0], distributed_costs)
+
+	def test_additional_cost_distribution_non_manufacture(self):
+		se = frappe.get_doc(
+				doctype="Stock Entry",
+				purpose="Material Receipt",
+				additional_costs=[frappe._dict(base_amount=100)],
+				items=[
+					frappe._dict(item_code="RECEIVED_1", basic_amount=20, t_warehouse="X"),
+					frappe._dict(item_code="RECEIVED_2", basic_amount=30, t_warehouse="X")
+				],
+			)
+
+		se.distribute_additional_costs()
+
+		distributed_costs = [d.additional_cost for d in se.items]
+		self.assertEqual([40.0, 60.0], distributed_costs)
+
 def make_serialized_item(**args):
 	args = frappe._dict(args)
 	se = frappe.copy_doc(test_records[0])
diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
index 2463a21..40ae340 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
+++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
@@ -142,6 +142,7 @@
    "oldfieldtype": "Data",
    "print_width": "150px",
    "read_only": 1,
+   "search_index": 1,
    "width": "150px"
   },
   {
@@ -316,7 +317,7 @@
  "in_create": 1,
  "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2020-09-07 11:10:35.318872",
+ "modified": "2021-10-08 12:42:51.857631",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Ledger Entry",
@@ -338,4 +339,4 @@
  ],
  "sort_field": "modified",
  "sort_order": "DESC"
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index caa1d42..382fdfa 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -181,4 +181,3 @@
 
 	frappe.db.add_index("Stock Ledger Entry", ["voucher_no", "voucher_type"])
 	frappe.db.add_index("Stock Ledger Entry", ["batch_no", "item_code", "warehouse"])
-	frappe.db.add_index("Stock Ledger Entry", ["voucher_detail_no"])
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index fa96c5a..f59a4e6 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -619,6 +619,11 @@
 	item_dict = frappe.db.get_value("Item", item_code,
 		["has_serial_no", "has_batch_no"], as_dict=1)
 
+	if not item_dict:
+		# In cases of data upload to Items table
+		msg = _("Item {} does not exist.").format(item_code)
+		frappe.throw(msg, title=_("Missing"))
+
 	serial_nos = ""
 	with_serial_no = True if item_dict.get("has_serial_no") else False
 	data = get_stock_balance(item_code, warehouse, posting_date, posting_time,
diff --git a/erpnext/healthcare/doctype/healthcare_settings/__init__.py b/erpnext/stock/doctype/stock_reposting_settings/__init__.py
similarity index 100%
rename from erpnext/healthcare/doctype/healthcare_settings/__init__.py
rename to erpnext/stock/doctype/stock_reposting_settings/__init__.py
diff --git a/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.js b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.js
new file mode 100644
index 0000000..42d0723
--- /dev/null
+++ b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Stock Reposting Settings', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json
new file mode 100644
index 0000000..2474059
--- /dev/null
+++ b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json
@@ -0,0 +1,72 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "creation": "2021-10-01 10:56:30.814787",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "scheduling_section",
+  "limit_reposting_timeslot",
+  "start_time",
+  "end_time",
+  "limits_dont_apply_on"
+ ],
+ "fields": [
+  {
+   "fieldname": "scheduling_section",
+   "fieldtype": "Section Break",
+   "label": "Scheduling"
+  },
+  {
+   "depends_on": "limit_reposting_timeslot",
+   "fieldname": "start_time",
+   "fieldtype": "Time",
+   "label": "Start Time",
+   "mandatory_depends_on": "limit_reposting_timeslot"
+  },
+  {
+   "depends_on": "limit_reposting_timeslot",
+   "fieldname": "end_time",
+   "fieldtype": "Time",
+   "label": "End Time",
+   "mandatory_depends_on": "limit_reposting_timeslot"
+  },
+  {
+   "depends_on": "limit_reposting_timeslot",
+   "fieldname": "limits_dont_apply_on",
+   "fieldtype": "Select",
+   "label": "Limits don't apply on",
+   "options": "\nMonday\nTuesday\nWednesday\nThursday\nFriday\nSaturday\nSunday"
+  },
+  {
+   "default": "0",
+   "fieldname": "limit_reposting_timeslot",
+   "fieldtype": "Check",
+   "label": "Limit timeslot for Stock Reposting"
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "issingle": 1,
+ "links": [],
+ "modified": "2021-10-01 11:27:28.981594",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Stock Reposting Settings",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "print": 1,
+   "read": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py
new file mode 100644
index 0000000..bab521d
--- /dev/null
+++ b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py
@@ -0,0 +1,28 @@
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from frappe.model.document import Document
+from frappe.utils import add_to_date, get_datetime, get_time_str, time_diff_in_hours
+
+
+class StockRepostingSettings(Document):
+
+
+	def validate(self):
+		self.set_minimum_reposting_time_slot()
+
+	def set_minimum_reposting_time_slot(self):
+		"""Ensure that timeslot for reposting is at least 12 hours."""
+		if not self.limit_reposting_timeslot:
+			return
+
+		start_time = get_datetime(self.start_time)
+		end_time = get_datetime(self.end_time)
+
+		if start_time > end_time:
+			end_time = add_to_date(end_time, days=1, as_datetime=True)
+
+		diff = time_diff_in_hours(end_time, start_time)
+
+		if diff < 10:
+			self.end_time = get_time_str(add_to_date(self.start_time, hours=10, as_datetime=True))
diff --git a/erpnext/stock/doctype/stock_reposting_settings/test_stock_reposting_settings.py b/erpnext/stock/doctype/stock_reposting_settings/test_stock_reposting_settings.py
new file mode 100644
index 0000000..fad74d3
--- /dev/null
+++ b/erpnext/stock/doctype/stock_reposting_settings/test_stock_reposting_settings.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+
+# import frappe
+import unittest
+
+
+class TestStockRepostingSettings(unittest.TestCase):
+	pass
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 19597c3..cbff214 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -382,7 +382,7 @@
 
 	return out
 
-def get_item_warehouse(item, args, overwrite_warehouse, defaults={}):
+def get_item_warehouse(item, args, overwrite_warehouse, defaults=None):
 	if not defaults:
 		defaults = frappe._dict({
 			'item_defaults' : get_item_defaults(item.name, args.company),
diff --git a/erpnext/stock/reorder_item.py b/erpnext/stock/reorder_item.py
index 3cd4cd2..7c6fbfd 100644
--- a/erpnext/stock/reorder_item.py
+++ b/erpnext/stock/reorder_item.py
@@ -4,6 +4,7 @@
 from __future__ import unicode_literals
 
 import json
+from math import ceil
 
 import frappe
 from frappe import _
@@ -149,11 +150,16 @@
 							conversion_factor = frappe.db.get_value("UOM Conversion Detail",
 								{'parent': item.name, 'uom': uom}, 'conversion_factor') or 1.0
 
+					must_be_whole_number = frappe.db.get_value("UOM", uom, "must_be_whole_number", cache=True)
+					qty = d.reorder_qty / conversion_factor
+					if must_be_whole_number:
+						qty = ceil(qty)
+
 					mr.append("items", {
 						"doctype": "Material Request Item",
 						"item_code": d.item_code,
 						"schedule_date": add_days(nowdate(),cint(item.lead_time_days)),
-						"qty": d.reorder_qty / conversion_factor,
+						"qty": qty,
 						"uom": uom,
 						"stock_uom": item.stock_uom,
 						"warehouse": d.warehouse,
diff --git a/erpnext/stock/report/stock_ageing/stock_ageing.js b/erpnext/stock/report/stock_ageing/stock_ageing.js
index b22788f..db463b7 100644
--- a/erpnext/stock/report/stock_ageing/stock_ageing.js
+++ b/erpnext/stock/report/stock_ageing/stock_ageing.js
@@ -22,7 +22,15 @@
 			"fieldname":"warehouse",
 			"label": __("Warehouse"),
 			"fieldtype": "Link",
-			"options": "Warehouse"
+			"options": "Warehouse",
+			get_query: () => {
+				const company = frappe.query_report.get_filter_value("company");
+				return {
+					filters: {
+						...company && {company},
+					}
+				};
+			}
 		},
 		{
 			"fieldname":"item_code",
diff --git a/erpnext/stock/report/stock_balance/stock_balance.js b/erpnext/stock/report/stock_balance/stock_balance.js
index 7d22823..ce6ffa0 100644
--- a/erpnext/stock/report/stock_balance/stock_balance.js
+++ b/erpnext/stock/report/stock_balance/stock_balance.js
@@ -53,13 +53,14 @@
 			"width": "80",
 			"options": "Warehouse",
 			get_query: () => {
-				var warehouse_type = frappe.query_report.get_filter_value('warehouse_type');
-				if(warehouse_type){
-					return {
-						filters: {
-							'warehouse_type': warehouse_type
-						}
-					};
+				let warehouse_type = frappe.query_report.get_filter_value("warehouse_type");
+				let company = frappe.query_report.get_filter_value("company");
+
+				return {
+					filters: {
+						...warehouse_type && {warehouse_type},
+						...company && {company}
+					}
 				}
 			}
 		},
diff --git a/erpnext/stock/report/test_reports.py b/erpnext/stock/report/test_reports.py
new file mode 100644
index 0000000..d7fb5b2
--- /dev/null
+++ b/erpnext/stock/report/test_reports.py
@@ -0,0 +1,63 @@
+import unittest
+from typing import List, Tuple
+
+from erpnext.tests.utils import ReportFilters, ReportName, execute_script_report
+
+DEFAULT_FILTERS = {
+	"company": "_Test Company",
+	"from_date": "2010-01-01",
+	"to_date": "2030-01-01",
+}
+
+
+REPORT_FILTER_TEST_CASES: List[Tuple[ReportName, ReportFilters]] = [
+	("Stock Ledger", {"_optional": True}),
+	("Stock Balance", {"_optional": True}),
+	("Stock Projected Qty", {"_optional": True}),
+	("Batch-Wise Balance History", {}),
+	("Itemwise Recommended Reorder Level", {"item_group": "All Item Groups"}),
+	("COGS By Item Group", {}),
+	("Stock Qty vs Serial No Count", {"warehouse": "_Test Warehouse - _TC"}),
+	(
+		"Stock and Account Value Comparison",
+		{
+			"company": "_Test Company with perpetual inventory",
+			"account": "Stock In Hand - TCP1",
+			"as_on_date": "2021-01-01",
+		},
+	),
+	("Product Bundle Balance", {"date": "2022-01-01", "_optional": True}),
+	(
+		"Stock Analytics",
+		{
+			"from_date": "2021-01-01",
+			"to_date": "2021-12-31",
+			"value_quantity": "Quantity",
+			"_optional": True,
+		},
+	),
+	("Warehouse wise Item Balance Age and Value", {"_optional": True}),
+	("Item Variant Details", {"item": "_Test Variant Item",}),
+	("Total Stock Summary", {"group_by": "warehouse",}),
+	("Batch Item Expiry Status", {}),
+	("Stock Ageing", {"range1": 30, "range2": 60, "range3": 90, "_optional": True}),
+]
+
+OPTIONAL_FILTERS = {
+	"warehouse": "_Test Warehouse - _TC",
+	"item": "_Test Item",
+	"item_group": "_Test Item Group",
+}
+
+
+class TestReports(unittest.TestCase):
+	def test_execute_all_stock_reports(self):
+		"""Test that all script report in stock modules are executable with supported filters"""
+		for report, filter in REPORT_FILTER_TEST_CASES:
+			execute_script_report(
+				report_name=report,
+				module="Stock",
+				filters=filter,
+				default_filters=DEFAULT_FILTERS,
+				optional_filters=OPTIONAL_FILTERS if filter.get("_optional") else None,
+			)
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index 5421242..1b5b792 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -407,7 +407,8 @@
 				return
 
 		# Get dynamic incoming/outgoing rate
-		self.get_dynamic_incoming_outgoing_rate(sle)
+		if not self.args.get("sle_id"):
+			self.get_dynamic_incoming_outgoing_rate(sle)
 
 		if sle.serial_no:
 			self.get_serialized_values(sle)
@@ -447,7 +448,8 @@
 		sle.doctype="Stock Ledger Entry"
 		frappe.get_doc(sle).db_update()
 
-		self.update_outgoing_rate_on_transaction(sle)
+		if not self.args.get("sle_id"):
+			self.update_outgoing_rate_on_transaction(sle)
 
 	def validate_negative_stock(self, sle):
 		"""
@@ -681,11 +683,15 @@
 			if self.wh_data.stock_queue[-1][1]==incoming_rate:
 				self.wh_data.stock_queue[-1][0] += actual_qty
 			else:
+				# Item has a positive balance qty, add new entry
 				if self.wh_data.stock_queue[-1][0] > 0:
 					self.wh_data.stock_queue.append([actual_qty, incoming_rate])
-				else:
+				else: # negative balance qty
 					qty = self.wh_data.stock_queue[-1][0] + actual_qty
-					self.wh_data.stock_queue[-1] = [qty, incoming_rate]
+					if qty > 0: # new balance qty is positive
+						self.wh_data.stock_queue[-1] = [qty, incoming_rate]
+					else: # new balance qty is still negative, maintain same rate
+						self.wh_data.stock_queue[-1][0] = qty
 		else:
 			qty_to_pop = abs(actual_qty)
 			while qty_to_pop:
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index 7d7399d..0fe1068 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -228,7 +228,7 @@
 def set_first_response_time(communication, method):
 	if communication.get('reference_doctype') == "Issue":
 		issue = get_parent_doc(communication)
-		if is_first_response(issue):
+		if is_first_response(issue) and issue.service_level_agreement:
 			first_response_time = calculate_first_response_time(issue, get_datetime(issue.first_responded_on))
 			issue.db_set("first_response_time", first_response_time)
 
diff --git a/erpnext/support/doctype/service_level_agreement/service_level_agreement.json b/erpnext/support/doctype/service_level_agreement/service_level_agreement.json
index b649b87..5f470aa 100644
--- a/erpnext/support/doctype/service_level_agreement/service_level_agreement.json
+++ b/erpnext/support/doctype/service_level_agreement/service_level_agreement.json
@@ -203,10 +203,11 @@
   }
  ],
  "links": [],
- "modified": "2021-07-27 11:16:45.596579",
+ "modified": "2021-10-02 11:32:55.556024",
  "modified_by": "Administrator",
  "module": "Support",
  "name": "Service Level Agreement",
+ "naming_rule": "Expression",
  "owner": "Administrator",
  "permissions": [
   {
@@ -237,4 +238,4 @@
  "sort_field": "modified",
  "sort_order": "DESC",
  "track_changes": 1
-}
+}
\ No newline at end of file
diff --git a/erpnext/support/doctype/service_level_agreement/service_level_agreement.py b/erpnext/support/doctype/service_level_agreement/service_level_agreement.py
index bd47811..6bdd8f2 100644
--- a/erpnext/support/doctype/service_level_agreement/service_level_agreement.py
+++ b/erpnext/support/doctype/service_level_agreement/service_level_agreement.py
@@ -339,7 +339,7 @@
 
 def apply(doc, method=None):
 	# Applies SLA to document on validate
-	if frappe.flags.in_patch or frappe.flags.in_install or frappe.flags.in_setup_wizard or \
+	if frappe.flags.in_patch or frappe.flags.in_migrate or frappe.flags.in_install or frappe.flags.in_setup_wizard or \
 		doc.doctype not in get_documents_with_active_service_level_agreement():
 		return
 
diff --git a/erpnext/templates/emails/holiday_reminder.html b/erpnext/templates/emails/holiday_reminder.html
index e38d27b..bbef6be 100644
--- a/erpnext/templates/emails/holiday_reminder.html
+++ b/erpnext/templates/emails/holiday_reminder.html
@@ -11,6 +11,6 @@
         {% endfor %}
     </ol>
     {% else %}
-    <p>You don't have no upcoming holidays this {{ frequency }}.</p>
+    <p>You have no upcoming holidays this {{ frequency }}.</p>
     {% endif %}
 {% endif %}
diff --git a/erpnext/templates/print_formats/includes/total.html b/erpnext/templates/print_formats/includes/total.html
index 8179980..879203b 100644
--- a/erpnext/templates/print_formats/includes/total.html
+++ b/erpnext/templates/print_formats/includes/total.html
@@ -7,7 +7,7 @@
 		</div>
 	{% else %}
 		<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
-			<label>{{ _(doc.meta.get_label('total')) }}</label></div>
+			<label>{{ _(df.label) }}</label></div>
 		<div class="col-xs-7 text-right">
 			{{ doc.get_formatted("total", doc) }}
 		</div>
diff --git a/erpnext/tests/test_webform.py b/erpnext/tests/test_webform.py
new file mode 100644
index 0000000..19255db
--- /dev/null
+++ b/erpnext/tests/test_webform.py
@@ -0,0 +1,138 @@
+import unittest
+
+import frappe
+
+from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
+
+
+class TestWebsite(unittest.TestCase):
+	def test_permission_for_custom_doctype(self):
+		create_user('Supplier 1', 'supplier1@gmail.com')
+		create_user('Supplier 2', 'supplier2@gmail.com')
+		create_supplier_with_contact('Supplier1', 'All Supplier Groups', 'Supplier 1', 'supplier1@gmail.com')
+		create_supplier_with_contact('Supplier2', 'All Supplier Groups', 'Supplier 2', 'supplier2@gmail.com')
+		po1 = create_purchase_order(supplier='Supplier1')
+		po2 = create_purchase_order(supplier='Supplier2')
+
+		create_custom_doctype()
+		create_webform()
+		create_order_assignment(supplier='Supplier1', po = po1.name)
+		create_order_assignment(supplier='Supplier2', po = po2.name)
+
+		frappe.set_user("Administrator")
+		# checking if data consist of all order assignment of Supplier1 and Supplier2
+		self.assertTrue('Supplier1' and 'Supplier2' in [data.supplier for data in get_data()])
+
+		frappe.set_user("supplier1@gmail.com")
+		# checking if data only consist of order assignment of Supplier1
+		self.assertTrue('Supplier1' in [data.supplier for data in get_data()])
+		self.assertFalse([data.supplier for data in get_data() if data.supplier != 'Supplier1'])
+
+		frappe.set_user("supplier2@gmail.com")
+		# checking if data only consist of order assignment of Supplier2
+		self.assertTrue('Supplier2' in [data.supplier for data in get_data()])
+		self.assertFalse([data.supplier for data in get_data() if data.supplier != 'Supplier2'])
+
+		frappe.set_user("Administrator")
+
+def get_data():
+	webform_list_contexts = frappe.get_hooks('webform_list_context')
+	if webform_list_contexts:
+		context = frappe._dict(frappe.get_attr(webform_list_contexts[0])('Buying') or {})
+	kwargs = dict(doctype='Order Assignment', order_by = 'modified desc')
+	return context.get_list(**kwargs)
+
+def create_user(name, email):
+	frappe.get_doc({
+		'doctype': 'User',
+		'send_welcome_email': 0,
+		'user_type': 'Website User',
+		'first_name': name,
+		'email': email,
+		'roles': [{"doctype": "Has Role", "role": "Supplier"}]
+	}).insert(ignore_if_duplicate = True)
+
+def create_supplier_with_contact(name, group, contact_name, contact_email):
+	supplier = frappe.get_doc({
+		'doctype': 'Supplier',
+		'supplier_name': name,
+		'supplier_group': group
+	}).insert(ignore_if_duplicate = True)
+
+	if not frappe.db.exists('Contact', contact_name+'-1-'+name):
+		new_contact = frappe.new_doc("Contact")
+		new_contact.first_name = contact_name
+		new_contact.is_primary_contact = True,
+		new_contact.append('links', {
+			"link_doctype": "Supplier",
+			"link_name": supplier.name
+		})
+		new_contact.append('email_ids', {
+			"email_id": contact_email,
+			"is_primary": 1
+		})
+
+		new_contact.insert(ignore_mandatory=True)
+
+def create_custom_doctype():
+	frappe.get_doc({
+		'doctype': 'DocType',
+		'name': 'Order Assignment',
+		'module': 'Buying',
+		'custom': 1,
+		'autoname': 'field:po',
+		'fields': [
+			{'label': 'PO', 'fieldname': 'po', 'fieldtype': 'Link', 'options': 'Purchase Order'},
+			{'label': 'Supplier', 'fieldname': 'supplier', 'fieldtype': 'Data', "fetch_from": "po.supplier"}
+		],
+		'permissions': [
+			{
+				"create": 1,
+				"delete": 1,
+				"email": 1,
+				"export": 1,
+				"print": 1,
+				"read": 1,
+				"report": 1,
+				"role": "System Manager",
+				"share": 1,
+				"write": 1
+			},
+			{
+				"read": 1,
+				"role": "Supplier"
+			}
+		]
+	}).insert(ignore_if_duplicate = True)
+
+def create_webform():
+	frappe.get_doc({
+		'doctype': 'Web Form',
+		'module': 'Buying',
+		'title': 'SO Schedule',
+		'route': 'so-schedule',
+		'doc_type': 'Order Assignment',
+		'web_form_fields': [
+			{
+				'doctype': 'Web Form Field',
+				'fieldname': 'po',
+				'fieldtype': 'Link',
+				'options': 'Purchase Order',
+				'label': 'PO'
+			},
+			{
+				'doctype': 'Web Form Field',
+				'fieldname': 'supplier',
+				'fieldtype': 'Data',
+				'label': 'Supplier'
+			}
+		]
+
+	}).insert(ignore_if_duplicate = True)
+
+def create_order_assignment(supplier, po):
+	frappe.get_doc({
+		'doctype': 'Order Assignment',
+		'po': po,
+		'supplier': supplier,
+	}).insert(ignore_if_duplicate = True)
\ No newline at end of file
diff --git a/erpnext/tests/ui_test_helpers.py b/erpnext/tests/ui_test_helpers.py
index 76c7608..9c8c371 100644
--- a/erpnext/tests/ui_test_helpers.py
+++ b/erpnext/tests/ui_test_helpers.py
@@ -7,6 +7,8 @@
 	create_company()
 	create_missing_designation()
 
+	frappe.db.sql("DELETE FROM tabEmployee WHERE company='Test Org Chart'")
+
 	emp1 = create_employee('Test Employee 1', 'CEO')
 	emp2 = create_employee('Test Employee 2', 'CTO')
 	emp3 = create_employee('Test Employee 3', 'Head of Marketing and Sales', emp1)
diff --git a/erpnext/tests/utils.py b/erpnext/tests/utils.py
index 2156bd5..a3cab4b 100644
--- a/erpnext/tests/utils.py
+++ b/erpnext/tests/utils.py
@@ -3,8 +3,13 @@
 
 import copy
 from contextlib import contextmanager
+from typing import Any, Dict, NewType, Optional
 
 import frappe
+from frappe.core.doctype.report.report import get_report_module_dotted_path
+
+ReportFilters = Dict[str, Any]
+ReportName = NewType("ReportName", str)
 
 
 def create_test_contact_and_address():
@@ -78,3 +83,39 @@
 		for key, value in previous_settings.items():
 			setattr(settings, key, value)
 		settings.save()
+
+
+def execute_script_report(
+		report_name: ReportName,
+		module: str,
+		filters: ReportFilters,
+		default_filters: Optional[ReportFilters] = None,
+		optional_filters: Optional[ReportFilters] = None
+	):
+	"""Util for testing execution of a report with specified filters.
+
+	Tests the execution of report with default_filters + filters.
+	Tests the execution using optional_filters one at a time.
+
+	Args:
+		report_name: Human readable name of report (unscrubbed)
+		module: module to which report belongs to
+		filters: specific values for filters
+		default_filters: default values for filters such as company name.
+		optional_filters: filters which should be tested one at a time in addition to default filters.
+	"""
+
+	if default_filters is None:
+		default_filters = {}
+
+	report_execute_fn = frappe.get_attr(get_report_module_dotted_path(module, report_name) + ".execute")
+	report_filters = frappe._dict(default_filters).copy().update(filters)
+
+	report_data = report_execute_fn(report_filters)
+
+	if optional_filters:
+		for key, value in optional_filters.items():
+			filter_with_optional_param = report_filters.copy().update({key: value})
+			report_execute_fn(filter_with_optional_param)
+
+	return report_data
diff --git a/erpnext/www/all-products/index.html b/erpnext/www/all-products/index.html
index 7c18ecc..a7838ee 100644
--- a/erpnext/www/all-products/index.html
+++ b/erpnext/www/all-products/index.html
@@ -98,14 +98,14 @@
 					<div class="filter-options">
 						{% for attr_value in attribute.item_attribute_values %}
 						<div class="checkbox">
-							<label data-value="{{ value }}">
+							<label>
 								<input type="checkbox"
 									class="product-filter attribute-filter"
-									id="{{attr_value.name}}"
+									id="{{attr_value}}"
 									data-attribute-name="{{ attribute.name }}"
-									data-attribute-value="{{ attr_value.attribute_value }}"
+									data-attribute-value="{{ attr_value }}"
 									{% if attr_value.checked %} checked {% endif %}>
-									<span class="label-area">{{ attr_value.attribute_value }}</span>
+									<span class="label-area">{{ attr_value }}</span>
 							</label>
 						</div>
 						{% endfor %}
diff --git a/erpnext/www/all-products/index.py b/erpnext/www/all-products/index.py
index 335c104..df5258b 100644
--- a/erpnext/www/all-products/index.py
+++ b/erpnext/www/all-products/index.py
@@ -27,7 +27,7 @@
 	filter_engine = ProductFiltersBuilder()
 
 	context.field_filters = filter_engine.get_field_filters()
-	context.attribute_filters = filter_engine.get_attribute_fitlers()
+	context.attribute_filters = filter_engine.get_attribute_filters()
 
 	context.product_settings = product_settings
 	context.body_class = "product-page"
diff --git a/package.json b/package.json
index 5bc1e56..6c11e9d 100644
--- a/package.json
+++ b/package.json
@@ -11,16 +11,9 @@
   "bugs": {
     "url": "https://github.com/frappe/erpnext/issues"
   },
-  "devDependencies": {
-    "snyk": "^1.518.0"
-  },
+  "devDependencies": {},
   "dependencies": {
-    "onscan.js": "^1.5.2",
-    "html2canvas": "^1.1.4"
-  },
-  "scripts": {
-    "snyk-protect": "snyk protect",
-    "prepare": "yarn run snyk-protect"
-  },
-  "snyk": true
+    "html2canvas": "^1.1.4",
+    "onscan.js": "^1.5.2"
+  }
 }
diff --git a/yarn.lock b/yarn.lock
index 0a49c52..8e5d1bd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,1006 +2,11 @@
 # yarn lockfile v1
 
 
-"@arcanis/slice-ansi@^1.0.2":
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/@arcanis/slice-ansi/-/slice-ansi-1.0.2.tgz#35331e41a1062e3c53c01ad2ec1555c5c1959d8f"
-  integrity sha512-lDL63z0W/L/WTgqrwVOuNyMAsTv+pvjybd21z9SWdStmQoXT59E/iVWwat3gYjcdTNBf6oHAMoyFm8dtjpXEYw==
-  dependencies:
-    grapheme-splitter "^1.0.4"
-
-"@deepcode/dcignore@^1.0.2":
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/@deepcode/dcignore/-/dcignore-1.0.2.tgz#39e4a3df7dde8811925330506e4bb3fbf3c288d8"
-  integrity sha512-DPgxtHuJwBORpqRkPXzzOT+uoPRVJmaN7LR+pmeL6DQM90kj6G6GFUH1i/YpRH8NbML8ZGEDwB9f9u4UwD2pzg==
-
-"@nodelib/fs.scandir@2.1.4":
-  version "2.1.4"
-  resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69"
-  integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==
-  dependencies:
-    "@nodelib/fs.stat" "2.0.4"
-    run-parallel "^1.1.9"
-
-"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2":
-  version "2.0.4"
-  resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655"
-  integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==
-
-"@nodelib/fs.walk@^1.2.3":
-  version "1.2.6"
-  resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063"
-  integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==
-  dependencies:
-    "@nodelib/fs.scandir" "2.1.4"
-    fastq "^1.6.0"
-
-"@octetstream/promisify@2.0.2":
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/@octetstream/promisify/-/promisify-2.0.2.tgz#29ac3bd7aefba646db670227f895d812c1a19615"
-  integrity sha512-7XHoRB61hxsz8lBQrjC1tq/3OEIgpvGWg6DKAdwi7WRzruwkmsdwmOoUXbU4Dtd4RSOMDwed0SkP3y8UlMt1Bg==
-
-"@open-policy-agent/opa-wasm@^1.2.0":
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/@open-policy-agent/opa-wasm/-/opa-wasm-1.2.0.tgz#481b766093f70b00efefbee1e4192f375fd34ca2"
-  integrity sha512-CtUBTnzvDrT0NASa8IuGQTxFGgt2vxbLnMYuTA+uDFxOcA4uK4mGFgrhHJtxUZnWHiwemOvKKSY3BMCo7qiAsQ==
-  dependencies:
-    sprintf-js "^1.1.2"
-    utf8 "^3.0.0"
-
-"@sindresorhus/is@^0.14.0":
-  version "0.14.0"
-  resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
-  integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
-
-"@sindresorhus/is@^2.1.1":
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-2.1.1.tgz#ceff6a28a5b4867c2dd4a1ba513de278ccbe8bb1"
-  integrity sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==
-
-"@sindresorhus/is@^4.0.0":
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.1.tgz#d26729db850fa327b7cacc5522252194404226f5"
-  integrity sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==
-
-"@snyk/cli-interface@2.11.0", "@snyk/cli-interface@^2.11.0", "@snyk/cli-interface@^2.9.1", "@snyk/cli-interface@^2.9.2":
-  version "2.11.0"
-  resolved "https://registry.yarnpkg.com/@snyk/cli-interface/-/cli-interface-2.11.0.tgz#9df68c8cd54de5dff69f0ab797a188541d9c8965"
-  integrity sha512-T3xfDqrEFKclHGdJx4/5+D5F7e76/99f33guE4RTlVITBhy7VVnjz4t/NDr3UYqcC0MgAmiC4bSVYHnlshuwJw==
-  dependencies:
-    "@types/graphlib" "^2"
-
-"@snyk/cli-interface@^2.0.3":
-  version "2.3.1"
-  resolved "https://registry.yarnpkg.com/@snyk/cli-interface/-/cli-interface-2.3.1.tgz#73f2f4bd717b9f03f096ede3ff5830eb8d2f3716"
-  integrity sha512-JZvsmhDXSyjv1dkc12lPI3tNTNYlIaOiIQMYFg2RgqF3QmWjTyBUgRZcF7LoKyufHtS4dIudM6k1aHBpSaDrhw==
-  dependencies:
-    tslib "^1.9.3"
-
-"@snyk/cloud-config-parser@^1.9.2":
-  version "1.9.2"
-  resolved "https://registry.yarnpkg.com/@snyk/cloud-config-parser/-/cloud-config-parser-1.9.2.tgz#e6c8e575db8527b33cf1ba766f86e1b3414cf6e1"
-  integrity sha512-m8Y2+3l4fxj96QMrTfiCEaXgCpDkCkJIX/5wv0V0RHuxpUiyh+KxC2yJ8Su4wybBj6v6hB9hB7h5/L+Gy4V4PA==
-  dependencies:
-    esprima "^4.0.1"
-    tslib "^1.10.0"
-    yaml-js "^0.3.0"
-
-"@snyk/cocoapods-lockfile-parser@3.6.2":
-  version "3.6.2"
-  resolved "https://registry.yarnpkg.com/@snyk/cocoapods-lockfile-parser/-/cocoapods-lockfile-parser-3.6.2.tgz#803ae9466f408c48ba7c5a8ec51b9dbac6f633b3"
-  integrity sha512-ca2JKOnSRzYHJkhOB9gYmdRZHmd02b/uBd/S0D5W+L9nIMS7sUBV5jfhKwVgrYPIpVNIc0XCI9rxK4TfkQRpiA==
-  dependencies:
-    "@snyk/dep-graph" "^1.23.1"
-    "@types/js-yaml" "^3.12.1"
-    js-yaml "^3.13.1"
-    tslib "^1.10.0"
-
-"@snyk/code-client@3.4.1":
-  version "3.4.1"
-  resolved "https://registry.yarnpkg.com/@snyk/code-client/-/code-client-3.4.1.tgz#b9d025897cd586e0aef903162ac0407d0bffc3cd"
-  integrity sha512-XJ7tUdX1iQyzN/BmHac7p+Oyw1SyTcqSkCNExwBJxyQdlnUAKK6QKIWLXS81tTpZ79FgCdT+0fdS0AjsyS99eA==
-  dependencies:
-    "@deepcode/dcignore" "^1.0.2"
-    "@snyk/fast-glob" "^3.2.6-patch"
-    "@types/flat-cache" "^2.0.0"
-    "@types/lodash.chunk" "^4.2.6"
-    "@types/lodash.omit" "^4.5.6"
-    "@types/lodash.union" "^4.6.6"
-    "@types/micromatch" "^4.0.1"
-    "@types/sarif" "^2.1.3"
-    "@types/uuid" "^8.3.0"
-    axios "^0.21.1"
-    ignore "^5.1.8"
-    lodash.chunk "^4.2.0"
-    lodash.omit "^4.5.0"
-    lodash.union "^4.6.0"
-    micromatch "^4.0.2"
-    queue "^6.0.1"
-    uuid "^8.3.2"
-
-"@snyk/composer-lockfile-parser@^1.4.1":
-  version "1.4.1"
-  resolved "https://registry.yarnpkg.com/@snyk/composer-lockfile-parser/-/composer-lockfile-parser-1.4.1.tgz#2f7c93ad367520322b16d9490a208fec08445e0e"
-  integrity sha512-wNANv235j95NFsQuODIXCiQZ9kcyg9fz92Kg1zoGvaP3kN/ma7fgCnvQL/dyml6iouQJR5aZovjhrrfEFoKtiQ==
-  dependencies:
-    lodash.findkey "^4.6.0"
-    lodash.get "^4.4.2"
-    lodash.invert "^4.3.0"
-    lodash.isempty "^4.4.0"
-
-"@snyk/dep-graph@^1.19.3", "@snyk/dep-graph@^1.21.0", "@snyk/dep-graph@^1.23.0", "@snyk/dep-graph@^1.23.1", "@snyk/dep-graph@^1.27.1", "@snyk/dep-graph@^1.28.0":
-  version "1.28.0"
-  resolved "https://registry.yarnpkg.com/@snyk/dep-graph/-/dep-graph-1.28.0.tgz#d68c0576cb3562c6e819ca8a8c7ac29ee11d9776"
-  integrity sha512-Oup9nAvb558jdNvbZah/vaBtOtCcizkdeS+OBQeBIqIffyer4mc4juSn4b1SFjCpu7AG7piio8Lj8k1B9ps6Tg==
-  dependencies:
-    event-loop-spinner "^2.1.0"
-    lodash.clone "^4.5.0"
-    lodash.constant "^3.0.0"
-    lodash.filter "^4.6.0"
-    lodash.foreach "^4.5.0"
-    lodash.isempty "^4.4.0"
-    lodash.isequal "^4.5.0"
-    lodash.isfunction "^3.0.9"
-    lodash.isundefined "^3.0.1"
-    lodash.keys "^4.2.0"
-    lodash.map "^4.6.0"
-    lodash.reduce "^4.6.0"
-    lodash.size "^4.2.0"
-    lodash.transform "^4.6.0"
-    lodash.union "^4.6.0"
-    lodash.values "^4.3.0"
-    object-hash "^2.0.3"
-    semver "^7.0.0"
-    tslib "^1.13.0"
-
-"@snyk/docker-registry-v2-client@1.13.9":
-  version "1.13.9"
-  resolved "https://registry.yarnpkg.com/@snyk/docker-registry-v2-client/-/docker-registry-v2-client-1.13.9.tgz#54c2e3071de58fc6fc12c5fef5eaeae174ecda12"
-  integrity sha512-DIFLEhr8m1GrAwsLGInJmpcQMacjuhf3jcbpQTR+LeMvZA9IuKq+B7kqw2O2FzMiHMZmUb5z+tV+BR7+IUHkFQ==
-  dependencies:
-    needle "^2.5.0"
-    parse-link-header "^1.0.1"
-    tslib "^1.10.0"
-
-"@snyk/fast-glob@^3.2.6-patch":
-  version "3.2.6-patch"
-  resolved "https://registry.yarnpkg.com/@snyk/fast-glob/-/fast-glob-3.2.6-patch.tgz#a0866bedb17f95255e4050dad08daeaff0f4caa8"
-  integrity sha512-E/Pfdze/WFfxwyuTFcfhQN1SwyUsc43yuCoW63RVBCaxTD6OzhVD2Pvc/Sy7BjiWUfmelzyKkIBpoow8zZX7Zg==
-  dependencies:
-    "@nodelib/fs.stat" "^2.0.2"
-    "@nodelib/fs.walk" "^1.2.3"
-    "@snyk/glob-parent" "^5.1.2-patch.1"
-    merge2 "^1.3.0"
-    micromatch "^4.0.2"
-    picomatch "^2.2.1"
-
-"@snyk/fix@1.554.0":
-  version "1.554.0"
-  resolved "https://registry.yarnpkg.com/@snyk/fix/-/fix-1.554.0.tgz#7ae786882e0ffea5e7f10d0b41e3d593b65555c4"
-  integrity sha512-q2eRVStgspPeI2wZ2EQGLpiWZMRg7o+4tsCk6m/kHZgQGDN4Bb7L3xslFW3OgF0+ZksYSaHl2cW2HmGiLRaYcA==
-  dependencies:
-    "@snyk/dep-graph" "^1.21.0"
-    chalk "4.1.0"
-    debug "^4.3.1"
-    ora "5.3.0"
-    p-map "^4.0.0"
-    strip-ansi "6.0.0"
-
-"@snyk/gemfile@1.2.0":
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/@snyk/gemfile/-/gemfile-1.2.0.tgz#919857944973cce74c650e5428aaf11bcd5c0457"
-  integrity sha512-nI7ELxukf7pT4/VraL4iabtNNMz8mUo7EXlqCFld8O5z6mIMLX9llps24iPpaIZOwArkY3FWA+4t+ixyvtTSIA==
-
-"@snyk/glob-parent@^5.1.2-patch.1":
-  version "5.1.2-patch.1"
-  resolved "https://registry.yarnpkg.com/@snyk/glob-parent/-/glob-parent-5.1.2-patch.1.tgz#87733b4ab282043fa7915200bc94cb391df6d44f"
-  integrity sha512-OkUPdHgxIWKAAzceG1nraNA0kgI+eS0I9wph8tll9UL0slD2mIWSj4mAqroGovaEXm8nHedoUfuDRGEb6wnzCQ==
-  dependencies:
-    is-glob "^4.0.1"
-
-"@snyk/graphlib@2.1.9-patch.3", "@snyk/graphlib@^2.1.9-patch.3":
-  version "2.1.9-patch.3"
-  resolved "https://registry.yarnpkg.com/@snyk/graphlib/-/graphlib-2.1.9-patch.3.tgz#b8edb2335af1978db7f3cb1f28f5d562960acf23"
-  integrity sha512-bBY9b9ulfLj0v2Eer0yFYa3syVeIxVKl2EpxSrsVeT4mjA0CltZyHsF0JjoaGXP27nItTdJS5uVsj1NA+3aE+Q==
-  dependencies:
-    lodash.clone "^4.5.0"
-    lodash.constant "^3.0.0"
-    lodash.filter "^4.6.0"
-    lodash.foreach "^4.5.0"
-    lodash.has "^4.5.2"
-    lodash.isempty "^4.4.0"
-    lodash.isfunction "^3.0.9"
-    lodash.isundefined "^3.0.1"
-    lodash.keys "^4.2.0"
-    lodash.map "^4.6.0"
-    lodash.reduce "^4.6.0"
-    lodash.size "^4.2.0"
-    lodash.transform "^4.6.0"
-    lodash.union "^4.6.0"
-    lodash.values "^4.3.0"
-
-"@snyk/inquirer@^7.3.3-patch":
-  version "7.3.3-patch"
-  resolved "https://registry.yarnpkg.com/@snyk/inquirer/-/inquirer-7.3.3-patch.tgz#ef84d531724c53b755e8dd454e1a3c2ccdcfc0bf"
-  integrity sha512-aWiQSOacH2lOpJ1ard9ErABcH4tdJogdr+mg1U67iZJOPO9n2gFgAwz1TQJDyPkv4/A5mh4hT2rg03Uq+KBn2Q==
-  dependencies:
-    ansi-escapes "^4.2.1"
-    chalk "^4.1.0"
-    cli-cursor "^3.1.0"
-    cli-width "^3.0.0"
-    external-editor "^3.0.3"
-    figures "^3.0.0"
-    lodash.assign "^4.2.0"
-    lodash.assignin "^4.2.0"
-    lodash.clone "^4.5.0"
-    lodash.defaults "^4.2.0"
-    lodash.filter "^4.6.0"
-    lodash.find "^4.6.0"
-    lodash.findindex "^4.6.0"
-    lodash.flatten "^4.4.0"
-    lodash.isboolean "^3.0.3"
-    lodash.isfunction "^3.0.9"
-    lodash.isnumber "^3.0.3"
-    lodash.isplainobject "^4.0.6"
-    lodash.isstring "^4.0.1"
-    lodash.last "^3.0.0"
-    lodash.map "^4.6.0"
-    lodash.omit "^4.5.0"
-    lodash.set "^4.3.2"
-    lodash.sum "^4.0.2"
-    lodash.uniq "^4.5.0"
-    mute-stream "0.0.8"
-    run-async "^2.4.0"
-    rxjs "^6.6.0"
-    string-width "^4.1.0"
-    strip-ansi "^6.0.0"
-    through "^2.3.6"
-
-"@snyk/java-call-graph-builder@1.19.1":
-  version "1.19.1"
-  resolved "https://registry.yarnpkg.com/@snyk/java-call-graph-builder/-/java-call-graph-builder-1.19.1.tgz#1d579d782df3bb5f9d5171cc35180596cd90aa8b"
-  integrity sha512-bxjHef5Qm3pNc+BrFlxMudmSSbOjA395ZqBddc+dvsFHoHeyNbiY56Y1JSGUlTgjRM+PKNPBiCuELTSMaROeZg==
-  dependencies:
-    "@snyk/graphlib" "2.1.9-patch.3"
-    ci-info "^2.0.0"
-    debug "^4.1.1"
-    glob "^7.1.6"
-    jszip "^3.2.2"
-    needle "^2.3.3"
-    progress "^2.0.3"
-    snyk-config "^4.0.0-rc.2"
-    source-map-support "^0.5.7"
-    temp-dir "^2.0.0"
-    tmp "^0.2.1"
-    tslib "^1.9.3"
-    xml-js "^1.6.11"
-
-"@snyk/java-call-graph-builder@1.20.0":
-  version "1.20.0"
-  resolved "https://registry.yarnpkg.com/@snyk/java-call-graph-builder/-/java-call-graph-builder-1.20.0.tgz#ffca734cf7ce276a69277963149358190eaac3e5"
-  integrity sha512-NX8bpIu7oG5cuSSm6WvtxqcCuJs2gRjtKhtuSeF1p5TYXyESs3FXQ0nHjfY90LiyTTc+PW/UBq6SKbBA6bCBww==
-  dependencies:
-    "@snyk/graphlib" "2.1.9-patch.3"
-    ci-info "^2.0.0"
-    debug "^4.1.1"
-    glob "^7.1.6"
-    jszip "^3.2.2"
-    needle "^2.3.3"
-    progress "^2.0.3"
-    snyk-config "^4.0.0-rc.2"
-    source-map-support "^0.5.7"
-    temp-dir "^2.0.0"
-    tmp "^0.2.1"
-    tslib "^1.9.3"
-    xml-js "^1.6.11"
-
-"@snyk/mix-parser@^1.1.1":
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/@snyk/mix-parser/-/mix-parser-1.3.2.tgz#930de1d9c3a91e20660751f78c3e6f6a88ac5b2b"
-  integrity sha512-0Aq9vcgmjH0d9Gk5q0k6l4ZOvSHPf6/BCQGDVOpKp0hwOkXWnpDOLLPxL+uBCktuH9zTYQFB0aTk91kQImZqmA==
-  dependencies:
-    "@snyk/dep-graph" "^1.28.0"
-    tslib "^2.0.0"
-
-"@snyk/rpm-parser@^2.0.0":
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/@snyk/rpm-parser/-/rpm-parser-2.2.1.tgz#b61ccf5478684b203576bd2be68de434ccbb0069"
-  integrity sha512-OAON0bPf3c5fgM/GK9DX0aZErB6SnuRyYlPH0rqI1TXGsKrYnVELhaE6ctNbEfPTQuY9r6q0vM+UYDaFM/YliA==
-  dependencies:
-    event-loop-spinner "^2.0.0"
-
-"@snyk/snyk-cocoapods-plugin@2.5.2":
-  version "2.5.2"
-  resolved "https://registry.yarnpkg.com/@snyk/snyk-cocoapods-plugin/-/snyk-cocoapods-plugin-2.5.2.tgz#cd724fcd637cb3af76187bf7254819b6079489f6"
-  integrity sha512-WHhnwyoGOhjFOjBXqUfszD84SErrtjHjium/4xFbqKpEE+yuwxs8OwV/S29BtxhYiGtjpD1azv5QtH30VUMl0A==
-  dependencies:
-    "@snyk/cli-interface" "^2.11.0"
-    "@snyk/cocoapods-lockfile-parser" "3.6.2"
-    "@snyk/dep-graph" "^1.23.1"
-    source-map-support "^0.5.7"
-    tslib "^2.0.0"
-
-"@snyk/snyk-docker-pull@3.2.3":
-  version "3.2.3"
-  resolved "https://registry.yarnpkg.com/@snyk/snyk-docker-pull/-/snyk-docker-pull-3.2.3.tgz#9743ea624098c7abd0f95c438c76067530494f4b"
-  integrity sha512-hiFiSmWGLc2tOI7FfgIhVdFzO2f69im8O6p3OV4xEZ/Ss1l58vwtqudItoswsk7wj/azRlgfBW8wGu2MjoudQg==
-  dependencies:
-    "@snyk/docker-registry-v2-client" "1.13.9"
-    child-process "^1.0.2"
-    tar-stream "^2.1.2"
-    tmp "^0.1.0"
-
-"@snyk/snyk-hex-plugin@1.1.4":
-  version "1.1.4"
-  resolved "https://registry.yarnpkg.com/@snyk/snyk-hex-plugin/-/snyk-hex-plugin-1.1.4.tgz#4a5b1684cecc1a557ec1a9f5f8646683ae89f0da"
-  integrity sha512-kLfFGckSmyKe667UGPyWzR/H7/Trkt4fD8O/ktElOx1zWgmivpLm0Symb4RCfEmz9irWv+N6zIKRrfSNdytcPQ==
-  dependencies:
-    "@snyk/dep-graph" "^1.28.0"
-    "@snyk/mix-parser" "^1.1.1"
-    debug "^4.3.1"
-    tmp "^0.0.33"
-    tslib "^2.0.0"
-    upath "2.0.1"
-
-"@szmarczak/http-timer@^1.1.2":
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
-  integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
-  dependencies:
-    defer-to-connect "^1.0.1"
-
-"@szmarczak/http-timer@^4.0.5":
-  version "4.0.5"
-  resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152"
-  integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==
-  dependencies:
-    defer-to-connect "^2.0.0"
-
-"@types/braces@*":
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/@types/braces/-/braces-3.0.0.tgz#7da1c0d44ff1c7eb660a36ec078ea61ba7eb42cb"
-  integrity sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw==
-
-"@types/cacheable-request@^6.0.1":
-  version "6.0.1"
-  resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976"
-  integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==
-  dependencies:
-    "@types/http-cache-semantics" "*"
-    "@types/keyv" "*"
-    "@types/node" "*"
-    "@types/responselike" "*"
-
-"@types/debug@^4.1.4":
-  version "4.1.5"
-  resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd"
-  integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==
-
-"@types/emscripten@^1.38.0":
-  version "1.39.4"
-  resolved "https://registry.yarnpkg.com/@types/emscripten/-/emscripten-1.39.4.tgz#d61990c0cee72c4e475de737a140b51fe925a2c8"
-  integrity sha512-k3LLVMFrdNA9UCvMDPWMbFrGPNb+GcPyw29ktJTo1RCN7RmxFG5XzPZcPKRlnLuLT/FRm8wp4ohvDwNY7GlROQ==
-
-"@types/flat-cache@^2.0.0":
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/@types/flat-cache/-/flat-cache-2.0.0.tgz#64e5d3b426c392b603a208a55bdcc7d920ce6e57"
-  integrity sha512-fHeEsm9hvmZ+QHpw6Fkvf19KIhuqnYLU6vtWLjd5BsMd/qVi7iTkMioDZl0mQmfNRA1A6NwvhrSRNr9hGYZGww==
-
-"@types/graphlib@^2":
-  version "2.1.7"
-  resolved "https://registry.yarnpkg.com/@types/graphlib/-/graphlib-2.1.7.tgz#e6a47a4f43511f5bad30058a669ce5ce93bfd823"
-  integrity sha512-K7T1n6U2HbTYu+SFHlBjz/RH74OA2D/zF1qlzn8uXbvB4uRg7knOM85ugS2bbXI1TXMh7rLqk4OVRwIwEBaixg==
-
-"@types/http-cache-semantics@*":
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a"
-  integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==
-
-"@types/js-yaml@^3.12.1":
-  version "3.12.2"
-  resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.2.tgz#a35a1809c33a68200fb6403d1ad708363c56470a"
-  integrity sha512-0CFu/g4mDSNkodVwWijdlr8jH7RoplRWNgovjFLEZeT+QEbbZXjBmCe3HwaWheAlCbHwomTwzZoSedeOycABug==
-
-"@types/keyv@*":
-  version "3.1.1"
-  resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7"
-  integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==
-  dependencies:
-    "@types/node" "*"
-
-"@types/lodash.chunk@^4.2.6":
-  version "4.2.6"
-  resolved "https://registry.yarnpkg.com/@types/lodash.chunk/-/lodash.chunk-4.2.6.tgz#9d35f05360b0298715d7f3d9efb34dd4f77e5d2a"
-  integrity sha512-SPlusB7jxXyGcTXYcUdWr7WmhArO/rmTq54VN88iKMxGUhyg79I4Q8n4riGn3kjaTjOJrVlHhxgX/d7woak5BQ==
-  dependencies:
-    "@types/lodash" "*"
-
-"@types/lodash.omit@^4.5.6":
-  version "4.5.6"
-  resolved "https://registry.yarnpkg.com/@types/lodash.omit/-/lodash.omit-4.5.6.tgz#f2a9518259e481a48ff7ec423420fa8fd58933e2"
-  integrity sha512-KXPpOSNX2h0DAG2w7ajpk7TXvWF28ZHs5nJhOJyP0BQHkehgr948RVsToItMme6oi0XJkp19CbuNXkIX8FiBlQ==
-  dependencies:
-    "@types/lodash" "*"
-
-"@types/lodash.union@^4.6.6":
-  version "4.6.6"
-  resolved "https://registry.yarnpkg.com/@types/lodash.union/-/lodash.union-4.6.6.tgz#2f77f2088326ed147819e9e384182b99aae8d4b0"
-  integrity sha512-Wu0ZEVNcyCz8eAn6TlUbYWZoGbH9E+iOHxAZbwUoCEXdUiy6qpcz5o44mMXViM4vlPLLCPlkAubEP1gokoSZaw==
-  dependencies:
-    "@types/lodash" "*"
-
-"@types/lodash@*":
-  version "4.14.168"
-  resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008"
-  integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==
-
-"@types/micromatch@^4.0.1":
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.1.tgz#9381449dd659fc3823fd2a4190ceacc985083bc7"
-  integrity sha512-my6fLBvpY70KattTNzYOK6KU1oR1+UCz9ug/JbcF5UrEmeCt9P7DV2t7L8+t18mMPINqGQCE4O8PLOPbI84gxw==
-  dependencies:
-    "@types/braces" "*"
-
-"@types/node@*":
-  version "13.5.3"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-13.5.3.tgz#37f1f539b7535b9fb4ef77d59db1847a837b7f17"
-  integrity sha512-ZPnWX9PW992w6DUsz3JIXHaSb5v7qmKCVzC3km6SxcDGxk7zmLfYaCJTbktIa5NeywJkkZDhGldKqDIvC5DRrA==
-
-"@types/node@^13.7.0":
-  version "13.13.50"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.50.tgz#bc8ebf70c392a98ffdba7aab9b46989ea96c1c62"
-  integrity sha512-y7kkh+hX/0jZNxMyBR/6asG0QMSaPSzgeVK63dhWHl4QAXCQB8lExXmzLL6SzmOgKHydtawpMnNhlDbv7DXPEA==
-
-"@types/responselike@*", "@types/responselike@^1.0.0":
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29"
-  integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==
-  dependencies:
-    "@types/node" "*"
-
-"@types/sarif@^2.1.3":
-  version "2.1.3"
-  resolved "https://registry.yarnpkg.com/@types/sarif/-/sarif-2.1.3.tgz#1f9c16033f1461536ac014284920350109614c02"
-  integrity sha512-zf+EoIplTkQW2TV2mwtJtlI0g540Z3Rs9tX9JqRAtyjnDCqkP+eMTgWCj3PGNbQpi+WXAjvC3Ou/dvvX2sLK4w==
-
-"@types/semver@^7.1.0":
-  version "7.3.4"
-  resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.4.tgz#43d7168fec6fa0988bb1a513a697b29296721afb"
-  integrity sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ==
-
-"@types/treeify@^1.0.0":
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/@types/treeify/-/treeify-1.0.0.tgz#f04743cb91fc38254e8585d692bd92503782011c"
-  integrity sha512-ONpcZAEYlbPx4EtJwfTyCDQJGUpKf4sEcuySdCVjK5Fj/3vHp5HII1fqa1/+qrsLnpYELCQTfVW/awsGJePoIg==
-
-"@types/uuid@^8.3.0":
-  version "8.3.0"
-  resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.0.tgz#215c231dff736d5ba92410e6d602050cce7e273f"
-  integrity sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==
-
-"@yarnpkg/core@^2.4.0":
-  version "2.4.0"
-  resolved "https://registry.yarnpkg.com/@yarnpkg/core/-/core-2.4.0.tgz#b5d8cc7ee2ddb022816c7afa3f83c3ee3d317c80"
-  integrity sha512-FYjcPNTfDfMKLFafQPt49EY28jnYC82Z2S7oMwLPUh144BL8v8YXzb4aCnFyi5nFC5h2kcrJfZh7+Pm/qvCqGw==
-  dependencies:
-    "@arcanis/slice-ansi" "^1.0.2"
-    "@types/semver" "^7.1.0"
-    "@types/treeify" "^1.0.0"
-    "@yarnpkg/fslib" "^2.4.0"
-    "@yarnpkg/json-proxy" "^2.1.0"
-    "@yarnpkg/libzip" "^2.2.1"
-    "@yarnpkg/parsers" "^2.3.0"
-    "@yarnpkg/pnp" "^2.3.2"
-    "@yarnpkg/shell" "^2.4.1"
-    binjumper "^0.1.4"
-    camelcase "^5.3.1"
-    chalk "^3.0.0"
-    ci-info "^2.0.0"
-    clipanion "^2.6.2"
-    cross-spawn "7.0.3"
-    diff "^4.0.1"
-    globby "^11.0.1"
-    got "^11.7.0"
-    json-file-plus "^3.3.1"
-    lodash "^4.17.15"
-    micromatch "^4.0.2"
-    mkdirp "^0.5.1"
-    p-limit "^2.2.0"
-    pluralize "^7.0.0"
-    pretty-bytes "^5.1.0"
-    semver "^7.1.2"
-    stream-to-promise "^2.2.0"
-    tar-stream "^2.0.1"
-    treeify "^1.1.0"
-    tslib "^1.13.0"
-    tunnel "^0.0.6"
-
-"@yarnpkg/fslib@^2.1.0", "@yarnpkg/fslib@^2.4.0":
-  version "2.4.0"
-  resolved "https://registry.yarnpkg.com/@yarnpkg/fslib/-/fslib-2.4.0.tgz#a265b737cd089ef293ad964e06c143f5efd411a9"
-  integrity sha512-CwffYY9owtl3uImNOn1K4jl5iIb/L16a9UZ9Q3lkBARk6tlUsPrNFX00eoUlFcLn49TTfd3zdN6higloGCyncw==
-  dependencies:
-    "@yarnpkg/libzip" "^2.2.1"
-    tslib "^1.13.0"
-
-"@yarnpkg/json-proxy@^2.1.0":
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/@yarnpkg/json-proxy/-/json-proxy-2.1.0.tgz#362a161678cd7dda74b47b4fc848a2f1730d16cd"
-  integrity sha512-rOgCg2DkyviLgr80mUMTt9vzdf5RGOujQB26yPiXjlz4WNePLBshKlTNG9rKSoKQSOYEQcw6cUmosfOKDatrCw==
-  dependencies:
-    "@yarnpkg/fslib" "^2.1.0"
-    tslib "^1.13.0"
-
-"@yarnpkg/libzip@^2.2.1":
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/@yarnpkg/libzip/-/libzip-2.2.1.tgz#61c9b8b2499ee6bd9c4fcbf8248f68e07bd89948"
-  integrity sha512-AYDJXrkzayoDd3ZlVgFJ+LyDX+Zj/cki3vxIpcYxejtgkl3aquVWOxlC0DD9WboBWsJFIP1MjrUbchLyh++/7A==
-  dependencies:
-    "@types/emscripten" "^1.38.0"
-    tslib "^1.13.0"
-
-"@yarnpkg/lockfile@^1.1.0":
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
-  integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
-
-"@yarnpkg/parsers@^2.3.0":
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-2.3.0.tgz#7b9564c6df02f4921d5cfe8287c4b648e93ea84b"
-  integrity sha512-qgz0QUgOvnhtF92kaluIhIIKBUHlYlHUBQxqh5v9+sxEQvUeF6G6PKiFlzo3E6O99XwvNEGpVu1xZPoSGyGscQ==
-  dependencies:
-    js-yaml "^3.10.0"
-    tslib "^1.13.0"
-
-"@yarnpkg/pnp@^2.3.2":
-  version "2.3.2"
-  resolved "https://registry.yarnpkg.com/@yarnpkg/pnp/-/pnp-2.3.2.tgz#9a052a06bf09c9f0b7c31e0867a7e725cb6401ed"
-  integrity sha512-JdwHu1WBCISqJEhIwx6Hbpe8MYsYbkGMxoxolkDiAeJ9IGEe08mQcbX1YmUDV1ozSWlm9JZE90nMylcDsXRFpA==
-  dependencies:
-    "@types/node" "^13.7.0"
-    "@yarnpkg/fslib" "^2.4.0"
-    tslib "^1.13.0"
-
-"@yarnpkg/shell@^2.4.1":
-  version "2.4.1"
-  resolved "https://registry.yarnpkg.com/@yarnpkg/shell/-/shell-2.4.1.tgz#abc557f8924987c9c382703e897433a82780265d"
-  integrity sha512-oNNJkH8ZI5uwu0dMkJf737yMSY1WXn9gp55DqSA5wAOhKvV5DJTXFETxkVgBQhO6Bow9tMGSpvowTMD/oAW/9g==
-  dependencies:
-    "@yarnpkg/fslib" "^2.4.0"
-    "@yarnpkg/parsers" "^2.3.0"
-    clipanion "^2.6.2"
-    cross-spawn "7.0.3"
-    fast-glob "^3.2.2"
-    micromatch "^4.0.2"
-    stream-buffers "^3.0.2"
-    tslib "^1.13.0"
-
-abbrev@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
-  integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
-
-aggregate-error@^3.0.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
-  integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==
-  dependencies:
-    clean-stack "^2.0.0"
-    indent-string "^4.0.0"
-
-ansi-align@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb"
-  integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==
-  dependencies:
-    string-width "^3.0.0"
-
-ansi-escapes@3.2.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b"
-  integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==
-
-ansi-escapes@^4.2.1:
-  version "4.3.2"
-  resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
-  integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==
-  dependencies:
-    type-fest "^0.21.3"
-
-ansi-regex@^4.1.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
-  integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
-
-ansi-regex@^5.0.0:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
-  integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
-
-ansi-styles@^3.2.0, ansi-styles@^3.2.1:
-  version "3.2.1"
-  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
-  integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
-  dependencies:
-    color-convert "^1.9.0"
-
-ansi-styles@^4.1.0:
-  version "4.3.0"
-  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
-  integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
-  dependencies:
-    color-convert "^2.0.1"
-
-ansicolors@^0.3.2:
-  version "0.3.2"
-  resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979"
-  integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=
-
-any-promise@^1.1.0, any-promise@~1.3.0:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
-  integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
-
-archy@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40"
-  integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=
-
-argparse@^1.0.7:
-  version "1.0.10"
-  resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
-  integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
-  dependencies:
-    sprintf-js "~1.0.2"
-
-array-union@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
-  integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
-
-asap@~2.0.3:
-  version "2.0.6"
-  resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
-  integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
-
-asn1@~0.2.0:
-  version "0.2.4"
-  resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
-  integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
-  dependencies:
-    safer-buffer "~2.1.0"
-
-async@^3.2.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720"
-  integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==
-
-axios@^0.21.1:
-  version "0.21.1"
-  resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
-  integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
-  dependencies:
-    follow-redirects "^1.10.0"
-
-balanced-match@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
-  integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
-
 base64-arraybuffer@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz#4b944fac0191aa5907afe2d8c999ccc57ce80f45"
   integrity sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==
 
-base64-js@^1.3.1:
-  version "1.5.1"
-  resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
-  integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
-
-bcrypt-pbkdf@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
-  integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
-  dependencies:
-    tweetnacl "^0.14.3"
-
-binjumper@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/binjumper/-/binjumper-0.1.4.tgz#4acc0566832714bd6508af6d666bd9e5e21fc7f8"
-  integrity sha512-Gdxhj+U295tIM6cO4bJO1jsvSjBVHNpj2o/OwW7pqDEtaqF6KdOxjtbo93jMMKAkP7+u09+bV8DhSqjIv4qR3w==
-
-bl@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/bl/-/bl-3.0.1.tgz#1cbb439299609e419b5a74d7fce2f8b37d8e5c6f"
-  integrity sha512-jrCW5ZhfQ/Vt07WX1Ngs+yn9BDqPL/gw28S7s9H6QK/gupnizNzJAss5akW20ISgOrbLTlXOOCTJeNUQqruAWQ==
-  dependencies:
-    readable-stream "^3.0.1"
-
-bl@^4.0.3:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
-  integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
-  dependencies:
-    buffer "^5.5.0"
-    inherits "^2.0.4"
-    readable-stream "^3.4.0"
-
-boolean@^3.0.1:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.0.3.tgz#0fee0c9813b66bef25a8a6a904bb46736d05f024"
-  integrity sha512-EqrTKXQX6Z3A2nRmMEIlAIfjQOgFnVO2nqZGpbcsPnYGWBwpFqzlrozU1dy+S2iqfYDLh26ef4KrgTxu9xQrxA==
-
-boxen@^4.2.0:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64"
-  integrity sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==
-  dependencies:
-    ansi-align "^3.0.0"
-    camelcase "^5.3.1"
-    chalk "^3.0.0"
-    cli-boxes "^2.2.0"
-    string-width "^4.1.0"
-    term-size "^2.1.0"
-    type-fest "^0.8.1"
-    widest-line "^3.1.0"
-
-brace-expansion@^1.1.7:
-  version "1.1.11"
-  resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
-  integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
-  dependencies:
-    balanced-match "^1.0.0"
-    concat-map "0.0.1"
-
-braces@^3.0.1:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
-  integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
-  dependencies:
-    fill-range "^7.0.1"
-
-browserify-zlib@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d"
-  integrity sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=
-  dependencies:
-    pako "~0.2.0"
-
-buffer-from@^1.0.0:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
-  integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
-
-buffer@^5.5.0:
-  version "5.7.1"
-  resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
-  integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
-  dependencies:
-    base64-js "^1.3.1"
-    ieee754 "^1.1.13"
-
-cacheable-lookup@^5.0.3:
-  version "5.0.4"
-  resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005"
-  integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==
-
-cacheable-request@^6.0.0:
-  version "6.1.0"
-  resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
-  integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==
-  dependencies:
-    clone-response "^1.0.2"
-    get-stream "^5.1.0"
-    http-cache-semantics "^4.0.0"
-    keyv "^3.0.0"
-    lowercase-keys "^2.0.0"
-    normalize-url "^4.1.0"
-    responselike "^1.0.2"
-
-cacheable-request@^7.0.1:
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58"
-  integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==
-  dependencies:
-    clone-response "^1.0.2"
-    get-stream "^5.1.0"
-    http-cache-semantics "^4.0.0"
-    keyv "^4.0.0"
-    lowercase-keys "^2.0.0"
-    normalize-url "^4.1.0"
-    responselike "^2.0.0"
-
-call-bind@^1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
-  integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
-  dependencies:
-    function-bind "^1.1.1"
-    get-intrinsic "^1.0.2"
-
-camelcase@^5.3.1:
-  version "5.3.1"
-  resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
-  integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
-
-chalk@4.1.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a"
-  integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==
-  dependencies:
-    ansi-styles "^4.1.0"
-    supports-color "^7.1.0"
-
-chalk@^2.4.2:
-  version "2.4.2"
-  resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
-  integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
-  dependencies:
-    ansi-styles "^3.2.1"
-    escape-string-regexp "^1.0.5"
-    supports-color "^5.3.0"
-
-chalk@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
-  integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
-  dependencies:
-    ansi-styles "^4.1.0"
-    supports-color "^7.1.0"
-
-chalk@^4.1.0:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad"
-  integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==
-  dependencies:
-    ansi-styles "^4.1.0"
-    supports-color "^7.1.0"
-
-chardet@^0.7.0:
-  version "0.7.0"
-  resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
-  integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
-
-child-process@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/child-process/-/child-process-1.0.2.tgz#98974dc7ed1ee4c6229f8e305fa7313a6885a7f2"
-  integrity sha1-mJdNx+0e5MYin44wX6cxOmiFp/I=
-
-chownr@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
-  integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
-
-ci-info@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
-  integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
-
-clean-stack@^2.0.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
-  integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==
-
-cli-boxes@^2.2.0:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f"
-  integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==
-
-cli-cursor@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
-  integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==
-  dependencies:
-    restore-cursor "^3.1.0"
-
-cli-spinner@0.2.10:
-  version "0.2.10"
-  resolved "https://registry.yarnpkg.com/cli-spinner/-/cli-spinner-0.2.10.tgz#f7d617a36f5c47a7bc6353c697fc9338ff782a47"
-  integrity sha512-U0sSQ+JJvSLi1pAYuJykwiA8Dsr15uHEy85iCJ6A+0DjVxivr3d+N2Wjvodeg89uP5K6TswFkKBfAD7B3YSn/Q==
-
-cli-spinners@^2.5.0:
-  version "2.6.0"
-  resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939"
-  integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==
-
-cli-width@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6"
-  integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
-
-clipanion@^2.6.2:
-  version "2.6.2"
-  resolved "https://registry.yarnpkg.com/clipanion/-/clipanion-2.6.2.tgz#820e7440812052442455b248f927b187ed732f71"
-  integrity sha512-0tOHJNMF9+4R3qcbBL+4IxLErpaYSYvzs10aXuECDbZdJOuJHdagJMAqvLdeaUQTI/o2uSCDRpet6ywDiKOAYw==
-
-clone-response@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
-  integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
-  dependencies:
-    mimic-response "^1.0.0"
-
-clone@^1.0.2:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
-  integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
-
-color-convert@^1.9.0:
-  version "1.9.3"
-  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
-  integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
-  dependencies:
-    color-name "1.1.3"
-
-color-convert@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
-  integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
-  dependencies:
-    color-name "~1.1.4"
-
-color-name@1.1.3:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
-  integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
-
-color-name@~1.1.4:
-  version "1.1.4"
-  resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
-  integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
-
-concat-map@0.0.1:
-  version "0.0.1"
-  resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
-  integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
-
-configstore@^5.0.1:
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96"
-  integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==
-  dependencies:
-    dot-prop "^5.2.0"
-    graceful-fs "^4.1.2"
-    make-dir "^3.0.0"
-    unique-string "^2.0.0"
-    write-file-atomic "^3.0.0"
-    xdg-basedir "^4.0.0"
-
-core-js@^3.6.5:
-  version "3.11.0"
-  resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.11.0.tgz#05dac6aa70c0a4ad842261f8957b961d36eb8926"
-  integrity sha512-bd79DPpx+1Ilh9+30aT5O1sgpQd4Ttg8oqkqi51ZzhedMM1omD2e6IOF48Z/DzDCZ2svp49tN/3vneTK6ZBkXw==
-
-core-util-is@~1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
-  integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
-
-cross-spawn@7.0.3:
-  version "7.0.3"
-  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
-  integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
-  dependencies:
-    path-key "^3.1.0"
-    shebang-command "^2.0.0"
-    which "^2.0.1"
-
-cross-spawn@^6.0.0:
-  version "6.0.5"
-  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
-  integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
-  dependencies:
-    nice-try "^1.0.4"
-    path-key "^2.0.1"
-    semver "^5.5.0"
-    shebang-command "^1.2.0"
-    which "^1.2.9"
-
-crypto-random-string@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"
-  integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==
-
 css-line-break@1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/css-line-break/-/css-line-break-1.1.1.tgz#d5e9bdd297840099eb0503c7310fd34927a026ef"
@@ -1009,481 +14,6 @@
   dependencies:
     base64-arraybuffer "^0.2.0"
 
-debug@^3.1.0, debug@^3.2.6:
-  version "3.2.6"
-  resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
-  integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
-  dependencies:
-    ms "^2.1.1"
-
-debug@^4.1.1:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
-  integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
-  dependencies:
-    ms "^2.1.1"
-
-debug@^4.2.0, debug@^4.3.1:
-  version "4.3.1"
-  resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
-  integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
-  dependencies:
-    ms "2.1.2"
-
-decompress-response@^3.3.0:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
-  integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
-  dependencies:
-    mimic-response "^1.0.0"
-
-decompress-response@^6.0.0:
-  version "6.0.0"
-  resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
-  integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==
-  dependencies:
-    mimic-response "^3.1.0"
-
-deep-extend@^0.6.0:
-  version "0.6.0"
-  resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
-  integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
-
-defaults@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
-  integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=
-  dependencies:
-    clone "^1.0.2"
-
-defer-to-connect@^1.0.1:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591"
-  integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==
-
-defer-to-connect@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587"
-  integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==
-
-define-properties@^1.1.3:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
-  integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
-  dependencies:
-    object-keys "^1.0.12"
-
-detect-node@^2.0.4:
-  version "2.0.5"
-  resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.5.tgz#9d270aa7eaa5af0b72c4c9d9b814e7f4ce738b79"
-  integrity sha512-qi86tE6hRcFHy8jI1m2VG+LaPUR1LhqDa5G8tVjuUXmOrpuAgqsA1pN0+ldgr3aKUH+QLI9hCY/OcRYisERejw==
-
-diff@^4.0.1:
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
-  integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
-
-dir-glob@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
-  integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
-  dependencies:
-    path-type "^4.0.0"
-
-docker-modem@2.1.3:
-  version "2.1.3"
-  resolved "https://registry.yarnpkg.com/docker-modem/-/docker-modem-2.1.3.tgz#15432225f63db02eb5de4bb9a621b7293e5f264d"
-  integrity sha512-cwaRptBmYZwu/FyhGcqBm2MzXA77W2/E6eVkpOZVDk6PkI9Bjj84xPrXiHMA+OWjzNy+DFjgKh8Q+1hMR7/OHg==
-  dependencies:
-    debug "^4.1.1"
-    readable-stream "^3.5.0"
-    split-ca "^1.0.1"
-    ssh2 "^0.8.7"
-
-dockerfile-ast@0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/dockerfile-ast/-/dockerfile-ast-0.2.0.tgz#13cc4a6fe3aea30a4104622b30f49a0fe3a5c038"
-  integrity sha512-iQyp12k1A4tF3sEfLAq2wfFPKdpoiGTJeuiu2Y1bdEqIZu0DfSSL2zm0fk7a/UHeQkngnYaRRGuON+C+2LO1Fw==
-  dependencies:
-    vscode-languageserver-types "^3.16.0"
-
-dot-prop@^5.2.0:
-  version "5.2.0"
-  resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb"
-  integrity sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==
-  dependencies:
-    is-obj "^2.0.0"
-
-dotnet-deps-parser@5.0.0:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/dotnet-deps-parser/-/dotnet-deps-parser-5.0.0.tgz#5115c442cbefea59e4fb9f9ed8fa4863a0f3186d"
-  integrity sha512-1l9K4UnQQHSfKgeHeLrxnB53AidCZqPyf9dkRL4/fZl8//NPiiDD43zHtgylw8DHlO7gvM8+O5a0UPHesNYZKw==
-  dependencies:
-    lodash.isempty "^4.4.0"
-    lodash.set "^4.3.2"
-    lodash.uniq "^4.5.0"
-    source-map-support "^0.5.7"
-    tslib "^1.10.0"
-    xml2js "0.4.23"
-
-duplexer3@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
-  integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
-
-duplexify@^3.5.0, duplexify@^3.6.0:
-  version "3.7.1"
-  resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309"
-  integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==
-  dependencies:
-    end-of-stream "^1.0.0"
-    inherits "^2.0.1"
-    readable-stream "^2.0.0"
-    stream-shift "^1.0.0"
-
-elfy@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/elfy/-/elfy-1.0.0.tgz#7a1c86af7d41e0a568cbb4a3fa5b685648d9efcd"
-  integrity sha512-4Kp3AA94jC085IJox+qnvrZ3PudqTi4gQNvIoTZfJJ9IqkRuCoqP60vCVYlIg00c5aYusi5Wjh2bf0cHYt+6gQ==
-  dependencies:
-    endian-reader "^0.3.0"
-
-email-validator@^2.0.4:
-  version "2.0.4"
-  resolved "https://registry.yarnpkg.com/email-validator/-/email-validator-2.0.4.tgz#b8dfaa5d0dae28f1b03c95881d904d4e40bfe7ed"
-  integrity sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ==
-
-emoji-regex@^7.0.1:
-  version "7.0.3"
-  resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
-  integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
-
-emoji-regex@^8.0.0:
-  version "8.0.0"
-  resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
-  integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
-
-end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1:
-  version "1.4.4"
-  resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
-  integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
-  dependencies:
-    once "^1.4.0"
-
-end-of-stream@~1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.1.0.tgz#e9353258baa9108965efc41cb0ef8ade2f3cfb07"
-  integrity sha1-6TUyWLqpEIll78QcsO+K3i88+wc=
-  dependencies:
-    once "~1.3.0"
-
-endian-reader@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/endian-reader/-/endian-reader-0.3.0.tgz#84eca436b80aed0d0639c47291338b932efe50a0"
-  integrity sha1-hOykNrgK7Q0GOcRykTOLky7+UKA=
-
-es6-error@^4.1.1:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
-  integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
-
-escape-goat@^2.0.0:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675"
-  integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==
-
-escape-string-regexp@^1.0.5:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
-  integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
-
-escape-string-regexp@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
-  integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
-
-esprima@^4.0.0, esprima@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
-  integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
-
-event-loop-spinner@^2.0.0, event-loop-spinner@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/event-loop-spinner/-/event-loop-spinner-2.1.0.tgz#75f501d585105c6d57f174073b39af1b6b3a1567"
-  integrity sha512-RJ10wL8/F9AlfBgRCvYctJIXSb9XkVmSCK3GGUvPD3dJrvTjDeDT0tmhcbEC6I2NEjNM9xD38HQJ4F/f/gb4VQ==
-  dependencies:
-    tslib "^2.1.0"
-
-execa@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
-  integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
-  dependencies:
-    cross-spawn "^6.0.0"
-    get-stream "^4.0.0"
-    is-stream "^1.1.0"
-    npm-run-path "^2.0.0"
-    p-finally "^1.0.0"
-    signal-exit "^3.0.0"
-    strip-eof "^1.0.0"
-
-external-editor@^3.0.3:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495"
-  integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==
-  dependencies:
-    chardet "^0.7.0"
-    iconv-lite "^0.4.24"
-    tmp "^0.0.33"
-
-fast-glob@^3.1.1, fast-glob@^3.2.2:
-  version "3.2.5"
-  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661"
-  integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==
-  dependencies:
-    "@nodelib/fs.stat" "^2.0.2"
-    "@nodelib/fs.walk" "^1.2.3"
-    glob-parent "^5.1.0"
-    merge2 "^1.3.0"
-    micromatch "^4.0.2"
-    picomatch "^2.2.1"
-
-fastq@^1.6.0:
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858"
-  integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==
-  dependencies:
-    reusify "^1.0.4"
-
-figures@^3.0.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af"
-  integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==
-  dependencies:
-    escape-string-regexp "^1.0.5"
-
-fill-range@^7.0.1:
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
-  integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
-  dependencies:
-    to-regex-range "^5.0.1"
-
-follow-redirects@^1.10.0:
-  version "1.14.0"
-  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.0.tgz#f5d260f95c5f8c105894491feee5dc8993b402fe"
-  integrity sha512-0vRwd7RKQBTt+mgu87mtYeofLFZpTas2S9zY+jIeuLJMNvudIgF52nr19q40HOwH5RrhWIPuj9puybzSJiRrVg==
-
-fs-constants@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
-  integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
-
-fs-minipass@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
-  integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==
-  dependencies:
-    minipass "^3.0.0"
-
-fs.realpath@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
-  integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
-
-function-bind@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
-  integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
-
-get-intrinsic@^1.0.2:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6"
-  integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==
-  dependencies:
-    function-bind "^1.1.1"
-    has "^1.0.3"
-    has-symbols "^1.0.1"
-
-get-stream@^4.0.0, get-stream@^4.1.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
-  integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
-  dependencies:
-    pump "^3.0.0"
-
-get-stream@^5.1.0:
-  version "5.2.0"
-  resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
-  integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
-  dependencies:
-    pump "^3.0.0"
-
-glob-parent@^5.1.0:
-  version "5.1.2"
-  resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
-  integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
-  dependencies:
-    is-glob "^4.0.1"
-
-glob@^7.1.3, glob@^7.1.6:
-  version "7.1.6"
-  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
-  integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
-  dependencies:
-    fs.realpath "^1.0.0"
-    inflight "^1.0.4"
-    inherits "2"
-    minimatch "^3.0.4"
-    once "^1.3.0"
-    path-is-absolute "^1.0.0"
-
-global-agent@^2.1.12:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-2.2.0.tgz#566331b0646e6bf79429a16877685c4a1fbf76dc"
-  integrity sha512-+20KpaW6DDLqhG7JDiJpD1JvNvb8ts+TNl7BPOYcURqCrXqnN1Vf+XVOrkKJAFPqfX+oEhsdzOj1hLWkBTdNJg==
-  dependencies:
-    boolean "^3.0.1"
-    core-js "^3.6.5"
-    es6-error "^4.1.1"
-    matcher "^3.0.0"
-    roarr "^2.15.3"
-    semver "^7.3.2"
-    serialize-error "^7.0.1"
-
-global-dirs@^2.0.1:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.1.0.tgz#e9046a49c806ff04d6c1825e196c8f0091e8df4d"
-  integrity sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==
-  dependencies:
-    ini "1.3.7"
-
-globalthis@^1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b"
-  integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==
-  dependencies:
-    define-properties "^1.1.3"
-
-globby@^11.0.1:
-  version "11.0.3"
-  resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb"
-  integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==
-  dependencies:
-    array-union "^2.1.0"
-    dir-glob "^3.0.1"
-    fast-glob "^3.1.1"
-    ignore "^5.1.4"
-    merge2 "^1.3.0"
-    slash "^3.0.0"
-
-got@11.4.0:
-  version "11.4.0"
-  resolved "https://registry.yarnpkg.com/got/-/got-11.4.0.tgz#1f0910310572af4efcc6890e1dacd7affb710b39"
-  integrity sha512-XysJZuZNVpaQ37Oo2LV90MIkPeYITehyy1A0QzO1JwOXm8EWuEf9eeGk2XuHePvLEGnm9AVOI37bHwD6KYyBtg==
-  dependencies:
-    "@sindresorhus/is" "^2.1.1"
-    "@szmarczak/http-timer" "^4.0.5"
-    "@types/cacheable-request" "^6.0.1"
-    "@types/responselike" "^1.0.0"
-    cacheable-lookup "^5.0.3"
-    cacheable-request "^7.0.1"
-    decompress-response "^6.0.0"
-    http2-wrapper "^1.0.0-beta.4.5"
-    lowercase-keys "^2.0.0"
-    p-cancelable "^2.0.0"
-    responselike "^2.0.0"
-
-got@^11.7.0:
-  version "11.8.2"
-  resolved "https://registry.yarnpkg.com/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599"
-  integrity sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==
-  dependencies:
-    "@sindresorhus/is" "^4.0.0"
-    "@szmarczak/http-timer" "^4.0.5"
-    "@types/cacheable-request" "^6.0.1"
-    "@types/responselike" "^1.0.0"
-    cacheable-lookup "^5.0.3"
-    cacheable-request "^7.0.1"
-    decompress-response "^6.0.0"
-    http2-wrapper "^1.0.0-beta.5.2"
-    lowercase-keys "^2.0.0"
-    p-cancelable "^2.0.0"
-    responselike "^2.0.0"
-
-got@^9.6.0:
-  version "9.6.0"
-  resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
-  integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==
-  dependencies:
-    "@sindresorhus/is" "^0.14.0"
-    "@szmarczak/http-timer" "^1.1.2"
-    cacheable-request "^6.0.0"
-    decompress-response "^3.3.0"
-    duplexer3 "^0.1.4"
-    get-stream "^4.1.0"
-    lowercase-keys "^1.0.1"
-    mimic-response "^1.0.1"
-    p-cancelable "^1.0.0"
-    to-readable-stream "^1.0.0"
-    url-parse-lax "^3.0.0"
-
-graceful-fs@^4.1.2:
-  version "4.1.15"
-  resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
-  integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
-
-grapheme-splitter@^1.0.4:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
-  integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
-
-gunzip-maybe@^1.4.2:
-  version "1.4.2"
-  resolved "https://registry.yarnpkg.com/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz#b913564ae3be0eda6f3de36464837a9cd94b98ac"
-  integrity sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==
-  dependencies:
-    browserify-zlib "^0.1.4"
-    is-deflate "^1.0.0"
-    is-gzip "^1.0.0"
-    peek-stream "^1.1.0"
-    pumpify "^1.3.3"
-    through2 "^2.0.3"
-
-has-flag@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
-  integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
-
-has-flag@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
-  integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
-
-has-symbols@^1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423"
-  integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==
-
-has-yarn@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77"
-  integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==
-
-has@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
-  integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
-  dependencies:
-    function-bind "^1.1.1"
-
-hosted-git-info@^3.0.4, hosted-git-info@^3.0.7:
-  version "3.0.8"
-  resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d"
-  integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==
-  dependencies:
-    lru-cache "^6.0.0"
-
 html2canvas@^1.1.4:
   version "1.1.4"
   resolved "https://registry.yarnpkg.com/html2canvas/-/html2canvas-1.1.4.tgz#53ae91cd26e9e9e623c56533cccb2e3f57c8124c"
@@ -1491,2086 +21,7 @@
   dependencies:
     css-line-break "1.1.1"
 
-http-cache-semantics@^4.0.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
-  integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
-
-http2-wrapper@^1.0.0-beta.4.5, http2-wrapper@^1.0.0-beta.5.2:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d"
-  integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==
-  dependencies:
-    quick-lru "^5.1.1"
-    resolve-alpn "^1.0.0"
-
-iconv-lite@^0.4.24, iconv-lite@^0.4.4:
-  version "0.4.24"
-  resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
-  integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
-  dependencies:
-    safer-buffer ">= 2.1.2 < 3"
-
-ieee754@^1.1.13:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
-  integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
-
-ignore@^5.1.4, ignore@^5.1.8:
-  version "5.1.8"
-  resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
-  integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
-
-immediate@~3.0.5:
-  version "3.0.6"
-  resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
-  integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=
-
-import-lazy@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43"
-  integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=
-
-imurmurhash@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
-  integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
-
-indent-string@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
-  integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
-
-inflight@^1.0.4:
-  version "1.0.6"
-  resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
-  integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
-  dependencies:
-    once "^1.3.0"
-    wrappy "1"
-
-inherits@2, inherits@~2.0.3:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
-  integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
-
-inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4:
-  version "2.0.4"
-  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
-  integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-
-ini@1.3.7, ini@~1.3.0:
-  version "1.3.7"
-  resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84"
-  integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==
-
-is-callable@^1.1.5:
-  version "1.2.3"
-  resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e"
-  integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==
-
-is-ci@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c"
-  integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==
-  dependencies:
-    ci-info "^2.0.0"
-
-is-deflate@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-deflate/-/is-deflate-1.0.0.tgz#c862901c3c161fb09dac7cdc7e784f80e98f2f14"
-  integrity sha1-yGKQHDwWH7CdrHzcfnhPgOmPLxQ=
-
-is-docker@^2.0.0:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
-  integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
-
-is-extglob@^2.1.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
-  integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
-
-is-fullwidth-code-point@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
-  integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
-
-is-fullwidth-code-point@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
-  integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
-
-is-glob@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
-  integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
-  dependencies:
-    is-extglob "^2.1.1"
-
-is-gzip@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-gzip/-/is-gzip-1.0.0.tgz#6ca8b07b99c77998025900e555ced8ed80879a83"
-  integrity sha1-bKiwe5nHeZgCWQDlVc7Y7YCHmoM=
-
-is-installed-globally@^0.3.1:
-  version "0.3.2"
-  resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141"
-  integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==
-  dependencies:
-    global-dirs "^2.0.1"
-    is-path-inside "^3.0.1"
-
-is-interactive@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e"
-  integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==
-
-is-npm@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d"
-  integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==
-
-is-number@^7.0.0:
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
-  integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
-
-is-obj@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982"
-  integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==
-
-is-path-inside@^3.0.1:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
-  integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
-
-is-stream@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
-  integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
-
-is-typedarray@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
-  integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
-
-is-unicode-supported@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
-  integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
-
-is-wsl@^2.1.1:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
-  integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
-  dependencies:
-    is-docker "^2.0.0"
-
-is-yarn-global@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232"
-  integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==
-
-is@^3.2.1:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/is/-/is-3.3.0.tgz#61cff6dd3c4193db94a3d62582072b44e5645d79"
-  integrity sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==
-
-isarray@~1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
-  integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
-
-isexe@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
-  integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
-
-js-yaml@^3.10.0:
-  version "3.14.1"
-  resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
-  integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
-  dependencies:
-    argparse "^1.0.7"
-    esprima "^4.0.0"
-
-js-yaml@^3.13.1:
-  version "3.13.1"
-  resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
-  integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
-  dependencies:
-    argparse "^1.0.7"
-    esprima "^4.0.0"
-
-json-buffer@3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
-  integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
-
-json-buffer@3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
-  integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
-
-json-file-plus@^3.3.1:
-  version "3.3.1"
-  resolved "https://registry.yarnpkg.com/json-file-plus/-/json-file-plus-3.3.1.tgz#f4363806b82819ff8803d83d539d6a9edd2a5258"
-  integrity sha512-wo0q1UuiV5NsDPQDup1Km8IwEeqe+olr8tkWxeJq9Bjtcp7DZ0l+yrg28fSC3DEtrE311mhTZ54QGS6oiqnZEA==
-  dependencies:
-    is "^3.2.1"
-    node.extend "^2.0.0"
-    object.assign "^4.1.0"
-    promiseback "^2.0.2"
-    safer-buffer "^2.0.2"
-
-json-stringify-safe@^5.0.1:
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
-  integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
-
-jszip@3.4.0:
-  version "3.4.0"
-  resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.4.0.tgz#1a69421fa5f0bb9bc222a46bca88182fba075350"
-  integrity sha512-gZAOYuPl4EhPTXT0GjhI3o+ZAz3su6EhLrKUoAivcKqyqC7laS5JEv4XWZND9BgcDcF83vI85yGbDmDR6UhrIg==
-  dependencies:
-    lie "~3.3.0"
-    pako "~1.0.2"
-    readable-stream "~2.3.6"
-    set-immediate-shim "~1.0.1"
-
-jszip@^3.2.2:
-  version "3.6.0"
-  resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.6.0.tgz#839b72812e3f97819cc13ac4134ffced95dd6af9"
-  integrity sha512-jgnQoG9LKnWO3mnVNBnfhkh0QknICd1FGSrXcgrl67zioyJ4wgx25o9ZqwNtrROSflGBCGYnJfjrIyRIby1OoQ==
-  dependencies:
-    lie "~3.3.0"
-    pako "~1.0.2"
-    readable-stream "~2.3.6"
-    set-immediate-shim "~1.0.1"
-
-keyv@^3.0.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
-  integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==
-  dependencies:
-    json-buffer "3.0.0"
-
-keyv@^4.0.0:
-  version "4.0.3"
-  resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254"
-  integrity sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==
-  dependencies:
-    json-buffer "3.0.1"
-
-latest-version@^5.0.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face"
-  integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==
-  dependencies:
-    package-json "^6.3.0"
-
-lie@~3.3.0:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a"
-  integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==
-  dependencies:
-    immediate "~3.0.5"
-
-lodash.assign@^4.2.0:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"
-  integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=
-
-lodash.assignin@^4.2.0:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2"
-  integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI=
-
-lodash.camelcase@^4.3.0:
-  version "4.3.0"
-  resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
-  integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY=
-
-lodash.chunk@^4.2.0:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/lodash.chunk/-/lodash.chunk-4.2.0.tgz#66e5ce1f76ed27b4303d8c6512e8d1216e8106bc"
-  integrity sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=
-
-lodash.clone@^4.5.0:
-  version "4.5.0"
-  resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6"
-  integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=
-
-lodash.clonedeep@^4.3.0, lodash.clonedeep@^4.5.0:
-  version "4.5.0"
-  resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
-  integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
-
-lodash.constant@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/lodash.constant/-/lodash.constant-3.0.0.tgz#bfe05cce7e515b3128925d6362138420bd624910"
-  integrity sha1-v+Bczn5RWzEokl1jYhOEIL1iSRA=
-
-lodash.defaults@^4.2.0:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
-  integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=
-
-lodash.endswith@^4.2.1:
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/lodash.endswith/-/lodash.endswith-4.2.1.tgz#fed59ac1738ed3e236edd7064ec456448b37bc09"
-  integrity sha1-/tWawXOO0+I27dcGTsRWRIs3vAk=
-
-lodash.filter@^4.6.0:
-  version "4.6.0"
-  resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace"
-  integrity sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=
-
-lodash.find@^4.6.0:
-  version "4.6.0"
-  resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1"
-  integrity sha1-ywcE1Hq3F4n/oN6Ll92Sb7iLE7E=
-
-lodash.findindex@^4.6.0:
-  version "4.6.0"
-  resolved "https://registry.yarnpkg.com/lodash.findindex/-/lodash.findindex-4.6.0.tgz#a3245dee61fb9b6e0624b535125624bb69c11106"
-  integrity sha1-oyRd7mH7m24GJLU1ElYku2nBEQY=
-
-lodash.findkey@^4.6.0:
-  version "4.6.0"
-  resolved "https://registry.yarnpkg.com/lodash.findkey/-/lodash.findkey-4.6.0.tgz#83058e903b51cbb759d09ccf546dea3ea39c4718"
-  integrity sha1-gwWOkDtRy7dZ0JzPVG3qPqOcRxg=
-
-lodash.flatmap@^4.5.0:
-  version "4.5.0"
-  resolved "https://registry.yarnpkg.com/lodash.flatmap/-/lodash.flatmap-4.5.0.tgz#ef8cbf408f6e48268663345305c6acc0b778702e"
-  integrity sha1-74y/QI9uSCaGYzRTBcaswLd4cC4=
-
-lodash.flatten@^4.4.0:
-  version "4.4.0"
-  resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
-  integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
-
-lodash.flattendeep@^4.4.0:
-  version "4.4.0"
-  resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
-  integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=
-
-lodash.foreach@^4.5.0:
-  version "4.5.0"
-  resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53"
-  integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=
-
-lodash.get@^4.4.2:
-  version "4.4.2"
-  resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
-  integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
-
-lodash.groupby@^4.6.0:
-  version "4.6.0"
-  resolved "https://registry.yarnpkg.com/lodash.groupby/-/lodash.groupby-4.6.0.tgz#0b08a1dcf68397c397855c3239783832df7403d1"
-  integrity sha1-Cwih3PaDl8OXhVwyOXg4Mt90A9E=
-
-lodash.has@^4.5.2:
-  version "4.5.2"
-  resolved "https://registry.yarnpkg.com/lodash.has/-/lodash.has-4.5.2.tgz#d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862"
-  integrity sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=
-
-lodash.invert@^4.3.0:
-  version "4.3.0"
-  resolved "https://registry.yarnpkg.com/lodash.invert/-/lodash.invert-4.3.0.tgz#8ffe20d4b616f56bea8f1aa0c6ebd80dcf742aee"
-  integrity sha1-j/4g1LYW9WvqjxqgxuvYDc90Ku4=
-
-lodash.isboolean@^3.0.3:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
-  integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
-
-lodash.isempty@^4.4.0:
-  version "4.4.0"
-  resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e"
-  integrity sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=
-
-lodash.isequal@^4.5.0:
-  version "4.5.0"
-  resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
-  integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
-
-lodash.isfunction@^3.0.9:
-  version "3.0.9"
-  resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051"
-  integrity sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==
-
-lodash.isnumber@^3.0.3:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
-  integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
-
-lodash.isobject@^3.0.2:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d"
-  integrity sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=
-
-lodash.isplainobject@^4.0.6:
-  version "4.0.6"
-  resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
-  integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
-
-lodash.isstring@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
-  integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
-
-lodash.isundefined@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz#23ef3d9535565203a66cefd5b830f848911afb48"
-  integrity sha1-I+89lTVWUgOmbO/VuDD4SJEa+0g=
-
-lodash.keys@^4.2.0:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-4.2.0.tgz#a08602ac12e4fb83f91fc1fb7a360a4d9ba35205"
-  integrity sha1-oIYCrBLk+4P5H8H7ejYKTZujUgU=
-
-lodash.last@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/lodash.last/-/lodash.last-3.0.0.tgz#242f663112dd4c6e63728c60a3c909d1bdadbd4c"
-  integrity sha1-JC9mMRLdTG5jcoxgo8kJ0b2tvUw=
-
-lodash.map@^4.6.0:
-  version "4.6.0"
-  resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
-  integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=
-
-lodash.merge@^4.6.2:
-  version "4.6.2"
-  resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
-  integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
-
-lodash.omit@^4.5.0:
-  version "4.5.0"
-  resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60"
-  integrity sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=
-
-lodash.orderby@^4.6.0:
-  version "4.6.0"
-  resolved "https://registry.yarnpkg.com/lodash.orderby/-/lodash.orderby-4.6.0.tgz#e697f04ce5d78522f54d9338b32b81a3393e4eb3"
-  integrity sha1-5pfwTOXXhSL1TZM4syuBozk+TrM=
-
-lodash.reduce@^4.6.0:
-  version "4.6.0"
-  resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b"
-  integrity sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=
-
-lodash.set@^4.3.2:
-  version "4.3.2"
-  resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
-  integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=
-
-lodash.size@^4.2.0:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/lodash.size/-/lodash.size-4.2.0.tgz#71fe75ed3eabdb2bcb73a1b0b4f51c392ee27b86"
-  integrity sha1-cf517T6r2yvLc6GwtPUcOS7ie4Y=
-
-lodash.sortby@^4.7.0:
-  version "4.7.0"
-  resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
-  integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
-
-lodash.sum@^4.0.2:
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/lodash.sum/-/lodash.sum-4.0.2.tgz#ad90e397965d803d4f1ff7aa5b2d0197f3b4637b"
-  integrity sha1-rZDjl5ZdgD1PH/eqWy0Bl/O0Y3s=
-
-lodash.topairs@^4.3.0:
-  version "4.3.0"
-  resolved "https://registry.yarnpkg.com/lodash.topairs/-/lodash.topairs-4.3.0.tgz#3b6deaa37d60fb116713c46c5f17ea190ec48d64"
-  integrity sha1-O23qo31g+xFnE8RsXxfqGQ7EjWQ=
-
-lodash.transform@^4.6.0:
-  version "4.6.0"
-  resolved "https://registry.yarnpkg.com/lodash.transform/-/lodash.transform-4.6.0.tgz#12306422f63324aed8483d3f38332b5f670547a0"
-  integrity sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A=
-
-lodash.union@^4.6.0:
-  version "4.6.0"
-  resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88"
-  integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=
-
-lodash.uniq@^4.5.0:
-  version "4.5.0"
-  resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
-  integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
-
-lodash.upperfirst@^4.3.1:
-  version "4.3.1"
-  resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce"
-  integrity sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=
-
-lodash.values@^4.3.0:
-  version "4.3.0"
-  resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-4.3.0.tgz#a3a6c2b0ebecc5c2cba1c17e6e620fe81b53d347"
-  integrity sha1-o6bCsOvsxcLLocF+bmIP6BtT00c=
-
-lodash@^4.17.15:
-  version "4.17.21"
-  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
-  integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
-
-log-symbols@^4.0.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
-  integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
-  dependencies:
-    chalk "^4.1.0"
-    is-unicode-supported "^0.1.0"
-
-lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
-  integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
-
-lowercase-keys@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
-  integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
-
-lru-cache@^4.0.0:
-  version "4.1.5"
-  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
-  integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
-  dependencies:
-    pseudomap "^1.0.2"
-    yallist "^2.1.2"
-
-lru-cache@^5.1.1:
-  version "5.1.1"
-  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
-  integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
-  dependencies:
-    yallist "^3.0.2"
-
-lru-cache@^6.0.0:
-  version "6.0.0"
-  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
-  integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
-  dependencies:
-    yallist "^4.0.0"
-
-macos-release@^2.2.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f"
-  integrity sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==
-
-make-dir@^3.0.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
-  integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
-  dependencies:
-    semver "^6.0.0"
-
-matcher@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca"
-  integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==
-  dependencies:
-    escape-string-regexp "^4.0.0"
-
-merge2@^1.3.0:
-  version "1.4.1"
-  resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
-  integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
-
-micromatch@4.0.2:
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259"
-  integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==
-  dependencies:
-    braces "^3.0.1"
-    picomatch "^2.0.5"
-
-micromatch@^4.0.2:
-  version "4.0.4"
-  resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
-  integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
-  dependencies:
-    braces "^3.0.1"
-    picomatch "^2.2.3"
-
-mimic-fn@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
-  integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
-
-mimic-response@^1.0.0, mimic-response@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
-  integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
-
-mimic-response@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
-  integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
-
-minimatch@^3.0.4:
-  version "3.0.4"
-  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
-  integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
-  dependencies:
-    brace-expansion "^1.1.7"
-
-minimist@^1.2.0, minimist@^1.2.5:
-  version "1.2.5"
-  resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
-  integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
-
-minipass@^3.0.0:
-  version "3.1.3"
-  resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd"
-  integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==
-  dependencies:
-    yallist "^4.0.0"
-
-minizlib@^2.1.1:
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"
-  integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==
-  dependencies:
-    minipass "^3.0.0"
-    yallist "^4.0.0"
-
-mkdirp@^0.5.1:
-  version "0.5.5"
-  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
-  integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
-  dependencies:
-    minimist "^1.2.5"
-
-mkdirp@^1.0.3, mkdirp@^1.0.4:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
-  integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
-
-ms@2.1.2:
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
-  integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-
-ms@^2.1.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
-  integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
-
-mute-stream@0.0.8:
-  version "0.0.8"
-  resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
-  integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
-
-needle@2.6.0, needle@^2.3.3, needle@^2.5.0:
-  version "2.6.0"
-  resolved "https://registry.yarnpkg.com/needle/-/needle-2.6.0.tgz#24dbb55f2509e2324b4a99d61f413982013ccdbe"
-  integrity sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==
-  dependencies:
-    debug "^3.2.6"
-    iconv-lite "^0.4.4"
-    sax "^1.2.4"
-
-nice-try@^1.0.4:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
-  integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
-
-node.extend@^2.0.0:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/node.extend/-/node.extend-2.0.2.tgz#b4404525494acc99740f3703c496b7d5182cc6cc"
-  integrity sha512-pDT4Dchl94/+kkgdwyS2PauDFjZG0Hk0IcHIB+LkW27HLDtdoeMxHTxZh39DYbPP8UflWXWj9JcdDozF+YDOpQ==
-  dependencies:
-    has "^1.0.3"
-    is "^3.2.1"
-
-normalize-url@^4.1.0:
-  version "4.5.0"
-  resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
-  integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==
-
-npm-run-path@^2.0.0:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
-  integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
-  dependencies:
-    path-key "^2.0.0"
-
-object-hash@^2.0.3:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.1.1.tgz#9447d0279b4fcf80cff3259bf66a1dc73afabe09"
-  integrity sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==
-
-object-keys@^1.0.12, object-keys@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
-  integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
-
-object.assign@^4.1.0:
-  version "4.1.2"
-  resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940"
-  integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==
-  dependencies:
-    call-bind "^1.0.0"
-    define-properties "^1.1.3"
-    has-symbols "^1.0.1"
-    object-keys "^1.1.1"
-
-once@^1.3.0, once@^1.3.1, once@^1.4.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
-  integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
-  dependencies:
-    wrappy "1"
-
-once@~1.3.0:
-  version "1.3.3"
-  resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20"
-  integrity sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=
-  dependencies:
-    wrappy "1"
-
-onetime@^5.1.0:
-  version "5.1.2"
-  resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
-  integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
-  dependencies:
-    mimic-fn "^2.1.0"
-
 onscan.js@^1.5.2:
   version "1.5.2"
   resolved "https://registry.yarnpkg.com/onscan.js/-/onscan.js-1.5.2.tgz#14ed636e5f4c3f0a78bacbf9a505dad3140ee341"
   integrity sha512-9oGYy2gXYRjvXO9GYqqVca0VuCTAmWhbmX3egBSBP13rXiMNb+dKPJzKFEeECGqPBpf0m40Zoo+GUQ7eCackdw==
-
-open@^7.0.3:
-  version "7.4.2"
-  resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321"
-  integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==
-  dependencies:
-    is-docker "^2.0.0"
-    is-wsl "^2.1.1"
-
-ora@5.3.0:
-  version "5.3.0"
-  resolved "https://registry.yarnpkg.com/ora/-/ora-5.3.0.tgz#fb832899d3a1372fe71c8b2c534bbfe74961bb6f"
-  integrity sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==
-  dependencies:
-    bl "^4.0.3"
-    chalk "^4.1.0"
-    cli-cursor "^3.1.0"
-    cli-spinners "^2.5.0"
-    is-interactive "^1.0.0"
-    log-symbols "^4.0.0"
-    strip-ansi "^6.0.0"
-    wcwidth "^1.0.1"
-
-os-name@^3.0.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801"
-  integrity sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==
-  dependencies:
-    macos-release "^2.2.0"
-    windows-release "^3.1.0"
-
-os-tmpdir@~1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
-  integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
-
-p-cancelable@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
-  integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
-
-p-cancelable@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.0.tgz#4d51c3b91f483d02a0d300765321fca393d758dd"
-  integrity sha512-HAZyB3ZodPo+BDpb4/Iu7Jv4P6cSazBz9ZM0ChhEXp70scx834aWCEjQRwgt41UzzejUAPdbqqONfRWTPYrPAQ==
-
-p-finally@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
-  integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
-
-p-limit@^2.2.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
-  integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
-  dependencies:
-    p-try "^2.0.0"
-
-p-map@2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
-  integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==
-
-p-map@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b"
-  integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==
-  dependencies:
-    aggregate-error "^3.0.0"
-
-p-try@^2.0.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
-  integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
-
-package-json@^6.3.0:
-  version "6.5.0"
-  resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0"
-  integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==
-  dependencies:
-    got "^9.6.0"
-    registry-auth-token "^4.0.0"
-    registry-url "^5.0.0"
-    semver "^6.2.0"
-
-pako@~0.2.0:
-  version "0.2.9"
-  resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
-  integrity sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=
-
-pako@~1.0.2:
-  version "1.0.11"
-  resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
-  integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
-
-parse-link-header@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/parse-link-header/-/parse-link-header-1.0.1.tgz#bedfe0d2118aeb84be75e7b025419ec8a61140a7"
-  integrity sha1-vt/g0hGK64S+deewJUGeyKYRQKc=
-  dependencies:
-    xtend "~4.0.1"
-
-path-is-absolute@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
-  integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
-
-path-key@^2.0.0, path-key@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
-  integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
-
-path-key@^3.1.0:
-  version "3.1.1"
-  resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
-  integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
-
-path-type@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
-  integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
-
-peek-stream@^1.1.0:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/peek-stream/-/peek-stream-1.1.3.tgz#3b35d84b7ccbbd262fff31dc10da56856ead6d67"
-  integrity sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==
-  dependencies:
-    buffer-from "^1.0.0"
-    duplexify "^3.5.0"
-    through2 "^2.0.3"
-
-picomatch@^2.0.5, picomatch@^2.2.1, picomatch@^2.2.3:
-  version "2.2.3"
-  resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d"
-  integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==
-
-pluralize@^7.0.0:
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
-  integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==
-
-prepend-http@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
-  integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
-
-pretty-bytes@^5.1.0:
-  version "5.6.0"
-  resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
-  integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==
-
-process-nextick-args@~2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
-  integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==
-
-progress@^2.0.3:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
-  integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
-
-promise-deferred@^2.0.3:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/promise-deferred/-/promise-deferred-2.0.3.tgz#b99c9588820798501862a593d49cece51d06fd7f"
-  integrity sha512-n10XaoznCzLfyPFOlEE8iurezHpxrYzyjgq/1eW9Wk1gJwur/N7BdBmjJYJpqMeMcXK4wEbzo2EvZQcqjYcKUQ==
-  dependencies:
-    promise "^7.3.1"
-
-promise-fs@^2.1.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/promise-fs/-/promise-fs-2.1.1.tgz#0b725a592c165ff16157d1f13640ba390637e557"
-  integrity sha512-43p7e4QzAQ3w6eyN0+gbBL7jXiZFWLWYITg9wIObqkBySu/a5K1EDcQ/S6UyB/bmiZWDA4NjTbcopKLTaKcGSw==
-  dependencies:
-    "@octetstream/promisify" "2.0.2"
-
-promise-queue@^2.2.5:
-  version "2.2.5"
-  resolved "https://registry.yarnpkg.com/promise-queue/-/promise-queue-2.2.5.tgz#2f6f5f7c0f6d08109e967659c79b88a9ed5e93b4"
-  integrity sha1-L29ffA9tCBCelnZZx5uIqe1ek7Q=
-
-"promise@>=3.2 <8", promise@^7.3.1:
-  version "7.3.1"
-  resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
-  integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==
-  dependencies:
-    asap "~2.0.3"
-
-promiseback@^2.0.2:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/promiseback/-/promiseback-2.0.3.tgz#bd468d86930e8cd44bfc3292de9a6fbafb6378e6"
-  integrity sha512-VZXdCwS0ppVNTIRfNsCvVwJAaP2b+pxQF7lM8DMWfmpNWyTxB6O5YNbzs+8z0ki/KIBHKHk308NTIl4kJUem3w==
-  dependencies:
-    is-callable "^1.1.5"
-    promise-deferred "^2.0.3"
-
-proxy-from-env@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee"
-  integrity sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=
-
-pseudomap@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
-  integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
-
-pump@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909"
-  integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==
-  dependencies:
-    end-of-stream "^1.1.0"
-    once "^1.3.1"
-
-pump@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
-  integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
-  dependencies:
-    end-of-stream "^1.1.0"
-    once "^1.3.1"
-
-pumpify@^1.3.3:
-  version "1.5.1"
-  resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce"
-  integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==
-  dependencies:
-    duplexify "^3.6.0"
-    inherits "^2.0.3"
-    pump "^2.0.0"
-
-pupa@^2.0.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62"
-  integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==
-  dependencies:
-    escape-goat "^2.0.0"
-
-queue-microtask@^1.2.2:
-  version "1.2.3"
-  resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
-  integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
-
-queue@^6.0.1:
-  version "6.0.2"
-  resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.2.tgz#b91525283e2315c7553d2efa18d83e76432fed65"
-  integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==
-  dependencies:
-    inherits "~2.0.3"
-
-quick-lru@^5.1.1:
-  version "5.1.1"
-  resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
-  integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
-
-rc@^1.2.8:
-  version "1.2.8"
-  resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
-  integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
-  dependencies:
-    deep-extend "^0.6.0"
-    ini "~1.3.0"
-    minimist "^1.2.0"
-    strip-json-comments "~2.0.1"
-
-readable-stream@^2.0.0, readable-stream@~2.3.6:
-  version "2.3.7"
-  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
-  integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
-  dependencies:
-    core-util-is "~1.0.0"
-    inherits "~2.0.3"
-    isarray "~1.0.0"
-    process-nextick-args "~2.0.0"
-    safe-buffer "~5.1.1"
-    string_decoder "~1.1.1"
-    util-deprecate "~1.0.1"
-
-readable-stream@^3.0.1, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0:
-  version "3.6.0"
-  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
-  integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
-  dependencies:
-    inherits "^2.0.3"
-    string_decoder "^1.1.1"
-    util-deprecate "^1.0.1"
-
-registry-auth-token@^4.0.0:
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250"
-  integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==
-  dependencies:
-    rc "^1.2.8"
-
-registry-url@^5.0.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009"
-  integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==
-  dependencies:
-    rc "^1.2.8"
-
-resolve-alpn@^1.0.0:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.1.2.tgz#30b60cfbb0c0b8dc897940fe13fe255afcdd4d28"
-  integrity sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA==
-
-responselike@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
-  integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
-  dependencies:
-    lowercase-keys "^1.0.0"
-
-responselike@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723"
-  integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==
-  dependencies:
-    lowercase-keys "^2.0.0"
-
-restore-cursor@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e"
-  integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==
-  dependencies:
-    onetime "^5.1.0"
-    signal-exit "^3.0.2"
-
-reusify@^1.0.4:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
-  integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
-
-rimraf@^2.6.3:
-  version "2.7.1"
-  resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
-  integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
-  dependencies:
-    glob "^7.1.3"
-
-rimraf@^3.0.0:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
-  integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
-  dependencies:
-    glob "^7.1.3"
-
-roarr@^2.15.3:
-  version "2.15.4"
-  resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd"
-  integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==
-  dependencies:
-    boolean "^3.0.1"
-    detect-node "^2.0.4"
-    globalthis "^1.0.1"
-    json-stringify-safe "^5.0.1"
-    semver-compare "^1.0.0"
-    sprintf-js "^1.1.2"
-
-run-async@^2.4.0:
-  version "2.4.1"
-  resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455"
-  integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==
-
-run-parallel@^1.1.9:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
-  integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
-  dependencies:
-    queue-microtask "^1.2.2"
-
-rxjs@^6.6.0:
-  version "6.6.7"
-  resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"
-  integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==
-  dependencies:
-    tslib "^1.9.0"
-
-safe-buffer@~5.1.0, safe-buffer@~5.1.1:
-  version "5.1.2"
-  resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
-  integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-
-safe-buffer@~5.2.0:
-  version "5.2.1"
-  resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
-  integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
-
-"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@~2.1.0:
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
-  integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
-
-sax@>=0.6.0, sax@^1.2.4:
-  version "1.2.4"
-  resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
-  integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
-
-semver-compare@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
-  integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
-
-semver-diff@^3.1.1:
-  version "3.1.1"
-  resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b"
-  integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==
-  dependencies:
-    semver "^6.3.0"
-
-semver@^5.5.0:
-  version "5.6.0"
-  resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
-  integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==
-
-semver@^5.5.1:
-  version "5.7.1"
-  resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
-  integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
-
-semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0:
-  version "6.3.0"
-  resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
-  integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
-
-semver@^7.0.0, semver@^7.1.2, semver@^7.3.2, semver@^7.3.4:
-  version "7.3.5"
-  resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
-  integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
-  dependencies:
-    lru-cache "^6.0.0"
-
-serialize-error@^7.0.1:
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"
-  integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==
-  dependencies:
-    type-fest "^0.13.1"
-
-set-immediate-shim@~1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
-  integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=
-
-shebang-command@^1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
-  integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
-  dependencies:
-    shebang-regex "^1.0.0"
-
-shebang-command@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
-  integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
-  dependencies:
-    shebang-regex "^3.0.0"
-
-shebang-regex@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
-  integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
-
-shebang-regex@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
-  integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
-
-signal-exit@^3.0.0, signal-exit@^3.0.2:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
-  integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
-
-slash@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
-  integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
-
-snyk-config@4.0.0, snyk-config@^4.0.0-rc.2:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/snyk-config/-/snyk-config-4.0.0.tgz#21d459f19087991246cc07a7ffb4501dce6f4159"
-  integrity sha512-E6jNe0oUjjzVASWBOAc/mA23DhbzABDF9MI6UZvl0gylh2NSXSXw2/LjlqMNOKL2c1qkbSkzLOdIX5XACoLCAQ==
-  dependencies:
-    async "^3.2.0"
-    debug "^4.1.1"
-    lodash.merge "^4.6.2"
-    minimist "^1.2.5"
-
-snyk-cpp-plugin@2.2.1:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/snyk-cpp-plugin/-/snyk-cpp-plugin-2.2.1.tgz#55891511a43a6448e5a7c836a94f66f70fa705eb"
-  integrity sha512-NFwVLMCqKTocY66gcim0ukF6e31VRDJqDapg5sy3vCHqlD1OCNUXSK/aI4VQEEndDrsnFmQepsL5KpEU0dDRIQ==
-  dependencies:
-    "@snyk/dep-graph" "^1.19.3"
-    chalk "^4.1.0"
-    debug "^4.1.1"
-    hosted-git-info "^3.0.7"
-    tslib "^2.0.0"
-
-snyk-docker-plugin@4.19.3:
-  version "4.19.3"
-  resolved "https://registry.yarnpkg.com/snyk-docker-plugin/-/snyk-docker-plugin-4.19.3.tgz#14569f25c52a3fc71a20f80f5beac4ccdc326c11"
-  integrity sha512-5WkXyT7uY5NrTOvEqxeMqb6dDcskT3c/gbHUTOyPuvE6tMut+OOYK8RRXbwZFeLzpS8asq4e1R7U7syYG3VXwg==
-  dependencies:
-    "@snyk/dep-graph" "^1.21.0"
-    "@snyk/rpm-parser" "^2.0.0"
-    "@snyk/snyk-docker-pull" "3.2.3"
-    chalk "^2.4.2"
-    debug "^4.1.1"
-    docker-modem "2.1.3"
-    dockerfile-ast "0.2.0"
-    elfy "^1.0.0"
-    event-loop-spinner "^2.0.0"
-    gunzip-maybe "^1.4.2"
-    mkdirp "^1.0.4"
-    semver "^7.3.4"
-    snyk-nodejs-lockfile-parser "1.30.2"
-    tar-stream "^2.1.0"
-    tmp "^0.2.1"
-    tslib "^1"
-    uuid "^8.2.0"
-
-snyk-go-parser@1.4.1:
-  version "1.4.1"
-  resolved "https://registry.yarnpkg.com/snyk-go-parser/-/snyk-go-parser-1.4.1.tgz#df16a5fbd7a517ee757268ef081abc33506c8857"
-  integrity sha512-StU3uHB85VMEkcgXta63M0Fgd+9cs5sMCjQXTBoYTdE4dxarPn7U67yCuwkRRdZdny1ZXtzfY8LKns9i0+dy9w==
-  dependencies:
-    toml "^3.0.0"
-    tslib "^1.10.0"
-
-snyk-go-plugin@1.17.0:
-  version "1.17.0"
-  resolved "https://registry.yarnpkg.com/snyk-go-plugin/-/snyk-go-plugin-1.17.0.tgz#56d0c92d7def29ba4c3c2030c5830093e3b0dd26"
-  integrity sha512-1jAYPRgMapO2BYL+HWsUq5gsAiDGmI0Pn7omc0lk24tcUOMhUB+1hb0u9WBMNzHvXBjevBkjOctjpnt2hMKN6Q==
-  dependencies:
-    "@snyk/dep-graph" "^1.23.1"
-    "@snyk/graphlib" "2.1.9-patch.3"
-    debug "^4.1.1"
-    snyk-go-parser "1.4.1"
-    tmp "0.2.1"
-    tslib "^1.10.0"
-
-snyk-gradle-plugin@3.14.2:
-  version "3.14.2"
-  resolved "https://registry.yarnpkg.com/snyk-gradle-plugin/-/snyk-gradle-plugin-3.14.2.tgz#898b051f679e681b6d859f0ca84a500ac028af7d"
-  integrity sha512-l/nivKDZz7e2wymrwP6g2WQD8qgaYeE22SnbZrfIpwGolif81U28A9FsRedwkxKyB/shrM0vGEoD3c3zI8NLBw==
-  dependencies:
-    "@snyk/cli-interface" "2.11.0"
-    "@snyk/dep-graph" "^1.28.0"
-    "@snyk/java-call-graph-builder" "1.20.0"
-    "@types/debug" "^4.1.4"
-    chalk "^3.0.0"
-    debug "^4.1.1"
-    tmp "0.2.1"
-    tslib "^2.0.0"
-
-snyk-module@3.1.0, snyk-module@^3.0.0, snyk-module@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/snyk-module/-/snyk-module-3.1.0.tgz#3e088ff473ddf0d4e253a46ea6749d76d8e6e7ba"
-  integrity sha512-HHuOYEAACpUpkFgU8HT57mmxmonaJ4O3YADoSkVhnhkmJ+AowqZyJOau703dYHNrq2DvQ7qYw81H7yyxS1Nfjw==
-  dependencies:
-    debug "^4.1.1"
-    hosted-git-info "^3.0.4"
-
-snyk-mvn-plugin@2.25.3:
-  version "2.25.3"
-  resolved "https://registry.yarnpkg.com/snyk-mvn-plugin/-/snyk-mvn-plugin-2.25.3.tgz#fb7f6fa1d565b9f07c032e8b34e6308c310b2a27"
-  integrity sha512-JAxOThX51JDbgMMjp3gQDVi07G9VgTYSF06QC7f5LNA0zoXNr743e2rm78RGw5bqE3JRjZxEghiLHPPuvS5DDg==
-  dependencies:
-    "@snyk/cli-interface" "2.11.0"
-    "@snyk/dep-graph" "^1.23.1"
-    "@snyk/java-call-graph-builder" "1.19.1"
-    debug "^4.1.1"
-    glob "^7.1.6"
-    needle "^2.5.0"
-    tmp "^0.1.0"
-    tslib "1.11.1"
-
-snyk-nodejs-lockfile-parser@1.30.2:
-  version "1.30.2"
-  resolved "https://registry.yarnpkg.com/snyk-nodejs-lockfile-parser/-/snyk-nodejs-lockfile-parser-1.30.2.tgz#8dbb64c42382aeaf4488c36e48c1e48eb75a1584"
-  integrity sha512-wI3VXVYO/ok0uaQm5i+Koo4rKBNilYC/QRIQFlyGbZXf+WBdRcTBKVDfTy8uNfUhMRSGzd84lNclMnetU9Y+vw==
-  dependencies:
-    "@snyk/graphlib" "2.1.9-patch.3"
-    "@yarnpkg/lockfile" "^1.1.0"
-    event-loop-spinner "^2.0.0"
-    got "11.4.0"
-    lodash.clonedeep "^4.5.0"
-    lodash.flatmap "^4.5.0"
-    lodash.isempty "^4.4.0"
-    lodash.set "^4.3.2"
-    lodash.topairs "^4.3.0"
-    p-map "2.1.0"
-    snyk-config "^4.0.0-rc.2"
-    tslib "^1.9.3"
-    uuid "^8.3.0"
-    yaml "^1.9.2"
-
-snyk-nodejs-lockfile-parser@1.32.0:
-  version "1.32.0"
-  resolved "https://registry.yarnpkg.com/snyk-nodejs-lockfile-parser/-/snyk-nodejs-lockfile-parser-1.32.0.tgz#2e25ea8622ef03ae7457a93ae70e156d6c46c2ef"
-  integrity sha512-FdYa/7NibnJPqBfobyw5jgI1/rd0LpMZf2W4WYYLRc2Hz7LZjKAByPjIX6qoA+lB9SC7yk5HYwWj2n4Fbg/DDw==
-  dependencies:
-    "@snyk/graphlib" "2.1.9-patch.3"
-    "@yarnpkg/core" "^2.4.0"
-    "@yarnpkg/lockfile" "^1.1.0"
-    event-loop-spinner "^2.0.0"
-    got "11.4.0"
-    lodash.clonedeep "^4.5.0"
-    lodash.flatmap "^4.5.0"
-    lodash.isempty "^4.4.0"
-    lodash.set "^4.3.2"
-    lodash.topairs "^4.3.0"
-    p-map "2.1.0"
-    snyk-config "^4.0.0-rc.2"
-    tslib "^1.9.3"
-    uuid "^8.3.0"
-    yaml "^1.9.2"
-
-snyk-nuget-plugin@1.21.1:
-  version "1.21.1"
-  resolved "https://registry.yarnpkg.com/snyk-nuget-plugin/-/snyk-nuget-plugin-1.21.1.tgz#a79bbc65456823a1148119873226afb0e4907ec8"
-  integrity sha512-nRtedIvrow5ODqOKkQWolKrxn8ZoNL3iNJGuW0jNhwv+/9K0XE1UORM5F1ENAsd+nzCSO/kiYAXCc5CNK8HWEw==
-  dependencies:
-    debug "^4.1.1"
-    dotnet-deps-parser "5.0.0"
-    jszip "3.4.0"
-    snyk-paket-parser "1.6.0"
-    tslib "^1.11.2"
-    xml2js "^0.4.17"
-
-snyk-paket-parser@1.6.0:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/snyk-paket-parser/-/snyk-paket-parser-1.6.0.tgz#f70c423b33d31484c8c4cae74bb7f5deb9bbc382"
-  integrity sha512-6htFynjBe/nakclEHUZ1A3j5Eu32/0pNve5Qm4MFn3YQmJgj7UcAO8hdyK3QfzEY29/kAv/rkJQg+SKshn+N9Q==
-  dependencies:
-    tslib "^1.9.3"
-
-snyk-php-plugin@1.9.2:
-  version "1.9.2"
-  resolved "https://registry.yarnpkg.com/snyk-php-plugin/-/snyk-php-plugin-1.9.2.tgz#282ef733060aab49da23e1fb2d2dd1af8f71f7cd"
-  integrity sha512-IQcdsQBqqXVRY5DatlI7ASy4flbhtU2V7cr4P2rK9rkFnVHO6LHcitwKXVZa9ocdOmpZDzk7U6iwHJkVFcR6OA==
-  dependencies:
-    "@snyk/cli-interface" "^2.9.1"
-    "@snyk/composer-lockfile-parser" "^1.4.1"
-    tslib "1.11.1"
-
-snyk-poetry-lockfile-parser@^1.1.6:
-  version "1.1.6"
-  resolved "https://registry.yarnpkg.com/snyk-poetry-lockfile-parser/-/snyk-poetry-lockfile-parser-1.1.6.tgz#bab5a279c103cbcca8eb86ab87717b115592881e"
-  integrity sha512-MoekbWOZPj9umfukjk2bd2o3eRj0OyO+58sxq9crMtHmTlze4h0/Uj4+fb0JFPBOtBO3c2zwbA+dvFQmpKoOTA==
-  dependencies:
-    "@snyk/cli-interface" "^2.9.2"
-    "@snyk/dep-graph" "^1.23.0"
-    debug "^4.2.0"
-    toml "^3.0.0"
-    tslib "^2.0.0"
-
-snyk-policy@1.19.0:
-  version "1.19.0"
-  resolved "https://registry.yarnpkg.com/snyk-policy/-/snyk-policy-1.19.0.tgz#0cbc442d9503970fb3afea938f57d57993a914ad"
-  integrity sha512-XYjhOTRPFA7NfDUsH6uH1fbML2OgSFsqdUPbud7x01urNP9CHXgUgAD4NhKMi3dVQK+7IdYadWt0wrFWw4y+qg==
-  dependencies:
-    debug "^4.1.1"
-    email-validator "^2.0.4"
-    js-yaml "^3.13.1"
-    lodash.clonedeep "^4.5.0"
-    promise-fs "^2.1.1"
-    semver "^6.0.0"
-    snyk-module "^3.0.0"
-    snyk-resolve "^1.1.0"
-    snyk-try-require "^2.0.0"
-
-snyk-python-plugin@1.19.8:
-  version "1.19.8"
-  resolved "https://registry.yarnpkg.com/snyk-python-plugin/-/snyk-python-plugin-1.19.8.tgz#9e4dfa8ed7e16ef2752f934b786d2e033de62ce0"
-  integrity sha512-LMKVnv0J4X/qHMoKB17hMND0abWtm9wdgI4xVzrOcf2Vtzs3J87trRhwLxQA2lMoBW3gcjtTeBUvNKaxikSVeQ==
-  dependencies:
-    "@snyk/cli-interface" "^2.0.3"
-    snyk-poetry-lockfile-parser "^1.1.6"
-    tmp "0.0.33"
-
-snyk-resolve-deps@4.7.2:
-  version "4.7.2"
-  resolved "https://registry.yarnpkg.com/snyk-resolve-deps/-/snyk-resolve-deps-4.7.2.tgz#11e7051110dadd8756819594bb30e6b88777a8b4"
-  integrity sha512-Bmtr7QdRL2b3Js+mPDmvXbkprOpzO8aUFXqR0nJKAOlUVQqZ84yiuT0n/mssEiJJ0vP+k0kZvTeiTwgio4KZRg==
-  dependencies:
-    ansicolors "^0.3.2"
-    debug "^4.1.1"
-    lodash.assign "^4.2.0"
-    lodash.assignin "^4.2.0"
-    lodash.clone "^4.5.0"
-    lodash.flatten "^4.4.0"
-    lodash.get "^4.4.2"
-    lodash.set "^4.3.2"
-    lru-cache "^4.0.0"
-    semver "^5.5.1"
-    snyk-module "^3.1.0"
-    snyk-resolve "^1.0.0"
-    snyk-tree "^1.0.0"
-    snyk-try-require "^1.1.1"
-    then-fs "^2.0.0"
-
-snyk-resolve@1.1.0, snyk-resolve@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/snyk-resolve/-/snyk-resolve-1.1.0.tgz#52740cb01ba477851086855f9857b3a44296ee0e"
-  integrity sha512-OZMF8I8TOu0S58Z/OS9mr8jkEzGAPByCsAkrWlcmZgPaE0RsxVKVIFPhbMNy/JlYswgGDYYIEsNw+e0j1FnTrw==
-  dependencies:
-    debug "^4.1.1"
-    promise-fs "^2.1.1"
-
-snyk-resolve@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/snyk-resolve/-/snyk-resolve-1.0.1.tgz#eaa4a275cf7e2b579f18da5b188fe601b8eed9ab"
-  integrity sha512-7+i+LLhtBo1Pkth01xv+RYJU8a67zmJ8WFFPvSxyCjdlKIcsps4hPQFebhz+0gC5rMemlaeIV6cqwqUf9PEDpw==
-  dependencies:
-    debug "^3.1.0"
-    then-fs "^2.0.0"
-
-snyk-sbt-plugin@2.11.0:
-  version "2.11.0"
-  resolved "https://registry.yarnpkg.com/snyk-sbt-plugin/-/snyk-sbt-plugin-2.11.0.tgz#f5469dcf5589e34575fc901e2064475582cc3e48"
-  integrity sha512-wUqHLAa3MzV6sVO+05MnV+lwc+T6o87FZZaY+43tQPytBI2Wq23O3j4POREM4fa2iFfiQJoEYD6c7xmhiEUsSA==
-  dependencies:
-    debug "^4.1.1"
-    semver "^6.1.2"
-    tmp "^0.1.0"
-    tree-kill "^1.2.2"
-    tslib "^1.10.0"
-
-snyk-tree@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/snyk-tree/-/snyk-tree-1.0.0.tgz#0fb73176dbf32e782f19100294160448f9111cc8"
-  integrity sha1-D7cxdtvzLngvGRAClBYESPkRHMg=
-  dependencies:
-    archy "^1.0.0"
-
-snyk-try-require@1.3.1, snyk-try-require@^1.1.1:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/snyk-try-require/-/snyk-try-require-1.3.1.tgz#6e026f92e64af7fcccea1ee53d524841e418a212"
-  integrity sha1-bgJvkuZK9/zM6h7lPVJIQeQYohI=
-  dependencies:
-    debug "^3.1.0"
-    lodash.clonedeep "^4.3.0"
-    lru-cache "^4.0.0"
-    then-fs "^2.0.0"
-
-snyk-try-require@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/snyk-try-require/-/snyk-try-require-2.0.1.tgz#076ae9bc505d64d28389452ce19fcac28f26655a"
-  integrity sha512-VCOfFIvqLMXgCXEdooQgu3A40XYIFBnj0X8Y01RJ5iAbu08b4WKGN/uAKaRVF30dABS4EcjsalmCO+YlKUPEIA==
-  dependencies:
-    debug "^4.1.1"
-    lodash.clonedeep "^4.3.0"
-    lru-cache "^5.1.1"
-
-snyk@^1.518.0:
-  version "1.564.0"
-  resolved "https://registry.yarnpkg.com/snyk/-/snyk-1.564.0.tgz#c8c511128351f8b8fe239b010b6799f40bb659c5"
-  integrity sha512-Fh4YusvJ9XdQfyz8JH9J8mBbipfgGLiF60MW9DYhQgP6h8z5uckAfd+S/uFMwPOVOIoe00fFo7aCLxFUuPcVJQ==
-  dependencies:
-    "@open-policy-agent/opa-wasm" "^1.2.0"
-    "@snyk/cli-interface" "2.11.0"
-    "@snyk/cloud-config-parser" "^1.9.2"
-    "@snyk/code-client" "3.4.1"
-    "@snyk/dep-graph" "^1.27.1"
-    "@snyk/fix" "1.554.0"
-    "@snyk/gemfile" "1.2.0"
-    "@snyk/graphlib" "^2.1.9-patch.3"
-    "@snyk/inquirer" "^7.3.3-patch"
-    "@snyk/snyk-cocoapods-plugin" "2.5.2"
-    "@snyk/snyk-hex-plugin" "1.1.4"
-    abbrev "^1.1.1"
-    ansi-escapes "3.2.0"
-    chalk "^2.4.2"
-    cli-spinner "0.2.10"
-    configstore "^5.0.1"
-    debug "^4.1.1"
-    diff "^4.0.1"
-    global-agent "^2.1.12"
-    lodash.assign "^4.2.0"
-    lodash.camelcase "^4.3.0"
-    lodash.clonedeep "^4.5.0"
-    lodash.endswith "^4.2.1"
-    lodash.flatten "^4.4.0"
-    lodash.flattendeep "^4.4.0"
-    lodash.get "^4.4.2"
-    lodash.groupby "^4.6.0"
-    lodash.isempty "^4.4.0"
-    lodash.isobject "^3.0.2"
-    lodash.map "^4.6.0"
-    lodash.omit "^4.5.0"
-    lodash.orderby "^4.6.0"
-    lodash.sortby "^4.7.0"
-    lodash.uniq "^4.5.0"
-    lodash.upperfirst "^4.3.1"
-    lodash.values "^4.3.0"
-    micromatch "4.0.2"
-    needle "2.6.0"
-    open "^7.0.3"
-    ora "5.3.0"
-    os-name "^3.0.0"
-    promise-queue "^2.2.5"
-    proxy-from-env "^1.0.0"
-    rimraf "^2.6.3"
-    semver "^6.0.0"
-    snyk-config "4.0.0"
-    snyk-cpp-plugin "2.2.1"
-    snyk-docker-plugin "4.19.3"
-    snyk-go-plugin "1.17.0"
-    snyk-gradle-plugin "3.14.2"
-    snyk-module "3.1.0"
-    snyk-mvn-plugin "2.25.3"
-    snyk-nodejs-lockfile-parser "1.32.0"
-    snyk-nuget-plugin "1.21.1"
-    snyk-php-plugin "1.9.2"
-    snyk-policy "1.19.0"
-    snyk-python-plugin "1.19.8"
-    snyk-resolve "1.1.0"
-    snyk-resolve-deps "4.7.2"
-    snyk-sbt-plugin "2.11.0"
-    snyk-tree "^1.0.0"
-    snyk-try-require "1.3.1"
-    source-map-support "^0.5.11"
-    strip-ansi "^5.2.0"
-    tar "^6.1.0"
-    tempfile "^2.0.0"
-    update-notifier "^4.1.0"
-    uuid "^3.3.2"
-    wrap-ansi "^5.1.0"
-
-source-map-support@^0.5.11, source-map-support@^0.5.7:
-  version "0.5.16"
-  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042"
-  integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==
-  dependencies:
-    buffer-from "^1.0.0"
-    source-map "^0.6.0"
-
-source-map@^0.6.0:
-  version "0.6.1"
-  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
-  integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
-
-split-ca@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/split-ca/-/split-ca-1.0.1.tgz#6c83aff3692fa61256e0cd197e05e9de157691a6"
-  integrity sha1-bIOv82kvphJW4M0ZfgXp3hV2kaY=
-
-sprintf-js@^1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
-  integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
-
-sprintf-js@~1.0.2:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
-  integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
-
-ssh2-streams@~0.4.10:
-  version "0.4.10"
-  resolved "https://registry.yarnpkg.com/ssh2-streams/-/ssh2-streams-0.4.10.tgz#48ef7e8a0e39d8f2921c30521d56dacb31d23a34"
-  integrity sha512-8pnlMjvnIZJvmTzUIIA5nT4jr2ZWNNVHwyXfMGdRJbug9TpI3kd99ffglgfSWqujVv/0gxwMsDn9j9RVst8yhQ==
-  dependencies:
-    asn1 "~0.2.0"
-    bcrypt-pbkdf "^1.0.2"
-    streamsearch "~0.1.2"
-
-ssh2@^0.8.7:
-  version "0.8.9"
-  resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-0.8.9.tgz#54da3a6c4ba3daf0d8477a538a481326091815f3"
-  integrity sha512-GmoNPxWDMkVpMFa9LVVzQZHF6EW3WKmBwL+4/GeILf2hFmix5Isxm7Amamo8o7bHiU0tC+wXsGcUXOxp8ChPaw==
-  dependencies:
-    ssh2-streams "~0.4.10"
-
-stream-buffers@^3.0.2:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-3.0.2.tgz#5249005a8d5c2d00b3a32e6e0a6ea209dc4f3521"
-  integrity sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==
-
-stream-shift@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
-  integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
-
-stream-to-array@~2.3.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/stream-to-array/-/stream-to-array-2.3.0.tgz#bbf6b39f5f43ec30bc71babcb37557acecf34353"
-  integrity sha1-u/azn19D7DC8cbq8s3VXrOzzQ1M=
-  dependencies:
-    any-promise "^1.1.0"
-
-stream-to-promise@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/stream-to-promise/-/stream-to-promise-2.2.0.tgz#b1edb2e1c8cb11289d1b503c08d3f2aef51e650f"
-  integrity sha1-se2y4cjLESidG1A8CNPyrvUeZQ8=
-  dependencies:
-    any-promise "~1.3.0"
-    end-of-stream "~1.1.0"
-    stream-to-array "~2.3.0"
-
-streamsearch@~0.1.2:
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
-  integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=
-
-string-width@^3.0.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
-  integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==
-  dependencies:
-    emoji-regex "^7.0.1"
-    is-fullwidth-code-point "^2.0.0"
-    strip-ansi "^5.1.0"
-
-string-width@^4.0.0, string-width@^4.1.0:
-  version "4.2.2"
-  resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5"
-  integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==
-  dependencies:
-    emoji-regex "^8.0.0"
-    is-fullwidth-code-point "^3.0.0"
-    strip-ansi "^6.0.0"
-
-string_decoder@^1.1.1:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
-  integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
-  dependencies:
-    safe-buffer "~5.2.0"
-
-string_decoder@~1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
-  integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
-  dependencies:
-    safe-buffer "~5.1.0"
-
-strip-ansi@6.0.0, strip-ansi@^6.0.0:
-  version "6.0.0"
-  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
-  integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
-  dependencies:
-    ansi-regex "^5.0.0"
-
-strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
-  version "5.2.0"
-  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
-  integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
-  dependencies:
-    ansi-regex "^4.1.0"
-
-strip-eof@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
-  integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
-
-strip-json-comments@~2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
-  integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
-
-supports-color@^5.3.0:
-  version "5.5.0"
-  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
-  integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
-  dependencies:
-    has-flag "^3.0.0"
-
-supports-color@^7.1.0:
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
-  integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
-  dependencies:
-    has-flag "^4.0.0"
-
-tar-stream@^2.0.1, tar-stream@^2.1.2:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
-  integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
-  dependencies:
-    bl "^4.0.3"
-    end-of-stream "^1.4.1"
-    fs-constants "^1.0.0"
-    inherits "^2.0.3"
-    readable-stream "^3.1.1"
-
-tar-stream@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.0.tgz#d1aaa3661f05b38b5acc9b7020efdca5179a2cc3"
-  integrity sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==
-  dependencies:
-    bl "^3.0.0"
-    end-of-stream "^1.4.1"
-    fs-constants "^1.0.0"
-    inherits "^2.0.3"
-    readable-stream "^3.1.1"
-
-tar@^6.1.0:
-  version "6.1.11"
-  resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621"
-  integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==
-  dependencies:
-    chownr "^2.0.0"
-    fs-minipass "^2.0.0"
-    minipass "^3.0.0"
-    minizlib "^2.1.1"
-    mkdirp "^1.0.3"
-    yallist "^4.0.0"
-
-temp-dir@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d"
-  integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=
-
-temp-dir@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e"
-  integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==
-
-tempfile@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-2.0.0.tgz#6b0446856a9b1114d1856ffcbe509cccb0977265"
-  integrity sha1-awRGhWqbERTRhW/8vlCczLCXcmU=
-  dependencies:
-    temp-dir "^1.0.0"
-    uuid "^3.0.1"
-
-term-size@^2.1.0:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54"
-  integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==
-
-then-fs@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/then-fs/-/then-fs-2.0.0.tgz#72f792dd9d31705a91ae19ebfcf8b3f968c81da2"
-  integrity sha1-cveS3Z0xcFqRrhnr/Piz+WjIHaI=
-  dependencies:
-    promise ">=3.2 <8"
-
-through2@^2.0.3:
-  version "2.0.5"
-  resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
-  integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
-  dependencies:
-    readable-stream "~2.3.6"
-    xtend "~4.0.1"
-
-through@^2.3.6:
-  version "2.3.8"
-  resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
-  integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
-
-tmp@0.0.33, tmp@^0.0.33:
-  version "0.0.33"
-  resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
-  integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
-  dependencies:
-    os-tmpdir "~1.0.2"
-
-tmp@0.2.1, tmp@^0.2.1:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
-  integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==
-  dependencies:
-    rimraf "^3.0.0"
-
-tmp@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877"
-  integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==
-  dependencies:
-    rimraf "^2.6.3"
-
-to-readable-stream@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771"
-  integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==
-
-to-regex-range@^5.0.1:
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
-  integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
-  dependencies:
-    is-number "^7.0.0"
-
-toml@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee"
-  integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==
-
-tree-kill@^1.2.2:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
-  integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
-
-treeify@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/treeify/-/treeify-1.1.0.tgz#4e31c6a463accd0943879f30667c4fdaff411bb8"
-  integrity sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==
-
-tslib@1.11.1:
-  version "1.11.1"
-  resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
-  integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==
-
-tslib@^1, tslib@^1.10.0, tslib@^1.9.0, tslib@^1.9.3:
-  version "1.10.0"
-  resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
-  integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
-
-tslib@^1.11.2, tslib@^1.13.0:
-  version "1.14.1"
-  resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
-  integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
-
-tslib@^2.0.0, tslib@^2.1.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c"
-  integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==
-
-tunnel@^0.0.6:
-  version "0.0.6"
-  resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
-  integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
-
-tweetnacl@^0.14.3:
-  version "0.14.5"
-  resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
-  integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
-
-type-fest@^0.13.1:
-  version "0.13.1"
-  resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
-  integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
-
-type-fest@^0.21.3:
-  version "0.21.3"
-  resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
-  integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
-
-type-fest@^0.8.1:
-  version "0.8.1"
-  resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
-  integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
-
-typedarray-to-buffer@^3.1.5:
-  version "3.1.5"
-  resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
-  integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==
-  dependencies:
-    is-typedarray "^1.0.0"
-
-unique-string@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d"
-  integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==
-  dependencies:
-    crypto-random-string "^2.0.0"
-
-upath@2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b"
-  integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==
-
-update-notifier@^4.1.0:
-  version "4.1.3"
-  resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.3.tgz#be86ee13e8ce48fb50043ff72057b5bd598e1ea3"
-  integrity sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==
-  dependencies:
-    boxen "^4.2.0"
-    chalk "^3.0.0"
-    configstore "^5.0.1"
-    has-yarn "^2.1.0"
-    import-lazy "^2.1.0"
-    is-ci "^2.0.0"
-    is-installed-globally "^0.3.1"
-    is-npm "^4.0.0"
-    is-yarn-global "^0.3.0"
-    latest-version "^5.0.0"
-    pupa "^2.0.1"
-    semver-diff "^3.1.1"
-    xdg-basedir "^4.0.0"
-
-url-parse-lax@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
-  integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=
-  dependencies:
-    prepend-http "^2.0.0"
-
-utf8@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1"
-  integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==
-
-util-deprecate@^1.0.1, util-deprecate@~1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
-  integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
-
-uuid@^3.0.1, uuid@^3.3.2:
-  version "3.4.0"
-  resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
-  integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
-
-uuid@^8.2.0, uuid@^8.3.0, uuid@^8.3.2:
-  version "8.3.2"
-  resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
-  integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
-
-vscode-languageserver-types@^3.16.0:
-  version "3.16.0"
-  resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz#ecf393fc121ec6974b2da3efb3155644c514e247"
-  integrity sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==
-
-wcwidth@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
-  integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=
-  dependencies:
-    defaults "^1.0.3"
-
-which@^1.2.9:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
-  integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
-  dependencies:
-    isexe "^2.0.0"
-
-which@^2.0.1:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
-  integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
-  dependencies:
-    isexe "^2.0.0"
-
-widest-line@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca"
-  integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==
-  dependencies:
-    string-width "^4.0.0"
-
-windows-release@^3.1.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.2.0.tgz#8122dad5afc303d833422380680a79cdfa91785f"
-  integrity sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==
-  dependencies:
-    execa "^1.0.0"
-
-wrap-ansi@^5.1.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09"
-  integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==
-  dependencies:
-    ansi-styles "^3.2.0"
-    string-width "^3.0.0"
-    strip-ansi "^5.0.0"
-
-wrappy@1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
-  integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-
-write-file-atomic@^3.0.0:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8"
-  integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==
-  dependencies:
-    imurmurhash "^0.1.4"
-    is-typedarray "^1.0.0"
-    signal-exit "^3.0.2"
-    typedarray-to-buffer "^3.1.5"
-
-xdg-basedir@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
-  integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==
-
-xml-js@^1.6.11:
-  version "1.6.11"
-  resolved "https://registry.yarnpkg.com/xml-js/-/xml-js-1.6.11.tgz#927d2f6947f7f1c19a316dd8eea3614e8b18f8e9"
-  integrity sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==
-  dependencies:
-    sax "^1.2.4"
-
-xml2js@0.4.23, xml2js@^0.4.17:
-  version "0.4.23"
-  resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66"
-  integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==
-  dependencies:
-    sax ">=0.6.0"
-    xmlbuilder "~11.0.0"
-
-xmlbuilder@~11.0.0:
-  version "11.0.1"
-  resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
-  integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
-
-xtend@~4.0.1:
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
-  integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
-
-yallist@^2.1.2:
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
-  integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
-
-yallist@^3.0.2:
-  version "3.1.1"
-  resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
-  integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
-
-yallist@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
-  integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
-
-yaml-js@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/yaml-js/-/yaml-js-0.3.0.tgz#ad0893d9de881a93fd6bf936e8d89cdde309e848"
-  integrity sha512-JbTUdsPiCkOyz+JOSqAVc19omTnUBnBQglhuclYov5HpWbEOz8y+ftqWjiMa9Pe/eF/dmCUeNgVs/VWg53GlgQ==
-
-yaml@^1.9.2:
-  version "1.10.2"
-  resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
-  integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==