Merge pull request #31676 from ruthra-kumar/fix_tax_withholding_checkbox_on_PI

fix: enable tax withholding checkbox in PI with supplier_tds
diff --git a/.github/helper/install.sh b/.github/helper/install.sh
index f0f83b0..efd2f5c 100644
--- a/.github/helper/install.sh
+++ b/.github/helper/install.sh
@@ -2,13 +2,6 @@
 
 set -e
 
-# Check for merge conflicts before proceeding
-python -m compileall -f "${GITHUB_WORKSPACE}"
-if grep -lr --exclude-dir=node_modules "^<<<<<<< " "${GITHUB_WORKSPACE}"
-    then echo "Found merge conflicts"
-    exit 1
-fi
-
 cd ~ || exit
 
 sudo apt update && sudo apt install redis-server libcups2-dev
diff --git a/.github/workflows/patch.yml b/.github/workflows/patch.yml
index a71db72..ecbb7c6 100644
--- a/.github/workflows/patch.yml
+++ b/.github/workflows/patch.yml
@@ -34,6 +34,14 @@
       - name: Clone
         uses: actions/checkout@v2
 
+      - name: Check for valid Python & Merge Conflicts
+        run: |
+          python -m compileall -f "${GITHUB_WORKSPACE}"
+          if grep -lr --exclude-dir=node_modules "^<<<<<<< " "${GITHUB_WORKSPACE}"
+              then echo "Found merge conflicts"
+              exit 1
+          fi
+
       - name: Setup Python
         uses: "gabrielfalcao/pyenv-action@v9"
         with:
diff --git a/.github/workflows/server-tests-mariadb.yml b/.github/workflows/server-tests-mariadb.yml
index f65cb46..64134bc 100644
--- a/.github/workflows/server-tests-mariadb.yml
+++ b/.github/workflows/server-tests-mariadb.yml
@@ -61,6 +61,14 @@
         with:
           python-version: '3.10'
 
+      - name: Check for valid Python & Merge Conflicts
+        run: |
+          python -m compileall -f "${GITHUB_WORKSPACE}"
+          if grep -lr --exclude-dir=node_modules "^<<<<<<< " "${GITHUB_WORKSPACE}"
+              then echo "Found merge conflicts"
+              exit 1
+          fi
+
       - name: Setup Node
         uses: actions/setup-node@v2
         with:
diff --git a/.github/workflows/server-tests-postgres.yml b/.github/workflows/server-tests-postgres.yml
index 53a94db..651c935 100644
--- a/.github/workflows/server-tests-postgres.yml
+++ b/.github/workflows/server-tests-postgres.yml
@@ -48,6 +48,14 @@
         with:
           python-version: '3.10'
 
+      - name: Check for valid Python & Merge Conflicts
+        run: |
+          python -m compileall -f "${GITHUB_WORKSPACE}"
+          if grep -lr --exclude-dir=node_modules "^<<<<<<< " "${GITHUB_WORKSPACE}"
+              then echo "Found merge conflicts"
+              exit 1
+          fi
+
       - name: Setup Node
         uses: actions/setup-node@v2
         with:
@@ -90,7 +98,6 @@
           restore-keys: |
             ${{ runner.os }}-yarn-
 
-
       - name: Install
         run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh
         env:
diff --git a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py
index 3dca588..e9ed2e4 100644
--- a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py
+++ b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py
@@ -114,7 +114,7 @@
 			(pcv.name),
 		)
 
-		self.assertEqual(pcv_gle, expected_gle)
+		self.assertSequenceEqual(pcv_gle, expected_gle)
 
 		pcv.reload()
 		pcv.cancel()
@@ -175,7 +175,7 @@
 			(pcv.name),
 		)
 
