Merge pull request #27124 from GangaManoj/gross-profit-product-bundle

feat: Improve Product Bundle handling
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index 566323a..e762580 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -16,3 +16,4 @@
 
 # Whitespace fix throughout codebase
 4551d7d6029b6f587f6c99d4f8df5519241c6a86
+b147b85e6ac19a9220cd1e2958a6ebd99373283a
diff --git a/.github/helper/.flake8_strict b/.github/helper/.flake8_strict
new file mode 100644
index 0000000..c17871d
--- /dev/null
+++ b/.github/helper/.flake8_strict
@@ -0,0 +1,72 @@
+[flake8]
+ignore =
+    B007,
+    B950,
+    E101,
+    E111,
+    E114,
+    E116,
+    E117,
+    E121,
+    E122,
+    E123,
+    E124,
+    E125,
+    E126,
+    E127,
+    E128,
+    E131,
+    E201,
+    E202,
+    E203,
+    E211,
+    E221,
+    E222,
+    E223,
+    E224,
+    E225,
+    E226,
+    E228,
+    E231,
+    E241,
+    E242,
+    E251,
+    E261,
+    E262,
+    E265,
+    E266,
+    E271,
+    E272,
+    E273,
+    E274,
+    E301,
+    E302,
+    E303,
+    E305,
+    E306,
+    E401,
+    E402,
+    E501,
+    E502,
+    E701,
+    E702,
+    E703,
+    E741,
+    F401,
+    F403,
+    W191,
+    W291,
+    W292,
+    W293,
+    W391,
+    W503,
+    W504,
+    E711,
+    E129,
+    F841,
+    E713,
+    E712,
+
+
+max-line-length = 200
+exclude=.github/helper/semgrep_rules,test_*.py
diff --git a/.github/helper/semgrep_rules/report.py b/.github/helper/semgrep_rules/report.py
new file mode 100644
index 0000000..ff27840
--- /dev/null
+++ b/.github/helper/semgrep_rules/report.py
@@ -0,0 +1,15 @@
+from frappe import _
+
+
+# ruleid: frappe-missing-translate-function-in-report-python
+{"label": "Field Label"}
+
+# ruleid: frappe-missing-translate-function-in-report-python
+dict(label="Field Label")
+
+
+# ok: frappe-missing-translate-function-in-report-python
+{"label": _("Field Label")}
+
+# ok: frappe-missing-translate-function-in-report-python
+dict(label=_("Field Label"))
diff --git a/.github/helper/semgrep_rules/report.yml b/.github/helper/semgrep_rules/report.yml
new file mode 100644
index 0000000..7f3dd01
--- /dev/null
+++ b/.github/helper/semgrep_rules/report.yml
@@ -0,0 +1,21 @@
+rules:
+- id: frappe-missing-translate-function-in-report-python
+  paths:
+    include:
+    - "**/report"
+    exclude:
+    - "**/regional"
+  pattern-either:
+  - patterns:
+      - pattern: |
+          {..., "label": "...", ...}
+      - pattern-not: |
+          {..., "label": _("..."), ...}
+  - patterns:
+      - pattern: dict(..., label="...", ...)
+      - pattern-not: dict(..., label=_("..."), ...)
+  message: |
+      All user facing text must be wrapped in translate function. Please refer to translation documentation. https://frappeframework.com/docs/user/en/guides/basics/translations
+  languages: [python]
+  severity: ERROR
+
diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml
new file mode 100644
index 0000000..c236339
--- /dev/null
+++ b/.github/workflows/linters.yml
@@ -0,0 +1,27 @@
+name: Linters
+
+on:
+  pull_request: { }
+
+jobs:
+
+  linters:
+    name: linters
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: returntocorp/semgrep-action@v1
+        env:
+            SEMGREP_TIMEOUT: 120
+        with:
+            config: >-
+              r/python.lang.correctness
+              .github/helper/semgrep_rules
+
+      - name: Set up Python 3.8
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3.8
+
+      - name: Install and Run Pre-commit
+        uses: pre-commit/action@v2.0.0
diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml
deleted file mode 100644
index e27b406..0000000
--- a/.github/workflows/semgrep.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-name: Semgrep
-
-on:
-  pull_request: { }
-
-jobs:
-  semgrep:
-    name: Frappe Linter
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v2
-      - uses: returntocorp/semgrep-action@v1
-        env:
-            SEMGREP_TIMEOUT: 120
-        with:
-            config: >-
-              r/python.lang.correctness
-              .github/helper/semgrep_rules
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..df15b68
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,29 @@
+exclude: 'node_modules|.git'
+default_stages: [commit]
+fail_fast: false
+
+
+repos:
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v4.0.1
+    hooks:
+      - id: trailing-whitespace
+        files: "erpnext.*"
+        exclude: ".*json$|.*txt$|.*csv|.*md"
+      - id: check-yaml
+      - id: no-commit-to-branch
+        args: ['--branch', 'develop']
+      - id: check-merge-conflict
+      - id: check-ast
+
+  - repo: https://gitlab.com/pycqa/flake8
+    rev: 3.9.2
+    hooks:
+      - id: flake8
+        args: ['--config', '.github/helper/.flake8_strict']
+        exclude: ".*setup.py$"
+
+ci:
+    autoupdate_schedule: weekly
+    skip: []
+    submodules: false
diff --git a/erpnext/accounts/custom/address.py b/erpnext/accounts/custom/address.py
index 834227b..628b713 100644
--- a/erpnext/accounts/custom/address.py
+++ b/erpnext/accounts/custom/address.py
@@ -31,7 +31,7 @@
 		customers = frappe.db.get_all("Customer", filters=filters, as_list=True)
 		for customer_name in customers:
 			frappe.db.set_value("Customer", customer_name[0], "primary_address", address_display)
