Merge branch 'healthcare_v11_wip' of https://github.com/ESS-LLP/erpnext-healthcare into ESS-LLP-healthcare_v11_wip
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index dc201b0..e00d17d 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -16,7 +16,8 @@
 	},
 	onload: function() {
 		var me = this;
-		this._super();		
+		this._super();
+		console.log("class erpnext.accounts.SalesInvoiceController, onload this->", this);
 
 		if(!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) {
 			// show debit_to in print format
@@ -466,7 +467,7 @@
 	}
 }
 
-//project name
+// project name
 //--------------------------
 cur_frm.fields_dict['project'].get_query = function(doc, cdt, cdn) {
 	return{
@@ -543,7 +544,7 @@
 
 frappe.ui.form.on('Sales Invoice', {
 	setup: function(frm){
-		
+
 		frm.custom_make_buttons = {
 			'Delivery Note': 'Delivery',
 			'Sales Invoice': 'Sales Return',
@@ -625,7 +626,7 @@
 			}
 		};
 	},
-	//When multiple companies are set up. in case company name is changed set default company address
+	// When multiple companies are set up. in case company name is changed set default company address
 	company:function(frm){
 		if (frm.doc.company)
 		{
@@ -712,8 +713,52 @@
 			}
 			frm.set_value("loyalty_amount", loyalty_amount);
 		}
-	}
+	},
 
+	// Healthcare
+	patient: function(frm) {
+		if (frappe.boot.active_domains.includes("Healthcare")){
+			if(frm.doc.patient){
+				frappe.call({
+					method: "frappe.client.get_value",
+					args:{
+						doctype: "Patient",
+						filters: {"name": frm.doc.patient},
+						fieldname: "customer"
+					},
+					callback:function(patient_customer) {
+						if(patient_customer){
+							frm.set_value("customer", patient_customer.message.customer);
+							frm.refresh_fields();
+						}
+					}
+				});
+			}
+			else{
+					frm.set_value("customer", '');
+			}
+		}
+	},
+	refresh: function(frm) {
+		if (frappe.boot.active_domains.includes("Healthcare")){
+			frm.set_df_property("patient", "hidden", 0);
+			frm.set_df_property("patient_name", "hidden", 0);
+			frm.set_df_property("ref_practitioner", "hidden", 0);
+			if (cint(frm.doc.docstatus==0) && cur_frm.page.current_view_name!=="pos" && !frm.doc.is_return) {
+				frm.add_custom_button(__('Healthcare Services'), function() {
+					get_healthcare_services_to_invoice(frm);
+				},"Get items from");
+				frm.add_custom_button(__('Prescriptions'), function() {
+					get_drugs_to_invoice(frm);
+				},"Get items from");
+			}
+		}
+		else{
+			frm.set_df_property("patient", "hidden", 1);
+			frm.set_df_property("patient_name", "hidden", 1);
+			frm.set_df_property("ref_practitioner", "hidden", 1);
+		}
+	}
 })
 
 frappe.ui.form.on('Sales Invoice Timesheet', {
@@ -816,3 +861,270 @@
 
 	dialog.show();
 }
+
+// Healthcare
+var get_healthcare_services_to_invoice = function(frm) {
+	var me = this;
+	let selected_patient = '';
+	var dialog = new frappe.ui.Dialog({
+		title: __("Get Items from Healthcare Services"),
+		fields:[
+			{
+				fieldtype: 'Link',
+				options: 'Patient',
+				label: 'Patient',
+				fieldname: "patient",
+				reqd: true
+			},
+			{ fieldtype: 'Section Break'	},
+			{ fieldtype: 'HTML', fieldname: 'results_area' }
+		]
+	});
+	var $wrapper;
+	var $results;
+	var $placeholder;
+	dialog.set_values({
+		'patient': frm.doc.patient
+	});
+	dialog.fields_dict["patient"].df.onchange = () => {
+		var patient = dialog.fields_dict.patient.input.value;
+		if(patient && patient!=selected_patient){
+			selected_patient = patient;
+			var method = "erpnext.healthcare.utils.get_healthcare_services_to_invoice";
+			var args = {patient: patient};
+			var columns = (["service", "reference_name", "reference_type"]);
+			get_healthcare_items(frm, true, $results, $placeholder, method, args, columns);
+		}
+		else if(!patient){
+			selected_patient = '';
+			$results.empty();
+			$results.append($placeholder);
+		}
+	}
+	$wrapper = dialog.fields_dict.results_area.$wrapper.append(`<div class="results"
+		style="border: 1px solid #d1d8dd; border-radius: 3px; height: 300px; overflow: auto;"></div>`);
+	$results = $wrapper.find('.results');
+	$placeholder = $(`<div class="multiselect-empty-state">
+				<span class="text-center" style="margin-top: -40px;">
+					<i class="fa fa-2x fa-heartbeat text-extra-muted"></i>
+					<p class="text-extra-muted">No billable Healthcare Services found</p>
+				</span>
+			</div>`);
+	$results.on('click', '.list-item--head :checkbox', (e) => {
+		$results.find('.list-item-container .list-row-check')
+			.prop("checked", ($(e.target).is(':checked')));
+	});
+	set_primary_action(frm, dialog, $results, true);
+	dialog.show();
+};
+
+var get_healthcare_items = function(frm, invoice_healthcare_services, $results, $placeholder, method, args, columns) {
+	var me = this;
+	$results.empty();
+	frappe.call({
+		method: method,
+		args: args,
+		callback: function(data) {
+			if(data.message){
+				$results.append(make_list_row(columns, invoice_healthcare_services));
+				for(let i=0; i<data.message.length; i++){
+					$results.append(make_list_row(columns, invoice_healthcare_services, data.message[i]));
+				}
+			}else {
+				$results.append($placeholder);
+			}
+		}
+	});
+}
+
+var make_list_row= function(columns, invoice_healthcare_services, result={}) {
+	var me = this;
+	// Make a head row by default (if result not passed)
+	let head = Object.keys(result).length === 0;
+	let contents = ``;
+	columns.forEach(function(column) {
+		contents += `<div class="list-item__content ellipsis">
+			${
+				head ? `<span class="ellipsis">${__(frappe.model.unscrub(column))}</span>`
+
+				:(column !== "name" ? `<span class="ellipsis">${__(result[column])}</span>`
+					: `<a class="list-id ellipsis">
+						${__(result[column])}</a>`)
+			}
+		</div>`;
+	})
+
+	let $row = $(`<div class="list-item">
+		<div class="list-item__content" style="flex: 0 0 10px;">
+			<input type="checkbox" class="list-row-check" ${result.checked ? 'checked' : ''}>
+		</div>
+		${contents}
+	</div>`);
+
+	$row = list_row_data_items(head, $row, result, invoice_healthcare_services);
+	return $row;
+};
+
+var set_primary_action= function(frm, dialog, $results, invoice_healthcare_services) {
+	var me = this;
+	dialog.set_primary_action(__('Add'), function() {
+		let checked_values = get_checked_values($results);
+		if(checked_values.length > 0){
+			frm.set_value("patient", dialog.fields_dict.patient.input.value);
+			frm.set_value("items", []);
+			add_to_item_line(frm, checked_values, invoice_healthcare_services);
+			dialog.hide();
+		}
+		else{
+			if(invoice_healthcare_services){
+				frappe.msgprint(__("Please select Healthcare Service"));
+			}
+			else{
+				frappe.msgprint(__("Please select Drug"));
+			}
+		}
+	});
+};
+
+var get_checked_values= function($results) {
+	return $results.find('.list-item-container').map(function() {
+		let checked_values = {};
+		if ($(this).find('.list-row-check:checkbox:checked').length > 0 ) {
+			checked_values['dn'] = $(this).attr('data-dn');
+			checked_values['dt'] = $(this).attr('data-dt');
+			checked_values['item'] = $(this).attr('data-item');
+			if($(this).attr('data-rate') != 'undefined'){
+				checked_values['rate'] = $(this).attr('data-rate');
+			}
+			else{
+				checked_values['rate'] = false;
+			}
+			if($(this).attr('data-income-account') != 'undefined'){
+				checked_values['income_account'] = $(this).attr('data-income-account');
+			}
+			else{
+				checked_values['income_account'] = false;
+			}
+			if($(this).attr('data-qty') != 'undefined'){
+				checked_values['qty'] = $(this).attr('data-qty');
+			}
+			else{
+				checked_values['qty'] = false;
+			}
+			if($(this).attr('data-description') != 'undefined'){
+				checked_values['description'] = $(this).attr('data-description');
+			}
+			else{
+				checked_values['description'] = false;
+			}
+			return checked_values;
+		}
+	}).get();
+};
+
+var get_drugs_to_invoice = function(frm) {
+	var me = this;
+	let selected_encounter = '';
+	var dialog = new frappe.ui.Dialog({
+		title: __("Get Items from Prescriptions"),
+		fields:[
+			{ fieldtype: 'Link', options: 'Patient', label: 'Patient', fieldname: "patient", reqd: true },
+			{ fieldtype: 'Link', options: 'Patient Encounter', label: 'Patient Encounter', fieldname: "encounter", reqd: true,
+				description:'Quantity will be calculated only for items which has "Nos" as UoM. You may change as required for each invoice item.',
+				get_query: function(doc) {
+					return {
+						filters: { patient :dialog.get_value("patient") }
+					};
+				}
+			},
+			{ fieldtype: 'Section Break' },
+			{ fieldtype: 'HTML', fieldname: 'results_area' }
+		]
+	});
+	var $wrapper;
+	var $results;
+	var $placeholder;
+	dialog.set_values({
+		'patient': frm.doc.patient,
+		'encounter': ""
+	});
+	dialog.fields_dict["encounter"].df.onchange = () => {
+		var encounter = dialog.fields_dict.encounter.input.value;
+		if(encounter && encounter!=selected_encounter){
+			selected_encounter = encounter;
+			var method = "erpnext.healthcare.utils.get_drugs_to_invoice";
+			var args = {encounter: encounter};
+			var columns = (["drug_code", "quantity", "description"]);
+			get_healthcare_items(frm, false, $results, $placeholder, method, args, columns);
+		}
+		else if(!encounter){
+			selected_encounter = '';
+			$results.empty();
+			$results.append($placeholder);
+		}
+	}
+	$wrapper = dialog.fields_dict.results_area.$wrapper.append(`<div class="results"
+		style="border: 1px solid #d1d8dd; border-radius: 3px; height: 300px; overflow: auto;"></div>`);
+	$results = $wrapper.find('.results');
+	$placeholder = $(`<div class="multiselect-empty-state">
+				<span class="text-center" style="margin-top: -40px;">
+					<i class="fa fa-2x fa-heartbeat text-extra-muted"></i>
+					<p class="text-extra-muted">No Drug Prescription found</p>
+				</span>
+			</div>`);
+	$results.on('click', '.list-item--head :checkbox', (e) => {
+		$results.find('.list-item-container .list-row-check')
+			.prop("checked", ($(e.target).is(':checked')));
+	});
+	set_primary_action(frm, dialog, $results, false);
+	dialog.show();
+};
+
+var list_row_data_items = function(head, $row, result, invoice_healthcare_services) {
+	if(invoice_healthcare_services){
+		head ? $row.addClass('list-item--head')
+			: $row = $(`<div class="list-item-container"
+				data-dn= "${result.reference_name}" data-dt= "${result.reference_type}" data-item= "${result.service}"
+				data-rate = ${result.rate}
+				data-income-account = "${result.income_account}"
+				data-qty = ${result.qty}
+				data-description = "${result.description}">
+				</div>`).append($row);
+	}
+	else{
+		head ? $row.addClass('list-item--head')
+			: $row = $(`<div class="list-item-container"
+				data-item= "${result.drug_code}"
+				data-qty = ${result.quantity}
+				data-description = "${result.description}">
+				</div>`).append($row);
+	}
+	return $row
+};
+
+var add_to_item_line = function(frm, checked_values, invoice_healthcare_services){
+	if(invoice_healthcare_services){
+		frappe.call({
+			doc: frm.doc,
+			method: "set_healthcare_services",
+			args:{
+				checked_values: checked_values
+			},
+			callback: function() {
+				frm.trigger("validate");
+				frm.refresh_fields();
+			}
+		});
+	}
+	else{
+		for(let i=0; i<checked_values.length; i++){
+			var si_item = frappe.model.add_child(frm.doc, 'Sales Invoice Item', 'items');
+			frappe.model.set_value(si_item.doctype, si_item.name, 'item_code', checked_values[i]['item']);
+			frappe.model.set_value(si_item.doctype, si_item.name, 'qty', 1);
+			if(checked_values[i]['qty'] > 1){
+				frappe.model.set_value(si_item.doctype, si_item.name, 'qty', parseFloat(checked_values[i]['qty']));
+			}
+		}
+		frm.refresh_fields();
+	}
+};
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 53d0fda..b90a555 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -24,6 +24,8 @@
 from erpnext.accounts.doctype.loyalty_program.loyalty_program import \
 	get_loyalty_program_details_with_points, get_loyalty_details, validate_loyalty_points
 
+from erpnext.healthcare.utils import manage_invoice_submit_cancel
+
 from six import iteritems
 
 form_grid_templates = {
@@ -179,6 +181,13 @@
 		if self.redeem_loyalty_points and self.loyalty_points:
 			self.apply_loyalty_points()
 
+		# Healthcare Service Invoice.
+		domain_settings = frappe.get_doc('Domain Settings')
+		active_domains = [d.domain for d in domain_settings.active_domains]
+
+		if "Healthcare" in active_domains:
+			manage_invoice_submit_cancel(self, "on_submit")
+
 	def validate_pos_paid_amount(self):
 		if len(self.payments) == 0 and self.is_pos:
 			frappe.throw(_("At least one mode of payment is required for POS invoice."))
@@ -227,6 +236,13 @@
 
 		unlink_inter_company_invoice(self.doctype, self.name, self.inter_company_invoice_reference)
 
+		# Healthcare Service Invoice.
+		domain_settings = frappe.get_doc('Domain Settings')
+		active_domains = [d.domain for d in domain_settings.active_domains]
+
+		if "Healthcare" in active_domains:
+			manage_invoice_submit_cancel(self, "on_cancel")
+
 	def update_status_updater_args(self):
 		if cint(self.update_stock):
 			self.status_updater.extend([{
@@ -1176,6 +1192,43 @@
 			from erpnext.accounts.general_ledger import make_gl_entries
 			make_gl_entries(gl_entries, cancel=(self.docstatus == 2), merge_entries=True)
 
+	# Healthcare
+	def set_healthcare_services(self, checked_values):
+		self.set("items", [])
+		from erpnext.stock.get_item_details import get_item_details
+		for checked_item in checked_values:
+			item_line = self.append("items", {})
+			price_list, price_list_currency = frappe.db.get_values("Price List", {"selling": 1}, ['name', 'currency'])[0]
+			args = {
+				'doctype': "Sales Invoice",
+				'item_code': checked_item['item'],
+				'company': self.company,
+				'customer': frappe.db.get_value("Patient", self.patient, "customer"),
+				'selling_price_list': price_list,
+				'price_list_currency': price_list_currency,
+				'plc_conversion_rate': 1.0,
+				'conversion_rate': 1.0
+			}
+			item_details = get_item_details(args)
+			item_line.item_code = checked_item['item']
+			item_line.qty = 1
+			if checked_item['qty']:
+				item_line.qty = checked_item['qty']
+			if checked_item['rate']:
+				item_line.rate = checked_item['rate']
+			else:
+				item_line.rate = item_details.price_list_rate
+			item_line.amount = float(item_line.rate) * float(item_line.qty)
+			if checked_item['income_account']:
+				item_line.income_account = checked_item['income_account']
+			if checked_item['dt']:
+				item_line.reference_dt = checked_item['dt']
+			if checked_item['dn']:
+				item_line.reference_dn = checked_item['dn']
+			if checked_item['description']:
+				item_line.description = checked_item['description']
+
+		self.set_missing_values(for_validate = True)
 
 def booked_deferred_revenue(start_date=None, end_date=None):
 	# check for the sales invoice for which GL entries has to be done
diff --git a/erpnext/domains/healthcare.py b/erpnext/domains/healthcare.py
index 5a54cf6..ee8dc81 100644
--- a/erpnext/domains/healthcare.py
+++ b/erpnext/domains/healthcare.py
@@ -21,9 +21,30 @@
 		'Patient'
 	],
 	'custom_fields': {
-		'Sales Invoice': dict(fieldname='appointment', label='Patient Appointment',
-			fieldtype='Link', options='Patient Appointment',
-			insert_after='customer')
+		'Sales Invoice': [
+			{
+				'fieldname': 'patient', 'label': 'Patient', 'fieldtype': 'Link', 'options': 'Patient',
+				'insert_after': 'naming_series'
+			},
+			{
+				'fieldname': 'patient_name', 'label': 'Patient Name', 'fieldtype': 'Data', 'fetch_from': 'patient.patient_name',
+				'insert_after': 'patient', 'read_only': True
+			},
+			{
+				'fieldname': 'ref_practitioner', 'label': 'Referring Practitioner', 'fieldtype': 'Link', 'options': 'Healthcare Practitioner',
+				'insert_after': 'customer'
+			}
+		],
+		'Sales Invoice Item': [
+			{
+				'fieldname': 'reference_dt', 'label': 'Reference DocType', 'fieldtype': 'Link', 'options': 'DocType',
+				'insert_after': 'edit_references'
+			},
+			{
+				'fieldname': 'reference_dn', 'label': 'Reference Name', 'fieldtype': 'Dynamic Link', 'options': 'reference_dt',
+				'insert_after': 'reference_dt'
+			}
+		]
 	},
 	'on_setup': 'erpnext.healthcare.setup.setup_healthcare'
 }
diff --git a/erpnext/healthcare/doctype/appointment_type/appointment_type.json b/erpnext/healthcare/doctype/appointment_type/appointment_type.json
index 4dc40b1..ceabce2 100644
--- a/erpnext/healthcare/doctype/appointment_type/appointment_type.json
+++ b/erpnext/healthcare/doctype/appointment_type/appointment_type.json
@@ -1,7 +1,7 @@
 {
  "allow_copy": 0, 
  "allow_guest_to_view": 0, 
- "allow_import": 0, 
+ "allow_import": 1, 
  "allow_rename": 1, 
  "autoname": "field:appointment_type", 
  "beta": 1, 
@@ -152,7 +152,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-06-13 00:04:24.597019", 
+ "modified": "2018-08-08 12:57:54.544216", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Appointment Type", 
@@ -208,5 +208,6 @@
  "sort_order": "DESC", 
  "title_field": "", 
  "track_changes": 0, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
index 9fc5b37..7f866e1 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
@@ -264,21 +264,20 @@
 		let args = null;
 		if(d.item_code) {
 			args = {
-				'item_code'			: d.item_code,
-				'transfer_qty'		: d.transfer_qty,
-				'company'			: frm.doc.company,
-				'quantity'				: d.qty
+				'doctype' : "Clinical Procedure",
+				'item_code' : d.item_code,
+				'company' : frm.doc.company,
+				'warehouse': frm.doc.warehouse
 			};
 			return frappe.call({
-				doc: frm.doc,
-				method: "get_item_details",
-				args: args,
+				method: "erpnext.stock.get_item_details.get_item_details",
+				args: {args: args},
 				callback: function(r) {
 					if(r.message) {
-						var d = locals[cdt][cdn];
-						$.each(r.message, function(k, v){
-							d[k] = v;
-						});
+						frappe.model.set_value(cdt, cdn, "item_name", r.message.item_name);
+						frappe.model.set_value(cdt, cdn, "stock_uom", r.message.stock_uom);
+						frappe.model.set_value(cdt, cdn, "conversion_factor", r.message.conversion_factor);
+						frappe.model.set_value(cdt, cdn, "actual_qty", r.message.actual_qty);
 						refresh_field("items");
 					}
 				}
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
index 04b96e9..c755b7f 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
@@ -252,6 +252,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "prescription", 
+   "fieldtype": "Link", 
+   "hidden": 1, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Procedure Prescription", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Procedure Prescription", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "medical_department", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -480,7 +513,8 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "is_invoiced", 
+   "default": "0", 
+   "fieldname": "invoiced", 
    "fieldtype": "Check", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
@@ -489,9 +523,9 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Is Invoiced", 
+   "label": "Invoiced", 
    "length": 0, 
-   "no_copy": 0, 
+   "no_copy": 1, 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -677,6 +711,139 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "default": "0", 
+   "fieldname": "invoice_separately_as_consumables", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Consumables Invoice Separately", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "invoice_separately_as_consumables", 
+   "fieldname": "consumable_total_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Consumable Total Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "invoice_separately_as_consumables", 
+   "fieldname": "consumption_details", 
+   "fieldtype": "Small Text", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Consumption Details", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "0", 
+   "depends_on": "invoice_separately_as_consumables", 
+   "fieldname": "consumption_invoiced", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Consumption Invoiced", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "default": "", 
    "fieldname": "status", 
    "fieldtype": "Select", 
@@ -745,10 +912,11 @@
  "quick_entry": 0, 
  "read_only": 0, 
  "read_only_onload": 0, 
+ "restrict_to_domain": "Healthcare", 
  "show_name_in_global_search": 0, 
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 1, 
  "track_seen": 0, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
index 97d8a02..6d00c25 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
@@ -10,20 +10,29 @@
 from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_account
 from erpnext.healthcare.doctype.lab_test.lab_test import create_sample_doc
 from erpnext.stock.stock_ledger import get_previous_sle
+from erpnext.stock.get_item_details import get_item_details
 
 class ClinicalProcedure(Document):
 	def validate(self):
 		if self.consume_stock and not self.status == 'Draft':
 			if not self.warehouse:
-				frappe.throw(("Set warehouse for Procedure {0} ").format(self.name))
+				frappe.throw(_("Set warehouse for Procedure {0} ").format(self.name))
 			self.set_actual_qty()
 
+		if self.items:
+			self.invoice_separately_as_consumables = False
+			for item in self.items:
+				if item.invoice_separately_as_consumables == 1:
+					self.invoice_separately_as_consumables = True
+
 	def before_insert(self):
 		if self.consume_stock:
 			set_stock_items(self, self.procedure_template, "Clinical Procedure Template")
 			self.set_actual_qty();
 
 	def after_insert(self):
+		if self.prescription:
+			frappe.db.set_value("Procedure Prescription", self.prescription, "procedure_created", 1)
 		if self.appointment:
 			frappe.db.set_value("Patient Appointment", self.appointment, "status", "Closed")
 		template = frappe.get_doc("Clinical Procedure Template", self.procedure_template)
@@ -38,6 +47,36 @@
 			create_stock_entry(self)
 		frappe.db.set_value("Clinical Procedure", self.name, "status", 'Completed')
 
+		if self.items:
+			consumable_total_amount = 0
+			consumption_details = False
+			for item in self.items:
+				if item.invoice_separately_as_consumables:
+					price_list, price_list_currency = frappe.db.get_values("Price List", {"selling": 1}, ['name', 'currency'])[0]
+					args = {
+						'doctype': "Sales Invoice",
+						'item_code': item.item_code,
+						'company': self.company,
+						'warehouse': self.warehouse,
+						'customer': frappe.db.get_value("Patient", self.patient, "customer"),
+						'selling_price_list': price_list,
+						'price_list_currency': price_list_currency,
+						'plc_conversion_rate': 1.0,
+						'conversion_rate': 1.0
+					}
+					item_details = get_item_details(args)
+					item_price = item_details.price_list_rate * item.transfer_qty
+					item_consumption_details = item_details.item_name+"\t"+str(item.qty)+" "+item.uom+"\t"+str(item_price)
+					consumable_total_amount += item_price
+					if not consumption_details:
+						consumption_details = "Clinical Procedure ("+self.name+"):\n\t"+item_consumption_details
+					else:
+						consumption_details += "\n\t"+item_consumption_details
+			if consumable_total_amount > 0:
+				frappe.db.set_value("Clinical Procedure", self.name, "consumable_total_amount", consumable_total_amount)
+				frappe.db.set_value("Clinical Procedure", self.name, "consumption_details", consumption_details)
+
+
 	def start(self):
 		allow_start = self.set_actual_qty()
 		if allow_start:
@@ -52,16 +91,7 @@
 
 		allow_start = True
 		for d in self.get('items'):
-			previous_sle = get_previous_sle({
-				"item_code": d.item_code,
-				"warehouse": self.warehouse,
-				"posting_date": nowdate(),
-				"posting_time": nowtime()
-			})
-
-			# get actual stock at source warehouse
-			d.actual_qty = previous_sle.get("qty_after_transaction") or 0
-
+			d.actual_qty = get_stock_qty(d.item_code, self.warehouse)
 			# validate qty
 			if not allow_negative_stock and d.actual_qty < d.qty:
 				allow_start = False
@@ -91,28 +121,14 @@
 				se_child.expense_account = expense_account
 		return stock_entry.as_dict()
 
-	def get_item_details(self, args=None):
-		item = frappe.db.sql("""select stock_uom, description, image, item_name,
-			expense_account, buying_cost_center, item_group from `tabItem`
-			where name = %s
-				and disabled=0
-				and (end_of_life is null or end_of_life='0000-00-00' or end_of_life > %s)""",
-			(args.get('item_code'), nowdate()), as_dict = 1)
-		if not item:
-			frappe.throw(_("Item {0} is not active or end of life has been reached").format(args.get('item_code')))
-
-		item = item[0]
-
-		ret = {
-			'uom'			      	: item.stock_uom,
-			'stock_uom'			  	: item.stock_uom,
-			'item_name' 		  	: item.item_name,
-			'quantity'				: 0,
-			'transfer_qty'			: 0,
-			'conversion_factor'		: 1
-		}
-		return ret
-
+@frappe.whitelist()
+def get_stock_qty(item_code, warehouse):
+	return get_previous_sle({
+		"item_code": item_code,
+		"warehouse": warehouse,
+		"posting_date": nowdate(),
+		"posting_time": nowtime()
+	}).get("qty_after_transaction") or 0
 
 @frappe.whitelist()
 def set_stock_items(doc, stock_detail_parent, parenttype):
@@ -130,6 +146,8 @@
 		se_child.conversion_factor = flt(d["conversion_factor"])
 		if d["batch_no"]:
 			se_child.batch_no = d["batch_no"]
+		if parenttype == "Clinical Procedure Template":
+			se_child.invoice_separately_as_consumables = d["invoice_separately_as_consumables"]
 	return doc
 
 def get_item_dict(table, parent, parenttype):
@@ -165,6 +183,8 @@
 	procedure.patient_age = appointment.patient_age
 	procedure.patient_sex = appointment.patient_sex
 	procedure.procedure_template = appointment.procedure_template
+	procedure.procedure_prescription = appointment.procedure_prescription
+	procedure.invoiced = appointment.invoiced
 	procedure.medical_department = appointment.department
 	procedure.start_date = appointment.appointment_date
 	procedure.start_time = appointment.appointment_time
diff --git a/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json b/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
index c0a3247..a974f21 100644
--- a/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
+++ b/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
@@ -14,6 +14,7 @@
  "fields": [
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 1, 
    "collapsible": 0, 
@@ -46,6 +47,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -77,6 +79,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -108,6 +111,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -139,6 +143,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -171,6 +176,39 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "invoice_separately_as_consumables", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Invoice Separately as Consumables", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -201,6 +239,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -233,6 +272,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -264,6 +304,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -296,6 +337,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -327,6 +369,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -367,7 +410,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-03-28 14:34:03.796229", 
+ "modified": "2018-07-26 17:05:29.402908", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Clinical Procedure Item", 
@@ -381,5 +424,6 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
index 35c0ff5..df56918 100644
--- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
@@ -1,7 +1,7 @@
 {
  "allow_copy": 0, 
  "allow_guest_to_view": 0, 
- "allow_import": 0, 
+ "allow_import": 1, 
  "allow_rename": 1, 
  "autoname": "field:template", 
  "beta": 1, 
@@ -16,6 +16,7 @@
  "fields": [
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -43,11 +44,12 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
+   "translatable": 0, 
+   "unique": 1
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -75,11 +77,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -107,11 +110,12 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -139,11 +143,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -169,11 +174,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -200,11 +206,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -232,11 +239,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -263,11 +271,12 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -294,11 +303,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -325,11 +335,12 @@
    "reqd": 0, 
    "search_index": 1, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -357,11 +368,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -389,11 +401,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 1, 
@@ -421,11 +434,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -453,16 +467,17 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fetch_from": "sample.sample_uom",
+   "fetch_from": "sample.sample_uom", 
    "fieldname": "sample_uom", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -486,11 +501,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -517,11 +533,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -547,11 +564,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -578,11 +596,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -609,11 +628,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -640,11 +660,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -672,7 +693,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }
  ], 
@@ -686,7 +707,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-05-16 22:43:29.674822",
+ "modified": "2018-08-08 13:00:06.260997", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Clinical Procedure Template", 
@@ -780,5 +801,6 @@
  "sort_order": "DESC", 
  "title_field": "template", 
  "track_changes": 1, 
- "track_seen": 1
-}
+ "track_seen": 1, 
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/fee_validity/fee_validity.py b/erpnext/healthcare/doctype/fee_validity/fee_validity.py
index 53a1741..9028545 100644
--- a/erpnext/healthcare/doctype/fee_validity/fee_validity.py
+++ b/erpnext/healthcare/doctype/fee_validity/fee_validity.py
@@ -4,6 +4,33 @@
 
 from __future__ import unicode_literals
 from frappe.model.document import Document
+import frappe
+from frappe.utils import getdate
+import datetime
 
 class FeeValidity(Document):
 	pass
+
+def update_fee_validity(fee_validity, date, ref_invoice=None):
+	max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
+	valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
+	if not valid_days:
+		valid_days = 1
+	if not max_visit:
+		max_visit = 1
+	date = getdate(date)
+	valid_till = date + datetime.timedelta(days=int(valid_days))
+	fee_validity.max_visit = max_visit
+	fee_validity.visited = 1
+	fee_validity.valid_till = valid_till
+	fee_validity.ref_invoice = ref_invoice
+	fee_validity.save(ignore_permissions=True)
+	return fee_validity
+
+
+def create_fee_validity(practitioner, patient, date, ref_invoice=None):
+	fee_validity = frappe.new_doc("Fee Validity")
+	fee_validity.practitioner = practitioner
+	fee_validity.patient = patient
+	fee_validity = update_fee_validity(fee_validity, date, ref_invoice)
+	return fee_validity
diff --git a/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py b/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py
index 64222ad..b8305d7 100644
--- a/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py
+++ b/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py
@@ -5,33 +5,35 @@
 
 import frappe
 import unittest
-from erpnext.healthcare.doctype.patient_appointment.patient_appointment import invoice_appointment
 from frappe.utils.make_random import get_random
-from frappe.utils import nowdate, add_days
-# test_records = frappe.get_test_records('Fee Validity')
+from frappe.utils import nowdate, add_days, getdate
+
+test_dependencies = ["Company"]
 
 class TestFeeValidity(unittest.TestCase):
 	def test_fee_validity(self):
+		frappe.db.sql("""delete from `tabPatient Appointment`""")
+		frappe.db.sql("""delete from `tabFee Validity`""")
 		patient = get_random("Patient")
 		practitioner = get_random("Healthcare Practitioner")
 		department = get_random("Medical Department")
 
 		if not patient:
 			patient = frappe.new_doc("Patient")
-			patient.patient_name = "Test Patient"
+			patient.patient_name = "_Test Patient"
 			patient.sex = "Male"
 			patient.save(ignore_permissions=True)
 			patient = patient.name
 
 		if not department:
 			medical_department = frappe.new_doc("Medical Department")
-			medical_department.department = "Test Medical Department"
+			medical_department.department = "_Test Medical Department"
 			medical_department.save(ignore_permissions=True)
 			department = medical_department.name
 
 		if not practitioner:
 			practitioner = frappe.new_doc("Healthcare Practitioner")
-			practitioner.first_name = "Amit Jain"
+			practitioner.first_name = "_Test Healthcare Practitioner"
 			practitioner.department = department
 			practitioner.save(ignore_permissions=True)
 			practitioner = practitioner.name
@@ -42,18 +44,22 @@
 		frappe.db.set_value("Healthcare Settings", None, "valid_days", 7)
 
 		appointment = create_appointment(patient, practitioner, nowdate(), department)
-		invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
-		self.assertEqual(invoice, None)
+		invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
+		self.assertEqual(invoiced, 0)
+
 		invoice_appointment(appointment)
+
 		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 4), department)
-		invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
-		self.assertTrue(invoice)
+		invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
+		self.assertTrue(invoiced)
+
 		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 5), department)
-		invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
-		self.assertEqual(invoice, None)
+		invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
+		self.assertEqual(invoiced, 0)
+
 		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 10), department)
-		invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
-		self.assertEqual(invoice, None)
+		invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
+		self.assertEqual(invoiced, 0)
 
 def create_appointment(patient, practitioner, appointment_date, department):
 	appointment = frappe.new_doc("Patient Appointment")
@@ -64,3 +70,34 @@
 	appointment.company = "_Test Company"
 	appointment.save(ignore_permissions=True)
 	return appointment
+
+def invoice_appointment(appointment_doc):
+	if not appointment_doc.name:
+		return False
+	sales_invoice = frappe.new_doc("Sales Invoice")
+	sales_invoice.customer = frappe.get_value("Patient", appointment_doc.patient, "customer")
+	sales_invoice.due_date = getdate()
+	sales_invoice.is_pos = 0
+	sales_invoice.company = appointment_doc.company
+	sales_invoice.debit_to = "_Test Receivable - _TC"
+
+	create_invoice_items(appointment_doc, sales_invoice)
+
+	sales_invoice.save(ignore_permissions=True)
+	sales_invoice.submit()
+
+def create_invoice_items(appointment, invoice):
+	item_line = invoice.append("items")
+	item_line.item_name = "Consulting Charges"
+	item_line.description = "Consulting Charges:  " + appointment.practitioner
+	item_line.uom = "Nos"
+	item_line.conversion_factor = 1
+	item_line.income_account = "_Test Account Cost for Goods Sold - _TC"
+	item_line.cost_center = "_Test Cost Center - _TC"
+	item_line.rate = 250
+	item_line.amount = 250
+	item_line.qty = 1
+	item_line.reference_dt = "Patient Appointment"
+	item_line.reference_dn = appointment.name
+
+	return invoice
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js
index f2dc849..efca484 100644
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js
@@ -27,9 +27,22 @@
 				}
 			};
 		});