-		self.assertEqual(pcv_gle, expected_gle)
+		self.assertSequenceEqual(pcv_gle, expected_gle)
 
 	def make_period_closing_voucher(self, submit=True):
 		surplus_account = create_account()
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index 17dd804..1c9d3fb 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -412,7 +412,7 @@
   },
   {
    "default": "0",
-   "depends_on": "eval: doc.is_return && doc.return_against",
+   "depends_on": "eval: doc.is_return",
    "fieldname": "update_billed_amount_in_sales_order",
    "fieldtype": "Check",
    "hide_days": 1,
@@ -2022,7 +2022,7 @@
    "link_fieldname": "consolidated_invoice"
   }
  ],
- "modified": "2022-06-16 16:22:44.870575",
+ "modified": "2022-07-11 17:43:56.435382",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice",
diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py
index 34d374c..986b700 100644
--- a/erpnext/assets/doctype/asset/test_asset.py
+++ b/erpnext/assets/doctype/asset/test_asset.py
@@ -133,7 +133,7 @@
 			order by account""",
 			pi.name,
 		)
-		self.assertEqual(gle, expected_gle)
+		self.assertSequenceEqual(gle, expected_gle)
 
 		pi.cancel()
 		asset.cancel()
@@ -208,7 +208,7 @@
 			order by account""",
 			asset.journal_entry_for_scrap,
 		)
-		self.assertEqual(gle, expected_gle)
+		self.assertSequenceEqual(gle, expected_gle)
 
 		restore_asset(asset.name)
 
@@ -253,7 +253,7 @@
 			si.name,
 		)
 
-		self.assertEqual(gle, expected_gle)
+		self.assertSequenceEqual(gle, expected_gle)
 
 		si.cancel()
 		self.assertEqual(frappe.db.get_value("Asset", asset.name, "status"), "Partially Depreciated")
@@ -361,7 +361,7 @@
 			pr.name,
 		)
 
-		self.assertEqual(pr_gle, expected_gle)
+		self.assertSequenceEqual(pr_gle, expected_gle)
 
 		pi = make_invoice(pr.name)
 		pi.submit()
@@ -381,7 +381,7 @@
 			pi.name,
 		)
 
-		self.assertEqual(pi_gle, expected_gle)
+		self.assertSequenceEqual(pi_gle, expected_gle)
 
 		asset = frappe.db.get_value("Asset", {"purchase_receipt": pr.name, "docstatus": 0}, "name")
 
@@ -414,7 +414,7 @@
 			asset_doc.name,
 		)
 
-		self.assertEqual(gle, expected_gle)
+		self.assertSequenceEqual(gle, expected_gle)
 
 	def test_asset_cwip_toggling_cases(self):
 		cwip = frappe.db.get_value("Asset Category", "Computers", "enable_cwip_accounting")
@@ -1287,7 +1287,7 @@
 			asset.name,
 		)
 
-		self.assertEqual(gle, expected_gle)
+		self.assertSequenceEqual(gle, expected_gle)
 		self.assertEqual(asset.get("value_after_depreciation"), 0)
 
 	def test_expected_value_change(self):
diff --git a/erpnext/assets/doctype/asset_value_adjustment/test_asset_value_adjustment.py b/erpnext/assets/doctype/asset_value_adjustment/test_asset_value_adjustment.py
index ebeb174..62c6366 100644
--- a/erpnext/assets/doctype/asset_value_adjustment/test_asset_value_adjustment.py
+++ b/erpnext/assets/doctype/asset_value_adjustment/test_asset_value_adjustment.py
@@ -91,7 +91,7 @@
 			adj_doc.journal_entry,
 		)
 
-		self.assertEqual(gle, expected_gle)
+		self.assertSequenceEqual(gle, expected_gle)
 
 
 def make_asset_value_adjustment(**args):
diff --git a/erpnext/patches/v14_0/remove_hr_and_payroll_modules.py b/erpnext/patches/v14_0/remove_hr_and_payroll_modules.py
index 259b111..4d01fcb 100644
--- a/erpnext/patches/v14_0/remove_hr_and_payroll_modules.py
+++ b/erpnext/patches/v14_0/remove_hr_and_payroll_modules.py
@@ -31,22 +31,22 @@
 		"Professional Tax Deductions",
 		"Provident Fund Deductions",
 	]:
