feat(Transaction Deletion Record): Editable "DocTypes To Delete" List with CSV import/export (#50592)

* feat: add editable DocTypes To Delete list with import/export

Add user control over transaction deletion with reviewable and reusable deletion templates.

- New "DocTypes To Delete" table allows users to review and customize what will be deleted before submission
- Import/Export CSV templates for reusability across environments
- Company field rule: only filter by company if field is specifically named "company", otherwise delete all records
- Child tables (istable=1) automatically excluded from selection
- "Remove Zero Counts" helper button to clean up list
- Backward compatible with existing deletion records

* refactor: improve Transaction Deletion Record code quality

- Remove unnecessary chatty comments from AI-generated code
- Add concise docstrings to all new methods
- Remove redundant @frappe.whitelist() decorators from internal methods
- Improve CSV import validation (header check, child table filtering)
- Add better error feedback with consolidated skip messages
- Reorder form fields: To Delete list now appears before Excluded list
- Add conditional visibility for Summary table (legacy records only)
- Improve architectural clarity: single API entry point per feature

Technical improvements:
- export_to_delete_template_method and import_to_delete_template_method
  are now internal helpers without whitelist decorators
- CSV import now validates format and provides detailed skip reasons
- Summary table only shows for submitted records without To Delete list
- Maintains backward compatibility for existing deletion records

* fix: field order

* test: fix broken tests and add new ones

* fix: adapt create_transaction_deletion_request

* test: fix assertRaises trigger

* fix: conditionally execute Transaction Deletion pre-tasks based on selected DocTypes

* refactor: replace boolean task flags with status fields

* fix: remove UI comment

* fix: don't allow virtual doctype selection and improve protected Doctype List

* fix: replace outdated frappe.db.sql by frappe.qb

* feat: add support for multiple company fields

* fix: autofill comapny field, add docstrings, filter for company_field

* fix: add edge case handling for update_naming_series and add tests for prefix extraction

* fix: use redis for running deletion validation, check per doctype instead of company

(cherry picked from commit 0fb37ad792)

# Conflicts:
#	erpnext/patches.txt
This commit is contained in:
Henning Wendtland
2026-01-25 09:50:28 +01:00
committed by Mergify
parent 81e65757ee
commit 4963261dc8
14 changed files with 1787 additions and 150 deletions

View File

@@ -0,0 +1,42 @@
import frappe
def execute():
"""
Migrate Transaction Deletion Record boolean task flags to status Select fields.
Renames fields from old names to new names with _status suffix.
Maps: 0 -> "Pending", 1 -> "Completed"
"""
if not frappe.db.table_exists("tabTransaction Deletion Record"):
return
# Field mapping: old boolean field name -> new status field name
field_mapping = {
"delete_bin_data": "delete_bin_data_status",
"delete_leads_and_addresses": "delete_leads_and_addresses_status",
"reset_company_default_values": "reset_company_default_values_status",
"clear_notifications": "clear_notifications_status",
"initialize_doctypes_table": "initialize_doctypes_table_status",
"delete_transactions": "delete_transactions_status",
}
# Get all Transaction Deletion Records
records = frappe.db.get_all("Transaction Deletion Record", pluck="name")
for name in records or []:
updates = {}
for old_field, new_field in field_mapping.items():
# Read from old boolean field
current_value = frappe.db.get_value("Transaction Deletion Record", name, old_field)
# Map to new status and write to new field name
if current_value in (1, "1", True):
updates[new_field] = "Completed"
else:
# Handle 0, "0", False, None, empty string
updates[new_field] = "Pending"
# Update all fields at once
if updates:
frappe.db.set_value("Transaction Deletion Record", name, updates, update_modified=False)