diff --git a/erpnext/manufacturing/doctype/job_card/job_card.js b/erpnext/manufacturing/doctype/job_card/job_card.js index 52423c600d9..be8e534e1f0 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.js +++ b/erpnext/manufacturing/doctype/job_card/job_card.js @@ -355,6 +355,10 @@ frappe.ui.form.on("Job Card", { default: frm.doc.for_quantity - frm.doc.total_completed_qty, }, (data) => { + if (data.qty < 0) { + frappe.throw(__("Completed Quantity cannot be negative")); + } + frm.events.complete_job(frm, "Complete", data.qty); }, __("Enter Value") diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py index 16a454a984b..0807d98e61a 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.py +++ b/erpnext/manufacturing/doctype/job_card/job_card.py @@ -755,9 +755,10 @@ class JobCard(Document): def set_process_loss(self): precision = self.precision("total_completed_qty") + should_set_process_loss = self.total_completed_qty or self.process_loss_qty self.process_loss_qty = 0.0 - if self.total_completed_qty and self.for_quantity > self.total_completed_qty: + if should_set_process_loss and self.for_quantity > self.total_completed_qty: self.process_loss_qty = flt(self.for_quantity, precision) - flt( self.total_completed_qty, precision ) diff --git a/erpnext/manufacturing/doctype/job_card/test_job_card.py b/erpnext/manufacturing/doctype/job_card/test_job_card.py index ceb5ce299eb..f9b4cc0eabc 100644 --- a/erpnext/manufacturing/doctype/job_card/test_job_card.py +++ b/erpnext/manufacturing/doctype/job_card/test_job_card.py @@ -1157,6 +1157,19 @@ class TestJobCard(FrappeTestCase): assert_operating_costs(s4, 3, [s, s3]) + def test_set_process_loss(self): + nothing_done = frappe.new_doc("Job Card") + nothing_done.for_quantity = 10 + nothing_done.total_completed_qty = 0 + nothing_done.set_process_loss() + self.assertEqual(nothing_done.process_loss_qty, 0) + + all_process_loss = frappe.new_doc("Job Card") + all_process_loss.for_quantity = 10 + all_process_loss.process_loss_qty = 10 + all_process_loss.set_process_loss() + self.assertEqual(all_process_loss.process_loss_qty, 10) + def create_bom_with_multiple_operations(): "Create a BOM with multiple operations and Material Transfer against Job Card"