diff --git a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py index 36cbb321518..1467400b598 100644 --- a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py +++ b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py @@ -90,7 +90,14 @@ class BankClearance(Document): @frappe.whitelist() def update_clearance_date(self): - clearance_date_updated = False + payment_docs = [] + for d in self.get("payment_entries"): + if d.payment_document not in payment_docs: + payment_docs.append(d.payment_document) + + for doctype in payment_docs: + frappe.has_permission(doctype, "write", throw=True) + for d in self.get("payment_entries"): if d.clearance_date: if not d.payment_document: diff --git a/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py b/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py index a8e468415c1..f11aeda4383 100644 --- a/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py +++ b/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py @@ -154,12 +154,13 @@ class RepostAccountingLedger(Document): @frappe.whitelist() -def start_repost(account_repost_doc=str) -> None: +def start_repost(account_repost_doc: str | None = None) -> None: from erpnext.accounts.general_ledger import make_reverse_gl_entries frappe.flags.through_repost_accounting_ledger = True if account_repost_doc: repost_doc = frappe.get_doc("Repost Accounting Ledger", account_repost_doc) + repost_doc.check_permission("write") if repost_doc.docstatus == 1: # Prevent repost on invoices with deferred accounting diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index 5c0860b4fd3..14146a7872e 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -511,7 +511,8 @@ def get_party_advance_account(party_type, party, company): @frappe.whitelist() -def get_party_bank_account(party_type, party): +def get_party_bank_account(party_type: str, party: str): + frappe.has_permission("Bank Account", "read", throw=True) return frappe.db.get_value("Bank Account", {"party_type": party_type, "party": party, "is_default": 1}) diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py index f0f492191fb..0f901b5eff6 100644 --- a/erpnext/crm/doctype/lead/lead.py +++ b/erpnext/crm/doctype/lead/lead.py @@ -471,7 +471,7 @@ def get_lead_details(lead, posting_date=None, company=None, doctype=None): @frappe.whitelist() -def make_lead_from_communication(communication, ignore_communication_links=False): +def make_lead_from_communication(communication: str, ignore_communication_links: bool = False): """raise a issue from email""" doc = frappe.get_doc("Communication", communication) @@ -490,7 +490,6 @@ def make_lead_from_communication(communication, ignore_communication_links=False } ) lead.flags.ignore_mandatory = True - lead.flags.ignore_permissions = True lead.insert() lead_name = lead.name diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py index 91d60c924bf..b68ab28ee82 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.py +++ b/erpnext/crm/doctype/opportunity/opportunity.py @@ -522,7 +522,9 @@ def auto_close_opportunity(): @frappe.whitelist() -def make_opportunity_from_communication(communication, company, ignore_communication_links=False): +def make_opportunity_from_communication( + communication: str, company: str, ignore_communication_links: bool = False +): from erpnext.crm.doctype.lead.lead import make_lead_from_communication doc = frappe.get_doc("Communication", communication) @@ -540,7 +542,7 @@ def make_opportunity_from_communication(communication, company, ignore_communica "opportunity_from": opportunity_from, "party_name": lead, } - ).insert(ignore_permissions=True) + ).insert() link_communication_to_document(doc, "Opportunity", opportunity.name, ignore_communication_links) diff --git a/erpnext/manufacturing/doctype/bom_creator/bom_creator.py b/erpnext/manufacturing/doctype/bom_creator/bom_creator.py index 71ba95cc8a6..fd32d29fb50 100644 --- a/erpnext/manufacturing/doctype/bom_creator/bom_creator.py +++ b/erpnext/manufacturing/doctype/bom_creator/bom_creator.py @@ -288,8 +288,6 @@ class BOMCreator(Document): @frappe.whitelist() def edit_qty(self, docname: str, qty: float): - self.check_permission("write") - if not frappe.db.exists("BOM Creator Item", {"name": docname, "parent": self.name}): frappe.throw(_("BOM Creator Item {0} does not exist").format(docname)) @@ -364,8 +362,6 @@ class BOMCreator(Document): @frappe.whitelist() def add_item(self, **kwargs): - self.check_permission("write") - if isinstance(kwargs, str): kwargs = frappe.parse_json(kwargs) @@ -400,8 +396,6 @@ class BOMCreator(Document): @frappe.whitelist() def add_sub_assembly(self, **kwargs): - self.check_permission("write") - if isinstance(kwargs, str): kwargs = frappe.parse_json(kwargs) @@ -464,8 +458,6 @@ class BOMCreator(Document): @frappe.whitelist() def delete_node(self, **kwargs): - self.check_permission("write") - if isinstance(kwargs, str): kwargs = frappe.parse_json(kwargs) diff --git a/erpnext/manufacturing/doctype/workstation/workstation.py b/erpnext/manufacturing/doctype/workstation/workstation.py index 216194f68ff..c45fd7852f4 100644 --- a/erpnext/manufacturing/doctype/workstation/workstation.py +++ b/erpnext/manufacturing/doctype/workstation/workstation.py @@ -176,7 +176,7 @@ class Workstation(Document): doc.check_permission("write") doc.append("time_logs", {"from_time": from_time, "employee": employee}) - doc.save(ignore_permissions=True) + doc.save() return doc @@ -191,7 +191,7 @@ class Workstation(Document): row.time_in_mins = time_diff_in_hours(row.to_time, row.from_time) / 60 row.completed_qty = qty - doc.save(ignore_permissions=True) + doc.save() doc.submit() return doc 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 9fa32c9d5ec..919dd29b040 100644 --- a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py +++ b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py @@ -209,6 +209,8 @@ class TransactionDeletionRecord(Document): @frappe.whitelist() def start_deletion_tasks(self): + self.check_permission("write") + # This method is the entry point for the chain of events that follow self.db_set("status", "Running") self.enqueue_task(task="Delete Bins") diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py index 58f393df5d0..9e5185dc0a0 100644 --- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py +++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py @@ -335,7 +335,9 @@ def get_default_address(out, name): @frappe.whitelist() -def get_contact_display(contact): +def get_contact_display(contact: str): + frappe.has_permission("Contact", "read", doc=contact, throw=True) + contact_info = frappe.db.get_value( "Contact", contact, ["first_name", "last_name", "phone", "mobile_no"], as_dict=1 ) @@ -436,7 +438,9 @@ def get_attachments(delivery_stop): @frappe.whitelist() -def get_driver_email(driver): +def get_driver_email(driver: str): + frappe.has_permission("Driver", "read", doc=driver, throw=True) + employee = frappe.db.get_value("Driver", driver, "employee") email = frappe.db.get_value("Employee", employee, "prefered_email") return {"email": email} diff --git a/erpnext/stock/doctype/shipment/shipment.py b/erpnext/stock/doctype/shipment/shipment.py index 880f6b5e1c1..e1fb199c10b 100644 --- a/erpnext/stock/doctype/shipment/shipment.py +++ b/erpnext/stock/doctype/shipment/shipment.py @@ -123,7 +123,9 @@ def get_contact_name(ref_doctype, docname): @frappe.whitelist() -def get_company_contact(user): +def get_company_contact(user: str): + frappe.has_permission("User", "read", throw=True) + contact = frappe.db.get_value( "User", user, diff --git a/erpnext/stock/report/incorrect_serial_and_batch_bundle/incorrect_serial_and_batch_bundle.py b/erpnext/stock/report/incorrect_serial_and_batch_bundle/incorrect_serial_and_batch_bundle.py index 0b27d697a4d..2a9640bab9e 100644 --- a/erpnext/stock/report/incorrect_serial_and_batch_bundle/incorrect_serial_and_batch_bundle.py +++ b/erpnext/stock/report/incorrect_serial_and_batch_bundle/incorrect_serial_and_batch_bundle.py @@ -134,12 +134,15 @@ def get_linked_cancelled_sabb(filters): @frappe.whitelist() -def fix_sabb_entries(selected_rows): +def fix_sabb_entries(selected_rows: str | list): + frappe.has_permission("Serial and Batch Bundle", "write", throw=True) + if isinstance(selected_rows, str): selected_rows = frappe.parse_json(selected_rows) for row in selected_rows: doc = frappe.get_doc("Serial and Batch Bundle", row.get("name")) + doc.check_permission("write") if doc.is_cancelled == 0 and not frappe.db.get_value( "Stock Ledger Entry", {"serial_and_batch_bundle": doc.name, "is_cancelled": 0}, diff --git a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py index aaf0ec87c23..7a8d4d62124 100644 --- a/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py +++ b/erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py @@ -3,6 +3,7 @@ import frappe from frappe import _ +from frappe.model.document import Document from frappe.model.mapper import get_mapped_doc from frappe.utils import flt @@ -364,8 +365,9 @@ def get_mapped_subcontracting_receipt(source_name, target_doc=None): @frappe.whitelist() -def update_subcontracting_order_status(sco, status=None): +def update_subcontracting_order_status(sco: str | Document, status: str | None = None): if isinstance(sco, str): sco = frappe.get_doc("Subcontracting Order", sco) + sco.check_permission("write") sco.update_status(status) diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py index faa12bd5419..c35b76cf37d 100644 --- a/erpnext/support/doctype/issue/issue.py +++ b/erpnext/support/doctype/issue/issue.py @@ -118,7 +118,9 @@ class Issue(Document): communication.save() @frappe.whitelist() - def split_issue(self, subject, communication_id): + def split_issue(self, subject: str, communication_id: str): + self.check_permission("write") + # Bug: Pressing enter doesn't send subject from copy import deepcopy @@ -274,7 +276,7 @@ def make_task(source_name, target_doc=None): @frappe.whitelist() -def make_issue_from_communication(communication, ignore_communication_links=False): +def make_issue_from_communication(communication: str, ignore_communication_links: bool = False): """raise a issue from email""" doc = frappe.get_doc("Communication", communication) @@ -286,7 +288,7 @@ def make_issue_from_communication(communication, ignore_communication_links=Fals "raised_by": doc.sender or "", "raised_by_phone": doc.phone_no or "", } - ).insert(ignore_permissions=True) + ).insert() link_communication_to_document(doc, "Issue", issue.name, ignore_communication_links)