From a7f75de1aa1b42bef6147fa506e47fc8b2496ace Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Tue, 11 Aug 2026 13:08:33 +0530 Subject: [PATCH] fix: require material transfer before job card start and completion When the work order transfers material against Job Card, the Start Job and Complete Job actions (and the whitelisted start_timer and complete_job_card methods behind them) accepted work before any Material Transfer for Manufacture existed; the transfer gate only fired on job card submission. Run validate_transfer_qty on both actions, and drop the finished_good escape in materials_ready so the dashboard hides the buttons while transfer is pending. Job cards that skip material transfer, corrective job cards, and work orders transferring against Work Order are exempt, as on submit. (cherry picked from commit 808b2e298432dfec7558da3262eff292b12b9027) --- erpnext/manufacturing/doctype/job_card/job_card.js | 3 +-- erpnext/manufacturing/doctype/job_card/job_card.py | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/manufacturing/doctype/job_card/job_card.js b/erpnext/manufacturing/doctype/job_card/job_card.js index 2f62c5d1304..e55b25d5422 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.js +++ b/erpnext/manufacturing/doctype/job_card/job_card.js @@ -598,8 +598,7 @@ frappe.ui.form.on("Job Card", { const has_remaining_qty = doc.for_quantity + doc.process_loss_qty > doc.total_completed_qty; const pending_transfer = has_items && doc.items.some((row) => flt(row.transferred_qty) < flt(row.required_qty)); - const materials_ready = - doc.skip_material_transfer || !pending_transfer || !doc.finished_good || !has_items; + const materials_ready = doc.skip_material_transfer || !pending_transfer; let last_row = {}; const has_sub_ops_or_pending_qty = doc.sub_operations?.length || doc.pending_qty > 0; diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py index 5c248a3e3e3..0e05bfb18a8 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.py +++ b/erpnext/manufacturing/doctype/job_card/job_card.py @@ -1579,6 +1579,7 @@ class JobCard(Document): def start_timer(self, **kwargs): frappe.has_permission("Job Card", "write", doc=self, throw=True) self.validate_docstatus() + self.validate_transfer_qty() if isinstance(kwargs, dict): kwargs = frappe._dict(kwargs) @@ -1596,6 +1597,7 @@ class JobCard(Document): frappe.has_permission("Job Card", "write", doc=self, throw=True) self.validate_docstatus() + self.validate_transfer_qty() if isinstance(kwargs, dict): kwargs = frappe._dict(kwargs)