feat(Healthcare): Rehabilitation Module (#21216)

* feat: added rehab sub-module doctypes

* feat: rehab module

* feat: prescribe procedures in Patient Encounter

* feat: create Therapy Plan on Encounter submission

* feat: manage item for Therapy Type

* feat: book appointments, get prescribed therapies for Therapy Sessions

* feat: invoice Therapy Sessions

* feat: plan completion progress bar and exercise countsindicators

* feat: Motor Assessment Scale

* feat: add editable card view for exercise steps

* fix: add rehab in healthcare desk page

* fix: card deletion not working when child table is hidden

* feat: automatically fetch therapies according to Body Part

* fix: added tests for Therapy Type and Plan

* fix: add exercises according to body parts in Therapy Type

* fix: label for Exercise Instructions

* fix: exercise cards css

* feat: add dashboard for Therapy Plan

* feat: Patient Assessment Template and Patient Assessment

* feat: add title fields in Therapy Plan and Session

* fix: remove Motor Assessment Scale

* fix: fetch assessment description

* feat: create Patient Assessment from Therapy Session

* fix: anti pattern code

* fix: update desk page

* fix: exercise card rendering

* fix(test): filter out disabled Items in test_mapper

* fix: get stock uom from Stock Settings for Therapy Type Item creation

* fix: multiline SQL query

* fix: permissions for DocTypes

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
diff --git a/erpnext/config/healthcare.py b/erpnext/config/healthcare.py
index 2b46127..da24d11 100644
--- a/erpnext/config/healthcare.py
+++ b/erpnext/config/healthcare.py
@@ -214,5 +214,41 @@
 					"label": _("Lab Test Report")
 				}
 			]
+		},
+		{
+			"label": _("Rehabilitation"),
+			"icon": "icon-cog",
+			"items": [
+				{
+					"type": "doctype",
+					"name": "Exercise Type",
+					"label": _("Exercise Type")
+				},
+				{
+					"type": "doctype",
+					"name": "Exercise Difficulty Level",
+					"label": _("Exercise Difficulty Level")
+				},
+				{
+					"type": "doctype",
+					"name": "Therapy Type",
+					"label": _("Therapy Type")
+				},
+				{
+					"type": "doctype",
+					"name": "Therapy Plan",
+					"label": _("Therapy Plan")
+				},
+				{
+					"type": "doctype",
+					"name": "Therapy Session",
+					"label": _("Therapy Session")
+				},
+				{
+					"type": "doctype",
+					"name": "Motor Assessment Scale",
+					"label": _("Motor Assessment Scale")
+				}
+			]
 		}
 	]
diff --git a/erpnext/controllers/tests/test_mapper.py b/erpnext/controllers/tests/test_mapper.py
index d02308d..8839e00 100644
--- a/erpnext/controllers/tests/test_mapper.py
+++ b/erpnext/controllers/tests/test_mapper.py
@@ -13,7 +13,7 @@
 		'''Test mapping of multiple source docs on a single target doc'''
 
 		make_test_records("Item")
-		items = frappe.get_all("Item", fields = ["name", "item_code"], filters = {'is_sales_item': 1, 'has_variants': 0})
+		items = frappe.get_all("Item", fields = ["name", "item_code"], filters = {'is_sales_item': 1, 'has_variants': 0, 'disabled': 0})
 		customers = frappe.get_all("Customer")
 		if items and customers:
 			# Make source docs (quotations) and a target doc (sales order)
