fix: consumable total amount not set in Clinical Procedure
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
index 41e7a3f..1e2cb10 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
@@ -22,6 +22,7 @@
 			}
 		});
 	},
+
 	refresh: function(frm) {
 		frm.set_query('patient', function () {
 			return {
@@ -60,7 +61,7 @@
 				function(doc) { return (doc.qty<=doc.actual_qty) ? 'green' : 'orange' ; });
 		}
 
-		if (frm.doc.docstatus == 2) {
+		if (frm.doc.docstatus == 1) {
 			if (frm.doc.status == 'In Progress') {
 				let btn_label = '';
 				let msg = '';
@@ -77,17 +78,22 @@
 						msg,
 						function() {
 							frappe.call({
-								doc: frm.doc,
 								method: 'complete_procedure',
+								doc: frm.doc,
 								callback: function(r) {
-									if (!r.exc) {
-										cur_frm.reload_doc();
+									if (r.message) {
+										frappe.show_alert({
+											message:  __('Stock Entry {0} created',
+											['<a class="bold" href="#Form/Stock Entry/'+ r.message + '">' + r.message + '</a>']),
+											indicator: 'green'
+										});
+										frm.reload_doc();
 									}
 								}
 							});
 						}
 					);
-				});
+				}).addClass("btn-primary");
 
 			} else if (frm.doc.status == 'Pending') {
 				frm.add_custom_button(__('Start'), function() {
@@ -96,9 +102,11 @@
 						method: 'start_procedure',
 						callback: function(r) {
 							if (!r.exc) {
-								if (r.data.message == 'insufficient stock') {
+								if (r.message == 'insufficient stock') {
+									let msg = __('Stock quantity to start the Procedure is not available in the Warehouse {0}. Do you want to record a Stock Entry?',
+										[frm.doc.warehouse.bold()]);
 									frappe.confirm(
-										__('Stock quantity to start the procedure is not available in the warehouse. Do you want to record a Stock Transfer?'),
+										msg,
 										function() {
 											frappe.call({
 												doc: frm.doc,
@@ -119,10 +127,9 @@
 							}
 						}
 					});
-				});
+				}).addClass("btn-primary");
 			}
 		}
-
 	},
 
 	onload: function(frm) {
@@ -257,6 +264,7 @@
 		let d = locals[cdt][cdn];
 		frappe.model.set_value(cdt, cdn, 'transfer_qty', d.qty*d.conversion_factor);
 	},
+
 	uom: function(doc, cdt, cdn) {
 		let d = locals[cdt][cdn];
 		if (d.uom && d.item_code) {
@@ -275,6 +283,7 @@
 			});
 		}
 	},
+
 	item_code: function(frm, cdt, cdn) {
 		let d = locals[cdt][cdn];
 		let args = null;
@@ -286,14 +295,14 @@
 				'warehouse': frm.doc.warehouse
 			};
 			return frappe.call({
-				method: 'erpnext.stock.get_item_details.get_item_details',
+				method: 'erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.get_item_details',
 				args: {args: args},
 				callback: function(r) {
 					if (r.message) {
-						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);
+						let d = locals[cdt][cdn];
+						$.each(r.message, function(k, v) {
+							d[k] = v;
+						});
 						refresh_field('items');
 					}
 				}
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
index ea53030..f45ea78 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
@@ -17,7 +17,7 @@
 		self.set_status()
 		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:
@@ -28,19 +28,19 @@
 
 	def before_insert(self):
 		if self.consume_stock:
-			set_stock_items(self, self.procedure_template, "Clinical Procedure Template")
-			self.set_actual_qty();
+			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)
+			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)
+			frappe.db.set_value('Patient Appointment', self.appointment, 'status', 'Closed')
+		template = frappe.get_doc('Clinical Procedure Template', self.procedure_template)
 		if template.sample:
-			patient = frappe.get_doc("Patient", self.patient)
+			patient = frappe.get_doc('Patient', self.patient)
 			sample_collection = create_sample_doc(template, patient, None)
-			frappe.db.set_value("Clinical Procedure", self.name, "sample", sample_collection.name)
+			frappe.db.set_value('Clinical Procedure', self.name, 'sample', sample_collection.name)
 		self.reload()
 
 	def set_status(self):
@@ -52,52 +52,57 @@
 		elif self.docstatus == 2:
 			self.status = 'Cancelled'
 
-	def complete(self):
+	def complete_procedure(self):
 		if self.consume_stock and self.items:
-			create_stock_entry(self)
-		frappe.db.set_value("Clinical Procedure", self.name, "status", 'Completed')
+			stock_entry = make_stock_entry(self)
 
 		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)
+			customer = frappe.db.get_value('Patient', self.patient, 'customer')
+			if customer:
+				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': 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.qty
+						item_consumption_details = item_details.item_name + ' ' + str(item.qty) + ' ' + item.uom + ' ' + str(item_price)
+						consumable_total_amount += item_price
+						if not consumption_details:
+							consumption_details = _('Clinical Procedure ({0}):').format(self.name)
+						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)
+			else:
+				frappe.throw(_('Please set Customer in Patient {0}').format(frappe.bold(self.patient)), title=_('Customer Not Found'))
 
-	def start(self):
+		frappe.db.set_value('Clinical Procedure', self.name, 'status', 'Completed')
+		if self.consume_stock and self.items:
+			return stock_entry.name
+
+	def start_procedure(self):
 		allow_start = self.set_actual_qty()
 		if allow_start:
-			self.status = 'In Progress'
+			self.db_set('status', 'In Progress')
 			insert_clinical_procedure_to_medical_record(self)
-		else:
-			self.status = 'Pending'
-		self.save()
+			return 'success'
+		return 'insufficient stock'
 
 	def set_actual_qty(self):
