diff --git a/erpnext/manufacturing/doctype/job_card/job_card.js b/erpnext/manufacturing/doctype/job_card/job_card.js index 4e5041d4c06..dedc7c20966 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.js +++ b/erpnext/manufacturing/doctype/job_card/job_card.js @@ -67,7 +67,11 @@ frappe.ui.form.on("Job Card", { if (remaining_qty < frm.doc.pending_qty) { frm.doc.pending_qty = 0.0; refresh_field("pending_qty"); - frappe.throw(__("Pending Quantity cannot be greater than {0}", [remaining_qty])); + frappe.throw( + __("Pending Quantity cannot be greater than {0}", [ + get_qty_with_uom(remaining_qty, frm.doc.stock_uom), + ]) + ); } const process_loss_qty = flt(remaining_qty) - flt(frm.doc.pending_qty); @@ -272,7 +276,9 @@ frappe.ui.form.on("Job Card", { flt(dialog.get_value("for_quantity")) - flt(dialog.get_value("process_loss_qty")); dialog.set_value("completed_qty", max_completed_qty); frappe.throw( - __("Completed Quantity cannot be greater than {0}", [max_completed_qty]) + __("Completed Quantity cannot be greater than {0}", [ + get_qty_with_uom(max_completed_qty, frm.doc.stock_uom), + ]) ); } @@ -298,8 +304,11 @@ frappe.ui.form.on("Job Card", { dialog.set_value("pending_qty", 0); frappe.throw( __("Pending Quantity cannot be greater than {0}", [ - flt(dialog.get_value("for_quantity")) - - flt(dialog.get_value("completed_qty")), + get_qty_with_uom( + flt(dialog.get_value("for_quantity")) - + flt(dialog.get_value("completed_qty")), + frm.doc.stock_uom + ), ]) ); } @@ -325,8 +334,11 @@ frappe.ui.form.on("Job Card", { dialog.set_value("process_loss_qty", 0); frappe.throw( __("Process Loss Quantity cannot be greater than {0}", [ - flt(dialog.get_value("for_quantity")) - - flt(dialog.get_value("completed_qty")), + get_qty_with_uom( + flt(dialog.get_value("for_quantity")) - + flt(dialog.get_value("completed_qty")), + frm.doc.stock_uom + ), ]) ); } @@ -884,3 +896,7 @@ function get_last_completed_row(time_logs) { function get_last_row(time_logs) { return time_logs[time_logs.length - 1] || {}; } + +function get_qty_with_uom(qty, stock_uom) { + return stock_uom ? `${flt(qty)} ${stock_uom}` : flt(qty); +} diff --git a/erpnext/manufacturing/doctype/job_card/test_job_card.py b/erpnext/manufacturing/doctype/job_card/test_job_card.py index 8762a6a3d13..da1b40af076 100644 --- a/erpnext/manufacturing/doctype/job_card/test_job_card.py +++ b/erpnext/manufacturing/doctype/job_card/test_job_card.py @@ -924,6 +924,14 @@ class TestJobCard(ERPNextTestSuite): )[0], ) + def test_stock_uom_is_set_from_the_produced_item(self): + work_order = make_wo_order_test_record(item="_Test FG Item 2", qty=5) + + job_card = self.get_first_job_card(work_order.name) + item_code = job_card.finished_good or job_card.production_item + + self.assertEqual(job_card.stock_uom, frappe.db.get_value("Item", item_code, "stock_uom")) + def test_completion_qty_reduces_for_quantity_without_process_loss(self): work_order = make_wo_order_test_record(item="_Test FG Item 2", qty=5) @@ -2228,6 +2236,13 @@ class TestJobCardLogic(ERPNextTestSuite): frappe.ValidationError, jc.validate_complete_job_card_qty, frappe._dict(pending_qty=10) ) + def test_qty_in_messages_carries_the_uom(self): + jc = frappe.new_doc("Job Card") + jc.stock_uom = "Nos" + + self.assertEqual(jc.get_qty_with_uom(5), "5.0 Nos") + self.assertEqual(jc.get_qty_with_uom(0), "0.0 Nos") + def test_completion_qty_split_must_add_up(self): jc = frappe.new_doc("Job Card") jc.for_quantity = 5 diff --git a/erpnext/public/js/shop_floor/shop_floor.js b/erpnext/public/js/shop_floor/shop_floor.js index 13b8ca657d2..b28b3d0646c 100644 --- a/erpnext/public/js/shop_floor/shop_floor.js +++ b/erpnext/public/js/shop_floor/shop_floor.js @@ -786,6 +786,8 @@ class ShopFloor { pending = flt(jc.pending_qty); } + const qty_with_uom = (qty) => `${flt(qty)} ${jc.stock_uom || ""}`.trim(); + const fields = [ { fieldtype: "Float", @@ -819,7 +821,9 @@ class ShopFloor { flt(d.get_value("for_quantity")) - flt(d.get_value("process_loss_qty")); d.set_value("completed_qty", max_completed_qty); frappe.throw( - __("Completed Quantity cannot be greater than {0}", [max_completed_qty]) + __("Completed Quantity cannot be greater than {0}", [ + qty_with_uom(max_completed_qty), + ]) ); } @@ -845,7 +849,9 @@ class ShopFloor { d.set_value("pending_qty", 0); frappe.throw( __("Pending Quantity cannot be greater than {0}", [ - flt(d.get_value("for_quantity")) - flt(d.get_value("completed_qty")), + qty_with_uom( + flt(d.get_value("for_quantity")) - flt(d.get_value("completed_qty")) + ), ]) ); } @@ -872,7 +878,9 @@ class ShopFloor { d.set_value("process_loss_qty", 0); frappe.throw( __("Process Loss Quantity cannot be greater than {0}", [ - flt(d.get_value("for_quantity")) - flt(d.get_value("completed_qty")), + qty_with_uom( + flt(d.get_value("for_quantity")) - flt(d.get_value("completed_qty")) + ), ]) ); }