feat(healthcare): Added Treatment Plan Template feature (#26557)

* feat: Added doctypes for treatment plan template

* feat: Added child doctype

* feat: Added validations for patient age

* chore: Clean up treatment plan template

* fix: Limit plan items to templates

* Added multiselectdialogbox for treatment plan template

* Add template name as autoname

* Clean up code

* Cleanup lint issues

* Clean up code

* Added tests for tpt filters

* Added test records

* Fix order of fields

* Added tests for care plan template

* Added age property for patient

* Clean up code

* Clean up list view

* Clean up code

* Fix lint issues

* Clean up test records

* Code cleanup

no-docs

* chore: Code cleanup

* chore: Use ORM instead of raw sql

* fix: Make treatment plan item fields mandatory

* fix: Added healthcare roles in permissions rules

* fix: Added filters for symptoms, diagnosis

* fix: Show applicable treatment plans button only if patient is present

* fix: Fix key error issues

* fix: Fix issues with filters in plan templates

* chore: Fix age filters

* refactor: appending treatment plan items

* fix: treatment plan test

Co-authored-by: Jannat Patel <31363128+pateljannat@users.noreply.github.com>
Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
diff --git a/erpnext/healthcare/doctype/drug_prescription/drug_prescription.json b/erpnext/healthcare/doctype/drug_prescription/drug_prescription.json
index d91e6bf..a65c566 100644
--- a/erpnext/healthcare/doctype/drug_prescription/drug_prescription.json
+++ b/erpnext/healthcare/doctype/drug_prescription/drug_prescription.json
@@ -56,6 +56,7 @@
    "reqd": 1
   },
   {
+   "allow_in_quick_entry": 1,
    "fieldname": "dosage_form",
    "fieldtype": "Link",
    "ignore_user_permissions": 1,
@@ -109,7 +110,7 @@
  ],
  "istable": 1,
  "links": [],
- "modified": "2020-09-30 23:32:09.495288",
+ "modified": "2021-06-11 11:53:06.343704",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Drug Prescription",
diff --git a/erpnext/healthcare/doctype/patient/patient.py b/erpnext/healthcare/doctype/patient/patient.py
index 56a3400..f77ad70 100644
--- a/erpnext/healthcare/doctype/patient/patient.py
+++ b/erpnext/healthcare/doctype/patient/patient.py
@@ -102,12 +102,19 @@
 
 		return name
 
+	@property
+	def age(self):
+		if not self.dob:
+			return
+		dob = getdate(self.dob)
+		age = dateutil.relativedelta.relativedelta(getdate(), dob)
+		return age
+
 	def get_age(self):
-		age_str = ''
-		if self.dob:
-			dob = getdate(self.dob)
-			age = dateutil.relativedelta.relativedelta(getdate(), dob)
-			age_str = str(age.years) + ' ' + _("Years(s)") + ' ' + str(age.months) + ' ' + _("Month(s)") + ' ' + str(age.days) + ' ' + _("Day(s)")
+		age = self.age
+		if not age:
+			return
+		age_str = str(age.years) + ' ' + _("Years(s)") + ' ' + str(age.months) + ' ' + _("Month(s)") + ' ' + str(age.days) + ' ' + _("Day(s)")
 		return age_str
 
 	@frappe.whitelist()
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
index aaeaa69..c346626 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
@@ -185,7 +185,42 @@
 			};
 			frm.set_value(values);
 		}