-			
+
 @frappe.whitelist()
 def get_shipping_address(company, address = None):
 	filters = [
diff --git a/erpnext/accounts/deferred_revenue.py b/erpnext/accounts/deferred_revenue.py
index 0c81d83..173b1ee 100644
--- a/erpnext/accounts/deferred_revenue.py
+++ b/erpnext/accounts/deferred_revenue.py
@@ -359,7 +359,7 @@
 		try:
 			make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
 			frappe.db.commit()
-		except:
+		except Exception:
 			frappe.db.rollback()
 			traceback = frappe.get_traceback()
 			frappe.log_error(message=traceback)
@@ -430,7 +430,7 @@
 
 		if submit:
 			journal_entry.submit()
-	except:
+	except Exception:
 		frappe.db.rollback()
 		traceback = frappe.get_traceback()
 		frappe.log_error(message=traceback)
diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py
index 7ea71fc..235af2d 100644
--- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py
+++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py
@@ -21,7 +21,7 @@
 		self.update_allocations()
 		self.clear_linked_payment_entries()
 		self.set_status(update=True)
-	
+
 	def on_cancel(self):
 		self.clear_linked_payment_entries(for_cancel=True)
 		self.set_status(update=True)
@@ -45,7 +45,7 @@
 			frappe.db.set_value(self.doctype, self.name, "status", "Reconciled")
 
 		self.reload()
-	
+
 	def clear_linked_payment_entries(self, for_cancel=False):
 		for payment_entry in self.payment_entries:
 			if payment_entry.payment_document in ["Payment Entry", "Journal Entry", "Purchase Invoice", "Expense Claim"]:
@@ -77,7 +77,7 @@
 
 def get_reconciled_bank_transactions(payment_entry):
 	reconciled_bank_transactions = frappe.get_all(
-		'Bank Transaction Payments', 
+		'Bank Transaction Payments',
 		filters = {
 			'payment_entry': payment_entry.payment_entry
 		},
diff --git a/erpnext/accounts/doctype/finance_book/test_finance_book.py b/erpnext/accounts/doctype/finance_book/test_finance_book.py
index 2ba2139..bb9a46d 100644
--- a/erpnext/accounts/doctype/finance_book/test_finance_book.py
+++ b/erpnext/accounts/doctype/finance_book/test_finance_book.py
@@ -40,4 +40,4 @@
 	else:
 		finance_book = frappe.get_doc("Finance Book", "_Test Finance Book")
 
-	return finance_book
\ No newline at end of file
+	return finance_book
diff --git a/erpnext/accounts/doctype/party_link/party_link.py b/erpnext/accounts/doctype/party_link/party_link.py
index 7d58506..9cbba35 100644
--- a/erpnext/accounts/doctype/party_link/party_link.py
+++ b/erpnext/accounts/doctype/party_link/party_link.py
@@ -10,14 +10,14 @@
 		if self.primary_role not in ['Customer', 'Supplier']:
 			frappe.throw(_("Allowed primary roles are 'Customer' and 'Supplier'. Please select one of these roles only."),
 				title=_("Invalid Primary Role"))
-		
+
 		existing_party_link = frappe.get_all('Party Link', {
 			'primary_party': self.secondary_party
 		}, pluck="primary_role")
 		if existing_party_link:
 			frappe.throw(_('{} {} is already linked with another {}')
 				.format(self.secondary_role, self.secondary_party, existing_party_link[0]))
-		
+
 		existing_party_link = frappe.get_all('Party Link', {
 			'secondary_party': self.primary_party
 		}, pluck="primary_role")
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index a5fcad4..f9fa63d 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -484,7 +484,7 @@
 
 	def validate_amounts(self):
 		self.validate_received_amount()
-	
+
 	def validate_received_amount(self):
 		if self.paid_from_account_currency == self.paid_to_account_currency:
 			if self.paid_amount != self.received_amount:
diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
index 289278e..ebe55f6 100644
--- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
+++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
@@ -54,7 +54,7 @@
 		if gl_entries:
 			from erpnext.accounts.general_ledger import make_gl_entries
 			make_gl_entries(gl_entries)
-	
+
 	def get_gl_entries(self):
 		gl_entries = []
 		pl_accounts = self.get_pl_balances()
@@ -77,7 +77,7 @@
 			gl_entries += gle_for_net_pl_bal
 
 		return gl_entries
-	
+
 	def get_pnl_gl_entry(self, pl_accounts):
 		company_cost_center = frappe.db.get_value("Company", self.company, "cost_center")
 		gl_entries = []
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index 4903c50..ccfb29f 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -203,13 +203,13 @@
 	serialized_items = dict()
 	for item_code, val in query_items:
 		serialized_items.setdefault(item_code, val)
-	
+
 	for item in item_list:
 		args_copy = copy.deepcopy(args)
 		args_copy.update(item)
 		data = get_pricing_rule_for_item(args_copy, item.get('price_list_rate'), doc=doc)
 		out.append(data)
-		
+
 		if serialized_items.get(item.get('item_code')) and not item.get("serial_no") and set_serial_nos_based_on_fifo and not args.get('is_return'):
 			out[0].update(get_serial_no_for_item(args_copy))
 
@@ -315,9 +315,8 @@
 	if not (args.item_group and args.brand):
 		try:
 			args.item_group, args.brand = frappe.get_cached_value("Item", args.item_code, ["item_group", "brand"])
-		except TypeError:
-			# invalid item_code
-			return item_details
+		except frappe.DoesNotExistError:
+			return
 		if not args.item_group:
 			frappe.throw(_("Item Group not mentioned in item master for item {0}").format(args.item_code))
 
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 5467cb0..6f24587 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -81,7 +81,7 @@
 				try:
 					if frappe.safe_eval(pricing_rule.condition, None, doc.as_dict()):
 						filtered_pricing_rules.append(pricing_rule)
-				except:
+				except Exception:
 					pass
 			else:
 				filtered_pricing_rules.append(pricing_rule)
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 a12ea40..30b1edc 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
@@ -158,7 +158,7 @@
 	if doc.cc_to != '':
 		try:
 			cc=[frappe.get_value('User', doc.cc_to, 'email')]
-		except:
+		except Exception:
 			pass
 
 	return recipients, cc
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index fe3ed16..93546c3 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -24,7 +24,6 @@
 from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import get_party_tax_withholding_details
 from frappe.model.utils import get_fetch_values
 from frappe.contacts.doctype.address.address import get_address_display
-from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import get_party_tax_withholding_details
 
 from erpnext.healthcare.utils import manage_invoice_submit_cancel
 
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js
index 97a6fdd..066c4ea 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js
@@ -4,4 +4,3 @@
 cur_frm.cscript.tax_table = "Sales Taxes and Charges";
 
 {% include "erpnext/public/js/controllers/accounts.js" %}
-
diff --git a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
index 0cb872c..5772ac2 100644
--- a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
+++ b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
@@ -240,7 +240,7 @@
 def get_tds_amount(ldc, parties, inv, tax_details, fiscal_year_details, tax_deducted, vouchers):
 	tds_amount = 0
 	invoice_filters = {
-		'name': ('in', vouchers), 
+		'name': ('in', vouchers),
 		'docstatus': 1,
 		'apply_tds': 1
 	}
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index de7dde9..b78ea42 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -648,7 +648,7 @@
 	if out:
 		try:
 			return out[0][0]
-		except:
+		except Exception:
 			return None
 	else:
 		return None
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 39ff804..f5309cd 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -339,7 +339,7 @@
 	"""Sort root types as Asset, Liability, Equity, Income, Expense"""
 
 	def compare_accounts(a, b):
-		if re.split('\W+', a[key])[0].isdigit():
+		if re.split(r'\W+', a[key])[0].isdigit():
 			# if chart of accounts is numbered, then sort by number
 			return cmp(a[key], b[key])
 		elif is_root:
diff --git a/erpnext/agriculture/doctype/disease/disease.py b/erpnext/agriculture/doctype/disease/disease.py
index affa570..8e6ceb4 100644
--- a/erpnext/agriculture/doctype/disease/disease.py
+++ b/erpnext/agriculture/doctype/disease/disease.py
@@ -6,7 +6,6 @@
 import frappe
 from frappe import _
 from frappe.model.document import Document
-from frappe import _
 
 class Disease(Document):
 	def validate(self):
diff --git a/erpnext/agriculture/doctype/soil_texture/soil_texture.py b/erpnext/agriculture/doctype/soil_texture/soil_texture.py
index 209b2c8..d7a5f09 100644
--- a/erpnext/agriculture/doctype/soil_texture/soil_texture.py
+++ b/erpnext/agriculture/doctype/soil_texture/soil_texture.py
@@ -7,7 +7,6 @@
 from frappe import _
 from frappe.model.document import Document
 from frappe.utils import flt, cint
-from frappe import _
 
 class SoilTexture(Document):
 	soil_edit_order = [2, 1, 0]
diff --git a/erpnext/agriculture/doctype/water_analysis/water_analysis.py b/erpnext/agriculture/doctype/water_analysis/water_analysis.py
index cb2691d..ece0700 100644
--- a/erpnext/agriculture/doctype/water_analysis/water_analysis.py
+++ b/erpnext/agriculture/doctype/water_analysis/water_analysis.py
@@ -6,7 +6,6 @@
 import frappe
 from frappe import _
 from frappe.model.document import Document
-from frappe import _
 
 class WaterAnalysis(Document):
 	@frappe.whitelist()
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 7afb43b..f1bf31a 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -11,7 +11,7 @@
 from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
 from erpnext.assets.doctype.asset.depreciation \
 	import get_disposal_account_and_cost_center, get_depreciation_accounts
-from erpnext.accounts.general_ledger import make_gl_entries, make_reverse_gl_entries
+from erpnext.accounts.general_ledger import make_reverse_gl_entries
 from erpnext.accounts.utils import get_account_currency
 from erpnext.controllers.accounts_controller import AccountsController
 
@@ -546,7 +546,7 @@
 		cwip_account = None
 		try:
 			cwip_account = get_asset_account("capital_work_in_progress_account", self.name, self.asset_category, self.company)
-		except:
+		except Exception:
 			# if no cwip account found in category or company and "cwip is enabled" then raise else silently pass
 			if cwip_enabled:
 				raise
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index 01486fc..f673a9b 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -63,7 +63,7 @@
 
 	if doc.doctype in ("Delivery Note", "Sales Invoice"):
 		for d in frappe.db.sql("""select item_code, qty, serial_no, batch_no from `tabPacked Item`
-			where parent = %s""".format(doc.doctype), doc.return_against, as_dict=1):
+			where parent = %s""", doc.return_against, as_dict=1):
 				valid_items = get_ref_item_dict(valid_items, d)
 
 	already_returned_items = get_already_returned_items(doc)
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 7c6d355..993c354 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -686,7 +686,7 @@
 				'mode_of_payment': default_mode_of_payment.mode_of_payment,
 				'amount': total_amount_to_pay,
 				'default': 1
-			})	
+			})
 
 def get_itemised_tax_breakup_html(doc):
 	if not doc.taxes:
diff --git a/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py b/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py
index 27f14b1..ad781d6 100644
--- a/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py
+++ b/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py
@@ -28,10 +28,10 @@
 			to_time = datetime.datetime.strptime(
 				self.min_date+record.to_time, self.format_string)
 			timedelta = to_time-from_time
-			self.validate_from_and_to_time(from_time, to_time)
+			self.validate_from_and_to_time(from_time, to_time, record)
 			self.duration_is_divisible(from_time, to_time)
 
-	def validate_from_and_to_time(self, from_time, to_time):
+	def validate_from_and_to_time(self, from_time, to_time, record):
 		if from_time > to_time:
 			err_msg = _('<b>From Time</b> cannot be later than <b>To Time</b> for {0}').format(record.day_of_week)
 			frappe.throw(_(err_msg))
diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py
index aa6c07b..7610a24 100644
--- a/erpnext/crm/doctype/lead/lead.py
+++ b/erpnext/crm/doctype/lead/lead.py
@@ -174,6 +174,7 @@
 			"salutation": self.salutation,
 			"gender": self.gender,
 			"designation": self.designation,
+			"company_name": self.company_name,
 		})
 
 		if self.email_id:
@@ -371,4 +372,3 @@
 	prospect.save(ignore_permissions=True)
 	frappe.msgprint(_('Lead {0} has been added to prospect {1}.').format(frappe.bold(lead), frappe.bold(prospect.name)),
 		title=_('Lead Added'), indicator='green')
-	
\ No newline at end of file
diff --git a/erpnext/crm/doctype/linkedin_settings/linkedin_settings.py b/erpnext/crm/doctype/linkedin_settings/linkedin_settings.py
index 9b88d78..c56eed8 100644
--- a/erpnext/crm/doctype/linkedin_settings/linkedin_settings.py
+++ b/erpnext/crm/doctype/linkedin_settings/linkedin_settings.py
@@ -146,7 +146,7 @@
 
 		except Exception as e:
 			self.api_error(response)
-		
+
 		return response
 
 	def get_headers(self):
@@ -168,7 +168,7 @@
 				raise
 		except Exception:
 			self.api_error(response)
-	
+
 	def get_post(self, post_id):
 		url = "https://api.linkedin.com/v2/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn:li:organization:{0}&shares[0]=urn:li:share:{1}".format(self.company_id, post_id)
 
@@ -176,7 +176,7 @@
 			response = requests.get(url=url, headers=self.get_headers())
 			if response.status_code !=200:
 				raise
-	
+
 		except Exception:
 			self.api_error(response)
 
diff --git a/erpnext/crm/doctype/prospect/prospect.py b/erpnext/crm/doctype/prospect/prospect.py
index 5f5815d..3fa6fe8 100644
--- a/erpnext/crm/doctype/prospect/prospect.py
+++ b/erpnext/crm/doctype/prospect/prospect.py
@@ -15,7 +15,7 @@
 
 	def on_update(self):
 		self.link_with_lead_contact_and_address()
-	
+
 	def on_trash(self):
 		self.unlink_dynamic_links()
 
diff --git a/erpnext/crm/doctype/social_media_post/social_media_post.js b/erpnext/crm/doctype/social_media_post/social_media_post.js
index a8f5dee..6874caa 100644
--- a/erpnext/crm/doctype/social_media_post/social_media_post.js
+++ b/erpnext/crm/doctype/social_media_post/social_media_post.js
@@ -80,10 +80,10 @@
 
 	refresh: function(frm) {
 		frm.trigger('text');
-	
+
 		if (frm.doc.docstatus === 1) {
 			if (!['Posted', 'Deleted'].includes(frm.doc.post_status)) {
-				frm.trigger('add_post_btn'); 
+				frm.trigger('add_post_btn');
 			}
 			if (frm.doc.post_status !='Deleted') {
 				frm.add_custom_button(('Delete Post'), function() {
diff --git a/erpnext/crm/doctype/social_media_post/social_media_post.py b/erpnext/crm/doctype/social_media_post/social_media_post.py
index 95320bf..8e441ed 100644
--- a/erpnext/crm/doctype/social_media_post/social_media_post.py
+++ b/erpnext/crm/doctype/social_media_post/social_media_post.py
@@ -26,7 +26,7 @@
 		if self.scheduled_time:
 			self.post_status = "Scheduled"
 		super(SocialMediaPost, self).submit()
-	
+
 	def on_cancel(self):
 		self.db_set('post_status', 'Cancelled')
 
@@ -35,11 +35,11 @@
 		if self.twitter and self.twitter_post_id:
 			twitter = frappe.get_doc("Twitter Settings")
 			twitter.delete_tweet(self.twitter_post_id)
-	
+
 		if self.linkedin and self.linkedin_post_id:
 			linkedin = frappe.get_doc("LinkedIn Settings")
 			linkedin.delete_post(self.linkedin_post_id)
-		
+
 		self.db_set('post_status', 'Deleted')
 
 	@frappe.whitelist()
@@ -51,7 +51,7 @@
 		if self.twitter and self.twitter_post_id:
 			twitter = frappe.get_doc("Twitter Settings")
 			response['twitter'] = twitter.get_tweet(self.twitter_post_id)
-		
+
 		return response
 
 	@frappe.whitelist()
@@ -67,7 +67,7 @@
 				self.db_set("linkedin_post_id", linkedin_post.headers['X-RestLi-Id'])
 			self.db_set("post_status", "Posted")
 
-		except:
+		except Exception:
 			self.db_set("post_status", "Error")
 			title = _("Error while POSTING {0}").format(self.name)
 			frappe.log_error(message=frappe.get_traceback(), title=title)
diff --git a/erpnext/crm/doctype/twitter_settings/twitter_settings.py b/erpnext/crm/doctype/twitter_settings/twitter_settings.py
index 4775656..9c37ffd 100644
--- a/erpnext/crm/doctype/twitter_settings/twitter_settings.py
+++ b/erpnext/crm/doctype/twitter_settings/twitter_settings.py
@@ -53,10 +53,10 @@
 			frappe.throw(_('Invalid Consumer Key or Consumer Secret Key'))
 
 	def get_api(self):
-		# authentication of consumer key and secret 
-		auth = tweepy.OAuthHandler(self.consumer_key, self.get_password(fieldname="consumer_secret")) 
-		# authentication of access token and secret 
-		auth.set_access_token(self.access_token, self.access_token_secret) 
+		# authentication of consumer key and secret
+		auth = tweepy.OAuthHandler(self.consumer_key, self.get_password(fieldname="consumer_secret"))
+		# authentication of access token and secret
+		auth.set_access_token(self.access_token, self.access_token_secret)
 
 		return tweepy.API(auth)
 
@@ -90,20 +90,20 @@
 
 	def delete_tweet(self, tweet_id):
 		api = self.get_api()
-		try: 
+		try:
 			api.destroy_status(tweet_id)
 		except TweepError as e:
 			self.api_error(e)
 
 	def get_tweet(self, tweet_id):
 		api = self.get_api()
-		try: 
+		try:
 			response = api.get_status(tweet_id, trim_user=True, include_entities=True)
 		except TweepError as e:
 			self.api_error(e)
-		
+
 		return response._json
-	
+
 	def api_error(self, e):
 		content = json.loads(e.response.content)
 		content = content["errors"][0]
diff --git a/erpnext/demo/demo.py b/erpnext/demo/demo.py
index e89b689..a4e4220 100644
--- a/erpnext/demo/demo.py
+++ b/erpnext/demo/demo.py
@@ -88,7 +88,7 @@
 			elif domain=='Education':
 				edu.work()
 
-		except:
+		except Exception:
 			frappe.db.set_global('demo_last_date', current_date)
 			raise
 		finally:
diff --git a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.py b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.py
index 0f2ea96..66587f0 100644
--- a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.py
+++ b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.py
@@ -95,7 +95,7 @@
 				if self.day == calendar.day_name[getdate(d.schedule_date).weekday()]:
 					frappe.delete_doc("Course Schedule", d.name)
 					rescheduled.append(d.name)
-			except:
+			except Exception:
 				reschedule_errors.append(d.name)
 		return rescheduled, reschedule_errors
 
diff --git a/erpnext/education/utils.py b/erpnext/education/utils.py
index 3070e6a..7ce8212 100644
--- a/erpnext/education/utils.py
+++ b/erpnext/education/utils.py
@@ -219,7 +219,7 @@
 	try:
 		quiz = frappe.get_doc("Quiz", quiz_name)
 		questions = quiz.get_questions()
-	except:
+	except Exception:
 		frappe.throw(_("Quiz {0} does not exist").format(quiz_name), frappe.DoesNotExistError)
 		return None
 
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/xml_utils.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/xml_utils.py
index 99ede8f..52ba023 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/xml_utils.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/xml_utils.py
@@ -88,7 +88,7 @@
 		ns = http://cs.sfsu.edu/csc867/myscheduler
 		name = patients
 		"""
-		result = re.compile("\{(.*)\}(.*)").search(tag)
+		result = re.compile(r"\{(.*)\}(.*)").search(tag)
 		if result:
 			value.namespace, tag = result.groups()
 
diff --git a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py
index 907a223..77dba8b 100644
--- a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py
+++ b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py
@@ -266,7 +266,7 @@
 
 			self.is_master_data_processed = 1
 
-		except:
+		except Exception:
 			self.publish("Process Master Data", _("Process Failed"), -1, 5)
 			self.log()
 
@@ -302,14 +302,14 @@
 				try:
 					party_doc = frappe.get_doc(party)
 					party_doc.insert()
-				except:
+				except Exception:
 					self.log(party_doc)
 			addresses_file = frappe.get_doc("File", {"file_url": addresses_file_url})
 			for address in json.loads(addresses_file.get_content()):
 				try:
 					address_doc = frappe.get_doc(address)
 					address_doc.insert(ignore_mandatory=True)
-				except:
+				except Exception:
 					self.log(address_doc)
 
 		def create_items_uoms(items_file_url, uoms_file_url):
@@ -319,7 +319,7 @@
 					try:
 						uom_doc = frappe.get_doc(uom)
 						uom_doc.insert()
-					except:
+					except Exception:
 						self.log(uom_doc)
 
 			items_file = frappe.get_doc("File", {"file_url": items_file_url})
@@ -327,7 +327,7 @@
 				try:
 					item_doc = frappe.get_doc(item)
 					item_doc.insert()
-				except:
+				except Exception:
 					self.log(item_doc)
 
 		try:
@@ -346,7 +346,7 @@
 			self.is_master_data_imported = 1
 			frappe.db.commit()
 
-		except:
+		except Exception:
 			self.publish("Import Master Data", _("Process Failed"), -1, 5)
 			frappe.db.rollback()
 			self.log()
@@ -370,7 +370,7 @@
 					if processed_voucher:
 						vouchers.append(processed_voucher)
 					frappe.db.commit()
-				except:
+				except Exception:
 					frappe.db.rollback()
 					self.log(voucher)
 			return vouchers
@@ -494,7 +494,7 @@
 
 			self.is_day_book_data_processed = 1
 
-		except:
+		except Exception:
 			self.publish("Process Day Book Data", _("Process Failed"), -1, 5)
 			self.log()
 
@@ -564,7 +564,7 @@
 					is_last = True
 				frappe.enqueue_doc(self.doctype, self.name, "_import_vouchers", queue="long", timeout=3600, start=index+1, total=total, is_last=is_last)
 
-		except:
+		except Exception:
 			self.log()
 
 		finally:
@@ -583,7 +583,7 @@
 				voucher_doc.submit()
 				self.publish("Importing Vouchers", _("{} of {}").format(index, total), index, total)
 				frappe.db.commit()
-			except:
+			except Exception:
 				frappe.db.rollback()
 				self.log(voucher_doc)
 
diff --git a/erpnext/erpnext_integrations/taxjar_integration.py b/erpnext/erpnext_integrations/taxjar_integration.py
index 83764ae..574fe25 100644
--- a/erpnext/erpnext_integrations/taxjar_integration.py
+++ b/erpnext/erpnext_integrations/taxjar_integration.py
@@ -15,7 +15,7 @@
 	"SE", "SI", "SK", "US"]
 SUPPORTED_STATE_CODES = ['AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'DC', 'FL', 'GA', 'HI', 'ID', 'IL',
 	'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MD', 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE',
-	'NV', 'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 
+	'NV', 'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD',
 	'TN', 'TX', 'UT', 'VT', 'VA', 'WA', 'WV', 'WI', 'WY']
 
 
@@ -66,7 +66,7 @@
 	try:
 		if doc.is_return:
 			client.create_refund(tax_dict)
-		else:	
+		else:
 			client.create_order(tax_dict)
 	except taxjar.exceptions.TaxJarResponseError as err:
 		frappe.throw(_(sanitize_error_response(err)))
@@ -108,7 +108,7 @@
 
 	if to_shipping_state not in SUPPORTED_STATE_CODES:
 		to_shipping_state = get_state_code(to_address, 'Shipping')
-	
+
 	tax_dict = {
 		'from_country': from_country_code,
 		'from_zip': from_address.pincode,
@@ -125,7 +125,7 @@
 		'plugin': 'erpnext',
 		'line_items': line_items
 	}
-	return tax_dict	
+	return tax_dict
 
 def get_state_code(address, location):
 	if address is not None:
@@ -134,16 +134,16 @@
 			frappe.throw(_("Please enter a valid State in the {0} Address").format(location))
 	else:
 		frappe.throw(_("Please enter a valid State in the {0} Address").format(location))
-	
+
 	return state_code
 
 def get_line_item_dict(item):
-	return dict( 
+	return dict(
 		id = item.get('idx'),
 		quantity = item.get('qty'),
 		unit_price = item.get('rate'),
 		product_tax_code = item.get('product_tax_category')
-	)  	
+	)
 
 def set_sales_tax(doc, method):
 	if not TAXJAR_CALCULATE_TAX:
@@ -202,7 +202,7 @@
 				break
 		doc.run_method("calculate_taxes_and_totals")
 		return True
-	else: 
+	else:
 		return False
 
 def validate_tax_request(tax_dict):
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.py b/erpnext/healthcare/doctype/lab_test/lab_test.py
index 74495a8..03e16f5 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.py
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.py
@@ -48,7 +48,7 @@
 			if item.result_value and item.secondary_uom and item.conversion_factor:
 				try:
 					item.secondary_uom_result = float(item.result_value) * float(item.conversion_factor)
-				except:
+				except Exception:
 					item.secondary_uom_result = ''
 					frappe.msgprint(_('Row #{0}: Result for Secondary UOM not calculated').format(item.idx), title = _('Warning'))
 
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
index 7a745ae..c935274 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
@@ -7,7 +7,6 @@
 from frappe import _
 from frappe.model.document import Document
 from frappe.utils import cstr, getdate, add_days
-from frappe import _
 from frappe.model.mapper import get_mapped_doc
 
 
diff --git a/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py b/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py
index 983fba9..54e00ea 100644
--- a/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py
+++ b/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py
@@ -31,7 +31,7 @@
 		self.assertEqual(frappe.db.get_value('Therapy Plan', plan.name, 'status'), 'Completed')
 
 		patient, practitioner = create_healthcare_docs()
-		appointment = create_appointment(patient, practitioner, nowdate())		
+		appointment = create_appointment(patient, practitioner, nowdate())
 
 		session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab', '_Test Company', appointment.name)
 		session = frappe.get_doc(session)
diff --git a/erpnext/healthcare/page/patient_history/patient_history.js b/erpnext/healthcare/page/patient_history/patient_history.js
index bf947ca..ed2dc52 100644
--- a/erpnext/healthcare/page/patient_history/patient_history.js
+++ b/erpnext/healthcare/page/patient_history/patient_history.js
@@ -452,4 +452,4 @@
 			}
 		});
 	}
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/page/patient_history/patient_history_sidebar.html b/erpnext/healthcare/page/patient_history/patient_history_sidebar.html
index 4560e7e..fc7eab0 100644
--- a/erpnext/healthcare/page/patient_history/patient_history_sidebar.html
+++ b/erpnext/healthcare/page/patient_history/patient_history_sidebar.html
@@ -18,4 +18,3 @@
     <div class="patient-details">
     </div>
 </div>
