Merge pull request #30726 from ankush/dependent_gle_reposting

fix: dependent gle reposting
diff --git a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.js b/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.js
index 6302d26..69b9cfa 100644
--- a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.js
+++ b/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.js
@@ -24,17 +24,16 @@
 			);
 		}
 
-		frappe.model.with_doctype("Item", () => {
+		frappe.model.with_doctype("Website Item", () => {
 			const web_item_meta = frappe.get_meta('Website Item');
 
-			const valid_fields = web_item_meta.fields.filter(
-				df => ["Link", "Table MultiSelect"].includes(df.fieldtype) && !df.hidden
-			).map(df => ({ label: df.label, value: df.fieldname }));
-
-			frm.fields_dict.filter_fields.grid.update_docfield_property(
-				'fieldname', 'fieldtype', 'Select'
+			const valid_fields = web_item_meta.fields.filter(df =>
+				["Link", "Table MultiSelect"].includes(df.fieldtype) && !df.hidden
+			).map(df =>
+				({ label: df.label, value: df.fieldname })
 			);
-			frm.fields_dict.filter_fields.grid.update_docfield_property(
+
+			frm.get_field("filter_fields").grid.update_docfield_property(
 				'fieldname', 'options', valid_fields
 			);
 		});
diff --git a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.py b/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.py
index f85667e..c27d29a 100644
--- a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.py
+++ b/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.py
@@ -27,7 +27,7 @@
 		self.is_redisearch_loaded = is_search_module_loaded()
 
 	def validate(self):
-		self.validate_field_filters()
+		self.validate_field_filters(self.filter_fields, self.enable_field_filters)
 		self.validate_attribute_filters()
 		self.validate_checkout()
 		self.validate_search_index_fields()
@@ -51,21 +51,22 @@
 			define_autocomplete_dictionary()
 			create_website_items_index()
 
-	def validate_field_filters(self):
-		if not (self.enable_field_filters and self.filter_fields):
+	@staticmethod
+	def validate_field_filters(filter_fields, enable_field_filters):
+		if not (enable_field_filters and filter_fields):
 			return
 
-		item_meta = frappe.get_meta("Item")
+		web_item_meta = frappe.get_meta("Website Item")
 		valid_fields = [
-			df.fieldname for df in item_meta.fields if df.fieldtype in ["Link", "Table MultiSelect"]
+			df.fieldname for df in web_item_meta.fields if df.fieldtype in ["Link", "Table MultiSelect"]
 		]
 
-		for f in self.filter_fields:
-			if f.fieldname not in valid_fields:
+		for row in filter_fields:
+			if row.fieldname not in valid_fields:
 				frappe.throw(
 					_(
-						"Filter Fields Row #{0}: Fieldname <b>{1}</b> must be of type 'Link' or 'Table MultiSelect'"
-					).format(f.idx, f.fieldname)
+						"Filter Fields Row #{0}: Fieldname {1} must be of type 'Link' or 'Table MultiSelect'"
+					).format(row.idx, frappe.bold(row.fieldname))
 				)
 
 	def validate_attribute_filters(self):
diff --git a/erpnext/e_commerce/doctype/e_commerce_settings/test_e_commerce_settings.py b/erpnext/e_commerce/doctype/e_commerce_settings/test_e_commerce_settings.py
index c4c958b..662db4d 100644
--- a/erpnext/e_commerce/doctype/e_commerce_settings/test_e_commerce_settings.py
+++ b/erpnext/e_commerce/doctype/e_commerce_settings/test_e_commerce_settings.py
@@ -1,5 +1,4 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
+# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
 # See license.txt
 import unittest
 
@@ -11,44 +10,35 @@
 
 
 class TestECommerceSettings(unittest.TestCase):
-	def setUp(self):
-		frappe.db.sql("""delete from `tabSingles` where doctype="Shipping Cart Settings" """)
-
-	def get_cart_settings(self):
-		return frappe.get_doc({"doctype": "E Commerce Settings", "company": "_Test Company"})
-
-	# NOTE: Exchangrate API has all enabled currencies that ERPNext supports.
-	# We aren't checking just currency exchange record anymore
-	# while validating price list currency exchange rate to that of company.
-	# The API is being used to fetch the rate which again almost always
-	# gives back a valid value (for valid currencies).
-	# This makes the test obsolete.
-	# Commenting because im not sure if there's a better test we can write
-
-	# def test_exchange_rate_exists(self):
-	# 	frappe.db.sql("""delete from `tabCurrency Exchange`""")
-
-	# 	cart_settings = self.get_cart_settings()
-	# 	cart_settings.price_list = "_Test Price List Rest of the World"
-	# 	self.assertRaises(ShoppingCartSetupError, cart_settings.validate_exchange_rates_exist)
-
-	# 	from erpnext.setup.doctype.currency_exchange.test_currency_exchange import (
-	# 		test_records as currency_exchange_records,
-	# 	)
-	# 	frappe.get_doc(currency_exchange_records[0]).insert()
-	# 	cart_settings.validate_exchange_rates_exist()
+	def tearDown(self):
+		frappe.db.rollback()
 
 	def test_tax_rule_validation(self):
 		frappe.db.sql("update `tabTax Rule` set use_for_shopping_cart = 0")
 		frappe.db.commit()  # nosemgrep
 
-		cart_settings = self.get_cart_settings()
+		cart_settings = frappe.get_doc("E Commerce Settings")
 		cart_settings.enabled = 1
 		if not frappe.db.get_value("Tax Rule", {"use_for_shopping_cart": 1}, "name"):
 			self.assertRaises(ShoppingCartSetupError, cart_settings.validate_tax_rule)
 
 		frappe.db.sql("update `tabTax Rule` set use_for_shopping_cart = 1")
 
+	def test_invalid_filter_fields(self):
+		"Check if Item fields are blocked in E Commerce Settings filter fields."
+		from frappe.custom.doctype.custom_field.custom_field import create_custom_field
+
+		setup_e_commerce_settings({"enable_field_filters": 1})
+
+		create_custom_field(
+			"Item",
+			dict(owner="Administrator", fieldname="test_data", label="Test", fieldtype="Data"),
+		)
+		settings = frappe.get_doc("E Commerce Settings")
+		settings.append("filter_fields", {"fieldname": "test_data"})
+
+		self.assertRaises(frappe.ValidationError, settings.save)
+
 
 def setup_e_commerce_settings(values_dict):
 	"Accepts a dict of values that updates E Commerce Settings."
diff --git a/erpnext/e_commerce/product_data_engine/filters.py b/erpnext/e_commerce/product_data_engine/filters.py
index feb89c1..e5e5e97 100644
--- a/erpnext/e_commerce/product_data_engine/filters.py
+++ b/erpnext/e_commerce/product_data_engine/filters.py
@@ -22,12 +22,14 @@
 		fields, filter_data = [], []
 		filter_fields = [row.fieldname for row in self.doc.filter_fields]  # fields in settings
 
-		# filter valid field filters i.e. those that exist in Item
-		item_meta = frappe.get_meta("Item", cached=True)
-		fields = [item_meta.get_field(field) for field in filter_fields if item_meta.has_field(field)]
+		# filter valid field filters i.e. those that exist in Website Item
+		web_item_meta = frappe.get_meta("Website Item", cached=True)
+		fields = [
+			web_item_meta.get_field(field) for field in filter_fields if web_item_meta.has_field(field)
+		]
 
 		for df in fields:
-			item_filters, item_or_filters = {"published_in_website": 1}, []
+			item_filters, item_or_filters = {"published": 1}, []
 			link_doctype_values = self.get_filtered_link_doctype_records(df)
 
 			if df.fieldtype == "Link":
@@ -50,9 +52,13 @@
 							]
 						)
 
+				# exclude variants if mentioned in settings
+				if frappe.db.get_single_value("E Commerce Settings", "hide_variants"):
+					item_filters["variant_of"] = ["is", "not set"]
+
 				# Get link field values attached to published items
 				item_values = frappe.get_all(
-					"Item",
+					"Website Item",
 					fields=[df.fieldname],
 					filters=item_filters,
 					or_filters=item_or_filters,
diff --git a/erpnext/e_commerce/product_data_engine/test_product_data_engine.py b/erpnext/e_commerce/product_data_engine/test_product_data_engine.py
index ab958d1..c3b6ed5 100644
--- a/erpnext/e_commerce/product_data_engine/test_product_data_engine.py
+++ b/erpnext/e_commerce/product_data_engine/test_product_data_engine.py
@@ -277,6 +277,54 @@
 		# tear down
 		setup_e_commerce_settings({"enable_attribute_filters": 1, "hide_variants": 0})
 
+	def test_custom_field_as_filter(self):
+		"Test if custom field functions as filter correctly."
+		from frappe.custom.doctype.custom_field.custom_field import create_custom_field
+
+		create_custom_field(
+			"Website Item",
+			dict(
+				owner="Administrator",
+				fieldname="supplier",
+				label="Supplier",
+				fieldtype="Link",
+				options="Supplier",
+				insert_after="on_backorder",
+			),
+		)
+
+		frappe.db.set_value(
+			"Website Item", {"item_code": "Test 11I Laptop"}, "supplier", "_Test Supplier"
+		)
+		frappe.db.set_value(
+			"Website Item", {"item_code": "Test 12I Laptop"}, "supplier", "_Test Supplier 1"
+		)
+
+		settings = frappe.get_doc("E Commerce Settings")
+		settings.append("filter_fields", {"fieldname": "supplier"})
+		settings.save()
+
+		filter_engine = ProductFiltersBuilder()
+		field_filters = filter_engine.get_field_filters()
+		custom_filter = field_filters[1]
+		filter_values = custom_filter[1]
+
+		self.assertEqual(custom_filter[0].options, "Supplier")
+		self.assertEqual(len(filter_values), 2)
+		self.assertIn("_Test Supplier", filter_values)
+
+		# test if custom filter works in query
+		field_filters = {"supplier": "_Test Supplier 1"}
+		engine = ProductQuery()
+		result = engine.query(
+			attributes={}, fields=field_filters, search_term=None, start=0, item_group=None
+		)
+		items = result.get("items")
+
+		# check if only 'Raw Material' are fetched in the right order
+		self.assertEqual(len(items), 1)
+		self.assertEqual(items[0].get("item_code"), "Test 12I Laptop")
+
 
 def create_variant_web_item():
 	"Create Variant and Template Website Items."
diff --git a/erpnext/hr/doctype/shift_assignment/shift_assignment.py b/erpnext/hr/doctype/shift_assignment/shift_assignment.py
index cbf798e..51298de 100644
--- a/erpnext/hr/doctype/shift_assignment/shift_assignment.py
+++ b/erpnext/hr/doctype/shift_assignment/shift_assignment.py
@@ -121,7 +121,7 @@
 
 @frappe.whitelist()
 def get_events(start, end, filters=None):
-	events = []
+	from frappe.desk.calendar import get_event_conditions
 
 	employee = frappe.db.get_value(
 		"Employee", {"user_id": frappe.session.user}, ["name", "company"], as_dict=True
@@ -132,20 +132,22 @@
 		employee = ""
 		company = frappe.db.get_value("Global Defaults", None, "default_company")
 
-	from frappe.desk.reportview import get_filters_cond
-
-	conditions = get_filters_cond("Shift Assignment", filters, [])
-	add_assignments(events, start, end, conditions=conditions)
+	conditions = get_event_conditions("Shift Assignment", filters)
+	events = add_assignments(start, end, conditions=conditions)
 	return events
 
 
-def add_assignments(events, start, end, conditions=None):
+def add_assignments(start, end, conditions=None):
+	events = []
+
 	query = """select name, start_date, end_date, employee_name,
 		employee, docstatus, shift_type
 		from `tabShift Assignment` where
-		start_date >= %(start_date)s
-		or end_date <=  %(end_date)s
-		or (%(start_date)s between start_date and end_date and %(end_date)s between start_date and end_date)
+		(
+			start_date >= %(start_date)s
+			or end_date <=  %(end_date)s
+			or (%(start_date)s between start_date and end_date and %(end_date)s between start_date and end_date)
+		)
 		and docstatus = 1"""
 	if conditions:
 		query += conditions
diff --git a/erpnext/hr/doctype/shift_assignment/test_shift_assignment.py b/erpnext/hr/doctype/shift_assignment/test_shift_assignment.py
index 0fe9108..de82a24 100644
--- a/erpnext/hr/doctype/shift_assignment/test_shift_assignment.py
+++ b/erpnext/hr/doctype/shift_assignment/test_shift_assignment.py
@@ -8,7 +8,7 @@
 from frappe.utils import add_days, getdate, nowdate
 
 from erpnext.hr.doctype.employee.test_employee import make_employee
-from erpnext.hr.doctype.shift_assignment.shift_assignment import OverlappingShiftError
+from erpnext.hr.doctype.shift_assignment.shift_assignment import OverlappingShiftError, get_events
 from erpnext.hr.doctype.shift_type.test_shift_type import make_shift_assignment, setup_shift_type
 
 test_dependencies = ["Shift Type"]
@@ -154,3 +154,18 @@
 		shift_type = setup_shift_type(shift_type="Shift 2", start_time="13:00:00", end_time="15:00:00")
 		date = getdate()
 		make_shift_assignment(shift_type.name, employee, date)
+
+	def test_shift_assignment_calendar(self):
+		employee1 = make_employee("test_shift_assignment1@example.com", company="_Test Company")
+		employee2 = make_employee("test_shift_assignment2@example.com", company="_Test Company")
+
+		shift_type = setup_shift_type(shift_type="Shift 1", start_time="08:00:00", end_time="12:00:00")
+		date = getdate()
+		shift1 = make_shift_assignment(shift_type.name, employee1, date)
+		make_shift_assignment(shift_type.name, employee2, date)
+
+		events = get_events(
+			start=date, end=date, filters=[["Shift Assignment", "employee", "=", employee1, False]]
+		)
+		self.assertEqual(len(events), 1)
+		self.assertEqual(events[0]["name"], shift1.name)
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.js b/erpnext/manufacturing/doctype/job_card/job_card.js
index b2824e1..b6646b1 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.js
+++ b/erpnext/manufacturing/doctype/job_card/job_card.js
@@ -73,10 +73,22 @@
 		if (frm.doc.docstatus == 0 && !frm.is_new() &&
 			(frm.doc.for_quantity > frm.doc.total_completed_qty || !frm.doc.for_quantity)
 			&& (frm.doc.items || !frm.doc.items.length || frm.doc.for_quantity == frm.doc.transferred_qty)) {
-			frm.trigger("prepare_timer_buttons");
+
+			// if Job Card is link to Work Order, the job card must not be able to start if Work Order not "Started"
+			// and if stock mvt for WIP is required
+			if (frm.doc.work_order) {
+				frappe.db.get_value('Work Order', frm.doc.work_order, ['skip_transfer', 'status'], (result) => {
+					if (result.skip_transfer === 1 || result.status == 'In Process') {
+						frm.trigger("prepare_timer_buttons");
+					}
+				});
+			} else {
+				frm.trigger("prepare_timer_buttons");
+			}
 		}
 
 		frm.trigger("setup_quality_inspection");
+
 		if (frm.doc.work_order) {
 			frappe.db.get_value('Work Order', frm.doc.work_order,
 				'transfer_material_against').then((r) => {
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 63b6bb7..c290551 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -364,3 +364,4 @@
 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
+erpnext.patches.v13_0.copy_custom_field_filters_to_website_item
diff --git a/erpnext/patches/v13_0/copy_custom_field_filters_to_website_item.py b/erpnext/patches/v13_0/copy_custom_field_filters_to_website_item.py
new file mode 100644
index 0000000..e8d0b59
--- /dev/null
+++ b/erpnext/patches/v13_0/copy_custom_field_filters_to_website_item.py
@@ -0,0 +1,94 @@
+import frappe
+from frappe.custom.doctype.custom_field.custom_field import create_custom_field
+
+
+def execute():
+	"Add Field Filters, that are not standard fields in Website Item, as Custom Fields."
+
+	def move_table_multiselect_data(docfield):
+		"Copy child table data (Table Multiselect) from Item to Website Item for a docfield."
+		table_multiselect_data = get_table_multiselect_data(docfield)
+		field = docfield.fieldname
+
+		for row in table_multiselect_data:
+			# add copied multiselect data rows in Website Item
+			web_item = frappe.db.get_value("Website Item", {"item_code": row.parent})
+			web_item_doc = frappe.get_doc("Website Item", web_item)
+
+			child_doc = frappe.new_doc(docfield.options, web_item_doc, field)
+
+			for field in ["name", "creation", "modified", "idx"]:
+				row[field] = None
+
+			child_doc.update(row)
+
+			child_doc.parenttype = "Website Item"
+			child_doc.parent = web_item
+
+			child_doc.insert()
+
+	def get_table_multiselect_data(docfield):
+		child_table = frappe.qb.DocType(docfield.options)
+		item = frappe.qb.DocType("Item")
+
+		table_multiselect_data = (  # query table data for field
+			frappe.qb.from_(child_table)
+			.join(item)
+			.on(item.item_code == child_table.parent)
+			.select(child_table.star)
+			.where((child_table.parentfield == docfield.fieldname) & (item.published_in_website == 1))
+		).run(as_dict=True)
+
+		return table_multiselect_data
+
+	settings = frappe.get_doc("E Commerce Settings")
+
+	if not (settings.enable_field_filters or settings.filter_fields):
+		return
+
+	item_meta = frappe.get_meta("Item")
+	valid_item_fields = [
+		df.fieldname for df in item_meta.fields if df.fieldtype in ["Link", "Table MultiSelect"]
+	]
+
+	web_item_meta = frappe.get_meta("Website Item")
+	valid_web_item_fields = [
+		df.fieldname for df in web_item_meta.fields if df.fieldtype in ["Link", "Table MultiSelect"]
+	]
+
+	for row in settings.filter_fields:
+		# skip if illegal field
+		if row.fieldname not in valid_item_fields:
+			continue
+
+		# if Item field is not in Website Item, add it as a custom field
+		if row.fieldname not in valid_web_item_fields:
+			df = item_meta.get_field(row.fieldname)
+			create_custom_field(
+				"Website Item",
+				dict(
+					owner="Administrator",
+					fieldname=df.fieldname,
+					label=df.label,
+					fieldtype=df.fieldtype,
+					options=df.options,
+					description=df.description,
+					read_only=df.read_only,
+					no_copy=df.no_copy,
+					insert_after="on_backorder",
+				),
+			)
+
+			# map field values
+			if df.fieldtype == "Table MultiSelect":
+				move_table_multiselect_data(df)
+			else:
+				frappe.db.sql(  # nosemgrep
+					"""
+						UPDATE `tabWebsite Item` wi, `tabItem` i
+						SET wi.{0} = i.{0}
+						WHERE wi.item_code = i.item_code
+					""".format(
+						row.fieldname
+					)
+				)
diff --git a/erpnext/portal/doctype/website_filter_field/website_filter_field.json b/erpnext/portal/doctype/website_filter_field/website_filter_field.json
index 67c0d0a..45543a6 100644
--- a/erpnext/portal/doctype/website_filter_field/website_filter_field.json
+++ b/erpnext/portal/doctype/website_filter_field/website_filter_field.json
@@ -1,76 +1,31 @@
 {
- "allow_copy": 0, 
- "allow_events_in_timeline": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "beta": 0, 
- "creation": "2018-12-31 17:06:08.716134", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "creation": "2018-12-31 17:06:08.716134",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "fieldname"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "fieldname", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Fieldname", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
+   "fieldname": "fieldname",
+   "fieldtype": "Autocomplete",
+   "in_list_view": 1,
+   "label": "Fieldname"
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 1, 
- "max_attachments": 0, 
- "modified": "2019-01-01 18:26:11.550380", 
- "modified_by": "Administrator", 
- "module": "Portal", 
- "name": "Website Filter Field", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0, 
- "track_views": 0
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2022-04-18 18:55:17.835666",
+ "modified_by": "Administrator",
+ "module": "Portal",
+ "name": "Website Filter Field",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": [],
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py
index f317569..a97ad79 100644
--- a/erpnext/regional/india/e_invoice/utils.py
+++ b/erpnext/regional/india/e_invoice/utils.py
@@ -1074,7 +1074,7 @@
 				"Distance": cint(eway_bill_details.distance),
 				"TransMode": eway_bill_details.mode_of_transport,
 				"TransId": eway_bill_details.gstin,
-				"TransName": eway_bill_details.transporter,
+				"TransName": eway_bill_details.name,
 				"TrnDocDt": eway_bill_details.document_date,
 				"TrnDocNo": eway_bill_details.document_name,
 				"VehNo": eway_bill_details.vehicle_no,
diff --git a/erpnext/setup/doctype/item_group/item_group.js b/erpnext/setup/doctype/item_group/item_group.js
index f570c2f..4b04ac1 100644
--- a/erpnext/setup/doctype/item_group/item_group.js
+++ b/erpnext/setup/doctype/item_group/item_group.js
@@ -72,17 +72,16 @@
 			});
 		}
 
-		frappe.model.with_doctype('Item', () => {
-			const item_meta = frappe.get_meta('Item');
+		frappe.model.with_doctype('Website Item', () => {
+			const web_item_meta = frappe.get_meta('Website Item');
 
-			const valid_fields = item_meta.fields.filter(
-				df => ['Link', 'Table MultiSelect'].includes(df.fieldtype) && !df.hidden
-			).map(df => ({ label: df.label, value: df.fieldname }));
-
-			frm.fields_dict.filter_fields.grid.update_docfield_property(
-				'fieldname', 'fieldtype', 'Select'
+			const valid_fields = web_item_meta.fields.filter(df =>
+				['Link', 'Table MultiSelect'].includes(df.fieldtype) && !df.hidden
+			).map(df =>
+				({ label: df.label, value: df.fieldname })
 			);
-			frm.fields_dict.filter_fields.grid.update_docfield_property(
+
+			frm.get_field("filter_fields").grid.update_docfield_property(
 				'fieldname', 'options', valid_fields
 			);
 		});
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index 35557a5..6e940d0 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -11,6 +11,7 @@
 from frappe.website.utils import clear_cache
 from frappe.website.website_generator import WebsiteGenerator
 
+from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import ECommerceSettings
 from erpnext.e_commerce.product_data_engine.filters import ProductFiltersBuilder
 
 
@@ -35,6 +36,7 @@
 
 		self.make_route()
 		self.validate_item_group_defaults()
+		ECommerceSettings.validate_field_filters(self.filter_fields, enable_field_filters=True)
 
 	def on_update(self):
 		NestedSet.on_update(self)
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 316c897..7101190 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -777,11 +777,11 @@
 		exclude_sr_nos = get_serial_nos(clean_serial_no_string("\n".join(exclude_sr_nos)))
 
 	if batch_nos:
-		batch_nos = safe_json_loads(batch_nos)
-		if isinstance(batch_nos, list):
-			filters.batch_no = batch_nos
+		batch_nos_list = safe_json_loads(batch_nos)
+		if isinstance(batch_nos_list, list):
+			filters.batch_no = batch_nos_list
 		else:
-			filters.batch_no = [str(batch_nos)]
+			filters.batch_no = [batch_nos]
 
 	if posting_date:
 		filters.expiry_date = posting_date