mirror of
https://github.com/frappe/erpnext.git
synced 2026-02-12 17:23:38 +00:00
fix: Added validation for quality inspection in job card
(cherry picked from commit 46b4cf3add)
# Conflicts:
# erpnext/manufacturing/doctype/job_card/job_card.py
# erpnext/manufacturing/doctype/job_card/test_job_card.py
This commit is contained in:
@@ -24,6 +24,14 @@ from frappe.utils import (
|
||||
time_diff_in_seconds,
|
||||
)
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
from erpnext.controllers.stock_controller import (
|
||||
QualityInspectionNotSubmittedError,
|
||||
QualityInspectionRejectedError,
|
||||
)
|
||||
from erpnext.manufacturing.doctype.bom.bom import add_additional_cost, get_bom_items_as_dict
|
||||
>>>>>>> 46b4cf3add (fix: Added validation for quality inspection in job card)
|
||||
from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import (
|
||||
get_mins_between_operations,
|
||||
)
|
||||
@@ -669,6 +677,7 @@ class JobCard(Document):
|
||||
self.set_process_loss()
|
||||
|
||||
def on_submit(self):
|
||||
self.validate_inspection()
|
||||
self.validate_transfer_qty()
|
||||
self.validate_job_card()
|
||||
self.update_work_order()
|
||||
@@ -678,6 +687,66 @@ class JobCard(Document):
|
||||
self.update_work_order()
|
||||
self.set_transferred_qty()
|
||||
|
||||
def validate_inspection(self):
|
||||
action_submit, action_reject = frappe.get_single_value(
|
||||
"Stock Settings",
|
||||
["action_if_quality_inspection_is_not_submitted", "action_if_quality_inspection_is_rejected"],
|
||||
)
|
||||
|
||||
item = self.finished_good or self.production_item
|
||||
bom_inspection_required = frappe.db.get_value(
|
||||
"BOM", self.semi_fg_bom or self.bom_no, "inspection_required"
|
||||
)
|
||||
if bom_inspection_required:
|
||||
if not self.quality_inspection:
|
||||
frappe.throw(
|
||||
_(
|
||||
"Quality Inspection is required for the item {0} before completing the job card {1}"
|
||||
).format(get_link_to_form("Item", item), bold(self.name))
|
||||
)
|
||||
qa_status, docstatus = frappe.db.get_value(
|
||||
"Quality Inspection", self.quality_inspection, ["status", "docstatus"]
|
||||
)
|
||||
|
||||
if docstatus != 1:
|
||||
if action_submit == "Stop":
|
||||
frappe.throw(
|
||||
_("Quality Inspection {0} is not submitted for the item: {1}").format(
|
||||
get_link_to_form("Quality Inspection", self.quality_inspection),
|
||||
get_link_to_form("Item", item),
|
||||
),
|
||||
title=_("Inspection Submission"),
|
||||
exc=QualityInspectionNotSubmittedError,
|
||||
)
|
||||
else:
|
||||
frappe.msgprint(
|
||||
_("Quality Inspection {0} is not submitted for the item: {1}").format(
|
||||
get_link_to_form("Quality Inspection", self.quality_inspection),
|
||||
get_link_to_form("Item", item),
|
||||
),
|
||||
alert=True,
|
||||
indicator="orange",
|
||||
)
|
||||
elif qa_status == "Rejected":
|
||||
if action_reject == "Stop":
|
||||
frappe.throw(
|
||||
_("Quality Inspection {0} is rejected for the item: {1}").format(
|
||||
get_link_to_form("Quality Inspection", self.quality_inspection),
|
||||
get_link_to_form("Item", item),
|
||||
),
|
||||
title=_("Inspection Rejected"),
|
||||
exc=QualityInspectionRejectedError,
|
||||
)
|
||||
else:
|
||||
frappe.msgprint(
|
||||
_("Quality Inspection {0} is rejected for the item: {1}").format(
|
||||
get_link_to_form("Quality Inspection", self.quality_inspection),
|
||||
get_link_to_form("Item", item),
|
||||
),
|
||||
alert=True,
|
||||
indicator="orange",
|
||||
)
|
||||
|
||||
def validate_transfer_qty(self):
|
||||
if not self.is_corrective_job_card and self.items and self.transferred_qty < self.for_quantity:
|
||||
frappe.throw(
|
||||
|
||||
@@ -21,8 +21,9 @@ from erpnext.manufacturing.doctype.job_card.job_card import (
|
||||
make_stock_entry as make_stock_entry_from_jc,
|
||||
)
|
||||
from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record
|
||||
from erpnext.manufacturing.doctype.work_order.work_order import WorkOrder
|
||||
from erpnext.manufacturing.doctype.work_order.work_order import WorkOrder, make_work_order
|
||||
from erpnext.manufacturing.doctype.workstation.test_workstation import make_workstation
|
||||
from erpnext.stock.doctype.item.test_item import create_item
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||
|
||||
|
||||
@@ -58,6 +59,50 @@ class TestJobCard(FrappeTestCase):
|
||||
def tearDown(self):
|
||||
frappe.db.rollback()
|
||||
|
||||
def test_quality_inspection_mandatory_check(self):
|
||||
from erpnext.manufacturing.doctype.operation.test_operation import make_operation
|
||||
|
||||
raw = create_item("Fabric-Raw")
|
||||
cut_fg = create_item("Cut-Fabric-SFG")
|
||||
stitch_fg = create_item("Stitched-TShirt-SFG")
|
||||
final = create_item("Finished-TShirt")
|
||||
|
||||
row = {"operation": "Cutting", "workstation": "_Test Workstation 1"}
|
||||
|
||||
cutting = make_operation(row)
|
||||
stitching = make_operation({"operation": "Stitching", "workstation": "_Test Workstation 1"})
|
||||
ironing = make_operation({"operation": "Ironing", "workstation": "_Test Workstation 1"})
|
||||
|
||||
cut_bom = create_semi_fg_bom(cut_fg.name, raw.name, inspection_required=1)
|
||||
stitch_bom = create_semi_fg_bom(stitch_fg.name, cut_fg.name, inspection_required=0)
|
||||
final_bom = frappe.new_doc("BOM")
|
||||
final_bom.item = final.name
|
||||
final_bom.quantity = 1
|
||||
final_bom.with_operations = 1
|
||||
final_bom.track_semi_finished_goods = 1
|
||||
final_bom.append("items", {"item_code": raw.name, "qty": 1})
|
||||
final_bom.append(
|
||||
"operations", {"operation": cutting.name, "workstation": "_Test Workstation 1", "bom_no": cut_bom}
|
||||
)
|
||||
final_bom.append(
|
||||
"operations",
|
||||
{"operation": stitching.name, "workstation": "_Test Workstation 1", "bom_no": stitch_bom},
|
||||
)
|
||||
final_bom.append("operations", {"operation": ironing.name, "workstation": "_Test Workstation 1"})
|
||||
final_bom.insert()
|
||||
final_bom.submit()
|
||||
work_order = make_work_order(final_bom.name, final.name, 1, variant_items=[], use_multi_level_bom=0)
|
||||
work_order.wip_warehouse = "Work In Progress - WP"
|
||||
work_order.fg_warehouse = "Finished Goods - WP"
|
||||
work_order.scrap_warehouse = "All Warehouses - WP"
|
||||
for operation in work_order.operations:
|
||||
operation.time_in_mins = 60
|
||||
|
||||
work_order.submit()
|
||||
job_card = frappe.get_all("Job Card", filters={"work_order": work_order.name, "operation": "Cutting"})
|
||||
job_card_doc = frappe.get_doc("Job Card", job_card[0].name)
|
||||
self.assertRaises(frappe.ValidationError, job_card_doc.submit)
|
||||
|
||||
def test_job_card_operations(self):
|
||||
job_cards = frappe.get_all(
|
||||
"Job Card", filters={"work_order": self.work_order.name}, fields=["operation_id", "name"]
|
||||
@@ -750,6 +795,7 @@ def make_wo_with_transfer_against_jc():
|
||||
return work_order
|
||||
|
||||
|
||||
<<<<<<< HEAD
|
||||
def make_bom_for_jc_tests():
|
||||
test_records = frappe.get_test_records("BOM")
|
||||
bom = frappe.copy_doc(test_records[2])
|
||||
@@ -758,3 +804,13 @@ def make_bom_for_jc_tests():
|
||||
bom.items[0].uom = "_Test UOM 1"
|
||||
bom.items[0].conversion_factor = 5
|
||||
bom.insert()
|
||||
=======
|
||||
def create_semi_fg_bom(semi_fg_item, raw_item, inspection_required):
|
||||
bom = frappe.new_doc("BOM")
|
||||
bom.item = semi_fg_item
|
||||
bom.quantity = 1
|
||||
bom.inspection_required = inspection_required
|
||||
bom.append("items", {"item_code": raw_item, "qty": 1})
|
||||
bom.submit()
|
||||
return bom.name
|
||||
>>>>>>> 46b4cf3add (fix: Added validation for quality inspection in job card)
|
||||
|
||||
Reference in New Issue
Block a user