chore: UX improvement

- Removed 'single reading' checkbox, unnecessary
- Removed 'Mean' field and added computed mean to formula data
- Changed 'Value Based' to 'Non-Numeric'
- Re-arranged fields
This commit is contained in:
marination 2020-12-21 11:44:48 +05:30
parent d6277cdc7f
commit 0c4f97368d
4 changed files with 58 additions and 110 deletions

View File

@ -8,14 +8,12 @@
"field_order": [ "field_order": [
"specification", "specification",
"value", "value",
"value_based", "non_numeric",
"single_reading",
"column_break_3", "column_break_3",
"formula_based_criteria",
"acceptance_formula",
"min_value", "min_value",
"max_value", "max_value",
"mean_value" "formula_based_criteria",
"acceptance_formula"
], ],
"fields": [ "fields": [
{ {
@ -27,10 +25,10 @@
"oldfieldtype": "Data", "oldfieldtype": "Data",
"print_width": "200px", "print_width": "200px",
"reqd": 1, "reqd": 1,
"width": "200px" "width": "100px"
}, },
{ {
"depends_on": "eval:(!doc.formula_based_criteria && doc.value_based)", "depends_on": "eval:(!doc.formula_based_criteria && doc.non_numeric)",
"fieldname": "value", "fieldname": "value",
"fieldtype": "Data", "fieldtype": "Data",
"in_list_view": 1, "in_list_view": 1,
@ -44,10 +42,9 @@
}, },
{ {
"depends_on": "formula_based_criteria", "depends_on": "formula_based_criteria",
"description": "Simple Python formula applied on Reading fields.<br> Numeric eg.: <b>reading_1 &gt; 0.2 and reading_1 &lt; 0.5</b><br>\nValue based eg.: <b>reading_value in (\"A\", \"B\", \"C)</b>", "description": "Simple Python formula applied on Reading fields.<br> Numeric eg. 1: <b>reading_1 &gt; 0.2 and reading_1 &lt; 0.5</b><br>\nNumeric eg. 2: <b>mean &gt; 3.5</b> (mean of populated fields)<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,
"label": "Acceptance Criteria Formula" "label": "Acceptance Criteria Formula"
}, },
{ {
@ -57,42 +54,32 @@
"label": "Formula Based Criteria" "label": "Formula Based Criteria"
}, },
{ {
"default": "0", "depends_on": "eval:(!doc.formula_based_criteria && !doc.non_numeric)",
"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", "fieldname": "min_value",
"fieldtype": "Float", "fieldtype": "Float",
"in_list_view": 1,
"label": "Minimum Value" "label": "Minimum Value"
}, },
{ {
"depends_on": "eval:(!doc.formula_based_criteria && !doc.value_based)", "depends_on": "eval:(!doc.formula_based_criteria && !doc.non_numeric)",
"fieldname": "max_value", "fieldname": "max_value",
"fieldtype": "Float", "fieldtype": "Float",
"in_list_view": 1,
"label": "Maximum Value" "label": "Maximum Value"
}, },
{ {
"default": "0", "default": "0",
"description": "Non-numeric Inspection.", "fieldname": "non_numeric",
"fieldname": "value_based",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Value Based" "in_list_view": 1,
"label": "Non-Numeric",
"width": "80px"
} }
], ],
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"links": [], "links": [],
"modified": "2020-12-18 21:03:29.828723", "modified": "2020-12-21 11:37:55.387677",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Item Quality Inspection Parameter", "name": "Item Quality Inspection Parameter",

View File

