Merge pull request #34563 from KerollesFathy/ft/add-apply-module-export-filter-on-export-customization
feat: Add Apply Module Export Filter on Export Customization Dialog
This commit is contained in:
commit
f09dc7cc07
3 changed files with 83 additions and 4 deletions
|
|
@ -265,6 +265,15 @@ frappe.ui.form.on("Customize Form", {
|
|||
),
|
||||
default: 0,
|
||||
},
|
||||
{
|
||||
fieldtype: "Check",
|
||||
fieldname: "apply_module_export_filter",
|
||||
label: __("Apply Module Export Filter"),
|
||||
description: __(
|
||||
"Export only customizations assigned to the selected module.<br><span class='text-muted'><strong>Note:</strong> You must set the <em>Module (for export)</em> field on Custom Field and Property Setter records before applying this filter.</span><p class='alert alert-warning'> <strong>Warning:</strong> Customizations from other modules will be excluded.</p>"
|
||||
),
|
||||
default: 0,
|
||||
},
|
||||
],
|
||||
function (data) {
|
||||
frappe.call({
|
||||
|
|
@ -274,6 +283,7 @@ frappe.ui.form.on("Customize Form", {
|
|||
module: data.module,
|
||||
sync_on_migrate: data.sync_on_migrate,
|
||||
with_permissions: data.with_permissions,
|
||||
apply_module_export_filter: data.apply_module_export_filter,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -56,21 +56,41 @@ def get_doc_module(module: str, doctype: str, name: str) -> "ModuleType":
|
|||
|
||||
@frappe.whitelist()
|
||||
def export_customizations(
|
||||
module: str, doctype: str, sync_on_migrate: bool = False, with_permissions: bool = False
|
||||
module: str,
|
||||
doctype: str,
|
||||
sync_on_migrate: bool = False,
|
||||
with_permissions: bool = False,
|
||||
apply_module_export_filter: bool = False,
|
||||
):
|
||||
"""Export Custom Field and Property Setter for the current document to the app folder.
|
||||
This will be synced with bench migrate"""
|
||||
|
||||
sync_on_migrate = cint(sync_on_migrate)
|
||||
with_permissions = cint(with_permissions)
|
||||
apply_module_export_filter = cint(apply_module_export_filter)
|
||||
|
||||
cf_filters = {"dt": doctype}
|
||||
ps_filters = {"doc_type": doctype}
|
||||
|
||||
if apply_module_export_filter:
|
||||
cf_filters["module"] = module
|
||||
ps_filters["module"] = module
|
||||
|
||||
if not frappe.conf.developer_mode:
|
||||
frappe.throw(_("Only allowed to export customizations in developer mode"))
|
||||
|
||||
custom = {
|
||||
"custom_fields": frappe.get_all("Custom Field", fields="*", filters={"dt": doctype}, order_by="name"),
|
||||
"custom_fields": frappe.get_all(
|
||||
"Custom Field",
|
||||
fields="*",
|
||||
filters=cf_filters,
|
||||
order_by="name",
|
||||
),
|
||||
"property_setters": frappe.get_all(
|
||||
"Property Setter", fields="*", filters={"doc_type": doctype}, order_by="name"
|
||||
"Property Setter",
|
||||
fields="*",
|
||||
filters=ps_filters,
|
||||
order_by="name",
|
||||
),
|
||||
"custom_perms": [],
|
||||
"links": frappe.get_all("DocType Link", fields="*", filters={"parent": doctype}, order_by="name"),
|
||||
|
|
@ -85,7 +105,9 @@ def export_customizations(
|
|||
|
||||
# also update the custom fields and property setters for all child tables
|
||||
for d in frappe.get_meta(doctype).get_table_fields():
|
||||
export_customizations(module, d.options, sync_on_migrate, with_permissions)
|
||||
export_customizations(
|
||||
module, d.options, sync_on_migrate, with_permissions, apply_module_export_filter
|
||||
)
|
||||
|
||||
if custom["custom_fields"] or custom["property_setters"] or custom["custom_perms"]:
|
||||
folder_path = os.path.join(get_module_path(module), "custom")
|
||||
|
|
|
|||
|
|
@ -84,6 +84,53 @@ class TestUtils(IntegrationTestCase):
|
|||
self.assertTrue(file_path.endswith("/custom/custom/note.json"))
|
||||
self.assertTrue(os.path.exists(file_path))
|
||||
|
||||
@unittest.skipUnless(
|
||||
os.access(frappe.get_app_path("frappe"), os.W_OK), "Only run if frappe app paths is writable"
|
||||
)
|
||||
def test_export_customizations_with_module_filter(self):
|
||||
# create two customizations, one matching the module, one under a different module
|
||||
with note_customizations() as (custom_field, property_setter):
|
||||
custom_field.db_set("module", "Custom")
|
||||
property_setter.db_set("module", "Custom")
|
||||
|
||||
# create module def called OtherModule
|
||||
other_module = frappe.new_doc("Module Def")
|
||||
|
||||
other_module.update({"module_name": "OtherModule", "app_name": "frappe"})
|
||||
other_module.save(ignore_permissions=True)
|
||||
self.addCleanup(other_module.delete)
|
||||
|
||||
# create a customization belonging to another module (should be excluded)
|
||||
other_cf = create_custom_field(
|
||||
"Note",
|
||||
df={
|
||||
"fieldname": "other_mod_field",
|
||||
"label": "Other Mod Field",
|
||||
"fieldtype": "Data",
|
||||
"module": "OtherModule",
|
||||
},
|
||||
)
|
||||
|
||||
self.addCleanup(other_cf.delete)
|
||||
|
||||
file_path = export_customizations(
|
||||
module="Custom",
|
||||
doctype="Note",
|
||||
apply_module_export_filter=True,
|
||||
)
|
||||
self.addCleanup(delete_file, path=file_path)
|
||||
|
||||
self.assertTrue(os.path.exists(file_path))
|
||||
|
||||
with open(file_path) as f:
|
||||
exported = frappe.parse_json(f.read())
|
||||
|
||||
exported_fields = {f["fieldname"] for f in exported.get("custom_fields", [])}
|
||||
|
||||
self.assertIn("test_export_customizations_field", exported_fields)
|
||||
|
||||
self.assertNotIn("other_mod_field", exported_fields)
|
||||
|
||||
@unittest.skipUnless(
|
||||
os.access(frappe.get_app_path("frappe"), os.W_OK), "Only run if frappe app paths is writable"
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue