mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-29 14:48:26 +00:00
fix: support quality inspection for stock entry by purpose
Fetch QI items by warehouse direction per inspection_type, require QI on the correct rows per stock entry purpose (finished good for Manufacture, inward goods for Receipt/Repack, outgoing rows for issue/transfer), and show the QI field only on those rows.
This commit is contained in:
@@ -405,7 +405,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
|||||||
}
|
}
|
||||||
|
|
||||||
const incoming_doctypes = ["Purchase Receipt", "Purchase Invoice", "Subcontracting Receipt"];
|
const incoming_doctypes = ["Purchase Receipt", "Purchase Invoice", "Subcontracting Receipt"];
|
||||||
const incoming_purposes = ["Manufacture", "Material Receipt"];
|
const incoming_purposes = ["Manufacture", "Material Receipt", "Repack"];
|
||||||
const inspection_type =
|
const inspection_type =
|
||||||
incoming_doctypes.includes(this.frm.doc.doctype) ||
|
incoming_doctypes.includes(this.frm.doc.doctype) ||
|
||||||
(this.frm.doc.doctype === "Stock Entry" && incoming_purposes.includes(this.frm.doc.purpose))
|
(this.frm.doc.doctype === "Stock Entry" && incoming_purposes.includes(this.frm.doc.purpose))
|
||||||
@@ -2967,7 +2967,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
|||||||
|
|
||||||
const me = this;
|
const me = this;
|
||||||
const incoming_doctypes = ["Purchase Receipt", "Purchase Invoice", "Subcontracting Receipt"];
|
const incoming_doctypes = ["Purchase Receipt", "Purchase Invoice", "Subcontracting Receipt"];
|
||||||
const incoming_purposes = ["Manufacture", "Material Receipt"];
|
const incoming_purposes = ["Manufacture", "Material Receipt", "Repack"];
|
||||||
const inspection_type =
|
const inspection_type =
|
||||||
incoming_doctypes.includes(this.frm.doc.doctype) ||
|
incoming_doctypes.includes(this.frm.doc.doctype) ||
|
||||||
(this.frm.doc.doctype === "Stock Entry" && incoming_purposes.includes(this.frm.doc.purpose))
|
(this.frm.doc.doctype === "Stock Entry" && incoming_purposes.includes(this.frm.doc.purpose))
|
||||||
@@ -3065,13 +3065,20 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
|||||||
}
|
}
|
||||||
|
|
||||||
has_inspection_required(item) {
|
has_inspection_required(item) {
|
||||||
if (this.frm.doc.doctype === "Stock Entry" && this.frm.doc.purpose == "Manufacture") {
|
if (item.quality_inspection) {
|
||||||
if (item.is_finished_item && !item.quality_inspection) {
|
return false;
|
||||||
return true;
|
}
|
||||||
}
|
if (this.frm.doc.doctype !== "Stock Entry") {
|
||||||
} else if (!item.quality_inspection) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
const purpose = this.frm.doc.purpose;
|
||||||
|
if (purpose === "Manufacture") {
|
||||||
|
return !!item.is_finished_item;
|
||||||
|
}
|
||||||
|
if (["Material Receipt", "Repack"].includes(purpose)) {
|
||||||
|
return !!item.t_warehouse;
|
||||||
|
}
|
||||||
|
return !!item.s_warehouse && item.s_warehouse !== item.t_warehouse;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_method_for_payment() {
|
get_method_for_payment() {
|
||||||
|
|||||||
@@ -387,12 +387,29 @@ def item_query(doctype: Any, txt: str | None, searchfield: Any, start: int, page
|
|||||||
]
|
]
|
||||||
|
|
||||||
if reference_doctype == "Stock Entry":
|
if reference_doctype == "Stock Entry":
|
||||||
my_filters.extend(
|
if filters.get("inspection_type") == "Incoming":
|
||||||
[
|
purpose = frappe.db.get_value("Stock Entry", filters.get("reference_name"), "purpose")
|
||||||
"and",
|
if purpose == "Manufacture":
|
||||||
["items.t_warehouse", "is", "not set"],
|
my_filters.extend(
|
||||||
]
|
[
|
||||||
)
|
"and",
|
||||||
|
["items.is_finished_item", "=", 1],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
my_filters.extend(
|
||||||
|
[
|
||||||
|
"and",
|
||||||
|
["items.t_warehouse", "is", "set"],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
elif filters.get("inspection_type") == "Outgoing":
|
||||||
|
my_filters.extend(
|
||||||
|
[
|
||||||
|
"and",
|
||||||
|
["items.s_warehouse", "is", "set"],
|
||||||
|
]
|
||||||
|
)
|
||||||
elif filters.get("inspection_type") != "In Process":
|
elif filters.get("inspection_type") != "In Process":
|
||||||
my_filters.extend(
|
my_filters.extend(
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -199,6 +199,17 @@ frappe.ui.form.on("Stock Entry", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
setup_quality_inspection: function (frm) {
|
setup_quality_inspection: function (frm) {
|
||||||
|
const incoming_purposes = ["Manufacture", "Material Receipt", "Repack"];
|
||||||
|
|
||||||
|
// Show the Quality Inspection field only on rows that require inspection.
|
||||||
|
frm.get_docfield("items", "quality_inspection").depends_on = (row) =>
|
||||||
|
frm.doc.inspection_required &&
|
||||||
|
(frm.doc.purpose === "Manufacture"
|
||||||
|
? row.is_finished_item
|
||||||
|
: incoming_purposes.includes(frm.doc.purpose)
|
||||||
|
? row.t_warehouse
|
||||||
|
: row.s_warehouse && row.s_warehouse !== row.t_warehouse);
|
||||||
|
|
||||||
if (!frm.doc.inspection_required) {
|
if (!frm.doc.inspection_required) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -216,7 +227,6 @@ frappe.ui.form.on("Stock Entry", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let quality_inspection_field = frm.get_docfield("items", "quality_inspection");
|
let quality_inspection_field = frm.get_docfield("items", "quality_inspection");
|
||||||
const incoming_purposes = ["Manufacture", "Material Receipt"];
|
|
||||||
quality_inspection_field.get_route_options_for_new_doc = function (row) {
|
quality_inspection_field.get_route_options_for_new_doc = function (row) {
|
||||||
if (frm.is_new()) return {};
|
if (frm.is_new()) return {};
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -324,7 +324,6 @@
|
|||||||
"options": "Batch"
|
"options": "Batch"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:parent.inspection_required && doc.t_warehouse",
|
|
||||||
"fieldname": "quality_inspection",
|
"fieldname": "quality_inspection",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Quality Inspection",
|
"label": "Quality Inspection",
|
||||||
@@ -679,7 +678,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2026-06-01 10:00:00.000000",
|
"modified": "2026-06-25 11:39:55.152526",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Stock Entry Detail",
|
"name": "Stock Entry Detail",
|
||||||
|
|||||||
@@ -49,8 +49,16 @@ class QualityInspectionService:
|
|||||||
"Item", row.item_code, inspection_required_fieldname
|
"Item", row.item_code, inspection_required_fieldname
|
||||||
):
|
):
|
||||||
qi_required = True
|
qi_required = True
|
||||||
elif self.doc.doctype == "Stock Entry" and row.t_warehouse:
|
elif self.doc.doctype == "Stock Entry":
|
||||||
qi_required = True # inward stock needs inspection
|
if self.doc.purpose == "Manufacture":
|
||||||
|
# only the finished good needs inspection
|
||||||
|
if row.is_finished_item:
|
||||||
|
qi_required = True
|
||||||
|
elif self.doc.purpose in ["Material Receipt", "Repack"]:
|
||||||
|
if row.t_warehouse:
|
||||||
|
qi_required = True
|
||||||
|
elif row.s_warehouse and row.s_warehouse != row.t_warehouse:
|
||||||
|
qi_required = True
|
||||||
|
|
||||||
if row.get("secondary_item_type") or row.get("is_legacy_scrap_item"):
|
if row.get("secondary_item_type") or row.get("is_legacy_scrap_item"):
|
||||||
continue
|
continue
|
||||||
|
|||||||
Reference in New Issue
Block a user