@ -79,46 +79,27 @@ class QualityInspection(Document):
if reading.formula_based_criteria: if reading.formula_based_criteria:
self.set_status_based_on_acceptance_formula(reading) self.set_status_based_on_acceptance_formula(reading)
else: else:
# if not formula based check acceptance values set
self.set_status_based_on_acceptance_values(reading) self.set_status_based_on_acceptance_values(reading)
def set_status_based_on_acceptance_values(self, reading): def set_status_based_on_acceptance_values(self, reading):
if cint(reading.value_based): if cint(reading.non_numeric):
result = reading.get("reading_value") == reading.get("value") result = reading.get("reading_value") == reading.get("value")
else: else:
# numeric readings # numeric readings
if cint(reading.single_reading): result = self.min_max_criteria_passed(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" reading.status = "Accepted" if result else "Rejected"
def min_max_criteria_passed(self, reading): def min_max_criteria_passed(self, reading):
"""Determine whether all readings fall in the acceptable range.""" """Determine whether all readings fall in the acceptable range."""
for i in range(1, 11): for i in range(1, 11):
reading_field = reading.get("reading_" + str(i)) reading_value = reading.get("reading_" + str(i))
if reading_field is not None: if reading_value is not None and reading_value.strip():
result = flt(reading.get("min_value")) <= flt(reading_field) <= flt(reading.get("max_value")) result = flt(reading.get("min_value")) <= flt(reading_value) <= flt(reading.get("max_value"))
if not result: return False if not result: return False
return True 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 = []
for i in range(1, 11):
reading_value = reading.get("reading_" + str(i))
if reading_value is not None:
readings_list.append(flt(reading_value))
actual_mean = mean(readings_list) if readings_list else 0
return True if actual_mean == reading.get("mean_value") else False
return True # no mean value, nothing to check
def set_status_based_on_acceptance_formula(self, reading): def set_status_based_on_acceptance_formula(self, reading):
if not reading.acceptance_formula: if not reading.acceptance_formula:
frappe.throw(_("Row #{0}: Acceptance Criteria Formula is required.").format(reading.idx), frappe.throw(_("Row #{0}: Acceptance Criteria Formula is required.").format(reading.idx),
@ -141,18 +122,30 @@ class QualityInspection(Document):
def get_formula_evaluation_data(self, reading): def get_formula_evaluation_data(self, reading):
data = {} data = {}
if cint(reading.value_based): if cint(reading.non_numeric):
data = {"reading_value": reading.get("reading_value")} data = {"reading_value": reading.get("reading_value")}
else: else:
# numeric readings # numeric readings
data = {"reading_1": flt(reading.get("reading_1"))} for i in range(1, 11):
if not cint(reading.single_reading): field = "reading_" + str(i)
# if multiple numeric readings add all readings to data data[field] = flt(reading.get(field))
for i in range(2, 11): data["mean"] = self.calculate_mean(reading)
field = "reading_" + str(i)
data[field] = flt(reading.get(field))
return data return data
def calculate_mean(self, reading):
"""Calculate mean of all non-empty readings."""
from statistics import mean
readings_list = []
for i in range(1, 11):
reading_value = reading.get("reading_" + str(i))
if reading_value is not None and reading_value.strip():
readings_list.append(flt(reading_value))
actual_mean = mean(readings_list) if readings_list else 0
return actual_mean
@frappe.whitelist() @frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs @frappe.validate_and_sanitize_search_inputs
def item_query(doctype, txt, searchfield, start, page_len, filters): def item_query(doctype, txt, searchfield, start, page_len, filters):

View File

@ -9,18 +9,15 @@
"specification", "specification",
"status", "status",
"value", "value",
"value_based", "non_numeric",
"column_break_4", "column_break_4",
"formula_based_criteria",
"acceptance_formula",
"min_value", "min_value",
"max_value", "max_value",
"mean_value", "formula_based_criteria",
"acceptance_formula",
"section_break_3", "section_break_3",
"reading_value", "reading_value",
"section_break_14", "section_break_14",
"single_reading",
"section_break_12",
"reading_1", "reading_1",
"reading_2", "reading_2",
"reading_3", "reading_3",
@ -47,7 +44,7 @@
}, },
{ {
"columns": 2, "columns": 2,
"depends_on": "eval:(!doc.formula_based_criteria && doc.value_based)", "depends_on": "eval:(!doc.formula_based_criteria && doc.non_numeric)",
"fieldname": "value", "fieldname": "value",
"fieldtype": "Data", "fieldtype": "Data",
"in_list_view": 1, "in_list_view": 1,
@ -66,7 +63,6 @@
}, },
{ {
"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,
@ -76,7 +72,6 @@
}, },
{ {
"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,
@ -85,7 +80,6 @@
"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",
@ -93,7 +87,6 @@
"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",
@ -101,7 +94,6 @@
"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",
@ -109,7 +101,6 @@
"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",
@ -117,7 +108,6 @@
"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",
@ -125,7 +115,6 @@
"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",
@ -133,7 +122,6 @@
"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",
@ -152,7 +140,7 @@
"options": "Accepted\nRejected" "options": "Accepted\nRejected"
}, },
{ {
"depends_on": "value_based", "depends_on": "non_numeric",
"fieldname": "section_break_3", "fieldname": "section_break_3",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Value Based Inspection" "label": "Value Based Inspection"
@ -163,7 +151,7 @@
}, },
{ {
"depends_on": "formula_based_criteria", "depends_on": "formula_based_criteria",
"description": "Simple Python formula applied on Reading fields.<br> Numeric eg.: <b>reading_1 &gt; 0.2 and reading_1 &lt; 0.5</b><br>\nValue based eg.: <b>reading_value in (\"A\", \"B\", \"C)</b>", "description": "Simple Python formula applied on Reading fields.<br> Numeric eg. 1: <b>reading_1 &gt; 0.2 and reading_1 &lt; 0.5</b><br>\nNumeric eg. 2: <b>mean &gt; 3.5</b> (mean of populated fields)<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"
@ -183,61 +171,42 @@
"label": "Formula Based Criteria" "label": "Formula Based Criteria"
}, },
{ {
"depends_on": "eval:(!doc.formula_based_criteria && !doc.single_reading && !doc.value_based)", "depends_on": "eval:(!doc.formula_based_criteria && !doc.non_numeric)",
"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.", "description": "Applied on each reading.",
"fieldname": "min_value", "fieldname": "min_value",
"fieldtype": "Float", "fieldtype": "Float",
"label": "Minimum Value" "label": "Minimum Value"
}, },
{ {
"depends_on": "eval:(!doc.formula_based_criteria && !doc.value_based)", "depends_on": "eval:(!doc.formula_based_criteria && !doc.non_numeric)",
"description": "Applied on each reading.", "description": "Applied on each reading.",
"fieldname": "max_value", "fieldname": "max_value",
"fieldtype": "Float", "fieldtype": "Float",
"label": "Maximum Value" "label": "Maximum Value"
}, },
{ {
"default": "0", "depends_on": "non_numeric",
"description": "Non-numeric Inspection.",
"fieldname": "value_based",
"fieldtype": "Check",
"label": "Value Based"
},
{
"depends_on": "value_based",
"fieldname": "reading_value", "fieldname": "reading_value",
"fieldtype": "Data", "fieldtype": "Data",
"label": "Reading Value" "label": "Reading Value"
}, },
{ {
"depends_on": "eval:!doc.value_based", "depends_on": "eval:!doc.non_numeric",
"fieldname": "section_break_14", "fieldname": "section_break_14",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Numeric Inspection" "label": "Numeric Inspection"
},
{
"default": "0",
"fieldname": "non_numeric",
"fieldtype": "Check",
"label": "Non-Numeric"
} }
], ],
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"links": [], "links": [],
"modified": "2020-12-18 21:02:04.865777", "modified": "2020-12-21 11:36:24.885019",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Quality Inspection Reading", "name": "Quality Inspection Reading",

View File

@ -14,7 +14,6 @@ def get_template_details(template):
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", "non_numeric", "formula_based_criteria", "min_value", "max_value"],
"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")