-
diff --git a/erpnext/hr/doctype/daily_work_summary/daily_work_summary.py b/erpnext/hr/doctype/daily_work_summary/daily_work_summary.py
index 1cc2381..76c7a14 100644
--- a/erpnext/hr/doctype/daily_work_summary/daily_work_summary.py
+++ b/erpnext/hr/doctype/daily_work_summary/daily_work_summary.py
@@ -82,7 +82,7 @@
 							crop=True
 						)
 						d.image = thumbnail_image
-			except:
+			except Exception:
 				d.image = original_image
 
 			if d.sender in did_not_reply:
diff --git a/erpnext/hr/doctype/employee/test_employee_reminders.py b/erpnext/hr/doctype/employee/test_employee_reminders.py
index 7e560f5..f46a3d1 100644
--- a/erpnext/hr/doctype/employee/test_employee_reminders.py
+++ b/erpnext/hr/doctype/employee/test_employee_reminders.py
@@ -18,7 +18,7 @@
 		# Create a test holiday list
 		test_holiday_dates = cls.get_test_holiday_dates()
 		test_holiday_list = make_holiday_list(
-			'TestHolidayRemindersList', 
+			'TestHolidayRemindersList',
 			holiday_dates=[
 				{'holiday_date': test_holiday_dates[0], 'description': 'test holiday1'},
 				{'holiday_date': test_holiday_dates[1], 'description': 'test holiday2'},
@@ -49,8 +49,8 @@
 	def get_test_holiday_dates(cls):
 		today_date = getdate()
 		return [
-			today_date, 
-			today_date-timedelta(days=4), 
+			today_date,
+			today_date-timedelta(days=4),
 			today_date-timedelta(days=3),
 			today_date+timedelta(days=1),
 			today_date+timedelta(days=3),
@@ -63,7 +63,7 @@
 
 	def test_is_holiday(self):
 		from erpnext.hr.doctype.employee.employee import is_holiday
-		
+
 		self.assertTrue(is_holiday(self.test_employee.name))
 		self.assertTrue(is_holiday(self.test_employee.name, date=self.test_holiday_dates[1]))
 		self.assertFalse(is_holiday(self.test_employee.name, date=getdate()-timedelta(days=1)))
@@ -118,7 +118,7 @@
 
 		email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True)
 		self.assertTrue("Subject: Work Anniversary Reminder" in email_queue[0].message)
-	
+
 	def test_send_holidays_reminder_in_advance(self):
 		from erpnext.hr.utils import get_holidays_for_employee
 		from erpnext.hr.doctype.employee.employee_reminders import send_holidays_reminder_in_advance
@@ -133,10 +133,10 @@
 		holidays = get_holidays_for_employee(
 					self.test_employee.get('name'),
 					getdate(), getdate() + timedelta(days=3),
-					only_non_weekly=True, 
+					only_non_weekly=True,
 					raise_exception=False
 				)
-		
+
 		send_holidays_reminder_in_advance(
 			self.test_employee.get('name'),
 			holidays
@@ -158,7 +158,7 @@
 
 		email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True)
 		self.assertTrue(len(email_queue) > 0)
-	
+
 	def test_advance_holiday_reminders_weekly(self):
 		from erpnext.hr.doctype.employee.employee_reminders import send_reminders_in_advance_weekly
 		# Get HR settings and enable advance holiday reminders
diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
index b5fc1fb..d61c590 100644
--- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
@@ -144,20 +144,20 @@
 		expense_claim = make_expense_claim(payable_account, 5500, 5500, "_Test Company", "Travel Expenses - _TC")
 		expense_claim.save()
 		expense_claim.submit()
-		
+
 		# Payment entry 1: paying 500
 		make_payment_entry(expense_claim, payable_account,500)
 		outstanding_amount, total_amount_reimbursed = get_outstanding_and_total_reimbursed_amounts(expense_claim)
 		self.assertEqual(outstanding_amount, 5000)
 		self.assertEqual(total_amount_reimbursed, 500)
-		
+
 		# Payment entry 1: paying 2000
 		make_payment_entry(expense_claim, payable_account,2000)
 		outstanding_amount, total_amount_reimbursed = get_outstanding_and_total_reimbursed_amounts(expense_claim)
 		self.assertEqual(outstanding_amount, 3000)
 		self.assertEqual(total_amount_reimbursed, 2500)
-		
-		# Payment entry 1: paying 3000		
+
+		# Payment entry 1: paying 3000
 		make_payment_entry(expense_claim, payable_account,3000)
 		outstanding_amount, total_amount_reimbursed = get_outstanding_and_total_reimbursed_amounts(expense_claim)
 		self.assertEqual(outstanding_amount, 0)
@@ -221,7 +221,7 @@
 	outstanding_amount = flt(frappe.db.get_value("Expense Claim", expense_claim.name, "total_sanctioned_amount")) - \
 			flt(frappe.db.get_value("Expense Claim", expense_claim.name, "total_amount_reimbursed"))
 	total_amount_reimbursed = flt(frappe.db.get_value("Expense Claim", expense_claim.name, "total_amount_reimbursed"))
-	
+
 	return outstanding_amount,total_amount_reimbursed
 
 def make_payment_entry(expense_claim, payable_account, amt):
@@ -234,5 +234,4 @@
 	pe.paid_to = payable_account
 	pe.references[0].allocated_amount = amt
 	pe.insert()
-	pe.submit() 
-	
+	pe.submit()
diff --git a/erpnext/hr/doctype/leave_control_panel/leave_control_panel.py b/erpnext/hr/doctype/leave_control_panel/leave_control_panel.py
index 7401402..642ab6a 100644
--- a/erpnext/hr/doctype/leave_control_panel/leave_control_panel.py
+++ b/erpnext/hr/doctype/leave_control_panel/leave_control_panel.py
@@ -51,7 +51,7 @@
 				la.docstatus = 1
 				la.save()
 				leave_allocated_for.append(d[0])
-			except:
+			except Exception:
 				pass
 		if leave_allocated_for:
 			msgprint(_("Leaves Allocated Successfully for {0}").format(comma_and(leave_allocated_for)))
diff --git a/erpnext/hr/doctype/leave_period/leave_period.py b/erpnext/hr/doctype/leave_period/leave_period.py
index 28a33f6..86dccfc 100644
--- a/erpnext/hr/doctype/leave_period/leave_period.py
+++ b/erpnext/hr/doctype/leave_period/leave_period.py
@@ -5,7 +5,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe import _
-from frappe.utils import getdate, cstr, add_days, date_diff, getdate, ceil
+from frappe.utils import getdate, cstr, add_days, date_diff, ceil
 from frappe.model.document import Document
 from erpnext.hr.utils import validate_overlap
 from frappe.utils.background_jobs import enqueue
diff --git a/erpnext/hr/page/organizational_chart/organizational_chart.js b/erpnext/hr/page/organizational_chart/organizational_chart.js
index 81162a4..b0e41e0 100644
--- a/erpnext/hr/page/organizational_chart/organizational_chart.js
+++ b/erpnext/hr/page/organizational_chart/organizational_chart.js
@@ -15,6 +15,8 @@
 			} else {
 				organizational_chart = new erpnext.HierarchyChart('Employee', wrapper, method);
 			}
+
+			frappe.breadcrumbs.add('HR');
 			organizational_chart.show();
 		});
 	});