-		frappe.delete_doc("Report", report, ignore_missing=True)
+		frappe.delete_doc("Report", report, ignore_missing=True, force=True)
 
 	doctypes = frappe.get_all(
 		"DocType", {"module": ("in", ["HR", "Payroll"]), "custom": 0}, pluck="name"
 	)
 	for doctype in doctypes:
-		frappe.delete_doc("DocType", doctype, ignore_missing=True)
+		frappe.delete_doc("DocType", doctype, ignore_missing=True, force=True)
 
-	frappe.delete_doc("DocType", "Salary Slip Loan", ignore_missing=True)
-	frappe.delete_doc("DocType", "Salary Component Account", ignore_missing=True)
+	frappe.delete_doc("DocType", "Salary Slip Loan", ignore_missing=True, force=True)
+	frappe.delete_doc("DocType", "Salary Component Account", ignore_missing=True, force=True)
 
 	notifications = frappe.get_all(
 		"Notification", {"module": ("in", ["HR", "Payroll"]), "is_standard": 1}, pluck="name"
 	)
 	for notifcation in notifications:
-		frappe.delete_doc("Notification", notifcation, ignore_missing=True)
+		frappe.delete_doc("Notification", notifcation, ignore_missing=True, force=True)
 
 	frappe.delete_doc("User Type", "Employee Self Service", ignore_missing=True, force=True)
 
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 35e0b0d..6605685 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -527,11 +527,14 @@
 					_("Please contact your administrator to extend the credit limits for {0}.").format(customer)
 				)
 
