fix(refactor): refactor tests, client side code
diff --git a/erpnext/quality_management/desk_page/quality/quality.json b/erpnext/quality_management/desk_page/quality/quality.json
index ffa35df..7a049b2 100644
--- a/erpnext/quality_management/desk_page/quality/quality.json
+++ b/erpnext/quality_management/desk_page/quality/quality.json
@@ -33,7 +33,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "Quality",
- "modified": "2020-10-26 15:24:58.058088",
+ "modified": "2020-10-27 16:28:54.138055",
  "modified_by": "Administrator",
  "module": "Quality Management",
  "name": "Quality",
@@ -47,6 +47,7 @@
    "type": "DocType"
   },
   {
+   "doc_view": "Tree",
    "label": "Quality Procedure",
    "link_to": "Quality Procedure",
    "type": "DocType"
@@ -57,9 +58,12 @@
    "type": "DocType"
   },
   {
+   "color": "#ff8989",
    "doc_view": "",
+   "format": "{} Open",
    "label": "Quality Review",
    "link_to": "Quality Review",
+   "stats_filter": "{\"status\": \"Open\"}",
    "type": "DocType"
   },
   {
@@ -72,9 +76,12 @@
    "type": "DocType"
   },
   {
+   "color": "#ff8989",
    "doc_view": "",
+   "format": "{} Open",
    "label": "Non Conformance",
    "link_to": "Non Conformance",
+   "stats_filter": "{\"status\": \"Open\"}",
    "type": "DocType"
   }
  ]
diff --git a/erpnext/quality_management/doctype/quality_action/quality_action.json b/erpnext/quality_management/doctype/quality_action/quality_action.json
index 02f84be..0cc2a98 100644
--- a/erpnext/quality_management/doctype/quality_action/quality_action.json
+++ b/erpnext/quality_management/doctype/quality_action/quality_action.json
@@ -80,8 +80,7 @@
    "fieldtype": "Link",
    "in_list_view": 1,
    "label": "Review",
-   "options": "Quality Review",
-   "reqd": 1
+   "options": "Quality Review"
   },
   {
    "fieldname": "feedback",
@@ -92,7 +91,7 @@
  ],
  "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2020-10-21 13:01:31.920215",
+ "modified": "2020-10-27 16:21:59.533937",
  "modified_by": "Administrator",
  "module": "Quality Management",
  "name": "Quality Action",
diff --git a/erpnext/quality_management/doctype/quality_action/test_quality_action.js b/erpnext/quality_management/doctype/quality_action/test_quality_action.js
deleted file mode 100644
index 34a8c86..0000000
--- a/erpnext/quality_management/doctype/quality_action/test_quality_action.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* eslint-disable */
-// rename this file from _test_[name] to test_[name] to activate
-// and remove above this line
-
-QUnit.test("test: Quality Action", function (assert) {
-	let done = assert.async();
-
-	// number of asserts
-	assert.expect(1);
-
-	frappe.run_serially([
-		// insert a new Quality Actions
-		() => frappe.tests.make('Quality Actions', [
-			// values to be set
-			{key: 'value'}
-		]),
-		() => {
-			assert.equal(cur_frm.doc.key, 'value');
-		},
-		() => done()
-	]);
-
-});
diff --git a/erpnext/quality_management/doctype/quality_action/test_quality_action.py b/erpnext/quality_management/doctype/quality_action/test_quality_action.py
index 51178d6..24b97ca 100644
--- a/erpnext/quality_management/doctype/quality_action/test_quality_action.py
+++ b/erpnext/quality_management/doctype/quality_action/test_quality_action.py
@@ -5,42 +5,7 @@
 
 import frappe
 import unittest
-from erpnext.quality_management.doctype.quality_procedure.test_quality_procedure import create_procedure
-from erpnext.quality_management.doctype.quality_goal.test_quality_goal import create_unit
-from erpnext.quality_management.doctype.quality_goal.test_quality_goal import create_goal
-from erpnext.quality_management.doctype.quality_review.test_quality_review import create_review
 
 class TestQualityAction(unittest.TestCase):
-
-	def test_quality_action(self):
-		create_procedure()
-		create_unit()
-		create_goal()
-		create_review()
-		test_create_action = create_action()
-		test_get_action = get_action()
-
-		self.assertEquals(test_create_action, test_get_action)
-
-def create_action():
-	review = frappe.db.exists("Quality Review", {"goal": "GOAL-_Test Quality Goal"})
-	action = frappe.get_doc({
-		"doctype": "Quality Action",
-		"action": "Corrective",
-		"document_type": "Quality Review",
-		"document_name": review,
-		"date": frappe.utils.nowdate(),
-		"goal": "GOAL-_Test Quality Goal",
-		"procedure": "PRC-_Test Quality Procedure"
-	})
-	action_exist = frappe.db.exists("Quality Action", {"review": review})
-
-	if not action_exist:
-		action.insert()
-		return action.name
-	else:
-		return action_exist
-
-def get_action():
-	review = frappe.db.exists("Quality Review", {"goal": "GOAL-_Test Quality Goal"})
-	return frappe.db.exists("Quality Action", {"document_name": review})
\ No newline at end of file
+	# quality action has no code
+	pass
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_feedback/quality_feedback.js b/erpnext/quality_management/doctype/quality_feedback/quality_feedback.js
index dac6ac4..6fb3267 100644
--- a/erpnext/quality_management/doctype/quality_feedback/quality_feedback.js
+++ b/erpnext/quality_management/doctype/quality_feedback/quality_feedback.js
@@ -2,31 +2,9 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on('Quality Feedback', {
-	refresh: function(frm) {
-		frm.set_value("date", frappe.datetime.get_today());
-	},
-
 	template: function(frm) {
 		if (frm.doc.template) {
-			frappe.call({
-				"method": "frappe.client.get",
-				args: {
-					doctype: "Quality Feedback Template",
-					name: frm.doc.template
-				},
-				callback: function(data) {
-					if (data && data.message) {
-						frm.fields_dict.parameters.grid.remove_all();
-
-						// fetch parameters from template and autofill
-						for (let template_parameter of data.message.parameters) {
-							let row = frm.add_child("parameters");
-							row.parameter = template_parameter.parameter;
-						}
-						frm.refresh();
-					}
-				}
-			});
+			frm.call('set_parameters');
 		}
 	}
 });
diff --git a/erpnext/quality_management/doctype/quality_feedback/quality_feedback.json b/erpnext/quality_management/doctype/quality_feedback/quality_feedback.json
index 8d4b996..f3bd0dd 100644
--- a/erpnext/quality_management/doctype/quality_feedback/quality_feedback.json
+++ b/erpnext/quality_management/doctype/quality_feedback/quality_feedback.json
@@ -6,11 +6,10 @@
  "editable_grid": 1,
  "engine": "InnoDB",
  "field_order": [
-  "document_type",
   "template",
   "cb_00",
+  "document_type",
   "document_name",
-  "date",
   "sb_00",
   "parameters"
  ],
@@ -18,6 +17,7 @@
   {
    "fieldname": "template",
    "fieldtype": "Link",
+   "in_list_view": 1,
    "label": "Template",
    "options": "Quality Feedback Template",
    "reqd": 1
@@ -27,13 +27,6 @@
    "fieldtype": "Column Break"
   },
   {
-   "fieldname": "date",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "label": "Date",
-   "read_only": 1
-  },
-  {
    "fieldname": "sb_00",
    "fieldtype": "Section Break"
   },
@@ -47,6 +40,7 @@
   {
    "fieldname": "document_type",
    "fieldtype": "Select",
+   "in_list_view": 1,
    "label": "Type",
    "options": "User\nCustomer",
    "reqd": 1
@@ -54,13 +48,20 @@
   {
    "fieldname": "document_name",
    "fieldtype": "Dynamic Link",
+   "in_list_view": 1,
    "label": "Feedback By",
    "options": "document_type",
    "reqd": 1
   }
  ],
- "links": [],
- "modified": "2020-10-21 12:39:20.740854",
+ "links": [
+  {
+   "group": "Actions",
+   "link_doctype": "Quality Action",
+   "link_fieldname": "feedback"
+  }
+ ],
+ "modified": "2020-10-27 16:20:10.918544",
  "modified_by": "Administrator",
  "module": "Quality Management",
  "name": "Quality Feedback",
diff --git a/erpnext/quality_management/doctype/quality_feedback/quality_feedback.py b/erpnext/quality_management/doctype/quality_feedback/quality_feedback.py
index 9894181..bf82cc0 100644
--- a/erpnext/quality_management/doctype/quality_feedback/quality_feedback.py
+++ b/erpnext/quality_management/doctype/quality_feedback/quality_feedback.py
@@ -7,4 +7,17 @@
 from frappe.model.document import Document
 
 class QualityFeedback(Document):
-	pass
\ No newline at end of file
+	def set_parameters(self):
+		if self.template and not getattr(self, 'parameters', []):
+			for d in frappe.get_doc('Quality Feedback Template', self.template).parameters:
+				self.append('parameters', dict(
+					parameter = d.parameter,
+					rating = 1
+				))
+
+	def validate(self):
+		if not self.document_name:
+			self.document_type ='User'
+			self.document_name = frappe.session.user
+		self.set_parameters()
+
diff --git a/erpnext/quality_management/doctype/quality_feedback/test_quality_feedback.py b/erpnext/quality_management/doctype/quality_feedback/test_quality_feedback.py
index 3be1eb2..5a8bd5c 100644
--- a/erpnext/quality_management/doctype/quality_feedback/test_quality_feedback.py
+++ b/erpnext/quality_management/doctype/quality_feedback/test_quality_feedback.py
@@ -5,49 +5,27 @@
 
 import frappe
 import unittest
-from erpnext.quality_management.doctype.quality_feedback_template.test_quality_feedback_template import create_template
+
 
 class TestQualityFeedback(unittest.TestCase):
-
 	def test_quality_feedback(self):
-		create_template()
-		test_create_feedback = create_feedback()
-		test_get_feedback = get_feedback()
+		template = frappe.get_doc(dict(
+			doctype = 'Quality Feedback Template',
+			template = 'Test Template',
+			parameters = [
+				dict(parameter='Test Parameter 1'),
+				dict(parameter='Test Parameter 2')
+			]
+		)).insert()
 
-		self.assertEqual(test_create_feedback, test_get_feedback)
+		feedback = frappe.get_doc(dict(
+			doctype = 'Quality Feedback',
+			template = template.name,
+			document_type = 'User',
+			document_name = frappe.session.user
+		)).insert()
 
