diff --git a/frappe/core/doctype/submission_queue/submission_queue.py b/frappe/core/doctype/submission_queue/submission_queue.py index dc0cbba962..0c53fe3ddf 100644 --- a/frappe/core/doctype/submission_queue/submission_queue.py +++ b/frappe/core/doctype/submission_queue/submission_queue.py @@ -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"} ): frappe.msgprint( - _( - "This document has already been queued for submission. You can track the progress over {0}." - ).format(f"here"), + _("This document has already been queued for {0}. You can track the progress over {1}.").format( + action, f"here" + ), indicator="orange", alert=True, ) @@ -183,8 +183,8 @@ def queue_submission(doc: Document, action: str, alert: bool = True): if alert: frappe.msgprint( - _("Queued for Submission. You can track the progress over {0}.").format( - f"here" + _("Queued for {0}. You can track the progress over {1}.").format( + action, f"here" ), indicator="green", alert=True, diff --git a/frappe/core/doctype/submission_queue/test_submission_queue.py b/frappe/core/doctype/submission_queue/test_submission_queue.py index afecd49709..b88b3a37b5 100644 --- a/frappe/core/doctype/submission_queue/test_submission_queue.py +++ b/frappe/core/doctype/submission_queue/test_submission_queue.py @@ -51,3 +51,71 @@ class TestSubmissionQueue(IntegrationTestCase): job = self.queue.fetch_job(submission_queue.job_id) # Test completion 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() diff --git a/frappe/desk/form/save.py b/frappe/desk/form/save.py index c37d7452eb..4b15caaabd 100644 --- a/frappe/desk/form/save.py +++ b/frappe/desk/form/save.py @@ -64,6 +64,11 @@ def cancel( if workflow_state_fieldname and 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() send_updated_docs(doc) frappe.msgprint(frappe._("Cancelled"), indicator="red", alert=True) diff --git a/frappe/model/workflow.py b/frappe/model/workflow.py index b0f58da46e..d3e0d1cf4d 100644 --- a/frappe/model/workflow.py +++ b/frappe/model/workflow.py @@ -218,6 +218,10 @@ def apply_workflow(doc: Document | str | dict, action: str): elif doc.docstatus.is_submitted() and new_docstatus.is_submitted(): doc.save() 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() else: frappe.throw(_("Illegal Document Status for {0}").format(next_state.state)) diff --git a/frappe/public/js/frappe/form/form.js b/frappe/public/js/frappe/form/form.js index cdbeca6dd0..381f5daa34 100644 --- a/frappe/public/js/frappe/form/form.js +++ b/frappe/public/js/frappe/form/form.js @@ -2270,7 +2270,7 @@ frappe.ui.form.Form = class FrappeForm { this.meta.is_submittable && this.meta.queue_in_background && !this.doc.__islocal && - this.doc.docstatus === 0 + this.doc.docstatus <= 1 ) ) { wrapper.length && wrapper.remove(); @@ -2288,7 +2288,7 @@ frappe.ui.form.Form = class FrappeForm { args: { doctype: this.doctype, docname: this.docname }, }) .then((r) => { - if (r.message?.latest_submission) { + if (r.message?.latest_submission && r.message.status !== "Finished") { // if we are here that means some submission(s) were queued and are in queued/failed state let submission_label = __("Previous Submission"); let secondary = "";