Merge pull request #25866 from deepeshgarg007/itc_reversa_address

fix(India): Show only company addresses for ITC reversal entry
diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml
deleted file mode 100644
index 84ecfb1..0000000
--- a/.github/workflows/ci-tests.yml
+++ /dev/null
@@ -1,108 +0,0 @@
-name: CI
-
-on: [pull_request, workflow_dispatch, push]
-
-jobs:
-  test:
-    runs-on: ubuntu-18.04
-
-    strategy:
-      fail-fast: false
-
-      matrix:
-       include:
-        - TYPE: "server"
-          JOB_NAME: "Server"
-          RUN_COMMAND: cd ~/frappe-bench/ && bench --site test_site run-tests --app erpnext --coverage
-        - TYPE: "patch"
-          JOB_NAME: "Patch"
-          RUN_COMMAND: cd ~/frappe-bench/ && wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz &&  bench --site test_site --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz && bench --site test_site migrate
-
-    name: ${{ matrix.JOB_NAME }}
-
-    services:
-      mysql:
-        image: mariadb:10.3
-        env:
-          MYSQL_ALLOW_EMPTY_PASSWORD: YES
-        ports:
-          - 3306:3306
-        options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
-
-    steps:
-      - name: Clone
-        uses: actions/checkout@v2
-
-      - name: Setup Python
-        uses: actions/setup-python@v2
-        with:
-          python-version: 3.6
-
-      - name: Add to Hosts
-        run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts
-
-      - name: Cache pip
-        uses: actions/cache@v2
-        with:
-          path: ~/.cache/pip
-          key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
-          restore-keys: |
-            ${{ runner.os }}-pip-
-            ${{ runner.os }}-
-      - name: Cache node modules
-        uses: actions/cache@v2
-        env:
-          cache-name: cache-node-modules
-        with:
-          path: ~/.npm
-          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
-          restore-keys: |
-            ${{ runner.os }}-build-${{ env.cache-name }}-
-            ${{ runner.os }}-build-
-            ${{ runner.os }}-
-      - name: Get yarn cache directory path
-        id: yarn-cache-dir-path
-        run: echo "::set-output name=dir::$(yarn cache dir)"
-
-      - uses: actions/cache@v2
-        id: yarn-cache
-        with:
-          path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
-          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
-          restore-keys: |
-            ${{ runner.os }}-yarn-
-
-      - name: Install
-        run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh
-
-      - name: Run Tests
-        run: ${{ matrix.RUN_COMMAND }}
-        env:
-          TYPE: ${{ matrix.TYPE }}
-
-      - name: Coverage - Pull Request
-        if: matrix.TYPE == 'server' && github.event_name == 'pull_request'
-        run: |
-          cp ~/frappe-bench/sites/.coverage ${GITHUB_WORKSPACE}
-          cd ${GITHUB_WORKSPACE}
-          pip install coveralls==2.2.0
-          pip install coverage==4.5.4
-          coveralls --service=github
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-          COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }}
-          COVERALLS_SERVICE_NAME: github
-          
-      - name: Coverage - Push
-        if: matrix.TYPE == 'server' && github.event_name == 'push'
-        run: |
-          cp ~/frappe-bench/sites/.coverage ${GITHUB_WORKSPACE}
-          cd ${GITHUB_WORKSPACE}
-          pip install coveralls==2.2.0
-          pip install coverage==4.5.4
-          coveralls --service=github-actions
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-          COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }}
-          COVERALLS_SERVICE_NAME: github-actions
-
diff --git a/.github/workflows/patch.yml b/.github/workflows/patch.yml
new file mode 100644
index 0000000..7c9e027
--- /dev/null
+++ b/.github/workflows/patch.yml
@@ -0,0 +1,69 @@
+name: Patch
+
+on: [pull_request, workflow_dispatch]
+
+jobs:
+  test:
+    runs-on: ubuntu-18.04
+
+    name: Patch Test
+
+    services:
+      mysql:
+        image: mariadb:10.3
+        env:
+          MYSQL_ALLOW_EMPTY_PASSWORD: YES
+        ports:
+          - 3306:3306
+        options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
+
+    steps:
+      - name: Clone
+        uses: actions/checkout@v2
+
+      - name: Setup Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3.6
+
+      - name: Add to Hosts
+        run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts
+
+      - name: Cache pip
+        uses: actions/cache@v2
+        with:
+          path: ~/.cache/pip
+          key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
+          restore-keys: |
+            ${{ runner.os }}-pip-
+            ${{ runner.os }}-
+
+      - name: Cache node modules
+        uses: actions/cache@v2
+        env:
+          cache-name: cache-node-modules
+        with:
+          path: ~/.npm
+          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
+          restore-keys: |
+            ${{ runner.os }}-build-${{ env.cache-name }}-
+            ${{ runner.os }}-build-
+            ${{ runner.os }}-
+
+      - name: Get yarn cache directory path
+        id: yarn-cache-dir-path
+        run: echo "::set-output name=dir::$(yarn cache dir)"
+
+      - uses: actions/cache@v2
+        id: yarn-cache
+        with:
+          path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
+          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
+          restore-keys: |
+            ${{ runner.os }}-yarn-
+
+      - name: Install
+        run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh
+
+      - name: Run Patch Tests
+        run: cd ~/frappe-bench/ && wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz &&  bench --site test_site --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz && bench --site test_site migrate
diff --git a/.github/workflows/server-tests.yml b/.github/workflows/server-tests.yml
new file mode 100644
index 0000000..92685e2
--- /dev/null
+++ b/.github/workflows/server-tests.yml
@@ -0,0 +1,110 @@
+name: Server
+
+on: [pull_request, workflow_dispatch]
+
+jobs:
+  test:
+    runs-on: ubuntu-18.04
+
+    strategy:
+      fail-fast: false
+
+      matrix:
+        container: [1, 2, 3]
+
+    name: Python Unit Tests
+
+    services:
+      mysql:
+        image: mariadb:10.3
+        env:
+          MYSQL_ALLOW_EMPTY_PASSWORD: YES
+        ports:
+          - 3306:3306
+        options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
+
+    steps:
+      - name: Clone
+        uses: actions/checkout@v2
+
+      - name: Setup Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3.7
+
+      - name: Add to Hosts
+        run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts
+
+      - name: Cache pip
+        uses: actions/cache@v2
+        with:
+          path: ~/.cache/pip
+          key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
+          restore-keys: |
+            ${{ runner.os }}-pip-
+            ${{ runner.os }}-
+
+      - name: Cache node modules
+        uses: actions/cache@v2
+        env:
+          cache-name: cache-node-modules
+        with:
+          path: ~/.npm
+          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
+          restore-keys: |
+            ${{ runner.os }}-build-${{ env.cache-name }}-
+            ${{ runner.os }}-build-
+            ${{ runner.os }}-
+
+      - name: Get yarn cache directory path
+        id: yarn-cache-dir-path
+        run: echo "::set-output name=dir::$(yarn cache dir)"
+
+      - uses: actions/cache@v2
+        id: yarn-cache
+        with:
+          path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
+          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
+          restore-keys: |
+            ${{ runner.os }}-yarn-
+
+      - name: Install
+        run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh
+
+      - name: Run Tests
+        run: cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --app erpnext --use-orchestrator --with-coverage
+        env:
+          TYPE: server
+          CI_BUILD_ID: ${{ github.run_id }}
+          ORCHESTRATOR_URL: http://test-orchestrator.frappe.io
+
+      - name: Upload Coverage Data
+        run: |
+          cp ~/frappe-bench/sites/.coverage ${GITHUB_WORKSPACE}
+          cd ${GITHUB_WORKSPACE}
+          pip3 install coverage==5.5
+          pip3 install coveralls==3.0.1
+          coveralls
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          COVERALLS_FLAG_NAME: run-${{ matrix.container }}
+          COVERALLS_SERVICE_NAME: ${{ github.event_name == 'pull_request' && 'github' || 'github-actions' }}
+          COVERALLS_PARALLEL: true
+
+  coveralls:
+    name: Coverage Wrap Up
+    needs: test
+    container: python:3-slim
+    runs-on: ubuntu-18.04
+    steps:
+      - name: Clone
+        uses: actions/checkout@v2
+
+      - name: Coveralls Finished
+        run: |
+          cd ${GITHUB_WORKSPACE}
+          pip3 install coverage==5.5
+          pip3 install coveralls==3.0.1
+          coveralls --finish
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/erpnext/accounts/doctype/accounting_dimension/test_accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/test_accounting_dimension.py
index fc1d7e3..e657a9a 100644
--- a/erpnext/accounts/doctype/accounting_dimension/test_accounting_dimension.py
+++ b/erpnext/accounts/doctype/accounting_dimension/test_accounting_dimension.py
@@ -7,7 +7,8 @@
 import unittest
 from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
 from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