+		set_query_service_item(frm, 'inpatient_visit_charge_item');
+		set_query_service_item(frm, 'op_consulting_charge_item');
 	}
 });
 
+var set_query_service_item = function(frm, service_item_field) {
+	frm.set_query(service_item_field, function() {
+		return {
+			filters: {
+				'is_sales_item': 1,
+				'is_stock_item': 0
+			}
+		};
+	});
+};
+
 frappe.ui.form.on("Healthcare Practitioner", "user_id",function(frm) {
 	if(frm.doc.user_id){
 		frappe.call({
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json
index e7c575d..ad68924 100644
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json
@@ -201,7 +201,7 @@
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
-   "search_index": 0, 
+   "search_index": 1, 
    "set_only_once": 0, 
    "translatable": 0, 
    "unique": 0
@@ -535,6 +535,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "op_consulting_charge_item", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Out Patient Consulting Charge Item", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Item", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "op_consulting_charge", 
    "fieldtype": "Currency", 
    "hidden": 0, 
@@ -568,6 +601,102 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "column_break_18", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "inpatient_visit_charge_item", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Inpatient Visit Charge Item", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Item", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "inpatient_visit_charge", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Inpatient Visit Charge", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "contacts_and_address", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -798,7 +927,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-07-10 11:18:58.760297", 
+ "modified": "2018-08-06 16:45:37.899084", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Healthcare Practitioner", 
@@ -873,5 +1002,6 @@
  "sort_order": "DESC", 
  "title_field": "first_name", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
index 753ecd1..8a087dd 100644
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
@@ -21,6 +21,10 @@
 
 	def validate(self):
 		validate_party_accounts(self)
+		if self.inpatient_visit_charge_item:
+			validate_service_item(self.inpatient_visit_charge_item, "Configure a service Item for Inpatient Visit Charge Item")
+		if self.op_consulting_charge_item:
+			validate_service_item(self.op_consulting_charge_item, "Configure a service Item for Out Patient Consulting Charge Item")
 
 		if self.user_id:
 			self.validate_for_enabled_user_id()
@@ -57,3 +61,7 @@
 
 	def on_trash(self):
 		delete_contact_and_address('Healthcare Practitioner', self.name)
+
+def validate_service_item(item, msg):
+	if frappe.db.get_value("Item", item, "is_stock_item") == 1:
+		frappe.throw(_(msg))
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py
index 3c01ab0..635464e 100644
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py
@@ -9,10 +9,6 @@
 			{
 				'label': _('Appointments and Patient Encounters'),
 				'items': ['Patient Appointment', 'Patient Encounter']
-			},
-			{
-				'label': _('Lab Tests'),
- 				'items': ['Lab Test']
 			}
 		]
 	}
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
index 945817c..7d6b6c1 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
@@ -1,7 +1,7 @@
 {
  "allow_copy": 0, 
  "allow_guest_to_view": 0, 
- "allow_import": 0, 
+ "allow_import": 1, 
  "allow_rename": 1, 
  "autoname": "field:healthcare_service_unit_name", 
  "beta": 1, 
@@ -43,7 +43,7 @@
    "search_index": 0, 
    "set_only_once": 0, 
    "translatable": 0, 
-   "unique": 0
+   "unique": 1
   }, 
   {
    "allow_bulk_edit": 0, 
@@ -116,7 +116,7 @@
    "allow_bulk_edit": 0, 
    "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
-   "bold": 0, 
+   "bold": 1, 
    "collapsible": 0, 
    "columns": 0, 
    "depends_on": "eval:doc.is_group != 1", 
@@ -246,7 +246,7 @@
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
-   "search_index": 0, 
+   "search_index": 1, 
    "set_only_once": 0, 
    "translatable": 0, 
    "unique": 0
@@ -258,10 +258,10 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "default": "0", 
+   "default": "", 
    "depends_on": "eval:doc.inpatient_occupancy == 1", 
-   "fieldname": "occupied", 
-   "fieldtype": "Check", 
+   "fieldname": "occupancy_status", 
+   "fieldtype": "Select", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -269,9 +269,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Occupied", 
+   "label": "Occupancy Status", 
    "length": 0, 
    "no_copy": 1, 
+   "options": "Vacant\nOccupied", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -460,7 +461,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-07-17 17:40:18.867327", 
+ "modified": "2018-08-08 12:57:12.709806", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Healthcare Service Unit", 
@@ -535,5 +536,6 @@
  "sort_order": "DESC", 
  "title_field": "healthcare_service_unit_name", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js
index 4eb9475..a03b579 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js
@@ -1,3 +1,35 @@
 frappe.treeview_settings["Healthcare Service Unit"] = {
-	ignore_fields:["parent_healthcare_service_unit"]
+	breadcrumbs: "Healthcare Service Unit",
+	title: __("Healthcare Service Unit"),
+	get_tree_root: false,
+	filters: [{
+		fieldname: "company",
+		fieldtype: "Select",
+		options: erpnext.utils.get_tree_options("company"),
+		label: __("Company"),
+		default: erpnext.utils.get_tree_default("company")
+	}],
+	get_tree_nodes: 'erpnext.healthcare.utils.get_children',
+	ignore_fields:["parent_healthcare_service_unit"],
+	onrender: function(node) {
+		if (node.data.occupied_out_of_vacant!==undefined){
+			$('<span class="balance-area pull-right text-muted small">'
+				+ " " + node.data.occupied_out_of_vacant
+				+ '</span>').insertBefore(node.$ul);
+		}
+		if (node.data && node.data.inpatient_occupancy!==undefined) {
+			if (node.data.inpatient_occupancy == 1){
+				if (node.data.occupancy_status == "Occupied"){
+					$('<span class="balance-area pull-right small">'
+						+ " " + node.data.occupancy_status
+						+ '</span>').insertBefore(node.$ul);
+				}
+				if (node.data.occupancy_status == "Vacant"){
+					$('<span class="balance-area pull-right text-muted small">'
+						+ " " + node.data.occupancy_status
+						+ '</span>').insertBefore(node.$ul);
+				}
+			}
+		}
+	},
 };
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json
index 6394ce7..40681e9 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json
@@ -1,8 +1,8 @@
 {
  "allow_copy": 0, 
  "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
+ "allow_import": 1, 
+ "allow_rename": 1, 
  "autoname": "field:service_unit_type", 
  "beta": 0, 
  "creation": "2018-07-11 16:47:51.414675", 
@@ -43,7 +43,7 @@
    "search_index": 0, 
    "set_only_once": 0, 
    "translatable": 0, 
-   "unique": 0
+   "unique": 1
   }, 
   {
    "allow_bulk_edit": 0, 
@@ -351,8 +351,8 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "rate", 
-   "fieldtype": "Currency", 
+   "fieldname": "no_of_hours", 
+   "fieldtype": "Int", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -360,7 +360,7 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Rate / UOM", 
+   "label": "UOM Conversion in Hours", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -414,6 +414,38 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "rate", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Rate / UOM", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "default": "0", 
    "fieldname": "disabled", 
    "fieldtype": "Check", 
@@ -515,7 +547,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-07-13 16:54:59.131606", 
+ "modified": "2018-08-08 13:00:23.751635", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Healthcare Service Unit Type", 
@@ -545,10 +577,12 @@
  "quick_entry": 0, 
  "read_only": 0, 
  "read_only_onload": 0, 
+ "restrict_to_domain": "Healthcare", 
  "show_name_in_global_search": 0, 
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "title_field": "service_unit_type", 
  "track_changes": 0, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
index e0d380b..727d035 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
@@ -8,6 +8,11 @@
 from frappe.model.document import Document
 
 class HealthcareServiceUnitType(Document):
+	def validate(self):
+		if self.is_billable == 1:
+			if not self.uom or not self.item_group or not self.description or not self.no_of_hours > 0:
+				frappe.throw(_("Configure Item Fields like UOM, Item Group, Description and No of Hours."))
+
 	def after_insert(self):
 		if self.inpatient_occupancy and self.is_billable:
 			create_item(self)
@@ -22,13 +27,16 @@
 	def on_update(self):
 		if(self.change_in_item and self.is_billable == 1 and self.item):
 			updating_item(self)
-			if not item_price_exist(self):
-				if(self.test_rate != 0.0):
+			item_price = item_price_exist(self)
+			if not item_price:
+				if(self.rate != 0.0):
 					price_list_name = frappe.db.get_value("Price List", {"selling": 1})
-					if(self.test_rate):
-						make_item_price(self.test_code, price_list_name, self.test_rate)
+					if(self.rate):
+						make_item_price(self.item_code, price_list_name, self.rate)
 					else:
-						make_item_price(self.test_code, price_list_name, 0.0)
+						make_item_price(self.item_code, price_list_name, 0.0)
+			else:
+				frappe.db.set_value("Item Price", item_price, "price_list_rate", self.rate)
 
 			frappe.db.set_value(self.doctype,self.name,"change_in_item",0)
 		elif(self.is_billable == 0 and self.item):
@@ -40,7 +48,7 @@
 	"doctype": "Item Price",
 	"item_code": doc.item_code})
 	if(item_price):
-		return True
+		return item_price[0][0]
 	else:
 		return False
 
diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.js b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.js
index 8e98fee..22fbf50 100644
--- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.js
+++ b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.js
@@ -23,5 +23,19 @@
 				}
 			};
 		});
