feat: add create Sales Invoice option from Therapy Session
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session.js b/erpnext/healthcare/doctype/therapy_session/therapy_session.js
index 80fca39..abe4def 100644
--- a/erpnext/healthcare/doctype/therapy_session/therapy_session.js
+++ b/erpnext/healthcare/doctype/therapy_session/therapy_session.js
@@ -19,12 +19,86 @@
 		}
 
 		if (frm.doc.docstatus === 1) {
-			frm.add_custom_button(__('Patient Assessment'),function() {
+			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');
+
+			frm.add_custom_button(__('Sales Invoice'), function() {
+				frappe.model.open_mapped_doc({
+					method: 'erpnext.healthcare.doctype.therapy_session.therapy_session.invoice_therapy_session',
+					frm: frm,
+				})
+			}, 'Create');
+		}
+	},
+
+	patient: function(frm) {
+		if (frm.doc.patient) {
+			frappe.call({
+				'method': 'erpnext.healthcare.doctype.patient.patient.get_patient_detail',
+				args: {
+					patient: frm.doc.patient
+				},
+				callback: function (data) {
+					let age = '';
+					if (data.message.dob) {
+						age = calculate_age(data.message.dob);
+					} else if (data.message.age) {
+						age = data.message.age;
+						if (data.message.age_as_on) {
+							age = __('{0} as on {1}', [age, data.message.age_as_on]);
+						}
+					}
+					frm.set_value('patient_age', age);
+					frm.set_value('gender', data.message.sex);
+					frm.set_value('patient_name', data.message.patient_name);
+				}
+			});
+		} else {
+			frm.set_value('patient_age', '');
+			frm.set_value('gender', '');
+			frm.set_value('patient_name', '');
+		}
+	},
+
+	appointment: function(frm) {
+		if (frm.doc.appointment) {
+			frappe.call({
+				'method': 'frappe.client.get',
+				args: {
+					doctype: 'Patient Appointment',
+					name: frm.doc.appointment
+				},
+				callback: function(data) {
+					let values = {
+						'patient':data.message.patient,
+						'therapy_type': data.message.therapy_type,
+						'therapy_plan': data.message.therapy_plan,
+						'practitioner': data.message.practitioner,
+						'department': data.message.department,
+						'start_date': data.message.appointment_date,
+						'start_time': data.message.appointment_time,
+						'service_unit': data.message.service_unit,
+						'company': data.message.company
+					};
+					frm.set_value(values);
+				}
+			});
+		} else {
+			let values = {
+				'patient': '',
+				'therapy_type': '',
+				'therapy_plan': '',
+				'practitioner': '',
+				'department': '',
+				'start_date': '',
+				'start_time': '',
+				'service_unit': '',
+			};
+			frm.set_value(values);
 		}
 	},
 
@@ -39,6 +113,8 @@
 				callback: function(data) {
 					frm.set_value('duration', data.message.default_duration);
 					frm.set_value('rate', data.message.rate);
+					frm.set_value('service_unit', data.message.healthcare_service_unit);
+					frm.set_value('department', data.message.medical_department);
 					frm.doc.exercises = [];
 					$.each(data.message.exercises, function(_i, e) {
 						let exercise = frm.add_child('exercises');
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session.json b/erpnext/healthcare/doctype/therapy_session/therapy_session.json
index d8c4b99..00d74a0 100644
--- a/erpnext/healthcare/doctype/therapy_session/therapy_session.json
+++ b/erpnext/healthcare/doctype/therapy_session/therapy_session.json
@@ -9,9 +9,11 @@
   "naming_series",
   "appointment",
   "patient",
+  "patient_name",
   "patient_age",
   "gender",
   "column_break_5",
+  "company",
   "therapy_plan",
   "therapy_type",
   "practitioner",
@@ -20,7 +22,6 @@
   "duration",
   "rate",
   "location",
-  "company",
   "column_break_12",
   "service_unit",
   "start_date",
@@ -163,7 +164,8 @@
    "fieldname": "company",
    "fieldtype": "Link",
    "label": "Company",
-   "options": "Company"
+   "options": "Company",
+   "reqd": 1
   },
   {
    "default": "0",
@@ -197,11 +199,18 @@
   {
    "fieldname": "column_break_25",
    "fieldtype": "Column Break"
+  },
+  {
+   "fetch_from": "patient.patient_name",
+   "fieldname": "patient_name",
+   "fieldtype": "Data",
+   "label": "Patient Name",
+   "read_only": 1
   }
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2020-04-29 13:22:13.190353",
+ "modified": "2020-04-29 16:49:16.286006",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Therapy Session",
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session.py b/erpnext/healthcare/doctype/therapy_session/therapy_session.py
index 7e24095..9650183 100644
--- a/erpnext/healthcare/doctype/therapy_session/therapy_session.py
+++ b/erpnext/healthcare/doctype/therapy_session/therapy_session.py
@@ -7,7 +7,8 @@
 from frappe.model.document import Document
 from frappe.model.mapper import get_mapped_doc
 from frappe import _
-from frappe.utils import cstr
+from frappe.utils import cstr, getdate
+from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account, get_income_account
 
 class TherapySession(Document):
 	def validate(self):
@@ -73,6 +74,44 @@
 	return doc
 
 
+@frappe.whitelist()
+def invoice_therapy_session(source_name, target_doc=None):
+	def set_missing_values(source, target):
+		target.customer = frappe.db.get_value('Patient', source.patient, 'customer')
+		target.due_date = getdate()
+		target.debit_to = get_receivable_account(source.company)
+		item = target.append('items', {})
+		item = get_therapy_item(source, item)
+		target.set_missing_values(for_validate=True)
+
+	doc = get_mapped_doc('Therapy Session', source_name, {
+			'Therapy Session': {
+				'doctype': 'Sales Invoice',
+				'field_map': [
+					['patient', 'patient'],
+					['referring_practitioner', 'practitioner'],
+					['company', 'company'],
+					['due_date', 'start_date']
+				]
+			}
+		}, target_doc, set_missing_values)
+
+	return doc
+
+
+def get_therapy_item(therapy, item):
+	item.item_code = frappe.db.get_value('Therapy Type', therapy.therapy_type, 'item')
+	item.description = _('Therapy Session Charges: {0}').format(therapy.practitioner)
+	item.income_account = get_income_account(therapy.practitioner, therapy.company)
+	item.cost_center = frappe.get_cached_value('Company', therapy.company, 'cost_center')
+	item.rate = therapy.rate
+	item.amount = therapy.rate
+	item.qty = 1
+	item.reference_dt = 'Therapy Session'
+	item.reference_dn = therapy.name
+	return item
+
+
 def insert_session_medical_record(doc):
 	subject = frappe.bold(_('Therapy: ')) + cstr(doc.therapy_type) + '<br>'
 	if doc.therapy_plan: