fix: remove portal menu items in pre-model sync patch
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 73e0a95..76e4dee 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -262,6 +262,7 @@
 erpnext.patches.v15_0.saudi_depreciation_warning
 erpnext.patches.v15_0.delete_saudi_doctypes
 erpnext.patches.v14_0.show_loan_management_deprecation_warning
+erpnext.patches.v14_0.delete_education_module_portal_menu_items
 
 [post_model_sync]
 execute:frappe.delete_doc_if_exists('Workspace', 'ERPNext Integrations Settings')
diff --git a/erpnext/patches/v14_0/delete_education_module_portal_menu_items.py b/erpnext/patches/v14_0/delete_education_module_portal_menu_items.py
new file mode 100644
index 0000000..d964f14
--- /dev/null
+++ b/erpnext/patches/v14_0/delete_education_module_portal_menu_items.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
+# License: MIT. See LICENSE
+
+import frappe
+
+
+def execute():
+	doctypes = frappe.get_all("DocType", {"module": "education", "custom": 0}, pluck="name")
+	items = frappe.get_all(
+		"Portal Menu Item", filters={"reference_doctype": ("in", doctypes)}, pluck="name"
+	)
+	for item in items:
+		frappe.delete_doc("Portal Menu Item", item, ignore_missing=True, force=True)