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 808b2e2984)
This commit is contained in:
Mihir Kandoi
2026-08-11 13:08:33 +05:30
committed by Mergify
parent 4229161f4f
commit a7f75de1aa
2 changed files with 3 additions and 2 deletions

View File

@@ -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;

View File

@@ -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)