-from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import delete_accounting_dimension
+
+test_dependencies = ['Cost Center', 'Location', 'Warehouse', 'Department']
 
 class TestAccountingDimension(unittest.TestCase):
 	def setUp(self):
diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py
index 7877abd..7f6254f 100644
--- a/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py
+++ b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py
@@ -9,6 +9,8 @@
 from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension import create_dimension, disable_dimension
 from erpnext.exceptions import InvalidAccountDimensionError, MandatoryAccountDimensionError
 
+test_dependencies = ['Location', 'Cost Center', 'Department']
+
 class TestAccountingDimensionFilter(unittest.TestCase):
 	def setUp(self):
 		create_dimension()
diff --git a/erpnext/accounts/doctype/accounting_period/test_accounting_period.py b/erpnext/accounts/doctype/accounting_period/test_accounting_period.py
index 10cd939..dc472c7 100644
--- a/erpnext/accounts/doctype/accounting_period/test_accounting_period.py
+++ b/erpnext/accounts/doctype/accounting_period/test_accounting_period.py
@@ -10,6 +10,8 @@
 from erpnext.accounts.doctype.accounting_period.accounting_period import OverlapError
 from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
 
+test_dependencies = ['Item']
+
 class TestAccountingPeriod(unittest.TestCase):
 	def test_overlap(self):
 		ap1 = create_accounting_period(start_date = "2018-04-01",
@@ -38,7 +40,7 @@
 	accounting_period.start_date = args.start_date or nowdate()
 	accounting_period.end_date = args.end_date or add_months(nowdate(), 1)
 	accounting_period.company = args.company or "_Test Company"
-	accounting_period.period_name =args.period_name or  "_Test_Period_Name_1"
+	accounting_period.period_name = args.period_name or "_Test_Period_Name_1"
 	accounting_period.append("closed_documents", {
 		"document_type": 'Sales Invoice', "closed": 1
 	})
diff --git a/erpnext/accounts/doctype/budget/test_budget.py b/erpnext/accounts/doctype/budget/test_budget.py
index c5ec23c..603e21e 100644
--- a/erpnext/accounts/doctype/budget/test_budget.py
+++ b/erpnext/accounts/doctype/budget/test_budget.py
@@ -11,6 +11,8 @@
 from erpnext.accounts.doctype.budget.budget import get_actual_expense, BudgetError
 from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
 
+test_dependencies = ['Monthly Distribution']
+
 class TestBudget(unittest.TestCase):
 	def test_monthly_budget_crossed_ignore(self):
 		set_total_expense_zero(nowdate(), "cost_center")
diff --git a/erpnext/accounts/doctype/dunning/test_dunning.py b/erpnext/accounts/doctype/dunning/test_dunning.py
index c5ce514..e2d4d82 100644
--- a/erpnext/accounts/doctype/dunning/test_dunning.py
+++ b/erpnext/accounts/doctype/dunning/test_dunning.py
@@ -29,7 +29,7 @@
 		self.assertEqual(round(amounts.get('interest_amount'), 2), 0.44)
 		self.assertEqual(round(amounts.get('dunning_amount'), 2), 20.44)
 		self.assertEqual(round(amounts.get('grand_total'), 2), 120.44)
-	
+
 	def test_gl_entries(self):
 		dunning = create_dunning()
 		dunning.submit()
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index aedf1c6..556f49d 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -152,7 +152,7 @@
 			frappe.throw(_("Valid from date must be less than valid upto date"))
 
 	def validate_condition(self):
-		if self.condition and ("=" in self.condition) and re.match("""[\w\.:_]+\s*={1}\s*[\w\.@'"]+""", self.condition):
+		if self.condition and ("=" in self.condition) and re.match(r'[\w\.:_]+\s*={1}\s*[\w\.@\'"]+', self.condition):
 			frappe.throw(_("Invalid condition expression"))
 
 #--------------------------------------------------------------------------------
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index 66be11f..53db689 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -636,8 +636,8 @@
 
 	def test_rejected_serial_no(self):
 		pi = make_purchase_invoice(item_code="_Test Serialized Item With Series", received_qty=2, qty=1,
-			rejected_qty=1, rate=500, update_stock=1,
-			rejected_warehouse = "_Test Rejected Warehouse - _TC")
+			rejected_qty=1, rate=500, update_stock=1, rejected_warehouse = "_Test Rejected Warehouse - _TC",
+			allow_zero_valuation_rate=1)
 
 		self.assertEqual(frappe.db.get_value("Serial No", pi.get("items")[0].serial_no, "warehouse"),
 			pi.get("items")[0].warehouse)
