test: appointment booking for admission service unit
diff --git a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
index 10990d4..8a918b0 100644
--- a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
+++ b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
@@ -142,11 +142,15 @@
 	return inpatient_record
 
 
-def get_healthcare_service_unit():
-	service_unit = get_random("Healthcare Service Unit", filters={"inpatient_occupancy": 1})
+def get_healthcare_service_unit(unit_name=None):
+	if not unit_name:
+		service_unit = get_random("Healthcare Service Unit", filters={"inpatient_occupancy": 1})
+	else:
+		service_unit = frappe.db.exists("Healthcare Service Unit", {"healthcare_service_unit_name": unit_name})
+
 	if not service_unit:
 		service_unit = frappe.new_doc("Healthcare Service Unit")
-		service_unit.healthcare_service_unit_name = "Test Service Unit Ip Occupancy"
+		service_unit.healthcare_service_unit_name = unit_name or "Test Service Unit Ip Occupancy"
 		service_unit.company = "_Test Company"
 		service_unit.service_unit_type = get_service_unit_type()
 		service_unit.inpatient_occupancy = 1
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
index 3d9f878..3d5073b 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
@@ -38,7 +38,7 @@
 					company: frm.doc.company,
 					inpatient_record: frm.doc.inpatient_record
 				}
-			}
+			};
 		});
 
 		frm.set_query('therapy_plan', function() {
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
index dc820cb..b05c673 100755
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
@@ -18,6 +18,7 @@
 class PatientAppointment(Document):
 	def validate(self):
 		self.validate_overlaps()
+		self.validate_service_unit()
 		self.set_appointment_datetime()
 		self.validate_customer_created()
 		self.set_status()
@@ -68,6 +69,19 @@
 				overlaps[0][1], overlaps[0][2], overlaps[0][3], overlaps[0][4])
 			frappe.throw(overlapping_details, title=_('Appointments Overlapping'))
 
+	def validate_service_unit(self):
+		if self.inpatient_record and self.service_unit:
+			from erpnext.healthcare.doctype.inpatient_medication_entry.inpatient_medication_entry import get_current_healthcare_service_unit
+
+			is_inpatient_occupancy_unit = frappe.db.get_value('Healthcare Service Unit', self.service_unit,
+				'inpatient_occupancy')
+			service_unit = get_current_healthcare_service_unit(self.inpatient_record)
+			if is_inpatient_occupancy_unit and service_unit != self.service_unit:
+				msg = _('Patient {0} is not admitted in the service unit {1}').format(frappe.bold(self.patient), frappe.bold(self.service_unit)) + '<br>'
+				msg += _('Appointment for service units with Inpatient Occupancy can only be created against the unit where patient has been admitted.')
+				frappe.throw(msg, title=_('Invalid Healthcare Service Unit'))
+
+
 	def set_appointment_datetime(self):
 		self.appointment_datetime = "%s %s" % (self.appointment_date, self.appointment_time or "00:00:00")
 
diff --git a/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py
index b681ed1..7870813 100644
--- a/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py
@@ -5,7 +5,7 @@
 import unittest
 import frappe
 from erpnext.healthcare.doctype.patient_appointment.patient_appointment import update_status, make_encounter
-from frappe.utils import nowdate, add_days
+from frappe.utils import nowdate, add_days, now_datetime
 from frappe.utils.make_random import get_random
 from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
 
@@ -78,6 +78,61 @@
 		sales_invoice_name = frappe.db.get_value('Sales Invoice Item', {'reference_dn': appointment.name}, 'parent')
 		self.assertEqual(frappe.db.get_value('Sales Invoice', sales_invoice_name, 'status'), 'Cancelled')
 
+	def test_appointment_booking_for_admission_service_unit(self):
+		from erpnext.healthcare.doctype.inpatient_record.inpatient_record import admit_patient, discharge_patient, schedule_discharge
+		from erpnext.healthcare.doctype.lab_test.test_lab_test import create_patient_encounter
+		from erpnext.healthcare.doctype.inpatient_record.test_inpatient_record import \
+			create_inpatient, get_healthcare_service_unit, mark_invoiced_inpatient_occupancy
+
+		frappe.db.sql("""delete from `tabInpatient Record`""")
+		patient, medical_department, practitioner = create_healthcare_docs()
+		patient = create_patient()
+		# Schedule Admission
+		ip_record = create_inpatient(patient)
+		ip_record.expected_length_of_stay = 0
+		ip_record.save(ignore_permissions = True)
+
+		# Admit
+		service_unit = get_healthcare_service_unit('Test Service Unit Ip Occupancy')
+		admit_patient(ip_record, service_unit, now_datetime())
+
+		appointment = create_appointment(patient, practitioner, nowdate(), service_unit=service_unit)
+		self.assertEqual(appointment.service_unit, service_unit)
+
+		# Discharge
+		schedule_discharge(frappe.as_json({'patient': patient}))
+		ip_record1 = frappe.get_doc("Inpatient Record", ip_record.name)
+		mark_invoiced_inpatient_occupancy(ip_record1)
+		discharge_patient(ip_record1)
+
+	def test_invalid_healthcare_service_unit_validation(self):
+		from erpnext.healthcare.doctype.inpatient_record.inpatient_record import admit_patient, discharge_patient, schedule_discharge
+		from erpnext.healthcare.doctype.lab_test.test_lab_test import create_patient_encounter
+		from erpnext.healthcare.doctype.inpatient_record.test_inpatient_record import \
+			create_inpatient, get_healthcare_service_unit, mark_invoiced_inpatient_occupancy
+
+		frappe.db.sql("""delete from `tabInpatient Record`""")
+		patient, medical_department, practitioner = create_healthcare_docs()
+		patient = create_patient()
+		# Schedule Admission
+		ip_record = create_inpatient(patient)
+		ip_record.expected_length_of_stay = 0
+		ip_record.save(ignore_permissions = True)
+
+		# Admit
+		service_unit = get_healthcare_service_unit('Test Service Unit Ip Occupancy')
+		admit_patient(ip_record, service_unit, now_datetime())
+
+		appointment_service_unit = get_healthcare_service_unit('Test Service Unit Ip Occupancy for Appointment')
+		appointment = create_appointment(patient, practitioner, nowdate(), service_unit=appointment_service_unit, save=0)
+		self.assertRaises(frappe.exceptions.ValidationError, appointment.save)
+
+		# Discharge
+		schedule_discharge(frappe.as_json({'patient': patient}))
+		ip_record1 = frappe.get_doc("Inpatient Record", ip_record.name)
+		mark_invoiced_inpatient_occupancy(ip_record1)
+		discharge_patient(ip_record1)
+
 
 def create_healthcare_docs():
 	patient = create_patient()
@@ -125,7 +180,7 @@
 		encounter.submit()
 		return encounter
 
-def create_appointment(patient, practitioner, appointment_date, invoice=0, procedure_template=0):
+def create_appointment(patient, practitioner, appointment_date, invoice=0, procedure_template=0, service_unit=None, save=1):
 	item = create_healthcare_service_items()
 	frappe.db.set_value('Healthcare Settings', None, 'inpatient_visit_charge_item', item)
 	frappe.db.set_value('Healthcare Settings', None, 'op_consulting_charge_item', item)
@@ -136,12 +191,15 @@
 	appointment.appointment_date = appointment_date
 	appointment.company = '_Test Company'
 	appointment.duration = 15
+	if service_unit:
+		appointment.service_unit = service_unit
 	if invoice:
 		appointment.mode_of_payment = 'Cash'
 		appointment.paid_amount = 500
 	if procedure_template:
 		appointment.procedure_template = create_clinical_procedure_template().get('name')
-	appointment.save(ignore_permissions=True)
+	if save:
+		appointment.save(ignore_permissions=True)
 	return appointment
 
 def create_healthcare_service_items():