fix: user created manual job card not linking job card operations with work order operations
This commit is contained in:
parent
e7ab53a711
commit
a5963e1b2c
@ -2,6 +2,17 @@
|
|||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on('Job Card', {
|
frappe.ui.form.on('Job Card', {
|
||||||
|
setup: function(frm) {
|
||||||
|
frm.set_query('operation', function() {
|
||||||
|
return {
|
||||||
|
query: 'erpnext.manufacturing.doctype.job_card.job_card.get_operations',
|
||||||
|
filters: {
|
||||||
|
'work_order': frm.doc.work_order
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
frappe.flags.pause_job = 0;
|
frappe.flags.pause_job = 0;
|
||||||
frappe.flags.resume_job = 0;
|
frappe.flags.resume_job = 0;
|
||||||
@ -20,12 +31,60 @@ frappe.ui.form.on('Job Card', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frm.trigger("toggle_operation_number");
|
||||||
|
|
||||||
if (frm.doc.docstatus == 0 && (frm.doc.for_quantity > frm.doc.total_completed_qty || !frm.doc.for_quantity)
|
if (frm.doc.docstatus == 0 && (frm.doc.for_quantity > frm.doc.total_completed_qty || !frm.doc.for_quantity)
|
||||||
&& (!frm.doc.items.length || frm.doc.for_quantity == frm.doc.transferred_qty)) {
|
&& (!frm.doc.items || !frm.doc.items.length || frm.doc.for_quantity == frm.doc.transferred_qty)) {
|
||||||
frm.trigger("prepare_timer_buttons");
|
frm.trigger("prepare_timer_buttons");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
operation: function(frm) {
|
||||||
|
frm.trigger("toggle_operation_number");
|
||||||
|
|
||||||
|
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: function (r) {
|
||||||
|
if (r.message) {
|
||||||
|
if (r.message.length == 1) {
|
||||||
|
frm.set_value("operation_id", r.message[0].name);
|
||||||
|
} else {
|
||||||
|
let args = [];
|
||||||
|
|
||||||
|
r.message.forEach((row) => {
|
||||||
|
args.push({ "label": row.idx, "value": row.name });
|
||||||
|
});
|
||||||
|
|
||||||
|
let 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_row_number) {
|
||||||
|
frm.set_value("operation_id", frm.doc.operation_row_number);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
toggle_operation_number(frm) {
|
||||||
|
frm.toggle_display("operation_row_number", !frm.doc.operation_id && frm.doc.operation);
|
||||||
|
frm.toggle_reqd("operation_row_number", !frm.doc.operation_id && frm.doc.operation);
|
||||||
|
},
|
||||||
|
|
||||||
prepare_timer_buttons: function(frm) {
|
prepare_timer_buttons: function(frm) {
|
||||||
frm.trigger("make_dashboard");
|
frm.trigger("make_dashboard");
|
||||||
if (!frm.doc.job_started) {
|
if (!frm.doc.job_started) {
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
"bom_no",
|
"bom_no",
|
||||||
"workstation",
|
"workstation",
|
||||||
"operation",
|
"operation",
|
||||||
|
"operation_row_number",
|
||||||
"column_break_4",
|
"column_break_4",
|
||||||
"posting_date",
|
"posting_date",
|
||||||
"company",
|
"company",
|
||||||
@ -291,11 +292,15 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "operation_row_number",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"label": "Operation Row Number"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"modified": "2020-08-24 15:21:21.398267",
|
||||||
"modified": "2020-04-20 15:14:00.273441",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Job Card",
|
"name": "Job Card",
|
||||||
@ -347,7 +352,6 @@
|
|||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"title_field": "operation",
|
"title_field": "operation",
|
||||||
|
|||||||
@ -15,10 +15,13 @@ from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings
|
|||||||
|
|
||||||
class OverlapError(frappe.ValidationError): pass
|
class OverlapError(frappe.ValidationError): pass
|
||||||
|
|
||||||
|
class OperationMismatchError(frappe.ValidationError): pass
|
||||||
|
|
||||||
class JobCard(Document):
|
class JobCard(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_time_logs()
|
self.validate_time_logs()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
|
self.validate_operation_id()
|
||||||
|
|
||||||
def validate_time_logs(self):
|
def validate_time_logs(self):
|
||||||
self.total_completed_qty = 0.0
|
self.total_completed_qty = 0.0
|
||||||
@ -306,6 +309,37 @@ class JobCard(Document):
|
|||||||
if update_status:
|
if update_status:
|
||||||
self.db_set('status', self.status)
|
self.db_set('status', self.status)
|
||||||
|
|
||||||
|
def validate_operation_id(self):
|
||||||
|
if (self.get("operation_id") and self.get("operation_row_number") and self.operation and self.work_order and
|
||||||
|
frappe.get_cached_value("Work Order Operation", self.operation_row_number, "name") != self.operation_id):
|
||||||
|
work_order = frappe.bold(get_link_to_form("Work Order", self.work_order))
|
||||||
|
frappe.throw(_("Operation {0} does not belong to the work order {1}")
|
||||||
|
.format(frappe.bold(self.operation), work_order), OperationMismatchError)
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_operation_details(work_order, operation):
|
||||||
|
if work_order and operation:
|
||||||
|
return frappe.get_all("Work Order Operation", fields = ["name", "idx"],
|
||||||
|
filters = {
|
||||||
|
"parent": work_order,
|
||||||
|
"operation": operation
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_operations(doctype, txt, searchfield, start, page_len, filters):
|
||||||
|
if filters.get("work_order"):
|
||||||
|
args = {"parent": filters.get("work_order")}
|
||||||
|
if txt:
|
||||||
|
args["operation"] = ("like", "%{0}%".format(txt))
|
||||||
|
|
||||||
|
return frappe.get_all("Work Order Operation",
|
||||||
|
filters = args,
|
||||||
|
fields = ["distinct operation as operation"],
|
||||||
|
limit_start = start,
|
||||||
|
limit_page_length = page_len,
|
||||||
|
order_by="idx asc", as_list=1)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_material_request(source_name, target_doc=None):
|
def make_material_request(source_name, target_doc=None):
|
||||||
def update_item(obj, target, source_parent):
|
def update_item(obj, target, source_parent):
|
||||||
|
|||||||
@ -4,6 +4,28 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
import frappe
|
||||||
|
from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record
|
||||||
|
from erpnext.manufacturing.doctype.job_card.job_card import OperationMismatchError
|
||||||
|
|
||||||
class TestJobCard(unittest.TestCase):
|
class TestJobCard(unittest.TestCase):
|
||||||
pass
|
def test_job_card(self):
|
||||||
|
data = frappe.get_cached_value('BOM',
|
||||||
|
{'docstatus': 1, 'with_operations': 1, 'company': '_Test Company'}, ['name', 'item'])
|
||||||
|
|
||||||
|
if data:
|
||||||
|
bom, bom_item = data
|
||||||
|
|
||||||
|
work_order = make_wo_order_test_record(item=bom_item, qty=1, bom_no=bom)
|
||||||
|
|
||||||
|
job_cards = frappe.get_all('Job Card',
|
||||||
|
filters = {'work_order': work_order.name}, fields = ["operation_id", "name"])
|
||||||
|
|
||||||
|
if job_cards:
|
||||||
|
job_card = job_cards[0]
|
||||||
|
frappe.db.set_value("Job Card", job_card.name, "operation_row_number", job_card.operation_id)
|
||||||
|
|
||||||
|
doc = frappe.get_doc("Job Card", job_card.name)
|
||||||
|
doc.operation_id = "Test Data"
|
||||||
|
self.assertRaises(OperationMismatchError, doc.save)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user