feat: enqueue cancellation in submission queue

This commit is contained in:
Shrihari Mahabal 2026-03-25 15:27:20 +05:30
parent 21417c67b1
commit 377cc70d8b
5 changed files with 83 additions and 6 deletions

View file

@ -168,9 +168,9 @@ def queue_submission(doc: Document, action: str, alert: bool = True):
"Submission Queue", {"ref_doctype": doc.doctype, "ref_docname": doc.name, "status": "Queued"} "Submission Queue", {"ref_doctype": doc.doctype, "ref_docname": doc.name, "status": "Queued"}
): ):
frappe.msgprint( frappe.msgprint(
_( _("This document has already been queued for {0}. You can track the progress over {1}.").format(
"This document has already been queued for submission. You can track the progress over {0}." action, f"<a href='/desk/submission-queue/{existing_queue}'><b>here</b></a>"
).format(f"<a href='/desk/submission-queue/{existing_queue}'><b>here</b></a>"), ),
indicator="orange", indicator="orange",
alert=True, alert=True,
) )
@ -183,8 +183,8 @@ def queue_submission(doc: Document, action: str, alert: bool = True):
if alert: if alert:
frappe.msgprint( frappe.msgprint(
_("Queued for Submission. You can track the progress over {0}.").format( _("Queued for {0}. You can track the progress over {1}.").format(
f"<a href='/desk/submission-queue/{queue.name}'><b>here</b></a>" action, f"<a href='/desk/submission-queue/{queue.name}'><b>here</b></a>"
), ),
indicator="green", indicator="green",
alert=True, alert=True,

View file

@ -51,3 +51,71 @@ class TestSubmissionQueue(IntegrationTestCase):
job = self.queue.fetch_job(submission_queue.job_id) job = self.queue.fetch_job(submission_queue.job_id)
# Test completion # Test completion
self.check_status(job, status="finished") self.check_status(job, status="finished")
def test_cancel_operation(self):
from frappe.core.doctype.doctype.test_doctype import new_doctype
from frappe.core.doctype.submission_queue.submission_queue import queue_submission
if not frappe.db.table_exists("Test Submission Queue", cached=False):
doc = new_doctype("Test Submission Queue", is_submittable=True, queue_in_background=True)
doc.insert()
d = frappe.new_doc("Test Submission Queue")
d.update({"some_fieldname": "Random"})
d.insert()
d.submit()
frappe.db.commit()
self.assertEqual(d.docstatus, 1)
queue_submission(d, "Cancel")
frappe.db.commit()
time.sleep(4)
submission_queue = frappe.get_last_doc("Submission Queue")
job = self.queue.fetch_job(submission_queue.job_id)
self.check_status(job, status="finished")
d.reload()
self.assertEqual(d.docstatus, 2)
def test_cancel_on_cancelled_doc(self):
from frappe.core.doctype.doctype.test_doctype import new_doctype
from frappe.core.doctype.submission_queue.submission_queue import queue_submission
if not frappe.db.table_exists("Test Submission Queue", cached=False):
doc = new_doctype("Test Submission Queue", is_submittable=True, queue_in_background=True)
doc.insert()
d = frappe.new_doc("Test Submission Queue")
d.update({"some_fieldname": "Random"})
d.insert()
d.submit()
frappe.db.commit()
existing = frappe.get_doc(
{
"doctype": "Submission Queue",
"ref_doctype": d.doctype,
"ref_docname": d.name,
"status": "Queued",
}
)
existing.insert(d, "Cancel")
frappe.db.commit()
initial_count = frappe.db.count(
"Submission Queue", {"ref_doctype": d.doctype, "ref_docname": d.name, "status": "Queued"}
)
queue_submission(d, "Cancel")
final_count = frappe.db.count(
"Submission Queue", {"ref_doctype": d.doctype, "ref_docname": d.name, "status": "Queued"}
)
self.assertEqual(initial_count, final_count)
existing.delete(ignore_permissions=True)
frappe.db.commit()

View file

@ -64,6 +64,11 @@ def cancel(
if workflow_state_fieldname and workflow_state: if workflow_state_fieldname and workflow_state:
doc.set(workflow_state_fieldname, workflow_state) doc.set(workflow_state_fieldname, workflow_state)
if doc.meta.queue_in_background and not is_scheduler_inactive():
queue_submission(doc, "Cancel")
return
doc.cancel() doc.cancel()
send_updated_docs(doc) send_updated_docs(doc)
frappe.msgprint(frappe._("Cancelled"), indicator="red", alert=True) frappe.msgprint(frappe._("Cancelled"), indicator="red", alert=True)

View file

@ -218,6 +218,10 @@ def apply_workflow(doc: Document | str | dict, action: str):
elif doc.docstatus.is_submitted() and new_docstatus.is_submitted(): elif doc.docstatus.is_submitted() and new_docstatus.is_submitted():
doc.save() doc.save()
elif doc.docstatus.is_submitted() and new_docstatus.is_cancelled(): elif doc.docstatus.is_submitted() and new_docstatus.is_cancelled():
if doc.meta.queue_in_background and not is_scheduler_inactive():
queue_submission(doc, "Cancel")
return
doc.cancel() doc.cancel()
else: else:
frappe.throw(_("Illegal Document Status for {0}").format(next_state.state)) frappe.throw(_("Illegal Document Status for {0}").format(next_state.state))

View file

@ -2270,7 +2270,7 @@ frappe.ui.form.Form = class FrappeForm {
this.meta.is_submittable && this.meta.is_submittable &&
this.meta.queue_in_background && this.meta.queue_in_background &&
!this.doc.__islocal && !this.doc.__islocal &&
this.doc.docstatus === 0 this.doc.docstatus <= 1
) )
) { ) {
wrapper.length && wrapper.remove(); wrapper.length && wrapper.remove();