+		set_query_service_item(frm, 'inpatient_visit_charge_item');
+		set_query_service_item(frm, 'op_consulting_charge_item');
+		set_query_service_item(frm, 'clinical_procedure_consumable_item');
 	}
 });
+
+var set_query_service_item = function(frm, service_item_field) {
+	frm.set_query(service_item_field, function() {
+		return {
+			filters: {
+				'is_sales_item': 1,
+				'is_stock_item': 0
+			}
+		};
+	});
+};
diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
index 0bd8534..24c3cd9 100644
--- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
+++ b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
@@ -248,6 +248,40 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "default": "0", 
+   "description": "Manage Appointment Invoice submit and cancel automatically for Patient Encounter", 
+   "fieldname": "manage_appointment_invoice_automatically", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Manage Appointment Invoice Automatically", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "max_visit", 
    "fieldtype": "Int", 
    "hidden": 0, 
@@ -312,6 +346,168 @@
    "bold": 0, 
    "collapsible": 1, 
    "columns": 0, 
+   "fieldname": "healthcare_service_items", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Healthcare Service Items", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "inpatient_visit_charge_item", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Inpatient Visit Charge Item", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Item", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "op_consulting_charge_item", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Out Patient Consulting Charge Item", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Item", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "column_break_13", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "clinical_procedure_consumable_item", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Clinical Procedure Consumable Item", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Item", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 1, 
+   "columns": 0, 
    "fieldname": "out_patient_sms_alerts", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -804,6 +1000,38 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "create_test_on_si_submit", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Create Lab Test(s) on Sales Invoice Submit", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "description": "Create documents for sample collection", 
    "fieldname": "require_sample_collection", 
    "fieldtype": "Check", 
@@ -1099,7 +1327,7 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-07-16 14:00:04.171717", 
+ "modified": "2018-08-03 15:18:36.631441", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Healthcare Settings", 
@@ -1134,5 +1362,6 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py
index 8c3cdfe..8555e80 100644
--- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py
+++ b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py
@@ -10,13 +10,19 @@
 import json
 
 class HealthcareSettings(Document):
-    def validate(self):
-        for key in ["collect_registration_fee","manage_customer","patient_master_name",
-        "require_test_result_approval","require_sample_collection", "default_medical_code_standard"]:
-            frappe.db.set_default(key, self.get(key, ""))
-        if(self.collect_registration_fee):
-            if self.registration_fee <= 0 :
-                frappe.throw(_("Registration fee can not be Zero"))
+	def validate(self):
+		for key in ["collect_registration_fee","manage_customer","patient_master_name",
+		"require_test_result_approval","require_sample_collection", "default_medical_code_standard"]:
+			frappe.db.set_default(key, self.get(key, ""))
+		if(self.collect_registration_fee):
+			if self.registration_fee <= 0 :
+				frappe.throw(_("Registration fee can not be Zero"))
+		if self.inpatient_visit_charge_item:
+			validate_service_item(self.inpatient_visit_charge_item, "Configure a service Item for Inpatient Visit Charge Item")
+		if self.op_consulting_charge_item:
+			validate_service_item(self.op_consulting_charge_item, "Configure a service Item for Out Patient Consulting Charge Item")
+		if self.clinical_procedure_consumable_item:
+			validate_service_item(self.clinical_procedure_consumable_item, "Configure a service Item for Clinical Procedure Consumable Item")
 
 @frappe.whitelist()
 def get_sms_text(doc):
@@ -67,3 +73,7 @@
     if(parent_field):
         return frappe.db.get_value("Party Account",
             {"parentfield": parent_field, "parent": parent, "company": company}, "account")
+
+def validate_service_item(item, msg):
+	if frappe.db.get_value("Item", item, "is_stock_item") == 1:
+		frappe.throw(_(msg))
diff --git a/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json b/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json
index 2ac498d..62dc198 100644
--- a/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json
+++ b/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json
@@ -104,7 +104,7 @@
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
-   "search_index": 0, 
+   "search_index": 1, 
    "set_only_once": 0, 
    "translatable": 0, 
    "unique": 0
@@ -140,6 +140,39 @@
    "set_only_once": 0, 
    "translatable": 0, 
    "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "0", 
+   "fieldname": "invoiced", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Invoiced", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
   }
  ], 
  "has_web_view": 0, 
@@ -152,7 +185,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-07-17 18:26:46.009878", 
+ "modified": "2018-08-06 16:46:54.699133", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Inpatient Occupancy", 
@@ -166,5 +199,6 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js
index 936c682..67c12f6 100644
--- a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js
+++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js
@@ -94,7 +94,7 @@
 			filters: {
 				"is_group": 0,
 				"service_unit_type": dialog.get_value("service_unit_type"),
-				"occupied" : 0
+				"occupancy_status" : "Vacant"
 			}
 		};
 	};
@@ -166,7 +166,7 @@
 			filters: {
 				"is_group": 0,
 				"service_unit_type": dialog.get_value("service_unit_type"),
-				"occupied" : 0
+				"occupancy_status" : "Vacant"
 			}
 		};
 	};
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.json b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.json
index 50f17e9..92c11fb 100644
--- a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.json
+++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.json
@@ -968,6 +968,7 @@
  "quick_entry": 0, 
  "read_only": 0, 
  "read_only_onload": 0, 
+ "restrict_to_domain": "Healthcare", 
  "search_fields": "patient", 
  "show_name_in_global_search": 0, 
  "sort_field": "modified", 
@@ -976,4 +977,4 @@
  "track_changes": 1, 
  "track_seen": 0, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
index 07cd9e4..c107cd7 100644
--- a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
+++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
@@ -69,29 +69,75 @@
 	inpatient_record.save(ignore_permissions = True)
 
 @frappe.whitelist()
-def schedule_discharge(patient, encounter_id, practitioner):
+def schedule_discharge(patient, encounter_id=None, practitioner=None):
 	inpatient_record_id = frappe.db.get_value('Patient', patient, 'inpatient_record')
 	if inpatient_record_id:
 		inpatient_record = frappe.get_doc("Inpatient Record", inpatient_record_id)
 		inpatient_record.discharge_practitioner = practitioner
 		inpatient_record.discharge_encounter = encounter_id
 		inpatient_record.status = "Discharge Scheduled"
+
+		check_out_inpatient(inpatient_record)
+
 		inpatient_record.save(ignore_permissions = True)
 	frappe.db.set_value("Patient", patient, "inpatient_status", "Discharge Scheduled")
 
-def discharge_patient(inpatient_record):
+def check_out_inpatient(inpatient_record):
 	if inpatient_record.inpatient_occupancies:
 		for inpatient_occupancy in inpatient_record.inpatient_occupancies:
 			if inpatient_occupancy.left != 1:
 				inpatient_occupancy.left = True
 				inpatient_occupancy.check_out = now_datetime()
-				frappe.db.set_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "occupied", False)
+				frappe.db.set_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "occupancy_status", "Vacant")
 
+def discharge_patient(inpatient_record):
+	validate_invoiced_inpatient(inpatient_record)
 	inpatient_record.discharge_date = today()
 	inpatient_record.status = "Discharged"
 
 	inpatient_record.save(ignore_permissions = True)
 
+def validate_invoiced_inpatient(inpatient_record):
+	pending_invoices = []
+	if inpatient_record.inpatient_occupancies:
+		service_unit_names = False
+		for inpatient_occupancy in inpatient_record.inpatient_occupancies:
+			if inpatient_occupancy.invoiced != 1:
+				if service_unit_names:
+					service_unit_names += ", " + inpatient_occupancy.service_unit
+				else:
+					service_unit_names = inpatient_occupancy.service_unit
+		if service_unit_names:
+			pending_invoices.append("Inpatient Occupancy (" + service_unit_names + ")")
+
+	docs = ["Patient Appointment", "Patient Encounter", "Lab Test", "Clinical Procedure"]
+
+	for doc in docs:
+		doc_name_list = get_inpatient_docs_not_invoiced(doc, inpatient_record)
+		if doc_name_list:
+			pending_invoices = get_pending_doc(doc, doc_name_list, pending_invoices)
+
+	if pending_invoices:
+		frappe.throw(_("Can not mark Inpatient Record Discharged, there are Unbilled Invoices {0}").format(", "
+			.join(pending_invoices)))
+
+def get_pending_doc(doc, doc_name_list, pending_invoices):
+	if doc_name_list:
+		doc_ids = False
+		for doc_name in doc_name_list:
+			if doc_ids:
+				doc_ids += ", "+doc_name.name
+			else:
+				doc_ids = doc_name.name
+		if doc_ids:
+			pending_invoices.append(doc + " (" + doc_ids + ")")
+
+	return pending_invoices
+
+def get_inpatient_docs_not_invoiced(doc, inpatient_record):
+	return frappe.db.get_list(doc, filters = {"patient": inpatient_record.patient,
+					"inpatient_record": inpatient_record.name, "invoiced": 0})
+
 def admit_patient(inpatient_record, service_unit, check_in, expected_discharge=None):
 	inpatient_record.admitted_datetime = check_in
 	inpatient_record.status = "Admitted"
@@ -110,7 +156,7 @@
 
 	inpatient_record.save(ignore_permissions = True)
 
-	frappe.db.set_value("Healthcare Service Unit", service_unit, "occupied", True)
+	frappe.db.set_value("Healthcare Service Unit", service_unit, "occupancy_status", "Occupied")
 
 def patient_leave_service_unit(inpatient_record, check_out, leave_from):
 	if inpatient_record.inpatient_occupancies:
@@ -118,7 +164,7 @@
 			if inpatient_occupancy.left != 1 and inpatient_occupancy.service_unit == leave_from:
 				inpatient_occupancy.left = True
 				inpatient_occupancy.check_out = check_out
-				frappe.db.set_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "occupied", False)
+				frappe.db.set_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "occupancy_status", "Vacant")
 	inpatient_record.save(ignore_permissions = True)
 
 @frappe.whitelist()
diff --git a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
index b192064..8849748 100644
--- a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
+++ b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
@@ -7,10 +7,11 @@
 import unittest
 from frappe.utils import now_datetime, today
 from frappe.utils.make_random import get_random
