Merge pull request #22853 from ruchamahabal/refactor-lab-module

refactor: Laboratory Module
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.js b/erpnext/healthcare/doctype/lab_test/lab_test.js
index 8036c7d..f1634c1 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.js
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.js
@@ -34,10 +34,10 @@
 			if (frm.doc.docstatus === 1 && frm.doc.status !== 'Approved' && frm.doc.status !== 'Rejected') {
 				frm.add_custom_button(__('Approve'), function () {
 					status_update(1, frm);
-				});
+				}, __('Actions'));
 				frm.add_custom_button(__('Reject'), function () {
 					status_update(0, frm);
-				});
+				}, __('Actions'));
 			}
 		}
 
@@ -179,23 +179,6 @@
 	d.show();
 };
 
-cur_frm.cscript.custom_before_submit = function (doc) {
-	if (doc.normal_test_items) {
-		for (let result in doc.normal_test_items) {
-			if (!doc.normal_test_items[result].result_value && !doc.normal_test_items[result].allow_blank && doc.normal_test_items[result].require_result_value) {
-				frappe.throw(__('Please input all required result values'));
-			}
-		}
-	}
-	if (doc.descriptive_test_items) {
-		for (let result in doc.descriptive_test_items) {
-			if (!doc.descriptive_test_items[result].result_value && !doc.descriptive_test_items[result].allow_blank && doc.descriptive_test_items[result].require_result_value) {
-				frappe.throw(__('Please input all required result values'));
-			}
-		}
-	}
-};
-
 var make_dialog = function (frm, emailed, printed) {
 	var number = frm.doc.mobile;
 
@@ -203,7 +186,7 @@
 		title: 'Send SMS',
 		width: 400,
 		fields: [
-			{ fieldname: 'sms_type', fieldtype: 'Select', label: 'Type', options: ['Emailed', 'Printed'] },
+			{ fieldname: 'result_format', fieldtype: 'Select', label: 'Result Format', options: ['Emailed', 'Printed'] },
 			{ fieldname: 'number', fieldtype: 'Data', label: 'Mobile Number', reqd: 1 },
 			{ fieldname: 'message', fieldtype: 'Small Text', label: 'Message', reqd: 1 }
 		],
@@ -217,22 +200,22 @@
 			dialog.hide();
 		}
 	});