-			message = """Please contact any of the following users to extend the credit limits for {0}:
-				<br><br><ul><li>{1}</li></ul>""".format(
-				customer, "<li>".join(credit_controller_users_formatted)
+			user_list = "<br><br><ul><li>{0}</li></ul>".format(
+				"<li>".join(credit_controller_users_formatted)
 			)
 
+			message = _(
+				"Please contact any of the following users to extend the credit limits for {0}: {1}"
+			).format(customer, user_list)
+
 			# if the current user does not have permissions to override credit limit,
 			# prompt them to send out an email to the controller users
 			frappe.msgprint(
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index e5e317c..adfb39c 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -1620,6 +1620,65 @@
 		so.load_from_db()
 		self.assertEqual(so.billing_status, "Fully Billed")
 
+	def test_so_billing_status_with_crnote_against_sales_return(self):
+		"""
+		| Step | Document creation                    |                               |
+		|------+--------------------------------------+-------------------------------|
+		|    1 | SO -> DN -> SI                       | SO Fully Billed and Completed |
+		|    2 | DN -> Sales Return(Partial)          | SO 50% Delivered, 100% billed |
+		|    3 | Sales Return(Partial) -> Credit Note | SO 50% Delivered, 50% billed  |
+
+		"""
+		from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
+
+		so = make_sales_order(uom="Nos", do_not_save=1)
+		so.save()
+		so.submit()
+
+		self.assertEqual(so.billing_status, "Not Billed")
+
+		dn1 = make_delivery_note(so.name)
+		dn1.taxes_and_charges = ""
+		dn1.taxes.clear()
+		dn1.save().submit()
+
+		si = create_sales_invoice(qty=10, do_not_save=1)
+		si.items[0].sales_order = so.name
+		si.items[0].so_detail = so.items[0].name
+		si.items[0].delivery_note = dn1.name
+		si.items[0].dn_detail = dn1.items[0].name
+		si.save()
+		si.submit()
+
+		so.reload()
+		self.assertEqual(so.billing_status, "Fully Billed")
+		self.assertEqual(so.status, "Completed")
+
+		from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
+
+		dn1.reload()
+		dn_ret = create_delivery_note(is_return=1, return_against=dn1.name, qty=-5, do_not_submit=True)
+		dn_ret.items[0].against_sales_order = so.name
+		dn_ret.items[0].so_detail = so.items[0].name
+		dn_ret.submit()
+
+		so.reload()
+		self.assertEqual(so.per_billed, 100)
+		self.assertEqual(so.per_delivered, 50)
+
+		cr_note = create_sales_invoice(is_return=1, qty=-1, do_not_submit=True)
+		cr_note.items[0].qty = -5
+		cr_note.items[0].sales_order = so.name
+		cr_note.items[0].so_detail = so.items[0].name
+		cr_note.items[0].delivery_note = dn_ret.name
+		cr_note.items[0].dn_detail = dn_ret.items[0].name
+		cr_note.update_billed_amount_in_sales_order = True
+		cr_note.submit()
+
+		so.reload()
+		self.assertEqual(so.per_billed, 50)
+		self.assertEqual(so.per_delivered, 50)
+
 	def test_so_back_updated_from_wo_via_mr(self):
 		"SO -> MR (Manufacture) -> WO. Test if WO Qty is updated in SO."
 		from erpnext.manufacturing.doctype.work_order.work_order import (
diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js
index cb4bd51..da7576e 100644
--- a/erpnext/selling/page/point_of_sale/pos_controller.js
+++ b/erpnext/selling/page/point_of_sale/pos_controller.js
@@ -497,7 +497,10 @@
 
 	set_pos_profile_data() {
 		if (this.company && !this.frm.doc.company) this.frm.doc.company = this.company;
-		if (this.pos_profile && !this.frm.doc.pos_profile) this.frm.doc.pos_profile = this.pos_profile;
+		if ((this.pos_profile && !this.frm.doc.pos_profile) | (this.frm.doc.is_return && this.pos_profile != this.frm.doc.pos_profile)) {
+			this.frm.doc.pos_profile = this.pos_profile;
+		}
+
 		if (!this.frm.doc.company) return;
 
 		return this.frm.trigger("set_pos_data");
diff --git a/erpnext/setup/doctype/global_defaults/global_defaults.py b/erpnext/setup/doctype/global_defaults/global_defaults.py
index 984bab4..16e9434 100644
--- a/erpnext/setup/doctype/global_defaults/global_defaults.py
+++ b/erpnext/setup/doctype/global_defaults/global_defaults.py
@@ -30,18 +30,20 @@
 			frappe.db.set_default(key, self.get(keydict[key], ""))
 
 		# update year start date and year end date from fiscal_year
-		year_start_end_date = frappe.db.sql(
-			"""select year_start_date, year_end_date
-			from `tabFiscal Year` where name=%s""",
-			self.current_fiscal_year,
-		)
-		if year_start_end_date:
-			ysd = year_start_end_date[0][0] or ""
-			yed = year_start_end_date[0][1] or ""
+		if self.current_fiscal_year:
+			if fiscal_year := frappe.get_all(
+				"Fiscal Year",
+				filters={"name": self.current_fiscal_year},
+				fields=["year_start_date", "year_end_date"],
+				limit=1,
+				order_by=None,
+			):
+				ysd = fiscal_year[0].year_start_date or ""
+				yed = fiscal_year[0].year_end_date or ""
 
-			if ysd and yed:
-				frappe.db.set_default("year_start_date", ysd.strftime("%Y-%m-%d"))
-				frappe.db.set_default("year_end_date", yed.strftime("%Y-%m-%d"))
+				if ysd and yed:
+					frappe.db.set_default("year_start_date", ysd.strftime("%Y-%m-%d"))
+					frappe.db.set_default("year_end_date", yed.strftime("%Y-%m-%d"))
 
 		# enable default currency
 		if self.default_currency:
@@ -50,7 +52,6 @@
 		self.toggle_rounded_total()
 		self.toggle_in_words()
 
-		# clear cache
 		frappe.clear_cache()
 
 	@frappe.whitelist()