Merge pull request #30443 from frappe/mergify/bp/develop/pr-30438

fix: Incorrect default amount to pay for POS invoices (backport #30438)
diff --git a/.github/workflows/server-tests-mariadb.yml b/.github/workflows/server-tests-mariadb.yml
index 69be765..8cc5826 100644
--- a/.github/workflows/server-tests-mariadb.yml
+++ b/.github/workflows/server-tests-mariadb.yml
@@ -119,9 +119,22 @@
           ORCHESTRATOR_URL: http://test-orchestrator.frappe.io
 
       - name: Upload coverage data
+        uses: actions/upload-artifact@v3
+        with:
+          name: coverage-${{ matrix.container }}
+          path: /home/runner/frappe-bench/sites/coverage.xml
+
+  coverage:
+    name: Coverage Wrap Up
+    needs: test
+    runs-on: ubuntu-latest
+    steps:
+      - name: Download artifacts
+        uses: actions/download-artifact@v3
+
+      - name: Upload coverage data
         uses: codecov/codecov-action@v2
         with:
           name: MariaDB
           fail_ci_if_error: true
-          files: /home/runner/frappe-bench/sites/coverage.xml
           verbose: true
diff --git a/codecov.yml b/codecov.yml
index 1fa602a..7d9c37d 100644
--- a/codecov.yml
+++ b/codecov.yml
@@ -21,7 +21,6 @@
 comment:
   layout: "diff, files"
   require_changes: true
-  after_n_builds: 3
 
 ignore:
   - "erpnext/demo"
diff --git a/erpnext/accounts/doctype/gst_account/gst_account.json b/erpnext/accounts/doctype/gst_account/gst_account.json
index b6ec884..be5124c 100644
--- a/erpnext/accounts/doctype/gst_account/gst_account.json
+++ b/erpnext/accounts/doctype/gst_account/gst_account.json
@@ -10,6 +10,7 @@
   "sgst_account",
   "igst_account",
   "cess_account",
+  "utgst_account",
   "is_reverse_charge_account"
  ],
  "fields": [
@@ -64,12 +65,18 @@
    "fieldtype": "Check",
    "in_list_view": 1,
    "label": "Is Reverse Charge Account"
+  },
+  {
+   "fieldname": "utgst_account",
+   "fieldtype": "Link",
+   "label": "UTGST Account",
+   "options": "Account"
   }
  ],
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-04-09 12:30:25.889993",
+ "modified": "2022-04-07 12:59:14.039768",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "GST Account",
@@ -78,5 +85,6 @@
  "quick_entry": 1,
  "sort_field": "modified",
  "sort_order": "DESC",
+ "states": [],
  "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index bdde3a1..bd4b59b 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -330,7 +330,6 @@
 		doc = frappe.get_doc(target)
 		doc.is_return = 1
 		doc.return_against = source.name
-		doc.ignore_pricing_rule = 1
 		doc.set_warehouse = ""
 		if doctype == "Sales Invoice" or doctype == "POS Invoice":
 			doc.is_pos = source.is_pos
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index a3bf78b..6e5ffed 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -364,3 +364,4 @@
 erpnext.patches.v13_0.set_return_against_in_pos_invoice_references
 erpnext.patches.v13_0.remove_unknown_links_to_prod_plan_items # 24-03-2022
 erpnext.patches.v13_0.update_expense_claim_status_for_paid_advances
+erpnext.patches.v13_0.create_gst_custom_fields_in_quotation
\ No newline at end of file
diff --git a/erpnext/patches/v13_0/create_gst_custom_fields_in_quotation.py b/erpnext/patches/v13_0/create_gst_custom_fields_in_quotation.py
new file mode 100644
index 0000000..3217eab
--- /dev/null
+++ b/erpnext/patches/v13_0/create_gst_custom_fields_in_quotation.py
@@ -0,0 +1,53 @@
+import frappe
+from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
+
+
+def execute():
+	company = frappe.get_all("Company", filters={"country": "India"}, fields=["name"])
+	if not company:
+		return
+
+	sales_invoice_gst_fields = [
+		dict(
+			fieldname="billing_address_gstin",
+			label="Billing Address GSTIN",
+			fieldtype="Data",
+			insert_after="customer_address",
+			read_only=1,
+			fetch_from="customer_address.gstin",
+			print_hide=1,
+			length=15,
+		),
+		dict(
+			fieldname="customer_gstin",
+			label="Customer GSTIN",
+			fieldtype="Data",
+			insert_after="shipping_address_name",
+			fetch_from="shipping_address_name.gstin",
+			print_hide=1,
+			length=15,
+		),
+		dict(
+			fieldname="place_of_supply",
+			label="Place of Supply",
+			fieldtype="Data",
+			insert_after="customer_gstin",
+			print_hide=1,
+			read_only=1,
+			length=50,
+		),
+		dict(
+			fieldname="company_gstin",
+			label="Company GSTIN",
+			fieldtype="Data",
+			insert_after="company_address",
+			fetch_from="company_address.gstin",
+			print_hide=1,
+			read_only=1,
+			length=15,
+		),
+	]
+
+	custom_fields = {"Quotation": sales_invoice_gst_fields}
+
+	create_custom_fields(custom_fields, update=True)
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index 7031fcb..29f1ce4 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -326,21 +326,39 @@
 def get_project_list(
 	doctype, txt, filters, limit_start, limit_page_length=20, order_by="modified"
 ):