-	if (frm.doc.report_preference == 'Print') {
+	if (frm.doc.report_preference === 'Print') {
 		dialog.set_values({
-			'sms_type': 'Printed',
+			'result_format': 'Printed',
 			'number': number,
 			'message': printed
 		});
 	} else {
 		dialog.set_values({
-			'sms_type': 'Emailed',
+			'result_format': 'Emailed',
 			'number': number,
 			'message': emailed
 		});
 	}
 	var fd = dialog.fields_dict;
-	$(fd.sms_type.input).change(function () {
-		if (dialog.get_value('sms_type') == 'Emailed') {
+	$(fd.result_format.input).change(function () {
+		if (dialog.get_value('result_format') === 'Emailed') {
 			dialog.set_values({
 				'number': number,
 				'message': emailed
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.json b/erpnext/healthcare/doctype/lab_test/lab_test.json
index 2eb8014..edf1d91 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.json
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.json
@@ -84,7 +84,7 @@
    "fieldname": "naming_series",
    "fieldtype": "Select",
    "label": "Series",
-   "options": "LP-",
+   "options": "HLC-LAB-.YYYY.-",
    "print_hide": 1,
    "report_hide": 1,
    "reqd": 1
@@ -197,11 +197,10 @@
   {
    "fieldname": "status",
    "fieldtype": "Select",
+   "in_list_view": 1,
    "label": "Status",
    "options": "Draft\nCompleted\nApproved\nRejected\nCancelled",
-   "print_hide": 1,
    "read_only": 1,
-   "report_hide": 1,
    "search_index": 1
   },
   {
@@ -249,8 +248,8 @@
   {
    "fieldname": "result_date",
    "fieldtype": "Date",
-   "hidden": 1,
    "label": "Result Date",
+   "read_only": 1,
    "search_index": 1
   },
   {
@@ -354,7 +353,8 @@
   },
   {
    "fieldname": "sb_normal",
-   "fieldtype": "Section Break"
+   "fieldtype": "Section Break",
+   "label": "Compound Test Result"
   },
   {
    "fieldname": "normal_test_items",
@@ -369,11 +369,13 @@
   {
    "depends_on": "descriptive_toggle",
    "fieldname": "organisms_section",
-   "fieldtype": "Section Break"
+   "fieldtype": "Section Break",
+   "label": "Organism Test Result"
   },
   {
    "fieldname": "sb_sensitivity",
-   "fieldtype": "Section Break"
+   "fieldtype": "Section Break",
+   "label": "Sensitivity Test Result"
   },
   {
    "fieldname": "sensitivity_test_items",
@@ -383,8 +385,10 @@
    "report_hide": 1
   },
   {
+   "collapsible": 1,
    "fieldname": "sb_comments",
-   "fieldtype": "Section Break"
+   "fieldtype": "Section Break",
+   "label": "Comments"
   },
   {
    "fieldname": "lab_test_comment",
@@ -531,7 +535,8 @@
   },
   {
    "fieldname": "sb_descriptive",
-   "fieldtype": "Section Break"
+   "fieldtype": "Section Break",
+   "label": "Descriptive Test Result"
   },
   {
    "default": "0",
@@ -550,7 +555,7 @@
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2020-07-16 13:35:24.811062",
+ "modified": "2020-07-30 18:18:38.516215",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Lab Test",
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.py b/erpnext/healthcare/doctype/lab_test/lab_test.py
index 865f4a1..2db7743 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.py
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.py
@@ -6,23 +6,24 @@
 import frappe
 from frappe import _
 from frappe.model.document import Document
-from frappe.utils import getdate, cstr
+from frappe.utils import getdate, cstr, get_link_to_form
 
 class LabTest(Document):
+	def validate(self):
+		if not self.is_new():
+			self.set_secondary_uom_result()
+
 	def on_submit(self):
+		self.validate_result_values()
 		self.db_set('submitted_date', getdate())
 		self.db_set('status', 'Completed')
 		insert_lab_test_to_medical_record(self)
 
 	def on_cancel(self):
-		delete_lab_test_from_medical_record(self)
 		self.db_set('status', 'Cancelled')
+		delete_lab_test_from_medical_record(self)
 		self.reload()
 
-	def validate(self):
-		if not self.is_new():
-			self.set_secondary_uom_result()
-
 	def on_update(self):
 		if self.sensitivity_test_items:
 			sensitivity = sorted(self.sensitivity_test_items, key=lambda x: x.antibiotic_sensitivity)
@@ -51,7 +52,20 @@
 					item.secondary_uom_result = float(item.result_value) * float(item.conversion_factor)
 				except:
 					item.secondary_uom_result = ''
-					frappe.msgprint(_('Result for Secondary UOM not calculated for row #{0}'.format(item.idx)), title = _('Warning'))
+					frappe.msgprint(_('Row #{0}: Result for Secondary UOM not calculated'.format(item.idx)), title = _('Warning'))
+
+	def validate_result_values(self):
+		if self.normal_test_items:
+			for item in self.normal_test_items:
+				if not item.result_value and not item.allow_blank and item.require_result_value:
+					frappe.throw(_('Row #{0}: Please enter the result value for {1}').format(
+						item.idx, frappe.bold(item.lab_test_name)), title=_('Mandatory Results'))
+
+		if self.descriptive_test_items:
+			for item in self.descriptive_test_items:
+				if not item.result_value and not item.allow_blank and item.require_result_value:
+					frappe.throw(_('Row #{0}: Please enter the result value for {1}').format(
+						item.idx, frappe.bold(item.lab_test_particulars)), title=_('Mandatory Results'))
 
 
 def create_test_from_template(lab_test):
@@ -89,7 +103,7 @@
 		lab_test_created = create_lab_test_from_encounter(docname)
 
 	if lab_test_created:
-		frappe.msgprint(_('Lab Test(s) {0} created'.format(lab_test_created)))
+		frappe.msgprint(_('Lab Test(s) {0} created successfully').format(lab_test_created), indicator='green')
 	else:
 		frappe.msgprint(_('No Lab Tests created'))
 
@@ -211,8 +225,9 @@
 			'docstatus': 0,
 			'sample': template.sample
 		})
+
 		if sample_exists:
-			# Update Sample Collection by adding quantity
+			# update sample collection by adding quantity
 			sample_collection = frappe.get_doc('Sample Collection', sample_exists[0][0])
 			quantity = int(sample_collection.sample_qty) + int(template.sample_qty)
 			if template.sample_details:
@@ -238,7 +253,7 @@
 			sample_collection.company = company
 
 			if template.sample_details:
-				sample_collection.sample_details = 'Test :' + (template.get('lab_test_name') or template.get('template')) + '\n' + 'Collection Detials:\n\t' + template.sample_details
+				sample_collection.sample_details = _('Test :') + (template.get('lab_test_name') or template.get('template')) + '\n' + 'Collection Detials:\n\t' + template.sample_details
 			sample_collection.save(ignore_permissions=True)
 
 		return sample_collection
@@ -248,26 +263,31 @@
 		sample_collection = create_sample_doc(template, patient, invoice, lab_test.company)
 		if sample_collection:
 			lab_test.sample = sample_collection.name
-
+			sample_collection_doc = get_link_to_form('Sample Collection', sample_collection.name)
+			frappe.msgprint(_('Sample Collection {0} has been created').format(sample_collection_doc),
+				title=_('Sample Collection'), indicator='green')
 	return lab_test
 
 def load_result_format(lab_test, template, prescription, invoice):
 	if template.lab_test_template_type == 'Single':
 		create_normals(template, lab_test)
+
 	elif template.lab_test_template_type == 'Compound':
 		create_compounds(template, lab_test, False)
+
 	elif template.lab_test_template_type == 'Descriptive':
 		create_descriptives(template, lab_test)
+
 	elif template.lab_test_template_type == 'Grouped':
 		# Iterate for each template in the group and create one result for all.
 		for lab_test_group in template.lab_test_groups:
 			# Template_in_group = None
 			if lab_test_group.lab_test_template:
-				template_in_group = frappe.get_doc('Lab Test Template',
-								lab_test_group.lab_test_template)
+				template_in_group = frappe.get_doc('Lab Test Template', lab_test_group.lab_test_template)
 				if template_in_group:
 					if template_in_group.lab_test_template_type == 'Single':
 						create_normals(template_in_group, lab_test)
+
 					elif template_in_group.lab_test_template_type == 'Compound':
 						normal_heading = lab_test.append('normal_test_items')
 						normal_heading.lab_test_name = template_in_group.lab_test_name
@@ -275,6 +295,7 @@
 						normal_heading.allow_blank = 1
 						normal_heading.template = template_in_group.name
 						create_compounds(template_in_group, lab_test, True)
+
 					elif template_in_group.lab_test_template_type == 'Descriptive':
 						descriptive_heading = lab_test.append('descriptive_test_items')
 						descriptive_heading.lab_test_name = template_in_group.lab_test_name
@@ -282,6 +303,7 @@
 						descriptive_heading.allow_blank = 1
 						descriptive_heading.template = template_in_group.name
 						create_descriptives(template_in_group, lab_test)
+
 			else: # Lab Test Group - Add New Line
 				normal = lab_test.append('normal_test_items')
 				normal.lab_test_name = lab_test_group.group_event
@@ -292,6 +314,7 @@
 				normal.allow_blank = lab_test_group.allow_blank
 				normal.require_result_value = 1
 				normal.template = template.name
+
 	if template.lab_test_template_type != 'No Result':
 		if prescription:
 			lab_test.prescription = prescription
@@ -302,9 +325,10 @@
 
 @frappe.whitelist()
 def get_employee_by_user_id(user_id):
-	emp_id = frappe.db.get_value('Employee', { 'user_id': user_id })
-	employee = frappe.get_doc('Employee', emp_id)
-	return employee
+	emp_id = frappe.db.exists('Employee', { 'user_id': user_id })
+	if emp_id:
+		return frappe.get_doc('Employee', emp_id)
+	return None
 
 def insert_lab_test_to_medical_record(doc):
 	table_row = False
@@ -325,7 +349,7 @@
 			table_row += ' ' + frappe.bold(_('Lab Test Result: ')) + item.result_value
 
 		if item.normal_range:
-			table_row += ' ' + _('Normal Range:') + item.normal_range
+			table_row += ' ' + _('Normal Range: ') + item.normal_range
 		table_row += ' ' + comment
 
 	elif doc.descriptive_test_items:
@@ -356,7 +380,7 @@
 	medical_record.save(ignore_permissions = True)
 
 def delete_lab_test_from_medical_record(self):
-	medical_record_id = frappe.db.sql('select name from `tabPatient Medical Record` where reference_name= %s', (self.name))
+	medical_record_id = frappe.db.sql('select name from `tabPatient Medical Record` where reference_name=%s', (self.name))
 
 	if medical_record_id and medical_record_id[0][0]:
 		frappe.delete_doc('Patient Medical Record', medical_record_id[0][0])
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test_list.js b/erpnext/healthcare/doctype/lab_test/lab_test_list.js
index b7f157c..7b5b9d9 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test_list.js
+++ b/erpnext/healthcare/doctype/lab_test/lab_test_list.js
@@ -3,13 +3,16 @@
 */
 frappe.listview_settings['Lab Test'] = {
 	add_fields: ['name', 'status', 'invoiced'],
-	filters: [['docstatus', '=', '0']],
+	filters: [['docstatus', '=', '1']],
 	get_indicator: function (doc) {
-		if (doc.status == 'Approved') {
-			return [__('Approved'), 'green', 'status, = ,Approved'];
-		}
-		if (doc.status == 'Rejected') {
+		if (doc.status === 'Approved') {
+			return [__('Approved'), 'green', 'status, =, Approved'];
+		} else if (doc.status === 'Rejected') {
 			return [__('Rejected'), 'orange', 'status, =, Rejected'];
+		} else if (doc.status === 'Completed') {
+			return [__('Completed'), 'green', 'status, =, Completed'];
+		} else if (doc.status === 'Cancelled') {
+			return [__('Cancelled'), 'red', 'status, =, Cancelled'];
 		}
 	},
 	onload: function (listview) {
@@ -21,7 +24,7 @@
 
 var create_multiple_dialog = function (listview) {
 	var dialog = new frappe.ui.Dialog({
-		title: 'Create Multiple Lab Test',
+		title: 'Create Multiple Lab Tests',
 		width: 100,
 		fields: [
 			{ fieldtype: 'Link', label: 'Patient', fieldname: 'patient', options: 'Patient', reqd: 1 },
@@ -41,7 +44,7 @@
 				}
 			}
 		],
-		primary_action_label: __('Create Lab Test'),
+		primary_action_label: __('Create'),
 		primary_action: function () {
 			frappe.call({
 				method: 'erpnext.healthcare.doctype.lab_test.lab_test.create_multiple',
diff --git a/erpnext/healthcare/doctype/lab_test/test_lab_test.py b/erpnext/healthcare/doctype/lab_test/test_lab_test.py
index 4131ad9..79ab8a4 100644
--- a/erpnext/healthcare/doctype/lab_test/test_lab_test.py
+++ b/erpnext/healthcare/doctype/lab_test/test_lab_test.py
@@ -3,8 +3,204 @@
 # See license.txt
 from __future__ import unicode_literals
 import unittest
-
-# test_records = frappe.get_test_records('Lab Test')
+import frappe
+from frappe.utils import getdate, nowtime
+from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_patient
+from erpnext.healthcare.doctype.lab_test.lab_test import create_multiple
+from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account, get_income_account
+from erpnext.healthcare.doctype.patient_medical_record.test_patient_medical_record import create_lab_test_template as create_blood_test_template
 
 class TestLabTest(unittest.TestCase):
-	pass
+	def test_lab_test_item(self):
+		lab_template = create_lab_test_template()
+		self.assertTrue(frappe.db.exists('Item', lab_template.item))
+		self.assertEqual(frappe.db.get_value('Item Price', {'item_code':lab_template.item}, 'price_list_rate'), lab_template.lab_test_rate)
+
+		lab_template.disabled = 1
+		lab_template.save()
+		self.assertEquals(frappe.db.get_value('Item', lab_template.item, 'disabled'), 1)
+
+		lab_template.reload()
+
+		lab_template.disabled = 0
+		lab_template.save()
+
+	def test_descriptive_lab_test(self):
+		lab_template = create_lab_test_template()
+
+		# blank result value not allowed as per template
+		lab_test = create_lab_test(lab_template)
+		lab_test.descriptive_test_items[0].result_value = 12
+		lab_test.descriptive_test_items[2].result_value = 1
+		lab_test.save()
+		self.assertRaises(frappe.ValidationError, lab_test.submit)
+
+	def test_sample_collection(self):
+		frappe.db.set_value('Healthcare Settings', 'Healthcare Settings', 'create_sample_collection_for_lab_test', 1)
+		lab_template = create_lab_test_template()
+
+		lab_test = create_lab_test(lab_template)
+		lab_test.descriptive_test_items[0].result_value = 12
+		lab_test.descriptive_test_items[1].result_value = 1
+		lab_test.descriptive_test_items[2].result_value = 2.3
+		lab_test.save()
+
+		# check sample collection created
+		self.assertTrue(frappe.db.exists('Sample Collection', {'sample': lab_template.sample}))
+
+		frappe.db.set_value('Healthcare Settings', 'Healthcare Settings', 'create_sample_collection_for_lab_test', 0)
+		lab_test = create_lab_test(lab_template)
+		lab_test.descriptive_test_items[0].result_value = 12
+		lab_test.descriptive_test_items[1].result_value = 1
+		lab_test.descriptive_test_items[2].result_value = 2.3
+		lab_test.save()
+
+		# sample collection should not be created
+		lab_test.reload()
+		self.assertEquals(lab_test.sample, None)
+
+	def test_create_lab_tests_from_sales_invoice(self):
+		sales_invoice = create_sales_invoice()
+		create_multiple('Sales Invoice', sales_invoice.name)
+		sales_invoice.reload()
+		self.assertIsNotNone(sales_invoice.items[0].reference_dn)
+		self.assertIsNotNone(sales_invoice.items[1].reference_dn)
+
+	def test_create_lab_tests_from_patient_encounter(self):
+		patient_encounter = create_patient_encounter()
+		create_multiple('Patient Encounter', patient_encounter.name)
+		patient_encounter.reload()
+		self.assertTrue(patient_encounter.lab_test_prescription[0].lab_test_created)
+		self.assertTrue(patient_encounter.lab_test_prescription[0].lab_test_created)
+
+
+def create_lab_test_template(test_sensitivity=0, sample_collection=1):
+	medical_department = create_medical_department()
+	if frappe.db.exists('Lab Test Template', 'Insulin Resistance'):
+		return frappe.get_doc('Lab Test Template', 'Insulin Resistance')
+	template = frappe.new_doc('Lab Test Template')
+	template.lab_test_name = 'Insulin Resistance'
+	template.lab_test_template_type = 'Descriptive'
+	template.lab_test_code = 'Insulin Resistance'
+	template.lab_test_group = 'Services'
+	template.department = medical_department
+	template.is_billable = 1
+	template.lab_test_description = 'Insulin Resistance'
+	template.lab_test_rate = 2000
+
+	for entry in ['FBS', 'Insulin', 'IR']:
+		template.append('descriptive_test_templates', {
+			'particulars': entry,
+			'allow_blank': 1 if entry=='IR' else 0
+		})
+
+	if test_sensitivity:
+		template.sensitivity = 1
+
+	if sample_collection:
+		template.sample = create_lab_test_sample()
+		template.sample_qty = 5.0
+
+	template.save()
+	return template
+
+def create_medical_department():
+	medical_department = frappe.db.exists('Medical Department', '_Test Medical Department')
+	if not medical_department:
+		medical_department = frappe.new_doc('Medical Department')
+		medical_department.department = '_Test Medical Department'
+		medical_department.save()
+		medical_department = medical_department.name
+
+	return medical_department
+
+def create_lab_test(lab_template):
+	patient = create_patient()
+	lab_test = frappe.new_doc('Lab Test')
+	lab_test.template = lab_template.name
+	lab_test.patient = patient
+	lab_test.patient_sex = 'Female'
+	lab_test.save()
+
+	return lab_test
+
+def create_lab_test_sample():
+	blood_sample = frappe.db.exists('Lab Test Sample', 'Blood Sample')
+	if blood_sample:
+		return blood_sample
+
+	sample = frappe.new_doc('Lab Test Sample')
+	sample.sample = 'Blood Sample'
+	sample.sample_uom = 'U/ml'
+	sample.save()
+
+	return sample.name
+
+def create_sales_invoice():
+	patient = create_patient()
+	medical_department = create_medical_department()
+	insulin_resistance_template = create_lab_test_template()
+	blood_test_template = create_blood_test_template(medical_department)
+
+	sales_invoice = frappe.new_doc('Sales Invoice')
+	sales_invoice.patient = patient
+	sales_invoice.customer = frappe.db.get_value('Patient', patient, 'customer')
+	sales_invoice.due_date = getdate()
+	sales_invoice.company = '_Test Company'
+	sales_invoice.debit_to = get_receivable_account('_Test Company')
+
+	tests = [insulin_resistance_template, blood_test_template]
+	for entry in tests:
+		sales_invoice.append('items', {
+			'item_code': entry.item,
+			'item_name': entry.lab_test_name,
+			'description': entry.lab_test_description,
+			'qty': 1,
+			'uom': 'Nos',
+			'conversion_factor': 1,
+			'income_account': get_income_account(None, '_Test Company'),
+			'rate': entry.lab_test_rate,
+			'amount': entry.lab_test_rate
+		})
+
+	sales_invoice.set_missing_values()
+
+	sales_invoice.submit()
+	return sales_invoice
+
+def create_patient_encounter():
+	patient = create_patient()
+	medical_department = create_medical_department()
+	insulin_resistance_template = create_lab_test_template()
+	blood_test_template = create_blood_test_template(medical_department)
+
+	patient_encounter = frappe.new_doc('Patient Encounter')
+	patient_encounter.patient = patient
+	patient_encounter.practitioner = create_practitioner()
+	patient_encounter.encounter_date = getdate()
+	patient_encounter.encounter_time = nowtime()
+
+	tests = [insulin_resistance_template, blood_test_template]
+	for entry in tests:
+		patient_encounter.append('lab_test_prescription', {
+			'lab_test_code': entry.item,
+			'lab_test_name': entry.lab_test_name
+		})
+
+	patient_encounter.submit()
+	return patient_encounter
+
+
+def create_practitioner():
+	practitioner = frappe.db.exists('Healthcare Practitioner', '_Test Healthcare Practitioner')
+
+	if not practitioner:
+		practitioner = frappe.new_doc('Healthcare Practitioner')
+		practitioner.first_name = '_Test Healthcare Practitioner'
+		practitioner.gender = 'Female'
+		practitioner.op_consulting_charge = 500
+		practitioner.inpatient_visit_charge = 500
+		practitioner.save(ignore_permissions=True)
+		practitioner = practitioner.name
+
+	return practitioner
diff --git a/erpnext/healthcare/doctype/lab_test_group_template/lab_test_group_template.json b/erpnext/healthcare/doctype/lab_test_group_template/lab_test_group_template.json
index beea7a3..2767f7e 100644
--- a/erpnext/healthcare/doctype/lab_test_group_template/lab_test_group_template.json
+++ b/erpnext/healthcare/doctype/lab_test_group_template/lab_test_group_template.json
@@ -93,7 +93,8 @@
    "depends_on": "secondary_uom",
    "fieldname": "conversion_factor",
    "fieldtype": "Float",
-   "label": "Conversion Factor"
+   "label": "Conversion Factor",
+   "mandatory_depends_on": "secondary_uom"
   },
   {
    "default": "0",
@@ -106,7 +107,7 @@
  ],
  "istable": 1,
  "links": [],
- "modified": "2020-06-24 10:59:01.921924",
+ "modified": "2020-07-30 12:36:03.082391",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Lab Test Group Template",
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json
index db64297..c3fc842 100644
--- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json
+++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json
@@ -34,14 +34,15 @@
   "descriptive_test_templates",
   "section_break_group",
   "lab_test_groups",
-  "medical_coding_section",
-  "medical_code_standard",
-  "medical_code",
   "sb_sample_collection",
   "sample",
   "sample_uom",
   "sample_qty",
+  "column_break_33",
   "sample_details",
+  "medical_coding_section",
+  "medical_code",
+  "medical_code_standard",
   "worksheet_section",
   "worksheet_instructions",
   "result_legend_section",
@@ -112,7 +113,7 @@
   {
    "default": "1",
    "depends_on": "eval:doc.lab_test_template_type != 'Grouped'",
-   "description": "If unchecked, the item wont be appear in Sales Invoice, but can be used in group test creation. ",
+   "description": "If unchecked, the item will not be available in Sales Invoices for billing but can be used in group test creation. ",
    "fieldname": "is_billable",
    "fieldtype": "Check",
    "label": "Is Billable",
@@ -128,6 +129,7 @@
    "mandatory_depends_on": "eval:doc.is_billable == 1"
   },
   {
+   "collapsible": 1,
    "fieldname": "medical_coding_section",
    "fieldtype": "Section Break",
    "label": "Medical Coding"
@@ -184,7 +186,7 @@
    "depends_on": "eval:doc.lab_test_template_type == 'Descriptive'",
    "fieldname": "section_break_special",
    "fieldtype": "Section Break",
-   "label": "Descriptive"
+   "label": "Descriptive Test"
   },
   {
    "default": "0",
@@ -196,7 +198,7 @@
    "depends_on": "eval:doc.lab_test_template_type == 'Grouped'",
    "fieldname": "section_break_group",
    "fieldtype": "Section Break",
-   "label": "Group"
+   "label": "Group Tests"
   },
   {
    "fieldname": "lab_test_groups",
@@ -217,7 +219,6 @@
    "no_copy": 1
   },
   {
-   "collapsible": 1,
    "fieldname": "sb_sample_collection",
    "fieldtype": "Section Break",
    "label": "Sample Collection"
@@ -311,10 +312,14 @@
    "fieldname": "descriptive_test_templates",
    "fieldtype": "Table",
    "options": "Descriptive Test Template"
+  },
+  {
+   "fieldname": "column_break_33",
+   "fieldtype": "Column Break"
   }
  ],
  "links": [],
- "modified": "2020-07-13 12:57:09.925436",
+ "modified": "2020-07-30 14:32:40.449818",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Lab Test Template",
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
index 6f0d08c..543dee2 100644
--- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
+++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
@@ -15,7 +15,8 @@
 
 	def validate(self):
 		if self.is_billable and (not self.lab_test_rate or self.lab_test_rate <= 0.0):
-			frappe.throw(_("Standard Selling Rate should be greater than zero."))
+			frappe.throw(_('Standard Selling Rate should be greater than zero.'))
+
 		self.validate_conversion_factor()
 		self.enable_disable_item()
 
@@ -42,7 +43,9 @@
 		# Remove template reference from item and disable item
 		if self.item:
 			try:
-				frappe.delete_doc('Item', self.item)
+				item = self.item
+				self.db_set('item', '')
+				frappe.delete_doc('Item', item)
 			except Exception:
 				frappe.throw(_('Not permitted. Please disable the Lab Test Template'))
 
@@ -63,26 +66,26 @@
 				'standard_rate': self.lab_test_rate,
 				'description': self.lab_test_description
 			})
-			item.save()
+			item.flags.ignore_mandatory = True
+			item.save(ignore_permissions=True)
 
 	def item_price_exists(self):
 		item_price = frappe.db.exists({'doctype': 'Item Price', 'item_code': self.lab_test_code})
 		if item_price:
 			return item_price[0][0]
-		else:
-			return False
+		return False
 
 	def validate_conversion_factor(self):
-		if self.lab_test_template_type == "Single" and self.secondary_uom and not self.conversion_factor:
-			frappe.throw(_("Conversion Factor is mandatory"))
-		if self.lab_test_template_type == "Compound":
+		if self.lab_test_template_type == 'Single' and self.secondary_uom and not self.conversion_factor:
+			frappe.throw(_('Conversion Factor is mandatory'))
+		if self.lab_test_template_type == 'Compound':
 			for item in self.normal_test_templates:
 				if item.secondary_uom and not item.conversion_factor:
-					frappe.throw(_("Conversion Factor is mandatory"))
-		if self.lab_test_template_type == "Grouped":
+					frappe.throw(_('Row #{0}: Conversion Factor is mandatory').format(item.idx))
+		if self.lab_test_template_type == 'Grouped':
 			for group in self.lab_test_groups:
-				if group.template_or_new_line == "Add New Line" and group.secondary_uom and not group.conversion_factor:
-					frappe.throw(_("Conversion Factor is mandatory"))
+				if group.template_or_new_line == 'Add New Line' and group.secondary_uom and not group.conversion_factor:
+					frappe.throw(_('Row #{0}: Conversion Factor is mandatory').format(group.idx))
 
 
 def create_item_from_template(doc):
@@ -101,9 +104,9 @@
 		'include_item_in_manufacturing': 0,
 		'show_in_website': 0,
 		'is_pro_applicable': 0,
-		'disabled': 0 if doc.is_billable and not doc.disabled else doc.disabled, 
+		'disabled': 0 if doc.is_billable and not doc.disabled else doc.disabled,
 		'stock_uom': uom
-	}).insert(ignore_permissions = True, ignore_mandatory = True)
+	}).insert(ignore_permissions=True, ignore_mandatory=True)
 
 	# Insert item price
 	if doc.is_billable and doc.lab_test_rate != 0.0:
@@ -123,7 +126,7 @@
 		'price_list': price_list_name,
 		'item_code': item,
 		'price_list_rate': item_price
-	}).insert(ignore_permissions = True, ignore_mandatory = True)
+	}).insert(ignore_permissions=True, ignore_mandatory=True)
 
 @frappe.whitelist()
 def change_test_code_from_template(lab_test_code, doc):
@@ -132,8 +135,8 @@
 	if frappe.db.exists({'doctype': 'Item', 'item_code': lab_test_code}):
 		frappe.throw(_('Lab Test Item {0} already exist').format(lab_test_code))
 	else:
-		rename_doc('Item', doc.name, lab_test_code, ignore_permissions = True)
+		rename_doc('Item', doc.name, lab_test_code, ignore_permissions=True)
 		frappe.db.set_value('Lab Test Template', doc.name, 'lab_test_code', lab_test_code)
 		frappe.db.set_value('Lab Test Template', doc.name, 'lab_test_name', lab_test_code)
-		rename_doc('Lab Test Template', doc.name, lab_test_code, ignore_permissions = True)
+		rename_doc('Lab Test Template', doc.name, lab_test_code, ignore_permissions=True)
 	return lab_test_code
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template_dashboard.py b/erpnext/healthcare/doctype/lab_test_template/lab_test_template_dashboard.py
new file mode 100644
index 0000000..94dfeea
--- /dev/null
+++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template_dashboard.py
@@ -0,0 +1,13 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+	return {
+		'fieldname': 'template',
+		'transactions': [
+			{
+				'label': _('Lab Tests'),
+				'items': ['Lab Test']
+			}
+		]
+	}
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template_list.js b/erpnext/healthcare/doctype/lab_test_template/lab_test_template_list.js
index a3417eb..08fc2cd 100644
--- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template_list.js
+++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template_list.js
@@ -3,5 +3,5 @@
 */
 frappe.listview_settings['Lab Test Template'] = {
 	add_fields: ['lab_test_name', 'lab_test_code', 'lab_test_rate'],
-	filters: [['disabled', '=', 0]]
+	filters: [['disabled', '=', 'No']]
 };
diff --git a/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.py b/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.py
index e5a5e4c..aa85a23 100644
--- a/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.py
+++ b/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.py
@@ -34,7 +34,7 @@
 		self.assertTrue(medical_rec)
 
 		template = create_lab_test_template(medical_department)
-		lab_test = create_lab_test(template, patient)
+		lab_test = create_lab_test(template.name, patient)
 		# check for lab test
 		medical_rec = frappe.db.exists('Patient Medical Record', {'status': 'Open', 'reference_name': lab_test.name})
 		self.assertTrue(medical_rec)
@@ -66,7 +66,7 @@
 
 def create_lab_test_template(medical_department):
 	if frappe.db.exists('Lab Test Template', 'Blood Test'):
-		return 'Blood Test'
+		return frappe.get_doc('Lab Test Template', 'Blood Test')
 
 	template = frappe.new_doc('Lab Test Template')
 	template.lab_test_name = 'Blood Test'
@@ -76,7 +76,7 @@
 	template.is_billable = 1
 	template.lab_test_rate = 2000
 	template.save()
-	return template.name
+	return template
 
 def create_lab_test(template, patient):
 	lab_test = frappe.new_doc('Lab Test')
diff --git a/erpnext/healthcare/doctype/sample_collection/sample_collection.js b/erpnext/healthcare/doctype/sample_collection/sample_collection.js
index 2f5278b..0390391 100644
--- a/erpnext/healthcare/doctype/sample_collection/sample_collection.js
+++ b/erpnext/healthcare/doctype/sample_collection/sample_collection.js
@@ -3,29 +3,29 @@
 
 frappe.ui.form.on('Sample Collection', {
 	refresh: function(frm) {
-		if(frappe.defaults.get_default("create_sample_collection_for_lab_test")){
-			frm.add_custom_button(__("View Lab Tests"), function() {
-				frappe.route_options = {"sample": frm.doc.name};
-				frappe.set_route("List", "Lab Test");
+		if (frappe.defaults.get_default('create_sample_collection_for_lab_test')) {
+			frm.add_custom_button(__('View Lab Tests'), function() {
+				frappe.route_options = {'sample': frm.doc.name};
+				frappe.set_route('List', 'Lab Test');
 			});
 		}
 	}
 });
 
-frappe.ui.form.on("Sample Collection", "patient", function(frm) {
+frappe.ui.form.on('Sample Collection', 'patient', function(frm) {
 	if(frm.doc.patient){
 		frappe.call({
-			"method": "erpnext.healthcare.doctype.patient.patient.get_patient_detail",
+			'method': 'erpnext.healthcare.doctype.patient.patient.get_patient_detail',
 			args: {
 				patient: frm.doc.patient
 			},
 			callback: function (data) {
 				var age = null;
-				if(data.message.dob){
+				if (data.message.dob){
 					age = calculate_age(data.message.dob);
 				}
-				frappe.model.set_value(frm.doctype,frm.docname, "patient_age", age);
-				frappe.model.set_value(frm.doctype,frm.docname, "patient_sex", data.message.sex);
+				frappe.model.set_value(frm.doctype,frm.docname, 'patient_age', age);
+				frappe.model.set_value(frm.doctype,frm.docname, 'patient_sex', data.message.sex);
 			}
 		});
 	}
@@ -36,5 +36,5 @@
 	var	age = new Date();
 	age.setTime(ageMS);
 	var	years =  age.getFullYear() - 1970;
-	return  years + " Year(s) " + age.getMonth() + " Month(s) " + age.getDate() + " Day(s)";
+	return  years + ' Year(s) ' + age.getMonth() + ' Month(s) ' + age.getDate() + ' Day(s)';
 };
diff --git a/erpnext/healthcare/doctype/sample_collection/sample_collection.json b/erpnext/healthcare/doctype/sample_collection/sample_collection.json
index 016cfbc..83383e3 100644
--- a/erpnext/healthcare/doctype/sample_collection/sample_collection.json
+++ b/erpnext/healthcare/doctype/sample_collection/sample_collection.json
@@ -9,8 +9,10 @@
  "document_type": "Document",
  "engine": "InnoDB",
  "field_order": [
+  "patient_details_section",
   "naming_series",
   "patient",
+  "patient_name",
   "patient_age",
   "patient_sex",
   "column_break_4",
@@ -25,15 +27,17 @@
   "collected_by",
   "collected_time",
   "num_print",
-  "amended_from",
   "section_break_15",
-  "sample_details"
+  "sample_details",
+  "amended_from"
  ],
  "fields": [
   {
    "fetch_from": "patient.inpatient_record",
    "fieldname": "inpatient_record",
    "fieldtype": "Link",
+   "hide_days": 1,
+   "hide_seconds": 1,
    "label": "Inpatient Record",
    "options": "Inpatient Record",
    "read_only": 1
@@ -42,6 +46,8 @@
    "bold": 1,
    "fieldname": "naming_series",
    "fieldtype": "Select",
+   "hide_days": 1,
+   "hide_seconds": 1,
    "label": "Series",
    "no_copy": 1,
    "options": "HLC-SC-.YYYY.-",
@@ -52,6 +58,8 @@
    "default": "0",
    "fieldname": "invoiced",
    "fieldtype": "Check",
+   "hide_days": 1,
+   "hide_seconds": 1,
    "label": "Invoiced",
    "no_copy": 1,
    "read_only": 1,
@@ -61,41 +69,60 @@
    "fetch_from": "inpatient_record.patient",
    "fieldname": "patient",
    "fieldtype": "Link",
+   "hide_days": 1,
+   "hide_seconds": 1,
    "ignore_user_permissions": 1,
    "in_standard_filter": 1,
    "label": "Patient",
    "options": "Patient",
+   "reqd": 1,
    "search_index": 1
   },
   {
    "fieldname": "column_break_4",
-   "fieldtype": "Column Break"
+   "fieldtype": "Column Break",
+   "hide_days": 1,
+   "hide_seconds": 1
   },
   {
    "fieldname": "patient_age",
    "fieldtype": "Data",
-   "label": "Age"
+   "hide_days": 1,
+   "hide_seconds": 1,
+   "label": "Age",
+   "read_only": 1
   },
   {
    "fetch_from": "patient.sex",
    "fieldname": "patient_sex",
-   "fieldtype": "Data",
-   "label": "Gender"
+   "fieldtype": "Link",
+   "hide_days": 1,
+   "hide_seconds": 1,
+   "label": "Gender",
+   "options": "Gender",
+   "read_only": 1
   },
   {
    "fieldname": "company",
    "fieldtype": "Link",
+   "hide_days": 1,
+   "hide_seconds": 1,
    "in_standard_filter": 1,
    "label": "Company",
    "options": "Company"
   },
   {
    "fieldname": "section_break_6",
-   "fieldtype": "Section Break"
+   "fieldtype": "Section Break",
+   "hide_days": 1,
+   "hide_seconds": 1,
+   "label": "Sample Details"
   },
   {
    "fieldname": "sample",
    "fieldtype": "Link",
+   "hide_days": 1,
+   "hide_seconds": 1,
    "ignore_user_permissions": 1,
    "in_list_view": 1,
    "in_standard_filter": 1,
@@ -108,16 +135,23 @@
    "fetch_from": "sample.sample_uom",
    "fieldname": "sample_uom",
    "fieldtype": "Data",
+   "hide_days": 1,
+   "hide_seconds": 1,
    "in_list_view": 1,
-   "label": "UOM"
+   "label": "UOM",
+   "read_only": 1
   },
   {
    "fieldname": "column_break_10",
-   "fieldtype": "Column Break"
+   "fieldtype": "Column Break",
+   "hide_days": 1,
+   "hide_seconds": 1
   },
   {
    "fieldname": "collected_by",
    "fieldtype": "Link",
+   "hide_days": 1,
+   "hide_seconds": 1,
    "ignore_user_permissions": 1,
    "label": "Collected By",
    "options": "User"
@@ -125,20 +159,27 @@
   {
    "fieldname": "collected_time",
    "fieldtype": "Datetime",
-   "label": "Collected Time"
+   "hide_days": 1,
+   "hide_seconds": 1,
+   "label": "Collected On"
   },
   {
    "allow_on_submit": 1,
    "default": "1",
+   "description": "Number of prints required for labelling the samples",
    "fieldname": "num_print",
    "fieldtype": "Int",
-   "label": "No. of print",
+   "hide_days": 1,
+   "hide_seconds": 1,
+   "label": "No. of prints",
    "print_hide": 1,
    "report_hide": 1
   },
   {
    "fieldname": "amended_from",
    "fieldtype": "Link",
+   "hide_days": 1,
+   "hide_seconds": 1,
    "label": "Amended From",
    "no_copy": 1,
    "options": "Sample Collection",
@@ -147,25 +188,43 @@
   },
   {
    "fieldname": "section_break_15",
-   "fieldtype": "Section Break"
+   "fieldtype": "Section Break",
+   "hide_days": 1,
+   "hide_seconds": 1
   },
   {
    "default": "0",
    "fieldname": "sample_qty",
    "fieldtype": "Float",
+   "hide_days": 1,
+   "hide_seconds": 1,
    "in_list_view": 1,
    "label": "Quantity"
   },
   {
    "fieldname": "sample_details",
    "fieldtype": "Long Text",
+   "hide_days": 1,
+   "hide_seconds": 1,
    "ignore_xss_filter": 1,
    "label": "Collection Details"
+  },
+  {
+   "fieldname": "patient_details_section",
+   "fieldtype": "Section Break",
+   "label": "Patient Details"
+  },
+  {
+   "fetch_from": "patient.patient_name",
+   "fieldname": "patient_name",
+   "fieldtype": "Data",
+   "label": "Patient Name",
+   "read_only": 1
   }
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2020-05-25 14:36:46.990469",
+ "modified": "2020-07-30 16:53:13.076104",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Sample Collection",
diff --git a/erpnext/healthcare/doctype/sample_collection/sample_collection.py b/erpnext/healthcare/doctype/sample_collection/sample_collection.py
index 2c64320..461f809 100644
--- a/erpnext/healthcare/doctype/sample_collection/sample_collection.py
+++ b/erpnext/healthcare/doctype/sample_collection/sample_collection.py
@@ -3,7 +3,12 @@
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
+import frappe
 from frappe.model.document import Document
+from frappe.utils import flt
+from frappe import _
 
 class SampleCollection(Document):
-	pass
+	def validate(self):
+		if flt(self.sample_qty) <= 0:
+			frappe.throw(_('Sample Quantity cannot be negative or 0'), title=_('Invalid Quantity'))
diff --git a/erpnext/healthcare/report/lab_test_report/lab_test_report.js b/erpnext/healthcare/report/lab_test_report/lab_test_report.js
index 3128f81..7754e2e 100644
--- a/erpnext/healthcare/report/lab_test_report/lab_test_report.js
+++ b/erpnext/healthcare/report/lab_test_report/lab_test_report.js
@@ -4,29 +4,54 @@
 frappe.query_reports["Lab Test Report"] = {
 	"filters": [
 		{
-			"fieldname":"from_date",
+			"fieldname": "from_date",
 			"label": __("From Date"),
 			"fieldtype": "Date",
-			"default": frappe.datetime.now_date(),
-			"width": "80"
+			"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
+			"reqd": 1
 		},
 		{
-			"fieldname":"to_date",
+			"fieldname": "to_date",
 			"label": __("To Date"),
 			"fieldtype": "Date",
-			"default": frappe.datetime.now_date()
+			"default": frappe.datetime.now_date(),
+			"reqd": 1
 		},
 		{
-			"fieldname":"patient",
+			"fieldname": "company",
+			"label": __("Company"),
+			"fieldtype": "Link",
+			"default": frappe.defaults.get_default("Company"),
+			"options": "Company"
+		},
+		{
+			"fieldname": "template",
+			"label": __("Lab Test Template"),
+			"fieldtype": "Link",
+			"options": "Lab Test Template"
+		},
+		{
+			"fieldname": "patient",
 			"label": __("Patient"),
 			"fieldtype": "Link",
 			"options": "Patient"
 		},
 		{
-			"fieldname":"department",
+			"fieldname": "department",
 			"label": __("Medical Department"),
 			"fieldtype": "Link",
 			"options": "Medical Department"
+		},
+		{
+			"fieldname": "status",
+			"label": __("Status"),
+			"fieldtype": "Select",
+			"options": "\nCompleted\nApproved\nRejected"
+		},
+		{
+			"fieldname": "invoiced",
+			"label": __("Invoiced"),
+			"fieldtype": "Check"
 		}
 	]
 };
diff --git a/erpnext/healthcare/report/lab_test_report/lab_test_report.json b/erpnext/healthcare/report/lab_test_report/lab_test_report.json
index 30e5a5f..aeb4289 100644
--- a/erpnext/healthcare/report/lab_test_report/lab_test_report.json
+++ b/erpnext/healthcare/report/lab_test_report/lab_test_report.json
@@ -1,30 +1,31 @@
 {
- "add_total_row": 1, 
- "creation": "2013-04-23 18:15:29", 
- "disabled": 0, 
- "docstatus": 0, 
- "doctype": "Report", 
- "idx": 1, 
- "is_standard": "Yes", 
- "modified": "2018-08-06 11:41:50.218737", 
- "modified_by": "Administrator", 
- "module": "Healthcare", 
- "name": "Lab Test Report", 
- "owner": "Administrator", 
- "prepared_report": 0, 
- "ref_doctype": "Lab Test", 
- "report_name": "Lab Test Report", 
- "report_type": "Script Report", 
+ "add_total_row": 0,
+ "creation": "2013-04-23 18:15:29",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 1,
+ "is_standard": "Yes",
+ "modified": "2020-07-30 18:53:20.102873",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Lab Test Report",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Lab Test",
+ "report_name": "Lab Test Report",
+ "report_type": "Script Report",
  "roles": [
   {
    "role": "Laboratory User"
-  }, 
+  },
   {
    "role": "Nursing User"
-  }, 
+  },
   {
    "role": "LabTest Approver"
-  }, 
+  },
   {
    "role": "Healthcare Administrator"
   }
diff --git a/erpnext/healthcare/report/lab_test_report/lab_test_report.py b/erpnext/healthcare/report/lab_test_report/lab_test_report.py
index 17f25fa..2e59bed 100644
--- a/erpnext/healthcare/report/lab_test_report/lab_test_report.py
+++ b/erpnext/healthcare/report/lab_test_report/lab_test_report.py
@@ -8,51 +8,204 @@
 def execute(filters=None):
 	if not filters: filters = {}
 
-	lab_test_list = get_lab_test(filters)
+	data, columns = [], []
+
 	columns = get_columns()
+	lab_test_list = get_lab_tests(filters)
 
 	if not lab_test_list:
-		msgprint(_("No record found"))
+		msgprint(_('No records found'))
 		return columns, lab_test_list
 
 	data = []
 	for lab_test in lab_test_list:
-		row = [ lab_test.lab_test_name, lab_test.patient, lab_test.practitioner, lab_test.invoiced, lab_test.status, lab_test.result_date, lab_test.department]
+		row = frappe._dict({
+				'test': lab_test.name,
+				'template': lab_test.template,
+				'company': lab_test.company,
+				'patient': lab_test.patient,
+				'patient_name': lab_test.patient_name,
+				'practitioner': lab_test.practitioner,
+				'employee': lab_test.employee,
+				'status': lab_test.status,
+				'invoiced': lab_test.invoiced,
+				'result_date': lab_test.result_date,
+				'department': lab_test.department
+			})
 		data.append(row)
 
-	return columns, data
+	chart = get_chart_data(data)
+	report_summary = get_report_summary(data)
+	return columns, data, None, chart, report_summary
 
 
 def get_columns():
-	columns = [
-		_("Test") + ":Data:120",
-		_("Patient") + ":Link/Patient:180",
-		_("Healthcare Practitioner") + ":Link/Healthcare Practitioner:120",
-		_("Invoiced") + ":Check:100",
-		_("Status") + ":Data:120",
-		_("Result Date") + ":Date:120",
-		_("Department") + ":Data:120",
+	return [
+		{
+			'fieldname': 'test',
+			'label': _('Lab Test'),
+			'fieldtype': 'Link',
+			'options': 'Lab Test',
+			'width': '120'
+		},
+		{
+			'fieldname': 'template',
+			'label': _('Lab Test Template'),
+			'fieldtype': 'Link',
+			'options': 'Lab Test Template',
+			'width': '120'
+		},
+		{
+			'fieldname': 'company',
+			'label': _('Company'),
+			'fieldtype': 'Link',
+			'options': 'Company',
+			'width': '120'
+		},
+		{
+			'fieldname': 'patient',
+			'label': _('Patient'),
+			'fieldtype': 'Link',
+			'options': 'Patient',
+			'width': '120'
+		},
+		{
+			'fieldname': 'patient_name',
+			'label': _('Patient Name'),
+			'fieldtype': 'Data',
+			'width': '120'
+		},
+		{
+			'fieldname': 'employee',
+			'label': _('Lab Technician'),
+			'fieldtype': 'Link',
+			'options': 'Employee',
+			'width': '120'
+		},
+		{
+			'fieldname': 'status',
+			'label': _('Status'),
+			'fieldtype': 'Data',
+			'width': '100'
+		},
+		{
+			'fieldname': 'invoiced',
+			'label': _('Invoiced'),
+			'fieldtype': 'Check',
+			'width': '100'
+		},
+		{
+			'fieldname': 'result_date',
+			'label': _('Result Date'),
+			'fieldtype': 'Date',
+			'width': '100'
+		},
+		{
+			'fieldname': 'practitioner',
+			'label': _('Requesting Practitioner'),
+			'fieldtype': 'Link',
+			'options': 'Healthcare Practitioner',
+			'width': '120'
+		},
+		{
+			'fieldname': 'department',
+			'label': _('Medical Department'),
+			'fieldtype': 'Link',
+			'options': 'Medical Department',
+			'width': '100'
+		}
 	]
 
-	return columns
+def get_lab_tests(filters):
+	conditions = get_conditions(filters)
+	data = frappe.get_all(
+		doctype='Lab Test',
+		fields=['name', 'template', 'company', 'patient', 'patient_name', 'practitioner', 'employee', 'status', 'invoiced', 'result_date', 'department'],
+		filters=conditions,
+		order_by='submitted_date desc'
+	)
+	return data
 
 def get_conditions(filters):
-	conditions = ""
+	conditions = {
+		'docstatus': ('=', 1)
+	}
 
-	if filters.get("patient"):
-		conditions += "and patient = %(patient)s"
-	if filters.get("from_date"):
-		conditions += "and result_date >= %(from_date)s"
-	if filters.get("to_date"):
-		conditions += " and result_date <= %(to_date)s"
-	if filters.get("department"):
-		conditions += " and department = %(department)s"
+	if filters.get('from_date') and filters.get('to_date'):
+		conditions['result_date'] = ('between', (filters.get('from_date'), filters.get('to_date')))
+		filters.pop('from_date')
+		filters.pop('to_date')
+
+	for key, value in filters.items():
+		if filters.get(key):
+			conditions[key] = value
 
 	return conditions
 
-def get_lab_test(filters):
-	conditions = get_conditions(filters)
-	return frappe.db.sql("""select name, patient, lab_test_name, patient_name, status, result_date, practitioner, invoiced, department
-		from `tabLab Test`
-		where docstatus<2 %s order by submitted_date desc, name desc""" %
-		conditions, filters, as_dict=1)
+def get_chart_data(data):
+	if not data:
+		return None
+
+	labels = ['Completed', 'Approved', 'Rejected']
+
+	status_wise_data = {
+		'Completed': 0,
+		'Approved': 0,
+		'Rejected': 0
+	}
+
+	datasets = []
+
+	for entry in data:
+		status_wise_data[entry.status] += 1
+
+	datasets.append({
+		'name': 'Lab Test Status',
+		'values': [status_wise_data.get('Completed'), status_wise_data.get('Approved'), status_wise_data.get('Rejected')]
+	})
+
+	chart = {
+		'data': {
+			'labels': labels,
+			'datasets': datasets
+		},
+		'type': 'donut',
+		'height': 300,
+	}
+
+	return chart
+
+
+def get_report_summary(data):
+	if not data:
+		return None
+
+	total_lab_tests = len(data)
+	invoiced_lab_tests, unbilled_lab_tests = 0, 0
+
+	for entry in data:
+		if entry.invoiced:
+			invoiced_lab_tests += 1
+		else:
+			unbilled_lab_tests += 1
+
+	return [
+		{
+			'value': total_lab_tests,
+			'indicator': 'Blue',
+			'label': 'Total Lab Tests',
+			'datatype': 'Int',
+		},
+		{
+			'value': invoiced_lab_tests,
+			'indicator': 'Green',
+			'label': 'Invoiced Lab Tests',
+			'datatype': 'Int',
+		},
+		{
+			'value': unbilled_lab_tests,
+			'indicator': 'Red',
+			'label': 'Unbilled Lab Tests',
+			'datatype': 'Int',
+		}
+	]