-def create_feedback():
-	create_customer()
+		self.assertEqual(template.parameters[0].parameter, feedback.parameters[0].parameter)
 
-	feedabck = frappe.get_doc({
-		"doctype": "Quality Feedback",
-		"template": "TMPL-_Test Feedback Template",
-		"document_type": "Customer",
-		"document_name": "Quality Feedback Customer",
-		"date": frappe.utils.nowdate(),
-		"parameters": [
-			{
-				"parameter": "Test Parameter",
-				"rating": 3,
-				"feedback": "Test Feedback"
-			}
-		]
-	})
-
-	feedback_exists = frappe.db.exists("Quality Feedback", {"template": "TMPL-_Test Feedback Template"})
-
-	if not feedback_exists:
-		feedabck.insert()
-		return feedabck.name
-	else:
-		return feedback_exists
-
-def get_feedback():
-	return frappe.db.exists("Quality Feedback", {"template": "TMPL-_Test Feedback Template"})
-
-def create_customer():
-	if not frappe.db.exists("Customer", {"customer_name": "Quality Feedback Customer"}):
-		customer = frappe.get_doc({
-				"doctype": "Customer",
-				"customer_name": "Quality Feedback Customer"
-			}).insert(ignore_permissions=True)
\ No newline at end of file
+		feedback.delete()
+		template.delete()
diff --git a/erpnext/quality_management/doctype/quality_feedback_parameter/quality_feedback_parameter.json b/erpnext/quality_management/doctype/quality_feedback_parameter/quality_feedback_parameter.json
index 5bd8920..ce5d4cf 100644
--- a/erpnext/quality_management/doctype/quality_feedback_parameter/quality_feedback_parameter.json
+++ b/erpnext/quality_management/doctype/quality_feedback_parameter/quality_feedback_parameter.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "creation": "2019-05-26 21:25:01.715807",
  "doctype": "DocType",
  "editable_grid": 1,
@@ -39,12 +40,13 @@
    "fieldname": "feedback",
    "fieldtype": "Text Editor",
    "in_list_view": 1,
-   "label": "Feedback",
-   "reqd": 1
+   "label": "Feedback"
   }
  ],
+ "index_web_pages_for_search": 1,
  "istable": 1,
- "modified": "2019-07-13 19:58:08.966141",
+ "links": [],
+ "modified": "2020-10-27 17:28:12.033145",
  "modified_by": "Administrator",
  "module": "Quality Management",
  "name": "Quality Feedback Parameter",
diff --git a/erpnext/quality_management/doctype/quality_feedback_template/quality_feedback_template.json b/erpnext/quality_management/doctype/quality_feedback_template/quality_feedback_template.json
index 4927518..1696470 100644
--- a/erpnext/quality_management/doctype/quality_feedback_template/quality_feedback_template.json
+++ b/erpnext/quality_management/doctype/quality_feedback_template/quality_feedback_template.json
@@ -7,7 +7,6 @@
  "engine": "InnoDB",
  "field_order": [
   "template",
-  "cb_00",
   "sb_00",
   "parameters"
  ],
@@ -16,15 +15,11 @@
    "fieldname": "template",
    "fieldtype": "Data",
    "in_list_view": 1,
-   "label": "Template",
+   "label": "Template Name",
    "reqd": 1,
    "unique": 1
   },
   {
-   "fieldname": "cb_00",
-   "fieldtype": "Column Break"
-  },
-  {
    "fieldname": "sb_00",
    "fieldtype": "Section Break"
   },
@@ -36,8 +31,14 @@
    "reqd": 1
   }
  ],
- "links": [],
- "modified": "2020-10-21 12:39:02.221128",
+ "links": [
+  {
+   "group": "Records",
+   "link_doctype": "Quality Feedback",
+   "link_fieldname": "template"
+  }
+ ],
+ "modified": "2020-10-27 16:18:53.579688",
  "modified_by": "Administrator",
  "module": "Quality Management",
  "name": "Quality Feedback Template",
diff --git a/erpnext/quality_management/doctype/quality_feedback_template/test_quality_feedback_template.py b/erpnext/quality_management/doctype/quality_feedback_template/test_quality_feedback_template.py
index 36dbe13..b3eed10 100644
--- a/erpnext/quality_management/doctype/quality_feedback_template/test_quality_feedback_template.py
+++ b/erpnext/quality_management/doctype/quality_feedback_template/test_quality_feedback_template.py
@@ -7,31 +7,4 @@
 import unittest
 
 class TestQualityFeedbackTemplate(unittest.TestCase):
-
-	def test_quality_feedback_template(self):
-		test_create_template = create_template()
-		test_get_template = get_template()
-
-		self.assertEqual(test_create_template, test_get_template)
-
-def create_template():
-	template = frappe.get_doc({
-		"doctype": "Quality Feedback Template",
-		"template": "_Test Feedback Template",
-		"parameters": [
-			{
-				"parameter": "Test Parameter"
-			}
-		]
-	})
-
-	template_exists = frappe.db.exists("Quality Feedback Template", {"template": "_Test Feedback Template"})
-
-	if not template_exists:
-		template.insert()
-		return template.name
-	else:
-		return template_exists
-
-def get_template():
-	return frappe.db.exists("Quality Feedback Template", {"template": "_Test Feedback Template"})
\ No newline at end of file
+	pass
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_goal/quality_goal.js b/erpnext/quality_management/doctype/quality_goal/quality_goal.js
index ff58c5a..40cb4d9 100644
--- a/erpnext/quality_management/doctype/quality_goal/quality_goal.js
+++ b/erpnext/quality_management/doctype/quality_goal/quality_goal.js
@@ -2,7 +2,6 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on('Quality Goal', {
-	refresh: function(frm) {
-		frm.doc.created_by = frappe.session.user;
-	}
+	// refresh: function(frm) {
+	// }
 });
