mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-19 04:59:18 +00:00
feat: Value Based and Numeric Quality Inspection
- Acceptance Formula is optional - Choose between Value based and Numeric QI - If numeric, select single or multiple readings - Added Min, Max and Mean Values for numeric inspection to avoid formula usage - Deprecated code cleanup in js file
This commit is contained in:
@@ -8,8 +8,14 @@
|
|||||||
"field_order": [
|
"field_order": [
|
||||||
"specification",
|
"specification",
|
||||||
"value",
|
"value",
|
||||||
|
"value_based",
|
||||||
|
"single_reading",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"acceptance_formula"
|
"formula_based_criteria",
|
||||||
|
"acceptance_formula",
|
||||||
|
"min_value",
|
||||||
|
"max_value",
|
||||||
|
"mean_value"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -24,10 +30,11 @@
|
|||||||
"width": "200px"
|
"width": "200px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:(!doc.formula_based_criteria && doc.value_based)",
|
||||||
"fieldname": "value",
|
"fieldname": "value",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Acceptance Criteria",
|
"label": "Acceptance Criteria Value",
|
||||||
"oldfieldname": "value",
|
"oldfieldname": "value",
|
||||||
"oldfieldtype": "Data"
|
"oldfieldtype": "Data"
|
||||||
},
|
},
|
||||||
@@ -36,17 +43,56 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Simple Python formula based on numeric Readings.<br> Example 1: <b>reading_1 > 0.2 and reading_1 < 0.5</b><br>\nExample 2: <b>(reading_1 + reading_2) / 2 < 10</b>",
|
"depends_on": "formula_based_criteria",
|
||||||
|
"description": "Simple Python formula applied on Reading fields.<br> Numeric eg.: <b>reading_1 > 0.2 and reading_1 < 0.5</b><br>\nValue based eg.: <b>reading_value in (\"A\", \"B\", \"C)</b>",
|
||||||
"fieldname": "acceptance_formula",
|
"fieldname": "acceptance_formula",
|
||||||
"fieldtype": "Code",
|
"fieldtype": "Code",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Acceptance Criteria Formula"
|
"label": "Acceptance Criteria Formula"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "formula_based_criteria",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Formula Based Criteria"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"depends_on": "eval:!doc.value_based",
|
||||||
|
"fieldname": "single_reading",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Single Reading"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:(!doc.formula_based_criteria && !doc.single_reading && !doc.value_based)",
|
||||||
|
"fieldname": "mean_value",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"label": "Mean Value"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:(!doc.formula_based_criteria && !doc.value_based)",
|
||||||
|
"fieldname": "min_value",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"label": "Minimum Value"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:(!doc.formula_based_criteria && !doc.value_based)",
|
||||||
|
"fieldname": "max_value",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"label": "Maximum Value"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"description": "Non-numeric Inspection.",
|
||||||
|
"fieldname": "value_based",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Value Based"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-11-16 16:33:42.421842",
|
"modified": "2020-12-18 21:03:29.828723",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Item Quality Inspection Parameter",
|
"name": "Item Quality Inspection Parameter",
|
||||||
|
|||||||
@@ -4,6 +4,54 @@
|
|||||||
cur_frm.cscript.refresh = cur_frm.cscript.inspection_type;
|
cur_frm.cscript.refresh = cur_frm.cscript.inspection_type;
|
||||||
|
|
||||||
frappe.ui.form.on("Quality Inspection", {
|
frappe.ui.form.on("Quality Inspection", {
|
||||||
|
setup: function(frm) {
|
||||||
|
frm.set_query("batch_no", function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
"item": frm.doc.item_code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Serial No based on item_code
|
||||||
|
frm.set_query("item_serial_no", function() {
|
||||||
|
var filters = {};
|
||||||
|
if (frm.doc.item_code) {
|
||||||
|
filters = {
|
||||||
|
'item_code': frm.doc.item_code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { filters: filters }
|
||||||
|
});
|
||||||
|
|
||||||
|
// item code based on GRN/DN
|
||||||
|
frm.set_query("item_code", function(doc) {
|
||||||
|
let doctype = doc.reference_type;
|
||||||
|
|
||||||
|
if (doc.reference_type !== "Job Card") {
|
||||||
|
doctype = (doc.reference_type == "Stock Entry") ?
|
||||||
|
"Stock Entry Detail" : doc.reference_type + " Item";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doc.reference_type && doc.reference_name) {
|
||||||
|
let filters = {
|
||||||
|
"from": doctype,
|
||||||
|
"inspection_type": doc.inspection_type
|
||||||
|
};
|
||||||
|
|
||||||
|
if (doc.reference_type == doctype)
|
||||||
|
filters["reference_name"] = doc.reference_name;
|
||||||
|
else
|
||||||
|
filters["parent"] = doc.reference_name;
|
||||||
|
|
||||||
|
return {
|
||||||
|
query: "erpnext.stock.doctype.quality_inspection.quality_inspection.item_query",
|
||||||
|
filters: filters
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
item_code: function(frm) {
|
item_code: function(frm) {
|
||||||
if (frm.doc.item_code) {
|
if (frm.doc.item_code) {
|
||||||
return frm.call({
|
return frm.call({
|
||||||
@@ -26,55 +74,5 @@ frappe.ui.form.on("Quality Inspection", {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// item code based on GRN/DN
|
|
||||||
cur_frm.fields_dict['item_code'].get_query = function(doc, cdt, cdn) {
|
|
||||||
let doctype = doc.reference_type;
|
|
||||||
|
|
||||||
if (doc.reference_type !== "Job Card") {
|
|
||||||
doctype = (doc.reference_type == "Stock Entry") ?
|
|
||||||
"Stock Entry Detail" : doc.reference_type + " Item";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doc.reference_type && doc.reference_name) {
|
|
||||||
let filters = {
|
|
||||||
"from": doctype,
|
|
||||||
"inspection_type": doc.inspection_type
|
|
||||||
};
|
|
||||||
|
|
||||||
if (doc.reference_type == doctype)
|
|
||||||
filters["reference_name"] = doc.reference_name;
|
|
||||||
else
|
|
||||||
filters["parent"] = doc.reference_name;
|
|
||||||
|
|
||||||
return {
|
|
||||||
query: "erpnext.stock.doctype.quality_inspection.quality_inspection.item_query",
|
|
||||||
filters: filters
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Serial No based on item_code
|
|
||||||
cur_frm.fields_dict['item_serial_no'].get_query = function(doc, cdt, cdn) {
|
|
||||||
var filters = {};
|
|
||||||
if (doc.item_code) {
|
|
||||||
filters = {
|
|
||||||
'item_code': doc.item_code
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return { filters: filters }
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_frm.set_query("batch_no", function(doc) {
|
|
||||||
return {
|
|
||||||
filters: {
|
|
||||||
"item": doc.item_code
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
cur_frm.add_fetch('item_code', 'item_name', 'item_name');
|
|
||||||
cur_frm.add_fetch('item_code', 'description', 'description');
|
|
||||||
|
|
||||||
@@ -136,6 +136,7 @@
|
|||||||
"width": "50%"
|
"width": "50%"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"fetch_from": "item_code.item_name",
|
||||||
"fieldname": "item_name",
|
"fieldname": "item_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_global_search": 1,
|
"in_global_search": 1,
|
||||||
@@ -143,6 +144,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"fetch_from": "item_code.description",
|
||||||
"fieldname": "description",
|
"fieldname": "description",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Description",
|
"label": "Description",
|
||||||
@@ -236,7 +238,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-11-19 17:06:05.409963",
|
"modified": "2020-12-18 19:59:55.710300",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Quality Inspection",
|
"name": "Quality Inspection",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import frappe
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.model.mapper import get_mapped_doc
|
from frappe.model.mapper import get_mapped_doc
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt, cint
|
||||||
from erpnext.stock.doctype.quality_inspection_template.quality_inspection_template \
|
from erpnext.stock.doctype.quality_inspection_template.quality_inspection_template \
|
||||||
import get_template_details
|
import get_template_details
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ class QualityInspection(Document):
|
|||||||
self.get_item_specification_details()
|
self.get_item_specification_details()
|
||||||
|
|
||||||
if self.readings:
|
if self.readings:
|
||||||
self.set_status_based_on_acceptance_formula()
|
self.inspect_and_set_status()
|
||||||
|
|
||||||
def get_item_specification_details(self):
|
def get_item_specification_details(self):
|
||||||
if not self.quality_inspection_template:
|
if not self.quality_inspection_template:
|
||||||
@@ -29,9 +29,7 @@ class QualityInspection(Document):
|
|||||||
parameters = get_template_details(self.quality_inspection_template)
|
parameters = get_template_details(self.quality_inspection_template)
|
||||||
for d in parameters:
|
for d in parameters:
|
||||||
child = self.append('readings', {})
|
child = self.append('readings', {})
|
||||||
child.specification = d.specification
|
child.update(d)
|
||||||
child.value = d.value
|
|
||||||
child.acceptance_formula = d.acceptance_formula
|
|
||||||
child.status = "Accepted"
|
child.status = "Accepted"
|
||||||
|
|
||||||
def get_quality_inspection_template(self):
|
def get_quality_inspection_template(self):
|
||||||
@@ -76,28 +74,84 @@ class QualityInspection(Document):
|
|||||||
""".format(parent_doc=self.reference_type, child_doc=doctype),
|
""".format(parent_doc=self.reference_type, child_doc=doctype),
|
||||||
(quality_inspection, self.modified, self.reference_name, self.item_code))
|
(quality_inspection, self.modified, self.reference_name, self.item_code))
|
||||||
|
|
||||||
def set_status_based_on_acceptance_formula(self):
|
def inspect_and_set_status(self):
|
||||||
for reading in self.readings:
|
for reading in self.readings:
|
||||||
if not reading.acceptance_formula: continue
|
if reading.formula_based_criteria:
|
||||||
|
self.set_status_based_on_acceptance_formula(reading)
|
||||||
|
else:
|
||||||
|
self.set_status_based_on_acceptance_values(reading)
|
||||||
|
|
||||||
|
def set_status_based_on_acceptance_values(self, reading):
|
||||||
|
if cint(reading.value_based):
|
||||||
|
result = reading.get("reading_value") == reading.get("value")
|
||||||
|
else:
|
||||||
|
# numeric readings
|
||||||
|
if cint(reading.single_reading):
|
||||||
|
reading_1 = flt(reading.get("reading_1"))
|
||||||
|
result = flt(reading.get("min_value")) <= reading_1 <= flt(reading.get("max_value"))
|
||||||
|
else:
|
||||||
|
result = self.min_max_criteria_passed(reading) and self.mean_criteria_passed(reading)
|
||||||
|
|
||||||
|
reading.status = "Accepted" if result else "Rejected"
|
||||||
|
|
||||||
|
def min_max_criteria_passed(self, reading):
|
||||||
|
"""Determine whether all readings fall in the acceptable range."""
|
||||||
|
for i in range(1, 11):
|
||||||
|
reading_field = reading.get("reading_" + str(i))
|
||||||
|
if reading_field is not None:
|
||||||
|
result = flt(reading.get("min_value")) <= flt(reading_field) <= flt(reading.get("max_value"))
|
||||||
|
if not result: return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def mean_criteria_passed(self, reading):
|
||||||
|
"""Determine whether mean of all readings is acceptable."""
|
||||||
|
if reading.get("mean_value"):
|
||||||
|
from statistics import mean
|
||||||
|
readings_list = []
|
||||||
|
|
||||||
condition = reading.acceptance_formula
|
|
||||||
data = {}
|
|
||||||
for i in range(1, 11):
|
for i in range(1, 11):
|
||||||
field = "reading_" + str(i)
|
reading_value = reading.get("reading_" + str(i))
|
||||||
data[field] = flt(reading.get(field)) or 0
|
if reading_value is not None:
|
||||||
|
readings_list.append(flt(reading_value))
|
||||||
|
|
||||||
try:
|
actual_mean = mean(readings_list) if readings_list else 0
|
||||||
result = frappe.safe_eval(condition, None, data)
|
return True if actual_mean == reading.get("mean_value") else False
|
||||||
reading.status = "Accepted" if result else "Rejected"
|
|
||||||
except SyntaxError:
|
|
||||||
frappe.throw(_("Row #{0}: Acceptance Criteria Formula is incorrect.").format(reading.idx),
|
|
||||||
title=_("Invalid Formula"))
|
|
||||||
except NameError as e:
|
|
||||||
field = frappe.bold(e.args[0].split()[1])
|
|
||||||
frappe.throw(_("Row #{0}: {1} is not a valid reading field. Please refer to the field description.")
|
|
||||||
.format(reading.idx, field),
|
|
||||||
title=_("Invalid Formula"))
|
|
||||||
|
|
||||||
|
return True # no mean value, nothing to check
|
||||||
|
|
||||||
|
def set_status_based_on_acceptance_formula(self, reading):
|
||||||
|
if not reading.acceptance_formula:
|
||||||
|
frappe.throw(_("Row #{0}: Acceptance Criteria Formula is required.").format(reading.idx),
|
||||||
|
title=_("Missing Formula"))
|
||||||
|
|
||||||
|
condition = reading.acceptance_formula
|
||||||
|
data = self.get_formula_evaluation_data(reading)
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = frappe.safe_eval(condition, None, data)
|
||||||
|
reading.status = "Accepted" if result else "Rejected"
|
||||||
|
except NameError as e:
|
||||||
|
field = frappe.bold(e.args[0].split()[1])
|
||||||
|
frappe.throw(_("Row #{0}: {1} is not a valid reading field. Please refer to the field description.")
|
||||||
|
.format(reading.idx, field),
|
||||||
|
title=_("Invalid Formula"))
|
||||||
|
except Exception:
|
||||||
|
frappe.throw(_("Row #{0}: Acceptance Criteria Formula is incorrect.").format(reading.idx),
|
||||||
|
title=_("Invalid Formula"))
|
||||||
|
|
||||||
|
def get_formula_evaluation_data(self, reading):
|
||||||
|
data = {}
|
||||||
|
if cint(reading.value_based):
|
||||||
|
data = {"reading_value": reading.get("reading_value")}
|
||||||
|
else:
|
||||||
|
# numeric readings
|
||||||
|
data = {"reading_1": flt(reading.get("reading_1"))}
|
||||||
|
if not cint(reading.single_reading):
|
||||||
|
# if multiple numeric readings add all readings to data
|
||||||
|
for i in range(2, 11):
|
||||||
|
field = "reading_" + str(i)
|
||||||
|
data[field] = flt(reading.get(field))
|
||||||
|
return data
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@frappe.validate_and_sanitize_search_inputs
|
@frappe.validate_and_sanitize_search_inputs
|
||||||
|
|||||||
@@ -7,21 +7,30 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"specification",
|
"specification",
|
||||||
"value",
|
|
||||||
"status",
|
"status",
|
||||||
|
"value",
|
||||||
|
"value_based",
|
||||||
"column_break_4",
|
"column_break_4",
|
||||||
|
"formula_based_criteria",
|
||||||
"acceptance_formula",
|
"acceptance_formula",
|
||||||
|
"min_value",
|
||||||
|
"max_value",
|
||||||
|
"mean_value",
|
||||||
"section_break_3",
|
"section_break_3",
|
||||||
|
"reading_value",
|
||||||
|
"section_break_14",
|
||||||
|
"single_reading",
|
||||||
|
"section_break_12",
|
||||||
"reading_1",
|
"reading_1",
|
||||||
"reading_2",
|
"reading_2",
|
||||||
"reading_3",
|
"reading_3",
|
||||||
"column_break_10",
|
|
||||||
"reading_4",
|
"reading_4",
|
||||||
|
"column_break_10",
|
||||||
"reading_5",
|
"reading_5",
|
||||||
"reading_6",
|
"reading_6",
|
||||||
"column_break_14",
|
|
||||||
"reading_7",
|
"reading_7",
|
||||||
"reading_8",
|
"reading_8",
|
||||||
|
"column_break_14",
|
||||||
"reading_9",
|
"reading_9",
|
||||||
"reading_10"
|
"reading_10"
|
||||||
],
|
],
|
||||||
@@ -38,10 +47,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"columns": 2,
|
"columns": 2,
|
||||||
|
"depends_on": "eval:(!doc.formula_based_criteria && doc.value_based)",
|
||||||
"fieldname": "value",
|
"fieldname": "value",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Acceptance Criteria",
|
"label": "Acceptance Criteria Value",
|
||||||
"oldfieldname": "value",
|
"oldfieldname": "value",
|
||||||
"oldfieldtype": "Data"
|
"oldfieldtype": "Data"
|
||||||
},
|
},
|
||||||
@@ -56,6 +66,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"columns": 1,
|
"columns": 1,
|
||||||
|
"depends_on": "eval:!doc.single_reading",
|
||||||
"fieldname": "reading_2",
|
"fieldname": "reading_2",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@@ -65,6 +76,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"columns": 1,
|
"columns": 1,
|
||||||
|
"depends_on": "eval:!doc.single_reading",
|
||||||
"fieldname": "reading_3",
|
"fieldname": "reading_3",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@@ -73,6 +85,7 @@
|
|||||||
"oldfieldtype": "Data"
|
"oldfieldtype": "Data"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:!doc.single_reading",
|
||||||
"fieldname": "reading_4",
|
"fieldname": "reading_4",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Reading 4",
|
"label": "Reading 4",
|
||||||
@@ -80,6 +93,7 @@
|
|||||||
"oldfieldtype": "Data"
|
"oldfieldtype": "Data"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:!doc.single_reading",
|
||||||
"fieldname": "reading_5",
|
"fieldname": "reading_5",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Reading 5",
|
"label": "Reading 5",
|
||||||
@@ -87,6 +101,7 @@
|
|||||||
"oldfieldtype": "Data"
|
"oldfieldtype": "Data"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:!doc.single_reading",
|
||||||
"fieldname": "reading_6",
|
"fieldname": "reading_6",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Reading 6",
|
"label": "Reading 6",
|
||||||
@@ -94,6 +109,7 @@
|
|||||||
"oldfieldtype": "Data"
|
"oldfieldtype": "Data"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:!doc.single_reading",
|
||||||
"fieldname": "reading_7",
|
"fieldname": "reading_7",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Reading 7",
|
"label": "Reading 7",
|
||||||
@@ -101,6 +117,7 @@
|
|||||||
"oldfieldtype": "Data"
|
"oldfieldtype": "Data"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:!doc.single_reading",
|
||||||
"fieldname": "reading_8",
|
"fieldname": "reading_8",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Reading 8",
|
"label": "Reading 8",
|
||||||
@@ -108,6 +125,7 @@
|
|||||||
"oldfieldtype": "Data"
|
"oldfieldtype": "Data"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:!doc.single_reading",
|
||||||
"fieldname": "reading_9",
|
"fieldname": "reading_9",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Reading 9",
|
"label": "Reading 9",
|
||||||
@@ -115,6 +133,7 @@
|
|||||||
"oldfieldtype": "Data"
|
"oldfieldtype": "Data"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:!doc.single_reading",
|
||||||
"fieldname": "reading_10",
|
"fieldname": "reading_10",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Reading 10",
|
"label": "Reading 10",
|
||||||
@@ -133,15 +152,18 @@
|
|||||||
"options": "Accepted\nRejected"
|
"options": "Accepted\nRejected"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "value_based",
|
||||||
"fieldname": "section_break_3",
|
"fieldname": "section_break_3",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Value Based Inspection"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_4",
|
"fieldname": "column_break_4",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Simple Python formula based on numeric Readings.<br> Example 1: <b>reading_1 > 0.2 and reading_1 < 0.5</b><br>\nExample 2: <b>(reading_1 + reading_2) / 2 < 10</b>",
|
"depends_on": "formula_based_criteria",
|
||||||
|
"description": "Simple Python formula applied on Reading fields.<br> Numeric eg.: <b>reading_1 > 0.2 and reading_1 < 0.5</b><br>\nValue based eg.: <b>reading_value in (\"A\", \"B\", \"C)</b>",
|
||||||
"fieldname": "acceptance_formula",
|
"fieldname": "acceptance_formula",
|
||||||
"fieldtype": "Code",
|
"fieldtype": "Code",
|
||||||
"label": "Acceptance Criteria Formula"
|
"label": "Acceptance Criteria Formula"
|
||||||
@@ -153,12 +175,69 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "column_break_14",
|
"fieldname": "column_break_14",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "formula_based_criteria",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Formula Based Criteria"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:(!doc.formula_based_criteria && !doc.single_reading && !doc.value_based)",
|
||||||
|
"fieldname": "mean_value",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"label": "Mean Value"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "single_reading",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Single Reading"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:!doc.value_based",
|
||||||
|
"fieldname": "section_break_12",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hide_border": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:(!doc.formula_based_criteria && !doc.value_based)",
|
||||||
|
"description": "Applied on each reading.",
|
||||||
|
"fieldname": "min_value",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"label": "Minimum Value"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:(!doc.formula_based_criteria && !doc.value_based)",
|
||||||
|
"description": "Applied on each reading.",
|
||||||
|
"fieldname": "max_value",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"label": "Maximum Value"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"description": "Non-numeric Inspection.",
|
||||||
|
"fieldname": "value_based",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Value Based"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "value_based",
|
||||||
|
"fieldname": "reading_value",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Reading Value"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:!doc.value_based",
|
||||||
|
"fieldname": "section_break_14",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Numeric Inspection"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-11-16 16:34:29.947856",
|
"modified": "2020-12-18 21:02:04.865777",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Quality Inspection Reading",
|
"name": "Quality Inspection Reading",
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ def get_template_details(template):
|
|||||||
if not template: return []
|
if not template: return []
|
||||||
|
|
||||||
return frappe.get_all('Item Quality Inspection Parameter',
|
return frappe.get_all('Item Quality Inspection Parameter',
|
||||||
fields=["specification", "value", "acceptance_formula"],
|
fields=["specification", "value", "acceptance_formula",
|
||||||
|
"value_based", "formula_based_criteria", "single_reading",
|
||||||
|
"min_value", "max_value", "mean_value"],
|
||||||
filters={'parenttype': 'Quality Inspection Template', 'parent': template},
|
filters={'parenttype': 'Quality Inspection Template', 'parent': template},
|
||||||
order_by="idx")
|
order_by="idx")
|
||||||
Reference in New Issue
Block a user