@@ -994,7 +994,8 @@
 		"project": args.project,
 		"rejected_warehouse": args.rejected_warehouse or "",
 		"rejected_serial_no": args.rejected_serial_no or "",
-		"asset_location": args.location or ""
+		"asset_location": args.location or "",
+		"allow_zero_valuation_rate": args.get("allow_zero_valuation_rate") or 0
 	})
 
 	if args.get_taxes_and_charges:
diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py
index 30a270c..3cd4b80 100644
--- a/erpnext/assets/doctype/asset/test_asset.py
+++ b/erpnext/assets/doctype/asset/test_asset.py
@@ -566,7 +566,7 @@
 		doc = make_invoice(pr.name)
 
 		self.assertEqual('Asset Received But Not Billed - _TC', doc.items[0].expense_account)
-	
+
 	def test_asset_cwip_toggling_cases(self):
 		cwip = frappe.db.get_value("Asset Category", "Computers", "enable_cwip_accounting")
 		name = frappe.db.get_value("Asset Category Account", filters={"parent": "Computers"}, fieldname=["name"])
diff --git a/erpnext/buying/report/subcontracted_raw_materials_to_be_transferred/test_subcontracted_raw_materials_to_be_transferred.py b/erpnext/buying/report/subcontracted_raw_materials_to_be_transferred/test_subcontracted_raw_materials_to_be_transferred.py
index 6900938..c1fc6fb 100644
--- a/erpnext/buying/report/subcontracted_raw_materials_to_be_transferred/test_subcontracted_raw_materials_to_be_transferred.py
+++ b/erpnext/buying/report/subcontracted_raw_materials_to_be_transferred/test_subcontracted_raw_materials_to_be_transferred.py
@@ -9,12 +9,12 @@
 from erpnext.buying.report.subcontracted_raw_materials_to_be_transferred.subcontracted_raw_materials_to_be_transferred import execute
 import json, frappe, unittest
 