diff --git a/erpnext/quality_management/doctype/quality_goal/quality_goal.json b/erpnext/quality_management/doctype/quality_goal/quality_goal.json
index b64754e..2680255 100644
--- a/erpnext/quality_management/doctype/quality_goal/quality_goal.json
+++ b/erpnext/quality_management/doctype/quality_goal/quality_goal.json
@@ -8,28 +8,15 @@
  "field_order": [
   "goal",
   "frequency",
-  "created_by",
   "cb_00",
   "procedure",
   "weekday",
-  "quarter",
   "date",
-  "sb_00",
-  "revision",
-  "cb_01",
-  "revised_on",
   "sb_01",
   "objectives"
  ],
  "fields": [
   {
-   "fieldname": "created_by",
-   "fieldtype": "Link",
-   "label": "Created By",
-   "options": "User",
-   "read_only": 1
-  },
-  {
    "default": "None",
    "fieldname": "frequency",
    "fieldtype": "Select",
@@ -52,20 +39,6 @@
    "options": "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30"
   },
   {
-   "default": "0",
-   "fieldname": "revision",
-   "fieldtype": "Int",
-   "label": "Revision",
-   "read_only": 1
-  },
-  {
-   "fieldname": "revised_on",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "label": "Revised On",
-   "read_only": 1
-  },
-  {
    "depends_on": "eval:doc.frequency == 'Weekly';",
    "fieldname": "weekday",
    "fieldtype": "Select",
@@ -77,15 +50,6 @@
    "fieldtype": "Column Break"
   },
   {
-   "fieldname": "sb_00",
-   "fieldtype": "Section Break",
-   "label": "Revision and Revised On"
-  },
-  {
-   "fieldname": "cb_01",
-   "fieldtype": "Column Break"
-  },
-  {
    "fieldname": "sb_01",
    "fieldtype": "Section Break",
    "label": "Objectives"
@@ -102,15 +66,6 @@
    "label": "Goal",
    "reqd": 1,
    "unique": 1
-  },
-  {
-   "default": "January-April-July-October",
-   "depends_on": "eval:doc.frequency == 'Quarterly';",
-   "fieldname": "quarter",
-   "fieldtype": "Select",
-   "label": "Quarter",
-   "options": "January-April-July-October",
-   "read_only": 1
   }
  ],
  "index_web_pages_for_search": 1,
@@ -121,7 +76,7 @@
    "link_fieldname": "goal"
   }
  ],
- "modified": "2020-10-21 12:49:38.251228",
+ "modified": "2020-10-27 15:57:59.368605",
  "modified_by": "Administrator",
  "module": "Quality Management",
  "name": "Quality Goal",
diff --git a/erpnext/quality_management/doctype/quality_goal/quality_goal.py b/erpnext/quality_management/doctype/quality_goal/quality_goal.py
index 4ae015e..f3fe986 100644
--- a/erpnext/quality_management/doctype/quality_goal/quality_goal.py
+++ b/erpnext/quality_management/doctype/quality_goal/quality_goal.py
@@ -8,7 +8,5 @@
 from frappe.model.document import Document
 
 class QualityGoal(Document):
-
 	def validate(self):
-		self.revision += 1
-		self.revised_on = frappe.utils.today()
+		pass
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_goal/test_quality_goal.js b/erpnext/quality_management/doctype/quality_goal/test_quality_goal.js
deleted file mode 100644
index f8afe54..0000000
--- a/erpnext/quality_management/doctype/quality_goal/test_quality_goal.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* eslint-disable */
-// rename this file from _test_[name] to test_[name] to activate
-// and remove above this line
-
-QUnit.test("test: Quality Goal", function (assert) {
-	let done = assert.async();
-
-	// number of asserts
-	assert.expect(1);
-
-	frappe.run_serially([
-		// insert a new Quality Goal
-		() => frappe.tests.make('Quality Goal', [
-			// values to be set
-			{key: 'value'}
-		]),
-		() => {
-			assert.equal(cur_frm.doc.key, 'value');
-		},
-		() => done()
-	]);
-
-});
diff --git a/erpnext/quality_management/doctype/quality_goal/test_quality_goal.py b/erpnext/quality_management/doctype/quality_goal/test_quality_goal.py
index d77187a..f61d6e5 100644
--- a/erpnext/quality_management/doctype/quality_goal/test_quality_goal.py
+++ b/erpnext/quality_management/doctype/quality_goal/test_quality_goal.py
@@ -8,44 +8,18 @@
 from erpnext.quality_management.doctype.quality_procedure.test_quality_procedure import create_procedure
 
 class TestQualityGoal(unittest.TestCase):
-
 	def test_quality_goal(self):