diff --git a/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py b/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py
index e86fa2b..0fb3f5e 100644
--- a/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py
+++ b/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py
@@ -65,7 +65,7 @@
 			for leave_type in leave_types:
 				remaining = 0
 				if leave_type in available_leave["leave_allocation"]:
-				# opening balance
+					# opening balance
 					remaining = available_leave["leave_allocation"][leave_type]['remaining_leaves']
 
 				row += [remaining]
diff --git a/erpnext/hr/report/vehicle_expenses/vehicle_expenses.py b/erpnext/hr/report/vehicle_expenses/vehicle_expenses.py
index d847cbb..c053559 100644
--- a/erpnext/hr/report/vehicle_expenses/vehicle_expenses.py
+++ b/erpnext/hr/report/vehicle_expenses/vehicle_expenses.py
@@ -96,8 +96,6 @@
 		}
 	]
 
-	return columns
-
 
 def get_vehicle_log_data(filters):
 	start_date, end_date = get_period_dates(filters)
diff --git a/erpnext/hr/utils.py b/erpnext/hr/utils.py
index 15b237d..eb35e42 100644
--- a/erpnext/hr/utils.py
+++ b/erpnext/hr/utils.py
@@ -337,9 +337,9 @@
 
 def get_holiday_dates_for_employee(employee, start_date, end_date):
 	"""return a list of holiday dates for the given employee between start_date and end_date"""
-	# return only date	
-	holidays = get_holidays_for_employee(employee, start_date, end_date) 
-	
+	# return only date
+	holidays = get_holidays_for_employee(employee, start_date, end_date)
+
 	return [cstr(h.holiday_date) for h in holidays]
 
 
@@ -352,7 +352,7 @@
 		`raise_exception` (bool)
 		`only_non_weekly` (bool)
 
