Added input validation
Added document existence checks Added reference field validation Changed None to empty strings for reference fields
This commit is contained in:
parent
499888b4a7
commit
51823d1b88
134
crm/api/doc.py
134
crm/api/doc.py
@ -751,7 +751,12 @@ def getCounts(d, doctype):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_linked_docs_of_document(doctype, docname):
|
def get_linked_docs_of_document(doctype, docname):
|
||||||
doc = frappe.get_doc(doctype, docname)
|
try:
|
||||||
|
doc = frappe.get_doc(doctype, docname)
|
||||||
|
except frappe.DoesNotExistError:
|
||||||
|
|
||||||
|
return []
|
||||||
|
|
||||||
linked_docs = get_linked_docs(doc)
|
linked_docs = get_linked_docs(doc)
|
||||||
dynamic_linked_docs = get_dynamic_linked_docs(doc)
|
dynamic_linked_docs = get_dynamic_linked_docs(doc)
|
||||||
|
|
||||||
@ -760,7 +765,16 @@ def get_linked_docs_of_document(doctype, docname):
|
|||||||
|
|
||||||
docs_data = []
|
docs_data = []
|
||||||
for doc in linked_docs:
|
for doc in linked_docs:
|
||||||
data = frappe.get_doc(doc["reference_doctype"], doc["reference_docname"])
|
|
||||||
|
if not doc.get("reference_doctype") or not doc.get("reference_docname"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = frappe.get_doc(doc["reference_doctype"], doc["reference_docname"])
|
||||||
|
except (frappe.DoesNotExistError, frappe.ValidationError):
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
title = data.get("title")
|
title = data.get("title")
|
||||||
if data.doctype == "CRM Call Log":
|
if data.doctype == "CRM Call Log":
|
||||||
title = f"Call from {data.get('from')} to {data.get('to')}"
|
title = f"Call from {data.get('from')} to {data.get('to')}"
|
||||||
@ -780,25 +794,42 @@ def get_linked_docs_of_document(doctype, docname):
|
|||||||
|
|
||||||
|
|
||||||
def remove_doc_link(doctype, docname):
|
def remove_doc_link(doctype, docname):
|
||||||
linked_doc_data = frappe.get_doc(doctype, docname)
|
|
||||||
linked_doc_data.update(
|
if not doctype or not docname:
|
||||||
{
|
return
|
||||||
"reference_doctype": None,
|
|
||||||
"reference_docname": None,
|
try:
|
||||||
}
|
linked_doc_data = frappe.get_doc(doctype, docname)
|
||||||
)
|
|
||||||
linked_doc_data.save(ignore_permissions=True)
|
linked_doc_data.update(
|
||||||
|
{
|
||||||
|
"reference_doctype": "",
|
||||||
|
"reference_docname": "",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
linked_doc_data.save(ignore_permissions=True)
|
||||||
|
except (frappe.DoesNotExistError, frappe.ValidationError):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def remove_contact_link(doctype, docname):
|
def remove_contact_link(doctype, docname):
|
||||||
linked_doc_data = frappe.get_doc(doctype, docname)
|
|
||||||
linked_doc_data.update(
|
if not doctype or not docname:
|
||||||
{
|
return
|
||||||
"contact": None,
|
|
||||||
"contacts": [],
|
try:
|
||||||
}
|
linked_doc_data = frappe.get_doc(doctype, docname)
|
||||||
)
|
linked_doc_data.update(
|
||||||
linked_doc_data.save(ignore_permissions=True)
|
{
|
||||||
|
"contact": None,
|
||||||
|
"contacts": [],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
linked_doc_data.save(ignore_permissions=True)
|
||||||
|
except (frappe.DoesNotExistError, frappe.ValidationError):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@ -807,13 +838,21 @@ def remove_linked_doc_reference(items, remove_contact=None, delete=False):
|
|||||||
items = frappe.parse_json(items)
|
items = frappe.parse_json(items)
|
||||||
|
|
||||||
for item in items:
|
for item in items:
|
||||||
if remove_contact:
|
|
||||||
remove_contact_link(item["doctype"], item["docname"])
|
if not item.get("doctype") or not item.get("docname"):
|
||||||
else:
|
continue
|
||||||
remove_doc_link(item["doctype"], item["docname"])
|
|
||||||
|
try:
|
||||||
|
if remove_contact:
|
||||||
|
remove_contact_link(item["doctype"], item["docname"])
|
||||||
|
else:
|
||||||
|
remove_doc_link(item["doctype"], item["docname"])
|
||||||
|
|
||||||
if delete:
|
if delete:
|
||||||
frappe.delete_doc(item["doctype"], item["docname"])
|
frappe.delete_doc(item["doctype"], item["docname"])
|
||||||
|
except (frappe.DoesNotExistError, frappe.ValidationError):
|
||||||
|
# Skip if document doesn't exist or has validation errors
|
||||||
|
continue
|
||||||
|
|
||||||
return "success"
|
return "success"
|
||||||
|
|
||||||
@ -822,20 +861,43 @@ def remove_linked_doc_reference(items, remove_contact=None, delete=False):
|
|||||||
def delete_bulk_docs(doctype, items, delete_linked=False):
|
def delete_bulk_docs(doctype, items, delete_linked=False):
|
||||||
from frappe.desk.reportview import delete_bulk
|
from frappe.desk.reportview import delete_bulk
|
||||||
|
|
||||||
|
|
||||||
|
if not doctype:
|
||||||
|
frappe.throw("Doctype is required")
|
||||||
|
|
||||||
|
if not items:
|
||||||
|
frappe.throw("Items are required")
|
||||||
|
|
||||||
items = frappe.parse_json(items)
|
items = frappe.parse_json(items)
|
||||||
|
if not isinstance(items, list):
|
||||||
|
frappe.throw("Items must be a list")
|
||||||
|
|
||||||
for doc in items:
|
for doc in items:
|
||||||
linked_docs = get_linked_docs_of_document(doctype, doc)
|
try:
|
||||||
for linked_doc in linked_docs:
|
|
||||||
remove_linked_doc_reference(
|
if not frappe.db.exists(doctype, doc):
|
||||||
[
|
frappe.log_error(f"Document {doctype} {doc} does not exist", "Bulk Delete Error")
|
||||||
{
|
continue
|
||||||
"doctype": linked_doc["reference_doctype"],
|
|
||||||
"docname": linked_doc["reference_docname"],
|
linked_docs = get_linked_docs_of_document(doctype, doc)
|
||||||
}
|
for linked_doc in linked_docs:
|
||||||
],
|
|
||||||
remove_contact=doctype == "Contact",
|
if not linked_doc.get("reference_doctype") or not linked_doc.get("reference_docname"):
|
||||||
delete=delete_linked,
|
continue
|
||||||
)
|
|
||||||
|
remove_linked_doc_reference(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"doctype": linked_doc["reference_doctype"],
|
||||||
|
"docname": linked_doc["reference_docname"],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
remove_contact=doctype == "Contact",
|
||||||
|
delete=delete_linked,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
|
||||||
|
frappe.log_error(f"Error processing linked docs for {doctype} {doc}: {str(e)}", "Bulk Delete Error")
|
||||||
|
|
||||||
if len(items) > 10:
|
if len(items) > 10:
|
||||||
frappe.enqueue("frappe.desk.reportview.delete_bulk", doctype=doctype, items=items)
|
frappe.enqueue("frappe.desk.reportview.delete_bulk", doctype=doctype, items=items)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user