-from erpnext.healthcare.doctype.inpatient_record.inpatient_record import admit_patient, discharge_patient
+from erpnext.healthcare.doctype.inpatient_record.inpatient_record import admit_patient, discharge_patient, schedule_discharge
 
 class TestInpatientRecord(unittest.TestCase):
 	def test_admit_and_discharge(self):
+		frappe.db.sql("""delete from `tabInpatient Record`""")
 		patient = get_patient()
 		# Schedule Admission
 		ip_record = create_inpatient(patient)
@@ -22,13 +23,21 @@
 		service_unit = get_healthcare_service_unit()
 		admit_patient(ip_record, service_unit, now_datetime())
 		self.assertEqual("Admitted", frappe.db.get_value("Patient", patient, "inpatient_status"))
-		self.assertEqual(1, frappe.db.get_value("Healthcare Service Unit", service_unit, "occupied"))
+		self.assertEqual("Occupied", frappe.db.get_value("Healthcare Service Unit", service_unit, "occupancy_status"))
 
 		# Discharge
-		discharge_patient(ip_record)
+		schedule_discharge(patient=patient)
+		self.assertEqual("Vacant", frappe.db.get_value("Healthcare Service Unit", service_unit, "occupancy_status"))
+
+		ip_record1 = frappe.get_doc("Inpatient Record", ip_record.name)
+		# Validate Pending Invoices
+		self.assertRaises(frappe.ValidationError, ip_record.discharge)
+		mark_invoiced_inpatient_occupancy(ip_record1)
+
+		discharge_patient(ip_record1)
+
 		self.assertEqual(None, frappe.db.get_value("Patient", patient, "inpatient_record"))
 		self.assertEqual(None, frappe.db.get_value("Patient", patient, "inpatient_status"))
-		self.assertEqual(0, frappe.db.get_value("Healthcare Service Unit", service_unit, "occupied"))
 
 	def test_validate_overlap_admission(self):
 		frappe.db.sql("""delete from `tabInpatient Record`""")
@@ -45,6 +54,12 @@
 		self.assertRaises(frappe.ValidationError, ip_record_new.save)
 		frappe.db.sql("""delete from `tabInpatient Record`""")
 
+def mark_invoiced_inpatient_occupancy(ip_record):
+	if ip_record.inpatient_occupancies:
+		for inpatient_occupancy in ip_record.inpatient_occupancies:
+			inpatient_occupancy.invoiced = 1
+		ip_record.save(ignore_permissions = True)
+
 def create_inpatient(patient):
 	patient_obj = frappe.get_doc('Patient', patient)
 	inpatient_record = frappe.new_doc('Inpatient Record')
@@ -78,7 +93,7 @@
 		service_unit.healthcare_service_unit_name = "Test Service Unit Ip Occupancy"
 		service_unit.service_unit_type = get_service_unit_type()
 		service_unit.inpatient_occupancy = 1