-class TestSubcontractedItemToBeReceived(unittest.TestCase):
+class TestSubcontractedItemToBeTransferred(unittest.TestCase):
 
-	def test_pending_and_received_qty(self):
+	def test_pending_and_transferred_qty(self):
 		po = create_purchase_order(item_code='_Test FG Item', is_subcontracted='Yes')
-		make_stock_entry(item_code='_Test Item', target='_Test Warehouse 1 - _TC', qty=100, basic_rate=100)
-		make_stock_entry(item_code='_Test Item Home Desktop 100', target='_Test Warehouse 1 - _TC', qty=100, basic_rate=100)
+		make_stock_entry(item_code='_Test Item', target='_Test Warehouse - _TC', qty=100, basic_rate=100)
+		make_stock_entry(item_code='_Test Item Home Desktop 100', target='_Test Warehouse - _TC', qty=100, basic_rate=100)
 		transfer_subcontracted_raw_materials(po.name)
 		col, data = execute(filters=frappe._dict({'supplier': po.supplier,
 		   'from_date': frappe.utils.get_datetime(frappe.utils.add_to_date(po.transaction_date, days=-10)),
@@ -38,7 +38,8 @@
 		'warehouse': '_Test Warehouse - _TC', 'rate': 100, 'amount': 200, 'stock_uom': 'Nos'}]
 	rm_item_string = json.dumps(rm_item)
 	se = frappe.get_doc(make_rm_stock_entry(po, rm_item_string))
+	se.from_warehouse = '_Test Warehouse 1 - _TC'
 	se.to_warehouse = '_Test Warehouse 1 - _TC'
 	se.stock_entry_type = 'Send to Subcontractor'
 	se.save()
-	se.submit()
\ No newline at end of file
+	se.submit()
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 544e624..f88e8df 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -1011,7 +1011,6 @@
 				else:
 					grand_total -= self.get("total_advance")
 					base_grand_total = flt(grand_total * self.get("conversion_rate"), self.precision("base_grand_total"))
-
 			if total != flt(grand_total, self.precision("grand_total")) or \
 				base_total != flt(base_grand_total, self.precision("base_grand_total")):
 				frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand / Rounded Total"))
diff --git a/erpnext/education/doctype/fees/test_fees.py b/erpnext/education/doctype/fees/test_fees.py
index eedc2ae..c6bb704 100644
--- a/erpnext/education/doctype/fees/test_fees.py
+++ b/erpnext/education/doctype/fees/test_fees.py
@@ -9,8 +9,7 @@
 from frappe.utils.make_random import get_random
 from erpnext.education.doctype.program.test_program import make_program_and_linked_courses
 
-# test_records = frappe.get_test_records('Fees')
-
+test_dependencies = ['Company']
 class TestFees(unittest.TestCase):
 
 	def test_fees(self):
diff --git a/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py b/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py
index d370fbc..3c2e59a 100644
--- a/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py
+++ b/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py
@@ -81,7 +81,7 @@
 		integration_request.reload()
 		self.assertEqual(pos_invoice.mpesa_receipt_number, "LGR7OWQX0R")
 		self.assertEqual(integration_request.status, "Completed")
-		
+
 		frappe.db.set_value("Customer", "_Test Customer", "default_currency", "")
 		integration_request.delete()
 		pr.reload()
@@ -139,7 +139,7 @@
 		pr.cancel()
 		pr.delete()
 		pos_invoice.delete()
-	
+
 	def test_processing_of_only_one_succes_callback_payload(self):
 		create_mpesa_settings(payment_gateway_name="Payment")
 		mpesa_account = frappe.db.get_value("Payment Gateway Account", {"payment_gateway": 'Mpesa-Payment'}, "payment_account")
diff --git a/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py b/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py
index d079bed..113fa51 100644
--- a/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py
+++ b/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py
@@ -29,7 +29,7 @@
 		self.assertEqual(frappe.db.get_value('Therapy Plan', plan.name, 'status'), 'Completed')
 
 		patient, medical_department, 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)
 		session.submit()