diff --git a/erpnext/healthcare/desk_page/healthcare/healthcare.json b/erpnext/healthcare/desk_page/healthcare/healthcare.json
index 54798ba..24c6d6f 100644
--- a/erpnext/healthcare/desk_page/healthcare/healthcare.json
+++ b/erpnext/healthcare/desk_page/healthcare/healthcare.json
@@ -1,48 +1,53 @@
 {
  "cards": [
   {
-   "icon": "",
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient\",\n\t\t\"label\": \"Patient\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Practitioner\",\n\t\t\"label\":\"Healthcare Practitioner\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Practitioner Schedule\",\n\t\t\"label\": \"Practitioner Schedule\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Department\",\n\t\t\"label\": \"Medical Department\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit Type\",\n\t\t\"label\": \"Healthcare Service Unit Type\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit\",\n\t\t\"label\": \"Healthcare Service Unit\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code Standard\",\n\t\t\"label\": \"Medical Code Standard\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code\",\n\t\t\"label\": \"Medical Code\"\n\t}\n]",
-   "title": "Masters"
+   "hidden": 0,
+   "label": "Masters",
+   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient\",\n\t\t\"label\": \"Patient\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Practitioner\",\n\t\t\"label\":\"Healthcare Practitioner\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Practitioner Schedule\",\n\t\t\"label\": \"Practitioner Schedule\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Department\",\n\t\t\"label\": \"Medical Department\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit Type\",\n\t\t\"label\": \"Healthcare Service Unit Type\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit\",\n\t\t\"label\": \"Healthcare Service Unit\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code Standard\",\n\t\t\"label\": \"Medical Code Standard\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code\",\n\t\t\"label\": \"Medical Code\"\n\t}\n]"
   },
   {
-   "icon": "",
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Appointment Type\",\n\t\t\"label\": \"Appointment Type\"\n    },\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure Template\",\n\t\t\"label\": \"Clinical Procedure Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Dosage\",\n\t\t\"label\": \"Prescription Dosage\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Duration\",\n\t\t\"label\": \"Prescription Duration\"\n\t},\n\t{\n\t    \"type\": \"doctype\",\n\t\t\"name\": \"Antibiotic\",\n\t\t\"label\": \"Antibiotic\"\n\t}\n]",
-   "title": "Consultation Setup"
+   "hidden": 0,
+   "label": "Consultation Setup",
+   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Appointment Type\",\n\t\t\"label\": \"Appointment Type\"\n    },\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure Template\",\n\t\t\"label\": \"Clinical Procedure Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Dosage\",\n\t\t\"label\": \"Prescription Dosage\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Duration\",\n\t\t\"label\": \"Prescription Duration\"\n\t},\n\t{\n\t    \"type\": \"doctype\",\n\t\t\"name\": \"Antibiotic\",\n\t\t\"label\": \"Antibiotic\"\n\t}\n]"
   },
   {
-   "icon": "icon-star",
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Appointment\",\n\t\t\"label\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure\",\n\t\t\"label\": \"Clinical Procedure\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Encounter\",\n\t\t\"label\": \"Patient Encounter\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Vital Signs\",\n\t\t\"label\": \"Vital Signs\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Complaint\",\n\t\t\"label\": \"Complaint\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Diagnosis\",\n\t\t\"label\": \"Diagnosis\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Fee Validity\",\n\t\t\"label\": \"Fee Validity\"\n\t}\n]",
-   "title": "Consultation"
+   "hidden": 0,
+   "label": "Consultation",
+   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Appointment\",\n\t\t\"label\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure\",\n\t\t\"label\": \"Clinical Procedure\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Encounter\",\n\t\t\"label\": \"Patient Encounter\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Vital Signs\",\n\t\t\"label\": \"Vital Signs\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Complaint\",\n\t\t\"label\": \"Complaint\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Diagnosis\",\n\t\t\"label\": \"Diagnosis\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Fee Validity\",\n\t\t\"label\": \"Fee Validity\"\n\t}\n]"
   },
   {
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Settings\",\n\t\t\"label\": \"Healthcare Settings\",\n\t\t\"onboard\": 1\n\t}\n]",
-   "title": "Settings"
+   "hidden": 0,
+   "label": "Settings",
+   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Settings\",\n\t\t\"label\": \"Healthcare Settings\",\n\t\t\"onboard\": 1\n\t}\n]"
   },
   {
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Template\",\n\t\t\"label\": \"Lab Test Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Sample\",\n\t\t\"label\": \"Lab Test Sample\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test UOM\",\n\t\t\"label\": \"Lab Test UOM\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sensitivity\",\n\t\t\"label\": \"Sensitivity\"\n\t}\n]",
-   "title": "Laboratory Setup"
+   "hidden": 0,
+   "label": "Laboratory Setup",
+   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Template\",\n\t\t\"label\": \"Lab Test Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Sample\",\n\t\t\"label\": \"Lab Test Sample\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test UOM\",\n\t\t\"label\": \"Lab Test UOM\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sensitivity\",\n\t\t\"label\": \"Sensitivity\"\n\t}\n]"
   },
   {
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test\",\n\t\t\"label\": \"Lab Test\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sample Collection\",\n\t\t\"label\": \"Sample Collection\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Dosage Form\",\n\t\t\"label\": \"Dosage Form\"\n\t}\n]",
-   "title": "Laboratory"
+   "hidden": 0,
+   "label": "Laboratory",
+   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test\",\n\t\t\"label\": \"Lab Test\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sample Collection\",\n\t\t\"label\": \"Sample Collection\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Dosage Form\",\n\t\t\"label\": \"Dosage Form\"\n\t}\n]"
   },
   {
-   "links": "[\n\t{\n\t\t\"type\": \"page\",\n\t\t\"name\": \"patient_history\",\n\t\t\"label\": \"Patient History\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Medical Record\",\n\t\t\"label\": \"Patient Medical Record\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Inpatient Record\",\n\t\t\"label\": \"Inpatient Record\"\n\t}\n]",
-   "title": "Records and History"
+   "hidden": 0,
+   "label": "Rehabilitation and Physiotherapy",
+   "links": "[\n    {\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Exercise Type\",\n\t\t\"label\": \"Exercise Type\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Therapy Type\",\n\t\t\"label\": \"Therapy Type\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Therapy Plan\",\n\t\t\"label\": \"Therapy Plan\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Therapy Session\",\n\t\t\"label\": \"Therapy Session\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Assessment Template\",\n\t\t\"label\": \"Patient Assessment Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Assessment\",\n\t\t\"label\": \"Patient Assessment\"\n\t}\n]"
   },
   {
-   "links": "[\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Patient Appointment Analytics\",\n\t\t\"doctype\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Lab Test Report\",\n\t\t\"doctype\": \"Lab Test\",\n\t\t\"label\": \"Lab Test Report\"\n\t}\n]",
-   "title": "Reports"
+   "hidden": 0,
+   "label": "Records and History",
+   "links": "[\n\t{\n\t\t\"type\": \"page\",\n\t\t\"name\": \"patient_history\",\n\t\t\"label\": \"Patient History\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Medical Record\",\n\t\t\"label\": \"Patient Medical Record\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Inpatient Record\",\n\t\t\"label\": \"Inpatient Record\"\n\t}\n]"
+  },
+  {
+   "hidden": 0,
+   "label": "Reports",
+   "links": "[\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Patient Appointment Analytics\",\n\t\t\"doctype\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Lab Test Report\",\n\t\t\"doctype\": \"Lab Test\",\n\t\t\"label\": \"Lab Test Report\"\n\t}\n]"
   }
  ],
  "category": "Domains",
- "charts": [
-  {
-   "chart_name": "Patient Appointments",
-   "label": "Patient Appointments"
-  }
- ],
+ "charts": [],
  "charts_label": "",
  "creation": "2020-03-02 17:23:17.919682",
  "developer_mode_only": 0,
@@ -53,7 +58,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "Healthcare",
- "modified": "2020-03-26 16:10:44.629795",
+ "modified": "2020-04-20 11:42:43.889576",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Healthcare",
@@ -64,32 +69,32 @@
  "shortcuts": [
   {
    "format": "{} Open",
-   "is_query_report": 0,
+   "label": "Patient Appointment",
    "link_to": "Patient Appointment",
    "stats_filter": "{\n    \"status\": \"Open\"\n}",
    "type": "DocType"
   },
   {
    "format": "{} Active",
-   "is_query_report": 0,
+   "label": "Patient",
    "link_to": "Patient",
    "stats_filter": "{\n    \"status\": \"Active\"\n}",
    "type": "DocType"
   },
   {
    "format": "{} Vacant",
-   "is_query_report": 0,
+   "label": "Healthcare Service Unit",
    "link_to": "Healthcare Service Unit",
    "stats_filter": "{\n    \"occupancy_status\": \"Vacant\",\n    \"is_group\": 0\n}",
    "type": "DocType"
   },
   {
-   "is_query_report": 0,
+   "label": "Healthcare Practitioner",
    "link_to": "Healthcare Practitioner",
    "type": "DocType"
   },
   {
-   "is_query_report": 0,
+   "label": "Patient History",
    "link_to": "patient_history",
    "type": "Page"
   }
diff --git a/erpnext/healthcare/doctype/body_part/__init__.py b/erpnext/healthcare/doctype/body_part/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/body_part/__init__.py
diff --git a/erpnext/healthcare/doctype/body_part/body_part.js b/erpnext/healthcare/doctype/body_part/body_part.js
new file mode 100644
index 0000000..d2f9d09
--- /dev/null
+++ b/erpnext/healthcare/doctype/body_part/body_part.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Body Part', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/healthcare/doctype/body_part/body_part.json b/erpnext/healthcare/doctype/body_part/body_part.json
new file mode 100644
index 0000000..6e3d1d4
--- /dev/null
+++ b/erpnext/healthcare/doctype/body_part/body_part.json
@@ -0,0 +1,45 @@
+{
+ "actions": [],
+ "autoname": "field:body_part",
+ "creation": "2020-04-10 12:21:55.036402",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "body_part"
+ ],
+ "fields": [
+  {
+   "fieldname": "body_part",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Body Part",
+   "reqd": 1,
+   "unique": 1
+  }
+ ],
+ "links": [],
+ "modified": "2020-04-10 12:26:44.087985",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Body Part",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/body_part/body_part.py b/erpnext/healthcare/doctype/body_part/body_part.py
new file mode 100644
index 0000000..300493a
--- /dev/null
+++ b/erpnext/healthcare/doctype/body_part/body_part.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class BodyPart(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/body_part/test_body_part.py b/erpnext/healthcare/doctype/body_part/test_body_part.py
new file mode 100644
index 0000000..cb3a611
--- /dev/null
+++ b/erpnext/healthcare/doctype/body_part/test_body_part.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestBodyPart(unittest.TestCase):
+	pass
diff --git a/erpnext/healthcare/doctype/body_part_link/__init__.py b/erpnext/healthcare/doctype/body_part_link/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/body_part_link/__init__.py
diff --git a/erpnext/healthcare/doctype/body_part_link/body_part_link.json b/erpnext/healthcare/doctype/body_part_link/body_part_link.json
new file mode 100644
index 0000000..400b7c6
--- /dev/null
+++ b/erpnext/healthcare/doctype/body_part_link/body_part_link.json
@@ -0,0 +1,32 @@
+{
+ "actions": [],
+ "creation": "2020-04-10 12:23:15.259816",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "body_part"
+ ],
+ "fields": [
+  {
+   "fieldname": "body_part",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Body Part",
+   "options": "Body Part",
+   "reqd": 1
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-04-10 12:25:23.101749",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Body Part Link",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/body_part_link/body_part_link.py b/erpnext/healthcare/doctype/body_part_link/body_part_link.py
new file mode 100644
index 0000000..0371529
--- /dev/null
+++ b/erpnext/healthcare/doctype/body_part_link/body_part_link.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class BodyPartLink(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/exercise/__init__.py b/erpnext/healthcare/doctype/exercise/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise/__init__.py
diff --git a/erpnext/healthcare/doctype/exercise/exercise.json b/erpnext/healthcare/doctype/exercise/exercise.json
new file mode 100644
index 0000000..2486a5d
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise/exercise.json
@@ -0,0 +1,61 @@
+{
+ "actions": [],
+ "creation": "2020-03-11 09:25:00.968572",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "exercise_type",
+  "difficulty_level",
+  "counts_target",
+  "counts_completed",
+  "assistance_level"
+ ],
+ "fields": [
+  {
+   "fieldname": "exercise_type",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Exercise Type",
+   "options": "Exercise Type",
+   "reqd": 1
+  },
+  {
+   "fetch_from": "exercise_type.difficulty_level",
+   "fieldname": "difficulty_level",
+   "fieldtype": "Link",
+   "label": "Difficulty Level",
+   "options": "Exercise Difficulty Level"
+  },
+  {
+   "fieldname": "counts_target",
+   "fieldtype": "Int",
+   "in_list_view": 1,
+   "label": "Counts Target"
+  },
+  {
+   "depends_on": "eval:doc.parenttype==\"Therapy\";",
+   "fieldname": "counts_completed",
+   "fieldtype": "Int",
+   "label": "Counts Completed"
+  },
+  {
+   "fieldname": "assistance_level",
+   "fieldtype": "Select",
+   "label": "Assistance Level",
+   "options": "\nPassive\nActive Assist\nActive"
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-04-10 13:41:06.662351",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Exercise",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/exercise/exercise.py b/erpnext/healthcare/doctype/exercise/exercise.py
new file mode 100644
index 0000000..efd8999
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise/exercise.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class Exercise(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/exercise_difficulty_level/__init__.py b/erpnext/healthcare/doctype/exercise_difficulty_level/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_difficulty_level/__init__.py
diff --git a/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.js b/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.js
new file mode 100644
index 0000000..ff51c34
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Exercise Difficulty Level', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.json b/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.json
new file mode 100644
index 0000000..a6aed75
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.json
@@ -0,0 +1,45 @@
+{
+ "actions": [],
+ "autoname": "field:difficulty_level",
+ "creation": "2020-03-29 21:12:55.835941",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "difficulty_level"
+ ],
+ "fields": [
+  {
+   "fieldname": "difficulty_level",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Difficulty Level",
+   "reqd": 1,
+   "unique": 1
+  }
+ ],
+ "links": [],
+ "modified": "2020-03-31 23:14:33.554066",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Exercise Difficulty Level",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.py b/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.py
new file mode 100644
index 0000000..17e97b8
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class ExerciseDifficultyLevel(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/exercise_difficulty_level/test_exercise_difficulty_level.py b/erpnext/healthcare/doctype/exercise_difficulty_level/test_exercise_difficulty_level.py
new file mode 100644
index 0000000..80ef3a7
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_difficulty_level/test_exercise_difficulty_level.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestExerciseDifficultyLevel(unittest.TestCase):
+	pass
diff --git a/erpnext/healthcare/doctype/exercise_type/__init__.py b/erpnext/healthcare/doctype/exercise_type/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_type/__init__.py
diff --git a/erpnext/healthcare/doctype/exercise_type/exercise_type.js b/erpnext/healthcare/doctype/exercise_type/exercise_type.js
new file mode 100644
index 0000000..f450c9b
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_type/exercise_type.js
@@ -0,0 +1,180 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Exercise Type', {
+	refresh: function(frm) {
+		let wrapper = frm.fields_dict.steps_html.wrapper;
+
+		frm.ExerciseEditor = new erpnext.ExerciseEditor(frm, wrapper);
+	}
+});
+
+erpnext.ExerciseEditor = Class.extend({
+	init: function(frm, wrapper) {
+		this.wrapper = wrapper;
+		this.frm = frm;
+		this.make(frm, wrapper);
+	},
+
+	make: function(frm, wrapper) {
+		$(this.wrapper).empty();
+
+		this.exercise_toolbar = $('<p>\
+		<button class="btn btn-default btn-add btn-xs" style="margin-left: 10px;"></button>').appendTo(this.wrapper);
+
+		this.exercise_cards = $('<div class="exercise-cards"></div>').appendTo(this.wrapper);
+
+		let me = this;
+
+		this.exercise_toolbar.find(".btn-add")
+			.html(__('Add'))
+			.on("click", function() {
+				me.show_add_card_dialog(frm);
+			});
+
+		if (frm.doc.steps_table.length > 0) {
+			this.make_cards(frm);
+			this.make_buttons(frm);
+		}
+	},
+
+	make_cards: function(frm) {
+		var me = this;
+		$(me.exercise_cards).empty();
+		this.row = $('<div class="exercise-row"></div>').appendTo(me.exercise_cards);
+
+		$.each(frm.doc.steps_table, function(i, step) {
+			$(repl(`
+				<div class="exercise-col col-sm-4" id="%(col_id)s">
+					<div class="card h-100 exercise-card" id="%(card_id)s">
+						<div class="card-body exercise-card-body">
+							<img src=%(image_src)s class="card-img-top" alt="...">
+							<h4 class="card-title">%(title)s</h4>
+							<p class="card-text text-truncate">%(description)s</p>
+						</div>
+						<div class="card-footer">
+							<button class="btn btn-default btn-xs btn-edit" data-id="%(id)s"><i class="fa fa-pencil" aria-hidden="true"></i></button>
+							<button class="btn btn-default btn-xs btn-del" data-id="%(id)s"><i class="fa fa-trash" aria-hidden="true"></i></button>
+						</div>
+					</div>
+			</div>`, {image_src: step.image, title: step.title, description: step.description, col_id: "col-"+i, card_id: "card-"+i, id: i})).appendTo(me.row);
+		});
+	},
+
+	make_buttons: function(frm) {
+		let me = this;
+		$('.btn-edit').on('click', function() {
+			let id = $(this).attr('data-id');
+			me.show_edit_card_dialog(frm, id);
+		});
+
+		$('.btn-del').on('click', function() {
+			let id = $(this).attr('data-id');
+			$('#card-'+id).addClass("zoomOutDelete");
+
+			setTimeout(() => {
+				// not using grid_rows[id].remove because
+				// grid_rows is not defined when the table is hidden
+				frm.doc.steps_table.pop(id);
+				frm.refresh_field('steps_table');
+				$('#col-'+id).remove();
+			}, 300);
+		});
+	},
+
+	show_add_card_dialog: function(frm) {
+		let me = this;
+		let d = new frappe.ui.Dialog({
+			title: __('Add Exercise Step'),
+			fields: [
+				{
+					"label": "Title",
+					"fieldname": "title",
+					"fieldtype": "Data",
+					"reqd": 1
+				},
+				{
+					"label": "Attach Image",
+					"fieldname": "image",
+					"fieldtype": "Attach Image"
+				},
+				{
+					"label": "Step Description",
+					"fieldname": "step_description",
+					"fieldtype": "Long Text"
+				}
+			],
+			primary_action: function() {
+				let data = d.get_values();
+				let i = frm.doc.steps_table.length;
+				$(repl(`
+					<div class="exercise-col col-sm-4" id="%(col_id)s">
+						<div class="card h-100 exercise-card" id="%(card_id)s">
+							<div class="card-body exercise-card-body">
+								<img src=%(image_src)s class="card-img-top" alt="...">
+								<h4 class="card-title">%(title)s</h4>
+								<p class="card-text text-truncate">%(description)s</p>
+							</div>
+							<div class="card-footer">
+								<button class="btn btn-default btn-xs btn-edit" data-id="%(id)s"><i class="fa fa-pencil" aria-hidden="true"></i></button>
+								<button class="btn btn-default btn-xs btn-del" data-id="%(id)s"><i class="fa fa-trash" aria-hidden="true"></i></button>
+							</div>
+						</div>
+					</div>`, {image_src: data.image, title: data.title, description: data.step_description, col_id: "col-"+i, card_id: "card-"+i, id: i})).appendTo(me.row);
+				let step = frappe.model.add_child(frm.doc, 'Exercise Type Step', 'steps_table');
+				step.title = data.title;
+				step.image = data.image;
+				step.description = data.step_description;
+				me.make_buttons(frm);
+				frm.refresh_field('steps_table');
+				d.hide();
+			},
+			primary_action_label: __('Add')
+		});
+		d.show();
+	},
+
+	show_edit_card_dialog: function(frm, id) {
+		let new_dialog = new frappe.ui.Dialog({
+			title: __("Edit Exercise Step"),
+			fields: [
+				{
+					"label": "Title",
+					"fieldname": "title",
+					"fieldtype": "Data",
+					"reqd": 1
+				},
+				{
+					"label": "Attach Image",
+					"fieldname": "image",
+					"fieldtype": "Attach Image"
+				},
+				{
+					"label": "Step Description",
+					"fieldname": "step_description",
+					"fieldtype": "Long Text"
+				}
+			],
+			primary_action: () => {
+				let data = new_dialog.get_values();
+				$('#card-'+id).find('.card-title').html(data.title);
+				$('#card-'+id).find('img').attr('src', data.image);
+				$('#card-'+id).find('.card-text').html(data.step_description);
+
+				frm.doc.steps_table[id].title = data.title;
+				frm.doc.steps_table[id].image = data.image;
+				frm.doc.steps_table[id].description = data.step_description;
+				refresh_field('steps_table');
+				new_dialog.hide();
+			},
+			primary_action_label: __("Save"),
+		});
+
+		new_dialog.set_values({
+			title: frm.doc.steps_table[id].title,
+			image: frm.doc.steps_table[id].image,
+			step_description: frm.doc.steps_table[id].description
+		});
+		new_dialog.show();
+	}
+});
diff --git a/erpnext/healthcare/doctype/exercise_type/exercise_type.json b/erpnext/healthcare/doctype/exercise_type/exercise_type.json
new file mode 100644
index 0000000..0db9c6e
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_type/exercise_type.json
@@ -0,0 +1,144 @@
+{
+ "actions": [],
+ "creation": "2020-03-29 21:37:03.366344",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "exercise_name",
+  "body_parts",
+  "column_break_3",
+  "difficulty_level",
+  "section_break_5",
+  "description",
+  "section_break_7",
+  "exercise_steps",
+  "column_break_9",
+  "exercise_video",
+  "section_break_11",
+  "steps_html",
+  "section_break_13",
+  "steps_table"
+ ],
+ "fields": [
+  {
+   "fieldname": "exercise_name",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Exercise Name",
+   "reqd": 1
+  },
+  {
+   "fieldname": "difficulty_level",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Difficulty Level",
+   "options": "Exercise Difficulty Level"
+  },
+  {
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "section_break_5",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "description",
+   "fieldtype": "Long Text",
+   "label": "Description"
+  },
+  {
+   "fieldname": "section_break_7",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "exercise_steps",
+   "fieldtype": "Attach",
+   "label": "Exercise Instructions"
+  },
+  {
+   "fieldname": "exercise_video",
+   "fieldtype": "Link",
+   "label": "Exercise Video",
+   "options": "Video"
+  },
+  {
+   "fieldname": "column_break_9",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "steps_html",
+   "fieldtype": "HTML",
+   "label": "Steps"
+  },
+  {
+   "fieldname": "steps_table",
+   "fieldtype": "Table",
+   "hidden": 1,
+   "label": "Steps Table",
+   "options": "Exercise Type Step"
+  },
+  {
+   "fieldname": "section_break_11",
+   "fieldtype": "Section Break",
+   "label": "Exercise Steps"
+  },
+  {
+   "fieldname": "section_break_13",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "body_parts",
+   "fieldtype": "Table MultiSelect",
+   "label": "Body Parts",
+   "options": "Body Part Link"
+  }
+ ],
+ "links": [],
+ "modified": "2020-04-21 13:05:36.555060",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Exercise Type",
+ "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": "Healthcare Administrator",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Physician",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/exercise_type/exercise_type.py b/erpnext/healthcare/doctype/exercise_type/exercise_type.py
new file mode 100644
index 0000000..fb635c8
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_type/exercise_type.py
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class ExerciseType(Document):
+	def autoname(self):
+		if self.difficulty_level:
+			self.name = ' - '.join(filter(None, [self.exercise_name, self.difficulty_level]))
+		else:
+			self.name = self.exercise_name
+
diff --git a/erpnext/healthcare/doctype/exercise_type/test_exercise_type.py b/erpnext/healthcare/doctype/exercise_type/test_exercise_type.py
new file mode 100644
index 0000000..bf217e8
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_type/test_exercise_type.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestExerciseType(unittest.TestCase):
+	pass
diff --git a/erpnext/healthcare/doctype/exercise_type_step/__init__.py b/erpnext/healthcare/doctype/exercise_type_step/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_type_step/__init__.py
diff --git a/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.json b/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.json
new file mode 100644
index 0000000..b37ff00
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.json
@@ -0,0 +1,44 @@
+{
+ "actions": [],
+ "creation": "2020-03-31 23:01:18.761967",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "title",
+  "image",
+  "description"
+ ],
+ "fields": [
+  {
+   "fieldname": "title",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Title",
+   "reqd": 1
+  },
+  {
+   "fieldname": "image",
+   "fieldtype": "Attach Image",
+   "label": "Image"
+  },
+  {
+   "fieldname": "description",
+   "fieldtype": "Long Text",
+   "in_list_view": 1,
+   "label": "Description"
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-04-02 20:39:34.258512",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Exercise Type Step",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.py b/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.py
new file mode 100644
index 0000000..13d7e57
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class ExerciseTypeStep(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
index efa6b24..fa58934 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
@@ -102,6 +102,13 @@
 						frm: frm,
 					});
 				}, __('Create'));
+			} else if (frm.doc.therapy_type) {
+				frm.add_custom_button(__('Therapy Session'),function(){
+					frappe.model.open_mapped_doc({
+						method: 'erpnext.healthcare.doctype.therapy_session.therapy_session.create_therapy_session',
+						frm: frm,
+					})
+				}, 'Create');
 			} else {
 				frm.add_custom_button(__('Patient Encounter'), function() {
 					frappe.model.open_mapped_doc({
@@ -123,6 +130,16 @@
 		}
 	},
 
+	therapy_type: function(frm) {
+		if (frm.doc.therapy_type) {
+			frappe.db.get_value('Therapy Type', frm.doc.therapy_type, 'default_duration', (r) => {
+				if (r.default_duration) {
+					frm.set_value('duration', r.default_duration)
+				}
+			});
+		}
+	},
+
 	get_procedure_from_encounter: function(frm) {
 		get_prescribed_procedure(frm);
 	},
@@ -148,6 +165,26 @@
 				}
 			}
 		});
+	},
+
+	get_prescribed_therapies: function(frm) {
+		if (frm.doc.patient) {
+			frappe.call({
+				method: "erpnext.healthcare.doctype.patient_appointment.patient_appointment.get_prescribed_therapies",
+				args: {patient: frm.doc.patient},
+				callback: function(r) {
+					if (r.message) {
+						show_therapy_types(frm, r.message);
+					} else {
+						frappe.msgprint({
+							title: __('Not Therapies Prescribed'),
+							message: __('There are no Therapies prescribed for Patient {0}', [frm.doc.patient.bold()]),
+							indicator: 'blue'
+						});
+					}
+				}
+			});
+		}
 	}
 });
 
@@ -393,6 +430,50 @@
 	d.show();
 };
 
+let show_therapy_types = function(frm, result) {
+	var d = new frappe.ui.Dialog({
+		title: __('Prescribed Therapies'),
+		fields: [
+			{
+				fieldtype: 'HTML', fieldname: 'therapy_type'
+			}
+		]
+	});
+	var html_field = d.fields_dict.therapy_type.$wrapper;
+	$.each(result, function(x, y){
+		var row = $(repl('<div class="col-xs-12" style="padding-top:12px; text-align:center;" >\
+		<div class="col-xs-5"> %(encounter)s <br> %(practitioner)s <br> %(date)s </div>\
+		<div class="col-xs-5"> %(therapy)s </div>\
+		<div class="col-xs-2">\
+		<a data-therapy="%(therapy)s" data-therapy-plan="%(therapy_plan)s" data-name="%(name)s"\
+		data-encounter="%(encounter)s" data-practitioner="%(practitioner)s"\
+		data-date="%(date)s"  data-department="%(department)s">\
+		<button class="btn btn-default btn-xs">Add\
+		</button></a></div></div><div class="col-xs-12"><hr/><div/>', {therapy:y[0],
+		name: y[1], encounter:y[2], practitioner:y[3], date:y[4],
+		department:y[6]? y[6]:'', therapy_plan:y[5]})).appendTo(html_field);
+
+		row.find("a").click(function() {
+			frm.doc.therapy_type = $(this).attr("data-therapy");
+			frm.doc.practitioner = $(this).attr("data-practitioner");
+			frm.doc.department = $(this).attr("data-department");
+			frm.doc.therapy_plan = $(this).attr("data-therapy-plan");
+			frm.refresh_field("therapy_type");
+			frm.refresh_field("practitioner");
+			frm.refresh_field("department");
+			frm.refresh_field("therapy-plan");
+			frappe.db.get_value('Therapy Type', frm.doc.therapy_type, 'default_duration', (r) => {
+				if (r.default_duration) {
+					frm.set_value('duration', r.default_duration)
+				}
+			});
+			d.hide();
+			return false;
+		});
+	});
+	d.show();
+};
+
 let create_vital_signs = function(frm) {
 	if (!frm.doc.patient) {
 		frappe.throw(__('Please select patient'));
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
index 7f9a671..57e6c47 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
@@ -20,6 +20,9 @@
   "procedure_template",
   "get_procedure_from_encounter",
   "procedure_prescription",
+  "therapy_type",
+  "get_prescribed_therapies",
+  "therapy_plan",
   "service_unit",
   "section_break_12",
   "practitioner",
@@ -270,6 +273,28 @@
    "report_hide": 1
   },
   {
+   "depends_on": "eval:doc.patient;",
+   "fieldname": "therapy_type",
+   "fieldtype": "Link",
+   "label": "Therapy",
+   "options": "Therapy Type",
+   "set_only_once": 1
+  },
+  {
+   "depends_on": "eval:doc.patient && doc.__islocal;",
+   "fieldname": "get_prescribed_therapies",
+   "fieldtype": "Button",
+   "label": "Get Prescribed Therapies"
+  },
+  {
+   "depends_on": "eval: doc.patient && doc.therapy_type",
+   "fieldname": "therapy_plan",
+   "fieldtype": "Link",
+   "label": "Therapy Plan",
+   "mandatory_depends_on": "eval: doc.patient && doc.therapy_type",
+   "options": "Therapy Plan"
+  },
+  {
    "fieldname": "ref_sales_invoice",
    "fieldtype": "Link",
    "label": "Reference Sales Invoice",
@@ -285,7 +310,7 @@
   }
  ],
  "links": [],
- "modified": "2020-03-27 11:27:33.773195",
+ "modified": "2020-03-31 16:16:32.116865",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Patient Appointment",
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
index a2d9d02..512d44e 100755
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
@@ -412,11 +412,36 @@
 
 @frappe.whitelist()
 def get_procedure_prescribed(patient):
-	return frappe.db.sql("""select pp.name, pp.procedure, pp.parent, ct.practitioner,
-	ct.encounter_date, pp.practitioner, pp.date, pp.department
-	from `tabPatient Encounter` ct, `tabProcedure Prescription` pp
-	where ct.patient=%(patient)s and pp.parent=ct.name and pp.appointment_booked=0
-	order by ct.creation desc""", {'patient': patient})
+	return frappe.db.sql(
+		"""
+			SELECT
+				pp.name, pp.procedure, pp.parent, ct.practitioner,
+				ct.encounter_date, pp.practitioner, pp.date, pp.department
+			FROM
+				`tabPatient Encounter` ct, `tabProcedure Prescription` pp
+			WHERE
+				ct.patient=%(patient)s and pp.parent=ct.name and pp.appointment_booked=0
+			ORDER BY
+				ct.creation desc
+		""", {'patient': patient}
+	)
+
+
+@frappe.whitelist()
+def get_prescribed_therapies(patient):
+	return frappe.db.sql(
+		"""
+			SELECT
+				t.therapy_type, t.name, t.parent, e.practitioner,
+				e.encounter_date, e.therapy_plan, e.visit_department
+			FROM
+				`tabPatient Encounter` e, `tabTherapy Plan Detail` t
+			WHERE
+				e.patient=%(patient)s and t.parent=e.name
+			ORDER BY
+				e.creation desc
+		""", {'patient': patient}
+	)
 
 
 def update_appointment_status():
diff --git a/erpnext/healthcare/doctype/patient_assessment/__init__.py b/erpnext/healthcare/doctype/patient_assessment/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_assessment/patient_assessment.js b/erpnext/healthcare/doctype/patient_assessment/patient_assessment.js
new file mode 100644
index 0000000..c7074e8
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment/patient_assessment.js
@@ -0,0 +1,86 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Patient Assessment', {
+	refresh: function(frm) {
+		if (frm.doc.assessment_template) {
+			frm.trigger('set_score_range');
+		}
+
+		if (!frm.doc.__islocal) {
+			frm.trigger('show_patient_progress');
+		}
+	},
+
+	assessment_template: function(frm) {
+		if (frm.doc.assessment_template) {
+			frappe.call({
+				'method': 'frappe.client.get',
+				args: {
+					doctype: 'Patient Assessment Template',
+					name: frm.doc.assessment_template
+				},
+				callback: function(data) {
+					frm.doc.assessment_sheet = [];
+					$.each(data.message.parameters, function(_i, e) {
+						let entry = frm.add_child('assessment_sheet');
+						entry.parameter = e.assessment_parameter;
+					});
+
+					frm.set_value('scale_min', data.message.scale_min);
+					frm.set_value('scale_max', data.message.scale_max);
+					frm.set_value('assessment_description', data.message.assessment_description);
+					frm.set_value('total_score', data.message.scale_max * data.message.parameters.length);
+					frm.trigger('set_score_range');
+					refresh_field('assessment_sheet');
+				}
+			});
+		}
+	},
+
+	set_score_range: function(frm) {
+		let options = [];
+		for(let i = frm.doc.scale_min; i <= frm.doc.scale_max; i++) {
+			options.push(i);
+		}
+		frappe.meta.get_docfield('Patient Assessment Sheet', 'score', frm.doc.name).options = [''].concat(options);
+	},
+
+	calculate_total_score: function(frm, cdt, cdn) {
+		let row = locals[cdt][cdn];
+		let total_score = 0;
+		$.each(frm.doc.assessment_sheet || [], function(_i, item) {
+			if (item.score) {
+				total_score += parseInt(item.score);
+			}
+		});
+
+		frm.set_value('total_score_obtained', total_score);
+	},
+
+	show_patient_progress: function(frm) {
+		let bars = [];
+		let message = '';
+		let added_min = false;
+
+		let title = __('{0} out of {1}', [frm.doc.total_score_obtained, frm.doc.total_score]);
+
+		bars.push({
+			'title': title,
+			'width': (frm.doc.total_score_obtained / frm.doc.total_score * 100) + '%',
+			'progress_class': 'progress-bar-success'
+		});
+		if (bars[0].width == '0%') {
+			bars[0].width = '0.5%';
+			added_min = 0.5;
+		}
+		message = title;
+		frm.dashboard.add_progress(__('Status'), bars, message);
+	},
+});
+
+frappe.ui.form.on('Patient Assessment Sheet', {
+	score: function(frm, cdt, cdn) {
+		frm.events.calculate_total_score(frm, cdt, cdn);
+	}
+});
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment/patient_assessment.json b/erpnext/healthcare/doctype/patient_assessment/patient_assessment.json
new file mode 100644
index 0000000..3952a81
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment/patient_assessment.json
@@ -0,0 +1,172 @@
+{
+ "actions": [],
+ "autoname": "naming_series:",
+ "creation": "2020-04-19 22:45:12.356209",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "naming_series",
+  "therapy_session",
+  "patient",
+  "assessment_template",
+  "column_break_4",
+  "healthcare_practitioner",
+  "assessment_datetime",
+  "assessment_description",
+  "section_break_7",
+  "assessment_sheet",
+  "section_break_9",
+  "total_score_obtained",
+  "column_break_11",
+  "total_score",
+  "scale_min",
+  "scale_max",
+  "amended_from"
+ ],
+ "fields": [
+  {
+   "fetch_from": "therapy_session.patient",
+   "fieldname": "patient",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Patient",
+   "options": "Patient",
+   "reqd": 1
+  },
+  {
+   "fieldname": "assessment_template",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Assessment Template",
+   "options": "Patient Assessment Template",
+   "reqd": 1
+  },
+  {
+   "fieldname": "therapy_session",
+   "fieldtype": "Link",
+   "label": "Therapy Session",
+   "options": "Therapy Session"
+  },
+  {
+   "fieldname": "column_break_4",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fetch_from": "therapy_session.practitioner",
+   "fieldname": "healthcare_practitioner",
+   "fieldtype": "Link",
+   "label": "Healthcare Practitioner",
+   "options": "Healthcare Practitioner"
+  },
+  {
+   "fieldname": "assessment_datetime",
+   "fieldtype": "Datetime",
+   "label": "Assessment Datetime"
+  },
+  {
+   "fieldname": "section_break_7",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "assessment_sheet",
+   "fieldtype": "Table",
+   "label": "Assessment Sheet",
+   "options": "Patient Assessment Sheet"
+  },
+  {
+   "fieldname": "section_break_9",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "total_score",
+   "fieldtype": "Int",
+   "label": "Total Score",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_11",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "total_score_obtained",
+   "fieldtype": "Int",
+   "label": "Total Score Obtained",
+   "read_only": 1
+  },
+  {
+   "fieldname": "scale_min",
+   "fieldtype": "Int",
+   "hidden": 1,
+   "label": "Scale Min",
+   "read_only": 1
+  },
+  {
+   "fieldname": "scale_max",
+   "fieldtype": "Int",
+   "hidden": 1,
+   "label": "Scale Max",
+   "read_only": 1
+  },
+  {
+   "fieldname": "naming_series",
+   "fieldtype": "Select",
+   "label": "Naming Series",
+   "options": "HLC-PA-.YYYY.-"
+  },
+  {
+   "fieldname": "amended_from",
+   "fieldtype": "Link",
+   "label": "Amended From",
+   "no_copy": 1,
+   "options": "Patient Assessment",
+   "print_hide": 1,
+   "read_only": 1
+  },
+  {
+   "fieldname": "assessment_description",
+   "fieldtype": "Small Text",
+   "label": "Assessment Description"
+  }
+ ],
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2020-04-21 13:23:09.815007",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Assessment",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  },
+  {
+   "cancel": 1,
+   "create": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Physician",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "patient",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment/patient_assessment.py b/erpnext/healthcare/doctype/patient_assessment/patient_assessment.py
new file mode 100644
index 0000000..3033a3e
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment/patient_assessment.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+from frappe.model.mapper import get_mapped_doc
+
+class PatientAssessment(Document):
+	def validate(self):
+		self.set_total_score()
+
+	def set_total_score(self):
+		total_score = 0
+		for entry in self.assessment_sheet:
+			total_score += int(entry.score)
+		self.total_score_obtained = total_score
+
+@frappe.whitelist()
+def create_patient_assessment(source_name, target_doc=None):
+	doc = get_mapped_doc('Therapy Session', source_name, {
+			'Therapy Session': {
+				'doctype': 'Patient Assessment',
+				'field_map': [
+					['therapy_session', 'name'],
+					['patient', 'patient'],
+					['practitioner', 'practitioner']
+				]
+			}
+		}, target_doc)
+
+	return doc
+
+
+
diff --git a/erpnext/healthcare/doctype/patient_assessment/test_patient_assessment.py b/erpnext/healthcare/doctype/patient_assessment/test_patient_assessment.py
new file mode 100644
index 0000000..3fda855
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment/test_patient_assessment.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestPatientAssessment(unittest.TestCase):
+	pass
diff --git a/erpnext/healthcare/doctype/patient_assessment_detail/__init__.py b/erpnext/healthcare/doctype/patient_assessment_detail/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_detail/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.json b/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.json
new file mode 100644
index 0000000..179f441
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.json
@@ -0,0 +1,32 @@
+{
+ "actions": [],
+ "creation": "2020-04-19 19:33:00.115395",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "assessment_parameter"
+ ],
+ "fields": [
+  {
+   "fieldname": "assessment_parameter",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Assessment Parameter",
+   "options": "Patient Assessment Parameter",
+   "reqd": 1
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-04-19 19:33:00.115395",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Assessment Detail",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.py b/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.py
new file mode 100644
index 0000000..0519599
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class PatientAssessmentDetail(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/patient_assessment_parameter/__init__.py b/erpnext/healthcare/doctype/patient_assessment_parameter/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_parameter/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.js b/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.js
new file mode 100644
index 0000000..2c5d270
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Patient Assessment Parameter', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.json b/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.json
new file mode 100644
index 0000000..098bdef
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.json
@@ -0,0 +1,45 @@
+{
+ "actions": [],
+ "autoname": "field:assessment_parameter",
+ "creation": "2020-04-15 14:34:46.551042",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "assessment_parameter"
+ ],
+ "fields": [
+  {
+   "fieldname": "assessment_parameter",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Assessment Parameter",
+   "reqd": 1,
+   "unique": 1
+  }
+ ],
+ "links": [],
+ "modified": "2020-04-20 09:22:19.135196",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Assessment Parameter",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.py b/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.py
new file mode 100644
index 0000000..b8e0074
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class PatientAssessmentParameter(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/patient_assessment_parameter/test_patient_assessment_parameter.py b/erpnext/healthcare/doctype/patient_assessment_parameter/test_patient_assessment_parameter.py
new file mode 100644
index 0000000..e722f99
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_parameter/test_patient_assessment_parameter.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestPatientAssessmentParameter(unittest.TestCase):
+	pass
diff --git a/erpnext/healthcare/doctype/patient_assessment_sheet/__init__.py b/erpnext/healthcare/doctype/patient_assessment_sheet/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_sheet/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.json b/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.json
new file mode 100644
index 0000000..64e4aef
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.json
@@ -0,0 +1,57 @@
+{
+ "actions": [],
+ "creation": "2020-04-19 23:07:02.220244",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "parameter",
+  "score",
+  "time",
+  "column_break_4",
+  "comments"
+ ],
+ "fields": [
+  {
+   "fieldname": "parameter",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Parameter",
+   "options": "Patient Assessment Parameter",
+   "reqd": 1
+  },
+  {
+   "fieldname": "score",
+   "fieldtype": "Select",
+   "in_list_view": 1,
+   "label": "Score",
+   "reqd": 1
+  },
+  {
+   "fieldname": "time",
+   "fieldtype": "Time",
+   "label": "Time"
+  },
+  {
+   "fieldname": "column_break_4",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "comments",
+   "fieldtype": "Small Text",
+   "label": "Comments"
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-04-20 09:56:28.746619",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Assessment Sheet",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.py b/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.py
new file mode 100644
index 0000000..40da763
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class PatientAssessmentSheet(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/patient_assessment_template/__init__.py b/erpnext/healthcare/doctype/patient_assessment_template/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_template/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.js b/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.js
new file mode 100644
index 0000000..4041936
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Patient Assessment Template', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.json b/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.json
new file mode 100644
index 0000000..de006b1
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.json
@@ -0,0 +1,109 @@
+{
+ "actions": [],
+ "autoname": "field:assessment_name",
+ "creation": "2020-04-19 19:33:13.204707",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "assessment_name",
+  "section_break_2",
+  "parameters",
+  "assessment_scale_details_section",
+  "scale_min",
+  "scale_max",
+  "column_break_8",
+  "assessment_description"
+ ],
+ "fields": [
+  {
+   "fieldname": "parameters",
+   "fieldtype": "Table",
+   "label": "Parameters",
+   "options": "Patient Assessment Detail"
+  },
+  {
+   "fieldname": "assessment_name",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Assessment Name",
+   "reqd": 1,
+   "unique": 1
+  },
+  {
+   "fieldname": "section_break_2",
+   "fieldtype": "Section Break",
+   "label": "Assessment Parameters"
+  },
+  {
+   "fieldname": "assessment_scale_details_section",
+   "fieldtype": "Section Break",
+   "label": "Assessment Scale"
+  },
+  {
+   "fieldname": "scale_min",
+   "fieldtype": "Int",
+   "label": "Scale Minimum"
+  },
+  {
+   "fieldname": "scale_max",
+   "fieldtype": "Int",
+   "label": "Scale Maximum"
+  },
+  {
+   "fieldname": "column_break_8",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "assessment_description",
+   "fieldtype": "Small Text",
+   "label": "Assessment Description"
+  }
+ ],
+ "links": [],
+ "modified": "2020-04-21 13:14:19.075167",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Assessment 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": "Healthcare Administrator",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Physician",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.py b/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.py
new file mode 100644
index 0000000..083cab5
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class PatientAssessmentTemplate(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/patient_assessment_template/test_patient_assessment_template.py b/erpnext/healthcare/doctype/patient_assessment_template/test_patient_assessment_template.py
new file mode 100644
index 0000000..86dbd54
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_template/test_patient_assessment_template.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestPatientAssessmentTemplate(unittest.TestCase):
+	pass
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
index 83c5d2b..78e789d 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
@@ -3,6 +3,10 @@
 
 frappe.ui.form.on('Patient Encounter', {
 	setup: function(frm) {
+		frm.get_field('therapies').grid.editable_fields = [
+			{fieldname: 'therapy_type', columns: 8},
+			{fieldname: 'no_of_sessions', columns: 2}
+		];
 		frm.get_field('drug_prescription').grid.editable_fields = [
 			{fieldname: 'drug_code', columns: 2},
 			{fieldname: 'drug_name', columns: 2},
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
index d00e7bc..5f11039 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
@@ -42,6 +42,10 @@
   "lab_test_prescription",
   "sb_procedures",
   "procedure_prescription",
+  "rehabilitation_section",
+  "therapy_plan",
+  "therapies",
+  "section_break_33",
   "encounter_comment",
   "amended_from"
  ],
@@ -257,6 +261,29 @@
    "read_only": 1
   },
   {
+   "fieldname": "rehabilitation_section",
+   "fieldtype": "Section Break",
+   "label": "Rehabilitation"
+  },
+  {
+   "fieldname": "therapies",
+   "fieldtype": "Table",
+   "label": "Therapies",
+   "options": "Therapy Plan Detail"
+  },
+  {
+   "fieldname": "section_break_33",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "therapy_plan",
+   "fieldtype": "Link",
+   "hidden": 1,
+   "label": "Therapy Plan",
+   "options": "Therapy Plan",
+   "read_only": 1
+  },
+  {
    "fieldname": "appointment_type",
    "fieldtype": "Link",
    "ignore_user_permissions": 1,
@@ -291,7 +318,7 @@
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2020-02-27 12:42:21.751964",
+ "modified": "2020-04-14 16:18:08.180457",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Patient Encounter",
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
index ade4748..767643b 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
@@ -4,6 +4,7 @@
 
 from __future__ import unicode_literals
 import frappe
+from frappe import _
 from frappe.model.document import Document
 from frappe.utils import cstr
 from frappe import _
@@ -22,6 +23,24 @@
 			frappe.db.set_value('Patient Appointment', self.appointment, 'status', 'Open')
 		delete_medical_record(self)
 
+	def on_submit(self):
+		create_therapy_plan(self)
+
+def create_therapy_plan(encounter):
+	if len(encounter.therapies):
+		doc = frappe.new_doc('Therapy Plan')
+		doc.patient = encounter.patient
+		doc.start_date = encounter.encounter_date
+		for entry in encounter.therapies:
+			doc.append('therapy_plan_details', {
+				'therapy_type': entry.therapy_type,
+				'no_of_sessions': entry.no_of_sessions
+			})
+		doc.save(ignore_permissions=True)
+		if doc.get('name'):
+			encounter.db_set('therapy_plan', doc.name)
+			frappe.msgprint(_('Therapy Plan {0} created successfully.').format(frappe.bold(doc.name)), alert=True)
+
 def insert_encounter_to_medical_record(doc):
 	subject = set_subject_field(doc)
 	medical_record = frappe.new_doc('Patient Medical Record')
diff --git a/erpnext/healthcare/doctype/therapy_plan/__init__.py b/erpnext/healthcare/doctype/therapy_plan/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan/__init__.py
diff --git a/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py b/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py
new file mode 100644
index 0000000..526bb95
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+from frappe.utils import getdate
+from erpnext.healthcare.doctype.therapy_type.test_therapy_type import create_therapy_type
+from erpnext.healthcare.doctype.therapy_plan.therapy_plan import make_therapy_session
+from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_healthcare_docs, create_patient
+
+class TestTherapyPlan(unittest.TestCase):
+	def test_creation_on_encounter_submission(self):
+		patient, medical_department, practitioner = create_healthcare_docs()
+		encounter = create_encounter(patient, medical_department, practitioner)
+		self.assertTrue(frappe.db.exists('Therapy Plan', encounter.therapy_plan))
+
+	def test_status(self):
+		plan = create_therapy_plan()
+		self.assertEquals(plan.status, 'Not Started')
+
+		session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab')
+		frappe.get_doc(session).submit()
+		self.assertEquals(frappe.db.get_value('Therapy Plan', plan.name, 'status'), 'In Progress')
+
+		session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab')
+		frappe.get_doc(session).submit()
+		self.assertEquals(frappe.db.get_value('Therapy Plan', plan.name, 'status'), 'Completed')
+
+
+def create_therapy_plan():
+	patient = create_patient()
+	therapy_type = create_therapy_type()
+	plan = frappe.new_doc('Therapy Plan')
+	plan.patient = patient
+	plan.start_date = getdate()
+	plan.append('therapy_plan_details', {
+		'therapy_type': therapy_type.name,
+		'no_of_sessions': 2
+	})
+	plan.save()
+	return plan
+
+def create_encounter(patient, medical_department, practitioner):
+	encounter = frappe.new_doc('Patient Encounter')
+	encounter.patient = patient
+	encounter.practitioner = practitioner
+	encounter.medical_department = medical_department
+	therapy_type = create_therapy_type()
+	encounter.append('therapies', {
+		'therapy_type': therapy_type.name,
+		'no_of_sessions': 2
+	})
+	encounter.save()
+	encounter.submit()
+	return encounter
diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan.js b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.js
new file mode 100644
index 0000000..dea0cfe
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.js
@@ -0,0 +1,90 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Therapy Plan', {
+	setup: function(frm) {
+		frm.get_field('therapy_plan_details').grid.editable_fields = [
+			{fieldname: 'therapy_type', columns: 6},
+			{fieldname: 'no_of_sessions', columns: 2},
+			{fieldname: 'sessions_completed', columns: 2}
+		];
+	},
+
+	refresh: function(frm) {
+		if (!frm.doc.__islocal) {
+			frm.trigger('show_progress_for_therapies');
+		}
+
+		if (!frm.doc.__islocal && frm.doc.status != 'Completed') {
+			let therapy_types = (frm.doc.therapy_plan_details || []).map(function(d){ return d.therapy_type });
+			const fields = [{
+				fieldtype: 'Link',
+				label: __('Therapy Type'),
+				fieldname: 'therapy_type',
+				options: 'Therapy Type',
+				reqd: 1,
+				get_query: function() {
+					return {
+						filters: { 'therapy_type': ['in', therapy_types]}
+					}
+				}
+			}];
+
+			frm.add_custom_button(__('Therapy Session'), function() {
+				frappe.prompt(fields, data => {
+					frappe.call({
+						method: 'erpnext.healthcare.doctype.therapy_plan.therapy_plan.make_therapy_session',
+						args: {
+							therapy_plan: frm.doc.name,
+							patient: frm.doc.patient,
+							therapy_type: data.therapy_type
+						},
+						freeze: true,
+						callback: function(r) {
+							if (r.message) {
+								frappe.model.sync(r.message);
+								frappe.set_route('Form', r.message.doctype, r.message.name);
+							}
+						}
+					});
+				}, __('Select Therapy Type'), __('Create'));
+			}, __('Create'));
+		}
+	},
+
+	show_progress_for_therapies: function(frm) {
+		let bars = [];
+		let message = '';
+		let added_min = false;
+
+		// completed sessions
+		let title = __('{0} sessions completed', [frm.doc.total_sessions_completed]);
+		if (frm.doc.total_sessions_completed === 1) {
+			title = __('{0} session completed', [frm.doc.total_sessions_completed]);
+		}
+		title += __(' out of {0}', [frm.doc.total_sessions]);
+
+		bars.push({
+			'title': title,
+			'width': (frm.doc.total_sessions_completed / frm.doc.total_sessions * 100) + '%',
+			'progress_class': 'progress-bar-success'
+		});
+		if (bars[0].width == '0%') {
+			bars[0].width = '0.5%';
+			added_min = 0.5;
+		}
+		message = title;
+		frm.dashboard.add_progress(__('Status'), bars, message);
+	},
+});
+
+frappe.ui.form.on('Therapy Plan Detail', {
+	no_of_sessions: function(frm) {
+		let total = 0;
+		$.each(frm.doc.therapy_plan_details, function(_i, e) {
+			total += e.no_of_sessions;
+		});
+		frm.set_value('total_sessions', total);
+		refresh_field('total_sessions');
+	}
+});
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan.json b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.json
new file mode 100644
index 0000000..ca78b66
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.json
@@ -0,0 +1,151 @@
+{
+ "actions": [],
+ "autoname": "naming_series:",
+ "creation": "2020-03-29 20:56:49.758602",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "naming_series",
+  "patient",
+  "patient_name",
+  "column_break_4",
+  "status",
+  "start_date",
+  "section_break_3",
+  "therapy_plan_details",
+  "title",
+  "section_break_9",
+  "total_sessions",
+  "column_break_11",
+  "total_sessions_completed"
+ ],
+ "fields": [
+  {
+   "fieldname": "patient",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Patient",
+   "options": "Patient",
+   "reqd": 1
+  },
+  {
+   "fieldname": "start_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "Start Date",
+   "reqd": 1
+  },
+  {
+   "fieldname": "section_break_3",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "therapy_plan_details",
+   "fieldtype": "Table",
+   "label": "Therapy Plan Details",
+   "options": "Therapy Plan Detail",
+   "reqd": 1
+  },
+  {
+   "fieldname": "naming_series",
+   "fieldtype": "Select",
+   "label": "Naming Series",
+   "options": "HLC-THP-.YYYY.-"
+  },
+  {
+   "fetch_from": "patient.patient_name",
+   "fieldname": "patient_name",
+   "fieldtype": "Data",
+   "label": "Patient Name",
+   "read_only": 1
+  },
+  {
+   "default": "{patient_name}",
+   "fieldname": "title",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Title",
+   "no_copy": 1
+  },
+  {
+   "fieldname": "column_break_4",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "section_break_9",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "total_sessions",
+   "fieldtype": "Int",
+   "label": "Total Sessions",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_11",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "total_sessions_completed",
+   "fieldtype": "Int",
+   "label": "Total Sessions Completed",
+   "read_only": 1
+  },
+  {
+   "fieldname": "status",
+   "fieldtype": "Select",
+   "label": "Status",
+   "options": "Not Started\nIn Progress\nCompleted\nCancelled",
+   "read_only": 1
+  }
+ ],
+ "links": [],
+ "modified": "2020-04-21 13:13:43.956014",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Therapy Plan",
+ "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": "Healthcare Administrator",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Physician",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "search_fields": "patient",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "patient",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan.py b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.py
new file mode 100644
index 0000000..201264f
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class TherapyPlan(Document):
+	def validate(self):
+		self.set_totals()
+		self.set_status()
+
+	def set_status(self):
+		if not self.total_sessions_completed:
+			self.status = 'Not Started'
+		else:
+			if self.total_sessions_completed < self.total_sessions:
+				self.status = 'In Progress'
+			elif self.total_sessions_completed == self.total_sessions:
+				self.status = 'Completed'
+
+	def set_totals(self):
+		total_sessions = sum([int(d.no_of_sessions) for d in self.get('therapy_plan_details')])
+		total_sessions_completed = sum([int(d.sessions_completed) for d in self.get('therapy_plan_details')])
+		self.db_set('total_sessions', total_sessions)
+		self.db_set('total_sessions_completed', total_sessions_completed)
+
+
+@frappe.whitelist()
+def make_therapy_session(therapy_plan, patient, therapy_type):
+	therapy_type = frappe.get_doc('Therapy Type', therapy_type)
+
+	therapy_session = frappe.new_doc('Therapy Session')
+	therapy_session.therapy_plan = therapy_plan
+	therapy_session.patient = patient
+	therapy_session.therapy_type = therapy_type.name
+	therapy_session.duration = therapy_type.default_duration
+	therapy_session.rate = therapy_type.rate
+	therapy_session.exercises = therapy_type.exercises
+
+	return therapy_session.as_dict()
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan_dashboard.py b/erpnext/healthcare/doctype/therapy_plan/therapy_plan_dashboard.py
new file mode 100644
index 0000000..df64782
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan/therapy_plan_dashboard.py
@@ -0,0 +1,13 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+	return {
+		'fieldname': 'therapy_plan',
+		'transactions': [
+			{
+				'label': _('Therapy Sessions'),
+				'items': ['Therapy Session']
+			}
+		]
+	}
diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan_list.js b/erpnext/healthcare/doctype/therapy_plan/therapy_plan_list.js
new file mode 100644
index 0000000..63967af
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan/therapy_plan_list.js
@@ -0,0 +1,11 @@
+frappe.listview_settings['Therapy Plan'] = {
+	get_indicator: function(doc) {
+		var colors = {
+			'Completed': 'green',
+			'In Progress': 'orange',
+			'Not Started': 'red',
+			'Cancelled': 'grey'
+		};
+		return [__(doc.status), colors[doc.status], 'status,=,' + doc.status];
+	}
+};
diff --git a/erpnext/healthcare/doctype/therapy_plan_detail/__init__.py b/erpnext/healthcare/doctype/therapy_plan_detail/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan_detail/__init__.py
diff --git a/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.json b/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.json
new file mode 100644
index 0000000..9eb20e2
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.json
@@ -0,0 +1,48 @@
+{
+ "actions": [],
+ "creation": "2020-03-29 20:52:57.068731",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "therapy_type",
+  "no_of_sessions",
+  "sessions_completed"
+ ],
+ "fields": [
+  {
+   "fieldname": "therapy_type",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Therapy Type",
+   "options": "Therapy Type",
+   "reqd": 1
+  },
+  {
+   "fieldname": "no_of_sessions",
+   "fieldtype": "Int",
+   "in_list_view": 1,
+   "label": "No of Sessions"
+  },
+  {
+   "default": "0",
+   "depends_on": "eval:doc.parenttype=='Therapy Plan';",
+   "fieldname": "sessions_completed",
+   "fieldtype": "Int",
+   "label": "Sessions Completed",
+   "read_only": 1
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-03-30 22:02:01.740109",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Therapy Plan Detail",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.py b/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.py
new file mode 100644
index 0000000..44211f3
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class TherapyPlanDetail(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/therapy_session/__init__.py b/erpnext/healthcare/doctype/therapy_session/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_session/__init__.py
diff --git a/erpnext/healthcare/doctype/therapy_session/test_therapy_session.py b/erpnext/healthcare/doctype/therapy_session/test_therapy_session.py
new file mode 100644
index 0000000..75bb8df
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_session/test_therapy_session.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestTherapySession(unittest.TestCase):
+	pass
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session.js b/erpnext/healthcare/doctype/therapy_session/therapy_session.js
new file mode 100644
index 0000000..bb67575
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_session/therapy_session.js
@@ -0,0 +1,60 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Therapy Session', {
+	setup: function(frm) {
+		frm.get_field('exercises').grid.editable_fields = [
+			{fieldname: 'exercise_type', columns: 7},
+			{fieldname: 'counts_target', columns: 1},
+			{fieldname: 'counts_completed', columns: 1},
+			{fieldname: 'assistance_level', columns: 1}
+		];
+	},
+
+	refresh: function(frm) {
+		if (!frm.doc.__islocal) {
+			let target = 0;
+			let completed = 0;
+			$.each(frm.doc.exercises, function(_i, e) {
+				target += e.counts_target;
+				completed += e.counts_completed;
+			});
+			frm.dashboard.add_indicator(__('Counts Targetted: {0}', [target]), 'blue');
+			frm.dashboard.add_indicator(__('Counts Completed: {0}', [completed]), (completed < target) ? 'orange' : 'green');
+		}
+
+		if (frm.doc.docstatus === 1) {
+			frm.add_custom_button(__('Patient Assessment'),function() {
+				frappe.model.open_mapped_doc({
+					method: 'erpnext.healthcare.doctype.patient_assessment.patient_assessment.create_patient_assessment',
+					frm: frm,
+				})
+			}, 'Create');
+		}
+	},
+
+	therapy_type: function(frm) {
+		if (frm.doc.therapy_type) {
+			frappe.call({
+				'method': 'frappe.client.get',
+				args: {
+					doctype: 'Therapy Type',
+					name: frm.doc.therapy_type
+				},
+				callback: function(data) {
+					frm.set_value('duration', data.message.default_duration);
+					frm.set_value('rate', data.message.rate);
+					frm.doc.exercises = [];
+					$.each(data.message.exercises, function(_i, e) {
+						let exercise = frm.add_child('exercises');
+						exercise.exercise_type = e.exercise_type;
+						exercise.difficulty_level = e.difficulty_level;
+						exercise.counts_target = e.counts_target;
+						exercise.assistance_level = e.assistance_level;
+					});
+					refresh_field('exercises');
+				}
+			});
+		}
+	}
+});
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session.json b/erpnext/healthcare/doctype/therapy_session/therapy_session.json
new file mode 100644
index 0000000..5ff7196
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_session/therapy_session.json
@@ -0,0 +1,218 @@
+{
+ "actions": [],
+ "autoname": "naming_series:",
+ "creation": "2020-03-11 08:57:40.669857",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "naming_series",
+  "appointment",
+  "patient",
+  "patient_age",
+  "gender",
+  "column_break_5",
+  "therapy_plan",
+  "therapy_type",
+  "practitioner",
+  "department",
+  "details_section",
+  "duration",
+  "rate",
+  "location",
+  "company",
+  "column_break_12",
+  "service_unit",
+  "start_date",
+  "start_time",
+  "invoiced",
+  "exercises_section",
+  "exercises",
+  "amended_from"
+ ],
+ "fields": [
+  {
+   "fieldname": "naming_series",
+   "fieldtype": "Select",
+   "label": "Series",
+   "options": "HLC-THP-.YYYY.-"
+  },
+  {
+   "fieldname": "appointment",
+   "fieldtype": "Link",
+   "label": "Appointment",
+   "options": "Patient Appointment"
+  },
+  {
+   "fieldname": "patient",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Patient",
+   "options": "Patient",
+   "reqd": 1
+  },
+  {
+   "fetch_from": "patient.sex",
+   "fieldname": "gender",
+   "fieldtype": "Link",
+   "label": "Gender",
+   "options": "Gender",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_5",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "practitioner",
+   "fieldtype": "Link",
+   "label": "Healthcare Practitioner",
+   "options": "Healthcare Practitioner"
+  },
+  {
+   "fieldname": "department",
+   "fieldtype": "Link",
+   "label": "Medical Department",
+   "options": "Medical Department"
+  },
+  {
+   "fieldname": "details_section",
+   "fieldtype": "Section Break",
+   "label": "Details"
+  },
+  {
+   "fetch_from": "therapy_template.default_duration",
+   "fieldname": "duration",
+   "fieldtype": "Int",
+   "label": "Duration"
+  },
+  {
+   "fieldname": "location",
+   "fieldtype": "Select",
+   "label": "Location",
+   "options": "\nCenter\nHome\nTele"
+  },
+  {
+   "fieldname": "column_break_12",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fetch_from": "therapy_template.rate",
+   "fieldname": "rate",
+   "fieldtype": "Currency",
+   "label": "Rate"
+  },
+  {
+   "fieldname": "exercises_section",
+   "fieldtype": "Section Break",
+   "label": "Exercises"
+  },
+  {
+   "fieldname": "exercises",
+   "fieldtype": "Table",
+   "label": "Exercises",
+   "options": "Exercise"
+  },
+  {
+   "depends_on": "eval: doc.therapy_plan",
+   "fieldname": "therapy_type",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Therapy Type",
+   "options": "Therapy Type",
+   "reqd": 1
+  },
+  {
+   "fieldname": "therapy_plan",
+   "fieldtype": "Link",
+   "label": "Therapy Plan",
+   "options": "Therapy Plan",
+   "reqd": 1,
+   "set_only_once": 1
+  },
+  {
+   "fieldname": "amended_from",
+   "fieldtype": "Link",
+   "label": "Amended From",
+   "no_copy": 1,
+   "options": "Therapy Session",
+   "print_hide": 1,
+   "read_only": 1
+  },
+  {
+   "fieldname": "service_unit",
+   "fieldtype": "Link",
+   "label": "Healthcare Service Unit",
+   "options": "Healthcare Service Unit"
+  },
+  {
+   "fieldname": "start_date",
+   "fieldtype": "Date",
+   "label": "Start Date"
+  },
+  {
+   "fieldname": "start_time",
+   "fieldtype": "Time",
+   "label": "Start Time"
+  },
+  {
+   "fieldname": "company",
+   "fieldtype": "Link",
+   "label": "Company",
+   "options": "Company"
+  },
+  {
+   "default": "0",
+   "fieldname": "invoiced",
+   "fieldtype": "Check",
+   "label": "Invoiced",
+   "read_only": 1
+  },
+  {
+   "fieldname": "patient_age",
+   "fieldtype": "Data",
+   "label": "Patient Age",
+   "read_only": 1
+  }
+ ],
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2020-04-21 13:16:46.378798",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Therapy Session",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "cancel": 1,
+   "create": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Physician",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "search_fields": "patient,appointment,therapy_plan,therapy_type",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "patient",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session.py b/erpnext/healthcare/doctype/therapy_session/therapy_session.py
new file mode 100644
index 0000000..45d2ee6
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_session/therapy_session.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+from frappe.model.mapper import get_mapped_doc
+
+class TherapySession(Document):
+	def on_submit(self):
+		self.update_sessions_count_in_therapy_plan()
+
+	def on_cancel(self):
+		self.update_sessions_count_in_therapy_plan(on_cancel=True)
+
+	def update_sessions_count_in_therapy_plan(self, on_cancel=False):
+		therapy_plan = frappe.get_doc('Therapy Plan', self.therapy_plan)
+		for entry in therapy_plan.therapy_plan_details:
+			if entry.therapy_type == self.therapy_type:
+				if on_cancel:
+					entry.sessions_completed -= 1
+				else:
+					entry.sessions_completed += 1
+		therapy_plan.save()
+
+
+@frappe.whitelist()
+def create_therapy_session(source_name, target_doc=None):
+	def set_missing_values(source, target):
+		therapy_type = frappe.get_doc('Therapy Type', source.therapy_type)
+		target.exercises = therapy_type.exercises
+
+	doc = get_mapped_doc('Patient Appointment', source_name, {
+			'Patient Appointment': {
+				'doctype': 'Therapy Session',
+				'field_map': [
+					['appointment', 'name'],
+					['patient', 'patient'],
+					['patient_age', 'patient_age'],
+					['gender', 'patient_sex'],
+					['therapy_type', 'therapy_type'],
+					['therapy_plan', 'therapy_plan'],
+					['practitioner', 'practitioner'],
+					['department', 'department'],
+					['start_date', 'appointment_date'],
+					['start_time', 'appointment_time'],
+					['service_unit', 'service_unit'],
+					['company', 'company'],
+					['invoiced', 'invoiced']
+				]
+			}
+		}, target_doc, set_missing_values)
+
+	return doc
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session_dashboard.py b/erpnext/healthcare/doctype/therapy_session/therapy_session_dashboard.py
new file mode 100644
index 0000000..9de7e29
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_session/therapy_session_dashboard.py
@@ -0,0 +1,13 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+	return {
+		'fieldname': 'therapy_session',
+		'transactions': [
+			{
+				'label': _('Assessments'),
+				'items': ['Patient Assessment']
+			}
+		]
+	}
diff --git a/erpnext/healthcare/doctype/therapy_type/__init__.py b/erpnext/healthcare/doctype/therapy_type/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_type/__init__.py
diff --git a/erpnext/healthcare/doctype/therapy_type/test_therapy_type.py b/erpnext/healthcare/doctype/therapy_type/test_therapy_type.py
new file mode 100644
index 0000000..03a1be8
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_type/test_therapy_type.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestTherapyType(unittest.TestCase):
+	def test_therapy_type_item(self):
+		therapy_type = create_therapy_type()
+		self.assertTrue(frappe.db.exists('Item', therapy_type.item))
+
+		therapy_type.disabled = 1
+		therapy_type.save()
+		self.assertEquals(frappe.db.get_value('Item', therapy_type.item, 'disabled'), 1)
+
+def create_therapy_type():
+	exercise = create_exercise_type()
+	therapy_type = frappe.db.exists('Therapy Type', 'Basic Rehab')
+	if not therapy_type:
+		therapy_type = frappe.new_doc('Therapy Type')
+		therapy_type.therapy_type = 'Basic Rehab'
+		therapy_type.default_duration = 30
+		therapy_type.is_billable = 1
+		therapy_type.rate = 5000
+		therapy_type.item_code = 'Basic Rehab'
+		therapy_type.item_name = 'Basic Rehab'
+		therapy_type.item_group = 'Services'
+		therapy_type.append('exercises', {
+			'exercise_type': exercise.name,
+			'counts_target': 10,
+			'assistance_level': 'Passive'
+		})
+		therapy_type.save()
+	else:
+		therapy_type = frappe.get_doc('Therapy Type', 'Basic Rehab')
+	return therapy_type
+
+def create_exercise_type():
+	exercise_type = frappe.db.exists('Exercise Type', 'Sit to Stand')
+	if not exercise_type:
+		exercise_type = frappe.new_doc('Exercise Type')
+		exercise_type.exercise_name = 'Sit to Stand'
+		exercise_type.append('steps_table', {
+			'title': 'Step 1',
+			'description': 'Squat and Rise'
+		})
+		exercise_type.save()
+	return exercise_type
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_type/therapy_type.js b/erpnext/healthcare/doctype/therapy_type/therapy_type.js
new file mode 100644
index 0000000..7a61b0d
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_type/therapy_type.js
@@ -0,0 +1,93 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Therapy Type', {
+	setup: function(frm) {
+		frm.get_field('exercises').grid.editable_fields = [
+			{fieldname: 'exercise_type', columns: 7},
+			{fieldname: 'difficulty_level', columns: 1},
+			{fieldname: 'counts_target', columns: 1},
+			{fieldname: 'assistance_level', columns: 1}
+		];
+	},
+
+	refresh: function(frm) {
+		if (!frm.doc.__islocal) {
+			cur_frm.add_custom_button(__('Change Item Code'), function() {
+				change_template_code(frm.doc);
+			});
+		}
+	},
+
+	therapy_type: function(frm) {
+		if (!frm.doc.item_code)
+			frm.set_value('item_code', frm.doc.therapy_type);
+		if (!frm.doc.description)
+			frm.set_value('description', frm.doc.therapy_type);
+		mark_change_in_item(frm);
+	},
+
+	rate: function(frm) {
+		mark_change_in_item(frm);
+	},
+
+	is_billable: function (frm) {
+		mark_change_in_item(frm);
+	},
+
+	item_group: function(frm) {
+		mark_change_in_item(frm);
+	},
+
+	description: function(frm) {
+		mark_change_in_item(frm);
+	},
+
+	medical_department: function(frm) {
+		mark_change_in_item(frm);
+	}
+});
+
+let mark_change_in_item = function(frm) {
+	if (!frm.doc.__islocal) {
+		frm.doc.change_in_item = 1;
+	}
+};
+
+let change_template_code = function(doc) {
+	let d = new frappe.ui.Dialog({
+		title:__('Change Item Code'),
+		fields:[
+			{
+				'fieldtype': 'Data',
+				'label': 'Item Code',
+				'fieldname': 'item_code',
+				reqd: 1
+			}
+		],
+		primary_action: function() {
+			let values = d.get_values();
+
+			if (values) {
+				frappe.call({
+					'method': 'erpnext.healthcare.doctype.therapy_type.therapy_type.change_item_code_from_therapy',
+					'args': {item_code: values.item_code, doc: doc},
+					callback: function () {
+						cur_frm.reload_doc();
+						frappe.show_alert({
+							message: 'Item Code renamed successfully',
+							indicator: 'green'
+						});
+					}
+				});
+			}
+			d.hide();
+		},
+		primary_action_label: __('Change Item Code')
+	});
+	d.show();
+
+	d.set_values({
+		'item_code': doc.item_code
+	});
+};
diff --git a/erpnext/healthcare/doctype/therapy_type/therapy_type.json b/erpnext/healthcare/doctype/therapy_type/therapy_type.json
new file mode 100644
index 0000000..0b3c3ca
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_type/therapy_type.json
@@ -0,0 +1,211 @@
+{
+ "actions": [],
+ "autoname": "field:therapy_type",
+ "creation": "2020-03-29 20:48:31.715063",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "disabled",
+  "section_break_2",
+  "therapy_type",
+  "default_duration",
+  "medical_department",
+  "column_break_3",
+  "is_billable",
+  "rate",
+  "healthcare_service_unit",
+  "item_details_section",
+  "item",
+  "item_code",
+  "item_name",
+  "item_group",
+  "column_break_12",
+  "description",
+  "section_break_18",
+  "therapy_for",
+  "add_exercises",
+  "section_break_6",
+  "exercises",
+  "change_in_item"
+ ],
+ "fields": [
+  {
+   "fieldname": "therapy_type",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Therapy Type",
+   "reqd": 1,
+   "unique": 1
+  },
+  {
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
+  {
+   "default": "0",
+   "fieldname": "is_billable",
+   "fieldtype": "Check",
+   "label": "Is Billable"
+  },
+  {
+   "depends_on": "eval:doc.is_billable;",
+   "fieldname": "rate",
+   "fieldtype": "Currency",
+   "label": "Rate",
+   "mandatory_depends_on": "eval:doc.is_billable;"
+  },
+  {
+   "fieldname": "section_break_6",
+   "fieldtype": "Section Break",
+   "label": "Exercises"
+  },
+  {
+   "fieldname": "exercises",
+   "fieldtype": "Table",
+   "label": "Exercises",
+   "options": "Exercise"
+  },
+  {
+   "fieldname": "default_duration",
+   "fieldtype": "Int",
+   "label": "Default Duration (In Minutes)"
+  },
+  {
+   "default": "0",
+   "fieldname": "disabled",
+   "fieldtype": "Check",
+   "label": "Disabled"
+  },
+  {
+   "fieldname": "item_details_section",
+   "fieldtype": "Section Break",
+   "label": "Item Details"
+  },
+  {
+   "fieldname": "item",
+   "fieldtype": "Link",
+   "label": "Item",
+   "options": "Item",
+   "read_only": 1
+  },
+  {
+   "fieldname": "item_code",
+   "fieldtype": "Data",
+   "label": "Item Code",
+   "reqd": 1,
+   "set_only_once": 1
+  },
+  {
+   "fieldname": "item_group",
+   "fieldtype": "Link",
+   "label": "Item Group",
+   "options": "Item Group",
+   "reqd": 1
+  },
+  {
+   "fieldname": "item_name",
+   "fieldtype": "Data",
+   "label": "Item Name",
+   "reqd": 1
+  },
+  {
+   "fieldname": "column_break_12",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "description",
+   "fieldtype": "Small Text",
+   "label": "Description"
+  },
+  {
+   "fieldname": "section_break_2",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "medical_department",
+   "fieldtype": "Link",
+   "label": "Medical Department",
+   "options": "Medical Department"
+  },
+  {
+   "default": "0",
+   "fieldname": "change_in_item",
+   "fieldtype": "Check",
+   "hidden": 1,
+   "label": "Change In Item",
+   "print_hide": 1,
+   "read_only": 1,
+   "report_hide": 1
+  },
+  {
+   "fieldname": "therapy_for",
+   "fieldtype": "Table MultiSelect",
+   "label": "Therapy For",
+   "options": "Body Part Link"
+  },
+  {
+   "fieldname": "healthcare_service_unit",
+   "fieldtype": "Link",
+   "label": "Healthcare Service Unit",
+   "options": "Healthcare Service Unit"
+  },
+  {
+   "depends_on": "eval: doc.therapy_for",
+   "fieldname": "add_exercises",
+   "fieldtype": "Button",
+   "label": "Add Exercises",
+   "options": "add_exercises"
+  },
+  {
+   "fieldname": "section_break_18",
+   "fieldtype": "Section Break"
+  }
+ ],
+ "links": [],
+ "modified": "2020-04-21 13:09:04.006289",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Therapy Type",
+ "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": "Healthcare Administrator",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Physician",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_type/therapy_type.py b/erpnext/healthcare/doctype/therapy_type/therapy_type.py
new file mode 100644
index 0000000..ea3d84e
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_type/therapy_type.py
@@ -0,0 +1,122 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+import json
+from frappe import _
+from frappe.utils import cint
+from frappe.model.document import Document
+from frappe.model.rename_doc import rename_doc
+
+class TherapyType(Document):
+	def validate(self):
+		self.enable_disable_item()
+
+	def after_insert(self):
+		create_item_from_therapy(self)
+
+	def on_update(self):
+		if self.change_in_item:
+			self.update_item_and_item_price()
+
+	def enable_disable_item(self):
+		if self.is_billable:
+			if self.disabled:
+				frappe.db.set_value('Item', self.item, 'disabled', 1)
+			else:
+				frappe.db.set_value('Item', self.item, 'disabled', 0)
+
+	def update_item_and_item_price(self):
+		if self.is_billable and self.item:
+			item_doc = frappe.get_doc('Item', {'item_code': self.item})
+			item_doc.item_name = self.item_name
+			item_doc.item_group = self.item_group
+			item_doc.description = self.description
+			item_doc.disabled = 0
+			item_doc.ignore_mandatory = True
+			item_doc.save(ignore_permissions=True)
+
+			if self.rate:
+				item_price = frappe.get_doc('Item Price', {'item_code': self.item})
+				item_price.item_name = self.item_name
+				item_price.price_list_name = self.rate
+				item_price.ignore_mandatory = True
+				item_price.save()
+
+		elif not self.is_billable and self.item:
+			frappe.db.set_value('Item', self.item, 'disabled', 1)
+
+		self.db_set('change_in_item', 0)
+
+	def add_exercises(self):
+		exercises = self.get_exercises_for_body_parts()
+		last_idx = max([cint(d.idx) for d in self.get('exercises')] or [0,])
+		for i, d in enumerate(exercises):
+			ch = self.append('exercises', {})
+			ch.exercise_type = d.parent
+			ch.idx = last_idx + i + 1
+
+	def get_exercises_for_body_parts(self):
+		body_parts = [entry.body_part for entry in self.therapy_for]
+
+		exercises = frappe.db.sql(
+			"""
+				SELECT DISTINCT
+					b.parent, e.name, e.difficulty_level
+				FROM
+				 	`tabExercise Type` e, `tabBody Part Link` b
+				WHERE
+					b.body_part IN %(body_parts)s AND b.parent=e.name
+			""", {'body_parts': body_parts}, as_dict=1)
+
+		return exercises
+
+
+def create_item_from_therapy(doc):
+	disabled = doc.disabled
+	if doc.is_billable and not doc.disabled:
+		disabled = 0
+
+	uom = frappe.db.exists('UOM', 'Unit') or frappe.db.get_single_value('Stock Settings', 'stock_uom')
+
+	item = frappe.get_doc({
+		'doctype': 'Item',
+		'item_code': doc.item_code,
+		'item_name': doc.item_name,
+		'item_group': doc.item_group,
+		'description': doc.description,
+		'is_sales_item': 1,
+		'is_service_item': 1,
+		'is_purchase_item': 0,
+		'is_stock_item': 0,
+		'show_in_website': 0,
+		'is_pro_applicable': 0,
+		'disabled': disabled,
+		'stock_uom': uom
+	}).insert(ignore_permissions=True, ignore_mandatory=True)
+
+	make_item_price(item.name, doc.rate)
+	doc.db_set('item', item.name)
+
+
+def make_item_price(item, item_price):
+	price_list_name = frappe.db.get_value('Price List', {'selling': 1})
+	frappe.get_doc({
+		'doctype': 'Item Price',
+		'price_list': price_list_name,
+		'item_code': item,
+		'price_list_rate': item_price
+	}).insert(ignore_permissions=True, ignore_mandatory=True)
+
+@frappe.whitelist()
+def change_item_code_from_therapy(item_code, doc):
+	doc = frappe._dict(json.loads(doc))
+
+	if frappe.db.exists('Item', {'item_code': item_code}):
+		frappe.throw(_('Item with Item Code {0} already exists').format(item_code))
+	else:
+		rename_doc('Item', doc.item, item_code, ignore_permissions=True)
+		frappe.db.set_value('Therapy Type', doc.name, 'item_code', item_code)
+	return
diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py
index 246242a..9a32c73 100644
--- a/erpnext/healthcare/utils.py
+++ b/erpnext/healthcare/utils.py
@@ -30,8 +30,9 @@
 		lab_tests = get_lab_tests_to_invoice(patient)
 		clinical_procedures = get_clinical_procedures_to_invoice(patient)
 		inpatient_services = get_inpatient_services_to_invoice(patient)
+		therapy_sessions = get_therapy_sessions_to_invoice(patient)
 
-		items_to_invoice += encounters + lab_tests + clinical_procedures + inpatient_services
+		items_to_invoice += encounters + lab_tests + clinical_procedures + inpatient_services + therapy_sessions
 		return items_to_invoice
 
 def validate_customer_created(patient):
@@ -243,6 +244,25 @@
 	return services_to_invoice
 
 
+def get_therapy_sessions_to_invoice(patient):
+	therapy_sessions_to_invoice = []
+	therapy_sessions = frappe.get_list(
+		'Therapy Session',
+		fields='*',
+		filters={'patient': patient.name, 'invoiced': False}
+	)
+	for therapy in therapy_sessions:
+		if not therapy.appointment:
+			if therapy.therapy_type and frappe.db.get_value('Therapy Type', therapy.therapy_type, 'is_billable'):
+				therapy_sessions_to_invoice.append({
+					'reference_type': 'Therapy Session',
+					'reference_name': therapy.name,
+					'service': frappe.db.get_value('Therapy Type', therapy.therapy_type, 'item')
+				})
+
+	return therapy_sessions_to_invoice
+
+
 def get_service_item_and_practitioner_charge(doc):
 	is_inpatient = doc.inpatient_record
 	if is_inpatient:
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js
index 96e5cd5..b49b0ba 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.js
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js
@@ -188,7 +188,7 @@
 	},
 
 	get_items_for_mr: function(frm) {
-		const set_fields = ['actual_qty', 'item_code','item_name', 'description', 'uom', 
+		const set_fields = ['actual_qty', 'item_code','item_name', 'description', 'uom',
 			'min_order_qty', 'quantity', 'sales_order', 'warehouse', 'projected_qty', 'material_request_type'];
 		frappe.call({
 			method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_items_for_material_requests",
diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index 1490374..e94d1ff 100644
--- a/erpnext/public/build.json
+++ b/erpnext/public/build.json
@@ -1,18 +1,18 @@
 {
-    "css/erpnext.css": [
-        "public/less/erpnext.less",
-        "public/less/hub.less",
-        "public/less/call_popup.less"
-    ],
-    "css/marketplace.css": [
-        "public/less/hub.less"
-    ],
-    "js/erpnext-web.min.js": [
-        "public/js/website_utils.js",
-        "public/js/shopping_cart.js"
-    ],
+	"css/erpnext.css": [
+		"public/less/erpnext.less",
+		"public/less/hub.less",
+		"public/less/call_popup.less"
+	],
+	"css/marketplace.css": [
+		"public/less/hub.less"
+	],
+	"js/erpnext-web.min.js": [
+		"public/js/website_utils.js",
+		"public/js/shopping_cart.js"
+	],
 	"css/erpnext-web.css": [
-        "public/scss/website.scss"
+		"public/scss/website.scss"
 	],
 	"js/marketplace.min.js": [
 		"public/js/hub/marketplace.js"
@@ -47,15 +47,15 @@
 		"public/js/templates/item_quick_entry.html",
 		"public/js/utils/item_quick_entry.js",
 		"public/js/utils/customer_quick_entry.js",
-        "public/js/education/student_button.html",
-        "public/js/education/assessment_result_tool.html",
-        "public/js/hub/hub_factory.js",
-        "public/js/call_popup/call_popup.js",
-        "public/js/utils/dimension_tree_filter.js"
-    ],
-    "js/item-dashboard.min.js": [
-        "stock/dashboard/item_dashboard.html",
-        "stock/dashboard/item_dashboard_list.html",
-        "stock/dashboard/item_dashboard.js"
-    ]
+		"public/js/education/student_button.html",
+		"public/js/education/assessment_result_tool.html",
+		"public/js/hub/hub_factory.js",
+		"public/js/call_popup/call_popup.js",
+		"public/js/utils/dimension_tree_filter.js"
+	],
+	"js/item-dashboard.min.js": [
+		"stock/dashboard/item_dashboard.html",
+		"stock/dashboard/item_dashboard_list.html",
+		"stock/dashboard/item_dashboard.js"
+	]
 }
diff --git a/erpnext/public/css/erpnext.css b/erpnext/public/css/erpnext.css
index c55e422..6e4efcb 100644
--- a/erpnext/public/css/erpnext.css
+++ b/erpnext/public/css/erpnext.css
@@ -370,3 +370,39 @@
 .leaderboard .list-item_content {
   padding-right: 45px;
 }
+.exercise-card {
+	box-shadow: 0 1px 3px rgba(0,0,0,0.30);
+	border-radius: 2px;
+	padding: 6px 6px 6px 8px;
+	margin-top: 10px;
+	height: 100% !important;
+}
+.exercise-card .card-img-top {
+	width: 100%;
+	height: 15vw;
+	object-fit: cover;
+}
+.exercise-card .btn-edit {
+	position: absolute;
+	bottom: 10px;
+	left: 20px;
+}
+.exercise-card .btn-del {
+	position: absolute;
+	bottom: 10px;
+	left: 50px;
+}
+.exercise-card .card-body {
+		margin-bottom: 10px;
+}
+.exercise-card .card-footer {
+		padding: 10px;
+}
+.exercise-row {
+	height: 100% !important;
+	display: flex;
+	flex-wrap: wrap;
+}
+.exercise-col {
+	padding: 10px;
+}
diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less
index abe4868..8685837 100644
--- a/erpnext/public/less/erpnext.less
+++ b/erpnext/public/less/erpnext.less
@@ -458,4 +458,50 @@
 	.list-item_content {
 		padding-right: 45px;
 	}
+}
+
+// Healthcare
+
+.exercise-card {
+	box-shadow: 0 1px 3px rgba(0,0,0,0.30);
+	border-radius: 2px;
+	padding: 6px 6px 6px 8px;
+	margin-top: 10px;
+	height: 100% !important;
+
+	.card-img-top {
+		width: 100%;
+		height: 15vw;
+		object-fit: cover;
+	}
+
+	.btn-edit {
+		position: absolute;
+		bottom: 10px;
+		left: 20px;
+	}
+
+	.btn-del {
+		position: absolute;
+		bottom: 10px;
+		left: 50px;
+	}
+
+	.card-body {
+		margin-bottom: 10px;
+	}
+
+	.card-footer {
+		padding: 10px;
+	}
+}
+
+.exercise-row {
+	height: 100% !important;
+	display: flex;
+	flex-wrap: wrap;
+}
+
+.exercise-col {
+	padding: 10px;
 }
\ No newline at end of file