-		service_unit.occupied = 0
+		service_unit.occupancy_status = "Vacant"
 		service_unit.is_group = 0
 		service_unit_parent_name = frappe.db.exists({
 				"doctype": "Healthcare Service Unit",
diff --git a/erpnext/healthcare/doctype/lab_prescription/lab_prescription.json b/erpnext/healthcare/doctype/lab_prescription/lab_prescription.json
index 127bebf..ce6b206 100644
--- a/erpnext/healthcare/doctype/lab_prescription/lab_prescription.json
+++ b/erpnext/healthcare/doctype/lab_prescription/lab_prescription.json
@@ -13,6 +13,7 @@
  "fields": [
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -40,16 +41,17 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fetch_from": "test_code.test_name",
+   "fetch_from": "test_code.test_name", 
    "fieldname": "test_name", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -73,17 +75,19 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "invoice", 
-   "fieldtype": "Link", 
+   "default": "0", 
+   "fieldname": "invoiced", 
+   "fieldtype": "Check", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -91,10 +95,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Invoice", 
+   "label": "Invoiced", 
    "length": 0, 
-   "no_copy": 0, 
-   "options": "Sales Invoice", 
+   "no_copy": 1, 
+   "options": "", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -103,13 +107,14 @@
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
-   "search_index": 0, 
+   "search_index": 1, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -135,11 +140,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -166,11 +172,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -195,9 +202,9 @@
    "remember_last_selected_value": 0, 
    "report_hide": 1, 
    "reqd": 0, 
-   "search_index": 0, 
+   "search_index": 1, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }
  ], 
@@ -211,7 +218,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-05-16 22:43:39.014193",
+ "modified": "2018-08-06 16:53:02.033406", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Lab Prescription", 
@@ -226,5 +233,6 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 0, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.js b/erpnext/healthcare/doctype/lab_test/lab_test.js
index c3b069d..06637bc 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.js
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.js
@@ -24,11 +24,6 @@
 	refresh :  function(frm){
 		refresh_field('normal_test_items');
 		refresh_field('special_test_items');
-		if(!frm.doc.__islocal && !frm.doc.invoice && frappe.user.has_role("Accounts User")){
-			frm.add_custom_button(__('Make Invoice'), function() {
-				make_invoice(frm);
-			});
-		}
 		if(frm.doc.__islocal){
 			frm.add_custom_button(__('Get from Patient Encounter'), function () {
 				get_lab_test_prescribed(frm);
@@ -166,8 +161,8 @@
 		<div class="col-xs-1">\
 		<a data-name="%(name)s" data-lab-test="%(lab_test)s"\
 		data-encounter="%(encounter)s" data-practitioner="%(practitioner)s"\
-		data-invoice="%(invoice)s" href="#"><button class="btn btn-default btn-xs">Get Lab Test\
-		</button></a></div></div>', {name:y[0], lab_test: y[1], encounter:y[2], invoice:y[3], practitioner:y[4], date:y[5]})).appendTo(html_field);
+		data-invoiced="%(invoiced)s" href="#"><button class="btn btn-default btn-xs">Get Lab Test\
+		</button></a></div></div>', {name:y[0], lab_test: y[1], encounter:y[2], invoiced:y[3], practitioner:y[4], date:y[5]})).appendTo(html_field);
 		row.find("a").click(function() {
 			frm.doc.template = $(this).attr("data-lab-test");
 			frm.doc.prescription = $(this).attr("data-name");
@@ -175,14 +170,11 @@
 			frm.set_df_property("template", "read_only", 1);
 			frm.set_df_property("patient", "read_only", 1);
 			frm.set_df_property("practitioner", "read_only", 1);
-			if($(this).attr("data-invoice") != 'null'){
-				frm.doc.invoice = $(this).attr("data-invoice");
-				refresh_field("invoice");
-			}else {
-				frm.doc.invoice = "";
-				refresh_field("invoice");
+			frm.doc.invoiced = 0;
+			if($(this).attr("data-invoiced") == 1){
+				frm.doc.invoiced = 1;
 			}
-
+			refresh_field("invoiced");
 			refresh_field("template");
 			d.hide();
 			return false;
@@ -195,24 +187,6 @@
 	d.show();
 };
 
-var make_invoice = function(frm){
-	var doc = frm.doc;
-	frappe.call({
-		method: "erpnext.healthcare.doctype.lab_test.lab_test.create_invoice",
-		args: {company:doc.company, patient:doc.patient, lab_tests: [doc.name], prescriptions:[]},
-		callback: function(r){
-			if(!r.exc){
-				if(r.message){
-					/*	frappe.show_alert(__('Sales Invoice {0} created',
-					['<a href="#Form/Sales Invoice/'+r.message+'">' + r.message+ '</a>']));	*/
-					frappe.set_route("Form", "Sales Invoice", r.message);
-				}
-				cur_frm.reload_doc();
-			}
-		}
-	});
-};
-
 cur_frm.cscript.custom_before_submit =  function(doc) {
 	if(doc.normal_test_items){
 		for(let result in doc.normal_test_items){
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.json b/erpnext/healthcare/doctype/lab_test/lab_test.json
index 89b513f..9db3ae5 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.json
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.json
@@ -88,8 +88,9 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "invoice", 
-   "fieldtype": "Link", 
+   "default": "0", 
+   "fieldname": "invoiced", 
+   "fieldtype": "Check", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -97,10 +98,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Invoice", 
+   "label": "Invoiced", 
    "length": 0, 
    "no_copy": 1, 
-   "options": "Sales Invoice", 
+   "options": "", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -1586,7 +1587,7 @@
  "read_only": 0, 
  "read_only_onload": 0, 
  "restrict_to_domain": "Healthcare", 
- "search_fields": "patient,invoice,practitioner,test_name,sample", 
+ "search_fields": "patient,practitioner,test_name,sample", 
  "show_name_in_global_search": 1, 
  "sort_field": "modified", 
  "sort_order": "DESC", 
@@ -1594,4 +1595,4 @@
  "track_changes": 1, 
  "track_seen": 1, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.py b/erpnext/healthcare/doctype/lab_test/lab_test.py
index 767581f..98ab696 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.py
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.py
@@ -4,11 +4,9 @@
 
 from __future__ import unicode_literals
 import frappe
-from frappe.model.document import Document
-import json
-from frappe.utils import getdate, cstr
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account
 from frappe import _
+from frappe.model.document import Document
+from frappe.utils import getdate, cstr
 
 class LabTest(Document):
 	def on_submit(self):
@@ -31,6 +29,8 @@
 	def after_insert(self):
 		if(self.prescription):
 			frappe.db.set_value("Lab Prescription", self.prescription, "test_created", 1)
+			if frappe.db.get_value("Lab Prescription", self.prescription, 'invoiced') == 1:
+				self.invoiced = True
 		if not self.test_name and self.template:
 			self.load_test_from_template()
 			self.reload()
@@ -60,20 +60,97 @@
 def update_lab_test_print_sms_email_status(print_sms_email, name):
 	frappe.db.set_value("Lab Test",name,print_sms_email,1)
 
-def create_lab_test_doc(invoice, encounter, patient, template):
-	#create Test Result for template, copy vals from Invoice
+@frappe.whitelist()
+def create_multiple(doctype, docname):
+	lab_test_created = False
+	if doctype == "Sales Invoice":
+		lab_test_created = create_lab_test_from_invoice(docname)
+	elif doctype == "Patient Encounter":
+		lab_test_created = create_lab_test_from_encounter(docname)
+
+	if lab_test_created:
+		frappe.msgprint(_("Lab Test(s) "+lab_test_created+" created."))
+	else:
+		frappe.msgprint(_("No Lab Test created"))
+
+def create_lab_test_from_encounter(encounter_id):
+	lab_test_created = False
+	encounter = frappe.get_doc("Patient Encounter", encounter_id)
+
+	lab_test_ids = frappe.db.sql("""select lp.name, lp.test_code, lp.invoiced
+	from `tabPatient Encounter` et, `tabLab Prescription` lp
+	where et.patient=%s and lp.parent=%s and
+	lp.parent=et.name and lp.test_created=0 and et.docstatus=1""", (encounter.patient, encounter_id))
+
+	if lab_test_ids:
+		patient = frappe.get_doc("Patient", encounter.patient)
+		for lab_test_id in lab_test_ids:
+			template = get_lab_test_template(lab_test_id[1])
+			if template:
+				lab_test = create_lab_test_doc(lab_test_id[2], encounter.practitioner, patient, template)
+				lab_test.save(ignore_permissions = True)
+				frappe.db.set_value("Lab Prescription", lab_test_id[0], "test_created", 1)
+				if not lab_test_created:
+					lab_test_created = lab_test.name
+				else:
+					lab_test_created += ", "+lab_test.name
+	return lab_test_created
+
+
+def create_lab_test_from_invoice(invoice_name):
+	lab_test_created = False
+	invoice = frappe.get_doc("Sales Invoice", invoice_name)
+	if invoice.patient:
+		patient = frappe.get_doc("Patient", invoice.patient)
+		for item in invoice.items:
+			test_created = 0
+			if item.reference_dt == "Lab Prescription":
+				test_created = frappe.db.get_value("Lab Prescription", item.reference_dn, "test_created")
+			elif item.reference_dt == "Lab Test":
+				test_created = 1
+			if test_created != 1:
+				template = get_lab_test_template(item.item_code)
+				if template:
+					lab_test = create_lab_test_doc(True, invoice.ref_practitioner, patient, template)
+					if item.reference_dt == "Lab Prescription":
+						lab_test.prescription = item.reference_dn
+					lab_test.save(ignore_permissions = True)
+					if item.reference_dt != "Lab Prescription":
+						frappe.db.set_value("Sales Invoice Item", item.name, "reference_dt", "Lab Test")
+						frappe.db.set_value("Sales Invoice Item", item.name, "reference_dn", lab_test.name)
+					if not lab_test_created:
+						lab_test_created = lab_test.name
+					else:
+						lab_test_created += ", "+lab_test.name
+	return lab_test_created
+
+def get_lab_test_template(item):
+	template_id = check_template_exists(item)
+	if template_id:
+		return frappe.get_doc("Lab Test Template", template_id)
+	return False
+
+def check_template_exists(item):
+	template_exists = frappe.db.exists(
+		"Lab Test Template",
+		{
+			'item': item
+		}
+	)
+	if template_exists:
+		return template_exists
+	return False
+
+def create_lab_test_doc(invoiced, practitioner, patient, template):
 	lab_test = frappe.new_doc("Lab Test")
-	if(invoice):
-		lab_test.invoice = invoice
-	if(encounter):
-		lab_test.practitioner = encounter.practitioner
+	lab_test.invoiced = invoiced
+	lab_test.practitioner = practitioner
 	lab_test.patient = patient.name
 	lab_test.patient_age = patient.get_age()
 	lab_test.patient_sex = patient.sex
 	lab_test.email = patient.email
 	lab_test.mobile = patient.mobile
 	lab_test.department = template.department
-	lab_test.test_name = template.test_name
 	lab_test.template = template.name
 	lab_test.test_group = template.test_group
 	lab_test.result_date = getdate()
@@ -133,7 +210,7 @@
 			#create Sample Collection for template, copy vals from Invoice
 			sample_collection = frappe.new_doc("Sample Collection")
 			if(invoice):
-				sample_collection.invoice = invoice
+				sample_collection.invoiced = True
 			sample_collection.patient = patient.name
 			sample_collection.patient_age = patient.get_age()
 			sample_collection.patient_sex = patient.sex
@@ -146,24 +223,6 @@
 
 		return sample_collection
 
-@frappe.whitelist()
-def create_lab_test_from_desk(patient, template, prescription, invoice=None):
-	lab_test_exist = frappe.db.exists({
-		"doctype": "Lab Test",
-		"prescription": prescription
-		})
-	if lab_test_exist:
-		return
-	template = frappe.get_doc("Lab Test Template", template)
-	#skip the loop if there is no test_template for Item
-	if not (template):
-		return
-	patient = frappe.get_doc("Patient", patient)
-	encounter_id = frappe.get_value("Lab Prescription", prescription, "parent")
-	encounter = frappe.get_doc("Patient Encounter", encounter_id)
-	lab_test = create_lab_test(patient, template, prescription, encounter, invoice)
-	return lab_test.name
-
 def create_sample_collection(lab_test, template, patient, invoice):
 	if(frappe.db.get_value("Healthcare Settings", None, "require_sample_collection") == "1"):
 		sample_collection = create_sample_doc(template, patient, invoice)
@@ -211,16 +270,10 @@
 		if(prescription):
 			lab_test.prescription = prescription
 			if(invoice):
-				frappe.db.set_value("Lab Prescription", prescription, "invoice", invoice)
+				frappe.db.set_value("Lab Prescription", prescription, "invoiced", True)
 		lab_test.save(ignore_permissions=True) # insert the result
 		return lab_test
 
-def create_lab_test(patient, template, prescription,  encounter, invoice):
-	lab_test = create_lab_test_doc(invoice, encounter, patient, template)
-	lab_test = create_sample_collection(lab_test, template, patient, invoice)
-	lab_test = load_result_format(lab_test, template, prescription, invoice)
-	return lab_test
-
 @frappe.whitelist()
 def get_employee_by_user_id(user_id):
 	emp_id = frappe.db.get_value("Employee",{"user_id":user_id})
@@ -248,49 +301,7 @@
 	if medical_record_id and medical_record_id[0][0]:
 		frappe.delete_doc("Patient Medical Record", medical_record_id[0][0])
 
-def create_item_line(test_code, sales_invoice):
-	if test_code:
-		item = frappe.get_doc("Item", test_code)
-		if item:
-			if not item.disabled:
-				sales_invoice_line = sales_invoice.append("items")
-				sales_invoice_line.item_code = item.item_code
-				sales_invoice_line.item_name =  item.item_name
-				sales_invoice_line.qty = 1.0
-				sales_invoice_line.description = item.description
-
-@frappe.whitelist()
-def create_invoice(company, patient, lab_tests, prescriptions):
-	test_ids = json.loads(lab_tests)
-	line_ids = json.loads(prescriptions)
-	if not test_ids and not line_ids:
-		return
-	sales_invoice = frappe.new_doc("Sales Invoice")
-	sales_invoice.customer = frappe.get_value("Patient", patient, "customer")
-	sales_invoice.due_date = getdate()
-	sales_invoice.is_pos = '0'
-	sales_invoice.debit_to = get_receivable_account(company)
-	for line in line_ids:
-		test_code = frappe.get_value("Lab Prescription", line, "test_code")
-		create_item_line(test_code, sales_invoice)
-	for test in test_ids:
-		template = frappe.get_value("Lab Test", test, "template")
-		test_code = frappe.get_value("Lab Test Template", template, "item")
-		create_item_line(test_code, sales_invoice)
-	sales_invoice.set_missing_values()
-	sales_invoice.save()
-	#set invoice in lab test
-	for test in test_ids:
-		frappe.db.set_value("Lab Test", test, "invoice", sales_invoice.name)
-		prescription = frappe.db.get_value("Lab Test", test, "prescription")
-		if prescription:
-			frappe.db.set_value("Lab Prescription", prescription, "invoice", sales_invoice.name)
-	#set invoice in prescription
-	for line in line_ids:
-		frappe.db.set_value("Lab Prescription", line, "invoice", sales_invoice.name)
-	return sales_invoice.name
-
 @frappe.whitelist()
 def get_lab_test_prescribed(patient):
-	return frappe.db.sql("""select cp.name, cp.test_code, cp.parent, cp.invoice, ct.practitioner, ct.encounter_date from `tabPatient Encounter` ct,
+	return frappe.db.sql("""select cp.name, cp.test_code, cp.parent, cp.invoiced, ct.practitioner, ct.encounter_date from `tabPatient Encounter` ct,
 	`tabLab Prescription` cp where ct.patient=%s and cp.parent=ct.name and cp.test_created=0""", (patient))
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test_list.js b/erpnext/healthcare/doctype/lab_test/lab_test_list.js
index c36c115..1f6a12f 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test_list.js
+++ b/erpnext/healthcare/doctype/lab_test/lab_test_list.js
@@ -2,7 +2,7 @@
 (c) ESS 2015-16
 */
 frappe.listview_settings['Lab Test'] = {
-	add_fields: ["name", "status", "invoice"],
+	add_fields: ["name", "status", "invoiced"],
 	filters:[["docstatus","=","0"]],
 	get_indicator: function(doc) {
 		if(doc.status=="Approved"){
@@ -11,5 +11,52 @@
 		if(doc.status=="Rejected"){
 			return [__("Rejected"), "yellow", "status,=,Rejected"];
 		}
+	},
+	onload: function(listview) {
+		listview.page.add_menu_item(__("Create Multiple"), function() {
+			create_multiple_dialog(listview);
+		});
 	}
 };
+
+var create_multiple_dialog = function(listview){
+	var dialog = new frappe.ui.Dialog({
+		title: 'Create Multiple Lab Test',
+		width: 100,
+		fields: [
+			{fieldtype: "Link", label: "Patient", fieldname: "patient", options: "Patient", reqd: 1},
+			{fieldtype: "Select", label: "Invoice / Patient Encounter", fieldname: "doctype",
+				options: "\nSales Invoice\nPatient Encounter", reqd: 1},
+			{fieldtype: "Dynamic Link", fieldname: "docname", options: "doctype", reqd: 1,
+				get_query: function(){
+					return {
+						filters: {
+							"patient": dialog.get_value("patient"),
+							"docstatus": 1
+						}
+					};
+				}
+			}
+		],
+		primary_action_label: __("Create Lab Test"),
+		primary_action : function(){
+			frappe.call({
+				method: 'erpnext.healthcare.doctype.lab_test.lab_test.create_multiple',
+				args:{
+					'doctype': dialog.get_value("doctype"),
+					'docname': dialog.get_value("docname")
+				},
+				callback: function(data) {
+					if(!data.exc){
+						listview.refresh();
+					}
+				},
+				freeze: true,
+				freeze_message: "Creating Lab Test..."
+			});
+			dialog.hide();
+		}
+	});
+
+	dialog.show();
+};
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
index d76fb29..62a3b30 100644
--- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
+++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
@@ -12,13 +12,16 @@
 		#Item and Price List update --> if (change_in_item)
 		if(self.change_in_item and self.is_billable == 1 and self.item):
 			updating_item(self)
-			if not item_price_exist(self):
+			item_price = item_price_exist(self)
+			if not item_price:
 				if(self.test_rate != 0.0):
 					price_list_name = frappe.db.get_value("Price List", {"selling": 1})
 					if(self.test_rate):
 						make_item_price(self.test_code, price_list_name, self.test_rate)
 					else:
 						make_item_price(self.test_code, price_list_name, 0.0)
+			else:
+				frappe.db.set_value("Item Price", item_price, "price_list_rate", self.test_rate)
 
 			frappe.db.set_value(self.doctype,self.name,"change_in_item",0)
 		elif(self.is_billable == 0 and self.item):
@@ -43,7 +46,7 @@
 	"doctype": "Item Price",
 	"item_code": doc.test_code})
 	if(item_price):
-		return True
+		return item_price[0][0]
 	else:
 		return False
 
diff --git a/erpnext/healthcare/doctype/patient/patient_dashboard.py b/erpnext/healthcare/doctype/patient/patient_dashboard.py
index 098497c..46b1013 100644
--- a/erpnext/healthcare/doctype/patient/patient_dashboard.py
+++ b/erpnext/healthcare/doctype/patient/patient_dashboard.py
@@ -13,6 +13,10 @@
 			{
 				'label': _('Lab Tests and Vital Signs'),
  				'items': ['Lab Test', 'Sample Collection', 'Vital Signs']
+			},
+			{
+				'label': _('Billing'),
+				'items': ['Sales Invoice']
 			}
 		]
 	}
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
index 9799018..9338b9f 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
@@ -4,7 +4,6 @@
 frappe.ui.form.on('Patient Appointment', {
 	setup: function(frm) {
 		frm.custom_make_buttons = {
-			'Sales Invoice': 'Invoice',
 			'Vital Signs': 'Vital Signs',
 			'Patient Encounter': 'Patient Encounter'
 		};
@@ -84,20 +83,21 @@
 				btn_update_status(frm, "Cancelled");
 			});
 		}
-
-		if(!frm.doc.__islocal){
-			if(frm.doc.sales_invoice && frappe.user.has_role("Accounts User")){
-				frm.add_custom_button(__('Invoice'), function() {
-					frappe.set_route("Form", "Sales Invoice", frm.doc.sales_invoice);
-				},__("View") );
-			}
-			else if(frm.doc.status != "Cancelled" && frappe.user.has_role("Accounts User")){
-				frm.add_custom_button(__('Invoice'), function() {
-					btn_invoice_encounter(frm);
-				},__("Create"));
-			}
-		}
 		frm.set_df_property("get_procedure_from_encounter", "read_only", frm.doc.__islocal ? 0 : 1);
+		frappe.db.get_value('Healthcare Settings', {name: 'Healthcare Settings'}, 'manage_appointment_invoice_automatically', (r) => {
+			if(r.manage_appointment_invoice_automatically == 1){
+				frm.set_df_property("mode_of_payment", "hidden", 0);
+				frm.set_df_property("paid_amount", "hidden", 0);
+				frm.set_df_property("mode_of_payment", "reqd", 1);
+				frm.set_df_property("paid_amount", "reqd", 1);
+			}
+			else{
+				frm.set_df_property("mode_of_payment", "hidden", 1);
+				frm.set_df_property("paid_amount", "hidden", 1);
+				frm.set_df_property("mode_of_payment", "reqd", 0);
+				frm.set_df_property("paid_amount", "reqd", 0);
+			}
+		});
 	},
 	check_availability: function(frm) {
 		var { practitioner, appointment_date } = frm.doc;
@@ -339,21 +339,6 @@
 	);
 };
 
-var btn_invoice_encounter = function(frm){
-	frappe.call({
-		doc: frm.doc,
-		method:"create_invoice",
-		callback: function(data){
-			if(!data.exc){
-				if(data.message){
-					frappe.set_route("Form", "Sales Invoice", data.message);
-				}
-				cur_frm.reload_doc();
-			}
-		}
-	});
-};
-
 frappe.ui.form.on("Patient Appointment", "practitioner", function(frm) {
 	if(frm.doc.practitioner){
 		frappe.call({
@@ -364,6 +349,7 @@
 			},
 			callback: function (data) {
 				frappe.model.set_value(frm.doctype,frm.docname, "department",data.message.department);
+				frappe.model.set_value(frm.doctype,frm.docname, "paid_amount",data.message.op_consulting_charge);
 			}
 		});
 	}
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
index 960648b..5215c28 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
@@ -108,7 +108,7 @@
    "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
-   "reqd": 1, 
+   "reqd": 0, 
    "search_index": 1, 
    "set_only_once": 1, 
    "translatable": 0, 
@@ -617,7 +617,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "depends_on": "eval:!doc.__islocal", 
+   "depends_on": "", 
    "fieldname": "section_break_1", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -681,6 +681,71 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "mode_of_payment", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Mode of Payment", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Mode of Payment", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "paid_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Paid Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "column_break_2", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -712,8 +777,9 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "sales_invoice", 
-   "fieldtype": "Link", 
+   "default": "0", 
+   "fieldname": "invoiced", 
+   "fieldtype": "Check", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -721,10 +787,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Sales Invoice", 
+   "label": "Invoiced", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "Sales Invoice", 
+   "options": "", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -989,4 +1055,4 @@
  "track_changes": 1, 
  "track_seen": 1, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
index ad2a933..3e6706f 100755
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
@@ -6,12 +6,13 @@
 import frappe
 from frappe.model.document import Document
 import json
-from frappe.utils import getdate
+from frappe.utils import getdate, add_days
 from frappe import _
 import datetime
 from frappe.core.doctype.sms_settings.sms_settings import send_sms
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account,get_income_account
 from erpnext.hr.doctype.employee.employee import is_holiday
+from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account,get_income_account
+from erpnext.healthcare.utils import validity_exists, service_item_and_practitioner_charge
 
 class PatientAppointment(Document):
 	def on_update(self):
@@ -38,30 +39,112 @@
 				visited = fee_validity.visited + 1
 				frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
 				if fee_validity.ref_invoice:
-					frappe.db.set_value("Patient Appointment", appointment.name, "sales_invoice", fee_validity.ref_invoice)
+					frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", True)
 				frappe.msgprint(_("{0} has fee validity till {1}").format(appointment.patient, fee_validity.valid_till))
 		confirm_sms(self)
 
-	def create_invoice(self):
-		return invoice_appointment(self)
+		if frappe.db.get_value("Healthcare Settings", None, "manage_appointment_invoice_automatically") == '1' and \
+			frappe.db.get_value("Patient Appointment", self.name, "invoiced") != 1:
+			invoice_appointment(self)
+
+@frappe.whitelist()
+def invoice_appointment(appointment_doc):
+	if not appointment_doc.name:
+		return False
+	sales_invoice = frappe.new_doc("Sales Invoice")
+	sales_invoice.customer = frappe.get_value("Patient", appointment_doc.patient, "customer")
+	sales_invoice.appointment = appointment_doc.name
+	sales_invoice.due_date = getdate()
+	sales_invoice.is_pos = True
+	sales_invoice.company = appointment_doc.company
+	sales_invoice.debit_to = get_receivable_account(appointment_doc.company)
+
+	item_line = sales_invoice.append("items")
+	service_item, practitioner_charge = service_item_and_practitioner_charge(appointment_doc)
+	item_line.item_code = service_item
+	item_line.description = "Consulting Charges:  " + appointment_doc.practitioner
+	item_line.income_account = get_income_account(appointment_doc.practitioner, appointment_doc.company)
+	item_line.rate = practitioner_charge
+	item_line.amount = practitioner_charge
+	item_line.qty = 1
+	item_line.reference_dt = "Patient Appointment"
+	item_line.reference_dn = appointment_doc.name
+
+	payments_line = sales_invoice.append("payments")
+	payments_line.mode_of_payment = appointment_doc.mode_of_payment
+	payments_line.amount = appointment_doc.paid_amount
+
+	sales_invoice.set_missing_values(for_validate = True)
+
+	sales_invoice.save(ignore_permissions=True)
+	sales_invoice.submit()
+	frappe.msgprint(_("Sales Invoice {0} created as paid".format(sales_invoice.name)), alert=True)
 
 def appointment_cancel(appointment_id):
 	appointment = frappe.get_doc("Patient Appointment", appointment_id)
-
-	# If invoice --> fee_validity update with -1 visit
-	if appointment.sales_invoice:
-		validity = frappe.db.exists({"doctype": "Fee Validity", "ref_invoice": appointment.sales_invoice})
-		if validity:
-			fee_validity = frappe.get_doc("Fee Validity", validity[0][0])
-			visited = fee_validity.visited - 1
-			frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
-			if visited <= 0:
-				frappe.msgprint(
-					_("Appointment cancelled, Please review and cancel the invoice {0}".format(appointment.sales_invoice))
-				)
+	# If invoiced --> fee_validity update with -1 visit
+	if appointment.invoiced:
+		sales_invoice = exists_sales_invoice(appointment)
+		if sales_invoice and cancel_sales_invoice(sales_invoice):
+			frappe.msgprint(
+				_("Appointment {0} and Sales Invoice {1} cancelled".format(appointment.name, sales_invoice.name))
+			)
+		else:
+			validity = validity_exists(appointment.practitioner, appointment.patient)
+			if validity:
+				fee_validity = frappe.get_doc("Fee Validity", validity[0][0])
+				if appointment_valid_in_fee_validity(appointment, fee_validity.valid_till, True, fee_validity.ref_invoice):
+					visited = fee_validity.visited - 1
+					frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
+					frappe.msgprint(
+						_("Appointment cancelled, Please review and cancel the invoice {0}".format(fee_validity.ref_invoice))
+					)
+				else:
+					frappe.msgprint(_("Appointment cancelled"))
 			else:
 				frappe.msgprint(_("Appointment cancelled"))
+	else:
+		frappe.msgprint(_("Appointment cancelled"))
 
+def appointment_valid_in_fee_validity(appointment, valid_end_date, invoiced, ref_invoice):
+	valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
+	max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
+	valid_start_date = add_days(getdate(valid_end_date), -int(valid_days))
+
+	# Appointments which has same fee validity range with the appointment
+	appointments = frappe.get_list("Patient Appointment",{'patient': appointment.patient, 'invoiced': invoiced,
+	'appointment_date':("<=", getdate(valid_end_date)), 'appointment_date':(">=", getdate(valid_start_date)),
+	'practitioner': appointment.practitioner}, order_by="appointment_date desc", limit=int(max_visit))
+
+	if appointments and len(appointments) > 0:
+		appointment_obj = appointments[len(appointments)-1]
+		sales_invoice = exists_sales_invoice(appointment_obj)
+		if sales_invoice.name == ref_invoice:
+			return True
+	return False
+
+def cancel_sales_invoice(sales_invoice):
+	if frappe.db.get_value("Healthcare Settings", None, "manage_appointment_invoice_automatically") == '1':
+		if len(sales_invoice.items) == 1:
+			sales_invoice.cancel()
+			return True
+	return False
+
+def exists_sales_invoice_item(appointment):
+	return frappe.db.exists(
+		"Sales Invoice Item",
+		{
+			"reference_dt": "Patient Appointment",
+			"reference_dn": appointment.name
+		}
+	)
+
+def exists_sales_invoice(appointment):
+	sales_item_exist = exists_sales_invoice_item(appointment)
+	if sales_item_exist:
+		sales_invoice = frappe.get_doc("Sales Invoice", frappe.db.get_value("Sales Invoice Item", sales_item_exist, "parent"))
+		return sales_invoice
+	return False
 
 @frappe.whitelist()
 def get_availability_data(date, practitioner):
@@ -197,100 +280,6 @@
 		message = frappe.db.get_value("Healthcare Settings", None, "app_con_msg")
 		send_message(doc, message)
 
-
-@frappe.whitelist()
-def invoice_appointment(appointment_doc):
-	if not appointment_doc.name:
-		return False
-	sales_invoice = frappe.new_doc("Sales Invoice")
-	sales_invoice.customer = frappe.get_value("Patient", appointment_doc.patient, "customer")
-	sales_invoice.appointment = appointment_doc.name
-	sales_invoice.due_date = getdate()
-	sales_invoice.is_pos = '0'
-	sales_invoice.company = appointment_doc.company
-	sales_invoice.debit_to = get_receivable_account(appointment_doc.company)
-
-	fee_validity = get_fee_validity(appointment_doc.practitioner, appointment_doc.patient, appointment_doc.appointment_date)
-	procedure_template = False
-	if appointment_doc.procedure_template:
-		procedure_template = appointment_doc.procedure_template
-	create_invoice_items(appointment_doc.practitioner, appointment_doc.company, sales_invoice, procedure_template)
-
-	sales_invoice.save(ignore_permissions=True)
-	frappe.db.sql("""update `tabPatient Appointment` set sales_invoice=%s where name=%s""", (sales_invoice.name, appointment_doc.name))
-	frappe.db.set_value("Fee Validity", fee_validity.name, "ref_invoice", sales_invoice.name)
-	encounter = frappe.db.exists({
-			"doctype": "Patient Encounter",
-			"appointment": appointment_doc.name})
-	if encounter:
-		frappe.db.set_value("Patient Encounter", encounter[0][0], "invoice", sales_invoice.name)
-	return sales_invoice.name
-
-
-def get_fee_validity(practitioner, patient, date):
-	validity_exist = validity_exists(practitioner, patient)
-	if validity_exist:
-		fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
-		fee_validity = update_fee_validity(fee_validity, date)
-	else:
-		fee_validity = create_fee_validity(practitioner, patient, date)
-	return fee_validity
-
-
-def validity_exists(practitioner, patient):
-	return frappe.db.exists({
-			"doctype": "Fee Validity",
-			"practitioner": practitioner,
-			"patient": patient})
-
-
-def update_fee_validity(fee_validity, date):
-	max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
-	valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
-	if not valid_days:
-		valid_days = 1
-	if not max_visit:
-		max_visit = 1
-	date = getdate(date)
-	valid_till = date + datetime.timedelta(days=int(valid_days))
-	fee_validity.max_visit = max_visit
-	fee_validity.visited = 1
-	fee_validity.valid_till = valid_till
-	fee_validity.save(ignore_permissions=True)
-	return fee_validity
-
-
-def create_fee_validity(practitioner, patient, date):
-	fee_validity = frappe.new_doc("Fee Validity")
-	fee_validity.practitioner = practitioner
-	fee_validity.patient = patient
-	fee_validity = update_fee_validity(fee_validity, date)
-	return fee_validity
-
-
-def create_invoice_items(practitioner, company, invoice, procedure_template):
-	item_line = invoice.append("items")
-	if procedure_template:
-		procedure_template_obj = frappe.get_doc("Clinical Procedure Template", procedure_template)
-		item_line.item_code = procedure_template_obj.item_code
-		item_line.item_name = procedure_template_obj.template
-		item_line.description = procedure_template_obj.description
-	else:
-		item_line.item_name = "Consulting Charges"
-		item_line.description = "Consulting Charges:  " + practitioner
-		item_line.uom = "Nos"
-		item_line.conversion_factor = 1
-		item_line.income_account = get_income_account(practitioner, company)
-		op_consulting_charge = frappe.db.get_value("Healthcare Practitioner", practitioner, "op_consulting_charge")
-		if op_consulting_charge:
-			item_line.rate = op_consulting_charge
-			item_line.amount = op_consulting_charge
-	item_line.qty = 1
-
-
-	return invoice
-
-
 @frappe.whitelist()
 def create_encounter(appointment):
 	appointment = frappe.get_doc("Patient Appointment", appointment)
@@ -301,8 +290,8 @@
 	encounter.visit_department = appointment.department
 	encounter.patient_sex = appointment.patient_sex
 	encounter.encounter_date = appointment.appointment_date
-	if appointment.sales_invoice:
-		encounter.invoice = appointment.sales_invoice
+	if appointment.invoiced:
+		encounter.invoiced = True
 	return encounter.as_dict()
 
 
@@ -359,6 +348,7 @@
 		item.appointment_datetime = item.appointment_date + datetime.timedelta(minutes = item.duration)
 
 	return data
+
 @frappe.whitelist()
 def get_procedure_prescribed(patient):
 	return frappe.db.sql("""select pp.name, pp.procedure, pp.parent, ct.practitioner,
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_dashboard.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment_dashboard.py
index f9ef1cb..a030f19 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_dashboard.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment_dashboard.py
@@ -10,10 +10,6 @@
 			{
 				'label': _('Consultations'),
 				'items': ['Patient Encounter', 'Vital Signs', 'Patient Medical Record']
-			},
-			{
-				'label': _('Billing'),
-				'items': ['Sales Invoice']
 			}
 		]
 	}
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
index 47c9cad..2dd3512 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
@@ -94,11 +94,6 @@
 				}
 			};
 		});
-		if(!frm.doc.__islocal && !frm.doc.invoice && (frappe.user.has_role("Accounts User"))){
-			frm.add_custom_button(__('Invoice'), function() {
-				btn_invoice_encounter(frm);
-			},__("Create"));
-		}
 		frm.set_df_property("appointment", "read_only", frm.doc.__islocal ? 0:1);
 		frm.set_df_property("patient", "read_only", frm.doc.__islocal ? 0:1);
 		frm.set_df_property("patient_age", "read_only", frm.doc.__islocal ? 0:1);
@@ -139,23 +134,6 @@
 	});
 };
 
-var btn_invoice_encounter = function(frm){
-	var doc = frm.doc;
-	frappe.call({
-		method:
-		"erpnext.healthcare.doctype.encounter.encounter.create_invoice",
-		args: {company: doc.company, patient: doc.patient, practitioner: doc.practitioner, encounter_id: doc.name },
-		callback: function(data){
-			if(!data.exc){
-				if(data.message){
-					frappe.set_route("Form", "Sales Invoice", data.message);
-				}
-				cur_frm.reload_doc();
-			}
-		}
-	});
-};
-
 var create_medical_record = function (frm) {
 	if(!frm.doc.patient){
 		frappe.throw(__("Please select patient"));
@@ -203,10 +181,16 @@
 				frappe.model.set_value(frm.doctype,frm.docname, "patient", data.message.patient);
 				frappe.model.set_value(frm.doctype,frm.docname, "type", data.message.appointment_type);
 				frappe.model.set_value(frm.doctype,frm.docname, "practitioner", data.message.practitioner);
-				frappe.model.set_value(frm.doctype,frm.docname, "invoice", data.message.sales_invoice);
+				frappe.model.set_value(frm.doctype,frm.docname, "invoiced", data.message.invoiced);
 			}
 		});
 	}
