Merge branch 'develop' into make-against-field-dynamic
diff --git a/.github/helper/install.sh b/.github/helper/install.sh
index d1a97f8..915a463 100644
--- a/.github/helper/install.sh
+++ b/.github/helper/install.sh
@@ -4,7 +4,9 @@
 
 cd ~ || exit
 
-sudo apt update && sudo apt install redis-server libcups2-dev
+sudo apt update
+sudo apt remove mysql-server mysql-client
+sudo apt install libcups2-dev redis-server mariadb-client-10.6
 
 pip install frappe-bench
 
@@ -25,14 +27,14 @@
 
 
 if [ "$DB" == "mariadb" ];then
-    mysql --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL character_set_server = 'utf8mb4'"
-    mysql --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'"
+    mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL character_set_server = 'utf8mb4'"
+    mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'"
 
-    mysql --host 127.0.0.1 --port 3306 -u root -proot -e "CREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe'"
-    mysql --host 127.0.0.1 --port 3306 -u root -proot -e "CREATE DATABASE test_frappe"
-    mysql --host 127.0.0.1 --port 3306 -u root -proot -e "GRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost'"
+    mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "CREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe'"
+    mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "CREATE DATABASE test_frappe"
+    mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "GRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost'"
 
-    mysql --host 127.0.0.1 --port 3306 -u root -proot -e "FLUSH PRIVILEGES"
+    mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "FLUSH PRIVILEGES"
 fi
 
 if [ "$DB" == "postgres" ];then
diff --git a/.github/workflows/initiate_release.yml b/.github/workflows/initiate_release.yml
index ee60bad..e51c194 100644
--- a/.github/workflows/initiate_release.yml
+++ b/.github/workflows/initiate_release.yml
@@ -15,7 +15,7 @@
     strategy:
       fail-fast: false
       matrix:
-        version: ["13", "14"]
+        version: ["13", "14", "15"]
 
     steps:
       - uses: octokit/request-action@v2.x
@@ -30,23 +30,3 @@
           head: version-${{ matrix.version }}-hotfix
         env:
           GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
-
-  beta-release:
-    name: Release
-    runs-on: ubuntu-latest
-    strategy:
-      fail-fast: false
-
-    steps:
-      - uses: octokit/request-action@v2.x
-        with:
-          route: POST /repos/{owner}/{repo}/pulls
-          owner: frappe
-          repo: erpnext
-          title: |-
-            "chore: release v15 beta"
-          body: "Automated beta release."
-          base: version-15-beta
-          head: develop
-        env:
-          GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
diff --git a/.github/workflows/patch.yml b/.github/workflows/patch.yml
index 07b8de7..3514f0d 100644
--- a/.github/workflows/patch.yml
+++ b/.github/workflows/patch.yml
@@ -28,7 +28,7 @@
           MARIADB_ROOT_PASSWORD: 'root'
         ports:
           - 3306:3306
-        options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
+        options: --health-cmd="mariadb-admin ping" --health-interval=5s --health-timeout=2s --health-retries=3
 
     steps:
       - name: Clone
@@ -134,6 +134,7 @@
           }
 
           update_to_version 14
+          update_to_version 15
 
           echo "Updating to latest version"
           git -C "apps/frappe" checkout -q -f "${GITHUB_BASE_REF:-${GITHUB_REF##*/}}"
diff --git a/.github/workflows/server-tests-mariadb.yml b/.github/workflows/server-tests-mariadb.yml
index 559be06..ccdfc8c 100644
--- a/.github/workflows/server-tests-mariadb.yml
+++ b/.github/workflows/server-tests-mariadb.yml
@@ -47,7 +47,7 @@
           MARIADB_ROOT_PASSWORD: 'root'
         ports:
           - 3306:3306
-        options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
+        options: --health-cmd="mariadb-admin ping" --health-interval=5s --health-timeout=2s --health-retries=3
 
     steps:
       - name: Clone
diff --git a/.mergify.yml b/.mergify.yml
index 804b27d..5359606 100644
--- a/.mergify.yml
+++ b/.mergify.yml
@@ -17,6 +17,7 @@
           - base=version-12
           - base=version-14
           - base=version-15
+          - base=version-16
     actions:
       close:
       comment:
@@ -24,16 +25,6 @@
             @{{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: Auto-close PRs on pre-release branch
-    conditions:
-      - base=version-13-pre-release
-    actions:
-      close:
-      comment:
-          message: |
-            @{{author}}, pre-release branch is not maintained anymore. Releases are directly done by merging hotfix branch to stable branches.
-
-
   - name: backport to develop
     conditions:
       - label="backport develop"
@@ -54,13 +45,13 @@
         assignees:
           - "{{ author }}"
 
-  - name: backport to version-14-pre-release
+  - name: backport to version-15-hotfix
     conditions:
-      - label="backport version-14-pre-release"
+      - label="backport version-15-hotfix"
     actions:
       backport:
         branches:
-          - version-14-pre-release
+          - version-15-hotfix
         assignees:
           - "{{ author }}"
 
@@ -74,35 +65,6 @@
         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 }}"
 
   - name: Automatic merge on CI success and review
     conditions:
diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/verified/ni_catalogo_de_cuentas.json b/erpnext/accounts/doctype/account/chart_of_accounts/verified/ni_catalogo_de_cuentas.json
index e8402d6..73ac4ab 100644
--- a/erpnext/accounts/doctype/account/chart_of_accounts/verified/ni_catalogo_de_cuentas.json
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/verified/ni_catalogo_de_cuentas.json
@@ -1,6 +1,6 @@
 {
     "country_code": "ni", 
-    "name": "Nicaragua - Catalogo de Cuentas", 
+    "name": "Nicaragua - Catálogo de Cuentas", 
     "tree": {
         "Activo": {
             "Activo Corriente": {
@@ -491,4 +491,4 @@
             "root_type": "Liability"
         }
     }
-}
\ No newline at end of file
+}
diff --git a/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py b/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py
index e75af70..d06bd83 100644
--- a/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py
+++ b/erpnext/accounts/doctype/account_closing_balance/account_closing_balance.py
@@ -37,6 +37,7 @@
 			}
 		)
 		cle.flags.ignore_permissions = True
+		cle.flags.ignore_links = True
 		cle.submit()
 
 
diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
index 3a2c3cb..8f76492 100644
--- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
+++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
@@ -302,3 +302,30 @@
 		default_dimensions_map[dimension.company][dimension.fieldname] = dimension.default_dimension
 
 	return dimension_filters, default_dimensions_map
+
+
+def create_accounting_dimensions_for_doctype(doctype):
+	accounting_dimensions = frappe.db.get_all(
+		"Accounting Dimension", fields=["fieldname", "label", "document_type", "disabled"]
+	)
+
+	if not accounting_dimensions:
+		return
+
+	for d in accounting_dimensions:
+		field = frappe.db.get_value("Custom Field", {"dt": doctype, "fieldname": d.fieldname})
+
+		if field:
+			continue
+
+		df = {
+			"fieldname": d.fieldname,
+			"label": d.label,
+			"fieldtype": "Link",
+			"options": d.document_type,
+			"insert_after": "accounting_dimensions_section",
+		}
+
+		create_custom_field(doctype, df, ignore_validate=True)
+
+	frappe.clear_cache(doctype=doctype)
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
index 6857ba3..061bab3 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
@@ -32,6 +32,7 @@
   "column_break_19",
   "add_taxes_from_item_tax_template",
   "book_tax_discount_loss",
+  "round_row_wise_tax",
   "print_settings",
   "show_inclusive_tax_in_print",
   "show_taxes_as_table_in_print",
@@ -414,6 +415,13 @@
    "fieldname": "ignore_account_closing_balance",
    "fieldtype": "Check",
    "label": "Ignore Account Closing Balance"
+  },
+  {
+   "default": "0",
+   "description": "Tax Amount will be rounded on a row(items) level",
+   "fieldname": "round_row_wise_tax",
+   "fieldtype": "Check",
+   "label": "Round Tax Amount Row-wise"
   }
  ],
  "icon": "icon-cog",
@@ -421,7 +429,7 @@
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2023-07-27 15:05:34.000264",
+ "modified": "2023-08-28 00:12:02.740633",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Accounts Settings",
diff --git a/erpnext/accounts/doctype/bank_account/bank_account.json b/erpnext/accounts/doctype/bank_account/bank_account.json
index 41d7947..32f1c67 100644
--- a/erpnext/accounts/doctype/bank_account/bank_account.json
+++ b/erpnext/accounts/doctype/bank_account/bank_account.json
@@ -13,6 +13,7 @@
   "account_type",
   "account_subtype",
   "column_break_7",
+  "disabled",
   "is_default",
   "is_company_account",
   "company",
@@ -199,10 +200,16 @@
    "fieldtype": "Data",
    "in_global_search": 1,
    "label": "Branch Code"
+  },
+  {
+   "default": "0",
+   "fieldname": "disabled",
+   "fieldtype": "Check",
+   "label": "Disabled"
   }
  ],
  "links": [],
- "modified": "2022-05-04 15:49:42.620630",
+ "modified": "2023-09-22 21:31:34.763977",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Bank Account",
diff --git a/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py b/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py
index c7404d1..ace751b 100644
--- a/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py
+++ b/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py
@@ -35,13 +35,14 @@
 		from lending.loan_management.doctype.loan.test_loan import (
 			create_loan,
 			create_loan_accounts,
-			create_loan_type,
+			create_loan_product,
 			create_repayment_entry,
 			make_loan_disbursement_entry,
 		)
 
 		def create_loan_masters():
-			create_loan_type(
+			create_loan_product(
+				"Clearance Loan",
 				"Clearance Loan",
 				2000000,
 				13.5,
diff --git a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py
index 9a7a9a3..7e2f763 100644
--- a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py
+++ b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py
@@ -18,6 +18,7 @@
 	get_entries,
 )
 from erpnext.accounts.utils import get_account_currency, get_balance_on
+from erpnext.setup.utils import get_exchange_rate
 
 
 class BankReconciliationTool(Document):
@@ -130,7 +131,7 @@
 	bank_transaction = frappe.db.get_values(
 		"Bank Transaction",
 		bank_transaction_name,
-		fieldname=["name", "deposit", "withdrawal", "bank_account"],
+		fieldname=["name", "deposit", "withdrawal", "bank_account", "currency"],
 		as_dict=True,
 	)[0]
 	company_account = frappe.get_value("Bank Account", bank_transaction.bank_account, "account")
@@ -144,29 +145,94 @@
 			)
 
 	company = frappe.get_value("Account", company_account, "company")
+	company_default_currency = frappe.get_cached_value("Company", company, "default_currency")
+	company_account_currency = frappe.get_cached_value("Account", company_account, "account_currency")
+	second_account_currency = frappe.get_cached_value("Account", second_account, "account_currency")
+
+	# determine if multi-currency Journal or not
+	is_multi_currency = (
+		True
+		if company_default_currency != company_account_currency
+		or company_default_currency != second_account_currency
+		or company_default_currency != bank_transaction.currency
+		else False
+	)
 
 	accounts = []
-	# Multi Currency?
-	accounts.append(
-		{
-			"account": second_account,
-			"credit_in_account_currency": bank_transaction.deposit,
-			"debit_in_account_currency": bank_transaction.withdrawal,
-			"party_type": party_type,
-			"party": party,
-			"cost_center": get_default_cost_center(company),
-		}
-	)
+	second_account_dict = {
+		"account": second_account,
+		"account_currency": second_account_currency,
+		"credit_in_account_currency": bank_transaction.deposit,
+		"debit_in_account_currency": bank_transaction.withdrawal,
+		"party_type": party_type,
+		"party": party,
+		"cost_center": get_default_cost_center(company),
+	}
 
-	accounts.append(
-		{
-			"account": company_account,
-			"bank_account": bank_transaction.bank_account,
-			"credit_in_account_currency": bank_transaction.withdrawal,
-			"debit_in_account_currency": bank_transaction.deposit,
-			"cost_center": get_default_cost_center(company),
-		}
-	)
+	company_account_dict = {
+		"account": company_account,
+		"account_currency": company_account_currency,
+		"bank_account": bank_transaction.bank_account,
+		"credit_in_account_currency": bank_transaction.withdrawal,
+		"debit_in_account_currency": bank_transaction.deposit,
+		"cost_center": get_default_cost_center(company),
+	}
+
+	# convert transaction amount to company currency
+	if is_multi_currency:
+		exc_rate = get_exchange_rate(bank_transaction.currency, company_default_currency, posting_date)
+		withdrawal_in_company_currency = flt(exc_rate * abs(bank_transaction.withdrawal))
+		deposit_in_company_currency = flt(exc_rate * abs(bank_transaction.deposit))
+	else:
+		withdrawal_in_company_currency = bank_transaction.withdrawal
+		deposit_in_company_currency = bank_transaction.deposit
+
+	# if second account is of foreign currency, convert and set debit and credit fields.
+	if second_account_currency != company_default_currency:
+		exc_rate = get_exchange_rate(second_account_currency, company_default_currency, posting_date)
+		second_account_dict.update(
+			{
+				"exchange_rate": exc_rate,
+				"credit": deposit_in_company_currency,
+				"debit": withdrawal_in_company_currency,
+				"credit_in_account_currency": flt(deposit_in_company_currency / exc_rate) or 0,
+				"debit_in_account_currency": flt(withdrawal_in_company_currency / exc_rate) or 0,
+			}
+		)
+	else:
+		second_account_dict.update(
+			{
+				"exchange_rate": 1,
+				"credit": deposit_in_company_currency,
+				"debit": withdrawal_in_company_currency,
+				"credit_in_account_currency": deposit_in_company_currency,
+				"debit_in_account_currency": withdrawal_in_company_currency,
+			}
+		)
+
+	# if company account is of foreign currency, convert and set debit and credit fields.
+	if company_account_currency != company_default_currency:
+		exc_rate = get_exchange_rate(company_account_currency, company_default_currency, posting_date)
+		company_account_dict.update(
+			{
+				"exchange_rate": exc_rate,
+				"credit": withdrawal_in_company_currency,
+				"debit": deposit_in_company_currency,
+			}
+		)
+	else:
+		company_account_dict.update(
+			{
+				"exchange_rate": 1,
+				"credit": withdrawal_in_company_currency,
+				"debit": deposit_in_company_currency,
+				"credit_in_account_currency": withdrawal_in_company_currency,
+				"debit_in_account_currency": deposit_in_company_currency,
+			}
+		)
+
+	accounts.append(second_account_dict)
+	accounts.append(company_account_dict)
 
 	journal_entry_dict = {
 		"voucher_type": entry_type,
@@ -176,6 +242,9 @@
 		"cheque_no": reference_number,
 		"mode_of_payment": mode_of_payment,
 	}
+	if is_multi_currency:
+		journal_entry_dict.update({"multi_currency": True})
+
 	journal_entry = frappe.new_doc("Journal Entry")
 	journal_entry.update(journal_entry_dict)
 	journal_entry.set("accounts", accounts)
diff --git a/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.js b/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.js
index 04af323..db68dfa 100644
--- a/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.js
+++ b/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.js
@@ -2,6 +2,16 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on("Bank Statement Import", {
+	onload(frm) {
+		frm.set_query("bank_account", function (doc) {
+			return {
+				filters: {
+					company: doc.company,
+				},
+			};
+		});
+	},
+
 	setup(frm) {
 		frappe.realtime.on("data_import_refresh", ({ data_import }) => {
 			frm.import_in_progress = false;
@@ -352,10 +362,11 @@
 
 	export_errored_rows(frm) {
 		open_url_post(
-			"/api/method/frappe.core.doctype.data_import.data_import.download_errored_template",
+			"/api/method/erpnext.accounts.doctype.bank_statement_import.bank_statement_import.download_errored_template",
 			{
 				data_import_name: frm.doc.name,
-			}
+			},
+			true
 		);
 	},
 
diff --git a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py
index 5d94a08..04dab4c 100644
--- a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py
+++ b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py
@@ -112,7 +112,8 @@
 
 		for party in parties:
 			filters = {"status": "Active"} if party == "Employee" else {"disabled": 0}
-			names = frappe.get_all(party, filters=filters, pluck=party.lower() + "_name")
+			field = party.lower() + "_name"
+			names = frappe.get_all(party, filters=filters, fields=[f"{field} as party_name", "name"])
 
 			for field in ["bank_party_name", "description"]:
 				if not self.get(field):
@@ -131,7 +132,11 @@
 
 	def fuzzy_search_and_return_result(self, party, names, field) -> Union[Tuple, None]:
 		skip = False
-		result = process.extract(query=self.get(field), choices=names, scorer=fuzz.token_set_ratio)
+		result = process.extract(
+			query=self.get(field),
+			choices={row.get("name"): row.get("party_name") for row in names},
+			scorer=fuzz.token_set_ratio,
+		)
 		party_name, skip = self.process_fuzzy_result(result)
 
 		if not party_name:
@@ -149,14 +154,14 @@
 
 		Returns: Result, Skip (whether or not to discontinue matching)
 		"""
-		PARTY, SCORE, CUTOFF = 0, 1, 80
+		SCORE, PARTY_ID, CUTOFF = 1, 2, 80
 
 		if not result or not len(result):
 			return None, False
 
 		first_result = result[0]
 		if len(result) == 1:
-			return (first_result[PARTY] if first_result[SCORE] > CUTOFF else None), True
+			return (first_result[PARTY_ID] if first_result[SCORE] > CUTOFF else None), True
 
 		second_result = result[1]
 		if first_result[SCORE] > CUTOFF:
@@ -165,7 +170,7 @@
 			if first_result[SCORE] == second_result[SCORE]:
 				return None, True
 
-			return first_result[PARTY], True
+			return first_result[PARTY_ID], True
 		else:
 			return None, False
 
diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py
index 6a47562..4649d23 100644
--- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py
+++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py
@@ -89,7 +89,6 @@
 		    - 0 > a: Error: already over-allocated
 		- clear means: set the latest transaction date as clearance date
 		"""
-		gl_bank_account = frappe.db.get_value("Bank Account", self.bank_account, "account")
 		remaining_amount = self.unallocated_amount
 		for payment_entry in self.payment_entries:
 			if payment_entry.allocated_amount == 0.0:
diff --git a/erpnext/accounts/doctype/bank_transaction/test_bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/test_bank_transaction.py
index 0c328ff..4a6491d 100644
--- a/erpnext/accounts/doctype/bank_transaction/test_bank_transaction.py
+++ b/erpnext/accounts/doctype/bank_transaction/test_bank_transaction.py
@@ -410,7 +410,7 @@
 def create_loan_and_repayment():
 	from lending.loan_management.doctype.loan.test_loan import (
 		create_loan,
-		create_loan_type,
+		create_loan_product,
 		create_repayment_entry,
 		make_loan_disbursement_entry,
 	)
@@ -420,7 +420,8 @@
 
 	from erpnext.setup.doctype.employee.test_employee import make_employee
 
-	create_loan_type(
+	create_loan_product(
+		"Personal Loan",
 		"Personal Loan",
 		500000,
 		8.4,
@@ -441,7 +442,7 @@
 			"applicant_type": "Employee",
 			"company": "_Test Company",
 			"applicant": applicant,
-			"loan_type": "Personal Loan",
+			"loan_product": "Personal Loan",
 			"loan_amount": 5000,
 			"repayment_method": "Repay Fixed Amount per Period",
 			"monthly_repayment_amount": 500,
diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json
index c62b711..df232a5 100644
--- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json
+++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json
@@ -9,6 +9,7 @@
   "disabled",
   "service_provider",
   "api_endpoint",
+  "access_key",
   "url",
   "column_break_3",
   "help",
@@ -84,12 +85,18 @@
    "fieldname": "disabled",
    "fieldtype": "Check",
    "label": "Disabled"
+  },
+  {
+   "depends_on": "eval:doc.service_provider == 'exchangerate.host';",
+   "fieldname": "access_key",
+   "fieldtype": "Data",
+   "label": "Access Key"
   }
  ],
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2023-01-09 12:19:03.955906",
+ "modified": "2023-10-04 15:30:25.333860",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Currency Exchange Settings",
diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py
index d618c5c..117d5ff 100644
--- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py
+++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py
@@ -18,11 +18,21 @@
 
 	def set_parameters_and_result(self):
 		if self.service_provider == "exchangerate.host":
+
+			if not self.access_key:
+				frappe.throw(
+					_("Access Key is required for Service Provider: {0}").format(
+						frappe.bold(self.service_provider)
+					)
+				)
+
 			self.set("result_key", [])
 			self.set("req_params", [])
 
 			self.api_endpoint = "https://api.exchangerate.host/convert"
 			self.append("result_key", {"key": "result"})
+			self.append("req_params", {"key": "access_key", "value": self.access_key})
+			self.append("req_params", {"key": "amount", "value": "1"})
 			self.append("req_params", {"key": "date", "value": "{transaction_date}"})
 			self.append("req_params", {"key": "from", "value": "{from_currency}"})
 			self.append("req_params", {"key": "to", "value": "{to_currency}"})
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js
index cdd1203..22b6880 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.js
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js
@@ -53,7 +53,15 @@
 
 		erpnext.accounts.unreconcile_payments.add_unreconcile_btn(frm);
 	},
-
+	before_save: function(frm) {
+		if ((frm.doc.docstatus == 0) && (!frm.doc.is_system_generated)) {
+			let payment_entry_references = frm.doc.accounts.filter(elem => (elem.reference_type == "Payment Entry"));
+			if (payment_entry_references.length > 0) {
+				let rows = payment_entry_references.map(x => "#"+x.idx);
+				frappe.throw(__("Rows: {0} have 'Payment Entry' as reference_type. This should not be set manually.", [frappe.utils.comma_and(rows)]));
+			}
+		}
+	},
 	make_inter_company_journal_entry: function(frm) {
 		var d = new frappe.ui.Dialog({
 			title: __("Select Company"),
diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/test_opening_invoice_creation_tool.py b/erpnext/accounts/doctype/opening_invoice_creation_tool/test_opening_invoice_creation_tool.py
index 1e22c64..02c2c67 100644
--- a/erpnext/accounts/doctype/opening_invoice_creation_tool/test_opening_invoice_creation_tool.py
+++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/test_opening_invoice_creation_tool.py
@@ -218,6 +218,7 @@
 			"territory": "All Territories",
 		}
 	)
+
 	if not frappe.db.exists("Customer", customer_name):
 		customer.insert(ignore_permissions=True)
 		return customer.name
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 6cfc072..ff558b2 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -271,16 +271,18 @@
 
 				# if no payment template is used by invoice and has a custom term(no `payment_term`), then invoice outstanding will be in 'None' key
 				latest = latest.get(d.payment_term) or latest.get(None)
-
 				# The reference has already been fully paid
 				if not latest:
 					frappe.throw(
 						_("{0} {1} has already been fully paid.").format(_(d.reference_doctype), d.reference_name)
 					)
 				# The reference has already been partly paid
-				elif latest.outstanding_amount < latest.invoice_amount and flt(
-					d.outstanding_amount, d.precision("outstanding_amount")
-				) != flt(latest.outstanding_amount, d.precision("outstanding_amount")):
+				elif (
+					latest.outstanding_amount < latest.invoice_amount
+					and flt(d.outstanding_amount, d.precision("outstanding_amount"))
+					!= flt(latest.outstanding_amount, d.precision("outstanding_amount"))
+					and d.payment_term == ""
+				):
 					frappe.throw(
 						_(
 							"{0} {1} has already been partly paid. Please use the 'Get Outstanding Invoice' or the 'Get Outstanding Orders' button to get the latest outstanding amounts."
@@ -1758,11 +1760,10 @@
 										"voucher_type": d.voucher_type,
 										"posting_date": d.posting_date,
 										"invoice_amount": flt(d.invoice_amount),
-										"outstanding_amount": flt(d.outstanding_amount),
-										"payment_term_outstanding": payment_term_outstanding,
-										"allocated_amount": payment_term_outstanding
+										"outstanding_amount": payment_term_outstanding
 										if payment_term_outstanding
 										else d.outstanding_amount,
+										"payment_term_outstanding": payment_term_outstanding,
 										"payment_amount": payment_term.payment_amount,
 										"payment_term": payment_term.payment_term,
 										"account": d.account,
diff --git a/erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.json b/erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.json
index 9cf2ac6..28c9529 100644
--- a/erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.json
+++ b/erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.json
@@ -30,7 +30,8 @@
   {
    "fieldname": "posting_date",
    "fieldtype": "Date",
-   "label": "Posting Date"
+   "label": "Posting Date",
+   "search_index": 1
   },
   {
    "fieldname": "account_type",
@@ -64,7 +65,8 @@
    "fieldtype": "Link",
    "in_standard_filter": 1,
    "label": "Voucher Type",
-   "options": "DocType"
+   "options": "DocType",
+   "search_index": 1
   },
   {
    "fieldname": "voucher_no",
@@ -72,14 +74,16 @@
    "in_list_view": 1,
    "in_standard_filter": 1,
    "label": "Voucher No",
-   "options": "voucher_type"
+   "options": "voucher_type",
+   "search_index": 1
   },
   {
    "fieldname": "against_voucher_type",
    "fieldtype": "Link",
    "in_standard_filter": 1,
    "label": "Against Voucher Type",
-   "options": "DocType"
+   "options": "DocType",
+   "search_index": 1
   },
   {
    "fieldname": "against_voucher_no",
@@ -87,7 +91,8 @@
    "in_list_view": 1,
    "in_standard_filter": 1,
    "label": "Against Voucher No",
-   "options": "against_voucher_type"
+   "options": "against_voucher_type",
+   "search_index": 1
   },
   {
    "fieldname": "amount",
@@ -147,13 +152,14 @@
   {
    "fieldname": "voucher_detail_no",
    "fieldtype": "Data",
-   "label": "Voucher Detail No"
+   "label": "Voucher Detail No",
+   "search_index": 1
   }
  ],
  "in_create": 1,
  "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2023-06-29 12:24:20.500632",
+ "modified": "2023-11-03 16:39:58.904113",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Ledger Entry",
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
index d9f00be..fc90c3d 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
@@ -229,6 +229,7 @@
 			this.data = [];
 			const dialog = new frappe.ui.Dialog({
 				title: __("Select Difference Account"),
+				size: 'extra-large',
 				fields: [
 					{
 						fieldname: "allocation",
@@ -252,6 +253,13 @@
 							in_list_view: 1,
 							read_only: 1
 						}, {
+							fieldtype:'Date',
+							fieldname:"gain_loss_posting_date",
+							label: __("Posting Date"),
+							in_list_view: 1,
+							reqd: 1,
+						}, {
+
 							fieldtype:'Link',
 							options: 'Account',
 							in_list_view: 1,
@@ -285,6 +293,9 @@
 					args.forEach(d => {
 						frappe.model.set_value("Payment Reconciliation Allocation", d.docname,
 							"difference_account", d.difference_account);
+						frappe.model.set_value("Payment Reconciliation Allocation", d.docname,
+							"gain_loss_posting_date", d.gain_loss_posting_date);
+
 					});
 
 					this.reconcile_payment_entries();
@@ -300,6 +311,7 @@
 						'reference_name': d.reference_name,
 						'difference_amount': d.difference_amount,
 						'difference_account': d.difference_account,
+						'gain_loss_posting_date': d.gain_loss_posting_date
 					});
 				}
 			});
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
index 3285a52..43167be 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
@@ -109,6 +109,8 @@
 			"t2.against_account like %(bank_cash_account)s" if self.bank_cash_account else "1=1"
 		)
 
+		limit = f"limit {self.payment_limit}" if self.payment_limit else " "
+
 		# nosemgrep
 		journal_entries = frappe.db.sql(
 			"""
@@ -132,11 +134,13 @@
 					ELSE {bank_account_condition}
 				END)
 			order by t1.posting_date
+			{limit}
 			""".format(
 				**{
 					"dr_or_cr": dr_or_cr,
 					"bank_account_condition": bank_account_condition,
 					"condition": condition,
+					"limit": limit,
 				}
 			),
 			{
@@ -162,7 +166,7 @@
 		if self.payment_name:
 			conditions.append(doc.name.like(f"%{self.payment_name}%"))
 
-		self.return_invoices = (
+		self.return_invoices_query = (
 			qb.from_(doc)
 			.select(
 				ConstantColumn(voucher_type).as_("voucher_type"),
@@ -170,8 +174,11 @@
 				doc.return_against,
 			)
 			.where(Criterion.all(conditions))
-			.run(as_dict=True)
 		)
+		if self.payment_limit:
+			self.return_invoices_query = self.return_invoices_query.limit(self.payment_limit)
+
+		self.return_invoices = self.return_invoices_query.run(as_dict=True)
 
 	def get_dr_or_cr_notes(self):
 
@@ -328,6 +335,7 @@
 				res.difference_amount = self.get_difference_amount(pay, inv, res["allocated_amount"])
 				res.difference_account = default_exchange_gain_loss_account
 				res.exchange_rate = inv.get("exchange_rate")
+				res.update({"gain_loss_posting_date": pay.get("posting_date")})
 
 				if pay.get("amount") == 0:
 					entries.append(res)
@@ -434,6 +442,7 @@
 				"allocated_amount": flt(row.get("allocated_amount")),
 				"difference_amount": flt(row.get("difference_amount")),
 				"difference_account": row.get("difference_account"),
+				"difference_posting_date": row.get("gain_loss_posting_date"),
 				"cost_center": row.get("cost_center"),
 			}
 		)
diff --git a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
index 1d843ab..71bc498 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
@@ -14,6 +14,7 @@
 from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
 from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
 from erpnext.accounts.party import get_party_account
+from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
 from erpnext.stock.doctype.item.test_item import create_item
 
 test_dependencies = ["Item"]
@@ -85,26 +86,44 @@
 		self.customer5 = make_customer("_Test PR Customer 5", "EUR")
 
 	def create_account(self):
-		account_name = "Debtors EUR"
-		if not frappe.db.get_value(
-			"Account", filters={"account_name": account_name, "company": self.company}
-		):
-			acc = frappe.new_doc("Account")
-			acc.account_name = account_name
-			acc.parent_account = "Accounts Receivable - _PR"
-			acc.company = self.company
-			acc.account_currency = "EUR"
-			acc.account_type = "Receivable"
-			acc.insert()
-		else:
-			name = frappe.db.get_value(
-				"Account",
-				filters={"account_name": account_name, "company": self.company},
-				fieldname="name",
-				pluck=True,
-			)
-			acc = frappe.get_doc("Account", name)
-		self.debtors_eur = acc.name
+		accounts = [
+			{
+				"attribute": "debtors_eur",
+				"account_name": "Debtors EUR",
+				"parent_account": "Accounts Receivable - _PR",
+				"account_currency": "EUR",
+				"account_type": "Receivable",
+			},
+			{
+				"attribute": "creditors_usd",
+				"account_name": "Payable USD",
+				"parent_account": "Accounts Payable - _PR",
+				"account_currency": "USD",
+				"account_type": "Payable",
+			},
+		]
+
+		for x in accounts:
+			x = frappe._dict(x)
+			if not frappe.db.get_value(
+				"Account", filters={"account_name": x.account_name, "company": self.company}
+			):
+				acc = frappe.new_doc("Account")
+				acc.account_name = x.account_name
+				acc.parent_account = x.parent_account
+				acc.company = self.company
+				acc.account_currency = x.account_currency
+				acc.account_type = x.account_type
+				acc.insert()
+			else:
+				name = frappe.db.get_value(
+					"Account",
+					filters={"account_name": x.account_name, "company": self.company},
+					fieldname="name",
+					pluck=True,
+				)
+				acc = frappe.get_doc("Account", name)
+			setattr(self, x.attribute, acc.name)
 
 	def create_sales_invoice(
 		self, qty=1, rate=100, posting_date=nowdate(), do_not_save=False, do_not_submit=False
@@ -151,6 +170,64 @@
 		payment.posting_date = posting_date
 		return payment
 
+	def create_purchase_invoice(
+		self, qty=1, rate=100, posting_date=nowdate(), do_not_save=False, do_not_submit=False
+	):
+		"""
+		Helper function to populate default values in sales invoice
+		"""
+		pinv = make_purchase_invoice(
+			qty=qty,
+			rate=rate,
+			company=self.company,
+			customer=self.supplier,
+			item_code=self.item,
+			item_name=self.item,
+			cost_center=self.cost_center,
+			warehouse=self.warehouse,
+			debit_to=self.debit_to,
+			parent_cost_center=self.cost_center,
+			update_stock=0,
+			currency="INR",
+			is_pos=0,
+			is_return=0,
+			return_against=None,
+			income_account=self.income_account,
+			expense_account=self.expense_account,
+			do_not_save=do_not_save,
+			do_not_submit=do_not_submit,
+		)
+		return pinv
+
+	def create_purchase_order(
+		self, qty=1, rate=100, posting_date=nowdate(), do_not_save=False, do_not_submit=False
+	):
+		"""
+		Helper function to populate default values in sales invoice
+		"""
+		pord = create_purchase_order(
+			qty=qty,
+			rate=rate,
+			company=self.company,
+			customer=self.supplier,
+			item_code=self.item,
+			item_name=self.item,
+			cost_center=self.cost_center,
+			warehouse=self.warehouse,
+			debit_to=self.debit_to,
+			parent_cost_center=self.cost_center,
+			update_stock=0,
+			currency="INR",
+			is_pos=0,
+			is_return=0,
+			return_against=None,
+			income_account=self.income_account,
+			expense_account=self.expense_account,
+			do_not_save=do_not_save,
+			do_not_submit=do_not_submit,
+		)
+		return pord
+
 	def clear_old_entries(self):
 		doctype_list = [
 			"GL Entry",
@@ -163,13 +240,11 @@
 		for doctype in doctype_list:
 			qb.from_(qb.DocType(doctype)).delete().where(qb.DocType(doctype).company == self.company).run()
 
-	def create_payment_reconciliation(self):
+	def create_payment_reconciliation(self, party_is_customer=True):
 		pr = frappe.new_doc("Payment Reconciliation")
 		pr.company = self.company
-		pr.party_type = (
-			self.party_type if hasattr(self, "party_type") and self.party_type else "Customer"
-		)
-		pr.party = self.customer
+		pr.party_type = "Customer" if party_is_customer else "Supplier"
+		pr.party = self.customer if party_is_customer else self.supplier
 		pr.receivable_payable_account = get_party_account(pr.party_type, pr.party, pr.company)
 		pr.from_invoice_date = pr.to_invoice_date = pr.from_payment_date = pr.to_payment_date = nowdate()
 		return pr
@@ -906,9 +981,13 @@
 		self.assertEqual(pr.allocation[0].difference_amount, 0)
 
 	def test_reconciliation_purchase_invoice_against_return(self):
-		pi = make_purchase_invoice(
-			supplier="_Test Supplier USD", currency="USD", conversion_rate=50
-		).submit()
+		self.supplier = "_Test Supplier USD"
+		pi = self.create_purchase_invoice(qty=5, rate=50, do_not_submit=True)
+		pi.supplier = self.supplier
+		pi.currency = "USD"
+		pi.conversion_rate = 50
+		pi.credit_to = self.creditors_usd
+		pi.save().submit()
 
 		pi_return = frappe.get_doc(pi.as_dict())
 		pi_return.name = None
@@ -918,11 +997,12 @@
 		pi_return.items[0].qty = -pi_return.items[0].qty
 		pi_return.submit()
 
-		self.company = "_Test Company"
-		self.party_type = "Supplier"
-		self.customer = "_Test Supplier USD"
-
-		pr = self.create_payment_reconciliation()
+		pr = frappe.get_doc("Payment Reconciliation")
+		pr.company = self.company
+		pr.party_type = "Supplier"
+		pr.party = self.supplier
+		pr.receivable_payable_account = self.creditors_usd
+		pr.from_invoice_date = pr.to_invoice_date = pr.from_payment_date = pr.to_payment_date = nowdate()
 		pr.get_unreconciled_entries()
 
 		invoices = []
@@ -931,6 +1011,7 @@
 			if invoice.invoice_number == pi.name:
 				invoices.append(invoice.as_dict())
 				break
+
 		for payment in pr.payments:
 			if payment.reference_name == pi_return.name:
 				payments.append(payment.as_dict())
@@ -941,6 +1022,121 @@
 		# Should not raise frappe.exceptions.ValidationError: Total Debit must be equal to Total Credit.
 		pr.reconcile()
 
+	def test_reconciliation_from_purchase_order_to_multiple_invoices(self):
+		"""
+		Reconciling advance payment from PO/SO to multiple invoices should not cause overallocation
+		"""
+
+		self.supplier = "_Test Supplier"
+
+		pi1 = self.create_purchase_invoice(qty=10, rate=100)
+		pi2 = self.create_purchase_invoice(qty=10, rate=100)
+		po = self.create_purchase_order(qty=20, rate=100)
+		pay = get_payment_entry(po.doctype, po.name)
+		# Overpay Puchase Order
+		pay.paid_amount = 3000
+		pay.save().submit()
+		# assert total allocated and unallocated before reconciliation
+		self.assertEqual(
+			(
+				pay.references[0].reference_doctype,
+				pay.references[0].reference_name,
+				pay.references[0].allocated_amount,
+			),
+			(po.doctype, po.name, 2000),
+		)
+		self.assertEqual(pay.total_allocated_amount, 2000)
+		self.assertEqual(pay.unallocated_amount, 1000)
+		self.assertEqual(pay.difference_amount, 0)
+
+		pr = self.create_payment_reconciliation(party_is_customer=False)
+		pr.get_unreconciled_entries()
+
+		self.assertEqual(len(pr.invoices), 2)
+		self.assertEqual(len(pr.payments), 2)
+
+		for x in pr.payments:
+			self.assertEqual((x.reference_type, x.reference_name), (pay.doctype, pay.name))
+
+		invoices = [x.as_dict() for x in pr.invoices]
+		payments = [x.as_dict() for x in pr.payments]
+		pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
+		# partial allocation on pi1 and full allocate on pi2
+		pr.allocation[0].allocated_amount = 100
+		pr.reconcile()
+
+		# assert references and total allocated and unallocated amount
+		pay.reload()
+		self.assertEqual(len(pay.references), 3)
+		self.assertEqual(
+			(
+				pay.references[0].reference_doctype,
+				pay.references[0].reference_name,
+				pay.references[0].allocated_amount,
+			),
+			(po.doctype, po.name, 900),
+		)
+		self.assertEqual(
+			(
+				pay.references[1].reference_doctype,
+				pay.references[1].reference_name,
+				pay.references[1].allocated_amount,
+			),
+			(pi1.doctype, pi1.name, 100),
+		)
+		self.assertEqual(
+			(
+				pay.references[2].reference_doctype,
+				pay.references[2].reference_name,
+				pay.references[2].allocated_amount,
+			),
+			(pi2.doctype, pi2.name, 1000),
+		)
+		self.assertEqual(pay.total_allocated_amount, 2000)
+		self.assertEqual(pay.unallocated_amount, 1000)
+		self.assertEqual(pay.difference_amount, 0)
+
+		pr.get_unreconciled_entries()
+		self.assertEqual(len(pr.invoices), 1)
+		self.assertEqual(len(pr.payments), 2)
+
+		invoices = [x.as_dict() for x in pr.invoices]
+		payments = [x.as_dict() for x in pr.payments]
+		pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
+		pr.reconcile()
+
+		# assert references and total allocated and unallocated amount
+		pay.reload()
+		self.assertEqual(len(pay.references), 3)
+		# PO references should be removed now
+		self.assertEqual(
+			(
+				pay.references[0].reference_doctype,
+				pay.references[0].reference_name,
+				pay.references[0].allocated_amount,
+			),
+			(pi1.doctype, pi1.name, 100),
+		)
+		self.assertEqual(
+			(
+				pay.references[1].reference_doctype,
+				pay.references[1].reference_name,
+				pay.references[1].allocated_amount,
+			),
+			(pi2.doctype, pi2.name, 1000),
+		)
+		self.assertEqual(
+			(
+				pay.references[2].reference_doctype,
+				pay.references[2].reference_name,
+				pay.references[2].allocated_amount,
+			),
+			(pi1.doctype, pi1.name, 900),
+		)
+		self.assertEqual(pay.total_allocated_amount, 2000)
+		self.assertEqual(pay.unallocated_amount, 1000)
+		self.assertEqual(pay.difference_amount, 0)
+
 
 def make_customer(customer_name, currency=None):
 	if not frappe.db.exists("Customer", customer_name):
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 ec718aa..5b8556e 100644
--- a/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json
+++ b/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json
@@ -19,6 +19,7 @@
   "is_advance",
   "section_break_5",
   "difference_amount",
+  "gain_loss_posting_date",
   "column_break_7",
   "difference_account",
   "exchange_rate",
@@ -151,11 +152,16 @@
    "fieldtype": "Link",
    "label": "Cost Center",
    "options": "Cost Center"
+  },
+  {
+   "fieldname": "gain_loss_posting_date",
+   "fieldtype": "Date",
+   "label": "Difference Posting Date"
   }
  ],
  "istable": 1,
  "links": [],
- "modified": "2023-09-03 07:52:33.684217",
+ "modified": "2023-10-23 10:44:56.066303",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Reconciliation Allocation",
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.json b/erpnext/accounts/doctype/payment_request/payment_request.json
index 5ffd718..66b5c4b 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.json
+++ b/erpnext/accounts/doctype/payment_request/payment_request.json
@@ -268,8 +268,7 @@
    "fieldname": "email_to",
    "fieldtype": "Data",
    "in_global_search": 1,
-   "label": "To",
-   "options": "Email"
+   "label": "To"
   },
   {
    "depends_on": "eval: doc.payment_channel != \"Phone\"",
@@ -340,8 +339,8 @@
   },
   {
    "fieldname": "payment_url",
-   "hidden": 1,
    "fieldtype": "Data",
+   "hidden": 1,
    "length": 500,
    "options": "URL",
    "read_only": 1
@@ -396,7 +395,7 @@
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-09-16 14:15:02.510890",
+ "modified": "2023-09-27 09:51:42.277638",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Request",
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py
index 11d6d5f..5f0b434 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/payment_request.py
@@ -1,13 +1,9 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-
 import json
 
 import frappe
 from frappe import _
 from frappe.model.document import Document
-from frappe.utils import flt, get_url, nowdate
+from frappe.utils import flt, nowdate
 from frappe.utils.background_jobs import enqueue
 
 from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
@@ -20,7 +16,6 @@
 from erpnext.accounts.doctype.subscription_plan.subscription_plan import get_plan_rate
 from erpnext.accounts.party import get_party_account, get_party_bank_account
 from erpnext.accounts.utils import get_account_currency
-from erpnext.erpnext_integrations.stripe_integration import create_stripe_subscription
 from erpnext.utilities import payment_app_import_guard
 
 
@@ -249,7 +244,7 @@
 		if (
 			party_account_currency == ref_doc.company_currency and party_account_currency != self.currency
 		):
-			party_amount = ref_doc.base_grand_total
+			party_amount = ref_doc.get("base_rounded_total") or ref_doc.get("base_grand_total")
 		else:
 			party_amount = self.grand_total
 
@@ -364,35 +359,11 @@
 	def get_payment_success_url(self):
 		return self.payment_success_url
 
-	def on_payment_authorized(self, status=None):
-		if not status:
-			return
-
-		shopping_cart_settings = frappe.get_doc("E Commerce Settings")
-
-		if status in ["Authorized", "Completed"]:
-			redirect_to = None
-			self.set_as_paid()
-
-			# if shopping cart enabled and in session
-			if (
-				shopping_cart_settings.enabled
-				and hasattr(frappe.local, "session")
-				and frappe.local.session.user != "Guest"
-			) and self.payment_channel != "Phone":
-
-				success_url = shopping_cart_settings.payment_success_url
-				if success_url:
-					redirect_to = ({"Orders": "/orders", "Invoices": "/invoices", "My Account": "/me"}).get(
-						success_url, "/me"
-					)
-				else:
-					redirect_to = get_url("/orders/{0}".format(self.reference_name))
-
-			return redirect_to
-
 	def create_subscription(self, payment_provider, gateway_controller, data):
 		if payment_provider == "stripe":
+			with payment_app_import_guard():
+				from payments.payment_gateways.stripe_integration import create_stripe_subscription
+
 			return create_stripe_subscription(gateway_controller, data)
 
 
@@ -544,13 +515,12 @@
 
 
 def get_gateway_details(args):  # nosemgrep
-	"""return gateway and payment account of default payment gateway"""
-	if args.get("payment_gateway_account"):
-		return get_payment_gateway_account(args.get("payment_gateway_account"))
-
-	if args.order_type == "Shopping Cart":
-		payment_gateway_account = frappe.get_doc("E Commerce Settings").payment_gateway_account
-		return get_payment_gateway_account(payment_gateway_account)
+	"""
+	Return gateway and payment account of default payment gateway
+	"""
+	gateway_account = args.get("payment_gateway_account", {"is_default": 1})
+	if gateway_account:
+		return get_payment_gateway_account(gateway_account)
 
 	gateway_account = get_payment_gateway_account({"is_default": 1})
 
diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json
index 54a76b3..624b5f8 100644
--- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json
+++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json
@@ -8,6 +8,7 @@
   "transaction_date",
   "posting_date",
   "fiscal_year",
+  "year_start_date",
   "amended_from",
   "company",
   "column_break1",
@@ -100,16 +101,22 @@
    "fieldtype": "Text",
    "label": "Error Message",
    "read_only": 1
+  },
+  {
+   "fieldname": "year_start_date",
+   "fieldtype": "Date",
+   "label": "Year Start Date"
   }
  ],
  "icon": "fa fa-file-text",
  "idx": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2022-07-20 14:51:04.714154",
+ "modified": "2023-09-11 20:19:11.810533",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Period Closing Voucher",
+ "naming_rule": "Expression (old style)",
  "owner": "Administrator",
  "permissions": [
   {
@@ -144,5 +151,6 @@
  "search_fields": "posting_date, fiscal_year",
  "sort_field": "modified",
  "sort_order": "DESC",
+ "states": [],
  "title_field": "closing_account_head"
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
index d984d86..674db6c 100644
--- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
+++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
@@ -95,15 +95,23 @@
 
 		self.check_if_previous_year_closed()
 
-		pce = frappe.db.sql(
-			"""select name from `tabPeriod Closing Voucher`
-			where posting_date > %s and fiscal_year = %s and docstatus = 1 and company = %s""",
-			(self.posting_date, self.fiscal_year, self.company),
+		pcv = frappe.qb.DocType("Period Closing Voucher")
+		existing_entry = (
+			frappe.qb.from_(pcv)
+			.select(pcv.name)
+			.where(
+				(pcv.posting_date >= self.posting_date)
+				& (pcv.fiscal_year == self.fiscal_year)
+				& (pcv.docstatus == 1)
+				& (pcv.company == self.company)
+			)
+			.run()
 		)
-		if pce and pce[0][0]:
+
+		if existing_entry and existing_entry[0][0]:
 			frappe.throw(
 				_("Another Period Closing Entry {0} has been made after {1}").format(
-					pce[0][0], self.posting_date
+					existing_entry[0][0], self.posting_date
 				)
 			)
 
@@ -130,18 +138,27 @@
 			frappe.enqueue(
 				process_gl_entries,
 				gl_entries=gl_entries,
+				voucher_name=self.name,
+				timeout=3000,
+			)
+
+			frappe.enqueue(
+				process_closing_entries,
+				gl_entries=gl_entries,
 				closing_entries=closing_entries,
 				voucher_name=self.name,
 				company=self.company,
 				closing_date=self.posting_date,
-				queue="long",
+				timeout=3000,
 			)
+
 			frappe.msgprint(
 				_("The GL Entries will be processed in the background, it can take a few minutes."),
 				alert=True,
 			)
 		else:
-			process_gl_entries(gl_entries, closing_entries, self.name, self.company, self.posting_date)
+			process_gl_entries(gl_entries, self.name)
+			process_closing_entries(gl_entries, closing_entries, self.name, self.company, self.posting_date)
 
 	def get_grouped_gl_entries(self, get_opening_entries=False):
 		closing_entries = []
@@ -322,17 +339,12 @@
 		return query.run(as_dict=1)
 
 
-def process_gl_entries(gl_entries, closing_entries, voucher_name, company, closing_date):
-	from erpnext.accounts.doctype.account_closing_balance.account_closing_balance import (
-		make_closing_entries,
-	)
+def process_gl_entries(gl_entries, voucher_name):
 	from erpnext.accounts.general_ledger import make_gl_entries
 
 	try:
 		if gl_entries:
 			make_gl_entries(gl_entries, merge_entries=False)
-
-		make_closing_entries(gl_entries + closing_entries, voucher_name, company, closing_date)
 		frappe.db.set_value("Period Closing Voucher", voucher_name, "gle_processing_status", "Completed")
 	except Exception as e:
 		frappe.db.rollback()
@@ -340,6 +352,19 @@
 		frappe.db.set_value("Period Closing Voucher", voucher_name, "gle_processing_status", "Failed")
 
 
+def process_closing_entries(gl_entries, closing_entries, voucher_name, company, closing_date):
+	from erpnext.accounts.doctype.account_closing_balance.account_closing_balance import (
+		make_closing_entries,
+	)
+
+	try:
+		if gl_entries + closing_entries:
+			make_closing_entries(gl_entries + closing_entries, voucher_name, company, closing_date)
+	except Exception as e:
+		frappe.db.rollback()
+		frappe.log_error(e)
+
+
 def make_reverse_gl_entries(voucher_type, voucher_no):
 	from erpnext.accounts.general_ledger import make_reverse_gl_entries
 
diff --git a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py
index 5d08e8d..1bd565e 100644
--- a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py
+++ b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py
@@ -10,7 +10,7 @@
 from erpnext.accounts.doctype.finance_book.test_finance_book import create_finance_book
 from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
 from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
-from erpnext.accounts.utils import get_fiscal_year, now
+from erpnext.accounts.utils import get_fiscal_year
 
 
 class TestPeriodClosingVoucher(unittest.TestCase):
diff --git a/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py
index 00c402f..982bdc1 100644
--- a/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py
+++ b/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py
@@ -6,6 +6,7 @@
 
 import frappe
 from frappe import _
+from frappe.utils import add_days, nowdate
 
 from erpnext.accounts.doctype.pos_invoice.pos_invoice import make_sales_return
 from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
@@ -125,70 +126,64 @@
 		self.assertEqual(inv.grand_total, 5474.0)
 
 	def test_tax_calculation_with_item_tax_template(self):
-		inv = create_pos_invoice(qty=84, rate=4.6, do_not_save=1)
-		item_row = inv.get("items")[0]
+		import json
 
-		add_items = [
-			(54, "_Test Account Excise Duty @ 12 - _TC"),
-			(288, "_Test Account Excise Duty @ 15 - _TC"),
-			(144, "_Test Account Excise Duty @ 20 - _TC"),
-			(430, "_Test Item Tax Template 1 - _TC"),
+		from erpnext.stock.get_item_details import get_item_details
+
+		# set tax template in item
+		item = frappe.get_cached_doc("Item", "_Test Item")
+		item.set(
+			"taxes",
+			[
+				{
+					"item_tax_template": "_Test Account Excise Duty @ 15 - _TC",
+					"valid_from": add_days(nowdate(), -5),
+				}
+			],
+		)
+		item.save()
+
+		# create POS invoice with item
+		pos_inv = create_pos_invoice(qty=84, rate=4.6, do_not_save=True)
+		item_details = get_item_details(
+			doc=pos_inv,
+			args={
+				"item_code": item.item_code,
+				"company": pos_inv.company,
+				"doctype": "POS Invoice",
+				"conversion_rate": 1.0,
+			},
+		)
+		tax_map = json.loads(item_details.item_tax_rate)
+		for tax in tax_map:
+			pos_inv.append(
+				"taxes",
+				{
+					"charge_type": "On Net Total",
+					"account_head": tax,
+					"rate": tax_map[tax],
+					"description": "Test",
+					"cost_center": "_Test Cost Center - _TC",
+				},
+			)
+		pos_inv.submit()
+		pos_inv.load_from_db()
+
+		# check if correct tax values are applied from tax template
+		self.assertEqual(pos_inv.net_total, 386.4)
+
+		expected_taxes = [
+			{
+				"tax_amount": 57.96,
+				"total": 444.36,
+			},
 		]
-		for qty, item_tax_template in add_items:
-			item_row_copy = copy.deepcopy(item_row)
-			item_row_copy.qty = qty
-			item_row_copy.item_tax_template = item_tax_template
-			inv.append("items", item_row_copy)
 
-		inv.append(
-			"taxes",
-			{
-				"account_head": "_Test Account Excise Duty - _TC",
-				"charge_type": "On Net Total",
-				"cost_center": "_Test Cost Center - _TC",
-				"description": "Excise Duty",
-				"doctype": "Sales Taxes and Charges",
-				"rate": 11,
-			},
-		)
-		inv.append(
-			"taxes",
-			{
-				"account_head": "_Test Account Education Cess - _TC",
-				"charge_type": "On Net Total",
-				"cost_center": "_Test Cost Center - _TC",
-				"description": "Education Cess",
-				"doctype": "Sales Taxes and Charges",
-				"rate": 0,
-			},
-		)
-		inv.append(
-			"taxes",
-			{
-				"account_head": "_Test Account S&H Education Cess - _TC",
-				"charge_type": "On Net Total",
-				"cost_center": "_Test Cost Center - _TC",
-				"description": "S&H Education Cess",
-				"doctype": "Sales Taxes and Charges",
-				"rate": 3,
-			},
-		)
-		inv.insert()
+		for i in range(len(expected_taxes)):
+			for key in expected_taxes[i]:
+				self.assertEqual(expected_taxes[i][key], pos_inv.get("taxes")[i].get(key))
 
-		self.assertEqual(inv.net_total, 4600)
-
-		self.assertEqual(inv.get("taxes")[0].tax_amount, 502.41)
-		self.assertEqual(inv.get("taxes")[0].total, 5102.41)
-
-		self.assertEqual(inv.get("taxes")[1].tax_amount, 197.80)
-		self.assertEqual(inv.get("taxes")[1].total, 5300.21)
-
-		self.assertEqual(inv.get("taxes")[2].tax_amount, 375.36)
-		self.assertEqual(inv.get("taxes")[2].total, 5675.57)
-
-		self.assertEqual(inv.grand_total, 5675.57)
-		self.assertEqual(inv.rounding_adjustment, 0.43)
-		self.assertEqual(inv.rounded_total, 5676.0)
+		self.assertEqual(pos_inv.get("base_total_taxes_and_charges"), 57.96)
 
 	def test_tax_calculation_with_multiple_items_and_discount(self):
 		inv = create_pos_invoice(qty=1, rate=75, do_not_save=True)
@@ -776,19 +771,28 @@
 		)
 
 		create_batch_item_with_batch("_BATCH ITEM Test For Reserve", "TestBatch-RS 02")
-		make_stock_entry(
+		se = make_stock_entry(
 			target="_Test Warehouse - _TC",
 			item_code="_BATCH ITEM Test For Reserve",
-			qty=20,
+			qty=30,
 			basic_rate=100,
-			batch_no="TestBatch-RS 02",
 		)
 
+		se.reload()
+
+		batch_no = get_batch_from_bundle(se.items[0].serial_and_batch_bundle)
+
+		# POS Invoice 1, for the batch without bundle
 		pos_inv1 = create_pos_invoice(
-			item="_BATCH ITEM Test For Reserve", rate=300, qty=15, batch_no="TestBatch-RS 02"
+			item="_BATCH ITEM Test For Reserve", rate=300, qty=15, do_not_save=1
 		)
+
+		pos_inv1.items[0].batch_no = batch_no
 		pos_inv1.save()
 		pos_inv1.submit()
+		pos_inv1.reload()
+
+		self.assertFalse(pos_inv1.items[0].serial_and_batch_bundle)
 
 		batches = get_auto_batch_nos(
 			frappe._dict(
@@ -797,7 +801,24 @@
 		)
 
 		for batch in batches:
-			if batch.batch_no == "TestBatch-RS 02" and batch.warehouse == "_Test Warehouse - _TC":
+			if batch.batch_no == batch_no and batch.warehouse == "_Test Warehouse - _TC":
+				self.assertEqual(batch.qty, 15)
+
+		# POS Invoice 2, for the batch with bundle
+		pos_inv2 = create_pos_invoice(
+			item="_BATCH ITEM Test For Reserve", rate=300, qty=10, batch_no=batch_no
+		)
+		pos_inv2.reload()
+		self.assertTrue(pos_inv2.items[0].serial_and_batch_bundle)
+
+		batches = get_auto_batch_nos(
+			frappe._dict(
+				{"item_code": "_BATCH ITEM Test For Reserve", "warehouse": "_Test Warehouse - _TC"}
+			)
+		)
+
+		for batch in batches:
+			if batch.batch_no == batch_no and batch.warehouse == "_Test Warehouse - _TC":
 				self.assertEqual(batch.qty, 5)
 
 	def test_pos_batch_item_qty_validation(self):
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 d42b1e4..c161dac 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
@@ -454,7 +454,7 @@
 	except Exception as e:
 		frappe.db.rollback()
 		message_log = frappe.message_log.pop() if frappe.message_log else str(e)
-		error_message = safe_load_json(message_log)
+		error_message = get_error_message(message_log)
 
 		if closing_entry:
 			closing_entry.set_status(update=True, status="Failed")
@@ -483,7 +483,7 @@
 	except Exception as e:
 		frappe.db.rollback()
 		message_log = frappe.message_log.pop() if frappe.message_log else str(e)
-		error_message = safe_load_json(message_log)
+		error_message = get_error_message(message_log)
 
 		if closing_entry:
 			closing_entry.set_status(update=True, status="Submitted")
@@ -525,10 +525,8 @@
 		frappe.throw(_("Scheduler is inactive. Cannot enqueue job."), title=_("Scheduler Inactive"))
 
 
-def safe_load_json(message):
+def get_error_message(message) -> str:
 	try:
-		json_message = json.loads(message).get("message")
+		return message["message"]
 	except Exception:
-		json_message = message
-
-	return json_message
+		return str(message)
diff --git a/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.json b/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.json
index 1131a0f..b4ac981 100644
--- a/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.json
+++ b/erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.json
@@ -110,7 +110,7 @@
  "in_create": 1,
  "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2023-04-21 17:36:26.642617",
+ "modified": "2023-11-02 11:32:12.254018",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Process Payment Reconciliation Log",
@@ -125,7 +125,19 @@
    "print": 1,
    "read": 1,
    "report": 1,
-   "role": "System Manager",
+   "role": "Accounts Manager",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Accounts User",
    "share": 1,
    "write": 1
   }
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 9a5ad35..6c959ba 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
@@ -48,6 +48,20 @@
 
 
 def get_report_pdf(doc, consolidated=True):
+	statement_dict = get_statement_dict(doc)
+	if not bool(statement_dict):
+		return False
+	elif consolidated:
+		delimiter = '<div style="page-break-before: always;"></div>' if doc.include_break else ""
+		result = delimiter.join(list(statement_dict.values()))
+		return get_pdf(result, {"orientation": doc.orientation})
+	else:
+		for customer, statement_html in statement_dict.items():
+			statement_dict[customer] = get_pdf(statement_html, {"orientation": doc.orientation})
+		return statement_dict
+
+
+def get_statement_dict(doc, get_statement_dict=False):
 	statement_dict = {}
 	ageing = ""
 
@@ -78,18 +92,11 @@
 			if not res:
 				continue
 
-		statement_dict[entry.customer] = get_html(doc, filters, entry, col, res, ageing)
+		statement_dict[entry.customer] = (
+			[res, ageing] if get_statement_dict else get_html(doc, filters, entry, col, res, ageing)
+		)
 
-	if not bool(statement_dict):
-		return False
-	elif consolidated:
-		delimiter = '<div style="page-break-before: always;"></div>' if doc.include_break else ""
-		result = delimiter.join(list(statement_dict.values()))
-		return get_pdf(result, {"orientation": doc.orientation})
-	else:
-		for customer, statement_html in statement_dict.items():
-			statement_dict[customer] = get_pdf(statement_html, {"orientation": doc.orientation})
-		return statement_dict
+	return statement_dict
 
 
 def set_ageing(doc, entry):
@@ -102,7 +109,8 @@
 			"range2": 60,
 			"range3": 90,
 			"range4": 120,
-			"customer": entry.customer,
+			"party_type": "Customer",
+			"party": [entry.customer],
 		}
 	)
 	col1, ageing = get_ageing(ageing_filters)
@@ -145,7 +153,8 @@
 def get_ar_filters(doc, entry):
 	return {
 		"report_date": doc.posting_date if doc.posting_date else None,
-		"customer": entry.customer,
+		"party_type": "Customer",
+		"party": [entry.customer],
 		"customer_name": entry.customer_name if entry.customer_name else None,
 		"payment_terms_template": doc.payment_terms_template if doc.payment_terms_template else None,
 		"sales_partner": doc.sales_partner if doc.sales_partner else None,
diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py b/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py
index fb0d8d1..a3a74df 100644
--- a/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py
+++ b/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py
@@ -4,39 +4,107 @@
 import unittest
 
 import frappe
+from frappe.tests.utils import FrappeTestCase
 from frappe.utils import add_days, getdate, today
 
 from erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts import (
+	get_statement_dict,
 	send_emails,
 )
 from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
+from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
 
 
-class TestProcessStatementOfAccounts(unittest.TestCase):
+class TestProcessStatementOfAccounts(AccountsTestMixin, FrappeTestCase):
 	def setUp(self):
+		self.create_company()
+		self.create_customer()
+		self.create_customer(customer_name="Other Customer")
+		self.clear_old_entries()
 		self.si = create_sales_invoice()
-		self.process_soa = create_process_soa()
+		create_sales_invoice(customer="Other Customer")
+
+	def test_process_soa_for_gl(self):
+		"""Tests the utils for Statement of Accounts(General Ledger)"""
+		process_soa = create_process_soa(
+			name="_Test Process SOA for GL",
+			customers=[{"customer": "_Test Customer"}, {"customer": "Other Customer"}],
+		)
+		statement_dict = get_statement_dict(process_soa, get_statement_dict=True)
+
+		# Checks if the statements are filtered based on the Customer
+		self.assertIn("Other Customer", statement_dict)
+		self.assertIn("_Test Customer", statement_dict)
+
+		# Checks if the correct number of receivable entries exist
+		# 3 rows for opening and closing and 1 row for SI
+		receivable_entries = statement_dict["_Test Customer"][0]
+		self.assertEqual(len(receivable_entries), 4)
+
+		# Checks the amount for the receivable entry
+		self.assertEqual(receivable_entries[1].voucher_no, self.si.name)
+		self.assertEqual(receivable_entries[1].balance, 100)
+
+	def test_process_soa_for_ar(self):
+		"""Tests the utils for Statement of Accounts(Accounts Receivable)"""
+		process_soa = create_process_soa(name="_Test Process SOA for AR", report="Accounts Receivable")
+		statement_dict = get_statement_dict(process_soa, get_statement_dict=True)
+
+		# Checks if the statements are filtered based on the Customer
+		self.assertNotIn("Other Customer", statement_dict)
+		self.assertIn("_Test Customer", statement_dict)
+
+		# Checks if the correct number of receivable entries exist
+		receivable_entries = statement_dict["_Test Customer"][0]
+		self.assertEqual(len(receivable_entries), 1)
+
+		# Checks the amount for the receivable entry
+		self.assertEqual(receivable_entries[0].voucher_no, self.si.name)
+		self.assertEqual(receivable_entries[0].total_due, 100)
+
+		# Checks the ageing summary for AR
+		ageing_summary = statement_dict["_Test Customer"][1][0]
+		expected_summary = frappe._dict(
+			range1=100,
+			range2=0,
+			range3=0,
+			range4=0,
+			range5=0,
+		)
+		self.check_ageing_summary(ageing_summary, expected_summary)
 
 	def test_auto_email_for_process_soa_ar(self):
-		send_emails(self.process_soa.name, from_scheduler=True)
-		self.process_soa.load_from_db()
-		self.assertEqual(self.process_soa.posting_date, getdate(add_days(today(), 7)))
+		process_soa = create_process_soa(
+			name="_Test Process SOA", enable_auto_email=1, report="Accounts Receivable"
+		)
+		send_emails(process_soa.name, from_scheduler=True)
+		process_soa.load_from_db()
+		self.assertEqual(process_soa.posting_date, getdate(add_days(today(), 7)))
+
+	def check_ageing_summary(self, ageing, expected_ageing):
+		for age_range in expected_ageing:
+			self.assertEqual(expected_ageing[age_range], ageing.get(age_range))
 
 	def tearDown(self):
-		frappe.delete_doc_if_exists("Process Statement Of Accounts", "Test Process SOA")
+		frappe.db.rollback()
 
 
-def create_process_soa():
-	frappe.delete_doc_if_exists("Process Statement Of Accounts", "Test Process SOA")
+def create_process_soa(**args):
+	args = frappe._dict(args)
+	frappe.delete_doc_if_exists("Process Statement Of Accounts", args.name)
 	process_soa = frappe.new_doc("Process Statement Of Accounts")
-	soa_dict = {
-		"name": "Test Process SOA",
-		"company": "_Test Company",
-	}
+	soa_dict = frappe._dict(
+		name=args.name,
+		company=args.company or "_Test Company",
+		customers=args.customers or [{"customer": "_Test Customer"}],
+		enable_auto_email=1 if args.enable_auto_email else 0,
+		frequency=args.frequency or "Weekly",
+		report=args.report or "General Ledger",
+		from_date=args.from_date or getdate(today()),
+		to_date=args.to_date or getdate(today()),
+		posting_date=args.posting_date or getdate(today()),
+		include_ageing=1,
+	)
 	process_soa.update(soa_dict)
-	process_soa.set("customers", [{"customer": "_Test Customer"}])
-	process_soa.enable_auto_email = 1
-	process_soa.frequency = "Weekly"
-	process_soa.report = "Accounts Receivable"
 	process_soa.save()
 	return process_soa
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index c8c9ad1..2eaa337 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -65,6 +65,25 @@
 			erpnext.accounts.ledger_preview.show_stock_ledger_preview(this.frm);
 		}
 
+		if (this.frm.doc.repost_required && this.frm.doc.docstatus===1) {
+			this.frm.set_intro(__("Accounting entries for this invoice need to be reposted. Please click on 'Repost' button to update."));
+			this.frm.add_custom_button(__('Repost Accounting Entries'),
+				() => {
+					this.frm.call({
+						doc: this.frm.doc,
+						method: 'repost_accounting_entries',
+						freeze: true,
+						freeze_message: __('Reposting...'),
+						callback: (r) => {
+							if (!r.exc) {
+								frappe.msgprint(__('Accounting Entries are reposted.'));
+								me.frm.refresh();
+							}
+						}
+					});
+				}).removeClass('btn-default').addClass('btn-warning');
+		}
+
 		if(!doc.is_return && doc.docstatus == 1 && doc.outstanding_amount != 0){
 			if(doc.on_hold) {
 				this.frm.add_custom_button(
@@ -460,6 +479,12 @@
 	}
 });
 
+cur_frm.set_query("wip_composite_asset", "items", function() {
+	return {
+		filters: {'is_composite_asset': 1, 'docstatus': 0 }
+	}
+});
+
 cur_frm.cscript.expense_account = function(doc, cdt, cdn){
 	var d = locals[cdt][cdn];
 	if(d.idx == 1 && d.expense_account){
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index 0599e19..09bffff 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -36,6 +36,7 @@
   "currency_and_price_list",
   "currency",
   "conversion_rate",
+  "use_transaction_date_exchange_rate",
   "column_break2",
   "buying_price_list",
   "price_list_currency",
@@ -166,6 +167,7 @@
   "against_expense_account",
   "column_break_63",
   "unrealized_profit_loss_account",
+  "repost_required",
   "subscription_section",
   "subscription",
   "auto_repeat",
@@ -191,8 +193,7 @@
   "inter_company_invoice_reference",
   "is_old_subcontracting_flow",
   "remarks",
-  "connections_tab",
-  "column_break_38"
+  "connections_tab"
  ],
  "fields": [
   {
@@ -383,7 +384,8 @@
    "label": "Supplier Invoice No",
    "oldfieldname": "bill_no",
    "oldfieldtype": "Data",
-   "print_hide": 1
+   "print_hide": 1,
+   "search_index": 1
   },
   {
    "fieldname": "column_break_15",
@@ -406,7 +408,8 @@
    "no_copy": 1,
    "options": "Purchase Invoice",
    "print_hide": 1,
-   "read_only": 1
+   "read_only": 1,
+   "search_index": 1
   },
   {
    "fieldname": "section_addresses",
@@ -990,6 +993,7 @@
    "print_hide": 1
   },
   {
+   "allow_on_submit": 1,
    "fieldname": "cash_bank_account",
    "fieldtype": "Link",
    "label": "Cash/Bank Account",
@@ -1053,6 +1057,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "allow_on_submit": 1,
    "depends_on": "eval:flt(doc.write_off_amount)!=0",
    "fieldname": "write_off_account",
    "fieldtype": "Link",
@@ -1217,6 +1222,7 @@
    "read_only": 1
   },
   {
+   "allow_on_submit": 1,
    "default": "No",
    "fieldname": "is_opening",
    "fieldtype": "Select",
@@ -1349,6 +1355,7 @@
    "options": "Project"
   },
   {
+   "allow_on_submit": 1,
    "depends_on": "eval:doc.is_internal_supplier",
    "description": "Unrealized Profit/Loss account for intra-company transfers",
    "fieldname": "unrealized_profit_loss_account",
@@ -1381,6 +1388,7 @@
    "depends_on": "eval:doc.is_subcontracted",
    "fieldname": "supplier_warehouse",
    "fieldtype": "Link",
+   "ignore_user_permissions": 1,
    "label": "Supplier Warehouse",
    "no_copy": 1,
    "options": "Warehouse",
@@ -1505,10 +1513,6 @@
    "fieldtype": "Column Break"
   },
   {
-   "fieldname": "column_break_38",
-   "fieldtype": "Column Break"
-  },
-  {
    "fieldname": "column_break_50",
    "fieldtype": "Column Break"
   },
@@ -1578,13 +1582,29 @@
    "fieldname": "use_company_roundoff_cost_center",
    "fieldtype": "Check",
    "label": "Use Company Default Round Off Cost Center"
+  },
+  {
+   "default": "0",
+   "fieldname": "repost_required",
+   "fieldtype": "Check",
+   "hidden": 1,
+   "label": "Repost Required",
+   "options": "Account",
+   "read_only": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "use_transaction_date_exchange_rate",
+   "fieldtype": "Check",
+   "label": "Use Transaction Date Exchange Rate",
+   "read_only": 1
   }
  ],
  "icon": "fa fa-file-text",
  "idx": 204,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-07-25 17:22:59.145031",
+ "modified": "2023-11-03 15:47:30.319200",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice",
@@ -1647,4 +1667,4 @@
  "timeline_field": "supplier",
  "title_field": "title",
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 1dc67ef..99b9c4e 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -11,6 +11,9 @@
 import erpnext
 from erpnext.accounts.deferred_revenue import validate_service_stop_date
 from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
+from erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger import (
+	validate_docs_for_deferred_accounting,
+)
 from erpnext.accounts.doctype.sales_invoice.sales_invoice import (
 	check_if_return_invoice_linked_with_payment_entry,
 	get_total_in_party_account_currency,
@@ -30,7 +33,7 @@
 )
 from erpnext.accounts.party import get_due_date, get_party_account
 from erpnext.accounts.utils import get_account_currency, get_fiscal_year
-from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_enabled
+from erpnext.assets.doctype.asset.asset import is_cwip_accounting_enabled
 from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
 from erpnext.buying.utils import check_on_hold_or_closed_status
 from erpnext.controllers.accounts_controller import validate_account_head
@@ -278,9 +281,6 @@
 			# in case of auto inventory accounting,
 			# expense account is always "Stock Received But Not Billed" for a stock item
 			# except opening entry, drop-ship entry and fixed asset items
-			if item.item_code:
-				asset_category = frappe.get_cached_value("Item", item.item_code, "asset_category")
-
 			if (
 				auto_accounting_for_stock
 				and item.item_code in stock_items
@@ -347,22 +347,26 @@
 							frappe.msgprint(msg, title=_("Expense Head Changed"))
 
 						item.expense_account = stock_not_billed_account
-
-			elif item.is_fixed_asset and not is_cwip_accounting_enabled(asset_category):
+			elif item.is_fixed_asset and item.pr_detail:
+				if not asset_received_but_not_billed:
+					asset_received_but_not_billed = self.get_company_default("asset_received_but_not_billed")
+				item.expense_account = asset_received_but_not_billed
+			elif item.is_fixed_asset:
+				account_type = (
+					"capital_work_in_progress_account"
+					if is_cwip_accounting_enabled(item.asset_category)
+					else "fixed_asset_account"
+				)
 				asset_category_account = get_asset_category_account(
-					"fixed_asset_account", item=item.item_code, company=self.company
+					account_type, item=item.item_code, company=self.company
 				)
 				if not asset_category_account:
-					form_link = get_link_to_form("Asset Category", asset_category)
+					form_link = get_link_to_form("Asset Category", item.asset_category)
 					throw(
 						_("Please set Fixed Asset Account in {} against {}.").format(form_link, self.company),
 						title=_("Missing Account"),
 					)
 				item.expense_account = asset_category_account
-			elif item.is_fixed_asset and item.pr_detail:
-				if not asset_received_but_not_billed:
-					asset_received_but_not_billed = self.get_company_default("asset_received_but_not_billed")
-				item.expense_account = asset_received_but_not_billed
 			elif not item.expense_account and for_validate:
 				throw(_("Expense account is mandatory for item {0}").format(item.item_code or item.item_name))
 
@@ -484,6 +488,11 @@
 						_("Stock cannot be updated against Purchase Receipt {0}").format(item.purchase_receipt)
 					)
 
+	def validate_for_repost(self):
+		self.validate_write_off_account()
+		self.validate_expense_account()
+		validate_docs_for_deferred_accounting([], [self.name])
+
 	def on_submit(self):
 		super(PurchaseInvoice, self).on_submit()
 
@@ -522,6 +531,19 @@
 
 		self.process_common_party_accounting()
 
+	def on_update_after_submit(self):
+		if hasattr(self, "repost_required"):
+			fields_to_check = [
+				"cash_bank_account",
+				"write_off_account",
+				"unrealized_profit_loss_account",
+			]
+			child_tables = {"items": ("expense_account",), "taxes": ("account_head",)}
+			self.needs_repost = self.check_if_fields_updated(fields_to_check, child_tables)
+			if self.needs_repost:
+				self.validate_for_repost()
+				self.db_set("repost_required", self.needs_repost)
+
 	def make_gl_entries(self, gl_entries=None, from_repost=False):
 		if not gl_entries:
 			gl_entries = self.get_gl_entries()
@@ -563,12 +585,11 @@
 
 	def get_gl_entries(self, warehouse_account=None):
 		self.auto_accounting_for_stock = erpnext.is_perpetual_inventory_enabled(self.company)
+
 		if self.auto_accounting_for_stock:
 			self.stock_received_but_not_billed = self.get_company_default("stock_received_but_not_billed")
-			self.expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
 		else:
 			self.stock_received_but_not_billed = None
-			self.expenses_included_in_valuation = None
 
 		self.negative_expense_to_be_booked = 0.0
 		gl_entries = []
@@ -577,9 +598,6 @@
 		self.make_item_gl_entries(gl_entries)
 		self.make_precision_loss_gl_entry(gl_entries)
 
-		if self.check_asset_cwip_enabled():
-			self.get_asset_gl_entry(gl_entries)
-
 		self.make_tax_gl_entries(gl_entries)
 		self.make_internal_transfer_gl_entries(gl_entries)
 
@@ -682,7 +700,11 @@
 				if item.item_code:
 					asset_category = frappe.get_cached_value("Item", item.item_code, "asset_category")
 
-				if self.update_stock and self.auto_accounting_for_stock and item.item_code in stock_items:
+				if (
+					self.update_stock
+					and self.auto_accounting_for_stock
+					and (item.item_code in stock_items or item.is_fixed_asset)
+				):
 					# warehouse account
 					warehouse_debit_amount = self.make_stock_adjustment_entry(
 						gl_entries, item, voucher_wise_stock_value, account_currency
@@ -803,9 +825,7 @@
 							)
 						)
 
-				elif not item.is_fixed_asset or (
-					item.is_fixed_asset and not is_cwip_accounting_enabled(asset_category)
-				):
+				else:
 					expense_account = (
 						item.expense_account
 						if (not item.enable_deferred_expense or self.is_return)
@@ -900,43 +920,7 @@
 										item=item,
 									)
 								)
-
-					# If asset is bought through this document and not linked to PR
-					if self.update_stock and item.landed_cost_voucher_amount:
-						expenses_included_in_asset_valuation = self.get_company_default(
-							"expenses_included_in_asset_valuation"
-						)
-						# Amount added through landed-cost-voucher
-						gl_entries.append(
-							self.get_gl_dict(
-								{
-									"account": expenses_included_in_asset_valuation,
-									"against_type": "Account",
-									"against": expense_account,
-									"cost_center": item.cost_center,
-									"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
-									"credit": flt(item.landed_cost_voucher_amount),
-									"project": item.project or self.project,
-								},
-								item=item,
-							)
-						)
-
-						gl_entries.append(
-							self.get_gl_dict(
-								{
-									"account": expense_account,
-									"against_type": "Account",
-									"against": expenses_included_in_asset_valuation,
-									"cost_center": item.cost_center,
-									"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
-									"debit": flt(item.landed_cost_voucher_amount),
-									"project": item.project or self.project,
-								},
-								item=item,
-							)
-						)
-
+                
 						# update gross amount of asset bought through this document
 						assets = frappe.db.get_all(
 							"Asset", filters={"purchase_invoice": self.name, "item_code": item.item_code}
@@ -961,11 +945,17 @@
 						(item.purchase_receipt, valuation_tax_accounts),
 					)
 
+					stock_rbnb = (
+						self.get_company_default("asset_received_but_not_billed")
+						if item.is_fixed_asset
+						else self.stock_received_but_not_billed
+					)
+
 					if not negative_expense_booked_in_pr:
 						gl_entries.append(
 							self.get_gl_dict(
 								{
-									"account": self.stock_received_but_not_billed,
+									"account": stock_rbnb,
 									"against_type": "Supplier",
 									"against": self.supplier,
 									"debit": flt(item.item_tax_amount, item.precision("item_tax_amount")),
@@ -981,162 +971,12 @@
 							item.item_tax_amount, item.precision("item_tax_amount")
 						)
 
-	def get_asset_gl_entry(self, gl_entries):
-		arbnb_account = None
-		eiiav_account = None
-		asset_eiiav_currency = None
-
-		for item in self.get("items"):
-			if item.is_fixed_asset:
-				asset_amount = flt(item.net_amount) + flt(item.item_tax_amount / self.conversion_rate)
-				base_asset_amount = flt(item.base_net_amount + item.item_tax_amount)
-
-				item_exp_acc_type = frappe.get_cached_value("Account", item.expense_account, "account_type")
-				if not item.expense_account or item_exp_acc_type not in [
-					"Asset Received But Not Billed",
-					"Fixed Asset",
-				]:
-					if not arbnb_account:
-						arbnb_account = self.get_company_default("asset_received_but_not_billed")
-					item.expense_account = arbnb_account
-
-				if not self.update_stock:
-					arbnb_currency = get_account_currency(item.expense_account)
-					gl_entries.append(
-						self.get_gl_dict(
-							{
-								"account": item.expense_account,
-								"against_type": "Supplier",
-								"against": self.supplier,
-								"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
-								"debit": base_asset_amount,
-								"debit_in_account_currency": (
-									base_asset_amount if arbnb_currency == self.company_currency else asset_amount
-								),
-								"cost_center": item.cost_center,
-								"project": item.project or self.project,
-							},
-							item=item,
-						)
-					)
-
-					if item.item_tax_amount:
-						if not eiiav_account or not asset_eiiav_currency:
-							eiiav_account = self.get_company_default("expenses_included_in_asset_valuation")
-							asset_eiiav_currency = get_account_currency(eiiav_account)
-
-						gl_entries.append(
-							self.get_gl_dict(
-								{
-									"account": eiiav_account,
-									"against_type": "Supplier",
-									"against": self.supplier,
-									"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
-									"cost_center": item.cost_center,
-									"project": item.project or self.project,
-									"credit": item.item_tax_amount,
-									"credit_in_account_currency": (
-										item.item_tax_amount
-										if asset_eiiav_currency == self.company_currency
-										else item.item_tax_amount / self.conversion_rate
-									),
-								},
-								item=item,
-							)
-						)
-				else:
-					cwip_account = get_asset_account(
-						"capital_work_in_progress_account", asset_category=item.asset_category, company=self.company
-					)
-
-					cwip_account_currency = get_account_currency(cwip_account)
-					gl_entries.append(
-						self.get_gl_dict(
-							{
-								"account": cwip_account,
-								"against_type": "Supplier",
-								"against": self.supplier,
-								"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
-								"debit": base_asset_amount,
-								"debit_in_account_currency": (
-									base_asset_amount if cwip_account_currency == self.company_currency else asset_amount
-								),
-								"cost_center": self.cost_center,
-								"project": item.project or self.project,
-							},
-							item=item,
-						)
-					)
-
-					if item.item_tax_amount and not cint(erpnext.is_perpetual_inventory_enabled(self.company)):
-						if not eiiav_account or not asset_eiiav_currency:
-							eiiav_account = self.get_company_default("expenses_included_in_asset_valuation")
-							asset_eiiav_currency = get_account_currency(eiiav_account)
-
-						gl_entries.append(
-							self.get_gl_dict(
-								{
-									"account": eiiav_account,
-									"against_type": "Supplier",
-									"against": self.supplier,
-									"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
-									"cost_center": item.cost_center,
-									"credit": item.item_tax_amount,
-									"project": item.project or self.project,
-									"credit_in_account_currency": (
-										item.item_tax_amount
-										if asset_eiiav_currency == self.company_currency
-										else item.item_tax_amount / self.conversion_rate
-									),
-								},
-								item=item,
-							)
-						)
-
-					# Assets are bought through this document then it will be linked to this document
-					if flt(item.landed_cost_voucher_amount):
-						if not eiiav_account:
-							eiiav_account = self.get_company_default("expenses_included_in_asset_valuation")
-
-						gl_entries.append(
-							self.get_gl_dict(
-								{
-									"account": eiiav_account,
-									"against_type": "Account",
-									"against": cwip_account,
-									"cost_center": item.cost_center,
-									"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
-									"credit": flt(item.landed_cost_voucher_amount),
-									"project": item.project or self.project,
-								},
-								item=item,
-							)
-						)
-
-						gl_entries.append(
-							self.get_gl_dict(
-								{
-									"account": cwip_account,
-									"against_type": "Account",
-									"against": eiiav_account,
-									"cost_center": item.cost_center,
-									"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
-									"debit": flt(item.landed_cost_voucher_amount),
-									"project": item.project or self.project,
-								},
-								item=item,
-							)
-						)
-
-					# update gross amount of assets bought through this document
-					assets = frappe.db.get_all(
-						"Asset", filters={"purchase_invoice": self.name, "item_code": item.item_code}
-					)
-					for asset in assets:
-						frappe.db.set_value("Asset", asset.name, "gross_purchase_amount", flt(item.valuation_rate))
-						frappe.db.set_value("Asset", asset.name, "purchase_receipt_amount", flt(item.valuation_rate))
-
-		return gl_entries
+		assets = frappe.db.get_all(
+			"Asset", filters={"purchase_invoice": self.name, "item_code": item.item_code}
+		)
+		for asset in assets:
+			frappe.db.set_value("Asset", asset.name, "gross_purchase_amount", flt(item.valuation_rate))
+			frappe.db.set_value("Asset", asset.name, "purchase_receipt_amount", flt(item.valuation_rate))
 
 	def make_stock_adjustment_entry(
 		self, gl_entries, item, voucher_wise_stock_value, account_currency
@@ -1845,6 +1685,7 @@
 					"po_detail": "purchase_order_item",
 					"material_request": "material_request",
 					"material_request_item": "material_request_item",
+					"wip_composite_asset": "wip_composite_asset",
 				},
 				"postprocess": update_item,
 				"condition": lambda doc: abs(doc.received_qty) < abs(doc.qty),
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index b4dd75a..13593bc 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -5,7 +5,7 @@
 import unittest
 
 import frappe
-from frappe.tests.utils import change_settings
+from frappe.tests.utils import FrappeTestCase, change_settings
 from frappe.utils import add_days, cint, flt, getdate, nowdate, today
 
 import erpnext
@@ -38,7 +38,7 @@
 test_ignore = ["Serial No"]
 
 
-class TestPurchaseInvoice(unittest.TestCase, StockTestMixin):
+class TestPurchaseInvoice(FrappeTestCase, StockTestMixin):
 	@classmethod
 	def setUpClass(self):
 		unlink_payment_on_cancel_of_invoice()
@@ -48,6 +48,9 @@
 	def tearDownClass(self):
 		unlink_payment_on_cancel_of_invoice(0)
 
+	def tearDown(self):
+		frappe.db.rollback()
+
 	def test_purchase_invoice_received_qty(self):
 		"""
 		1. Test if received qty is validated against accepted + rejected
@@ -422,6 +425,7 @@
 			self.assertEqual(tax.tax_amount, expected_values[i][1])
 			self.assertEqual(tax.total, expected_values[i][2])
 
+	@change_settings("Accounts Settings", {"unlink_payment_on_cancellation_of_invoice": 1})
 	def test_purchase_invoice_with_advance(self):
 		from erpnext.accounts.doctype.journal_entry.test_journal_entry import (
 			test_records as jv_test_records,
@@ -476,6 +480,7 @@
 			)
 		)
 
+	@change_settings("Accounts Settings", {"unlink_payment_on_cancellation_of_invoice": 1})
 	def test_invoice_with_advance_and_multi_payment_terms(self):
 		from erpnext.accounts.doctype.journal_entry.test_journal_entry import (
 			test_records as jv_test_records,
@@ -1220,6 +1225,7 @@
 		acc_settings.submit_journal_entriessubmit_journal_entries = 0
 		acc_settings.save()
 
+	@change_settings("Accounts Settings", {"unlink_payment_on_cancellation_of_invoice": 1})
 	def test_gain_loss_with_advance_entry(self):
 		unlink_enabled = frappe.db.get_value(
 			"Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice"
@@ -1420,6 +1426,7 @@
 		)
 		frappe.db.set_value("Company", "_Test Company", "exchange_gain_loss_account", original_account)
 
+	@change_settings("Accounts Settings", {"unlink_payment_on_cancellation_of_invoice": 1})
 	def test_purchase_invoice_advance_taxes(self):
 		from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
 
@@ -1744,7 +1751,6 @@
 
 		pi = make_purchase_invoice(
 			company="_Test Company",
-			customer="_Test Supplier",
 			do_not_save=True,
 			do_not_submit=True,
 			rate=1000,
@@ -1862,7 +1868,6 @@
 
 		pi = make_purchase_invoice(
 			company="_Test Company",
-			customer="_Test Supplier",
 			do_not_save=True,
 			do_not_submit=True,
 			rate=1000,
@@ -1892,6 +1897,82 @@
 		clear_dimension_defaults("Branch")
 		disable_dimension()
 
+	def test_repost_accounting_entries(self):
+		pi = make_purchase_invoice(
+			rate=1000,
+			price_list_rate=1000,
+			qty=1,
+		)
+		expected_gle = [
+			["_Test Account Cost for Goods Sold - _TC", 1000, 0.0, nowdate()],
+			["Creditors - _TC", 0.0, 1000, nowdate()],
+		]
+		check_gl_entries(self, pi.name, expected_gle, nowdate())
+
+		pi.items[0].expense_account = "Service - _TC"
+		pi.save()
+		pi.load_from_db()
+		self.assertTrue(pi.repost_required)
+		pi.repost_accounting_entries()
+
+		expected_gle = [
+			["Creditors - _TC", 0.0, 1000, nowdate()],
+			["Service - _TC", 1000, 0.0, nowdate()],
+		]
+		check_gl_entries(self, pi.name, expected_gle, nowdate())
+		pi.load_from_db()
+		self.assertFalse(pi.repost_required)
+
+	@change_settings("Buying Settings", {"supplier_group": None})
+	def test_purchase_invoice_without_supplier_group(self):
+		# Create a Supplier
+		test_supplier_name = "_Test Supplier Without Supplier Group"
+		if not frappe.db.exists("Supplier", test_supplier_name):
+			supplier = frappe.get_doc(
+				{
+					"doctype": "Supplier",
+					"supplier_name": test_supplier_name,
+				}
+			).insert(ignore_permissions=True)
+
+			self.assertEqual(supplier.supplier_group, None)
+
+		po = create_purchase_order(
+			supplier=test_supplier_name,
+			rate=3000,
+			item="_Test Non Stock Item",
+			posting_date="2021-09-15",
+		)
+
+		pi = make_purchase_invoice(supplier=test_supplier_name)
+
+		self.assertEqual(po.docstatus, 1)
+		self.assertEqual(pi.docstatus, 1)
+
+	def test_default_cost_center_for_purchase(self):
+		from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
+
+		for c_center in ["_Test Cost Center Selling", "_Test Cost Center Buying"]:
+			create_cost_center(cost_center_name=c_center)
+
+		item = create_item(
+			"_Test Cost Center Item For Purchase",
+			is_stock_item=1,
+			buying_cost_center="_Test Cost Center Buying - _TC",
+			selling_cost_center="_Test Cost Center Selling - _TC",
+		)
+
+		pi = make_purchase_invoice(
+			item=item.name, qty=1, rate=1000, update_stock=True, do_not_submit=True, cost_center=""
+		)
+
+		pi.items[0].cost_center = ""
+		pi.set_missing_values()
+		pi.calculate_taxes_and_totals()
+		pi.save()
+
+		self.assertEqual(pi.items[0].cost_center, "_Test Cost Center Buying - _TC")
+
 
 def set_advance_flag(company, flag, default_account):
 	frappe.db.set_value(
diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
index 81c7577..424e942 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -77,6 +77,7 @@
   "manufacturer_part_no",
   "accounting",
   "expense_account",
+  "wip_composite_asset",
   "col_break5",
   "is_fixed_asset",
   "asset_location",
@@ -473,6 +474,7 @@
    "label": "Accounting"
   },
   {
+   "allow_on_submit": 1,
    "fieldname": "expense_account",
    "fieldtype": "Link",
    "label": "Expense Head",
@@ -902,12 +904,18 @@
    "no_copy": 1,
    "options": "Serial and Batch Bundle",
    "print_hide": 1
+  },
+  {
+   "fieldname": "wip_composite_asset",
+   "fieldtype": "Link",
+   "label": "WIP Composite Asset",
+   "options": "Asset"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-07-26 12:54:53.178156",
+ "modified": "2023-10-03 21:01:01.824892",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice Item",
diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json
index d86abad..347cae0 100644
--- a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json
+++ b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json
@@ -86,6 +86,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "allow_on_submit": 1,
    "columns": 2,
    "fieldname": "account_head",
    "fieldtype": "Link",
@@ -97,6 +98,7 @@
    "reqd": 1
   },
   {
+   "allow_on_submit": 1,
    "default": ":Company",
    "fieldname": "cost_center",
    "fieldtype": "Link",
diff --git a/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.json b/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.json
index 8d56c9b..5b7cd2b 100644
--- a/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.json
+++ b/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.json
@@ -55,7 +55,7 @@
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-07-27 15:47:58.975034",
+ "modified": "2023-09-26 14:21:27.362567",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Repost Accounting Ledger",
@@ -77,5 +77,6 @@
  ],
  "sort_field": "modified",
  "sort_order": "DESC",
- "states": []
+ "states": [],
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py b/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py
index 4cf2ed2..dbb0971 100644
--- a/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py
+++ b/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py
@@ -21,29 +21,8 @@
 
 	def validate_for_deferred_accounting(self):
 		sales_docs = [x.voucher_no for x in self.vouchers if x.voucher_type == "Sales Invoice"]
-		docs_with_deferred_revenue = frappe.db.get_all(
-			"Sales Invoice Item",
-			filters={"parent": ["in", sales_docs], "docstatus": 1, "enable_deferred_revenue": True},
-			fields=["parent"],
-			as_list=1,
-		)
-
 		purchase_docs = [x.voucher_no for x in self.vouchers if x.voucher_type == "Purchase Invoice"]
-		docs_with_deferred_expense = frappe.db.get_all(
-			"Purchase Invoice Item",
-			filters={"parent": ["in", purchase_docs], "docstatus": 1, "enable_deferred_expense": 1},
-			fields=["parent"],
-			as_list=1,
-		)
-
-		if docs_with_deferred_revenue or docs_with_deferred_expense:
-			frappe.throw(
-				_("Documents: {0} have deferred revenue/expense enabled for them. Cannot repost.").format(
-					frappe.bold(
-						comma_and([x[0] for x in docs_with_deferred_expense + docs_with_deferred_revenue])
-					)
-				)
-			)
+		validate_docs_for_deferred_accounting(sales_docs, purchase_docs)
 
 	def validate_for_closed_fiscal_year(self):
 		if self.vouchers:
@@ -139,14 +118,17 @@
 		return rendered_page
 
 	def on_submit(self):
-		job_name = "repost_accounting_ledger_" + self.name
-		frappe.enqueue(
-			method="erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger.start_repost",
-			account_repost_doc=self.name,
-			is_async=True,
-			job_name=job_name,
-		)
-		frappe.msgprint(_("Repost has started in the background"))
+		if len(self.vouchers) > 1:
+			job_name = "repost_accounting_ledger_" + self.name
+			frappe.enqueue(
+				method="erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger.start_repost",
+				account_repost_doc=self.name,
+				is_async=True,
+				job_name=job_name,
+			)
+			frappe.msgprint(_("Repost has started in the background"))
+		else:
+			start_repost(self.name)
 
 
 @frappe.whitelist()
@@ -181,3 +163,26 @@
 					doc.make_gl_entries()
 
 				frappe.db.commit()
+
+
+def validate_docs_for_deferred_accounting(sales_docs, purchase_docs):
+	docs_with_deferred_revenue = frappe.db.get_all(
+		"Sales Invoice Item",
+		filters={"parent": ["in", sales_docs], "docstatus": 1, "enable_deferred_revenue": True},
+		fields=["parent"],
+		as_list=1,
+	)
+
+	docs_with_deferred_expense = frappe.db.get_all(
+		"Purchase Invoice Item",
+		filters={"parent": ["in", purchase_docs], "docstatus": 1, "enable_deferred_expense": 1},
+		fields=["parent"],
+		as_list=1,
+	)
+
+	if docs_with_deferred_revenue or docs_with_deferred_expense:
+		frappe.throw(
+			_("Documents: {0} have deferred revenue/expense enabled for them. Cannot repost.").format(
+				frappe.bold(comma_and([x[0] for x in docs_with_deferred_expense + docs_with_deferred_revenue]))
+			)
+		)
diff --git a/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.json b/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.json
index 5175fd1..ed8d395 100644
--- a/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.json
+++ b/erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.json
@@ -99,7 +99,7 @@
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2022-11-08 07:38:40.079038",
+ "modified": "2023-09-26 14:21:35.719727",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Repost Payment Ledger",
@@ -155,5 +155,6 @@
  ],
  "sort_field": "modified",
  "sort_order": "DESC",
- "states": []
+ "states": [],
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index e5adeae..cd725b9 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -26,6 +26,7 @@
   "is_return",
   "return_against",
   "update_billed_amount_in_sales_order",
+  "update_billed_amount_in_delivery_note",
   "is_debit_note",
   "amended_from",
   "accounting_dimensions_section",
@@ -2153,6 +2154,13 @@
    "fieldname": "use_company_roundoff_cost_center",
    "fieldtype": "Check",
    "label": "Use Company default Cost Center for Round off"
+  },
+  {
+   "default": "0",
+   "depends_on": "eval: doc.is_return",
+   "fieldname": "update_billed_amount_in_delivery_note",
+   "fieldtype": "Check",
+   "label": "Update Billed Amount in Delivery Note"
   }
  ],
  "icon": "fa fa-file-text",
@@ -2165,7 +2173,7 @@
    "link_fieldname": "consolidated_invoice"
   }
  ],
- "modified": "2023-07-25 16:02:18.988799",
+ "modified": "2023-11-03 14:39:38.012346",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index db3d5c6..8033dbf 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -11,13 +11,13 @@
 
 import erpnext
 from erpnext.accounts.deferred_revenue import validate_service_stop_date
-from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
-	get_accounting_dimensions,
-)
 from erpnext.accounts.doctype.loyalty_program.loyalty_program import (
 	get_loyalty_program_details_with_points,
 	validate_loyalty_points,
 )
+from erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger import (
+	validate_docs_for_deferred_accounting,
+)
 from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import (
 	get_party_tax_withholding_details,
 )
@@ -168,6 +168,12 @@
 		self.validate_account_for_change_amount()
 		self.validate_income_account()
 
+	def validate_for_repost(self):
+		self.validate_write_off_account()
+		self.validate_account_for_change_amount()
+		self.validate_income_account()
+		validate_docs_for_deferred_accounting([self.name], [])
+
 	def validate_fixed_asset(self):
 		for d in self.get("items"):
 			if d.is_fixed_asset and d.meta.get_field("asset") and d.asset:
@@ -247,6 +253,7 @@
 
 		self.update_status_updater_args()
 		self.update_prevdoc_status()
+
 		self.update_billing_status_in_dn()
 		self.clear_unallocated_mode_of_payments()
 
@@ -517,90 +524,22 @@
 
 	def on_update_after_submit(self):
 		if hasattr(self, "repost_required"):
-			needs_repost = 0
-
-			# Check if any field affecting accounting entry is altered
-			doc_before_update = self.get_doc_before_save()
-			accounting_dimensions = get_accounting_dimensions() + ["cost_center", "project"]
-
-			# Check if opening entry check updated
-			if doc_before_update.get("is_opening") != self.is_opening:
-				needs_repost = 1
-
-			if not needs_repost:
-				# Parent Level Accounts excluding party account
-				for field in (
-					"additional_discount_account",
-					"cash_bank_account",
-					"account_for_change_amount",
-					"write_off_account",
-					"loyalty_redemption_account",
-					"unrealized_profit_loss_account",
-				):
-					if doc_before_update.get(field) != self.get(field):
-						needs_repost = 1
-						break
-
-				# Check for parent accounting dimensions
-				for dimension in accounting_dimensions:
-					if doc_before_update.get(dimension) != self.get(dimension):
-						needs_repost = 1
-						break
-
-				# Check for child tables
-				if self.check_if_child_table_updated(
-					"items",
-					doc_before_update,
-					("income_account", "expense_account", "discount_account"),
-					accounting_dimensions,
-				):
-					needs_repost = 1
-
-				if self.check_if_child_table_updated(
-					"taxes", doc_before_update, ("account_head",), accounting_dimensions
-				):
-					needs_repost = 1
-
-			self.validate_accounts()
-
-			# validate if deferred revenue is enabled for any item
-			# Don't allow to update the invoice if deferred revenue is enabled
-			if needs_repost:
-				for item in self.get("items"):
-					if item.enable_deferred_revenue:
-						frappe.throw(
-							_(
-								"Deferred Revenue is enabled for item {0}. You cannot update the invoice after submission."
-							).format(item.item_code)
-						)
-
-			self.db_set("repost_required", needs_repost)
-
-	def check_if_child_table_updated(
-		self, child_table, doc_before_update, fields_to_check, accounting_dimensions
-	):
-		# Check if any field affecting accounting entry is altered
-		for index, item in enumerate(self.get(child_table)):
-			for field in fields_to_check:
-				if doc_before_update.get(child_table)[index].get(field) != item.get(field):
-					return True
-
-			for dimension in accounting_dimensions:
-				if doc_before_update.get(child_table)[index].get(dimension) != item.get(dimension):
-					return True
-
-		return False
-
-	@frappe.whitelist()
-	def repost_accounting_entries(self):
-		if self.repost_required:
-			self.docstatus = 2
-			self.make_gl_entries_on_cancel()
-			self.docstatus = 1
-			self.make_gl_entries()
-			self.db_set("repost_required", 0)
-		else:
-			frappe.throw(_("No updates pending for reposting"))
+			fields_to_check = [
+				"additional_discount_account",
+				"cash_bank_account",
+				"account_for_change_amount",
+				"write_off_account",
+				"loyalty_redemption_account",
+				"unrealized_profit_loss_account",
+			]
+			child_tables = {
+				"items": ("income_account", "expense_account", "discount_account"),
+				"taxes": ("account_head",),
+			}
+			self.needs_repost = self.check_if_fields_updated(fields_to_check, child_tables)
+			if self.needs_repost:
+				self.validate_for_repost()
+				self.db_set("repost_required", self.needs_repost)
 
 	def set_paid_amount(self):
 		paid_amount = 0.0
@@ -1081,7 +1020,7 @@
 
 	def make_customer_gl_entry(self, gl_entries):
 		# Checked both rounding_adjustment and rounded_total
-		# because rounded_total had value even before introcution of posting GLE based on rounded total
+		# because rounded_total had value even before introduction of posting GLE based on rounded total
 		grand_total = (
 			self.rounded_total if (self.rounding_adjustment and self.rounded_total) else self.grand_total
 		)
@@ -1336,7 +1275,7 @@
 				if skip_change_gl_entries and payment_mode.account == self.account_for_change_amount:
 					payment_mode.base_amount -= flt(self.change_amount)
 
-				if payment_mode.amount:
+				if payment_mode.base_amount:
 					# POS, make payment entries
 					gl_entries.append(
 						self.get_gl_dict(
@@ -1505,6 +1444,8 @@
 			)
 
 	def update_billing_status_in_dn(self, update_modified=True):
+		if self.is_return and not self.update_billed_amount_in_delivery_note:
+			return
 		updated_delivery_notes = []
 		for d in self.get("items"):
 			if d.dn_detail:
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 84b0149..21cc253 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -6,7 +6,7 @@
 
 import frappe
 from frappe.model.dynamic_links import get_dynamic_link_map
-from frappe.tests.utils import change_settings
+from frappe.tests.utils import FrappeTestCase, change_settings
 from frappe.utils import add_days, flt, getdate, nowdate, today
 
 import erpnext
@@ -26,6 +26,7 @@
 from erpnext.controllers.accounts_controller import update_invoice_status
 from erpnext.controllers.taxes_and_totals import get_itemised_tax_breakup_data
 from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
+from erpnext.selling.doctype.customer.test_customer import get_customer_dict
 from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
 from erpnext.stock.doctype.item.test_item import create_item
 from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
@@ -44,13 +45,17 @@
 from erpnext.stock.utils import get_incoming_rate, get_stock_balance
 
 
-class TestSalesInvoice(unittest.TestCase):
+class TestSalesInvoice(FrappeTestCase):
 	def setUp(self):
 		from erpnext.stock.doctype.stock_ledger_entry.test_stock_ledger_entry import create_items
 
 		create_items(["_Test Internal Transfer Item"], uoms=[{"uom": "Box", "conversion_factor": 10}])
 		create_internal_parties()
 		setup_accounts()
+		frappe.db.set_single_value("Accounts Settings", "acc_frozen_upto", None)
+
+	def tearDown(self):
+		frappe.db.rollback()
 
 	def make(self):
 		w = frappe.copy_doc(test_records[0])
@@ -178,6 +183,7 @@
 		self.assertRaises(frappe.LinkExistsError, si.cancel)
 		unlink_payment_on_cancel_of_invoice()
 
+	@change_settings("Accounts Settings", {"unlink_payment_on_cancellation_of_invoice": 1})
 	def test_payment_entry_unlink_against_standalone_credit_note(self):
 		from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
 
@@ -510,70 +516,72 @@
 		self.assertEqual(si.grand_total, 5474.0)
 
 	def test_tax_calculation_with_item_tax_template(self):
+		import json
+
+		from erpnext.stock.get_item_details import get_item_details
+
+		# set tax template in item
+		item = frappe.get_cached_doc("Item", "_Test Item")
+		item.set(
+			"taxes",
+			[
+				{
+					"item_tax_template": "_Test Item Tax Template 1 - _TC",
+					"valid_from": add_days(nowdate(), -5),
+				}
+			],
+		)
+		item.save()
+
+		# create sales invoice with item
 		si = create_sales_invoice(qty=84, rate=4.6, do_not_save=True)
-		item_row = si.get("items")[0]
+		item_details = get_item_details(
+			doc=si,
+			args={
+				"item_code": item.item_code,
+				"company": si.company,
+				"doctype": "Sales Invoice",
+				"conversion_rate": 1.0,
+			},
+		)
+		tax_map = json.loads(item_details.item_tax_rate)
+		for tax in tax_map:
+			si.append(
+				"taxes",
+				{
+					"charge_type": "On Net Total",
+					"account_head": tax,
+					"rate": tax_map[tax],
+					"description": "Test",
+					"cost_center": "_Test Cost Center - _TC",
+				},
+			)
+		si.submit()
+		si.load_from_db()
 
-		add_items = [
-			(54, "_Test Account Excise Duty @ 12 - _TC"),
-			(288, "_Test Account Excise Duty @ 15 - _TC"),
-			(144, "_Test Account Excise Duty @ 20 - _TC"),
-			(430, "_Test Item Tax Template 1 - _TC"),
+		# check if correct tax values are applied from tax template
+		self.assertEqual(si.net_total, 386.4)
+
+		expected_taxes = [
+			{
+				"tax_amount": 19.32,
+				"total": 405.72,
+			},
+			{
+				"tax_amount": 38.64,
+				"total": 444.36,
+			},
+			{
+				"tax_amount": 57.96,
+				"total": 502.32,
+			},
 		]
-		for qty, item_tax_template in add_items:
-			item_row_copy = copy.deepcopy(item_row)
-			item_row_copy.qty = qty
-			item_row_copy.item_tax_template = item_tax_template
-			si.append("items", item_row_copy)
 
-		si.append(
-			"taxes",
-			{
-				"account_head": "_Test Account Excise Duty - _TC",
-				"charge_type": "On Net Total",
-				"cost_center": "_Test Cost Center - _TC",
-				"description": "Excise Duty",
-				"doctype": "Sales Taxes and Charges",
-				"rate": 11,
-			},
-		)
-		si.append(
-			"taxes",
-			{
-				"account_head": "_Test Account Education Cess - _TC",
-				"charge_type": "On Net Total",
-				"cost_center": "_Test Cost Center - _TC",
-				"description": "Education Cess",
-				"doctype": "Sales Taxes and Charges",
-				"rate": 0,
-			},
-		)
-		si.append(
-			"taxes",
-			{
-				"account_head": "_Test Account S&H Education Cess - _TC",
-				"charge_type": "On Net Total",
-				"cost_center": "_Test Cost Center - _TC",
-				"description": "S&H Education Cess",
-				"doctype": "Sales Taxes and Charges",
-				"rate": 3,
-			},
-		)
-		si.insert()
+		for i in range(len(expected_taxes)):
+			for key in expected_taxes[i]:
+				self.assertEqual(expected_taxes[i][key], si.get("taxes")[i].get(key))
 
-		self.assertEqual(si.net_total, 4600)
-
-		self.assertEqual(si.get("taxes")[0].tax_amount, 502.41)
-		self.assertEqual(si.get("taxes")[0].total, 5102.41)
-
-		self.assertEqual(si.get("taxes")[1].tax_amount, 197.80)
-		self.assertEqual(si.get("taxes")[1].total, 5300.21)
-
-		self.assertEqual(si.get("taxes")[2].tax_amount, 375.36)
-		self.assertEqual(si.get("taxes")[2].total, 5675.57)
-
-		self.assertEqual(si.grand_total, 5675.57)
-		self.assertEqual(si.rounding_adjustment, 0.43)
-		self.assertEqual(si.rounded_total, 5676.0)
+		self.assertEqual(si.get("base_total_taxes_and_charges"), 115.92)
 
 	def test_tax_calculation_with_multiple_items_and_discount(self):
 		si = create_sales_invoice(qty=1, rate=75, do_not_save=True)
@@ -1299,6 +1307,7 @@
 		dn.submit()
 		return dn
 
+	@change_settings("Accounts Settings", {"unlink_payment_on_cancellation_of_invoice": 1})
 	def test_sales_invoice_with_advance(self):
 		from erpnext.accounts.doctype.journal_entry.test_journal_entry import (
 			test_records as jv_test_records,
@@ -2491,12 +2500,6 @@
 			"stock_received_but_not_billed",
 			"Stock Received But Not Billed - _TC1",
 		)
-		frappe.db.set_value(
-			"Company",
-			"_Test Company 1",
-			"expenses_included_in_valuation",
-			"Expenses Included In Valuation - _TC1",
-		)
 
 		# begin test
 		si = create_sales_invoice(
@@ -2546,6 +2549,7 @@
 		)
 
 		si = frappe.copy_doc(test_records[0])
+		si.customer = "_Test Internal Customer 3"
 		si.update_stock = 1
 		si.set_warehouse = "Finished Goods - _TC"
 		si.set_target_warehouse = "Stores - _TC"
@@ -2774,6 +2778,13 @@
 			company="_Test Company",
 		)
 
+		tds_payable_account = create_account(
+			account_name="TDS Payable",
+			account_type="Tax",
+			parent_account="Duties and Taxes - _TC",
+			company="_Test Company",
+		)
+
 		si = create_sales_invoice(parent_cost_center="Main - _TC", do_not_save=1)
 		si.apply_discount_on = "Grand Total"
 		si.additional_discount_account = additional_discount_account
@@ -3072,8 +3083,8 @@
 			si.commission_rate = commission_rate
 			self.assertRaises(frappe.ValidationError, si.save)
 
+	@change_settings("Accounts Settings", {"acc_frozen_upto": add_days(getdate(), 1)})
 	def test_sales_invoice_submission_post_account_freezing_date(self):
-		frappe.db.set_single_value("Accounts Settings", "acc_frozen_upto", add_days(getdate(), 1))
 		si = create_sales_invoice(do_not_save=True)
 		si.posting_date = add_days(getdate(), 1)
 		si.save()
@@ -3082,8 +3093,6 @@
 		si.posting_date = getdate()
 		si.submit()
 
-		frappe.db.set_single_value("Accounts Settings", "acc_frozen_upto", None)
-
 	def test_over_billing_case_against_delivery_note(self):
 		"""
 		Test a case where duplicating the item with qty = 1 in the invoice
@@ -3112,6 +3121,13 @@
 
 		frappe.db.set_single_value("Accounts Settings", "over_billing_allowance", over_billing_allowance)
 
+	@change_settings(
+		"Accounts Settings",
+		{
+			"book_deferred_entries_via_journal_entry": 1,
+			"submit_journal_entries": 1,
+		},
+	)
 	def test_multi_currency_deferred_revenue_via_journal_entry(self):
 		deferred_account = create_account(
 			account_name="Deferred Revenue",
@@ -3119,11 +3135,6 @@
 			company="_Test Company",
 		)
 
-		acc_settings = frappe.get_single("Accounts Settings")
-		acc_settings.book_deferred_entries_via_journal_entry = 1
-		acc_settings.submit_journal_entries = 1
-		acc_settings.save()
-
 		item = create_item("_Test Item for Deferred Accounting")
 		item.enable_deferred_expense = 1
 		item.item_defaults[0].deferred_revenue_account = deferred_account
@@ -3189,13 +3200,6 @@
 			self.assertEqual(expected_gle[i][2], gle.debit)
 			self.assertEqual(getdate(expected_gle[i][3]), gle.posting_date)
 
-		acc_settings = frappe.get_single("Accounts Settings")
-		acc_settings.book_deferred_entries_via_journal_entry = 0
-		acc_settings.submit_journal_entries = 0
-		acc_settings.save()
-
-		frappe.db.set_single_value("Accounts Settings", "acc_frozen_upto", None)
-
 	def test_standalone_serial_no_return(self):
 		si = create_sales_invoice(
 			item_code="_Test Serialized Item With Series", update_stock=True, is_return=True, qty=-1
@@ -3400,6 +3404,24 @@
 
 		set_advance_flag(company="_Test Company", flag=0, default_account="")
 
+	@change_settings("Selling Settings", {"customer_group": None, "territory": None})
+	def test_sales_invoice_without_customer_group_and_territory(self):
+		# create a customer
+		if not frappe.db.exists("Customer", "_Test Simple Customer"):
+			customer_dict = get_customer_dict("_Test Simple Customer")
+			customer_dict.pop("customer_group")
+			customer_dict.pop("territory")
+			customer = frappe.get_doc(customer_dict).insert(ignore_permissions=True)
+
+			self.assertEqual(customer.customer_group, None)
+			self.assertEqual(customer.territory, None)
+
+		# create a sales invoice
+		si = create_sales_invoice(customer="_Test Simple Customer")
+		self.assertEqual(si.docstatus, 1)
+		self.assertEqual(si.customer_group, None)
+		self.assertEqual(si.territory, None)
+
 	@change_settings("Selling Settings", {"allow_negative_rates_for_items": 0})
 	def test_sales_return_negative_rate(self):
 		si = create_sales_invoice(is_return=1, qty=-2, rate=-10, do_not_save=True)
@@ -3671,6 +3693,20 @@
 		allowed_to_interact_with="_Test Company with perpetual inventory",
 	)
 
+	create_internal_customer(
+		customer_name="_Test Internal Customer 3",
+		represents_company="_Test Company",
+		allowed_to_interact_with="_Test Company",
+	)
+
+	account = create_account(
+		account_name="Unrealized Profit",
+		parent_account="Current Liabilities - _TC",
+		company="_Test Company",
+	)
+
+	frappe.db.set_value("Company", "_Test Company", "unrealized_profit_loss_account", account)
+
 	create_internal_supplier(
 		supplier_name="_Test Internal Supplier",
 		represents_company="Wind Power LLC",
diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
index abeaab1..5d2764b 100644
--- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
+++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
@@ -157,7 +157,6 @@
    "oldfieldname": "description",
    "oldfieldtype": "Text",
    "print_width": "200px",
-   "reqd": 1,
    "width": "200px"
   },
   {
@@ -912,4 +911,4 @@
  "sort_field": "modified",
  "sort_order": "DESC",
  "states": []
-}
\ No newline at end of file
+}
diff --git a/erpnext/accounts/doctype/subscription/subscription.js b/erpnext/accounts/doctype/subscription/subscription.js
index ae789b5..92f8a3a 100644
--- a/erpnext/accounts/doctype/subscription/subscription.js
+++ b/erpnext/accounts/doctype/subscription/subscription.js
@@ -18,6 +18,14 @@
 				}
 			};
 		});
+
+		frm.set_query('sales_tax_template', function () {
+			return {
+				filters: {
+					company: frm.doc.company
+				}
+			};
+		});
 	},
 
 	refresh: function (frm) {
diff --git a/erpnext/accounts/doctype/subscription/test_subscription.py b/erpnext/accounts/doctype/subscription/test_subscription.py
index 803e879..785fd04 100644
--- a/erpnext/accounts/doctype/subscription/test_subscription.py
+++ b/erpnext/accounts/doctype/subscription/test_subscription.py
@@ -4,6 +4,7 @@
 import unittest
 
 import frappe
+from frappe.tests.utils import FrappeTestCase
 from frappe.utils.data import (
 	add_days,
 	add_months,
@@ -21,11 +22,15 @@
 test_dependencies = ("UOM", "Item Group", "Item")
 
 
-class TestSubscription(unittest.TestCase):
+class TestSubscription(FrappeTestCase):
 	def setUp(self):
 		make_plans()
 		create_parties()
 		reset_settings()
+		frappe.db.set_single_value("Accounts Settings", "acc_frozen_upto", None)
+
+	def tearDown(self):
+		frappe.db.rollback()
 
 	def test_create_subscription_with_trial_with_correct_period(self):
 		subscription = create_subscription(
diff --git a/erpnext/accounts/doctype/subscription_plan/subscription_plan.py b/erpnext/accounts/doctype/subscription_plan/subscription_plan.py
index 75223c2..f6e5c56 100644
--- a/erpnext/accounts/doctype/subscription_plan/subscription_plan.py
+++ b/erpnext/accounts/doctype/subscription_plan/subscription_plan.py
@@ -22,7 +22,7 @@
 
 @frappe.whitelist()
 def get_plan_rate(
-	plan, quantity=1, customer=None, start_date=None, end_date=None, prorate_factor=1
+	plan, quantity=1, customer=None, start_date=None, end_date=None, prorate_factor=1, party=None
 ):
 	plan = frappe.get_doc("Subscription Plan", plan)
 	if plan.price_determination == "Fixed Rate":
@@ -40,6 +40,7 @@
 			customer_group=customer_group,
 			company=None,
 			qty=quantity,
+			party=party,
 		)
 		if not price:
 			return 0
diff --git a/erpnext/accounts/doctype/tax_rule/tax_rule.py b/erpnext/accounts/doctype/tax_rule/tax_rule.py
index 87c5e6d..ac0dd51 100644
--- a/erpnext/accounts/doctype/tax_rule/tax_rule.py
+++ b/erpnext/accounts/doctype/tax_rule/tax_rule.py
@@ -8,7 +8,7 @@
 from frappe import _
 from frappe.contacts.doctype.address.address import get_default_address
 from frappe.model.document import Document
-from frappe.utils import cint, cstr
+from frappe.utils import cstr
 from frappe.utils.nestedset import get_root_of
 
 from erpnext.setup.doctype.customer_group.customer_group import get_parent_customer_groups
@@ -34,7 +34,6 @@
 		self.validate_tax_template()
 		self.validate_from_to_dates("from_date", "to_date")
 		self.validate_filters()
-		self.validate_use_for_shopping_cart()
 
 	def validate_tax_template(self):
 		if self.tax_type == "Sales":
@@ -106,21 +105,6 @@
 			if tax_rule[0].priority == self.priority:
 				frappe.throw(_("Tax Rule Conflicts with {0}").format(tax_rule[0].name), ConflictingTaxRule)
 
-	def validate_use_for_shopping_cart(self):
-		"""If shopping cart is enabled and no tax rule exists for shopping cart, enable this one"""
-		if (
-			not self.use_for_shopping_cart
-			and cint(frappe.db.get_single_value("E Commerce Settings", "enabled"))
-			and not frappe.db.get_value("Tax Rule", {"use_for_shopping_cart": 1, "name": ["!=", self.name]})
-		):
-
-			self.use_for_shopping_cart = 1
-			frappe.msgprint(
-				_(
-					"Enabling 'Use for Shopping Cart', as Shopping Cart is enabled and there should be at least one Tax Rule for Shopping Cart"
-				)
-			)
-
 
 @frappe.whitelist()
 def get_party_details(party, party_type, args=None):
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index d496778..70a8470 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -41,7 +41,7 @@
 					from_repost=from_repost,
 				)
 				save_entries(gl_map, adv_adj, update_outstanding, from_repost)
-			# Post GL Map proccess there may no be any GL Entries
+			# Post GL Map process there may no be any GL Entries
 			elif gl_map:
 				frappe.throw(
 					_(
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index b99bb83..16e73ea 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -5,13 +5,8 @@
 from typing import Optional
 
 import frappe
-from frappe import _, msgprint, scrub
-from frappe.contacts.doctype.address.address import (
-	get_address_display,
-	get_company_address,
-	get_default_address,
-)
-from frappe.contacts.doctype.contact.contact import get_contact_details
+from frappe import _, msgprint, qb, scrub
+from frappe.contacts.doctype.address.address import get_company_address, get_default_address
 from frappe.core.doctype.user_permission.user_permission import get_permitted_documents
 from frappe.model.utils import get_fetch_values
 from frappe.query_builder.functions import Abs, Date, Sum
@@ -133,6 +128,7 @@
 		party_address,
 		company_address,
 		shipping_address,
+		ignore_permissions=ignore_permissions,
 	)
 	set_contact_details(party_details, party, party_type)
 	set_other_values(party_details, party, party_type)
@@ -193,6 +189,8 @@
 	party_address=None,
 	company_address=None,
 	shipping_address=None,
+	*,
+	ignore_permissions=False
 ):
 	billing_address_field = (
 		"customer_address" if party_type == "Lead" else party_type.lower() + "_address"
@@ -205,13 +203,17 @@
 			get_fetch_values(doctype, billing_address_field, party_details[billing_address_field])
 		)
 	# address display
-	party_details.address_display = get_address_display(party_details[billing_address_field])
+	party_details.address_display = render_address(
+		party_details[billing_address_field], check_permissions=not ignore_permissions
+	)
 	# shipping address
 	if party_type in ["Customer", "Lead"]:
 		party_details.shipping_address_name = shipping_address or get_party_shipping_address(
 			party_type, party.name
 		)
-		party_details.shipping_address = get_address_display(party_details["shipping_address_name"])
+		party_details.shipping_address = render_address(
+			party_details["shipping_address_name"], check_permissions=not ignore_permissions
+		)
 		if doctype:
 			party_details.update(
 				get_fetch_values(doctype, "shipping_address_name", party_details.shipping_address_name)
@@ -229,7 +231,7 @@
 		if shipping_address:
 			party_details.update(
 				shipping_address=shipping_address,
-				shipping_address_display=get_address_display(shipping_address),
+				shipping_address_display=render_address(shipping_address),
 				**get_fetch_values(doctype, "shipping_address", shipping_address)
 			)
 
@@ -238,7 +240,8 @@
 			party_details.update(
 				billing_address=party_details.company_address,
 				billing_address_display=(
-					party_details.company_address_display or get_address_display(party_details.company_address)
+					party_details.company_address_display
+					or render_address(party_details.company_address, check_permissions=False)
 				),
 				**get_fetch_values(doctype, "billing_address", party_details.company_address)
 			)
@@ -290,7 +293,21 @@
 			}
 		)
 	else:
-		party_details.update(get_contact_details(party_details.contact_person))
+		fields = [
+			"name as contact_person",
+			"full_name as contact_display",
+			"email_id as contact_email",
+			"mobile_no as contact_mobile",
+			"phone as contact_phone",
+			"designation as contact_designation",
+			"department as contact_department",
+		]
+
+		contact_details = frappe.db.get_value(
+			"Contact", party_details.contact_person, fields, as_dict=True
+		)
+
+		party_details.update(contact_details)
 
 
 def set_other_values(party_details, party, party_type):
@@ -463,11 +480,19 @@
 
 def get_party_gle_currency(party_type, party, company):
 	def generator():
-		existing_gle_currency = frappe.db.sql(
-			"""select account_currency from `tabGL Entry`
-			where docstatus=1 and company=%(company)s and party_type=%(party_type)s and party=%(party)s
-			limit 1""",
-			{"company": company, "party_type": party_type, "party": party},
+		gl = qb.DocType("GL Entry")
+		existing_gle_currency = (
+			qb.from_(gl)
+			.select(gl.account_currency)
+			.where(
+				(gl.docstatus == 1)
+				& (gl.company == company)
+				& (gl.party_type == party_type)
+				& (gl.party == party)
+				& (gl.is_cancelled == 0)
+			)
+			.limit(1)
+			.run()
 		)
 
 		return existing_gle_currency[0][0] if existing_gle_currency else None
@@ -995,3 +1020,13 @@
 		doc.append("accounts", accounts)
 
 		doc.save()
+
+
+def render_address(address, check_permissions=True):
+	try:
+		from frappe.contacts.doctype.address.address import render_address as _render
+	except ImportError:
+		# Older frappe versions where this function is not available
+		from frappe.contacts.doctype.address.address import get_address_display as _render
+
+	return frappe.call(_render, address, check_permissions=check_permissions)
diff --git a/erpnext/accounts/report/accounts_payable/accounts_payable.js b/erpnext/accounts/report/accounts_payable/accounts_payable.js
index 27a8570..eff705d 100644
--- a/erpnext/accounts/report/accounts_payable/accounts_payable.js
+++ b/erpnext/accounts/report/accounts_payable/accounts_payable.js
@@ -95,30 +95,27 @@
 			"options": "Payment Terms Template"
 		},
 		{
-			"fieldname": "party_type",
+			"fieldname":"party_type",
 			"label": __("Party Type"),
-			"fieldtype": "Link",
-			"options": "Party Type",
-			get_query: () => {
-				return {
-					filters: {
-						'account_type': 'Payable'
-					}
-				};
-			},
-			on_change: () => {
+			"fieldtype": "Autocomplete",
+			options: get_party_type_options(),
+			on_change: function() {
 				frappe.query_report.set_filter_value('party', "");
-				let party_type = frappe.query_report.get_filter_value('party_type');
 				frappe.query_report.toggle_filter_display('supplier_group', frappe.query_report.get_filter_value('party_type') !== "Supplier");
-
 			}
-
 		},
 		{
 			"fieldname":"party",
 			"label": __("Party"),
-			"fieldtype": "Dynamic Link",
-			"options": "party_type",
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
+				if (!frappe.query_report.filters) return;
+
+				let party_type = frappe.query_report.get_filter_value('party_type');
+				if (!party_type) return;
+
+				return frappe.db.get_link_options(party_type, txt);
+			},
 		},
 		{
 			"fieldname": "supplier_group",
@@ -146,7 +143,13 @@
 			"fieldname": "show_future_payments",
 			"label": __("Show Future Payments"),
 			"fieldtype": "Check",
+		},
+		{
+			"fieldname": "ignore_accounts",
+			"label": __("Group by Voucher"),
+			"fieldtype": "Check",
 		}
+
 	],
 
 	"formatter": function(value, row, column, data, default_formatter) {
@@ -167,3 +170,15 @@
 }
 
 erpnext.utils.add_dimensions('Accounts Payable', 9);
+
+function get_party_type_options() {
+	let options = [];
+	frappe.db.get_list(
+		"Party Type", {filters:{"account_type": "Payable"}, fields:['name']}
+	).then((res) => {
+		res.forEach((party_type) => {
+			options.push(party_type.name);
+		});
+	});
+	return options;
+}
diff --git a/erpnext/accounts/report/accounts_payable/test_accounts_payable.py b/erpnext/accounts/report/accounts_payable/test_accounts_payable.py
index 3cf93cc..9f03d92 100644
--- a/erpnext/accounts/report/accounts_payable/test_accounts_payable.py
+++ b/erpnext/accounts/report/accounts_payable/test_accounts_payable.py
@@ -34,7 +34,7 @@
 		filters = {
 			"company": self.company,
 			"party_type": "Supplier",
-			"party": self.supplier,
+			"party": [self.supplier],
 			"report_date": today(),
 			"range1": 30,
 			"range2": 60,
diff --git a/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js b/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js
index ea20072..9e575e6 100644
--- a/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js
+++ b/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js
@@ -72,10 +72,27 @@
 			}
 		},
 		{
-			"fieldname":"supplier",
-			"label": __("Supplier"),
-			"fieldtype": "Link",
-			"options": "Supplier"
+			"fieldname":"party_type",
+			"label": __("Party Type"),
+			"fieldtype": "Autocomplete",
+			options: get_party_type_options(),
+			on_change: function() {
+				frappe.query_report.set_filter_value('party', "");
+				frappe.query_report.toggle_filter_display('supplier_group', frappe.query_report.get_filter_value('party_type') !== "Supplier");
+			}
+		},
+		{
+			"fieldname":"party",
+			"label": __("Party"),
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
+				if (!frappe.query_report.filters) return;
+
+				let party_type = frappe.query_report.get_filter_value('party_type');
+				if (!party_type) return;
+
+				return frappe.db.get_link_options(party_type, txt);
+			},
 		},
 		{
 			"fieldname":"payment_terms_template",
@@ -105,3 +122,15 @@
 }
 
 erpnext.utils.add_dimensions('Accounts Payable Summary', 9);
+
+function get_party_type_options() {
+	let options = [];
+	frappe.db.get_list(
+		"Party Type", {filters:{"account_type": "Payable"}, fields:['name']}
+	).then((res) => {
+		res.forEach((party_type) => {
+			options.push(party_type.name);
+		});
+	});
+	return options;
+}
\ No newline at end of file
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
index bb00d61..786aad6 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
@@ -1,6 +1,8 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
+frappe.provide("erpnext.utils");
+
 frappe.query_reports["Accounts Receivable"] = {
 	"filters": [
 		{
@@ -38,30 +40,27 @@
 			}
 		},
 		{
-			"fieldname": "party_type",
+			"fieldname":"party_type",
 			"label": __("Party Type"),
-			"fieldtype": "Link",
-			"options": "Party Type",
-			"Default": "Customer",
-			get_query: () => {
-				return {
-					filters: {
-						'account_type': 'Receivable'
-					}
-				};
-			},
-			on_change: () => {
+			"fieldtype": "Autocomplete",
+			options: get_party_type_options(),
+			on_change: function() {
 				frappe.query_report.set_filter_value('party', "");
-				let party_type = frappe.query_report.get_filter_value('party_type');
 				frappe.query_report.toggle_filter_display('customer_group', frappe.query_report.get_filter_value('party_type') !== "Customer");
-
 			}
 		},
 		{
 			"fieldname":"party",
 			"label": __("Party"),
-			"fieldtype": "Dynamic Link",
-			"options": "party_type",
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
+				if (!frappe.query_report.filters) return;
+
+				let party_type = frappe.query_report.get_filter_value('party_type');
+				if (!party_type) return;
+
+				return frappe.db.get_link_options(party_type, txt);
+			},
 		},
 		{
 			"fieldname": "party_account",
@@ -173,7 +172,13 @@
 			"fieldname": "show_remarks",
 			"label": __("Show Remarks"),
 			"fieldtype": "Check",
+		},
+		{
+			"fieldname": "ignore_accounts",
+			"label": __("Group by Voucher"),
+			"fieldtype": "Check",
 		}
+
 	],
 
 	"formatter": function(value, row, column, data, default_formatter) {
@@ -194,3 +199,16 @@
 }
 
 erpnext.utils.add_dimensions('Accounts Receivable', 9);
+
+
+function get_party_type_options() {
+	let options = [];
+	frappe.db.get_list(
+		"Party Type", {filters:{"account_type": "Receivable"}, fields:['name']}
+	).then((res) => {
+		res.forEach((party_type) => {
+			options.push(party_type.name);
+		});
+	});
+	return options;
+}
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index 7942402..f24a24e 100755
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -116,7 +116,12 @@
 		# build all keys, since we want to exclude vouchers beyond the report date
 		for ple in self.ple_entries:
 			# get the balance object for voucher_type
-			key = (ple.voucher_type, ple.voucher_no, ple.party)
+
+			if self.filters.get("ingore_accounts"):
+				key = (ple.voucher_type, ple.voucher_no, ple.party)
+			else:
+				key = (ple.account, ple.voucher_type, ple.voucher_no, ple.party)
+
 			if not key in self.voucher_balance:
 				self.voucher_balance[key] = frappe._dict(
 					voucher_type=ple.voucher_type,
@@ -183,7 +188,10 @@
 			):
 				return
 
-		key = (ple.against_voucher_type, ple.against_voucher_no, ple.party)
+		if self.filters.get("ingore_accounts"):
+			key = (ple.against_voucher_type, ple.against_voucher_no, ple.party)
+		else:
+			key = (ple.account, ple.against_voucher_type, ple.against_voucher_no, ple.party)
 
 		# If payment is made against credit note
 		# and credit note is made against a Sales Invoice
@@ -192,13 +200,19 @@
 			if ple.against_voucher_no in self.return_entries:
 				return_against = self.return_entries.get(ple.against_voucher_no)
 				if return_against:
-					key = (ple.against_voucher_type, return_against, ple.party)
+					if self.filters.get("ingore_accounts"):
+						key = (ple.against_voucher_type, return_against, ple.party)
+					else:
+						key = (ple.account, ple.against_voucher_type, return_against, ple.party)
 
 		row = self.voucher_balance.get(key)
 
 		if not row:
 			# no invoice, this is an invoice / stand-alone payment / credit note
-			row = self.voucher_balance.get((ple.voucher_type, ple.voucher_no, ple.party))
+			if self.filters.get("ingore_accounts"):
+				row = self.voucher_balance.get((ple.voucher_type, ple.voucher_no, ple.party))
+			else:
+				row = self.voucher_balance.get((ple.account, ple.voucher_type, ple.voucher_no, ple.party))
 
 		row.party_type = ple.party_type
 		return row
@@ -718,6 +732,7 @@
 		query = (
 			qb.from_(ple)
 			.select(
+				ple.name,
 				ple.account,
 				ple.voucher_type,
 				ple.voucher_no,
@@ -731,13 +746,15 @@
 				ple.account_currency,
 				ple.amount,
 				ple.amount_in_account_currency,
-				ple.remarks,
 			)
 			.where(ple.delinked == 0)
 			.where(Criterion.all(self.qb_selection_filter))
 			.where(Criterion.any(self.or_filters))
 		)
 
+		if self.filters.get("show_remarks"):
+			query = query.select(ple.remarks)
+
 		if self.filters.get("group_by_party"):
 			query = query.orderby(self.ple.party, self.ple.posting_date)
 		else:
@@ -801,7 +818,7 @@
 			self.qb_selection_filter.append(self.filters.party_type == self.ple.party_type)
 
 		if self.filters.get("party"):
-			self.qb_selection_filter.append(self.filters.party == self.ple.party)
+			self.qb_selection_filter.append(self.ple.party.isin(self.filters.party))
 
 		if self.filters.party_account:
 			self.qb_selection_filter.append(self.ple.account == self.filters.party_account)
diff --git a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py
index b98916e..cbeb6d3 100644
--- a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py
@@ -1,6 +1,7 @@
 import unittest
 
 import frappe
+from frappe import qb
 from frappe.tests.utils import FrappeTestCase, change_settings
 from frappe.utils import add_days, flt, getdate, today
 
@@ -23,29 +24,6 @@
 	def tearDown(self):
 		frappe.db.rollback()
 
-	def create_usd_account(self):
-		name = "Debtors USD"
-		exists = frappe.db.get_list(
-			"Account", filters={"company": "_Test Company 2", "account_name": "Debtors USD"}
-		)
-		if exists:
-			self.debtors_usd = exists[0].name
-		else:
-			debtors = frappe.get_doc(
-				"Account",
-				frappe.db.get_list(
-					"Account", filters={"company": "_Test Company 2", "account_name": "Debtors"}
-				)[0].name,
-			)
-
-			debtors_usd = frappe.new_doc("Account")
-			debtors_usd.company = debtors.company
-			debtors_usd.account_name = "Debtors USD"
-			debtors_usd.account_currency = "USD"
-			debtors_usd.parent_account = debtors.parent_account
-			debtors_usd.account_type = debtors.account_type
-			self.debtors_usd = debtors_usd.save().name
-
 	def create_sales_invoice(self, no_payment_schedule=False, do_not_submit=False):
 		frappe.set_user("Administrator")
 		si = create_sales_invoice(
@@ -573,7 +551,7 @@
 		filters = {
 			"company": self.company,
 			"party_type": "Customer",
-			"party": self.customer,
+			"party": [self.customer],
 			"report_date": today(),
 			"range1": 30,
 			"range2": 60,
@@ -605,3 +583,132 @@
 		for field in expected:
 			with self.subTest(field=field):
 				self.assertEqual(report_output.get(field), expected.get(field))
+
+	def test_multi_select_party_filter(self):
+		self.customer1 = self.customer
+		self.create_customer("_Test Customer 2")
+		self.customer2 = self.customer
+		self.create_customer("_Test Customer 3")
+		self.customer3 = self.customer
+
+		filters = {
+			"company": self.company,
+			"party_type": "Customer",
+			"party": [self.customer1, self.customer3],
+			"report_date": today(),
+			"range1": 30,
+			"range2": 60,
+			"range3": 90,
+			"range4": 120,
+		}
+
+		si1 = self.create_sales_invoice(no_payment_schedule=True, do_not_submit=True)
+		si1.customer = self.customer1
+		si1.save().submit()
+
+		si2 = self.create_sales_invoice(no_payment_schedule=True, do_not_submit=True)
+		si2.customer = self.customer2
+		si2.save().submit()
+
+		si3 = self.create_sales_invoice(no_payment_schedule=True, do_not_submit=True)
+		si3.customer = self.customer3
+		si3.save().submit()
+
+		# check invoice grand total and invoiced column's value for 3 payment terms
+		report = execute(filters)
+
+		expected_output = {self.customer1, self.customer3}
+		self.assertEqual(len(report[1]), 2)
+		output_for = set([x.party for x in report[1]])
+		self.assertEqual(output_for, expected_output)
+
+	def test_report_output_if_party_is_missing(self):
+		acc_name = "Additional Debtors"
+		if not frappe.db.get_value(
+			"Account", filters={"account_name": acc_name, "company": self.company}
+		):
+			additional_receivable_acc = frappe.get_doc(
+				{
+					"doctype": "Account",
+					"account_name": acc_name,
+					"parent_account": "Accounts Receivable - " + self.company_abbr,
+					"company": self.company,
+					"account_type": "Receivable",
+				}
+			).save()
+			self.debtors2 = additional_receivable_acc.name
+
+		je = frappe.new_doc("Journal Entry")
+		je.company = self.company
+		je.posting_date = today()
+		je.append(
+			"accounts",
+			{
+				"account": self.debit_to,
+				"party_type": "Customer",
+				"party": self.customer,
+				"debit_in_account_currency": 150,
+				"credit_in_account_currency": 0,
+				"cost_center": self.cost_center,
+			},
+		)
+		je.append(
+			"accounts",
+			{
+				"account": self.debtors2,
+				"party_type": "Customer",
+				"party": self.customer,
+				"debit_in_account_currency": 200,
+				"credit_in_account_currency": 0,
+				"cost_center": self.cost_center,
+			},
+		)
+		je.append(
+			"accounts",
+			{
+				"account": self.cash,
+				"debit_in_account_currency": 0,
+				"credit_in_account_currency": 350,
+				"cost_center": self.cost_center,
+			},
+		)
+		je.save().submit()
+
+		# manually remove party from Payment Ledger
+		ple = qb.DocType("Payment Ledger Entry")
+		qb.update(ple).set(ple.party, None).where(ple.voucher_no == je.name).run()
+
+		filters = {
+			"company": self.company,
+			"report_date": today(),
+			"range1": 30,
+			"range2": 60,
+			"range3": 90,
+			"range4": 120,
+		}
+
+		report_ouput = execute(filters)[1]
+		expected_data = [
+			[self.debtors2, je.doctype, je.name, "Customer", self.customer, 200.0, 0.0, 0.0, 200.0],
+			[self.debit_to, je.doctype, je.name, "Customer", self.customer, 150.0, 0.0, 0.0, 150.0],
+		]
+		self.assertEqual(len(report_ouput), 2)
+		# fetch only required fields
+		report_output = [
+			[
+				x.party_account,
+				x.voucher_type,
+				x.voucher_no,
+				"Customer",
+				self.customer,
+				x.invoiced,
+				x.paid,
+				x.credit_note,
+				x.outstanding,
+			]
+			for x in report_ouput
+		]
+		# use account name to sort
+		# post sorting output should be [[Additional Debtors, ...], [Debtors, ...]]
+		report_output = sorted(report_output, key=lambda x: x[0])
+		self.assertEqual(expected_data, report_output)
diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js
index 715cd64..5ad10c7 100644
--- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js
+++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js
@@ -72,10 +72,27 @@
 			}
 		},
 		{
-			"fieldname":"customer",
-			"label": __("Customer"),
-			"fieldtype": "Link",
-			"options": "Customer"
+			"fieldname":"party_type",
+			"label": __("Party Type"),
+			"fieldtype": "Autocomplete",
+			options: get_party_type_options(),
+			on_change: function() {
+				frappe.query_report.set_filter_value('party', "");
+				frappe.query_report.toggle_filter_display('customer_group', frappe.query_report.get_filter_value('party_type') !== "Customer");
+			}
+		},
+		{
+			"fieldname":"party",
+			"label": __("Party"),
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
+				if (!frappe.query_report.filters) return;
+
+				let party_type = frappe.query_report.get_filter_value('party_type');
+				if (!party_type) return;
+
+				return frappe.db.get_link_options(party_type, txt);
+			},
 		},
 		{
 			"fieldname":"customer_group",
@@ -133,3 +150,15 @@
 }
 
 erpnext.utils.add_dimensions('Accounts Receivable Summary', 9);
+
+function get_party_type_options() {
+	let options = [];
+	frappe.db.get_list(
+		"Party Type", {filters:{"account_type": "Receivable"}, fields:['name']}
+	).then((res) => {
+		res.forEach((party_type) => {
+			options.push(party_type.name);
+		});
+	});
+	return options;
+}
\ No newline at end of file
diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
index cffc878..60274cd 100644
--- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
+++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
@@ -99,13 +99,11 @@
 
 			# Add all amount columns
 			for k in list(self.party_total[d.party]):
-				if k not in ["currency", "sales_person"]:
-
-					self.party_total[d.party][k] += d.get(k, 0.0)
+				if isinstance(self.party_total[d.party][k], float):
+					self.party_total[d.party][k] += d.get(k) or 0.0
 
 			# set territory, customer_group, sales person etc
 			self.set_party_details(d)
-			self.party_total[d.party].update({"party_type": d.party_type})
 
 	def init_party_total(self, row):
 		self.party_total.setdefault(
@@ -124,6 +122,7 @@
 					"total_due": 0.0,
 					"future_amount": 0.0,
 					"sales_person": [],
+					"party_type": row.party_type,
 				}
 			),
 		)
@@ -133,13 +132,12 @@
 
 		for key in ("territory", "customer_group", "supplier_group"):
 			if row.get(key):
-				self.party_total[row.party][key] = row.get(key)
-
+				self.party_total[row.party][key] = row.get(key, "")
 		if row.sales_person:
-			self.party_total[row.party].sales_person.append(row.sales_person)
+			self.party_total[row.party].sales_person.append(row.get("sales_person", ""))
 
 		if self.filters.sales_partner:
-			self.party_total[row.party]["default_sales_partner"] = row.get("default_sales_partner")
+			self.party_total[row.party]["default_sales_partner"] = row.get("default_sales_partner", "")
 
 	def get_columns(self):
 		self.columns = []
diff --git a/erpnext/accounts/report/balance_sheet/balance_sheet.js b/erpnext/accounts/report/balance_sheet/balance_sheet.js
index ecc13d7..c2b57f7 100644
--- a/erpnext/accounts/report/balance_sheet/balance_sheet.js
+++ b/erpnext/accounts/report/balance_sheet/balance_sheet.js
@@ -1,25 +1,23 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-frappe.require("assets/erpnext/js/financial_statements.js", function () {
-	frappe.query_reports["Balance Sheet"] = $.extend(
-		{},
-		erpnext.financial_statements
-	);
+frappe.query_reports["Balance Sheet"] = $.extend(
+	{},
+	erpnext.financial_statements
+);
 
-	erpnext.utils.add_dimensions("Balance Sheet", 10);
+erpnext.utils.add_dimensions("Balance Sheet", 10);
 
-	frappe.query_reports["Balance Sheet"]["filters"].push({
-		fieldname: "accumulated_values",
-		label: __("Accumulated Values"),
-		fieldtype: "Check",
-		default: 1,
-	});
+frappe.query_reports["Balance Sheet"]["filters"].push({
+	fieldname: "accumulated_values",
+	label: __("Accumulated Values"),
+	fieldtype: "Check",
+	default: 1,
+});
 
-	frappe.query_reports["Balance Sheet"]["filters"].push({
-		fieldname: "include_default_book_entries",
-		label: __("Include Default Book Entries"),
-		fieldtype: "Check",
-		default: 1,
-	});
+frappe.query_reports["Balance Sheet"]["filters"].push({
+	fieldname: "include_default_book_entries",
+	label: __("Include Default Book Entries"),
+	fieldtype: "Check",
+	default: 1,
 });
diff --git a/erpnext/accounts/report/cash_flow/cash_flow.js b/erpnext/accounts/report/cash_flow/cash_flow.js
index a2c34c6..6b8ed27 100644
--- a/erpnext/accounts/report/cash_flow/cash_flow.js
+++ b/erpnext/accounts/report/cash_flow/cash_flow.js
@@ -1,24 +1,24 @@
 // Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
 // For license information, please see license.txt
 
-frappe.require("assets/erpnext/js/financial_statements.js", function() {
-	frappe.query_reports["Cash Flow"] = $.extend({},
-		erpnext.financial_statements);
+frappe.query_reports["Cash Flow"] = $.extend(
+	{},
+	erpnext.financial_statements
+);
 
-	erpnext.utils.add_dimensions('Cash Flow', 10);
+erpnext.utils.add_dimensions('Cash Flow', 10);
 
-	// The last item in the array is the definition for Presentation Currency
-	// filter. It won't be used in cash flow for now so we pop it. Please take
-	// of this if you are working here.
+// The last item in the array is the definition for Presentation Currency
+// filter. It won't be used in cash flow for now so we pop it. Please take
+// of this if you are working here.
 
-	frappe.query_reports["Cash Flow"]["filters"].splice(8, 1);
+frappe.query_reports["Cash Flow"]["filters"].splice(8, 1);
 
-	frappe.query_reports["Cash Flow"]["filters"].push(
-		{
-			"fieldname": "include_default_book_entries",
-			"label": __("Include Default Book Entries"),
-			"fieldtype": "Check",
-			"default": 1
-		}
-	);
-});
+frappe.query_reports["Cash Flow"]["filters"].push(
+	{
+		"fieldname": "include_default_book_entries",
+		"label": __("Include Default Book Entries"),
+		"fieldtype": "Check",
+		"default": 1
+	}
+);
diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js
index 1afa8d5..590408c 100644
--- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js
+++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js
@@ -2,152 +2,150 @@
 // For license information, please see license.txt
 
 
-frappe.require("assets/erpnext/js/financial_statements.js", function() {
-	frappe.query_reports["Consolidated Financial Statement"] = {
-		"filters": [
-			{
-				"fieldname":"company",
-				"label": __("Company"),
-				"fieldtype": "Link",
-				"options": "Company",
-				"default": frappe.defaults.get_user_default("Company"),
-				"reqd": 1
-			},
-			{
-				"fieldname":"filter_based_on",
-				"label": __("Filter Based On"),
-				"fieldtype": "Select",
-				"options": ["Fiscal Year", "Date Range"],
-				"default": ["Fiscal Year"],
-				"reqd": 1,
-				on_change: function() {
-					let filter_based_on = frappe.query_report.get_filter_value('filter_based_on');
-					frappe.query_report.toggle_filter_display('from_fiscal_year', filter_based_on === 'Date Range');
-					frappe.query_report.toggle_filter_display('to_fiscal_year', filter_based_on === 'Date Range');
-					frappe.query_report.toggle_filter_display('period_start_date', filter_based_on === 'Fiscal Year');
-					frappe.query_report.toggle_filter_display('period_end_date', filter_based_on === 'Fiscal Year');
-
-					frappe.query_report.refresh();
-				}
-			},
-			{
-				"fieldname":"period_start_date",
-				"label": __("Start Date"),
-				"fieldtype": "Date",
-				"hidden": 1,
-				"reqd": 1
-			},
-			{
-				"fieldname":"period_end_date",
-				"label": __("End Date"),
-				"fieldtype": "Date",
-				"hidden": 1,
-				"reqd": 1
-			},
-			{
-				"fieldname":"from_fiscal_year",
-				"label": __("Start Year"),
-				"fieldtype": "Link",
-				"options": "Fiscal Year",
-				"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
-				"reqd": 1,
-				on_change: () => {
-					frappe.model.with_doc("Fiscal Year", frappe.query_report.get_filter_value('from_fiscal_year'), function(r) {
-						let year_start_date = frappe.model.get_value("Fiscal Year", frappe.query_report.get_filter_value('from_fiscal_year'), "year_start_date");
-						frappe.query_report.set_filter_value({
-							period_start_date: year_start_date
-						});
-					});
-				}
-			},
-			{
-				"fieldname":"to_fiscal_year",
-				"label": __("End Year"),
-				"fieldtype": "Link",
-				"options": "Fiscal Year",
-				"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
-				"reqd": 1,
-				on_change: () => {
-					frappe.model.with_doc("Fiscal Year", frappe.query_report.get_filter_value('to_fiscal_year'), function(r) {
-						let year_end_date = frappe.model.get_value("Fiscal Year", frappe.query_report.get_filter_value('to_fiscal_year'), "year_end_date");
-						frappe.query_report.set_filter_value({
-							period_end_date: year_end_date
-						});
-					});
-				}
-			},
-			{
-				"fieldname":"finance_book",
-				"label": __("Finance Book"),
-				"fieldtype": "Link",
-				"options": "Finance Book"
-			},
-			{
-				"fieldname":"report",
-				"label": __("Report"),
-				"fieldtype": "Select",
-				"options": ["Profit and Loss Statement", "Balance Sheet", "Cash Flow"],
-				"default": "Balance Sheet",
-				"reqd": 1
-			},
-			{
-				"fieldname": "presentation_currency",
-				"label": __("Currency"),
-				"fieldtype": "Select",
-				"options": erpnext.get_presentation_currency_list(),
-				"default": frappe.defaults.get_user_default("Currency")
-			},
-			{
-				"fieldname":"accumulated_in_group_company",
-				"label": __("Accumulated Values in Group Company"),
-				"fieldtype": "Check",
-				"default": 0
-			},
-			{
-				"fieldname": "include_default_book_entries",
-				"label": __("Include Default Book Entries"),
-				"fieldtype": "Check",
-				"default": 1
-			},
-			{
-				"fieldname": "show_zero_values",
-				"label": __("Show zero values"),
-				"fieldtype": "Check"
-			}
-		],
-		"formatter": function(value, row, column, data, default_formatter) {
-			if (data && column.fieldname=="account") {
-				value = data.account_name || value;
-
-				column.link_onclick =
-				"erpnext.financial_statements.open_general_ledger(" + JSON.stringify(data) + ")";
-				column.is_tree = true;
-			}
-
-			if (data && data.account && column.apply_currency_formatter) {
-				data.currency = erpnext.get_currency(column.company_name);
-			}
-
-			value = default_formatter(value, row, column, data);
-			if (!data.parent_account) {
-				value = $(`<span>${value}</span>`);
-
-				var $value = $(value).css("font-weight", "bold");
-
-				value = $value.wrap("<p></p>").parent().html();
-			}
-			return value;
+frappe.query_reports["Consolidated Financial Statement"] = {
+	"filters": [
+		{
+			"fieldname":"company",
+			"label": __("Company"),
+			"fieldtype": "Link",
+			"options": "Company",
+			"default": frappe.defaults.get_user_default("Company"),
+			"reqd": 1
 		},
-		onload: function() {
-			let fiscal_year = erpnext.utils.get_fiscal_year(frappe.datetime.get_today());
+		{
+			"fieldname":"filter_based_on",
+			"label": __("Filter Based On"),
+			"fieldtype": "Select",
+			"options": ["Fiscal Year", "Date Range"],
+			"default": ["Fiscal Year"],
+			"reqd": 1,
+			on_change: function() {
+				let filter_based_on = frappe.query_report.get_filter_value('filter_based_on');
+				frappe.query_report.toggle_filter_display('from_fiscal_year', filter_based_on === 'Date Range');
+				frappe.query_report.toggle_filter_display('to_fiscal_year', filter_based_on === 'Date Range');
+				frappe.query_report.toggle_filter_display('period_start_date', filter_based_on === 'Fiscal Year');
+				frappe.query_report.toggle_filter_display('period_end_date', filter_based_on === 'Fiscal Year');
 
-			frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
-				var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
-				frappe.query_report.set_filter_value({
-					period_start_date: fy.year_start_date,
-					period_end_date: fy.year_end_date
+				frappe.query_report.refresh();
+			}
+		},
+		{
+			"fieldname":"period_start_date",
+			"label": __("Start Date"),
+			"fieldtype": "Date",
+			"hidden": 1,
+			"reqd": 1
+		},
+		{
+			"fieldname":"period_end_date",
+			"label": __("End Date"),
+			"fieldtype": "Date",
+			"hidden": 1,
+			"reqd": 1
+		},
+		{
+			"fieldname":"from_fiscal_year",
+			"label": __("Start Year"),
+			"fieldtype": "Link",
+			"options": "Fiscal Year",
+			"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
+			"reqd": 1,
+			on_change: () => {
+				frappe.model.with_doc("Fiscal Year", frappe.query_report.get_filter_value('from_fiscal_year'), function(r) {
+					let year_start_date = frappe.model.get_value("Fiscal Year", frappe.query_report.get_filter_value('from_fiscal_year'), "year_start_date");
+					frappe.query_report.set_filter_value({
+						period_start_date: year_start_date
+					});
 				});
-			});
+			}
+		},
+		{
+			"fieldname":"to_fiscal_year",
+			"label": __("End Year"),
+			"fieldtype": "Link",
+			"options": "Fiscal Year",
+			"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
+			"reqd": 1,
+			on_change: () => {
+				frappe.model.with_doc("Fiscal Year", frappe.query_report.get_filter_value('to_fiscal_year'), function(r) {
+					let year_end_date = frappe.model.get_value("Fiscal Year", frappe.query_report.get_filter_value('to_fiscal_year'), "year_end_date");
+					frappe.query_report.set_filter_value({
+						period_end_date: year_end_date
+					});
+				});
+			}
+		},
+		{
+			"fieldname":"finance_book",
+			"label": __("Finance Book"),
+			"fieldtype": "Link",
+			"options": "Finance Book"
+		},
+		{
+			"fieldname":"report",
+			"label": __("Report"),
+			"fieldtype": "Select",
+			"options": ["Profit and Loss Statement", "Balance Sheet", "Cash Flow"],
+			"default": "Balance Sheet",
+			"reqd": 1
+		},
+		{
+			"fieldname": "presentation_currency",
+			"label": __("Currency"),
+			"fieldtype": "Select",
+			"options": erpnext.get_presentation_currency_list(),
+			"default": frappe.defaults.get_user_default("Currency")
+		},
+		{
+			"fieldname":"accumulated_in_group_company",
+			"label": __("Accumulated Values in Group Company"),
+			"fieldtype": "Check",
+			"default": 0
+		},
+		{
+			"fieldname": "include_default_book_entries",
+			"label": __("Include Default Book Entries"),
+			"fieldtype": "Check",
+			"default": 1
+		},
+		{
+			"fieldname": "show_zero_values",
+			"label": __("Show zero values"),
+			"fieldtype": "Check"
 		}
+	],
+	"formatter": function(value, row, column, data, default_formatter) {
+		if (data && column.fieldname=="account") {
+			value = data.account_name || value;
+
+			column.link_onclick =
+				"erpnext.financial_statements.open_general_ledger(" + JSON.stringify(data) + ")";
+			column.is_tree = true;
+		}
+
+		if (data && data.account && column.apply_currency_formatter) {
+			data.currency = erpnext.get_currency(column.company_name);
+		}
+
+		value = default_formatter(value, row, column, data);
+		if (!data.parent_account) {
+			value = $(`<span>${value}</span>`);
+
+			var $value = $(value).css("font-weight", "bold");
+
+			value = $value.wrap("<p></p>").parent().html();
+		}
+		return value;
+	},
+	onload: function() {
+		let fiscal_year = erpnext.utils.get_fiscal_year(frappe.datetime.get_today());
+
+		frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
+			var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
+			frappe.query_report.set_filter_value({
+				period_start_date: fy.year_start_date,
+				period_end_date: fy.year_end_date
+			});
+		});
 	}
-});
+}
diff --git a/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.js b/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.js
index 79e5a09..51fa8c8 100644
--- a/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.js
+++ b/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.js
@@ -2,83 +2,81 @@
 // For license information, please see license.txt
 
 
-frappe.require("assets/erpnext/js/financial_statements.js", function() {
-	frappe.query_reports["Dimension-wise Accounts Balance Report"] = {
-		"filters": [
-			{
-				"fieldname": "company",
-				"label": __("Company"),
-				"fieldtype": "Link",
-				"options": "Company",
-				"default": frappe.defaults.get_user_default("Company"),
-				"reqd": 1
-			},
-			{
-				"fieldname": "fiscal_year",
-				"label": __("Fiscal Year"),
-				"fieldtype": "Link",
-				"options": "Fiscal Year",
-				"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
-				"reqd": 1,
-				"on_change": function(query_report) {
-					var fiscal_year = query_report.get_values().fiscal_year;
-					if (!fiscal_year) {
-						return;
-					}
-					frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
-						var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
-						frappe.query_report.set_filter_value({
-							from_date: fy.year_start_date,
-							to_date: fy.year_end_date
-						});
-					});
+frappe.query_reports["Dimension-wise Accounts Balance Report"] = {
+	"filters": [
+		{
+			"fieldname": "company",
+			"label": __("Company"),
+			"fieldtype": "Link",
+			"options": "Company",
+			"default": frappe.defaults.get_user_default("Company"),
+			"reqd": 1
+		},
+		{
+			"fieldname": "fiscal_year",
+			"label": __("Fiscal Year"),
+			"fieldtype": "Link",
+			"options": "Fiscal Year",
+			"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
+			"reqd": 1,
+			"on_change": function(query_report) {
+				var fiscal_year = query_report.get_values().fiscal_year;
+				if (!fiscal_year) {
+					return;
 				}
-			},
-			{
-				"fieldname": "from_date",
-				"label": __("From Date"),
-				"fieldtype": "Date",
-				"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[1],
-				"reqd": 1
-			},
-			{
-				"fieldname": "to_date",
-				"label": __("To Date"),
-				"fieldtype": "Date",
-				"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
-				"reqd": 1
-			},
-			{
-				"fieldname": "finance_book",
-				"label": __("Finance Book"),
-				"fieldtype": "Link",
-				"options": "Finance Book",
-			},
-			{
-				"fieldname": "dimension",
-				"label": __("Select Dimension"),
-				"fieldtype": "Select",
-				"default": "Cost Center",
-				"options": get_accounting_dimension_options(),
-				"reqd": 1,
-			},
-		],
-		"formatter": erpnext.financial_statements.formatter,
-		"tree": true,
-		"name_field": "account",
-		"parent_field": "parent_account",
-		"initial_depth": 3
-	}
+				frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
+					var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
+					frappe.query_report.set_filter_value({
+						from_date: fy.year_start_date,
+						to_date: fy.year_end_date
+					});
+				});
+			}
+		},
+		{
+			"fieldname": "from_date",
+			"label": __("From Date"),
+			"fieldtype": "Date",
+			"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[1],
+			"reqd": 1
+		},
+		{
+			"fieldname": "to_date",
+			"label": __("To Date"),
+			"fieldtype": "Date",
+			"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
+			"reqd": 1
+		},
+		{
+			"fieldname": "finance_book",
+			"label": __("Finance Book"),
+			"fieldtype": "Link",
+			"options": "Finance Book",
+		},
+		{
+			"fieldname": "dimension",
+			"label": __("Select Dimension"),
+			"fieldtype": "Select",
+			"default": "Cost Center",
+			"options": get_accounting_dimension_options(),
+			"reqd": 1,
+		},
+	],
+	"formatter": erpnext.financial_statements.formatter,
+	"tree": true,
+	"name_field": "account",
+	"parent_field": "parent_account",
+	"initial_depth": 3
+}
 
-});
 
 function get_accounting_dimension_options() {
 	let options =["Cost Center", "Project"];
 	frappe.db.get_list('Accounting Dimension',
-		{fields:['document_type']}).then((res) => {
-			res.forEach((dimension) => {
-				options.push(dimension.document_type);
-			});
-		});
+			   {fields:['document_type']}).then((res) => {
+				   res.forEach((dimension) => {
+					   options.push(dimension.document_type);
+				   });
+			   });
 	return options
 }
diff --git a/erpnext/accounts/report/financial_ratios/financial_ratios.py b/erpnext/accounts/report/financial_ratios/financial_ratios.py
index 57421eb..47b4fd0 100644
--- a/erpnext/accounts/report/financial_ratios/financial_ratios.py
+++ b/erpnext/accounts/report/financial_ratios/financial_ratios.py
@@ -177,8 +177,8 @@
 	return_on_equity_ratio = {"ratio": "Return on Equity Ratio"}
 
 	for year in years:
-		profit_after_tax = total_income[year] + total_expense[year]
-		share_holder_fund = total_asset[year] - total_liability[year]
+		profit_after_tax = flt(total_income.get(year)) + flt(total_expense.get(year))
+		share_holder_fund = flt(total_asset.get(year)) - flt(total_liability.get(year))
 
 		debt_equity_ratio[year] = calculate_ratio(
 			total_liability.get(year), share_holder_fund, precision
diff --git a/erpnext/accounts/report/general_and_payment_ledger_comparison/general_and_payment_ledger_comparison.py b/erpnext/accounts/report/general_and_payment_ledger_comparison/general_and_payment_ledger_comparison.py
index 553c137..696a03b 100644
--- a/erpnext/accounts/report/general_and_payment_ledger_comparison/general_and_payment_ledger_comparison.py
+++ b/erpnext/accounts/report/general_and_payment_ledger_comparison/general_and_payment_ledger_comparison.py
@@ -79,7 +79,9 @@
 					.select(
 						gle.company,
 						gle.account,
+						gle.voucher_type,
 						gle.voucher_no,
+						gle.party_type,
 						gle.party,
 						outstanding,
 					)
@@ -89,7 +91,9 @@
 						& (gle.account.isin(val.accounts))
 					)
 					.where(Criterion.all(filter_criterion))
-					.groupby(gle.company, gle.account, gle.voucher_no, gle.party)
+					.groupby(
+						gle.company, gle.account, gle.voucher_type, gle.voucher_no, gle.party_type, gle.party
+					)
 					.run()
 				)
 
@@ -112,7 +116,13 @@
 				self.account_types[acc_type].ple = (
 					qb.from_(ple)
 					.select(
-						ple.company, ple.account, ple.voucher_no, ple.party, Sum(ple.amount).as_("outstanding")
+						ple.company,
+						ple.account,
+						ple.voucher_type,
+						ple.voucher_no,
+						ple.party_type,
+						ple.party,
+						Sum(ple.amount).as_("outstanding"),
 					)
 					.where(
 						(ple.company == self.filters.company)
@@ -120,7 +130,9 @@
 						& (ple.account.isin(val.accounts))
 					)
 					.where(Criterion.all(filter_criterion))
-					.groupby(ple.company, ple.account, ple.voucher_no, ple.party)
+					.groupby(
+						ple.company, ple.account, ple.voucher_type, ple.voucher_no, ple.party_type, ple.party
+					)
 					.run()
 				)
 
@@ -133,15 +145,17 @@
 			self.gle_balances = set(val.gle) | self.gle_balances
 			self.ple_balances = set(val.ple) | self.ple_balances
 
-		self.diff1 = self.gle_balances.difference(self.ple_balances)
-		self.diff2 = self.ple_balances.difference(self.gle_balances)
+		self.variation_in_payment_ledger = self.gle_balances.difference(self.ple_balances)
+		self.variation_in_general_ledger = self.ple_balances.difference(self.gle_balances)
 		self.diff = frappe._dict({})
 
-		for x in self.diff1:
-			self.diff[(x[0], x[1], x[2], x[3])] = frappe._dict({"gl_balance": x[4]})
+		for x in self.variation_in_payment_ledger:
+			self.diff[(x[0], x[1], x[2], x[3], x[4], x[5])] = frappe._dict({"gl_balance": x[6]})
 
-		for x in self.diff2:
-			self.diff[(x[0], x[1], x[2], x[3])].update(frappe._dict({"pl_balance": x[4]}))
+		for x in self.variation_in_general_ledger:
+			self.diff.setdefault(
+				(x[0], x[1], x[2], x[3], x[4], x[5]), frappe._dict({"gl_balance": 0.0})
+			).update(frappe._dict({"pl_balance": x[6]}))
 
 	def generate_data(self):
 		self.data = []
@@ -149,8 +163,12 @@
 			self.data.append(
 				frappe._dict(
 					{
-						"voucher_no": key[2],
-						"party": key[3],
+						"company": key[0],
+						"account": key[1],
+						"voucher_type": key[2],
+						"voucher_no": key[3],
+						"party_type": key[4],
+						"party": key[5],
 						"gl_balance": val.gl_balance,
 						"pl_balance": val.pl_balance,
 					}
@@ -162,10 +180,50 @@
 		options = None
 		self.columns.append(
 			dict(
+				label=_("Company"),
+				fieldname="company",
+				fieldtype="Link",
+				options="Company",
+				width="100",
+			)
+		)
+
+		self.columns.append(
+			dict(
+				label=_("Account"),
+				fieldname="account",
+				fieldtype="Link",
+				options="Account",
+				width="100",
+			)
+		)
+
+		self.columns.append(
+			dict(
+				label=_("Voucher Type"),
+				fieldname="voucher_type",
+				fieldtype="Link",
+				options="DocType",
+				width="100",
+			)
+		)
+
+		self.columns.append(
+			dict(
 				label=_("Voucher No"),
 				fieldname="voucher_no",
-				fieldtype="Data",
-				options=options,
+				fieldtype="Dynamic Link",
+				options="voucher_type",
+				width="100",
+			)
+		)
+
+		self.columns.append(
+			dict(
+				label=_("Party Type"),
+				fieldname="party_type",
+				fieldtype="Link",
+				options="DocType",
 				width="100",
 			)
 		)
@@ -174,8 +232,8 @@
 			dict(
 				label=_("Party"),
 				fieldname="party",
-				fieldtype="Data",
-				options=options,
+				fieldtype="Dynamic Link",
+				options="party_type",
 				width="100",
 			)
 		)
diff --git a/erpnext/accounts/report/general_and_payment_ledger_comparison/test_general_and_payment_ledger_comparison.py b/erpnext/accounts/report/general_and_payment_ledger_comparison/test_general_and_payment_ledger_comparison.py
index 4b0e99d..59e906b 100644
--- a/erpnext/accounts/report/general_and_payment_ledger_comparison/test_general_and_payment_ledger_comparison.py
+++ b/erpnext/accounts/report/general_and_payment_ledger_comparison/test_general_and_payment_ledger_comparison.py
@@ -50,7 +50,11 @@
 		self.assertEqual(len(data), 1)
 
 		expected = {
+			"company": sinv.company,
+			"account": sinv.debit_to,
+			"voucher_type": sinv.doctype,
 			"voucher_no": sinv.name,
+			"party_type": "Customer",
 			"party": sinv.customer,
 			"gl_balance": sinv.grand_total,
 			"pl_balance": sinv.grand_total - 1,
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js
index 37d0659..c0b4f59 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.js
+++ b/erpnext/accounts/report/general_ledger/general_ledger.js
@@ -193,7 +193,13 @@
 			"fieldname": "add_values_in_transaction_currency",
 			"label": __("Add Columns in Transaction Currency"),
 			"fieldtype": "Check"
+		},
+		{
+			"fieldname": "show_remarks",
+			"label": __("Show Remarks"),
+			"fieldtype": "Check"
 		}
+
 	]
 }
 
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index 79bfd78..5e484cf 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -163,6 +163,9 @@
 	select_fields = """, debit, credit, debit_in_account_currency,
 		credit_in_account_currency """
 
+	if filters.get("show_remarks"):
+		select_fields += """,remarks"""
+
 	order_by_statement = "order by posting_date, account, creation"
 
 	if filters.get("include_dimensions"):
@@ -195,7 +198,7 @@
 			voucher_type, voucher_no, {dimension_fields}
 			cost_center, project, {transaction_currency_fields}
 			against_voucher_type, against_voucher, account_currency,
-			remarks, against, is_opening, creation {select_fields}
+			against, is_opening, creation {select_fields}
 		from `tabGL Entry`
 		where company=%(company)s {conditions}
 		{order_by_statement}
@@ -631,8 +634,10 @@
 				"width": 100,
 			},
 			{"label": _("Supplier Invoice No"), "fieldname": "bill_no", "fieldtype": "Data", "width": 100},
-			{"label": _("Remarks"), "fieldname": "remarks", "width": 400},
 		]
 	)
 
+	if filters.get("show_remarks"):
+		columns.extend([{"label": _("Remarks"), "fieldname": "remarks", "width": 400}])
+
 	return columns
diff --git a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js
index f6b0b8c..40d4259 100644
--- a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js
+++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js
@@ -2,20 +2,15 @@
 // For license information, please see license.txt
 
 
-frappe.query_reports["Gross and Net Profit Report"] = {
-	"filters": [
+frappe.query_reports["Gross and Net Profit Report"] = $.extend(
+	{},
+	erpnext.financial_statements
+);
 
-	]
-}
-frappe.require("assets/erpnext/js/financial_statements.js", function() {
-	frappe.query_reports["Gross and Net Profit Report"] = $.extend({},
-		erpnext.financial_statements);
-
-	frappe.query_reports["Gross and Net Profit Report"]["filters"].push(
-		{
-			"fieldname": "accumulated_values",
-			"label": __("Accumulated Values"),
-			"fieldtype": "Check"
-		}
-	);
-});
+frappe.query_reports["Gross and Net Profit Report"]["filters"].push(
+	{
+		"fieldname": "accumulated_values",
+		"label": __("Accumulated Values"),
+		"fieldtype": "Check"
+	}
+);
diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py
index 3324a73..38060bb 100644
--- a/erpnext/accounts/report/gross_profit/gross_profit.py
+++ b/erpnext/accounts/report/gross_profit/gross_profit.py
@@ -544,6 +544,8 @@
 						new_row.qty += flt(row.qty)
 						new_row.buying_amount += flt(row.buying_amount, self.currency_precision)
 						new_row.base_amount += flt(row.base_amount, self.currency_precision)
+						if self.filters.get("group_by") == "Sales Person":
+							new_row.allocated_amount += flt(row.allocated_amount, self.currency_precision)
 				new_row = self.set_average_rate(new_row)
 				self.grouped_data.append(new_row)
 
diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
index 9fe93b9..e5898bf 100644
--- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
+++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
@@ -1,18 +1,16 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-frappe.require("assets/erpnext/js/financial_statements.js", function () {
-	frappe.query_reports["Profit and Loss Statement"] = $.extend(
-		{},
-		erpnext.financial_statements
-	);
+frappe.query_reports["Profit and Loss Statement"] = $.extend(
+	{},
+	erpnext.financial_statements
+);
 
-	erpnext.utils.add_dimensions("Profit and Loss Statement", 10);
+erpnext.utils.add_dimensions("Profit and Loss Statement", 10);
 
-	frappe.query_reports["Profit and Loss Statement"]["filters"].push({
-		fieldname: "accumulated_values",
-		label: __("Accumulated Values"),
-		fieldtype: "Check",
-		default: 1,
-	});
+frappe.query_reports["Profit and Loss Statement"]["filters"].push({
+	fieldname: "accumulated_values",
+	label: __("Accumulated Values"),
+	fieldtype: "Check",
+	default: 1,
 });
diff --git a/erpnext/accounts/report/profitability_analysis/profitability_analysis.js b/erpnext/accounts/report/profitability_analysis/profitability_analysis.js
index c9accef..b6bbd97 100644
--- a/erpnext/accounts/report/profitability_analysis/profitability_analysis.js
+++ b/erpnext/accounts/report/profitability_analysis/profitability_analysis.js
@@ -1,133 +1,124 @@
 // Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
 // For license information, please see license.txt
 
-frappe.require("assets/erpnext/js/financial_statements.js", function() {
-	frappe.query_reports["Profitability Analysis"] = {
-		"filters": [
-			{
-				"fieldname": "company",
-				"label": __("Company"),
-				"fieldtype": "Link",
-				"options": "Company",
-				"default": frappe.defaults.get_user_default("Company"),
-				"reqd": 1
-			},
-			{
-				"fieldname": "based_on",
-				"label": __("Based On"),
-				"fieldtype": "Select",
-				"options": ["Cost Center", "Project", "Accounting Dimension"],
-				"default": "Cost Center",
-				"reqd": 1,
-				"on_change": function(query_report){
-					let based_on = query_report.get_values().based_on;
-					if(based_on!='Accounting Dimension'){
-						frappe.query_report.set_filter_value({
-							accounting_dimension: ''
-						});
-					}
-				}
-			},
-			{
-				"fieldname": "accounting_dimension",
-				"label": __("Accounting Dimension"),
-				"fieldtype": "Link",
-				"options": "Accounting Dimension",
-				"get_query": () =>{
-					return {
-						filters: {
-							"disabled": 0
-						}
-					}
-				}
-			},
-			{
-				"fieldname": "fiscal_year",
-				"label": __("Fiscal Year"),
-				"fieldtype": "Link",
-				"options": "Fiscal Year",
-				"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
-				"reqd": 1,
-				"on_change": function(query_report) {
-					var fiscal_year = query_report.get_values().fiscal_year;
-					if (!fiscal_year) {
-						return;
-					}
-					frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
-						var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
-						frappe.query_report.set_filter_value({
-							from_date: fy.year_start_date,
-							to_date: fy.year_end_date
-						});
+frappe.query_reports["Profitability Analysis"] = {
+	"filters": [
+		{
+			"fieldname": "company",
+			"label": __("Company"),
+			"fieldtype": "Link",
+			"options": "Company",
+			"default": frappe.defaults.get_user_default("Company"),
+			"reqd": 1
+		},
+		{
+			"fieldname": "based_on",
+			"label": __("Based On"),
+			"fieldtype": "Select",
+			"options": ["Cost Center", "Project", "Accounting Dimension"],
+			"default": "Cost Center",
+			"reqd": 1,
+			"on_change": function(query_report){
+				let based_on = query_report.get_values().based_on;
+				if(based_on!='Accounting Dimension'){
+					frappe.query_report.set_filter_value({
+						accounting_dimension: ''
 					});
 				}
-			},
-			{
-				"fieldname": "from_date",
-				"label": __("From Date"),
-				"fieldtype": "Date",
-				"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[1],
-			},
-			{
-				"fieldname": "to_date",
-				"label": __("To Date"),
-				"fieldtype": "Date",
-				"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
-			},
-			{
-				"fieldname": "show_zero_values",
-				"label": __("Show zero values"),
-				"fieldtype": "Check"
 			}
-		],
-		"formatter": function(value, row, column, data, default_formatter) {
-			if (column.fieldname=="account") {
-				value = data.account_name;
-
-				column.link_onclick =
-					"frappe.query_reports['Profitability Analysis'].open_profit_and_loss_statement(" + JSON.stringify(data) + ")";
-				column.is_tree = true;
-			}
-
-			value = default_formatter(value, row, column, data);
-
-			if (!data.parent_account && data.based_on != 'project') {
-				value = $(`<span>${value}</span>`);
-				var $value = $(value).css("font-weight", "bold");
-				if (data.warn_if_negative && data[column.fieldname] < 0) {
-					$value.addClass("text-danger");
+		},
+		{
+			"fieldname": "accounting_dimension",
+			"label": __("Accounting Dimension"),
+			"fieldtype": "Link",
+			"options": "Accounting Dimension",
+		},
+		{
+			"fieldname": "fiscal_year",
+			"label": __("Fiscal Year"),
+			"fieldtype": "Link",
+			"options": "Fiscal Year",
+			"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
+			"reqd": 1,
+			"on_change": function(query_report) {
+				var fiscal_year = query_report.get_values().fiscal_year;
+				if (!fiscal_year) {
+					return;
 				}
+				frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
+					var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
+					frappe.query_report.set_filter_value({
+						from_date: fy.year_start_date,
+						to_date: fy.year_end_date
+					});
+				});
+			}
+		},
+		{
+			"fieldname": "from_date",
+			"label": __("From Date"),
+			"fieldtype": "Date",
+			"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[1],
+		},
+		{
+			"fieldname": "to_date",
+			"label": __("To Date"),
+			"fieldtype": "Date",
+			"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
+		},
+		{
+			"fieldname": "show_zero_values",
+			"label": __("Show zero values"),
+			"fieldtype": "Check"
+		}
+	],
+	"formatter": function(value, row, column, data, default_formatter) {
+		if (column.fieldname=="account") {
+			value = data.account_name;
 
-				value = $value.wrap("<p></p>").parent().html();
+			column.link_onclick =
+				"frappe.query_reports['Profitability Analysis'].open_profit_and_loss_statement(" + JSON.stringify(data) + ")";
+			column.is_tree = true;
+		}
+
+		value = default_formatter(value, row, column, data);
+
+		if (!data.parent_account && data.based_on != 'project') {
+			value = $(`<span>${value}</span>`);
+			var $value = $(value).css("font-weight", "bold");
+			if (data.warn_if_negative && data[column.fieldname] < 0) {
+				$value.addClass("text-danger");
 			}
 
-			return value;
-		},
-		"open_profit_and_loss_statement": function(data) {
-			if (!data.account) return;
+			value = $value.wrap("<p></p>").parent().html();
+		}
 
-			frappe.route_options = {
-				"company": frappe.query_report.get_filter_value('company'),
-				"from_fiscal_year": data.fiscal_year,
-				"to_fiscal_year": data.fiscal_year
-			};
+		return value;
+	},
+	"open_profit_and_loss_statement": function(data) {
+		if (!data.account) return;
 
-			if(data.based_on == 'cost_center'){
-				frappe.route_options["cost_center"] = data.account
-			} else {
-				frappe.route_options["project"] = data.account
-			}
+		frappe.route_options = {
+			"company": frappe.query_report.get_filter_value('company'),
+			"from_fiscal_year": data.fiscal_year,
+			"to_fiscal_year": data.fiscal_year
+		};
 
-			frappe.set_route("query-report", "Profit and Loss Statement");
-		},
-		"tree": true,
-		"name_field": "account",
-		"parent_field": "parent_account",
-		"initial_depth": 3
-	}
+		if(data.based_on == 'Cost Center'){
+			frappe.route_options["cost_center"] = data.account
+		} else {
+			frappe.route_options["project"] = data.account
+		}
 
-	erpnext.dimension_filters.forEach((dimension) => {
-		frappe.query_reports["Profitability Analysis"].filters[1].options.push(dimension["document_type"]);
-	});
+		frappe.set_route("query-report", "Profit and Loss Statement");
+	},
+	"tree": true,
+	"name_field": "account",
+	"parent_field": "parent_account",
+	"initial_depth": 3
+}
 
+erpnext.dimension_filters.forEach((dimension) => {
+	frappe.query_reports["Profitability Analysis"].filters[1].options.push(dimension["document_type"]);
 });
+
diff --git a/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py b/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py
index 91ad3d6..e842d2e 100644
--- a/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py
+++ b/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py
@@ -47,6 +47,7 @@
 	out = []
 	for name, details in gle_map.items():
 		tax_amount, total_amount, grand_total, base_total = 0, 0, 0, 0
+		bill_no, bill_date = "", ""
 		tax_withholding_category = tax_category_map.get(name)
 		rate = tax_rate_map.get(tax_withholding_category)
 
@@ -68,7 +69,14 @@
 				tax_amount += entry.credit - entry.debit
 
 			if net_total_map.get(name):
-				total_amount, grand_total, base_total = net_total_map.get(name)
+				if voucher_type == "Journal Entry" and tax_amount and rate:
+					# back calcalute total amount from rate and tax_amount
+					if rate:
+						total_amount = grand_total = base_total = tax_amount / (rate / 100)
+				elif voucher_type == "Purchase Invoice":
+					total_amount, grand_total, base_total, bill_no, bill_date = net_total_map.get(name)
+				else:
+					total_amount, grand_total, base_total = net_total_map.get(name)
 			else:
 				total_amount += entry.credit
 
@@ -92,7 +100,7 @@
 
 			row.update(
 				{
-					"section_code": tax_withholding_category,
+					"section_code": tax_withholding_category or "",
 					"entity_type": party_map.get(party, {}).get(party_type),
 					"rate": rate,
 					"total_amount": total_amount,
@@ -102,10 +110,14 @@
 					"transaction_date": posting_date,
 					"transaction_type": voucher_type,
 					"ref_no": name,
+					"supplier_invoice_no": bill_no,
+					"supplier_invoice_date": bill_date,
 				}
 			)
 			out.append(row)
 
+	out.sort(key=lambda x: x["section_code"])
+
 	return out
 
 
@@ -153,14 +165,14 @@
 def get_columns(filters):
 	pan = "pan" if frappe.db.has_column(filters.party_type, "pan") else "tax_id"
 	columns = [
-		{"label": _(frappe.unscrub(pan)), "fieldname": pan, "fieldtype": "Data", "width": 60},
 		{
-			"label": _(filters.get("party_type")),
-			"fieldname": "party",
-			"fieldtype": "Dynamic Link",
-			"options": "party_type",
-			"width": 180,
+			"label": _("Section Code"),
+			"options": "Tax Withholding Category",
+			"fieldname": "section_code",
+			"fieldtype": "Link",
+			"width": 90,
 		},
+		{"label": _(frappe.unscrub(pan)), "fieldname": pan, "fieldtype": "Data", "width": 60},
 	]
 
 	if filters.naming_series == "Naming Series":
@@ -175,51 +187,60 @@
 
 	columns.extend(
 		[
-			{
-				"label": _("Date of Transaction"),
-				"fieldname": "transaction_date",
-				"fieldtype": "Date",
-				"width": 100,
-			},
-			{
-				"label": _("Section Code"),
-				"options": "Tax Withholding Category",
-				"fieldname": "section_code",
-				"fieldtype": "Link",
-				"width": 90,
-			},
 			{"label": _("Entity Type"), "fieldname": "entity_type", "fieldtype": "Data", "width": 100},
-			{
-				"label": _("Total Amount"),
-				"fieldname": "total_amount",
-				"fieldtype": "Float",
-				"width": 90,
-			},
+		]
+	)
+	if filters.party_type == "Supplier":
+		columns.extend(
+			[
+				{
+					"label": _("Supplier Invoice No"),
+					"fieldname": "supplier_invoice_no",
+					"fieldtype": "Data",
+					"width": 120,
+				},
+				{
+					"label": _("Supplier Invoice Date"),
+					"fieldname": "supplier_invoice_date",
+					"fieldtype": "Date",
+					"width": 120,
+				},
+			]
+		)
+
+	columns.extend(
+		[
 			{
 				"label": _("TDS Rate %") if filters.get("party_type") == "Supplier" else _("TCS Rate %"),
 				"fieldname": "rate",
 				"fieldtype": "Percent",
-				"width": 90,
+				"width": 60,
 			},
 			{
-				"label": _("Tax Amount"),
-				"fieldname": "tax_amount",
+				"label": _("Total Amount"),
+				"fieldname": "total_amount",
 				"fieldtype": "Float",
-				"width": 90,
-			},
-			{
-				"label": _("Grand Total"),
-				"fieldname": "grand_total",
-				"fieldtype": "Float",
-				"width": 90,
+				"width": 120,
 			},
 			{
 				"label": _("Base Total"),
 				"fieldname": "base_total",
 				"fieldtype": "Float",
-				"width": 90,
+				"width": 120,
 			},
-			{"label": _("Transaction Type"), "fieldname": "transaction_type", "width": 100},
+			{
+				"label": _("Tax Amount"),
+				"fieldname": "tax_amount",
+				"fieldtype": "Float",
+				"width": 120,
+			},
+			{
+				"label": _("Grand Total"),
+				"fieldname": "grand_total",
+				"fieldtype": "Float",
+				"width": 120,
+			},
+			{"label": _("Transaction Type"), "fieldname": "transaction_type", "width": 130},
 			{
 				"label": _("Reference No."),
 				"fieldname": "ref_no",
@@ -227,6 +248,12 @@
 				"options": "transaction_type",
 				"width": 180,
 			},
+			{
+				"label": _("Date of Transaction"),
+				"fieldname": "transaction_date",
+				"fieldtype": "Date",
+				"width": 100,
+			},
 		]
 	)
 
@@ -249,27 +276,7 @@
 		"Tax Withholding Account", {"company": filters.get("company")}, pluck="account"
 	)
 
-	query_filters = {
-		"account": ("in", tds_accounts),
-		"posting_date": ("between", [filters.get("from_date"), filters.get("to_date")]),
-		"is_cancelled": 0,
-		"against": ("not in", bank_accounts),
-	}
-
-	party = frappe.get_all(filters.get("party_type"), pluck="name")
-	or_filters.update({"against": ("in", party), "voucher_type": "Journal Entry"})
-
-	if filters.get("party"):
-		del query_filters["account"]
-		del query_filters["against"]
-		or_filters = {"against": filters.get("party"), "party": filters.get("party")}
-
-	tds_docs = frappe.get_all(
-		"GL Entry",
-		filters=query_filters,
-		or_filters=or_filters,
-		fields=["voucher_no", "voucher_type", "against", "party"],
-	)
+	tds_docs = get_tds_docs_query(filters, bank_accounts, tds_accounts).run(as_dict=True)
 
 	for d in tds_docs:
 		if d.voucher_type == "Purchase Invoice":
@@ -305,6 +312,47 @@
 	)
 
 
+def get_tds_docs_query(filters, bank_accounts, tds_accounts):
+	if not tds_accounts:
+		frappe.throw(
+			_("No {0} Accounts found for this company.").format(frappe.bold("Tax Withholding")),
+			title="Accounts Missing Error",
+		)
+	gle = frappe.qb.DocType("GL Entry")
+	query = (
+		frappe.qb.from_(gle)
+		.select("voucher_no", "voucher_type", "against", "party")
+		.where((gle.is_cancelled == 0))
+	)
+
+	if filters.get("from_date"):
+		query = query.where(gle.posting_date >= filters.get("from_date"))
+	if filters.get("to_date"):
+		query = query.where(gle.posting_date <= filters.get("to_date"))
+
+	if bank_accounts:
+		query = query.where(gle.against.notin(bank_accounts))
+
+	if filters.get("party"):
+		party = [filters.get("party")]
+		query = query.where(
+			((gle.account.isin(tds_accounts) & gle.against.isin(party)))
+			| ((gle.voucher_type == "Journal Entry") & (gle.party == filters.get("party")))
+			| gle.party.isin(party)
+		)
+	else:
+		party = frappe.get_all(filters.get("party_type"), pluck="name")
+		query = query.where(
+			((gle.account.isin(tds_accounts) & gle.against.isin(party)))
+			| (
+				(gle.voucher_type == "Journal Entry")
+				& ((gle.party_type == filters.get("party_type")) | (gle.party_type == ""))
+			)
+			| gle.party.isin(party)
+		)
+	return query
+
+
 def get_journal_entry_party_map(journal_entries):
 	journal_entry_party_map = {}
 	for d in frappe.db.get_all(
@@ -331,6 +379,8 @@
 			"base_tax_withholding_net_total",
 			"grand_total",
 			"base_total",
+			"bill_no",
+			"bill_date",
 		],
 		"Sales Invoice": ["base_net_total", "grand_total", "base_total"],
 		"Payment Entry": [
@@ -349,7 +399,13 @@
 	for entry in entries:
 		tax_category_map.update({entry.name: entry.tax_withholding_category})
 		if doctype == "Purchase Invoice":
-			value = [entry.base_tax_withholding_net_total, entry.grand_total, entry.base_total]
+			value = [
+				entry.base_tax_withholding_net_total,
+				entry.grand_total,
+				entry.base_total,
+				entry.bill_no,
+				entry.bill_date,
+			]
 		elif doctype == "Sales Invoice":
 			value = [entry.base_net_total, entry.grand_total, entry.base_total]
 		elif doctype == "Payment Entry":
diff --git a/erpnext/accounts/report/trial_balance/trial_balance.js b/erpnext/accounts/report/trial_balance/trial_balance.js
index c12ab0f..edd40b6 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.js
+++ b/erpnext/accounts/report/trial_balance/trial_balance.js
@@ -1,118 +1,116 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-frappe.require("assets/erpnext/js/financial_statements.js", function() {
-	frappe.query_reports["Trial Balance"] = {
-		"filters": [
-			{
-				"fieldname": "company",
-				"label": __("Company"),
-				"fieldtype": "Link",
-				"options": "Company",
-				"default": frappe.defaults.get_user_default("Company"),
-				"reqd": 1
-			},
-			{
-				"fieldname": "fiscal_year",
-				"label": __("Fiscal Year"),
-				"fieldtype": "Link",
-				"options": "Fiscal Year",
-				"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
-				"reqd": 1,
-				"on_change": function(query_report) {
-					var fiscal_year = query_report.get_values().fiscal_year;
-					if (!fiscal_year) {
-						return;
-					}
-					frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
-						var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
-						frappe.query_report.set_filter_value({
-							from_date: fy.year_start_date,
-							to_date: fy.year_end_date
-						});
+frappe.query_reports["Trial Balance"] = {
+	"filters": [
+		{
+			"fieldname": "company",
+			"label": __("Company"),
+			"fieldtype": "Link",
+			"options": "Company",
+			"default": frappe.defaults.get_user_default("Company"),
+			"reqd": 1
+		},
+		{
+			"fieldname": "fiscal_year",
+			"label": __("Fiscal Year"),
+			"fieldtype": "Link",
+			"options": "Fiscal Year",
+			"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
+			"reqd": 1,
+			"on_change": function(query_report) {
+				var fiscal_year = query_report.get_values().fiscal_year;
+				if (!fiscal_year) {
+					return;
+				}
+				frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
+					var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
+					frappe.query_report.set_filter_value({
+						from_date: fy.year_start_date,
+						to_date: fy.year_end_date
 					});
-				}
-			},
-			{
-				"fieldname": "from_date",
-				"label": __("From Date"),
-				"fieldtype": "Date",
-				"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[1],
-			},
-			{
-				"fieldname": "to_date",
-				"label": __("To Date"),
-				"fieldtype": "Date",
-				"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
-			},
-			{
-				"fieldname": "cost_center",
-				"label": __("Cost Center"),
-				"fieldtype": "Link",
-				"options": "Cost Center",
-				"get_query": function() {
-					var company = frappe.query_report.get_filter_value('company');
-					return {
-						"doctype": "Cost Center",
-						"filters": {
-							"company": company,
-						}
+				});
+			}
+		},
+		{
+			"fieldname": "from_date",
+			"label": __("From Date"),
+			"fieldtype": "Date",
+			"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[1],
+		},
+		{
+			"fieldname": "to_date",
+			"label": __("To Date"),
+			"fieldtype": "Date",
+			"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
+		},
+		{
+			"fieldname": "cost_center",
+			"label": __("Cost Center"),
+			"fieldtype": "Link",
+			"options": "Cost Center",
+			"get_query": function() {
+				var company = frappe.query_report.get_filter_value('company');
+				return {
+					"doctype": "Cost Center",
+					"filters": {
+						"company": company,
 					}
 				}
-			},
-			{
-				"fieldname": "project",
-				"label": __("Project"),
-				"fieldtype": "Link",
-				"options": "Project"
-			},
-			{
-				"fieldname": "finance_book",
-				"label": __("Finance Book"),
-				"fieldtype": "Link",
-				"options": "Finance Book",
-			},
-			{
-				"fieldname": "presentation_currency",
-				"label": __("Currency"),
-				"fieldtype": "Select",
-				"options": erpnext.get_presentation_currency_list()
-			},
-			{
-				"fieldname": "with_period_closing_entry",
-				"label": __("Period Closing Entry"),
-				"fieldtype": "Check",
-				"default": 1
-			},
-			{
-				"fieldname": "show_zero_values",
-				"label": __("Show zero values"),
-				"fieldtype": "Check"
-			},
-			{
-				"fieldname": "show_unclosed_fy_pl_balances",
-				"label": __("Show unclosed fiscal year's P&L balances"),
-				"fieldtype": "Check"
-			},
-			{
-				"fieldname": "include_default_book_entries",
-				"label": __("Include Default Book Entries"),
-				"fieldtype": "Check",
-				"default": 1
-			},
-			{
-				"fieldname": "show_net_values",
-				"label": __("Show net values in opening and closing columns"),
-				"fieldtype": "Check",
-				"default": 1
 			}
-		],
-		"formatter": erpnext.financial_statements.formatter,
-		"tree": true,
-		"name_field": "account",
-		"parent_field": "parent_account",
-		"initial_depth": 3
-	}
+		},
+		{
+			"fieldname": "project",
+			"label": __("Project"),
+			"fieldtype": "Link",
+			"options": "Project"
+		},
+		{
+			"fieldname": "finance_book",
+			"label": __("Finance Book"),
+			"fieldtype": "Link",
+			"options": "Finance Book",
+		},
+		{
+			"fieldname": "presentation_currency",
+			"label": __("Currency"),
+			"fieldtype": "Select",
+			"options": erpnext.get_presentation_currency_list()
+		},
+		{
+			"fieldname": "with_period_closing_entry",
+			"label": __("Period Closing Entry"),
+			"fieldtype": "Check",
+			"default": 1
+		},
+		{
+			"fieldname": "show_zero_values",
+			"label": __("Show zero values"),
+			"fieldtype": "Check"
+		},
+		{
+			"fieldname": "show_unclosed_fy_pl_balances",
+			"label": __("Show unclosed fiscal year's P&L balances"),
+			"fieldtype": "Check"
+		},
+		{
+			"fieldname": "include_default_book_entries",
+			"label": __("Include Default Book Entries"),
+			"fieldtype": "Check",
+			"default": 1
+		},
+		{
+			"fieldname": "show_net_values",
+			"label": __("Show net values in opening and closing columns"),
+			"fieldtype": "Check",
+			"default": 1
+		}
+	],
+	"formatter": erpnext.financial_statements.formatter,
+	"tree": true,
+	"name_field": "account",
+	"parent_field": "parent_account",
+	"initial_depth": 3
+}
 
-	erpnext.utils.add_dimensions('Trial Balance', 6);
-});
+erpnext.utils.add_dimensions('Trial Balance', 6);
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 555ed4f..e0adac4 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -10,7 +10,7 @@
 from frappe import _, qb, throw
 from frappe.model.meta import get_field_precision
 from frappe.query_builder import AliasedQuery, Criterion, Table
-from frappe.query_builder.functions import Sum
+from frappe.query_builder.functions import Round, Sum
 from frappe.query_builder.utils import DocType
 from frappe.utils import (
 	cint,
@@ -536,6 +536,8 @@
 		)
 
 	else:
+		precision = frappe.get_precision("Payment Entry", "unallocated_amount")
+
 		payment_entry = frappe.qb.DocType("Payment Entry")
 		payment_ref = frappe.qb.DocType("Payment Entry Reference")
 
@@ -557,7 +559,10 @@
 				.where(payment_ref.allocated_amount == args.get("unreconciled_amount"))
 			)
 		else:
-			q = q.where(payment_entry.unallocated_amount == args.get("unreconciled_amount"))
+			q = q.where(
+				Round(payment_entry.unallocated_amount, precision)
+				== Round(args.get("unreconciled_amount"), precision)
+			)
 
 	ret = q.run(as_dict=True)
 
@@ -645,7 +650,7 @@
 		"outstanding_amount": d.outstanding_amount,
 		"allocated_amount": d.allocated_amount,
 		"exchange_rate": d.exchange_rate if d.exchange_gain_loss else payment_entry.get_exchange_rate(),
-		"exchange_gain_loss": d.exchange_gain_loss,  # only populated from invoice in case of advance allocation
+		"exchange_gain_loss": d.exchange_gain_loss,
 		"account": d.account,
 	}
 
@@ -658,28 +663,29 @@
 				existing_row.reference_doctype, existing_row.reference_name
 			).set_total_advance_paid()
 
-		original_row = existing_row.as_dict().copy()
-		existing_row.update(reference_details)
+		if d.allocated_amount <= existing_row.allocated_amount:
+			existing_row.allocated_amount -= d.allocated_amount
 
-		if d.allocated_amount < original_row.allocated_amount:
 			new_row = payment_entry.append("references")
 			new_row.docstatus = 1
 			for field in list(reference_details):
-				new_row.set(field, original_row[field])
+				new_row.set(field, reference_details[field])
 
-			new_row.allocated_amount = original_row.allocated_amount - d.allocated_amount
 	else:
 		new_row = payment_entry.append("references")
 		new_row.docstatus = 1
 		new_row.update(reference_details)
 
 	payment_entry.flags.ignore_validate_update_after_submit = True
+	payment_entry.clear_unallocated_reference_document_rows()
 	payment_entry.setup_party_account_field()
 	payment_entry.set_missing_values()
 	if not skip_ref_details_update_for_pe:
 		payment_entry.set_missing_ref_details()
 	payment_entry.set_amounts()
-	payment_entry.make_exchange_gain_loss_journal()
+	payment_entry.make_exchange_gain_loss_journal(
+		frappe._dict({"difference_posting_date": d.difference_posting_date})
+	)
 
 	if not do_not_save:
 		payment_entry.save(ignore_permissions=True)
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index 962292b..d378fbd 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -9,7 +9,6 @@
 		frm.set_query("item_code", function() {
 			return {
 				"filters": {
-					"disabled": 0,
 					"is_fixed_asset": 1,
 					"is_stock_item": 0
 				}
@@ -148,6 +147,15 @@
 
 		if (frm.doc.docstatus == 0) {
 			frm.toggle_reqd("finance_books", frm.doc.calculate_depreciation);
+
+			if (frm.doc.is_composite_asset && !frm.doc.capitalized_in) {
+				$('.primary-action').prop('hidden', true);
+				$('.form-message').text('Capitalize this asset to confirm');
+
+				frm.add_custom_button(__("Capitalize Asset"), function() {
+					frm.trigger("create_asset_capitalization");
+				});
+			}
 		}
 	},
 
@@ -169,7 +177,7 @@
 			frm.set_df_property('purchase_invoice', 'read_only', 1);
 			frm.set_df_property('purchase_receipt', 'read_only', 1);
 		}
-		else if (frm.doc.is_existing_asset) {
+		else if (frm.doc.is_existing_asset || frm.doc.is_composite_asset) {
 			frm.toggle_reqd('purchase_receipt', 0);
 			frm.toggle_reqd('purchase_invoice', 0);
 		}
@@ -239,7 +247,7 @@
 
 		datatable.style.setStyle(`.dt-scrollable`, {'font-size': '0.75rem', 'margin-bottom': '1rem', 'margin-left': '0.35rem', 'margin-right': '0.35rem'});
 		datatable.style.setStyle(`.dt-header`, {'margin-left': '0.35rem', 'margin-right': '0.35rem'});
-		datatable.style.setStyle(`.dt-cell--header`, {'color': 'var(--text-muted)'});
+		datatable.style.setStyle(`.dt-cell--header .dt-cell__content`, {'color': 'var(--gray-600)', 'font-size': 'var(--text-sm)'});
 		datatable.style.setStyle(`.dt-cell`, {'color': 'var(--text-color)'});
 		datatable.style.setStyle(`.dt-cell--col-1`, {'text-align': 'center'});
 		datatable.style.setStyle(`.dt-cell--col-2`, {'font-weight': 600});
@@ -328,7 +336,7 @@
 
 
 	item_code: function(frm) {
-		if(frm.doc.item_code && frm.doc.calculate_depreciation) {
+		if(frm.doc.item_code && frm.doc.calculate_depreciation && frm.doc.gross_purchase_amount) {
 			frm.trigger('set_finance_book');
 		} else {
 			frm.set_value('finance_books', []);
@@ -340,7 +348,8 @@
 			method: "erpnext.assets.doctype.asset.asset.get_item_details",
 			args: {
 				item_code: frm.doc.item_code,
-				asset_category: frm.doc.asset_category
+				asset_category: frm.doc.asset_category,
+				gross_purchase_amount: frm.doc.gross_purchase_amount
 			},
 			callback: function(r, rt) {
 				if(r.message) {
@@ -352,7 +361,17 @@
 
 	is_existing_asset: function(frm) {
 		frm.trigger("toggle_reference_doc");
-		// frm.toggle_reqd("next_depreciation_date", (!frm.doc.is_existing_asset && frm.doc.calculate_depreciation));
+	},
+
+	is_composite_asset: function(frm) {
+		if(frm.doc.is_composite_asset) {
+			frm.set_value('gross_purchase_amount', 0);
+			frm.set_df_property('gross_purchase_amount', 'read_only', 1);
+		} else {
+			frm.set_df_property('gross_purchase_amount', 'read_only', 0);
+		}
+
+		frm.trigger("toggle_reference_doc");
 	},
 
 	make_sales_invoice: function(frm) {
@@ -402,6 +421,19 @@
 		});
 	},
 
+	create_asset_capitalization: function(frm) {
+		frappe.call({
+			args: {
+				"asset": frm.doc.name,
+			},
+			method: "erpnext.assets.doctype.asset.asset.create_asset_capitalization",
+			callback: function(r) {
+				var doclist = frappe.model.sync(r.message);
+				frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
+			}
+		});
+	},
+
 	split_asset: function(frm) {
 		const title = __('Split Asset');
 
@@ -457,7 +489,7 @@
 
 	calculate_depreciation: function(frm) {
 		frm.toggle_reqd("finance_books", frm.doc.calculate_depreciation);
-		if (frm.doc.item_code && frm.doc.calculate_depreciation ) {
+		if (frm.doc.item_code && frm.doc.calculate_depreciation && frm.doc.gross_purchase_amount) {
 			frm.trigger("set_finance_book");
 		} else {
 			frm.set_value("finance_books", []);
@@ -465,9 +497,11 @@
 	},
 
 	gross_purchase_amount: function(frm) {
-		frm.doc.finance_books.forEach(d => {
-			frm.events.set_depreciation_rate(frm, d);
-		})
+		if (frm.doc.finance_books) {
+			frm.doc.finance_books.forEach(d => {
+				frm.events.set_depreciation_rate(frm, d);
+			})
+		}
 	},
 
 	purchase_receipt: (frm) => {
@@ -546,7 +580,21 @@
 				}
 			});
 		}
-	}
+	},
+
+	set_salvage_value_percentage_or_expected_value_after_useful_life: function(frm, row, salvage_value_percentage_changed, expected_value_after_useful_life_changed) {
+		if (expected_value_after_useful_life_changed) {
+			frappe.flags.from_set_salvage_value_percentage_or_expected_value_after_useful_life = true;
+			const new_salvage_value_percentage = flt((row.expected_value_after_useful_life * 100) / frm.doc.gross_purchase_amount, precision("salvage_value_percentage", row));
+			frappe.model.set_value(row.doctype, row.name, "salvage_value_percentage", new_salvage_value_percentage);
+			frappe.flags.from_set_salvage_value_percentage_or_expected_value_after_useful_life = false;
+		} else if (salvage_value_percentage_changed) {
+			frappe.flags.from_set_salvage_value_percentage_or_expected_value_after_useful_life = true;
+			const new_expected_value_after_useful_life = flt(frm.doc.gross_purchase_amount * (row.salvage_value_percentage / 100), precision('gross_purchase_amount'));
+			frappe.model.set_value(row.doctype, row.name, "expected_value_after_useful_life", new_expected_value_after_useful_life);
+			frappe.flags.from_set_salvage_value_percentage_or_expected_value_after_useful_life = false;
+		}
+	},
 });
 
 frappe.ui.form.on('Asset Finance Book', {
@@ -557,9 +605,19 @@
 
 	expected_value_after_useful_life: function(frm, cdt, cdn) {
 		const row = locals[cdt][cdn];
+		if (!frappe.flags.from_set_salvage_value_percentage_or_expected_value_after_useful_life) {
+			frm.events.set_salvage_value_percentage_or_expected_value_after_useful_life(frm, row, false, true);
+		}
 		frm.events.set_depreciation_rate(frm, row);
 	},
 
+	salvage_value_percentage: function(frm, cdt, cdn) {
+		const row = locals[cdt][cdn];
+		if (!frappe.flags.from_set_salvage_value_percentage_or_expected_value_after_useful_life) {
+			frm.events.set_salvage_value_percentage_or_expected_value_after_useful_life(frm, row, true, false);
+		}
+	},
+
 	frequency_of_depreciation: function(frm, cdt, cdn) {
 		const row = locals[cdt][cdn];
 		frm.events.set_depreciation_rate(frm, row);
diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json
index befb524..40f51ab 100644
--- a/erpnext/assets/doctype/asset/asset.json
+++ b/erpnext/assets/doctype/asset/asset.json
@@ -14,6 +14,7 @@
   "asset_owner",
   "asset_owner_company",
   "is_existing_asset",
+  "is_composite_asset",
   "supplier",
   "customer",
   "image",
@@ -72,7 +73,8 @@
   "purchase_receipt_amount",
   "default_finance_book",
   "depr_entry_posting_status",
-  "amended_from"
+  "amended_from",
+  "capitalized_in"
  ],
  "fields": [
   {
@@ -199,7 +201,7 @@
    "fieldtype": "Date",
    "label": "Purchase Date",
    "read_only": 1,
-   "read_only_depends_on": "eval:!doc.is_existing_asset",
+   "read_only_depends_on": "eval:!doc.is_existing_asset && !doc.is_composite_asset",
    "reqd": 1
   },
   {
@@ -219,11 +221,11 @@
    "read_only": 1
   },
   {
+   "depends_on": "eval:!(doc.is_composite_asset && !doc.capitalized_in)",
    "fieldname": "gross_purchase_amount",
    "fieldtype": "Currency",
    "label": "Gross Purchase Amount",
    "options": "Company:company:default_currency",
-   "read_only": 1,
    "read_only_depends_on": "eval:!doc.is_existing_asset",
    "reqd": 1
   },
@@ -237,10 +239,12 @@
    "default": "0",
    "fieldname": "calculate_depreciation",
    "fieldtype": "Check",
-   "label": "Calculate Depreciation"
+   "label": "Calculate Depreciation",
+   "read_only_depends_on": "eval:doc.is_composite_asset && !doc.gross_purchase_amount"
   },
   {
    "default": "0",
+   "depends_on": "eval:!doc.is_composite_asset",
    "fieldname": "is_existing_asset",
    "fieldtype": "Check",
    "label": "Is Existing Asset"
@@ -395,6 +399,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "depends_on": "eval:!doc.is_composite_asset && !doc.is_existing_asset",
    "fieldname": "purchase_receipt",
    "fieldtype": "Link",
    "label": "Purchase Receipt",
@@ -412,6 +417,7 @@
    "read_only": 1
   },
   {
+   "depends_on": "eval:!doc.is_composite_asset && !doc.is_existing_asset",
    "fieldname": "purchase_invoice",
    "fieldtype": "Link",
    "label": "Purchase Invoice",
@@ -475,10 +481,11 @@
    "read_only": 1
   },
   {
+   "depends_on": "eval.doc.asset_quantity",
    "fieldname": "asset_quantity",
    "fieldtype": "Int",
    "label": "Asset Quantity",
-   "read_only_depends_on": "eval:!doc.is_existing_asset"
+   "read_only": 1
   },
   {
    "fieldname": "depr_entry_posting_status",
@@ -507,6 +514,21 @@
    "fieldname": "is_fully_depreciated",
    "fieldtype": "Check",
    "label": "Is Fully Depreciated"
+  },
+  {
+   "default": "0",
+   "depends_on": "eval:!doc.is_existing_asset",
+   "fieldname": "is_composite_asset",
+   "fieldtype": "Check",
+   "label": "Is Composite Asset"
+  },
+  {
+   "fieldname": "capitalized_in",
+   "fieldtype": "Link",
+   "hidden": 1,
+   "label": "Capitalized In",
+   "options": "Asset Capitalization",
+   "read_only": 1
   }
  ],
  "idx": 72,
@@ -543,9 +565,14 @@
    "link_doctype": "Journal Entry",
    "link_fieldname": "reference_name",
    "table_fieldname": "accounts"
+  },
+  {
+   "group": "Asset Capitalization",
+   "link_doctype": "Asset Capitalization",
+   "link_fieldname": "target_asset"
   }
  ],
- "modified": "2023-07-28 20:12:44.819616",
+ "modified": "2023-10-27 17:03:46.629617",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Asset",
@@ -589,4 +616,4 @@
  "states": [],
  "title_field": "asset_name",
  "track_changes": 1
-}
+}
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index a732dec..32518a1 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -198,7 +198,9 @@
 			self.asset_category = frappe.get_cached_value("Item", self.item_code, "asset_category")
 
 		if self.item_code and not self.get("finance_books"):
-			finance_books = get_item_details(self.item_code, self.asset_category)
+			finance_books = get_item_details(
+				self.item_code, self.asset_category, self.gross_purchase_amount
+			)
 			self.set("finance_books", finance_books)
 
 	def validate_finance_books(self):
@@ -226,7 +228,7 @@
 		if not self.asset_category:
 			self.asset_category = frappe.get_cached_value("Item", self.item_code, "asset_category")
 
-		if not flt(self.gross_purchase_amount):
+		if not flt(self.gross_purchase_amount) and not self.is_composite_asset:
 			frappe.throw(_("Gross Purchase Amount is mandatory"), frappe.MandatoryError)
 
 		if is_cwip_accounting_enabled(self.asset_category):
@@ -769,6 +771,15 @@
 
 
 @frappe.whitelist()
+def create_asset_capitalization(asset):
+	asset_capitalization = frappe.new_doc("Asset Capitalization")
+	asset_capitalization.update(
+		{"target_asset": asset, "capitalization_method": "Choose a WIP composite asset"}
+	)
+	return asset_capitalization
+
+
+@frappe.whitelist()
 def create_asset_value_adjustment(asset, asset_category, company):
 	asset_value_adjustment = frappe.new_doc("Asset Value Adjustment")
 	asset_value_adjustment.update(
@@ -799,7 +810,7 @@
 
 
 @frappe.whitelist()
-def get_item_details(item_code, asset_category):
+def get_item_details(item_code, asset_category, gross_purchase_amount):
 	asset_category_doc = frappe.get_doc("Asset Category", asset_category)
 	books = []
 	for d in asset_category_doc.finance_books:
@@ -809,7 +820,11 @@
 				"depreciation_method": d.depreciation_method,
 				"total_number_of_depreciations": d.total_number_of_depreciations,
 				"frequency_of_depreciation": d.frequency_of_depreciation,
-				"start_date": nowdate(),
+				"daily_prorata_based": d.daily_prorata_based,
+				"salvage_value_percentage": d.salvage_value_percentage,
+				"expected_value_after_useful_life": flt(gross_purchase_amount)
+				* flt(d.salvage_value_percentage / 100),
+				"depreciation_start_date": d.depreciation_start_date or nowdate(),
 			}
 		)
 
diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py
index e2a4b29..84a428c 100644
--- a/erpnext/assets/doctype/asset/depreciation.py
+++ b/erpnext/assets/doctype/asset/depreciation.py
@@ -780,6 +780,15 @@
 def get_value_after_depreciation_on_disposal_date(asset, disposal_date, finance_book=None):
 	asset_doc = frappe.get_doc("Asset", asset)
 
+	if asset_doc.available_for_use_date > getdate(disposal_date):
+		frappe.throw(
+			"Disposal date {0} cannot be before available for use date {1} of the asset.".format(
+				disposal_date, asset_doc.available_for_use_date
+			)
+		)
+	elif asset_doc.available_for_use_date == getdate(disposal_date):
+		return flt(asset_doc.gross_purchase_amount - asset_doc.opening_accumulated_depreciation)
+
 	if not asset_doc.calculate_depreciation:
 		return flt(asset_doc.value_after_depreciation)
 
diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py
index 39fcb21..9e3ec6f 100644
--- a/erpnext/assets/doctype/asset/test_asset.py
+++ b/erpnext/assets/doctype/asset/test_asset.py
@@ -19,7 +19,6 @@
 from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
 from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
 from erpnext.assets.doctype.asset.asset import (
-	get_asset_value_after_depreciation,
 	make_sales_invoice,
 	split_asset,
 	update_maintenance_status,
@@ -194,6 +193,7 @@
 	def test_is_fixed_asset_set(self):
 		asset = create_asset(is_existing_asset=1)
 		doc = frappe.new_doc("Purchase Invoice")
+		doc.company = "_Test Company"
 		doc.supplier = "_Test Supplier"
 		doc.append("items", {"item_code": "Macbook Pro", "qty": 1, "asset": asset.name})
 
@@ -534,7 +534,7 @@
 
 		self.assertEqual("Asset Received But Not Billed - _TC", doc.items[0].expense_account)
 
-	# CWIP: Capital Work In Progress
+	# Capital Work In Progress
 	def test_cwip_accounting(self):
 		pr = make_purchase_receipt(
 			item_code="Macbook Pro", qty=1, rate=5000, do_not_submit=True, location="Test Location"
@@ -567,7 +567,8 @@
 		pr.submit()
 
 		expected_gle = (
-			("Asset Received But Not Billed - _TC", 0.0, 5250.0),
+			("_Test Account Shipping Charges - _TC", 0.0, 250.0),
+			("Asset Received But Not Billed - _TC", 0.0, 5000.0),
 			("CWIP Account - _TC", 5250.0, 0.0),
 		)
 
@@ -586,9 +587,8 @@
 		expected_gle = (
 			("_Test Account Service Tax - _TC", 250.0, 0.0),
 			("_Test Account Shipping Charges - _TC", 250.0, 0.0),
-			("Asset Received But Not Billed - _TC", 5250.0, 0.0),
+			("Asset Received But Not Billed - _TC", 5000.0, 0.0),
 			("Creditors - _TC", 0.0, 5500.0),
-			("Expenses Included In Asset Valuation - _TC", 0.0, 250.0),
 		)
 
 		pi_gle = frappe.db.sql(
@@ -755,7 +755,9 @@
 
 		self.assertEqual(schedules, expected_schedules)
 
-	def test_schedule_for_straight_line_method_with_daily_depreciation(self):
+	def test_schedule_for_straight_line_method_with_daily_prorata_based(
+		self,
+	):
 		asset = create_asset(
 			calculate_depreciation=1,
 			available_for_use_date="2023-01-01",
@@ -764,7 +766,7 @@
 			depreciation_start_date="2023-01-31",
 			total_number_of_depreciations=12,
 			frequency_of_depreciation=1,
-			daily_depreciation=1,
+			daily_prorata_based=1,
 		)
 
 		expected_schedules = [
@@ -1744,6 +1746,7 @@
 			"location": args.location or "Test Location",
 			"asset_owner": args.asset_owner or "Company",
 			"is_existing_asset": args.is_existing_asset or 1,
+			"is_composite_asset": args.is_composite_asset or 0,
 			"asset_quantity": args.get("asset_quantity") or 1,
 			"depr_entry_posting_status": args.depr_entry_posting_status or "",
 		}
@@ -1759,7 +1762,7 @@
 				"total_number_of_depreciations": args.total_number_of_depreciations or 5,
 				"expected_value_after_useful_life": args.expected_value_after_useful_life or 0,
 				"depreciation_start_date": args.depreciation_start_date,
-				"daily_depreciation": args.daily_depreciation or 0,
+				"daily_prorata_based": args.daily_prorata_based or 0,
 			},
 		)
 
@@ -1788,6 +1791,7 @@
 			"fixed_asset_account": "_Test Fixed Asset - _TC",
 			"accumulated_depreciation_account": "_Test Accumulated Depreciations - _TC",
 			"depreciation_expense_account": "_Test Depreciations - _TC",
+			"capital_work_in_progress_account": "CWIP Account - _TC",
 		},
 	)
 	asset_category.append(
diff --git a/erpnext/assets/doctype/asset_activity/asset_activity.json b/erpnext/assets/doctype/asset_activity/asset_activity.json
index 476fb27..00992e2 100644
--- a/erpnext/assets/doctype/asset_activity/asset_activity.json
+++ b/erpnext/assets/doctype/asset_activity/asset_activity.json
@@ -75,13 +75,14 @@
  "in_create": 1,
  "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2023-08-01 11:09:52.584482",
+ "modified": "2023-09-29 15:56:17.608643",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Asset Activity",
  "owner": "Administrator",
  "permissions": [
   {
+   "delete": 1,
    "email": 1,
    "read": 1,
    "report": 1,
@@ -89,6 +90,7 @@
    "share": 1
   },
   {
+   "delete": 1,
    "email": 1,
    "read": 1,
    "report": 1,
@@ -96,6 +98,7 @@
    "share": 1
   },
   {
+   "delete": 1,
    "email": 1,
    "read": 1,
    "report": 1,
diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js
index 6d55d77..be78d9e 100644
--- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js
+++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js
@@ -16,9 +16,15 @@
 
 	refresh() {
 		this.show_general_ledger();
+
 		if ((this.frm.doc.stock_items && this.frm.doc.stock_items.length) || !this.frm.doc.target_is_fixed_asset) {
 			this.show_stock_ledger();
 		}
+
+		if (this.frm.doc.stock_items && !this.frm.doc.stock_items.length && this.frm.doc.target_asset && this.frm.doc.capitalization_method === "Choose a WIP composite asset") {
+			this.set_consumed_stock_items_tagged_to_wip_composite_asset(this.frm.doc.target_asset);
+			this.get_target_asset_details();
+		}
 	}
 
 	setup_queries() {
@@ -35,18 +41,9 @@
 		});
 
 		me.frm.set_query("target_asset", function() {
-			var filters = {};
-
-			if (me.frm.doc.target_item_code) {
-				filters['item_code'] = me.frm.doc.target_item_code;
-			}
-
-			filters['status'] = ["not in", ["Draft", "Scrapped", "Sold", "Capitalized", "Decapitalized"]];
-			filters['docstatus'] = 1;
-
 			return {
-				filters: filters
-			};
+				filters: {'is_composite_asset': 1, 'docstatus': 0 }
+			}
 		});
 
 		me.frm.set_query("asset", "asset_items", function() {
@@ -128,6 +125,39 @@
 		return this.get_target_item_details();
 	}
 
+	target_asset() {
+		if (this.frm.doc.target_asset && this.frm.doc.capitalization_method === "Choose a WIP composite asset") {
+			this.set_consumed_stock_items_tagged_to_wip_composite_asset(this.frm.doc.target_asset);
+			this.get_target_asset_details();
+		}
+	}
+
+	set_consumed_stock_items_tagged_to_wip_composite_asset(asset) {
+		var me = this;
+
+		if (asset) {
+			return me.frm.call({
+				method: "erpnext.assets.doctype.asset_capitalization.asset_capitalization.get_items_tagged_to_wip_composite_asset",
+				args: {
+					asset: asset,
+				},
+				callback: function (r) {
+					if (!r.exc && r.message) {
+						me.frm.clear_table("stock_items");
+
+						for (let item of r.message) {
+							me.frm.add_child("stock_items", item);
+						}
+
+						refresh_field("stock_items");
+
+						me.calculate_totals();
+					}
+				}
+			});
+		}
+	}
+
 	item_code(doc, cdt, cdn) {
 		var row = frappe.get_doc(cdt, cdn);
 		if (cdt === "Asset Capitalization Stock Item") {
@@ -242,6 +272,26 @@
 		}
 	}
 
+	get_target_asset_details() {
+		var me = this;
+
+		if (me.frm.doc.target_asset) {
+			return me.frm.call({
+				method: "erpnext.assets.doctype.asset_capitalization.asset_capitalization.get_target_asset_details",
+				child: me.frm.doc,
+				args: {
+					asset: me.frm.doc.target_asset,
+					company: me.frm.doc.company,
+				},
+				callback: function (r) {
+					if (!r.exc) {
+						me.frm.refresh_fields();
+					}
+				}
+			});
+		}
+	}
+
 	get_consumed_stock_item_details(row) {
 		var me = this;
 
diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.json b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.json
index 04b0c4e..9ddc442 100644
--- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.json
+++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.json
@@ -8,24 +8,25 @@
  "engine": "InnoDB",
  "field_order": [
   "title",
+  "company",
   "naming_series",
   "entry_type",
-  "target_item_code",
-  "target_asset",
   "target_item_name",
   "target_is_fixed_asset",
   "target_has_batch_no",
   "target_has_serial_no",
   "column_break_9",
-  "target_asset_name",
+  "capitalization_method",
+  "target_item_code",
   "target_asset_location",
+  "target_asset",
+  "target_asset_name",
   "target_warehouse",
   "target_qty",
   "target_stock_uom",
   "target_batch_no",
   "target_serial_no",
   "column_break_5",
-  "company",
   "finance_book",
   "posting_date",
   "posting_time",
@@ -57,12 +58,13 @@
    "label": "Title"
   },
   {
+   "depends_on": "eval:(doc.target_item_code && !doc.__islocal && doc.capitalization_method !== 'Choose a WIP composite asset') || ((doc.entry_type=='Capitalization' && doc.capitalization_method=='Create a new composite asset') || doc.entry_type=='Decapitalization')",
    "fieldname": "target_item_code",
    "fieldtype": "Link",
    "in_standard_filter": 1,
    "label": "Target Item Code",
-   "options": "Item",
-   "reqd": 1
+   "mandatory_depends_on": "eval:(doc.entry_type=='Capitalization' && doc.capitalization_method=='Create a new composite asset') || doc.entry_type=='Decapitalization'",
+   "options": "Item"
   },
   {
    "depends_on": "eval:doc.target_item_code && doc.target_item_name != doc.target_item_code",
@@ -86,16 +88,18 @@
    "fieldtype": "Column Break"
   },
   {
+   "depends_on": "eval:(doc.target_asset && !doc.__islocal) || (doc.entry_type=='Capitalization' && doc.capitalization_method=='Choose a WIP composite asset')",
    "fieldname": "target_asset",
    "fieldtype": "Link",
    "in_standard_filter": 1,
    "label": "Target Asset",
+   "mandatory_depends_on": "eval:doc.entry_type=='Capitalization' && doc.capitalization_method=='Choose a WIP composite asset'",
    "no_copy": 1,
    "options": "Asset",
-   "read_only": 1
+   "read_only_depends_on": "eval:(doc.entry_type=='Decapitalization') || (doc.entry_type=='Capitalization' && doc.capitalization_method=='Create a new composite asset')"
   },
   {
-   "depends_on": "eval:doc.entry_type=='Capitalization'",
+   "depends_on": "eval:(doc.target_asset_name && !doc.__islocal) || (doc.target_asset && doc.entry_type=='Capitalization' && doc.capitalization_method=='Choose a WIP composite asset')",
    "fetch_from": "target_asset.asset_name",
    "fieldname": "target_asset_name",
    "fieldtype": "Data",
@@ -186,12 +190,14 @@
   },
   {
    "default": "1",
+   "depends_on": "eval:doc.entry_type=='Decapitalization'",
    "fieldname": "target_qty",
    "fieldtype": "Float",
    "label": "Target Qty",
    "read_only_depends_on": "eval:doc.entry_type=='Capitalization'"
   },
   {
+   "depends_on": "eval:doc.entry_type=='Decapitalization'",
    "fetch_from": "target_item_code.stock_uom",
    "fieldname": "target_stock_uom",
    "fieldtype": "Link",
@@ -331,18 +337,26 @@
    "read_only": 1
   },
   {
-   "depends_on": "eval:doc.entry_type=='Capitalization'",
+   "depends_on": "eval:doc.entry_type=='Capitalization' && doc.capitalization_method=='Create a new composite asset'",
    "fieldname": "target_asset_location",
    "fieldtype": "Link",
    "label": "Target Asset Location",
-   "mandatory_depends_on": "eval:doc.entry_type=='Capitalization'",
+   "mandatory_depends_on": "eval:doc.entry_type=='Capitalization' && doc.capitalization_method=='Create a new composite asset'",
    "options": "Location"
+  },
+  {
+   "depends_on": "eval:doc.entry_type=='Capitalization'",
+   "fieldname": "capitalization_method",
+   "fieldtype": "Select",
+   "label": "Capitalization Method",
+   "mandatory_depends_on": "eval:doc.entry_type=='Capitalization'",
+   "options": "\nCreate a new composite asset\nChoose a WIP composite asset"
   }
  ],
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-06-22 14:17:07.995120",
+ "modified": "2023-10-03 22:55:59.461456",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Asset Capitalization",
diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
index ad91edc..229c16d 100644
--- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
+++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
@@ -53,6 +53,7 @@
 		self.validate_posting_time()
 		self.set_missing_values(for_validate=True)
 		self.validate_target_item()
+		self.validate_target_asset()
 		self.validate_consumed_stock_item()
 		self.validate_consumed_asset_item()
 		self.validate_service_item()
@@ -67,12 +68,12 @@
 
 	def before_submit(self):
 		self.validate_source_mandatory()
-		if self.entry_type == "Capitalization":
-			self.create_target_asset()
+		self.create_target_asset()
 
 	def on_submit(self):
 		self.update_stock_ledger()
 		self.make_gl_entries()
+		self.update_target_asset()
 
 	def on_cancel(self):
 		self.ignore_linked_doctypes = (
@@ -94,6 +95,11 @@
 			if self.meta.has_field(k) and (not self.get(k) or k in force_fields):
 				self.set(k, v)
 
+		target_asset_details = get_target_asset_details(self.target_asset, self.company)
+		for k, v in target_asset_details.items():
+			if self.meta.has_field(k) and (not self.get(k) or k in force_fields):
+				self.set(k, v)
+
 		for d in self.stock_items:
 			args = self.as_dict()
 			args.update(d.as_dict())
@@ -155,6 +161,33 @@
 
 		self.validate_item(target_item)
 
+	def validate_target_asset(self):
+		if self.target_asset:
+			target_asset = self.get_asset_for_validation(self.target_asset)
+
+			if not target_asset.is_composite_asset:
+				frappe.throw(_("Target Asset {0} needs to be composite asset").format(target_asset.name))
+
+			if target_asset.item_code != self.target_item_code:
+				frappe.throw(
+					_("Asset {0} does not belong to Item {1}").format(self.target_asset, self.target_item_code)
+				)
+
+			if target_asset.status in ("Scrapped", "Sold", "Capitalized", "Decapitalized"):
+				frappe.throw(
+					_("Target Asset {0} cannot be {1}").format(target_asset.name, target_asset.status)
+				)
+
+			if target_asset.docstatus == 1:
+				frappe.throw(_("Target Asset {0} cannot be submitted").format(target_asset.name))
+			elif target_asset.docstatus == 2:
+				frappe.throw(_("Target Asset {0} cannot be cancelled").format(target_asset.name))
+
+			if target_asset.company != self.company:
+				frappe.throw(
+					_("Target Asset {0} does not belong to company {1}").format(target_asset.name, self.company)
+				)
+
 	def validate_consumed_stock_item(self):
 		for d in self.stock_items:
 			if d.item_code:
@@ -179,7 +212,23 @@
 					)
 
 				asset = self.get_asset_for_validation(d.asset)
-				self.validate_asset(asset)
+
+				if asset.status in ("Draft", "Scrapped", "Sold", "Capitalized", "Decapitalized"):
+					frappe.throw(
+						_("Row #{0}: Consumed Asset {1} cannot be {2}").format(d.idx, asset.name, asset.status)
+					)
+
+				if asset.docstatus == 0:
+					frappe.throw(_("Row #{0}: Consumed Asset {1} cannot be Draft").format(d.idx, asset.name))
+				elif asset.docstatus == 2:
+					frappe.throw(_("Row #{0}: Consumed Asset {1} cannot be cancelled").format(d.idx, asset.name))
+
+				if asset.company != self.company:
+					frappe.throw(
+						_("Row #{0}: Consumed Asset {1} does not belong to company {2}").format(
+							d.idx, asset.name, self.company
+						)
+					)
 
 	def validate_service_item(self):
 		for d in self.service_items:
@@ -214,21 +263,12 @@
 
 	def get_asset_for_validation(self, asset):
 		return frappe.db.get_value(
-			"Asset", asset, ["name", "item_code", "company", "status", "docstatus"], as_dict=1
+			"Asset",
+			asset,
+			["name", "item_code", "company", "status", "docstatus", "is_composite_asset"],
+			as_dict=1,
 		)
 
-	def validate_asset(self, asset):
-		if asset.status in ("Draft", "Scrapped", "Sold", "Capitalized", "Decapitalized"):
-			frappe.throw(_("Asset {0} is {1}").format(asset.name, asset.status))
-
-		if asset.docstatus == 0:
-			frappe.throw(_("Asset {0} is Draft").format(asset.name))
-		if asset.docstatus == 2:
-			frappe.throw(_("Asset {0} is cancelled").format(asset.name))
-
-		if asset.company != self.company:
-			frappe.throw(_("Asset {0} does not belong to company {1}").format(asset.name, self.company))
-
 	@frappe.whitelist()
 	def set_warehouse_details(self):
 		for d in self.get("stock_items"):
@@ -501,16 +541,25 @@
 					)
 
 	def create_target_asset(self):
+		if (
+			self.entry_type != "Capitalization"
+			or self.capitalization_method != "Create a new composite asset"
+		):
+			return
+
 		total_target_asset_value = flt(self.total_value, self.precision("total_value"))
+
 		asset_doc = frappe.new_doc("Asset")
 		asset_doc.company = self.company
 		asset_doc.item_code = self.target_item_code
-		asset_doc.is_existing_asset = 1
+		asset_doc.is_composite_asset = 1
 		asset_doc.location = self.target_asset_location
 		asset_doc.available_for_use_date = self.posting_date
 		asset_doc.purchase_date = self.posting_date
 		asset_doc.gross_purchase_amount = total_target_asset_value
 		asset_doc.purchase_receipt_amount = total_target_asset_value
+		asset_doc.purchase_receipt_amount = total_target_asset_value
+		asset_doc.capitalized_in = self.name
 		asset_doc.flags.ignore_validate = True
 		asset_doc.flags.asset_created_via_asset_capitalization = True
 		asset_doc.insert()
@@ -534,6 +583,28 @@
 			).format(get_link_to_form("Asset", asset_doc.name))
 		)
 
+	def update_target_asset(self):
+		if (
+			self.entry_type != "Capitalization"
+			or self.capitalization_method != "Choose a WIP composite asset"
+		):
+			return
+
+		total_target_asset_value = flt(self.total_value, self.precision("total_value"))
+
+		asset_doc = frappe.get_doc("Asset", self.target_asset)
+		asset_doc.gross_purchase_amount = total_target_asset_value
+		asset_doc.purchase_receipt_amount = total_target_asset_value
+		asset_doc.capitalized_in = self.name
+		asset_doc.flags.ignore_validate = True
+		asset_doc.save()
+
+		frappe.msgprint(
+			_(
+				"Asset {0} has been updated. Please set the depreciation details if any and submit it."
+			).format(get_link_to_form("Asset", asset_doc.name))
+		)
+
 	def restore_consumed_asset_items(self):
 		for item in self.asset_items:
 			asset = frappe.get_doc("Asset", item.asset)
@@ -619,6 +690,33 @@
 
 
 @frappe.whitelist()
+def get_target_asset_details(asset=None, company=None):
+	out = frappe._dict()
+
+	# Get Asset Details
+	asset_details = frappe._dict()
+	if asset:
+		asset_details = frappe.db.get_value("Asset", asset, ["asset_name", "item_code"], as_dict=1)
+		if not asset_details:
+			frappe.throw(_("Asset {0} does not exist").format(asset))
+
+		# Re-set item code from Asset
+		out.target_item_code = asset_details.item_code
+
+	# Set Asset Details
+	out.asset_name = asset_details.asset_name
+
+	if asset_details.item_code:
+		out.target_fixed_asset_account = get_asset_category_account(
+			"fixed_asset_account", item=asset_details.item_code, company=company
+		)
+	else:
+		out.target_fixed_asset_account = None
+
+	return out
+
+
+@frappe.whitelist()
 def get_consumed_stock_item_details(args):
 	if isinstance(args, str):
 		args = json.loads(args)
@@ -766,3 +864,26 @@
 	)
 
 	return out
+
+
+@frappe.whitelist()
+def get_items_tagged_to_wip_composite_asset(asset):
+	fields = [
+		"item_code",
+		"item_name",
+		"batch_no",
+		"serial_no",
+		"stock_qty",
+		"stock_uom",
+		"warehouse",
+		"cost_center",
+		"qty",
+		"valuation_rate",
+		"amount",
+	]
+
+	pr_items = frappe.get_all(
+		"Purchase Receipt Item", filters={"wip_composite_asset": asset}, fields=fields
+	)
+
+	return pr_items
diff --git a/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py
index 1c445da..7a7a10d 100644
--- a/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py
+++ b/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py
@@ -58,6 +58,7 @@
 		# Create and submit Asset Captitalization
 		asset_capitalization = create_asset_capitalization(
 			entry_type="Capitalization",
+			capitalization_method="Create a new composite asset",
 			target_item_code="Macbook Pro",
 			target_asset_location="Test Location",
 			stock_qty=stock_qty,
@@ -147,6 +148,7 @@
 		# Create and submit Asset Captitalization
 		asset_capitalization = create_asset_capitalization(
 			entry_type="Capitalization",
+			capitalization_method="Create a new composite asset",
 			target_item_code="Macbook Pro",
 			target_asset_location="Test Location",
 			stock_qty=stock_qty,
@@ -212,6 +214,77 @@
 		self.assertFalse(get_actual_gle_dict(asset_capitalization.name))
 		self.assertFalse(get_actual_sle_dict(asset_capitalization.name))
 
+	def test_capitalization_with_wip_composite_asset(self):
+		company = "_Test Company with perpetual inventory"
+		set_depreciation_settings_in_company(company=company)
+
+		stock_rate = 1000
+		stock_qty = 2
+		stock_amount = 2000
+
+		total_amount = 2000
+
+		wip_composite_asset = create_asset(
+			asset_name="Asset Capitalization WIP Composite Asset",
+			is_composite_asset=1,
+			warehouse="Stores - TCP1",
+			company=company,
+		)
+
+		# Create and submit Asset Captitalization
+		asset_capitalization = create_asset_capitalization(
+			entry_type="Capitalization",
+			capitalization_method="Choose a WIP composite asset",
+			target_asset=wip_composite_asset.name,
+			target_asset_location="Test Location",
+			stock_qty=stock_qty,
+			stock_rate=stock_rate,
+			service_expense_account="Expenses Included In Asset Valuation - TCP1",
+			company=company,
+			submit=1,
+		)
+
+		# Test Asset Capitalization values
+		self.assertEqual(asset_capitalization.entry_type, "Capitalization")
+		self.assertEqual(asset_capitalization.capitalization_method, "Choose a WIP composite asset")
+		self.assertEqual(asset_capitalization.target_qty, 1)
+
+		self.assertEqual(asset_capitalization.stock_items[0].valuation_rate, stock_rate)
+		self.assertEqual(asset_capitalization.stock_items[0].amount, stock_amount)
+		self.assertEqual(asset_capitalization.stock_items_total, stock_amount)
+
+		self.assertEqual(asset_capitalization.total_value, total_amount)
+		self.assertEqual(asset_capitalization.target_incoming_rate, total_amount)
+
+		# Test Target Asset values
+		target_asset = frappe.get_doc("Asset", asset_capitalization.target_asset)
+		self.assertEqual(target_asset.gross_purchase_amount, total_amount)
+		self.assertEqual(target_asset.purchase_receipt_amount, total_amount)
+
+		# Test General Ledger Entries
+		expected_gle = {
+			"_Test Fixed Asset - TCP1": 2000,
+			"_Test Warehouse - TCP1": -2000,
+		}
+		actual_gle = get_actual_gle_dict(asset_capitalization.name)
+
+		self.assertEqual(actual_gle, expected_gle)
+
+		# Test Stock Ledger Entries
+		expected_sle = {
+			("Capitalization Source Stock Item", "_Test Warehouse - TCP1"): {
+				"actual_qty": -stock_qty,
+				"stock_value_difference": -stock_amount,
+			}
+		}
+		actual_sle = get_actual_sle_dict(asset_capitalization.name)
+		self.assertEqual(actual_sle, expected_sle)
+
+		# Cancel Asset Capitalization and make test entries and status are reversed
+		asset_capitalization.cancel()
+		self.assertFalse(get_actual_gle_dict(asset_capitalization.name))
+		self.assertFalse(get_actual_sle_dict(asset_capitalization.name))
+
 	def test_decapitalization_with_depreciation(self):
 		# Variables
 		purchase_date = "2020-01-01"
@@ -349,6 +422,7 @@
 	asset_capitalization.update(
 		{
 			"entry_type": args.entry_type or "Capitalization",
+			"capitalization_method": args.capitalization_method or None,
 			"company": company,
 			"posting_date": args.posting_date or now.strftime("%Y-%m-%d"),
 			"posting_time": args.posting_time or now.strftime("%H:%M:%S.%f"),
diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json
index 3772ef4..8d8b463 100644
--- a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json
+++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json
@@ -19,7 +19,7 @@
   "depreciation_method",
   "total_number_of_depreciations",
   "rate_of_depreciation",
-  "daily_depreciation",
+  "daily_prorata_based",
   "column_break_8",
   "frequency_of_depreciation",
   "expected_value_after_useful_life",
@@ -179,9 +179,9 @@
   {
    "default": "0",
    "depends_on": "eval:doc.depreciation_method == \"Straight Line\" || doc.depreciation_method == \"Manual\"",
-   "fieldname": "daily_depreciation",
+   "fieldname": "daily_prorata_based",
    "fieldtype": "Check",
-   "label": "Daily Depreciation",
+   "label": "Depreciate based on daily pro-rata",
    "print_hide": 1,
    "read_only": 1
   }
@@ -189,7 +189,7 @@
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-08-10 22:22:09.722968",
+ "modified": "2023-11-03 21:32:15.021796",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Asset Depreciation Schedule",
diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
index 7a88ffc..7305691 100644
--- a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
+++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
@@ -153,7 +153,7 @@
 		self.frequency_of_depreciation = row.frequency_of_depreciation
 		self.rate_of_depreciation = row.rate_of_depreciation
 		self.expected_value_after_useful_life = row.expected_value_after_useful_life
-		self.daily_depreciation = row.daily_depreciation
+		self.daily_prorata_based = row.daily_prorata_based
 		self.status = "Draft"
 
 	def make_depr_schedule(
@@ -573,7 +573,7 @@
 		)
 	# if the Depreciation Schedule is being modified after Asset Value Adjustment due to decrease in asset value
 	elif asset.flags.decrease_in_asset_value_due_to_value_adjustment:
-		if row.daily_depreciation:
+		if row.daily_prorata_based:
 			daily_depr_amount = (
 				flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)
 			) / date_diff(
@@ -618,7 +618,7 @@
 			) / number_of_pending_depreciations
 	# if the Depreciation Schedule is being prepared for the first time
 	else:
-		if row.daily_depreciation:
+		if row.daily_prorata_based:
 			daily_depr_amount = (
 				flt(asset.gross_purchase_amount)
 				- flt(asset.opening_accumulated_depreciation)
diff --git a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
index 4121302..e597d5f 100644
--- a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
+++ b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
@@ -8,10 +8,11 @@
   "finance_book",
   "depreciation_method",
   "total_number_of_depreciations",
-  "daily_depreciation",
+  "daily_prorata_based",
   "column_break_5",
   "frequency_of_depreciation",
   "depreciation_start_date",
+  "salvage_value_percentage",
   "expected_value_after_useful_life",
   "value_after_depreciation",
   "rate_of_depreciation"
@@ -86,17 +87,22 @@
    "label": "Rate of Depreciation"
   },
   {
+   "fieldname": "salvage_value_percentage",
+   "fieldtype": "Percent",
+   "label": "Salvage Value Percentage"
+  },
+  {
    "default": "0",
    "depends_on": "eval:doc.depreciation_method == \"Straight Line\" || doc.depreciation_method == \"Manual\"",
-   "fieldname": "daily_depreciation",
+   "fieldname": "daily_prorata_based",
    "fieldtype": "Check",
-   "label": "Daily Depreciation"
+   "label": "Depreciate based on daily pro-rata"
   }
  ],
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-08-10 22:10:36.576199",
+ "modified": "2023-11-03 21:30:24.266601",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Asset Finance Book",
diff --git a/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py b/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py
index 23088c9..a33acfd 100644
--- a/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py
+++ b/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py
@@ -13,25 +13,22 @@
 class TestAssetMaintenance(unittest.TestCase):
 	def setUp(self):
 		set_depreciation_settings_in_company()
-		create_asset_data()
-		create_maintenance_team()
-
-	def test_create_asset_maintenance(self):
-		pr = make_purchase_receipt(
+		self.pr = make_purchase_receipt(
 			item_code="Photocopier", qty=1, rate=100000.0, location="Test Location"
 		)
+		self.asset_name = frappe.db.get_value("Asset", {"purchase_receipt": self.pr.name}, "name")
+		self.asset_doc = frappe.get_doc("Asset", self.asset_name)
 
-		asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, "name")
-		asset_doc = frappe.get_doc("Asset", asset_name)
+	def test_create_asset_maintenance_with_log(self):
 		month_end_date = get_last_day(nowdate())
 
 		purchase_date = nowdate() if nowdate() != month_end_date else add_days(nowdate(), -15)
 
-		asset_doc.available_for_use_date = purchase_date
-		asset_doc.purchase_date = purchase_date
+		self.asset_doc.available_for_use_date = purchase_date
+		self.asset_doc.purchase_date = purchase_date
 
-		asset_doc.calculate_depreciation = 1
-		asset_doc.append(
+		self.asset_doc.calculate_depreciation = 1
+		self.asset_doc.append(
 			"finance_books",
 			{
 				"expected_value_after_useful_life": 200,
@@ -42,97 +39,40 @@
 			},
 		)
 
-		asset_doc.save()
+		self.asset_doc.save()
 
-		if not frappe.db.exists("Asset Maintenance", "Photocopier"):
-			asset_maintenance = frappe.get_doc(
-				{
-					"doctype": "Asset Maintenance",
-					"asset_name": "Photocopier",
-					"maintenance_team": "Team Awesome",
-					"company": "_Test Company",
-					"asset_maintenance_tasks": get_maintenance_tasks(),
-				}
-			).insert()
+		asset_maintenance = frappe.get_doc(
+			{
+				"doctype": "Asset Maintenance",
+				"asset_name": self.asset_name,
+				"maintenance_team": "Team Awesome",
+				"company": "_Test Company",
+				"asset_maintenance_tasks": get_maintenance_tasks(),
+			}
+		).insert()
 
-			next_due_date = calculate_next_due_date(nowdate(), "Monthly")
-			self.assertEqual(asset_maintenance.asset_maintenance_tasks[0].next_due_date, next_due_date)
-
-	def test_create_asset_maintenance_log(self):
-		if not frappe.db.exists("Asset Maintenance Log", "Photocopier"):
-			asset_maintenance_log = frappe.get_doc(
-				{
-					"doctype": "Asset Maintenance Log",
-					"asset_maintenance": "Photocopier",
-					"task": "Change Oil",
-					"completion_date": add_days(nowdate(), 2),
-					"maintenance_status": "Completed",
-				}
-			).insert()
-		asset_maintenance = frappe.get_doc("Asset Maintenance", "Photocopier")
-		next_due_date = calculate_next_due_date(asset_maintenance_log.completion_date, "Monthly")
+		next_due_date = calculate_next_due_date(nowdate(), "Monthly")
 		self.assertEqual(asset_maintenance.asset_maintenance_tasks[0].next_due_date, next_due_date)
 
+		asset_maintenance_log = frappe.db.get_value(
+			"Asset Maintenance Log",
+			{"asset_maintenance": asset_maintenance.name, "task_name": "Change Oil"},
+			"name",
+		)
 
-def create_asset_data():
-	if not frappe.db.exists("Asset Category", "Equipment"):
-		create_asset_category()
-
-	if not frappe.db.exists("Location", "Test Location"):
-		frappe.get_doc({"doctype": "Location", "location_name": "Test Location"}).insert()
-
-	if not frappe.db.exists("Item", "Photocopier"):
-		meta = frappe.get_meta("Asset")
-		naming_series = meta.get_field("naming_series").options
-		frappe.get_doc(
+		asset_maintenance_log_doc = frappe.get_doc("Asset Maintenance Log", asset_maintenance_log)
+		asset_maintenance_log_doc.update(
 			{
-				"doctype": "Item",
-				"item_code": "Photocopier",
-				"item_name": "Photocopier",
-				"item_group": "All Item Groups",
-				"company": "_Test Company",
-				"is_fixed_asset": 1,
-				"is_stock_item": 0,
-				"asset_category": "Equipment",
-				"auto_create_assets": 1,
-				"asset_naming_series": naming_series,
+				"completion_date": add_days(nowdate(), 2),
+				"maintenance_status": "Completed",
 			}
-		).insert()
+		)
 
+		asset_maintenance_log_doc.save()
+		next_due_date = calculate_next_due_date(asset_maintenance_log_doc.completion_date, "Monthly")
 
-def create_maintenance_team():
-	user_list = ["marcus@abc.com", "thalia@abc.com", "mathias@abc.com"]
-	if not frappe.db.exists("Role", "Technician"):
-		frappe.get_doc({"doctype": "Role", "role_name": "Technician"}).insert()
-	for user in user_list:
-		if not frappe.db.get_value("User", user):
-			frappe.get_doc(
-				{
-					"doctype": "User",
-					"email": user,
-					"first_name": user,
-					"new_password": "password",
-					"roles": [{"doctype": "Has Role", "role": "Technician"}],
-				}
-			).insert()
-
-	if not frappe.db.exists("Asset Maintenance Team", "Team Awesome"):
-		frappe.get_doc(
-			{
-				"doctype": "Asset Maintenance Team",
-				"maintenance_manager": "marcus@abc.com",
-				"maintenance_team_name": "Team Awesome",
-				"company": "_Test Company",
-				"maintenance_team_members": get_maintenance_team(user_list),
-			}
-		).insert()
-
-
-def get_maintenance_team(user_list):
-	return [
-		{"team_member": user, "full_name": user, "maintenance_role": "Technician"}
-		for user in user_list[1:]
-	]
+		asset_maintenance.reload()
+		self.assertEqual(asset_maintenance.asset_maintenance_tasks[0].next_due_date, next_due_date)
 
 
 def get_maintenance_tasks():
@@ -156,23 +96,6 @@
 	]
 
 
-def create_asset_category():
-	asset_category = frappe.new_doc("Asset Category")
-	asset_category.asset_category_name = "Equipment"
-	asset_category.total_number_of_depreciations = 3
-	asset_category.frequency_of_depreciation = 3
-	asset_category.append(
-		"accounts",
-		{
-			"company_name": "_Test Company",
-			"fixed_asset_account": "_Test Fixed Asset - _TC",
-			"accumulated_depreciation_account": "_Test Accumulated Depreciations - _TC",
-			"depreciation_expense_account": "_Test Depreciations - _TC",
-		},
-	)
-	asset_category.insert()
-
-
 def set_depreciation_settings_in_company():
 	company = frappe.get_doc("Company", "_Test Company")
 	company.accumulated_depreciation_account = "_Test Accumulated Depreciations - _TC"
diff --git a/erpnext/assets/doctype/asset_maintenance/test_records.json b/erpnext/assets/doctype/asset_maintenance/test_records.json
new file mode 100644
index 0000000..8306fad
--- /dev/null
+++ b/erpnext/assets/doctype/asset_maintenance/test_records.json
@@ -0,0 +1,68 @@
+[
+  {
+     "doctype": "Asset Category",
+     "asset_category_name": "Equipment",
+     "total_number_of_depreciations": 3,
+     "frequency_of_depreciation": 3,
+     "accounts": [
+        {
+	  "company_name": "_Test Company",
+	  "fixed_asset_account": "_Test Fixed Asset - _TC",
+	  "accumulated_depreciation_account": "_Test Accumulated Depreciations - _TC",
+	  "depreciation_expense_account": "_Test Depreciations - _TC"
+	}
+     ]
+  },
+  {
+     "doctype": "Location",
+     "location_name": "Test Location"
+  },
+  {
+     "doctype": "Role",
+     "role_name": "Technician"
+  },
+  {
+    "doctype": "User",
+    "email": "marcus@abc.com",
+    "first_name": "marcus@abc.com",
+    "new_password": "password",
+    "roles": [{"doctype": "Has Role", "role": "Technician"}]
+  },
+  {
+    "doctype": "User",
+    "email": "thalia@abc.com",
+    "first_name": "thalia@abc.com",
+    "new_password": "password",
+    "roles": [{"doctype": "Has Role", "role": "Technician"}]
+  },
+  {
+    "doctype": "User",
+    "email": "mathias@abc.com",
+    "first_name": "mathias@abc.com",
+    "new_password": "password",
+    "roles": [{"doctype": "Has Role", "role": "Technician"}]
+  },
+  {
+    "doctype": "Asset Maintenance Team",
+    "maintenance_manager": "marcus@abc.com",
+    "maintenance_team_name": "Team Awesome",
+    "company": "_Test Company",
+    "maintenance_team_members": [
+      {"team_member": "marcus@abc.com", "full_name": "marcus@abc.com", "maintenance_role": "Technician"},
+      {"team_member": "thalia@abc.com", "full_name": "thalia@abc.com", "maintenance_role": "Technician"},
+      {"team_member": "mathias@abc.com", "full_name": "mathias@abc.com", "maintenance_role": "Technician"}
+    ]
+  },
+  {
+    "doctype": "Item",
+    "item_code": "Photocopier",
+    "item_name": "Photocopier",
+    "item_group": "All Item Groups",
+    "company": "_Test Company",
+    "is_fixed_asset": 1,
+    "is_stock_item": 0,
+    "asset_category": "Equipment",
+    "auto_create_assets": 1,
+    "asset_naming_series": "ABC.###"
+  }
+]
diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py
index 30c0371..65d2f8e 100644
--- a/erpnext/assets/doctype/asset_repair/asset_repair.py
+++ b/erpnext/assets/doctype/asset_repair/asset_repair.py
@@ -177,7 +177,7 @@
 					"item_code": stock_item.item_code,
 					"qty": stock_item.consumed_quantity,
 					"basic_rate": stock_item.valuation_rate,
-					"serial_no": stock_item.serial_and_batch_bundle,
+					"serial_and_batch_bundle": stock_item.serial_and_batch_bundle,
 					"cost_center": self.cost_center,
 					"project": self.project,
 				},
diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.json b/erpnext/buying/doctype/buying_settings/buying_settings.json
index 8c73e56..0599992 100644
--- a/erpnext/buying/doctype/buying_settings/buying_settings.json
+++ b/erpnext/buying/doctype/buying_settings/buying_settings.json
@@ -16,7 +16,7 @@
   "transaction_settings_section",
   "po_required",
   "pr_required",
-  "over_order_allowance",
+  "blanket_order_allowance",
   "column_break_12",
   "maintain_same_rate",
   "set_landed_cost_based_on_purchase_invoice_rate",
@@ -24,6 +24,7 @@
   "bill_for_rejected_quantity_in_purchase_invoice",
   "disable_last_purchase_rate",
   "show_pay_button",
+  "use_transaction_date_exchange_rate",
   "subcontract",
   "backflush_raw_materials_of_subcontract_based_on",
   "column_break_11",
@@ -160,10 +161,17 @@
   },
   {
    "default": "0",
-   "description": "Percentage you are allowed to order more against the Blanket Order Quantity. For example: If you have a Blanket Order of Quantity 100 units. and your Allowance is 10% then you are allowed to order 110 units.",
-   "fieldname": "over_order_allowance",
+   "description": "While making Purchase Invoice from Purchase Order, use Exchange Rate on Invoice's transaction date rather than inheriting it from Purchase Order. Only applies for Purchase Invoice.",
+   "fieldname": "use_transaction_date_exchange_rate",
+   "fieldtype": "Check",
+   "label": "Use Transaction Date Exchange Rate"
+  },
+  {
+   "default": "0",
+   "description": "Percentage you are allowed to order beyond the Blanket Order quantity.",
+   "fieldname": "blanket_order_allowance",
    "fieldtype": "Float",
-   "label": "Over Order Allowance (%)"
+   "label": "Blanket Order Allowance (%)"
   }
  ],
  "icon": "fa fa-cog",
@@ -171,7 +179,7 @@
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2023-03-02 17:02:14.404622",
+ "modified": "2023-10-25 14:03:32.520418",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Buying Settings",
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index 5b5cc2b..f74df66 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -477,6 +477,7 @@
    "depends_on": "eval:doc.is_subcontracted",
    "fieldname": "supplier_warehouse",
    "fieldtype": "Link",
+   "ignore_user_permissions": 1,
    "label": "Supplier Warehouse",
    "options": "Warehouse"
   },
@@ -1274,7 +1275,7 @@
  "idx": 105,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-09-13 16:21:07.361700",
+ "modified": "2023-10-01 20:58:07.851037",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order",
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 465fe96..961697c 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -556,6 +556,9 @@
 					"bom": "bom",
 					"material_request": "material_request",
 					"material_request_item": "material_request_item",
+					"sales_order": "sales_order",
+					"sales_order_item": "sales_order_item",
+					"wip_composite_asset": "wip_composite_asset",
 				},
 				"postprocess": update_item,
 				"condition": lambda doc: abs(doc.received_qty) < abs(doc.qty)
@@ -632,6 +635,7 @@
 			"field_map": {
 				"name": "po_detail",
 				"parent": "purchase_order",
+				"wip_composite_asset": "wip_composite_asset",
 			},
 			"postprocess": update_item,
 			"condition": lambda doc: (doc.base_amount == 0 or abs(doc.billed_amt) < abs(doc.amount)),
diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
index f79b622..b1da97d 100644
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
@@ -86,6 +86,8 @@
   "billed_amt",
   "accounting_details",
   "expense_account",
+  "column_break_fyqr",
+  "wip_composite_asset",
   "manufacture_details",
   "manufacturer",
   "manufacturer_part_no",
@@ -180,7 +182,6 @@
    "oldfieldname": "description",
    "oldfieldtype": "Small Text",
    "print_width": "300px",
-   "reqd": 1,
    "width": "300px"
   },
   {
@@ -897,13 +898,23 @@
    "fieldname": "apply_tds",
    "fieldtype": "Check",
    "label": "Apply TDS"
+  },
+  {
+   "fieldname": "wip_composite_asset",
+   "fieldtype": "Link",
+   "label": "WIP Composite Asset",
+   "options": "Asset"
+  },
+  {
+   "fieldname": "column_break_fyqr",
+   "fieldtype": "Column Break"
   }
  ],
  "idx": 1,
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-09-13 16:22:40.825092",
+ "modified": "2023-10-27 15:50:42.655573",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order Item",
diff --git a/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json b/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
index e07f462..82fcfa2 100644
--- a/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
+++ b/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
@@ -84,7 +84,6 @@
    "oldfieldname": "description",
    "oldfieldtype": "Small Text",
    "print_width": "300px",
-   "reqd": 1,
    "width": "300px"
   },
   {
@@ -270,4 +269,4 @@
  "sort_field": "modified",
  "sort_order": "DESC",
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js
index 08dc44c..70d2782 100644
--- a/erpnext/buying/doctype/supplier/supplier.js
+++ b/erpnext/buying/doctype/supplier/supplier.js
@@ -88,7 +88,7 @@
 			}, __("View"));
 
 			frm.add_custom_button(__('Accounts Payable'), function () {
-				frappe.set_route('query-report', 'Accounts Payable', { supplier: frm.doc.name });
+				frappe.set_route('query-report', 'Accounts Payable', { party_type: "Supplier", party: frm.doc.name });
 			}, __("View"));
 
 			frm.add_custom_button(__('Bank Account'), function () {
diff --git a/erpnext/buying/doctype/supplier/supplier.json b/erpnext/buying/doctype/supplier/supplier.json
index 19972ca..60dd54c 100644
--- a/erpnext/buying/doctype/supplier/supplier.json
+++ b/erpnext/buying/doctype/supplier/supplier.json
@@ -167,15 +167,14 @@
    "label": "Supplier Group",
    "oldfieldname": "supplier_type",
    "oldfieldtype": "Link",
-   "options": "Supplier Group",
-   "reqd": 1
+   "options": "Supplier Group"
   },
   {
    "default": "Company",
    "fieldname": "supplier_type",
    "fieldtype": "Select",
    "label": "Supplier Type",
-   "options": "Company\nIndividual",
+   "options": "Company\nIndividual\nProprietorship\nPartnership",
    "reqd": 1
   },
   {
@@ -486,7 +485,7 @@
    "link_fieldname": "party"
   }
  ],
- "modified": "2023-09-21 12:24:20.398889",
+ "modified": "2023-10-19 16:55:15.148325",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Supplier",
diff --git a/erpnext/buying/doctype/supplier/supplier_dashboard.py b/erpnext/buying/doctype/supplier/supplier_dashboard.py
index 11bb06e..3bd306e 100644
--- a/erpnext/buying/doctype/supplier/supplier_dashboard.py
+++ b/erpnext/buying/doctype/supplier/supplier_dashboard.py
@@ -8,7 +8,7 @@
 			"This is based on transactions against this Supplier. See timeline below for details"
 		),
 		"fieldname": "supplier",
-		"non_standard_fieldnames": {"Payment Entry": "party_name", "Bank Account": "party"},
+		"non_standard_fieldnames": {"Payment Entry": "party", "Bank Account": "party"},
 		"transactions": [
 			{"label": _("Procurement"), "items": ["Request for Quotation", "Supplier Quotation"]},
 			{"label": _("Orders"), "items": ["Purchase Order", "Purchase Receipt", "Purchase Invoice"]},
diff --git a/erpnext/buying/doctype/supplier/test_supplier.py b/erpnext/buying/doctype/supplier/test_supplier.py
index ee2ada3..350a25f 100644
--- a/erpnext/buying/doctype/supplier/test_supplier.py
+++ b/erpnext/buying/doctype/supplier/test_supplier.py
@@ -207,11 +207,14 @@
 			"doctype": "Supplier",
 			"supplier_name": args.supplier_name,
 			"default_currency": args.default_currency,
-			"supplier_group": args.supplier_group or "Services",
 			"supplier_type": args.supplier_type or "Company",
 			"tax_withholding_category": args.tax_withholding_category,
 		}
-	).insert()
+	)
+	if not args.without_supplier_group:
+		doc.supplier_group = args.supplier_group or "Services"
+
+	doc.insert()
 
 	return doc
 
diff --git a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
index 638cde0..8d491fb 100644
--- a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
+++ b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
@@ -126,7 +126,6 @@
    "oldfieldname": "description",
    "oldfieldtype": "Small Text",
    "print_width": "300px",
-   "reqd": 1,
    "width": "300px"
   },
   {
@@ -569,4 +568,4 @@
  "sort_field": "modified",
  "sort_order": "DESC",
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py
index 6e22acf..683a12a 100644
--- a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py
+++ b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py
@@ -334,6 +334,11 @@
 			"variable_label": "Total Ordered",
 			"path": "get_ordered_qty",
 		},
+		{
+			"param_name": "total_invoiced",
+			"variable_label": "Total Invoiced",
+			"path": "get_invoiced_qty",
+		},
 	]
 	install_standing_docs = [
 		{
diff --git a/erpnext/buying/doctype/supplier_scorecard_variable/supplier_scorecard_variable.py b/erpnext/buying/doctype/supplier_scorecard_variable/supplier_scorecard_variable.py
index 4080d1f..6c91a04 100644
--- a/erpnext/buying/doctype/supplier_scorecard_variable/supplier_scorecard_variable.py
+++ b/erpnext/buying/doctype/supplier_scorecard_variable/supplier_scorecard_variable.py
@@ -440,6 +440,23 @@
 	).run(as_list=True)[0][0] or 0
 
 
+def get_invoiced_qty(scorecard):
+	"""Returns the total number of invoiced quantity (based on Purchase Invoice)"""
+
+	pi = frappe.qb.DocType("Purchase Invoice")
+
+	return (
+		frappe.qb.from_(pi)
+		.select(Sum(pi.total_qty))
+		.where(
+			(pi.supplier == scorecard.supplier)
+			& (pi.docstatus == 1)
+			& (pi.posting_date >= scorecard.get("start_date"))
+			& (pi.posting_date <= scorecard.get("end_date"))
+		)
+	).run(as_list=True)[0][0] or 0
+
+
 def get_rfq_total_number(scorecard):
 	"""Gets the total number of RFQs sent to supplier"""
 	supplier = frappe.get_doc("Supplier", scorecard.supplier)
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 e10c0e2..b6e4630 100644
--- a/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py
+++ b/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py
@@ -6,7 +6,7 @@
 
 import frappe
 from frappe import _
-from frappe.query_builder.functions import IfNull
+from frappe.query_builder.functions import IfNull, Sum
 from frappe.utils import date_diff, flt, getdate
 
 
@@ -57,7 +57,7 @@
 			po_item.qty,
 			po_item.received_qty,
 			(po_item.qty - po_item.received_qty).as_("pending_qty"),
-			IfNull(pi_item.qty, 0).as_("billed_qty"),
+			Sum(IfNull(pi_item.qty, 0)).as_("billed_qty"),
 			po_item.base_amount.as_("amount"),
 			(po_item.received_qty * po_item.base_rate).as_("received_qty_amount"),
 			(po_item.billed_amt * IfNull(po.conversion_rate, 1)).as_("billed_amount"),
diff --git a/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.js b/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.js
index fd73b87..579c0a6 100644
--- a/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.js
+++ b/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.js
@@ -44,11 +44,6 @@
 						}
 					}
 				}
-				else {
-					return {
-						filters: { "disabled": 0 }
-					}
-				}
 			}
 		},
 		{
diff --git a/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py b/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py
index a728290..01ff28d 100644
--- a/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py
+++ b/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py
@@ -35,8 +35,12 @@
 			sq_item.parent,
 			sq_item.item_code,
 			sq_item.qty,
+			sq.currency,
 			sq_item.stock_qty,
 			sq_item.amount,
+			sq_item.base_rate,
+			sq_item.base_amount,
+			sq.price_list_currency,
 			sq_item.uom,
 			sq_item.stock_uom,
 			sq_item.request_for_quotation,
@@ -105,7 +109,11 @@
 			"qty": data.get("qty"),
 			"price": flt(data.get("amount") * exchange_rate, float_precision),
 			"uom": data.get("uom"),
+			"price_list_currency": data.get("price_list_currency"),
+			"currency": data.get("currency"),
 			"stock_uom": data.get("stock_uom"),
+			"base_amount": flt(data.get("base_amount"), float_precision),
+			"base_rate": flt(data.get("base_rate"), float_precision),
 			"request_for_quotation": data.get("request_for_quotation"),
 			"valid_till": data.get("valid_till"),
 			"lead_time_days": data.get("lead_time_days"),
@@ -183,6 +191,8 @@
 
 
 def get_columns(filters):
+	currency = frappe.get_cached_value("Company", filters.get("company"), "default_currency")
+
 	group_by_columns = [
 		{
 			"fieldname": "supplier_name",
@@ -204,10 +214,17 @@
 		{"fieldname": "uom", "label": _("UOM"), "fieldtype": "Link", "options": "UOM", "width": 90},
 		{"fieldname": "qty", "label": _("Quantity"), "fieldtype": "Float", "width": 80},
 		{
+			"fieldname": "currency",
+			"label": _("Currency"),
+			"fieldtype": "Link",
+			"options": "Currency",
+			"width": 110,
+		},
+		{
 			"fieldname": "price",
 			"label": _("Price"),
 			"fieldtype": "Currency",
-			"options": "Company:company:default_currency",
+			"options": "currency",
 			"width": 110,
 		},
 		{
@@ -221,10 +238,24 @@
 			"fieldname": "price_per_unit",
 			"label": _("Price per Unit (Stock UOM)"),
 			"fieldtype": "Currency",
-			"options": "Company:company:default_currency",
+			"options": "currency",
 			"width": 120,
 		},
 		{
+			"fieldname": "base_amount",
+			"label": _("Price ({0})").format(currency),
+			"fieldtype": "Currency",
+			"options": "price_list_currency",
+			"width": 180,
+		},
+		{
+			"fieldname": "base_rate",
+			"label": _("Price Per Unit ({0})").format(currency),
+			"fieldtype": "Currency",
+			"options": "price_list_currency",
+			"width": 180,
+		},
+		{
 			"fieldname": "quotation",
 			"label": _("Supplier Quotation"),
 			"fieldtype": "Link",
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index d77b8a3..e984730 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -13,6 +13,7 @@
 	add_days,
 	add_months,
 	cint,
+	comma_and,
 	flt,
 	fmt_money,
 	formatdate,
@@ -181,6 +182,17 @@
 		self.validate_party_account_currency()
 
 		if self.doctype in ["Purchase Invoice", "Sales Invoice"]:
+			if invalid_advances := [
+				x for x in self.advances if not x.reference_type or not x.reference_name
+			]:
+				frappe.throw(
+					_(
+						"Rows: {0} in {1} section are Invalid. Reference Name should point to a valid Payment Entry or Journal Entry."
+					).format(
+						frappe.bold(comma_and([x.idx for x in invalid_advances])), frappe.bold(_("Advance Payments"))
+					)
+				)
+
 			pos_check_field = "is_pos" if self.doctype == "Sales Invoice" else "is_paid"
 			if cint(self.allocate_advances_automatically) and not cint(self.get(pos_check_field)):
 				self.set_advances()
@@ -243,13 +255,38 @@
 				_doc.cancel()
 			_doc.delete()
 
-	def on_trash(self):
-		# delete references in 'Repost Payment Ledger'
-		rpi = frappe.qb.DocType("Repost Payment Ledger Items")
-		frappe.qb.from_(rpi).delete().where(
-			(rpi.voucher_type == self.doctype) & (rpi.voucher_no == self.name)
-		).run()
+	def _remove_references_in_repost_doctypes(self):
+		repost_doctypes = ["Repost Payment Ledger Items", "Repost Accounting Ledger Items"]
 
+		for _doctype in repost_doctypes:
+			dt = frappe.qb.DocType(_doctype)
+			rows = (
+				frappe.qb.from_(dt)
+				.select(dt.name, dt.parent, dt.parenttype)
+				.where((dt.voucher_type == self.doctype) & (dt.voucher_no == self.name))
+				.run(as_dict=True)
+			)
+
+			if rows:
+				references_map = frappe._dict()
+				for x in rows:
+					references_map.setdefault((x.parenttype, x.parent), []).append(x.name)
+
+				for doc, rows in references_map.items():
+					repost_doc = frappe.get_doc(doc[0], doc[1])
+
+					for row in rows:
+						if _doctype == "Repost Payment Ledger Items":
+							repost_doc.remove(repost_doc.get("repost_vouchers", {"name": row})[0])
+						else:
+							repost_doc.remove(repost_doc.get("vouchers", {"name": row})[0])
+
+					repost_doc.flags.ignore_validate_update_after_submit = True
+					repost_doc.flags.ignore_links = True
+					repost_doc.save(ignore_permissions=True)
+
+	def on_trash(self):
+		self._remove_references_in_repost_doctypes()
 		self._remove_references_in_unreconcile()
 
 		# delete sl and gl entries on deletion of transaction
@@ -547,6 +584,17 @@
 					self.currency, self.company_currency, transaction_date, args
 				)
 
+			if (
+				self.currency
+				and buying_or_selling == "Buying"
+				and frappe.db.get_single_value("Buying Settings", "use_transaction_date_exchange_rate")
+				and self.doctype == "Purchase Invoice"
+			):
+				self.use_transaction_date_exchange_rate = True
+				self.conversion_rate = get_exchange_rate(
+					self.currency, self.company_currency, transaction_date, args
+				)
+
 	def set_missing_item_details(self, for_validate=False):
 		"""set missing item values"""
 		from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
@@ -1132,7 +1180,9 @@
 								self.name,
 								arg.get("referenced_row"),
 							):
-								posting_date = frappe.db.get_value(arg.voucher_type, arg.voucher_no, "posting_date")
+								posting_date = arg.get("difference_posting_date") or frappe.db.get_value(
+									arg.voucher_type, arg.voucher_no, "posting_date"
+								)
 								je = create_gain_loss_journal(
 									self.company,
 									posting_date,
@@ -1215,7 +1265,7 @@
 
 						je = create_gain_loss_journal(
 							self.company,
-							self.posting_date,
+							args.get("difference_posting_date") if args else self.posting_date,
 							self.party_type,
 							self.party,
 							party_account,
@@ -1473,7 +1523,7 @@
 						"against_type": against_type,
 						"against": supplier_or_customer,
 						dr_or_cr: self.base_discount_amount,
-						"cost_center": self.cost_center,
+						"cost_center": self.cost_center or erpnext.get_default_cost_center(self.company),
 					},
 					item=self,
 				)
@@ -2193,6 +2243,46 @@
 				_("Select finance book for the item {0} at row {1}").format(item.item_code, item.idx)
 			)
 
+	def check_if_fields_updated(self, fields_to_check, child_tables):
+		# Check if any field affecting accounting entry is altered
+		doc_before_update = self.get_doc_before_save()
+		accounting_dimensions = get_accounting_dimensions() + ["cost_center", "project"]
+
+		# Check if opening entry check updated
+		needs_repost = doc_before_update.get("is_opening") != self.is_opening
+
+		if not needs_repost:
+			# Parent Level Accounts excluding party account
+			fields_to_check += accounting_dimensions
+			for field in fields_to_check:
+				if doc_before_update.get(field) != self.get(field):
+					needs_repost = 1
+					break
+
+			if not needs_repost:
+				# Check for child tables
+				for table in child_tables:
+					needs_repost = check_if_child_table_updated(
+						doc_before_update.get(table), self.get(table), child_tables[table]
+					)
+					if needs_repost:
+						break
+
+		return needs_repost
+
+	@frappe.whitelist()
+	def repost_accounting_entries(self):
+		if self.repost_required:
+			repost_ledger = frappe.new_doc("Repost Accounting Ledger")
+			repost_ledger.company = self.company
+			repost_ledger.append("vouchers", {"voucher_type": self.doctype, "voucher_no": self.name})
+			repost_ledger.flags.ignore_permissions = True
+			repost_ledger.insert()
+			repost_ledger.submit()
+			self.db_set("repost_required", 0)
+		else:
+			frappe.throw(_("No updates pending for reposting"))
+
 
 @frappe.whitelist()
 def get_tax_rate(account_head):
@@ -3198,6 +3288,23 @@
 				parent.create_stock_reservation_entries()
 
 
+def check_if_child_table_updated(
+	child_table_before_update, child_table_after_update, fields_to_check
+):
+	accounting_dimensions = get_accounting_dimensions() + ["cost_center", "project"]
+	# Check if any field affecting accounting entry is altered
+	for index, item in enumerate(child_table_after_update):
+		for field in fields_to_check:
+			if child_table_before_update[index].get(field) != item.get(field):
+				return True
+
+		for dimension in accounting_dimensions:
+			if child_table_before_update[index].get(dimension) != item.get(dimension):
+				return True
+
+	return False
+
+
 @erpnext.allow_regional
 def validate_regional(doc):
 	pass
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index a76abe2..3a802bd 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -4,7 +4,7 @@
 
 import frappe
 from frappe import ValidationError, _, msgprint
-from frappe.contacts.doctype.address.address import get_address_display
+from frappe.contacts.doctype.address.address import render_address
 from frappe.utils import cint, flt, getdate
 from frappe.utils.data import nowtime
 
@@ -246,7 +246,9 @@
 
 		for address_field, address_display_field in address_dict.items():
 			if self.get(address_field):
-				self.set(address_display_field, get_address_display(self.get(address_field)))
+				self.set(
+					address_display_field, render_address(self.get(address_field), check_permissions=False)
+				)
 
 	def set_total_in_words(self):
 		from frappe.utils import money_in_words
diff --git a/erpnext/controllers/item_variant.py b/erpnext/controllers/item_variant.py
index e68ee90..c8785a5 100644
--- a/erpnext/controllers/item_variant.py
+++ b/erpnext/controllers/item_variant.py
@@ -9,6 +9,8 @@
 from frappe import _
 from frappe.utils import cstr, flt
 
+from erpnext.utilities.product import get_item_codes_by_attributes
+
 
 class ItemVariantExistsError(frappe.ValidationError):
 	pass
@@ -24,7 +26,8 @@
 
 @frappe.whitelist()
 def get_variant(template, args=None, variant=None, manufacturer=None, manufacturer_part_no=None):
-	"""Validates Attributes and their Values, then looks for an exactly
+	"""
+	Validates Attributes and their Values, then looks for an exactly
 	matching Item Variant
 
 	:param item: Template Item
@@ -34,13 +37,14 @@
 
 	if item_template.variant_based_on == "Manufacturer" and manufacturer:
 		return make_variant_based_on_manufacturer(item_template, manufacturer, manufacturer_part_no)
-	else:
-		if isinstance(args, str):
-			args = json.loads(args)
 
-		if not args:
-			frappe.throw(_("Please specify at least one attribute in the Attributes table"))
-		return find_variant(template, args, variant)
+	if isinstance(args, str):
+		args = json.loads(args)
+
+	if not args:
+		frappe.throw(_("Please specify at least one attribute in the Attributes table"))
+
+	return find_variant(template, args, variant)
 
 
 def make_variant_based_on_manufacturer(template, manufacturer, manufacturer_part_no):
@@ -157,17 +161,6 @@
 
 
 def find_variant(template, args, variant_item_code=None):
-	conditions = [
-		"""(iv_attribute.attribute={0} and iv_attribute.attribute_value={1})""".format(
-			frappe.db.escape(key), frappe.db.escape(cstr(value))
-		)
-		for key, value in args.items()
-	]
-
-	conditions = " or ".join(conditions)
-
-	from erpnext.e_commerce.variant_selector.utils import get_item_codes_by_attributes
-
 	possible_variants = [
 		i for i in get_item_codes_by_attributes(args, template) if i != variant_item_code
 	]
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 9014662..d34fbeb 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -4,9 +4,9 @@
 
 import frappe
 from frappe import _, bold, throw
-from frappe.contacts.doctype.address.address import get_address_display
 from frappe.utils import cint, flt, get_link_to_form, nowtime
 
+from erpnext.accounts.party import render_address
 from erpnext.controllers.accounts_controller import get_taxes_and_charges
 from erpnext.controllers.sales_and_purchase_return import get_rate_for_return
 from erpnext.controllers.stock_controller import StockController
@@ -288,7 +288,9 @@
 			last_valuation_rate_in_sales_uom = last_valuation_rate * (item.conversion_factor or 1)
 
 			if flt(item.base_net_rate) < flt(last_valuation_rate_in_sales_uom):
-				throw_message(item.idx, item.item_name, last_valuation_rate_in_sales_uom, "valuation rate")
+				throw_message(
+					item.idx, item.item_name, last_valuation_rate_in_sales_uom, "valuation rate (Moving Average)"
+				)
 
 	def get_item_list(self):
 		il = []
@@ -600,7 +602,9 @@
 
 		for address_field, address_display_field in address_dict.items():
 			if self.get(address_field):
-				self.set(address_display_field, get_address_display(self.get(address_field)))
+				self.set(
+					address_display_field, render_address(self.get(address_field), check_permissions=False)
+				)
 
 	def validate_for_duplicate_items(self):
 		check_list, chk_dupl_itm = [], []
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index 73a248f..d09001c 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -47,15 +47,15 @@
 		],
 		[
 			"To Bill",
-			"eval:(self.per_delivered == 100 or self.skip_delivery_note) and self.per_billed < 100 and self.docstatus == 1",
+			"eval:(self.per_delivered >= 100 or self.skip_delivery_note) and self.per_billed < 100 and self.docstatus == 1",
 		],
 		[
 			"To Deliver",
-			"eval:self.per_delivered < 100 and self.per_billed == 100 and self.docstatus == 1 and not self.skip_delivery_note",
+			"eval:self.per_delivered < 100 and self.per_billed >= 100 and self.docstatus == 1 and not self.skip_delivery_note",
 		],
 		[
 			"Completed",
-			"eval:(self.per_delivered == 100 or self.skip_delivery_note) and self.per_billed == 100 and self.docstatus == 1",
+			"eval:(self.per_delivered >= 100 or self.skip_delivery_note) and self.per_billed >= 100 and self.docstatus == 1",
 		],
 		["Cancelled", "eval:self.docstatus==2"],
 		["Closed", "eval:self.status=='Closed' and self.docstatus != 2"],
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index d816780..335f2b0 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -62,9 +62,12 @@
 			)
 		)
 
+		is_asset_pr = any(d.get("is_fixed_asset") for d in self.get("items"))
+
 		if (
 			cint(erpnext.is_perpetual_inventory_enabled(self.company))
 			or provisional_accounting_for_non_stock_items
+			or is_asset_pr
 		):
 			warehouse_account = get_warehouse_account_map(self.company)
 
@@ -73,11 +76,6 @@
 					gl_entries = self.get_gl_entries(warehouse_account)
 				make_gl_entries(gl_entries, from_repost=from_repost)
 
-		elif self.doctype in ["Purchase Receipt", "Purchase Invoice"] and self.docstatus == 1:
-			gl_entries = []
-			gl_entries = self.get_asset_gl_entry(gl_entries)
-			make_gl_entries(gl_entries, from_repost=from_repost)
-
 	def validate_serialized_batch(self):
 		from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
 
@@ -696,13 +694,21 @@
 				d.stock_uom_rate = d.rate / (d.conversion_factor or 1)
 
 	def validate_internal_transfer(self):
-		if (
-			self.doctype in ("Sales Invoice", "Delivery Note", "Purchase Invoice", "Purchase Receipt")
-			and self.is_internal_transfer()
-		):
-			self.validate_in_transit_warehouses()
-			self.validate_multi_currency()
-			self.validate_packed_items()
+		if self.doctype in ("Sales Invoice", "Delivery Note", "Purchase Invoice", "Purchase Receipt"):
+			if self.is_internal_transfer():
+				self.validate_in_transit_warehouses()
+				self.validate_multi_currency()
+				self.validate_packed_items()
+			else:
+				self.validate_internal_transfer_warehouse()
+
+	def validate_internal_transfer_warehouse(self):
+		for row in self.items:
+			if row.get("target_warehouse"):
+				row.target_warehouse = None
+
+			if row.get("from_warehouse"):
+				row.from_warehouse = None
 
 	def validate_in_transit_warehouses(self):
 		if (
@@ -861,8 +867,9 @@
 
 @frappe.whitelist()
 def show_accounting_ledger_preview(company, doctype, docname):
-	filters = {"company": company, "include_dimensions": 1}
+	filters = frappe._dict(company=company, include_dimensions=1)
 	doc = frappe.get_doc(doctype, docname)
+	doc.run_method("before_gl_preview")
 
 	gl_columns, gl_data = get_accounting_ledger_preview(doc, filters)
 
@@ -873,8 +880,9 @@
 
 @frappe.whitelist()
 def show_stock_ledger_preview(company, doctype, docname):
-	filters = {"company": company}
+	filters = frappe._dict(company=company)
 	doc = frappe.get_doc(doctype, docname)
+	doc.run_method("before_sl_preview")
 
 	sl_columns, sl_data = get_stock_ledger_preview(doc, filters)
 
@@ -1208,8 +1216,6 @@
 
 		repost_entry = frappe.new_doc("Repost Item Valuation")
 		repost_entry.based_on = "Item and Warehouse"
-		repost_entry.voucher_type = voucher_type
-		repost_entry.voucher_no = voucher_no
 
 		repost_entry.item_code = sle.item_code
 		repost_entry.warehouse = sle.warehouse
diff --git a/erpnext/controllers/subcontracting_controller.py b/erpnext/controllers/subcontracting_controller.py
index d4270a7..5fa66b1 100644
--- a/erpnext/controllers/subcontracting_controller.py
+++ b/erpnext/controllers/subcontracting_controller.py
@@ -804,7 +804,7 @@
 						{
 							"item_code": item.rm_item_code,
 							"warehouse": self.supplier_warehouse,
-							"actual_qty": -1 * flt(item.consumed_qty),
+							"actual_qty": -1 * flt(item.consumed_qty, item.precision("consumed_qty")),
 							"dependant_sle_voucher_detail_no": item.reference_name,
 						},
 					)
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 62d4c53..96284d6 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -25,6 +25,9 @@
 	def __init__(self, doc: Document):
 		self.doc = doc
 		frappe.flags.round_off_applicable_accounts = []
+		frappe.flags.round_row_wise_tax = frappe.db.get_single_value(
+			"Accounts Settings", "round_row_wise_tax"
+		)
 
 		self._items = self.filter_rows() if self.doc.doctype == "Quotation" else self.doc.get("items")
 
@@ -190,7 +193,9 @@
 
 				item.net_rate = item.rate
 
-				if not item.qty and self.doc.get("is_return"):
+				if (
+					not item.qty and self.doc.get("is_return") and self.doc.get("doctype") != "Purchase Receipt"
+				):
 					item.amount = flt(-1 * item.rate, item.precision("amount"))
 				elif not item.qty and self.doc.get("is_debit_note"):
 					item.amount = flt(item.rate, item.precision("amount"))
@@ -368,6 +373,8 @@
 			for i, tax in enumerate(self.doc.get("taxes")):
 				# tax_amount represents the amount of tax for the current step
 				current_tax_amount = self.get_current_tax_amount(item, tax, item_tax_map)
+				if frappe.flags.round_row_wise_tax:
+					current_tax_amount = flt(current_tax_amount, tax.precision("tax_amount"))
 
 				# Adjust divisional loss to the last item
 				if tax.charge_type == "Actual":
@@ -478,10 +485,19 @@
 		# store tax breakup for each item
 		key = item.item_code or item.item_name
 		item_wise_tax_amount = current_tax_amount * self.doc.conversion_rate
-		if tax.item_wise_tax_detail.get(key):
-			item_wise_tax_amount += tax.item_wise_tax_detail[key][1]
+		if frappe.flags.round_row_wise_tax:
+			item_wise_tax_amount = flt(item_wise_tax_amount, tax.precision("tax_amount"))
+			if tax.item_wise_tax_detail.get(key):
+				item_wise_tax_amount += flt(tax.item_wise_tax_detail[key][1], tax.precision("tax_amount"))
+			tax.item_wise_tax_detail[key] = [
+				tax_rate,
+				flt(item_wise_tax_amount, tax.precision("tax_amount")),
+			]
+		else:
+			if tax.item_wise_tax_detail.get(key):
+				item_wise_tax_amount += tax.item_wise_tax_detail[key][1]
 
-		tax.item_wise_tax_detail[key] = [tax_rate, flt(item_wise_tax_amount)]
+			tax.item_wise_tax_detail[key] = [tax_rate, flt(item_wise_tax_amount)]
 
 	def round_off_totals(self, tax):
 		if tax.account_head in frappe.flags.round_off_applicable_accounts:
diff --git a/erpnext/controllers/tests/test_accounts_controller.py b/erpnext/controllers/tests/test_accounts_controller.py
index 391258f..97d3c5c 100644
--- a/erpnext/controllers/tests/test_accounts_controller.py
+++ b/erpnext/controllers/tests/test_accounts_controller.py
@@ -7,7 +7,7 @@
 from frappe import qb
 from frappe.query_builder.functions import Sum
 from frappe.tests.utils import FrappeTestCase, change_settings
-from frappe.utils import add_days, flt, nowdate
+from frappe.utils import add_days, flt, getdate, nowdate
 
 from erpnext import get_default_cost_center
 from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
@@ -614,6 +614,73 @@
 		self.assertEqual(exc_je_for_si, [])
 		self.assertEqual(exc_je_for_pe, [])
 
+	def test_15_gain_loss_on_different_posting_date(self):
+		# Invoice in Foreign Currency
+		si = self.create_sales_invoice(
+			posting_date=add_days(nowdate(), -2), qty=2, conversion_rate=80, rate=1
+		)
+		# Payment
+		pe = (
+			self.create_payment_entry(posting_date=add_days(nowdate(), -1), amount=2, source_exc_rate=75)
+			.save()
+			.submit()
+		)
+
+		# There should be outstanding in both currencies
+		si.reload()
+		self.assertEqual(si.outstanding_amount, 2)
+		self.assert_ledger_outstanding(si.doctype, si.name, 160.0, 2.0)
+
+		# Reconcile the remaining amount
+		pr = frappe.get_doc("Payment Reconciliation")
+		pr.company = self.company
+		pr.party_type = "Customer"
+		pr.party = self.customer
+		pr.receivable_payable_account = self.debit_usd
+		pr.get_unreconciled_entries()
+		self.assertEqual(len(pr.invoices), 1)
+		self.assertEqual(len(pr.payments), 1)
+		invoices = [x.as_dict() for x in pr.invoices]
+		payments = [x.as_dict() for x in pr.payments]
+		pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
+		pr.allocation[0].gain_loss_posting_date = add_days(nowdate(), 1)
+		pr.reconcile()
+
+		# Exchange Gain/Loss Journal should've been created.
+		exc_je_for_si = self.get_journals_for(si.doctype, si.name)
+		exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
+		self.assertNotEqual(exc_je_for_si, [])
+		self.assertEqual(len(exc_je_for_si), 1)
+		self.assertEqual(len(exc_je_for_pe), 1)
+		self.assertEqual(exc_je_for_si[0], exc_je_for_pe[0])
+
+		self.assertEqual(
+			frappe.db.get_value("Journal Entry", exc_je_for_si[0].parent, "posting_date"),
+			getdate(add_days(nowdate(), 1)),
+		)
+
+		self.assertEqual(len(pr.invoices), 0)
+		self.assertEqual(len(pr.payments), 0)
+
+		# There should be no outstanding
+		si.reload()
+		self.assertEqual(si.outstanding_amount, 0)
+		self.assert_ledger_outstanding(si.doctype, si.name, 0.0, 0.0)
+
+		# Cancel Payment
+		pe.reload()
+		pe.cancel()
+
+		si.reload()
+		self.assertEqual(si.outstanding_amount, 2)
+		self.assert_ledger_outstanding(si.doctype, si.name, 160.0, 2.0)
+
+		# Exchange Gain/Loss Journal should've been cancelled
+		exc_je_for_si = self.get_journals_for(si.doctype, si.name)
+		exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
+		self.assertEqual(exc_je_for_si, [])
+		self.assertEqual(exc_je_for_pe, [])
+
 	def test_20_journal_against_sales_invoice(self):
 		# Invoice in Foreign Currency
 		si = self.create_sales_invoice(qty=1, conversion_rate=80, rate=1)
diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py
index 105c58d..e897ba4 100644
--- a/erpnext/crm/doctype/lead/lead.py
+++ b/erpnext/crm/doctype/lead/lead.py
@@ -379,7 +379,7 @@
 		}
 	)
 
-	set_address_details(out, lead, "Lead")
+	set_address_details(out, lead, "Lead", company=company)
 
 	taxes_and_charges = set_taxes(
 		None,
diff --git a/erpnext/crm/report/lead_details/lead_details.py b/erpnext/crm/report/lead_details/lead_details.py
index 7b8c43b..98dfbec 100644
--- a/erpnext/crm/report/lead_details/lead_details.py
+++ b/erpnext/crm/report/lead_details/lead_details.py
@@ -4,6 +4,7 @@
 
 import frappe
 from frappe import _
+from frappe.query_builder.functions import Concat_ws, Date
 
 
 def execute(filters=None):
@@ -69,53 +70,41 @@
 
 
 def get_data(filters):
-	return frappe.db.sql(
-		"""
-		SELECT
-			`tabLead`.name,
-			`tabLead`.lead_name,
-			`tabLead`.status,
-			`tabLead`.lead_owner,
-			`tabLead`.territory,
-			`tabLead`.source,
-			`tabLead`.email_id,
-			`tabLead`.mobile_no,
-			`tabLead`.phone,
-			`tabLead`.owner,
-			`tabLead`.company,
-			concat_ws(', ',
-				trim(',' from `tabAddress`.address_line1),
-				trim(',' from tabAddress.address_line2)
-			) AS address,
-			`tabAddress`.state,
-			`tabAddress`.pincode,
-			`tabAddress`.country
-		FROM
-			`tabLead` left join `tabDynamic Link` on (
-			`tabLead`.name = `tabDynamic Link`.link_name and
-			`tabDynamic Link`.parenttype = 'Address')
-			left join `tabAddress` on (
-			`tabAddress`.name=`tabDynamic Link`.parent)
-		WHERE
-			company = %(company)s
-			AND DATE(`tabLead`.creation) BETWEEN %(from_date)s AND %(to_date)s
-			{conditions}
-		ORDER BY
-			`tabLead`.creation asc """.format(
-			conditions=get_conditions(filters)
-		),
-		filters,
-		as_dict=1,
+	lead = frappe.qb.DocType("Lead")
+	address = frappe.qb.DocType("Address")
+	dynamic_link = frappe.qb.DocType("Dynamic Link")
+
+	query = (
+		frappe.qb.from_(lead)
+		.left_join(dynamic_link)
+		.on((lead.name == dynamic_link.link_name) & (dynamic_link.parenttype == "Address"))
+		.left_join(address)
+		.on(address.name == dynamic_link.parent)
+		.select(
+			lead.name,
+			lead.lead_name,
+			lead.status,
+			lead.lead_owner,
+			lead.territory,
+			lead.source,
+			lead.email_id,
+			lead.mobile_no,
+			lead.phone,
+			lead.owner,
+			lead.company,
+			(Concat_ws(", ", address.address_line1, address.address_line2)).as_("address"),
+			address.state,
+			address.pincode,
+			address.country,
+		)
+		.where(lead.company == filters.company)
+		.where(Date(lead.creation).between(filters.from_date, filters.to_date))
 	)
 
-
-def get_conditions(filters):
-	conditions = []
-
 	if filters.get("territory"):
-		conditions.append(" and `tabLead`.territory=%(territory)s")
+		query = query.where(lead.territory == filters.get("territory"))
 
 	if filters.get("status"):
-		conditions.append(" and `tabLead`.status=%(status)s")
+		query = query.where(lead.status == filters.get("status"))
 
-	return " ".join(conditions) if conditions else ""
+	return query.run(as_dict=1)
diff --git a/erpnext/e_commerce/__init__.py b/erpnext/e_commerce/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/api.py b/erpnext/e_commerce/api.py
deleted file mode 100644
index bfada0f..0000000
--- a/erpnext/e_commerce/api.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-import json
-
-import frappe
-from frappe.utils import cint
-
-from erpnext.e_commerce.product_data_engine.filters import ProductFiltersBuilder
-from erpnext.e_commerce.product_data_engine.query import ProductQuery
-from erpnext.setup.doctype.item_group.item_group import get_child_groups_for_website
-
-
-@frappe.whitelist(allow_guest=True)
-def get_product_filter_data(query_args=None):
-	"""
-	Returns filtered products and discount filters.
-	:param query_args (dict): contains filters to get products list
-
-	Query Args filters:
-	search (str): Search Term.
-	field_filters (dict): Keys include item_group, brand, etc.
-	attribute_filters(dict): Keys include Color, Size, etc.
-	start (int): Offset items by
-	item_group (str): Valid Item Group
-	from_filters (bool): Set as True to jump to page 1
-	"""
-	if isinstance(query_args, str):
-		query_args = json.loads(query_args)
-
-	query_args = frappe._dict(query_args)
-	if query_args:
-		search = query_args.get("search")
-		field_filters = query_args.get("field_filters", {})
-		attribute_filters = query_args.get("attribute_filters", {})
-		start = cint(query_args.start) if query_args.get("start") else 0
-		item_group = query_args.get("item_group")
-		from_filters = query_args.get("from_filters")
-	else:
-		search, attribute_filters, item_group, from_filters = None, None, None, None
-		field_filters = {}
-		start = 0
-
-	# if new filter is checked, reset start to show filtered items from page 1
-	if from_filters:
-		start = 0
-
-	sub_categories = []
-	if item_group:
-		sub_categories = get_child_groups_for_website(item_group, immediate=True)
-
-	engine = ProductQuery()
-	try:
-		result = engine.query(
-			attribute_filters, field_filters, search_term=search, start=start, item_group=item_group
-		)
-	except Exception:
-		frappe.log_error("Product query with filter failed")
-		return {"exc": "Something went wrong!"}
-
-	# discount filter data
-	filters = {}
-	discounts = result["discounts"]
-
-	if discounts:
-		filter_engine = ProductFiltersBuilder()
-		filters["discount_filters"] = filter_engine.get_discount_filters(discounts)
-
-	return {
-		"items": result["items"] or [],
-		"filters": filters,
-		"settings": engine.settings,
-		"sub_categories": sub_categories,
-		"items_count": result["items_count"],
-	}
-
-
-@frappe.whitelist(allow_guest=True)
-def get_guest_redirect_on_action():
-	return frappe.db.get_single_value("E Commerce Settings", "redirect_on_action")
diff --git a/erpnext/e_commerce/doctype/__init__.py b/erpnext/e_commerce/doctype/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/doctype/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/doctype/e_commerce_settings/__init__.py b/erpnext/e_commerce/doctype/e_commerce_settings/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/doctype/e_commerce_settings/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.js b/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.js
deleted file mode 100644
index c37fa2f..0000000
--- a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on("E Commerce Settings", {
-	onload: function(frm) {
-		if(frm.doc.__onload && frm.doc.__onload.quotation_series) {
-			frm.fields_dict.quotation_series.df.options = frm.doc.__onload.quotation_series;
-			frm.refresh_field("quotation_series");
-		}
-
-		frm.set_query('payment_gateway_account', function() {
-			return { 'filters': { 'payment_channel': "Email" } };
-		});
-	},
-	refresh: function(frm) {
-		if (frm.doc.enabled) {
-			frm.get_field('store_page_docs').$wrapper.removeClass('hide-control').html(
-				`<div>${__("Follow these steps to create a landing page for your store")}:
-					<a href="https://docs.erpnext.com/docs/user/manual/en/website/store-landing-page"
-						style="color: var(--gray-600)">
-						docs/store-landing-page
-					</a>
-				</div>`
-			);
-		}
-
-		frappe.model.with_doctype("Website Item", () => {
-			const web_item_meta = frappe.get_meta('Website Item');
-
-			const valid_fields = web_item_meta.fields.filter(df =>
-				["Link", "Table MultiSelect"].includes(df.fieldtype) && !df.hidden
-			).map(df =>
-				({ label: df.label, value: df.fieldname })
-			);
-
-			frm.get_field("filter_fields").grid.update_docfield_property(
-				'fieldname', 'options', valid_fields
-			);
-		});
-	},
-	enabled: function(frm) {
-		if (frm.doc.enabled === 1) {
-			frm.set_value('enable_variants', 1);
-		}
-		else {
-			frm.set_value('company', '');
-			frm.set_value('price_list', '');
-			frm.set_value('default_customer_group', '');
-			frm.set_value('quotation_series', '');
-		}
-	},
-
-	enable_checkout: function(frm) {
-		if (frm.doc.enable_checkout) {
-			erpnext.utils.check_payments_app();
-		}
-	}
-});
diff --git a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.json b/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.json
deleted file mode 100644
index e6f08f7..0000000
--- a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.json
+++ /dev/null
@@ -1,395 +0,0 @@
-{
- "actions": [],
- "creation": "2021-02-10 17:13:39.139103",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "products_per_page",
-  "filter_categories_section",
-  "enable_field_filters",
-  "filter_fields",
-  "enable_attribute_filters",
-  "filter_attributes",
-  "display_settings_section",
-  "hide_variants",
-  "enable_variants",
-  "show_price",
-  "column_break_9",
-  "show_stock_availability",
-  "show_quantity_in_website",
-  "allow_items_not_in_stock",
-  "column_break_13",
-  "show_apply_coupon_code_in_website",
-  "show_contact_us_button",
-  "show_attachments",
-  "section_break_18",
-  "company",
-  "price_list",
-  "enabled",
-  "store_page_docs",
-  "column_break_21",
-  "default_customer_group",
-  "quotation_series",
-  "checkout_settings_section",
-  "enable_checkout",
-  "show_price_in_quotation",
-  "column_break_27",
-  "save_quotations_as_draft",
-  "payment_gateway_account",
-  "payment_success_url",
-  "add_ons_section",
-  "enable_wishlist",
-  "column_break_22",
-  "enable_reviews",
-  "column_break_23",
-  "enable_recommendations",
-  "item_search_settings_section",
-  "redisearch_warning",
-  "search_index_fields",
-  "is_redisearch_enabled",
-  "is_redisearch_loaded",
-  "shop_by_category_section",
-  "slideshow",
-  "guest_display_settings_section",
-  "hide_price_for_guest",
-  "redirect_on_action"
- ],
- "fields": [
-  {
-   "default": "6",
-   "fieldname": "products_per_page",
-   "fieldtype": "Int",
-   "label": "Products per Page"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "filter_categories_section",
-   "fieldtype": "Section Break",
-   "label": "Filters and Categories"
-  },
-  {
-   "default": "0",
-   "fieldname": "hide_variants",
-   "fieldtype": "Check",
-   "label": "Hide Variants"
-  },
-  {
-   "default": "0",
-   "description": "The field filters will also work as categories in the <b>Shop by Category</b> page.",
-   "fieldname": "enable_field_filters",
-   "fieldtype": "Check",
-   "label": "Enable Field Filters (Categories)"
-  },
-  {
-   "default": "0",
-   "fieldname": "enable_attribute_filters",
-   "fieldtype": "Check",
-   "label": "Enable Attribute Filters"
-  },
-  {
-   "depends_on": "enable_field_filters",
-   "fieldname": "filter_fields",
-   "fieldtype": "Table",
-   "label": "Website Item Fields",
-   "options": "Website Filter Field"
-  },
-  {
-   "depends_on": "enable_attribute_filters",
-   "fieldname": "filter_attributes",
-   "fieldtype": "Table",
-   "label": "Attributes",
-   "options": "Website Attribute"
-  },
-  {
-   "default": "0",
-   "fieldname": "enabled",
-   "fieldtype": "Check",
-   "in_list_view": 1,
-   "label": "Enable Shopping Cart"
-  },
-  {
-   "depends_on": "doc.enabled",
-   "fieldname": "store_page_docs",
-   "fieldtype": "HTML"
-  },
-  {
-   "fieldname": "display_settings_section",
-   "fieldtype": "Section Break",
-   "label": "Display Settings"
-  },
-  {
-   "default": "0",
-   "fieldname": "show_attachments",
-   "fieldtype": "Check",
-   "label": "Show Public Attachments"
-  },
-  {
-   "default": "0",
-   "fieldname": "show_price",
-   "fieldtype": "Check",
-   "label": "Show Price"
-  },
-  {
-   "default": "0",
-   "fieldname": "show_stock_availability",
-   "fieldtype": "Check",
-   "label": "Show Stock Availability"
-  },
-  {
-   "default": "0",
-   "fieldname": "enable_variants",
-   "fieldtype": "Check",
-   "label": "Enable Variant Selection"
-  },
-  {
-   "fieldname": "column_break_13",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "0",
-   "fieldname": "show_contact_us_button",
-   "fieldtype": "Check",
-   "label": "Show Contact Us Button"
-  },
-  {
-   "default": "0",
-   "depends_on": "show_stock_availability",
-   "fieldname": "show_quantity_in_website",
-   "fieldtype": "Check",
-   "label": "Show Stock Quantity"
-  },
-  {
-   "default": "0",
-   "fieldname": "show_apply_coupon_code_in_website",
-   "fieldtype": "Check",
-   "label": "Show Apply Coupon Code"
-  },
-  {
-   "default": "0",
-   "fieldname": "allow_items_not_in_stock",
-   "fieldtype": "Check",
-   "label": "Allow items not in stock to be added to cart"
-  },
-  {
-   "fieldname": "section_break_18",
-   "fieldtype": "Section Break",
-   "label": "Shopping Cart"
-  },
-  {
-   "depends_on": "enabled",
-   "fieldname": "company",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Company",
-   "mandatory_depends_on": "eval: doc.enabled === 1",
-   "options": "Company",
-   "remember_last_selected_value": 1
-  },
-  {
-   "depends_on": "enabled",
-   "description": "Prices will not be shown if Price List is not set",
-   "fieldname": "price_list",
-   "fieldtype": "Link",
-   "label": "Price List",
-   "mandatory_depends_on": "eval: doc.enabled === 1",
-   "options": "Price List"
-  },
-  {
-   "fieldname": "column_break_21",
-   "fieldtype": "Column Break"
-  },
-  {
-   "depends_on": "enabled",
-   "fieldname": "default_customer_group",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "label": "Default Customer Group",
-   "mandatory_depends_on": "eval: doc.enabled === 1",
-   "options": "Customer Group"
-  },
-  {
-   "depends_on": "enabled",
-   "fieldname": "quotation_series",
-   "fieldtype": "Select",
-   "label": "Quotation Series",
-   "mandatory_depends_on": "eval: doc.enabled === 1"
-  },
-  {
-   "collapsible": 1,
-   "collapsible_depends_on": "eval:doc.enable_checkout",
-   "depends_on": "enabled",
-   "fieldname": "checkout_settings_section",
-   "fieldtype": "Section Break",
-   "label": "Checkout Settings"
-  },
-  {
-   "default": "0",
-   "fieldname": "enable_checkout",
-   "fieldtype": "Check",
-   "label": "Enable Checkout"
-  },
-  {
-   "default": "Orders",
-   "depends_on": "enable_checkout",
-   "description": "After payment completion redirect user to selected page.",
-   "fieldname": "payment_success_url",
-   "fieldtype": "Select",
-   "label": "Payment Success Url",
-   "mandatory_depends_on": "enable_checkout",
-   "options": "\nOrders\nInvoices\nMy Account"
-  },
-  {
-   "fieldname": "column_break_27",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "0",
-   "depends_on": "eval: doc.enable_checkout == 0",
-   "fieldname": "save_quotations_as_draft",
-   "fieldtype": "Check",
-   "label": "Save Quotations as Draft"
-  },
-  {
-   "depends_on": "enable_checkout",
-   "fieldname": "payment_gateway_account",
-   "fieldtype": "Link",
-   "label": "Payment Gateway Account",
-   "mandatory_depends_on": "enable_checkout",
-   "options": "Payment Gateway Account"
-  },
-  {
-   "collapsible": 1,
-   "depends_on": "enable_field_filters",
-   "fieldname": "shop_by_category_section",
-   "fieldtype": "Section Break",
-   "label": "Shop by Category"
-  },
-  {
-   "fieldname": "slideshow",
-   "fieldtype": "Link",
-   "label": "Slideshow",
-   "options": "Website Slideshow"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "add_ons_section",
-   "fieldtype": "Section Break",
-   "label": "Add-ons"
-  },
-  {
-   "default": "0",
-   "fieldname": "enable_wishlist",
-   "fieldtype": "Check",
-   "label": "Enable Wishlist"
-  },
-  {
-   "default": "0",
-   "fieldname": "enable_reviews",
-   "fieldtype": "Check",
-   "label": "Enable Reviews and Ratings"
-  },
-  {
-   "fieldname": "search_index_fields",
-   "fieldtype": "Small Text",
-   "label": "Search Index Fields",
-   "mandatory_depends_on": "is_redisearch_enabled",
-   "read_only_depends_on": "eval:!doc.is_redisearch_loaded"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "item_search_settings_section",
-   "fieldtype": "Section Break",
-   "label": "Item Search Settings"
-  },
-  {
-   "default": "0",
-   "fieldname": "is_redisearch_loaded",
-   "fieldtype": "Check",
-   "hidden": 1,
-   "label": "Is Redisearch Loaded"
-  },
-  {
-   "depends_on": "eval:!doc.is_redisearch_loaded",
-   "fieldname": "redisearch_warning",
-   "fieldtype": "HTML",
-   "label": "Redisearch Warning",
-   "options": "<p class=\"alert alert-warning\">Redisearch is not loaded. If you want to use the advanced product search feature, refer <a class=\"alert-link\" href=\"https://docs.erpnext.com/docs/v13/user/manual/en/setting-up/articles/installing-redisearch\" target=\"_blank\">here</a>.</p>"
-  },
-  {
-   "default": "0",
-   "depends_on": "eval:doc.show_price",
-   "fieldname": "hide_price_for_guest",
-   "fieldtype": "Check",
-   "label": "Hide Price for Guest"
-  },
-  {
-   "fieldname": "column_break_9",
-   "fieldtype": "Column Break"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "guest_display_settings_section",
-   "fieldtype": "Section Break",
-   "label": "Guest Display Settings"
-  },
-  {
-   "description": "Link to redirect Guest on actions that need login such as add to cart, wishlist, etc. <b>E.g.: /login</b>",
-   "fieldname": "redirect_on_action",
-   "fieldtype": "Data",
-   "label": "Redirect on Action"
-  },
-  {
-   "fieldname": "column_break_22",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "column_break_23",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "0",
-   "fieldname": "enable_recommendations",
-   "fieldtype": "Check",
-   "label": "Enable Recommendations"
-  },
-  {
-   "default": "0",
-   "depends_on": "eval: doc.enable_checkout == 0",
-   "fieldname": "show_price_in_quotation",
-   "fieldtype": "Check",
-   "label": "Show Price in Quotation"
-  },
-  {
-   "default": "0",
-   "fieldname": "is_redisearch_enabled",
-   "fieldtype": "Check",
-   "label": "Enable Redisearch",
-   "read_only_depends_on": "eval:!doc.is_redisearch_loaded"
-  }
- ],
- "index_web_pages_for_search": 1,
- "issingle": 1,
- "links": [],
- "modified": "2022-04-01 18:35:56.106756",
- "modified_by": "Administrator",
- "module": "E-commerce",
- "name": "E Commerce 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",
- "states": [],
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.py b/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.py
deleted file mode 100644
index c27d29a..0000000
--- a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.py
+++ /dev/null
@@ -1,185 +0,0 @@
-# -*- coding: utf-8 -*-
-# 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
-from frappe.utils import comma_and, flt, unique
-
-from erpnext.e_commerce.redisearch_utils import (
-	create_website_items_index,
-	define_autocomplete_dictionary,
-	get_indexable_web_fields,
-	is_search_module_loaded,
-)
-
-
-class ShoppingCartSetupError(frappe.ValidationError):
-	pass
-
-
-class ECommerceSettings(Document):
-	def onload(self):
-		self.get("__onload").quotation_series = frappe.get_meta("Quotation").get_options("naming_series")
-
-		# flag >> if redisearch is installed and loaded
-		self.is_redisearch_loaded = is_search_module_loaded()
-
-	def validate(self):
-		self.validate_field_filters(self.filter_fields, self.enable_field_filters)
-		self.validate_attribute_filters()
-		self.validate_checkout()
-		self.validate_search_index_fields()
-
-		if self.enabled:
-			self.validate_price_list_exchange_rate()
-
-		frappe.clear_document_cache("E Commerce Settings", "E Commerce Settings")
-
-		self.is_redisearch_enabled_pre_save = frappe.db.get_single_value(
-			"E Commerce Settings", "is_redisearch_enabled"
-		)
-
-	def after_save(self):
-		self.create_redisearch_indexes()
-
-	def create_redisearch_indexes(self):
-		# if redisearch is enabled (value changed) create indexes and dictionary
-		value_changed = self.is_redisearch_enabled != self.is_redisearch_enabled_pre_save
-		if self.is_redisearch_loaded and self.is_redisearch_enabled and value_changed:
-			define_autocomplete_dictionary()
-			create_website_items_index()
-
-	@staticmethod
-	def validate_field_filters(filter_fields, enable_field_filters):
-		if not (enable_field_filters and filter_fields):
-			return
-
-		web_item_meta = frappe.get_meta("Website Item")
-		valid_fields = [
-			df.fieldname for df in web_item_meta.fields if df.fieldtype in ["Link", "Table MultiSelect"]
-		]
-
-		for row in filter_fields:
-			if row.fieldname not in valid_fields:
-				frappe.throw(
-					_(
-						"Filter Fields Row #{0}: Fieldname {1} must be of type 'Link' or 'Table MultiSelect'"
-					).format(row.idx, frappe.bold(row.fieldname))
-				)
-
-	def validate_attribute_filters(self):
-		if not (self.enable_attribute_filters and self.filter_attributes):
-			return
-
-		# if attribute filters are enabled, hide_variants should be disabled
-		self.hide_variants = 0
-
-	def validate_checkout(self):
-		if self.enable_checkout and not self.payment_gateway_account:
-			self.enable_checkout = 0
-
-	def validate_search_index_fields(self):
-		if not self.search_index_fields:
-			return
-
-		fields = self.search_index_fields.replace(" ", "")
-		fields = unique(fields.strip(",").split(","))  # Remove extra ',' and remove duplicates
-
-		# All fields should be indexable
-		allowed_indexable_fields = get_indexable_web_fields()
-
-		if not (set(fields).issubset(allowed_indexable_fields)):
-			invalid_fields = list(set(fields).difference(allowed_indexable_fields))
-			num_invalid_fields = len(invalid_fields)
-			invalid_fields = comma_and(invalid_fields)
-
-			if num_invalid_fields > 1:
-				frappe.throw(
-					_("{0} are not valid options for Search Index Field.").format(frappe.bold(invalid_fields))
-				)
-			else:
-				frappe.throw(
-					_("{0} is not a valid option for Search Index Field.").format(frappe.bold(invalid_fields))
-				)
-
-		self.search_index_fields = ",".join(fields)
-
-	def validate_price_list_exchange_rate(self):
-		"Check if exchange rate exists for Price List currency (to Company's currency)."
-		from erpnext.setup.utils import get_exchange_rate
-
-		if not self.enabled or not self.company or not self.price_list:
-			return  # this function is also called from hooks, check values again
-
-		company_currency = frappe.get_cached_value("Company", self.company, "default_currency")
-		price_list_currency = frappe.db.get_value("Price List", self.price_list, "currency")
-
-		if not company_currency:
-			msg = f"Please specify currency in Company {self.company}"
-			frappe.throw(_(msg), title=_("Missing Currency"), exc=ShoppingCartSetupError)
-
-		if not price_list_currency:
-			msg = f"Please specify currency in Price List {frappe.bold(self.price_list)}"
-			frappe.throw(_(msg), title=_("Missing Currency"), exc=ShoppingCartSetupError)
-
-		if price_list_currency != company_currency:
-			from_currency, to_currency = price_list_currency, company_currency
-
-			# Get exchange rate checks Currency Exchange Records too
-			exchange_rate = get_exchange_rate(from_currency, to_currency, args="for_selling")
-
-			if not flt(exchange_rate):
-				msg = f"Missing Currency Exchange Rates for {from_currency}-{to_currency}"
-				frappe.throw(_(msg), title=_("Missing"), exc=ShoppingCartSetupError)
-
-	def validate_tax_rule(self):
-		if not frappe.db.get_value("Tax Rule", {"use_for_shopping_cart": 1}, "name"):
-			frappe.throw(frappe._("Set Tax Rule for shopping cart"), ShoppingCartSetupError)
-
-	def get_tax_master(self, billing_territory):
-		tax_master = self.get_name_from_territory(
-			billing_territory, "sales_taxes_and_charges_masters", "sales_taxes_and_charges_master"
-		)
-		return tax_master and tax_master[0] or None
-
-	def get_shipping_rules(self, shipping_territory):
-		return self.get_name_from_territory(shipping_territory, "shipping_rules", "shipping_rule")
-
-	def on_change(self):
-		old_doc = self.get_doc_before_save()
-
-		if old_doc:
-			old_fields = old_doc.search_index_fields
-			new_fields = self.search_index_fields
-
-			# if search index fields get changed
-			if not (new_fields == old_fields):
-				create_website_items_index()
-
-
-def validate_cart_settings(doc=None, method=None):
-	frappe.get_doc("E Commerce Settings", "E Commerce Settings").run_method("validate")
-
-
-def get_shopping_cart_settings():
-	return frappe.get_cached_doc("E Commerce Settings")
-
-
-@frappe.whitelist(allow_guest=True)
-def is_cart_enabled():
-	return get_shopping_cart_settings().enabled
-
-
-def show_quantity_in_website():
-	return get_shopping_cart_settings().show_quantity_in_website
-
-
-def check_shopping_cart_enabled():
-	if not get_shopping_cart_settings().enabled:
-		frappe.throw(_("You need to enable Shopping Cart"), ShoppingCartSetupError)
-
-
-def show_attachments():
-	return get_shopping_cart_settings().show_attachments
diff --git a/erpnext/e_commerce/doctype/e_commerce_settings/test_e_commerce_settings.py b/erpnext/e_commerce/doctype/e_commerce_settings/test_e_commerce_settings.py
deleted file mode 100644
index 662db4d..0000000
--- a/erpnext/e_commerce/doctype/e_commerce_settings/test_e_commerce_settings.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-import unittest
-
-import frappe
-
-from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import (
-	ShoppingCartSetupError,
-)
-
-
-class TestECommerceSettings(unittest.TestCase):
-	def tearDown(self):
-		frappe.db.rollback()
-
-	def test_tax_rule_validation(self):
-		frappe.db.sql("update `tabTax Rule` set use_for_shopping_cart = 0")
-		frappe.db.commit()  # nosemgrep
-
-		cart_settings = frappe.get_doc("E Commerce Settings")
-		cart_settings.enabled = 1
-		if not frappe.db.get_value("Tax Rule", {"use_for_shopping_cart": 1}, "name"):
-			self.assertRaises(ShoppingCartSetupError, cart_settings.validate_tax_rule)
-
-		frappe.db.sql("update `tabTax Rule` set use_for_shopping_cart = 1")
-
-	def test_invalid_filter_fields(self):
-		"Check if Item fields are blocked in E Commerce Settings filter fields."
-		from frappe.custom.doctype.custom_field.custom_field import create_custom_field
-
-		setup_e_commerce_settings({"enable_field_filters": 1})
-
-		create_custom_field(
-			"Item",
-			dict(owner="Administrator", fieldname="test_data", label="Test", fieldtype="Data"),
-		)
-		settings = frappe.get_doc("E Commerce Settings")
-		settings.append("filter_fields", {"fieldname": "test_data"})
-
-		self.assertRaises(frappe.ValidationError, settings.save)
-
-
-def setup_e_commerce_settings(values_dict):
-	"Accepts a dict of values that updates E Commerce Settings."
-	if not values_dict:
-		return
-
-	doc = frappe.get_doc("E Commerce Settings", "E Commerce Settings")
-	doc.update(values_dict)
-	doc.save()
-
-
-test_dependencies = ["Tax Rule"]
diff --git a/erpnext/e_commerce/doctype/item_review/__init__.py b/erpnext/e_commerce/doctype/item_review/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/doctype/item_review/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/doctype/item_review/item_review.js b/erpnext/e_commerce/doctype/item_review/item_review.js
deleted file mode 100644
index a57c370..0000000
--- a/erpnext/e_commerce/doctype/item_review/item_review.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('Item Review', {
-	// refresh: function(frm) {
-
-	// }
-});
diff --git a/erpnext/e_commerce/doctype/item_review/item_review.json b/erpnext/e_commerce/doctype/item_review/item_review.json
deleted file mode 100644
index 57f719f..0000000
--- a/erpnext/e_commerce/doctype/item_review/item_review.json
+++ /dev/null
@@ -1,134 +0,0 @@
-{
- "actions": [],
- "beta": 1,
- "creation": "2021-03-23 16:47:26.542226",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "website_item",
-  "user",
-  "customer",
-  "column_break_3",
-  "item",
-  "published_on",
-  "reviews_section",
-  "review_title",
-  "rating",
-  "comment"
- ],
- "fields": [
-  {
-   "fieldname": "website_item",
-   "fieldtype": "Link",
-   "label": "Website Item",
-   "options": "Website Item",
-   "read_only": 1,
-   "reqd": 1
-  },
-  {
-   "fieldname": "user",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "User",
-   "options": "User",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_3",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fetch_from": "website_item.item_code",
-   "fieldname": "item",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Item",
-   "options": "Item",
-   "read_only": 1
-  },
-  {
-   "fieldname": "reviews_section",
-   "fieldtype": "Section Break",
-   "label": "Reviews"
-  },
-  {
-   "fieldname": "rating",
-   "fieldtype": "Rating",
-   "in_list_view": 1,
-   "label": "Rating",
-   "read_only": 1
-  },
-  {
-   "fieldname": "comment",
-   "fieldtype": "Small Text",
-   "label": "Comment",
-   "read_only": 1
-  },
-  {
-   "fieldname": "review_title",
-   "fieldtype": "Data",
-   "label": "Review Title",
-   "read_only": 1
-  },
-  {
-   "fieldname": "customer",
-   "fieldtype": "Link",
-   "label": "Customer",
-   "options": "Customer",
-   "read_only": 1
-  },
-  {
-   "fieldname": "published_on",
-   "fieldtype": "Data",
-   "label": "Published on",
-   "read_only": 1
-  }
- ],
- "index_web_pages_for_search": 1,
- "links": [],
- "modified": "2021-08-10 12:08:58.119691",
- "modified_by": "Administrator",
- "module": "E-commerce",
- "name": "Item Review",
- "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": "Website Manager",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "report": 1,
-   "role": "Customer",
-   "share": 1
-  }
- ],
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/e_commerce/doctype/item_review/item_review.py b/erpnext/e_commerce/doctype/item_review/item_review.py
deleted file mode 100644
index 3e540e3..0000000
--- a/erpnext/e_commerce/doctype/item_review/item_review.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from datetime import datetime
-
-import frappe
-from frappe import _
-from frappe.contacts.doctype.contact.contact import get_contact_name
-from frappe.model.document import Document
-from frappe.utils import cint, flt
-
-from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import (
-	get_shopping_cart_settings,
-)
-
-
-class UnverifiedReviewer(frappe.ValidationError):
-	pass
-
-
-class ItemReview(Document):
-	def after_insert(self):
-		# regenerate cache on review creation
-		reviews_dict = get_queried_reviews(self.website_item)
-		set_reviews_in_cache(self.website_item, reviews_dict)
-
-	def after_delete(self):
-		# regenerate cache on review deletion
-		reviews_dict = get_queried_reviews(self.website_item)
-		set_reviews_in_cache(self.website_item, reviews_dict)
-
-
-@frappe.whitelist()
-def get_item_reviews(web_item, start=0, end=10, data=None):
-	"Get Website Item Review Data."
-	start, end = cint(start), cint(end)
-	settings = get_shopping_cart_settings()
-
-	# Get cached reviews for first page (start=0)
-	# avoid cache when page is different
-	from_cache = not bool(start)
-
-	if not data:
-		data = frappe._dict()
-
-	if settings and settings.get("enable_reviews"):
-		reviews_cache = frappe.cache().hget("item_reviews", web_item)
-		if from_cache and reviews_cache:
-			data = reviews_cache
-		else:
-			data = get_queried_reviews(web_item, start, end, data)
-			if from_cache:
-				set_reviews_in_cache(web_item, data)
-
-	return data
-
-
-def get_queried_reviews(web_item, start=0, end=10, data=None):
-	"""
-	Query Website Item wise reviews and cache if needed.
-	Cache stores only first page of reviews i.e. 10 reviews maximum.
-	Returns:
-	        dict: Containing reviews, average ratings, % of reviews per rating and total reviews.
-	"""
-	if not data:
-		data = frappe._dict()
-
-	data.reviews = frappe.db.get_all(
-		"Item Review",
-		filters={"website_item": web_item},
-		fields=["*"],
-		limit_start=start,
-		limit_page_length=end,
-	)
-
-	rating_data = frappe.db.get_all(
-		"Item Review",
-		filters={"website_item": web_item},
-		fields=["avg(rating) as average, count(*) as total"],
-	)[0]
-
-	data.average_rating = flt(rating_data.average, 1)
-	data.average_whole_rating = flt(data.average_rating, 0)
-
-	# get % of reviews per rating
-	reviews_per_rating = []
-	for i in range(1, 6):
-		count = frappe.db.get_all(
-			"Item Review", filters={"website_item": web_item, "rating": i}, fields=["count(*) as count"]
-		)[0].count
-
-		percent = flt((count / rating_data.total or 1) * 100, 0) if count else 0
-		reviews_per_rating.append(percent)
-
-	data.reviews_per_rating = reviews_per_rating
-	data.total_reviews = rating_data.total
-
-	return data
-
-
-def set_reviews_in_cache(web_item, reviews_dict):
-	frappe.cache().hset("item_reviews", web_item, reviews_dict)
-
-
-@frappe.whitelist()
-def add_item_review(web_item, title, rating, comment=None):
-	"""Add an Item Review by a user if non-existent."""
-	if frappe.session.user == "Guest":
-		# guest user should not reach here ideally in the case they do via an API, throw error
-		frappe.throw(_("You are not verified to write a review yet."), exc=UnverifiedReviewer)
-
-	if not frappe.db.exists("Item Review", {"user": frappe.session.user, "website_item": web_item}):
-		doc = frappe.get_doc(
-			{
-				"doctype": "Item Review",
-				"user": frappe.session.user,
-				"customer": get_customer(),
-				"website_item": web_item,
-				"item": frappe.db.get_value("Website Item", web_item, "item_code"),
-				"review_title": title,
-				"rating": rating,
-				"comment": comment,
-			}
-		)
-		doc.published_on = datetime.today().strftime("%d %B %Y")
-		doc.insert()
-
-
-def get_customer(silent=False):
-	"""
-	silent: Return customer if exists else return nothing. Dont throw error.
-	"""
-	user = frappe.session.user
-	contact_name = get_contact_name(user)
-	customer = None
-
-	if contact_name:
-		contact = frappe.get_doc("Contact", contact_name)
-		for link in contact.links:
-			if link.link_doctype == "Customer":
-				customer = link.link_name
-				break
-
-	if customer:
-		return frappe.db.get_value("Customer", customer)
-	elif silent:
-		return None
-	else:
-		# should not reach here unless via an API
-		frappe.throw(
-			_("You are not a verified customer yet. Please contact us to proceed."), exc=UnverifiedReviewer
-		)
diff --git a/erpnext/e_commerce/doctype/item_review/test_item_review.py b/erpnext/e_commerce/doctype/item_review/test_item_review.py
deleted file mode 100644
index 8a4befc..0000000
--- a/erpnext/e_commerce/doctype/item_review/test_item_review.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-import unittest
-
-import frappe
-from frappe.core.doctype.user_permission.test_user_permission import create_user
-
-from erpnext.e_commerce.doctype.e_commerce_settings.test_e_commerce_settings import (
-	setup_e_commerce_settings,
-)
-from erpnext.e_commerce.doctype.item_review.item_review import (
-	UnverifiedReviewer,
-	add_item_review,
-	get_item_reviews,
-)
-from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
-from erpnext.e_commerce.shopping_cart.cart import get_party
-from erpnext.stock.doctype.item.test_item import make_item
-
-
-class TestItemReview(unittest.TestCase):
-	def setUp(self):
-		item = make_item("Test Mobile Phone")
-		if not frappe.db.exists("Website Item", {"item_code": "Test Mobile Phone"}):
-			make_website_item(item, save=True)
-
-		setup_e_commerce_settings({"enable_reviews": 1})
-		frappe.local.shopping_cart_settings = None
-
-	def tearDown(self):
-		frappe.get_cached_doc("Website Item", {"item_code": "Test Mobile Phone"}).delete()
-		setup_e_commerce_settings({"enable_reviews": 0})
-
-	def test_add_and_get_item_reviews_from_customer(self):
-		"Add / Get Reviews from a User that is a valid customer (has added to cart or purchased in the past)"
-		# create user
-		web_item = frappe.db.get_value("Website Item", {"item_code": "Test Mobile Phone"})
-		test_user = create_user("test_reviewer@example.com", "Customer")
-		frappe.set_user(test_user.name)
-
-		# create customer and contact against user
-		customer = get_party()
-
-		# post review on "Test Mobile Phone"
-		try:
-			add_item_review(web_item, "Great Product", 3, "Would recommend this product")
-			review_name = frappe.db.get_value("Item Review", {"website_item": web_item})
-		except Exception:
-			self.fail(f"Error while publishing review for {web_item}")
-
-		review_data = get_item_reviews(web_item, 0, 10)
-
-		self.assertEqual(len(review_data.reviews), 1)
-		self.assertEqual(review_data.average_rating, 3)
-		self.assertEqual(review_data.reviews_per_rating[2], 100)
-
-		# tear down
-		frappe.set_user("Administrator")
-		frappe.delete_doc("Item Review", review_name)
-		customer.delete()
-
-	def test_add_item_review_from_non_customer(self):
-		"Check if logged in user (who is not a customer yet) is blocked from posting reviews."
-		web_item = frappe.db.get_value("Website Item", {"item_code": "Test Mobile Phone"})
-		test_user = create_user("test_reviewer@example.com", "Customer")
-		frappe.set_user(test_user.name)
-
-		with self.assertRaises(UnverifiedReviewer):
-			add_item_review(web_item, "Great Product", 3, "Would recommend this product")
-
-		# tear down
-		frappe.set_user("Administrator")
-
-	def test_add_item_reviews_from_guest_user(self):
-		"Check if Guest user is blocked from posting reviews."
-		web_item = frappe.db.get_value("Website Item", {"item_code": "Test Mobile Phone"})
-		frappe.set_user("Guest")
-
-		with self.assertRaises(UnverifiedReviewer):
-			add_item_review(web_item, "Great Product", 3, "Would recommend this product")
-
-		# tear down
-		frappe.set_user("Administrator")
diff --git a/erpnext/e_commerce/doctype/recommended_items/__init__.py b/erpnext/e_commerce/doctype/recommended_items/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/doctype/recommended_items/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/doctype/recommended_items/recommended_items.json b/erpnext/e_commerce/doctype/recommended_items/recommended_items.json
deleted file mode 100644
index 1821532..0000000
--- a/erpnext/e_commerce/doctype/recommended_items/recommended_items.json
+++ /dev/null
@@ -1,88 +0,0 @@
-{
- "actions": [],
- "creation": "2021-07-12 20:52:12.503470",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "website_item",
-  "website_item_name",
-  "column_break_2",
-  "item_code",
-  "more_information_section",
-  "route",
-  "column_break_6",
-  "website_item_image",
-  "website_item_thumbnail"
- ],
- "fields": [
-  {
-   "fieldname": "website_item",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Website Item",
-   "options": "Website Item"
-  },
-  {
-   "fetch_from": "website_item.web_item_name",
-   "fieldname": "website_item_name",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Website Item Name",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_2",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "more_information_section",
-   "fieldtype": "Section Break",
-   "label": "More Information"
-  },
-  {
-   "fetch_from": "website_item.route",
-   "fieldname": "route",
-   "fieldtype": "Small Text",
-   "label": "Route",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "website_item.website_image",
-   "fieldname": "website_item_image",
-   "fieldtype": "Attach",
-   "label": "Website Item Image",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_6",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fetch_from": "website_item.thumbnail",
-   "fieldname": "website_item_thumbnail",
-   "fieldtype": "Data",
-   "label": "Website Item Thumbnail",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "website_item.item_code",
-   "fieldname": "item_code",
-   "fieldtype": "Data",
-   "label": "Item Code"
-  }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2022-06-28 16:44:24.718728",
- "modified_by": "Administrator",
- "module": "E-commerce",
- "name": "Recommended Items",
- "owner": "Administrator",
- "permissions": [],
- "sort_field": "modified",
- "sort_order": "DESC",
- "states": [],
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/e_commerce/doctype/recommended_items/recommended_items.py b/erpnext/e_commerce/doctype/recommended_items/recommended_items.py
deleted file mode 100644
index 16b6e52..0000000
--- a/erpnext/e_commerce/doctype/recommended_items/recommended_items.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 RecommendedItems(Document):
-	pass
diff --git a/erpnext/e_commerce/doctype/website_item/__init__.py b/erpnext/e_commerce/doctype/website_item/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/doctype/website_item/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/doctype/website_item/templates/website_item.html b/erpnext/e_commerce/doctype/website_item/templates/website_item.html
deleted file mode 100644
index db12309..0000000
--- a/erpnext/e_commerce/doctype/website_item/templates/website_item.html
+++ /dev/null
@@ -1,7 +0,0 @@
-{% extends "templates/web.html" %}
-
-{% block page_content %}
-<h1>{{ title }}</h1>
-{% endblock %}
-
-<!-- this is a sample default web page template -->
\ No newline at end of file
diff --git a/erpnext/e_commerce/doctype/website_item/templates/website_item_row.html b/erpnext/e_commerce/doctype/website_item/templates/website_item_row.html
deleted file mode 100644
index d7014b4..0000000
--- a/erpnext/e_commerce/doctype/website_item/templates/website_item_row.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<div>
-	<a href="{{ doc.route }}">{{ doc.title or doc.name }}</a>
-</div>
-<!-- this is a sample default list template -->
diff --git a/erpnext/e_commerce/doctype/website_item/test_website_item.py b/erpnext/e_commerce/doctype/website_item/test_website_item.py
deleted file mode 100644
index 2ba84c0..0000000
--- a/erpnext/e_commerce/doctype/website_item/test_website_item.py
+++ /dev/null
@@ -1,564 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-
-import unittest
-
-import frappe
-
-from erpnext.controllers.item_variant import create_variant
-from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import (
-	get_shopping_cart_settings,
-)
-from erpnext.e_commerce.doctype.e_commerce_settings.test_e_commerce_settings import (
-	setup_e_commerce_settings,
-)
-from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
-from erpnext.e_commerce.shopping_cart.product_info import get_product_info_for_website
-from erpnext.stock.doctype.item.item import DataValidationError
-from erpnext.stock.doctype.item.test_item import make_item
-
-WEBITEM_DESK_TESTS = ("test_website_item_desk_item_sync", "test_publish_variant_and_template")
-WEBITEM_PRICE_TESTS = (
-	"test_website_item_price_for_logged_in_user",
-	"test_website_item_price_for_guest_user",
-)
-
-
-class TestWebsiteItem(unittest.TestCase):
-	@classmethod
-	def setUpClass(cls):
-		setup_e_commerce_settings(
-			{
-				"company": "_Test Company",
-				"enabled": 1,
-				"default_customer_group": "_Test Customer Group",
-				"price_list": "_Test Price List India",
-			}
-		)
-
-	@classmethod
-	def tearDownClass(cls):
-		frappe.db.rollback()
-
-	def setUp(self):
-		if self._testMethodName in WEBITEM_DESK_TESTS:
-			make_item(
-				"Test Web Item",
-				{
-					"has_variant": 1,
-					"variant_based_on": "Item Attribute",
-					"attributes": [{"attribute": "Test Size"}],
-				},
-			)
-		elif self._testMethodName in WEBITEM_PRICE_TESTS:
-			create_user_and_customer_if_not_exists(
-				"test_contact_customer@example.com", "_Test Contact For _Test Customer"
-			)
-			create_regular_web_item()
-			make_web_item_price(item_code="Test Mobile Phone")
-
-			# Note: When testing web item pricing rule logged-in user pricing rule must differ from guest pricing rule or test will falsely pass.
-			# 	  This is because make_web_pricing_rule creates a pricing rule "selling": 1, without specifying "applicable_for". Therefor,
-			# 	  when testing for logged-in user the test will get the previous pricing rule because "selling" is still true.
-			#
-			#     I've attempted to mitigate this by setting applicable_for=Customer, and customer=Guest however, this only results in PermissionError failing the test.
-			make_web_pricing_rule(
-				title="Test Pricing Rule for Test Mobile Phone", item_code="Test Mobile Phone", selling=1
-			)
-			make_web_pricing_rule(
-				title="Test Pricing Rule for Test Mobile Phone (Customer)",
-				item_code="Test Mobile Phone",
-				selling=1,
-				discount_percentage="25",
-				applicable_for="Customer",
-				customer="_Test Customer",
-			)
-
-	def test_index_creation(self):
-		"Check if index is getting created in db."
-		from erpnext.e_commerce.doctype.website_item.website_item import on_doctype_update
-
-		on_doctype_update()
-
-		indices = frappe.db.sql("show index from `tabWebsite Item`", as_dict=1)
-		expected_columns = {"route", "item_group", "brand"}
-		for index in indices:
-			expected_columns.discard(index.get("Column_name"))
-
-		if expected_columns:
-			self.fail(f"Expected db index on these columns: {', '.join(expected_columns)}")
-
-	def test_website_item_desk_item_sync(self):
-		"Check creation/updation/deletion of Website Item and its impact on Item master."
-		web_item = None
-		item = make_item("Test Web Item")  # will return item if exists
-		try:
-			web_item = make_website_item(item, save=False)
-			web_item.save()
-		except Exception:
-			self.fail(f"Error while creating website item for {item}")
-
-		# check if website item was created
-		self.assertTrue(bool(web_item))
-		self.assertTrue(bool(web_item.route))
-
-		item.reload()
-		self.assertEqual(web_item.published, 1)
-		self.assertEqual(item.published_in_website, 1)  # check if item was back updated
-		self.assertEqual(web_item.item_group, item.item_group)
-
-		# check if changing item data changes it in website item
-		item.item_name = "Test Web Item 1"
-		item.stock_uom = "Unit"
-		item.save()
-		web_item.reload()
-		self.assertEqual(web_item.item_name, item.item_name)
-		self.assertEqual(web_item.stock_uom, item.stock_uom)
-
-		# check if disabling item unpublished website item
-		item.disabled = 1
-		item.save()
-		web_item.reload()
-		self.assertEqual(web_item.published, 0)
-
-		# check if website item deletion, unpublishes desk item
-		web_item.delete()
-		item.reload()
-		self.assertEqual(item.published_in_website, 0)
-
-		item.delete()
-
-	def test_publish_variant_and_template(self):
-		"Check if template is published on publishing variant."
-		# template "Test Web Item" created on setUp
-		variant = create_variant("Test Web Item", {"Test Size": "Large"})
-		variant.save()
-
-		# check if template is not published
-		self.assertIsNone(frappe.db.exists("Website Item", {"item_code": variant.variant_of}))
-
-		variant_web_item = make_website_item(variant, save=False)
-		variant_web_item.save()
-
-		# check if template is published
-		try:
-			template_web_item = frappe.get_doc("Website Item", {"item_code": variant.variant_of})
-		except frappe.DoesNotExistError:
-			self.fail(f"Template of {variant.item_code}, {variant.variant_of} not published")
-
-		# teardown
-		variant_web_item.delete()
-		template_web_item.delete()
-		variant.delete()
-
-	def test_impact_on_merging_items(self):
-		"Check if merging items is blocked if old and new items both have website items"
-		first_item = make_item("Test First Item")
-		second_item = make_item("Test Second Item")
-
-		first_web_item = make_website_item(first_item, save=False)
-		first_web_item.save()
-		second_web_item = make_website_item(second_item, save=False)
-		second_web_item.save()
-
-		with self.assertRaises(DataValidationError):
-			frappe.rename_doc("Item", "Test First Item", "Test Second Item", merge=True)
-
-		# tear down
-		second_web_item.delete()
-		first_web_item.delete()
-		second_item.delete()
-		first_item.delete()
-
-	# Website Item Portal Tests Begin
-
-	def test_website_item_breadcrumbs(self):
-		"""
-		Check if breadcrumbs include homepage, product listing navigation page,
-		parent item group(s) and item group
-		"""
-		from erpnext.setup.doctype.item_group.item_group import get_parent_item_groups
-
-		item_code = "Test Breadcrumb Item"
-		item = make_item(
-			item_code,
-			{
-				"item_group": "_Test Item Group B - 1",
-			},
-		)
-
-		if not frappe.db.exists("Website Item", {"item_code": item_code}):
-			web_item = make_website_item(item, save=False)
-			web_item.save()
-		else:
-			web_item = frappe.get_cached_doc("Website Item", {"item_code": item_code})
-
-		frappe.db.set_value("Item Group", "_Test Item Group B - 1", "show_in_website", 1)
-		frappe.db.set_value("Item Group", "_Test Item Group B", "show_in_website", 1)
-
-		breadcrumbs = get_parent_item_groups(item.item_group)
-
-		settings = frappe.get_cached_doc("E Commerce Settings")
-		if settings.enable_field_filters:
-			base_breadcrumb = "Shop by Category"
-		else:
-			base_breadcrumb = "All Products"
-
-		self.assertEqual(breadcrumbs[0]["name"], "Home")
-		self.assertEqual(breadcrumbs[1]["name"], base_breadcrumb)
-		self.assertEqual(breadcrumbs[2]["name"], "_Test Item Group B")  # parent item group
-		self.assertEqual(breadcrumbs[3]["name"], "_Test Item Group B - 1")
-
-		# tear down
-		web_item.delete()
-		item.delete()
-
-	def test_website_item_price_for_logged_in_user(self):
-		"Check if price details are fetched correctly while logged in."
-		item_code = "Test Mobile Phone"
-
-		# show price in e commerce settings
-		setup_e_commerce_settings({"show_price": 1})
-
-		# price and pricing rule added via setUp
-
-		# login as customer with pricing rule
-		frappe.set_user("test_contact_customer@example.com")
-
-		# check if price and slashed price is fetched correctly
-		frappe.local.shopping_cart_settings = None
-		data = get_product_info_for_website(item_code, skip_quotation_creation=True)
-		self.assertTrue(bool(data.product_info["price"]))
-
-		price_object = data.product_info["price"]
-		self.assertEqual(price_object.get("discount_percent"), 25.0)
-		self.assertEqual(price_object.get("price_list_rate"), 750)
-		self.assertEqual(price_object.get("formatted_mrp"), "₹ 1,000.00")
-		self.assertEqual(price_object.get("formatted_price"), "₹ 750.00")
-		self.assertEqual(price_object.get("formatted_discount_percent"), "25.0%")
-
-		# switch to admin and disable show price
-		frappe.set_user("Administrator")
-		setup_e_commerce_settings({"show_price": 0})
-
-		# price should not be fetched for logged in user.
-		frappe.set_user("test_contact_customer@example.com")
-		frappe.local.shopping_cart_settings = None
-		data = get_product_info_for_website(item_code, skip_quotation_creation=True)
-		self.assertFalse(bool(data.product_info["price"]))
-
-		# tear down
-		frappe.set_user("Administrator")
-
-	def test_website_item_price_for_guest_user(self):
-		"Check if price details are fetched correctly for guest user."
-		item_code = "Test Mobile Phone"
-
-		# show price for guest user in e commerce settings
-		setup_e_commerce_settings({"show_price": 1, "hide_price_for_guest": 0})
-
-		# price and pricing rule added via setUp
-
-		# switch to guest user
-		frappe.set_user("Guest")
-
-		# price should be fetched
-		frappe.local.shopping_cart_settings = None
-		data = get_product_info_for_website(item_code, skip_quotation_creation=True)
-		self.assertTrue(bool(data.product_info["price"]))
-
-		price_object = data.product_info["price"]
-		self.assertEqual(price_object.get("discount_percent"), 10)
-		self.assertEqual(price_object.get("price_list_rate"), 900)
-
-		# hide price for guest user
-		frappe.set_user("Administrator")
-		setup_e_commerce_settings({"hide_price_for_guest": 1})
-		frappe.set_user("Guest")
-
-		# price should not be fetched
-		frappe.local.shopping_cart_settings = None
-		data = get_product_info_for_website(item_code, skip_quotation_creation=True)
-		self.assertFalse(bool(data.product_info["price"]))
-
-		# tear down
-		frappe.set_user("Administrator")
-
-	def test_website_item_stock_when_out_of_stock(self):
-		"""
-		Check if stock details are fetched correctly for empty inventory when:
-		1) Showing stock availability enabled:
-		        - Warehouse unset
-		        - Warehouse set
-		2) Showing stock availability disabled
-		"""
-		item_code = "Test Mobile Phone"
-		create_regular_web_item()
-		setup_e_commerce_settings({"show_stock_availability": 1})
-
-		frappe.local.shopping_cart_settings = None
-		data = get_product_info_for_website(item_code, skip_quotation_creation=True)
-
-		# check if stock details are fetched and item not in stock without warehouse set
-		self.assertFalse(bool(data.product_info["in_stock"]))
-		self.assertFalse(bool(data.product_info["stock_qty"]))
-
-		# set warehouse
-		frappe.db.set_value(
-			"Website Item", {"item_code": item_code}, "website_warehouse", "_Test Warehouse - _TC"
-		)
-
-		# check if stock details are fetched and item not in stock with warehouse set
-		data = get_product_info_for_website(item_code, skip_quotation_creation=True)
-		self.assertFalse(bool(data.product_info["in_stock"]))
-		self.assertEqual(data.product_info["stock_qty"], 0)
-
-		# disable show stock availability
-		setup_e_commerce_settings({"show_stock_availability": 0})
-		frappe.local.shopping_cart_settings = None
-		data = get_product_info_for_website(item_code, skip_quotation_creation=True)
-
-		# check if stock detail attributes are not fetched if stock availability is hidden
-		self.assertIsNone(data.product_info.get("in_stock"))
-		self.assertIsNone(data.product_info.get("stock_qty"))
-		self.assertIsNone(data.product_info.get("show_stock_qty"))
-
-		# tear down
-		frappe.get_cached_doc("Website Item", {"item_code": "Test Mobile Phone"}).delete()
-
-	def test_website_item_stock_when_in_stock(self):
-		"""
-		Check if stock details are fetched correctly for available inventory when:
-		1) Showing stock availability enabled:
-		        - Warehouse set
-		        - Warehouse unset
-		2) Showing stock availability disabled
-		"""
-		from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
-
-		item_code = "Test Mobile Phone"
-		create_regular_web_item()
-		setup_e_commerce_settings({"show_stock_availability": 1})
-		frappe.local.shopping_cart_settings = None
-
-		# set warehouse
-		frappe.db.set_value(
-			"Website Item", {"item_code": item_code}, "website_warehouse", "_Test Warehouse - _TC"
-		)
-
-		# stock up item
-		stock_entry = make_stock_entry(
-			item_code=item_code, target="_Test Warehouse - _TC", qty=2, rate=100
-		)
-
-		# check if stock details are fetched and item is in stock with warehouse set
-		data = get_product_info_for_website(item_code, skip_quotation_creation=True)
-		self.assertTrue(bool(data.product_info["in_stock"]))
-		self.assertEqual(data.product_info["stock_qty"], 2)
-
-		# unset warehouse
-		frappe.db.set_value("Website Item", {"item_code": item_code}, "website_warehouse", "")
-
-		# check if stock details are fetched and item not in stock without warehouse set
-		# (even though it has stock in some warehouse)
-		data = get_product_info_for_website(item_code, skip_quotation_creation=True)
-		self.assertFalse(bool(data.product_info["in_stock"]))
-		self.assertFalse(data.product_info["stock_qty"])
-
-		# disable show stock availability
-		setup_e_commerce_settings({"show_stock_availability": 0})
-		frappe.local.shopping_cart_settings = None
-		data = get_product_info_for_website(item_code, skip_quotation_creation=True)
-
-		# check if stock detail attributes are not fetched if stock availability is hidden
-		self.assertIsNone(data.product_info.get("in_stock"))
-		self.assertIsNone(data.product_info.get("stock_qty"))
-		self.assertIsNone(data.product_info.get("show_stock_qty"))
-
-		# tear down
-		stock_entry.cancel()
-		frappe.get_cached_doc("Website Item", {"item_code": "Test Mobile Phone"}).delete()
-
-	def test_recommended_item(self):
-		"Check if added recommended items are fetched correctly."
-		item_code = "Test Mobile Phone"
-		web_item = create_regular_web_item(item_code)
-
-		setup_e_commerce_settings({"enable_recommendations": 1, "show_price": 1})
-
-		# create recommended web item and price for it
-		recommended_web_item = create_regular_web_item("Test Mobile Phone 1")
-		make_web_item_price(item_code="Test Mobile Phone 1")
-
-		# add recommended item to first web item
-		web_item.append("recommended_items", {"website_item": recommended_web_item.name})
-		web_item.save()
-
-		frappe.local.shopping_cart_settings = None
-		e_commerce_settings = get_shopping_cart_settings()
-		recommended_items = web_item.get_recommended_items(e_commerce_settings)
-
-		# test results if show price is enabled
-		self.assertEqual(len(recommended_items), 1)
-		recomm_item = recommended_items[0]
-		self.assertEqual(recomm_item.get("website_item_name"), "Test Mobile Phone 1")
-		self.assertTrue(bool(recomm_item.get("price_info")))  # price fetched
-
-		price_info = recomm_item.get("price_info")
-		self.assertEqual(price_info.get("price_list_rate"), 1000)
-		self.assertEqual(price_info.get("formatted_price"), "₹ 1,000.00")
-
-		# test results if show price is disabled
-		setup_e_commerce_settings({"show_price": 0})
-
-		frappe.local.shopping_cart_settings = None
-		e_commerce_settings = get_shopping_cart_settings()
-		recommended_items = web_item.get_recommended_items(e_commerce_settings)
-
-		self.assertEqual(len(recommended_items), 1)
-		self.assertFalse(bool(recommended_items[0].get("price_info")))  # price not fetched
-
-		# tear down
-		web_item.delete()
-		recommended_web_item.delete()
-		frappe.get_cached_doc("Item", "Test Mobile Phone 1").delete()
-
-	def test_recommended_item_for_guest_user(self):
-		"Check if added recommended items are fetched correctly for guest user."
-		item_code = "Test Mobile Phone"
-		web_item = create_regular_web_item(item_code)
-
-		# price visible to guests
-		setup_e_commerce_settings(
-			{"enable_recommendations": 1, "show_price": 1, "hide_price_for_guest": 0}
-		)
-
-		# create recommended web item and price for it
-		recommended_web_item = create_regular_web_item("Test Mobile Phone 1")
-		make_web_item_price(item_code="Test Mobile Phone 1")
-
-		# add recommended item to first web item
-		web_item.append("recommended_items", {"website_item": recommended_web_item.name})
-		web_item.save()
-
-		frappe.set_user("Guest")
-
-		frappe.local.shopping_cart_settings = None
-		e_commerce_settings = get_shopping_cart_settings()
-		recommended_items = web_item.get_recommended_items(e_commerce_settings)
-
-		# test results if show price is enabled
-		self.assertEqual(len(recommended_items), 1)
-		self.assertTrue(bool(recommended_items[0].get("price_info")))  # price fetched
-
-		# price hidden from guests
-		frappe.set_user("Administrator")
-		setup_e_commerce_settings({"hide_price_for_guest": 1})
-		frappe.set_user("Guest")
-
-		frappe.local.shopping_cart_settings = None
-		e_commerce_settings = get_shopping_cart_settings()
-		recommended_items = web_item.get_recommended_items(e_commerce_settings)
-
-		# test results if show price is enabled
-		self.assertEqual(len(recommended_items), 1)
-		self.assertFalse(bool(recommended_items[0].get("price_info")))  # price fetched
-
-		# tear down
-		frappe.set_user("Administrator")
-		web_item.delete()
-		recommended_web_item.delete()
-		frappe.get_cached_doc("Item", "Test Mobile Phone 1").delete()
-
-
-def create_regular_web_item(item_code=None, item_args=None, web_args=None):
-	"Create Regular Item and Website Item."
-	item_code = item_code or "Test Mobile Phone"
-	item = make_item(item_code, properties=item_args)
-
-	if not frappe.db.exists("Website Item", {"item_code": item_code}):
-		web_item = make_website_item(item, save=False)
-		if web_args:
-			web_item.update(web_args)
-		web_item.save()
-	else:
-		web_item = frappe.get_cached_doc("Website Item", {"item_code": item_code})
-
-	return web_item
-
-
-def make_web_item_price(**kwargs):
-	item_code = kwargs.get("item_code")
-	if not item_code:
-		return
-
-	if not frappe.db.exists("Item Price", {"item_code": item_code}):
-		item_price = frappe.get_doc(
-			{
-				"doctype": "Item Price",
-				"item_code": item_code,
-				"price_list": kwargs.get("price_list") or "_Test Price List India",
-				"price_list_rate": kwargs.get("price_list_rate") or 1000,
-			}
-		)
-		item_price.insert()
-	else:
-		item_price = frappe.get_cached_doc("Item Price", {"item_code": item_code})
-
-	return item_price
-
-
-def make_web_pricing_rule(**kwargs):
-	title = kwargs.get("title")
-	if not title:
-		return
-
-	if not frappe.db.exists("Pricing Rule", title):
-		pricing_rule = frappe.get_doc(
-			{
-				"doctype": "Pricing Rule",
-				"title": title,
-				"apply_on": kwargs.get("apply_on") or "Item Code",
-				"items": [{"item_code": kwargs.get("item_code")}],
-				"selling": kwargs.get("selling") or 0,
-				"buying": kwargs.get("buying") or 0,
-				"rate_or_discount": kwargs.get("rate_or_discount") or "Discount Percentage",
-				"discount_percentage": kwargs.get("discount_percentage") or 10,
-				"company": kwargs.get("company") or "_Test Company",
-				"currency": kwargs.get("currency") or "INR",
-				"for_price_list": kwargs.get("price_list") or "_Test Price List India",
-				"applicable_for": kwargs.get("applicable_for") or "",
-				"customer": kwargs.get("customer") or "",
-			}
-		)
-		pricing_rule.insert()
-	else:
-		pricing_rule = frappe.get_doc("Pricing Rule", {"title": title})
-
-	return pricing_rule
-
-
-def create_user_and_customer_if_not_exists(email, first_name=None):
-	if frappe.db.exists("User", email):
-		return
-
-	frappe.get_doc(
-		{
-			"doctype": "User",
-			"user_type": "Website User",
-			"email": email,
-			"send_welcome_email": 0,
-			"first_name": first_name or email.split("@")[0],
-		}
-	).insert(ignore_permissions=True)
-
-	contact = frappe.get_last_doc("Contact", filters={"email_id": email})
-	link = contact.append("links", {})
-	link.link_doctype = "Customer"
-	link.link_name = "_Test Customer"
-	link.link_title = "_Test Customer"
-	contact.save()
-
-
-test_dependencies = ["Price List", "Item Price", "Customer", "Contact", "Item"]
diff --git a/erpnext/e_commerce/doctype/website_item/website_item.js b/erpnext/e_commerce/doctype/website_item/website_item.js
deleted file mode 100644
index b6595cc..0000000
--- a/erpnext/e_commerce/doctype/website_item/website_item.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Website Item', {
-	onload: (frm) => {
-		// should never check Private
-		frm.fields_dict["website_image"].df.is_private = 0;
-	},
-
-	refresh: (frm) => {
-		frm.add_custom_button(__("Prices"), function() {
-			frappe.set_route("List", "Item Price", {"item_code": frm.doc.item_code});
-		}, __("View"));
-
-		frm.add_custom_button(__("Stock"), function() {
-			frappe.route_options = {
-				"item_code": frm.doc.item_code
-			};
-			frappe.set_route("query-report", "Stock Balance");
-		}, __("View"));
-
-		frm.add_custom_button(__("E Commerce Settings"), function() {
-			frappe.set_route("Form", "E Commerce Settings");
-		}, __("View"));
-	},
-
-	copy_from_item_group: (frm) => {
-		return frm.call({
-			doc: frm.doc,
-			method: "copy_specification_from_item_group"
-		});
-	},
-
-	set_meta_tags: (frm) => {
-		frappe.utils.set_meta_tag(frm.doc.route);
-	}
-});
diff --git a/erpnext/e_commerce/doctype/website_item/website_item.json b/erpnext/e_commerce/doctype/website_item/website_item.json
deleted file mode 100644
index 6f551a0..0000000
--- a/erpnext/e_commerce/doctype/website_item/website_item.json
+++ /dev/null
@@ -1,414 +0,0 @@
-{
- "actions": [],
- "allow_guest_to_view": 1,
- "allow_import": 1,
- "autoname": "naming_series",
- "creation": "2021-02-09 21:06:14.441698",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "naming_series",
-  "web_item_name",
-  "route",
-  "has_variants",
-  "variant_of",
-  "published",
-  "column_break_3",
-  "item_code",
-  "item_name",
-  "item_group",
-  "stock_uom",
-  "column_break_11",
-  "description",
-  "brand",
-  "display_section",
-  "website_image",
-  "website_image_alt",
-  "column_break_13",
-  "slideshow",
-  "thumbnail",
-  "stock_information_section",
-  "website_warehouse",
-  "column_break_24",
-  "on_backorder",
-  "section_break_17",
-  "short_description",
-  "web_long_description",
-  "column_break_27",
-  "website_specifications",
-  "copy_from_item_group",
-  "display_additional_information_section",
-  "show_tabbed_section",
-  "tabs",
-  "recommended_items_section",
-  "recommended_items",
-  "offers_section",
-  "offers",
-  "section_break_6",
-  "ranking",
-  "set_meta_tags",
-  "column_break_22",
-  "website_item_groups",
-  "advanced_display_section",
-  "website_content"
- ],
- "fields": [
-  {
-   "description": "Website display name",
-   "fetch_from": "item_code.item_name",
-   "fetch_if_empty": 1,
-   "fieldname": "web_item_name",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Website Item Name",
-   "reqd": 1
-  },
-  {
-   "fieldname": "column_break_3",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "item_code",
-   "fieldtype": "Link",
-   "label": "Item Code",
-   "options": "Item",
-   "read_only_depends_on": "eval:!doc.__islocal",
-   "reqd": 1
-  },
-  {
-   "fetch_from": "item_code.item_name",
-   "fieldname": "item_name",
-   "fieldtype": "Data",
-   "label": "Item Name",
-   "read_only": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "section_break_6",
-   "fieldtype": "Section Break",
-   "label": "Search and SEO"
-  },
-  {
-   "fieldname": "route",
-   "fieldtype": "Small Text",
-   "in_list_view": 1,
-   "label": "Route",
-   "no_copy": 1
-  },
-  {
-   "description": "Items with higher ranking will be shown higher",
-   "fieldname": "ranking",
-   "fieldtype": "Int",
-   "label": "Ranking"
-  },
-  {
-   "description": "Show a slideshow at the top of the page",
-   "fieldname": "slideshow",
-   "fieldtype": "Link",
-   "label": "Slideshow",
-   "options": "Website Slideshow"
-  },
-  {
-   "description": "Item Image (if not slideshow)",
-   "fieldname": "website_image",
-   "fieldtype": "Attach Image",
-   "hidden": 1,
-   "in_preview": 1,
-   "label": "Website Image",
-   "print_hide": 1
-  },
-  {
-   "description": "Image Alternative Text",
-   "fieldname": "website_image_alt",
-   "fieldtype": "Data",
-   "label": "Image Description"
-  },
-  {
-   "fieldname": "thumbnail",
-   "fieldtype": "Data",
-   "label": "Thumbnail",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_13",
-   "fieldtype": "Column Break"
-  },
-  {
-   "description": "Show Stock availability based on this warehouse. If the parent warehouse is selected, then the system will display the consolidated available quantity of all child warehouses.",
-   "fieldname": "website_warehouse",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "label": "Website Warehouse",
-   "options": "Warehouse"
-  },
-  {
-   "description": "List this Item in multiple groups on the website.",
-   "fieldname": "website_item_groups",
-   "fieldtype": "Table",
-   "label": "Website Item Groups",
-   "options": "Website Item Group"
-  },
-  {
-   "fieldname": "set_meta_tags",
-   "fieldtype": "Button",
-   "label": "Set Meta Tags"
-  },
-  {
-   "fieldname": "section_break_17",
-   "fieldtype": "Section Break",
-   "label": "Display Information"
-  },
-  {
-   "fieldname": "copy_from_item_group",
-   "fieldtype": "Button",
-   "label": "Copy From Item Group"
-  },
-  {
-   "fieldname": "website_specifications",
-   "fieldtype": "Table",
-   "label": "Website Specifications",
-   "options": "Item Website Specification"
-  },
-  {
-   "fieldname": "web_long_description",
-   "fieldtype": "Text Editor",
-   "label": "Website Description"
-  },
-  {
-   "description": "You can use any valid Bootstrap 4 markup in this field. It will be shown on your Item Page.",
-   "fieldname": "website_content",
-   "fieldtype": "HTML Editor",
-   "label": "Website Content"
-  },
-  {
-   "fetch_from": "item_code.item_group",
-   "fieldname": "item_group",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Item Group",
-   "options": "Item Group",
-   "read_only": 1,
-   "search_index": 1
-  },
-  {
-   "default": "1",
-   "fieldname": "published",
-   "fieldtype": "Check",
-   "label": "Published"
-  },
-  {
-   "default": "0",
-   "depends_on": "has_variants",
-   "fetch_from": "item_code.has_variants",
-   "fieldname": "has_variants",
-   "fieldtype": "Check",
-   "in_standard_filter": 1,
-   "label": "Has Variants",
-   "no_copy": 1,
-   "read_only": 1
-  },
-  {
-   "depends_on": "variant_of",
-   "fetch_from": "item_code.variant_of",
-   "fieldname": "variant_of",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "in_standard_filter": 1,
-   "label": "Variant Of",
-   "options": "Item",
-   "read_only": 1,
-   "search_index": 1,
-   "set_only_once": 1
-  },
-  {
-   "fetch_from": "item_code.stock_uom",
-   "fieldname": "stock_uom",
-   "fieldtype": "Link",
-   "label": "Stock UOM",
-   "options": "UOM",
-   "read_only": 1
-  },
-  {
-   "depends_on": "brand",
-   "fetch_from": "item_code.brand",
-   "fieldname": "brand",
-   "fieldtype": "Link",
-   "label": "Brand",
-   "options": "Brand",
-   "search_index": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "advanced_display_section",
-   "fieldtype": "Section Break",
-   "label": "Advanced Display Content"
-  },
-  {
-   "fieldname": "display_section",
-   "fieldtype": "Section Break",
-   "label": "Display Images"
-  },
-  {
-   "fieldname": "column_break_27",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "column_break_22",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fetch_from": "item_code.description",
-   "fieldname": "description",
-   "fieldtype": "Text Editor",
-   "label": "Item Description",
-   "read_only": 1
-  },
-  {
-   "default": "WEB-ITM-.####",
-   "fieldname": "naming_series",
-   "fieldtype": "Select",
-   "hidden": 1,
-   "label": "Naming Series",
-   "no_copy": 1,
-   "options": "WEB-ITM-.####",
-   "print_hide": 1
-  },
-  {
-   "fieldname": "display_additional_information_section",
-   "fieldtype": "Section Break",
-   "label": "Display Additional Information"
-  },
-  {
-   "depends_on": "show_tabbed_section",
-   "fieldname": "tabs",
-   "fieldtype": "Table",
-   "label": "Tabs",
-   "options": "Website Item Tabbed Section"
-  },
-  {
-   "default": "0",
-   "fieldname": "show_tabbed_section",
-   "fieldtype": "Check",
-   "label": "Add Section with Tabs"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "offers_section",
-   "fieldtype": "Section Break",
-   "label": "Offers"
-  },
-  {
-   "fieldname": "offers",
-   "fieldtype": "Table",
-   "label": "Offers to Display",
-   "options": "Website Offer"
-  },
-  {
-   "fieldname": "column_break_11",
-   "fieldtype": "Column Break"
-  },
-  {
-   "description": "Short Description for List View",
-   "fieldname": "short_description",
-   "fieldtype": "Small Text",
-   "label": "Short Website Description"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "recommended_items_section",
-   "fieldtype": "Section Break",
-   "label": "Recommended Items"
-  },
-  {
-   "fieldname": "recommended_items",
-   "fieldtype": "Table",
-   "label": "Recommended/Similar Items",
-   "options": "Recommended Items"
-  },
-  {
-   "fieldname": "stock_information_section",
-   "fieldtype": "Section Break",
-   "label": "Stock Information"
-  },
-  {
-   "fieldname": "column_break_24",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "0",
-   "description": "Indicate that Item is available on backorder and not usually pre-stocked",
-   "fieldname": "on_backorder",
-   "fieldtype": "Check",
-   "label": "On Backorder"
-  }
- ],
- "has_web_view": 1,
- "image_field": "website_image",
- "index_web_pages_for_search": 1,
- "links": [],
- "make_attachments_public": 1,
- "modified": "2023-09-12 14:19:22.822689",
- "modified_by": "Administrator",
- "module": "E-commerce",
- "name": "Website Item",
- "naming_rule": "Expression (old style)",
- "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": "Website Manager",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Stock User",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Stock Manager",
-   "share": 1,
-   "write": 1
-  }
- ],
- "search_fields": "web_item_name, item_code, item_group",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "states": [],
- "title_field": "web_item_name",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/e_commerce/doctype/website_item/website_item.py b/erpnext/e_commerce/doctype/website_item/website_item.py
deleted file mode 100644
index 81b8eca..0000000
--- a/erpnext/e_commerce/doctype/website_item/website_item.py
+++ /dev/null
@@ -1,469 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-import json
-from typing import TYPE_CHECKING, List, Union
-
-if TYPE_CHECKING:
-	from erpnext.stock.doctype.item.item import Item
-
-import frappe
-from frappe import _
-from frappe.utils import cint, cstr, flt, random_string
-from frappe.website.doctype.website_slideshow.website_slideshow import get_slideshow
-from frappe.website.website_generator import WebsiteGenerator
-
-from erpnext.e_commerce.doctype.item_review.item_review import get_item_reviews
-from erpnext.e_commerce.redisearch_utils import (
-	delete_item_from_index,
-	insert_item_to_index,
-	update_index_for_item,
-)
-from erpnext.e_commerce.shopping_cart.cart import _set_price_list
-from erpnext.setup.doctype.item_group.item_group import (
-	get_parent_item_groups,
-	invalidate_cache_for,
-)
-from erpnext.utilities.product import get_price
-
-
-class WebsiteItem(WebsiteGenerator):
-	website = frappe._dict(
-		page_title_field="web_item_name",
-		condition_field="published",
-		template="templates/generators/item/item.html",
-		no_cache=1,
-	)
-
-	def autoname(self):
-		# use naming series to accomodate items with same name (different item code)
-		from frappe.model.naming import get_default_naming_series, make_autoname
-
-		naming_series = get_default_naming_series("Website Item")
-		if not self.name and naming_series:
-			self.name = make_autoname(naming_series, doc=self)
-
-	def onload(self):
-		super(WebsiteItem, self).onload()
-
-	def validate(self):
-		super(WebsiteItem, self).validate()
-
-		if not self.item_code:
-			frappe.throw(_("Item Code is required"), title=_("Mandatory"))
-
-		self.validate_duplicate_website_item()
-		self.validate_website_image()
-		self.make_thumbnail()
-		self.publish_unpublish_desk_item(publish=True)
-
-		if not self.get("__islocal"):
-			wig = frappe.qb.DocType("Website Item Group")
-			query = (
-				frappe.qb.from_(wig)
-				.select(wig.item_group)
-				.where(
-					(wig.parentfield == "website_item_groups")
-					& (wig.parenttype == "Website Item")
-					& (wig.parent == self.name)
-				)
-			)
-			result = query.run(as_list=True)
-
-			self.old_website_item_groups = [x[0] for x in result]
-
-	def on_update(self):
-		invalidate_cache_for_web_item(self)
-		self.update_template_item()
-
-	def on_trash(self):
-		super(WebsiteItem, self).on_trash()
-		delete_item_from_index(self)
-		self.publish_unpublish_desk_item(publish=False)
-
-	def validate_duplicate_website_item(self):
-		existing_web_item = frappe.db.exists("Website Item", {"item_code": self.item_code})
-		if existing_web_item and existing_web_item != self.name:
-			message = _("Website Item already exists against Item {0}").format(frappe.bold(self.item_code))
-			frappe.throw(message, title=_("Already Published"))
-
-	def publish_unpublish_desk_item(self, publish=True):
-		if frappe.db.get_value("Item", self.item_code, "published_in_website") and publish:
-			return  # if already published don't publish again
-		frappe.db.set_value("Item", self.item_code, "published_in_website", publish)
-
-	def make_route(self):
-		"""Called from set_route in WebsiteGenerator."""
-		if not self.route:
-			return (
-				cstr(frappe.db.get_value("Item Group", self.item_group, "route"))
-				+ "/"
-				+ self.scrub((self.item_name if self.item_name else self.item_code) + "-" + random_string(5))
-			)
-
-	def update_template_item(self):
-		"""Publish Template Item if Variant is published."""
-		if self.variant_of:
-			if self.published:
-				# show template
-				template_item = frappe.get_doc("Item", self.variant_of)
-
-				if not template_item.published_in_website:
-					template_item.flags.ignore_permissions = True
-					make_website_item(template_item)
-
-	def validate_website_image(self):
-		if frappe.flags.in_import:
-			return
-
-		"""Validate if the website image is a public file"""
-		if not self.website_image:
-			return
-
-		# find if website image url exists as public
-		file_doc = frappe.get_all(
-			"File",
-			filters={"file_url": self.website_image},
-			fields=["name", "is_private"],
-			order_by="is_private asc",
-			limit_page_length=1,
-		)
-
-		if file_doc:
-			file_doc = file_doc[0]
-
-		if not file_doc:
-			frappe.msgprint(
-				_("Website Image {0} attached to Item {1} cannot be found").format(
-					self.website_image, self.name
-				)
-			)
-
-			self.website_image = None
-
-		elif file_doc.is_private:
-			frappe.msgprint(_("Website Image should be a public file or website URL"))
-
-			self.website_image = None
-
-	def make_thumbnail(self):
-		"""Make a thumbnail of `website_image`"""
-		if frappe.flags.in_import or frappe.flags.in_migrate:
-			return
-
-		import requests.exceptions
-
-		db_website_image = frappe.db.get_value(self.doctype, self.name, "website_image")
-		if not self.is_new() and self.website_image != db_website_image:
-			self.thumbnail = None
-
-		if self.website_image and not self.thumbnail:
-			file_doc = None
-
-			try:
-				file_doc = frappe.get_doc(
-					"File",
-					{
-						"file_url": self.website_image,
-						"attached_to_doctype": "Website Item",
-						"attached_to_name": self.name,
-					},
-				)
-			except frappe.DoesNotExistError:
-				pass
-				# cleanup
-				frappe.local.message_log.pop()
-
-			except requests.exceptions.HTTPError:
-				frappe.msgprint(_("Warning: Invalid attachment {0}").format(self.website_image))
-				self.website_image = None
-
-			except requests.exceptions.SSLError:
-				frappe.msgprint(
-					_("Warning: Invalid SSL certificate on attachment {0}").format(self.website_image)
-				)
-				self.website_image = None
-
-			# for CSV import
-			if self.website_image and not file_doc:
-				try:
-					file_doc = frappe.get_doc(
-						{
-							"doctype": "File",
-							"file_url": self.website_image,
-							"attached_to_doctype": "Website Item",
-							"attached_to_name": self.name,
-						}
-					).save()
-
-				except IOError:
-					self.website_image = None
-
-			if file_doc:
-				if not file_doc.thumbnail_url:
-					file_doc.make_thumbnail()
-
-				self.thumbnail = file_doc.thumbnail_url
-
-	def get_context(self, context):
-		context.show_search = True
-		context.search_link = "/search"
-		context.body_class = "product-page"
-
-		context.parents = get_parent_item_groups(self.item_group, from_item=True)  # breadcumbs
-		self.attributes = frappe.get_all(
-			"Item Variant Attribute",
-			fields=["attribute", "attribute_value"],
-			filters={"parent": self.item_code},
-		)
-
-		if self.slideshow:
-			context.update(get_slideshow(self))
-
-		self.set_metatags(context)
-		self.set_shopping_cart_data(context)
-
-		settings = context.shopping_cart.cart_settings
-
-		self.get_product_details_section(context)
-
-		if settings.get("enable_reviews"):
-			reviews_data = get_item_reviews(self.name)
-			context.update(reviews_data)
-			context.reviews = context.reviews[:4]
-
-		context.wished = False
-		if frappe.db.exists(
-			"Wishlist Item", {"item_code": self.item_code, "parent": frappe.session.user}
-		):
-			context.wished = True
-
-		context.user_is_customer = check_if_user_is_customer()
-
-		context.recommended_items = None
-		if settings and settings.enable_recommendations:
-			context.recommended_items = self.get_recommended_items(settings)
-
-		return context
-
-	def set_selected_attributes(self, variants, context, attribute_values_available):
-		for variant in variants:
-			variant.attributes = frappe.get_all(
-				"Item Variant Attribute",
-				filters={"parent": variant.name},
-				fields=["attribute", "attribute_value as value"],
-			)
-
-			# make an attribute-value map for easier access in templates
-			variant.attribute_map = frappe._dict(
-				{attr.attribute: attr.value for attr in variant.attributes}
-			)
-
-			for attr in variant.attributes:
-				values = attribute_values_available.setdefault(attr.attribute, [])
-				if attr.value not in values:
-					values.append(attr.value)
-
-				if variant.name == context.variant.name:
-					context.selected_attributes[attr.attribute] = attr.value
-
-	def set_attribute_values(self, attributes, context, attribute_values_available):
-		for attr in attributes:
-			values = context.attribute_values.setdefault(attr.attribute, [])
-
-			if cint(frappe.db.get_value("Item Attribute", attr.attribute, "numeric_values")):
-				for val in sorted(attribute_values_available.get(attr.attribute, []), key=flt):
-					values.append(val)
-			else:
-				# get list of values defined (for sequence)
-				for attr_value in frappe.db.get_all(
-					"Item Attribute Value",
-					fields=["attribute_value"],
-					filters={"parent": attr.attribute},
-					order_by="idx asc",
-				):
-
-					if attr_value.attribute_value in attribute_values_available.get(attr.attribute, []):
-						values.append(attr_value.attribute_value)
-
-	def set_metatags(self, context):
-		context.metatags = frappe._dict({})
-
-		safe_description = frappe.utils.to_markdown(self.description)
-
-		context.metatags.url = frappe.utils.get_url() + "/" + context.route
-
-		if context.website_image:
-			if context.website_image.startswith("http"):
-				url = context.website_image
-			else:
-				url = frappe.utils.get_url() + context.website_image
-			context.metatags.image = url
-
-		context.metatags.description = safe_description[:300]
-
-		context.metatags.title = self.web_item_name or self.item_name or self.item_code
-
-		context.metatags["og:type"] = "product"
-		context.metatags["og:site_name"] = "ERPNext"
-
-	def set_shopping_cart_data(self, context):
-		from erpnext.e_commerce.shopping_cart.product_info import get_product_info_for_website
-
-		context.shopping_cart = get_product_info_for_website(
-			self.item_code, skip_quotation_creation=True
-		)
-
-	@frappe.whitelist()
-	def copy_specification_from_item_group(self):
-		self.set("website_specifications", [])
-		if self.item_group:
-			for label, desc in frappe.db.get_values(
-				"Item Website Specification", {"parent": self.item_group}, ["label", "description"]
-			):
-				row = self.append("website_specifications")
-				row.label = label
-				row.description = desc
-
-	def get_product_details_section(self, context):
-		"""Get section with tabs or website specifications."""
-		context.show_tabs = self.show_tabbed_section
-		if self.show_tabbed_section and (self.tabs or self.website_specifications):
-			context.tabs = self.get_tabs()
-		else:
-			context.website_specifications = self.website_specifications
-
-	def get_tabs(self):
-		tab_values = {}
-		tab_values["tab_1_title"] = "Product Details"
-		tab_values["tab_1_content"] = frappe.render_template(
-			"templates/generators/item/item_specifications.html",
-			{"website_specifications": self.website_specifications, "show_tabs": self.show_tabbed_section},
-		)
-
-		for row in self.tabs:
-			tab_values[f"tab_{row.idx + 1}_title"] = _(row.label)
-			tab_values[f"tab_{row.idx + 1}_content"] = row.content
-
-		return tab_values
-
-	def get_recommended_items(self, settings):
-		ri = frappe.qb.DocType("Recommended Items")
-		wi = frappe.qb.DocType("Website Item")
-
-		query = (
-			frappe.qb.from_(ri)
-			.join(wi)
-			.on(ri.item_code == wi.item_code)
-			.select(ri.item_code, ri.route, ri.website_item_name, ri.website_item_thumbnail)
-			.where((ri.parent == self.name) & (wi.published == 1))
-			.orderby(ri.idx)
-		)
-		items = query.run(as_dict=True)
-
-		if settings.show_price:
-			is_guest = frappe.session.user == "Guest"
-			# Show Price if logged in.
-			# If not logged in and price is hidden for guest, skip price fetch.
-			if is_guest and settings.hide_price_for_guest:
-				return items
-
-			selling_price_list = _set_price_list(settings, None)
-			for item in items:
-				item.price_info = get_price(
-					item.item_code, selling_price_list, settings.default_customer_group, settings.company
-				)
-
-		return items
-
-
-def invalidate_cache_for_web_item(doc):
-	"""Invalidate Website Item Group cache and rebuild ItemVariantsCacheManager."""
-	from erpnext.stock.doctype.item.item import invalidate_item_variants_cache_for_website
-
-	invalidate_cache_for(doc, doc.item_group)
-
-	website_item_groups = list(
-		set(
-			(doc.get("old_website_item_groups") or [])
-			+ [d.item_group for d in doc.get({"doctype": "Website Item Group"}) if d.item_group]
-		)
-	)
-
-	for item_group in website_item_groups:
-		invalidate_cache_for(doc, item_group)
-
-	# Update Search Cache
-	update_index_for_item(doc)
-
-	invalidate_item_variants_cache_for_website(doc)
-
-
-def on_doctype_update():
-	# since route is a Text column, it needs a length for indexing
-	frappe.db.add_index("Website Item", ["route(500)"])
-
-
-def check_if_user_is_customer(user=None):
-	from frappe.contacts.doctype.contact.contact import get_contact_name
-
-	if not user:
-		user = frappe.session.user
-
-	contact_name = get_contact_name(user)
-	customer = None
-
-	if contact_name:
-		contact = frappe.get_doc("Contact", contact_name)
-		for link in contact.links:
-			if link.link_doctype == "Customer":
-				customer = link.link_name
-				break
-
-	return True if customer else False
-
-
-@frappe.whitelist()
-def make_website_item(doc: "Item", save: bool = True) -> Union["WebsiteItem", List[str]]:
-	"Make Website Item from Item. Used via Form UI or patch."
-
-	if not doc:
-		return
-
-	if isinstance(doc, str):
-		doc = json.loads(doc)
-
-	if frappe.db.exists("Website Item", {"item_code": doc.get("item_code")}):
-		message = _("Website Item already exists against {0}").format(frappe.bold(doc.get("item_code")))
-		frappe.throw(message, title=_("Already Published"))
-
-	website_item = frappe.new_doc("Website Item")
-	website_item.web_item_name = doc.get("item_name")
-
-	fields_to_map = [
-		"item_code",
-		"item_name",
-		"item_group",
-		"stock_uom",
-		"brand",
-		"has_variants",
-		"variant_of",
-		"description",
-	]
-	for field in fields_to_map:
-		website_item.update({field: doc.get(field)})
-
-	# Needed for publishing/mapping via Form UI only
-	if not frappe.flags.in_migrate and (doc.get("image") and not website_item.website_image):
-		website_item.website_image = doc.get("image")
-
-	if not save:
-		return website_item
-
-	website_item.save()
-
-	# Add to search cache
-	insert_item_to_index(website_item)
-
-	return [website_item.name, website_item.web_item_name]
diff --git a/erpnext/e_commerce/doctype/website_item/website_item_list.js b/erpnext/e_commerce/doctype/website_item/website_item_list.js
deleted file mode 100644
index b9dd921..0000000
--- a/erpnext/e_commerce/doctype/website_item/website_item_list.js
+++ /dev/null
@@ -1,20 +0,0 @@
-frappe.listview_settings['Website Item'] = {
-	add_fields: ["item_name", "web_item_name", "published", "website_image", "has_variants", "variant_of"],
-	filters: [["published", "=", "1"]],
-
-	get_indicator: function(doc) {
-		if (doc.has_variants && doc.published) {
-			return [__("Template"), "orange", "has_variants,=,Yes|published,=,1"];
-		} else if (doc.has_variants && !doc.published) {
-			return [__("Template"), "grey", "has_variants,=,Yes|published,=,0"];
-		} else if (doc.variant_of  && doc.published) {
-			return [__("Variant"), "blue", "published,=,1|variant_of,=," + doc.variant_of];
-		} else if (doc.variant_of  && !doc.published) {
-			return [__("Variant"), "grey", "published,=,0|variant_of,=," + doc.variant_of];
-		} else if (doc.published) {
-			return [__("Published"), "green", "published,=,1"];
-		} else {
-			return [__("Not Published"), "grey", "published,=,0"];
-		}
-	}
-};
\ No newline at end of file
diff --git a/erpnext/e_commerce/doctype/website_item_tabbed_section/__init__.py b/erpnext/e_commerce/doctype/website_item_tabbed_section/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/doctype/website_item_tabbed_section/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/doctype/website_item_tabbed_section/website_item_tabbed_section.json b/erpnext/e_commerce/doctype/website_item_tabbed_section/website_item_tabbed_section.json
deleted file mode 100644
index 6601dd8..0000000
--- a/erpnext/e_commerce/doctype/website_item_tabbed_section/website_item_tabbed_section.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- "actions": [],
- "creation": "2021-03-18 20:32:15.321402",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "label",
-  "content"
- ],
- "fields": [
-  {
-   "fieldname": "label",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Label"
-  },
-  {
-   "fieldname": "content",
-   "fieldtype": "HTML Editor",
-   "in_list_view": 1,
-   "label": "Content"
-  }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2021-03-18 20:35:26.991192",
- "modified_by": "Administrator",
- "module": "E-commerce",
- "name": "Website Item Tabbed Section",
- "owner": "Administrator",
- "permissions": [],
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/e_commerce/doctype/website_item_tabbed_section/website_item_tabbed_section.py b/erpnext/e_commerce/doctype/website_item_tabbed_section/website_item_tabbed_section.py
deleted file mode 100644
index 91148b8..0000000
--- a/erpnext/e_commerce/doctype/website_item_tabbed_section/website_item_tabbed_section.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# 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 WebsiteItemTabbedSection(Document):
-	pass
diff --git a/erpnext/e_commerce/doctype/website_offer/__init__.py b/erpnext/e_commerce/doctype/website_offer/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/doctype/website_offer/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/doctype/website_offer/website_offer.json b/erpnext/e_commerce/doctype/website_offer/website_offer.json
deleted file mode 100644
index 627d548..0000000
--- a/erpnext/e_commerce/doctype/website_offer/website_offer.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "actions": [],
- "creation": "2021-04-21 13:37:14.162162",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "offer_title",
-  "offer_subtitle",
-  "offer_details"
- ],
- "fields": [
-  {
-   "fieldname": "offer_title",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Offer Title"
-  },
-  {
-   "fieldname": "offer_subtitle",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Offer Subtitle"
-  },
-  {
-   "fieldname": "offer_details",
-   "fieldtype": "Text Editor",
-   "label": "Offer Details"
-  }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2021-04-21 13:56:04.660331",
- "modified_by": "Administrator",
- "module": "E-commerce",
- "name": "Website Offer",
- "owner": "Administrator",
- "permissions": [],
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/e_commerce/doctype/website_offer/website_offer.py b/erpnext/e_commerce/doctype/website_offer/website_offer.py
deleted file mode 100644
index 8c92f75..0000000
--- a/erpnext/e_commerce/doctype/website_offer/website_offer.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# -*- coding: utf-8 -*-
-# 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 WebsiteOffer(Document):
-	pass
-
-
-@frappe.whitelist(allow_guest=True)
-def get_offer_details(offer_id):
-	return frappe.db.get_value("Website Offer", {"name": offer_id}, ["offer_details"])
diff --git a/erpnext/e_commerce/doctype/wishlist/__init__.py b/erpnext/e_commerce/doctype/wishlist/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/doctype/wishlist/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/doctype/wishlist/test_wishlist.py b/erpnext/e_commerce/doctype/wishlist/test_wishlist.py
deleted file mode 100644
index 9d27126..0000000
--- a/erpnext/e_commerce/doctype/wishlist/test_wishlist.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-import unittest
-
-import frappe
-from frappe.core.doctype.user_permission.test_user_permission import create_user
-
-from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
-from erpnext.e_commerce.doctype.wishlist.wishlist import add_to_wishlist, remove_from_wishlist
-from erpnext.stock.doctype.item.test_item import make_item
-
-
-class TestWishlist(unittest.TestCase):
-	def setUp(self):
-		item = make_item("Test Phone Series X")
-		if not frappe.db.exists("Website Item", {"item_code": "Test Phone Series X"}):
-			make_website_item(item, save=True)
-
-		item = make_item("Test Phone Series Y")
-		if not frappe.db.exists("Website Item", {"item_code": "Test Phone Series Y"}):
-			make_website_item(item, save=True)
-
-	def tearDown(self):
-		frappe.get_cached_doc("Website Item", {"item_code": "Test Phone Series X"}).delete()
-		frappe.get_cached_doc("Website Item", {"item_code": "Test Phone Series Y"}).delete()
-		frappe.get_cached_doc("Item", "Test Phone Series X").delete()
-		frappe.get_cached_doc("Item", "Test Phone Series Y").delete()
-
-	def test_add_remove_items_in_wishlist(self):
-		"Check if items are added and removed from user's wishlist."
-		# add first item
-		add_to_wishlist("Test Phone Series X")
-
-		# check if wishlist was created and item was added
-		self.assertTrue(frappe.db.exists("Wishlist", {"user": frappe.session.user}))
-		self.assertTrue(
-			frappe.db.exists(
-				"Wishlist Item", {"item_code": "Test Phone Series X", "parent": frappe.session.user}
-			)
-		)
-
-		# add second item to wishlist
-		add_to_wishlist("Test Phone Series Y")
-		wishlist_length = frappe.db.get_value(
-			"Wishlist Item", {"parent": frappe.session.user}, "count(*)"
-		)
-		self.assertEqual(wishlist_length, 2)
-
-		remove_from_wishlist("Test Phone Series X")
-		remove_from_wishlist("Test Phone Series Y")
-
-		wishlist_length = frappe.db.get_value(
-			"Wishlist Item", {"parent": frappe.session.user}, "count(*)"
-		)
-		self.assertIsNone(frappe.db.exists("Wishlist Item", {"parent": frappe.session.user}))
-		self.assertEqual(wishlist_length, 0)
-
-		# tear down
-		frappe.get_doc("Wishlist", {"user": frappe.session.user}).delete()
-
-	def test_add_remove_in_wishlist_multiple_users(self):
-		"Check if items are added and removed from the correct user's wishlist."
-		test_user = create_user("test_reviewer@example.com", "Customer")
-		test_user_1 = create_user("test_reviewer_1@example.com", "Customer")
-
-		# add to wishlist for first user
-		frappe.set_user(test_user.name)
-		add_to_wishlist("Test Phone Series X")
-
-		# add to wishlist for second user
-		frappe.set_user(test_user_1.name)
-		add_to_wishlist("Test Phone Series X")
-
-		# check wishlist and its content for users
-		self.assertTrue(frappe.db.exists("Wishlist", {"user": test_user.name}))
-		self.assertTrue(
-			frappe.db.exists(
-				"Wishlist Item", {"item_code": "Test Phone Series X", "parent": test_user.name}
-			)
-		)
-
-		self.assertTrue(frappe.db.exists("Wishlist", {"user": test_user_1.name}))
-		self.assertTrue(
-			frappe.db.exists(
-				"Wishlist Item", {"item_code": "Test Phone Series X", "parent": test_user_1.name}
-			)
-		)
-
-		# remove item for second user
-		remove_from_wishlist("Test Phone Series X")
-
-		# make sure item was removed for second user and not first
-		self.assertFalse(
-			frappe.db.exists(
-				"Wishlist Item", {"item_code": "Test Phone Series X", "parent": test_user_1.name}
-			)
-		)
-		self.assertTrue(
-			frappe.db.exists(
-				"Wishlist Item", {"item_code": "Test Phone Series X", "parent": test_user.name}
-			)
-		)
-
-		# remove item for first user
-		frappe.set_user(test_user.name)
-		remove_from_wishlist("Test Phone Series X")
-		self.assertFalse(
-			frappe.db.exists(
-				"Wishlist Item", {"item_code": "Test Phone Series X", "parent": test_user.name}
-			)
-		)
-
-		# tear down
-		frappe.set_user("Administrator")
-		frappe.get_doc("Wishlist", {"user": test_user.name}).delete()
-		frappe.get_doc("Wishlist", {"user": test_user_1.name}).delete()
diff --git a/erpnext/e_commerce/doctype/wishlist/wishlist.js b/erpnext/e_commerce/doctype/wishlist/wishlist.js
deleted file mode 100644
index d96e552..0000000
--- a/erpnext/e_commerce/doctype/wishlist/wishlist.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('Wishlist', {
-	// refresh: function(frm) {
-
-	// }
-});
diff --git a/erpnext/e_commerce/doctype/wishlist/wishlist.json b/erpnext/e_commerce/doctype/wishlist/wishlist.json
deleted file mode 100644
index 922924e..0000000
--- a/erpnext/e_commerce/doctype/wishlist/wishlist.json
+++ /dev/null
@@ -1,65 +0,0 @@
-{
- "actions": [],
- "autoname": "field:user",
- "creation": "2021-03-10 18:52:28.769126",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "user",
-  "section_break_2",
-  "items"
- ],
- "fields": [
-  {
-   "fieldname": "user",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "User",
-   "options": "User",
-   "reqd": 1,
-   "unique": 1
-  },
-  {
-   "fieldname": "section_break_2",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "items",
-   "fieldtype": "Table",
-   "label": "Items",
-   "options": "Wishlist Item"
-  }
- ],
- "in_create": 1,
- "index_web_pages_for_search": 1,
- "links": [],
- "modified": "2021-07-08 13:11:21.693956",
- "modified_by": "Administrator",
- "module": "E-commerce",
- "name": "Wishlist",
- "owner": "Administrator",
- "permissions": [
-  {
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "System Manager",
-   "share": 1
-  },
-  {
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Website Manager",
-   "share": 1
-  }
- ],
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/e_commerce/doctype/wishlist/wishlist.py b/erpnext/e_commerce/doctype/wishlist/wishlist.py
deleted file mode 100644
index eb74027..0000000
--- a/erpnext/e_commerce/doctype/wishlist/wishlist.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# -*- coding: utf-8 -*-
-# 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 Wishlist(Document):
-	pass
-
-
-@frappe.whitelist()
-def add_to_wishlist(item_code):
-	"""Insert Item into wishlist."""
-
-	if frappe.db.exists("Wishlist Item", {"item_code": item_code, "parent": frappe.session.user}):
-		return
-
-	web_item_data = frappe.db.get_value(
-		"Website Item",
-		{"item_code": item_code},
-		[
-			"website_image",
-			"website_warehouse",
-			"name",
-			"web_item_name",
-			"item_name",
-			"item_group",
-			"route",
-		],
-		as_dict=1,
-	)
-
-	wished_item_dict = {
-		"item_code": item_code,
-		"item_name": web_item_data.get("item_name"),
-		"item_group": web_item_data.get("item_group"),
-		"website_item": web_item_data.get("name"),
-		"web_item_name": web_item_data.get("web_item_name"),
-		"image": web_item_data.get("website_image"),
-		"warehouse": web_item_data.get("website_warehouse"),
-		"route": web_item_data.get("route"),
-	}
-
-	if not frappe.db.exists("Wishlist", frappe.session.user):
-		# initialise wishlist
-		wishlist = frappe.get_doc({"doctype": "Wishlist"})
-		wishlist.user = frappe.session.user
-		wishlist.append("items", wished_item_dict)
-		wishlist.save(ignore_permissions=True)
-	else:
-		wishlist = frappe.get_doc("Wishlist", frappe.session.user)
-		item = wishlist.append("items", wished_item_dict)
-		item.db_insert()
-
-	if hasattr(frappe.local, "cookie_manager"):
-		frappe.local.cookie_manager.set_cookie("wish_count", str(len(wishlist.items)))
-
-
-@frappe.whitelist()
-def remove_from_wishlist(item_code):
-	if frappe.db.exists("Wishlist Item", {"item_code": item_code, "parent": frappe.session.user}):
-		frappe.db.delete("Wishlist Item", {"item_code": item_code, "parent": frappe.session.user})
-		frappe.db.commit()  # nosemgrep
-
-		wishlist_items = frappe.db.get_values("Wishlist Item", filters={"parent": frappe.session.user})
-
-		if hasattr(frappe.local, "cookie_manager"):
-			frappe.local.cookie_manager.set_cookie("wish_count", str(len(wishlist_items)))
diff --git a/erpnext/e_commerce/doctype/wishlist_item/__init__.py b/erpnext/e_commerce/doctype/wishlist_item/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/doctype/wishlist_item/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/doctype/wishlist_item/wishlist_item.json b/erpnext/e_commerce/doctype/wishlist_item/wishlist_item.json
deleted file mode 100644
index c0414a7..0000000
--- a/erpnext/e_commerce/doctype/wishlist_item/wishlist_item.json
+++ /dev/null
@@ -1,147 +0,0 @@
-{
- "actions": [],
- "creation": "2021-03-10 19:03:00.662714",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "item_code",
-  "website_item",
-  "web_item_name",
-  "column_break_3",
-  "item_name",
-  "item_group",
-  "item_details_section",
-  "description",
-  "column_break_7",
-  "route",
-  "image",
-  "image_view",
-  "section_break_8",
-  "warehouse_section",
-  "warehouse"
- ],
- "fields": [
-  {
-   "fetch_from": "website_item.item_code",
-   "fetch_if_empty": 1,
-   "fieldname": "item_code",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Item Code",
-   "options": "Item",
-   "reqd": 1
-  },
-  {
-   "fieldname": "website_item",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Website Item",
-   "options": "Website Item",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_3",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fetch_from": "item_code.item_name",
-   "fetch_if_empty": 1,
-   "fieldname": "item_name",
-   "fieldtype": "Data",
-   "label": "Item Name",
-   "read_only": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "item_details_section",
-   "fieldtype": "Section Break",
-   "label": "Item Details",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "item_code.description",
-   "fetch_if_empty": 1,
-   "fieldname": "description",
-   "fieldtype": "Text Editor",
-   "label": "Description",
-   "read_only": 1
-  },
-  {
-   "fieldname": "column_break_7",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fetch_from": "item_code.image",
-   "fetch_if_empty": 1,
-   "fieldname": "image",
-   "fieldtype": "Attach",
-   "hidden": 1,
-   "label": "Image"
-  },
-  {
-   "fetch_from": "item_code.image",
-   "fetch_if_empty": 1,
-   "fieldname": "image_view",
-   "fieldtype": "Image",
-   "hidden": 1,
-   "label": "Image View",
-   "options": "image",
-   "print_hide": 1
-  },
-  {
-   "fieldname": "warehouse_section",
-   "fieldtype": "Section Break",
-   "label": "Warehouse"
-  },
-  {
-   "fieldname": "warehouse",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Warehouse",
-   "options": "Warehouse",
-   "read_only": 1
-  },
-  {
-   "fieldname": "section_break_8",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fetch_from": "item_code.item_group",
-   "fetch_if_empty": 1,
-   "fieldname": "item_group",
-   "fieldtype": "Link",
-   "label": "Item Group",
-   "options": "Item Group",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "website_item.route",
-   "fetch_if_empty": 1,
-   "fieldname": "route",
-   "fieldtype": "Small Text",
-   "label": "Route",
-   "read_only": 1
-  },
-  {
-   "fetch_from": "website_item.web_item_name",
-   "fetch_if_empty": 1,
-   "fieldname": "web_item_name",
-   "fieldtype": "Data",
-   "label": "Website Item Name",
-   "read_only": 1
-  }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2021-08-09 10:30:41.964802",
- "modified_by": "Administrator",
- "module": "E-commerce",
- "name": "Wishlist Item",
- "owner": "Administrator",
- "permissions": [],
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/e_commerce/doctype/wishlist_item/wishlist_item.py b/erpnext/e_commerce/doctype/wishlist_item/wishlist_item.py
deleted file mode 100644
index 75ebccb..0000000
--- a/erpnext/e_commerce/doctype/wishlist_item/wishlist_item.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# 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 WishlistItem(Document):
-	pass
diff --git a/erpnext/e_commerce/legacy_search.py b/erpnext/e_commerce/legacy_search.py
deleted file mode 100644
index ef8e86d..0000000
--- a/erpnext/e_commerce/legacy_search.py
+++ /dev/null
@@ -1,134 +0,0 @@
-import frappe
-from frappe.search.full_text_search import FullTextSearch
-from frappe.utils import strip_html_tags
-from whoosh.analysis import StemmingAnalyzer
-from whoosh.fields import ID, KEYWORD, TEXT, Schema
-from whoosh.qparser import FieldsPlugin, MultifieldParser, WildcardPlugin
-from whoosh.query import Prefix
-
-# TODO: Make obsolete
-INDEX_NAME = "products"
-
-
-class ProductSearch(FullTextSearch):
-	"""Wrapper for WebsiteSearch"""
-
-	def get_schema(self):
-		return Schema(
-			title=TEXT(stored=True, field_boost=1.5),
-			name=ID(stored=True),
-			path=ID(stored=True),
-			content=TEXT(stored=True, analyzer=StemmingAnalyzer()),
-			keywords=KEYWORD(stored=True, scorable=True, commas=True),
-		)
-
-	def get_id(self):
-		return "name"
-
-	def get_items_to_index(self):
-		"""Get all routes to be indexed, this includes the static pages
-		in www/ and routes from published documents
-
-		Returns:
-		        self (object): FullTextSearch Instance
-		"""
-		items = get_all_published_items()
-		documents = [self.get_document_to_index(item) for item in items]
-		return documents
-
-	def get_document_to_index(self, item):
-		try:
-			item = frappe.get_doc("Item", item)
-			title = item.item_name
-			keywords = [item.item_group]
-
-			if item.brand:
-				keywords.append(item.brand)
-
-			if item.website_image_alt:
-				keywords.append(item.website_image_alt)
-
-			if item.has_variants and item.variant_based_on == "Item Attribute":
-				keywords = keywords + [attr.attribute for attr in item.attributes]
-
-			if item.web_long_description:
-				content = strip_html_tags(item.web_long_description)
-			elif item.description:
-				content = strip_html_tags(item.description)
-
-			return frappe._dict(
-				title=title,
-				name=item.name,
-				path=item.route,
-				content=content,
-				keywords=", ".join(keywords),
-			)
-		except Exception:
-			pass
-
-	def search(self, text, scope=None, limit=20):
-		"""Search from the current index
-
-		Args:
-		        text (str): String to search for
-		        scope (str, optional): Scope to limit the search. Defaults to None.
-		        limit (int, optional): Limit number of search results. Defaults to 20.
-
-		Returns:
-		        [List(_dict)]: Search results
-		"""
-		ix = self.get_index()
-
-		results = None
-		out = []
-
-		with ix.searcher() as searcher:
-			parser = MultifieldParser(["title", "content", "keywords"], ix.schema)
-			parser.remove_plugin_class(FieldsPlugin)
-			parser.remove_plugin_class(WildcardPlugin)
-			query = parser.parse(text)
-
-			filter_scoped = None
-			if scope:
-				filter_scoped = Prefix(self.id, scope)
-			results = searcher.search(query, limit=limit, filter=filter_scoped)
-
-			for r in results:
-				out.append(self.parse_result(r))
-
-		return out
-
-	def parse_result(self, result):
-		title_highlights = result.highlights("title")
-		content_highlights = result.highlights("content")
-		keyword_highlights = result.highlights("keywords")
-
-		return frappe._dict(
-			title=result["title"],
-			path=result["path"],
-			keywords=result["keywords"],
-			title_highlights=title_highlights,
-			content_highlights=content_highlights,
-			keyword_highlights=keyword_highlights,
-		)
-
-
-def get_all_published_items():
-	return frappe.get_all(
-		"Website Item", filters={"variant_of": "", "published": 1}, pluck="item_code"
-	)
-
-
-def update_index_for_path(path):
-	search = ProductSearch(INDEX_NAME)
-	return search.update_index_by_name(path)
-
-
-def remove_document_from_index(path):
-	search = ProductSearch(INDEX_NAME)
-	return search.remove_document_from_index(path)
-
-
-def build_index_for_all_routes():
-	search = ProductSearch(INDEX_NAME)
-	return search.build()
diff --git a/erpnext/e_commerce/product_data_engine/filters.py b/erpnext/e_commerce/product_data_engine/filters.py
deleted file mode 100644
index e5e5e97..0000000
--- a/erpnext/e_commerce/product_data_engine/filters.py
+++ /dev/null
@@ -1,158 +0,0 @@
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-import frappe
-from frappe.utils import floor
-
-
-class ProductFiltersBuilder:
-	def __init__(self, item_group=None):
-		if not item_group:
-			self.doc = frappe.get_doc("E Commerce Settings")
-		else:
-			self.doc = frappe.get_doc("Item Group", item_group)
-
-		self.item_group = item_group
-
-	def get_field_filters(self):
-		from erpnext.setup.doctype.item_group.item_group import get_child_groups_for_website
-
-		if not self.item_group and not self.doc.enable_field_filters:
-			return
-
-		fields, filter_data = [], []
-		filter_fields = [row.fieldname for row in self.doc.filter_fields]  # fields in settings
-
-		# filter valid field filters i.e. those that exist in Website Item
-		web_item_meta = frappe.get_meta("Website Item", cached=True)
-		fields = [
-			web_item_meta.get_field(field) for field in filter_fields if web_item_meta.has_field(field)
-		]
-
-		for df in fields:
-			item_filters, item_or_filters = {"published": 1}, []
-			link_doctype_values = self.get_filtered_link_doctype_records(df)
-
-			if df.fieldtype == "Link":
-				if self.item_group:
-					include_child = frappe.db.get_value("Item Group", self.item_group, "include_descendants")
-					if include_child:
-						include_groups = get_child_groups_for_website(self.item_group, include_self=True)
-						include_groups = [x.name for x in include_groups]
-						item_or_filters.extend(
-							[
-								["item_group", "in", include_groups],
-								["Website Item Group", "item_group", "=", self.item_group],  # consider website item groups
-							]
-						)
-					else:
-						item_or_filters.extend(
-							[
-								["item_group", "=", self.item_group],
-								["Website Item Group", "item_group", "=", self.item_group],  # consider website item groups
-							]
-						)
-
-				# exclude variants if mentioned in settings
-				if frappe.db.get_single_value("E Commerce Settings", "hide_variants"):
-					item_filters["variant_of"] = ["is", "not set"]
-
-				# Get link field values attached to published items
-				item_values = frappe.get_all(
-					"Website Item",
-					fields=[df.fieldname],
-					filters=item_filters,
-					or_filters=item_or_filters,
-					distinct="True",
-					pluck=df.fieldname,
-				)
-
-				values = list(set(item_values) & link_doctype_values)  # intersection of both
-			else:
-				# table multiselect
-				values = list(link_doctype_values)
-
-			# Remove None
-			if None in values:
-				values.remove(None)
-
-			if values:
-				filter_data.append([df, values])
-
-		return filter_data
-
-	def get_filtered_link_doctype_records(self, field):
-		"""
-		Get valid link doctype records depending on filters.
-		Apply enable/disable/show_in_website filter.
-		Returns:
-		        set: A set containing valid record names
-		"""
-		link_doctype = field.get_link_doctype()
-		meta = frappe.get_meta(link_doctype, cached=True) if link_doctype else None
-		if meta:
-			filters = self.get_link_doctype_filters(meta)
-			link_doctype_values = set(d.name for d in frappe.get_all(link_doctype, filters))
-
-		return link_doctype_values if meta else set()
-
-	def get_link_doctype_filters(self, meta):
-		"Filters for Link Doctype eg. 'show_in_website'."
-		filters = {}
-		if not meta:
-			return filters
-
-		if meta.has_field("enabled"):
-			filters["enabled"] = 1
-		if meta.has_field("disabled"):
-			filters["disabled"] = 0
-		if meta.has_field("show_in_website"):
-			filters["show_in_website"] = 1
-
-		return filters
-
-	def get_attribute_filters(self):
-		if not self.item_group and not self.doc.enable_attribute_filters:
-			return
-
-		attributes = [row.attribute for row in self.doc.filter_attributes]
-
-		if not attributes:
-			return []
-
-		result = frappe.get_all(
-			"Item Variant Attribute",
-			filters={"attribute": ["in", attributes], "attribute_value": ["is", "set"]},
-			fields=["attribute", "attribute_value"],
-			distinct=True,
-		)
-
-		attribute_value_map = {}
-		for d in result:
-			attribute_value_map.setdefault(d.attribute, []).append(d.attribute_value)
-
-		out = []
-		for name, values in attribute_value_map.items():
-			out.append(frappe._dict(name=name, item_attribute_values=values))
-		return out
-
-	def get_discount_filters(self, discounts):
-		discount_filters = []
-
-		# [25.89, 60.5] min max
-		min_discount, max_discount = discounts[0], discounts[1]
-		# [25, 60] rounded min max
-		min_range_absolute, max_range_absolute = floor(min_discount), floor(max_discount)
-
-		min_range = int(min_discount - (min_range_absolute % 10))  # 20
-		max_range = int(max_discount - (max_range_absolute % 10))  # 60
-
-		min_range = (
-			(min_range + 10) if min_range != min_range_absolute else min_range
-		)  # 30 (upper limit of 25.89 in range of 10)
-		max_range = (max_range + 10) if max_range != max_range_absolute else max_range  # 60
-
-		for discount in range(min_range, (max_range + 1), 10):
-			label = f"{discount}% and below"
-			discount_filters.append([discount, label])
-
-		return discount_filters
diff --git a/erpnext/e_commerce/product_data_engine/query.py b/erpnext/e_commerce/product_data_engine/query.py
deleted file mode 100644
index 975f876..0000000
--- a/erpnext/e_commerce/product_data_engine/query.py
+++ /dev/null
@@ -1,321 +0,0 @@
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-import frappe
-from frappe.utils import flt
-
-from erpnext.e_commerce.doctype.item_review.item_review import get_customer
-from erpnext.e_commerce.shopping_cart.product_info import get_product_info_for_website
-from erpnext.utilities.product import get_non_stock_item_status
-
-
-class ProductQuery:
-	"""Query engine for product listing
-
-	Attributes:
-	        fields (list): Fields to fetch in query
-	        conditions (string): Conditions for query building
-	        or_conditions (string): Search conditions
-	        page_length (Int): Length of page for the query
-	        settings (Document): E Commerce Settings DocType
-	"""
-
-	def __init__(self):
-		self.settings = frappe.get_doc("E Commerce Settings")
-		self.page_length = self.settings.products_per_page or 20
-
-		self.or_filters = []
-		self.filters = [["published", "=", 1]]
-		self.fields = [
-			"web_item_name",
-			"name",
-			"item_name",
-			"item_code",
-			"website_image",
-			"variant_of",
-			"has_variants",
-			"item_group",
-			"web_long_description",
-			"short_description",
-			"route",
-			"website_warehouse",
-			"ranking",
-			"on_backorder",
-		]
-
-	def query(self, attributes=None, fields=None, search_term=None, start=0, item_group=None):
-		"""
-		Args:
-		        attributes (dict, optional): Item Attribute filters
-		        fields (dict, optional): Field level filters
-		        search_term (str, optional): Search term to lookup
-		        start (int, optional): Page start
-
-		Returns:
-		        dict: Dict containing items, item count & discount range
-		"""
-		# track if discounts included in field filters
-		self.filter_with_discount = bool(fields.get("discount"))
-		result, discount_list, website_item_groups, cart_items, count = [], [], [], [], 0
-
-		if fields:
-			self.build_fields_filters(fields)
-		if item_group:
-			self.build_item_group_filters(item_group)
-		if search_term:
-			self.build_search_filters(search_term)
-		if self.settings.hide_variants:
-			self.filters.append(["variant_of", "is", "not set"])
-
-		# query results
-		if attributes:
-			result, count = self.query_items_with_attributes(attributes, start)
-		else:
-			result, count = self.query_items(start=start)
-
-		# sort combined results by ranking
-		result = sorted(result, key=lambda x: x.get("ranking"), reverse=True)
-
-		if self.settings.enabled:
-			cart_items = self.get_cart_items()
-
-		result, discount_list = self.add_display_details(result, discount_list, cart_items)
-
-		discounts = []
-		if discount_list:
-			discounts = [min(discount_list), max(discount_list)]
-
-		result = self.filter_results_by_discount(fields, result)
-
-		return {"items": result, "items_count": count, "discounts": discounts}
-
-	def query_items(self, start=0):
-		"""Build a query to fetch Website Items based on field filters."""
-		# MySQL does not support offset without limit,
-		# frappe does not accept two parameters for limit
-		# https://dev.mysql.com/doc/refman/8.0/en/select.html#id4651989
-		count_items = frappe.db.get_all(
-			"Website Item",
-			filters=self.filters,
-			or_filters=self.or_filters,
-			limit_page_length=184467440737095516,
-			limit_start=start,  # get all items from this offset for total count ahead
-			order_by="ranking desc",
-		)
-		count = len(count_items)
-
-		# If discounts included, return all rows.
-		# Slice after filtering rows with discount (See `filter_results_by_discount`).
-		# Slicing before hand will miss discounted items on the 3rd or 4th page.
-		# Discounts are fetched on computing Pricing Rules so we cannot query them directly.
-		page_length = 184467440737095516 if self.filter_with_discount else self.page_length
-
-		items = frappe.db.get_all(
-			"Website Item",
-			fields=self.fields,
-			filters=self.filters,
-			or_filters=self.or_filters,
-			limit_page_length=page_length,
-			limit_start=start,
-			order_by="ranking desc",
-		)
-
-		return items, count
-
-	def query_items_with_attributes(self, attributes, start=0):
-		"""Build a query to fetch Website Items based on field & attribute filters."""
-		item_codes = []
-
-		for attribute, values in attributes.items():
-			if not isinstance(values, list):
-				values = [values]
-
-			# get items that have selected attribute & value
-			item_code_list = frappe.db.get_all(
-				"Item",
-				fields=["item_code"],
-				filters=[
-					["published_in_website", "=", 1],
-					["Item Variant Attribute", "attribute", "=", attribute],
-					["Item Variant Attribute", "attribute_value", "in", values],
-				],
-			)
-			item_codes.append({x.item_code for x in item_code_list})
-
-		if item_codes:
-			item_codes = list(set.intersection(*item_codes))
-			self.filters.append(["item_code", "in", item_codes])
-
-		items, count = self.query_items(start=start)
-
-		return items, count
-
-	def build_fields_filters(self, filters):
-		"""Build filters for field values
-
-		Args:
-		        filters (dict): Filters
-		"""
-		for field, values in filters.items():
-			if not values or field == "discount":
-				continue
-
-			# handle multiselect fields in filter addition
-			meta = frappe.get_meta("Website Item", cached=True)
-			df = meta.get_field(field)
-			if df.fieldtype == "Table MultiSelect":
-				child_doctype = df.options
-				child_meta = frappe.get_meta(child_doctype, cached=True)
-				fields = child_meta.get("fields")
-				if fields:
-					self.filters.append([child_doctype, fields[0].fieldname, "IN", values])
-			elif isinstance(values, list):
-				# If value is a list use `IN` query
-				self.filters.append([field, "in", values])
-			else:
-				# `=` will be faster than `IN` for most cases
-				self.filters.append([field, "=", values])
-
-	def build_item_group_filters(self, item_group):
-		"Add filters for Item group page and include Website Item Groups."
-		from erpnext.setup.doctype.item_group.item_group import get_child_groups_for_website
-
-		item_group_filters = []
-
-		item_group_filters.append(["Website Item", "item_group", "=", item_group])
-		# Consider Website Item Groups
-		item_group_filters.append(["Website Item Group", "item_group", "=", item_group])
-
-		if frappe.db.get_value("Item Group", item_group, "include_descendants"):
-			# include child item group's items as well
-			# eg. Group Node A, will show items of child 1 and child 2 as well
-			# on it's web page
-			include_groups = get_child_groups_for_website(item_group, include_self=True)
-			include_groups = [x.name for x in include_groups]
-			item_group_filters.append(["Website Item", "item_group", "in", include_groups])
-
-		self.or_filters.extend(item_group_filters)
-
-	def build_search_filters(self, search_term):
-		"""Query search term in specified fields
-
-		Args:
-		        search_term (str): Search candidate
-		"""
-		# Default fields to search from
-		default_fields = {"item_code", "item_name", "web_long_description", "item_group"}
-
-		# Get meta search fields
-		meta = frappe.get_meta("Website Item")
-		meta_fields = set(meta.get_search_fields())
-
-		# Join the meta fields and default fields set
-		search_fields = default_fields.union(meta_fields)
-		if frappe.db.count("Website Item", cache=True) > 50000:
-			search_fields.discard("web_long_description")
-
-		# Build or filters for query
-		search = "%{}%".format(search_term)
-		for field in search_fields:
-			self.or_filters.append([field, "like", search])
-
-	def add_display_details(self, result, discount_list, cart_items):
-		"""Add price and availability details in result."""
-		for item in result:
-			product_info = get_product_info_for_website(item.item_code, skip_quotation_creation=True).get(
-				"product_info"
-			)
-
-			if product_info and product_info["price"]:
-				# update/mutate item and discount_list objects
-				self.get_price_discount_info(item, product_info["price"], discount_list)
-
-			if self.settings.show_stock_availability:
-				self.get_stock_availability(item)
-
-			item.in_cart = item.item_code in cart_items
-
-			item.wished = False
-			if frappe.db.exists(
-				"Wishlist Item", {"item_code": item.item_code, "parent": frappe.session.user}
-			):
-				item.wished = True
-
-		return result, discount_list
-
-	def get_price_discount_info(self, item, price_object, discount_list):
-		"""Modify item object and add price details."""
-		fields = ["formatted_mrp", "formatted_price", "price_list_rate"]
-		for field in fields:
-			item[field] = price_object.get(field)
-
-		if price_object.get("discount_percent"):
-			item.discount_percent = flt(price_object.discount_percent)
-			discount_list.append(price_object.discount_percent)
-
-		if item.formatted_mrp:
-			item.discount = price_object.get("formatted_discount_percent") or price_object.get(
-				"formatted_discount_rate"
-			)
-
-	def get_stock_availability(self, item):
-		from erpnext.templates.pages.wishlist import (
-			get_stock_availability as get_stock_availability_from_template,
-		)
-
-		"""Modify item object and add stock details."""
-		item.in_stock = False
-		warehouse = item.get("website_warehouse")
-		is_stock_item = frappe.get_cached_value("Item", item.item_code, "is_stock_item")
-
-		if item.get("on_backorder"):
-			return
-
-		if not is_stock_item:
-			if warehouse:
-				# product bundle case
-				item.in_stock = get_non_stock_item_status(item.item_code, "website_warehouse")
-			else:
-				item.in_stock = True
-		elif warehouse:
-			item.in_stock = get_stock_availability_from_template(item.item_code, warehouse)
-
-	def get_cart_items(self):
-		customer = get_customer(silent=True)
-		if customer:
-			quotation = frappe.get_all(
-				"Quotation",
-				fields=["name"],
-				filters={
-					"party_name": customer,
-					"contact_email": frappe.session.user,
-					"order_type": "Shopping Cart",
-					"docstatus": 0,
-				},
-				order_by="modified desc",
-				limit_page_length=1,
-			)
-			if quotation:
-				items = frappe.get_all(
-					"Quotation Item", fields=["item_code"], filters={"parent": quotation[0].get("name")}
-				)
-				items = [row.item_code for row in items]
-				return items
-
-		return []
-
-	def filter_results_by_discount(self, fields, result):
-		if fields and fields.get("discount"):
-			discount_percent = frappe.utils.flt(fields["discount"][0])
-			result = [
-				row
-				for row in result
-				if row.get("discount_percent") and row.discount_percent <= discount_percent
-			]
-
-		if self.filter_with_discount:
-			# no limit was added to results while querying
-			# slice results manually
-			result[: self.page_length]
-
-		return result
diff --git a/erpnext/e_commerce/product_data_engine/test_item_group_product_data_engine.py b/erpnext/e_commerce/product_data_engine/test_item_group_product_data_engine.py
deleted file mode 100644
index 45bc20e..0000000
--- a/erpnext/e_commerce/product_data_engine/test_item_group_product_data_engine.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-import unittest
-
-import frappe
-
-from erpnext.e_commerce.api import get_product_filter_data
-from erpnext.e_commerce.doctype.website_item.test_website_item import create_regular_web_item
-
-test_dependencies = ["Item", "Item Group"]
-
-
-class TestItemGroupProductDataEngine(unittest.TestCase):
-	"Test Products & Sub-Category Querying for Product Listing on Item Group Page."
-
-	def setUp(self):
-		item_codes = [
-			("Test Mobile A", "_Test Item Group B"),
-			("Test Mobile B", "_Test Item Group B"),
-			("Test Mobile C", "_Test Item Group B - 1"),
-			("Test Mobile D", "_Test Item Group B - 1"),
-			("Test Mobile E", "_Test Item Group B - 2"),
-		]
-		for item in item_codes:
-			item_code = item[0]
-			item_args = {"item_group": item[1]}
-			if not frappe.db.exists("Website Item", {"item_code": item_code}):
-				create_regular_web_item(item_code, item_args=item_args)
-
-		frappe.db.set_value("Item Group", "_Test Item Group B - 1", "show_in_website", 1)
-		frappe.db.set_value("Item Group", "_Test Item Group B - 2", "show_in_website", 1)
-
-	def tearDown(self):
-		frappe.db.rollback()
-
-	def test_product_listing_in_item_group(self):
-		"Test if only products belonging to the Item Group are fetched."
-		result = get_product_filter_data(
-			query_args={
-				"field_filters": {},
-				"attribute_filters": {},
-				"start": 0,
-				"item_group": "_Test Item Group B",
-			}
-		)
-
-		items = result.get("items")
-		item_codes = [item.get("item_code") for item in items]
-
-		self.assertEqual(len(items), 2)
-		self.assertIn("Test Mobile A", item_codes)
-		self.assertNotIn("Test Mobile C", item_codes)
-
-	def test_products_in_multiple_item_groups(self):
-		"""Test if product is visible on multiple item group pages barring its own."""
-		website_item = frappe.get_doc("Website Item", {"item_code": "Test Mobile E"})
-
-		# show item belonging to '_Test Item Group B - 2' in '_Test Item Group B - 1' as well
-		website_item.append("website_item_groups", {"item_group": "_Test Item Group B - 1"})
-		website_item.save()
-
-		result = get_product_filter_data(
-			query_args={
-				"field_filters": {},
-				"attribute_filters": {},
-				"start": 0,
-				"item_group": "_Test Item Group B - 1",
-			}
-		)
-
-		items = result.get("items")
-		item_codes = [item.get("item_code") for item in items]
-
-		self.assertEqual(len(items), 3)
-		self.assertIn("Test Mobile E", item_codes)  # visible in other item groups
-		self.assertIn("Test Mobile C", item_codes)
-		self.assertIn("Test Mobile D", item_codes)
-
-		result = get_product_filter_data(
-			query_args={
-				"field_filters": {},
-				"attribute_filters": {},
-				"start": 0,
-				"item_group": "_Test Item Group B - 2",
-			}
-		)
-
-		items = result.get("items")
-
-		self.assertEqual(len(items), 1)
-		self.assertEqual(items[0].get("item_code"), "Test Mobile E")  # visible in own item group
-
-	def test_item_group_with_sub_groups(self):
-		"Test Valid Sub Item Groups in Item Group Page."
-		frappe.db.set_value("Item Group", "_Test Item Group B - 2", "show_in_website", 0)
-
-		result = get_product_filter_data(
-			query_args={
-				"field_filters": {},
-				"attribute_filters": {},
-				"start": 0,
-				"item_group": "_Test Item Group B",
-			}
-		)
-
-		self.assertTrue(bool(result.get("sub_categories")))
-
-		child_groups = [d.name for d in result.get("sub_categories")]
-		# check if child group is fetched if shown in website
-		self.assertIn("_Test Item Group B - 1", child_groups)
-
-		frappe.db.set_value("Item Group", "_Test Item Group B - 2", "show_in_website", 1)
-		result = get_product_filter_data(
-			query_args={
-				"field_filters": {},
-				"attribute_filters": {},
-				"start": 0,
-				"item_group": "_Test Item Group B",
-			}
-		)
-		child_groups = [d.name for d in result.get("sub_categories")]
-
-		# check if child group is fetched if shown in website
-		self.assertIn("_Test Item Group B - 1", child_groups)
-		self.assertIn("_Test Item Group B - 2", child_groups)
-
-	def test_item_group_page_with_descendants_included(self):
-		"""
-		Test if 'include_descendants' pulls Items belonging to descendant Item Groups (Level 2 & 3).
-		> _Test Item Group B [Level 1]
-		        > _Test Item Group B - 1 [Level 2]
-		                > _Test Item Group B - 1 - 1 [Level 3]
-		"""
-		frappe.get_doc(
-			{  # create Level 3 nested child group
-				"doctype": "Item Group",
-				"is_group": 1,
-				"item_group_name": "_Test Item Group B - 1 - 1",
-				"parent_item_group": "_Test Item Group B - 1",
-			}
-		).insert()
-
-		create_regular_web_item(  # create an item belonging to level 3 item group
-			"Test Mobile F", item_args={"item_group": "_Test Item Group B - 1 - 1"}
-		)
-
-		frappe.db.set_value("Item Group", "_Test Item Group B - 1 - 1", "show_in_website", 1)
-
-		# enable 'include descendants' in Level 1
-		frappe.db.set_value("Item Group", "_Test Item Group B", "include_descendants", 1)
-
-		result = get_product_filter_data(
-			query_args={
-				"field_filters": {},
-				"attribute_filters": {},
-				"start": 0,
-				"item_group": "_Test Item Group B",
-			}
-		)
-
-		items = result.get("items")
-		item_codes = [item.get("item_code") for item in items]
-
-		# check if all sub groups' items are pulled
-		self.assertEqual(len(items), 6)
-		self.assertIn("Test Mobile A", item_codes)
-		self.assertIn("Test Mobile C", item_codes)
-		self.assertIn("Test Mobile E", item_codes)
-		self.assertIn("Test Mobile F", item_codes)
diff --git a/erpnext/e_commerce/product_data_engine/test_product_data_engine.py b/erpnext/e_commerce/product_data_engine/test_product_data_engine.py
deleted file mode 100644
index c3b6ed5..0000000
--- a/erpnext/e_commerce/product_data_engine/test_product_data_engine.py
+++ /dev/null
@@ -1,348 +0,0 @@
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-import unittest
-
-import frappe
-
-from erpnext.e_commerce.doctype.e_commerce_settings.test_e_commerce_settings import (
-	setup_e_commerce_settings,
-)
-from erpnext.e_commerce.doctype.website_item.test_website_item import create_regular_web_item
-from erpnext.e_commerce.product_data_engine.filters import ProductFiltersBuilder
-from erpnext.e_commerce.product_data_engine.query import ProductQuery
-
-test_dependencies = ["Item", "Item Group"]
-
-
-class TestProductDataEngine(unittest.TestCase):
-	"Test Products Querying and Filters for Product Listing."
-
-	@classmethod
-	def setUpClass(cls):
-		item_codes = [
-			("Test 11I Laptop", "Products"),  # rank 1
-			("Test 12I Laptop", "Products"),  # rank 2
-			("Test 13I Laptop", "Products"),  # rank 3
-			("Test 14I Laptop", "Raw Material"),  # rank 4
-			("Test 15I Laptop", "Raw Material"),  # rank 5
-			("Test 16I Laptop", "Raw Material"),  # rank 6
-			("Test 17I Laptop", "Products"),  # rank 7
-		]
-		for index, item in enumerate(item_codes, start=1):
-			item_code = item[0]
-			item_args = {"item_group": item[1]}
-			web_args = {"ranking": index}
-			if not frappe.db.exists("Website Item", {"item_code": item_code}):
-				create_regular_web_item(item_code, item_args=item_args, web_args=web_args)
-
-		setup_e_commerce_settings(
-			{
-				"products_per_page": 4,
-				"enable_field_filters": 1,
-				"filter_fields": [{"fieldname": "item_group"}],
-				"enable_attribute_filters": 1,
-				"filter_attributes": [{"attribute": "Test Size"}],
-				"company": "_Test Company",
-				"enabled": 1,
-				"default_customer_group": "_Test Customer Group",
-				"price_list": "_Test Price List India",
-			}
-		)
-		frappe.local.shopping_cart_settings = None
-
-	@classmethod
-	def tearDownClass(cls):
-		frappe.db.rollback()
-
-	def test_product_list_ordering_and_paging(self):
-		"Test if website items appear by ranking on different pages."
-		engine = ProductQuery()
-		result = engine.query(attributes={}, fields={}, search_term=None, start=0, item_group=None)
-		items = result.get("items")
-
-		self.assertIsNotNone(items)
-		self.assertEqual(len(items), 4)
-		self.assertGreater(result.get("items_count"), 4)
-
-		# check if items appear as per ranking set in setUpClass
-		self.assertEqual(items[0].get("item_code"), "Test 17I Laptop")
-		self.assertEqual(items[1].get("item_code"), "Test 16I Laptop")
-		self.assertEqual(items[2].get("item_code"), "Test 15I Laptop")
-		self.assertEqual(items[3].get("item_code"), "Test 14I Laptop")
-
-		# check next page
-		result = engine.query(attributes={}, fields={}, search_term=None, start=4, item_group=None)
-		items = result.get("items")
-
-		# check if items appear as per ranking set in setUpClass on next page
-		self.assertEqual(items[0].get("item_code"), "Test 13I Laptop")
-		self.assertEqual(items[1].get("item_code"), "Test 12I Laptop")
-		self.assertEqual(items[2].get("item_code"), "Test 11I Laptop")
-
-	def test_change_product_ranking(self):
-		"Test if item on second page appear on first if ranking is changed."
-		item_code = "Test 12I Laptop"
-		old_ranking = frappe.db.get_value("Website Item", {"item_code": item_code}, "ranking")
-
-		# low rank, appears on second page
-		self.assertEqual(old_ranking, 2)
-
-		# set ranking as highest rank
-		frappe.db.set_value("Website Item", {"item_code": item_code}, "ranking", 10)
-
-		engine = ProductQuery()
-		result = engine.query(attributes={}, fields={}, search_term=None, start=0, item_group=None)
-		items = result.get("items")
-
-		# check if item is the first item on the first page
-		self.assertEqual(items[0].get("item_code"), item_code)
-		self.assertEqual(items[1].get("item_code"), "Test 17I Laptop")
-
-		# tear down
-		frappe.db.set_value("Website Item", {"item_code": item_code}, "ranking", old_ranking)
-
-	def test_product_list_field_filter_builder(self):
-		"Test if field filters are fetched correctly."
-		frappe.db.set_value("Item Group", "Raw Material", "show_in_website", 0)
-
-		filter_engine = ProductFiltersBuilder()
-		field_filters = filter_engine.get_field_filters()
-
-		# Web Items belonging to 'Products' and 'Raw Material' are available
-		# but only 'Products' has 'show_in_website' enabled
-		item_group_filters = field_filters[0]
-		docfield = item_group_filters[0]
-		valid_item_groups = item_group_filters[1]
-
-		self.assertEqual(docfield.options, "Item Group")
-		self.assertIn("Products", valid_item_groups)
-		self.assertNotIn("Raw Material", valid_item_groups)
-
-		frappe.db.set_value("Item Group", "Raw Material", "show_in_website", 1)
-		field_filters = filter_engine.get_field_filters()
-
-		#'Products' and 'Raw Materials' both have 'show_in_website' enabled
-		item_group_filters = field_filters[0]
-		docfield = item_group_filters[0]
-		valid_item_groups = item_group_filters[1]
-
-		self.assertEqual(docfield.options, "Item Group")
-		self.assertIn("Products", valid_item_groups)
-		self.assertIn("Raw Material", valid_item_groups)
-
-	def test_product_list_with_field_filter(self):
-		"Test if field filters are applied correctly."
-		field_filters = {"item_group": "Raw Material"}
-
-		engine = ProductQuery()
-		result = engine.query(
-			attributes={}, fields=field_filters, search_term=None, start=0, item_group=None
-		)
-		items = result.get("items")
-
-		# check if only 'Raw Material' are fetched in the right order
-		self.assertEqual(len(items), 3)
-		self.assertEqual(items[0].get("item_code"), "Test 16I Laptop")
-		self.assertEqual(items[1].get("item_code"), "Test 15I Laptop")
-
-	# def test_product_list_with_field_filter_table_multiselect(self):
-	# 	TODO
-	# 	pass
-
-	def test_product_list_attribute_filter_builder(self):
-		"Test if attribute filters are fetched correctly."
-		create_variant_web_item()
-
-		filter_engine = ProductFiltersBuilder()
-		attribute_filter = filter_engine.get_attribute_filters()[0]
-		attribute_values = attribute_filter.item_attribute_values
-
-		self.assertEqual(attribute_filter.name, "Test Size")
-		self.assertGreater(len(attribute_values), 0)
-		self.assertIn("Large", attribute_values)
-
-	def test_product_list_with_attribute_filter(self):
-		"Test if attribute filters are applied correctly."
-		create_variant_web_item()
-
-		attribute_filters = {"Test Size": ["Large"]}
-		engine = ProductQuery()
-		result = engine.query(
-			attributes=attribute_filters, fields={}, search_term=None, start=0, item_group=None
-		)
-		items = result.get("items")
-
-		# check if only items with Test Size 'Large' are fetched
-		self.assertEqual(len(items), 1)
-		self.assertEqual(items[0].get("item_code"), "Test Web Item-L")
-
-	def test_product_list_discount_filter_builder(self):
-		"Test if discount filters are fetched correctly."
-		from erpnext.e_commerce.doctype.website_item.test_website_item import (
-			make_web_item_price,
-			make_web_pricing_rule,
-		)
-
-		item_code = "Test 12I Laptop"
-		make_web_item_price(item_code=item_code)
-		make_web_pricing_rule(title=f"Test Pricing Rule for {item_code}", item_code=item_code, selling=1)
-
-		setup_e_commerce_settings({"show_price": 1})
-		frappe.local.shopping_cart_settings = None
-
-		engine = ProductQuery()
-		result = engine.query(attributes={}, fields={}, search_term=None, start=4, item_group=None)
-		self.assertTrue(bool(result.get("discounts")))
-
-		filter_engine = ProductFiltersBuilder()
-		discount_filters = filter_engine.get_discount_filters(result["discounts"])
-
-		self.assertEqual(len(discount_filters[0]), 2)
-		self.assertEqual(discount_filters[0][0], 10)
-		self.assertEqual(discount_filters[0][1], "10% and below")
-
-	def test_product_list_with_discount_filters(self):
-		"Test if discount filters are applied correctly."
-		from erpnext.e_commerce.doctype.website_item.test_website_item import (
-			make_web_item_price,
-			make_web_pricing_rule,
-		)
-
-		field_filters = {"discount": [10]}
-
-		make_web_item_price(item_code="Test 12I Laptop")
-		make_web_pricing_rule(
-			title="Test Pricing Rule for Test 12I Laptop",  # 10% discount
-			item_code="Test 12I Laptop",
-			selling=1,
-		)
-		make_web_item_price(item_code="Test 13I Laptop")
-		make_web_pricing_rule(
-			title="Test Pricing Rule for Test 13I Laptop",  # 15% discount
-			item_code="Test 13I Laptop",
-			discount_percentage=15,
-			selling=1,
-		)
-
-		setup_e_commerce_settings({"show_price": 1})
-		frappe.local.shopping_cart_settings = None
-
-		engine = ProductQuery()
-		result = engine.query(
-			attributes={}, fields=field_filters, search_term=None, start=0, item_group=None
-		)
-		items = result.get("items")
-
-		# check if only product with 10% and below discount are fetched
-		self.assertEqual(len(items), 1)
-		self.assertEqual(items[0].get("item_code"), "Test 12I Laptop")
-
-	def test_product_list_with_api(self):
-		"Test products listing using API."
-		from erpnext.e_commerce.api import get_product_filter_data
-
-		create_variant_web_item()
-
-		result = get_product_filter_data(
-			query_args={
-				"field_filters": {"item_group": "Products"},
-				"attribute_filters": {"Test Size": ["Large"]},
-				"start": 0,
-			}
-		)
-
-		items = result.get("items")
-
-		self.assertEqual(len(items), 1)
-		self.assertEqual(items[0].get("item_code"), "Test Web Item-L")
-
-	def test_product_list_with_variants(self):
-		"Test if variants are hideen on hiding variants in settings."
-		create_variant_web_item()
-
-		setup_e_commerce_settings({"enable_attribute_filters": 0, "hide_variants": 1})
-		frappe.local.shopping_cart_settings = None
-
-		attribute_filters = {"Test Size": ["Large"]}
-		engine = ProductQuery()
-		result = engine.query(
-			attributes=attribute_filters, fields={}, search_term=None, start=0, item_group=None
-		)
-		items = result.get("items")
-
-		# check if any variants are fetched even though published variant exists
-		self.assertEqual(len(items), 0)
-
-		# tear down
-		setup_e_commerce_settings({"enable_attribute_filters": 1, "hide_variants": 0})
-
-	def test_custom_field_as_filter(self):
-		"Test if custom field functions as filter correctly."
-		from frappe.custom.doctype.custom_field.custom_field import create_custom_field
-
-		create_custom_field(
-			"Website Item",
-			dict(
-				owner="Administrator",
-				fieldname="supplier",
-				label="Supplier",
-				fieldtype="Link",
-				options="Supplier",
-				insert_after="on_backorder",
-			),
-		)
-
-		frappe.db.set_value(
-			"Website Item", {"item_code": "Test 11I Laptop"}, "supplier", "_Test Supplier"
-		)
-		frappe.db.set_value(
-			"Website Item", {"item_code": "Test 12I Laptop"}, "supplier", "_Test Supplier 1"
-		)
-
-		settings = frappe.get_doc("E Commerce Settings")
-		settings.append("filter_fields", {"fieldname": "supplier"})
-		settings.save()
-
-		filter_engine = ProductFiltersBuilder()
-		field_filters = filter_engine.get_field_filters()
-		custom_filter = field_filters[1]
-		filter_values = custom_filter[1]
-
-		self.assertEqual(custom_filter[0].options, "Supplier")
-		self.assertEqual(len(filter_values), 2)
-		self.assertIn("_Test Supplier", filter_values)
-
-		# test if custom filter works in query
-		field_filters = {"supplier": "_Test Supplier 1"}
-		engine = ProductQuery()
-		result = engine.query(
-			attributes={}, fields=field_filters, search_term=None, start=0, item_group=None
-		)
-		items = result.get("items")
-
-		# check if only 'Raw Material' are fetched in the right order
-		self.assertEqual(len(items), 1)
-		self.assertEqual(items[0].get("item_code"), "Test 12I Laptop")
-
-
-def create_variant_web_item():
-	"Create Variant and Template Website Items."
-	from erpnext.controllers.item_variant import create_variant
-	from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
-	from erpnext.stock.doctype.item.test_item import make_item
-
-	make_item(
-		"Test Web Item",
-		{
-			"has_variant": 1,
-			"variant_based_on": "Item Attribute",
-			"attributes": [{"attribute": "Test Size"}],
-		},
-	)
-	if not frappe.db.exists("Item", "Test Web Item-L"):
-		variant = create_variant("Test Web Item", {"Test Size": "Large"})
-		variant.save()
-
-	if not frappe.db.exists("Website Item", {"variant_of": "Test Web Item"}):
-		make_website_item(variant, save=True)
diff --git a/erpnext/e_commerce/product_ui/grid.js b/erpnext/e_commerce/product_ui/grid.js
deleted file mode 100644
index 20a6c30..0000000
--- a/erpnext/e_commerce/product_ui/grid.js
+++ /dev/null
@@ -1,201 +0,0 @@
-erpnext.ProductGrid = class {
-	/* Options:
-		- items: Items
-		- settings: E Commerce Settings
-		- products_section: Products Wrapper
-		- preference: If preference is not grid view, render but hide
-	*/
-	constructor(options) {
-		Object.assign(this, options);
-
-		if (this.preference !== "Grid View") {
-			this.products_section.addClass("hidden");
-		}
-
-		this.products_section.empty();
-		this.make();
-	}
-
-	make() {
-		let me = this;
-		let html = ``;
-
-		this.items.forEach(item => {
-			let title = item.web_item_name || item.item_name || item.item_code || "";
-			title =  title.length > 90 ? title.substr(0, 90) + "..." : title;
-
-			html += `<div class="col-sm-4 item-card"><div class="card text-left">`;
-			html += me.get_image_html(item, title);
-			html += me.get_card_body_html(item, title, me.settings);
-			html += `</div></div>`;
-		});
-
-		let $product_wrapper = this.products_section;
-		$product_wrapper.append(html);
-	}
-
-	get_image_html(item, title) {
-		let image = item.website_image;
-
-		if (image) {
-			return `
-				<div class="card-img-container">
-					<a href="/${ item.route || '#' }" style="text-decoration: none;">
-						<img class="card-img" src="${ image }" alt="${ title }">
-					</a>
-				</div>
-			`;
-		} else {
-			return `
-				<div class="card-img-container">
-					<a href="/${ item.route || '#' }" style="text-decoration: none;">
-						<div class="card-img-top no-image">
-							${ frappe.get_abbr(title) }
-						</div>
-					</a>
-				</div>
-			`;
-		}
-	}
-
-	get_card_body_html(item, title, settings) {
-		let body_html = `
-			<div class="card-body text-left card-body-flex" style="width:100%">
-				<div style="margin-top: 1rem; display: flex;">
-		`;
-		body_html += this.get_title(item, title);
-
-		// get floating elements
-		if (!item.has_variants) {
-			if (settings.enable_wishlist) {
-				body_html += this.get_wishlist_icon(item);
-			}
-			if (settings.enabled) {
-				body_html += this.get_cart_indicator(item);
-			}
-
-		}
-
-		body_html += `</div>`;
-		body_html += `<div class="product-category">${ item.item_group || '' }</div>`;
-
-		if (item.formatted_price) {
-			body_html += this.get_price_html(item);
-		}
-
-		body_html += this.get_stock_availability(item, settings);
-		body_html += this.get_primary_button(item, settings);
-		body_html += `</div>`; // close div on line 49
-
-		return body_html;
-	}
-
-	get_title(item, title) {
-		let title_html = `
-			<a href="/${ item.route || '#' }">
-				<div class="product-title">
-					${ title || '' }
-				</div>
-			</a>
-		`;
-		return title_html;
-	}
-
-	get_wishlist_icon(item) {
-		let icon_class = item.wished ? "wished" : "not-wished";
-		return `
-			<div class="like-action ${ item.wished ? "like-action-wished" : ''}"
-				data-item-code="${ item.item_code }">
-				<svg class="icon sm">
-					<use class="${ icon_class } wish-icon" href="#icon-heart"></use>
-				</svg>
-			</div>
-		`;
-	}
-
-	get_cart_indicator(item) {
-		return `
-			<div class="cart-indicator ${item.in_cart ? '' : 'hidden'}" data-item-code="${ item.item_code }">
-				1
-			</div>
-		`;
-	}
-
-	get_price_html(item) {
-		let price_html = `
-			<div class="product-price">
-				${ item.formatted_price || '' }
-		`;
-
-		if (item.formatted_mrp) {
-			price_html += `
-				<small class="striked-price">
-					<s>${ item.formatted_mrp ? item.formatted_mrp.replace(/ +/g, "") : "" }</s>
-				</small>
-				<small class="ml-1 product-info-green">
-					${ item.discount } OFF
-				</small>
-			`;
-		}
-		price_html += `</div>`;
-		return price_html;
-	}
-
-	get_stock_availability(item, settings) {
-		if (settings.show_stock_availability && !item.has_variants) {
-			if (item.on_backorder) {
-				return `
-					<span class="out-of-stock mb-2 mt-1" style="color: var(--primary-color)">
-						${ __("Available on backorder") }
-					</span>
-				`;
-			} else if (!item.in_stock) {
-				return `
-					<span class="out-of-stock mb-2 mt-1">
-						${ __("Out of stock") }
-					</span>
-				`;
-			}
-		}
-
-		return ``;
-	}
-
-	get_primary_button(item, settings) {
-		if (item.has_variants) {
-			return `
-				<a href="/${ item.route || '#' }">
-					<div class="btn btn-sm btn-explore-variants w-100 mt-4">
-						${ __('Explore') }
-					</div>
-				</a>
-			`;
-		} else if (settings.enabled && (settings.allow_items_not_in_stock || item.in_stock)) {
-			return `
-				<div id="${ item.name }" class="btn
-					btn-sm btn-primary btn-add-to-cart-list
-					w-100 mt-2 ${ item.in_cart ? 'hidden' : '' }"
-					data-item-code="${ item.item_code }">
-					<span class="mr-2">
-						<svg class="icon icon-md">
-							<use href="#icon-assets"></use>
-						</svg>
-					</span>
-					${ settings.enable_checkout ? __('Add to Cart') :  __('Add to Quote') }
-				</div>
-
-				<a href="/cart">
-					<div id="${ item.name }" class="btn
-						btn-sm btn-primary btn-add-to-cart-list
-						w-100 mt-4 go-to-cart-grid
-						${ item.in_cart ? '' : 'hidden' }"
-						data-item-code="${ item.item_code }">
-						${ settings.enable_checkout ? __('Go to Cart') :  __('Go to Quote') }
-					</div>
-				</a>
-			`;
-		} else {
-			return ``;
-		}
-	}
-};
\ No newline at end of file
diff --git a/erpnext/e_commerce/product_ui/list.js b/erpnext/e_commerce/product_ui/list.js
deleted file mode 100644
index c8fd767..0000000
--- a/erpnext/e_commerce/product_ui/list.js
+++ /dev/null
@@ -1,205 +0,0 @@
-erpnext.ProductList = class {
-	/* Options:
-		- items: Items
-		- settings: E Commerce Settings
-		- products_section: Products Wrapper
-		- preference: If preference is not list view, render but hide
-	*/
-	constructor(options) {
-		Object.assign(this, options);
-
-		if (this.preference !== "List View") {
-			this.products_section.addClass("hidden");
-		}
-
-		this.products_section.empty();
-		this.make();
-	}
-
-	make() {
-		let me = this;
-		let html = `<br><br>`;
-
-		this.items.forEach(item => {
-			let title = item.web_item_name || item.item_name || item.item_code || "";
-			title =  title.length > 200 ? title.substr(0, 200) + "..." : title;
-
-			html += `<div class='row list-row w-100 mb-4'>`;
-			html += me.get_image_html(item, title, me.settings);
-			html += me.get_row_body_html(item, title, me.settings);
-			html += `</div>`;
-		});
-
-		let $product_wrapper = this.products_section;
-		$product_wrapper.append(html);
-	}
-
-	get_image_html(item, title, settings) {
-		let image = item.website_image;
-		let wishlist_enabled = !item.has_variants && settings.enable_wishlist;
-		let image_html = ``;
-
-		if (image) {
-			image_html += `
-				<div class="col-2 border text-center rounded list-image">
-					<a class="product-link product-list-link" href="/${ item.route || '#' }">
-						<img itemprop="image" class="website-image h-100 w-100" alt="${ title }"
-							src="${ image }">
-					</a>
-					${ wishlist_enabled ? this.get_wishlist_icon(item): '' }
-				</div>
-			`;
-		} else {
-			image_html += `
-				<div class="col-2 border text-center rounded list-image">
-					<a class="product-link product-list-link" href="/${ item.route || '#' }"
-						style="text-decoration: none">
-						<div class="card-img-top no-image-list">
-							${ frappe.get_abbr(title) }
-						</div>
-					</a>
-					${ wishlist_enabled ? this.get_wishlist_icon(item): '' }
-				</div>
-			`;
-		}
-
-		return image_html;
-	}
-
-	get_row_body_html(item, title, settings) {
-		let body_html = `<div class='col-10 text-left'>`;
-		body_html += this.get_title_html(item, title, settings);
-		body_html += this.get_item_details(item, settings);
-		body_html += `</div>`;
-		return body_html;
-	}
-
-	get_title_html(item, title, settings) {
-		let title_html = `<div style="display: flex; margin-left: -15px;">`;
-		title_html += `
-			<div class="col-8" style="margin-right: -15px;">
-				<a href="/${ item.route || '#' }">
-					<div class="product-title">
-					${ title }
-					</div>
-				</a>
-			</div>
-		`;
-
-		if (settings.enabled) {
-			title_html += `<div class="col-4 cart-action-container ${item.in_cart ? 'd-flex' : ''}">`;
-			title_html += this.get_primary_button(item, settings);
-			title_html += `</div>`;
-		}
-		title_html += `</div>`;
-
-		return title_html;
-	}
-
-	get_item_details(item, settings) {
-		let details = `
-			<p class="product-code">
-				${ item.item_group } | Item Code : ${ item.item_code }
-			</p>
-			<div class="mt-2" style="color: var(--gray-600) !important; font-size: 13px;">
-				${ item.short_description || '' }
-			</div>
-			<div class="product-price">
-				${ item.formatted_price || '' }
-		`;
-
-		if (item.formatted_mrp) {
-			details += `
-				<small class="striked-price">
-					<s>${ item.formatted_mrp ? item.formatted_mrp.replace(/ +/g, "") : "" }</s>
-				</small>
-				<small class="ml-1 product-info-green">
-					${ item.discount } OFF
-				</small>
-			`;
-		}
-
-		details += this.get_stock_availability(item, settings);
-		details += `</div>`;
-
-		return details;
-	}
-
-	get_stock_availability(item, settings) {
-		if (settings.show_stock_availability && !item.has_variants) {
-			if (item.on_backorder) {
-				return `
-					<br>
-					<span class="out-of-stock mt-2" style="color: var(--primary-color)">
-						${ __("Available on backorder") }
-					</span>
-				`;
-			} else if (!item.in_stock) {
-				return `
-					<br>
-					<span class="out-of-stock mt-2">${ __("Out of stock") }</span>
-				`;
-			}
-		}
-		return ``;
-	}
-
-	get_wishlist_icon(item) {
-		let icon_class = item.wished ? "wished" : "not-wished";
-
-		return `
-			<div class="like-action-list ${ item.wished ? "like-action-wished" : ''}"
-				data-item-code="${ item.item_code }">
-				<svg class="icon sm">
-					<use class="${ icon_class } wish-icon" href="#icon-heart"></use>
-				</svg>
-			</div>
-		`;
-	}
-
-	get_primary_button(item, settings) {
-		if (item.has_variants) {
-			return `
-				<a href="/${ item.route || '#' }">
-					<div class="btn btn-sm btn-explore-variants btn mb-0 mt-0">
-						${ __('Explore') }
-					</div>
-				</a>
-			`;
-		} else if (settings.enabled && (settings.allow_items_not_in_stock || item.in_stock)) {
-			return `
-				<div id="${ item.name }" class="btn
-					btn-sm btn-primary btn-add-to-cart-list mb-0
-					${ item.in_cart ? 'hidden' : '' }"
-					data-item-code="${ item.item_code }"
-					style="margin-top: 0px !important; max-height: 30px; float: right;
-						padding: 0.25rem 1rem; min-width: 135px;">
-					<span class="mr-2">
-						<svg class="icon icon-md">
-							<use href="#icon-assets"></use>
-						</svg>
-					</span>
-					${ settings.enable_checkout ? __('Add to Cart') :  __('Add to Quote') }
-				</div>
-
-				<div class="cart-indicator list-indicator ${item.in_cart ? '' : 'hidden'}">
-					1
-				</div>
-
-				<a href="/cart">
-					<div id="${ item.name }" class="btn
-						btn-sm btn-primary btn-add-to-cart-list
-						ml-4 go-to-cart mb-0 mt-0
-						${ item.in_cart ? '' : 'hidden' }"
-						data-item-code="${ item.item_code }"
-						style="padding: 0.25rem 1rem; min-width: 135px;">
-						${ settings.enable_checkout ? __('Go to Cart') :  __('Go to Quote') }
-					</div>
-				</a>
-			`;
-		} else {
-			return ``;
-		}
-	}
-
-};
diff --git a/erpnext/e_commerce/product_ui/search.js b/erpnext/e_commerce/product_ui/search.js
deleted file mode 100644
index 1688cc1..0000000
--- a/erpnext/e_commerce/product_ui/search.js
+++ /dev/null
@@ -1,244 +0,0 @@
-erpnext.ProductSearch = class {
-	constructor(opts) {
-		/* Options: search_box_id (for custom search box) */
-		$.extend(this, opts);
-		this.MAX_RECENT_SEARCHES = 4;
-		this.search_box_id = this.search_box_id || "#search-box";
-		this.searchBox = $(this.search_box_id);
-
-		this.setupSearchDropDown();
-		this.bindSearchAction();
-	}
-
-	setupSearchDropDown() {
-		this.search_area = $("#dropdownMenuSearch");
-		this.setupSearchResultContainer();
-		this.populateRecentSearches();
-	}
-
-	bindSearchAction() {
-		let me = this;
-
-		// Show Search dropdown
-		this.searchBox.on("focus", () => {
-			this.search_dropdown.removeClass("hidden");
-		});
-
-		// If click occurs outside search input/results, hide results.
-		// Click can happen anywhere on the page
-		$("body").on("click", (e) => {
-			let searchEvent = $(e.target).closest(this.search_box_id).length;
-			let resultsEvent = $(e.target).closest('#search-results-container').length;
-			let isResultHidden = this.search_dropdown.hasClass("hidden");
-
-			if (!searchEvent && !resultsEvent && !isResultHidden) {
-				this.search_dropdown.addClass("hidden");
-			}
-		});
-
-		// Process search input
-		this.searchBox.on("input", (e) => {
-			let query = e.target.value;
-
-			if (query.length == 0) {
-				me.populateResults(null);
-				me.populateCategoriesList(null);
-			}
-
-			if (query.length < 3 || !query.length) return;
-
-			frappe.call({
-				method: "erpnext.templates.pages.product_search.search",
-				args: {
-					query: query
-				},
-				callback: (data) => {
-					let product_results = null, category_results = null;
-
-					// Populate product results
-					product_results = data.message ? data.message.product_results : null;
-					me.populateResults(product_results);
-
-					// Populate categories
-					if (me.category_container) {
-						category_results = data.message ? data.message.category_results : null;
-						me.populateCategoriesList(category_results);
-					}
-
-					// Populate recent search chips only on successful queries
-					if (!$.isEmptyObject(product_results) || !$.isEmptyObject(category_results)) {
-						me.setRecentSearches(query);
-					}
-				}
-			});
-
-			this.search_dropdown.removeClass("hidden");
-		});
-	}
-
-	setupSearchResultContainer() {
-		this.search_dropdown = this.search_area.append(`
-			<div class="overflow-hidden shadow dropdown-menu w-100 hidden"
-				id="search-results-container"
-				aria-labelledby="dropdownMenuSearch"
-				style="display: flex; flex-direction: column;">
-			</div>
-		`).find("#search-results-container");
-
-		this.setupCategoryContainer();
-		this.setupProductsContainer();
-		this.setupRecentsContainer();
-	}
-
-	setupProductsContainer() {
-		this.products_container = this.search_dropdown.append(`
-			<div id="product-results mt-2">
-				<div id="product-scroll" style="overflow: scroll; max-height: 300px">
-				</div>
-			</div>
-		`).find("#product-scroll");
-	}
-
-	setupCategoryContainer() {
-		this.category_container = this.search_dropdown.append(`
-			<div class="category-container mt-2 mb-1">
-				<div class="category-chips">
-				</div>
-			</div>
-		`).find(".category-chips");
-	}
-
-	setupRecentsContainer() {
-		let $recents_section = this.search_dropdown.append(`
-			<div class="mb-2 mt-2 recent-searches">
-				<div>
-					<b>${ __("Recent") }</b>
-				</div>
-			</div>
-		`).find(".recent-searches");
-
-		this.recents_container = $recents_section.append(`
-			<div id="recents" style="padding: .25rem 0 1rem 0;">
-			</div>
-		`).find("#recents");
-	}
-
-	getRecentSearches() {
-		return JSON.parse(localStorage.getItem("recent_searches") || "[]");
-	}
-
-	attachEventListenersToChips() {
-		let me  = this;
-		const chips = $(".recent-search");
-		window.chips = chips;
-
-		for (let chip of chips) {
-			chip.addEventListener("click", () => {
-				me.searchBox[0].value = chip.innerText.trim();
-
-				// Start search with `recent query`
-				me.searchBox.trigger("input");
-				me.searchBox.focus();
-			});
-		}
-	}
-
-	setRecentSearches(query) {
-		let recents = this.getRecentSearches();
-		if (recents.length >= this.MAX_RECENT_SEARCHES) {
-			// Remove the `first` query
-			recents.splice(0, 1);
-		}
-
-		if (recents.indexOf(query) >= 0) {
-			return;
-		}
-
-		recents.push(query);
-		localStorage.setItem("recent_searches", JSON.stringify(recents));
-
-		this.populateRecentSearches();
-	}
-
-	populateRecentSearches() {
-		let recents = this.getRecentSearches();
-
-		if (!recents.length) {
-			this.recents_container.html(`<span class=""text-muted">No searches yet.</span>`);
-			return;
-		}
-
-		let html = "";
-		recents.forEach((key) => {
-			html += `
-				<div class="recent-search mr-1" style="font-size: 13px">
-					<span class="mr-2">
-						<svg width="20" height="20" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
-							<path d="M8 14C11.3137 14 14 11.3137 14 8C14 4.68629 11.3137 2 8 2C4.68629 2 2 4.68629 2 8C2 11.3137 4.68629 14 8 14Z" stroke="var(--gray-500)"" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
-							<path d="M8.00027 5.20947V8.00017L10 10" stroke="var(--gray-500)" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
-						</svg>
-					</span>
-					${ key }
-				</div>
-			`;
-		});
-
-		this.recents_container.html(html);
-		this.attachEventListenersToChips();
-	}
-
-	populateResults(product_results) {
-		if (!product_results || product_results.length === 0) {
-			let empty_html = ``;
-			this.products_container.html(empty_html);
-			return;
-		}
-
-		let html = "";
-
-		product_results.forEach((res) => {
-			let thumbnail = res.thumbnail || '/assets/erpnext/images/ui-states/cart-empty-state.png';
-			html += `
-				<div class="dropdown-item" style="display: flex;">
-					<img class="item-thumb col-2" src=${encodeURI(thumbnail)} />
-					<div class="col-9" style="white-space: normal;">
-						<a href="/${res.route}">${res.web_item_name}</a><br>
-						<span class="brand-line">${res.brand ? "by " + res.brand : ""}</span>
-					</div>
-				</div>
-			`;
-		});
-
-		this.products_container.html(html);
-	}
-
-	populateCategoriesList(category_results) {
-		if (!category_results || category_results.length === 0) {
-			let empty_html = `
-				<div class="category-container mt-2">
-					<div class="category-chips">
-					</div>
-				</div>
-			`;
-			this.category_container.html(empty_html);
-			return;
-		}
-
-		let html = `
-			<div class="mb-2">
-				<b>${ __("Categories") }</b>
-			</div>
-		`;
-
-		category_results.forEach((category) => {
-			html += `
-				<a href="/${category.route}" class="btn btn-sm category-chip mr-2 mb-2"
-					style="font-size: 13px" role="button">
-				${ category.name }
-				</button>
-			`;
-		});
-
-		this.category_container.html(html);
-	}
-};
diff --git a/erpnext/e_commerce/product_ui/views.js b/erpnext/e_commerce/product_ui/views.js
deleted file mode 100644
index fb63b21..0000000
--- a/erpnext/e_commerce/product_ui/views.js
+++ /dev/null
@@ -1,548 +0,0 @@
-erpnext.ProductView =  class {
-	/* Options:
-		- View Type
-		- Products Section Wrapper,
-		- Item Group: If its an Item Group page
-	*/
-	constructor(options) {
-		Object.assign(this, options);
-		this.preference = this.view_type;
-		this.make();
-	}
-
-	make(from_filters=false) {
-		this.products_section.empty();
-		this.prepare_toolbar();
-		this.get_item_filter_data(from_filters);
-	}
-
-	prepare_toolbar() {
-		this.products_section.append(`
-			<div class="toolbar d-flex">
-			</div>
-		`);
-		this.prepare_search();
-		this.prepare_view_toggler();
-
-		new erpnext.ProductSearch();
-	}
-
-	prepare_view_toggler() {
-
-		if (!$("#list").length || !$("#image-view").length) {
-			this.render_view_toggler();
-			this.bind_view_toggler_actions();
-			this.set_view_state();
-		}
-	}
-
-	get_item_filter_data(from_filters=false) {
-		// Get and render all Product related views
-		let me = this;
-		this.from_filters = from_filters;
-		let args = this.get_query_filters();
-
-		this.disable_view_toggler(true);
-
-		frappe.call({
-			method: "erpnext.e_commerce.api.get_product_filter_data",
-			args: {
-				query_args: args
-			},
-			callback: function(result) {
-				if (!result || result.exc || !result.message || result.message.exc) {
-					me.render_no_products_section(true);
-				} else {
-					// Sub Category results are independent of Items
-					if (me.item_group && result.message["sub_categories"].length) {
-						me.render_item_sub_categories(result.message["sub_categories"]);
-					}
-
-					if (!result.message["items"].length) {
-						// if result has no items or result is empty
-						me.render_no_products_section();
-					} else {
-						// Add discount filters
-						me.re_render_discount_filters(result.message["filters"].discount_filters);
-
-						// Render views
-						me.render_list_view(result.message["items"], result.message["settings"]);
-						me.render_grid_view(result.message["items"], result.message["settings"]);
-
-						me.products = result.message["items"];
-						me.product_count = result.message["items_count"];
-					}
-
-					// Bind filter actions
-					if (!from_filters) {
-						// If `get_product_filter_data` was triggered after checking a filter,
-						// don't touch filters unnecessarily, only data must change
-						// filter persistence is handle on filter change event
-						me.bind_filters();
-						me.restore_filters_state();
-					}
-
-					// Bottom paging
-					me.add_paging_section(result.message["settings"]);
-				}
-
-				me.disable_view_toggler(false);
-			}
-		});
-	}
-
-	disable_view_toggler(disable=false) {
-		$('#list').prop('disabled', disable);
-		$('#image-view').prop('disabled', disable);
-	}
-
-	render_grid_view(items, settings) {
-		// loop over data and add grid html to it
-		let me = this;
-		this.prepare_product_area_wrapper("grid");
-
-		new erpnext.ProductGrid({
-			items: items,
-			products_section: $("#products-grid-area"),
-			settings: settings,
-			preference: me.preference
-		});
-	}
-
-	render_list_view(items, settings) {
-		let me = this;
-		this.prepare_product_area_wrapper("list");
-
-		new erpnext.ProductList({
-			items: items,
-			products_section: $("#products-list-area"),
-			settings: settings,
-			preference: me.preference
-		});
-	}
-
-	prepare_product_area_wrapper(view) {
-		let left_margin = view == "list" ? "ml-2" : "";
-		let top_margin = view == "list" ? "mt-6" : "mt-minus-1";
-		return this.products_section.append(`
-			<br>
-			<div id="products-${view}-area" class="row products-list ${ top_margin } ${ left_margin }"></div>
-		`);
-	}
-
-	get_query_filters() {
-		const filters = frappe.utils.get_query_params();
-		let {field_filters, attribute_filters} = filters;
-
-		field_filters = field_filters ? JSON.parse(field_filters) : {};
-		attribute_filters = attribute_filters ? JSON.parse(attribute_filters) : {};
-
-		return {
-			field_filters: field_filters,
-			attribute_filters: attribute_filters,
-			item_group: this.item_group,
-			start: filters.start || null,
-			from_filters: this.from_filters || false
-		};
-	}
-
-	add_paging_section(settings) {
-		$(".product-paging-area").remove();
-
-		if (this.products) {
-			let paging_html = `
-				<div class="row product-paging-area mt-5">
-					<div class="col-3">
-					</div>
-					<div class="col-9 text-right">
-			`;
-			let query_params = frappe.utils.get_query_params();
-			let start = query_params.start ? cint(JSON.parse(query_params.start)) : 0;
-			let page_length = settings.products_per_page || 0;
-
-			let prev_disable = start > 0 ? "" : "disabled";
-			let next_disable = (this.product_count > page_length) ? "" : "disabled";
-
-			paging_html += `
-				<button class="btn btn-default btn-prev" data-start="${ start - page_length }"
-					style="float: left" ${prev_disable}>
-					${ __("Prev") }
-				</button>`;
-
-			paging_html += `
-				<button class="btn btn-default btn-next" data-start="${ start + page_length }"
-					${next_disable}>
-					${ __("Next") }
-				</button>
-			`;
-
-			paging_html += `</div></div>`;
-
-			$(".page_content").append(paging_html);
-			this.bind_paging_action();
-		}
-	}
-
-	prepare_search() {
-		$(".toolbar").append(`
-			<div class="input-group col-8 p-0">
-				<div class="dropdown w-100" id="dropdownMenuSearch">
-					<input type="search" name="query" id="search-box" class="form-control font-md"
-						placeholder="Search for Products"
-						aria-label="Product" aria-describedby="button-addon2">
-					<div class="search-icon">
-						<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"
-							fill="none"
-							stroke="currentColor" stroke-width="2" stroke-linecap="round"
-							stroke-linejoin="round"
-							class="feather feather-search">
-							<circle cx="11" cy="11" r="8"></circle>
-							<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
-						</svg>
-					</div>
-					<!-- Results dropdown rendered in product_search.js -->
-				</div>
-			</div>
-		`);
-	}
-
-	render_view_toggler() {
-		$(".toolbar").append(`<div class="toggle-container col-4 p-0"></div>`);
-
-		["btn-list-view", "btn-grid-view"].forEach(view => {
-			let icon = view === "btn-list-view" ? "list" : "image-view";
-			$(".toggle-container").append(`
-				<div class="form-group mb-0" id="toggle-view">
-					<button id="${ icon }" class="btn ${ view } mr-2">
-						<span>
-							<svg class="icon icon-md">
-								<use href="#icon-${ icon }"></use>
-							</svg>
-						</span>
-					</button>
-				</div>
-			`);
-		});
-	}
-
-	bind_view_toggler_actions() {
-		$("#list").click(function() {
-			let $btn = $(this);
-			$btn.removeClass('btn-primary');
-			$btn.addClass('btn-primary');
-			$(".btn-grid-view").removeClass('btn-primary');
-
-			$("#products-grid-area").addClass("hidden");
-			$("#products-list-area").removeClass("hidden");
-			localStorage.setItem("product_view", "List View");
-		});
-
-		$("#image-view").click(function() {
-			let $btn = $(this);
-			$btn.removeClass('btn-primary');
-			$btn.addClass('btn-primary');
-			$(".btn-list-view").removeClass('btn-primary');
-
-			$("#products-list-area").addClass("hidden");
-			$("#products-grid-area").removeClass("hidden");
-			localStorage.setItem("product_view", "Grid View");
-		});
-	}
-
-	set_view_state() {
-		if (this.preference === "List View") {
-			$("#list").addClass('btn-primary');
-			$("#image-view").removeClass('btn-primary');
-		} else {
-			$("#image-view").addClass('btn-primary');
-			$("#list").removeClass('btn-primary');
-		}
-	}
-
-	bind_paging_action() {
-		let me = this;
-		$('.btn-prev, .btn-next').click((e) => {
-			const $btn = $(e.target);
-			me.from_filters = false;
-
-			$btn.prop('disabled', true);
-			const start = $btn.data('start');
-
-			let query_params = frappe.utils.get_query_params();
-			query_params.start = start;
-			let path = window.location.pathname + '?' + frappe.utils.get_url_from_dict(query_params);
-			window.location.href = path;
-		});
-	}
-
-	re_render_discount_filters(filter_data) {
-		this.get_discount_filter_html(filter_data);
-		if (this.from_filters) {
-			// Bind filter action if triggered via filters
-			// if not from filter action, page load will bind actions
-			this.bind_discount_filter_action();
-		}
-		// discount filters are rendered with Items (later)
-		// unlike the other filters
-		this.restore_discount_filter();
-	}
-
-	get_discount_filter_html(filter_data) {
-		$("#discount-filters").remove();
-		if (filter_data) {
-			$("#product-filters").append(`
-				<div id="discount-filters" class="mb-4 filter-block pb-5">
-					<div class="filter-label mb-3">${ __("Discounts") }</div>
-				</div>
-			`);
-
-			let html = `<div class="filter-options">`;
-			filter_data.forEach(filter => {
-				html += `
-					<div class="checkbox">
-						<label data-value="${ filter[0] }">
-							<input type="radio"
-								class="product-filter discount-filter"
-								name="discount" id="${ filter[0] }"
-								data-filter-name="discount"
-								data-filter-value="${ filter[0] }"
-								style="width: 14px !important"
-							>
-								<span class="label-area" for="${ filter[0] }">
-									${ filter[1] }
-								</span>
-						</label>
-					</div>
-				`;
-			});
-			html += `</div>`;
-
-			$("#discount-filters").append(html);
-		}
-	}
-
-	restore_discount_filter() {
-		const filters = frappe.utils.get_query_params();
-		let field_filters = filters.field_filters;
-		if (!field_filters) return;
-
-		field_filters = JSON.parse(field_filters);
-
-		if (field_filters && field_filters["discount"]) {
-			const values = field_filters["discount"];
-			const selector = values.map(value => {
-				return `input[data-filter-name="discount"][data-filter-value="${value}"]`;
-			}).join(',');
-			$(selector).prop('checked', true);
-			this.field_filters = field_filters;
-		}
-	}
-
-	bind_discount_filter_action() {
-		let me = this;
-		$('.discount-filter').on('change', (e) => {
-			const $checkbox = $(e.target);
-			const is_checked = $checkbox.is(':checked');
-
-			const {
-				filterValue: filter_value
-			} = $checkbox.data();
-
-			delete this.field_filters["discount"];
-
-			if (is_checked) {
-				this.field_filters["discount"] = [];
-				this.field_filters["discount"].push(filter_value);
-			}
-
-			if (this.field_filters["discount"].length === 0) {
-				delete this.field_filters["discount"];
-			}
-
-			me.change_route_with_filters();
-		});
-	}
-
-	bind_filters() {
-		let me = this;
-		this.field_filters = {};
-		this.attribute_filters = {};
-
-		$('.product-filter').on('change', (e) => {
-			me.from_filters = true;
-
-			const $checkbox = $(e.target);
-			const is_checked = $checkbox.is(':checked');
-
-			if ($checkbox.is('.attribute-filter')) {
-				const {
-					attributeName: attribute_name,
-					attributeValue: attribute_value
-				} = $checkbox.data();
-
-				if (is_checked) {
-					this.attribute_filters[attribute_name] = this.attribute_filters[attribute_name] || [];
-					this.attribute_filters[attribute_name].push(attribute_value);
-				} else {
-					this.attribute_filters[attribute_name] = this.attribute_filters[attribute_name] || [];
-					this.attribute_filters[attribute_name] = this.attribute_filters[attribute_name].filter(v => v !== attribute_value);
-				}
-
-				if (this.attribute_filters[attribute_name].length === 0) {
-					delete this.attribute_filters[attribute_name];
-				}
-			} else if ($checkbox.is('.field-filter') || $checkbox.is('.discount-filter')) {
-				const {
-					filterName: filter_name,
-					filterValue: filter_value
-				} = $checkbox.data();
-
-				if ($checkbox.is('.discount-filter')) {
-					// clear previous discount filter to accomodate new
-					delete this.field_filters["discount"];
-				}
-				if (is_checked) {
-					this.field_filters[filter_name] = this.field_filters[filter_name] || [];
-					if (!in_list(this.field_filters[filter_name], filter_value)) {
-						this.field_filters[filter_name].push(filter_value);
-					}
-				} else {
-					this.field_filters[filter_name] = this.field_filters[filter_name] || [];
-					this.field_filters[filter_name] = this.field_filters[filter_name].filter(v => v !== filter_value);
-				}
-
-				if (this.field_filters[filter_name].length === 0) {
-					delete this.field_filters[filter_name];
-				}
-			}
-
-			me.change_route_with_filters();
-		});
-
-		// bind filter lookup input box
-		$('.filter-lookup-input').on('keydown', frappe.utils.debounce((e) => {
-			const $input = $(e.target);
-			const keyword = ($input.val() || '').toLowerCase();
-			const $filter_options = $input.next('.filter-options');
-
-			$filter_options.find('.filter-lookup-wrapper').show();
-			$filter_options.find('.filter-lookup-wrapper').each((i, el) => {
-				const $el = $(el);
-				const value = $el.data('value').toLowerCase();
-				if (!value.includes(keyword)) {
-					$el.hide();
-				}
-			});
-		}, 300));
-	}
-
-	change_route_with_filters() {
-		let route_params = frappe.utils.get_query_params();
-
-		let start = this.if_key_exists(route_params.start) || 0;
-		if (this.from_filters) {
-			start = 0; // show items from first page if new filters are triggered
-		}
-
-		const query_string = this.get_query_string({
-			start: start,
-			field_filters: JSON.stringify(this.if_key_exists(this.field_filters)),
-			attribute_filters: JSON.stringify(this.if_key_exists(this.attribute_filters)),
-		});
-		window.history.pushState('filters', '', `${location.pathname}?` + query_string);
-
-		$('.page_content input').prop('disabled', true);
-
-		this.make(true);
-		$('.page_content input').prop('disabled', false);
-	}
-
-	restore_filters_state() {
-		const filters = frappe.utils.get_query_params();
-		let {field_filters, attribute_filters} = filters;
-
-		if (field_filters) {
-			field_filters = JSON.parse(field_filters);
-			for (let fieldname in field_filters) {
-				const values = field_filters[fieldname];
-				const selector = values.map(value => {
-					return `input[data-filter-name="${fieldname}"][data-filter-value="${value}"]`;
-				}).join(',');
-				$(selector).prop('checked', true);
-			}
-			this.field_filters = field_filters;
-		}
-		if (attribute_filters) {
-			attribute_filters = JSON.parse(attribute_filters);
-			for (let attribute in attribute_filters) {
-				const values = attribute_filters[attribute];
-				const selector = values.map(value => {
-					return `input[data-attribute-name="${attribute}"][data-attribute-value="${value}"]`;
-				}).join(',');
-				$(selector).prop('checked', true);
-			}
-			this.attribute_filters = attribute_filters;
-		}
-	}
-
-	render_no_products_section(error=false) {
-		let error_section = `
-			<div class="mt-4 w-100 alert alert-error font-md">
-				Something went wrong. Please refresh or contact us.
-			</div>
-		`;
-		let no_results_section = `
-			<div class="cart-empty frappe-card mt-4">
-				<div class="cart-empty-state">
-					<img src="/assets/erpnext/images/ui-states/cart-empty-state.png" alt="Empty Cart">
-				</div>
-				<div class="cart-empty-message mt-4">${ __('No products found') }</p>
-			</div>
-		`;
-
-		this.products_section.append(error ? error_section : no_results_section);
-	}
-
-	render_item_sub_categories(categories) {
-		if (categories && categories.length) {
-			let sub_group_html = `
-				<div class="sub-category-container scroll-categories">
-			`;
-
-			categories.forEach(category => {
-				sub_group_html += `
-					<a href="/${ category.route || '#' }" style="text-decoration: none;">
-						<div class="category-pill">
-							${ category.name }
-						</div>
-					</a>
-				`;
-			});
-			sub_group_html += `</div>`;
-
-			$("#product-listing").prepend(sub_group_html);
-		}
-	}
-
-	get_query_string(object) {
-		const url = new URLSearchParams();
-		for (let key in object) {
-			const value = object[key];
-			if (value) {
-				url.append(key, value);
-			}
-		}
-		return url.toString();
-	}
-
-	if_key_exists(obj) {
-		let exists = false;
-		for (let key in obj) {
-			if (Object.prototype.hasOwnProperty.call(obj, key) && obj[key]) {
-				exists = true;
-				break;
-			}
-		}
-		return exists ? obj : undefined;
-	}
-};
\ No newline at end of file
diff --git a/erpnext/e_commerce/redisearch_utils.py b/erpnext/e_commerce/redisearch_utils.py
deleted file mode 100644
index 87ca9bd..0000000
--- a/erpnext/e_commerce/redisearch_utils.py
+++ /dev/null
@@ -1,255 +0,0 @@
-# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-import json
-
-import frappe
-from frappe import _
-from frappe.utils.redis_wrapper import RedisWrapper
-from redis import ResponseError
-from redis.commands.search.field import TagField, TextField
-from redis.commands.search.indexDefinition import IndexDefinition
-from redis.commands.search.suggestion import Suggestion
-
-WEBSITE_ITEM_INDEX = "website_items_index"
-WEBSITE_ITEM_KEY_PREFIX = "website_item:"
-WEBSITE_ITEM_NAME_AUTOCOMPLETE = "website_items_name_dict"
-WEBSITE_ITEM_CATEGORY_AUTOCOMPLETE = "website_items_category_dict"
-
-
-def get_indexable_web_fields():
-	"Return valid fields from Website Item that can be searched for."
-	web_item_meta = frappe.get_meta("Website Item", cached=True)
-	valid_fields = filter(
-		lambda df: df.fieldtype in ("Link", "Table MultiSelect", "Data", "Small Text", "Text Editor"),
-		web_item_meta.fields,
-	)
-
-	return [df.fieldname for df in valid_fields]
-
-
-def is_redisearch_enabled():
-	"Return True only if redisearch is loaded and enabled."
-	is_redisearch_enabled = frappe.db.get_single_value("E Commerce Settings", "is_redisearch_enabled")
-	return is_search_module_loaded() and is_redisearch_enabled
-
-
-def is_search_module_loaded():
-	try:
-		cache = frappe.cache()
-		for module in cache.module_list():
-			if module.get(b"name") == b"search":
-				return True
-	except Exception:
-		return False  # handling older redis versions
-
-
-def if_redisearch_enabled(function):
-	"Decorator to check if Redisearch is enabled."
-
-	def wrapper(*args, **kwargs):
-		if is_redisearch_enabled():
-			func = function(*args, **kwargs)
-			return func
-		return
-
-	return wrapper
-
-
-def make_key(key):
-	return frappe.cache().make_key(key)
-
-
-@if_redisearch_enabled
-def create_website_items_index():
-	"Creates Index Definition."
-
-	redis = frappe.cache()
-	index = redis.ft(WEBSITE_ITEM_INDEX)
-
-	try:
-		index.dropindex()  # drop if already exists
-	except ResponseError:
-		# will most likely raise a ResponseError if index does not exist
-		# ignore and create index
-		pass
-	except Exception:
-		raise_redisearch_error()
-
-	idx_def = IndexDefinition([make_key(WEBSITE_ITEM_KEY_PREFIX)])
-
-	# Index fields mentioned in e-commerce settings
-	idx_fields = frappe.db.get_single_value("E Commerce Settings", "search_index_fields")
-	idx_fields = idx_fields.split(",") if idx_fields else []
-
-	if "web_item_name" in idx_fields:
-		idx_fields.remove("web_item_name")
-
-	idx_fields = [to_search_field(f) for f in idx_fields]
-
-	# TODO: sortable?
-	index.create_index(
-		[TextField("web_item_name", sortable=True)] + idx_fields,
-		definition=idx_def,
-	)
-
-	reindex_all_web_items()
-	define_autocomplete_dictionary()
-
-
-def to_search_field(field):
-	if field == "tags":
-		return TagField("tags", separator=",")
-
-	return TextField(field)
-
-
-@if_redisearch_enabled
-def insert_item_to_index(website_item_doc):
-	# Insert item to index
-	key = get_cache_key(website_item_doc.name)
-	cache = frappe.cache()
-	web_item = create_web_item_map(website_item_doc)
-
-	for field, value in web_item.items():
-		super(RedisWrapper, cache).hset(make_key(key), field, value)
-
-	insert_to_name_ac(website_item_doc.web_item_name, website_item_doc.name)
-
-
-@if_redisearch_enabled
-def insert_to_name_ac(web_name, doc_name):
-	ac = frappe.cache().ft()
-	ac.sugadd(WEBSITE_ITEM_NAME_AUTOCOMPLETE, Suggestion(web_name, payload=doc_name))
-
-
-def create_web_item_map(website_item_doc):
-	fields_to_index = get_fields_indexed()
-	web_item = {}
-
-	for field in fields_to_index:
-		web_item[field] = website_item_doc.get(field) or ""
-
-	return web_item
-
-
-@if_redisearch_enabled
-def update_index_for_item(website_item_doc):
-	# Reinsert to Cache
-	insert_item_to_index(website_item_doc)
-	define_autocomplete_dictionary()
-
-
-@if_redisearch_enabled
-def delete_item_from_index(website_item_doc):
-	cache = frappe.cache()
-	key = get_cache_key(website_item_doc.name)
-
-	try:
-		cache.delete(key)
-	except Exception:
-		raise_redisearch_error()
-
-	delete_from_ac_dict(website_item_doc)
-	return True
-
-
-@if_redisearch_enabled
-def delete_from_ac_dict(website_item_doc):
-	"""Removes this items's name from autocomplete dictionary"""
-	ac = frappe.cache().ft()
-	ac.sugdel(website_item_doc.web_item_name)
-
-
-@if_redisearch_enabled
-def define_autocomplete_dictionary():
-	"""
-	Defines/Redefines an autocomplete search dictionary for Website Item Name.
-	Also creats autocomplete dictionary for Published Item Groups.
-	"""
-
-	cache = frappe.cache()
-
-	# Delete both autocomplete dicts
-	try:
-		cache.delete(make_key(WEBSITE_ITEM_NAME_AUTOCOMPLETE))
-		cache.delete(make_key(WEBSITE_ITEM_CATEGORY_AUTOCOMPLETE))
-	except Exception:
-		raise_redisearch_error()
-
-	create_items_autocomplete_dict()
-	create_item_groups_autocomplete_dict()
-
-
-@if_redisearch_enabled
-def create_items_autocomplete_dict():
-	"Add items as suggestions in Autocompleter."
-
-	ac = frappe.cache().ft()
-	items = frappe.get_all(
-		"Website Item", fields=["web_item_name", "item_group"], filters={"published": 1}
-	)
-	for item in items:
-		ac.sugadd(WEBSITE_ITEM_NAME_AUTOCOMPLETE, Suggestion(item.web_item_name))
-
-
-@if_redisearch_enabled
-def create_item_groups_autocomplete_dict():
-	"Add item groups with weightage as suggestions in Autocompleter."
-
-	published_item_groups = frappe.get_all(
-		"Item Group", fields=["name", "route", "weightage"], filters={"show_in_website": 1}
-	)
-	if not published_item_groups:
-		return
-
-	ac = frappe.cache().ft()
-
-	for item_group in published_item_groups:
-		payload = json.dumps({"name": item_group.name, "route": item_group.route})
-		ac.sugadd(
-			WEBSITE_ITEM_CATEGORY_AUTOCOMPLETE,
-			Suggestion(
-				string=item_group.name,
-				score=frappe.utils.flt(item_group.weightage) or 1.0,
-				payload=payload,  # additional info that can be retrieved later
-			),
-		)
-
-
-@if_redisearch_enabled
-def reindex_all_web_items():
-	items = frappe.get_all("Website Item", fields=get_fields_indexed(), filters={"published": True})
-
-	cache = frappe.cache()
-	for item in items:
-		web_item = create_web_item_map(item)
-		key = make_key(get_cache_key(item.name))
-
-		for field, value in web_item.items():
-			super(RedisWrapper, cache).hset(key, field, value)
-
-
-def get_cache_key(name):
-	name = frappe.scrub(name)
-	return f"{WEBSITE_ITEM_KEY_PREFIX}{name}"
-
-
-def get_fields_indexed():
-	fields_to_index = frappe.db.get_single_value("E Commerce Settings", "search_index_fields")
-	fields_to_index = fields_to_index.split(",") if fields_to_index else []
-
-	mandatory_fields = ["name", "web_item_name", "route", "thumbnail", "ranking"]
-	fields_to_index = fields_to_index + mandatory_fields
-
-	return fields_to_index
-
-
-def raise_redisearch_error():
-	"Create an Error Log and raise error."
-	log = frappe.log_error("Redisearch Error")
-	log_link = frappe.utils.get_link_to_form("Error Log", log.name)
-
-	frappe.throw(
-		msg=_("Something went wrong. Check {0}").format(log_link), title=_("Redisearch Error")
-	)
diff --git a/erpnext/e_commerce/shopping_cart/__init__.py b/erpnext/e_commerce/shopping_cart/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/shopping_cart/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/shopping_cart/cart.py b/erpnext/e_commerce/shopping_cart/cart.py
deleted file mode 100644
index 7c7e169..0000000
--- a/erpnext/e_commerce/shopping_cart/cart.py
+++ /dev/null
@@ -1,721 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-import frappe
-import frappe.defaults
-from frappe import _, throw
-from frappe.contacts.doctype.address.address import get_address_display
-from frappe.contacts.doctype.contact.contact import get_contact_name
-from frappe.utils import cint, cstr, flt, get_fullname
-from frappe.utils.nestedset import get_root_of
-
-from erpnext.accounts.utils import get_account_name
-from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import (
-	get_shopping_cart_settings,
-)
-from erpnext.utilities.product import get_web_item_qty_in_stock
-
-
-class WebsitePriceListMissingError(frappe.ValidationError):
-	pass
-
-
-def set_cart_count(quotation=None):
-	if cint(frappe.db.get_singles_value("E Commerce Settings", "enabled")):
-		if not quotation:
-			quotation = _get_cart_quotation()
-		cart_count = cstr(cint(quotation.get("total_qty")))
-
-		if hasattr(frappe.local, "cookie_manager"):
-			frappe.local.cookie_manager.set_cookie("cart_count", cart_count)
-
-
-@frappe.whitelist()
-def get_cart_quotation(doc=None):
-	party = get_party()
-
-	if not doc:
-		quotation = _get_cart_quotation(party)
-		doc = quotation
-		set_cart_count(quotation)
-
-	addresses = get_address_docs(party=party)
-
-	if not doc.customer_address and addresses:
-		update_cart_address("billing", addresses[0].name)
-
-	return {
-		"doc": decorate_quotation_doc(doc),
-		"shipping_addresses": get_shipping_addresses(party),
-		"billing_addresses": get_billing_addresses(party),
-		"shipping_rules": get_applicable_shipping_rules(party),
-		"cart_settings": frappe.get_cached_doc("E Commerce Settings"),
-	}
-
-
-@frappe.whitelist()
-def get_shipping_addresses(party=None):
-	if not party:
-		party = get_party()
-	addresses = get_address_docs(party=party)
-	return [
-		{"name": address.name, "title": address.address_title, "display": address.display}
-		for address in addresses
-		if address.address_type == "Shipping"
-	]
-
-
-@frappe.whitelist()
-def get_billing_addresses(party=None):
-	if not party:
-		party = get_party()
-	addresses = get_address_docs(party=party)
-	return [
-		{"name": address.name, "title": address.address_title, "display": address.display}
-		for address in addresses
-		if address.address_type == "Billing"
-	]
-
-
-@frappe.whitelist()
-def place_order():
-	quotation = _get_cart_quotation()
-	cart_settings = frappe.db.get_value(
-		"E Commerce Settings", None, ["company", "allow_items_not_in_stock"], as_dict=1
-	)
-	quotation.company = cart_settings.company
-
-	quotation.flags.ignore_permissions = True
-	quotation.submit()
-
-	if quotation.quotation_to == "Lead" and quotation.party_name:
-		# company used to create customer accounts
-		frappe.defaults.set_user_default("company", quotation.company)
-
-	if not (quotation.shipping_address_name or quotation.customer_address):
-		frappe.throw(_("Set Shipping Address or Billing Address"))
-
-	from erpnext.selling.doctype.quotation.quotation import _make_sales_order
-
-	sales_order = frappe.get_doc(_make_sales_order(quotation.name, ignore_permissions=True))
-	sales_order.payment_schedule = []
-
-	if not cint(cart_settings.allow_items_not_in_stock):
-		for item in sales_order.get("items"):
-			item.warehouse = frappe.db.get_value(
-				"Website Item", {"item_code": item.item_code}, "website_warehouse"
-			)
-			is_stock_item = frappe.db.get_value("Item", item.item_code, "is_stock_item")
-
-			if is_stock_item:
-				item_stock = get_web_item_qty_in_stock(item.item_code, "website_warehouse")
-				if not cint(item_stock.in_stock):
-					throw(_("{0} Not in Stock").format(item.item_code))
-				if item.qty > item_stock.stock_qty:
-					throw(_("Only {0} in Stock for item {1}").format(item_stock.stock_qty, item.item_code))
-
-	sales_order.flags.ignore_permissions = True
-	sales_order.insert()
-	sales_order.submit()
-
-	if hasattr(frappe.local, "cookie_manager"):
-		frappe.local.cookie_manager.delete_cookie("cart_count")
-
-	return sales_order.name
-
-
-@frappe.whitelist()
-def request_for_quotation():
-	quotation = _get_cart_quotation()
-	quotation.flags.ignore_permissions = True
-
-	if get_shopping_cart_settings().save_quotations_as_draft:
-		quotation.save()
-	else:
-		quotation.submit()
-	return quotation.name
-
-
-@frappe.whitelist()
-def update_cart(item_code, qty, additional_notes=None, with_items=False):
-	quotation = _get_cart_quotation()
-
-	empty_card = False
-	qty = flt(qty)
-	if qty == 0:
-		quotation_items = quotation.get("items", {"item_code": ["!=", item_code]})
-		if quotation_items:
-			quotation.set("items", quotation_items)
-		else:
-			empty_card = True
-
-	else:
-		warehouse = frappe.get_cached_value(
-			"Website Item", {"item_code": item_code}, "website_warehouse"
-		)
-
-		quotation_items = quotation.get("items", {"item_code": item_code})
-		if not quotation_items:
-			quotation.append(
-				"items",
-				{
-					"doctype": "Quotation Item",
-					"item_code": item_code,
-					"qty": qty,
-					"additional_notes": additional_notes,
-					"warehouse": warehouse,
-				},
-			)
-		else:
-			quotation_items[0].qty = qty
-			quotation_items[0].additional_notes = additional_notes
-			quotation_items[0].warehouse = warehouse
-
-	apply_cart_settings(quotation=quotation)
-
-	quotation.flags.ignore_permissions = True
-	quotation.payment_schedule = []
-	if not empty_card:
-		quotation.save()
-	else:
-		quotation.delete()
-		quotation = None
-
-	set_cart_count(quotation)
-
-	if cint(with_items):
-		context = get_cart_quotation(quotation)
-		return {
-			"items": frappe.render_template("templates/includes/cart/cart_items.html", context),
-			"total": frappe.render_template("templates/includes/cart/cart_items_total.html", context),
-			"taxes_and_totals": frappe.render_template(
-				"templates/includes/cart/cart_payment_summary.html", context
-			),
-		}
-	else:
-		return {"name": quotation.name}
-
-
-@frappe.whitelist()
-def get_shopping_cart_menu(context=None):
-	if not context:
-		context = get_cart_quotation()
-
-	return frappe.render_template("templates/includes/cart/cart_dropdown.html", context)
-
-
-@frappe.whitelist()
-def add_new_address(doc):
-	doc = frappe.parse_json(doc)
-	doc.update({"doctype": "Address"})
-	address = frappe.get_doc(doc)
-	address.save(ignore_permissions=True)
-
-	return address
-
-
-@frappe.whitelist(allow_guest=True)
-def create_lead_for_item_inquiry(lead, subject, message):
-	lead = frappe.parse_json(lead)
-	lead_doc = frappe.new_doc("Lead")
-	for fieldname in ("lead_name", "company_name", "email_id", "phone"):
-		lead_doc.set(fieldname, lead.get(fieldname))
-
-	lead_doc.set("lead_owner", "")
-
-	if not frappe.db.exists("Lead Source", "Product Inquiry"):
-		frappe.get_doc({"doctype": "Lead Source", "source_name": "Product Inquiry"}).insert(
-			ignore_permissions=True
-		)
-
-	lead_doc.set("source", "Product Inquiry")
-
-	try:
-		lead_doc.save(ignore_permissions=True)
-	except frappe.exceptions.DuplicateEntryError:
-		frappe.clear_messages()
-		lead_doc = frappe.get_doc("Lead", {"email_id": lead["email_id"]})
-
-	lead_doc.add_comment(
-		"Comment",
-		text="""
-		<div>
-			<h5>{subject}</h5>
-			<p>{message}</p>
-		</div>
-	""".format(
-			subject=subject, message=message
-		),
-	)
-
-	return lead_doc
-
-
-@frappe.whitelist()
-def get_terms_and_conditions(terms_name):
-	return frappe.db.get_value("Terms and Conditions", terms_name, "terms")
-
-
-@frappe.whitelist()
-def update_cart_address(address_type, address_name):
-	quotation = _get_cart_quotation()
-	address_doc = frappe.get_doc("Address", address_name).as_dict()
-	address_display = get_address_display(address_doc)
-
-	if address_type.lower() == "billing":
-		quotation.customer_address = address_name
-		quotation.address_display = address_display
-		quotation.shipping_address_name = quotation.shipping_address_name or address_name
-		address_doc = next((doc for doc in get_billing_addresses() if doc["name"] == address_name), None)
-	elif address_type.lower() == "shipping":
-		quotation.shipping_address_name = address_name
-		quotation.shipping_address = address_display
-		quotation.customer_address = quotation.customer_address or address_name
-		address_doc = next(
-			(doc for doc in get_shipping_addresses() if doc["name"] == address_name), None
-		)
-	apply_cart_settings(quotation=quotation)
-
-	quotation.flags.ignore_permissions = True
-	quotation.save()
-
-	context = get_cart_quotation(quotation)
-	context["address"] = address_doc
-
-	return {
-		"taxes": frappe.render_template("templates/includes/order/order_taxes.html", context),
-		"address": frappe.render_template("templates/includes/cart/address_card.html", context),
-	}
-
-
-def guess_territory():
-	territory = None
-	geoip_country = frappe.session.get("session_country")
-	if geoip_country:
-		territory = frappe.db.get_value("Territory", geoip_country)
-
-	return (
-		territory
-		or frappe.db.get_value("E Commerce Settings", None, "territory")
-		or get_root_of("Territory")
-	)
-
-
-def decorate_quotation_doc(doc):
-	for d in doc.get("items", []):
-		item_code = d.item_code
-		fields = ["web_item_name", "thumbnail", "website_image", "description", "route"]
-
-		# Variant Item
-		if not frappe.db.exists("Website Item", {"item_code": item_code}):
-			variant_data = frappe.db.get_values(
-				"Item",
-				filters={"item_code": item_code},
-				fieldname=["variant_of", "item_name", "image"],
-				as_dict=True,
-			)[0]
-			item_code = variant_data.variant_of
-			fields = fields[1:]
-			d.web_item_name = variant_data.item_name
-
-			if variant_data.image:  # get image from variant or template web item
-				d.thumbnail = variant_data.image
-				fields = fields[2:]
-
-		d.update(frappe.db.get_value("Website Item", {"item_code": item_code}, fields, as_dict=True))
-		website_warehouse = frappe.get_cached_value(
-			"Website Item", {"item_code": item_code}, "website_warehouse"
-		)
-		d.warehouse = website_warehouse
-
-	return doc
-
-
-def _get_cart_quotation(party=None):
-	"""Return the open Quotation of type "Shopping Cart" or make a new one"""
-	if not party:
-		party = get_party()
-
-	quotation = frappe.get_all(
-		"Quotation",
-		fields=["name"],
-		filters={
-			"party_name": party.name,
-			"contact_email": frappe.session.user,
-			"order_type": "Shopping Cart",
-			"docstatus": 0,
-		},
-		order_by="modified desc",
-		limit_page_length=1,
-	)
-
-	if quotation:
-		qdoc = frappe.get_doc("Quotation", quotation[0].name)
-	else:
-		company = frappe.db.get_value("E Commerce Settings", None, ["company"])
-		qdoc = frappe.get_doc(
-			{
-				"doctype": "Quotation",
-				"naming_series": get_shopping_cart_settings().quotation_series or "QTN-CART-",
-				"quotation_to": party.doctype,
-				"company": company,
-				"order_type": "Shopping Cart",
-				"status": "Draft",
-				"docstatus": 0,
-				"__islocal": 1,
-				"party_name": party.name,
-			}
-		)
-
-		qdoc.contact_person = frappe.db.get_value("Contact", {"email_id": frappe.session.user})
-		qdoc.contact_email = frappe.session.user
-
-		qdoc.flags.ignore_permissions = True
-		qdoc.run_method("set_missing_values")
-		apply_cart_settings(party, qdoc)
-
-	return qdoc
-
-
-def update_party(fullname, company_name=None, mobile_no=None, phone=None):
-	party = get_party()
-
-	party.customer_name = company_name or fullname
-	party.customer_type = "Company" if company_name else "Individual"
-
-	contact_name = frappe.db.get_value("Contact", {"email_id": frappe.session.user})
-	contact = frappe.get_doc("Contact", contact_name)
-	contact.first_name = fullname
-	contact.last_name = None
-	contact.customer_name = party.customer_name
-	contact.mobile_no = mobile_no
-	contact.phone = phone
-	contact.flags.ignore_permissions = True
-	contact.save()
-
-	party_doc = frappe.get_doc(party.as_dict())
-	party_doc.flags.ignore_permissions = True
-	party_doc.save()
-
-	qdoc = _get_cart_quotation(party)
-	if not qdoc.get("__islocal"):
-		qdoc.customer_name = company_name or fullname
-		qdoc.run_method("set_missing_lead_customer_details")
-		qdoc.flags.ignore_permissions = True
-		qdoc.save()
-
-
-def apply_cart_settings(party=None, quotation=None):
-	if not party:
-		party = get_party()
-	if not quotation:
-		quotation = _get_cart_quotation(party)
-
-	cart_settings = frappe.get_doc("E Commerce Settings")
-
-	set_price_list_and_rate(quotation, cart_settings)
-
-	quotation.run_method("calculate_taxes_and_totals")
-
-	set_taxes(quotation, cart_settings)
-
-	_apply_shipping_rule(party, quotation, cart_settings)
-
-
-def set_price_list_and_rate(quotation, cart_settings):
-	"""set price list based on billing territory"""
-
-	_set_price_list(cart_settings, quotation)
-
-	# reset values
-	quotation.price_list_currency = (
-		quotation.currency
-	) = quotation.plc_conversion_rate = quotation.conversion_rate = None
-	for item in quotation.get("items"):
-		item.price_list_rate = item.discount_percentage = item.rate = item.amount = None
-
-	# refetch values
-	quotation.run_method("set_price_list_and_item_details")
-
-	if hasattr(frappe.local, "cookie_manager"):
-		# set it in cookies for using in product page
-		frappe.local.cookie_manager.set_cookie("selling_price_list", quotation.selling_price_list)
-
-
-def _set_price_list(cart_settings, quotation=None):
-	"""Set price list based on customer or shopping cart default"""
-	from erpnext.accounts.party import get_default_price_list
-
-	party_name = quotation.get("party_name") if quotation else get_party().get("name")
-	selling_price_list = None
-
-	# check if default customer price list exists
-	if party_name and frappe.db.exists("Customer", party_name):
-		selling_price_list = get_default_price_list(frappe.get_doc("Customer", party_name))
-
-	# check default price list in shopping cart
-	if not selling_price_list:
-		selling_price_list = cart_settings.price_list
-
-	if quotation:
-		quotation.selling_price_list = selling_price_list
-
-	return selling_price_list
-
-
-def set_taxes(quotation, cart_settings):
-	"""set taxes based on billing territory"""
-	from erpnext.accounts.party import set_taxes
-
-	customer_group = frappe.db.get_value("Customer", quotation.party_name, "customer_group")
-
-	quotation.taxes_and_charges = set_taxes(
-		quotation.party_name,
-		"Customer",
-		quotation.transaction_date,
-		quotation.company,
-		customer_group=customer_group,
-		supplier_group=None,
-		tax_category=quotation.tax_category,
-		billing_address=quotation.customer_address,
-		shipping_address=quotation.shipping_address_name,
-		use_for_shopping_cart=1,
-	)
-	#
-	# 	# clear table
-	quotation.set("taxes", [])
-	#
-	# 	# append taxes
-	quotation.append_taxes_from_master()
-
-
-def get_party(user=None):
-	if not user:
-		user = frappe.session.user
-
-	contact_name = get_contact_name(user)
-	party = None
-
-	if contact_name:
-		contact = frappe.get_doc("Contact", contact_name)
-		if contact.links:
-			party_doctype = contact.links[0].link_doctype
-			party = contact.links[0].link_name
-
-	cart_settings = frappe.get_doc("E Commerce Settings")
-
-	debtors_account = ""
-
-	if cart_settings.enable_checkout:
-		debtors_account = get_debtors_account(cart_settings)
-
-	if party:
-		return frappe.get_doc(party_doctype, party)
-
-	else:
-		if not cart_settings.enabled:
-			frappe.local.flags.redirect_location = "/contact"
-			raise frappe.Redirect
-		customer = frappe.new_doc("Customer")
-		fullname = get_fullname(user)
-		customer.update(
-			{
-				"customer_name": fullname,
-				"customer_type": "Individual",
-				"customer_group": get_shopping_cart_settings().default_customer_group,
-				"territory": get_root_of("Territory"),
-			}
-		)
-
-		customer.append("portal_users", {"user": user})
-
-		if debtors_account:
-			customer.update({"accounts": [{"company": cart_settings.company, "account": debtors_account}]})
-
-		customer.flags.ignore_mandatory = True
-		customer.insert(ignore_permissions=True)
-
-		contact = frappe.new_doc("Contact")
-		contact.update({"first_name": fullname, "email_ids": [{"email_id": user, "is_primary": 1}]})
-		contact.append("links", dict(link_doctype="Customer", link_name=customer.name))
-		contact.flags.ignore_mandatory = True
-		contact.insert(ignore_permissions=True)
-
-		return customer
-
-
-def get_debtors_account(cart_settings):
-	if not cart_settings.payment_gateway_account:
-		frappe.throw(_("Payment Gateway Account not set"), _("Mandatory"))
-
-	payment_gateway_account_currency = frappe.get_doc(
-		"Payment Gateway Account", cart_settings.payment_gateway_account
-	).currency
-
-	account_name = _("Debtors ({0})").format(payment_gateway_account_currency)
-
-	debtors_account_name = get_account_name(
-		"Receivable",
-		"Asset",
-		is_group=0,
-		account_currency=payment_gateway_account_currency,
-		company=cart_settings.company,
-	)
-
-	if not debtors_account_name:
-		debtors_account = frappe.get_doc(
-			{
-				"doctype": "Account",
-				"account_type": "Receivable",
-				"root_type": "Asset",
-				"is_group": 0,
-				"parent_account": get_account_name(
-					root_type="Asset", is_group=1, company=cart_settings.company
-				),
-				"account_name": account_name,
-				"currency": payment_gateway_account_currency,
-			}
-		).insert(ignore_permissions=True)
-
-		return debtors_account.name
-
-	else:
-		return debtors_account_name
-
-
-def get_address_docs(
-	doctype=None, txt=None, filters=None, limit_start=0, limit_page_length=20, party=None
-):
-	if not party:
-		party = get_party()
-
-	if not party:
-		return []
-
-	address_names = frappe.db.get_all(
-		"Dynamic Link",
-		fields=("parent"),
-		filters=dict(parenttype="Address", link_doctype=party.doctype, link_name=party.name),
-	)
-
-	out = []
-
-	for a in address_names:
-		address = frappe.get_doc("Address", a.parent)
-		address.display = get_address_display(address.as_dict())
-		out.append(address)
-
-	return out
-
-
-@frappe.whitelist()
-def apply_shipping_rule(shipping_rule):
-	quotation = _get_cart_quotation()
-
-	quotation.shipping_rule = shipping_rule
-
-	apply_cart_settings(quotation=quotation)
-
-	quotation.flags.ignore_permissions = True
-	quotation.save()
-
-	return get_cart_quotation(quotation)
-
-
-def _apply_shipping_rule(party=None, quotation=None, cart_settings=None):
-	if not quotation.shipping_rule:
-		shipping_rules = get_shipping_rules(quotation, cart_settings)
-
-		if not shipping_rules:
-			return
-
-		elif quotation.shipping_rule not in shipping_rules:
-			quotation.shipping_rule = shipping_rules[0]
-
-	if quotation.shipping_rule:
-		quotation.run_method("apply_shipping_rule")
-		quotation.run_method("calculate_taxes_and_totals")
-
-
-def get_applicable_shipping_rules(party=None, quotation=None):
-	shipping_rules = get_shipping_rules(quotation)
-
-	if shipping_rules:
-		# we need this in sorted order as per the position of the rule in the settings page
-		return [[rule, rule] for rule in shipping_rules]
-
-
-def get_shipping_rules(quotation=None, cart_settings=None):
-	if not quotation:
-		quotation = _get_cart_quotation()
-
-	shipping_rules = []
-	if quotation.shipping_address_name:
-		country = frappe.db.get_value("Address", quotation.shipping_address_name, "country")
-		if country:
-			sr_country = frappe.qb.DocType("Shipping Rule Country")
-			sr = frappe.qb.DocType("Shipping Rule")
-			query = (
-				frappe.qb.from_(sr_country)
-				.join(sr)
-				.on(sr.name == sr_country.parent)
-				.select(sr.name)
-				.distinct()
-				.where((sr_country.country == country) & (sr.disabled != 1))
-			)
-			result = query.run(as_list=True)
-			shipping_rules = [x[0] for x in result]
-
-	return shipping_rules
-
-
-def get_address_territory(address_name):
-	"""Tries to match city, state and country of address to existing territory"""
-	territory = None
-
-	if address_name:
-		address_fields = frappe.db.get_value("Address", address_name, ["city", "state", "country"])
-		for value in address_fields:
-			territory = frappe.db.get_value("Territory", value)
-			if territory:
-				break
-
-	return territory
-
-
-def show_terms(doc):
-	return doc.tc_name
-
-
-@frappe.whitelist(allow_guest=True)
-def apply_coupon_code(applied_code, applied_referral_sales_partner):
-	quotation = True
-
-	if not applied_code:
-		frappe.throw(_("Please enter a coupon code"))
-
-	coupon_list = frappe.get_all("Coupon Code", filters={"coupon_code": applied_code})
-	if not coupon_list:
-		frappe.throw(_("Please enter a valid coupon code"))
-
-	coupon_name = coupon_list[0].name
-
-	from erpnext.accounts.doctype.pricing_rule.utils import validate_coupon_code
-
-	validate_coupon_code(coupon_name)
-	quotation = _get_cart_quotation()
-	quotation.coupon_code = coupon_name
-	quotation.flags.ignore_permissions = True
-	quotation.save()
-
-	if applied_referral_sales_partner:
-		sales_partner_list = frappe.get_all(
-			"Sales Partner", filters={"referral_code": applied_referral_sales_partner}
-		)
-		if sales_partner_list:
-			sales_partner_name = sales_partner_list[0].name
-			quotation.referral_sales_partner = sales_partner_name
-			quotation.flags.ignore_permissions = True
-			quotation.save()
-
-	return quotation
diff --git a/erpnext/e_commerce/shopping_cart/product_info.py b/erpnext/e_commerce/shopping_cart/product_info.py
deleted file mode 100644
index 0248ca7..0000000
--- a/erpnext/e_commerce/shopping_cart/product_info.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-import frappe
-
-from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import (
-	get_shopping_cart_settings,
-	show_quantity_in_website,
-)
-from erpnext.e_commerce.shopping_cart.cart import _get_cart_quotation, _set_price_list
-from erpnext.utilities.product import (
-	get_non_stock_item_status,
-	get_price,
-	get_web_item_qty_in_stock,
-)
-
-
-@frappe.whitelist(allow_guest=True)
-def get_product_info_for_website(item_code, skip_quotation_creation=False):
-	"""get product price / stock info for website"""
-
-	cart_settings = get_shopping_cart_settings()
-	if not cart_settings.enabled:
-		# return settings even if cart is disabled
-		return frappe._dict({"product_info": {}, "cart_settings": cart_settings})
-
-	cart_quotation = frappe._dict()
-	if not skip_quotation_creation:
-		cart_quotation = _get_cart_quotation()
-
-	selling_price_list = (
-		cart_quotation.get("selling_price_list")
-		if cart_quotation
-		else _set_price_list(cart_settings, None)
-	)
-
-	price = {}
-	if cart_settings.show_price:
-		is_guest = frappe.session.user == "Guest"
-		# Show Price if logged in.
-		# If not logged in, check if price is hidden for guest.
-		if not is_guest or not cart_settings.hide_price_for_guest:
-			price = get_price(
-				item_code, selling_price_list, cart_settings.default_customer_group, cart_settings.company
-			)
-
-	stock_status = None
-
-	if cart_settings.show_stock_availability:
-		on_backorder = frappe.get_cached_value("Website Item", {"item_code": item_code}, "on_backorder")
-		if on_backorder:
-			stock_status = frappe._dict({"on_backorder": True})
-		else:
-			stock_status = get_web_item_qty_in_stock(item_code, "website_warehouse")
-
-	product_info = {
-		"price": price,
-		"qty": 0,
-		"uom": frappe.db.get_value("Item", item_code, "stock_uom"),
-		"sales_uom": frappe.db.get_value("Item", item_code, "sales_uom"),
-	}
-
-	if stock_status:
-		if stock_status.on_backorder:
-			product_info["on_backorder"] = True
-		else:
-			product_info["stock_qty"] = stock_status.stock_qty
-			product_info["in_stock"] = (
-				stock_status.in_stock
-				if stock_status.is_stock_item
-				else get_non_stock_item_status(item_code, "website_warehouse")
-			)
-			product_info["show_stock_qty"] = show_quantity_in_website()
-
-	if product_info["price"]:
-		if frappe.session.user != "Guest":
-			item = cart_quotation.get({"item_code": item_code}) if cart_quotation else None
-			if item:
-				product_info["qty"] = item[0].qty
-
-	return frappe._dict({"product_info": product_info, "cart_settings": cart_settings})
-
-
-def set_product_info_for_website(item):
-	"""set product price uom for website"""
-	product_info = get_product_info_for_website(item.item_code, skip_quotation_creation=True).get(
-		"product_info"
-	)
-
-	if product_info:
-		item.update(product_info)
-		item["stock_uom"] = product_info.get("uom")
-		item["sales_uom"] = product_info.get("sales_uom")
-		if product_info.get("price"):
-			item["price_stock_uom"] = product_info.get("price").get("formatted_price")
-			item["price_sales_uom"] = product_info.get("price").get("formatted_price_sales_uom")
-		else:
-			item["price_stock_uom"] = ""
-			item["price_sales_uom"] = ""
diff --git a/erpnext/e_commerce/shopping_cart/test_shopping_cart.py b/erpnext/e_commerce/shopping_cart/test_shopping_cart.py
deleted file mode 100644
index 951039d..0000000
--- a/erpnext/e_commerce/shopping_cart/test_shopping_cart.py
+++ /dev/null
@@ -1,347 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-
-import unittest
-
-import frappe
-from frappe.tests.utils import change_settings
-from frappe.utils import add_months, cint, nowdate
-
-from erpnext.accounts.doctype.tax_rule.tax_rule import ConflictingTaxRule
-from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
-from erpnext.e_commerce.shopping_cart.cart import (
-	_get_cart_quotation,
-	get_cart_quotation,
-	get_party,
-	request_for_quotation,
-	update_cart,
-)
-from erpnext.tests.utils import create_test_contact_and_address
-
-
-class TestShoppingCart(unittest.TestCase):
-	"""
-	Note:
-	Shopping Cart == Quotation
-	"""
-
-	def setUp(self):
-		frappe.set_user("Administrator")
-		create_test_contact_and_address()
-		self.enable_shopping_cart()
-		if not frappe.db.exists("Website Item", {"item_code": "_Test Item"}):
-			make_website_item(frappe.get_cached_doc("Item", "_Test Item"))
-
-		if not frappe.db.exists("Website Item", {"item_code": "_Test Item 2"}):
-			make_website_item(frappe.get_cached_doc("Item", "_Test Item 2"))
-
-	def tearDown(self):
-		frappe.db.rollback()
-		frappe.set_user("Administrator")
-		self.disable_shopping_cart()
-
-	@classmethod
-	def tearDownClass(cls):
-		frappe.db.sql("delete from `tabTax Rule`")
-
-	def test_get_cart_new_user(self):
-		self.login_as_new_user()
-
-		# test if lead is created and quotation with new lead is fetched
-		quotation = _get_cart_quotation()
-		self.assertEqual(quotation.quotation_to, "Customer")
-		self.assertEqual(
-			quotation.contact_person,
-			frappe.db.get_value("Contact", dict(email_id="test_cart_user@example.com")),
-		)
-		self.assertEqual(quotation.contact_email, frappe.session.user)
-
-		return quotation
-
-	def test_get_cart_customer(self):
-		def validate_quotation():
-			# test if quotation with customer is fetched
-			quotation = _get_cart_quotation()
-			self.assertEqual(quotation.quotation_to, "Customer")
-			self.assertEqual(quotation.party_name, "_Test Customer")
-			self.assertEqual(quotation.contact_email, frappe.session.user)
-			return quotation
-
-		self.login_as_customer(
-			"test_contact_two_customer@example.com", "_Test Contact 2 For _Test Customer"
-		)
-		validate_quotation()
-
-		self.login_as_customer()
-		quotation = validate_quotation()
-
-		return quotation
-
-	def test_add_to_cart(self):
-		self.login_as_customer()
-
-		# clear existing quotations
-		self.clear_existing_quotations()
-
-		# add first item
-		update_cart("_Test Item", 1)
-
-		quotation = self.test_get_cart_customer()
-
-		self.assertEqual(quotation.get("items")[0].item_code, "_Test Item")
-		self.assertEqual(quotation.get("items")[0].qty, 1)
-		self.assertEqual(quotation.get("items")[0].amount, 10)
-
-		# add second item
-		update_cart("_Test Item 2", 1)
-		quotation = self.test_get_cart_customer()
-		self.assertEqual(quotation.get("items")[1].item_code, "_Test Item 2")
-		self.assertEqual(quotation.get("items")[1].qty, 1)
-		self.assertEqual(quotation.get("items")[1].amount, 20)
-
-		self.assertEqual(len(quotation.get("items")), 2)
-
-	def test_update_cart(self):
-		# first, add to cart
-		self.test_add_to_cart()
-
-		# update first item
-		update_cart("_Test Item", 5)
-		quotation = self.test_get_cart_customer()
-		self.assertEqual(quotation.get("items")[0].item_code, "_Test Item")
-		self.assertEqual(quotation.get("items")[0].qty, 5)
-		self.assertEqual(quotation.get("items")[0].amount, 50)
-		self.assertEqual(quotation.net_total, 70)
-		self.assertEqual(len(quotation.get("items")), 2)
-
-	def test_remove_from_cart(self):
-		# first, add to cart
-		self.test_add_to_cart()
-
-		# remove first item
-		update_cart("_Test Item", 0)
-		quotation = self.test_get_cart_customer()
-
-		self.assertEqual(quotation.get("items")[0].item_code, "_Test Item 2")
-		self.assertEqual(quotation.get("items")[0].qty, 1)
-		self.assertEqual(quotation.get("items")[0].amount, 20)
-		self.assertEqual(quotation.net_total, 20)
-		self.assertEqual(len(quotation.get("items")), 1)
-
-	@unittest.skip("Flaky in CI")
-	def test_tax_rule(self):
-		self.create_tax_rule()
-		self.login_as_customer()
-		quotation = self.create_quotation()
-
-		from erpnext.accounts.party import set_taxes
-
-		tax_rule_master = set_taxes(
-			quotation.party_name,
-			"Customer",
-			None,
-			quotation.company,
-			customer_group=None,
-			supplier_group=None,
-			tax_category=quotation.tax_category,
-			billing_address=quotation.customer_address,
-			shipping_address=quotation.shipping_address_name,
-			use_for_shopping_cart=1,
-		)
-
-		self.assertEqual(quotation.taxes_and_charges, tax_rule_master)
-		self.assertEqual(quotation.total_taxes_and_charges, 1000.0)
-
-		self.remove_test_quotation(quotation)
-
-	@change_settings(
-		"E Commerce Settings",
-		{
-			"company": "_Test Company",
-			"enabled": 1,
-			"default_customer_group": "_Test Customer Group",
-			"price_list": "_Test Price List India",
-			"show_price": 1,
-		},
-	)
-	def test_add_item_variant_without_web_item_to_cart(self):
-		"Test adding Variants having no Website Items in cart via Template Web Item."
-		from erpnext.controllers.item_variant import create_variant
-		from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
-		from erpnext.stock.doctype.item.test_item import make_item
-
-		template_item = make_item(
-			"Test-Tshirt-Temp",
-			{
-				"has_variant": 1,
-				"variant_based_on": "Item Attribute",
-				"attributes": [{"attribute": "Test Size"}, {"attribute": "Test Colour"}],
-			},
-		)
-		variant = create_variant("Test-Tshirt-Temp", {"Test Size": "Small", "Test Colour": "Red"})
-		variant.save()
-		make_website_item(template_item)  # publish template not variant
-
-		update_cart("Test-Tshirt-Temp-S-R", 1)
-
-		cart = get_cart_quotation()  # test if cart page gets data without errors
-		doc = cart.get("doc")
-
-		self.assertEqual(doc.get("items")[0].item_name, "Test-Tshirt-Temp-S-R")
-
-		# test if items are rendered without error
-		frappe.render_template("templates/includes/cart/cart_items.html", cart)
-
-	@change_settings("E Commerce Settings", {"save_quotations_as_draft": 1})
-	def test_cart_without_checkout_and_draft_quotation(self):
-		"Test impact of 'save_quotations_as_draft' checkbox."
-		frappe.local.shopping_cart_settings = None
-
-		# add item to cart
-		update_cart("_Test Item", 1)
-		quote_name = request_for_quotation()  # Request for Quote
-		quote_doctstatus = cint(frappe.db.get_value("Quotation", quote_name, "docstatus"))
-
-		self.assertEqual(quote_doctstatus, 0)
-
-		frappe.db.set_single_value("E Commerce Settings", "save_quotations_as_draft", 0)
-		frappe.local.shopping_cart_settings = None
-		update_cart("_Test Item", 1)
-		quote_name = request_for_quotation()  # Request for Quote
-		quote_doctstatus = cint(frappe.db.get_value("Quotation", quote_name, "docstatus"))
-
-		self.assertEqual(quote_doctstatus, 1)
-
-	def create_tax_rule(self):
-		tax_rule = frappe.get_test_records("Tax Rule")[0]
-		try:
-			frappe.get_doc(tax_rule).insert(ignore_if_duplicate=True)
-		except (frappe.DuplicateEntryError, ConflictingTaxRule):
-			pass
-
-	def create_quotation(self):
-		quotation = frappe.new_doc("Quotation")
-
-		values = {
-			"doctype": "Quotation",
-			"quotation_to": "Customer",
-			"order_type": "Shopping Cart",
-			"party_name": get_party(frappe.session.user).name,
-			"docstatus": 0,
-			"contact_email": frappe.session.user,
-			"selling_price_list": "_Test Price List Rest of the World",
-			"currency": "USD",
-			"taxes_and_charges": "_Test Tax 1 - _TC",
-			"conversion_rate": 1,
-			"transaction_date": nowdate(),
-			"valid_till": add_months(nowdate(), 1),
-			"items": [{"item_code": "_Test Item", "qty": 1}],
-			"taxes": frappe.get_doc("Sales Taxes and Charges Template", "_Test Tax 1 - _TC").taxes,
-			"company": "_Test Company",
-		}
-
-		quotation.update(values)
-
-		quotation.insert(ignore_permissions=True)
-
-		return quotation
-
-	def remove_test_quotation(self, quotation):
-		frappe.set_user("Administrator")
-		quotation.delete()
-
-	# helper functions
-	def enable_shopping_cart(self):
-		settings = frappe.get_doc("E Commerce Settings", "E Commerce Settings")
-
-		settings.update(
-			{
-				"enabled": 1,
-				"company": "_Test Company",
-				"default_customer_group": "_Test Customer Group",
-				"quotation_series": "_T-Quotation-",
-				"price_list": "_Test Price List India",
-			}
-		)
-
-		# insert item price
-		if not frappe.db.get_value(
-			"Item Price", {"price_list": "_Test Price List India", "item_code": "_Test Item"}
-		):
-			frappe.get_doc(
-				{
-					"doctype": "Item Price",
-					"price_list": "_Test Price List India",
-					"item_code": "_Test Item",
-					"price_list_rate": 10,
-				}
-			).insert()
-			frappe.get_doc(
-				{
-					"doctype": "Item Price",
-					"price_list": "_Test Price List India",
-					"item_code": "_Test Item 2",
-					"price_list_rate": 20,
-				}
-			).insert()
-
-		settings.save()
-		frappe.local.shopping_cart_settings = None
-
-	def disable_shopping_cart(self):
-		settings = frappe.get_doc("E Commerce Settings", "E Commerce Settings")
-		settings.enabled = 0
-		settings.save()
-		frappe.local.shopping_cart_settings = None
-
-	def login_as_new_user(self):
-		self.create_user_if_not_exists("test_cart_user@example.com")
-		frappe.set_user("test_cart_user@example.com")
-
-	def login_as_customer(
-		self, email="test_contact_customer@example.com", name="_Test Contact For _Test Customer"
-	):
-		self.create_user_if_not_exists(email, name)
-		frappe.set_user(email)
-
-	def clear_existing_quotations(self):
-		quotations = frappe.get_all(
-			"Quotation",
-			filters={"party_name": get_party().name, "order_type": "Shopping Cart", "docstatus": 0},
-			order_by="modified desc",
-			pluck="name",
-		)
-
-		for quotation in quotations:
-			frappe.delete_doc("Quotation", quotation, ignore_permissions=True, force=True)
-
-	def create_user_if_not_exists(self, email, first_name=None):
-		if frappe.db.exists("User", email):
-			return
-
-		frappe.get_doc(
-			{
-				"doctype": "User",
-				"user_type": "Website User",
-				"email": email,
-				"send_welcome_email": 0,
-				"first_name": first_name or email.split("@")[0],
-			}
-		).insert(ignore_permissions=True)
-
-
-test_dependencies = [
-	"Sales Taxes and Charges Template",
-	"Price List",
-	"Item Price",
-	"Shipping Rule",
-	"Currency Exchange",
-	"Customer Group",
-	"Lead",
-	"Customer",
-	"Contact",
-	"Address",
-	"Item",
-	"Tax Rule",
-]
diff --git a/erpnext/e_commerce/shopping_cart/utils.py b/erpnext/e_commerce/shopping_cart/utils.py
deleted file mode 100644
index 3d48c28..0000000
--- a/erpnext/e_commerce/shopping_cart/utils.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-import frappe
-
-from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import is_cart_enabled
-
-
-def show_cart_count():
-	if (
-		is_cart_enabled()
-		and frappe.db.get_value("User", frappe.session.user, "user_type") == "Website User"
-	):
-		return True
-
-	return False
-
-
-def set_cart_count(login_manager):
-	# since this is run only on hooks login event
-	# make sure user is already a customer
-	# before trying to set cart count
-	user_is_customer = is_customer()
-	if not user_is_customer:
-		return
-
-	if show_cart_count():
-		from erpnext.e_commerce.shopping_cart.cart import set_cart_count
-
-		# set_cart_count will try to fetch existing cart quotation
-		# or create one if non existent (and create a customer too)
-		# cart count is calculated from this quotation's items
-		set_cart_count()
-
-
-def clear_cart_count(login_manager):
-	if show_cart_count():
-		frappe.local.cookie_manager.delete_cookie("cart_count")
-
-
-def update_website_context(context):
-	cart_enabled = is_cart_enabled()
-	context["shopping_cart_enabled"] = cart_enabled
-
-
-def is_customer():
-	if frappe.session.user and frappe.session.user != "Guest":
-		contact_name = frappe.get_value("Contact", {"email_id": frappe.session.user})
-		if contact_name:
-			contact = frappe.get_doc("Contact", contact_name)
-			for link in contact.links:
-				if link.link_doctype == "Customer":
-					return True
-
-		return False
diff --git a/erpnext/e_commerce/variant_selector/__init__.py b/erpnext/e_commerce/variant_selector/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/variant_selector/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/variant_selector/item_variants_cache.py b/erpnext/e_commerce/variant_selector/item_variants_cache.py
deleted file mode 100644
index f8439d5..0000000
--- a/erpnext/e_commerce/variant_selector/item_variants_cache.py
+++ /dev/null
@@ -1,130 +0,0 @@
-import frappe
-
-
-class ItemVariantsCacheManager:
-	def __init__(self, item_code):
-		self.item_code = item_code
-
-	def get_item_variants_data(self):
-		val = frappe.cache().hget("item_variants_data", self.item_code)
-
-		if not val:
-			self.build_cache()
-
-		return frappe.cache().hget("item_variants_data", self.item_code)
-
-	def get_attribute_value_item_map(self):
-		val = frappe.cache().hget("attribute_value_item_map", self.item_code)
-
-		if not val:
-			self.build_cache()
-
-		return frappe.cache().hget("attribute_value_item_map", self.item_code)
-
-	def get_item_attribute_value_map(self):
-		val = frappe.cache().hget("item_attribute_value_map", self.item_code)
-
-		if not val:
-			self.build_cache()
-
-		return frappe.cache().hget("item_attribute_value_map", self.item_code)
-
-	def get_optional_attributes(self):
-		val = frappe.cache().hget("optional_attributes", self.item_code)
-
-		if not val:
-			self.build_cache()
-
-		return frappe.cache().hget("optional_attributes", self.item_code)
-
-	def get_ordered_attribute_values(self):
-		val = frappe.cache().get_value("ordered_attribute_values_map")
-		if val:
-			return val
-
-		all_attribute_values = frappe.get_all(
-			"Item Attribute Value", ["attribute_value", "idx", "parent"], order_by="idx asc"
-		)
-
-		ordered_attribute_values_map = frappe._dict({})
-		for d in all_attribute_values:
-			ordered_attribute_values_map.setdefault(d.parent, []).append(d.attribute_value)
-
-		frappe.cache().set_value("ordered_attribute_values_map", ordered_attribute_values_map)
-		return ordered_attribute_values_map
-
-	def build_cache(self):
-		parent_item_code = self.item_code
-
-		attributes = [
-			a.attribute
-			for a in frappe.get_all(
-				"Item Variant Attribute", {"parent": parent_item_code}, ["attribute"], order_by="idx asc"
-			)
-		]
-
-		# Get Variants and tehir Attributes that are not disabled
-		iva = frappe.qb.DocType("Item Variant Attribute")
-		item = frappe.qb.DocType("Item")
-		query = (
-			frappe.qb.from_(iva)
-			.join(item)
-			.on(item.name == iva.parent)
-			.select(iva.parent, iva.attribute, iva.attribute_value)
-			.where((iva.variant_of == parent_item_code) & (item.disabled == 0))
-			.orderby(iva.name)
-		)
-		item_variants_data = query.run()
-
-		attribute_value_item_map = frappe._dict()
-		item_attribute_value_map = frappe._dict()
-
-		for row in item_variants_data:
-			item_code, attribute, attribute_value = row
-			# (attr, value) => [item1, item2]
-			attribute_value_item_map.setdefault((attribute, attribute_value), []).append(item_code)
-			# item => {attr1: value1, attr2: value2}
-			item_attribute_value_map.setdefault(item_code, {})[attribute] = attribute_value
-
-		optional_attributes = set()
-		for item_code, attr_dict in item_attribute_value_map.items():
-			for attribute in attributes:
-				if attribute not in attr_dict:
-					optional_attributes.add(attribute)
-
-		frappe.cache().hset("attribute_value_item_map", parent_item_code, attribute_value_item_map)
-		frappe.cache().hset("item_attribute_value_map", parent_item_code, item_attribute_value_map)
-		frappe.cache().hset("item_variants_data", parent_item_code, item_variants_data)
-		frappe.cache().hset("optional_attributes", parent_item_code, optional_attributes)
-
-	def clear_cache(self):
-		keys = [
-			"attribute_value_item_map",
-			"item_attribute_value_map",
-			"item_variants_data",
-			"optional_attributes",
-		]
-
-		for key in keys:
-			frappe.cache().hdel(key, self.item_code)
-
-	def rebuild_cache(self):
-		self.clear_cache()
-		enqueue_build_cache(self.item_code)
-
-
-def build_cache(item_code):
-	frappe.cache().hset("item_cache_build_in_progress", item_code, 1)
-	i = ItemVariantsCacheManager(item_code)
-	i.build_cache()
-	frappe.cache().hset("item_cache_build_in_progress", item_code, 0)
-
-
-def enqueue_build_cache(item_code):
-	if frappe.cache().hget("item_cache_build_in_progress", item_code):
-		return
-	frappe.enqueue(
-		"erpnext.e_commerce.variant_selector.item_variants_cache.build_cache",
-		item_code=item_code,
-		queue="long",
-	)
diff --git a/erpnext/e_commerce/variant_selector/test_variant_selector.py b/erpnext/e_commerce/variant_selector/test_variant_selector.py
deleted file mode 100644
index 8eb497c..0000000
--- a/erpnext/e_commerce/variant_selector/test_variant_selector.py
+++ /dev/null
@@ -1,125 +0,0 @@
-import frappe
-from frappe.tests.utils import FrappeTestCase
-
-from erpnext.controllers.item_variant import create_variant
-from erpnext.e_commerce.doctype.e_commerce_settings.test_e_commerce_settings import (
-	setup_e_commerce_settings,
-)
-from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
-from erpnext.e_commerce.variant_selector.utils import get_next_attribute_and_values
-from erpnext.stock.doctype.item.test_item import make_item
-
-test_dependencies = ["Item"]
-
-
-class TestVariantSelector(FrappeTestCase):
-	@classmethod
-	def setUpClass(cls):
-		super().setUpClass()
-		template_item = make_item(
-			"Test-Tshirt-Temp",
-			{
-				"has_variant": 1,
-				"variant_based_on": "Item Attribute",
-				"attributes": [{"attribute": "Test Size"}, {"attribute": "Test Colour"}],
-			},
-		)
-
-		# create L-R, L-G, M-R, M-G and S-R
-		for size in (
-			"Large",
-			"Medium",
-		):
-			for colour in (
-				"Red",
-				"Green",
-			):
-				variant = create_variant("Test-Tshirt-Temp", {"Test Size": size, "Test Colour": colour})
-				variant.save()
-
-		variant = create_variant("Test-Tshirt-Temp", {"Test Size": "Small", "Test Colour": "Red"})
-		variant.save()
-
-		make_website_item(template_item)  # publish template not variants
-
-	def test_item_attributes(self):
-		"""
-		Test if the right attributes are fetched in the popup.
-		(Attributes must only come from active items)
-
-		Attribute selection must not be linked to Website Items.
-		"""
-		from erpnext.e_commerce.variant_selector.utils import get_attributes_and_values
-
-		attr_data = get_attributes_and_values("Test-Tshirt-Temp")
-
-		self.assertEqual(attr_data[0]["attribute"], "Test Size")
-		self.assertEqual(attr_data[1]["attribute"], "Test Colour")
-		self.assertEqual(len(attr_data[0]["values"]), 3)  # ['Small', 'Medium', 'Large']
-		self.assertEqual(len(attr_data[1]["values"]), 2)  # ['Red', 'Green']
-
-		# disable small red tshirt, now there are no small tshirts.
-		# but there are some red tshirts
-		small_variant = frappe.get_doc("Item", "Test-Tshirt-Temp-S-R")
-		small_variant.disabled = 1
-		small_variant.save()  # trigger cache rebuild
-
-		attr_data = get_attributes_and_values("Test-Tshirt-Temp")
-
-		# Only L and M attribute values must be fetched since S is disabled
-		self.assertEqual(len(attr_data[0]["values"]), 2)  # ['Medium', 'Large']
-
-		# teardown
-		small_variant.disabled = 0
-		small_variant.save()
-
-	def test_next_item_variant_values(self):
-		"""
-		Test if on selecting an attribute value, the next possible values
-		are filtered accordingly.
-		Values that dont apply should not be fetched.
-		E.g.
-		There is a ** Small-Red ** Tshirt. No other colour in this size.
-		On selecting ** Small **, only ** Red ** should be selectable next.
-		"""
-		next_values = get_next_attribute_and_values(
-			"Test-Tshirt-Temp", selected_attributes={"Test Size": "Small"}
-		)
-		next_colours = next_values["valid_options_for_attributes"]["Test Colour"]
-		filtered_items = next_values["filtered_items"]
-
-		self.assertEqual(len(next_colours), 1)
-		self.assertEqual(next_colours.pop(), "Red")
-		self.assertEqual(len(filtered_items), 1)
-		self.assertEqual(filtered_items.pop(), "Test-Tshirt-Temp-S-R")
-
-	def test_exact_match_with_price(self):
-		"""
-		Test price fetching and matching of variant without Website Item
-		"""
-		from erpnext.e_commerce.doctype.website_item.test_website_item import make_web_item_price
-
-		frappe.set_user("Administrator")
-		setup_e_commerce_settings(
-			{
-				"company": "_Test Company",
-				"enabled": 1,
-				"default_customer_group": "_Test Customer Group",
-				"price_list": "_Test Price List India",
-				"show_price": 1,
-			}
-		)
-
-		make_web_item_price(item_code="Test-Tshirt-Temp-S-R", price_list_rate=100)
-
-		frappe.local.shopping_cart_settings = None  # clear cached settings values
-		next_values = get_next_attribute_and_values(
-			"Test-Tshirt-Temp", selected_attributes={"Test Size": "Small", "Test Colour": "Red"}
-		)
-		print(">>>>", next_values)
-		price_info = next_values["product_info"]["price"]
-
-		self.assertEqual(next_values["exact_match"][0], "Test-Tshirt-Temp-S-R")
-		self.assertEqual(next_values["exact_match"][0], "Test-Tshirt-Temp-S-R")
-		self.assertEqual(price_info["price_list_rate"], 100.0)
-		self.assertEqual(price_info["formatted_price_sales_uom"], "₹ 100.00")
diff --git a/erpnext/e_commerce/variant_selector/utils.py b/erpnext/e_commerce/variant_selector/utils.py
deleted file mode 100644
index 88356f5..0000000
--- a/erpnext/e_commerce/variant_selector/utils.py
+++ /dev/null
@@ -1,251 +0,0 @@
-import frappe
-from frappe.utils import cint, flt
-
-from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import (
-	get_shopping_cart_settings,
-)
-from erpnext.e_commerce.shopping_cart.cart import _set_price_list
-from erpnext.e_commerce.variant_selector.item_variants_cache import ItemVariantsCacheManager
-from erpnext.utilities.product import get_price
-
-
-def get_item_codes_by_attributes(attribute_filters, template_item_code=None):
-	items = []
-
-	for attribute, values in attribute_filters.items():
-		attribute_values = values
-
-		if not isinstance(attribute_values, list):
-			attribute_values = [attribute_values]
-
-		if not attribute_values:
-			continue
-
-		wheres = []
-		query_values = []
-		for attribute_value in attribute_values:
-			wheres.append("( attribute = %s and attribute_value = %s )")
-			query_values += [attribute, attribute_value]
-
-		attribute_query = " or ".join(wheres)
-
-		if template_item_code:
-			variant_of_query = "AND t2.variant_of = %s"
-			query_values.append(template_item_code)
-		else:
-			variant_of_query = ""
-
-		query = """
-			SELECT
-				t1.parent
-			FROM
-				`tabItem Variant Attribute` t1
-			WHERE
-				1 = 1
-				AND (
-					{attribute_query}
-				)
-				AND EXISTS (
-					SELECT
-						1
-					FROM
-						`tabItem` t2
-					WHERE
-						t2.name = t1.parent
-						{variant_of_query}
-				)
-			GROUP BY
-				t1.parent
-			ORDER BY
-				NULL
-		""".format(
-			attribute_query=attribute_query, variant_of_query=variant_of_query
-		)
-
-		item_codes = set([r[0] for r in frappe.db.sql(query, query_values)])  # nosemgrep
-		items.append(item_codes)
-
-	res = list(set.intersection(*items))
-
-	return res
-
-
-@frappe.whitelist(allow_guest=True)
-def get_attributes_and_values(item_code):
-	"""Build a list of attributes and their possible values.
-	This will ignore the values upon selection of which there cannot exist one item.
-	"""
-	item_cache = ItemVariantsCacheManager(item_code)
-	item_variants_data = item_cache.get_item_variants_data()
-
-	attributes = get_item_attributes(item_code)
-	attribute_list = [a.attribute for a in attributes]
-
-	valid_options = {}
-	for item_code, attribute, attribute_value in item_variants_data:
-		if attribute in attribute_list:
-			valid_options.setdefault(attribute, set()).add(attribute_value)
-
-	item_attribute_values = frappe.db.get_all(
-		"Item Attribute Value", ["parent", "attribute_value", "idx"], order_by="parent asc, idx asc"
-	)
-	ordered_attribute_value_map = frappe._dict()
-	for iv in item_attribute_values:
-		ordered_attribute_value_map.setdefault(iv.parent, []).append(iv.attribute_value)
-
-	# build attribute values in idx order
-	for attr in attributes:
-		valid_attribute_values = valid_options.get(attr.attribute, [])
-		ordered_values = ordered_attribute_value_map.get(attr.attribute, [])
-		attr["values"] = [v for v in ordered_values if v in valid_attribute_values]
-
-	return attributes
-
-
-@frappe.whitelist(allow_guest=True)
-def get_next_attribute_and_values(item_code, selected_attributes):
-	from erpnext.stock.doctype.warehouse.warehouse import get_child_warehouses
-
-	"""Find the count of Items that match the selected attributes.
-	Also, find the attribute values that are not applicable for further searching.
-	If less than equal to 10 items are found, return item_codes of those items.
-	If one item is matched exactly, return item_code of that item.
-	"""
-	selected_attributes = frappe.parse_json(selected_attributes)
-
-	item_cache = ItemVariantsCacheManager(item_code)
-	item_variants_data = item_cache.get_item_variants_data()
-
-	attributes = get_item_attributes(item_code)
-	attribute_list = [a.attribute for a in attributes]
-	filtered_items = get_items_with_selected_attributes(item_code, selected_attributes)
-
-	next_attribute = None
-
-	for attribute in attribute_list:
-		if attribute not in selected_attributes:
-			next_attribute = attribute
-			break
-
-	valid_options_for_attributes = frappe._dict()
-
-	for a in attribute_list:
-		valid_options_for_attributes[a] = set()
-
-		selected_attribute = selected_attributes.get(a, None)
-		if selected_attribute:
-			# already selected attribute values are valid options
-			valid_options_for_attributes[a].add(selected_attribute)
-
-	for row in item_variants_data:
-		item_code, attribute, attribute_value = row
-		if (
-			item_code in filtered_items
-			and attribute not in selected_attributes
-			and attribute in attribute_list
-		):
-			valid_options_for_attributes[attribute].add(attribute_value)
-
-	optional_attributes = item_cache.get_optional_attributes()
-	exact_match = []
-	# search for exact match if all selected attributes are required attributes
-	if len(selected_attributes.keys()) >= (len(attribute_list) - len(optional_attributes)):
-		item_attribute_value_map = item_cache.get_item_attribute_value_map()
-		for item_code, attr_dict in item_attribute_value_map.items():
-			if item_code in filtered_items and set(attr_dict.keys()) == set(selected_attributes.keys()):
-				exact_match.append(item_code)
-
-	filtered_items_count = len(filtered_items)
-
-	# get product info if exact match
-	# from erpnext.e_commerce.shopping_cart.product_info import get_product_info_for_website
-	if exact_match:
-		cart_settings = get_shopping_cart_settings()
-		product_info = get_item_variant_price_dict(exact_match[0], cart_settings)
-
-		if product_info:
-			product_info["is_stock_item"] = frappe.get_cached_value("Item", exact_match[0], "is_stock_item")
-			product_info["allow_items_not_in_stock"] = cint(cart_settings.allow_items_not_in_stock)
-	else:
-		product_info = None
-
-	product_id = ""
-	warehouse = ""
-	if exact_match or filtered_items:
-		if exact_match and len(exact_match) == 1:
-			product_id = exact_match[0]
-		elif filtered_items_count == 1:
-			product_id = list(filtered_items)[0]
-
-	if product_id:
-		warehouse = frappe.get_cached_value(
-			"Website Item", {"item_code": product_id}, "website_warehouse"
-		)
-
-	available_qty = 0.0
-	if warehouse and frappe.get_cached_value("Warehouse", warehouse, "is_group") == 1:
-		warehouses = get_child_warehouses(warehouse)
-	else:
-		warehouses = [warehouse] if warehouse else []
-
-	for warehouse in warehouses:
-		available_qty += flt(
-			frappe.db.get_value("Bin", {"item_code": product_id, "warehouse": warehouse}, "actual_qty")
-		)
-
-	return {
-		"next_attribute": next_attribute,
-		"valid_options_for_attributes": valid_options_for_attributes,
-		"filtered_items_count": filtered_items_count,
-		"filtered_items": filtered_items if filtered_items_count < 10 else [],
-		"exact_match": exact_match,
-		"product_info": product_info,
-		"available_qty": available_qty,
-	}
-
-
-def get_items_with_selected_attributes(item_code, selected_attributes):
-	item_cache = ItemVariantsCacheManager(item_code)
-	attribute_value_item_map = item_cache.get_attribute_value_item_map()
-
-	items = []
-	for attribute, value in selected_attributes.items():
-		filtered_items = attribute_value_item_map.get((attribute, value), [])
-		items.append(set(filtered_items))
-
-	return set.intersection(*items)
-
-
-# utilities
-
-
-def get_item_attributes(item_code):
-	attributes = frappe.db.get_all(
-		"Item Variant Attribute",
-		fields=["attribute"],
-		filters={"parenttype": "Item", "parent": item_code},
-		order_by="idx asc",
-	)
-
-	optional_attributes = ItemVariantsCacheManager(item_code).get_optional_attributes()
-
-	for a in attributes:
-		if a.attribute in optional_attributes:
-			a.optional = True
-
-	return attributes
-
-
-def get_item_variant_price_dict(item_code, cart_settings):
-	if cart_settings.enabled and cart_settings.show_price:
-		is_guest = frappe.session.user == "Guest"
-		# Show Price if logged in.
-		# If not logged in, check if price is hidden for guest.
-		if not is_guest or not cart_settings.hide_price_for_guest:
-			price_list = _set_price_list(cart_settings, None)
-			price = get_price(
-				item_code, price_list, cart_settings.default_customer_group, cart_settings.company
-			)
-			return {"price": price}
-
-	return None
diff --git a/erpnext/e_commerce/web_template/__init__.py b/erpnext/e_commerce/web_template/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/web_template/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/web_template/hero_slider/__init__.py b/erpnext/e_commerce/web_template/hero_slider/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/web_template/hero_slider/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/web_template/hero_slider/hero_slider.html b/erpnext/e_commerce/web_template/hero_slider/hero_slider.html
deleted file mode 100644
index fe4fee3..0000000
--- a/erpnext/e_commerce/web_template/hero_slider/hero_slider.html
+++ /dev/null
@@ -1,86 +0,0 @@
-{%- macro slide(image, title, subtitle, action, label, index, align="Left", theme="Dark") -%}
-{%- set align_class = resolve_class({
-	'text-right': align == 'Right',
-	'text-center': align == 'Centre',
-	'text-left': align == 'Left',
-}) -%}
-
-{%- set heading_class = resolve_class({
-	'text-white': theme == 'Dark',
-	'': theme == 'Light',
-}) -%}
-<div class="carousel-item {{ 'active' if index=='1' else ''}}" style="height: 450px;">
-	<img class="d-block h-100 w-100" style="object-fit: cover;" src="{{ image }}" alt="{{ title }}">
-	{%- if title or subtitle -%}
-	<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="{{ heading_class }} mt-2">{{ subtitle }}</p>{%- endif -%}
-			{%- if action -%}
-			<a href="{{ action }}" class="btn btn-primary mt-3">
-				{{ label }}
-			</a>
-			{%- endif -%}
-		</div>
-	</div>
-	{%- endif -%}
-</div>
-{%- endmacro -%}
-
-{%- 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="#{{ hero_slider_id }}" data-slide-to="{{ frappe.utils.cint(index) - 1 }}" class="{{ 'active' if index=='1' else ''}}"></li>
-		{%- endif -%}
-		{%- endfor -%}
-	</ol>
-	{%- endif -%}
-	<div class="carousel-inner {{ resolve_class({'rounded-carousel': rounded }) }}">
-		{%- for index in ['1', '2', '3', '4', '5'] -%}
-			{%- set image = values['slide_' + index + '_image'] -%}
-			{%- set title = values['slide_' + index + '_title'] -%}
-			{%- set subtitle = values['slide_' + index + '_subtitle'] -%}
-			{%- set primary_action = values['slide_' + index + '_primary_action'] -%}
-			{%- set primary_action_label = values['slide_' + index + '_primary_action_label'] -%}
-			{%- set align = values['slide_' + index + '_content_align'] -%}
-			{%- set theme = values['slide_' + index + '_theme'] -%}
-
-			{%- if image -%}
-				{{ slide(image, title, subtitle, primary_action, primary_action_label, index, align, theme) }}
-			{%- endif -%}
-
-		{%- endfor -%}
-	</div>
-	{%- if show_controls -%}
-	<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"/>
-			</svg>
-		</div>
-		<span class="sr-only">Previous</span>
-	</a>
-	<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"/>
-			</svg>
-		</div>
-		<span class="sr-only">Next</span>
-	</a>
-	{%- endif -%}
-</div>
-
-<script>
-	frappe.ready(function () {
-		$('.carousel').carousel({
-			interval: false,
-			pause: "hover",
-			wrap: true
-		})
-	});
-</script>
diff --git a/erpnext/e_commerce/web_template/hero_slider/hero_slider.json b/erpnext/e_commerce/web_template/hero_slider/hero_slider.json
deleted file mode 100644
index 39b2b3e..0000000
--- a/erpnext/e_commerce/web_template/hero_slider/hero_slider.json
+++ /dev/null
@@ -1,288 +0,0 @@
-{
- "__unsaved": 1,
- "creation": "2020-11-17 15:21:51.207221",
- "docstatus": 0,
- "doctype": "Web Template",
- "fields": [
-  {
-   "fieldname": "slider_name",
-   "fieldtype": "Data",
-   "label": "Slider Name",
-   "reqd": 1
-  },
-  {
-   "default": "1",
-   "fieldname": "show_indicators",
-   "fieldtype": "Check",
-   "label": "Show Indicators",
-   "reqd": 0
-  },
-  {
-   "default": "1",
-   "fieldname": "show_controls",
-   "fieldtype": "Check",
-   "label": "Show Controls",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_1",
-   "fieldtype": "Section Break",
-   "label": "Slide 1",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_1_image",
-   "fieldtype": "Attach Image",
-   "label": "Image",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_1_title",
-   "fieldtype": "Data",
-   "label": "Title",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_1_subtitle",
-   "fieldtype": "Small Text",
-   "label": "Subtitle",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_1_primary_action_label",
-   "fieldtype": "Data",
-   "label": "Primary Action Label",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_1_primary_action",
-   "fieldtype": "Data",
-   "label": "Primary Action",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_1_content_align",
-   "fieldtype": "Select",
-   "label": "Content Align",
-   "options": "Left\nCentre\nRight",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_1_theme",
-   "fieldtype": "Select",
-   "label": "Slide Theme",
-   "options": "Dark\nLight",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_2",
-   "fieldtype": "Section Break",
-   "label": "Slide 2",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_2_image",
-   "fieldtype": "Attach Image",
-   "label": "Image ",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_2_title",
-   "fieldtype": "Data",
-   "label": "Title ",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_2_subtitle",
-   "fieldtype": "Small Text",
-   "label": "Subtitle ",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_2_primary_action_label",
-   "fieldtype": "Data",
-   "label": "Primary Action Label ",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_2_primary_action",
-   "fieldtype": "Data",
-   "label": "Primary Action ",
-   "reqd": 0
-  },
-  {
-   "default": "Left",
-   "fieldname": "slide_2_content_align",
-   "fieldtype": "Select",
-   "label": "Content Align",
-   "options": "Left\nCentre\nRight",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_2_theme",
-   "fieldtype": "Select",
-   "label": "Slide Theme",
-   "options": "Dark\nLight",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_3",
-   "fieldtype": "Section Break",
-   "label": "Slide 3",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_3_image",
-   "fieldtype": "Attach Image",
-   "label": "Image",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_3_title",
-   "fieldtype": "Data",
-   "label": "Title",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_3_subtitle",
-   "fieldtype": "Small Text",
-   "label": "Subtitle",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_3_primary_action_label",
-   "fieldtype": "Data",
-   "label": "Primary Action Label",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_3_primary_action",
-   "fieldtype": "Data",
-   "label": "Primary Action",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_3_content_align",
-   "fieldtype": "Select",
-   "label": "Content Align",
-   "options": "Left\nCentre\nRight",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_3_theme",
-   "fieldtype": "Select",
-   "label": "Slide Theme",
-   "options": "Dark\nLight",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_4",
-   "fieldtype": "Section Break",
-   "label": "Slide 4",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_4_image",
-   "fieldtype": "Attach Image",
-   "label": "Image",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_4_title",
-   "fieldtype": "Data",
-   "label": "Title",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_4_subtitle",
-   "fieldtype": "Small Text",
-   "label": "Subtitle",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_4_primary_action_label",
-   "fieldtype": "Data",
-   "label": "Primary Action Label",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_4_primary_action",
-   "fieldtype": "Data",
-   "label": "Primary Action",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_4_content_align",
-   "fieldtype": "Select",
-   "label": "Content Align",
-   "options": "Left\nCentre\nRight",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_4_theme",
-   "fieldtype": "Select",
-   "label": "Slide Theme",
-   "options": "Dark\nLight",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_5",
-   "fieldtype": "Section Break",
-   "label": "Slide 5",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_5_image",
-   "fieldtype": "Attach Image",
-   "label": "Image",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_5_title",
-   "fieldtype": "Data",
-   "label": "Title",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_5_subtitle",
-   "fieldtype": "Small Text",
-   "label": "Subtitle",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_5_primary_action_label",
-   "fieldtype": "Data",
-   "label": "Primary Action Label",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_5_primary_action",
-   "fieldtype": "Data",
-   "label": "Primary Action",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_5_content_align",
-   "fieldtype": "Select",
-   "label": "Content Align",
-   "options": "Left\nCentre\nRight",
-   "reqd": 0
-  },
-  {
-   "fieldname": "slide_5_theme",
-   "fieldtype": "Select",
-   "label": "Slide Theme",
-   "options": "Dark\nLight",
-   "reqd": 0
-  }
- ],
- "idx": 2,
- "modified": "2023-05-12 15:03:57.604060",
- "modified_by": "Administrator",
- "module": "E-commerce",
- "name": "Hero Slider",
- "owner": "Administrator",
- "standard": 1,
- "template": "",
- "type": "Section"
-}
\ No newline at end of file
diff --git a/erpnext/e_commerce/web_template/item_card_group/__init__.py b/erpnext/e_commerce/web_template/item_card_group/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/web_template/item_card_group/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/web_template/item_card_group/item_card_group.html b/erpnext/e_commerce/web_template/item_card_group/item_card_group.html
deleted file mode 100644
index 07952f0..0000000
--- a/erpnext/e_commerce/web_template/item_card_group/item_card_group.html
+++ /dev/null
@@ -1,37 +0,0 @@
-{% from "erpnext/templates/includes/macros.html" import item_card, item_card_body %}
-
-<div class="section-with-cards item-card-group-section">
-	<div class="item-group-header d-flex justify-content-between">
-		<div class="title-section">
-			{%- if title -%}
-			<h2 class="section-title">{{ title }}</h2>
-			{%- endif -%}
-			{%- if subtitle -%}
-			<p class="section-description">{{ subtitle }}</p>
-			{%- endif -%}
-		</div>
-		<div class="primary-action-section">
-			{%- if primary_action -%}
-			<a href="{{ action }}" class="btn btn-primary pull-right">
-				{{ primary_action_label }}
-			</a>
-			{%- endif -%}
-		</div>
-	</div>
-
-	<div class="row">
-		{%- for index in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'] -%}
-		{%- set item = values['card_' + index + '_item'] -%}
-			{%- if item -%}
-				{%- set web_item = frappe.get_doc("Website Item", item) -%}
-				{{ item_card(
-					web_item, is_featured=values['card_' + index + '_featured'],
-					is_full_width=True, align="Center"
-				) }}
-			{%- endif -%}
-		{%- endfor -%}
-	</div>
-</div>
-
-<style>
-</style>
diff --git a/erpnext/e_commerce/web_template/item_card_group/item_card_group.json b/erpnext/e_commerce/web_template/item_card_group/item_card_group.json
deleted file mode 100644
index ad9e2a7..0000000
--- a/erpnext/e_commerce/web_template/item_card_group/item_card_group.json
+++ /dev/null
@@ -1,270 +0,0 @@
-{
- "__unsaved": 1,
- "creation": "2020-11-17 15:35:05.285322",
- "docstatus": 0,
- "doctype": "Web Template",
- "fields": [
-  {
-   "fieldname": "title",
-   "fieldtype": "Data",
-   "label": "Title",
-   "reqd": 1
-  },
-  {
-   "fieldname": "subtitle",
-   "fieldtype": "Data",
-   "label": "Subtitle",
-   "reqd": 0
-  },
-  {
-   "fieldname": "primary_action_label",
-   "fieldtype": "Data",
-   "label": "Primary Action Label",
-   "reqd": 0
-  },
-  {
-   "fieldname": "primary_action",
-   "fieldtype": "Data",
-   "label": "Primary Action",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_1",
-   "fieldtype": "Section Break",
-   "label": "Card 1",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_1_item",
-   "fieldtype": "Link",
-   "label": "Website Item",
-   "options": "Website Item",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_1_featured",
-   "fieldtype": "Check",
-   "label": "Featured",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_2",
-   "fieldtype": "Section Break",
-   "label": "Card 2",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_2_item",
-   "fieldtype": "Link",
-   "label": "Website Item",
-   "options": "Website Item",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_2_featured",
-   "fieldtype": "Check",
-   "label": "Featured",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_3",
-   "fieldtype": "Section Break",
-   "label": "Card 3",
-   "options": "",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_3_item",
-   "fieldtype": "Link",
-   "label": "Website Item",
-   "options": "Website Item",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_3_featured",
-   "fieldtype": "Check",
-   "label": "Featured",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_4",
-   "fieldtype": "Section Break",
-   "label": "Card 4",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_4_item",
-   "fieldtype": "Link",
-   "label": "Website Item",
-   "options": "Website Item",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_4_featured",
-   "fieldtype": "Check",
-   "label": "Featured",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_5",
-   "fieldtype": "Section Break",
-   "label": "Card 5",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_5_item",
-   "fieldtype": "Link",
-   "label": "Website Item",
-   "options": "Website Item",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_5_featured",
-   "fieldtype": "Check",
-   "label": "Featured",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_6",
-   "fieldtype": "Section Break",
-   "label": "Card 6",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_6_item",
-   "fieldtype": "Link",
-   "label": "Website Item",
-   "options": "Website Item",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_6_featured",
-   "fieldtype": "Check",
-   "label": "Featured",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_7",
-   "fieldtype": "Section Break",
-   "label": "Card 7",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_7_item",
-   "fieldtype": "Link",
-   "label": "Website Item",
-   "options": "Website Item",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_7_featured",
-   "fieldtype": "Check",
-   "label": "Featured",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_8",
-   "fieldtype": "Section Break",
-   "label": "Card 8",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_8_item",
-   "fieldtype": "Link",
-   "label": "Website Item",
-   "options": "Website Item",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_8_featured",
-   "fieldtype": "Check",
-   "label": "Featured",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_9",
-   "fieldtype": "Section Break",
-   "label": "Card 9",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_9_item",
-   "fieldtype": "Link",
-   "label": "Website Item",
-   "options": "Website Item",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_9_featured",
-   "fieldtype": "Check",
-   "label": "Featured",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_10",
-   "fieldtype": "Section Break",
-   "label": "Card 10",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_10_item",
-   "fieldtype": "Link",
-   "label": "Website Item",
-   "options": "Website Item",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_10_featured",
-   "fieldtype": "Check",
-   "label": "Featured",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_11",
-   "fieldtype": "Section Break",
-   "label": "Card 11",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_11_item",
-   "fieldtype": "Link",
-   "label": "Website Item",
-   "options": "Website Item",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_11_featured",
-   "fieldtype": "Check",
-   "label": "Featured",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_12",
-   "fieldtype": "Section Break",
-   "label": "Card 12",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_12_item",
-   "fieldtype": "Link",
-   "label": "Website Item",
-   "options": "Website Item",
-   "reqd": 0
-  },
-  {
-   "fieldname": "card_12_featured",
-   "fieldtype": "Check",
-   "label": "Featured",
-   "reqd": 0
-  }
- ],
- "idx": 0,
- "modified": "2021-12-21 14:44:59.821335",
- "modified_by": "Administrator",
- "module": "E-commerce",
- "name": "Item Card Group",
- "owner": "Administrator",
- "standard": 1,
- "template": "",
- "type": "Section"
-}
\ No newline at end of file
diff --git a/erpnext/e_commerce/web_template/product_card/__init__.py b/erpnext/e_commerce/web_template/product_card/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/web_template/product_card/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/web_template/product_card/product_card.html b/erpnext/e_commerce/web_template/product_card/product_card.html
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/web_template/product_card/product_card.html
+++ /dev/null
diff --git a/erpnext/e_commerce/web_template/product_card/product_card.json b/erpnext/e_commerce/web_template/product_card/product_card.json
deleted file mode 100644
index 2eb7374..0000000
--- a/erpnext/e_commerce/web_template/product_card/product_card.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "__unsaved": 1,
- "creation": "2020-11-17 15:28:47.809342",
- "docstatus": 0,
- "doctype": "Web Template",
- "fields": [
-  {
-   "fieldname": "item",
-   "fieldtype": "Link",
-   "label": "Item",
-   "options": "Item",
-   "reqd": 0
-  },
-  {
-   "fieldname": "featured",
-   "fieldtype": "Check",
-   "label": "Featured",
-   "options": "",
-   "reqd": 0
-  }
- ],
- "idx": 0,
- "modified": "2021-02-24 16:05:17.926610",
- "modified_by": "Administrator",
- "module": "E-commerce",
- "name": "Product Card",
- "owner": "Administrator",
- "standard": 1,
- "template": "",
- "type": "Component"
-}
\ No newline at end of file
diff --git a/erpnext/e_commerce/web_template/product_category_cards/__init__.py b/erpnext/e_commerce/web_template/product_category_cards/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/e_commerce/web_template/product_category_cards/__init__.py
+++ /dev/null
diff --git a/erpnext/e_commerce/web_template/product_category_cards/product_category_cards.html b/erpnext/e_commerce/web_template/product_category_cards/product_category_cards.html
deleted file mode 100644
index 6d75a8b..0000000
--- a/erpnext/e_commerce/web_template/product_category_cards/product_category_cards.html
+++ /dev/null
@@ -1,47 +0,0 @@
-{%- macro card(title, image, url, text_primary=False) -%}
-{%- set align_class = resolve_class({
-	'text-right': text_primary,
-	'text-centre': align == 'Center',
-	'text-left': align == 'Left',
-}) -%}
-<div class="card h-100">
-	{% if image %}
-	<img class="card-img-top" src="{{ image }}" alt="{{ title }}" style="max-height: 200px;">
-	{% else %}
-	<div class="placeholder-div" style="max-height: 200px;">
-		<span class="placeholder">
-			{{ frappe.utils.get_abbr(title or '') }}
-		</span>
-	</div>
-	{% endif %}
-
-	<div class="card-body text-center text-muted small">
-		{{ title or '' }}
-	</div>
-	<a href="{{ url or '#' }}" class="stretched-link"></a>
-</div>
-{%- endmacro -%}
-
-<div class="section-with-cards product-category-section">
-	{%- if title -%}
-	<h2 class="section-title">{{ title }}</h2>
-	{%- endif -%}
-	{%- if subtitle -%}
-	<p class="section-description">{{ subtitle }}</p>
-	{%- endif -%}
-	<!-- {%- set card_size = card_size or 'Small' -%} -->
-	<div class="{{ resolve_class({'mt-6': title}) }}">
-		<div class="card-grid">
-			{%- for index in ['1', '2', '3', '4', '5', '6', '7', '8'] -%}
-			{%- set category = values['category_' + index] -%}
-				{%- if category -%}
-					{%- set category = frappe.get_doc("Item Group", category) -%}
-					{{ card(category.name, category.image, category.route) }}
-				{%- endif -%}
-			{%- endfor -%}
-		</div>
-	</div>
-</div>
-
-<style>
-</style>
diff --git a/erpnext/e_commerce/web_template/product_category_cards/product_category_cards.json b/erpnext/e_commerce/web_template/product_category_cards/product_category_cards.json
deleted file mode 100644
index 0202165..0000000
--- a/erpnext/e_commerce/web_template/product_category_cards/product_category_cards.json
+++ /dev/null
@@ -1,85 +0,0 @@
-{
- "__unsaved": 1,
- "creation": "2020-11-17 15:25:50.855934",
- "docstatus": 0,
- "doctype": "Web Template",
- "fields": [
-  {
-   "fieldname": "title",
-   "fieldtype": "Data",
-   "label": "Title",
-   "reqd": 1
-  },
-  {
-   "fieldname": "subtitle",
-   "fieldtype": "Data",
-   "label": "Subtitle",
-   "reqd": 0
-  },
-  {
-   "fieldname": "category_1",
-   "fieldtype": "Link",
-   "label": "Item Group",
-   "options": "Item Group",
-   "reqd": 0
-  },
-  {
-   "fieldname": "category_2",
-   "fieldtype": "Link",
-   "label": "Item Group",
-   "options": "Item Group",
-   "reqd": 0
-  },
-  {
-   "fieldname": "category_3",
-   "fieldtype": "Link",
-   "label": "Item Group",
-   "options": "Item Group",
-   "reqd": 0
-  },
-  {
-   "fieldname": "category_4",
-   "fieldtype": "Link",
-   "label": "Item Group",
-   "options": "Item Group",
-   "reqd": 0
-  },
-  {
-   "fieldname": "category_5",
-   "fieldtype": "Link",
-   "label": "Item Group",
-   "options": "Item Group",
-   "reqd": 0
-  },
-  {
-   "fieldname": "category_6",
-   "fieldtype": "Link",
-   "label": "Item Group",
-   "options": "Item Group",
-   "reqd": 0
-  },
-  {
-   "fieldname": "category_7",
-   "fieldtype": "Link",
-   "label": "Item Group",
-   "options": "Item Group",
-   "reqd": 0
-  },
-  {
-   "fieldname": "category_8",
-   "fieldtype": "Link",
-   "label": "Item Group",
-   "options": "Item Group",
-   "reqd": 0
-  }
- ],
- "idx": 0,
- "modified": "2021-02-24 16:03:33.835635",
- "modified_by": "Administrator",
- "module": "E-commerce",
- "name": "Product Category Cards",
- "owner": "Administrator",
- "standard": 1,
- "template": "",
- "type": "Section"
-}
\ No newline at end of file
diff --git a/erpnext/erpnext_integrations/doctype/gocardless_mandate/__init__.py b/erpnext/erpnext_integrations/doctype/gocardless_mandate/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/erpnext_integrations/doctype/gocardless_mandate/__init__.py
+++ /dev/null
diff --git a/erpnext/erpnext_integrations/doctype/gocardless_mandate/gocardless_mandate.js b/erpnext/erpnext_integrations/doctype/gocardless_mandate/gocardless_mandate.js
deleted file mode 100644
index 37f9f7b..0000000
--- a/erpnext/erpnext_integrations/doctype/gocardless_mandate/gocardless_mandate.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2018, Frappe Technologies and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('GoCardless Mandate', {
-});
diff --git a/erpnext/erpnext_integrations/doctype/gocardless_mandate/gocardless_mandate.json b/erpnext/erpnext_integrations/doctype/gocardless_mandate/gocardless_mandate.json
deleted file mode 100644
index edf652c..0000000
--- a/erpnext/erpnext_integrations/doctype/gocardless_mandate/gocardless_mandate.json
+++ /dev/null
@@ -1,184 +0,0 @@
-{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "field:mandate",
- "beta": 0,
- "creation": "2018-02-08 11:33:15.721919",
- "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": "disabled",
-   "fieldtype": "Check",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 0,
-   "in_standard_filter": 0,
-   "label": "Disabled",
-   "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
-  },
-  {
-   "allow_bulk_edit": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fieldname": "customer",
-   "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": "Customer",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Customer",
-   "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": "mandate",
-   "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": "Mandate",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 1,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 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": "gocardless_customer",
-   "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": "GoCardless Customer",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 1,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 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": "2018-02-11 12:28:03.183095",
- "modified_by": "Administrator",
- "module": "ERPNext Integrations",
- "name": "GoCardless Mandate",
- "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": "System Manager",
-   "set_user_permissions": 0,
-   "share": 1,
-   "submit": 0,
-   "write": 1
-  }
- ],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0
-}
diff --git a/erpnext/erpnext_integrations/doctype/gocardless_mandate/gocardless_mandate.py b/erpnext/erpnext_integrations/doctype/gocardless_mandate/gocardless_mandate.py
deleted file mode 100644
index bceb3ca..0000000
--- a/erpnext/erpnext_integrations/doctype/gocardless_mandate/gocardless_mandate.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2018, Frappe Technologies and contributors
-# For license information, please see license.txt
-
-
-from frappe.model.document import Document
-
-
-class GoCardlessMandate(Document):
-	pass
diff --git a/erpnext/erpnext_integrations/doctype/gocardless_mandate/test_gocardless_mandate.py b/erpnext/erpnext_integrations/doctype/gocardless_mandate/test_gocardless_mandate.py
deleted file mode 100644
index 0c1952a..0000000
--- a/erpnext/erpnext_integrations/doctype/gocardless_mandate/test_gocardless_mandate.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright (c) 2018, Frappe Technologies and Contributors
-# See license.txt
-
-import unittest
-
-
-class TestGoCardlessMandate(unittest.TestCase):
-	pass
diff --git a/erpnext/erpnext_integrations/doctype/gocardless_settings/__init__.py b/erpnext/erpnext_integrations/doctype/gocardless_settings/__init__.py
deleted file mode 100644
index 65be599..0000000
--- a/erpnext/erpnext_integrations/doctype/gocardless_settings/__init__.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright (c) 2018, Frappe Technologies and contributors
-# For license information, please see license.txt
-
-
-import hashlib
-import hmac
-import json
-
-import frappe
-
-
-@frappe.whitelist(allow_guest=True)
-def webhooks():
-	r = frappe.request
-	if not r:
-		return
-
-	if not authenticate_signature(r):
-		raise frappe.AuthenticationError
-
-	gocardless_events = json.loads(r.get_data()) or []
-	for event in gocardless_events["events"]:
-		set_status(event)
-
-	return 200
-
-
-def set_status(event):
-	resource_type = event.get("resource_type", {})
-
-	if resource_type == "mandates":
-		set_mandate_status(event)
-
-
-def set_mandate_status(event):
-	mandates = []
-	if isinstance(event["links"], (list,)):
-		for link in event["links"]:
-			mandates.append(link["mandate"])
-	else:
-		mandates.append(event["links"]["mandate"])
-
-	if (
-		event["action"] == "pending_customer_approval"
-		or event["action"] == "pending_submission"
-		or event["action"] == "submitted"
-		or event["action"] == "active"
-	):
-		disabled = 0
-	else:
-		disabled = 1
-
-	for mandate in mandates:
-		frappe.db.set_value("GoCardless Mandate", mandate, "disabled", disabled)
-
-
-def authenticate_signature(r):
-	"""Returns True if the received signature matches the generated signature"""
-	received_signature = frappe.get_request_header("Webhook-Signature")
-
-	if not received_signature:
-		return False
-
-	for key in get_webhook_keys():
-		computed_signature = hmac.new(key.encode("utf-8"), r.get_data(), hashlib.sha256).hexdigest()
-		if hmac.compare_digest(str(received_signature), computed_signature):
-			return True
-
-	return False
-
-
-def get_webhook_keys():
-	def _get_webhook_keys():
-		webhook_keys = [
-			d.webhooks_secret
-			for d in frappe.get_all(
-				"GoCardless Settings",
-				fields=["webhooks_secret"],
-			)
-			if d.webhooks_secret
-		]
-
-		return webhook_keys
-
-	return frappe.cache().get_value("gocardless_webhooks_secret", _get_webhook_keys)
-
-
-def clear_cache():
-	frappe.cache().delete_value("gocardless_webhooks_secret")
diff --git a/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.js b/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.js
deleted file mode 100644
index 2411297..0000000
--- a/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2018, Frappe Technologies and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('GoCardless Settings', {
-	refresh: function(frm) {
-		erpnext.utils.check_payments_app();
-	}
-});
diff --git a/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.json b/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.json
deleted file mode 100644
index cca3653..0000000
--- a/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.json
+++ /dev/null
@@ -1,211 +0,0 @@
-{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "field:gateway_name",
- "beta": 0,
- "creation": "2018-02-06 16:11:10.028249",
- "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": "gateway_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": "Payment Gateway 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,
-   "unique": 0
-  },
-  {
-   "allow_bulk_edit": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fieldname": "section_break_2",
-   "fieldtype": "Section Break",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 0,
-   "in_standard_filter": 0,
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "unique": 0
-  },
-  {
-   "allow_bulk_edit": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fieldname": "access_token",
-   "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": "Access Token",
-   "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": "webhooks_secret",
-   "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": "Webhooks Secret",
-   "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
-  },
-  {
-   "allow_bulk_edit": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fieldname": "use_sandbox",
-   "fieldtype": "Check",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 0,
-   "in_standard_filter": 0,
-   "label": "Use Sandbox",
-   "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": 0,
- "max_attachments": 0,
- "modified": "2022-02-12 14:18:47.209114",
- "modified_by": "Administrator",
- "module": "ERPNext Integrations",
- "name": "GoCardless Settings",
- "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": "System Manager",
-   "set_user_permissions": 0,
-   "share": 1,
-   "submit": 0,
-   "write": 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
-}
diff --git a/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.py b/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.py
deleted file mode 100644
index 4a29a6a..0000000
--- a/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.py
+++ /dev/null
@@ -1,220 +0,0 @@
-# Copyright (c) 2018, Frappe Technologies and contributors
-# For license information, please see license.txt
-
-
-from urllib.parse import urlencode
-
-import frappe
-import gocardless_pro
-from frappe import _
-from frappe.integrations.utils import create_request_log
-from frappe.model.document import Document
-from frappe.utils import call_hook_method, cint, flt, get_url
-
-from erpnext.utilities import payment_app_import_guard
-
-
-class GoCardlessSettings(Document):
-	supported_currencies = ["EUR", "DKK", "GBP", "SEK", "AUD", "NZD", "CAD", "USD"]
-
-	def validate(self):
-		self.initialize_client()
-
-	def initialize_client(self):
-		self.environment = self.get_environment()
-		try:
-			self.client = gocardless_pro.Client(
-				access_token=self.access_token, environment=self.environment
-			)
-			return self.client
-		except Exception as e:
-			frappe.throw(e)
-
-	def on_update(self):
-		with payment_app_import_guard():
-			from payments.utils import create_payment_gateway
-
-		create_payment_gateway(
-			"GoCardless-" + self.gateway_name, settings="GoCardLess Settings", controller=self.gateway_name
-		)
-		call_hook_method("payment_gateway_enabled", gateway="GoCardless-" + self.gateway_name)
-
-	def on_payment_request_submission(self, data):
-		if data.reference_doctype != "Fees":
-			customer_data = frappe.db.get_value(
-				data.reference_doctype, data.reference_name, ["company", "customer_name"], as_dict=1
-			)
-
-		data = {
-			"amount": flt(data.grand_total, data.precision("grand_total")),
-			"title": customer_data.company.encode("utf-8"),
-			"description": data.subject.encode("utf-8"),
-			"reference_doctype": data.doctype,
-			"reference_docname": data.name,
-			"payer_email": data.email_to or frappe.session.user,
-			"payer_name": customer_data.customer_name,
-			"order_id": data.name,
-			"currency": data.currency,
-		}
-
-		valid_mandate = self.check_mandate_validity(data)
-		if valid_mandate is not None:
-			data.update(valid_mandate)
-
-			self.create_payment_request(data)
-			return False
-		else:
-			return True
-
-	def check_mandate_validity(self, data):
-
-		if frappe.db.exists("GoCardless Mandate", dict(customer=data.get("payer_name"), disabled=0)):
-			registered_mandate = frappe.db.get_value(
-				"GoCardless Mandate", dict(customer=data.get("payer_name"), disabled=0), "mandate"
-			)
-			self.initialize_client()
-			mandate = self.client.mandates.get(registered_mandate)
-
-			if (
-				mandate.status == "pending_customer_approval"
-				or mandate.status == "pending_submission"
-				or mandate.status == "submitted"
-				or mandate.status == "active"
-			):
-				return {"mandate": registered_mandate}
-			else:
-				return None
-		else:
-			return None
-
-	def get_environment(self):
-		if self.use_sandbox:
-			return "sandbox"
-		else:
-			return "live"
-
-	def validate_transaction_currency(self, currency):
-		if currency not in self.supported_currencies:
-			frappe.throw(
-				_(
-					"Please select another payment method. Go Cardless does not support transactions in currency '{0}'"
-				).format(currency)
-			)
-
-	def get_payment_url(self, **kwargs):
-		return get_url("./integrations/gocardless_checkout?{0}".format(urlencode(kwargs)))
-
-	def create_payment_request(self, data):
-		self.data = frappe._dict(data)
-
-		try:
-			self.integration_request = create_request_log(self.data, "Host", "GoCardless")
-			return self.create_charge_on_gocardless()
-
-		except Exception:
-			frappe.log_error("Gocardless payment reqeust failed")
-			return {
-				"redirect_to": frappe.redirect_to_message(
-					_("Server Error"),
-					_(
-						"There seems to be an issue with the server's GoCardless configuration. Don't worry, in case of failure, the amount will get refunded to your account."
-					),
-				),
-				"status": 401,
-			}
-
-	def create_charge_on_gocardless(self):
-		redirect_to = self.data.get("redirect_to") or None
-		redirect_message = self.data.get("redirect_message") or None
-
-		reference_doc = frappe.get_doc(
-			self.data.get("reference_doctype"), self.data.get("reference_docname")
-		)
-		self.initialize_client()
-
-		try:
-			payment = self.client.payments.create(
-				params={
-					"amount": cint(reference_doc.grand_total * 100),
-					"currency": reference_doc.currency,
-					"links": {"mandate": self.data.get("mandate")},
-					"metadata": {
-						"reference_doctype": reference_doc.doctype,
-						"reference_document": reference_doc.name,
-					},
-				},
-				headers={
-					"Idempotency-Key": self.data.get("reference_docname"),
-				},
-			)
-
-			if (
-				payment.status == "pending_submission"
-				or payment.status == "pending_customer_approval"
-				or payment.status == "submitted"
-			):
-				self.integration_request.db_set("status", "Authorized", update_modified=False)
-				self.flags.status_changed_to = "Completed"
-				self.integration_request.db_set("output", payment.status, update_modified=False)
-
-			elif payment.status == "confirmed" or payment.status == "paid_out":
-				self.integration_request.db_set("status", "Completed", update_modified=False)
-				self.flags.status_changed_to = "Completed"
-				self.integration_request.db_set("output", payment.status, update_modified=False)
-
-			elif (
-				payment.status == "cancelled"
-				or payment.status == "customer_approval_denied"
-				or payment.status == "charged_back"
-			):
-				self.integration_request.db_set("status", "Cancelled", update_modified=False)
-				frappe.log_error("Gocardless payment cancelled")
-				self.integration_request.db_set("error", payment.status, update_modified=False)
-			else:
-				self.integration_request.db_set("status", "Failed", update_modified=False)
-				frappe.log_error("Gocardless payment failed")
-				self.integration_request.db_set("error", payment.status, update_modified=False)
-
-		except Exception as e:
-			frappe.log_error("GoCardless Payment Error")
-
-		if self.flags.status_changed_to == "Completed":
-			status = "Completed"
-			if "reference_doctype" in self.data and "reference_docname" in self.data:
-				custom_redirect_to = None
-				try:
-					custom_redirect_to = frappe.get_doc(
-						self.data.get("reference_doctype"), self.data.get("reference_docname")
-					).run_method("on_payment_authorized", self.flags.status_changed_to)
-				except Exception:
-					frappe.log_error("Gocardless redirect failed")
-
-				if custom_redirect_to:
-					redirect_to = custom_redirect_to
-
-			redirect_url = redirect_to
-		else:
-			status = "Error"
-			redirect_url = "payment-failed"
-
-			if redirect_message:
-				redirect_url += "&" + urlencode({"redirect_message": redirect_message})
-
-			redirect_url = get_url(redirect_url)
-
-		return {"redirect_to": redirect_url, "status": status}
-
-
-def get_gateway_controller(doc):
-	payment_request = frappe.get_doc("Payment Request", doc)
-	gateway_controller = frappe.db.get_value(
-		"Payment Gateway", payment_request.payment_gateway, "gateway_controller"
-	)
-	return gateway_controller
-
-
-def gocardless_initialization(doc):
-	gateway_controller = get_gateway_controller(doc)
-	settings = frappe.get_doc("GoCardless Settings", gateway_controller)
-	client = settings.initialize_client()
-	return client
diff --git a/erpnext/erpnext_integrations/doctype/gocardless_settings/test_gocardless_settings.py b/erpnext/erpnext_integrations/doctype/gocardless_settings/test_gocardless_settings.py
deleted file mode 100644
index 379afe5..0000000
--- a/erpnext/erpnext_integrations/doctype/gocardless_settings/test_gocardless_settings.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright (c) 2018, Frappe Technologies and Contributors
-# See license.txt
-
-import unittest
-
-
-class TestGoCardlessSettings(unittest.TestCase):
-	pass
diff --git a/erpnext/erpnext_integrations/doctype/mpesa_settings/__init__.py b/erpnext/erpnext_integrations/doctype/mpesa_settings/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/erpnext_integrations/doctype/mpesa_settings/__init__.py
+++ /dev/null
diff --git a/erpnext/erpnext_integrations/doctype/mpesa_settings/account_balance.html b/erpnext/erpnext_integrations/doctype/mpesa_settings/account_balance.html
deleted file mode 100644
index b74a718..0000000
--- a/erpnext/erpnext_integrations/doctype/mpesa_settings/account_balance.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-{% if not jQuery.isEmptyObject(data) %}
-<h5 style="margin-top: 20px;"> {{ __("Balance Details") }} </h5>
-<table class="table table-bordered small">
-	<thead>
-		<tr>
-			<th style="width: 20%">{{ __("Account Type") }}</th>
-			<th style="width: 20%" class="text-right">{{ __("Current Balance") }}</th>
-			<th style="width: 20%" class="text-right">{{ __("Available Balance") }}</th>
-			<th style="width: 20%" class="text-right">{{ __("Reserved Balance") }}</th>
-			<th style="width: 20%" class="text-right">{{ __("Uncleared Balance") }}</th>
-		</tr>
-	</thead>
-	<tbody>
-		{% for(const [key, value] of Object.entries(data)) { %}
-			<tr>
-				<td> {%= key %} </td>
-				<td class="text-right"> {%= value["current_balance"] %} </td>
-				<td class="text-right"> {%= value["available_balance"] %} </td>
-				<td class="text-right"> {%= value["reserved_balance"] %} </td>
-				<td class="text-right"> {%= value["uncleared_balance"] %} </td>
-			</tr>
-		{% } %}
-	</tbody>
-</table>
-{% else %}
-<p style="margin-top: 30px;"> Account Balance Information Not Available. </p>
-{% endif %}
diff --git a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_connector.py b/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_connector.py
deleted file mode 100644
index a577e7f..0000000
--- a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_connector.py
+++ /dev/null
@@ -1,149 +0,0 @@
-import base64
-import datetime
-
-import requests
-from requests.auth import HTTPBasicAuth
-
-
-class MpesaConnector:
-	def __init__(
-		self,
-		env="sandbox",
-		app_key=None,
-		app_secret=None,
-		sandbox_url="https://sandbox.safaricom.co.ke",
-		live_url="https://api.safaricom.co.ke",
-	):
-		"""Setup configuration for Mpesa connector and generate new access token."""
-		self.env = env
-		self.app_key = app_key
-		self.app_secret = app_secret
-		if env == "sandbox":
-			self.base_url = sandbox_url
-		else:
-			self.base_url = live_url
-		self.authenticate()
-
-	def authenticate(self):
-		"""
-		This method is used to fetch the access token required by Mpesa.
-
-		Returns:
-		        access_token (str): This token is to be used with the Bearer header for further API calls to Mpesa.
-		"""
-		authenticate_uri = "/oauth/v1/generate?grant_type=client_credentials"
-		authenticate_url = "{0}{1}".format(self.base_url, authenticate_uri)
-		r = requests.get(authenticate_url, auth=HTTPBasicAuth(self.app_key, self.app_secret))
-		self.authentication_token = r.json()["access_token"]
-		return r.json()["access_token"]
-
-	def get_balance(
-		self,
-		initiator=None,
-		security_credential=None,
-		party_a=None,
-		identifier_type=None,
-		remarks=None,
-		queue_timeout_url=None,
-		result_url=None,
-	):
-		"""
-		This method uses Mpesa's Account Balance API to to enquire the balance on a M-Pesa BuyGoods (Till Number).
-
-		Args:
-		        initiator (str): Username used to authenticate the transaction.
-		        security_credential (str): Generate from developer portal.
-		        command_id (str): AccountBalance.
-		        party_a (int): Till number being queried.
-		        identifier_type (int): Type of organization receiving the transaction. (MSISDN/Till Number/Organization short code)
-		        remarks (str): Comments that are sent along with the transaction(maximum 100 characters).
-		        queue_timeout_url (str): The url that handles information of timed out transactions.
-		        result_url (str): The url that receives results from M-Pesa api call.
-
-		Returns:
-		        OriginatorConverstionID (str): The unique request ID for tracking a transaction.
-		        ConversationID (str): The unique request ID returned by mpesa for each request made
-		        ResponseDescription (str): Response Description message
-		"""
-
-		payload = {
-			"Initiator": initiator,
-			"SecurityCredential": security_credential,
-			"CommandID": "AccountBalance",
-			"PartyA": party_a,
-			"IdentifierType": identifier_type,
-			"Remarks": remarks,
-			"QueueTimeOutURL": queue_timeout_url,
-			"ResultURL": result_url,
-		}
-		headers = {
-			"Authorization": "Bearer {0}".format(self.authentication_token),
-			"Content-Type": "application/json",
-		}
-		saf_url = "{0}{1}".format(self.base_url, "/mpesa/accountbalance/v1/query")
-		r = requests.post(saf_url, headers=headers, json=payload)
-		return r.json()
-
-	def stk_push(
-		self,
-		business_shortcode=None,
-		passcode=None,
-		amount=None,
-		callback_url=None,
-		reference_code=None,
-		phone_number=None,
-		description=None,
-	):
-		"""
-		This method uses Mpesa's Express API to initiate online payment on behalf of a customer.
-
-		Args:
-		        business_shortcode (int): The short code of the organization.
-		        passcode (str): Get from developer portal
-		        amount (int): The amount being transacted
-		        callback_url (str): A CallBack URL is a valid secure URL that is used to receive notifications from M-Pesa API.
-		        reference_code(str): Account Reference: This is an Alpha-Numeric parameter that is defined by your system as an Identifier of the transaction for CustomerPayBillOnline transaction type.
-		        phone_number(int): The Mobile Number to receive the STK Pin Prompt.
-		        description(str): This is any additional information/comment that can be sent along with the request from your system. MAX 13 characters
-
-		Success Response:
-		        CustomerMessage(str): Messages that customers can understand.
-		        CheckoutRequestID(str): This is a global unique identifier of the processed checkout transaction request.
-		        ResponseDescription(str): Describes Success or failure
-		        MerchantRequestID(str): This is a global unique Identifier for any submitted payment request.
-		        ResponseCode(int): 0 means success all others are error codes. e.g.404.001.03
-
-		Error Reponse:
-		        requestId(str): This is a unique requestID for the payment request
-		        errorCode(str): This is a predefined code that indicates the reason for request failure.
-		        errorMessage(str): This is a predefined code that indicates the reason for request failure.
-		"""
-
-		time = (
-			str(datetime.datetime.now()).split(".")[0].replace("-", "").replace(" ", "").replace(":", "")
-		)
-		password = "{0}{1}{2}".format(str(business_shortcode), str(passcode), time)
-		encoded = base64.b64encode(bytes(password, encoding="utf8"))
-		payload = {
-			"BusinessShortCode": business_shortcode,
-			"Password": encoded.decode("utf-8"),
-			"Timestamp": time,
-			"Amount": amount,
-			"PartyA": int(phone_number),
-			"PartyB": reference_code,
-			"PhoneNumber": int(phone_number),
-			"CallBackURL": callback_url,
-			"AccountReference": reference_code,
-			"TransactionDesc": description,
-			"TransactionType": "CustomerPayBillOnline"
-			if self.env == "sandbox"
-			else "CustomerBuyGoodsOnline",
-		}
-		headers = {
-			"Authorization": "Bearer {0}".format(self.authentication_token),
-			"Content-Type": "application/json",
-		}
-
-		saf_url = "{0}{1}".format(self.base_url, "/mpesa/stkpush/v1/processrequest")
-		r = requests.post(saf_url, headers=headers, json=payload)
-		return r.json()
diff --git a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_custom_fields.py b/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_custom_fields.py
deleted file mode 100644
index c92edc5..0000000
--- a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_custom_fields.py
+++ /dev/null
@@ -1,56 +0,0 @@
-import frappe
-from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
-
-
-def create_custom_pos_fields():
-	"""Create custom fields corresponding to POS Settings and POS Invoice."""
-	pos_field = {
-		"POS Invoice": [
-			{
-				"fieldname": "request_for_payment",
-				"label": "Request for Payment",
-				"fieldtype": "Button",
-				"hidden": 1,
-				"insert_after": "contact_email",
-			},
-			{
-				"fieldname": "mpesa_receipt_number",
-				"label": "Mpesa Receipt Number",
-				"fieldtype": "Data",
-				"read_only": 1,
-				"insert_after": "company",
-			},
-		]
-	}
-	if not frappe.get_meta("POS Invoice").has_field("request_for_payment"):
-		create_custom_fields(pos_field)
-
-	record_dict = [
-		{
-			"doctype": "POS Field",
-			"fieldname": "contact_mobile",
-			"label": "Mobile No",
-			"fieldtype": "Data",
-			"options": "Phone",
-			"parenttype": "POS Settings",
-			"parent": "POS Settings",
-			"parentfield": "invoice_fields",
-		},
-		{
-			"doctype": "POS Field",
-			"fieldname": "request_for_payment",
-			"label": "Request for Payment",
-			"fieldtype": "Button",
-			"parenttype": "POS Settings",
-			"parent": "POS Settings",
-			"parentfield": "invoice_fields",
-		},
-	]
-	create_pos_settings(record_dict)
-
-
-def create_pos_settings(record_dict):
-	for record in record_dict:
-		if frappe.db.exists("POS Field", {"fieldname": record.get("fieldname")}):
-			continue
-		frappe.get_doc(record).insert()
diff --git a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.js b/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.js
deleted file mode 100644
index 447d720..0000000
--- a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Mpesa Settings', {
-	onload_post_render: function(frm) {
-		frm.events.setup_account_balance_html(frm);
-	},
-
-	refresh: function(frm) {
-		erpnext.utils.check_payments_app();
-
-		frappe.realtime.on("refresh_mpesa_dashboard", function(){
-			frm.reload_doc();
-			frm.events.setup_account_balance_html(frm);
-		});
-	},
-
-	get_account_balance: function(frm) {
-		if (!frm.doc.initiator_name && !frm.doc.security_credential) {
-			frappe.throw(__("Please set the initiator name and the security credential"));
-		}
-		frappe.call({
-			method: "get_account_balance_info",
-			doc: frm.doc
-		});
-	},
-
-	setup_account_balance_html: function(frm) {
-		if (!frm.doc.account_balance) return;
-		$("div").remove(".form-dashboard-section.custom");
-		frm.dashboard.add_section(
-			frappe.render_template('account_balance', {
-				data: JSON.parse(frm.doc.account_balance)
-			})
-		);
-		frm.dashboard.show();
-	}
-
-});
diff --git a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.json b/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.json
deleted file mode 100644
index 8f3b427..0000000
--- a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.json
+++ /dev/null
@@ -1,152 +0,0 @@
-{
- "actions": [],
- "autoname": "field:payment_gateway_name",
- "creation": "2020-09-10 13:21:27.398088",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "payment_gateway_name",
-  "consumer_key",
-  "consumer_secret",
-  "initiator_name",
-  "till_number",
-  "transaction_limit",
-  "sandbox",
-  "column_break_4",
-  "business_shortcode",
-  "online_passkey",
-  "security_credential",
-  "get_account_balance",
-  "account_balance"
- ],
- "fields": [
-  {
-   "fieldname": "payment_gateway_name",
-   "fieldtype": "Data",
-   "label": "Payment Gateway Name",
-   "reqd": 1,
-   "unique": 1
-  },
-  {
-   "fieldname": "consumer_key",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Consumer Key",
-   "reqd": 1
-  },
-  {
-   "fieldname": "consumer_secret",
-   "fieldtype": "Password",
-   "in_list_view": 1,
-   "label": "Consumer Secret",
-   "reqd": 1
-  },
-  {
-   "fieldname": "till_number",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Till Number",
-   "reqd": 1
-  },
-  {
-   "default": "0",
-   "fieldname": "sandbox",
-   "fieldtype": "Check",
-   "label": "Sandbox"
-  },
-  {
-   "fieldname": "column_break_4",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "online_passkey",
-   "fieldtype": "Password",
-   "label": " Online PassKey",
-   "reqd": 1
-  },
-  {
-   "fieldname": "initiator_name",
-   "fieldtype": "Data",
-   "label": "Initiator Name"
-  },
-  {
-   "fieldname": "security_credential",
-   "fieldtype": "Small Text",
-   "label": "Security Credential"
-  },
-  {
-   "fieldname": "account_balance",
-   "fieldtype": "Long Text",
-   "hidden": 1,
-   "label": "Account Balance",
-   "read_only": 1
-  },
-  {
-   "fieldname": "get_account_balance",
-   "fieldtype": "Button",
-   "label": "Get Account Balance"
-  },
-  {
-   "depends_on": "eval:(doc.sandbox==0)",
-   "fieldname": "business_shortcode",
-   "fieldtype": "Data",
-   "label": "Business Shortcode",
-   "mandatory_depends_on": "eval:(doc.sandbox==0)"
-  },
-  {
-   "default": "150000",
-   "fieldname": "transaction_limit",
-   "fieldtype": "Float",
-   "label": "Transaction Limit",
-   "non_negative": 1
-  }
- ],
- "links": [],
- "modified": "2021-03-02 17:35:14.084342",
- "modified_by": "Administrator",
- "module": "ERPNext Integrations",
- "name": "Mpesa Settings",
- "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": "Accounts Manager",
-   "share": 1,
-   "write": 1
-  },
-  {
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Accounts User",
-   "share": 1,
-   "write": 1
-  }
- ],
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.py b/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.py
deleted file mode 100644
index a298e11..0000000
--- a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.py
+++ /dev/null
@@ -1,354 +0,0 @@
-# Copyright (c) 2020, Frappe Technologies and contributors
-# For license information, please see license.txt
-
-
-from json import dumps, loads
-
-import frappe
-from frappe import _
-from frappe.integrations.utils import create_request_log
-from frappe.model.document import Document
-from frappe.utils import call_hook_method, fmt_money, get_request_site_address
-
-from erpnext.erpnext_integrations.doctype.mpesa_settings.mpesa_connector import MpesaConnector
-from erpnext.erpnext_integrations.doctype.mpesa_settings.mpesa_custom_fields import (
-	create_custom_pos_fields,
-)
-from erpnext.erpnext_integrations.utils import create_mode_of_payment
-from erpnext.utilities import payment_app_import_guard
-
-
-class MpesaSettings(Document):
-	supported_currencies = ["KES"]
-
-	def validate_transaction_currency(self, currency):
-		if currency not in self.supported_currencies:
-			frappe.throw(
-				_(
-					"Please select another payment method. Mpesa does not support transactions in currency '{0}'"
-				).format(currency)
-			)
-
-	def on_update(self):
-		with payment_app_import_guard():
-			from payments.utils import create_payment_gateway
-
-		create_custom_pos_fields()
-		create_payment_gateway(
-			"Mpesa-" + self.payment_gateway_name,
-			settings="Mpesa Settings",
-			controller=self.payment_gateway_name,
-		)
-		call_hook_method(
-			"payment_gateway_enabled", gateway="Mpesa-" + self.payment_gateway_name, payment_channel="Phone"
-		)
-
-		# required to fetch the bank account details from the payment gateway account
-		frappe.db.commit()
-		create_mode_of_payment("Mpesa-" + self.payment_gateway_name, payment_type="Phone")
-
-	def request_for_payment(self, **kwargs):
-		args = frappe._dict(kwargs)
-		request_amounts = self.split_request_amount_according_to_transaction_limit(args)
-
-		for i, amount in enumerate(request_amounts):
-			args.request_amount = amount
-			if frappe.flags.in_test:
-				from erpnext.erpnext_integrations.doctype.mpesa_settings.test_mpesa_settings import (
-					get_payment_request_response_payload,
-				)
-
-				response = frappe._dict(get_payment_request_response_payload(amount))
-			else:
-				response = frappe._dict(generate_stk_push(**args))
-
-			self.handle_api_response("CheckoutRequestID", args, response)
-
-	def split_request_amount_according_to_transaction_limit(self, args):
-		request_amount = args.request_amount
-		if request_amount > self.transaction_limit:
-			# make multiple requests
-			request_amounts = []
-			requests_to_be_made = frappe.utils.ceil(
-				request_amount / self.transaction_limit
-			)  # 480/150 = ceil(3.2) = 4
-			for i in range(requests_to_be_made):
-				amount = self.transaction_limit
-				if i == requests_to_be_made - 1:
-					amount = request_amount - (
-						self.transaction_limit * i
-					)  # for 4th request, 480 - (150 * 3) = 30
-				request_amounts.append(amount)
-		else:
-			request_amounts = [request_amount]
-
-		return request_amounts
-
-	@frappe.whitelist()
-	def get_account_balance_info(self):
-		payload = dict(
-			reference_doctype="Mpesa Settings", reference_docname=self.name, doc_details=vars(self)
-		)
-
-		if frappe.flags.in_test:
-			from erpnext.erpnext_integrations.doctype.mpesa_settings.test_mpesa_settings import (
-				get_test_account_balance_response,
-			)
-
-			response = frappe._dict(get_test_account_balance_response())
-		else:
-			response = frappe._dict(get_account_balance(payload))
-
-		self.handle_api_response("ConversationID", payload, response)
-
-	def handle_api_response(self, global_id, request_dict, response):
-		"""Response received from API calls returns a global identifier for each transaction, this code is returned during the callback."""
-		# check error response
-		if getattr(response, "requestId"):
-			req_name = getattr(response, "requestId")
-			error = response
-		else:
-			# global checkout id used as request name
-			req_name = getattr(response, global_id)
-			error = None
-
-		if not frappe.db.exists("Integration Request", req_name):
-			create_request_log(request_dict, "Host", "Mpesa", req_name, error)
-
-		if error:
-			frappe.throw(_(getattr(response, "errorMessage")), title=_("Transaction Error"))
-
-
-def generate_stk_push(**kwargs):
-	"""Generate stk push by making a API call to the stk push API."""
-	args = frappe._dict(kwargs)
-	try:
-		callback_url = (
-			get_request_site_address(True)
-			+ "/api/method/erpnext.erpnext_integrations.doctype.mpesa_settings.mpesa_settings.verify_transaction"
-		)
-
-		mpesa_settings = frappe.get_doc("Mpesa Settings", args.payment_gateway[6:])
-		env = "production" if not mpesa_settings.sandbox else "sandbox"
-		# for sandbox, business shortcode is same as till number
-		business_shortcode = (
-			mpesa_settings.business_shortcode if env == "production" else mpesa_settings.till_number
-		)
-
-		connector = MpesaConnector(
-			env=env,
-			app_key=mpesa_settings.consumer_key,
-			app_secret=mpesa_settings.get_password("consumer_secret"),
-		)
-
-		mobile_number = sanitize_mobile_number(args.sender)
-
-		response = connector.stk_push(
-			business_shortcode=business_shortcode,
-			amount=args.request_amount,
-			passcode=mpesa_settings.get_password("online_passkey"),
-			callback_url=callback_url,
-			reference_code=mpesa_settings.till_number,
-			phone_number=mobile_number,
-			description="POS Payment",
-		)
-
-		return response
-
-	except Exception:
-		frappe.log_error("Mpesa Express Transaction Error")
-		frappe.throw(
-			_("Issue detected with Mpesa configuration, check the error logs for more details"),
-			title=_("Mpesa Express Error"),
-		)
-
-
-def sanitize_mobile_number(number):
-	"""Add country code and strip leading zeroes from the phone number."""
-	return "254" + str(number).lstrip("0")
-
-
-@frappe.whitelist(allow_guest=True)
-def verify_transaction(**kwargs):
-	"""Verify the transaction result received via callback from stk."""
-	transaction_response = frappe._dict(kwargs["Body"]["stkCallback"])
-
-	checkout_id = getattr(transaction_response, "CheckoutRequestID", "")
-	if not isinstance(checkout_id, str):
-		frappe.throw(_("Invalid Checkout Request ID"))
-
-	integration_request = frappe.get_doc("Integration Request", checkout_id)
-	transaction_data = frappe._dict(loads(integration_request.data))
-	total_paid = 0  # for multiple integration request made against a pos invoice
-	success = False  # for reporting successfull callback to point of sale ui
-
-	if transaction_response["ResultCode"] == 0:
-		if integration_request.reference_doctype and integration_request.reference_docname:
-			try:
-				item_response = transaction_response["CallbackMetadata"]["Item"]
-				amount = fetch_param_value(item_response, "Amount", "Name")
-				mpesa_receipt = fetch_param_value(item_response, "MpesaReceiptNumber", "Name")
-				pr = frappe.get_doc(
-					integration_request.reference_doctype, integration_request.reference_docname
-				)
-
-				mpesa_receipts, completed_payments = get_completed_integration_requests_info(
-					integration_request.reference_doctype, integration_request.reference_docname, checkout_id
-				)
-
-				total_paid = amount + sum(completed_payments)
-				mpesa_receipts = ", ".join(mpesa_receipts + [mpesa_receipt])
-
-				if total_paid >= pr.grand_total:
-					pr.run_method("on_payment_authorized", "Completed")
-					success = True
-
-				frappe.db.set_value("POS Invoice", pr.reference_name, "mpesa_receipt_number", mpesa_receipts)
-				integration_request.handle_success(transaction_response)
-			except Exception:
-				integration_request.handle_failure(transaction_response)
-				frappe.log_error("Mpesa: Failed to verify transaction")
-
-	else:
-		integration_request.handle_failure(transaction_response)
-
-	frappe.publish_realtime(
-		event="process_phone_payment",
-		doctype="POS Invoice",
-		docname=transaction_data.payment_reference,
-		user=integration_request.owner,
-		message={
-			"amount": total_paid,
-			"success": success,
-			"failure_message": transaction_response["ResultDesc"]
-			if transaction_response["ResultCode"] != 0
-			else "",
-		},
-	)
-
-
-def get_completed_integration_requests_info(reference_doctype, reference_docname, checkout_id):
-	output_of_other_completed_requests = frappe.get_all(
-		"Integration Request",
-		filters={
-			"name": ["!=", checkout_id],
-			"reference_doctype": reference_doctype,
-			"reference_docname": reference_docname,
-			"status": "Completed",
-		},
-		pluck="output",
-	)
-
-	mpesa_receipts, completed_payments = [], []
-
-	for out in output_of_other_completed_requests:
-		out = frappe._dict(loads(out))
-		item_response = out["CallbackMetadata"]["Item"]
-		completed_amount = fetch_param_value(item_response, "Amount", "Name")
-		completed_mpesa_receipt = fetch_param_value(item_response, "MpesaReceiptNumber", "Name")
-		completed_payments.append(completed_amount)
-		mpesa_receipts.append(completed_mpesa_receipt)
-
-	return mpesa_receipts, completed_payments
-
-
-def get_account_balance(request_payload):
-	"""Call account balance API to send the request to the Mpesa Servers."""
-	try:
-		mpesa_settings = frappe.get_doc("Mpesa Settings", request_payload.get("reference_docname"))
-		env = "production" if not mpesa_settings.sandbox else "sandbox"
-		connector = MpesaConnector(
-			env=env,
-			app_key=mpesa_settings.consumer_key,
-			app_secret=mpesa_settings.get_password("consumer_secret"),
-		)
-
-		callback_url = (
-			get_request_site_address(True)
-			+ "/api/method/erpnext.erpnext_integrations.doctype.mpesa_settings.mpesa_settings.process_balance_info"
-		)
-
-		response = connector.get_balance(
-			mpesa_settings.initiator_name,
-			mpesa_settings.security_credential,
-			mpesa_settings.till_number,
-			4,
-			mpesa_settings.name,
-			callback_url,
-			callback_url,
-		)
-		return response
-	except Exception:
-		frappe.log_error("Mpesa: Failed to get account balance")
-		frappe.throw(_("Please check your configuration and try again"), title=_("Error"))
-
-
-@frappe.whitelist(allow_guest=True)
-def process_balance_info(**kwargs):
-	"""Process and store account balance information received via callback from the account balance API call."""
-	account_balance_response = frappe._dict(kwargs["Result"])
-
-	conversation_id = getattr(account_balance_response, "ConversationID", "")
-	if not isinstance(conversation_id, str):
-		frappe.throw(_("Invalid Conversation ID"))
-
-	request = frappe.get_doc("Integration Request", conversation_id)
-
-	if request.status == "Completed":
-		return
-
-	transaction_data = frappe._dict(loads(request.data))
-
-	if account_balance_response["ResultCode"] == 0:
-		try:
-			result_params = account_balance_response["ResultParameters"]["ResultParameter"]
-
-			balance_info = fetch_param_value(result_params, "AccountBalance", "Key")
-			balance_info = format_string_to_json(balance_info)
-
-			ref_doc = frappe.get_doc(transaction_data.reference_doctype, transaction_data.reference_docname)
-			ref_doc.db_set("account_balance", balance_info)
-
-			request.handle_success(account_balance_response)
-			frappe.publish_realtime(
-				"refresh_mpesa_dashboard",
-				doctype="Mpesa Settings",
-				docname=transaction_data.reference_docname,
-				user=transaction_data.owner,
-			)
-		except Exception:
-			request.handle_failure(account_balance_response)
-			frappe.log_error(
-				title="Mpesa Account Balance Processing Error", message=account_balance_response
-			)
-	else:
-		request.handle_failure(account_balance_response)
-
-
-def format_string_to_json(balance_info):
-	"""
-	Format string to json.
-
-	e.g: '''Working Account|KES|481000.00|481000.00|0.00|0.00'''
-	=> {'Working Account': {'current_balance': '481000.00',
-	        'available_balance': '481000.00',
-	        'reserved_balance': '0.00',
-	        'uncleared_balance': '0.00'}}
-	"""
-	balance_dict = frappe._dict()
-	for account_info in balance_info.split("&"):
-		account_info = account_info.split("|")
-		balance_dict[account_info[0]] = dict(
-			current_balance=fmt_money(account_info[2], currency="KES"),
-			available_balance=fmt_money(account_info[3], currency="KES"),
-			reserved_balance=fmt_money(account_info[4], currency="KES"),
-			uncleared_balance=fmt_money(account_info[5], currency="KES"),
-		)
-	return dumps(balance_dict)
-
-
-def fetch_param_value(response, key, key_field):
-	"""Fetch the specified key from list of dictionary. Key is identified via the key field."""
-	for param in response:
-		if param[key_field] == key:
-			return param["Value"]
diff --git a/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py b/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py
deleted file mode 100644
index b526624..0000000
--- a/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py
+++ /dev/null
@@ -1,361 +0,0 @@
-# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-
-import unittest
-from json import dumps
-
-import frappe
-
-from erpnext.accounts.doctype.pos_invoice.test_pos_invoice import create_pos_invoice
-from erpnext.erpnext_integrations.doctype.mpesa_settings.mpesa_settings import (
-	process_balance_info,
-	verify_transaction,
-)
-from erpnext.erpnext_integrations.utils import create_mode_of_payment
-
-
-class TestMpesaSettings(unittest.TestCase):
-	def setUp(self):
-		# create payment gateway in setup
-		create_mpesa_settings(payment_gateway_name="_Test")
-		create_mpesa_settings(payment_gateway_name="_Account Balance")
-		create_mpesa_settings(payment_gateway_name="Payment")
-
-	def tearDown(self):
-		frappe.db.sql("delete from `tabMpesa Settings`")
-		frappe.db.sql("delete from `tabIntegration Request` where integration_request_service = 'Mpesa'")
-
-	def test_creation_of_payment_gateway(self):
-		mode_of_payment = create_mode_of_payment("Mpesa-_Test", payment_type="Phone")
-		self.assertTrue(frappe.db.exists("Payment Gateway Account", {"payment_gateway": "Mpesa-_Test"}))
-		self.assertTrue(mode_of_payment.name)
-		self.assertEqual(mode_of_payment.type, "Phone")
-
-	def test_processing_of_account_balance(self):
-		mpesa_doc = create_mpesa_settings(payment_gateway_name="_Account Balance")
-		mpesa_doc.get_account_balance_info()
-
-		callback_response = get_account_balance_callback_payload()
-		process_balance_info(**callback_response)
-		integration_request = frappe.get_doc("Integration Request", "AG_20200927_00007cdb1f9fb6494315")
-
-		# test integration request creation and successful update of the status on receiving callback response
-		self.assertTrue(integration_request)
-		self.assertEqual(integration_request.status, "Completed")
-
-		# test formatting of account balance received as string to json with appropriate currency symbol
-		mpesa_doc.reload()
-		self.assertEqual(
-			mpesa_doc.account_balance,
-			dumps(
-				{
-					"Working Account": {
-						"current_balance": "Sh 481,000.00",
-						"available_balance": "Sh 481,000.00",
-						"reserved_balance": "Sh 0.00",
-						"uncleared_balance": "Sh 0.00",
-					}
-				}
-			),
-		)
-
-		integration_request.delete()
-
-	def test_processing_of_callback_payload(self):
-		mpesa_account = frappe.db.get_value(
-			"Payment Gateway Account", {"payment_gateway": "Mpesa-Payment"}, "payment_account"
-		)
-		frappe.db.set_value("Account", mpesa_account, "account_currency", "KES")
-		frappe.db.set_value("Customer", "_Test Customer", "default_currency", "KES")
-
-		pos_invoice = create_pos_invoice(do_not_submit=1)
-		pos_invoice.append(
-			"payments", {"mode_of_payment": "Mpesa-Payment", "account": mpesa_account, "amount": 500}
-		)
-		pos_invoice.contact_mobile = "093456543894"
-		pos_invoice.currency = "KES"
-		pos_invoice.save()
-
-		pr = pos_invoice.create_payment_request()
-		# test payment request creation
-		self.assertEqual(pr.payment_gateway, "Mpesa-Payment")
-
-		# submitting payment request creates integration requests with random id
-		integration_req_ids = frappe.get_all(
-			"Integration Request",
-			filters={
-				"reference_doctype": pr.doctype,
-				"reference_docname": pr.name,
-			},
-			pluck="name",
-		)
-
-		callback_response = get_payment_callback_payload(
-			Amount=500, CheckoutRequestID=integration_req_ids[0]
-		)
-		verify_transaction(**callback_response)
-		# test creation of integration request
-		integration_request = frappe.get_doc("Integration Request", integration_req_ids[0])
-
-		# test integration request creation and successful update of the status on receiving callback response
-		self.assertTrue(integration_request)
-		self.assertEqual(integration_request.status, "Completed")
-
-		pos_invoice.reload()
-		integration_request.reload()
-		self.assertEqual(pos_invoice.mpesa_receipt_number, "LGR7OWQX0R")
-		self.assertEqual(integration_request.status, "Completed")
-
-		frappe.db.set_value("Customer", "_Test Customer", "default_currency", "")
-		integration_request.delete()
-		pr.reload()
-		pr.cancel()
-		pr.delete()
-		pos_invoice.delete()
-
-	def test_processing_of_multiple_callback_payload(self):
-		mpesa_account = frappe.db.get_value(
-			"Payment Gateway Account", {"payment_gateway": "Mpesa-Payment"}, "payment_account"
-		)
-		frappe.db.set_value("Account", mpesa_account, "account_currency", "KES")
-		frappe.db.set_value("Mpesa Settings", "Payment", "transaction_limit", "500")
-		frappe.db.set_value("Customer", "_Test Customer", "default_currency", "KES")
-
-		pos_invoice = create_pos_invoice(do_not_submit=1)
-		pos_invoice.append(
-			"payments", {"mode_of_payment": "Mpesa-Payment", "account": mpesa_account, "amount": 1000}
-		)
-		pos_invoice.contact_mobile = "093456543894"
-		pos_invoice.currency = "KES"
-		pos_invoice.save()
-
-		pr = pos_invoice.create_payment_request()
-		# test payment request creation
-		self.assertEqual(pr.payment_gateway, "Mpesa-Payment")
-
-		# submitting payment request creates integration requests with random id
-		integration_req_ids = frappe.get_all(
-			"Integration Request",
-			filters={
-				"reference_doctype": pr.doctype,
-				"reference_docname": pr.name,
-			},
-			pluck="name",
-		)
-
-		# create random receipt nos and send it as response to callback handler
-		mpesa_receipt_numbers = [frappe.utils.random_string(5) for d in integration_req_ids]
-
-		integration_requests = []
-		for i in range(len(integration_req_ids)):
-			callback_response = get_payment_callback_payload(
-				Amount=500,
-				CheckoutRequestID=integration_req_ids[i],
-				MpesaReceiptNumber=mpesa_receipt_numbers[i],
-			)
-			# handle response manually
-			verify_transaction(**callback_response)
-			# test completion of integration request
-			integration_request = frappe.get_doc("Integration Request", integration_req_ids[i])
-			self.assertEqual(integration_request.status, "Completed")
-			integration_requests.append(integration_request)
-
-		# check receipt number once all the integration requests are completed
-		pos_invoice.reload()
-		self.assertEqual(pos_invoice.mpesa_receipt_number, ", ".join(mpesa_receipt_numbers))
-
-		frappe.db.set_value("Customer", "_Test Customer", "default_currency", "")
-		[d.delete() for d in integration_requests]
-		pr.reload()
-		pr.cancel()
-		pr.delete()
-		pos_invoice.delete()
-
-	def test_processing_of_only_one_succes_callback_payload(self):
-		mpesa_account = frappe.db.get_value(
-			"Payment Gateway Account", {"payment_gateway": "Mpesa-Payment"}, "payment_account"
-		)
-		frappe.db.set_value("Account", mpesa_account, "account_currency", "KES")
-		frappe.db.set_value("Mpesa Settings", "Payment", "transaction_limit", "500")
-		frappe.db.set_value("Customer", "_Test Customer", "default_currency", "KES")
-
-		pos_invoice = create_pos_invoice(do_not_submit=1)
-		pos_invoice.append(
-			"payments", {"mode_of_payment": "Mpesa-Payment", "account": mpesa_account, "amount": 1000}
-		)
-		pos_invoice.contact_mobile = "093456543894"
-		pos_invoice.currency = "KES"
-		pos_invoice.save()
-
-		pr = pos_invoice.create_payment_request()
-		# test payment request creation
-		self.assertEqual(pr.payment_gateway, "Mpesa-Payment")
-
-		# submitting payment request creates integration requests with random id
-		integration_req_ids = frappe.get_all(
-			"Integration Request",
-			filters={
-				"reference_doctype": pr.doctype,
-				"reference_docname": pr.name,
-			},
-			pluck="name",
-		)
-
-		# create random receipt nos and send it as response to callback handler
-		mpesa_receipt_numbers = [frappe.utils.random_string(5) for d in integration_req_ids]
-
-		callback_response = get_payment_callback_payload(
-			Amount=500,
-			CheckoutRequestID=integration_req_ids[0],
-			MpesaReceiptNumber=mpesa_receipt_numbers[0],
-		)
-		# handle response manually
-		verify_transaction(**callback_response)
-		# test completion of integration request
-		integration_request = frappe.get_doc("Integration Request", integration_req_ids[0])
-		self.assertEqual(integration_request.status, "Completed")
-
-		# now one request is completed
-		# second integration request fails
-		# now retrying payment request should make only one integration request again
-		pr = pos_invoice.create_payment_request()
-		new_integration_req_ids = frappe.get_all(
-			"Integration Request",
-			filters={
-				"reference_doctype": pr.doctype,
-				"reference_docname": pr.name,
-				"name": ["not in", integration_req_ids],
-			},
-			pluck="name",
-		)
-
-		self.assertEqual(len(new_integration_req_ids), 1)
-
-		frappe.db.set_value("Customer", "_Test Customer", "default_currency", "")
-		frappe.db.sql("delete from `tabIntegration Request` where integration_request_service = 'Mpesa'")
-		pr.reload()
-		pr.cancel()
-		pr.delete()
-		pos_invoice.delete()
-
-
-def create_mpesa_settings(payment_gateway_name="Express"):
-	if frappe.db.exists("Mpesa Settings", payment_gateway_name):
-		return frappe.get_doc("Mpesa Settings", payment_gateway_name)
-
-	doc = frappe.get_doc(
-		dict(  # nosec
-			doctype="Mpesa Settings",
-			sandbox=1,
-			payment_gateway_name=payment_gateway_name,
-			consumer_key="5sMu9LVI1oS3oBGPJfh3JyvLHwZOdTKn",
-			consumer_secret="VI1oS3oBGPJfh3JyvLHw",
-			online_passkey="LVI1oS3oBGPJfh3JyvLHwZOd",
-			till_number="174379",
-		)
-	)
-
-	doc.insert(ignore_permissions=True)
-	return doc
-
-
-def get_test_account_balance_response():
-	"""Response received after calling the account balance API."""
-	return {
-		"ResultType": 0,
-		"ResultCode": 0,
-		"ResultDesc": "The service request has been accepted successfully.",
-		"OriginatorConversationID": "10816-694520-2",
-		"ConversationID": "AG_20200927_00007cdb1f9fb6494315",
-		"TransactionID": "LGR0000000",
-		"ResultParameters": {
-			"ResultParameter": [
-				{"Key": "ReceiptNo", "Value": "LGR919G2AV"},
-				{"Key": "Conversation ID", "Value": "AG_20170727_00004492b1b6d0078fbe"},
-				{"Key": "FinalisedTime", "Value": 20170727101415},
-				{"Key": "Amount", "Value": 10},
-				{"Key": "TransactionStatus", "Value": "Completed"},
-				{"Key": "ReasonType", "Value": "Salary Payment via API"},
-				{"Key": "TransactionReason"},
-				{"Key": "DebitPartyCharges", "Value": "Fee For B2C Payment|KES|33.00"},
-				{"Key": "DebitAccountType", "Value": "Utility Account"},
-				{"Key": "InitiatedTime", "Value": 20170727101415},
-				{"Key": "Originator Conversation ID", "Value": "19455-773836-1"},
-				{"Key": "CreditPartyName", "Value": "254708374149 - John Doe"},
-				{"Key": "DebitPartyName", "Value": "600134 - Safaricom157"},
-			]
-		},
-		"ReferenceData": {"ReferenceItem": {"Key": "Occasion", "Value": "aaaa"}},
-	}
-
-
-def get_payment_request_response_payload(Amount=500):
-	"""Response received after successfully calling the stk push process request API."""
-
-	CheckoutRequestID = frappe.utils.random_string(10)
-
-	return {
-		"MerchantRequestID": "8071-27184008-1",
-		"CheckoutRequestID": CheckoutRequestID,
-		"ResultCode": 0,
-		"ResultDesc": "The service request is processed successfully.",
-		"CallbackMetadata": {
-			"Item": [
-				{"Name": "Amount", "Value": Amount},
-				{"Name": "MpesaReceiptNumber", "Value": "LGR7OWQX0R"},
-				{"Name": "TransactionDate", "Value": 20201006113336},
-				{"Name": "PhoneNumber", "Value": 254723575670},
-			]
-		},
-	}
-
-
-def get_payment_callback_payload(
-	Amount=500, CheckoutRequestID="ws_CO_061020201133231972", MpesaReceiptNumber="LGR7OWQX0R"
-):
-	"""Response received from the server as callback after calling the stkpush process request API."""
-	return {
-		"Body": {
-			"stkCallback": {
-				"MerchantRequestID": "19465-780693-1",
-				"CheckoutRequestID": CheckoutRequestID,
-				"ResultCode": 0,
-				"ResultDesc": "The service request is processed successfully.",
-				"CallbackMetadata": {
-					"Item": [
-						{"Name": "Amount", "Value": Amount},
-						{"Name": "MpesaReceiptNumber", "Value": MpesaReceiptNumber},
-						{"Name": "Balance"},
-						{"Name": "TransactionDate", "Value": 20170727154800},
-						{"Name": "PhoneNumber", "Value": 254721566839},
-					]
-				},
-			}
-		}
-	}
-
-
-def get_account_balance_callback_payload():
-	"""Response received from the server as callback after calling the account balance API."""
-	return {
-		"Result": {
-			"ResultType": 0,
-			"ResultCode": 0,
-			"ResultDesc": "The service request is processed successfully.",
-			"OriginatorConversationID": "16470-170099139-1",
-			"ConversationID": "AG_20200927_00007cdb1f9fb6494315",
-			"TransactionID": "OIR0000000",
-			"ResultParameters": {
-				"ResultParameter": [
-					{"Key": "AccountBalance", "Value": "Working Account|KES|481000.00|481000.00|0.00|0.00"},
-					{"Key": "BOCompletedTime", "Value": 20200927234123},
-				]
-			},
-			"ReferenceData": {
-				"ReferenceItem": {
-					"Key": "QueueTimeoutURL",
-					"Value": "https://internalsandbox.safaricom.co.ke/mpesa/abresults/v1/submit",
-				}
-			},
-		}
-	}
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
index 11d5f6a..eb99345 100644
--- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
@@ -7,7 +7,7 @@
 from frappe import _
 from frappe.desk.doctype.tag.tag import add_tag
 from frappe.model.document import Document
-from frappe.utils import add_months, formatdate, getdate, today
+from frappe.utils import add_months, formatdate, getdate, sbool, today
 from plaid.errors import ItemError
 
 from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
@@ -237,8 +237,6 @@
 		deposit = abs(amount)
 		withdrawal = 0.0
 
-	status = "Pending" if transaction["pending"] == True else "Settled"
-
 	tags = []
 	if transaction["category"]:
 		try:
@@ -247,13 +245,14 @@
 		except KeyError:
 			pass
 
-	if not frappe.db.exists("Bank Transaction", dict(transaction_id=transaction["transaction_id"])):
+	if not frappe.db.exists(
+		"Bank Transaction", dict(transaction_id=transaction["transaction_id"])
+	) and not sbool(transaction["pending"]):
 		try:
 			new_transaction = frappe.get_doc(
 				{
 					"doctype": "Bank Transaction",
 					"date": getdate(transaction["date"]),
-					"status": status,
 					"bank_account": bank_account,
 					"deposit": deposit,
 					"withdrawal": withdrawal,
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py
index 86e1b31..6716853 100644
--- a/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py
@@ -43,40 +43,6 @@
 		add_account_subtype("loan")
 		self.assertEqual(frappe.get_doc("Bank Account Subtype", "loan").name, "loan")
 
-	def test_default_bank_account(self):
-		if not frappe.db.exists("Bank", "Citi"):
-			frappe.get_doc({"doctype": "Bank", "bank_name": "Citi"}).insert()
-
-		bank_accounts = {
-			"account": {
-				"subtype": "checking",
-				"mask": "0000",
-				"type": "depository",
-				"id": "6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK",
-				"name": "Plaid Checking",
-			},
-			"account_id": "6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK",
-			"link_session_id": "db673d75-61aa-442a-864f-9b3f174f3725",
-			"accounts": [
-				{
-					"type": "depository",
-					"subtype": "checking",
-					"mask": "0000",
-					"id": "6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK",
-					"name": "Plaid Checking",
-				}
-			],
-			"institution": {"institution_id": "ins_6", "name": "Citi"},
-		}
-
-		bank = json.dumps(frappe.get_doc("Bank", "Citi").as_dict(), default=json_handler)
-		company = frappe.db.get_single_value("Global Defaults", "default_company")
-		frappe.db.set_value("Company", company, "default_bank_account", None)
-
-		self.assertRaises(
-			frappe.ValidationError, add_bank_accounts, response=bank_accounts, bank=bank, company=company
-		)
-
 	def test_new_transaction(self):
 		if not frappe.db.exists("Bank", "Citi"):
 			frappe.get_doc({"doctype": "Bank", "bank_name": "Citi"}).insert()
diff --git a/erpnext/erpnext_integrations/stripe_integration.py b/erpnext/erpnext_integrations/stripe_integration.py
deleted file mode 100644
index 634e5c2..0000000
--- a/erpnext/erpnext_integrations/stripe_integration.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-import frappe
-from frappe import _
-from frappe.integrations.utils import create_request_log
-
-from erpnext.utilities import payment_app_import_guard
-
-
-def create_stripe_subscription(gateway_controller, data):
-	with payment_app_import_guard():
-		import stripe
-
-	stripe_settings = frappe.get_doc("Stripe Settings", gateway_controller)
-	stripe_settings.data = frappe._dict(data)
-
-	stripe.api_key = stripe_settings.get_password(fieldname="secret_key", raise_exception=False)
-	stripe.default_http_client = stripe.http_client.RequestsClient()
-
-	try:
-		stripe_settings.integration_request = create_request_log(stripe_settings.data, "Host", "Stripe")
-		stripe_settings.payment_plans = frappe.get_doc(
-			"Payment Request", stripe_settings.data.reference_docname
-		).subscription_plans
-		return create_subscription_on_stripe(stripe_settings)
-
-	except Exception:
-		stripe_settings.log_error("Unable to create Stripe subscription")
-		return {
-			"redirect_to": frappe.redirect_to_message(
-				_("Server Error"),
-				_(
-					"It seems that there is an issue with the server's stripe configuration. In case of failure, the amount will get refunded to your account."
-				),
-			),
-			"status": 401,
-		}
-
-
-def create_subscription_on_stripe(stripe_settings):
-	with payment_app_import_guard():
-		import stripe
-
-	items = []
-	for payment_plan in stripe_settings.payment_plans:
-		plan = frappe.db.get_value("Subscription Plan", payment_plan.plan, "product_price_id")
-		items.append({"price": plan, "quantity": payment_plan.qty})
-
-	try:
-		customer = stripe.Customer.create(
-			source=stripe_settings.data.stripe_token_id,
-			description=stripe_settings.data.payer_name,
-			email=stripe_settings.data.payer_email,
-		)
-
-		subscription = stripe.Subscription.create(customer=customer, items=items)
-
-		if subscription.status == "active":
-			stripe_settings.integration_request.db_set("status", "Completed", update_modified=False)
-			stripe_settings.flags.status_changed_to = "Completed"
-
-		else:
-			stripe_settings.integration_request.db_set("status", "Failed", update_modified=False)
-			frappe.log_error(f"Stripe Subscription ID {subscription.id}: Payment failed")
-	except Exception:
-		stripe_settings.integration_request.db_set("status", "Failed", update_modified=False)
-		stripe_settings.log_error("Unable to create Stripe subscription")
-
-	return stripe_settings.finalize_request()
diff --git a/erpnext/erpnext_integrations/utils.py b/erpnext/erpnext_integrations/utils.py
index 981486e..8984f1b 100644
--- a/erpnext/erpnext_integrations/utils.py
+++ b/erpnext/erpnext_integrations/utils.py
@@ -6,8 +6,6 @@
 import frappe
 from frappe import _
 
-from erpnext import get_default_company
-
 
 def validate_webhooks_request(doctype, hmac_key, secret_key="secret"):
 	def innerfn(fn):
@@ -47,35 +45,6 @@
 	return server_url
 
 
-def create_mode_of_payment(gateway, payment_type="General"):
-	payment_gateway_account = frappe.db.get_value(
-		"Payment Gateway Account", {"payment_gateway": gateway}, ["payment_account"]
-	)
-
-	mode_of_payment = frappe.db.exists("Mode of Payment", gateway)
-	if not mode_of_payment and payment_gateway_account:
-		mode_of_payment = frappe.get_doc(
-			{
-				"doctype": "Mode of Payment",
-				"mode_of_payment": gateway,
-				"enabled": 1,
-				"type": payment_type,
-				"accounts": [
-					{
-						"doctype": "Mode of Payment Account",
-						"company": get_default_company(),
-						"default_account": payment_gateway_account,
-					}
-				],
-			}
-		)
-		mode_of_payment.insert(ignore_permissions=True)
-
-		return mode_of_payment
-	elif mode_of_payment:
-		return frappe.get_doc("Mode of Payment", mode_of_payment)
-
-
 def get_tracking_url(carrier, tracking_number):
 	# Return the formatted Tracking URL.
 	tracking_url = ""
diff --git a/erpnext/erpnext_integrations/workspace/erpnext_integrations/erpnext_integrations.json b/erpnext/erpnext_integrations/workspace/erpnext_integrations/erpnext_integrations.json
index 510317f..dfef223 100644
--- a/erpnext/erpnext_integrations/workspace/erpnext_integrations/erpnext_integrations.json
+++ b/erpnext/erpnext_integrations/workspace/erpnext_integrations/erpnext_integrations.json
@@ -195,26 +195,6 @@
   {
    "hidden": 0,
    "is_query_report": 0,
-   "label": "GoCardless Settings",
-   "link_count": 0,
-   "link_to": "GoCardless Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Mpesa Settings",
-   "link_count": 0,
-   "link_to": "Mpesa Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
    "label": "Plaid Settings",
    "link_count": 0,
    "link_to": "Plaid Settings",
@@ -223,7 +203,7 @@
    "type": "Link"
   }
  ],
- "modified": "2023-08-29 15:48:59.010704",
+ "modified": "2023-10-31 19:57:32.748726",
  "modified_by": "Administrator",
  "module": "ERPNext Integrations",
  "name": "ERPNext Integrations",
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 2155699..5483a10 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -52,11 +52,7 @@
 filters_config = "erpnext.startup.filters.get_filters_config"
 additional_print_settings = "erpnext.controllers.print_settings.get_print_settings"
 
-on_session_creation = [
-	"erpnext.portal.utils.create_customer_or_supplier",
-	"erpnext.e_commerce.shopping_cart.utils.set_cart_count",
-]
-on_logout = "erpnext.e_commerce.shopping_cart.utils.clear_cart_count"
+on_session_creation = "erpnext.portal.utils.create_customer_or_supplier"
 
 treeviews = [
 	"Account",
@@ -90,15 +86,11 @@
 }
 
 # website
-update_website_context = [
-	"erpnext.e_commerce.shopping_cart.utils.update_website_context",
-]
-my_account_context = "erpnext.e_commerce.shopping_cart.utils.update_my_account_context"
 webform_list_context = "erpnext.controllers.website_list_for_contact.get_webform_list_context"
 
 calendars = ["Task", "Work Order", "Sales Order", "Holiday List", "ToDo"]
 
-website_generators = ["Item Group", "Website Item", "BOM", "Sales Partner"]
+website_generators = ["BOM", "Sales Partner"]
 
 website_context = {
 	"favicon": "/assets/erpnext/images/erpnext-favicon.svg",
@@ -349,9 +341,6 @@
 	"Event": {
 		"after_insert": "erpnext.crm.utils.link_events_with_prospect",
 	},
-	"Sales Taxes and Charges Template": {
-		"on_update": "erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings.validate_cart_settings"
-	},
 	"Sales Invoice": {
 		"on_submit": [
 			"erpnext.regional.create_transaction_log",
@@ -519,6 +508,7 @@
 	"Sales Invoice Item",
 	"Purchase Invoice Item",
 	"Purchase Order Item",
+	"Sales Order Item",
 	"Journal Entry Account",
 	"Material Request Item",
 	"Delivery Note Item",
diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py
index 32f1c36..0135a4f 100644
--- a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py
+++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py
@@ -107,7 +107,7 @@
 			allowance = flt(
 				frappe.db.get_single_value(
 					"Selling Settings" if order_doc.doctype == "Sales Order" else "Buying Settings",
-					"over_order_allowance",
+					"blanket_order_allowance",
 				)
 			)
 			for bo_name, item_data in order_data.items():
diff --git a/erpnext/manufacturing/doctype/blanket_order/test_blanket_order.py b/erpnext/manufacturing/doctype/blanket_order/test_blanket_order.py
index 58f3c95..e9fc25b 100644
--- a/erpnext/manufacturing/doctype/blanket_order/test_blanket_order.py
+++ b/erpnext/manufacturing/doctype/blanket_order/test_blanket_order.py
@@ -63,7 +63,7 @@
 		po1.currency = get_company_currency(po1.company)
 		self.assertEqual(po1.items[0].qty, (bo.items[0].qty - bo.items[0].ordered_qty))
 
-	def test_over_order_allowance(self):
+	def test_blanket_order_allowance(self):
 		# Sales Order
 		bo = make_blanket_order(blanket_order_type="Selling", quantity=100)
 
@@ -74,7 +74,7 @@
 		so.items[0].qty = 110
 		self.assertRaises(frappe.ValidationError, so.submit)
 
-		frappe.db.set_single_value("Selling Settings", "over_order_allowance", 10)
+		frappe.db.set_single_value("Selling Settings", "blanket_order_allowance", 10)
 		so.submit()
 
 		# Purchase Order
@@ -87,7 +87,7 @@
 		po.items[0].qty = 110
 		self.assertRaises(frappe.ValidationError, po.submit)
 
-		frappe.db.set_single_value("Buying Settings", "over_order_allowance", 10)
+		frappe.db.set_single_value("Buying Settings", "blanket_order_allowance", 10)
 		po.submit()
 
 
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 0231668..229f885 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -1196,12 +1196,12 @@
 def add_additional_cost(stock_entry, work_order):
 	# Add non stock items cost in the additional cost
 	stock_entry.additional_costs = []
-	expenses_included_in_valuation = frappe.get_cached_value(
-		"Company", work_order.company, "expenses_included_in_valuation"
+	default_expense_account = frappe.get_cached_value(
+		"Company", work_order.company, "default_expense_account"
 	)
 
-	add_non_stock_items_cost(stock_entry, work_order, expenses_included_in_valuation)
-	add_operations_cost(stock_entry, work_order, expenses_included_in_valuation)
+	add_non_stock_items_cost(stock_entry, work_order, default_expense_account)
+	add_operations_cost(stock_entry, work_order, default_expense_account)
 
 
 def add_non_stock_items_cost(stock_entry, work_order, expense_account):
diff --git a/erpnext/manufacturing/doctype/job_card/job_card_calendar.js b/erpnext/manufacturing/doctype/job_card/job_card_calendar.js
index f4877fd..9e32085 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card_calendar.js
+++ b/erpnext/manufacturing/doctype/job_card/job_card_calendar.js
@@ -10,8 +10,8 @@
 	},
 	gantt: {
 		field_map: {
-			"start": "started_time",
-			"end": "started_time",
+			"start": "expected_start_date",
+			"end": "expected_end_date",
 			"id": "name",
 			"title": "subject",
 			"color": "color",
diff --git a/erpnext/manufacturing/doctype/job_card/job_card_list.js b/erpnext/manufacturing/doctype/job_card/job_card_list.js
index 5d883bf..99fca95 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card_list.js
+++ b/erpnext/manufacturing/doctype/job_card/job_card_list.js
@@ -1,6 +1,6 @@
 frappe.listview_settings['Job Card'] = {
 	has_indicator_for_draft: true,
-
+	add_fields: ["expected_start_date", "expected_end_date"],
 	get_indicator: function(doc) {
 		const status_colors = {
 			"Work In Progress": "orange",
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.json b/erpnext/manufacturing/doctype/production_plan/production_plan.json
index 0d0fd5e..49386c4 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.json
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.json
@@ -36,6 +36,7 @@
   "prod_plan_references",
   "section_break_24",
   "combine_sub_items",
+  "sub_assembly_warehouse",
   "section_break_ucc4",
   "skip_available_sub_assembly_item",
   "column_break_igxl",
@@ -228,7 +229,7 @@
   },
   {
    "default": "0",
-   "description": "If enabled, the system won't create material requests for the available items.",
+   "description": "If enabled, the system will create material requests even if the stock exists in the 'Raw Materials Warehouse'.",
    "fieldname": "ignore_existing_ordered_qty",
    "fieldtype": "Check",
    "label": "Ignore Available Stock"
@@ -416,13 +417,19 @@
   {
    "fieldname": "column_break_igxl",
    "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "sub_assembly_warehouse",
+   "fieldtype": "Link",
+   "label": "Sub Assembly Warehouse",
+   "options": "Warehouse"
   }
  ],
  "icon": "fa fa-calendar",
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-07-28 13:37:43.926686",
+ "modified": "2023-11-03 14:08:11.928027",
  "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 e88b791..6b12a29 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -490,6 +490,12 @@
 				bin = frappe.get_doc("Bin", bin_name, for_update=True)
 				bin.update_reserved_qty_for_production_plan()
 
+		for d in self.sub_assembly_items:
+			if d.fg_warehouse and d.type_of_manufacturing == "In House":
+				bin_name = get_or_make_bin(d.production_item, d.fg_warehouse)
+				bin = frappe.get_doc("Bin", bin_name, for_update=True)
+				bin.update_reserved_qty_for_for_sub_assembly()
+
 	def delete_draft_work_order(self):
 		for d in frappe.get_all(
 			"Work Order", fields=["name"], filters={"docstatus": 0, "production_plan": ("=", self.name)}
@@ -809,7 +815,11 @@
 
 			bom_data = []
 
-			warehouse = row.warehouse if self.skip_available_sub_assembly_item else None
+			warehouse = (
+				(self.sub_assembly_warehouse or row.warehouse)
+				if self.skip_available_sub_assembly_item
+				else None
+			)
 			get_sub_assembly_items(row.bom_no, bom_data, row.planned_qty, self.company, warehouse=warehouse)
 			self.set_sub_assembly_items_based_on_level(row, bom_data, manufacturing_type)
 			sub_assembly_items_store.extend(bom_data)
@@ -831,7 +841,7 @@
 		for data in bom_data:
 			data.qty = data.stock_qty
 			data.production_plan_item = row.name
-			data.fg_warehouse = row.warehouse
+			data.fg_warehouse = self.sub_assembly_warehouse or row.warehouse
 			data.schedule_date = row.planned_start_date
 			data.type_of_manufacturing = manufacturing_type or (
 				"Subcontract" if data.is_sub_contracted_item else "In House"
@@ -1509,6 +1519,10 @@
 def get_materials_from_other_locations(item, warehouses, new_mr_items, company):
 	from erpnext.stock.doctype.pick_list.pick_list import get_available_item_locations
 
+	stock_uom, purchase_uom = frappe.db.get_value(
+		"Item", item.get("item_code"), ["stock_uom", "purchase_uom"]
+	)
+
 	locations = get_available_item_locations(
 		item.get("item_code"), warehouses, item.get("quantity"), company, ignore_validation=True
 	)
@@ -1519,6 +1533,10 @@
 		if required_qty <= 0:
 			return
 
+		conversion_factor = 1.0
+		if purchase_uom != stock_uom and purchase_uom == item["uom"]:
+			conversion_factor = get_uom_conversion_factor(item["item_code"], item["uom"])
+
 		new_dict = copy.deepcopy(item)
 		quantity = required_qty if d.get("qty") > required_qty else d.get("qty")
 
@@ -1531,25 +1549,14 @@
 			}
 		)
 
-		required_qty -= quantity
+		required_qty -= quantity / conversion_factor
 		new_mr_items.append(new_dict)
 
 	# raise purchase request for remaining qty
-	if required_qty:
-		stock_uom, purchase_uom = frappe.db.get_value(
-			"Item", item["item_code"], ["stock_uom", "purchase_uom"]
-		)
 
-		if purchase_uom != stock_uom and purchase_uom == item["uom"]:
-			conversion_factor = get_uom_conversion_factor(item["item_code"], item["uom"])
-			if not (conversion_factor or frappe.flags.show_qty_in_stock_uom):
-				frappe.throw(
-					_("UOM Conversion factor ({0} -> {1}) not found for item: {2}").format(
-						purchase_uom, stock_uom, item["item_code"]
-					)
-				)
-
-			required_qty = required_qty / conversion_factor
+	precision = frappe.get_precision("Material Request Plan Item", "quantity")
+	if flt(required_qty, precision) > 0:
+		required_qty = required_qty
 
 		if frappe.db.get_value("UOM", purchase_uom, "must_be_whole_number"):
 			required_qty = ceil(required_qty)
@@ -1620,26 +1627,35 @@
 	table = frappe.qb.DocType("Production Plan")
 	child = frappe.qb.DocType("Material Request Plan Item")
 
+	non_completed_production_plans = get_non_completed_production_plans()
+
 	query = (
 		frappe.qb.from_(table)
 		.inner_join(child)
 		.on(table.name == child.parent)
-		.select(Sum(child.quantity * IfNull(child.conversion_factor, 1.0)))
+		.select(Sum(child.required_bom_qty))
 		.where(
 			(table.docstatus == 1)
 			& (child.item_code == item_code)
 			& (child.warehouse == warehouse)
 			& (table.status.notin(["Completed", "Closed"]))
 		)
-	).run()
+	)
 
-	if not query:
-		return 0.0
+	if non_completed_production_plans:
+		query = query.where(table.name.isin(non_completed_production_plans))
+
+	query = query.run()
+
+	if not query or query[0][0] is None:
+		return None
 
 	reserved_qty_for_production_plan = flt(query[0][0])
 
 	reserved_qty_for_production = flt(
-		get_reserved_qty_for_production(item_code, warehouse, check_production_plan=True)
+		get_reserved_qty_for_production(
+			item_code, warehouse, non_completed_production_plans, check_production_plan=True
+		)
 	)
 
 	if reserved_qty_for_production > reserved_qty_for_production_plan:
@@ -1648,6 +1664,25 @@
 	return reserved_qty_for_production_plan - reserved_qty_for_production
 
 
+def get_non_completed_production_plans():
+	table = frappe.qb.DocType("Production Plan")
+	child = frappe.qb.DocType("Production Plan Item")
+
+	query = (
+		frappe.qb.from_(table)
+		.inner_join(child)
+		.on(table.name == child.parent)
+		.select(table.name)
+		.where(
+			(table.docstatus == 1)
+			& (table.status.notin(["Completed", "Closed"]))
+			& (child.planned_qty > child.ordered_qty)
+		)
+	).run(as_dict=True)
+
+	return list(set([d.name for d in query]))
+
+
 def get_raw_materials_of_sub_assembly_items(
 	item_details, company, bom_no, include_non_stock_items, sub_assembly_items, planned_qty=1
 ):
@@ -1710,7 +1745,10 @@
 			if not item.conversion_factor and item.purchase_uom:
 				item.conversion_factor = get_uom_conversion_factor(item.item_code, item.purchase_uom)
 
-			item_details.setdefault(item.get("item_code"), item)
+			if details := item_details.get(item.get("item_code")):
+				details.qty += item.get("qty")
+			else:
+				item_details.setdefault(item.get("item_code"), item)
 
 	return item_details
 
@@ -1752,3 +1790,29 @@
 		query = query.offset(start)
 
 	return query.run()
+
+
+def get_reserved_qty_for_sub_assembly(item_code, warehouse):
+	table = frappe.qb.DocType("Production Plan")
+	child = frappe.qb.DocType("Production Plan Sub Assembly Item")
+
+	query = (
+		frappe.qb.from_(table)
+		.inner_join(child)
+		.on(table.name == child.parent)
+		.select(Sum(child.qty - IfNull(child.wo_produced_qty, 0)))
+		.where(
+			(table.docstatus == 1)
+			& (child.production_item == item_code)
+			& (child.fg_warehouse == warehouse)
+			& (table.status.notin(["Completed", "Closed"]))
+		)
+	)
+
+	query = query.run()
+
+	if not query or query[0][0] is None:
+		return None
+
+	qty = flt(query[0][0])
+	return qty if qty > 0 else 0.0
diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
index 5292571..e9c6ee3 100644
--- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
@@ -7,6 +7,7 @@
 from erpnext.controllers.item_variant import create_variant
 from erpnext.manufacturing.doctype.production_plan.production_plan import (
 	get_items_for_material_requests,
+	get_non_completed_production_plans,
 	get_sales_orders,
 	get_warehouse_list,
 )
@@ -1041,15 +1042,112 @@
 		after_qty = flt(frappe.db.get_value("Bin", bin_name, "reserved_qty_for_production_plan"))
 
 		self.assertEqual(after_qty - before_qty, 1)
-
 		pln = frappe.get_doc("Production Plan", pln.name)
 		pln.cancel()
 
 		bin_name = get_or_make_bin("Raw Material Item 1", "_Test Warehouse - _TC")
 		after_qty = flt(frappe.db.get_value("Bin", bin_name, "reserved_qty_for_production_plan"))
 
+		pln.reload()
+		self.assertEqual(pln.docstatus, 2)
 		self.assertEqual(after_qty, before_qty)
 
+	def test_resered_qty_for_production_plan_for_work_order(self):
+		from erpnext.stock.utils import get_or_make_bin
+
+		bin_name = get_or_make_bin("Raw Material Item 1", "_Test Warehouse - _TC")
+		before_qty = flt(frappe.db.get_value("Bin", bin_name, "reserved_qty_for_production_plan"))
+
+		pln = create_production_plan(item_code="Test Production Item 1")
+
+		bin_name = get_or_make_bin("Raw Material Item 1", "_Test Warehouse - _TC")
+		after_qty = flt(frappe.db.get_value("Bin", bin_name, "reserved_qty_for_production_plan"))
+
+		self.assertEqual(after_qty - before_qty, 1)
+
+		pln.make_work_order()
+
+		work_orders = []
+		for row in frappe.get_all("Work Order", filters={"production_plan": pln.name}, fields=["name"]):
+			wo_doc = frappe.get_doc("Work Order", row.name)
+			wo_doc.source_warehouse = "_Test Warehouse - _TC"
+			wo_doc.wip_warehouse = "_Test Warehouse 1 - _TC"
+			wo_doc.fg_warehouse = "_Test Warehouse - _TC"
+			for d in wo_doc.required_items:
+				d.source_warehouse = "_Test Warehouse - _TC"
+				make_stock_entry(
+					item_code=d.item_code,
+					qty=d.required_qty,
+					rate=100,
+					target="_Test Warehouse - _TC",
+				)
+
+			wo_doc.submit()
+			work_orders.append(wo_doc)
+
+		bin_name = get_or_make_bin("Raw Material Item 1", "_Test Warehouse - _TC")
+		after_qty = flt(frappe.db.get_value("Bin", bin_name, "reserved_qty_for_production_plan"))
+
+		self.assertEqual(after_qty, before_qty)
+
+		rm_work_order = None
+		for wo_doc in work_orders:
+			for d in wo_doc.required_items:
+				if d.item_code == "Raw Material Item 1":
+					rm_work_order = wo_doc
+					break
+
+		if rm_work_order:
+			s = frappe.get_doc(make_se_from_wo(rm_work_order.name, "Material Transfer for Manufacture", 1))
+			s.submit()
+			bin_name = get_or_make_bin("Raw Material Item 1", "_Test Warehouse - _TC")
+			after_qty = flt(frappe.db.get_value("Bin", bin_name, "reserved_qty_for_production_plan"))
+
+			self.assertEqual(after_qty, before_qty)
+
+	def test_resered_qty_for_production_plan_for_less_rm_qty(self):
+		from erpnext.stock.utils import get_or_make_bin
+
+		bin_name = get_or_make_bin("Raw Material Item 1", "_Test Warehouse - _TC")
+		before_qty = flt(frappe.db.get_value("Bin", bin_name, "reserved_qty_for_production_plan"))
+
+		pln = create_production_plan(item_code="Test Production Item 1", planned_qty=10)
+
+		bin_name = get_or_make_bin("Raw Material Item 1", "_Test Warehouse - _TC")
+		after_qty = flt(frappe.db.get_value("Bin", bin_name, "reserved_qty_for_production_plan"))
+
+		self.assertEqual(after_qty - before_qty, 10)
+
+		pln.make_work_order()
+
+		plans = []
+		for row in frappe.get_all("Work Order", filters={"production_plan": pln.name}, fields=["name"]):
+			wo_doc = frappe.get_doc("Work Order", row.name)
+			wo_doc.source_warehouse = "_Test Warehouse - _TC"
+			wo_doc.wip_warehouse = "_Test Warehouse 1 - _TC"
+			wo_doc.fg_warehouse = "_Test Warehouse - _TC"
+			for d in wo_doc.required_items:
+				d.source_warehouse = "_Test Warehouse - _TC"
+				d.required_qty -= 5
+				make_stock_entry(
+					item_code=d.item_code,
+					qty=d.required_qty,
+					rate=100,
+					target="_Test Warehouse - _TC",
+				)
+
+			wo_doc.submit()
+			plans.append(pln.name)
+
+		bin_name = get_or_make_bin("Raw Material Item 1", "_Test Warehouse - _TC")
+		after_qty = flt(frappe.db.get_value("Bin", bin_name, "reserved_qty_for_production_plan"))
+
+		self.assertEqual(after_qty, before_qty)
+
+		completed_plans = get_non_completed_production_plans()
+		for plan in plans:
+			self.assertFalse(plan in completed_plans)
+
 	def test_resered_qty_for_production_plan_for_material_requests_with_multi_UOM(self):
 		from erpnext.stock.utils import get_or_make_bin
 
@@ -1177,6 +1275,178 @@
 			if row.item_code == "SubAssembly2 For SUB Test":
 				self.assertEqual(row.quantity, 10)
 
+	def test_transfer_and_purchase_mrp_for_purchase_uom(self):
+		from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
+		from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
+
+		bom_tree = {
+			"Test FG Item INK PEN": {
+				"Test RM Item INK": {},
+			}
+		}
+
+		parent_bom = create_nested_bom(bom_tree, prefix="")
+		if not frappe.db.exists("UOM Conversion Detail", {"parent": "Test RM Item INK", "uom": "Kg"}):
+			doc = frappe.get_doc("Item", "Test RM Item INK")
+			doc.purchase_uom = "Kg"
+			doc.append("uoms", {"uom": "Kg", "conversion_factor": 0.5})
+			doc.save()
+
+		wh1 = create_warehouse("PNE Warehouse", company="_Test Company")
+		wh2 = create_warehouse("MBE Warehouse", company="_Test Company")
+		mrp_warhouse = create_warehouse("MRPBE Warehouse", company="_Test Company")
+
+		make_stock_entry(
+			item_code="Test RM Item INK",
+			qty=2,
+			rate=100,
+			target=wh1,
+		)
+
+		make_stock_entry(
+			item_code="Test RM Item INK",
+			qty=2,
+			rate=100,
+			target=wh2,
+		)
+
+		plan = create_production_plan(
+			item_code=parent_bom.item,
+			planned_qty=10,
+			do_not_submit=1,
+			warehouse="_Test Warehouse - _TC",
+		)
+
+		plan.for_warehouse = mrp_warhouse
+
+		items = get_items_for_material_requests(
+			plan.as_dict(), warehouses=[{"warehouse": wh1}, {"warehouse": wh2}]
+		)
+
+		for row in items:
+			row = frappe._dict(row)
+			if row.material_request_type == "Material Transfer":
+				self.assertTrue(row.from_warehouse in [wh1, wh2])
+				self.assertEqual(row.quantity, 2)
+
+			if row.material_request_type == "Purchase":
+				self.assertTrue(row.warehouse == mrp_warhouse)
+				self.assertEqual(row.quantity, 12)
+
+	def test_mr_qty_for_same_rm_with_different_sub_assemblies(self):
+		from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
+
+		bom_tree = {
+			"Fininshed Goods2 For SUB Test": {
+				"SubAssembly2 For SUB Test": {"ChildPart2 For SUB Test": {}},
+				"SubAssembly3 For SUB Test": {"ChildPart2 For SUB Test": {}},
+			}
+		}
+
+		parent_bom = create_nested_bom(bom_tree, prefix="")
+		plan = create_production_plan(
+			item_code=parent_bom.item,
+			planned_qty=1,
+			ignore_existing_ordered_qty=1,
+			do_not_submit=1,
+			skip_available_sub_assembly_item=1,
+			warehouse="_Test Warehouse - _TC",
+		)
+
+		plan.get_sub_assembly_items()
+		plan.make_material_request()
+
+		for row in plan.mr_items:
+			if row.item_code == "ChildPart2 For SUB Test":
+				self.assertEqual(row.quantity, 2)
+
+	def test_reserve_sub_assembly_items(self):
+		from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
+		from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
+
+		bom_tree = {
+			"Fininshed Goods Bicycle": {
+				"Frame Assembly": {"Frame": {}},
+				"Chain Assembly": {"Chain": {}},
+			}
+		}
+		parent_bom = create_nested_bom(bom_tree, prefix="")
+
+		warehouse = "_Test Warehouse - _TC"
+		company = "_Test Company"
+
+		sub_assembly_warehouse = create_warehouse("SUB ASSEMBLY WH", company=company)
+
+		for item_code in ["Frame", "Chain"]:
+			make_stock_entry(item_code=item_code, target=warehouse, qty=2, basic_rate=100)
+
+		before_qty = flt(
+			frappe.db.get_value(
+				"Bin",
+				{"item_code": "Frame Assembly", "warehouse": sub_assembly_warehouse},
+				"reserved_qty_for_production_plan",
+			)
+		)
+
+		plan = create_production_plan(
+			item_code=parent_bom.item,
+			planned_qty=2,
+			ignore_existing_ordered_qty=1,
+			do_not_submit=1,
+			skip_available_sub_assembly_item=1,
+			warehouse=warehouse,
+			sub_assembly_warehouse=sub_assembly_warehouse,
+		)
+
+		plan.get_sub_assembly_items()
+		plan.submit()
+
+		after_qty = flt(
+			frappe.db.get_value(
+				"Bin",
+				{"item_code": "Frame Assembly", "warehouse": sub_assembly_warehouse},
+				"reserved_qty_for_production_plan",
+			)
+		)
+
+		self.assertEqual(after_qty, before_qty + 2)
+
+		plan.make_work_order()
+		work_orders = frappe.get_all(
+			"Work Order",
+			fields=["name", "production_item"],
+			filters={"production_plan": plan.name},
+			order_by="creation desc",
+		)
+
+		for d in work_orders:
+			wo_doc = frappe.get_doc("Work Order", d.name)
+			wo_doc.skip_transfer = 1
+			wo_doc.from_wip_warehouse = 1
+
+			wo_doc.wip_warehouse = (
+				warehouse
+				if d.production_item in ["Frame Assembly", "Chain Assembly"]
+				else sub_assembly_warehouse
+			)
+
+			wo_doc.submit()
+
+			if d.production_item == "Frame Assembly":
+				self.assertEqual(wo_doc.fg_warehouse, sub_assembly_warehouse)
+				se_doc = frappe.get_doc(make_se_from_wo(wo_doc.name, "Manufacture", 2))
+				se_doc.submit()
+
+		after_qty = flt(
+			frappe.db.get_value(
+				"Bin",
+				{"item_code": "Frame Assembly", "warehouse": sub_assembly_warehouse},
+				"reserved_qty_for_production_plan",
+			)
+		)
+
+		self.assertEqual(after_qty, before_qty)
+
 
 def create_production_plan(**args):
 	"""
@@ -1197,6 +1467,7 @@
 			"ignore_existing_ordered_qty": args.ignore_existing_ordered_qty or 0,
 			"get_items_from": "Sales Order",
 			"skip_available_sub_assembly_item": args.skip_available_sub_assembly_item or 0,
+			"sub_assembly_warehouse": args.sub_assembly_warehouse,
 		}
 	)
 
diff --git a/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json b/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json
index fde0404..aff740b 100644
--- a/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json
+++ b/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json
@@ -17,11 +17,10 @@
   "type_of_manufacturing",
   "supplier",
   "work_order_details_section",
-  "work_order",
+  "wo_produced_qty",
   "purchase_order",
   "production_plan_item",
   "column_break_7",
-  "produced_qty",
   "received_qty",
   "indent",
   "section_break_19",
@@ -53,13 +52,6 @@
    "label": "Reference"
   },
   {
-   "fieldname": "work_order",
-   "fieldtype": "Link",
-   "label": "Work Order",
-   "options": "Work Order",
-   "read_only": 1
-  },
-  {
    "fieldname": "column_break_7",
    "fieldtype": "Column Break"
   },
@@ -81,7 +73,8 @@
   {
    "fieldname": "received_qty",
    "fieldtype": "Float",
-   "label": "Received Qty"
+   "label": "Received Qty",
+   "read_only": 1
   },
   {
    "fieldname": "bom_no",
@@ -162,12 +155,6 @@
    "options": "Warehouse"
   },
   {
-   "fieldname": "produced_qty",
-   "fieldtype": "Data",
-   "label": "Produced Quantity",
-   "read_only": 1
-  },
-  {
    "default": "In House",
    "fieldname": "type_of_manufacturing",
    "fieldtype": "Select",
@@ -209,12 +196,18 @@
    "label": "Projected Qty",
    "no_copy": 1,
    "read_only": 1
+  },
+  {
+   "fieldname": "wo_produced_qty",
+   "fieldtype": "Float",
+   "label": "Produced Qty",
+   "read_only": 1
   }
  ],
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-05-22 17:52:34.708879",
+ "modified": "2023-11-03 13:33:42.959387",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Production Plan Sub Assembly Item",
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index c828c87..0ae7657 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -494,6 +494,7 @@
 						"from_time": row.from_time,
 						"to_time": row.to_time,
 						"time_in_mins": row.time_in_mins,
+						"completed_qty": 0,
 					},
 				)
 
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index 5ad79f9..36a0cae 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -293,6 +293,7 @@
 				update_produced_qty_in_so_item(self.sales_order, self.sales_order_item)
 
 		if self.production_plan:
+			self.set_produced_qty_for_sub_assembly_item()
 			self.update_production_plan_status()
 
 	def get_transferred_or_manufactured_qty(self, purpose):
@@ -358,10 +359,10 @@
 		else:
 			self.update_work_order_qty_in_so()
 
+		self.update_ordered_qty()
 		self.update_reserved_qty_for_production()
 		self.update_completed_qty_in_material_request()
 		self.update_planned_qty()
-		self.update_ordered_qty()
 		self.create_job_card()
 
 	def on_cancel(self):
@@ -569,16 +570,49 @@
 			)
 
 	def update_planned_qty(self):
+		from erpnext.manufacturing.doctype.production_plan.production_plan import (
+			get_reserved_qty_for_sub_assembly,
+		)
+
+		qty_dict = {"planned_qty": get_planned_qty(self.production_item, self.fg_warehouse)}
+
+		if self.production_plan_sub_assembly_item and self.production_plan:
+			qty_dict["reserved_qty_for_production_plan"] = get_reserved_qty_for_sub_assembly(
+				self.production_item, self.fg_warehouse
+			)
+
 		update_bin_qty(
 			self.production_item,
 			self.fg_warehouse,
-			{"planned_qty": get_planned_qty(self.production_item, self.fg_warehouse)},
+			qty_dict,
 		)
 
 		if self.material_request:
 			mr_obj = frappe.get_doc("Material Request", self.material_request)
 			mr_obj.update_requested_qty([self.material_request_item])
 
+	def set_produced_qty_for_sub_assembly_item(self):
+		table = frappe.qb.DocType("Work Order")
+
+		query = (
+			frappe.qb.from_(table)
+			.select(Sum(table.produced_qty))
+			.where(
+				(table.production_plan == self.production_plan)
+				& (table.production_plan_sub_assembly_item == self.production_plan_sub_assembly_item)
+				& (table.docstatus == 1)
+			)
+		).run()
+
+		produced_qty = flt(query[0][0]) if query else 0
+
+		frappe.db.set_value(
+			"Production Plan Sub Assembly Item",
+			self.production_plan_sub_assembly_item,
+			"wo_produced_qty",
+			produced_qty,
+		)
+
 	def update_ordered_qty(self):
 		if (
 			self.production_plan
@@ -1513,37 +1547,47 @@
 
 
 def get_reserved_qty_for_production(
-	item_code: str, warehouse: str, check_production_plan: bool = False
+	item_code: str,
+	warehouse: str,
+	non_completed_production_plans: list = None,
+	check_production_plan: bool = False,
 ) -> float:
 	"""Get total reserved quantity for any item in specified warehouse"""
 	wo = frappe.qb.DocType("Work Order")
 	wo_item = frappe.qb.DocType("Work Order Item")
 
+	if check_production_plan:
+		qty_field = wo_item.required_qty
+	else:
+		qty_field = Case()
+		qty_field = qty_field.when(wo.skip_transfer == 0, wo_item.required_qty - wo_item.transferred_qty)
+		qty_field = qty_field.else_(wo_item.required_qty - wo_item.consumed_qty)
+
 	query = (
 		frappe.qb.from_(wo)
 		.from_(wo_item)
-		.select(
-			Sum(
-				Case()
-				.when(wo.skip_transfer == 0, wo_item.required_qty - wo_item.transferred_qty)
-				.else_(wo_item.required_qty - wo_item.consumed_qty)
-			)
-		)
+		.select(Sum(qty_field))
 		.where(
 			(wo_item.item_code == item_code)
 			& (wo_item.parent == wo.name)
 			& (wo.docstatus == 1)
 			& (wo_item.source_warehouse == warehouse)
-			& (wo.status.notin(["Stopped", "Completed", "Closed"]))
-			& (
-				(wo_item.required_qty > wo_item.transferred_qty)
-				| (wo_item.required_qty > wo_item.consumed_qty)
-			)
 		)
 	)
 
 	if check_production_plan:
 		query = query.where(wo.production_plan.isnotnull())
+	else:
+		query = query.where(
+			(wo.status.notin(["Stopped", "Completed", "Closed"]))
+			& (
+				(wo_item.required_qty > wo_item.transferred_qty)
+				| (wo_item.required_qty > wo_item.consumed_qty)
+			)
+		)
+
+	if non_completed_production_plans:
+		query = query.where(wo.production_plan.isin(non_completed_production_plans))
 
 	return query.run()[0][0] or 0.0
 
diff --git a/erpnext/manufacturing/report/bom_operations_time/bom_operations_time.js b/erpnext/manufacturing/report/bom_operations_time/bom_operations_time.js
index 34edb9d..8729775 100644
--- a/erpnext/manufacturing/report/bom_operations_time/bom_operations_time.js
+++ b/erpnext/manufacturing/report/bom_operations_time/bom_operations_time.js
@@ -12,7 +12,7 @@
 			"options": "Item",
 			"get_query": () =>{
 				return {
-					filters: { "disabled": 0, "is_stock_item": 1 }
+					filters: { "is_stock_item": 1 }
 				}
 			}
 		},
diff --git a/erpnext/modules.txt b/erpnext/modules.txt
index dcb4212..c53cdf4 100644
--- a/erpnext/modules.txt
+++ b/erpnext/modules.txt
@@ -17,5 +17,4 @@
 Communication
 Telephony
 Bulk Transaction
-E-commerce
-Subcontracting
\ No newline at end of file
+Subcontracting
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index e9c056e..e0f32c5 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -223,9 +223,6 @@
 erpnext.patches.v13_0.set_operation_time_based_on_operating_cost
 erpnext.patches.v13_0.create_gst_payment_entry_fields #27-11-2021
 erpnext.patches.v13_0.fix_invoice_statuses
-erpnext.patches.v13_0.create_website_items #30-09-2021
-erpnext.patches.v13_0.populate_e_commerce_settings
-erpnext.patches.v13_0.make_homepage_products_website_items
 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
@@ -242,7 +239,6 @@
 erpnext.patches.v13_0.healthcare_deprecation_warning
 erpnext.patches.v13_0.item_naming_series_not_mandatory
 erpnext.patches.v13_0.update_category_in_ltds_certificate
-erpnext.patches.v13_0.fetch_thumbnail_in_website_items
 erpnext.patches.v13_0.update_maintenance_schedule_field_in_visit
 erpnext.patches.v14_0.migrate_crm_settings
 erpnext.patches.v13_0.wipe_serial_no_field_for_0_qty
@@ -257,6 +253,7 @@
 erpnext.patches.v13_0.reset_corrupt_defaults
 erpnext.patches.v13_0.create_accounting_dimensions_for_asset_repair
 erpnext.patches.v15_0.delete_taxjar_doctypes
+erpnext.patches.v15_0.delete_ecommerce_doctypes
 erpnext.patches.v15_0.create_asset_depreciation_schedules_from_assets
 erpnext.patches.v14_0.update_reference_due_date_in_journal_entry
 erpnext.patches.v15_0.saudi_depreciation_warning
@@ -277,8 +274,6 @@
 erpnext.patches.v14_0.rearrange_company_fields
 erpnext.patches.v13_0.update_sane_transfer_against
 erpnext.patches.v14_0.migrate_cost_center_allocations
-erpnext.patches.v13_0.convert_to_website_item_in_item_card_group_template
-erpnext.patches.v13_0.shopping_cart_to_ecommerce
 erpnext.patches.v13_0.update_reserved_qty_closed_wo
 erpnext.patches.v13_0.update_exchange_rate_settings
 erpnext.patches.v14_0.delete_amazon_mws_doctype
@@ -288,7 +283,6 @@
 erpnext.patches.v14_0.delete_non_profit_doctypes
 erpnext.patches.v13_0.set_return_against_in_pos_invoice_references
 erpnext.patches.v13_0.remove_unknown_links_to_prod_plan_items # 24-03-2022
-erpnext.patches.v13_0.copy_custom_field_filters_to_website_item
 erpnext.patches.v13_0.change_default_item_manufacturer_fieldtype
 erpnext.patches.v13_0.requeue_recoverable_reposts
 erpnext.patches.v14_0.discount_accounting_separation
@@ -322,7 +316,7 @@
 execute:frappe.db.set_single_value("Accounts Settings", "merge_similar_account_heads", 0)
 erpnext.patches.v14_0.update_reference_type_in_journal_entry_accounts
 erpnext.patches.v14_0.update_subscription_details
-execute:frappe.delete_doc_if_exists("Report", "Tax Detail")
+execute:frappe.delete_doc("Report", "Tax Detail", force=True)
 erpnext.patches.v15_0.enable_all_leads
 erpnext.patches.v14_0.update_company_in_ldc
 erpnext.patches.v14_0.set_packed_qty_in_draft_delivery_notes
@@ -344,5 +338,15 @@
 erpnext.patches.v14_0.migrate_deferred_accounts_to_item_defaults
 erpnext.patches.v14_0.update_invoicing_period_in_subscription
 execute:frappe.delete_doc("Page", "welcome-to-erpnext")
+erpnext.patches.v15_0.delete_payment_gateway_doctypes
+erpnext.patches.v14_0.create_accounting_dimensions_in_sales_order_item
+erpnext.patches.v15_0.update_sre_from_voucher_details
+erpnext.patches.v14_0.rename_over_order_allowance_field
+erpnext.patches.v14_0.migrate_delivery_stop_lock_field
+execute:frappe.db.set_single_value("Payment Reconciliation", "invoice_limit", 50)
+execute:frappe.db.set_single_value("Payment Reconciliation", "payment_limit", 50)
+erpnext.patches.v15_0.rename_daily_depreciation_to_depreciation_amount_based_on_num_days_in_month
+erpnext.patches.v15_0.rename_depreciation_amount_based_on_num_days_in_month_to_daily_prorata_based
+erpnext.patches.v15_0.set_reserved_stock_in_bin
 # below migration patch should always run last
 erpnext.patches.v14_0.migrate_gl_to_payment_ledger
diff --git a/erpnext/patches/v12_0/set_expense_account_in_landed_cost_voucher_taxes.py b/erpnext/patches/v12_0/set_expense_account_in_landed_cost_voucher_taxes.py
deleted file mode 100644
index 9588e02..0000000
--- a/erpnext/patches/v12_0/set_expense_account_in_landed_cost_voucher_taxes.py
+++ /dev/null
@@ -1,42 +0,0 @@
-import frappe
-
-
-def execute():
-	frappe.reload_doctype("Landed Cost Taxes and Charges")
-
-	company_account_map = frappe._dict(
-		frappe.db.sql(
-			"""
-		SELECT name, expenses_included_in_valuation from `tabCompany`
-	"""
-		)
-	)
-
-	for company, account in company_account_map.items():
-		frappe.db.sql(
-			"""
-			UPDATE
-				`tabLanded Cost Taxes and Charges` t, `tabLanded Cost Voucher` l
-			SET
-				t.expense_account = %s
-			WHERE
-				l.docstatus = 1
-				AND l.company = %s
-				AND t.parent = l.name
-		""",
-			(account, company),
-		)
-
-		frappe.db.sql(
-			"""
-			UPDATE
-				`tabLanded Cost Taxes and Charges` t, `tabStock Entry` s
-			SET
-				t.expense_account = %s
-			WHERE
-				s.docstatus = 1
-				AND s.company = %s
-				AND t.parent = s.name
-		""",
-			(account, company),
-		)
diff --git a/erpnext/patches/v13_0/convert_qi_parameter_to_link_field.py b/erpnext/patches/v13_0/convert_qi_parameter_to_link_field.py
index efbb96c..e53bdf8 100644
--- a/erpnext/patches/v13_0/convert_qi_parameter_to_link_field.py
+++ b/erpnext/patches/v13_0/convert_qi_parameter_to_link_field.py
@@ -3,23 +3,24 @@
 
 def execute():
 	frappe.reload_doc("stock", "doctype", "quality_inspection_parameter")
+	params = set()
 
-	# get all distinct parameters from QI readigs table
-	reading_params = frappe.db.get_all(
-		"Quality Inspection Reading", fields=["distinct specification"]
-	)
-	reading_params = [d.specification for d in reading_params]
+	# get all parameters from QI readings table
+	for (p,) in frappe.db.get_all(
+		"Quality Inspection Reading", fields=["specification"], as_list=True
+	):
+		params.add(p.strip())
 
-	# get all distinct parameters from QI Template as some may be unused in QI
-	template_params = frappe.db.get_all(
-		"Item Quality Inspection Parameter", fields=["distinct specification"]
-	)
-	template_params = [d.specification for d in template_params]
+	# get all parameters from QI Template as some may be unused in QI
+	for (p,) in frappe.db.get_all(
+		"Item Quality Inspection Parameter", fields=["specification"], as_list=True
+	):
+		params.add(p.strip())
 
-	params = list(set(reading_params + template_params))
+	# because db primary keys are case insensitive, so duplicates will cause an exception
+	params = set({x.casefold(): x for x in params}.values())
 
 	for parameter in params:
-		if not frappe.db.exists("Quality Inspection Parameter", parameter):
-			frappe.get_doc(
-				{"doctype": "Quality Inspection Parameter", "parameter": parameter, "description": parameter}
-			).insert(ignore_permissions=True)
+		frappe.get_doc(
+			{"doctype": "Quality Inspection Parameter", "parameter": parameter, "description": parameter}
+		).insert(ignore_permissions=True)
diff --git a/erpnext/patches/v13_0/convert_to_website_item_in_item_card_group_template.py b/erpnext/patches/v13_0/convert_to_website_item_in_item_card_group_template.py
deleted file mode 100644
index 1bac0fd..0000000
--- a/erpnext/patches/v13_0/convert_to_website_item_in_item_card_group_template.py
+++ /dev/null
@@ -1,60 +0,0 @@
-import json
-from typing import List, Union
-
-import frappe
-
-from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
-
-
-def execute():
-	"""
-	Convert all Item links to Website Item link values in
-	exisitng 'Item Card Group' Web Page Block data.
-	"""
-	frappe.reload_doc("e_commerce", "web_template", "item_card_group")
-
-	blocks = frappe.db.get_all(
-		"Web Page Block",
-		filters={"web_template": "Item Card Group"},
-		fields=["parent", "web_template_values", "name"],
-	)
-
-	fields = generate_fields_to_edit()
-
-	for block in blocks:
-		web_template_value = json.loads(block.get("web_template_values"))
-
-		for field in fields:
-			item = web_template_value.get(field)
-			if not item:
-				continue
-
-			if frappe.db.exists("Website Item", {"item_code": item}):
-				website_item = frappe.db.get_value("Website Item", {"item_code": item})
-			else:
-				website_item = make_new_website_item(item)
-
-			if website_item:
-				web_template_value[field] = website_item
-
-		frappe.db.set_value(
-			"Web Page Block", block.name, "web_template_values", json.dumps(web_template_value)
-		)
-
-
-def generate_fields_to_edit() -> List:
-	fields = []
-	for i in range(1, 13):
-		fields.append(f"card_{i}_item")  # fields like 'card_1_item', etc.
-
-	return fields
-
-
-def make_new_website_item(item: str) -> Union[str, None]:
-	try:
-		doc = frappe.get_doc("Item", item)
-		web_item = make_website_item(doc)  # returns [website_item.name, item_name]
-		return web_item[0]
-	except Exception:
-		doc.log_error("Website Item creation failed")
-		return None
diff --git a/erpnext/patches/v13_0/copy_custom_field_filters_to_website_item.py b/erpnext/patches/v13_0/copy_custom_field_filters_to_website_item.py
deleted file mode 100644
index 4ad572f..0000000
--- a/erpnext/patches/v13_0/copy_custom_field_filters_to_website_item.py
+++ /dev/null
@@ -1,94 +0,0 @@
-import frappe
-from frappe.custom.doctype.custom_field.custom_field import create_custom_field
-
-
-def execute():
-	"Add Field Filters, that are not standard fields in Website Item, as Custom Fields."
-
-	def move_table_multiselect_data(docfield):
-		"Copy child table data (Table Multiselect) from Item to Website Item for a docfield."
-		table_multiselect_data = get_table_multiselect_data(docfield)
-		field = docfield.fieldname
-
-		for row in table_multiselect_data:
-			# add copied multiselect data rows in Website Item
-			web_item = frappe.db.get_value("Website Item", {"item_code": row.parent})
-			web_item_doc = frappe.get_doc("Website Item", web_item)
-
-			child_doc = frappe.new_doc(docfield.options, parent_doc=web_item_doc, parentfield=field)
-
-			for field in ["name", "creation", "modified", "idx"]:
-				row[field] = None
-
-			child_doc.update(row)
-
-			child_doc.parenttype = "Website Item"
-			child_doc.parent = web_item
-
-			child_doc.insert()
-
-	def get_table_multiselect_data(docfield):
-		child_table = frappe.qb.DocType(docfield.options)
-		item = frappe.qb.DocType("Item")
-
-		table_multiselect_data = (  # query table data for field
-			frappe.qb.from_(child_table)
-			.join(item)
-			.on(item.item_code == child_table.parent)
-			.select(child_table.star)
-			.where((child_table.parentfield == docfield.fieldname) & (item.published_in_website == 1))
-		).run(as_dict=True)
-
-		return table_multiselect_data
-
-	settings = frappe.get_doc("E Commerce Settings")
-
-	if not (settings.enable_field_filters or settings.filter_fields):
-		return
-
-	item_meta = frappe.get_meta("Item")
-	valid_item_fields = [
-		df.fieldname for df in item_meta.fields if df.fieldtype in ["Link", "Table MultiSelect"]
-	]
-
-	web_item_meta = frappe.get_meta("Website Item")
-	valid_web_item_fields = [
-		df.fieldname for df in web_item_meta.fields if df.fieldtype in ["Link", "Table MultiSelect"]
-	]
-
-	for row in settings.filter_fields:
-		# skip if illegal field
-		if row.fieldname not in valid_item_fields:
-			continue
-
-		# if Item field is not in Website Item, add it as a custom field
-		if row.fieldname not in valid_web_item_fields:
-			df = item_meta.get_field(row.fieldname)
-			create_custom_field(
-				"Website Item",
-				dict(
-					owner="Administrator",
-					fieldname=df.fieldname,
-					label=df.label,
-					fieldtype=df.fieldtype,
-					options=df.options,
-					description=df.description,
-					read_only=df.read_only,
-					no_copy=df.no_copy,
-					insert_after="on_backorder",
-				),
-			)
-
-			# map field values
-			if df.fieldtype == "Table MultiSelect":
-				move_table_multiselect_data(df)
-			else:
-				frappe.db.sql(  # nosemgrep
-					"""
-						UPDATE `tabWebsite Item` wi, `tabItem` i
-						SET wi.{0} = i.{0}
-						WHERE wi.item_code = i.item_code
-					""".format(
-						row.fieldname
-					)
-				)
diff --git a/erpnext/patches/v13_0/create_website_items.py b/erpnext/patches/v13_0/create_website_items.py
deleted file mode 100644
index b010f0e..0000000
--- a/erpnext/patches/v13_0/create_website_items.py
+++ /dev/null
@@ -1,85 +0,0 @@
-import frappe
-
-from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
-
-
-def execute():
-	frappe.reload_doc("e_commerce", "doctype", "website_item")
-	frappe.reload_doc("e_commerce", "doctype", "website_item_tabbed_section")
-	frappe.reload_doc("e_commerce", "doctype", "website_offer")
-	frappe.reload_doc("e_commerce", "doctype", "recommended_items")
-	frappe.reload_doc("e_commerce", "doctype", "e_commerce_settings")
-	frappe.reload_doc("stock", "doctype", "item")
-
-	item_fields = [
-		"item_code",
-		"item_name",
-		"item_group",
-		"stock_uom",
-		"brand",
-		"has_variants",
-		"variant_of",
-		"description",
-		"weightage",
-	]
-	web_fields_to_map = [
-		"route",
-		"slideshow",
-		"website_image_alt",
-		"website_warehouse",
-		"web_long_description",
-		"website_content",
-		"website_image",
-		"thumbnail",
-	]
-
-	# get all valid columns (fields) from Item master DB schema
-	item_table_fields = frappe.db.sql("desc `tabItem`", as_dict=1)  # nosemgrep
-	item_table_fields = [d.get("Field") for d in item_table_fields]
-
-	# prepare fields to query from Item, check if the web field exists in Item master
-	web_query_fields = []
-	for web_field in web_fields_to_map:
-		if web_field in item_table_fields:
-			web_query_fields.append(web_field)
-			item_fields.append(web_field)
-
-	# check if the filter fields exist in Item master
-	or_filters = {}
-	for field in ["show_in_website", "show_variant_in_website"]:
-		if field in item_table_fields:
-			or_filters[field] = 1
-
-	if not web_query_fields or not or_filters:
-		# web fields to map are not present in Item master schema
-		# most likely a fresh installation that doesnt need this patch
-		return
-
-	items = frappe.db.get_all("Item", fields=item_fields, or_filters=or_filters)
-	total_count = len(items)
-
-	for count, item in enumerate(items, start=1):
-		if frappe.db.exists("Website Item", {"item_code": item.item_code}):
-			continue
-
-		# make new website item from item (publish item)
-		website_item = make_website_item(item, save=False)
-		website_item.ranking = item.get("weightage")
-
-		for field in web_fields_to_map:
-			website_item.update({field: item.get(field)})
-
-		website_item.save()
-
-		# move Website Item Group & Website Specification table to Website Item
-		for doctype in ("Website Item Group", "Item Website Specification"):
-			frappe.db.set_value(
-				doctype,
-				{"parenttype": "Item", "parent": item.item_code},  # filters
-				{"parenttype": "Website Item", "parent": website_item.name},  # value dict
-			)
-
-		if count % 20 == 0:  # commit after every 20 items
-			frappe.db.commit()
-
-		frappe.utils.update_progress_bar("Creating Website Items", count, total_count)
diff --git a/erpnext/patches/v13_0/fetch_thumbnail_in_website_items.py b/erpnext/patches/v13_0/fetch_thumbnail_in_website_items.py
deleted file mode 100644
index 9197d86..0000000
--- a/erpnext/patches/v13_0/fetch_thumbnail_in_website_items.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import frappe
-
-
-def execute():
-	if frappe.db.has_column("Item", "thumbnail"):
-		website_item = frappe.qb.DocType("Website Item").as_("wi")
-		item = frappe.qb.DocType("Item")
-
-		frappe.qb.update(website_item).inner_join(item).on(website_item.item_code == item.item_code).set(
-			website_item.thumbnail, item.thumbnail
-		).where(website_item.website_image.notnull() & website_item.thumbnail.isnull()).run()
diff --git a/erpnext/patches/v13_0/make_homepage_products_website_items.py b/erpnext/patches/v13_0/make_homepage_products_website_items.py
deleted file mode 100644
index 50bfd35..0000000
--- a/erpnext/patches/v13_0/make_homepage_products_website_items.py
+++ /dev/null
@@ -1,15 +0,0 @@
-import frappe
-
-
-def execute():
-	homepage = frappe.get_doc("Homepage")
-
-	for row in homepage.products:
-		web_item = frappe.db.get_value("Website Item", {"item_code": row.item_code}, "name")
-		if not web_item:
-			continue
-
-		row.item_code = web_item
-
-	homepage.flags.ignore_mandatory = True
-	homepage.save()
diff --git a/erpnext/patches/v13_0/populate_e_commerce_settings.py b/erpnext/patches/v13_0/populate_e_commerce_settings.py
deleted file mode 100644
index ecf512b..0000000
--- a/erpnext/patches/v13_0/populate_e_commerce_settings.py
+++ /dev/null
@@ -1,68 +0,0 @@
-import frappe
-from frappe.utils import cint
-
-
-def execute():
-	frappe.reload_doc("e_commerce", "doctype", "e_commerce_settings")
-	frappe.reload_doc("portal", "doctype", "website_filter_field")
-	frappe.reload_doc("portal", "doctype", "website_attribute")
-
-	products_settings_fields = [
-		"hide_variants",
-		"products_per_page",
-		"enable_attribute_filters",
-		"enable_field_filters",
-	]
-
-	shopping_cart_settings_fields = [
-		"enabled",
-		"show_attachments",
-		"show_price",
-		"show_stock_availability",
-		"enable_variants",
-		"show_contact_us_button",
-		"show_quantity_in_website",
-		"show_apply_coupon_code_in_website",
-		"allow_items_not_in_stock",
-		"company",
-		"price_list",
-		"default_customer_group",
-		"quotation_series",
-		"enable_checkout",
-		"payment_success_url",
-		"payment_gateway_account",
-		"save_quotations_as_draft",
-	]
-
-	settings = frappe.get_doc("E Commerce Settings")
-
-	def map_into_e_commerce_settings(doctype, fields):
-		singles = frappe.qb.DocType("Singles")
-		query = (
-			frappe.qb.from_(singles)
-			.select(singles["field"], singles.value)
-			.where((singles.doctype == doctype) & (singles["field"].isin(fields)))
-		)
-		data = query.run(as_dict=True)
-
-		# {'enable_attribute_filters': '1', ...}
-		mapper = {row.field: row.value for row in data}
-
-		for key, value in mapper.items():
-			value = cint(value) if (value and value.isdigit()) else value
-			settings.update({key: value})
-
-		settings.save()
-
-	# shift data to E Commerce Settings
-	map_into_e_commerce_settings("Products Settings", products_settings_fields)
-	map_into_e_commerce_settings("Shopping Cart Settings", shopping_cart_settings_fields)
-
-	# move filters and attributes tables to E Commerce Settings from Products Settings
-	for doctype in ("Website Filter Field", "Website Attribute"):
-		frappe.db.set_value(
-			doctype,
-			{"parent": "Products Settings"},
-			{"parenttype": "E Commerce Settings", "parent": "E Commerce Settings"},
-			update_modified=False,
-		)
diff --git a/erpnext/patches/v13_0/shopping_cart_to_ecommerce.py b/erpnext/patches/v13_0/shopping_cart_to_ecommerce.py
deleted file mode 100644
index 35710a9..0000000
--- a/erpnext/patches/v13_0/shopping_cart_to_ecommerce.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import click
-import frappe
-
-
-def execute():
-
-	frappe.delete_doc("DocType", "Shopping Cart Settings", ignore_missing=True)
-	frappe.delete_doc("DocType", "Products Settings", ignore_missing=True)
-	frappe.delete_doc("DocType", "Supplier Item Group", ignore_missing=True)
-
-	if frappe.db.get_single_value("E Commerce Settings", "enabled"):
-		notify_users()
-
-
-def notify_users():
-
-	click.secho(
-		"Shopping cart and Product settings are merged into E-commerce settings.\n"
-		"Checkout the documentation to learn more:"
-		"https://docs.erpnext.com/docs/v13/user/manual/en/e_commerce/set_up_e_commerce",
-		fg="yellow",
-	)
-
-	note = frappe.new_doc("Note")
-	note.title = "New E-Commerce Module"
-	note.public = 1
-	note.notify_on_login = 1
-	note.content = """<div class="ql-editor read-mode"><p>You are seeing this message because Shopping Cart is enabled on your site. </p><p><br></p><p>Shopping Cart Settings and Products settings are now merged into "E Commerce Settings". </p><p><br></p><p>You can learn about new and improved E-Commerce features in the official documentation.</p><ol><li data-list="bullet"><span class="ql-ui" contenteditable="false"></span><a href="https://docs.erpnext.com/docs/v13/user/manual/en/e_commerce/set_up_e_commerce" rel="noopener noreferrer">https://docs.erpnext.com/docs/v13/user/manual/en/e_commerce/set_up_e_commerce</a></li></ol><p><br></p></div>"""
-	note.insert(ignore_mandatory=True)
diff --git a/erpnext/patches/v14_0/create_accounting_dimensions_in_sales_order_item.py b/erpnext/patches/v14_0/create_accounting_dimensions_in_sales_order_item.py
new file mode 100644
index 0000000..8f77c35
--- /dev/null
+++ b/erpnext/patches/v14_0/create_accounting_dimensions_in_sales_order_item.py
@@ -0,0 +1,7 @@
+from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
+	create_accounting_dimensions_for_doctype,
+)
+
+
+def execute():
+	create_accounting_dimensions_for_doctype(doctype="Sales Order Item")
diff --git a/erpnext/patches/v14_0/migrate_delivery_stop_lock_field.py b/erpnext/patches/v14_0/migrate_delivery_stop_lock_field.py
new file mode 100644
index 0000000..c9ec1e1
--- /dev/null
+++ b/erpnext/patches/v14_0/migrate_delivery_stop_lock_field.py
@@ -0,0 +1,7 @@
+import frappe
+from frappe.model.utils.rename_field import rename_field
+
+
+def execute():
+	if frappe.db.has_column("Delivery Stop", "lock"):
+		rename_field("Delivery Stop", "lock", "locked")
diff --git a/erpnext/patches/v14_0/rename_over_order_allowance_field.py b/erpnext/patches/v14_0/rename_over_order_allowance_field.py
new file mode 100644
index 0000000..a81fe88
--- /dev/null
+++ b/erpnext/patches/v14_0/rename_over_order_allowance_field.py
@@ -0,0 +1,15 @@
+from frappe.model.utils.rename_field import rename_field
+
+
+def execute():
+	rename_field(
+		"Buying Settings",
+		"over_order_allowance",
+		"blanket_order_allowance",
+	)
+
+	rename_field(
+		"Selling Settings",
+		"over_order_allowance",
+		"blanket_order_allowance",
+	)
diff --git a/erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py b/erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py
index a53adf1..9a2a39f 100644
--- a/erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py
+++ b/erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py
@@ -11,6 +11,9 @@
 	asset_depreciation_schedules_map = get_asset_depreciation_schedules_map()
 
 	for asset in assets:
+		if not asset_depreciation_schedules_map.get(asset.name):
+			continue
+
 		depreciation_schedules = asset_depreciation_schedules_map[asset.name]
 
 		for fb_row in asset_finance_books_map[asset.name]:
diff --git a/erpnext/patches/v15_0/delete_ecommerce_doctypes.py b/erpnext/patches/v15_0/delete_ecommerce_doctypes.py
new file mode 100644
index 0000000..af03987
--- /dev/null
+++ b/erpnext/patches/v15_0/delete_ecommerce_doctypes.py
@@ -0,0 +1,30 @@
+import click
+import frappe
+
+
+def execute():
+	if "webshop" in frappe.get_installed_apps():
+		return
+
+	if not frappe.db.table_exists("Website Item"):
+		return
+
+	doctypes = [
+		"E Commerce Settings",
+		"Website Item",
+		"Recommended Items",
+		"Item Review",
+		"Wishlist Item",
+		"Wishlist",
+		"Website Offer",
+		"Website Item Tabbed Section",
+	]
+
+	for doctype in doctypes:
+		frappe.delete_doc("DocType", doctype, ignore_missing=True)
+
+	click.secho(
+		"ECommerce is renamed and moved to a separate app"
+		"Please install the app for ECommerce features: https://github.com/frappe/webshop",
+		fg="yellow",
+	)
diff --git a/erpnext/patches/v15_0/delete_payment_gateway_doctypes.py b/erpnext/patches/v15_0/delete_payment_gateway_doctypes.py
new file mode 100644
index 0000000..959b065
--- /dev/null
+++ b/erpnext/patches/v15_0/delete_payment_gateway_doctypes.py
@@ -0,0 +1,6 @@
+import frappe
+
+
+def execute():
+	for dt in ("GoCardless Settings", "GoCardless Mandate", "Mpesa Settings"):
+		frappe.delete_doc("DocType", dt, ignore_missing=True)
diff --git a/erpnext/patches/v15_0/rename_daily_depreciation_to_depreciation_amount_based_on_num_days_in_month.py b/erpnext/patches/v15_0/rename_daily_depreciation_to_depreciation_amount_based_on_num_days_in_month.py
new file mode 100644
index 0000000..63dc0e0
--- /dev/null
+++ b/erpnext/patches/v15_0/rename_daily_depreciation_to_depreciation_amount_based_on_num_days_in_month.py
@@ -0,0 +1,21 @@
+# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+
+from frappe.model.utils.rename_field import rename_field
+
+
+def execute():
+	try:
+		rename_field(
+			"Asset Finance Book", "daily_depreciation", "depreciation_amount_based_on_num_days_in_month"
+		)
+		rename_field(
+			"Asset Depreciation Schedule",
+			"daily_depreciation",
+			"depreciation_amount_based_on_num_days_in_month",
+		)
+
+	except Exception as e:
+		if e.args[0] != 1054:
+			raise
diff --git a/erpnext/patches/v15_0/rename_depreciation_amount_based_on_num_days_in_month_to_daily_prorata_based.py b/erpnext/patches/v15_0/rename_depreciation_amount_based_on_num_days_in_month_to_daily_prorata_based.py
new file mode 100644
index 0000000..2c03c23
--- /dev/null
+++ b/erpnext/patches/v15_0/rename_depreciation_amount_based_on_num_days_in_month_to_daily_prorata_based.py
@@ -0,0 +1,21 @@
+# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+
+from frappe.model.utils.rename_field import rename_field
+
+
+def execute():
+	try:
+		rename_field(
+			"Asset Finance Book", "depreciation_amount_based_on_num_days_in_month", "daily_prorata_based"
+		)
+		rename_field(
+			"Asset Depreciation Schedule",
+			"depreciation_amount_based_on_num_days_in_month",
+			"daily_prorata_based",
+		)
+
+	except Exception as e:
+		if e.args[0] != 1054:
+			raise
diff --git a/erpnext/patches/v15_0/set_reserved_stock_in_bin.py b/erpnext/patches/v15_0/set_reserved_stock_in_bin.py
new file mode 100644
index 0000000..fd0a233
--- /dev/null
+++ b/erpnext/patches/v15_0/set_reserved_stock_in_bin.py
@@ -0,0 +1,24 @@
+import frappe
+from frappe.query_builder.functions import Sum
+
+
+def execute():
+	sre = frappe.qb.DocType("Stock Reservation Entry")
+	query = (
+		frappe.qb.from_(sre)
+		.select(
+			sre.item_code,
+			sre.warehouse,
+			Sum(sre.reserved_qty - sre.delivered_qty).as_("reserved_stock"),
+		)
+		.where((sre.docstatus == 1) & (sre.status.notin(["Delivered", "Cancelled"])))
+		.groupby(sre.item_code, sre.warehouse)
+	)
+
+	for d in query.run(as_dict=True):
+		frappe.db.set_value(
+			"Bin",
+			{"item_code": d.item_code, "warehouse": d.warehouse},
+			"reserved_stock",
+			d.reserved_stock,
+		)
diff --git a/erpnext/patches/v15_0/update_sre_from_voucher_details.py b/erpnext/patches/v15_0/update_sre_from_voucher_details.py
new file mode 100644
index 0000000..06ba553
--- /dev/null
+++ b/erpnext/patches/v15_0/update_sre_from_voucher_details.py
@@ -0,0 +1,18 @@
+import frappe
+from frappe.query_builder.functions import IfNull
+
+
+def execute():
+	columns = frappe.db.get_table_columns("Stock Reservation Entry")
+
+	if set(["against_pick_list", "against_pick_list_item"]).issubset(set(columns)):
+		sre = frappe.qb.DocType("Stock Reservation Entry")
+		(
+			frappe.qb.update(sre)
+			.set(sre.from_voucher_type, "Pick List")
+			.set(sre.from_voucher_no, sre.against_pick_list)
+			.set(sre.from_voucher_detail_no, sre.against_pick_list_item)
+			.where(
+				(IfNull(sre.against_pick_list, "") != "") & (IfNull(sre.against_pick_list_item, "") != "")
+			)
+		).run()
diff --git a/erpnext/portal/doctype/homepage/homepage.js b/erpnext/portal/doctype/homepage/homepage.js
index 59f808a..6797904 100644
--- a/erpnext/portal/doctype/homepage/homepage.js
+++ b/erpnext/portal/doctype/homepage/homepage.js
@@ -19,12 +19,3 @@
 		});
 	},
 });
-
-frappe.ui.form.on('Homepage Featured Product', {
-	view: function(frm, cdt, cdn) {
-		var child= locals[cdt][cdn];
-		if (child.item_code && child.route) {
-			window.open('/' + child.route, '_blank');
-		}
-	}
-});
diff --git a/erpnext/portal/doctype/homepage/homepage.json b/erpnext/portal/doctype/homepage/homepage.json
index 73f816d..2b891f7 100644
--- a/erpnext/portal/doctype/homepage/homepage.json
+++ b/erpnext/portal/doctype/homepage/homepage.json
@@ -15,10 +15,7 @@
   "description",
   "hero_image",
   "slideshow",
-  "hero_section",
-  "products_section",
-  "products_url",
-  "products"
+  "hero_section"
  ],
  "fields": [
   {
@@ -86,30 +83,11 @@
    "fieldtype": "Link",
    "label": "Homepage Section",
    "options": "Homepage Section"
-  },
-  {
-   "fieldname": "products_section",
-   "fieldtype": "Section Break",
-   "label": "Products"
-  },
-  {
-   "default": "/all-products",
-   "fieldname": "products_url",
-   "fieldtype": "Data",
-   "label": "URL for \"All Products\""
-  },
-  {
-   "description": "Products to be shown on website homepage",
-   "fieldname": "products",
-   "fieldtype": "Table",
-   "label": "Products",
-   "options": "Homepage Featured Product",
-   "width": "40px"
   }
  ],
  "issingle": 1,
  "links": [],
- "modified": "2021-02-18 13:29:29.531639",
+ "modified": "2022-12-19 21:10:29.127277",
  "modified_by": "Administrator",
  "module": "Portal",
  "name": "Homepage",
@@ -138,6 +116,7 @@
  ],
  "sort_field": "modified",
  "sort_order": "DESC",
+ "states": [],
  "title_field": "company",
  "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/portal/doctype/homepage/homepage.py b/erpnext/portal/doctype/homepage/homepage.py
index 0d2e360..c0a0c07 100644
--- a/erpnext/portal/doctype/homepage/homepage.py
+++ b/erpnext/portal/doctype/homepage/homepage.py
@@ -12,26 +12,3 @@
 		if not self.description:
 			self.description = frappe._("This is an example website auto-generated from ERPNext")
 		delete_page_cache("home")
-
-	def setup_items(self):
-		for d in frappe.get_all(
-			"Website Item",
-			fields=["name", "item_name", "description", "website_image", "route"],
-			filters={"published": 1},
-			limit=3,
-		):
-
-			doc = frappe.get_doc("Website Item", d.name)
-			if not doc.route:
-				# set missing route
-				doc.save()
-			self.append(
-				"products",
-				dict(
-					item_code=d.name,
-					item_name=d.item_name,
-					description=d.description,
-					image=d.website_image,
-					route=d.route,
-				),
-			)
diff --git a/erpnext/portal/doctype/homepage_featured_product/__init__.py b/erpnext/portal/doctype/homepage_featured_product/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/portal/doctype/homepage_featured_product/__init__.py
+++ /dev/null
diff --git a/erpnext/portal/doctype/homepage_featured_product/homepage_featured_product.json b/erpnext/portal/doctype/homepage_featured_product/homepage_featured_product.json
deleted file mode 100644
index 63789e3..0000000
--- a/erpnext/portal/doctype/homepage_featured_product/homepage_featured_product.json
+++ /dev/null
@@ -1,118 +0,0 @@
-{
- "actions": [],
- "autoname": "hash",
- "creation": "2016-04-22 05:57:06.261401",
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "item_code",
-  "col_break1",
-  "item_name",
-  "view",
-  "section_break_5",
-  "description",
-  "column_break_7",
-  "image",
-  "thumbnail",
-  "route"
- ],
- "fields": [
-  {
-   "bold": 1,
-   "fieldname": "item_code",
-   "fieldtype": "Link",
-   "in_filter": 1,
-   "in_list_view": 1,
-   "label": "Item",
-   "oldfieldname": "item_code",
-   "oldfieldtype": "Link",
-   "options": "Website Item",
-   "print_width": "150px",
-   "reqd": 1,
-   "search_index": 1,
-   "width": "150px"
-  },
-  {
-   "fieldname": "col_break1",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fetch_from": "item_code.item_name",
-   "fetch_if_empty": 1,
-   "fieldname": "item_name",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Item Name",
-   "oldfieldname": "item_name",
-   "oldfieldtype": "Data",
-   "print_hide": 1,
-   "print_width": "150",
-   "read_only": 1,
-   "reqd": 1,
-   "width": "150"
-  },
-  {
-   "fieldname": "view",
-   "fieldtype": "Button",
-   "in_list_view": 1,
-   "label": "View"
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "section_break_5",
-   "fieldtype": "Section Break",
-   "label": "Details"
-  },
-  {
-   "fetch_from": "item_code.web_long_description",
-   "fieldname": "description",
-   "fieldtype": "Text Editor",
-   "in_filter": 1,
-   "in_list_view": 1,
-   "label": "Description",
-   "oldfieldname": "description",
-   "oldfieldtype": "Small Text",
-   "print_width": "300px",
-   "width": "300px"
-  },
-  {
-   "fieldname": "column_break_7",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fetch_from": "item_code.website_image",
-   "fetch_if_empty": 1,
-   "fieldname": "image",
-   "fieldtype": "Attach Image",
-   "label": "Image"
-  },
-  {
-   "fetch_from": "item_code.thumbnail",
-   "fieldname": "thumbnail",
-   "fieldtype": "Attach Image",
-   "hidden": 1,
-   "label": "Thumbnail"
-  },
-  {
-   "fetch_from": "item_code.route",
-   "fieldname": "route",
-   "fieldtype": "Small Text",
-   "label": "route",
-   "read_only": 1
-  }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2021-02-18 13:05:50.669311",
- "modified_by": "Administrator",
- "module": "Portal",
- "name": "Homepage Featured Product",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "sort_field": "modified",
- "sort_order": "DESC"
-}
\ No newline at end of file
diff --git a/erpnext/portal/doctype/homepage_featured_product/homepage_featured_product.py b/erpnext/portal/doctype/homepage_featured_product/homepage_featured_product.py
deleted file mode 100644
index c21461d..0000000
--- a/erpnext/portal/doctype/homepage_featured_product/homepage_featured_product.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-
-from frappe.model.document import Document
-
-
-class HomepageFeaturedProduct(Document):
-	pass
diff --git a/erpnext/portal/utils.py b/erpnext/portal/utils.py
index c8b03e6..903d4a6 100644
--- a/erpnext/portal/utils.py
+++ b/erpnext/portal/utils.py
@@ -1,10 +1,4 @@
 import frappe
-from frappe.utils.nestedset import get_root_of
-
-from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import (
-	get_shopping_cart_settings,
-)
-from erpnext.e_commerce.shopping_cart.cart import get_debtors_account
 
 
 def set_default_role(doc, method):
@@ -56,26 +50,7 @@
 	party = frappe.new_doc(doctype)
 	fullname = frappe.utils.get_fullname(user)
 
-	if doctype == "Customer":
-		cart_settings = get_shopping_cart_settings()
-
-		if cart_settings.enable_checkout:
-			debtors_account = get_debtors_account(cart_settings)
-		else:
-			debtors_account = ""
-
-		party.update(
-			{
-				"customer_name": fullname,
-				"customer_type": "Individual",
-				"customer_group": cart_settings.default_customer_group,
-				"territory": get_root_of("Territory"),
-			}
-		)
-
-		if debtors_account:
-			party.update({"accounts": [{"company": cart_settings.company, "account": debtors_account}]})
-	else:
+	if not doctype == "Customer":
 		party.update(
 			{
 				"supplier_name": fullname,
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index a66b549..e9aed1a 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -70,6 +70,7 @@
 				tmp_task_details.append(template_task_details)
 				task = self.create_task_from_template(template_task_details)
 				project_tasks.append(task)
+
 			self.dependency_mapping(tmp_task_details, project_tasks)
 
 	def create_task_from_template(self, task_details):
@@ -108,36 +109,28 @@
 
 	def dependency_mapping(self, template_tasks, project_tasks):
 		for project_task in project_tasks:
-			if project_task.get("template_task"):
-				template_task = frappe.get_doc("Task", project_task.template_task)
-			else:
-				template_task = list(filter(lambda x: x.subject == project_task.subject, template_tasks))[0]
-				template_task = frappe.get_doc("Task", template_task.name)
+			template_task = frappe.get_doc("Task", project_task.template_task)
 
 			self.check_depends_on_value(template_task, project_task, project_tasks)
 			self.check_for_parent_tasks(template_task, project_task, project_tasks)
 
 	def check_depends_on_value(self, template_task, project_task, project_tasks):
 		if template_task.get("depends_on") and not project_task.get("depends_on"):
+			project_template_map = {pt.template_task: pt for pt in project_tasks}
+
 			for child_task in template_task.get("depends_on"):
-				child_task_subject = frappe.db.get_value("Task", child_task.task, "subject")
-				corresponding_project_task = list(
-					filter(lambda x: x.subject == child_task_subject, project_tasks)
-				)
-				if len(corresponding_project_task):
+				if project_template_map and project_template_map.get(child_task.task):
 					project_task.reload()  # reload, as it might have been updated in the previous iteration
-					project_task.append("depends_on", {"task": corresponding_project_task[0].name})
+					project_task.append("depends_on", {"task": project_template_map.get(child_task.task).name})
 					project_task.save()
 
 	def check_for_parent_tasks(self, template_task, project_task, project_tasks):
 		if template_task.get("parent_task") and not project_task.get("parent_task"):
-			parent_task_subject = frappe.db.get_value("Task", template_task.get("parent_task"), "subject")
-			corresponding_project_task = list(
-				filter(lambda x: x.subject == parent_task_subject, project_tasks)
-			)
-			if len(corresponding_project_task):
-				project_task.parent_task = corresponding_project_task[0].name
-				project_task.save()
+			for pt in project_tasks:
+				if pt.template_task == template_task.parent_task:
+					project_task.parent_task = pt.name
+					project_task.save()
+					break
 
 	def is_row_updated(self, row, existing_task_data, fields):
 		if self.get("__islocal") or not existing_task_data:
diff --git a/erpnext/projects/doctype/task/task.json b/erpnext/projects/doctype/task/task.json
index 05a70c3..25a5455 100644
--- a/erpnext/projects/doctype/task/task.json
+++ b/erpnext/projects/doctype/task/task.json
@@ -60,7 +60,6 @@
    "fieldname": "subject",
    "fieldtype": "Data",
    "in_global_search": 1,
-   "in_list_view": 1,
    "in_standard_filter": 1,
    "label": "Subject",
    "reqd": 1,
@@ -140,7 +139,6 @@
    "fieldname": "parent_task",
    "fieldtype": "Link",
    "ignore_user_permissions": 1,
-   "in_list_view": 1,
    "label": "Parent Task",
    "options": "Task",
    "search_index": 1
@@ -398,7 +396,7 @@
  "is_tree": 1,
  "links": [],
  "max_attachments": 5,
- "modified": "2023-09-06 13:52:05.861175",
+ "modified": "2023-09-28 13:52:05.861175",
  "modified_by": "Administrator",
  "module": "Projects",
  "name": "Task",
diff --git a/erpnext/projects/doctype/task_depends_on/task_depends_on.json b/erpnext/projects/doctype/task_depends_on/task_depends_on.json
index dbbe9d3..3300b7e 100644
--- a/erpnext/projects/doctype/task_depends_on/task_depends_on.json
+++ b/erpnext/projects/doctype/task_depends_on/task_depends_on.json
@@ -1,156 +1,52 @@
 {
- "allow_copy": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "beta": 0, 
- "creation": "2015-04-29 04:52:48.868079", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
+ "actions": [],
+ "creation": "2015-04-29 04:52:48.868079",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "task",
+  "column_break_2",
+  "subject",
+  "project"
+ ],
  "fields": [
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "task", 
-   "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": "Task", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Task", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "task",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Task",
+   "options": "Task"
+  },
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_2", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_2",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "subject", 
-   "fieldtype": "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": "Subject", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "task.subject",
+   "fetch_if_empty": 1,
+   "fieldname": "subject",
+   "fieldtype": "Text",
+   "in_list_view": 1,
+   "label": "Subject",
+   "read_only": 1
+  },
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "project", 
-   "fieldtype": "Text", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Project", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
+   "fieldname": "project",
+   "fieldtype": "Text",
+   "label": "Project",
+   "read_only": 1
   }
- ], 
- "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-02-24 04:56:04.862502", 
- "modified_by": "Administrator", 
- "module": "Projects", 
- "name": "Task Depends On", 
- "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
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2023-10-17 12:45:21.536165",
+ "modified_by": "Administrator",
+ "module": "Projects",
+ "name": "Task Depends On",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
 }
\ No newline at end of file
diff --git a/erpnext/projects/report/billing_summary.py b/erpnext/projects/report/billing_summary.py
deleted file mode 100644
index ac1524a..0000000
--- a/erpnext/projects/report/billing_summary.py
+++ /dev/null
@@ -1,155 +0,0 @@
-# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-
-import frappe
-from frappe import _
-from frappe.utils import flt, time_diff_in_hours
-
-
-def get_columns():
-	return [
-		{
-			"label": _("Employee ID"),
-			"fieldtype": "Link",
-			"fieldname": "employee",
-			"options": "Employee",
-			"width": 300,
-		},
-		{
-			"label": _("Employee Name"),
-			"fieldtype": "data",
-			"fieldname": "employee_name",
-			"hidden": 1,
-			"width": 200,
-		},
-		{
-			"label": _("Timesheet"),
-			"fieldtype": "Link",
-			"fieldname": "timesheet",
-			"options": "Timesheet",
-			"width": 150,
-		},
-		{"label": _("Working Hours"), "fieldtype": "Float", "fieldname": "total_hours", "width": 150},
-		{
-			"label": _("Billable Hours"),
-			"fieldtype": "Float",
-			"fieldname": "total_billable_hours",
-			"width": 150,
-		},
-		{"label": _("Billing Amount"), "fieldtype": "Currency", "fieldname": "amount", "width": 150},
-	]
-
-
-def get_data(filters):
-	data = []
-	if filters.from_date > filters.to_date:
-		frappe.msgprint(_("From Date can not be greater than To Date"))
-		return data
-
-	timesheets = get_timesheets(filters)
-
-	filters.from_date = frappe.utils.get_datetime(filters.from_date)
-	filters.to_date = frappe.utils.add_to_date(
-		frappe.utils.get_datetime(filters.to_date), days=1, seconds=-1
-	)
-
-	timesheet_details = get_timesheet_details(filters, timesheets.keys())
-
-	for ts, ts_details in timesheet_details.items():
-		total_hours = 0
-		total_billing_hours = 0
-		total_amount = 0
-
-		for row in ts_details:
-			from_time, to_time = filters.from_date, filters.to_date
-
-			if row.to_time < from_time or row.from_time > to_time:
-				continue
-
-			if row.from_time > from_time:
-				from_time = row.from_time
-
-			if row.to_time < to_time:
-				to_time = row.to_time
-
-			activity_duration, billing_duration = get_billable_and_total_duration(row, from_time, to_time)
-
-			total_hours += activity_duration
-			total_billing_hours += billing_duration
-			total_amount += billing_duration * flt(row.billing_rate)
-
-		if total_hours:
-			data.append(
-				{
-					"employee": timesheets.get(ts).employee,
-					"employee_name": timesheets.get(ts).employee_name,
-					"timesheet": ts,
-					"total_billable_hours": total_billing_hours,
-					"total_hours": total_hours,
-					"amount": total_amount,
-				}
-			)
-
-	return data
-
-
-def get_timesheets(filters):
-	record_filters = [
-		["start_date", "<=", filters.to_date],
-		["end_date", ">=", filters.from_date],
-	]
-	if not filters.get("include_draft_timesheets"):
-		record_filters.append(["docstatus", "=", 1])
-	else:
-		record_filters.append(["docstatus", "!=", 2])
-	if "employee" in filters:
-		record_filters.append(["employee", "=", filters.employee])
-
-	timesheets = frappe.get_all(
-		"Timesheet", filters=record_filters, fields=["employee", "employee_name", "name"]
-	)
-	timesheet_map = frappe._dict()
-	for d in timesheets:
-		timesheet_map.setdefault(d.name, d)
-
-	return timesheet_map
-
-
-def get_timesheet_details(filters, timesheet_list):
-	timesheet_details_filter = {"parent": ["in", timesheet_list]}
-
-	if "project" in filters:
-		timesheet_details_filter["project"] = filters.project
-
-	timesheet_details = frappe.get_all(
-		"Timesheet Detail",
-		filters=timesheet_details_filter,
-		fields=[
-			"from_time",
-			"to_time",
-			"hours",
-			"is_billable",
-			"billing_hours",
-			"billing_rate",
-			"parent",
-		],
-	)
-
-	timesheet_details_map = frappe._dict()
-	for d in timesheet_details:
-		timesheet_details_map.setdefault(d.parent, []).append(d)
-
-	return timesheet_details_map
-
-
-def get_billable_and_total_duration(activity, start_time, end_time):
-	precision = frappe.get_precision("Timesheet Detail", "hours")
-	activity_duration = time_diff_in_hours(end_time, start_time)
-	billing_duration = 0.0
-	if activity.is_billable:
-		billing_duration = activity.billing_hours
-		if activity_duration != activity.billing_hours:
-			billing_duration = activity_duration * activity.billing_hours / activity.hours
-
-	return flt(activity_duration, precision), flt(billing_duration, precision)
diff --git a/erpnext/projects/report/employee_billing_summary/__init__.py b/erpnext/projects/report/employee_billing_summary/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/projects/report/employee_billing_summary/__init__.py
+++ /dev/null
diff --git a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js
deleted file mode 100644
index 2c25465..0000000
--- a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-
-frappe.query_reports["Employee Billing Summary"] = {
-	"filters": [
-		{
-			fieldname: "employee",
-			label: __("Employee"),
-			fieldtype: "Link",
-			options: "Employee",
-			reqd: 1
-		},
-		{
-			fieldname:"from_date",
-			label: __("From Date"),
-			fieldtype: "Date",
-			default: frappe.datetime.add_months(frappe.datetime.month_start(), -1),
-			reqd: 1
-		},
-		{
-			fieldname:"to_date",
-			label: __("To Date"),
-			fieldtype: "Date",
-			default: frappe.datetime.add_days(frappe.datetime.month_start(), -1),
-			reqd: 1
-		},
-		{
-			fieldname:"include_draft_timesheets",
-			label: __("Include Timesheets in Draft Status"),
-			fieldtype: "Check",
-		},
-	]
-}
diff --git a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py
deleted file mode 100644
index a2f7378..0000000
--- a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-
-import frappe
-
-from erpnext.projects.report.billing_summary import get_columns, get_data
-
-
-def execute(filters=None):
-	filters = frappe._dict(filters or {})
-	columns = get_columns()
-
-	data = get_data(filters)
-	return columns, data
diff --git a/erpnext/projects/report/project_billing_summary/project_billing_summary.js b/erpnext/projects/report/project_billing_summary/project_billing_summary.js
deleted file mode 100644
index fce0c68..0000000
--- a/erpnext/projects/report/project_billing_summary/project_billing_summary.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-
-frappe.query_reports["Project Billing Summary"] = {
-	"filters": [
-		{
-			fieldname: "project",
-			label: __("Project"),
-			fieldtype: "Link",
-			options: "Project",
-			reqd: 1
-		},
-		{
-			fieldname:"from_date",
-			label: __("From Date"),
-			fieldtype: "Date",
-			default: frappe.datetime.add_months(frappe.datetime.month_start(), -1),
-			reqd: 1
-		},
-		{
-			fieldname:"to_date",
-			label: __("To Date"),
-			fieldtype: "Date",
-			default: frappe.datetime.add_days(frappe.datetime.month_start(),-1),
-			reqd: 1
-		},
-		{
-			fieldname:"include_draft_timesheets",
-			label: __("Include Timesheets in Draft Status"),
-			fieldtype: "Check",
-		},
-	]
-}
diff --git a/erpnext/projects/report/project_billing_summary/project_billing_summary.json b/erpnext/projects/report/project_billing_summary/project_billing_summary.json
deleted file mode 100644
index 817d0cd..0000000
--- a/erpnext/projects/report/project_billing_summary/project_billing_summary.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "add_total_row": 1,
- "creation": "2019-03-11 16:22:39.460524",
- "disable_prepared_report": 0,
- "disabled": 0,
- "docstatus": 0,
- "doctype": "Report",
- "idx": 0,
- "is_standard": "Yes",
- "modified": "2019-06-13 15:54:55.255947",
- "modified_by": "Administrator",
- "module": "Projects",
- "name": "Project Billing Summary",
- "owner": "Administrator",
- "prepared_report": 0,
- "ref_doctype": "Timesheet",
- "report_name": "Project Billing Summary",
- "report_type": "Script Report",
- "roles": [
-  {
-   "role": "Projects User"
-  },
-  {
-   "role": "HR User"
-  },
-  {
-   "role": "Manufacturing User"
-  },
-  {
-   "role": "Employee"
-  },
-  {
-   "role": "Accounts User"
-  }
- ]
-}
\ No newline at end of file
diff --git a/erpnext/projects/report/project_billing_summary/project_billing_summary.py b/erpnext/projects/report/project_billing_summary/project_billing_summary.py
deleted file mode 100644
index a2f7378..0000000
--- a/erpnext/projects/report/project_billing_summary/project_billing_summary.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-
-import frappe
-
-from erpnext.projects.report.billing_summary import get_columns, get_data
-
-
-def execute(filters=None):
-	filters = frappe._dict(filters or {})
-	columns = get_columns()
-
-	data = get_data(filters)
-	return columns, data
diff --git a/erpnext/projects/report/project_billing_summary/__init__.py b/erpnext/projects/report/timesheet_billing_summary/__init__.py
similarity index 100%
rename from erpnext/projects/report/project_billing_summary/__init__.py
rename to erpnext/projects/report/timesheet_billing_summary/__init__.py
diff --git a/erpnext/projects/report/timesheet_billing_summary/timesheet_billing_summary.js b/erpnext/projects/report/timesheet_billing_summary/timesheet_billing_summary.js
new file mode 100644
index 0000000..1efd0c6
--- /dev/null
+++ b/erpnext/projects/report/timesheet_billing_summary/timesheet_billing_summary.js
@@ -0,0 +1,67 @@
+// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.query_reports["Timesheet Billing Summary"] = {
+	tree: true,
+	initial_depth: 0,
+	filters: [
+		{
+			fieldname: "employee",
+			label: __("Employee"),
+			fieldtype: "Link",
+			options: "Employee",
+			on_change: function (report) {
+				unset_group_by(report, "employee");
+			},
+		},
+		{
+			fieldname: "project",
+			label: __("Project"),
+			fieldtype: "Link",
+			options: "Project",
+			on_change: function (report) {
+				unset_group_by(report, "project");
+			},
+		},
+		{
+			fieldname: "from_date",
+			label: __("From Date"),
+			fieldtype: "Date",
+			default: frappe.datetime.add_months(
+				frappe.datetime.month_start(),
+				-1
+			),
+		},
+		{
+			fieldname: "to_date",
+			label: __("To Date"),
+			fieldtype: "Date",
+			default: frappe.datetime.add_days(
+				frappe.datetime.month_start(),
+				-1
+			),
+		},
+		{  // NOTE: `update_group_by_options` expects this filter to be the fifth in the list
+			fieldname: "group_by",
+			label: __("Group By"),
+			fieldtype: "Select",
+			options: [
+				"",
+				{ value: "employee", label: __("Employee") },
+				{ value: "project", label: __("Project") },
+				{ value: "date", label: __("Start Date") },
+			],
+		},
+		{
+			fieldname: "include_draft_timesheets",
+			label: __("Include Timesheets in Draft Status"),
+			fieldtype: "Check",
+		},
+	],
+};
+
+function unset_group_by(report, fieldname) {
+	if (report.get_filter_value(fieldname) && report.get_filter_value("group_by") == fieldname) {
+		report.set_filter_value("group_by", "");
+	}
+}
diff --git a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.json b/erpnext/projects/report/timesheet_billing_summary/timesheet_billing_summary.json
similarity index 61%
rename from erpnext/projects/report/employee_billing_summary/employee_billing_summary.json
rename to erpnext/projects/report/timesheet_billing_summary/timesheet_billing_summary.json
index e5626a0..0f070cb 100644
--- a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.json
+++ b/erpnext/projects/report/timesheet_billing_summary/timesheet_billing_summary.json
@@ -1,36 +1,42 @@
 {
  "add_total_row": 1,
- "creation": "2019-03-08 15:08:19.929728",
- "disable_prepared_report": 0,
+ "columns": [],
+ "creation": "2023-10-10 23:53:43.692067",
  "disabled": 0,
  "docstatus": 0,
  "doctype": "Report",
+ "filters": [],
  "idx": 0,
  "is_standard": "Yes",
- "modified": "2019-06-13 15:54:49.213973",
+ "letter_head": "ALYF GmbH",
+ "letterhead": null,
+ "modified": "2023-10-11 00:58:30.639078",
  "modified_by": "Administrator",
  "module": "Projects",
- "name": "Employee Billing Summary",
+ "name": "Timesheet Billing Summary",
  "owner": "Administrator",
  "prepared_report": 0,
  "ref_doctype": "Timesheet",
- "report_name": "Employee Billing Summary",
+ "report_name": "Timesheet Billing Summary",
  "report_type": "Script Report",
  "roles": [
   {
    "role": "Projects User"
   },
   {
-   "role": "HR User"
+   "role": "Employee"
+  },
+  {
+   "role": "Accounts User"
   },
   {
    "role": "Manufacturing User"
   },
   {
-   "role": "Employee"
+   "role": "HR User"
   },
   {
-   "role": "Accounts User"
+   "role": "Employee Self Service"
   }
  ]
 }
\ No newline at end of file
diff --git a/erpnext/projects/report/timesheet_billing_summary/timesheet_billing_summary.py b/erpnext/projects/report/timesheet_billing_summary/timesheet_billing_summary.py
new file mode 100644
index 0000000..a6e7150
--- /dev/null
+++ b/erpnext/projects/report/timesheet_billing_summary/timesheet_billing_summary.py
@@ -0,0 +1,146 @@
+import frappe
+from frappe import _
+from frappe.model.docstatus import DocStatus
+
+
+def execute(filters=None):
+	group_fieldname = filters.pop("group_by", None)
+
+	filters = frappe._dict(filters or {})
+	columns = get_columns(filters, group_fieldname)
+
+	data = get_data(filters, group_fieldname)
+	return columns, data
+
+
+def get_columns(filters, group_fieldname=None):
+	group_columns = {
+		"date": {
+			"label": _("Date"),
+			"fieldtype": "Date",
+			"fieldname": "date",
+			"width": 150,
+		},
+		"project": {
+			"label": _("Project"),
+			"fieldtype": "Link",
+			"fieldname": "project",
+			"options": "Project",
+			"width": 200,
+			"hidden": int(bool(filters.get("project"))),
+		},
+		"employee": {
+			"label": _("Employee ID"),
+			"fieldtype": "Link",
+			"fieldname": "employee",
+			"options": "Employee",
+			"width": 200,
+			"hidden": int(bool(filters.get("employee"))),
+		},
+	}
+	columns = []
+	if group_fieldname:
+		columns.append(group_columns.get(group_fieldname))
+		columns.extend(
+			column for column in group_columns.values() if column.get("fieldname") != group_fieldname
+		)
+	else:
+		columns.extend(group_columns.values())
+
+	columns.extend(
+		[
+			{
+				"label": _("Employee Name"),
+				"fieldtype": "data",
+				"fieldname": "employee_name",
+				"hidden": 1,
+			},
+			{
+				"label": _("Timesheet"),
+				"fieldtype": "Link",
+				"fieldname": "timesheet",
+				"options": "Timesheet",
+				"width": 150,
+			},
+			{"label": _("Working Hours"), "fieldtype": "Float", "fieldname": "hours", "width": 150},
+			{
+				"label": _("Billing Hours"),
+				"fieldtype": "Float",
+				"fieldname": "billing_hours",
+				"width": 150,
+			},
+			{
+				"label": _("Billing Amount"),
+				"fieldtype": "Currency",
+				"fieldname": "billing_amount",
+				"width": 150,
+			},
+		]
+	)
+
+	return columns
+
+
+def get_data(filters, group_fieldname=None):
+	_filters = []
+	if filters.get("employee"):
+		_filters.append(("employee", "=", filters.get("employee")))
+	if filters.get("project"):
+		_filters.append(("Timesheet Detail", "project", "=", filters.get("project")))
+	if filters.get("from_date"):
+		_filters.append(("Timesheet Detail", "from_time", ">=", filters.get("from_date")))
+	if filters.get("to_date"):
+		_filters.append(("Timesheet Detail", "to_time", "<=", filters.get("to_date")))
+	if not filters.get("include_draft_timesheets"):
+		_filters.append(("docstatus", "=", DocStatus.submitted()))
+	else:
+		_filters.append(("docstatus", "in", (DocStatus.submitted(), DocStatus.draft())))
+
+	data = frappe.get_list(
+		"Timesheet",
+		fields=[
+			"name as timesheet",
+			"`tabTimesheet`.employee",
+			"`tabTimesheet`.employee_name",
+			"`tabTimesheet Detail`.from_time as date",
+			"`tabTimesheet Detail`.project",
+			"`tabTimesheet Detail`.hours",
+			"`tabTimesheet Detail`.billing_hours",
+			"`tabTimesheet Detail`.billing_amount",
+		],
+		filters=_filters,
+		order_by="`tabTimesheet Detail`.from_time",
+	)
+
+	return group_by(data, group_fieldname) if group_fieldname else data
+
+
+def group_by(data, fieldname):
+	groups = {row.get(fieldname) for row in data}
+	grouped_data = []
+	for group in sorted(groups):
+		group_row = {
+			fieldname: group,
+			"hours": sum(row.get("hours") for row in data if row.get(fieldname) == group),
+			"billing_hours": sum(row.get("billing_hours") for row in data if row.get(fieldname) == group),
+			"billing_amount": sum(row.get("billing_amount") for row in data if row.get(fieldname) == group),
+			"indent": 0,
+			"is_group": 1,
+		}
+		if fieldname == "employee":
+			group_row["employee_name"] = next(
+				row.get("employee_name") for row in data if row.get(fieldname) == group
+			)
+
+		grouped_data.append(group_row)
+		for row in data:
+			if row.get(fieldname) != group:
+				continue
+
+			_row = row.copy()
+			_row[fieldname] = None
+			_row["indent"] = 1
+			_row["is_group"] = 0
+			grouped_data.append(_row)
+
+	return grouped_data
diff --git a/erpnext/projects/workspace/projects/projects.json b/erpnext/projects/workspace/projects/projects.json
index 94ae9c0..e6bead9 100644
--- a/erpnext/projects/workspace/projects/projects.json
+++ b/erpnext/projects/workspace/projects/projects.json
@@ -155,9 +155,9 @@
    "dependencies": "Project",
    "hidden": 0,
    "is_query_report": 1,
-   "label": "Project Billing Summary",
+   "label": "Timesheet Billing Summary",
    "link_count": 0,
-   "link_to": "Project Billing Summary",
+   "link_to": "Timesheet Billing Summary",
    "link_type": "Report",
    "onboard": 0,
    "type": "Link"
@@ -192,7 +192,7 @@
    "type": "Link"
   }
  ],
- "modified": "2023-07-04 14:39:08.935853",
+ "modified": "2023-10-10 23:54:33.082108",
  "modified_by": "Administrator",
  "module": "Projects",
  "name": "Projects",
@@ -234,8 +234,8 @@
    "type": "DocType"
   },
   {
-   "label": "Project Billing Summary",
-   "link_to": "Project Billing Summary",
+   "label": "Timesheet Billing Summary",
+   "link_to": "Timesheet Billing Summary",
    "type": "Report"
   },
   {
diff --git a/erpnext/public/images/erpnext-favicon.svg b/erpnext/public/images/erpnext-favicon.svg
index 6bc6b2c..768e6e5 100644
--- a/erpnext/public/images/erpnext-favicon.svg
+++ b/erpnext/public/images/erpnext-favicon.svg
@@ -1,5 +1,5 @@
 <svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M0 12C0 5.37258 5.37258 0 12 0H88C94.6274 0 100 5.37258 100 12V88C100 94.6274 94.6274 100 88 100H12C5.37258 100 0 94.6274 0 88V12Z" fill="#0089FF"/>
+<path d="M0 12C0 5.37258 5.37258 0 12 0H88C94.6274 0 100 5.37258 100 12V88C100 94.6274 94.6274 100 88 100H12C5.37258 100 0 94.6274 0 88V12Z" fill="#171717"/>
 <path d="M65.7097 32.9462H67.3871V24H33V32.9462H43.9032H65.7097Z" fill="white"/>
 <path d="M43.9032 66.2151V53.914H65.7097V44.9677H43.9032H33V75.1613H67.6667V66.2151H43.9032Z" fill="white"/>
 </svg>
diff --git a/erpnext/public/images/erpnext-logo.png b/erpnext/public/images/erpnext-logo.png
index 3090727..b4c2749 100644
--- a/erpnext/public/images/erpnext-logo.png
+++ b/erpnext/public/images/erpnext-logo.png
Binary files differ
diff --git a/erpnext/public/images/erpnext-logo.svg b/erpnext/public/images/erpnext-logo.svg
index 6bc6b2c..768e6e5 100644
--- a/erpnext/public/images/erpnext-logo.svg
+++ b/erpnext/public/images/erpnext-logo.svg
@@ -1,5 +1,5 @@
 <svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M0 12C0 5.37258 5.37258 0 12 0H88C94.6274 0 100 5.37258 100 12V88C100 94.6274 94.6274 100 88 100H12C5.37258 100 0 94.6274 0 88V12Z" fill="#0089FF"/>
+<path d="M0 12C0 5.37258 5.37258 0 12 0H88C94.6274 0 100 5.37258 100 12V88C100 94.6274 94.6274 100 88 100H12C5.37258 100 0 94.6274 0 88V12Z" fill="#171717"/>
 <path d="M65.7097 32.9462H67.3871V24H33V32.9462H43.9032H65.7097Z" fill="white"/>
 <path d="M43.9032 66.2151V53.914H65.7097V44.9677H43.9032H33V75.1613H67.6667V66.2151H43.9032Z" fill="white"/>
 </svg>
diff --git a/erpnext/public/js/controllers/accounts.js b/erpnext/public/js/controllers/accounts.js
index a2e4bda..7879173 100644
--- a/erpnext/public/js/controllers/accounts.js
+++ b/erpnext/public/js/controllers/accounts.js
@@ -30,7 +30,6 @@
 							filters: {
 								"account_type": account_type,
 								"company": doc.company,
-								"disabled": 0
 							}
 						}
 					});
@@ -116,7 +115,7 @@
 			account_head: function(frm, cdt, cdn) {
 				let d = locals[cdt][cdn];
 
-				if (doc.docstatus == 1) {
+				if (d.docstatus == 1) {
 					// Should not trigger any changes on change post submit
 					return;
 				}
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index eeb09cb..6b613ce 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -135,7 +135,15 @@
 				}
 				else {
 					// allow for '0' qty on Credit/Debit notes
-					let qty = item.qty || (me.frm.doc.is_debit_note ? 1 : -1);
+					let qty = flt(item.qty);
+					if (!qty) {
+						qty = (me.frm.doc.is_debit_note ? 1 : -1);
+						if (me.frm.doc.doctype !== "Purchase Receipt" && me.frm.doc.is_return === 1) {
+							// In case of Purchase Receipt, qty can be 0 if all items are rejected
+							qty = flt(item.qty);
+						}
+					}
+
 					item.net_amount = item.amount = flt(item.rate * qty, precision("amount", item));
 				}
 
@@ -185,7 +193,7 @@
 		frappe.flags.round_off_applicable_accounts = [];
 
 		if (me.frm.doc.company) {
-			return frappe.call({
+			frappe.call({
 				"method": "erpnext.controllers.taxes_and_totals.get_round_off_applicable_accounts",
 				"args": {
 					"company": me.frm.doc.company,
@@ -198,6 +206,11 @@
 				}
 			});
 		}
+
+		frappe.db.get_single_value("Accounts Settings", "round_row_wise_tax")
+			.then((round_row_wise_tax) => {
+				frappe.flags.round_row_wise_tax = round_row_wise_tax;
+			})
 	}
 
 	determine_exclusive_rate() {
@@ -338,6 +351,9 @@
 			$.each(me.frm.doc["taxes"] || [], function(i, tax) {
 				// tax_amount represents the amount of tax for the current step
 				var current_tax_amount = me.get_current_tax_amount(item, tax, item_tax_map);
+				if (frappe.flags.round_row_wise_tax) {
+					current_tax_amount = flt(current_tax_amount, precision("tax_amount", tax));
+				}
 
 				// Adjust divisional loss to the last item
 				if (tax.charge_type == "Actual") {
@@ -472,8 +488,15 @@
 		}
 
 		let item_wise_tax_amount = current_tax_amount * this.frm.doc.conversion_rate;
-		if (tax_detail && tax_detail[key])
-			item_wise_tax_amount += tax_detail[key][1];
+		if (frappe.flags.round_row_wise_tax) {
+			item_wise_tax_amount = flt(item_wise_tax_amount, precision("tax_amount", tax));
+			if (tax_detail && tax_detail[key]) {
+				item_wise_tax_amount += flt(tax_detail[key][1], precision("tax_amount", tax));
+			}
+		} else {
+			if (tax_detail && tax_detail[key])
+				item_wise_tax_amount += tax_detail[key][1];
+		}
 
 		tax_detail[key] = [tax_rate, flt(item_wise_tax_amount, precision("base_tax_amount", tax))];
 	}
diff --git a/erpnext/public/js/customer_reviews.js b/erpnext/public/js/customer_reviews.js
deleted file mode 100644
index e13ded6..0000000
--- a/erpnext/public/js/customer_reviews.js
+++ /dev/null
@@ -1,138 +0,0 @@
-$(() => {
-	class CustomerReviews {
-		constructor() {
-			this.bind_button_actions();
-			this.start = 0;
-			this.page_length = 10;
-		}
-
-		bind_button_actions() {
-			this.write_review();
-			this.view_more();
-		}
-
-		write_review() {
-			//TODO: make dialog popup on stray page
-			$('.page_content').on('click', '.btn-write-review', (e) => {
-				// Bind action on write a review button
-				const $btn = $(e.currentTarget);
-
-				let d = new frappe.ui.Dialog({
-					title: __("Write a Review"),
-					fields: [
-						{fieldname: "title", fieldtype: "Data", label: "Headline", reqd: 1},
-						{fieldname: "rating", fieldtype: "Rating", label: "Overall Rating", reqd: 1},
-						{fieldtype: "Section Break"},
-						{fieldname: "comment", fieldtype: "Small Text", label: "Your Review"}
-					],
-					primary_action: function() {
-						let data = d.get_values();
-						frappe.call({
-							method: "erpnext.e_commerce.doctype.item_review.item_review.add_item_review",
-							args: {
-								web_item: $btn.attr('data-web-item'),
-								title: data.title,
-								rating: data.rating,
-								comment: data.comment
-							},
-							freeze: true,
-							freeze_message: __("Submitting Review ..."),
-							callback: (r) => {
-								if (!r.exc) {
-									frappe.msgprint({
-										message: __("Thank you for submitting your review"),
-										title: __("Review Submitted"),
-										indicator: "green"
-									});
-									d.hide();
-									location.reload();
-								}
-							}
-						});
-					},
-					primary_action_label: __('Submit')
-				});
-				d.show();
-			});
-		}
-
-		view_more() {
-			$('.page_content').on('click', '.btn-view-more', (e) => {
-				// Bind action on view more button
-				const $btn = $(e.currentTarget);
-				$btn.prop('disabled', true);
-
-				this.start += this.page_length;
-				let me = this;
-
-				frappe.call({
-					method: "erpnext.e_commerce.doctype.item_review.item_review.get_item_reviews",
-					args: {
-						web_item: $btn.attr('data-web-item'),
-						start: me.start,
-						end: me.page_length
-					},
-					callback: (result) => {
-						if (result.message) {
-							let res = result.message;
-							me.get_user_review_html(res.reviews);
-
-							$btn.prop('disabled', false);
-							if (res.total_reviews <= (me.start + me.page_length)) {
-								$btn.hide();
-							}
-
-						}
-					}
-				});
-			});
-
-		}
-
-		get_user_review_html(reviews) {
-			let me = this;
-			let $content = $('.user-reviews');
-
-			reviews.forEach((review) => {
-				$content.append(`
-					<div class="mb-3 review">
-						<div class="d-flex">
-							<p class="mr-4 user-review-title">
-								<span>${__(review.review_title)}</span>
-							</p>
-							<div class="rating">
-								${me.get_review_stars(review.rating)}
-							</div>
-						</div>
-
-						<div class="product-description mb-4">
-							<p>
-								${__(review.comment)}
-							</p>
-						</div>
-						<div class="review-signature mb-2">
-							<span class="reviewer">${__(review.customer)}</span>
-							<span class="indicator grey" style="--text-on-gray: var(--gray-300);"></span>
-							<span class="reviewer">${__(review.published_on)}</span>
-						</div>
-					</div>
-				`);
-			});
-		}
-
-		get_review_stars(rating) {
-			let stars = ``;
-			for (let i = 1; i < 6; i++) {
-				let fill_class = i <= rating ? 'star-click' : '';
-				stars += `
-					<svg class="icon icon-sm ${fill_class}">
-						<use href="#icon-star"></use>
-					</svg>
-				`;
-			}
-			return stars;
-		}
-	}
-
-	new CustomerReviews();
-});
\ No newline at end of file
diff --git a/erpnext/public/js/erpnext-web.bundle.js b/erpnext/public/js/erpnext-web.bundle.js
index cbe899d..45c6a64 100644
--- a/erpnext/public/js/erpnext-web.bundle.js
+++ b/erpnext/public/js/erpnext-web.bundle.js
@@ -1,8 +1 @@
 import "./website_utils";
-import "./wishlist";
-import "./shopping_cart";
-import "./customer_reviews";
-import "../../e_commerce/product_ui/list";
-import "../../e_commerce/product_ui/views";
-import "../../e_commerce/product_ui/grid";
-import "../../e_commerce/product_ui/search";
\ No newline at end of file
diff --git a/erpnext/public/js/erpnext.bundle.js b/erpnext/public/js/erpnext.bundle.js
index 0e1b23b..dee9a06 100644
--- a/erpnext/public/js/erpnext.bundle.js
+++ b/erpnext/public/js/erpnext.bundle.js
@@ -30,5 +30,6 @@
 import "./utils/sales_common.js";
 import "./controllers/buying.js";
 import "./utils/demo.js";
+import "./financial_statements.js";
 
 // import { sum } from 'frappe/public/utils/util.js'
diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js
index 959cf50..907a775 100644
--- a/erpnext/public/js/financial_statements.js
+++ b/erpnext/public/js/financial_statements.js
@@ -6,8 +6,10 @@
 		if (data && column.fieldname=="account") {
 			value = data.account_name || value;
 
-			column.link_onclick =
-				"erpnext.financial_statements.open_general_ledger(" + JSON.stringify(data) + ")";
+			if (data.account) {
+				column.link_onclick =
+					"erpnext.financial_statements.open_general_ledger(" + JSON.stringify(data) + ")";
+			}
 			column.is_tree = true;
 		}
 
diff --git a/erpnext/public/js/shopping_cart.js b/erpnext/public/js/shopping_cart.js
deleted file mode 100644
index d14740c..0000000
--- a/erpnext/public/js/shopping_cart.js
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-// License: GNU General Public License v3. See license.txt
-
-// shopping cart
-frappe.provide("erpnext.e_commerce.shopping_cart");
-var shopping_cart = erpnext.e_commerce.shopping_cart;
-
-var getParams = function (url) {
-	var params = [];
-	var parser = document.createElement('a');
-	parser.href = url;
-	var query = parser.search.substring(1);
-	var vars = query.split('&');
-	for (var i = 0; i < vars.length; i++) {
-		var pair = vars[i].split('=');
-		params[pair[0]] = decodeURIComponent(pair[1]);
-	}
-	return params;
-};
-
-frappe.ready(function() {
-	var full_name = frappe.session && frappe.session.user_fullname;
-	// update user
-	if(full_name) {
-		$('.navbar li[data-label="User"] a')
-			.html('<i class="fa fa-fixed-width fa fa-user"></i> ' + full_name);
-	}
-	// set coupon code and sales partner code
-
-	var url_args = getParams(window.location.href);
-
-	var referral_coupon_code = url_args['cc'];
-	var referral_sales_partner = url_args['sp'];
-
-	var d = new Date();
-	// expires within 30 minutes
-	d.setTime(d.getTime() + (0.02 * 24 * 60 * 60 * 1000));
-	var expires = "expires="+d.toUTCString();
-	if (referral_coupon_code) {
-		document.cookie = "referral_coupon_code=" + referral_coupon_code + ";" + expires + ";path=/";
-	}
-	if (referral_sales_partner) {
-		document.cookie = "referral_sales_partner=" + referral_sales_partner + ";" + expires + ";path=/";
-	}
-	referral_coupon_code=frappe.get_cookie("referral_coupon_code");
-	referral_sales_partner=frappe.get_cookie("referral_sales_partner");
-
-	if (referral_coupon_code && $(".tot_quotation_discount").val()==undefined ) {
-		$(".txtcoupon").val(referral_coupon_code);
-	}
-	if (referral_sales_partner) {
-		$(".txtreferral_sales_partner").val(referral_sales_partner);
-	}
-
-	// update login
-	shopping_cart.show_shoppingcart_dropdown();
-	shopping_cart.set_cart_count();
-	shopping_cart.show_cart_navbar();
-});
-
-$.extend(shopping_cart, {
-	show_shoppingcart_dropdown: function() {
-		$(".shopping-cart").on('shown.bs.dropdown', function() {
-			if (!$('.shopping-cart-menu .cart-container').length) {
-				return frappe.call({
-					method: 'erpnext.e_commerce.shopping_cart.cart.get_shopping_cart_menu',
-					callback: function(r) {
-						if (r.message) {
-							$('.shopping-cart-menu').html(r.message);
-						}
-					}
-				});
-			}
-		});
-	},
-
-	update_cart: function(opts) {
-		if (frappe.session.user==="Guest") {
-			if (localStorage) {
-				localStorage.setItem("last_visited", window.location.pathname);
-			}
-			frappe.call('erpnext.e_commerce.api.get_guest_redirect_on_action').then((res) => {
-				window.location.href = res.message || "/login";
-			});
-		} else {
-			shopping_cart.freeze();
-			return frappe.call({
-				type: "POST",
-				method: "erpnext.e_commerce.shopping_cart.cart.update_cart",
-				args: {
-					item_code: opts.item_code,
-					qty: opts.qty,
-					additional_notes: opts.additional_notes !== undefined ? opts.additional_notes : undefined,
-					with_items: opts.with_items || 0
-				},
-				btn: opts.btn,
-				callback: function(r) {
-					shopping_cart.unfreeze();
-					shopping_cart.set_cart_count(true);
-					if(opts.callback)
-						opts.callback(r);
-				}
-			});
-		}
-	},
-
-	set_cart_count: function(animate=false) {
-		$(".intermediate-empty-cart").remove();
-
-		var cart_count = frappe.get_cookie("cart_count");
-		if(frappe.session.user==="Guest") {
-			cart_count = 0;
-		}
-
-		if(cart_count) {
-			$(".shopping-cart").toggleClass('hidden', false);
-		}
-
-		var $cart = $('.cart-icon');
-		var $badge = $cart.find("#cart-count");
-
-		if(parseInt(cart_count) === 0 || cart_count === undefined) {
-			$cart.css("display", "none");
-			$(".cart-tax-items").hide();
-			$(".btn-place-order").hide();
-			$(".cart-payment-addresses").hide();
-
-			let intermediate_empty_cart_msg = `
-				<div class="text-center w-100 intermediate-empty-cart mt-4 mb-4 text-muted">
-					${ __("Cart is Empty") }
-				</div>
-			`;
-			$(".cart-table").after(intermediate_empty_cart_msg);
-		}
-		else {
-			$cart.css("display", "inline");
-			$("#cart-count").text(cart_count);
-		}
-
-		if(cart_count) {
-			$badge.html(cart_count);
-
-			if (animate) {
-				$cart.addClass("cart-animate");
-				setTimeout(() => {
-					$cart.removeClass("cart-animate");
-				}, 500);
-			}
-		} else {
-			$badge.remove();
-		}
-	},
-
-	shopping_cart_update: function({item_code, qty, cart_dropdown, additional_notes}) {
-		shopping_cart.update_cart({
-			item_code,
-			qty,
-			additional_notes,
-			with_items: 1,
-			btn: this,
-			callback: function(r) {
-				if(!r.exc) {
-					$(".cart-items").html(r.message.items);
-					$(".cart-tax-items").html(r.message.total);
-					$(".payment-summary").html(r.message.taxes_and_totals);
-					shopping_cart.set_cart_count();
-
-					if (cart_dropdown != true) {
-						$(".cart-icon").hide();
-					}
-				}
-			},
-		});
-	},
-
-	show_cart_navbar: function () {
-		frappe.call({
-			method: "erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings.is_cart_enabled",
-			callback: function(r) {
-				$(".shopping-cart").toggleClass('hidden', r.message ? false : true);
-			}
-		});
-	},
-
-	toggle_button_class(button, remove, add) {
-		button.removeClass(remove);
-		button.addClass(add);
-	},
-
-	bind_add_to_cart_action() {
-		$('.page_content').on('click', '.btn-add-to-cart-list', (e) => {
-			const $btn = $(e.currentTarget);
-			$btn.prop('disabled', true);
-
-			if (frappe.session.user==="Guest") {
-				if (localStorage) {
-					localStorage.setItem("last_visited", window.location.pathname);
-				}
-				frappe.call('erpnext.e_commerce.api.get_guest_redirect_on_action').then((res) => {
-					window.location.href = res.message || "/login";
-				});
-				return;
-			}
-
-			$btn.addClass('hidden');
-			$btn.closest('.cart-action-container').addClass('d-flex');
-			$btn.parent().find('.go-to-cart').removeClass('hidden');
-			$btn.parent().find('.go-to-cart-grid').removeClass('hidden');
-			$btn.parent().find('.cart-indicator').removeClass('hidden');
-
-			const item_code = $btn.data('item-code');
-			erpnext.e_commerce.shopping_cart.update_cart({
-				item_code,
-				qty: 1
-			});
-
-		});
-	},
-
-	freeze() {
-		if (window.location.pathname !== "/cart") return;
-
-		if (!$('#freeze').length) {
-			let freeze = $('<div id="freeze" class="modal-backdrop fade"></div>')
-				.appendTo("body");
-
-			setTimeout(function() {
-				freeze.addClass("show");
-			}, 1);
-		} else {
-			$("#freeze").addClass("show");
-		}
-	},
-
-	unfreeze() {
-		if ($('#freeze').length) {
-			let freeze = $('#freeze').removeClass("show");
-			setTimeout(function() {
-				freeze.remove();
-			}, 1);
-		}
-	}
-});
diff --git a/erpnext/public/js/utils/item_selector.js b/erpnext/public/js/utils/item_selector.js
index 9fc2640..e74d291 100644
--- a/erpnext/public/js/utils/item_selector.js
+++ b/erpnext/public/js/utils/item_selector.js
@@ -97,14 +97,14 @@
 		}
 
 		var me = this;
-		frappe.link_search("Item", args, function(r) {
-			$.each(r.values, function(i, d) {
+		frappe.link_search("Item", args, function(results) {
+			$.each(results, function(i, d) {
 				if(!d.image) {
 					d.abbr = frappe.get_abbr(d.item_name);
 					d.color = frappe.get_palette(d.item_name);
 				}
 			});
-			me.dialog.results.html(frappe.render_template('item_selector', {'data':r.values}));
+			me.dialog.results.html(frappe.render_template('item_selector', {'data': results}));
 		});
 	}
 };
diff --git a/erpnext/public/js/wishlist.js b/erpnext/public/js/wishlist.js
deleted file mode 100644
index f6599e9..0000000
--- a/erpnext/public/js/wishlist.js
+++ /dev/null
@@ -1,204 +0,0 @@
-frappe.provide("erpnext.e_commerce.wishlist");
-var wishlist = erpnext.e_commerce.wishlist;
-
-frappe.provide("erpnext.e_commerce.shopping_cart");
-var shopping_cart = erpnext.e_commerce.shopping_cart;
-
-$.extend(wishlist, {
-	set_wishlist_count: function(animate=false) {
-		// set badge count for wishlist icon
-		var wish_count = frappe.get_cookie("wish_count");
-		if (frappe.session.user==="Guest") {
-			wish_count = 0;
-		}
-
-		if (wish_count) {
-			$(".wishlist").toggleClass('hidden', false);
-		}
-
-		var $wishlist = $('.wishlist-icon');
-		var $badge = $wishlist.find("#wish-count");
-
-		if (parseInt(wish_count) === 0 || wish_count === undefined) {
-			$wishlist.css("display", "none");
-		} else {
-			$wishlist.css("display", "inline");
-		}
-		if (wish_count) {
-			$badge.html(wish_count);
-			if (animate) {
-				$wishlist.addClass('cart-animate');
-				setTimeout(() => {
-					$wishlist.removeClass('cart-animate');
-				}, 500);
-			}
-		} else {
-			$badge.remove();
-		}
-	},
-
-	bind_move_to_cart_action: function() {
-		// move item to cart from wishlist
-		$('.page_content').on("click", ".btn-add-to-cart", (e) => {
-			const $move_to_cart_btn = $(e.currentTarget);
-			let item_code = $move_to_cart_btn.data("item-code");
-
-			shopping_cart.shopping_cart_update({
-				item_code,
-				qty: 1,
-				cart_dropdown: true
-			});
-
-			let success_action = function() {
-				const $card_wrapper = $move_to_cart_btn.closest(".wishlist-card");
-				$card_wrapper.addClass("wish-removed");
-			};
-			let args = { item_code: item_code };
-			this.add_remove_from_wishlist("remove", args, success_action, null, true);
-		});
-	},
-
-	bind_remove_action: function() {
-		// remove item from wishlist
-		let me = this;
-
-		$('.page_content').on("click", ".remove-wish", (e) => {
-			const $remove_wish_btn = $(e.currentTarget);
-			let item_code = $remove_wish_btn.data("item-code");
-
-			let success_action = function() {
-				const $card_wrapper = $remove_wish_btn.closest(".wishlist-card");
-				$card_wrapper.addClass("wish-removed");
-				if (frappe.get_cookie("wish_count") == 0) {
-					$(".page_content").empty();
-					me.render_empty_state();
-				}
-			};
-			let args = { item_code: item_code };
-			this.add_remove_from_wishlist("remove", args, success_action);
-		});
-	},
-
-	bind_wishlist_action() {
-		// 'wish'('like') or 'unwish' item in product listing
-		$('.page_content').on('click', '.like-action, .like-action-list', (e) => {
-			const $btn = $(e.currentTarget);
-			this.wishlist_action($btn);
-		});
-	},
-
-	wishlist_action(btn) {
-		const $wish_icon = btn.find('.wish-icon');
-		let me = this;
-
-		if (frappe.session.user==="Guest") {
-			if (localStorage) {
-				localStorage.setItem("last_visited", window.location.pathname);
-			}
-			this.redirect_guest();
-			return;
-		}
-
-		let success_action = function() {
-			erpnext.e_commerce.wishlist.set_wishlist_count(true);
-		};
-
-		if ($wish_icon.hasClass('wished')) {
-			// un-wish item
-			btn.removeClass("like-animate");
-			btn.addClass("like-action-wished");
-			this.toggle_button_class($wish_icon, 'wished', 'not-wished');
-
-			let args = { item_code: btn.data('item-code') };
-			let failure_action = function() {
-				me.toggle_button_class($wish_icon, 'not-wished', 'wished');
-			};
-			this.add_remove_from_wishlist("remove", args, success_action, failure_action);
-		} else {
-			// wish item
-			btn.addClass("like-animate");
-			btn.addClass("like-action-wished");
-			this.toggle_button_class($wish_icon, 'not-wished', 'wished');
-
-			let args = {item_code: btn.data('item-code')};
-			let failure_action = function() {
-				me.toggle_button_class($wish_icon, 'wished', 'not-wished');
-			};
-			this.add_remove_from_wishlist("add", args, success_action, failure_action);
-		}
-	},
-
-	toggle_button_class(button, remove, add) {
-		button.removeClass(remove);
-		button.addClass(add);
-	},
-
-	add_remove_from_wishlist(action, args, success_action, failure_action, async=false) {
-		/*	AJAX call to add or remove Item from Wishlist
-			action: "add" or "remove"
-			args: args for method (item_code, price, formatted_price),
-			success_action: method to execute on successs,
-			failure_action: method to execute on failure,
-			async: make call asynchronously (true/false).	*/
-		if (frappe.session.user==="Guest") {
-			if (localStorage) {
-				localStorage.setItem("last_visited", window.location.pathname);
-			}
-			this.redirect_guest();
-		} else {
-			let method = "erpnext.e_commerce.doctype.wishlist.wishlist.add_to_wishlist";
-			if (action === "remove") {
-				method = "erpnext.e_commerce.doctype.wishlist.wishlist.remove_from_wishlist";
-			}
-
-			frappe.call({
-				async: async,
-				type: "POST",
-				method: method,
-				args: args,
-				callback: function (r) {
-					if (r.exc) {
-						if (failure_action && (typeof failure_action === 'function')) {
-							failure_action();
-						}
-						frappe.msgprint({
-							message: __("Sorry, something went wrong. Please refresh."),
-							indicator: "red", title: __("Note")
-						});
-					} else if (success_action && (typeof success_action === 'function')) {
-						success_action();
-					}
-				}
-			});
-		}
-	},
-
-	redirect_guest() {
-		frappe.call('erpnext.e_commerce.api.get_guest_redirect_on_action').then((res) => {
-			window.location.href = res.message || "/login";
-		});
-	},
-
-	render_empty_state() {
-		$(".page_content").append(`
-			<div class="cart-empty frappe-card">
-				<div class="cart-empty-state">
-					<img src="/assets/erpnext/images/ui-states/cart-empty-state.png" alt="Empty Cart">
-				</div>
-				<div class="cart-empty-message mt-4">${ __('Wishlist is empty !') }</p>
-			</div>
-		`);
-	}
-
-});
-
-frappe.ready(function() {
-	if (window.location.pathname !== "/wishlist") {
-		$(".wishlist").toggleClass('hidden', true);
-		wishlist.set_wishlist_count();
-	} else {
-		wishlist.bind_move_to_cart_action();
-		wishlist.bind_remove_action();
-	}
-
-});
\ No newline at end of file
diff --git a/erpnext/public/scss/erpnext-web.bundle.scss b/erpnext/public/scss/erpnext-web.bundle.scss
index 6ef1892..18d7c6c 100644
--- a/erpnext/public/scss/erpnext-web.bundle.scss
+++ b/erpnext/public/scss/erpnext-web.bundle.scss
@@ -1,2 +1 @@
-@import "./shopping_cart";
 @import "./website";
diff --git a/erpnext/public/scss/shopping_cart.scss b/erpnext/public/scss/shopping_cart.scss
deleted file mode 100644
index 6ae464d..0000000
--- a/erpnext/public/scss/shopping_cart.scss
+++ /dev/null
@@ -1,1381 +0,0 @@
-@import "frappe/public/scss/common/mixins";
-
-:root {
-	--green-info: #38A160;
-	--product-bg-color: white;
-	--body-bg-color:  var(--gray-50);
-}
-
-body.product-page {
-	background: var(--body-bg-color);
-}
-
-.item-breadcrumbs {
-	.breadcrumb-container {
-		a {
-			color: var(--gray-900);
-		}
-	}
-}
-
-.carousel-control {
-	height: 42px;
-	width: 42px;
-	display: flex;
-	align-items: center;
-	justify-content: center;
-	background: white;
-	box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.08), 0px 1px 2px 1px rgba(0, 0, 0, 0.06);
-	border-radius: 100px;
-}
-
-.carousel-control-prev,
-.carousel-control-next {
-	opacity: 1;
-	width: 8%;
-
-	@media (max-width: 1200px) {
-		width: 10%;
-	}
-	@media (max-width: 768px) {
-		width: 15%;
-	}
-}
-
-.carousel-body {
-	position: absolute;
-	top: 0;
-	left: 0;
-	right: 0;
-	bottom: 0;
-}
-
-.carousel-content {
-	max-width: 400px;
-	margin-left: 5rem;
-	margin-right: 5rem;
-}
-
-.card {
-	border: none;
-}
-
-.product-category-section {
-	.card:hover {
-		box-shadow: 0px 16px 45px 6px rgba(0, 0, 0, 0.08), 0px 8px 10px -10px rgba(0, 0, 0, 0.04);
-	}
-
-	.card-grid {
-		display: grid;
-		grid-gap: 15px;
-		grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
-	}
-}
-
-.no-image-item {
-	height: 340px;
-	width: 340px;
-	background: var(--gray-100);
-	border-radius: var(--border-radius);
-	font-size: 2rem;
-	color: var(--gray-500);
-	display: flex;
-	align-items: center;
-	justify-content: center;
-}
-
-.item-card-group-section {
-	.card {
-		height: 100%;
-		align-items: center;
-		justify-content: center;
-
-		&:hover {
-			box-shadow: 0px 16px 60px rgba(0, 0, 0, 0.08), 0px 8px 30px -20px rgba(0, 0, 0, 0.04);
-			transition: box-shadow 400ms;
-		}
-	}
-
-	.card:hover, .card:focus-within {
-		.btn-add-to-cart-list {
-			visibility: visible;
-		}
-		.like-action {
-			visibility: visible;
-		}
-		.btn-explore-variants {
-			visibility: visible;
-		}
-	}
-
-
-	.card-img-container {
-		height: 210px;
-		width: 100%;
-	}
-
-	.card-img {
-		max-height: 210px;
-		object-fit: contain;
-		margin-top: 1.25rem;
-	}
-
-	.no-image {
-		@include flex(flex, center, center, null);
-		height: 220px;
-		background: var(--gray-100);
-		width: 100%;
-		border-radius: var(--border-radius) var(--border-radius) 0 0;
-		font-size: 2rem;
-		color: var(--gray-500);
-	}
-
-	.no-image-list {
-		@include flex(flex, center, center, null);
-		height: 150px;
-		background: var(--gray-100);
-		border-radius: var(--border-radius);
-		font-size: 2rem;
-		color: var(--gray-500);
-		margin-top: 15px;
-		margin-bottom: 15px;
-	}
-
-	.card-body-flex {
-		display: flex;
-		flex-direction: column;
-	}
-
-	.product-title {
-		font-size: 14px;
-		color: var(--gray-800);
-		font-weight: 500;
-	}
-
-	.product-description {
-		font-size: 12px;
-		color: var(--text-color);
-		margin: 20px 0;
-		display: -webkit-box;
-		-webkit-line-clamp: 6;
-		-webkit-box-orient: vertical;
-
-		p {
-			margin-bottom: 0.5rem;
-		}
-	}
-
-	.product-category {
-		font-size: 13px;
-		color: var(--text-muted);
-		margin: var(--margin-sm) 0;
-	}
-
-	.product-price {
-		font-size: 18px;
-		font-weight: 600;
-		color: var(--text-color);
-		margin: var(--margin-sm) 0;
-		margin-bottom: auto !important;
-
-		.striked-price {
-			font-weight: 500;
-			font-size: 15px;
-			color: var(--gray-500);
-		}
-	}
-
-	.product-info-green {
-		color: var(--green-info);
-		font-weight: 600;
-	}
-
-	.item-card {
-		padding: var(--padding-sm);
-		min-width: 300px;
-	}
-
-	.wishlist-card {
-		padding: var(--padding-sm);
-		min-width: 260px;
-		.card-body-flex {
-			display: flex;
-			flex-direction: column;
-		}
-	}
-}
-
-#products-list-area, #products-grid-area {
-	padding: 0 5px;
-}
-
-.list-row {
-	background-color: white;
-	padding-bottom: 1rem;
-	padding-top: 1.5rem !important;
-	border-radius: 8px;
-	border-bottom: 1px solid var(--gray-50);
-
-	&:hover, &:focus-within {
-		box-shadow: 0px 16px 60px rgba(0, 0, 0, 0.08), 0px 8px 30px -20px rgba(0, 0, 0, 0.04);
-		transition: box-shadow 400ms;
-
-		.btn-add-to-cart-list {
-			visibility: visible;
-		}
-		.like-action-list {
-			visibility: visible;
-		}
-		.btn-explore-variants {
-			visibility: visible;
-		}
-	}
-
-	.product-code {
-		padding-top: 0 !important;
-	}
-
-	.btn-explore-variants {
-		min-width: 135px;
-		max-height: 30px;
-		float: right;
-		padding: 0.25rem 1rem;
-	}
-}
-
-[data-doctype="Item Group"],
-#page-index {
-	.page-header {
-		font-size: 20px;
-		font-weight: 700;
-		color: var(--text-color);
-	}
-
-	.filters-section {
-		.title-section {
-			border-bottom: 1px solid var(--table-border-color);
-		}
-
-		.filter-title {
-			font-weight: 500;
-		}
-
-		.clear-filters {
-			font-size: 13px;
-		}
-
-		.filter-lookup-input {
-			background-color: white;
-			border: 1px solid var(--gray-300);
-
-			&:focus {
-				border: 1px solid var(--primary);
-			}
-		}
-
-		.filter-label {
-			font-size: 11px;
-			font-weight: 600;
-			color: var(--gray-700);
-			text-transform: uppercase;
-		}
-
-		.filter-block {
-			border-bottom: 1px solid var(--table-border-color);
-		}
-
-		.checkbox {
-			.label-area {
-				font-size: 13px;
-				color: var(--gray-800);
-			}
-		}
-	}
-}
-
-.product-filter {
-	width: 14px !important;
-	height: 14px !important;
-}
-
-.discount-filter {
-	&:before {
-		width: 14px !important;
-		height: 14px !important;
-	}
-}
-
-.list-image {
-	border: none !important;
-	overflow: hidden;
-	max-height: 200px;
-	background-color: white;
-}
-
-.product-container {
-	@include card($padding: var(--padding-md));
-	background-color: var(--product-bg-color) !important;
-	min-height: fit-content;
-
-	.product-details {
-		max-width: 50%;
-
-		.btn-add-to-cart {
-			font-size: 14px;
-		}
-	}
-
-	&.item-main {
-		.product-image {
-			width: 100%;
-		}
-	}
-
-	.expand {
-		max-width: 100% !important; // expand in absence of slideshow
-	}
-
-	@media (max-width: 789px) {
-		.product-details {
-			max-width: 90% !important;
-
-			.btn-add-to-cart {
-				font-size: 14px;
-			}
-		}
-	}
-
-	.btn-add-to-wishlist {
-		svg use {
-			--icon-stroke: #F47A7A;
-		}
-	}
-
-	.btn-view-in-wishlist {
-		svg use {
-			fill: #F47A7A;
-			--icon-stroke: none;
-		}
-	}
-
-	.product-title {
-		font-size: 16px;
-		font-weight: 600;
-		color: var(--text-color);
-		padding: 0 !important;
-	}
-
-	.product-description {
-		font-size: 13px;
-		color: var(--gray-800);
-	}
-
-	.product-image {
-		border-color: var(--table-border-color) !important;
-		padding: 15px;
-
-		@media (max-width: var(--md-width)) {
-			height: 300px;
-			width: 300px;
-		}
-
-		@media (min-width: var(--lg-width)) {
-			height: 350px;
-			width: 350px;
-		}
-
-	 	img {
-			object-fit: contain;
-		}
-	}
-
-	.item-slideshow {
-
-		@media (max-width: var(--md-width)) {
-			max-height: 320px;
-		}
-
-		@media (min-width: var(--lg-width)) {
-			max-height: 430px;
-		}
-
-		overflow: auto;
-	}
-
-	.item-slideshow-image {
-		height: 4rem;
-		width: 6rem;
-		object-fit: contain;
-		padding: 0.5rem;
-		border: 1px solid var(--table-border-color);
-		border-radius: 4px;
-		cursor: pointer;
-
-		&:hover, &.active {
-			border-color: var(--primary);
-		}
-	}
-
-	.item-cart {
-		.product-price {
-			font-size: 22px;
-			color: var(--text-color);
-			font-weight: 600;
-
-			.formatted-price {
-				color: var(--text-muted);
-				font-size: 14px;
-			}
-		}
-
-		.no-stock {
-			font-size: var(--text-base);
-		}
-
-		.offers-heading {
-			font-size: 16px !important;
-			color: var(--text-color);
-			.tag-icon {
-				--icon-stroke: var(--gray-500);
-			}
-		}
-
-		.w-30-40 {
-			width: 30%;
-
-			@media (max-width: 992px) {
-				width: 40%;
-			}
-		}
-	}
-
-	.tab-content {
-		font-size: 14px;
-	}
-}
-
-// Item Recommendations
-.recommended-item-section {
-	padding-right: 0;
-
-	.recommendation-header {
-		font-size: 16px;
-		font-weight: 500
-	}
-
-	.recommendation-container {
-		padding: .5rem;
-		min-height: 0px;
-
-		.r-item-image {
-			min-height: 100px;
-			width: 40%;
-
-			.r-product-image {
-				padding: 2px 15px;
-			}
-
-			.no-image-r-item {
-				display: flex; justify-content: center;
-				background-color: var(--gray-200);
-				align-items: center;
-				color: var(--gray-400);
-				margin-top: .15rem;
-				border-radius: 6px;
-				height: 100%;
-				font-size: 24px;
-			}
-		}
-
-		.r-item-info {
-			font-size: 14px;
-			padding-right: 0;
-			padding-left: 10px;
-			width: 60%;
-
-			a {
-				color: var(--gray-800);
-				font-weight: 400;
-			}
-
-			.item-price {
-				font-size: 15px;
-				font-weight: 600;
-				color: var(--text-color);
-			}
-
-			.striked-item-price {
-				font-weight: 500;
-				color: var(--gray-500);
-			}
-		}
-	}
-}
-
-.product-code {
-	padding: .5rem 0;
-	color: var(--text-muted);
-	font-size: 14px;
-	.product-item-group {
-		padding-right: .25rem;
-		border-right: solid 1px var(--text-muted);
-	}
-
-	.product-item-code {
-		padding-left: .5rem;
-	}
-}
-
-.item-configurator-dialog {
-	.modal-body {
-		padding-bottom: var(--padding-xl);
-
-		.status-area {
-			.alert {
-				padding: var(--padding-xs) var(--padding-sm);
-				font-size: var(--text-sm);
-			}
-		}
-
-		.form-layout {
-			max-height: 50vh;
-			overflow-y: auto;
-		}
-
-		.section-body {
-			.form-column {
-				.form-group {
-					.control-label {
-						font-size: var(--text-md);
-						color: var(--gray-700);
-					}
-
-					.help-box {
-						margin-top: 2px;
-						font-size: var(--text-sm);
-					}
-				}
-			}
-		}
-	}
-}
-
-.item-group-slideshow {
-
-	.carousel-inner.rounded-carousel {
-		border-radius: var(--card-border-radius);
-	}
-}
-
-.sub-category-container {
-	padding-bottom: .5rem;
-	margin-bottom: 1.25rem;
-	border-bottom: 1px solid var(--table-border-color);
-
-	.heading {
-		color: var(--gray-500);
-	}
-}
-
-.scroll-categories {
-	.category-pill {
-		display: inline-block;
-		width: fit-content;
-		padding: 6px 12px;
-		margin-bottom: 8px;
-		background-color: #ecf5fe;
-		font-size: 14px;
-		border-radius: 18px;
-		color: var(--blue-500);
-	}
-}
-
-
-.shopping-badge {
-	position: relative;
-	top: -10px;
-	left: -12px;
-	background: var(--red-600);
-	align-items: center;
-	height: 16px;
-	font-size: 10px;
-	border-radius: 50%;
-}
-
-
-.cart-animate {
-	animation: wiggle 0.5s linear;
-}
-@keyframes wiggle {
-	8%,
-	41% {
-		transform: translateX(-10px);
-	}
-	25%,
-	58% {
-		transform: translate(10px);
-	}
-	75% {
-		transform: translate(-5px);
-	}
-	92% {
-		transform: translate(5px);
-	}
-	0%,
-	100% {
-		transform: translate(0);
-	}
-}
-
-.total-discount {
-	font-size: 14px;
-	color: var(--primary-color) !important;
-}
-
-#page-cart {
-	.shopping-cart-header {
-		font-weight: bold;
-	}
-
-	.cart-container {
-		color: var(--text-color);
-
-		.frappe-card {
-			display: flex;
-			flex-direction: column;
-			justify-content: space-between;
-			height: fit-content;
-		}
-
-		.cart-items-header {
-			font-weight: 600;
-		}
-
-		.cart-table {
-			tr {
-				margin-bottom: 1rem;
-			}
-
-			th, tr, td {
-				border-color: var(--border-color);
-				border-width: 1px;
-			}
-
-			th {
-				font-weight: normal;
-				font-size: 13px;
-				color: var(--text-muted);
-				padding: var(--padding-sm) 0;
-			}
-
-			td {
-				padding: var(--padding-sm) 0;
-				color: var(--text-color);
-			}
-
-			.cart-item-image {
-				width: 20%;
-				min-width: 100px;
-				img {
-					max-height: 112px;
-				}
-			}
-
-			.cart-items {
-				.item-title {
-					width: 80%;
-					font-size: 14px;
-					font-weight: 500;
-					color: var(--text-color);
-				}
-
-				.item-subtitle {
-					color: var(--text-muted);
-					font-size: 13px;
-				}
-
-				.item-subtotal {
-					font-size: 14px;
-					font-weight: 500;
-				}
-
-				.sm-item-subtotal {
-					font-size: 14px;
-					font-weight: 500;
-					display: none;
-
-					@media (max-width: 992px) {
-						display: unset !important;
-					}
-				}
-
-				.item-rate {
-					font-size: 13px;
-					color: var(--text-muted);
-				}
-
-				.free-tag {
-					padding: 4px 8px;
-					border-radius: 4px;
-					background-color: var(--dark-green-50);
-				}
-
-				textarea {
-					width: 80%;
-					height: 60px;
-					font-size: 14px;
-				}
-
-			}
-
-			.cart-tax-items {
-				.item-grand-total {
-					font-size: 16px;
-					font-weight: 700;
-					color: var(--text-color);
-				}
-			}
-
-			.column-sm-view {
-				@media (max-width: 992px) {
-					display: none !important;
-				}
-			}
-
-			.item-column {
-				width: 50%;
-				@media (max-width: 992px) {
-					width: 70%;
-				}
-			}
-
-			.remove-cart-item {
-				border-radius: 6px;
-				border: 1px solid var(--gray-100);
-				width: 28px;
-				height: 28px;
-				font-weight: 300;
-				color: var(--gray-700);
-				background-color: var(--gray-100);
-				float: right;
-				cursor: pointer;
-				margin-top: .25rem;
-				justify-content: center;
-			}
-
-			.remove-cart-item-logo {
-				margin-top: 2px;
-				margin-left: 2.2px;
-				fill: var(--gray-700) !important;
-			}
-		}
-
-		.cart-payment-addresses {
-			hr {
-				border-color: var(--border-color);
-			}
-		}
-
-		.payment-summary {
-			h6 {
-				padding-bottom: 1rem;
-				border-bottom: solid 1px var(--gray-200);
-			}
-
-			table {
-				font-size: 14px;
-				td {
-					padding: 0;
-					padding-top: 0.35rem !important;
-					border: none !important;
-				}
-
-				&.grand-total {
-					border-top: solid 1px var(--gray-200);
-				}
-			}
-
-			.bill-label {
-				color: var(--gray-600);
-			}
-
-			.bill-content {
-				font-weight: 500;
-				&.net-total {
-					font-size: 16px;
-					font-weight: 600;
-				}
-			}
-
-			.btn-coupon-code {
-				font-size: 14px;
-				border: dashed 1px var(--gray-400);
-				box-shadow: none;
-			}
-		}
-
-		.number-spinner {
-			width: 75%;
-			min-width: 105px;
-			.cart-btn {
-				border: none;
-				background: var(--gray-100);
-				box-shadow: none;
-				width: 24px;
-				height: 28px;
-				align-items: center;
-				justify-content: center;
-				display: flex;
-				font-size: 20px;
-				font-weight: 300;
-				color: var(--gray-700);
-			}
-
-			.cart-qty {
-				height: 28px;
-				font-size: 13px;
-				&:disabled {
-					background: var(--gray-100);
-					opacity: 0.65;
-				}
-			}
-		}
-
-		.place-order-container {
-			.btn-place-order {
-				float: right;
-			}
-		}
-	}
-
-	.t-and-c-container {
-		padding: 1.5rem;
-	}
-
-	.t-and-c-terms {
-		font-size: 14px;
-	}
-}
-
-.no-image-cart-item {
-	max-height: 112px;
-	display: flex; justify-content: center;
-	background-color: var(--gray-200);
-	align-items: center;
-	color: var(--gray-400);
-	margin-top: .15rem;
-	border-radius: 6px;
-	height: 100%;
-	font-size: 24px;
-}
-
-.cart-empty.frappe-card {
-	min-height: 76vh;
-	@include flex(flex, center, center, column);
-
-	.cart-empty-message {
-		font-size: 18px;
-		color: var(--text-color);
-		font-weight: bold;
-	}
-}
-
-.address-card {
-	.card-title {
-		font-size: 14px;
-		font-weight: 500;
-	}
-
-	.card-body {
-		max-width: 80%;
-	}
-
-	.card-text {
-		font-size: 13px;
-		color: var(--gray-700);
-	}
-
-	.card-link {
-		font-size: 13px;
-
-		svg use {
-			stroke: var(--primary-color);
-		}
-	}
-
-	.btn-change-address {
-		border: 1px solid var(--primary-color);
-		color: var(--primary-color);
-		box-shadow: none;
-	}
-}
-
-.address-header {
-	margin-top: .15rem;padding: 0;
-}
-
-.btn-new-address {
-	float: right;
-	font-size: 15px !important;
-	color: var(--primary-color) !important;
-}
-
-.btn-new-address:hover, .btn-change-address:hover {
-	color: var(--primary-color) !important;
-}
-
-.modal .address-card {
-	.card-body {
-		padding: var(--padding-sm);
-		border-radius: var(--border-radius);
-		border: 1px solid var(--dark-border-color);
-	}
-}
-
-.cart-indicator {
-	position: absolute;
-	text-align: center;
-	width: 22px;
-	height: 22px;
-	left: calc(100% - 40px);
-	top: 22px;
-
-	border-radius: 66px;
-	box-shadow: 0px 2px 6px rgba(17, 43, 66, 0.08), 0px 1px 4px rgba(17, 43, 66, 0.1);
-	background: white;
-	color: var(--primary-color);
-	font-size: 14px;
-
-	&.list-indicator {
-		position: unset;
-		margin-left: auto;
-	}
-}
-
-
-.like-action {
-	visibility: hidden;
-	text-align: center;
-	position: absolute;
-	cursor: pointer;
-	width: 28px;
-	height: 28px;
-	left: 20px;
-	top: 20px;
-
-	/* White */
-	background: white;
-	box-shadow: 0px 2px 6px rgba(17, 43, 66, 0.08), 0px 1px 4px rgba(17, 43, 66, 0.1);
-	border-radius: 66px;
-
-	&.like-action-wished {
-		visibility: visible !important;
-	}
-
-	@media (max-width: 992px) {
-		visibility: visible !important;
-	}
-}
-
-.like-action-list {
-	visibility: hidden;
-	text-align: center;
-	position: absolute;
-	cursor: pointer;
-	width: 28px;
-	height: 28px;
-	left: 20px;
-	top: 0;
-
-	/* White */
-	background: white;
-	box-shadow: 0px 2px 6px rgba(17, 43, 66, 0.08), 0px 1px 4px rgba(17, 43, 66, 0.1);
-	border-radius: 66px;
-
-	&.like-action-wished {
-		visibility: visible !important;
-	}
-
-	@media (max-width: 992px) {
-		visibility: visible !important;
-	}
-}
-
-.like-action-item-fp {
-	visibility: visible !important;
-	position: unset;
-	float: right;
-}
-
-.like-animate {
-	animation: expand cubic-bezier(0.04, 0.4, 0.5, 0.95) 1.6s forwards 1;
-}
-
-@keyframes expand {
-	30% {
-	  transform: scale(1.3);
-	}
-	50% {
-	  transform: scale(0.8);
-	}
-	70% {
-		transform: scale(1.1);
-	}
-	100% {
-	  transform: scale(1);
-	}
-  }
-
-.not-wished {
-	cursor: pointer;
-	--icon-stroke: #F47A7A !important;
-
-	&:hover {
-		fill: #F47A7A;
-	}
-}
-
-.wished {
-	--icon-stroke: none;
-	fill: #F47A7A !important;
-}
-
-.list-row-checkbox {
-	&:before {
-		display: none;
-	}
-
-	&:checked:before {
-		display: block;
-		z-index: 1;
-	}
-}
-
-#pay-for-order {
-	padding: .5rem 1rem; // Pay button in SO
-}
-
-.btn-explore-variants {
-	visibility: hidden;
-	box-shadow: none;
-	margin: var(--margin-sm) 0;
-	width: 90px;
-	max-height: 50px; // to avoid resizing on window resize
-	flex: none;
-	transition: 0.3s ease;
-
-	color: white;
-	background-color: var(--orange-500);
-	border: 1px solid var(--orange-500);
-	font-size: 13px;
-
-	&:hover {
-		color: white;
-	}
-}
-
-.btn-add-to-cart-list{
-	visibility: hidden;
-	box-shadow: none;
-	margin: var(--margin-sm) 0;
-	// margin-top: auto !important;
-	max-height: 50px; // to avoid resizing on window resize
-	flex: none;
-	transition: 0.3s ease;
-
-	font-size: 13px;
-
-	&:hover {
-		color: white;
-	}
-
-	@media (max-width: 992px) {
-		visibility: visible !important;
-	}
-}
-
-.go-to-cart-grid {
-	max-height: 30px;
-	margin-top: 1rem !important;
-}
-
-.go-to-cart {
-	max-height: 30px;
-	float: right;
-}
-
-.remove-wish {
-	background-color: white;
-	position: absolute;
-	cursor: pointer;
-	top:10px;
-	right: 20px;
-	width: 32px;
-	height: 32px;
-
-	border-radius: 50%;
-	border: 1px solid var(--gray-100);
-	box-shadow: 0px 2px 6px rgba(17, 43, 66, 0.08), 0px 1px 4px rgba(17, 43, 66, 0.1);
-}
-
-.wish-removed {
-	display: none;
-}
-
-.item-website-specification {
-	font-size: .875rem;
-	.product-title {
-		font-size: 18px;
-	}
-
-	.table {
-		width: 70%;
-	}
-
-	td {
-		border: none !important;
-	}
-
-	.spec-label {
-		color: var(--gray-600);
-	}
-
-	.spec-content {
-		color: var(--gray-800);
-	}
-}
-
-.reviews-full-page {
-	padding: 1rem 2rem;
-}
-
-.ratings-reviews-section {
-	border-top: 1px solid #E2E6E9;
-	padding: .5rem 1rem;
-}
-
-.reviews-header {
-	font-size: 20px;
-	font-weight: 600;
-	color: var(--gray-800);
-	display: flex;
-	align-items: center;
-	padding: 0;
-}
-
-.btn-write-review {
-	float: right;
-	padding: .5rem 1rem;
-	font-size: 14px;
-	font-weight: 400;
-	border: none !important;
-	box-shadow: none;
-
-	color: var(--gray-900);
-	background-color: var(--gray-100);
-
-	&:hover {
-		box-shadow: var(--btn-shadow);
-	}
-}
-
-.btn-view-more {
-	font-size: 14px;
-}
-
-.rating-summary-section {
-	display: flex;
-}
-
-.rating-summary-title {
-	margin-top: 0.15rem;
-	font-size: 18px;
-}
-
-.rating-summary-numbers {
-	display: flex;
-	flex-direction: column;
-	align-items: center;
-
-	border-right: solid 1px var(--gray-100);
-}
-
-.user-review-title {
-	margin-top: 0.15rem;
-	font-size: 15px;
-	font-weight: 600;
-}
-
-.rating {
-	--star-fill: var(--gray-300);
-	.star-hover {
-		--star-fill: var(--yellow-100);
-	}
-	.star-click {
-		--star-fill: var(--yellow-300);
-	}
-}
-
-.ratings-pill {
-	background-color: var(--gray-100);
-	padding: .5rem 1rem;
-	border-radius: 66px;
-}
-
-.review {
-	max-width: 80%;
-	line-height: 1.6;
-	padding-bottom: 0.5rem;
-	border-bottom: 1px solid #E2E6E9;
-}
-
-.review-signature {
-	display: flex;
-	font-size: 13px;
-	color: var(--gray-500);
-	font-weight: 400;
-
-	.reviewer {
-		padding-right: 8px;
-		color: var(--gray-600);
-	}
-}
-
-.rating-progress-bar-section {
-	padding-bottom: 2rem;
-
-	.rating-bar-title {
-		margin-left: -15px;
-	}
-
-	.rating-progress-bar {
-		margin-bottom: 4px;
-		height: 7px;
-		margin-top: 6px;
-
-		.progress-bar-cosmetic {
-			background-color: var(--gray-600);
-			border-radius: var(--border-radius);
-		}
-	}
-}
-
-.offer-container {
-	font-size: 14px;
-}
-
-#search-results-container {
-	border: 1px solid var(--gray-200);
-	padding: .25rem 1rem;
-
-	.category-chip {
-		background-color: var(--gray-100);
-		border: none !important;
-		box-shadow: none;
-	}
-
-	.recent-search {
-		padding: .5rem .5rem;
-		border-radius: var(--border-radius);
-
-		&:hover {
-			background-color: var(--gray-100);
-		}
-	}
-}
-
-#search-box {
-	background-color: white;
-	height: 100%;
-	padding-left: 2.5rem;
-	border: 1px solid var(--gray-200);
-}
-
-.search-icon {
-	position: absolute;
-	left: 0;
-	top: 0;
-	width: 2.5rem;
-	height: 100%;
-	display: flex;
-	justify-content: center;
-	align-items: center;
-	padding-bottom: 1px;
-}
-
-#toggle-view {
-	float: right;
-
-	.btn-primary {
-		background-color: var(--gray-600);
-		box-shadow: 0 0 0 0.2rem var(--gray-400);
-	}
-}
-
-.placeholder-div {
-	height:80%;
-	width: -webkit-fill-available;
-	padding: 50px;
-	text-align: center;
-	background-color: #F9FAFA;
-	border-top-left-radius: calc(0.75rem - 1px);
-	border-top-right-radius: calc(0.75rem - 1px);
-}
-.placeholder {
-	font-size: 72px;
-}
-
-[data-path="cart"] {
-	.modal-backdrop {
-		background-color: var(--gray-50); // lighter backdrop only on cart freeze
-	}
-}
-
-.item-thumb {
-	height: 50px;
-	max-width: 80px;
-	min-width: 80px;
-	object-fit: cover;
-}
-
-.brand-line {
-	color: gray;
-}
-
-.btn-next, .btn-prev {
-	font-size: 14px;
-}
-
-.alert-error {
-	color: #e27a84;
-	background-color: #fff6f7;
-	border-color: #f5c6cb;
-}
-
-.font-md {
-	font-size: 14px !important;
-}
-
-.in-green {
-	color: var(--green-info) !important;
-	font-weight: 500;
-}
-
-.has-stock {
-	font-weight: 400 !important;
-}
-
-.out-of-stock {
-	font-weight: 400;
-	font-size: 14px;
-	line-height: 20px;
-	color: #F47A7A;
-}
-
-.mt-minus-2 {
-	margin-top: -2rem;
-}
-
-.mt-minus-1 {
-	margin-top: -1rem;
-}
\ No newline at end of file
diff --git a/erpnext/regional/__init__.py b/erpnext/regional/__init__.py
index ec2db81..bd5d540 100644
--- a/erpnext/regional/__init__.py
+++ b/erpnext/regional/__init__.py
@@ -10,7 +10,7 @@
 
 def check_deletion_permission(doc, method):
 	region = get_region(doc.company)
-	if region in ["Nepal", "France"] and doc.docstatus != 0:
+	if region in ["Nepal"] and doc.docstatus != 0:
 		frappe.throw(_("Deletion is not permitted for country {0}").format(region))
 
 
@@ -20,7 +20,7 @@
 	Called on submit of Sales Invoice and Payment Entry.
 	"""
 	region = get_region()
-	if region not in ["France", "Germany"]:
+	if region not in ["Germany"]:
 		return
 
 	data = str(doc.as_dict())
diff --git a/erpnext/regional/address_template/templates/france.html b/erpnext/regional/address_template/templates/france.html
deleted file mode 100644
index 752331e..0000000
--- a/erpnext/regional/address_template/templates/france.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% if address_line1 %}{{ address_line1 }}{% endif -%}
-{% if address_line2 %}<br>{{ address_line2 }}{% endif -%}
-{% if pincode %}<br>{{ pincode }}{% endif -%}
-{% if city %} {{ city }}{% endif -%}
-{% if country %}<br>{{ country }}{% endif -%}
diff --git a/erpnext/regional/france/__init__.py b/erpnext/regional/france/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/regional/france/__init__.py
+++ /dev/null
diff --git a/erpnext/regional/france/setup.py b/erpnext/regional/france/setup.py
deleted file mode 100644
index da772d6..0000000
--- a/erpnext/regional/france/setup.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-
-import frappe
-from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
-
-
-def setup(company=None, patch=True):
-	make_custom_fields()
-	add_custom_roles_for_reports()
-
-
-def make_custom_fields():
-	custom_fields = {
-		"Company": [
-			dict(fieldname="siren_number", label="SIREN Number", fieldtype="Data", insert_after="website")
-		]
-	}
-
-	create_custom_fields(custom_fields)
-
-
-def add_custom_roles_for_reports():
-	report_name = "Fichier des Ecritures Comptables [FEC]"
-
-	if not frappe.db.get_value("Custom Role", dict(report=report_name)):
-		frappe.get_doc(
-			dict(doctype="Custom Role", report=report_name, roles=[dict(role="Accounts Manager")])
-		).insert()
diff --git a/erpnext/regional/france/utils.py b/erpnext/regional/france/utils.py
deleted file mode 100644
index 65dfd2d..0000000
--- a/erpnext/regional/france/utils.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright (c) 2018, Frappe Technologies and contributors
-# For license information, please see license.txt
-
-
-# don't remove this function it is used in tests
-def test_method():
-	"""test function"""
-	return "overridden"
diff --git "a/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/__init__.py" "b/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/__init__.py"
deleted file mode 100644
index e69de29..0000000
--- "a/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/__init__.py"
+++ /dev/null
diff --git "a/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.js" "b/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.js"
deleted file mode 100644
index b85b58f..0000000
--- "a/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.js"
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.query_reports["Fichier des Ecritures Comptables [FEC]"] = {
-	"filters": [
-		{
-			"fieldname": "company",
-			"label": __("Company"),
-			"fieldtype": "Link",
-			"options": "Company",
-			"default": frappe.defaults.get_user_default("Company"),
-			"reqd": 1
-		},
-		{
-			"fieldname": "fiscal_year",
-			"label": __("Fiscal Year"),
-			"fieldtype": "Link",
-			"options": "Fiscal Year",
-			"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
-			"reqd": 1
-		}
-	],
-	onload: function(query_report) {
-		query_report.page.add_inner_button(__("Export"), function() {
-			fec_export(query_report);
-		});
-
-		query_report.add_make_chart_button = function() {
-			//
-		};
-
-		query_report.export_report = function() {
-			fec_export(query_report);
-		};
-	}
-};
-
-let fec_export = function(query_report) {
-	const fiscal_year = query_report.get_values().fiscal_year;
-	const company = query_report.get_values().company;
-
-	frappe.db.get_value("Company", company, "siren_number", (value) => {
-		const company_data = value.siren_number;
-		if (company_data === null || company_data === undefined) {
-			frappe.msgprint(__("Please register the SIREN number in the company information file"));
-		} else {
-			frappe.db.get_value("Fiscal Year", fiscal_year, "year_end_date", (r) => {
-				const fy = r.year_end_date;
-				const title = company_data + "FEC" + moment(fy).format('YYYYMMDD');
-				const column_row = query_report.columns.map(col => col.label);
-				const column_data = query_report.get_data_for_csv(false);
-				const result = [column_row].concat(column_data);
-				downloadify(result, null, title);
-			});
-
-		}
-	});
-};
-
-let downloadify = function(data, roles, title) {
-	if (roles && roles.length && !has_common(roles, roles)) {
-		frappe.msgprint(__("Export not allowed. You need {0} role to export.", [frappe.utils.comma_or(roles)]));
-		return;
-	}
-
-	const filename = title + ".txt";
-	let csv_data = to_tab_csv(data);
-	const a = document.createElement('a');
-
-	if ("download" in a) {
-		// Used Blob object, because it can handle large files
-		let blob_object = new Blob([csv_data], {
-			type: 'text/csv;charset=UTF-8'
-		});
-		a.href = URL.createObjectURL(blob_object);
-		a.download = filename;
-
-	} else {
-		// use old method
-		a.href = 'data:attachment/csv,' + encodeURIComponent(csv_data);
-		a.download = filename;
-		a.target = "_blank";
-	}
-
-	document.body.appendChild(a);
-	a.click();
-
-	document.body.removeChild(a);
-};
-
-let to_tab_csv = function(data) {
-	let res = [];
-	$.each(data, function(i, row) {
-		res.push(row.join("\t"));
-	});
-	return res.join("\n");
-};
diff --git "a/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.json" "b/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.json"
deleted file mode 100644
index 9b48e11..0000000
--- "a/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.json"
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "add_total_row": 0, 
- "apply_user_permissions": 0, 
- "creation": "2018-01-10 15:10:16.650129", 
- "disabled": 0, 
- "docstatus": 0, 
- "doctype": "Report", 
- "idx": 0, 
- "is_standard": "Yes", 
- "modified": "2018-01-11 10:27:25.595485", 
- "modified_by": "Administrator", 
- "module": "Regional", 
- "name": "Fichier des Ecritures Comptables [FEC]", 
- "owner": "Administrator", 
- "ref_doctype": "GL Entry", 
- "report_name": "Fichier des Ecritures Comptables [FEC]", 
- "report_type": "Script Report", 
- "roles": []
-}
\ No newline at end of file
diff --git "a/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.py" "b/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.py"
deleted file mode 100644
index 6717989..0000000
--- "a/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.py"
+++ /dev/null
@@ -1,339 +0,0 @@
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-import re
-
-import frappe
-from frappe import _
-from frappe.utils import format_datetime
-
-COLUMNS = [
-	{
-		"label": "JournalCode",
-		"fieldname": "JournalCode",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-	{
-		"label": "JournalLib",
-		"fieldname": "JournalLib",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-	{
-		"label": "EcritureNum",
-		"fieldname": "EcritureNum",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-	{
-		"label": "EcritureDate",
-		"fieldname": "EcritureDate",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-	{
-		"label": "CompteNum",
-		"fieldname": "CompteNum",
-		"fieldtype": "Link",
-		"options": "Account",
-		"width": 100,
-	},
-	{
-		"label": "CompteLib",
-		"fieldname": "CompteLib",
-		"fieldtype": "Link",
-		"options": "Account",
-		"width": 200,
-	},
-	{
-		"label": "CompAuxNum",
-		"fieldname": "CompAuxNum",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-	{
-		"label": "CompAuxLib",
-		"fieldname": "CompAuxLib",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-	{
-		"label": "PieceRef",
-		"fieldname": "PieceRef",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-	{
-		"label": "PieceDate",
-		"fieldname": "PieceDate",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-	{
-		"label": "EcritureLib",
-		"fieldname": "EcritureLib",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-	{
-		"label": "Debit",
-		"fieldname": "Debit",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-	{
-		"label": "Credit",
-		"fieldname": "Credit",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-	{
-		"label": "EcritureLet",
-		"fieldname": "EcritureLet",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-	{
-		"label": "DateLet",
-		"fieldname": "DateLet",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-	{
-		"label": "ValidDate",
-		"fieldname": "ValidDate",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-	{
-		"label": "Montantdevise",
-		"fieldname": "Montantdevise",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-	{
-		"label": "Idevise",
-		"fieldname": "Idevise",
-		"fieldtype": "Data",
-		"width": 90,
-	},
-]
-
-
-def execute(filters=None):
-	validate_filters(filters)
-	return COLUMNS, get_result(
-		company=filters["company"],
-		fiscal_year=filters["fiscal_year"],
-	)
-
-
-def validate_filters(filters):
-	if not filters.get("company"):
-		frappe.throw(_("{0} is mandatory").format(_("Company")))
-
-	if not filters.get("fiscal_year"):
-		frappe.throw(_("{0} is mandatory").format(_("Fiscal Year")))
-
-
-def get_gl_entries(company, fiscal_year):
-	gle = frappe.qb.DocType("GL Entry")
-	sales_invoice = frappe.qb.DocType("Sales Invoice")
-	purchase_invoice = frappe.qb.DocType("Purchase Invoice")
-	journal_entry = frappe.qb.DocType("Journal Entry")
-	payment_entry = frappe.qb.DocType("Payment Entry")
-	customer = frappe.qb.DocType("Customer")
-	supplier = frappe.qb.DocType("Supplier")
-	employee = frappe.qb.DocType("Employee")
-
-	debit = frappe.query_builder.functions.Sum(gle.debit).as_("debit")
-	credit = frappe.query_builder.functions.Sum(gle.credit).as_("credit")
-	debit_currency = frappe.query_builder.functions.Sum(gle.debit_in_account_currency).as_(
-		"debitCurr"
-	)
-	credit_currency = frappe.query_builder.functions.Sum(gle.credit_in_account_currency).as_(
-		"creditCurr"
-	)
-
-	query = (
-		frappe.qb.from_(gle)
-		.left_join(sales_invoice)
-		.on(gle.voucher_no == sales_invoice.name)
-		.left_join(purchase_invoice)
-		.on(gle.voucher_no == purchase_invoice.name)
-		.left_join(journal_entry)
-		.on(gle.voucher_no == journal_entry.name)
-		.left_join(payment_entry)
-		.on(gle.voucher_no == payment_entry.name)
-		.left_join(customer)
-		.on(gle.party == customer.name)
-		.left_join(supplier)
-		.on(gle.party == supplier.name)
-		.left_join(employee)
-		.on(gle.party == employee.name)
-		.select(
-			gle.posting_date.as_("GlPostDate"),
-			gle.name.as_("GlName"),
-			gle.account,
-			gle.transaction_date,
-			debit,
-			credit,
-			debit_currency,
-			credit_currency,
-			gle.voucher_type,
-			gle.voucher_no,
-			gle.against_voucher_type,
-			gle.against_voucher,
-			gle.account_currency,
-			gle.against,
-			gle.party_type,
-			gle.party,
-			sales_invoice.name.as_("InvName"),
-			sales_invoice.title.as_("InvTitle"),
-			sales_invoice.posting_date.as_("InvPostDate"),
-			purchase_invoice.name.as_("PurName"),
-			purchase_invoice.title.as_("PurTitle"),
-			purchase_invoice.posting_date.as_("PurPostDate"),
-			journal_entry.cheque_no.as_("JnlRef"),
-			journal_entry.posting_date.as_("JnlPostDate"),
-			journal_entry.title.as_("JnlTitle"),
-			payment_entry.name.as_("PayName"),
-			payment_entry.posting_date.as_("PayPostDate"),
-			payment_entry.title.as_("PayTitle"),
-			customer.customer_name,
-			customer.name.as_("cusName"),
-			supplier.supplier_name,
-			supplier.name.as_("supName"),
-			employee.employee_name,
-			employee.name.as_("empName"),
-		)
-		.where((gle.company == company) & (gle.fiscal_year == fiscal_year))
-		.groupby(gle.voucher_type, gle.voucher_no, gle.account)
-		.orderby(gle.posting_date, gle.voucher_no)
-	)
-
-	return query.run(as_dict=True)
-
-
-def get_result(company, fiscal_year):
-	data = get_gl_entries(company, fiscal_year)
-
-	result = []
-
-	company_currency = frappe.get_cached_value("Company", company, "default_currency")
-	accounts = frappe.get_all(
-		"Account", filters={"Company": company}, fields=["name", "account_number"]
-	)
-
-	for d in data:
-		JournalCode = re.split("-|/|[0-9]", d.get("voucher_no"))[0]
-
-		if d.get("voucher_no").startswith("{0}-".format(JournalCode)) or d.get("voucher_no").startswith(
-			"{0}/".format(JournalCode)
-		):
-			EcritureNum = re.split("-|/", d.get("voucher_no"))[1]
-		else:
-			EcritureNum = re.search(r"{0}(\d+)".format(JournalCode), d.get("voucher_no"), re.IGNORECASE)[1]
-
-		EcritureDate = format_datetime(d.get("GlPostDate"), "yyyyMMdd")
-
-		account_number = [
-			account.account_number for account in accounts if account.name == d.get("account")
-		]
-		if account_number[0] is not None:
-			CompteNum = account_number[0]
-		else:
-			frappe.throw(
-				_(
-					"Account number for account {0} is not available.<br> Please setup your Chart of Accounts correctly."
-				).format(d.get("account"))
-			)
-
-		if d.get("party_type") == "Customer":
-			CompAuxNum = d.get("cusName")
-			CompAuxLib = d.get("customer_name")
-
-		elif d.get("party_type") == "Supplier":
-			CompAuxNum = d.get("supName")
-			CompAuxLib = d.get("supplier_name")
-
-		elif d.get("party_type") == "Employee":
-			CompAuxNum = d.get("empName")
-			CompAuxLib = d.get("employee_name")
-
-		elif d.get("party_type") == "Student":
-			CompAuxNum = d.get("stuName")
-			CompAuxLib = d.get("student_name")
-
-		elif d.get("party_type") == "Member":
-			CompAuxNum = d.get("memName")
-			CompAuxLib = d.get("member_name")
-
-		else:
-			CompAuxNum = ""
-			CompAuxLib = ""
-
-		ValidDate = format_datetime(d.get("GlPostDate"), "yyyyMMdd")
-
-		PieceRef = d.get("voucher_no") or "Sans Reference"
-
-		# EcritureLib is the reference title unless it is an opening entry
-		if d.get("is_opening") == "Yes":
-			EcritureLib = _("Opening Entry Journal")
-		if d.get("voucher_type") == "Sales Invoice":
-			EcritureLib = d.get("InvTitle")
-		elif d.get("voucher_type") == "Purchase Invoice":
-			EcritureLib = d.get("PurTitle")
-		elif d.get("voucher_type") == "Journal Entry":
-			EcritureLib = d.get("JnlTitle")
-		elif d.get("voucher_type") == "Payment Entry":
-			EcritureLib = d.get("PayTitle")
-		else:
-			EcritureLib = d.get("voucher_type")
-
-		PieceDate = format_datetime(d.get("GlPostDate"), "yyyyMMdd")
-
-		debit = "{:.2f}".format(d.get("debit")).replace(".", ",")
-
-		credit = "{:.2f}".format(d.get("credit")).replace(".", ",")
-
-		Idevise = d.get("account_currency")
-
-		if Idevise != company_currency:
-			Montantdevise = (
-				"{:.2f}".format(d.get("debitCurr")).replace(".", ",")
-				if d.get("debitCurr") != 0
-				else "{:.2f}".format(d.get("creditCurr")).replace(".", ",")
-			)
-		else:
-			Montantdevise = (
-				"{:.2f}".format(d.get("debit")).replace(".", ",")
-				if d.get("debit") != 0
-				else "{:.2f}".format(d.get("credit")).replace(".", ",")
-			)
-
-		row = [
-			JournalCode,
-			d.get("voucher_type"),
-			EcritureNum,
-			EcritureDate,
-			CompteNum,
-			d.get("account"),
-			CompAuxNum,
-			CompAuxLib,
-			PieceRef,
-			PieceDate,
-			EcritureLib,
-			debit,
-			credit,
-			"",
-			"",
-			ValidDate,
-			Montantdevise,
-			Idevise,
-		]
-
-		result.append(row)
-
-	return result
diff --git a/erpnext/regional/united_arab_emirates/utils.py b/erpnext/regional/united_arab_emirates/utils.py
index d70d546..a850d5b 100644
--- a/erpnext/regional/united_arab_emirates/utils.py
+++ b/erpnext/regional/united_arab_emirates/utils.py
@@ -7,32 +7,32 @@
 
 
 def update_itemised_tax_data(doc):
+	# maybe this should be a standard function rather than a regional one
 	if not doc.taxes:
 		return
 
+	if not doc.items:
+		return
+
+	meta = frappe.get_meta(doc.items[0].doctype)
+	if not meta.has_field("tax_rate"):
+		return
+
 	itemised_tax = get_itemised_tax(doc.taxes)
 
 	for row in doc.items:
-		tax_rate = 0.0
-		item_tax_rate = 0.0
+		tax_rate, tax_amount = 0.0, 0.0
+		# dont even bother checking in item tax template as it contains both input and output accounts - double the tax rate
+		item_code = row.item_code or row.item_name
+		if itemised_tax.get(item_code):
+			for tax in itemised_tax.get(row.item_code).values():
+				_tax_rate = flt(tax.get("tax_rate", 0), row.precision("tax_rate"))
+				tax_amount += flt((row.net_amount * _tax_rate) / 100, row.precision("tax_amount"))
+				tax_rate += _tax_rate
 
-		if row.item_tax_rate:
-			item_tax_rate = frappe.parse_json(row.item_tax_rate)
-
-		# First check if tax rate is present
-		# If not then look up in item_wise_tax_detail
-		if item_tax_rate:
-			for account, rate in item_tax_rate.items():
-				tax_rate += rate
-		elif row.item_code and itemised_tax.get(row.item_code):
-			tax_rate = sum([tax.get("tax_rate", 0) for d, tax in itemised_tax.get(row.item_code).items()])
-
-		meta = frappe.get_meta(row.doctype)
-
-		if meta.has_field("tax_rate"):
-			row.tax_rate = flt(tax_rate, row.precision("tax_rate"))
-			row.tax_amount = flt((row.net_amount * tax_rate) / 100, row.precision("net_amount"))
-			row.total_amount = flt((row.net_amount + row.tax_amount), row.precision("total_amount"))
+		row.tax_rate = flt(tax_rate, row.precision("tax_rate"))
+		row.tax_amount = flt(tax_amount, row.precision("tax_amount"))
+		row.total_amount = flt((row.net_amount + row.tax_amount), row.precision("total_amount"))
 
 
 def get_account_currency(account):
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index e274a52..42932ad 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -138,7 +138,7 @@
 			// custom buttons
 
 			frm.add_custom_button(__('Accounts Receivable'), function () {
-				frappe.set_route('query-report', 'Accounts Receivable', {customer:frm.doc.name});
+				frappe.set_route('query-report', 'Accounts Receivable', { party_type: "Customer", party: frm.doc.name });
 			}, __('View'));
 
 			frm.add_custom_button(__('Accounting Ledger'), function () {
diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json
index 0f42def..3b97123 100644
--- a/erpnext/selling/doctype/customer/customer.json
+++ b/erpnext/selling/doctype/customer/customer.json
@@ -134,7 +134,7 @@
    "label": "Customer Type",
    "oldfieldname": "customer_type",
    "oldfieldtype": "Select",
-   "options": "Company\nIndividual",
+   "options": "Company\nIndividual\nProprietorship\nPartnership",
    "reqd": 1
   },
   {
@@ -181,7 +181,6 @@
    "oldfieldname": "customer_group",
    "oldfieldtype": "Link",
    "options": "Customer Group",
-   "reqd": 1,
    "search_index": 1
   },
   {
@@ -193,8 +192,7 @@
    "oldfieldname": "territory",
    "oldfieldtype": "Link",
    "options": "Territory",
-   "print_hide": 1,
-   "reqd": 1
+   "print_hide": 1
   },
   {
    "fieldname": "tax_id",
@@ -586,7 +584,7 @@
    "link_fieldname": "party"
   }
  ],
- "modified": "2023-09-21 12:23:20.706020",
+ "modified": "2023-10-19 16:56:27.327035",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Customer",
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index d351c3c..a7a1aa2 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -15,14 +15,9 @@
 from frappe.model.naming import set_name_by_naming_series, set_name_from_naming_options
 from frappe.model.utils.rename_doc import update_linked_doctypes
 from frappe.utils import cint, cstr, flt, get_formatted_email, today
-from frappe.utils.nestedset import get_root_of
 from frappe.utils.user import get_users_with_role
 
-from erpnext.accounts.party import (  # noqa
-	get_dashboard_info,
-	get_timeline_data,
-	validate_party_accounts,
-)
+from erpnext.accounts.party import get_dashboard_info, validate_party_accounts  # noqa
 from erpnext.controllers.website_list_for_contact import add_role_for_portal_user
 from erpnext.utilities.transaction_base import TransactionBase
 
@@ -81,7 +76,6 @@
 		validate_party_accounts(self)
 		self.validate_credit_limit_on_change()
 		self.set_loyalty_program()
-		self.set_territory_and_group()
 		self.check_customer_group_change()
 		self.validate_default_bank_account()
 		self.validate_internal_customer()
@@ -140,12 +134,6 @@
 					_("{0} is not a company bank account").format(frappe.bold(self.default_bank_account))
 				)
 
-	def set_territory_and_group(self):
-		if not self.territory:
-			self.territory = get_root_of("Territory")
-		if not self.customer_group:
-			self.customer_group = get_root_of("Customer Group")
-
 	def validate_internal_customer(self):
 		if not self.is_internal_customer:
 			self.represents_company = ""
diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py
index 8ff681b..95d2d2c 100644
--- a/erpnext/selling/doctype/quotation/quotation.py
+++ b/erpnext/selling/doctype/quotation/quotation.py
@@ -26,7 +26,6 @@
 		self.set_status()
 		self.validate_uom_is_integer("stock_uom", "qty")
 		self.validate_valid_till()
-		self.validate_shopping_cart_items()
 		self.set_customer_name()
 		if self.items:
 			self.with_items = 1
@@ -42,26 +41,6 @@
 		if self.valid_till and getdate(self.valid_till) < getdate(self.transaction_date):
 			frappe.throw(_("Valid till date cannot be before transaction date"))
 
-	def validate_shopping_cart_items(self):
-		if self.order_type != "Shopping Cart":
-			return
-
-		for item in self.items:
-			has_web_item = frappe.db.exists("Website Item", {"item_code": item.item_code})
-
-			# If variant is unpublished but template is published: valid
-			template = frappe.get_cached_value("Item", item.item_code, "variant_of")
-			if template and not has_web_item:
-				has_web_item = frappe.db.exists("Website Item", {"item_code": template})
-
-			if not has_web_item:
-				frappe.throw(
-					_("Row #{0}: Item {1} must have a Website Item for Shopping Cart Quotations").format(
-						item.idx, frappe.bold(item.item_code)
-					),
-					title=_("Unpublished Item"),
-				)
-
 	def set_has_alternative_item(self):
 		"""Mark 'Has Alternative Item' for rows."""
 		if not any(row.is_alternative for row in self.get("items")):
@@ -263,8 +242,8 @@
 	return _make_sales_order(source_name, target_doc)
 
 
-def _make_sales_order(source_name, target_doc=None, ignore_permissions=False):
-	customer = _make_customer(source_name, ignore_permissions)
+def _make_sales_order(source_name, target_doc=None, customer_group=None, ignore_permissions=False):
+	customer = _make_customer(source_name, ignore_permissions, customer_group)
 	ordered_items = frappe._dict(
 		frappe.db.get_all(
 			"Sales Order Item",
@@ -428,7 +407,7 @@
 	return doclist
 
 
-def _make_customer(source_name, ignore_permissions=False):
+def _make_customer(source_name, ignore_permissions=False, customer_group=None):
 	quotation = frappe.db.get_value(
 		"Quotation", source_name, ["order_type", "party_name", "customer_name"], as_dict=1
 	)
@@ -445,10 +424,7 @@
 				customer_doclist = _make_customer(lead_name, ignore_permissions=ignore_permissions)
 				customer = frappe.get_doc(customer_doclist)
 				customer.flags.ignore_permissions = ignore_permissions
-				if quotation.get("party_name") == "Shopping Cart":
-					customer.customer_group = frappe.db.get_value(
-						"E Commerce Settings", None, "default_customer_group"
-					)
+				customer.customer_group = customer_group
 
 				try:
 					customer.insert()
diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py
index 5623a12..590cd3d 100644
--- a/erpnext/selling/doctype/quotation/test_quotation.py
+++ b/erpnext/selling/doctype/quotation/test_quotation.py
@@ -161,15 +161,6 @@
 
 		make_sales_order(quotation.name)
 
-	def test_shopping_cart_without_website_item(self):
-		if frappe.db.exists("Website Item", {"item_code": "_Test Item Home Desktop 100"}):
-			frappe.get_last_doc("Website Item", {"item_code": "_Test Item Home Desktop 100"}).delete()
-
-		quotation = frappe.copy_doc(test_records[0])
-		quotation.order_type = "Shopping Cart"
-		quotation.valid_till = getdate()
-		self.assertRaises(frappe.ValidationError, quotation.validate)
-
 	def test_create_quotation_with_margin(self):
 		from erpnext.selling.doctype.quotation.quotation import make_sales_order
 		from erpnext.selling.doctype.sales_order.sales_order import (
diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.json b/erpnext/selling/doctype/quotation_item/quotation_item.json
index f2aabc5..5016f1f 100644
--- a/erpnext/selling/doctype/quotation_item/quotation_item.json
+++ b/erpnext/selling/doctype/quotation_item/quotation_item.json
@@ -132,7 +132,6 @@
    "oldfieldname": "description",
    "oldfieldtype": "Small Text",
    "print_width": "300px",
-   "reqd": 1,
    "width": "300px"
   },
   {
@@ -235,6 +234,7 @@
   },
   {
    "collapsible": 1,
+   "collapsible_depends_on": "eval: doc.margin_type || doc.discount_amount",
    "fieldname": "discount_and_margin",
    "fieldtype": "Section Break",
    "label": "Discount and Margin"
@@ -666,7 +666,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-02-06 11:00:07.042364",
+ "modified": "2023-09-26 13:42:11.410294",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Quotation Item",
@@ -676,4 +676,4 @@
  "sort_order": "DESC",
  "states": [],
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index ba8bc33..3ad18da 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -87,17 +87,13 @@
 				frm.events.get_items_from_internal_purchase_order(frm);
 			}
 
-			if (frm.is_new()) {
+			if (frm.doc.docstatus === 0) {
 				frappe.db.get_single_value("Stock Settings", "enable_stock_reservation").then((value) => {
-					if (value) {
-						frappe.db.get_single_value("Stock Settings", "auto_reserve_stock_for_sales_order").then((value) => {
-							// If `Reserve Stock on Sales Order Submission` is enabled in Stock Settings, set Reserve Stock to 1 else 0.
-							frm.set_value("reserve_stock", value ? 1 : 0);
-						})
-					} else {
-						// If `Stock Reservation` is disabled in Stock Settings, set Reserve Stock to 0 and read only.
+					if (!value) {
+						// If `Stock Reservation` is disabled in Stock Settings, set Reserve Stock to 0 and make the field read-only and hidden.
 						frm.set_value("reserve_stock", 0);
 						frm.set_df_property("reserve_stock", "read_only", 1);
+						frm.set_df_property("reserve_stock", "hidden", 1);
 					}
 				})
 			}
diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json
index a74084d..01d047c 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.json
+++ b/erpnext/selling/doctype/sales_order/sales_order.json
@@ -1631,10 +1631,9 @@
   {
    "default": "0",
    "depends_on": "eval: (doc.docstatus == 0 || doc.reserve_stock)",
-   "description": "If checked, Stock Reservation Entries will be created on <b>Submit</b>",
+   "description": "If checked, Stock will be reserved on <b>Submit</b>",
    "fieldname": "reserve_stock",
    "fieldtype": "Check",
-   "hidden": 1,
    "label": "Reserve Stock",
    "no_copy": 1,
    "print_hide": 1,
@@ -1645,7 +1644,7 @@
  "idx": 105,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-07-24 08:59:11.599875",
+ "modified": "2023-10-18 12:41:54.813462",
  "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 aae0fee..e4f1a28 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -3,6 +3,7 @@
 
 
 import json
+from typing import Literal
 
 import frappe
 import frappe.utils
@@ -216,7 +217,15 @@
 
 	def validate_with_previous_doc(self):
 		super(SalesOrder, self).validate_with_previous_doc(
-			{"Quotation": {"ref_dn_field": "prevdoc_docname", "compare_fields": [["company", "="]]}}
+			{
+				"Quotation": {"ref_dn_field": "prevdoc_docname", "compare_fields": [["company", "="]]},
+				"Quotation Item": {
+					"ref_dn_field": "quotation_item",
+					"compare_fields": [["item_code", "="], ["uom", "="], ["conversion_factor", "="]],
+					"is_child_table": True,
+					"allow_duplicate_prev_row_id": True,
+				},
+			}
 		)
 
 		if cint(frappe.db.get_single_value("Selling Settings", "maintain_same_sales_rate")):
@@ -534,14 +543,24 @@
 		return False
 
 	@frappe.whitelist()
-	def create_stock_reservation_entries(self, items_details=None, notify=True) -> None:
+	def create_stock_reservation_entries(
+		self,
+		items_details: list[dict] = None,
+		from_voucher_type: Literal["Pick List", "Purchase Receipt"] = None,
+		notify=True,
+	) -> None:
 		"""Creates Stock Reservation Entries for Sales Order Items."""
 
 		from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import (
 			create_stock_reservation_entries_for_so_items as create_stock_reservation_entries,
 		)
 
-		create_stock_reservation_entries(so=self, items_details=items_details, notify=notify)
+		create_stock_reservation_entries(
+			sales_order=self,
+			items_details=items_details,
+			from_voucher_type=from_voucher_type,
+			notify=notify,
+		)
 
 	@frappe.whitelist()
 	def cancel_stock_reservation_entries(self, sre_list=None, notify=True) -> None:
@@ -606,29 +625,37 @@
 
 
 def get_requested_item_qty(sales_order):
-	return frappe._dict(
-		frappe.db.sql(
-			"""
-		select sales_order_item, sum(qty)
-		from `tabMaterial Request Item`
-		where docstatus = 1
-			and sales_order = %s
-		group by sales_order_item
-	""",
-			sales_order,
-		)
-	)
+	result = {}
+	for d in frappe.db.get_all(
+		"Material Request Item",
+		filters={"docstatus": 1, "sales_order": sales_order},
+		fields=["sales_order_item", "sum(qty) as qty", "sum(received_qty) as received_qty"],
+		group_by="sales_order_item",
+	):
+		result[d.sales_order_item] = frappe._dict({"qty": d.qty, "received_qty": d.received_qty})
+
+	return result
 
 
 @frappe.whitelist()
 def make_material_request(source_name, target_doc=None):
 	requested_item_qty = get_requested_item_qty(source_name)
 
+	def get_remaining_qty(so_item):
+		return flt(
+			flt(so_item.qty)
+			- flt(requested_item_qty.get(so_item.name, {}).get("qty"))
+			- max(
+				flt(so_item.get("delivered_qty"))
+				- flt(requested_item_qty.get(so_item.name, {}).get("received_qty")),
+				0,
+			)
+		)
+
 	def update_item(source, target, source_parent):
 		# qty is for packed items, because packed items don't have stock_qty field
-		qty = source.get("qty")
 		target.project = source_parent.project
-		target.qty = qty - requested_item_qty.get(source.name, 0) - flt(source.get("delivered_qty"))
+		target.qty = get_remaining_qty(source)
 		target.stock_qty = flt(target.qty) * flt(target.conversion_factor)
 
 		args = target.as_dict().copy()
@@ -661,8 +688,8 @@
 			"Sales Order Item": {
 				"doctype": "Material Request Item",
 				"field_map": {"name": "sales_order_item", "parent": "sales_order"},
-				"condition": lambda doc: not frappe.db.exists("Product Bundle", doc.item_code)
-				and (doc.stock_qty - flt(doc.get("delivered_qty"))) > requested_item_qty.get(doc.name, 0),
+				"condition": lambda item: not frappe.db.exists("Product Bundle", item.item_code)
+				and get_remaining_qty(item) > 0,
 				"postprocess": update_item,
 			},
 		},
@@ -740,6 +767,8 @@
 		if target.company_address:
 			target.update(get_fetch_values("Delivery Note", "company_address", target.company_address))
 
+		# set target items names to ensure proper linking with packed_items
+		target.set_new_name()
 		make_packing_list(target)
 
 	def condition(doc):
@@ -812,6 +841,7 @@
 							"postprocess": update_dn_item,
 						}
 					},
+					ignore_permissions=True,
 				)
 
 				dn_item.qty = flt(sre.reserved_qty) * flt(dn_item.get("conversion_factor", 1))
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index 83689a2..d8b5878 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -1784,10 +1784,10 @@
 		si.submit()
 		pe.load_from_db()
 
-		self.assertEqual(pe.references[0].reference_name, si.name)
-		self.assertEqual(pe.references[0].allocated_amount, 200)
-		self.assertEqual(pe.references[1].reference_name, so.name)
-		self.assertEqual(pe.references[1].allocated_amount, 300)
+		self.assertEqual(pe.references[0].reference_name, so.name)
+		self.assertEqual(pe.references[0].allocated_amount, 300)
+		self.assertEqual(pe.references[1].reference_name, si.name)
+		self.assertEqual(pe.references[1].allocated_amount, 200)
 
 	def test_delivered_item_material_request(self):
 		"SO -> MR (Manufacture) -> WO. Test if WO Qty is updated in SO."
diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.json b/erpnext/selling/doctype/sales_order_item/sales_order_item.json
index 07565c3..f82047f 100644
--- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json
+++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json
@@ -68,6 +68,7 @@
   "total_weight",
   "column_break_21",
   "weight_uom",
+  "accounting_dimensions_section",
   "warehouse_and_reference",
   "warehouse",
   "target_warehouse",
@@ -162,7 +163,6 @@
    "oldfieldname": "description",
    "oldfieldtype": "Small Text",
    "print_width": "300px",
-   "reqd": 1,
    "width": "300px"
   },
   {
@@ -890,12 +890,18 @@
    "label": "Production Plan Qty",
    "no_copy": 1,
    "read_only": 1
+  },
+  {
+   "collapsible": 1,
+   "fieldname": "accounting_dimensions_section",
+   "fieldtype": "Section Break",
+   "label": "Accounting Dimensions"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-07-28 14:56:42.031636",
+ "modified": "2023-10-17 18:18:26.475259",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Sales Order Item",
diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.json b/erpnext/selling/doctype/selling_settings/selling_settings.json
index 6855012..d6829ce 100644
--- a/erpnext/selling/doctype/selling_settings/selling_settings.json
+++ b/erpnext/selling/doctype/selling_settings/selling_settings.json
@@ -25,7 +25,7 @@
   "so_required",
   "dn_required",
   "sales_update_frequency",
-  "over_order_allowance",
+  "blanket_order_allowance",
   "column_break_5",
   "allow_multiple_items",
   "allow_against_multiple_purchase_orders",
@@ -184,12 +184,6 @@
    "label": "Allow Sales Order Creation For Expired Quotation"
   },
   {
-   "description": "Percentage you are allowed to order more against the Blanket Order Quantity. For example: If you have a Blanket Order of Quantity 100 units. and your Allowance is 10% then you are allowed to order 110 units.",
-   "fieldname": "over_order_allowance",
-   "fieldtype": "Float",
-   "label": "Over Order Allowance (%)"
-  },
-  {
    "default": "0",
    "fieldname": "dont_reserve_sales_order_qty_on_sales_return",
    "fieldtype": "Check",
@@ -200,6 +194,12 @@
    "fieldname": "allow_negative_rates_for_items",
    "fieldtype": "Check",
    "label": "Allow Negative rates for Items"
+  },
+  {
+   "description": "Percentage you are allowed to sell beyond the Blanket Order quantity.",
+   "fieldname": "blanket_order_allowance",
+   "fieldtype": "Float",
+   "label": "Blanket Order Allowance (%)"
   }
  ],
  "icon": "fa fa-cog",
@@ -207,7 +207,7 @@
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2023-08-14 20:33:05.693667",
+ "modified": "2023-10-25 14:03:03.966701",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Selling Settings",
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index 4973dab..1bd469b 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -40,7 +40,7 @@
 				filters:{
 					'warehouse_type' : 'Transit',
 					'is_group': 0,
-					'company': frm.doc.company
+					'company': frm.doc.company_name
 				}
 			};
 		});
@@ -221,7 +221,6 @@
 		["cost_center", {}],
 		["round_off_cost_center", {}],
 		["depreciation_cost_center", {}],
-		["expenses_included_in_asset_valuation", {"account_type": "Expenses Included In Asset Valuation"}],
 		["capital_work_in_progress_account", {"account_type": "Capital Work in Progress"}],
 		["asset_received_but_not_billed", {"account_type": "Asset Received But Not Billed"}],
 		["unrealized_profit_loss_account", {"root_type": ["in", ["Liability", "Asset"]]}],
@@ -236,8 +235,6 @@
 		$.each([
 			["stock_adjustment_account",
 				{"root_type": "Expense", "account_type": "Stock Adjustment"}],
-			["expenses_included_in_valuation",
-				{"root_type": "Expense", "account_type": "Expenses Included in Valuation"}],
 			["stock_received_but_not_billed",
 				{"root_type": "Liability", "account_type": "Stock Received But Not Billed"}],
 			["service_received_but_not_billed",
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index 24d7da4..b9ff3dd 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -80,7 +80,6 @@
   "accumulated_depreciation_account",
   "depreciation_expense_account",
   "series_for_depreciation_entry",
-  "expenses_included_in_asset_valuation",
   "column_break_40",
   "disposal_account",
   "depreciation_cost_center",
@@ -103,11 +102,10 @@
   "enable_provisional_accounting_for_non_stock_items",
   "default_inventory_account",
   "stock_adjustment_account",
-  "default_in_transit_warehouse",
   "column_break_32",
   "stock_received_but_not_billed",
   "default_provisional_account",
-  "expenses_included_in_valuation",
+  "default_in_transit_warehouse",
   "dashboard_tab"
  ],
  "fields": [
@@ -470,14 +468,6 @@
    "options": "Account"
   },
   {
-   "fieldname": "expenses_included_in_valuation",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "label": "Expenses Included In Valuation",
-   "no_copy": 1,
-   "options": "Account"
-  },
-  {
    "fieldname": "accumulated_depreciation_account",
    "fieldtype": "Link",
    "label": "Accumulated Depreciation Account",
@@ -497,12 +487,6 @@
    "label": "Series for Asset Depreciation Entry (Journal Entry)"
   },
   {
-   "fieldname": "expenses_included_in_asset_valuation",
-   "fieldtype": "Link",
-   "label": "Expenses Included In Asset Valuation",
-   "options": "Account"
-  },
-  {
    "fieldname": "column_break_40",
    "fieldtype": "Column Break"
   },
@@ -782,7 +766,7 @@
  "image_field": "company_logo",
  "is_tree": 1,
  "links": [],
- "modified": "2023-09-10 21:53:13.860791",
+ "modified": "2023-10-23 10:19:24.322898",
  "modified_by": "Administrator",
  "module": "Setup",
  "name": "Company",
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index b05696a..3413702 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -92,7 +92,6 @@
 			["Default Income Account", "default_income_account"],
 			["Stock Received But Not Billed Account", "stock_received_but_not_billed"],
 			["Stock Adjustment Account", "stock_adjustment_account"],
-			["Expense Included In Valuation Account", "expenses_included_in_valuation"],
 		]
 
 		for account in accounts:
@@ -384,7 +383,6 @@
 			"depreciation_expense_account": "Depreciation",
 			"capital_work_in_progress_account": "Capital Work in Progress",
 			"asset_received_but_not_billed": "Asset Received But Not Billed",
-			"expenses_included_in_asset_valuation": "Expenses Included In Asset Valuation",
 			"default_expense_account": "Cost of Goods Sold",
 		}
 
@@ -394,7 +392,6 @@
 					"stock_received_but_not_billed": "Stock Received But Not Billed",
 					"default_inventory_account": "Stock",
 					"stock_adjustment_account": "Stock Adjustment",
-					"expenses_included_in_valuation": "Expenses Included In Valuation",
 				}
 			)
 
diff --git a/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py b/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py
index 3b48c2b..8477984 100644
--- a/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py
+++ b/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py
@@ -121,6 +121,7 @@
 		# Update Currency Exchange Rate
 		settings = frappe.get_single("Currency Exchange Settings")
 		settings.service_provider = "exchangerate.host"
+		settings.access_key = "12345667890"
 		settings.save()
 
 		# Update exchange
diff --git a/erpnext/setup/doctype/driver/driver.json b/erpnext/setup/doctype/driver/driver.json
index 8d426cc..2e994b5 100644
--- a/erpnext/setup/doctype/driver/driver.json
+++ b/erpnext/setup/doctype/driver/driver.json
@@ -157,6 +157,22 @@
    "role": "HR Manager",
    "share": 1,
    "write": 1
+  },
+  {
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Delivery User"
+  },
+  {
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Delivery Manager",
+   "share": 1,
+   "write": 1
   }
  ],
  "quick_entry": 1,
@@ -166,4 +182,4 @@
  "sort_order": "DESC",
  "title_field": "full_name",
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/setup/doctype/employee/employee.json b/erpnext/setup/doctype/employee/employee.json
index 6cb4292..1143ccb 100644
--- a/erpnext/setup/doctype/employee/employee.json
+++ b/erpnext/setup/doctype/employee/employee.json
@@ -616,6 +616,7 @@
    "fieldname": "relieving_date",
    "fieldtype": "Date",
    "label": "Relieving Date",
+   "no_copy": 1,
    "mandatory_depends_on": "eval:doc.status == \"Left\"",
    "oldfieldname": "relieving_date",
    "oldfieldtype": "Date"
@@ -822,7 +823,7 @@
  "idx": 24,
  "image_field": "image",
  "links": [],
- "modified": "2023-03-30 15:57:05.174592",
+ "modified": "2023-10-04 10:57:05.174592",
  "modified_by": "Administrator",
  "module": "Setup",
  "name": "Employee",
@@ -870,4 +871,4 @@
  "sort_order": "DESC",
  "states": [],
  "title_field": "employee_name"
-}
\ No newline at end of file
+}
diff --git a/erpnext/setup/doctype/employee/employee.py b/erpnext/setup/doctype/employee/employee.py
index 566392c..78fb4df 100755
--- a/erpnext/setup/doctype/employee/employee.py
+++ b/erpnext/setup/doctype/employee/employee.py
@@ -123,7 +123,7 @@
 			user.gender = self.gender
 
 		if self.image:
-			if not user.user_image:
+			if not user.user_image or self.has_value_changed("image"):
 				user.user_image = self.image
 				try:
 					frappe.get_doc(
diff --git a/erpnext/setup/doctype/item_group/item_group.js b/erpnext/setup/doctype/item_group/item_group.js
index 4b04ac1..d6eb11f 100644
--- a/erpnext/setup/doctype/item_group/item_group.js
+++ b/erpnext/setup/doctype/item_group/item_group.js
@@ -71,20 +71,6 @@
 				frappe.set_route("List", "Item", {"item_group": frm.doc.name});
 			});
 		}
-
-		frappe.model.with_doctype('Website Item', () => {
-			const web_item_meta = frappe.get_meta('Website Item');
-
-			const valid_fields = web_item_meta.fields.filter(df =>
-				['Link', 'Table MultiSelect'].includes(df.fieldtype) && !df.hidden
-			).map(df =>
-				({ label: df.label, value: df.fieldname })
-			);
-
-			frm.get_field("filter_fields").grid.update_docfield_property(
-				'fieldname', 'options', valid_fields
-			);
-		});
 	},
 
 	set_root_readonly: function(frm) {
diff --git a/erpnext/setup/doctype/item_group/item_group.json b/erpnext/setup/doctype/item_group/item_group.json
index e0f5090..dfa5a8e 100644
--- a/erpnext/setup/doctype/item_group/item_group.json
+++ b/erpnext/setup/doctype/item_group/item_group.json
@@ -19,22 +19,9 @@
   "item_group_defaults",
   "sec_break_taxes",
   "taxes",
-  "sb9",
-  "route",
-  "website_title",
-  "description",
-  "show_in_website",
-  "include_descendants",
-  "column_break_16",
-  "weightage",
-  "slideshow",
-  "website_specifications",
-  "website_filters_section",
-  "filter_fields",
-  "filter_attributes",
   "lft",
-  "rgt",
-  "old_parent"
+  "old_parent",
+  "rgt"
  ],
  "fields": [
   {
@@ -107,54 +94,6 @@
    "options": "Item Tax"
   },
   {
-   "fieldname": "sb9",
-   "fieldtype": "Section Break",
-   "label": "Website Settings"
-  },
-  {
-   "default": "0",
-   "description": "Make Item Group visible in website",
-   "fieldname": "show_in_website",
-   "fieldtype": "Check",
-   "label": "Show in Website"
-  },
-  {
-   "depends_on": "show_in_website",
-   "fieldname": "route",
-   "fieldtype": "Data",
-   "label": "Route",
-   "no_copy": 1,
-   "unique": 1
-  },
-  {
-   "depends_on": "show_in_website",
-   "fieldname": "weightage",
-   "fieldtype": "Int",
-   "label": "Weightage"
-  },
-  {
-   "depends_on": "show_in_website",
-   "description": "Show this slideshow at the top of the page",
-   "fieldname": "slideshow",
-   "fieldtype": "Link",
-   "label": "Slideshow",
-   "options": "Website Slideshow"
-  },
-  {
-   "depends_on": "show_in_website",
-   "description": "HTML / Banner that will show on the top of product list.",
-   "fieldname": "description",
-   "fieldtype": "Text Editor",
-   "label": "Description"
-  },
-  {
-   "depends_on": "show_in_website",
-   "fieldname": "website_specifications",
-   "fieldtype": "Table",
-   "label": "Website Specifications",
-   "options": "Item Website Specification"
-  },
-  {
    "fieldname": "lft",
    "fieldtype": "Int",
    "hidden": 1,
@@ -188,43 +127,6 @@
    "options": "Item Group",
    "print_hide": 1,
    "report_hide": 1
-  },
-  {
-   "collapsible": 1,
-   "depends_on": "show_in_website",
-   "fieldname": "website_filters_section",
-   "fieldtype": "Section Break",
-   "label": "Website Filters"
-  },
-  {
-   "fieldname": "filter_fields",
-   "fieldtype": "Table",
-   "label": "Item Fields",
-   "options": "Website Filter Field"
-  },
-  {
-   "fieldname": "filter_attributes",
-   "fieldtype": "Table",
-   "label": "Attributes",
-   "options": "Website Attribute"
-  },
-  {
-   "depends_on": "show_in_website",
-   "fieldname": "website_title",
-   "fieldtype": "Data",
-   "label": "Title"
-  },
-  {
-   "fieldname": "column_break_16",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "0",
-   "depends_on": "show_in_website",
-   "description": "Include Website Items belonging to child Item Groups",
-   "fieldname": "include_descendants",
-   "fieldtype": "Check",
-   "label": "Include Descendants"
   }
  ],
  "icon": "fa fa-sitemap",
@@ -233,7 +135,7 @@
  "is_tree": 1,
  "links": [],
  "max_attachments": 3,
- "modified": "2023-08-28 22:27:48.382985",
+ "modified": "2023-10-12 13:44:13.611287",
  "modified_by": "Administrator",
  "module": "Setup",
  "name": "Item Group",
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index cc67c69..fe7a241 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -2,39 +2,19 @@
 # License: GNU General Public License v3. See license.txt
 
 import copy
-from urllib.parse import quote
 
 import frappe
 from frappe import _
-from frappe.utils import cint
 from frappe.utils.nestedset import NestedSet
-from frappe.website.utils import clear_cache
-from frappe.website.website_generator import WebsiteGenerator
-
-from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import ECommerceSettings
-from erpnext.e_commerce.product_data_engine.filters import ProductFiltersBuilder
 
 
-class ItemGroup(NestedSet, WebsiteGenerator):
-	nsm_parent_field = "parent_item_group"
-	website = frappe._dict(
-		condition_field="show_in_website",
-		template="templates/generators/item_group.html",
-		no_cache=1,
-		no_breadcrumbs=1,
-	)
-
+class ItemGroup(NestedSet):
 	def validate(self):
-		super(ItemGroup, self).validate()
-
 		if not self.parent_item_group and not frappe.flags.in_test:
 			if frappe.db.exists("Item Group", _("All Item Groups")):
 				self.parent_item_group = _("All Item Groups")
-
-		self.make_route()
 		self.validate_item_group_defaults()
 		self.check_item_tax()
-		ECommerceSettings.validate_field_filters(self.filter_fields, enable_field_filters=True)
 
 	def check_item_tax(self):
 		"""Check whether Tax Rate is not entered twice for same Tax Type"""
@@ -53,66 +33,13 @@
 
 	def on_update(self):
 		NestedSet.on_update(self)
-		invalidate_cache_for(self)
 		self.validate_one_root()
 		self.delete_child_item_groups_key()
 
-	def make_route(self):
-		"""Make website route"""
-		if not self.route:
-			self.route = ""
-			if self.parent_item_group:
-				parent_item_group = frappe.get_doc("Item Group", self.parent_item_group)
-
-				# make parent route only if not root
-				if parent_item_group.parent_item_group and parent_item_group.route:
-					self.route = parent_item_group.route + "/"
-
-			self.route += self.scrub(self.item_group_name)
-
-			return self.route
-
 	def on_trash(self):
 		NestedSet.on_trash(self, allow_root_deletion=True)
-		WebsiteGenerator.on_trash(self)
 		self.delete_child_item_groups_key()
 
-	def get_context(self, context):
-		context.show_search = True
-		context.body_class = "product-page"
-		context.page_length = (
-			cint(frappe.db.get_single_value("E Commerce Settings", "products_per_page")) or 6
-		)
-		context.search_link = "/product_search"
-
-		filter_engine = ProductFiltersBuilder(self.name)
-
-		context.field_filters = filter_engine.get_field_filters()
-		context.attribute_filters = filter_engine.get_attribute_filters()
-
-		context.update({"parents": get_parent_item_groups(self.parent_item_group), "title": self.name})
-
-		if self.slideshow:
-			values = {"show_indicators": 1, "show_controls": 0, "rounded": 1, "slider_name": self.slideshow}
-			slideshow = frappe.get_doc("Website Slideshow", self.slideshow)
-			slides = slideshow.get({"doctype": "Website Slideshow Item"})
-			for index, slide in enumerate(slides):
-				values[f"slide_{index + 1}_image"] = slide.image
-				values[f"slide_{index + 1}_title"] = slide.heading
-				values[f"slide_{index + 1}_subtitle"] = slide.description
-				values[f"slide_{index + 1}_theme"] = slide.get("theme") or "Light"
-				values[f"slide_{index + 1}_content_align"] = slide.get("content_align") or "Centre"
-				values[f"slide_{index + 1}_primary_action"] = slide.url
-
-			context.slideshow = values
-
-		context.no_breadcrumbs = False
-		context.title = self.website_title or self.name
-		context.name = self.name
-		context.item_group_name = self.item_group_name
-
-		return context
-
 	def delete_child_item_groups_key(self):
 		frappe.cache().hdel("child_item_groups", self.name)
 
@@ -122,20 +49,6 @@
 		validate_item_default_company_links(self.item_group_defaults)
 
 
-def get_child_groups_for_website(item_group_name, immediate=False, include_self=False):
-	"""Returns child item groups *excluding* passed group."""
-	item_group = frappe.get_cached_value("Item Group", item_group_name, ["lft", "rgt"], as_dict=1)
-	filters = {"lft": [">", item_group.lft], "rgt": ["<", item_group.rgt], "show_in_website": 1}
-
-	if immediate:
-		filters["parent_item_group"] = item_group_name
-
-	if include_self:
-		filters.update({"lft": [">=", item_group.lft], "rgt": ["<=", item_group.rgt]})
-
-	return frappe.get_all("Item Group", filters=filters, fields=["name", "route"], order_by="name")
-
-
 def get_child_item_groups(item_group_name):
 	item_group = frappe.get_cached_value("Item Group", item_group_name, ["lft", "rgt"], as_dict=1)
 
@@ -149,63 +62,6 @@
 	return child_item_groups or {}
 
 
-def get_item_for_list_in_html(context):
-	# add missing absolute link in files
-	# user may forget it during upload
-	if (context.get("website_image") or "").startswith("files/"):
-		context["website_image"] = "/" + quote(context["website_image"])
-
-	products_template = "templates/includes/products_as_list.html"
-
-	return frappe.get_template(products_template).render(context)
-
-
-def get_parent_item_groups(item_group_name, from_item=False):
-	settings = frappe.get_cached_doc("E Commerce Settings")
-
-	if settings.enable_field_filters:
-		base_nav_page = {"name": _("Shop by Category"), "route": "/shop-by-category"}
-	else:
-		base_nav_page = {"name": _("All Products"), "route": "/all-products"}
-
-	if from_item and frappe.request.environ.get("HTTP_REFERER"):
-		# base page after 'Home' will vary on Item page
-		last_page = frappe.request.environ["HTTP_REFERER"].split("/")[-1].split("?")[0]
-		if last_page and last_page in ("shop-by-category", "all-products"):
-			base_nav_page_title = " ".join(last_page.split("-")).title()
-			base_nav_page = {"name": _(base_nav_page_title), "route": "/" + last_page}
-
-	base_parents = [
-		{"name": _("Home"), "route": "/"},
-		base_nav_page,
-	]
-
-	if not item_group_name:
-		return base_parents
-
-	item_group = frappe.db.get_value("Item Group", item_group_name, ["lft", "rgt"], as_dict=1)
-	parent_groups = frappe.db.sql(
-		"""select name, route from `tabItem Group`
-		where lft <= %s and rgt >= %s
-		and show_in_website=1
-		order by lft asc""",
-		(item_group.lft, item_group.rgt),
-		as_dict=True,
-	)
-
-	return base_parents + parent_groups
-
-
-def invalidate_cache_for(doc, item_group=None):
-	if not item_group:
-		item_group = doc.name
-
-	for d in get_parent_item_groups(item_group):
-		item_group_name = frappe.db.get_value("Item Group", d.get("name"))
-		if item_group_name:
-			clear_cache(frappe.db.get_value("Item Group", item_group_name, "route"))
-
-
 def get_item_group_defaults(item, company):
 	item = frappe.get_cached_doc("Item", item)
 	item_group = frappe.get_cached_doc("Item Group", item.item_group)
diff --git a/erpnext/setup/doctype/vehicle/vehicle.json b/erpnext/setup/doctype/vehicle/vehicle.json
index ed803a7..b19d459 100644
--- a/erpnext/setup/doctype/vehicle/vehicle.json
+++ b/erpnext/setup/doctype/vehicle/vehicle.json
@@ -860,6 +860,22 @@
    "share": 1,
    "submit": 0,
    "write": 1
+  },
+  {
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Delivery User"
+  },
+  {
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Delivery Manager",
+   "share": 1,
+   "write": 1
   }
  ],
  "quick_entry": 1,
@@ -872,4 +888,4 @@
  "title_field": "",
  "track_changes": 1,
  "track_seen": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py
index 85eaf5f..b106cfc 100644
--- a/erpnext/setup/install.py
+++ b/erpnext/setup/install.py
@@ -33,6 +33,7 @@
 	add_app_name()
 	setup_log_settings()
 	hide_workspaces()
+	update_roles()
 	frappe.db.commit()
 
 
@@ -232,6 +233,12 @@
 		frappe.db.set_value("Workspace", ws, "public", 0)
 
 
+def update_roles():
+	website_user_roles = ("Customer", "Supplier")
+	for role in website_user_roles:
+		frappe.db.set_value("Role", role, "desk_access", 0)
+
+
 def create_default_role_profiles():
 	for role_profile_name, roles in DEFAULT_ROLE_PROFILES.items():
 		role_profile = frappe.new_doc("Role Profile")
diff --git a/erpnext/setup/setup_wizard/data/country_wise_tax.json b/erpnext/setup/setup_wizard/data/country_wise_tax.json
index 3532d6b..a746ebe 100644
--- a/erpnext/setup/setup_wizard/data/country_wise_tax.json
+++ b/erpnext/setup/setup_wizard/data/country_wise_tax.json
@@ -157,9 +157,14 @@
 	},
 
 	"Botswana": {
-		"Botswana Tax": {
+		"Botswana Tax 14%": {
 			"account_name": "VAT",
-			"tax_rate": 12.00
+			"tax_rate": 14.00
+		},
+		"Botswana Tax 12%": {
+			"account_name": "VAT",
+			"tax_rate": 12.00,
+			"default": 1
 		}
 	},
 
diff --git a/erpnext/setup/setup_wizard/operations/company_setup.py b/erpnext/setup/setup_wizard/operations/company_setup.py
index ace5cca..d4aac5e 100644
--- a/erpnext/setup/setup_wizard/operations/company_setup.py
+++ b/erpnext/setup/setup_wizard/operations/company_setup.py
@@ -33,20 +33,6 @@
 		).insert()
 
 
-def enable_shopping_cart(args):  # nosemgrep
-	# Needs price_lists
-	frappe.get_doc(
-		{
-			"doctype": "E Commerce Settings",
-			"enabled": 1,
-			"company": args.get("company_name"),
-			"price_list": frappe.db.get_value("Price List", {"selling": 1}),
-			"default_customer_group": _("Individual"),
-			"quotation_series": "QTN-",
-		}
-	).insert()
-
-
 def get_fy_details(fy_start_date, fy_end_date):
 	start_year = getdate(fy_start_date).year
 	if start_year == getdate(fy_end_date).year:
diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py
index ae6881b..2205924 100644
--- a/erpnext/setup/setup_wizard/operations/install_fixtures.py
+++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py
@@ -454,7 +454,6 @@
 
 	set_global_defaults(args)
 	update_stock_settings()
-	update_shopping_cart_settings(args)
 
 	args.update({"set_default": 1})
 	create_bank_account(args)
@@ -529,20 +528,6 @@
 			pass
 
 
-def update_shopping_cart_settings(args):  # nosemgrep
-	shopping_cart = frappe.get_doc("E Commerce Settings")
-	shopping_cart.update(
-		{
-			"enabled": 1,
-			"company": args.company_name,
-			"price_list": frappe.db.get_value("Price List", {"selling": 1}),
-			"default_customer_group": _("Individual"),
-			"quotation_series": "QTN-",
-		}
-	)
-	shopping_cart.update_single(shopping_cart.get_valid_dict())
-
-
 def get_fy_details(fy_start_date, fy_end_date):
 	start_year = getdate(fy_start_date).year
 	if start_year == getdate(fy_end_date).year:
diff --git a/erpnext/setup/workspace/erpnext_settings/erpnext_settings.json b/erpnext/setup/workspace/erpnext_settings/erpnext_settings.json
index 5806fd1..2f9cec4 100644
--- a/erpnext/setup/workspace/erpnext_settings/erpnext_settings.json
+++ b/erpnext/setup/workspace/erpnext_settings/erpnext_settings.json
@@ -1,500 +1,500 @@
 {
- "charts": [],
- "content": "[{\"id\":\"NO5yYHJopc\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Your Shortcuts\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t</b></span>\",\"col\":12}},{\"id\":\"CDxIM-WuZ9\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"System Settings\",\"col\":3}},{\"id\":\"-Uh7DKJNJX\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Settings\",\"col\":3}},{\"id\":\"K9ST9xcDXh\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Settings\",\"col\":3}},{\"id\":\"27IdVHVQMb\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Selling Settings\",\"col\":3}},{\"id\":\"Rwp5zff88b\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Buying Settings\",\"col\":3}},{\"id\":\"hkfnQ2sevf\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Global Defaults\",\"col\":3}},{\"id\":\"jjxI_PDawD\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Print Settings\",\"col\":3}},{\"id\":\"R3CoYYFXye\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"yynbm1J_VO\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Settings</b></span>\",\"col\":12}},{\"id\":\"KDCv2MvSg3\",\"type\":\"card\",\"data\":{\"card_name\":\"Module Settings\",\"col\":4}},{\"id\":\"Q0_bqT7cxQ\",\"type\":\"card\",\"data\":{\"card_name\":\"Email / Notifications\",\"col\":4}},{\"id\":\"UnqK5haBnh\",\"type\":\"card\",\"data\":{\"card_name\":\"Website\",\"col\":4}},{\"id\":\"kp7u1H5hCd\",\"type\":\"card\",\"data\":{\"card_name\":\"Core\",\"col\":4}},{\"id\":\"Ufc3jycgy9\",\"type\":\"card\",\"data\":{\"card_name\":\"Printing\",\"col\":4}},{\"id\":\"89bSNzv3Yh\",\"type\":\"card\",\"data\":{\"card_name\":\"Workflow\",\"col\":4}}]",
- "creation": "2022-01-27 13:14:47.349433",
- "custom_blocks": [],
- "docstatus": 0,
- "doctype": "Workspace",
- "for_user": "",
- "hide_custom": 0,
- "icon": "setting",
- "idx": 0,
- "is_hidden": 0,
- "label": "ERPNext Settings",
- "links": [
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Import Data",
-   "link_count": 0,
-   "link_to": "Data Import",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Export Data",
-   "link_count": 0,
-   "link_to": "Data Export",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Bulk Update",
-   "link_count": 0,
-   "link_to": "Bulk Update",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Download Backups",
-   "link_count": 0,
-   "link_to": "backups",
-   "link_type": "Page",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Deleted Documents",
-   "link_count": 0,
-   "link_to": "Deleted Document",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Email / Notifications",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Email Account",
-   "link_count": 0,
-   "link_to": "Email Account",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Email Domain",
-   "link_count": 0,
-   "link_to": "Email Domain",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Notification",
-   "link_count": 0,
-   "link_to": "Notification",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Email Template",
-   "link_count": 0,
-   "link_to": "Email Template",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Auto Email Report",
-   "link_count": 0,
-   "link_to": "Auto Email Report",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Newsletter",
-   "link_count": 0,
-   "link_to": "Newsletter",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Notification Settings",
-   "link_count": 0,
-   "link_to": "Notification Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Website",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Website Settings",
-   "link_count": 0,
-   "link_to": "Website Settings",
-   "link_type": "DocType",
-   "onboard": 1,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Website Theme",
-   "link_count": 0,
-   "link_to": "Website Theme",
-   "link_type": "DocType",
-   "onboard": 1,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Website Script",
-   "link_count": 0,
-   "link_to": "Website Script",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "About Us Settings",
-   "link_count": 0,
-   "link_to": "About Us Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Contact Us Settings",
-   "link_count": 0,
-   "link_to": "Contact Us Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Printing",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Print Format Builder",
-   "link_count": 0,
-   "link_to": "print-format-builder",
-   "link_type": "Page",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Print Settings",
-   "link_count": 0,
-   "link_to": "Print Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Print Format",
-   "link_count": 0,
-   "link_to": "Print Format",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Print Style",
-   "link_count": 0,
-   "link_to": "Print Style",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Workflow",
-   "link_count": 0,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Workflow",
-   "link_count": 0,
-   "link_to": "Workflow",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Workflow State",
-   "link_count": 0,
-   "link_to": "Workflow State",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Workflow Action",
-   "link_count": 0,
-   "link_to": "Workflow Action",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Core",
-   "link_count": 3,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "System Settings",
-   "link_count": 0,
-   "link_to": "System Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Domain Settings",
-   "link_count": 0,
-   "link_to": "Domain Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Global Defaults",
-   "link_count": 0,
-   "link_to": "Global Defaults",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Module Settings",
-   "link_count": 8,
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Accounts Settings",
-   "link_count": 0,
-   "link_to": "Accounts Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Stock Settings",
-   "link_count": 0,
-   "link_to": "Stock Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Selling Settings",
-   "link_count": 0,
-   "link_to": "Selling Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Buying Settings",
-   "link_count": 0,
-   "link_to": "Buying Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Manufacturing Settings",
-   "link_count": 0,
-   "link_to": "Manufacturing Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "CRM Settings",
-   "link_count": 0,
-   "link_to": "CRM Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Projects Settings",
-   "link_count": 0,
-   "link_to": "Projects Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Support Settings",
-   "link_count": 0,
-   "link_to": "Support Settings",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  }
- ],
- "modified": "2023-05-24 14:47:25.356531",
- "modified_by": "Administrator",
- "module": "Setup",
- "name": "ERPNext Settings",
- "number_cards": [],
- "owner": "Administrator",
- "parent_page": "",
- "public": 1,
- "quick_lists": [],
- "restrict_to_domain": "",
- "roles": [],
- "sequence_id": 19.0,
- "shortcuts": [
-  {
-   "color": "Grey",
-   "doc_view": "List",
-   "label": "Print Settings",
-   "link_to": "Print Settings",
-   "type": "DocType"
-  },
-  {
-   "color": "Grey",
-   "doc_view": "List",
-   "label": "System Settings",
-   "link_to": "System Settings",
-   "type": "DocType"
-  },
-  {
-   "icon": "accounting",
-   "label": "Accounts Settings",
-   "link_to": "Accounts Settings",
-   "type": "DocType"
-  },
-  {
-   "color": "Grey",
-   "doc_view": "List",
-   "label": "Global Defaults",
-   "link_to": "Global Defaults",
-   "type": "DocType"
-  },
-  {
-   "icon": "stock",
-   "label": "Stock Settings",
-   "link_to": "Stock Settings",
-   "type": "DocType"
-  },
-  {
-   "icon": "sell",
-   "label": "Selling Settings",
-   "link_to": "Selling Settings",
-   "type": "DocType"
-  },
-  {
-   "icon": "buying",
-   "label": "Buying Settings",
-   "link_to": "Buying Settings",
-   "type": "DocType"
-  }
- ],
- "title": "ERPNext Settings"
-}
\ No newline at end of file
+   "charts": [],
+   "content": "[{\"id\":\"NO5yYHJopc\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Your Shortcuts\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t</b></span>\",\"col\":12}},{\"id\":\"CDxIM-WuZ9\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"System Settings\",\"col\":3}},{\"id\":\"-Uh7DKJNJX\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Settings\",\"col\":3}},{\"id\":\"K9ST9xcDXh\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Settings\",\"col\":3}},{\"id\":\"27IdVHVQMb\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Selling Settings\",\"col\":3}},{\"id\":\"Rwp5zff88b\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Buying Settings\",\"col\":3}},{\"id\":\"hkfnQ2sevf\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Global Defaults\",\"col\":3}},{\"id\":\"jjxI_PDawD\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Print Settings\",\"col\":3}},{\"id\":\"R3CoYYFXye\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"yynbm1J_VO\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Settings</b></span>\",\"col\":12}},{\"id\":\"KDCv2MvSg3\",\"type\":\"card\",\"data\":{\"card_name\":\"Module Settings\",\"col\":4}},{\"id\":\"Q0_bqT7cxQ\",\"type\":\"card\",\"data\":{\"card_name\":\"Email / Notifications\",\"col\":4}},{\"id\":\"UnqK5haBnh\",\"type\":\"card\",\"data\":{\"card_name\":\"Website\",\"col\":4}},{\"id\":\"kp7u1H5hCd\",\"type\":\"card\",\"data\":{\"card_name\":\"Core\",\"col\":4}},{\"id\":\"Ufc3jycgy9\",\"type\":\"card\",\"data\":{\"card_name\":\"Printing\",\"col\":4}},{\"id\":\"89bSNzv3Yh\",\"type\":\"card\",\"data\":{\"card_name\":\"Workflow\",\"col\":4}}]",
+   "creation": "2022-01-27 13:14:47.349433",
+   "custom_blocks": [],
+   "docstatus": 0,
+   "doctype": "Workspace",
+   "for_user": "",
+   "hide_custom": 0,
+   "icon": "setting",
+   "idx": 0,
+   "is_hidden": 0,
+   "label": "ERPNext Settings",
+   "links": [
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Import Data",
+     "link_count": 0,
+     "link_to": "Data Import",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Export Data",
+     "link_count": 0,
+     "link_to": "Data Export",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Bulk Update",
+     "link_count": 0,
+     "link_to": "Bulk Update",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Download Backups",
+     "link_count": 0,
+     "link_to": "backups",
+     "link_type": "Page",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Deleted Documents",
+     "link_count": 0,
+     "link_to": "Deleted Document",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Email / Notifications",
+     "link_count": 0,
+     "onboard": 0,
+     "type": "Card Break"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Email Account",
+     "link_count": 0,
+     "link_to": "Email Account",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Email Domain",
+     "link_count": 0,
+     "link_to": "Email Domain",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Notification",
+     "link_count": 0,
+     "link_to": "Notification",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Email Template",
+     "link_count": 0,
+     "link_to": "Email Template",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Auto Email Report",
+     "link_count": 0,
+     "link_to": "Auto Email Report",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Newsletter",
+     "link_count": 0,
+     "link_to": "Newsletter",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Notification Settings",
+     "link_count": 0,
+     "link_to": "Notification Settings",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Website",
+     "link_count": 0,
+     "onboard": 0,
+     "type": "Card Break"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Website Settings",
+     "link_count": 0,
+     "link_to": "Website Settings",
+     "link_type": "DocType",
+     "onboard": 1,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Website Theme",
+     "link_count": 0,
+     "link_to": "Website Theme",
+     "link_type": "DocType",
+     "onboard": 1,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Website Script",
+     "link_count": 0,
+     "link_to": "Website Script",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "About Us Settings",
+     "link_count": 0,
+     "link_to": "About Us Settings",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Contact Us Settings",
+     "link_count": 0,
+     "link_to": "Contact Us Settings",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Printing",
+     "link_count": 0,
+     "onboard": 0,
+     "type": "Card Break"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Print Format Builder",
+     "link_count": 0,
+     "link_to": "print-format-builder",
+     "link_type": "Page",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Print Settings",
+     "link_count": 0,
+     "link_to": "Print Settings",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Print Format",
+     "link_count": 0,
+     "link_to": "Print Format",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Print Style",
+     "link_count": 0,
+     "link_to": "Print Style",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Workflow",
+     "link_count": 0,
+     "onboard": 0,
+     "type": "Card Break"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Workflow",
+     "link_count": 0,
+     "link_to": "Workflow",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Workflow State",
+     "link_count": 0,
+     "link_to": "Workflow State",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Workflow Action",
+     "link_count": 0,
+     "link_to": "Workflow Action",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Core",
+     "link_count": 3,
+     "onboard": 0,
+     "type": "Card Break"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "System Settings",
+     "link_count": 0,
+     "link_to": "System Settings",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "dependencies": "",
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Domain Settings",
+     "link_count": 0,
+     "link_to": "Domain Settings",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Global Defaults",
+     "link_count": 0,
+     "link_to": "Global Defaults",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Module Settings",
+     "link_count": 8,
+     "onboard": 0,
+     "type": "Card Break"
+    },
+    {
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Accounts Settings",
+     "link_count": 0,
+     "link_to": "Accounts Settings",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Stock Settings",
+     "link_count": 0,
+     "link_to": "Stock Settings",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Selling Settings",
+     "link_count": 0,
+     "link_to": "Selling Settings",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Buying Settings",
+     "link_count": 0,
+     "link_to": "Buying Settings",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Manufacturing Settings",
+     "link_count": 0,
+     "link_to": "Manufacturing Settings",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "CRM Settings",
+     "link_count": 0,
+     "link_to": "CRM Settings",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Projects Settings",
+     "link_count": 0,
+     "link_to": "Projects Settings",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    },
+    {
+     "hidden": 0,
+     "is_query_report": 0,
+     "label": "Support Settings",
+     "link_count": 0,
+     "link_to": "Support Settings",
+     "link_type": "DocType",
+     "onboard": 0,
+     "type": "Link"
+    }
+   ],
+   "modified": "2023-05-24 14:47:25.356531",
+   "modified_by": "Administrator",
+   "module": "Setup",
+   "name": "ERPNext Settings",
+   "number_cards": [],
+   "owner": "Administrator",
+   "parent_page": "",
+   "public": 1,
+   "quick_lists": [],
+   "restrict_to_domain": "",
+   "roles": [],
+   "sequence_id": 19.0,
+   "shortcuts": [
+    {
+     "color": "Grey",
+     "doc_view": "List",
+     "label": "Print Settings",
+     "link_to": "Print Settings",
+     "type": "DocType"
+    },
+    {
+     "color": "Grey",
+     "doc_view": "List",
+     "label": "System Settings",
+     "link_to": "System Settings",
+     "type": "DocType"
+    },
+    {
+     "icon": "accounting",
+     "label": "Accounts Settings",
+     "link_to": "Accounts Settings",
+     "type": "DocType"
+    },
+    {
+     "color": "Grey",
+     "doc_view": "List",
+     "label": "Global Defaults",
+     "link_to": "Global Defaults",
+     "type": "DocType"
+    },
+    {
+     "icon": "stock",
+     "label": "Stock Settings",
+     "link_to": "Stock Settings",
+     "type": "DocType"
+    },
+    {
+     "icon": "sell",
+     "label": "Selling Settings",
+     "link_to": "Selling Settings",
+     "type": "DocType"
+    },
+    {
+     "icon": "buying",
+     "label": "Buying Settings",
+     "link_to": "Buying Settings",
+     "type": "DocType"
+    }
+   ],
+   "title": "ERPNext Settings"
+  }
\ No newline at end of file
diff --git a/erpnext/stock/doctype/bin/bin.json b/erpnext/stock/doctype/bin/bin.json
index a115727..312470d 100644
--- a/erpnext/stock/doctype/bin/bin.json
+++ b/erpnext/stock/doctype/bin/bin.json
@@ -5,20 +5,24 @@
  "doctype": "DocType",
  "engine": "InnoDB",
  "field_order": [
-  "warehouse",
   "item_code",
-  "reserved_qty",
+  "column_break_yreo",
+  "warehouse",
+  "section_break_stag",
   "actual_qty",
-  "ordered_qty",
-  "indented_qty",
   "planned_qty",
+  "indented_qty",
+  "ordered_qty",
   "projected_qty",
+  "column_break_xn5j",
+  "reserved_qty",
   "reserved_qty_for_production",
   "reserved_qty_for_sub_contract",
   "reserved_qty_for_production_plan",
-  "ma_rate",
+  "reserved_stock",
+  "section_break_pmrs",
   "stock_uom",
-  "fcfs_rate",
+  "column_break_0slj",
   "valuation_rate",
   "stock_value"
  ],
@@ -56,7 +60,7 @@
    "fieldname": "reserved_qty",
    "fieldtype": "Float",
    "in_list_view": 1,
-   "label": "Reserved Quantity",
+   "label": "Reserved Qty",
    "oldfieldname": "reserved_qty",
    "oldfieldtype": "Currency",
    "read_only": 1
@@ -67,7 +71,7 @@
    "fieldtype": "Float",
    "in_filter": 1,
    "in_list_view": 1,
-   "label": "Actual Quantity",
+   "label": "Actual Qty",
    "oldfieldname": "actual_qty",
    "oldfieldtype": "Currency",
    "read_only": 1
@@ -77,7 +81,7 @@
    "fieldname": "ordered_qty",
    "fieldtype": "Float",
    "in_list_view": 1,
-   "label": "Ordered Quantity",
+   "label": "Ordered Qty",
    "oldfieldname": "ordered_qty",
    "oldfieldtype": "Currency",
    "read_only": 1
@@ -86,7 +90,7 @@
    "default": "0.00",
    "fieldname": "indented_qty",
    "fieldtype": "Float",
-   "label": "Requested Quantity",
+   "label": "Requested Qty",
    "oldfieldname": "indented_qty",
    "oldfieldtype": "Currency",
    "read_only": 1
@@ -116,21 +120,10 @@
   {
    "fieldname": "reserved_qty_for_sub_contract",
    "fieldtype": "Float",
-   "label": "Reserved Qty for sub contract",
+   "label": "Reserved Qty for Subcontract",
    "read_only": 1
   },
   {
-   "fieldname": "ma_rate",
-   "fieldtype": "Float",
-   "hidden": 1,
-   "label": "Moving Average Rate",
-   "oldfieldname": "ma_rate",
-   "oldfieldtype": "Currency",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
    "fieldname": "stock_uom",
    "fieldtype": "Link",
    "in_filter": 1,
@@ -141,17 +134,6 @@
    "read_only": 1
   },
   {
-   "fieldname": "fcfs_rate",
-   "fieldtype": "Float",
-   "hidden": 1,
-   "label": "FCFS Rate",
-   "oldfieldname": "fcfs_rate",
-   "oldfieldtype": "Currency",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
-  },
-  {
    "fieldname": "valuation_rate",
    "fieldtype": "Float",
    "label": "Valuation Rate",
@@ -172,13 +154,40 @@
    "fieldtype": "Float",
    "label": "Reserved Qty for Production Plan",
    "read_only": 1
+  },
+  {
+   "fieldname": "section_break_stag",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_yreo",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "column_break_xn5j",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "section_break_pmrs",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_0slj",
+   "fieldtype": "Column Break"
+  },
+  {
+   "default": "0",
+   "fieldname": "reserved_stock",
+   "fieldtype": "Float",
+   "label": "Reserved Stock",
+   "read_only": 1
   }
  ],
  "hide_toolbar": 1,
  "idx": 1,
  "in_create": 1,
  "links": [],
- "modified": "2023-05-02 23:26:21.806965",
+ "modified": "2023-11-01 16:51:17.079107",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Bin",
diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py
index 5abea9e..8b2e5cf 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -34,10 +34,15 @@
 			get_reserved_qty_for_production_plan,
 		)
 
-		self.reserved_qty_for_production_plan = get_reserved_qty_for_production_plan(
+		reserved_qty_for_production_plan = get_reserved_qty_for_production_plan(
 			self.item_code, self.warehouse
 		)
 
+		if reserved_qty_for_production_plan is None and not self.reserved_qty_for_production_plan:
+			return
+
+		self.reserved_qty_for_production_plan = flt(reserved_qty_for_production_plan)
+
 		self.db_set(
 			"reserved_qty_for_production_plan",
 			flt(self.reserved_qty_for_production_plan),
@@ -48,6 +53,29 @@
 			self.set_projected_qty()
 			self.db_set("projected_qty", self.projected_qty, update_modified=True)
 
+	def update_reserved_qty_for_for_sub_assembly(self):
+		from erpnext.manufacturing.doctype.production_plan.production_plan import (
+			get_reserved_qty_for_sub_assembly,
+		)
+
+		reserved_qty_for_production_plan = get_reserved_qty_for_sub_assembly(
+			self.item_code, self.warehouse
+		)
+
+		if reserved_qty_for_production_plan is None and not self.reserved_qty_for_production_plan:
+			return
+
+		self.reserved_qty_for_production_plan = flt(reserved_qty_for_production_plan)
+		self.set_projected_qty()
+
+		self.db_set(
+			{
+				"projected_qty": self.projected_qty,
+				"reserved_qty_for_production_plan": flt(self.reserved_qty_for_production_plan),
+			},
+			update_modified=True,
+		)
+
 	def update_reserved_qty_for_production(self):
 		"""Update qty reserved for production from Production Item tables
 		in open work orders"""
@@ -148,6 +176,17 @@
 		self.set_projected_qty()
 		self.db_set("projected_qty", self.projected_qty, update_modified=True)
 
+	def update_reserved_stock(self):
+		"""Update `Reserved Stock` on change in Reserved Qty of Stock Reservation Entry"""
+
+		from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import (
+			get_sre_reserved_qty_for_item_and_warehouse,
+		)
+
+		reserved_stock = get_sre_reserved_qty_for_item_and_warehouse(self.item_code, self.warehouse)
+
+		self.db_set("reserved_stock", flt(reserved_stock), update_modified=True)
+
 
 def on_doctype_update():
 	frappe.db.add_unique("Bin", ["item_code", "warehouse"], constraint_name="unique_item_warehouse")
diff --git a/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.py b/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.py
index 295d979..b0499bf 100644
--- a/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.py
+++ b/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.py
@@ -1,6 +1,6 @@
 # Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
 # For license information, please see license.txt
-
+import gzip
 import json
 
 import frappe
@@ -8,7 +8,7 @@
 from frappe.core.doctype.prepared_report.prepared_report import create_json_gz_file
 from frappe.desk.form.load import get_attachments
 from frappe.model.document import Document
-from frappe.utils import get_link_to_form, gzip_decompress, parse_json
+from frappe.utils import get_link_to_form, parse_json
 from frappe.utils.background_jobs import enqueue
 
 from erpnext.stock.report.stock_balance.stock_balance import execute
@@ -109,7 +109,7 @@
 			attachment = attachments[0]
 			attached_file = frappe.get_doc("File", attachment.name)
 
-			data = gzip_decompress(attached_file.get_content())
+			data = gzip.decompress(attached_file.get_content())
 			if data := json.loads(data.decode("utf-8")):
 				data = data
 
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index e0d4919..b85f296 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -1460,6 +1460,36 @@
    "read": 1,
    "role": "Stock Manager",
    "write": 1
+  },
+  {
+   "amend": 1,
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Delivery User",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  },
+  {
+   "amend": 1,
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Delivery Manager",
+   "share": 1,
+   "submit": 1,
+   "write": 1
   }
  ],
  "search_fields": "status,customer,customer_name, territory,base_grand_total",
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 190575e..66dd33a 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -365,6 +365,9 @@
 					# Update Stock Reservation Entry `Status` based on `Delivered Qty`.
 					sre_doc.update_status()
 
+					# Update Reserved Stock in Bin.
+					sre_doc.update_reserved_stock_in_bin()
+
 					qty_to_deliver -= qty_can_be_deliver
 
 		if self._action == "cancel":
@@ -427,6 +430,9 @@
 					# Update Stock Reservation Entry `Status` based on `Delivered Qty`.
 					sre_doc.update_status()
 
+					# Update Reserved Stock in Bin.
+					sre_doc.update_reserved_stock_in_bin()
+
 					qty_to_undelivered -= qty_can_be_undelivered
 
 	def validate_against_stock_reservation_entries(self):
diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
index 48b8ab7..137c352 100644
--- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
@@ -1029,6 +1029,7 @@
 
 		dn1 = create_delivery_note(is_return=1, return_against=dn.name, qty=-3)
 		si1 = make_sales_invoice(dn1.name)
+		si1.update_billed_amount_in_delivery_note = True
 		si1.insert()
 		si1.submit()
 		dn1.reload()
@@ -1037,6 +1038,7 @@
 
 		dn2 = create_delivery_note(is_return=1, return_against=dn.name, qty=-4)
 		si2 = make_sales_invoice(dn2.name)
+		si2.update_billed_amount_in_delivery_note = True
 		si2.insert()
 		si2.submit()
 		dn2.reload()
@@ -1230,6 +1232,21 @@
 		frappe.db.rollback()
 		frappe.db.set_single_value("Selling Settings", "dont_reserve_sales_order_qty_on_sales_return", 0)
 
+	def test_non_internal_transfer_delivery_note(self):
+		from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
+
+		dn = create_delivery_note(do_not_submit=True)
+		warehouse = create_warehouse("Internal Transfer Warehouse", company=dn.company)
+		dn.items[0].db_set("target_warehouse", warehouse)
+
+		dn.reload()
+
+		self.assertEqual(dn.items[0].target_warehouse, warehouse)
+
+		dn.save()
+		dn.reload()
+		self.assertFalse(dn.items[0].target_warehouse)
+
 
 def create_delivery_note(**args):
 	dn = frappe.new_doc("Delivery Note")
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 d3236ba..6148950 100644
--- a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
+++ b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
@@ -165,7 +165,6 @@
    "oldfieldname": "description",
    "oldfieldtype": "Small Text",
    "print_width": "300px",
-   "reqd": 1,
    "width": "300px"
   },
   {
@@ -726,7 +725,8 @@
    "label": "Against Delivery Note Item",
    "no_copy": 1,
    "print_hide": 1,
-   "read_only": 1
+   "read_only": 1,
+   "search_index": 1
   },
   {
    "fieldname": "stock_qty_sec_break",
@@ -893,7 +893,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-07-26 12:53:49.357171",
+ "modified": "2023-10-16 16:18:18.013379",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Delivery Note Item",
diff --git a/erpnext/stock/doctype/delivery_settings/delivery_settings.json b/erpnext/stock/doctype/delivery_settings/delivery_settings.json
index 963403b..ad0ac45 100644
--- a/erpnext/stock/doctype/delivery_settings/delivery_settings.json
+++ b/erpnext/stock/doctype/delivery_settings/delivery_settings.json
@@ -239,7 +239,7 @@
    "print": 1, 
    "read": 1, 
    "report": 0, 
-   "role": "System Manager", 
+   "role": "Delivery Manager",
    "set_user_permissions": 0, 
    "share": 1, 
    "submit": 0, 
@@ -255,4 +255,4 @@
  "track_changes": 1, 
  "track_seen": 0, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/doctype/delivery_stop/delivery_stop.json b/erpnext/stock/doctype/delivery_stop/delivery_stop.json
index 5610a81..42560e6 100644
--- a/erpnext/stock/doctype/delivery_stop/delivery_stop.json
+++ b/erpnext/stock/doctype/delivery_stop/delivery_stop.json
@@ -1,815 +1,197 @@
 {
- "allow_copy": 0, 
- "allow_events_in_timeline": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "beta": 0, 
- "creation": "2017-10-16 16:46:28.166950", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "creation": "2017-10-16 16:46:28.166950",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "customer",
+  "address",
+  "locked",
+  "column_break_6",
+  "customer_address",
+  "visited",
+  "order_information_section",
+  "delivery_note",
+  "cb_order",
+  "grand_total",
+  "section_break_7",
+  "contact",
+  "email_sent_to",
+  "column_break_7",
+  "customer_contact",
+  "section_break_9",
+  "distance",
+  "estimated_arrival",
+  "lat",
+  "column_break_19",
+  "uom",
+  "lng",
+  "more_information_section",
+  "details"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 2, 
-   "fieldname": "customer", 
-   "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": "Customer", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Customer", 
-   "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": "customer",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Customer",
+   "options": "Customer"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "address", 
-   "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": "Address Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Address", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 1, 
-   "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": "address",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Address Name",
+   "options": "Address",
+   "print_hide": 1,
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "lock", 
-   "fieldtype": "Check", 
-   "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": "Lock", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "default": "0",
+   "fieldname": "locked",
+   "fieldtype": "Check",
+   "in_list_view": 1,
+   "label": "Locked"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_6", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_6",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "customer_address", 
-   "fieldtype": "Small Text", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Customer Address", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "customer_address",
+   "fieldtype": "Small Text",
+   "label": "Customer Address",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 1, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "eval:doc.docstatus==1", 
-   "fieldname": "visited", 
-   "fieldtype": "Check", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Visited", 
-   "length": 0, 
-   "no_copy": 1, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 1, 
-   "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_on_submit": 1,
+   "default": "0",
+   "depends_on": "eval:doc.docstatus==1",
+   "fieldname": "visited",
+   "fieldtype": "Check",
+   "label": "Visited",
+   "no_copy": 1,
+   "print_hide": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "order_information_section", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Order Information", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "order_information_section",
+   "fieldtype": "Section Break",
+   "label": "Order Information"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "delivery_note", 
-   "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": "Delivery Note", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Delivery Note", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 1, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "delivery_note",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Delivery Note",
+   "no_copy": 1,
+   "options": "Delivery Note",
+   "print_hide": 1,
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "cb_order", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "cb_order",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "grand_total", 
-   "fieldtype": "Currency", 
-   "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": "Grand Total", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "grand_total",
+   "fieldtype": "Currency",
+   "label": "Grand Total",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "section_break_7", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Contact Information", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "section_break_7",
+   "fieldtype": "Section Break",
+   "label": "Contact Information"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "contact", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Contact Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Contact", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 1, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "contact",
+   "fieldtype": "Link",
+   "label": "Contact Name",
+   "options": "Contact",
+   "print_hide": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "email_sent_to", 
-   "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": "Email sent to", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "email_sent_to",
+   "fieldtype": "Data",
+   "label": "Email sent to",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_7", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_7",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "customer_contact", 
-   "fieldtype": "Small Text", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Customer Contact", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "customer_contact",
+   "fieldtype": "Small Text",
+   "label": "Customer Contact",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "section_break_9", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Dispatch Information", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "section_break_9",
+   "fieldtype": "Section Break",
+   "label": "Dispatch Information"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "distance", 
-   "fieldtype": "Float", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Distance", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "2", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "distance",
+   "fieldtype": "Float",
+   "label": "Distance",
+   "precision": "2",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "estimated_arrival", 
-   "fieldtype": "Datetime", 
-   "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": "Estimated Arrival", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "estimated_arrival",
+   "fieldtype": "Datetime",
+   "in_list_view": 1,
+   "label": "Estimated Arrival"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "lat", 
-   "fieldtype": "Float", 
-   "hidden": 1, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Latitude", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "lat",
+   "fieldtype": "Float",
+   "hidden": 1,
+   "label": "Latitude"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_19", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_19",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "default": "", 
-   "depends_on": "eval:doc.distance", 
-   "fieldname": "uom", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "UOM", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "UOM", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "depends_on": "eval:doc.distance",
+   "fieldname": "uom",
+   "fieldtype": "Link",
+   "label": "UOM",
+   "options": "UOM",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "lng", 
-   "fieldtype": "Float", 
-   "hidden": 1, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Longitude", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "lng",
+   "fieldtype": "Float",
+   "hidden": 1,
+   "label": "Longitude"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "more_information_section", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "More Information", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "more_information_section",
+   "fieldtype": "Section Break",
+   "label": "More Information"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "details", 
-   "fieldtype": "Text Editor", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Details", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
+   "fieldname": "details",
+   "fieldtype": "Text Editor",
+   "label": "Details"
   }
- ], 
- "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-10-16 05:23:25.661542", 
- "modified_by": "Administrator", 
- "module": "Stock", 
- "name": "Delivery Stop", 
- "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
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2023-09-29 09:22:53.435161",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Delivery Stop",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": [],
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.js b/erpnext/stock/doctype/delivery_trip/delivery_trip.js
index de503dc..158bd0c 100755
--- a/erpnext/stock/doctype/delivery_trip/delivery_trip.js
+++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.js
@@ -62,8 +62,13 @@
 						company: frm.doc.company,
 					}
 				})
-			}, __("Get customers from"));
+			}, __("Get stops from"));
 		}
+		frm.add_custom_button(__("Delivery Notes"), function () {
+			frappe.set_route("List", "Delivery Note",
+					{'name': ["in", frm.doc.delivery_stops.map((stop) => {return stop.delivery_note;})]}
+			);
+		}, __("View"));
 	},
 
 	calculate_arrival_time: function (frm) {
diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.json b/erpnext/stock/doctype/delivery_trip/delivery_trip.json
index 9d8fe46..ec72af8 100644
--- a/erpnext/stock/doctype/delivery_trip/delivery_trip.json
+++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.json
@@ -188,7 +188,7 @@
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2023-06-27 11:22:27.927637",
+ "modified": "2023-10-01 07:06:06.314503",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Delivery Trip",
@@ -224,10 +224,40 @@
    "share": 1,
    "submit": 1,
    "write": 1
+  },
+  {
+   "amend": 1,
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Delivery User",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  },
+  {
+   "amend": 1,
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Delivery Manager",
+   "share": 1,
+   "submit": 1,
+   "write": 1
   }
  ],
  "sort_field": "modified",
  "sort_order": "DESC",
  "states": [],
  "title_field": "driver_name"
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
index af2f411..c531a87 100644
--- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py
+++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
@@ -170,7 +170,7 @@
 		for stop in self.delivery_stops:
 			leg.append(stop.customer_address)
 
-			if optimize and stop.lock:
+			if optimize and stop.locked:
 				route_list.append(leg)
 				leg = [stop.customer_address]
 
diff --git a/erpnext/stock/doctype/delivery_trip/test_delivery_trip.py b/erpnext/stock/doctype/delivery_trip/test_delivery_trip.py
index ed699e3..9b8b46e 100644
--- a/erpnext/stock/doctype/delivery_trip/test_delivery_trip.py
+++ b/erpnext/stock/doctype/delivery_trip/test_delivery_trip.py
@@ -46,7 +46,7 @@
 		self.assertEqual(len(route_list[0]), 4)
 
 	def test_unoptimized_route_list_with_locks(self):
-		self.delivery_trip.delivery_stops[0].lock = 1
+		self.delivery_trip.delivery_stops[0].locked = 1
 		self.delivery_trip.save()
 		route_list = self.delivery_trip.form_route_list(optimize=False)
 
@@ -65,7 +65,7 @@
 		self.assertEqual(len(route_list[0]), 4)
 
 	def test_optimized_route_list_with_locks(self):
-		self.delivery_trip.delivery_stops[0].lock = 1
+		self.delivery_trip.delivery_stops[0].locked = 1
 		self.delivery_trip.save()
 		route_list = self.delivery_trip.form_route_list(optimize=True)
 
diff --git a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.js b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.js
index 0310682..35d1c02 100644
--- a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.js
+++ b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.js
@@ -37,7 +37,7 @@
 		if (frm.doc.__onload && frm.doc.__onload.has_stock_ledger
 			&& frm.doc.__onload.has_stock_ledger.length) {
 			let allow_to_edit_fields = ['disabled', 'fetch_from_parent',
-				'type_of_transaction', 'condition', 'mandatory_depends_on'];
+				'type_of_transaction', 'condition', 'mandatory_depends_on', 'validate_negative_stock'];
 
 			frm.fields.forEach((field) => {
 				if (!in_list(allow_to_edit_fields, field.df.fieldname)) {
diff --git a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.json b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.json
index eb6102a..0e40552 100644
--- a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.json
+++ b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.json
@@ -17,6 +17,8 @@
   "target_fieldname",
   "applicable_for_documents_tab",
   "apply_to_all_doctypes",
+  "column_break_niy2u",
+  "validate_negative_stock",
   "column_break_13",
   "document_type",
   "type_of_transaction",
@@ -173,11 +175,21 @@
    "fieldname": "reqd",
    "fieldtype": "Check",
    "label": "Mandatory"
+  },
+  {
+   "fieldname": "column_break_niy2u",
+   "fieldtype": "Column Break"
+  },
+  {
+   "default": "0",
+   "fieldname": "validate_negative_stock",
+   "fieldtype": "Check",
+   "label": "Validate Negative Stock"
   }
  ],
  "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2023-01-31 13:44:38.507698",
+ "modified": "2023-10-05 12:52:18.705431",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Inventory Dimension",
diff --git a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py
index 8bff4d5..257d18f 100644
--- a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py
+++ b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py
@@ -60,6 +60,7 @@
 			"fetch_from_parent",
 			"type_of_transaction",
 			"condition",
+			"validate_negative_stock",
 		]
 
 		for field in frappe.get_meta("Inventory Dimension").fields:
@@ -160,6 +161,7 @@
 				insert_after="inventory_dimension",
 				options=self.reference_document,
 				label=label,
+				search_index=1,
 				reqd=self.reqd,
 				mandatory_depends_on=self.mandatory_depends_on,
 			),
@@ -255,7 +257,7 @@
 def get_inventory_documents(
 	doctype=None, txt=None, searchfield=None, start=None, page_len=None, filters=None
 ):
-	and_filters = [["DocField", "parent", "not in", ["Batch", "Serial No"]]]
+	and_filters = [["DocField", "parent", "not in", ["Batch", "Serial No", "Item Price"]]]
 	or_filters = [
 		["DocField", "options", "in", ["Batch", "Serial No"]],
 		["DocField", "parent", "in", ["Putaway Rule"]],
@@ -340,6 +342,7 @@
 			fields=[
 				"distinct target_fieldname as fieldname",
 				"reference_document as doctype",
+				"validate_negative_stock",
 			],
 			filters={"disabled": 0},
 		)
diff --git a/erpnext/stock/doctype/inventory_dimension/test_inventory_dimension.py b/erpnext/stock/doctype/inventory_dimension/test_inventory_dimension.py
index 2d273c6..33394e5 100644
--- a/erpnext/stock/doctype/inventory_dimension/test_inventory_dimension.py
+++ b/erpnext/stock/doctype/inventory_dimension/test_inventory_dimension.py
@@ -414,6 +414,53 @@
 			else:
 				self.assertEqual(d.store, "Inter Transfer Store 2")
 
+	def test_validate_negative_stock_for_inventory_dimension(self):
+		frappe.local.inventory_dimensions = {}
+		item_code = "Test Negative Inventory Dimension Item"
+		frappe.db.set_single_value("Stock Settings", "allow_negative_stock", 1)
+		create_item(item_code)
+
+		inv_dimension = create_inventory_dimension(
+			apply_to_all_doctypes=1,
+			dimension_name="Inv Site",
+			reference_document="Inv Site",
+			document_type="Inv Site",
+			validate_negative_stock=1,
+		)
+
+		warehouse = create_warehouse("Negative Stock Warehouse")
+		doc = make_stock_entry(item_code=item_code, target=warehouse, qty=10, do_not_submit=True)
+
+		doc.items[0].to_inv_site = "Site 1"
+		doc.submit()
+
+		site_name = frappe.get_all(
+			"Stock Ledger Entry", filters={"voucher_no": doc.name, "is_cancelled": 0}, fields=["inv_site"]
+		)[0].inv_site
+
+		self.assertEqual(site_name, "Site 1")
+
+		doc = make_stock_entry(item_code=item_code, source=warehouse, qty=100, do_not_submit=True)
+
+		doc.items[0].inv_site = "Site 1"
+		self.assertRaises(frappe.ValidationError, doc.submit)
+
+		inv_dimension.reload()
+		inv_dimension.db_set("validate_negative_stock", 0)
+		frappe.local.inventory_dimensions = {}
+
+		doc = make_stock_entry(item_code=item_code, source=warehouse, qty=100, do_not_submit=True)
+
+		doc.items[0].inv_site = "Site 1"
+		doc.submit()
+		self.assertEqual(doc.docstatus, 1)
+
+		site_name = frappe.get_all(
+			"Stock Ledger Entry", filters={"voucher_no": doc.name, "is_cancelled": 0}, fields=["inv_site"]
+		)[0].inv_site
+
+		self.assertEqual(site_name, "Site 1")
+
 
 def get_voucher_sl_entries(voucher_no, fields):
 	return frappe.get_all(
@@ -504,6 +551,26 @@
 			}
 		).insert(ignore_permissions=True)
 
+	if not frappe.db.exists("DocType", "Inv Site"):
+		frappe.get_doc(
+			{
+				"doctype": "DocType",
+				"name": "Inv Site",
+				"module": "Stock",
+				"custom": 1,
+				"naming_rule": "By fieldname",
+				"autoname": "field:site_name",
+				"fields": [{"label": "Site Name", "fieldname": "site_name", "fieldtype": "Data"}],
+				"permissions": [
+					{"role": "System Manager", "permlevel": 0, "read": 1, "write": 1, "create": 1, "delete": 1}
+				],
+			}
+		).insert(ignore_permissions=True)
+
+	for site in ["Site 1", "Site 2"]:
+		if not frappe.db.exists("Inv Site", site):
+			frappe.get_doc({"doctype": "Inv Site", "site_name": site}).insert(ignore_permissions=True)
+
 
 def create_inventory_dimension(**args):
 	args = frappe._dict(args)
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index 4ae9bf5..6e810e5 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -125,36 +125,6 @@
 			erpnext.toggle_naming_series();
 		}
 
-		if (!frm.doc.published_in_website) {
-			frm.add_custom_button(__("Publish in Website"), function() {
-				frappe.call({
-					method: "erpnext.e_commerce.doctype.website_item.website_item.make_website_item",
-					args: {doc: frm.doc},
-					freeze: true,
-					freeze_message: __("Publishing Item ..."),
-					callback: function(result) {
-						frappe.msgprint({
-							message: __("Website Item {0} has been created.",
-								[repl('<a href="/app/website-item/%(item_encoded)s" class="strong">%(item)s</a>', {
-									item_encoded: encodeURIComponent(result.message[0]),
-									item: result.message[1]
-								})]
-							),
-							title: __("Published"),
-							indicator: "green"
-						});
-					}
-				});
-			}, __('Actions'));
-		} else {
-			frm.add_custom_button(__("Website Item"), function() {
-				frappe.db.get_value("Website Item", {item_code: frm.doc.name}, "name", (d) => {
-					if (!d.name) frappe.throw(__("Website Item not found"));
-					frappe.set_route("Form", "Website Item", d.name);
-				});
-			}, __("View"));
-		}
-
 		erpnext.item.edit_prices_button(frm);
 		erpnext.item.toggle_attributes(frm);
 
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index 1bcddfa..c13d3eb 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -117,7 +117,6 @@
   "customer_code",
   "default_item_manufacturer",
   "default_manufacturer_part_no",
-  "published_in_website",
   "total_projected_qty"
  ],
  "fields": [
@@ -380,7 +379,7 @@
    "options": "fa fa-rss"
   },
   {
-   "description": "Will also apply for variants unless overrridden",
+   "description": "Will also apply for variants unless overridden",
    "fieldname": "reorder_levels",
    "fieldtype": "Table",
    "label": "Reorder level based on Warehouse",
@@ -816,14 +815,6 @@
    "read_only": 1
   },
   {
-   "default": "0",
-   "depends_on": "published_in_website",
-   "fieldname": "published_in_website",
-   "fieldtype": "Check",
-   "label": "Published in Website",
-   "read_only": 1
-  },
-  {
    "default": "1",
    "fieldname": "grant_commission",
    "fieldtype": "Check",
@@ -970,4 +961,4 @@
  "states": [],
  "title_field": "item_name",
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index aff9587..d8935fe 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -32,7 +32,6 @@
 	make_variant_item_code,
 	validate_item_variant_attributes,
 )
-from erpnext.setup.doctype.item_group.item_group import invalidate_cache_for
 from erpnext.stock.doctype.item_default.item_default import ItemDefault
 
 
@@ -122,10 +121,8 @@
 			self.old_item_group = frappe.db.get_value(self.doctype, self.name, "item_group")
 
 	def on_update(self):
-		invalidate_cache_for_item(self)
 		self.update_variants()
 		self.update_item_price()
-		self.update_website_item()
 
 	def validate_description(self):
 		"""Clean HTML description if set"""
@@ -248,29 +245,6 @@
 		if self.stock_uom not in uoms_list:
 			self.append("uoms", {"uom": self.stock_uom, "conversion_factor": 1})
 
-	def update_website_item(self):
-		"""Update Website Item if change in Item impacts it."""
-		web_item = frappe.db.exists("Website Item", {"item_code": self.item_code})
-
-		if web_item:
-			changed = {}
-			editable_fields = ["item_name", "item_group", "stock_uom", "brand", "description", "disabled"]
-			doc_before_save = self.get_doc_before_save()
-
-			for field in editable_fields:
-				if doc_before_save.get(field) != self.get(field):
-					if field == "disabled":
-						changed["published"] = not self.get(field)
-					else:
-						changed[field] = self.get(field)
-
-			if not changed:
-				return
-
-			web_item_doc = frappe.get_doc("Website Item", web_item)
-			web_item_doc.update(changed)
-			web_item_doc.save()
-
 	def validate_item_tax_net_rate_range(self):
 		for tax in self.get("taxes"):
 			if flt(tax.maximum_net_rate) < flt(tax.minimum_net_rate):
@@ -281,7 +255,7 @@
 
 		# add item taxes from template
 		for d in template.get("taxes"):
-			self.append("taxes", {"item_tax_template": d.item_tax_template})
+			self.append("taxes", d)
 
 		# copy re-order table if empty
 		if not self.get("reorder_levels"):
@@ -454,7 +428,6 @@
 		if merge:
 			self.validate_properties_before_merge(new_name)
 			self.validate_duplicate_product_bundles_before_merge(old_name, new_name)
-			self.validate_duplicate_website_item_before_merge(old_name, new_name)
 			self.delete_old_bins(old_name)
 
 	def after_rename(self, old_name, new_name, merge):
@@ -466,9 +439,6 @@
 				title=_("Note"),
 			)
 
-		if self.published_in_website:
-			invalidate_cache_for_item(self)
-
 		frappe.db.set_value("Item", new_name, "item_code", new_name)
 
 		if merge:
@@ -554,27 +524,6 @@
 			)
 			frappe.throw(msg, title=_("Cannot Merge"), exc=DataValidationError)
 
-	def validate_duplicate_website_item_before_merge(self, old_name, new_name):
-		"""
-		Block merge if both old and new items have website items against them.
-		This is to avoid duplicate website items after merging.
-		"""
-		web_items = frappe.get_all(
-			"Website Item",
-			filters={"item_code": ["in", [old_name, new_name]]},
-			fields=["item_code", "name"],
-		)
-
-		if len(web_items) <= 1:
-			return
-
-		old_web_item = [d.get("name") for d in web_items if d.get("item_code") == old_name][0]
-		web_item_link = get_link_to_form("Website Item", old_web_item)
-		old_name, new_name = frappe.bold(old_name), frappe.bold(new_name)
-
-		msg = f"Please delete linked Website Item {frappe.bold(web_item_link)} before merging {old_name} into {new_name}"
-		frappe.throw(_(msg), title=_("Cannot Merge"), exc=DataValidationError)
-
 	def set_last_purchase_rate(self, new_name):
 		last_purchase_rate = get_last_purchase_details(new_name).get("base_net_rate", 0)
 		frappe.db.set_value("Item", new_name, "last_purchase_rate", last_purchase_rate)
@@ -1151,32 +1100,6 @@
 	return out
 
 
-def invalidate_cache_for_item(doc):
-	"""Invalidate Item Group cache and rebuild ItemVariantsCacheManager."""
-	invalidate_cache_for(doc, doc.item_group)
-
-	if doc.get("old_item_group") and doc.get("old_item_group") != doc.item_group:
-		invalidate_cache_for(doc, doc.old_item_group)
-
-	invalidate_item_variants_cache_for_website(doc)
-
-
-def invalidate_item_variants_cache_for_website(doc):
-	"""Rebuild ItemVariantsCacheManager via Item or Website Item."""
-	from erpnext.e_commerce.variant_selector.item_variants_cache import ItemVariantsCacheManager
-
-	item_code = None
-	is_web_item = doc.get("published_in_website") or doc.get("published")
-	if doc.has_variants and is_web_item:
-		item_code = doc.item_code
-	elif doc.variant_of and frappe.db.get_value("Item", doc.variant_of, "published_in_website"):
-		item_code = doc.variant_of
-
-	if item_code:
-		item_cache = ItemVariantsCacheManager(item_code)
-		item_cache.rebuild_cache()
-
-
 def check_stock_uom_with_bin(item, stock_uom):
 	if stock_uom == frappe.db.get_value("Item", item, "stock_uom"):
 		return
diff --git a/erpnext/stock/doctype/item/item_dashboard.py b/erpnext/stock/doctype/item/item_dashboard.py
index 34bb4d1..88ae34f 100644
--- a/erpnext/stock/doctype/item/item_dashboard.py
+++ b/erpnext/stock/doctype/item/item_dashboard.py
@@ -32,6 +32,5 @@
 			{"label": _("Manufacture"), "items": ["Production Plan", "Work Order", "Item Manufacturer"]},
 			{"label": _("Traceability"), "items": ["Serial No", "Batch"]},
 			{"label": _("Stock Movement"), "items": ["Stock Entry", "Stock Reconciliation"]},
-			{"label": _("E-commerce"), "items": ["Website Item"]},
 		],
 	}
diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py
index 0c6dc77..09d3dd1 100644
--- a/erpnext/stock/doctype/item/test_item.py
+++ b/erpnext/stock/doctype/item/test_item.py
@@ -163,7 +163,7 @@
 			{
 				"item_code": "_Test Item With Item Tax Template",
 				"tax_category": "_Test Tax Category 2",
-				"item_tax_template": None,
+				"item_tax_template": "",
 			},
 			{
 				"item_code": "_Test Item Inherit Group Item Tax Template 1",
@@ -178,7 +178,7 @@
 			{
 				"item_code": "_Test Item Inherit Group Item Tax Template 1",
 				"tax_category": "_Test Tax Category 2",
-				"item_tax_template": None,
+				"item_tax_template": "",
 			},
 			{
 				"item_code": "_Test Item Inherit Group Item Tax Template 2",
@@ -193,7 +193,7 @@
 			{
 				"item_code": "_Test Item Inherit Group Item Tax Template 2",
 				"tax_category": "_Test Tax Category 2",
-				"item_tax_template": None,
+				"item_tax_template": "",
 			},
 			{
 				"item_code": "_Test Item Override Group Item Tax Template",
@@ -208,12 +208,12 @@
 			{
 				"item_code": "_Test Item Override Group Item Tax Template",
 				"tax_category": "_Test Tax Category 2",
-				"item_tax_template": None,
+				"item_tax_template": "",
 			},
 		]
 
 		expected_item_tax_map = {
-			None: {},
+			"": {},
 			"_Test Account Excise Duty @ 10 - _TC": {"_Test Account Excise Duty - _TC": 10},
 			"_Test Account Excise Duty @ 12 - _TC": {"_Test Account Excise Duty - _TC": 12},
 			"_Test Account Excise Duty @ 15 - _TC": {"_Test Account Excise Duty - _TC": 15},
@@ -907,6 +907,8 @@
 	opening_stock=0,
 	is_fixed_asset=0,
 	asset_category=None,
+	buying_cost_center=None,
+	selling_cost_center=None,
 	company="_Test Company",
 ):
 	if not frappe.db.exists("Item", item_code):
@@ -924,7 +926,15 @@
 		item.is_purchase_item = is_purchase_item
 		item.is_customer_provided_item = is_customer_provided_item
 		item.customer = customer or ""
-		item.append("item_defaults", {"default_warehouse": warehouse, "company": company})
+		item.append(
+			"item_defaults",
+			{
+				"default_warehouse": warehouse,
+				"company": company,
+				"selling_cost_center": selling_cost_center,
+				"buying_cost_center": buying_cost_center,
+			},
+		)
 		item.save()
 	else:
 		item = frappe.get_doc("Item", item_code)
diff --git a/erpnext/stock/doctype/item_price/item_price.js b/erpnext/stock/doctype/item_price/item_price.js
index ce489ff..8a4b4ee 100644
--- a/erpnext/stock/doctype/item_price/item_price.js
+++ b/erpnext/stock/doctype/item_price/item_price.js
@@ -6,7 +6,6 @@
 		frm.set_query("item_code", function() {
 			return {
 				filters: {
-					"disabled": 0,
 					"has_variants": 0
 				}
 			};
diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
index 7f0dc2d..8bbc660 100644
--- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
+++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
@@ -205,7 +205,11 @@
 				)
 				docs = frappe.db.get_all(
 					"Asset",
-					filters={receipt_document_type: item.receipt_document, "item_code": item.item_code},
+					filters={
+						receipt_document_type: item.receipt_document,
+						"item_code": item.item_code,
+						"docstatus": ["!=", 2],
+					},
 					fields=["name", "docstatus"],
 				)
 				if not docs or len(docs) != item.qty:
diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js
index bf3301f..9673a70 100644
--- a/erpnext/stock/doctype/material_request/material_request.js
+++ b/erpnext/stock/doctype/material_request/material_request.js
@@ -102,6 +102,12 @@
 
 		if (frm.doc.docstatus == 1 && frm.doc.status != 'Stopped') {
 			let precision = frappe.defaults.get_default("float_precision");
+
+			if (flt(frm.doc.per_received, precision) < 100) {
+				frm.add_custom_button(__('Stop'),
+					() => frm.events.update_status(frm, 'Stopped'));
+			}
+
 			if (flt(frm.doc.per_ordered, precision) < 100) {
 				let add_create_pick_list_button = () => {
 					frm.add_custom_button(__('Pick List'),
@@ -148,11 +154,6 @@
 				}
 
 				frm.page.set_inner_btn_group_as_primary(__('Create'));
-
-				// stop
-				frm.add_custom_button(__('Stop'),
-					() => frm.events.update_status(frm, 'Stopped'));
-
 			}
 		}
 
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index a51028d..ecdec80 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -401,6 +401,7 @@
 					["uom", "uom"],
 					["sales_order", "sales_order"],
 					["sales_order_item", "sales_order_item"],
+					["wip_composite_asset", "wip_composite_asset"],
 				],
 				"postprocess": update_item,
 				"condition": select_item,
diff --git a/erpnext/stock/doctype/material_request_item/material_request_item.json b/erpnext/stock/doctype/material_request_item/material_request_item.json
index 770dacd..9912be1 100644
--- a/erpnext/stock/doctype/material_request_item/material_request_item.json
+++ b/erpnext/stock/doctype/material_request_item/material_request_item.json
@@ -37,6 +37,10 @@
   "rate",
   "col_break3",
   "amount",
+  "accounting_details_section",
+  "expense_account",
+  "column_break_glru",
+  "wip_composite_asset",
   "manufacture_details",
   "manufacturer",
   "manufacturer_part_no",
@@ -50,11 +54,10 @@
   "lead_time_date",
   "sales_order",
   "sales_order_item",
+  "col_break4",
   "production_plan",
   "material_request_plan_item",
   "job_card_item",
-  "col_break4",
-  "expense_account",
   "section_break_46",
   "page_break"
  ],
@@ -104,7 +107,6 @@
    "oldfieldname": "description",
    "oldfieldtype": "Text",
    "print_width": "250px",
-   "reqd": 1,
    "width": "250px"
   },
   {
@@ -455,13 +457,28 @@
    "label": "Job Card Item",
    "no_copy": 1,
    "print_hide": 1
+  },
+  {
+   "fieldname": "accounting_details_section",
+   "fieldtype": "Section Break",
+   "label": "Accounting Details"
+  },
+  {
+   "fieldname": "column_break_glru",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "wip_composite_asset",
+   "fieldtype": "Link",
+   "label": "WIP Composite Asset",
+   "options": "Asset"
   }
  ],
  "idx": 1,
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-05-07 20:23:31.250252",
+ "modified": "2023-10-27 15:53:41.444236",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Material Request Item",
diff --git a/erpnext/stock/doctype/pick_list/pick_list.js b/erpnext/stock/doctype/pick_list/pick_list.js
index ae05b80..7cd171e 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.js
+++ b/erpnext/stock/doctype/pick_list/pick_list.js
@@ -265,7 +265,8 @@
 			from_date: moment(frm.doc.creation).format('YYYY-MM-DD'),
 			to_date: to_date,
 			voucher_type: "Sales Order",
-			against_pick_list: frm.doc.name,
+			from_voucher_type: "Pick List",
+			from_voucher_no: frm.doc.name,
 		}
 		frappe.set_route("query-report", "Reserved Stock");
 	}
diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py
index 2fcd102..ed20209 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.py
+++ b/erpnext/stock/doctype/pick_list/pick_list.py
@@ -229,20 +229,27 @@
 	def create_stock_reservation_entries(self, notify=True) -> None:
 		"""Creates Stock Reservation Entries for Sales Order Items against Pick List."""
 
-		from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import (
-			create_stock_reservation_entries_for_so_items,
-		)
-
-		so_details = {}
+		so_items_details_map = {}
 		for location in self.locations:
 			if location.warehouse and location.sales_order and location.sales_order_item:
-				so_details.setdefault(location.sales_order, []).append(location)
+				item_details = {
+					"name": location.sales_order_item,
+					"item_code": location.item_code,
+					"warehouse": location.warehouse,
+					"qty_to_reserve": (flt(location.picked_qty) - flt(location.stock_reserved_qty)),
+					"from_voucher_no": location.parent,
+					"from_voucher_detail_no": location.name,
+					"serial_and_batch_bundle": location.serial_and_batch_bundle,
+				}
+				so_items_details_map.setdefault(location.sales_order, []).append(item_details)
 
-		if so_details:
-			for so, locations in so_details.items():
+		if so_items_details_map:
+			for so, items_details in so_items_details_map.items():
 				so_doc = frappe.get_doc("Sales Order", so)
-				create_stock_reservation_entries_for_so_items(
-					so=so_doc, items_details=locations, against_pick_list=True, notify=notify
+				so_doc.create_stock_reservation_entries(
+					items_details=items_details,
+					from_voucher_type="Pick List",
+					notify=notify,
 				)
 
 	@frappe.whitelist()
@@ -253,7 +260,9 @@
 			cancel_stock_reservation_entries,
 		)
 
-		cancel_stock_reservation_entries(against_pick_list=self.name, notify=notify)
+		cancel_stock_reservation_entries(
+			from_voucher_type="Pick List", from_voucher_no=self.name, notify=notify
+		)
 
 	def validate_picked_qty(self, data):
 		over_delivery_receipt_allowance = 100 + flt(
diff --git a/erpnext/stock/doctype/pick_list/pick_list_dashboard.py b/erpnext/stock/doctype/pick_list/pick_list_dashboard.py
index 0830fa2..29571a5 100644
--- a/erpnext/stock/doctype/pick_list/pick_list_dashboard.py
+++ b/erpnext/stock/doctype/pick_list/pick_list_dashboard.py
@@ -2,7 +2,7 @@
 	return {
 		"fieldname": "pick_list",
 		"non_standard_fieldnames": {
-			"Stock Reservation Entry": "against_pick_list",
+			"Stock Reservation Entry": "from_voucher_no",
 		},
 		"internal_links": {
 			"Sales Order": ["locations", "sales_order"],
diff --git a/erpnext/stock/doctype/price_list/price_list.py b/erpnext/stock/doctype/price_list/price_list.py
index e77d53a..21c0f18 100644
--- a/erpnext/stock/doctype/price_list/price_list.py
+++ b/erpnext/stock/doctype/price_list/price_list.py
@@ -13,9 +13,6 @@
 		if not cint(self.buying) and not cint(self.selling):
 			throw(_("Price List must be applicable for Buying or Selling"))
 
-		if not self.is_new():
-			self.check_impact_on_shopping_cart()
-
 	def on_update(self):
 		self.set_default_if_missing()
 		self.update_item_price()
@@ -37,19 +34,6 @@
 			(self.currency, cint(self.buying), cint(self.selling), self.name),
 		)
 
-	def check_impact_on_shopping_cart(self):
-		"Check if Price List currency change impacts E Commerce Cart."
-		from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import (
-			validate_cart_settings,
-		)
-
-		doc_before_save = self.get_doc_before_save()
-		currency_changed = self.currency != doc_before_save.currency
-		affects_cart = self.name == frappe.db.get_single_value("E Commerce Settings", "price_list")
-
-		if currency_changed and affects_cart:
-			validate_cart_settings()
-
 	def on_trash(self):
 		self.delete_price_list_details_key()
 
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index 2bb479b..6552cd7 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -37,6 +37,12 @@
 			}
 		});
 
+		frm.set_query("wip_composite_asset", "items", function() {
+			return {
+				filters: {'is_composite_asset': 1, 'docstatus': 0 }
+			}
+		});
+
 		frm.set_query("taxes_and_charges", function() {
 			return {
 				filters: {'company': frm.doc.company }
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
index 912b908..c8a9e3e 100755
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
@@ -464,6 +464,7 @@
    "depends_on": "eval:doc.is_subcontracted",
    "fieldname": "supplier_warehouse",
    "fieldtype": "Link",
+   "ignore_user_permissions": 1,
    "label": "Supplier Warehouse",
    "no_copy": 1,
    "oldfieldname": "supplier_warehouse",
@@ -1241,7 +1242,7 @@
  "idx": 261,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-07-04 17:23:17.025390",
+ "modified": "2023-10-01 21:00:44.556816",
  "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 836dda7..6874044 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -13,7 +13,6 @@
 import erpnext
 from erpnext.accounts.utils import get_account_currency
 from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_enabled
-from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
 from erpnext.buying.utils import check_on_hold_or_closed_status
 from erpnext.controllers.buying_controller import BuyingController
 from erpnext.stock.doctype.delivery_note.delivery_note import make_inter_company_transaction
@@ -144,8 +143,8 @@
 			if item.is_fixed_asset and is_cwip_accounting_enabled(item.asset_category):
 				# check cwip accounts before making auto assets
 				# Improves UX by not giving messages of "Assets Created" before throwing error of not finding arbnb account
-				arbnb_account = self.get_company_default("asset_received_but_not_billed")
-				cwip_account = get_asset_account(
+				self.get_company_default("asset_received_but_not_billed")
+				get_asset_account(
 					"capital_work_in_progress_account", asset_category=item.asset_category, company=self.company
 				)
 				break
@@ -264,6 +263,7 @@
 		self.make_gl_entries()
 		self.repost_future_sle_and_gle()
 		self.set_consumed_qty_in_subcontract_order()
+		self.reserve_stock_for_sales_order()
 
 	def check_next_docstatus(self):
 		submit_rv = frappe.db.sql(
@@ -313,7 +313,7 @@
 
 		self.make_item_gl_entries(gl_entries, warehouse_account=warehouse_account)
 		self.make_tax_gl_entries(gl_entries)
-		self.get_asset_gl_entry(gl_entries)
+		update_regional_gl_entries(gl_entries, self)
 
 		return process_gl_map(gl_entries)
 
@@ -322,14 +322,6 @@
 			get_purchase_document_details,
 		)
 
-		stock_rbnb = None
-		if erpnext.is_perpetual_inventory_enabled(self.company):
-			stock_rbnb = self.get_company_default("stock_received_but_not_billed")
-			landed_cost_entries = get_item_account_wise_additional_cost(self.name)
-			expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
-
-		warehouse_with_no_account = []
-		stock_items = self.get_stock_items()
 		provisional_accounting_for_non_stock_items = cint(
 			frappe.db.get_value(
 				"Company", self.company, "enable_provisional_accounting_for_non_stock_items"
@@ -338,28 +330,258 @@
 
 		exchange_rate_map, net_rate_map = get_purchase_document_details(self)
 
+		def validate_account(account_type):
+			frappe.throw(_("{0} account not found while submitting purchase receipt").format(account_type))
+
+		def make_item_asset_inward_gl_entry(item, stock_value_diff, stock_asset_account_name):
+			account_currency = get_account_currency(stock_asset_account_name)
+
+			if not stock_asset_account_name:
+				validate_account("Asset or warehouse account")
+
+			self.add_gl_entry(
+				gl_entries=gl_entries,
+				account=stock_asset_account_name,
+				cost_center=d.cost_center,
+				debit=stock_value_diff,
+				credit=0.0,
+				remarks=remarks,
+				against_account=stock_asset_rbnb,
+				account_currency=account_currency,
+				item=item,
+			)
+
+		def make_stock_received_but_not_billed_entry(item):
+			account = (
+				warehouse_account[item.from_warehouse]["account"] if item.from_warehouse else stock_asset_rbnb
+			)
+			account_currency = get_account_currency(account)
+
+			# GL Entry for from warehouse or Stock Received but not billed
+			# Intentionally passed negative debit amount to avoid incorrect GL Entry validation
+			credit_amount = (
+				flt(item.base_net_amount, item.precision("base_net_amount"))
+				if account_currency == self.company_currency
+				else flt(item.net_amount, item.precision("net_amount"))
+			)
+
+			outgoing_amount = item.base_net_amount
+			if self.is_internal_transfer() and item.valuation_rate:
+				outgoing_amount = abs(get_stock_value_difference(self.name, item.name, item.from_warehouse))
+				credit_amount = outgoing_amount
+
+			if credit_amount:
+				if not account:
+					validate_account("Stock or Asset Received But Not Billed")
+
+				self.add_gl_entry(
+					gl_entries=gl_entries,
+					account=account,
+					cost_center=item.cost_center,
+					debit=-1 * flt(outgoing_amount, item.precision("base_net_amount")),
+					credit=0.0,
+					remarks=remarks,
+					against_account=stock_asset_account_name,
+					debit_in_account_currency=-1 * flt(outgoing_amount, item.precision("base_net_amount")),
+					account_currency=account_currency,
+					item=item,
+				)
+
+				# check if the exchange rate has changed
+				if d.get("purchase_invoice"):
+					if (
+						exchange_rate_map[item.purchase_invoice]
+						and self.conversion_rate != exchange_rate_map[item.purchase_invoice]
+						and item.net_rate == net_rate_map[item.purchase_invoice_item]
+					):
+
+						discrepancy_caused_by_exchange_rate_difference = (item.qty * item.net_rate) * (
+							exchange_rate_map[item.purchase_invoice] - self.conversion_rate
+						)
+
+						self.add_gl_entry(
+							gl_entries=gl_entries,
+							account=account,
+							cost_center=item.cost_center,
+							debit=0.0,
+							credit=discrepancy_caused_by_exchange_rate_difference,
+							remarks=remarks,
+							against_account=self.supplier,
+							debit_in_account_currency=-1 * discrepancy_caused_by_exchange_rate_difference,
+							account_currency=account_currency,
+							item=item,
+						)
+   
+						self.add_gl_entry(
+							gl_entries=gl_entries,
+							account=self.get_company_default("exchange_gain_loss_account"),
+							cost_center=d.cost_center,
+							debit=discrepancy_caused_by_exchange_rate_difference,
+							credit=0.0,
+							remarks=remarks,
+							against_account=self.supplier,
+							debit_in_account_currency=-1 * discrepancy_caused_by_exchange_rate_difference,
+							account_currency=account_currency,
+							item=item,
+						)
+
+			return outgoing_amount
+
+		def make_landed_cost_gl_entries(item):
+			# Amount added through landed-cost-voucher
+			if item.landed_cost_voucher_amount and landed_cost_entries:
+				if (item.item_code, item.name) in landed_cost_entries:
+					for account, amount in landed_cost_entries[(item.item_code, item.name)].items():
+						account_currency = get_account_currency(account)
+						credit_amount = (
+							flt(amount["base_amount"])
+							if (amount["base_amount"] or account_currency != self.company_currency)
+							else flt(amount["amount"])
+						)
+
+						if not account:
+							validate_account("Landed Cost Account")
+
+						self.add_gl_entry(
+							gl_entries=gl_entries,
+							account=account,
+							cost_center=item.cost_center,
+							debit=0.0,
+							credit=credit_amount,
+							remarks=remarks,
+							against_account=stock_asset_account_name,
+							credit_in_account_currency=flt(amount["amount"]),
+							account_currency=account_currency,
+							project=item.project,
+							item=item,
+						)
+
+		def make_rate_difference_entry(item):
+			if item.rate_difference_with_purchase_invoice and stock_asset_rbnb:
+				account_currency = get_account_currency(stock_asset_rbnb)
+				self.add_gl_entry(
+					gl_entries=gl_entries,
+					account=stock_asset_rbnb,
+					cost_center=item.cost_center,
+					debit=0.0,
+					credit=flt(item.rate_difference_with_purchase_invoice),
+					remarks=_("Adjustment based on Purchase Invoice rate"),
+					against_account=stock_asset_account_name,
+					account_currency=account_currency,
+					project=item.project,
+					item=item,
+				)
+
+		def make_sub_contracting_gl_entries(item):
+			# sub-contracting warehouse
+			if flt(item.rm_supp_cost) and warehouse_account.get(self.supplier_warehouse):
+				self.add_gl_entry(
+					gl_entries=gl_entries,
+					account=supplier_warehouse_account,
+					cost_center=item.cost_center,
+					debit=0.0,
+					credit=flt(item.rm_supp_cost),
+					remarks=remarks,
+					against_account=stock_asset_account_name,
+					account_currency=supplier_warehouse_account_currency,
+					item=item,
+				)
+
+		def make_divisional_loss_gl_entry(item, outgoing_amount):
+			if item.is_fixed_asset:
+				return
+
+			# divisional loss adjustment
+			valuation_amount_as_per_doc = (
+				flt(outgoing_amount, d.precision("base_net_amount"))
+				+ flt(item.landed_cost_voucher_amount)
+				+ flt(item.rm_supp_cost)
+				+ flt(item.item_tax_amount)
+				+ flt(item.rate_difference_with_purchase_invoice)
+			)
+
+			divisional_loss = flt(
+				valuation_amount_as_per_doc - flt(stock_value_diff), item.precision("base_net_amount")
+			)
+
+			if divisional_loss:
+				loss_account = (
+					self.get_company_default("default_expense_account", ignore_validation=True)
+					or stock_asset_rbnb
+				)
+
+				cost_center = item.cost_center or frappe.get_cached_value(
+					"Company", self.company, "cost_center"
+				)
+				account_currency = get_account_currency(loss_account)
+				self.add_gl_entry(
+					gl_entries=gl_entries,
+					account=loss_account,
+					cost_center=cost_center,
+					debit=divisional_loss,
+					credit=0.0,
+					remarks=remarks,
+					against_account=stock_asset_account_name,
+					account_currency=account_currency,
+					project=item.project,
+					item=item,
+				)
+
+		stock_items = self.get_stock_items()
+		warehouse_with_no_account = []
+
 		for d in self.get("items"):
-			if d.item_code in stock_items and flt(d.valuation_rate) and flt(d.qty):
-				if warehouse_account.get(d.warehouse):
-					stock_value_diff = frappe.db.get_value(
-						"Stock Ledger Entry",
-						{
-							"voucher_type": "Purchase Receipt",
-							"voucher_no": self.name,
-							"voucher_detail_no": d.name,
-							"warehouse": d.warehouse,
-							"is_cancelled": 0,
-						},
-						"stock_value_difference",
+			if (
+				provisional_accounting_for_non_stock_items
+				and d.item_code not in stock_items
+				and flt(d.qty)
+				and d.get("provisional_expense_account")
+				and not d.is_fixed_asset
+			):
+				self.add_provisional_gl_entry(
+					d, gl_entries, self.posting_date, d.get("provisional_expense_account")
+				)
+			elif flt(d.qty) and (flt(d.valuation_rate) or self.is_return):
+				remarks = self.get("remarks") or _("Accounting Entry for {0}").format(
+					"Asset" if d.is_fixed_asset else "Stock"
+				)
+
+				if not (
+					(erpnext.is_perpetual_inventory_enabled(self.company) and d.item_code in stock_items)
+					or d.is_fixed_asset
+				):
+					continue
+
+				stock_asset_rbnb = (
+					self.get_company_default("asset_received_but_not_billed")
+					if d.is_fixed_asset
+					else self.get_company_default("stock_received_but_not_billed")
+				)
+				landed_cost_entries = get_item_account_wise_additional_cost(self.name)
+
+				if d.is_fixed_asset:
+					account_type = (
+						"capital_work_in_progress_account"
+						if is_cwip_accounting_enabled(d.asset_category)
+						else "fixed_asset_account"
 					)
 
-					warehouse_account_name = warehouse_account[d.warehouse]["account"]
-					warehouse_account_currency = warehouse_account[d.warehouse]["account_currency"]
+					stock_asset_account_name = get_asset_account(
+						account_type, asset_category=d.asset_category, company=self.company
+					)
+
+					stock_value_diff = (
+						flt(d.net_amount)
+						+ flt(d.item_tax_amount / self.conversion_rate)
+						+ flt(d.landed_cost_voucher_amount)
+					)
+				elif warehouse_account.get(d.warehouse):
+					stock_value_diff = get_stock_value_difference(self.name, d.name, d.warehouse)
+					stock_asset_account_name = warehouse_account[d.warehouse]["account"]
 					supplier_warehouse_account = warehouse_account.get(self.supplier_warehouse, {}).get("account")
 					supplier_warehouse_account_currency = warehouse_account.get(self.supplier_warehouse, {}).get(
 						"account_currency"
 					)
-					remarks = self.get("remarks") or _("Accounting Entry for Stock")
 
 					# If PR is sub-contracted and fg item rate is zero
 					# in that case if account for source and target warehouse are same,
@@ -367,216 +589,24 @@
 					if (
 						flt(stock_value_diff) == flt(d.rm_supp_cost)
 						and warehouse_account.get(self.supplier_warehouse)
-						and warehouse_account_name == supplier_warehouse_account
+						and stock_asset_account_name == supplier_warehouse_account
 					):
 						continue
 
-					self.add_gl_entry(
-						gl_entries=gl_entries,
-						account=warehouse_account_name,
-						cost_center=d.cost_center,
-						debit=stock_value_diff,
-						credit=0.0,
-						remarks=remarks,
-						against_account=stock_rbnb,
-						account_currency=warehouse_account_currency,
-						item=d,
-					)
-
-					# GL Entry for from warehouse or Stock Received but not billed
-					# Intentionally passed negative debit amount to avoid incorrect GL Entry validation
-					credit_currency = (
-						get_account_currency(warehouse_account[d.from_warehouse]["account"])
-						if d.from_warehouse
-						else get_account_currency(stock_rbnb)
-					)
-
-					credit_amount = (
-						flt(d.base_net_amount, d.precision("base_net_amount"))
-						if credit_currency == self.company_currency
-						else flt(d.net_amount, d.precision("net_amount"))
-					)
-
-					outgoing_amount = d.base_net_amount
-					if self.is_internal_transfer() and d.valuation_rate:
-						outgoing_amount = abs(
-							frappe.db.get_value(
-								"Stock Ledger Entry",
-								{
-									"voucher_type": "Purchase Receipt",
-									"voucher_no": self.name,
-									"voucher_detail_no": d.name,
-									"warehouse": d.from_warehouse,
-									"is_cancelled": 0,
-								},
-								"stock_value_difference",
-							)
-						)
-						credit_amount = outgoing_amount
-
-					if credit_amount:
-						account = warehouse_account[d.from_warehouse]["account"] if d.from_warehouse else stock_rbnb
-
-						self.add_gl_entry(
-							gl_entries=gl_entries,
-							account=account,
-							cost_center=d.cost_center,
-							debit=-1 * flt(outgoing_amount, d.precision("base_net_amount")),
-							credit=0.0,
-							remarks=remarks,
-							against_account=warehouse_account_name,
-							debit_in_account_currency=-1 * credit_amount,
-							account_currency=credit_currency,
-							item=d,
-						)
-
-						# check if the exchange rate has changed
-						if d.get("purchase_invoice"):
-							if (
-								exchange_rate_map[d.purchase_invoice]
-								and self.conversion_rate != exchange_rate_map[d.purchase_invoice]
-								and d.net_rate == net_rate_map[d.purchase_invoice_item]
-							):
-
-								discrepancy_caused_by_exchange_rate_difference = (d.qty * d.net_rate) * (
-									exchange_rate_map[d.purchase_invoice] - self.conversion_rate
-								)
-
-								self.add_gl_entry(
-									gl_entries=gl_entries,
-									account=account,
-									cost_center=d.cost_center,
-									debit=0.0,
-									credit=discrepancy_caused_by_exchange_rate_difference,
-									remarks=remarks,
-									against_type="Supplier",
-									against_account=self.supplier,
-									debit_in_account_currency=-1 * discrepancy_caused_by_exchange_rate_difference,
-									account_currency=credit_currency,
-									item=d,
-								)
-
-								self.add_gl_entry(
-									gl_entries=gl_entries,
-									account=self.get_company_default("exchange_gain_loss_account"),
-									cost_center=d.cost_center,
-									debit=discrepancy_caused_by_exchange_rate_difference,
-									credit=0.0,
-									remarks=remarks,
-									against_type="Supplier",
-									against_account=self.supplier,
-									debit_in_account_currency=-1 * discrepancy_caused_by_exchange_rate_difference,
-									account_currency=credit_currency,
-									item=d,
-								)
-
-					# Amount added through landed-cos-voucher
-					if d.landed_cost_voucher_amount and landed_cost_entries:
-						if (d.item_code, d.name) in landed_cost_entries:
-							for account, amount in landed_cost_entries[(d.item_code, d.name)].items():
-								account_currency = get_account_currency(account)
-								credit_amount = (
-									flt(amount["base_amount"])
-									if (amount["base_amount"] or account_currency != self.company_currency)
-									else flt(amount["amount"])
-								)
-
-								self.add_gl_entry(
-									gl_entries=gl_entries,
-									account=account,
-									cost_center=d.cost_center,
-									debit=0.0,
-									credit=credit_amount,
-									remarks=remarks,
-									against_account=warehouse_account_name,
-									credit_in_account_currency=flt(amount["amount"]),
-									account_currency=account_currency,
-									project=d.project,
-									item=d,
-								)
-
-					if d.rate_difference_with_purchase_invoice and stock_rbnb:
-						account_currency = get_account_currency(stock_rbnb)
-						self.add_gl_entry(
-							gl_entries=gl_entries,
-							account=stock_rbnb,
-							cost_center=d.cost_center,
-							debit=0.0,
-							credit=flt(d.rate_difference_with_purchase_invoice),
-							remarks=_("Adjustment based on Purchase Invoice rate"),
-							against_account=warehouse_account_name,
-							account_currency=account_currency,
-							project=d.project,
-							item=d,
-						)
-
-					# sub-contracting warehouse
-					if flt(d.rm_supp_cost) and warehouse_account.get(self.supplier_warehouse):
-						self.add_gl_entry(
-							gl_entries=gl_entries,
-							account=supplier_warehouse_account,
-							cost_center=d.cost_center,
-							debit=0.0,
-							credit=flt(d.rm_supp_cost),
-							remarks=remarks,
-							against_account=warehouse_account_name,
-							account_currency=supplier_warehouse_account_currency,
-							item=d,
-						)
-
-					# divisional loss adjustment
-					valuation_amount_as_per_doc = (
-						flt(outgoing_amount, d.precision("base_net_amount"))
-						+ flt(d.landed_cost_voucher_amount)
-						+ flt(d.rm_supp_cost)
-						+ flt(d.item_tax_amount)
-						+ flt(d.rate_difference_with_purchase_invoice)
-					)
-
-					divisional_loss = flt(
-						valuation_amount_as_per_doc - flt(stock_value_diff), d.precision("base_net_amount")
-					)
-
-					if divisional_loss:
-						if self.is_return or flt(d.item_tax_amount):
-							loss_account = expenses_included_in_valuation
-						else:
-							loss_account = (
-								self.get_company_default("default_expense_account", ignore_validation=True) or stock_rbnb
-							)
-
-						cost_center = d.cost_center or frappe.get_cached_value(
-							"Company", self.company, "cost_center"
-						)
-
-						self.add_gl_entry(
-							gl_entries=gl_entries,
-							account=loss_account,
-							cost_center=cost_center,
-							debit=divisional_loss,
-							credit=0.0,
-							remarks=remarks,
-							against_account=warehouse_account_name,
-							account_currency=credit_currency,
-							project=d.project,
-							item=d,
-						)
-
-				elif (
-					d.warehouse not in warehouse_with_no_account
-					or d.rejected_warehouse not in warehouse_with_no_account
-				):
-					warehouse_with_no_account.append(d.warehouse)
-			elif (
-				d.item_code not in stock_items
-				and not d.is_fixed_asset
-				and flt(d.qty)
-				and provisional_accounting_for_non_stock_items
-				and d.get("provisional_expense_account")
+				if (flt(d.valuation_rate) or self.is_return or d.is_fixed_asset) and flt(d.qty):
+					make_item_asset_inward_gl_entry(d, stock_value_diff, stock_asset_account_name)
+					outgoing_amount = make_stock_received_but_not_billed_entry(d)
+					make_landed_cost_gl_entries(d)
+					make_rate_difference_entry(d)
+					make_sub_contracting_gl_entries(d)
+					make_divisional_loss_gl_entry(d, outgoing_amount)
+			elif (d.warehouse and d.warehouse not in warehouse_with_no_account) or (
+				d.rejected_warehouse and d.rejected_warehouse not in warehouse_with_no_account
 			):
-				self.add_provisional_gl_entry(
-					d, gl_entries, self.posting_date, d.get("provisional_expense_account")
-				)
+				warehouse_with_no_account.append(d.warehouse or d.rejected_warehouse)
+
+			if d.is_fixed_asset:
+				self.update_assets(d, d.valuation_rate)
 
 		if warehouse_with_no_account:
 			frappe.msgprint(
@@ -589,8 +619,8 @@
 		self, item, gl_entries, posting_date, provisional_account, reverse=0
 	):
 		credit_currency = get_account_currency(provisional_account)
-		debit_currency = get_account_currency(item.expense_account)
 		expense_account = item.expense_account
+		debit_currency = get_account_currency(item.expense_account)
 		remarks = self.get("remarks") or _("Accounting Entry for Service")
 		multiplication_factor = 1
 
@@ -631,11 +661,8 @@
 		)
 
 	def make_tax_gl_entries(self, gl_entries):
-
-		if erpnext.is_perpetual_inventory_enabled(self.company):
-			expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
-
 		negative_expense_to_be_booked = sum([flt(d.item_tax_amount) for d in self.get("items")])
+		is_asset_pr = any(d.is_fixed_asset for d in self.get("items"))
 		# Cost center-wise amount breakup for other charges included for valuation
 		valuation_tax = {}
 		for tax in self.get("taxes"):
@@ -655,26 +682,26 @@
 
 		if negative_expense_to_be_booked and valuation_tax:
 			# Backward compatibility:
-			# If expenses_included_in_valuation account has been credited in against PI
 			# and charges added via Landed Cost Voucher,
 			# post valuation related charges on "Stock Received But Not Billed"
-			# introduced in 2014 for backward compatibility of expenses already booked in expenses_included_in_valuation account
-
-			negative_expense_booked_in_pi = frappe.db.sql(
-				"""select name from `tabPurchase Invoice Item` pi
-				where docstatus = 1 and purchase_receipt=%s
-				and exists(select name from `tabGL Entry` where voucher_type='Purchase Invoice'
-					and voucher_no=pi.parent and account=%s)""",
-				(self.name, expenses_included_in_valuation),
-			)
-
-			against_accounts = [d.account for d in gl_entries if flt(d.debit) > 0]
+			against_account = ", ".join([d.account for d in gl_entries if flt(d.debit) > 0])
 			total_valuation_amount = sum(valuation_tax.values())
 			amount_including_divisional_loss = negative_expense_to_be_booked
-			stock_rbnb = self.get_company_default("stock_received_but_not_billed")
+			stock_rbnb = (
+				self.get("asset_received_but_not_billed")
+				if is_asset_pr
+				else self.get_company_default("stock_received_but_not_billed")
+			)
 			i = 1
 			for tax in self.get("taxes"):
 				if valuation_tax.get(tax.name):
+					negative_expense_booked_in_pi = frappe.db.sql(
+						"""select name from `tabPurchase Invoice Item` pi
+						where docstatus = 1 and purchase_receipt=%s
+						and exists(select name from `tabGL Entry` where voucher_type='Purchase Invoice'
+							and voucher_no=pi.parent and account=%s)""",
+						(self.name, tax.account_head),
+					)
 
 					if negative_expense_booked_in_pi:
 						account = stock_rbnb
@@ -703,103 +730,6 @@
 
 					i += 1
 
-	def get_asset_gl_entry(self, gl_entries):
-		for item in self.get("items"):
-			if item.is_fixed_asset:
-				if is_cwip_accounting_enabled(item.asset_category):
-					self.add_asset_gl_entries(item, gl_entries)
-				if flt(item.landed_cost_voucher_amount):
-					self.add_lcv_gl_entries(item, gl_entries)
-					# update assets gross amount by its valuation rate
-					# valuation rate is total of net rate, raw mat supp cost, tax amount, lcv amount per item
-					self.update_assets(item, item.valuation_rate)
-		return gl_entries
-
-	def add_asset_gl_entries(self, item, gl_entries):
-		arbnb_account = self.get_company_default("asset_received_but_not_billed")
-		# This returns category's cwip account if not then fallback to company's default cwip account
-		cwip_account = get_asset_account(
-			"capital_work_in_progress_account", asset_category=item.asset_category, company=self.company
-		)
-
-		asset_amount = flt(item.net_amount) + flt(item.item_tax_amount / self.conversion_rate)
-		base_asset_amount = flt(item.base_net_amount + item.item_tax_amount)
-		remarks = self.get("remarks") or _("Accounting Entry for Asset")
-
-		cwip_account_currency = get_account_currency(cwip_account)
-		# debit cwip account
-		debit_in_account_currency = (
-			base_asset_amount if cwip_account_currency == self.company_currency else asset_amount
-		)
-
-		self.add_gl_entry(
-			gl_entries=gl_entries,
-			account=cwip_account,
-			cost_center=item.cost_center,
-			debit=base_asset_amount,
-			credit=0.0,
-			remarks=remarks,
-			against_account=arbnb_account,
-			debit_in_account_currency=debit_in_account_currency,
-			item=item,
-		)
-
-		asset_rbnb_currency = get_account_currency(arbnb_account)
-		# credit arbnb account
-		credit_in_account_currency = (
-			base_asset_amount if asset_rbnb_currency == self.company_currency else asset_amount
-		)
-
-		self.add_gl_entry(
-			gl_entries=gl_entries,
-			account=arbnb_account,
-			cost_center=item.cost_center,
-			debit=0.0,
-			credit=base_asset_amount,
-			remarks=remarks,
-			against_account=cwip_account,
-			credit_in_account_currency=credit_in_account_currency,
-			item=item,
-		)
-
-	def add_lcv_gl_entries(self, item, gl_entries):
-		expenses_included_in_asset_valuation = self.get_company_default(
-			"expenses_included_in_asset_valuation"
-		)
-		if not is_cwip_accounting_enabled(item.asset_category):
-			asset_account = get_asset_category_account(
-				asset_category=item.asset_category, fieldname="fixed_asset_account", company=self.company
-			)
-		else:
-			# This returns company's default cwip account
-			asset_account = get_asset_account("capital_work_in_progress_account", company=self.company)
-
-		remarks = self.get("remarks") or _("Accounting Entry for Stock")
-
-		self.add_gl_entry(
-			gl_entries=gl_entries,
-			account=expenses_included_in_asset_valuation,
-			cost_center=item.cost_center,
-			debit=0.0,
-			credit=flt(item.landed_cost_voucher_amount),
-			remarks=remarks,
-			against_account=asset_account,
-			project=item.project,
-			item=item,
-		)
-
-		self.add_gl_entry(
-			gl_entries=gl_entries,
-			account=asset_account,
-			cost_center=item.cost_center,
-			debit=flt(item.landed_cost_voucher_amount),
-			credit=0.0,
-			remarks=remarks,
-			against_account=expenses_included_in_asset_valuation,
-			project=item.project,
-			item=item,
-		)
-
 	def update_assets(self, item, valuation_rate):
 		assets = frappe.db.get_all(
 			"Asset", filters={"purchase_receipt": self.name, "item_code": item.item_code}
@@ -824,16 +754,59 @@
 				po_details.append(d.purchase_order_item)
 
 		if po_details:
-			updated_pr += update_billed_amount_based_on_po(po_details, update_modified)
+			updated_pr += update_billed_amount_based_on_po(po_details, update_modified, self)
 
 		for pr in set(updated_pr):
 			pr_doc = self if (pr == self.name) else frappe.get_doc("Purchase Receipt", pr)
 			update_billing_percentage(pr_doc, update_modified=update_modified)
 
-		self.load_from_db()
+	def reserve_stock_for_sales_order(self):
+		if self.is_return or not cint(
+			frappe.db.get_single_value("Stock Settings", "auto_reserve_stock_for_sales_order_on_purchase")
+		):
+			return
+
+		self.reload()  # reload to get the Serial and Batch Bundle Details
+
+		so_items_details_map = {}
+		for item in self.items:
+			if item.sales_order and item.sales_order_item:
+				item_details = {
+					"name": item.sales_order_item,
+					"item_code": item.item_code,
+					"warehouse": item.warehouse,
+					"qty_to_reserve": item.stock_qty,
+					"from_voucher_no": item.parent,
+					"from_voucher_detail_no": item.name,
+					"serial_and_batch_bundle": item.serial_and_batch_bundle,
+				}
+				so_items_details_map.setdefault(item.sales_order, []).append(item_details)
+
+		if so_items_details_map:
+			for so, items_details in so_items_details_map.items():
+				so_doc = frappe.get_doc("Sales Order", so)
+				so_doc.create_stock_reservation_entries(
+					items_details=items_details,
+					from_voucher_type="Purchase Receipt",
+					notify=True,
+				)
 
 
-def update_billed_amount_based_on_po(po_details, update_modified=True):
+def get_stock_value_difference(voucher_no, voucher_detail_no, warehouse):
+	return frappe.db.get_value(
+		"Stock Ledger Entry",
+		{
+			"voucher_type": "Purchase Receipt",
+			"voucher_no": voucher_no,
+			"voucher_detail_no": voucher_detail_no,
+			"warehouse": warehouse,
+			"is_cancelled": 0,
+		},
+		"stock_value_difference",
+	)
+
+
+def update_billed_amount_based_on_po(po_details, update_modified=True, pr_doc=None):
 	po_billed_amt_details = get_billed_amount_against_po(po_details)
 
 	# Get all Purchase Receipt Item rows against the Purchase Order Items
@@ -862,13 +835,19 @@
 		po_billed_amt_details[pr_item.purchase_order_item] = billed_against_po
 
 		if pr_item.billed_amt != billed_amt_agianst_pr:
-			frappe.db.set_value(
-				"Purchase Receipt Item",
-				pr_item.name,
-				"billed_amt",
-				billed_amt_agianst_pr,
-				update_modified=update_modified,
-			)
+			# update existing doc if possible
+			if pr_doc and pr_item.parent == pr_doc.name:
+				pr_item = next((item for item in pr_doc.items if item.name == pr_item.name), None)
+				pr_item.db_set("billed_amt", billed_amt_agianst_pr, update_modified=update_modified)
+
+			else:
+				frappe.db.set_value(
+					"Purchase Receipt Item",
+					pr_item.name,
+					"billed_amt",
+					billed_amt_agianst_pr,
+					update_modified=update_modified,
+				)
 
 			updated_pr.append(pr_item.parent)
 
@@ -944,9 +923,6 @@
 
 
 def update_billing_percentage(pr_doc, update_modified=True, adjust_incoming_rate=False):
-	# Reload as billed amount was set in db directly
-	pr_doc.load_from_db()
-
 	# Update Billing % based on pending accepted qty
 	total_amount, total_billed_amount = 0, 0
 	item_wise_returned_qty = get_item_wise_returned_qty(pr_doc)
@@ -959,6 +935,10 @@
 
 		total_amount += total_billable_amount
 		total_billed_amount += flt(item.billed_amt)
+
+		if pr_doc.get("is_return") and not total_amount and total_billed_amount:
+			total_amount = total_billed_amount
+
 		if adjust_incoming_rate:
 			adjusted_amt = 0.0
 			if item.billed_amt and item.amount:
@@ -968,7 +948,6 @@
 
 	percent_billed = round(100 * (total_billed_amount / (total_amount or 1)), 6)
 	pr_doc.db_set("per_billed", percent_billed)
-	pr_doc.load_from_db()
 
 	if update_modified:
 		pr_doc.set_status(update=True)
@@ -1090,6 +1069,7 @@
 					"is_fixed_asset": "is_fixed_asset",
 					"asset_location": "asset_location",
 					"asset_category": "asset_category",
+					"wip_composite_asset": "wip_composite_asset",
 				},
 				"postprocess": update_item,
 				"filter": lambda d: get_pending_qty(d)[0] <= 0
@@ -1254,3 +1234,8 @@
 
 def on_doctype_update():
 	frappe.db.add_index("Purchase Receipt", ["supplier", "is_return", "return_against"])
+
+
+@erpnext.allow_regional
+def update_regional_gl_entries(gl_list, doc):
+	return
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py
index b3ae7b5..71489fb 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py
@@ -10,6 +10,7 @@
 			"Landed Cost Voucher": "receipt_document",
 			"Auto Repeat": "reference_document",
 			"Purchase Receipt": "return_against",
+			"Stock Reservation Entry": "from_voucher_no",
 		},
 		"internal_links": {
 			"Material Request": ["items", "material_request"],
@@ -18,7 +19,10 @@
 			"Quality Inspection": ["items", "quality_inspection"],
 		},
 		"transactions": [
-			{"label": _("Related"), "items": ["Purchase Invoice", "Landed Cost Voucher", "Asset"]},
+			{
+				"label": _("Related"),
+				"items": ["Purchase Invoice", "Landed Cost Voucher", "Asset", "Stock Reservation Entry"],
+			},
 			{
 				"label": _("Reference"),
 				"items": ["Material Request", "Purchase Order", "Quality Inspection", "Project"],
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index b7712ee..146cbff 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -958,17 +958,33 @@
 		pr1.cancel()
 
 	def test_stock_transfer_from_purchase_receipt(self):
+		from erpnext.stock.doctype.delivery_note.delivery_note import make_inter_company_purchase_receipt
+		from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
+
+		prepare_data_for_internal_transfer()
+
+		customer = "_Test Internal Customer 2"
+		company = "_Test Company with perpetual inventory"
+
 		pr1 = make_purchase_receipt(
-			warehouse="Work In Progress - TCP1", company="_Test Company with perpetual inventory"
+			warehouse="Stores - TCP1", company="_Test Company with perpetual inventory"
 		)
 
-		pr = make_purchase_receipt(
-			company="_Test Company with perpetual inventory", warehouse="Stores - TCP1", do_not_save=1
+		dn1 = create_delivery_note(
+			item_code=pr1.items[0].item_code,
+			company=company,
+			customer=customer,
+			cost_center="Main - TCP1",
+			expense_account="Cost of Goods Sold - TCP1",
+			qty=5,
+			rate=500,
+			warehouse="Stores - TCP1",
+			target_warehouse="Work In Progress - TCP1",
 		)
 
-		pr.supplier_warehouse = ""
+		pr = make_inter_company_purchase_receipt(dn1.name)
 		pr.items[0].from_warehouse = "Work In Progress - TCP1"
-
+		pr.items[0].warehouse = "Stores - TCP1"
 		pr.submit()
 
 		gl_entries = get_gl_entries("Purchase Receipt", pr.name)
@@ -982,9 +998,13 @@
 			self.assertEqual(expected_sle[sle.warehouse], sle.actual_qty)
 
 		pr.cancel()
-		pr1.cancel()
 
 	def test_stock_transfer_from_purchase_receipt_with_valuation(self):
+		from erpnext.stock.doctype.delivery_note.delivery_note import make_inter_company_purchase_receipt
+		from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
+
+		prepare_data_for_internal_transfer()
+
 		create_warehouse(
 			"_Test Warehouse for Valuation",
 			company="_Test Company with perpetual inventory",
@@ -992,16 +1012,28 @@
 		)
 
 		pr1 = make_purchase_receipt(
-			warehouse="_Test Warehouse for Valuation - TCP1",
+			warehouse="Stores - TCP1",
 			company="_Test Company with perpetual inventory",
 		)
 
-		pr = make_purchase_receipt(
-			company="_Test Company with perpetual inventory", warehouse="Stores - TCP1", do_not_save=1
+		customer = "_Test Internal Customer 2"
+		company = "_Test Company with perpetual inventory"
+
+		dn1 = create_delivery_note(
+			item_code=pr1.items[0].item_code,
+			company=company,
+			customer=customer,
+			cost_center="Main - TCP1",
+			expense_account="Cost of Goods Sold - TCP1",
+			qty=5,
+			rate=50,
+			warehouse="Stores - TCP1",
+			target_warehouse="_Test Warehouse for Valuation - TCP1",
 		)
 
+		pr = make_inter_company_purchase_receipt(dn1.name)
 		pr.items[0].from_warehouse = "_Test Warehouse for Valuation - TCP1"
-		pr.supplier_warehouse = ""
+		pr.items[0].warehouse = "Stores - TCP1"
 
 		pr.append(
 			"taxes",
@@ -1037,7 +1069,6 @@
 			self.assertEqual(gle.credit, expected_gle[i][2])
 
 		pr.cancel()
-		pr1.cancel()
 
 	def test_po_to_pi_and_po_to_pr_worflow_full(self):
 		"""Test following behaviour:
@@ -2060,6 +2091,103 @@
 		company.enable_provisional_accounting_for_non_stock_items = 0
 		company.save()
 
+	def test_purchase_return_status_with_debit_note(self):
+		pr = make_purchase_receipt(rejected_qty=10, received_qty=10, rate=100, do_not_save=1)
+		pr.items[0].qty = 0
+		pr.items[0].stock_qty = 0
+		pr.submit()
+
+		return_pr = make_purchase_receipt(
+			is_return=1,
+			return_against=pr.name,
+			qty=0,
+			rejected_qty=10 * -1,
+			received_qty=10 * -1,
+			do_not_save=1,
+		)
+		return_pr.items[0].qty = 0.0
+		return_pr.items[0].stock_qty = 0.0
+		return_pr.submit()
+
+		self.assertEqual(return_pr.status, "To Bill")
+
+		pi = make_purchase_invoice(return_pr.name)
+		pi.submit()
+
+		return_pr.reload()
+		self.assertEqual(return_pr.status, "Completed")
+
+	def test_purchase_return_with_zero_rate(self):
+		company = "_Test Company with perpetual inventory"
+
+		# Step - 1: Create Item
+		item, warehouse = (
+			make_item(properties={"is_stock_item": 1, "valuation_method": "Moving Average"}).name,
+			"Stores - TCP1",
+		)
+
+		# Step - 2: Create Stock Entry (Material Receipt)
+		from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
+
+		se = make_stock_entry(
+			purpose="Material Receipt",
+			item_code=item,
+			qty=100,
+			basic_rate=100,
+			to_warehouse=warehouse,
+			company=company,
+		)
+
+		# Step - 3: Create Purchase Receipt
+		pr = make_purchase_receipt(
+			item_code=item,
+			qty=5,
+			rate=0,
+			warehouse=warehouse,
+			company=company,
+		)
+
+		# Step - 4: Create Purchase Return
+		from erpnext.controllers.sales_and_purchase_return import make_return_doc
+
+		pr_return = make_return_doc("Purchase Receipt", pr.name)
+		pr_return.save()
+		pr_return.submit()
+
+		sl_entries = get_sl_entries(pr_return.doctype, pr_return.name)
+		gl_entries = get_gl_entries(pr_return.doctype, pr_return.name)
+
+		# Test - 1: SLE Stock Value Difference should be equal to Qty * Average Rate
+		average_rate = (
+			(se.items[0].qty * se.items[0].basic_rate) + (pr.items[0].qty * pr.items[0].rate)
+		) / (se.items[0].qty + pr.items[0].qty)
+		expected_stock_value_difference = pr_return.items[0].qty * average_rate
+		self.assertEqual(
+			flt(sl_entries[0].stock_value_difference, 2), flt(expected_stock_value_difference, 2)
+		)
+
+		# Test - 2: GL Entries should be created for Stock Value Difference
+		self.assertEqual(len(gl_entries), 2)
+
+		# Test - 3: SLE Stock Value Difference should be equal to Debit or Credit of GL Entries.
+		for entry in gl_entries:
+			self.assertEqual(abs(entry.debit + entry.credit), abs(sl_entries[0].stock_value_difference))
+
+	def non_internal_transfer_purchase_receipt(self):
+		from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
+
+		pr_doc = make_purchase_receipt(do_not_submit=True)
+		warehouse = create_warehouse("Internal Transfer Warehouse", pr_doc.company)
+		pr_doc.items[0].db_set("target_warehouse", "warehouse")
+
+		pr_doc.reload()
+
+		self.assertEqual(pr_doc.items[0].from_warehouse, warehouse.name)
+
+		pr_doc.save()
+		pr_doc.reload()
+		self.assertFalse(pr_doc.items[0].from_warehouse)
+
 
 def prepare_data_for_internal_transfer():
 	from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier
diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
index 5eb3656..718f007 100644
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
@@ -117,6 +117,7 @@
   "accounting_details_section",
   "expense_account",
   "item_tax_rate",
+  "wip_composite_asset",
   "column_break_102",
   "provisional_expense_account",
   "accounting_dimensions_section",
@@ -124,7 +125,9 @@
   "dimension_col_break",
   "cost_center",
   "section_break_80",
-  "page_break"
+  "page_break",
+  "sales_order",
+  "sales_order_item"
  ],
  "fields": [
   {
@@ -186,7 +189,6 @@
    "oldfieldname": "description",
    "oldfieldtype": "Text",
    "print_width": "300px",
-   "reqd": 1,
    "width": "300px"
   },
   {
@@ -898,7 +900,8 @@
    "label": "Delivery Note Item",
    "no_copy": 1,
    "print_hide": 1,
-   "read_only": 1
+   "read_only": 1,
+   "search_index": 1
   },
   {
    "collapsible": 1,
@@ -1056,12 +1059,38 @@
    "fieldname": "add_serial_batch_bundle",
    "fieldtype": "Button",
    "label": "Add Serial / Batch No"
+  },
+  {
+   "fieldname": "wip_composite_asset",
+   "fieldtype": "Link",
+   "label": "WIP Composite Asset",
+   "options": "Asset"
+  },
+  {
+   "fieldname": "sales_order",
+   "fieldtype": "Link",
+   "label": "Sales Order",
+   "no_copy": 1,
+   "options": "Sales Order",
+   "print_hide": 1,
+   "read_only": 1,
+   "search_index": 1
+  },
+  {
+   "fieldname": "sales_order_item",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Sales Order Item",
+   "no_copy": 1,
+   "print_hide": 1,
+   "read_only": 1,
+   "search_index": 1
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-08-11 16:16:16.504549",
+ "modified": "2023-10-30 17:32:24.560337",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt Item",
diff --git a/erpnext/stock/doctype/quality_inspection_template/test_records.json b/erpnext/stock/doctype/quality_inspection_template/test_records.json
index 980f49a..2da99f6 100644
--- a/erpnext/stock/doctype/quality_inspection_template/test_records.json
+++ b/erpnext/stock/doctype/quality_inspection_template/test_records.json
@@ -1,5 +1,9 @@
 [
  {
+     "doctype": "Quality Inspection Parameter",
+     "parameter" : "_Test Param"
+ },
+ {
      "quality_inspection_template_name" : "_Test Quality Inspection Template",
      "doctype": "Quality Inspection Template",
      "item_quality_inspection_parameter" : [
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 1853f45..5b76e44 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
@@ -5,7 +5,7 @@
 from unittest.mock import MagicMock, call
 
 import frappe
-from frappe.tests.utils import FrappeTestCase
+from frappe.tests.utils import FrappeTestCase, change_settings
 from frappe.utils import add_days, add_to_date, now, nowdate, today
 
 from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
@@ -137,8 +137,6 @@
 			item_code="_Test Item",
 			warehouse="_Test Warehouse - _TC",
 			based_on="Item and Warehouse",
-			voucher_type="Sales Invoice",
-			voucher_no="SI-1",
 			posting_date="2021-01-02",
 			posting_time="00:01:00",
 		)
@@ -148,8 +146,6 @@
 		riv1.flags.dont_run_in_test = True
 		riv1.submit()
 		_assert_status(riv1, "Queued")
-		self.assertEqual(riv1.voucher_type, "Sales Invoice")  # traceability
-		self.assertEqual(riv1.voucher_no, "SI-1")
 
 		# newer than existing duplicate - riv1
 		riv2 = frappe.get_doc(riv_args.update({"posting_date": "2021-01-03"}))
@@ -200,6 +196,7 @@
 
 		riv.set_status("Skipped")
 
+	@change_settings("Stock Reposting Settings", {"item_based_reposting": 0})
 	def test_prevention_of_cancelled_transaction_riv(self):
 		frappe.flags.dont_execute_stock_reposts = True
 
@@ -377,6 +374,7 @@
 		accounts_settings.acc_frozen_upto = ""
 		accounts_settings.save()
 
+	@change_settings("Stock Reposting Settings", {"item_based_reposting": 0})
 	def test_create_repost_entry_for_cancelled_document(self):
 		pr = make_purchase_receipt(
 			company="_Test Company with perpetual inventory",
diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
index 96e4a55..f2bbf2b 100644
--- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
+++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
@@ -121,7 +121,7 @@
 	def throw_error_message(self, message, exception=frappe.ValidationError):
 		frappe.throw(_(message), exception, title=_("Error"))
 
-	def set_incoming_rate(self, row=None, save=False):
+	def set_incoming_rate(self, row=None, save=False, allow_negative_stock=False):
 		if self.type_of_transaction not in ["Inward", "Outward"] or self.voucher_type in [
 			"Installation Note",
 			"Job Card",
@@ -131,7 +131,9 @@
 			return
 
 		if self.type_of_transaction == "Outward":
-			self.set_incoming_rate_for_outward_transaction(row, save)
+			self.set_incoming_rate_for_outward_transaction(
+				row, save, allow_negative_stock=allow_negative_stock
+			)
 		else:
 			self.set_incoming_rate_for_inward_transaction(row, save)
 
@@ -152,7 +154,9 @@
 	def get_serial_nos(self):
 		return [d.serial_no for d in self.entries if d.serial_no]
 
-	def set_incoming_rate_for_outward_transaction(self, row=None, save=False):
+	def set_incoming_rate_for_outward_transaction(
+		self, row=None, save=False, allow_negative_stock=False
+	):
 		sle = self.get_sle_for_outward_transaction()
 
 		if self.has_serial_no:
@@ -181,7 +185,8 @@
 				if self.docstatus == 1:
 					available_qty += flt(d.qty)
 
-				self.validate_negative_batch(d.batch_no, available_qty)
+				if not allow_negative_stock:
+					self.validate_negative_batch(d.batch_no, available_qty)
 
 			d.stock_value_difference = flt(d.qty) * flt(d.incoming_rate)
 
@@ -658,7 +663,7 @@
 		if not available_batches:
 			return
 
-		available_batches = get_availabel_batches_qty(available_batches)
+		available_batches = get_available_batches_qty(available_batches)
 		for batch_no in batches:
 			if batch_no not in available_batches or available_batches[batch_no] < 0:
 				self.throw_error_message(
@@ -1074,7 +1079,7 @@
 		return get_auto_batch_nos(kwargs)
 
 
-def get_availabel_batches_qty(available_batches):
+def get_available_batches_qty(available_batches):
 	available_batches_qty = defaultdict(float)
 	for batch in available_batches:
 		available_batches_qty[batch.batch_no] += batch.qty
@@ -1301,6 +1306,7 @@
 		"POS Invoice",
 		fields=[
 			"`tabPOS Invoice Item`.batch_no",
+			"`tabPOS Invoice Item`.qty",
 			"`tabPOS Invoice`.is_return",
 			"`tabPOS Invoice Item`.warehouse",
 			"`tabPOS Invoice Item`.name as child_docname",
@@ -1321,9 +1327,6 @@
 		if pos_invoice.serial_and_batch_bundle
 	]
 
-	if not ids:
-		return {}
-
 	if ids:
 		for d in get_serial_batch_ledgers(kwargs.item_code, docstatus=1, name=ids):
 			key = (d.batch_no, d.warehouse)
@@ -1337,6 +1340,7 @@
 			else:
 				pos_batches[key].qty += d.qty
 
+	# POS invoices having batch without bundle (to handle old POS invoices)
 	for row in pos_invoices:
 		if not row.batch_no:
 			continue
@@ -1346,11 +1350,11 @@
 
 		key = (row.batch_no, row.warehouse)
 		if key in pos_batches:
-			pos_batches[key] -= row.qty * -1 if row.is_return else row.qty
+			pos_batches[key]["qty"] -= row.qty * -1 if row.is_return else row.qty
 		else:
 			pos_batches[key] = frappe._dict(
 				{
-					"qty": (row.qty * -1 if row.is_return else row.qty),
+					"qty": (row.qty * -1 if not row.is_return else row.qty),
 					"warehouse": row.warehouse,
 				}
 			)
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 2124168..1ed2f98 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -438,31 +438,37 @@
 								item_code.append(item.item_code)
 
 	def validate_fg_completed_qty(self):
-		item_wise_qty = {}
-		if self.purpose == "Manufacture" and self.work_order:
-			for d in self.items:
-				if d.is_finished_item:
-					if self.process_loss_qty:
-						d.qty = self.fg_completed_qty - self.process_loss_qty
+		if self.purpose != "Manufacture":
+			return
 
-					item_wise_qty.setdefault(d.item_code, []).append(d.qty)
+		fg_qty = defaultdict(float)
+		for d in self.items:
+			if d.is_finished_item:
+				fg_qty[d.item_code] += flt(d.qty)
+
+		if not fg_qty:
+			return
 
 		precision = frappe.get_precision("Stock Entry Detail", "qty")
-		for item_code, qty_list in item_wise_qty.items():
-			total = flt(sum(qty_list), precision)
+		fg_item = list(fg_qty.keys())[0]
+		fg_item_qty = flt(fg_qty[fg_item], precision)
+		fg_completed_qty = flt(self.fg_completed_qty, precision)
 
-			if (self.fg_completed_qty - total) > 0 and not self.process_loss_qty:
-				self.process_loss_qty = flt(self.fg_completed_qty - total, precision)
-				self.process_loss_percentage = flt(self.process_loss_qty * 100 / self.fg_completed_qty)
+		for d in self.items:
+			if not fg_qty.get(d.item_code):
+				continue
 
-			if self.process_loss_qty:
-				total += flt(self.process_loss_qty, precision)
+			if (fg_completed_qty - fg_item_qty) > 0:
+				self.process_loss_qty = fg_completed_qty - fg_item_qty
 
-			if self.fg_completed_qty != total:
+			if not self.process_loss_qty:
+				continue
+
+			if fg_completed_qty != (flt(fg_item_qty) + flt(self.process_loss_qty, precision)):
 				frappe.throw(
-					_("The finished product {0} quantity {1} and For Quantity {2} cannot be different").format(
-						frappe.bold(item_code), frappe.bold(total), frappe.bold(self.fg_completed_qty)
-					)
+					_(
+						"Since there is a process loss of {0} units for the finished good {1}, you should reduce the quantity by {0} units for the finished good {1} in the Items Table."
+					).format(frappe.bold(self.process_loss_qty), frappe.bold(d.item_code))
 				)
 
 	def validate_difference_account(self):
@@ -1014,14 +1020,34 @@
 						& (se.docstatus == 1)
 						& (se_detail.item_code == se_item.item_code)
 						& (
-							(se.purchase_order == self.purchase_order)
+							((se.purchase_order == self.purchase_order) & (se_detail.po_detail == se_item.po_detail))
 							if self.subcontract_data.order_doctype == "Purchase Order"
-							else (se.subcontracting_order == self.subcontracting_order)
+							else (
+								(se.subcontracting_order == self.subcontracting_order)
+								& (se_detail.sco_rm_detail == se_item.sco_rm_detail)
+							)
 						)
 					)
-				).run()[0][0]
+				).run()[0][0] or 0
 
-				if flt(total_supplied, precision) > flt(total_allowed, precision):
+				total_returned = 0
+				if self.subcontract_data.order_doctype == "Subcontracting Order":
+					total_returned = (
+						frappe.qb.from_(se)
+						.inner_join(se_detail)
+						.on(se.name == se_detail.parent)
+						.select(Sum(se_detail.transfer_qty))
+						.where(
+							(se.purpose == "Material Transfer")
+							& (se.docstatus == 1)
+							& (se.is_return == 1)
+							& (se_detail.item_code == se_item.item_code)
+							& (se_detail.sco_rm_detail == se_item.sco_rm_detail)
+							& (se.subcontracting_order == self.subcontracting_order)
+						)
+					).run()[0][0] or 0
+
+				if flt(total_supplied - total_returned, precision) > flt(total_allowed, precision):
 					frappe.throw(
 						_("Row {0}# Item {1} cannot be transferred more than {2} against {3} {4}").format(
 							se_item.idx,
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index cc8a108..b640983 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -449,9 +449,7 @@
 		repack.posting_date = nowdate()
 		repack.posting_time = nowtime()
 
-		expenses_included_in_valuation = frappe.get_value(
-			"Company", company, "expenses_included_in_valuation"
-		)
+		default_expense_account = frappe.get_value("Company", company, "default_expense_account")
 
 		items = get_multiple_items()
 		repack.items = []
@@ -462,12 +460,12 @@
 			"additional_costs",
 			[
 				{
-					"expense_account": expenses_included_in_valuation,
+					"expense_account": default_expense_account,
 					"description": "Actual Operating Cost",
 					"amount": 1000,
 				},
 				{
-					"expense_account": expenses_included_in_valuation,
+					"expense_account": default_expense_account,
 					"description": "Additional Operating Cost",
 					"amount": 200,
 				},
@@ -506,9 +504,7 @@
 		self.check_gl_entries(
 			"Stock Entry",
 			repack.name,
-			sorted(
-				[[stock_in_hand_account, 1200, 0.0], ["Expenses Included In Valuation - TCP1", 0.0, 1200.0]]
-			),
+			sorted([[stock_in_hand_account, 1200, 0.0], ["Cost of Goods Sold - TCP1", 0.0, 1200.0]]),
 		)
 
 	def check_stock_ledger_entries(self, voucher_type, voucher_no, expected_sle):
@@ -1471,6 +1467,7 @@
 		self.assertEqual(se.items[0].item_name, item.item_name)
 		self.assertEqual(se.items[0].stock_uom, item.stock_uom)
 
+	@change_settings("Stock Reposting Settings", {"item_based_reposting": 0})
 	def test_reposting_for_depedent_warehouse(self):
 		from erpnext.stock.doctype.repost_item_valuation.repost_item_valuation import repost_sl_entries
 		from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
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 3ca4bad..c1b2051 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -5,14 +5,16 @@
 from datetime import date
 
 import frappe
-from frappe import _
+from frappe import _, bold
 from frappe.core.doctype.role.role import get_users
 from frappe.model.document import Document
-from frappe.utils import add_days, cint, formatdate, get_datetime, getdate
+from frappe.utils import add_days, cint, flt, formatdate, get_datetime, getdate
 
 from erpnext.accounts.utils import get_fiscal_year
 from erpnext.controllers.item_variant import ItemTemplateCannotHaveStock
+from erpnext.stock.doctype.inventory_dimension.inventory_dimension import get_inventory_dimensions
 from erpnext.stock.serial_batch_bundle import SerialBatchBundle
+from erpnext.stock.stock_ledger import get_previous_sle
 
 
 class StockFreezeError(frappe.ValidationError):
@@ -48,6 +50,69 @@
 		self.validate_and_set_fiscal_year()
 		self.block_transactions_against_group_warehouse()
 		self.validate_with_last_transaction_posting_time()
+		self.validate_inventory_dimension_negative_stock()
+
+	def validate_inventory_dimension_negative_stock(self):
+		extra_cond = ""
+		kwargs = {}
+
+		dimensions = self._get_inventory_dimensions()
+		if not dimensions:
+			return
+
+		for dimension, values in dimensions.items():
+			kwargs[dimension] = values.get("value")
+			extra_cond += f" and {dimension} = %({dimension})s"
+
+		kwargs.update(
+			{
+				"item_code": self.item_code,
+				"warehouse": self.warehouse,
+				"posting_date": self.posting_date,
+				"posting_time": self.posting_time,
+				"company": self.company,
+			}
+		)
+
+		sle = get_previous_sle(kwargs, extra_cond=extra_cond)
+		if sle:
+			flt_precision = cint(frappe.db.get_default("float_precision")) or 2
+			diff = sle.qty_after_transaction + flt(self.actual_qty)
+			diff = flt(diff, flt_precision)
+			if diff < 0 and abs(diff) > 0.0001:
+				self.throw_validation_error(diff, dimensions)
+
+	def throw_validation_error(self, diff, dimensions):
+		dimension_msg = _(", with the inventory {0}: {1}").format(
+			"dimensions" if len(dimensions) > 1 else "dimension",
+			", ".join(f"{bold(d.doctype)} ({d.value})" for k, d in dimensions.items()),
+		)
+
+		msg = _(
+			"{0} units of {1} are required in {2}{3}, on {4} {5} for {6} to complete the transaction."
+		).format(
+			abs(diff),
+			frappe.get_desk_link("Item", self.item_code),
+			frappe.get_desk_link("Warehouse", self.warehouse),
+			dimension_msg,
+			self.posting_date,
+			self.posting_time,
+			frappe.get_desk_link(self.voucher_type, self.voucher_no),
+		)
+
+		frappe.throw(msg, title=_("Inventory Dimension Negative Stock"))
+
+	def _get_inventory_dimensions(self):
+		inv_dimensions = get_inventory_dimensions()
+		inv_dimension_dict = {}
+		for dimension in inv_dimensions:
+			if not dimension.get("validate_negative_stock") or not self.get(dimension.fieldname):
+				continue
+
+			dimension["value"] = self.get(dimension.fieldname)
+			inv_dimension_dict.setdefault(dimension.fieldname, dimension)
+
+		return inv_dimension_dict
 
 	def on_submit(self):
 		self.check_stock_frozen_date()
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
index 5452692..b3998b7 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
@@ -123,13 +123,6 @@
 				fieldname: "item_code",
 				fieldtype: "Link",
 				options: "Item",
-				"get_query": function() {
-					return {
-						"filters": {
-							"disabled": 0,
-						}
-					};
-				}
 			},
 			{
 				label: __("Ignore Empty Stock"),
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index e36d576..323ad4f 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -6,12 +6,13 @@
 import frappe
 from frappe import _, bold, msgprint
 from frappe.query_builder.functions import CombineDatetime, Sum
-from frappe.utils import cint, cstr, flt
+from frappe.utils import add_to_date, cint, cstr, flt
 
 import erpnext
 from erpnext.accounts.utils import get_company_default
 from erpnext.controllers.stock_controller import StockController
 from erpnext.stock.doctype.batch.batch import get_available_batches, get_batch_qty
+from erpnext.stock.doctype.inventory_dimension.inventory_dimension import get_inventory_dimensions
 from erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle import (
 	get_available_serial_nos,
 )
@@ -50,6 +51,7 @@
 		self.clean_serial_nos()
 		self.set_total_qty_and_amount()
 		self.validate_putaway_capacity()
+		self.validate_inventory_dimension()
 
 		if self._action == "submit":
 			self.validate_reserved_stock()
@@ -57,6 +59,17 @@
 	def on_update(self):
 		self.set_serial_and_batch_bundle(ignore_validate=True)
 
+	def validate_inventory_dimension(self):
+		dimensions = get_inventory_dimensions()
+		for dimension in dimensions:
+			for row in self.items:
+				if not row.batch_no and row.current_qty and row.get(dimension.get("fieldname")):
+					frappe.throw(
+						_(
+							"Row #{0}: You cannot use the inventory dimension '{1}' in Stock Reconciliation to modify the quantity or valuation rate. Stock reconciliation with inventory dimensions is intended solely for performing opening entries."
+						).format(row.idx, bold(dimension.get("doctype")))
+					)
+
 	def on_submit(self):
 		self.update_stock_ledger()
 		self.make_gl_entries()
@@ -75,9 +88,12 @@
 		self.repost_future_sle_and_gle()
 		self.delete_auto_created_batches()
 
-	def set_current_serial_and_batch_bundle(self):
+	def set_current_serial_and_batch_bundle(self, voucher_detail_no=None, save=False) -> None:
 		"""Set Serial and Batch Bundle for each item"""
 		for item in self.items:
+			if voucher_detail_no and voucher_detail_no != item.name:
+				continue
+
 			item_details = frappe.get_cached_value(
 				"Item", item.item_code, ["has_serial_no", "has_batch_no"], as_dict=1
 			)
@@ -135,6 +151,7 @@
 							"warehouse": item.warehouse,
 							"posting_date": self.posting_date,
 							"posting_time": self.posting_time,
+							"ignore_voucher_nos": [self.name],
 						}
 					)
 				)
@@ -150,11 +167,36 @@
 					)
 
 			if not serial_and_batch_bundle.entries:
+				if voucher_detail_no:
+					return
+
 				continue
 
-			item.current_serial_and_batch_bundle = serial_and_batch_bundle.save().name
+			serial_and_batch_bundle.save()
+			item.current_serial_and_batch_bundle = serial_and_batch_bundle.name
 			item.current_qty = abs(serial_and_batch_bundle.total_qty)
 			item.current_valuation_rate = abs(serial_and_batch_bundle.avg_rate)
+			if save:
+				sle_creation = frappe.db.get_value(
+					"Serial and Batch Bundle", item.serial_and_batch_bundle, "creation"
+				)
+				creation = add_to_date(sle_creation, seconds=-1)
+				item.db_set(
+					{
+						"current_serial_and_batch_bundle": item.current_serial_and_batch_bundle,
+						"current_qty": item.current_qty,
+						"current_valuation_rate": item.current_valuation_rate,
+						"creation": creation,
+					}
+				)
+
+				serial_and_batch_bundle.db_set(
+					{
+						"creation": creation,
+						"voucher_no": self.name,
+						"voucher_detail_no": voucher_detail_no,
+					}
+				)
 
 	def set_new_serial_and_batch_bundle(self):
 		for item in self.items:
@@ -202,8 +244,19 @@
 				self.calculate_difference_amount(item, bundle_data)
 				return True
 
+			inventory_dimensions_dict = {}
+			if not item.batch_no and not item.serial_no:
+				for dimension in get_inventory_dimensions():
+					if item.get(dimension.get("fieldname")):
+						inventory_dimensions_dict[dimension.get("fieldname")] = item.get(dimension.get("fieldname"))
+
 			item_dict = get_stock_balance_for(
-				item.item_code, item.warehouse, self.posting_date, self.posting_time, batch_no=item.batch_no
+				item.item_code,
+				item.warehouse,
+				self.posting_date,
+				self.posting_time,
+				batch_no=item.batch_no,
+				inventory_dimensions_dict=inventory_dimensions_dict,
 			)
 
 			if (item.qty is None or item.qty == item_dict.get("qty")) and (
@@ -507,7 +560,13 @@
 		if not row.batch_no:
 			data.qty_after_transaction = flt(row.qty, row.precision("qty"))
 
-		if self.docstatus == 2:
+		dimensions = get_inventory_dimensions()
+		has_dimensions = False
+		for dimension in dimensions:
+			if row.get(dimension.get("fieldname")):
+				has_dimensions = True
+
+		if self.docstatus == 2 and (not row.batch_no or not row.serial_and_batch_bundle):
 			if row.current_qty:
 				data.actual_qty = -1 * row.current_qty
 				data.qty_after_transaction = flt(row.current_qty)
@@ -523,6 +582,13 @@
 				data.valuation_rate = flt(row.valuation_rate)
 				data.stock_value_difference = -1 * flt(row.amount_difference)
 
+		elif (
+			self.docstatus == 1 and has_dimensions and (not row.batch_no or not row.serial_and_batch_bundle)
+		):
+			data.actual_qty = row.qty
+			data.qty_after_transaction = 0.0
+			data.incoming_rate = flt(row.valuation_rate)
+
 		self.update_inventory_dimensions(row, data)
 
 		return data
@@ -652,56 +718,84 @@
 		else:
 			self._cancel()
 
-	def recalculate_current_qty(self, item_code, batch_no):
+	def recalculate_current_qty(self, voucher_detail_no, sle_creation, add_new_sle=False):
 		from erpnext.stock.stock_ledger import get_valuation_rate
 
 		sl_entries = []
+
 		for row in self.items:
-			if (
-				not (row.item_code == item_code and row.batch_no == batch_no)
-				and not row.serial_and_batch_bundle
-			):
+			if voucher_detail_no != row.name:
 				continue
 
+			current_qty = 0.0
 			if row.current_serial_and_batch_bundle:
-				self.recalculate_qty_for_serial_and_batch_bundle(row)
-				continue
-
-			current_qty = get_batch_qty_for_stock_reco(
-				item_code, row.warehouse, batch_no, self.posting_date, self.posting_time, self.name
-			)
+				current_qty = self.get_qty_for_serial_and_batch_bundle(row)
+			elif row.batch_no:
+				current_qty = get_batch_qty_for_stock_reco(
+					row.item_code, row.warehouse, row.batch_no, self.posting_date, self.posting_time, self.name
+				)
 
 			precesion = row.precision("current_qty")
-			if flt(current_qty, precesion) == flt(row.current_qty, precesion):
-				continue
+			if flt(current_qty, precesion) != flt(row.current_qty, precesion):
+				val_rate = get_valuation_rate(
+					row.item_code,
+					row.warehouse,
+					self.doctype,
+					self.name,
+					company=self.company,
+					batch_no=row.batch_no,
+					serial_and_batch_bundle=row.current_serial_and_batch_bundle,
+				)
 
-			val_rate = get_valuation_rate(
-				item_code, row.warehouse, self.doctype, self.name, company=self.company, batch_no=batch_no
-			)
+				row.current_valuation_rate = val_rate
+				row.current_qty = current_qty
+				row.db_set(
+					{
+						"current_qty": row.current_qty,
+						"current_valuation_rate": row.current_valuation_rate,
+						"current_amount": flt(row.current_qty * row.current_valuation_rate),
+					}
+				)
 
-			row.current_valuation_rate = val_rate
-			if not row.current_qty and current_qty:
-				sle = self.get_sle_for_items(row)
-				sle.actual_qty = current_qty * -1
-				sle.valuation_rate = val_rate
-				sl_entries.append(sle)
+			if (
+				add_new_sle
+				and not frappe.db.get_value(
+					"Stock Ledger Entry",
+					{"voucher_detail_no": row.name, "actual_qty": ("<", 0), "is_cancelled": 0},
+					"name",
+				)
+				and (not row.current_serial_and_batch_bundle and not row.batch_no)
+			):
+				self.set_current_serial_and_batch_bundle(voucher_detail_no, save=True)
+				row.reload()
 
-			row.current_qty = current_qty
-			row.db_set(
-				{
-					"current_qty": row.current_qty,
-					"current_valuation_rate": row.current_valuation_rate,
-					"current_amount": flt(row.current_qty * row.current_valuation_rate),
-				}
-			)
+				if row.current_qty > 0 and row.current_serial_and_batch_bundle:
+					new_sle = self.get_sle_for_items(row)
+					new_sle.actual_qty = row.current_qty * -1
+					new_sle.valuation_rate = row.current_valuation_rate
+					new_sle.creation_time = add_to_date(sle_creation, seconds=-1)
+					new_sle.serial_and_batch_bundle = row.current_serial_and_batch_bundle
+					new_sle.qty_after_transaction = 0.0
+					sl_entries.append(new_sle)
 
 		if sl_entries:
-			self.make_sl_entries(sl_entries, allow_negative_stock=True)
+			self.make_sl_entries(sl_entries, allow_negative_stock=self.has_negative_stock_allowed())
+			if not frappe.db.exists("Repost Item Valuation", {"voucher_no": self.name, "status": "Queued"}):
+				self.repost_future_sle_and_gle(force=True)
 
-	def recalculate_qty_for_serial_and_batch_bundle(self, row):
+	def has_negative_stock_allowed(self):
+		allow_negative_stock = cint(frappe.db.get_single_value("Stock Settings", "allow_negative_stock"))
+
+		if all(d.serial_and_batch_bundle and flt(d.qty) == flt(d.current_qty) for d in self.items):
+			allow_negative_stock = True
+
+		return allow_negative_stock
+
+	def get_qty_for_serial_and_batch_bundle(self, row):
 		doc = frappe.get_doc("Serial and Batch Bundle", row.current_serial_and_batch_bundle)
 		precision = doc.entries[0].precision("qty")
 
+		current_qty = 0
 		for d in doc.entries:
 			qty = (
 				get_batch_qty(
@@ -714,10 +808,12 @@
 				or 0
 			) * -1
 
-			if flt(d.qty, precision) == flt(qty, precision):
-				continue
+			if flt(d.qty, precision) != flt(qty, precision):
+				d.db_set("qty", qty)
 
-			d.db_set("qty", qty)
+			current_qty += qty
+
+		return abs(current_qty)
 
 
 def get_batch_qty_for_stock_reco(
@@ -911,6 +1007,7 @@
 	posting_time,
 	batch_no: Optional[str] = None,
 	with_valuation_rate: bool = True,
+	inventory_dimensions_dict=None,
 ):
 	frappe.has_permission("Stock Reconciliation", "write", throw=True)
 
@@ -939,6 +1036,7 @@
 		posting_time,
 		with_valuation_rate=with_valuation_rate,
 		with_serial_no=has_serial_no,
+		inventory_dimensions_dict=inventory_dimensions_dict,
 	)
 
 	if has_serial_no:
diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
index 4817c8d..1ec99bf 100644
--- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
@@ -674,6 +674,7 @@
 		self.assertEqual(flt(sl_entry.actual_qty), 1.0)
 		self.assertEqual(flt(sl_entry.qty_after_transaction), 1.0)
 
+	@change_settings("Stock Reposting Settings", {"item_based_reposting": 0})
 	def test_backdated_stock_reco_entry(self):
 		from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
 
@@ -741,13 +742,6 @@
 
 		se2.cancel()
 
-		self.assertTrue(frappe.db.exists("Repost Item Valuation", {"voucher_no": stock_reco.name}))
-
-		self.assertEqual(
-			frappe.db.get_value("Repost Item Valuation", {"voucher_no": stock_reco.name}, "status"),
-			"Completed",
-		)
-
 		sle = frappe.get_all(
 			"Stock Ledger Entry",
 			filters={"item_code": item_code, "warehouse": warehouse, "is_cancelled": 0},
@@ -765,6 +759,68 @@
 
 		self.assertEqual(flt(sle[0].actual_qty), flt(-100.0))
 
+	def test_backdated_stock_reco_entry_with_batch(self):
+		from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
+
+		item_code = self.make_item(
+			"Test New Batch Item ABCVSD",
+			{
+				"is_stock_item": 1,
+				"has_batch_no": 1,
+				"batch_number_series": "BNS9.####",
+				"create_new_batch": 1,
+			},
+		).name
+
+		warehouse = "_Test Warehouse - _TC"
+
+		# Stock Reco for 100, Balace Qty 100
+		stock_reco = create_stock_reconciliation(
+			item_code=item_code,
+			posting_date=nowdate(),
+			posting_time="11:00:00",
+			warehouse=warehouse,
+			qty=100,
+			rate=100,
+		)
+
+		sles = frappe.get_all(
+			"Stock Ledger Entry",
+			fields=["actual_qty"],
+			filters={"voucher_no": stock_reco.name, "is_cancelled": 0},
+		)
+
+		self.assertEqual(len(sles), 1)
+
+		stock_reco.reload()
+		batch_no = get_batch_from_bundle(stock_reco.items[0].serial_and_batch_bundle)
+
+		# Stock Reco for 100, Balace Qty 100
+		stock_reco1 = create_stock_reconciliation(
+			item_code=item_code,
+			posting_date=add_days(nowdate(), -1),
+			posting_time="11:00:00",
+			batch_no=batch_no,
+			warehouse=warehouse,
+			qty=60,
+			rate=100,
+		)
+
+		sles = frappe.get_all(
+			"Stock Ledger Entry",
+			fields=["actual_qty"],
+			filters={"voucher_no": stock_reco.name, "is_cancelled": 0},
+		)
+
+		stock_reco1.reload()
+		new_batch_no = get_batch_from_bundle(stock_reco1.items[0].serial_and_batch_bundle)
+
+		self.assertEqual(len(sles), 2)
+
+		for row in sles:
+			if row.actual_qty < 0:
+				self.assertEqual(row.actual_qty, -60)
+
 	def test_update_stock_reconciliation_while_reposting(self):
 		from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
 
diff --git a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
index ca19bbb..d9cbf95 100644
--- a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
+++ b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
@@ -205,6 +205,7 @@
    "fieldname": "current_serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Current Serial / Batch Bundle",
+   "no_copy": 1,
    "options": "Serial and Batch Bundle",
    "read_only": 1
   },
@@ -216,7 +217,7 @@
  ],
  "istable": 1,
  "links": [],
- "modified": "2023-07-26 12:54:34.011915",
+ "modified": "2023-11-02 15:47:07.929550",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Reconciliation Item",
diff --git a/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json
index 7c712ce..68afd99 100644
--- a/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json
+++ b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json
@@ -50,7 +50,7 @@
    "label": "Limit timeslot for Stock Reposting"
   },
   {
-   "default": "0",
+   "default": "1",
    "fieldname": "item_based_reposting",
    "fieldtype": "Check",
    "label": "Use Item based reposting"
@@ -70,7 +70,7 @@
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2023-05-04 16:14:29.080697",
+ "modified": "2023-11-01 16:14:29.080697",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Reposting Settings",
diff --git a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.js b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.js
index c5df319..f60a037 100644
--- a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.js
+++ b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.js
@@ -92,7 +92,7 @@
 			'qty', 'read_only', frm.doc.has_serial_no
 		);
 
-		frm.set_df_property('sb_entries', 'allow_on_submit', frm.doc.against_pick_list ? 0 : 1);
+		frm.set_df_property('sb_entries', 'allow_on_submit', frm.doc.from_voucher_type == "Pick List" ? 0 : 1);
 	},
 
 	hide_rate_related_fields(frm) {
diff --git a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.json b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.json
index 5c3018f..76cedd4 100644
--- a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.json
+++ b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.json
@@ -17,8 +17,9 @@
   "voucher_no",
   "voucher_detail_no",
   "column_break_7dxj",
-  "against_pick_list",
-  "against_pick_list_item",
+  "from_voucher_type",
+  "from_voucher_no",
+  "from_voucher_detail_no",
   "section_break_xt4m",
   "stock_uom",
   "column_break_grdt",
@@ -158,7 +159,7 @@
    "oldfieldname": "actual_qty",
    "oldfieldtype": "Currency",
    "print_width": "150px",
-   "read_only_depends_on": "eval: ((doc.reservation_based_on == \"Serial and Batch\") || (doc.against_pick_list) || (doc.delivered_qty > 0))",
+   "read_only_depends_on": "eval: ((doc.reservation_based_on == \"Serial and Batch\") || (doc.from_voucher_type == \"Pick List\") || (doc.delivered_qty > 0))",
    "width": "150px"
   },
   {
@@ -268,27 +269,7 @@
    "label": "Reservation Based On",
    "no_copy": 1,
    "options": "Qty\nSerial and Batch",
-   "read_only_depends_on": "eval: (doc.delivered_qty > 0 || doc.against_pick_list)"
-  },
-  {
-   "fieldname": "against_pick_list",
-   "fieldtype": "Link",
-   "label": "Against Pick List",
-   "no_copy": 1,
-   "options": "Pick List",
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1,
-   "search_index": 1
-  },
-  {
-   "fieldname": "against_pick_list_item",
-   "fieldtype": "Data",
-   "label": "Against Pick List Item",
-   "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1,
-   "report_hide": 1
+   "read_only_depends_on": "eval: (doc.delivered_qty > 0 || doc.from_voucher_type == \"Pick List\")"
   },
   {
    "fieldname": "column_break_7dxj",
@@ -297,6 +278,36 @@
   {
    "fieldname": "column_break_grdt",
    "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "from_voucher_type",
+   "fieldtype": "Select",
+   "label": "From Voucher Type",
+   "no_copy": 1,
+   "options": "\nPick List\nPurchase Receipt",
+   "print_hide": 1,
+   "read_only": 1,
+   "report_hide": 1
+  },
+  {
+   "fieldname": "from_voucher_detail_no",
+   "fieldtype": "Data",
+   "label": "From Voucher Detail No",
+   "no_copy": 1,
+   "print_hide": 1,
+   "read_only": 1,
+   "report_hide": 1
+  },
+  {
+   "fieldname": "from_voucher_no",
+   "fieldtype": "Dynamic Link",
+   "label": "From Voucher No",
+   "no_copy": 1,
+   "options": "from_voucher_type",
+   "print_hide": 1,
+   "read_only": 1,
+   "report_hide": 1,
+   "search_index": 1
   }
  ],
  "hide_toolbar": 1,
@@ -304,7 +315,7 @@
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-08-08 17:15:13.317706",
+ "modified": "2023-10-19 16:41:16.545416",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Reservation Entry",
diff --git a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
index 936be3f..0954282 100644
--- a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
+++ b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
@@ -1,12 +1,16 @@
 # Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
 # For license information, please see license.txt
 
+from typing import Literal
+
 import frappe
 from frappe import _
 from frappe.model.document import Document
 from frappe.query_builder.functions import Sum
 from frappe.utils import cint, flt
 
+from erpnext.stock.utils import get_or_make_bin
+
 
 class StockReservationEntry(Document):
 	def validate(self) -> None:
@@ -29,6 +33,7 @@
 		self.update_reserved_qty_in_voucher()
 		self.update_reserved_qty_in_pick_list()
 		self.update_status()
+		self.update_reserved_stock_in_bin()
 
 	def on_update_after_submit(self) -> None:
 		self.can_be_updated()
@@ -38,12 +43,14 @@
 		self.validate_reservation_based_on_serial_and_batch()
 		self.update_reserved_qty_in_voucher()
 		self.update_status()
+		self.update_reserved_stock_in_bin()
 		self.reload()
 
 	def on_cancel(self) -> None:
 		self.update_reserved_qty_in_voucher()
 		self.update_reserved_qty_in_pick_list()
 		self.update_status()
+		self.update_reserved_stock_in_bin()
 
 	def validate_amended_doc(self) -> None:
 		"""Raises an exception if document is amended."""
@@ -113,7 +120,7 @@
 		"""Auto pick Serial and Batch Nos to reserve when `Reservation Based On` is `Serial and Batch`."""
 
 		if (
-			not self.against_pick_list
+			not self.from_voucher_type
 			and (self.get("_action") == "submit")
 			and (self.has_serial_no or self.has_batch_no)
 			and cint(frappe.db.get_single_value("Stock Settings", "auto_reserve_serial_and_batch"))
@@ -239,7 +246,7 @@
 
 					if available_qty_to_reserve <= 0:
 						msg = _(
-							"Row #{0}: Stock not availabe to reserve for Item {1} against Batch {2} in Warehouse {3}."
+							"Row #{0}: Stock not available to reserve for Item {1} against Batch {2} in Warehouse {3}."
 						).format(
 							entry.idx,
 							frappe.bold(self.item_code),
@@ -316,26 +323,36 @@
 	) -> None:
 		"""Updates total reserved qty in the Pick List."""
 
-		if self.against_pick_list and self.against_pick_list_item:
+		if (
+			self.from_voucher_type == "Pick List" and self.from_voucher_no and self.from_voucher_detail_no
+		):
 			sre = frappe.qb.DocType("Stock Reservation Entry")
 			reserved_qty = (
 				frappe.qb.from_(sre)
 				.select(Sum(sre.reserved_qty))
 				.where(
 					(sre.docstatus == 1)
-					& (sre.against_pick_list == self.against_pick_list)
-					& (sre.against_pick_list_item == self.against_pick_list_item)
+					& (sre.from_voucher_type == "Pick List")
+					& (sre.from_voucher_no == self.from_voucher_no)
+					& (sre.from_voucher_detail_no == self.from_voucher_detail_no)
 				)
 			).run(as_list=True)[0][0] or 0
 
 			frappe.db.set_value(
 				"Pick List Item",
-				self.against_pick_list_item,
+				self.from_voucher_detail_no,
 				reserved_qty_field,
 				reserved_qty,
 				update_modified=update_modified,
 			)
 
+	def update_reserved_stock_in_bin(self) -> None:
+		"""Updates `Reserved Stock` in Bin."""
+
+		bin_name = get_or_make_bin(self.item_code, self.warehouse)
+		bin_doc = frappe.get_cached_doc("Bin", bin_name)
+		bin_doc.update_reserved_stock()
+
 	def update_status(self, status: str = None, update_modified: bool = True) -> None:
 		"""Updates status based on Voucher Qty, Reserved Qty and Delivered Qty."""
 
@@ -365,7 +382,7 @@
 			).format(self.status, self.doctype)
 			frappe.throw(msg)
 
-		if self.against_pick_list:
+		if self.from_voucher_type == "Pick List":
 			msg = _(
 				"Stock Reservation Entry created against a Pick List cannot be updated. If you need to make changes, we recommend canceling the existing entry and creating a new one."
 			)
@@ -676,6 +693,68 @@
 	return flt(reserved_qty[0][0])
 
 
+def get_sre_reserved_serial_nos_details(
+	item_code: str, warehouse: str, serial_nos: list = None
+) -> dict:
+	"""Returns a dict of `Serial No` reserved in Stock Reservation Entry. The dict is like {serial_no: sre_name, ...}"""
+
+	sre = frappe.qb.DocType("Stock Reservation Entry")
+	sb_entry = frappe.qb.DocType("Serial and Batch Entry")
+	query = (
+		frappe.qb.from_(sre)
+		.inner_join(sb_entry)
+		.on(sre.name == sb_entry.parent)
+		.select(sb_entry.serial_no, sre.name)
+		.where(
+			(sre.docstatus == 1)
+			& (sre.item_code == item_code)
+			& (sre.warehouse == warehouse)
+			& (sre.reserved_qty > sre.delivered_qty)
+			& (sre.status.notin(["Delivered", "Cancelled"]))
+			& (sre.reservation_based_on == "Serial and Batch")
+		)
+		.orderby(sb_entry.creation)
+	)
+
+	if serial_nos:
+		query = query.where(sb_entry.serial_no.isin(serial_nos))
+
+	return frappe._dict(query.run())
+
+
+def get_sre_reserved_batch_nos_details(
+	item_code: str, warehouse: str, batch_nos: list = None
+) -> dict:
+	"""Returns a dict of `Batch Qty` reserved in Stock Reservation Entry. The dict is like {batch_no: qty, ...}"""
+
+	sre = frappe.qb.DocType("Stock Reservation Entry")
+	sb_entry = frappe.qb.DocType("Serial and Batch Entry")
+	query = (
+		frappe.qb.from_(sre)
+		.inner_join(sb_entry)
+		.on(sre.name == sb_entry.parent)
+		.select(
+			sb_entry.batch_no,
+			Sum(sb_entry.qty - sb_entry.delivered_qty),
+		)
+		.where(
+			(sre.docstatus == 1)
+			& (sre.item_code == item_code)
+			& (sre.warehouse == warehouse)
+			& ((sre.reserved_qty - sre.delivered_qty) > 0)
+			& (sre.status.notin(["Delivered", "Cancelled"]))
+			& (sre.reservation_based_on == "Serial and Batch")
+		)
+		.groupby(sb_entry.batch_no)
+		.orderby(sb_entry.creation)
+	)
+
+	if batch_nos:
+		query = query.where(sb_entry.batch_no.isin(batch_nos))
+
+	return frappe._dict(query.run())
+
+
 def get_sre_details_for_voucher(voucher_type: str, voucher_no: str) -> list[dict]:
 	"""Returns a list of SREs for the provided voucher."""
 
@@ -761,25 +840,27 @@
 
 
 def create_stock_reservation_entries_for_so_items(
-	so: object,
+	sales_order: object,
 	items_details: list[dict] = None,
-	against_pick_list: bool = False,
+	from_voucher_type: Literal["Pick List", "Purchase Receipt"] = None,
 	notify=True,
 ) -> None:
 	"""Creates Stock Reservation Entries for Sales Order Items."""
 
 	from erpnext.selling.doctype.sales_order.sales_order import get_unreserved_qty
 
-	if not against_pick_list and (
-		so.get("_action") == "submit"
-		and so.set_warehouse
-		and cint(frappe.get_cached_value("Warehouse", so.set_warehouse, "is_group"))
+	if not from_voucher_type and (
+		sales_order.get("_action") == "submit"
+		and sales_order.set_warehouse
+		and cint(frappe.get_cached_value("Warehouse", sales_order.set_warehouse, "is_group"))
 	):
 		return frappe.msgprint(
-			_("Stock cannot be reserved in the group warehouse {0}.").format(frappe.bold(so.set_warehouse))
+			_("Stock cannot be reserved in the group warehouse {0}.").format(
+				frappe.bold(sales_order.set_warehouse)
+			)
 		)
 
-	validate_stock_reservation_settings(so)
+	validate_stock_reservation_settings(sales_order)
 
 	allow_partial_reservation = frappe.db.get_single_value(
 		"Stock Settings", "allow_partial_reservation"
@@ -788,38 +869,36 @@
 	items = []
 	if items_details:
 		for item in items_details:
-			so_item = frappe.get_doc(
-				"Sales Order Item", item.get("sales_order_item") if against_pick_list else item.get("name")
-			)
-			so_item.reserve_stock = 1
+			so_item = frappe.get_doc("Sales Order Item", item.get("name"))
 			so_item.warehouse = item.get("warehouse")
 			so_item.qty_to_reserve = (
-				item.get("picked_qty") - item.get("stock_reserved_qty", 0)
-				if against_pick_list
-				else (flt(item.get("qty_to_reserve")) * flt(so_item.conversion_factor, 1))
+				flt(item.get("qty_to_reserve"))
+				if from_voucher_type in ["Pick List", "Purchase Receipt"]
+				else (
+					flt(item.get("qty_to_reserve"))
+					* (flt(item.get("conversion_factor")) or flt(so_item.conversion_factor) or 1)
+				)
 			)
-
-			if against_pick_list:
-				so_item.pick_list = item.get("parent")
-				so_item.pick_list_item = item.get("name")
-				so_item.pick_list_sbb = item.get("serial_and_batch_bundle")
+			so_item.from_voucher_no = item.get("from_voucher_no")
+			so_item.from_voucher_detail_no = item.get("from_voucher_detail_no")
+			so_item.serial_and_batch_bundle = item.get("serial_and_batch_bundle")
 
 			items.append(so_item)
 
 	sre_count = 0
-	reserved_qty_details = get_sre_reserved_qty_details_for_voucher("Sales Order", so.name)
+	reserved_qty_details = get_sre_reserved_qty_details_for_voucher("Sales Order", sales_order.name)
 
-	for item in items if items_details else so.get("items"):
+	for item in items if items_details else sales_order.get("items"):
 		# Skip if `Reserved Stock` is not checked for the item.
 		if not item.get("reserve_stock"):
 			continue
 
 		# Stock should be reserved from the Pick List if has Picked Qty.
-		if not against_pick_list and flt(item.picked_qty) > 0:
+		if not from_voucher_type == "Pick List" and flt(item.picked_qty) > 0:
 			frappe.throw(
-				_(
-					"Row #{0}: Item {1} has been picked, please create a Stock Reservation from the Pick List."
-				).format(item.idx, frappe.bold(item.item_code))
+				_("Row #{0}: Item {1} has been picked, please reserve stock from the Pick List.").format(
+					item.idx, frappe.bold(item.item_code)
+				)
 			)
 
 		is_stock_item, has_serial_no, has_batch_no = frappe.get_cached_value(
@@ -828,13 +907,15 @@
 
 		# Skip if Non-Stock Item.
 		if not is_stock_item:
-			frappe.msgprint(
-				_("Row #{0}: Stock cannot be reserved for a non-stock Item {1}").format(
-					item.idx, frappe.bold(item.item_code)
-				),
-				title=_("Stock Reservation"),
-				indicator="yellow",
-			)
+			if not from_voucher_type:
+				frappe.msgprint(
+					_("Row #{0}: Stock cannot be reserved for a non-stock Item {1}").format(
+						item.idx, frappe.bold(item.item_code)
+					),
+					title=_("Stock Reservation"),
+					indicator="yellow",
+				)
+
 			item.db_set("reserve_stock", 0)
 			continue
 
@@ -853,13 +934,15 @@
 
 		# Stock is already reserved for the item, notify the user and skip the item.
 		if unreserved_qty <= 0:
-			frappe.msgprint(
-				_("Row #{0}: Stock is already reserved for the Item {1}.").format(
-					item.idx, frappe.bold(item.item_code)
-				),
-				title=_("Stock Reservation"),
-				indicator="yellow",
-			)
+			if not from_voucher_type:
+				frappe.msgprint(
+					_("Row #{0}: Stock is already reserved for the Item {1}.").format(
+						item.idx, frappe.bold(item.item_code)
+					),
+					title=_("Stock Reservation"),
+					indicator="yellow",
+				)
+
 			continue
 
 		available_qty_to_reserve = get_available_qty_to_reserve(item.item_code, item.warehouse)
@@ -867,7 +950,7 @@
 		# No stock available to reserve, notify the user and skip the item.
 		if available_qty_to_reserve <= 0:
 			frappe.msgprint(
-				_("Row #{0}: No available stock to reserve for the Item {1} in Warehouse {2}.").format(
+				_("Row #{0}: Stock not available to reserve for the Item {1} in Warehouse {2}.").format(
 					item.idx, frappe.bold(item.item_code), frappe.bold(item.warehouse)
 				),
 				title=_("Stock Reservation"),
@@ -893,7 +976,9 @@
 
 		# Partial Reservation
 		if qty_to_be_reserved < unreserved_qty:
-			if not item.get("qty_to_reserve") or qty_to_be_reserved < flt(item.get("qty_to_reserve")):
+			if not from_voucher_type and (
+				not item.get("qty_to_reserve") or qty_to_be_reserved < flt(item.get("qty_to_reserve"))
+			):
 				msg = _("Row #{0}: Only {1} available to reserve for the Item {2}").format(
 					item.idx,
 					frappe.bold(str(qty_to_be_reserved / item.conversion_factor) + " " + item.uom),
@@ -915,33 +1000,42 @@
 		sre.warehouse = item.warehouse
 		sre.has_serial_no = has_serial_no
 		sre.has_batch_no = has_batch_no
-		sre.voucher_type = so.doctype
-		sre.voucher_no = so.name
+		sre.voucher_type = sales_order.doctype
+		sre.voucher_no = sales_order.name
 		sre.voucher_detail_no = item.name
 		sre.available_qty = available_qty_to_reserve
 		sre.voucher_qty = item.stock_qty
 		sre.reserved_qty = qty_to_be_reserved
-		sre.company = so.company
+		sre.company = sales_order.company
 		sre.stock_uom = item.stock_uom
-		sre.project = so.project
+		sre.project = sales_order.project
 
-		if against_pick_list:
-			sre.against_pick_list = item.pick_list
-			sre.against_pick_list_item = item.pick_list_item
+		if from_voucher_type:
+			sre.from_voucher_type = from_voucher_type
+			sre.from_voucher_no = item.from_voucher_no
+			sre.from_voucher_detail_no = item.from_voucher_detail_no
 
-			if item.pick_list_sbb:
-				sbb = frappe.get_doc("Serial and Batch Bundle", item.pick_list_sbb)
-				sre.reservation_based_on = "Serial and Batch"
-				for entry in sbb.entries:
-					sre.append(
-						"sb_entries",
-						{
-							"serial_no": entry.serial_no,
-							"batch_no": entry.batch_no,
-							"qty": 1 if has_serial_no else abs(entry.qty),
-							"warehouse": entry.warehouse,
-						},
-					)
+		if item.get("serial_and_batch_bundle"):
+			sbb = frappe.get_doc("Serial and Batch Bundle", item.serial_and_batch_bundle)
+			sre.reservation_based_on = "Serial and Batch"
+
+			index, picked_qty = 0, 0
+			while index < len(sbb.entries) and picked_qty < qty_to_be_reserved:
+				entry = sbb.entries[index]
+				qty = 1 if has_serial_no else min(abs(entry.qty), qty_to_be_reserved - picked_qty)
+
+				sre.append(
+					"sb_entries",
+					{
+						"serial_no": entry.serial_no,
+						"batch_no": entry.batch_no,
+						"qty": qty,
+						"warehouse": entry.warehouse,
+					},
+				)
+
+				index += 1
+				picked_qty += qty
 
 		sre.save()
 		sre.submit()
@@ -956,29 +1050,37 @@
 	voucher_type: str = None,
 	voucher_no: str = None,
 	voucher_detail_no: str = None,
-	against_pick_list: str = None,
+	from_voucher_type: Literal["Pick List", "Purchase Receipt"] = None,
+	from_voucher_no: str = None,
+	from_voucher_detail_no: str = None,
 	sre_list: list[dict] = None,
 	notify: bool = True,
 ) -> None:
 	"""Cancel Stock Reservation Entries."""
 
-	if not sre_list and against_pick_list:
-		sre = frappe.qb.DocType("Stock Reservation Entry")
-		sre_list = (
-			frappe.qb.from_(sre)
-			.select(sre.name)
-			.where(
-				(sre.docstatus == 1)
-				& (sre.against_pick_list == against_pick_list)
-				& (sre.status.notin(["Delivered", "Cancelled"]))
+	if not sre_list:
+		if voucher_type and voucher_no:
+			sre_list = get_stock_reservation_entries_for_voucher(
+				voucher_type, voucher_no, voucher_detail_no, fields=["name"]
 			)
-			.orderby(sre.creation)
-		).run(as_dict=True)
+		elif from_voucher_type and from_voucher_no:
+			sre = frappe.qb.DocType("Stock Reservation Entry")
+			query = (
+				frappe.qb.from_(sre)
+				.select(sre.name)
+				.where(
+					(sre.docstatus == 1)
+					& (sre.from_voucher_type == from_voucher_type)
+					& (sre.from_voucher_no == from_voucher_no)
+					& (sre.status.notin(["Delivered", "Cancelled"]))
+				)
+				.orderby(sre.creation)
+			)
 
-	elif not sre_list and (voucher_type and voucher_no):
-		sre_list = get_stock_reservation_entries_for_voucher(
-			voucher_type, voucher_no, voucher_detail_no, fields=["name"]
-		)
+			if from_voucher_detail_no:
+				query = query.where(sre.from_voucher_detail_no == from_voucher_detail_no)
+
+			sre_list = query.run(as_dict=True)
 
 	if sre_list:
 		for sre in sre_list:
diff --git a/erpnext/stock/doctype/stock_reservation_entry/test_stock_reservation_entry.py b/erpnext/stock/doctype/stock_reservation_entry/test_stock_reservation_entry.py
index 1168a4e..dd023e2 100644
--- a/erpnext/stock/doctype/stock_reservation_entry/test_stock_reservation_entry.py
+++ b/erpnext/stock/doctype/stock_reservation_entry/test_stock_reservation_entry.py
@@ -5,6 +5,7 @@
 
 import frappe
 from frappe.tests.utils import FrappeTestCase, change_settings
+from frappe.utils import today
 
 from erpnext.selling.doctype.sales_order.sales_order import create_pick_list, make_delivery_note
 from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
@@ -28,10 +29,6 @@
 			items={self.sr_item.name: self.sr_item}, warehouse=self.warehouse, qty=100
 		)
 
-	def tearDown(self) -> None:
-		cancel_all_stock_reservation_entries()
-		return super().tearDown()
-
 	@change_settings("Stock Settings", {"allow_negative_stock": 0})
 	def test_validate_stock_reservation_settings(self) -> None:
 		from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import (
@@ -289,6 +286,7 @@
 				self.assertEqual(item.stock_reserved_qty, sre_details.reserved_qty)
 				self.assertEqual(sre_details.status, "Partially Reserved")
 
+			cancel_stock_reservation_entries("Sales Order", so.name)
 			se.cancel()
 
 			# Test - 3: Stock should be fully Reserved if the Available Qty to Reserve is greater than the Un-reserved Qty.
@@ -496,7 +494,7 @@
 			"pick_serial_and_batch_based_on": "FIFO",
 		},
 	)
-	def test_stock_reservation_from_pick_list(self):
+	def test_stock_reservation_from_pick_list(self) -> None:
 		items_details = create_items()
 		create_material_receipt(items_details, self.warehouse, qty=100)
 
@@ -555,8 +553,9 @@
 						(sre.voucher_type == "Sales Order")
 						& (sre.voucher_no == location.sales_order)
 						& (sre.voucher_detail_no == location.sales_order_item)
-						& (sre.against_pick_list == pl.name)
-						& (sre.against_pick_list_item == location.name)
+						& (sre.from_voucher_type == "Pick List")
+						& (sre.from_voucher_no == pl.name)
+						& (sre.from_voucher_detail_no == location.name)
 					)
 				).run(as_dict=True)
 				reserved_sb_details: set[tuple] = {
@@ -567,6 +566,124 @@
 				# Test - 3: Reserved Serial/Batch Nos should be equal to Picked Serial/Batch Nos.
 				self.assertSetEqual(picked_sb_details, reserved_sb_details)
 
+	@change_settings(
+		"Stock Settings",
+		{
+			"allow_negative_stock": 0,
+			"enable_stock_reservation": 1,
+			"auto_reserve_serial_and_batch": 1,
+			"pick_serial_and_batch_based_on": "FIFO",
+			"auto_reserve_stock_for_sales_order_on_purchase": 1,
+		},
+	)
+	def test_stock_reservation_from_purchase_receipt(self) -> None:
+		from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt
+		from erpnext.selling.doctype.sales_order.sales_order import make_material_request
+		from erpnext.stock.doctype.material_request.material_request import make_purchase_order
+
+		items_details = create_items()
+		create_material_receipt(items_details, self.warehouse, qty=10)
+
+		item_list = []
+		for item_code, properties in items_details.items():
+			item_list.append(
+				{
+					"item_code": item_code,
+					"warehouse": self.warehouse,
+					"qty": randint(11, 100),
+					"uom": properties.stock_uom,
+					"rate": randint(10, 400),
+				}
+			)
+
+		so = make_sales_order(
+			item_list=item_list,
+			warehouse=self.warehouse,
+		)
+
+		mr = make_material_request(so.name)
+		mr.schedule_date = today()
+		mr.save().submit()
+
+		po = make_purchase_order(mr.name)
+		po.supplier = "_Test Supplier"
+		po.save().submit()
+
+		pr = make_purchase_receipt(po.name)
+		pr.save().submit()
+
+		for item in pr.items:
+			sre, status, reserved_qty = frappe.db.get_value(
+				"Stock Reservation Entry",
+				{
+					"from_voucher_type": "Purchase Receipt",
+					"from_voucher_no": pr.name,
+					"from_voucher_detail_no": item.name,
+				},
+				["name", "status", "reserved_qty"],
+			)
+
+			# Test - 1: SRE status should be `Reserved`.
+			self.assertEqual(status, "Reserved")
+
+			# Test - 2: SRE Reserved Qty should be equal to PR Item Qty.
+			self.assertEqual(reserved_qty, item.qty)
+
+			if item.serial_and_batch_bundle:
+				sb_details = frappe.db.get_all(
+					"Serial and Batch Entry",
+					filters={"parent": item.serial_and_batch_bundle},
+					fields=["serial_no", "batch_no", "qty"],
+					as_list=True,
+				)
+				reserved_sb_details = frappe.db.get_all(
+					"Serial and Batch Entry",
+					filters={"parent": sre},
+					fields=["serial_no", "batch_no", "qty"],
+					as_list=True,
+				)
+
+				# Test - 3: Reserved Serial/Batch Nos should be equal to PR Item Serial/Batch Nos.
+				self.assertEqual(set(sb_details), set(reserved_sb_details))
+
+	@change_settings(
+		"Stock Settings",
+		{
+			"allow_negative_stock": 0,
+			"enable_stock_reservation": 1,
+			"auto_reserve_serial_and_batch": 1,
+			"pick_serial_and_batch_based_on": "FIFO",
+		},
+	)
+	def test_consider_reserved_stock_while_cancelling_an_inward_transaction(self) -> None:
+		items_details = create_items()
+		se = create_material_receipt(items_details, self.warehouse, qty=100)
+
+		item_list = []
+		for item_code, properties in items_details.items():
+			item_list.append(
+				{
+					"item_code": item_code,
+					"warehouse": self.warehouse,
+					"qty": randint(11, 100),
+					"uom": properties.stock_uom,
+					"rate": randint(10, 400),
+				}
+			)
+
+		so = make_sales_order(
+			item_list=item_list,
+			warehouse=self.warehouse,
+		)
+		so.create_stock_reservation_entries()
+
+		# Test - 1: ValidationError should be thrown as the inwarded stock is reserved.
+		self.assertRaises(frappe.ValidationError, se.cancel)
+
+	def tearDown(self) -> None:
+		cancel_all_stock_reservation_entries()
+		return super().tearDown()
+
 
 def create_items() -> dict:
 	items_properties = [
diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.json b/erpnext/stock/doctype/stock_settings/stock_settings.json
index 4fbc0eb..1228290 100644
--- a/erpnext/stock/doctype/stock_settings/stock_settings.json
+++ b/erpnext/stock/doctype/stock_settings/stock_settings.json
@@ -38,8 +38,8 @@
   "stock_reservation_tab",
   "enable_stock_reservation",
   "column_break_rx3e",
-  "auto_reserve_stock_for_sales_order",
   "allow_partial_reservation",
+  "auto_reserve_stock_for_sales_order_on_purchase",
   "serial_and_batch_reservation_section",
   "auto_reserve_serial_and_batch",
   "serial_and_batch_item_settings_tab",
@@ -65,8 +65,7 @@
   "stock_frozen_upto_days",
   "column_break_26",
   "role_allowed_to_create_edit_back_dated_transactions",
-  "stock_auth_role",
-  "section_break_plhx"
+  "stock_auth_role"
  ],
  "fields": [
   {
@@ -356,7 +355,7 @@
   {
    "default": "1",
    "depends_on": "eval: doc.enable_stock_reservation",
-   "description": "If enabled, <b>Partial Stock Reservation Entries</b> can be created. For example, If you have a Sales Order of 100 units and the Available Stock is 90 units then a Stock Reservation Entry will be created for 90 units. ",
+   "description": "Partial stock can be reserved. For example, If you have a Sales Order of 100 units and the Available Stock is 90 units then a Stock Reservation Entry will be created for 90 units. ",
    "fieldname": "allow_partial_reservation",
    "fieldtype": "Check",
    "label": "Allow Partial Reservation"
@@ -383,7 +382,7 @@
   {
    "default": "1",
    "depends_on": "eval: doc.enable_stock_reservation",
-   "description": "If enabled, Serial and Batch Nos will be auto-reserved based on <b>Pick Serial / Batch Based On</b>",
+   "description": "Serial and Batch Nos will be auto-reserved based on <b>Pick Serial / Batch Based On</b>",
    "fieldname": "auto_reserve_serial_and_batch",
    "fieldtype": "Check",
    "label": "Auto Reserve Serial and Batch Nos"
@@ -394,14 +393,6 @@
    "label": "Serial and Batch Reservation"
   },
   {
-   "default": "0",
-   "depends_on": "eval: doc.enable_stock_reservation",
-   "description": "If enabled, <b>Stock Reservation Entries</b> will be created on submission of <b>Sales Order</b>",
-   "fieldname": "auto_reserve_stock_for_sales_order",
-   "fieldtype": "Check",
-   "label": "Auto Reserve Stock for Sales Order"
-  },
-  {
    "fieldname": "conversion_factor_section",
    "fieldtype": "Section Break",
    "label": "Stock UOM Quantity"
@@ -421,6 +412,14 @@
    "fieldname": "allow_to_edit_stock_uom_qty_for_purchase",
    "fieldtype": "Check",
    "label": "Allow to Edit Stock UOM Qty for Purchase Documents"
+  },
+  {
+   "default": "0",
+   "depends_on": "eval: doc.enable_stock_reservation",
+   "description": "Stock will be reserved on submission of <b>Purchase Receipt</b> created against Material Receipt for Sales Order.",
+   "fieldname": "auto_reserve_stock_for_sales_order_on_purchase",
+   "fieldtype": "Check",
+   "label": "Auto Reserve Stock for Sales Order on Purchase"
   }
  ],
  "icon": "icon-cog",
@@ -428,7 +427,7 @@
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2023-09-01 16:16:34.018947",
+ "modified": "2023-10-18 12:35:30.068799",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Settings",
@@ -442,6 +441,10 @@
    "role": "Stock Manager",
    "share": 1,
    "write": 1
+  },
+  {
+   "read": 1,
+   "role": "Sales User"
   }
  ],
  "quick_entry": 1,
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index a6ab63b..e29fc88 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -268,7 +268,7 @@
 	if not item:
 		item = frappe.get_doc("Item", args.get("item_code"))
 
-	if item.variant_of:
+	if item.variant_of and not item.taxes:
 		item.update_template_tables()
 
 	item_defaults = get_item_defaults(item.name, args.company)
@@ -330,8 +330,12 @@
 			),
 			"expense_account": expense_account
 			or get_default_expense_account(args, item_defaults, item_group_defaults, brand_defaults),
-			"discount_account": get_default_discount_account(args, item_defaults),
-			"provisional_expense_account": get_provisional_account(args, item_defaults),
+			"discount_account": get_default_discount_account(
+				args, item_defaults, item_group_defaults, brand_defaults
+			),
+			"provisional_expense_account": get_provisional_account(
+				args, item_defaults, item_group_defaults, brand_defaults
+			),
 			"cost_center": get_default_cost_center(
 				args, item_defaults, item_group_defaults, brand_defaults
 			),
@@ -606,6 +610,7 @@
 
 	# all templates have validity and no template is valid
 	if not taxes_with_validity and (not taxes_with_no_validity):
+		out["item_tax_template"] = ""
 		return None
 
 	# do not change if already a valid template
@@ -685,12 +690,22 @@
 	)
 
 
-def get_provisional_account(args, item):
-	return item.get("default_provisional_account") or args.default_provisional_account
+def get_provisional_account(args, item, item_group, brand):
+	return (
+		item.get("default_provisional_account")
+		or item_group.get("default_provisional_account")
+		or brand.get("default_provisional_account")
+		or args.default_provisional_account
+	)
 
 
-def get_default_discount_account(args, item):
-	return item.get("default_discount_account") or args.discount_account
+def get_default_discount_account(args, item, item_group, brand):
+	return (
+		item.get("default_discount_account")
+		or item_group.get("default_discount_account")
+		or brand.get("default_discount_account")
+		or args.discount_account
+	)
 
 
 def get_default_deferred_account(args, item, fieldname=None):
@@ -737,6 +752,12 @@
 			data = frappe.get_attr(path)(args.get("item_code"), company)
 
 			if data and (data.selling_cost_center or data.buying_cost_center):
+				if args.get("customer") and data.selling_cost_center:
+					return data.selling_cost_center
+
+				elif args.get("supplier") and data.buying_cost_center:
+					return data.buying_cost_center
+
 				return data.selling_cost_center or data.buying_cost_center
 
 	if not cost_center and args.get("cost_center"):
diff --git a/erpnext/stock/page/stock_balance/stock_balance.js b/erpnext/stock/page/stock_balance/stock_balance.js
index f00dd3e..90b8d45 100644
--- a/erpnext/stock/page/stock_balance/stock_balance.js
+++ b/erpnext/stock/page/stock_balance/stock_balance.js
@@ -11,6 +11,7 @@
 		label: __('Warehouse'),
 		fieldtype:'Link',
 		options:'Warehouse',
+		default: frappe.route_options && frappe.route_options.warehouse,
 		change: function() {
 			page.item_dashboard.start = 0;
 			page.item_dashboard.refresh();
@@ -22,6 +23,7 @@
 		label: __('Item'),
 		fieldtype:'Link',
 		options:'Item',
+		default: frappe.route_options && frappe.route_options.item_code,
 		change: function() {
 			page.item_dashboard.start = 0;
 			page.item_dashboard.refresh();
@@ -33,6 +35,7 @@
 		label: __('Item Group'),
 		fieldtype:'Link',
 		options:'Item Group',
+		default: frappe.route_options && frappe.route_options.item_group,
 		change: function() {
 			page.item_dashboard.start = 0;
 			page.item_dashboard.refresh();
diff --git a/erpnext/stock/report/reserved_stock/reserved_stock.js b/erpnext/stock/report/reserved_stock/reserved_stock.js
index 2199f52..6872741 100644
--- a/erpnext/stock/report/reserved_stock/reserved_stock.js
+++ b/erpnext/stock/report/reserved_stock/reserved_stock.js
@@ -91,16 +91,30 @@
 			},
 		},
 		{
-			fieldname: "against_pick_list",
-			label: __("Against Pick List"),
+			fieldname: "from_voucher_type",
+			label: __("From Voucher Type"),
 			fieldtype: "Link",
-			options: "Pick List",
+			options: "DocType",
+			get_query: () => ({
+				filters: {
+					name: ["in", ["Pick List", "Purchase Receipt"]],
+				}
+			}),
+		},
+		{
+			fieldname: "from_voucher_no",
+			label: __("From Voucher No"),
+			fieldtype: "Dynamic Link",
+			options: "from_voucher_type",
 			get_query: () => ({
 				filters: {
 					docstatus: 1,
 					company: frappe.query_report.get_filter_value("company"),
 				},
 			}),
+			get_options: function () {
+				return frappe.query_report.get_filter_value("from_voucher_type");
+			},
 		},
 		{
 			fieldname: "reservation_based_on",
diff --git a/erpnext/stock/report/reserved_stock/reserved_stock.py b/erpnext/stock/report/reserved_stock/reserved_stock.py
index d93ee1c..21ce203 100644
--- a/erpnext/stock/report/reserved_stock/reserved_stock.py
+++ b/erpnext/stock/report/reserved_stock/reserved_stock.py
@@ -44,7 +44,8 @@
 			(sre.available_qty - sre.reserved_qty).as_("available_qty"),
 			sre.voucher_type,
 			sre.voucher_no,
-			sre.against_pick_list,
+			sre.from_voucher_type,
+			sre.from_voucher_no,
 			sre.name.as_("stock_reservation_entry"),
 			sre.status,
 			sre.project,
@@ -65,7 +66,8 @@
 		"warehouse",
 		"voucher_type",
 		"voucher_no",
-		"against_pick_list",
+		"from_voucher_type",
+		"from_voucher_no",
 		"reservation_based_on",
 		"status",
 		"project",
@@ -142,7 +144,6 @@
 			"fieldname": "voucher_type",
 			"label": _("Voucher Type"),
 			"fieldtype": "Data",
-			"options": "Warehouse",
 			"width": 110,
 		},
 		{
@@ -153,11 +154,17 @@
 			"width": 120,
 		},
 		{
-			"fieldname": "against_pick_list",
-			"label": _("Against Pick List"),
-			"fieldtype": "Link",
-			"options": "Pick List",
-			"width": 130,
+			"fieldname": "from_voucher_type",
+			"label": _("From Voucher Type"),
+			"fieldtype": "Data",
+			"width": 110,
+		},
+		{
+			"fieldname": "from_voucher_no",
+			"label": _("From Voucher No"),
+			"fieldtype": "Dynamic Link",
+			"options": "from_voucher_type",
+			"width": 120,
 		},
 		{
 			"fieldname": "stock_reservation_entry",
diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py
index eeef396..e59f2fe 100644
--- a/erpnext/stock/report/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/report/stock_ledger/stock_ledger.py
@@ -249,6 +249,13 @@
 				"options": "Serial No",
 				"width": 100,
 			},
+			{
+				"label": _("Serial and Batch Bundle"),
+				"fieldname": "serial_and_batch_bundle",
+				"fieldtype": "Link",
+				"options": "Serial and Batch Bundle",
+				"width": 100,
+			},
 			{"label": _("Balance Serial No"), "fieldname": "balance_serial_no", "width": 100},
 			{
 				"label": _("Project"),
@@ -287,6 +294,7 @@
 			sle.voucher_type,
 			sle.qty_after_transaction,
 			sle.stock_value_difference,
+			sle.serial_and_batch_bundle,
 			sle.voucher_no,
 			sle.stock_value,
 			sle.batch_no,
diff --git a/erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py b/erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py
index ca15afe..fb392f7 100644
--- a/erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py
+++ b/erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py
@@ -24,6 +24,7 @@
 	"stock_value_difference",
 	"valuation_rate",
 	"voucher_detail_no",
+	"serial_and_batch_bundle",
 )
 
 
@@ -64,7 +65,11 @@
 
 		balance_qty += sle.actual_qty
 		balance_stock_value += sle.stock_value_difference
-		if sle.voucher_type == "Stock Reconciliation" and not sle.batch_no:
+		if (
+			sle.voucher_type == "Stock Reconciliation"
+			and not sle.batch_no
+			and not sle.serial_and_batch_bundle
+		):
 			balance_qty = frappe.db.get_value("Stock Reconciliation Item", sle.voucher_detail_no, "qty")
 			if balance_qty is None:
 				balance_qty = sle.qty_after_transaction
@@ -144,6 +149,12 @@
 			"options": "Batch",
 		},
 		{
+			"fieldname": "serial_and_batch_bundle",
+			"fieldtype": "Link",
+			"label": _("Serial and Batch Bundle"),
+			"options": "Serial and Batch Bundle",
+		},
+		{
 			"fieldname": "use_batchwise_valuation",
 			"fieldtype": "Check",
 			"label": _("Batchwise Valuation"),
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index db71fe2..e9381d4 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -2,6 +2,7 @@
 # License: GNU General Public License v3. See license.txt
 
 import copy
+import gzip
 import json
 from typing import Optional, Set, Tuple
 
@@ -10,26 +11,22 @@
 from frappe.model.meta import get_field_precision
 from frappe.query_builder import Case
 from frappe.query_builder.functions import CombineDatetime, Sum
-from frappe.utils import (
-	cint,
-	flt,
-	get_link_to_form,
-	getdate,
-	gzip_compress,
-	gzip_decompress,
-	now,
-	nowdate,
-	parse_json,
-)
+from frappe.utils import cint, flt, get_link_to_form, getdate, now, nowdate, nowtime, parse_json
 
 import erpnext
 from erpnext.stock.doctype.bin.bin import update_qty as update_bin_qty
+from erpnext.stock.doctype.inventory_dimension.inventory_dimension import get_inventory_dimensions
+from erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle import (
+	get_available_batches,
+)
 from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import (
-	get_sre_reserved_qty_for_item_and_warehouse as get_reserved_stock,
+	get_sre_reserved_batch_nos_details,
+	get_sre_reserved_serial_nos_details,
 )
 from erpnext.stock.utils import (
 	get_incoming_outgoing_rate_for_cancel,
 	get_or_make_bin,
+	get_stock_balance,
 	get_valuation_method,
 )
 from erpnext.stock.valuation import FIFOValuation, LIFOValuation, round_off_if_near_zero
@@ -96,6 +93,7 @@
 			is_stock_item = frappe.get_cached_value("Item", args.get("item_code"), "is_stock_item")
 			if is_stock_item:
 				bin_name = get_or_make_bin(args.get("item_code"), args.get("warehouse"))
+				args.reserved_stock = flt(frappe.db.get_value("Bin", bin_name, "reserved_stock"))
 				repost_current_voucher(args, allow_negative_stock, via_landed_cost_voucher)
 				update_bin_qty(bin_name, args)
 			else:
@@ -122,6 +120,7 @@
 					"voucher_no": args.get("voucher_no"),
 					"sle_id": args.get("name"),
 					"creation": args.get("creation"),
+					"reserved_stock": args.get("reserved_stock"),
 				},
 				allow_negative_stock=allow_negative_stock,
 				via_landed_cost_voucher=via_landed_cost_voucher,
@@ -211,6 +210,11 @@
 	sle.allow_negative_stock = allow_negative_stock
 	sle.via_landed_cost_voucher = via_landed_cost_voucher
 	sle.submit()
+
+	# Added to handle the case when the stock ledger entry is created from the repostig
+	if args.get("creation_time") and args.get("voucher_type") == "Stock Reconciliation":
+		sle.db_set("creation", args.get("creation_time"))
+
 	return sle
 
 
@@ -294,7 +298,7 @@
 
 	attached_file = frappe.get_doc("File", file_name)
 
-	data = gzip_decompress(attached_file.get_content())
+	data = gzip.decompress(attached_file.get_content())
 	if data := json.loads(data.decode("utf-8")):
 		data = data
 
@@ -377,7 +381,7 @@
 
 def create_json_gz_file(data, doc, file_name=None) -> str:
 	encoded_content = frappe.safe_encode(frappe.as_json(data))
-	compressed_content = gzip_compress(encoded_content)
+	compressed_content = gzip.compress(encoded_content)
 
 	if not file_name:
 		json_filename = f"{scrub(doc.doctype)}-{scrub(doc.name)}.json.gz"
@@ -514,7 +518,7 @@
 		self.new_items_found = False
 		self.distinct_item_warehouses = args.get("distinct_item_warehouses", frappe._dict())
 		self.affected_transactions: Set[Tuple[str, str]] = set()
-		self.reserved_stock = get_reserved_stock(self.args.item_code, self.args.warehouse)
+		self.reserved_stock = flt(self.args.reserved_stock)
 
 		self.data = frappe._dict()
 		self.initialize_previous_data(self.args)
@@ -697,9 +701,11 @@
 
 		if (
 			sle.voucher_type == "Stock Reconciliation"
-			and (sle.batch_no or (sle.has_batch_no and sle.serial_and_batch_bundle))
+			and (
+				sle.batch_no or (sle.has_batch_no and sle.serial_and_batch_bundle and not sle.has_serial_no)
+			)
 			and sle.voucher_detail_no
-			and sle.actual_qty < 0
+			and not self.args.get("sle_id")
 		):
 			self.reset_actual_qty_for_stock_reco(sle)
 
@@ -711,10 +717,17 @@
 		):
 			sle.outgoing_rate = get_incoming_rate_for_inter_company_transfer(sle)
 
+		dimensions = get_inventory_dimensions()
+		has_dimensions = False
+		if dimensions:
+			for dimension in dimensions:
+				if sle.get(dimension.get("fieldname")):
+					has_dimensions = True
+
 		if sle.serial_and_batch_bundle:
 			self.calculate_valuation_for_serial_batch_bundle(sle)
 		else:
-			if sle.voucher_type == "Stock Reconciliation" and not sle.batch_no:
+			if sle.voucher_type == "Stock Reconciliation" and not sle.batch_no and not has_dimensions:
 				# assert
 				self.wh_data.valuation_rate = sle.valuation_rate
 				self.wh_data.qty_after_transaction = sle.qty_after_transaction
@@ -755,27 +768,22 @@
 			self.update_outgoing_rate_on_transaction(sle)
 
 	def reset_actual_qty_for_stock_reco(self, sle):
-		if sle.serial_and_batch_bundle:
-			current_qty = frappe.get_cached_value(
-				"Serial and Batch Bundle", sle.serial_and_batch_bundle, "total_qty"
+		doc = frappe.get_cached_doc("Stock Reconciliation", sle.voucher_no)
+		doc.recalculate_current_qty(sle.voucher_detail_no, sle.creation, sle.actual_qty > 0)
+
+		if sle.actual_qty < 0:
+			sle.actual_qty = (
+				flt(frappe.db.get_value("Stock Reconciliation Item", sle.voucher_detail_no, "current_qty"))
+				* -1
 			)
 
-			if current_qty is not None:
-				current_qty = abs(current_qty)
-		else:
-			current_qty = frappe.get_cached_value(
-				"Stock Reconciliation Item", sle.voucher_detail_no, "current_qty"
-			)
-
-		if current_qty:
-			sle.actual_qty = current_qty * -1
-		elif current_qty == 0:
-			sle.is_cancelled = 1
+			if abs(sle.actual_qty) == 0.0:
+				sle.is_cancelled = 1
 
 	def calculate_valuation_for_serial_batch_bundle(self, sle):
 		doc = frappe.get_cached_doc("Serial and Batch Bundle", sle.serial_and_batch_bundle)
 
-		doc.set_incoming_rate(save=True)
+		doc.set_incoming_rate(save=True, allow_negative_stock=self.allow_negative_stock)
 		doc.calculate_qty_and_amount(save=True)
 
 		self.wh_data.stock_value = round_off_if_near_zero(self.wh_data.stock_value + doc.total_amount)
@@ -1297,7 +1305,7 @@
 	return sle[0] if sle else frappe._dict()
 
 
-def get_previous_sle(args, for_update=False):
+def get_previous_sle(args, for_update=False, extra_cond=None):
 	"""
 	get the last sle on or before the current time-bucket,
 	to get actual qty before transaction, this function
@@ -1312,7 +1320,9 @@
 	}
 	"""
 	args["name"] = args.get("sle", None) or ""
-	sle = get_stock_ledger_entries(args, "<=", "desc", "limit 1", for_update=for_update)
+	sle = get_stock_ledger_entries(
+		args, "<=", "desc", "limit 1", for_update=for_update, extra_cond=extra_cond
+	)
 	return sle and sle[0] or {}
 
 
@@ -1324,6 +1334,7 @@
 	for_update=False,
 	debug=False,
 	check_serial_no=True,
+	extra_cond=None,
 ):
 	"""get stock ledger entries filtered by specific posting datetime conditions"""
 	conditions = " and timestamp(posting_date, posting_time) {0} timestamp(%(posting_date)s, %(posting_time)s)".format(
@@ -1361,6 +1372,9 @@
 	if operator in (">", "<=") and previous_sle.get("name"):
 		conditions += " and name!=%(name)s"
 
+	if extra_cond:
+		conditions += f"{extra_cond}"
+
 	return frappe.db.sql(
 		"""
 		select *, timestamp(posting_date, posting_time) as "timestamp"
@@ -1456,6 +1470,7 @@
 	currency=None,
 	company=None,
 	raise_error_if_no_rate=True,
+	batch_no=None,
 	serial_and_batch_bundle=None,
 ):
 
@@ -1464,7 +1479,24 @@
 	if not company:
 		company = frappe.get_cached_value("Warehouse", warehouse, "company")
 
-	last_valuation_rate = None
+	if warehouse and batch_no and frappe.db.get_value("Batch", batch_no, "use_batchwise_valuation"):
+		table = frappe.qb.DocType("Stock Ledger Entry")
+		query = (
+			frappe.qb.from_(table)
+			.select(Sum(table.stock_value_difference) / Sum(table.actual_qty))
+			.where(
+				(table.item_code == item_code)
+				& (table.warehouse == warehouse)
+				& (table.batch_no == batch_no)
+				& (table.is_cancelled == 0)
+				& (table.voucher_no != voucher_no)
+				& (table.voucher_type != voucher_type)
+			)
+		)
+
+		last_valuation_rate = query.run()
+		if last_valuation_rate:
+			return flt(last_valuation_rate[0][0])
 
 	# Get moving average rate of a specific batch number
 	if warehouse and serial_and_batch_bundle:
@@ -1482,21 +1514,18 @@
 		return batch_obj.get_incoming_rate()
 
 	# Get valuation rate from last sle for the same item and warehouse
-	if not last_valuation_rate or last_valuation_rate[0][0] is None:
-		last_valuation_rate = frappe.db.sql(
-			"""select valuation_rate
-			from `tabStock Ledger Entry` force index (item_warehouse)
-			where
-				item_code = %s
-				AND warehouse = %s
-				AND valuation_rate >= 0
-				AND is_cancelled = 0
-				AND NOT (voucher_no = %s AND voucher_type = %s)
-			order by posting_date desc, posting_time desc, name desc limit 1""",
-			(item_code, warehouse, voucher_no, voucher_type),
-		)
-
-	if last_valuation_rate:
+	if last_valuation_rate := frappe.db.sql(
+		"""select valuation_rate
+		from `tabStock Ledger Entry` force index (item_warehouse)
+		where
+			item_code = %s
+			AND warehouse = %s
+			AND valuation_rate >= 0
+			AND is_cancelled = 0
+			AND NOT (voucher_no = %s AND voucher_type = %s)
+		order by posting_date desc, posting_time desc, name desc limit 1""",
+		(item_code, warehouse, voucher_no, voucher_type),
+	):
 		return flt(last_valuation_rate[0][0])
 
 	# If negative stock allowed, and item delivered without any incoming entry,
@@ -1563,8 +1592,6 @@
 	next_stock_reco_detail = get_next_stock_reco(args)
 	if next_stock_reco_detail:
 		detail = next_stock_reco_detail[0]
-		if detail.batch_no or (detail.serial_and_batch_bundle and detail.has_batch_no):
-			regenerate_sle_for_batch_stock_reco(detail)
 
 		# add condition to update SLEs before this date & time
 		datetime_limit_condition = get_datetime_limit_condition(detail)
@@ -1593,16 +1620,6 @@
 	validate_negative_qty_in_future_sle(args, allow_negative_stock)
 
 
-def regenerate_sle_for_batch_stock_reco(detail):
-	doc = frappe.get_cached_doc("Stock Reconciliation", detail.voucher_no)
-	doc.recalculate_current_qty(detail.item_code, detail.batch_no)
-
-	if not frappe.db.exists(
-		"Repost Item Valuation", {"voucher_no": doc.name, "status": "Queued", "docstatus": "1"}
-	):
-		doc.repost_future_sle_and_gle(force=True)
-
-
 def get_stock_reco_qty_shift(args):
 	stock_reco_qty_shift = 0
 	if args.get("is_cancelled"):
@@ -1709,22 +1726,23 @@
 
 		frappe.throw(message, NegativeStockError, title=_("Insufficient Stock"))
 
-	if not args.batch_no:
-		return
+	if args.batch_no:
+		neg_batch_sle = get_future_sle_with_negative_batch_qty(args)
+		if is_negative_with_precision(neg_batch_sle, is_batch=True):
+			message = _(
+				"{0} units of {1} needed in {2} on {3} {4} for {5} to complete this transaction."
+			).format(
+				abs(neg_batch_sle[0]["cumulative_total"]),
+				frappe.get_desk_link("Batch", args.batch_no),
+				frappe.get_desk_link("Warehouse", args.warehouse),
+				neg_batch_sle[0]["posting_date"],
+				neg_batch_sle[0]["posting_time"],
+				frappe.get_desk_link(neg_batch_sle[0]["voucher_type"], neg_batch_sle[0]["voucher_no"]),
+			)
+			frappe.throw(message, NegativeStockError, title=_("Insufficient Stock for Batch"))
 
-	neg_batch_sle = get_future_sle_with_negative_batch_qty(args)
-	if is_negative_with_precision(neg_batch_sle, is_batch=True):
-		message = _(
-			"{0} units of {1} needed in {2} on {3} {4} for {5} to complete this transaction."
-		).format(
-			abs(neg_batch_sle[0]["cumulative_total"]),
-			frappe.get_desk_link("Batch", args.batch_no),
-			frappe.get_desk_link("Warehouse", args.warehouse),
-			neg_batch_sle[0]["posting_date"],
-			neg_batch_sle[0]["posting_time"],
-			frappe.get_desk_link(neg_batch_sle[0]["voucher_type"], neg_batch_sle[0]["voucher_no"]),
-		)
-		frappe.throw(message, NegativeStockError, title=_("Insufficient Stock for Batch"))
+	if args.reserved_stock:
+		validate_reserved_stock(args)
 
 
 def is_negative_with_precision(neg_sle, is_batch=False):
@@ -1791,6 +1809,96 @@
 	)
 
 
+def validate_reserved_stock(kwargs):
+	if kwargs.serial_no:
+		serial_nos = kwargs.serial_no.split("\n")
+		validate_reserved_serial_nos(kwargs.item_code, kwargs.warehouse, serial_nos)
+
+	elif kwargs.batch_no:
+		validate_reserved_batch_nos(kwargs.item_code, kwargs.warehouse, [kwargs.batch_no])
+
+	elif kwargs.serial_and_batch_bundle:
+		sbb_entries = frappe.db.get_all(
+			"Serial and Batch Entry",
+			{
+				"parenttype": "Serial and Batch Bundle",
+				"parent": kwargs.serial_and_batch_bundle,
+				"docstatus": 1,
+			},
+			["batch_no", "serial_no"],
+		)
+
+		if serial_nos := [entry.serial_no for entry in sbb_entries if entry.serial_no]:
+			validate_reserved_serial_nos(kwargs.item_code, kwargs.warehouse, serial_nos)
+		elif batch_nos := [entry.batch_no for entry in sbb_entries if entry.batch_no]:
+			validate_reserved_batch_nos(kwargs.item_code, kwargs.warehouse, batch_nos)
+
+	# Qty based validation for non-serial-batch items OR SRE with Reservation Based On Qty.
+	precision = cint(frappe.db.get_default("float_precision")) or 2
+	balance_qty = get_stock_balance(kwargs.item_code, kwargs.warehouse)
+
+	diff = flt(balance_qty - kwargs.get("reserved_stock", 0), precision)
+	if diff < 0 and abs(diff) > 0.0001:
+		msg = _("{0} units of {1} needed in {2} on {3} {4} to complete this transaction.").format(
+			abs(diff),
+			frappe.get_desk_link("Item", kwargs.item_code),
+			frappe.get_desk_link("Warehouse", kwargs.warehouse),
+			nowdate(),
+			nowtime(),
+		)
+		frappe.throw(msg, title=_("Reserved Stock"))
+
+
+def validate_reserved_serial_nos(item_code, warehouse, serial_nos):
+	if reserved_serial_nos_details := get_sre_reserved_serial_nos_details(
+		item_code, warehouse, serial_nos
+	):
+		if common_serial_nos := list(
+			set(serial_nos).intersection(set(reserved_serial_nos_details.keys()))
+		):
+			msg = _(
+				"Serial Nos are reserved in Stock Reservation Entries, you need to unreserve them before proceeding."
+			)
+			msg += "<br />"
+			msg += _("Example: Serial No {0} reserved in {1}.").format(
+				frappe.bold(common_serial_nos[0]),
+				frappe.get_desk_link(
+					"Stock Reservation Entry", reserved_serial_nos_details[common_serial_nos[0]]
+				),
+			)
+			frappe.throw(msg, title=_("Reserved Serial No."))
+
+
+def validate_reserved_batch_nos(item_code, warehouse, batch_nos):
+	if reserved_batches_map := get_sre_reserved_batch_nos_details(item_code, warehouse, batch_nos):
+		available_batches = get_available_batches(
+			frappe._dict(
+				{
+					"item_code": item_code,
+					"warehouse": warehouse,
+					"posting_date": nowdate(),
+					"posting_time": nowtime(),
+				}
+			)
+		)
+		available_batches_map = {row.batch_no: row.qty for row in available_batches}
+		precision = cint(frappe.db.get_default("float_precision")) or 2
+
+		for batch_no in batch_nos:
+			diff = flt(
+				available_batches_map.get(batch_no, 0) - reserved_batches_map.get(batch_no, 0), precision
+			)
+			if diff < 0 and abs(diff) > 0.0001:
+				msg = _("{0} units of {1} needed in {2} on {3} {4} to complete this transaction.").format(
+					abs(diff),
+					frappe.get_desk_link("Batch", batch_no),
+					frappe.get_desk_link("Warehouse", warehouse),
+					nowdate(),
+					nowtime(),
+				)
+				frappe.throw(msg, title=_("Reserved Stock for Batch"))
+
+
 def is_negative_stock_allowed(*, item_code: Optional[str] = None) -> bool:
 	if cint(frappe.db.get_single_value("Stock Settings", "allow_negative_stock", cache=True)):
 		return True
diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py
index 0244406..bd0d469 100644
--- a/erpnext/stock/utils.py
+++ b/erpnext/stock/utils.py
@@ -95,6 +95,7 @@
 	posting_time=None,
 	with_valuation_rate=False,
 	with_serial_no=False,
+	inventory_dimensions_dict=None,
 ):
 	"""Returns stock balance quantity at given warehouse on given posting date or current date.
 
@@ -114,7 +115,13 @@
 		"posting_time": posting_time,
 	}
 
-	last_entry = get_previous_sle(args)
+	extra_cond = ""
+	if inventory_dimensions_dict:
+		for field, value in inventory_dimensions_dict.items():
+			args[field] = value
+			extra_cond += f" and {field} = %({field})s"
+
+	last_entry = get_previous_sle(args, extra_cond=extra_cond)
 
 	if with_valuation_rate:
 		if with_serial_no:
diff --git a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js
index f2b395a..587a3b4 100644
--- a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js
+++ b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js
@@ -107,7 +107,7 @@
 	get_materials_from_supplier: function (frm) {
 		let sco_rm_details = [];
 
-		if (frm.doc.status != "Closed" && frm.doc.supplied_items && frm.doc.per_received > 0) {
+		if (frm.doc.status != "Closed" && frm.doc.supplied_items) {
 			frm.doc.supplied_items.forEach(d => {
 				if (d.total_supplied_qty > 0 && d.total_supplied_qty != d.consumed_qty) {
 					sco_rm_details.push(d.name);
@@ -193,7 +193,7 @@
 	}
 
 	has_unsupplied_items() {
-		return this.frm.doc['supplied_items'].some(item => item.required_qty > item.supplied_qty);
+		return this.frm.doc['supplied_items'].some(item => item.required_qty > (item.supplied_qty - item.returned_qty));
 	}
 
 	make_subcontracting_receipt() {
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
index 6aecaf9..7e06444 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
@@ -410,7 +410,6 @@
 
 	def make_item_gl_entries(self, gl_entries, warehouse_account=None):
 		stock_rbnb = self.get_company_default("stock_received_but_not_billed")
-		expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
 
 		warehouse_with_no_account = []
 
@@ -482,10 +481,7 @@
 					divisional_loss = flt(item.amount - stock_value_diff, item.precision("amount"))
 
 					if divisional_loss:
-						if self.is_return:
-							loss_account = expenses_included_in_valuation
-						else:
-							loss_account = item.expense_account
+						loss_account = item.expense_account
 
 						self.add_gl_entry(
 							gl_entries=gl_entries,
diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js
index d4daacd..f96823b 100644
--- a/erpnext/support/doctype/issue/issue.js
+++ b/erpnext/support/doctype/issue/issue.js
@@ -1,13 +1,6 @@
 frappe.ui.form.on("Issue", {
 	onload: function(frm) {
 		frm.email_field = "raised_by";
-		frm.set_query("customer", function () {
-			return {
-				filters: {
-					"disabled": 0
-				}
-			};
-		});
 
 		frappe.db.get_value("Support Settings", {name: "Support Settings"},
 			["allow_resetting_service_level_agreement", "track_service_level_agreement"], (r) => {
diff --git a/erpnext/templates/generators/item/item.html b/erpnext/templates/generators/item/item.html
deleted file mode 100644
index 358c1c5..0000000
--- a/erpnext/templates/generators/item/item.html
+++ /dev/null
@@ -1,80 +0,0 @@
-{% extends "templates/web.html" %}
-{% from "erpnext/templates/includes/macros.html" import recommended_item_row %}
-
-{% block title %} {{ title }} {% endblock %}
-
-{% block breadcrumbs %}
-<div class="item-breadcrumbs small text-muted">
-	{% include "templates/includes/breadcrumbs.html" %}
-</div>
-{% endblock %}
-
-{% block page_content %}
-<div class="product-container item-main">
-	{% from "erpnext/templates/includes/macros.html" import product_image %}
-	<div class="item-content">
-		<div class="product-page-content" itemscope itemtype="http://schema.org/Product">
-			<!-- Image, Description, Add to Cart -->
-			<div class="row mb-5">
-				{% include "templates/generators/item/item_image.html" %}
-				{% include "templates/generators/item/item_details.html" %}
-			</div>
-		</div>
-	</div>
-</div>
-
-<!-- Additional Info/Reviews, Recommendations -->
-<div class="d-flex">
-	{% set show_recommended_items = recommended_items and shopping_cart.cart_settings.enable_recommendations %}
-	{% set info_col = 'col-9' if show_recommended_items else 'col-12' %}
-
-	{% set padding_top = 'pt-0' if (show_tabs and tabs) else '' %}
-
-	<div class="product-container mt-4 {{ padding_top }} {{ info_col }}">
-		<div class="item-content {{ 'mt-minus-2' if (show_tabs and tabs) else '' }}">
-			<div class="product-page-content">
-				<!-- Product Specifications Table Section -->
-				{% if show_tabs and tabs %}
-					<div class="category-tabs">
-						<!-- tabs -->
-							{{ web_block("Section with Tabs", values=tabs, add_container=0,
-								add_top_padding=0, add_bottom_padding=0)
-							}}
-					</div>
-				{% elif website_specifications %}
-					{% include "templates/generators/item/item_specifications.html"%}
-				{% endif %}
-
-				<!-- Advanced Custom Website Content -->
-				{{ doc.website_content or '' }}
-
-				<!-- Reviews and Comments -->
-				{% if shopping_cart.cart_settings.enable_reviews and not doc.has_variants %}
-					{% include "templates/generators/item/item_reviews.html"%}
-				{% endif %}
-			</div>
-		</div>
-	</div>
-
-	<!-- Recommended Items -->
-	{% if show_recommended_items %}
-		<div class="mt-4 col-3 recommended-item-section">
-			<span class="recommendation-header">Recommended</span>
-			<div class="product-container mt-2 recommendation-container">
-				{% for item in recommended_items %}
-					{{ recommended_item_row(item) }}
-				{% endfor %}
-			</div>
-		</div>
-	{% endif %}
-
-</div>
-{% endblock %}
-
-{% block base_scripts %}
-<!-- js should be loaded in body! -->
-<script type="text/javascript" src="/assets/frappe/js/lib/jquery/jquery.min.js"></script>
-{{ include_script("frappe-web.bundle.js") }}
-{{ include_script("controls.bundle.js") }}
-{{ include_script("dialog.bundle.js") }}
-{% endblock %}
diff --git a/erpnext/templates/generators/item/item_add_to_cart.html b/erpnext/templates/generators/item/item_add_to_cart.html
deleted file mode 100644
index 9bd3f75..0000000
--- a/erpnext/templates/generators/item/item_add_to_cart.html
+++ /dev/null
@@ -1,180 +0,0 @@
-{% if shopping_cart and shopping_cart.cart_settings.enabled %}
-
-{% set cart_settings = shopping_cart.cart_settings %}
-{% set product_info = shopping_cart.product_info %}
-
-<div class="item-cart row mt-2" data-variant-item-code="{{ item_code }}">
-	<div class="col-md-12">
-		<!-- Price and Availability -->
-		{% if cart_settings.show_price and product_info.price %}
-			{% set price_info = product_info.price %}
-
-			<div class="product-price">
-				<!-- Final Price -->
-				<span itemprop="offers" itemscope itemtype="https://schema.org/Offer">
-					<span itemprop="price" content="{{ price_info.price_list_rate }}">{{ price_info.formatted_price_sales_uom }}</span>
-					<span style="display:none;" itemprop="priceCurrency" content="{{ price_info.currency }}">{{ price_info.currency }}</span>
-				</span>
-
-				<!-- Striked Price and Discount  -->
-				{% if price_info.formatted_mrp %}
-					<small class="formatted-price">
-						<s>MRP {{ price_info.formatted_mrp }}</s>
-					</small>
-					<small class="ml-1 formatted-price in-green">
-						-{{ price_info.get("formatted_discount_percent") or price_info.get("formatted_discount_rate")}}
-					</small>
-				{% endif %}
-
-				<!-- Price per UOM -->
-				<small class="formatted-price ml-2">
-					({{ price_info.formatted_price }} / {{ product_info.uom }})
-				</small>
-			</div>
-		{% else %}
-			{{ _("UOM") }} : {{ product_info.uom }}
-		{% endif %}
-
-		{% if cart_settings.show_stock_availability %}
-		<div class="mt-2">
-			{% if product_info.get("on_backorder") %}
-				<span class="no-stock out-of-stock" style="color: var(--primary-color);">
-					{{ _('Available on backorder') }}
-				</span>
-			{% elif product_info.in_stock == 0 %}
-				<span class="no-stock out-of-stock">
-					{{ _('Out of stock') }}
-				</span>
-			{% elif product_info.in_stock == 1 %}
-				<span class="in-green has-stock">
-					{{ _('In stock') }}
-					{% if product_info.show_stock_qty and product_info.stock_qty %}
-						({{ product_info.stock_qty }})
-					{% endif %}
-				</span>
-			{% endif %}
-		</div>
-		{% endif %}
-
-		<!-- Offers -->
-		{% if doc.offers %}
-			<br>
-			<div class="offers-heading mb-4">
-				<span class="mr-1 tag-icon">
-					<svg class="icon icon-lg"><use href="#icon-tag"></use></svg>
-				</span>
-				<b>Available Offers</b>
-			</div>
-			<div class="offer-container">
-				{% for offer in doc.offers %}
-				<div class="mt-2 d-flex">
-					<div class="mr-2" >
-						<svg width="24" height="24" viewBox="0 0 24 24" stroke="var(--yellow-500)" fill="none" xmlns="http://www.w3.org/2000/svg">
-							<path d="M19 15.6213C19 15.2235 19.158 14.842 19.4393 14.5607L20.9393 13.0607C21.5251 12.4749 21.5251 11.5251 20.9393 10.9393L19.4393 9.43934C19.158 9.15804 19 8.7765 19 8.37868V6.5C19 5.67157 18.3284 5 17.5 5H15.6213C15.2235 5 14.842 4.84196 14.5607 4.56066L13.0607 3.06066C12.4749 2.47487 11.5251 2.47487 10.9393 3.06066L9.43934 4.56066C9.15804 4.84196 8.7765 5 8.37868 5H6.5C5.67157 5 5 5.67157 5 6.5V8.37868C5 8.7765 4.84196 9.15804 4.56066 9.43934L3.06066 10.9393C2.47487 11.5251 2.47487 12.4749 3.06066 13.0607L4.56066 14.5607C4.84196 14.842 5 15.2235 5 15.6213V17.5C5 18.3284 5.67157 19 6.5 19H8.37868C8.7765 19 9.15804 19.158 9.43934 19.4393L10.9393 20.9393C11.5251 21.5251 12.4749 21.5251 13.0607 20.9393L14.5607 19.4393C14.842 19.158 15.2235 19 15.6213 19H17.5C18.3284 19 19 18.3284 19 17.5V15.6213Z" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
-							<path d="M15 9L9 15" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
-							<path d="M10.5 9.5C10.5 10.0523 10.0523 10.5 9.5 10.5C8.94772 10.5 8.5 10.0523 8.5 9.5C8.5 8.94772 8.94772 8.5 9.5 8.5C10.0523 8.5 10.5 8.94772 10.5 9.5Z" fill="white" stroke-linecap="round" stroke-linejoin="round"/>
-							<path d="M15.5 14.5C15.5 15.0523 15.0523 15.5 14.5 15.5C13.9477 15.5 13.5 15.0523 13.5 14.5C13.5 13.9477 13.9477 13.5 14.5 13.5C15.0523 13.5 15.5 13.9477 15.5 14.5Z" fill="white" stroke-linecap="round" stroke-linejoin="round"/>
-						</svg>
-					</div>
-					<p class="mr-1 mb-1">
-						{{ _(offer.offer_title) }}:
-						{{ _(offer.offer_subtitle) if offer.offer_subtitle else '' }}
-						<a class="offer-details" href="#"
-							data-offer-title="{{ offer.offer_title }}" data-offer-id="{{ offer.name }}"
-							role="button">
-							{{ _("More") }}
-						</a>
-					</p>
-				</div>
-				{% endfor %}
-			</div>
-		{% endif %}
-
-		<!-- Add to Cart / View in Cart, Contact Us -->
-		<div class="mt-6 mb-5">
-			<div class="mb-4 d-flex">
-				<!-- Add to Cart -->
-				{% if product_info.price and (cart_settings.allow_items_not_in_stock or product_info.in_stock) %}
-					<a href="/cart" class="btn btn-light btn-view-in-cart hidden mr-2 font-md"
-						role="button">
-						{{  _("View in Cart") if cart_settings.enable_checkout else _("View in Quote") }}
-					</a>
-					<button
-						data-item-code="{{item_code}}"
-						class="btn btn-primary btn-add-to-cart mr-2 w-30-40"
-					>
-						<span class="mr-2">
-							<svg class="icon icon-md">
-								<use href="#icon-assets"></use>
-							</svg>
-						</span>
-						{{ _("Add to Cart") if cart_settings.enable_checkout else  _("Add to Quote") }}
-					</button>
-				{% endif %}
-
-				<!-- Contact Us -->
-				{% if cart_settings.show_contact_us_button %}
-					{% include "templates/generators/item/item_inquiry.html" %}
-				{% endif %}
-			</div>
-		</div>
-	</div>
-</div>
-
-<script>
-	frappe.ready(() => {
-		$('.page_content').on('click', '.btn-add-to-cart', (e) => {
-			// Bind action on add to cart button
-			const $btn = $(e.currentTarget);
-			$btn.prop('disabled', true);
-			const item_code = $btn.data('item-code');
-			erpnext.e_commerce.shopping_cart.update_cart({
-				item_code,
-				qty: 1,
-				callback(r) {
-					$btn.prop('disabled', false);
-					if (r.message) {
-						$('.btn-add-to-cart, .btn-view-in-cart').toggleClass('hidden');
-					}
-				}
-			});
-		});
-
-		$('.page_content').on('click', '.offer-details', (e) => {
-			// Bind action on More link in Offers
-			const $btn = $(e.currentTarget);
-			$btn.prop('disabled', true);
-
-			var d = new frappe.ui.Dialog({
-				title: __($btn.data('offer-title')),
-				fields: [
-					{
-						fieldname: 'offer_details',
-						fieldtype: 'HTML'
-					},
-					{
-						fieldname: 'section_break',
-						fieldtype: 'Section Break'
-					}
-				]
-			});
-
-			frappe.call({
-				method: 'erpnext.e_commerce.doctype.website_offer.website_offer.get_offer_details',
-				args: {
-					offer_id: $btn.data('offer-id')
-				},
-				callback: (value) => {
-					d.set_value("offer_details", value.message);
-					d.show();
-					$btn.prop('disabled', false);
-				}
-			})
-
-		});
-	});
-
-
-</script>
-
-{% endif %}
diff --git a/erpnext/templates/generators/item/item_configure.html b/erpnext/templates/generators/item/item_configure.html
deleted file mode 100644
index e97a275..0000000
--- a/erpnext/templates/generators/item/item_configure.html
+++ /dev/null
@@ -1,20 +0,0 @@
-{% if shopping_cart and shopping_cart.cart_settings.enabled %}
-{% set cart_settings = shopping_cart.cart_settings %}
-
-<div class="mt-5 mb-6">
-	{% if cart_settings.enable_variants | int %}
-	<button class="btn btn-primary-light btn-configure font-md mr-2"
-		data-item-code="{{ doc.item_code }}"
-		data-item-name="{{ doc.web_item_name }}"
-	>
-		{{ _('Select Variant') }}
-	</button>
-	{% endif %}
-	{% if cart_settings.show_contact_us_button %}
-		{% include "templates/generators/item/item_inquiry.html" %}
-	{% endif %}
-</div>
-<script>
-{% include "templates/generators/item/item_configure.js" %}
-</script>
-{% endif %}
diff --git a/erpnext/templates/generators/item/item_configure.js b/erpnext/templates/generators/item/item_configure.js
deleted file mode 100644
index 9beba3f..0000000
--- a/erpnext/templates/generators/item/item_configure.js
+++ /dev/null
@@ -1,343 +0,0 @@
-class ItemConfigure {
-	constructor(item_code, item_name) {
-		this.item_code = item_code;
-		this.item_name = item_name;
-
-		this.get_attributes_and_values()
-			.then(attribute_data => {
-				this.attribute_data = attribute_data;
-				this.show_configure_dialog();
-			});
-	}
-
-	show_configure_dialog() {
-		const fields = this.attribute_data.map(a => {
-			return {
-				fieldtype: 'Select',
-				label: a.attribute,
-				fieldname: a.attribute,
-				options: a.values.map(v => {
-					return {
-						label: v,
-						value: v
-					};
-				}),
-				change: (e) => {
-					this.on_attribute_selection(e);
-				}
-			};
-		});
-
-		this.dialog = new frappe.ui.Dialog({
-			title: __('Select Variant for {0}', [this.item_name]),
-			fields,
-			on_hide: () => {
-				set_continue_configuration();
-			}
-		});
-
-		this.attribute_data.forEach(a => {
-			const field = this.dialog.get_field(a.attribute);
-			const $a = $(`<a href>${__("Clear")}</a>`);
-			$a.on('click', (e) => {
-				e.preventDefault();
-				this.dialog.set_value(a.attribute, '');
-			});
-			field.$wrapper.find('.help-box').append($a);
-		});
-
-		this.append_status_area();
-		this.dialog.show();
-
-		this.dialog.set_values(JSON.parse(localStorage.getItem(this.get_cache_key())));
-
-		$('.btn-configure').prop('disabled', false);
-	}
-
-	on_attribute_selection(e) {
-		if (e) {
-			const changed_fieldname = $(e.target).data('fieldname');
-			this.show_range_input_if_applicable(changed_fieldname);
-		} else {
-			this.show_range_input_for_all_fields();
-		}
-
-		const values = this.dialog.get_values();
-		if (Object.keys(values).length === 0) {
-			this.clear_status();
-			localStorage.removeItem(this.get_cache_key());
-			return;
-		}
-
-		// save state
-		localStorage.setItem(this.get_cache_key(), JSON.stringify(values));
-
-		// show
-		this.set_loading_status();
-
-		this.get_next_attribute_and_values(values)
-			.then(data => {
-				const {
-					valid_options_for_attributes,
-				} = data;
-
-				this.set_item_found_status(data);
-
-				for (let attribute in valid_options_for_attributes) {
-					const valid_options = valid_options_for_attributes[attribute];
-					const options = this.dialog.get_field(attribute).df.options;
-					const new_options = options.map(o => {
-						o.disabled = !valid_options.includes(o.value);
-						return o;
-					});
-
-					this.dialog.set_df_property(attribute, 'options', new_options);
-					this.dialog.get_field(attribute).set_options();
-				}
-			});
-	}
-
-	show_range_input_for_all_fields() {
-		this.dialog.fields.forEach(f => {
-			this.show_range_input_if_applicable(f.fieldname);
-		});
-	}
-
-	show_range_input_if_applicable(fieldname) {
-		const changed_field = this.dialog.get_field(fieldname);
-		const changed_value = changed_field.get_value();
-		if (changed_value && changed_value.includes(' to ')) {
-			// possible range input
-			let numbers = changed_value.split(' to ');
-			numbers = numbers.map(number => parseFloat(number));
-
-			if (!numbers.some(n => isNaN(n))) {
-				numbers.sort((a, b) => a - b);
-				if (changed_field.$input_wrapper.find('.range-selector').length) {
-					return;
-				}
-				const parent = $('<div class="range-selector">')
-					.insertBefore(changed_field.$input_wrapper.find('.help-box'));
-				const control = frappe.ui.form.make_control({
-					df: {
-						fieldtype: 'Int',
-						label: __('Enter value betweeen {0} and {1}', [numbers[0], numbers[1]]),
-						change: () => {
-							const value = control.get_value();
-							if (value < numbers[0] || value > numbers[1]) {
-								control.$wrapper.addClass('was-validated');
-								control.set_description(
-									__('Value must be between {0} and {1}', [numbers[0], numbers[1]]));
-								control.$input[0].setCustomValidity('error');
-							} else {
-								control.$wrapper.removeClass('was-validated');
-								control.set_description('');
-								control.$input[0].setCustomValidity('');
-								this.update_range_values(fieldname, value);
-							}
-						}
-					},
-					render_input: true,
-					parent
-				});
-				control.$wrapper.addClass('mt-3');
-			}
-		}
-	}
-
-	update_range_values(attribute, range_value) {
-		this.range_values = this.range_values || {};
-		this.range_values[attribute] = range_value;
-	}
-
-	show_remaining_optional_attributes() {
-		// show all attributes if remaining
-		// unselected attributes are all optional
-		const unselected_attributes = this.dialog.fields.filter(df => {
-			const value_selected = this.dialog.get_value(df.fieldname);
-			return !value_selected;
-		});
-		const is_optional_attribute = df => {
-			const optional_attributes = this.attribute_data
-				.filter(a => a.optional).map(a => a.attribute);
-			return optional_attributes.includes(df.fieldname);
-		};
-		if (unselected_attributes.every(is_optional_attribute)) {
-			unselected_attributes.forEach(df => {
-				this.dialog.fields_dict[df.fieldname].$wrapper.show();
-			});
-		}
-	}
-
-	set_loading_status() {
-		this.dialog.$status_area.html(`
-			<div class="alert alert-warning d-flex justify-content-between align-items-center" role="alert">
-				${__('Loading...')}
-			</div>
-		`);
-	}
-
-	set_item_found_status(data) {
-		const html = this.get_html_for_item_found(data);
-		this.dialog.$status_area.html(html);
-	}
-
-	clear_status() {
-		this.dialog.$status_area.empty();
-	}
-
-	get_html_for_item_found({ filtered_items_count, filtered_items, exact_match, product_info, available_qty, settings }) {
-		const one_item = exact_match.length === 1
-			? exact_match[0]
-			: filtered_items_count === 1
-				? filtered_items[0]
-				: '';
-
-		let item_add_to_cart = one_item ? `
-			<button data-item-code="${one_item}"
-				class="btn btn-primary btn-add-to-cart w-100"
-				data-action="btn_add_to_cart"
-			>
-				<span class="mr-2">
-					${frappe.utils.icon('assets', 'md')}
-				</span>
-				${__("Add to Cart")}
-			</button>
-		` : '';
-
-		const items_found = filtered_items_count === 1 ?
-			__('{0} item found.', [filtered_items_count]) :
-			__('{0} items found.', [filtered_items_count]);
-
-		/* eslint-disable indent */
-		const item_found_status = exact_match.length === 1
-			? `<div class="alert alert-success d-flex justify-content-between align-items-center" role="alert">
-				<div><div>
-					${one_item}
-					${product_info && product_info.price && !$.isEmptyObject(product_info.price)
-						? '(' + product_info.price.formatted_price_sales_uom + ')'
-						: ''
-					}
-
-					${available_qty === 0 && product_info && product_info?.is_stock_item
-						? '<span class="text-danger">(' + __('Out of Stock') + ')</span>' : ''}
-
-				</div></div>
-				<a href data-action="btn_clear_values" data-item-code="${one_item}">
-					${__('Clear Values')}
-				</a>
-			</div>`
-			: `<div class="alert alert-warning d-flex justify-content-between align-items-center" role="alert">
-					<span>
-						${items_found}
-					</span>
-					<a href data-action="btn_clear_values">
-						${__('Clear values')}
-					</a>
-			</div>`;
-		/* eslint-disable indent */
-
-		if (!product_info?.allow_items_not_in_stock && available_qty === 0
-			&& product_info && product_info?.is_stock_item) {
-			item_add_to_cart = '';
-		}
-
-		return `
-			${item_found_status}
-			${item_add_to_cart}
-		`;
-	}
-
-	btn_add_to_cart(e) {
-		if (frappe.session.user !== 'Guest') {
-			localStorage.removeItem(this.get_cache_key());
-		}
-		const item_code = $(e.currentTarget).data('item-code');
-		const additional_notes = Object.keys(this.range_values || {}).map(attribute => {
-			return `${attribute}: ${this.range_values[attribute]}`;
-		}).join('\n');
-		erpnext.e_commerce.shopping_cart.update_cart({
-			item_code,
-			additional_notes,
-			qty: 1
-		});
-		this.dialog.hide();
-	}
-
-	btn_clear_values() {
-		this.dialog.fields_list.forEach(f => {
-			if (f.df?.options) {
-				f.df.options = f.df.options.map(option => {
-					option.disabled = false;
-					return option;
-				});
-			}
-		});
-		this.dialog.clear();
-		this.dialog.$status_area.empty();
-		this.on_attribute_selection();
-	}
-
-	append_status_area() {
-		this.dialog.$status_area = $('<div class="status-area mt-5">');
-		this.dialog.$wrapper.find('.modal-body').append(this.dialog.$status_area);
-		this.dialog.$wrapper.on('click', '[data-action]', (e) => {
-			e.preventDefault();
-			const $target = $(e.currentTarget);
-			const action = $target.data('action');
-			const method = this[action];
-			method.call(this, e);
-		});
-		this.dialog.$wrapper.addClass('item-configurator-dialog');
-	}
-
-	get_next_attribute_and_values(selected_attributes) {
-		return this.call('erpnext.e_commerce.variant_selector.utils.get_next_attribute_and_values', {
-			item_code: this.item_code,
-			selected_attributes
-		});
-	}
-
-	get_attributes_and_values() {
-		return this.call('erpnext.e_commerce.variant_selector.utils.get_attributes_and_values', {
-			item_code: this.item_code
-		});
-	}
-
-	get_cache_key() {
-		return `configure:${this.item_code}`;
-	}
-
-	call(method, args) {
-		// promisified frappe.call
-		return new Promise((resolve, reject) => {
-			frappe.call(method, args)
-				.then(r => resolve(r.message))
-				.fail(reject);
-		});
-	}
-}
-
-function set_continue_configuration() {
-	const $btn_configure = $('.btn-configure');
-	const { itemCode } = $btn_configure.data();
-
-	if (localStorage.getItem(`configure:${itemCode}`)) {
-		$btn_configure.text(__('Continue Selection'));
-	} else {
-		$btn_configure.text(__('Select Variant'));
-	}
-}
-
-frappe.ready(() => {
-	const $btn_configure = $('.btn-configure');
-	if (!$btn_configure.length) return;
-	const { itemCode, itemName } = $btn_configure.data();
-
-	set_continue_configuration();
-
-	$btn_configure.on('click', () => {
-		$btn_configure.prop('disabled', true);
-		new ItemConfigure(itemCode, itemName);
-	});
-});
diff --git a/erpnext/templates/generators/item/item_details.html b/erpnext/templates/generators/item/item_details.html
deleted file mode 100644
index 028936b..0000000
--- a/erpnext/templates/generators/item/item_details.html
+++ /dev/null
@@ -1,63 +0,0 @@
-{% set width_class = "expand" if not slides else "" %}
-{% set cart_settings = shopping_cart.cart_settings %}
-{% set product_info = shopping_cart.product_info %}
-{% set price_info = product_info.get('price') or {} %}
-
-<div class="col-md-7 product-details {{ width_class }}">
-	<div class="d-flex">
-		<!-- title -->
-		<div class="product-title col-11" itemprop="name">
-			{{ doc.web_item_name }}
-		</div>
-
-		<!-- Wishlist -->
-		{% if cart_settings.enable_wishlist %}
-			<div class="like-action-item-fp like-action {{ 'like-action-wished' if wished else ''}} ml-2"
-				data-item-code="{{ doc.item_code }}">
-				<svg class="icon sm">
-					<use class="{{ 'wished' if wished else 'not-wished' }} wish-icon" href="#icon-heart"></use>
-				</svg>
-			</div>
-		{% endif %}
-	</div>
-
-	<p class="product-code">
-		<span class="product-item-group">
-			{{ _(doc.item_group) }}
-		</span>
-		<span class="product-item-code">
-			{{ _("Item Code") }}:
-		</span>
-		<span itemprop="productID">{{ doc.item_code }}</span>
-	</p>
-	{% if has_variants %}
-		<!-- configure template -->
-		{% include "templates/generators/item/item_configure.html" %}
-	{% else %}
-		<!-- add variant to cart -->
-		{% include "templates/generators/item/item_add_to_cart.html" %}
-	{% endif %}
-	<!-- description -->
-	<div class="product-description" itemprop="description">
-	{% if frappe.utils.strip_html(doc.web_long_description or '') %}
-		{{ doc.web_long_description | safe }}
-	{% elif frappe.utils.strip_html(doc.description or '')  %}
-		{{ doc.description | safe }}
-	{% else %}
-		{{ "" }}
-	{% endif  %}
-	</div>
-</div>
-
-{% block base_scripts %}
-<!-- js should be loaded in body! -->
-<script type="text/javascript" src="/assets/frappe/js/lib/jquery/jquery.min.js"></script>
-{% endblock %}
-
-<script>
-	$('.page_content').on('click', '.like-action-item-fp', (e) => {
-			// Bind action on wishlist button
-			const $btn = $(e.currentTarget);
-			erpnext.e_commerce.wishlist.wishlist_action($btn);
-		});
-</script>
\ No newline at end of file
diff --git a/erpnext/templates/generators/item/item_image.html b/erpnext/templates/generators/item/item_image.html
deleted file mode 100644
index e1bb3b9..0000000
--- a/erpnext/templates/generators/item/item_image.html
+++ /dev/null
@@ -1,108 +0,0 @@
-{% set column_size = 5 if slides else 4 %}
-<div class="col-md-{{ column_size }} h-100 d-flex mb-4">
-	{% if slides %}
-		<div class="item-slideshow d-flex flex-column mr-3">
-			{% for item in slides %}
-			<img class="item-slideshow-image mb-2 {% if loop.first %}active{% endif %}"
-					src="{{ item.image }}" alt="{{ item.heading }}">
-			{% endfor %}
-		</div>
-		{{ product_image(slides[0].image, 'product-image') }}
-		<!-- Simple image slideshow -->
-		<script>
-			frappe.ready(() => {
-				$('.page_content').on('click', '.item-slideshow-image', (e) => {
-					const $img = $(e.currentTarget);
-					const link = $img.prop('src');
-					const $product_image = $('.product-image');
-					$product_image.find('a').prop('href', link);
-					$product_image.find('img').prop('src', link);
-
-					$('.item-slideshow-image').removeClass('active');
-					$img.addClass('active');
-				});
-			})
-		</script>
-	{% else %}
-		{{ product_image(doc.website_image, alt=doc.website_image_alt or doc.item_name) }}
-	{% endif %}
-
-	<!-- Simple image preview -->
-
-	<div class="image-zoom-view" style="display: none;">
-		<button type="button" class="close" aria-label="Close">
-			<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
-			stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-x">
-				<line x1="18" y1="6" x2="6" y2="18"></line>
-				<line x1="6" y1="6" x2="18" y2="18"></line>
-			</svg>
-		</button>
-	</div>
-</div>
-<style>
-	.website-image {
-		cursor: pointer;
-	}
-
-	.image-zoom-view {
-		position: fixed;
-		top: 0;
-		left: 0;
-		right: 0;
-		bottom: 0;
-		height: 100vh;
-		width: 100vw;
-		display: flex;
-		justify-content: center;
-		align-items: center;
-		background: rgba(0, 0, 0, 0.8);
-		z-index: 1080;
-	}
-
-	.image-zoom-view img {
-		max-height: 100%;
-		max-width: 100%;
-	}
-
-	.image-zoom-view button {
-		position: absolute;
-		right: 3rem;
-		top: 2rem;
-	}
-
-	.image-zoom-view svg {
-		color: var(--white);
-	}
-</style>
-<script>
-	frappe.ready(() => {
-		const $zoom_wrapper = $('.image-zoom-view');
-
-		$('.website-image').on('click', (e) => {
-			e.preventDefault();
-			const $img = $(e.target);
-			const src = $img.prop('src');
-			if (!src) return;
-			show_preview(src);
-		});
-
-		$zoom_wrapper.on('click', 'button', hide_preview);
-
-		$(document).on('keydown', (e) => {
-			if (e.key === 'Escape') {
-				hide_preview();
-			}
-		});
-
-		function show_preview(src) {
-			$zoom_wrapper.show();
-			const $img = $(`<img src="${src}">`)
-			$zoom_wrapper.append($img);
-		}
-
-		function hide_preview() {
-			$zoom_wrapper.find('img').remove();
-			$zoom_wrapper.hide();
-		}
-	})
-</script>
diff --git a/erpnext/templates/generators/item/item_inquiry.html b/erpnext/templates/generators/item/item_inquiry.html
deleted file mode 100644
index af636f1..0000000
--- a/erpnext/templates/generators/item/item_inquiry.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% if shopping_cart and shopping_cart.cart_settings.enabled %}
-{% set cart_settings = shopping_cart.cart_settings %}
-	{% if cart_settings.show_contact_us_button | int %}
-		<button class="btn btn-inquiry font-md w-30-40" data-item-code="{{ doc.name }}">
-			{{ _('Contact Us') }}
-		</button>
-	{% endif %}
-<script>
-{% include "templates/generators/item/item_inquiry.js" %}
-</script>
-{% endif %}
diff --git a/erpnext/templates/generators/item/item_inquiry.js b/erpnext/templates/generators/item/item_inquiry.js
deleted file mode 100644
index 0aee996..0000000
--- a/erpnext/templates/generators/item/item_inquiry.js
+++ /dev/null
@@ -1,77 +0,0 @@
-frappe.ready(() => {
-	const d = new frappe.ui.Dialog({
-		title: __('Contact Us'),
-		fields: [
-			{
-				fieldtype: 'Data',
-				label: __('Full Name'),
-				fieldname: 'lead_name',
-				reqd: 1
-			},
-			{
-				fieldtype: 'Data',
-				label: __('Organization Name'),
-				fieldname: 'company_name',
-			},
-			{
-				fieldtype: 'Data',
-				label: __('Email'),
-				fieldname: 'email_id',
-				options: 'Email',
-				reqd: 1
-			},
-			{
-				fieldtype: 'Data',
-				label: __('Phone Number'),
-				fieldname: 'phone',
-				options: 'Phone',
-				reqd: 1
-			},
-			{
-				fieldtype: 'Data',
-				label: __('Subject'),
-				fieldname: 'subject',
-				reqd: 1
-			},
-			{
-				fieldtype: 'Text',
-				label: __('Message'),
-				fieldname: 'message',
-				reqd: 1
-			}
-		],
-		primary_action: send_inquiry,
-		primary_action_label: __('Send')
-	});
-
-	function send_inquiry() {
-		const values = d.get_values();
-		const doc = Object.assign({}, values);
-		delete doc.subject;
-		delete doc.message;
-
-		d.hide();
-
-		frappe.call('erpnext.e_commerce.shopping_cart.cart.create_lead_for_item_inquiry', {
-			lead: doc,
-			subject: values.subject,
-			message: values.message
-		}).then(r => {
-			if (r.message) {
-				d.clear();
-			}
-		});
-	}
-
-	$('.btn-inquiry').click((e) => {
-		const $btn = $(e.target);
-		const item_code = $btn.data('item-code');
-		d.set_value('subject', 'Inquiry about ' + item_code);
-		if (!['Administrator', 'Guest'].includes(frappe.session.user)) {
-			d.set_value('email_id', frappe.session.user);
-			d.set_value('lead_name', frappe.get_cookie('full_name'));
-		}
-
-		d.show();
-	});
-});
diff --git a/erpnext/templates/generators/item/item_reviews.html b/erpnext/templates/generators/item/item_reviews.html
deleted file mode 100644
index c62c6f7..0000000
--- a/erpnext/templates/generators/item/item_reviews.html
+++ /dev/null
@@ -1,88 +0,0 @@
-{% from "erpnext/templates/includes/macros.html" import user_review, ratings_summary %}
-
-<div class="mt-4 ratings-reviews-section">
-		<!-- Title and Action -->
-		<div class="w-100 mt-4 mb-2 d-flex">
-			<div class="reviews-header col-9">
-				{{ _("Customer Reviews") }}
-			</div>
-
-			<div class="write-a-review-btn col-3">
-				<!-- Write a Review for legitimate users -->
-				{% if frappe.session.user != "Guest" and user_is_customer %}
-					<button class="btn btn-write-review"
-						data-web-item="{{ doc.name }}">
-						{{ _("Write a Review") }}
-					</button>
-				{% endif %}
-			</div>
-		</div>
-
-		<!-- Summary -->
-		{{ ratings_summary(reviews, reviews_per_rating, average_rating, average_whole_rating, for_summary=True, total_reviews=total_reviews) }}
-
-
-	<!-- Reviews and Comments -->
-	<div class="mt-8">
-		{% if reviews %}
-			{{ user_review(reviews) }}
-
-			{% if total_reviews > 4 %}
-				<div class="mt-6 mb-6"style="color: var(--primary);">
-					<a href="/customer_reviews?web_item={{ doc.name }}">{{ _("View all reviews") }}</a>
-				</div>
-			{% endif %}
-
-		{% else %}
-			<h6 class="text-muted mt-6">
-				{{ _("No Reviews") }}
-			</h6>
-		{% endif %}
-	</div>
-</div>
-
-<script>
-	frappe.ready(() => {
-		$('.page_content').on('click', '.btn-write-review', (e) => {
-			// Bind action on write a review button
-			const $btn = $(e.currentTarget);
-
-			let d = new frappe.ui.Dialog({
-				title: __("Write a Review"),
-				fields: [
-					{fieldname: "title", fieldtype: "Data", label: "Headline", reqd: 1},
-					{fieldname: "rating", fieldtype: "Rating", label: "Overall Rating", reqd: 1},
-					{fieldtype: "Section Break"},
-					{fieldname: "comment", fieldtype: "Small Text", label: "Your Review"}
-				],
-				primary_action: function() {
-					var data = d.get_values();
-					frappe.call({
-						method: "erpnext.e_commerce.doctype.item_review.item_review.add_item_review",
-						args: {
-							web_item: "{{ doc.name }}",
-							title: data.title,
-							rating: data.rating,
-							comment: data.comment
-						},
-						freeze: true,
-						freeze_message: __("Submitting Review ..."),
-						callback: function(r) {
-							if(!r.exc) {
-								frappe.msgprint({
-									message: __("Thank you for the review"),
-									title: __("Review Submitted"),
-									indicator: "green"
-								});
-								d.hide();
-								location.reload();
-							}
-						}
-					});
-				},
-				primary_action_label: __('Submit')
-			});
-			d.show();
-		});
-	});
-</script>
diff --git a/erpnext/templates/generators/item/item_specifications.html b/erpnext/templates/generators/item/item_specifications.html
deleted file mode 100644
index 0814d81..0000000
--- a/erpnext/templates/generators/item/item_specifications.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!-- Is reused to render within tabs as well as independently -->
-{% if website_specifications %}
-<div class="{{ 'mt-2' if not show_tabs else 'mt-5'}} item-website-specification">
-	<div class="col-md-11">
-		{% if not show_tabs %}
-			<div class="product-title mb-5 mt-4">
-				Product Details
-			</div>
-		{% endif %}
-		<table class="table">
-		{% for d in website_specifications -%}
-			<tr>
-				<td class="spec-label">{{ d.label }}</td>
-				<td class="spec-content">{{ d.description }}</td>
-			</tr>
-		{%- endfor %}
-		</table>
-	</div>
-</div>
-{% endif %}
diff --git a/erpnext/templates/generators/item_group.html b/erpnext/templates/generators/item_group.html
deleted file mode 100644
index 956c3c51..0000000
--- a/erpnext/templates/generators/item_group.html
+++ /dev/null
@@ -1,72 +0,0 @@
-{% from "erpnext/templates/includes/macros.html" import field_filter_section, attribute_filter_section, discount_range_filters %}
-{% extends "templates/web.html" %}
-
-{% block header %}
-<div class="mb-6">{{ _(item_group_name) }}</div>
-{% endblock header %}
-
-{% block script %}
-<script type="text/javascript" src="/all-products/index.js"></script>
-{% endblock %}
-
-{% block breadcrumbs %}
-<div class="item-breadcrumbs small text-muted">
-	{% include "templates/includes/breadcrumbs.html" %}
-</div>
-{% endblock %}
-
-{% block page_content %}
-<div class="item-group-content" itemscope itemtype="http://schema.org/Product"
-	data-item-group="{{ name }}">
-	<div class="item-group-slideshow">
-		{% if slideshow %} <!-- slideshow -->
-			{{ web_block(
-				"Hero Slider",
-				values=slideshow,
-				add_container=0,
-				add_top_padding=0,
-				add_bottom_padding=0,
-			) }}
-		{% endif %}
-
-		{% if description %} <!-- description -->
-		<div class="item-group-description text-muted mb-5" itemprop="description">{{ description or ""}}</div>
-		{% endif %}
-	</div>
-	<div class="row">
-		<div id="product-listing" class="col-12 order-2 col-md-9 order-md-2 item-card-group-section">
-			<!-- Products Rendered in all-products/index.js-->
-		</div>
-
-		<div class="col-12 order-1 col-md-3 order-md-1">
-			<div class="collapse d-md-block mr-4 filters-section" id="product-filters">
-				<div class="d-flex justify-content-between align-items-center mb-5 title-section">
-					<div class="mb-4 filters-title" > {{ _('Filters') }} </div>
-					<a class="mb-4 clear-filters" href="/{{ doc.route }}">{{ _('Clear All') }}</a>
-				</div>
-				<!-- field filters -->
-				{{ field_filter_section(field_filters) }}
-
-				<!-- attribute filters -->
-				{{ attribute_filter_section(attribute_filters) }}
-
-			</div>
-
-		</div>
-	</div>
-</div>
-
-<script>
-	frappe.ready(() => {
-		$('.btn-prev, .btn-next').click((e) => {
-			const $btn = $(e.target);
-			$btn.prop('disabled', true);
-			const start = $btn.data('start');
-			let query_params = frappe.utils.get_query_params();
-			query_params.start = start;
-			let path = window.location.pathname + '?' + frappe.utils.get_url_from_dict(query_params);
-			window.location.href = path;
-		});
-	});
-</script>
-{% endblock %}
diff --git a/erpnext/templates/includes/cart/address_card.html b/erpnext/templates/includes/cart/address_card.html
deleted file mode 100644
index 830ed64..0000000
--- a/erpnext/templates/includes/cart/address_card.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<div class="card address-card h-100">
-	<div class="btn btn-sm btn-default btn-change-address font-md" style="position: absolute; right: 0; top: 0;">
-		{{ _('Change') }}
-	</div>
-	<div class="card-body p-0">
-		<div class="card-title">{{ address.title }}</div>
-		<div class="card-text mb-2">
-			{{ address.display }}
-		</div>
-		<a href="/addresses?name={{address.name}}" class="card-link">
-			<svg class="icon icon-sm">
-				<use href="#icon-edit"></use>
-			</svg>
-			{{ _('Edit') }}
-		</a>
-	</div>
-</div>
diff --git a/erpnext/templates/includes/cart/address_picker_card.html b/erpnext/templates/includes/cart/address_picker_card.html
deleted file mode 100644
index 646210e..0000000
--- a/erpnext/templates/includes/cart/address_picker_card.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<div class="card address-card h-100">
-	<div class="check" style="position: absolute; right: 15px; top: 15px;">
-		<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-check"><polyline points="20 6 9 17 4 12"></polyline></svg>
-	</div>
-	<div class="card-body">
-		<h5 class="card-title">{{ address.title }}</h5>
-		<p class="card-text text-muted">
-			{{ address.display }}
-		</p>
-		<a href="/addresses?name={{address.name}}" class="card-link">{{ _('Edit') }}</a>
-	</div>
-</div>
diff --git a/erpnext/templates/includes/cart/cart_address.html b/erpnext/templates/includes/cart/cart_address.html
deleted file mode 100644
index a8188ec..0000000
--- a/erpnext/templates/includes/cart/cart_address.html
+++ /dev/null
@@ -1,189 +0,0 @@
-{% from "erpnext/templates/includes/cart/cart_macros.html" import show_address %}
-
-{% if addresses | length == 1%}
-	{% set select_address = True %}
-{% endif %}
-
-<div class="mb-3 frappe-card p-5" data-section="shipping-address">
-	<div class="d-flex">
-		<div class="col-6 address-header"><h6>{{ _("Shipping Address") }}</h6></div>
-		<div class="col-6" style="padding: 0;">
-			<a class="ml-4 btn-new-address" role="button">{{ _("Add a new address") }}</a>
-		</div>
-	</div>
-
-	<hr>
-	{% for address in shipping_addresses %}
-	{% if doc.shipping_address_name == address.name %}
-	<div class="row no-gutters" data-fieldname="shipping_address_name">
-		<div class="w-100 address-container" data-address-name="{{address.name}}" data-address-type="shipping" data-active>
-			{% include "templates/includes/cart/address_card.html" %}
-		</div>
-	</div>
-	{% endif %}
-	{% endfor %}
-</div>
-
-<!-- Billing Address -->
-<div class="checkbox ml-1 mb-2">
-	<label for="input_same_billing">
-		<input type="checkbox" class="product-filter" id="input_same_billing" checked style="width: 14px !important">
-		<span class="label-area font-md">{{ _('Billing Address is same as Shipping Address') }}</span>
-	</label>
-</div>
-
-{% if billing_addresses %}
-	<div class="mb-3 frappe-card p-5" data-section="billing-address">
-		<div class="d-flex">
-			<div class="col-6 address-header"><h6>{{ _("Billing Address") }}</h6></div>
-			<div class="col-6" style="padding: 0;">
-				<a class="ml-4 btn-new-address" role="button">{{ _("Add a new address") }}</a>
-			</div>
-		</div>
-
-		<hr>
-		{% for address in billing_addresses %}
-			{% if doc.customer_address == address.name %}
-			<div class="row no-gutters" data-fieldname="customer_address">
-				<div class="w-100 address-container" data-address-name="{{address.name}}" data-address-type="billing" data-active>
-						{% include "templates/includes/cart/address_card.html" %}
-					</div>
-			</div>
-			{% endif %}
-		{% endfor %}
-	</div>
-{% endif %}
-
-<script>
-frappe.boot = {{ boot }}
-frappe.ready(() => {
-	$(document).on('click', '.address-card', (e) => {
-		const $target = $(e.currentTarget);
-		const $section = $target.closest('[data-section]');
-		$section.find('.address-card').removeClass('active');
-		$target.addClass('active');
-	});
-
-	$('#input_same_billing').change((e) => {
-		const $check = $(e.target);
-		toggle_billing_address_section(!$check.is(':checked'));
-	});
-
-	$('.btn-new-address').click(() => {
-		const d = new frappe.ui.Dialog({
-			title: __('New Address'),
-			fields: [
-				{
-					label: __('Address Title'),
-					fieldname: 'address_title',
-					fieldtype: 'Data',
-					reqd: 1
-				},
-				{
-					label: __('Address Line 1'),
-					fieldname: 'address_line1',
-					fieldtype: 'Data',
-					reqd: 1
-				},
-				{
-					label: __('Address Line 2'),
-					fieldname: 'address_line2',
-					fieldtype: 'Data'
-				},
-				{
-					label: __('City/Town'),
-					fieldname: 'city',
-					fieldtype: 'Data',
-					reqd: 1
-				},
-				{
-					label: __('State'),
-					fieldname: 'state',
-					fieldtype: 'Data'
-				},
-				{
-					label: __('Country'),
-					fieldname: 'country',
-					fieldtype: 'Link',
-					options: 'Country',
-					only_select: true,
-					reqd: 1
-				},
-				{
-					fieldname: "column_break0",
-					fieldtype: "Column Break",
-					width: "50%"
-				},
-				{
-					label: __('Address Type'),
-					fieldname: 'address_type',
-					fieldtype: 'Select',
-					options: [
-						'Billing',
-						'Shipping'
-					],
-					reqd: 1
-				},
-				{
-					label: __('Postal Code'),
-					fieldname: 'pincode',
-					fieldtype: 'Data'
-				},
-				{
-					fieldname: "phone",
-					fieldtype: "Data",
-					label: "Phone",
-					reqd: 1
-				},
-			],
-			primary_action_label: __('Save'),
-			primary_action: (values) => {
-				frappe.call('erpnext.e_commerce.shopping_cart.cart.add_new_address', { doc: values })
-					.then(r => {
-						frappe.call({
-							method: "erpnext.e_commerce.shopping_cart.cart.update_cart_address",
-							args: {
-								address_type: r.message.address_type,
-								address_name: r.message.name
-							},
-							callback: function (r) {
-								d.hide();
-								window.location.reload();
-							}
-						});
-					});
-
-			}
-		})
-
-		d.show();
-	});
-
-	function setup_state() {
-		const shipping_address = $('[data-section="shipping-address"]')
-			.find('[data-address-name][data-active]').attr('data-address-name');
-
-		const billing_address = $('[data-section="billing-address"]')
-			.find('[data-address-name][data-active]').attr('data-address-name');
-
-		$('#input_same_billing').prop('checked', shipping_address === billing_address).trigger('change');
-
-		if (!shipping_address && !billing_address) {
-			$('#input_same_billing').prop('checked', true).trigger('change');
-		}
-
-		if (shipping_address) {
-			$(`[data-section="shipping-address"] [data-address-name="${shipping_address}"] .address-card`).addClass('active');
-		}
-		if (billing_address) {
-			$(`[data-section="billing-address"] [data-address-name="${billing_address}"] .address-card`).addClass('active');
-		}
-	}
-
-	setup_state();
-
-	function toggle_billing_address_section(flag) {
-		$('[data-section="billing-address"]').toggle(flag);
-	}
-});
-</script>
diff --git a/erpnext/templates/includes/cart/cart_address_picker.html b/erpnext/templates/includes/cart/cart_address_picker.html
deleted file mode 100644
index 66a50ec..0000000
--- a/erpnext/templates/includes/cart/cart_address_picker.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<div class="mb-3 frappe-card p-5" data-section="shipping-address">
-	<h6>{{ _("Shipping Address") }}</h6>
-</div>
diff --git a/erpnext/templates/includes/cart/cart_dropdown.html b/erpnext/templates/includes/cart/cart_dropdown.html
deleted file mode 100644
index 38ad183..0000000
--- a/erpnext/templates/includes/cart/cart_dropdown.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<div class="cart-dropdown-container">
-	<div id="cart-error" class="alert alert-danger"
-		style="display: none;"></div>
-	<div class="row checkout-btn">
-		<div class="col-sm-12 col-xs-12">
-			<a href="/cart" class="btn btn-block btn-primary">{{ _("Checkout") }}</a>
-		</div>
-	</div>
-	<div class="row cart-items-dropdown cart-item-header text-muted">
-		<div class="col-sm-6 col-xs-6 h6 text-uppercase">
-		{{ _("Item") }}
-		</div>
-		<div class="col-sm-6 col-xs-6 text-right h6 text-uppercase">
-		{{ _("Price") }}
-		</div>
-	</div>
-
-	{% if doc.items %}
-	<div class="row cart-items-dropdown">
-		<div class="col-sm-12 col-xs-12">
-			{% include "templates/includes/cart/cart_items_dropdown.html" %}
-		</div>
-	</div>
-	{% else %}
-	<p>{{ _("Cart is Empty") }}</p>
-	{% endif %}
-</div>
diff --git a/erpnext/templates/includes/cart/cart_items.html b/erpnext/templates/includes/cart/cart_items.html
deleted file mode 100644
index 428b36e..0000000
--- a/erpnext/templates/includes/cart/cart_items.html
+++ /dev/null
@@ -1,113 +0,0 @@
-{% from "erpnext/templates/includes/macros.html" import product_image %}
-
-{% macro item_subtotal(item) %}
-	<div>
-		{{ item.get_formatted('amount') }}
-	</div>
-
-	{% if item.is_free_item %}
-		<div class="text-success mt-4">
-			<span class="free-tag">
-				{{ _('FREE') }}
-			</span>
-		</div>
-	{% else %}
-		<span class="item-rate">
-			{{ _('Rate:') }} {{ item.get_formatted('rate') }}
-		</span>
-	{% endif %}
-{% endmacro %}
-
-{% for d in doc.items %}
-	<tr data-name="{{ d.name }}">
-		<td style="width: 60%;">
-			<div class="d-flex">
-				<div class="cart-item-image mr-4">
-					{% if d.thumbnail %}
-						{{ product_image(d.thumbnail, alt="d.web_item_name", no_border=True) }}
-					{% else %}
-						<div class = "no-image-cart-item">
-							{{ frappe.utils.get_abbr(d.web_item_name) or "NA" }}
-						</div>
-					{% endif %}
-				</div>
-
-				<div class="d-flex w-100" style="flex-direction: column;">
-					<div class="item-title mb-1 mr-3">
-						{{ d.get("web_item_name") or d.item_name }}
-					</div>
-					<div class="item-subtitle mr-2">
-						{{ d.item_code }}
-					</div>
-					{%- set variant_of = frappe.db.get_value('Item', d.item_code, 'variant_of') %}
-					{% if variant_of %}
-					<span class="item-subtitle mr-2">
-						{{ _('Variant of') }}
-						<a href="{{frappe.db.get_value('Website Item', {'item_code': variant_of}, 'route') or '#'}}">
-							{{ variant_of }}
-						</a>
-					</span>
-					{% endif %}
-
-					<div class="mt-2 notes">
-						<textarea data-item-code="{{d.item_code}}" class="form-control" rows="2" placeholder="{{ _('Add notes') }}">
-							{{d.additional_notes or ''}}
-						</textarea>
-					</div>
-				</div>
-			</div>
-		</td>
-
-		<!-- Qty column -->
-		<td class="text-right" style="width: 25%;">
-			<div class="d-flex">
-				{% set disabled = 'disabled' if d.is_free_item else '' %}
-				<div class="input-group number-spinner mt-1 mb-4">
-					<span class="input-group-prepend d-sm-inline-block">
-						<button class="btn cart-btn" data-dir="dwn" {{ disabled }}>
-							{{ '–' if not d.is_free_item else ''}}
-						</button>
-					</span>
-
-					<input class="form-control text-center cart-qty" value="{{ d.get_formatted('qty') }}" data-item-code="{{ d.item_code }}"
-						style="max-width: 70px;" {{ disabled }}>
-
-					<span class="input-group-append d-sm-inline-block">
-						<button class="btn cart-btn" data-dir="up" {{ disabled }}>
-							{{ '+' if not d.is_free_item else ''}}
-						</button>
-					</span>
-					</div>
-
-				<div>
-					{% if not d.is_free_item %}
-						<div class="remove-cart-item column-sm-view d-flex" data-item-code="{{ d.item_code }}">
-							<span>
-								<svg class="icon sm remove-cart-item-logo"
-									width="18" height="18" viewBox="0 0 18 18"
-									xmlns="http://www.w3.org/2000/svg" id="icon-close">
-									<path fill-rule="evenodd" clip-rule="evenodd" d="M4.146 11.217a.5.5 0 1 0 .708.708l3.182-3.182 3.181 3.182a.5.5 0 1 0 .708-.708l-3.182-3.18 3.182-3.182a.5.5 0 1 0-.708-.708l-3.18 3.181-3.183-3.182a.5.5 0 0 0-.708.708l3.182 3.182-3.182 3.181z" stroke-width="0"></path>
-								</svg>
-							</span>
-						</div>
-					{% endif %}
-					</div>
-			</div>
-
-
-			<!-- Shown on mobile view, else hidden -->
-			{% if cart_settings.enable_checkout or cart_settings.show_price_in_quotation %}
-				<div class="text-right sm-item-subtotal">
-					{{ item_subtotal(d) }}
-				</div>
-			{% endif %}
-		</td>
-
-		<!-- Subtotal column -->
-		{% if cart_settings.enable_checkout or cart_settings.show_price_in_quotation %}
-			<td class="text-right item-subtotal column-sm-view w-100">
-				{{ item_subtotal(d) }}
-			</td>
-		{% endif %}
-	</tr>
-{% endfor %}
diff --git a/erpnext/templates/includes/cart/cart_items_dropdown.html b/erpnext/templates/includes/cart/cart_items_dropdown.html
deleted file mode 100644
index 5d107fc..0000000
--- a/erpnext/templates/includes/cart/cart_items_dropdown.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% from "erpnext/templates/includes/order/order_macros.html" import item_name_and_description_cart %}
-
-{% for d in doc.items %}
-<div class="row cart-dropdown">
-    <div class="col-sm-8 col-xs-8 col-name-description">
-        {{ item_name_and_description_cart(d) }}
-    </div>
-    <div class="col-sm-4 col-xs-4 text-right col-amount">
-        {{ d.get_formatted("amount") }}
-    </div>
-</div>
-{% endfor %}
diff --git a/erpnext/templates/includes/cart/cart_items_total.html b/erpnext/templates/includes/cart/cart_items_total.html
deleted file mode 100644
index c94fde4..0000000
--- a/erpnext/templates/includes/cart/cart_items_total.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!-- Total at the end of the cart items -->
-<tr>
-	<th></th>
-	<th class="text-left item-grand-total" colspan="1">
-		{{ _("Total") }}
-	</th>
-	<th class="text-left item-grand-total totals" colspan="3">
-		{{ doc.get_formatted("total") }}
-	</th>
-</tr>
\ No newline at end of file
diff --git a/erpnext/templates/includes/cart/cart_macros.html b/erpnext/templates/includes/cart/cart_macros.html
deleted file mode 100644
index fd95dba..0000000
--- a/erpnext/templates/includes/cart/cart_macros.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{% macro show_address(address, doc, fieldname, select_address=False) %}
-{% set selected=address.name==doc.get(fieldname) %}
-
-<div class="panel panel-default">
-	<div class="panel-heading">
-		<div class="row">
-			<div class="col-sm-10 address-title"
-				data-address-name="{{ address.name }}">
-                <strong>{{ address.name }}</strong></div>
-			<div class="col-sm-2 text-right">
-                <input type="checkbox"
-                data-fieldname="{{ fieldname }}"
-				data-address-name="{{ address.name}}"
-                    {{ "checked" if selected else "" }}></div>
-		</div>
-	</div>
-	<div class="panel-collapse"
-        data-address-name="{{ address.name }}">
-		<div class="panel-body text-muted small">{{ address.display }}</div>
-	</div>
-</div>
-{% endmacro %}
diff --git a/erpnext/templates/includes/cart/cart_payment_summary.html b/erpnext/templates/includes/cart/cart_payment_summary.html
deleted file mode 100644
index b5655a2..0000000
--- a/erpnext/templates/includes/cart/cart_payment_summary.html
+++ /dev/null
@@ -1,84 +0,0 @@
-<!-- Payment -->
-{% if cart_settings.enable_checkout or cart_settings.show_price_in_quotation %}
-<h6>
-	{{ _("Payment Summary") }}
-</h6>
-{% endif %}
-
-<div class="card h-100">
-	<div class="card-body p-0">
-		{% if cart_settings.enable_checkout or cart_settings.show_price_in_quotation %}
-			<table class="table w-100">
-				<tr>
-					{% set total_items = frappe.utils.cstr(frappe.utils.flt(doc.total_qty, 0)) %}
-					<td class="bill-label">{{ _("Net Total (") + total_items + _(" Items)") }}</td>
-					<td class="bill-content net-total text-right">{{ doc.get_formatted("net_total") }}</td>
-				</tr>
-
-				<!-- taxes -->
-				{% for d in doc.taxes %}
-					{% if d.base_tax_amount %}
-						<tr>
-							<td class="bill-label">
-								{{ d.description }}
-							</td>
-							<td class="bill-content text-right">
-								{{ d.get_formatted("base_tax_amount") }}
-							</td>
-						</tr>
-					{% endif %}
-				{% endfor %}
-			</table>
-
-			<!-- TODO: Apply Coupon Dialog-->
-			<!-- {% set show_coupon_code = cart_settings.show_apply_coupon_code_in_website and cart_settings.enable_checkout %}
-			{% if show_coupon_code %}
-				<button class="btn btn-coupon-code w-100 text-left">
-					<svg width="24" height="24" viewBox="0 0 24 24" stroke="var(--gray-600)" fill="none" xmlns="http://www.w3.org/2000/svg">
-						<path d="M19 15.6213C19 15.2235 19.158 14.842 19.4393 14.5607L20.9393 13.0607C21.5251 12.4749 21.5251 11.5251 20.9393 10.9393L19.4393 9.43934C19.158 9.15804 19 8.7765 19 8.37868V6.5C19 5.67157 18.3284 5 17.5 5H15.6213C15.2235 5 14.842 4.84196 14.5607 4.56066L13.0607 3.06066C12.4749 2.47487 11.5251 2.47487 10.9393 3.06066L9.43934 4.56066C9.15804 4.84196 8.7765 5 8.37868 5H6.5C5.67157 5 5 5.67157 5 6.5V8.37868C5 8.7765 4.84196 9.15804 4.56066 9.43934L3.06066 10.9393C2.47487 11.5251 2.47487 12.4749 3.06066 13.0607L4.56066 14.5607C4.84196 14.842 5 15.2235 5 15.6213V17.5C5 18.3284 5.67157 19 6.5 19H8.37868C8.7765 19 9.15804 19.158 9.43934 19.4393L10.9393 20.9393C11.5251 21.5251 12.4749 21.5251 13.0607 20.9393L14.5607 19.4393C14.842 19.158 15.2235 19 15.6213 19H17.5C18.3284 19 19 18.3284 19 17.5V15.6213Z" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
-						<path d="M15 9L9 15" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
-						<path d="M10.5 9.5C10.5 10.0523 10.0523 10.5 9.5 10.5C8.94772 10.5 8.5 10.0523 8.5 9.5C8.5 8.94772 8.94772 8.5 9.5 8.5C10.0523 8.5 10.5 8.94772 10.5 9.5Z" fill="white" stroke-linecap="round" stroke-linejoin="round"/>
-						<path d="M15.5 14.5C15.5 15.0523 15.0523 15.5 14.5 15.5C13.9477 15.5 13.5 15.0523 13.5 14.5C13.5 13.9477 13.9477 13.5 14.5 13.5C15.0523 13.5 15.5 13.9477 15.5 14.5Z" fill="white" stroke-linecap="round" stroke-linejoin="round"/>
-					</svg>
-					<span class="ml-2">Apply Coupon</span>
-				</button>
-			{% endif %} -->
-
-			<table class="table w-100 grand-total mt-6">
-				<tr>
-					<td class="bill-content net-total">{{ _("Grand Total") }}</td>
-					<td class="bill-content net-total text-right">{{ doc.get_formatted("grand_total") }}</td>
-				</tr>
-			</table>
-		{% endif %}
-
-		{% if cart_settings.enable_checkout %}
-			<button class="btn btn-primary btn-place-order font-md w-100" type="button">
-				{{ _('Place Order') }}
-			</button>
-		{% else %}
-			<button class="btn btn-primary btn-request-for-quotation font-md w-100" type="button">
-				{{ _('Request for Quote') }}
-			</button>
-		{% endif %}
-	</div>
-</div>
-
-<!-- TODO: Apply Coupon Dialog-->
-<!-- <script>
-	frappe.ready(() => {
-		$('.btn-coupon-code').click((e) => {
-			const $btn = $(e.currentTarget);
-			const d = new frappe.ui.Dialog({
-				title: __('Coupons'),
-				fields: [
-					{
-						fieldname: 'coupons_area',
-						fieldtype: 'HTML'
-					}
-				]
-			});
-			d.show();
-		});
-	});
-</script> -->
\ No newline at end of file
diff --git a/erpnext/templates/includes/integrations/gocardless_checkout.js b/erpnext/templates/includes/integrations/gocardless_checkout.js
deleted file mode 100644
index b18d550..0000000
--- a/erpnext/templates/includes/integrations/gocardless_checkout.js
+++ /dev/null
@@ -1,24 +0,0 @@
-$(document).ready(function() {
-	var data = {{ frappe.form_dict | json }};
-	var doctype = "{{ reference_doctype }}"
-	var docname = "{{ reference_docname }}"
-
-	frappe.call({
-		method: "erpnext.templates.pages.integrations.gocardless_checkout.check_mandate",
-		freeze: true,
-		headers: {
-			"X-Requested-With": "XMLHttpRequest"
-		},
-		args: {
-			"data": JSON.stringify(data),
-			"reference_doctype": doctype,
-			"reference_docname": docname
-		},
-		callback: function(r) {
-			if (r.message) {
-				window.location.href = r.message.redirect_to
-			}
-		}
-	})
-
-})
diff --git a/erpnext/templates/includes/integrations/gocardless_confirmation.js b/erpnext/templates/includes/integrations/gocardless_confirmation.js
deleted file mode 100644
index fee1d2b..0000000
--- a/erpnext/templates/includes/integrations/gocardless_confirmation.js
+++ /dev/null
@@ -1,24 +0,0 @@
-$(document).ready(function() {
-	var redirect_flow_id = "{{ redirect_flow_id }}";
-	var doctype = "{{ reference_doctype }}";
-	var docname = "{{ reference_docname }}";
-
-	frappe.call({
-		method: "erpnext.templates.pages.integrations.gocardless_confirmation.confirm_payment",
-		freeze: true,
-		headers: {
-			"X-Requested-With": "XMLHttpRequest"
-		},
-		args: {
-			"redirect_flow_id": redirect_flow_id,
-			"reference_doctype": doctype,
-			"reference_docname": docname
-		},
-		callback: function(r) {
-			if (r.message) {
-				window.location.href = r.message.redirect_to;
-			}
-		}
-	});
-
-});
diff --git a/erpnext/templates/includes/navbar/navbar_items.html b/erpnext/templates/includes/navbar/navbar_items.html
deleted file mode 100644
index d7adae5..0000000
--- a/erpnext/templates/includes/navbar/navbar_items.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{% extends 'frappe/templates/includes/navbar/navbar_items.html' %}
-
-{% block navbar_right_extension %}
-	<li class="shopping-cart cart-icon hidden">
-		<a class="nav-link" href="/cart">
-			<svg class="icon icon-lg">
-				<use href="#icon-assets"></use>
-			</svg>
-			<span class="badge badge-primary shopping-badge" id="cart-count"></span>
-		</a>
-	</li>
-	{% if frappe.db.get_single_value("E Commerce Settings", "enable_wishlist") %}
-		<li class="wishlist wishlist-icon hidden">
-			<a class="nav-link" href="/wishlist">
-				<svg class="icon icon-lg">
-					<use href="#icon-heart"></use>
-				</svg>
-				<span class="badge badge-primary shopping-badge" id="wish-count"></span>
-			</a>
-		</li>
-	{% endif %}
-{% endblock %}
diff --git a/erpnext/templates/includes/order/order_macros.html b/erpnext/templates/includes/order/order_macros.html
deleted file mode 100644
index d95b289..0000000
--- a/erpnext/templates/includes/order/order_macros.html
+++ /dev/null
@@ -1,52 +0,0 @@
-{% from "erpnext/templates/includes/macros.html" import product_image %}
-
-{% macro item_name_and_description(d) %}
-	<div class="row item_name_and_description">
-		<div class="col-xs-4 col-sm-2 order-image-col">
-			<div class="order-image h-100">
-				{% if d.thumbnail or d.image %}
-					{{ product_image(d.thumbnail or d.image, no_border=True) }}
-				{% else %}
-					<div class="no-image-cart-item" style="min-height: 100px;">
-						{{ frappe.utils.get_abbr(d.item_name) or "NA" }}
-					</div>
-				{% endif %}
-			</div>
-		</div>
-		<div class="col-xs-8 col-sm-10">
-			{{ d.item_code }}
-			<div class="text-muted small item-description">
-				{{ html2text(d.description) | truncate(140) }}
-			</div>
-			<span class="text-muted mt-2 d-l-n order-qty">
-				{{ _("Qty ") }}({{ d.get_formatted("qty") }})
-			</span>
-		</div>
-	</div>
-{% endmacro %}
-
-{% macro item_name_and_description_cart(d) %}
-	<div class="row item_name_dropdown">
-		<div class="col-xs-4 col-sm-4 order-image-col">
-			<div class="order-image">
-			 {{ product_image_square(d.thumbnail or d.image) }}
-			</div>
-		</div>
-		<div class="col-xs-8 col-sm-8">
-		   {{ d.item_name|truncate(25) }}
-			<div class="input-group number-spinner">
-				<span class="input-group-btn">
-					<button class="btn btn-light cart-btn" data-dir="dwn">
-						–</button>
-				</span>
-				<input class="form-control text-right cart-qty"
-					value = "{{ d.get_formatted('qty') }}"
-					data-item-code="{{ d.item_code }}">
-				<span class="input-group-btn">
-					<button class="btn btn-light cart-btn" data-dir="up">
-						+</button>
-				</span>
-			</div>
-		</div>
-	</div>
-{% endmacro %}
diff --git a/erpnext/templates/includes/product_page.js b/erpnext/templates/includes/product_page.js
deleted file mode 100644
index a3979d0..0000000
--- a/erpnext/templates/includes/product_page.js
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-// License: GNU General Public License v3. See license.txt
-
-frappe.ready(function() {
-	window.item_code = $('[itemscope] [itemprop="productID"]').text().trim();
-	var qty = 0;
-
-	frappe.call({
-		type: "POST",
-		method: "erpnext.e_commerce.shopping_cart.product_info.get_product_info_for_website",
-		args: {
-			item_code: get_item_code()
-		},
-		callback: function(r) {
-			if(r.message) {
-				if(r.message.cart_settings.enabled) {
-					let hide_add_to_cart = !r.message.product_info.price
-						|| (!r.message.product_info.in_stock && !r.message.cart_settings.allow_items_not_in_stock);
-					$(".item-cart, .item-price, .item-stock").toggleClass('hide', hide_add_to_cart);
-				}
-				if(r.message.cart_settings.show_price) {
-					$(".item-price").toggleClass("hide", false);
-				}
-				if(r.message.cart_settings.show_stock_availability) {
-					$(".item-stock").toggleClass("hide", false);
-				}
-				if(r.message.product_info.price) {
-					$(".item-price")
-						.html(r.message.product_info.price.formatted_price_sales_uom + "<div style='font-size: small'>\
-							(" + r.message.product_info.price.formatted_price + " / " + r.message.product_info.uom + ")</div>");
-
-					if(r.message.product_info.in_stock===0) {
-						$(".item-stock").html("<div style='color: red'> <i class='fa fa-close'></i> {{ _("Not in stock") }}</div>");
-					}
-					else if(r.message.product_info.in_stock===1 && r.message.cart_settings.show_stock_availability) {
-						var qty_display = "{{ _("In stock") }}";
-						if (r.message.product_info.show_stock_qty) {
-							qty_display += " ("+r.message.product_info.stock_qty+")";
-						}
-						$(".item-stock").html("<div style='color: green'>\
-							<i class='fa fa-check'></i> "+qty_display+"</div>");
-					}
-
-					if(r.message.product_info.qty) {
-						qty = r.message.product_info.qty;
-						toggle_update_cart(r.message.product_info.qty);
-					} else {
-						toggle_update_cart(0);
-					}
-				}
-			}
-		}
-	})
-
-	$("#item-add-to-cart button").on("click", function() {
-		frappe.provide('erpnext.shopping_cart');
-
-		erpnext.shopping_cart.update_cart({
-			item_code: get_item_code(),
-			qty: $("#item-spinner .cart-qty").val(),
-			callback: function(r) {
-				if(!r.exc) {
-					toggle_update_cart(1);
-					qty = 1;
-				}
-			},
-			btn: this,
-		});
-	});
-
-	$("#item-spinner").on('click', '.number-spinner button', function () {
-		var btn = $(this),
-			input = btn.closest('.number-spinner').find('input'),
-			oldValue = input.val().trim(),
-			newVal = 0;
-
-		if (btn.attr('data-dir') == 'up') {
-			newVal = Number.parseInt(oldValue) + 1;
-		} else if (btn.attr('data-dir') == 'dwn')  {
-			if (Number.parseInt(oldValue) > 1) {
-				newVal = Number.parseInt(oldValue) - 1;
-			}
-			else {
-				newVal = Number.parseInt(oldValue);
-			}
-		}
-		input.val(newVal);
-	});
-
-	$("[itemscope] .item-view-attribute .form-control").on("change", function() {
-		try {
-			var item_code = encodeURIComponent(get_item_code());
-
-		} catch(e) {
-			// unable to find variant
-			// then chose the closest available one
-
-			var attribute = $(this).attr("data-attribute");
-			var attribute_value = $(this).val();
-			var item_code = find_closest_match(attribute, attribute_value);
-
-			if (!item_code) {
-				frappe.msgprint(__("Cannot find a matching Item. Please select some other value for {0}.", [attribute]))
-				throw e;
-			}
-		}
-
-		if (window.location.search == ("?variant=" + item_code) || window.location.search.includes(item_code)) {
-			return;
-		}
-
-		window.location.href = window.location.pathname + "?variant=" + item_code;
-	});
-
-	// change the item image src when alternate images are hovered
-	$(document.body).on('mouseover', '.item-alternative-image', (e) => {
-		const $alternative_image = $(e.currentTarget);
-		const src = $alternative_image.find('img').prop('src');
-		$('.item-image img').prop('src', src);
-	});
-});
-
-var toggle_update_cart = function(qty) {
-	$("#item-add-to-cart").toggle(qty ? false : true);
-	$("#item-update-cart")
-		.toggle(qty ? true : false)
-		.find("input").val(qty);
-	$("#item-spinner").toggle(qty ? false : true);
-}
-
-function get_item_code() {
-	var variant_info = window.variant_info;
-	if(variant_info) {
-		var attributes = get_selected_attributes();
-		var no_of_attributes = Object.keys(attributes).length;
-
-		for(var i in variant_info) {
-			var variant = variant_info[i];
-
-			if (variant.attributes.length < no_of_attributes) {
-				// the case when variant has less attributes than template
-				continue;
-			}
-
-			var match = true;
-			for(var j in variant.attributes) {
-				if(attributes[variant.attributes[j].attribute]
-					!= variant.attributes[j].attribute_value
-				) {
-					match = false;
-					break;
-				}
-			}
-			if(match) {
-				return variant.name;
-			}
-		}
-		throw "Unable to match variant";
-	} else {
-		return window.item_code;
-	}
-}
-
-function find_closest_match(selected_attribute, selected_attribute_value) {
-	// find the closest match keeping the selected attribute in focus and get the item code
-
-	var attributes = get_selected_attributes();
-
-	var previous_match_score = 0;
-	var previous_no_of_attributes = 0;
-	var matched;
-
-	var variant_info = window.variant_info;
-	for(var i in variant_info) {
-		var variant = variant_info[i];
-		var match_score = 0;
-		var has_selected_attribute = false;
-
-		for(var j in variant.attributes) {
-			if(attributes[variant.attributes[j].attribute]===variant.attributes[j].attribute_value) {
-				match_score = match_score + 1;
-
-				if (variant.attributes[j].attribute==selected_attribute && variant.attributes[j].attribute_value==selected_attribute_value) {
-					has_selected_attribute = true;
-				}
-			}
-		}
-
-		if (has_selected_attribute
-			&& ((match_score > previous_match_score) || (match_score==previous_match_score && previous_no_of_attributes < variant.attributes.length))) {
-			previous_match_score = match_score;
-			matched = variant;
-			previous_no_of_attributes = variant.attributes.length;
-
-
-		}
-	}
-
-	if (matched) {
-		for (var j in matched.attributes) {
-			var attr = matched.attributes[j];
-			$('[itemscope]')
-				.find(repl('.item-view-attribute .form-control[data-attribute="%(attribute)s"]', attr))
-				.val(attr.attribute_value);
-		}
-
-		return matched.name;
-	}
-}
-
-function get_selected_attributes() {
-	var attributes = {};
-	$('[itemscope]').find(".item-view-attribute .form-control").each(function() {
-		attributes[$(this).attr('data-attribute')] = $(this).val();
-	});
-	return attributes;
-}
diff --git a/erpnext/templates/includes/rfq/rfq_macros.html b/erpnext/templates/includes/rfq/rfq_macros.html
index 88724c3..78ec6ff 100644
--- a/erpnext/templates/includes/rfq/rfq_macros.html
+++ b/erpnext/templates/includes/rfq/rfq_macros.html
@@ -1,19 +1,25 @@
 {% from "erpnext/templates/includes/macros.html" import product_image_square, product_image %}
 
 {% macro item_name_and_description(d, doc) %}
-    <div class="row">
-        <div class="col-3">
-			{{ product_image(d.image) }}
-        </div>
-        <div class="col-9">
-            {{ d.item_code }}
-            <p class="text-muted small">{{ d.description }}</p>
+	<div class="row">
+		<div class="col-3">
+			{% if d.image %}
+				{{ product_image(d.image) }}
+			{% else %}
+				<div class="website-image h-100 w-100" style="background-color:var(--gray-100);text-align: center;line-height: 3.6;">
+					{{ frappe.utils.get_abbr(d.item_name)}}
+				</div>
+			{% endif %}
+		</div>
+		<div class="col-9">
+			{{ d.item_code }}
+			<p class="text-muted small">{{ d.description }}</p>
 			{% set supplier_part_no = frappe.db.get_value("Item Supplier", {'parent': d.item_code, 'supplier': doc.supplier}, "supplier_part_no") %}
 			<p class="text-muted small supplier-part-no">
 				{% if supplier_part_no %}
 					{{_("Supplier Part No") + ": "+ supplier_part_no}}
 				{% endif %}
 			</p>
-        </div>
-    </div>
+		</div>
+	</div>
 {% endmacro %}
diff --git a/erpnext/templates/includes/transaction_row.html b/erpnext/templates/includes/transaction_row.html
index 72d498c..a498ba0 100644
--- a/erpnext/templates/includes/transaction_row.html
+++ b/erpnext/templates/includes/transaction_row.html
@@ -15,10 +15,14 @@
 				{{ doc.items_preview }}
 			</div>
 		</div>
-		{% if doc.get('grand_total') %}
+		{% if doc.is_rounded_total_disabled() and doc.get('grand_total') %}
 			<div class="col-sm-3 text-right font-weight-bold item-total">
 				{{ doc.get_formatted("grand_total") }}
 			</div>
+		{% elif doc.get('rounded_total') %}
+			<div class="col-sm-3 text-right font-weight-bold item-total">
+				{{ doc.get_formatted("rounded_total") }}
+			</div>
 		{% endif %}
 	</div>
 	<a class="transaction-item-link" href="/{{ pathname }}/{{ doc.name }}">Link</a>
diff --git a/erpnext/templates/pages/cart.html b/erpnext/templates/pages/cart.html
deleted file mode 100644
index 2b7d9e3..0000000
--- a/erpnext/templates/pages/cart.html
+++ /dev/null
@@ -1,132 +0,0 @@
-{% extends "templates/web.html" %}
-
-{% block title %} {{ _("Shopping Cart") }} {% endblock %}
-
-{% block header %}<h3 class="shopping-cart-header mt-2 mb-6">{{ _("Shopping Cart") }}</h1>{% endblock %}
-
-{% block header_actions %}
-{% endblock %}
-
-{% block page_content %}
-
-{% from "templates/includes/macros.html" import item_name_and_description %}
-
-{% if doc.items %}
-<div class="cart-container">
-	<div class="row m-0">
-		<!-- Left section -->
-		<div class="col-md-8">
-			<div class="frappe-card p-5 mb-4">
-				<div id="cart-error" class="alert alert-danger" style="display: none;"></div>
-				<div class="cart-items-header">
-					{{ _('Items') }}
-				</div>
-				<table class="table mt-3 cart-table">
-					<thead>
-						<tr>
-							<th class="item-column">{{ _('Item') }}</th>
-							<th width="20%">{{ _('Quantity') }}</th>
-							{% if cart_settings.enable_checkout or cart_settings.show_price_in_quotation %}
-								<th width="20" class="text-right column-sm-view">{{ _('Subtotal') }}</th>
-							{% endif %}
-							<th width="10%" class="column-sm-view"></th>
-						</tr>
-					</thead>
-					<tbody class="cart-items">
-						{% include "templates/includes/cart/cart_items.html" %}
-					</tbody>
-
-					{% if cart_settings.enable_checkout or cart_settings.show_price_in_quotation %}
-						<tfoot class="cart-tax-items">
-							{% include "templates/includes/cart/cart_items_total.html" %}
-						</tfoot>
-					{% endif %}
-				</table>
-
-				<div class="row mt-2">
-					<div class="col-3">
-						{% if cart_settings.enable_checkout %}
-							<a class="btn btn-primary-light font-md" href="/orders">
-								{{ _('Past Orders') }}
-							</a>
-						{% else %}
-							<a class="btn btn-primary-light font-md" href="/quotations">
-								{{ _('Past Quotes') }}
-							</a>
-						{% endif %}
-					</div>
-					<div class="col-9">
-						{% if doc.items %}
-						<div class="place-order-container">
-							<a class="btn btn-primary-light mr-2 font-md" href="/all-products">
-								{{ _('Continue Shopping') }}
-							</a>
-						</div>
-						{% endif %}
-					</div>
-				</div>
-			</div>
-
-			<!-- Terms and Conditions -->
-			{% if doc.items %}
-				{% if doc.terms %}
-					<div class="t-and-c-container mt-4 frappe-card">
-						<h5>{{ _("Terms and Conditions") }}</h5>
-						<div class="t-and-c-terms mt-2">
-							{{ doc.terms }}
-						</div>
-					</div>
-				{% endif %}
-		</div>
-
-		<!-- Right section -->
-		<div class="col-md-4">
-			<div class="cart-payment-addresses">
-				<!-- Apply Coupon Code  -->
-				{% set show_coupon_code = cart_settings.show_apply_coupon_code_in_website and cart_settings.enable_checkout %}
-				{% if show_coupon_code == 1%}
-					<div class="mb-3">
-						<div class="row no-gutters">
-							<input type="text" class="txtcoupon form-control mr-3 w-50 font-md" placeholder="Enter Coupon Code" name="txtcouponcode"  ></input>
-							<button class="btn btn-primary btn-sm bt-coupon font-md">{{ _("Apply Coupon Code") }}</button>
-							<input type="hidden" class="txtreferral_sales_partner font-md" placeholder="Enter Sales Partner" name="txtreferral_sales_partner" type="text"></input>
-							</div>
-					</div>
-				{% endif %}
-
-				<div class="mb-3 frappe-card p-5 payment-summary">
-					{% include "templates/includes/cart/cart_payment_summary.html" %}
-				</div>
-
-				{% include "templates/includes/cart/cart_address.html" %}
-			</div>
-		</div>
-		{% endif %}
-	</div>
-</div>
-{% else %}
-<div class="cart-empty frappe-card">
-	<div class="cart-empty-state">
-		<img src="/assets/erpnext/images/ui-states/cart-empty-state.png" alt="Empty State">
-	</div>
-	<div class="cart-empty-message mt-4">{{ _('Your cart is Empty') }}</p>
-	{% if cart_settings.enable_checkout %}
-		<a class="btn btn-outline-primary" href="/orders" style="font-size: 16px;">
-			{{ _('See past orders') }}
-		</a>
-		{% else %}
-		<a class="btn btn-outline-primary" href="/quotations" style="font-size: 16px;">
-			{{ _('See past quotations') }}
-		</a>
-	{% endif %}
-</div>
-{% endif %}
-
-{% endblock %}
-
-{% block base_scripts %}
-<!-- js should be loaded in body! -->
-{{ include_script("frappe-web.bundle.js") }}
-{{ include_script("controls.bundle.js") }}
-{{ include_script("dialog.bundle.js") }}
-{% endblock %}
diff --git a/erpnext/templates/pages/cart.js b/erpnext/templates/pages/cart.js
deleted file mode 100644
index fb2d159..0000000
--- a/erpnext/templates/pages/cart.js
+++ /dev/null
@@ -1,303 +0,0 @@
-// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-// License: GNU General Public License v3. See license.txt
-
-// JS exclusive to /cart page
-frappe.provide("erpnext.e_commerce.shopping_cart");
-var shopping_cart = erpnext.e_commerce.shopping_cart;
-
-$.extend(shopping_cart, {
-	show_error: function(title, text) {
-		$("#cart-container").html('<div class="msg-box"><h4>' +
-			title + '</h4><p class="text-muted">' + text + '</p></div>');
-	},
-
-	bind_events: function() {
-		shopping_cart.bind_address_picker_dialog();
-		shopping_cart.bind_place_order();
-		shopping_cart.bind_request_quotation();
-		shopping_cart.bind_change_qty();
-		shopping_cart.bind_remove_cart_item();
-		shopping_cart.bind_change_notes();
-		shopping_cart.bind_coupon_code();
-	},
-
-	bind_address_picker_dialog: function() {
-		const d = this.get_update_address_dialog();
-		this.parent.find('.btn-change-address').on('click', (e) => {
-			const type = $(e.currentTarget).parents('.address-container').attr('data-address-type');
-			$(d.get_field('address_picker').wrapper).html(
-				this.get_address_template(type)
-			);
-			d.show();
-		});
-	},
-
-	get_update_address_dialog() {
-		let d = new frappe.ui.Dialog({
-			title: "Select Address",
-			fields: [{
-				'fieldtype': 'HTML',
-				'fieldname': 'address_picker',
-			}],
-			primary_action_label: __('Set Address'),
-			primary_action: () => {
-				const $card = d.$wrapper.find('.address-card.active');
-				const address_type = $card.closest('[data-address-type]').attr('data-address-type');
-				const address_name = $card.closest('[data-address-name]').attr('data-address-name');
-				frappe.call({
-					type: "POST",
-					method: "erpnext.e_commerce.shopping_cart.cart.update_cart_address",
-					freeze: true,
-					args: {
-						address_type,
-						address_name
-					},
-					callback: function(r) {
-						d.hide();
-						if (!r.exc) {
-							$(".cart-tax-items").html(r.message.total);
-							shopping_cart.parent.find(
-								`.address-container[data-address-type="${address_type}"]`
-							).html(r.message.address);
-						}
-					}
-				});
-			}
-		});
-
-		return d;
-	},
-
-	get_address_template(type) {
-		return {
-			shipping: `<div class="mb-3" data-section="shipping-address">
-				<div class="row no-gutters" data-fieldname="shipping_address_name">
-					{% for address in shipping_addresses %}
-						<div class="mr-3 mb-3 w-100" data-address-name="{{address.name}}" data-address-type="shipping"
-							{% if doc.shipping_address_name == address.name %} data-active {% endif %}>
-							{% include "templates/includes/cart/address_picker_card.html" %}
-						</div>
-					{% endfor %}
-				</div>
-			</div>`,
-			billing: `<div class="mb-3" data-section="billing-address">
-				<div class="row no-gutters" data-fieldname="customer_address">
-					{% for address in billing_addresses %}
-						<div class="mr-3 mb-3 w-100" data-address-name="{{address.name}}" data-address-type="billing"
-							{% if doc.shipping_address_name == address.name %} data-active {% endif %}>
-							{% include "templates/includes/cart/address_picker_card.html" %}
-						</div>
-					{% endfor %}
-				</div>
-			</div>`,
-		}[type];
-	},
-
-	bind_place_order: function() {
-		$(".btn-place-order").on("click", function() {
-			shopping_cart.place_order(this);
-		});
-	},
-
-	bind_request_quotation: function() {
-		$('.btn-request-for-quotation').on('click', function() {
-			shopping_cart.request_quotation(this);
-		});
-	},
-
-	bind_change_qty: function() {
-		// bind update button
-		$(".cart-items").on("change", ".cart-qty", function() {
-			var item_code = $(this).attr("data-item-code");
-			var newVal = $(this).val();
-			shopping_cart.shopping_cart_update({item_code, qty: newVal});
-		});
-
-		$(".cart-items").on('click', '.number-spinner button', function () {
-			var btn = $(this),
-				input = btn.closest('.number-spinner').find('input'),
-				oldValue = input.val().trim(),
-				newVal = 0;
-
-			if (btn.attr('data-dir') == 'up') {
-				newVal = parseInt(oldValue) + 1;
-			} else {
-				if (oldValue > 1) {
-					newVal = parseInt(oldValue) - 1;
-				}
-			}
-			input.val(newVal);
-
-			let notes = input.closest("td").siblings().find(".notes").text().trim();
-			var item_code = input.attr("data-item-code");
-			shopping_cart.shopping_cart_update({
-				item_code,
-				qty: newVal,
-				additional_notes: notes
-			});
-		});
-	},
-
-	bind_change_notes: function() {
-		$('.cart-items').on('change', 'textarea', function() {
-			const $textarea = $(this);
-			const item_code = $textarea.attr('data-item-code');
-			const qty = $textarea.closest('tr').find('.cart-qty').val();
-			const notes = $textarea.val();
-			shopping_cart.shopping_cart_update({
-				item_code,
-				qty,
-				additional_notes: notes
-			});
-		});
-	},
-
-	bind_remove_cart_item: function() {
-		$(".cart-items").on("click", ".remove-cart-item", (e) => {
-			const $remove_cart_item_btn = $(e.currentTarget);
-			var item_code = $remove_cart_item_btn.data("item-code");
-
-			shopping_cart.shopping_cart_update({
-				item_code: item_code,
-				qty: 0
-			});
-		});
-	},
-
-	render_tax_row: function($cart_taxes, doc, shipping_rules) {
-		var shipping_selector;
-		if(shipping_rules) {
-			shipping_selector = '<select class="form-control">' + $.map(shipping_rules, function(rule) {
-				return '<option value="' + rule[0] + '">' + rule[1] + '</option>' }).join("\n") +
-			'</select>';
-		}
-
-		var $tax_row = $(repl('<div class="row">\
-			<div class="col-md-9 col-sm-9">\
-				<div class="row">\
-					<div class="col-md-9 col-md-offset-3">' +
-					(shipping_selector || '<p>%(description)s</p>') +
-					'</div>\
-				</div>\
-			</div>\
-			<div class="col-md-3 col-sm-3 text-right">\
-				<p' + (shipping_selector ? ' style="margin-top: 5px;"' : "") + '>%(formatted_tax_amount)s</p>\
-			</div>\
-		</div>', doc)).appendTo($cart_taxes);
-
-		if(shipping_selector) {
-			$tax_row.find('select option').each(function(i, opt) {
-				if($(opt).html() == doc.description) {
-					$(opt).attr("selected", "selected");
-				}
-			});
-			$tax_row.find('select').on("change", function() {
-				shopping_cart.apply_shipping_rule($(this).val(), this);
-			});
-		}
-	},
-
-	apply_shipping_rule: function(rule, btn) {
-		return frappe.call({
-			btn: btn,
-			type: "POST",
-			method: "erpnext.e_commerce.shopping_cart.cart.apply_shipping_rule",
-			args: { shipping_rule: rule },
-			callback: function(r) {
-				if(!r.exc) {
-					shopping_cart.render(r.message);
-				}
-			}
-		});
-	},
-
-	place_order: function(btn) {
-		shopping_cart.freeze();
-
-		return frappe.call({
-			type: "POST",
-			method: "erpnext.e_commerce.shopping_cart.cart.place_order",
-			btn: btn,
-			callback: function(r) {
-				if(r.exc) {
-					shopping_cart.unfreeze();
-					var msg = "";
-					if(r._server_messages) {
-						msg = JSON.parse(r._server_messages || []).join("<br>");
-					}
-
-					$("#cart-error")
-						.empty()
-						.html(msg || frappe._("Something went wrong!"))
-						.toggle(true);
-				} else {
-					$(btn).hide();
-					window.location.href = '/orders/' + encodeURIComponent(r.message);
-				}
-			}
-		});
-	},
-
-	request_quotation: function(btn) {
-		shopping_cart.freeze();
-
-		return frappe.call({
-			type: "POST",
-			method: "erpnext.e_commerce.shopping_cart.cart.request_for_quotation",
-			btn: btn,
-			callback: function(r) {
-				if(r.exc) {
-					shopping_cart.unfreeze();
-					var msg = "";
-					if(r._server_messages) {
-						msg = JSON.parse(r._server_messages || []).join("<br>");
-					}
-
-					$("#cart-error")
-						.empty()
-						.html(msg || frappe._("Something went wrong!"))
-						.toggle(true);
-				} else {
-					$(btn).hide();
-					window.location.href = '/quotations/' + encodeURIComponent(r.message);
-				}
-			}
-		});
-	},
-
-	bind_coupon_code: function() {
-		$(".bt-coupon").on("click", function() {
-			shopping_cart.apply_coupon_code(this);
-		});
-	},
-
-	apply_coupon_code: function(btn) {
-		return frappe.call({
-			type: "POST",
-			method: "erpnext.e_commerce.shopping_cart.cart.apply_coupon_code",
-			btn: btn,
-			args : {
-				applied_code : $('.txtcoupon').val(),
-				applied_referral_sales_partner: $('.txtreferral_sales_partner').val()
-			},
-			callback: function(r) {
-				if (r && r.message){
-					location.reload();
-				}
-			}
-		});
-	}
-});
-
-frappe.ready(function() {
-	if (window.location.pathname === "/cart") {
-		$(".cart-icon").hide();
-	}
-	shopping_cart.parent = $(".cart-container");
-	shopping_cart.bind_events();
-});
-
-function show_terms() {
-	var html = $(".cart-terms").html();
-	frappe.msgprint(html);
-}
diff --git a/erpnext/templates/pages/cart.py b/erpnext/templates/pages/cart.py
deleted file mode 100644
index cadb46f..0000000
--- a/erpnext/templates/pages/cart.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-no_cache = 1
-
-from erpnext.e_commerce.shopping_cart.cart import get_cart_quotation
-
-
-def get_context(context):
-	context.body_class = "product-page"
-	context.update(get_cart_quotation())
diff --git a/erpnext/templates/pages/customer_reviews.html b/erpnext/templates/pages/customer_reviews.html
deleted file mode 100644
index 121bec3..0000000
--- a/erpnext/templates/pages/customer_reviews.html
+++ /dev/null
@@ -1,67 +0,0 @@
-{% extends "templates/web.html" %}
-{% from "erpnext/templates/includes/macros.html" import user_review, ratings_summary %}
-
-{% block title %} {{ _("Customer Reviews") }} {% endblock %}
-
-{% block page_content %}
-<div class="product-container reviews-full-page col-md-12">
-	{% if enable_reviews %}
-		<!-- Title and Action -->
-		<div class="w-100 mb-6 d-flex">
-			<div class="reviews-header col-9">
-				{{ _("Customer Reviews") }}
-			</div>
-
-			<div class="write-a-review-btn col-3">
-				<!-- Write a Review for legitimate users -->
-				{% if frappe.session.user != "Guest" and user_is_customer %}
-					<button class="btn btn-write-review"
-						data-web-item="{{ web_item }}">
-						{{ _("Write a Review") }}
-					</button>
-				{% endif %}
-			</div>
-		</div>
-
-		<!-- Summary -->
-		{{ ratings_summary(reviews, reviews_per_rating, average_rating, average_whole_rating, for_summary=True, total_reviews=total_reviews) }}
-
-
-		<!-- Reviews and Comments -->
-		<div class="mt-8">
-			{% if reviews %}
-				{{ user_review(reviews) }}
-
-				{% if not reviews | len >= total_reviews %}
-					<button class="btn btn-light btn-view-more mr-2 mt-4 mb-4 w-30"
-						data-web-item="{{ web_item }}">
-						{{ _("View More") }}
-					</button>
-				{% endif %}
-
-			{% else %}
-				<h6 class="text-muted mt-6">
-					{{ _("No Reviews") }}
-				</h6>
-			{% endif %}
-		</div>
-	{% else %}
-		<!-- If reviews are disabled -->
-		<div class="text-center">
-			<h3 class="text-muted mt-8">
-				{{ _("No Reviews") }}
-			</h3>
-		</div>
-	{% endif %}
-</div>
-
-{% endblock %}
-
-{% block base_scripts %}
-<!-- js should be loaded in body! -->
-<script type="text/javascript" src="/assets/frappe/js/lib/jquery/jquery.min.js"></script>
-<script type="text/javascript" src="/assets/js/frappe-web.min.js"></script>
-<script type="text/javascript" src="/assets/js/control.min.js"></script>
-<script type="text/javascript" src="/assets/js/dialog.min.js"></script>
-<script type="text/javascript" src="/assets/js/bootstrap-4-web.min.js"></script>
-{% endblock %}
\ No newline at end of file
diff --git a/erpnext/templates/pages/customer_reviews.py b/erpnext/templates/pages/customer_reviews.py
deleted file mode 100644
index c1f0c93..0000000
--- a/erpnext/templates/pages/customer_reviews.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-import frappe
-
-from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import (
-	get_shopping_cart_settings,
-)
-from erpnext.e_commerce.doctype.item_review.item_review import get_item_reviews
-from erpnext.e_commerce.doctype.website_item.website_item import check_if_user_is_customer
-
-
-def get_context(context):
-	context.body_class = "product-page"
-	context.no_cache = 1
-	context.full_page = True
-	context.reviews = None
-
-	if frappe.form_dict and frappe.form_dict.get("web_item"):
-		context.web_item = frappe.form_dict.get("web_item")
-		context.user_is_customer = check_if_user_is_customer()
-		context.enable_reviews = get_shopping_cart_settings().enable_reviews
-
-		if context.enable_reviews:
-			reviews_data = get_item_reviews(context.web_item)
-			context.update(reviews_data)
diff --git a/erpnext/templates/pages/home.html b/erpnext/templates/pages/home.html
index 27d966a..08e0432 100644
--- a/erpnext/templates/pages/home.html
+++ b/erpnext/templates/pages/home.html
@@ -17,9 +17,6 @@
 			<h3 class="d-block d-sm-none">{{ homepage.description }}</h3>
 		</div>
 
-		<div class="container">
-			<a href="{{ explore_link }}" class="mb-5 btn btn-primary">{{ _('Explore') }}</a>
-		</div>
 	</section>
 	{% elif homepage.hero_section_based_on == 'Slideshow' and slideshow %}
 	<section class="hero-section">
@@ -29,26 +26,6 @@
 		{{ render_homepage_section(homepage.hero_section_doc) }}
 	{% endif %}
 
-	{% if homepage.products %}
-	<section class="container section-products my-5">
-		<h3>{{ _('Products') }}</h3>
-
-		<div class="row">
-			{% for item in homepage.products %}
-			<div class="col-md-4 mb-4">
-				<div class="card h-100 justify-content-between">
-					<img class="card-img-top website-image-extra-large" src="{{ item.image }}" loading="lazy" alt="{{ item.item_name }}"></img>
-					<div class="card-body flex-grow-0">
-						<h5 class="card-title">{{ item.item_name }}</h5>
-						<a href="{{ item.route }}" class="card-link">{{ _('More details') }}</a>
-					</div>
-				</div>
-			</div>
-			{% endfor %}
-		</div>
-	</section>
-	{% endif %}
-
 	{% if blogs %}
 	<section class="container my-5">
 		<h3>{{ _('Publications') }}</h3>
diff --git a/erpnext/templates/pages/home.py b/erpnext/templates/pages/home.py
index 47fb89d..751a5b0 100644
--- a/erpnext/templates/pages/home.py
+++ b/erpnext/templates/pages/home.py
@@ -10,11 +10,6 @@
 def get_context(context):
 	homepage = frappe.get_cached_doc("Homepage")
 
-	for item in homepage.products:
-		route = frappe.db.get_value("Website Item", {"item_code": item.item_code}, "route")
-		if route:
-			item.route = "/" + route
-
 	homepage.title = homepage.title or homepage.company
 	context.title = homepage.title
 	context.homepage = homepage
@@ -52,5 +47,3 @@
 	context.metatags = context.metatags or frappe._dict({})
 	context.metatags.image = homepage.hero_image or None
 	context.metatags.description = homepage.description or None
-
-	context.explore_link = "/all-products"
diff --git a/erpnext/templates/pages/integrations/gocardless_checkout.html b/erpnext/templates/pages/integrations/gocardless_checkout.html
deleted file mode 100644
index 6072db4..0000000
--- a/erpnext/templates/pages/integrations/gocardless_checkout.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% extends "templates/web.html" %}
-
-{% block title %} Payment {% endblock %}
-
-{%- block header -%}{% endblock %}
-
-{% block script %}
-<script>{% include "templates/includes/integrations/gocardless_checkout.js" %}</script>
-{% endblock %}
-
-{%- block page_content -%}
-<p class='lead text-center'>
-	<span class='gocardless-loading'>{{ _("Loading Payment System") }}</span>
-</p>
-
-{% endblock %}
diff --git a/erpnext/templates/pages/integrations/gocardless_checkout.py b/erpnext/templates/pages/integrations/gocardless_checkout.py
deleted file mode 100644
index 655be52..0000000
--- a/erpnext/templates/pages/integrations/gocardless_checkout.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-import json
-
-import frappe
-from frappe import _
-from frappe.utils import flt, get_url
-
-from erpnext.erpnext_integrations.doctype.gocardless_settings.gocardless_settings import (
-	get_gateway_controller,
-	gocardless_initialization,
-)
-
-no_cache = 1
-
-expected_keys = (
-	"amount",
-	"title",
-	"description",
-	"reference_doctype",
-	"reference_docname",
-	"payer_name",
-	"payer_email",
-	"order_id",
-	"currency",
-)
-
-
-def get_context(context):
-	context.no_cache = 1
-
-	# all these keys exist in form_dict
-	if not (set(expected_keys) - set(frappe.form_dict.keys())):
-		for key in expected_keys:
-			context[key] = frappe.form_dict[key]
-
-		context["amount"] = flt(context["amount"])
-
-		gateway_controller = get_gateway_controller(context.reference_docname)
-		context["header_img"] = frappe.db.get_value(
-			"GoCardless Settings", gateway_controller, "header_img"
-		)
-
-	else:
-		frappe.redirect_to_message(
-			_("Some information is missing"),
-			_("Looks like someone sent you to an incomplete URL. Please ask them to look into it."),
-		)
-		frappe.local.flags.redirect_location = frappe.local.response.location
-		raise frappe.Redirect
-
-
-@frappe.whitelist(allow_guest=True)
-def check_mandate(data, reference_doctype, reference_docname):
-	data = json.loads(data)
-
-	client = gocardless_initialization(reference_docname)
-
-	payer = frappe.get_doc("Customer", data["payer_name"])
-
-	if payer.customer_type == "Individual" and payer.customer_primary_contact is not None:
-		primary_contact = frappe.get_doc("Contact", payer.customer_primary_contact)
-		prefilled_customer = {
-			"company_name": payer.name,
-			"given_name": primary_contact.first_name,
-		}
-		if primary_contact.last_name is not None:
-			prefilled_customer.update({"family_name": primary_contact.last_name})
-
-		if primary_contact.email_id is not None:
-			prefilled_customer.update({"email": primary_contact.email_id})
-		else:
-			prefilled_customer.update({"email": frappe.session.user})
-
-	else:
-		prefilled_customer = {"company_name": payer.name, "email": frappe.session.user}
-
-	success_url = get_url(
-		"./integrations/gocardless_confirmation?reference_doctype="
-		+ reference_doctype
-		+ "&reference_docname="
-		+ reference_docname
-	)
-
-	try:
-		redirect_flow = client.redirect_flows.create(
-			params={
-				"description": _("Pay {0} {1}").format(data["amount"], data["currency"]),
-				"session_token": frappe.session.user,
-				"success_redirect_url": success_url,
-				"prefilled_customer": prefilled_customer,
-			}
-		)
-
-		return {"redirect_to": redirect_flow.redirect_url}
-
-	except Exception as e:
-		frappe.log_error("GoCardless Payment Error")
-		return {"redirect_to": "/integrations/payment-failed"}
diff --git a/erpnext/templates/pages/integrations/gocardless_confirmation.html b/erpnext/templates/pages/integrations/gocardless_confirmation.html
deleted file mode 100644
index d961c63..0000000
--- a/erpnext/templates/pages/integrations/gocardless_confirmation.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% extends "templates/web.html" %}
-
-{% block title %} Payment {% endblock %}
-
-{%- block header -%}{% endblock %}
-
-{% block script %}
-<script>{% include "templates/includes/integrations/gocardless_confirmation.js" %}</script>
-{% endblock %}
-
-{%- block page_content -%}
-<p class='lead text-center'>
-	<span class='gocardless-loading'>{{ _("Payment Confirmation") }}</span>
-</p>
-
-{% endblock %}
diff --git a/erpnext/templates/pages/integrations/gocardless_confirmation.py b/erpnext/templates/pages/integrations/gocardless_confirmation.py
deleted file mode 100644
index 559aa48..0000000
--- a/erpnext/templates/pages/integrations/gocardless_confirmation.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-import frappe
-from frappe import _
-
-from erpnext.erpnext_integrations.doctype.gocardless_settings.gocardless_settings import (
-	get_gateway_controller,
-	gocardless_initialization,
-)
-
-no_cache = 1
-
-expected_keys = ("redirect_flow_id", "reference_doctype", "reference_docname")
-
-
-def get_context(context):
-	context.no_cache = 1
-
-	# all these keys exist in form_dict
-	if not (set(expected_keys) - set(frappe.form_dict.keys())):
-		for key in expected_keys:
-			context[key] = frappe.form_dict[key]
-
-	else:
-		frappe.redirect_to_message(
-			_("Some information is missing"),
-			_("Looks like someone sent you to an incomplete URL. Please ask them to look into it."),
-		)
-		frappe.local.flags.redirect_location = frappe.local.response.location
-		raise frappe.Redirect
-
-
-@frappe.whitelist(allow_guest=True)
-def confirm_payment(redirect_flow_id, reference_doctype, reference_docname):
-
-	client = gocardless_initialization(reference_docname)
-
-	try:
-		redirect_flow = client.redirect_flows.complete(
-			redirect_flow_id, params={"session_token": frappe.session.user}
-		)
-
-		confirmation_url = redirect_flow.confirmation_url
-		gocardless_success_page = frappe.get_hooks("gocardless_success_page")
-		if gocardless_success_page:
-			confirmation_url = frappe.get_attr(gocardless_success_page[-1])(
-				reference_doctype, reference_docname
-			)
-
-		data = {
-			"mandate": redirect_flow.links.mandate,
-			"customer": redirect_flow.links.customer,
-			"redirect_to": confirmation_url,
-			"redirect_message": "Mandate successfully created",
-			"reference_doctype": reference_doctype,
-			"reference_docname": reference_docname,
-		}
-
-		try:
-			create_mandate(data)
-		except Exception as e:
-			frappe.log_error("GoCardless Mandate Registration Error")
-
-		gateway_controller = get_gateway_controller(reference_docname)
-		frappe.get_doc("GoCardless Settings", gateway_controller).create_payment_request(data)
-
-		return {"redirect_to": confirmation_url}
-
-	except Exception as e:
-		frappe.log_error("GoCardless Payment Error")
-		return {"redirect_to": "/integrations/payment-failed"}
-
-
-def create_mandate(data):
-	data = frappe._dict(data)
-	frappe.logger().debug(data)
-
-	mandate = data.get("mandate")
-
-	if frappe.db.exists("GoCardless Mandate", mandate):
-		return
-
-	else:
-		reference_doc = frappe.db.get_value(
-			data.get("reference_doctype"),
-			data.get("reference_docname"),
-			["reference_doctype", "reference_name"],
-			as_dict=1,
-		)
-		erpnext_customer = frappe.db.get_value(
-			reference_doc.reference_doctype, reference_doc.reference_name, ["customer_name"], as_dict=1
-		)
-
-		try:
-			frappe.get_doc(
-				{
-					"doctype": "GoCardless Mandate",
-					"mandate": mandate,
-					"customer": erpnext_customer.customer_name,
-					"gocardless_customer": data.get("customer"),
-				}
-			).insert(ignore_permissions=True)
-
-		except Exception:
-			frappe.log_error("Gocardless: Unable to create mandate")
diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html
index bc34ad5..97bf487 100644
--- a/erpnext/templates/pages/order.html
+++ b/erpnext/templates/pages/order.html
@@ -1,5 +1,5 @@
 {% extends "templates/web.html" %}
-{% from "erpnext/templates/includes/order/order_macros.html" import item_name_and_description %}
+{% from "erpnext/templates/includes/macros.html" import product_image %}
 
 {% block breadcrumbs %}
 	{% include "templates/includes/breadcrumbs.html" %}
@@ -34,18 +34,6 @@
 				</a>
 			</ul>
 		</div>
-		{% if show_pay_button %}
-			<div class="form-column col-sm-6">
-				<div class="page-header-actions-block" data-html-block="header-actions">
-					<p>
-						<a href="/api/method/erpnext.accounts.doctype.payment_request.payment_request.make_payment_request?dn={{ doc.name }}&dt={{ doc.doctype }}&submit_doc=1&order_type=Shopping Cart"
-							class="btn btn-primary btn-sm" id="pay-for-order">
-							{{ _("Pay") }} {{doc.get_formatted("grand_total") }}
-						</a>
-					</p>
-				</div>
-			</div>
-		{% endif %}
 	</div>
 {% endblock %}
 
@@ -130,42 +118,6 @@
 		</div>
 	</div>
 
-	{% if enabled_checkout and ((doc.doctype=="Sales Order" and doc.per_billed <= 0)
-		or (doc.doctype=="Sales Invoice" and doc.outstanding_amount> 0)) %}
-		<div class="panel panel-default">
-			<div class="panel-collapse">
-				<div class="panel-body text-muted small">
-					<div class="row">
-						<div class="form-column col-sm-6">
-							{% if available_loyalty_points %}
-							<div class="panel-heading">
-								<div class="row">
-									<div class="form-column col-sm-6 address-title">
-										<strong>Loyalty Points</strong>
-									</div>
-								</div>
-							</div>
-
-							<div class="form-group">
-								<div class="h6">Enter Loyalty Points</div>
-								<div class="control-input-wrapper">
-									<div class="control-input">
-										<input class="form-control" type="number" min="0"
-											max="{{ available_loyalty_points }}" id="loyalty-point-to-redeem">
-									</div>
-									<p class="help-box small text-muted d-none d-sm-block"> Available Points: {{
-										available_loyalty_points }} </p>
-								</div>
-							</div>
-							{% endif %}
-						</div>
-					</div>
-				</div>
-			</div>
-		</div>
-	{% endif %}
-
-
 	{% if attachments %}
 		<div class="order-item-table">
 			<div class="row order-items order-item-header text-muted">
@@ -193,15 +145,27 @@
 	{% endif %}
 {% endblock %}
 
-{% block script %}
-	<script> {% include "templates/pages/order.js" %}</script>
-	<script>
-		window.doc_info = {
-			customer: '{{doc.customer}}',
-			doctype: '{{ doc.doctype }}',
-			doctype_name: '{{ doc.name }}',
-			grand_total: '{{ doc.grand_total }}',
-			currency: '{{ doc.currency }}'
-		}
-	</script>
-{% endblock %}
\ No newline at end of file
+{% macro item_name_and_description(d) %}
+	<div class="row item_name_and_description">
+		<div class="col-xs-4 col-sm-2 order-image-col">
+			<div class="order-image h-100">
+				{% if d.thumbnail or d.image %}
+					{{ product_image(d.thumbnail or d.image, no_border=True) }}
+				{% else %}
+					<div class="no-image-cart-item" style="min-height: 100px;">
+						{{ frappe.utils.get_abbr(d.item_name) or "NA" }}
+					</div>
+				{% endif %}
+			</div>
+		</div>
+		<div class="col-xs-8 col-sm-10">
+			{{ d.item_code }}
+			<div class="text-muted small item-description">
+				{{ html2text(d.description) | truncate(140) }}
+			</div>
+			<span class="text-muted mt-2 d-l-n order-qty">
+				{{ _("Qty ") }}({{ d.get_formatted("qty") }})
+			</span>
+		</div>
+	</div>
+{% endmacro %}
\ No newline at end of file
diff --git a/erpnext/templates/pages/order.js b/erpnext/templates/pages/order.js
deleted file mode 100644
index 0574cde..0000000
--- a/erpnext/templates/pages/order.js
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ready(function(){
-
-	var loyalty_points_input = document.getElementById("loyalty-point-to-redeem");
-	var loyalty_points_status = document.getElementById("loyalty-points-status");
-	if (loyalty_points_input) {
-		loyalty_points_input.onblur = apply_loyalty_points;
-	}
-
-	function apply_loyalty_points() {
-		var loyalty_points = parseInt(loyalty_points_input.value);
-		if (loyalty_points) {
-			frappe.call({
-				method: "erpnext.accounts.doctype.loyalty_program.loyalty_program.get_redeemption_factor",
-				args: {
-					"customer": doc_info.customer
-				},
-				callback: function(r) {
-					if (r) {
-						var message = ""
-						let loyalty_amount = flt(r.message*loyalty_points);
-						if (doc_info.grand_total && doc_info.grand_total < loyalty_amount) {
-							let redeemable_amount = parseInt(doc_info.grand_total/r.message);
-							message = "You can only redeem max " + redeemable_amount + " points in this order.";
-							frappe.msgprint(__(message));
-						} else {
-							message = loyalty_points + " Loyalty Points of amount "+ loyalty_amount + " is applied."
-							frappe.msgprint(__(message));
-							var remaining_amount = flt(doc_info.grand_total) - flt(loyalty_amount);
-							var payment_button = document.getElementById("pay-for-order");
-							payment_button.innerHTML = __("Pay Remaining");
-							payment_button.href = "/api/method/erpnext.accounts.doctype.payment_request.payment_request.make_payment_request?dn="+doc_info.doctype_name+"&dt="+doc_info.doctype+"&loyalty_points="+loyalty_points+"&submit_doc=1&order_type=Shopping Cart";
-						}
-						loyalty_points_status.innerHTML = message;
-					}
-				}
-			});
-		}
-	}
-})
diff --git a/erpnext/templates/pages/order.py b/erpnext/templates/pages/order.py
index 13772d3..d0968bf 100644
--- a/erpnext/templates/pages/order.py
+++ b/erpnext/templates/pages/order.py
@@ -4,8 +4,6 @@
 import frappe
 from frappe import _
 
-from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import show_attachments
-
 
 def get_context(context):
 	context.no_cache = 1
@@ -14,17 +12,12 @@
 	if hasattr(context.doc, "set_indicator"):
 		context.doc.set_indicator()
 
-	if show_attachments():
-		context.attachments = get_attachments(frappe.form_dict.doctype, frappe.form_dict.name)
-
 	context.parents = frappe.form_dict.parents
 	context.title = frappe.form_dict.name
 	context.payment_ref = frappe.db.get_value(
 		"Payment Request", {"reference_name": frappe.form_dict.name}, "name"
 	)
 
-	context.enabled_checkout = frappe.get_doc("E Commerce Settings").enable_checkout
-
 	default_print_format = frappe.db.get_value(
 		"Property Setter",
 		dict(property="default_print_format", doc_type=frappe.form_dict.doctype),
diff --git a/erpnext/templates/pages/product_search.html b/erpnext/templates/pages/product_search.html
deleted file mode 100644
index 6a5425b..0000000
--- a/erpnext/templates/pages/product_search.html
+++ /dev/null
@@ -1,32 +0,0 @@
-{% extends "templates/web.html" %}
-
-{% block title %} {{ _("Product Search") }} {% endblock %}
-
-{% block header %}<h2>{{ _("Product Search") }}</h2>{% endblock %}
-
-{% block page_content %}
-<script>{% include "templates/includes/product_list.js" %}</script>
-
-<script>
-frappe.ready(function() {
-	var txt = frappe.utils.get_url_arg("search");
-	$(".search-results").html('{{ _("Search results for") + ": " + html2text(frappe.form_dict.search or "") | e | trim }}');
-	window.search = txt;
-	window.start = 0;
-	window.get_product_list();
-});
-</script>
-
-<div class="product-search-content">
-    <h3 class="search-results">{{ _("Search Results") }}</h3>
-	<div id="search-list" class="row">
-
-	</div>
-	<div style="text-align: center;">
-		<div class="more-btn"
-			style="display: none; text-align: center;">
-            <button class="btn btn-light">{{ _("More...") }}</button>
-		</div>
-	</div>
-</div>
-{% endblock %}
diff --git a/erpnext/templates/pages/product_search.py b/erpnext/templates/pages/product_search.py
deleted file mode 100644
index f40fd47..0000000
--- a/erpnext/templates/pages/product_search.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-import json
-
-import frappe
-from frappe.utils import cint, cstr
-from redis.commands.search.query import Query
-
-from erpnext.e_commerce.redisearch_utils import (
-	WEBSITE_ITEM_CATEGORY_AUTOCOMPLETE,
-	WEBSITE_ITEM_INDEX,
-	WEBSITE_ITEM_NAME_AUTOCOMPLETE,
-	is_redisearch_enabled,
-)
-from erpnext.e_commerce.shopping_cart.product_info import set_product_info_for_website
-from erpnext.setup.doctype.item_group.item_group import get_item_for_list_in_html
-
-no_cache = 1
-
-
-def get_context(context):
-	context.show_search = True
-
-
-@frappe.whitelist(allow_guest=True)
-def get_product_list(search=None, start=0, limit=12):
-	data = get_product_data(search, start, limit)
-
-	for item in data:
-		set_product_info_for_website(item)
-
-	return [get_item_for_list_in_html(r) for r in data]
-
-
-def get_product_data(search=None, start=0, limit=12):
-	# limit = 12 because we show 12 items in the grid view
-	# base query
-	query = """
-		SELECT
-			web_item_name, item_name, item_code, brand, route,
-			website_image, thumbnail, item_group,
-			description, web_long_description as website_description,
-			website_warehouse, ranking
-		FROM `tabWebsite Item`
-		WHERE published = 1
-		"""
-
-	# search term condition
-	if search:
-		query += """ and (item_name like %(search)s
-				or web_item_name like %(search)s
-				or brand like %(search)s
-				or web_long_description like %(search)s)"""
-		search = "%" + cstr(search) + "%"
-
-	# order by
-	query += """ ORDER BY ranking desc, modified desc limit %s offset %s""" % (
-		cint(limit),
-		cint(start),
-	)
-
-	return frappe.db.sql(query, {"search": search}, as_dict=1)  # nosemgrep
-
-
-@frappe.whitelist(allow_guest=True)
-def search(query):
-	product_results = product_search(query)
-	category_results = get_category_suggestions(query)
-
-	return {
-		"product_results": product_results.get("results") or [],
-		"category_results": category_results.get("results") or [],
-	}
-
-
-@frappe.whitelist(allow_guest=True)
-def product_search(query, limit=10, fuzzy_search=True):
-	search_results = {"from_redisearch": True, "results": []}
-
-	if not is_redisearch_enabled():
-		# Redisearch module not enabled
-		search_results["from_redisearch"] = False
-		search_results["results"] = get_product_data(query, 0, limit)
-		return search_results
-
-	if not query:
-		return search_results
-
-	redis = frappe.cache()
-	query = clean_up_query(query)
-
-	# TODO: Check perf/correctness with Suggestions & Query vs only Query
-	# TODO: Use Levenshtein Distance in Query (max=3)
-	redisearch = redis.ft(WEBSITE_ITEM_INDEX)
-	suggestions = redisearch.sugget(
-		WEBSITE_ITEM_NAME_AUTOCOMPLETE,
-		query,
-		num=limit,
-		fuzzy=fuzzy_search and len(query) > 3,
-	)
-
-	# Build a query
-	query_string = query
-
-	for s in suggestions:
-		query_string += f"|('{clean_up_query(s.string)}')"
-
-	q = Query(query_string)
-	results = redisearch.search(q)
-
-	search_results["results"] = list(map(convert_to_dict, results.docs))
-	search_results["results"] = sorted(
-		search_results["results"], key=lambda k: frappe.utils.cint(k["ranking"]), reverse=True
-	)
-
-	return search_results
-
-
-def clean_up_query(query):
-	return "".join(c for c in query if c.isalnum() or c.isspace())
-
-
-def convert_to_dict(redis_search_doc):
-	return redis_search_doc.__dict__
-
-
-@frappe.whitelist(allow_guest=True)
-def get_category_suggestions(query):
-	search_results = {"results": []}
-
-	if not is_redisearch_enabled():
-		# Redisearch module not enabled, query db
-		categories = frappe.db.get_all(
-			"Item Group",
-			filters={"name": ["like", "%{0}%".format(query)], "show_in_website": 1},
-			fields=["name", "route"],
-		)
-		search_results["results"] = categories
-		return search_results
-
-	if not query:
-		return search_results
-
-	ac = frappe.cache().ft()
-	suggestions = ac.sugget(WEBSITE_ITEM_CATEGORY_AUTOCOMPLETE, query, num=10, with_payloads=True)
-
-	results = [json.loads(s.payload) for s in suggestions]
-
-	search_results["results"] = results
-
-	return search_results
diff --git a/erpnext/templates/pages/projects.html b/erpnext/templates/pages/projects.html
index 9fe4338..3b8698f 100644
--- a/erpnext/templates/pages/projects.html
+++ b/erpnext/templates/pages/projects.html
@@ -14,18 +14,16 @@
 
 {% block style %}
   <style>
-    {
-      % include "templates/includes/projects.css"%
-    }
+    {% include "templates/includes/projects.css" %}
   </style>
 {% endblock %}
 
 {% block page_content %}
   <div class="web-list-item transaction-list-item">
     <div class="row align-items-center">
-      <div class="col-sm-4 "><b>Status: {{ doc.status }}</b></div>
-      <div class="col-sm-4 "><b>Progress: {{ doc.percent_complete }}%</b></div>
-      <div class="col-sm-4 "><b>Hours Spent: {{ doc.actual_time | round }}</b></div>
+      <div class="col-sm-4 "><b>{{ _("Status") }}: {{ _(doc.status) }}</b></div>
+      <div class="col-sm-4 "><b>{{ _("Progress") }}: {{ doc.get_formatted("percent_complete") }}</b></div>
+      <div class="col-sm-4 "><b>{{ _("Hours Spent") }}: {{ doc.get_formatted("actual_time") }}</b></div>
     </div>
   </div>
 
@@ -34,7 +32,7 @@
   <hr>
 
   <div class="row align-items-center">
-    <div class="col-sm-6 my-account-header"> <h4>Tasks</h4></div>
+    <div class="col-sm-6 my-account-header"> <h4>{{ _("Tasks") }}</h4></div>
     <div class="col-sm-6 text-right">
       <a class="btn btn-secondary btn-light btn-sm" href='/tasks/new?project={{ doc.project_name }}'>{{ _("New task") }}</a>
     </div>
@@ -44,39 +42,39 @@
     <div class="result">
       <div class="web-list-item transaction-list-item">
         <div class="row align-items-center">
-          <div class="col-sm-4"><b>Tasks</b></div>
-          <div class="col-sm-2"><b>Status</b></div>
-          <div class="col-sm-2"><b>End Date</b></div>
-          <div class="col-sm-2"><b>Assignment</b></div>
-          <div class="col-sm-2"><b>Modified On</b></div>
+          <div class="col-sm-4"><b>{{ _("Tasks") }}</b></div>
+          <div class="col-sm-2"><b>{{ _("Status") }}</b></div>
+          <div class="col-sm-2"><b>{{ _("End Date") }}</b></div>
+          <div class="col-sm-2"><b>{{ _("Assignment") }}</b></div>
+          <div class="col-sm-2"><b>{{ _("Modified On") }}</b></div>
         </div>
       </div>
       {% include "erpnext/templates/includes/projects/project_tasks.html" %}
     </div>
   </div>
   {% else %}
-    {{ empty_state('Task')}}
+    {{ empty_state(_("Task")) }}
   {% endif %}
 
-  <h4 class="my-account-header">Timesheets</h4>
+  <h4 class="my-account-header">{{ _("Timesheets") }}</h4>
   {% if doc.timesheets %}
     <div class="website-list">
       <div class="result">
         <div class="web-list-item transaction-list-item">
           <div class="row align-items-center">
-            <div class="col-xs-2"><b>Timesheet</b></div>
-            <div class="col-xs-2"><b>Status</b></div>
-            <div class="col-xs-2"><b>From</b></div>
-            <div class="col-xs-2"><b>To</b></div>
-            <div class="col-xs-2"><b>Modified By</b></div>
-            <div class="col-xs-2"><b>Modified On</b></div>
+            <div class="col-xs-2"><b>{{ _("Timesheet") }}</b></div>
+            <div class="col-xs-2"><b>{{ _("Status") }}</b></div>
+            <div class="col-xs-2"><b>{{ _("From") }}</b></div>
+            <div class="col-xs-2"><b>{{ _("To") }}</b></div>
+            <div class="col-xs-2"><b>{{ _("Modified By") }}</b></div>
+            <div class="col-xs-2"><b>{{ _("Modified On") }}</b></div>
           </div>
         </div>
       {% include "erpnext/templates/includes/projects/project_timesheets.html" %}
       </div>
     </div>
   {% else %}
-    {{ empty_state('Timesheet')}}
+    {{ empty_state(_("Timesheet")) }}
   {% endif %}
 
   {% if doc.attachments %}
@@ -113,7 +111,7 @@
 
 {% macro progress_bar(percent_complete) %}
 {% if percent_complete %}
-  <span class="small py-2">Project Progress:</span>
+  <span class="small py-2">{{ _("Project Progress:") }}</span>
   <div class="progress progress-hg" style="height: 15px;">
     <div
       class="progress-bar progress-bar-{{ 'warning' if percent_complete|round < 100 else 'success' }} active"\
@@ -133,7 +131,7 @@
         <div>
           <img src="/assets/frappe/images/ui-states/list-empty-state.svg" alt="Generic Empty State" class="null-state">
         </div>
-        <p>You haven't created a {{ section_name }} yet</p>
+        <p>{{ _("You haven't created a {0} yet").format(section_name) }}</p>
       </div>
     </div>
   </div>
diff --git a/erpnext/templates/pages/rfq.html b/erpnext/templates/pages/rfq.html
index 6516482..d371bf2 100644
--- a/erpnext/templates/pages/rfq.html
+++ b/erpnext/templates/pages/rfq.html
@@ -1,7 +1,7 @@
 {% extends "templates/web.html" %}
 
 {% block header %}
-<h1>{{ doc.name }}</h1>
+<h1 style="margin-top: 10px;">{{ doc.name }}</h1>
 {% endblock %}
 
 {% block script %}
@@ -16,7 +16,7 @@
 {% if doc.items %}
 <button class="btn btn-primary btn-sm"
     type="button">
-    {{ _("Submit") }}</button>
+    {{ _("Make Quotation") }}</button>
 {% endif %}
 {% endblock %}
 
diff --git a/erpnext/templates/pages/wishlist.html b/erpnext/templates/pages/wishlist.html
deleted file mode 100644
index 7a81ded..0000000
--- a/erpnext/templates/pages/wishlist.html
+++ /dev/null
@@ -1,28 +0,0 @@
-{% extends "templates/web.html" %}
-
-{% block title %} {{ _("Wishlist") }} {% endblock %}
-
-{% block header %}<h3 class="shopping-cart-header mt-2 mb-6">{{ _("Wishlist") }}</h1>{% endblock %}
-
-{% block page_content %}
-{% if items %}
-	<div class="row">
-		<div class="col-md-12 item-card-group-section">
-			<div class="row products-list">
-					{% from "erpnext/templates/includes/macros.html" import wishlist_card %}
-					{% for item in items %}
-						{{ wishlist_card(item, settings) }}
-					{% endfor %}
-			</div>
-		</div>
-	</div>
-{% else %}
-	<div class="cart-empty frappe-card">
-		<div class="cart-empty-state">
-			<img src="/assets/erpnext/images/ui-states/cart-empty-state.png" alt="Empty Cart">
-		</div>
-		<div class="cart-empty-message mt-4">{{ _('Wishlist is empty!') }}</p>
-	</div>
-{% endif %}
-
-{% endblock %}
\ No newline at end of file
diff --git a/erpnext/templates/pages/wishlist.py b/erpnext/templates/pages/wishlist.py
deleted file mode 100644
index 17607e4..0000000
--- a/erpnext/templates/pages/wishlist.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-import frappe
-
-from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import (
-	get_shopping_cart_settings,
-)
-from erpnext.e_commerce.shopping_cart.cart import _set_price_list
-from erpnext.utilities.product import get_price
-
-
-def get_context(context):
-	is_guest = frappe.session.user == "Guest"
-
-	settings = get_shopping_cart_settings()
-	items = get_wishlist_items() if not is_guest else []
-	selling_price_list = _set_price_list(settings) if not is_guest else None
-
-	items = set_stock_price_details(items, settings, selling_price_list)
-
-	context.body_class = "product-page"
-	context.items = items
-	context.settings = settings
-	context.no_cache = 1
-
-
-def get_stock_availability(item_code, warehouse):
-	from erpnext.stock.doctype.warehouse.warehouse import get_child_warehouses
-
-	if warehouse and frappe.get_cached_value("Warehouse", warehouse, "is_group") == 1:
-		warehouses = get_child_warehouses(warehouse)
-	else:
-		warehouses = [warehouse] if warehouse else []
-
-	stock_qty = 0.0
-	for warehouse in warehouses:
-		stock_qty += frappe.utils.flt(
-			frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse}, "actual_qty")
-		)
-
-	return bool(stock_qty)
-
-
-def get_wishlist_items():
-	if not frappe.db.exists("Wishlist", frappe.session.user):
-		return []
-
-	return frappe.db.get_all(
-		"Wishlist Item",
-		filters={"parent": frappe.session.user},
-		fields=[
-			"web_item_name",
-			"item_code",
-			"item_name",
-			"website_item",
-			"warehouse",
-			"image",
-			"item_group",
-			"route",
-		],
-	)
-
-
-def set_stock_price_details(items, settings, selling_price_list):
-	for item in items:
-		if settings.show_stock_availability:
-			item.available = get_stock_availability(item.item_code, item.get("warehouse"))
-
-		price_details = get_price(
-			item.item_code, selling_price_list, settings.default_customer_group, settings.company
-		)
-
-		if price_details:
-			item.formatted_price = price_details.get("formatted_price")
-			item.formatted_mrp = price_details.get("formatted_mrp")
-			if item.formatted_mrp:
-				item.discount = price_details.get("formatted_discount_percent") or price_details.get(
-					"formatted_discount_rate"
-				)
-
-	return items
diff --git a/erpnext/tests/test_regional.py b/erpnext/tests/test_regional.py
index 2c16def..55c8bb7 100644
--- a/erpnext/tests/test_regional.py
+++ b/erpnext/tests/test_regional.py
@@ -14,6 +14,3 @@
 	def test_regional_overrides(self):
 		frappe.flags.country = "Maldives"
 		self.assertEqual(test_method(), "original")
-
-		frappe.flags.country = "France"
-		self.assertEqual(test_method(), "overridden")
diff --git a/erpnext/translations/af.csv b/erpnext/translations/af.csv
index 218bd69..f457314 100644
--- a/erpnext/translations/af.csv
+++ b/erpnext/translations/af.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Outo-herhaal dokument opgedateer,
 Automotive,Automotive,
 Available,beskikbaar,
-Available Leaves,Beskikbare blare,
 Available Qty,Beskikbare hoeveelheid,
 Available Selling,Beskikbaar verkoop,
 Available for use date is required,Beskikbaar vir gebruik datum is nodig,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub-sinkronisasie-ID,
 Human Resource,Menslike hulpbronne,
 Human Resources,Menslike hulpbronne,
-IFSC Code,IFSC-kode,
 IGST Amount,IGST Bedrag,
 IP Address,IP adres,
 ITC Available (whether in full op part),ITC beskikbaar (of dit volledig is),
@@ -1666,7 +1664,6 @@
 Other,ander,
 Other Reports,Ander verslae,
 "Other outward supplies(Nil rated,Exempted)","Ander voorrade (nul beoordeel, vrygestel)",
-Others,ander,
 Out Qty,Uit Aantal,
 Out Value,Uitwaarde,
 Out of Order,Buite werking,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Totaal (Sonder Belasting),
 Total Achieved,Totaal behaal,
 Total Actual,Totaal Werklik,
-Total Allocated Leaves,Totale toegekende blare,
 Total Amount,Totale bedrag,
 Total Amount Credited,Totale bedrag gekrediteer,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Totale Toepaslike Koste in Aankoopontvangste-items moet dieselfde wees as Totale Belasting en Heffings,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Laai jou briefhoof en logo op. (jy kan dit later wysig).,
 Upper Income,Boonste Inkomste,
 Use Sandbox,Gebruik Sandbox,
-Used Leaves,Gebruikte Blare,
 User,gebruiker,
 User ID,Gebruikers-ID,
 User ID not set for Employee {0},Gebruiker ID nie ingestel vir Werknemer {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Garantie Periode (in dae),
 Auto re-order,Outo herbestel,
 Reorder level based on Warehouse,Herbestel vlak gebaseer op Warehouse,
-Will also apply for variants unless overrridden,Sal ook aansoek doen vir variante tensy dit oortree word,
+Will also apply for variants unless overridden,Sal ook aansoek doen vir variante tensy dit oortree word,
 Units of Measure,Eenhede van maatreël,
 Will also apply for variants,Sal ook aansoek doen vir variante,
 Serial Nos and Batches,Serial Nos and Batches,
@@ -7949,12 +7944,10 @@
 Approvers,Betogers,
 The first Approver in the list will be set as the default Approver.,Die eerste goedkeuring in die lys sal as die standaard goedkeuring gestel word.,
 Shift Request Approver,Goedkeuring vir skofversoek,
-PAN Number,PAN-nommer,
 Provident Fund Account,Voorsorgfondsrekening,
 MICR Code,MICR-kode,
 Repay unclaimed amount from salary,Betaal onopgeëiste bedrag terug van die salaris,
 Deduction from salary,Aftrekking van salaris,
-Expired Leaves,Verlore blare,
 If this is not checked the loan by default will be considered as a Demand Loan,"As dit nie gekontroleer word nie, sal die lening by verstek as &#39;n vraaglening beskou word",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Hierdie rekening word gebruik om lenings van die lener terug te betaal en ook om lenings aan die lener uit te betaal,
 This account is capital account which is used to allocate capital for loan disbursal account ,Hierdie rekening is &#39;n kapitaalrekening wat gebruik word om kapitaal toe te ken vir die uitbetaling van lenings,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Is verpligtend,
 WhatsApp,WhatsApp,
 Make a call,Maak &#39;n oproep,
+Approve,goed te keur,
+Reject,verwerp,
diff --git a/erpnext/translations/am.csv b/erpnext/translations/am.csv
index 3ea1c78..0453d5d 100644
--- a/erpnext/translations/am.csv
+++ b/erpnext/translations/am.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,በቀጥታ ተዘምኗል,
 Automotive,አውቶሞቲቭ,
 Available,ይገኛል,
-Available Leaves,የሚገኝ ቅጠሎች,
 Available Qty,ይገኛል ብዛት,
 Available Selling,ሊሸጥ የሚቻል,
 Available for use date is required,ለመጠቀም ቀን ሊገኝ ይችላል,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,የሃብ ማመሳሰል መታወቂያ,
 Human Resource,የሰው ኃይል,
 Human Resources,የሰው ሀይል አስተዳደር,
-IFSC Code,የ IFSC ኮድ,
 IGST Amount,IGST ሂሳብ,
 IP Address,የአይፒ አድራሻ,
 ITC Available (whether in full op part),ITC አለ (በሙሉ ኦፕሬም ክፍል ውስጥም ቢሆን),
@@ -1666,7 +1664,6 @@
 Other,ሌላ,
 Other Reports,ሌሎች ሪፖርቶች,
 "Other outward supplies(Nil rated,Exempted)",ሌሎች የውጪ አቅርቦቶች (ኒል ደረጃ የተሰጠው ፣ ነፃ ...),
-Others,ሌሎች,
 Out Qty,ብዛት ውጪ,
 Out Value,ውጪ ዋጋ,
 Out of Order,ከትዕዛዝ ውጪ,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),ጠቅላላ (ያለ ግብር),
 Total Achieved,ጠቅላላ አሳክቷል,
 Total Actual,ትክክለኛ ጠቅላላ,
-Total Allocated Leaves,ጠቅላላ ድጐማዎችን,
 Total Amount,አጠቃላይ ድምሩ,
 Total Amount Credited,ጠቅላላ መጠን ተቀጠረ,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,የግዢ ደረሰኝ ንጥሎች ሰንጠረዥ ውስጥ ጠቅላላ የሚመለከታቸው ክፍያዎች ጠቅላላ ግብሮች እና ክፍያዎች እንደ አንድ አይነት መሆን አለበት,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,የእርስዎን ደብዳቤ ራስ እና አርማ ይስቀሉ. (ቆይተው አርትዕ ማድረግ ይችላሉ).,
 Upper Income,የላይኛው ገቢ,
 Use Sandbox,ይጠቀሙ ማጠሪያ,
-Used Leaves,ጥቅም ላይ የዋሉ ቅጠሎች,
 User,ተጠቃሚው,
 User ID,የተጠቃሚው መለያ,
 User ID not set for Employee {0},የተጠቃሚ መታወቂያ ሰራተኛ ለ ካልተዋቀረ {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),(ቀናት ውስጥ) የዋስትና ክፍለ ጊዜ,
 Auto re-order,ራስ-ዳግም-ትዕዛዝ,
 Reorder level based on Warehouse,መጋዘን ላይ የተመሠረተ አስይዝ ደረጃ,
-Will also apply for variants unless overrridden,overrridden በስተቀር ደግሞ ተለዋጮች ማመልከት ይሆን,
+Will also apply for variants unless overridden,overridden በስተቀር ደግሞ ተለዋጮች ማመልከት ይሆን,
 Units of Measure,ይለኩ አሃዶች,
 Will also apply for variants,በተጨማሪም ተለዋጮች ማመልከት ይሆን,
 Serial Nos and Batches,ተከታታይ ቁጥሮች እና ቡድኖች,
@@ -7949,12 +7944,10 @@
 Approvers,አወዛጋቢ,
 The first Approver in the list will be set as the default Approver.,በዝርዝሩ ውስጥ የመጀመሪያው አጽዳቂ እንደ ነባሪው ማጽደቂያ ይቀመጣል።,
 Shift Request Approver,የሺፍት ጥያቄ ማጽደቅ,
-PAN Number,የፓን ቁጥር,
 Provident Fund Account,የፕሮቪደንት ፈንድ ሂሳብ,
 MICR Code,MICR ኮድ,
 Repay unclaimed amount from salary,ከደመወዝ ያልተጠየቀውን መጠን ይክፈሉ,
 Deduction from salary,ከደመወዝ መቀነስ,
-Expired Leaves,ጊዜው ያለፈባቸው ቅጠሎች,
 If this is not checked the loan by default will be considered as a Demand Loan,ይህ ካልተረጋገጠ ብድሩ በነባሪነት እንደ ብድር ይቆጠራል,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,ይህ ሂሳብ ከተበዳሪው የብድር ክፍያዎችን ለማስያዝ እና እንዲሁም ለተበዳሪው ብድሮችን ለማሰራጨት ያገለግላል,
 This account is capital account which is used to allocate capital for loan disbursal account ,ይህ አካውንት ለብድር ማስከፈያ ሂሳብ ካፒታል ለመመደብ የሚያገለግል የካፒታል ሂሳብ ነው,
@@ -8748,3 +8741,5 @@
 Is Mandatory,አስገዳጅ ነው,
 WhatsApp,ዋትስአፕ,
 Make a call,ደውል,
+Approve,ማጽደቅ,
+Reject,አይቀበሉ,
diff --git a/erpnext/translations/ar.csv b/erpnext/translations/ar.csv
index 5858a25..67b409e 100644
--- a/erpnext/translations/ar.csv
+++ b/erpnext/translations/ar.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,تكرار تلقائي للمستندات المحدثة,
 Automotive,سيارات,
 Available,متاح,
-Available Leaves,المغادارت والاجازات المتاحة,
 Available Qty,الكمية المتاحة,
 Available Selling,المبيعات المتاحة,
 Available for use date is required,مطلوب تاريخ متاح للاستخدام,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,معرف مزامنة المحور,
 Human Resource,Human Resource,
 Human Resources,الموارد البشرية,
-IFSC Code,رمز IFSC,
 IGST Amount,كمية IGST,
 IP Address,عنوان IP,
 ITC Available (whether in full op part),مركز التجارة الدولية متاح (سواء في جزء المرجع الكامل),
@@ -1666,7 +1664,6 @@
 Other,آخر,
 Other Reports,تقارير أخرى,
 "Other outward supplies(Nil rated,Exempted)",اللوازم الخارجية الأخرى (بدون تقييم ، معفاة),
-Others,بدلات أخرى,
 Out Qty,كمية خارجة,
 Out Value,القيمة الخارجه,
 Out of Order,خارج عن السيطرة,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),الإجمالي (بدون ضريبة),
 Total Achieved,الإجمالي المحقق,
 Total Actual,الإجمالي الفعلي,
-Total Allocated Leaves,مجموع الأوراق المخصصة,
 Total Amount,الاعتماد الأساسي,
 Total Amount Credited,مجموع المبلغ المعتمد,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,مجموع الرسوم المطبقة في شراء طاولة إيصال عناصر يجب أن يكون نفس مجموع الضرائب والرسوم,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,تحميل رئيس رسالتكم والشعار. (يمكنك تحريرها لاحقا).,
 Upper Income,أعلى دخل,
 Use Sandbox,استخدام ساندبوكس,
-Used Leaves,مغادرات مستخدمة,
 User,المستعمل,
 User ID,تعريف المستخدم,
 User ID not set for Employee {0},هوية المستخدم لم يتم تعيين موظف ل {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),فترة الضمان (بالأيام),
 Auto re-order,إعادة ترتيب تلقائي,
 Reorder level based on Warehouse,مستوى إعادة الطلب بناء على مستودع,
-Will also apply for variants unless overrridden,سوف تطبق أيضا على المتغيرات الا اذا تم التغير فوقها,
+Will also apply for variants unless overridden,سوف تطبق أيضا على المتغيرات الا اذا تم التغير فوقها,
 Units of Measure,وحدات القياس,
 Will also apply for variants,سوف تطبق أيضا على المتغيرات,
 Serial Nos and Batches,الرقم التسلسلي ودفعات,
@@ -7949,12 +7944,10 @@
 Approvers,الموافقون,
 The first Approver in the list will be set as the default Approver.,سيتم تعيين الموافق الأول في القائمة باعتباره الموافق الافتراضي.,
 Shift Request Approver,الموافق على طلب التحول,
-PAN Number,رقم PAN,
 Provident Fund Account,حساب صندوق الادخار,
 MICR Code,كود MICR,
 Repay unclaimed amount from salary,سداد المبلغ غير المطالب به من الراتب,
 Deduction from salary,خصم من الراتب,
-Expired Leaves,أوراق منتهية الصلاحية,
 If this is not checked the loan by default will be considered as a Demand Loan,إذا لم يتم التحقق من ذلك ، فسيتم اعتبار القرض بشكل افتراضي كقرض تحت الطلب,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,يستخدم هذا الحساب لحجز أقساط سداد القرض من المقترض وأيضًا صرف القروض للمقترض,
 This account is capital account which is used to allocate capital for loan disbursal account ,هذا الحساب هو حساب رأس المال الذي يستخدم لتخصيص رأس المال لحساب صرف القرض,
@@ -8748,3 +8741,5 @@
 Is Mandatory,إلزامي,
 WhatsApp,ال WhatsApp,
 Make a call,إجراء مكالمة,
+Approve,وافق,
+Reject,رفض,
diff --git a/erpnext/translations/bg.csv b/erpnext/translations/bg.csv
index 8c94c5c..787f81e 100644
--- a/erpnext/translations/bg.csv
+++ b/erpnext/translations/bg.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Автоматичното повторение на документа е актуализиран,
 Automotive,автомобилен,
 Available,Наличен,
-Available Leaves,Налични листа,
 Available Qty,В наличност Количество,
 Available Selling,Налични продажби,
 Available for use date is required,Необходима е дата за употреба,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Идент,
 Human Resource,Човешки ресурси,
 Human Resources,Човешки ресурси,
-IFSC Code,Кодекс на IFSC,
 IGST Amount,IGST Сума,
 IP Address,IP адрес,
 ITC Available (whether in full op part),Наличен ITC (независимо дали в пълната част),
@@ -1666,7 +1664,6 @@
 Other,Друг,
 Other Reports,Други справки,
 "Other outward supplies(Nil rated,Exempted)","Други външни доставки (с нулева оценка, освободени)",
-Others,Други,
 Out Qty,Изх. Количество,
 Out Value,Изх. стойност,
 Out of Order,Извънредно,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Общо (без данъци),
 Total Achieved,Общо постигнати,
 Total Actual,Общо Край,
-Total Allocated Leaves,Общо разпределени листа,
 Total Amount,Обща сума,
 Total Amount Credited,Общата сума е кредитирана,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,"Общо приложими такси в Покупка получаване артикули маса трябва да са същите, както Общо данъци и такси",
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Качете ваш дизайн за заглавно писмо и лого. (Можете да ги редактирате по-късно).,
 Upper Income,Upper подоходно,
 Use Sandbox,Използвайте Sandbox,
-Used Leaves,Използвани листа,
 User,потребител,
 User ID,User ID,
 User ID not set for Employee {0},User ID не е конфигуриран за служител {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Гаранционен срок (в дни),
 Auto re-order,Автоматична повторна поръчка,
 Reorder level based on Warehouse,Пренареждане равнище въз основа на Warehouse,
-Will also apply for variants unless overrridden,"Ще се прилага и за варианти, освен ако overrridden",
+Will also apply for variants unless overridden,"Ще се прилага и за варианти, освен ако overridden",
 Units of Measure,Мерни единици за измерване,
 Will also apply for variants,Ще се прилага и за варианти,
 Serial Nos and Batches,Серийни номера и партиди,
@@ -7949,12 +7944,10 @@
 Approvers,Одобряващи,
 The first Approver in the list will be set as the default Approver.,Първият одобряващ в списъка ще бъде зададен като одобряващ по подразбиране.,
 Shift Request Approver,Одобряващ заявка за смяна,
-PAN Number,Номер на PAN,
 Provident Fund Account,Провиден фонд,
 MICR Code,MICR код,
 Repay unclaimed amount from salary,Изплатете непотърсена сума от заплата,
 Deduction from salary,Приспадане от заплата,
-Expired Leaves,Листа с изтекъл срок на годност,
 If this is not checked the loan by default will be considered as a Demand Loan,"Ако това не е отметнато, заемът по подразбиране ще се счита за кредит за търсене",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,"Тази сметка се използва за резервиране на изплащане на заеми от кредитополучателя, както и за изплащане на заеми на кредитополучателя",
 This account is capital account which is used to allocate capital for loan disbursal account ,"Тази сметка е капиталова сметка, която се използва за разпределяне на капитал за сметка за оттегляне на заеми",
@@ -8748,3 +8741,5 @@
 Is Mandatory,Задължително,
 WhatsApp,WhatsApp,
 Make a call,Обадете се,
+Approve,одобрявам,
+Reject,Отхвърляне,
diff --git a/erpnext/translations/bn.csv b/erpnext/translations/bn.csv
index 49617da..69fd08c 100644
--- a/erpnext/translations/bn.csv
+++ b/erpnext/translations/bn.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,স্বতঃ পুনরাবৃত্ত নথি আপডেট করা হয়েছে,
 Automotive,স্বয়ংচালিত,
 Available,উপলভ্য,
-Available Leaves,উপলব্ধ পাতা,
 Available Qty,প্রাপ্তিসাধ্য Qty,
 Available Selling,উপলভ্য বিক্রি,
 Available for use date is required,ব্যবহারের তারিখের জন্য উপলভ্য প্রয়োজন,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,হাব সিঙ্ক আইডি,
 Human Resource,মানব সম্পদ,
 Human Resources,মানব সম্পদ,
-IFSC Code,আইএফসিসি কোড,
 IGST Amount,IGST পরিমাণ,
 IP Address,আইপি ঠিকানা,
 ITC Available (whether in full op part),আইটিসি উপলব্ধ (সম্পূর্ণ বিকল্প অংশে থাকুক না কেন),
@@ -1666,7 +1664,6 @@
 Other,অন্যান্য,
 Other Reports,অন্যান্য রিপোর্ট,
 "Other outward supplies(Nil rated,Exempted)","অন্যান্য বাহ্যিক সরবরাহ (নিল রেটড, অব্যাহতিপ্রাপ্ত)",
-Others,অন্যরা,
 Out Qty,Qty আউট,
 Out Value,আউট মূল্য,
 Out of Order,অর্ডার আউট,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),মোট (কর ছাড়),
 Total Achieved,মোট অর্জন,
 Total Actual,প্রকৃত মোট,
-Total Allocated Leaves,মোট বরাদ্দ পাতা,
 Total Amount,মোট পরিমাণ,
 Total Amount Credited,মোট পরিমাণ কৃতিত্ব,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,ক্রয় রশিদ সামগ্রী টেবিলের মোট প্রযোজ্য চার্জ মোট কর ও চার্জ হিসাবে একই হতে হবে,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,আপনার চিঠি মাথা এবং লোগো আপলোড করুন. (আপনি তাদের পরে সম্পাদনা করতে পারেন).,
 Upper Income,আপার আয়,
 Use Sandbox,ব্যবহারের স্যান্ডবক্স,
-Used Leaves,ব্যবহৃত পাখি,
 User,ব্যবহারকারী,
 User ID,ব্যবহারকারী আইডি,
 User ID not set for Employee {0},ইউজার আইডি কর্মচারী জন্য নির্ধারণ করে না {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),(দিন) ওয়্যারেন্টি সময়কাল,
 Auto re-order,অটো পুনরায় আদেশ,
 Reorder level based on Warehouse,গুদাম উপর ভিত্তি রেকর্ডার স্তর,
-Will also apply for variants unless overrridden,Overrridden তবে এছাড়াও ভিন্নতা জন্য আবেদন করতে হবে,
+Will also apply for variants unless overridden,Overrridden তবে এছাড়াও ভিন্নতা জন্য আবেদন করতে হবে,
 Units of Measure,পরিমাপ ইউনিট,
 Will also apply for variants,এছাড়াও ভিন্নতা জন্য আবেদন করতে হবে,
 Serial Nos and Batches,সিরিয়াল আমরা এবং ব্যাচ,
@@ -7949,12 +7944,10 @@
 Approvers,বিতর্ক,
 The first Approver in the list will be set as the default Approver.,তালিকার প্রথম অনুমোদিতটি ডিফল্ট অনুমোদনকারী হিসাবে সেট করা হবে।,
 Shift Request Approver,শিফট অনুরোধ অনুমোদনকারী,
-PAN Number,প্যান নম্বর,
 Provident Fund Account,প্রভিডেন্ট ফান্ড অ্যাকাউন্ট,
 MICR Code,এমআইসিআর কোড,
 Repay unclaimed amount from salary,বেতন থেকে দায়হীন পরিমাণ পরিশোধ করুন ay,
 Deduction from salary,বেতন থেকে ছাড়,
-Expired Leaves,মেয়াদ শেষ হয়ে গেছে,
 If this is not checked the loan by default will be considered as a Demand Loan,এটি যদি চেক না করা হয় তবে ডিফল্ট হিসাবে loanণকে ডিমান্ড anণ হিসাবে বিবেচনা করা হবে,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,এই অ্যাকাউন্টটি orণগ্রহীতা থেকে repণ পরিশোধের বুকিং এবং orণগ্রহীতাকে loansণ বিতরণের জন্য ব্যবহৃত হয়,
 This account is capital account which is used to allocate capital for loan disbursal account ,এই অ্যাকাউন্টটি মূলধন অ্যাকাউন্ট যা disণ বিতরণ অ্যাকাউন্টের জন্য মূলধন বরাদ্দ করতে ব্যবহৃত হয়,
@@ -8748,3 +8741,5 @@
 Is Mandatory,আবশ্যক,
 WhatsApp,হোয়াটসঅ্যাপ,
 Make a call,ফোন করুন,
+Approve,অনুমোদন করা,
+Reject,প্রত্যাখ্যান,
diff --git a/erpnext/translations/bs.csv b/erpnext/translations/bs.csv
index 0805228..ef680a3 100644
--- a/erpnext/translations/bs.csv
+++ b/erpnext/translations/bs.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Automatsko ponavljanje dokumenta je ažurirano,
 Automotive,Automobilska industrija,
 Available,Dostupno,
-Available Leaves,Raspoložive liste,
 Available Qty,Dostupno Količina,
 Available Selling,Dostupna prodaja,
 Available for use date is required,Potreban je datum upotrebe,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub Sync ID,
 Human Resource,Human Resource,
 Human Resources,Ljudski resursi,
-IFSC Code,IFSC kod,
 IGST Amount,IGST Iznos,
 IP Address,IP adresa,
 ITC Available (whether in full op part),Dostupan ITC (bilo u cjelini op. Dio),
@@ -1666,7 +1664,6 @@
 Other,Drugi,
 Other Reports,Ostali izveštaji,
 "Other outward supplies(Nil rated,Exempted)","Ostale vanjske zalihe (Nil ocijenjeno, Izuzeti)",
-Others,Drugi,
 Out Qty,Od kol,
 Out Value,out vrijednost,
 Out of Order,Ne radi,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Ukupno (bez poreza),
 Total Achieved,Ukupno Ostvareni,
 Total Actual,Ukupno Actual,
-Total Allocated Leaves,Ukupno izdvojene liste,
 Total Amount,Ukupan iznos,
 Total Amount Credited,Ukupan iznos kredita,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Ukupno Primjenjivo Optužbe na račun za prodaju Predmeti sto mora biti isti kao Ukupni porezi i naknada,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Unos glavu pismo i logo. (Možete ih kasnije uređivanje).,
 Upper Income,Viši Prihodi,
 Use Sandbox,Koristite Sandbox,
-Used Leaves,Korišćeni listovi,
 User,User,
 User ID,Korisnički ID,
 User ID not set for Employee {0},Korisnik ID nije postavljen za zaposlenika {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Jamstveni period (u danima),
 Auto re-order,Autorefiniš reda,
 Reorder level based on Warehouse,Nivo Ponovno red zasnovan na Skladište,
-Will also apply for variants unless overrridden,Primjenjivat će se i za varijante osim overrridden,
+Will also apply for variants unless overridden,Primjenjivat će se i za varijante osim overridden,
 Units of Measure,Jedinice mjere,
 Will also apply for variants,Primjenjivat će se i za varijante,
 Serial Nos and Batches,Serijski brojevi i Paketi,
@@ -7949,12 +7944,10 @@
 Approvers,Odobrivači,
 The first Approver in the list will be set as the default Approver.,Prvi odobravatelj na listi postavit će se kao zadani odobravatelj.,
 Shift Request Approver,Odobrivač zahtjeva za smjenom,
-PAN Number,PAN broj,
 Provident Fund Account,Račun osiguravajućeg fonda,
 MICR Code,MICR kod,
 Repay unclaimed amount from salary,Otplatite neiskorišteni iznos iz plate,
 Deduction from salary,Odbitak od plate,
-Expired Leaves,Isteklo lišće,
 If this is not checked the loan by default will be considered as a Demand Loan,"Ako ovo nije potvrđeno, zajam će se prema zadanim postavkama smatrati zajmom na zahtjev",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Ovaj račun koristi se za rezerviranje otplate zajma od zajmoprimca i za isplatu zajmova zajmoprimcu,
 This account is capital account which is used to allocate capital for loan disbursal account ,Ovaj račun je račun kapitala koji se koristi za alokaciju kapitala za račun izdvajanja kredita,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Je obavezna,
 WhatsApp,WhatsApp,
 Make a call,Pozovite,
+Approve,odobriti,
+Reject,odbiti,
diff --git a/erpnext/translations/ca.csv b/erpnext/translations/ca.csv
index ba108e2..fa545a4 100644
--- a/erpnext/translations/ca.csv
+++ b/erpnext/translations/ca.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,S&#39;ha actualitzat el document de repetició automàtica,
 Automotive,Automòbil,
 Available,Disponible,
-Available Leaves,Fulles disponibles,
 Available Qty,Disponible Quantitat,
 Available Selling,Venda disponible,
 Available for use date is required,Disponible per a la data d&#39;ús,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Identificador de sincronització del concentrador,
 Human Resource,Recursos humans,
 Human Resources,Recursos humans,
-IFSC Code,Codi IFSC,
 IGST Amount,Import de l&#39;IGST,
 IP Address,Adreça IP,
 ITC Available (whether in full op part),TIC disponible (en qualsevol part opcional),
@@ -1666,7 +1664,6 @@
 Other,Un altre,
 Other Reports,Altres informes,
 "Other outward supplies(Nil rated,Exempted)","Altres subministraments externs (Nil, eximitat)",
-Others,Altres,
 Out Qty,Quantitat de sortida,
 Out Value,Valor fora,
 Out of Order,No funciona,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Total (sense impostos),
 Total Achieved,Total aconseguit,
 Total Actual,Actual total,
-Total Allocated Leaves,Total Allocated Leaves,
 Total Amount,Quantitat total,
 Total Amount Credited,Import total acreditat,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Total d&#39;comissions aplicables en la compra Taula de rebuts Els articles han de ser iguals que les taxes totals i càrrecs,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Puja el teu cap lletra i logotip. (Pots editar més tard).,
 Upper Income,Ingrés Alt,
 Use Sandbox,ús Sandbox,
-Used Leaves,Fulles utilitzades,
 User,Usuari,
 User ID,ID d'usuari,
 User ID not set for Employee {0},ID d'usuari no entrat per l'Empleat {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Període de garantia (en dies),
 Auto re-order,Acte reordenar,
 Reorder level based on Warehouse,Nivell de comanda basat en Magatzem,
-Will also apply for variants unless overrridden,També s'aplicarà per a les variants menys overrridden,
+Will also apply for variants unless overridden,També s'aplicarà per a les variants menys overridden,
 Units of Measure,Unitats de mesura,
 Will also apply for variants,També s'aplicarà per a les variants,
 Serial Nos and Batches,Nº de sèrie i lots,
@@ -7949,12 +7944,10 @@
 Approvers,Aprovadors,
 The first Approver in the list will be set as the default Approver.,El primer aprovador de la llista s&#39;establirà com a aprovador predeterminat.,
 Shift Request Approver,Aprovador de sol·licituds de torn,
-PAN Number,Número PAN,
 Provident Fund Account,Compte de fons de previsió,
 MICR Code,Codi MICR,
 Repay unclaimed amount from salary,Reemborsar l’import no reclamat del salari,
 Deduction from salary,Deducció del salari,
-Expired Leaves,Fulles caducades,
 If this is not checked the loan by default will be considered as a Demand Loan,"Si no es comprova això, el préstec per defecte es considerarà un préstec a la demanda",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Aquest compte s’utilitza per reservar els pagaments de préstecs del prestatari i també per desemborsar préstecs al prestatari,
 This account is capital account which is used to allocate capital for loan disbursal account ,Aquest compte és un compte de capital que s’utilitza per assignar capital per al compte de desemborsament del préstec,
@@ -8748,3 +8741,5 @@
 Is Mandatory,És obligatori,
 WhatsApp,Què tal,
 Make a call,Fer una trucada,
+Approve,aprovar,
+Reject,Rebutjar,
diff --git a/erpnext/translations/cs.csv b/erpnext/translations/cs.csv
index 4cd3ac5..7fb1679 100644
--- a/erpnext/translations/cs.csv
+++ b/erpnext/translations/cs.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Dokument byl aktualizován automaticky,
 Automotive,Automobilový,
 Available,K dispozici,
-Available Leaves,Dostupné listy,
 Available Qty,Množství k dispozici,
 Available Selling,Dostupné prodeje,
 Available for use date is required,K dispozici je datum k dispozici pro použití,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,ID synchronizace Hubu,
 Human Resource,Lidské zdroje,
 Human Resources,Lidské zdroje,
-IFSC Code,Kód IFSC,
 IGST Amount,IGST částka,
 IP Address,IP adresa,
 ITC Available (whether in full op part),ITC k dispozici (ať už v plné op části),
@@ -1666,7 +1664,6 @@
 Other,Ostatní,
 Other Reports,Ostatní zprávy,
 "Other outward supplies(Nil rated,Exempted)","Ostatní pasivní dodávky (bez hodnocení, osvobozeno)",
-Others,Ostatní,
 Out Qty,Out Množství,
 Out Value,limitu,
 Out of Order,Mimo provoz,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Celkem (bez daně),
 Total Achieved,Celkem Dosažená,
 Total Actual,Celkem Aktuální,
-Total Allocated Leaves,Celkové přidělené listy,
 Total Amount,Celková částka,
 Total Amount Credited,Celková částka připsána,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,"Celkový počet použitelných poplatcích v dokladu o koupi zboží, které tabulky musí být stejná jako celkem daní a poplatků",
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Nahrajte svůj dopis hlavu a logo. (Můžete je upravit později).,
 Upper Income,Horní příjmů,
 Use Sandbox,použití Sandbox,
-Used Leaves,Použité listy,
 User,Uživatel,
 User ID,User ID,
 User ID not set for Employee {0},User ID není nastavena pro zaměstnance {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Záruční doba (ve dnech),
 Auto re-order,Automatické znovuobjednání,
 Reorder level based on Warehouse,Úroveň Změna pořadí na základě Warehouse,
-Will also apply for variants unless overrridden,"Bude platit i pro varianty, pokud nebude přepsáno",
+Will also apply for variants unless overridden,"Bude platit i pro varianty, pokud nebude přepsáno",
 Units of Measure,Jednotky měření,
 Will also apply for variants,Bude platit i pro varianty,
 Serial Nos and Batches,Sériové čísla a dávky,
@@ -7949,12 +7944,10 @@
 Approvers,Schvalovatelé,
 The first Approver in the list will be set as the default Approver.,První schvalovatel v seznamu bude nastaven jako výchozí schvalovatel.,
 Shift Request Approver,Schvalovatel žádosti o změnu,
-PAN Number,PAN číslo,
 Provident Fund Account,Účet fondu Provident,
 MICR Code,Kód MICR,
 Repay unclaimed amount from salary,Vrátit nevyzvednutou částku z platu,
 Deduction from salary,Srážka z platu,
-Expired Leaves,Vypršela platnost listů,
 If this is not checked the loan by default will be considered as a Demand Loan,"Pokud to není zaškrtnuto, bude se úvěr ve výchozím nastavení považovat za půjčku na vyžádání",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Tento účet slouží k rezervaci splátek půjčky od dlužníka a také k vyplácení půjček dlužníkovi,
 This account is capital account which is used to allocate capital for loan disbursal account ,"Tento účet je kapitálovým účtem, který se používá k přidělení kapitálu pro účet vyplácení půjček",
@@ -8748,3 +8741,5 @@
 Is Mandatory,Je povinná,
 WhatsApp,WhatsApp,
 Make a call,Zavolat,
+Approve,Schvalovat,
+Reject,Odmítnout,
diff --git a/erpnext/translations/cz.csv b/erpnext/translations/cz.csv
index 270a710..96de062 100644
--- a/erpnext/translations/cz.csv
+++ b/erpnext/translations/cz.csv
@@ -1991,7 +1991,7 @@
 Actual End Date,Skutečné datum ukončen$1,
 Applicable To (Role),Vztahující se na (Role)
 Purpose,Účel,
-Will also apply for variants unless overrridden,"Bude platit i pro varianty, pokud nebude přepsáno"
+Will also apply for variants unless overridden,"Bude platit i pro varianty, pokud nebude přepsáno"
 Advances,Zálohy,
 Approving User cannot be same as user the rule is Applicable To,Schválení Uživatel nemůže být stejná jako uživatel pravidlo se vztahuje na,
 No of Requested SMS,Počet žádaným SMS,
diff --git a/erpnext/translations/da.csv b/erpnext/translations/da.csv
index b89f39c..4eb3960 100644
--- a/erpnext/translations/da.csv
+++ b/erpnext/translations/da.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Automatisk gentag dokument opdateret,
 Automotive,Bil,
 Available,Tilgængelig,
-Available Leaves,Tilgængelige blade,
 Available Qty,Tilgængelig antal,
 Available Selling,Tilgængelig salg,
 Available for use date is required,Tilgængelig til brug dato er påkrævet,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub Sync ID,
 Human Resource,Menneskelige ressourcer,
 Human Resources,Medarbejdere,
-IFSC Code,IFSC-kode,
 IGST Amount,IGST Beløb,
 IP Address,IP-adresse,
 ITC Available (whether in full op part),ITC tilgængelig (uanset om det er i fuld op-del),
@@ -1666,7 +1664,6 @@
 Other,Andre,
 Other Reports,Andre rapporter,
 "Other outward supplies(Nil rated,Exempted)","Andre udgående leverancer (Nul bedømt, undtaget)",
-Others,Andre,
 Out Qty,Out Antal,
 Out Value,Out Value,
 Out of Order,Virker ikke,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),I alt (uden skat),
 Total Achieved,Total Opnået,
 Total Actual,Samlede faktiske,
-Total Allocated Leaves,Samlede tildelte blade,
 Total Amount,Samlet beløb,
 Total Amount Credited,Samlede beløb krediteret,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Total gældende takster i købskvitteringsvaretabel skal være det samme som de samlede skatter og afgifter,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Upload dit brevhoved og logo. (du kan redigere dem senere).,
 Upper Income,Upper Indkomst,
 Use Sandbox,Brug Sandbox,
-Used Leaves,Brugte blade,
 User,Bruger,
 User ID,Bruger-id,
 User ID not set for Employee {0},Bruger-id ikke indstillet til Medarbejder {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Garantiperiode (i dage),
 Auto re-order,Auto genbestil,
 Reorder level based on Warehouse,Genbestil niveau baseret på Warehouse,
-Will also apply for variants unless overrridden,"Vil også gælde for varianter, medmindre overrridden",
+Will also apply for variants unless overridden,"Vil også gælde for varianter, medmindre overridden",
 Units of Measure,Måleenheder,
 Will also apply for variants,Vil også gælde for varianter,
 Serial Nos and Batches,Serienummer og partier,
@@ -7949,12 +7944,10 @@
 Approvers,Approverser,
 The first Approver in the list will be set as the default Approver.,Den første godkender på listen indstilles som standardgodkenderen.,
 Shift Request Approver,Godkendelse af skiftanmodning,
-PAN Number,PAN-nummer,
 Provident Fund Account,Provident Fund-konto,
 MICR Code,MICR-kode,
 Repay unclaimed amount from salary,Tilbagebetal ikke-krævet beløb fra løn,
 Deduction from salary,Fradrag fra løn,
-Expired Leaves,Udløbne blade,
 If this is not checked the loan by default will be considered as a Demand Loan,"Hvis dette ikke er markeret, vil lånet som standard blive betragtet som et behovslån",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Denne konto bruges til at booke tilbagebetaling af lån fra låntager og også udbetale lån til låntager,
 This account is capital account which is used to allocate capital for loan disbursal account ,"Denne konto er en kapitalkonto, der bruges til at allokere kapital til udbetaling af lånekonto",
@@ -8748,3 +8741,5 @@
 Is Mandatory,Er obligatorisk,
 WhatsApp,WhatsApp,
 Make a call,Ringe,
+Approve,Godkende,
+Reject,Afvise,
diff --git a/erpnext/translations/de.csv b/erpnext/translations/de.csv
index 03e9de4..c627f81 100644
--- a/erpnext/translations/de.csv
+++ b/erpnext/translations/de.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Automatisches Wiederholungsdokument aktualisiert,
 Automotive,Fahrzeugbau,
 Available,Verfügbar,
-Available Leaves,Verfügbare Blätter,
 Available Qty,Verfügbare Menge,
 Available Selling,Verfügbarer Verkauf,
 Available for use date is required,Verfügbar für das Nutzungsdatum ist erforderlich,
@@ -1129,7 +1128,6 @@
 Hub Sync ID,Hub-Synchronisierungs-ID,
 Human Resource,Personal,
 Human Resources,Personalwesen,
-IFSC Code,IFSC-Code,
 IGST Amount,IGST Betrag,
 IP Address,IP Adresse,
 ITC Available (whether in full op part),ITC verfügbar (ob vollständig oder teilweise),
@@ -1675,7 +1673,6 @@
 Other,Andere,
 Other Reports,Weitere Berichte,
 "Other outward supplies(Nil rated,Exempted)","Sonstige Auslandslieferungen (ohne Rating, ausgenommen)",
-Others,Andere,
 Out Qty,Ausgabe-Menge,
 Out Value,Out Wert,
 Out of Order,Außer Betrieb,
@@ -2825,7 +2822,6 @@
 Total (Without Tax),Summe (ohne Steuern),
 Total Achieved,Gesamtsumme erreicht,
 Total Actual,Summe Tatsächlich,
-Total Allocated Leaves,Insgesamt zugeteilte Blätter,
 Total Amount,Gesamtsumme,
 Total Amount Credited,Gesamtbetrag der Gutschrift,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Gesamt Die Gebühren in Kauf Eingangspositionen Tabelle muss als Gesamt Steuern und Abgaben gleich sein,
@@ -2935,7 +2931,6 @@
 Upload your letter head and logo. (you can edit them later).,Briefkopf und Logo hochladen. (Beides kann später noch bearbeitet werden.),
 Upper Income,Gehobenes Einkommen,
 Use Sandbox,Sandkastenmodus verwenden,
-Used Leaves,Genutzter Urlaub,
 User,Nutzer,
 User ID,Benutzer-ID,
 User ID not set for Employee {0},Benutzer-ID ist für Mitarbeiter {0} nicht eingegeben,
@@ -3345,7 +3340,7 @@
 Cannot Optimize Route as Driver Address is Missing.,"Route kann nicht optimiert werden, da die Fahreradresse fehlt.",
 Cannot complete task {0} as its dependant task {1} are not ccompleted / cancelled.,"Aufgabe {0} kann nicht abgeschlossen werden, da die abhängige Aufgabe {1} nicht abgeschlossen / abgebrochen wurde.",
 Cannot find a matching Item. Please select some other value for {0}.,Ein passender Artikel kann nicht gefunden werden. Bitte einen anderen Wert für {0} auswählen.,
-"Cannot overbill for Item {0} in row {1} more than {2}. To allow over-billing, please set allowance in Accounts Settings","Artikel {0} in Zeile {1} kann nicht mehr als {2} in Rechnung gestellt werden. Um eine Überberechnung zuzulassen, legen Sie die Überberechnung in den Kontoeinstellungen fest",
+"Cannot overbill for Item {0} in row {1} more than {2}. To allow over-billing, please set allowance in Accounts Settings","Für Artikel {0} in Zeile {1} kann nicht mehr als {2} zusätzlich in Rechnung gestellt werden. Um diese Überfakturierung zuzulassen, passen Sie bitte die Grenzwerte in den Buchhaltungseinstellungen an.",
 "Capacity Planning Error, planned start time can not be same as end time","Kapazitätsplanungsfehler, die geplante Startzeit darf nicht mit der Endzeit übereinstimmen",
 Categories,Kategorien,
 Changes in {0},Änderungen in {0},
@@ -3751,7 +3746,7 @@
 This page keeps track of your items in which buyers have showed some interest.,"Diese Seite verfolgt Ihre Artikel, an denen Käufer Interesse gezeigt haben.",
 Thursday,Donnerstag,
 Title,Bezeichnung,
-"To allow over billing, update ""Over Billing Allowance"" in Accounts Settings or the Item.","Aktualisieren Sie &quot;Over Billing Allowance&quot; in den Kontoeinstellungen oder im Artikel, um eine Überberechnung zuzulassen.",
+"To allow over billing, update ""Over Billing Allowance"" in Accounts Settings or the Item.","Aktualisieren Sie &quot;Over Billing Allowance&quot; in den Buchhaltungseinstellungen oder im Artikel, um eine Überberechnung zuzulassen.",
 "To allow over receipt / delivery, update ""Over Receipt/Delivery Allowance"" in Stock Settings or the Item.","Um eine Überbestätigung / Überlieferung zu ermöglichen, aktualisieren Sie &quot;Überbestätigung / Überlieferung&quot; in den Lagereinstellungen oder im Artikel.",
 Total,Summe,
 Total Payment Request amount cannot be greater than {0} amount,Der Gesamtbetrag der Zahlungsanforderung darf nicht größer als {0} sein,
@@ -4118,8 +4113,8 @@
 Accounting Period,Abrechnungszeitraum,
 Period Name,Zeitraumname,
 Closed Documents,Geschlossene Dokumente,
-Accounts Settings,Konteneinstellungen,
-Settings for Accounts,Konteneinstellungen,
+Accounts Settings,Buchhaltungseinstellungen,
+Settings for Accounts,Einstellungen für die Buchhaltung,
 Make Accounting Entry For Every Stock Movement,Eine Buchung für jede Lagerbewegung erstellen,
 Users with this role are allowed to set frozen accounts and create / modify accounting entries against frozen accounts,Benutzer mit dieser Rolle sind berechtigt Konten zu sperren und  Buchungen zu gesperrten Konten zu erstellen/verändern,
 Determine Address Tax Category From,Adresssteuerkategorie bestimmen von,
@@ -4591,7 +4586,7 @@
 Tax Withholding Category,Steuereinbehalt Kategorie,
 Edit Posting Date and Time,Buchungsdatum und -uhrzeit bearbeiten,
 Is Paid,Ist bezahlt,
-Is Return (Debit Note),ist Rücklieferung (Lastschrift),
+Is Return (Debit Note),Ist Rechnungskorrektur (Retoure),
 Apply Tax Withholding Amount,Steuereinbehaltungsbetrag anwenden,
 Accounting Dimensions ,Buchhaltung Dimensionen,
 Supplier Invoice Details,Lieferant Rechnungsdetails,
@@ -4715,7 +4710,7 @@
 ACC-SINV-.YYYY.-,ACC-SINV-.JJJJ.-,
 Include Payment (POS),(POS) Zahlung einschließen,
 Offline POS Name,Offline-Verkaufsstellen-Name,
-Is Return (Credit Note),ist Rücklieferung (Gutschrift),
+Is Return (Credit Note),Ist Rechnungskorrektur (Retoure),
 Update Billed Amount in Sales Order,Aktualisierung des Rechnungsbetrags im Auftrag,
 Customer PO Details,Auftragsdetails,
 Customer's Purchase Order,Bestellung des Kunden,
@@ -7003,7 +6998,7 @@
 Tariff Number,Tarifnummer,
 Delivery To,Lieferung an,
 MAT-DN-.YYYY.-,MAT-DN-.YYYY.-,
-Is Return,Ist Rückgabe,
+Is Return,Ist Retoure,
 Issue Credit Note,Gutschrift ausgeben,
 Return Against Delivery Note,Zurück zum Lieferschein,
 Customer's Purchase Order No,Bestellnummer des Kunden,
@@ -7079,7 +7074,7 @@
 Warranty Period (in days),Garantiefrist (in Tagen),
 Auto re-order,Automatische Nachbestellung,
 Reorder level based on Warehouse,Meldebestand auf Basis des Lagers,
-Will also apply for variants unless overrridden,"Gilt auch für Varianten, sofern nicht außer Kraft gesetzt",
+Will also apply for variants unless overridden,"Gilt auch für Varianten, sofern nicht außer Kraft gesetzt",
 Units of Measure,Maßeinheiten,
 Will also apply for variants,Gilt auch für Varianten,
 Serial Nos and Batches,Seriennummern und Chargen,
@@ -7622,7 +7617,7 @@
 Journal Entry Type,Buchungssatz-Typ,
 Journal Entry Template Account,Buchungssatzvorlagenkonto,
 Process Deferred Accounting,Aufgeschobene Buchhaltung verarbeiten,
-Manual entry cannot be created! Disable automatic entry for deferred accounting in accounts settings and try again,Manuelle Eingabe kann nicht erstellt werden! Deaktivieren Sie die automatische Eingabe für die verzögerte Buchhaltung in den Konteneinstellungen und versuchen Sie es erneut,
+Manual entry cannot be created! Disable automatic entry for deferred accounting in accounts settings and try again,Manuelle Eingabe kann nicht erstellt werden! Deaktivieren Sie die automatische Eingabe für die verzögerte Buchhaltung in den Buchhaltungseinstellungen und versuchen Sie es erneut,
 End date cannot be before start date,Das Enddatum darf nicht vor dem Startdatum liegen,
 Total Counts Targeted,Gesamtzahl der anvisierten Zählungen,
 Total Counts Completed,Gesamtzahl der abgeschlossenen Zählungen,
@@ -7966,12 +7961,10 @@
 Approvers,Genehmiger,
 The first Approver in the list will be set as the default Approver.,Der erste Genehmiger in der Liste wird als Standardgenehmiger festgelegt.,
 Shift Request Approver,Schichtanforderungsgenehmiger,
-PAN Number,PAN-Nummer,
 Provident Fund Account,Vorsorgefonds-Konto,
 MICR Code,MICR-Code,
 Repay unclaimed amount from salary,Nicht zurückgeforderten Betrag vom Gehalt zurückzahlen,
 Deduction from salary,Abzug vom Gehalt,
-Expired Leaves,Abgelaufene Blätter,
 If this is not checked the loan by default will be considered as a Demand Loan,"Wenn dies nicht aktiviert ist, wird das Darlehen standardmäßig als Nachfragedarlehen betrachtet",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Dieses Konto wird zur Buchung von Kreditrückzahlungen vom Kreditnehmer und zur Auszahlung von Krediten an den Kreditnehmer verwendet,
 This account is capital account which is used to allocate capital for loan disbursal account ,"Dieses Konto ist ein Kapitalkonto, das zur Zuweisung von Kapital für das Darlehensauszahlungskonto verwendet wird",
@@ -8670,7 +8663,7 @@
 Please set default Cash or Bank account in Mode of Payments {},Bitte setzen Sie das Standard-Bargeld- oder Bankkonto im Zahlungsmodus {},
 Please ensure {} account is a Balance Sheet account. You can change the parent account to a Balance Sheet account or select a different account.,"Bitte stellen Sie sicher, dass das Konto {} ein Bilanzkonto ist. Sie können das übergeordnete Konto in ein Bilanzkonto ändern oder ein anderes Konto auswählen.",
 Please ensure {} account is a Payable account. Change the account type to Payable or select a different account.,"Bitte stellen Sie sicher, dass das Konto {} ein zahlbares Konto ist. Ändern Sie den Kontotyp in &quot;Verbindlichkeiten&quot; oder wählen Sie ein anderes Konto aus.",
-"Row {0}: Expense Head changed to {1} because account {2} is not linked to warehouse {3} or it is not the default inventory account","Zeile {0}: Aufwandskonto geändert zu {1}, weil das Konto {2} nicht mit dem Lager {3} verknüpft ist oder es nicht das Standard-Inventarkonto ist",
+Row {0}: Expense Head changed to {1} because account {2} is not linked to warehouse {3} or it is not the default inventory account,"Zeile {0}: Aufwandskonto geändert zu {1}, weil das Konto {2} nicht mit dem Lager {3} verknüpft ist oder es nicht das Standard-Inventarkonto ist",
 Row {0}: Expense Head changed to {1} because expense is booked against this account in Purchase Receipt {2},"Zeile {0}: Aufwandskonto geändert zu {1}, da dieses bereits in Eingangsbeleg {2} verwendet wurde",
 Row {0}: Expense Head changed to {1} as no Purchase Receipt is created against Item {2}.,"Zeile {0}: Aufwandskonto geändert zu {1}, da kein Eingangsbeleg für Artikel {2} erstellt wird.",
 This is done to handle accounting for cases when Purchase Receipt is created after Purchase Invoice,"Dies erfolgt zur Abrechnung von Fällen, in denen der Eingangsbeleg nach der Eingangsrechnung erstellt wird",
@@ -8833,3 +8826,32 @@
 Is Mandatory,Ist obligatorisch,
 WhatsApp,WhatsApp,
 Make a call,Einen Anruf tätigen,
+Enable Automatic Party Matching,Automatisches Zuordnen von Parteien aktivieren,
+Auto match and set the Party in Bank Transactions,"Partei automatisch anhand der Kontonummer bzw. IBAN zuordnen",
+Enable Fuzzy Matching,Fuzzy Matching aktivieren,
+Approximately match the description/party name against parties,"Partei automatisch anhand grober Übereinstimmung des Namens zuordnen"
+Accounts Closing,Kontenabschluss,
+Period Closing Settings,Periodenabschlusseinstellungen,
+Ignore Account Closing Balance,Saldo des Kontos zum Periodenabschluss ignorieren,
+Financial reports will be generated using GL Entry doctypes (should be enabled if Period Closing Voucher is not posted for all years sequentially or missing),"Finanzberichte werden anhand des Hauptbuchs erstellt (sollte aktiviert sein, wenn Periodenabschlüsse fehlen oder nicht sequentiell für alle Jahre gebucht werden)",
+Asset Settings,Vermögenswerteinstellungen,
+POS Setting,POS-Einstellungen,
+Create Ledger Entries for Change Amount,Buchungssätze für Wechselgeld erstellen,
+"If enabled, ledger entries will be posted for change amount in POS transactions","Wenn aktiviert, werden Buchungssätze für Wechselgeld in POS-Transaktionen erstellt",
+Credit Limit Settings,Kreditlimit-Einstellungen,
+Role Allowed to Over Bill,
+Users with this role are allowed to over bill above the allowance percentage,"Roll, die mehr als den erlaubten Prozentsatz zusätzlich abrechnen darf",
+Role allowed to bypass Credit Limit,"Rolle, die das Kreditlimit umgehen darf",
+Invoice Cancellation,Rechnungsstornierung,
+Delete Accounting and Stock Ledger Entries on deletion of Transaction,Beim Löschen einer Transaktion auch die entsprechenden Buchungs- und Lagerbuchungssätze löschen,
+Enable Common Party Accounting,Verknüpfung von Kunden und Liefeanten erlauben,
+Allow multi-currency invoices against single party account,Rechnungsbeträge in Fremdwährungen dürfen umgerechnet und in der Hauptwährung gebucht werden,
+Enabling this will allow creation of multi-currency invoices against single party account in company currency,Bei Aktivierung können Rechnungen in Fremdwährungen gegen ein Konto in der Hauptwährung gebucht werden,
+Payment Terms from orders will be fetched into the invoices as is,Zahlungsbedingungen aus Aufträgen werden eins zu eins in Rechnungen übernommen,
+Automatically Fetch Payment Terms from Order,Zahlungsbedingungen aus Auftrag in die Rechnung übernehmen,
+Enable Custom Cash Flow Format,Individuelles Cashflow-Format aktivieren,
+Tax Settings,Umsatzsteuer-Einstellungen,
+Book Tax Loss on Early Payment Discount,Umsatzsteueranteil bei Skonto berücksichtigen,
+Split Early Payment Discount Loss into Income and Tax Loss,"Skontobetrag in Aufwand und Umsatzsteuerkorrektur aufteilen",
+Approve,Genehmigen,
+Reject,Ablehnen,
diff --git a/erpnext/translations/el.csv b/erpnext/translations/el.csv
index 8d48c3a..21fb435 100644
--- a/erpnext/translations/el.csv
+++ b/erpnext/translations/el.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Το έγγραφο αυτόματης επανάληψης ενημερώθηκε,
 Automotive,Αυτοκίνητο,
 Available,Διαθέσιμος,
-Available Leaves,Διαθέσιμα φύλλα,
 Available Qty,Διαθέσιμη ποσότητα,
 Available Selling,Διαθέσιμη πώληση,
 Available for use date is required,Απαιτείται ημερομηνία διαθέσιμη για χρήση,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Αναγνωριστικό συγχρονισμού Hub,
 Human Resource,Ανθρώπινο δυναμικό,
 Human Resources,Ανθρώπινοι πόροι,
-IFSC Code,Κωδικός IFSC,
 IGST Amount,Ποσό IGST,
 IP Address,Διεύθυνση IP,
 ITC Available (whether in full op part),ITC Διαθέσιμο (είτε σε πλήρη op μέρος),
@@ -1666,7 +1664,6 @@
 Other,Άλλος,
 Other Reports,άλλες εκθέσεις,
 "Other outward supplies(Nil rated,Exempted)","Άλλες παροχές προς το εξωτερικό (μη διαβαθμισμένες, απαλλαγμένες)",
-Others,Άλλα,
 Out Qty,Ποσότητα εκτός,
 Out Value,από Αξία,
 Out of Order,Εκτός λειτουργίας,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Σύνολο (χωρίς Φόρο),
 Total Achieved,Σύνολο που επιτεύχθηκε,
 Total Actual,Πραγματικό σύνολο,
-Total Allocated Leaves,Συνολικά κατανεμημένα φύλλα,
 Total Amount,Συνολικό ποσό,
 Total Amount Credited,Συνολικό ποσό που πιστώνεται,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Σύνολο χρεώσεων που επιβάλλονται στην Αγορά Παραλαβή Είδη πίνακα πρέπει να είναι ίδιο με το συνολικό φόροι και επιβαρύνσεις,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Ανεβάστε την κεφαλίδα επιστολόχαρτου και το λογότυπό σας. (Μπορείτε να τα επεξεργαστείτε αργότερα).,
 Upper Income,Άνω εισοδήματος,
 Use Sandbox,χρήση Sandbox,
-Used Leaves,Χρησιμοποιημένα φύλλα,
 User,Χρήστης,
 User ID,ID χρήστη,
 User ID not set for Employee {0},Το ID χρήστη δεν έχει οριστεί για τον υπάλληλο {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Περίοδος εγγύησης (σε ημέρες),
 Auto re-order,Αυτόματη εκ νέου προκειμένου,
 Reorder level based on Warehouse,Αναδιάταξη επίπεδο με βάση Αποθήκης,
-Will also apply for variants unless overrridden,Θα ισχύουν επίσης για τις παραλλαγές εκτός αν υπάρχει υπέρβαση,
+Will also apply for variants unless overridden,Θα ισχύουν επίσης για τις παραλλαγές εκτός αν υπάρχει υπέρβαση,
 Units of Measure,Μονάδες μέτρησης,
 Will also apply for variants,Θα ισχύουν επίσης για τις παραλλαγές,
 Serial Nos and Batches,Σειριακοί αριθμοί και παρτίδες,
@@ -7949,12 +7944,10 @@
 Approvers,Εγκρίνει,
 The first Approver in the list will be set as the default Approver.,Η πρώτη έγκριση στη λίστα θα οριστεί ως η προεπιλεγμένη έγκριση.,
 Shift Request Approver,Έγκριση αιτήματος Shift,
-PAN Number,Αριθμός PAN,
 Provident Fund Account,Λογαριασμός Ταμείου Προνοίας,
 MICR Code,Κωδικός MICR,
 Repay unclaimed amount from salary,Επιστρέψτε το ποσό που δεν ζητήθηκε από το μισθό,
 Deduction from salary,Έκπτωση από το μισθό,
-Expired Leaves,Έληξε φύλλα,
 If this is not checked the loan by default will be considered as a Demand Loan,"Εάν αυτό δεν ελεγχθεί, το δάνειο από προεπιλογή θα θεωρείται ως Δάνειο Ζήτησης",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Αυτός ο λογαριασμός χρησιμοποιείται για την κράτηση αποπληρωμών δανείου από τον δανειολήπτη και επίσης για την εκταμίευση δανείων προς τον οφειλέτη,
 This account is capital account which is used to allocate capital for loan disbursal account ,Αυτός ο λογαριασμός είναι λογαριασμός κεφαλαίου που χρησιμοποιείται για την κατανομή κεφαλαίου για λογαριασμό εκταμίευσης δανείου,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Ειναι υποχρεωτικό,
 WhatsApp,WhatsApp,
 Make a call,Τηλεφώνησε,
+Approve,Εγκρίνω,
+Reject,Απορρίπτω,
diff --git a/erpnext/translations/es.csv b/erpnext/translations/es.csv
index 50af180..2abe418 100644
--- a/erpnext/translations/es.csv
+++ b/erpnext/translations/es.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Documento automático editado,
 Automotive,Automotores,
 Available,Disponible,
-Available Leaves,Licencias Disponibles,
 Available Qty,Cantidad disponible,
 Available Selling,Venta disponible,
 Available for use date is required,Disponible para la fecha de uso es obligatorio,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,ID de Sincronización del Hub,
 Human Resource,Recursos humanos,
 Human Resources,Recursos humanos,
-IFSC Code,Código IFSC,
 IGST Amount,Monto IGST,
 IP Address,Dirección IP,
 ITC Available (whether in full op part),ITC disponible (ya sea en la parte op completa),
@@ -1666,7 +1664,6 @@
 Other,Otro,
 Other Reports,Otros Reportes,
 "Other outward supplies(Nil rated,Exempted)","Otros suministros externos (sin calificación, exentos)",
-Others,Otros,
 Out Qty,Cant. enviada,
 Out Value,Fuera de Valor,
 Out of Order,Fuera de servicio,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Total (Sin Impuestos),
 Total Achieved,Total Conseguido,
 Total Actual,Total Actual,
-Total Allocated Leaves,Total de Licencias Asignadas,
 Total Amount,Importe total,
 Total Amount Credited,Monto Total Acreditado,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Total de comisiones aplicables en la compra Tabla de recibos Los artículos deben ser iguales que las tasas totales y cargos,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Cargue su membrete y el logotipo. (Estos pueden editarse más tarde).,
 Upper Income,Ingresos superior,
 Use Sandbox,Utilizar Sandbox,
-Used Leaves,Licencias Usadas,
 User,Usuario,
 User ID,ID de usuario,
 User ID not set for Employee {0},ID de usuario no establecido para el empleado {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Período de garantía (en días),
 Auto re-order,Ordenar Automáticamente,
 Reorder level based on Warehouse,Nivel de reabastecimiento basado en almacén,
-Will also apply for variants unless overrridden,También se aplicará para las variantes menos que se sobre escriba,
+Will also apply for variants unless overridden,También se aplicará para las variantes menos que se sobre escriba,
 Units of Measure,Unidades de medida,
 Will also apply for variants,También se aplicará para las variantes,
 Serial Nos and Batches,Números de serie y lotes,
@@ -7949,12 +7944,10 @@
 Approvers,Aprobadores,
 The first Approver in the list will be set as the default Approver.,El primer Aprobador de la lista se establecerá como Aprobador predeterminado.,
 Shift Request Approver,Aprobador de solicitud de turno,
-PAN Number,Número PAN,
 Provident Fund Account,Cuenta del fondo de previsión,
 MICR Code,Código MICR,
 Repay unclaimed amount from salary,Reembolsar la cantidad no reclamada del salario,
 Deduction from salary,Deducción del salario,
-Expired Leaves,Hojas caducadas,
 If this is not checked the loan by default will be considered as a Demand Loan,"Si no se marca, el préstamo por defecto se considerará Préstamo a la vista.",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Esta cuenta se utiliza para registrar los reembolsos de préstamos del prestatario y también para desembolsar préstamos al prestatario.,
 This account is capital account which is used to allocate capital for loan disbursal account ,Esta cuenta es una cuenta de capital que se utiliza para asignar capital para la cuenta de desembolso de préstamos.,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Es obligatorio,
 WhatsApp,WhatsApp,
 Make a call,Haz una llamada,
+Approve,Aprobar,
+Reject,Rechazar,
diff --git a/erpnext/translations/et.csv b/erpnext/translations/et.csv
index e5da343..a4a8736 100644
--- a/erpnext/translations/et.csv
+++ b/erpnext/translations/et.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Auto kordusdokument uuendatud,
 Automotive,Autod,
 Available,Saadaval,
-Available Leaves,Saadaolevad lehed,
 Available Qty,Saadaval Kogus,
 Available Selling,Saadaval müügil,
 Available for use date is required,Kasutatav kasutuskuupäev on vajalik,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub Sync ID,
 Human Resource,Inimressurss,
 Human Resources,Inimressursid,
-IFSC Code,IFSC kood,
 IGST Amount,IGST summa,
 IP Address,IP-aadress,
 ITC Available (whether in full op part),ITC saadaval (kas täielikult op),
@@ -1666,7 +1664,6 @@
 Other,Muud,
 Other Reports,Teised aruanded,
 "Other outward supplies(Nil rated,Exempted)","Muud välistarbed (null, erand)",
-Others,Teised,
 Out Qty,Out Kogus,
 Out Value,välja väärtus,
 Out of Order,Korrast ära,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Kokku (maksudeta),
 Total Achieved,Kokku saavutatud,
 Total Actual,Kokku Tegelik,
-Total Allocated Leaves,Kokku eraldatud lehed,
 Total Amount,Kogu summa,
 Total Amount Credited,Kogu summa krediteeritakse,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Kokku kohaldatavate tasude kohta ostutšekk Esemed tabel peab olema sama Kokku maksud ja tasud,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Laadi üles oma kirjas pea ja logo. (seda saab muuta hiljem).,
 Upper Income,Ülemine tulu,
 Use Sandbox,Kasuta liivakasti,
-Used Leaves,Kasutatud lehed,
 User,Kasutaja,
 User ID,kasutaja ID,
 User ID not set for Employee {0},Kasutaja ID ei seatud Töötaja {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Garantii Periood (päeva),
 Auto re-order,Auto ümber korraldada,
 Reorder level based on Warehouse,Reorder tasandil põhineb Warehouse,
-Will also apply for variants unless overrridden,"Kehtib ka variante, kui overrridden",
+Will also apply for variants unless overridden,"Kehtib ka variante, kui overridden",
 Units of Measure,Mõõtühikud,
 Will also apply for variants,Kehtib ka variandid,
 Serial Nos and Batches,Serial Nos ning partiid,
@@ -7949,12 +7944,10 @@
 Approvers,Heakskiitjad,
 The first Approver in the list will be set as the default Approver.,Loendi esimene heakskiitja määratakse vaikimisi kinnitajaks.,
 Shift Request Approver,Vahetustaotluse kinnitaja,
-PAN Number,PAN-number,
 Provident Fund Account,Providence Fundi konto,
 MICR Code,MICR-kood,
 Repay unclaimed amount from salary,Tagasimakstud summa palgast tagasi maksta,
 Deduction from salary,Palgast mahaarvamine,
-Expired Leaves,Aegunud lehed,
 If this is not checked the loan by default will be considered as a Demand Loan,"Kui seda ei kontrollita, käsitatakse laenu vaikimisi nõudmislaenuna",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Seda kontot kasutatakse laenusaaja tagasimaksete broneerimiseks ja ka laenuvõtjale laenude väljamaksmiseks,
 This account is capital account which is used to allocate capital for loan disbursal account ,"See konto on kapitalikonto, mida kasutatakse kapitali eraldamiseks laenu väljamaksekontole",
@@ -8748,3 +8741,5 @@
 Is Mandatory,On kohustuslik,
 WhatsApp,WhatsApp,
 Make a call,Helistage,
+Approve,kinnitama,
+Reject,tagasi lükkama,
diff --git a/erpnext/translations/fa.csv b/erpnext/translations/fa.csv
index e59023d..bd40c8b 100644
--- a/erpnext/translations/fa.csv
+++ b/erpnext/translations/fa.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,تکرار خودکار سند به روز شد,
 Automotive,خودرو,
 Available,در دسترس,
-Available Leaves,برگهای موجود,
 Available Qty,در دسترس تعداد,
 Available Selling,فروش موجود,
 Available for use date is required,برای تاریخ استفاده لازم است,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,شناسه همگام سازی هاب,
 Human Resource,منابع انسانی,
 Human Resources,منابع انسانی,
-IFSC Code,کد IFSC,
 IGST Amount,مقدار IGST,
 IP Address,نشانی آیپی,
 ITC Available (whether in full op part),ITC موجود (چه در بخش کامل عمل),
@@ -1666,7 +1664,6 @@
 Other,دیگر,
 Other Reports,سایر گزارش,
 "Other outward supplies(Nil rated,Exempted)",سایر لوازم خارجی (امتیاز صفر ، معافیت),
-Others,دیگران,
 Out Qty,از تعداد,
 Out Value,ارزش از,
 Out of Order,خارج از سفارش,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),مجموع (بدون مالیات),
 Total Achieved,مجموع بهدستآمده,
 Total Actual,مجموع واقعی,
-Total Allocated Leaves,مجموع برگه های برگزیده,
 Total Amount,مقدار کل,
 Total Amount Credited,مبلغ کل اعتبار,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,مجموع اتهامات قابل اجرا در خرید اقلام دریافت جدول باید همان مجموع مالیات و هزینه شود,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,آپلود سر نامه و آرم خود را. (شما می توانید آنها را بعد از ویرایش).,
 Upper Income,درآمد بالاتر,
 Use Sandbox,استفاده از گودال ماسهبازی,
-Used Leaves,برگهای مورد استفاده,
 User,کاربر,
 User ID,ID کاربر,
 User ID not set for Employee {0},ID کاربر برای کارمند تنظیم نشده {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),دوره گارانتی (در روز),
 Auto re-order,خودکار دوباره سفارش,
 Reorder level based on Warehouse,سطح تغییر مجدد ترتیب بر اساس انبار,
-Will also apply for variants unless overrridden,همچنین برای انواع اعمال می شود مگر اینکه overrridden,
+Will also apply for variants unless overridden,همچنین برای انواع اعمال می شود مگر اینکه overridden,
 Units of Measure,واحدهای اندازه گیری,
 Will also apply for variants,همچنین برای انواع اعمال می شود,
 Serial Nos and Batches,سریال شماره و دسته,
@@ -7949,12 +7944,10 @@
 Approvers,متقن,
 The first Approver in the list will be set as the default Approver.,اولین تأیید کننده در لیست به عنوان تأیید کننده پیش فرض تنظیم می شود.,
 Shift Request Approver,تأیید کننده درخواست شیفت,
-PAN Number,شماره PAN,
 Provident Fund Account,حساب صندوق تأمین مالی,
 MICR Code,کد MICR,
 Repay unclaimed amount from salary,مبلغ مطالبه نشده از حقوق را بازپرداخت کنید,
 Deduction from salary,کسر از حقوق,
-Expired Leaves,برگهای منقضی شده,
 If this is not checked the loan by default will be considered as a Demand Loan,اگر این مورد بررسی نشود ، وام به طور پیش فرض به عنوان وام تقاضا در نظر گرفته می شود,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,این حساب برای رزرو بازپرداخت وام از وام گیرنده و همچنین پرداخت وام به وام گیرنده استفاده می شود,
 This account is capital account which is used to allocate capital for loan disbursal account ,این حساب حساب سرمایه ای است که برای تخصیص سرمایه برای حساب پرداخت وام استفاده می شود,
@@ -8748,3 +8741,5 @@
 Is Mandatory,اجباری است,
 WhatsApp,واتس اپ,
 Make a call,تماس بگیر,
+Approve,تایید,
+Reject,رد کردن,
diff --git a/erpnext/translations/fi.csv b/erpnext/translations/fi.csv
index 6a58343..33cf157 100644
--- a/erpnext/translations/fi.csv
+++ b/erpnext/translations/fi.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Automaattinen toistuva asiakirja päivitetty,
 Automotive,Automotive,
 Available,saatavissa,
-Available Leaves,Saatavilla olevat lehdet,
 Available Qty,saatava yksikkömäärä,
 Available Selling,Saatavana myyntiin,
 Available for use date is required,Käytettävä päivämäärä on pakollinen,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub-synkronointitunnus,
 Human Resource,henkilöstöresurssi,
 Human Resources,Henkilöstöresurssit,
-IFSC Code,IFSC-koodi,
 IGST Amount,IGST Määrä,
 IP Address,IP-osoite,
 ITC Available (whether in full op part),ITC käytettävissä (onko täysin op-osa),
@@ -1666,7 +1664,6 @@
 Other,muut,
 Other Reports,Muut raportit,
 "Other outward supplies(Nil rated,Exempted)","Muut ulkoiset tarvikkeet (nolla, vapautettu)",
-Others,Muut,
 Out Qty,ulkona yksikkömäärä,
 Out Value,out Arvo,
 Out of Order,Epäkunnossa,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Yhteensä (ilman veroa),
 Total Achieved,"Yhteensä, saavutettu",
 Total Actual,Kiinteä summa yhteensä,
-Total Allocated Leaves,Kokonaisrajaiset lehdet,
 Total Amount,Yhteensä,
 Total Amount Credited,Laskettu kokonaismäärä,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Saapumistositteen riveillä olevat maksut pitää olla sama kuin verot ja maksut osiossa,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Tuo kirjeen ylätunniste ja logo. (voit muokata niitä myöhemmin),
 Upper Income,Ylemmät tulot,
 Use Sandbox,Käytä Sandbox,
-Used Leaves,Käytetyt lehdet,
 User,käyttäjä,
 User ID,käyttäjätunnus,
 User ID not set for Employee {0},Käyttäjätunnusta ei asetettu työntekijälle {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Takuuaika (päivinä),
 Auto re-order,Auto re-order,
 Reorder level based on Warehouse,Varastoon perustuva täydennystilaustaso,
-Will also apply for variants unless overrridden,"Sovelletaan myös tuotemalleissa, ellei kumota",
+Will also apply for variants unless overridden,"Sovelletaan myös tuotemalleissa, ellei kumota",
 Units of Measure,Mittayksiköt,
 Will also apply for variants,Sovelletaan myös tuotemalleissa,
 Serial Nos and Batches,Sarjanumerot ja Erät,
@@ -7949,12 +7944,10 @@
 Approvers,Hyväksyjät,
 The first Approver in the list will be set as the default Approver.,Luettelon ensimmäinen hyväksyntä asetetaan oletuksen hyväksyjäksi.,
 Shift Request Approver,Vaihtopyynnön hyväksyntä,
-PAN Number,PAN-numero,
 Provident Fund Account,Provident Fund -tili,
 MICR Code,MICR-koodi,
 Repay unclaimed amount from salary,Palauta takaisin perimät palkat,
 Deduction from salary,Vähennys palkasta,
-Expired Leaves,Vanhentuneet lehdet,
 If this is not checked the loan by default will be considered as a Demand Loan,"Jos tätä ei ole valittu, laina katsotaan oletuksena kysyntälainaksi",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Tätä tiliä käytetään lainan takaisinmaksun varaamiseen luotonsaajalta ja lainojen maksamiseen myös luotonottajalle,
 This account is capital account which is used to allocate capital for loan disbursal account ,"Tämä tili on pääomatili, jota käytetään pääoman kohdistamiseen lainan maksamiseen",
@@ -8748,3 +8741,5 @@
 Is Mandatory,On pakollinen,
 WhatsApp,WhatsApp,
 Make a call,Soita,
+Approve,Hyväksyä,
+Reject,Hylätä,
diff --git a/erpnext/translations/fr.csv b/erpnext/translations/fr.csv
index 3180631..d15af74 100644
--- a/erpnext/translations/fr.csv
+++ b/erpnext/translations/fr.csv
@@ -21,9 +21,6 @@
 A customer with the same name already exists,Un client avec un nom identique existe déjà,
 A question must have more than one options,Une question doit avoir plus d'une option,
 A qustion must have at least one correct options,Une qustion doit avoir au moins une des options correctes,
-A4,A4,
-API Endpoint,API Endpoint,
-API Key,Clé API,
 Abbr can not be blank or space,Abré. ne peut être vide ou contenir un espace,
 Abbreviation already used for another company,Abréviation déjà utilisée pour une autre société,
 Abbreviation cannot have more than 5 characters,L'abbréviation ne peut pas avoir plus de 5 caractères,
@@ -36,9 +33,7 @@
 Academic Year,Année académique,
 Academic Year: ,Année scolaire:,
 Accepted + Rejected Qty must be equal to Received quantity for Item {0},La Qté Acceptée + Rejetée doit être égale à la quantité Reçue pour l'Article {0},
-Access Token,Jeton d'Accès,
 Accessable Value,Valeur accessible,
-Account,Compte,
 Account Number,Numéro de compte,
 Account Number {0} already used in account {1},Numéro de compte {0} déjà utilisé dans le compte {1},
 Account Pay Only,Compte Bénéficiaire Seulement,
@@ -75,12 +70,10 @@
 Accounting Ledger,Livre des Comptes,
 Accounting journal entries.,Les écritures comptables.,
 Accounts,Comptes,
-Accounts Manager,Responsable des Comptes,
 Accounts Payable,Comptes Créditeurs,
 Accounts Payable Summary,Résumé des Comptes Créditeurs,
 Accounts Receivable,Comptes débiteurs,
 Accounts Receivable Summary,Résumé des Comptes Débiteurs,
-Accounts User,Comptable,
 Accounts table cannot be blank.,Le tableau de comptes ne peut être vide.,
 Accumulated Depreciation,Amortissement Cumulé,
 Accumulated Depreciation Amount,Montant d'Amortissement Cumulé,
@@ -89,10 +82,8 @@
 Accumulated Values,Valeurs accumulées,
 Accumulated Values in Group Company,Valeurs accumulées dans la société mère,
 Achieved ({}),Atteint ({}),
-Action,Action,
 Action Initialised,Action initialisée,
 Actions,Actions,
-Active,actif,
 Activity Cost exists for Employee {0} against Activity Type - {1},Des Coûts d'Activité existent pour l'Employé {0} pour le Type d'Activité - {1},
 Activity Cost per Employee,Coût de l'Activité par Employé,
 Activity Type,Type d'activité,
@@ -104,7 +95,6 @@
 Actual Qty: Quantity available in the warehouse.,Quantité réelle : Quantité disponible dans l'entrepôt .,
 Actual qty in stock,Qté réelle en stock,
 Actual type tax cannot be included in Item rate in row {0},Le type de taxe réel ne peut pas être inclus dans le prix de l'Article à la ligne {0},
-Add,Ajouter,
 Add / Edit Prices,Ajouter / Modifier Prix,
 Add Comment,Ajouter un Commentaire,
 Add Customers,Ajouter des clients,
@@ -127,17 +117,11 @@
 Add notes,Ajouter des notes,
 Add the rest of your organization as your users. You can also add invite Customers to your portal by adding them from Contacts,Ajouter le reste de votre organisation en tant qu'utilisateurs. Vous pouvez aussi inviter des Clients sur votre portail en les ajoutant depuis les Contacts,
 Add/Remove Recipients,Ajouter/Supprimer des Destinataires,
-Added,Ajouté,
 Added {0} users,{0} utilisateurs ajoutés,
 Additional Salary Component Exists.,La composante salariale supplémentaire existe.,
-Address,Adresse,
-Address Line 2,Adresse Ligne 2,
 Address Name,Nom de l'Adresse,
-Address Title,Titre de l'Adresse,
-Address Type,Type d'Adresse,
 Administrative Expenses,Charges Administratives,
 Administrative Officer,Agent administratif,
-Administrator,Administrateur,
 Admission,Admission,
 Admission and Enrollment,Admission et inscription,
 Admissions for {0},Admissions pour {0},
@@ -171,7 +155,6 @@
 All BOMs,Toutes les nomenclatures,
 All Contacts.,Tous les contacts.,
 All Customer Groups,Tous les Groupes Client,
-All Day,Toute la Journée,
 All Departments,Tous les départements,
 All Healthcare Service Units,Tous les services de soins de santé,
 All Item Groups,Tous les Groupes d'Articles,
@@ -193,8 +176,6 @@
 "Already set default in pos profile {0} for user {1}, kindly disabled default","Déjà défini par défaut dans le profil pdv {0} pour l'utilisateur {1}, veuillez désactiver la valeur par défaut",
 Alternate Item,Article alternatif,
 Alternative item must not be same as item code,L'article alternatif ne doit pas être le même que le code article,
-Amended From,Modifié Depuis,
-Amount,Montant,
 Amount After Depreciation,Montant après amortissement,
 Amount of Integrated Tax,Montant de la taxe intégrée,
 Amount of TDS Deducted,Quantité de TDS déduite,
@@ -216,7 +197,6 @@
 Another Sales Person {0} exists with the same Employee id,Un autre Commercial {0} existe avec le même ID d'Employé,
 Antibiotic,Antibiotique,
 Apparel & Accessories,Vêtements & Accessoires,
-Applicable For,Applicable Pour,
 "Applicable if the company is SpA, SApA or SRL","Applicable si la société est SpA, SApA ou SRL",
 Applicable if the company is a limited liability company,Applicable si la société est une société à responsabilité limitée,
 Applicable if the company is an Individual or a Proprietorship,Applicable si la société est un particulier ou une entreprise,
@@ -264,15 +244,12 @@
 Asset {0} does not belong to company {1},L'actif {0} ne fait pas partie à la société {1},
 Asset {0} must be submitted,L'actif {0} doit être soumis,
 Assets,Actifs - Immo.,
-Assign To,Attribuer À,
 Associate,Associé,
 At least one mode of payment is required for POS invoice.,Au moins un mode de paiement est nécessaire pour une facture de PDV,
 Atleast one item should be entered with negative quantity in return document,Au moins un article doit être saisi avec quantité négative dans le document de retour,
 Atleast one of the Selling or Buying must be selected,Au moins Vente ou Achat doit être sélectionné,
 Atleast one warehouse is mandatory,Au moins un entrepôt est obligatoire,
 Attach Logo,Attacher le logo,
-Attachment,Pièce jointe,
-Attachments,Pièces jointes,
 Attendance can not be marked for future dates,La présence ne peut pas être marquée pour les dates à venir,
 Attendance date can not be less than employee's joining date,Date de présence ne peut pas être antérieure à la date d'embauche de l'employé,
 Attendance for employee {0} is already marked,La présence de l'employé {0} est déjà marquée,
@@ -282,11 +259,9 @@
 Attribute {0} selected multiple times in Attributes Table,Attribut {0} sélectionné à plusieurs reprises dans le Tableau des Attributs,
 Authorized Signatory,Signataire Autorisé,
 Auto Material Requests Generated,Demandes de Matériel Générées Automatiquement,
-Auto Repeat,Répétition automatique,
 Auto repeat document updated,Document de répétition automatique mis à jour,
 Automotive,Automobile,
 Available,Disponible,
-Available Leaves,Congés disponibles,
 Available Qty,Qté disponible,
 Available Selling,Vente disponible,
 Available for use date is required,La date de mise en service est nécessaire,
@@ -333,8 +308,6 @@
 Banking and Payments,Banque et paiements,
 Barcode {0} already used in Item {1},Le Code Barre {0} est déjà utilisé dans l'article {1},
 Barcode {0} is not a valid {1} code,Le code-barres {0} n'est pas un code {1} valide,
-Base URL,URL de base,
-Based On,Basé Sur,
 Based On Payment Terms,Basé sur les conditions de paiement,
 Batch,Lot,
 Batch Entries,Entrées de lot,
@@ -407,7 +380,6 @@
 Can refer row only if the charge type is 'On Previous Row Amount' or 'Previous Row Total',Peut se référer à ligne seulement si le type de charge est 'Montant de la ligne précedente' ou 'Total des lignes précedente',
 "Can't change valuation method, as there are transactions against some items which does not have it's own valuation method","Impossible de modifier la méthode de valorisation, car il existe des transactions sur certains articles ne possèdant pas leur propre méthode de valorisation",
 Can't create standard criteria. Please rename the criteria,Impossible de créer des critères standard. Veuillez renommer les critères,
-Cancel,Annuler,
 Cancel Material Visit {0} before cancelling this Warranty Claim,Annuler la Visite Matérielle {0} avant d'annuler cette Réclamation de Garantie,
 Cancel Material Visits {0} before cancelling this Maintenance Visit,Annuler les Visites Matérielles {0} avant d'annuler cette Visite de Maintenance,
 Cancel Subscription,Annuler l'abonnement,
@@ -460,8 +432,6 @@
 Cash In Hand,Liquidités,
 Cash or Bank Account is mandatory for making payment entry,Espèces ou Compte Bancaire est obligatoire pour réaliser une écriture de paiement,
 Cashier Closing,Fermeture de la caisse,
-Category,Catégorie,
-Category Name,Nom de la Catégorie,
 Caution,Mise en garde,
 Central Tax,Taxe centrale,
 Certification,Certification,
@@ -489,32 +459,22 @@
 Child nodes can be only created under 'Group' type nodes,Les noeuds enfants peuvent être créés uniquement dans les nœuds de type 'Groupe',
 Child warehouse exists for this warehouse. You can not delete this warehouse.,Un entrepôt enfant existe pour cet entrepôt. Vous ne pouvez pas supprimer cet entrepôt.,
 Circular Reference Error,Erreur de référence circulaire,
-City,Ville,
-City/Town,Ville,
 Clay,Argile,
-Clear filters,Effacer les filtres,
 Clear values,Des valeurs claires,
 Clearance Date,Date de Compensation,
 Clearance Date not mentioned,Date de Compensation non indiquée,
 Clearance Date updated,Date de Compensation mise à jour,
-Client,Client,
-Client ID,ID Client,
-Client Secret,Secret Client,
 Clinical Procedure,Procédure clinique,
 Clinical Procedure Template,Modèle de procédure clinique,
 Close Balance Sheet and book Profit or Loss.,Clôturer Bilan et Compte de Résultats.,
 Close Loan,Prêt proche,
 Close the POS,Clôturer le point de vente,
-Closed,Fermé,
 Closed order cannot be cancelled. Unclose to cancel.,Les commandes fermées ne peuvent être annulées. Réouvrir pour annuler.,
 Closing (Cr),Fermeture (Cr),
 Closing (Dr),Fermeture (Dr),
 Closing (Opening + Total),Fermeture (ouverture + total),
 Closing Account {0} must be of type Liability / Equity,Le Compte Clôturé {0} doit être de type Passif / Capitaux Propres,
 Closing Balance,Solde de clôture,
-Code,Code,
-Collapse All,Tout réduire,
-Color,Couleur,
 Colour,Couleur,
 Combined invoice portion must equal 100%,La portion combinée de la facture doit être égale à 100%,
 Commercial,Commercial,
@@ -526,7 +486,6 @@
 Company (not Customer or Supplier) master.,Données de base de la Société (ni les Clients ni les Fournisseurs),
 Company Abbreviation,Abréviation de la Société,
 Company Abbreviation cannot have more than 5 characters,L'abréviation de l'entreprise ne peut pas comporter plus de 5 caractères,
-Company Name,Nom de la Société,
 Company Name cannot be Company,Nom de la Société ne peut pas être Company,
 Company currencies of both the companies should match for Inter Company Transactions.,Les devises des deux sociétés doivent correspondre pour les transactions inter-sociétés.,
 Company is manadatory for company account,La société est le maître d'œuvre du compte d'entreprise,
@@ -536,7 +495,6 @@
 Complaint,Plainte,
 Completion Date,Date d'Achèvement,
 Computer,Ordinateur,
-Condition,Conditions,
 Configure,Configurer,
 Configure {0},Configurer {0},
 Confirmed orders from Customers.,Commandes confirmées des clients.,
@@ -553,11 +511,8 @@
 Consumed Amount,Montant Consommé,
 Consumed Qty,Qté Consommée,
 Consumer Products,Produits de Consommation,
-Contact,Contact,
 Contact Us,Contactez nous,
-Content,Contenu,
 Content Masters,Masters de contenu,
-Content Type,Type de Contenu,
 Continue Configuration,Continuer la configuration,
 Contract,Contrat,
 Contract End Date must be greater than Date of Joining,La Date de Fin de Contrat doit être supérieure à la Date d'Embauche,
@@ -598,7 +553,6 @@
 Course Schedule,Horaire du cours,
 Course: ,Cours:,
 Cr,Cr,
-Create,Créer,
 Create BOM,Créer une nomenclature,
 Create Delivery Trip,Créer un voyage de livraison,
 Create Employee,Créer un employé,
@@ -674,8 +628,6 @@
 Current Liabilities,Dettes Actuelles,
 Current Qty,Qté actuelle,
 Current invoice {0} is missing,La facture en cours {0} est manquante,
-Custom HTML,HTML Personnalisé,
-Custom?,Personnaliser ?,
 Customer,Client,
 Customer Addresses And Contacts,Adresses et Contacts des Clients,
 Customer Contact,Contact client,
@@ -700,7 +652,6 @@
 Data Import and Export,Importer et Exporter des Données,
 Data Import and Settings,Importation de données et paramètres,
 Database of potential customers.,Base de données de clients potentiels.,
-Date Format,Format de Date,
 Date Of Retirement must be greater than Date of Joining,La Date de Départ à la Retraite doit être supérieure à Date d'Embauche,
 Date of Birth,Date de naissance,
 Date of Birth cannot be greater than today.,Date de Naissance ne peut être après la Date du Jour.,
@@ -708,7 +659,6 @@
 Date of Joining,Date d'Embauche,
 Date of Joining must be greater than Date of Birth,La Date d'Embauche doit être après à la Date de Naissance,
 Date of Transaction,Date de transaction,
-Day,Jour,
 Debit,Débit,
 Debit ({0}),Débit ({0}),
 Debit Account,Compte de débit,
@@ -724,14 +674,12 @@
 Default BOM ({0}) must be active for this item or its template,Nomenclature par défaut ({0}) doit être actif pour ce produit ou son modèle,
 Default BOM for {0} not found,Nomenclature par défaut {0} introuvable,
 Default BOM not found for Item {0} and Project {1},La nomenclature par défaut n'a pas été trouvée pour l'Article {0} et le Projet {1},
-Default Letter Head,En-Tête de Courrier par Défaut,
 Default Tax Template,Modèle de Taxes par Défaut,
 Default Unit of Measure for Item {0} cannot be changed directly because you have already made some transaction(s) with another UOM. You will need to create a new Item to use a different Default UOM.,L’Unité de Mesure par Défaut pour l’Article {0} ne peut pas être modifiée directement parce que vous avez déjà fait une (des) transaction (s) avec une autre unité de mesure. Vous devez créer un nouvel article pour utiliser une UdM par défaut différente.,
 Default Unit of Measure for Variant '{0}' must be same as in Template '{1}',L’Unité de mesure par défaut pour la variante '{0}' doit être la même que dans le Modèle '{1}',
 Default settings for buying transactions.,Paramètres par défaut pour les transactions d'achat.,
 Default settings for selling transactions.,Paramètres par défaut pour les transactions de vente.,
 Default tax templates for sales and purchase are created.,Les modèles de taxe par défaut pour les ventes et les achats sont créés.,
-Defaults,Valeurs Par Défaut,
 Defense,Défense,
 Define Project type.,Définir le type de projet.,
 Define budget for a financial year.,Définir le budget pour un exercice.,
@@ -751,10 +699,8 @@
 Delivery Note {0} must not be submitted,Bon de Livraison {0} ne doit pas être soumis,
 Delivery Notes {0} must be cancelled before cancelling this Sales Order,Bons de Livraison {0} doivent être annulés avant d’annuler cette Commande Client,
 Delivery Notes {0} updated,Notes de livraison {0} mises à jour,
-Delivery Status,Statut de la Livraison,
 Delivery Trip,Service de Livraison,
 Delivery warehouse required for stock item {0},Entrepôt de Livraison requis pour article du stock {0},
-Department,Département,
 Department Stores,Grands magasins,
 Depreciation,Amortissement,
 Depreciation Amount,Montant d'Amortissement,
@@ -769,7 +715,6 @@
 Depreciation Row {0}: Next Depreciation Date cannot be before Purchase Date,Ligne d'amortissement {0}: la date d'amortissement suivante ne peut pas être antérieure à la date d'achat,
 Designer,Designer,
 Detailed Reason,Raison détaillée,
-Details,Détails,
 Details of Outward Supplies and inward supplies liable to reverse charge,Détails des livraisons sortantes et des livraisons entrantes susceptibles d'inverser la charge,
 Details of the operations carried out.,Détails des opérations effectuées.,
 Diagnosis,Diagnostique,
@@ -806,16 +751,11 @@
 Doc Name,Nom du document,
 Doc Type,Type de document,
 Docs Search,Recherche de documents,
-Document Name,Nom du Document,
-Document Type,Type de Document,
-Domain,Domaine,
-Domains,Domaines,
 Done,Terminé,
 Donor,Donneur,
 Donor Type information.,Informations sur le type de donneur.,
 Donor information.,Informations sur le donneur,
 Download JSON,Télécharger JSON,
-Draft,Brouillon,
 Drop Ship,Expédition Directe,
 Drug,Médicament,
 Due / Reference Date cannot be after {0},Date d’échéance / de référence ne peut pas être après le {0},
@@ -836,7 +776,6 @@
 ERPNext Settings,Paramètres ERPNext,
 Earliest,Au plus tôt,
 Earnest Money,Arrhes,
-Edit,modifier,
 Edit Publishing Details,Modifier les détails de publication,
 "Edit in full page for more options like assets, serial nos, batches etc.","Modifier en pleine page pour plus d'options comme les actifs, les numéros de série, les lots, etc.",
 Education,Éducation,
@@ -847,13 +786,9 @@
 Electronic Equipments,Équipements électroniques,
 Electronics,Électronique,
 Eligible ITC,CTI éligible,
-Email Account,Compte Email,
-Email Address,Adresse électronique,
 "Email Address must be unique, already exists for {0}","Adresse Email doit être unique, existe déjà pour {0}",
 Email Digest: ,Compte Rendu par Email :,
 Email Reminders will be sent to all parties with email contacts,Les rappels par emails seront envoyés à toutes les parties avec des contacts ayant une adresse email,
-Email Sent,Email Envoyé,
-Email Template,Modèle d'email,
 Email not found in default contact,Email non trouvé dans le contact par défaut,
 Email sent to {0},Email envoyé à {0},
 Employee,Employé,
@@ -867,9 +802,7 @@
 Employee {0} has already applied for {1} between {2} and {3} : ,L'employé {0} a déjà postulé pour {1} entre {2} et {3}:,
 Employee {0} of grade {1} have no default leave policy,L'employé {0} avec l'échelon {1} n'a pas de politique de congé par défaut,
 Enable / disable currencies.,Activer / Désactiver les devises,
-Enabled,Activé,
 "Enabling 'Use for Shopping Cart', as Shopping Cart is enabled and there should be at least one Tax Rule for Shopping Cart","Activation de 'Utiliser pour Panier', comme le Panier est activé et qu'il devrait y avoir au moins une Règle de Taxes pour le Panier",
-End Date,Date de Fin,
 End Date can not be less than Start Date,La date de fin ne peut être inférieure à la date de début,
 End Date cannot be before Start Date.,La date de fin ne peut pas être antérieure à la date de début.,
 End Year,Année de Fin,
@@ -890,7 +823,6 @@
 Entertainment & Leisure,Divertissement et Loisir,
 Entertainment Expenses,Charges de Représentation,
 Equity,Capitaux Propres,
-Error Log,Journal des Erreurs,
 Error evaluating the criteria formula,Erreur lors de l'évaluation de la formule du critère,
 Error in formula or condition: {0},Erreur dans la formule ou dans la condition : {0},
 Error: Not a valid id?,Erreur : Pas un identifiant valide ?,
@@ -902,7 +834,6 @@
 Excise Invoice,Facture d'Accise,
 Execution,Exécution,
 Executive Search,Recrutement de Cadres,
-Expand All,Développer Tout,
 Expected Delivery Date,Date de livraison prévue,
 Expected Delivery Date should be after Sales Order Date,La Date de Livraison Prévue doit être après la Date indiquée sur la Commande Client,
 Expected End Date,Date de fin prévue,
@@ -925,30 +856,22 @@
 Export E-Invoices,Exporter des factures électroniques,
 Extra Large,Extra large,
 Extra Small,Très Petit,
-Fail,Échec,
-Failed,Échoué,
 Failed to create website,Échec de la création du site Web,
 Failed to install presets,Échec de l'installation des préréglages,
 Failed to login,Échec de la connexion,
 Failed to setup company,Échec de la configuration de la société,
 Failed to setup defaults,Échec de la configuration par défaut,
 Failed to setup post company fixtures,Échec de la configuration des éléments liés la société,
-Fax,Fax,
 Fee,Frais,
 Fee Created,Honoraires Créés,
 Fee Creation Failed,La création des honoraires a échoué,
 Fee Creation Pending,Création d'honoraires en attente,
 Fee Records Created - {0},Archive d'Honoraires Créée - {0},
-Feedback,Retour d’Expérience,
 Fees,Honoraires,
-Female,Féminin,
 Fetch Data,Récupérer des données,
 Fetch Subscription Updates,Vérifier les mises à jour des abonnements,
 Fetch exploded BOM (including sub-assemblies),Récupérer la nomenclature éclatée (y compris les sous-ensembles),
 Fetching records......,Récupération des enregistrements ......,
-Field Name,Nom du Champ,
-Fieldname,Nom du Champ,
-Fields,Champ,
 "Filter Fields Row #{0}: Fieldname <b>{1}</b> must be of type ""Link"" or ""Table MultiSelect""",Filtrer les champs Ligne # {0}: le nom de champ <b>{1}</b> doit être de type &quot;Lien&quot; ou &quot;Table MultiSelect&quot;,
 Filter Total Zero Qty,Filtrer les totaux pour les qtés égales à zéro,
 Finance Book,Livre comptable,
@@ -962,7 +885,6 @@
 Finished Goods,Produits finis,
 Finished Item {0} must be entered for Manufacture type entry,Le Produit Fini {0} doit être saisi pour une écriture de type Production,
 Finished product quantity <b>{0}</b> and For Quantity <b>{1}</b> cannot be different,La quantité de produit fini <b>{0}</b> et Pour la quantité <b>{1}</b> ne peut pas être différente,
-First Name,Prénom,
 "Fiscal Regime is mandatory, kindly set the fiscal regime in the company {0}","Le régime fiscal est obligatoire, veuillez définir le régime fiscal de l'entreprise {0}",
 Fiscal Year,Exercice fiscal,
 Fiscal Year End Date should be one year after Fiscal Year Start Date,La date de fin d'exercice doit être un an après la date de début d'exercice,
@@ -995,9 +917,6 @@
 Forum Activity,Activité du forum,
 Free item code is not selected,Le code d'article gratuit n'est pas sélectionné,
 Freight and Forwarding Charges,Frais de Fret et d'Expédition,
-Frequency,Fréquence,
-Friday,Vendredi,
-From,À partir de,
 From Address 1,Ligne d'addresse 1 (Origine),
 From Address 2,Ligne d'addresse 2 (Origine),
 From Currency and To Currency cannot be same,La Devise de Base et la Devise de Cotation ne peuvent pas identiques,
@@ -1022,18 +941,15 @@
 From value must be less than to value in row {0},De la valeur doit être inférieure à la valeur de la ligne {0},
 From {0} | {1} {2},Du {0} | {1} {2},
 Fulfillment,Livraison,
-Full Name,Nom Complet,
 Fully Depreciated,Complètement Déprécié,
 Furnitures and Fixtures,Meubles et Accessoires,
 "Further accounts can be made under Groups, but entries can be made against non-Groups","D'autres comptes individuels peuvent être créés dans les groupes, mais les écritures ne peuvent être faites que sur les comptes individuels",
 Further cost centers can be made under Groups but entries can be made against non-Groups,"D'autres centres de coûts peuvent être créés dans des Groupes, mais des écritures ne peuvent être faites que sur des centres de coûts individuels.",
-Further nodes can be only created under 'Group' type nodes,D'autres nœuds peuvent être créés uniquement sous les nœuds de type 'Groupe',
 GSTIN,GSTIN,
 GSTR3B-Form,GSTR3B-Form,
 Gain/Loss on Asset Disposal,Gain/Perte sur Cessions des Immobilisations,
 Gantt Chart,Diagramme de Gantt,
 Gantt chart of all tasks.,Diagramme de Gantt de toutes les tâches.,
-Gender,Sexe,
 General,Général,
 General Ledger,Grand Livre,
 Generate Material Requests (MRP) and Work Orders.,Générer des demandes de matériel (MRP) et des ordres de travail.,
@@ -1051,7 +967,6 @@
 Get customers from,Obtenir les clients de,
 Get from Patient Encounter,Obtenez de la rencontre du patient,
 Getting Started,Commencer,
-GitHub Sync ID,GitHub Sync ID,
 Global settings for all manufacturing processes.,Paramètres globaux pour tous les processus de production.,
 Go to the Desktop and start using ERPNext,Accédez au bureau et commencez à utiliser ERPNext,
 GoCardless SEPA Mandate,Mandat SEPA GoCardless,
@@ -1091,8 +1006,6 @@
 HR Manager,Responsable RH,
 HSN,HSN,
 HSN/SAC,HSN / SAC,
-Half Yearly,Semestriel,
-Half-Yearly,Semestriel,
 Hardware,Matériel,
 Head of Marketing and Sales,Responsable du Marketing et des Ventes,
 Health Care,Soins de santé,
@@ -1107,7 +1020,6 @@
 Healthcare Services,Services de santé,
 Healthcare Settings,Paramètres de santé,
 Help Results for,Aide Résultats pour,
-High,Haut,
 High Sensitivity,Haute sensibilité,
 Hold,Mettre en attente,
 Hold Invoice,Facture en attente,
@@ -1115,16 +1027,12 @@
 Holiday List,Liste de vacances,
 Hotel Rooms of type {0} are unavailable on {1},Les chambres d'hôtel de type {0} sont indisponibles le {1},
 Hotels,Hôtels,
-Hourly,Horaire,
 Hours,Heures,
 How Pricing Rule is applied?,Comment la Règle de Prix doit-elle être appliquée ?,
 Hub Category,Catégorie du Hub,
-Hub Sync ID,Hub Sync ID,
 Human Resource,Ressource humaine,
 Human Resources,Ressources humaines,
-IFSC Code,Code IFSC,
 IGST Amount,IGST Montant,
-IP Address,Adresse IP,
 ITC Available (whether in full op part),CIT Disponible (que ce soit en partie op),
 ITC Reversed,CTI inversé,
 Identifying Decision Makers,Identifier les décideurs,
@@ -1135,11 +1043,7 @@
 "If unlimited expiry for the Loyalty Points, keep the Expiry Duration empty or 0.","Si vous souhaitez ne pas mettre de date d'expiration pour les points de fidélité, laissez la durée d'expiration vide ou mettez 0.",
 "If you have any questions, please get back to us.","Si vous avez des questions, veuillez revenir vers nous.",
 Ignore Existing Ordered Qty,Ignorer la quantité commandée existante,
-Image,Image,
-Image View,Voir l'Image,
-Import Data,Importer des données,
 Import Day Book Data,Données du journal d'importation,
-Import Log,Journal d'import,
 Import Master Data,Importer des données de base,
 Import in Bulk,Importer en Masse,
 Import of goods,Importation de marchandises,
@@ -1153,7 +1057,6 @@
 In Stock: ,En Stock :,
 In Value,En valeur,
 "In the case of multi-tier program, Customers will be auto assigned to the concerned tier as per their spent","Dans le cas d'un programme à plusieurs échelons, les clients seront automatiquement affectés au niveau approprié en fonction de leurs dépenses",
-Inactive,Inactif,
 Incentives,Incitations,
 Include Default Book Entries,Inclure les entrées de livre par défaut,
 Include Exploded Items,Inclure les articles éclatés,
@@ -1187,7 +1090,6 @@
 Inter-State Supplies,Fournitures inter-Etats,
 Internet Publishing,Publication Internet,
 Intra-State Supplies,Fournitures intra-étatiques,
-Introduction,Introduction,
 Invalid Attribute,Attribut invalide,
 Invalid Blanket Order for the selected Customer and Item,Commande avec limites non valide pour le client et l'article sélectionnés,
 Invalid Company for Inter Company Transaction.,Société non valide pour une transaction inter-sociétés.,
@@ -1219,8 +1121,6 @@
 Invoices for Costumers.,Factures pour les clients.,
 Inward supplies from ISD,Approvisionnement entrant de la DSI,
 Inward supplies liable to reverse charge (other than 1 & 2 above),Approvisionnements entrants susceptibles d’être dédouanés (autres que 1 et 2 ci-dessus),
-Is Active,Est Active,
-Is Default,Est Défaut,
 Is Existing Asset,Est Actif Existant,
 Is Frozen,Est gelé,
 Is Group,Est un Groupe,
@@ -1290,7 +1190,6 @@
 Journal Entries {0} are un-linked,Les Écritures de Journal {0} ne sont pas liées,
 Journal Entry,Écriture de Journal,
 Journal Entry {0} does not have account {1} or already matched against other voucher,L’Écriture de Journal {0} n'a pas le compte {1} ou est déjà réconciliée avec une autre pièce justificative,
-Kanban Board,Tableau Kanban,
 Key Reports,Rapports clés,
 LMS Activity,Activité LMS,
 Lab Test,Test de laboratoire,
@@ -1301,12 +1200,10 @@
 Lab Tests and Vital Signs,Tests de laboratoire et signes vitaux,
 Lab result datetime cannot be before testing datetime,La date et l'heure du résultat de laboratoire ne peuvent pas être avant la date et l'heure du test,
 Lab testing datetime cannot be before collection datetime,La date et l'heure du test de laboratoire ne peuvent pas être avant la date et l'heure de collecte,
-Label,Étiquette,
 Laboratory,Laboratoire,
 Large,Grand,
 Last Communication,Dernière communication,
 Last Communication Date,Date de la Dernière Communication,
-Last Name,Nom de Famille,
 Last Order Amount,Montant de la Dernière Commande,
 Last Order Date,Date de la dernière commande,
 Last Purchase Price,Dernier prix d'achat,
@@ -1328,9 +1225,7 @@
 Ledger,Livre,
 Legal,Juridique,
 Legal Expenses,Frais juridiques,
-Letter Head,En-Tête,
 Letter Heads for print templates.,En-Têtes pour les modèles d'impression.,
-Level,Niveau,
 Liability,Passif,
 Limit Crossed,Limite Dépassée,
 Link to Material Request,Lien vers la demande de matériel,
@@ -1345,7 +1240,6 @@
 Logs for maintaining sms delivery status,Journaux pour maintenir le statut de livraison des sms,
 Lost,Perdu,
 Lost Reasons,Raisons perdues,
-Low,Bas,
 Low Sensitivity,Faible sensibilité,
 Lower Income,Revenu bas,
 Loyalty Amount,Montant de fidélité,
@@ -1357,13 +1251,11 @@
 Main,Principal,
 Maintenance,Entretien,
 Maintenance Log,Journal de maintenance,
-Maintenance Manager,Responsable de Maintenance,
 Maintenance Schedule,Échéancier d'Entretien,
 Maintenance Schedule is not generated for all the items. Please click on 'Generate Schedule',L'Échéancier d'Entretien n'est pas créé pour tous les articles. Veuillez clicker sur 'Créer un Échéancier',
 Maintenance Schedule {0} exists against {1},Un Calendrier de Maintenance {0} existe pour {1},
 Maintenance Schedule {0} must be cancelled before cancelling this Sales Order,L'Échéancier d'Entretien {0} doit être annulé avant d'annuler cette Commande Client,
 Maintenance Status has to be Cancelled or Completed to Submit,Le statut de maintenance doit être annulé ou complété pour pouvoir être envoyé,
-Maintenance User,Maintenance Utilisateur,
 Maintenance Visit,Visite d'Entretien,
 Maintenance Visit {0} must be cancelled before cancelling this Sales Order,La Visite d'Entretien {0} doit être annulée avant d'annuler cette Commande Client,
 Maintenance start date can not be before delivery date for Serial No {0},La date de début d'entretien ne peut pas être antérieure à la date de livraison pour le N° de Série {0},
@@ -1371,7 +1263,6 @@
 Make Payment,Faire un Paiement,
 Make project from a template.,Faire un projet à partir d'un modèle.,
 Making Stock Entries,Faire des Écritures de Stock,
-Male,Masculin,
 Manage Customer Group Tree.,Gérer l'Arborescence des Groupes de Clients.,
 Manage Sales Partners.,Gérer les Partenaires Commerciaux.,
 Manage Sales Person Tree.,Gérer l'Arborescence des Vendeurs.,
@@ -1381,7 +1272,6 @@
 Manager,Directeur,
 Managing Projects,Gestion de Projets,
 Managing Subcontracting,Gestion de la Sous-traitance,
-Mandatory,Obligatoire,
 Mandatory field - Academic Year,Champ Obligatoire - Année Académique,
 Mandatory field - Get Students From,Champ Obligatoire - Obtenir des étudiants de,
 Mandatory field - Program,Champ obligatoire - Programme,
@@ -1390,8 +1280,6 @@
 Manufacturer Part Number,Numéro de Pièce du Fabricant,
 Manufacturing,Production,
 Manufacturing Quantity is mandatory,Quantité de production obligatoire,
-Mapping,Mapping,
-Mapping Type,Type de Mapping,
 Mark Absent,Marquer Absent,
 Mark Half Day,Marquer Demi-Journée,
 Mark Present,Marquer Présent,
@@ -1426,7 +1314,6 @@
 Medical Code Standard,Standard du code médical,
 Medical Department,Département médical,
 Medical Record,Dossier médical,
-Medium,Moyen,
 Member Activity,Activité des membres,
 Member ID,ID du membre,
 Member Name,Nom de membre,
@@ -1441,12 +1328,8 @@
 Merge Account,Fusionner le compte,
 Merge with Existing Account,Fusionner avec un compte existant,
 "Merging is only possible if following properties are same in both records. Is Group, Root Type, Company","La combinaison est possible seulement si les propriétés suivantes sont les mêmes dans les deux dossiers. Est Groupe, Type de Racine, Société",
-Message Examples,Exemples de Messages,
 Message Sent,Message envoyé,
-Method,Méthode,
 Middle Income,Revenu Intermédiaire,
-Middle Name,Deuxième Nom,
-Middle Name (Optional),Deuxième Prénom (Optionnel),
 Min Amt can not be greater than Max Amt,Min Amt ne peut pas être supérieur à Max Amt,
 Min Qty can not be greater than Max Qty,Qté Min ne peut pas être supérieure à Qté Max,
 Minimum Lead Age (Days),Âge Minimum du lead (Jours),
@@ -1460,14 +1343,9 @@
 Mode of Transportation,Mode de transport,
 Model,Modèle,
 Moderate Sensitivity,Sensibilité modérée,
-Monday,Lundi,
-Monthly,Mensuel,
 Monthly Distribution,Répartition Mensuelle,
-More,Plus,
-More Information,Informations Complémentaires,
 More...,Plus...,
 Motion Picture & Video,Cinéma & Vidéo,
-Move,mouvement,
 Move Item,Déplacer l'Article,
 Multi Currency,Multi-devise,
 Multiple Item prices.,Plusieurs Prix d'Articles.,
@@ -1499,7 +1377,6 @@
 Net Profit,Bénéfice net,
 Net Total,Total net,
 New Account Name,Nouveau Nom de Compte,
-New Address,Nouvelle adresse,
 New BOM,Nouvelle nomenclature,
 New Batch ID (Optional),Nouveau Numéro de Lot (Optionnel),
 New Batch Qty,Nouvelle Qté de Lot,
@@ -1519,13 +1396,11 @@
 New task,Nouvelle tâche,
 New {0} pricing rules are created,De nouvelles règles de tarification {0} sont créées.,
 Newspaper Publishers,Éditeurs de journaux,
-Next,Suivant,
 Next Contact By cannot be same as the Lead Email Address,Prochain Contact Par ne peut être identique à l’Adresse Email du Lead,
 Next Contact Date cannot be in the past,La Date de Prochain Contact ne peut pas être dans le passé,
 Next Steps,Prochaines étapes,
 No Action,Pas d'action,
 No Customers yet!,Pas encore de clients!,
-No Data,Aucune Donnée,
 No Delivery Note selected for Customer {},Aucun bon de livraison sélectionné pour le client {},
 No Item with Barcode {0},Aucun Article avec le Code Barre {0},
 No Item with Serial No {0},Aucun Article avec le N° de Série {0},
@@ -1567,15 +1442,12 @@
 Non Profit (beta),Association (bêta),
 Non-GST outward supplies,Fournitures sortantes non liées à la TPS,
 Non-Group to Group,Non-Groupe à Groupe,
-None,Aucun,
 None of the items have any change in quantity or value.,Aucun des Articles n’a de changement en quantité ou en valeur.,
 Nos,N°,
 Not Available,Indisponible,
 Not Marked,Non marqué,
 Not Paid and Not Delivered,Non payé et non livré,
-Not Permitted,Non Autorisé,
 Not Started,Non Commencé,
-Not active,Non actif,
 Not allow to set alternative item for the item {0},Ne permet pas de définir un autre article pour l'article {0},
 Not allowed to update stock transactions older than {0},Non autorisé à mettre à jour les transactions du stock antérieures à {0},
 Not authorized to edit frozen Account {0},Vous n'êtes pas autorisé à modifier le compte gelé {0},
@@ -1594,7 +1466,6 @@
 Nothing is included in gross,Rien n'est inclus dans le brut,
 Nothing more to show.,Rien de plus à montrer.,
 Notify Customers via Email,Avertir les clients par courrier électronique,
-Number,Nombre,
 Number of Depreciations Booked cannot be greater than Total Number of Depreciations,Nombre d’Amortissements Comptabilisés ne peut pas être supérieur à Nombre Total d'Amortissements,
 Number of Interaction,Nombre d'Interactions,
 Number of Order,Nombre de Commandes,
@@ -1636,7 +1507,6 @@
 Opening Stock Balance,Solde d'Ouverture des Stocks,
 Opening Value,Valeur d'Ouverture,
 Opening {0} Invoice created,Ouverture {0} Facture créée,
-Operation,Opération,
 Operation Time must be greater than 0 for Operation {0},Temps de l'Opération doit être supérieur à 0 pour l'Opération {0},
 "Operation {0} longer than any available working hours in workstation {1}, break down the operation into multiple operations","Opération {0} plus longue que toute heure de travail disponible dans la station de travail {1}, veuillez séparer l'opération en plusieurs opérations",
 Operations,Opérations,
@@ -1649,7 +1519,6 @@
 Opportunity Amount,Montant de l'opportunité,
 "Optional. Sets company's default currency, if not specified.","Optionnel. Défini la devise par défaut de l'entreprise, si non spécifié.",
 Optional. This setting will be used to filter in various transactions.,Facultatif. Ce paramètre sera utilisé pour filtrer différentes transactions.,
-Options,Options,
 Order Count,Compte de Commandes,
 Order Entry,Saisie de Commande,
 Order Value,Valeur de la commande,
@@ -1662,7 +1531,6 @@
 Orders released for production.,Commandes validées pour la production.,
 Organization,Organisation,
 Organization Name,Nom de l'Organisation,
-Other,Autre,
 Other Reports,Autres rapports,
 "Other outward supplies(Nil rated,Exempted)","Autres livraisons sortantes (cotations nulles, exemptées)",
 Others,Autres,
@@ -1679,7 +1547,6 @@
 Overdue,En retard,
 Overlap in scoring between {0} and {1},Chevauchement dans la notation entre {0} et {1},
 Overlapping conditions found between:,Conditions qui coincident touvées entre :,
-Owner,Responsable,
 PAN,Numéro de compte permanent (PAN),
 POS,PDV,
 POS Profile,Profil PDV,
@@ -1694,7 +1561,6 @@
 Paid Amount cannot be greater than total negative outstanding amount {0},Le Montant Payé ne peut pas être supérieur au montant impayé restant {0},
 Paid amount + Write Off Amount can not be greater than Grand Total,Le Montant Payé + Montant Repris ne peut pas être supérieur au Total Général,
 Paid and Not Delivered,Payé et non livré,
-Parameter,Paramètre,
 Parent Item {0} must not be a Stock Item,L'Article Parent {0} ne doit pas être un Élément de Stock,
 Parents Teacher Meeting Attendance,Participation à la réunion parents-professeurs,
 Partially Depreciated,Partiellement déprécié,
@@ -1754,7 +1620,6 @@
 Pension Funds,Fonds de Pension,
 Percentage Allocation should be equal to 100%,Pourcentage d'Allocation doit être égale à 100 %,
 Perception Analysis,Analyse de perception,
-Period,Période,
 Period Closing Entry,Écriture de Clôture de la Période,
 Period Closing Voucher,Bon de Clôture de la Période,
 Periodicity,Périodicité,
@@ -1781,7 +1646,6 @@
 Please define grade for Threshold 0%,Veuillez définir une note pour le Seuil 0%,
 Please enable Applicable on Booking Actual Expenses,Veuillez activer l'option : Applicable sur la base de l'enregistrement des dépenses réelles,
 Please enable Applicable on Purchase Order and Applicable on Booking Actual Expenses,Veuillez activer les options : Applicable sur la base des bons de commande d'achat et Applicable sur la base des bons de commande d'achat,
-Please enable pop-ups,Veuillez autoriser les pop-ups,
 Please enter 'Is Subcontracted' as Yes or No,Veuillez entrer Oui ou Non pour 'Est sous-traitée',
 Please enter API Consumer Key,"Veuillez entrer la clé ""API Consumer Key""",
 Please enter API Consumer Secret,"Veuillez entrer la clé ""API Consumer Secret""",
@@ -1837,7 +1701,6 @@
 Please select BOM in BOM field for Item {0},Veuillez sélectionner une nomenclature dans le champ nomenclature pour l’Article {0},
 Please select Category first,Veuillez d’abord sélectionner une Catégorie,
 Please select Charge Type first,Veuillez d’abord sélectionner le Type de Facturation,
-Please select Company,Veuillez sélectionner une Société,
 Please select Company and Posting Date to getting entries,Veuillez sélectionner la société et la date de comptabilisation pour obtenir les écritures,
 Please select Company first,Veuillez d’abord sélectionner une Société,
 Please select Completion Date for Completed Asset Maintenance Log,Veuillez sélectionner la date d'achèvement pour le journal de maintenance des actifs terminé,
@@ -1878,7 +1741,6 @@
 Please select the assessment group other than 'All Assessment Groups',Sélectionnez un groupe d'évaluation autre que «Tous les Groupes d'Évaluation»,
 Please select the document type first,Veuillez d’abord sélectionner le type de document,
 Please select weekly off day,Veuillez sélectionnez les jours de congé hebdomadaires,
-Please select {0},Veuillez sélectionner {0},
 Please select {0} first,Veuillez d’abord sélectionner {0},
 Please set 'Apply Additional Discount On',Veuillez définir ‘Appliquer Réduction Supplémentaire Sur ‘,
 Please set 'Asset Depreciation Cost Center' in Company {0},Veuillez définir 'Centre de Coûts des Amortissements d’Actifs’ de la Société {0},
@@ -1944,7 +1806,6 @@
 Prescription Duration,Durée de la prescription,
 Prescriptions,Les prescriptions,
 Prev,Précédent,
-Preview,Aperçu,
 Previous Financial Year is not closed,L’Exercice Financier Précédent n’est pas fermé,
 Price,Prix,
 Price List,Liste de prix,
@@ -1962,13 +1823,11 @@
 Pricing Rules are further filtered based on quantity.,Les Règles de Tarification sont d'avantage filtrés en fonction de la quantité.,
 Primary Address Details,Détails de l'adresse principale,
 Primary Contact Details,Détails du contact principal,
-Print Format,Format d'Impression,
 Print IRS 1099 Forms,Imprimer les formulaires IRS 1099,
 Print Report Card,Imprimer le rapport,
 Print Settings,Paramètres d'impression,
 Print and Stationery,Impression et Papeterie,
 Print settings updated in respective print format,Paramètres d'impression mis à jour avec le format d'impression indiqué,
-Print taxes with zero amount,Impression de taxes avec un montant nul,
 Printing and Branding,Impression et Marque,
 Private Equity,Capital Investissement,
 Procedure,Procédure,
@@ -2015,15 +1874,12 @@
 Provisional Profit / Loss (Credit),Gain / Perte (Crédit) Provisoire,
 Publications,Des publications,
 Publish Items on Website,Publier les Articles sur le Site Web,
-Published,Publié,
 Publishing,Édition,
 Purchase,achat,
 Purchase Amount,Montant de l'Achat,
 Purchase Date,Date d'Achat,
 Purchase Invoice,Facture d’Achat,
 Purchase Invoice {0} is already submitted,La Facture d’Achat {0} est déjà soumise,
-Purchase Manager,Responsable des Achats,
-Purchase Master Manager,Responsable des Données d’Achats,
 Purchase Order,Commande d'Achat,
 Purchase Order Amount,Montant de la Commande d'Achat,
 Purchase Order Amount(Company Currency),Montant de la Commande d'Achat (devise de la société),
@@ -2038,7 +1894,6 @@
 Purchase Receipt,Reçu d’Achat,
 Purchase Receipt {0} is not submitted,Le Reçu d’Achat {0} n'est pas soumis,
 Purchase Tax Template,Modèle de Taxes pour les Achats,
-Purchase User,Utilisateur Acheteur,
 Purchase orders help you plan and follow up on your purchases,Les Bons de Commande vous aider à planifier et à assurer le suivi de vos achats,
 Purchasing,Achat,
 Purpose must be one of {0},L'Objet doit être parmi {0},
@@ -2068,7 +1923,6 @@
 Quantity to Manufacture must be greater than 0.,La quantité à produire doit être supérieur à 0.,
 Quantity to Produce,Quantité à produire,
 Quantity to Produce can not be less than Zero,La quantité à produire ne peut être inférieure à zéro,
-Query Options,Options de Requête,
 Queued for replacing the BOM. It may take a few minutes.,En file d'attente pour remplacer la nomenclature. Cela peut prendre quelques minutes.,
 Queued for updating latest price in all Bill of Materials. It may take a few minutes.,Mise à jour des prix les plus récents dans toutes les nomenclatures en file d'attente. Cela peut prendre quelques minutes.,
 Quick Journal Entry,Écriture Rapide dans le Journal,
@@ -2083,10 +1937,8 @@
 Quotations: ,Devis :,
 Quotes to Leads or Customers.,Devis de Lead ou Clients.,
 RFQs are not allowed for {0} due to a scorecard standing of {1},Les Appels d'Offres ne sont pas autorisés pour {0} en raison d'une note de {1} sur la fiche d'évaluation,
-Range,Plage,
 Rate,Prix,
 Rate:,Prix:,
-Rating,Évaluation,
 Raw Material,Matières Premières,
 Raw Materials,Matières premières,
 Raw Materials cannot be blank.,Matières Premières ne peuvent pas être vides.,
@@ -2102,35 +1954,25 @@
 Receipt document must be submitted,Le reçu doit être soumis,
 Receivable,Créance,
 Receivable Account,Compte Débiteur,
-Received,Reçu,
 Received On,Reçu le,
 Received Quantity,Quantité reçue,
 Received Stock Entries,Entrées de stock reçues,
 Receiver List is empty. Please create Receiver List,La Liste de Destinataires est vide. Veuillez créer une Liste de Destinataires,
-Recipients,Destinataires,
 Reconcile,Réconcilier,
 "Record of all communications of type email, phone, chat, visit, etc.","Enregistrement de toutes les communications de type email, téléphone, chat, visite, etc.",
 Records,Dossiers,
-Redirect URL,URL de Redirection,
 Ref,Ref,
 Ref Date,Date de Réf.,
-Reference,Référence,
 Reference #{0} dated {1},Référence #{0} datée du {1},
-Reference Date,Date de Référence,
 Reference Doctype must be one of {0},Doctype de la Référence doit être parmi {0},
-Reference Document,Document de Référence,
-Reference Document Type,Type du document de référence,
 Reference No & Reference Date is required for {0},N° et Date de Référence sont nécessaires pour {0},
 Reference No and Reference Date is mandatory for Bank transaction,Le N° de Référence et la Date de Référence sont nécessaires pour une Transaction Bancaire,
 Reference No is mandatory if you entered Reference Date,N° de Référence obligatoire si vous avez entré une date,
 Reference No.,Numéro de référence,
 Reference Number,Numéro de réference,
-Reference Type,Type de référence,
 "Reference: {0}, Item Code: {1} and Customer: {2}","Référence: {0}, Code de l'article: {1} et Client: {2}",
 References,Références,
-Refresh Token,Jeton de Rafraîchissement,
 Register,registre,
-Rejected,Rejeté,
 Related,en relation,
 Relation with Guardian1,Relation avec Tuteur1,
 Relation with Guardian2,Relation avec Tuteur2,
@@ -2142,17 +1984,12 @@
 Reminder to update GSTIN Sent,Rappel pour mettre à jour GSTIN envoyé,
 Remove item if charges is not applicable to that item,Retirer l'article si les charges ne lui sont pas applicables,
 Removed items with no change in quantity or value.,Les articles avec aucune modification de quantité ou de valeur ont étés retirés.,
-Reopen,Ré-ouvrir,
 Reorder Level,Niveau de réapprovisionnement,
 Reorder Qty,Qté de Réapprovisionnement,
 Repeat Customer Revenue,Revenus de Clients Récurrents,
 Repeat Customers,Clients Récurrents,
 Replace BOM and update latest price in all BOMs,Remplacer la nomenclature et actualiser les prix les plus récents dans toutes les nomenclatures,
-Replied,Répondu,
-Report,Rapport,
-Report Type,Type de Rapport,
 Report Type is mandatory,Le Type de Rapport est nécessaire,
-Reports,Rapports,
 Reqd By Date,Requis par date,
 Reqd Qty,Qté obligatoire,
 Request for Quotation,Appel d'Offre,
@@ -2211,7 +2048,6 @@
 Root cannot have a parent cost center,Racine ne peut pas avoir un centre de coûts parent,
 Round Off,Arrondi,
 Rounded Total,Total arrondi,
-Route,Route,
 Row # {0}: ,Ligne # {0} :,
 Row # {0}: Batch No must be same as {1} {2},Ligne # {0} : Le N° de Lot doit être le même que {1} {2},
 Row # {0}: Cannot return more than {1} for Item {2},Ligne # {0} : Vous ne pouvez pas retourner plus de {1} pour l’Article {2},
@@ -2300,8 +2136,6 @@
 Sales Invoice,Facture de vente,
 Sales Invoice {0} has already been submitted,La Facture Vente {0} a déjà été transmise,
 Sales Invoice {0} must be cancelled before cancelling this Sales Order,Facture de Vente {0} doit être annulée avant l'annulation de cette Commande Client,
-Sales Manager,Responsable des Ventes,
-Sales Master Manager,Directeur des Ventes,
 Sales Order,Commande client,
 Sales Order Item,Article de la Commande Client,
 Sales Order required for Item {0},Commande Client requise pour l'Article {0},
@@ -2317,11 +2151,9 @@
 Sales Summary,Récapitulatif des ventes,
 Sales Tax Template,Modèle de la Taxe de Vente,
 Sales Team,Équipe des Ventes,
-Sales User,Chargé de Ventes,
 Sales and Returns,Ventes et retours,
 Sales campaigns.,Campagnes de vente.,
 Sales orders are not available for production,Aucune commande client n'est disponible pour la production,
-Salutation,Salutations,
 Same Company is entered more than once,La même Société a été entrée plus d'une fois,
 Same item cannot be entered multiple times.,Le même article ne peut pas être entré plusieurs fois.,
 Same supplier has been entered multiple times,Le même fournisseur a été saisi plusieurs fois,
@@ -2329,7 +2161,6 @@
 Sample quantity {0} cannot be more than received quantity {1},La quantité d'échantillon {0} ne peut pas dépasser la quantité reçue {1},
 Sanctioned,Sanctionné,
 Sand,Le sable,
-Saturday,Samedi,
 Saving {0},Enregistrement {0},
 Scan Barcode,Scan Code Barre,
 Schedule,Calendrier,
@@ -2337,18 +2168,15 @@
 Schedule Course,Cours Calendrier,
 Schedule Date,Date du Calendrier,
 Schedule Discharge,Décharge horaire,
-Scheduled,Prévu,
 Scheduled Upto,Programmé jusqu'à,
 "Schedules for {0} overlaps, do you want to proceed after skiping overlaped slots ?","Les plannings pour {0} se chevauchent, voulez-vous continuer sans prendre en compte les créneaux qui se chevauchent ?",
 Score cannot be greater than Maximum Score,Score ne peut pas être supérieure à Score maximum,
 Scorecards,Fiches d'Évaluation,
 Scrapped,Mis au rebut,
-Search,Rechercher,
 Search Results,Résultats de la recherche,
 Search Sub Assemblies,Rechercher les Sous-Ensembles,
 "Search by item code, serial number, batch no or barcode","Recherche par code article, numéro de série, numéro de lot ou code-barres",
 "Seasonality for setting budgets, targets etc.","Saisonnalité de l'établissement des budgets, des objectifs, etc.",
-Secret Key,Clef Secrète,
 Secretary,secrétaire,
 Section Code,Code de section,
 Secured Loans,Prêts garantis,
@@ -2358,7 +2186,6 @@
 See all open tickets,Voir tous les tickets ouverts,
 See past orders,Voir les commandes passées,
 See past quotations,Voir les citations passées,
-Select,Sélectionner,
 Select Alternate Item,Sélectionnez un autre élément,
 Select Attribute Values,Sélectionner les valeurs d'attribut,
 Select BOM,Sélectionner une nomenclature,
@@ -2372,7 +2199,6 @@
 Select Customer,Sélectionnez un client,
 Select Days,Choisissez des jours,
 Select Default Supplier,Sélectionner le Fournisseur par Défaut,
-Select DocType,Sélectionner le DocType,
 Select Fiscal Year...,Sélectionner Exercice ...,
 Select Item (optional),Sélectionnez l'Article (facultatif),
 Select Items based on Delivery Date,Sélectionnez les articles en fonction de la Date de Livraison,
@@ -2402,11 +2228,9 @@
 Selling Rate,Prix de vente,
 "Selling must be checked, if Applicable For is selected as {0}","Vente doit être vérifiée, si ""Applicable pour"" est sélectionné comme {0}",
 Send Grant Review Email,Envoyer un email d'examen de la demande de subvention,
-Send Now,Envoyer Maintenant,
 Send SMS,Envoyer un SMS,
 Send mass SMS to your contacts,Envoyer un SMS en masse à vos contacts,
 Sensitivity,Sensibilité,
-Sent,Envoyé,
 Serial No and Batch,N° de Série et lot,
 Serial No is mandatory for Item {0},N° de Série est obligatoire pour l'Article {0},
 Serial No {0} does not belong to Batch {1},Le numéro de série {0} n'appartient pas au lot {1},
@@ -2431,7 +2255,6 @@
 Series Updated,Série mise à jour,
 Series Updated Successfully,Mise à jour des Séries Réussie,
 Series is mandatory,Série est obligatoire,
-Service,Service,
 Service Level Agreement,Contrat de niveau de service,
 Service Level Agreement.,Contrat de niveau de service.,
 Service Level.,Niveau de service.,
@@ -2458,7 +2281,6 @@
 Setting up Employees,Configuration des Employés,
 Setting up Taxes,Configuration des Impôts,
 Setting up company,Création d'entreprise,
-Settings,Paramètres,
 "Settings for online shopping cart such as shipping rules, price list etc.","Paramètres du panier tels que les règles de livraison, liste de prix, etc.",
 Settings for website homepage,Paramètres de la page d'accueil du site,
 Settings for website product listing,Paramètres pour la liste de produits de sites Web,
@@ -2484,7 +2306,6 @@
 Shopify Supplier,Fournisseur Shopify,
 Shopping Cart,Panier,
 Shopping Cart Settings,Paramètres du panier,
-Short Name,Nom Court,
 Shortage Qty,Qté de Pénurie,
 Show Completed,Montrer terminé,
 Show Cumulative Amount,Afficher le montant cumulatif,
@@ -2503,7 +2324,6 @@
 Single Variant,Variante unique,
 Single unit of an Item.,Seule unité d'un Article.,
 "Skipping Leave Allocation for the following employees, as Leave Allocation records already exists against them. {0}","Attribution des congés de congé pour les employés suivants, car des dossiers de répartition des congés existent déjà contre eux. {0}",
-Slideshow,Diaporama,
 Slots for {0} are not added to the schedule,Les créneaux pour {0} ne sont pas ajoutés à l'agenda,
 Small,Petit,
 Soap & Detergent,Savons & Détergents,
@@ -2516,8 +2336,6 @@
 Some information is missing,Certaines informations sont manquantes,
 Something went wrong!,Quelque chose a mal tourné !,
 "Sorry, Serial Nos cannot be merged","Désolé, les N° de Série ne peut pas être fusionnés",
-Source,Source,
-Source Name,Nom de la Source,
 Source Warehouse,Entrepôt source,
 Source and Target Location cannot be same,Les localisations source et cible ne peuvent pas être identiques,
 Source and target warehouse cannot be same for row {0},L'entrepôt source et destination ne peuvent être similaire dans la ligne {0},
@@ -2532,14 +2350,12 @@
 Standard Buying,Achat standard,
 Standard Selling,Vente standard,
 Standard contract terms for Sales or Purchase.,Termes contractuels standards pour Ventes ou Achats,
-Start Date,Date de Début,
 Start Date of Agreement can't be greater than or equal to End Date.,La date de début de l'accord ne peut être supérieure ou égale à la date de fin.,
 Start Year,Année de début,
 Start date should be less than end date for Item {0},La date de début doit être antérieure à la date de fin pour l'Article {0},
 Start date should be less than end date for task {0},La date de début doit être inférieure à la date de fin de la tâche {0},
 Start day is greater than end day in task '{0}',La date de début est supérieure à la date de fin dans la tâche '{0}',
 Start on,Démarrer,
-State,Etat,
 State/UT Tax,Taxe Etat / UT,
 Statement of Account,Relevé de compte,
 Status must be one of {0},Le statut doit être l'un des {0},
@@ -2572,8 +2388,6 @@
 Stock cannot be updated against Purchase Receipt {0},Stock ne peut pas être mis à jour pour le Reçu d'Achat {0},
 Stock cannot exist for Item {0} since has variants,Stock ne peut pas exister pour l'Article {0} puisqu'il a des variantes,
 Stock transactions before {0} are frozen,Les transactions du stock avant {0} sont gelées,
-Stop,Arrêter,
-Stopped,Arrêté,
 "Stopped Work Order cannot be cancelled, Unstop it first to cancel","Un ordre de fabrication arrêté ne peut être annulé, Re-démarrez le pour pouvoir l'annuler",
 Stores,Magasins,
 Student,Étudiant,
@@ -2604,8 +2418,6 @@
 Sub Type,Sous type,
 Sub-contracting,Sous-traitant,
 Subcontract,Sous-traiter,
-Subject,Sujet,
-Submit,Valider,
 Submit this Work Order for further processing.,Valider cet ordre de fabrication pour continuer son traitement.,
 Subscription,Abonnement,
 Subscription Management,Gestion des abonnements,
@@ -2618,10 +2430,8 @@
 Successfully deleted all transactions related to this company!,Suppression de toutes les transactions liées à cette société avec succès !,
 Sum of Scores of Assessment Criteria needs to be {0}.,Somme des Scores de Critères d'Évaluation doit être {0}.,
 Sum of points for all goals should be 100. It is {0},Somme des points pour tous les objectifs devraient être 100. Il est {0},
-Summary,Résumé,
 Summary for this month and pending activities,Résumé du mois et des activités en suspens,
 Summary for this week and pending activities,Résumé de la semaine et des activités en suspens,
-Sunday,Dimanche,
 Suplier,Fournisseur,
 Supplier,Fournisseur,
 Supplier Group,Groupe de fournisseurs,
@@ -2651,20 +2461,15 @@
 Sync has been temporarily disabled because maximum retries have been exceeded,La synchronisation a été temporairement désactivée car les tentatives maximales ont été dépassées,
 Syntax error in condition: {0},Erreur de syntaxe dans la condition: {0},
 Syntax error in formula or condition: {0},Erreur de syntaxe dans la formule ou condition : {0},
-System Manager,Responsable Système,
 TDS Rate %,Pourcentage de TDS,
 Tap items to add them here,Choisissez des articles pour les ajouter ici,
-Target,Cible,
 Target ({}),Cible ({}),
 Target On,Cible sur,
 Target Warehouse,Entrepôt cible,
 Target warehouse is mandatory for row {0},L’Entrepôt cible est obligatoire pour la ligne {0},
-Task,Tâche,
-Tasks,Tâches,
 Tasks have been created for managing the {0} disease (on row {1}),Des tâches ont été créées pour gérer la maladie {0} (sur la ligne {1}),
 Tax,Taxe,
 Tax Assets,Actifs d'Impôts,
-Tax Category,Catégorie de taxe,
 Tax Category for overriding tax rates.,Catégorie de taxe pour les taux de taxe prépondérants.,
 "Tax Category has been changed to ""Total"" because all the Items are non-stock items","La Catégorie de Taxe a été changée à ""Total"" car tous les articles sont des articles hors stock",
 Tax ID,Numéro d'identification fiscale,
@@ -2772,11 +2577,9 @@
 Timesheets,Feuilles de temps,
 "Timesheets help keep track of time, cost and billing for activites done by your team","Les Feuilles de Temps aident au suivi du temps, coût et facturation des activités effectuées par votre équipe",
 Titles for print templates e.g. Proforma Invoice.,Titres pour les modèles d'impression e.g. Facture Proforma.,
-To,À,
 To Address 1,Ligne d'adresse 1 (Destination),
 To Address 2,Ligne d'adresse 2 (Destination),
 To Bill,À Facturer,
-To Date,Jusqu'au,
 To Date cannot be before From Date,La date de fin ne peut être antérieure à la date de début,
 To Date cannot be less than From Date,La date de fin ne peut pas précéder la date de début,
 To Date must be greater than From Date,La date de fin doit être supérieure à la date de début,
@@ -2892,7 +2695,6 @@
 UOM,UdM,
 UOM Conversion factor is required in row {0},Facteur de conversion de l'UdM est obligatoire dans la ligne {0},
 UOM coversion factor required for UOM: {0} in Item: {1},Facteur de coversion UdM requis pour l'UdM : {0} dans l'Article : {1},
-URL,URL,
 Unable to find exchange rate for {0} to {1} for key date {2}. Please create a Currency Exchange record manually,Impossible de trouver le taux de change pour {0} à {1} pour la date clé {2}. Veuillez créer une entrée de taux de change manuellement,
 Unable to find score starting at {0}. You need to have standing scores covering 0 to 100,Impossible de trouver un score démarrant à {0}. Vous devez avoir des scores couvrant 0 à 100,
 Unable to find variable: ,Impossible de trouver une variable:,
@@ -2906,7 +2708,6 @@
 Unpaid,Impayé,
 Unsecured Loans,Prêts non garantis,
 Unsubscribe from this Email Digest,Se Désinscire de ce Compte Rendu par Email,
-Unsubscribed,Désinscrit,
 Until,Jusqu'à,
 Unverified Webhook Data,Données de Webhook non vérifiées,
 Update Account Name / Number,Mettre à jour le nom / numéro du compte,
@@ -2923,8 +2724,6 @@
 Upper Income,Revenu Élevé,
 Use Sandbox,Utiliser Sandbox,
 Used Leaves,Congés utilisés,
-User,Utilisateur,
-User ID,Identifiant d'utilisateur,
 User ID not set for Employee {0},ID de l'Utilisateur non défini pour l'Employé {0},
 User Remark,Remarque de l'Utilisateur,
 User has not applied rule on the invoice {0},L'utilisateur n'a pas appliqué la règle sur la facture {0},
@@ -2934,14 +2733,12 @@
 User {0} doesn't have any default POS Profile. Check Default at Row {1} for this User.,L'utilisateur {0} n'a aucun profil POS par défaut. Vérifiez par défaut à la ligne {1} pour cet utilisateur.,
 User {0} is already assigned to Employee {1},Utilisateur {0} est déjà attribué à l'Employé {1},
 User {0} is already assigned to Healthcare Practitioner {1},L'utilisateur {0} est déjà attribué à un professionnel de la santé {1},
-Users,Utilisateurs,
 Utility Expenses,Frais de Services d'Utilité Publique,
 Valid From Date must be lesser than Valid Upto Date.,La date de début de validité doit être inférieure à la date de mise en service valide.,
 Valid Till,Valable Jusqu'au,
 Valid from and valid upto fields are mandatory for the cumulative,Les champs valides à partir de et valables jusqu'à sont obligatoires pour le cumulatif.,
 Valid from date must be less than valid upto date,La date de début de validité doit être inférieure à la date de validité,
 Valid till date cannot be before transaction date,La date de validité ne peut pas être avant la date de transaction,
-Validity,Validité,
 Validity period of this quotation has ended.,La période de validité de ce devis a pris fin.,
 Valuation Rate,Taux de Valorisation,
 Valuation Rate is mandatory if Opening Stock entered,Le Taux de Valorisation est obligatoire si un Stock Initial est entré,
@@ -2996,7 +2793,6 @@
 Warehouses with child nodes cannot be converted to ledger,Les entrepôts avec nœuds enfants ne peuvent pas être convertis en livre,
 Warehouses with existing transaction can not be converted to group.,Les entrepôts avec des transactions existantes ne peuvent pas être convertis en groupe.,
 Warehouses with existing transaction can not be converted to ledger.,Les entrepôts avec des transactions existantes ne peuvent pas être convertis en livre.,
-Warning,Avertissement,
 Warning: Another {0} # {1} exists against stock entry {2},Attention : Un autre {0} {1} # existe pour l'écriture de stock {2},
 Warning: Invalid SSL certificate on attachment {0},Attention : certificat SSL non valide sur la pièce jointe {0},
 Warning: Invalid attachment {0},Attention : Pièce jointe non valide {0},
@@ -3006,16 +2802,9 @@
 Warranty,garantie,
 Warranty Claim,Réclamation de Garantie,
 Warranty Claim against Serial No.,Réclamation de Garantie pour le N° de Série.,
-Website,Site Web,
 Website Image should be a public file or website URL,L'Image du Site Web doit être un fichier public ou l'URL d'un site web,
 Website Image {0} attached to Item {1} cannot be found,Image pour le Site Web {0} attachée à l'Article {1} ne peut pas être trouvée,
-Website Manager,Responsable du Site Web,
-Website Settings,Paramètres du Site web,
-Wednesday,Mercredi,
-Week,Semaine,
-Weekly,Hebdomadaire,
 "Weight is mentioned,\nPlease mention ""Weight UOM"" too","Poids est mentionné,\nVeuillez aussi mentionner ""UdM de Poids""",
-Welcome email sent,Email de bienvenue envoyé,
 Welcome to ERPNext,Bienvenue sur ERPNext,
 What do you need help with?,Avec quoi avez vous besoin d'aide ?,
 What does it do?,Qu'est-ce que ça fait ?,
@@ -3078,9 +2867,7 @@
 "e.g. ""Build tools for builders""","e.g. ""Construire des outils pour les constructeurs""",
 "e.g. ""Primary School"" or ""University""","e.g. ""École Primaire"" ou ""Université""",
 "e.g. Bank, Cash, Credit Card","e.g. Cash, Banque, Carte de crédit",
-hidden,Masqué,
 modified,modifié,
-old_parent,grand_parent,
 on,sur,
 {0} '{1}' is disabled,{0} '{1}' est désactivé(e),
 {0} '{1}' not in Fiscal Year {2},{0} '{1}' n'est pas dans l’Exercice {2},
@@ -3113,7 +2900,6 @@
 {0} hours,{0} heures,
 {0} in row {1},{0} dans la ligne {1},
 {0} is blocked so this transaction cannot proceed,{0} est bloqué donc cette transaction ne peut pas continuer,
-{0} is mandatory,{0} est obligatoire,
 {0} is mandatory for Item {1},{0} est obligatoire pour l’Article {1},
 {0} is mandatory. Maybe Currency Exchange record is not created for {1} to {2}.,{0} est obligatoire. Peut-être qu’un enregistrement de Taux de Change n'est pas créé pour {1} et {2}.,
 {0} is not a stock Item,{0} n'est pas un Article de stock,
@@ -3173,37 +2959,8 @@
 {0}: {1} does not exists,{0} : {1} n’existe pas,
 {0}: {1} not found in Invoice Details table,{0} : {1} introuvable dans la table de Détails de la Facture,
 {} of {},{} de {},
-Assigned To,Assigné À,
-Chat,Chat,
 Completed By,Effectué par,
-Day of Week,Jour de la semaine,
-"Dear System Manager,","Cher Administrateur Système ,",
-Default Value,Valeur par Défaut,
-Email Group,Groupe Email,
-Email Settings,Paramètres d'Email,
-Email not sent to {0} (unsubscribed / disabled),Email pas envoyé à {0} (désabonné / désactivé),
-Error Message,Message d'erreur,
-Fieldtype,Type de Champ,
-Help Articles,Articles d'Aide,
-ID,ID,
-Import,Importer,
-Language,Langue,
-Likes,Aime,
-Merge with existing,Fusionner avec existant,
-Orientation,Orientation,
-Parent,Parent,
 Payment Failed,Le Paiement a Échoué,
-Personal,Personnel,
-Post,Poster,
-Postal Code,code postal,
-Provider,Fournisseur,
-Read Only,Lecture Seule,
-Recipient,Destinataire,
-Reviews,Avis,
-Sender,Expéditeur,
-There were errors while sending email. Please try again.,Il y a eu des erreurs lors de l'envoi d’emails. Veuillez essayer à nouveau.,
-Values Changed,Valeurs Modifiées,
-or,ou,
 Ageing Range 4,Gamme de vieillissement 4,
 Allocated amount cannot be greater than unadjusted amount,Le montant alloué ne peut être supérieur au montant non ajusté,
 Allocated amount cannot be negative,Le montant alloué ne peut être négatif,
@@ -3229,22 +2986,7 @@
 Show {0},Montrer {0},
 Target Details,Détails de la cible,
 {0} already has a Parent Procedure {1}.,{0} a déjà une procédure parent {1}.,
-API,API,
-Annual,Annuel,
-Change,Changement,
-Contact Email,Email du Contact,
-From Date,A partir du,
-Group By,Par groupe,
-Invalid URL,URL invalide,
-Landscape,Paysage,
-Naming Series,Masque de numérotation,
-No data to export,Aucune donnée à exporter,
-Portrait,Portrait,
 Print Heading,Imprimer Titre,
-Scheduler Inactive,Planificateur inactif,
-Scheduler is inactive. Cannot import data.,Le planificateur est inactif. Impossible d'importer des données.,
-Show Document,Afficher le document,
-Show Traceback,Afficher le traçage,
 Video,Vidéo,
 % Of Grand Total,% Du grand total,
 <b>Company</b> is a mandatory filter.,<b>La société</b> est un filtre obligatoire.,
@@ -3262,20 +3004,11 @@
 Accounting Dimension <b>{0}</b> is required for 'Profit and Loss' account {1}.,La dimension de comptabilité <b>{0}</b> est requise pour le compte 'Bénéfices et pertes' {1}.,
 Accounting Masters,Maîtres Comptables,
 Accounting Period overlaps with {0},La période comptable chevauche avec {0},
-Activity,Activité,
-Add / Manage Email Accounts.,Ajouter / Gérer les Comptes de Messagerie.,
-Add Child,Ajouter une Sous-Catégorie,
-Add Multiple,Ajout Multiple,
-Add Participants,Ajouter des participants,
 Add to Featured Item,Ajouter à l'article en vedette,
 Add your review,Ajouter votre avis,
 Add/Edit Coupon Conditions,Ajouter / Modifier les conditions du coupon,
 Added to Featured Items,Ajouté aux articles en vedette,
-Added {0} ({1}),Ajouté {0} ({1}),
-Address Line 1,Adresse Ligne 1,
-Addresses,Adresses,
 Admission End Date should be greater than Admission Start Date.,La date de fin d'admission doit être supérieure à la date de début d'admission.,
-All,Tout,
 All bank transactions have been created,Toutes les transactions bancaires ont été créées,
 All the depreciations has been booked,Toutes les amortissements ont été comptabilisés,
 Allow Resetting Service Level Agreement from Support Settings.,Autoriser la réinitialisation du contrat de niveau de service à partir des paramètres de support.,
@@ -3310,17 +3043,12 @@
 Batch no is required for batched item {0},Le numéro de lot est requis pour l'article en lot {0}.,
 Billing Date,Date de facturation,
 Billing Interval Count cannot be less than 1,Le nombre d'intervalles de facturation ne peut pas être inférieur à 1,
-Blue,Bleu,
-Book,Livre,
 Book Appointment,Prendre rendez-vous,
-Brand,Marque,
-Browse,Feuilleter,
 Call Connected,Appel connecté,
 Call Disconnected,Appel déconnecté,
 Call Missed,Appel manqué,
 Call Summary,Résumé d'appel,
 Call Summary Saved,Résumé de l'appel enregistré,
-Cancelled,Annulé,
 Cannot Calculate Arrival Time as Driver Address is Missing.,Impossible de calculer l'heure d'arrivée car l'adresse du conducteur est manquante.,
 Cannot Optimize Route as Driver Address is Missing.,Impossible d'optimiser l'itinéraire car l'adresse du pilote est manquante.,
 Cannot complete task {0} as its dependant task {1} are not ccompleted / cancelled.,Impossible de terminer la tâche {0} car sa tâche dépendante {1} n'est pas terminée / annulée.,
@@ -3329,26 +3057,19 @@
 "Capacity Planning Error, planned start time can not be same as end time","Erreur de planification de capacité, l'heure de début prévue ne peut pas être identique à l'heure de fin",
 Categories,Catégories,
 Changes in {0},Changements dans {0},
-Chart,Graphique,
 Choose a corresponding payment,Choisissez un paiement correspondant,
 Click on the link below to verify your email and confirm the appointment,Cliquez sur le lien ci-dessous pour vérifier votre email et confirmer le rendez-vous,
-Close,Fermer,
 Communication,Communication,
 Compact Item Print,Impression de l'Article Compacté,
-Company,Société,
 Company of asset {0} and purchase document {1} doesn't matches.,La société de l'actif {0} et le document d'achat {1} ne correspondent pas.,
 Compare BOMs for changes in Raw Materials and Operations,Comparer les nomenclatures aux modifications apportées aux matières premières et aux opérations,
 Compare List function takes on list arguments,La fonction de comparaison de liste accepte les arguments de liste,
-Complete,Terminé,
-Completed,Terminé,
 Completed Quantity,Quantité terminée,
 Connect your Exotel Account to ERPNext and track call logs,Connectez votre compte Exotel à ERPNext et suivez les journaux d'appels,
 Connect your bank accounts to ERPNext,Connectez vos comptes bancaires à ERPNext,
 Contact Seller,Contacter le vendeur,
-Continue,Continuer,
 Cost Center: {0} does not exist,Centre de coûts: {0} n'existe pas,
 Couldn't Set Service Level Agreement {0}.,Impossible de définir le contrat de service {0}.,
-Country,Pays,
 Country Code in File does not match with country code set up in the system,Le code de pays dans le fichier ne correspond pas au code de pays configuré dans le système,
 Create New Contact,Créer un nouveau contact,
 Create New Lead,Créer une nouvelle lead,
@@ -3359,34 +3080,20 @@
 Credit limit is already defined for the Company {0},La limite de crédit est déjà définie pour la société {0}.,
 Ctrl + Enter to submit,Ctrl + Entrée pour valider,
 Ctrl+Enter to submit,Ctrl + Entrée pour valider,
-Currency,Devise,
-Current Status,Statut Actuel,
 Customer PO,Commande d'Achat client,
-Daily,Quotidien,
-Date,Date,
 Date of Birth cannot be greater than Joining Date.,La date de naissance ne peut pas être supérieure à la date d'adhésion.,
-Dear,Cher/Chère,
-Default,Par Défaut,
 Define coupon codes.,Définissez les codes promo.,
 Delayed Days,Jours retardés,
-Delete,Supprimer,
 Delivered Quantity,Quantité livrée,
 Delivery Notes,Bons de livraison,
 Depreciated Amount,Montant amorti,
-Description,Description,
-Designation,Désignation,
 Difference Value,Valeur de différence,
 Dimension Filter,Filtre de dimension,
-Disabled,Desactivé,
 Disbursement and Repayment,Décaissement et remboursement,
 Distance cannot be greater than 4000 kms,La distance ne peut pas dépasser 4000 km,
 Do you want to submit the material request,Voulez-vous valider la demande de matériel,
-Doctype,Doctype,
 Document {0} successfully uncleared,Document {0} non effacé avec succès,
-Download Template,Télécharger le Modèle,
 Dr,Dr,
-Due Date,Date d'Échéance,
-Duplicate,Dupliquer,
 Duplicate Project with Tasks,Projet en double avec tâches,
 Duplicate project has been created,Un projet en double a été créé,
 E-Way Bill JSON can only be generated from a submitted document,E-Way Bill JSON ne peut être généré qu'à partir d'un document soumis,
@@ -3396,7 +3103,6 @@
 Earliest Age,Âge le plus précoce,
 Edit Details,Modifier les détails,
 Either GST Transporter ID or Vehicle No is required if Mode of Transport is Road,Un numéro d'identification de transporteur ou un numéro de véhicule est requis si le mode de transport est la route.,
-Email,Email,
 Email Campaigns,Campagnes de courrier électronique,
 Employee ID is linked with another instructor,L'ID de l'employé est lié à un autre instructeur,
 Employee Tax and Benefits,Impôt et avantages sociaux des employés,
@@ -3408,21 +3114,13 @@
 Energy Point Leaderboard,Point de classement énergétique,
 Enter API key in Google Settings.,Entrez la clé API dans les paramètres Google.,
 Enter Supplier,Entrez le fournisseur,
-Enter Value,Entrez une Valeur,
-Entity Type,Type d'entité,
-Error,Erreur,
 Error in Exotel incoming call,Erreur dans un appel entrant Exotel,
 Error: {0} is mandatory field,Erreur: {0} est un champ obligatoire,
 Exception occurred while reconciling {0},Une exception s'est produite lors de la réconciliation {0},
 Expected and Discharge dates cannot be less than Admission Schedule date,Les dates prévues et de sortie ne peuvent pas être inférieures à la date du calendrier d'admission,
-Expired,Expiré,
-Export,Exporter,
-Export not allowed. You need {0} role to export.,Pas autorisé à exporter. Vous devez avoir le rôle {0} pour exporter.,
 Failed to add Domain,Impossible d'ajouter le domaine,
 Fetch Items from Warehouse,Récupérer des articles de l'entrepôt,
 Fetching...,Aller chercher...,
-Field,Champ,
-Filters,Filtres,
 Finding linked payments,Trouver des paiements liés,
 Fleet Management,Gestion de flotte,
 Following fields are mandatory to create address:,Les champs suivants sont obligatoires pour créer une adresse:,
@@ -3438,28 +3136,17 @@
 Future Payments,Paiements futurs,
 GST HSN Code does not exist for one or more items,Le code HSN de la TPS n’existe pas pour un ou plusieurs articles,
 Generate E-Way Bill JSON,Générer E-Way Bill JSON,
-Get Items,Obtenir les Articles,
 Get Outstanding Documents,Obtenez des documents en suspens,
-Goal,Objectif,
 Greater Than Amount,Plus grand que le montant,
-Green,Vert,
-Group,Groupe,
 Group By Customer,Regrouper par client,
 Group By Supplier,Regrouper par fournisseur,
-Group Node,Noeud de Groupe,
 Group Warehouses cannot be used in transactions. Please change the value of {0},Les entrepôts de groupe ne peuvent pas être utilisés dans les transactions. Veuillez modifier la valeur de {0},
-Help,Aidez-moi,
-Help Article,Article d’Aide,
 "Helps you keep tracks of Contracts based on Supplier, Customer and Employee","Vous aide à garder une trace des contrats en fonction du fournisseur, client et employé",
 Helps you manage appointments with your leads,Vous aide à gérer les rendez-vous avec vos leads,
-Home,Accueil,
 IBAN is not valid,IBAN n'est pas valide,
-Import Data from CSV / Excel files.,Importer des données à partir de fichiers CSV / Excel,
-In Progress,En cours,
 Incoming call from {0},Appel entrant du {0},
 Incorrect Warehouse,Entrepôt incorrect,
 Invalid Barcode. There is no Item attached to this barcode.,Code à barres invalide. Il n'y a pas d'article attaché à ce code à barres.,
-Invalid credentials,les informations d'identification invalides,
 Issue Priority.,Priorité d'émission.,
 Issue Type.,Type de probleme.,
 "It seems that there is an issue with the server's stripe configuration. In case of failure, the amount will get refunded to your account.","Il semble qu'il y a un problème avec la configuration de Stripe sur le serveur. En cas d'erreur, le montant est remboursé sur votre compte.",
@@ -3475,13 +3162,11 @@
 Leaves Taken,Feuilles prises,
 Less Than Amount,Moins que le montant,
 Liabilities,Passifs,
-Loading...,Chargement en Cours ...,
 Loan Applications from customers and employees.,Demandes de prêt des clients et des employés.,
 Loan Processes,Processus de prêt,
 Loan Type for interest and penalty rates,Type de prêt pour les taux d'intérêt et de pénalité,
 Loans,Les prêts,
 Loans provided to customers and employees.,Prêts accordés aux clients et aux employés.,
-Location,Lieu,
 Looks like someone sent you to an incomplete URL. Please ask them to look into it.,On dirait que quelqu'un vous a envoyé vers URL incomplète. Veuillez leur demander d’analyser l’erreur.,
 Make Journal Entry,Faire une écriture de journal,
 Make Purchase Invoice,Faire la facture d'achat,
@@ -3490,12 +3175,6 @@
 Master,Maître,
 Max strength cannot be less than zero.,La force maximale ne peut pas être inférieure à zéro.,
 Maximum attempts for this quiz reached!,Nombre maximal de tentatives pour ce quiz atteint!,
-Message,Message,
-Missing Values Required,Valeurs Manquantes Requises,
-Mobile No,N° Mobile,
-Mobile Number,Numéro de Mobile,
-Month,Mois,
-Name,Nom,
 Near you,Près de toi,
 Net Profit/Loss,Résultat net,
 New Expense,Nouvelle dépense,
@@ -3514,10 +3193,8 @@
 No reviews yet,Pas encore d'avis,
 No views yet,Pas encore de vue,
 Non stock items,Articles hors stock,
-Not Allowed,Non Autorisé,
 Not allowed to create accounting dimension for {0},Non autorisé à créer une dimension comptable pour {0},
 Not permitted. Please disable the Lab Test Template,Pas permis. Veuillez désactiver le modèle de test de laboratoire,
-Note,Note,
 Notes: ,Remarques :,
 On Converting Opportunity,Sur l'opportunité de conversion,
 On Purchase Order Submission,Sur soumission de commande,
@@ -3525,13 +3202,11 @@
 On Task Completion,En fin de tâche,
 On {0} Creation,Sur {0} Creation,
 Only .csv and .xlsx files are supported currently,Seuls les fichiers .csv et .xlsx sont actuellement pris en charge.,
-Open,Ouvert,
 Open Contact,Contact ouvert,
 Open Lead,Ouvrir le Lead,
 Opening and Closing,Ouverture et fermeture,
 Operating Cost as per Work Order / BOM,Coût d'exploitation selon l'ordre de fabrication / nomenclature,
 Order Amount,Montant de la commande,
-Page {0} of {1},Page {0} sur {1},
 Paid amount cannot be less than {0},Le montant payé ne peut pas être inférieur à {0},
 Parent Company must be a group company,La société mère doit être une société du groupe,
 Passing Score value should be between 0 and 100,La note de passage doit être comprise entre 0 et 100,
@@ -3540,11 +3215,9 @@
 Pay,Payer,
 Payment Document Type,Type de document de paiement,
 Payment Name,Nom du paiement,
-Pending,En Attente,
 Performance,Performance,
 Period based On,Période basée sur,
 Perpetual inventory required for the company {0} to view this report.,Inventaire permanent requis pour que la société {0} puisse consulter ce rapport.,
-Phone,Téléphone,
 Pick List,Liste de sélection,
 Plaid authentication error,Erreur d'authentification du plaid,
 Plaid public token error,Erreur de jeton public Plaid,
@@ -3575,14 +3248,11 @@
 Please set valid GSTIN No. in Company Address for company {0},Veuillez définir un numéro GSTIN valide dans l'adresse de l'entreprise pour l'entreprise {0},
 Please set {0},Veuillez définir {0},customer
 Please setup a default bank account for company {0},Veuillez configurer un compte bancaire par défaut pour la société {0}.,
-Please specify,Veuillez spécifier,
 Please specify a {0},Veuillez spécifier un {0},lead
-Priority,Priorité,
 Priority has been changed to {0}.,La priorité a été changée en {0}.,
 Priority {0} has been repeated.,La priorité {0} a été répétée.,
 Processing XML Files,Traitement des fichiers XML,
 Profitability,Rentabilité,
-Project,Projet,
 Provide the academic year and set the starting and ending date.,Indiquez l'année universitaire et définissez la date de début et de fin.,
 Public token is missing for this bank,Un jeton public est manquant pour cette banque,
 Publish 1 Item,Publier 1 élément,
@@ -3600,30 +3270,22 @@
 Quality Inspection required for Item {0} to submit,Inspection de qualité requise pour que l'élément {0} soit envoyé,
 Quantity to Manufacture,Quantité à fabriquer,
 Quantity to Manufacture can not be zero for the operation {0},La quantité à fabriquer ne peut pas être nulle pour l'opération {0},
-Quarterly,Trimestriel,
-Queued,File d'Attente,
-Quick Entry,Écriture Rapide,
 Quiz {0} does not exist,Le questionnaire {0} n'existe pas,
 Quotation Amount,Montant du devis,
 Rate or Discount is required for the price discount.,Le prix ou la remise est requis pour la remise.,
-Reason,Raison,
 Reconcile Entries,Réconcilier les entrées,
 Reconcile this account,Réconcilier ce compte,
 Reconciled,Réconcilié,
 Recruitment,Recrutement,
-Red,Rouge,
 Release date must be in the future,La date de sortie doit être dans le futur,
 Relieving Date must be greater than or equal to Date of Joining,La date de libération doit être supérieure ou égale à la date d'adhésion,
-Rename,Renommer,
 Rename Not Allowed,Renommer non autorisé,
 Report Item,Élément de rapport,
 Report this Item,Signaler cet article,
 Reserved Qty for Subcontract: Raw materials quantity to make subcontracted items.,Quantité réservée pour la sous-traitance: quantité de matières premières pour fabriquer des articles sous-traités.,
-Reset,Réinitialiser,
 Reset Service Level Agreement,Réinitialiser l'accord de niveau de service,
 Resetting Service Level Agreement.,Réinitialisation de l'accord de niveau de service.,
 Return amount cannot be greater unclaimed amount,Le montant du retour ne peut pas être supérieur au montant non réclamé,
-Review,La revue,
 Room,Chambre,
 Room Type,Type de chambre,
 Row # ,Ligne #,
@@ -3648,47 +3310,36 @@
 Row({0}): {1} is already discounted in {2},Ligne ({0}): {1} est déjà réduit dans {2}.,
 Rows Added in {0},Lignes ajoutées dans {0},
 Rows Removed in {0},Lignes supprimées dans {0},
-Save,sauvegarder,
 Save Item,Enregistrer l'élément,
 Saved Items,Articles sauvegardés,
 Search Items ...,Rechercher des articles ...,
 Search for a payment,Rechercher un paiement,
 Search for anything ...,Rechercher n'importe quoi ...,
-Search results for,Résultats de recherche pour,
 Select Difference Account,Sélectionnez compte différentiel,
 Select a Default Priority.,Sélectionnez une priorité par défaut.,
 Select a company,Sélectionnez une entreprise,
 Select finance book for the item {0} at row {1},Sélectionnez le livre de financement pour l'élément {0} à la ligne {1}.,
 Select only one Priority as Default.,Sélectionnez une seule priorité par défaut.,
 Seller Information,Information du vendeur,
-Send,Envoyer,
 Send a message,Envoyer un message,
-Sending,Envoi,
 Sends Mails to lead or contact based on a Campaign schedule,Envoie des courriers à diriger ou à contacter en fonction d'un calendrier de campagne,
 Serial Number Created,Numéro de série créé,
 Serial Numbers Created,Numéros de série créés,
 Serial no(s) required for serialized item {0},N ° de série requis pour l'article sérialisé {0},
 Series,Séries,
-Server Error,Erreur du Serveur,
 Service Level Agreement has been changed to {0}.,L'accord de niveau de service a été remplacé par {0}.,
 Service Level Agreement was reset.,L'accord de niveau de service a été réinitialisé.,
 Service Level Agreement with Entity Type {0} and Entity {1} already exists.,L'accord de niveau de service avec le type d'entité {0} et l'entité {1} existe déjà.,
 Set Meta Tags,Définir les balises méta,
 Set {0} in company {1},Définissez {0} dans l'entreprise {1},
-Setup,Configuration,
 Shift Management,Gestion des quarts,
 Show Future Payments,Afficher les paiements futurs,
 Show Linked Delivery Notes,Afficher les bons de livraison liés,
 Show Sales Person,Afficher le vendeur,
 Show Stock Ageing Data,Afficher les données sur le vieillissement des stocks,
 Show Warehouse-wise Stock,Afficher le stock entre les magasins,
-Size,Taille,
 Something went wrong while evaluating the quiz.,Quelque chose s'est mal passé lors de l'évaluation du quiz.,
-Sr,Sr,
-Start,Démarrer,
 Start Date cannot be before the current date,La date de début ne peut pas être antérieure à la date du jour,
-Start Time,Heure de Début,
-Status,Statut,
 Status must be Cancelled or Completed,Le statut doit être annulé ou complété,
 Stock Balance Report,Rapport de solde des stocks,
 Stock Entry has been already created against this Pick List,Une entrée de stock a déjà été créée dans cette liste de choix,
@@ -3697,10 +3348,8 @@
 Stores - {0},Magasins - {0},
 Student with email {0} does not exist,Étudiant avec le courrier électronique {0} n'existe pas,
 Submit Review,Poster un commentaire,
-Submitted,Valider,
 Supplier Addresses And Contacts,Adresses et contacts des fournisseurs,
 Synchronize this account,Synchroniser ce compte,
-Tag,Étiquette,
 Target Location is required while receiving Asset {0} from an employee,L'emplacement cible est requis lors de la réception de l'élément {0} d'un employé,
 Target Location is required while transferring Asset {0},L'emplacement cible est requis lors du transfert de l'élément {0},
 Target Location or To Employee is required while receiving Asset {0},L'emplacement cible ou l'employé est requis lors de la réception de l'élément {0},
@@ -3708,7 +3357,6 @@
 Task's {0} Start Date cannot be after Project's End Date.,La date de début {0} de la tâche ne peut pas être postérieure à la date de fin du projet.,
 Tax Account not specified for Shopify Tax {0},Compte de taxe non spécifié pour Shopify Tax {0},
 Tax Total,Total de la taxe,
-Template,Modèle,
 The Campaign '{0}' already exists for the {1} '{2}',La campagne '{0}' existe déjà pour le {1} '{2}'.,
 The difference between from time and To Time must be a multiple of Appointment,La différence entre from time et To Time doit être un multiple de Appointment,
 The field Asset Account cannot be blank,Le champ Compte d'actif ne peut pas être vide,
@@ -3725,19 +3373,13 @@
 This bank transaction is already fully reconciled,Cette transaction bancaire est déjà totalement réconciliée,
 This page keeps track of items you want to buy from sellers.,Cette page répertorie les articles que vous souhaitez acheter auprès des vendeurs.,
 This page keeps track of your items in which buyers have showed some interest.,Cette page conserve une trace de vos articles pour lesquels les acheteurs ont manifesté un certain intérêt.,
-Thursday,Jeudi,
-Title,Titre,
 "To allow over billing, update ""Over Billing Allowance"" in Accounts Settings or the Item.","Pour autoriser la facturation excédentaire, mettez à jour &quot;Provision de facturation excédentaire&quot; dans les paramètres de compte ou le poste.",
 "To allow over receipt / delivery, update ""Over Receipt/Delivery Allowance"" in Stock Settings or the Item.","Pour autoriser le dépassement de réception / livraison, mettez à jour &quot;Limite de dépassement de réception / livraison&quot; dans les paramètres de stock ou le poste.",
-Total,Total,
 Total Payment Request amount cannot be greater than {0} amount,Le montant total de la demande de paiement ne peut être supérieur à {0}.,
 Total payments amount can't be greater than {},Le montant total des paiements ne peut être supérieur à {},
-Totals,Totaux,
 Transactions already retreived from the statement,Transactions déjà extraites de la déclaration,
 Transfer Material to Supplier,Transfert de matériel au fournisseur,
 Transport Receipt No and Date are mandatory for your chosen Mode of Transport,Le numéro de reçu de transport et la date sont obligatoires pour le mode de transport choisi,
-Tuesday,Mardi,
-Type,Type,
 Unable to find the time slot in the next {0} days for the operation {1}.,Impossible de trouver l'intervalle de temps dans les {0} jours suivants pour l'opération {1}.,
 Unable to update remote activity,Impossible de mettre à jour l'activité à distance,
 Unknown Caller,Appelant inconnu,
@@ -3745,13 +3387,10 @@
 Unpublish Item,Annuler la publication,
 Unreconciled,Non réconcilié,
 Unsupported GST Category for E-Way Bill JSON generation,Catégorie GST non prise en charge pour la génération e-Way Bill JSON,
-Update,Mettre à Jour,
 Update Taxes for Items,Mettre à jour les taxes pour les articles,
 "Upload a bank statement, link or reconcile a bank account","Télécharger un relevé bancaire, un lien ou un rapprochement d'un compte bancaire",
 Upload a statement,Télécharger une déclaration,
 Use a name that is different from previous project name,Utilisez un nom différent du nom du projet précédent,
-User {0} is disabled,Utilisateur {0} est désactivé,
-Users and Permissions,Utilisateurs et Autorisations,
 Valuation Rate required for Item {0} at row {1},Taux de valorisation requis pour le poste {0} à la ligne {1},
 Values Out Of Sync,Valeurs désynchronisées,
 Vehicle Type is required if Mode of Transport is Road,Le type de véhicule est requis si le mode de transport est la route,
@@ -3760,15 +3399,11 @@
 View,Vue,
 View all issues from {0},Afficher tous les problèmes de {0},
 View call log,Voir le journal des appels,
-Warehouse,Entrepôt,
 Warehouse not found against the account {0},Entrepôt introuvable sur le compte {0},
-Welcome to {0},Bienvenue sur {0},
 Why do think this Item should be removed?,Pourquoi pensez-vous que cet élément devrait être supprimé?,
 Work Order {0}: Job Card not found for the operation {1},Bon de travail {0}: carte de travail non trouvée pour l'opération {1},
 Workday {0} has been repeated.,La journée de travail {0} a été répétée.,
 XML Files Processed,Fichiers XML traités,
-Year,Année,
-Yearly,Annuel,
 You are not allowed to enroll for this course,Vous n'êtes pas autorisé à vous inscrire à ce cours,
 You are not enrolled in program {0},Vous n'êtes pas inscrit au programme {0},
 You can Feature upto 8 items.,Vous pouvez présenter jusqu'à 8 éléments.,
@@ -3781,7 +3416,6 @@
 Your Items,Vos articles,
 Your Profile,Votre profil,
 Your rating:,Votre note :,
-and,et,
 e-Way Bill already exists for this document,e-Way Bill existe déjà pour ce document,
 woocommerce - {0},woocommerce - {0},
 {0} Coupon used are {1}. Allowed quantity is exhausted,Le {0} coupon utilisé est {1}. La quantité autorisée est épuisée,
@@ -3793,7 +3427,6 @@
 {0} is not a company bank account,{0} n'est pas un compte bancaire d'entreprise,
 {0} is not a group node. Please select a group node as parent cost center,{0} n'est pas un nœud de groupe. Veuillez sélectionner un nœud de groupe comme centre de coûts parent,
 {0} is not the default supplier for any items.,{0} n'est le fournisseur par défaut d'aucun élément.,
-{0} is required,{0} est nécessaire,
 {0}: {1} must be less than {2},{0}: {1} doit être inférieur à {2},
 {} is required to generate E-Way Bill JSON,{} est requis pour générer e-Way Bill JSON,
 "Invalid lost reason {0}, please create a new lost reason","Motif perdu non valide {0}, veuillez créer un nouveau motif perdu",
@@ -3802,20 +3435,6 @@
 Total Expense This Year,Dépenses totales cette année,
 Total Income,Revenu total,
 Total Income This Year,Revenu total cette année,
-Barcode,code à barre,
-Clear,Clair,
-Comments,Commentaires,
-DocType,DocType,
-Download,Télécharger,
-Left,Parti,
-Link,Lien,
-New,Nouveau,
-Print,Impression,
-Reference Name,Nom de référence,
-Refresh,Actualiser,
-Success,Succès,
-Time,Temps,
-Value,Valeur,
 Actual,Réel,
 Add to Cart,Ajouter au Panier,
 Days Since Last Order,Jours depuis la dernière commande,
@@ -3829,10 +3448,6 @@
 To date cannot be before From date,La date de fin ne peut être antérieure à la date de début,
 Write Off,Reprise,
 {0} Created,{0} Créé,
-Email Id,Identifiant Email,
-No,Non,
-Reference Doctype,DocType de la Référence,
-Yes,Oui,
 Actual ,Réel,
 Add to cart,Ajouter au Panier,
 Budget,Budget,
@@ -3843,16 +3458,13 @@
 End date can not be less than start date,La date de Fin ne peut pas être antérieure à la Date de Début,
 For Default Supplier (Optional),Pour le fournisseur par défaut (facultatif),
 From date cannot be greater than To date,La Date Initiale ne peut pas être postérieure à la Date Finale,
-Group by,Grouper Par,
 In stock,En stock,
 Item name,Libellé de l'article,
 Minimum Qty,Quantité minimum,
 More details,Plus de détails,
 Nature of Supplies,Nature des fournitures,
-No Items found.,Aucun article trouvé.,
 No students found,Aucun étudiant trouvé,
 Not in stock,En rupture,
-Not permitted,Pas permis,
 Open Issues ,Tickets ouverts,
 Open Projects ,Projets ouverts,
 Open To Do ,ToDo ouvertes,
@@ -3877,8 +3489,6 @@
 hours,heures,
 received from,reçu de,
 to,à,
-Cards,Cartes,
-Percentage,Pourcentage,
 Failed to setup defaults for country {0}. Please contact support@erpnext.com,Échec de la configuration des paramètres par défaut pour le pays {0}. Veuillez contacter support@erpnext.com,
 Row #{0}: Item {1} is not a Serialized/Batched Item. It cannot have a Serial No/Batch No against it.,Ligne # {0}: l'article {1} n'est pas un article sérialisé / en lot. Il ne peut pas avoir de numéro de série / de lot contre lui.,
 Please set {0},Veuillez définir {0},
@@ -3916,9 +3526,6 @@
 YouTube,Youtube,
 Vimeo,Vimeo,
 Publish Date,Date de publication,
-Duration,Durée,
-Advanced Settings,Réglages avancés,
-Path,Chemin,
 Components,Composants,
 Verified By,Vérifié Par,
 Invalid naming series (. missing) for {0},Masque de numérotation non valide (. Manquante) pour {0},
@@ -4235,7 +3842,6 @@
 Is Income Tax Liability,Est une dette d'impôt sur le revenu,
 Is Income Tax Expense,Est une dépense d'impôt sur le revenu,
 Cash Flow Mapping Accounts,Comptes du Mapping des Flux de Trésorerie,
-account,Compte,
 Cash Flow Mapping Template,Modèle de Mapping des Flux de Trésorerie,
 Cash Flow Mapping Template Details,Détails du Modèle de Mapping des Flux de Trésorerie,
 POS-CLO-,POS-CLO-,
@@ -4479,7 +4085,6 @@
 Invoice Portion,Pourcentage de facturation,
 Payment Amount,Montant du paiement,
 Payment Term Name,Nom du terme de paiement,
-Due Date Based On,Date d'échéance basée sur,
 Day(s) after invoice date,Jour (s) après la date de la facture,
 Day(s) after the end of the invoice month,Jour (s) après la fin du mois de facture,
 Month(s) after the end of the invoice month,Mois (s) après la fin du mois de la facture,
@@ -4774,7 +4379,6 @@
 (including),(compris),
 ACC-SH-.YYYY.-,ACC-SH-.YYYY.-,
 Folio no.,No. de Folio,
-Address and Contacts,Adresse et Contacts,
 Contact List,Liste de contacts,
 Hidden list maintaining the list of contacts linked to Shareholder,Liste cachée maintenant la liste des contacts liés aux actionnaires,
 Specify conditions to calculate shipping amount,Spécifier les conditions pour calculer le montant de la livraison,
@@ -5162,9 +4766,6 @@
 Score,Score,
 Supplier Scorecard Scoring Standing,Classement de la Fiche d'Évaluation Fournisseur,
 Standing Name,Nom du Classement,
-Purple,Violet,
-Yellow,jaune,
-Orange,orange,
 Min Grade,Note Minimale,
 Max Grade,Note Maximale,
 Warn Purchase Orders,Avertir lors de Bons de Commande,
@@ -5199,7 +4800,6 @@
 Customer Details,Détails du client,
 Phone Number,Numéro de téléphone,
 Skype ID,ID Skype,
-Linked Documents,Documents liés,
 Appointment With,Rendez-vous avec,
 Calendar Event,Événement de calendrier,
 Appointment Booking Settings,Paramètres de réservation de rendez-vous,
@@ -5217,7 +4817,6 @@
 Success Redirect URL,URL de redirection réussie,
 "Leave blank for home.\nThis is relative to site URL, for example ""about"" will redirect to ""https://yoursitename.com/about""","Laissez vide pour la maison. Ceci est relatif à l'URL du site, par exemple &quot;about&quot; redirigera vers &quot;https://yoursitename.com/about&quot;",
 Appointment Booking Slots,Horaires de prise de rendez-vous,
-Day Of Week,Jour de la Semaine,
 From Time ,Horaire de Début,
 Campaign Email Schedule,Calendrier des e-mails de campagne,
 Send After (days),Envoyer après (jours),
@@ -5260,7 +4859,6 @@
 Follow Up,Suivre,
 Next Contact By,Contact Suivant Par,
 Next Contact Date,Date du Prochain Contact,
-Ends On,Se termine le,
 Address & Contact,Adresse &amp; Contact,
 Mobile No.,N° Mobile.,
 Lead Type,Type de Lead,
@@ -5307,8 +4905,6 @@
 Post Status,Statut du message,
 Posted,Publié,
 Share On,Partager sur,
-Twitter,Twitter,
-LinkedIn,LinkedIn,
 Twitter Post Id,Identifiant de publication Twitter,
 LinkedIn Post Id,Identifiant de publication LinkedIn,
 Tweet,Tweet,
@@ -5858,7 +5454,6 @@
 Normal Test Template,Modèle de Test Normal,
 Patient Demographics,Démographie du Patient,
 HLC-PAT-.YYYY.-,HLC-PAT-. AAAA.-,
-Middle Name (optional),Prénom (facultatif),
 Inpatient Status,Statut d'hospitalisation,
 "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.","Si «Lier le client au patient» est coché dans les paramètres de soins de santé et qu'un client existant n'est pas sélectionné, un client sera créé pour ce patient pour enregistrer les transactions dans le module Comptes.",
 Personal and Social History,Antécédents Personnels et Sociaux,
@@ -6185,7 +5780,6 @@
 Scheduled Date,Date Prévue,
 Actual Date,Date Réelle,
 Maintenance Schedule Item,Article de Calendrier d'Entretien,
-Random,aléatoire,
 No of Visits,Nb de Visites,
 MAT-MVS-.YYYY.-,MAT-MVS-. AAAA.-,
 Maintenance Date,Date de l'Entretien,
@@ -6435,7 +6029,6 @@
 Payment ID,ID de paiement,
 Membership Settings,Paramètres d'adhésion,
 Enable RazorPay For Memberships,Activer RazorPay pour les adhésions,
-RazorPay Settings,Paramètres de RazorPay,
 Billing Cycle,Cycle de facturation,
 Billing Frequency,Fréquence de facturation,
 "The number of billing cycles for which the customer should be charged. For example, if a customer is buying a 1-year membership that should be billed on a monthly basis, this value should be 12.","Le nombre de cycles de facturation pour lesquels le client doit être facturé. Par exemple, si un client achète un abonnement d'un an qui doit être facturé sur une base mensuelle, cette valeur doit être de 12.",
@@ -7014,7 +6607,7 @@
 Send with Attachment,Envoyer avec pièce jointe,
 Delay between Delivery Stops,Délai entre les arrêts de livraison,
 Delivery Stop,Étape de Livraison,
-Lock,Fermer à clé,
+Lock,Verrouiller,
 Visited,Visité,
 Order Information,Informations sur la commande,
 Contact Information,Informations de contact,
@@ -7057,7 +6650,7 @@
 Warranty Period (in days),Période de Garantie (en jours),
 Auto re-order,Re-commande auto,
 Reorder level based on Warehouse,Niveau de réapprovisionnement basé sur l’Entrepôt,
-Will also apply for variants unless overrridden,S'appliquera également pour des variantes sauf si remplacé,
+Will also apply for variants unless overridden,S'appliquera également pour des variantes sauf si remplacé,
 Units of Measure,Unités de Mesure,
 Will also apply for variants,S'appliquera également pour les variantes,
 Serial Nos and Batches,N° de Série et Lots,
@@ -7097,8 +6690,8 @@
 No of Months,Nombre de mois,
 Customer Items,Articles du clients,
 Inspection Criteria,Critères d'Inspection,
-Inspection Required before Purchase,Inspection Requise avant Achat,
-Inspection Required before Delivery,Inspection Requise avant Livraison,
+Inspection Required before Purchase,Inspection Requise à la réception,
+Inspection Required before Delivery,Inspection Requise à l'expedition,
 Default BOM,Nomenclature par Défaut,
 Supply Raw Materials for Purchase,Fournir les Matières Premières pour l'Achat,
 If subcontracted to a vendor,Si sous-traité à un fournisseur,
@@ -7945,12 +7538,10 @@
 Approvers,Approbateurs,
 The first Approver in the list will be set as the default Approver.,Le premier approbateur de la liste sera défini comme approbateur par défaut.,
 Shift Request Approver,Approbateur de demande de quart,
-PAN Number,Numéro PAN,
 Provident Fund Account,Compte de prévoyance,
 MICR Code,Code MICR,
 Repay unclaimed amount from salary,Rembourser le montant non réclamé sur le salaire,
 Deduction from salary,Déduction du salaire,
-Expired Leaves,Feuilles expirées,
 If this is not checked the loan by default will be considered as a Demand Loan,"Si cette case n'est pas cochée, le prêt par défaut sera considéré comme un prêt à vue",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Ce compte est utilisé pour enregistrer les remboursements de prêts de l'emprunteur et également pour décaisser les prêts à l'emprunteur,
 This account is capital account which is used to allocate capital for loan disbursal account ,Ce compte est un compte de capital qui est utilisé pour allouer du capital au compte de décaissement du prêt,
@@ -8198,7 +7789,6 @@
 Academic Term and Program,Terme académique et programme,
 Please remove this item and try to submit again or update the posting time.,Veuillez supprimer cet élément et réessayer de le valider ou mettre à jour l'heure de publication.,
 Failed to Authenticate the API key.,Échec de l'authentification de la clé API.,
-Invalid Credentials,Les informations d'identification invalides,
 URL can only be a string,L'URL ne peut être qu'une chaîne,
 "Here is your webhook secret, this will be shown to you only once.","Voici votre secret de webhook, il ne vous sera montré qu'une seule fois.",
 The payment for this membership is not paid. To generate invoice fill the payment details,"Le paiement de cette adhésion n'est pas payé. Pour générer une facture, remplissez les détails du paiement",
@@ -8763,7 +8353,6 @@
 Billing Address Details,Adresse de facturation (détails)
 Supplier Address Details,Adresse Fournisseur (détails)
 Retail,Commerce,
-Users,Utilisateurs,
 Permission Manager,Gestion des permissions,
 Fetch Timesheet,Récuprer les temps saisis,
 Get Supplier Group Details,Appliquer les informations depuis le Groupe de fournisseur,
@@ -8840,3 +8429,23 @@
 Is Mandatory,Est obligatoire,
 WhatsApp,WhatsApp,
 Make a call,Passer un coup de téléphone,
+No of Employees,Nb de salarié(e)s
+No. of Employees,Nb de salarié(e)s
+Annual Revenue,CA annuel
+Qualified By,Qualifié par
+Qualified on,Qualifié le
+Open Tasks,Tâche à faire ouverte
+No open task,Pas de Tâche à faire ouverte
+Open Events,Evénements ouvert
+No open event,Pas Evénements ouvert
+New Task,Nv. Tâche à faire
+No Notes,Pas de note
+New Note,Nouvelle Note
+Prospect Owner,Resp. du Prospect
+Deal Owner,Resp. de l'opportunité
+Stage,Etape
+Probability,Probabilité
+Closing,Clôture
+Allow Sales,Autoriser à la vente
+Approve,Approuver,
+Reject,Rejeter,
diff --git a/erpnext/translations/gu.csv b/erpnext/translations/gu.csv
index 3e22bd9..06a3cc6 100644
--- a/erpnext/translations/gu.csv
+++ b/erpnext/translations/gu.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,સ્વતઃ પુનરાવર્તિત દસ્તાવેજ અપડેટ થયો,
 Automotive,ઓટોમોટિવ,
 Available,ઉપલબ્ધ,
-Available Leaves,ઉપલબ્ધ પાંદડા,
 Available Qty,ઉપલબ્ધ Qty,
 Available Selling,ઉપલબ્ધ વેચાણ,
 Available for use date is required,ઉપયોગ તારીખ માટે ઉપલબ્ધ જરૂરી છે,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,હબ સમન્વયન ID,
 Human Resource,માનવ સંસાધન,
 Human Resources,માનવ સંસાધન,
-IFSC Code,આઈએફએસસી કોડ,
 IGST Amount,IGST રકમ,
 IP Address,IP સરનામું,
 ITC Available (whether in full op part),આઇટીસી ઉપલબ્ધ છે (સંપૂર્ણ ઓપ ભાગમાં છે કે નહીં),
@@ -1666,7 +1664,6 @@
 Other,અન્ય,
 Other Reports,અન્ય અહેવાલો,
 "Other outward supplies(Nil rated,Exempted)","અન્ય બાહ્ય પુરવઠો (નીલ રેટેડ, મુકત)",
-Others,અન્ય,
 Out Qty,Qty આઉટ,
 Out Value,મૂલ્ય,
 Out of Order,હુકમ બહાર,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),કુલ (કર વગર),
 Total Achieved,કુલ પ્રાપ્ત,
 Total Actual,વાસ્તવિક કુલ,
-Total Allocated Leaves,કુલ ફાળવેલ પાંદડા,
 Total Amount,કુલ રકમ,
 Total Amount Credited,કુલ રકમનો શ્રેય,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,ખરીદી રસીદ વસ્તુઓ ટેબલ કુલ લાગુ ખર્ચ કુલ કર અને ખર્ચ તરીકે જ હોવી જોઈએ,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,તમારો પત્ર વડા અને લોગો અપલોડ કરો. (જો તમે પછીથી તેમને ફેરફાર કરી શકો છો).,
 Upper Income,ઉચ્ચ આવક,
 Use Sandbox,ઉપયોગ સેન્ડબોક્સ,
-Used Leaves,વપરાયેલ પાંદડા,
 User,વપરાશકર્તા,
 User ID,વપરાશકર્તા ID,
 User ID not set for Employee {0},વપરાશકર્તા ID કર્મચારી માટે સેટ નથી {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),(દિવસોમાં) વોરંટી સમયગાળા,
 Auto re-order,ઓટો ફરી ઓર્ડર,
 Reorder level based on Warehouse,વેરહાઉસ પર આધારિત પુનઃક્રમાંકિત કરો સ્તર,
-Will also apply for variants unless overrridden,Overrridden સિવાય પણ ચલો માટે લાગુ પડશે,
+Will also apply for variants unless overridden,Overrridden સિવાય પણ ચલો માટે લાગુ પડશે,
 Units of Measure,માપવા એકમો,
 Will also apply for variants,પણ ચલો માટે લાગુ પડશે,
 Serial Nos and Batches,સીરીયલ સંખ્યા અને બૅચેસ,
@@ -7949,12 +7944,10 @@
 Approvers,વિવાદ,
 The first Approver in the list will be set as the default Approver.,સૂચિમાં પ્રથમ મંજૂરી આપનારને ડિફ defaultલ્ટ મંજૂરી તરીકે સેટ કરવામાં આવશે.,
 Shift Request Approver,શિફ્ટ વિનંતી મંજૂરી,
-PAN Number,પાન નંબર,
 Provident Fund Account,પ્રોવિડન્ટ ફંડ એકાઉન્ટ,
 MICR Code,એમઆઈસીઆર કોડ,
 Repay unclaimed amount from salary,પગારમાંથી દાવેદારી રકમ પરત કરો,
 Deduction from salary,પગારમાંથી કપાત,
-Expired Leaves,સમાપ્ત પાંદડા,
 If this is not checked the loan by default will be considered as a Demand Loan,જો આને તપાસવામાં નહીં આવે તો ડિફોલ્ટ રૂપે લોનને ડિમાન્ડ લોન માનવામાં આવશે,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,આ એકાઉન્ટનો ઉપયોગ orણ લેનારા પાસેથી લોન ચુકવણી બુક કરવા અને લેનારાને લોન વહેંચવા માટે થાય છે.,
 This account is capital account which is used to allocate capital for loan disbursal account ,આ એકાઉન્ટ કેપિટલ એકાઉન્ટ છે જેનો ઉપયોગ લોન વિતરણ ખાતા માટે મૂડી ફાળવવા માટે થાય છે,
@@ -8748,3 +8741,5 @@
 Is Mandatory,ફરજિયાત છે,
 WhatsApp,વોટ્સેપ,
 Make a call,કોલ કરો,
+Approve,મંજૂર,
+Reject,નકારો,
diff --git a/erpnext/translations/he.csv b/erpnext/translations/he.csv
index b0e6306..d5fcab6 100644
--- a/erpnext/translations/he.csv
+++ b/erpnext/translations/he.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,מסמך חזרה אוטומטית עודכן,
 Automotive,רכב,
 Available,זמין,
-Available Leaves,עלים זמינים,
 Available Qty,כמות זמינה,
 Available Selling,מכירה זמינה,
 Available for use date is required,נדרש לתאריך השימוש,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,מזהה סנכרון רכזת,
 Human Resource,משאבי אנוש,
 Human Resources,משאבי אנוש,
-IFSC Code,קוד IFSC,
 IGST Amount,סכום IGST,
 IP Address,כתובת ה - IP,
 ITC Available (whether in full op part),ITC זמין (אם בחלק אופ מלא),
@@ -1666,7 +1664,6 @@
 Other,אחר,
 Other Reports,דוחות נוספים,
 "Other outward supplies(Nil rated,Exempted)","אספקה חיצונית אחרת (מדורג אפס, פטור)",
-Others,אחרים,
 Out Qty,מתוך כמות,
 Out Value,ערך מתוך,
 Out of Order,מקולקל,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),סה&quot;כ (ללא מס),
 Total Achieved,"סה""כ הושג",
 Total Actual,"סה""כ בפועל",
-Total Allocated Leaves,סה&quot;כ עלים שהוקצו,
 Total Amount,"סה""כ לתשלום",
 Total Amount Credited,סכום כולל אשראי,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,סה&quot;כ החיובים החלים בטבלת פריטי קבלה לרכישה חייבים להיות זהים לסכומי המסים והחיובים,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,העלה ראש המכתב ואת הלוגו שלך. (אתה יכול לערוך אותם מאוחר יותר).,
 Upper Income,עליון הכנסה,
 Use Sandbox,השתמש בארגז חול,
-Used Leaves,עלים משומשים,
 User,מִשׁתַמֵשׁ,
 User ID,זיהוי משתמש,
 User ID not set for Employee {0},זיהוי משתמש לא נקבע לעובדים {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),תקופת אחריות (בימים),
 Auto re-order,רכב מחדש כדי,
 Reorder level based on Warehouse,רמת הזמנה חוזרת המבוסס על מחסן,
-Will also apply for variants unless overrridden,תחול גם לגרסות אלא אם overrridden,
+Will also apply for variants unless overridden,תחול גם לגרסות אלא אם overridden,
 Units of Measure,יחידות מידה,
 Will also apply for variants,תחול גם לגרסות,
 Serial Nos and Batches,מספרים וסידורים סדרתיים,
@@ -7949,12 +7944,10 @@
 Approvers,מחלוקת,
 The first Approver in the list will be set as the default Approver.,המאשר הראשון ברשימה יוגדר כמאשר ברירת המחדל.,
 Shift Request Approver,אישור בקשת משמרת,
-PAN Number,מספר PAN,
 Provident Fund Account,חשבון קופת גמל,
 MICR Code,קוד MICR,
 Repay unclaimed amount from salary,החזר סכום שלא נתבע מהמשכורת,
 Deduction from salary,ניכוי משכר,
-Expired Leaves,עלים שפג תוקפם,
 If this is not checked the loan by default will be considered as a Demand Loan,אם זה לא מסומן ההלוואה כברירת מחדל תיחשב כהלוואת דרישה,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,חשבון זה משמש להזמנת החזרי הלוואות מהלווה וגם להוצאת הלוואות ללווה,
 This account is capital account which is used to allocate capital for loan disbursal account ,חשבון זה הוא חשבון הון המשמש להקצאת הון לחשבון פרסום הלוואות,
@@ -8748,3 +8741,5 @@
 Is Mandatory,זה חובה,
 WhatsApp,ווטסאפ,
 Make a call,להתקשר,
+Approve,לְאַשֵׁר,
+Reject,לִדחוֹת,
diff --git a/erpnext/translations/hi.csv b/erpnext/translations/hi.csv
index 35c4b81..a5caa66 100644
--- a/erpnext/translations/hi.csv
+++ b/erpnext/translations/hi.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,ऑटो दोहराना दस्तावेज़ अद्यतन,
 Automotive,मोटर वाहन,
 Available,उपलब्ध,
-Available Leaves,उपलब्ध पत्तियां,
 Available Qty,उपलब्ध मात्रा,
 Available Selling,उपलब्ध बेचना,
 Available for use date is required,उपयोग की तारीख के लिए उपलब्ध है,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,हब सिंक आईडी,
 Human Resource,मानव संसाधन,
 Human Resources,मानवीय संसाधन,
-IFSC Code,आईएफएससी कोड,
 IGST Amount,आईजीएसटी राशि,
 IP Address,आईपी पता,
 ITC Available (whether in full op part),ITC उपलब्ध (पूर्ण ऑप भाग में),
@@ -1666,7 +1664,6 @@
 Other,अन्य,
 Other Reports,अन्य रिपोर्टें,
 "Other outward supplies(Nil rated,Exempted)","अन्य बाहरी आपूर्ति (निल रेटेड, छूट)",
-Others,दूसरों,
 Out Qty,मात्रा बाहर,
 Out Value,आउट मान,
 Out of Order,खराब,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),कुल (कर के बिना),
 Total Achieved,कुल प्राप्त,
 Total Actual,वास्तविक कुल,
-Total Allocated Leaves,कुल आवंटित पत्तियां,
 Total Amount,कुल राशि,
 Total Amount Credited,कुल राशि क्रेडिट,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,खरीद रसीद आइटम तालिका में कुल लागू शुल्कों के कुल करों और शुल्कों के रूप में ही होना चाहिए,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,अपने पत्र सिर और लोगो अपलोड करें। (आप उन्हें बाद में संपादित कर सकते हैं)।,
 Upper Income,ऊपरी आय,
 Use Sandbox,उपयोग सैंडबॉक्स,
-Used Leaves,प्रयुक्त पत्तियां,
 User,उपयोगकर्ता,
 User ID,प्रयोक्ता आईडी,
 User ID not set for Employee {0},यूजर आईडी कर्मचारी के लिए सेट नहीं {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),वारंटी अवधि (दिनों में),
 Auto re-order,ऑटो पुनः आदेश,
 Reorder level based on Warehouse,गोदाम के आधार पर पुन: व्यवस्थित स्तर,
-Will also apply for variants unless overrridden,Overrridden जब तक भी वेरिएंट के लिए लागू होगी,
+Will also apply for variants unless overridden,Overrridden जब तक भी वेरिएंट के लिए लागू होगी,
 Units of Measure,मापन की इकाई,
 Will also apply for variants,यह भी वेरिएंट के लिए लागू होगी,
 Serial Nos and Batches,सीरियल नंबर और बैचों,
@@ -7949,12 +7944,10 @@
 Approvers,approvers,
 The first Approver in the list will be set as the default Approver.,सूची में पहले अनुमोदन डिफ़ॉल्ट डिफ़ॉल्ट के रूप में सेट किया जाएगा।,
 Shift Request Approver,शिफ्ट रिक्वेस्ट अप्रूवर,
-PAN Number,पैन नंबर,
 Provident Fund Account,भविष्य निधि खाता,
 MICR Code,MICR कोड,
 Repay unclaimed amount from salary,वेतन से लावारिस राशि को चुकाएं,
 Deduction from salary,वेतन से कटौती,
-Expired Leaves,समय सीमा समाप्त,
 If this is not checked the loan by default will be considered as a Demand Loan,"यदि यह डिफ़ॉल्ट रूप से ऋण की जाँच नहीं है, तो इसे डिमांड लोन माना जाएगा",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,इस खाते का उपयोग उधारकर्ता से ऋण चुकौती की बुकिंग के लिए किया जाता है और उधारकर्ता को ऋण का वितरण भी किया जाता है,
 This account is capital account which is used to allocate capital for loan disbursal account ,यह खाता पूंजी खाता है जिसका उपयोग ऋण वितरण खाते के लिए पूंजी आवंटित करने के लिए किया जाता है,
@@ -8748,3 +8741,5 @@
 Is Mandatory,अनिवार्य है,
 WhatsApp,WhatsApp,
 Make a call,कॉल करें,
+Approve,मंजूर,
+Reject,अस्वीकार,
diff --git a/erpnext/translations/hr.csv b/erpnext/translations/hr.csv
index c44d421..2834602 100644
--- a/erpnext/translations/hr.csv
+++ b/erpnext/translations/hr.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Ažurira se automatski ponavljanje dokumenta,
 Automotive,Automobilska industrija,
 Available,Dostupno,
-Available Leaves,Dostupni lišće,
 Available Qty,Dostupno Količina,
 Available Selling,Dostupna prodaja,
 Available for use date is required,Dostupan je za datum upotrebe,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,ID sinkronizacije huba,
 Human Resource,Ljudski resursi,
 Human Resources,Ljudski resursi,
-IFSC Code,IFSC kod,
 IGST Amount,Iznos IGST,
 IP Address,IP adresa,
 ITC Available (whether in full op part),Dostupan ITC (bilo u cijelom op. Dijelu),
@@ -1666,7 +1664,6 @@
 Other,Drugi,
 Other Reports,Ostala izvješća,
 "Other outward supplies(Nil rated,Exempted)","Ostale vanjske zalihe (ocjenjivano bez vrijednosti, izuzeće)",
-Others,Ostali,
 Out Qty,Od kol,
 Out Value,Iz vrijednost,
 Out of Order,Izvanredno,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Ukupno (bez poreza),
 Total Achieved,Ukupno Ostvareno,
 Total Actual,Ukupno Stvarni,
-Total Allocated Leaves,Ukupno dopuštena lišća,
 Total Amount,Ukupan iznos,
 Total Amount Credited,Ukupan iznos je odobren,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Ukupno odgovarajuće naknade u potvrdi o kupnji stavke stolu mora biti ista kao i Total poreza i naknada,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Upload Vaše pismo glavu i logotip. (Možete ih uređivati kasnije).,
 Upper Income,Gornja Prihodi,
 Use Sandbox,Sandbox,
-Used Leaves,Koristi lišće,
 User,Korisnik,
 User ID,Korisnički ID,
 User ID not set for Employee {0},Korisnik ID nije postavljen za zaposlenika {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Jamstveni period (u danima),
 Auto re-order,Automatski reorganiziraj,
 Reorder level based on Warehouse,Razina redoslijeda na temelju Skladište,
-Will also apply for variants unless overrridden,Također će zatražiti varijante osim overrridden,
+Will also apply for variants unless overridden,Također će zatražiti varijante osim overridden,
 Units of Measure,Mjerne jedinice,
 Will also apply for variants,Također će podnijeti zahtjev za varijante,
 Serial Nos and Batches,Serijski brojevi i serije,
@@ -7949,12 +7944,10 @@
 Approvers,Odobrivači,
 The first Approver in the list will be set as the default Approver.,Prvi odobravatelj s popisa postavit će se kao zadani odobravatelj.,
 Shift Request Approver,Odobritelj zahtjeva za smjenom,
-PAN Number,PAN broj,
 Provident Fund Account,Račun osiguravajućeg fonda,
 MICR Code,MICR kod,
 Repay unclaimed amount from salary,Otplatite neiskorišteni iznos iz plaće,
 Deduction from salary,Odbitak od plaće,
-Expired Leaves,Isteklo lišće,
 If this is not checked the loan by default will be considered as a Demand Loan,"Ako se ovo ne potvrdi, zajam će se prema zadanim postavkama smatrati zajmom na zahtjev",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Ovaj se račun koristi za rezerviranje otplate zajma od zajmoprimca i za isplatu zajmova zajmoprimcu,
 This account is capital account which is used to allocate capital for loan disbursal account ,Ovaj račun je račun kapitala koji se koristi za raspodjelu kapitala za račun izdvajanja zajma,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Je obavezno,
 WhatsApp,Što ima,
 Make a call,Uputi poziv,
+Approve,Odobriti,
+Reject,Odbiti,
diff --git a/erpnext/translations/hu.csv b/erpnext/translations/hu.csv
index c707a1e..a262c8a 100644
--- a/erpnext/translations/hu.csv
+++ b/erpnext/translations/hu.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Az automatikus ismétlődő dokumentum frissítve,
 Automotive,Autóipar,
 Available,Elérhető,
-Available Leaves,Lehetséges távollétek,
 Available Qty,Elérhető Menny.,
 Available Selling,Elérhető értékesítés,
 Available for use date is required,Rendelkezésre állási dátum szükséges,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub szinkronizálási azonosító ID,
 Human Resource,Emberi Erőforrás HR,
 Human Resources,Emberi erőforrások HR,
-IFSC Code,IFSC kód,
 IGST Amount,IGST összeg,
 IP Address,IP-cím,
 ITC Available (whether in full op part),ITC elérhető (teljes opcióban),
@@ -1666,7 +1664,6 @@
 Other,Egyéb,
 Other Reports,Más jelentések,
 "Other outward supplies(Nil rated,Exempted)","Egyéb külső készletek (nulla, mentes)",
-Others,Egyéb,
 Out Qty,Mennyiségen kívül,
 Out Value,Értéken kívül,
 Out of Order,Üzemen kívül,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Összesen (adó nélkül/nettó),
 Total Achieved,Összes Elért,
 Total Actual,Összes Aktuális,
-Total Allocated Leaves,Teljes elosztott távollétek száma,
 Total Amount,Összesen,
 Total Amount Credited,Összesen jóváírt összeg,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Összesen alkalmazandó díjak a vásárlási nyugta tételek táblázatban egyeznie kell az Összes adókkal és illetékekkel,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Kérjük töltse fel levele fejlécét és logo-ját. (Ezeket később szerkesztheti).,
 Upper Income,Magasabb jövedelem,
 Use Sandbox,Sandbox felhasználása,
-Used Leaves,Felhasznált távollétek,
 User,használó,
 User ID,Felhasználó ID,
 User ID not set for Employee {0},Felhasználói azonosítót nem állított be az Alkalmazotthoz: {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Garancia hossza (napokban),
 Auto re-order,Auto újra-rendelés,
 Reorder level based on Warehouse,Raktárkészleten alapuló újrerendelési szint,
-Will also apply for variants unless overrridden,"Változatokra is alkalmazni fogja, hacsak nem kerül fellülírásra",
+Will also apply for variants unless overridden,"Változatokra is alkalmazni fogja, hacsak nem kerül fellülírásra",
 Units of Measure,Mértékegységek,
 Will also apply for variants,Változatokra is alkalmazni fogja,
 Serial Nos and Batches,Sorszámok és kötegek,
@@ -7949,12 +7944,10 @@
 Approvers,Jóváhagyó,
 The first Approver in the list will be set as the default Approver.,A lista első jóváhagyója lesz az alapértelmezett jóváhagyó.,
 Shift Request Approver,Shift Request Approver,
-PAN Number,PAN szám,
 Provident Fund Account,Provident Fund számla,
 MICR Code,MICR kód,
 Repay unclaimed amount from salary,Visszafizetni az igényelt összeget a fizetésből,
 Deduction from salary,A fizetés levonása,
-Expired Leaves,Lejárt levelek,
 If this is not checked the loan by default will be considered as a Demand Loan,"Ha ez nincs bejelölve, akkor a hitelt alapértelmezés szerint Igény szerinti kölcsönnek kell tekinteni",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,"Ezt a számlát arra használják, hogy foglalják le a hiteltől származó hiteltörlesztéseket, és kölcsönöket is folyósítanak a hitelfelvevőnek",
 This account is capital account which is used to allocate capital for loan disbursal account ,"Ez a számla tőkeszámla, amelyet a hitel folyósítási számlájához szükséges tőke allokálására használnak",
@@ -8748,3 +8741,5 @@
 Is Mandatory,Kötelező,
 WhatsApp,WhatsApp,
 Make a call,Hívást kezdeményezni,
+Approve,Jóváhagy,
+Reject,Elutasít,
diff --git a/erpnext/translations/id.csv b/erpnext/translations/id.csv
index 2ec17e6..c4e50fd 100644
--- a/erpnext/translations/id.csv
+++ b/erpnext/translations/id.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Pembaruan dokumen otomatis diperbarui,
 Automotive,Otomotif,
 Available,Tersedia,
-Available Leaves,Cuti Yang Tersedia,
 Available Qty,Qty Tersedia,
 Available Selling,Jual Beli,
 Available for use date is required,Tersedia untuk tanggal penggunaan diperlukan,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub Sync ID,
 Human Resource,Sumber daya manusia,
 Human Resources,Sumber daya manusia,
-IFSC Code,Kode IFSC,
 IGST Amount,Jumlah IGST,
 IP Address,Alamat IP,
 ITC Available (whether in full op part),ITC Tersedia (baik dalam bagian op penuh),
@@ -1666,7 +1664,6 @@
 Other,Lain-lain,
 Other Reports,Laporan Lainnya,
 "Other outward supplies(Nil rated,Exempted)","Persediaan luar lainnya (nilai nol, Dibebaskan)",
-Others,Lainnya,
 Out Qty,Out Qty,
 Out Value,out Nilai,
 Out of Order,Habis,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Total (Tanpa Pajak),
 Total Achieved,Total Dicapai,
 Total Actual,Total Aktual,
-Total Allocated Leaves,Total Cuti Yang Dialokasikan,
 Total Amount,Nilai Total,
 Total Amount Credited,Jumlah Total Dikreditkan,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Total Biaya Berlaku di Purchase meja Jenis Penerimaan harus sama dengan jumlah Pajak dan Biaya,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Unggah kop surat dan logo. (Anda dapat mengubahnya nanti).,
 Upper Income,Penghasilan Atas,
 Use Sandbox,Gunakan Sandbox,
-Used Leaves,Cuti Yang Telah Digunakan,
 User,Pengguna,
 User ID,ID Pengguna,
 User ID not set for Employee {0},User ID tidak ditetapkan untuk Karyawan {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Masa Garansi (dalam hari),
 Auto re-order,Auto re-order,
 Reorder level based on Warehouse,Tingkat Re-Order berdasarkan Gudang,
-Will also apply for variants unless overrridden,Juga akan berlaku untuk varian kecuali tertimpa,
+Will also apply for variants unless overridden,Juga akan berlaku untuk varian kecuali tertimpa,
 Units of Measure,Satuan ukur,
 Will also apply for variants,Juga akan berlaku untuk varian,
 Serial Nos and Batches,Nomor Seri dan Partai,
@@ -7949,12 +7944,10 @@
 Approvers,Pemberi persetujuan,
 The first Approver in the list will be set as the default Approver.,Pemberi Persetujuan pertama dalam daftar akan ditetapkan sebagai Pemberi Persetujuan default.,
 Shift Request Approver,Penyetuju Permintaan Shift,
-PAN Number,Nomor PAN,
 Provident Fund Account,Rekening Dana Provident,
 MICR Code,Kode MICR,
 Repay unclaimed amount from salary,Membayar kembali jumlah gaji yang belum diklaim,
 Deduction from salary,Pemotongan gaji,
-Expired Leaves,Daun kadaluarsa,
 If this is not checked the loan by default will be considered as a Demand Loan,"Jika tidak dicentang, pinjaman secara default akan dianggap sebagai Pinjaman Permintaan",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Rekening ini digunakan untuk membukukan pembayaran pinjaman dari peminjam dan juga menyalurkan pinjaman kepada peminjam,
 This account is capital account which is used to allocate capital for loan disbursal account ,Akun ini adalah akun modal yang digunakan untuk mengalokasikan modal ke akun pencairan pinjaman,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Apakah Wajib,
 WhatsApp,Ada apa,
 Make a call,Menelpon,
+Approve,Menyetujui,
+Reject,Menolak,
diff --git a/erpnext/translations/is.csv b/erpnext/translations/is.csv
index 93df452..50c06ec 100644
--- a/erpnext/translations/is.csv
+++ b/erpnext/translations/is.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Sjálfvirk endurtaka skjal uppfært,
 Automotive,Automotive,
 Available,Laus,
-Available Leaves,Lausar blöð,
 Available Qty,Laus magn,
 Available Selling,Laus selja,
 Available for use date is required,Til staðar er hægt að nota dagsetninguna,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub Sync ID,
 Human Resource,Mannauðs,
 Human Resources,Mannauður,
-IFSC Code,IFSC-kóði,
 IGST Amount,IGST upphæð,
 IP Address,IP-tölu,
 ITC Available (whether in full op part),ITC í boði (hvort sem það er í heild hluta),
@@ -1666,7 +1664,6 @@
 Other,Annað,
 Other Reports,Aðrar skýrslur,
 "Other outward supplies(Nil rated,Exempted)","Aðrar birgðir út á við (ekki metnar, undanþegnar)",
-Others,Aðrir,
 Out Qty,Út magn,
 Out Value,út Value,
 Out of Order,Bilað,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Samtals (án skatta),
 Total Achieved,alls Náð,
 Total Actual,alls Raunveruleg,
-Total Allocated Leaves,Samtals úthlutað blöð,
 Total Amount,Heildarupphæð,
 Total Amount Credited,Heildarfjárhæð innheimt,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Samtals greiðsla í kvittun atriðum borðið verður að vera það sama og Samtals skatta og gjöld,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Hlaða bréf höfuðið og merki. (Þú getur breytt þeim síðar).,
 Upper Income,Efri tekjur,
 Use Sandbox,Nota Sandbox,
-Used Leaves,Notaðar blöð,
 User,Notandi,
 User ID,notandanafn,
 User ID not set for Employee {0},User ID ekki sett fyrir Starfsmaður {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Ábyrgðartímabilið (í dögum),
 Auto re-order,Auto endurraða,
 Reorder level based on Warehouse,Uppröðun stigi byggist á Lager,
-Will also apply for variants unless overrridden,Mun einnig gilda um afbrigði nema overrridden,
+Will also apply for variants unless overridden,Mun einnig gilda um afbrigði nema overridden,
 Units of Measure,Mælieiningar,
 Will also apply for variants,Mun einnig gilda fyrir afbrigði,
 Serial Nos and Batches,Raðnúmer og lotur,
@@ -7949,12 +7944,10 @@
 Approvers,Ágreiningsmenn,
 The first Approver in the list will be set as the default Approver.,Fyrsti samþykkur listans verður stilltur sem sjálfgefinn samþykkur.,
 Shift Request Approver,Samþykki vaktabeiðni,
-PAN Number,PAN númer,
 Provident Fund Account,Reikningur sjóðsins,
 MICR Code,MICR kóði,
 Repay unclaimed amount from salary,Endurgreiða óheimta upphæð af launum,
 Deduction from salary,Frádráttur frá launum,
-Expired Leaves,Útrunnið lauf,
 If this is not checked the loan by default will be considered as a Demand Loan,Ef ekki er hakað við þetta verður lánið sjálfgefið litið á sem eftirspurnarlán,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Þessi reikningur er notaður til að bóka endurgreiðslur lána frá lántakanda og einnig til að greiða út lán til lántakanda,
 This account is capital account which is used to allocate capital for loan disbursal account ,Þessi reikningur er fjármagnsreikningur sem er notaður til að úthluta fjármagni til útborgunarreiknings lána,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Er skylda,
 WhatsApp,WhatsApp,
 Make a call,Hringja,
+Approve,Samþykkja,
+Reject,Hafna,
diff --git a/erpnext/translations/it.csv b/erpnext/translations/it.csv
index 558b091..3760895 100644
--- a/erpnext/translations/it.csv
+++ b/erpnext/translations/it.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Ripetizione automatica aggiornata,
 Automotive,Automotive,
 Available,Disponibile,
-Available Leaves,Ferie disponibili,
 Available Qty,Disponibile Quantità,
 Available Selling,Vendita disponibile,
 Available for use date is required,Disponibile per la data di utilizzo è richiesto,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,ID di sincronizzazione Hub,
 Human Resource,Risorsa Umana,
 Human Resources,Risorse umane,
-IFSC Code,Codice IFSC,
 IGST Amount,Quantità IGST,
 IP Address,Indirizzo IP,
 ITC Available (whether in full op part),ITC disponibile (sia nella parte operativa completa),
@@ -1666,7 +1664,6 @@
 Other,Altro,
 Other Reports,Altri Reports,
 "Other outward supplies(Nil rated,Exempted)","Altre forniture esterne (esenti da zero, esenti)",
-Others,Altri,
 Out Qty,out Quantità,
 Out Value,Valore out,
 Out of Order,Guasto,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Totale (senza tasse),
 Total Achieved,Totale raggiunto,
 Total Actual,Totale Actual,
-Total Allocated Leaves,Ferie totali allocate,
 Total Amount,Totale Importo,
 Total Amount Credited,Importo totale accreditato,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Totale oneri addebitati in Acquisto tabella di carico Gli articoli devono essere uguale Totale imposte e oneri,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Carica la tua testa lettera e logo. (È possibile modificare in un secondo momento).,
 Upper Income,Reddito superiore,
 Use Sandbox,Usa Sandbox,
-Used Leaves,Ferie Usate,
 User,Utente,
 User ID,ID utente,
 User ID not set for Employee {0},ID utente non impostato per Dipedente {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Periodo di garanzia (in giorni),
 Auto re-order,Auto riordino,
 Reorder level based on Warehouse,Livello di riordino sulla base di Magazzino,
-Will also apply for variants unless overrridden,Si applica anche per le varianti meno overrridden,
+Will also apply for variants unless overridden,Si applica anche per le varianti meno overridden,
 Units of Measure,Unità di misura,
 Will also apply for variants,Si applica anche per le varianti,
 Serial Nos and Batches,Numero e lotti seriali,
@@ -7949,12 +7944,10 @@
 Approvers,Approvatori,
 The first Approver in the list will be set as the default Approver.,Il primo approvatore nell&#39;elenco verrà impostato come approvatore predefinito.,
 Shift Request Approver,Approvatore richiesta di turno,
-PAN Number,Numero PAN,
 Provident Fund Account,Conto del fondo di previdenza,
 MICR Code,Codice MICR,
 Repay unclaimed amount from salary,Rimborsare l&#39;importo non reclamato dallo stipendio,
 Deduction from salary,Detrazione dallo stipendio,
-Expired Leaves,Foglie scadute,
 If this is not checked the loan by default will be considered as a Demand Loan,"Se questa opzione non è selezionata, il prestito di default sarà considerato come un prestito a vista",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Questo conto viene utilizzato per la prenotazione del rimborso del prestito dal mutuatario e anche per l&#39;erogazione dei prestiti al mutuatario,
 This account is capital account which is used to allocate capital for loan disbursal account ,Questo conto è un conto capitale utilizzato per allocare il capitale per il conto di erogazione del prestito,
@@ -8748,3 +8741,5 @@
 Is Mandatory,È obbligatorio,
 WhatsApp,WhatsApp,
 Make a call,Effettuare una chiamata,
+Approve,Approva,
+Reject,Rifiutare,
diff --git a/erpnext/translations/ja.csv b/erpnext/translations/ja.csv
index 9a7bebe..888ec80 100644
--- a/erpnext/translations/ja.csv
+++ b/erpnext/translations/ja.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,自動繰り返し文書が更新されました,
 Automotive,自動車,
 Available,利用可,
-Available Leaves,利用可能な葉,
 Available Qty,利用可能な数量,
 Available Selling,販売可能,
 Available for use date is required,使用可能な日付が必要です,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,ハブ同期ID,
 Human Resource,人材,
 Human Resources,人事,
-IFSC Code,IFSCコード,
 IGST Amount,IGST金額,
 IP Address,IPアドレス,
 ITC Available (whether in full op part),利用可能なITC(完全な一部かどうかにかかわらず),
@@ -1666,7 +1664,6 @@
 Other,その他,
 Other Reports,その他のレポート,
 "Other outward supplies(Nil rated,Exempted)",その他の外部供給品(定格なし、免除),
-Others,その他,
 Out Qty,出量,
 Out Value,タイムアウト値,
 Out of Order,故障中,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),合計(税なし),
 Total Achieved,達成計,
 Total Actual,実費計,
-Total Allocated Leaves,割り当てられた合計葉,
 Total Amount,合計,
 Total Amount Credited,合計金額,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,購入レシートItemsテーブル内の合計有料合計税金、料金と同じでなければなりません,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,レターヘッドとロゴをアップロードします(後で編集可能です),
 Upper Income,高収益,
 Use Sandbox,サンドボックスを使用,
-Used Leaves,中古の葉,
 User,ユーザー,
 User ID,ユーザー ID,
 User ID not set for Employee {0},従業員{0}のユーザーIDが未設定です。,
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),保証期間(日数),
 Auto re-order,自動再注文,
 Reorder level based on Warehouse,倉庫ごとの再注文レベル,
-Will also apply for variants unless overrridden,上書きされない限り、バリエーションについても適用されます,
+Will also apply for variants unless overridden,上書きされない限り、バリエーションについても適用されます,
 Units of Measure,測定の単位,
 Will also apply for variants,バリエーションについても適用されます,
 Serial Nos and Batches,シリアル番号とバッチ,
@@ -7949,12 +7944,10 @@
 Approvers,承認者,
 The first Approver in the list will be set as the default Approver.,リストの最初の承認者がデフォルトの承認者として設定されます。,
 Shift Request Approver,シフトリクエスト承認者,
-PAN Number,PAN番号,
 Provident Fund Account,プロビデントファンドアカウント,
 MICR Code,MICRコード,
 Repay unclaimed amount from salary,未請求額を給与から返済する,
 Deduction from salary,給与からの控除,
-Expired Leaves,期限切れの葉,
 If this is not checked the loan by default will be considered as a Demand Loan,これがチェックされていない場合、デフォルトでローンはデマンドローンと見なされます,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,このアカウントは、借り手からのローン返済の予約と、借り手へのローンの支払いに使用されます。,
 This account is capital account which is used to allocate capital for loan disbursal account ,この口座は、ローン実行口座に資本を割り当てるために使用される資本口座です。,
@@ -8748,3 +8741,5 @@
 Is Mandatory,必須です,
 WhatsApp,WhatsApp,
 Make a call,電話を掛ける,
+Approve,承認,
+Reject,拒否,
diff --git a/erpnext/translations/km.csv b/erpnext/translations/km.csv
index 425940c..d2003c0 100644
--- a/erpnext/translations/km.csv
+++ b/erpnext/translations/km.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,បានធ្វើបច្ចុប្បន្នភាពឯកសារដោយស្វ័យប្រវត្តិ,
 Automotive,រថយន្ដ,
 Available,ដែលអាចប្រើបាន,
-Available Leaves,មានស្លឹក,
 Available Qty,ដែលអាចប្រើបាន Qty,
 Available Selling,លក់ដែលអាចប្រើបាន,
 Available for use date is required,អាចរកបានសម្រាប់កាលបរិច្ឆេទប្រើ,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub Sync ID,
 Human Resource,ធនធានមនុស្ស,
 Human Resources,ធនធានមនុស្ស,
-IFSC Code,កូដ IFSC,
 IGST Amount,បរិមាណ IGST,
 IP Address,អាសយដ្ឋាន IP,
 ITC Available (whether in full op part),មានអាយ។ ស៊ី។ ធី។ (មិនថាជាផ្នែកពេញលេញ),
@@ -1666,7 +1664,6 @@
 Other,ផ្សេងទៀត,
 Other Reports,របាយការណ៍ផ្សេងទៀត,
 "Other outward supplies(Nil rated,Exempted)",ការផ្គត់ផ្គង់ខាងក្រៅផ្សេងទៀត (បានវាយតម្លៃមិនលើកលែង),
-Others,អ្នកផ្សេងទៀត,
 Out Qty,ចេញ Qty,
 Out Value,តម្លៃចេញ,
 Out of Order,ចេញពីលំដាប់,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),សរុប (ដោយគ្មានពន្ធ),
 Total Achieved,សរុបសម្រេច,
 Total Actual,សរុបជាក់ស្តែង,
-Total Allocated Leaves,ស្លឹកបម្រុងសរុប,
 Total Amount,ចំនួនសរុប,
 Total Amount Credited,ចំនួនទឹកប្រាក់សរុបដែលបានផ្ទៀងផ្ទាត់,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,ការចោទប្រកាន់អនុវត្តសរុបនៅក្នុងការទិញតារាងការទទួលធាតុត្រូវដូចគ្នាដែលជាពន្ធសរុបនិងការចោទប្រកាន់,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,ផ្ទុកឡើងក្បាលលិខិតនិងស្លាកសញ្ញារបស់អ្នក។ (អ្នកអាចកែសម្រួលពួកវានៅពេលក្រោយ) ។,
 Upper Income,ផ្នែកខាងលើប្រាក់ចំណូល,
 Use Sandbox,ប្រើសេនបក់,
-Used Leaves,ប្រើស្លឹក,
 User,អ្នកប្រើ,
 User ID,លេខសម្គាល់អ្នកប្រើ,
 User ID not set for Employee {0},លេខសម្គាល់អ្នកប្រើដែលមិនបានកំណត់សម្រាប់បុគ្គលិក {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),ការធានារយៈពេល (នៅក្នុងថ្ងៃ),
 Auto re-order,ការបញ្ជាទិញជាថ្មីម្តងទៀតដោយស្វ័យប្រវត្តិ,
 Reorder level based on Warehouse,កម្រិតនៃការរៀបចំដែលមានមូលដ្ឋានលើឃ្លាំង,
-Will also apply for variants unless overrridden,ក៏នឹងអនុវត្តសម្រាប់វ៉ារ្យ៉ង់បានទេលុះត្រាតែ overrridden,
+Will also apply for variants unless overridden,ក៏នឹងអនុវត្តសម្រាប់វ៉ារ្យ៉ង់បានទេលុះត្រាតែ overridden,
 Units of Measure,ឯកតារង្វាស់,
 Will also apply for variants,ក៏នឹងអនុវត្តសម្រាប់វ៉ារ្យ៉ង់,
 Serial Nos and Batches,សៀរៀល nos និងជំនាន់,
@@ -7949,12 +7944,10 @@
 Approvers,គួរឱ្យសង្ស័យ,
 The first Approver in the list will be set as the default Approver.,អ្នកផ្តល់យោបល់ដំបូងគេនៅក្នុងបញ្ជីនឹងត្រូវបានកំណត់ជាអ្នកផ្តល់យោបល់លំនាំដើម,
 Shift Request Approver,ផ្លាស់ប្តូរសំណើរសុំការផ្លាស់ប្តូរ,
-PAN Number,លេខ PAN,
 Provident Fund Account,គណនីមូលនិធិអ្នកផ្តល់សេវា,
 MICR Code,MICR កូដ,
 Repay unclaimed amount from salary,សងចំនួនទឹកប្រាក់ដែលមិនបានទាមទារពីប្រាក់ខែ,
 Deduction from salary,ការកាត់បន្ថយពីប្រាក់ខែ,
-Expired Leaves,ស្លឹកផុតកំណត់,
 If this is not checked the loan by default will be considered as a Demand Loan,ប្រសិនបើនេះមិនត្រូវបានពិនិត្យប្រាក់កម្ចីតាមលំនាំដើមនឹងត្រូវបានចាត់ទុកថាជាប្រាក់កម្ចីតម្រូវការ,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,គណនីនេះត្រូវបានប្រើសម្រាប់ការកក់ការសងប្រាក់កម្ចីពីអ្នកខ្ចីហើយថែមទាំងផ្តល់ប្រាក់កម្ចីដល់អ្នកខ្ចីផងដែរ,
 This account is capital account which is used to allocate capital for loan disbursal account ,គណនីនេះគឺជាគណនីដើមទុនដែលត្រូវបានប្រើដើម្បីបែងចែកដើមទុនសម្រាប់គណនីប្រាក់កម្ចី,
@@ -8748,3 +8741,5 @@
 Is Mandatory,គឺចាំបាច់,
 WhatsApp,WhatsApp,
 Make a call,ធ្វើការហៅ,
+Approve,អនុម័ត,
+Reject,ច្រានចោល,
diff --git a/erpnext/translations/kn.csv b/erpnext/translations/kn.csv
index 5b42113..7206671 100644
--- a/erpnext/translations/kn.csv
+++ b/erpnext/translations/kn.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,ಸ್ವಯಂ ಪುನರಾವರ್ತಿತ ಡಾಕ್ಯುಮೆಂಟ್ ಅನ್ನು ನವೀಕರಿಸಲಾಗಿದೆ,
 Automotive,ಆಟೋಮೋಟಿವ್,
 Available,ಲಭ್ಯ,
-Available Leaves,ಲಭ್ಯವಿರುವ ಎಲೆಗಳು,
 Available Qty,ಲಭ್ಯವಿರುವ ಪ್ರಮಾಣ,
 Available Selling,ಲಭ್ಯವಿರುವ ಮಾರಾಟ,
 Available for use date is required,ಬಳಕೆ ದಿನಾಂಕಕ್ಕೆ ಲಭ್ಯವಿದೆ,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,ಹಬ್ ಸಿಂಕ್ ID,
 Human Resource,ಮಾನವ ಸಂಪನ್ಮೂಲ,
 Human Resources,ಮಾನವ ಸಂಪನ್ಮೂಲ,
-IFSC Code,IFSC ಕೋಡ್,
 IGST Amount,IGST ಮೊತ್ತ,
 IP Address,IP ವಿಳಾಸ,
 ITC Available (whether in full op part),ಐಟಿಸಿ ಲಭ್ಯವಿದೆ (ಪೂರ್ಣ ಆಪ್ ಭಾಗದಲ್ಲಿರಲಿ),
@@ -1666,7 +1664,6 @@
 Other,ಇತರ,
 Other Reports,ಇತರ ವರದಿಗಳು,
 "Other outward supplies(Nil rated,Exempted)","ಇತರ ಬಾಹ್ಯ ಸರಬರಾಜುಗಳು (ನಿಲ್ ರೇಟ್, ವಿನಾಯಿತಿ)",
-Others,ಇತರೆ,
 Out Qty,ಪ್ರಮಾಣ ಔಟ್,
 Out Value,ಔಟ್ ಮೌಲ್ಯ,
 Out of Order,ಆದೇಶದ ಹೊರಗೆ,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),ಒಟ್ಟು (ತೆರಿಗೆ ಇಲ್ಲದೆ),
 Total Achieved,ಒಟ್ಟು ಸಾಧಿಸಿದ,
 Total Actual,ನಿಜವಾದ ಒಟ್ಟು,
-Total Allocated Leaves,ಒಟ್ಟು ಹಂಚಲ್ಪಟ್ಟ ಎಲೆಗಳು,
 Total Amount,ಒಟ್ಟು ಪ್ರಮಾಣ,
 Total Amount Credited,ಒಟ್ಟು ಮೊತ್ತವನ್ನು ಕ್ರೆಡಿಟ್ ಮಾಡಲಾಗಿದೆ,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,ಖರೀದಿ ರಸೀತಿ ವಸ್ತುಗಳು ಕೋಷ್ಟಕದಲ್ಲಿ ಒಟ್ಟು ಅನ್ವಯಿಸುವ ತೆರಿಗೆ ಒಟ್ಟು ತೆರಿಗೆಗಳು ಮತ್ತು ಶುಲ್ಕಗಳು ಅದೇ ಇರಬೇಕು,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,ನಿಮ್ಮ ಪತ್ರ ತಲೆ ಮತ್ತು ಲೋಗೋ ಅಪ್ಲೋಡ್. (ನೀವು ಅವುಗಳನ್ನು ನಂತರ ಸಂಪಾದಿಸಬಹುದು).,
 Upper Income,ಮೇಲ್ ವರಮಾನ,
 Use Sandbox,ಸ್ಯಾಂಡ್ಬಾಕ್ಸ್ ಬಳಸಿ,
-Used Leaves,ಉಪಯೋಗಿಸಿದ ಎಲೆಗಳು,
 User,ಬಳಕೆದಾರ,
 User ID,ಬಳಕೆದಾರ ID,
 User ID not set for Employee {0},ಬಳಕೆದಾರ ID ನೌಕರ ಸೆಟ್ {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),( ದಿನಗಳಲ್ಲಿ ) ಖಾತರಿ ಅವಧಿಯ,
 Auto re-order,ಆಟೋ ಪುನಃ ಸಲುವಾಗಿ,
 Reorder level based on Warehouse,ವೇರ್ಹೌಸ್ ಆಧರಿಸಿ ಮರುಕ್ರಮಗೊಳಿಸಿ ಮಟ್ಟದ,
-Will also apply for variants unless overrridden,Overrridden ಹೊರತು ಸಹ ರೂಪಾಂತರಗಳು ಅನ್ವಯವಾಗುವುದು,
+Will also apply for variants unless overridden,Overrridden ಹೊರತು ಸಹ ರೂಪಾಂತರಗಳು ಅನ್ವಯವಾಗುವುದು,
 Units of Measure,ಮಾಪನದ ಘಟಕಗಳಿಗೆ,
 Will also apply for variants,ಸಹ ರೂಪಾಂತರಗಳು ಅನ್ವಯವಾಗುವುದು,
 Serial Nos and Batches,ಸೀರಿಯಲ್ ಸೂಲ ಮತ್ತು ಬ್ಯಾಚ್,
@@ -7949,12 +7944,10 @@
 Approvers,ಅನುಮೋದಕರು,
 The first Approver in the list will be set as the default Approver.,ಪಟ್ಟಿಯಲ್ಲಿನ ಮೊದಲ ಅನುಮೋದಕವನ್ನು ಡೀಫಾಲ್ಟ್ ಅನುಮೋದಕ ಎಂದು ಹೊಂದಿಸಲಾಗುವುದು.,
 Shift Request Approver,ಶಿಫ್ಟ್ ವಿನಂತಿ ಅನುಮೋದನೆ,
-PAN Number,ಪ್ಯಾನ್ ಸಂಖ್ಯೆ,
 Provident Fund Account,ಭವಿಷ್ಯ ನಿಧಿ ಖಾತೆ,
 MICR Code,MICR ಕೋಡ್,
 Repay unclaimed amount from salary,ಹಕ್ಕು ಪಡೆಯದ ಮೊತ್ತವನ್ನು ಸಂಬಳದಿಂದ ಮರುಪಾವತಿ ಮಾಡಿ,
 Deduction from salary,ಸಂಬಳದಿಂದ ಕಡಿತ,
-Expired Leaves,ಅವಧಿ ಮುಗಿದ ಎಲೆಗಳು,
 If this is not checked the loan by default will be considered as a Demand Loan,ಇದನ್ನು ಪರಿಶೀಲಿಸದಿದ್ದರೆ ಸಾಲವನ್ನು ಪೂರ್ವನಿಯೋಜಿತವಾಗಿ ಬೇಡಿಕೆ ಸಾಲವೆಂದು ಪರಿಗಣಿಸಲಾಗುತ್ತದೆ,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,ಈ ಖಾತೆಯನ್ನು ಸಾಲಗಾರರಿಂದ ಸಾಲ ಮರುಪಾವತಿಯನ್ನು ಕಾಯ್ದಿರಿಸಲು ಮತ್ತು ಸಾಲಗಾರನಿಗೆ ಸಾಲವನ್ನು ವಿತರಿಸಲು ಬಳಸಲಾಗುತ್ತದೆ,
 This account is capital account which is used to allocate capital for loan disbursal account ,"ಈ ಖಾತೆಯು ಬಂಡವಾಳ ಖಾತೆಯಾಗಿದ್ದು, ಸಾಲ ವಿತರಣಾ ಖಾತೆಗೆ ಬಂಡವಾಳವನ್ನು ನಿಯೋಜಿಸಲು ಬಳಸಲಾಗುತ್ತದೆ",
@@ -8748,3 +8741,5 @@
 Is Mandatory,ಕಡ್ಡಾಯವಾಗಿದೆ,
 WhatsApp,ವಾಟ್ಸಾಪ್,
 Make a call,ಕರೆ ಮಾಡಿ,
+Approve,ಅನುಮೋದಿಸಿ,
+Reject,ರಿಜೆಕ್ಟ್,
diff --git a/erpnext/translations/ko.csv b/erpnext/translations/ko.csv
index 48a3e0c..9911925 100644
--- a/erpnext/translations/ko.csv
+++ b/erpnext/translations/ko.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,자동 반복 문서 업데이트 됨,
 Automotive,자동차,
 Available,사용 가능함,
-Available Leaves,사용 가능한 잎,
 Available Qty,사용 가능한 수량,
 Available Selling,판매 가능,
 Available for use date is required,사용 가능한 날짜가 필요합니다.,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,허브 동기화 ID,
 Human Resource,인적 자원,
 Human Resources,인적 자원,
-IFSC Code,IFSC 코드,
 IGST Amount,IGST 금액,
 IP Address,IP 주소,
 ITC Available (whether in full op part),ITC 가능 (전체 운영 부분 포함),
@@ -1666,7 +1664,6 @@
 Other,기타,
 Other Reports,기타 보고서,
 "Other outward supplies(Nil rated,Exempted)","기타 외부 공급 (Nil rated, Exempted)",
-Others,기타사항,
 Out Qty,수량 아웃,
 Out Value,제한 값,
 Out of Order,고장난,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),합계 (세금 제외),
 Total Achieved,전체 달성,
 Total Actual,실제 총,
-Total Allocated Leaves,총 할당 된 잎,
 Total Amount,총액,
 Total Amount Credited,총 크레딧 금액,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,구매 영수증 항목 테이블에 전체 적용 요금은 총 세금 및 요금과 동일해야합니다,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,편지의 머리와 로고를 업로드합니다. (나중에 편집 할 수 있습니다).,
 Upper Income,위 소득,
 Use Sandbox,사용 샌드 박스,
-Used Leaves,중고 잎,
 User,사용자,
 User ID,사용자 ID,
 User ID not set for Employee {0},사용자 ID 직원에 대한 설정하지 {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),(일) 보증 기간,
 Auto re-order,자동 재 주문,
 Reorder level based on Warehouse,웨어 하우스를 기반으로 재정렬 수준,
-Will also apply for variants unless overrridden,overrridden가 아니면 변형 적용됩니다,
+Will also apply for variants unless overridden,overridden가 아니면 변형 적용됩니다,
 Units of Measure,측정 단위,
 Will also apply for variants,또한 변형 적용됩니다,
 Serial Nos and Batches,일련 번호 및 배치,
@@ -7949,12 +7944,10 @@
 Approvers,승인자,
 The first Approver in the list will be set as the default Approver.,목록의 첫 번째 승인자가 기본 승인자로 설정됩니다.,
 Shift Request Approver,교대 요청 승인자,
-PAN Number,PAN 번호,
 Provident Fund Account,프로 비 던트 펀드 계정,
 MICR Code,MICR 코드,
 Repay unclaimed amount from salary,급여에서 미 청구 금액 상환,
 Deduction from salary,급여에서 공제,
-Expired Leaves,만료 된 잎,
 If this is not checked the loan by default will be considered as a Demand Loan,선택하지 않으면 기본적으로 대출이 수요 대출로 간주됩니다.,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,이 계정은 차용인의 대출 상환을 예약하고 차용인에게 대출금을 지급하는 데 사용됩니다.,
 This account is capital account which is used to allocate capital for loan disbursal account ,이 계정은 대출 지급 계정에 자본을 할당하는 데 사용되는 자본 계정입니다.,
@@ -8748,3 +8741,5 @@
 Is Mandatory,필수,
 WhatsApp,WhatsApp,
 Make a call,전화하다,
+Approve,승인,
+Reject,받지 않다,
diff --git a/erpnext/translations/ku.csv b/erpnext/translations/ku.csv
index f1972e8..8fec059 100644
--- a/erpnext/translations/ku.csv
+++ b/erpnext/translations/ku.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Vebijêrkek belgekirinê nûve bike,
 Automotive,Automotive,
 Available,Berdeste,
-Available Leaves,Leaves Available,
 Available Qty,Available Qty,
 Available Selling,Bazirganiya Bazirganî,
 Available for use date is required,Ji bo karanîna karanîna pêdivî ye,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Nasnameya Hub Sync,
 Human Resource,çavkaniyê binirxîne mirovan,
 Human Resources,Çavkaniyên Mirovî,
-IFSC Code,Kodê IFSC,
 IGST Amount,Amûr IGST,
 IP Address,Navnîşana IP&#39;yê,
 ITC Available (whether in full op part),Danûstandinên ITC (gelo di beşa tevahiya opoyê de),
@@ -1666,7 +1664,6 @@
 Other,Yên din,
 Other Reports,din Reports,
 "Other outward supplies(Nil rated,Exempted)","Materyalên din ên derveyî (Nil nirxandin, Pezakirin)",
-Others,yên din,
 Out Qty,out Qty,
 Out Value,Nirx out,
 Out of Order,Xirab,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Tiştek Bacê,
 Total Achieved,Total nebine,
 Total Actual,Total Actual,
-Total Allocated Leaves,Niştecîhên Teva Allocated,
 Total Amount,Temamê meblaxa,
 Total Amount Credited,Jimareya Giştî ya Credited,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,"Total doz li wergirtinê li Purchase Nawy Meqbûz sifrê divê eynî wek Total Bac, û doz li be",
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Upload nameya serokê û logo xwe. (Tu ji wan paşê biguherîne).,
 Upper Income,Dahata Upper,
 Use Sandbox,bikaranîna Ceriban,
-Used Leaves,Leaves Used,
 User,Bikaranîvan,
 User ID,ID&#39;ya bikarhêner,
 User ID not set for Employee {0},ID&#39;ya bikarhêner ji bo karkirinê set ne {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Period Warranty (di rojên),
 Auto re-order,Auto re-da,
 Reorder level based on Warehouse,asta DIRTYHERTZ li ser Warehouse,
-Will also apply for variants unless overrridden,jî wê ji bo Guhertoyên serî heta overrridden,
+Will also apply for variants unless overridden,jî wê ji bo Guhertoyên serî heta overridden,
 Units of Measure,Yekîneyên Measure,
 Will also apply for variants,jî wê ji bo Guhertoyên serî,
 Serial Nos and Batches,Serial Nos û lekerên,
@@ -7949,12 +7944,10 @@
 Approvers,Têgihiştin,
 The first Approver in the list will be set as the default Approver.,Di lîsteyê de Pejirandina yekem dê wekî Destûra Pêşniyar were saz kirin.,
 Shift Request Approver,Pejirandina Daxwaza Guherînê,
-PAN Number,Hejmara PAN,
 Provident Fund Account,Hesabê Fona Pêşbîn,
 MICR Code,MICR Code,
 Repay unclaimed amount from salary,Mûçeya nevekirî ji meaşê paşde bidin,
 Deduction from salary,Daxistina ji meaş,
-Expired Leaves,Pelên Dawî,
 If this is not checked the loan by default will be considered as a Demand Loan,Ger ev neyê kontrol kirin dê deyn bi default dê wekî Krediyek Daxwaz were hesibandin,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Ev hesab ji bo veqetandina vegerandinên deyn ji deyndêr û her weha dayîna deyn ji deyndêr re tê bikar anîn,
 This account is capital account which is used to allocate capital for loan disbursal account ,Ev hesab hesabê sermiyan e ku ji bo veqetandina sermaye ji bo hesabê dayîna kredî tê bikar anîn,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Erkdar e,
 WhatsApp,WhatsApp,
 Make a call,Bang bikin,
+Approve,Destûrdan,
+Reject,Refzkirin,
diff --git a/erpnext/translations/lo.csv b/erpnext/translations/lo.csv
index cdb6f66..0831788 100644
--- a/erpnext/translations/lo.csv
+++ b/erpnext/translations/lo.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,ການປັບປຸງເອກະສານຊ້ໍາອັດຕະໂນມັດ,
 Automotive,ຍານຍົນ,
 Available,ສາມາດໃຊ້ໄດ້,
-Available Leaves,Available Leaves,
 Available Qty,ມີຈໍານວນ,
 Available Selling,Available Selling,
 Available for use date is required,ຕ້ອງມີວັນທີ່ໃຊ້ສໍາລັບການນໍາໃຊ້,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub Sync ID,
 Human Resource,ຊັບພະຍາກອນມະນຸດ,
 Human Resources,ຊັບພະຍາກອນມະນຸດ,
-IFSC Code,IFSC Code,
 IGST Amount,IGST Amount,
 IP Address,ທີ່ຢູ່ IP,
 ITC Available (whether in full op part),ມີ ITC (ບໍ່ວ່າຈະຢູ່ໃນສ່ວນເຕັມ),
@@ -1666,7 +1664,6 @@
 Other,ອື່ນ ໆ,
 Other Reports,ບົດລາຍງານອື່ນ ໆ,
 "Other outward supplies(Nil rated,Exempted)","ເຄື່ອງໃຊ້ພາຍນອກອື່ນໆ (ອັນດັບ, ຍົກເວັ້ນ)",
-Others,ຄົນອື່ນ,
 Out Qty,ອອກຈໍານວນ,
 Out Value,ມູນຄ່າອອກ,
 Out of Order,ອອກຈາກຄໍາສັ່ງ,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),ລວມ (ໂດຍບໍ່ມີພາສີ),
 Total Achieved,ທັງຫມົດບັນລຸ,
 Total Actual,ທັງຫມົດທີ່ເກີດຂຶ້ນຈິງ,
-Total Allocated Leaves,ຈໍານວນໃບທີ່ຖືກມອບຫມາຍ,
 Total Amount,ຈໍານວນທັງຫມົດ,
 Total Amount Credited,ຈໍານວນເງິນທີ່ໄດ້ຮັບການຢັ້ງຢືນ,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,ຄ່າໃຊ້ຈ່າຍທັງຫມົດໃນການຊື້ຕາຕະລາງໃບລາຍການຈະຕ້ອງເຊັ່ນດຽວກັນກັບພາສີອາກອນທັງຫມົດແລະຄ່າບໍລິການ,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,ອັບຫົວຈົດຫມາຍສະບັບແລະສັນຍາລັກຂອງທ່ານ. (ທ່ານສາມາດແກ້ໄຂໃຫ້ເຂົາເຈົ້າຕໍ່ມາ).,
 Upper Income,Upper ລາຍໄດ້,
 Use Sandbox,ການນໍາໃຊ້ Sandbox,
-Used Leaves,Used Leaves,
 User,ຜູ້ໃຊ້,
 User ID,User ID,
 User ID not set for Employee {0},User ID ບໍ່ກໍານົດສໍາລັບພະນັກງານ {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),ໄລຍະເວລາຮັບປະກັນ (ໃນວັນເວລາ),
 Auto re-order,Auto Re: ຄໍາສັ່ງ,
 Reorder level based on Warehouse,ລະດັບລໍາດັບຂຶ້ນຢູ່ກັບຄັງສິນຄ້າ,
-Will also apply for variants unless overrridden,ຍັງຈະນໍາໃຊ້ສໍາລັບການ variants ເວັ້ນເສຍແຕ່ວ່າ overrridden,
+Will also apply for variants unless overridden,ຍັງຈະນໍາໃຊ້ສໍາລັບການ variants ເວັ້ນເສຍແຕ່ວ່າ overridden,
 Units of Measure,ຫົວຫນ່ວຍວັດແທກ,
 Will also apply for variants,ຍັງຈະນໍາໃຊ້ສໍາລັບການ variants,
 Serial Nos and Batches,Serial Nos ແລະສໍາຫລັບຂະບວນ,
@@ -7949,12 +7944,10 @@
 Approvers,ຄວາມເປັນຫ່ວງ,
 The first Approver in the list will be set as the default Approver.,The Approver ຄັ້ງ ທຳ ອິດໃນລາຍຊື່ຈະຖືກຕັ້ງເປັນຄ່າເລີ່ມຕົ້ນຂອງ Approver.,
 Shift Request Approver,ການຂໍວິທີການປ່ຽນ,
-PAN Number,ເລກ PAN,
 Provident Fund Account,ບັນຊີກອງທຶນຜູ້ໃຫ້ບໍລິການ,
 MICR Code,ລະຫັດ MICR,
 Repay unclaimed amount from salary,ຈ່າຍຄືນ ຈຳ ນວນທີ່ບໍ່ໄດ້ຮັບຈາກເງິນເດືອນ,
 Deduction from salary,ການຫັກລົບຈາກເງິນເດືອນ,
-Expired Leaves,ໃບ ໝົດ ອາຍຸ,
 If this is not checked the loan by default will be considered as a Demand Loan,ຖ້າສິ່ງນີ້ບໍ່ຖືກກວດກາເງິນກູ້ໂດຍຄ່າເລີ່ມຕົ້ນຈະຖືກພິຈາລະນາເປັນເງິນກູ້ຕາມຄວາມຕ້ອງການ,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,ບັນຊີນີ້ໃຊ້ເພື່ອຈອງການຈ່າຍຄືນເງິນກູ້ຈາກຜູ້ກູ້ຢືມແລະຍັງຈ່າຍເງິນກູ້ໃຫ້ຜູ້ກູ້ຢືມອີກດ້ວຍ,
 This account is capital account which is used to allocate capital for loan disbursal account ,ບັນຊີນີ້ແມ່ນບັນຊີທຶນເຊິ່ງຖືກ ນຳ ໃຊ້ເພື່ອຈັດສັນທຶນ ສຳ ລັບບັນຊີການເບີກຈ່າຍເງິນກູ້,
@@ -8748,3 +8741,5 @@
 Is Mandatory,ແມ່ນບັງຄັບ,
 WhatsApp,WhatsApp,
 Make a call,ໂທອອກ,
+Approve,ອະນຸມັດ,
+Reject,ປະຕິເສດ,
diff --git a/erpnext/translations/lt.csv b/erpnext/translations/lt.csv
index 44bd069..8215275 100644
--- a/erpnext/translations/lt.csv
+++ b/erpnext/translations/lt.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Auto pakartotinis dokumentas atnaujintas,
 Automotive,Automobiliai,
 Available,pasiekiamas,
-Available Leaves,Galimos lapai,
 Available Qty,Turimas Kiekis,
 Available Selling,Galima parduoti,
 Available for use date is required,Reikia naudoti datą,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub Sync ID,
 Human Resource,Žmogiškasis išteklis,
 Human Resources,Žmogiškieji ištekliai,
-IFSC Code,IFSC kodas,
 IGST Amount,IGST suma,
 IP Address,IP adresas,
 ITC Available (whether in full op part),ITC yra prieinamas (ar visa jo dalis),
@@ -1666,7 +1664,6 @@
 Other,kitas,
 Other Reports,Kiti pranešimai,
 "Other outward supplies(Nil rated,Exempted)","Kiti išoriniai reikmenys (nulinis, neapmokestinamas)",
-Others,Kiti,
 Out Qty,iš Kiekis,
 Out Value,iš Vertė,
 Out of Order,Neveikia,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Iš viso (be mokesčio),
 Total Achieved,Iš viso Pasiektas,
 Total Actual,Iš viso Tikrasis,
-Total Allocated Leaves,Iš viso paskirstytų lapų,
 Total Amount,Visas kiekis,
 Total Amount Credited,Iš viso kredituota suma,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Iš viso taikomi mokesčiai į pirkimo kvito sumų lentelė turi būti tokios pačios kaip viso mokesčių ir rinkliavų,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Įkelti savo laiške galvą ir logotipą. (Galite redaguoti juos vėliau).,
 Upper Income,viršutinė pajamos,
 Use Sandbox,Naudokite Smėlio,
-Used Leaves,Naudotos lapai,
 User,Vartotojas,
 User ID,Vartotojo ID,
 User ID not set for Employee {0},Vartotojo ID nenustatyti Darbuotojo {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Garantinis laikotarpis (dienomis),
 Auto re-order,Auto naujo užsakymas,
 Reorder level based on Warehouse,Pertvarkyti lygį remiantis Warehouse,
-Will also apply for variants unless overrridden,Bus taikoma variantų nebent overrridden,
+Will also apply for variants unless overridden,Bus taikoma variantų nebent overridden,
 Units of Measure,Matavimo vienetai,
 Will also apply for variants,Bus taikoma variantų,
 Serial Nos and Batches,Eilės Nr ir Partijos,
@@ -7949,12 +7944,10 @@
 Approvers,Patvirtina,
 The first Approver in the list will be set as the default Approver.,Pirmasis patvirtintojas sąraše bus nustatytas kaip numatytasis patvirtintojas.,
 Shift Request Approver,„Shift Request Approver“,
-PAN Number,PAN numeris,
 Provident Fund Account,„Provident Fund“ sąskaita,
 MICR Code,MICR kodas,
 Repay unclaimed amount from salary,Iš atlyginimo grąžinkite neprašytą sumą,
 Deduction from salary,Išskaičiavimas iš atlyginimo,
-Expired Leaves,Pasibaigę lapai,
 If this is not checked the loan by default will be considered as a Demand Loan,"Jei tai nėra pažymėta, paskola pagal numatytuosius nustatymus bus laikoma paklausos paskola",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Ši sąskaita naudojama paskolos grąžinimo iš skolininko rezervavimui ir paskolos paskolos gavėjui išmokėjimui,
 This account is capital account which is used to allocate capital for loan disbursal account ,"Ši sąskaita yra kapitalo sąskaita, naudojama paskirstyti kapitalą paskolos išmokėjimo sąskaitai",
@@ -8748,3 +8741,5 @@
 Is Mandatory,Yra privaloma,
 WhatsApp,„WhatsApp“,
 Make a call,Paskambinti,
+Approve,Patvirtinti,
+Reject,Atmesti,
diff --git a/erpnext/translations/lv.csv b/erpnext/translations/lv.csv
index 131f94a..8c4526c 100644
--- a/erpnext/translations/lv.csv
+++ b/erpnext/translations/lv.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Auto atkārtots dokuments ir atjaunināts,
 Automotive,Automobiļu,
 Available,Pieejams,
-Available Leaves,Pieejamie lapas,
 Available Qty,Pieejams Daudz,
 Available Selling,Pieejams pārdošana,
 Available for use date is required,Pieejams izmantošanas datums ir nepieciešams,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub Sync ID,
 Human Resource,Cilvēkresursi,
 Human Resources,Cilvēkresursi,
-IFSC Code,IFSC kods,
 IGST Amount,IGST summa,
 IP Address,IP adrese,
 ITC Available (whether in full op part),Pieejams ITC (vai nu pilnā variantā),
@@ -1666,7 +1664,6 @@
 Other,Cits,
 Other Reports,citas Ziņojumi,
 "Other outward supplies(Nil rated,Exempted)","Citi izejmateriāli (bez nulles, ar atbrīvojumu)",
-Others,Pārējie,
 Out Qty,Out Daudz,
 Out Value,out Value,
 Out of Order,Nestrādā,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Kopā (bez nodokļiem),
 Total Achieved,Kopā Izpildīts,
 Total Actual,Kopā Faktiskais,
-Total Allocated Leaves,Kopējais izdalīto lapu skaits,
 Total Amount,Kopējā summa,
 Total Amount Credited,Kopējā kredīta summa,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,"Kopā piemērojamām izmaksām, kas pirkuma čeka Items galda jābūt tāds pats kā Kopā nodokļiem un nodevām",
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Augšupielādēt jūsu vēstules galva un logo. (Jūs varat rediģēt tos vēlāk).,
 Upper Income,Upper Ienākumi,
 Use Sandbox,Izmantot Sandbox,
-Used Leaves,Izmantotās lapas,
 User,Lietotājs,
 User ID,Lietotāja ID,
 User ID not set for Employee {0},"Lietotāja ID nav noteikts, Darbinieka {0}",
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Garantijas periods (dienās),
 Auto re-order,Auto re-pasūtīt,
 Reorder level based on Warehouse,Pārkārtot līmenis balstās uz Noliktava,
-Will also apply for variants unless overrridden,"Attieksies arī uz variantiem, ja vien overrridden",
+Will also apply for variants unless overridden,"Attieksies arī uz variantiem, ja vien overridden",
 Units of Measure,Mērvienību,
 Will also apply for variants,Attieksies arī uz variantiem,
 Serial Nos and Batches,Sērijas Nr un Partijām,
@@ -7949,12 +7944,10 @@
 Approvers,Apstiprinātāji,
 The first Approver in the list will be set as the default Approver.,Pirmais apstiprinātājs sarakstā tiks iestatīts kā noklusējuma apstiprinātājs.,
 Shift Request Approver,Maiņas pieprasījuma apstiprinātājs,
-PAN Number,PAN numurs,
 Provident Fund Account,Provident Fund konts,
 MICR Code,MICR kods,
 Repay unclaimed amount from salary,Atmaksājiet nepieprasīto summu no algas,
 Deduction from salary,Atskaitīšana no algas,
-Expired Leaves,"Lapas, kurām beidzies derīguma termiņš",
 If this is not checked the loan by default will be considered as a Demand Loan,"Ja tas nav pārbaudīts, aizdevums pēc noklusējuma tiks uzskatīts par Pieprasījuma aizdevumu",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,"Šis konts tiek izmantots, lai rezervētu aizdevuma atmaksu no aizņēmēja un arī aizdevuma izmaksu aizņēmējam",
 This account is capital account which is used to allocate capital for loan disbursal account ,"Šis konts ir kapitāla konts, ko izmanto, lai piešķirtu kapitālu aizdevuma izmaksas kontam",
@@ -8748,3 +8741,5 @@
 Is Mandatory,Ir obligāta,
 WhatsApp,WhatsApp,
 Make a call,Piezvanīt,
+Approve,Apstiprināt,
+Reject,Noraidīt,
diff --git a/erpnext/translations/mk.csv b/erpnext/translations/mk.csv
index 1084b12..a622524 100644
--- a/erpnext/translations/mk.csv
+++ b/erpnext/translations/mk.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Автоматско повторување на документот се ажурира,
 Automotive,Автомобилски,
 Available,Достапни,
-Available Leaves,Достапни листови,
 Available Qty,На располагање Количина,
 Available Selling,Достапно Продажба,
 Available for use date is required,Достапен е датум за користење,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub Sync ID,
 Human Resource,Човечки ресурси,
 Human Resources,Човечки ресурси,
-IFSC Code,IFSC код,
 IGST Amount,Износ на IGST,
 IP Address,IP адреса,
 ITC Available (whether in full op part),ИТЦ достапен (без разлика дали е во целост опција),
@@ -1666,7 +1664,6 @@
 Other,Други,
 Other Reports,Други извештаи,
 "Other outward supplies(Nil rated,Exempted)","Други надворешни материјали (нула со оценка, Ослободена)",
-Others,"Други, пак,",
 Out Qty,Од Количина,
 Out Value,Од вредност,
 Out of Order,Надвор од нарачката,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Вкупно (без данок),
 Total Achieved,Вкупно Постигнати,
 Total Actual,Вкупно Крај,
-Total Allocated Leaves,Вкупно распределени листови,
 Total Amount,Вкупен износ,
 Total Amount Credited,Вкупен износ на кредит,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Вкупно применливи давачки во Набавка Потврда Предмети маса мора да биде иста како и вкупните даноци и давачки,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Внеси писмо главата и логото. (Можете да ги менувате подоцна).,
 Upper Income,Горниот дел од приходите,
 Use Sandbox,Користете Sandbox,
-Used Leaves,Користени листови,
 User,Корисник,
 User ID,ID на корисникот,
 User ID not set for Employee {0},ID на корисникот не е поставена за вработените {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Гарантниот период (во денови),
 Auto re-order,Автоматско повторно цел,
 Reorder level based on Warehouse,Ниво врз основа на промените редоследот Магацински,
-Will also apply for variants unless overrridden,"Ќе се казни и варијанти, освен ако overrridden",
+Will also apply for variants unless overridden,"Ќе се казни и варијанти, освен ако overridden",
 Units of Measure,На мерните единици,
 Will also apply for variants,Ќе се применуваат и за варијанти,
 Serial Nos and Batches,Сериски броеви и Пакетите,
@@ -7949,12 +7944,10 @@
 Approvers,Аверверзно,
 The first Approver in the list will be set as the default Approver.,Првиот Одобрувач во списокот ќе биде поставен како стандарден Одобрувач.,
 Shift Request Approver,Одобрувач на барање за смена,
-PAN Number,Број на ПАН,
 Provident Fund Account,Сметка на фондот за провиденција,
 MICR Code,МИКР-код,
 Repay unclaimed amount from salary,Отплати небаран износ од плата,
 Deduction from salary,Намалување од плата,
-Expired Leaves,Истечени лисја,
 If this is not checked the loan by default will be considered as a Demand Loan,"Доколку ова не е проверено, заемот по дифолт ќе се смета како заем за побарувачка",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Оваа сметка се користи за резервирање на отплати на заеми од заемопримачот и исто така за исплата на заеми на заемопримачот,
 This account is capital account which is used to allocate capital for loan disbursal account ,Оваа сметка е капитална сметка што се користи за алокација на капитал за сметка за исплата на заем,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Задолжително е,
 WhatsApp,WhatsApp,
 Make a call,Направи повик,
+Approve,Одобри,
+Reject,Reject,
diff --git a/erpnext/translations/ml.csv b/erpnext/translations/ml.csv
index 2ddec21..777d5c6 100644
--- a/erpnext/translations/ml.csv
+++ b/erpnext/translations/ml.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,സ്വയം ആവർത്തന പ്രമാണം അപ്ഡേറ്റുചെയ്തു,
 Automotive,ഓട്ടോമോട്ടീവ്,
 Available,ലഭ്യമായ,
-Available Leaves,ലഭ്യമായ ഇലകൾ,
 Available Qty,ലഭ്യമായ Qty,
 Available Selling,വിൽക്കൽ ലഭ്യമാണ്,
 Available for use date is required,ഉപയോഗ തീയതിക്ക് ആവശ്യമാണ്,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,ഹബ് സമന്വയ ID,
 Human Resource,മാനവ വിഭവശേഷി,
 Human Resources,ഹ്യൂമൻ റിസോഴ്സസ്,
-IFSC Code,IFSC കോഡ്,
 IGST Amount,IGST തുക,
 IP Address,IP വിലാസം,
 ITC Available (whether in full op part),ഐടിസി ലഭ്യമാണ് (പൂർണ്ണമായ ഭാഗമാണെങ്കിലും),
@@ -1666,7 +1664,6 @@
 Other,മറ്റുള്ളവ,
 Other Reports,മറ്റ് റിപ്പോർട്ടുകളിൽ,
 "Other outward supplies(Nil rated,Exempted)","മറ്റ് ബാഹ്യ വിതരണങ്ങൾ (ഇല്ല റേറ്റുചെയ്തു, ഒഴിവാക്കി)",
-Others,മറ്റുള്ളവ,
 Out Qty,Qty ഔട്ട്,
 Out Value,മൂല്യം ഔട്ട്,
 Out of Order,പ്രവർത്തനരഹിതം,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),ആകെ (നികുതി കൂടാതെ),
 Total Achieved,മികച്ച വിജയം ആകെ,
 Total Actual,യഥാർത്ഥ ആകെ,
-Total Allocated Leaves,ആകെ അനുവദിച്ച ഇലകൾ,
 Total Amount,മൊത്തം തുക,
 Total Amount Credited,മൊത്തം തുക ലഭിച്ചു,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,വാങ്ങൽ രസീത് ഇനങ്ങൾ പട്ടികയിൽ ആകെ ബാധകമായ നിരക്കുകളും ആകെ നികുതി ചാർജുകളും തുല്യമായിരിക്കണം,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,നിങ്ങളുടെ കത്ത് തലയും ലോഗോ അപ്ലോഡ്. (നിങ്ങൾക്ക് പിന്നീട് എഡിറ്റ് ചെയ്യാൻ കഴിയും).,
 Upper Income,അപ്പർ ആദായ,
 Use Sandbox,താങ്കളെ,
-Used Leaves,ഉപയോഗിച്ച ഇലകൾ,
 User,ഉപയോക്താവ്,
 User ID,യൂസർ ഐഡി,
 User ID not set for Employee {0},ഉപയോക്തൃ ഐഡി ജീവനക്കാരുടെ {0} വെച്ചിരിക്കുന്നു അല്ല,
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),(ദിവസങ്ങളിൽ) വാറന്റി കാലാവധി,
 Auto re-order,ഓട്ടോ റീ-ഓർഡർ,
 Reorder level based on Warehouse,വെയർഹൗസ് അടിസ്ഥാനമാക്കിയുള്ള പുനഃക്രമീകരിക്കുക തലത്തിൽ,
-Will also apply for variants unless overrridden,കൂടാതെ overrridden അവയൊഴിച്ച് മോഡലുകൾക്കാണ് ബാധകമാകും,
+Will also apply for variants unless overridden,കൂടാതെ overridden അവയൊഴിച്ച് മോഡലുകൾക്കാണ് ബാധകമാകും,
 Units of Measure,അളവിന്റെ യൂണിറ്റുകൾ,
 Will also apply for variants,കൂടാതെ മോഡലുകൾക്കാണ് ബാധകമാകും,
 Serial Nos and Batches,സീരിയൽ എണ്ണം ബാച്ചുകളും,
@@ -7949,12 +7944,10 @@
 Approvers,അംഗങ്ങൾ,
 The first Approver in the list will be set as the default Approver.,ലിസ്റ്റിലെ ആദ്യ അംഗീകാരം സ്ഥിരസ്ഥിതി അംഗീകാരമായി സജ്ജമാക്കും.,
 Shift Request Approver,ഷിഫ്റ്റ് അഭ്യർത്ഥന അംഗീകാരം,
-PAN Number,പാൻ നമ്പർ,
 Provident Fund Account,പ്രൊവിഡന്റ് ഫണ്ട് അക്കൗണ്ട്,
 MICR Code,MICR കോഡ്,
 Repay unclaimed amount from salary,ക്ലെയിം ചെയ്യാത്ത തുക ശമ്പളത്തിൽ നിന്ന് തിരിച്ചടയ്ക്കുക,
 Deduction from salary,ശമ്പളത്തിൽ നിന്ന് കിഴിവ്,
-Expired Leaves,കാലഹരണപ്പെട്ട ഇലകൾ,
 If this is not checked the loan by default will be considered as a Demand Loan,ഇത് പരിശോധിച്ചില്ലെങ്കിൽ സ്ഥിരസ്ഥിതിയായി വായ്പ ഒരു ഡിമാൻഡ് വായ്പയായി കണക്കാക്കും,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,വായ്പക്കാരനിൽ നിന്ന് വായ്പ തിരിച്ചടവ് ബുക്ക് ചെയ്യുന്നതിനും വായ്പക്കാരന് വായ്പ വിതരണം ചെയ്യുന്നതിനും ഈ അക്കൗണ്ട് ഉപയോഗിക്കുന്നു,
 This account is capital account which is used to allocate capital for loan disbursal account ,വായ്പാ വിതരണ അക്കൗണ്ടിനായി മൂലധനം അനുവദിക്കുന്നതിന് ഉപയോഗിക്കുന്ന മൂലധന അക്കൗണ്ടാണ് ഈ അക്കൗണ്ട്,
@@ -8748,3 +8741,5 @@
 Is Mandatory,നിർബന്ധമാണ്,
 WhatsApp,വാട്ട്‌സ്ആപ്പ്,
 Make a call,ഒരു കാൾ ചെയ്യുക,
+Approve,അംഗീകരിക്കുക,
+Reject,നിരസിക്കുക,
diff --git a/erpnext/translations/mr.csv b/erpnext/translations/mr.csv
index 4206335..624f1ab 100644
--- a/erpnext/translations/mr.csv
+++ b/erpnext/translations/mr.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,स्वयं पुनरावृत्ती कागदजत्र अद्यतनित केले,
 Automotive,ऑटोमोटिव्ह,
 Available,उपलब्ध,
-Available Leaves,उपलब्ध पाने,
 Available Qty,उपलब्ध Qty,
 Available Selling,उपलब्ध विक्री,
 Available for use date is required,वापरण्याच्या तारखेसाठी उपलब्ध असणे आवश्यक आहे,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,हब सिंक ID,
 Human Resource,मानव संसाधन,
 Human Resources,मानव संसाधन,
-IFSC Code,आयएफएससी कोड,
 IGST Amount,आयजीएसटी रक्कम,
 IP Address,IP पत्ता,
 ITC Available (whether in full op part),आयटीसी उपलब्ध (पूर्ण ऑप भागातील आहे की नाही),
@@ -1666,7 +1664,6 @@
 Other,इतर,
 Other Reports,इतर अहवाल,
 "Other outward supplies(Nil rated,Exempted)","इतर बाह्य पुरवठा (शून्य रेट नाही, सूट दिलेला)",
-Others,इतर,
 Out Qty,आउट Qty,
 Out Value,मूल्य Qty,
 Out of Order,नियमबाह्य,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),एकूण (कर न करता),
 Total Achieved,एकूण गाठले,
 Total Actual,वास्तविक एकूण,
-Total Allocated Leaves,एकूण वाटप पाने,
 Total Amount,एकूण रक्कम,
 Total Amount Credited,एकूण रक्कम श्रेय,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,खरेदी पावती आयटम टेबल एकूण लागू शुल्क एकूण कर आणि शुल्क म्हणून समान असणे आवश्यक आहे,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,आपले पत्र डोके आणि लोगो अपलोड करा. (आपण नंतर संपादित करू शकता).,
 Upper Income,उच्च उत्पन्न,
 Use Sandbox,Sandbox वापर,
-Used Leaves,वापरले पाने,
 User,वापरकर्ता,
 User ID,वापरकर्ता आयडी,
 User ID not set for Employee {0},वापरकर्ता आयडी कर्मचारी  {0}साठी सेट नाही,
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),(दिवस मध्ये) वॉरंटी कालावधी,
 Auto re-order,ऑटो पुन्हा आदेश,
 Reorder level based on Warehouse,वखारवर  आधारित पुन्हा क्रमवारी लावा पातळी,
-Will also apply for variants unless overrridden,Overrridden आहेत तोपर्यंत देखील रूपे लागू राहील,
+Will also apply for variants unless overridden,Overrridden आहेत तोपर्यंत देखील रूपे लागू राहील,
 Units of Measure,माप युनिट,
 Will also apply for variants,तसेच रूपे लागू राहील,
 Serial Nos and Batches,सिरियल क्र आणि बॅच,
@@ -7949,12 +7944,10 @@
 Approvers,वाद,
 The first Approver in the list will be set as the default Approver.,सूचीतील प्रथम मंजूर डीफॉल्ट मंजूर म्हणून सेट केला जाईल.,
 Shift Request Approver,शिफ्ट विनंती मंजूर,
-PAN Number,पॅन क्रमांक,
 Provident Fund Account,भविष्य निर्वाह निधी,
 MICR Code,एमआयसीआर कोड,
 Repay unclaimed amount from salary,वेतनातून दावा न केलेली रक्कम परत द्या,
 Deduction from salary,वेतनातून वजावट,
-Expired Leaves,कालबाह्य झालेले पाने,
 If this is not checked the loan by default will be considered as a Demand Loan,हे तपासले नाही तर डीफॉल्टनुसार कर्ज डिमांड लोन मानले जाईल,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,हे खाते कर्जदाराकडून कर्ज परतफेड बुक करण्यासाठी आणि कर्जदाराला कर्ज वितरणासाठी वापरले जाते.,
 This account is capital account which is used to allocate capital for loan disbursal account ,हे खाते भांडवल खाते आहे जे कर्ज वितरण खात्यासाठी भांडवल वाटप करण्यासाठी वापरले जाते,
@@ -8748,3 +8741,5 @@
 Is Mandatory,अनिवार्य आहे,
 WhatsApp,व्हॉट्सअ‍ॅप,
 Make a call,कॉल करा,
+Approve,मंजूर,
+Reject,नकार,
diff --git a/erpnext/translations/ms.csv b/erpnext/translations/ms.csv
index ebfc36c..75e150a 100644
--- a/erpnext/translations/ms.csv
+++ b/erpnext/translations/ms.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Dokumen pengulang automatik dikemas kini,
 Automotive,Automotif,
 Available,Tersedia,
-Available Leaves,Daun yang disediakan,
 Available Qty,Terdapat Qty,
 Available Selling,Jualan Sedia Ada,
 Available for use date is required,Tersedia untuk tarikh penggunaan,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,ID Sync Hub,
 Human Resource,Sumber Manusia,
 Human Resources,Sumber Manusia,
-IFSC Code,Kod IFSC,
 IGST Amount,Jumlah IGST,
 IP Address,Alamat IP,
 ITC Available (whether in full op part),ITC Tersedia (sama ada dalam bahagian penuh),
@@ -1666,7 +1664,6 @@
 Other,Lain-lain,
 Other Reports,Laporan Lain,
 "Other outward supplies(Nil rated,Exempted)","Bekalan luaran lain (Tiada nilai, Dikecualikan)",
-Others,Lain,
 Out Qty,Keluar Qty,
 Out Value,Nilai Keluar,
 Out of Order,Telah habis,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Jumlah (Tanpa Cukai),
 Total Achieved,Jumlah Pencapaian,
 Total Actual,Jumlah Sebenar,
-Total Allocated Leaves,Jumlah Dikelilingi Daun,
 Total Amount,Jumlah,
 Total Amount Credited,Jumlah Jumlah Dikreditkan,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Jumlah Caj Terpakai di Purchase meja Resit Item mesti sama dengan Jumlah Cukai dan Caj,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Memuat naik kepala surat dan logo. (Anda boleh mengeditnya kemudian).,
 Upper Income,Pendapatan Atas,
 Use Sandbox,Penggunaan Sandbox,
-Used Leaves,Daun yang digunakan,
 User,Pengguna,
 User ID,ID Pengguna,
 User ID not set for Employee {0},ID Pengguna tidak ditetapkan untuk Pekerja {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Tempoh jaminan (dalam hari),
 Auto re-order,Auto semula perintah,
 Reorder level based on Warehouse,Tahap pesanan semula berdasarkan Warehouse,
-Will also apply for variants unless overrridden,Juga akan memohon varian kecuali overrridden,
+Will also apply for variants unless overridden,Juga akan memohon varian kecuali overridden,
 Units of Measure,Unit ukuran,
 Will also apply for variants,Juga akan memohon varian,
 Serial Nos and Batches,Serial Nos dan Kelompok,
@@ -7949,12 +7944,10 @@
 Approvers,Meluluskan,
 The first Approver in the list will be set as the default Approver.,Pelulus pertama dalam senarai akan ditetapkan sebagai Pelulus lalai.,
 Shift Request Approver,Kelulusan Permintaan Shift,
-PAN Number,Nombor PAN,
 Provident Fund Account,Akaun Kumpulan Wang Simpanan,
 MICR Code,Kod MICR,
 Repay unclaimed amount from salary,Bayar balik jumlah yang tidak dituntut dari gaji,
 Deduction from salary,Potongan gaji,
-Expired Leaves,Daun Tamat Tempoh,
 If this is not checked the loan by default will be considered as a Demand Loan,"Sekiranya ini tidak diperiksa, pinjaman secara lalai akan dianggap sebagai Permintaan Pinjaman",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Akaun ini digunakan untuk membuat pembayaran pinjaman dari peminjam dan juga mengeluarkan pinjaman kepada peminjam,
 This account is capital account which is used to allocate capital for loan disbursal account ,Akaun ini adalah akaun modal yang digunakan untuk memperuntukkan modal untuk akaun pengeluaran pinjaman,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Adakah Wajib,
 WhatsApp,WhatsApp,
 Make a call,Buat panggilan,
+Approve,Terima,
+Reject,Tolak,
diff --git a/erpnext/translations/my.csv b/erpnext/translations/my.csv
index 82015c8..36cd874 100644
--- a/erpnext/translations/my.csv
+++ b/erpnext/translations/my.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,အော်တိုထပ်စာရွက်စာတမ်း updated,
 Automotive,မော်တော်ယာဉ်,
 Available,ရရှိနိုင်,
-Available Leaves,ရရှိနိုင်အရွက်,
 Available Qty,ရရှိနိုင်သည့် Qty,
 Available Selling,ရောင်းချခြင်းရရှိနိုင်,
 Available for use date is required,အသုံးပြုမှုနေ့စွဲများအတွက်ရရှိနိုင်လိုအပ်ပါသည်,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,hub Sync ကို ID ကို,
 Human Resource,လူ့စွမ်းအားအရင်းအမြစ်,
 Human Resources,လူ့အင်အားအရင်းအမြစ်,
-IFSC Code,IFSC Code ကို,
 IGST Amount,IGST ငွေပမာဏ,
 IP Address,IP Address ကို,
 ITC Available (whether in full op part),(အပြည့်အဝ op အစိတ်အပိုင်းအတွက်ရှိမရှိ) ရရှိနိုင် ITC,
@@ -1666,7 +1664,6 @@
 Other,အခြား,
 Other Reports,အခြားအစီရင်ခံစာများ,
 "Other outward supplies(Nil rated,Exempted)","သည်အခြားအပြင်ထောက်ပံ့ရေးပစ္စည်းများ (nil rated, ကင်းလွတ်ခွင့်)",
-Others,အခြားသူများ,
 Out Qty,Qty out,
 Out Value,Value တစ်ခုအထဲက,
 Out of Order,အမိန့်များထဲက,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),(အခွန်မပါ) စုစုပေါင်း,
 Total Achieved,အကောင်အထည်ဖော်ခဲ့သောစုစုပေါင်း,
 Total Actual,အမှန်တကယ်စုစုပေါင်း,
-Total Allocated Leaves,စုစုပေါင်းခွဲဝေအရွက်,
 Total Amount,စုစုပေါင်းတန်ဘိုး,
 Total Amount Credited,စုစုပေါင်းငွေပမာဏအသိအမှတ်ပြု,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,အရစ်ကျငွေလက်ခံပြေစာပစ္စည်းများ table ထဲမှာစုစုပေါင်းသက်ဆိုင်သောစွပ်စွဲချက်စုစုပေါင်းအခွန်နှင့်စွပ်စွဲချက်အဖြစ်အတူတူပင်ဖြစ်ရပါမည်,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,သင့်ရဲ့စာကိုဦးခေါင်းနှင့်လိုဂို upload ။ (သင်နောက်ပိုင်းမှာသူတို့ကိုတည်းဖြတ်နိုင်သည်) ။,
 Upper Income,အထက်ဝင်ငွေခွန်,
 Use Sandbox,Sandbox ကိုသုံးပါ,
-Used Leaves,တပတ်ရစ်အရွက်,
 User,အသုံးပြုသူကို,
 User ID,သုံးစွဲသူအိုင်ဒီ,
 User ID not set for Employee {0},အသုံးပြုသူ ID န်ထမ်း {0} သည်စွဲလမ်းခြင်းမ,
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),(ရက်) ကိုအာမခံကာလ,
 Auto re-order,မော်တော်ကားပြန်လည်အမိန့်,
 Reorder level based on Warehouse,ဂိုဒေါင်အပေါ်အခြေခံပြီး reorder level ကို,
-Will also apply for variants unless overrridden,စ overrridden မဟုတ်လျှင်မျိုးကွဲလျှောက်ထားလိမ့်မည်ဟု,
+Will also apply for variants unless overridden,စ overridden မဟုတ်လျှင်မျိုးကွဲလျှောက်ထားလိမ့်မည်ဟု,
 Units of Measure,တိုင်း၏ယူနစ်,
 Will also apply for variants,စမျိုးကွဲလျှောက်ထားလိမ့်မည်ဟု,
 Serial Nos and Batches,serial Nos နှင့် batch,
@@ -7949,12 +7944,10 @@
 Approvers,ခွင့်ပြုချက်,
 The first Approver in the list will be set as the default Approver.,စာရင်းထဲတွင်ပထမအတည်ပြုချက်ကိုမူလအတည်ပြုချက်အဖြစ်သတ်မှတ်မည်။,
 Shift Request Approver,Shift Request Approver,
-PAN Number,PAN နံပါတ်,
 Provident Fund Account,Provident ရန်ပုံငွေအကောင့်,
 MICR Code,MICR ကုဒ်,
 Repay unclaimed amount from salary,မတောင်းဆိုသောငွေကိုလစာမှပြန်ပေးပါ,
 Deduction from salary,လစာမှနှုတ်ယူခြင်း,
-Expired Leaves,သက်တမ်းကုန်ဆုံးသောအရွက်,
 If this is not checked the loan by default will be considered as a Demand Loan,အကယ်၍ ၎င်းကိုမစစ်ဆေးပါကပုံမှန်အားဖြင့်ချေးငွေကို Demand Loan အဖြစ်သတ်မှတ်မည်,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,ဒီအကောင့်ကိုငွေချေးသူထံမှချေးငွေပြန်ဆပ်မှုကိုကြိုတင်မှာကြားပြီးငွေချေးသူမှချေးငွေများထုတ်ပေးသည်,
 This account is capital account which is used to allocate capital for loan disbursal account ,ဤအကောင့်သည်ငွေရင်းငွေစာရင်းဖြစ်သည်,
@@ -8748,3 +8741,5 @@
 Is Mandatory,မသင်မနေရဖြစ်ပါတယ်,
 WhatsApp,နင်,
 Make a call,ခေါ်ဆိုပါ,
+Approve,အတည်ပြု,
+Reject,ပယ်ချ,
diff --git a/erpnext/translations/nl.csv b/erpnext/translations/nl.csv
index 862d585..5859833 100644
--- a/erpnext/translations/nl.csv
+++ b/erpnext/translations/nl.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Automatisch herhaalde document bijgewerkt,
 Automotive,Automotive,
 Available,Beschikbaar,
-Available Leaves,Beschikbare bladeren,
 Available Qty,Beschikbaar aantal,
 Available Selling,Beschikbare verkoop,
 Available for use date is required,Beschikbaar voor gebruik datum is vereist,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub Sync ID,
 Human Resource,Human Resource,
 Human Resources,Human Resources,
-IFSC Code,IFSC-code,
 IGST Amount,IGST Bedrag,
 IP Address,IP adres,
 ITC Available (whether in full op part),ITC beschikbaar (al dan niet volledig),
@@ -1666,7 +1664,6 @@
 Other,Ander,
 Other Reports,Andere rapporten,
 "Other outward supplies(Nil rated,Exempted)","Andere uitgaande leveringen (nul, vrijgesteld)",
-Others,anderen,
 Out Qty,out Aantal,
 Out Value,out Value,
 Out of Order,Out of Order,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Totaal (zonder btw),
 Total Achieved,Totaal Bereikt,
 Total Actual,Totaal Werkelijke,
-Total Allocated Leaves,Totaal toegewezen bladeren,
 Total Amount,Totaal bedrag,
 Total Amount Credited,Totaal gecrediteerd bedrag,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Totaal van toepassing zijnde kosten in Kwitantie Items tabel moet hetzelfde zijn als de totale belastingen en heffingen,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Upload uw brief hoofd en logo. (Je kunt ze later bewerken).,
 Upper Income,Bovenste Inkomen,
 Use Sandbox,Gebruik Sandbox,
-Used Leaves,Gebruikte bladeren,
 User,Gebruiker,
 User ID,Gebruikers-ID,
 User ID not set for Employee {0},Gebruikers-ID niet ingesteld voor werknemer {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Garantieperiode (in dagen),
 Auto re-order,Auto re-order,
 Reorder level based on Warehouse,Bestelniveau gebaseerd op Warehouse,
-Will also apply for variants unless overrridden,Geldt ook voor varianten tenzij overrridden,
+Will also apply for variants unless overridden,Geldt ook voor varianten tenzij overridden,
 Units of Measure,Meeteenheden,
 Will also apply for variants,Geldt ook voor varianten,
 Serial Nos and Batches,Serienummers en batches,
@@ -7949,12 +7944,10 @@
 Approvers,Goedkeurders,
 The first Approver in the list will be set as the default Approver.,De eerste goedkeurder in de lijst wordt ingesteld als de standaard goedkeurder.,
 Shift Request Approver,Shift Request Approver,
-PAN Number,PAN-nummer,
 Provident Fund Account,Provident Fund-account,
 MICR Code,MICR-code,
 Repay unclaimed amount from salary,Betaal niet-opgeëiste bedrag terug van salaris,
 Deduction from salary,Inhouding op salaris,
-Expired Leaves,Verlopen bladeren,
 If this is not checked the loan by default will be considered as a Demand Loan,"Als dit niet is aangevinkt, wordt de lening standaard beschouwd als een opeisbare lening",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Deze rekening wordt gebruikt voor het boeken van aflossingen van leningen van de lener en ook voor het uitbetalen van leningen aan de lener,
 This account is capital account which is used to allocate capital for loan disbursal account ,Deze rekening is een kapitaalrekening die wordt gebruikt om kapitaal toe te wijzen voor het uitbetalen van leningen,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Is verplicht,
 WhatsApp,WhatsApp,
 Make a call,Bellen,
+Approve,Goedkeuren,
+Reject,afwijzen,
diff --git a/erpnext/translations/no.csv b/erpnext/translations/no.csv
index 0c1cfac..a3236ac 100644
--- a/erpnext/translations/no.csv
+++ b/erpnext/translations/no.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Automatisk gjentatt dokument oppdatert,
 Automotive,Automotive,
 Available,Tilgjengelig,
-Available Leaves,Tilgjengelige blader,
 Available Qty,Tilgjengelig antall,
 Available Selling,Tilgjengelig salg,
 Available for use date is required,Tilgjengelig for bruk er nødvendig,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub Sync ID,
 Human Resource,Menneskelig Resurs,
 Human Resources,Menneskelige ressurser,
-IFSC Code,IFSC-kode,
 IGST Amount,IGST Beløp,
 IP Address,IP adresse,
 ITC Available (whether in full op part),ITC tilgjengelig (om fullstendig del),
@@ -1666,7 +1664,6 @@
 Other,Andre,
 Other Reports,Andre rapporter,
 "Other outward supplies(Nil rated,Exempted)","Andre forsyninger (ikke vurdert, unntatt)",
-Others,Annet,
 Out Qty,Ut Antall,
 Out Value,ut Verdi,
 Out of Order,I ustand,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Totalt (uten skatt),
 Total Achieved,Oppnådd Total,
 Total Actual,Total Actual,
-Total Allocated Leaves,Totalt tildelte blad,
 Total Amount,Totalbeløp,
 Total Amount Credited,Totalt beløp krevet,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Totalt gjeldende avgifter i kvitteringen Elementer tabellen må være det samme som total skatter og avgifter,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Last opp din brevhode og logo. (Du kan redigere dem senere).,
 Upper Income,Øvre inntekt,
 Use Sandbox,bruk Sandbox,
-Used Leaves,Brukte blad,
 User,Bruker,
 User ID,bruker-ID,
 User ID not set for Employee {0},Bruker-ID ikke satt for Employee {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Garantiperioden (i dager),
 Auto re-order,Auto re-order,
 Reorder level based on Warehouse,Omgjøre nivå basert på Warehouse,
-Will also apply for variants unless overrridden,Vil også gjelde for varianter med mindre overrridden,
+Will also apply for variants unless overridden,Vil også gjelde for varianter med mindre overridden,
 Units of Measure,Måleenheter,
 Will also apply for variants,Vil også gjelde for varianter,
 Serial Nos and Batches,Serienummer og partier,
@@ -7949,12 +7944,10 @@
 Approvers,Tilstridende,
 The first Approver in the list will be set as the default Approver.,Den første godkjenneren i listen blir angitt som standard godkjenner.,
 Shift Request Approver,Godkjenning av skiftforespørsel,
-PAN Number,PAN-nummer,
 Provident Fund Account,Forsikringskonto,
 MICR Code,MICR-kode,
 Repay unclaimed amount from salary,Tilbakebetalt uavhentet beløp fra lønn,
 Deduction from salary,Trekk fra lønn,
-Expired Leaves,Utløpte blader,
 If this is not checked the loan by default will be considered as a Demand Loan,"Hvis dette ikke er sjekket, vil lånet som standard bli betraktet som et etterspørsel",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Denne kontoen brukes til å bestille tilbakebetaling av lån fra låntaker og også utbetale lån til låner,
 This account is capital account which is used to allocate capital for loan disbursal account ,Denne kontoen er en kapitalkonto som brukes til å fordele kapital til utbetaling av lån,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Er obligatorisk,
 WhatsApp,Hva skjer,
 Make a call,Ta en telefon,
+Approve,Vedta,
+Reject,Avvis,
diff --git a/erpnext/translations/pl.csv b/erpnext/translations/pl.csv
index 272e2fc..df41e39 100644
--- a/erpnext/translations/pl.csv
+++ b/erpnext/translations/pl.csv
@@ -285,7 +285,6 @@
 Auto Repeat,Auto Repeat,
 Auto repeat document updated,Automatycznie powtórzony dokument został zaktualizowany,
 Available,Dostępny,
-Available Leaves,Dostępne Nieobecności,
 Available Qty,Dostępne szt,
 Available Selling,Dostępne sprzedawanie,
 Available for use date is required,Dostępna jest data przydatności do użycia,
@@ -1121,7 +1120,6 @@
 Hub Sync ID,Identyfikator Hub Sync,
 Human Resource,Zasoby ludzkie,
 Human Resources,Kadry,
-IFSC Code,Kod IFSC,
 IGST Amount,Wielkość IGST,
 IP Address,Adres IP,
 ITC Available (whether in full op part),Dostępne ITC (czy w pełnej wersji),
@@ -1659,7 +1657,6 @@
 Other,Inne,
 Other Reports,Inne raporty,
 "Other outward supplies(Nil rated,Exempted)","Inne dostawy zewnętrzne (bez oceny, zwolnione)",
-Others,Inni,
 Out Qty,Brak Ilości,
 Out Value,Brak Wartości,
 Out of Order,Nieczynny,
@@ -2788,7 +2785,6 @@
 Total (Without Tax),Razem (bez podatku),
 Total Achieved,Razem Osiągnięte,
 Total Actual,Razem Rzeczywisty,
-Total Allocated Leaves,Całkowicie Przydzielone Nieobecności,
 Total Amount,Wartość całkowita,
 Total Amount Credited,Całkowita kwota kredytu,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Wszystkich obowiązujących opłat w ZAKUPU Elementy tabeli muszą być takie same jak Wszystkich podatkach i opłatach,
@@ -2898,7 +2894,6 @@
 Upload your letter head and logo. (you can edit them later).,Prześlij nagłówek firmowy i logo. (Można je edytować później).,
 Upper Income,Wzrost Wpływów,
 Use Sandbox,Korzystanie Sandbox,
-Used Leaves,Wykorzystane Nieobecności,
 User,Użytkownik,
 User ID,ID Użytkownika,
 User ID not set for Employee {0},ID Użytkownika nie ustawiony dla Pracownika {0},
@@ -6992,7 +6987,7 @@
 Warranty Period (in days),Okres gwarancji (w dniach),
 Auto re-order,Automatyczne ponowne zamówienie,
 Reorder level based on Warehouse,Zmiana kolejności w oparciu o poziom Magazynu,
-Will also apply for variants unless overrridden,"Również zostanie zastosowany do wariantów, chyba że zostanie nadpisany",
+Will also apply for variants unless overridden,"Również zostanie zastosowany do wariantów, chyba że zostanie nadpisany",
 Units of Measure,Jednostki miary,
 Will also apply for variants,Również zastosowanie do wariantów,
 Serial Nos and Batches,Numery seryjne i partie,
@@ -7860,12 +7855,10 @@
 Approvers,Osoby zatwierdzające,
 The first Approver in the list will be set as the default Approver.,Pierwsza osoba zatwierdzająca na liście zostanie ustawiona jako domyślna osoba zatwierdzająca.,
 Shift Request Approver,Zatwierdzający prośbę o zmianę,
-PAN Number,Numer PAN,
 Provident Fund Account,Konto funduszu rezerwowego,
 MICR Code,Kod MICR,
 Repay unclaimed amount from salary,Zwróć nieodebraną kwotę z wynagrodzenia,
 Deduction from salary,Odliczenie od wynagrodzenia,
-Expired Leaves,Wygasłe liście,
 If this is not checked the loan by default will be considered as a Demand Loan,"Jeśli opcja ta nie zostanie zaznaczona, pożyczka domyślnie zostanie uznana za pożyczkę na żądanie",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,"To konto służy do księgowania spłat pożyczki od pożyczkobiorcy, a także do wypłaty pożyczki pożyczkobiorcy",
 This account is capital account which is used to allocate capital for loan disbursal account ,"Rachunek ten jest rachunkiem kapitałowym, który służy do alokacji kapitału na rachunek wypłat pożyczki",
@@ -8659,3 +8652,5 @@
 Is Mandatory,Jest obowiązkowe,
 WhatsApp,WhatsApp,
 Make a call,Zadzwoń,
+Approve,Zatwierdzać,
+Reject,Odrzucać,
diff --git a/erpnext/translations/ps.csv b/erpnext/translations/ps.csv
index 8d4e467..5a0b2a5 100644
--- a/erpnext/translations/ps.csv
+++ b/erpnext/translations/ps.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,د اتوم بیاکتنه سند تازه شوی,
 Automotive,مشين,
 Available,شته,
-Available Leaves,شتون لري,
 Available Qty,موجود Qty,
 Available Selling,موجود پلورل,
 Available for use date is required,د کارولو نیټه اړینه ده,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,د کور همکاري ID,
 Human Resource,د بشري منابعو,
 Human Resources,بشري منابع,
-IFSC Code,د IFSC کود,
 IGST Amount,د IGST مقدار,
 IP Address,IP پته,
 ITC Available (whether in full op part),ITC شتون لري (ایا په بشپړ انتخابي برخه کې),
@@ -1666,7 +1664,6 @@
 Other,نور,
 Other Reports,نور راپورونه,
 "Other outward supplies(Nil rated,Exempted)",نور خارجی اکمالات (نیل ارزول شوی ، معاف شوی),
-Others,نور,
 Out Qty,له جملې څخه Qty,
 Out Value,له جملې څخه د ارزښت,
 Out of Order,له کاره وتلی,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),ټول (د مالیې پرته),
 Total Achieved,Total السته,
 Total Actual,Total واقعي,
-Total Allocated Leaves,ټول ټاکل شوي پاڼي,
 Total Amount,جمله پیسی,
 Total Amount Credited,ټولې پیسې اعتبار شوي,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,په رانيول رسيد توکي جدول ټولې د تطبیق په تور باید په توګه ټول ماليات او په تور ورته وي,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,پورته ستاسو لیک مشر او لوګو. (کولی شئ چې وروسته د سمولو لپاره).,
 Upper Income,د مشرانو پر عايداتو,
 Use Sandbox,sandbox استعمال,
-Used Leaves,استعمال شوي پاڼي,
 User,کارن,
 User ID,کارن نوم,
 User ID not set for Employee {0},کارن تذکرو لپاره د کارکونکو نه {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),ګرنټی د دورې (په ورځو),
 Auto re-order,د موټرونو د بيا نظم,
 Reorder level based on Warehouse,ترمیمي په کچه د پر بنسټ د ګدام,
-Will also apply for variants unless overrridden,مګر overrridden به د بېرغونو هم تر غوږو,
+Will also apply for variants unless overridden,مګر overridden به د بېرغونو هم تر غوږو,
 Units of Measure,د اندازه کولو واحدونه,
 Will also apply for variants,به هم د بېرغونو درخواست,
 Serial Nos and Batches,سریال وځيري او دستو,
@@ -7949,12 +7944,10 @@
 Approvers,مخالفت,
 The first Approver in the list will be set as the default Approver.,په لیست کې لومړی تصویبونکی به د ډیفالټ تصویب کونکي په توګه وټاکل شي.,
 Shift Request Approver,د شفټ غوښتنه تصویب,
-PAN Number,د پان شمیره,
 Provident Fund Account,د راتلونکي فنډ حساب,
 MICR Code,د MICR کوډ,
 Repay unclaimed amount from salary,له تنخوا څخه نامعلومه اندازه پیسې بیرته ورکړئ,
 Deduction from salary,له معاش څخه تخفیف,
-Expired Leaves,ختم شوې پاvesې,
 If this is not checked the loan by default will be considered as a Demand Loan,که چیرې دا چک نه شي نو په ډیفالټ ډول به د غوښتنې پور په توګه وګ .ل شي,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,دا حساب د پور ورکونکي څخه د پور بیرته تادیات کولو لپاره او هم پور اخیستونکي ته د پورونو توزیع لپاره کارول کیږي,
 This account is capital account which is used to allocate capital for loan disbursal account ,دا حساب د پانګوونې حساب دی چې د پور توزیع شوي حساب لپاره د پانګو ځانګړي کولو لپاره کارول کیږي,
@@ -8748,3 +8741,5 @@
 Is Mandatory,لازمي دی,
 WhatsApp,WhatsApp,
 Make a call,یو زنګ ووهه,
+Approve,منظور کړل,
+Reject,رد,
diff --git a/erpnext/translations/pt-BR.csv b/erpnext/translations/pt-BR.csv
index 0b7fa7e..bc5b616 100644
--- a/erpnext/translations/pt-BR.csv
+++ b/erpnext/translations/pt-BR.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Auto repetir documento atualizado,
 Automotive,Automotivo,
 Available,Disponível,
-Available Leaves,Folhas Disponíveis,
 Available Qty,Qtde Disponível,
 Available Selling,Venda Disponível,
 Available for use date is required,Disponível para data de uso é obrigatório,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Identificação da Sincronização do Hub,
 Human Resource,Recursos Humanos,
 Human Resources,Recursos Humanos,
-IFSC Code,Código IFSC,
 IGST Amount,Valor IGST,
 IP Address,Endereço de Ip,
 ITC Available (whether in full op part),ITC disponível (seja na parte operacional completa),
@@ -1666,7 +1664,6 @@
 Other,Outro,
 Other Reports,Relatórios Adicionais,
 "Other outward supplies(Nil rated,Exempted)","Outras fontes externas (valor nominal nominal, isentos)",
-Others,Outros,
 Out Qty,Qtde Saída,
 Out Value,Valor Saída,
 Out of Order,Fora de Serviço,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Total (sem Imposto),
 Total Achieved,Total de Alcançados,
 Total Actual,Total Atual,
-Total Allocated Leaves,Total de Folhas Alocadas,
 Total Amount,Valor Total,
 Total Amount Credited,Quantidade Total Creditada,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Total de encargos aplicáveis em Purchase mesa Itens recibo deve ser o mesmo que o total Tributos e Encargos,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Publique seu timbre e logotipo. (Você pode editá-las mais tarde).,
 Upper Income,Alta Renda,
 Use Sandbox,Use Sandbox,
-Used Leaves,Folhas Usadas,
 User,Usuário,
 User ID,ID de Usuário,
 User ID not set for Employee {0},ID de Usuário Não Definida Para Colaborador {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Período de Garantia (em dias),
 Auto re-order,Reposição Automática,
 Reorder level based on Warehouse,Nível de reposição baseado no Armazén,
-Will also apply for variants unless overrridden,Também se aplica a variantes a não ser que seja sobrescrito,
+Will also apply for variants unless overridden,Também se aplica a variantes a não ser que seja sobrescrito,
 Units of Measure,Unidades de Medida,
 Will also apply for variants,Também se aplica às variantes,
 Serial Nos and Batches,Números de Série e Lotes,
@@ -7949,12 +7944,10 @@
 Approvers,Aprovadores,
 The first Approver in the list will be set as the default Approver.,O primeiro aprovador da lista será definido como o aprovador padrão.,
 Shift Request Approver,Aprovador de Solicitação de Turno,
-PAN Number,Número PAN,
 Provident Fund Account,Conta do Fundo de Previdência,
 MICR Code,Código MICR,
 Repay unclaimed amount from salary,Reembolsar quantia não reclamada do salário,
 Deduction from salary,Dedução do salário,
-Expired Leaves,Folhas Vencidas,
 If this is not checked the loan by default will be considered as a Demand Loan,Se esta opção não for marcada o empréstimo por padrão será considerado um empréstimo à vista,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Esta conta é usada para registrar reembolsos de empréstimos do mutuário e também desembolsar empréstimos para o mutuário,
 This account is capital account which is used to allocate capital for loan disbursal account ,Esta conta é a conta de capital que é usada para alocar capital para a conta de desembolso do empréstimo,
@@ -8748,3 +8741,5 @@
 Is Mandatory,É mandatório,
 WhatsApp,Whatsapp,
 Make a call,Faça uma ligação,
+Approve,Aprovar,
+Reject,Rejeitar,
diff --git a/erpnext/translations/pt.csv b/erpnext/translations/pt.csv
index 10f1b71..e6846c6 100644
--- a/erpnext/translations/pt.csv
+++ b/erpnext/translations/pt.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Auto repetir documento atualizado,
 Automotive,Automóvel,
 Available,Disponível,
-Available Leaves,Folhas Disponíveis,
 Available Qty,Qtd disponível,
 Available Selling,Venda disponível,
 Available for use date is required,Disponível para data de uso é obrigatório,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Identificação da Sincronização do Hub,
 Human Resource,Recursos humanos,
 Human Resources,Recursos humanos,
-IFSC Code,Código IFSC,
 IGST Amount,Valor IGST,
 IP Address,Endereço de IP,
 ITC Available (whether in full op part),ITC disponível (seja na parte operacional completa),
@@ -1666,7 +1664,6 @@
 Other,Outro,
 Other Reports,Outros relatórios,
 "Other outward supplies(Nil rated,Exempted)","Outras fontes externas (valor nominal nominal, isentos)",
-Others,Outros,
 Out Qty,Qtd de Saída,
 Out Value,Valor de Saída,
 Out of Order,Fora de serviço,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Total (sem imposto),
 Total Achieved,Total Alcançado,
 Total Actual,Total real,
-Total Allocated Leaves,Total de Folhas Alocadas,
 Total Amount,Valor total,
 Total Amount Credited,Quantidade Total Creditada,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Total de encargos aplicáveis em Purchase mesa Itens recibo deve ser o mesmo que o total Tributos e Encargos,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Carregue o cabeçalho e logótipo da carta. (Pode editá-los mais tarde.),
 Upper Income,Rendimento Superior,
 Use Sandbox,Use Sandbox,
-Used Leaves,Folhas Usadas,
 User,Do utilizador,
 User ID,ID de Utiliz.,
 User ID not set for Employee {0},Não está definido a ID do utilizador para o Funcionário {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Período de Garantia (em dias),
 Auto re-order,Voltar a Pedir Autom.,
 Reorder level based on Warehouse,Nível de reencomenda no Armazém,
-Will also apply for variants unless overrridden,Também se aplica para as variantes a menos que seja anulado,
+Will also apply for variants unless overridden,Também se aplica para as variantes a menos que seja anulado,
 Units of Measure,Unidades de medida,
 Will also apply for variants,Também se aplicará para as variantes,
 Serial Nos and Batches,Números de série e lotes,
@@ -7949,12 +7944,10 @@
 Approvers,Aprovadores,
 The first Approver in the list will be set as the default Approver.,O primeiro aprovador da lista será definido como o aprovador padrão.,
 Shift Request Approver,Aprovador de solicitação de turno,
-PAN Number,Número PAN,
 Provident Fund Account,Conta do fundo de previdência,
 MICR Code,Código MICR,
 Repay unclaimed amount from salary,Reembolsar quantia não reclamada do salário,
 Deduction from salary,Dedução do salário,
-Expired Leaves,Folhas Vencidas,
 If this is not checked the loan by default will be considered as a Demand Loan,"Se esta opção não for marcada, o empréstimo, por padrão, será considerado um empréstimo à vista",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Esta conta é usada para registrar reembolsos de empréstimos do mutuário e também desembolsar empréstimos para o mutuário,
 This account is capital account which is used to allocate capital for loan disbursal account ,Esta conta é a conta de capital que é usada para alocar capital para a conta de desembolso do empréstimo,
@@ -8748,3 +8741,5 @@
 Is Mandatory,É mandatório,
 WhatsApp,Whatsapp,
 Make a call,Faça uma ligação,
+Approve,Aprovar,
+Reject,Rejeitar,
diff --git a/erpnext/translations/ro.csv b/erpnext/translations/ro.csv
index 80c32aa..ac7e598 100644
--- a/erpnext/translations/ro.csv
+++ b/erpnext/translations/ro.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Documentul repetat automat a fost actualizat,
 Automotive,Autopropulsat,
 Available,Disponibil,
-Available Leaves,Frunzele disponibile,
 Available Qty,Cantitate disponibilă,
 Available Selling,Vânzări disponibile,
 Available for use date is required,Data de utilizare disponibilă pentru utilizare este necesară,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub ID de sincronizare,
 Human Resource,Resurse umane,
 Human Resources,Resurse umane,
-IFSC Code,Codul IFSC,
 IGST Amount,Suma IGST,
 IP Address,Adresa IP,
 ITC Available (whether in full op part),ITC Disponibil (fie în opțiune integrală),
@@ -1666,7 +1664,6 @@
 Other,Altul,
 Other Reports,Alte rapoarte,
 "Other outward supplies(Nil rated,Exempted)","Alte consumabile exterioare (Nil evaluat, scutit)",
-Others,Altel,
 Out Qty,Out Cantitate,
 Out Value,Valoarea afară,
 Out of Order,Scos din uz,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Total (fără taxe),
 Total Achieved,Raport Realizat,
 Total Actual,Raport real,
-Total Allocated Leaves,Frunzele totale alocate,
 Total Amount,Suma totală,
 Total Amount Credited,Suma totală creditată,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Taxe totale aplicabile în tabelul de achiziție Chitanță Elementele trebuie să fie la fel ca total impozite și taxe,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Încărcați capul scrisoare și logo-ul. (Le puteți edita mai târziu).,
 Upper Income,Venituri de sus,
 Use Sandbox,utilizare Sandbox,
-Used Leaves,Frunze utilizate,
 User,Utilizator,
 User ID,ID-ul de utilizator,
 User ID not set for Employee {0},ID-ul de utilizator nu este setat pentru Angajat {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Perioada de garanție (în zile),
 Auto re-order,Re-comandă automată,
 Reorder level based on Warehouse,Nivel pentru re-comanda bazat pe Magazie,
-Will also apply for variants unless overrridden,Se va aplica și pentru variantele cu excepția cazului în overrridden,
+Will also apply for variants unless overridden,Se va aplica și pentru variantele cu excepția cazului în overridden,
 Units of Measure,Unitati de masura,
 Will also apply for variants,"Va aplică, de asemenea pentru variante",
 Serial Nos and Batches,Numere și loturi seriale,
@@ -7949,12 +7944,10 @@
 Approvers,Aprobatori,
 The first Approver in the list will be set as the default Approver.,Primul aprobator din listă va fi setat ca aprobator implicit.,
 Shift Request Approver,Aprobarea cererii de schimbare,
-PAN Number,Număr PAN,
 Provident Fund Account,Contul Fondului Provident,
 MICR Code,Cod MICR,
 Repay unclaimed amount from salary,Rambursați suma nepreluată din salariu,
 Deduction from salary,Deducerea din salariu,
-Expired Leaves,Frunze expirate,
 If this is not checked the loan by default will be considered as a Demand Loan,"Dacă acest lucru nu este verificat, împrumutul implicit va fi considerat un împrumut la cerere",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,"Acest cont este utilizat pentru rezervarea rambursărilor de împrumut de la împrumutat și, de asemenea, pentru a plăti împrumuturi către împrumutat",
 This account is capital account which is used to allocate capital for loan disbursal account ,Acest cont este un cont de capital care este utilizat pentru alocarea de capital pentru contul de debursare a împrumutului,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Este obligatoriu,
 WhatsApp,WhatsApp,
 Make a call,Efectua un apel,
+Approve,Aproba,
+Reject,Respinge,
diff --git a/erpnext/translations/ru.csv b/erpnext/translations/ru.csv
index 6a7e79f..52c2998 100644
--- a/erpnext/translations/ru.csv
+++ b/erpnext/translations/ru.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Автоматический повторный документ обновлен,
 Automotive,Автомобилестроение,
 Available,Доступно,
-Available Leaves,Доступные листья,
 Available Qty,Доступное количество,
 Available Selling,Доступные продажи,
 Available for use date is required,Доступна дата использования.,
@@ -1120,7 +1119,6 @@
 Hub Sync ID,Идентификатор синхронизации концентратора,
 Human Resource,Кадры,
 Human Resources,Персонал,
-IFSC Code,Код IFSC,
 IGST Amount,Сумма IGST,
 IP Address,IP адрес,
 ITC Available (whether in full op part),ITC Доступен (будь то в полной части оп),
@@ -1664,7 +1662,6 @@
 Other,Другое,
 Other Reports,Другие отчеты,
 "Other outward supplies(Nil rated,Exempted)","Другие внешние поставки (Ноль оценили, освобождены)",
-Others,Другое,
 Out Qty,Из кол-ва,
 Out Value,Выходное значение,
 Out of Order,Вышел из строя,
@@ -2810,7 +2807,6 @@
 Total (Without Tax),Всего (без налога),
 Total Achieved,Всего выполнено,
 Total Actual,Общий фактический,
-Total Allocated Leaves,Всего выделенных листов,
 Total Amount,Общая сумма,
 Total Amount Credited,Общая сумма кредита,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,"Всего Применимые сборы в таблице Purchase квитанций Элементов должны быть такими же, как все налоги и сборы",
@@ -2920,7 +2916,6 @@
 Upload your letter head and logo. (you can edit them later).,Загрузить шапку фирменного бланка и логотип. (Вы можете отредактировать их позднее).,
 Upper Income,Высокий уровень дохода,
 Use Sandbox,Использовать «песочницу»,
-Used Leaves,Используемые листы,
 User,Пользователь,
 User ID,ID пользователя,
 User ID not set for Employee {0},ID пользователя не установлен для сотрудника {0},
@@ -6990,7 +6985,7 @@
 Warranty Period (in days),Гарантийный период (дней),
 Auto re-order,Автоматический перезаказ,
 Reorder level based on Warehouse,Уровень переупорядочивания на основе склада,
-Will also apply for variants unless overrridden,"Будет также применяться для модификаций, если не отменено",
+Will also apply for variants unless overridden,"Будет также применяться для модификаций, если не отменено",
 Units of Measure,Единицы измерения,
 Will also apply for variants,Также применять к модификациям,
 Serial Nos and Batches,Серийные номера и партии,
@@ -7861,12 +7856,10 @@
 Approvers,Утверждающие,
 The first Approver in the list will be set as the default Approver.,Первый утверждающий в списке будет установлен как утверждающий по умолчанию.,
 Shift Request Approver,Утверждающий запрос смены,
-PAN Number,Номер PAN,
 Provident Fund Account,Счет фонда обеспечения персонала,
 MICR Code,Код MICR,
 Repay unclaimed amount from salary,Вернуть невостребованную сумму из заработной платы,
 Deduction from salary,Удержание из заработной платы,
-Expired Leaves,Просроченные листья,
 If this is not checked the loan by default will be considered as a Demand Loan,"Если этот флажок не установлен, ссуда по умолчанию будет считаться ссудой до востребования.",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,"Этот счет используется для регистрации платежей по ссуде от заемщика, а также для выдачи ссуд заемщику.",
 This account is capital account which is used to allocate capital for loan disbursal account ,"Этот счет является счетом движения капитала, который используется для распределения капитала на счет выдачи кредита.",
@@ -8668,3 +8661,5 @@
 WhatsApp,WhatsApp,
 Make a call,Позвонить,
 Is Template,Является шаблоном,
+Approve,Одобрить,
+Reject,Отклонить,
diff --git a/erpnext/translations/rw.csv b/erpnext/translations/rw.csv
index f487f19..f035d57 100644
--- a/erpnext/translations/rw.csv
+++ b/erpnext/translations/rw.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Ongera usubiremo inyandiko ivugururwa,
 Automotive,Imodoka,
 Available,Birashoboka,
-Available Leaves,Amababi aboneka,
 Available Qty,Kuboneka Qty,
 Available Selling,Kugurisha Kuboneka,
 Available for use date is required,Kuboneka kumatariki yo gukoresha birakenewe,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Indangamuntu ya Hub,
 Human Resource,Abakozi,
 Human Resources,Abakozi,
-IFSC Code,Kode ya IFSC,
 IGST Amount,Amafaranga IGST,
 IP Address,Aderesi ya IP,
 ITC Available (whether in full op part),ITC Iraboneka (haba mubice byuzuye op),
@@ -1666,7 +1664,6 @@
 Other,Ibindi,
 Other Reports,Izindi Raporo,
 "Other outward supplies(Nil rated,Exempted)","Ibindi bikoresho byo hanze (Nil rated, Usonewe)",
-Others,Abandi,
 Out Qty,Hanze Qty,
 Out Value,Agaciro,
 Out of Order,Bitemewe,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Igiteranyo (Nta musoro),
 Total Achieved,Byose Byagezweho,
 Total Actual,Igiteranyo Cyuzuye,
-Total Allocated Leaves,Amababi yose yatanzwe,
 Total Amount,Umubare wose,
 Total Amount Credited,Amafaranga yose yatanzwe,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Amafaranga yose akoreshwa muburyo bwo kugura ibicuruzwa byakiriwe bigomba kumera nkimisoro yose hamwe,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Kuramo ibaruwa yawe umutwe hamwe nikirangantego. (urashobora kubihindura nyuma).,
 Upper Income,Amafaranga yinjira,
 Use Sandbox,Koresha Sandbox,
-Used Leaves,Amababi yakoreshejwe,
 User,Umukoresha,
 User ID,Indangamuntu,
 User ID not set for Employee {0},Indangamuntu yumukoresha ntabwo yashyizweho kubakozi {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Igihe cya garanti (muminsi),
 Auto re-order,Ongera utumire,
 Reorder level based on Warehouse,Urwego rwo kwisubiramo rushingiye kububiko,
-Will also apply for variants unless overrridden,Uzasaba kandi kubitandukanye keretse birenze,
+Will also apply for variants unless overridden,Uzasaba kandi kubitandukanye keretse birenze,
 Units of Measure,Ibipimo,
 Will also apply for variants,Uzasaba kandi kubitandukanye,
 Serial Nos and Batches,Urutonde Nomero,
@@ -7949,12 +7944,10 @@
 Approvers,Abashinzwe,
 The first Approver in the list will be set as the default Approver.,Icyemezo cya mbere murutonde kizashyirwaho nkibisanzwe byemewe.,
 Shift Request Approver,Guhindura Gusaba,
-PAN Number,Numero ya PAN,
 Provident Fund Account,Konti y&#39;Ikigega cy&#39;Imari,
 MICR Code,Kode ya MICR,
 Repay unclaimed amount from salary,Subiza amafaranga atasabwe kuva kumushahara,
 Deduction from salary,Gukurwa ku mushahara,
-Expired Leaves,Amababi yarangiye,
 If this is not checked the loan by default will be considered as a Demand Loan,Niba ibi bitagenzuwe inguzanyo byanze bikunze bizafatwa nkinguzanyo isabwa,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Iyi konti ikoreshwa mugutanga inguzanyo zishyuwe nuwagurijwe kandi ikanatanga inguzanyo kubagurijwe,
 This account is capital account which is used to allocate capital for loan disbursal account ,Konti ni konti shingiro ikoreshwa mugutanga igishoro kuri konti yo gutanga inguzanyo,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Ni itegeko,
 WhatsApp,WhatsApp,
 Make a call,Hamagara,
+Approve,Emeza,
+Reject,Wange,
diff --git a/erpnext/translations/si.csv b/erpnext/translations/si.csv
index fff7817..4047263 100644
--- a/erpnext/translations/si.csv
+++ b/erpnext/translations/si.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,ස්වයං යාවත්කාලීන ලියවිල්ල යාවත්කාලීන කරන ලදි,
 Automotive,රථ,
 Available,ඇත,
-Available Leaves,පවතින ලීස්,
 Available Qty,ලබා ගත හැකි යවන ලද,
 Available Selling,විකුණා තිබේ,
 Available for use date is required,භාවිතයට ගත හැකි දිනය සඳහා අවශ්ය වේ,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub Sync ID,
 Human Resource,මානව සම්පත්,
 Human Resources,මානව සම්පත්,
-IFSC Code,IFSC සංග්රහය,
 IGST Amount,IGST මුදල,
 IP Address,IP ලිපිනය,
 ITC Available (whether in full op part),ITC ලබා ගත හැකිය (පූර්ණ වශයෙන් වුවද),
@@ -1666,7 +1664,6 @@
 Other,වෙනත්,
 Other Reports,වෙනත් වාර්තා,
 "Other outward supplies(Nil rated,Exempted)","වෙනත් බාහිර සැපයුම් (නිල් ශ්‍රේණිගත, නිදහස්)",
-Others,අන් අය,
 Out Qty,යවන ලද අතරින්,
 Out Value,අගය පෙන්වා,
 Out of Order,ක්රියාවිරහිත වී ඇත,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),මුළු (බදු රහිත),
 Total Achieved,මුළු ලබාගත්,
 Total Actual,මුළු තත,
-Total Allocated Leaves,සමස්ථ වෙන් කළ කොළ,
 Total Amount,මුලු වටිනාකම,
 Total Amount Credited,මුළු මුදල අයකෙරේ,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,මිලදී ගැනීම රිසිට්පත අයිතම වගුවේ මුළු අදාළ ගාස්තු මුළු බදු හා ගාස්තු ලෙස එම විය යුතුය,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,ඔබේ ලිපිය හිස සහ ලාංඡනය උඩුගත කරන්න. (ඔබ ඔවුන්ට පසුව සංස්කරණය කළ හැකි).,
 Upper Income,ඉහළ ආදායම්,
 Use Sandbox,වැලිපිල්ල භාවිතා,
-Used Leaves,පාවිච්චි කළ කොළ,
 User,පරිශීලක,
 User ID,පරිශීලක ID,
 User ID not set for Employee {0},සේවක {0} සඳහා පරිශීලක අනන්යාංකය පිහිටුවා නැත,
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),වගකීම් කාලය (දින තුළ),
 Auto re-order,වාහන නැවත අනුපිළිවෙලට,
 Reorder level based on Warehouse,ගබඩාව මත පදනම් මොහොත මට්ටමේ,
-Will also apply for variants unless overrridden,ද overrridden මිස ප්රභේද සඳහා අයදුම් කරනු ඇත,
+Will also apply for variants unless overridden,ද overridden මිස ප්රභේද සඳහා අයදුම් කරනු ඇත,
 Units of Measure,නු ඒකක,
 Will also apply for variants,ද ප්රභේද සඳහා අයදුම් කරනු ඇත,
 Serial Nos and Batches,අනුක්රමික අංක සහ කාණ්ඩ,
@@ -7949,12 +7944,10 @@
 Approvers,අනුමත කරන්නන්,
 The first Approver in the list will be set as the default Approver.,ලැයිස්තුවේ පළමු අනුමත කරන්නා පෙරනිමි අනුමත කරන්නා ලෙස සකසනු ඇත.,
 Shift Request Approver,මාරුව ඉල්ලීම් අනුමත කරන්නා,
-PAN Number,පෑන් අංකය,
 Provident Fund Account,අර්ථසාධක අරමුදල් ගිණුම,
 MICR Code,MICR කේතය,
 Repay unclaimed amount from salary,ඉල්ලුම් නොකළ මුදල වැටුපෙන් ආපසු ගෙවන්න,
 Deduction from salary,වැටුපෙන් අඩු කිරීම,
-Expired Leaves,කල් ඉකුත් වූ කොළ,
 If this is not checked the loan by default will be considered as a Demand Loan,මෙය පරීක්‍ෂා නොකළ හොත් ණය පෙරනිමියෙන් ඉල්ලුම් ණය ලෙස සැලකේ,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,මෙම ගිණුම ණය ගැනුම්කරුගෙන් ණය ආපසු ගෙවීම් වෙන්කරවා ගැනීම සඳහා සහ ණය ගැනුම්කරුට ණය ලබා දීම සඳහා යොදා ගනී,
 This account is capital account which is used to allocate capital for loan disbursal account ,මෙම ගිණුම ණය බෙදා හැරීමේ ගිණුම සඳහා ප්‍රාග්ධනය වෙන් කිරීම සඳහා භාවිතා කරන ප්‍රාග්ධන ගිණුමකි,
@@ -8748,3 +8741,5 @@
 Is Mandatory,අනිවාර්යයි,
 WhatsApp,WhatsApp,
 Make a call,ඇමතුමක් ගන්න,
+Approve,අනුමත,
+Reject,ප්රතික්ෂේප,
diff --git a/erpnext/translations/sk.csv b/erpnext/translations/sk.csv
index 05d3496..98e1663 100644
--- a/erpnext/translations/sk.csv
+++ b/erpnext/translations/sk.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Dokument bol aktualizovaný automaticky,
 Automotive,Automobilový,
 Available,K dispozici,
-Available Leaves,Dostupné listy,
 Available Qty,Množství k dispozici,
 Available Selling,Dostupný predaj,
 Available for use date is required,Je potrebný dátum použiteľného na použitie,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,ID synchronizácie Hubu,
 Human Resource,Ľudské Zdroje,
 Human Resources,Lidské zdroje,
-IFSC Code,Kód IFSC,
 IGST Amount,Suma IGST,
 IP Address,IP adresa,
 ITC Available (whether in full op part),ITC k dispozícii (či už v plnej op časti),
@@ -1666,7 +1664,6 @@
 Other,Ostatní,
 Other Reports,Ostatné správy,
 "Other outward supplies(Nil rated,Exempted)","Ostatné pasívne výrobky (bez hodnotenia, oslobodené)",
-Others,Ostatní,
 Out Qty,Out Množství,
 Out Value,limitu,
 Out of Order,Mimo prevádzky,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Spolu (bez dane),
 Total Achieved,Celkem Dosažená,
 Total Actual,Celkem Aktuální,
-Total Allocated Leaves,Celkové pridelené listy,
 Total Amount,Celková částka,
 Total Amount Credited,Celková čiastka bola pripísaná,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,"Celkom Použiteľné Poplatky v doklade o kúpe tovaru, ktorý tabuľky musí byť rovnaká ako celkom daní a poplatkov",
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Nahrajte svoju hlavičku a logo pre dokumenty. (Môžete ich upravovať neskôr.),
 Upper Income,Horní příjmů,
 Use Sandbox,použitie Sandbox,
-Used Leaves,Použité listy,
 User,užívateľ,
 User ID,User ID,
 User ID not set for Employee {0},User ID není nastavena pro zaměstnance {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Záruční doba (ve dnech),
 Auto re-order,Auto re-order,
 Reorder level based on Warehouse,Úroveň Zmena poradia na základe Warehouse,
-Will also apply for variants unless overrridden,"Bude platiť aj pre varianty, pokiaľ nebude prepísané",
+Will also apply for variants unless overridden,"Bude platiť aj pre varianty, pokiaľ nebude prepísané",
 Units of Measure,merné jednotky,
 Will also apply for variants,Bude platiť aj pre varianty,
 Serial Nos and Batches,Sériové čísla a dávky,
@@ -7949,12 +7944,10 @@
 Approvers,Schvaľovatelia,
 The first Approver in the list will be set as the default Approver.,Prvý schvaľovateľ v zozname bude nastavený ako predvolený schvaľovateľ.,
 Shift Request Approver,Schvaľovateľ žiadosti o zmenu,
-PAN Number,Číslo PAN,
 Provident Fund Account,Účet podielového fondu,
 MICR Code,Kód MICR,
 Repay unclaimed amount from salary,Vrátiť nevyzdvihnutú sumu z platu,
 Deduction from salary,Odpočet z platu,
-Expired Leaves,Vypršala platnosť,
 If this is not checked the loan by default will be considered as a Demand Loan,"Pokiaľ to nie je zaškrtnuté, pôžička sa štandardne bude považovať za pôžičku na požiadanie",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Tento účet sa používa na rezerváciu splátok pôžičky od dlžníka a tiež na vyplácanie pôžičiek dlžníkovi,
 This account is capital account which is used to allocate capital for loan disbursal account ,"Tento účet je kapitálovým účtom, ktorý sa používa na pridelenie kapitálu pre účet vyplácania pôžičiek",
@@ -8748,3 +8741,5 @@
 Is Mandatory,Je povinné,
 WhatsApp,WhatsApp,
 Make a call,Zavolať,
+Approve,schvaľovať,
+Reject,Odmietnuť,
diff --git a/erpnext/translations/sl.csv b/erpnext/translations/sl.csv
index 8eafe41..5380714 100644
--- a/erpnext/translations/sl.csv
+++ b/erpnext/translations/sl.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Posodobljen samodejno ponavljanje dokumenta,
 Automotive,Avtomobilizem,
 Available,Na voljo,
-Available Leaves,Na voljo listi,
 Available Qty,Na voljo Količina,
 Available Selling,Razpoložljiva prodaja,
 Available for use date is required,Potreben je datum uporabe,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Sync ID vozlišča,
 Human Resource,Človeški vir,
 Human Resources,Človeški viri,
-IFSC Code,Kodeks IFSC,
 IGST Amount,Znesek IGST,
 IP Address,IP naslov,
 ITC Available (whether in full op part),ITC Na voljo (v celoti v delu),
@@ -1666,7 +1664,6 @@
 Other,Drugi,
 Other Reports,Druga poročila,
 "Other outward supplies(Nil rated,Exempted)","Druge zunanje dobave (ničelno, oproščeno)",
-Others,Drugi,
 Out Qty,Out Kol,
 Out Value,iz Vrednost,
 Out of Order,Ne deluje,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Skupaj (brez davka),
 Total Achieved,Skupaj Doseženi,
 Total Actual,Skupaj Actual,
-Total Allocated Leaves,Skupna dodeljena lista,
 Total Amount,Skupni znesek,
 Total Amount Credited,Skupni znesek kredita,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Skupaj veljavnih cenah na Potrdilo o nakupu postavke tabele mora biti enaka kot Skupaj davkov in dajatev,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Naložite svoje pismo glavo in logotip. (lahko jih uredite kasneje).,
 Upper Income,Zgornja Prihodki,
 Use Sandbox,uporaba Sandbox,
-Used Leaves,Uporabljeni listi,
 User,Uporabnik,
 User ID,Uporabniško ime,
 User ID not set for Employee {0},ID uporabnika ni nastavljena za Employee {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Garancijski rok (v dnevih),
 Auto re-order,Auto re-order,
 Reorder level based on Warehouse,Raven Preureditev temelji na Warehouse,
-Will also apply for variants unless overrridden,Bo veljalo tudi za variante razen overrridden,
+Will also apply for variants unless overridden,Bo veljalo tudi za variante razen overridden,
 Units of Measure,Merske enote,
 Will also apply for variants,Bo veljalo tudi za variante,
 Serial Nos and Batches,Serijska št in Serije,
@@ -7949,12 +7944,10 @@
 Approvers,Odobritelji,
 The first Approver in the list will be set as the default Approver.,Prvi odobritelj na seznamu bo nastavljen kot privzeti odobritelj.,
 Shift Request Approver,Odobritelj zahteve za premik,
-PAN Number,Številka PAN,
 Provident Fund Account,Račun rezervnega sklada,
 MICR Code,Koda MICR,
 Repay unclaimed amount from salary,Vrnite neizterjani znesek iz plače,
 Deduction from salary,Odbitek od plače,
-Expired Leaves,Potekli listi,
 If this is not checked the loan by default will be considered as a Demand Loan,"Če to ni potrjeno, bo posojilo privzeto obravnavano kot posojilo na zahtevo",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Ta račun se uporablja za rezervacijo odplačil posojilojemalca in tudi za izplačilo posojil posojilojemalcu,
 This account is capital account which is used to allocate capital for loan disbursal account ,"Ta račun je račun kapitala, ki se uporablja za dodelitev kapitala za račun izplačila posojila",
@@ -8748,3 +8741,5 @@
 Is Mandatory,Je obvezno,
 WhatsApp,WhatsApp,
 Make a call,Opraviti klic,
+Approve,Odobri,
+Reject,Zavrni,
diff --git a/erpnext/translations/sq.csv b/erpnext/translations/sq.csv
index 8c9a2ed..2a893d2 100644
--- a/erpnext/translations/sq.csv
+++ b/erpnext/translations/sq.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Dokumenti i përsëritjes automatike përditësohej,
 Automotive,automobilistik,
 Available,në dispozicion,
-Available Leaves,Lejet e disponueshme,
 Available Qty,Qty në dispozicion,
 Available Selling,Shitja në dispozicion,
 Available for use date is required,Kërkohet data e përdorimit,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,ID e sinkronizimit të Hub,
 Human Resource,Burimeve Njerëzore,
 Human Resources,Burimeve Njerëzore,
-IFSC Code,Kodi IFSC,
 IGST Amount,Shuma IGST,
 IP Address,Adresa IP,
 ITC Available (whether in full op part),ITC në dispozicion (qoftë në pjesën e plotë të op),
@@ -1666,7 +1664,6 @@
 Other,Tjetër,
 Other Reports,Raportet tjera,
 "Other outward supplies(Nil rated,Exempted)","Furnizime të tjera të jashtme (vlerësuar me Nil, Përjashtuar)",
-Others,Të tjerët,
 Out Qty,Nga Qty,
 Out Value,Vlera out,
 Out of Order,Jashtë përdorimit,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Totali (Pa Tatimore),
 Total Achieved,Gjithsej Arritur,
 Total Actual,Gjithsej aktuale,
-Total Allocated Leaves,Totali i lëkundjeve të alokuara,
 Total Amount,Shuma totale,
 Total Amount Credited,Shuma totale e kredituar,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Akuzat totale të zbatueshme në Blerje tryezë Receipt artikujt duhet të jetë i njëjtë si Total taksat dhe tarifat,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Ngarko kokën tuaj letër dhe logo. (Ju mund të modifikoni ato më vonë).,
 Upper Income,Të ardhurat e sipërme,
 Use Sandbox,Përdorimi Sandbox,
-Used Leaves,Lë të përdorura,
 User,përdorues,
 User ID,User ID,
 User ID not set for Employee {0},Përdoruesi ID nuk është caktuar për punonjësit {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Garanci Periudha (në ditë),
 Auto re-order,Auto ri-qëllim,
 Reorder level based on Warehouse,Niveli Reorder bazuar në Magazina,
-Will also apply for variants unless overrridden,Gjithashtu do të aplikojë për variantet nëse overrridden,
+Will also apply for variants unless overridden,Gjithashtu do të aplikojë për variantet nëse overridden,
 Units of Measure,Njësitë e masës,
 Will also apply for variants,Gjithashtu do të aplikojë për variantet,
 Serial Nos and Batches,Serial Nr dhe Batches,
@@ -7949,12 +7944,10 @@
 Approvers,Përgjegjës,
 The first Approver in the list will be set as the default Approver.,Miratuesi i parë në listë do të caktohet si Miratuesi i paracaktuar.,
 Shift Request Approver,Miratuesi i kërkesës për ndërrim,
-PAN Number,Numri PAN,
 Provident Fund Account,Llogaria e Fondit të Providencës,
 MICR Code,Kodi MICR,
 Repay unclaimed amount from salary,Shlyeni shumën e pakërkuar nga paga,
 Deduction from salary,Zbritja nga paga,
-Expired Leaves,Gjethet e skaduara,
 If this is not checked the loan by default will be considered as a Demand Loan,"Nëse kjo nuk kontrollohet, kredia si parazgjedhje do të konsiderohet si një Kredi e Kërkesës",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Kjo llogari përdoret për rezervimin e ripagimeve të huasë nga huamarrësi dhe gjithashtu disbursimin e huamarrësve,
 This account is capital account which is used to allocate capital for loan disbursal account ,Kjo llogari është llogari kapitale e cila përdoret për të alokuar kapitalin për llogarinë e disbursimit të kredisë,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Shtë e Detyrueshme,
 WhatsApp,WhatsApp,
 Make a call,Bej nje telefonate,
+Approve,miratoj,
+Reject,hedh poshtë,
diff --git a/erpnext/translations/sr-SP.csv b/erpnext/translations/sr-SP.csv
index c70ae81..ac5711f 100644
--- a/erpnext/translations/sr-SP.csv
+++ b/erpnext/translations/sr-SP.csv
@@ -7,10 +7,8 @@
 Warehouse {0} does not exist,Skladište {0} ne postoji,
 Confirmed orders from Customers.,Potvrđene porudžbine od strane kupaca,
 Healthcare (beta),Klinika (beta)
-Salary Structure,Структура плата
 Item Reorder,Dopuna artikla,
 Report an Issue,Prijavi grešku,
-Net Pay,Neto plaćanje,
 Internal Transfer,Interni prenos,
 Item Tax Rate,Poreska stopa,
 Create a new Customer,Kreirajte novog kupca,
@@ -52,7 +50,6 @@
 You can only select a maximum of one option from the list of check boxes.,Из листе поља за потврду можете изабрати највише једну опцију.
 Group by Voucher,Grupiši po knjiženjima,
 Total Outstanding,Ukupno preostalo,
-Email Salary Slip to Employee,Pošalji platnu listu Zaposlenom,
 Customer Code,Šifra kupca,
 Allow multiple Sales Orders against a Customer's Purchase Order,Dozvolite više prodajnih naloga koji su vezani sa porudžbenicom kupca,
 Total Outgoing,Ukupno isporučeno,
@@ -61,7 +58,6 @@
 %  Delivered,% Isporučeno,
 Appraisal {0} created for Employee {1} in the given date range,Procjena {0} kreirana za Zaposlenog {1} za dati period,
 Party Balance,Stanje kupca,
-{0} already allocated for Employee {1} for period {2} to {3},{0} već dodijeljeno zaposlenom {1} za period {2} {3}
 Customers,Kupci,
 Please set User ID field in an Employee record to set Employee Role,Molimo podesite polje Korisnički ID u evidenciji Zaposlenih radi podešavanja zaduženja Zaposlenih,
 Task Completion,Završenost zadataka,
@@ -89,7 +85,6 @@
 Consultations,Pregledi,
 Classification of Customers by region,Klasifikacija kupaca po regiji,
 Quotation To,Ponuda za,
-Payroll Employee Detail,Detalji o platnom spisku Zaposlenih,
 Timesheet for tasks.,Potrošeno vrijeme za zadatke,
 Remark,Napomena,
 Tree of Item Groups.,Stablo Vrste artikala,
@@ -122,13 +117,11 @@
 `Freeze Stocks Older Than` should be smaller than %d days.,"""Zamrzni akcije starije"" trebalo bi da budu manje %d dana."
 Patient Age,Starost pacijenta,
 Employee cannot report to himself.,Zaposleni ne može izvještavati sebi,
-You can only submit Leave Encashment for a valid encashment amount,Можете поднети Исплату одсуства само са валидном количином за исплату.
 Customer Address,Adresa kupca,
 Total Amount {0},Ukupan iznos {0}
 Total (Credit),Ukupno bez PDV-a (duguje)
 In Words (Export) will be visible once you save the Delivery Note.,Slovima (izvoz) će biti vidljiv onda kad sačuvate otpremnicu,
 Opportunity Date,Datum prilike,
-Marked Attendance HTML,Označeno prisustvo HTML,
 Delivery Note Item,Pozicija otpremnice,
 Customer's Purchase Order,Porudžbenica kupca,
 Get items from,Dodaj stavke iz,
@@ -150,14 +143,12 @@
 Account: {0} can only be updated via Stock Transactions,Računovodstvo: {0} može samo da se ažurira u dijelu Promjene na zalihama,
 Leave Approver,Odobrava izlaske s posla,
 Customer or Item,Kupac ili proizvod,
-Attendance To Date,Prisustvo do danas,
 Requested Qty,Tražena kol,
 Attendance Freeze Date,Datum zamrzavanja prisustva,
 No Item with Serial No {0},Ne postoji artikal sa serijskim brojem {0}
 Taxes and Charges,Porezi i naknade,
 Serial Number Series,Serijski broj serije,
 Delivered,Isporučeno,
-No employee found,Zaposleni nije pronađen,
 Default Territory,Podrazumijevana država,
 Asset Category,Grupe osnovnih sredstava,
 Customer Warehouse (Optional),Skladište kupca (opciono)
@@ -190,10 +181,8 @@
 Sales Partners Commission,Provizija za prodajne partnere,
 Territory,Teritorija,
 Sales Order Message,Poruka prodajnog naloga,
-Employees HTML,HTML Zaposlenih,
 Employee Leave Balance,Pregled odsustva Zaposlenih,
 Minute,Minut,
-Emails salary slip to employee based on preferred email selected in Employee,Pošalji platnu listu Zaposlenom na željenu adresu označenu u tab-u ZAPOSLENI,
 Litre,Litar,
 Opening (Cr),Početno stanje (Po)
 Academics User,Akademski korisnik,
@@ -222,11 +211,9 @@
 Product Bundle Item,Sastavljeni proizvodi,
 Select Employees,Odaberite Zaposlene,
 "Create Employee records to manage leaves, expense claims and payroll","Kreiraj evidenciju o Zaposlenom kako bi upravljali odsustvom, potraživanjima za troškove i platnim spiskovima"
-This is based on the attendance of this Employee,Ovo se zasniva na pohađanju ovog zaposlenog,
 Address & Contact,Adresa i kontakt,
 Reserved Qty for Production,Rezervisana kol. za proizvodnju,
 This is based on stock movement. See {0} for details,Ovo praćenje je zasnovano na kretanje zaliha. Pogledajte {0} za više detalja,
-Training Event Employee,Obuke Zaposlenih,
 All Contacts.,Svi kontakti,
 Sales Person,Prodajni agent,
 Default Warehouse,Podrazumijevano skladište,
@@ -237,7 +224,6 @@
 Credit,Potražuje,
 Grand Total,Za plaćanje,
 Human Resource,Ljudski resursi,
-Employees,Zaposleni,
 Delivery Note Required,Otpremnica je obavezna,
 Type of Payment,Vrsta plaćanja,
 UOM,JM,
@@ -284,15 +270,12 @@
 Customer is required,Kupac je obavezan podatak,
 Manufacturer,Proizvođač
 Selling Amount,Prodajni iznos,
-Please set the Date Of Joining for employee {0},Molimo podesite datum zasnivanja radnog odnosa {0}
 Allow over delivery or receipt upto this percent,Dozvolite isporukuili prijem robe ukoliko ne premaši ovaj procenat,
 Orders,Porudžbine,
 Stock Transactions,Promjene na zalihama,
-You are not authorized to approve leaves on Block Dates,Немате дозволу да одобравате одсуства на Блок Датумима.
 Daily Timesheet Summary,Pregled dnevnog potrošenog vremena,
 View Timesheet,Pogledaj potrošeno vrijeme,
 Rounded Total (Company Currency),Zaokruženi ukupan iznos (valuta preduzeća)
-Salary Slip of employee {0} already created for this period,Isplatna lista Zaposlenog {0} kreirana je već za ovaj period,
 "If this item has variants, then it cannot be selected in sales orders etc.","Ako ovaj artikal ima varijante, onda ne može biti biran u prodajnom nalogu."
 You can only redeem max {0} points in this order.,Можете унети највише {0} поена у овој наруџбини.
 No leave record found for employee {0} for {1},Nije nađena evidancija o odsustvu Zaposlenog {0} za {1}
@@ -312,7 +295,6 @@
 Additional Operating Cost,Dodatni operativni troškovi,
 Rejected Warehouse,Odbijeno skladište,
 Manufacturing Manager,Menadžer proizvodnje,
-You are not present all day(s) between compensatory leave request days,Нисте присутни свих дана између захтева за компензацијски одмор.
 Is Fixed Asset,Artikal je osnovno sredstvo,
 POS,POS,
 Timesheet {0} is already completed or cancelled,Potrošeno vrijeme {0} je već potvrđeno ili otkazano,
@@ -327,7 +309,6 @@
 Sync Offline Invoices,Sinhronizuj offline fakture,
 Manufacturing,Proizvodnja,
 {0}% Delivered,{0}% Isporučeno,
-Attendance,Prisustvo,
 Customer's Purchase Order No,Broj porudžbenice kupca,
 Please enter Sales Orders in the above table,U tabelu iznad unesite prodajni nalog,
 Report Date,Datum izvještaja,
@@ -338,7 +319,6 @@
 Payment Request,Upit za plaćanje,
 Purchase Analytics,Analiza nabavke,
 Tree Details,Detalji stabla,
-Upload Attendance,Priloži evidenciju,
 Against,Povezano sa,
 Requested Amount,Traženi iznos,
 "Record of all communications of type email, phone, chat, visit, etc.","Snimanje svih komunikacija tipa email, telefon, poruke, posjete, itd."
@@ -381,7 +361,6 @@
 Please select a warehouse,Izaberite skladište,
 Received and Accepted,Primio i prihvatio,
 Project will be accessible on the website to these users,Projekat će biti dostupan na sajtu sledećim korisnicima,
-Upload HTML,Priloži HTML,
 Services,Usluge,
 Item Cart,Korpa sa artiklima,
 Total Paid Amt,Ukupno plaćeno,
@@ -390,7 +369,6 @@
 Employee Advance,Napredak Zaposlenog,
 Warehouse and Reference,Skladište i veza,
 {0} {1}: Account {2} is inactive,{0} {1}: Nalog {2} je neaktivan,
-Fiscal Year {0} not found,Fiskalna godina {0} nije pronađena,
 No Remarks,Nema napomene,
 Purchase Receipt Message,Poruka u Prijemu robe,
 Taxes and Charges Deducted,Umanjeni porezi i naknade,
@@ -427,7 +405,6 @@
 Closing Date,Datum zatvaranja,
 Cheque/Reference Date,Datum izvoda,
 Planned Qty,Planirana količina,
-Payment Date,Datum plaćanja,
 Additional Details,Dodatni detalji,
 Create Chart Of Accounts Based On,Kreiraj kontni plan prema,
 You can not change rate if BOM mentioned agianst any item,Не можете променити цену ако постоји Саставница за било коју ставку.
@@ -440,8 +417,6 @@
 Add Employees,Dodaj Zaposlenog,
 Setting up Employees,Podešavanja Zaposlenih,
 Warehouse not found in the system,Skladište nije pronađeno u sistemu,
-Attendance for employee {0} is already marked for this day,Prisustvo zaposlenog {0} је već označeno za ovaj dan,
-Employee relieved on {0} must be set as 'Left',"Zaposleni smijenjen na {0} mora biti označen kao ""Napustio"""
  Shipping Bill Number,Broj isporuke,
 Lab Test Report,Izvještaj labaratorijskog testa,
 You cannot credit and debit same account at the same time,Не можете кредитирати и дебитовати исти налог у исто време.
@@ -475,17 +450,14 @@
 Reserved for manufacturing,Rezervisana za proizvodnju,
 Pricing Rule Help,Pravilnik za cijene pomoć
 Ageing Range 2,Opseg dospijeća 2,
-Employee Benefits,Primanja Zaposlenih,
 POS Item Group,POS Vrsta artikala,
 Lead,Lead,
-Employee Settings,Podešavanja zaposlenih,
 View All Products,Pogledajte sve proizvode,
 Patient Medical Record,Medicinski karton pacijenta,
 Batch,Serija,
 Purchase Receipt,Prijem robe,
 Warranty Period (in days),Garantni rok (u danima)
 Customer database.,Korisnička baza podataka,
-Attendance Date,Datum prisustva,
 Notify Employee,Obavijestiti Zaposlenog,
 User ID not set for Employee {0},Korisnički ID nije podešen za Zaposlenog {0}
 Stock Projected Qty,Projektovana količina na zalihama,
@@ -507,7 +479,6 @@
 Task,Zadatak,
 Add / Edit Prices,Dodaj / Izmijeni cijene,
 Item Prices,Cijene artikala,
-Salary Component,Компонента плате
 Customer's Purchase Order Date,Datum porudžbenice kupca,
 Country of Origin,Zemlja porijekla,
 Please select Employee Record first.,Molimo izaberite registar Zaposlenih prvo,
@@ -520,7 +491,6 @@
 {0} against Bill {1} dated {2},{0} veza sa računom {1} na datum {2}
 You are not authorized to set Frozen value,Немате дозволу да постављате замрзнуту вредност
 Requested Items To Be Ordered,Tražene stavke za isporuku,
-Unmarked Attendance,Neobilježeno prisustvo,
 Sales Order {0} is not submitted,Prodajni nalog {0} nije potvrđen,
 Default Material Request Type,Podrazumijevani zahtjev za tip materijala,
 Sales Pipeline,Prodajna linija,
@@ -580,7 +550,6 @@
 Warning: Another {0} # {1} exists against stock entry {2},Upozorenje: Još jedan  {0} # {1} postoji u vezanom Unosu zaliha {2}
 Suplier,Dobavljač
 Has Serial No,Ima serijski broj,
-Employee {0} on Half day on {1},Zaposleni {0} na pola radnog vremena {1}
 Difference Amount (Company Currency),Razlika u iznosu (Valuta)
 Add Serial No,Dodaj serijski broj,
 Company and Accounts,Preduzeće i računi,
@@ -614,7 +583,6 @@
 Customer / Item Name,Kupac / Naziv proizvoda,
 Total Billed Amount,Ukupno fakturisano,
 In Value,Prijem vrije.
-Employees Email Id,ID email Zaposlenih,
 Tree Type,Tip stabla,
 Update Rate and Availability,Izmijenite cijenu i dostupnost,
 Supplier Quotation,Ponuda dobavljača,
@@ -643,11 +611,8 @@
 Purchase Receipt Item,Stavka Prijema robe,
 Invoices,Fakture,
 Task Progress,% završenosti zadataka,
-Employee Attendance Tool,Alat za prisustvo Zaposlenih,
-Payment Days,Dana za plaćanje,
 Recruitment,Zapošljavanje,
 Taxes and Charges Calculation,Izračun Poreza,
-For Employee,Za Zaposlenog,
 Terms and Conditions Template,Uslovi i odredbe šablon,
 Change,Kusur,
 Stock Entry {0} created,Unos zaliha {0} je kreiran,
@@ -672,7 +637,6 @@
 Income Account,Račun prihoda,
 Account Balance,Knjigovodstveno stanje,
 'Expected Start Date' can not be greater than 'Expected End Date',Očekivani datum početka ne može biti veći od očekivanog datuma završetka,
-Employee Emails,Elektronska pošta Zaposlenog,
 Opening Qty,Početna količina,
 Reorder level based on Warehouse,Nivo dopune u zavisnosti od skladišta,
 To Warehouse,U skladište,
@@ -683,7 +647,6 @@
 Request for Quotation Supplier,Zahtjev za ponudu dobavljača,
 LeaderBoard,Tabla,
 Lab Test Groups,Labaratorijske grupe,
-Training Result Employee,Rezultati obuke Zaposlenih,
 Invoice Details,Detalji fakture,
 Banking and Payments,Bakarstvo i plaćanja,
 Employee Name,Ime Zaposlenog,
@@ -702,10 +665,8 @@
 Transaction reference no {0} dated {1},Broj izvoda {0} na datum {1}
 Make Sales Order,Kreiraj prodajni nalog,
 Items,Artikli,
-Employees working on a holiday,Zaposleni koji rade za vrijeme praznika,
 Allocate Payment Amount,Poveži uplaćeni iznos,
 Patient ID,ID pacijenta,
-Printed On,Datum i vrijeme štampe,
 Debit To,Zaduženje za,
 Global Settings,Globalna podešavanja,
 Make Employee,Keriraj Zaposlenog,
@@ -732,7 +693,6 @@
 Target Warehouse,Ciljno skladište,
 Delivery Note Trends,Trendovi Otpremnica,
 Default Source Warehouse,Izdajno skladište,
-"{0}: Employee email not found, hence email not sent","{0}: Email zaposlenog nije pronađena, stoga email nije poslat"
 All Warehouses,Sva skladišta,
 Difference Amount,Razlika u iznosu,
 User Remark,Korisnička napomena,
@@ -775,22 +735,18 @@
 Ageing Range 1,Opseg dospijeća 1,
 Incoming Rate,Nabavna cijena,
 Timesheets,Potrošnja vremena,
-Attendance From Date,Datum početka prisustva,
 Stock Items,Artikli na zalihama,
 New Cart,Nova korpa,
 Opening Value,Početna vrijednost,
 "Setting Events to {0}, since the Employee attached to the below Sales Persons does not have a User ID{1}","Podešavanje stanja na {0}, pošto Zaposleni koji se priključio Prodavcima nema koririsnički ID {1}"
-Import Attendance,Uvoz prisustva,
 Bank Balance,Stanje na računu,
 Employee Number,Broj Zaposlenog,
 Rate and Amount,Cijena i vrijednost sa popustom,
 'Total','Ukupno bez PDV-a'
 Total Taxes and Charges,Porez,
-No active or default Salary Structure found for employee {0} for the given dates,Nisu pronađene aktivne ili podrazumjevane strukture plate za Zaposlenog {0} za dati period,
 Supplier Part Number,Dobavljačeva šifra,
 Project Task,Projektni zadatak,
 Parent Item Group,Nadređena Vrsta artikala,
-Mark Attendance,Označi prisustvo,
 {0} created,Kreirao je korisnik {0}
 Advance Paid,Avansno plačanje,
 Projected,Projektovana količina na zalihama,
@@ -824,7 +780,6 @@
 Purchase Price List,Nabavni cjenovnik,
 Accounts Payable Summary,Pregled obaveze prema dobavljačima,
 Delivery Notes {0} must be cancelled before cancelling this Sales Order,Otpremnice {0} moraju biti otkazane prije otkazivanja prodajnog naloga,
-Total Payment,Ukupno plaćeno,
 POS Settings,POS podešavanja,
 Buying Amount,Iznos nabavke,
 Valuation Rate,Prosječna nab. cijena,
@@ -906,7 +861,6 @@
 From Customer,Od kupca,
 Maintain Stock,Vođenje zalihe,
 Sales Order Item,Pozicija prodajnog naloga,
-Attendance From Date and Attendance To Date is mandatory,Datum početka prisustva i prisustvo do danas su obavezni,
 Reserved Qty,Rezervisana kol.
 Not items found,Ništa nije pronađeno,
 Copy From Item Group,Kopiraj iz vrste artikala,
@@ -932,7 +886,6 @@
 Due Date is mandatory,Datum dospijeća je obavezan,
 Cart,Korpa,
 Stock transactions before {0} are frozen,Promjene na zalihama prije {0} su zamrznute,
-Employee {0} is not active or does not exist,Zaposleni {0} nije aktivan ili ne postoji,
 You have entered duplicate items. Please rectify and try again.,Унели сте дупликате. Молимо проверите и покушајте поново.
 Closing (Dr),Saldo (Du)
 Product Bundle Help,Sastavnica Pomoć
@@ -947,7 +900,6 @@
 Gantt Chart,Gant dijagram,
 Requested Quantity,Tražena količina,
 Chart Of Accounts Template,Templejt za kontni plan,
-Marked Attendance,Označeno prisustvo,
 Please set a default Holiday List for Employee {0} or Company {1},Molimo podesite podrazumjevanu listu praznika za Zaposlenog {0} ili Preduzeće {1}
 Pending Amount,Iznos na čekanju,
 Supplier Invoice No,Broj fakture dobavljača,
@@ -973,18 +925,15 @@
 You cannot delete Project Type 'External',"Не можете обрисати ""Спољни"" тип пројекта."
 Delivery Note,Otpremnice,
 In Words will be visible once you save the Sales Order.,U riječima će biti vidljivo tek kada sačuvate prodajni nalog.
-Show Salary Slip,Прикажи одсечак плате
 Activity Cost per Employee,Troškovi aktivnosti po zaposlenom,
 Sales Order,Prodajni nalog,
 Customer or Supplier Details,Detalji kupca ili dobavljača,
 Sell,Prodaja,
-Salary Slip of employee {0} already created for time sheet {1},Isplatna lista Zaposlenog {0} kreirana je već za raspored {1}
 Additional Discount Percentage,Dodatni procenat popusta,
 HR User,Korisnik za ljudske resure,
 Stock Reports,Izvještaji zaliha robe,
 Return Against Sales Invoice,Povraćaj u vezi sa Fakturom prodaje,
 Naming Series,Vrste dokumenta,
-Monthly Attendance Sheet,Mjesečni list prisustva,
 Stock Ledger,Skladišni karton,
 Sales Invoice {0} must be cancelled before cancelling this Sales Order,Faktura {0} mora biti otkazana prije otkazivanja ovog prodajnog naloga,
 New Quotations,Nove ponude,
diff --git a/erpnext/translations/sr.csv b/erpnext/translations/sr.csv
index cf32d36..c1e5eb0 100644
--- a/erpnext/translations/sr.csv
+++ b/erpnext/translations/sr.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Аутоматско понављање документа је ажурирано,
 Automotive,аутомобилски,
 Available,Доступно,
-Available Leaves,Расположиве листе,
 Available Qty,Доступно ком,
 Available Selling,Доступна продаја,
 Available for use date is required,Потребан је датум употребе,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Хуб Синц ИД,
 Human Resource,Људски ресурси,
 Human Resources,Человеческие ресурсы,
-IFSC Code,ИФСЦ код,
 IGST Amount,ИГСТ Износ,
 IP Address,ИП адреса,
 ITC Available (whether in full op part),Доступан ИТЦ (било у целокупном делу),
@@ -1666,7 +1664,6 @@
 Other,Други,
 Other Reports,Остали извештаји,
 "Other outward supplies(Nil rated,Exempted)","Остале спољне залихе (Нил, Ослобођено)",
-Others,другие,
 Out Qty,Од Кол,
 Out Value,od Вредност,
 Out of Order,Неисправно,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Укупно (без пореза),
 Total Achieved,Укупно Постигнута,
 Total Actual,Укупно Стварна,
-Total Allocated Leaves,Укупно издвојене листе,
 Total Amount,Укупан износ,
 Total Amount Credited,Укупан износ кредита,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Укупно Важећи Оптужбе у куповини потврда за ставке табели мора бити исти као и укупних пореза и накнада,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Уплоад главу писмо и лого. (Можете их уредити касније).,
 Upper Income,Горња прихода,
 Use Sandbox,Употреба Песак,
-Used Leaves,Користи Леавес,
 User,Усер,
 User ID,Кориснички ИД,
 User ID not set for Employee {0},ID пользователя не установлен Требуются {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Гарантни период (у данима),
 Auto re-order,Ауто поново реда,
 Reorder level based on Warehouse,Промени редослед ниво на основу Варехоусе,
-Will also apply for variants unless overrridden,Ће конкурисати и за варијанте осим оверрридден,
+Will also apply for variants unless overridden,Ће конкурисати и за варијанте осим оверрридден,
 Units of Measure,Мерних јединица,
 Will also apply for variants,Ће конкурисати и за варијанте,
 Serial Nos and Batches,Сериал Нос анд Пакети,
@@ -7949,12 +7944,10 @@
 Approvers,Одобривачи,
 The first Approver in the list will be set as the default Approver.,Први одобравач на листи биће постављен као подразумевани одобраватељ.,
 Shift Request Approver,Одобривач захтева за смену,
-PAN Number,ПАН број,
 Provident Fund Account,Рачун осигуравајућег фонда,
 MICR Code,МИЦР код,
 Repay unclaimed amount from salary,Отплати неискоришћени износ из плате,
 Deduction from salary,Одбитак од зараде,
-Expired Leaves,Истекло лишће,
 If this is not checked the loan by default will be considered as a Demand Loan,"Ако ово није потврђено, зајам ће се подразумевано сматрати зајмом на захтев",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Овај рачун се користи за резервирање отплате зајма од зајмопримца и за исплату зајмова зајмопримцу,
 This account is capital account which is used to allocate capital for loan disbursal account ,Овај рачун је рачун капитала који се користи за алокацију капитала за рачун за издвајање кредита,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Је обавезно,
 WhatsApp,ВхатсАпп,
 Make a call,Позивање,
+Approve,одобрити,
+Reject,Одбити,
diff --git a/erpnext/translations/sv.csv b/erpnext/translations/sv.csv
index c07fda2..8b4ab06 100644
--- a/erpnext/translations/sv.csv
+++ b/erpnext/translations/sv.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Automatisk upprepa dokument uppdaterad,
 Automotive,Fordon,
 Available,Tillgängligt,
-Available Leaves,Tillgängliga löv,
 Available Qty,Tillgång Antal,
 Available Selling,Tillgänglig försäljning,
 Available for use date is required,Tillgängligt för användning datum krävs,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub Sync ID,
 Human Resource,Personal administration,
 Human Resources,Personal Resurser,
-IFSC Code,IFSC-kod,
 IGST Amount,IGST-belopp,
 IP Address,IP-adress,
 ITC Available (whether in full op part),ITC tillgängligt (oavsett om det är fullständigt),
@@ -1666,7 +1664,6 @@
 Other,Annat,
 Other Reports,Andra rapporter,
 "Other outward supplies(Nil rated,Exempted)","Andra leveranser utifrån (noll betyg, undantagna)",
-Others,Annat,
 Out Qty,Ut antal,
 Out Value,ut Värde,
 Out of Order,Trasig,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Totalt (utan skatt),
 Total Achieved,Totalt Uppnått,
 Total Actual,Totalt Faktisk,
-Total Allocated Leaves,Totalt tilldelade blad,
 Total Amount,Totala summan,
 Total Amount Credited,Summa belopp Credited,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Totalt tillämpliga avgifter i inköpskvittot Items tabellen måste vara densamma som den totala skatter och avgifter,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Ladda upp din brevhuvud och logotyp. (Du kan redigera dem senare).,
 Upper Income,Övre inkomst,
 Use Sandbox,användning Sandbox,
-Used Leaves,Använda löv,
 User,Användare,
 User ID,användar ID,
 User ID not set for Employee {0},Användar-ID inte satt för anställd {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Garantitiden (i dagar),
 Auto re-order,Auto återbeställning,
 Reorder level based on Warehouse,Beställningsnivå baserat på Warehouse,
-Will also apply for variants unless overrridden,Kommer också att ansöka om varianter såvida inte överskriden,
+Will also apply for variants unless overridden,Kommer också att ansöka om varianter såvida inte överskriden,
 Units of Measure,Måttenheter,
 Will also apply for variants,Kommer också att ansöka om varianter,
 Serial Nos and Batches,Serienummer och partier,
@@ -7949,12 +7944,10 @@
 Approvers,Omstridda,
 The first Approver in the list will be set as the default Approver.,Den första godkännaren i listan kommer att ställas in som standard godkännare.,
 Shift Request Approver,Skiftbegäran godkännare,
-PAN Number,PAN-nummer,
 Provident Fund Account,Försäkringskassakonto,
 MICR Code,MICR-kod,
 Repay unclaimed amount from salary,Återbetala obefogat belopp från lönen,
 Deduction from salary,Avdrag från lön,
-Expired Leaves,Utgångna löv,
 If this is not checked the loan by default will be considered as a Demand Loan,Om detta inte är markerat kommer lånet som standard att betraktas som ett efterfrågelån,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Detta konto används för bokning av återbetalningar av lån från låntagaren och för utbetalning av lån till låntagaren,
 This account is capital account which is used to allocate capital for loan disbursal account ,Det här kontot är ett kapitalkonto som används för att fördela kapital för lånekonto,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Är obligatorisk,
 WhatsApp,WhatsApp,
 Make a call,Ringa ett samtal,
+Approve,Godkänna,
+Reject,Avvisa,
diff --git a/erpnext/translations/sw.csv b/erpnext/translations/sw.csv
index 243994f..fa2287c 100644
--- a/erpnext/translations/sw.csv
+++ b/erpnext/translations/sw.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Rudia tena hati iliyosasishwa,
 Automotive,Magari,
 Available,Inapatikana,
-Available Leaves,Majani Inapatikana,
 Available Qty,Uchina unaopatikana,
 Available Selling,Inapatikana Kuuza,
 Available for use date is required,Inapatikana kwa tarehe ya matumizi inahitajika,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,ID ya Usawazishaji wa Hub,
 Human Resource,Rasilimali watu,
 Human Resources,Rasilimali,
-IFSC Code,IFSC Kanuni,
 IGST Amount,IGST Kiasi,
 IP Address,Anwani ya IP,
 ITC Available (whether in full op part),ITC Inapatikana (iwe katika sehemu kamili),
@@ -1666,7 +1664,6 @@
 Other,Nyingine,
 Other Reports,Taarifa nyingine,
 "Other outward supplies(Nil rated,Exempted)","Vifaa vingine vya nje (Nilikadiriwa, Imesamehewa)",
-Others,Wengine,
 Out Qty,Nje ya Uchina,
 Out Value,Thamani ya nje,
 Out of Order,Nje ya Utaratibu,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Jumla (bila ya Kodi),
 Total Achieved,Jumla imefikia,
 Total Actual,Jumla halisi,
-Total Allocated Leaves,Jumla ya Majani yaliyowekwa,
 Total Amount,Jumla,
 Total Amount Credited,Jumla ya Kizuizi,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Malipo Yote ya Kuhitajika katika Jedwali la Vipokezi vya Ununuzi lazima lifanane na Jumla ya Kodi na Malipo,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Pakia kichwa chako na alama. (unaweza kuwahariri baadaye).,
 Upper Income,Mapato ya Juu,
 Use Sandbox,Tumia Sandbox,
-Used Leaves,Majani yaliyotumika,
 User,Mtumiaji,
 User ID,Kitambulisho cha mtumiaji,
 User ID not set for Employee {0},Kitambulisho cha mtumiaji hakiwekwa kwa Waajiriwa {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Kipindi cha udhamini (katika siku),
 Auto re-order,Rejesha upya,
 Reorder level based on Warehouse,Weka upya ngazi kulingana na Ghala,
-Will also apply for variants unless overrridden,Pia itatumika kwa vipengee isipokuwa imeingizwa,
+Will also apply for variants unless overridden,Pia itatumika kwa vipengee isipokuwa imeingizwa,
 Units of Measure,Units of Measure,
 Will also apply for variants,Pia itatumika kwa vipengee,
 Serial Nos and Batches,Serial Nos na Batches,
@@ -7949,12 +7944,10 @@
 Approvers,Waunga mkono,
 The first Approver in the list will be set as the default Approver.,Mtangazaji wa kwanza kwenye orodha atawekwa kama Mtoaji Mbadala.,
 Shift Request Approver,Ombi la Shift Liidhinishe,
-PAN Number,Nambari ya PAN,
 Provident Fund Account,Akaunti ya Mfuko wa Utoaji,
 MICR Code,Nambari ya MICR,
 Repay unclaimed amount from salary,Lipa kiasi ambacho hakijadai kutoka kwa mshahara,
 Deduction from salary,Utoaji kutoka kwa mshahara,
-Expired Leaves,Majani yaliyomalizika,
 If this is not checked the loan by default will be considered as a Demand Loan,Ikiwa hii haijakaguliwa mkopo kwa chaguo-msingi utazingatiwa kama Mkopo wa Mahitaji,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Akaunti hii inatumika kwa uhifadhi wa mikopo kutoka kwa akopaye na pia kutoa mikopo kwa akopaye,
 This account is capital account which is used to allocate capital for loan disbursal account ,Akaunti hii ni akaunti kuu ambayo hutumiwa kutenga mtaji kwa akaunti ya utoaji wa mkopo,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Ni lazima,
 WhatsApp,WhatsApp,
 Make a call,Piga simu,
+Approve,Thibitisha,
+Reject,Kataa,
diff --git a/erpnext/translations/ta.csv b/erpnext/translations/ta.csv
index d2c3dfb..6eaae34 100644
--- a/erpnext/translations/ta.csv
+++ b/erpnext/translations/ta.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,தானியங்கு திரும்ப ஆவணம் புதுப்பிக்கப்பட்டது,
 Automotive,வாகன,
 Available,கிடைக்கக்கூடிய,
-Available Leaves,கிடைக்கும் இலைகள்,
 Available Qty,கிடைக்கும் அளவு,
 Available Selling,கிடைக்கும் விற்பனை,
 Available for use date is required,உபயோகத்திற்கான தேதி கிடைக்க வேண்டும்,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,மைய ஒருங்கிணைப்பு ஐடி,
 Human Resource,மையம்  வள,
 Human Resources,மனித வளங்கள்,
-IFSC Code,IFSC கோட்,
 IGST Amount,IGST தொகை,
 IP Address,ஐபி முகவரி,
 ITC Available (whether in full op part),ஐ.டி.சி கிடைக்கிறது (முழு ஒப் பகுதியாக இருந்தாலும்),
@@ -1666,7 +1664,6 @@
 Other,வேறு,
 Other Reports,பிற அறிக்கைகள்,
 "Other outward supplies(Nil rated,Exempted)","பிற வெளிப்புற பொருட்கள் (இல்லை மதிப்பிடப்பட்டது, விலக்கு)",
-Others,மற்றவை,
 Out Qty,அளவு அவுட்,
 Out Value,அவுட் மதிப்பு,
 Out of Order,ஆர்டர் அவுட்,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),மொத்தம் (வரி இல்லாமல்),
 Total Achieved,மொத்த Achieved,
 Total Actual,உண்மையான மொத்த,
-Total Allocated Leaves,மொத்த ஒதுக்கப்பட்ட இலைகள்,
 Total Amount,மொத்த தொகை,
 Total Amount Credited,மொத்த தொகை பாராட்டப்பட்டது,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,கொள்முதல் ரசீது பொருட்கள் அட்டவணையில் மொத்த பொருந்தும் கட்டணங்கள் மொத்த வரி மற்றும் கட்டணங்கள் அதே இருக்க வேண்டும்,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,உங்கள் கடிதம் தலை மற்றும் சின்னம் பதிவேற்ற. (நீங்கள் பின்னர் அவர்களை திருத்த முடியும்).,
 Upper Income,உயர் வருமானம்,
 Use Sandbox,சாண்ட்பாக்ஸினைப் பயன்படுத்தவும்,
-Used Leaves,பயன்படுத்திய இலைகள்,
 User,பயனர்,
 User ID,பயனர் ஐடி,
 User ID not set for Employee {0},பயனர் ஐடி பணியாளர் அமைக்க{0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),உத்தரவாதத்தை காலம் (நாட்கள்),
 Auto re-order,வாகன மறு ஒழுங்கு,
 Reorder level based on Warehouse,கிடங்கில் அடிப்படையில் மறுவரிசைப்படுத்துக நிலை,
-Will also apply for variants unless overrridden,Overrridden வரை கூட வகைகளில் விண்ணப்பிக்க,
+Will also apply for variants unless overridden,Overrridden வரை கூட வகைகளில் விண்ணப்பிக்க,
 Units of Measure,அளவின் அலகுகள்,
 Will also apply for variants,கூட வகைகளில் விண்ணப்பிக்க,
 Serial Nos and Batches,சீரியல் எண்கள் மற்றும் தொகுப்புகளும்,
@@ -7949,12 +7944,10 @@
 Approvers,ஒப்புதல்கள்,
 The first Approver in the list will be set as the default Approver.,பட்டியலில் முதல் ஒப்புதல் இயல்புநிலை ஒப்புதலாக அமைக்கப்படும்.,
 Shift Request Approver,ஷிப்ட் கோரிக்கை ஒப்புதல்,
-PAN Number,பான் எண்,
 Provident Fund Account,வருங்கால வைப்பு நிதி கணக்கு,
 MICR Code,MICR குறியீடு,
 Repay unclaimed amount from salary,கோரப்படாத தொகையை சம்பளத்திலிருந்து திருப்பிச் செலுத்துங்கள்,
 Deduction from salary,சம்பளத்திலிருந்து கழித்தல்,
-Expired Leaves,காலாவதியான இலைகள்,
 If this is not checked the loan by default will be considered as a Demand Loan,"இது சரிபார்க்கப்படாவிட்டால், இயல்புநிலையாக கடன் தேவை கடனாக கருதப்படும்",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,கடன் வாங்கியவரிடமிருந்து கடன் திருப்பிச் செலுத்துவதற்கு முன்பதிவு செய்வதற்கும் கடன் வாங்கியவருக்கு கடன்களை வழங்குவதற்கும் இந்த கணக்கு பயன்படுத்தப்படுகிறது,
 This account is capital account which is used to allocate capital for loan disbursal account ,"இந்த கணக்கு மூலதன கணக்கு ஆகும், இது கடன் வழங்கல் கணக்கிற்கு மூலதனத்தை ஒதுக்க பயன்படுகிறது",
@@ -8748,3 +8741,5 @@
 Is Mandatory,அத்தியாவசியமானதாகும்,
 WhatsApp,பகிரி,
 Make a call,அழைப்பு விடுங்கள்,
+Approve,ஒப்புதல்,
+Reject,நிராகரி,
diff --git a/erpnext/translations/te.csv b/erpnext/translations/te.csv
index 228f293..d3f739a 100644
--- a/erpnext/translations/te.csv
+++ b/erpnext/translations/te.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,ఆటో రిపీట్ పత్రం నవీకరించబడింది,
 Automotive,ఆటోమోటివ్,
 Available,అందుబాటులో,
-Available Leaves,అందుబాటులో ఉన్న ఆకులు,
 Available Qty,అందుబాటులో ప్యాక్ చేసిన అంశాల,
 Available Selling,అందుబాటులో సెల్లింగ్,
 Available for use date is required,ఉపయోగ తేదీ కోసం అందుబాటులో ఉంది,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,హబ్ సమకాలీకరణ ID,
 Human Resource,మానవ వనరుల,
 Human Resources,మానవ వనరులు,
-IFSC Code,IFSC కోడ్,
 IGST Amount,IGST మొత్తం,
 IP Address,IP చిరునామా,
 ITC Available (whether in full op part),ఐటిసి అందుబాటులో ఉంది (పూర్తిస్థాయిలో ఉన్నా),
@@ -1666,7 +1664,6 @@
 Other,ఇతర,
 Other Reports,ఇతర నివేదికలు,
 "Other outward supplies(Nil rated,Exempted)","ఇతర బాహ్య సామాగ్రి (నిల్ రేట్, మినహాయింపు)",
-Others,ఇతరత్రా,
 Out Qty,ప్యాక్ చేసిన అంశాల అవుట్,
 Out Value,అవుట్ విలువ,
 Out of Order,పనిచేయటంలేదు,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),మొత్తం (పన్ను లేకుండా),
 Total Achieved,మొత్తం ఆర్జిత,
 Total Actual,యదార్థమైన మొత్తం,
-Total Allocated Leaves,మొత్తం కేటాయించిన ఆకులు,
 Total Amount,మొత్తం డబ్బు,
 Total Amount Credited,మొత్తం మొత్తంలో పొందింది,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,కొనుగోలు స్వీకరణపై అంశాలు పట్టికలో మొత్తం వర్తించే ఛార్జీలు మొత్తం పన్నులు మరియు ఆరోపణలు అదే ఉండాలి,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,మీ లేఖ తల మరియు లోగో అప్లోడ్. (మీరు తర్వాత వాటిని సవరించవచ్చు).,
 Upper Income,ఉన్నత ఆదాయపు,
 Use Sandbox,శాండ్బాక్స్ ఉపయోగించండి,
-Used Leaves,వాడిన ఆకులు,
 User,వాడుకరి,
 User ID,వినియోగదారుని గుర్తింపు,
 User ID not set for Employee {0},వాడుకరి ID ఉద్యోగి సెట్ {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),(రోజుల్లో) వారంటీ వ్యవధి,
 Auto re-order,ఆటో క్రమాన్ని,
 Reorder level based on Warehouse,వేర్హౌస్ ఆధారంగా క్రమాన్ని స్థాయి,
-Will also apply for variants unless overrridden,Overrridden తప్ప కూడా రూపాంతరాలు వర్తిస్తాయని,
+Will also apply for variants unless overridden,Overrridden తప్ప కూడా రూపాంతరాలు వర్తిస్తాయని,
 Units of Measure,యూనిట్స్ ఆఫ్ మెజర్,
 Will also apply for variants,కూడా రూపాంతరాలు వర్తిస్తాయని,
 Serial Nos and Batches,సీరియల్ Nos మరియు ఇస్తున్న,
@@ -7949,12 +7944,10 @@
 Approvers,అప్రూవర్స్,
 The first Approver in the list will be set as the default Approver.,జాబితాలోని మొదటి ఆమోదం డిఫాల్ట్ ఆమోదంగా సెట్ చేయబడుతుంది.,
 Shift Request Approver,షిఫ్ట్ అభ్యర్థన ఆమోదం,
-PAN Number,పాన్ సంఖ్య,
 Provident Fund Account,ప్రావిడెంట్ ఫండ్ ఖాతా,
 MICR Code,MICR కోడ్,
 Repay unclaimed amount from salary,క్లెయిమ్ చేయని మొత్తాన్ని జీతం నుండి తిరిగి చెల్లించండి,
 Deduction from salary,జీతం నుండి మినహాయింపు,
-Expired Leaves,గడువు ముగిసిన ఆకులు,
 If this is not checked the loan by default will be considered as a Demand Loan,ఇది తనిఖీ చేయకపోతే అప్పును అప్పుగా డిమాండ్ లోన్‌గా పరిగణిస్తారు,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,ఈ ఖాతా రుణగ్రహీత నుండి రుణ తిరిగి చెల్లించటానికి మరియు రుణగ్రహీతకు రుణాలు పంపిణీ చేయడానికి ఉపయోగించబడుతుంది,
 This account is capital account which is used to allocate capital for loan disbursal account ,"ఈ ఖాతా మూలధన ఖాతా, ఇది రుణ పంపిణీ ఖాతాకు మూలధనాన్ని కేటాయించడానికి ఉపయోగించబడుతుంది",
@@ -8748,3 +8741,5 @@
 Is Mandatory,తప్పనిసరి,
 WhatsApp,వాట్సాప్,
 Make a call,కాల్ చేయుము,
+Approve,ఆమోదించడానికి,
+Reject,తిరస్కరించు,
diff --git a/erpnext/translations/th.csv b/erpnext/translations/th.csv
index 86b8d15..a065595 100644
--- a/erpnext/translations/th.csv
+++ b/erpnext/translations/th.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,อัปเดตเอกสารซ้ำอัตโนมัติแล้ว,
 Automotive,ยานยนต์,
 Available,ที่มีจำหน่าย,
-Available Leaves,มีใบ,
 Available Qty,จำนวนที่มีจำหน่าย,
 Available Selling,ขายได้,
 Available for use date is required,ต้องมีวันที่ใช้งาน,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,รหัสการซิงค์ของ Hub,
 Human Resource,ทรัพยากรมนุษย์,
 Human Resources,ทรัพยากรบุคคล,
-IFSC Code,รหัส IFSC,
 IGST Amount,IGST Amount,
 IP Address,ที่อยู่ IP,
 ITC Available (whether in full op part),ITC ว่าง (ไม่ว่าจะอยู่ในส่วน op แบบเต็ม),
@@ -1666,7 +1664,6 @@
 Other,อื่น ๆ,
 Other Reports,รายงานอื่น ๆ,
 "Other outward supplies(Nil rated,Exempted)","วัสดุภายนอกอื่น ๆ (ไม่มีการจัดอันดับ, ยกเว้น)",
-Others,คนอื่น ๆ,
 Out Qty,ออก จำนวน,
 Out Value,ราคาออกมา,
 Out of Order,ชำรุด,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),รวม (ไม่มีภาษี),
 Total Achieved,รวมประสบความสำเร็จ,
 Total Actual,ทั้งหมดที่เกิดขึ้นจริง,
-Total Allocated Leaves,ยอดรวมใบ,
 Total Amount,รวมเป็นเงิน,
 Total Amount Credited,ยอดรวมเครดิต,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,ค่าใช้จ่ายรวมในการซื้อโต๊ะใบเสร็จรับเงินรายการที่จะต้องเป็นเช่นเดียวกับภาษีและค่าใช้จ่ายรวม,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,อัปโหลดหัวจดหมายของคุณและโลโก้ (คุณสามารถแก้ไขได้ในภายหลัง),
 Upper Income,รายได้บน,
 Use Sandbox,ใช้ Sandbox,
-Used Leaves,ใบที่ใช้แล้ว,
 User,ผู้ใช้งาน,
 User ID,รหัสผู้ใช้,
 User ID not set for Employee {0},รหัสผู้ใช้ ไม่ได้ ตั้งไว้สำหรับ พนักงาน {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),ระยะเวลารับประกัน (วัน),
 Auto re-order,Auto สั่งซื้อใหม่,
 Reorder level based on Warehouse,ระดับสั่งซื้อใหม่บนพื้นฐานของคลังสินค้า,
-Will also apply for variants unless overrridden,นอกจากนี้ยังจะใช้สำหรับสายพันธุ์เว้นแต่ overrridden,
+Will also apply for variants unless overridden,นอกจากนี้ยังจะใช้สำหรับสายพันธุ์เว้นแต่ overridden,
 Units of Measure,หน่วยวัด,
 Will also apply for variants,นอกจากนี้ยังจะใช้สำหรับสายพันธุ์,
 Serial Nos and Batches,หมายเลขและชุดเลขที่ผลิตภัณฑ์,
@@ -7949,12 +7944,10 @@
 Approvers,ผู้อนุมัติ,
 The first Approver in the list will be set as the default Approver.,ผู้อนุมัติคนแรกในรายการจะถูกตั้งเป็นผู้อนุมัติเริ่มต้น,
 Shift Request Approver,ผู้อนุมัติคำขอกะ,
-PAN Number,หมายเลข PAN,
 Provident Fund Account,บัญชีกองทุนสำรองเลี้ยงชีพ,
 MICR Code,รหัส MICR,
 Repay unclaimed amount from salary,ชำระคืนจำนวนเงินที่ไม่มีการเรียกร้องจากเงินเดือน,
 Deduction from salary,หักจากเงินเดือน,
-Expired Leaves,ใบหมดอายุ,
 If this is not checked the loan by default will be considered as a Demand Loan,หากไม่ได้ตรวจสอบเงินกู้โดยค่าเริ่มต้นจะถือว่าเป็น Demand Loan,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,บัญชีนี้ใช้สำหรับจองการชำระคืนเงินกู้จากผู้กู้และการเบิกจ่ายเงินกู้ให้กับผู้กู้,
 This account is capital account which is used to allocate capital for loan disbursal account ,บัญชีนี้เป็นบัญชีทุนที่ใช้ในการจัดสรรเงินทุนสำหรับบัญชีการเบิกจ่ายเงินกู้,
@@ -8748,3 +8741,5 @@
 Is Mandatory,เป็นข้อบังคับ,
 WhatsApp,WhatsApp,
 Make a call,ทำการโทร,
+Approve,อนุมัติ,
+Reject,ปฏิเสธ,
diff --git a/erpnext/translations/tr.csv b/erpnext/translations/tr.csv
index 78d6a79..9e916f0 100644
--- a/erpnext/translations/tr.csv
+++ b/erpnext/translations/tr.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Otomatik tekrar dokümanı güncellendi,
 Automotive,Otomotiv,
 Available,Mevcut,
-Available Leaves,Mevcut İzinler,
 Available Qty,Mevcut Miktar,
 Available Selling,Mevcut Satış,
 Available for use date is required,Kullanılabilir olacağı tarih gereklidir,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Hub Senkronizasyon Kimliği,
 Human Resource,İnsan Kaynağı,
 Human Resources,İnsan Kaynakları,
-IFSC Code,IFSC Kodu,
 IGST Amount,IGST Tutarı,
 IP Address,IP adresi,
 ITC Available (whether in full op part),ITC Müsait (tam hüküm olsun),
@@ -1666,7 +1664,6 @@
 Other,Diğer,
 Other Reports,Diğer Raporlar,
 "Other outward supplies(Nil rated,Exempted)","Diğer dış sarf malzemeleri (Nil puan, Muaf)",
-Others,Diğer,
 Out Qty,Çıkış Miktarı,
 Out Value,Çıkış Değeri,
 Out of Order,bozuk,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Toplam (Vergi hariç),
 Total Achieved,Toplam Eldeki,
 Total Actual,Gerçek Toplam,
-Total Allocated Leaves,Toplam Tahsis Edilen İzin,
 Total Amount,Toplam Tutar,
 Total Amount Credited,Kredili Toplam Tutar,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Satınalma Makbuzu Vergi Öğeleri tablosundaki toplam uygulanabilir Masraflar Toplam ve Masraflar aynı olmalıdır,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Mektup baş ve logo yükleyin. (Daha sonra bunları düzenleyebilirsiniz).,
 Upper Income,üst gelir,
 Use Sandbox,Kullanım Sandbox,
-Used Leaves,Kullanılan İzin,
 User,Kullanıcı,
 User ID,Kullanıcı kimliği,
 User ID not set for Employee {0},Çalışan {0} için kullanıcı sıfatı ayarlanmamış,
@@ -7056,7 +7051,7 @@
 Warranty Period (in days),Garanti Süresi (gün),
 Auto re-order,Otomatik Yeniden Sipariş,
 Reorder level based on Warehouse,Depo bazlı Yeniden sipariş seviyesi,
-Will also apply for variants unless overrridden,Geçersiz kılınmadığı sürece varyantlar için de geçerli olacaktır.,
+Will also apply for variants unless overridden,Geçersiz kılınmadığı sürece varyantlar için de geçerli olacaktır.,
 Units of Measure,Ölçü Birimleri,
 Will also apply for variants,Varyantlar için de geçerli olacak,
 Serial Nos and Batches,Seri No ve Batches (Parti),
@@ -7948,12 +7943,10 @@
 Approvers,Onaylayanlar,
 The first Approver in the list will be set as the default Approver.,"Listedeki ilk Onaylayan, varsayılan Onaylayan olarak ayarlanacaktır.",
 Shift Request Approver,Vardiya İsteği Onaylayıcısı,
-PAN Number,PAN Numarası,
 Provident Fund Account,İhtiyat Fonu Hesabı,
 MICR Code,MICR Kodu,
 Repay unclaimed amount from salary,Talep edilmeyen maaştan geri ödeyin,
 Deduction from salary,Maaştan kesinti,
-Expired Leaves,Süresi biten İzinler,
 If this is not checked the loan by default will be considered as a Demand Loan,"Bu kontrol reddedilirse, varsayılan olarak kredi bir Talep Kredisi olarak kabul edilecektir.",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,"Bu hesap, borçludan kredi geri ödemelerini yapmak ve ayrıca borçluya kredi vermek için kullanılır.",
 This account is capital account which is used to allocate capital for loan disbursal account ,"Bu hesap, kredi ödeme hesabına sermaye tahsis etmek için kullanılan sermaye hesabıdır.",
@@ -9005,3 +8998,5 @@
 Is Mandatory,Zorunludur,
 WhatsApp,WhatsApp,
 Make a call,Arama yap,
+Approve,Onayla,
+Reject,Reddet,
diff --git a/erpnext/translations/uk.csv b/erpnext/translations/uk.csv
index 3ad588c..8d1fb04 100644
--- a/erpnext/translations/uk.csv
+++ b/erpnext/translations/uk.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Автоматичний повторення документа оновлено,
 Automotive,Автомобільний,
 Available,наявний,
-Available Leaves,Доступні листи,
 Available Qty,Доступна к-сть,
 Available Selling,Доступні продажі,
 Available for use date is required,Необхідна дата для використання,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Ідентифікатор концентратора синхронізації,
 Human Resource,Людський ресурс,
 Human Resources,Кадри,
-IFSC Code,IFSC Code,
 IGST Amount,Сума IGST,
 IP Address,IP-адреса,
 ITC Available (whether in full op part),Доступний ITC (будь то в повній частині,
@@ -1666,7 +1664,6 @@
 Other,Інший,
 Other Reports,Інші звіти,
 "Other outward supplies(Nil rated,Exempted)","Інші зовнішні поставки (з нульовою оцінкою, звільнено)",
-Others,Інші,
 Out Qty,Розхід у к-сті,
 Out Value,Розхід у Сумі,
 Out of Order,Вийшов з ладу,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Усього (без податку),
 Total Achieved,Всього Виконано,
 Total Actual,Загальний фактичний,
-Total Allocated Leaves,Усього виділених листів,
 Total Amount,Загалом,
 Total Amount Credited,Загальна сума кредитується,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,"Всього Застосовуються збори в таблиці Purchase квитанцій Елементів повинні бути такими ж, як всі податки і збори",
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Відвантажити ваш фірмовий заголовок та логотип. (Ви зможете відредагувати їх пізніше).,
 Upper Income,Верхня прибуток,
 Use Sandbox,Використання Пісочниця,
-Used Leaves,Використовувані листи,
 User,Користувач,
 User ID,ідентифікатор користувача,
 User ID not set for Employee {0},Ідентифікатор користувача не встановлений Employee {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Гарантійний термін (в днях),
 Auto re-order,Авто-дозамовлення,
 Reorder level based on Warehouse,Рівень перезамовлення по складу,
-Will also apply for variants unless overrridden,"Буде також застосовуватися для варіантів, якщо не перевказано",
+Will also apply for variants unless overridden,"Буде також застосовуватися для варіантів, якщо не перевказано",
 Units of Measure,одиниці виміру,
 Will also apply for variants,Буде також застосовуватися для варіантів,
 Serial Nos and Batches,Серійні номери і Порції,
@@ -7949,12 +7944,10 @@
 Approvers,Схвалювачі,
 The first Approver in the list will be set as the default Approver.,Перший затверджувач у списку буде встановлений як затверджувач за замовчуванням.,
 Shift Request Approver,Затверджувач запиту на зміну,
-PAN Number,Номер PAN,
 Provident Fund Account,Рахунок забезпеченого фонду,
 MICR Code,Кодекс MICR,
 Repay unclaimed amount from salary,Повернути незатребувану суму із заробітної плати,
 Deduction from salary,Відрахування із зарплати,
-Expired Leaves,Листя закінчилися,
 If this is not checked the loan by default will be considered as a Demand Loan,"Якщо це не позначено, позика за замовчуванням буде розглядатися як позика на вимогу",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,"Цей рахунок використовується для бронювання виплат позики у позичальника, а також для видачі позик позичальнику",
 This account is capital account which is used to allocate capital for loan disbursal account ,"Цей рахунок є рахунком капіталу, який використовується для розподілу капіталу на рахунок виплати позики",
@@ -8748,3 +8741,5 @@
 Is Mandatory,Обов’язковий,
 WhatsApp,WhatsApp,
 Make a call,Зроби дзвінок,
+Approve,Затвердити,
+Reject,відхиляти,
diff --git a/erpnext/translations/ur.csv b/erpnext/translations/ur.csv
index c5610f0..649c1c7 100644
--- a/erpnext/translations/ur.csv
+++ b/erpnext/translations/ur.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,خود بخود دستاویز کو اپ ڈیٹ کیا,
 Automotive,آٹوموٹو,
 Available,دستیاب,
-Available Leaves,دستیاب پتیوں,
 Available Qty,دستیاب مقدار,
 Available Selling,دستیاب فروخت,
 Available for use date is required,استعمال کی تاریخ کے لئے دستیاب ہے,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,حب ہم آہنگی کی شناخت,
 Human Resource,انسانی وسائل,
 Human Resources,انسانی وسائل,
-IFSC Code,IFSC کوڈ,
 IGST Amount,IGST رقم,
 IP Address,IP پتہ,
 ITC Available (whether in full op part),آئی ٹی سی دستیاب ہے (چاہے وہ پوری طرح سے ہو),
@@ -1666,7 +1664,6 @@
 Other,دیگر,
 Other Reports,دیگر رپورٹوں,
 "Other outward supplies(Nil rated,Exempted)",دیگر ظاہری رسد (نیل ریٹیڈ ، مستثنیٰ),
-Others,دیگر,
 Out Qty,مقدار باہر,
 Out Value,آؤٹ ویلیو,
 Out of Order,حکم سے باہر,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),کل (ٹیکس کے بغیر),
 Total Achieved,کل حاصل کیا,
 Total Actual,اصل کل,
-Total Allocated Leaves,کل مختص شدہ پتیوں,
 Total Amount,کل رقم,
 Total Amount Credited,کریڈٹ کل رقم,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,خریداری کی رسید اشیا ٹیبل میں تمام قابل اطلاق چارجز کل ٹیکس اور الزامات طور پر ایک ہی ہونا چاہیے,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,اپنے خط سر اور علامت (لوگو). (آپ کو بعد ان میں ترمیم کر سکتے ہیں).,
 Upper Income,بالائی آمدنی,
 Use Sandbox,سینڈباکس استعمال,
-Used Leaves,استعمال شدہ پتیوں,
 User,صارف,
 User ID,صارف کی شناخت,
 User ID not set for Employee {0},صارف ID ملازم کے لئے مقرر نہیں {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),(دن میں) وارنٹی مدت,
 Auto re-order,آٹو دوبارہ آرڈر,
 Reorder level based on Warehouse,گودام کی بنیاد پر ترتیب کی سطح کو منتخب,
-Will also apply for variants unless overrridden,overrridden جب تک بھی مختلف حالتوں کے لئے لاگو ہوں گے,
+Will also apply for variants unless overridden,overridden جب تک بھی مختلف حالتوں کے لئے لاگو ہوں گے,
 Units of Measure,پیمائش کی اکائیوں,
 Will also apply for variants,بھی مختلف حالتوں کے لئے لاگو ہوں گے,
 Serial Nos and Batches,سیریل نمبر اور بیچوں,
@@ -7949,12 +7944,10 @@
 Approvers,تنازعہ,
 The first Approver in the list will be set as the default Approver.,فہرست میں پہلا منظور نامہ پہلے سے طے شدہ منظوری کے طور پر مقرر کیا جائے گا۔,
 Shift Request Approver,شفٹ کی درخواست منظور کریں,
-PAN Number,پین نمبر,
 Provident Fund Account,پروویڈنٹ فنڈ اکاؤنٹ,
 MICR Code,ایم آئی سی آر کوڈ,
 Repay unclaimed amount from salary,تنخواہ سے غیر دعویدار رقم واپس کریں,
 Deduction from salary,تنخواہ سے کٹوتی,
-Expired Leaves,ختم شدہ پتے,
 If this is not checked the loan by default will be considered as a Demand Loan,اگر اس کی جانچ نہیں کی گئی تو قرض کو بطور ڈیفانٹ لون سمجھا جائے گا,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,یہ اکاؤنٹ قرض لینے والے سے قرض کی واپسیوں کی بکنگ اور قرض لینے والے کو قرضوں کی تقسیم کے لئے استعمال ہوتا ہے,
 This account is capital account which is used to allocate capital for loan disbursal account ,یہ کھاتہ دارالحکومت کا کھاتہ ہے جو قرض تقسیم کے اکاؤنٹ کے لئے سرمایہ مختص کرنے کے لئے استعمال ہوتا ہے,
@@ -8748,3 +8741,5 @@
 Is Mandatory,لازمی ہے,
 WhatsApp,واٹس ایپ,
 Make a call,بنائیں ایک کال,
+Approve,منظور کریں,
+Reject,مسترد,
diff --git a/erpnext/translations/uz.csv b/erpnext/translations/uz.csv
index a3fc3f4..5ca51cc 100644
--- a/erpnext/translations/uz.csv
+++ b/erpnext/translations/uz.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Avtomatik qayta-qayta hujjat yangilandi,
 Automotive,Avto,
 Available,Mavjud,
-Available Leaves,Mavjud barglar,
 Available Qty,Mavjud Miqdor,
 Available Selling,Sotuvga tayyor,
 Available for use date is required,Foydalanish uchun mavjud bo&#39;lgan sana talab qilinadi,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,Uyadagi sinxronlash identifikatori,
 Human Resource,Inson resursi,
 Human Resources,Kadrlar bo&#39;limi,
-IFSC Code,IFSC kodi,
 IGST Amount,IGST miqdori,
 IP Address,IP manzili,
 ITC Available (whether in full op part),ITC mavjud (to&#39;liq holatda bo&#39;lsin),
@@ -1666,7 +1664,6 @@
 Other,Boshqa,
 Other Reports,Boshqa hisobotlar,
 "Other outward supplies(Nil rated,Exempted)","Boshqa tashqi etkazib berish (Nil baholanmagan, ozod qilingan)",
-Others,Boshqalar,
 Out Qty,Miqdori,
 Out Value,Chiqish qiymati,
 Out of Order,Tartibsiz,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Hammasi bo&#39;lib (soliqsiz),
 Total Achieved,Jami erishildi,
 Total Actual,Jami haqiqiy,
-Total Allocated Leaves,Jami ajratilgan barglar,
 Total Amount,Umumiy hisob,
 Total Amount Credited,Jami kredit miqdori,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Buyurtma olish bo&#39;yicha ma&#39;lumotlar jamlanmasi jami soliqlar va yig&#39;imlar bilan bir xil bo&#39;lishi kerak,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Sizning xat boshingizni va logotipingizni yuklang. (keyinchalik ularni tahrirlashingiz mumkin).,
 Upper Income,Yuqori daromad,
 Use Sandbox,Sandboxdan foydalaning,
-Used Leaves,Ishlatilgan barglar,
 User,Foydalanuvchi,
 User ID,foydalanuvchi IDsi,
 User ID not set for Employee {0},Foydalanuvchining identifikatori {0} xizmatdoshiga o&#39;rnatilmagan,
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Kafolat muddati (kunlar),
 Auto re-order,Avtomatik buyurtma,
 Reorder level based on Warehouse,Qoidalarga asoslangan qayta tartiblash,
-Will also apply for variants unless overrridden,"Variantlar uchun ham qo&#39;llanilmaydi, agar bekor qilinsa",
+Will also apply for variants unless overridden,"Variantlar uchun ham qo&#39;llanilmaydi, agar bekor qilinsa",
 Units of Measure,O&#39;lchov birliklari,
 Will also apply for variants,"Shuningdek, variantlar uchun ham qo&#39;llaniladi",
 Serial Nos and Batches,Seriya nos va paketlar,
@@ -7949,12 +7944,10 @@
 Approvers,Qarama-qarshilik,
 The first Approver in the list will be set as the default Approver.,Ro&#39;yxatdagi birinchi Approver standart Approver sifatida o&#39;rnatiladi.,
 Shift Request Approver,Shift so&#39;rovini tasdiqlovchi,
-PAN Number,PAN raqami,
 Provident Fund Account,Provayder fondining hisobvarag&#39;i,
 MICR Code,MICR kodi,
 Repay unclaimed amount from salary,Talab qilinmagan miqdorni ish haqidan qaytaring,
 Deduction from salary,Ish haqidan ushlab qolish,
-Expired Leaves,Muddati o&#39;tgan barglar,
 If this is not checked the loan by default will be considered as a Demand Loan,"Agar bu tekshirilmasa, sukut bo&#39;yicha qarz talabga javob beradigan kredit sifatida qabul qilinadi",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Ushbu hisob qarz oluvchidan kreditni to&#39;lashni bron qilish va qarz oluvchiga qarz berish uchun ishlatiladi,
 This account is capital account which is used to allocate capital for loan disbursal account ,"Ushbu hisob kapital hisobvarag&#39;i bo&#39;lib, u ssudani to&#39;lash hisobiga kapital ajratish uchun ishlatiladi",
@@ -8748,3 +8741,5 @@
 Is Mandatory,Majburiy,
 WhatsApp,WhatsApp,
 Make a call,Qo&#39;ng&#39;iroq qiling,
+Approve,Tasdiqlang,
+Reject,Rad etish,
diff --git a/erpnext/translations/vi.csv b/erpnext/translations/vi.csv
index 10bc92a..7a005fa 100644
--- a/erpnext/translations/vi.csv
+++ b/erpnext/translations/vi.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,Tự động cập nhật tài liệu được cập nhật,
 Automotive,Ô tô,
 Available,Khả dụng,
-Available Leaves,Lá có sẵn,
 Available Qty,Số lượng có sẵn,
 Available Selling,Bán có sẵn,
 Available for use date is required,Có sẵn cho ngày sử dụng là bắt buộc,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,ID đồng bộ hóa của Hub,
 Human Resource,Nguồn nhân lực,
 Human Resources,Nhân sự,
-IFSC Code,Mã IFSC,
 IGST Amount,Lượng IGST,
 IP Address,Địa chỉ IP,
 ITC Available (whether in full op part),ITC Có sẵn (cho dù trong phần op đầy đủ),
@@ -1666,7 +1664,6 @@
 Other,Khác,
 Other Reports,Báo cáo khác,
 "Other outward supplies(Nil rated,Exempted)","Các nguồn cung bên ngoài khác (Không được xếp hạng, Được miễn)",
-Others,Các thông tin khác,
 Out Qty,Số lượng ra,
 Out Value,Giá trị hiện,
 Out of Order,Out of Order,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),Tổng (Không Thuế),
 Total Achieved,Tổng số đã đạt được,
 Total Actual,Tổng số thực tế,
-Total Allocated Leaves,Tổng số lá được phân bổ,
 Total Amount,Tổng số,
 Total Amount Credited,Tổng số tiền được ghi có,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,Tổng phí tại biên lai mua các mẫu hàng phải giống như tổng các loại thuế và phí,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,Tải lên tiêu đề trang và logo. (Bạn có thể chỉnh sửa chúng sau này).,
 Upper Income,Thu nhập trên,
 Use Sandbox,sử dụng Sandbox,
-Used Leaves,Lá đã qua sử dụng,
 User,Người dùng,
 User ID,ID người dùng,
 User ID not set for Employee {0},ID người dùng không thiết lập cho nhân viên {0},
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),Thời gian bảo hành (trong...ngày),
 Auto re-order,Auto lại trật tự,
 Reorder level based on Warehouse,mức đèn đỏ mua vật tư (phải bổ xung hoặc đặt mua thêm),
-Will also apply for variants unless overrridden,Cũng sẽ được áp dụng cho các biến thể trừ phần bị ghi đèn,
+Will also apply for variants unless overridden,Cũng sẽ được áp dụng cho các biến thể trừ phần bị ghi đèn,
 Units of Measure,Đơn vị đo lường,
 Will also apply for variants,Cũng sẽ được áp dụng cho các biến thể,
 Serial Nos and Batches,Số hàng loạt và hàng loạt,
@@ -7949,12 +7944,10 @@
 Approvers,Người phê duyệt,
 The first Approver in the list will be set as the default Approver.,Người phê duyệt đầu tiên trong danh sách sẽ được đặt làm Người phê duyệt mặc định.,
 Shift Request Approver,Người phê duyệt yêu cầu thay đổi,
-PAN Number,Số PAN,
 Provident Fund Account,Tài khoản Quỹ cấp,
 MICR Code,Mã MICR,
 Repay unclaimed amount from salary,Hoàn trả số tiền chưa nhận được từ tiền lương,
 Deduction from salary,Khấu trừ lương,
-Expired Leaves,Lá hết hạn,
 If this is not checked the loan by default will be considered as a Demand Loan,"Nếu điều này không được kiểm tra, khoản vay mặc định sẽ được coi là Khoản vay không kỳ hạn",
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,Tài khoản này được sử dụng để hoàn trả khoản vay từ người đi vay và cũng để giải ngân các khoản vay cho người vay,
 This account is capital account which is used to allocate capital for loan disbursal account ,Tài khoản này là tài khoản vốn dùng để cấp vốn cho tài khoản giải ngân cho vay,
@@ -8748,3 +8741,5 @@
 Is Mandatory,Bắt buộc,
 WhatsApp,WhatsApp,
 Make a call,Thực hiện cuộc gọi,
+Approve,Tán thành,
+Reject,Từ chối,
diff --git a/erpnext/translations/zh-TW.csv b/erpnext/translations/zh-TW.csv
index 752c1f5..0f76e97 100644
--- a/erpnext/translations/zh-TW.csv
+++ b/erpnext/translations/zh-TW.csv
@@ -712,7 +712,6 @@
 Account {0} does not belong to company: {1},科目{0}不屬於公司:{1}
 Abbreviation already used for another company,另一家公司已使用此縮寫
 Default Customer Group,預設客戶群組
-IFSC Code,IFSC代碼
 "If disable, 'Rounded Total' field will not be visible in any transaction",如果禁用,“圓角總計”字段將不可見的任何交易
 Operating Cost,營業成本
 Produced Items,生產物品
@@ -2965,7 +2964,7 @@
 Code {0} already exist,代碼{0}已經存在
 Sales orders are not available for production,銷售訂單不可用於生產
 Fixed Asset Depreciation Settings,固定資產折舊設置
-Will also apply for variants unless overrridden,同時將申請變種,除非overrridden,
+Will also apply for variants unless overridden,同時將申請變種,除非overridden,
 Advances,進展
 Manufacture against Material Request,對製造材料要求
 Assessment Group: ,評估組:
@@ -4144,7 +4143,6 @@
 Finance Book Id,金融書籍ID,
 Safety Stock,安全庫存
 Healthcare Settings,醫療設置
-Total Allocated Leaves,總分配的葉子
 Progress % for a task cannot be more than 100.,為任務進度百分比不能超過100個。
 Before reconciliation,調整前
 Taxes and Charges Added (Company Currency),稅收和收費上架(公司貨幣)
@@ -4523,7 +4521,6 @@
 Settings for website homepage,對網站的主頁設置
 {0} is on hold till {1},{0}一直保持到{1}
 RFQs are not allowed for {0} due to a scorecard standing of {1},由於{1}的記分卡,{0}不允許使用RFQ,
-Used Leaves,使用的葉子
 Link Options,鏈接選項
 Total Amount {0},總金額{0}
 Invalid attribute {0} {1},無效的屬性{0} {1}
@@ -4654,7 +4651,6 @@
 Contact Desc,聯絡倒序
 Send regular summary reports via Email.,使用電子郵件發送定期匯總報告。
 Please set default account in Expense Claim Type {0},請報銷類型設置默認科目{0}
-Available Leaves,可用的葉子
 Student Name,學生姓名
 Item Manager,項目經理
 Payroll Payable,應付職工薪酬
@@ -5975,3 +5971,4 @@
 Payment Gateway,支付網關
 Address and Contacts,地址和聯絡方式
 Plan Name,計劃名稱
+Reject,拒絕
diff --git a/erpnext/translations/zh.csv b/erpnext/translations/zh.csv
index bb30bd4..cf89dc6 100644
--- a/erpnext/translations/zh.csv
+++ b/erpnext/translations/zh.csv
@@ -286,7 +286,6 @@
 Auto repeat document updated,自动重复文件更新,
 Automotive,汽车,
 Available,可用的,
-Available Leaves,可用休假天数,
 Available Qty,可用数量,
 Available Selling,可用销售,
 Available for use date is required,需要使用可用日期,
@@ -1122,7 +1121,6 @@
 Hub Sync ID,集线器同步ID,
 Human Resource,人力资源,
 Human Resources,人力资源,
-IFSC Code,IFSC代码,
 IGST Amount,IGST金额,
 IP Address,IP地址,
 ITC Available (whether in full op part),ITC可用(无论是全部操作部分),
@@ -1666,7 +1664,6 @@
 Other,其他,
 Other Reports,其他报表,
 "Other outward supplies(Nil rated,Exempted)",其他外向供应(未评级,豁免),
-Others,他人,
 Out Qty,发出数量,
 Out Value,输出值,
 Out of Order,乱序,
@@ -2812,7 +2809,6 @@
 Total (Without Tax),总计(不含税),
 Total Achieved,总体上实现的,
 Total Actual,实际总和,
-Total Allocated Leaves,合计已分配休假天数,
 Total Amount,总金额,
 Total Amount Credited,记入贷方的总金额,
 Total Applicable Charges in Purchase Receipt Items table must be same as Total Taxes and Charges,基于采购收货单信息计算的总税费必须与采购单(单头)的总税费一致,
@@ -2922,7 +2918,6 @@
 Upload your letter head and logo. (you can edit them later).,上传你的信头和logo。(您可以在以后对其进行编辑)。,
 Upper Income,高收入,
 Use Sandbox,使用沙盒,
-Used Leaves,已休假(天数),
 User,用户,
 User ID,用户ID,
 User ID not set for Employee {0},员工设置{0}为设置用户ID,
@@ -7057,7 +7052,7 @@
 Warranty Period (in days),保修期限(天数),
 Auto re-order,自动重订货,
 Reorder level based on Warehouse,根据仓库订货点水平,
-Will also apply for variants unless overrridden,除非手动指定,否则会同时应用于变体,
+Will also apply for variants unless overridden,除非手动指定,否则会同时应用于变体,
 Units of Measure,计量单位,
 Will also apply for variants,会同时应用于变体,
 Serial Nos and Batches,序列号和批号,
@@ -7949,12 +7944,10 @@
 Approvers,批准人,
 The first Approver in the list will be set as the default Approver.,列表中的第一个批准人将被设置为默认批准人。,
 Shift Request Approver,轮班请求批准人,
-PAN Number,PAN号码,
 Provident Fund Account,公积金帐户,
 MICR Code,MICR代码,
 Repay unclaimed amount from salary,从工资中偿还无人认领的金额,
 Deduction from salary,从工资中扣除,
-Expired Leaves,过期的叶子,
 If this is not checked the loan by default will be considered as a Demand Loan,如果未选中此选项,则默认情况下该贷款将被视为需求贷款,
 This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower,此帐户用于预订借款人的还款,也用于向借款人发放贷款,
 This account is capital account which is used to allocate capital for loan disbursal account ,该帐户是资本帐户,用于为贷款支付帐户分配资本,
@@ -8748,3 +8741,6 @@
 Is Mandatory,是强制性的,
 WhatsApp,WhatsApp的,
 Make a call,打个电话,
+Approve,同意,
+Reject,拒绝,
+Stock,库存,
diff --git a/erpnext/translations/zh_tw.csv b/erpnext/translations/zh_tw.csv
index 75157f0..8ecbaaa 100644
--- a/erpnext/translations/zh_tw.csv
+++ b/erpnext/translations/zh_tw.csv
@@ -7485,7 +7485,7 @@
 Warranty Period (in days),保修期限(天數),
 Auto re-order,自動重新排序,
 Reorder level based on Warehouse,根據倉庫訂貨點水平,
-Will also apply for variants unless overrridden,同時將申請變種,除非overrridden,
+Will also apply for variants unless overridden,同時將申請變種,除非overridden,
 Units of Measure,測量的單位,
 Will also apply for variants,同時將申請變種,
 Serial Nos and Batches,序列號和批號,
diff --git a/erpnext/utilities/product.py b/erpnext/utilities/product.py
index e967f70..7897c15 100644
--- a/erpnext/utilities/product.py
+++ b/erpnext/utilities/product.py
@@ -2,93 +2,12 @@
 # License: GNU General Public License v3. See license.txt
 
 import frappe
-from frappe.utils import cint, flt, fmt_money, getdate, nowdate
+from frappe.utils import cint, flt, fmt_money
 
 from erpnext.accounts.doctype.pricing_rule.pricing_rule import get_pricing_rule_for_item
-from erpnext.stock.doctype.batch.batch import get_batch_qty
-from erpnext.stock.doctype.warehouse.warehouse import get_child_warehouses
 
 
-def get_web_item_qty_in_stock(item_code, item_warehouse_field, warehouse=None):
-	in_stock, stock_qty = 0, ""
-	template_item_code, is_stock_item = frappe.db.get_value(
-		"Item", item_code, ["variant_of", "is_stock_item"]
-	)
-
-	if not warehouse:
-		warehouse = frappe.db.get_value("Website Item", {"item_code": item_code}, item_warehouse_field)
-
-	if not warehouse and template_item_code and template_item_code != item_code:
-		warehouse = frappe.db.get_value(
-			"Website Item", {"item_code": template_item_code}, item_warehouse_field
-		)
-
-	if warehouse and frappe.get_cached_value("Warehouse", warehouse, "is_group") == 1:
-		warehouses = get_child_warehouses(warehouse)
-	else:
-		warehouses = [warehouse] if warehouse else []
-
-	total_stock = 0.0
-	if warehouses:
-		for warehouse in warehouses:
-			stock_qty = frappe.db.sql(
-				"""
-				select GREATEST(S.actual_qty - S.reserved_qty - S.reserved_qty_for_production - S.reserved_qty_for_sub_contract, 0) / IFNULL(C.conversion_factor, 1)
-				from tabBin S
-				inner join `tabItem` I on S.item_code = I.Item_code
-				left join `tabUOM Conversion Detail` C on I.sales_uom = C.uom and C.parent = I.Item_code
-				where S.item_code=%s and S.warehouse=%s""",
-				(item_code, warehouse),
-			)
-
-			if stock_qty:
-				total_stock += adjust_qty_for_expired_items(item_code, stock_qty, warehouse)
-
-		in_stock = total_stock > 0 and 1 or 0
-
-	return frappe._dict(
-		{"in_stock": in_stock, "stock_qty": total_stock, "is_stock_item": is_stock_item}
-	)
-
-
-def adjust_qty_for_expired_items(item_code, stock_qty, warehouse):
-	batches = frappe.get_all("Batch", filters=[{"item": item_code}], fields=["expiry_date", "name"])
-	expired_batches = get_expired_batches(batches)
-	stock_qty = [list(item) for item in stock_qty]
-
-	for batch in expired_batches:
-		if warehouse:
-			stock_qty[0][0] = max(0, stock_qty[0][0] - get_batch_qty(batch, warehouse))
-		else:
-			stock_qty[0][0] = max(0, stock_qty[0][0] - qty_from_all_warehouses(get_batch_qty(batch)))
-
-		if not stock_qty[0][0]:
-			break
-
-	return stock_qty[0][0] if stock_qty else 0
-
-
-def get_expired_batches(batches):
-	"""
-	:param batches: A list of dict in the form [{'expiry_date': datetime.date(20XX, 1, 1), 'name': 'batch_id'}, ...]
-	"""
-	return [b.name for b in batches if b.expiry_date and b.expiry_date <= getdate(nowdate())]
-
-
-def qty_from_all_warehouses(batch_info):
-	"""
-	:param batch_info: A list of dict in the form [{u'warehouse': u'Stores - I', u'qty': 0.8}, ...]
-	"""
-	qty = 0
-	for batch in batch_info:
-		qty = qty + batch.qty
-
-	return qty
-
-
-def get_price(item_code, price_list, customer_group, company, qty=1):
-	from erpnext.e_commerce.shopping_cart.cart import get_party
-
+def get_price(item_code, price_list, customer_group, company, qty=1, party=None):
 	template_item_code = frappe.db.get_value("Item", item_code, "variant_of")
 
 	if price_list:
@@ -106,7 +25,6 @@
 			)
 
 		if price:
-			party = get_party()
 			pricing_rule_dict = frappe._dict(
 				{
 					"item_code": item_code,
@@ -187,16 +105,62 @@
 			return price_obj
 
 
-def get_non_stock_item_status(item_code, item_warehouse_field):
-	# if item is a product bundle, check if its bundle items are in stock
-	if frappe.db.exists("Product Bundle", item_code):
-		items = frappe.get_doc("Product Bundle", item_code).get_all_children()
-		bundle_warehouse = frappe.db.get_value(
-			"Website Item", {"item_code": item_code}, item_warehouse_field
+def get_item_codes_by_attributes(attribute_filters, template_item_code=None):
+	items = []
+
+	for attribute, values in attribute_filters.items():
+		attribute_values = values
+
+		if not isinstance(attribute_values, list):
+			attribute_values = [attribute_values]
+
+		if not attribute_values:
+			continue
+
+		wheres = []
+		query_values = []
+		for attribute_value in attribute_values:
+			wheres.append("( attribute = %s and attribute_value = %s )")
+			query_values += [attribute, attribute_value]
+
+		attribute_query = " or ".join(wheres)
+
+		if template_item_code:
+			variant_of_query = "AND t2.variant_of = %s"
+			query_values.append(template_item_code)
+		else:
+			variant_of_query = ""
+
+		query = """
+			SELECT
+				t1.parent
+			FROM
+				`tabItem Variant Attribute` t1
+			WHERE
+				1 = 1
+				AND (
+					{attribute_query}
+				)
+				AND EXISTS (
+					SELECT
+						1
+					FROM
+						`tabItem` t2
+					WHERE
+						t2.name = t1.parent
+						{variant_of_query}
+				)
+			GROUP BY
+				t1.parent
+			ORDER BY
+				NULL
+		""".format(
+			attribute_query=attribute_query, variant_of_query=variant_of_query
 		)
-		return all(
-			get_web_item_qty_in_stock(d.item_code, item_warehouse_field, bundle_warehouse).in_stock
-			for d in items
-		)
-	else:
-		return 1
+
+		item_codes = set([r[0] for r in frappe.db.sql(query, query_values)])
+		items.append(item_codes)
+
+	res = list(set.intersection(*items))
+
+	return res
diff --git a/erpnext/www/all-products/__init__.py b/erpnext/www/all-products/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/www/all-products/__init__.py
+++ /dev/null
diff --git a/erpnext/www/all-products/index.html b/erpnext/www/all-products/index.html
deleted file mode 100644
index 04fc74c..0000000
--- a/erpnext/www/all-products/index.html
+++ /dev/null
@@ -1,51 +0,0 @@
-{% from "erpnext/templates/includes/macros.html" import attribute_filter_section, field_filter_section, discount_range_filters %}
-{% extends "templates/web.html" %}
-
-{% block title %}{{ _('All Products') }}{% endblock %}
-{% block header %}
-<div class="mb-6">{{ _('All Products') }}</div>
-{% endblock header %}
-
-{% block page_content %}
-<div class="row">
-	<!-- Items section -->
-	<div id="product-listing" class="col-12 order-2 col-md-9 order-md-2 item-card-group-section">
-		<!-- Rendered via JS -->
-	</div>
-
-	<!-- Filters Section -->
-	<div class="col-12 order-1 col-md-3 order-md-1">
-		<div class="collapse d-md-block mr-4 filters-section" id="product-filters">
-			<div class="d-flex justify-content-between align-items-center mb-5 title-section">
-				<div class="mb-4 filters-title" > {{ _('Filters') }} </div>
-				<a class="mb-4 clear-filters" href="/all-products">{{ _('Clear All') }}</a>
-			</div>
-			<!-- field filters -->
-			{% if field_filters %}
-				{{ field_filter_section(field_filters) }}
-			{% endif %}
-
-			<!-- attribute filters -->
-			{% if attribute_filters %}
-				{{ attribute_filter_section(attribute_filters) }}
-			{% endif %}
-		</div>
-
-	</div>
-</div>
-
-<script>
-	frappe.ready(() => {
-		$('.btn-prev, .btn-next').click((e) => {
-			const $btn = $(e.target);
-			$btn.prop('disabled', true);
-			const start = $btn.data('start');
-			let query_params = frappe.utils.get_query_params();
-			query_params.start = start;
-			let path = window.location.pathname + '?' + frappe.utils.get_url_from_dict(query_params);
-			window.location.href = path;
-		});
-	});
-</script>
-
-{% endblock %}
diff --git a/erpnext/www/all-products/index.js b/erpnext/www/all-products/index.js
deleted file mode 100644
index 98a8441..0000000
--- a/erpnext/www/all-products/index.js
+++ /dev/null
@@ -1,27 +0,0 @@
-$(() => {
-	class ProductListing {
-		constructor() {
-			let me = this;
-			let is_item_group_page = $(".item-group-content").data("item-group");
-			this.item_group = is_item_group_page || null;
-
-			let view_type = localStorage.getItem("product_view") || "List View";
-
-			// Render Product Views, Filters & Search
-			new erpnext.ProductView({
-				view_type: view_type,
-				products_section: $('#product-listing'),
-				item_group: me.item_group
-			});
-
-			this.bind_card_actions();
-		}
-
-		bind_card_actions() {
-			erpnext.e_commerce.shopping_cart.bind_add_to_cart_action();
-			erpnext.e_commerce.wishlist.bind_wishlist_action();
-		}
-	}
-
-	new ProductListing();
-});
diff --git a/erpnext/www/all-products/index.py b/erpnext/www/all-products/index.py
deleted file mode 100644
index fbf0dce..0000000
--- a/erpnext/www/all-products/index.py
+++ /dev/null
@@ -1,22 +0,0 @@
-import frappe
-from frappe.utils import cint
-
-from erpnext.e_commerce.product_data_engine.filters import ProductFiltersBuilder
-
-sitemap = 1
-
-
-def get_context(context):
-	# Add homepage as parent
-	context.body_class = "product-page"
-	context.parents = [{"name": frappe._("Home"), "route": "/"}]
-
-	filter_engine = ProductFiltersBuilder()
-	context.field_filters = filter_engine.get_field_filters()
-	context.attribute_filters = filter_engine.get_attribute_filters()
-
-	context.page_length = (
-		cint(frappe.db.get_single_value("E Commerce Settings", "products_per_page")) or 20
-	)
-
-	context.no_cache = 1
diff --git a/erpnext/www/all-products/not_found.html b/erpnext/www/all-products/not_found.html
deleted file mode 100644
index 91989a9..0000000
--- a/erpnext/www/all-products/not_found.html
+++ /dev/null
@@ -1 +0,0 @@
-<div class="d-flex justify-content-center p-3 text-muted">{{ _('No products found') }}</div>
diff --git a/erpnext/www/shop-by-category/__init__.py b/erpnext/www/shop-by-category/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/www/shop-by-category/__init__.py
+++ /dev/null
diff --git a/erpnext/www/shop-by-category/category_card_section.html b/erpnext/www/shop-by-category/category_card_section.html
deleted file mode 100644
index 56cb63a..0000000
--- a/erpnext/www/shop-by-category/category_card_section.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{%- macro card(title, image, type, url=None, text_primary=False) -%}
-<!-- style defined at shop-by-category index -->
-<div class="card category-card" data-type="{{ type }}" data-name="{{ title }}">
-	{% if image %}
-	<img class="card-img-top" src="{{ image }}" alt="{{ title }}" style="height: 80%;">
-	{% else %}
-	<div class="placeholder-div">
-		<span class="placeholder">
-			{{ frappe.utils.get_abbr(title) }}
-		</span>
-	</div>
-	{% endif %}
-	<div class="card-body text-center text-muted">
-		{{ title or '' }}
-	</div>
-	<a href="{{ url or '#' }}" class="stretched-link"></a>
-</div>
-{%- endmacro -%}
-
-<div class="col-12 item-card-group-section">
-	<div class="row products-list product-category-section">
-		{%- for row in data -%}
-			{%- set title = row.name -%}
-			{%- set image = row.get("image") -%}
-			{%- if title -%}
-				{{ card(title, image, type, row.get("route")) }}
-			{%- endif -%}
-		{%- endfor -%}
-	</div>
-</div>
\ No newline at end of file
diff --git a/erpnext/www/shop-by-category/index.html b/erpnext/www/shop-by-category/index.html
deleted file mode 100644
index 04d2d57..0000000
--- a/erpnext/www/shop-by-category/index.html
+++ /dev/null
@@ -1,48 +0,0 @@
-{% extends "templates/web.html" %}
-{% block title %}{{ _('Shop by Category') }}{% endblock %}
-
-{% block head_include %}
-<style>
-	.category-slideshow {
-		margin-bottom: 2rem;
-	}
-	.category-card {
-		height: 300px !important;
-		width: 300px !important;
-		margin: 30px !important;
-	}
-</style>
-{% endblock %}
-
-{% block script %}
-<script type="text/javascript" src="/shop-by-category/index.js"></script>
-{% endblock %}
-
-{% block page_content %}
-<div class="shop-by-category-content">
-	<div class="category-slideshow">
-		{% if slideshow %}
-		<!-- slideshow -->
-			{{ web_block(
-				"Hero Slider",
-				values=slideshow,
-				add_container=0,
-				add_top_padding=0,
-				add_bottom_padding=0,
-			) }}
-		{% endif %}
-	</div>
-	<div class="category-tabs">
-		{% if tabs %}
-		<!-- tabs -->
-			{{ web_block(
-				"Section with Tabs",
-				values=tabs,
-				add_container=0,
-				add_top_padding=0,
-				add_bottom_padding=0
-			) }}
-		{% endif %}
-	</div>
-</div>
-{% endblock %}
\ No newline at end of file
diff --git a/erpnext/www/shop-by-category/index.js b/erpnext/www/shop-by-category/index.js
deleted file mode 100644
index 1b3116f..0000000
--- a/erpnext/www/shop-by-category/index.js
+++ /dev/null
@@ -1,12 +0,0 @@
-$(() => {
-	$('.category-card').on('click', (e) => {
-		let category_type = e.currentTarget.dataset.type;
-		let category_name = e.currentTarget.dataset.name;
-
-		if (category_type != "item_group") {
-			let filters = {};
-			filters[category_type] =  [category_name];
-			window.location.href = "/all-products?field_filters=" + JSON.stringify(filters);
-		}
-	});
-});
\ No newline at end of file
diff --git a/erpnext/www/shop-by-category/index.py b/erpnext/www/shop-by-category/index.py
deleted file mode 100644
index 913c183..0000000
--- a/erpnext/www/shop-by-category/index.py
+++ /dev/null
@@ -1,91 +0,0 @@
-import frappe
-from frappe import _
-
-sitemap = 1
-
-
-def get_context(context):
-	context.body_class = "product-page"
-
-	settings = frappe.get_cached_doc("E Commerce Settings")
-	context.categories_enabled = settings.enable_field_filters
-
-	if context.categories_enabled:
-		categories = [row.fieldname for row in settings.filter_fields]
-		context.tabs = get_tabs(categories)
-
-	if settings.slideshow:
-		context.slideshow = get_slideshow(settings.slideshow)
-
-	context.no_cache = 1
-
-
-def get_slideshow(slideshow):
-	values = {"show_indicators": 1, "show_controls": 1, "rounded": 1, "slider_name": "Categories"}
-	slideshow = frappe.get_cached_doc("Website Slideshow", slideshow)
-	slides = slideshow.get({"doctype": "Website Slideshow Item"})
-	for index, slide in enumerate(slides, start=1):
-		values[f"slide_{index}_image"] = slide.image
-		values[f"slide_{index}_title"] = slide.heading
-		values[f"slide_{index}_subtitle"] = slide.description
-		values[f"slide_{index}_theme"] = slide.get("theme") or "Light"
-		values[f"slide_{index}_content_align"] = slide.get("content_align") or "Centre"
-		values[f"slide_{index}_primary_action"] = slide.url
-
-	return values
-
-
-def get_tabs(categories):
-	tab_values = {
-		"title": _("Shop by Category"),
-	}
-
-	categorical_data = get_category_records(categories)
-	for index, tab in enumerate(categorical_data, start=1):
-		tab_values[f"tab_{index + 1}_title"] = frappe.unscrub(tab)
-		# pre-render cards for each tab
-		tab_values[f"tab_{index + 1}_content"] = frappe.render_template(
-			"erpnext/www/shop-by-category/category_card_section.html",
-			{"data": categorical_data[tab], "type": tab},
-		)
-	return tab_values
-
-
-def get_category_records(categories: list):
-	categorical_data = {}
-	website_item_meta = frappe.get_meta("Website Item", cached=True)
-
-	for c in categories:
-		if c == "item_group":
-			categorical_data["item_group"] = frappe.db.get_all(
-				"Item Group",
-				filters={"parent_item_group": "All Item Groups", "show_in_website": 1},
-				fields=["name", "parent_item_group", "is_group", "image", "route"],
-			)
-
-			continue
-
-		field_type = website_item_meta.get_field(c).fieldtype
-
-		if field_type == "Table MultiSelect":
-			child_doc = website_item_meta.get_field(c).options
-			for field in frappe.get_meta(child_doc, cached=True).fields:
-				if field.fieldtype == "Link" and field.reqd:
-					doctype = field.options
-		else:
-			doctype = website_item_meta.get_field(c).options
-
-		fields = ["name"]
-
-		try:
-			meta = frappe.get_meta(doctype, cached=True)
-			if meta.get_field("image"):
-				fields += ["image"]
-
-			data = frappe.db.get_all(doctype, fields=fields)
-			categorical_data[c] = data
-		except BaseException:
-			frappe.throw(_("DocType {} not found").format(doctype))
-			continue
-
-	return categorical_data
diff --git a/pyproject.toml b/pyproject.toml
index 7841c92..604aa44 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -16,11 +16,9 @@
     "holidays~=0.28",
 
     # integration dependencies
-    "gocardless-pro~=1.22.0",
     "googlemaps",
     "plaid-python~=7.2.1",
     "python-youtube~=0.8.0",
-    "tweepy~=4.14.0",
 
     # Not used directly - required by PyQRCode for PNG generation
     "pypng~=0.20220715.0",