Merge pull request #30799 from nextchamp-saqib/einv-cess-fix

fix(india): cess value not considered while validating e-invoice totals
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..5a46002
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,31 @@
+name: Generate Semantic Release
+on:
+  push:
+    branches:
+      - version-13
+jobs:
+  release:
+    name: Release
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout Entire Repository
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+          persist-credentials: false
+      - name: Setup Node.js v14
+        uses: actions/setup-node@v2
+        with:
+          node-version: 14
+      - name: Setup dependencies
+        run: |
+          npm install @semantic-release/git @semantic-release/exec --no-save
+      - name: Create Release
+        env:
+          GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
+          GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
+          GIT_AUTHOR_NAME: "Frappe PR Bot"
+          GIT_AUTHOR_EMAIL: "developers@frappe.io"
+          GIT_COMMITTER_NAME: "Frappe PR Bot"
+          GIT_COMMITTER_EMAIL: "developers@frappe.io"
+        run: npx semantic-release
\ No newline at end of file
diff --git a/.github/workflows/server-tests-mariadb.yml b/.github/workflows/server-tests-mariadb.yml
index 8cc5826..cdb6849 100644
--- a/.github/workflows/server-tests-mariadb.yml
+++ b/.github/workflows/server-tests-mariadb.yml
@@ -129,6 +129,9 @@
     needs: test
     runs-on: ubuntu-latest
     steps:
+      - name: Clone
+        uses: actions/checkout@v2
+
       - name: Download artifacts
         uses: actions/download-artifact@v3
 
diff --git a/.releaserc b/.releaserc
new file mode 100644
index 0000000..8a758ed
--- /dev/null
+++ b/.releaserc
@@ -0,0 +1,24 @@
+{
+	"branches": ["version-13"],
+	"plugins": [
+		"@semantic-release/commit-analyzer", {
+			"preset": "angular",
+			"releaseRules": [
+				{"breaking": true, "release": false}
+			]
+		},
+		"@semantic-release/release-notes-generator",
+		[
+			"@semantic-release/exec", {
+				"prepareCmd": 'sed -ir "s/[0-9]*\.[0-9]*\.[0-9]*/${nextRelease.version}/" erpnext/__init__.py'
+			}
+		],
+		[
+			"@semantic-release/git", {
+				"assets": ["erpnext/__init__.py"],
+				"message": "chore(release): Bumped to Version ${nextRelease.version}\n\n${nextRelease.notes}"
+			}
+		],
+		"@semantic-release/github"
+	]
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
index 897151a..3f1998a 100644
--- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
+++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
@@ -99,7 +99,7 @@
 			if doctype == "Budget":
 				add_dimension_to_budget_doctype(df.copy(), doc)
 			else:
-				create_custom_field(doctype, df)
+				create_custom_field(doctype, df, ignore_validate=True)
 
 		count += 1
 
@@ -115,7 +115,7 @@
 		}
 	)
 
-	create_custom_field("Budget", df)
+	create_custom_field("Budget", df, ignore_validate=True)
 
 	property_setter = frappe.db.exists("Property Setter", "Budget-budget_against-options")
 
@@ -205,10 +205,16 @@
 	return frappe.get_hooks("accounting_dimension_doctypes")
 
 
-def get_accounting_dimensions(as_list=True):
+def get_accounting_dimensions(as_list=True, filters=None):
+
+	if not filters:
+		filters = {"disabled": 0}
+
 	if frappe.flags.accounting_dimensions is None:
 		frappe.flags.accounting_dimensions = frappe.get_all(
-			"Accounting Dimension", fields=["label", "fieldname", "disabled", "document_type"]
+			"Accounting Dimension",
+			fields=["label", "fieldname", "disabled", "document_type"],
+			filters=filters,
 		)
 
 	if as_list:
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
index 9a35a24..417611f 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
@@ -18,7 +18,6 @@
   "automatically_fetch_payment_terms",
   "column_break_17",
   "enable_common_party_accounting",
-  "enable_discount_accounting",
   "report_setting_section",
   "use_custom_cash_flow",
   "deferred_accounting_settings_section",
@@ -274,13 +273,6 @@
   },
   {
    "default": "0",
-   "description": "If enabled, additional ledger entries will be made for discounts in a separate Discount Account",
-   "fieldname": "enable_discount_accounting",
-   "fieldtype": "Check",
-   "label": "Enable Discount Accounting"
-  },
-  {
-   "default": "0",
    "description": "Learn about <a href=\"https://docs.erpnext.com/docs/v13/user/manual/en/accounts/articles/common_party_accounting#:~:text=Common%20Party%20Accounting%20in%20ERPNext,Invoice%20against%20a%20primary%20Supplier.\">Common Party</a>",
    "fieldname": "enable_common_party_accounting",
    "fieldtype": "Check",
@@ -354,7 +346,7 @@
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2022-02-04 12:32:36.805652",
+ "modified": "2022-04-08 14:45:06.796418",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Accounts Settings",
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py
index 8354981..3b125a2 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py
@@ -28,7 +28,6 @@
 
 		self.validate_stale_days()
 		self.enable_payment_schedule_in_print()
-		self.toggle_discount_accounting_fields()
 		self.validate_pending_reposts()
 
 	def validate_stale_days(self):
@@ -52,74 +51,6 @@
 				validate_fields_for_doctype=False,
 			)
 
-	def toggle_discount_accounting_fields(self):
-		enable_discount_accounting = cint(self.enable_discount_accounting)
-
-		for doctype in ["Sales Invoice Item", "Purchase Invoice Item"]:
-			make_property_setter(
-				doctype,
-				"discount_account",
-				"hidden",
-				not (enable_discount_accounting),
-				"Check",
-				validate_fields_for_doctype=False,
-			)
-			if enable_discount_accounting:
-				make_property_setter(
-					doctype,
-					"discount_account",
-					"mandatory_depends_on",
-					"eval: doc.discount_amount",
-					"Code",
-					validate_fields_for_doctype=False,
-				)
-			else:
-				make_property_setter(
-					doctype,
-					"discount_account",
-					"mandatory_depends_on",
-					"",
-					"Code",
-					validate_fields_for_doctype=False,
-				)
-
-		for doctype in ["Sales Invoice", "Purchase Invoice"]:
-			make_property_setter(
-				doctype,
-				"additional_discount_account",
-				"hidden",
-				not (enable_discount_accounting),
-				"Check",
-				validate_fields_for_doctype=False,
-			)
-			if enable_discount_accounting:
-				make_property_setter(
-					doctype,
-					"additional_discount_account",
-					"mandatory_depends_on",
-					"eval: doc.discount_amount",
-					"Code",
-					validate_fields_for_doctype=False,
-				)
-			else:
-				make_property_setter(
-					doctype,
-					"additional_discount_account",
-					"mandatory_depends_on",
-					"",
-					"Code",
-					validate_fields_for_doctype=False,
-				)
-
-		make_property_setter(
-			"Item",
-			"default_discount_account",
-			"hidden",
-			not (enable_discount_accounting),
-			"Check",
-			validate_fields_for_doctype=False,
-		)
-
 	def validate_pending_reposts(self):
 		if self.acc_frozen_upto:
 			check_pending_reposting(self.acc_frozen_upto)
diff --git a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py
index 96779d7..0f617b5 100644
--- a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py
+++ b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py
@@ -5,7 +5,10 @@
 import frappe
 from frappe import _, msgprint
 from frappe.model.document import Document
-from frappe.utils import flt, fmt_money, getdate, nowdate
+from frappe.query_builder.custom import ConstantColumn
+from frappe.utils import flt, fmt_money, getdate
+
+import erpnext
 
 form_grid_templates = {"journal_entries": "templates/form_grid/bank_reconciliation_grid.html"}
 
@@ -76,6 +79,52 @@
 			as_dict=1,
 		)
 
+		loan_disbursement = frappe.qb.DocType("Loan Disbursement")
+
+		loan_disbursements = (
+			frappe.qb.from_(loan_disbursement)
+			.select(
+				ConstantColumn("Loan Disbursement").as_("payment_document"),
+				loan_disbursement.name.as_("payment_entry"),
+				loan_disbursement.disbursed_amount.as_("credit"),
+				ConstantColumn(0).as_("debit"),
+				loan_disbursement.reference_number.as_("cheque_number"),
+				loan_disbursement.reference_date.as_("cheque_date"),
+				loan_disbursement.disbursement_date.as_("posting_date"),
+				loan_disbursement.applicant.as_("against_account"),
+			)
+			.where(loan_disbursement.docstatus == 1)
+			.where(loan_disbursement.disbursement_date >= self.from_date)
+			.where(loan_disbursement.disbursement_date <= self.to_date)
+			.where(loan_disbursement.clearance_date.isnull())
+			.where(loan_disbursement.disbursement_account.isin([self.bank_account, self.account]))
+			.orderby(loan_disbursement.disbursement_date)
+			.orderby(loan_disbursement.name, frappe.qb.desc)
+		).run(as_dict=1)
+
+		loan_repayment = frappe.qb.DocType("Loan Repayment")
+
+		loan_repayments = (
+			frappe.qb.from_(loan_repayment)
+			.select(
+				ConstantColumn("Loan Repayment").as_("payment_document"),
+				loan_repayment.name.as_("payment_entry"),
+				loan_repayment.amount_paid.as_("debit"),
+				ConstantColumn(0).as_("credit"),
+				loan_repayment.reference_number.as_("cheque_number"),
+				loan_repayment.reference_date.as_("cheque_date"),
+				loan_repayment.applicant.as_("against_account"),
+				loan_repayment.posting_date,
+			)
+			.where(loan_repayment.docstatus == 1)
+			.where(loan_repayment.clearance_date.isnull())
+			.where(loan_repayment.posting_date >= self.from_date)
+			.where(loan_repayment.posting_date <= self.to_date)
+			.where(loan_repayment.payment_account.isin([self.bank_account, self.account]))
+			.orderby(loan_repayment.posting_date)
+			.orderby(loan_repayment.name, frappe.qb.desc)
+		).run(as_dict=1)
+
 		pos_sales_invoices, pos_purchase_invoices = [], []
 		if self.include_pos_transactions:
 			pos_sales_invoices = frappe.db.sql(
@@ -114,20 +163,29 @@
 
 		entries = sorted(
 			list(payment_entries)
-			+ list(journal_entries + list(pos_sales_invoices) + list(pos_purchase_invoices)),
-			key=lambda k: k["posting_date"] or getdate(nowdate()),
+			+ list(journal_entries)
+			+ list(pos_sales_invoices)
+			+ list(pos_purchase_invoices)
+			+ list(loan_disbursements)
+			+ list(loan_repayments),
+			key=lambda k: getdate(k["posting_date"]),
 		)
 
 		self.set("payment_entries", [])
 		self.total_amount = 0.0
+		default_currency = erpnext.get_default_currency()
 
 		for d in entries:
 			row = self.append("payment_entries", {})
 
 			amount = flt(d.get("debit", 0)) - flt(d.get("credit", 0))
 
+			if not d.get("account_currency"):
+				d.account_currency = default_currency
+
 			formatted_amount = fmt_money(abs(amount), 2, d.account_currency)
 			d.amount = formatted_amount + " " + (_("Dr") if amount > 0 else _("Cr"))
+			d.posting_date = getdate(d.posting_date)
 
 			d.pop("credit")
 			d.pop("debit")
diff --git a/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py b/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py
index 706fbbe..c1e55f6 100644
--- a/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py
+++ b/erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py
@@ -1,9 +1,96 @@
 # Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
 # See license.txt
 
-# import frappe
 import unittest
 
+import frappe
+from frappe.utils import add_months, getdate
+
+from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
+from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
+from erpnext.loan_management.doctype.loan.test_loan import (
+	create_loan,
+	create_loan_accounts,
+	create_loan_type,
+	create_repayment_entry,
+	make_loan_disbursement_entry,
+)
+
 
 class TestBankClearance(unittest.TestCase):
-	pass
+	@classmethod
+	def setUpClass(cls):
+		make_bank_account()
+		create_loan_accounts()
+		create_loan_masters()
+		add_transactions()
+
+	# Basic test case to test if bank clearance tool doesn't break
+	# Detailed test can be added later
+	def test_bank_clearance(self):
+		bank_clearance = frappe.get_doc("Bank Clearance")
+		bank_clearance.account = "_Test Bank Clearance - _TC"
+		bank_clearance.from_date = add_months(getdate(), -1)
+		bank_clearance.to_date = getdate()
+		bank_clearance.get_payment_entries()
+		self.assertEqual(len(bank_clearance.payment_entries), 3)
+
+
+def make_bank_account():
+	if not frappe.db.get_value("Account", "_Test Bank Clearance - _TC"):
+		frappe.get_doc(
+			{
+				"doctype": "Account",
+				"account_type": "Bank",
+				"account_name": "_Test Bank Clearance",
+				"company": "_Test Company",
+				"parent_account": "Bank Accounts - _TC",
+			}
+		).insert()
+
+
+def create_loan_masters():
+	create_loan_type(
+		"Clearance Loan",
+		2000000,
+		13.5,
+		25,
+		0,
+		5,
+		"Cash",
+		"_Test Bank Clearance - _TC",
+		"_Test Bank Clearance - _TC",
+		"Loan Account - _TC",
+		"Interest Income Account - _TC",
+		"Penalty Income Account - _TC",
+	)
+
+
+def add_transactions():
+	make_payment_entry()
+	make_loan()
+
+
+def make_loan():
+	loan = create_loan(
+		"_Test Customer",
+		"Clearance Loan",
+		280000,
+		"Repay Over Number of Periods",
+		20,
+		applicant_type="Customer",
+	)
+	loan.submit()
+	make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=getdate())
+	repayment_entry = create_repayment_entry(loan.name, "_Test Customer", getdate(), loan.loan_amount)
+	repayment_entry.save()
+	repayment_entry.submit()
+
+
+def make_payment_entry():
+	pi = make_purchase_invoice(supplier="_Test Supplier", qty=1, rate=690)
+	pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank Clearance - _TC")
+	pe.reference_no = "Conrad Oct 18"
+	pe.reference_date = "2018-10-24"
+	pe.insert()
+	pe.submit()
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 920db5b..d28c3a8 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -18,7 +18,6 @@
 )
 from erpnext.accounts.party import get_party_account
 from erpnext.accounts.utils import (
-	check_if_stock_and_account_balance_synced,
 	get_account_currency,
 	get_balance_on,
 	get_stock_accounts,
@@ -88,9 +87,6 @@
 		self.update_inter_company_jv()
 		self.update_invoice_discounting()
 		self.update_status_for_full_and_final_statement()
-		check_if_stock_and_account_balance_synced(
-			self.posting_date, self.company, self.doctype, self.name
-		)
 
 	def on_cancel(self):
 		from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
index 907b769..b596df9 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
@@ -350,9 +350,13 @@
 			)
 
 			if self.minimum_invoice_amount:
-				condition += " and `{0}` >= {1}".format(dr_or_cr, flt(self.minimum_invoice_amount))
+				condition += " and {dr_or_cr} >= {amount}".format(
+					dr_or_cr=dr_or_cr, amount=flt(self.minimum_invoice_amount)
+				)
 			if self.maximum_invoice_amount:
-				condition += " and `{0}` <= {1}".format(dr_or_cr, flt(self.maximum_invoice_amount))
+				condition += " and {dr_or_cr} <= {amount}".format(
+					dr_or_cr=dr_or_cr, amount=flt(self.maximum_invoice_amount)
+				)
 
 		elif get_return_invoices:
 			condition = " and doc.company = '{0}' ".format(self.company)
@@ -367,15 +371,19 @@
 				else ""
 			)
 			dr_or_cr = (
-				"gl.debit_in_account_currency"
+				"debit_in_account_currency"
 				if erpnext.get_party_account_type(self.party_type) == "Receivable"
-				else "gl.credit_in_account_currency"
+				else "credit_in_account_currency"
 			)
 
 			if self.minimum_invoice_amount:
-				condition += " and `{0}` >= {1}".format(dr_or_cr, flt(self.minimum_payment_amount))
+				condition += " and gl.{dr_or_cr} >= {amount}".format(
+					dr_or_cr=dr_or_cr, amount=flt(self.minimum_payment_amount)
+				)
 			if self.maximum_invoice_amount:
-				condition += " and `{0}` <= {1}".format(dr_or_cr, flt(self.maximum_payment_amount))
+				condition += " and gl.{dr_or_cr} <= {amount}".format(
+					dr_or_cr=dr_or_cr, amount=flt(self.maximum_payment_amount)
+				)
 
 		else:
 			condition += (
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 fea55a3..01f716d 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
@@ -34,8 +34,9 @@
 			frappe.throw(_("Customers not selected."))
 
 		if self.enable_auto_email:
-			self.to_date = self.start_date
-			self.from_date = add_months(self.to_date, -1 * self.filter_duration)
+			if self.start_date and getdate(self.start_date) >= getdate(today()):
+				self.to_date = self.start_date
+				self.from_date = add_months(self.to_date, -1 * self.filter_duration)
 
 
 def get_report_pdf(doc, consolidated=True):
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index ee29d2a..42917f8 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -30,6 +30,9 @@
 	onload() {
 		super.onload();
 
+		// Ignore linked advances
+		this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry'];
+
 		if(!this.frm.doc.__islocal) {
 			// show credit_to in print format
 			if(!this.frm.doc.supplier && this.frm.doc.credit_to) {
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index e6a46d0..c06809c 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -669,7 +669,7 @@
 		exchange_rate_map, net_rate_map = get_purchase_document_details(self)
 
 		enable_discount_accounting = cint(
-			frappe.db.get_single_value("Accounts Settings", "enable_discount_accounting")
+			frappe.db.get_single_value("Buying Settings", "enable_discount_accounting")
 		)
 		provisional_accounting_for_non_stock_items = cint(
 			frappe.db.get_value(
@@ -811,7 +811,9 @@
 
 					if provisional_accounting_for_non_stock_items:
 						if item.purchase_receipt:
-							provisional_account = self.get_company_default("default_provisional_account")
+							provisional_account = frappe.db.get_value(
+								"Purchase Receipt Item", item.pr_detail, "provisional_expense_account"
+							) or self.get_company_default("default_provisional_account")
 							purchase_receipt_doc = purchase_receipt_doc_map.get(item.purchase_receipt)
 
 							if not purchase_receipt_doc:
@@ -834,7 +836,7 @@
 							if expense_booked_in_pr:
 								# Intentionally passing purchase invoice item to handle partial billing
 								purchase_receipt_doc.add_provisional_gl_entry(
-									item, gl_entries, self.posting_date, reverse=1
+									item, gl_entries, self.posting_date, provisional_account, reverse=1
 								)
 
 					if not self.is_internal_transfer():
@@ -1157,7 +1159,7 @@
 		# tax table gl entries
 		valuation_tax = {}
 		enable_discount_accounting = cint(
-			frappe.db.get_single_value("Accounts Settings", "enable_discount_accounting")
+			frappe.db.get_single_value("Buying Settings", "enable_discount_accounting")
 		)
 
 		for tax in self.get("taxes"):
@@ -1250,7 +1252,7 @@
 	def enable_discount_accounting(self):
 		if not hasattr(self, "_enable_discount_accounting"):
 			self._enable_discount_accounting = cint(
-				frappe.db.get_single_value("Accounts Settings", "enable_discount_accounting")
+				frappe.db.get_single_value("Buying Settings", "enable_discount_accounting")
 			)
 
 		return self._enable_discount_accounting
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index 73390dd..30d26ac 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -5,6 +5,7 @@
 import unittest
 
 import frappe
+from frappe.tests.utils import change_settings
 from frappe.utils import add_days, cint, flt, getdate, nowdate, today
 
 import erpnext
@@ -336,8 +337,8 @@
 
 		self.assertEqual(discrepancy_caused_by_exchange_rate_diff, amount)
 
+	@change_settings("Buying Settings", {"enable_discount_accounting": 1})
 	def test_purchase_invoice_with_discount_accounting_enabled(self):
-		enable_discount_accounting()
 
 		discount_account = create_account(
 			account_name="Discount Account",
@@ -353,10 +354,10 @@
 		]
 
 		check_gl_entries(self, pi.name, expected_gle, nowdate())
-		enable_discount_accounting(enable=0)
 
+	@change_settings("Buying Settings", {"enable_discount_accounting": 1})
 	def test_additional_discount_for_purchase_invoice_with_discount_accounting_enabled(self):
-		enable_discount_accounting()
+
 		additional_discount_account = create_account(
 			account_name="Discount Account",
 			parent_account="Indirect Expenses - _TC",
@@ -1482,7 +1483,8 @@
 		self.assertEqual(payment_entry.taxes[0].allocated_amount, 0)
 
 	def test_provisional_accounting_entry(self):
-		item = create_item("_Test Non Stock Item", is_stock_item=0)
+		create_item("_Test Non Stock Item", is_stock_item=0)
+
 		provisional_account = create_account(
 			account_name="Provision Account",
 			parent_account="Current Liabilities - _TC",
@@ -1505,6 +1507,8 @@
 		pi.save()
 		pi.submit()
 
+		self.assertEquals(pr.items[0].provisional_expense_account, "Provision Account - _TC")
+
 		# Check GLE for Purchase Invoice
 		expected_gle = [
 			["Cost of Goods Sold - _TC", 250, 0, add_days(pr.posting_date, -1)],
@@ -1585,12 +1589,6 @@
 	accounts_settings.save()
 
 
-def enable_discount_accounting(enable=1):
-	accounts_settings = frappe.get_doc("Accounts Settings")
-	accounts_settings.enable_discount_accounting = enable
-	accounts_settings.save()
-
-
 def make_purchase_invoice(**args):
 	pi = frappe.new_doc("Purchase Invoice")
 	args = frappe._dict(args)
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 6818955..0f7c13f 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -33,7 +33,9 @@
 		var me = this;
 		super.onload();
 
-		this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice', 'Timesheet', 'POS Invoice Merge Log', 'POS Closing Entry'];
+		this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice', 'Timesheet', 'POS Invoice Merge Log',
+			'POS Closing Entry', 'Journal Entry', 'Payment Entry'];
+
 		if(!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) {
 			// show debit_to in print format
 			this.frm.set_df_property("debit_to", "print_hide", 0);
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 1efd3dc..dd85d99 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -1051,7 +1051,7 @@
 
 	def make_tax_gl_entries(self, gl_entries):
 		enable_discount_accounting = cint(
-			frappe.db.get_single_value("Accounts Settings", "enable_discount_accounting")
+			frappe.db.get_single_value("Selling Settings", "enable_discount_accounting")
 		)
 
 		for tax in self.get("taxes"):
@@ -1097,7 +1097,7 @@
 	def make_item_gl_entries(self, gl_entries):
 		# income account gl entries
 		enable_discount_accounting = cint(
-			frappe.db.get_single_value("Accounts Settings", "enable_discount_accounting")
+			frappe.db.get_single_value("Selling Settings", "enable_discount_accounting")
 		)
 
 		for item in self.get("items"):
@@ -1276,7 +1276,7 @@
 	def enable_discount_accounting(self):
 		if not hasattr(self, "_enable_discount_accounting"):
 			self._enable_discount_accounting = cint(
-				frappe.db.get_single_value("Accounts Settings", "enable_discount_accounting")
+				frappe.db.get_single_value("Selling Settings", "enable_discount_accounting")
 			)
 
 		return self._enable_discount_accounting
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 7781fe3..98a5755 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -7,6 +7,7 @@
 import frappe
 from frappe.model.dynamic_links import get_dynamic_link_map
 from frappe.model.naming import make_autoname
+from frappe.tests.utils import change_settings
 from frappe.utils import add_days, flt, getdate, nowdate
 
 import erpnext
@@ -2684,12 +2685,8 @@
 			sales_invoice.items[0].item_tax_template, "_Test Account Excise Duty @ 10 - _TC"
 		)
 
+	@change_settings("Selling Settings", {"enable_discount_accounting": 1})
 	def test_sales_invoice_with_discount_accounting_enabled(self):
-		from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import (
-			enable_discount_accounting,
-		)
-
-		enable_discount_accounting()
 
 		discount_account = create_account(
 			account_name="Discount Account",
@@ -2705,14 +2702,10 @@
 		]
 
 		check_gl_entries(self, si.name, expected_gle, add_days(nowdate(), -1))
-		enable_discount_accounting(enable=0)
 
+	@change_settings("Selling Settings", {"enable_discount_accounting": 1})
 	def test_additional_discount_for_sales_invoice_with_discount_accounting_enabled(self):
-		from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import (
-			enable_discount_accounting,
-		)
 
-		enable_discount_accounting()
 		additional_discount_account = create_account(
 			account_name="Discount Account",
 			parent_account="Indirect Expenses - _TC",
@@ -2743,7 +2736,6 @@
 		]
 
 		check_gl_entries(self, si.name, expected_gle, add_days(nowdate(), -1))
-		enable_discount_accounting(enable=0)
 
 	def test_asset_depreciation_on_sale_with_pro_rata(self):
 		"""
@@ -3124,6 +3116,62 @@
 		si.reload()
 		self.assertTrue(si.items[0].serial_no)
 
+	def test_gain_loss_with_advance_entry(self):
+		from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
+
+		unlink_enabled = frappe.db.get_value(
+			"Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice"
+		)
+
+		frappe.db.set_value(
+			"Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice", 1
+		)
+
+		jv = make_journal_entry("_Test Receivable USD - _TC", "_Test Bank - _TC", -7000, save=False)
+
+		jv.accounts[0].exchange_rate = 70
+		jv.accounts[0].credit_in_account_currency = 100
+		jv.accounts[0].party_type = "Customer"
+		jv.accounts[0].party = "_Test Customer USD"
+
+		jv.save()
+		jv.submit()
+
+		si = create_sales_invoice(
+			customer="_Test Customer USD",
+			debit_to="_Test Receivable USD - _TC",
+			currency="USD",
+			conversion_rate=75,
+			do_not_save=1,
+			rate=100,
+		)
+
+		si.append(
+			"advances",
+			{
+				"reference_type": "Journal Entry",
+				"reference_name": jv.name,
+				"reference_row": jv.accounts[0].name,
+				"advance_amount": 100,
+				"allocated_amount": 100,
+				"ref_exchange_rate": 70,
+			},
+		)
+		si.save()
+		si.submit()
+
+		expected_gle = [
+			["_Test Receivable USD - _TC", 7500.0, 500],
+			["Exchange Gain/Loss - _TC", 500.0, 0.0],
+			["Sales - _TC", 0.0, 7500.0],
+		]
+
+		check_gl_entries(self, si.name, expected_gle, nowdate())
+
+		frappe.db.set_value(
+			"Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice", unlink_enabled
+		)
+
 
 def get_sales_invoice_for_e_invoice():
 	si = make_sales_invoice_for_ewaybill()
diff --git a/erpnext/accounts/test/test_utils.py b/erpnext/accounts/test/test_utils.py
index 0fe5008..77c40ba 100644
--- a/erpnext/accounts/test/test_utils.py
+++ b/erpnext/accounts/test/test_utils.py
@@ -1,10 +1,17 @@
 import unittest
 
+import frappe
 from frappe.test_runner import make_test_objects
 
 from erpnext.accounts.party import get_party_shipping_address
-from erpnext.accounts.utils import get_future_stock_vouchers, get_voucherwise_gl_entries
+from erpnext.accounts.utils import (
+	get_future_stock_vouchers,
+	get_voucherwise_gl_entries,
+	sort_stock_vouchers_by_posting_date,
+)
+from erpnext.stock.doctype.item.test_item import make_item
 from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
+from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
 
 
 class TestUtils(unittest.TestCase):
@@ -47,6 +54,25 @@
 			msg="get_voucherwise_gl_entries not returning expected GLes",
 		)
 
+	def test_stock_voucher_sorting(self):
+		vouchers = []
+
+		item = make_item().name
+
+		stock_entry = {"item": item, "to_warehouse": "_Test Warehouse - _TC", "qty": 1, "rate": 10}
+
+		se1 = make_stock_entry(posting_date="2022-01-01", **stock_entry)
+		se2 = make_stock_entry(posting_date="2022-02-01", **stock_entry)
+		se3 = make_stock_entry(posting_date="2022-03-01", **stock_entry)
+
+		for doc in (se1, se2, se3):
+			vouchers.append((doc.doctype, doc.name))
+
+		vouchers.append(("Stock Entry", "Wat"))
+
+		sorted_vouchers = sort_stock_vouchers_by_posting_date(list(reversed(vouchers)))
+		self.assertEqual(sorted_vouchers, vouchers)
+
 
 ADDRESS_RECORDS = [
 	{
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index d17207a..405922e 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -3,6 +3,7 @@
 
 
 from json import loads
+from typing import List, Tuple
 
 import frappe
 import frappe.defaults
@@ -18,10 +19,6 @@
 from erpnext.stock.utils import get_stock_value_on
 
 
-class StockValueAndAccountBalanceOutOfSync(frappe.ValidationError):
-	pass
-
-
 class FiscalYearError(frappe.ValidationError):
 	pass
 
@@ -1126,6 +1123,9 @@
 def repost_gle_for_stock_vouchers(
 	stock_vouchers, posting_date, company=None, warehouse_account=None
 ):
+	if not stock_vouchers:
+		return
+
 	def _delete_gl_entries(voucher_type, voucher_no):
 		frappe.db.sql(
 			"""delete from `tabGL Entry`
@@ -1133,6 +1133,8 @@
 			(voucher_type, voucher_no),
 		)
 
+	stock_vouchers = sort_stock_vouchers_by_posting_date(stock_vouchers)
+
 	if not warehouse_account:
 		warehouse_account = get_warehouse_account_map(company)
 
@@ -1153,6 +1155,27 @@
 			_delete_gl_entries(voucher_type, voucher_no)
 
 
+def sort_stock_vouchers_by_posting_date(
+	stock_vouchers: List[Tuple[str, str]]
+) -> List[Tuple[str, str]]:
+	sle = frappe.qb.DocType("Stock Ledger Entry")
+	voucher_nos = [v[1] for v in stock_vouchers]
+
+	sles = (
+		frappe.qb.from_(sle)
+		.select(sle.voucher_type, sle.voucher_no, sle.posting_date, sle.posting_time, sle.creation)
+		.where((sle.is_cancelled == 0) & (sle.voucher_no.isin(voucher_nos)))
+		.groupby(sle.voucher_type, sle.voucher_no)
+	).run(as_dict=True)
+	sorted_vouchers = [(sle.voucher_type, sle.voucher_no) for sle in sles]
+
+	unknown_vouchers = set(stock_vouchers) - set(sorted_vouchers)
+	if unknown_vouchers:
+		sorted_vouchers.extend(unknown_vouchers)
+
+	return sorted_vouchers
+
+
 def get_future_stock_vouchers(
 	posting_date, posting_time, for_warehouses=None, for_items=None, company=None
 ):
@@ -1246,47 +1269,6 @@
 	return matched
 
 
-def check_if_stock_and_account_balance_synced(
-	posting_date, company, voucher_type=None, voucher_no=None
-):
-	if not cint(erpnext.is_perpetual_inventory_enabled(company)):
-		return
-
-	accounts = get_stock_accounts(company, voucher_type, voucher_no)
-	stock_adjustment_account = frappe.db.get_value("Company", company, "stock_adjustment_account")
-
-	for account in accounts:
-		account_bal, stock_bal, warehouse_list = get_stock_and_account_balance(
-			account, posting_date, company
-		)
-
-		if abs(account_bal - stock_bal) > 0.1:
-			precision = get_field_precision(
-				frappe.get_meta("GL Entry").get_field("debit"),
-				currency=frappe.get_cached_value("Company", company, "default_currency"),
-			)
-
-			diff = flt(stock_bal - account_bal, precision)
-
-			error_reason = _(
-				"Stock Value ({0}) and Account Balance ({1}) are out of sync for account {2} and it's linked warehouses as on {3}."
-			).format(stock_bal, account_bal, frappe.bold(account), posting_date)
-			error_resolution = _("Please create an adjustment Journal Entry for amount {0} on {1}").format(
-				frappe.bold(diff), frappe.bold(posting_date)
-			)
-
-			frappe.msgprint(
-				msg="""{0}<br></br>{1}<br></br>""".format(error_reason, error_resolution),
-				raise_exception=StockValueAndAccountBalanceOutOfSync,
-				title=_("Values Out Of Sync"),
-				primary_action={
-					"label": _("Make Journal Entry"),
-					"client_action": "erpnext.route_to_adjustment_jv",
-					"args": get_journal_entry(account, stock_adjustment_account, diff),
-				},
-			)
-
-
 def get_stock_accounts(company, voucher_type=None, voucher_no=None):
 	stock_accounts = [
 		d.name
diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.json b/erpnext/buying/doctype/buying_settings/buying_settings.json
index 50321ba..89a9448 100644
--- a/erpnext/buying/doctype/buying_settings/buying_settings.json
+++ b/erpnext/buying/doctype/buying_settings/buying_settings.json
@@ -20,6 +20,7 @@
   "maintain_same_rate",
   "allow_multiple_items",
   "bill_for_rejected_quantity_in_purchase_invoice",
+  "enable_discount_accounting",
   "subcontract",
   "backflush_raw_materials_of_subcontract_based_on",
   "column_break_11",
@@ -133,6 +134,13 @@
   {
    "fieldname": "column_break_12",
    "fieldtype": "Column Break"
+  },
+  {
+   "default": "0",
+   "description": "If enabled, additional ledger entries will be made for discounts in a separate Discount Account",
+   "fieldname": "enable_discount_accounting",
+   "fieldtype": "Check",
+   "label": "Enable Discount Accounting for Buying"
   }
  ],
  "icon": "fa fa-cog",
@@ -140,7 +148,7 @@
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2022-01-27 17:57:58.367048",
+ "modified": "2022-04-14 15:56:42.340223",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Buying Settings",
diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.py b/erpnext/buying/doctype/buying_settings/buying_settings.py
index 5507254..c52b59e 100644
--- a/erpnext/buying/doctype/buying_settings/buying_settings.py
+++ b/erpnext/buying/doctype/buying_settings/buying_settings.py
@@ -5,10 +5,15 @@
 
 
 import frappe
+from frappe.custom.doctype.property_setter.property_setter import make_property_setter
 from frappe.model.document import Document
+from frappe.utils import cint
 
 
 class BuyingSettings(Document):
+	def on_update(self):
+		self.toggle_discount_accounting_fields()
+
 	def validate(self):
 		for key in ["supplier_group", "supp_master_name", "maintain_same_rate", "buying_price_list"]:
 			frappe.db.set_default(key, self.get(key, ""))
@@ -21,3 +26,60 @@
 			self.get("supp_master_name") == "Naming Series",
 			hide_name_field=False,
 		)
+
+	def toggle_discount_accounting_fields(self):
+		enable_discount_accounting = cint(self.enable_discount_accounting)
+
+		make_property_setter(
+			"Purchase Invoice Item",
+			"discount_account",
+			"hidden",
+			not (enable_discount_accounting),
+			"Check",
+			validate_fields_for_doctype=False,
+		)
+		if enable_discount_accounting:
+			make_property_setter(
+				"Purchase Invoice Item",
+				"discount_account",
+				"mandatory_depends_on",
+				"eval: doc.discount_amount",
+				"Code",
+				validate_fields_for_doctype=False,
+			)
+		else:
+			make_property_setter(
+				"Purchase Invoice Item",
+				"discount_account",
+				"mandatory_depends_on",
+				"",
+				"Code",
+				validate_fields_for_doctype=False,
+			)
+
+		make_property_setter(
+			"Purchase Invoice",
+			"additional_discount_account",
+			"hidden",
+			not (enable_discount_accounting),
+			"Check",
+			validate_fields_for_doctype=False,
+		)
+		if enable_discount_accounting:
+			make_property_setter(
+				"Purchase Invoice",
+				"additional_discount_account",
+				"mandatory_depends_on",
+				"eval: doc.discount_amount",
+				"Code",
+				validate_fields_for_doctype=False,
+			)
+		else:
+			make_property_setter(
+				"Purchase Invoice",
+				"additional_discount_account",
+				"mandatory_depends_on",
+				"",
+				"Code",
+				validate_fields_for_doctype=False,
+			)
diff --git a/erpnext/buying/doctype/request_for_quotation/test_request_for_quotation.py b/erpnext/buying/doctype/request_for_quotation/test_request_for_quotation.py
index dcdba09..064b806 100644
--- a/erpnext/buying/doctype/request_for_quotation/test_request_for_quotation.py
+++ b/erpnext/buying/doctype/request_for_quotation/test_request_for_quotation.py
@@ -65,7 +65,6 @@
 		)
 		sq.submit()
 
-		frappe.form_dict = frappe.local("form_dict")
 		frappe.form_dict.name = rfq.name
 
 		self.assertEqual(check_supplier_has_docname_access(supplier_wt_appos[0].get("supplier")), True)
diff --git a/erpnext/buying/doctype/supplier/supplier.json b/erpnext/buying/doctype/supplier/supplier.json
index a57d9a9..e0ee658 100644
--- a/erpnext/buying/doctype/supplier/supplier.json
+++ b/erpnext/buying/doctype/supplier/supplier.json
@@ -18,16 +18,16 @@
   "tax_id",
   "tax_category",
   "tax_withholding_category",
-  "is_transporter",
-  "is_internal_supplier",
-  "represents_company",
   "image",
   "column_break0",
   "supplier_group",
   "supplier_type",
   "allow_purchase_invoice_creation_without_purchase_order",
   "allow_purchase_invoice_creation_without_purchase_receipt",
+  "is_internal_supplier",
+  "represents_company",
   "disabled",
+  "is_transporter",
   "warn_rfqs",
   "warn_pos",
   "prevent_rfqs",
@@ -38,12 +38,6 @@
   "default_currency",
   "column_break_10",
   "default_price_list",
-  "section_credit_limit",
-  "payment_terms",
-  "cb_21",
-  "on_hold",
-  "hold_type",
-  "release_date",
   "address_contacts",
   "address_html",
   "column_break1",
@@ -57,6 +51,12 @@
   "primary_address",
   "default_payable_accounts",
   "accounts",
+  "section_credit_limit",
+  "payment_terms",
+  "cb_21",
+  "on_hold",
+  "hold_type",
+  "release_date",
   "default_tax_withholding_config",
   "column_break2",
   "website",
@@ -258,7 +258,7 @@
    "collapsible": 1,
    "fieldname": "section_credit_limit",
    "fieldtype": "Section Break",
-   "label": "Credit Limit"
+   "label": "Payment Terms"
   },
   {
    "fieldname": "payment_terms",
@@ -432,7 +432,7 @@
    "link_fieldname": "party"
   }
  ],
- "modified": "2021-10-20 22:03:33.147249",
+ "modified": "2022-04-16 18:02:27.838623",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Supplier",
@@ -497,6 +497,7 @@
  "show_name_in_global_search": 1,
  "sort_field": "modified",
  "sort_order": "ASC",
+ "states": [],
  "title_field": "supplier_name",
  "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 7cbd2bd..78645e0 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -1079,9 +1079,14 @@
 		return amount, base_amount
 
 	def make_discount_gl_entries(self, gl_entries):
-		enable_discount_accounting = cint(
-			frappe.db.get_single_value("Accounts Settings", "enable_discount_accounting")
-		)
+		if self.doctype == "Purchase Invoice":
+			enable_discount_accounting = cint(
+				frappe.db.get_single_value("Buying Settings", "enable_discount_accounting")
+			)
+		elif self.doctype == "Sales Invoice":
+			enable_discount_accounting = cint(
+				frappe.db.get_single_value("Selling Settings", "enable_discount_accounting")
+			)
 
 		if enable_discount_accounting:
 			if self.doctype == "Purchase Invoice":
@@ -1997,12 +2002,13 @@
 
 	reference_condition = " and (" + " or ".join(conditions) + ")" if conditions else ""
 
+	# nosemgrep
 	journal_entries = frappe.db.sql(
 		"""
 		select
 			"Journal Entry" as reference_type, t1.name as reference_name,
 			t1.remark as remarks, t2.{0} as amount, t2.name as reference_row,
-			t2.reference_name as against_order
+			t2.reference_name as against_order, t2.exchange_rate
 		from
 			`tabJournal Entry` t1, `tabJournal Entry Account` t2
 		where
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index eda3686..233b476 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -22,6 +22,9 @@
 
 
 class BuyingController(StockController, Subcontracting):
+	def __setup__(self):
+		self.flags.ignore_permlevel_for_fields = ["buying_price_list", "price_list_currency"]
+
 	def get_feed(self):
 		if self.get("supplier_name"):
 			return _("From {0} | {1} {2}").format(self.supplier_name, self.currency, self.grand_total)
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 7877827..19fedb3 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -16,6 +16,9 @@
 
 
 class SellingController(StockController):
+	def __setup__(self):
+		self.flags.ignore_permlevel_for_fields = ["selling_price_list", "price_list_currency"]
+
 	def get_feed(self):
 		return _("To {0} | {1} {2}").format(self.customer_name, self.currency, self.grand_total)
 
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
index 6302d26..69b9cfa 100644
--- a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.js
+++ b/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.js
@@ -24,17 +24,16 @@
 			);
 		}
 
-		frappe.model.with_doctype("Item", () => {
+		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.fields_dict.filter_fields.grid.update_docfield_property(
-				'fieldname', 'fieldtype', 'Select'
+			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.fields_dict.filter_fields.grid.update_docfield_property(
+
+			frm.get_field("filter_fields").grid.update_docfield_property(
 				'fieldname', 'options', valid_fields
 			);
 		});
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
index f85667e..c27d29a 100644
--- a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.py
+++ b/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.py
@@ -27,7 +27,7 @@
 		self.is_redisearch_loaded = is_search_module_loaded()
 
 	def validate(self):
-		self.validate_field_filters()
+		self.validate_field_filters(self.filter_fields, self.enable_field_filters)
 		self.validate_attribute_filters()
 		self.validate_checkout()
 		self.validate_search_index_fields()
@@ -51,21 +51,22 @@
 			define_autocomplete_dictionary()
 			create_website_items_index()
 
-	def validate_field_filters(self):
-		if not (self.enable_field_filters and self.filter_fields):
+	@staticmethod
+	def validate_field_filters(filter_fields, enable_field_filters):
+		if not (enable_field_filters and filter_fields):
 			return
 
-		item_meta = frappe.get_meta("Item")
+		web_item_meta = frappe.get_meta("Website Item")
 		valid_fields = [
-			df.fieldname for df in item_meta.fields if df.fieldtype in ["Link", "Table MultiSelect"]
+			df.fieldname for df in web_item_meta.fields if df.fieldtype in ["Link", "Table MultiSelect"]
 		]
 
-		for f in self.filter_fields:
-			if f.fieldname not in valid_fields:
+		for row in filter_fields:
+			if row.fieldname not in valid_fields:
 				frappe.throw(
 					_(
-						"Filter Fields Row #{0}: Fieldname <b>{1}</b> must be of type 'Link' or 'Table MultiSelect'"
-					).format(f.idx, f.fieldname)
+						"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):
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
index c4c958b..662db4d 100644
--- 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
@@ -1,5 +1,4 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
+# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
 # See license.txt
 import unittest
 
@@ -11,44 +10,35 @@
 
 
 class TestECommerceSettings(unittest.TestCase):
-	def setUp(self):
-		frappe.db.sql("""delete from `tabSingles` where doctype="Shipping Cart Settings" """)
-
-	def get_cart_settings(self):
-		return frappe.get_doc({"doctype": "E Commerce Settings", "company": "_Test Company"})
-
-	# NOTE: Exchangrate API has all enabled currencies that ERPNext supports.
-	# We aren't checking just currency exchange record anymore
-	# while validating price list currency exchange rate to that of company.
-	# The API is being used to fetch the rate which again almost always
-	# gives back a valid value (for valid currencies).
-	# This makes the test obsolete.
-	# Commenting because im not sure if there's a better test we can write
-
-	# def test_exchange_rate_exists(self):
-	# 	frappe.db.sql("""delete from `tabCurrency Exchange`""")
-
-	# 	cart_settings = self.get_cart_settings()
-	# 	cart_settings.price_list = "_Test Price List Rest of the World"
-	# 	self.assertRaises(ShoppingCartSetupError, cart_settings.validate_exchange_rates_exist)
-
-	# 	from erpnext.setup.doctype.currency_exchange.test_currency_exchange import (
-	# 		test_records as currency_exchange_records,
-	# 	)
-	# 	frappe.get_doc(currency_exchange_records[0]).insert()
-	# 	cart_settings.validate_exchange_rates_exist()
+	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 = self.get_cart_settings()
+		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."
diff --git a/erpnext/e_commerce/product_data_engine/filters.py b/erpnext/e_commerce/product_data_engine/filters.py
index feb89c1..e5e5e97 100644
--- a/erpnext/e_commerce/product_data_engine/filters.py
+++ b/erpnext/e_commerce/product_data_engine/filters.py
@@ -22,12 +22,14 @@
 		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 Item
-		item_meta = frappe.get_meta("Item", cached=True)
-		fields = [item_meta.get_field(field) for field in filter_fields if item_meta.has_field(field)]
+		# 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_in_website": 1}, []
+			item_filters, item_or_filters = {"published": 1}, []
 			link_doctype_values = self.get_filtered_link_doctype_records(df)
 
 			if df.fieldtype == "Link":
@@ -50,9 +52,13 @@
 							]
 						)
 
+				# 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(
-					"Item",
+					"Website Item",
 					fields=[df.fieldname],
 					filters=item_filters,
 					or_filters=item_or_filters,
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
index ab958d1..c3b6ed5 100644
--- a/erpnext/e_commerce/product_data_engine/test_product_data_engine.py
+++ b/erpnext/e_commerce/product_data_engine/test_product_data_engine.py
@@ -277,6 +277,54 @@
 		# 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."
diff --git a/erpnext/erpnext_integrations/exotel_integration.py b/erpnext/erpnext_integrations/exotel_integration.py
index 1f5df67..522de9e 100644
--- a/erpnext/erpnext_integrations/exotel_integration.py
+++ b/erpnext/erpnext_integrations/exotel_integration.py
@@ -37,11 +37,26 @@
 
 @frappe.whitelist(allow_guest=True)
 def handle_missed_call(**kwargs):
-	update_call_log(kwargs, "Missed")
+	status = ""
+	call_type = kwargs.get("CallType")
+	dial_call_status = kwargs.get("DialCallStatus")
+
+	if call_type == "incomplete" and dial_call_status == "no-answer":
+		status = "No Answer"
+	elif call_type == "client-hangup" and dial_call_status == "canceled":
+		status = "Canceled"
+	elif call_type == "incomplete" and dial_call_status == "failed":
+		status = "Failed"
+
+	update_call_log(kwargs, status)
 
 
 def update_call_log(call_payload, status="Ringing", call_log=None):
 	call_log = call_log or get_call_log(call_payload)
+
+	# for a new sid, call_log and get_call_log will be empty so create a new log
+	if not call_log:
+		call_log = create_call_log(call_payload)
 	if call_log:
 		call_log.status = status
 		call_log.to = call_payload.get("DialWhomNumber")
@@ -53,16 +68,9 @@
 
 
 def get_call_log(call_payload):
-	call_log = frappe.get_all(
-		"Call Log",
-		{
-			"id": call_payload.get("CallSid"),
-		},
-		limit=1,
-	)
-
-	if call_log:
-		return frappe.get_doc("Call Log", call_log[0].name)
+	call_log_id = call_payload.get("CallSid")
+	if frappe.db.exists("Call Log", call_log_id):
+		return frappe.get_doc("Call Log", call_log_id)
 
 
 def create_call_log(call_payload):
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 1c009d3..fe0a89a 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -59,6 +59,7 @@
 	"Warehouse",
 	"Item Group",
 	"Customer Group",
+	"Supplier Group",
 	"Sales Person",
 	"Territory",
 	"Assessment Group",
diff --git a/erpnext/hr/doctype/employee/employee.json b/erpnext/hr/doctype/employee/employee.json
index d592a9c..a3638e1 100644
--- a/erpnext/hr/doctype/employee/employee.json
+++ b/erpnext/hr/doctype/employee/employee.json
@@ -4,7 +4,7 @@
  "allow_import": 1,
  "allow_rename": 1,
  "autoname": "naming_series:",
- "creation": "2013-03-07 09:04:18",
+ "creation": "2022-02-21 11:54:09.632218",
  "doctype": "DocType",
  "document_type": "Setup",
  "editable_grid": 1,
@@ -62,6 +62,8 @@
   "holiday_list",
   "default_shift",
   "salary_information",
+  "salary_currency",
+  "ctc",
   "salary_mode",
   "payroll_cost_center",
   "column_break_52",
@@ -807,17 +809,30 @@
    "fieldtype": "Link",
    "label": "Shift Request Approver",
    "options": "User"
+  },
+  {
+   "fieldname": "salary_currency",
+   "fieldtype": "Link",
+   "label": "Salary Currency",
+   "options": "Currency"
+  },
+  {
+   "fieldname": "ctc",
+   "fieldtype": "Currency",
+   "label": "Cost to Company (CTC)",
+   "options": "salary_currency"
   }
  ],
  "icon": "fa fa-user",
  "idx": 24,
  "image_field": "image",
  "links": [],
- "modified": "2021-06-17 11:31:37.730760",
+ "modified": "2022-04-22 16:21:55.811983",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Employee",
  "name_case": "Title Case",
+ "naming_rule": "By \"Naming Series\" field",
  "owner": "Administrator",
  "permissions": [
   {
@@ -857,7 +872,9 @@
  ],
  "search_fields": "employee_name",
  "show_name_in_global_search": 1,
+ "show_title_field_in_link": 1,
  "sort_field": "modified",
  "sort_order": "DESC",
+ "states": [],
  "title_field": "employee_name"
 }
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_checkin/test_employee_checkin.py b/erpnext/hr/doctype/employee_checkin/test_employee_checkin.py
index 81b44f8..ced42bb 100644
--- a/erpnext/hr/doctype/employee_checkin/test_employee_checkin.py
+++ b/erpnext/hr/doctype/employee_checkin/test_employee_checkin.py
@@ -153,6 +153,31 @@
 		log = make_checkin(employee, timestamp)
 		self.assertIsNone(log.shift)
 
+	def test_fetch_shift_for_assignment_with_end_date(self):
+		employee = make_employee("test_employee_checkin@example.com", company="_Test Company")
+
+		# shift setup for 8-12
+		shift1 = setup_shift_type()
+		# 12:30 - 16:30
+		shift2 = setup_shift_type(shift_type="Shift 2", start_time="12:30:00", end_time="16:30:00")
+
+		date = getdate()
+		make_shift_assignment(shift1.name, employee, date, add_days(date, 15))
+		make_shift_assignment(shift2.name, employee, date, add_days(date, 15))
+
+		timestamp = datetime.combine(date, get_time("08:45:00"))
+		log = make_checkin(employee, timestamp)
+		self.assertEqual(log.shift, shift1.name)
+
+		timestamp = datetime.combine(date, get_time("12:45:00"))
+		log = make_checkin(employee, timestamp)
+		self.assertEqual(log.shift, shift2.name)
+
+		# log after end date
+		timestamp = datetime.combine(add_days(date, 16), get_time("12:45:00"))
+		log = make_checkin(employee, timestamp)
+		self.assertIsNone(log.shift)
+
 	def test_shift_start_and_end_timings(self):
 		employee = make_employee("test_employee_checkin@example.com", company="_Test Company")
 
diff --git a/erpnext/hr/doctype/employee_promotion/employee_promotion.json b/erpnext/hr/doctype/employee_promotion/employee_promotion.json
index e0fbd23..173573e 100644
--- a/erpnext/hr/doctype/employee_promotion/employee_promotion.json
+++ b/erpnext/hr/doctype/employee_promotion/employee_promotion.json
@@ -1,397 +1,172 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "autoname": "HR-EMP-PRO-.YYYY.-.#####", 
- "beta": 0, 
- "creation": "2018-04-13 18:33:59.476562", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "autoname": "HR-EMP-PRO-.YYYY.-.#####",
+ "creation": "2018-04-13 18:33:59.476562",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "employee",
+  "employee_name",
+  "department",
+  "salary_currency",
+  "column_break_3",
+  "promotion_date",
+  "company",
+  "details_section",
+  "promotion_details",
+  "salary_details_section",
+  "current_ctc",
+  "column_break_12",
+  "revised_ctc",
+  "amended_from"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "employee", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Employee", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Employee", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "employee",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Employee",
+   "options": "Employee",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "employee.employee_name", 
-   "fieldname": "employee_name", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Employee Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "employee.employee_name",
+   "fieldname": "employee_name",
+   "fieldtype": "Data",
+   "label": "Employee Name",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "employee.department", 
-   "fieldname": "department", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Department", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Department", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "employee.department",
+   "fieldname": "department",
+   "fieldtype": "Link",
+   "label": "Department",
+   "options": "Department",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_3", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "promotion_date", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Promotion Date", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "promotion_date",
+   "fieldtype": "Date",
+   "label": "Promotion Date",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "employee.company", 
-   "fieldname": "company", 
-   "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": "Company", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Company", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "employee.company",
+   "fieldname": "company",
+   "fieldtype": "Link",
+   "label": "Company",
+   "options": "Company"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "details_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": "Employee Promotion 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
-  }, 
+   "description": "Set the properties that should be updated in the Employee master on promotion submission",
+   "fieldname": "details_section",
+   "fieldtype": "Section Break",
+   "label": "Employee Promotion Details"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "promotion_details", 
-   "fieldtype": "Table", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Employee Promotion Detail", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Employee Property History", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "promotion_details",
+   "fieldtype": "Table",
+   "options": "Employee Property History",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "amended_from", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Amended From", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Employee Promotion", 
-   "permlevel": 0, 
-   "print_hide": 1, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
+   "fieldname": "amended_from",
+   "fieldtype": "Link",
+   "label": "Amended From",
+   "no_copy": 1,
+   "options": "Employee Promotion",
+   "print_hide": 1,
+   "read_only": 1
+  },
+  {
+   "fieldname": "salary_details_section",
+   "fieldtype": "Section Break",
+   "label": "Salary Details"
+  },
+  {
+   "fieldname": "column_break_12",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fetch_from": "employee.salary_currency",
+   "fieldname": "salary_currency",
+   "fieldtype": "Link",
+   "label": "Salary Currency",
+   "options": "Currency",
+   "read_only": 1
+  },
+  {
+   "fetch_from": "employee.ctc",
+   "fetch_if_empty": 1,
+   "fieldname": "current_ctc",
+   "fieldtype": "Currency",
+   "label": "Current CTC",
+   "mandatory_depends_on": "revised_ctc",
+   "options": "salary_currency"
+  },
+  {
+   "depends_on": "current_ctc",
+   "fieldname": "revised_ctc",
+   "fieldtype": "Currency",
+   "label": "Revised CTC",
+   "options": "salary_currency"
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 1, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-08-21 16:15:40.284987", 
- "modified_by": "Administrator", 
- "module": "HR", 
- "name": "Employee Promotion", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2022-04-22 18:47:10.168744",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Employee Promotion",
+ "naming_rule": "Expression (old style)",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 0, 
-   "delete": 0, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Employee", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 0
-  }, 
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Employee",
+   "share": 1
+  },
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 0, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "HR User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 1, 
+   "create": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "HR User",
+   "share": 1,
+   "submit": 1,
    "write": 1
-  }, 
+  },
   {
-   "amend": 1, 
-   "cancel": 1, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "HR Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 1, 
+   "amend": 1,
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "HR Manager",
+   "share": 1,
+   "submit": 1,
    "write": 1
   }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "title_field": "employee_name", 
- "track_changes": 1, 
- "track_seen": 0, 
- "track_views": 0
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": [],
+ "title_field": "employee_name",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_promotion/employee_promotion.py b/erpnext/hr/doctype/employee_promotion/employee_promotion.py
index d77c1dd..8c802e9 100644
--- a/erpnext/hr/doctype/employee_promotion/employee_promotion.py
+++ b/erpnext/hr/doctype/employee_promotion/employee_promotion.py
@@ -26,9 +26,17 @@
 		employee = update_employee_work_history(
 			employee, self.promotion_details, date=self.promotion_date
 		)
+
+		if self.revised_ctc:
+			employee.ctc = self.revised_ctc
+
 		employee.save()
 
 	def on_cancel(self):
 		employee = frappe.get_doc("Employee", self.employee)
 		employee = update_employee_work_history(employee, self.promotion_details, cancel=True)
+
+		if self.revised_ctc:
+			employee.ctc = self.current_ctc
+
 		employee.save()
diff --git a/erpnext/hr/doctype/employee_promotion/test_employee_promotion.py b/erpnext/hr/doctype/employee_promotion/test_employee_promotion.py
index 06825ec..71bb1a6 100644
--- a/erpnext/hr/doctype/employee_promotion/test_employee_promotion.py
+++ b/erpnext/hr/doctype/employee_promotion/test_employee_promotion.py
@@ -4,21 +4,22 @@
 import unittest
 
 import frappe
+from frappe.tests.utils import FrappeTestCase
 from frappe.utils import add_days, getdate
 
 from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_employee
 
 
-class TestEmployeePromotion(unittest.TestCase):
+class TestEmployeePromotion(FrappeTestCase):
 	def setUp(self):
-		self.employee = make_employee("employee@promotions.com")
-		frappe.db.sql("""delete from `tabEmployee Promotion`""")
+		frappe.db.delete("Employee Promotion")
 
 	def test_submit_before_promotion_date(self):
-		promotion_obj = frappe.get_doc(
+		employee = make_employee("employee@promotions.com")
+		promotion = frappe.get_doc(
 			{
 				"doctype": "Employee Promotion",
-				"employee": self.employee,
+				"employee": employee,
 				"promotion_details": [
 					{
 						"property": "Designation",
@@ -29,10 +30,68 @@
 				],
 			}
 		)
-		promotion_obj.promotion_date = add_days(getdate(), 1)
-		promotion_obj.save()
-		self.assertRaises(frappe.DocstatusTransitionError, promotion_obj.submit)
-		promotion = frappe.get_doc("Employee Promotion", promotion_obj.name)
+		promotion.promotion_date = add_days(getdate(), 1)
+		self.assertRaises(frappe.DocstatusTransitionError, promotion.submit)
+
 		promotion.promotion_date = getdate()
 		promotion.submit()
 		self.assertEqual(promotion.docstatus, 1)
+
+	def test_employee_history(self):
+		for grade in ["L1", "L2"]:
+			frappe.get_doc({"doctype": "Employee Grade", "__newname": grade}).insert()
+
+		employee = make_employee(
+			"test_employee_promotion@example.com",
+			company="_Test Company",
+			date_of_birth=getdate("30-09-1980"),
+			date_of_joining=getdate("01-10-2021"),
+			designation="Software Developer",
+			grade="L1",
+			salary_currency="INR",
+			ctc="500000",
+		)
+
+		promotion = frappe.get_doc(
+			{
+				"doctype": "Employee Promotion",
+				"employee": employee,
+				"promotion_date": getdate(),
+				"revised_ctc": "1000000",
+				"promotion_details": [
+					{
+						"property": "Designation",
+						"current": "Software Developer",
+						"new": "Project Manager",
+						"fieldname": "designation",
+					},
+					{"property": "Grade", "current": "L1", "new": "L2", "fieldname": "grade"},
+				],
+			}
+		).submit()
+
+		# employee fields updated
+		employee = frappe.get_doc("Employee", employee)
+		self.assertEqual(employee.grade, "L2")
+		self.assertEqual(employee.designation, "Project Manager")
+		self.assertEqual(employee.ctc, 1000000)
+
+		# internal work history updated
+		self.assertEqual(employee.internal_work_history[0].designation, "Software Developer")
+		self.assertEqual(employee.internal_work_history[0].from_date, getdate("01-10-2021"))
+
+		self.assertEqual(employee.internal_work_history[1].designation, "Project Manager")
+		self.assertEqual(employee.internal_work_history[1].from_date, getdate())
+
+		promotion.cancel()
+		employee.reload()
+
+		# fields restored
+		self.assertEqual(employee.grade, "L1")
+		self.assertEqual(employee.designation, "Software Developer")
+		self.assertEqual(employee.ctc, 500000)
+
+		# internal work history updated on cancellation
+		self.assertEqual(len(employee.internal_work_history), 1)
+		self.assertEqual(employee.internal_work_history[0].designation, "Software Developer")
+		self.assertEqual(employee.internal_work_history[0].from_date, getdate("01-10-2021"))
diff --git a/erpnext/hr/doctype/employee_transfer_property/employee_transfer_property.js b/erpnext/hr/doctype/employee_transfer_property/employee_transfer_property.js
deleted file mode 100644
index 9987c82..0000000
--- a/erpnext/hr/doctype/employee_transfer_property/employee_transfer_property.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Employee Transfer Property', {
-	refresh: function(frm) {
-
-	}
-});
diff --git a/erpnext/hr/doctype/employee_transfer_property/employee_transfer_property.json b/erpnext/hr/doctype/employee_transfer_property/employee_transfer_property.json
deleted file mode 100644
index 829169d..0000000
--- a/erpnext/hr/doctype/employee_transfer_property/employee_transfer_property.json
+++ /dev/null
@@ -1,154 +0,0 @@
-{
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "beta": 0, 
- "creation": "2018-04-13 18:24:30.579965", 
- "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": "property", 
-   "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": "Property", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "current", 
-   "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": "Current", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "new", 
-   "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": "New", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-04-13 18:25:54.889579", 
- "modified_by": "Administrator", 
- "module": "HR", 
- "name": "Employee Transfer Property", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "System Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }
- ], 
- "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
-}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_transfer_property/employee_transfer_property.py b/erpnext/hr/doctype/employee_transfer_property/employee_transfer_property.py
deleted file mode 100644
index 76e2006..0000000
--- a/erpnext/hr/doctype/employee_transfer_property/employee_transfer_property.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-
-from frappe.model.document import Document
-
-
-class EmployeeTransferProperty(Document):
-	pass
diff --git a/erpnext/hr/doctype/employee_transfer_property/test_employee_transfer_property.py b/erpnext/hr/doctype/employee_transfer_property/test_employee_transfer_property.py
deleted file mode 100644
index 981d46f..0000000
--- a/erpnext/hr/doctype/employee_transfer_property/test_employee_transfer_property.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-
-import unittest
-
-
-class TestEmployeeTransferProperty(unittest.TestCase):
-	pass
diff --git a/erpnext/hr/doctype/shift_assignment/shift_assignment.py b/erpnext/hr/doctype/shift_assignment/shift_assignment.py
index 0b21c00..51298de 100644
--- a/erpnext/hr/doctype/shift_assignment/shift_assignment.py
+++ b/erpnext/hr/doctype/shift_assignment/shift_assignment.py
@@ -121,7 +121,7 @@
 
 @frappe.whitelist()
 def get_events(start, end, filters=None):
-	events = []
+	from frappe.desk.calendar import get_event_conditions
 
 	employee = frappe.db.get_value(
 		"Employee", {"user_id": frappe.session.user}, ["name", "company"], as_dict=True
@@ -132,20 +132,22 @@
 		employee = ""
 		company = frappe.db.get_value("Global Defaults", None, "default_company")
 
-	from frappe.desk.reportview import get_filters_cond
-
-	conditions = get_filters_cond("Shift Assignment", filters, [])
-	add_assignments(events, start, end, conditions=conditions)
+	conditions = get_event_conditions("Shift Assignment", filters)
+	events = add_assignments(start, end, conditions=conditions)
 	return events
 
 
-def add_assignments(events, start, end, conditions=None):
+def add_assignments(start, end, conditions=None):
+	events = []
+
 	query = """select name, start_date, end_date, employee_name,
 		employee, docstatus, shift_type
 		from `tabShift Assignment` where
-		start_date >= %(start_date)s
-		or end_date <=  %(end_date)s
-		or (%(start_date)s between start_date and end_date and %(end_date)s between start_date and end_date)
+		(
+			start_date >= %(start_date)s
+			or end_date <=  %(end_date)s
+			or (%(start_date)s between start_date and end_date and %(end_date)s between start_date and end_date)
+		)
 		and docstatus = 1"""
 	if conditions:
 		query += conditions
@@ -251,7 +253,7 @@
 				Criterion.any(
 					[
 						assignment.end_date.isnull(),
-						(assignment.end_date.isnotnull() & (getdate(for_timestamp.date()) >= assignment.end_date)),
+						(assignment.end_date.isnotnull() & (getdate(for_timestamp.date()) <= assignment.end_date)),
 					]
 				)
 			)
diff --git a/erpnext/hr/doctype/shift_assignment/test_shift_assignment.py b/erpnext/hr/doctype/shift_assignment/test_shift_assignment.py
index 0fe9108..de82a24 100644
--- a/erpnext/hr/doctype/shift_assignment/test_shift_assignment.py
+++ b/erpnext/hr/doctype/shift_assignment/test_shift_assignment.py
@@ -8,7 +8,7 @@
 from frappe.utils import add_days, getdate, nowdate
 
 from erpnext.hr.doctype.employee.test_employee import make_employee
-from erpnext.hr.doctype.shift_assignment.shift_assignment import OverlappingShiftError
+from erpnext.hr.doctype.shift_assignment.shift_assignment import OverlappingShiftError, get_events
 from erpnext.hr.doctype.shift_type.test_shift_type import make_shift_assignment, setup_shift_type
 
 test_dependencies = ["Shift Type"]
@@ -154,3 +154,18 @@
 		shift_type = setup_shift_type(shift_type="Shift 2", start_time="13:00:00", end_time="15:00:00")
 		date = getdate()
 		make_shift_assignment(shift_type.name, employee, date)
+
+	def test_shift_assignment_calendar(self):
+		employee1 = make_employee("test_shift_assignment1@example.com", company="_Test Company")
+		employee2 = make_employee("test_shift_assignment2@example.com", company="_Test Company")
+
+		shift_type = setup_shift_type(shift_type="Shift 1", start_time="08:00:00", end_time="12:00:00")
+		date = getdate()
+		shift1 = make_shift_assignment(shift_type.name, employee1, date)
+		make_shift_assignment(shift_type.name, employee2, date)
+
+		events = get_events(
+			start=date, end=date, filters=[["Shift Assignment", "employee", "=", employee1, False]]
+		)
+		self.assertEqual(len(events), 1)
+		self.assertEqual(events[0]["name"], shift1.name)
diff --git a/erpnext/hr/employee_property_update.js b/erpnext/hr/employee_property_update.js
index 60d06b4..86130bf 100644
--- a/erpnext/hr/employee_property_update.js
+++ b/erpnext/hr/employee_property_update.js
@@ -8,39 +8,65 @@
 			};
 		});
 	},
-	onload: function(frm){
-		if(frm.doc.__islocal){
-			if(frm.doctype == "Employee Promotion"){
-				frm.doc.promotion_details = [];
-			}else if (frm.doctype == "Employee Transfer") {
-				frm.doc.transfer_details = [];
-			}
-		}
+
+	onload: function(frm) {
+		if (frm.doc.__islocal)
+			frm.trigger("clear_property_table");
 	},
+
 	employee: function(frm) {
-		frm.add_fetch("employee", "company", "company");
+		frm.trigger("clear_property_table");
 	},
+
+	clear_property_table: function(frm) {
+		let table = (frm.doctype == "Employee Promotion") ? "promotion_details" : "transfer_details";
+		frm.clear_table(table);
+		frm.refresh_field(table);
+
+		frm.fields_dict[table].grid.wrapper.find(".grid-add-row").hide();
+	},
+
 	refresh: function(frm) {
-		var table;
-		if(frm.doctype == "Employee Promotion"){
+		let table;
+		if (frm.doctype == "Employee Promotion") {
 			table = "promotion_details";
-		}else if (frm.doctype == "Employee Transfer") {
+		} else if (frm.doctype == "Employee Transfer") {
 			table = "transfer_details";
 		}
-		if(!table){return;}
-		cur_frm.fields_dict[table].grid.wrapper.find('.grid-add-row').hide();
-		cur_frm.fields_dict[table].grid.add_custom_button(__('Add Row'), () => {
-			if(!frm.doc.employee){
-				frappe.msgprint(__("Please select Employee"));
+
+		if (!table)
+			return;
+
+		frm.fields_dict[table].grid.wrapper.find(".grid-add-row").hide();
+		frm.events.setup_employee_property_button(frm, table);
+	},
+
+	setup_employee_property_button: function(frm, table) {
+		frm.fields_dict[table].grid.add_custom_button(__("Add Employee Property"), () => {
+			if (!frm.doc.employee) {
+				frappe.msgprint(__("Please select Employee first."));
 				return;
 			}
-			frappe.call({
-				method: 'erpnext.hr.utils.get_employee_fields_label',
-				callback: function(r) {
-					if(r.message){
-						show_dialog(frm, table, r.message);
+
+			const allowed_fields = [];
+			const exclude_fields = ["naming_series", "employee", "first_name", "middle_name", "last_name", "marital_status", "ctc",
+				"employee_name", "status", "image", "gender", "date_of_birth", "date_of_joining", "lft", "rgt", "old_parent"];
+
+			const exclude_field_types = ["HTML", "Section Break", "Column Break", "Button", "Read Only", "Tab Break", "Table"];
+
+			frappe.model.with_doctype("Employee", () => {
+				const field_label_map = {};
+				frappe.get_meta("Employee").fields.forEach(d => {
+					field_label_map[d.fieldname] = __(d.label) + ` (${d.fieldname})`;
+					if (!in_list(exclude_field_types, d.fieldtype) && !in_list(exclude_fields, d.fieldname)) {
+						allowed_fields.push({
+							label: field_label_map[d.fieldname],
+							value: d.fieldname,
+						});
 					}
-				}
+				});
+
+				show_dialog(frm, table, allowed_fields);
 			});
 		});
 	}
@@ -50,21 +76,20 @@
 	var d = new frappe.ui.Dialog({
 		title: "Update Property",
 		fields: [
-			{fieldname: "property", label: __('Select Property'), fieldtype:"Select", options: field_labels},
-			{fieldname: "current", fieldtype: "Data", label:__('Current'), read_only: true},
-			{fieldname: "field_html", fieldtype: "HTML"}
+			{fieldname: "property", label: __("Select Property"), fieldtype: "Autocomplete", options: field_labels},
+			{fieldname: "current", fieldtype: "Data", label: __("Current"), read_only: true},
+			{fieldname: "new_value", fieldtype: "Data", label: __("New")}
 		],
-		primary_action_label: __('Add to Details'),
+		primary_action_label: __("Add to Details"),
 		primary_action: () => {
-			d.get_primary_btn().attr('disabled', true);
-			if(d.data) {
-				var input = $('[data-fieldname="field_html"] input');
-				d.data.new = input.val();
-				$(input).remove();
+			d.get_primary_btn().attr("disabled", true);
+			if (d.data) {
+				d.data.new = d.get_values().new_value;
 				add_to_details(frm, d, table);
 			}
 		}
 	});
+
 	d.fields_dict["property"].df.onchange = () => {
 		let property = d.get_values().property;
 		d.data.fieldname = property;
@@ -73,10 +98,10 @@
 			method: 'erpnext.hr.utils.get_employee_field_property',
 			args: {employee: frm.doc.employee, fieldname: property},
 			callback: function(r) {
-				if(r.message){
+				if (r.message) {
 					d.data.current = r.message.value;
 					d.data.property = r.message.label;
-					d.fields_dict.field_html.$wrapper.html("");
+
 					d.set_value('current', r.message.value);
 					render_dynamic_field(d, r.message.datatype, r.message.options, property);
 					d.get_primary_btn().attr('disabled', false);
@@ -95,25 +120,26 @@
 		df: {
 			"fieldtype": fieldtype,
 			"fieldname": fieldname,
-			"options": options || ''
+			"options": options || '',
+			"label": __("New")
 		},
-		parent: d.fields_dict.field_html.wrapper,
+		parent: d.fields_dict.new_value.wrapper,
 		only_input: false
 	});
 	dynamic_field.make_input();
-	$(dynamic_field.label_area).text(__("New"));
+	d.replace_field("new_value", dynamic_field.df);
 };
 
 var add_to_details = function(frm, d, table) {
 	let data = d.data;
-	if(data.fieldname){
-		if(validate_duplicate(frm, table, data.fieldname)){
-			frappe.show_alert({message:__("Property already added"), indicator:'orange'});
+	if (data.fieldname) {
+		if (validate_duplicate(frm, table, data.fieldname)) {
+			frappe.show_alert({message: __("Property already added"), indicator: "orange"});
 			return false;
 		}
-		if(data.current == data.new){
-			frappe.show_alert({message:__("Nothing to change"), indicator:'orange'});
-			d.get_primary_btn().attr('disabled', false);
+		if (data.current == data.new) {
+			frappe.show_alert({message: __("Nothing to change"), indicator: "orange"});
+			d.get_primary_btn().attr("disabled", false);
 			return false;
 		}
 		frm.add_child(table, {
@@ -123,13 +149,16 @@
 			new: data.new
 		});
 		frm.refresh_field(table);
-		d.fields_dict.field_html.$wrapper.html("");
+
+		frm.fields_dict[table].grid.wrapper.find(".grid-add-row").hide();
+
+		d.fields_dict.new_value.$wrapper.html("");
 		d.set_value("property", "");
-		d.set_value('current', "");
-		frappe.show_alert({message:__("Added to details"),indicator:'green'});
+		d.set_value("current", "");
+		frappe.show_alert({message: __("Added to details"), indicator: "green"});
 		d.data = {};
-	}else {
-		frappe.show_alert({message:__("Value missing"),indicator:'red'});
+	} else {
+		frappe.show_alert({message: __("Value missing"), indicator: "red"});
 	}
 };
 
diff --git a/erpnext/hr/utils.py b/erpnext/hr/utils.py
index 40ab805..4e30b0f 100644
--- a/erpnext/hr/utils.py
+++ b/erpnext/hr/utils.py
@@ -89,29 +89,6 @@
 
 
 @frappe.whitelist()
-def get_employee_fields_label():
-	fields = []
-	for df in frappe.get_meta("Employee").get("fields"):
-		if df.fieldname in [
-			"salutation",
-			"user_id",
-			"employee_number",
-			"employment_type",
-			"holiday_list",
-			"branch",
-			"department",
-			"designation",
-			"grade",
-			"notice_number_of_days",
-			"reports_to",
-			"leave_policy",
-			"company_email",
-		]:
-			fields.append({"value": df.fieldname, "label": df.label})
-	return fields
-
-
-@frappe.whitelist()
 def get_employee_field_property(employee, fieldname):
 	if employee and fieldname:
 		field = frappe.get_meta("Employee").get_field(fieldname)
diff --git a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js
index 035290d..5252798 100644
--- a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js
+++ b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js
@@ -140,26 +140,6 @@
 		}
 	}
 
-	start_date(doc, cdt, cdn) {
-		this.set_no_of_visits(doc, cdt, cdn);
-	}
-
-	end_date(doc, cdt, cdn) {
-		this.set_no_of_visits(doc, cdt, cdn);
-	}
-
-	periodicity(doc, cdt, cdn) {
-		this.set_no_of_visits(doc, cdt, cdn);
-	}
-
-	set_no_of_visits(doc, cdt, cdn) {
-		var item = frappe.get_doc(cdt, cdn);
-		let me = this;
-		if (item.start_date && item.periodicity) {
-			me.frm.call('validate_end_date_visits');
-
-		}
-	}
 };
 
 extend_cscript(cur_frm.cscript, new erpnext.maintenance.MaintenanceSchedule({frm: cur_frm}));
diff --git a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py
index 9a23c07..04c080c 100644
--- a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py
+++ b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py
@@ -213,6 +213,26 @@
 				if chk:
 					throw(_("Maintenance Schedule {0} exists against {1}").format(chk[0][0], d.sales_order))
 
+	def validate_items_table_change(self):
+		doc_before_save = self.get_doc_before_save()
+		if not doc_before_save:
+			return
+		for prev_item, item in zip(doc_before_save.items, self.items):
+			fields = [
+				"item_code",
+				"start_date",
+				"end_date",
+				"periodicity",
+				"sales_person",
+				"no_of_visits",
+				"serial_no",
+			]
+			for field in fields:
+				b_doc = prev_item.as_dict()
+				doc = item.as_dict()
+				if cstr(b_doc[field]) != cstr(doc[field]):
+					return True
+
 	def validate_no_of_visits(self):
 		return len(self.schedules) != sum(d.no_of_visits for d in self.items)
 
@@ -221,7 +241,7 @@
 		self.validate_maintenance_detail()
 		self.validate_dates_with_periodicity()
 		self.validate_sales_order()
-		if not self.schedules or self.validate_no_of_visits():
+		if not self.schedules or self.validate_items_table_change() or self.validate_no_of_visits():
 			self.generate_schedule()
 
 	def on_update(self):
diff --git a/erpnext/maintenance/doctype/maintenance_schedule/test_maintenance_schedule.py b/erpnext/maintenance/doctype/maintenance_schedule/test_maintenance_schedule.py
index a98cd10..2268e0f 100644
--- a/erpnext/maintenance/doctype/maintenance_schedule/test_maintenance_schedule.py
+++ b/erpnext/maintenance/doctype/maintenance_schedule/test_maintenance_schedule.py
@@ -123,6 +123,36 @@
 
 		frappe.db.rollback()
 
+	def test_schedule_with_serials(self):
+		# Checks whether serials are automatically updated when changing in items table.
+		# Also checks if other fields trigger generate schdeule if changed in items table.
+		item_code = "_Test Serial Item"
+		make_serial_item_with_serial(item_code)
+		ms = make_maintenance_schedule(item_code=item_code, serial_no="TEST001, TEST002")
+		ms.save()
+
+		# Before Save
+		self.assertEqual(ms.schedules[0].serial_no, "TEST001, TEST002")
+		self.assertEqual(ms.schedules[0].sales_person, "Sales Team")
+		self.assertEqual(len(ms.schedules), 4)
+		self.assertFalse(ms.validate_items_table_change())
+		# After Save
+		ms.items[0].serial_no = "TEST001"
+		ms.items[0].sales_person = "_Test Sales Person"
+		ms.items[0].no_of_visits = 2
+		self.assertTrue(ms.validate_items_table_change())
+		ms.save()
+		self.assertEqual(ms.schedules[0].serial_no, "TEST001")
+		self.assertEqual(ms.schedules[0].sales_person, "_Test Sales Person")
+		self.assertEqual(len(ms.schedules), 2)
+		# When user manually deleted a row from schedules table.
+		ms.schedules.pop()
+		self.assertEqual(len(ms.schedules), 1)
+		ms.save()
+		self.assertEqual(len(ms.schedules), 2)
+
+		frappe.db.rollback()
+
 
 def make_serial_item_with_serial(item_code):
 	serial_item_doc = create_item(item_code, is_stock_item=1)
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.js b/erpnext/manufacturing/doctype/job_card/job_card.js
index b2824e1..b6646b1 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.js
+++ b/erpnext/manufacturing/doctype/job_card/job_card.js
@@ -73,10 +73,22 @@
 		if (frm.doc.docstatus == 0 && !frm.is_new() &&
 			(frm.doc.for_quantity > frm.doc.total_completed_qty || !frm.doc.for_quantity)
 			&& (frm.doc.items || !frm.doc.items.length || frm.doc.for_quantity == frm.doc.transferred_qty)) {
-			frm.trigger("prepare_timer_buttons");
+
+			// if Job Card is link to Work Order, the job card must not be able to start if Work Order not "Started"
+			// and if stock mvt for WIP is required
+			if (frm.doc.work_order) {
+				frappe.db.get_value('Work Order', frm.doc.work_order, ['skip_transfer', 'status'], (result) => {
+					if (result.skip_transfer === 1 || result.status == 'In Process') {
+						frm.trigger("prepare_timer_buttons");
+					}
+				});
+			} else {
+				frm.trigger("prepare_timer_buttons");
+			}
 		}
 
 		frm.trigger("setup_quality_inspection");
+
 		if (frm.doc.work_order) {
 			frappe.db.get_value('Work Order', frm.doc.work_order,
 				'transfer_material_against').then((r) => {
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index 60b32b8..9ca05b9 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -462,6 +462,7 @@
 			work_order_data = {
 				"wip_warehouse": default_warehouses.get("wip_warehouse"),
 				"fg_warehouse": default_warehouses.get("fg_warehouse"),
+				"company": self.get("company"),
 			}
 
 			self.prepare_data_for_sub_assembly_items(row, work_order_data)
@@ -499,6 +500,7 @@
 
 		for supplier, po_list in subcontracted_po.items():
 			po = frappe.new_doc("Purchase Order")
+			po.company = self.company
 			po.supplier = supplier
 			po.schedule_date = getdate(po_list[0].schedule_date) if po_list[0].schedule_date else nowdate()
 			po.is_subcontracted = 1
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 6e5ffed..d6c44cb 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -262,8 +262,6 @@
 erpnext.patches.v13_0.update_shipment_status
 erpnext.patches.v13_0.remove_attribute_field_from_item_variant_setting
 erpnext.patches.v12_0.add_ewaybill_validity_field
-erpnext.patches.v13_0.germany_make_custom_fields
-erpnext.patches.v13_0.germany_fill_debtor_creditor_number
 erpnext.patches.v13_0.set_pos_closing_as_failed
 erpnext.patches.v13_0.rename_stop_to_send_birthday_reminders
 execute:frappe.rename_doc("Workspace", "Loan Management", "Loans", force=True)
@@ -343,6 +341,7 @@
 erpnext.patches.v14_0.delete_hub_doctypes
 erpnext.patches.v14_0.delete_hospitality_doctypes # 20-01-2022
 erpnext.patches.v14_0.delete_agriculture_doctypes
+erpnext.patches.v14_0.delete_datev_doctypes
 erpnext.patches.v14_0.rearrange_company_fields
 erpnext.patches.v14_0.update_leave_notification_template
 erpnext.patches.v14_0.restore_einvoice_fields
@@ -364,4 +363,7 @@
 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.update_expense_claim_status_for_paid_advances
-erpnext.patches.v13_0.create_gst_custom_fields_in_quotation
\ No newline at end of file
+erpnext.patches.v13_0.create_gst_custom_fields_in_quotation
+erpnext.patches.v13_0.copy_custom_field_filters_to_website_item
+erpnext.patches.v14_0.discount_accounting_separation
+erpnext.patches.v14_0.delete_employee_transfer_property_doctype
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
new file mode 100644
index 0000000..e8d0b59
--- /dev/null
+++ b/erpnext/patches/v13_0/copy_custom_field_filters_to_website_item.py
@@ -0,0 +1,94 @@
+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, web_item_doc, 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/germany_fill_debtor_creditor_number.py b/erpnext/patches/v13_0/germany_fill_debtor_creditor_number.py
deleted file mode 100644
index fc3e68a..0000000
--- a/erpnext/patches/v13_0/germany_fill_debtor_creditor_number.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (c) 2019, Frappe and Contributors
-# License: GNU General Public License v3. See license.txt
-
-
-import frappe
-
-
-def execute():
-	"""Move account number into the new custom field debtor_creditor_number.
-
-	German companies used to use a dedicated payable/receivable account for
-	every party to mimick party accounts in the external accounting software
-	"DATEV". This is no longer necessary. The reference ID for DATEV will be
-	stored in a new custom field "debtor_creditor_number".
-	"""
-	company_list = frappe.get_all("Company", filters={"country": "Germany"})
-
-	for company in company_list:
-		party_account_list = frappe.get_all(
-			"Party Account",
-			filters={"company": company.name},
-			fields=["name", "account", "debtor_creditor_number"],
-		)
-		for party_account in party_account_list:
-			if (not party_account.account) or party_account.debtor_creditor_number:
-				# account empty or debtor_creditor_number already filled
-				continue
-
-			account_number = frappe.db.get_value("Account", party_account.account, "account_number")
-			if not account_number:
-				continue
-
-			frappe.db.set_value(
-				"Party Account", party_account.name, "debtor_creditor_number", account_number
-			)
-			frappe.db.set_value("Party Account", party_account.name, "account", "")
diff --git a/erpnext/patches/v13_0/germany_make_custom_fields.py b/erpnext/patches/v13_0/germany_make_custom_fields.py
deleted file mode 100644
index cc35813..0000000
--- a/erpnext/patches/v13_0/germany_make_custom_fields.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (c) 2019, Frappe and Contributors
-# License: GNU General Public License v3. See license.txt
-
-
-import frappe
-
-from erpnext.regional.germany.setup import make_custom_fields
-
-
-def execute():
-	"""Execute the make_custom_fields method for german companies.
-
-	It is usually run once at setup of a new company. Since it's new, run it
-	once for existing companies as well.
-	"""
-	company_list = frappe.get_all("Company", filters={"country": "Germany"})
-	if not company_list:
-		return
-
-	make_custom_fields()
diff --git a/erpnext/patches/v13_0/patch_to_fix_reverse_linking_in_additional_salary_encashment_and_incentive.py b/erpnext/patches/v13_0/patch_to_fix_reverse_linking_in_additional_salary_encashment_and_incentive.py
index edd0a97..45acf49 100644
--- a/erpnext/patches/v13_0/patch_to_fix_reverse_linking_in_additional_salary_encashment_and_incentive.py
+++ b/erpnext/patches/v13_0/patch_to_fix_reverse_linking_in_additional_salary_encashment_and_incentive.py
@@ -10,54 +10,58 @@
 
 	frappe.reload_doc("hr", "doctype", "Leave Encashment")
 
-	additional_salaries = frappe.get_all(
-		"Additional Salary",
-		fields=["name", "salary_slip", "type", "salary_component"],
-		filters={"salary_slip": ["!=", ""]},
-		group_by="salary_slip",
-	)
-	leave_encashments = frappe.get_all(
-		"Leave Encashment",
-		fields=["name", "additional_salary"],
-		filters={"additional_salary": ["!=", ""]},
-	)
-	employee_incentives = frappe.get_all(
-		"Employee Incentive",
-		fields=["name", "additional_salary"],
-		filters={"additional_salary": ["!=", ""]},
-	)
-
-	for incentive in employee_incentives:
-		frappe.db.sql(
-			""" UPDATE `tabAdditional Salary`
-			SET ref_doctype = 'Employee Incentive', ref_docname = %s
-			WHERE name = %s
-		""",
-			(incentive["name"], incentive["additional_salary"]),
+	if frappe.db.has_column("Leave Encashment", "additional_salary"):
+		leave_encashments = frappe.get_all(
+			"Leave Encashment",
+			fields=["name", "additional_salary"],
+			filters={"additional_salary": ["!=", ""]},
 		)
-
-	for leave_encashment in leave_encashments:
-		frappe.db.sql(
-			""" UPDATE `tabAdditional Salary`
-			SET ref_doctype = 'Leave Encashment', ref_docname = %s
-			WHERE name = %s
-		""",
-			(leave_encashment["name"], leave_encashment["additional_salary"]),
-		)
-
-	salary_slips = [sal["salary_slip"] for sal in additional_salaries]
-
-	for salary in additional_salaries:
-		comp_type = "earnings" if salary["type"] == "Earning" else "deductions"
-		if salary["salary_slip"] and salary_slips.count(salary["salary_slip"]) == 1:
+		for leave_encashment in leave_encashments:
 			frappe.db.sql(
-				"""
-				UPDATE `tabSalary Detail`
-				SET additional_salary = %s
-				WHERE parenttype = 'Salary Slip'
-					and parentfield = %s
-					and parent = %s
-					and salary_component = %s
+				""" UPDATE `tabAdditional Salary`
+				SET ref_doctype = 'Leave Encashment', ref_docname = %s
+				WHERE name = %s
 			""",
-				(salary["name"], comp_type, salary["salary_slip"], salary["salary_component"]),
+				(leave_encashment["name"], leave_encashment["additional_salary"]),
 			)
+
+	if frappe.db.has_column("Employee Incentive", "additional_salary"):
+		employee_incentives = frappe.get_all(
+			"Employee Incentive",
+			fields=["name", "additional_salary"],
+			filters={"additional_salary": ["!=", ""]},
+		)
+
+		for incentive in employee_incentives:
+			frappe.db.sql(
+				""" UPDATE `tabAdditional Salary`
+				SET ref_doctype = 'Employee Incentive', ref_docname = %s
+				WHERE name = %s
+			""",
+				(incentive["name"], incentive["additional_salary"]),
+			)
+
+	if frappe.db.has_column("Additional Salary", "salary_slip"):
+		additional_salaries = frappe.get_all(
+			"Additional Salary",
+			fields=["name", "salary_slip", "type", "salary_component"],
+			filters={"salary_slip": ["!=", ""]},
+			group_by="salary_slip",
+		)
+
+		salary_slips = [sal["salary_slip"] for sal in additional_salaries]
+
+		for salary in additional_salaries:
+			comp_type = "earnings" if salary["type"] == "Earning" else "deductions"
+			if salary["salary_slip"] and salary_slips.count(salary["salary_slip"]) == 1:
+				frappe.db.sql(
+					"""
+					UPDATE `tabSalary Detail`
+					SET additional_salary = %s
+					WHERE parenttype = 'Salary Slip'
+						and parentfield = %s
+						and parent = %s
+						and salary_component = %s
+				""",
+					(salary["name"], comp_type, salary["salary_slip"], salary["salary_component"]),
+				)
diff --git a/erpnext/patches/v14_0/delete_datev_doctypes.py b/erpnext/patches/v14_0/delete_datev_doctypes.py
new file mode 100644
index 0000000..a5de91f
--- /dev/null
+++ b/erpnext/patches/v14_0/delete_datev_doctypes.py
@@ -0,0 +1,13 @@
+import frappe
+
+
+def execute():
+	install_apps = frappe.get_installed_apps()
+	if "erpnext_datev_uo" in install_apps or "erpnext_datev" in install_apps:
+		return
+
+	# doctypes
+	frappe.delete_doc("DocType", "DATEV Settings", ignore_missing=True, force=True)
+
+	# reports
+	frappe.delete_doc("Report", "DATEV", ignore_missing=True, force=True)
diff --git a/erpnext/patches/v14_0/delete_employee_transfer_property_doctype.py b/erpnext/patches/v14_0/delete_employee_transfer_property_doctype.py
new file mode 100644
index 0000000..b50e010
--- /dev/null
+++ b/erpnext/patches/v14_0/delete_employee_transfer_property_doctype.py
@@ -0,0 +1,5 @@
+import frappe
+
+
+def execute():
+	frappe.delete_doc("DocType", "Employee Transfer Property", ignore_missing=True)
diff --git a/erpnext/patches/v14_0/discount_accounting_separation.py b/erpnext/patches/v14_0/discount_accounting_separation.py
new file mode 100644
index 0000000..fd49805
--- /dev/null
+++ b/erpnext/patches/v14_0/discount_accounting_separation.py
@@ -0,0 +1,9 @@
+import frappe
+
+
+def execute():
+	doc = frappe.get_doc("Accounts Settings")
+	discount_account = doc.enable_discount_accounting
+	if discount_account:
+		for doctype in ["Buying Settings", "Selling Settings"]:
+			frappe.db.set_value(doctype, doctype, "enable_discount_accounting", 1, update_modified=False)
diff --git a/erpnext/payroll/doctype/gratuity/test_gratuity.py b/erpnext/payroll/doctype/gratuity/test_gratuity.py
index 67bb447..aa03d80 100644
--- a/erpnext/payroll/doctype/gratuity/test_gratuity.py
+++ b/erpnext/payroll/doctype/gratuity/test_gratuity.py
@@ -24,7 +24,9 @@
 		frappe.db.delete("Gratuity")
 		frappe.db.delete("Additional Salary", {"ref_doctype": "Gratuity"})
 
-		make_earning_salary_component(setup=True, test_tax=True, company_list=["_Test Company"])
+		make_earning_salary_component(
+			setup=True, test_tax=True, company_list=["_Test Company"], include_flexi_benefits=True
+		)
 		make_deduction_salary_component(setup=True, test_tax=True, company_list=["_Test Company"])
 
 	def test_get_last_salary_slip_should_return_none_for_new_employee(self):
diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.py b/erpnext/payroll/doctype/salary_slip/salary_slip.py
index 38fecac..1922329 100644
--- a/erpnext/payroll/doctype/salary_slip/salary_slip.py
+++ b/erpnext/payroll/doctype/salary_slip/salary_slip.py
@@ -952,8 +952,12 @@
 		)
 
 		# Structured tax amount
-		total_structured_tax_amount = self.calculate_tax_by_tax_slab(
-			total_taxable_earnings_without_full_tax_addl_components, tax_slab
+		eval_locals = self.get_data_for_eval()
+		total_structured_tax_amount = calculate_tax_by_tax_slab(
+			total_taxable_earnings_without_full_tax_addl_components,
+			tax_slab,
+			self.whitelisted_globals,
+			eval_locals,
 		)
 		current_structured_tax_amount = (
 			total_structured_tax_amount - previous_total_paid_taxes
@@ -962,7 +966,9 @@
 		# Total taxable earnings with additional earnings with full tax
 		full_tax_on_additional_earnings = 0.0
 		if current_additional_earnings_with_full_tax:
-			total_tax_amount = self.calculate_tax_by_tax_slab(total_taxable_earnings, tax_slab)
+			total_tax_amount = calculate_tax_by_tax_slab(
+				total_taxable_earnings, tax_slab, self.whitelisted_globals, eval_locals
+			)
 			full_tax_on_additional_earnings = total_tax_amount - total_structured_tax_amount
 
 		current_tax_amount = current_structured_tax_amount + full_tax_on_additional_earnings
@@ -1278,50 +1284,6 @@
 			fields="SUM(amount) as total_amount",
 		)[0].total_amount
 
-	def calculate_tax_by_tax_slab(self, annual_taxable_earning, tax_slab):
-		data = self.get_data_for_eval()
-		data.update({"annual_taxable_earning": annual_taxable_earning})
-		tax_amount = 0
-		for slab in tax_slab.slabs:
-			cond = cstr(slab.condition).strip()
-			if cond and not self.eval_tax_slab_condition(cond, data):
-				continue
-			if not slab.to_amount and annual_taxable_earning >= slab.from_amount:
-				tax_amount += (annual_taxable_earning - slab.from_amount + 1) * slab.percent_deduction * 0.01
-				continue
-			if annual_taxable_earning >= slab.from_amount and annual_taxable_earning < slab.to_amount:
-				tax_amount += (annual_taxable_earning - slab.from_amount + 1) * slab.percent_deduction * 0.01
-			elif annual_taxable_earning >= slab.from_amount and annual_taxable_earning >= slab.to_amount:
-				tax_amount += (slab.to_amount - slab.from_amount + 1) * slab.percent_deduction * 0.01
-
-		# other taxes and charges on income tax
-		for d in tax_slab.other_taxes_and_charges:
-			if flt(d.min_taxable_income) and flt(d.min_taxable_income) > annual_taxable_earning:
-				continue
-
-			if flt(d.max_taxable_income) and flt(d.max_taxable_income) < annual_taxable_earning:
-				continue
-
-			tax_amount += tax_amount * flt(d.percent) / 100
-
-		return tax_amount
-
-	def eval_tax_slab_condition(self, condition, data):
-		try:
-			condition = condition.strip()
-			if condition:
-				return frappe.safe_eval(condition, self.whitelisted_globals, data)
-		except NameError as err:
-			frappe.throw(
-				_("{0} <br> This error can be due to missing or deleted field.").format(err),
-				title=_("Name error"),
-			)
-		except SyntaxError as err:
-			frappe.throw(_("Syntax error in condition: {0}").format(err))
-		except Exception as e:
-			frappe.throw(_("Error in formula or condition: {0}").format(e))
-			raise
-
 	def get_component_totals(self, component_type, depends_on_payment_days=0):
 		joining_date, relieving_date = frappe.get_cached_value(
 			"Employee", self.employee, ["date_of_joining", "relieving_date"]
@@ -1705,3 +1667,60 @@
 		)
 
 	return payroll_payable_account
+
+
+def calculate_tax_by_tax_slab(
+	annual_taxable_earning, tax_slab, eval_globals=None, eval_locals=None
+):
+	eval_locals.update({"annual_taxable_earning": annual_taxable_earning})
+	tax_amount = 0
+	for slab in tax_slab.slabs:
+		cond = cstr(slab.condition).strip()
+		if cond and not eval_tax_slab_condition(cond, eval_globals, eval_locals):
+			continue
+		if not slab.to_amount and annual_taxable_earning >= slab.from_amount:
+			tax_amount += (annual_taxable_earning - slab.from_amount + 1) * slab.percent_deduction * 0.01
+			continue
+		if annual_taxable_earning >= slab.from_amount and annual_taxable_earning < slab.to_amount:
+			tax_amount += (annual_taxable_earning - slab.from_amount + 1) * slab.percent_deduction * 0.01
+		elif annual_taxable_earning >= slab.from_amount and annual_taxable_earning >= slab.to_amount:
+			tax_amount += (slab.to_amount - slab.from_amount + 1) * slab.percent_deduction * 0.01
+
+	# other taxes and charges on income tax
+	for d in tax_slab.other_taxes_and_charges:
+		if flt(d.min_taxable_income) and flt(d.min_taxable_income) > annual_taxable_earning:
+			continue
+
+		if flt(d.max_taxable_income) and flt(d.max_taxable_income) < annual_taxable_earning:
+			continue
+
+		tax_amount += tax_amount * flt(d.percent) / 100
+
+	return tax_amount
+
+
+def eval_tax_slab_condition(condition, eval_globals=None, eval_locals=None):
+	if not eval_globals:
+		eval_globals = {
+			"int": int,
+			"float": float,
+			"long": int,
+			"round": round,
+			"date": datetime.date,
+			"getdate": getdate,
+		}
+
+	try:
+		condition = condition.strip()
+		if condition:
+			return frappe.safe_eval(condition, eval_globals, eval_locals)
+	except NameError as err:
+		frappe.throw(
+			_("{0} <br> This error can be due to missing or deleted field.").format(err),
+			title=_("Name error"),
+		)
+	except SyntaxError as err:
+		frappe.throw(_("Syntax error in condition: {0} in Income Tax Slab").format(err))
+	except Exception as e:
+		frappe.throw(_("Error in formula or condition: {0} in Income Tax Slab").format(e))
+		raise
diff --git a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
index dbeadc5..869ea83 100644
--- a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
@@ -772,6 +772,7 @@
 			"Monthly",
 			other_details={"max_benefits": 100000},
 			test_tax=True,
+			include_flexi_benefits=True,
 			employee=employee,
 			payroll_period=payroll_period,
 		)
@@ -875,6 +876,7 @@
 			"Monthly",
 			other_details={"max_benefits": 100000},
 			test_tax=True,
+			include_flexi_benefits=True,
 			employee=employee,
 			payroll_period=payroll_period,
 		)
@@ -1022,7 +1024,9 @@
 	return account
 
 
-def make_earning_salary_component(setup=False, test_tax=False, company_list=None):
+def make_earning_salary_component(
+	setup=False, test_tax=False, company_list=None, include_flexi_benefits=False
+):
 	data = [
 		{
 			"salary_component": "Basic Salary",
@@ -1043,7 +1047,7 @@
 		},
 		{"salary_component": "Leave Encashment", "abbr": "LE", "type": "Earning"},
 	]
-	if test_tax:
+	if include_flexi_benefits:
 		data.extend(
 			[
 				{
@@ -1063,11 +1067,18 @@
 					"type": "Earning",
 					"max_benefit_amount": 15000,
 				},
+			]
+		)
+	if test_tax:
+		data.extend(
+			[
 				{"salary_component": "Performance Bonus", "abbr": "B", "type": "Earning"},
 			]
 		)
+
 	if setup or test_tax:
 		make_salary_component(data, test_tax, company_list)
+
 	data.append(
 		{
 			"salary_component": "Basic Salary",
diff --git a/erpnext/payroll/doctype/salary_structure/test_salary_structure.py b/erpnext/payroll/doctype/salary_structure/test_salary_structure.py
index def622b..2eb1671 100644
--- a/erpnext/payroll/doctype/salary_structure/test_salary_structure.py
+++ b/erpnext/payroll/doctype/salary_structure/test_salary_structure.py
@@ -149,6 +149,7 @@
 	company=None,
 	currency=erpnext.get_default_currency(),
 	payroll_period=None,
+	include_flexi_benefits=False,
 ):
 	if test_tax:
 		frappe.db.sql("""delete from `tabSalary Structure` where name=%s""", (salary_structure))
@@ -161,7 +162,10 @@
 		"name": salary_structure,
 		"company": company or erpnext.get_default_company(),
 		"earnings": make_earning_salary_component(
-			setup=True, test_tax=test_tax, company_list=["_Test Company"]
+			setup=True,
+			test_tax=test_tax,
+			company_list=["_Test Company"],
+			include_flexi_benefits=include_flexi_benefits,
 		),
 		"deductions": make_deduction_salary_component(
 			setup=True, test_tax=test_tax, company_list=["_Test Company"]
diff --git a/erpnext/hr/doctype/employee_transfer_property/__init__.py b/erpnext/payroll/report/income_tax_computation/__init__.py
similarity index 100%
rename from erpnext/hr/doctype/employee_transfer_property/__init__.py
rename to erpnext/payroll/report/income_tax_computation/__init__.py
diff --git a/erpnext/payroll/report/income_tax_computation/income_tax_computation.js b/erpnext/payroll/report/income_tax_computation/income_tax_computation.js
new file mode 100644
index 0000000..26e463f
--- /dev/null
+++ b/erpnext/payroll/report/income_tax_computation/income_tax_computation.js
@@ -0,0 +1,47 @@
+// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Income Tax Computation"] = {
+	"filters": [
+		{
+			"fieldname":"company",
+			"label": __("Company"),
+			"fieldtype": "Link",
+			"options": "Company",
+			"default": frappe.defaults.get_user_default("Company"),
+			"width": "100px",
+			"reqd": 1
+		},
+		{
+			"fieldname":"payroll_period",
+			"label": __("Payroll Period"),
+			"fieldtype": "Link",
+			"options": "Payroll Period",
+			"width": "100px",
+			"reqd": 1
+		},
+		{
+			"fieldname":"employee",
+			"label": __("Employee"),
+			"fieldtype": "Link",
+			"options": "Employee",
+			"width": "100px"
+		},
+		{
+			"fieldname":"department",
+			"label": __("Department"),
+			"fieldtype": "Link",
+			"options": "Department",
+			"width": "100px",
+		},
+		{
+			"fieldname":"consider_tax_exemption_declaration",
+			"label": __("Consider Tax Exemption Declaration"),
+			"fieldtype": "Check",
+			"width": "180px"
+		}
+	]
+};
+
+
diff --git a/erpnext/payroll/report/income_tax_computation/income_tax_computation.json b/erpnext/payroll/report/income_tax_computation/income_tax_computation.json
new file mode 100644
index 0000000..7cb5b22
--- /dev/null
+++ b/erpnext/payroll/report/income_tax_computation/income_tax_computation.json
@@ -0,0 +1,36 @@
+{
+ "add_total_row": 0,
+ "columns": [],
+ "creation": "2022-02-17 17:19:30.921422",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "filters": [],
+ "idx": 0,
+ "is_standard": "Yes",
+ "letter_head": "",
+ "modified": "2022-02-23 13:07:30.347861",
+ "modified_by": "Administrator",
+ "module": "Payroll",
+ "name": "Income Tax Computation",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Salary Slip",
+ "report_name": "Income Tax Computation",
+ "report_type": "Script Report",
+ "roles": [
+  {
+   "role": "Employee"
+  },
+  {
+   "role": "HR User"
+  },
+  {
+   "role": "HR Manager"
+  },
+  {
+   "role": "Employee Self Service"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/payroll/report/income_tax_computation/income_tax_computation.py b/erpnext/payroll/report/income_tax_computation/income_tax_computation.py
new file mode 100644
index 0000000..739ed8e
--- /dev/null
+++ b/erpnext/payroll/report/income_tax_computation/income_tax_computation.py
@@ -0,0 +1,513 @@
+# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+import frappe
+from frappe import _, scrub
+from frappe.query_builder.functions import Sum
+from frappe.utils import add_days, flt, getdate, rounded
+
+from erpnext.payroll.doctype.payroll_entry.payroll_entry import get_start_end_dates
+from erpnext.payroll.doctype.salary_slip.salary_slip import calculate_tax_by_tax_slab
+
+
+def execute(filters=None):
+	return IncomeTaxComputationReport(filters).run()
+
+
+class IncomeTaxComputationReport(object):
+	def __init__(self, filters=None):
+		self.filters = frappe._dict(filters or {})
+		self.columns = []
+		self.data = []
+		self.employees = frappe._dict()
+		self.payroll_period_start_date = None
+		self.payroll_period_end_date = None
+		if self.filters.payroll_period:
+			self.payroll_period_start_date, self.payroll_period_end_date = frappe.db.get_value(
+				"Payroll Period", self.filters.payroll_period, ["start_date", "end_date"]
+			)
+
+	def run(self):
+		self.get_fixed_columns()
+		self.get_data()
+		return self.columns, self.data
+
+	def get_data(self):
+		self.get_employee_details()
+		self.get_future_salary_slips()
+		self.get_ctc()
+		self.get_tax_exempted_earnings_and_deductions()
+		self.get_employee_tax_exemptions()
+		self.get_hra()
+		self.get_standard_tax_exemption()
+		self.get_total_taxable_amount()
+		self.get_applicable_tax()
+		self.get_total_deducted_tax()
+		self.get_payable_tax()
+
+		self.data = list(self.employees.values())
+
+	def get_employee_details(self):
+		filters, or_filters = self.get_employee_filters()
+		fields = [
+			"name as employee",
+			"employee_name",
+			"department",
+			"designation",
+			"date_of_joining",
+			"relieving_date",
+		]
+
+		employees = frappe.get_all("Employee", filters=filters, or_filters=or_filters, fields=fields)
+		ss_assignments = self.get_ss_assignments([d.employee for d in employees])
+
+		for d in employees:
+			if d.employee in list(ss_assignments.keys()):
+				d.update(ss_assignments[d.employee])
+				self.employees.setdefault(d.employee, d)
+
+		if not self.employees:
+			frappe.throw(_("No employees found with selected filters and active salary structure"))
+
+	def get_employee_filters(self):
+		filters = {"company": self.filters.company}
+		or_filters = {
+			"status": "Active",
+			"relieving_date": ["between", [self.payroll_period_start_date, self.payroll_period_end_date]],
+		}
+		if self.filters.employee:
+			filters = {"name": self.filters.employee}
+		elif self.filters.department:
+			filters.update({"department": self.filters.department})
+
+		return filters, or_filters
+
+	def get_ss_assignments(self, employees):
+		ss_assignments = frappe.get_all(
+			"Salary Structure Assignment",
+			filters={
+				"employee": ["in", employees],
+				"docstatus": 1,
+				"salary_structure": ["is", "set"],
+				"income_tax_slab": ["is", "set"],
+			},
+			fields=["employee", "income_tax_slab", "salary_structure"],
+			order_by="from_date desc",
+		)
+
+		employee_ss_assignments = frappe._dict()
+		for d in ss_assignments:
+			if d.employee not in list(employee_ss_assignments.keys()):
+				tax_slab = frappe.get_cached_value(
+					"Income Tax Slab", d.income_tax_slab, ["allow_tax_exemption", "disabled"], as_dict=1
+				)
+
+				if tax_slab and not tax_slab.disabled:
+					employee_ss_assignments.setdefault(
+						d.employee,
+						{
+							"salary_structure": d.salary_structure,
+							"income_tax_slab": d.income_tax_slab,
+							"allow_tax_exemption": tax_slab.allow_tax_exemption,
+						},
+					)
+		return employee_ss_assignments
+
+	def get_future_salary_slips(self):
+		self.future_salary_slips = frappe._dict()
+		for employee in list(self.employees.keys()):
+			last_ss = self.get_last_salary_slip(employee)
+			if last_ss and last_ss.end_date == self.payroll_period_end_date:
+				continue
+
+			relieving_date = self.employees[employee].get("relieving_date", "")
+			if last_ss:
+				ss_start_date = add_days(last_ss.end_date, 1)
+			else:
+				ss_start_date = self.payroll_period_start_date
+				last_ss = frappe._dict(
+					{
+						"payroll_frequency": "Monthly",
+						"salary_structure": self.employees[employee].get("salary_structure"),
+					}
+				)
+
+			while getdate(ss_start_date) < getdate(self.payroll_period_end_date) and (
+				not relieving_date or getdate(ss_start_date) < relieving_date
+			):
+				ss_end_date = get_start_end_dates(last_ss.payroll_frequency, ss_start_date).end_date
+
+				ss = frappe.new_doc("Salary Slip")
+				ss.employee = employee
+				ss.start_date = ss_start_date
+				ss.end_date = ss_end_date
+				ss.salary_structure = last_ss.salary_structure
+				ss.payroll_frequency = last_ss.payroll_frequency
+				ss.company = self.filters.company
+				try:
+					ss.process_salary_structure(for_preview=1)
+					self.future_salary_slips.setdefault(employee, []).append(ss.as_dict())
+				except Exception:
+					break
+
+				ss_start_date = add_days(ss_end_date, 1)
+
+	def get_last_salary_slip(self, employee):
+		last_salary_slip = frappe.db.get_value(
+			"Salary Slip",
+			{
+				"employee": employee,
+				"docstatus": 1,
+				"start_date": ["between", [self.payroll_period_start_date, self.payroll_period_end_date]],
+			},
+			["start_date", "end_date", "salary_structure", "payroll_frequency"],
+			order_by="start_date desc",
+			as_dict=1,
+		)
+
+		return last_salary_slip
+
+	def get_ctc(self):
+		# Get total earnings from existing salary slip
+		ss = frappe.qb.DocType("Salary Slip")
+		existing_ss = frappe._dict(
+			(
+				frappe.qb.from_(ss)
+				.select(ss.employee, Sum(ss.base_gross_pay).as_("amount"))
+				.where(ss.docstatus == 1)
+				.where(ss.employee.isin(list(self.employees.keys())))
+				.where(ss.start_date >= self.payroll_period_start_date)
+				.where(ss.end_date <= self.payroll_period_end_date)
+				.groupby(ss.employee)
+			).run()
+		)
+
+		for employee in list(self.employees.keys()):
+			future_ss_earnings = self.get_future_earnings(employee)
+			ctc = flt(existing_ss.get(employee)) + future_ss_earnings
+
+			self.employees[employee].setdefault("ctc", ctc)
+
+	def get_future_earnings(self, employee):
+		future_earnings = 0.0
+		for ss in self.future_salary_slips.get(employee, []):
+			future_earnings += flt(ss.base_gross_pay)
+
+		return future_earnings
+
+	def get_tax_exempted_earnings_and_deductions(self):
+		tax_exempted_components = self.get_tax_exempted_components()
+
+		# Get component totals from existing salary slips
+		ss = frappe.qb.DocType("Salary Slip")
+		ss_comps = frappe.qb.DocType("Salary Detail")
+
+		records = (
+			frappe.qb.from_(ss)
+			.inner_join(ss_comps)
+			.on(ss.name == ss_comps.parent)
+			.select(ss.name, ss.employee, ss_comps.salary_component, Sum(ss_comps.amount).as_("amount"))
+			.where(ss.docstatus == 1)
+			.where(ss.employee.isin(list(self.employees.keys())))
+			.where(ss_comps.salary_component.isin(tax_exempted_components))
+			.where(ss.start_date >= self.payroll_period_start_date)
+			.where(ss.end_date <= self.payroll_period_end_date)
+			.groupby(ss.employee, ss_comps.salary_component)
+		).run(as_dict=True)
+
+		existing_ss_exemptions = frappe._dict()
+		for d in records:
+			existing_ss_exemptions.setdefault(d.employee, {}).setdefault(
+				scrub(d.salary_component), d.amount
+			)
+
+		for employee in list(self.employees.keys()):
+			if not self.employees[employee]["allow_tax_exemption"]:
+				continue
+
+			exemptions = existing_ss_exemptions.get(employee, {})
+			self.add_exemptions_from_future_salary_slips(employee, exemptions)
+			self.employees[employee].update(exemptions)
+
+			total_exemptions = sum(list(exemptions.values()))
+			self.add_to_total_exemption(employee, total_exemptions)
+
+	def add_exemptions_from_future_salary_slips(self, employee, exemptions):
+		for ss in self.future_salary_slips.get(employee, []):
+			for e in ss.earnings:
+				if not e.is_tax_applicable:
+					exemptions.setdefault(scrub(e.salary_component), 0)
+					exemptions[scrub(e.salary_component)] += flt(e.amount)
+
+			for d in ss.deductions:
+				if d.exempted_from_income_tax:
+					exemptions.setdefault(scrub(d.salary_component), 0)
+					exemptions[scrub(d.salary_component)] += flt(d.amount)
+
+		return exemptions
+
+	def get_tax_exempted_components(self):
+		# nontaxable earning components
+		nontaxable_earning_components = [
+			d.name
+			for d in frappe.get_all(
+				"Salary Component", {"type": "Earning", "is_tax_applicable": 0, "disabled": 0}
+			)
+		]
+
+		# tax exempted deduction components
+		tax_exempted_deduction_components = [
+			d.name
+			for d in frappe.get_all(
+				"Salary Component", {"type": "Deduction", "exempted_from_income_tax": 1, "disabled": 0}
+			)
+		]
+
+		tax_exempted_components = nontaxable_earning_components + tax_exempted_deduction_components
+
+		# Add columns
+		for d in tax_exempted_components:
+			self.add_column(d)
+
+		return tax_exempted_components
+
+	def add_to_total_exemption(self, employee, amount):
+		self.employees[employee].setdefault("total_exemption", 0)
+		self.employees[employee]["total_exemption"] += amount
+
+	def get_employee_tax_exemptions(self):
+		# add columns
+		exemption_categories = frappe.get_all("Employee Tax Exemption Category", {"is_active": 1})
+		for d in exemption_categories:
+			self.add_column(d.name)
+
+		self.employees_with_proofs = []
+		self.get_tax_exemptions("Employee Tax Exemption Proof Submission")
+		if self.filters.consider_tax_exemption_declaration:
+			self.get_tax_exemptions("Employee Tax Exemption Declaration")
+
+	def get_tax_exemptions(self, source):
+		# Get category-wise exmeptions based on submitted proofs or declarations
+		if source == "Employee Tax Exemption Proof Submission":
+			child_doctype = "Employee Tax Exemption Proof Submission Detail"
+		else:
+			child_doctype = "Employee Tax Exemption Declaration Category"
+
+		max_exemptions = self.get_max_exemptions_based_on_category()
+
+		par = frappe.qb.DocType(source)
+		child = frappe.qb.DocType(child_doctype)
+
+		records = (
+			frappe.qb.from_(par)
+			.inner_join(child)
+			.on(par.name == child.parent)
+			.select(par.employee, child.exemption_category, Sum(child.amount).as_("amount"))
+			.where(par.docstatus == 1)
+			.where(par.employee.isin(list(self.employees.keys())))
+			.where(par.payroll_period == self.filters.payroll_period)
+			.groupby(par.employee, child.exemption_category)
+		).run(as_dict=True)
+
+		for d in records:
+			if not self.employees[d.employee]["allow_tax_exemption"]:
+				continue
+
+			if source == "Employee Tax Exemption Declaration" and d.employee in self.employees_with_proofs:
+				continue
+
+			amount = flt(d.amount)
+			max_eligible_amount = flt(max_exemptions.get(d.exemption_category))
+			if max_eligible_amount and amount > max_eligible_amount:
+				amount = max_eligible_amount
+
+			self.employees[d.employee].setdefault(scrub(d.exemption_category), amount)
+			self.add_to_total_exemption(d.employee, amount)
+
+			if (
+				source == "Employee Tax Exemption Proof Submission"
+				and d.employee not in self.employees_with_proofs
+			):
+				self.employees_with_proofs.append(d.employee)
+
+	def get_max_exemptions_based_on_category(self):
+		return dict(
+			frappe.get_all(
+				"Employee Tax Exemption Category",
+				filters={"is_active": 1},
+				fields=["name", "max_amount"],
+				as_list=1,
+			)
+		)
+
+	def get_hra(self):
+		if not frappe.get_meta("Employee Tax Exemption Declaration").has_field("monthly_house_rent"):
+			return
+
+		self.add_column("HRA")
+
+		self.employees_with_proofs = []
+		self.get_eligible_hra("Employee Tax Exemption Proof Submission")
+		if self.filters.consider_tax_exemption_declaration:
+			self.get_eligible_hra("Employee Tax Exemption Declaration")
+
+	def get_eligible_hra(self, source):
+		if source == "Employee Tax Exemption Proof Submission":
+			hra_amount_field = "total_eligible_hra_exemption"
+		else:
+			hra_amount_field = "annual_hra_exemption"
+
+		records = frappe.get_all(
+			source,
+			filters={
+				"docstatus": 1,
+				"employee": ["in", list(self.employees.keys())],
+				"payroll_period": self.filters.payroll_period,
+			},
+			fields=["employee", hra_amount_field],
+			as_list=1,
+		)
+
+		for d in records:
+			if not self.employees[d[0]]["allow_tax_exemption"]:
+				continue
+
+			if d[0] not in self.employees_with_proofs:
+				self.employees[d[0]].setdefault("hra", d[1])
+				self.add_to_total_exemption(d[0], d[1])
+				self.employees_with_proofs.append(d[0])
+
+	def get_standard_tax_exemption(self):
+		self.add_column("Standard Tax Exemption")
+
+		standard_exemptions_per_slab = dict(
+			frappe.get_all(
+				"Income Tax Slab",
+				filters={"company": self.filters.company, "docstatus": 1, "disabled": 0},
+				fields=["name", "standard_tax_exemption_amount"],
+				as_list=1,
+			)
+		)
+
+		for emp, emp_details in self.employees.items():
+			if not self.employees[emp]["allow_tax_exemption"]:
+				continue
+
+			income_tax_slab = emp_details.get("income_tax_slab")
+			standard_exemption = standard_exemptions_per_slab.get(income_tax_slab, 0)
+			emp_details["standard_tax_exemption"] = standard_exemption
+			self.add_to_total_exemption(emp, standard_exemption)
+
+		self.add_column("Total Exemption")
+
+	def get_total_taxable_amount(self):
+		self.add_column("Total Taxable Amount")
+		for emp, emp_details in self.employees.items():
+			emp_details["total_taxable_amount"] = flt(emp_details.get("ctc")) - flt(
+				emp_details.get("total_exemption")
+			)
+
+	def get_applicable_tax(self):
+		self.add_column("Applicable Tax")
+
+		is_tax_rounded = frappe.db.get_value(
+			"Salary Component",
+			{"variable_based_on_taxable_salary": 1, "disabled": 0},
+			"round_to_the_nearest_integer",
+		)
+
+		for emp, emp_details in self.employees.items():
+			tax_slab = emp_details.get("income_tax_slab")
+			if tax_slab:
+				tax_slab = frappe.get_cached_doc("Income Tax Slab", tax_slab)
+				employee_dict = frappe.get_doc("Employee", emp).as_dict()
+				tax_amount = calculate_tax_by_tax_slab(
+					emp_details["total_taxable_amount"], tax_slab, eval_globals=None, eval_locals=employee_dict
+				)
+			else:
+				tax_amount = 0.0
+
+			if is_tax_rounded:
+				tax_amount = rounded(tax_amount)
+			emp_details["applicable_tax"] = tax_amount
+
+	def get_total_deducted_tax(self):
+		self.add_column("Total Tax Deducted")
+
+		ss = frappe.qb.DocType("Salary Slip")
+		ss_ded = frappe.qb.DocType("Salary Detail")
+
+		records = (
+			frappe.qb.from_(ss)
+			.inner_join(ss_ded)
+			.on(ss.name == ss_ded.parent)
+			.select(ss.employee, Sum(ss_ded.amount).as_("amount"))
+			.where(ss.docstatus == 1)
+			.where(ss.employee.isin(list(self.employees.keys())))
+			.where(ss_ded.parentfield == "deductions")
+			.where(ss_ded.variable_based_on_taxable_salary == 1)
+			.where(ss.start_date >= self.payroll_period_start_date)
+			.where(ss.end_date <= self.payroll_period_end_date)
+			.groupby(ss.employee)
+		).run(as_dict=True)
+
+		for d in records:
+			self.employees[d.employee].setdefault("total_tax_deducted", d.amount)
+
+	def get_payable_tax(self):
+		self.add_column("Payable Tax")
+
+		for emp, emp_details in self.employees.items():
+			emp_details["payable_tax"] = flt(emp_details.get("applicable_tax")) - flt(
+				emp_details.get("total_tax_deducted")
+			)
+
+	def add_column(self, label, fieldname=None, fieldtype=None, options=None, width=None):
+		col = {
+			"label": _(label),
+			"fieldname": fieldname or scrub(label),
+			"fieldtype": fieldtype or "Currency",
+			"options": options,
+			"width": width or "140px",
+		}
+		self.columns.append(col)
+
+	def get_fixed_columns(self):
+		self.columns = [
+			{
+				"label": _("Employee"),
+				"fieldname": "employee",
+				"fieldtype": "Link",
+				"options": "Employee",
+				"width": "140px",
+			},
+			{
+				"label": _("Employee Name"),
+				"fieldname": "employee_name",
+				"fieldtype": "Data",
+				"width": "160px",
+			},
+			{
+				"label": _("Department"),
+				"fieldname": "department",
+				"fieldtype": "Link",
+				"options": "Department",
+				"width": "140px",
+			},
+			{
+				"label": _("Designation"),
+				"fieldname": "designation",
+				"fieldtype": "Link",
+				"options": "Designation",
+				"width": "140px",
+			},
+			{"label": _("Date of Joining"), "fieldname": "date_of_joining", "fieldtype": "Date"},
+			{
+				"label": _("Income Tax Slab"),
+				"fieldname": "income_tax_slab",
+				"fieldtype": "Link",
+				"options": "Income Tax Slab",
+				"width": "140px",
+			},
+			{"label": _("CTC"), "fieldname": "ctc", "fieldtype": "Currency", "width": "140px"},
+		]
diff --git a/erpnext/payroll/report/income_tax_computation/test_income_tax_computation.py b/erpnext/payroll/report/income_tax_computation/test_income_tax_computation.py
new file mode 100644
index 0000000..57ca317
--- /dev/null
+++ b/erpnext/payroll/report/income_tax_computation/test_income_tax_computation.py
@@ -0,0 +1,115 @@
+import unittest
+
+import frappe
+from frappe.utils import getdate
+
+from erpnext.hr.doctype.employee.test_employee import make_employee
+from erpnext.payroll.doctype.employee_tax_exemption_declaration.test_employee_tax_exemption_declaration import (
+	create_payroll_period,
+)
+from erpnext.payroll.doctype.salary_slip.test_salary_slip import (
+	create_exemption_declaration,
+	create_salary_slips_for_payroll_period,
+	create_tax_slab,
+)
+from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure
+from erpnext.payroll.report.income_tax_computation.income_tax_computation import execute
+
+
+class TestIncomeTaxComputation(unittest.TestCase):
+	def setUp(self):
+		self.cleanup_records()
+		self.create_records()
+
+	def tearDown(self):
+		frappe.db.rollback()
+
+	def cleanup_records(self):
+		frappe.db.sql("delete from `tabEmployee Tax Exemption Declaration`")
+		frappe.db.sql("delete from `tabPayroll Period`")
+		frappe.db.sql("delete from `tabIncome Tax Slab`")
+		frappe.db.sql("delete from `tabSalary Component`")
+		frappe.db.sql("delete from `tabEmployee Benefit Application`")
+		frappe.db.sql("delete from `tabEmployee Benefit Claim`")
+		frappe.db.sql("delete from `tabEmployee` where company='_Test Company'")
+		frappe.db.sql("delete from `tabSalary Slip`")
+
+	def create_records(self):
+		self.employee = make_employee(
+			"employee_tax_computation@example.com",
+			company="_Test Company",
+			date_of_joining=getdate("01-10-2021"),
+		)
+
+		self.payroll_period = create_payroll_period(
+			name="_Test Payroll Period 1", company="_Test Company"
+		)
+
+		self.income_tax_slab = create_tax_slab(
+			self.payroll_period,
+			allow_tax_exemption=True,
+			effective_date=getdate("2019-04-01"),
+			company="_Test Company",
+		)
+		salary_structure = make_salary_structure(
+			"Monthly Salary Structure Test Income Tax Computation",
+			"Monthly",
+			employee=self.employee,
+			company="_Test Company",
+			currency="INR",
+			payroll_period=self.payroll_period,
+			test_tax=True,
+		)
+
+		create_exemption_declaration(self.employee, self.payroll_period.name)
+
+		create_salary_slips_for_payroll_period(
+			self.employee, salary_structure.name, self.payroll_period, deduct_random=False, num=3
+		)
+
+	def test_report(self):
+		filters = frappe._dict(
+			{
+				"company": "_Test Company",
+				"payroll_period": self.payroll_period.name,
+				"employee": self.employee,
+			}
+		)
+
+		result = execute(filters)
+
+		expected_data = {
+			"employee": self.employee,
+			"employee_name": "employee_tax_computation@example.com",
+			"department": "All Departments",
+			"income_tax_slab": self.income_tax_slab,
+			"ctc": 936000.0,
+			"professional_tax": 2400.0,
+			"standard_tax_exemption": 50000,
+			"total_exemption": 52400.0,
+			"total_taxable_amount": 883600.0,
+			"applicable_tax": 92789.0,
+			"total_tax_deducted": 17997.0,
+			"payable_tax": 74792,
+		}
+
+		for key, val in expected_data.items():
+			self.assertEqual(result[1][0].get(key), val)
+
+		# Run report considering tax exemption declaration
+		filters.consider_tax_exemption_declaration = 1
+
+		result = execute(filters)
+
+		expected_data.update(
+			{
+				"_test_category": 100000.0,
+				"total_exemption": 152400.0,
+				"total_taxable_amount": 783600.0,
+				"applicable_tax": 71989.0,
+				"payable_tax": 53992.0,
+			}
+		)
+
+		for key, val in expected_data.items():
+			self.assertEqual(result[1][0].get(key), val)
diff --git a/erpnext/payroll/workspace/payroll/payroll.json b/erpnext/payroll/workspace/payroll/payroll.json
index 762bea0..5629e63 100644
--- a/erpnext/payroll/workspace/payroll/payroll.json
+++ b/erpnext/payroll/workspace/payroll/payroll.json
@@ -246,6 +246,17 @@
    "type": "Link"
   },
   {
+    "dependencies": "Salary Structure",
+    "hidden": 0,
+    "is_query_report": 1,
+    "label": "Income Tax Computation",
+    "link_count": 0,
+    "link_to": "Income Tax Computation",
+    "link_type": "Report",
+    "onboard": 0,
+    "type": "Link"
+   },
+  {
    "dependencies": "Salary Slip",
    "hidden": 0,
    "is_query_report": 1,
@@ -312,7 +323,7 @@
    "type": "Link"
   }
  ],
- "modified": "2022-01-13 17:41:19.098813",
+ "modified": "2022-02-23 17:41:19.098813",
  "modified_by": "Administrator",
  "module": "Payroll",
  "name": "Payroll",
diff --git a/erpnext/portal/doctype/website_filter_field/website_filter_field.json b/erpnext/portal/doctype/website_filter_field/website_filter_field.json
index 67c0d0a..45543a6 100644
--- a/erpnext/portal/doctype/website_filter_field/website_filter_field.json
+++ b/erpnext/portal/doctype/website_filter_field/website_filter_field.json
@@ -1,76 +1,31 @@
 {
- "allow_copy": 0, 
- "allow_events_in_timeline": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "beta": 0, 
- "creation": "2018-12-31 17:06:08.716134", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "creation": "2018-12-31 17:06:08.716134",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "fieldname"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "fieldname", 
-   "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": "Fieldname", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
+   "fieldname": "fieldname",
+   "fieldtype": "Autocomplete",
+   "in_list_view": 1,
+   "label": "Fieldname"
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 1, 
- "max_attachments": 0, 
- "modified": "2019-01-01 18:26:11.550380", 
- "modified_by": "Administrator", 
- "module": "Portal", 
- "name": "Website Filter Field", 
- "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": "2022-04-18 18:55:17.835666",
+ "modified_by": "Administrator",
+ "module": "Portal",
+ "name": "Website Filter Field",
+ "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/public/js/call_popup/call_popup.js b/erpnext/public/js/call_popup/call_popup.js
index c954f12..2dbe999 100644
--- a/erpnext/public/js/call_popup/call_popup.js
+++ b/erpnext/public/js/call_popup/call_popup.js
@@ -141,6 +141,14 @@
 				'fieldtype': 'Section Break',
 				'hide_border': 1,
 			}, {
+				'fieldname': 'call_type',
+				'label': 'Call Type',
+				'fieldtype': 'Link',
+				'options': 'Telephony Call Type',
+			}, {
+				'fieldtype': 'Section Break',
+				'hide_border': 1,
+			}, {
 				'fieldtype': 'Small Text',
 				'label': __('Call Summary'),
 				'fieldname': 'call_summary',
@@ -149,10 +157,12 @@
 				'label': __('Save'),
 				'click': () => {
 					const call_summary = this.call_details.get_value('call_summary');
+					const call_type = this.call_details.get_value('call_type');
 					if (!call_summary) return;
-					frappe.xcall('erpnext.telephony.doctype.call_log.call_log.add_call_summary', {
+					frappe.xcall('erpnext.telephony.doctype.call_log.call_log.add_call_summary_and_call_type', {
 						'call_log': this.call_log.name,
 						'summary': call_summary,
+						'call_type': call_type,
 					}).then(() => {
 						this.close_modal();
 						frappe.show_alert({
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index c9faf68..767221e 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -1388,6 +1388,11 @@
 			return;
 		}
 
+		// Target doc created from a mapped doc
+		if (this.frm.doc.__onload && this.frm.doc.__onload.ignore_price_list) {
+			return;
+		}
+
 		return this.frm.call({
 			method: "erpnext.accounts.doctype.pricing_rule.pricing_rule.apply_pricing_rule",
 			args: {	args: args, doc: me.frm.doc },
@@ -1504,7 +1509,7 @@
 				me.remove_pricing_rule(frappe.get_doc(d.doctype, d.name));
 			}
 
-			if (d.free_item_data) {
+			if (d.free_item_data.length > 0) {
 				me.apply_product_discount(d);
 			}
 
diff --git a/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.py b/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.py
index daf7a69..04e8211 100644
--- a/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.py
+++ b/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.py
@@ -19,7 +19,7 @@
 				)
 			).insert()
 
-			frappe.form_dict = dict(
+			frappe.local.form_dict = frappe._dict(
 				doctype="Quality Procedure",
 				quality_procedure_name="Test Child 1",
 				parent_quality_procedure=procedure.name,
diff --git a/erpnext/regional/doctype/datev_settings/__init__.py b/erpnext/regional/doctype/datev_settings/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/regional/doctype/datev_settings/__init__.py
+++ /dev/null
diff --git a/erpnext/regional/doctype/datev_settings/datev_settings.js b/erpnext/regional/doctype/datev_settings/datev_settings.js
deleted file mode 100644
index 3c36549..0000000
--- a/erpnext/regional/doctype/datev_settings/datev_settings.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('DATEV Settings', {
-	refresh: function(frm) {
-		frm.add_custom_button(__('Show Report'), () => frappe.set_route('query-report', 'DATEV'), "fa fa-table");
-	}
-});
diff --git a/erpnext/regional/doctype/datev_settings/datev_settings.json b/erpnext/regional/doctype/datev_settings/datev_settings.json
deleted file mode 100644
index f60de4c..0000000
--- a/erpnext/regional/doctype/datev_settings/datev_settings.json
+++ /dev/null
@@ -1,125 +0,0 @@
-{
- "actions": [],
- "autoname": "field:client",
- "creation": "2019-08-13 23:56:34.259906",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
-  "client",
-  "client_number",
-  "column_break_2",
-  "consultant_number",
-  "consultant",
-  "section_break_4",
-  "account_number_length",
-  "column_break_6",
-  "temporary_against_account_number"
- ],
- "fields": [
-  {
-   "fieldname": "client",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Client",
-   "options": "Company",
-   "reqd": 1,
-   "unique": 1
-  },
-  {
-   "fieldname": "client_number",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Client ID",
-   "length": 5,
-   "reqd": 1
-  },
-  {
-   "fieldname": "consultant",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Consultant",
-   "options": "Supplier"
-  },
-  {
-   "fieldname": "consultant_number",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Consultant ID",
-   "length": 7,
-   "reqd": 1
-  },
-  {
-   "fieldname": "column_break_2",
-   "fieldtype": "Column Break"
-  },
-  {
-   "fieldname": "section_break_4",
-   "fieldtype": "Section Break"
-  },
-  {
-   "fieldname": "column_break_6",
-   "fieldtype": "Column Break"
-  },
-  {
-   "default": "4",
-   "fieldname": "account_number_length",
-   "fieldtype": "Int",
-   "label": "Account Number Length",
-   "reqd": 1
-  },
-  {
-   "allow_in_quick_entry": 1,
-   "fieldname": "temporary_against_account_number",
-   "fieldtype": "Data",
-   "label": "Temporary Against Account Number",
-   "reqd": 1
-  }
- ],
- "links": [],
- "modified": "2020-11-19 19:00:09.088816",
- "modified_by": "Administrator",
- "module": "Regional",
- "name": "DATEV 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,
-   "email": 1,
-   "export": 1,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Accounts User",
-   "share": 1
-  }
- ],
- "quick_entry": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/erpnext/regional/doctype/datev_settings/datev_settings.py b/erpnext/regional/doctype/datev_settings/datev_settings.py
deleted file mode 100644
index 686a93e..0000000
--- a/erpnext/regional/doctype/datev_settings/datev_settings.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-
-# import frappe
-from frappe.model.document import Document
-
-
-class DATEVSettings(Document):
-	pass
diff --git a/erpnext/regional/doctype/datev_settings/test_datev_settings.py b/erpnext/regional/doctype/datev_settings/test_datev_settings.py
deleted file mode 100644
index ba70eb4..0000000
--- a/erpnext/regional/doctype/datev_settings/test_datev_settings.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-
-# import frappe
-import unittest
-
-
-class TestDATEVSettings(unittest.TestCase):
-	pass
diff --git a/erpnext/regional/germany/__init__.py b/erpnext/regional/germany/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/regional/germany/__init__.py
+++ /dev/null
diff --git a/erpnext/regional/germany/setup.py b/erpnext/regional/germany/setup.py
deleted file mode 100644
index b8e66c3..0000000
--- a/erpnext/regional/germany/setup.py
+++ /dev/null
@@ -1,35 +0,0 @@
-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 = {
-		"Party Account": [
-			dict(
-				fieldname="debtor_creditor_number",
-				label="Debtor/Creditor Number",
-				fieldtype="Data",
-				insert_after="account",
-				translatable=0,
-			)
-		]
-	}
-
-	create_custom_fields(custom_fields)
-
-
-def add_custom_roles_for_reports():
-	"""Add Access Control to UAE VAT 201."""
-	if not frappe.db.get_value("Custom Role", dict(report="DATEV")):
-		frappe.get_doc(
-			dict(
-				doctype="Custom Role",
-				report="DATEV",
-				roles=[dict(role="Accounts User"), dict(role="Accounts Manager")],
-			)
-		).insert()
diff --git a/erpnext/regional/germany/utils/__init__.py b/erpnext/regional/germany/utils/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/regional/germany/utils/__init__.py
+++ /dev/null
diff --git a/erpnext/regional/germany/utils/datev/__init__.py b/erpnext/regional/germany/utils/datev/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/regional/germany/utils/datev/__init__.py
+++ /dev/null
diff --git a/erpnext/regional/germany/utils/datev/datev_constants.py b/erpnext/regional/germany/utils/datev/datev_constants.py
deleted file mode 100644
index 9524481..0000000
--- a/erpnext/regional/germany/utils/datev/datev_constants.py
+++ /dev/null
@@ -1,501 +0,0 @@
-"""Constants used in datev.py."""
-
-TRANSACTION_COLUMNS = [
-	# All possible columns must tbe listed here, because DATEV requires them to
-	# be present in the CSV.
-	# ---
-	# Umsatz
-	"Umsatz (ohne Soll/Haben-Kz)",
-	"Soll/Haben-Kennzeichen",
-	"WKZ Umsatz",
-	"Kurs",
-	"Basis-Umsatz",
-	"WKZ Basis-Umsatz",
-	# Konto/Gegenkonto
-	"Konto",
-	"Gegenkonto (ohne BU-Schlüssel)",
-	"BU-Schlüssel",
-	# Datum
-	"Belegdatum",
-	# Rechnungs- / Belegnummer
-	"Belegfeld 1",
-	# z.B. Fälligkeitsdatum Format: TTMMJJ
-	"Belegfeld 2",
-	# Skonto-Betrag / -Abzug (Der Wert 0 ist unzulässig)
-	"Skonto",
-	# Beschreibung des Buchungssatzes
-	"Buchungstext",
-	# Mahn- / Zahl-Sperre (1 = Postensperre)
-	"Postensperre",
-	"Diverse Adressnummer",
-	"Geschäftspartnerbank",
-	"Sachverhalt",
-	# Keine Mahnzinsen
-	"Zinssperre",
-	# Link auf den Buchungsbeleg (Programmkürzel + GUID)
-	"Beleglink",
-	# Beleginfo
-	"Beleginfo - Art 1",
-	"Beleginfo - Inhalt 1",
-	"Beleginfo - Art 2",
-	"Beleginfo - Inhalt 2",
-	"Beleginfo - Art 3",
-	"Beleginfo - Inhalt 3",
-	"Beleginfo - Art 4",
-	"Beleginfo - Inhalt 4",
-	"Beleginfo - Art 5",
-	"Beleginfo - Inhalt 5",
-	"Beleginfo - Art 6",
-	"Beleginfo - Inhalt 6",
-	"Beleginfo - Art 7",
-	"Beleginfo - Inhalt 7",
-	"Beleginfo - Art 8",
-	"Beleginfo - Inhalt 8",
-	# Zuordnung des Geschäftsvorfalls für die Kostenrechnung
-	"KOST1 - Kostenstelle",
-	"KOST2 - Kostenstelle",
-	"KOST-Menge",
-	# USt-ID-Nummer (Beispiel: DE133546770)
-	"EU-Mitgliedstaat u. USt-IdNr.",
-	# Der im EU-Bestimmungsland gültige Steuersatz
-	"EU-Steuersatz",
-	# I = Ist-Versteuerung,
-	# K = keine Umsatzsteuerrechnung
-	# P = Pauschalierung (z. B. für Land- und Forstwirtschaft),
-	# S = Soll-Versteuerung
-	"Abw. Versteuerungsart",
-	# Sachverhalte gem. § 13b Abs. 1 Satz 1 Nrn. 1.-5. UStG
-	"Sachverhalt L+L",
-	# Steuersatz / Funktion zum L+L-Sachverhalt (Beispiel: Wert 190 für 19%)
-	"Funktionsergänzung L+L",
-	# Bei Verwendung des BU-Schlüssels 49 für „andere Steuersätze“ muss der
-	# steuerliche Sachverhalt mitgegeben werden
-	"BU 49 Hauptfunktionstyp",
-	"BU 49 Hauptfunktionsnummer",
-	"BU 49 Funktionsergänzung",
-	# Zusatzinformationen, besitzen den Charakter eines Notizzettels und können
-	# frei erfasst werden.
-	"Zusatzinformation - Art 1",
-	"Zusatzinformation - Inhalt 1",
-	"Zusatzinformation - Art 2",
-	"Zusatzinformation - Inhalt 2",
-	"Zusatzinformation - Art 3",
-	"Zusatzinformation - Inhalt 3",
-	"Zusatzinformation - Art 4",
-	"Zusatzinformation - Inhalt 4",
-	"Zusatzinformation - Art 5",
-	"Zusatzinformation - Inhalt 5",
-	"Zusatzinformation - Art 6",
-	"Zusatzinformation - Inhalt 6",
-	"Zusatzinformation - Art 7",
-	"Zusatzinformation - Inhalt 7",
-	"Zusatzinformation - Art 8",
-	"Zusatzinformation - Inhalt 8",
-	"Zusatzinformation - Art 9",
-	"Zusatzinformation - Inhalt 9",
-	"Zusatzinformation - Art 10",
-	"Zusatzinformation - Inhalt 10",
-	"Zusatzinformation - Art 11",
-	"Zusatzinformation - Inhalt 11",
-	"Zusatzinformation - Art 12",
-	"Zusatzinformation - Inhalt 12",
-	"Zusatzinformation - Art 13",
-	"Zusatzinformation - Inhalt 13",
-	"Zusatzinformation - Art 14",
-	"Zusatzinformation - Inhalt 14",
-	"Zusatzinformation - Art 15",
-	"Zusatzinformation - Inhalt 15",
-	"Zusatzinformation - Art 16",
-	"Zusatzinformation - Inhalt 16",
-	"Zusatzinformation - Art 17",
-	"Zusatzinformation - Inhalt 17",
-	"Zusatzinformation - Art 18",
-	"Zusatzinformation - Inhalt 18",
-	"Zusatzinformation - Art 19",
-	"Zusatzinformation - Inhalt 19",
-	"Zusatzinformation - Art 20",
-	"Zusatzinformation - Inhalt 20",
-	# Wirkt sich nur bei Sachverhalt mit SKR 14 Land- und Forstwirtschaft aus,
-	# für andere SKR werden die Felder beim Import / Export überlesen bzw.
-	# leer exportiert.
-	"Stück",
-	"Gewicht",
-	# 1 = Lastschrift
-	# 2 = Mahnung
-	# 3 = Zahlung
-	"Zahlweise",
-	"Forderungsart",
-	# JJJJ
-	"Veranlagungsjahr",
-	# TTMMJJJJ
-	"Zugeordnete Fälligkeit",
-	# 1 = Einkauf von Waren
-	# 2 = Erwerb von Roh-Hilfs- und Betriebsstoffen
-	"Skontotyp",
-	# Allgemeine Bezeichnung, des Auftrags / Projekts.
-	"Auftragsnummer",
-	# AA = Angeforderte Anzahlung / Abschlagsrechnung
-	# AG = Erhaltene Anzahlung (Geldeingang)
-	# AV = Erhaltene Anzahlung (Verbindlichkeit)
-	# SR = Schlussrechnung
-	# SU = Schlussrechnung (Umbuchung)
-	# SG = Schlussrechnung (Geldeingang)
-	# SO = Sonstige
-	"Buchungstyp",
-	"USt-Schlüssel (Anzahlungen)",
-	"EU-Mitgliedstaat (Anzahlungen)",
-	"Sachverhalt L+L (Anzahlungen)",
-	"EU-Steuersatz (Anzahlungen)",
-	"Erlöskonto (Anzahlungen)",
-	# Wird beim Import durch SV (Stapelverarbeitung) ersetzt.
-	"Herkunft-Kz",
-	# Wird von DATEV verwendet.
-	"Leerfeld",
-	# Format TTMMJJJJ
-	"KOST-Datum",
-	# Vom Zahlungsempfänger individuell vergebenes Kennzeichen eines Mandats
-	# (z.B. Rechnungs- oder Kundennummer).
-	"SEPA-Mandatsreferenz",
-	# 1 = Skontosperre
-	# 0 = Keine Skontosperre
-	"Skontosperre",
-	# Gesellschafter und Sonderbilanzsachverhalt
-	"Gesellschaftername",
-	# Amtliche Nummer aus der Feststellungserklärung
-	"Beteiligtennummer",
-	"Identifikationsnummer",
-	"Zeichnernummer",
-	# Format TTMMJJJJ
-	"Postensperre bis",
-	# Gesellschafter und Sonderbilanzsachverhalt
-	"Bezeichnung SoBil-Sachverhalt",
-	"Kennzeichen SoBil-Buchung",
-	# 0 = keine Festschreibung
-	# 1 = Festschreibung
-	"Festschreibung",
-	# Format TTMMJJJJ
-	"Leistungsdatum",
-	# Format TTMMJJJJ
-	"Datum Zuord. Steuerperiode",
-	# OPOS-Informationen, Format TTMMJJJJ
-	"Fälligkeit",
-	# G oder 1 = Generalumkehr
-	# 0 = keine Generalumkehr
-	"Generalumkehr (GU)",
-	# Steuersatz für Steuerschlüssel
-	"Steuersatz",
-	# Beispiel: DE für Deutschland
-	"Land",
-]
-
-DEBTOR_CREDITOR_COLUMNS = [
-	# All possible columns must tbe listed here, because DATEV requires them to
-	# be present in the CSV.
-	# Columns "Leerfeld" have been replaced with "Leerfeld #" to not confuse pandas
-	# ---
-	"Konto",
-	"Name (Adressatentyp Unternehmen)",
-	"Unternehmensgegenstand",
-	"Name (Adressatentyp natürl. Person)",
-	"Vorname (Adressatentyp natürl. Person)",
-	"Name (Adressatentyp keine Angabe)",
-	"Adressatentyp",
-	"Kurzbezeichnung",
-	"EU-Land",
-	"EU-USt-IdNr.",
-	"Anrede",
-	"Titel/Akad. Grad",
-	"Adelstitel",
-	"Namensvorsatz",
-	"Adressart",
-	"Straße",
-	"Postfach",
-	"Postleitzahl",
-	"Ort",
-	"Land",
-	"Versandzusatz",
-	"Adresszusatz",
-	"Abweichende Anrede",
-	"Abw. Zustellbezeichnung 1",
-	"Abw. Zustellbezeichnung 2",
-	"Kennz. Korrespondenzadresse",
-	"Adresse gültig von",
-	"Adresse gültig bis",
-	"Telefon",
-	"Bemerkung (Telefon)",
-	"Telefon Geschäftsleitung",
-	"Bemerkung (Telefon GL)",
-	"E-Mail",
-	"Bemerkung (E-Mail)",
-	"Internet",
-	"Bemerkung (Internet)",
-	"Fax",
-	"Bemerkung (Fax)",
-	"Sonstige",
-	"Bemerkung (Sonstige)",
-	"Bankleitzahl 1",
-	"Bankbezeichnung 1",
-	"Bankkonto-Nummer 1",
-	"Länderkennzeichen 1",
-	"IBAN 1",
-	"Leerfeld 1",
-	"SWIFT-Code 1",
-	"Abw. Kontoinhaber 1",
-	"Kennz. Haupt-Bankverb. 1",
-	"Bankverb. 1 Gültig von",
-	"Bankverb. 1 Gültig bis",
-	"Bankleitzahl 2",
-	"Bankbezeichnung 2",
-	"Bankkonto-Nummer 2",
-	"Länderkennzeichen 2",
-	"IBAN 2",
-	"Leerfeld 2",
-	"SWIFT-Code 2",
-	"Abw. Kontoinhaber 2",
-	"Kennz. Haupt-Bankverb. 2",
-	"Bankverb. 2 gültig von",
-	"Bankverb. 2 gültig bis",
-	"Bankleitzahl 3",
-	"Bankbezeichnung 3",
-	"Bankkonto-Nummer 3",
-	"Länderkennzeichen 3",
-	"IBAN 3",
-	"Leerfeld 3",
-	"SWIFT-Code 3",
-	"Abw. Kontoinhaber 3",
-	"Kennz. Haupt-Bankverb. 3",
-	"Bankverb. 3 gültig von",
-	"Bankverb. 3 gültig bis",
-	"Bankleitzahl 4",
-	"Bankbezeichnung 4",
-	"Bankkonto-Nummer 4",
-	"Länderkennzeichen 4",
-	"IBAN 4",
-	"Leerfeld 4",
-	"SWIFT-Code 4",
-	"Abw. Kontoinhaber 4",
-	"Kennz. Haupt-Bankverb. 4",
-	"Bankverb. 4 Gültig von",
-	"Bankverb. 4 Gültig bis",
-	"Bankleitzahl 5",
-	"Bankbezeichnung 5",
-	"Bankkonto-Nummer 5",
-	"Länderkennzeichen 5",
-	"IBAN 5",
-	"Leerfeld 5",
-	"SWIFT-Code 5",
-	"Abw. Kontoinhaber 5",
-	"Kennz. Haupt-Bankverb. 5",
-	"Bankverb. 5 gültig von",
-	"Bankverb. 5 gültig bis",
-	"Leerfeld 6",
-	"Briefanrede",
-	"Grußformel",
-	"Kundennummer",
-	"Steuernummer",
-	"Sprache",
-	"Ansprechpartner",
-	"Vertreter",
-	"Sachbearbeiter",
-	"Diverse-Konto",
-	"Ausgabeziel",
-	"Währungssteuerung",
-	"Kreditlimit (Debitor)",
-	"Zahlungsbedingung",
-	"Fälligkeit in Tagen (Debitor)",
-	"Skonto in Prozent (Debitor)",
-	"Kreditoren-Ziel 1 (Tage)",
-	"Kreditoren-Skonto 1 (%)",
-	"Kreditoren-Ziel 2 (Tage)",
-	"Kreditoren-Skonto 2 (%)",
-	"Kreditoren-Ziel 3 Brutto (Tage)",
-	"Kreditoren-Ziel 4 (Tage)",
-	"Kreditoren-Skonto 4 (%)",
-	"Kreditoren-Ziel 5 (Tage)",
-	"Kreditoren-Skonto 5 (%)",
-	"Mahnung",
-	"Kontoauszug",
-	"Mahntext 1",
-	"Mahntext 2",
-	"Mahntext 3",
-	"Kontoauszugstext",
-	"Mahnlimit Betrag",
-	"Mahnlimit %",
-	"Zinsberechnung",
-	"Mahnzinssatz 1",
-	"Mahnzinssatz 2",
-	"Mahnzinssatz 3",
-	"Lastschrift",
-	"Verfahren",
-	"Mandantenbank",
-	"Zahlungsträger",
-	"Indiv. Feld 1",
-	"Indiv. Feld 2",
-	"Indiv. Feld 3",
-	"Indiv. Feld 4",
-	"Indiv. Feld 5",
-	"Indiv. Feld 6",
-	"Indiv. Feld 7",
-	"Indiv. Feld 8",
-	"Indiv. Feld 9",
-	"Indiv. Feld 10",
-	"Indiv. Feld 11",
-	"Indiv. Feld 12",
-	"Indiv. Feld 13",
-	"Indiv. Feld 14",
-	"Indiv. Feld 15",
-	"Abweichende Anrede (Rechnungsadresse)",
-	"Adressart (Rechnungsadresse)",
-	"Straße (Rechnungsadresse)",
-	"Postfach (Rechnungsadresse)",
-	"Postleitzahl (Rechnungsadresse)",
-	"Ort (Rechnungsadresse)",
-	"Land (Rechnungsadresse)",
-	"Versandzusatz (Rechnungsadresse)",
-	"Adresszusatz (Rechnungsadresse)",
-	"Abw. Zustellbezeichnung 1 (Rechnungsadresse)",
-	"Abw. Zustellbezeichnung 2 (Rechnungsadresse)",
-	"Adresse Gültig von (Rechnungsadresse)",
-	"Adresse Gültig bis (Rechnungsadresse)",
-	"Bankleitzahl 6",
-	"Bankbezeichnung 6",
-	"Bankkonto-Nummer 6",
-	"Länderkennzeichen 6",
-	"IBAN 6",
-	"Leerfeld 7",
-	"SWIFT-Code 6",
-	"Abw. Kontoinhaber 6",
-	"Kennz. Haupt-Bankverb. 6",
-	"Bankverb 6 gültig von",
-	"Bankverb 6 gültig bis",
-	"Bankleitzahl 7",
-	"Bankbezeichnung 7",
-	"Bankkonto-Nummer 7",
-	"Länderkennzeichen 7",
-	"IBAN 7",
-	"Leerfeld 8",
-	"SWIFT-Code 7",
-	"Abw. Kontoinhaber 7",
-	"Kennz. Haupt-Bankverb. 7",
-	"Bankverb 7 gültig von",
-	"Bankverb 7 gültig bis",
-	"Bankleitzahl 8",
-	"Bankbezeichnung 8",
-	"Bankkonto-Nummer 8",
-	"Länderkennzeichen 8",
-	"IBAN 8",
-	"Leerfeld 9",
-	"SWIFT-Code 8",
-	"Abw. Kontoinhaber 8",
-	"Kennz. Haupt-Bankverb. 8",
-	"Bankverb 8 gültig von",
-	"Bankverb 8 gültig bis",
-	"Bankleitzahl 9",
-	"Bankbezeichnung 9",
-	"Bankkonto-Nummer 9",
-	"Länderkennzeichen 9",
-	"IBAN 9",
-	"Leerfeld 10",
-	"SWIFT-Code 9",
-	"Abw. Kontoinhaber 9",
-	"Kennz. Haupt-Bankverb. 9",
-	"Bankverb 9 gültig von",
-	"Bankverb 9 gültig bis",
-	"Bankleitzahl 10",
-	"Bankbezeichnung 10",
-	"Bankkonto-Nummer 10",
-	"Länderkennzeichen 10",
-	"IBAN 10",
-	"Leerfeld 11",
-	"SWIFT-Code 10",
-	"Abw. Kontoinhaber 10",
-	"Kennz. Haupt-Bankverb. 10",
-	"Bankverb 10 gültig von",
-	"Bankverb 10 gültig bis",
-	"Nummer Fremdsystem",
-	"Insolvent",
-	"SEPA-Mandatsreferenz 1",
-	"SEPA-Mandatsreferenz 2",
-	"SEPA-Mandatsreferenz 3",
-	"SEPA-Mandatsreferenz 4",
-	"SEPA-Mandatsreferenz 5",
-	"SEPA-Mandatsreferenz 6",
-	"SEPA-Mandatsreferenz 7",
-	"SEPA-Mandatsreferenz 8",
-	"SEPA-Mandatsreferenz 9",
-	"SEPA-Mandatsreferenz 10",
-	"Verknüpftes OPOS-Konto",
-	"Mahnsperre bis",
-	"Lastschriftsperre bis",
-	"Zahlungssperre bis",
-	"Gebührenberechnung",
-	"Mahngebühr 1",
-	"Mahngebühr 2",
-	"Mahngebühr 3",
-	"Pauschalberechnung",
-	"Verzugspauschale 1",
-	"Verzugspauschale 2",
-	"Verzugspauschale 3",
-	"Alternativer Suchname",
-	"Status",
-	"Anschrift manuell geändert (Korrespondenzadresse)",
-	"Anschrift individuell (Korrespondenzadresse)",
-	"Anschrift manuell geändert (Rechnungsadresse)",
-	"Anschrift individuell (Rechnungsadresse)",
-	"Fristberechnung bei Debitor",
-	"Mahnfrist 1",
-	"Mahnfrist 2",
-	"Mahnfrist 3",
-	"Letzte Frist",
-]
-
-ACCOUNT_NAME_COLUMNS = [
-	# Account number
-	"Konto",
-	# Account name
-	"Kontenbeschriftung",
-	# Language of the account name
-	# "de-DE" or "en-GB"
-	"Sprach-ID",
-]
-
-
-class DataCategory:
-
-	"""Field of the CSV Header."""
-
-	DEBTORS_CREDITORS = "16"
-	ACCOUNT_NAMES = "20"
-	TRANSACTIONS = "21"
-	POSTING_TEXT_CONSTANTS = "67"
-
-
-class FormatName:
-
-	"""Field of the CSV Header, corresponds to DataCategory."""
-
-	DEBTORS_CREDITORS = "Debitoren/Kreditoren"
-	ACCOUNT_NAMES = "Kontenbeschriftungen"
-	TRANSACTIONS = "Buchungsstapel"
-	POSTING_TEXT_CONSTANTS = "Buchungstextkonstanten"
-
-
-class Transactions:
-	DATA_CATEGORY = DataCategory.TRANSACTIONS
-	FORMAT_NAME = FormatName.TRANSACTIONS
-	FORMAT_VERSION = "9"
-	COLUMNS = TRANSACTION_COLUMNS
-
-
-class DebtorsCreditors:
-	DATA_CATEGORY = DataCategory.DEBTORS_CREDITORS
-	FORMAT_NAME = FormatName.DEBTORS_CREDITORS
-	FORMAT_VERSION = "5"
-	COLUMNS = DEBTOR_CREDITOR_COLUMNS
-
-
-class AccountNames:
-	DATA_CATEGORY = DataCategory.ACCOUNT_NAMES
-	FORMAT_NAME = FormatName.ACCOUNT_NAMES
-	FORMAT_VERSION = "2"
-	COLUMNS = ACCOUNT_NAME_COLUMNS
diff --git a/erpnext/regional/germany/utils/datev/datev_csv.py b/erpnext/regional/germany/utils/datev/datev_csv.py
deleted file mode 100644
index d4e9c27..0000000
--- a/erpnext/regional/germany/utils/datev/datev_csv.py
+++ /dev/null
@@ -1,184 +0,0 @@
-import datetime
-import zipfile
-from csv import QUOTE_NONNUMERIC
-from io import BytesIO
-
-import frappe
-import pandas as pd
-from frappe import _
-
-from .datev_constants import DataCategory
-
-
-def get_datev_csv(data, filters, csv_class):
-	"""
-	Fill in missing columns and return a CSV in DATEV Format.
-
-	For automatic processing, DATEV requires the first line of the CSV file to
-	hold meta data such as the length of account numbers oder the category of
-	the data.
-
-	Arguments:
-	data -- array of dictionaries
-	filters -- dict
-	csv_class -- defines DATA_CATEGORY, FORMAT_NAME and COLUMNS
-	"""
-	empty_df = pd.DataFrame(columns=csv_class.COLUMNS)
-	data_df = pd.DataFrame.from_records(data)
-	result = empty_df.append(data_df, sort=True)
-
-	if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS:
-		result["Belegdatum"] = pd.to_datetime(result["Belegdatum"])
-
-		result["Beleginfo - Inhalt 6"] = pd.to_datetime(result["Beleginfo - Inhalt 6"])
-		result["Beleginfo - Inhalt 6"] = result["Beleginfo - Inhalt 6"].dt.strftime("%d%m%Y")
-
-		result["Fälligkeit"] = pd.to_datetime(result["Fälligkeit"])
-		result["Fälligkeit"] = result["Fälligkeit"].dt.strftime("%d%m%y")
-
-		result.sort_values(by="Belegdatum", inplace=True, kind="stable", ignore_index=True)
-
-	if csv_class.DATA_CATEGORY == DataCategory.ACCOUNT_NAMES:
-		result["Sprach-ID"] = "de-DE"
-
-	data = result.to_csv(
-		# Reason for str(';'): https://github.com/pandas-dev/pandas/issues/6035
-		sep=";",
-		# European decimal seperator
-		decimal=",",
-		# Windows "ANSI" encoding
-		encoding="latin_1",
-		# format date as DDMM
-		date_format="%d%m",
-		# Windows line terminator
-		line_terminator="\r\n",
-		# Do not number rows
-		index=False,
-		# Use all columns defined above
-		columns=csv_class.COLUMNS,
-		# Quote most fields, even currency values with "," separator
-		quoting=QUOTE_NONNUMERIC,
-	)
-
-	data = data.encode("latin_1", errors="replace")
-
-	header = get_header(filters, csv_class)
-	header = ";".join(header).encode("latin_1", errors="replace")
-
-	# 1st Row: Header with meta data
-	# 2nd Row: Data heading (Überschrift der Nutzdaten), included in `data` here.
-	# 3rd - nth Row: Data (Nutzdaten)
-	return header + b"\r\n" + data
-
-
-def get_header(filters, csv_class):
-	description = filters.get("voucher_type", csv_class.FORMAT_NAME)
-	company = filters.get("company")
-	datev_settings = frappe.get_doc("DATEV Settings", {"client": company})
-	default_currency = frappe.get_value("Company", company, "default_currency")
-	coa = frappe.get_value("Company", company, "chart_of_accounts")
-	coa_short_code = "04" if "SKR04" in coa else ("03" if "SKR03" in coa else "")
-
-	header = [
-		# DATEV format
-		# 	"DTVF" = created by DATEV software,
-		# 	"EXTF" = created by other software
-		'"EXTF"',
-		# version of the DATEV format
-		# 	141 = 1.41,
-		# 	510 = 5.10,
-		# 	720 = 7.20
-		"700",
-		csv_class.DATA_CATEGORY,
-		'"%s"' % csv_class.FORMAT_NAME,
-		# Format version (regarding format name)
-		csv_class.FORMAT_VERSION,
-		# Generated on
-		datetime.datetime.now().strftime("%Y%m%d%H%M%S") + "000",
-		# Imported on -- stays empty
-		"",
-		# Origin. Any two symbols, will be replaced by "SV" on import.
-		'"EN"',
-		# I = Exported by
-		'"%s"' % frappe.session.user,
-		# J = Imported by -- stays empty
-		"",
-		# K = Tax consultant number (Beraternummer)
-		datev_settings.get("consultant_number", "0000000"),
-		# L = Tax client number (Mandantennummer)
-		datev_settings.get("client_number", "00000"),
-		# M = Start of the fiscal year (Wirtschaftsjahresbeginn)
-		frappe.utils.formatdate(filters.get("fiscal_year_start"), "yyyyMMdd"),
-		# N = Length of account numbers (Sachkontenlänge)
-		str(filters.get("account_number_length", 4)),
-		# O = Transaction batch start date (YYYYMMDD)
-		frappe.utils.formatdate(filters.get("from_date"), "yyyyMMdd")
-		if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS
-		else "",
-		# P = Transaction batch end date (YYYYMMDD)
-		frappe.utils.formatdate(filters.get("to_date"), "yyyyMMdd")
-		if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS
-		else "",
-		# Q = Description (for example, "Sales Invoice") Max. 30 chars
-		'"{}"'.format(_(description)) if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else "",
-		# R = Diktatkürzel
-		"",
-		# S = Buchungstyp
-		# 	1 = Transaction batch (Finanzbuchführung),
-		# 	2 = Annual financial statement (Jahresabschluss)
-		"1" if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else "",
-		# T = Rechnungslegungszweck
-		# 	0 oder leer = vom Rechnungslegungszweck unabhängig
-		# 	50 = Handelsrecht
-		# 	30 = Steuerrecht
-		# 	64 = IFRS
-		# 	40 = Kalkulatorik
-		# 	11 = Reserviert
-		# 	12 = Reserviert
-		"0" if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else "",
-		# U = Festschreibung
-		# TODO: Filter by Accounting Period. In export for closed Accounting Period, this will be "1"
-		"0",
-		# V = Default currency, for example, "EUR"
-		'"%s"' % default_currency if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else "",
-		# reserviert
-		"",
-		# Derivatskennzeichen
-		"",
-		# reserviert
-		"",
-		# reserviert
-		"",
-		# SKR
-		'"%s"' % coa_short_code,
-		# Branchen-Lösungs-ID
-		"",
-		# reserviert
-		"",
-		# reserviert
-		"",
-		# Anwendungsinformation (Verarbeitungskennzeichen der abgebenden Anwendung)
-		"",
-	]
-	return header
-
-
-def zip_and_download(zip_filename, csv_files):
-	"""
-	Put CSV files in a zip archive and send that to the client.
-
-	Params:
-	zip_filename	Name of the zip file
-	csv_files		list of dicts [{'file_name': 'my_file.csv', 'csv_data': 'comma,separated,values'}]
-	"""
-	zip_buffer = BytesIO()
-
-	zip_file = zipfile.ZipFile(zip_buffer, mode="w", compression=zipfile.ZIP_DEFLATED)
-	for csv_file in csv_files:
-		zip_file.writestr(csv_file.get("file_name"), csv_file.get("csv_data"))
-
-	zip_file.close()
-
-	frappe.response["filecontent"] = zip_buffer.getvalue()
-	frappe.response["filename"] = zip_filename
-	frappe.response["type"] = "binary"
diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py
index 5518e1c..0f73c5f 100644
--- a/erpnext/regional/india/e_invoice/utils.py
+++ b/erpnext/regional/india/e_invoice/utils.py
@@ -12,6 +12,7 @@
 
 import frappe
 import jwt
+import requests
 from frappe import _, bold
 from frappe.core.page.background_jobs.background_jobs import get_info
 from frappe.integrations.utils import make_get_request, make_post_request
@@ -830,14 +831,25 @@
 		return self.e_invoice_settings.auth_token
 
 	def make_request(self, request_type, url, headers=None, data=None):
-		if request_type == "post":
-			res = make_post_request(url, headers=headers, data=data)
-		else:
-			res = make_get_request(url, headers=headers, data=data)
+		try:
+			if request_type == "post":
+				res = make_post_request(url, headers=headers, data=data)
+			else:
+				res = make_get_request(url, headers=headers, data=data)
+
+		except requests.exceptions.HTTPError as e:
+			if e.response.status_code in [401, 403] and not hasattr(self, "token_auto_refreshed"):
+				self.auto_refresh_token()
+				headers = self.get_headers()
+				return self.make_request(request_type, url, headers, data)
 
 		self.log_request(url, headers, data, res)
 		return res
 
+	def auto_refresh_token(self):
+		self.fetch_auth_token()
+		self.token_auto_refreshed = True
+
 	def log_request(self, url, headers, data, res):
 		headers.update({"password": self.credentials.password})
 		request_log = frappe.get_doc(
@@ -1075,7 +1087,7 @@
 				"Distance": cint(eway_bill_details.distance),
 				"TransMode": eway_bill_details.mode_of_transport,
 				"TransId": eway_bill_details.gstin,
-				"TransName": eway_bill_details.transporter,
+				"TransName": eway_bill_details.name,
 				"TrnDocDt": eway_bill_details.document_date,
 				"TrnDocNo": eway_bill_details.document_name,
 				"VehNo": eway_bill_details.vehicle_no,
diff --git a/erpnext/regional/report/datev/__init__.py b/erpnext/regional/report/datev/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/regional/report/datev/__init__.py
+++ /dev/null
diff --git a/erpnext/regional/report/datev/datev.js b/erpnext/regional/report/datev/datev.js
deleted file mode 100644
index 03c729e..0000000
--- a/erpnext/regional/report/datev/datev.js
+++ /dev/null
@@ -1,56 +0,0 @@
-frappe.query_reports["DATEV"] = {
-	"filters": [
-		{
-			"fieldname": "company",
-			"label": __("Company"),
-			"fieldtype": "Link",
-			"options": "Company",
-			"default": frappe.defaults.get_user_default("Company") || frappe.defaults.get_global_default("Company"),
-			"reqd": 1
-		},
-		{
-			"fieldname": "from_date",
-			"label": __("From Date"),
-			"default": moment().subtract(1, 'month').startOf('month').format(),
-			"fieldtype": "Date",
-			"reqd": 1
-		},
-		{
-			"fieldname": "to_date",
-			"label": __("To Date"),
-			"default": moment().subtract(1, 'month').endOf('month').format(),
-			"fieldtype": "Date",
-			"reqd": 1
-		},
-		{
-			"fieldname": "voucher_type",
-			"label": __("Voucher Type"),
-			"fieldtype": "Select",
-			"options": "\nSales Invoice\nPurchase Invoice\nPayment Entry\nExpense Claim\nPayroll Entry\nBank Reconciliation\nAsset\nStock Entry"
-		}
-	],
-	onload: function(query_report) {
-		let company = frappe.query_report.get_filter_value('company');
-		frappe.db.exists('DATEV Settings', company).then((settings_exist) => {
-			if (!settings_exist) {
-				frappe.confirm(__('DATEV Settings for your Company are missing. Would you like to create them now?'),
-					() => frappe.new_doc('DATEV Settings', {'company': company})
-				);
-			}
-		});
-
-		query_report.page.add_menu_item(__("Download DATEV File"), () => {
-			const filters = encodeURIComponent(
-				JSON.stringify(
-					query_report.get_values()
-				)
-			);
-			window.open(`/api/method/erpnext.regional.report.datev.datev.download_datev_csv?filters=${filters}`);
-		});
-
-		query_report.page.add_menu_item(__("Change DATEV Settings"), () => {
-			let company = frappe.query_report.get_filter_value('company'); // read company from filters again – it might have changed by now.
-			frappe.set_route('Form', 'DATEV Settings', company);
-		});
-	}
-};
diff --git a/erpnext/regional/report/datev/datev.json b/erpnext/regional/report/datev/datev.json
deleted file mode 100644
index 94e3960..0000000
--- a/erpnext/regional/report/datev/datev.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "add_total_row": 0,
- "columns": [],
- "creation": "2019-04-24 08:45:16.650129",
- "disable_prepared_report": 0,
- "disabled": 0,
- "docstatus": 0,
- "doctype": "Report",
- "filters": [],
- "idx": 0,
- "is_standard": "Yes",
- "modified": "2021-04-06 12:23:00.379517",
- "modified_by": "Administrator",
- "module": "Regional",
- "name": "DATEV",
- "owner": "Administrator",
- "prepared_report": 0,
- "ref_doctype": "GL Entry",
- "report_name": "DATEV",
- "report_type": "Script Report",
- "roles": []
-}
\ No newline at end of file
diff --git a/erpnext/regional/report/datev/datev.py b/erpnext/regional/report/datev/datev.py
deleted file mode 100644
index 2d888a8..0000000
--- a/erpnext/regional/report/datev/datev.py
+++ /dev/null
@@ -1,570 +0,0 @@
-"""
-Provide a report and downloadable CSV according to the German DATEV format.
-
-- Query report showing only the columns that contain data, formatted nicely for
-	dispay to the user.
-- CSV download functionality `download_datev_csv` that provides a CSV file with
-	all required columns. Used to import the data into the DATEV Software.
-"""
-
-import json
-
-import frappe
-from frappe import _
-
-from erpnext.accounts.utils import get_fiscal_year
-from erpnext.regional.germany.utils.datev.datev_constants import (
-	AccountNames,
-	DebtorsCreditors,
-	Transactions,
-)
-from erpnext.regional.germany.utils.datev.datev_csv import get_datev_csv, zip_and_download
-
-COLUMNS = [
-	{
-		"label": "Umsatz (ohne Soll/Haben-Kz)",
-		"fieldname": "Umsatz (ohne Soll/Haben-Kz)",
-		"fieldtype": "Currency",
-		"width": 100,
-	},
-	{
-		"label": "Soll/Haben-Kennzeichen",
-		"fieldname": "Soll/Haben-Kennzeichen",
-		"fieldtype": "Data",
-		"width": 100,
-	},
-	{"label": "Konto", "fieldname": "Konto", "fieldtype": "Data", "width": 100},
-	{
-		"label": "Gegenkonto (ohne BU-Schlüssel)",
-		"fieldname": "Gegenkonto (ohne BU-Schlüssel)",
-		"fieldtype": "Data",
-		"width": 100,
-	},
-	{"label": "BU-Schlüssel", "fieldname": "BU-Schlüssel", "fieldtype": "Data", "width": 100},
-	{"label": "Belegdatum", "fieldname": "Belegdatum", "fieldtype": "Date", "width": 100},
-	{"label": "Belegfeld 1", "fieldname": "Belegfeld 1", "fieldtype": "Data", "width": 150},
-	{"label": "Buchungstext", "fieldname": "Buchungstext", "fieldtype": "Text", "width": 300},
-	{
-		"label": "Beleginfo - Art 1",
-		"fieldname": "Beleginfo - Art 1",
-		"fieldtype": "Link",
-		"options": "DocType",
-		"width": 100,
-	},
-	{
-		"label": "Beleginfo - Inhalt 1",
-		"fieldname": "Beleginfo - Inhalt 1",
-		"fieldtype": "Dynamic Link",
-		"options": "Beleginfo - Art 1",
-		"width": 150,
-	},
-	{
-		"label": "Beleginfo - Art 2",
-		"fieldname": "Beleginfo - Art 2",
-		"fieldtype": "Link",
-		"options": "DocType",
-		"width": 100,
-	},
-	{
-		"label": "Beleginfo - Inhalt 2",
-		"fieldname": "Beleginfo - Inhalt 2",
-		"fieldtype": "Dynamic Link",
-		"options": "Beleginfo - Art 2",
-		"width": 150,
-	},
-	{
-		"label": "Beleginfo - Art 3",
-		"fieldname": "Beleginfo - Art 3",
-		"fieldtype": "Link",
-		"options": "DocType",
-		"width": 100,
-	},
-	{
-		"label": "Beleginfo - Inhalt 3",
-		"fieldname": "Beleginfo - Inhalt 3",
-		"fieldtype": "Dynamic Link",
-		"options": "Beleginfo - Art 3",
-		"width": 150,
-	},
-	{
-		"label": "Beleginfo - Art 4",
-		"fieldname": "Beleginfo - Art 4",
-		"fieldtype": "Data",
-		"width": 100,
-	},
-	{
-		"label": "Beleginfo - Inhalt 4",
-		"fieldname": "Beleginfo - Inhalt 4",
-		"fieldtype": "Data",
-		"width": 150,
-	},
-	{
-		"label": "Beleginfo - Art 5",
-		"fieldname": "Beleginfo - Art 5",
-		"fieldtype": "Data",
-		"width": 150,
-	},
-	{
-		"label": "Beleginfo - Inhalt 5",
-		"fieldname": "Beleginfo - Inhalt 5",
-		"fieldtype": "Data",
-		"width": 100,
-	},
-	{
-		"label": "Beleginfo - Art 6",
-		"fieldname": "Beleginfo - Art 6",
-		"fieldtype": "Data",
-		"width": 150,
-	},
-	{
-		"label": "Beleginfo - Inhalt 6",
-		"fieldname": "Beleginfo - Inhalt 6",
-		"fieldtype": "Date",
-		"width": 100,
-	},
-	{"label": "Fälligkeit", "fieldname": "Fälligkeit", "fieldtype": "Date", "width": 100},
-]
-
-
-def execute(filters=None):
-	"""Entry point for frappe."""
-	data = []
-	if filters and validate(filters):
-		fn = "temporary_against_account_number"
-		filters[fn] = frappe.get_value("DATEV Settings", filters.get("company"), fn)
-		data = get_transactions(filters, as_dict=0)
-
-	return COLUMNS, data
-
-
-def validate(filters):
-	"""Make sure all mandatory filters and settings are present."""
-	company = filters.get("company")
-	if not company:
-		frappe.throw(_("<b>Company</b> is a mandatory filter."))
-
-	from_date = filters.get("from_date")
-	if not from_date:
-		frappe.throw(_("<b>From Date</b> is a mandatory filter."))
-
-	to_date = filters.get("to_date")
-	if not to_date:
-		frappe.throw(_("<b>To Date</b> is a mandatory filter."))
-
-	validate_fiscal_year(from_date, to_date, company)
-
-	if not frappe.db.exists("DATEV Settings", filters.get("company")):
-		msg = "Please create DATEV Settings for Company {}".format(filters.get("company"))
-		frappe.log_error(msg, title="DATEV Settings missing")
-		return False
-
-	return True
-
-
-def validate_fiscal_year(from_date, to_date, company):
-	from_fiscal_year = get_fiscal_year(date=from_date, company=company)
-	to_fiscal_year = get_fiscal_year(date=to_date, company=company)
-	if from_fiscal_year != to_fiscal_year:
-		frappe.throw(_("Dates {} and {} are not in the same fiscal year.").format(from_date, to_date))
-
-
-def get_transactions(filters, as_dict=1):
-	def run(params_method, filters):
-		extra_fields, extra_joins, extra_filters = params_method(filters)
-		return run_query(filters, extra_fields, extra_joins, extra_filters, as_dict=as_dict)
-
-	def sort_by(row):
-		# "Belegdatum" is in the fifth column when list format is used
-		return row["Belegdatum" if as_dict else 5]
-
-	type_map = {
-		# specific query methods for some voucher types
-		"Payment Entry": get_payment_entry_params,
-		"Sales Invoice": get_sales_invoice_params,
-		"Purchase Invoice": get_purchase_invoice_params,
-	}
-
-	only_voucher_type = filters.get("voucher_type")
-	transactions = []
-
-	for voucher_type, get_voucher_params in type_map.items():
-		if only_voucher_type and only_voucher_type != voucher_type:
-			continue
-
-		transactions.extend(run(params_method=get_voucher_params, filters=filters))
-
-	if not only_voucher_type or only_voucher_type not in type_map:
-		# generic query method for all other voucher types
-		filters["exclude_voucher_types"] = type_map.keys()
-		transactions.extend(run(params_method=get_generic_params, filters=filters))
-
-	return sorted(transactions, key=sort_by)
-
-
-def get_payment_entry_params(filters):
-	extra_fields = """
-		, 'Zahlungsreferenz' as 'Beleginfo - Art 5'
-		, pe.reference_no as 'Beleginfo - Inhalt 5'
-		, 'Buchungstag' as 'Beleginfo - Art 6'
-		, pe.reference_date as 'Beleginfo - Inhalt 6'
-		, '' as 'Fälligkeit'
-	"""
-
-	extra_joins = """
-		LEFT JOIN `tabPayment Entry` pe
-		ON gl.voucher_no = pe.name
-	"""
-
-	extra_filters = """
-		AND gl.voucher_type = 'Payment Entry'
-	"""
-
-	return extra_fields, extra_joins, extra_filters
-
-
-def get_sales_invoice_params(filters):
-	extra_fields = """
-		, '' as 'Beleginfo - Art 5'
-		, '' as 'Beleginfo - Inhalt 5'
-		, '' as 'Beleginfo - Art 6'
-		, '' as 'Beleginfo - Inhalt 6'
-		, si.due_date as 'Fälligkeit'
-	"""
-
-	extra_joins = """
-		LEFT JOIN `tabSales Invoice` si
-		ON gl.voucher_no = si.name
-	"""
-
-	extra_filters = """
-		AND gl.voucher_type = 'Sales Invoice'
-	"""
-
-	return extra_fields, extra_joins, extra_filters
-
-
-def get_purchase_invoice_params(filters):
-	extra_fields = """
-		, 'Lieferanten-Rechnungsnummer' as 'Beleginfo - Art 5'
-		, pi.bill_no as 'Beleginfo - Inhalt 5'
-		, 'Lieferanten-Rechnungsdatum' as 'Beleginfo - Art 6'
-		, pi.bill_date as 'Beleginfo - Inhalt 6'
-		, pi.due_date as 'Fälligkeit'
-	"""
-
-	extra_joins = """
-		LEFT JOIN `tabPurchase Invoice` pi
-		ON gl.voucher_no = pi.name
-	"""
-
-	extra_filters = """
-		AND gl.voucher_type = 'Purchase Invoice'
-	"""
-
-	return extra_fields, extra_joins, extra_filters
-
-
-def get_generic_params(filters):
-	# produce empty fields so all rows will have the same length
-	extra_fields = """
-		, '' as 'Beleginfo - Art 5'
-		, '' as 'Beleginfo - Inhalt 5'
-		, '' as 'Beleginfo - Art 6'
-		, '' as 'Beleginfo - Inhalt 6'
-		, '' as 'Fälligkeit'
-	"""
-	extra_joins = ""
-
-	if filters.get("exclude_voucher_types"):
-		# exclude voucher types that are queried by a dedicated method
-		exclude = "({})".format(
-			", ".join("'{}'".format(key) for key in filters.get("exclude_voucher_types"))
-		)
-		extra_filters = "AND gl.voucher_type NOT IN {}".format(exclude)
-
-	# if voucher type filter is set, allow only this type
-	if filters.get("voucher_type"):
-		extra_filters += " AND gl.voucher_type = %(voucher_type)s"
-
-	return extra_fields, extra_joins, extra_filters
-
-
-def run_query(filters, extra_fields, extra_joins, extra_filters, as_dict=1):
-	"""
-	Get a list of accounting entries.
-
-	Select GL Entries joined with Account and Party Account in order to get the
-	account numbers. Returns a list of accounting entries.
-
-	Arguments:
-	filters -- dict of filters to be passed to the sql query
-	as_dict -- return as list of dicts [0,1]
-	"""
-	query = """
-		SELECT
-
-			/* either debit or credit amount; always positive */
-			case gl.debit when 0 then gl.credit else gl.debit end as 'Umsatz (ohne Soll/Haben-Kz)',
-
-			/* 'H' when credit, 'S' when debit */
-			case gl.debit when 0 then 'H' else 'S' end as 'Soll/Haben-Kennzeichen',
-
-			/* account number or, if empty, party account number */
-			acc.account_number as 'Konto',
-
-			/* against number or, if empty, party against number */
-			%(temporary_against_account_number)s as 'Gegenkonto (ohne BU-Schlüssel)',
-
-			'' as 'BU-Schlüssel',
-
-			gl.posting_date as 'Belegdatum',
-			gl.voucher_no as 'Belegfeld 1',
-			REPLACE(LEFT(gl.remarks, 60), '\n', ' ') as 'Buchungstext',
-			gl.voucher_type as 'Beleginfo - Art 1',
-			gl.voucher_no as 'Beleginfo - Inhalt 1',
-			gl.against_voucher_type as 'Beleginfo - Art 2',
-			gl.against_voucher as 'Beleginfo - Inhalt 2',
-			gl.party_type as 'Beleginfo - Art 3',
-			gl.party as 'Beleginfo - Inhalt 3',
-			case gl.party_type when 'Customer' then 'Debitorennummer' when 'Supplier' then 'Kreditorennummer' else NULL end as 'Beleginfo - Art 4',
-			par.debtor_creditor_number as 'Beleginfo - Inhalt 4'
-
-			{extra_fields}
-
-		FROM `tabGL Entry` gl
-
-			/* Kontonummer */
-			LEFT JOIN `tabAccount` acc
-			ON gl.account = acc.name
-
-			LEFT JOIN `tabParty Account` par
-			ON par.parent = gl.party
-			AND par.parenttype = gl.party_type
-			AND par.company = %(company)s
-
-			{extra_joins}
-
-		WHERE gl.company = %(company)s
-		AND DATE(gl.posting_date) >= %(from_date)s
-		AND DATE(gl.posting_date) <= %(to_date)s
-
-		{extra_filters}
-
-		ORDER BY 'Belegdatum', gl.voucher_no""".format(
-		extra_fields=extra_fields, extra_joins=extra_joins, extra_filters=extra_filters
-	)
-
-	gl_entries = frappe.db.sql(query, filters, as_dict=as_dict)
-
-	return gl_entries
-
-
-def get_customers(filters):
-	"""
-	Get a list of Customers.
-
-	Arguments:
-	filters -- dict of filters to be passed to the sql query
-	"""
-	return frappe.db.sql(
-		"""
-		SELECT
-
-			par.debtor_creditor_number as 'Konto',
-			CASE cus.customer_type
-				WHEN 'Company' THEN cus.customer_name
-				ELSE null
-				END as 'Name (Adressatentyp Unternehmen)',
-			CASE cus.customer_type
-				WHEN 'Individual' THEN TRIM(SUBSTR(cus.customer_name, LOCATE(' ', cus.customer_name)))
-				ELSE null
-				END as 'Name (Adressatentyp natürl. Person)',
-			CASE cus.customer_type
-				WHEN 'Individual' THEN SUBSTRING_INDEX(SUBSTRING_INDEX(cus.customer_name, ' ', 1), ' ', -1)
-				ELSE null
-				END as 'Vorname (Adressatentyp natürl. Person)',
-			CASE cus.customer_type
-				WHEN 'Individual' THEN '1'
-				WHEN 'Company' THEN '2'
-				ELSE '0'
-				END as 'Adressatentyp',
-			adr.address_line1 as 'Straße',
-			adr.pincode as 'Postleitzahl',
-			adr.city as 'Ort',
-			UPPER(country.code) as 'Land',
-			adr.address_line2 as 'Adresszusatz',
-			adr.email_id as 'E-Mail',
-			adr.phone as 'Telefon',
-			adr.fax as 'Fax',
-			cus.website as 'Internet',
-			cus.tax_id as 'Steuernummer'
-
-		FROM `tabCustomer` cus
-
-			left join `tabParty Account` par
-			on par.parent = cus.name
-			and par.parenttype = 'Customer'
-			and par.company = %(company)s
-
-			left join `tabDynamic Link` dyn_adr
-			on dyn_adr.link_name = cus.name
-			and dyn_adr.link_doctype = 'Customer'
-			and dyn_adr.parenttype = 'Address'
-
-			left join `tabAddress` adr
-			on adr.name = dyn_adr.parent
-			and adr.is_primary_address = '1'
-
-			left join `tabCountry` country
-			on country.name = adr.country
-
-		WHERE adr.is_primary_address = '1'
-		""",
-		filters,
-		as_dict=1,
-	)
-
-
-def get_suppliers(filters):
-	"""
-	Get a list of Suppliers.
-
-	Arguments:
-	filters -- dict of filters to be passed to the sql query
-	"""
-	return frappe.db.sql(
-		"""
-		SELECT
-
-			par.debtor_creditor_number as 'Konto',
-			CASE sup.supplier_type
-				WHEN 'Company' THEN sup.supplier_name
-				ELSE null
-				END as 'Name (Adressatentyp Unternehmen)',
-			CASE sup.supplier_type
-				WHEN 'Individual' THEN TRIM(SUBSTR(sup.supplier_name, LOCATE(' ', sup.supplier_name)))
-				ELSE null
-				END as 'Name (Adressatentyp natürl. Person)',
-			CASE sup.supplier_type
-				WHEN 'Individual' THEN SUBSTRING_INDEX(SUBSTRING_INDEX(sup.supplier_name, ' ', 1), ' ', -1)
-				ELSE null
-				END as 'Vorname (Adressatentyp natürl. Person)',
-			CASE sup.supplier_type
-				WHEN 'Individual' THEN '1'
-				WHEN 'Company' THEN '2'
-				ELSE '0'
-				END as 'Adressatentyp',
-			adr.address_line1 as 'Straße',
-			adr.pincode as 'Postleitzahl',
-			adr.city as 'Ort',
-			UPPER(country.code) as 'Land',
-			adr.address_line2 as 'Adresszusatz',
-			adr.email_id as 'E-Mail',
-			adr.phone as 'Telefon',
-			adr.fax as 'Fax',
-			sup.website as 'Internet',
-			sup.tax_id as 'Steuernummer',
-			case sup.on_hold when 1 then sup.release_date else null end as 'Zahlungssperre bis'
-
-		FROM `tabSupplier` sup
-
-			left join `tabParty Account` par
-			on par.parent = sup.name
-			and par.parenttype = 'Supplier'
-			and par.company = %(company)s
-
-			left join `tabDynamic Link` dyn_adr
-			on dyn_adr.link_name = sup.name
-			and dyn_adr.link_doctype = 'Supplier'
-			and dyn_adr.parenttype = 'Address'
-
-			left join `tabAddress` adr
-			on adr.name = dyn_adr.parent
-			and adr.is_primary_address = '1'
-
-			left join `tabCountry` country
-			on country.name = adr.country
-
-		WHERE adr.is_primary_address = '1'
-		""",
-		filters,
-		as_dict=1,
-	)
-
-
-def get_account_names(filters):
-	return frappe.db.sql(
-		"""
-		SELECT
-
-			account_number as 'Konto',
-			LEFT(account_name, 40) as 'Kontenbeschriftung',
-			'de-DE' as 'Sprach-ID'
-
-		FROM `tabAccount`
-		WHERE company = %(company)s
-		AND is_group = 0
-		AND account_number != ''
-	""",
-		filters,
-		as_dict=1,
-	)
-
-
-@frappe.whitelist()
-def download_datev_csv(filters):
-	"""
-	Provide accounting entries for download in DATEV format.
-
-	Validate the filters, get the data, produce the CSV file and provide it for
-	download. Can be called like this:
-
-	GET /api/method/erpnext.regional.report.datev.datev.download_datev_csv
-
-	Arguments / Params:
-	filters -- dict of filters to be passed to the sql query
-	"""
-	if isinstance(filters, str):
-		filters = json.loads(filters)
-
-	validate(filters)
-	company = filters.get("company")
-
-	fiscal_year = get_fiscal_year(date=filters.get("from_date"), company=company)
-	filters["fiscal_year_start"] = fiscal_year[1]
-
-	# set chart of accounts used
-	coa = frappe.get_value("Company", company, "chart_of_accounts")
-	filters["skr"] = "04" if "SKR04" in coa else ("03" if "SKR03" in coa else "")
-
-	datev_settings = frappe.get_doc("DATEV Settings", company)
-	filters["account_number_length"] = datev_settings.account_number_length
-	filters["temporary_against_account_number"] = datev_settings.temporary_against_account_number
-
-	transactions = get_transactions(filters)
-	account_names = get_account_names(filters)
-	customers = get_customers(filters)
-	suppliers = get_suppliers(filters)
-
-	zip_name = "{} DATEV.zip".format(frappe.utils.datetime.date.today())
-	zip_and_download(
-		zip_name,
-		[
-			{
-				"file_name": "EXTF_Buchungsstapel.csv",
-				"csv_data": get_datev_csv(transactions, filters, csv_class=Transactions),
-			},
-			{
-				"file_name": "EXTF_Kontenbeschriftungen.csv",
-				"csv_data": get_datev_csv(account_names, filters, csv_class=AccountNames),
-			},
-			{
-				"file_name": "EXTF_Kunden.csv",
-				"csv_data": get_datev_csv(customers, filters, csv_class=DebtorsCreditors),
-			},
-			{
-				"file_name": "EXTF_Lieferanten.csv",
-				"csv_data": get_datev_csv(suppliers, filters, csv_class=DebtorsCreditors),
-			},
-		],
-	)
diff --git a/erpnext/regional/report/datev/test_datev.py b/erpnext/regional/report/datev/test_datev.py
deleted file mode 100644
index 0df8c06..0000000
--- a/erpnext/regional/report/datev/test_datev.py
+++ /dev/null
@@ -1,252 +0,0 @@
-import zipfile
-from io import BytesIO
-from unittest import TestCase
-
-import frappe
-from frappe.utils import cstr, now_datetime, today
-
-from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
-from erpnext.regional.germany.utils.datev.datev_constants import (
-	AccountNames,
-	DebtorsCreditors,
-	Transactions,
-)
-from erpnext.regional.germany.utils.datev.datev_csv import get_datev_csv, get_header
-from erpnext.regional.report.datev.datev import (
-	download_datev_csv,
-	get_account_names,
-	get_customers,
-	get_suppliers,
-	get_transactions,
-)
-
-
-def make_company(company_name, abbr):
-	if not frappe.db.exists("Company", company_name):
-		company = frappe.get_doc(
-			{
-				"doctype": "Company",
-				"company_name": company_name,
-				"abbr": abbr,
-				"default_currency": "EUR",
-				"country": "Germany",
-				"create_chart_of_accounts_based_on": "Standard Template",
-				"chart_of_accounts": "SKR04 mit Kontonummern",
-			}
-		)
-		company.insert()
-	else:
-		company = frappe.get_doc("Company", company_name)
-
-	# indempotent
-	company.create_default_warehouses()
-
-	if not frappe.db.get_value("Cost Center", {"is_group": 0, "company": company.name}):
-		company.create_default_cost_center()
-
-	company.save()
-	return company
-
-
-def setup_fiscal_year():
-	fiscal_year = None
-	year = cstr(now_datetime().year)
-	if not frappe.db.get_value("Fiscal Year", {"year": year}, "name"):
-		try:
-			fiscal_year = frappe.get_doc(
-				{
-					"doctype": "Fiscal Year",
-					"year": year,
-					"year_start_date": "{0}-01-01".format(year),
-					"year_end_date": "{0}-12-31".format(year),
-				}
-			)
-			fiscal_year.insert()
-		except frappe.NameError:
-			pass
-
-	if fiscal_year:
-		fiscal_year.set_as_default()
-
-
-def make_customer_with_account(customer_name, company):
-	acc_name = frappe.db.get_value(
-		"Account", {"account_name": customer_name, "company": company.name}, "name"
-	)
-
-	if not acc_name:
-		acc = frappe.get_doc(
-			{
-				"doctype": "Account",
-				"parent_account": "1 - Forderungen aus Lieferungen und Leistungen - _TG",
-				"account_name": customer_name,
-				"company": company.name,
-				"account_type": "Receivable",
-				"account_number": "10001",
-			}
-		)
-		acc.insert()
-		acc_name = acc.name
-
-	if not frappe.db.exists("Customer", customer_name):
-		customer = frappe.get_doc(
-			{
-				"doctype": "Customer",
-				"customer_name": customer_name,
-				"customer_type": "Company",
-				"accounts": [{"company": company.name, "account": acc_name}],
-			}
-		)
-		customer.insert()
-	else:
-		customer = frappe.get_doc("Customer", customer_name)
-
-	return customer
-
-
-def make_item(item_code, company):
-	warehouse_name = frappe.db.get_value(
-		"Warehouse", {"warehouse_name": "Stores", "company": company.name}, "name"
-	)
-
-	if not frappe.db.exists("Item", item_code):
-		item = frappe.get_doc(
-			{
-				"doctype": "Item",
-				"item_code": item_code,
-				"item_name": item_code,
-				"description": item_code,
-				"item_group": "All Item Groups",
-				"is_stock_item": 0,
-				"is_purchase_item": 0,
-				"is_customer_provided_item": 0,
-				"item_defaults": [{"default_warehouse": warehouse_name, "company": company.name}],
-			}
-		)
-		item.insert()
-	else:
-		item = frappe.get_doc("Item", item_code)
-	return item
-
-
-def make_datev_settings(company):
-	if not frappe.db.exists("DATEV Settings", company.name):
-		frappe.get_doc(
-			{
-				"doctype": "DATEV Settings",
-				"client": company.name,
-				"client_number": "12345",
-				"consultant_number": "67890",
-				"temporary_against_account_number": "9999",
-			}
-		).insert()
-
-
-class TestDatev(TestCase):
-	def setUp(self):
-		self.company = make_company("_Test GmbH", "_TG")
-		self.customer = make_customer_with_account("_Test Kunde GmbH", self.company)
-		self.filters = {
-			"company": self.company.name,
-			"from_date": today(),
-			"to_date": today(),
-			"temporary_against_account_number": "9999",
-		}
-
-		make_datev_settings(self.company)
-		item = make_item("_Test Item", self.company)
-		setup_fiscal_year()
-
-		warehouse = frappe.db.get_value(
-			"Item Default", {"parent": item.name, "company": self.company.name}, "default_warehouse"
-		)
-
-		income_account = frappe.db.get_value(
-			"Account", {"account_number": "4200", "company": self.company.name}, "name"
-		)
-
-		tax_account = frappe.db.get_value(
-			"Account", {"account_number": "3806", "company": self.company.name}, "name"
-		)
-
-		si = create_sales_invoice(
-			company=self.company.name,
-			customer=self.customer.name,
-			currency=self.company.default_currency,
-			debit_to=self.customer.accounts[0].account,
-			income_account="4200 - Erlöse - _TG",
-			expense_account="6990 - Herstellungskosten - _TG",
-			cost_center=self.company.cost_center,
-			warehouse=warehouse,
-			item=item.name,
-			do_not_save=1,
-		)
-
-		si.append(
-			"taxes",
-			{
-				"charge_type": "On Net Total",
-				"account_head": tax_account,
-				"description": "Umsatzsteuer 19 %",
-				"rate": 19,
-				"cost_center": self.company.cost_center,
-			},
-		)
-
-		si.cost_center = self.company.cost_center
-
-		si.save()
-		si.submit()
-
-	def test_columns(self):
-		def is_subset(get_data, allowed_keys):
-			"""
-			Validate that the dict contains only allowed keys.
-
-			Params:
-			get_data -- Function that returns a list of dicts.
-			allowed_keys -- List of allowed keys
-			"""
-			data = get_data(self.filters)
-			if data == []:
-				# No data and, therefore, no columns is okay
-				return True
-			actual_set = set(data[0].keys())
-			# allowed set must be interpreted as unicode to match the actual set
-			allowed_set = set({frappe.as_unicode(key) for key in allowed_keys})
-			return actual_set.issubset(allowed_set)
-
-		self.assertTrue(is_subset(get_transactions, Transactions.COLUMNS))
-		self.assertTrue(is_subset(get_customers, DebtorsCreditors.COLUMNS))
-		self.assertTrue(is_subset(get_suppliers, DebtorsCreditors.COLUMNS))
-		self.assertTrue(is_subset(get_account_names, AccountNames.COLUMNS))
-
-	def test_header(self):
-		self.assertTrue(Transactions.DATA_CATEGORY in get_header(self.filters, Transactions))
-		self.assertTrue(AccountNames.DATA_CATEGORY in get_header(self.filters, AccountNames))
-		self.assertTrue(DebtorsCreditors.DATA_CATEGORY in get_header(self.filters, DebtorsCreditors))
-
-	def test_csv(self):
-		test_data = [
-			{
-				"Umsatz (ohne Soll/Haben-Kz)": 100,
-				"Soll/Haben-Kennzeichen": "H",
-				"Kontonummer": "4200",
-				"Gegenkonto (ohne BU-Schlüssel)": "10000",
-				"Belegdatum": today(),
-				"Buchungstext": "No remark",
-				"Beleginfo - Art 1": "Sales Invoice",
-				"Beleginfo - Inhalt 1": "SINV-0001",
-			}
-		]
-		get_datev_csv(data=test_data, filters=self.filters, csv_class=Transactions)
-
-	def test_download(self):
-		"""Assert that the returned file is a ZIP file."""
-		download_datev_csv(self.filters)
-
-		# zipfile.is_zipfile() expects a file-like object
-		zip_buffer = BytesIO()
-		zip_buffer.write(frappe.response["filecontent"])
-
-		self.assertTrue(zipfile.is_zipfile(zip_buffer))
diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json
index ae40630..7cba141 100644
--- a/erpnext/selling/doctype/customer/customer.json
+++ b/erpnext/selling/doctype/customer/customer.json
@@ -15,23 +15,23 @@
   "salutation",
   "customer_name",
   "gender",
-  "customer_type",
-  "tax_withholding_category",
   "default_bank_account",
+  "tax_id",
+  "tax_category",
+  "tax_withholding_category",
   "lead_name",
   "opportunity_name",
   "image",
   "column_break0",
-  "account_manager",
   "customer_group",
+  "customer_type",
   "territory",
-  "tax_id",
-  "tax_category",
+  "account_manager",
   "so_required",
   "dn_required",
-  "disabled",
   "is_internal_customer",
   "represents_company",
+  "disabled",
   "allowed_to_transact_section",
   "companies",
   "currency_and_price_list",
@@ -40,7 +40,6 @@
   "default_price_list",
   "address_contacts",
   "address_html",
-  "website",
   "column_break1",
   "contact_html",
   "primary_address_and_contact_detail",
@@ -60,6 +59,7 @@
   "column_break_45",
   "market_segment",
   "industry",
+  "website",
   "language",
   "is_frozen",
   "column_break_38",
@@ -100,7 +100,7 @@
    "fieldname": "customer_name",
    "fieldtype": "Data",
    "in_global_search": 1,
-   "label": "Full Name",
+   "label": "Customer Name",
    "no_copy": 1,
    "oldfieldname": "customer_name",
    "oldfieldtype": "Data",
@@ -118,7 +118,7 @@
    "default": "Company",
    "fieldname": "customer_type",
    "fieldtype": "Select",
-   "label": "Type",
+   "label": "Customer Type",
    "oldfieldname": "customer_type",
    "oldfieldtype": "Select",
    "options": "Company\nIndividual",
@@ -337,7 +337,7 @@
    "collapsible": 1,
    "fieldname": "default_receivable_accounts",
    "fieldtype": "Section Break",
-   "label": "Accounting"
+   "label": "Default Receivable Accounts"
   },
   {
    "description": "Mention if non-standard receivable account",
@@ -511,7 +511,7 @@
    "link_fieldname": "party"
   }
  ],
- "modified": "2021-10-20 22:07:52.485809",
+ "modified": "2022-04-16 20:32:34.000304",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Customer",
@@ -595,6 +595,7 @@
  "show_name_in_global_search": 1,
  "sort_field": "modified",
  "sort_order": "ASC",
+ "states": [],
  "title_field": "customer_name",
  "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py
index 61c0b8a..548813d 100644
--- a/erpnext/selling/doctype/quotation/quotation.py
+++ b/erpnext/selling/doctype/quotation/quotation.py
@@ -27,6 +27,7 @@
 		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
@@ -49,6 +50,26 @@
 		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 has_sales_order(self):
 		return frappe.db.get_value("Sales Order Item", {"prevdoc_docname": self.name, "docstatus": 1})
 
diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py
index b44fa5e..6f0b381 100644
--- a/erpnext/selling/doctype/quotation/test_quotation.py
+++ b/erpnext/selling/doctype/quotation/test_quotation.py
@@ -130,6 +130,15 @@
 		quotation.submit()
 		self.assertRaises(frappe.ValidationError, 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/selling_settings/selling_settings.json b/erpnext/selling/doctype/selling_settings/selling_settings.json
index 7c4a3f6..005e24c 100644
--- a/erpnext/selling/doctype/selling_settings/selling_settings.json
+++ b/erpnext/selling/doctype/selling_settings/selling_settings.json
@@ -27,7 +27,8 @@
   "column_break_5",
   "allow_multiple_items",
   "allow_against_multiple_purchase_orders",
-  "hide_tax_id"
+  "hide_tax_id",
+  "enable_discount_accounting"
  ],
  "fields": [
   {
@@ -164,6 +165,13 @@
    "fieldname": "editable_bundle_item_rates",
    "fieldtype": "Check",
    "label": "Calculate Product Bundle Price based on Child Items' Rates"
+  },
+  {
+   "default": "0",
+   "description": "If enabled, additional ledger entries will be made for discounts in a separate Discount Account",
+   "fieldname": "enable_discount_accounting",
+   "fieldtype": "Check",
+   "label": "Enable Discount Accounting for Selling"
   }
  ],
  "icon": "fa fa-cog",
@@ -171,7 +179,7 @@
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2022-02-04 15:41:59.939261",
+ "modified": "2022-04-14 16:01:29.405642",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Selling Settings",
diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.py b/erpnext/selling/doctype/selling_settings/selling_settings.py
index 29e4712..6c09894 100644
--- a/erpnext/selling/doctype/selling_settings/selling_settings.py
+++ b/erpnext/selling/doctype/selling_settings/selling_settings.py
@@ -14,6 +14,7 @@
 	def on_update(self):
 		self.toggle_hide_tax_id()
 		self.toggle_editable_rate_for_bundle_items()
+		self.toggle_discount_accounting_fields()
 
 	def validate(self):
 		for key in [
@@ -58,3 +59,60 @@
 			"Check",
 			validate_fields_for_doctype=False,
 		)
+
+	def toggle_discount_accounting_fields(self):
+		enable_discount_accounting = cint(self.enable_discount_accounting)
+
+		make_property_setter(
+			"Sales Invoice Item",
+			"discount_account",
+			"hidden",
+			not (enable_discount_accounting),
+			"Check",
+			validate_fields_for_doctype=False,
+		)
+		if enable_discount_accounting:
+			make_property_setter(
+				"Sales Invoice Item",
+				"discount_account",
+				"mandatory_depends_on",
+				"eval: doc.discount_amount",
+				"Code",
+				validate_fields_for_doctype=False,
+			)
+		else:
+			make_property_setter(
+				"Sales Invoice Item",
+				"discount_account",
+				"mandatory_depends_on",
+				"",
+				"Code",
+				validate_fields_for_doctype=False,
+			)
+
+		make_property_setter(
+			"Sales Invoice",
+			"additional_discount_account",
+			"hidden",
+			not (enable_discount_accounting),
+			"Check",
+			validate_fields_for_doctype=False,
+		)
+		if enable_discount_accounting:
+			make_property_setter(
+				"Sales Invoice",
+				"additional_discount_account",
+				"mandatory_depends_on",
+				"eval: doc.discount_amount",
+				"Code",
+				validate_fields_for_doctype=False,
+			)
+		else:
+			make_property_setter(
+				"Sales Invoice",
+				"additional_discount_account",
+				"mandatory_depends_on",
+				"",
+				"Code",
+				validate_fields_for_doctype=False,
+			)
diff --git a/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py
index a410513..dcfb10a 100644
--- a/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py
+++ b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py
@@ -81,7 +81,7 @@
 			ON sii.so_detail = soi.name and sii.docstatus = 1)
 		LEFT JOIN `tabDelivery Note Item` dni
 			on dni.so_detail = soi.name
-		RIGHT JOIN `tabDelivery Note` dn
+		LEFT JOIN `tabDelivery Note` dn
 			on dni.parent = dn.name and dn.docstatus = 1
 		WHERE
 			soi.parent = so.name
diff --git a/erpnext/selling/report/sales_order_analysis/test_sales_order_analysis.py b/erpnext/selling/report/sales_order_analysis/test_sales_order_analysis.py
new file mode 100644
index 0000000..25cbb73
--- /dev/null
+++ b/erpnext/selling/report/sales_order_analysis/test_sales_order_analysis.py
@@ -0,0 +1,166 @@
+import frappe
+from frappe.tests.utils import FrappeTestCase
+from frappe.utils import add_days
+
+from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note, make_sales_invoice
+from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
+from erpnext.selling.report.sales_order_analysis.sales_order_analysis import execute
+from erpnext.stock.doctype.item.test_item import create_item
+
+test_dependencies = ["Sales Order", "Item", "Sales Invoice", "Delivery Note"]
+
+
+class TestSalesOrderAnalysis(FrappeTestCase):
+	def create_sales_order(self, transaction_date):
+		item = create_item(item_code="_Test Excavator", is_stock_item=0)
+		so = make_sales_order(
+			transaction_date=transaction_date,
+			item=item.item_code,
+			qty=10,
+			rate=100000,
+			do_not_save=True,
+		)
+		so.po_no = ""
+		so.taxes_and_charges = ""
+		so.taxes = ""
+		so.items[0].delivery_date = add_days(transaction_date, 15)
+		so.save()
+		so.submit()
+		return item, so
+
+	def create_sales_invoice(self, so):
+		sinv = make_sales_invoice(so.name)
+		sinv.posting_date = so.transaction_date
+		sinv.taxes_and_charges = ""
+		sinv.taxes = ""
+		sinv.insert()
+		sinv.submit()
+		return sinv
+
+	def create_delivery_note(self, so):
+		dn = make_delivery_note(so.name)
+		dn.set_posting_time = True
+		dn.posting_date = add_days(so.transaction_date, 1)
+		dn.save()
+		dn.submit()
+		return dn
+
+	def test_01_so_to_deliver_and_bill(self):
+		transaction_date = "2021-06-01"
+		item, so = self.create_sales_order(transaction_date)
+		columns, data, message, chart = execute(
+			{
+				"company": "_Test Company",
+				"from_date": "2021-06-01",
+				"to_date": "2021-06-30",
+				"status": ["To Deliver and Bill"],
+			}
+		)
+		expected_value = {
+			"status": "To Deliver and Bill",
+			"sales_order": so.name,
+			"delay_days": frappe.utils.date_diff(frappe.utils.datetime.date.today(), so.delivery_date),
+			"qty": 10,
+			"delivered_qty": 0,
+			"pending_qty": 10,
+			"qty_to_bill": 10,
+			"time_taken_to_deliver": 0,
+		}
+		self.assertEqual(len(data), 1)
+		for key, val in expected_value.items():
+			with self.subTest(key=key, val=val):
+				self.assertEqual(data[0][key], val)
+
+	def test_02_so_to_deliver(self):
+		transaction_date = "2021-06-01"
+		item, so = self.create_sales_order(transaction_date)
+		self.create_sales_invoice(so)
+		columns, data, message, chart = execute(
+			{
+				"company": "_Test Company",
+				"from_date": "2021-06-01",
+				"to_date": "2021-06-30",
+				"status": ["To Deliver"],
+			}
+		)
+		expected_value = {
+			"status": "To Deliver",
+			"sales_order": so.name,
+			"delay_days": frappe.utils.date_diff(frappe.utils.datetime.date.today(), so.delivery_date),
+			"qty": 10,
+			"delivered_qty": 0,
+			"pending_qty": 10,
+			"qty_to_bill": 0,
+			"time_taken_to_deliver": 0,
+		}
+		self.assertEqual(len(data), 1)
+		for key, val in expected_value.items():
+			with self.subTest(key=key, val=val):
+				self.assertEqual(data[0][key], val)
+
+	def test_03_so_to_bill(self):
+		transaction_date = "2021-06-01"
+		item, so = self.create_sales_order(transaction_date)
+		self.create_delivery_note(so)
+		columns, data, message, chart = execute(
+			{
+				"company": "_Test Company",
+				"from_date": "2021-06-01",
+				"to_date": "2021-06-30",
+				"status": ["To Bill"],
+			}
+		)
+		expected_value = {
+			"status": "To Bill",
+			"sales_order": so.name,
+			"delay_days": frappe.utils.date_diff(frappe.utils.datetime.date.today(), so.delivery_date),
+			"qty": 10,
+			"delivered_qty": 10,
+			"pending_qty": 0,
+			"qty_to_bill": 10,
+			"time_taken_to_deliver": 86400,
+		}
+		self.assertEqual(len(data), 1)
+		for key, val in expected_value.items():
+			with self.subTest(key=key, val=val):
+				self.assertEqual(data[0][key], val)
+
+	def test_04_so_completed(self):
+		transaction_date = "2021-06-01"
+		item, so = self.create_sales_order(transaction_date)
+		self.create_sales_invoice(so)
+		self.create_delivery_note(so)
+		columns, data, message, chart = execute(
+			{
+				"company": "_Test Company",
+				"from_date": "2021-06-01",
+				"to_date": "2021-06-30",
+				"status": ["Completed"],
+			}
+		)
+		expected_value = {
+			"status": "Completed",
+			"sales_order": so.name,
+			"delay_days": frappe.utils.date_diff(frappe.utils.datetime.date.today(), so.delivery_date),
+			"qty": 10,
+			"delivered_qty": 10,
+			"pending_qty": 0,
+			"qty_to_bill": 0,
+			"billed_qty": 10,
+			"time_taken_to_deliver": 86400,
+		}
+		self.assertEqual(len(data), 1)
+		for key, val in expected_value.items():
+			with self.subTest(key=key, val=val):
+				self.assertEqual(data[0][key], val)
+
+	def test_05_all_so_status(self):
+		columns, data, message, chart = execute(
+			{
+				"company": "_Test Company",
+				"from_date": "2021-06-01",
+				"to_date": "2021-06-30",
+			}
+		)
+		# SO's from first 4 test cases should be in output
+		self.assertEqual(len(data), 4)
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index dd185fc..0de5b2d 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -233,7 +233,8 @@
 		["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"]]}]
+		["unrealized_profit_loss_account", {"root_type": ["in", ["Liability", "Asset"]]}],
+		["default_provisional_account", {"root_type": ["in", ["Liability", "Asset"]]}]
 	], function(i, v) {
 		erpnext.company.set_custom_query(frm, v);
 	});
diff --git a/erpnext/setup/doctype/item_group/item_group.js b/erpnext/setup/doctype/item_group/item_group.js
index f570c2f..4b04ac1 100644
--- a/erpnext/setup/doctype/item_group/item_group.js
+++ b/erpnext/setup/doctype/item_group/item_group.js
@@ -72,17 +72,16 @@
 			});
 		}
 
-		frappe.model.with_doctype('Item', () => {
-			const item_meta = frappe.get_meta('Item');
+		frappe.model.with_doctype('Website Item', () => {
+			const web_item_meta = frappe.get_meta('Website Item');
 
-			const valid_fields = item_meta.fields.filter(
-				df => ['Link', 'Table MultiSelect'].includes(df.fieldtype) && !df.hidden
-			).map(df => ({ label: df.label, value: df.fieldname }));
-
-			frm.fields_dict.filter_fields.grid.update_docfield_property(
-				'fieldname', 'fieldtype', 'Select'
+			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.fields_dict.filter_fields.grid.update_docfield_property(
+
+			frm.get_field("filter_fields").grid.update_docfield_property(
 				'fieldname', 'options', valid_fields
 			);
 		});
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index 35557a5..6e940d0 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -11,6 +11,7 @@
 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
 
 
@@ -35,6 +36,7 @@
 
 		self.make_route()
 		self.validate_item_group_defaults()
+		ECommerceSettings.validate_field_filters(self.filter_fields, enable_field_filters=True)
 
 	def on_update(self):
 		NestedSet.on_update(self)
diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py
index 6ea4525..1bfce66 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -4,8 +4,8 @@
 
 import frappe
 from frappe.model.document import Document
-from frappe.query_builder import Case
-from frappe.query_builder.functions import Coalesce, Sum
+from frappe.query_builder import Case, Order
+from frappe.query_builder.functions import Coalesce, CombineDatetime, Sum
 from frappe.utils import flt
 
 
@@ -121,24 +121,23 @@
 
 	bin_details = get_bin_details(bin_name)
 	# actual qty is already updated by processing current voucher
-	actual_qty = bin_details.actual_qty
+	actual_qty = bin_details.actual_qty or 0.0
+	sle = frappe.qb.DocType("Stock Ledger Entry")
 
 	# actual qty is not up to date in case of backdated transaction
 	if future_sle_exists(args):
-		actual_qty = (
-			frappe.db.get_value(
-				"Stock Ledger Entry",
-				filters={
-					"item_code": args.get("item_code"),
-					"warehouse": args.get("warehouse"),
-					"is_cancelled": 0,
-				},
-				fieldname="qty_after_transaction",
-				order_by="posting_date desc, posting_time desc, creation desc",
-			)
-			or 0.0
+		last_sle_qty = (
+			frappe.qb.from_(sle)
+			.select(sle.qty_after_transaction)
+			.where((sle.item_code == args.get("item_code")) & (sle.warehouse == args.get("warehouse")))
+			.orderby(CombineDatetime(sle.posting_date, sle.posting_time), order=Order.desc)
+			.orderby(sle.creation, order=Order.desc)
+			.run()
 		)
 
+		if last_sle_qty:
+			actual_qty = last_sle_qty[0][0]
+
 	ordered_qty = flt(bin_details.ordered_qty) + flt(args.get("ordered_qty"))
 	reserved_qty = flt(bin_details.reserved_qty) + flt(args.get("reserved_qty"))
 	indented_qty = flt(bin_details.indented_qty) + flt(args.get("indented_qty"))
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index 23301a6..ae8b488 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -377,6 +377,17 @@
 			}
 		}
 
+		frm.set_query('default_provisional_account', 'item_defaults', (doc, cdt, cdn) => {
+			let row = locals[cdt][cdn];
+			return {
+				filters: {
+					"company": row.company,
+					"root_type": ["in", ["Liability", "Asset"]],
+					"is_group": 0
+				}
+			};
+		});
+
 	},
 
 	make_dashboard: function(frm) {
diff --git a/erpnext/stock/doctype/item_default/item_default.json b/erpnext/stock/doctype/item_default/item_default.json
index bc17160..042d398 100644
--- a/erpnext/stock/doctype/item_default/item_default.json
+++ b/erpnext/stock/doctype/item_default/item_default.json
@@ -15,6 +15,7 @@
   "default_supplier",
   "column_break_8",
   "expense_account",
+  "default_provisional_account",
   "selling_defaults",
   "selling_cost_center",
   "column_break_12",
@@ -101,11 +102,17 @@
    "fieldtype": "Link",
    "label": "Default Discount Account",
    "options": "Account"
+  },
+  {
+   "fieldname": "default_provisional_account",
+   "fieldtype": "Link",
+   "label": "Default Provisional Account",
+   "options": "Account"
   }
  ],
  "istable": 1,
  "links": [],
- "modified": "2021-07-13 01:26:03.860065",
+ "modified": "2022-04-10 20:18:54.148195",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Item Default",
@@ -114,5 +121,6 @@
  "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/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
index 6e5f6f5..19c490d 100755
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
@@ -106,8 +106,6 @@
   "terms",
   "bill_no",
   "bill_date",
-  "accounting_details_section",
-  "provisional_expense_account",
   "more_info",
   "project",
   "status",
@@ -1145,26 +1143,13 @@
    "label": "Represents Company",
    "options": "Company",
    "read_only": 1
-  },
-  {
-   "collapsible": 1,
-   "fieldname": "accounting_details_section",
-   "fieldtype": "Section Break",
-   "label": "Accounting Details"
-  },
-  {
-   "fieldname": "provisional_expense_account",
-   "fieldtype": "Link",
-   "hidden": 1,
-   "label": "Provisional Expense Account",
-   "options": "Account"
   }
  ],
  "icon": "fa fa-truck",
  "idx": 261,
  "is_submittable": 1,
  "links": [],
- "modified": "2022-03-10 11:40:52.690984",
+ "modified": "2022-04-10 22:50:37.761362",
  "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 1e1c0b9..ec0e809 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -145,10 +145,13 @@
 			)
 		)
 
-		if provisional_accounting_for_non_stock_items:
-			default_provisional_account = self.get_company_default("default_provisional_account")
-			if not self.provisional_expense_account:
-				self.provisional_expense_account = default_provisional_account
+		if not provisional_accounting_for_non_stock_items:
+			return
+
+		default_provisional_account = self.get_company_default("default_provisional_account")
+		for item in self.get("items"):
+			if not item.get("provisional_expense_account"):
+				item.provisional_expense_account = default_provisional_account
 
 	def validate_with_previous_doc(self):
 		super(PurchaseReceipt, self).validate_with_previous_doc(
@@ -509,7 +512,9 @@
 				and flt(d.qty)
 				and provisional_accounting_for_non_stock_items
 			):
-				self.add_provisional_gl_entry(d, gl_entries, self.posting_date)
+				self.add_provisional_gl_entry(
+					d, gl_entries, self.posting_date, d.get("provisional_expense_account")
+				)
 
 		if warehouse_with_no_account:
 			frappe.msgprint(
@@ -518,9 +523,10 @@
 				+ "\n".join(warehouse_with_no_account)
 			)
 
-	def add_provisional_gl_entry(self, item, gl_entries, posting_date, reverse=0):
-		provisional_expense_account = self.get("provisional_expense_account")
-		credit_currency = get_account_currency(provisional_expense_account)
+	def add_provisional_gl_entry(
+		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
 		remarks = self.get("remarks") or _("Accounting Entry for Service")
@@ -534,7 +540,7 @@
 
 		self.add_gl_entry(
 			gl_entries=gl_entries,
-			account=provisional_expense_account,
+			account=provisional_account,
 			cost_center=item.cost_center,
 			debit=0.0,
 			credit=multiplication_factor * item.amount,
@@ -554,7 +560,7 @@
 			debit=multiplication_factor * item.amount,
 			credit=0.0,
 			remarks=remarks,
-			against_account=provisional_expense_account,
+			against_account=provisional_account,
 			account_currency=debit_currency,
 			project=item.project,
 			voucher_detail_no=item.name,
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index f3faba4..ce3bd56 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -747,14 +747,13 @@
 			update_purchase_receipt_status,
 		)
 
-		pr = make_purchase_receipt()
+		item = make_item()
+
+		pr = make_purchase_receipt(item_code=item.name)
 
 		update_purchase_receipt_status(pr.name, "Closed")
 		self.assertEqual(frappe.db.get_value("Purchase Receipt", pr.name, "status"), "Closed")
 
-		pr.reload()
-		pr.cancel()
-
 	def test_pr_billing_status(self):
 		"""Flow:
 		1. PO -> PR1 -> PI
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 03a4201..1c65ac8 100644
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
@@ -96,7 +96,6 @@
   "include_exploded_items",
   "batch_no",
   "rejected_serial_no",
-  "expense_account",
   "item_tax_rate",
   "item_weight_details",
   "weight_per_unit",
@@ -107,6 +106,10 @@
   "manufacturer",
   "column_break_16",
   "manufacturer_part_no",
+  "accounting_details_section",
+  "expense_account",
+  "column_break_102",
+  "provisional_expense_account",
   "accounting_dimensions_section",
   "project",
   "dimension_col_break",
@@ -971,12 +974,27 @@
    "label": "Product Bundle",
    "options": "Product Bundle",
    "read_only": 1
+  },
+  {
+   "fieldname": "provisional_expense_account",
+   "fieldtype": "Link",
+   "label": "Provisional Expense Account",
+   "options": "Account"
+  },
+  {
+   "fieldname": "accounting_details_section",
+   "fieldtype": "Section Break",
+   "label": "Accounting Details"
+  },
+  {
+   "fieldname": "column_break_102",
+   "fieldtype": "Column Break"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2022-02-01 11:32:27.980524",
+ "modified": "2022-04-11 13:07:32.061402",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt Item",
diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json
index 6148e16..156f77f 100644
--- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json
+++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json
@@ -23,6 +23,7 @@
   "error_section",
   "error_log",
   "items_to_be_repost",
+  "affected_transactions",
   "distinct_item_and_warehouse",
   "current_index"
  ],
@@ -172,12 +173,20 @@
    "no_copy": 1,
    "print_hide": 1,
    "read_only": 1
+  },
+  {
+   "fieldname": "affected_transactions",
+   "fieldtype": "Code",
+   "hidden": 1,
+   "label": "Affected Transactions",
+   "no_copy": 1,
+   "read_only": 1
   }
  ],
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2022-03-30 07:22:48.520266",
+ "modified": "2022-04-18 14:08:08.821602",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Repost Item Valuation",
diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
index 54c00d1..eb0be46 100644
--- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
+++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
@@ -4,16 +4,16 @@
 import frappe
 from frappe import _
 from frappe.model.document import Document
-from frappe.utils import cint, get_link_to_form, get_weekday, now, nowtime, today
+from frappe.utils import cint, get_link_to_form, get_weekday, now, nowtime
 from frappe.utils.user import get_users_with_role
-from rq.timeouts import JobTimeoutException
 
 import erpnext
-from erpnext.accounts.utils import (
-	check_if_stock_and_account_balance_synced,
-	update_gl_entries_after,
+from erpnext.accounts.utils import get_future_stock_vouchers, repost_gle_for_stock_vouchers
+from erpnext.stock.stock_ledger import (
+	get_affected_transactions,
+	get_items_to_be_repost,
+	repost_future_sle,
 )
-from erpnext.stock.stock_ledger import get_items_to_be_repost, repost_future_sle
 
 
 class RepostItemValuation(Document):
@@ -132,12 +132,12 @@
 
 		doc.set_status("Completed")
 
-	except (Exception, JobTimeoutException):
+	except Exception:
 		frappe.db.rollback()
 		traceback = frappe.get_traceback()
 		frappe.log_error(traceback)
 
-		message = frappe.message_log.pop()
+		message = frappe.message_log.pop() if frappe.message_log else ""
 		if traceback:
 			message += "<br>" + "Traceback: <br>" + traceback
 		frappe.db.set_value(doc.doctype, doc.name, "error_log", message)
@@ -173,6 +173,7 @@
 			],
 			allow_negative_stock=doc.allow_negative_stock,
 			via_landed_cost_voucher=doc.via_landed_cost_voucher,
+			doc=doc,
 		)
 
 
@@ -180,27 +181,46 @@
 	if not cint(erpnext.is_perpetual_inventory_enabled(doc.company)):
 		return
 
+	# directly modified transactions
+	directly_dependent_transactions = _get_directly_dependent_vouchers(doc)
+	repost_affected_transaction = get_affected_transactions(doc)
+	repost_gle_for_stock_vouchers(
+		directly_dependent_transactions + list(repost_affected_transaction),
+		doc.posting_date,
+		doc.company,
+	)
+
+
+def _get_directly_dependent_vouchers(doc):
+	"""Get stock vouchers that are directly affected by reposting
+	i.e. any one item-warehouse is present in the stock transaction"""
+
+	items = set()
+	warehouses = set()
+
 	if doc.based_on == "Transaction":
 		ref_doc = frappe.get_doc(doc.voucher_type, doc.voucher_no)
 		doc_items, doc_warehouses = ref_doc.get_items_and_warehouses()
+		items.update(doc_items)
+		warehouses.update(doc_warehouses)
 
 		sles = get_items_to_be_repost(doc.voucher_type, doc.voucher_no)
-		sle_items = [sle.item_code for sle in sles]
-		sle_warehouse = [sle.warehouse for sle in sles]
-
-		items = list(set(doc_items).union(set(sle_items)))
-		warehouses = list(set(doc_warehouses).union(set(sle_warehouse)))
+		sle_items = {sle.item_code for sle in sles}
+		sle_warehouses = {sle.warehouse for sle in sles}
+		items.update(sle_items)
+		warehouses.update(sle_warehouses)
 	else:
-		items = [doc.item_code]
-		warehouses = [doc.warehouse]
+		items.add(doc.item_code)
+		warehouses.add(doc.warehouse)
 
-	update_gl_entries_after(
-		doc.posting_date,
-		doc.posting_time,
-		for_warehouses=warehouses,
-		for_items=items,
+	affected_vouchers = get_future_stock_vouchers(
+		posting_date=doc.posting_date,
+		posting_time=doc.posting_time,
+		for_warehouses=list(warehouses),
+		for_items=list(items),
 		company=doc.company,
 	)
+	return affected_vouchers
 
 
 def notify_error_to_stock_managers(doc, traceback):
@@ -224,6 +244,10 @@
 
 
 def repost_entries():
+	"""
+	Reposts 'Repost Item Valuation' entries in queue.
+	Called hourly via hooks.py.
+	"""
 	if not in_configured_timeslot():
 		return
 
@@ -239,9 +263,6 @@
 	if riv_entries:
 		return
 
-	for d in frappe.get_all("Company", filters={"enable_perpetual_inventory": 1}):
-		check_if_stock_and_account_balance_synced(today(), d.name)
-
 
 def get_repost_item_valuation_entries():
 	return frappe.db.sql(
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 55117ce..3184f69 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
@@ -186,3 +186,10 @@
 		riv.db_set("status", "Skipped")
 		riv.reload()
 		riv.cancel()  # it should cancel now
+
+	def test_queue_progress_serialization(self):
+		# Make sure set/tuple -> list behaviour is retained.
+		self.assertEqual(
+			[["a", "b"], ["c", "d"]],
+			sorted(frappe.parse_json(frappe.as_json(set([("a", "b"), ("c", "d")])))),
+		)
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 316c897..7101190 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -777,11 +777,11 @@
 		exclude_sr_nos = get_serial_nos(clean_serial_no_string("\n".join(exclude_sr_nos)))
 
 	if batch_nos:
-		batch_nos = safe_json_loads(batch_nos)
-		if isinstance(batch_nos, list):
-			filters.batch_no = batch_nos
+		batch_nos_list = safe_json_loads(batch_nos)
+		if isinstance(batch_nos_list, list):
+			filters.batch_no = batch_nos_list
 		else:
-			filters.batch_no = [str(batch_nos)]
+			filters.batch_no = [batch_nos]
 
 	if posting_date:
 		filters.expiry_date = posting_date
diff --git a/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py
index 6561362..5850ec7 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py
+++ b/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py
@@ -2,14 +2,15 @@
 # See license.txt
 
 import json
-from operator import itemgetter
 from uuid import uuid4
 
 import frappe
 from frappe.core.page.permission_manager.permission_manager import reset
 from frappe.custom.doctype.property_setter.property_setter import make_property_setter
+from frappe.query_builder.functions import CombineDatetime
 from frappe.tests.utils import FrappeTestCase
 from frappe.utils import add_days, today
+from frappe.utils.data import add_to_date
 
 from erpnext.accounts.doctype.gl_entry.gl_entry import rename_gle_sle_docs
 from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
@@ -1067,6 +1068,121 @@
 		receipt2 = make_stock_entry(item_code=item, target=warehouse, qty=15, rate=15)
 		self.assertSLEs(receipt2, [{"stock_queue": [[5, 15]], "stock_value_difference": 175}])
 
+	def test_dependent_gl_entry_reposting(self):
+		def _get_stock_credit(doc):
+			return frappe.db.get_value(
+				"GL Entry",
+				{
+					"voucher_no": doc.name,
+					"voucher_type": doc.doctype,
+					"is_cancelled": 0,
+					"account": "Stock In Hand - TCP1",
+				},
+				"sum(credit)",
+			)
+
+		def _day(days):
+			return add_to_date(date=today(), days=days)
+
+		item = make_item().name
+		A = "Stores - TCP1"
+		B = "Work In Progress - TCP1"
+		C = "Finished Goods - TCP1"
+
+		make_stock_entry(item_code=item, to_warehouse=A, qty=5, rate=10, posting_date=_day(0))
+		make_stock_entry(item_code=item, from_warehouse=A, to_warehouse=B, qty=5, posting_date=_day(1))
+		depdendent_consumption = make_stock_entry(
+			item_code=item, from_warehouse=B, qty=5, posting_date=_day(2)
+		)
+		self.assertEqual(50, _get_stock_credit(depdendent_consumption))
+
+		# backdated receipt - should trigger GL repost of all previous stock entries
+		bd_receipt = make_stock_entry(
+			item_code=item, to_warehouse=A, qty=5, rate=20, posting_date=_day(-1)
+		)
+		self.assertEqual(100, _get_stock_credit(depdendent_consumption))
+
+		# cancelling receipt should reset it back
+		bd_receipt.cancel()
+		self.assertEqual(50, _get_stock_credit(depdendent_consumption))
+
+		bd_receipt2 = make_stock_entry(
+			item_code=item, to_warehouse=A, qty=2, rate=20, posting_date=_day(-2)
+		)
+		# total as per FIFO -> 2 * 20 + 3 * 10 = 70
+		self.assertEqual(70, _get_stock_credit(depdendent_consumption))
+
+		# transfer WIP material to final destination and consume it all
+		depdendent_consumption.cancel()
+		make_stock_entry(item_code=item, from_warehouse=B, to_warehouse=C, qty=5, posting_date=_day(3))
+		final_consumption = make_stock_entry(
+			item_code=item, from_warehouse=C, qty=5, posting_date=_day(4)
+		)
+		# exact amount gets consumed
+		self.assertEqual(70, _get_stock_credit(final_consumption))
+
+		# cancel original backdated receipt - should repost A -> B -> C
+		bd_receipt2.cancel()
+		# original amount
+		self.assertEqual(50, _get_stock_credit(final_consumption))
+
+	def test_tie_breaking(self):
+		frappe.flags.dont_execute_stock_reposts = True
+		self.addCleanup(frappe.flags.pop, "dont_execute_stock_reposts")
+
+		item = make_item().name
+		warehouse = "_Test Warehouse - _TC"
+
+		posting_date = "2022-01-01"
+		posting_time = "00:00:01"
+		sle = frappe.qb.DocType("Stock Ledger Entry")
+
+		def ordered_qty_after_transaction():
+			return (
+				frappe.qb.from_(sle)
+				.select("qty_after_transaction")
+				.where((sle.item_code == item) & (sle.warehouse == warehouse) & (sle.is_cancelled == 0))
+				.orderby(CombineDatetime(sle.posting_date, sle.posting_time))
+				.orderby(sle.creation)
+			).run(pluck=True)
+
+		first = make_stock_entry(
+			item_code=item,
+			to_warehouse=warehouse,
+			qty=10,
+			posting_time=posting_time,
+			posting_date=posting_date,
+			do_not_submit=True,
+		)
+		second = make_stock_entry(
+			item_code=item,
+			to_warehouse=warehouse,
+			qty=1,
+			posting_date=posting_date,
+			posting_time=posting_time,
+			do_not_submit=True,
+		)
+
+		first.submit()
+		second.submit()
+
+		self.assertEqual([10, 11], ordered_qty_after_transaction())
+
+		first.cancel()
+		self.assertEqual([1], ordered_qty_after_transaction())
+
+		backdated = make_stock_entry(
+			item_code=item,
+			to_warehouse=warehouse,
+			qty=1,
+			posting_date="2021-01-01",
+			posting_time=posting_time,
+		)
+		self.assertEqual([1, 2], ordered_qty_after_transaction())
+
+		backdated.cancel()
+		self.assertEqual([1], ordered_qty_after_transaction())
+
 
 def create_repack_entry(**args):
 	args = frappe._dict(args)
diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
index 46a3f2a..e826e00 100644
--- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
@@ -10,7 +10,7 @@
 from frappe.utils import add_days, cstr, flt, nowdate, nowtime, random_string
 
 from erpnext.accounts.utils import get_stock_and_account_balance
-from erpnext.stock.doctype.item.test_item import create_item
+from erpnext.stock.doctype.item.test_item import create_item, make_item
 from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
 from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
 from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import (
@@ -31,6 +31,7 @@
 
 	def tearDown(self):
 		frappe.flags.dont_execute_stock_reposts = None
+		frappe.local.future_sle = {}
 
 	def test_reco_for_fifo(self):
 		self._test_reco_sle_gle("FIFO")
@@ -311,9 +312,8 @@
 		SR4		| Reco	|	0	|	6	(posting date: today-1) [backdated]
 		PR3		| PR	|	1	|	7	(posting date: today) # can't post future PR
 		"""
-		item_code = "Backdated-Reco-Item"
+		item_code = make_item().name
 		warehouse = "_Test Warehouse - _TC"
-		create_item(item_code)
 
 		pr1 = make_purchase_receipt(
 			item_code=item_code, warehouse=warehouse, qty=10, rate=100, posting_date=add_days(nowdate(), -3)
@@ -395,9 +395,8 @@
 		from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
 		from erpnext.stock.stock_ledger import NegativeStockError
 
-		item_code = "Backdated-Reco-Item"
+		item_code = make_item().name
 		warehouse = "_Test Warehouse - _TC"
-		create_item(item_code)
 
 		pr1 = make_purchase_receipt(
 			item_code=item_code, warehouse=warehouse, qty=10, rate=100, posting_date=add_days(nowdate(), -2)
@@ -444,9 +443,8 @@
 		from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
 		from erpnext.stock.stock_ledger import NegativeStockError
 
-		item_code = "Backdated-Reco-Cancellation-Item"
+		item_code = make_item().name
 		warehouse = "_Test Warehouse - _TC"
-		create_item(item_code)
 
 		sr = create_stock_reconciliation(
 			item_code=item_code,
@@ -487,9 +485,8 @@
 		frappe.flags.dont_execute_stock_reposts = True
 		frappe.db.rollback()
 
-		item_code = "Backdated-Reco-Cancellation-Item"
+		item_code = make_item().name
 		warehouse = "_Test Warehouse - _TC"
-		create_item(item_code)
 
 		sr = create_stock_reconciliation(
 			item_code=item_code, warehouse=warehouse, qty=10, rate=100, posting_date=add_days(nowdate(), 10)
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index d3a230e..324ff4f 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -345,6 +345,7 @@
 			"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),
 			"cost_center": get_default_cost_center(
 				args, item_defaults, item_group_defaults, brand_defaults
 			),
@@ -699,6 +700,10 @@
 	)
 
 
+def get_provisional_account(args, item):
+	return item.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
 
diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py
index afbc6fe..6369f91 100644
--- a/erpnext/stock/report/stock_balance/stock_balance.py
+++ b/erpnext/stock/report/stock_balance/stock_balance.py
@@ -3,24 +3,41 @@
 
 
 from operator import itemgetter
+from typing import Any, Dict, List, Optional, TypedDict
 
 import frappe
 from frappe import _
+from frappe.query_builder.functions import CombineDatetime
 from frappe.utils import cint, date_diff, flt, getdate
+from frappe.utils.nestedset import get_descendants_of
+from pypika.terms import ExistsCriterion
 
 import erpnext
 from erpnext.stock.report.stock_ageing.stock_ageing import FIFOSlots, get_average_age
-from erpnext.stock.report.stock_ledger.stock_ledger import get_item_group_condition
 from erpnext.stock.utils import add_additional_uom_columns, is_reposting_item_valuation_in_progress
 
 
-def execute(filters=None):
+class StockBalanceFilter(TypedDict):
+	company: Optional[str]
+	from_date: str
+	to_date: str
+	item_group: Optional[str]
+	item: Optional[str]
+	warehouse: Optional[str]
+	warehouse_type: Optional[str]
+	include_uom: Optional[str]  # include extra info in converted UOM
+	show_stock_ageing_data: bool
+	show_variant_attributes: bool
+
+
+SLEntry = Dict[str, Any]
+
+
+def execute(filters: Optional[StockBalanceFilter] = None):
 	is_reposting_item_valuation_in_progress()
 	if not filters:
 		filters = {}
 
-	to_date = filters.get("to_date")
-
 	if filters.get("company"):
 		company_currency = erpnext.get_company_currency(filters.get("company"))
 	else:
@@ -48,6 +65,7 @@
 
 	_func = itemgetter(1)
 
+	to_date = filters.get("to_date")
 	for (company, item, warehouse) in sorted(iwb_map):
 		if item_map.get(item):
 			qty_dict = iwb_map[(company, item, warehouse)]
@@ -92,7 +110,7 @@
 	return columns, data
 
 
-def get_columns(filters):
+def get_columns(filters: StockBalanceFilter):
 	"""return columns"""
 	columns = [
 		{
@@ -215,66 +233,77 @@
 	return columns
 
 
-def get_conditions(filters):
-	conditions = ""
+def apply_conditions(query, filters):
+	sle = frappe.qb.DocType("Stock Ledger Entry")
+	warehouse_table = frappe.qb.DocType("Warehouse")
+
 	if not filters.get("from_date"):
 		frappe.throw(_("'From Date' is required"))
 
-	if filters.get("to_date"):
-		conditions += " and sle.posting_date <= %s" % frappe.db.escape(filters.get("to_date"))
+	if to_date := filters.get("to_date"):
+		query = query.where(sle.posting_date <= to_date)
 	else:
 		frappe.throw(_("'To Date' is required"))
 
-	if filters.get("company"):
-		conditions += " and sle.company = %s" % frappe.db.escape(filters.get("company"))
+	if company := filters.get("company"):
+		query = query.where(sle.company == company)
 
-	if filters.get("warehouse"):
-		warehouse_details = frappe.db.get_value(
-			"Warehouse", filters.get("warehouse"), ["lft", "rgt"], as_dict=1
-		)
-		if warehouse_details:
-			conditions += (
-				" and exists (select name from `tabWarehouse` wh \
-				where wh.lft >= %s and wh.rgt <= %s and sle.warehouse = wh.name)"
-				% (warehouse_details.lft, warehouse_details.rgt)
+	if warehouse := filters.get("warehouse"):
+		lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
+		chilren_subquery = (
+			frappe.qb.from_(warehouse_table)
+			.select(warehouse_table.name)
+			.where(
+				(warehouse_table.lft >= lft)
+				& (warehouse_table.rgt <= rgt)
+				& (warehouse_table.name == sle.warehouse)
 			)
-
-	if filters.get("warehouse_type") and not filters.get("warehouse"):
-		conditions += (
-			" and exists (select name from `tabWarehouse` wh \
-			where wh.warehouse_type = '%s' and sle.warehouse = wh.name)"
-			% (filters.get("warehouse_type"))
+		)
+		query = query.where(ExistsCriterion(chilren_subquery))
+	elif warehouse_type := filters.get("warehouse_type"):
+		query = (
+			query.join(warehouse_table)
+			.on(warehouse_table.name == sle.warehouse)
+			.where(warehouse_table.warehouse_type == warehouse_type)
 		)
 
-	return conditions
+	return query
 
 
-def get_stock_ledger_entries(filters, items):
-	item_conditions_sql = ""
-	if items:
-		item_conditions_sql = " and sle.item_code in ({})".format(
-			", ".join(frappe.db.escape(i, percent=False) for i in items)
+def get_stock_ledger_entries(filters: StockBalanceFilter, items: List[str]) -> List[SLEntry]:
+	sle = frappe.qb.DocType("Stock Ledger Entry")
+
+	query = (
+		frappe.qb.from_(sle)
+		.select(
+			sle.item_code,
+			sle.warehouse,
+			sle.posting_date,
+			sle.actual_qty,
+			sle.valuation_rate,
+			sle.company,
+			sle.voucher_type,
+			sle.qty_after_transaction,
+			sle.stock_value_difference,
+			sle.item_code.as_("name"),
+			sle.voucher_no,
+			sle.stock_value,
+			sle.batch_no,
 		)
-
-	conditions = get_conditions(filters)
-
-	return frappe.db.sql(
-		"""
-		select
-			sle.item_code, warehouse, sle.posting_date, sle.actual_qty, sle.valuation_rate,
-			sle.company, sle.voucher_type, sle.qty_after_transaction, sle.stock_value_difference,
-			sle.item_code as name, sle.voucher_no, sle.stock_value, sle.batch_no
-		from
-			`tabStock Ledger Entry` sle
-		where sle.docstatus < 2 %s %s
-		and is_cancelled = 0
-		order by sle.posting_date, sle.posting_time, sle.creation, sle.actual_qty"""
-		% (item_conditions_sql, conditions),  # nosec
-		as_dict=1,
+		.where((sle.docstatus < 2) & (sle.is_cancelled == 0))
+		.orderby(CombineDatetime(sle.posting_date, sle.posting_time))
+		.orderby(sle.creation)
+		.orderby(sle.actual_qty)
 	)
 
+	if items:
+		query = query.where(sle.item_code.isin(items))
 
-def get_item_warehouse_map(filters, sle):
+	query = apply_conditions(query, filters)
+	return query.run(as_dict=True)
+
+
+def get_item_warehouse_map(filters: StockBalanceFilter, sle: List[SLEntry]):
 	iwb_map = {}
 	from_date = getdate(filters.get("from_date"))
 	to_date = getdate(filters.get("to_date"))
@@ -332,7 +361,7 @@
 	return iwb_map
 
 
-def filter_items_with_no_transactions(iwb_map, float_precision):
+def filter_items_with_no_transactions(iwb_map, float_precision: float):
 	for (company, item, warehouse) in sorted(iwb_map):
 		qty_dict = iwb_map[(company, item, warehouse)]
 
@@ -349,26 +378,22 @@
 	return iwb_map
 
 
-def get_items(filters):
+def get_items(filters: StockBalanceFilter) -> List[str]:
 	"Get items based on item code, item group or brand."
-	conditions = []
-	if filters.get("item_code"):
-		conditions.append("item.name=%(item_code)s")
+	if item_code := filters.get("item_code"):
+		return [item_code]
 	else:
-		if filters.get("item_group"):
-			conditions.append(get_item_group_condition(filters.get("item_group")))
-		if filters.get("brand"):  # used in stock analytics report
-			conditions.append("item.brand=%(brand)s")
+		item_filters = {}
+		if item_group := filters.get("item_group"):
+			children = get_descendants_of("Item Group", item_group, ignore_permissions=True)
+			item_filters["item_group"] = ("in", children + [item_group])
+		if brand := filters.get("brand"):
+			item_filters["brand"] = brand
 
-	items = []
-	if conditions:
-		items = frappe.db.sql_list(
-			"""select name from `tabItem` item where {}""".format(" and ".join(conditions)), filters
-		)
-	return items
+		return frappe.get_all("Item", filters=item_filters, pluck="name", order_by=None)
 
 
-def get_item_details(items, sle, filters):
+def get_item_details(items: List[str], sle: List[SLEntry], filters: StockBalanceFilter):
 	item_details = {}
 	if not items:
 		items = list(set(d.item_code for d in sle))
@@ -376,33 +401,35 @@
 	if not items:
 		return item_details
 
-	cf_field = cf_join = ""
-	if filters.get("include_uom"):
-		cf_field = ", ucd.conversion_factor"
-		cf_join = (
-			"left join `tabUOM Conversion Detail` ucd on ucd.parent=item.name and ucd.uom=%s"
-			% frappe.db.escape(filters.get("include_uom"))
-		)
+	item_table = frappe.qb.DocType("Item")
 
-	res = frappe.db.sql(
-		"""
-		select
-			item.name, item.item_name, item.description, item.item_group, item.brand, item.stock_uom %s
-		from
-			`tabItem` item
-			%s
-		where
-			item.name in (%s)
-	"""
-		% (cf_field, cf_join, ",".join(["%s"] * len(items))),
-		items,
-		as_dict=1,
+	query = (
+		frappe.qb.from_(item_table)
+		.select(
+			item_table.name,
+			item_table.item_name,
+			item_table.description,
+			item_table.item_group,
+			item_table.brand,
+			item_table.stock_uom,
+		)
+		.where(item_table.name.isin(items))
 	)
 
-	for item in res:
-		item_details.setdefault(item.name, item)
+	if uom := filters.get("include_uom"):
+		uom_conv_detail = frappe.qb.DocType("UOM Conversion Detail")
+		query = (
+			query.left_join(uom_conv_detail)
+			.on((uom_conv_detail.parent == item_table.name) & (uom_conv_detail.uom == uom))
+			.select(uom_conv_detail.conversion_factor)
+		)
 
-	if filters.get("show_variant_attributes", 0) == 1:
+	result = query.run(as_dict=1)
+
+	for item_table in result:
+		item_details.setdefault(item_table.name, item_table)
+
+	if filters.get("show_variant_attributes"):
 		variant_values = get_variant_values_for(list(item_details))
 		item_details = {k: v.update(variant_values.get(k, {})) for k, v in item_details.items()}
 
@@ -413,36 +440,33 @@
 	item_reorder_details = frappe._dict()
 
 	if items:
-		item_reorder_details = frappe.db.sql(
-			"""
-			select parent, warehouse, warehouse_reorder_qty, warehouse_reorder_level
-			from `tabItem Reorder`
-			where parent in ({0})
-		""".format(
-				", ".join(frappe.db.escape(i, percent=False) for i in items)
-			),
-			as_dict=1,
+		item_reorder_details = frappe.get_all(
+			"Item Reorder",
+			["parent", "warehouse", "warehouse_reorder_qty", "warehouse_reorder_level"],
+			filters={"parent": ("in", items)},
 		)
 
 	return dict((d.parent + d.warehouse, d) for d in item_reorder_details)
 
 
-def get_variants_attributes():
+def get_variants_attributes() -> List[str]:
 	"""Return all item variant attributes."""
-	return [i.name for i in frappe.get_all("Item Attribute")]
+	return frappe.get_all("Item Attribute", pluck="name")
 
 
 def get_variant_values_for(items):
 	"""Returns variant values for items."""
 	attribute_map = {}
-	for attr in frappe.db.sql(
-		"""select parent, attribute, attribute_value
-		from `tabItem Variant Attribute` where parent in (%s)
-		"""
-		% ", ".join(["%s"] * len(items)),
-		tuple(items),
-		as_dict=1,
-	):
+
+	attribute_info = frappe.get_all(
+		"Item Variant Attribute",
+		["parent", "attribute", "attribute_value"],
+		{
+			"parent": ("in", items),
+		},
+	)
+
+	for attr in attribute_info:
 		attribute_map.setdefault(attr["parent"], {})
 		attribute_map[attr["parent"]].update({attr["attribute"]: attr["attribute_value"]})
 
diff --git a/erpnext/stock/report/stock_balance/test_stock_balance.py b/erpnext/stock/report/stock_balance/test_stock_balance.py
new file mode 100644
index 0000000..e963de2
--- /dev/null
+++ b/erpnext/stock/report/stock_balance/test_stock_balance.py
@@ -0,0 +1,174 @@
+from typing import Any, Dict
+
+import frappe
+from frappe import _dict
+from frappe.tests.utils import FrappeTestCase
+from frappe.utils import today
+
+from erpnext.stock.doctype.item.test_item import make_item
+from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
+from erpnext.stock.report.stock_balance.stock_balance import execute
+
+
+def stock_balance(filters):
+	"""Get rows from stock balance report"""
+	return [_dict(row) for row in execute(filters)[1]]
+
+
+class TestStockBalance(FrappeTestCase):
+	# ----------- utils
+
+	def setUp(self):
+		self.item = make_item()
+		self.filters = _dict(
+			{
+				"company": "_Test Company",
+				"item_code": self.item.name,
+				"from_date": "2020-01-01",
+				"to_date": str(today()),
+			}
+		)
+
+	def tearDown(self):
+		frappe.db.rollback()
+
+	def assertPartialDictEq(self, expected: Dict[str, Any], actual: Dict[str, Any]):
+		for k, v in expected.items():
+			self.assertEqual(v, actual[k], msg=f"{expected=}\n{actual=}")
+
+	def generate_stock_ledger(self, item_code: str, movements):
+
+		for movement in map(_dict, movements):
+			if "to_warehouse" not in movement:
+				movement.to_warehouse = "_Test Warehouse - _TC"
+			make_stock_entry(item_code=item_code, **movement)
+
+	def assertInvariants(self, rows):
+		last_balance = frappe.db.sql(
+			"""
+			WITH last_balances AS (
+				SELECT item_code, warehouse,
+					stock_value, qty_after_transaction,
+					ROW_NUMBER() OVER (PARTITION BY item_code, warehouse
+						ORDER BY timestamp(posting_date, posting_time) desc, creation desc)
+						AS rn
+					FROM `tabStock Ledger Entry`
+					where is_cancelled=0
+				)
+				SELECT * FROM last_balances WHERE rn = 1""",
+			as_dict=True,
+		)
+
+		item_wh_stock = _dict()
+
+		for line in last_balance:
+			item_wh_stock.setdefault((line.item_code, line.warehouse), line)
+
+		for row in rows:
+			msg = f"Invariants not met for {rows=}"
+			# qty invariant
+			self.assertAlmostEqual(row.bal_qty, row.opening_qty + row.in_qty - row.out_qty, msg)
+
+			# value invariant
+			self.assertAlmostEqual(row.bal_val, row.opening_val + row.in_val - row.out_val, msg)
+
+			# check against SLE
+			last_sle = item_wh_stock[(row.item_code, row.warehouse)]
+			self.assertAlmostEqual(row.bal_qty, last_sle.qty_after_transaction, 3)
+			self.assertAlmostEqual(row.bal_val, last_sle.stock_value, 3)
+
+			# valuation rate
+			if not row.bal_qty:
+				continue
+			self.assertAlmostEqual(row.val_rate, row.bal_val / row.bal_qty, 3, msg)
+
+	# ----------- tests
+
+	def test_basic_stock_balance(self):
+		"""Check very basic functionality and item info"""
+		rows = stock_balance(self.filters)
+		self.assertEqual(rows, [])
+
+		self.generate_stock_ledger(self.item.name, [_dict(qty=5, rate=10)])
+
+		# check item info
+		rows = stock_balance(self.filters)
+		self.assertPartialDictEq(
+			{
+				"item_code": self.item.name,
+				"item_name": self.item.item_name,
+				"item_group": self.item.item_group,
+				"stock_uom": self.item.stock_uom,
+				"in_qty": 5,
+				"in_val": 50,
+				"val_rate": 10,
+			},
+			rows[0],
+		)
+		self.assertInvariants(rows)
+
+	def test_opening_balance(self):
+		self.generate_stock_ledger(
+			self.item.name,
+			[
+				_dict(qty=1, rate=1, posting_date="2021-01-01"),
+				_dict(qty=2, rate=2, posting_date="2021-01-02"),
+				_dict(qty=3, rate=3, posting_date="2021-01-03"),
+			],
+		)
+		rows = stock_balance(self.filters)
+		self.assertInvariants(rows)
+
+		rows = stock_balance(self.filters.update({"from_date": "2021-01-02"}))
+		self.assertInvariants(rows)
+		self.assertPartialDictEq({"opening_qty": 1, "in_qty": 5}, rows[0])
+
+		rows = stock_balance(self.filters.update({"from_date": "2022-01-01"}))
+		self.assertInvariants(rows)
+		self.assertPartialDictEq({"opening_qty": 6, "in_qty": 0}, rows[0])
+
+	def test_uom_converted_info(self):
+
+		self.item.append("uoms", {"conversion_factor": 5, "uom": "Box"})
+		self.item.save()
+
+		self.generate_stock_ledger(self.item.name, [_dict(qty=5, rate=10)])
+
+		rows = stock_balance(self.filters.update({"include_uom": "Box"}))
+		self.assertEqual(rows[0].bal_qty_alt, 1)
+		self.assertInvariants(rows)
+
+	def test_item_group(self):
+		self.filters.pop("item_code", None)
+		rows = stock_balance(self.filters.update({"item_group": self.item.item_group}))
+		self.assertTrue(all(r.item_group == self.item.item_group for r in rows))
+
+	def test_child_warehouse_balances(self):
+		# This is default
+		self.generate_stock_ledger(self.item.name, [_dict(qty=5, rate=10, to_warehouse="Stores - _TC")])
+
+		self.filters.pop("item_code", None)
+		rows = stock_balance(self.filters.update({"warehouse": "All Warehouses - _TC"}))
+
+		self.assertTrue(
+			any(r.item_code == self.item.name and r.warehouse == "Stores - _TC" for r in rows),
+			msg=f"Expected child warehouse balances \n{rows}",
+		)
+
+	def test_show_item_attr(self):
+		from erpnext.controllers.item_variant import create_variant
+
+		self.item.has_variants = True
+		self.item.append("attributes", {"attribute": "Test Size"})
+		self.item.save()
+
+		attributes = {"Test Size": "Large"}
+		variant = create_variant(self.item.name, attributes)
+		variant.save()
+
+		self.generate_stock_ledger(variant.name, [_dict(qty=5, rate=10)])
+		rows = stock_balance(
+			self.filters.update({"show_variant_attributes": 1, "item_code": variant.name})
+		)
+		self.assertPartialDictEq(attributes, rows[0])
+		self.assertInvariants(rows)
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index b7fd65b..a781479 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -3,7 +3,7 @@
 
 import copy
 import json
-from typing import Optional
+from typing import Optional, Set, Tuple
 
 import frappe
 from frappe import _
@@ -214,6 +214,7 @@
 		args = get_items_to_be_repost(voucher_type, voucher_no, doc)
 
 	distinct_item_warehouses = get_distinct_item_warehouse(args, doc)
+	affected_transactions = get_affected_transactions(doc)
 
 	i = get_current_index(doc) or 0
 	while i < len(args):
@@ -231,6 +232,7 @@
 			allow_negative_stock=allow_negative_stock,
 			via_landed_cost_voucher=via_landed_cost_voucher,
 		)
+		affected_transactions.update(obj.affected_transactions)
 
 		distinct_item_warehouses[
 			(args[i].get("item_code"), args[i].get("warehouse"))
@@ -250,10 +252,14 @@
 		i += 1
 
 		if doc and i % 2 == 0:
-			update_args_in_repost_item_valuation(doc, i, args, distinct_item_warehouses)
+			update_args_in_repost_item_valuation(
+				doc, i, args, distinct_item_warehouses, affected_transactions
+			)
 
 	if doc and args:
-		update_args_in_repost_item_valuation(doc, i, args, distinct_item_warehouses)
+		update_args_in_repost_item_valuation(
+			doc, i, args, distinct_item_warehouses, affected_transactions
+		)
 
 
 def validate_item_warehouse(args):
@@ -263,20 +269,22 @@
 			frappe.throw(_(validation_msg))
 
 
-def update_args_in_repost_item_valuation(doc, index, args, distinct_item_warehouses):
-	frappe.db.set_value(
-		doc.doctype,
-		doc.name,
+def update_args_in_repost_item_valuation(
+	doc, index, args, distinct_item_warehouses, affected_transactions
+):
+	doc.db_set(
 		{
 			"items_to_be_repost": json.dumps(args, default=str),
 			"distinct_item_and_warehouse": json.dumps(
 				{str(k): v for k, v in distinct_item_warehouses.items()}, default=str
 			),
 			"current_index": index,
-		},
+			"affected_transactions": frappe.as_json(affected_transactions),
+		}
 	)
 
-	frappe.db.commit()
+	if not frappe.flags.in_test:
+		frappe.db.commit()
 
 	frappe.publish_realtime(
 		"item_reposting_progress",
@@ -313,6 +321,14 @@
 	return distinct_item_warehouses
 
 
+def get_affected_transactions(doc) -> Set[Tuple[str, str]]:
+	if not doc.affected_transactions:
+		return set()
+
+	transactions = frappe.parse_json(doc.affected_transactions)
+	return {tuple(transaction) for transaction in transactions}
+
+
 def get_current_index(doc=None):
 	if doc and doc.current_index:
 		return doc.current_index
@@ -360,6 +376,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.data = frappe._dict()
 		self.initialize_previous_data(self.args)
@@ -518,6 +535,7 @@
 
 		# previous sle data for this warehouse
 		self.wh_data = self.data[sle.warehouse]
+		self.affected_transactions.add((sle.voucher_type, sle.voucher_no))
 
 		if (sle.serial_no and not self.via_landed_cost_voucher) or not cint(self.allow_negative_stock):
 			# validate negative stock for serialized items, fifo valuation
diff --git a/erpnext/telephony/doctype/call_log/call_log.json b/erpnext/telephony/doctype/call_log/call_log.json
index 1d6c39e..a41ddb1 100644
--- a/erpnext/telephony/doctype/call_log/call_log.json
+++ b/erpnext/telephony/doctype/call_log/call_log.json
@@ -1,7 +1,7 @@
 {
  "actions": [],
  "autoname": "field:id",
- "creation": "2019-06-05 12:07:02.634534",
+ "creation": "2022-02-21 11:54:58.414784",
  "doctype": "DocType",
  "engine": "InnoDB",
  "field_order": [
@@ -9,6 +9,8 @@
   "id",
   "from",
   "to",
+  "call_received_by",
+  "employee_user_id",
   "medium",
   "start_time",
   "end_time",
@@ -20,6 +22,7 @@
   "recording_url",
   "recording_html",
   "section_break_11",
+  "type_of_call",
   "summary",
   "section_break_19",
   "links"
@@ -103,7 +106,8 @@
   },
   {
    "fieldname": "summary",
-   "fieldtype": "Small Text"
+   "fieldtype": "Small Text",
+   "label": "Summary"
   },
   {
    "fieldname": "section_break_11",
@@ -134,15 +138,37 @@
    "fieldname": "call_details_section",
    "fieldtype": "Section Break",
    "label": "Call Details"
+  },
+  {
+   "fieldname": "employee_user_id",
+   "fieldtype": "Link",
+   "hidden": 1,
+   "label": "Employee User Id",
+   "options": "User"
+  },
+  {
+   "fieldname": "type_of_call",
+   "fieldtype": "Link",
+   "label": "Type Of Call",
+   "options": "Telephony Call Type"
+  },
+  {
+   "depends_on": "to",
+   "fieldname": "call_received_by",
+   "fieldtype": "Link",
+   "label": "Call Received By",
+   "options": "Employee",
+   "read_only": 1
   }
  ],
  "in_create": 1,
  "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2021-02-08 14:23:28.744844",
+ "modified": "2022-04-14 02:59:22.503202",
  "modified_by": "Administrator",
  "module": "Telephony",
  "name": "Call Log",
+ "naming_rule": "By fieldname",
  "owner": "Administrator",
  "permissions": [
   {
@@ -164,6 +190,7 @@
  ],
  "sort_field": "creation",
  "sort_order": "DESC",
+ "states": [],
  "title_field": "from",
  "track_changes": 1,
  "track_views": 1
diff --git a/erpnext/telephony/doctype/call_log/call_log.py b/erpnext/telephony/doctype/call_log/call_log.py
index 1c88883..7725e71 100644
--- a/erpnext/telephony/doctype/call_log/call_log.py
+++ b/erpnext/telephony/doctype/call_log/call_log.py
@@ -32,6 +32,10 @@
 		if lead:
 			self.add_link(link_type="Lead", link_name=lead)
 
+		# Add Employee Name
+		if self.is_incoming_call():
+			self.update_received_by()
+
 	def after_insert(self):
 		self.trigger_call_popup()
 
@@ -49,6 +53,9 @@
 		if not doc_before_save:
 			return
 
+		if self.is_incoming_call() and self.has_value_changed("to"):
+			self.update_received_by()
+
 		if _is_call_missed(doc_before_save, self):
 			frappe.publish_realtime("call_{id}_missed".format(id=self.id), self)
 			self.trigger_call_popup()
@@ -65,7 +72,8 @@
 	def trigger_call_popup(self):
 		if self.is_incoming_call():
 			scheduled_employees = get_scheduled_employees_for_popup(self.medium)
-			employee_emails = get_employees_with_number(self.to)
+			employees = get_employees_with_number(self.to)
+			employee_emails = [employee.get("user_id") for employee in employees]
 
 			# check if employees with matched number are scheduled to receive popup
 			emails = set(scheduled_employees).intersection(employee_emails)
@@ -85,10 +93,17 @@
 			for email in emails:
 				frappe.publish_realtime("show_call_popup", self, user=email)
 
+	def update_received_by(self):
+		if employees := get_employees_with_number(self.get("to")):
+			self.call_received_by = employees[0].get("name")
+			self.employee_user_id = employees[0].get("user_id")
+
 
 @frappe.whitelist()
-def add_call_summary(call_log, summary):
+def add_call_summary_and_call_type(call_log, summary, call_type):
 	doc = frappe.get_doc("Call Log", call_log)
+	doc.type_of_call = call_type
+	doc.save()
 	doc.add_comment("Comment", frappe.bold(_("Call Summary")) + "<br><br>" + summary)
 
 
@@ -97,20 +112,19 @@
 	if not number:
 		return []
 
-	employee_emails = frappe.cache().hget("employees_with_number", number)
-	if employee_emails:
-		return employee_emails
+	employee_doc_name_and_emails = frappe.cache().hget("employees_with_number", number)
+	if employee_doc_name_and_emails:
+		return employee_doc_name_and_emails
 
-	employees = frappe.get_all(
+	employee_doc_name_and_emails = frappe.get_all(
 		"Employee",
-		filters={"cell_number": ["like", "%{}%".format(number)], "user_id": ["!=", ""]},
-		fields=["user_id"],
+		filters={"cell_number": ["like", f"%{number}%"], "user_id": ["!=", ""]},
+		fields=["name", "user_id"],
 	)
 
-	employee_emails = [employee.user_id for employee in employees]
-	frappe.cache().hset("employees_with_number", number, employee_emails)
+	frappe.cache().hset("employees_with_number", number, employee_doc_name_and_emails)
 
-	return employee_emails
+	return employee_doc_name_and_emails
 
 
 def link_existing_conversations(doc, state):
diff --git a/erpnext/hr/doctype/employee_transfer_property/__init__.py b/erpnext/telephony/doctype/telephony_call_type/__init__.py
similarity index 100%
copy from erpnext/hr/doctype/employee_transfer_property/__init__.py
copy to erpnext/telephony/doctype/telephony_call_type/__init__.py
diff --git a/erpnext/telephony/doctype/telephony_call_type/telephony_call_type.js b/erpnext/telephony/doctype/telephony_call_type/telephony_call_type.js
new file mode 100644
index 0000000..efba2b8
--- /dev/null
+++ b/erpnext/telephony/doctype/telephony_call_type/telephony_call_type.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Telephony Call Type', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/telephony/doctype/telephony_call_type/telephony_call_type.json b/erpnext/telephony/doctype/telephony_call_type/telephony_call_type.json
new file mode 100644
index 0000000..603709e
--- /dev/null
+++ b/erpnext/telephony/doctype/telephony_call_type/telephony_call_type.json
@@ -0,0 +1,58 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "field:call_type",
+ "creation": "2022-02-25 16:13:37.321312",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "call_type",
+  "amended_from"
+ ],
+ "fields": [
+  {
+   "fieldname": "call_type",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Call Type",
+   "reqd": 1,
+   "unique": 1
+  },
+  {
+   "fieldname": "amended_from",
+   "fieldtype": "Link",
+   "label": "Amended From",
+   "no_copy": 1,
+   "options": "Telephony Call Type",
+   "print_hide": 1,
+   "read_only": 1
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2022-02-25 16:14:07.087461",
+ "modified_by": "Administrator",
+ "module": "Telephony",
+ "name": "Telephony Call Type",
+ "naming_rule": "By fieldname",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/erpnext/telephony/doctype/telephony_call_type/telephony_call_type.py b/erpnext/telephony/doctype/telephony_call_type/telephony_call_type.py
new file mode 100644
index 0000000..944ffef
--- /dev/null
+++ b/erpnext/telephony/doctype/telephony_call_type/telephony_call_type.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+
+class TelephonyCallType(Document):
+	pass
diff --git a/erpnext/telephony/doctype/telephony_call_type/test_telephony_call_type.py b/erpnext/telephony/doctype/telephony_call_type/test_telephony_call_type.py
new file mode 100644
index 0000000..b3c19c3
--- /dev/null
+++ b/erpnext/telephony/doctype/telephony_call_type/test_telephony_call_type.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+
+# import frappe
+import unittest
+
+
+class TestTelephonyCallType(unittest.TestCase):
+	pass
diff --git a/erpnext/tests/exotel_test_data.py b/erpnext/tests/exotel_test_data.py
new file mode 100644
index 0000000..3ad2575
--- /dev/null
+++ b/erpnext/tests/exotel_test_data.py
@@ -0,0 +1,122 @@
+import frappe
+
+call_initiation_data = frappe._dict(
+	{
+		"CallSid": "23c162077629863c1a2d7f29263a162m",
+		"CallFrom": "09999999991",
+		"CallTo": "09999999980",
+		"Direction": "incoming",
+		"Created": "Wed, 23 Feb 2022 12:31:59",
+		"From": "09999999991",
+		"To": "09999999988",
+		"CurrentTime": "2022-02-23 12:32:02",
+		"DialWhomNumber": "09999999999",
+		"Status": "busy",
+		"EventType": "Dial",
+		"AgentEmail": "test_employee_exotel@company.com",
+	}
+)
+
+call_end_data = frappe._dict(
+	{
+		"CallSid": "23c162077629863c1a2d7f29263a162m",
+		"CallFrom": "09999999991",
+		"CallTo": "09999999980",
+		"Direction": "incoming",
+		"ForwardedFrom": "null",
+		"Created": "Wed, 23 Feb 2022 12:31:59",
+		"DialCallDuration": "17",
+		"RecordingUrl": "https://s3-ap-southeast-1.amazonaws.com/random.mp3",
+		"StartTime": "2022-02-23 12:31:58",
+		"EndTime": "1970-01-01 05:30:00",
+		"DialCallStatus": "completed",
+		"CallType": "completed",
+		"DialWhomNumber": "09999999999",
+		"ProcessStatus": "null",
+		"flow_id": "228040",
+		"tenant_id": "67291",
+		"From": "09999999991",
+		"To": "09999999988",
+		"RecordingAvailableBy": "Wed, 23 Feb 2022 12:37:25",
+		"CurrentTime": "2022-02-23 12:32:25",
+		"OutgoingPhoneNumber": "09999999988",
+		"Legs": [
+			{
+				"Number": "09999999999",
+				"Type": "single",
+				"OnCallDuration": "10",
+				"CallerId": "09999999980",
+				"CauseCode": "NORMAL_CLEARING",
+				"Cause": "16",
+			}
+		],
+	}
+)
+
+call_disconnected_data = frappe._dict(
+	{
+		"CallSid": "d96421addce69e24bdc7ce5880d1162l",
+		"CallFrom": "09999999991",
+		"CallTo": "09999999980",
+		"Direction": "incoming",
+		"ForwardedFrom": "null",
+		"Created": "Mon, 21 Feb 2022 15:58:12",
+		"DialCallDuration": "0",
+		"StartTime": "2022-02-21 15:58:12",
+		"EndTime": "1970-01-01 05:30:00",
+		"DialCallStatus": "canceled",
+		"CallType": "client-hangup",
+		"DialWhomNumber": "09999999999",
+		"ProcessStatus": "null",
+		"flow_id": "228040",
+		"tenant_id": "67291",
+		"From": "09999999991",
+		"To": "09999999988",
+		"CurrentTime": "2022-02-21 15:58:47",
+		"OutgoingPhoneNumber": "09999999988",
+		"Legs": [
+			{
+				"Number": "09999999999",
+				"Type": "single",
+				"OnCallDuration": "0",
+				"CallerId": "09999999980",
+				"CauseCode": "RING_TIMEOUT",
+				"Cause": "1003",
+			}
+		],
+	}
+)
+
+call_not_answered_data = frappe._dict(
+	{
+		"CallSid": "fdb67a2b4b2d057b610a52ef43f81622",
+		"CallFrom": "09999999991",
+		"CallTo": "09999999980",
+		"Direction": "incoming",
+		"ForwardedFrom": "null",
+		"Created": "Mon, 21 Feb 2022 15:47:02",
+		"DialCallDuration": "0",
+		"StartTime": "2022-02-21 15:47:02",
+		"EndTime": "1970-01-01 05:30:00",
+		"DialCallStatus": "no-answer",
+		"CallType": "incomplete",
+		"DialWhomNumber": "09999999999",
+		"ProcessStatus": "null",
+		"flow_id": "228040",
+		"tenant_id": "67291",
+		"From": "09999999991",
+		"To": "09999999988",
+		"CurrentTime": "2022-02-21 15:47:40",
+		"OutgoingPhoneNumber": "09999999988",
+		"Legs": [
+			{
+				"Number": "09999999999",
+				"Type": "single",
+				"OnCallDuration": "0",
+				"CallerId": "09999999980",
+				"CauseCode": "RING_TIMEOUT",
+				"Cause": "1003",
+			}
+		],
+	}
+)
diff --git a/erpnext/tests/test_exotel.py b/erpnext/tests/test_exotel.py
new file mode 100644
index 0000000..76bbb3e
--- /dev/null
+++ b/erpnext/tests/test_exotel.py
@@ -0,0 +1,69 @@
+import frappe
+from frappe.contacts.doctype.contact.test_contact import create_contact
+from frappe.tests.test_api import FrappeAPITestCase
+
+from erpnext.hr.doctype.employee.test_employee import make_employee
+
+
+class TestExotel(FrappeAPITestCase):
+	@classmethod
+	def setUpClass(cls):
+		cls.CURRENT_DB_CONNECTION = frappe.db
+		cls.test_employee_name = make_employee(
+			user="test_employee_exotel@company.com", cell_number="9999999999"
+		)
+		frappe.db.set_value("Exotel Settings", "Exotel Settings", "enabled", 1)
+		phones = [{"phone": "+91 9999999991", "is_primary_phone": 0, "is_primary_mobile_no": 1}]
+		create_contact(name="Test Contact", salutation="Mr", phones=phones)
+		frappe.db.commit()
+
+	def test_for_successful_call(self):
+		from .exotel_test_data import call_end_data, call_initiation_data
+
+		api_method = "handle_incoming_call"
+		end_call_api_method = "handle_end_call"
+
+		self.emulate_api_call_from_exotel(api_method, call_initiation_data)
+		self.emulate_api_call_from_exotel(end_call_api_method, call_end_data)
+		call_log = frappe.get_doc("Call Log", call_initiation_data.CallSid)
+
+		self.assertEqual(call_log.get("from"), call_initiation_data.CallFrom)
+		self.assertEqual(call_log.get("to"), call_initiation_data.DialWhomNumber)
+		self.assertEqual(call_log.get("call_received_by"), self.test_employee_name)
+		self.assertEqual(call_log.get("status"), "Completed")
+
+	def test_for_disconnected_call(self):
+		from .exotel_test_data import call_disconnected_data
+
+		api_method = "handle_missed_call"
+		self.emulate_api_call_from_exotel(api_method, call_disconnected_data)
+		call_log = frappe.get_doc("Call Log", call_disconnected_data.CallSid)
+		self.assertEqual(call_log.get("from"), call_disconnected_data.CallFrom)
+		self.assertEqual(call_log.get("to"), call_disconnected_data.DialWhomNumber)
+		self.assertEqual(call_log.get("call_received_by"), self.test_employee_name)
+		self.assertEqual(call_log.get("status"), "Canceled")
+
+	def test_for_call_not_answered(self):
+		from .exotel_test_data import call_not_answered_data
+
+		api_method = "handle_missed_call"
+		self.emulate_api_call_from_exotel(api_method, call_not_answered_data)
+		call_log = frappe.get_doc("Call Log", call_not_answered_data.CallSid)
+		self.assertEqual(call_log.get("from"), call_not_answered_data.CallFrom)
+		self.assertEqual(call_log.get("to"), call_not_answered_data.DialWhomNumber)
+		self.assertEqual(call_log.get("call_received_by"), self.test_employee_name)
+		self.assertEqual(call_log.get("status"), "No Answer")
+
+	def emulate_api_call_from_exotel(self, api_method, data):
+		self.post(
+			f"/api/method/erpnext.erpnext_integrations.exotel_integration.{api_method}",
+			data=frappe.as_json(data),
+			content_type="application/json",
+			as_tuple=True,
+		)
+		# restart db connection to get latest data
+		frappe.connect()
+
+	@classmethod
+	def tearDownClass(cls):
+		frappe.db = cls.CURRENT_DB_CONNECTION
diff --git a/erpnext/translations/de.csv b/erpnext/translations/de.csv
index c8d6c06..98666bf 100644
--- a/erpnext/translations/de.csv
+++ b/erpnext/translations/de.csv
@@ -9224,7 +9224,7 @@
 Unmarked Days,Nicht markierte Tage,
 Jan,Jan.,
 Feb,Feb.,
-Mar,Beschädigen,
+Mar,Mrz.,
 Apr,Apr.,
 Aug,Aug.,
 Sep,Sep.,
diff --git a/erpnext/translations/fr.csv b/erpnext/translations/fr.csv
index 3295136..8518156 100644
--- a/erpnext/translations/fr.csv
+++ b/erpnext/translations/fr.csv
@@ -271,7 +271,7 @@
 Assessment Reports,Rapports d'évaluation,
 Assessment Result,Résultat de l'Évaluation,
 Assessment Result record {0} already exists.,Le Résultat d'Évaluation {0} existe déjà.,
-Asset,Atout,
+Asset,Actif - Immo.,
 Asset Category,Catégorie d'Actif,
 Asset Category is mandatory for Fixed Asset item,Catégorie d'Actif est obligatoire pour l'article Immobilisé,
 Asset Maintenance,Maintenance des actifs,
@@ -3037,6 +3037,7 @@
 To Date should be within the Fiscal Year. Assuming To Date = {0},La Date Finale doit être dans l'exercice. En supposant Date Finale = {0},
 To Datetime,À la Date,
 To Deliver,À Livrer,
+{}  To Deliver,{} à livrer
 To Deliver and Bill,À Livrer et Facturer,
 To Fiscal Year,À l'année fiscale,
 To GSTIN,GSTIN (Destination),
@@ -9871,3 +9872,4 @@
 Convert Item Description to Clean HTML in Transactions,Convertir les descriptions d'articles en HTML valide lors des transactions
 Have Default Naming Series for Batch ID?,Nom de série par défaut pour les Lots ou Séries
 "The percentage you are allowed to transfer more against the quantity ordered. For example, if you have ordered 100 units, and your Allowance is 10%, then you are allowed transfer 110 units","Le pourcentage de quantité que vous pourrez réceptionner en plus de la quantité commandée. Par exemple, vous avez commandé 100 unités, votre pourcentage de dépassement est de 10%, vous pourrez réceptionner 110 unités"
+Unit Of Measure (UOM),Unité de mesure (UDM),
diff --git a/erpnext/translations/ru.csv b/erpnext/translations/ru.csv
index 7fcb7b0..6703da6 100644
--- a/erpnext/translations/ru.csv
+++ b/erpnext/translations/ru.csv
@@ -2,7 +2,7 @@
 """Customer Provided Item"" cannot have Valuation Rate",«Предоставленный клиентом товар» не может иметь оценку,
 """Is Fixed Asset"" cannot be unchecked, as Asset record exists against the item","Нельзя отменить выбор ""Является основным средством"", поскольку по данному пункту имеется запись по активам",
 'Based On' and 'Group By' can not be same,"""На основании"" и ""Группировка по"" не могут быть одинаковыми",
-'Days Since Last Order' must be greater than or equal to zero,"""Дней с последнего Заказа"" должно быть больше или равно 0",
+'Days Since Last Order' must be greater than or equal to zero,"""Дней с момента последнего заказа"" должно быть больше или равно 0",
 'Entries' cannot be empty,"""Записи"" не могут быть пустыми",
 'From Date' is required,"Поле ""С даты"" является обязательным для заполнения",
 'From Date' must be after 'To Date',"Поле ""С даты"" должно быть после ""До даты""",
@@ -70,20 +70,20 @@
 Account {0}: You can not assign itself as parent account,Счёт {0}: Вы не можете  назначить самого себя родительским счётом,
 Account: {0} can only be updated via Stock Transactions,Счет: {0} можно обновить только через  перемещение по складу,
 Account: {0} with currency: {1} can not be selected,Счет: {0} с валютой: {1} не может быть выбран,
-Accountant,бухгалтер,
+Accountant,Бухгалтер,
 Accounting,Бухгалтерия,
 Accounting Entry for Asset,Учетная запись для активов,
 Accounting Entry for Stock,Бухгалтерская Проводка по Запасам,
 Accounting Entry for {0}: {1} can only be made in currency: {2},Бухгалтерская Проводка для {0}: {1} может быть сделана только в валюте: {2},
-Accounting Ledger,Главная книга,
+Accounting Ledger,Бухгалтерская книга,
 Accounting journal entries.,Журнал бухгалтерских записей.,
 Accounts,Счета,
-Accounts Manager,Диспетчер учетных записей,
+Accounts Manager,Диспетчер счетов,
 Accounts Payable,Счета к оплате,
 Accounts Payable Summary,Сводка кредиторской задолженности,
 Accounts Receivable,Дебиторская задолженность,
 Accounts Receivable Summary,Сводка дебиторской задолженности,
-Accounts User,Пользователь Учетных записей,
+Accounts User,Пользователь Счетов,
 Accounts table cannot be blank.,Таблица учета не может быть пустой.,
 Accrual Journal Entry for salaries from {0} to {1},Запись журнала начислений для зарплат от {0} до {1},
 Accumulated Depreciation,начисленной амортизации,
@@ -115,7 +115,7 @@
 Add Employees,Добавить сотрудников,
 Add Item,Добавить продукт,
 Add Items,Добавить продукты,
-Add Leads,Добавить Обращения,
+Add Leads,Добавить лид,
 Add Multiple Tasks,Добавить несколько задач,
 Add Row,Добавить ряд,
 Add Sales Partners,Добавить партнеров по продажам,
@@ -125,7 +125,7 @@
 Add Time Slots,Добавление временных интервалов,
 Add Timesheets,Добавить табели,
 Add Timeslots,Добавить таймслоты,
-Add Users to Marketplace,Добавить пользователей на рынок,
+Add Users to Marketplace,Добавить пользователей на торговую площадку,
 Add a new address,добавить новый адрес,
 Add cards or custom sections on homepage,Добавить карты или пользовательские разделы на главной странице,
 Add more items or open full form,Добавить ещё продукты или открыть полную форму,
@@ -144,8 +144,8 @@
 Address Type,Тип адреса,
 Administrative Expenses,Административные затраты,
 Administrative Officer,Администратор,
-Administrator,администратор,
-Admission,вход,
+Administrator,Администратор,
+Admission,Допуск,
 Admission and Enrollment,Прием и зачисление,
 Admissions for {0},Поступающим для {0},
 Admit,Допустить,
@@ -154,9 +154,9 @@
 Advance Payments,Авансовые платежи,
 Advance account currency should be same as company currency {0},"Валюта авансового счета должна быть такой же, как и валюта компании {0}",
 Advance amount cannot be greater than {0} {1},"Предварительная сумма не может быть больше, чем {0} {1}",
-Advertising,реклама,
+Advertising,Реклама,
 Aerospace,авиационно-космический,
-Against,против,
+Against,Против,
 Against Account,Со счета,
 Against Journal Entry {0} does not have any unmatched {1} entry,Против Запись в журнале {0} не имеет никакого непревзойденную {1} запись,
 Against Journal Entry {0} is already adjusted against some other voucher,Против Запись в журнале {0} уже настроен против какой-либо другой ваучер,
@@ -200,7 +200,7 @@
 Allocating leaves...,Выделенные разрешения,
 Already record exists for the item {0},Уже существует запись для элемента {0},
 "Already set default in pos profile {0} for user {1}, kindly disabled default","Уже задан по умолчанию в pos-профиле {0} для пользователя {1}, любезно отключен по умолчанию",
-Alternate Item,Альтернативный товар,
+Alternate Item,Альтернативный продукт,
 Alternative item must not be same as item code,"Альтернативный элемент не должен быть таким же, как код позиции",
 Amended From,Измененный С,
 Amount,Сумма,
@@ -232,7 +232,7 @@
 "Applicable if the company is SpA, SApA or SRL","Применимо, если компания SpA, SApA или SRL",
 Applicable if the company is a limited liability company,"Применимо, если компания является обществом с ограниченной ответственностью",
 Applicable if the company is an Individual or a Proprietorship,"Применимо, если компания является частным лицом или собственником",
-Applicant,заявитель,
+Applicant,Заявитель,
 Applicant Type,Тип заявителя,
 Application of Funds (Assets),Применение средств (активов),
 Application period cannot be across two allocation records,Период применения не может быть через две записи распределения,
@@ -295,11 +295,11 @@
 At least one mode of payment is required for POS invoice.,По крайней мере один способ оплаты требуется для POS счета.,
 Atleast one item should be entered with negative quantity in return document,Как минимум один продукт должен быть введен с отрицательным количеством в возвратном документе,
 Atleast one of the Selling or Buying must be selected,По крайней мере один из продажи или покупки должен быть выбран,
-Atleast one warehouse is mandatory,"По крайней мере, один склад является обязательным",
+Atleast one warehouse is mandatory,"По крайней мере, один склад обязателен",
 Attach Logo,Прикрепить логотип,
 Attachment,Вложение,
 Attachments,Приложения,
-Attendance,посещаемость,
+Attendance,Посещаемость,
 Attendance From Date and Attendance To Date is mandatory,"""Начало учетного периода"" и ""Конец учетного периода"" обязательны к заполнению",
 Attendance can not be marked for future dates,Посещаемость не могут быть отмечены для будущих дат,
 Attendance date can not be less than employee's joining date,"Дата Посещаемость не может быть меньше, чем присоединение даты работника",
@@ -310,13 +310,13 @@
 Attendance not submitted for {0} as {1} on leave.,Посещаемость не была отправлена {0} как {1} в отпуске.,
 Attribute table is mandatory,Таблица атрибутов является обязательной,
 Attribute {0} selected multiple times in Attributes Table,Атрибут {0} выбран несколько раз в таблице атрибутов,
-Author,автор,
+Author,Автор,
 Authorized Signatory,Право подписи,
 Auto Material Requests Generated,"Запросы Авто материал, полученный",
 Auto Repeat,Автоматическое повторение,
 Auto repeat document updated,Автоматический повторный документ обновлен,
 Automotive,Автомобилестроение,
-Available,имеется,
+Available,Доступно,
 Available Leaves,Доступные листья,
 Available Qty,Доступное количество,
 Available Selling,Доступные продажи,
@@ -329,7 +329,7 @@
 Avg Daily Outgoing,Среднедневные исходящие,
 Avg. Buying Price List Rate,Avg. Цена прайс-листа,
 Avg. Selling Price List Rate,Avg. Цена прайс-листа,
-Avg. Selling Rate,Средняя Цена Продажи,
+Avg. Selling Rate,Средняя цена продажи,
 BOM,ВМ,
 BOM Browser,Браузер ВМ,
 BOM No,ВМ №,
@@ -369,39 +369,39 @@
 Base URL,Базовый URL,
 Based On,На основании,
 Based On Payment Terms,На основании условий оплаты,
-Basic,основной,
-Batch,партия,
+Basic,Основной,
+Batch,Партия,
 Batch Entries,Пакетные записи,
 Batch ID is mandatory,Идентификатор партии является обязательным,
 Batch Inventory,Пакетная Инвентарь,
 Batch Name,Наименование партии,
-Batch No,№ партии,
+Batch No,Партия №,
 Batch number is mandatory for Item {0},Номер партии является обязательным для продукта {0},
 Batch {0} of Item {1} has expired.,Партия {0} продукта {1} просрочена,
 Batch {0} of Item {1} is disabled.,Пакет {0} элемента {1} отключен.,
-Batch: ,Batch:,
-Batches,Порции,
+Batch: ,Партия: ,
+Batches,Партии,
 Become a Seller,Стать продавцом,
-Beginner,начинающий,
-Bill,Билл,
-Bill Date,Дата оплаты,
-Bill No,Номер накладной,
+Beginner,Начинающий,
+Bill,Счет,
+Bill Date,Дата выставления счета,
+Bill No,Номер счета,
 Bill of Materials,Ведомость материалов,
 Bill of Materials (BOM),Ведомость материалов (ВМ),
 Billable Hours,Оплачиваемые часы,
-Billed,Выдавать счета,
-Billed Amount,Счетов выдано количество,
+Billed,Выставлен счет,
+Billed Amount,Количество выставленных счетов,
 Billing,Выставление счетов,
 Billing Address,Адрес для выставления счетов,
 Billing Address is same as Shipping Address,Платежный адрес совпадает с адресом доставки,
-Billing Amount,Биллинг Сумма,
+Billing Amount,Количество счетов,
 Billing Status,Статус оплаты,
 Billing currency must be equal to either default company's currency or party account currency,Валюта платежа должна быть равна валюте валюты дефолта или валюте счета участника,
-Bills raised by Suppliers.,Платежи Поставщикам,
-Bills raised to Customers.,Платежи Заказчиков,
+Bills raised by Suppliers.,Счета выставленные поставщиками,
+Bills raised to Customers.,Счета выставленные клиентам,
 Biotechnology,Биотехнологии,
 Birthday Reminder,День рождения,
-Black,черный,
+Black,Черный,
 Blanket Orders from Costumers.,Заказы на одеяла от клиентов.,
 Block Invoice,Блок-счет,
 Boms,Boms,
@@ -414,13 +414,13 @@
 Browse BOM,Просмотр спецификации,
 Budget Against,Бюджет против,
 Budget List,Бюджетный список,
-Budget Variance Report,Бюджет Разница Сообщить,
+Budget Variance Report,Отчет об отклонении бюджета,
 Budget cannot be assigned against Group Account {0},Бюджет не может быть назначен на учетную запись группы {0},
 "Budget cannot be assigned against {0}, as it's not an Income or Expense account","Бюджет не может быть назначен на {0}, так как это не доход или расход счета",
-Buildings,здания,
+Buildings,Здания,
 Bundle items at time of sale.,Собирать продукты в момент продажи.,
 Business Development Manager,Менеджер по развитию бизнеса,
-Buy,купить,
+Buy,Купить,
 Buying,Покупки,
 Buying Amount,Сумма покупки,
 Buying Price List,Ценовой список покупок,
@@ -437,7 +437,7 @@
 CWIP Account,CWIP-аккаунт,
 Calculated Bank Statement balance,Расчетный банк себе баланс,
 Calls,Звонки,
-Campaign,кампания,
+Campaign,Кампания,
 Can be approved by {0},Может быть одобрено {0},
 "Can not filter based on Account, if grouped by Account","Не можете фильтровать на основе счета, если сгруппированы по Счет",
 "Can not filter based on Voucher No, if grouped by Voucher","Не можете фильтровать на основе ваучером Нет, если сгруппированы по ваучером",
@@ -451,10 +451,10 @@
 Cancel Material Visits {0} before cancelling this Maintenance Visit,Отменить Материал просмотров {0} до отмены этого обслуживания визит,
 Cancel Subscription,Отменить подписку,
 Cancel the journal entry {0} first,Сначала отменить запись журнала {0},
-Canceled,отменен,
+Canceled,Отменен,
 "Cannot Submit, Employees left to mark attendance","Не могу отправить, Сотрудники оставили отмечать посещаемость",
 Cannot be a fixed asset item as Stock Ledger is created.,"Не может быть элементом фиксированного актива, так как создается складская книга.",
-Cannot cancel because submitted Stock Entry {0} exists,"Нельзя отменить, так как проведена учетная запись по Запасам {0}",
+Cannot cancel because submitted Stock Entry {0} exists,"Нельзя отменить, так как проведен счет по Запасам {0}",
 Cannot cancel transaction for Completed Work Order.,Невозможно отменить транзакцию для выполненного рабочего заказа.,
 Cannot cancel {0} {1} because Serial No {2} does not belong to the warehouse {3},"Невозможно отменить {0} {1}, поскольку Serial No {2} не относится к складу {3}",
 Cannot change Attributes after stock transaction. Make a new Item and transfer stock to the new Item,Невозможно изменить атрибуты после транзакции с акциями. Сделайте новый предмет и переведите запас на новый элемент,
@@ -489,33 +489,33 @@
 Capital Equipments,Капитальные оборудование,
 Capital Stock,Капитал,
 Capital Work in Progress,Капитальная работа в процессе,
-Cart,Тележка,
+Cart,Корзина,
 Cart is Empty,Корзина Пусто,
 Case No(s) already in use. Try from Case No {0},Случай Нет (ы) уже используется. Попробуйте из дела № {0},
 Cash,Наличные,
 Cash Flow Statement,О движении денежных средств,
 Cash Flow from Financing,Поток денежных средств от финансовой,
-Cash Flow from Investing,Поток денежных средств от инвестиционной,
+Cash Flow from Investing,Поток денежных средств от инвестиций,
 Cash Flow from Operations,Поток денежных средств от операций,
-Cash In Hand,Наличность кассы,
+Cash In Hand,Наличные на руках,
 Cash or Bank Account is mandatory for making payment entry,Наличными или банковский счет является обязательным для внесения записи платежей,
 Cashier Closing,Закрытие кассы,
 Casual Leave,Повседневная Оставить,
 Category,Категория,
 Category Name,Название категории,
-Caution,предосторожность,
+Caution,Предосторожность,
 Central Tax,Центральный налог,
-Certification,сертификация,
-Cess,налог,
-Change Amount,Изменение Сумма,
-Change Item Code,Изменить код товара,
+Certification,Сертификация,
+Cess,Налог,
+Change Amount,Изменить сумму,
+Change Item Code,Изменить код продукта,
 Change Release Date,Изменить дату выпуска,
 Change Template Code,Изменить шаблонный код,
 Changing Customer Group for the selected Customer is not allowed.,Изменение группы клиентов для выбранного Клиента запрещено.,
-Chapter,глава,
+Chapter,Глава,
 Chapter information.,Информация о главе.,
 Charge of type 'Actual' in row {0} cannot be included in Item Rate,Начисление типа «Актуальные 'в строке {0} не могут быть включены в пункт Оценить,
-Chargeble,Chargeble,
+Chargeble,Платный,
 Charges are updated in Purchase Receipt against each item,Расходы обновляются в приобретении получение против каждого пункта,
 "Charges will be distributed proportionately based on item qty or amount, as per your selection","Расходы будут распределяться пропорционально на основе количества или суммы продукта, согласно вашему выбору",
 Chart of Cost Centers,План МВЗ,
@@ -536,10 +536,10 @@
 Clay,глина,
 Clear filters,Очистить фильтры,
 Clear values,Очистить значения,
-Clearance Date,Клиренс Дата,
-Clearance Date not mentioned,Клиренс Дата не упоминается,
-Clearance Date updated,Зазор Дата обновления,
-Client,клиент,
+Clearance Date,Дата оформления,
+Clearance Date not mentioned,Дата оформления не упоминается,
+Clearance Date updated,Дата оформления обновлена,
+Client,Клиент,
 Client ID,ID клиента,
 Client Secret,Секрет клиента,
 Clinical Procedure,Клиническая процедура,
@@ -556,7 +556,7 @@
 Closing Balance,Конечное сальдо,
 Code,Код,
 Collapse All,Свернуть все,
-Color,цвет,
+Color,Цвет,
 Colour,Цвет,
 Combined invoice portion must equal 100%,Комбинированная часть счета должна равняться 100%,
 Commercial,Коммерческий сектор,
@@ -576,11 +576,11 @@
 Company {0} does not exist,Компания {0} не существует,
 Compensatory Off,Компенсационные Выкл,
 Compensatory leave request days not in valid holidays,Дни запроса на получение компенсационных отчислений не действительны,
-Complaint,жалоба,
+Complaint,Жалоба,
 Completion Date,Дата завершения,
 Computer,компьютер,
 Condition,Условия,
-Configure,конфигурировать,
+Configure,Конфигурировать,
 Configure {0},Настроить {0},
 Confirmed orders from Customers.,Подтвержденные заказы от клиентов.,
 Connect Amazon with ERPNext,Подключить Amazon к ERPNext,
@@ -589,13 +589,13 @@
 Connected to QuickBooks,Подключено к QuickBooks,
 Connecting to QuickBooks,Подключение к QuickBooks,
 Consultation,Консультация,
-Consultations,консультации,
-Consulting,консалтинг,
-Consumable,потребляемый,
+Consultations,Консультации,
+Consulting,Консалтинг,
+Consumable,Потребляемый,
 Consumed,Потребляемый,
 Consumed Amount,Израсходованное количество,
-Consumed Qty,Потребляемая Кол-во,
-Consumer Products,Потребительские товары,
+Consumed Qty,Потребляемое кол-во,
+Consumer Products,Потребительские продукты,
 Contact,Контакты,
 Contact Details,Контактная информация,
 Contact Number,Контактный номер,
@@ -604,8 +604,8 @@
 Content Masters,Мастера контента,
 Content Type,Тип контента,
 Continue Configuration,Продолжить настройку,
-Contract,контракт,
-Contract End Date must be greater than Date of Joining,"Конец контракта Дата должна быть больше, чем дата вступления",
+Contract,Договор,
+Contract End Date must be greater than Date of Joining,"Дата окончания договора должна быть позже, чем дата его заключения",
 Contribution %,Вклад%,
 Contribution Amount,Вклад Сумма,
 Conversion factor for default Unit of Measure must be 1 in row {0},Коэффициент пересчета для дефолтного Единица измерения должна быть 1 в строке {0},
@@ -623,7 +623,7 @@
 Cost Updated,Стоимость Обновлено,
 Cost as on,"Стоимость, как на",
 Cost of Delivered Items,Затраты по поставленным продуктам,
-Cost of Goods Sold,Себестоимость проданного товара,
+Cost of Goods Sold,Себестоимость проданных продуктов,
 Cost of Issued Items,Стоимость выпущенных продуктов,
 Cost of New Purchase,Стоимость новой покупки,
 Cost of Purchased Items,Стоимость поставленных продуктов,
@@ -631,13 +631,13 @@
 Cost of Sold Asset,Себестоимость проданных активов,
 Cost of various activities,Стоимость различных видов деятельности,
 "Could not create Credit Note automatically, please uncheck 'Issue Credit Note' and submit again","Не удалось создать кредитную ноту автоматически, снимите флажок «Выдавать кредитную ноту» и отправьте снова",
-Could not generate Secret,Не удалось создать секрет,
+Could not generate Secret,Не удалось сгенерировать секретный ключ,
 Could not retrieve information for {0}.,Не удалось получить информацию для {0}.,
 Could not solve criteria score function for {0}. Make sure the formula is valid.,"Не удалось решить функцию оценки критериев для {0}. Убедитесь, что формула действительна.",
 Could not solve weighted score function. Make sure the formula is valid.,"Не удалось решить функцию взвешенного балла. Убедитесь, что формула действительна.",
-Could not submit some Salary Slips,Не удалось подтвердить некоторые зарплатные листки,
-"Could not update stock, invoice contains drop shipping item.","Не удалось обновить запас, счет-фактура содержит падение пункт доставки.",
-Country wise default Address Templates,Шаблоны Страна мудрый адрес по умолчанию,
+Could not submit some Salary Slips,Не удалось отправить некоторые зарплатные ведомости,
+"Could not update stock, invoice contains drop shipping item.","Не удалось обновить запасы, счет-фактура содержит продукт прямой доставки.",
+Country wise default Address Templates,Шаблоны адресов по умолчанию для разных стран,
 Course,Курс,
 Course Code: ,Код курса:,
 Course Enrollment {0} does not exists,Зачисление на курс {0} не существует,
@@ -658,8 +658,8 @@
 Create Invoices,Создать счета,
 Create Job Card,Создать вакансию,
 Create Journal Entry,Создать запись в журнале,
-Create Lead,Создать лидерство,
-Create Leads,Создать Обращения,
+Create Lead,Создать обращение,
+Create Leads,Создать лид,
 Create Maintenance Visit,Создать техническое посещение,
 Create Material Request,Создать заявку на материал,
 Create Multiple,Создать несколько,
@@ -667,13 +667,13 @@
 Create Payment Entries,Создать платежные записи,
 Create Payment Entry,Создать платежную запись,
 Create Print Format,Создание Формат печати,
-Create Purchase Order,Создать заказ на поставку,
-Create Purchase Orders,Создание заказов на поставку,
-Create Quotation,Создание цитаты,
-Create Salary Slip,Создание Зарплата Слип,
-Create Salary Slips,Создать зарплатные листки,
+Create Purchase Order,Создать заявку на поставку,
+Create Purchase Orders,Создание заявки на поставку,
+Create Quotation,Создать предложение,
+Create Salary Slip,Создать зарплатную ведомость,
+Create Salary Slips,Создать зарплатные ведомости,
 Create Sales Invoice,Создать счет на продажу,
-Create Sales Order,Создать Сделку,
+Create Sales Order,Создать заявку на продажу,
 Create Sales Orders to help you plan your work and deliver on-time,"Создавайте заказы на продажу, чтобы помочь вам спланировать свою работу и выполнить ее в срок",
 Create Sample Retention Stock Entry,Создать образец записи для удержания запаса,
 Create Student,Создать ученика,
@@ -696,19 +696,19 @@
 Creating Salary Slips...,Создание зарплатных листков...,
 Creating student groups,Создание групп студентов,
 Creating {0} Invoice,Создание {0} счета-фактуры,
-Credit,кредит,
+Credit,Кредит,
 Credit ({0}),Кредит ({0}),
 Credit Account,Кредитный счет,
-Credit Balance,Остаток кредита,
+Credit Balance,Кредитный баланс,
 Credit Card,Кредитная карта,
 Credit Days cannot be a negative number,Кредитные дни не могут быть отрицательным числом,
 Credit Limit,{0}{/0} {1}Кредитный лимит {/1},
-Credit Note,Кредит-нота,
+Credit Note,Кредитная запись ,
 Credit Note Amount,Сумма кредитной записи,
 Credit Note Issued,Кредит выдается справка,
-Credit Note {0} has been created automatically,Кредитная нота {0} создана автоматически,
+Credit Note {0} has been created automatically,Кредитная запись {0} была создана автоматически,
 Credit limit has been crossed for customer {0} ({1}/{2}),Кредитный лимит был скрещен для клиента {0} ({1} / {2}),
-Creditors,кредиторы,
+Creditors,Кредиторы,
 Criteria weights must add up to 100%,Критерии веса должны составлять до 100%,
 Crop Cycle,Цикл урожая,
 Crops & Lands,Сельскохозяйственные культуры и земли,
@@ -725,15 +725,15 @@
 Current BOM and New BOM can not be same,"Текущий спецификации и Нью-BOM не может быть таким же,",
 Current Job Openings,Текущие вакансии Вакансии,
 Current Liabilities,Текущие обязательства,
-Current Qty,Текущий Кол-во,
+Current Qty,Текущее количество,
 Current invoice {0} is missing,Текущий счет-фактура {0} отсутствует,
-Custom HTML,Особый HTML,
-Custom?,Пользовательские?,
+Custom HTML,Пользовательский HTML,
+Custom?,Пользовательский?,
 Customer,Клиент,
 Customer Addresses And Contacts,Адреса клиентов и Контакты,
 Customer Contact,Контакты с клиентами,
 Customer Database.,База данных клиентов.,
-Customer Group,Группа Клиентов,
+Customer Group,Группа клиентов,
 Customer LPO,Клиент LPO,
 Customer LPO No.,Номер клиента LPO,
 Customer Name,Имя клиента,
@@ -764,19 +764,19 @@
 Date of Joining,Дата вступления,
 Date of Joining must be greater than Date of Birth,Дата Присоединение должно быть больше Дата рождения,
 Date of Transaction,Дата транзакции,
-Datetime,Datetime,
+Datetime,Дата и время,
 Day,День,
 Debit,Дебет,
 Debit ({0}),Дебет ({0}),
 Debit A/C Number,Дебетовый номер кондиционера,
 Debit Account,Дебетовый счет,
-Debit Note,Дебет-нота,
-Debit Note Amount,Сумма дебетовой ноты,
-Debit Note Issued,Дебет Примечание Выпущенный,
+Debit Note,Дебетовая запись,
+Debit Note Amount,Сумма дебетовой записи,
+Debit Note Issued,Дата дебетовой записи,
 Debit To is required,Дебет требуется,
 Debit and Credit not equal for {0} #{1}. Difference is {2}.,Дебет и Кредит не равны для {0} # {1}. Разница {2}.,
-Debtors,Должники,
-Debtors ({0}),Должники ({0}),
+Debtors,Дебеторы,
+Debtors ({0}),Дебеторы ({0}),
 Declare Lost,Объявить потерянным,
 Deduction,Вычет,
 Default Activity Cost exists for Activity Type - {0},По умолчанию активность Стоимость существует для вида деятельности - {0},
@@ -816,67 +816,67 @@
 Department,Отдел,
 Department Stores,Универмаги,
 Depreciation,Амортизация,
-Depreciation Amount,Амортизация основных средств Сумма,
-Depreciation Amount during the period,Амортизация Сумма за период,
-Depreciation Date,Износ Дата,
+Depreciation Amount,Сумма амортизации основных средств,
+Depreciation Amount during the period,Сумма амортизации за период,
+Depreciation Date,Дата амортизации,
 Depreciation Eliminated due to disposal of assets,Амортизация Дошел вследствие выбытия активов,
 Depreciation Entry,Износ Вход,
-Depreciation Method,метод начисления износа,
+Depreciation Method,Метод начисления износа,
 Depreciation Row {0}: Depreciation Start Date is entered as past date,Строка амортизации {0}: дата начала амортизации вводится как прошедшая дата,
 Depreciation Row {0}: Expected value after useful life must be greater than or equal to {1},Строка амортизации {0}: ожидаемое значение после полезного срока службы должно быть больше или равно {1},
 Depreciation Row {0}: Next Depreciation Date cannot be before Available-for-use Date,"Строка амортизации {0}: следующая дата амортизации не может быть до даты, доступной для использования",
 Depreciation Row {0}: Next Depreciation Date cannot be before Purchase Date,Строка амортизации {0}: следующая дата амортизации не может быть до даты покупки,
-Designer,дизайнер,
+Designer,Дизайнер,
 Detailed Reason,Подробная причина,
 Details,Подробности,
 Details of Outward Supplies and inward supplies liable to reverse charge,"Сведения о расходных материалах и расходных материалах, подлежащих возврату",
 Details of the operations carried out.,Информация о выполненных операциях.,
-Diagnosis,диагностика,
+Diagnosis,Диагностика,
 Did not find any item called {0},Не нашли какой-либо пункт под названием {0},
 Diff Qty,Diff Qty,
-Difference Account,Учетная запись,
+Difference Account,Разница счета,
 "Difference Account must be a Asset/Liability type account, since this Stock Reconciliation is an Opening Entry","Разница аккаунт должен быть тип счета активов / пассивов, так как это со Примирение запись Открытие",
-Difference Amount,Разница Сумма,
-Difference Amount must be zero,Разница Сумма должна быть равна нулю,
+Difference Amount,Разница,
+Difference Amount must be zero,Разница должна быть равна нулю,
 Different UOM for items will lead to incorrect (Total) Net Weight value. Make sure that Net Weight of each item is in the same UOM.,"Различные единицы измерения (ЕИ) продуктов приведут к некорректному (общему) значению массы нетто. Убедитесь, что вес нетто каждого продукта находится в одной ЕИ.",
 Direct Expenses,Прямые расходы,
 Direct Income,Прямая прибыль,
 Disable,Отключить,
-Disabled template must not be default template,Шаблон для инвалидов не должно быть по умолчанию шаблон,
+Disabled template must not be default template,Отключенный шаблон не может быть шаблоном по умолчанию,
 Disburse Loan,Выдавать кредит,
 Disbursed,Освоено,
 Disc,диск,
 Discharge,разрядка,
-Discount,скидка,
+Discount,Скидка,
 Discount Percentage can be applied either against a Price List or for all Price List.,"Процент скидки может применяться либо к Прайс-листу, либо ко всем Прайс-листам.",
 Discount must be less than 100,Скидка должна быть меньше 100,
 Diseases & Fertilizers,Болезни и удобрения,
-Dispatch,отправка,
+Dispatch,Отправка,
 Dispatch Notification,Уведомление о рассылке,
 Dispatch State,Состояние отправки,
 Distance,Дистанция,
-Distribution,распределение,
-Distributor,дистрибьютор,
+Distribution,Дистрибьюция,
+Distributor,Дистрибьютор,
 Dividends Paid,Оплачено дивидендов,
-Do you really want to restore this scrapped asset?,Вы действительно хотите восстановить этот актив на слом?,
+Do you really want to restore this scrapped asset?,Вы действительно хотите восстановить этот списанный актив?,
 Do you really want to scrap this asset?,Вы действительно хотите отказаться от этого актива?,
 Do you want to notify all the customers by email?,Вы хотите уведомить всех клиентов по электронной почте?,
 Doc Date,Дата документа,
 Doc Name,Имя документа,
 Doc Type,Тип документа,
 Docs Search,Поиск документов,
-Document Name,название документа,
+Document Name,Название документа,
 Document Status,Статус документа,
-Document Type,тип документа,
-Domain,Домен,
+Document Type,Тип документа,
+Domain,Направление,
 Domains,Направление деятельности,
-Done,Сделать,
-Donor,даритель,
+Done,Готово,
+Donor,Донор,
 Donor Type information.,Информация о доноре.,
 Donor information.,Донорская информация.,
 Download JSON,Скачать JSON,
-Draft,Проект,
-Drop Ship,Корабль падения,
+Draft,Черновик,
+Drop Ship,Прямая поставка,
 Drug,Лекарство,
 Due / Reference Date cannot be after {0},Из-за / Reference Дата не может быть в течение {0},
 Due Date cannot be before Posting / Supplier Invoice Date,Срок оплаты не может быть раньше даты публикации / выставления счета поставщику,
@@ -885,7 +885,7 @@
 Duplicate Serial No entered for Item {0},Дубликат Серийный номер вводится для Пункт {0},
 Duplicate customer group found in the cutomer group table,Дубликат группа клиентов найти в таблице Cutomer группы,
 Duplicate entry,Дублировать запись,
-Duplicate item group found in the item group table,Повторяющаяся группа находке в таблице группы товаров,
+Duplicate item group found in the item group table,Дубликат группы продуктов в таблице групп продуктов,
 Duplicate roll number for student {0},Повторяющийся номер ролика для ученика {0},
 Duplicate row {0} with same {1},Дубликат строка {0} с же {1},
 Duplicate {0} found in the table,Дубликат {0} найден в таблице,
@@ -894,10 +894,10 @@
 E-Invoicing Information Missing,Отсутствует информация об инвойсировании,
 ERPNext Demo,ERPNext Demo,
 ERPNext Settings,Настройки ERPNext,
-Earliest,Старейшие,
+Earliest,Самый ранний,
 Earnest Money,Задаток,
 Earning,Зарабатывание,
-Edit,редактировать,
+Edit,Ред.,
 Edit Publishing Details,Редактировать информацию о публикации,
 "Edit in full page for more options like assets, serial nos, batches etc.","Редактируйте на полной странице дополнительные параметры, такие как активы, серийные номера, партии и т. Д.",
 Education,образование,
@@ -906,7 +906,7 @@
 Either target qty or target amount is mandatory.,Либо целевой Количество или целевое количество является обязательным.,
 Electrical,электрический,
 Electronic Equipments,Электронные приборы,
-Electronics,электроника,
+Electronics,Электроника,
 Eligible ITC,Соответствующий ITC,
 Email Account,Электронная почта,
 Email Address,Адрес электронной почты,
@@ -918,14 +918,14 @@
 Email not found in default contact,Адрес электронной почты не найден в контакте по умолчанию,
 Email sent to {0},Письмо отправлено на адрес {0},
 Employee,Сотрудник,
-Employee A/C Number,Номер A / C сотрудника,
+Employee A/C Number,A/C номер сотрудника,
 Employee Advances,Достижения сотрудников,
 Employee Benefits,Вознаграждения работникам,
 Employee Grade,Уровень персонала,
 Employee ID,ID сотрудника,
 Employee Lifecycle,Жизненный цикл сотрудников,
 Employee Name,Имя сотрудника,
-Employee Promotion cannot be submitted before Promotion Date ,Продвижение сотрудника не может быть отправлено до даты акции,
+Employee Promotion cannot be submitted before Promotion Date ,Повышение сотрудника не может быть выполнено до даты приступления к должности,
 Employee Referral,Перечень сотрудников,
 Employee Transfer cannot be submitted before Transfer Date ,Передача сотрудника не может быть отправлена до даты передачи,
 Employee cannot report to himself.,Сотрудник не может сообщить себе.,
@@ -937,9 +937,9 @@
 Employee {0} is on Leave on {1},Сотрудник {0} отправляется в {1},
 Employee {0} of grade {1} have no default leave policy,Сотрудник {0} класса {1} не имеет политики отпуска по умолчанию,
 Employee {0} on Half day on {1},Сотрудник {0} на полдня на {1},
-Enable,Автоматическое обновление,
-Enable / disable currencies.,Включение / отключение валюты.,
-Enabled,Включено,
+Enable, Разрешить,
+Enable / disable currencies.,Разрешить / запретить валюты.,
+Enabled,Разрешено,
 "Enabling 'Use for Shopping Cart', as Shopping Cart is enabled and there should be at least one Tax Rule for Shopping Cart","Включение &quot;Использовать для Корзине», как Корзина включена и должно быть по крайней мере один налог Правило Корзина",
 End Date,Дата окончания,
 End Date can not be less than Start Date,Дата окончания не может быть меньше даты начала,
@@ -950,8 +950,8 @@
 End time cannot be before start time,Время окончания не может быть раньше времени начала,
 Ends On date cannot be before Next Contact Date.,Конец дата не может быть до следующей даты контакта.,
 Energy,Энергоэффективность,
-Engineer,инженер,
-Enough Parts to Build,Достаточно части для сборки,
+Engineer,Инженер,
+Enough Parts to Build,Достаточно деталей для сборки,
 Enroll,зачислять,
 Enrolling student,поступив студент,
 Enrolling students,Регистрация студентов,
@@ -966,9 +966,9 @@
 Error Log,Журнал ошибок,
 Error evaluating the criteria formula,Ошибка оценки формулы критериев,
 Error in formula or condition: {0},Ошибка в формуле или условие: {0},
-Error: Not a valid id?,Ошибка: Не действует ID?,
+Error: Not a valid id?,Ошибка: Не действительный ID?,
 Estimated Cost,Ориентировочная стоимость,
-Evaluation,оценка,
+Evaluation,Оценка,
 "Even if there are multiple Pricing Rules with highest priority, then following internal priorities are applied:","Даже если существует несколько правил ценообразования с наивысшим приоритетом, применяются следующие внутренние приоритеты:",
 Event,Событие,
 Event Location,Место проведения мероприятия,
@@ -979,13 +979,13 @@
 Excise Invoice,Акцизный Счет,
 Execution,Реализация,
 Executive Search,Executive Search,
-Expand All,Расширить все,
+Expand All,Развернуть все,
 Expected Delivery Date,Ожидаемая дата доставки,
 Expected Delivery Date should be after Sales Order Date,Ожидаемая дата доставки должна быть после даты Сделки,
 Expected End Date,Ожидаемая дата завершения,
 Expected Hrs,Ожидаемые часы,
 Expected Start Date,Ожидаемая дата начала,
-Expense,расходы,
+Expense,Расходы,
 Expense / Difference account ({0}) must be a 'Profit or Loss' account,"Расходов / Разница счет ({0}) должен быть ""прибыль или убыток» счета",
 Expense Account,Расходов счета,
 Expense Claim,Заявка на возмещение,
@@ -996,7 +996,7 @@
 Expenses,Расходы,
 Expenses Included In Asset Valuation,"Расходы, включенные в оценку активов",
 Expenses Included In Valuation,"Затрат, включаемых в оценке",
-Expired Batches,Истекшие партии,
+Expired Batches,Просроченные партии,
 Expires On,Годен до,
 Expiring On,Срок действия,
 Expiry (In Days),Срок действия (в днях),
@@ -1004,7 +1004,7 @@
 Export E-Invoices,Экспорт электронных счетов,
 Extra Large,Очень большой,
 Extra Small,Очень маленький,
-Fail,Потерпеть неудачу,
+Fail,Неудача,
 Failed,Не выполнено,
 Failed to create website,Не удалось создать веб-сайт,
 Failed to install presets,Не удалось установить пресеты,
@@ -1013,7 +1013,7 @@
 Failed to setup defaults,Не удалось установить значения по умолчанию,
 Failed to setup post company fixtures,Не удалось настроить оборудование для компании,
 Fax,Факс,
-Fee,плата,
+Fee,Оплата,
 Fee Created,Плата создана,
 Fee Creation Failed,Не удалось создать сбор,
 Fee Creation Pending,Платежное создание ожидается,
@@ -1039,8 +1039,8 @@
 Financial Year,Финансовый год,
 Finish,Завершить,
 Finished Good,Готово Хорошо,
-Finished Good Item Code,Готовый товарный код,
-Finished Goods,Готовая продукция,
+Finished Good Item Code,Код готовых продуктов,
+Finished Goods,Готовые продукты,
 Finished Item {0} must be entered for Manufacture type entry,Готовая единица {0} должна быть введена для Производственного типа записи,
 Finished product quantity <b>{0}</b> and For Quantity <b>{1}</b> cannot be different,Количество готового продукта <b>{0}</b> и для количества <b>{1}</b> не может быть разным,
 First Name,Имя,
@@ -1079,7 +1079,7 @@
 Forum Activity,Активность в форуме,
 Free item code is not selected,Бесплатный код товара не выбран,
 Freight and Forwarding Charges,Грузовые и экспедиторские Сборы,
-Frequency,частота,
+Frequency,Частота,
 Friday,Пятница,
 From,От,
 From Address 1,Из адреса 1,
@@ -1132,7 +1132,7 @@
 Generate Secret,Создать секрет,
 Get Details From Declaration,Получить детали из декларации,
 Get Employees,Получить сотрудников,
-Get Invocies,Получить призывы,
+Get Invocies,Получить счета,
 Get Invoices,Получить счета,
 Get Invoices based on Filters,Получить счета на основе фильтров,
 Get Items from BOM,Получить продукты из спецификации,
@@ -1153,7 +1153,7 @@
 Goal and Procedure,Цель и процедура,
 Goals cannot be empty,Цели не могут быть пустыми,
 Goods In Transit,Товары в пути,
-Goods Transferred,Товар перенесен,
+Goods Transferred,Товар передан,
 Goods and Services Tax (GST India),Налог на товары и услуги (GST India),
 Goods are already received against the outward entry {0},Товар уже получен против выездной записи {0},
 Government,Правительство,
@@ -1169,19 +1169,19 @@
 Gross Profit / Loss,Валовая прибыль / убыток,
 Gross Purchase Amount,Валовая сумма покупки,
 Gross Purchase Amount is mandatory,Валовая сумма покупки является обязательным,
-Group by Account,Группа по Счет,
-Group by Party,Группа по партии,
-Group by Voucher,Группа по ваучером,
-Group by Voucher (Consolidated),Группа по ваучеру (консолидировано),
-Group node warehouse is not allowed to select for transactions,"склад группы узлов не допускается, чтобы выбрать для сделок",
+Group by Account,Сгруппировать по счетам,
+Group by Party,Сгруппировать по партии,
+Group by Voucher,Сгруппировать по ваучеру,
+Group by Voucher (Consolidated),Сгруппировать по ваучеру (консолидировано),
+Group node warehouse is not allowed to select for transactions,Склад узла группы не может выбирать для транзакций,
 Group to Non-Group,Группа не-группы,
 Group your students in batches,Группа ваших студентов в партиях,
-Groups,группы,
+Groups,Группы,
 Guardian1 Email ID,Идентификатор электронной почты Guardian1,
-Guardian1 Mobile No,Guardian1 Mobile Нет,
+Guardian1 Mobile No,Guardian1 Mobile №,
 Guardian1 Name,Имя Guardian1,
 Guardian2 Email ID,Идентификатор электронной почты Guardian2,
-Guardian2 Mobile No,Guardian2 Mobile Нет,
+Guardian2 Mobile No,Guardian2 Mobile №,
 Guardian2 Name,Имя Guardian2,
 Guest,Гость,
 HR Manager,Менеджер отдела кадров,
@@ -1189,8 +1189,8 @@
 HSN/SAC,HSN / SAC,
 Half Day,Полдня,
 Half Day Date is mandatory,Полдня Дата обязательна,
-Half Day Date should be between From Date and To Date,Поаяся Дата должна быть в пределах от даты и до настоящего времени,
-Half Day Date should be in between Work From Date and Work End Date,Половина дня должна находиться между Работой с даты и датой окончания работы,
+Half Day Date should be between From Date and To Date,Дата половины дня должна быть между датой начала и датой окончания.,
+Half Day Date should be in between Work From Date and Work End Date,Дата половины дня должна находиться между датой начала работы и датой окончания работы,
 Half Yearly,Половина года,
 Half day date should be in between from date and to date,Половина дня должна быть между датой и датой,
 Half-Yearly,Раз в полгода,
@@ -1217,8 +1217,8 @@
 Holiday List,Список праздников,
 Hotel Rooms of type {0} are unavailable on {1},Номера отеля типа {0} недоступны в {1},
 Hotels,Отели,
-Hourly,почасовой,
-Hours,часов,
+Hourly,Почасовой,
+Hours,Часов,
 House rent paid days overlapping with {0},Аренда дома оплачивается по дням с перекрытием {0},
 House rented dates required for exemption calculation,"Даты аренды дома, необходимые для расчета освобождения",
 House rented dates should be atleast 15 days apart,Даты аренды дома должны быть как минимум на 15 дней друг от друга,
@@ -1265,7 +1265,7 @@
 Include POS Transactions,Включить POS-транзакции,
 Include UOM,Включить UOM,
 Included in Gross Profit,Включено в валовую прибыль,
-Income,доход,
+Income,Доход,
 Income Account,Счет Доходов,
 Income Tax,Подоходный налог,
 Incoming,Входящий,
@@ -1286,7 +1286,7 @@
 Installing presets,Установка пресетов,
 Institute Abbreviation,институт Аббревиатура,
 Institute Name,Название института,
-Instructor,инструктор,
+Instructor,Инструктор,
 Insufficient Stock,Недостаточный Stock,
 Insurance Start date should be less than Insurance End date,"Дата страхование начала должна быть меньше, чем дата страхование End",
 Integrated Tax,Интегрированный налог,
@@ -1352,7 +1352,7 @@
 Item Group,Продуктовая группа,
 Item Group Tree,Структура продуктовых групп,
 Item Group not mentioned in item master for item {0},Пункт Группа не упоминается в мастера пункт по пункту {0},
-Item Name,Имя элемента,
+Item Name,Название продукта,
 Item Price added for {0} in Price List {1},Цена продукта {0} добавлена в прайс-лист {1},
 "Item Price appears multiple times based on Price List, Supplier/Customer, Currency, Item, UOM, Qty and Dates.","Цена товара отображается несколько раз на основе Прайс-листа, Поставщика / Клиента, Валюты, Предмет, UOM, Кол-во и Даты.",
 Item Price updated for {0} in Price List {1},Цена продукта {0} обновлена в прайс-листе {1},
@@ -1397,7 +1397,7 @@
 Job Description,Описание работы,
 Job Offer,Предложение работы,
 Job card {0} created,Карта работы {0} создана,
-Jobs,работы,
+Jobs,Работы,
 Join,Присоединиться,
 Journal Entries {0} are un-linked,Записи в журнале {0} не-связаны,
 Journal Entry,Запись в дневнике,
@@ -1413,10 +1413,10 @@
 Lab Tests and Vital Signs,Лабораторные тесты и жизненные знаки,
 Lab result datetime cannot be before testing datetime,Лабораторный результат datetime не может быть до тестирования даты и времени,
 Lab testing datetime cannot be before collection datetime,Лабораторное тестирование datetime не может быть до даты сбора данных,
-Label,Имя поля,
-Laboratory,лаборатория,
+Label,Ярлык,
+Laboratory,Лаборатория,
 Language Name,Название языка,
-Large,большой,
+Large,Большой,
 Last Communication,Последнее сообщение,
 Last Communication Date,Дата последнего общения,
 Last Name,Фамилия,
@@ -1426,13 +1426,13 @@
 Last Purchase Rate,Последняя цена покупки,
 Latest,Последние,
 Latest price updated in all BOMs,Последняя цена обновлена во всех спецификациях,
-Lead,Обращение,
-Lead Count,Счет Обращения,
-Lead Owner,Ответственный,
-Lead Owner cannot be same as the Lead,Ответственным за Обращение не может быть сам обратившийся,
-Lead Time Days,Время выполнения,
-Lead to Quotation,Обращение в Предложение,
-"Leads help you get business, add all your contacts and more as your leads",Обращения необходимы бизнесу. Добавьте все свои контакты в качестве Обращений,
+Lead,Лид,
+Lead Count,Количество лидов,
+Lead Owner,Ответственный за лид,
+Lead Owner cannot be same as the Lead,Ответственным за лид не может быть сам лид,
+Lead Time Days,Время лида,
+Lead to Quotation,Лид в предложение,
+"Leads help you get business, add all your contacts and more as your leads",Лиды необходимы бизнесу. Добавьте все свои контакты в качестве лидов,
 Learn,Справка,
 Leave Approval Notification,Оставить уведомление об утверждении,
 Leave Blocked,Оставьте Заблокированные,
@@ -1464,7 +1464,7 @@
 Liability,Ответственность сторон,
 License,Лицензия,
 Lifecycle,Жизненный цикл,
-Limit,предел,
+Limit,Предел,
 Limit Crossed,предел Скрещенные,
 Link to Material Request,Ссылка на запрос материала,
 List of all share transactions,Список всех сделок с акциями,
@@ -1482,7 +1482,7 @@
 Log,Запись в журнале,
 Logs for maintaining sms delivery status,Журналы для просмотра статуса доставки СМС,
 Lost,Поражений,
-Lost Reasons,Потерянные Причины,
+Lost Reasons,Потерянные причины,
 Low,Низкий,
 Low Sensitivity,Низкая чувствительность,
 Lower Income,Низкий уровень дохода,
@@ -1515,7 +1515,7 @@
 Manage Sales Person Tree.,Управление деревом менеджеров по продажам.,
 Manage Territory Tree.,Управление деревом территорий.,
 Manage your orders,Управляйте свои заказы,
-Management,управление,
+Management,Менеджмент,
 Manager,Менеджер,
 Managing Projects,Управление проектами,
 Managing Subcontracting,Управление субподрядом,
@@ -1524,17 +1524,17 @@
 Mandatory field - Get Students From,Обязательное поле — получить учащихся из,
 Mandatory field - Program,Обязательное поле — программа,
 Manufacture,Производство,
-Manufacturer,производитель,
+Manufacturer,Производитель,
 Manufacturer Part Number,Номер партии производителя,
 Manufacturing,Производство,
 Manufacturing Quantity is mandatory,Производство Количество является обязательным,
-Mapping,картографирование,
+Mapping,Картографирование,
 Mapping Type,Тип отображения,
 Mark Absent,Отметка отсутствует,
 Mark Attendance,Пометить посещаемость,
 Mark Half Day,Отметить Полдня,
 Mark Present,Марк Присутствует,
-Marketing,маркетинг,
+Marketing,Маркетинг,
 Marketing Expenses,Маркетинговые расходы,
 Marketplace,Торговая площадка,
 Marketplace Error,Ошибка рынка,
@@ -1578,13 +1578,13 @@
 Member ID,ID пользователя,
 Member Name,Имя участника,
 Member information.,Информация о членах.,
-Membership,членство,
+Membership,Членство,
 Membership Details,Сведения о членстве,
 Membership ID,Идентификатор членства,
 Membership Type,Тип членства,
 Memebership Details,Меморандум,
 Memebership Type Details,Информация о типе памяти,
-Merge,сливаться,
+Merge,Объеденить,
 Merge Account,Объединить учетную запись,
 Merge with Existing Account,Слияние с существующей учетной записью,
 "Merging is only possible if following properties are same in both records. Is Group, Root Type, Company","Объединение возможно только, если следующие свойства такие же, как в отчетах. Есть группа, корневого типа, компания",
@@ -1596,7 +1596,7 @@
 Middle Name (Optional),Отчество (необязательно),
 Min Amt can not be greater than Max Amt,Min Amt не может быть больше Max Amt,
 Min Qty can not be greater than Max Qty,"Мин Кол-во не может быть больше, чем максимальное Кол-во",
-Minimum Lead Age (Days),Минимальный срок Обращения (в днях),
+Minimum Lead Age (Days),Минимальный срок лида (в днях),
 Miscellaneous Expenses,Прочие расходы,
 Missing Currency Exchange Rates for {0},Пропавших без вести Курсы валют на {0},
 Missing email template for dispatch. Please set one in Delivery Settings.,Отсутствует шаблон электронной почты для отправки. Установите его в настройках доставки.,
@@ -1606,7 +1606,7 @@
 Mode of Transport,Вид транспорта,
 Mode of Transportation,Способ транспортировки,
 Mode of payment is required to make a payment,Способ оплаты требуется произвести оплату,
-Model,модель,
+Model,Модель,
 Moderate Sensitivity,Умеренная Чувствительность,
 Monday,Понедельник,
 Monthly,Ежемесячно,
@@ -1625,13 +1625,13 @@
 "Multiple Price Rules exists with same criteria, please resolve conflict by assigning priority. Price Rules: {0}","Несколько Цена Правила существует с теми же критериями, пожалуйста разрешить конфликт путем присвоения приоритета. Цена Правила: {0}",
 Multiple Variants,Несколько вариантов,
 Multiple fiscal years exist for the date {0}. Please set company in Fiscal Year,"Несколько финансовых лет существуют на дату {0}. Пожалуйста, установите компанию в финансовый год",
-Music,музыка,
+Music,Музыка,
 My Account,Мой аккаунт,
 Name error: {0},Ошибка Имя: {0},
 Name of new Account. Note: Please don't create accounts for Customers and Suppliers,"Название нового счёта. Примечание: Пожалуйста, не создавайте счета для клиентов и поставщиков",
 Name or Email is mandatory,Имя или адрес электронной почты является обязательным,
 Nature Of Supplies,Природа поставок,
-Navigating,навигационный,
+Navigating,Навигационный,
 Needs Analysis,Анализ потребностей,
 Negative Quantity is not allowed,Отрицательное количество недопустимо,
 Negative Valuation Rate is not allowed,Отрицательный Оценка курс не допускается,
@@ -1659,7 +1659,7 @@
 New Batch ID (Optional),Новый идентификатор партии (необязательно),
 New Batch Qty,Новое количество партий,
 New Company,Новая Компания,
-New Cost Center Name,Новый Центр Стоимость Имя,
+New Cost Center Name,Название нового центра затрат,
 New Customer Revenue,Новый Выручка клиентов,
 New Customers,новые клиенты,
 New Department,Новый отдел,
@@ -1676,7 +1676,7 @@
 Newsletters,Информационная рассылка,
 Newspaper Publishers,Информационное издательство,
 Next,Далее,
-Next Contact By cannot be same as the Lead Email Address,Следующий контакт не может совпадать с адресом электронной почты Обращения,
+Next Contact By cannot be same as the Lead Email Address,Следующий контакт не может совпадать с адресом электронной почты лида,
 Next Contact Date cannot be in the past,Дата следующего контакта не может быть в прошлом,
 Next Steps,Следующие шаги,
 No Action,Бездействие,
@@ -1692,7 +1692,7 @@
 No Items with Bill of Materials to Manufacture,Нет предметов с Биллом материалов не Manufacture,
 No Items with Bill of Materials.,Нет предметов с ведомостью материалов.,
 No Permission,Нет разрешения,
-No Remarks,Нет Замечания,
+No Remarks,Нет замечаний,
 No Result to submit,Нет результатов для отправки,
 No Salary Structure assigned for Employee {0} on given date {1},"Нет структуры заработной платы, назначенной для сотрудника {0} в данную дату {1}",
 No Staffing Plans found for this Designation,Никаких кадровых планов для этого обозначения,
@@ -1727,16 +1727,16 @@
 No {0} found for Inter Company Transactions.,Нет {0} найдено для транзакций Inter Company.,
 Non GST Inward Supplies,Не входящие в GST поставки,
 Non Profit,Некоммерческое предприятие,
-Non Profit (beta),Непрофит (бета),
+Non Profit (beta),Некоммерческое предприятие (бета),
 Non-GST outward supplies,Внешние поставки без GST,
 Non-Group to Group,Non-группы к группе,
 None,Никто,
 None of the items have any change in quantity or value.,Ни одному продукту не изменено количество или объём.,
-Nos,кол-во,
-Not Available,Не доступен,
-Not Marked,без маркировки,
+Nos,Кол-во,
+Not Available,Недоступен,
+Not Marked,Без маркировки,
 Not Paid and Not Delivered,Не оплачен и не доставлен,
-Not Permitted,Не Допустимая,
+Not Permitted,Нет допуска,
 Not Started,Не начато,
 Not active,Не действует,
 Not allow to set alternative item for the item {0},Не разрешить установку альтернативного элемента для элемента {0},
@@ -1766,12 +1766,12 @@
 "Number of new Account, it will be included in the account name as a prefix","Номер новой учетной записи, она будет включена в имя учетной записи в качестве префикса",
 "Number of new Cost Center, it will be included in the cost center name as a prefix","Количество нового МВЗ, оно будет включено в название МВЗ в качестве префикса",
 Number of root accounts cannot be less than 4,Количество корневых учетных записей не может быть меньше 4,
-Odometer,одометр,
+Odometer,Одометр,
 Office Equipments,Оборудование офиса,
 Office Maintenance Expenses,Эксплуатационные расходы на офис,
 Office Rent,Аренда площади для офиса,
 On Hold,На удерживании,
-On Net Total,On Net Всего,
+On Net Total,Чистая сумма,
 One customer can be part of only single Loyalty Program.,Один клиент может быть частью единой программы лояльности.,
 Online Auctions,Аукционы в Интернете,
 Only Leave Applications with status 'Approved' and 'Rejected' can be submitted,Только оставьте приложения со статусом «Одобрено» и «Отклонено» могут быть представлены,
@@ -1782,7 +1782,7 @@
 Open Notifications,Открытые уведомления,
 Open Orders,Открытые заказы,
 Open a new ticket,Открыть новый билет,
-Opening,открытие,
+Opening,Открытие,
 Opening (Cr),Начальное сальдо (кредит),
 Opening (Dr),Начальное сальдо (дебет),
 Opening Accounting Balance,Начальный бухгалтерский баланс,
@@ -1808,11 +1808,11 @@
 Operations,Эксплуатация,
 Operations cannot be left blank,"Операции, не может быть оставлено пустым",
 Opp Count,Счетчик Opp,
-Opp/Lead %,"Выявления/Обращения, %",
+Opp/Lead %,"Выявления/Лиды, %",
 Opportunities,Возможности,
-Opportunities by lead source,Выявления из источника обращения,
-Opportunity,Выявление,
-Opportunity Amount,Количество Выявления,
+Opportunities by lead source,Возможность из источника лидов,
+Opportunity,Возможность,
+Opportunity Amount,Сумма возможности,
 Optional Holiday List not set for leave period {0},Необязательный список праздников не установлен для периода отпуска {0},
 "Optional. Sets company's default currency, if not specified.","Необязательный. Устанавливает по умолчанию валюту компании, если не указано.",
 Optional. This setting will be used to filter in various transactions.,Факультативно. Эта установка будет использоваться для фильтрации в различных сделок.,
@@ -1821,13 +1821,13 @@
 Order Entry,Порядок въезда,
 Order Value,Ценность заказа,
 Order rescheduled for sync,Заказ перенесен на синхронизацию,
-Order/Quot %,Заказ / Котировка%,
+Order/Quot %,Заказ/Котировка %,
 Ordered,В обработке,
 Ordered Qty,Заказал кол-во,
 "Ordered Qty: Quantity ordered for purchase, but not received.","Заказал Количество: Количество заказал для покупки, но не получил.",
-Orders,заказы,
+Orders,Заказы,
 Orders released for production.,"Заказы, выпущенные для производства.",
-Organization,организация,
+Organization,Организация,
 Organization Name,Название организации,
 Other,Другое,
 Other Reports,Другие отчеты,
@@ -1900,7 +1900,7 @@
 Payment Failed. Please check your GoCardless Account for more details,"Платеж не прошел. Пожалуйста, проверьте свою учетную запись GoCardless для получения более подробной информации.",
 Payment Gateway,Платежный шлюз,
 "Payment Gateway Account not created, please create one manually.","Payment Gateway Account не создан, создайте его вручную.",
-Payment Gateway Name,Имя платежного шлюза,
+Payment Gateway Name,Название платежного шлюза,
 Payment Mode,Режим платежа,
 Payment Receipt Note,Оплата Получение Примечание,
 Payment Request,Платежная заявка,
@@ -1937,7 +1937,7 @@
 Personal Details,Личные Данные,
 Pharmaceutical,Фармацевтический,
 Pharmaceuticals,Фармацевтика,
-Physician,врач,
+Physician,Врач,
 Piecework,Сдельная работа,
 Pincode,Pincode,
 Place Of Supply (State/UT),Место поставки (штат / UT),
@@ -1946,16 +1946,16 @@
 Plan for maintenance visits.,Запланируйте для посещения технического обслуживания.,
 Planned Qty,Планируемое кол-во,
 "Planned Qty: Quantity, for which, Work Order has been raised, but is pending to be manufactured.","Запланированное кол-во: количество, для которого было задано рабочее задание, но ожидается его изготовление.",
-Planning,планирование,
+Planning,Планирование,
 Plants and Machineries,Растения и Механизмов,
 Please Set Supplier Group in Buying Settings.,Установите группу поставщиков в разделе «Настройки покупок».,
 Please add a Temporary Opening account in Chart of Accounts,"Пожалуйста, добавьте временный вступительный счет в План счетов",
-Please add the account to root level Company - ,"Пожалуйста, добавьте учетную запись на корневой уровень компании -",
+Please add the account to root level Company - ,"Пожалуйста, добавьте счет на корневой уровень компании -",
 Please add the remaining benefits {0} to any of the existing component,Добавьте оставшиеся преимущества {0} к любому из существующих компонентов,
 Please check Multi Currency option to allow accounts with other currency,"Пожалуйста, проверьте мультивалютный вариант, позволяющий счета другой валюте",
-Please click on 'Generate Schedule',"Пожалуйста, нажмите на кнопку ""Generate Расписание""",
-Please click on 'Generate Schedule' to fetch Serial No added for Item {0},"Пожалуйста, нажмите на кнопку ""Generate Расписание"", чтобы принести Серийный номер добавлен для Пункт {0}",
-Please click on 'Generate Schedule' to get schedule,"Пожалуйста, нажмите на кнопку ""Generate Расписание"", чтобы получить график",
+Please click on 'Generate Schedule',"Пожалуйста, нажмите на кнопку ""Создать расписание""",
+Please click on 'Generate Schedule' to fetch Serial No added for Item {0},"Пожалуйста, нажмите на кнопку ""Создать расписание"", чтобы принести Серийный номер добавлен для Пункт {0}",
+Please click on 'Generate Schedule' to get schedule,"Пожалуйста, нажмите на кнопку ""Создать расписание"", чтобы получить график",
 Please confirm once you have completed your training,"Пожалуйста, подтвердите, как только вы закончили обучение",
 Please create purchase receipt or purchase invoice for the item {0},Создайте квитанцию о покупке или фактуру покупки для товара {0},
 Please define grade for Threshold 0%,"Пожалуйста, определите оценку для Threshold 0%",
@@ -2007,7 +2007,7 @@
 Please mention Round Off Account in Company,"Пожалуйста, укажите округлить счет в компании",
 Please mention Round Off Cost Center in Company,"Пожалуйста, укажите округлить МВЗ в компании",
 Please mention no of visits required,"Пожалуйста, укажите кол-во посещений, необходимых",
-Please mention the Lead Name in Lead {0},"Пожалуйста, укажите Имя в Обращении {0}",
+Please mention the Lead Name in Lead {0},"Пожалуйста, укажите имя в лиде {0}",
 Please pull items from Delivery Note,Пожалуйста вытяните продукты из транспортной накладной,
 Please register the SIREN number in the company information file,"Пожалуйста, зарегистрируйте номер SIREN в файле информации о компании",
 Please remove this Invoice {0} from C-Form {1},"Пожалуйста, удалите этот счет {0} из C-Form {1}",
@@ -2067,9 +2067,9 @@
 Please select weekly off day,"Пожалуйста, выберите в неделю выходной",
 Please select {0},"Пожалуйста, выберите {0}",
 Please select {0} first,"Пожалуйста, выберите {0} первый",
-Please set 'Apply Additional Discount On',"Пожалуйста, установите &quot;Применить Дополнительная Скидка On &#39;",
+Please set 'Apply Additional Discount On',"Пожалуйста, установите &quot;Применить дополнительную скидку на &#39;",
 Please set 'Asset Depreciation Cost Center' in Company {0},"Пожалуйста, установите &quot;активов Амортизация затрат по МВЗ&quot; в компании {0}",
-Please set 'Gain/Loss Account on Asset Disposal' in Company {0},"Пожалуйста, установите &quot;прибыль / убыток Счет по обращению с отходами актива в компании {0}",
+Please set 'Gain/Loss Account on Asset Disposal' in Company {0},"Пожалуйста, установите &quot;прибыль / убыток Счет по лиду с отходами актива в компании {0}",
 Please set Account in Warehouse {0} or Default Inventory Account in Company {1},Укажите учетную запись в хранилище {0} или учетную запись инвентаризации по умолчанию в компании {1},
 Please set B2C Limit in GST Settings.,Установите B2C Limit в настройках GST.,
 Please set Company,Укажите компанию,
@@ -2133,9 +2133,9 @@
 Potential opportunities for selling.,Потенциальные возможности для продажи.,
 Practitioner Schedule,Расписание практикующих,
 Pre Sales,Предпродажа,
-Preference,предпочтение,
+Preference,Предпочтение,
 Prescribed Procedures,Предписанные процедуры,
-Prescription,давность,
+Prescription,Рецепт,
 Prescription Dosage,Дозировка по рецепту,
 Prescription Duration,Продолжительность рецепта,
 Prescriptions,Предписания,
@@ -2152,8 +2152,8 @@
 Price List must be applicable for Buying or Selling,Прайс-лист должен быть применим для покупки или продажи,
 Price List {0} is disabled or does not exist,Прайс-лист {0} отключен или не существует,
 Price or product discount slabs are required,Требуется цена или скидка на продукцию,
-Pricing,ценообразование,
-Pricing Rule,Цены Правило,
+Pricing,Ценообразование,
+Pricing Rule,Правила ценообразования,
 "Pricing Rule is first selected based on 'Apply On' field, which can be Item, Item Group or Brand.","Правило ценообразования сначала выбирается на основе поля «Применить на», значением которого может быть Позиция, Группа Позиций, Торговая Марка.",
 "Pricing Rule is made to overwrite Price List / define discount percentage, based on some criteria.","Правило ценообразования делается для того, чтобы изменить Прайс-лист / определить процент скидки, основанный на некоторых критериях.",
 Pricing Rule {0} is updated,Правило ценообразования {0} обновлено,
@@ -2171,8 +2171,8 @@
 Printing and Branding,Печать и брендинг,
 Private Equity,Частные капиталовложения,
 Privilege Leave,Привилегированный Оставить,
-Probation,испытательный срок,
-Probationary Period,Испытательный срок,
+Probation,Испытательный срок,
+Probationary Period,Испытательный период,
 Procedure,Процедура,
 Process Day Book Data,Обработка данных дневника,
 Process Master Data,Обработка основных данных,
@@ -2193,12 +2193,12 @@
 Program,программа,
 Program in the Fee Structure and Student Group {0} are different.,Программа в структуре вознаграждения и студенческой группе {0} отличается.,
 Program {0} does not exist.,Программа {0} не существует.,
-Program: ,Программа:,
+Program: ,Программа: ,
 Progress % for a task cannot be more than 100.,Готовность задачи не может превышать 100%.,
 Project Collaboration Invitation,Сотрудничество Приглашение проекта,
 Project Id,Идентификатор проекта,
 Project Manager,Менеджер проектов,
-Project Name,название проекта,
+Project Name,Название проекта,
 Project Start Date,Дата начала проекта,
 Project Status,Статус проекта,
 Project Summary for {0},Краткое описание проекта для {0},
@@ -2239,12 +2239,12 @@
 Purchase Orders are not allowed for {0} due to a scorecard standing of {1}.,"Заказы на поставку не допускаются для {0} из-за того, что система показателей имеет значение {1}.",
 Purchase Orders given to Suppliers.,"Заказы, выданные поставщикам.",
 Purchase Price List,Прайс-лист закупки,
-Purchase Receipt,Товарный чек,
+Purchase Receipt,Квитанция о покупке,
 Purchase Receipt {0} is not submitted,Приход закупки {0} не проведен,
 Purchase Tax Template,Налог на покупку шаблон,
 Purchase User,Специалист поставок,
 Purchase orders help you plan and follow up on your purchases,Заказы помогут вам планировать и следить за ваши покупки,
-Purchasing,покупка,
+Purchasing,Покупка,
 Purpose must be one of {0},Цель должна быть одна из {0},
 Qty,Кол-во,
 Qty To Manufacture,Кол-во для производства,
@@ -2276,8 +2276,8 @@
 Queued for replacing the BOM. It may take a few minutes.,Очередь на замену спецификации. Это может занять несколько минут.,
 Queued for updating latest price in all Bill of Materials. It may take a few minutes.,Очередь для обновления последней цены во всех Биллях материалов. Это может занять несколько минут.,
 Quick Journal Entry,Быстрый журнал запись,
-Quot Count,Количество котировок,
-Quot/Lead %,"Предложения/Обращения, %",
+Quot Count,Количество предложений,
+Quot/Lead %,"Предложения/Лиды, %",
 Quotation,Предложение,
 Quotation {0} is cancelled,Предложение {0} отменено,
 Quotation {0} not of type {1},Предложение {0} не типа {1},
@@ -2285,7 +2285,7 @@
 "Quotations are proposals, bids you have sent to your customers","Предложения - это коммерческие предложения, которые вы отправили своим клиентам",
 Quotations received from Suppliers.,"Предложения, полученные от Поставщиков.",
 Quotations: ,Предложения:,
-Quotes to Leads or Customers.,Предложения Обращениям или Клиентам.,
+Quotes to Leads or Customers.,Предложения в Лиды или Клиентов.,
 RFQs are not allowed for {0} due to a scorecard standing of {1},"Запросы не допускаются для {0} из-за того, что значение показателя {1}",
 Range,Диапазон,
 Rate,Цена,
@@ -2303,7 +2303,7 @@
 Reason for Hold,Причина удержания,
 Reason for hold: ,Причина удержания:,
 Receipt,Квитанция,
-Receipt document must be submitted,Документ о получении должен быть проведен,
+Receipt document must be submitted,Документ о получении должен быть исполнен,
 Receivable,Дебиторская задолженность,
 Receivable Account,Счет Дебиторской задолженности,
 Received,Получено,
@@ -2316,7 +2316,7 @@
 "Record of all communications of type email, phone, chat, visit, etc.","Запись всех способов коммуникации — электронной почты, звонков, чатов, посещений и т. п.",
 Records,Записи,
 Redirect URL,Перенаправление URL,
-Ref,ссылка,
+Ref,Ссылка,
 Ref Date,Дата ссылки,
 Reference,Справка,
 Reference #{0} dated {1},Ссылка №{0} от {1},
@@ -2333,17 +2333,17 @@
 Reference Type,Тип ссылки,
 "Reference: {0}, Item Code: {1} and Customer: {2}","Ссылка: {0}, Код товара: {1} и Заказчик: {2}",
 References,Рекомендации,
-Refresh Token,токен обновления,
+Refresh Token,Токен обновления,
 Region,Область,
-Register,регистр,
-Reject,отклонять,
+Register,Регистр,
+Reject,Отклонить,
 Rejected,Отклоненные,
 Related,Связанный,
 Relation with Guardian1,Связь с Guardian1,
 Relation with Guardian2,Связь с Guardian2,
 Release Date,Дата выпуска,
 Reload Linked Analysis,Обновить связанный анализ,
-Remaining,осталось,
+Remaining,Осталось,
 Remaining Balance,Остаток средств,
 Remarks,Примечания,
 Reminder to update GSTIN Sent,Напоминание об обновлении отправленного GSTIN,
@@ -2373,9 +2373,9 @@
 "Requested Qty: Quantity requested for purchase, but not ordered.","Запрашиваемые Кол-во: Количество просил для покупки, но не заказали.",
 Requesting Site,Запрашивающий сайт,
 Requesting payment against {0} {1} for amount {2},Запрос платеж против {0} {1} на сумму {2},
-Requestor,Requestor,
-Required On,Обязательно На,
-Required Qty,Обязательные Кол-во,
+Requestor,Заявитель,
+Required On,Требуется на,
+Required Qty,Требуемое количество,
 Required Quantity,Необходимое количество,
 Reschedule,Перепланирование,
 Research,Исследования,
@@ -2393,7 +2393,7 @@
 Reserved for sub contracting,Зарезервировано для субподряда,
 Resistant,резистентный,
 Resolve error and upload again.,Устраните ошибку и загрузите снова.,
-Responsibilities,обязанности,
+Responsibilities,Обязанности,
 Rest Of The World,Остальной мир,
 Restart Subscription,Перезапустить подписку,
 Restaurant,Ресторан,
@@ -2411,18 +2411,18 @@
 Return / Debit Note,Возврат / дебетовые Примечание,
 Returns,Возвращает,
 Reverse Journal Entry,Обратная запись журнала,
-Review Invitation Sent,Отправлено приглашение на просмотр,
+Review Invitation Sent,Отправлено приглашение на рассмотрение,
 Review and Action,Обзор и действие,
 Role,Роль,
 Rooms Booked,Забронированные номера,
-Root Company,Корневая Компания,
+Root Company,Родительская компания,
 Root Type,Корневая Тип,
 Root Type is mandatory,Корневая Тип является обязательным,
 Root cannot be edited.,Корневая не могут быть изменены.,
 Root cannot have a parent cost center,Корневая не может иметь родителей МВЗ,
 Round Off,Округлять,
-Rounded Total,Округлые Всего,
-Route,маршрут,
+Rounded Total,Итого с округлением,
+Route,Маршрут,
 Row # {0}: ,Ряд # {0}:,
 Row # {0}: Batch No must be same as {1} {2},"Ряд # {0}: Пакетное Нет должно быть таким же, как {1} {2}",
 Row # {0}: Cannot return more than {1} for Item {2},Ряд # {0}: Невозможно вернуть более {1} для п {2},
@@ -2507,7 +2507,7 @@
 Salary Slip ID,Зарплата скольжения ID,
 Salary Slip of employee {0} already created for this period,Зарплата Скольжение работника {0} уже создано за этот период,
 Salary Slip of employee {0} already created for time sheet {1},Зарплата Скольжение работника {0} уже создан для табеля {1},
-Salary Slip submitted for period from {0} to {1},"Зарплатный сальс, представленный на период от {0} до {1}",
+Salary Slip submitted for period from {0} to {1},"Зарплатная ведомость отправлена за период с {0} по {1}",
 Salary Structure Assignment for Employee already exists,Присвоение структуры зарплаты сотруднику уже существует,
 Salary Structure Missing,Структура заработной платы Отсутствующий,
 Salary Structure must be submitted before submission of Tax Ememption Declaration,Структура заработной платы должна быть представлена до подачи декларации об освобождении от налогов,
@@ -2583,7 +2583,7 @@
 See All Articles,Просмотреть все статьи,
 See all open tickets,Просмотреть все открытые билеты,
 See past orders,Посмотреть прошлые заказы,
-See past quotations,Посмотреть прошлые цитаты,
+See past quotations,Посмотреть прошлые предложения,
 Select,Выбрать,
 Select Alternate Item,Выбрать альтернативный элемент,
 Select Attribute Values,Выберите значения атрибута,
@@ -2624,16 +2624,16 @@
 Select your Domains,Выберите свои домены,
 Selected Price List should have buying and selling fields checked.,Выбранный прейскурант должен иметь поля для покупки и продажи.,
 Sell,Продажа,
-Selling,продажа,
-Selling Amount,Продажа Сумма,
+Selling,Продажа,
+Selling Amount,Сумма продажа,
 Selling Price List,Продажа прайс-листа,
 Selling Rate,Стоимость продажи,
 "Selling must be checked, if Applicable For is selected as {0}","Продажа должна быть проверена, если выбран Применимо для как {0}",
 Send Grant Review Email,Отправить отзыв по электронной почте,
-Send Now,Отправить Сейчас,
+Send Now,Отправить сейчас,
 Send SMS,Отправить смс,
 Send mass SMS to your contacts,Отправить массовое СМС по списку контактов,
-Sensitivity,чувствительность,
+Sensitivity,Чувствительность,
 Sent,Отправлено,
 Serial No and Batch,Серийный номер и партия,
 Serial No is mandatory for Item {0},Серийный номер является обязательным для п. {0},
@@ -2673,12 +2673,12 @@
 Set New Release Date,Установите новую дату выпуска,
 Set Project and all Tasks to status {0}?,Установить проект и все задачи в статус {0}?,
 Set Status,Установить статус,
-Set Tax Rule for shopping cart,Установите Налоговый Правило корзине,
-Set as Closed,Установить как Закрыт,
+Set Tax Rule for shopping cart,Установить налоговое правило для корзины,
+Set as Closed,Установить как "Закрыт",
 Set as Completed,Сделать завершенным,
 Set as Default,Установить по умолчанию,
-Set as Lost,Установить как Остаться в живых,
-Set as Open,Установить как Open,
+Set as Lost,Установить как "Потерянный",
+Set as Open,Установить как "Открытый",
 Set default inventory account for perpetual inventory,Установить учетную запись по умолчанию для вечной инвентаризации,
 Set this if the customer is a Public Administration company.,"Установите это, если клиент является компанией государственного управления.",
 Set {0} in asset category {1} or company {2},Установите {0} в категории активов {1} или компании {2},
@@ -2687,9 +2687,9 @@
 Setting up Email,Настройка электронной почты,
 Setting up Email Account,Настройка учетной записи электронной почты,
 Setting up Employees,Настройка сотрудников,
-Setting up Taxes,Настройка Налоги,
+Setting up Taxes,Настройка налога,
 Setting up company,Создание компании,
-Settings,настройки,
+Settings,Настройки,
 "Settings for online shopping cart such as shipping rules, price list etc.","Настройки для онлайн корзины, такие как правилами перевозок, прайс-лист и т.д.",
 Settings for website homepage,Настройки для сайта домашнюю страницу,
 Settings for website product listing,Настройки для списка товаров на сайте,
@@ -2701,11 +2701,11 @@
 Setup mode of POS (Online / Offline),Режим настройки POS (Online / Offline),
 Setup your Institute in ERPNext,Установите свой институт в ERPNext,
 Share Balance,Баланс акций,
-Share Ledger,Share Ledger,
+Share Ledger,Поделиться записями,
 Share Management,Управление долями,
 Share Transfer,Передача акций,
 Share Type,Share Тип,
-Shareholder,акционер,
+Shareholder,Акционер,
 Ship To State,Корабль в штат,
 Shipments,Поставки,
 Shipping,Доставка,
@@ -2715,17 +2715,17 @@
 Shipping rule only applicable for Selling,Правило доставки применимо только для продажи,
 Shopify Supplier,Покупатель,
 Shopping Cart,Корзина,
-Shopping Cart Settings,Корзина Настройки,
-Short Name,Короткое Имя,
+Shopping Cart Settings,Настройки корзины,
+Short Name,Короткое имя,
 Shortage Qty,Нехватка Кол-во,
-Show Completed,Показать выполнено,
+Show Completed,Показать завершенные,
 Show Cumulative Amount,Показать суммарную сумму,
 Show Employee,Показать сотрудника,
-Show Open,Показать открыт,
+Show Open,Показать открытые,
 Show Opening Entries,Показать вступительные записи,
 Show Payment Details,Показать данные платежа,
 Show Return Entries,Показать возвращенные записи,
-Show Salary Slip,Показать Зарплата скольжению,
+Show Salary Slip,Показать зарплатную ведомость,
 Show Variant Attributes,Показать атрибуты варианта,
 Show Variants,Показать варианты,
 Show closed,Показать закрыто,
@@ -2787,14 +2787,14 @@
 Stock Adjustment,Регулирование запасов,
 Stock Analytics,Аналитика запасов,
 Stock Assets,Капитал запасов,
-Stock Available,Имеется в наличии,
+Stock Available,Есть в наличии,
 Stock Balance,Баланс запасов,
 Stock Entries already created for Work Order ,"Записи запаса, уже созданные для рабочего заказа",
 Stock Entry,Движения на складе,
 Stock Entry {0} created,Создана складская запись {0},
 Stock Entry {0} is not submitted,Складской акт {0} не проведен,
 Stock Expenses,Расходы по Запасам,
-Stock In Hand,Товарная наличность,
+Stock In Hand,Запасы на руках,
 Stock Items,Позиции на складе,
 Stock Ledger,Книга учета Запасов,
 Stock Ledger Entries and GL Entries are reposted for the selected Purchase Receipts,Записи складской книги и записи GL запасов отправляются для выбранных покупок,
@@ -2816,7 +2816,7 @@
 Stop,Стоп,
 Stopped,Приостановлено,
 "Stopped Work Order cannot be cancelled, Unstop it first to cancel","Прекращенный рабочий заказ не может быть отменен, отмените его сначала, чтобы отменить",
-Stores,магазины,
+Stores,Магазины,
 Structures have been assigned successfully,Структуры были успешно назначены,
 Student,Студент,
 Student Activity,Студенческая деятельность,
@@ -2833,7 +2833,7 @@
 Student ID,Студенческий билет,
 Student ID: ,Студенческий билет:,
 Student LMS Activity,Студенческая LMS Активность,
-Student Mobile No.,Student Mobile No.,
+Student Mobile No.,Мобильный номер студента,
 Student Name,Имя ученика,
 Student Name: ,Имя ученика:,
 Student Report Card,Студенческая отчетная карточка,
@@ -2845,7 +2845,7 @@
 Sub Assemblies,Sub сборки,
 Sub Type,Подтип,
 Sub-contracting,Суб-сжимания,
-Subcontract,субподряд,
+Subcontract,Субподряд,
 Subject,Тема,
 Submit,Провести,
 Submit Proof,Подтвердить,
@@ -2891,7 +2891,7 @@
 Support,Поддержка,
 Support Analytics,Аналитика поддержки,
 Support Settings,Настройки поддержки,
-Support Tickets,Билеты на поддержку,
+Support Tickets,Заявки на поддержку,
 Support queries from customers.,Поддержка запросов от клиентов.,
 Susceptible,восприимчивый,
 Sync has been temporarily disabled because maximum retries have been exceeded,"Синхронизация временно отключена, поскольку превышены максимальные повторные попытки",
@@ -2900,21 +2900,21 @@
 System Manager,Менеджер системы,
 TDS Rate %,TDS Rate%,
 Tap items to add them here,"Выберите продукты, чтобы добавить их",
-Target,цель,
+Target,Цель,
 Target ({}),Цель ({}),
 Target On,Целевая На,
 Target Warehouse,Склад готовой продукции,
 Target warehouse is mandatory for row {0},Целевая склад является обязательным для ряда {0},
-Task,задача,
+Task,Задача,
 Tasks,Задачи,
 Tasks have been created for managing the {0} disease (on row {1}),Задачи были созданы для управления {0} болезнью (в строке {1}),
-Tax,налог,
+Tax,Налог,
 Tax Assets,Налоговые активы,
 Tax Category,Налоговая категория,
 Tax Category for overriding tax rates.,Налоговая категория для переопределения налоговых ставок.,
 "Tax Category has been changed to ""Total"" because all the Items are non-stock items","Налоговая категория была изменена на «Итого», потому что все элементы не являются складскими запасами",
 Tax ID,ИНН,
-Tax Id: ,Идентификатор налога:,
+Tax Id: ,Идентификатор налога: ,
 Tax Rate,Размер налога,
 Tax Rule Conflicts with {0},Налоговый Правило конфликты с {0},
 Tax Rule for transactions.,Налоговый Правило для сделок.,
@@ -2924,13 +2924,13 @@
 Tax template for item tax rates.,Налоговый шаблон для налоговых ставок.,
 Tax template for selling transactions.,Налоговый шаблон для продажи сделок.,
 Taxable Amount,Налогооблагаемая сумма,
-Taxes,налоги,
+Taxes,Налоги,
 Team Updates,Команда обновления,
 Technology,Технология,
 Telecommunications,Телекоммуникации,
 Telephone Expenses,Телефон Расходы,
-Television,телевидение,
-Template Name,Имя Шаблона,
+Television,Телевидение,
+Template Name,Название шаблона,
 Template of terms or contract.,Шаблон терминов или договором.,
 Templates of supplier scorecard criteria.,Шаблоны критериев оценки поставщиков.,
 Templates of supplier scorecard variables.,Шаблоны переменных показателей поставщика.,
@@ -2974,7 +2974,7 @@
 "The task has been enqueued as a background job. In case there is any issue on processing in background, the system will add a comment about the error on this Stock Reconciliation and revert to the Draft stage",Задача была поставлена в качестве фонового задания. В случае возникновения каких-либо проблем с обработкой в фоновом режиме система добавит комментарий об ошибке в этой сверке запасов и вернется к этапу черновика.,
 "Then Pricing Rules are filtered out based on Customer, Customer Group, Territory, Supplier, Supplier Type, Campaign, Sales Partner etc.","Затем Правила ценообразования отфильтровываются на основе Клиента, Группы клиентов, Территории, Поставщика, Типа поставщика, Кампании, Партнера по продажам и т. д.",
 "There are inconsistencies between the rate, no of shares and the amount calculated","Существуют несоответствия между ставкой, количеством акций и рассчитанной суммой",
-There are more holidays than working days this month.,"Есть больше праздников, чем рабочих дней в этом месяце.",
+There are more holidays than working days this month.,"В этом месяце праздников больше, чем рабочих дней.",
 There can be multiple tiered collection factor based on the total spent. But the conversion factor for redemption will always be same for all the tier.,"Может быть многоуровневый коэффициент сбора, основанный на общей затрате. Но коэффициент пересчета для погашения всегда будет одинаковым для всех уровней.",
 There can only be 1 Account per Company in {0} {1},Там может быть только 1 аккаунт на компанию в {0} {1},
 "There can only be one Shipping Rule Condition with 0 or blank value for ""To Value""","Там может быть только один Правило Начальные с 0 или пустое значение для ""To Размер""",
@@ -2992,18 +2992,18 @@
 This action will stop future billing. Are you sure you want to cancel this subscription?,Это действие остановит будущий биллинг. Вы действительно хотите отменить эту подписку?,
 This covers all scorecards tied to this Setup,"Это охватывает все оценочные карточки, привязанные к этой настройке",
 This document is over limit by {0} {1} for item {4}. Are you making another {3} against the same {2}?,Этот документ находится над пределом {0} {1} для элемента {4}. Вы делаете другой {3} против того же {2}?,
-This is a root account and cannot be edited.,Это корень счета и не могут быть изменены.,
+This is a root account and cannot be edited.,Это корень счетов и не может быть изменен.,
 This is a root customer group and cannot be edited.,Это корневая группа клиентов и не могут быть изменены.,
 This is a root department and cannot be edited.,Это корневой отдел и не может быть отредактирован.,
 This is a root healthcare service unit and cannot be edited.,Это корневая служба здравоохранения и не может быть отредактирована.,
-This is a root item group and cannot be edited.,Это корень группу товаров и не могут быть изменены.,
-This is a root sales person and cannot be edited.,Это корень продавец и не могут быть изменены.,
+This is a root item group and cannot be edited.,Это корень группы продуктов и не может быть изменен.,
+This is a root sales person and cannot be edited.,Это корневой продавец и не может быть изменен.,
 This is a root supplier group and cannot be edited.,Это группа поставщиков корней и не может быть отредактирована.,
-This is a root territory and cannot be edited.,Это корень территории и не могут быть изменены.,
+This is a root territory and cannot be edited.,Это корневая территория и не может быть изменена.,
 This is an example website auto-generated from ERPNext,Это пример сайт автоматически сгенерированный из ERPNext,
-This is based on logs against this Vehicle. See timeline below for details,Это основано на бревнах против этого транспортного средства. См график ниже для получения подробной информации,
+This is based on logs against this Vehicle. See timeline below for details,Это основано на журналах для этого транспортного средства. Смотрите график ниже для деталей,
 This is based on stock movement. See {0} for details,Это основано на фондовом движении. См {0} для получения более подробной,
-This is based on the Time Sheets created against this project,"Это основано на табелей учета рабочего времени, созданных против этого проекта",
+This is based on the Time Sheets created against this project,"Это основано на табелях учета рабочего времени, созданных по этому проекту",
 This is based on the attendance of this Employee,Это основано на посещаемости этого сотрудника,
 This is based on the attendance of this Student,Это основано на посещаемости этого студента,
 This is based on transactions against this Customer. See timeline below for details,Это основано на операциях против этого клиента. См график ниже для получения подробной информации,
@@ -3018,15 +3018,15 @@
 "Time slot skiped, the slot {0} to {1} overlap exisiting slot {2} to {3}","Временной интервал пропущен, слот {0} - {1} перекрывает существующий слот {2} до {3}",
 Time slots added,Добавлены временные интервалы,
 Time(in mins),Время (в мин),
-Timer,таймер,
+Timer,Таймер,
 Timer exceeded the given hours.,Таймер превысил указанные часы.,
-Timesheet,табель,
+Timesheet,Табель,
 Timesheet for tasks.,Табель для задач.,
 Timesheet {0} is already completed or cancelled,Табель {0} уже заполнен или отменен,
 Timesheets,Табели,
 "Timesheets help keep track of time, cost and billing for activites done by your team","Timesheets поможет отслеживать время, стоимость и выставление счетов для Активности сделанной вашей команды",
 Titles for print templates e.g. Proforma Invoice.,"Титулы для шаблонов печати, например, счет-проформа.",
-To,к,
+To,К,
 To Address 1,Адрес 1,
 To Address 2,Адрес 2,
 To Bill,Укомплектован,
@@ -3034,7 +3034,7 @@
 To Date cannot be before From Date,На сегодняшний день не может быть раньше от даты,
 To Date cannot be less than From Date,"Дата не может быть меньше, чем с даты",
 To Date must be greater than From Date,"До даты должно быть больше, чем с даты",
-To Date should be within the Fiscal Year. Assuming To Date = {0},Чтобы Дата должна быть в пределах финансового года. Предполагая To Date = {0},
+To Date should be within the Fiscal Year. Assuming To Date = {0},Дата должна быть в пределах финансового года. Предположим, до даты = {0},
 To Datetime,Для DateTime,
 To Deliver,Для доставки,
 To Deliver and Bill,Для доставки и оплаты,
@@ -3061,7 +3061,7 @@
 To view logs of Loyalty Points assigned to a Customer.,"Просмотр журналов лояльности, назначенных Клиенту.",
 To {0},Для {0},
 To {0} | {1} {2},Для {0} | {1} {2},
-Toggle Filters,Toggle Filters,
+Toggle Filters,Изменить фильтры,
 Too many columns. Export the report and print it using a spreadsheet application.,Слишком много столбцов. Экспортируйте отчет и распечатайте его с помощью приложения для электронных таблиц.,
 Tools,Инструменты,
 Total (Credit),Итого (кредит),
@@ -3079,10 +3079,10 @@
 Total Contribution Amount: {0},Общая сумма вклада: {0},
 Total Credit/ Debit Amount should be same as linked Journal Entry,"Общая сумма кредита / дебетовой суммы должна быть такой же, как связанная запись журнала",
 Total Debit must be equal to Total Credit. The difference is {0},"Всего Дебет должна быть равна общей выработке. Разница в том, {0}",
-Total Deduction,Всего Вычет,
-Total Invoiced Amount,Всего Сумма по счетам,
+Total Deduction,Общий вычет,
+Total Invoiced Amount,Общая сумма по счетам,
 Total Leaves,Всего Листья,
-Total Order Considered,Итоговый заказ считается,
+Total Order Considered,Всего рассмотренных заказов,
 Total Order Value,Общая стоимость заказа,
 Total Outgoing,Всего исходящих,
 Total Outstanding,Всего выдающихся,
@@ -3092,12 +3092,12 @@
 Total Payment Amount in Payment Schedule must be equal to Grand / Rounded Total,Общая сумма платежа в Графе платежей должна быть равна Grand / Rounded Total,
 Total Payments,Всего платежей,
 Total Present,Итого Текущая,
-Total Qty,Всего кол-во,
+Total Qty,Общее количество,
 Total Quantity,Общая численность,
 Total Revenue,Общий доход,
 Total Student,Всего учеников,
 Total Target,Всего Target,
-Total Tax,Совокупная налоговая,
+Total Tax,Совокупный налог,
 Total Taxable Amount,Общая сумма налогооблагаемой суммы,
 Total Taxable Value,Общая налогооблагаемая стоимость,
 Total Unpaid: {0},Общая сумма невыплаченных: {0},
@@ -3121,33 +3121,33 @@
 Total(Qty),Всего (кол-во),
 Traceability,прослеживаемость,
 Traceback,Диагностика,
-Track Leads by Lead Source.,Отслеживать Обращения по Источнику.,
+Track Leads by Lead Source.,Отслеживать лидов по источнику.,
 Training,Обучение,
 Training Event,Учебное мероприятие,
 Training Events,Учебные мероприятия,
 Training Feedback,Обучение Обратная связь,
 Training Result,Результат обучения,
 Transaction,Транзакция,
-Transaction Date,Сделка Дата,
+Transaction Date,Дата транзакции,
 Transaction Type,Тип операции,
 Transaction currency must be same as Payment Gateway currency,"Валюта сделки должна быть такой же, как платежный шлюз валюты",
 Transaction not allowed against stopped Work Order {0},Транзакция не разрешена против прекращенного рабочего заказа {0},
 Transaction reference no {0} dated {1},Референция сделка не {0} от {1},
-Transactions,операции,
+Transactions,Транзакции,
 Transactions can only be deleted by the creator of the Company,Сделки могут быть удалены только создателем компании,
-Transfer,Переложить,
+Transfer,Передача,
 Transfer Material,О передаче материала,
 Transfer Type,Тип передачи,
 Transfer an asset from one warehouse to another,Передача актива с одного склада на другой,
 Transfered,Все передаваемые,
 Transferred Quantity,Переданное количество,
 Transport Receipt Date,Дата получения транспортного сообщения,
-Transport Receipt No,Транспортная квитанция Нет,
+Transport Receipt No,Транспортная квитанция №,
 Transportation,Транспортировка,
 Transporter ID,Идентификатор транспортника,
 Transporter Name,Название транспорта,
 Travel,Путешествия,
-Travel Expenses,Командировочные Pасходы,
+Travel Expenses,Командировочные расходы,
 Tree Type,Дерево Тип,
 Tree of Bill of Materials,Дерево Билла материалов,
 Tree of Item Groups.,Структура продуктовых групп,
@@ -3181,11 +3181,11 @@
 Unsubscribed,Отписался,
 Until,До,
 Unverified Webhook Data,Непроверенные данные Webhook,
-Update Account Name / Number,Обновить имя учетной записи / номер,
-Update Account Number / Name,Обновить номер / имя учетной записи,
-Update Cost,Обновление Стоимость,
+Update Account Name / Number,Обновить имя / номер счета,
+Update Account Number / Name,Обновить номер / имя счета,
+Update Cost,Обновить стоимость,
 Update Items,Обновить элементы,
-Update Print Format,Обновление Формат печати,
+Update Print Format,Обновить формат печати,
 Update Response,Обновить ответ,
 Update bank payment dates with journals.,Обновление банк платежные даты с журналов.,
 Update in progress. It might take a while.,Идет обновление. Это может занять некоторое время.,
@@ -3196,7 +3196,7 @@
 Upper Income,Высокий уровень дохода,
 Use Sandbox,Использовать «песочницу»,
 Used Leaves,Используемые листы,
-User,пользователь,
+User,Пользователь,
 User ID,ID пользователя,
 User ID not set for Employee {0},ID пользователя не установлен для сотрудника {0},
 User Remark,Примечание Пользователь,
@@ -3225,7 +3225,7 @@
 Value missing,Недостающее значение,
 Value must be between {0} and {1},Значение должно быть между {0} и {1},
 "Values of exempt, nil rated and non-GST inward supplies","Значения льготных, нулевых и не связанных с GST внутренних поставок",
-Variable,переменная,
+Variable,Переменная,
 Variance,Дисперсия,
 Variance ({}),Дисперсия ({}),
 Variant,Вариант,
@@ -3242,7 +3242,7 @@
 View Fees Records,Посмотреть рекорды,
 View Form,Посмотреть форму,
 View Lab Tests,Просмотр лабораторных тестов,
-View Leads,Посмотреть Обращения,
+View Leads,Посмотреть лиды,
 View Ledger,Посмотреть Леджер,
 View Now,Просмотр сейчас,
 View a list of all the help videos,Просмотреть список всех справочных видео,
@@ -3250,12 +3250,12 @@
 Visit report for maintenance call.,Посетите отчет за призыв обслуживания.,
 Visit the forums,Посетите форумы,
 Vital Signs,Жизненно важные признаки,
-Volunteer,доброволец,
+Volunteer,Волонтер,
 Volunteer Type information.,Информация о волонтере.,
 Volunteer information.,Информация о волонтерах.,
 Voucher #,Ваучер #,
 Voucher No,Ваучер №,
-Voucher Type,Ваучер Тип,
+Voucher Type,Тип ваучера,
 WIP Warehouse,WIP Склад,
 Walk In,Прогулка в,
 Warehouse can not be deleted as stock ledger entry exists for this warehouse.,"Склад не может быть удалён, так как существует запись в складкой книге  этого склада.",
@@ -3263,7 +3263,7 @@
 Warehouse is mandatory,Склад является обязательным,
 Warehouse is mandatory for stock Item {0} in row {1},Склад является обязательным для Запаса {0} в строке {1},
 Warehouse not found in the system,Склад не найден в системе,
-"Warehouse required at Row No {0}, please set default warehouse for the item {1} for the company {2}","Требуется хранилище в строке «Нет» {0}, пожалуйста, установите для хранилища по умолчанию для товара {1} для компании {2}",
+"Warehouse required at Row No {0}, please set default warehouse for the item {1} for the company {2}","Требуется хранилище в строке № {0}, пожалуйста, установите для хранилища по умолчанию для товара {1} для компании {2}",
 Warehouse required for stock Item {0},Требуется Склад для Запаса {0},
 Warehouse {0} can not be deleted as quantity exists for Item {1},Склад {0} не может быть удален как существует количество для Пункт {1},
 Warehouse {0} does not belong to company {1},Склад {0} не принадлежит компания {1},
@@ -3299,7 +3299,7 @@
 What do you need help with?,Как я могу вам помочь?,
 What does it do?,Что оно делает?,
 Where manufacturing operations are carried.,Где производственные операции проводятся.,
-White,белый,
+White,Белый,
 Wire Transfer,Банковский перевод,
 WooCommerce Products,Продукты WooCommerce,
 Work In Progress,Незавершенная работа,
@@ -3313,11 +3313,11 @@
 Work Orders Created: {0},Созданы рабочие задания: {0},
 Work Summary for {0},Резюме работы для {0},
 Work-in-Progress Warehouse is required before Submit,Работа-в-Прогресс Склад требуется перед Отправить,
-Workflow,Поток,
+Workflow, Рабочий процесс,
 Working,Работающий,
 Working Hours,Часы работы,
-Workstation,рабочая станция,
-Workstation is closed on the following dates as per Holiday List: {0},Рабочая станция закрыта в следующие сроки согласно Список праздников: {0},
+Workstation,Рабочая станция,
+Workstation is closed on the following dates as per Holiday List: {0},Рабочая станция закрыта в следующие даты согласно списка праздников: {0},
 Wrapping up,Завершение,
 Wrong Password,Неправильный пароль,
 Year start date or end date is overlapping with {0}. To avoid please set company,"Год дата начала или дата окончания перекрывается с {0}. Чтобы избежать, пожалуйста, установите компанию",
@@ -3353,7 +3353,7 @@
 Your cart is Empty,Ваша корзина пуста,
 Your email address...,Ваш адрес электронной почты...,
 Your order is out for delivery!,Ваш заказ для доставки!,
-Your tickets,Ваши билеты,
+Your tickets,Ваши заявки,
 ZIP Code,Почтовый индекс,
 [Error],[Ошибка],
 [{0}](#Form/Item/{0}) is out of stock,[{0}](#Form/Item/{0}) нет в наличии,
@@ -3364,10 +3364,10 @@
 "e.g. ""Build tools for builders""","например ""Построить инструменты для строителей """,
 "e.g. ""Primary School"" or ""University""","например, &quot;Начальная школа&quot; или &quot;Университет&quot;",
 "e.g. Bank, Cash, Credit Card","например банк, наличные, кредитная карта",
-hidden,Скрытый,
+hidden,скрытый,
 modified,модифицированный,
 old_parent,old_parent,
-on,Вкл,
+on,вкл,
 {0} '{1}' is disabled,{0} '{1}' отключен,
 {0} '{1}' not in Fiscal Year {2},{0} '{1}' не в {2} Финансовом году,
 {0} ({1}) cannot be greater than planned quantity ({2}) in Work Order {3},{0} ({1}) не может быть больше запланированного количества ({2}) в рабочем порядке {3},
@@ -3389,7 +3389,7 @@
 {0} applicable after {1} working days,{0} применимо после {1} рабочих дней,
 {0} asset cannot be transferred,{0} актив не может быть перемещён,
 {0} can not be negative,{0} не может быть отрицательным,
-{0} created,Создано {0},
+{0} created,{0} создано,
 "{0} currently has a {1} Supplier Scorecard standing, and Purchase Orders to this supplier should be issued with caution.","{0} в настоящее время имеет {1} систему показателей поставщика, и Заказы на поставку этому поставщику должны выдаваться с осторожностью.",
 "{0} currently has a {1} Supplier Scorecard standing, and RFQs to this supplier should be issued with caution.","{0} в настоящее время имеет {1} систему показателей поставщика, и RFQ для этого поставщика должны выдаваться с осторожностью.",
 {0} does not belong to Company {1},{0} не принадлежит компании {1},
@@ -3469,8 +3469,8 @@
 Assigned To,Назначено для,
 Chat,Чат,
 Completed By,Завершено,
-Conditions,условия,
-County,округ,
+Conditions,Условия,
+County,Округ,
 Day of Week,День недели,
 "Dear System Manager,","Уважаемый Менеджер системы,",
 Default Value,Значение по умолчанию,
@@ -3483,11 +3483,11 @@
 ID,ID,
 Images,Изображении,
 Import,Импорт,
-Language,язык,
-Likes,Понравившееся,
+Language,Язык,
+Likes,Лайки,
 Merge with existing,Слияние с существующими,
 Office,Офис,
-Orientation,ориентация,
+Orientation,Ориентация,
 Parent,Родитель,
 Passive,Пассивный,
 Payment Failed,Платеж не прошел,
@@ -3499,25 +3499,25 @@
 Postal,Почтовый,
 Postal Code,Почтовый индекс,
 Previous,Предыдущая,
-Provider,поставщик,
+Provider,Поставщик,
 Read Only,Только чтения,
 Recipient,Сторона-реципиент,
 Reviews,Отзывы,
 Sender,Отправитель,
 Shop,Магазин,
-Sign Up,Подписаться,
+Sign Up,Регистрация,
 Subsidiary,Филиал,
 There is some problem with the file url: {0},Существует некоторая проблема с файловой URL: {0},
 There were errors while sending email. Please try again.,"При отправке электронной почты возникли ошибки. Пожалуйста, попробуйте ещё раз.",
-Values Changed,Значения Изменено,
+Values Changed,Значения изменено,
 or,или,
 Ageing Range 4,Диапазон старения 4,
 Allocated amount cannot be greater than unadjusted amount,Выделенная сумма не может быть больше нескорректированной,
 Allocated amount cannot be negative,Выделенная сумма не может быть отрицательной,
 "Difference Account must be a Asset/Liability type account, since this Stock Entry is an Opening Entry","Разница счета должна быть учетной записью типа актива / пассива, так как эта запись акции является вводной",
 Error in some rows,Ошибка в некоторых строках,
-Import Successful,Импорт успешен,
-Please save first,"Пожалуйста, сохраните сначала",
+Import Successful,Импорт успешно завершен,
+Please save first,"Пожалуйста, сначала сохраните",
 Price not found for item {0} in price list {1},Цена не найдена для товара {0} в прайс-листе {1},
 Warehouse Type,Тип склада,
 'Date' is required,Требуется дата,
@@ -3535,7 +3535,7 @@
 Quality Feedback,Отзыв о качестве,
 Quality Feedback Template,Шаблон обратной связи по качеству,
 Rules for applying different promotional schemes.,Правила применения разных рекламных схем.,
-Shift,сдвиг,
+Shift,Сдвиг,
 Show {0},Показать {0},
 "Special Characters except ""-"", ""#"", ""."", ""/"", ""{"" and ""}"" not allowed in naming series","Специальные символы, кроме &quot;-&quot;, &quot;#&quot;, &quot;.&quot;, &quot;/&quot;, &quot;{&quot; И &quot;}&quot;, не допускаются в именных сериях",
 Target Details,Детали цели,
@@ -3546,21 +3546,21 @@
 Change,Изменение,
 Contact Email,Эл.почта для связи,
 Export Type,Тип экспорта,
-From Date,С,
+From Date,С даты,
 Group By,Группа по,
 Importing {0} of {1},Импорт {0} из {1},
 Invalid URL,неправильный адрес,
-Landscape,Пейзаж,
+Landscape,Альбомный,
 Last Sync On,Последняя синхронизация,
 Naming Series,Идентификация по Имени,
 No data to export,Нет данных для экспорта,
-Portrait,Портрет,
+Portrait,Портретный,
 Print Heading,Распечатать Заголовок,
 Scheduler Inactive,Планировщик неактивен,
 Scheduler is inactive. Cannot import data.,Планировщик неактивен. Невозможно импортировать данные.,
 Show Document,Показать документ,
 Show Traceback,Показать трассировку,
-Video,видео,
+Video,Видео,
 Webhook Secret,Webhook Secret,
 % Of Grand Total,% От общего итога,
 'employee_field_value' and 'timestamp' are required.,&#39;employee_field_value&#39; и &#39;timestamp&#39; являются обязательными.,
@@ -3583,7 +3583,7 @@
 Activity,Активность,
 Add / Manage Email Accounts.,Добавление / Управление учетными записями электронной почты,
 Add Child,Добавить потомка,
-Add Loan Security,Добавить кредит безопасности,
+Add Loan Security,Добавить обеспечение по кредиту,
 Add Multiple,Добавить несколько,
 Add Participants,Добавить участников,
 Add to Featured Item,Добавить в избранное,
@@ -3641,12 +3641,12 @@
 Book Appointment,Назначение книги,
 Brand,Бренд,
 Browse,Обзор,
-Call Connected,Call Connected,
+Call Connected,Вызов подключен,
 Call Disconnected,Вызов отключен,
 Call Missed,Звонок пропущен,
 Call Summary,Сводка вызовов,
 Call Summary Saved,Сводка вызовов сохранена,
-Cancelled,отменен,
+Cancelled,Отменен,
 Cannot Calculate Arrival Time as Driver Address is Missing.,"Невозможно рассчитать время прибытия, так как отсутствует адрес водителя.",
 Cannot Optimize Route as Driver Address is Missing.,"Не удается оптимизировать маршрут, так как отсутствует адрес драйвера.",
 Cannot complete task {0} as its dependant task {1} are not ccompleted / cancelled.,"Невозможно выполнить задачу {0}, поскольку ее зависимая задача {1} не завершена / не отменена.",
@@ -3666,19 +3666,19 @@
 Company of asset {0} and purchase document {1} doesn't matches.,Компания актива {0} и документ покупки {1} не совпадают.,
 Compare BOMs for changes in Raw Materials and Operations,Сравните спецификации для изменений в сырье и операциях,
 Compare List function takes on list arguments,Функция сравнения списка принимает аргументы списка,
-Complete,полный,
-Completed,Завершено,
+Complete,Завершенно,
+Completed,Завершенный,
 Completed Quantity,Завершенное количество,
 Connect your Exotel Account to ERPNext and track call logs,Подключите свою учетную запись Exotel к ERPNext и отслеживайте журналы вызовов,
 Connect your bank accounts to ERPNext,Подключите свои банковские счета к ERPNext,
 Contact Seller,Связаться с продавцом,
-Continue,Продолжать,
+Continue,Продолжить,
 Cost Center: {0} does not exist,МВЗ: {0} не существует,
 Couldn't Set Service Level Agreement {0}.,Не удалось установить соглашение об уровне обслуживания {0}.,
 Country,Страна,
 Country Code in File does not match with country code set up in the system,"Код страны в файле не совпадает с кодом страны, установленным в системе",
 Create New Contact,Создать новый контакт,
-Create New Lead,Создать новое руководство,
+Create New Lead,Создать новый лид,
 Create Pick List,Создать список выбора,
 Create Quality Inspection for Item {0},Создать проверку качества для позиции {0},
 Creating Accounts...,Создание аккаунтов ...,
@@ -3716,7 +3716,7 @@
 Dr,Доктор,
 Due Date,Дата выполнения,
 Duplicate,Дублировать,
-Duplicate Project with Tasks,Дублирующий проект с задачами,
+Duplicate Project with Tasks,Дублировать проект с задачами,
 Duplicate project has been created,Дублированный проект создан,
 E-Way Bill JSON can only be generated from a submitted document,E-Way Bill JSON может быть создан только из представленного документа,
 E-Way Bill JSON can only be generated from submitted document,E-Way Bill JSON может быть создан только из представленного документа,
@@ -3750,10 +3750,10 @@
 Expired,Истек срок действия,
 Export,Экспорт,
 Export not allowed. You need {0} role to export.,Экспорт не допускается. Вам нужно {0} роль для экспорта.,
-Failed to add Domain,Не удалось добавить домен,
+Failed to add Domain,Не удалось вид деятельности,
 Fetch Items from Warehouse,Получить товары со склада,
-Fetching...,Fetching ...,
-Field,поле,
+Fetching...,Получение...,
+Field,Поле,
 File Manager,Файловый менеджер,
 Filters,Фильтры,
 Finding linked payments,Поиск связанных платежей,
@@ -3777,7 +3777,7 @@
 Goal,Цель,
 Greater Than Amount,"Больше, чем сумма",
 Green,Зеленый,
-Group,группа,
+Group,Группа,
 Group By Customer,Группировать по клиенту,
 Group By Supplier,Группа по поставщикам,
 Group Node,Узел Группа,
@@ -3785,7 +3785,7 @@
 Help,Помощь,
 Help Article,Статья помощи,
 "Helps you keep tracks of Contracts based on Supplier, Customer and Employee","Помогает вам отслеживать контракты на основе поставщика, клиента и сотрудника",
-Helps you manage appointments with your leads,Помогает вам управлять назначениями с вашими лидами,
+Helps you manage appointments with your leads,Помогает вам управлять назначениями с вашими обращениями,
 Home,Главная,
 IBAN is not valid,IBAN недействителен,
 Import Data from CSV / Excel files.,Импорт данных из файлов CSV / Excel.,
@@ -3811,7 +3811,7 @@
 Leave application is linked with leave allocations {0}. Leave application cannot be set as leave without pay,Заявка на отпуск связана с распределением отпуска {0}. Заявка на отпуск не может быть установлена как отпуск без оплаты,
 Leaves Taken,Листья взяты,
 Less Than Amount,Меньше чем сумма,
-Liabilities,пассивы,
+Liabilities,Обязательства,
 Loading...,Загрузка...,
 Loan Amount exceeds maximum loan amount of {0} as per proposed securities,Сумма кредита превышает максимальную сумму кредита {0} в соответствии с предлагаемыми ценными бумагами,
 Loan Applications from customers and employees.,Кредитные заявки от клиентов и сотрудников.,
@@ -3827,7 +3827,7 @@
 Loan Type for interest and penalty rates,Тип кредита для процентов и пеней,
 Loan amount cannot be greater than {0},Сумма кредита не может превышать {0},
 Loan is mandatory,Кредит обязателен,
-Loans,кредитование,
+Loans,Кредиты,
 Loans provided to customers and employees.,"Кредиты, предоставленные клиентам и сотрудникам.",
 Location,Местоположение,
 Log Type is required for check-ins falling in the shift: {0}.,Тип регистрации необходим для регистрации заезда в смену: {0}.,
@@ -3844,11 +3844,11 @@
 Mobile No,Мобильный номер,
 Mobile Number,Мобильный номер,
 Month,Mесяц,
-Name,имя,
+Name,Имя,
 Near you,Возле тебя,
 Net Profit/Loss,Чистая прибыль / убыток,
-New Expense,Новый Расход,
-New Invoice,Новый Счет,
+New Expense,Новый расход,
+New Invoice,Новый счет,
 New Payment,Новый платеж,
 New release date should be in the future,Дата нового релиза должна быть в будущем,
 Newsletter,Рассылка новостей,
@@ -3857,7 +3857,7 @@
 No Leaves Allocated to Employee: {0} for Leave Type: {1},Сотрудникам не выделено ни одного листа: {0} для типа отпуска: {1},
 No communication found.,Связь не найдена.,
 No correct answer is set for {0},Не указан правильный ответ для {0},
-No description,без описания,
+No description,Без описания,
 No issue has been raised by the caller.,Никакая проблема не была поднята вызывающим абонентом.,
 No items to publish,Нет материалов для публикации,
 No outstanding invoices found,Не найдено неоплаченных счетов,
@@ -3870,7 +3870,7 @@
 Not allowed to create accounting dimension for {0},Не разрешено создавать учетное измерение для {0},
 Not permitted. Please disable the Lab Test Template,"Не разрешено Пожалуйста, отключите шаблон лабораторного теста",
 Note,Заметки,
-Notes: ,Заметки:,
+Notes: ,Заметки: ,
 On Converting Opportunity,О возможности конвертации,
 On Purchase Order Submission,При подаче заказа на поставку,
 On Sales Order Submission,На подаче заказа клиента,
@@ -3879,9 +3879,9 @@
 Only .csv and .xlsx files are supported currently,В настоящее время поддерживаются только файлы .csv и .xlsx,
 Only expired allocation can be cancelled,Только истекшее распределение может быть отменено,
 Only users with the {0} role can create backdated leave applications,Только пользователи с ролью {0} могут создавать оставленные приложения с задним сроком действия,
-Open,Создано,
+Open,Открыт,
 Open Contact,Открытый контакт,
-Open Lead,Открытое руководство,
+Open Lead,Открытое обращение,
 Opening and Closing,Открытие и Закрытие,
 Operating Cost as per Work Order / BOM,Эксплуатационные расходы согласно заказу на работу / спецификации,
 Order Amount,Сумма заказа,
@@ -3891,13 +3891,13 @@
 Passing Score value should be between 0 and 100,Проходной балл должен быть от 0 до 100,
 Password policy cannot contain spaces or simultaneous hyphens. The format will be restructured automatically,Политика паролей не может содержать пробелов или дефисов одновременно. Формат будет реструктурирован автоматически,
 Patient History,История пациента,
-Pause,пауза,
-Pay,Платить,
+Pause,Пауза,
+Pay,Оплатить,
 Payment Document Type,Тип платежного документа,
 Payment Name,Название платежа,
 Penalty Amount,Сумма штрафа,
 Pending,В ожидании,
-Performance,Спектакль,
+Performance,Производительность,
 Period based On,Период на основе,
 Perpetual inventory required for the company {0} to view this report.,"Постоянная инвентаризация требуется для компании {0}, чтобы просмотреть этот отчет.",
 Phone,Телефон,
@@ -3943,8 +3943,8 @@
 Priority has been changed to {0}.,Приоритет был изменен на {0}.,
 Priority {0} has been repeated.,Приоритет {0} был повторен.,
 Processing XML Files,Обработка файлов XML,
-Profitability,рентабельность,
-Project,проект,
+Profitability,Рентабельность,
+Project,Проект,
 Proposed Pledges are mandatory for secured Loans,Предлагаемые залоги являются обязательными для обеспеченных займов,
 Provide the academic year and set the starting and ending date.,Укажите учебный год и установите дату начала и окончания.,
 Public token is missing for this bank,Публичный токен отсутствует для этого банка,
@@ -3959,7 +3959,7 @@
 Purchase Invoices,Счета на покупку,
 Purchase Orders,Заказы,
 Purchase Receipt doesn't have any Item for which Retain Sample is enabled.,"В квитанции о покупке нет ни одного предмета, для которого включена функция сохранения образца.",
-Purchase Return,Покупка Вернуться,
+Purchase Return,Возврат покупки,
 Qty of Finished Goods Item,Кол-во готовых товаров,
 Qty or Amount is mandatroy for loan security,Кол-во или сумма является мандатрой для обеспечения кредита,
 Quality Inspection required for Item {0} to submit,Инспекция по качеству требуется для отправки элемента {0},
@@ -3977,11 +3977,11 @@
 Reconciled,Примирение,
 Recruitment,Набор персонала,
 Red,Красный,
-Refreshing,освежение,
+Refreshing,Обновление,
 Release date must be in the future,Дата релиза должна быть в будущем,
 Relieving Date must be greater than or equal to Date of Joining,Дата освобождения должна быть больше или равна дате присоединения,
 Rename,Переименовать,
-Rename Not Allowed,Переименовать не разрешено,
+Rename Not Allowed,Переименовывать запрещено,
 Repayment Method is mandatory for term loans,Метод погашения обязателен для срочных кредитов,
 Repayment Start Date is mandatory for term loans,Дата начала погашения обязательна для срочных кредитов,
 Report Item,Элемент отчета,
@@ -3993,7 +3993,7 @@
 Return amount cannot be greater unclaimed amount,Возврат суммы не может быть больше невостребованной суммы,
 Review,Обзор,
 Room,Комната,
-Room Type,Тип номера,
+Room Type,Тип комнаты,
 Row # ,Ряд #,
 Row #{0}: Accepted Warehouse and Supplier Warehouse cannot be same,Строка # {0}: принятый склад и склад поставщика не могут быть одинаковыми,
 Row #{0}: Cannot delete item {1} which has already been billed.,"Строка # {0}: невозможно удалить элемент {1}, для которого уже выставлен счет.",
@@ -4023,9 +4023,9 @@
 Saved Items,Сохраненные предметы,
 Search Items ...,Поиск предметов ...,
 Search for a payment,Поиск платежа,
-Search for anything ...,Ищите что-нибудь ...,
+Search for anything ...,Искать что угодно ...,
 Search results for,Результаты поиска,
-Select All,Выбрать Все,
+Select All,Выбрать все,
 Select Difference Account,Выберите учетную запись разницы,
 Select a Default Priority.,Выберите приоритет по умолчанию.,
 Select a company,Выберите компанию,
@@ -4060,7 +4060,7 @@
 Sr,Sr,
 Start,Начать,
 Start Date cannot be before the current date,Дата начала не может быть раньше текущей даты,
-Start Time,Время,
+Start Time,Время начала,
 Status,Статус,
 Status must be Cancelled or Completed,Статус должен быть отменен или завершен,
 Stock Balance Report,Отчет об остатках на складе,
@@ -4069,7 +4069,7 @@
 Stock Value ({0}) and Account Balance ({1}) are out of sync for account {2} and it's linked warehouses.,Стоимость запаса ({0}) и остаток на счете ({1}) не синхронизированы для счета {2} и связанных хранилищ.,
 Stores - {0},Магазины - {0},
 Student with email {0} does not exist,Студент с электронной почтой {0} не существует,
-Submit Review,добавить отзыв,
+Submit Review,Добавить отзыв,
 Submitted,Проведенный,
 Supplier Addresses And Contacts,Адреса и контакты поставщика,
 Synchronize this account,Синхронизировать этот аккаунт,
@@ -4101,7 +4101,7 @@
 This page keeps track of items you want to buy from sellers.,"На этой странице отслеживаются товары, которые вы хотите купить у продавцов.",
 This page keeps track of your items in which buyers have showed some interest.,"Эта страница отслеживает ваши товары, к которым покупатели проявили определенный интерес.",
 Thursday,Четверг,
-Timing,тайминг,
+Timing,Сроки,
 Title,Заголовок,
 "To allow over billing, update ""Over Billing Allowance"" in Accounts Settings or the Item.","Чтобы разрешить чрезмерную оплату, обновите «Разрешение на чрезмерную оплату» в настройках учетных записей или элемента.",
 "To allow over receipt / delivery, update ""Over Receipt/Delivery Allowance"" in Stock Settings or the Item.","Чтобы разрешить перерасход / доставку, обновите параметр «Сверх квитанция / доставка» в настройках запаса или позиции.",
@@ -4132,7 +4132,7 @@
 Update Taxes for Items,Обновить налоги на товары,
 "Upload a bank statement, link or reconcile a bank account","Загрузить выписку из банковского счета, связать или сверить банковский счет",
 Upload a statement,Загрузить заявление,
-Use a name that is different from previous project name,"Используйте имя, которое отличается от предыдущего названия проекта",
+Use a name that is different from previous project name,"Используйте название, которое отличается от предыдущего названия проекта",
 User {0} is disabled,Пользователь {0} отключен,
 Users and Permissions,Пользователи и Права,
 Vacancies cannot be lower than the current openings,Вакансии не могут быть ниже текущих вакансий,
@@ -4141,7 +4141,7 @@
 Values Out Of Sync,Значения не синхронизированы,
 Vehicle Type is required if Mode of Transport is Road,"Тип транспортного средства требуется, если вид транспорта - дорога",
 Vendor Name,Имя продавца,
-Verify Email,подтвердить электронную почту,
+Verify Email,Подтвердить Email,
 View,Посмотреть,
 View all issues from {0},Просмотреть все проблемы от {0},
 View call log,Просмотр журнала звонков,
@@ -4157,9 +4157,9 @@
 You,Вы,
 You are not allowed to enroll for this course,Вы не можете записаться на этот курс,
 You are not enrolled in program {0},Вы не зарегистрированы в программе {0},
-You can Feature upto 8 items.,Вы можете добавить до 8 предметов.,
+You can Feature upto 8 items.,Вы можете добавить до 8 элементов.,
 You can also copy-paste this link in your browser,Ещё можно скопировать эту ссылку в браузер,
-You can publish upto 200 items.,Вы можете опубликовать до 200 пунктов.,
+You can publish upto 200 items.,Вы можете опубликовать до 200 элементов.,
 You have to enable auto re-order in Stock Settings to maintain re-order levels.,"Вы должны включить автоматический повторный заказ в настройках запаса, чтобы поддерживать уровни повторного заказа.",
 You must be a registered supplier to generate e-Way Bill,Вы должны быть зарегистрированным поставщиком для создания электронного билля,
 You need to login as a Marketplace User before you can add any reviews.,"Вам необходимо войти в систему как пользователь Marketplace, чтобы добавить какие-либо отзывы.",
@@ -4193,22 +4193,22 @@
 Barcode,Штрих-код,
 Bold,Жирный,
 Center,Центр,
-Clear,ясно,
+Clear,Отчистить,
 Comment,Комментарий,
 Comments,Комментарии,
 DocType,DocType,
 Download,Скачать,
 Left,Слева,
-Link,Ссылка на сайт,
-New,новый,
+Link,Ссылка,
+New,Новый,
 Not Found,Не найдено,
 Print,Распечатать,
 Reference Name,Имя ссылки,
 Refresh,Обновить,
-Success,успех,
+Success,Успешно,
 Time,Время,
 Value,Значение,
-Actual,фактический,
+Actual,Актуальность,
 Add to Cart,добавить в корзину,
 Days Since Last Order,Дней с последнего заказа,
 In Stock,В наличии,
@@ -4222,15 +4222,15 @@
 Sales Person,Продавец,
 To date cannot be before From date,На сегодняшний день не может быть раньше От даты,
 Write Off,Списать,
-{0} Created,Создано {0},
+{0} Created,{0} Создано,
 Email Id,Email ID,
-No,нет,
+No,№,
 Reference Doctype,Ссылка DocType,
 User Id,Идентификатор пользователя,
-Yes,да,
+Yes,Да,
 Actual ,Фактически,
 Add to cart,Добавить в корзину,
-Budget,бюджет,
+Budget,Бюджет,
 Chart of Accounts,План счетов,
 Customer database.,База данных клиентов.,
 Days Since Last order,Дни с последнего Заказать,
@@ -4244,7 +4244,7 @@
 Loan amount is mandatory,Сумма кредита обязательна,
 Minimum Qty,Минимальное количество,
 More details,Больше параметров,
-Nature of Supplies,Природа поставок,
+Nature of Supplies,Характер поставок,
 No Items found.,Ничего не найдено.,
 No employee found,Сотрудник не найден,
 No students found,Нет студентов не найдено,
@@ -4252,10 +4252,10 @@
 Not permitted,Не разрешено,
 Open Issues ,Открыть вопросы,
 Open Projects ,Открыть проекты,
-Open To Do ,Открыть список дел,
+Open To Do ,Открыть список задач,
 Operation Id,Код операции,
 Partially ordered,Частично заказанно,
-Please select company first,"Пожалуйста, выберите КОМПАНИЯ Первый",
+Please select company first,Сначала выберите компанию,
 Please select patient,Выберите пациента,
 Printed On ,Напечатано на,
 Projected qty,Прогнозируемое кол-во,
@@ -4268,14 +4268,14 @@
 Total Taxable value,Общая налогооблагаемая стоимость,
 Upcoming Calendar Events ,Предстоящие события календаря,
 Value or Qty,Значение или кол-во,
-Variance ,отклонение,
+Variance ,Расхождение ,
 Variant of,Вариант,
 Write off,Списать,
 hours,часов,
 received from,получено от,
 to,для,
 Cards,Карты,
-Percentage,процент,
+Percentage,Процент,
 Failed to setup defaults for country {0}. Please contact support@erpnext.com,"Не удалось установить значения по умолчанию для страны {0}. Пожалуйста, свяжитесь с support@erpnext.com",
 Row #{0}: Item {1} is not a Serialized/Batched Item. It cannot have a Serial No/Batch No against it.,Строка # {0}: элемент {1} не является сериализованным / пакетным элементом. Он не может иметь серийный номер / пакетный номер против него.,
 Please set {0},"Пожалуйста, установите {0}",
@@ -4319,7 +4319,7 @@
 Publish Date,Дата публикации,
 Duration,Продолжительность,
 Advanced Settings,Расширенные настройки,
-Path,Дорожка,
+Path,Путь,
 Components,Компоненты,
 Verified By,Утверждено,
 Invalid naming series (. missing) for {0},Недопустимая серия имен (. Отсутствует) для {0},
@@ -4363,7 +4363,7 @@
 Row {0}: {1} is required in the expenses table to book an expense claim.,Строка {0}: {1} требуется в таблице расходов для регистрации претензии по расходам.,
 Set the default account for the {0} {1},Установите учетную запись по умолчанию для {0} {1},
 (Half Day),(Полдня),
-Income Tax Slab,Плита подоходного налога,
+Income Tax Slab,Подоходный налог,
 Row #{0}: Cannot set amount or formula for Salary Component {1} with Variable Based On Taxable Salary,Строка № {0}: невозможно установить сумму или формулу для компонента заработной платы {1} с переменной на основе налогооблагаемой заработной платы.,
 Row #{}: {} of {} should be {}. Please modify the account or select a different account.,Строка № {}: {} из {} должно быть {}. Измените учетную запись или выберите другую учетную запись.,
 Row #{}: Please asign task to a member.,Строка № {}: назначьте задачу участнику.,
@@ -4438,12 +4438,12 @@
 Item with Item Code {0} already exists,Товар с кодом товара {0} уже существует,
 Registration Fee cannot be negative or zero,Регистрационный взнос не может быть отрицательным или нулевым.,
 Configure a service Item for {0},Настроить сервисный элемент для {0},
-Temperature: ,Температура:,
-Pulse: ,Пульс:,
-Respiratory Rate: ,Частота дыхания:,
-BP: ,АД:,
-BMI: ,ИМТ:,
-Note: ,Примечание:,
+Temperature: ,Температура: ,
+Pulse: ,Пульс: ,
+Respiratory Rate: ,Частота дыхания: ,
+BP: ,АД :,
+BMI: ,ИМТ: ,
+Note: ,Примечание: ,
 Check Availability,Проверить наличие свободных мест,
 Please select Patient first,"Пожалуйста, сначала выберите пациента",
 Please select a Mode of Payment first,"Пожалуйста, сначала выберите способ оплаты",
@@ -4476,9 +4476,9 @@
 Please set Customer in Patient {0},Установите клиента в пациенте {0},
 Item {0} is not active,Пункт {0} не активен,
 Therapy Plan {0} created successfully.,План терапии {0} успешно создан.,
-Symptoms: ,Симптомы:,
+Symptoms: ,Симптомы: ,
 No Symptoms,Нет симптомов,
-Diagnosis: ,Диагноз:,
+Diagnosis: ,Диагноз: ,
 No Diagnosis,Нет диагноза,
 Drug(s) Prescribed.,Выписанные лекарства.,
 Test(s) Prescribed.,Предписанные испытания.,
@@ -4589,7 +4589,7 @@
 New Transactions,Новые транзакции,
 Match Transaction to Invoices,Сопоставление транзакций с счетами-фактурами,
 Create New Payment/Journal Entry,Создать новую запись о платеже / журнале,
-Submit/Reconcile Payments,Отправить / Согласовать платежи,
+Submit/Reconcile Payments,Утвердить/Согласовать платежи,
 Matching Invoices,Сопоставление счетов-фактур,
 Payment Invoice Items,Платежные счета,
 Reconciled Transactions,Согласованные транзакции,
@@ -4631,7 +4631,7 @@
 C-Form No,C-образный Нет,
 Received Date,Дата получения,
 Quarter,Квартал,
-I,Я,
+I,I,
 II,II,
 III,III,
 IV,IV,
@@ -4653,7 +4653,7 @@
 Is Income Tax Liability,Ответственность подоходного налога,
 Is Income Tax Expense,Расходы на подоходный налог,
 Cash Flow Mapping Accounts,Учетные записи денежных потоков,
-account,Аккаунт,
+account,аккаунт,
 Cash Flow Mapping Template,Шаблон сопоставления денежных потоков,
 Cash Flow Mapping Template Details,Подробное описание шаблонов движения денежных средств,
 POS-CLO-,POS-ClO-,
@@ -4669,7 +4669,7 @@
 Has Print Format,Имеет формат печати,
 Primary Settings,Основные настройки,
 Cheque Size,Cheque Размер,
-Regular,регулярное,
+Regular,Обычный,
 Starting position from top edge,Исходное положение от верхнего края,
 Cheque Width,Cheque Ширина,
 Cheque Height,Cheque Высота,
@@ -4691,7 +4691,7 @@
 Parent Cost Center,Родитель МВЗ,
 lft,LFT,
 rgt,РТГ,
-Coupon Code,код купона,
+Coupon Code,Код купона,
 Coupon Name,Название купона,
 "e.g. ""Summer Holiday 2019 Offer 20""","например, &quot;Летние каникулы 2019 Предложение 20&quot;",
 Coupon Type,Тип купона,
@@ -4913,7 +4913,7 @@
 POS Field,POS Field,
 POS Item Group,POS Item Group,
 Company Address,Адрес компании,
-Update Stock,Обновить склад,
+Update Stock,Обновить остатки,
 Ignore Pricing Rule,Игнорировать правило ценообразования,
 Applicable for Users,Применимо для пользователей,
 Sales Invoice Payment,Накладная Оплата,
@@ -5039,7 +5039,7 @@
 Group same items,Сгруппировать похожие продукты,
 Print Language,Язык печати,
 "Once set, this invoice will be on hold till the set date",После этого этот счет будет приостановлен до установленной даты,
-Credit To,Кредитная Для,
+Credit To,Кредит для,
 Party Account Currency,Партия Валюта счета,
 Against Expense Account,Со счета расходов,
 Inter Company Invoice Reference,Справочная информация для Inter Company,
@@ -5068,8 +5068,8 @@
 Raw Materials Supplied Cost,Стоимость поставленного сырья,
 Accepted Warehouse,Принимающий склад,
 Serial No,Серийный номер,
-Rejected Serial No,Отклонен Серийный номер,
-Expense Head,Расходов Глава,
+Rejected Serial No,Отклоненный Серийный номер,
+Expense Head,Глава расходов,
 Is Fixed Asset,Фиксирована Asset,
 Asset Location,Месторасположение активов,
 Deferred Expense,Отложенные расходы,
@@ -5114,8 +5114,8 @@
 Customer PO Details,Детали заказа клиента,
 Customer's Purchase Order,Заказ клиента,
 Customer's Purchase Order Date,Клиентам Дата Заказ,
-Customer Address,Клиент Адрес,
-Shipping Address Name,Адрес доставки Имя,
+Customer Address,Адрес клиента,
+Shipping Address Name,Название адрес доставки,
 Company Address Name,Название компании,
 Rate at which Customer Currency is converted to customer's base currency,Курс по которому валюта Покупателя конвертируется в базовую валюту покупателя,
 Rate at which Price list currency is converted to customer's base currency,Курс по которому валюта Прайс листа конвертируется в базовую валюту покупателя,
@@ -5123,9 +5123,9 @@
 Packing List,Список упаковки,
 Packed Items,Упакованные продукты,
 Product Bundle Help,Продукт Связка Помощь,
-Time Sheet List,Список времени лист,
-Time Sheets,Time Sheets,
-Total Billing Amount,Всего счетов Сумма,
+Time Sheet List,Список табелей учета рабочего времени,
+Time Sheets,Табель учета рабочего времени,
+Total Billing Amount,Общая сумма счета,
 Sales Taxes and Charges Template,Продажи Налоги и сборы шаблона,
 Sales Taxes and Charges,Налоги и сборы с продаж,
 Loyalty Points Redemption,Выкуп лояльности очков,
@@ -5170,19 +5170,19 @@
 Delivery Note Item,Доставляемый продукт,
 Base Amount (Company Currency),Базовая сумма (Компания Валюта),
 Sales Invoice Timesheet,Счет по табелю,
-Time Sheet,Время Sheet,
-Billing Hours,Платежная часы,
-Timesheet Detail,Timesheet Деталь,
+Time Sheet,Табель учета рабочего времени,
+Billing Hours,Оплачеваемые часы,
+Timesheet Detail,Сведения о расписании,
 Tax Amount After Discount Amount (Company Currency),Сумма налога после скидки Сумма (Компания валют),
-Item Wise Tax Detail,Пункт Мудрый Налоговый Подробно,
+Item Wise Tax Detail,Подробная информация о налоге на товар,
 Parenttype,ParentType,
 "Standard tax template that can be applied to all Sales Transactions. This template can contain list of tax heads and also other expense / income heads like ""Shipping"", ""Insurance"", ""Handling"" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n    - This can be on **Net Total** (that is the sum of basic amount).\n    - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n    - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on ""Previous Row Total"" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Is this Tax included in Basic Rate?: If you check this, it means that this tax will not be shown below the item table, but will be included in the Basic Rate in your main item table. This is useful where you want give a flat price (inclusive of all taxes) price to customers.","Стандартный шаблон налог, который может быть применен ко всем сделок купли-продажи. Этот шаблон может содержать перечень налоговых руководителей, а также других глав расходы / доходы, как ""Shipping"", ""Insurance"", ""Обращение"" и т.д. \n\n #### Примечание \n\n ставка налога на Вы Определить здесь будет стандартная ставка налога на прибыль для всех ** деталей **. Если есть ** товары **, которые имеют различные цены, они должны быть добавлены в ** деталь налога ** стол в ** деталь ** мастера.\n\n #### Описание колонок \n\n 1. Расчет Тип: \n - Это может быть ** Чистый Всего ** (то есть сумма основной суммы).\n - ** На предыдущей строке Total / сумма ** (по совокупности налогов и сборов). Если вы выбираете эту опцию, налог будет применяться в процентах от предыдущего ряда (в налоговом таблицы) суммы или объема.\n - ** ** Фактический (как уже упоминалось).\n 2. Счет Руководитель: лицевому счету, при которых этот налог будут забронированы \n 3. Центр Стоимость: Если налог / налог на заряд доход (как перевозка груза) или расходов это должен быть забронирован на МВЗ.\n 4. Описание: Описание налога (которые будут напечатаны в счетах-фактурах / кавычек).\n 5. Оценить: Налоговая ставка.\n 6. Количество: Сумма налога.\n 7. Всего: Суммарное к этой точке.\n 8. Введите Row: Если на базе ""Предыдущая сумма по строке"" вы можете выбрать номер строки которой будет приниматься в качестве основы для такого расчета (по умолчанию предыдущего ряда).\n 9. Это налог Включено в основной ставке ?: Если вы посмотрите, это значит, что этот налог не будет показано ниже в таблице элементов, но будет включен в основной ставке в основной таблице элементов. Это полезно, если вы хотите дать квартира Цена (включая все налоги) цену к клиентам.",
 * Will be calculated in the transaction.,* Будет рассчитана в сделке.,
-From No,От Нет,
-To No,Нет,
-Is Company,Является ли компания,
+From No,От №,
+To No,К №,
+Is Company,Это компания,
 Current State,Текущее состояние,
-Purchased,купленный,
+Purchased,Купленный,
 From Shareholder,От акционеров,
 From Folio No,Из Folio No,
 To Shareholder,Акционеру,
@@ -5223,7 +5223,7 @@
 Number of days that the subscriber has to pay invoices generated by this subscription,"Количество дней, в течение которых абонент должен оплатить счета, сгенерированные этой подпиской",
 Cancel At End Of Period,Отмена на конец периода,
 Generate Invoice At Beginning Of Period,Сформировать счет в начале периода,
-Plans,планы,
+Plans,Планы,
 Discounts,Скидки,
 Additional DIscount Percentage,Процент Дополнительной Скидки,
 Additional DIscount Amount,Сумма Дополнительной Скидки,
@@ -5307,7 +5307,7 @@
 List of diseases detected on the field. When selected it'll automatically add a list of tasks to deal with the disease ,"Список заболеваний, обнаруженных на поле. При выборе он автоматически добавит список задач для борьбы с болезнью",
 Detected Disease,Обнаруженная болезнь,
 LInked Analysis,Анализ LInked,
-Disease,болезнь,
+Disease,Болезнь,
 Tasks Created,Созданные задачи,
 Common Name,Распространенное имя,
 Treatment Task,Лечебная задача,
@@ -5326,10 +5326,10 @@
 Plant Analysis Criteria,Критерии анализа производства,
 Minimum Permissible Value,Минимальное допустимое значение,
 Maximum Permissible Value,Максимально допустимое значение,
-Ca/K,Са / К,
-Ca/Mg,Са / Mg,
-Mg/K,Мг / К,
-(Ca+Mg)/K,(Са + Mg) / К,
+Ca/K,Са/К,
+Ca/Mg,Са/Mg,
+Mg/K,Мг/К,
+(Ca+Mg)/K,(Са+Mg)/К,
 Ca/(K+Ca+Mg),Са / (К + Са + Mg),
 Soil Analysis Criterias,Критерий анализа почвы,
 Soil Analysis Criteria,Критерии оценки почвы,
@@ -5379,7 +5379,7 @@
 Depreciation Schedules,Амортизационные Расписания,
 Insurance details,Детали страхования,
 Policy number,Номер полиса,
-Insurer,страхователь,
+Insurer,Страхователь,
 Insured value,Страховое значение,
 Insurance Start Date,Дата начала страхования,
 Insurance End Date,Дата окончания страхования,
@@ -5453,8 +5453,8 @@
 Is Container,Контейнер,
 Check if it is a hydroponic unit,"Проверьте, является ли это гидропонной единицей",
 Location Details,Информация о местоположении,
-Latitude,широта,
-Longitude,долгота,
+Latitude,Широта,
+Longitude,Долгота,
 Area,Площадь,
 Area UOM,Область UOM,
 Tree Details,Детали Дерево,
@@ -5515,13 +5515,13 @@
 Required Date,Требуемая дата,
 Request for Quotation Supplier,Запрос на предложение поставщика,
 Send Email,Отправить письмо,
-Quote Status,Статус цитаты,
+Quote Status,Статус предложения,
 Download PDF,Скачать PDF,
 Supplier of Goods or Services.,Поставщик товаров или услуг.,
 Name and Type,Наименование и тип,
 SUP-.YYYY.-,SUP-.YYYY.-,
 Default Bank Account,По умолчанию Банковский счет,
-Is Transporter,Является Transporter,
+Is Transporter,Является перевозчиком,
 Represents Company,Представляет компанию,
 Supplier Type,Тип поставщика,
 Allow Purchase Invoice Creation Without Purchase Order,Разрешить создание счета-фактуры без заказа на покупку,
@@ -5574,16 +5574,16 @@
 PU-SSP-.YYYY.-,PU-SSP-.YYYY.-,
 Period Score,Период,
 Calculations,вычисления,
-Criteria,критерии,
-Variables,переменные,
+Criteria,Критерии,
+Variables,Переменные,
 Supplier Scorecard Setup,Поставщик Scorecard Setup,
 Supplier Scorecard Scoring Criteria,Критерии оценки поставщика,
 Score,Балл,
 Supplier Scorecard Scoring Standing,Поставщик Scorecard Scoring Standing,
 Standing Name,Постоянное имя,
 Purple,Пурпурный,
-Yellow,жёлтый,
-Orange,оранжевый,
+Yellow,Жёлтый,
+Orange,Оранжевый,
 Min Grade,Min Grade,
 Max Grade,Макс. Класс,
 Warn Purchase Orders,Предупреждать заказы на поставку,
@@ -5598,16 +5598,16 @@
 Call Log,Журнал вызовов,
 Received By,Получено,
 Caller Information,Информация о звонящем,
-Contact Name,Имя Контакта,
-Lead ,вести,
-Lead Name,Имя,
-Ringing,звонкий,
+Contact Name,Имя контакта,
+Lead ,Лид ,
+Lead Name,Имя лида,
+Ringing,Звонок,
 Missed,Пропущенный,
 Call Duration in seconds,Продолжительность звонка в секундах,
 Recording URL,Запись URL,
 Communication Medium,Связь Средний,
 Communication Medium Type,Тип средств связи,
-Voice,голос,
+Voice,Голос,
 Catch All,Поймать все,
 "If there is no assigned timeslot, then communication will be handled by this group","Если нет назначенного временного интервала, то связь будет обрабатываться этой группой",
 Timeslots,Временные интервалы,
@@ -5615,10 +5615,10 @@
 Employee Group,Группа сотрудников,
 Appointment,"Деловое свидание, встреча",
 Scheduled Time,Назначенное время,
-Unverified,непроверенный,
+Unverified,Непроверенный,
 Customer Details,Данные клиента,
 Phone Number,Телефонный номер,
-Skype ID,Скайп ай-ди,
+Skype ID,Skype ID,
 Linked Documents,Связанные документы,
 Appointment With,Встреча с,
 Calendar Event,Календарь событий,
@@ -5638,22 +5638,22 @@
 "Leave blank for home.\nThis is relative to site URL, for example ""about"" will redirect to ""https://yoursitename.com/about""","Оставьте пустым для дома. Это относительно URL сайта, например, «about» будет перенаправлен на «https://yoursitename.com/about»",
 Appointment Booking Slots,Назначение Бронирование Слоты,
 Day Of Week,День недели,
-From Time ,С,
+From Time ,С ,
 Campaign Email Schedule,Расписание рассылки кампании,
 Send After (days),Отправить после (дней),
 Signed,подписанный,
 Party User,Пользователь Party,
-Unsigned,неподписанный,
+Unsigned,Неподписанный,
 Fulfilment Status,Статус выполнения,
-N/A,N / A,
+N/A,N/A,
 Unfulfilled,невыполненный,
 Partially Fulfilled,Частично выполнено,
 Fulfilled,Исполненная,
 Lapsed,Просроченные,
 Contract Period,Контрактный период,
 Signee Details,Информация о подписчике,
-Signee,грузополучатель,
-Signed On,Подпись,
+Signee,Грузополучатель,
+Signed On,Подписано,
 Contract Details,Информация о контракте,
 Contract Template,Шаблон контракта,
 Contract Terms,Условия договора,
@@ -5662,7 +5662,7 @@
 Fulfilment Deadline,Срок выполнения,
 Fulfilment Terms,Условия выполнения,
 Contract Fulfilment Checklist,Контрольный список выполнения контракта,
-Requirement,требование,
+Requirement,Требование,
 Contract Terms and Conditions,Условия договора,
 Fulfilment Terms and Conditions,Сроки и условия выполнения,
 Contract Template Fulfilment Terms,Условия заключения контрактов,
@@ -5683,7 +5683,7 @@
 Ends On,Заканчивается,
 Address & Contact,Адрес и контакт,
 Mobile No.,Мобильный,
-Lead Type,Тип Обращения,
+Lead Type,Тип лидов,
 Channel Partner,Партнер,
 Consultant,Консультант,
 Market Segment,Сегмент рынка,
@@ -5705,9 +5705,9 @@
 Opportunity Lost Reason,Возможность потерянной причины,
 Potential Sales Deal,Сделка потенциальных продаж,
 CRM-OPP-.YYYY.-,CRM-ОПП-.YYYY.-,
-Opportunity From,Выявление из,
-Customer / Lead Name,Имя Клиента / Обращения,
-Opportunity Type,Тип Выявления,
+Opportunity From,Возможность из,
+Customer / Lead Name,Имя Клиента / Лида,
+Opportunity Type,Тип возможности,
 Converted By,Преобразовано,
 Sales Stage,Этап продажи,
 Lost Reason,Забыли Причина,
@@ -5716,7 +5716,7 @@
 With Items,С продуктами,
 Probability (%),Вероятность (%),
 Contact Info,Контактная информация,
-Customer / Lead Address,Адрес Клиента / Обращения,
+Customer / Lead Address,Адрес Клиента / Лида,
 Contact Mobile No,Связаться Мобильный Нет,
 Enter name of campaign if source of enquiry is campaign,"Введите имя кампании, если источником исследования является кампания",
 Opportunity Date,Дата Выявления,
@@ -5747,7 +5747,7 @@
 Assessment Name,Название оценки,
 Grading Scale,Оценочная шкала,
 Examiner,экзаменатор,
-Examiner Name,Имя Examiner,
+Examiner Name,Имя экзаменатора,
 Supervisor,Руководитель,
 Supervisor Name,Имя супервизора,
 Evaluate,оценивать,
@@ -5765,7 +5765,7 @@
 Content Question,Содержание вопроса,
 Question Link,Ссылка на вопрос,
 Course Name,Название курса,
-Topics,темы,
+Topics,Темы,
 Hero Image,Образ героя,
 Default Grading Scale,Шкала оценок,
 Education Manager,Менеджер по образованию,
@@ -5775,7 +5775,7 @@
 Course Assessment Criteria,Критерии оценки курса,
 Weightage,Добавка,
 Course Content,Содержание курса,
-Quiz,викторина,
+Quiz,Викторина,
 Program Enrollment,Программа подачи заявок,
 Enrollment Date,Дата поступления,
 Instructor Name,Имя инструктора,
@@ -5785,7 +5785,7 @@
 To TIme,До,
 Course End Date,Дата окончания курса,
 Course Topic,Тема курса,
-Topic,тема,
+Topic,Тема,
 Topic Name,Название темы,
 Education Settings,Настройки образования,
 Current Academic Year,Текущий академический год,
@@ -5845,11 +5845,11 @@
 EDU-INS-.YYYY.-,EDU-INS-.YYYY.-,
 Instructor Log,Журнал инструктора,
 Other details,Другие детали,
-Option,вариант,
+Option,Вариант,
 Is Correct,Верно,
 Program Name,Название программы,
 Program Abbreviation,Программа Аббревиатура,
-Courses,курсы,
+Courses,Курсы,
 Is Published,Опубликовано,
 Allow Self Enroll,Разрешить самостоятельную регистрацию,
 Is Featured,Показано,
@@ -5910,7 +5910,7 @@
 A-,A-,
 B+,B+,
 B-,B-,
-O+,O +,
+O+,O+,
 O-,О-,
 AB+,AB+,
 AB-,AB-,
@@ -5991,17 +5991,17 @@
 AE,AE,
 AU,AU,
 BR,BR,
-CA,Калифорния,
+CA,CA,
 CN,CN,
-DE,Делавэр,
+DE,DE,
 ES,ES,
 FR,FR,
-IN,В,
+IN,IN,
 JP,JP,
-IT,ЭТО,
+IT,IT,
 MX,MX,
-UK,Великобритания,
-US,НАС,
+UK,UK,
+US,US,
 Customer Type,Тип клиента,
 Market Place Account Group,Группа учета рынка,
 After Date,После даты,
@@ -6018,19 +6018,19 @@
 Exotel Settings,Настройки Exotel,
 Account SID,SID аккаунта,
 API Token,API-токен,
-GoCardless Mandate,Безрукий мандат,
-Mandate,мандат,
-GoCardless Customer,Без комиссии,
-GoCardless Settings,Настройки бездорожья,
-Webhooks Secret,Секретные клипы,
-Plaid Settings,Настройки пледа,
+GoCardless Mandate,GoCardless мандат,
+Mandate,Мандат,
+GoCardless Customer,Клиент GoCardless,
+GoCardless Settings,Настройки GoCardless,
+Webhooks Secret,Webhooks Secret,
+Plaid Settings,Настройки Plaid,
 Synchronize all accounts every hour,Синхронизировать все учетные записи каждый час,
 Plaid Client ID,Идентификатор клиента,
-Plaid Secret,Плед секрет,
-Plaid Environment,Плед среды,
+Plaid Secret,Plaid Secret,
+Plaid Environment,Plaid Environment,
 sandbox,песочница,
-development,развитие,
-production,производство,
+development,development,
+production,production,
 QuickBooks Migrator,QuickBooks Migrator,
 Application Settings,Настройки приложения,
 Token Endpoint,Конечная точка маркера,
@@ -6044,9 +6044,9 @@
 Default Warehouse,Склад по умолчанию,
 Default Cost Center,По умолчанию Центр Стоимость,
 Undeposited Funds Account,Учет нераспределенных средств,
-Shopify Log,Shopify Вход,
+Shopify Log,Логи Shopify,
 Request Data,Запросить данные,
-Shopify Settings,Изменить настройки,
+Shopify Settings,Shopify настройки,
 status html,статус html,
 Enable Shopify,Включить Shopify,
 App Type,Тип приложения,
@@ -6068,7 +6068,7 @@
 Delivery Note Series,Идентификаторы документов доставки,
 Import Sales Invoice from Shopify if Payment is marked,"Импортировать счет-фактуру продавца, чтобы узнать, отмечен ли платеж",
 Sales Invoice Series,Идентификаторы счетов продаж,
-Shopify Tax Account,Уточнить налоговый счет,
+Shopify Tax Account,Shopify налоговый счет,
 Shopify Tax/Shipping Title,Изменить название налога / доставки,
 ERPNext Account,Учетная запись ERPNext,
 Shopify Webhook Detail,Узнайте подробности веб-камеры,
@@ -6193,7 +6193,7 @@
 Inpatient Occupancy,Стационарное размещение,
 Occupancy Status,Статус занятости,
 Vacant,Вакантно,
-Occupied,занятый,
+Occupied,Занято,
 Item Details,Детальная информация о товаре,
 UOM Conversion in Hours,Преобразование UOM в часы,
 Rate / UOM,Скорость / UOM,
@@ -6296,10 +6296,10 @@
 Marital Status,Семейное положение,
 Married,Замужем,
 Divorced,Разведенный,
-Widow,вдова,
+Widow,Вдова,
 Patient Relation,Отношение пациентов,
 "Allergies, Medical and Surgical History","Аллергии, медицинская и хирургическая история",
-Allergies,аллергии,
+Allergies,Аллергии,
 Medication,медикаментозное лечение,
 Medical History,История болезни,
 Surgical History,Хирургическая история,
@@ -6344,7 +6344,7 @@
 Symptoms,Симптомы,
 In print,В печати,
 Medical Coding,Медицинское кодирование,
-Procedures,процедуры,
+Procedures,Поцедуры,
 Therapies,Терапии,
 Review Details,Обзорная информация,
 Patient Encounter Diagnosis,Диагностика встречи с пациентом,
@@ -6352,8 +6352,8 @@
 HLC-PMR-.YYYY.-,HLC-PMR-.YYYY.-,
 Attach Medical Record,Прикрепите медицинскую карту,
 Reference DocType,Ссылка DocType,
-Spouse,супруга,
-Family,семья,
+Spouse,Супруга,
+Family,Семья,
 Schedule Details,Детали расписания,
 Schedule Name,Название расписания,
 Time Slots,Временные интервалы,
@@ -6390,9 +6390,9 @@
 Cuts,Порезы,
 Abdomen,Брюшная полость,
 Bloated,Раздутый,
-Fluid,жидкость,
+Fluid,Жидкость,
 Constipated,Запор,
-Reflexes,рефлексы,
+Reflexes,Рефлексы,
 Hyper,Hyper,
 Very Hyper,Очень Hyper,
 One Sided,Односторонняя,
@@ -6419,7 +6419,7 @@
 Hotel Room Reservation,Бронирование номеров в гостинице,
 Guest Name,Имя гостя,
 Late Checkin,Поздняя регистрация,
-Booked,бронирования,
+Booked,Забронировано,
 Hotel Reservation User,Бронирование отеля,
 Hotel Room Reservation Item,Бронирование номера в гостинице,
 Hotel Settings,Отель,
@@ -6441,7 +6441,7 @@
 Applicant Name,Имя заявителя,
 Appointment Date,Назначенная дата,
 Appointment Letter Template,Шаблон письма о назначении,
-Body,тело,
+Body,Тело,
 Closing Notes,Заметки,
 Appointment Letter content,Письмо о назначении,
 Appraisal,Оценка,
@@ -6456,12 +6456,12 @@
 Weightage (%),Weightage (%),
 Score (0-5),Оценка (0-5),
 Score Earned,Оценка Заработано,
-Appraisal Template Title,Оценка шаблона Название,
-Appraisal Template Goal,Оценка шаблона Гол,
+Appraisal Template Title,Название шаблона оценки,
+Appraisal Template Goal,Цель шаблона оценки,
 KRA,КРА,
-Key Performance Area,Ключ Площадь Производительность,
+Key Performance Area,Ключевая область производительности,
 HR-ATT-.YYYY.-,HR-ATT-.YYYY.-,
-On Leave,в отпуске,
+On Leave,В отпуске,
 Work From Home,Работа из дома,
 Leave Application,Заявление на отпуск,
 Attendance Date,Посещаемость Дата,
@@ -6476,10 +6476,10 @@
 Worked On Holiday,Работал на отдыхе,
 Work From Date,Работа с даты,
 Work End Date,Дата окончания работы,
-Email Sent To,Е-мейл отправлен,
+Email Sent To,Email отправлен,
 Select Users,Выберите пользователей,
 Send Emails At,Отправить электронные письма на,
-Reminder,напоминание,
+Reminder,Напоминание,
 Daily Work Summary Group User,Ежедневная рабочая группа,
 email,Эл. адрес,
 Parent Department,Родительский отдел,
@@ -6495,7 +6495,7 @@
 Skill,Умение,
 Driver,Водитель,
 HR-DRI-.YYYY.-,HR-DRI-.YYYY.-,
-Suspended,подвешенный,
+Suspended,Приостановленный,
 Transporter,Транспортер,
 Applicable for external driver,Применимо для внешнего драйвера,
 Cellphone Number,номер мобильного телефона,
@@ -6614,7 +6614,7 @@
 Year of Passing,Год прохождения,
 Class / Percentage,Класс / в процентах,
 Major/Optional Subjects,Основные / факультативных предметов,
-Employee External Work History,Сотрудник Внешний Работа История,
+Employee External Work History,История внешней работы сотрудника,
 Total Experience,Суммарный опыт,
 Default Leave Policy,Политика по умолчанию,
 Default Salary Structure,Структура заработной платы по умолчанию,
@@ -6628,7 +6628,7 @@
 Employee Onboarding,Сотрудник по бортовому,
 Notify users by email,Уведомить пользователей по электронной почте,
 Employee Onboarding Template,Шаблон рабочего стола,
-Activities,мероприятия,
+Activities,Мероприятия,
 Employee Onboarding Activity,Деятельность бортового персонала,
 Employee Other Income,Другой доход сотрудника,
 Employee Promotion,Продвижение сотрудников,
@@ -6640,7 +6640,7 @@
 Employee Separation Template,Шаблон разделения сотрудников,
 Exit Interview Summary,Выйти из интервью,
 Employee Skill,Навыки сотрудников,
-Proficiency,умение,
+Proficiency,Умения,
 Evaluation Date,Дата оценки,
 Employee Skill Map,Карта навыков сотрудников,
 Employee Skills,Навыки сотрудников,
@@ -6683,7 +6683,7 @@
 Total Claimed Amount,Всего заявленной суммы,
 Total Amount Reimbursed,Общая сумма возмещаются,
 Vehicle Log,Автомобиль Вход,
-Employees Email Id,Идентификаторы Электронных почт сотрудников,
+Employees Email Id,Идентификаторы почты сотрудников,
 More Details,Подробнее,
 Expense Claim Account,Счет Авансового Отчета,
 Expense Claim Advance,Претензия на увеличение расходов,
@@ -6701,7 +6701,7 @@
 HR Settings,Настройки HR,
 Employee Settings,Работники Настройки,
 Retirement Age,Пенсионный возраст,
-Enter retirement age in years,Введите возраст выхода на пенсию в ближайшие годы,
+Enter retirement age in years,Введите возраст выхода на пенсию,
 Stop Birthday Reminders,Стоп День рождения Напоминания,
 Expense Approver Mandatory In Expense Claim,"Утверждение о расходах, обязательный для покрытия расходов",
 Payroll Settings,Настройки по заработной плате,
@@ -6723,7 +6723,7 @@
 Role Allowed to Create Backdated Leave Application,"Роль, разрешенная для создания приложения с задним сроком выхода",
 Leave Approver Mandatory In Leave Application,Утвердить заявление на отпуск,
 Show Leaves Of All Department Members In Calendar,Показать листы всех членов Департамента в календаре,
-Auto Leave Encashment,Авто оставить инкассо,
+Auto Leave Encashment,Автоматический выход из инкассации,
 Hiring Settings,Настройки найма,
 Check Vacancies On Job Offer Creation,Проверьте вакансии на создание предложения о работе,
 Identification Document Type,Тип идентификационного документа,
@@ -6757,7 +6757,7 @@
 Planned number of Positions,Планируемое количество позиций,
 "Job profile, qualifications required etc.","Профиль работы, необходимая квалификация и т.д.",
 HR-LAL-.YYYY.-,HR-LAL-.YYYY.-,
-Allocation,распределение,
+Allocation,Распределение,
 New Leaves Allocated,Новые листья Выделенные,
 Add unused leaves from previous allocations,Добавить неиспользованные отпуска с прошлых периодов,
 Unused leaves,Неиспользованные листья,
@@ -6785,15 +6785,15 @@
 Allow User,Разрешить пользователю,
 Leave Block List Date,Оставьте Блок-лист Дата,
 Block Date,Блок Дата,
-Leave Control Panel,Оставьте панели управления,
-Select Employees,Выберите Сотрудников,
+Leave Control Panel,Выйти из панели управления,
+Select Employees,Выберите сотрудников,
 Employment Type (optional),Тип занятости (необязательно),
 Branch (optional),Филиал (необязательно),
 Department (optional),Отдел (необязательно),
 Designation (optional),Обозначение (необязательно),
 Employee Grade (optional),Оценка сотрудника (необязательно),
 Employee (optional),Сотрудник (необязательно),
-Allocate Leaves,Выделить листья,
+Allocate Leaves,Распределить записи,
 Carry Forward,Переносить,
 Please select Carry Forward if you also want to include previous fiscal year's balance leaves to this fiscal year,"Пожалуйста, выберите переносить, если вы также хотите включить баланс предыдущего финансового года оставляет в этом финансовом году",
 New Leaves Allocated (In Days),Новые листья Выделенные (в днях),
@@ -6811,7 +6811,7 @@
 Leave Policy Details,Оставьте сведения о политике,
 Leave Policy Detail,Оставить информацию о политике,
 Annual Allocation,Ежегодное распределение,
-Leave Type Name,Оставьте Тип Название,
+Leave Type Name,Оставить имя типа,
 Max Leaves Allowed,Максимальные листья разрешены,
 Applicable After (Working Days),Применимые после (рабочие дни),
 Maximum Continuous Days Applicable,Максимальные непрерывные дни,
@@ -6828,9 +6828,9 @@
 Earned Leave,Заработано,
 Is Earned Leave,Заработано,
 Earned Leave Frequency,Заработок,
-Rounding,округление,
-Payroll Employee Detail,Сведения о сотрудниках по расчетам,
-Payroll Frequency,Расчет заработной платы Частота,
+Rounding,Округление,
+Payroll Employee Detail,Сведения о сотруднике по заработной плате,
+Payroll Frequency,Частота расчета заработной платы,
 Fortnightly,раз в две недели,
 Bimonthly,Раз в два месяца,
 Employees,Сотрудники,
@@ -6842,8 +6842,8 @@
 Deduct Tax For Unclaimed Employee Benefits,Вычет налога для невостребованных сотрудников,
 Deduct Tax For Unsubmitted Tax Exemption Proof,Доход от вычета налога за отказ в освобождении от налогов,
 Select Payment Account to make Bank Entry,Выберите Учетная запись Оплата сделать Банк Стажер,
-Salary Slips Created,Созданы зарплатные слайды,
-Salary Slips Submitted,Заявки на зарплату,
+Salary Slips Created,Зарплатные ведомости созданы,
+Salary Slips Submitted,Утвержденные зарплатные ведомости,
 Payroll Periods,Периоды начисления заработной платы,
 Payroll Period Date,Дата периода расчета заработной платы,
 Purpose of Travel,Цель поездки,
@@ -6917,7 +6917,7 @@
 Working Hours Threshold for Half Day,Порог рабочего времени на полдня,
 Working hours below which Half Day is marked. (Zero to disable),"Рабочее время, ниже которого отмечается полдня. (Ноль отключить)",
 Working Hours Threshold for Absent,Порог рабочего времени для отсутствующих,
-Working hours below which Absent is marked. (Zero to disable),"Рабочее время, ниже которого отмечается отсутствие. (Ноль отключить)",
+Working hours below which Absent is marked. (Zero to disable),Порог рабочего времени, ниже которого устанавливается отметка «Отсутствует». (Ноль для отключения),",
 Process Attendance After,Посещаемость процесса после,
 Attendance will be marked automatically only after this date.,Посещаемость будет отмечена автоматически только после этой даты.,
 Last Sync of Checkin,Последняя синхронизация регистрации,
@@ -6960,7 +6960,7 @@
 Employee Emails,Электронные почты сотрудников,
 Training Event Employee,Обучение сотрудников Событие,
 Invited,приглашенный,
-Feedback Submitted,Обратная связь Представлено,
+Feedback Submitted,Отзыв отправлен,
 Optional,Необязательный,
 Training Result Employee,Результат обучения сотрудника,
 Travel Itinerary,Маршрут путешествия,
@@ -6972,7 +6972,7 @@
 Taxi,Такси,
 Rented Car,Прокат автомобилей,
 Meal Preference,Предпочитаемая еда,
-Vegetarian,вегетарианец,
+Vegetarian,Вегетарианец,
 Non-Vegetarian,Не вегетарианский,
 Gluten Free,Не содержит глютен,
 Non Diary,Не дневник,
@@ -6992,7 +6992,7 @@
 Fully Sponsored,Полностью спонсируемый,
 "Partially Sponsored, Require Partial Funding","Частично спонсируется, требует частичного финансирования",
 Copy of Invitation/Announcement,Копия приглашения / объявление,
-"Details of Sponsor (Name, Location)","Подробная информация о спонсоре (название, местоположение)",
+"Details of Sponsor (Name, Location)","Подробная информация о спонсоре (Название, Местоположение)",
 Identification Document Number,Идентификационный номер документа,
 Any other details,Любые другие детали,
 Costing Details,Сведения о стоимости,
@@ -7014,29 +7014,29 @@
 License Plate,Номерной знак,
 Odometer Value (Last),Значение одометра (последнее),
 Acquisition Date,Дата приобретения,
-Chassis No,Шасси Нет,
+Chassis No,VIN код,
 Vehicle Value,Значение автомобиля,
 Insurance Details,Страхование Подробнее,
 Insurance Company,Страховая компания,
-Policy No,Политика Нет,
+Policy No,Полис №,
 Additional Details,дополнительные детали,
 Fuel Type,Тип топлива,
 Petrol,Бензин,
-Diesel,дизель,
+Diesel,Дизель,
 Natural Gas,Природный газ,
-Electric,электрический,
+Electric,Электрический,
 Fuel UOM,Топливо UOM,
-Last Carbon Check,Последний Carbon Проверить,
+Last Carbon Check,Последняя проверка на углерод,
 Wheels,Колеса,
-Doors,двери,
+Doors,Двери,
 HR-VLOG-.YYYY.-,HR-Видеоблог-.YYYY.-,
 Odometer Reading,Показания одометра,
 Current Odometer value ,Текущее значение одометра,
-last Odometer Value ,Значение последнего одометра,
+last Odometer Value ,последнее значение одометра,
 Refuelling Details,Заправочные Подробнее,
 Invoice Ref,Счет-фактура Ссылка,
 Service Details,Сведения о службе,
-Service Detail,Деталь обслуживания,
+Service Detail,Сведения об услуге,
 Vehicle Service,Обслуживание автомобиля,
 Service Item,Продукт-услуга,
 Brake Oil,Тормозные масла,
@@ -7044,8 +7044,8 @@
 Clutch Plate,Диск сцепления,
 Engine Oil,Машинное масло,
 Oil Change,Замена масла,
-Inspection,осмотр,
-Mileage,пробег,
+Inspection,Осмотр,
+Mileage,Пробег,
 Hub Tracked Item,Отслеживаемый элемент концентратора,
 Hub Node,Узел хаба,
 Image List,Список изображений,
@@ -7098,7 +7098,7 @@
 Total Payable Interest,Общая задолженность по процентам,
 Against Loan ,Против ссуды,
 Loan Interest Accrual,Начисление процентов по кредитам,
-Amounts,суммы,
+Amounts,Суммы,
 Pending Principal Amount,Ожидающая основная сумма,
 Payable Principal Amount,Основная сумма к оплате,
 Paid Principal Amount,Выплаченная основная сумма,
@@ -7164,7 +7164,7 @@
 No of Visits,Кол-во посещений,
 MAT-MVS-.YYYY.-,MAT-MVS-.YYYY.-,
 Maintenance Date,Дата технического обслуживания,
-Maintenance Time,Техническое обслуживание Время,
+Maintenance Time,Время технического обслуживания,
 Completion Status,Статус завершения,
 Partially Completed,Частично завершено,
 Fully Completed,Полностью завершен,
@@ -7172,10 +7172,10 @@
 Breakdown,Разбивка,
 Purposes,Цели,
 Customer Feedback,Обратная связь с клиентами,
-Maintenance Visit Purpose,Техническое обслуживание Посетить Цель,
-Work Done,Сделано,
+Maintenance Visit Purpose,Цель технического обслуживания,
+Work Done,Работа выполнена,
 Against Document No,Против Документ №,
-Against Document Detail No,Против деталях документа Нет,
+Against Document Detail No,Против деталях документа №,
 MFG-BLR-.YYYY.-,MFG-BLR-.YYYY.-,
 Order Type,Тип заказа,
 Blanket Order Item,Элемент заказа одеяла,
@@ -7193,8 +7193,8 @@
 Routing,Маршрутизация,
 Materials,Материалы,
 Quality Inspection Required,Требуется проверка качества,
-Quality Inspection Template,Качественный контрольный шаблон,
-Scrap,лом,
+Quality Inspection Template,Шаблон контроля качества,
+Scrap,Брак,
 Scrap Items,Утилизированные продукты,
 Operating Cost,Эксплуатационные затраты,
 Raw Material Cost,Стоимость сырья,
@@ -7243,7 +7243,7 @@
 Operation Time,Время работы,
 PO-JOB.#####,ПО-РАБОТА. #####,
 Timing Detail,Сроки,
-Time Logs,Журналы Время,
+Time Logs,Журналы времени,
 Total Time in Mins,Общее время в минутах,
 Operation ID,ID операции,
 Transferred Qty,Передано кол-во,
@@ -7302,13 +7302,13 @@
 Planned Start Date,Планируемая дата начала,
 Quantity and Description,Количество и описание,
 material_request_item,material_request_item,
-Product Bundle Item,Продукт Связка товара,
+Product Bundle Item,Связка продуктов,
 Production Plan Material Request,Производство План Материал Запрос,
 Production Plan Sales Order,Производственный План по Сделкам,
 Sales Order Date,Дата Сделки,
 Routing Name,Название маршрутизации,
 MFG-WO-.YYYY.-,MFG-WO-.YYYY.-,
-Item To Manufacture,Продукт в производство,
+Item To Manufacture,Продукт для производство,
 Material Transferred for Manufacturing,Материал переведен на Производство,
 Manufactured Qty,Изготовлено Кол-во,
 Use Multi-Level BOM,Использование Multi-Level BOM,
@@ -7381,7 +7381,7 @@
 Meetup Embed HTML,Вставить HTML-код,
 chapters/chapter_name\nleave blank automatically set after saving chapter.,главы / chapter_name оставить пустым автоматически после сохранения главы.,
 Chapter Members,Члены группы,
-Members,члены,
+Members,Участники,
 Chapter Member,Участник,
 Website URL,URL веб-сайта,
 Leave Reason,Оставить разум,
@@ -7391,16 +7391,16 @@
 Grant Application Details ,Сведения о предоставлении гранта,
 Grant Description,Описание гранта,
 Requested Amount,Запрошенная сумма,
-Has any past Grant Record,Имеет ли какая-либо прошлая грантовая запись,
+Has any past Grant Record,Имеет предидущую связь в диаграмме,
 Show on Website,Показать на сайте,
-Assessment  Mark (Out of 10),Оценка Оценка (из 10),
+Assessment  Mark (Out of 10),Оценка (из 10),
 Assessment  Manager,Менеджер по оценке,
-Email Notification Sent,Уведомление отправлено по электронной почте,
+Email Notification Sent,Отправлено уведомление по электронной почте,
 NPO-MEM-.YYYY.-,НПО-MEM-.YYYY.-,
 Membership Expiry Date,Дата истечения срока членства,
 Razorpay Details,Детали Razorpay,
 Subscription ID,ID подписки,
-Customer ID,Пользовательский ИД,
+Customer ID,Пользовательский ID,
 Subscription Activated,Подписка активирована,
 Subscription Start ,Подписка Старт,
 Subscription End,Конец подписки,
@@ -7420,8 +7420,8 @@
 Availability and Skills,Доступность и навыки,
 Availability,Доступность,
 Weekends,Выходные дни,
-Availability Timeslot,Доступность Timeslot,
-Morning,утро,
+Availability Timeslot,Временной интервал доступности,
+Morning,Утро,
 Afternoon,После полудня,
 Evening,Вечер,
 Anytime,В любой момент,
@@ -7430,7 +7430,7 @@
 Homepage,Главная страница,
 Hero Section Based On,Раздел героя на основе,
 Homepage Section,Раздел домашней страницы,
-Hero Section,Раздел героя,
+Hero Section,Раздел героев,
 Tag Line,Tag Line,
 Company Tagline for website homepage,Компания Слоган на главную страницу сайта,
 Company Description for website homepage,Описание компании на главную страницу сайта,
@@ -7448,8 +7448,8 @@
 Section Order,Раздел Заказ,
 "Order in which sections should appear. 0 is first, 1 is second and so on.","Порядок, в котором должны появляться разделы. 0 - первое, 1 - второе и т. Д.",
 Homepage Section Card,Домашняя страница Раздел Карта,
-Subtitle,подзаголовок,
-Products Settings,Настройки Продукты,
+Subtitle,Подзаголовок,
+Products Settings,Настройки продуктов,
 Home Page is Products,Главная — Продукты,
 "If checked, the Home page will be the default Item Group for the website","Если этот флажок установлен, главная страница будет по умолчанию Item Group для веб-сайте",
 Show Availability Status,Показать статус доступности,
@@ -7464,31 +7464,31 @@
 Attribute,Атрибут,
 Website Filter Field,Поле фильтра веб-сайта,
 Activity Cost,Стоимость деятельности,
-Billing Rate,Платежная Оценить,
-Costing Rate,Калькуляция Оценить,
-title,заглавие,
+Billing Rate,Платежная оценка,
+Costing Rate,Стоимость,
+title,название,
 Projects User,Исполнитель проектов,
-Default Costing Rate,По умолчанию Калькуляция Оценить,
-Default Billing Rate,По умолчанию Платежная Оценить,
+Default Costing Rate,Ставка стоимости по умолчанию,
+Default Billing Rate,Платежная ставка по умолчанию,
 Dependent Task,Зависимая задача,
 Project Type,Тип проекта,
-% Complete Method,% Полный метод,
-Task Completion,Завершение задачи,
-Task Progress,Готовность задачи,
+% Complete Method,% выполнения,
+Task Completion,Завершеные задачи,
+Task Progress,Ход выполнения задачи,
 % Completed,% Завершено,
 From Template,Из шаблона,
 Project will be accessible on the website to these users,Проект будет доступен на веб-сайте для этих пользователей,
 Copied From,Скопировано из,
 Start and End Dates,Даты начала и окончания,
 Actual Time (in Hours),Фактическое время (в часах),
-Costing and Billing,Калькуляция и биллинг,
-Total Costing Amount (via Timesheets),Общая сумма калькуляции (через расписания),
-Total Expense Claim (via Expense Claims),Итоговая сумма аванса (через Авансовые Отчеты),
-Total Purchase Cost (via Purchase Invoice),Общая стоимость покупки (через счет покупки),
-Total Sales Amount (via Sales Order),Общая Сумма Продаж (по Сделке),
-Total Billable Amount (via Timesheets),Общая сумма платежа (через расписания),
+Costing and Billing,Стоимость и платежи,
+Total Costing Amount (via Timesheets),Общая стоимость (по табелю учета рабочего времени),
+Total Expense Claim (via Expense Claims),Итоговая сумма аванса (через возмещение расходов),
+Total Purchase Cost (via Purchase Invoice),Общая стоимость покупки (по счетам закупок),
+Total Sales Amount (via Sales Order),Общая сумма продажи (по сделке),
+Total Billable Amount (via Timesheets),Общая сумма платежа (по табелю учета рабочего времени),
 Total Billed Amount (via Sales Invoices),Общая сумма выставленных счетов (через счета-фактуры),
-Total Consumed Material Cost  (via Stock Entry),Общая потребляемая материальная стоимость (через вход запаса),
+Total Consumed Material Cost  (via Stock Entry),Общая потребляемая материальная стоимость (через записи на складе),
 Gross Margin,Валовая прибыль,
 Gross Margin %,Валовая маржа %,
 Monitor Progress,Мониторинг готовности,
@@ -7509,26 +7509,26 @@
 Project User,Пользователь проекта,
 View attachments,Просмотр вложений,
 Projects Settings,Настройки проектов,
-Ignore Workstation Time Overlap,Игнорировать перекрытие рабочей станции,
+Ignore Workstation Time Overlap,Игнорировать перекрытие времени рабочей станции,
 Ignore User Time Overlap,Игнорировать перекрытие пользовательского времени,
-Ignore Employee Time Overlap,Игнорировать перекрытие сотрудников,
+Ignore Employee Time Overlap,Игнорировать перекрытие времени сотрудников,
 Weight,Вес,
 Parent Task,Родительская задача,
 Timeline,График,
 Expected Time (in hours),Ожидаемое время (в часах),
 % Progress,% Прогресс,
-Is Milestone,Это этап,
+Is Milestone,Является этапом,
 Task Description,Описание задания,
-Dependencies,зависимости,
+Dependencies,Зависимости,
 Dependent Tasks,Зависимые задачи,
 Depends on Tasks,Зависит от задач,
-Actual Start Date (via Time Sheet),Фактическая дата начала (с помощью Time Sheet),
+Actual Start Date (via Time Sheet),Фактическая дата начала (по табелю учета рабочего времени),
 Actual Time (in hours),Фактическое время (в часах),
-Actual End Date (via Time Sheet),Фактическая дата окончания (с помощью табеля рабочего времени),
-Total Costing Amount (via Time Sheet),Общая калькуляция Сумма (с помощью Time Sheet),
+Actual End Date (via Time Sheet),Фактическая дата окончания (по табелю учета рабочего времени),
+Total Costing Amount (via Time Sheet),Общая калькуляция Сумма (по табелю учета рабочего времени),
 Total Expense Claim (via Expense Claim),Итоговая сумма аванса (через Авансовый Отчет),
-Total Billing Amount (via Time Sheet),Общая сумма Billing (через табель),
-Review Date,Дата пересмотра,
+Total Billing Amount (via Time Sheet),Общая сумма Billing (по табелю учета рабочего времени),
+Review Date,Дата проверки,
 Closing Date,Дата закрытия,
 Task Depends On,Задача зависит от,
 Task Type,Тип задачи,
@@ -7536,16 +7536,16 @@
 Employee Detail,Сотрудник Деталь,
 Billing Details,Платежные реквизиты,
 Total Billable Hours,Всего человеко-часов,
-Total Billed Hours,Всего Оплачиваемые Часы,
+Total Billed Hours,Всего оплачиваемые часы,
 Total Costing Amount,Общая сумма Стоимостью,
 Total Billable Amount,Общая сумма Выплачиваемый,
 Total Billed Amount,Общая сумма Объявленный,
 % Amount Billed,% Сумма счета,
-Hrs,часов,
+Hrs,Часов,
 Costing Amount,Калькуляция Сумма,
-Corrective/Preventive,Корректирующее / Профилактическая,
-Corrective,корректив,
-Preventive,превентивный,
+Corrective/Preventive,Корректирующее / Превентивная,
+Corrective,Корректив,
+Preventive,Превентивный,
 Resolution,Разрешение,
 Resolutions,Решения,
 Quality Action Resolution,Решение по качеству действий,
@@ -7553,24 +7553,24 @@
 Quality Feedback Template Parameter,Параметр шаблона обратной связи по качеству,
 Quality Goal,Цель качества,
 Monitoring Frequency,Частота мониторинга,
-Weekday,будний день,
+Weekday,Будний день,
 Objectives,Цели,
 Quality Goal Objective,Цель качества,
 Objective,Задача,
 Agenda,Повестка дня,
-Minutes,минут,
-Quality Meeting Agenda,Повестка дня встречи качества,
-Quality Meeting Minutes,Протокол встречи качества,
+Minutes,Минут,
+Quality Meeting Agenda,Встреча для оценки работ,
+Quality Meeting Minutes,Протокол встречи для оценки работ,
 Minute,Минута,
 Parent Procedure,Родительская процедура,
 Processes,Процессы,
-Quality Procedure Process,Процесс качественного процесса,
+Quality Procedure Process,Процедура контроля качества,
 Process Description,Описание процесса,
 Link existing Quality Procedure.,Ссылка существующей процедуры качества.,
 Additional Information,Дополнительная информация,
 Quality Review Objective,Цель проверки качества,
 DATEV Settings,Настройки DATEV,
-Regional,региональный,
+Regional,Региональный,
 Consultant ID,Идентификатор консультанта,
 GST HSN Code,Код GST HSN,
 HSN Code,Код HSN,
@@ -7581,17 +7581,17 @@
 B2C Limit,Ограничение B2C,
 Set Invoice Value for B2C. B2CL and B2CS calculated based on this invoice value.,"Установите значение счета для B2C. B2CL и B2CS, рассчитанные на основе этой стоимости счета.",
 GSTR 3B Report,Отчет GSTR 3B,
-January,январь,
-February,февраль,
-March,марш,
-April,апрель,
+January,Январь,
+February,Февраль,
+March,Март,
+April,Апрель,
 May,Мая,
-June,июнь,
-July,июль,
-August,августейший,
-September,сентябрь,
-October,октября,
-November,ноябрь,
+June,Июнь,
+July,Июль,
+August,Август,
+September,Сентябрь,
+October,Октября,
+November,Ноябрь,
 December,Декабрь,
 JSON Output,Выход JSON,
 Invoices with no Place Of Supply,Счета без места поставки,
@@ -7612,9 +7612,9 @@
 194LA,194LA,
 194LBB,194LBB,
 194LBC,194LBC,
-Certificate No,Сертификат номер,
+Certificate No,Сертификат №,
 Deductee Details,Детали франшизы,
-PAN No,PAN Нет,
+PAN No,PAN №,
 Validity Details,Сведения о сроке действия,
 Rate Of TDS As Per Certificate,Ставка TDS согласно сертификату,
 Certificate Limit,Лимит сертификата,
@@ -7639,13 +7639,13 @@
 Reservation End Time,Время окончания бронирования,
 No of Seats,Количество мест,
 Minimum Seating,Минимальное размещение,
-"Keep Track of Sales Campaigns. Keep track of Leads, Quotations, Sales Order etc from Campaigns to gauge Return on Investment. ","Следите за Кампаниями по продажам. Отслеживайте Обращения, Предложения, Сделки и т.п. от Кампаний и оцените отдачу от инвестиций.",
+"Keep Track of Sales Campaigns. Keep track of Leads, Quotations, Sales Order etc from Campaigns to gauge Return on Investment. ","Следите за Кампаниями по продажам. Отслеживайте Лиды, Предложения, Сделки и т.п. от Кампаний и оцените отдачу от инвестиций.",
 SAL-CAM-.YYYY.-,SAL-CAM-.YYYY.-,
 Campaign Schedules,Расписание кампаний,
 Buyer of Goods and Services.,Покупатель товаров и услуг.,
 CUST-.YYYY.-,КЛИЕНТ-.YYYY.-,
 Default Company Bank Account,Стандартный банковский счет компании,
-From Lead,Из Обращения,
+From Lead,Из Лида,
 Account Manager,Менеджер по работе с клиентами,
 Allow Sales Invoice Creation Without Sales Order,Разрешить создание счета-фактуры без заказа на продажу,
 Allow Sales Invoice Creation Without Delivery Note,Разрешить создание счета-фактуры без накладной,
@@ -7672,11 +7672,11 @@
 Installation Time,Время установки,
 Installation Note Item,Установка Примечание Пункт,
 Installed Qty,Установленное количество,
-Lead Source,Источник Обращения,
+Lead Source,Источник лида,
 Period Start Date,Дата начала периода,
 Period End Date,Дата окончания периода,
 Cashier,Касса,
-Difference,разница,
+Difference,Разница,
 Modes of Payment,Способы оплаты,
 Linked Invoices,Связанные счета-фактуры,
 POS Closing Voucher Details,Информация о закрытии ваучера POS,
@@ -7726,7 +7726,7 @@
 Contact No.,Контактный номер,
 Contribution (%),Вклад (%),
 Contribution to Net Total,Вклад в Сумму,
-Selling Settings,Продажа Настройки,
+Selling Settings,Настройки продаж,
 Settings for Selling Module,Настройки по продаже модуля,
 Customer Naming By,Именование клиентов По,
 Campaign Naming By,Кампания Именование По,
@@ -7742,7 +7742,7 @@
 All Customer Contact,Контакты всех клиентов,
 All Supplier Contact,Всем Контактам Поставщиков,
 All Sales Partner Contact,Всем Контактам Торговых Партнеров,
-All Lead (Open),Всем Обращениям (Созданным),
+All Lead (Open),Всем лидам (Созданным),
 All Employee (Active),Всем Сотрудникам (Активным),
 All Sales Person,Всем Продавцам,
 Create Receiver List,Создать список получателей,
@@ -7859,7 +7859,7 @@
 Purchase Orders Items Overdue,Элементы заказа на поставку просрочены,
 Upcoming Calendar Events,Предстоящие события календаря,
 Open To Do,Открыто делать,
-Add Quote,Добавить Цитата,
+Add Quote,Добавить предложение,
 Global Defaults,Глобальные вводные по умолчанию,
 Default Company,Компания по умолчанию,
 Current Fiscal Year,Текущий финансовый год,
@@ -7908,8 +7908,8 @@
 All Sales Transactions can be tagged against multiple **Sales Persons** so that you can set and monitor targets.,Все сделок купли-продажи могут быть помечены против нескольких ** продавцы ** так что вы можете устанавливать и контролировать цели.,
 Name and Employee ID,Имя и ID сотрудника,
 Sales Person Name,Имя продавца,
-Parent Sales Person,Головная группа продаж,
-Select company name first.,Выберите название компании в первую очередь.,
+Parent Sales Person,Выше стоящий продавец,
+Select company name first.,В первую очередь выберите название компании.,
 Sales Person Targets,Цели продавца,
 Set targets Item Group-wise for this Sales Person.,Задайте цели Продуктовых Групп для Продавца,
 Supplier Group Name,Название группы поставщиков,
@@ -7922,9 +7922,9 @@
 Applicable Modules,Применимые модули,
 Terms and Conditions Help,Правила и условия Помощь,
 Classification of Customers by region,Классификация клиентов по регионам,
-Territory Name,Территория Имя,
-Parent Territory,Родитель Территория,
-Territory Manager,Territory Manager,
+Territory Name,Название региона,
+Parent Territory,Родительский регион,
+Territory Manager,Региональный менеджер,
 For reference,Для справки,
 Territory Targets,Территория Цели,
 Set Item Group-wise budgets on this Territory. You can also include seasonality by setting the Distribution.,"Установите группу товаров стрелке бюджеты на этой территории. Вы можете также включить сезонность, установив распределение.",
@@ -7937,7 +7937,7 @@
 Display Settings,Настройки отображения,
 Show Public Attachments,Показать общедоступные приложения,
 Show Price,Показать цену,
-Show Stock Availability,Доступность,
+Show Stock Availability,Показать наличие на складе,
 Show Contact Us Button,Кнопка «Связаться с нами»,
 Show Stock Quantity,Показывать количество запаса,
 Show Apply Coupon Code,Показать Применить код купона,
@@ -7946,7 +7946,7 @@
 Quotation Series,Идентификаторы Предложений,
 Checkout Settings,Checkout Настройки,
 Enable Checkout,Включить Checkout,
-Payment Success Url,Успех Оплата URL,
+Payment Success Url,URL успешного платежа,
 After payment completion redirect user to selected page.,После завершения оплаты перенаправить пользователя на выбранную страницу.,
 Batch Details,Детали партии,
 Batch ID,ID партии,
@@ -7988,7 +7988,7 @@
 Installation Status,Состояние установки,
 Excise Page Number,Количество Акцизный Страница,
 Instructions,Инструкции,
-From Warehouse,От Склад,
+From Warehouse,Со склада,
 Against Sales Order,По Сделке,
 Against Sales Order Item,По Продукту Сделки,
 Against Sales Invoice,Повторная накладная,
@@ -8003,7 +8003,7 @@
 Send with Attachment,Отправить с прикрепленным файлом,
 Delay between Delivery Stops,Задержка между поставками,
 Delivery Stop,Остановить доставку,
-Lock,Замок,
+Lock,Заблокировано,
 Visited,Посещен,
 Order Information,запросить информацию,
 Contact Information,Контакты,
@@ -8014,7 +8014,7 @@
 Initial Email Notification Sent,Исходящее уведомление по электронной почте отправлено,
 Delivery Details,Подробности доставки,
 Driver Email,Электронная почта водителя,
-Driver Address,Адрес драйвера,
+Driver Address,Адрес водителя,
 Total Estimated Distance,Общее расчетное расстояние,
 Distance UOM,Расстояние UOM,
 Departure Time,Время отправления,
@@ -8049,7 +8049,7 @@
 Will also apply for variants unless overrridden,"Будет также применяться для модификаций, если не отменено",
 Units of Measure,Единицы измерения,
 Will also apply for variants,Также применять к модификациям,
-Serial Nos and Batches,Серийные номера  и партии,
+Serial Nos and Batches,Серийные номера и партии,
 Has Batch No,Имеет номер партии,
 Automatically Create New Batch,Автоматически создавать новую группу,
 Batch Number Series,Партия Идентификаторов по номеру,
@@ -8184,7 +8184,7 @@
 % Ordered,% заказано,
 Terms and Conditions Content,Условия Содержимое,
 Quantity and Warehouse,Количество и Склад,
-Lead Time Date,Время и Дата Обращения,
+Lead Time Date,Время и Дата Лида,
 Min Order Qty,Минимальный заказ Кол-во,
 Packed Item,Упаковано,
 To Warehouse (Optional),На склад (Необязательно),
@@ -8216,7 +8216,7 @@
 Pick List Item,Элемент списка выбора,
 Picked Qty,Выбрал кол-во,
 Price List Master,Прайс-лист Мастер,
-Price List Name,Цена Имя,
+Price List Name,Название прайс-листа,
 Price Not UOM Dependent,Цена не зависит от UOM,
 Applicable for Countries,Применимо для стран,
 Price List Country,Цены Страна,
@@ -8278,7 +8278,7 @@
 Warranty / AMC Details,Гарантия / подробная информация,
 Warranty Expiry Date,Срок действия гарантии,
 AMC Expiry Date,Срок действия AMC,
-Under Warranty,Под гарантии,
+Under Warranty,На гарантии,
 Out of Warranty,По истечении гарантийного срока,
 Under AMC,Под КУА,
 Out of AMC,Из КУА,
@@ -8290,9 +8290,9 @@
 Material Consumption for Manufacture,Потребление материала для производства,
 Repack,Перепаковать,
 Send to Subcontractor,Отправить субподрядчику,
-Delivery Note No,Документ  Отгрузки №,
-Sales Invoice No,№ Счета на продажу,
-Purchase Receipt No,Покупка Получение Нет,
+Delivery Note No,Накладная о доставке №,
+Sales Invoice No,Номер счета на продажу,
+Purchase Receipt No,Квитанция о покупке №,
 Inspection Required,Инспекция Обязательные,
 From BOM,Из спецификации,
 For Quantity,Для Количество,
@@ -8440,7 +8440,7 @@
 Rename Log,Переименовать Входить,
 SMS Log,СМС-журнал,
 Sender Name,Имя отправителя,
-Sent On,Направлено на,
+Sent On,Отправлено на,
 No of Requested SMS,Кол-во запрошенных СМС,
 Requested Numbers,Запрошенные номера,
 No of Sent SMS,Кол-во отправленных СМС,
@@ -8517,8 +8517,8 @@
 Items To Be Requested,Запрашиваемые продукты,
 Reserved,Зарезервировано,
 Itemwise Recommended Reorder Level,Рекомендация пополнения уровня продукта,
-Lead Details,Подробнее об Обращении,
-Lead Owner Efficiency,Эффективность Ответственного за Обращения,
+Lead Details,Подробнее об лиде,
+Lead Owner Efficiency,Эффективность ответственного за лид,
 Loan Repayment and Closure,Погашение и закрытие кредита,
 Loan Security Status,Состояние безопасности ссуды,
 Lost Opportunity,Потерянная возможность,
@@ -8679,7 +8679,7 @@
 Days,Дней,
 Months,Месяцы,
 Book Deferred Entries Via Journal Entry,Книга отложенных записей через запись в журнале,
-Submit Journal Entries,Отправить записи журнала,
+Submit Journal Entries,Утвердить журнальные записи,
 If this is unchecked Journal Entries will be saved in a Draft state and will have to be submitted manually,"Если этот флажок не установлен, записи журнала будут сохранены в состоянии черновик, и их придется отправлять вручную.",
 Enable Distributed Cost Center,Включить центр распределенных затрат,
 Distributed Cost Center,Центр распределенных затрат,
@@ -8797,7 +8797,7 @@
 Customer GSTIN,Клиент GSTIN,
 GST Transporter ID,GST Transporter ID,
 Distance (in km),Расстояние (в км),
-Road,дорога,
+Road,Дорога,
 Air,Воздух,
 Rail,Железнодорожный,
 Ship,Корабль,
@@ -9070,7 +9070,7 @@
 Consider Unmarked Attendance As,Считайте неотмеченную посещаемость как,
 Fraction of Daily Salary for Half Day,Доля дневной заработной платы за полдня,
 Component Type,Тип компонента,
-Provident Fund,резервный фонд,
+Provident Fund,Резервный фонд,
 Additional Provident Fund,Дополнительный резервный фонд,
 Provident Fund Loan,Ссуда из фонда обеспечения персонала,
 Professional Tax,Профессиональный налог,
@@ -9146,8 +9146,8 @@
 Select Assessment Template,Выберите шаблон экзамена,
  out of ,снаружи,
 Select Assessment Parameter,Выберите параметр оценки,
-Gender: ,Пол:,
-Contact: ,Контакты:,
+Gender: ,Пол: ,
+Contact: ,Контакты: ,
 Total Therapy Sessions: ,Всего сеансов терапии:,
 Monthly Therapy Sessions: ,Ежемесячные сеансы терапии:,
 Patient Profile,Профиль пациента,
@@ -9177,7 +9177,7 @@
 There was an error saving the document.,При сохранении документа произошла ошибка.,
 You must select a customer before adding an item.,Перед добавлением товара необходимо выбрать клиента.,
 Please Select a Company,"Пожалуйста, выберите компанию",
-Active Leads,Активные лиды,
+Active Leads,Активные обращения,
 Please Select a Company.,"Пожалуйста, выберите компанию.",
 BOM Operations Time,Время операций по спецификации,
 BOM ID,Идентификатор спецификации,
@@ -9210,8 +9210,8 @@
 Time Required (In Mins),Требуемое время (в минутах),
 From Posting Date,С даты публикации,
 To Posting Date,До даты публикации,
-No records found,записей не найдено,
-Customer/Lead Name,Имя клиента / лида,
+No records found,Записей не найдено,
+Customer/Lead Name,Имя клиента / обратившегося,
 Unmarked Days,Дни без отметок,
 Jan,Янв,
 Feb,Фев,
@@ -9219,9 +9219,9 @@
 Apr,Апр,
 Aug,Авг,
 Sep,Сен,
-Oct,Октябрь,
+Oct,Окт,
 Nov,Ноя,
-Dec,Декабрь,
+Dec,Дек,
 Summarized View,Обобщенный вид,
 Production Planning Report,Отчет о производственном планировании,
 Order Qty,Кол-во заказа,
@@ -9416,7 +9416,7 @@
 "Valuation Rate for the Item {0}, is required to do accounting entries for {1} {2}.","Курс оценки для Предмета {0}, необходим для ведения бухгалтерских записей для {1} {2}.",
  Here are the options to proceed:,"Вот варианты, чтобы продолжить:",
 "If the item is transacting as a Zero Valuation Rate item in this entry, please enable 'Allow Zero Valuation Rate' in the {0} Item table.","Если в этой записи предмет используется как предмет с нулевой оценкой, включите параметр «Разрешить нулевую ставку оценки» в таблице предметов {0}.",
-"If not, you can Cancel / Submit this entry ","Если нет, вы можете отменить / отправить эту запись",
+"If not, you can Cancel / Submit this entry ","Если нет, вы можете отменить / утвердить эту запись",
  performing either one below:,выполнение одного из следующих:,
 Create an incoming stock transaction for the Item.,Создайте проводку входящего запаса для Товара.,
 Mention Valuation Rate in the Item master.,Упомяните коэффициент оценки в мастере предметов.,
@@ -9475,7 +9475,7 @@
 Row #{0}: Child Item should not be a Product Bundle. Please remove Item {1} and Save,Строка № {0}: дочерний элемент не должен быть набором продукта. Удалите элемент {1} и сохраните,
 Credit limit reached for customer {0},Достигнут кредитный лимит для клиента {0},
 Could not auto create Customer due to the following missing mandatory field(s):,Не удалось автоматически создать клиента из-за отсутствия следующих обязательных полей:,
-Please create Customer from Lead {0}.,Создайте клиента из лида {0}.,
+Please create Customer from Lead {0}.,Создайте клиента из обращения {0}.,
 Mandatory Missing,Обязательно отсутствует,
 Please set Payroll based on in Payroll settings,"Пожалуйста, установите Расчет заработной платы на основе в настройках Заработной платы",
 Additional Salary: {0} already exist for Salary Component: {1} for period {2} and {3},Дополнительная зарплата: {0} уже существует для компонента зарплаты: {1} за период {2} и {3},
@@ -9623,7 +9623,7 @@
 Is Order Completed,Заказ выполнен,
 Employee Records to Be Created By,"Записи о сотрудниках, которые будут создавать",
 Employee records are created using the selected field,Записи о сотрудниках создаются с использованием выбранного поля,
-Don't send employee birthday reminders,Не отправляйте сотрудникам напоминания о днях рождения,
+Don't send employee birthday reminders,Не отправлять сотрудникам напоминания о днях рождения,
 Restrict Backdated Leave Applications,Ограничение подачи заявлений на отпуск задним числом,
 Sequence ID,Идентификатор последовательности,
 Sequence Id,Идентификатор последовательности,
@@ -9677,7 +9677,7 @@
 Mpesa Account Balance Processing Error,Ошибка обработки остатка на счете Mpesa,
 Balance Details,Детали баланса,
 Current Balance,Текущий баланс,
-Available Balance,доступные средства,
+Available Balance,Доступные средства,
 Reserved Balance,Зарезервированный баланс,
 Uncleared Balance,Неочищенный баланс,
 Payment related to {0} is not completed,"Платеж, связанный с {0}, не завершен",
@@ -9744,7 +9744,7 @@
 Edit Receipt,Редактировать квитанцию,
 Focus on search input,Сосредоточьтесь на вводе поиска,
 Focus on Item Group filter,Фильтр по группам товаров,
-Checkout Order / Submit Order / New Order,Заказ оформления заказа / Отправить заказ / Новый заказ,
+Checkout Order / Submit Order / New Order,Оформление заказа / Утвердить заказ / Новый заказ,
 Add Order Discount,Добавить скидку на заказ,
 Item Code: {0} is not available under warehouse {1}.,Код товара: {0} недоступен на складе {1}.,
 Serial numbers unavailable for Item {0} under warehouse {1}. Please try changing warehouse.,Отсутствуют серийные номера для позиции {0} на складе {1}. Попробуйте сменить склад.,
@@ -9813,7 +9813,7 @@
 Invalid POS Invoices,Недействительные счета-фактуры POS,
 Please add the account to root level Company - {},"Пожалуйста, добавьте аккаунт в компанию корневого уровня - {}",
 "While creating account for Child Company {0}, parent account {1} not found. Please create the parent account in corresponding COA","При создании аккаунта для дочерней компании {0} родительский аккаунт {1} не найден. Пожалуйста, создайте родительский аккаунт в соответствующем сертификате подлинности",
-Account Not Found,Аккаунт не найден,
+Account Not Found,Счет не найден,
 "While creating account for Child Company {0}, parent account {1} found as a ledger account.",При создании аккаунта для дочерней компании {0} родительский аккаунт {1} обнаружен как счет главной книги.,
 Please convert the parent account in corresponding child company to a group account.,Преобразуйте родительскую учетную запись в соответствующей дочерней компании в групповую.,
 Invalid Parent Account,Неверный родительский аккаунт,
diff --git a/requirements.txt b/requirements.txt
index 657054f..85ff515 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,6 @@
 # frappe   # https://github.com/frappe/frappe is installed during bench-init
 gocardless-pro~=1.22.0
 googlemaps
-pandas>=1.1.5,<2.0.0
 plaid-python~=7.2.1
 pycountry~=20.7.3
 PyGithub~=1.55