-		create_procedure()
-		create_unit()
-		test_create_goal = create_goal()
-		test_get_goal = get_goal()
+		# no code, just a basic sanity check
+		goal = get_quality_goal()
+		self.assertTrue(goal)
+		goal.delete()
 
-		self.assertEquals(test_create_goal, test_get_goal)
-
-def create_goal():
-	goal = frappe.get_doc({
-		"doctype": "Quality Goal",
-		"goal": "_Test Quality Goal",
-		"procedure": "PRC-_Test Quality Procedure",
-		"objectives": [
-			{
-				"objective": "_Test Quality Objective",
-				"target": "4",
-				"uom": "_Test UOM"
-			}
+def get_quality_goal():
+	return frappe.get_doc(dict(
+		doctype = 'Quality Goal',
+		goal = 'Test Quality Module',
+		frequency = 'Daily',
+		objectives = [
+			dict(objective = 'Check test cases', target='100', uom='Percent')
 		]
-	})
-	goal_exist = frappe.db.exists("Quality Goal", {"goal": goal.goal})
-	if not goal_exist:
-		goal.insert()
-		return goal.name
-	else:
-		return goal_exist
-
-def get_goal():
-	goal = frappe.db.exists("Quality Goal", "GOAL-_Test Quality Goal")
-	return goal
-
-def create_unit():
-	unit = frappe.get_doc({
-		"doctype": "UOM",
-		"uom_name": "_Test UOM",
-	})
-	unit_exist = frappe.db.exists("UOM", unit.uom_name)
-	if not unit_exist:
-		unit.insert()
+	)).insert()
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_meeting/quality_meeting.js b/erpnext/quality_management/doctype/quality_meeting/quality_meeting.js
index 32c7c33..eb7a8c3 100644
--- a/erpnext/quality_management/doctype/quality_meeting/quality_meeting.js
+++ b/erpnext/quality_management/doctype/quality_meeting/quality_meeting.js
@@ -2,8 +2,5 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on('Quality Meeting', {
-	onload: function(frm){
-		frm.set_value("date", frappe.datetime.get_today());
-		frm.refresh();
-	}
+
 });
diff --git a/erpnext/quality_management/doctype/quality_meeting/quality_meeting.json b/erpnext/quality_management/doctype/quality_meeting/quality_meeting.json
index 480abf0..ead403d 100644
--- a/erpnext/quality_management/doctype/quality_meeting/quality_meeting.json
+++ b/erpnext/quality_management/doctype/quality_meeting/quality_meeting.json
@@ -6,9 +6,8 @@
  "editable_grid": 1,
  "engine": "InnoDB",
  "field_order": [
-  "date",
-  "cb_00",
   "status",
+  "cb_00",
   "sb_00",
   "agenda",
   "sb_01",
@@ -16,13 +15,6 @@
  ],
  "fields": [
   {
-   "fieldname": "date",
-   "fieldtype": "Date",
-   "in_list_view": 1,
-   "label": "Date",
-   "read_only": 1
-  },
-  {
    "default": "Open",
    "fieldname": "status",
    "fieldtype": "Select",
@@ -58,7 +50,7 @@
  ],
  "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2020-10-21 13:08:50.367577",
+ "modified": "2020-10-27 16:36:45.657883",
  "modified_by": "Administrator",
  "module": "Quality Management",
  "name": "Quality Meeting",
diff --git a/erpnext/quality_management/doctype/quality_meeting/test_quality_meeting.js b/erpnext/quality_management/doctype/quality_meeting/test_quality_meeting.js
deleted file mode 100644
index 196cc85..0000000
--- a/erpnext/quality_management/doctype/quality_meeting/test_quality_meeting.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* eslint-disable */
-// rename this file from _test_[name] to test_[name] to activate
-// and remove above this line
-
-QUnit.test("test: Quality Meeting", function (assert) {
-	let done = assert.async();
-
-	// number of asserts
-	assert.expect(1);
-
-	frappe.run_serially([
-		// insert a new Quality Meeting
-		() => frappe.tests.make('Quality Meeting', [
-			// values to be set
-			{key: 'value'}
-		]),
-		() => {
-			assert.equal(cur_frm.doc.key, 'value');
-		},
-		() => done()
-	]);
-
-});
diff --git a/erpnext/quality_management/doctype/quality_meeting/test_quality_meeting.py b/erpnext/quality_management/doctype/quality_meeting/test_quality_meeting.py
index e61b5df..754bccb 100644
--- a/erpnext/quality_management/doctype/quality_meeting/test_quality_meeting.py
+++ b/erpnext/quality_management/doctype/quality_meeting/test_quality_meeting.py
@@ -5,41 +5,7 @@
 
 import frappe
 import unittest
-from erpnext.quality_management.doctype.quality_review.test_quality_review import create_review
 
 class TestQualityMeeting(unittest.TestCase):
-	def test_quality_meeting(self):
-		create_review()
-		test_create_meeting = create_meeting()
-		test_get_meeting = get_meeting()
-		self.assertEquals(test_create_meeting, test_get_meeting)
-
-def create_meeting():
-	meeting = frappe.get_doc({
-		"doctype": "Quality Meeting",
-		"status": "Open",
-		"date": frappe.utils.nowdate(),
-		"agenda": [
-			{
-				"agenda": "Test Agenda"
-			}
-		],
-		"minutes": [
-			{
-				"document_type": "Quality Review",
-				"document_name": frappe.db.exists("Quality Review", {"goal": "GOAL-_Test Quality Goal"}),
-				"minute": "Test Minute"
-			}
-		]
-	})
-	meeting_exist = frappe.db.exists("Quality Meeting", {"date": frappe.utils.nowdate(), "status": "Open"})
-
-	if not meeting_exist:
-		meeting.insert()
-		return meeting.name
-	else:
-		return meeting_exist
-
-def get_meeting():
-	meeting = frappe.db.exists("Quality Meeting", {"date": frappe.utils.nowdate(), "status": "Open"})
-	return meeting
\ No newline at end of file
+	# nothing to test
+	pass
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py
index 797c26b..f085727 100644
--- a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py
+++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py
@@ -14,69 +14,58 @@
 		self.check_for_incorrect_child()
 
 	def on_update(self):
+		NestedSet.on_update(self)
 		self.set_parent()
 
 	def after_insert(self):
 		self.set_parent()
-		#if Child is Added through Tree View.
+
+		# add child to parent if missing
 		if self.parent_quality_procedure:
-			parent_quality_procedure = frappe.get_doc("Quality Procedure", self.parent_quality_procedure)
-			parent_quality_procedure.append("processes", {"procedure": self.name})
-			parent_quality_procedure.save()
+			parent = frappe.get_doc("Quality Procedure", self.parent_quality_procedure)
+			if not [d for d in parent.processes if d.procedure == self.name]:
+				parent.append("processes", {"procedure": self.name, "process_description": self.name})
+				parent.save()
 
 	def on_trash(self):
-		if self.parent_quality_procedure:
-			doc = frappe.get_doc("Quality Procedure", self.parent_quality_procedure)
-			for process in doc.processes:
-				if process.procedure == self.name:
-					doc.processes.remove(process)
-					doc.save(ignore_permissions=True)
-
-			flag_is_group = 0
-			doc.load_from_db()
-
-			for process in doc.processes:
-				flag_is_group = 1 if process.procedure else 0
-
-			doc.is_group = 0 if flag_is_group == 0 else 1
-			doc.save(ignore_permissions=True)
+		# clear from child table (sub procedures)
+		frappe.db.sql('''update `tabQuality Procedure Process`
+			set `procedure`='' where `procedure`=%s''', self.name)
+		NestedSet.on_trash(self, allow_root_deletion=True)
 
 	def set_parent(self):
-		rebuild_tree('Quality Procedure', 'parent_quality_procedure')
-
 		for process in self.processes:
 			# Set parent for only those children who don't have a parent
-			parent_quality_procedure = frappe.db.get_value("Quality Procedure", process.procedure, "parent_quality_procedure")
-			if not parent_quality_procedure and process.procedure:
+			has_parent = frappe.db.get_value("Quality Procedure", process.procedure, "parent_quality_procedure")
+			if not has_parent and process.procedure:
 				frappe.db.set_value(self.doctype, process.procedure, "parent_quality_procedure", self.name)
 
 	def check_for_incorrect_child(self):
 		for process in self.processes:
 			if process.procedure:
+				self.is_group = 1
 				# Check if any child process belongs to another parent.
 				parent_quality_procedure = frappe.db.get_value("Quality Procedure", process.procedure, "parent_quality_procedure")
 				if parent_quality_procedure and parent_quality_procedure != self.name:
 					frappe.throw(_("{0} already has a Parent Procedure {1}.".format(frappe.bold(process.procedure), frappe.bold(parent_quality_procedure))),
 						title=_("Invalid Child Procedure"))
-				self.is_group = 1
 
 @frappe.whitelist()
 def get_children(doctype, parent=None, parent_quality_procedure=None, is_root=False):
 	if parent is None or parent == "All Quality Procedures":
 		parent = ""
 
-	return frappe.db.sql("""
-		select
-			name as value,
-			is_group as expandable
-		from
-			`tab{doctype}`
-		where
-			ifnull(parent_quality_procedure, "")={parent}
-		""".format(
-			doctype = doctype,
-			parent=frappe.db.escape(parent)
-		), as_dict=1)
+	if parent:
+		parent_procedure = frappe.get_doc('Quality Procedure', parent)
+		# return the list in order
+		return [dict(
+				value=d.procedure,
+				expandable=frappe.db.get_value('Quality Procedure', d.procedure, 'is_group'))
+				for d in parent_procedure.processes if d.procedure
+			]
+	else:
+		return frappe.get_all(doctype, fields=['name as value', 'is_group as expandable'],
+			filters = dict(parent_quality_procedure = parent), order_by='name asc')
 
 @frappe.whitelist()
 def add_node():
@@ -88,4 +77,4 @@
 	if args.parent_quality_procedure == 'All Quality Procedures':
 		args.parent_quality_procedure = None
 
-	frappe.get_doc(args).insert()
\ No newline at end of file
+	return frappe.get_doc(args).insert()
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js b/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js
index ef48ab6..eeb4cf6 100644
--- a/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js
+++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js
@@ -15,7 +15,7 @@
 			}
 		},
 	],