-		return: list of dicts with `holiday_date` and `description` 
+		return: list of dicts with `holiday_date` and `description`
 	"""
 	holiday_list = get_holiday_list_for_employee(employee, raise_exception=raise_exception)
 
@@ -368,11 +368,11 @@
 		filters['weekly_off'] = False
 
 	holidays = frappe.get_all(
-		'Holiday', 
+		'Holiday',
 		fields=['description', 'holiday_date'],
 		filters=filters
 	)
-	
+
 	return holidays
 
 @erpnext.allow_regional
diff --git a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
index d75213c..b5b3048 100644
--- a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
+++ b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
@@ -7,7 +7,7 @@
 from frappe import _
 from frappe.model.document import Document
 from frappe.utils import (nowdate, getdate, now_datetime, get_datetime, flt, date_diff, get_last_day, cint,
-	get_first_day, get_datetime, add_days)
+	get_first_day, add_days)
 from erpnext.controllers.accounts_controller import AccountsController
 from erpnext.accounts.general_ledger import make_gl_entries
 
diff --git a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
index b67b4c4..6c74a9b 100644
--- a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
+++ b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
@@ -6,10 +6,9 @@
 import frappe, erpnext
 import json
 from frappe import _
-from frappe.utils import flt, getdate, cint
 from six import iteritems
 from frappe.model.document import Document
-from frappe.utils import date_diff, add_days, getdate, add_months, get_first_day, get_datetime
+from frappe.utils import flt, cint, date_diff, add_days, getdate, add_months, get_first_day, get_datetime
 from erpnext.controllers.accounts_controller import AccountsController
 from erpnext.accounts.general_ledger import make_gl_entries
 from erpnext.loan_management.doctype.loan_security_shortfall.loan_security_shortfall import update_shortfall_status
diff --git a/erpnext/loan_management/doctype/sanctioned_loan_amount/sanctioned_loan_amount.py b/erpnext/loan_management/doctype/sanctioned_loan_amount/sanctioned_loan_amount.py
index 74a1310..7ed838d 100644
--- a/erpnext/loan_management/doctype/sanctioned_loan_amount/sanctioned_loan_amount.py
+++ b/erpnext/loan_management/doctype/sanctioned_loan_amount/sanctioned_loan_amount.py
@@ -4,6 +4,7 @@
 
 from __future__ import unicode_literals
 import frappe
+from frappe import _
 from frappe.model.document import Document
 
 class SanctionedLoanAmount(Document):
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index 05123d5..8a92413 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -714,4 +714,4 @@
 		__("Set Process Loss Item Quantity"),
 		__("Set Quantity")
 	);
-}
\ No newline at end of file
+}
diff --git a/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json b/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
index 6c60bbd..27d7c41 100644
--- a/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
+++ b/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
@@ -6,17 +6,17 @@
  "engine": "InnoDB",
  "field_order": [
   "item_code",
-  "item_name",
-  "material_request_type",
   "from_warehouse",
   "warehouse",
-  "column_break_4",
+  "item_name",
+  "material_request_type",
+  "actual_qty",
+  "ordered_qty",
   "required_bom_qty",
+  "column_break_4",
   "quantity",
   "uom",
   "projected_qty",
-  "actual_qty",
-  "ordered_qty",
   "reserved_qty_for_production",
   "safety_stock",
   "item_details",
@@ -28,6 +28,7 @@
  ],
  "fields": [
   {
+   "columns": 2,
    "fieldname": "item_code",
    "fieldtype": "Link",
    "in_list_view": 1,
@@ -41,6 +42,7 @@
    "label": "Item Name"
   },
   {
+   "columns": 2,
    "fieldname": "warehouse",
    "fieldtype": "Link",
    "in_list_view": 1,
@@ -50,10 +52,11 @@
    "reqd": 1
   },
   {
+   "columns": 1,
    "fieldname": "material_request_type",
    "fieldtype": "Select",
    "in_list_view": 1,
-   "label": "Material Request Type",
+   "label": "Type",
    "options": "\nPurchase\nMaterial Transfer\nMaterial Issue\nManufacture\nCustomer Provided"
   },
   {
@@ -61,10 +64,11 @@
    "fieldtype": "Column Break"
   },
   {
+   "columns": 1,
    "fieldname": "quantity",
    "fieldtype": "Float",
    "in_list_view": 1,
-   "label": "Required Quantity",
+   "label": "Plan to Request Qty",
    "no_copy": 1,
    "reqd": 1
   },
@@ -75,11 +79,12 @@
    "read_only": 1
   },
   {
+   "columns": 2,
    "default": "0",
    "fieldname": "actual_qty",
    "fieldtype": "Float",
    "in_list_view": 1,
-   "label": "Actual Qty",
+   "label": "Available Qty",
    "no_copy": 1,
    "read_only": 1
   },
@@ -157,16 +162,18 @@
    "read_only": 1
   },
   {
+   "columns": 2,
    "fieldname": "required_bom_qty",
    "fieldtype": "Float",
-   "label": "Required Qty as per BOM",
+   "in_list_view": 1,
+   "label": "Qty As Per BOM",
    "no_copy": 1,
    "read_only": 1
   }
  ],
  "istable": 1,
  "links": [],
- "modified": "2021-03-26 12:41:13.013149",
+ "modified": "2021-08-23 18:17:58.400462",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Material Request Plan Item",
diff --git a/erpnext/manufacturing/doctype/operation/operation.js b/erpnext/manufacturing/doctype/operation/operation.js
index 95643bf..ea73fd6 100644
--- a/erpnext/manufacturing/doctype/operation/operation.js
+++ b/erpnext/manufacturing/doctype/operation/operation.js
@@ -29,4 +29,4 @@
 		title: "Sub Operations",
 		description: __("If an operation is divided into sub operations, they can be added here.")
 	}
-];
\ No newline at end of file
+];
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js
index 847004f..7b4b7c3 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.js
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js
@@ -254,7 +254,7 @@
 
 	get_items_for_mr: function(frm) {
 		if (!frm.doc.for_warehouse) {
-			frappe.throw(__("Select warehouse for material requests"));
+			frappe.throw(__("To make material requests, 'Make Material Request for Warehouse' field is mandatory"));
 		}
 
 		if (frm.doc.ignore_existing_ordered_qty) {
@@ -265,9 +265,18 @@
 				title: title,
 				fields: [
 					{
-						"fieldtype": "Table MultiSelect", "label": __("Source Warehouses (Optional)"),
-						"fieldname": "warehouses", "options": "Production Plan Material Request Warehouse",
-						"description": __("System will pickup the materials from the selected warehouses. If not specified, system will create material request for purchase."),
+						'label': __('Target Warehouse'),
+						'fieldtype': 'Link',
+						'fieldname': 'target_warehouse',
+						'read_only': true,
+						'default': frm.doc.for_warehouse
+					},
+					{
+						'label': __('Source Warehouses (Optional)'),
+						'fieldtype': 'Table MultiSelect',
+						'fieldname': 'warehouses',
+						'options': 'Production Plan Material Request Warehouse',
+						'description': __('If source warehouse selected then system will create the material request with type Material Transfer from Source to Target warehouse. If not selected then will create the material request with type Purchase for the target warehouse.'),
 						get_query: function () {
 							return {
 								filters: {
@@ -342,7 +351,11 @@
 
 		frappe.prompt(fields, (row) => {
 			let get_template_url = 'erpnext.manufacturing.doctype.production_plan.production_plan.download_raw_materials';
-			open_url_post(frappe.request.url, { cmd: get_template_url, doc: frm.doc, warehouses: row.warehouses });
+			open_url_post(frappe.request.url, {
+				cmd: get_template_url,
+				doc: frm.doc,
+				warehouses: row.warehouses
+			});
 		}, __('Select Warehouses to get Stock for Materials Planning'), __('Get Stock'));
 	},
 
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.json b/erpnext/manufacturing/doctype/production_plan/production_plan.json
index 8437895..b5ed288 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.json
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.json
@@ -300,7 +300,7 @@
   {
    "fieldname": "for_warehouse",
    "fieldtype": "Link",
-   "label": "Material Request Warehouse",
+   "label": "Make Material Request for Warehouse",
    "options": "Warehouse"
   },
   {
@@ -364,7 +364,7 @@
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-06-28 20:00:33.905114",
+ "modified": "2021-08-23 17:26:03.799876",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Production Plan",
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index 6b61c6d..2c77c9c 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -331,7 +331,7 @@
 	def get_production_items(self):
 		item_dict = {}
 		for d in self.po_items:
-			item_details= {
+			item_details = {
 				"production_item"		: d.item_code,
 				"use_multi_level_bom"   : d.include_exploded_items,
 				"sales_order"			: d.sales_order,
@@ -346,8 +346,7 @@
 				"production_plan"       : self.name,
 				"production_plan_item"  : d.name,
 				"product_bundle_item"	: d.product_bundle_item,
-				"planned_start_date"    : d.planned_start_date,
-				"make_work_order_for_sub_assembly_items": d.get("make_work_order_for_sub_assembly_items", 0)
+				"planned_start_date"    : d.planned_start_date
 			}
 
 			item_details.update({
@@ -458,6 +457,7 @@
 		warehouse = get_default_warehouse()
 		wo = frappe.new_doc("Work Order")
 		wo.update(item)
+		wo.planned_start_date = item.get('planned_start_date') or item.get('schedule_date')
 
 		if item.get("warehouse"):
 			wo.fg_warehouse = item.get("warehouse")
@@ -569,7 +569,10 @@
 		'Reserved Qty for Production', 'Safety Stock', 'Required Qty']]
 
 	doc.warehouse = None
-	for d in get_items_for_material_requests(doc, warehouses=warehouses, get_parent_warehouse_data=True):
+	frappe.flags.show_qty_in_stock_uom = 1
+	items = get_items_for_material_requests(doc, warehouses=warehouses, get_parent_warehouse_data=True)
+
+	for d in items:
 		item_list.append([d.get('item_code'), d.get('description'), d.get('stock_uom'), d.get('warehouse'),
 			d.get('required_bom_qty'), d.get('projected_qty'), d.get('actual_qty'), d.get('ordered_qty'),
 			d.get('planned_qty'), d.get('reserved_qty_for_production'), d.get('safety_stock'), d.get('quantity')])
@@ -605,9 +608,16 @@
 			and bom.name=%s and item.is_stock_item in (1, {0})
 		group by bei.item_code, bei.stock_uom""".format(0 if include_non_stock_items else 1),
 		(planned_qty, company, bom_no), as_dict=1):
-			item_details.setdefault(d.get('item_code'), d)
+		if not d.conversion_factor and d.purchase_uom:
+			d.conversion_factor = get_uom_conversion_factor(d.item_code, d.purchase_uom)
+		item_details.setdefault(d.get('item_code'), d)
+
 	return item_details
 
