Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions rmax_custom/api/delivery_note.py
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,38 @@ def consolidate_dns_to_si(delivery_note_names):
return si.name


def clear_consolidated_si_links(si_name):
"""Clear the ``custom_consolidated_si`` back-reference on every Delivery
Note that points to this Sales Invoice.

``consolidate_dns_to_si`` stamps each source DN with
``custom_consolidated_si = <SI>``. That Link field makes Frappe's
link-integrity check (``check_if_doc_is_linked``) block cancel/delete of the
SI. Both the cancel path (submitted SI) and the trash path (draft SI delete)
must clear it first, or the operation is refused with
"Cannot delete or cancel ... is linked with Delivery Note ...".
"""
for dn_name in frappe.get_all(
"Delivery Note",
filters={"custom_consolidated_si": si_name},
pluck="name",
):
frappe.db.set_value(
"Delivery Note", dn_name,
"custom_consolidated_si", None,
update_modified=False,
)


def sales_invoice_on_trash_clear_consolidated(doc, method=None):
"""Sales Invoice ``on_trash``: free the netted-off DN stamps so a DRAFT
consolidated SI can be deleted. ``on_trash`` runs before
``check_if_doc_is_linked`` in ``frappe.delete_doc`` (verified against v15),
so clearing here lets the link-integrity check pass. The submitted-SI case
is handled separately on ``on_cancel``. No-op for non-consolidated SIs."""
clear_consolidated_si_links(doc.name)


# ---------------------------------------------------------------------------
# Multi-source return allocation APIs
# ---------------------------------------------------------------------------
Expand Down
3 changes: 3 additions & 0 deletions rmax_custom/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@
"rmax_custom.inter_company_dn.sales_invoice_on_cancel",
"rmax_custom.api.delivery_note.sales_invoice_on_cancel_clear_dn_return",
],
"on_trash": [
"rmax_custom.api.delivery_note.sales_invoice_on_trash_clear_consolidated",
],
},
"Quotation": {
"before_insert": [
Expand Down
14 changes: 3 additions & 11 deletions rmax_custom/inter_company_dn.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,17 +291,9 @@ def sales_invoice_on_cancel(doc, method=None):

# Clear the net-off consolidation stamp on every DN linked via
# custom_consolidated_si. (Set by api.delivery_note.consolidate_dns_to_si.)
consolidated_dns = frappe.get_all(
"Delivery Note",
filters={"custom_consolidated_si": doc.name},
pluck="name",
)
for dn_name in consolidated_dns:
frappe.db.set_value(
"Delivery Note", dn_name,
"custom_consolidated_si", None,
update_modified=False,
)
# Shared with the on_trash path. Local import avoids a circular import.
from rmax_custom.api.delivery_note import clear_consolidated_si_links
clear_consolidated_si_links(doc.name)


def _source_dns_for_si(si_doc) -> set[str]:
Expand Down
17 changes: 17 additions & 0 deletions rmax_custom/tests/test_dn_consolidation.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,23 @@ def test_si_cancel_clears_stamp(self):
frappe.db.get_value("Delivery Note", dn.name, "custom_consolidated_si")
)

def test_draft_si_delete_clears_stamp_and_succeeds(self):
# Reproduces the bug: a DRAFT consolidated SI stamps the DN via
# custom_consolidated_si; deleting it must clear the stamp (on_trash)
# so the link-integrity check doesn't block the delete.
dn = _make_submitted_dn(self.customer, self.item, self.company,
self.warehouse, qty=5, rate=10)
si_name = consolidate_dns_to_si([dn.name])
self.assertEqual(
frappe.db.get_value("Delivery Note", dn.name, "custom_consolidated_si"),
si_name,
)
frappe.delete_doc("Sales Invoice", si_name)
self.assertFalse(frappe.db.exists("Sales Invoice", si_name))
self.assertFalse(
frappe.db.get_value("Delivery Note", dn.name, "custom_consolidated_si")
)


# --- fixtures helpers ---

Expand Down
Loading