@@ -854,8 +854,8 @@ def get_meta_module(doctype): | |||
import frappe.modules | |||
return frappe.modules.load_doctype_module(doctype) | |||
def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, | |||
for_reload=False, ignore_permissions=False, flags=None, ignore_on_trash=False, ignore_missing=True): | |||
def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, for_reload=False, | |||
ignore_permissions=False, flags=None, ignore_on_trash=False, ignore_missing=True, delete_permanently=False): | |||
"""Delete a document. Calls `frappe.model.delete_doc.delete_doc`. | |||
:param doctype: DocType of document to be delete. | |||
@@ -863,10 +863,11 @@ def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, | |||
:param force: Allow even if document is linked. Warning: This may lead to data integrity errors. | |||
:param ignore_doctypes: Ignore if child table is one of these. | |||
:param for_reload: Call `before_reload` trigger before deleting. | |||
:param ignore_permissions: Ignore user permissions.""" | |||
:param ignore_permissions: Ignore user permissions. | |||
:param delete_permanently: Do not create a Deleted Document for the document.""" | |||
import frappe.model.delete_doc | |||
frappe.model.delete_doc.delete_doc(doctype, name, force, ignore_doctypes, for_reload, | |||
ignore_permissions, flags, ignore_on_trash, ignore_missing) | |||
ignore_permissions, flags, ignore_on_trash, ignore_missing, delete_permanently) | |||
def delete_doc_if_exists(doctype, name, force=0): | |||
"""Delete document if exists.""" | |||
@@ -718,7 +718,7 @@ def delete_file(path): | |||
os.remove(path) | |||
def remove_file(fid=None, attached_to_doctype=None, attached_to_name=None, from_delete=False): | |||
def remove_file(fid=None, attached_to_doctype=None, attached_to_name=None, from_delete=False, delete_permanently=False): | |||
"""Remove file and File entry""" | |||
file_name = None | |||
if not (attached_to_doctype and attached_to_name): | |||
@@ -736,7 +736,7 @@ def remove_file(fid=None, attached_to_doctype=None, attached_to_name=None, from_ | |||
if not file_name: | |||
file_name = frappe.db.get_value("File", fid, "file_name") | |||
comment = doc.add_comment("Attachment Removed", _("Removed {0}").format(file_name)) | |||
frappe.delete_doc("File", fid, ignore_permissions=ignore_permissions) | |||
frappe.delete_doc("File", fid, ignore_permissions=ignore_permissions, delete_permanently=delete_permanently) | |||
return comment | |||
@@ -745,17 +745,18 @@ def get_max_file_size(): | |||
return cint(conf.get('max_file_size')) or 10485760 | |||
def remove_all(dt, dn, from_delete=False): | |||
def remove_all(dt, dn, from_delete=False, delete_permanently=False): | |||
"""remove all files in a transaction""" | |||
try: | |||
for fid in frappe.db.sql_list("""select name from `tabFile` where | |||
attached_to_doctype=%s and attached_to_name=%s""", (dt, dn)): | |||
if from_delete: | |||
# If deleting a doc, directly delete files | |||
frappe.delete_doc("File", fid, ignore_permissions=True) | |||
frappe.delete_doc("File", fid, ignore_permissions=True, delete_permanently=delete_permanently) | |||
else: | |||
# Removes file and adds a comment in the document it is attached to | |||
remove_file(fid=fid, attached_to_doctype=dt, attached_to_name=dn, from_delete=from_delete) | |||
remove_file(fid=fid, attached_to_doctype=dt, attached_to_name=dn, | |||
from_delete=from_delete, delete_permanently=delete_permanently) | |||
except Exception as e: | |||
if e.args[0]!=1054: raise # (temp till for patched) | |||
@@ -24,8 +24,6 @@ class PreparedReport(Document): | |||
def enqueue_report(self): | |||
enqueue(run_background, prepared_report=self.name, timeout=6000) | |||
def on_trash(self): | |||
remove_all("Prepared Report", self.name) | |||
def run_background(prepared_report): | |||
@@ -100,7 +98,7 @@ def delete_expired_prepared_reports(): | |||
def delete_prepared_reports(reports): | |||
reports = frappe.parse_json(reports) | |||
for report in reports: | |||
frappe.delete_doc('Prepared Report', report['name'], ignore_permissions=True) | |||
frappe.delete_doc('Prepared Report', report['name'], ignore_permissions=True, delete_permanently=True) | |||
def create_json_gz_file(data, dt, dn): | |||
# Storing data in CSV file causes information loss | |||
@@ -1,5 +1,7 @@ | |||
{ | |||
"actions": [], | |||
"allow_read": 1, | |||
"allow_workflow": 1, | |||
"creation": "2014-04-17 16:53:52.640856", | |||
"doctype": "DocType", | |||
"document_type": "System", | |||
@@ -439,7 +441,7 @@ | |||
{ | |||
"default": "30", | |||
"depends_on": "enable_prepared_report_auto_deletion", | |||
"description": "System will automatically delete Prepared Reports after these many days since creation", | |||
"description": "System will auto-delete Prepared Reports permanently after these many days since creation", | |||
"fieldname": "prepared_report_expiry_period", | |||
"fieldtype": "Int", | |||
"label": "Prepared Report Expiry Period (Days)" | |||
@@ -462,13 +464,6 @@ | |||
"fieldtype": "Data", | |||
"label": "App Name" | |||
}, | |||
{ | |||
"default": "3", | |||
"description": "Hourly rate limit for generating password reset links", | |||
"fieldname": "password_reset_limit", | |||
"fieldtype": "Int", | |||
"label": "Password Reset Link Generation Limit" | |||
}, | |||
{ | |||
"default": "1", | |||
"fieldname": "strip_exif_metadata_from_uploaded_images", | |||
@@ -479,7 +474,7 @@ | |||
"icon": "fa fa-cog", | |||
"issingle": 1, | |||
"links": [], | |||
"modified": "2021-03-25 13:58:12.750629", | |||
"modified": "2021-03-25 17:54:32.668876", | |||
"modified_by": "Administrator", | |||
"module": "Core", | |||
"name": "System Settings", | |||
@@ -22,8 +22,8 @@ from frappe.exceptions import FileNotFoundError | |||
doctypes_to_skip = ("Communication", "ToDo", "DocShare", "Email Unsubscribe", "Activity Log", "File", | |||
"Version", "Document Follow", "Comment" , "View Log", "Tag Link", "Notification Log", "Email Queue") | |||
def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, for_reload=False, | |||
ignore_permissions=False, flags=None, ignore_on_trash=False, ignore_missing=True): | |||
def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, for_reload=False, ignore_permissions=False, | |||
flags=None, ignore_on_trash=False, ignore_missing=True, delete_permanently=False): | |||
""" | |||
Deletes a doc(dt, dn) and validates if it is not submitted and not linked in a live record | |||
""" | |||
@@ -110,7 +110,7 @@ def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, for_reloa | |||
doc.run_method("after_delete") | |||
# delete attachments | |||
remove_all(doctype, name, from_delete=True) | |||
remove_all(doctype, name, from_delete=True, delete_permanently=delete_permanently) | |||
if not for_reload: | |||
# Enqueued at the end, because it gets committed | |||
@@ -125,8 +125,13 @@ def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, for_reloa | |||
# delete tag link entry | |||
delete_tags_for_document(doc) | |||
if doc and not for_reload: | |||
if for_reload: | |||
delete_permanently = True | |||
if not delete_permanently: | |||
add_to_deleted_document(doc) | |||
if doc and not for_reload: | |||
if not frappe.flags.in_patch: | |||
try: | |||
doc.notify_update() | |||