-	breadcrumb: "Setup",
+	breadcrumb: "Quality Management",
 	disable_add_node: true,
 	root_label: "All Quality Procedures",
 	get_tree_root: false,
diff --git a/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.js b/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.js
deleted file mode 100644
index 0a187eb..0000000
--- a/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* eslint-disable */
-// rename this file from _test_[name] to test_[name] to activate
-// and remove above this line
-
-QUnit.test("test: Quality Procedure", function (assert) {
-	let done = assert.async();
-
-	// number of asserts
-	assert.expect(1);
-
-	frappe.run_serially([
-		// insert a new Quality Procedure
-		() => frappe.tests.make('Quality Procedure', [
-			// values to be set
-			{key: 'value'}
-		]),
-		() => {
-			assert.equal(cur_frm.doc.key, 'value');
-		},
-		() => done()
-	]);
-
-});
diff --git a/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.py b/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.py
index 3289bb5..36bdf26 100644
--- a/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.py
+++ b/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.py
@@ -6,54 +6,45 @@
 import frappe
 import unittest
 
-class TestQualityProcedure(unittest.TestCase):
-	def test_quality_procedure(self):
-		test_create_procedure = create_procedure()
-		test_create_nested_procedure = create_nested_procedure()
-		test_get_procedure, test_get_nested_procedure = get_procedure()
+from .quality_procedure import add_node
 