diff --git a/erpnext/hr/doctype/upload_attendance/test_upload_attendance.py b/erpnext/hr/doctype/upload_attendance/test_upload_attendance.py
index 6e151d0..03b0cf3 100644
--- a/erpnext/hr/doctype/upload_attendance/test_upload_attendance.py
+++ b/erpnext/hr/doctype/upload_attendance/test_upload_attendance.py
@@ -5,11 +5,18 @@
 
 import frappe
 import unittest
+import erpnext
 from frappe.utils import getdate
 from erpnext.hr.doctype.upload_attendance.upload_attendance import get_data
 from erpnext.hr.doctype.employee.test_employee import make_employee
 
+test_dependencies = ['Holiday List']
+
 class TestUploadAttendance(unittest.TestCase):
+	@classmethod
+	def setUpClass(cls):
+		frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", '_Test Holiday List')
+
 	def test_date_range(self):
 		employee = make_employee("test_employee@company.com")
 		employee_doc = frappe.get_doc("Employee", employee)
diff --git a/erpnext/payroll/doctype/payroll_entry/test_payroll_entry.py b/erpnext/payroll/doctype/payroll_entry/test_payroll_entry.py
index 7528bf7..b80b320 100644
--- a/erpnext/payroll/doctype/payroll_entry/test_payroll_entry.py
+++ b/erpnext/payroll/doctype/payroll_entry/test_payroll_entry.py
@@ -15,7 +15,13 @@
 from erpnext.loan_management.doctype.loan.test_loan import create_loan, make_loan_disbursement_entry, create_loan_type, create_loan_accounts
 from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_term_loans
 
+test_dependencies = ['Holiday List']
+
 class TestPayrollEntry(unittest.TestCase):
+	@classmethod
+	def setUpClass(cls):
+		frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", '_Test Holiday List')
+
 	def setUp(self):
 		for dt in ["Salary Slip", "Salary Component", "Salary Component Account",
 			"Payroll Entry", "Salary Structure", "Salary Structure Assignment", "Payroll Employee Detail", "Additional Salary"]:
diff --git a/erpnext/public/js/help_links.js b/erpnext/public/js/help_links.js
index e789923..aa9bba1 100644
--- a/erpnext/public/js/help_links.js
+++ b/erpnext/public/js/help_links.js
@@ -644,14 +644,14 @@
 frappe.help.help_links["List/Asset"] = [
 	{
 		label: "Managing Fixed Assets",
-		url: docsUrl + "user/manual/en/accounts/managing-fixed-assets",
+		url: docsUrl + "user/manual/en/accounts/opening-balance/fixed_assets",
 	},
 ];
 
 frappe.help.help_links["List/Asset Category"] = [
 	{
 		label: "Asset Category",
-		url: docsUrl + "user/manual/en/accounts/managing-fixed-assets",
+		url: docsUrl + "user/manual/en/asset/asset-category",
 	},
 ];
 
@@ -663,7 +663,7 @@
 	{ label: "Item", url: docsUrl + "user/manual/en/stock/item" },
 	{
 		label: "Item Price",
-		url: docsUrl + "user/manual/en/stock/item/item-price",
+		url: docsUrl + "user/manual/en/stock/item-price",
 	},
 	{
 		label: "Barcode",
@@ -672,25 +672,25 @@
 	},
 	{
 		label: "Item Wise Taxation",
-		url: docsUrl + "user/manual/en/accounts/item-wise-taxation",
+		url: docsUrl + "user/manual/en/accounts/item-tax-template",
 	},
 	{
 		label: "Managing Fixed Assets",
-		url: docsUrl + "user/manual/en/accounts/managing-fixed-assets",
+		url: docsUrl + "user/manual/en/accounts/opening-balance/fixed_assets",
 	},
 	{
 		label: "Item Codification",
-		url: docsUrl + "user/manual/en/stock/item/item-codification",
+		url: docsUrl + "user/manual/en/stock/articles/item-codification",
 	},
 	{
 		label: "Item Variants",
-		url: docsUrl + "user/manual/en/stock/item/item-variants",
+		url: docsUrl + "user/manual/en/stock/item-variants",
 	},
 	{
 		label: "Item Valuation",
 		url:
 			docsUrl +
-			"user/manual/en/stock/item/item-valuation-fifo-and-moving-average",
+			"user/manual/en/stock/articles/item-valuation-fifo-and-moving-average",
 	},
 ];
 
@@ -698,7 +698,7 @@
 	{ label: "Item", url: docsUrl + "user/manual/en/stock/item" },
 	{
 		label: "Item Price",
-		url: docsUrl + "user/manual/en/stock/item/item-price",
+		url: docsUrl + "user/manual/en/stock/item-price",
 	},
 	{
 		label: "Barcode",
@@ -707,19 +707,19 @@
 	},
 	{
 		label: "Item Wise Taxation",
-		url: docsUrl + "user/manual/en/accounts/item-wise-taxation",
+		url: docsUrl + "user/manual/en/accounts/item-tax-template",
 	},
 	{
 		label: "Managing Fixed Assets",
-		url: docsUrl + "user/manual/en/accounts/managing-fixed-assets",
+		url: docsUrl + "user/manual/en/accounts/opening-balance/fixed_assets",
 	},
 	{
 		label: "Item Codification",
-		url: docsUrl + "user/manual/en/stock/item/item-codification",
+		url: docsUrl + "user/manual/en/stock/articles/item-codification",
 	},
 	{
 		label: "Item Variants",
-		url: docsUrl + "user/manual/en/stock/item/item-variants",
+		url: docsUrl + "user/manual/en/stock/item-variants",
 	},
 	{
 		label: "Item Valuation",
diff --git a/erpnext/public/scss/shopping_cart.scss b/erpnext/public/scss/shopping_cart.scss
index 159a8a4..9402cf9 100644
--- a/erpnext/public/scss/shopping_cart.scss
+++ b/erpnext/public/scss/shopping_cart.scss
@@ -1,4 +1,3 @@
-@import "frappe/public/scss/desk/variables";
 @import "frappe/public/scss/common/mixins";
 
 body.product-page {
@@ -74,15 +73,6 @@
 		}
 	}
 