+def get_uom_conversion_factor(item_code, uom):
+	return frappe.db.get_value('UOM Conversion Detail',
+		{'parent': item_code, 'uom': uom}, 'conversion_factor')
+
 def get_subitems(doc, data, item_details, bom_no, company, include_non_stock_items,
 	include_subcontracted_items, parent_qty, planned_qty=1):
 	items = frappe.db.sql("""
@@ -642,6 +652,9 @@
 			if d.item_code in item_details:
 				item_details[d.item_code].qty = item_details[d.item_code].qty + d.qty
 			else:
+				if not d.conversion_factor and d.purchase_uom:
+					d.conversion_factor = get_uom_conversion_factor(d.item_code, d.purchase_uom)
+
 				item_details[d.item_code] = d
 
 		if data.get('include_exploded_items') and d.default_bom:
@@ -669,10 +682,11 @@
 		row['purchase_uom'] = row['stock_uom']
 
 	if row['purchase_uom'] != row['stock_uom']:
-		if not row['conversion_factor']:
+		if not (row['conversion_factor'] or frappe.flags.show_qty_in_stock_uom):
 			frappe.throw(_("UOM Conversion factor ({0} -> {1}) not found for item: {2}")
 				.format(row['purchase_uom'], row['stock_uom'], row.item_code))
-		required_qty = required_qty / row['conversion_factor']
+
+			required_qty = required_qty / row['conversion_factor']
 
 	if frappe.db.get_value("UOM", row['purchase_uom'], "must_be_whole_number"):
 		required_qty = ceil(required_qty)
@@ -841,10 +855,8 @@
 		elif data.get('item_code'):
 			item_master = frappe.get_doc('Item', data['item_code']).as_dict()
 			purchase_uom = item_master.purchase_uom or item_master.stock_uom
-			conversion_factor = 0
-			for d in item_master.get("uoms"):
-				if d.uom == purchase_uom:
-					conversion_factor = d.conversion_factor
+			conversion_factor = (get_uom_conversion_factor(item_master.name, purchase_uom)
+				if item_master.purchase_uom else 1.0)
 
 			item_details[item_master.name] = frappe._dict(
 				{
diff --git a/erpnext/manufacturing/doctype/routing/routing.js b/erpnext/manufacturing/doctype/routing/routing.js
index c17a8e9..33a313e 100644
--- a/erpnext/manufacturing/doctype/routing/routing.js
+++ b/erpnext/manufacturing/doctype/routing/routing.js
@@ -82,4 +82,3 @@
 		description: __("Enter the Operation, the table will fetch the Operation details like Hourly Rate, Workstation automatically.\n\n After that, set the Operation Time in minutes and the table will calculate the Operation Costs based on the Hourly Rate and Operation Time.")
 	}
 ];
-
diff --git a/erpnext/manufacturing/doctype/workstation/workstation.js b/erpnext/manufacturing/doctype/workstation/workstation.js
index 4f5231e..5b9cedb 100644
--- a/erpnext/manufacturing/doctype/workstation/workstation.js
+++ b/erpnext/manufacturing/doctype/workstation/workstation.js
@@ -41,4 +41,4 @@
 	},
 
 
-];
\ No newline at end of file
+];
diff --git a/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py b/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py
index ffd9242..d7ebfd6 100644
--- a/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py
+++ b/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py
@@ -7,7 +7,7 @@
 from frappe.utils.data import comma_and
 
 def execute(filters=None):
-#	if not filters: filters = {}
+	# if not filters: filters = {}
 	columns = get_columns()
 	summ_data = []
 
diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py
index b584116..9eb973b 100644
--- a/erpnext/non_profit/doctype/membership/membership.py
+++ b/erpnext/non_profit/doctype/membership/membership.py
@@ -207,7 +207,7 @@
 
 	try:
 		return frappe.get_doc("Member", members[0]["name"])
-	except:
+	except Exception:
 		return None
 
 
@@ -393,7 +393,7 @@
 		""".format(get_link_to_form("Error Log", log.name))
 
 		sendmail_to_system_managers("[Important] [ERPNext] Razorpay membership webhook failed , please check.", content)
-	except:
+	except Exception:
 		pass
 
 
@@ -402,7 +402,7 @@
 
 	try:
 		return plan[0]["name"]
-	except:
+	except Exception:
 		return None
 
 
diff --git a/erpnext/patches/v11_0/move_item_defaults_to_child_table_for_multicompany.py b/erpnext/patches/v11_0/move_item_defaults_to_child_table_for_multicompany.py
index 6da70b4..83617f7 100644
--- a/erpnext/patches/v11_0/move_item_defaults_to_child_table_for_multicompany.py
+++ b/erpnext/patches/v11_0/move_item_defaults_to_child_table_for_multicompany.py
@@ -30,7 +30,7 @@
 						buying_cost_center, selling_cost_center, expense_account, income_account, default_supplier
 					FROM `tabItem`;
 			''', companies[0].name)
-		except:
+		except Exception:
 			pass
 	else:
 		item_details = frappe.db.sql(""" SELECT name, default_warehouse,
diff --git a/erpnext/patches/v12_0/update_is_cancelled_field.py b/erpnext/patches/v12_0/update_is_cancelled_field.py
index 4bbec44..f69dcc9 100644
--- a/erpnext/patches/v12_0/update_is_cancelled_field.py
+++ b/erpnext/patches/v12_0/update_is_cancelled_field.py
@@ -11,5 +11,5 @@
 
 		frappe.reload_doc("stock", "doctype", "stock_ledger_entry")
 		frappe.reload_doc("stock", "doctype", "serial_no")
-	except:
+	except Exception:
 		pass
diff --git a/erpnext/patches/v13_0/custom_fields_for_taxjar_integration.py b/erpnext/patches/v13_0/custom_fields_for_taxjar_integration.py
index 1d57550..125be9b 100644
--- a/erpnext/patches/v13_0/custom_fields_for_taxjar_integration.py
+++ b/erpnext/patches/v13_0/custom_fields_for_taxjar_integration.py
@@ -14,9 +14,9 @@
 		'Sales Invoice Item': [
 			dict(fieldname='product_tax_category', fieldtype='Link', insert_after='description', options='Product Tax Category',
 				label='Product Tax Category', fetch_from='item_code.product_tax_category'),
-			dict(fieldname='tax_collectable', fieldtype='Currency', insert_after='net_amount', 
+			dict(fieldname='tax_collectable', fieldtype='Currency', insert_after='net_amount',
 				label='Tax Collectable', read_only=1),
-			dict(fieldname='taxable_amount', fieldtype='Currency', insert_after='tax_collectable', 
+			dict(fieldname='taxable_amount', fieldtype='Currency', insert_after='tax_collectable',
 				label='Taxable Amount', read_only=1)
 		],
 		'Item': [
@@ -26,4 +26,4 @@
 	}
 	create_custom_fields(custom_fields, update=True)
 	add_permissions()
-	frappe.enqueue('erpnext.regional.united_states.setup.add_product_tax_categories', now=True)
\ No newline at end of file
+	frappe.enqueue('erpnext.regional.united_states.setup.add_product_tax_categories', now=True)
diff --git a/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py b/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py
index 1a91d21..4262920 100644
--- a/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py
+++ b/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py
@@ -86,7 +86,7 @@
 			try:
 				employee_other_income.submit()
 				migrated.append([proof.employee, proof.payroll_period])
-			except:
+			except Exception:
 				pass
 
 	if not frappe.db.table_exists("Employee Tax Exemption Declaration"):
@@ -108,5 +108,5 @@
 
 			try:
 				employee_other_income.submit()
-			except:
+			except Exception:
 				pass
diff --git a/erpnext/patches/v13_0/rename_stop_to_send_birthday_reminders.py b/erpnext/patches/v13_0/rename_stop_to_send_birthday_reminders.py
index 1787a56..014f026 100644
--- a/erpnext/patches/v13_0/rename_stop_to_send_birthday_reminders.py
+++ b/erpnext/patches/v13_0/rename_stop_to_send_birthday_reminders.py
@@ -7,17 +7,17 @@
 	try:
 		# Rename the field
 		rename_field('HR Settings', 'stop_birthday_reminders', 'send_birthday_reminders')
-		
+
 		# Reverse the value
 		old_value = frappe.db.get_single_value('HR Settings', 'send_birthday_reminders')
 
 		frappe.db.set_value(
-			'HR Settings', 
-			'HR Settings', 
-			'send_birthday_reminders', 
+			'HR Settings',
+			'HR Settings',
+			'send_birthday_reminders',
 			1 if old_value == 0 else 0
 		)
-		
+
 	except Exception as e:
 		if e.args[0] != 1054:
-			raise
\ No newline at end of file
+			raise
diff --git a/erpnext/patches/v13_0/reset_clearance_date_for_intracompany_payment_entries.py b/erpnext/patches/v13_0/reset_clearance_date_for_intracompany_payment_entries.py
index 1da5275..1caa17f 100644
--- a/erpnext/patches/v13_0/reset_clearance_date_for_intracompany_payment_entries.py
+++ b/erpnext/patches/v13_0/reset_clearance_date_for_intracompany_payment_entries.py
@@ -35,11 +35,11 @@
 
     for payment_entry in intra_company_pe:
         reconciled_bank_transactions[payment_entry] = frappe.get_all(
-            'Bank Transaction Payments', 
+            'Bank Transaction Payments',
             filters = {
                 'payment_entry': payment_entry
-            }, 
+            },
             pluck='parent'
         )
 
-    return reconciled_bank_transactions
\ No newline at end of file
+    return reconciled_bank_transactions
diff --git a/erpnext/patches/v13_0/set_operation_time_based_on_operating_cost.py b/erpnext/patches/v13_0/set_operation_time_based_on_operating_cost.py
index 4acbdd6..4fdd82f 100644
--- a/erpnext/patches/v13_0/set_operation_time_based_on_operating_cost.py
+++ b/erpnext/patches/v13_0/set_operation_time_based_on_operating_cost.py
@@ -12,4 +12,4 @@
 		WHERE
 			time_in_mins = 0 AND operating_cost > 0
 			AND hour_rate > 0 AND docstatus = 1 AND parenttype = "BOM"
-	''')
\ No newline at end of file
+	''')
diff --git a/erpnext/patches/v13_0/validate_options_for_data_field.py b/erpnext/patches/v13_0/validate_options_for_data_field.py
index 568d1a4..03f9929 100644
--- a/erpnext/patches/v13_0/validate_options_for_data_field.py
+++ b/erpnext/patches/v13_0/validate_options_for_data_field.py
@@ -3,11 +3,11 @@
 
 from __future__ import unicode_literals
 import frappe
-from frappe.model import data_field_options 
+from frappe.model import data_field_options
 
 def execute():
 
-    for field in frappe.get_all('Custom Field', 
+    for field in frappe.get_all('Custom Field',
                             fields = ['name'],
                             filters = {
                                 'fieldtype': 'Data',
@@ -16,7 +16,7 @@
 
         if field not in data_field_options:
             frappe.db.sql("""
-                UPDATE 
+                UPDATE
                     `tabCustom Field`
                 SET
                     options=NULL
diff --git a/erpnext/patches/v14_0/delete_einvoicing_doctypes.py b/erpnext/patches/v14_0/delete_einvoicing_doctypes.py
index b77d244..6e5775b 100644
--- a/erpnext/patches/v14_0/delete_einvoicing_doctypes.py
+++ b/erpnext/patches/v14_0/delete_einvoicing_doctypes.py
@@ -6,4 +6,4 @@
 	frappe.delete_doc('Report', 'E-Invoice Summary', ignore_missing=True)
 	frappe.delete_doc('Print Format', 'GST E-Invoice', ignore_missing=True)
 	frappe.delete_doc('Custom Field', 'Sales Invoice-eway_bill_cancelled', ignore_missing=True)
-	frappe.delete_doc('Custom Field', 'Sales Invoice-irn_cancelled', ignore_missing=True)
\ No newline at end of file
+	frappe.delete_doc('Custom Field', 'Sales Invoice-irn_cancelled', ignore_missing=True)
diff --git a/erpnext/patches/v4_2/update_requested_and_ordered_qty.py b/erpnext/patches/v4_2/update_requested_and_ordered_qty.py
index 7bb49e6..8a31c73 100644
--- a/erpnext/patches/v4_2/update_requested_and_ordered_qty.py
+++ b/erpnext/patches/v4_2/update_requested_and_ordered_qty.py
@@ -20,5 +20,5 @@
 				})
 				if count % 200 == 0:
 					frappe.db.commit()
-			except:
+			except Exception:
 				frappe.db.rollback()
diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.js b/erpnext/payroll/doctype/salary_slip/salary_slip.js
index 5258f3a..3ef9762 100644
--- a/erpnext/payroll/doctype/salary_slip/salary_slip.js
+++ b/erpnext/payroll/doctype/salary_slip/salary_slip.js
@@ -135,15 +135,15 @@
 
 	change_form_labels: function(frm, company_currency) {
 		frm.set_currency_labels(["base_hour_rate", "base_gross_pay", "base_total_deduction",
-			"base_net_pay", "base_rounded_total", "base_total_in_words", "base_year_to_date", "base_month_to_date"],
+			"base_net_pay", "base_rounded_total", "base_total_in_words", "base_year_to_date", "base_month_to_date", "gross_base_year_to_date"],
 		company_currency);
 
-		frm.set_currency_labels(["hour_rate", "gross_pay", "total_deduction", "net_pay", "rounded_total", "total_in_words", "year_to_date", "month_to_date"],
+		frm.set_currency_labels(["hour_rate", "gross_pay", "total_deduction", "net_pay", "rounded_total", "total_in_words", "year_to_date", "month_to_date", "gross_year_to_date"],
 			frm.doc.currency);
 
 		// toggle fields
 		frm.toggle_display(["exchange_rate", "base_hour_rate", "base_gross_pay", "base_total_deduction",
-			"base_net_pay", "base_rounded_total", "base_total_in_words", "base_year_to_date", "base_month_to_date"],
+			"base_net_pay", "base_rounded_total", "base_total_in_words", "base_year_to_date", "base_month_to_date", "base_gross_year_to_date"],
 		frm.doc.currency != company_currency);
 	},
 
diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.json b/erpnext/payroll/doctype/salary_slip/salary_slip.json
index 42a0f29..1974403 100644
--- a/erpnext/payroll/doctype/salary_slip/salary_slip.json
+++ b/erpnext/payroll/doctype/salary_slip/salary_slip.json
@@ -56,6 +56,8 @@
   "totals",
   "gross_pay",
   "base_gross_pay",
+  "gross_year_to_date",
+  "base_gross_year_to_date",
   "column_break_25",
   "total_deduction",
   "base_total_deduction",
@@ -625,13 +627,27 @@
    "label": "Leave Details",
    "options": "Salary Slip Leave",
    "read_only": 1
+  },
+  {
+   "fieldname": "gross_year_to_date",
+   "fieldtype": "Currency",
+   "label": "Gross Year To Date",
+   "options": "currency",
+   "read_only": 1
+  },
+  {
+   "fieldname": "base_gross_year_to_date",
+   "fieldtype": "Currency",
+   "label": "Gross Year To Date(Company Currency)",
+   "options": "Company:company:default_currency",
+   "read_only": 1
   }
  ],
  "icon": "fa fa-file-text",
  "idx": 9,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-03-31 22:44:09.772331",
+ "modified": "2021-09-01 10:35:52.374549",
  "modified_by": "Administrator",
  "module": "Payroll",
  "name": "Salary Slip",
@@ -672,4 +688,4 @@
  "sort_order": "DESC",
  "timeline_field": "employee",
  "title_field": "employee_name"
-}
\ No newline at end of file
+}
diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.py b/erpnext/payroll/doctype/salary_slip/salary_slip.py
index 6325351..37a0b60 100644
--- a/erpnext/payroll/doctype/salary_slip/salary_slip.py
+++ b/erpnext/payroll/doctype/salary_slip/salary_slip.py
@@ -1214,7 +1214,7 @@
 		period_start_date, period_end_date = self.get_year_to_date_period()
 
 		salary_slip_sum = frappe.get_list('Salary Slip',
-			fields = ['sum(net_pay) as sum'],
+			fields = ['sum(net_pay) as net_sum', 'sum(gross_pay) as gross_sum'],
 			filters = {'employee_name' : self.employee_name,
 				'start_date' : ['>=', period_start_date],
 				'end_date' : ['<', period_end_date],
@@ -1222,10 +1222,13 @@
 				'docstatus': 1
 			})
 
-		year_to_date = flt(salary_slip_sum[0].sum) if salary_slip_sum else 0.0
+		year_to_date = flt(salary_slip_sum[0].net_sum) if salary_slip_sum else 0.0
+		gross_year_to_date = flt(salary_slip_sum[0].gross_sum) if salary_slip_sum else 0.0
 
 		year_to_date += self.net_pay
+		gross_year_to_date += self.gross_pay
 		self.year_to_date = year_to_date
+		self.gross_year_to_date = gross_year_to_date
 
 	def compute_month_to_date(self):
 		month_to_date = 0
diff --git a/erpnext/public/js/hierarchy_chart/hierarchy_chart_desktop.js b/erpnext/public/js/hierarchy_chart/hierarchy_chart_desktop.js
index 23ec2fd..6286732 100644
--- a/erpnext/public/js/hierarchy_chart/hierarchy_chart_desktop.js
+++ b/erpnext/public/js/hierarchy_chart/hierarchy_chart_desktop.js
@@ -67,8 +67,6 @@
 	}
 
 	show() {
-		frappe.breadcrumbs.add('HR');
-
 		this.setup_actions();
 		if ($(`[data-fieldname="company"]`).length) return;
 		let me = this;
@@ -83,8 +81,9 @@
 			reqd: 1,
 			change: () => {
 				me.company = undefined;
+				$('#hierarchy-chart-wrapper').remove();
 
-				if (company.get_value() && me.company != company.get_value()) {
+				if (company.get_value()) {
 					me.company = company.get_value();
 
 					// svg for connectors
@@ -92,6 +91,8 @@
 					me.setup_hierarchy();
 					me.render_root_nodes();
 					me.all_nodes_expanded = false;
+				} else {
+					frappe.throw(__('Please select a company first.'));
 				}
 			}
 		});
@@ -172,11 +173,11 @@
 			</ul>`);
 
 		this.page.main
-			.find('#hierarchy-chart-wrapper')
+			.find('#hierarchy-chart')
+			.empty()
 			.append(this.$hierarchy);
 
 		this.nodes = {};
-		this.all_nodes_expanded = false;
 	}
 
 	make_svg_markers() {
@@ -203,6 +204,8 @@
 					<g id="connectors" fill="none">
 					</g>
 				</svg>
+				<div id="hierarchy-chart">
+				</div>
 			</div>`);
 	}
 
@@ -219,7 +222,10 @@
 				let expand_node = undefined;
 				let node = undefined;
 
-				$.each(r.message, (i, data) => {
+				$.each(r.message, (_i, data) => {
+					if ($(`#${data.id}`).length)
+						return;
+
 					node = new me.Node({
 						id: data.id,
 						parent: $('<li class="child-node"></li>').appendTo(me.$hierarchy.find('.node-children')),
@@ -290,7 +296,7 @@
 				() => frappe.dom.freeze(),
 				() => this.setup_hierarchy(),
 				() => this.render_root_nodes(true),
-				() => this.get_all_nodes(node.id, node.name),
+				() => this.get_all_nodes(),
 				(data_list) => this.render_children_of_all_nodes(data_list),
 				() => frappe.dom.unfreeze()
 			]);
@@ -341,15 +347,13 @@
 		node.expanded = true;
 	}
 
-	get_all_nodes(node_id, node_name) {
+	get_all_nodes() {
 		return new Promise(resolve => {
 			frappe.call({
 				method: 'erpnext.utilities.hierarchy_chart.get_all_nodes',
 				args: {
 					method: this.method,
-					company: this.company,
-					parent: node_id,
-					parent_name: node_name
+					company: this.company
 				},
 				callback: (r) => {
 					resolve(r.message);
diff --git a/erpnext/public/js/hierarchy_chart/hierarchy_chart_mobile.js b/erpnext/public/js/hierarchy_chart/hierarchy_chart_mobile.js
index b1b78c0..b1a8879 100644
--- a/erpnext/public/js/hierarchy_chart/hierarchy_chart_mobile.js
+++ b/erpnext/public/js/hierarchy_chart/hierarchy_chart_mobile.js
@@ -59,8 +59,6 @@
 	}
 
 	show() {
-		frappe.breadcrumbs.add('HR');
-
 		let me = this;
 		if ($(`[data-fieldname="company"]`).length) return;
 
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 9caf1de..e0610eb 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -86,9 +86,9 @@
 
 	proceed_save_with_reminders_frequency_change: () => {
 		frappe.ui.hide_open_dialog();
-		
+
 		frappe.call({
-			method: 'erpnext.hr.doctype.hr_settings.hr_settings.set_proceed_with_frequency_change', 
+			method: 'erpnext.hr.doctype.hr_settings.hr_settings.set_proceed_with_frequency_change',
 			callback: () => {
 				cur_frm.save();
 			}
diff --git a/erpnext/regional/germany/utils/datev/datev_csv.py b/erpnext/regional/germany/utils/datev/datev_csv.py
index 122c15f..c5c2bc4 100644
--- a/erpnext/regional/germany/utils/datev/datev_csv.py
+++ b/erpnext/regional/germany/utils/datev/datev_csv.py
@@ -33,6 +33,14 @@
 	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'
 
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index ce5aa10..ac31f77 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -887,4 +887,3 @@
 		gst_settings.remove(d)
 
 	gst_settings.save()
-
diff --git a/erpnext/regional/report/datev/datev.py b/erpnext/regional/report/datev/datev.py
index 86aed2e..9abdb3b 100644
--- a/erpnext/regional/report/datev/datev.py
+++ b/erpnext/regional/report/datev/datev.py
@@ -44,6 +44,12 @@
 		"width": 100
 	},
 	{
+		"label": "BU-Schlüssel",
+		"fieldname": "BU-Schlüssel",
+		"fieldtype": "Data",
+		"width": 100
+	},
+	{
 		"label": "Belegdatum",
 		"fieldname": "Belegdatum",
 		"fieldtype": "Date",
@@ -114,6 +120,36 @@
 		"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
 	}
 ]
 
@@ -161,6 +197,125 @@
 
 
 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.
 
@@ -171,8 +326,7 @@
 	filters -- dict of filters to be passed to the sql query
 	as_dict -- return as list of dicts [0,1]
 	"""
-	filter_by_voucher = 'AND gl.voucher_type = %(voucher_type)s' if filters.get('voucher_type') else ''
-	gl_entries = frappe.db.sql("""
+	query = """
 		SELECT
 
 			/* either debit or credit amount; always positive */
@@ -187,6 +341,9 @@
 			/* against number or, if empty, party against number */
 			%(temporary_against_account_number)s as 'Gegenkonto (ohne BU-Schlüssel)',
 
+			/* disable automatic VAT deduction */
+			'40' as 'BU-Schlüssel',
+
 			gl.posting_date as 'Belegdatum',
 			gl.voucher_no as 'Belegfeld 1',
 			LEFT(gl.remarks, 60) as 'Buchungstext',
@@ -199,30 +356,34 @@
 			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 `tabAccount` acc
+			ON gl.account = acc.name
 
-			left join `tabCustomer` cus
-			on gl.party_type = 'Customer'
-			and gl.party = cus.name
+			LEFT JOIN `tabParty Account` par
+			ON par.parent = gl.party
+			AND par.parenttype = gl.party_type
+			AND par.company = %(company)s
 
-			left join `tabSupplier` sup
-			on gl.party_type = 'Supplier'
-			and gl.party = sup.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
-		{}
-		ORDER BY 'Belegdatum', gl.voucher_no""".format(filter_by_voucher), filters, as_dict=as_dict)
+
+		{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
 
diff --git a/erpnext/regional/report/eway_bill/eway_bill.py b/erpnext/regional/report/eway_bill/eway_bill.py
index 4f777fc..09d5f79 100644
--- a/erpnext/regional/report/eway_bill/eway_bill.py
+++ b/erpnext/regional/report/eway_bill/eway_bill.py
@@ -41,7 +41,7 @@
 	}
 
 	# Regular expression set to remove all the special characters
-	special_characters = "[$%^*()+\\[\]{};':\"\\|<>.?]"
+	special_characters = r"[$%^*()+\\[\]{};':\"\\|<>.?]"
 
 	for row in data:
 		set_defaults(row)
diff --git "a/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.py" "b/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.py"
index e903c9f..697058d 100644
--- "a/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.py"
+++ "b/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.py"
@@ -116,7 +116,7 @@
 		if d.get("voucher_no").startswith("{0}-".format(JournalCode)) or d.get("voucher_no").startswith("{0}/".format(JournalCode)):
 			EcritureNum = re.split("-|/", d.get("voucher_no"))[1]
 		else:
-			EcritureNum = re.search("{0}(\d+)".format(JournalCode), d.get("voucher_no"), re.IGNORECASE).group(1)
+			EcritureNum = re.search(r"{0}(\d+)".format(JournalCode), d.get("voucher_no"), re.IGNORECASE).group(1)
 
 		EcritureDate = format_datetime(d.get("GlPostDate"), "yyyyMMdd")
 
diff --git a/erpnext/regional/united_states/setup.py b/erpnext/regional/united_states/setup.py
index c0cec3a..9c183af 100644
--- a/erpnext/regional/united_states/setup.py
+++ b/erpnext/regional/united_states/setup.py
@@ -63,9 +63,9 @@
 		'Sales Invoice Item': [
 			dict(fieldname='product_tax_category', fieldtype='Link', insert_after='description', options='Product Tax Category',
 				label='Product Tax Category', fetch_from='item_code.product_tax_category'),
-			dict(fieldname='tax_collectable', fieldtype='Currency', insert_after='net_amount', 
+			dict(fieldname='tax_collectable', fieldtype='Currency', insert_after='net_amount',
 				label='Tax Collectable', read_only=1),
-			dict(fieldname='taxable_amount', fieldtype='Currency', insert_after='tax_collectable', 
+			dict(fieldname='taxable_amount', fieldtype='Currency', insert_after='tax_collectable',
 				label='Taxable Amount', read_only=1)
 		],
 		'Item': [
diff --git a/erpnext/selling/doctype/customer/test_customer.py b/erpnext/selling/doctype/customer/test_customer.py
index 5b33731..3d3dffa 100644
--- a/erpnext/selling/doctype/customer/test_customer.py
+++ b/erpnext/selling/doctype/customer/test_customer.py
@@ -374,4 +374,4 @@
 	else:
 		customer_name = frappe.db.get_value("Customer", customer_name)
 
-	return customer_name
\ No newline at end of file
+	return customer_name
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.py b/erpnext/selling/page/point_of_sale/point_of_sale.py
index 03c46bb..8c652c9 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.py
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.py
@@ -2,7 +2,8 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
-import frappe, json
+import json
+import frappe
 from frappe.utils.nestedset import get_root_of
 from frappe.utils import cint
 from erpnext.accounts.doctype.pos_profile.pos_profile import get_item_groups
@@ -209,7 +210,6 @@
 
 @frappe.whitelist()
 def create_opening_voucher(pos_profile, company, balance_details):
-	import json
 	balance_details = json.loads(balance_details)
 
 	new_pos_opening = frappe.get_doc({
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index 56700af..8403193 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -55,10 +55,10 @@
 				{"fieldtype": "Button", "label": "Update", "fieldname": "update"},
 			]
 		});
-	
+
 		dialog.fields_dict.update.$input.click(function() {
 			var args = dialog.get_values();
-			if (!args) return; 
+			if (!args) return;
 			frappe.show_alert(__("Update in progress. It might take a while."));
 			return frappe.call({
 				method: "erpnext.setup.doctype.company.company.enqueue_replace_abbr",
diff --git a/erpnext/setup/doctype/naming_series/naming_series.py b/erpnext/setup/doctype/naming_series/naming_series.py
index c1f9433..c5d5747 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.py
+++ b/erpnext/setup/doctype/naming_series/naming_series.py
@@ -79,7 +79,8 @@
 		options = self.scrub_options_list(ol)
 
 		# validate names
-		for i in options: self.validate_series_name(i)
+		for i in options:
+			self.validate_series_name(i)
 
 		if options and self.user_must_always_select:
 			options = [''] + options
@@ -138,7 +139,7 @@
 
 	def validate_series_name(self, n):
 		import re
-		if not re.match("^[\w\- /.#{}]*$", n, re.UNICODE):
+		if not re.match(r"^[\w\- \/.#{}]+$", n, re.UNICODE):
 			throw(_('Special Characters except "-", "#", ".", "/", "{" and "}" not allowed in naming series'))
 
 	@frappe.whitelist()
diff --git a/erpnext/setup/setup_wizard/setup_wizard.py b/erpnext/setup/setup_wizard/setup_wizard.py
index f63d269..9275d1b 100644
--- a/erpnext/setup/setup_wizard/setup_wizard.py
+++ b/erpnext/setup/setup_wizard/setup_wizard.py
@@ -106,7 +106,7 @@
 def make_sample_data(domains):
 	try:
 		sample_data.make_sample_data(domains)
-	except:
+	except Exception:
 		# clear message
 		if frappe.message_log:
 			frappe.message_log.pop()
diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py
index e49259e..409f776 100644
--- a/erpnext/setup/utils.py
+++ b/erpnext/setup/utils.py
@@ -109,7 +109,7 @@
 			value = response.json()["result"]
 			cache.setex(name=key, time=21600, value=flt(value))
 		return flt(value)
-	except:
+	except Exception:
 		frappe.log_error(title="Get Exchange Rate")
 		frappe.msgprint(_("Unable to find exchange rate for {0} to {1} for key date {2}. Please create a Currency Exchange record manually").format(from_currency, to_currency, transaction_date))
 		return 0.0
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index f99a01b..9113b59 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -331,7 +331,7 @@
 			credit_note_link = frappe.utils.get_link_to_form('Sales Invoice', return_invoice.name)
 
 			frappe.msgprint(_("Credit Note {0} has been created automatically").format(credit_note_link))
-		except:
+		except Exception:
 			frappe.throw(_("Could not create Credit Note automatically, please uncheck 'Issue Credit Note' and submit again"))
 
 def update_billed_amount_based_on_so(so_detail, update_modified=True):
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 70312bc..319597f 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -573,7 +573,7 @@
 	if batch_nos:
 		try:
 			filters["batch_no"] = json.loads(batch_nos) if (type(json.loads(batch_nos)) == list) else [json.loads(batch_nos)]
-		except:
+		except Exception:
 			filters["batch_no"] = [batch_nos]
 
 	if posting_date:
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 8f34794..908020d 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -1101,4 +1101,3 @@
 }
 
 $.extend(cur_frm.cscript, new erpnext.stock.StockEntry({frm: cur_frm}));
-
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 760cb7d..c5c2868 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -1200,10 +1200,10 @@
 
 			wo_item_qty = item.transferred_qty or item.required_qty
 
-			req_qty_each = (
-				(flt(wo_item_qty) - flt(item.consumed_qty)) /
-					(flt(work_order_qty) - flt(wo.produced_qty))
-			)
+			wo_qty_consumed = flt(wo_item_qty) - flt(item.consumed_qty)
+			wo_qty_to_produce = flt(work_order_qty) - flt(wo.produced_qty)
+
+			req_qty_each = (wo_qty_consumed) / (wo_qty_to_produce or 1)
 
 			qty = req_qty_each * flt(self.fg_completed_qty)
 
@@ -1582,7 +1582,7 @@
 			if material_request and material_request not in material_requests:
 				material_requests.append(material_request)
 				frappe.db.set_value('Material Request', material_request, 'transfer_status', status)
-				
+
 	def update_items_for_process_loss(self):
 		process_loss_dict = {}
 		for d in self.get("items"):
diff --git a/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_manufacture.js b/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_manufacture.js
index 285ae4f..e51c90c 100644
--- a/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_manufacture.js
+++ b/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_manufacture.js
@@ -24,4 +24,3 @@
 		() => done()
 	]);
 });
-
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
index aa502a4..84f65a0 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
@@ -302,4 +302,3 @@
 };
 
 cur_frm.cscript = new erpnext.stock.StockReconciliation({frm: cur_frm});
-
diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.js b/erpnext/stock/doctype/stock_settings/stock_settings.js
index 6167bec..cc0e2cf 100644
--- a/erpnext/stock/doctype/stock_settings/stock_settings.js
+++ b/erpnext/stock/doctype/stock_settings/stock_settings.js
@@ -15,4 +15,3 @@
 		frm.set_query("sample_retention_warehouse", filters);
 	}
 });
-
diff --git a/erpnext/stock/doctype/warehouse/warehouse.js b/erpnext/stock/doctype/warehouse/warehouse.js
index 4e1679c4..9243e1e 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.js
+++ b/erpnext/stock/doctype/warehouse/warehouse.js
@@ -86,4 +86,3 @@
 
 	})
 }
-
diff --git a/erpnext/stock/reorder_item.py b/erpnext/stock/reorder_item.py
index 4c721ac..4d8dcc6 100644
--- a/erpnext/stock/reorder_item.py
+++ b/erpnext/stock/reorder_item.py
@@ -166,7 +166,7 @@
 				mr.submit()
 				mr_list.append(mr)
 
-			except:
+			except Exception:
 				_log_exception()
 
 	if mr_list:
diff --git a/erpnext/stock/report/cogs_by_item_group/cogs_by_item_group.py b/erpnext/stock/report/cogs_by_item_group/cogs_by_item_group.py
index da593a4..7532d02 100644
--- a/erpnext/stock/report/cogs_by_item_group/cogs_by_item_group.py
+++ b/erpnext/stock/report/cogs_by_item_group/cogs_by_item_group.py
@@ -43,13 +43,13 @@
 def get_columns() -> Columns:
 	return [
 		{
-			'label': 'Item Group',
+			'label': _('Item Group'),
 			'fieldname': 'item_group',
 			'fieldtype': 'Data',
 			'width': '200'
 		},
 		{
-			'label': 'COGS Debit',
+			'label': _('COGS Debit'),
 			'fieldname': 'cogs_debit',
 			'fieldtype': 'Currency',
 			'width': '200'
diff --git a/erpnext/stock/report/process_loss_report/process_loss_report.py b/erpnext/stock/report/process_loss_report/process_loss_report.py
index 3d48ebd..ebb32f1 100644
--- a/erpnext/stock/report/process_loss_report/process_loss_report.py
+++ b/erpnext/stock/report/process_loss_report/process_loss_report.py
@@ -92,7 +92,7 @@
 
 def run_query(query_args: QueryArgs) -> Data:
 	return frappe.db.sql("""
-		SELECT 
+		SELECT
 			wo.name, wo.status, wo.production_item, wo.qty,
 			wo.produced_qty, wo.process_loss_qty,
 			(wo.produced_qty - wo.process_loss_qty) as actual_produced_qty,
@@ -130,4 +130,3 @@
 			{"work_order_filter": f"AND wo.name='{work_order_name}'"}
 		)
 	return filter_conditions
-
diff --git a/erpnext/stock/report/stock_ageing/stock_ageing.py b/erpnext/stock/report/stock_ageing/stock_ageing.py
index 8a9f0a5..11d50cd 100644
--- a/erpnext/stock/report/stock_ageing/stock_ageing.py
+++ b/erpnext/stock/report/stock_ageing/stock_ageing.py
@@ -4,6 +4,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe import _
+from operator import itemgetter
 from frappe.utils import date_diff, flt, cint
 from six import iteritems
 from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
@@ -12,7 +13,7 @@
 	columns = get_columns(filters)
 	item_details = get_fifo_queue(filters)
 	to_date = filters["to_date"]
-	_func = lambda x: x[1]
+	_func = itemgetter(1)
 
 	data = []
 	for item, item_dict in iteritems(item_details):
diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py
index fc3d719..f530ac2 100644
--- a/erpnext/stock/report/stock_balance/stock_balance.py
+++ b/erpnext/stock/report/stock_balance/stock_balance.py
@@ -2,6 +2,7 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
+from operator import itemgetter
 import frappe, erpnext
 from frappe import _
 from frappe.utils import flt, cint, getdate, now, date_diff
@@ -44,7 +45,7 @@
 	data = []
 	conversion_factors = {}
 
-	_func = lambda x: x[1]
+	_func = itemgetter(1)
 
 	for (company, item, warehouse) in sorted(iwb_map):
 		if item_map.get(item):
diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py
index 8917bfe..e5819d6 100644
--- a/erpnext/stock/stock_balance.py
+++ b/erpnext/stock/stock_balance.py
@@ -29,7 +29,7 @@
 		try:
 			repost_stock(d[0], d[1], allow_zero_rate, only_actual, only_bin, allow_negative_stock)
 			frappe.db.commit()
-		except:
+		except Exception:
 			frappe.db.rollback()
 
 	if allow_negative_stock:
@@ -247,5 +247,5 @@
 
 				sr.via_stock_ledger = True
 				sr.save()
-			except:
+			except Exception:
 				pass
diff --git a/erpnext/support/doctype/service_level_agreement/service_level_agreement.py b/erpnext/support/doctype/service_level_agreement/service_level_agreement.py
index 8c1c1ef..b1d77ce 100644
--- a/erpnext/support/doctype/service_level_agreement/service_level_agreement.py
+++ b/erpnext/support/doctype/service_level_agreement/service_level_agreement.py
@@ -13,7 +13,6 @@
 from datetime import datetime
 from frappe.utils.safe_exec import get_safe_globals
 from erpnext.support.doctype.issue.issue import get_holidays
-from frappe.utils.safe_exec import get_safe_globals
 
 class ServiceLevelAgreement(Document):
 	def validate(self):
diff --git a/erpnext/templates/emails/anniversary_reminder.html b/erpnext/templates/emails/anniversary_reminder.html
index ac9f7e4..db338dd 100644
--- a/erpnext/templates/emails/anniversary_reminder.html
+++ b/erpnext/templates/emails/anniversary_reminder.html
@@ -22,4 +22,4 @@
 		<span>{{ reminder_text }}</span>
 		<p class="text-muted">{{ message }}</p>
 	</div>
-</div>
\ No newline at end of file
+</div>
diff --git a/erpnext/utilities/hierarchy_chart.py b/erpnext/utilities/hierarchy_chart.py
index 384d841..cc506e5 100644
--- a/erpnext/utilities/hierarchy_chart.py
+++ b/erpnext/utilities/hierarchy_chart.py
@@ -6,17 +6,21 @@
 from frappe import _
 
 @frappe.whitelist()
-def get_all_nodes(parent, parent_name, method, company):
+def get_all_nodes(method, company):
 	'''Recursively gets all data from nodes'''
 	method = frappe.get_attr(method)
 
 	if method not in frappe.whitelisted:
 		frappe.throw(_('Not Permitted'), frappe.PermissionError)
 
-	data = method(parent, company)
-	result = [dict(parent=parent, parent_name=parent_name, data=data)]
+	root_nodes = method(company=company)
+	result = []
+	nodes_to_expand = []
 
-	nodes_to_expand = [{'id': d.get('id'), 'name': d.get('name')} for d in data if d.get('expandable')]
+	for root in root_nodes:
+		data = method(root.id, company)
+		result.append(dict(parent=root.id, parent_name=root.name, data=data))
+		nodes_to_expand.extend([{'id': d.get('id'), 'name': d.get('name')} for d in data if d.get('expandable')])
 
 	while nodes_to_expand:
 		parent = nodes_to_expand.pop(0)
diff --git a/erpnext/utilities/product.py b/erpnext/utilities/product.py
index 70b4176..f6c53ca 100644
--- a/erpnext/utilities/product.py
+++ b/erpnext/utilities/product.py
@@ -127,7 +127,7 @@
 			return price_obj
 
 def get_non_stock_item_status(item_code, item_warehouse_field):
-#if item belongs to product bundle, check if bundle items are in stock
+	#if item belongs to product bundle, check if bundle items are in stock
 	if frappe.db.exists("Product Bundle", item_code):
 		items = frappe.get_doc("Product Bundle", item_code).get_all_children()
 		bundle_warehouse = frappe.db.get_value('Item', item_code, item_warehouse_field)