+	else{
+		frappe.model.set_value(frm.doctype,frm.docname, "patient", "");
+		frappe.model.set_value(frm.doctype,frm.docname, "type", "");
+		frappe.model.set_value(frm.doctype,frm.docname, "practitioner", "");
+		frappe.model.set_value(frm.doctype,frm.docname, "invoiced", 0);
+	}
 });
 
 frappe.ui.form.on("Patient Encounter", "practitioner", function(frm) {
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
index d11d1a7..6f00e5b 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
@@ -220,9 +220,43 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "default": "", 
+   "fetch_from": "patient.patient_name", 
+   "fieldname": "patient_name", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Patient Name", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "patient_age", 
    "fieldtype": "Data", 
-   "hidden": 1, 
+   "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
@@ -235,9 +269,9 @@
    "options": "", 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 1, 
+   "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 1, 
    "reqd": 0, 
@@ -255,7 +289,7 @@
    "columns": 0, 
    "fieldname": "patient_sex", 
    "fieldtype": "Select", 
-   "hidden": 1, 
+   "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
@@ -268,9 +302,9 @@
    "options": "\nMale\nFemale\nOther", 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 1, 
+   "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 1, 
    "reqd": 0, 
@@ -286,39 +320,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "practitioner", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 1, 
-   "label": "Healthcare Practitioner", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Healthcare Practitioner", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "fieldname": "company", 
    "fieldtype": "Link", 
    "hidden": 1, 
@@ -383,6 +384,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "practitioner", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 1, 
+   "label": "Healthcare Practitioner", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Healthcare Practitioner", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "visit_department", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -482,8 +516,9 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "invoice", 
-   "fieldtype": "Link", 
+   "default": "0", 
+   "fieldname": "invoiced", 
+   "fieldtype": "Check", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -491,10 +526,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Invoice", 
+   "label": "Invoiced", 
    "length": 0, 
    "no_copy": 1, 
-   "options": "Sales Invoice", 
+   "options": "", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -1145,4 +1180,4 @@
  "track_changes": 1, 
  "track_seen": 1, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
index 3d8f952..4c62e57 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
@@ -5,9 +5,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe.model.document import Document
-from frappe.utils import getdate, cstr
-import json
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account, get_income_account
+from frappe.utils import cstr
 
 class PatientEncounter(Document):
 	def on_update(self):
@@ -23,77 +21,6 @@
 			frappe.db.set_value("Patient Appointment", self.appointment, "status", "Open")
 		delete_medical_record(self)
 
-def set_sales_invoice_fields(company, patient):
-	sales_invoice = frappe.new_doc("Sales Invoice")
-	sales_invoice.customer = frappe.get_value("Patient", patient, "customer")
-	# patient is custom field in sales inv.
-	sales_invoice.due_date = getdate()
-	sales_invoice.is_pos = '0'
-	sales_invoice.debit_to = get_receivable_account(company)
-
-	return sales_invoice
-
-def create_sales_invoice_item_lines(item, sales_invoice):
-	sales_invoice_line = sales_invoice.append("items")
-	sales_invoice_line.item_code = item.item_code
-	sales_invoice_line.item_name =  item.item_name
-	sales_invoice_line.qty = 1.0
-	sales_invoice_line.description = item.description
-	return sales_invoice_line
-
-@frappe.whitelist()
-def create_drug_invoice(company, patient, prescriptions):
-	list_ids = json.loads(prescriptions)
-	if not (company or patient or prescriptions):
-		return False
-
-	sales_invoice = set_sales_invoice_fields(company, patient)
-	sales_invoice.update_stock = 1
-
-	for line_id in list_ids:
-		line_obj = frappe.get_doc("Drug Prescription", line_id)
-		if line_obj:
-			if(line_obj.drug_code):
-				item = frappe.get_doc("Item", line_obj.drug_code)
-				sales_invoice_line = create_sales_invoice_item_lines(item, sales_invoice)
-				sales_invoice_line.qty = line_obj.get_quantity()
-	#income_account and cost_center in itemlines - by set_missing_values()
-	sales_invoice.set_missing_values()
-	return sales_invoice.as_dict()
-
-@frappe.whitelist()
-def create_invoice(company, patient, practitioner, encounter_id):
-	if not encounter_id:
-		return False
-	sales_invoice = frappe.new_doc("Sales Invoice")
-	sales_invoice.customer = frappe.get_value("Patient", patient, "customer")
-	sales_invoice.due_date = getdate()
-	sales_invoice.is_pos = '0'
-	sales_invoice.debit_to = get_receivable_account(company)
-
-	create_invoice_items(practitioner, sales_invoice, company)
-
-	sales_invoice.save(ignore_permissions=True)
-	frappe.db.sql("""update `tabPatient Encounter` set invoice=%s where name=%s""", (sales_invoice.name, encounter_id))
-	appointment = frappe.db.get_value("Patient Encounter", encounter_id, "appointment")
-	if appointment:
-		frappe.db.set_value("Patient Appointment", appointment, "sales_invoice", sales_invoice.name)
-	return sales_invoice.name
-
-def create_invoice_items(practitioner, invoice, company):
-	item_line = invoice.append("items")
-	item_line.item_name = "Consulting Charges"
-	item_line.description = "Consulting Charges:  " + practitioner
-	item_line.qty = 1
-	item_line.uom = "Nos"
-	item_line.conversion_factor = 1
-	item_line.income_account = get_income_account(practitioner, company)
-	op_consulting_charge = frappe.get_value("Healthcare Practitioner", practitioner, "op_consulting_charge")
-	if op_consulting_charge:
-		item_line.rate = op_consulting_charge
-		item_line.amount = op_consulting_charge
-	return invoice
-
 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/patient_medical_record/patient_medical_record.json b/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json
index 8c35ccd..c6a6b44 100644
--- a/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json
+++ b/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json
@@ -331,7 +331,7 @@
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
-   "search_index": 0, 
+   "search_index": 1, 
    "set_only_once": 0, 
    "translatable": 0, 
    "unique": 0
@@ -454,4 +454,4 @@
  "track_changes": 1, 
  "track_seen": 1, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json b/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
index b4c4532..d67da97 100644
--- a/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
+++ b/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
@@ -236,7 +236,72 @@
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
-   "search_index": 0, 
+   "search_index": 1, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "procedure_created", 
+   "fieldtype": "Check", 
+   "hidden": 1, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Procedure Created", 
+   "length": 0, 
+   "no_copy": 1, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 1, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "0", 
+   "fieldname": "invoiced", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Invoiced", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 1, 
    "set_only_once": 0, 
    "translatable": 0, 
    "unique": 0
@@ -252,7 +317,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-07-16 13:08:15.499491", 
+ "modified": "2018-08-06 16:53:36.440428", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Procedure Prescription", 
@@ -266,5 +331,6 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/sample_collection/sample_collection.json b/erpnext/healthcare/doctype/sample_collection/sample_collection.json
index 7655685..783fc3d 100644
--- a/erpnext/healthcare/doctype/sample_collection/sample_collection.json
+++ b/erpnext/healthcare/doctype/sample_collection/sample_collection.json
@@ -88,8 +88,8 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "invoice", 
-   "fieldtype": "Link", 
+   "fieldname": "invoiced", 
+   "fieldtype": "Check", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -97,10 +97,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Invoice", 
+   "label": "Invoiced", 
    "length": 0, 
-   "no_copy": 0, 
-   "options": "Sales Invoice", 
+   "no_copy": 1, 
+   "options": "", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -684,4 +684,4 @@
  "track_changes": 1, 
  "track_seen": 1, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/page/appointment_analytic/appointment_analytic.json b/erpnext/healthcare/page/appointment_analytic/appointment_analytic.json
index 4deff80..ac5ca1a 100644
--- a/erpnext/healthcare/page/appointment_analytic/appointment_analytic.json
+++ b/erpnext/healthcare/page/appointment_analytic/appointment_analytic.json
@@ -1,22 +1,24 @@
 {
- "content": null,
- "creation": "2016-08-18 12:29:52.497819",
- "docstatus": 0,
- "doctype": "Page",
- "idx": 0,
- "modified": "2016-08-18 12:29:52.497819",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "appointment-analytic",
- "owner": "Administrator",
- "page_name": "Appointment Analytics",
+ "content": null, 
+ "creation": "2016-08-18 12:29:52.497819", 
+ "docstatus": 0, 
+ "doctype": "Page", 
+ "idx": 0, 
+ "modified": "2018-08-06 11:40:53.082863", 
+ "modified_by": "Administrator", 
+ "module": "Healthcare", 
+ "name": "appointment-analytic", 
+ "owner": "Administrator", 
+ "page_name": "Appointment Analytics", 
+ "restrict_to_domain": "Healthcare", 
  "roles": [
   {
    "role": "Physician"
   }
- ],
- "script": null,
- "standard": "Yes",
- "style": null,
+ ], 
+ "script": null, 
+ "standard": "Yes", 
+ "style": null, 
+ "system_page": 0, 
  "title": "Appointment Analytics"
-}
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/page/medical_record/medical_record.json b/erpnext/healthcare/page/medical_record/medical_record.json
index 7c786ca..ca30c3b 100644
--- a/erpnext/healthcare/page/medical_record/medical_record.json
+++ b/erpnext/healthcare/page/medical_record/medical_record.json
@@ -1,23 +1,25 @@
 {
- "content": null,
- "creation": "2016-06-09 11:33:14.025787",
- "docstatus": 0,
- "doctype": "Page",
- "icon": "icon-play",
- "idx": 0,
- "modified": "2017-03-06 11:20:40.174661",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "medical_record",
- "owner": "Administrator",
- "page_name": "medical_record",
+ "content": null, 
+ "creation": "2016-06-09 11:33:14.025787", 
+ "docstatus": 0, 
+ "doctype": "Page", 
+ "icon": "icon-play", 
+ "idx": 0, 
+ "modified": "2018-08-06 11:40:39.705660", 
+ "modified_by": "Administrator", 
+ "module": "Healthcare", 
+ "name": "medical_record", 
+ "owner": "Administrator", 
+ "page_name": "medical_record", 
+ "restrict_to_domain": "Healthcare", 
  "roles": [
   {
    "role": "Physician"
   }
- ],
- "script": null,
- "standard": "Yes",
- "style": null,
+ ], 
+ "script": null, 
+ "standard": "Yes", 
+ "style": null, 
+ "system_page": 0, 
  "title": "Medical Record"
-}
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json b/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json
index 2f85ff6..d3ad440 100644
--- a/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json
+++ b/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json
@@ -7,10 +7,10 @@
  "docstatus": 0, 
  "doctype": "Print Format", 
  "font": "Default", 
