mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-28 06:08:25 +00:00
Merge pull request #57387 from mihir-kandoi/drop-job-card-operation-row-number
refactor: drop unused operation_row_number field from Job Card
This commit is contained in:
@@ -172,8 +172,6 @@ frappe.ui.form.on("Job Card", {
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
frm.trigger("toggle_operation_number");
|
|
||||||
|
|
||||||
const is_timer_running = frm.events.setup_job_action_buttons(frm, has_items);
|
const is_timer_running = frm.events.setup_job_action_buttons(frm, has_items);
|
||||||
|
|
||||||
if (!is_timer_running) {
|
if (!is_timer_running) {
|
||||||
@@ -498,45 +496,46 @@ frappe.ui.form.on("Job Card", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
operation(frm) {
|
operation(frm) {
|
||||||
frm.trigger("toggle_operation_number");
|
if (frm.doc.operation_id) {
|
||||||
|
frm.set_value("operation_id", "");
|
||||||
if (frm.doc.operation && frm.doc.work_order) {
|
|
||||||
frappe.call({
|
|
||||||
method: "erpnext.manufacturing.doctype.job_card.job_card.get_operation_details",
|
|
||||||
args: {
|
|
||||||
work_order: frm.doc.work_order,
|
|
||||||
operation: frm.doc.operation,
|
|
||||||
},
|
|
||||||
callback(r) {
|
|
||||||
if (!r.message) return;
|
|
||||||
|
|
||||||
if (r.message.length == 1) {
|
|
||||||
frm.set_value("operation_id", r.message[0].name);
|
|
||||||
} else {
|
|
||||||
const args = r.message.map((row) => ({ label: row.idx, value: row.name }));
|
|
||||||
const description = __("Operation {0} added multiple times in the work order {1}", [
|
|
||||||
frm.doc.operation,
|
|
||||||
frm.doc.work_order,
|
|
||||||
]);
|
|
||||||
frm.set_df_property("operation_row_number", "options", args);
|
|
||||||
frm.set_df_property("operation_row_number", "description", description);
|
|
||||||
}
|
|
||||||
|
|
||||||
frm.trigger("toggle_operation_number");
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
operation_row_number(frm) {
|
if (!frm.doc.operation || !frm.doc.work_order) return;
|
||||||
if (frm.doc.operation_row_number) {
|
|
||||||
frm.set_value("operation_id", frm.doc.operation_row_number);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
toggle_operation_number(frm) {
|
const { operation, work_order } = frm.doc;
|
||||||
frm.toggle_display("operation_row_number", !frm.doc.operation_id && frm.doc.operation);
|
const is_current = () => frm.doc.operation === operation && frm.doc.work_order === work_order;
|
||||||
frm.toggle_reqd("operation_row_number", !frm.doc.operation_id && frm.doc.operation);
|
|
||||||
|
frappe.call({
|
||||||
|
method: "erpnext.manufacturing.doctype.job_card.job_card.get_operation_details",
|
||||||
|
args: { work_order, operation },
|
||||||
|
callback(r) {
|
||||||
|
if (!is_current() || !r.message || !r.message.length) return;
|
||||||
|
|
||||||
|
if (r.message.length == 1) {
|
||||||
|
frm.set_value("operation_id", r.message[0].name);
|
||||||
|
} else {
|
||||||
|
frappe.prompt(
|
||||||
|
{
|
||||||
|
fieldname: "operation_row",
|
||||||
|
fieldtype: "Select",
|
||||||
|
label: __("Operation Row"),
|
||||||
|
options: r.message.map((row) => ({ label: row.idx, value: row.name })),
|
||||||
|
reqd: 1,
|
||||||
|
description: __("Operation {0} is added multiple times in the work order {1}", [
|
||||||
|
operation,
|
||||||
|
work_order,
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
(values) => {
|
||||||
|
if (is_current()) {
|
||||||
|
frm.set_value("operation_id", values.operation_row);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
__("Select Operation Row")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
make_time_log(frm, args) {
|
make_time_log(frm, args) {
|
||||||
|
|||||||
@@ -92,7 +92,6 @@
|
|||||||
"operation_row_id",
|
"operation_row_id",
|
||||||
"amended_from",
|
"amended_from",
|
||||||
"column_break_xhzg",
|
"column_break_xhzg",
|
||||||
"operation_row_number",
|
|
||||||
"operation_id",
|
"operation_id",
|
||||||
"sequence_id",
|
"sequence_id",
|
||||||
"section_break_jcmx",
|
"section_break_jcmx",
|
||||||
@@ -324,11 +323,6 @@
|
|||||||
"label": "Item Name",
|
"label": "Item Name",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "operation_row_number",
|
|
||||||
"fieldtype": "Select",
|
|
||||||
"label": "Operation Row Number"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "sequence_id",
|
"fieldname": "sequence_id",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
@@ -695,7 +689,7 @@
|
|||||||
"grid_page_length": 50,
|
"grid_page_length": 50,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2026-06-20 17:39:42.293242",
|
"modified": "2026-07-23 12:00:00.000000",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Job Card",
|
"name": "Job Card",
|
||||||
|
|||||||
@@ -45,10 +45,6 @@ class OverlapError(frappe.ValidationError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OperationMismatchError(frappe.ValidationError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class OperationSequenceError(frappe.ValidationError):
|
class OperationSequenceError(frappe.ValidationError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -106,7 +102,6 @@ class JobCard(Document):
|
|||||||
operation: DF.Link
|
operation: DF.Link
|
||||||
operation_id: DF.Data | None
|
operation_id: DF.Data | None
|
||||||
operation_row_id: DF.Int
|
operation_row_id: DF.Int
|
||||||
operation_row_number: DF.Literal[None]
|
|
||||||
pending_qty: DF.Float
|
pending_qty: DF.Float
|
||||||
posting_date: DF.Date | None
|
posting_date: DF.Date | None
|
||||||
process_loss_qty: DF.Float
|
process_loss_qty: DF.Float
|
||||||
@@ -168,7 +163,7 @@ class JobCard(Document):
|
|||||||
self.validate_time_logs()
|
self.validate_time_logs()
|
||||||
self.validate_on_hold()
|
self.validate_on_hold()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
self.validate_operation_id()
|
self.set_operation_id()
|
||||||
self.validate_sequence_id()
|
self.validate_sequence_id()
|
||||||
self.set_sub_operations()
|
self.set_sub_operations()
|
||||||
self.update_sub_operation_status()
|
self.update_sub_operation_status()
|
||||||
@@ -1344,21 +1339,33 @@ class JobCard(Document):
|
|||||||
if not self.wip_warehouse:
|
if not self.wip_warehouse:
|
||||||
self.wip_warehouse = frappe.get_cached_value("Company", self.company, "default_wip_warehouse")
|
self.wip_warehouse = frappe.get_cached_value("Company", self.company, "default_wip_warehouse")
|
||||||
|
|
||||||
def validate_operation_id(self):
|
def set_operation_id(self):
|
||||||
if (
|
if not (self.work_order and self.operation):
|
||||||
self.get("operation_id")
|
return
|
||||||
and self.get("operation_row_number")
|
|
||||||
and self.operation
|
if self.operation_id and self.docstatus != 0:
|
||||||
and self.work_order
|
return
|
||||||
and frappe.get_cached_value("Work Order Operation", self.operation_row_number, "name")
|
|
||||||
!= self.operation_id
|
operation_rows = frappe.get_all(
|
||||||
):
|
"Work Order Operation",
|
||||||
work_order = bold(get_link_to_form("Work Order", self.work_order))
|
filters={"parent": self.work_order, "operation": self.operation},
|
||||||
|
pluck="name",
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.operation_id:
|
||||||
|
if operation_rows and self.operation_id not in operation_rows:
|
||||||
|
frappe.throw(
|
||||||
|
_("Operation {0} does not belong to the work order {1}").format(
|
||||||
|
bold(self.operation), get_link_to_form("Work Order", self.work_order)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif len(operation_rows) == 1:
|
||||||
|
self.operation_id = operation_rows[0]
|
||||||
|
elif operation_rows and self.docstatus == 0:
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
_("Operation {0} does not belong to the work order {1}").format(
|
_(
|
||||||
bold(self.operation), work_order
|
"Operation {0} is added multiple times in the work order {1}. Please select the operation row."
|
||||||
),
|
).format(bold(self.operation), get_link_to_form("Work Order", self.work_order))
|
||||||
OperationMismatchError,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ from frappe.utils.data import add_to_date, now, today
|
|||||||
|
|
||||||
from erpnext.manufacturing.doctype.job_card.job_card import (
|
from erpnext.manufacturing.doctype.job_card.job_card import (
|
||||||
JobCardOverTransferError,
|
JobCardOverTransferError,
|
||||||
OperationMismatchError,
|
|
||||||
OverlapError,
|
OverlapError,
|
||||||
)
|
)
|
||||||
from erpnext.manufacturing.doctype.job_card.mapper import (
|
from erpnext.manufacturing.doctype.job_card.mapper import (
|
||||||
@@ -149,18 +148,39 @@ class TestJobCard(ERPNextTestSuite):
|
|||||||
)
|
)
|
||||||
self.assertRaises(frappe.ValidationError, job_card_doc.submit)
|
self.assertRaises(frappe.ValidationError, job_card_doc.submit)
|
||||||
|
|
||||||
def test_job_card_operations(self):
|
def test_set_operation_id(self):
|
||||||
job_cards = frappe.get_all(
|
work_order = make_wo_order_test_record(item="_Test FG Item 2", qty=2, do_not_submit=1)
|
||||||
"Job Card", filters={"work_order": self.work_order.name}, fields=["operation_id", "name"]
|
operation_row = work_order.operations[0]
|
||||||
|
|
||||||
|
job_card = frappe.new_doc("Job Card")
|
||||||
|
job_card.work_order = work_order.name
|
||||||
|
job_card.operation = operation_row.operation
|
||||||
|
job_card.set_operation_id()
|
||||||
|
self.assertEqual(job_card.operation_id, operation_row.name)
|
||||||
|
|
||||||
|
work_order.append(
|
||||||
|
"operations",
|
||||||
|
{
|
||||||
|
"operation": operation_row.operation,
|
||||||
|
"workstation": operation_row.workstation,
|
||||||
|
"time_in_mins": operation_row.time_in_mins,
|
||||||
|
"hour_rate": operation_row.hour_rate,
|
||||||
|
"sequence_id": work_order.operations[-1].sequence_id,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
work_order.save()
|
||||||
|
|
||||||
if job_cards:
|
job_card = frappe.new_doc("Job Card")
|
||||||
job_card = job_cards[0]
|
job_card.work_order = work_order.name
|
||||||
frappe.db.set_value("Job Card", job_card.name, "operation_row_number", job_card.operation_id)
|
job_card.operation = operation_row.operation
|
||||||
|
self.assertRaises(frappe.ValidationError, job_card.set_operation_id)
|
||||||
|
|
||||||
doc = frappe.get_doc("Job Card", job_card.name)
|
job_card.operation_id = "bogus-row"
|
||||||
doc.operation_id = "Test Data"
|
self.assertRaises(frappe.ValidationError, job_card.set_operation_id)
|
||||||
self.assertRaises(OperationMismatchError, doc.save)
|
|
||||||
|
job_card.operation_id = work_order.operations[-1].name
|
||||||
|
job_card.set_operation_id()
|
||||||
|
self.assertEqual(job_card.operation_id, work_order.operations[-1].name)
|
||||||
|
|
||||||
def test_job_card_with_different_work_station(self):
|
def test_job_card_with_different_work_station(self):
|
||||||
job_cards = frappe.get_all(
|
job_cards = frappe.get_all(
|
||||||
|
|||||||
Reference in New Issue
Block a user