-	// .card-body {
-	// 	text-align: center;
-	// }
-
-	// .featured-item {
-	// 	.card-body {
-	// 		text-align: left;
-	// 	}
-	// }
 	.card-img-container {
 		height: 210px;
 		width: 100%;
@@ -217,12 +207,12 @@
 		border-color: var(--table-border-color) !important;
 		padding: 15px;
 
-		@include media-breakpoint-between(xs, md) {
+		@media (max-width: var(--md-width)) {
 			height: 300px;
 			width: 300px;
 		}
 
-		@include media-breakpoint-up(lg) {
+		@media (min-width: var(--lg-width)) {
 			height: 350px;
 			width: 350px;
 		}
@@ -233,11 +223,12 @@
 	}
 
 	.item-slideshow {
-		@include media-breakpoint-between(xs, md) {
+
+		@media (max-width: var(--md-width)) {
 			max-height: 320px;
 		}
 
-		@include media-breakpoint-up(lg) {
+		@media (min-width: var(--lg-width)) {
 			max-height: 430px;
 		}
 
@@ -254,7 +245,7 @@
 		cursor: pointer;
 
 		&:hover, &.active {
-			border-color: $primary;
+			border-color: var(--primary);
 		}
 	}
 
@@ -316,12 +307,9 @@
 }
 
 .item-group-slideshow {
-	.item-group-description {
-		// max-width: 900px;
-	}
 
 	.carousel-inner.rounded-carousel {
-		border-radius: $card-border-radius;
+		border-radius: var(--card-border-radius);
 	}
 }
 
diff --git a/erpnext/public/scss/website.scss b/erpnext/public/scss/website.scss
index 56b717c..f4325c0 100644
--- a/erpnext/public/scss/website.scss
+++ b/erpnext/public/scss/website.scss
@@ -1,4 +1,3 @@
-@import "frappe/public/scss/website/variables";
 
 .filter-options {
 	max-height: 300px;
@@ -14,7 +13,7 @@
 	}
 
 	&.active {
-		border-color: $primary;
+		border-color: var(--primary);
 
 		.check {
 			display: inline-flex;
@@ -25,7 +24,7 @@
 .check {
 	display: inline-flex;
 	padding: 0.25rem;
-	background: $primary;
+	background: var(--primary);
 	color: white;
 	border-radius: 50%;
 	font-size: 12px;
@@ -38,12 +37,12 @@
 }
 
 .result {
-	border-bottom: 1px solid $border-color;
+	border-bottom: 1px solid var(--border-color);
 }
 
 .transaction-list-item {
 	padding: 1rem 0;
-	border-top: 1px solid $border-color;
+	border-top: 1px solid var(--border-color);
 	position: relative;
 
 	a.transaction-item-link {
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index fc227de..075c698 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -500,7 +500,7 @@
 
 		if not isinstance(docname, list):
 			# removes characters not allowed in a filename (https://stackoverflow.com/a/38766141/4767738)
-			filename_prefix = re.sub('[^\w_.)( -]', '', docname)
+			filename_prefix = re.sub(r'[^\w_.)( -]', '', docname)
 
 	frappe.local.response.filename = '{0}_e-WayBill_Data_{1}.json'.format(filename_prefix, frappe.utils.random_string(5))
 
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 750a1a6..cb811df 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.py
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.py
@@ -15,7 +15,6 @@
 	data = dict()
 	result = []
 
-	allow_negative_stock = frappe.db.get_single_value('Stock Settings', 'allow_negative_stock')
 	warehouse, hide_unavailable_items = frappe.db.get_value('POS Profile', pos_profile, ['warehouse', 'hide_unavailable_items'])
 
 	if not frappe.db.exists('Item Group', item_group):
@@ -62,7 +61,6 @@
 			`tabItem` item {bin_join_selection}
 		WHERE
 			item.disabled = 0
-			AND item.is_stock_item = 1
 			AND item.has_variants = 0
 			AND item.is_sales_item = 1
 			AND item.is_fixed_asset = 0
@@ -84,6 +82,7 @@
 		), {'warehouse': warehouse}, as_dict=1)
 
 	if items_data:
+		items_data = filter_service_items(items_data)
 		items = [d.item_code for d in items_data]
 		item_prices_data = frappe.get_all("Item Price",
 			fields = ["item_code", "price_list_rate", "currency"],
@@ -96,10 +95,7 @@
 		for item in items_data:
 			item_code = item.item_code
 			item_price = item_prices.get(item_code) or {}
-			if allow_negative_stock:
-				item_stock_qty = frappe.db.sql("""select ifnull(sum(actual_qty), 0) from `tabBin` where item_code = %s""", item_code)[0][0]
-			else:
-				item_stock_qty = get_stock_availability(item_code, warehouse)
+			item_stock_qty = get_stock_availability(item_code, warehouse)
 
 			row = {}
 			row.update(item)
@@ -135,6 +131,14 @@
 
 	return {}
 
+def filter_service_items(items):
+	for item in items:
+		if not item['is_stock_item']:
+			if not frappe.db.exists('Product Bundle', item['item_code']):
+				items.remove(item)
+	
+	return items
+
 def get_conditions(item_code, serial_no, batch_no, barcode):
 	if serial_no or batch_no or barcode:
 		return "item.name = {0}".format(frappe.db.escape(item_code))
diff --git a/erpnext/setup/doctype/email_digest/email_digest.py b/erpnext/setup/doctype/email_digest/email_digest.py
index 8c97322..340d89b 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.py
+++ b/erpnext/setup/doctype/email_digest/email_digest.py
@@ -249,7 +249,7 @@
 				card = cache.get(cache_key)
 
 				if card:
-					card = eval(card)
+					card = frappe.safe_eval(card)
 
 				else:
 					card = frappe._dict(getattr(self, "get_" + key)())
@@ -808,7 +808,6 @@
 			val = balance_on_to_date - balance_before_from_date
 		else:
 			last_year_closing_balance = get_balance_on(account, date=fy_start_date - timedelta(days=1))
-			print(fy_start_date - timedelta(days=1), last_year_closing_balance)
 			val = balance_on_to_date + (last_year_closing_balance - balance_before_from_date)
 
 		return val
@@ -837,4 +836,4 @@
 	elif frequency == "Monthly":
 		to_date = add_to_date(from_date, months=1)
 
-	return from_date, to_date
\ No newline at end of file
+	return from_date, to_date
diff --git a/erpnext/shopping_cart/test_shopping_cart.py b/erpnext/shopping_cart/test_shopping_cart.py
index d857bf5..ac61aeb 100644
--- a/erpnext/shopping_cart/test_shopping_cart.py
+++ b/erpnext/shopping_cart/test_shopping_cart.py
@@ -7,7 +7,7 @@
 from frappe.utils import nowdate, add_months
 from erpnext.shopping_cart.cart import _get_cart_quotation, update_cart, get_party
 from erpnext.tests.utils import create_test_contact_and_address
-
+from erpnext.accounts.doctype.tax_rule.tax_rule import  ConflictingTaxRule
 
 # test_dependencies = ['Payment Terms Template']
 
@@ -125,7 +125,7 @@
 		tax_rule = frappe.get_test_records("Tax Rule")[0]
 		try:
 			frappe.get_doc(tax_rule).insert()
-		except frappe.DuplicateEntryError:
+		except (frappe.DuplicateEntryError, ConflictingTaxRule):
 			pass
 
 	def create_quotation(self):
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index e5ef978..5095a80 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -297,6 +297,8 @@
 			item_code = "Test Extra Item 1", qty=10, basic_rate=100)
 		se2 = make_stock_entry(target="_Test Warehouse - _TC",
 			item_code = "_Test FG Item", qty=1, basic_rate=100)
+		se3 = make_stock_entry(target="_Test Warehouse - _TC",
+			item_code = "Test Extra Item 2", qty=1, basic_rate=100)
 		rm_items = [
 			{
 				"item_code": item_code,
@@ -331,6 +333,7 @@
 		se.cancel()
 		se1.cancel()
 		se2.cancel()
+		se3.cancel()
 		po.reload()
 		po.cancel()
 
diff --git a/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py
index 3296f5b..ba31ad7 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py
+++ b/erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py
@@ -15,10 +15,12 @@
 from erpnext.stock.doctype.landed_cost_voucher.test_landed_cost_voucher import create_landed_cost_voucher
 from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
 from erpnext.stock.doctype.stock_ledger_entry.stock_ledger_entry import BackDatedStockTransaction
+from frappe.core.page.permission_manager.permission_manager import reset
 
 class TestStockLedgerEntry(unittest.TestCase):
 	def setUp(self):
 		items = create_items()
+		reset('Stock Entry')
 
 		# delete SLE and BINs for all items
 		frappe.db.sql("delete from `tabStock Ledger Entry` where item_code in (%s)" % (', '.join(['%s']*len(items))), items)
@@ -314,10 +316,11 @@
 		# Set User with Stock User role but not Stock Manager
 		try:
 			user = frappe.get_doc("User", "test@example.com")
-			frappe.set_user(user.name)
 			user.add_roles("Stock User")
 			user.remove_roles("Stock Manager")
 
+			frappe.set_user(user.name)
+
 			stock_entry_on_today = make_stock_entry(target="_Test Warehouse - _TC", qty=10, basic_rate=100)
 			back_dated_se_1 = make_stock_entry(target="_Test Warehouse - _TC", qty=10, basic_rate=100,
 				posting_date=add_days(today(), -1), do_not_submit=True)
diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py
index 8ba1f1c..8917bfe 100644
--- a/erpnext/stock/stock_balance.py
+++ b/erpnext/stock/stock_balance.py
@@ -194,9 +194,6 @@
 		serial_nos = frappe.db.sql("""select count(name) from `tabSerial No`
 			where item_code=%s and warehouse=%s and docstatus < 2""", (d[0], d[1]))
 
-		if serial_nos and flt(serial_nos[0][0]) != flt(d[2]):
-			print(d[0], d[1], d[2], serial_nos[0][0])
-
 		sle = frappe.db.sql("""select valuation_rate, company from `tabStock Ledger Entry`
 			where item_code = %s and warehouse = %s and is_cancelled = 0
 			order by posting_date desc limit 1""", (d[0], d[1]))
@@ -230,7 +227,7 @@
 		})
 
 		update_bin(args)
-		
+
 		create_repost_item_valuation_entry({
 			"item_code": d[0],
 			"warehouse": d[1],
diff --git a/erpnext/tests/__init__.py b/erpnext/tests/__init__.py
index e69de29..a504340 100644
--- a/erpnext/tests/__init__.py
+++ b/erpnext/tests/__init__.py
@@ -0,0 +1 @@
+global_test_dependencies = ['User', 'Company', 'Item']
diff --git a/erpnext/utilities/__init__.py b/erpnext/utilities/__init__.py
index 618cc98..0a5aa3c 100644
--- a/erpnext/utilities/__init__.py
+++ b/erpnext/utilities/__init__.py
@@ -12,7 +12,6 @@
 
 		for f in dt.fields:
 			if f.fieldname == d.fieldname and f.fieldtype in ("Text", "Small Text"):
-				print(f.parent, f.fieldname)
 				f.fieldtype = "Text Editor"
 				dt.save()
 				break