- "html": "<div >\n  {% if letter_head and not no_letterhead -%}\n    <div class=\"letter-head\">{{ letter_head }}</div>\n    <hr>\n  {%- endif %}\n\n  {% if (doc.docstatus != 1) %}\n  <b>Lab Tests have to be Submitted for Print .. !</b>\n  {% elif (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"require_test_result_approval\") == '1' and doc.approval_status != \"Approved\") %}\n  <b>Lab Tests have to be Approved for Print .. !</b>\n  {%- else -%}\n  <div class=\"row section-break\">\n    <div class=\"col-xs-6 column-break\">\n      {% if doc.invoice %}\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Order No.</label>\n        </div>\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong>{{doc.invoice}}\n        </div>\n      </div>\n      {%- endif -%}\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Patient</label>\n        </div>\n        {% if doc.patient %}\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong>{{doc.patient}}\n        </div>\n        {% else %}\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong><em>Patient Name</em>\n        </div>\n        {%- endif -%}\n      </div>\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Age</label>\n        </div>\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong> {{doc.patient_age}}\n        </div>\n      </div>\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Gender</label>\n        </div>\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong> {{doc.patient_sex}}\n        </div>\n      </div>\n\n    </div>\n\n    <div class=\"col-xs-6 column-break\">\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Healthcare Practitioner</label>\n        </div>\n        {% if doc.practitioner %}\n        <div class=\"col-xs-7  text-left value\">\n          <strong>: </strong>{{doc.practitioner}}\n        </div>\n        {%- endif -%}\n      </div>\n\n      {% if doc.sample_date %}\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Sample Date</label>\n        </div>\n        <div class=\"col-xs-7 text-left value\">\n          <strong>: </strong>{{doc.sample_date}}\n        </div>\n      </div>\n      {%- endif -%}\n\n      {% if doc.result_date %}\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Result Date</label>\n        </div>\n        <div class=\"col-xs-7 text-left value\">\n          <strong>: </strong>{{doc.result_date}}\n        </div>\n      </div>\n      {%- endif -%}\n\n    </div>\n\n  </div>\n\n  <div align=\"center\">\n    <hr><h4 class=\"text-uppercase\"><b><u>Department of {{doc.department}}</u></b></h4>\n  </div>\n\n  <table class=\"table\">\n    <tbody>\n      {%- if doc.normal_test_items -%}\n      <tr>\n        <th>Name of Test</th>\n        <th class=\"text-left\">Result</th>\n        <th class=\"text-right\">Normal Range</th>\n      </tr>\n\n      {%- if doc.normal_test_items|length > 1 %}\n      <tr><td style=\"width: 40%;\"> <b>{{ doc.test_name }}</b> </td><td></td></tr>\n      {%- endif -%}\n\n      {%- for row in doc.normal_test_items -%}\n      <tr>\n        <td style=\"width: 40%;border:none;\">\n          {%- if doc.normal_test_items|length > 1 %}&emsp;&emsp;{%- endif -%}\n          {%- if row.test_name -%}<b>{{ row.test_name }}</b>\n          {%- else -%}&emsp;&emsp;&emsp;{%- endif -%}\n          {%- if row.test_event -%} &emsp;&emsp;{{ row.test_event }}{%- endif -%}\n        </td>\n\n        <td style=\"width: 20%;text-align: left;border:none;\">\n          {%- if row.result_value -%}{{ row.result_value }}{%- endif -%}&emsp;\n          {%- if row.test_uom -%}{{ row.test_uom }}{%- endif -%}\n        </td>\n\n        <td style=\"width: 30%;text-align: right;border:none;\">\n          <div style=\"border: 0px;\">\n            {%- if row.normal_range -%}{{ row.normal_range }}{%- endif -%}\n          </div>\n        </td>\n      </tr>\n\n      {%- endfor -%}\n      {%- endif -%}\n    </tbody>\n  </table>\n\n  <table class=\"table\">\n    <tbody>\n      {%- if doc.special_test_items -%}\n      <tr>\n        <th>Name of Test</th>\n        <th class=\"text-left\">Result</th>\n      </tr>\n      <tr><td style=\"width: 30%;border:none;\"> <b>{{ doc.test_name }}</b> </td><td></td></tr>\n      {%- for row in doc.special_test_items -%}\n      <tr>\n        <td style=\"width: 30%;border:none;\"> &emsp;&emsp;{{ row.test_particulars }} </td>\n        <td style=\"width: 70%;text-align: left;border:none;\">\n          {%- if row.result_value -%}{{ row.result_value }}{%- endif -%}\n        </td>\n      </tr>\n\n      {%- endfor -%}\n      {%- endif -%}\n\n      {%- if doc.sensitivity_test_items -%}\n      <tr>\n        <th>Antibiotic</th>\n        <th class=\"text-left\">Sensitivity</th>\n      </tr>\n      {%- for row in doc.sensitivity_test_items -%}\n      <tr>\n        <td style=\"width: 30%;border:none;\"> {{ row.antibiotic }} </td>\n        <td style=\"width: 70%;text-align: left;border:none;\">{{ row.antibiotic_sensitivity }}</td>\n      </tr>\n\n      {%- endfor -%}\n      {%- endif -%}\n\n    </tbody>\n  </table>\n  {%- endif -%}\n\n  <div align=\"right\">\n    {%- if (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"employee_name_and_designation_in_print\") == '1') -%}\n    <h6 class=\"text-uppercase\"><b>{{doc.employee_name}}</b></h6>\n    <h6 class=\"text-uppercase\"><b>{{doc.employee_designation}}</b></h6>\n    {%- else -%}\n    <h6 ><b>{{frappe.db.get_value(\"Healthcare Settings\", \"None\", \"custom_signature_in_print\") }}</b></h6>\n    {%- endif -%}\n  </div>\n</div>\n", 
+ "html": "<div >\n  {% if letter_head and not no_letterhead -%}\n    <div class=\"letter-head\">{{ letter_head }}</div>\n    <hr>\n  {%- endif %}\n\n  {% if (doc.docstatus != 1) %}\n  <b>Lab Tests have to be Submitted for Print .. !</b>\n  {% elif (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"require_test_result_approval\") == '1' and doc.approval_status != \"Approved\") %}\n  <b>Lab Tests have to be Approved for Print .. !</b>\n  {%- else -%}\n  <div class=\"row section-break\">\n    <div class=\"col-xs-6 column-break\">\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Patient</label>\n        </div>\n        {% if doc.patient %}\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong>{{doc.patient}}\n        </div>\n        {% else %}\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong><em>Patient Name</em>\n        </div>\n        {%- endif -%}\n      </div>\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Age</label>\n        </div>\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong> {{doc.patient_age}}\n        </div>\n      </div>\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Gender</label>\n        </div>\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong> {{doc.patient_sex}}\n        </div>\n      </div>\n\n    </div>\n\n    <div class=\"col-xs-6 column-break\">\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Practitioner</label>\n        </div>\n        {% if doc.practitioner %}\n        <div class=\"col-xs-7  text-left value\">\n          <strong>: </strong>{{doc.practitioner}}\n        </div>\n        {%- endif -%}\n      </div>\n\n      {% if doc.sample_date %}\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Sample Date</label>\n        </div>\n        <div class=\"col-xs-7 text-left value\">\n          <strong>: </strong>{{doc.sample_date}}\n        </div>\n      </div>\n      {%- endif -%}\n\n      {% if doc.result_date %}\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Result Date</label>\n        </div>\n        <div class=\"col-xs-7 text-left value\">\n          <strong>: </strong>{{doc.result_date}}\n        </div>\n      </div>\n      {%- endif -%}\n\n    </div>\n\n  </div>\n\n  <div align=\"center\">\n    <hr><h4 class=\"text-uppercase\"><b><u>Department of {{doc.department}}</u></b></h4>\n  </div>\n\n  <table class=\"table\">\n    <tbody>\n      {%- if doc.normal_test_items -%}\n      <tr>\n        <th>Name of Test</th>\n        <th class=\"text-left\">Result</th>\n        <th class=\"text-right\">Normal Range</th>\n      </tr>\n\n      {%- if doc.normal_test_items|length > 1 %}\n      <tr><td style=\"width: 40%;\"> <b>{{ doc.test_name }}</b> </td><td></td></tr>\n      {%- endif -%}\n\n      {%- for row in doc.normal_test_items -%}\n      <tr>\n        <td style=\"width: 40%;border:none;\">\n          {%- if doc.normal_test_items|length > 1 %}&emsp;&emsp;{%- endif -%}\n          {%- if row.test_name -%}<b>{{ row.test_name }}</b>\n          {%- else -%}&emsp;&emsp;&emsp;{%- endif -%}\n          {%- if row.test_event -%} &emsp;&emsp;{{ row.test_event }}{%- endif -%}\n        </td>\n\n        <td style=\"width: 20%;text-align: left;border:none;\">\n          {%- if row.result_value -%}{{ row.result_value }}{%- endif -%}&emsp;\n          {%- if row.test_uom -%}{{ row.test_uom }}{%- endif -%}\n        </td>\n\n        <td style=\"width: 30%;text-align: right;border:none;\">\n          <div style=\"border: 0px;\">\n            {%- if row.normal_range -%}{{ row.normal_range }}{%- endif -%}\n          </div>\n        </td>\n      </tr>\n\n      {%- endfor -%}\n      {%- endif -%}\n    </tbody>\n  </table>\n\n  <table class=\"table\">\n    <tbody>\n      {%- if doc.special_test_items -%}\n      <tr>\n        <th>Name of Test</th>\n        <th class=\"text-left\">Result</th>\n      </tr>\n      <tr><td style=\"width: 30%;border:none;\"> <b>{{ doc.test_name }}</b> </td><td></td></tr>\n      {%- for row in doc.special_test_items -%}\n      <tr>\n        <td style=\"width: 30%;border:none;\"> &emsp;&emsp;{{ row.test_particulars }} </td>\n        <td style=\"width: 70%;text-align: left;border:none;\">\n          {%- if row.result_value -%}{{ row.result_value }}{%- endif -%}\n        </td>\n      </tr>\n\n      {%- endfor -%}\n      {%- endif -%}\n\n      {%- if doc.sensitivity_test_items -%}\n      <tr>\n        <th>Antibiotic</th>\n        <th class=\"text-left\">Sensitivity</th>\n      </tr>\n      {%- for row in doc.sensitivity_test_items -%}\n      <tr>\n        <td style=\"width: 30%;border:none;\"> {{ row.antibiotic }} </td>\n        <td style=\"width: 70%;text-align: left;border:none;\">{{ row.antibiotic_sensitivity }}</td>\n      </tr>\n\n      {%- endfor -%}\n      {%- endif -%}\n\n    </tbody>\n  </table>\n  {%- endif -%}\n\n  <div align=\"right\">\n    {%- if (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"employee_name_and_designation_in_print\") == '1') -%}\n    <h6 class=\"text-uppercase\"><b>{{doc.employee_name}}</b></h6>\n    <h6 class=\"text-uppercase\"><b>{{doc.employee_designation}}</b></h6>\n    {%- else -%}\n    <h6 ><b>{{frappe.db.get_value(\"Healthcare Settings\", \"None\", \"custom_signature_in_print\") }}</b></h6>\n    {%- endif -%}\n  </div>\n</div>\n", 
  "idx": 0, 
  "line_breaks": 0, 
- "modified": "2018-07-10 11:29:24.167265", 
+ "modified": "2018-07-13 12:51:25.750441", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Lab Test Print", 
@@ -19,4 +19,4 @@
  "print_format_type": "Server", 
  "show_section_headings": 0, 
  "standard": "Yes"
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/report/lab_test_report/lab_test_report.json b/erpnext/healthcare/report/lab_test_report/lab_test_report.json
index f133a8e..30e5a5f 100644
--- a/erpnext/healthcare/report/lab_test_report/lab_test_report.json
+++ b/erpnext/healthcare/report/lab_test_report/lab_test_report.json
@@ -1,17 +1,17 @@
 {
  "add_total_row": 1, 
- "apply_user_permissions": 1, 
  "creation": "2013-04-23 18:15:29", 
  "disabled": 0, 
  "docstatus": 0, 
  "doctype": "Report", 
  "idx": 1, 
  "is_standard": "Yes", 
- "modified": "2017-08-23 14:54:12.593140", 
+ "modified": "2018-08-06 11:41:50.218737", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Lab Test Report", 
  "owner": "Administrator", 
+ "prepared_report": 0, 
  "ref_doctype": "Lab Test", 
  "report_name": "Lab Test Report", 
  "report_type": "Script Report", 
@@ -20,7 +20,13 @@
    "role": "Laboratory User"
   }, 
   {
-   "role": "System Manager"
+   "role": "Nursing User"
+  }, 
+  {
+   "role": "LabTest Approver"
+  }, 
+  {
+   "role": "Healthcare Administrator"
   }
  ]
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/report/lab_test_report/lab_test_report.py b/erpnext/healthcare/report/lab_test_report/lab_test_report.py
index e4771c5..b9a26df 100644
--- a/erpnext/healthcare/report/lab_test_report/lab_test_report.py
+++ b/erpnext/healthcare/report/lab_test_report/lab_test_report.py
@@ -17,7 +17,7 @@
 
 	data = []
 	for lab_test in lab_test_list:
-		row = [ lab_test.test_name, lab_test.patient, lab_test.practitioner, lab_test.invoice, lab_test.status, lab_test.result_date, lab_test.department]
+		row = [ lab_test.test_name, lab_test.patient, lab_test.practitioner, lab_test.invoiced, lab_test.status, lab_test.result_date, lab_test.department]
 		data.append(row)
 
 	return columns, data
@@ -28,7 +28,7 @@
 		_("Test") + ":Data:120",
 		_("Patient") + ":Link/Patient:180",
 		_("Healthcare Practitioner") + ":Link/Healthcare Practitioner:120",
-		_("Invoice") + ":Link/Sales Invoice:120",
+		_("Invoiced") + ":Check:100",
 		_("Status") + ":Data:120",
 		_("Result Date") + ":Date:120",
 		_("Department") + ":Data:120",
@@ -52,7 +52,7 @@
 
 def get_lab_test(filters):
 	conditions = get_conditions(filters)