-	return frappe.db.sql(
-		"""select distinct project.*
-		from tabProject project, `tabProject User` project_user
-		where
-			(project_user.user = %(user)s
-			and project_user.parent = project.name)
-			or project.owner = %(user)s
-			order by project.modified desc
-			limit {0}, {1}
-		""".format(
-			limit_start, limit_page_length
-		),
-		{"user": frappe.session.user},
-		as_dict=True,
-		update={"doctype": "Project"},
+	meta = frappe.get_meta(doctype)
+	if not filters:
+		filters = []
+
+	fields = "distinct *"
+
+	or_filters = []
+
+	if txt:
+		if meta.search_fields:
+			for f in meta.get_search_fields():
+				if f == "name" or meta.get_field(f).fieldtype in (
+					"Data",
+					"Text",
+					"Small Text",
+					"Text Editor",
+					"select",
+				):
+					or_filters.append([doctype, f, "like", "%" + txt + "%"])
+		else:
+			if isinstance(filters, dict):
+				filters["name"] = ("like", "%" + txt + "%")
+			else:
+				filters.append([doctype, "name", "like", "%" + txt + "%"])
+
+	return frappe.get_list(
+		doctype,
+		fields=fields,
+		filters=filters,
+		or_filters=or_filters,
+		limit_start=limit_start,
+		limit_page_length=limit_page_length,
+		order_by=order_by,
 	)
 
 
diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py
index 8fd9c1c..f317569 100644
--- a/erpnext/regional/india/e_invoice/utils.py
+++ b/erpnext/regional/india/e_invoice/utils.py
@@ -314,10 +314,14 @@
 					item.cess_rate += item_tax_rate
 					item.cess_amount += abs(item_tax_amount_after_discount)
 
-			for tax_type in ["igst", "cgst", "sgst"]:
+			for tax_type in ["igst", "cgst", "sgst", "utgst"]:
 				if t.account_head in gst_accounts[f"{tax_type}_account"]:
 					item.tax_rate += item_tax_rate
-					item[f"{tax_type}_amount"] += abs(item_tax_amount)
+					if tax_type == "utgst":
+						# utgst taxes are reported same as sgst tax
+						item["sgst_amount"] += abs(item_tax_amount)
+					else:
+						item[f"{tax_type}_amount"] += abs(item_tax_amount)
 		else:
 			# TODO: other charges per item
 			pass
@@ -359,11 +363,15 @@
 				# using after discount amt since item also uses after discount amt for cess calc
 				invoice_value_details.total_cess_amt += abs(t.base_tax_amount_after_discount_amount)
 
-			for tax_type in ["igst", "cgst", "sgst"]:
+			for tax_type in ["igst", "cgst", "sgst", "utgst"]:
 				if t.account_head in gst_accounts[f"{tax_type}_account"]:
+					if tax_type == "utgst":
+						invoice_value_details["total_sgst_amt"] += abs(tax_amount)
+					else:
+						invoice_value_details[f"total_{tax_type}_amt"] += abs(tax_amount)
 
-					invoice_value_details[f"total_{tax_type}_amt"] += abs(tax_amount)
 				update_other_charges(t, invoice_value_details, gst_accounts_list, invoice, considered_rows)
+
 		else:
 			invoice_value_details.total_other_charges += abs(tax_amount)
 
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index 40fa6cd..446faaa 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -930,6 +930,7 @@
 		"Journal Entry": journal_entry_fields,
 		"Sales Order": sales_invoice_gst_fields,
 		"Tax Category": inter_state_gst_field,
+		"Quotation": sales_invoice_gst_fields,
 		"Item": [
 			dict(
 				fieldname="gst_hsn_code",
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index 249c1b7..0b6fcc6 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -225,7 +225,7 @@
 	if not frappe.get_meta("Address").has_field("gst_state"):
 		return
 
-	if doctype in ("Sales Invoice", "Delivery Note", "Sales Order"):
+	if doctype in ("Sales Invoice", "Delivery Note", "Sales Order", "Quotation"):
 		address_name = party_details.customer_address or party_details.shipping_address_name
 	elif doctype in ("Purchase Invoice", "Purchase Order", "Purchase Receipt"):
 		address_name = party_details.shipping_address or party_details.supplier_address
@@ -254,7 +254,7 @@
 		party_details.taxes = []
 		return party_details
 
-	if doctype in ("Sales Invoice", "Delivery Note", "Sales Order"):
+	if doctype in ("Sales Invoice", "Delivery Note", "Sales Order", "Quotation"):
 		master_doctype = "Sales Taxes and Charges Template"
 		tax_template_by_category = get_tax_template_based_on_category(
 			master_doctype, company, party_details
@@ -311,7 +311,7 @@
 
 
 def is_internal_transfer(party_details, doctype):
-	if doctype in ("Sales Invoice", "Delivery Note", "Sales Order"):
+	if doctype in ("Sales Invoice", "Delivery Note", "Sales Order", "Quotation"):
 		destination_gstin = party_details.company_gstin
 	elif doctype in ("Purchase Invoice", "Purchase Order", "Purchase Receipt"):
 		destination_gstin = party_details.supplier_gstin
@@ -824,7 +824,7 @@
 	gst_settings_accounts = frappe.get_all(
 		"GST Account",
 		filters=filters,
-		fields=["cgst_account", "sgst_account", "igst_account", "cess_account"],
+		fields=["cgst_account", "sgst_account", "igst_account", "cess_account", "utgst_account"],
 	)
 
 	if not gst_settings_accounts and not frappe.flags.in_test and not frappe.flags.in_migrate:
diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json
index 0318b70..75443ab 100644
--- a/erpnext/selling/doctype/quotation/quotation.json
+++ b/erpnext/selling/doctype/quotation/quotation.json
@@ -31,6 +31,8 @@
   "col_break98",
   "shipping_address_name",
   "shipping_address",
+  "company_address",
+  "company_address_display",
   "customer_group",
   "territory",
   "currency_and_price_list",
@@ -955,7 +957,18 @@
    "fieldname": "competitors",
    "fieldtype": "Table MultiSelect",
    "label": "Competitors",
-   "options": "Competitor Detail",
+   "options": "Competitor Detail"
+  },
+  {
+   "fieldname": "company_address",
+   "fieldtype": "Link",
+   "label": "Company Address Name",
+   "options": "Address"
+  },
+  {
+   "fieldname": "company_address_display",
+   "fieldtype": "Small Text",
+   "label": "Company Address",
    "read_only": 1
   },
   {
diff --git a/erpnext/selling/doctype/quotation/regional/india.js b/erpnext/selling/doctype/quotation/regional/india.js
new file mode 100644
index 0000000..9550835
--- /dev/null
+++ b/erpnext/selling/doctype/quotation/regional/india.js
@@ -0,0 +1,3 @@
+{% include "erpnext/regional/india/taxes.js" %}
+
+erpnext.setup_auto_gst_taxation('Quotation');
diff --git a/erpnext/stock/doctype/pick_list/test_pick_list.py b/erpnext/stock/doctype/pick_list/test_pick_list.py
index ec5011b..27b06d2 100644
--- a/erpnext/stock/doctype/pick_list/test_pick_list.py
+++ b/erpnext/stock/doctype/pick_list/test_pick_list.py
@@ -8,7 +8,7 @@
 
 from frappe.tests.utils import FrappeTestCase
 
-from erpnext.stock.doctype.item.test_item import create_item
+from erpnext.stock.doctype.item.test_item import create_item, make_item
 from erpnext.stock.doctype.pick_list.pick_list import create_delivery_note
 from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
 from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import (
@@ -18,6 +18,7 @@
 
 class TestPickList(FrappeTestCase):
 	def test_pick_list_picks_warehouse_for_each_item(self):
+		item_code = make_item().name
 		try:
 			frappe.get_doc(
 				{
@@ -27,7 +28,7 @@
 					"expense_account": "Temporary Opening - _TC",
 					"items": [
 						{
-							"item_code": "_Test Item",
+							"item_code": item_code,
 							"warehouse": "_Test Warehouse - _TC",
 							"valuation_rate": 100,
 							"qty": 5,
@@ -47,7 +48,7 @@
 				"purpose": "Delivery",
 				"locations": [
 					{
-						"item_code": "_Test Item",
+						"item_code": item_code,
 						"qty": 5,
 						"stock_qty": 5,
 						"conversion_factor": 1,
@@ -59,7 +60,7 @@
 		)
 		pick_list.set_item_locations()
 
-		self.assertEqual(pick_list.locations[0].item_code, "_Test Item")
+		self.assertEqual(pick_list.locations[0].item_code, item_code)
 		self.assertEqual(pick_list.locations[0].warehouse, "_Test Warehouse - _TC")
 		self.assertEqual(pick_list.locations[0].qty, 5)
 
@@ -270,6 +271,8 @@
 		pr2.cancel()
 
 	def test_pick_list_for_items_from_multiple_sales_orders(self):
+
+		item_code = make_item().name
 		try:
 			frappe.get_doc(
 				{
@@ -279,7 +282,7 @@
 					"expense_account": "Temporary Opening - _TC",
 					"items": [
 						{
-							"item_code": "_Test Item",
+							"item_code": item_code,
 							"warehouse": "_Test Warehouse - _TC",
 							"valuation_rate": 100,
 							"qty": 10,
@@ -295,7 +298,14 @@
 				"doctype": "Sales Order",
 				"customer": "_Test Customer",
 				"company": "_Test Company",
-				"items": [{"item_code": "_Test Item", "qty": 10, "delivery_date": frappe.utils.today()}],
+				"items": [
+					{
+						"item_code": item_code,
+						"qty": 10,
+						"delivery_date": frappe.utils.today(),
+						"warehouse": "_Test Warehouse - _TC",
+					}
+				],
 			}
 		)
 		sales_order.submit()
@@ -309,7 +319,7 @@
 				"purpose": "Delivery",
 				"locations": [
 					{
-						"item_code": "_Test Item",
+						"item_code": item_code,
 						"qty": 5,
 						"stock_qty": 5,
 						"conversion_factor": 1,
@@ -317,7 +327,7 @@
 						"sales_order_item": "_T-Sales Order-1_item",
 					},
 					{
-						"item_code": "_Test Item",
+						"item_code": item_code,
 						"qty": 5,
 						"stock_qty": 5,
 						"conversion_factor": 1,
@@ -329,18 +339,19 @@
 		)
 		pick_list.set_item_locations()
 
-		self.assertEqual(pick_list.locations[0].item_code, "_Test Item")
+		self.assertEqual(pick_list.locations[0].item_code, item_code)
 		self.assertEqual(pick_list.locations[0].warehouse, "_Test Warehouse - _TC")
 		self.assertEqual(pick_list.locations[0].qty, 5)
 		self.assertEqual(pick_list.locations[0].sales_order_item, "_T-Sales Order-1_item")
 
-		self.assertEqual(pick_list.locations[1].item_code, "_Test Item")
+		self.assertEqual(pick_list.locations[1].item_code, item_code)
 		self.assertEqual(pick_list.locations[1].warehouse, "_Test Warehouse - _TC")
 		self.assertEqual(pick_list.locations[1].qty, 5)
 		self.assertEqual(pick_list.locations[1].sales_order_item, sales_order.items[0].name)
 
 	def test_pick_list_for_items_with_multiple_UOM(self):
-		purchase_receipt = make_purchase_receipt(item_code="_Test Item", qty=10)
+		item_code = make_item().name
+		purchase_receipt = make_purchase_receipt(item_code=item_code, qty=10)
 		purchase_receipt.submit()
 
 		sales_order = frappe.get_doc(
@@ -350,17 +361,19 @@
 				"company": "_Test Company",
 				"items": [
 					{
-						"item_code": "_Test Item",
+						"item_code": item_code,
 						"qty": 1,
 						"conversion_factor": 5,
 						"stock_qty": 5,
 						"delivery_date": frappe.utils.today(),
+						"warehouse": "_Test Warehouse - _TC",
 					},
 					{
-						"item_code": "_Test Item",
+						"item_code": item_code,
 						"qty": 1,
 						"conversion_factor": 1,
 						"delivery_date": frappe.utils.today(),
+						"warehouse": "_Test Warehouse - _TC",
 					},
 				],
 			}
@@ -376,7 +389,7 @@
 				"purpose": "Delivery",
 				"locations": [
 					{
-						"item_code": "_Test Item",
+						"item_code": item_code,
 						"qty": 2,
 						"stock_qty": 1,
 						"conversion_factor": 0.5,
@@ -384,7 +397,7 @@
 						"sales_order_item": sales_order.items[0].name,
 					},
 					{
-						"item_code": "_Test Item",
+						"item_code": item_code,
 						"qty": 1,
 						"stock_qty": 1,
 						"conversion_factor": 1,