-		allow_negative_stock = cint(frappe.db.get_value("Stock Settings", None, "allow_negative_stock"))
+		allow_negative_stock = cint(frappe.db.get_value('Stock Settings', None, 'allow_negative_stock'))
 
 		allow_start = True
 		for d in self.get('items'):
@@ -109,11 +114,11 @@
 		return allow_start
 
 	def make_material_transfer(self):
-		stock_entry = frappe.new_doc("Stock Entry")
+		stock_entry = frappe.new_doc('Stock Entry')
 
-		stock_entry.purpose = "Material Transfer"
+		stock_entry.stock_entry_type = 'Material Receipt'
 		stock_entry.to_warehouse = self.warehouse
-		expense_account = get_account(None, "expense_account", "Healthcare Settings", self.company)
+		expense_account = get_account(None, 'expense_account', 'Healthcare Settings', self.company)
 		for item in self.items:
 			if item.qty > item.actual_qty:
 				se_child = stock_entry.append('items')
@@ -131,69 +136,68 @@
 				se_child.expense_account = expense_account
 		return stock_entry.as_dict()
 
-@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
+		'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):
-	item_dict = get_item_dict("Clinical Procedure Item", stock_detail_parent, parenttype)
+	item_dict = get_item_dict('Clinical Procedure Item', stock_detail_parent, parenttype)
 
 	for d in item_dict:
 		se_child = doc.append('items')
-		se_child.item_code = d["item_code"]
-		se_child.item_name = d["item_name"]
-		se_child.uom = d["uom"]
-		se_child.stock_uom = d["stock_uom"]
-		se_child.qty = flt(d["qty"])
+		se_child.item_code = d['item_code']
+		se_child.item_name = d['item_name']
+		se_child.uom = d['uom']
+		se_child.stock_uom = d['stock_uom']
+		se_child.qty = flt(d['qty'])
 		# in stock uom
-		se_child.transfer_qty = flt(d["transfer_qty"])
-		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"]
+		se_child.transfer_qty = flt(d['transfer_qty'])
+		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):
-	query = """select * from `tab{table}` where parent = '{parent}' and parenttype = '{parenttype}' """
+	query = '''select * from `tab{table}` where parent = '{parent}' and parenttype = '{parenttype}' '''
 
 	return frappe.db.sql(query.format(table=table, parent=parent, parenttype=parenttype), as_dict=True)
 
-def create_stock_entry(doc):
-	stock_entry = frappe.new_doc("Stock Entry")
-	stock_entry = set_stock_items(stock_entry, doc.name, "Clinical Procedure")
-	stock_entry.purpose = "Material Issue"
+@frappe.whitelist()
+def make_stock_entry(doc):
+	stock_entry = frappe.new_doc('Stock Entry')
+	stock_entry = set_stock_items(stock_entry, doc.name, 'Clinical Procedure')
+	stock_entry.stock_entry_type = 'Material Issue'
 	stock_entry.from_warehouse = doc.warehouse
 	stock_entry.company = doc.company
-	expense_account = get_account(None, "expense_account", "Healthcare Settings", doc.company)
+	expense_account = get_account(None, 'expense_account', 'Healthcare Settings', doc.company)
 
 	for item_line in stock_entry.items:
 		cost_center = frappe.get_cached_value('Company',  doc.company,  'cost_center')
-		#item_line.s_warehouse = warehouse #deaful source warehouse set, stock entry to copy to lines
 		item_line.cost_center = cost_center
-		#if not expense_account:
-		#	expense_account = frappe.db.get_value("Item", item_line.item_code, "expense_account")
 		item_line.expense_account = expense_account
 
-	stock_entry.insert(ignore_permissions = True)
+	stock_entry.save(ignore_permissions=True)
 	stock_entry.submit()
+	return stock_entry
 
 def make_procedure(source_name, target_doc=None):
 	def set_missing_values(source, target):
-		consume_stock = frappe.db.get_value("Clinical Procedure Template", source.procedure_template, "consume_stock")
+		consume_stock = frappe.db.get_value('Clinical Procedure Template', source.procedure_template, 'consume_stock')
 		if consume_stock:
 			target.consume_stock = 1
 			warehouse = None
 			if source.service_unit:
-				warehouse = frappe.db.get_value("Healthcare Service Unit", source.service_unit, "warehouse")
+				warehouse = frappe.db.get_value('Healthcare Service Unit', source.service_unit, 'warehouse')
 			if not warehouse:
-				warehouse = frappe.db.get_value("Stock Settings", None, "default_warehouse")
+				warehouse = frappe.db.get_value('Stock Settings', None, 'default_warehouse')
 			if warehouse:
 				target.warehouse = warehouse
 
@@ -224,16 +228,16 @@
 def insert_clinical_procedure_to_medical_record(doc):
 	subject = cstr(doc.procedure_template)
 	if doc.practitioner:
-		subject += " "+doc.practitioner
+		subject += ' '+doc.practitioner
 	if subject and doc.notes:
-		subject += "<br/>"+doc.notes
+		subject += '<br/>'+doc.notes
 
-	medical_record = frappe.new_doc("Patient Medical Record")
+	medical_record = frappe.new_doc('Patient Medical Record')
 	medical_record.patient = doc.patient
 	medical_record.subject = subject
-	medical_record.status = "Open"
+	medical_record.status = 'Open'
 	medical_record.communication_date = doc.start_date
-	medical_record.reference_doctype = "Clinical Procedure"
+	medical_record.reference_doctype = 'Clinical Procedure'
 	medical_record.reference_name = doc.name
 	medical_record.reference_owner = doc.owner
 	medical_record.save(ignore_permissions=True)