-	}
+	},
+
+	get_applicable_treatment_plans: function(frm) {
+		frappe.call({
+			method: 'get_applicable_treatment_plans',
+			doc: frm.doc,
+			args: {'encounter': frm.doc},
+			freeze: true,
+			freeze_message: __('Fetching Treatment Plans'),
+			callback: function() {
+				new frappe.ui.form.MultiSelectDialog({
+					doctype: "Treatment Plan Template",
+					target: this.cur_frm,
+					setters: {
+						medical_department: "",
+					},
+					action(selections) {
+						frappe.call({
+							method: 'set_treatment_plans',
+							doc: frm.doc,
+							args: selections,
+						}).then(() => {
+							frm.refresh_field('drug_prescription');
+							frm.refresh_field('procedure_prescription');
+							frm.refresh_field('lab_test_prescription');
+							frm.refresh_field('therapies');
+						});
+						cur_dialog.hide();
+					}
+				});
+
+
+			}
+		});
+	},
+
 });
 
 var schedule_inpatient = function(frm) {
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
index b646ff9..994597d 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
@@ -31,6 +31,7 @@
   "sb_symptoms",
   "symptoms",
   "symptoms_in_print",
+  "get_applicable_treatment_plans",
   "physical_examination",
   "diagnosis",
   "diagnosis_in_print",
@@ -324,11 +325,17 @@
    "no_copy": 1,
    "print_hide": 1,
    "read_only": 1
+  },
+  {
+   "depends_on": "eval:doc.patient",
+   "fieldname": "get_applicable_treatment_plans",
+   "fieldtype": "Button",
+   "label": "Get Applicable Treatment Plans"
   }
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2020-11-30 10:39:00.783119",
+ "modified": "2021-07-27 11:39:12.347704",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Patient Encounter",
@@ -358,4 +365,4 @@
  "title_field": "title",
  "track_changes": 1,
  "track_seen": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
index 2b3029e..7a745ae 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
@@ -10,6 +10,7 @@
 from frappe import _
 from frappe.model.mapper import get_mapped_doc
 
+
 class PatientEncounter(Document):
 	def validate(self):
 		self.set_title()
@@ -33,6 +34,85 @@
 		self.title = _('{0} with {1}').format(self.patient_name or self.patient,
 			self.practitioner_name or self.practitioner)[:100]
 
+	@frappe.whitelist()
+	@staticmethod
+	def get_applicable_treatment_plans(encounter):
+		patient = frappe.get_doc('Patient', encounter['patient'])
+
+		plan_filters = {}
+		plan_filters['name'] = ['in', []]
+
+		age = patient.age
+		if age:
+			plan_filters['patient_age_from'] = ['<=', age.years]
+			plan_filters['patient_age_to'] = ['>=', age.years]
+
+		gender = patient.sex
+		if gender:
+			plan_filters['gender'] = ['in', [gender, None]]
+
+		diagnosis = encounter.get('diagnosis')
+		if diagnosis:
+			diagnosis = [_diagnosis['diagnosis'] for _diagnosis in encounter['diagnosis']]
+			filters = [
+				['diagnosis', 'in', diagnosis],
+				['parenttype', '=', 'Treatment Plan Template'],
+			]
+			diagnosis = frappe.get_list('Patient Encounter Diagnosis', filters=filters, fields='*')
+			plan_names = [_diagnosis['parent'] for _diagnosis in diagnosis]
+			plan_filters['name'][1].extend(plan_names)
+
+		symptoms = encounter.get('symptoms')
+		if symptoms:
+			symptoms = [symptom['complaint'] for symptom in encounter['symptoms']]
+			filters = [
+				['complaint', 'in', symptoms],
+				['parenttype', '=', 'Treatment Plan Template'],
+			]
+			symptoms = frappe.get_list('Patient Encounter Symptom', filters=filters, fields='*')
+			plan_names = [symptom['parent'] for symptom in symptoms]
+			plan_filters['name'][1].extend(plan_names)
+
+		if not plan_filters['name'][1]:
+			plan_filters.pop('name')
+
+		plans = frappe.get_list('Treatment Plan Template', fields='*', filters=plan_filters)
+
+		return plans
+
+	@frappe.whitelist()
+	def set_treatment_plans(self, treatment_plans=None):
+		for treatment_plan in treatment_plans:
+			self.set_treatment_plan(treatment_plan)
+
+	def set_treatment_plan(self, plan):
+		plan_items = frappe.get_list('Treatment Plan Template Item', filters={'parent': plan}, fields='*')
+		for plan_item in plan_items:
+			self.set_treatment_plan_item(plan_item)
+
+		drugs = frappe.get_list('Drug Prescription', filters={'parent': plan}, fields='*')
+		for drug in drugs:
+			self.append('drug_prescription', drug)
+
+		self.save()
+
+	def set_treatment_plan_item(self, plan_item):
+		if plan_item.type == 'Clinical Procedure Template':
+			self.append('procedure_prescription', {
+				'procedure': plan_item.template
+			})
+
+		if plan_item.type == 'Lab Test Template':
+			self.append('lab_test_prescription', {
+				'lab_test_code': plan_item.template
+			})
+
+		if plan_item.type == 'Therapy Type':
+			self.append('therapies', {
+				'therapy_type': plan_item.template
+			})
+
+
 @frappe.whitelist()
 def make_ip_medication_order(source_name, target_doc=None):
 	def set_missing_values(source, target):