-	return frappe.db.sql("""select name, patient, test_name, patient_name, status, result_date, practitioner, invoice, department
+	return frappe.db.sql("""select name, patient, test_name, patient_name, status, result_date, practitioner, invoiced, department
 		from `tabLab Test`
 		where docstatus<2 %s order by submitted_date desc, name desc""" %
 		conditions, filters, as_dict=1)
diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py
new file mode 100644
index 0000000..1045d49
--- /dev/null
+++ b/erpnext/healthcare/utils.py
@@ -0,0 +1,426 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, earthians and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+import datetime
+from frappe import _
+import math
+from frappe.utils import time_diff_in_hours, rounded, getdate, add_days
+from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_income_account
+from erpnext.healthcare.doctype.fee_validity.fee_validity import create_fee_validity, update_fee_validity
+from erpnext.healthcare.doctype.lab_test.lab_test import create_multiple
+
+@frappe.whitelist()
+def get_healthcare_services_to_invoice(patient):
+	patient = frappe.get_doc("Patient", patient)
+	if patient:
+		if patient.customer:
+			item_to_invoice = []
+			patient_appointments = frappe.get_list("Patient Appointment",{'patient': patient.name, 'invoiced': False},
+			order_by="appointment_date")
+			if patient_appointments:
+				fee_validity_details = []
+				valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
+				max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
+				for patient_appointment in patient_appointments:
+					patient_appointment_obj = frappe.get_doc("Patient Appointment", patient_appointment['name'])
+
+					if patient_appointment_obj.procedure_template:
+						if frappe.db.get_value("Clinical Procedure Template", patient_appointment_obj.procedure_template, "is_billable") == 1:
+							item_to_invoice.append({'reference_type': 'Patient Appointment', 'reference_name': patient_appointment_obj.name, 'service': patient_appointment_obj.procedure_template})
+					else:
+						practitioner_exist_in_list = False
+						skip_invoice = False
+						if fee_validity_details:
+							for validity in fee_validity_details:
+								if validity['practitioner'] == patient_appointment_obj.practitioner:
+									practitioner_exist_in_list = True
+									if validity['valid_till'] >= patient_appointment_obj.appointment_date:
+										validity['visits'] = validity['visits']+1
+										if int(max_visit) > validity['visits']:
+											skip_invoice = True
+									if not skip_invoice:
+										validity['visits'] = 1
+										validity['valid_till'] = patient_appointment_obj.appointment_date + datetime.timedelta(days=int(valid_days))
+						if not practitioner_exist_in_list:
+							valid_till = patient_appointment_obj.appointment_date + datetime.timedelta(days=int(valid_days))
+							visits = 0
+							validity_exist = validity_exists(patient_appointment_obj.practitioner, patient_appointment_obj.patient)
+							if validity_exist:
+								fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
+								valid_till = fee_validity.valid_till
+								visits = fee_validity.visited
+							fee_validity_details.append({'practitioner': patient_appointment_obj.practitioner,
+							'valid_till': valid_till, 'visits': visits})
+
+						if not skip_invoice:
+							practitioner_charge = 0
+							income_account = None
+							service_item = None
+							if patient_appointment_obj.practitioner:
+								service_item, practitioner_charge = service_item_and_practitioner_charge(patient_appointment_obj)
+								income_account = get_income_account(patient_appointment_obj.practitioner, patient_appointment_obj.company)
+							item_to_invoice.append({'reference_type': 'Patient Appointment', 'reference_name': patient_appointment_obj.name,
+							'service': service_item, 'rate': practitioner_charge,
+							'income_account': income_account})
+
+			encounters = frappe.get_list("Patient Encounter", {'patient': patient.name, 'invoiced': False, 'docstatus': 1})
+			if encounters:
+				for encounter in encounters:
+					encounter_obj = frappe.get_doc("Patient Encounter", encounter['name'])
+					if not encounter_obj.appointment:
+						practitioner_charge = 0
+						income_account = None
+						service_item = None
+						if encounter_obj.practitioner:
+							service_item, practitioner_charge = service_item_and_practitioner_charge(encounter_obj)
+							income_account = get_income_account(encounter_obj.practitioner, encounter_obj.company)
+
+						item_to_invoice.append({'reference_type': 'Patient Encounter', 'reference_name': encounter_obj.name,
+						'service': service_item, 'rate': practitioner_charge,
+						'income_account': income_account})
+
+			lab_tests = frappe.get_list("Lab Test", {'patient': patient.name, 'invoiced': False})
+			if lab_tests:
+				for lab_test in lab_tests:
+					lab_test_obj = frappe.get_doc("Lab Test", lab_test['name'])
+					if frappe.db.get_value("Lab Test Template", lab_test_obj.template, "is_billable") == 1:
+						item_to_invoice.append({'reference_type': 'Lab Test', 'reference_name': lab_test_obj.name,
+						'service': frappe.db.get_value("Lab Test Template", lab_test_obj.template, "item")})
+
+			lab_rxs = frappe.db.sql("""select lp.name from `tabPatient Encounter` et, `tabLab Prescription` lp
+			where et.patient=%s and lp.parent=et.name and lp.test_created=0 and lp.invoiced=0""", (patient.name))
+			if lab_rxs:
+				for lab_rx in lab_rxs:
+					rx_obj = frappe.get_doc("Lab Prescription", lab_rx[0])
+					if rx_obj.test_code and (frappe.db.get_value("Lab Test Template", rx_obj.test_code, "is_billable") == 1):
+						item_to_invoice.append({'reference_type': 'Lab Prescription', 'reference_name': rx_obj.name,
+						'service': frappe.db.get_value("Lab Test Template", rx_obj.test_code, "item")})
+
+			procedures = frappe.get_list("Clinical Procedure", {'patient': patient.name, 'invoiced': False})
+			if procedures:
+				for procedure in procedures:
+					procedure_obj = frappe.get_doc("Clinical Procedure", procedure['name'])
+					if not procedure_obj.appointment:
+						if procedure_obj.procedure_template and (frappe.db.get_value("Clinical Procedure Template", procedure_obj.procedure_template, "is_billable") == 1):
+							item_to_invoice.append({'reference_type': 'Clinical Procedure', 'reference_name': procedure_obj.name,
+							'service': frappe.db.get_value("Clinical Procedure Template", procedure_obj.procedure_template, "item")})
+
+			procedure_rxs = frappe.db.sql("""select pp.name from `tabPatient Encounter` et,
+			`tabProcedure Prescription` pp where et.patient=%s and pp.parent=et.name and
+			pp.procedure_created=0 and pp.invoiced=0 and pp.appointment_booked=0""", (patient.name))
+			if procedure_rxs:
+				for procedure_rx in procedure_rxs:
+					rx_obj = frappe.get_doc("Procedure Prescription", procedure_rx[0])
+					if frappe.db.get_value("Clinical Procedure Template", rx_obj.procedure, "is_billable") == 1:
+						item_to_invoice.append({'reference_type': 'Procedure Prescription', 'reference_name': rx_obj.name,
+						'service': frappe.db.get_value("Clinical Procedure Template", rx_obj.procedure, "item")})
+
+			procedures = frappe.get_list("Clinical Procedure",
+			{'patient': patient.name, 'invoice_separately_as_consumables': True, 'consumption_invoiced': False,
+			'consume_stock': True, 'status': 'Completed'})
+			if procedures:
+				service_item = get_healthcare_service_item('clinical_procedure_consumable_item')
+				if not service_item:
+					msg = _(("Please Configure {0} in ").format("Clinical Procedure Consumable Item") \
+						+ """<b><a href="#Form/Healthcare Settings">Healthcare Settings</a></b>""")
+					frappe.throw(msg)
+				for procedure in procedures:
+					procedure_obj = frappe.get_doc("Clinical Procedure", procedure['name'])
+					item_to_invoice.append({'reference_type': 'Clinical Procedure', 'reference_name': procedure_obj.name,
+					'service': service_item, 'rate': procedure_obj.consumable_total_amount, 'description': procedure_obj.consumption_details})
+
+			inpatient_services = frappe.db.sql("""select io.name, io.parent from `tabInpatient Record` ip,
+			`tabInpatient Occupancy` io where ip.patient=%s and io.parent=ip.name and
+			io.left=1 and io.invoiced=0""", (patient.name))
+			if inpatient_services:
+				for inpatient_service in inpatient_services:
+					inpatient_occupancy = frappe.get_doc("Inpatient Occupancy", inpatient_service[0])
+					service_unit_type = frappe.get_doc("Healthcare Service Unit Type", frappe.db.get_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "service_unit_type"))
+					if service_unit_type and service_unit_type.is_billable == 1:
+						hours_occupied = time_diff_in_hours(inpatient_occupancy.check_out, inpatient_occupancy.check_in)
+						qty = 0.5
+						if hours_occupied > 0:
+							actual_qty = hours_occupied / service_unit_type.no_of_hours
+							floor = math.floor(actual_qty)
+							decimal_part = actual_qty - floor
+							if decimal_part > 0.5:
+								qty = rounded(floor + 1, 1)
+							elif decimal_part < 0.5 and decimal_part > 0:
+								qty = rounded(floor + 0.5, 1)
+							if qty <= 0:
+								qty = 0.5
+						item_to_invoice.append({'reference_type': 'Inpatient Occupancy', 'reference_name': inpatient_occupancy.name,
+						'service': service_unit_type.item, 'qty': qty})
+
+			return item_to_invoice
+		else:
+			frappe.throw(_("The Patient {0} do not have customer refrence to invoice").format(patient.name))
+
+def service_item_and_practitioner_charge(doc):
+	is_ip = doc_is_ip(doc)
+	if is_ip:
+		service_item = get_practitioner_service_item(doc.practitioner, "inpatient_visit_charge_item")
+		if not service_item:
+			service_item = get_healthcare_service_item("inpatient_visit_charge_item")
+	else:
+		service_item = get_practitioner_service_item(doc.practitioner, "op_consulting_charge_item")
+		if not service_item:
+			service_item = get_healthcare_service_item("op_consulting_charge_item")
+	if not service_item:
+		throw_config_service_item(is_ip)
+
+	practitioner_charge = get_practitioner_charge(doc.practitioner, is_ip)
+	if not practitioner_charge:
+		throw_config_practitioner_charge(is_ip, doc.practitioner)
+
+	return service_item, practitioner_charge
+
+def throw_config_service_item(is_ip):
+	service_item_lable = "Out Patient Consulting Charge Item"
+	if is_ip:
+		service_item_lable = "Inpatient Visit Charge Item"
+
+	msg = _(("Please Configure {0} in ").format(service_item_lable) \
+		+ """<b><a href="#Form/Healthcare Settings">Healthcare Settings</a></b>""")
+	frappe.throw(msg)
+
+def throw_config_practitioner_charge(is_ip, practitioner):
+	charge_name = "OP Consulting Charge"
+	if is_ip:
+		charge_name = "Inpatient Visit Charge"
+
+	msg = _(("Please Configure {0} for Healthcare Practitioner").format(charge_name) \
+		+ """ <b><a href="#Form/Healthcare Practitioner/{0}">{0}</a></b>""".format(practitioner))
+	frappe.throw(msg)
+
+def get_practitioner_service_item(practitioner, service_item_field):
+	return frappe.db.get_value("Healthcare Practitioner", practitioner, service_item_field)
+
+def get_healthcare_service_item(service_item_field):
+	return frappe.db.get_value("Healthcare Settings", None, service_item_field)
+
+def doc_is_ip(doc):
+	is_ip = False
+	if doc.inpatient_record:
+		is_ip = True
+	return is_ip
+
+def get_practitioner_charge(practitioner, is_ip):
+	if is_ip:
+		practitioner_charge = frappe.db.get_value("Healthcare Practitioner", practitioner, "inpatient_visit_charge")
+	else:
+		practitioner_charge = frappe.db.get_value("Healthcare Practitioner", practitioner, "op_consulting_charge")
+	if practitioner_charge:
+		return practitioner_charge
+	return False
+
+def manage_invoice_submit_cancel(doc, method):
+	if doc.items:
+		for item in doc.items:
+			if item.reference_dt and item.reference_dn:
+				if frappe.get_meta(item.reference_dt).has_field("invoiced"):
+					set_invoiced(item, method, doc.name)
+
+	if method=="on_submit" and frappe.db.get_value("Healthcare Settings", None, "create_test_on_si_submit") == '1':
+		create_multiple("Sales Invoice", doc.name)
+
+def set_invoiced(item, method, ref_invoice=None):
+	invoiced = False
+	if(method=="on_submit"):
+		validate_invoiced_on_submit(item)
+		invoiced = True
+
+	if item.reference_dt == 'Clinical Procedure':
+		if get_healthcare_service_item('clinical_procedure_consumable_item') == item.item_code:
+			frappe.db.set_value(item.reference_dt, item.reference_dn, "consumption_invoiced", invoiced)
+		else:
+			frappe.db.set_value(item.reference_dt, item.reference_dn, "invoiced", invoiced)
+	else:
+		frappe.db.set_value(item.reference_dt, item.reference_dn, "invoiced", invoiced)
+
+	if item.reference_dt == 'Patient Appointment':
+		if frappe.db.get_value('Patient Appointment', item.reference_dn, 'procedure_template'):
+			dt_from_appointment = "Clinical Procedure"
+		else:
+			manage_fee_validity(item.reference_dn, method, ref_invoice)
+			dt_from_appointment = "Patient Encounter"
+		manage_doc_for_appoitnment(dt_from_appointment, item.reference_dn, invoiced)
+
+	elif item.reference_dt == 'Lab Prescription':
+		manage_prescriptions(invoiced, item.reference_dt, item.reference_dn, "Lab Test", "test_created")
+
+	elif item.reference_dt == 'Procedure Prescription':
+		manage_prescriptions(invoiced, item.reference_dt, item.reference_dn, "Clinical Procedure", "procedure_created")
+
+def validate_invoiced_on_submit(item):
+	if item.reference_dt == 'Clinical Procedure' and get_healthcare_service_item('clinical_procedure_consumable_item') == item.item_code:
+			is_invoiced = frappe.db.get_value(item.reference_dt, item.reference_dn, "consumption_invoiced")
+	else:
+		is_invoiced = frappe.db.get_value(item.reference_dt, item.reference_dn, "invoiced")
+	if is_invoiced == 1:
+		frappe.throw(_("The item referenced by {0} - {1} is already invoiced"\
+		).format(item.reference_dt, item.reference_dn))
+
+def manage_prescriptions(invoiced, ref_dt, ref_dn, dt, created_check_field):
+	created = frappe.db.get_value(ref_dt, ref_dn, created_check_field)
+	if created == 1:
+		# Fetch the doc created for the prescription
+		doc_created = frappe.db.get_value(dt, {'prescription': ref_dn})
+		frappe.db.set_value(dt, doc_created, 'invoiced', invoiced)
+
+def validity_exists(practitioner, patient):
+	return frappe.db.exists({
+			"doctype": "Fee Validity",
+			"practitioner": practitioner,
+			"patient": patient})
+
+def manage_fee_validity(appointment_name, method, ref_invoice=None):
+	appointment_doc = frappe.get_doc("Patient Appointment", appointment_name)
+	validity_exist = validity_exists(appointment_doc.practitioner, appointment_doc.patient)
+	do_not_update = False
+	visited = 0
+	if validity_exist:
+		fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
+		# Check if the validity is valid
+		if (fee_validity.valid_till >= appointment_doc.appointment_date):
+			if (method == "on_cancel" and appointment_doc.status != "Closed"):
+				if ref_invoice == fee_validity.ref_invoice:
+					visited = fee_validity.visited - 1
+					if visited < 0:
+						visited = 0
+					frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
+				do_not_update = True
+			elif (method == "on_submit" and fee_validity.visited < fee_validity.max_visit):
+				visited = fee_validity.visited + 1
+				frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
+				do_not_update = True
+			else:
+				do_not_update = False
+
+		if not do_not_update:
+			fee_validity = update_fee_validity(fee_validity, appointment_doc.appointment_date, ref_invoice)
+			visited = fee_validity.visited
+	else:
+		fee_validity = create_fee_validity(appointment_doc.practitioner, appointment_doc.patient, appointment_doc.appointment_date, ref_invoice)
+		visited = fee_validity.visited
+
+	print "do_not_update: ", do_not_update
+	print "visited: ", visited
+
+	# Mark All Patient Appointment invoiced = True in the validity range do not cross the max visit
+	if (method == "on_cancel"):
+		invoiced = True
+	else:
+		invoiced = False
+
+	patient_appointments = appointments_valid_in_fee_validity(appointment_doc, invoiced)
+	if patient_appointments and fee_validity:
+		visit = visited
+		for appointment in patient_appointments:
+			if (method == "on_cancel" and appointment.status != "Closed"):
+				if ref_invoice == fee_validity.ref_invoice:
+					visited = visited - 1
+					if visited < 0:
+						visited = 0
+					frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
+				frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", False)
+				manage_doc_for_appoitnment("Patient Encounter", appointment.name, False)
+			elif method == "on_submit" and int(fee_validity.max_visit) > visit:
+				if ref_invoice == fee_validity.ref_invoice:
+					visited = visited + 1
+					frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
+				frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", True)
+				manage_doc_for_appoitnment("Patient Encounter", appointment.name, True)
+			if ref_invoice == fee_validity.ref_invoice:
+				visit = visit + 1
+
+	if method == "on_cancel":
+		ref_invoice_in_fee_validity = frappe.db.get_value("Fee Validity", fee_validity.name, 'ref_invoice')
+		if ref_invoice_in_fee_validity == ref_invoice:
+			frappe.delete_doc("Fee Validity", fee_validity.name)
+
+def appointments_valid_in_fee_validity(appointment, invoiced):
+	valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
+	max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
+	valid_days_date = add_days(getdate(appointment.appointment_date), int(valid_days))
+	return frappe.get_list("Patient Appointment",{'patient': appointment.patient, 'invoiced': invoiced,
+	'appointment_date':("<=", valid_days_date), 'appointment_date':(">=", getdate(appointment.appointment_date)),
+	'practitioner': appointment.practitioner}, order_by="appointment_date", limit=int(max_visit)-1)
+
+def manage_doc_for_appoitnment(dt_from_appointment, appointment, invoiced):
+	dn_from_appointment = frappe.db.exists(
+		dt_from_appointment,
+		{
+			"appointment": appointment
+		}
+	)
+	if dn_from_appointment:
+		frappe.db.set_value(dt_from_appointment, dn_from_appointment, "invoiced", invoiced)
+
+@frappe.whitelist()
+def get_drugs_to_invoice(encounter):
+	encounter = frappe.get_doc("Patient Encounter", encounter)
+	if encounter:
+		patient = frappe.get_doc("Patient", encounter.patient)
+		if patient and patient.customer:
+				item_to_invoice = []
+				for drug_line in encounter.drug_prescription:
+					if drug_line.drug_code:
+						qty = 1
+						if frappe.db.get_value("Item", drug_line.drug_code, "stock_uom") == "Nos":
+							qty = drug_line.get_quantity()
+						item_to_invoice.append({'drug_code': drug_line.drug_code, 'quantity': qty,
+						'description': drug_line.dosage+" for "+drug_line.period})
+				return item_to_invoice
+
+@frappe.whitelist()
+def get_children(doctype, parent, company, is_root=False):
+	parent_fieldname = 'parent_' + doctype.lower().replace(' ', '_')
+	fields = [
+		'name as value',
+		'is_group as expandable',
+		'lft',
+		'rgt'
+	]
+	# fields = [ 'name', 'is_group', 'lft', 'rgt' ]
+	filters = [['ifnull(`{0}`,"")'.format(parent_fieldname), '=', '' if is_root else parent]]
+
+	if is_root:
+		fields += ['service_unit_type'] if doctype == 'Healthcare Service Unit' else []
+		filters.append(['company', '=', company])
+
+	else:
+		fields += ['service_unit_type', 'allow_appointments', 'inpatient_occupancy', 'occupancy_status'] if doctype == 'Healthcare Service Unit' else []
+		fields += [parent_fieldname + ' as parent']
+
+	hc_service_units = frappe.get_list(doctype, fields=fields, filters=filters)
+
+	if doctype == 'Healthcare Service Unit':
+		for each in hc_service_units:
+			occupancy_msg = ""
+			if each['expandable'] == 1:
+				occupied = False
+				vacant = False
+				child_list = frappe.db.sql("""
+					select name, occupancy_status from `tabHealthcare Service Unit`
+					where inpatient_occupancy = 1 and
+					lft > %s and rgt < %s""",
+					(each['lft'], each['rgt']))
+				for child in child_list:
+					print child[0], child[1]
+					if not occupied:
+						occupied = 0
+					if child[1] == "Occupied":
+						occupied += 1
+					if not vacant:
+						vacant = 0
+					if child[1] == "Vacant":
+						vacant += 1
+				if vacant and occupied:
+					occupancy_total = vacant+occupied
+					occupancy_msg = str(occupied) + " Occupied out of " + str(occupancy_total)
+			each["occupied_out_of_vacant"] = occupancy_msg
+	return hc_service_units
diff --git a/erpnext/healthcare/web_form/lab_test/lab_test.json b/erpnext/healthcare/web_form/lab_test/lab_test.json
index 89029fa..f6f51b2 100644
--- a/erpnext/healthcare/web_form/lab_test/lab_test.json
+++ b/erpnext/healthcare/web_form/lab_test/lab_test.json
@@ -18,7 +18,7 @@
  "is_standard": 1, 
  "login_required": 1, 
  "max_attachment_size": 0, 
- "modified": "2018-07-16 13:10:47.940128", 
+ "modified": "2018-07-17 13:10:47.940128", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "lab-test", 
@@ -44,13 +44,14 @@
    "reqd": 1
   }, 
   {
-   "fieldname": "invoice", 
-   "fieldtype": "Link", 
+   "default": "0", 
+   "fieldname": "invoiced", 
+   "fieldtype": "Check", 
    "hidden": 0, 
-   "label": "Invoice", 
+   "label": "Invoiced", 
    "max_length": 0, 
    "max_value": 0, 
-   "options": "Sales Invoice", 
+   "options": "", 
    "read_only": 0, 
    "reqd": 0
   }, 
@@ -232,4 +233,4 @@
    "reqd": 0
   }
  ]
-}
\ No newline at end of file
+}
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 512e33b..0fe66e3 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -563,3 +563,4 @@
 erpnext.patches.v11_0.update_hub_url # 2018-08-31  # 2018-09-03
 erpnext.patches.v10_0.set_discount_amount
 erpnext.patches.v10_0.recalculate_gross_margin_for_project
+erpnext.patches.v11_0.redesign_healthcare_billing_work_flow
diff --git a/erpnext/patches/v11_0/redesign_healthcare_billing_work_flow.py b/erpnext/patches/v11_0/redesign_healthcare_billing_work_flow.py
new file mode 100644
index 0000000..08c3497
--- /dev/null
+++ b/erpnext/patches/v11_0/redesign_healthcare_billing_work_flow.py
@@ -0,0 +1,60 @@
+import frappe
+from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
+from erpnext.domains.healthcare import data
+from frappe.modules import scrub, get_doctype_module
+
+sales_invoice_referenced_doc = {
+	"Patient Appointment": "sales_invoice",
+	"Patient Encounter": "invoice",
+	"Lab Test": "invoice",
+	"Lab Prescription": "invoice",
+	"Sample Collection": "invoice"
+}
+
+def execute():
+	healthcare_custom_field_in_sales_invoice()
+	frappe.reload_doc('accounts', 'doctype', 'sales_invoice_item')
+	for si_ref_doc in sales_invoice_referenced_doc:
+		if frappe.db.exists('DocType', si_ref_doc):
+			frappe.reload_doc(get_doctype_module(si_ref_doc), 'doctype', scrub(si_ref_doc))
+
+			if frappe.db.has_column(si_ref_doc, sales_invoice_referenced_doc[si_ref_doc]) \
+			and frappe.db.has_column(si_ref_doc, 'invoiced'):
+				# Set Reference DocType and Reference Docname
+				doc_list = frappe.db.sql("""
+							select name from `tab{0}`
+							where {1} is not null
+						""".format(si_ref_doc, sales_invoice_referenced_doc[si_ref_doc]))
+				if doc_list:
+					frappe.reload_doc(get_doctype_module("Sales Invoice"), 'doctype', 'sales_invoice')
+					for doc_id in doc_list:
+						invoice_id = frappe.db.get_value(si_ref_doc, doc_id[0], sales_invoice_referenced_doc[si_ref_doc])
+						invoice = frappe.get_doc("Sales Invoice", invoice_id)
+						if invoice.items:
+							marked = False
+							if not marked:
+								for item_line in invoice.items:
+									marked = True
+									frappe.db.sql("""
+												update `tabSales Invoice Item`
+												set reference_dt = '{0}', reference_dn = '{1}'
+												where name = '{2}'
+											""".format(si_ref_doc, doc_id[0], item_line.name))
+
+				# Documents mark invoiced for submitted sales invoice
+				frappe.db.sql("""
+							update `tab{0}` doc, `tabSales Invoice` si
+							set doc.invoiced = 1
+							where si.docstatus = 1 and doc.{1} = si.name
+						""".format(si_ref_doc, sales_invoice_referenced_doc[si_ref_doc]))
+
+def healthcare_custom_field_in_sales_invoice():
+	frappe.reload_doc('healthcare', 'doctype', 'patient')
+	frappe.reload_doc('healthcare', 'doctype', 'healthcare_practitioner')
+	if data['custom_fields']:
+		create_custom_fields(data['custom_fields'])
+
+	frappe.db.sql("""
+				delete from `tabCustom Field`
+				where fieldname = 'appointment' and options = 'Patient Appointment'
+			""")