-		self.assertEquals(test_create_procedure, test_get_procedure.get("name"))
-		self.assertEquals(test_create_nested_procedure, test_get_nested_procedure.get("name"))
+class TestQualityProcedure(unittest.TestCase):
+	def test_add_node(self):
+		try:
+			procedure = frappe.get_doc(dict(
+				doctype = 'Quality Procedure',
+				quality_procedure_name = 'Test Procedure 1',
+				processes = [
+					dict(process_description = 'Test Step 1')
+				]
+			)).insert()
+
+			frappe.form_dict = dict(doctype = 'Quality Procedure', quality_procedure_name = 'Test Child 1',
+				parent_quality_procedure = procedure.name, cmd='test', is_root='false')
+			node = add_node()
+
+			procedure.reload()
+
+			self.assertEqual(procedure.is_group, 1)
+
+			# child row created
+			self.assertTrue([d for d in procedure.processes if d.procedure == node.name])
+
+			node.delete()
+			procedure.reload()
+
+			# child unset
+			self.assertFalse([d for d in procedure.processes if d.name == node.name])
+
+		finally:
+			procedure.delete()
 
 def create_procedure():
-	procedure = frappe.get_doc({
-		"doctype": "Quality Procedure",
-		"quality_procedure_name": "_Test Quality Procedure",
-		"processes": [
-			{
-				"process_description": "_Test Quality Procedure Table",
-			}
+	return frappe.get_doc(dict(
+		doctype = 'Quality Procedure',
+		quality_procedure_name = 'Test Procedure 1',
+		is_group = 1,
+		processes = [
+			dict(process_description = 'Test Step 1')
 		]
-	})
-
-	procedure_exist = frappe.db.exists("Quality Procedure", "PRC-_Test Quality Procedure")
-
-	if not procedure_exist:
-		procedure.insert()
-		return procedure.name
-	else:
-		return procedure_exist
-
-def create_nested_procedure():
-	nested_procedure = frappe.get_doc({
-		"doctype": "Quality Procedure",
-		"quality_procedure_name": "_Test Nested Quality Procedure",
-		"processes": [
-			{
-				"procedure": "PRC-_Test Quality Procedure"
-			}
-		]
-	})
-
-	nested_procedure_exist = frappe.db.exists("Quality Procedure", "PRC-_Test Nested Quality Procedure")
-
-	if not nested_procedure_exist:
-		nested_procedure.insert()
-		return nested_procedure.name
-	else:
-		return nested_procedure_exist
-
-def get_procedure():
-	procedure = frappe.get_doc("Quality Procedure", "PRC-_Test Quality Procedure")
-	nested_procedure = frappe.get_doc("Quality Procedure",  "PRC-_Test Nested Quality Procedure")
-	return {"name": procedure.name}, {"name": nested_procedure.name, "parent_quality_procedure": nested_procedure.parent_quality_procedure}
\ No newline at end of file
+	)).insert()
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json b/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json
index cf7606e..aeca6ff 100644
--- a/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json
+++ b/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json
@@ -21,14 +21,14 @@
    "fieldname": "procedure",
    "fieldtype": "Link",
    "in_list_view": 1,
-   "label": "Sub Produre",
+   "label": "Sub Procedure",
    "options": "Quality Procedure"
   }
  ],
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-10-21 12:10:23.790655",
+ "modified": "2020-10-27 13:55:11.252945",
  "modified_by": "Administrator",
  "module": "Quality Management",
  "name": "Quality Procedure Process",
diff --git a/erpnext/quality_management/doctype/quality_review/quality_review.py b/erpnext/quality_management/doctype/quality_review/quality_review.py
index ddf6207..e3a8b07 100644
--- a/erpnext/quality_management/doctype/quality_review/quality_review.py
+++ b/erpnext/quality_management/doctype/quality_review/quality_review.py
@@ -8,8 +8,25 @@
 
 class QualityReview(Document):
 	def validate(self):
+		# fetch targets from goal
+		if not self.reviews:
+			for d in frappe.get_doc('Quality Goal', self.goal).objectives:
+				self.append('reviews', dict(
+					objective = d.objective,
+					target = d.target,
+					uom = d.uom
+				))
+
+		self.set_status()
+
+	def set_status(self):
 		# if any child item is failed, fail the parent