diff --git a/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.py b/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.py
index f5df152..9697682 100644
--- a/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.py
+++ b/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.py
@@ -4,5 +4,82 @@
 from __future__ import unicode_literals
 import unittest
 
+import frappe
+from erpnext.healthcare.doctype.patient_encounter.patient_encounter import PatientEncounter
+
+
 class TestPatientEncounter(unittest.TestCase):
-	pass
+	def setUp(self):
+		try:
+			gender_m = frappe.get_doc({
+				'doctype': 'Gender',
+				'gender': 'MALE'
+			}).insert()
+			gender_f = frappe.get_doc({
+				'doctype': 'Gender',
+				'gender': 'FEMALE'
+			}).insert()
+		except frappe.exceptions.DuplicateEntryError:
+			gender_m = frappe.get_doc({
+				'doctype': 'Gender',
+				'gender': 'MALE'
+			})
+			gender_f = frappe.get_doc({
+				'doctype': 'Gender',
+				'gender': 'FEMALE'
+			})
+
+		self.patient_male = frappe.get_doc({
+			'doctype': 'Patient',
+			'first_name': 'John',
+			'sex': gender_m.gender,
+		}).insert()
+		self.patient_female = frappe.get_doc({
+			'doctype': 'Patient',
+			'first_name': 'Curie',
+			'sex': gender_f.gender,
+		}).insert()
+		self.practitioner = frappe.get_doc({
+			'doctype': 'Healthcare Practitioner',
+			'first_name': 'Doc',
+			'sex': 'MALE',
+		}).insert()
+		try:
+			self.care_plan_male = frappe.get_doc({
+				'doctype': 'Treatment Plan Template',
+				'template_name': 'test plan - m',
+				'gender': gender_m.gender,
+			}).insert()
+			self.care_plan_female = frappe.get_doc({
+				'doctype': 'Treatment Plan Template',
+				'template_name': 'test plan - f',
+				'gender': gender_f.gender,
+			}).insert()
+		except frappe.exceptions.DuplicateEntryError:
+			self.care_plan_male = frappe.get_doc({
+				'doctype': 'Treatment Plan Template',
+				'template_name': 'test plan - m',
+				'gender': gender_m.gender,
+			})
+			self.care_plan_female = frappe.get_doc({
+				'doctype': 'Treatment Plan Template',
+				'template_name': 'test plan - f',
+				'gender': gender_f.gender,
+			})
+
+	def test_treatment_plan_template_filter(self):
+		encounter = frappe.get_doc({
+			'doctype': 'Patient Encounter',
+			'patient': self.patient_male.name,
+			'practitioner': self.practitioner.name,
+		}).insert()
+		plans = PatientEncounter.get_applicable_treatment_plans(encounter.as_dict())
+		self.assertEqual(plans[0]['name'], self.care_plan_male.template_name)
+
+		encounter = frappe.get_doc({
+			'doctype': 'Patient Encounter',
+			'patient': self.patient_female.name,
+			'practitioner': self.practitioner.name,
+		}).insert()
+		plans = PatientEncounter.get_applicable_treatment_plans(encounter.as_dict())
+		self.assertEqual(plans[0]['name'], self.care_plan_female.template_name)
diff --git a/erpnext/healthcare/doctype/treatment_plan_template/__init__.py b/erpnext/healthcare/doctype/treatment_plan_template/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/treatment_plan_template/__init__.py
diff --git a/erpnext/healthcare/doctype/treatment_plan_template/test_records.json b/erpnext/healthcare/doctype/treatment_plan_template/test_records.json
new file mode 100644
index 0000000..d661b43
--- /dev/null
+++ b/erpnext/healthcare/doctype/treatment_plan_template/test_records.json
@@ -0,0 +1,7 @@
+[
+  {
+    "doctype": "Treatment Plan Template",
+    "template_name": "Chemo",
+    "patient_age_from": 21
+  }
+]
diff --git a/erpnext/healthcare/doctype/treatment_plan_template/test_treatment_plan_template.py b/erpnext/healthcare/doctype/treatment_plan_template/test_treatment_plan_template.py
new file mode 100644
index 0000000..21ede71
--- /dev/null
+++ b/erpnext/healthcare/doctype/treatment_plan_template/test_treatment_plan_template.py
@@ -0,0 +1,8 @@
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+
+# import frappe
+import unittest
+
+class TestTreatmentPlanTemplate(unittest.TestCase):
+	pass
diff --git a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.js b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.js
new file mode 100644
index 0000000..986c3cb
--- /dev/null
+++ b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.js
@@ -0,0 +1,14 @@
+// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Treatment Plan Template', {
+	refresh: function (frm) {
+		frm.set_query('type', 'items', function () {
+			return {
+				filters: {
+					'name': ['in', ['Lab Test Template', 'Clinical Procedure Template', 'Therapy Type']],
+				}
+			};
+		});
+	},
+});
diff --git a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.json b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.json
new file mode 100644
index 0000000..85a312f
--- /dev/null
+++ b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.json
@@ -0,0 +1,189 @@
+{
+ "actions": [],
+ "autoname": "field:template_name",
+ "creation": "2021-06-10 10:14:17.901273",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "section_break_1",
+  "template_name",
+  "description",
+  "practitioners",
+  "disabled",
+  "column_break_1",
+  "medical_department",
+  "goal",
+  "order_group",
+  "section_break_8",
+  "patient_age_from",
+  "complaints",
+  "gender",
+  "column_break_12",
+  "patient_age_to",
+  "diagnosis",
+  "plan_items_section",
+  "items",
+  "drugs"
+ ],
+ "fields": [
+  {
+   "fieldname": "section_break_1",
+   "fieldtype": "Section Break",
+   "label": "Plan Details"
+  },
+  {
+   "fieldname": "medical_department",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Medical Department",
+   "options": "Medical Department"
+  },
+  {
+   "fieldname": "description",
+   "fieldtype": "Small Text",
+   "label": "Description"
+  },
+  {
+   "fieldname": "goal",
+   "fieldtype": "Small Text",
+   "label": "Goal"
+  },
+  {
+   "fieldname": "practitioners",
+   "fieldtype": "Table MultiSelect",
+   "label": "Practitioners",
+   "options": "Treatment Plan Template Practitioner"
+  },
+  {
+   "fieldname": "order_group",
+   "fieldtype": "Link",
+   "label": "Order Group",
+   "options": "Patient Encounter",
+   "read_only": 1
+  },
+  {
+   "fieldname": "section_break_8",
+   "fieldtype": "Section Break",
+   "label": "Plan Conditions"
+  },
+  {
+   "fieldname": "template_name",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Template Name",
+   "reqd": 1,
+   "unique": 1
+  },
+  {
+   "fieldname": "patient_age_from",
+   "fieldtype": "Int",
+   "label": "Patient Age From",
+   "non_negative": 1
+  },
+  {
+   "fieldname": "column_break_12",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "patient_age_to",
+   "fieldtype": "Int",
+   "label": "Patient Age To",
+   "non_negative": 1
+  },
+  {
+   "fieldname": "gender",
+   "fieldtype": "Link",
+   "label": "Gender",
+   "options": "Gender"
+  },
+  {
+   "fieldname": "complaints",
+   "fieldtype": "Table MultiSelect",
+   "label": "Complaints",
+   "options": "Patient Encounter Symptom"
+  },
+  {
+   "fieldname": "diagnosis",
+   "fieldtype": "Table MultiSelect",
+   "label": "Diagnosis",
+   "options": "Patient Encounter Diagnosis"
+  },
+  {
+   "fieldname": "plan_items_section",
+   "fieldtype": "Section Break",
+   "label": "Plan Items"
+  },
+  {
+   "fieldname": "items",
+   "fieldtype": "Table",
+   "label": "Items",
+   "options": "Treatment Plan Template Item"
+  },
+  {
+   "fieldname": "drugs",
+   "fieldtype": "Table",
+   "label": "Drugs",
+   "options": "Drug Prescription"
+  },
+  {
+   "default": "0",
+   "fieldname": "disabled",
+   "fieldtype": "Check",
+   "label": "Disabled"
+  },
+  {
+   "fieldname": "column_break_1",
+   "fieldtype": "Column Break"
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "links": [],
+ "modified": "2021-08-18 02:41:58.354296",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Treatment Plan Template",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Physician",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Healthcare Administrator",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "template_name",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.py b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.py
new file mode 100644
index 0000000..a92e266
--- /dev/null
+++ b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.py
@@ -0,0 +1,19 @@
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+import frappe
+from frappe import _
+from frappe.model.document import Document
+
+class TreatmentPlanTemplate(Document):
+	def validate(self):
+		self.validate_age()
+
+	def validate_age(self):
+		if self.patient_age_from and self.patient_age_from < 0:
+			frappe.throw(_('Patient Age From cannot be less than 0'))
+		if self.patient_age_to and self.patient_age_to < 0:
+			frappe.throw(_('Patient Age To cannot be less than 0'))
+		if self.patient_age_to and self.patient_age_from and \
+			self.patient_age_to < self.patient_age_from:
+			frappe.throw(_('Patient Age To cannot be less than Patient Age From'))
diff --git a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template_list.js b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template_list.js
new file mode 100644
index 0000000..7ab31df
--- /dev/null
+++ b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template_list.js
@@ -0,0 +1,10 @@
+frappe.listview_settings['Treatment Plan Template'] = {
+	get_indicator: function(doc) {
+		var colors = {
+			1: 'gray',
+			0: 'blue',
+		};
+		let label  = doc.disabled == 1 ? 'Disabled' : 'Enabled';
+		return [__(label), colors[doc.disabled], 'disable,=,' + doc.disabled];
+	}
+};
diff --git a/erpnext/healthcare/doctype/treatment_plan_template_item/__init__.py b/erpnext/healthcare/doctype/treatment_plan_template_item/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/treatment_plan_template_item/__init__.py
diff --git a/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.json b/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.json
new file mode 100644
index 0000000..20a9d67
--- /dev/null
+++ b/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.json
@@ -0,0 +1,55 @@
+{
+ "actions": [],
+ "creation": "2021-06-10 11:47:29.194795",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "type",
+  "template",
+  "qty",
+  "instructions"
+ ],
+ "fields": [
+  {
+   "fieldname": "type",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Type",
+   "options": "DocType",
+   "reqd": 1
+  },
+  {
+   "fieldname": "template",
+   "fieldtype": "Dynamic Link",
+   "in_list_view": 1,
+   "label": "Template",
+   "options": "type",
+   "reqd": 1
+  },
+  {
+   "default": "1",
+   "fieldname": "qty",
+   "fieldtype": "Int",
+   "label": "Qty"
+  },
+  {
+   "fieldname": "instructions",
+   "fieldtype": "Small Text",
+   "in_list_view": 1,
+   "label": "Instructions"
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2021-08-17 11:19:03.515441",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Treatment Plan Template Item",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.py b/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.py
new file mode 100644
index 0000000..5f58b06
--- /dev/null
+++ b/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.py
@@ -0,0 +1,8 @@
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+class TreatmentPlanTemplateItem(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/treatment_plan_template_practitioner/__init__.py b/erpnext/healthcare/doctype/treatment_plan_template_practitioner/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/treatment_plan_template_practitioner/__init__.py
diff --git a/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.json b/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.json
new file mode 100644
index 0000000..04da387
--- /dev/null
+++ b/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.json
@@ -0,0 +1,32 @@
+{
+ "actions": [],
+ "creation": "2021-06-10 10:37:56.669416",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "practitioner"
+ ],
+ "fields": [
+  {
+   "fieldname": "practitioner",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Practitioner",
+   "options": "Healthcare Practitioner",
+   "reqd": 1
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2021-06-11 16:05:06.733299",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Treatment Plan Template Practitioner",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.py b/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.py
new file mode 100644
index 0000000..6d34568
--- /dev/null
+++ b/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.py
@@ -0,0 +1,8 @@
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+class TreatmentPlanTemplatePractitioner(Document):
+	pass