diff --git a/erpnext/accounts/doctype/transaction_deletion_record_details/__init__.py b/erpnext/accounts/doctype/transaction_deletion_record_details/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/transaction_deletion_record_details/transaction_deletion_record_details.json b/erpnext/accounts/doctype/transaction_deletion_record_details/transaction_deletion_record_details.json new file mode 100644 index 00000000000..e8a5eb6c432 --- /dev/null +++ b/erpnext/accounts/doctype/transaction_deletion_record_details/transaction_deletion_record_details.json @@ -0,0 +1,59 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2024-02-04 10:53:32.307930", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "doctype_name", + "docfield_name", + "no_of_docs", + "done" + ], + "fields": [ + { + "fieldname": "doctype_name", + "fieldtype": "Link", + "in_list_view": 1, + "label": "DocType", + "options": "DocType", + "read_only": 1, + "reqd": 1 + }, + { + "fieldname": "docfield_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "DocField", + "read_only": 1 + }, + { + "fieldname": "no_of_docs", + "fieldtype": "Int", + "in_list_view": 1, + "label": "No of Docs", + "read_only": 1 + }, + { + "default": "0", + "fieldname": "done", + "fieldtype": "Check", + "in_list_view": 1, + "label": "Done", + "read_only": 1 + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2024-02-04 10:55:52.060417", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Transaction Deletion Record Details", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/transaction_deletion_record_details/transaction_deletion_record_details.py b/erpnext/accounts/doctype/transaction_deletion_record_details/transaction_deletion_record_details.py new file mode 100644 index 00000000000..bc5b5c41fdd --- /dev/null +++ b/erpnext/accounts/doctype/transaction_deletion_record_details/transaction_deletion_record_details.py @@ -0,0 +1,26 @@ +# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class TransactionDeletionRecordDetails(Document): + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + docfield_name: DF.Data | None + doctype_name: DF.Link + done: DF.Check + no_of_docs: DF.Int + parent: DF.Data + parentfield: DF.Data + parenttype: DF.Data + # end: auto-generated types + + pass diff --git a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.js b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.js index 1a8b52f46bd..c6bb3781bfc 100644 --- a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.js +++ b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.js @@ -41,6 +41,18 @@ frappe.ui.form.on("Transaction Deletion Record", { }); }); } + + if (frm.doc.docstatus==1 && ['Queued', 'Failed'].find(x => x == frm.doc.status)) { + let execute_btn = __("Start Chain of Events") + + frm.add_custom_button(execute_btn, () => { + frm.call({ + method: 'delete_bins', + doc: frm.doc + }); + }); + } + }, }); diff --git a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.json b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.json index dc35fe59553..bbc571a0816 100644 --- a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.json +++ b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.json @@ -34,7 +34,7 @@ "fieldname": "doctypes", "fieldtype": "Table", "label": "Summary", - "options": "Transaction Deletion Record Item", + "options": "Transaction Deletion Record Details", "read_only": 1 }, { @@ -123,7 +123,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2024-02-04 08:09:26.784109", + "modified": "2024-02-04 10:55:09.430373", "modified_by": "Administrator", "module": "Setup", "name": "Transaction Deletion Record", diff --git a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py index 9911d44fc3c..60976aa572b 100644 --- a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py +++ b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py @@ -18,6 +18,9 @@ class TransactionDeletionRecord(Document): if TYPE_CHECKING: from frappe.types import DF + from erpnext.accounts.doctype.transaction_deletion_record_details.transaction_deletion_record_details import ( + TransactionDeletionRecordDetails, + ) from erpnext.setup.doctype.transaction_deletion_record_item.transaction_deletion_record_item import ( TransactionDeletionRecordItem, ) @@ -28,7 +31,7 @@ class TransactionDeletionRecord(Document): delete_bin_data: DF.Check delete_leads_and_addresses: DF.Check delete_transactions: DF.Check - doctypes: DF.Table[TransactionDeletionRecordItem] + doctypes: DF.Table[TransactionDeletionRecordDetails] doctypes_to_be_ignored: DF.Table[TransactionDeletionRecordItem] initialize_doctypes_table: DF.Check reset_company_default_values: DF.Check @@ -37,7 +40,7 @@ class TransactionDeletionRecord(Document): def __init__(self, *args, **kwargs): super(TransactionDeletionRecord, self).__init__(*args, **kwargs) - self.batch_size = 5000 + self.batch_size = 5 def validate(self): frappe.only_for("System Manager") @@ -75,7 +78,7 @@ class TransactionDeletionRecord(Document): def on_cancel(self): self.db_set("status", "Cancelled") - def chain_callback(self, method): + def chain_call(self, method): frappe.enqueue( "frappe.utils.background_jobs.run_doc_method", doctype=self.doctype, @@ -98,7 +101,7 @@ class TransactionDeletionRecord(Document): if not self.clear_notifications: clear_notifications() self.db_set("clear_notifications", 1) - self.chain_callback("initialize_doctypes_to_be_deleted_table") + self.chain_call("initialize_doctypes_to_be_deleted_table") def populate_doctypes_to_be_ignored_table(self): doctypes_to_be_ignored_list = get_doctypes_to_be_ignored() @@ -114,7 +117,7 @@ class TransactionDeletionRecord(Document): self.company, ) self.db_set("delete_bin_data", 1) - self.chain_callback(method="delete_lead_addresses") + self.chain_call(method="delete_lead_addresses") def delete_lead_addresses(self): """Delete addresses to which leads are linked""" @@ -155,7 +158,7 @@ class TransactionDeletionRecord(Document): ) ) self.db_set("delete_leads_and_addresses", 1) - self.chain_callback(method="reset_company_values") + self.chain_call(method="reset_company_values") def reset_company_values(self): if not self.reset_company_default_values: @@ -164,7 +167,7 @@ class TransactionDeletionRecord(Document): company_obj.sales_monthly_history = None company_obj.save() self.db_set("reset_company_default_values", 1) - self.chain_callback(method="delete_notifications") + self.chain_call(method="delete_notifications") def initialize_doctypes_to_be_deleted_table(self): if not self.initialize_doctypes_table: @@ -180,7 +183,7 @@ class TransactionDeletionRecord(Document): # Initialize self.populate_doctypes_table(tables, docfield["parent"], docfield["fieldname"], 0) self.db_set("initialize_doctypes_table", 1) - self.chain_callback(method="delete_company_transactions") + self.chain_call(method="delete_company_transactions") def delete_company_transactions(self): if not self.delete_transactions: @@ -203,20 +206,24 @@ class TransactionDeletionRecord(Document): self.delete_communications(docfield.doctype_name, reference_doc_names) self.delete_comments(docfield.doctype_name, reference_doc_names) self.unlink_attachments(docfield.doctype_name, reference_doc_names) - self.delete_child_tables(docfield.doctype_name, reference_doc_names) - self.delete_docs_linked_with_specified_company(docfield.doctype_name, docfield.docfield_name) - + self.delete_docs_linked_with_specified_company(docfield.doctype_name, reference_doc_names) + processed = int(docfield.no_of_docs) + len(reference_doc_names) + frappe.db.set_value(docfield.doctype, docfield.name, "no_of_docs", processed) + else: naming_series = frappe.db.get_value("DocType", docfield.doctype_name, "autoname") - # TODO: do this at the end of each doctype if naming_series: if "#" in naming_series: self.update_naming_series(naming_series, docfield.doctype_name) - - self.chain_callback(method="delete_company_transactions") - else: frappe.db.set_value(docfield.doctype, docfield.name, "done", 1) - self.db_set("delete_transactions", 1) + + pending_doctypes = frappe.db.get_all( + docfield.doctype, filters={"parent": self.name, "done": 0}, pluck="doctype_name" + ) + if pending_doctypes: + self.chain_call(method="delete_company_transactions") + else: + self.db_set("delete_transactions", 1) def get_doctypes_to_be_ignored_list(self): singles = frappe.get_all("DocType", filters={"issingle": 1}, pluck="name") @@ -261,8 +268,8 @@ class TransactionDeletionRecord(Document): for table in child_tables: frappe.db.delete(table, {"parent": ["in", reference_doc_names]}) - def delete_docs_linked_with_specified_company(self, doctype, company_fieldname): - frappe.db.delete(doctype, {company_fieldname: self.company}) + def delete_docs_linked_with_specified_company(self, doctype, reference_doc_names): + frappe.db.delete(doctype, {"name": ("in", reference_doc_names)}) def update_naming_series(self, naming_series, doctype_name): if "." in naming_series: diff --git a/erpnext/setup/doctype/transaction_deletion_record_item/transaction_deletion_record_item.json b/erpnext/setup/doctype/transaction_deletion_record_item/transaction_deletion_record_item.json index 4e5e1846999..89db63694c2 100644 --- a/erpnext/setup/doctype/transaction_deletion_record_item/transaction_deletion_record_item.json +++ b/erpnext/setup/doctype/transaction_deletion_record_item/transaction_deletion_record_item.json @@ -5,10 +5,7 @@ "editable_grid": 1, "engine": "InnoDB", "field_order": [ - "doctype_name", - "docfield_name", - "no_of_docs", - "done" + "doctype_name" ], "fields": [ { @@ -18,30 +15,12 @@ "label": "DocType", "options": "DocType", "reqd": 1 - }, - { - "fieldname": "no_of_docs", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Number of Docs" - }, - { - "default": "0", - "fieldname": "done", - "fieldtype": "Check", - "in_list_view": 1, - "label": "Done" - }, - { - "fieldname": "docfield_name", - "fieldtype": "Data", - "label": "DocField Name" } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2024-02-03 21:06:32.274445", + "modified": "2024-02-04 10:56:27.413691", "modified_by": "Administrator", "module": "Setup", "name": "Transaction Deletion Record Item", diff --git a/erpnext/setup/doctype/transaction_deletion_record_item/transaction_deletion_record_item.py b/erpnext/setup/doctype/transaction_deletion_record_item/transaction_deletion_record_item.py index ce716ac477c..906660739e4 100644 --- a/erpnext/setup/doctype/transaction_deletion_record_item/transaction_deletion_record_item.py +++ b/erpnext/setup/doctype/transaction_deletion_record_item/transaction_deletion_record_item.py @@ -15,10 +15,7 @@ class TransactionDeletionRecordItem(Document): if TYPE_CHECKING: from frappe.types import DF - docfield_name: DF.Data | None doctype_name: DF.Link - done: DF.Check - no_of_docs: DF.Data | None parent: DF.Data parentfield: DF.Data parenttype: DF.Data