-		self.status = 'Failed' if any([d.status=='Failed' for d in self.reviews]) else 'Passed'
+		if not len(self.reviews or []) or any([d.status=='Open' for d in self.reviews]):
+			self.status = 'Open'
+		elif any([d.status=='Failed' for d in self.reviews]):
+			self.status = 'Failed'
+		else:
+			self.status = 'Passed'
 
 def review():
 	day = frappe.utils.getdate().day
@@ -26,7 +43,7 @@
 		elif goal.frequency == 'Monthly' and goal.date == str(day):
 			create_review(goal.name)
 
-		elif goal.frequency == 'Quarterly' and goal.data == str(day) and get_quarter(month):
+		elif goal.frequency == 'Quarterly' and day==1 and get_quarter(month):
 			create_review(goal.name)
 
 def create_review(goal):
@@ -38,15 +55,6 @@
 		"date": frappe.utils.getdate()
 	})
 
-	for objective in goal.objectives:
-		review.append("reviews",
-			{
-				"objective": objective.objective,
-				"target": objective.target,
-				"uom": objective.uom
-			}
-		)
-
 	review.insert(ignore_permissions=True)
 
 def get_quarter(month):
diff --git a/erpnext/quality_management/doctype/quality_review/test_quality_review.js b/erpnext/quality_management/doctype/quality_review/test_quality_review.js
deleted file mode 100644
index cf910b2..0000000
--- a/erpnext/quality_management/doctype/quality_review/test_quality_review.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* eslint-disable */
-// rename this file from _test_[name] to test_[name] to activate
-// and remove above this line
-
-QUnit.test("test: Performance Monitoring", function (assert) {
-	let done = assert.async();
-
-	// number of asserts
-	assert.expect(1);
-
-	frappe.run_serially([
-		// insert a new Performance Monitoring
-		() => frappe.tests.make('Performance Monitoring', [
-			// values to be set
-			{key: 'value'}
-		]),
-		() => {
-			assert.equal(cur_frm.doc.key, 'value');
-		},
-		() => done()
-	]);
-
-});
diff --git a/erpnext/quality_management/doctype/quality_review/test_quality_review.py b/erpnext/quality_management/doctype/quality_review/test_quality_review.py
index 8add6db..a7d92da 100644
--- a/erpnext/quality_management/doctype/quality_review/test_quality_review.py
+++ b/erpnext/quality_management/doctype/quality_review/test_quality_review.py
@@ -5,42 +5,18 @@
 
 import frappe
 import unittest
-from erpnext.quality_management.doctype.quality_procedure.test_quality_procedure import create_procedure
-from erpnext.quality_management.doctype.quality_goal.test_quality_goal import create_unit
-from erpnext.quality_management.doctype.quality_goal.test_quality_goal import create_goal
+
+from ..quality_goal.test_quality_goal import get_quality_goal
+from .quality_review import review
 
 class TestQualityReview(unittest.TestCase):
+	def test_review_creation(self):
+		quality_goal = get_quality_goal()
+		review()
 
-	def test_quality_review(self):
-		create_procedure()
-		create_unit()
-		create_goal()
-		test_create_review = create_review()
-		test_get_review = get_review()
-		self.assertEquals(test_create_review, test_get_review)
+		# check if review exists
+		quality_review = frappe.get_doc('Quality Review', dict(goal = quality_goal.name))
+		self.assertEqual(quality_goal.objectives[0].target, quality_review.reviews[0].target)
+		quality_review.delete()
 
-def create_review():
-	review = frappe.get_doc({
-		"doctype": "Quality Review",
-		"goal": "GOAL-_Test Quality Goal",
-		"procedure": "PRC-_Test Quality Procedure",
-		"date": frappe.utils.nowdate(),
-		"reviews": [
-			{
-				"objective": "_Test Quality Objective",
-				"target": "100",
-				"uom": "_Test UOM",
-				"review": "Test Review"
-			}
-		]
-	})
-	review_exist = frappe.db.exists("Quality Review", {"goal": "GOAL-_Test Quality Goal"})
-	if not review_exist:
-		review.insert(ignore_permissions=True)
-		return review.name
-	else:
-		return review_exist
-
-def get_review():
-	review = frappe.db.exists("Quality Review", {"goal": "GOAL-_Test Quality Goal"})
-	return review
\ No newline at end of file
+		quality_goal.delete()
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_review_objective/quality_review_objective.json b/erpnext/quality_management/doctype/quality_review_objective/quality_review_objective.json
index e31e65e..3a750c2 100644
--- a/erpnext/quality_management/doctype/quality_review_objective/quality_review_objective.json
+++ b/erpnext/quality_management/doctype/quality_review_objective/quality_review_objective.json
@@ -61,13 +61,13 @@
    "fieldtype": "Select",
    "in_list_view": 1,
    "label": "Status",
-   "options": "Passed\nFailed"
+   "options": "Open\nPassed\nFailed"
   }
  ],
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-10-21 12:21:18.460863",
+ "modified": "2020-10-27 16:28:20.908637",
  "modified_by": "Administrator",
  "module": "Quality Management",
  "name": "Quality Review Objective",