refactor: Clinical Procedure code
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
index 40f9c1c..2d17f75 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
@@ -110,7 +110,7 @@
 										function() {
 											frappe.call({
 												doc: frm.doc,
-												method: 'make_material_transfer',
+												method: 'make_material_receipt',
 												callback: function(r) {
 													if (!r.exc) {
 														cur_frm.reload_doc();
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
index 2c5cd5a..3c936bb 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
@@ -27,13 +27,15 @@
   "invoiced",
   "notes",
   "company",
+  "consumables_section",
   "consume_stock",
-  "consumables",
   "items",
+  "section_break_24",
   "invoice_separately_as_consumables",
-  "consumable_total_amount",
-  "consumption_details",
   "consumption_invoiced",
+  "consumable_total_amount",
+  "column_break_27",
+  "consumption_details",
   "amended_from"
  ],
  "fields": [
@@ -65,8 +67,7 @@
    "in_list_view": 1,
    "label": "Patient",
    "options": "Patient",
-   "reqd": 1,
-   "set_only_once": 1
+   "reqd": 1
   },
   {
    "fieldname": "patient_age",
@@ -124,28 +125,25 @@
    "fieldname": "warehouse",
    "fieldtype": "Link",
    "label": "Warehouse",
-   "options": "Warehouse",
-   "set_only_once": 1
+   "mandatory_depends_on": "eval: doc.consume_stock == 1",
+   "options": "Warehouse"
   },
   {
    "default": "Today",
    "fieldname": "start_date",
    "fieldtype": "Date",
-   "label": "Start Date",
-   "set_only_once": 1
+   "label": "Start Date"
   },
   {
    "fieldname": "start_time",
    "fieldtype": "Time",
-   "label": "Time",
-   "read_only": 1
+   "label": "Start Time"
   },
   {
    "fieldname": "sample",
    "fieldtype": "Link",
    "label": "Sample",
-   "options": "Sample Collection",
-   "read_only": 1
+   "options": "Sample Collection"
   },
   {
    "default": "0",
@@ -164,7 +162,6 @@
   {
    "fieldname": "company",
    "fieldtype": "Link",
-   "hidden": 1,
    "label": "Company",
    "options": "Company"
   },
@@ -172,16 +169,9 @@
    "default": "0",
    "fieldname": "consume_stock",
    "fieldtype": "Check",
-   "hidden": 1,
    "label": "Consume Stock"
   },
   {
-   "depends_on": "eval:doc.consume_stock == 1",
-   "fieldname": "consumables",
-   "fieldtype": "Section Break",
-   "label": "Consumables"
-  },
-  {
    "fieldname": "items",
    "fieldtype": "Table",
    "label": "Consumables",
@@ -191,7 +181,8 @@
    "default": "0",
    "fieldname": "invoice_separately_as_consumables",
    "fieldtype": "Check",
-   "label": "Consumables Invoice Separately",
+   "hidden": 1,
+   "label": "Invoice Consumables Separately",
    "read_only": 1
   },
   {
@@ -212,6 +203,7 @@
    "depends_on": "invoice_separately_as_consumables",
    "fieldname": "consumption_invoiced",
    "fieldtype": "Check",
+   "hidden": 1,
    "label": "Consumption Invoiced",
    "read_only": 1
   },
@@ -232,11 +224,24 @@
    "options": "Clinical Procedure",
    "print_hide": 1,
    "read_only": 1
+  },
+  {
+   "fieldname": "consumables_section",
+   "fieldtype": "Section Break",
+   "label": "Consumables"
+  },
+  {
+   "fieldname": "column_break_27",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "section_break_24",
+   "fieldtype": "Section Break"
   }
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2020-02-28 15:02:09.344548",
+ "modified": "2020-03-02 11:44:27.970651",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Clinical Procedure",
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
index 708e041..99a4b91 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
@@ -11,19 +11,18 @@
 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
+from frappe.model.mapper import get_mapped_doc
 
 class ClinicalProcedure(Document):
 	def validate(self):
 		self.set_status()
 		if self.consume_stock:
-			if not self.warehouse:
-				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:
+				if item.invoice_separately_as_consumables:
 					self.invoice_separately_as_consumables = True
 
 	def before_insert(self):
@@ -90,7 +89,7 @@
 
 		frappe.db.set_value('Clinical Procedure', self.name, 'status', 'Completed')
 		if self.consume_stock and self.items:
-			return stock_entry.name
+			return stock_entry
 
 	def start_procedure(self):
 		allow_start = self.set_actual_qty()
@@ -101,7 +100,7 @@
 		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 = frappe.db.get_single_value('Stock Settings', 'allow_negative_stock')
 
 		allow_start = True
 		for d in self.get('items'):
@@ -109,10 +108,11 @@
 			# validate qty
 			if not allow_negative_stock and d.actual_qty < d.qty:
 				allow_start = False
+				break
 
 		return allow_start
 
-	def make_material_transfer(self):
+	def make_material_receipt(self):
 		stock_entry = frappe.new_doc('Stock Entry')
 
 		stock_entry.stock_entry_type = 'Material Receipt'
@@ -125,7 +125,7 @@
 				se_child.item_name = item.item_name
 				se_child.uom = item.uom
 				se_child.stock_uom = item.stock_uom
-				se_child.qty = flt(item.qty-item.actual_qty)
+				se_child.qty = flt(item.qty - item.actual_qty)
 				se_child.t_warehouse = self.warehouse
 				# in stock uom
 				se_child.transfer_qty = flt(item.transfer_qty)
@@ -154,22 +154,24 @@
 def set_stock_items(doc, stock_detail_parent, parenttype):
 	items = get_items('Clinical Procedure Item', stock_detail_parent, parenttype)
 
-	for d in items:
+	for item in items:
 		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 = item.item_code
+		se_child.item_name = item.item_name
+		se_child.uom = item.uom
+		se_child.stock_uom = item.stock_uom
+		se_child.qty = flt(item.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']
+		se_child.transfer_qty = flt(item.transfer_qty)
+		se_child.conversion_factor = flt(item.conversion_factor)
+		if item.batch_no:
+			se_child.batch_no = item.batch_no
 		if parenttype == 'Clinical Procedure Template':
-			se_child.invoice_separately_as_consumables = d['invoice_separately_as_consumables']
+			se_child.invoice_separately_as_consumables = item.invoice_separately_as_consumables
+
 	return doc
 
+
 def get_items(table, parent, parenttype):
 	items = frappe.db.get_all(table, filters={
 		'parent': parent,
@@ -178,6 +180,7 @@
 
 	return items
 
+
 @frappe.whitelist()
 def make_stock_entry(doc):
 	stock_entry = frappe.new_doc('Stock Entry')
@@ -194,8 +197,10 @@
 
 	stock_entry.save(ignore_permissions=True)
 	stock_entry.submit()
-	return stock_entry
+	return stock_entry.name
 
+
+@frappe.whitelist()
 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')
@@ -209,6 +214,8 @@
 			if warehouse:
 				target.warehouse = warehouse
 
+			set_stock_items(target, source.procedure_template, 'Clinical Procedure Template')
+
 	doc = get_mapped_doc('Patient Appointment', source_name, {
 			'Patient Appointment': {
 				'doctype': 'Clinical Procedure',
@@ -233,12 +240,13 @@
 
 	return doc
 
+
 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.patient = doc.patient
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 4d0502b..a7dde0b 100644
--- a/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
+++ b/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
@@ -7,9 +7,9 @@
  "engine": "InnoDB",
  "field_order": [
   "item_code",
-  "barcode",
   "item_name",
   "qty",
+  "barcode",
   "uom",
   "invoice_separately_as_consumables",
   "column_break_5",
@@ -42,7 +42,8 @@
    "fieldname": "item_name",
    "fieldtype": "Data",
    "in_list_view": 1,
-   "label": "Item Name"
+   "label": "Item Name",
+   "read_only": 1
   },
   {
    "fieldname": "qty",
@@ -108,7 +109,7 @@
  ],
  "istable": 1,
  "links": [],
- "modified": "2020-02-28 13:15:09.058073",
+ "modified": "2020-03-01 15:34:54.226722",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Clinical Procedure Item",
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js
index 181881e..57f4cdf 100644
--- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js
@@ -117,17 +117,15 @@
 			let args = {
 				'item_code'			: d.item_code,
 				'transfer_qty'		: d.transfer_qty,
-				'company'			: frm.doc.company,
 				'quantity'			: d.qty
 			};
 			return frappe.call({
-				doc: frm.doc,
-				method: 'get_item_details',
-				args: args,
+				method: 'erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.get_item_details',
+				args: {args: args},
 				callback: function(r) {
 					if (r.message) {
 						let d = locals[cdt][cdn];
-						$.each(r.message, function(k, v){
+						$.each(r.message, function(k, v) {
 							d[k] = v;
 						});
 						refresh_field('items');
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
index ebf6afd..ec9a4cb 100644
--- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
@@ -34,29 +34,6 @@
 			except Exception:
 				frappe.throw(_('Not permitted. Please disable the Procedure Template'), title='Not Permitted')
 
-	def get_item_details(self, args=None):
-		item = frappe.db.get_all('Item',
-			filters={
-				'disabled': 0,
-				'name': args.get('item_code')
-			},
-			fields=['stock_uom', 'item_name']
-		)
-
-		if not item:
-			frappe.throw(_('Item {0} is not active').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
-
 	def update_item_and_item_price(self):
 		if self.is_billable and self.item:
 			item_doc = frappe.get_doc('Item', {'item_code': self.item})
@@ -79,6 +56,33 @@
 		self.reload()
 
 
+@frappe.whitelist()
+def get_item_details(args=None):
+	if not isinstance(args, dict):
+		args = json.loads(args)
+
+	item = frappe.db.get_all('Item',
+		filters={
+			'disabled': 0,
+			'name': args.get('item_code')
+		},
+		fields=['stock_uom', 'item_name']
+	)
+
+	if not item:
+		frappe.throw(_('Item {0} is not active').format(args.get('item_code')))
+
+	item = item[0]
+	ret = {
+		'uom': item.stock_uom,
+		'stock_uom': item.stock_uom,
+		'item_name': item.item_name,
+		'qty': 1,
+		'transfer_qty': 0,
+		'conversion_factor': 1
+	}
+	return ret
+
 def create_item_from_template(doc):
 	disabled = doc.disabled
 	if doc.is_billable and not doc.disabled:
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
index 133fee1..f9f6668 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
@@ -90,7 +90,7 @@
 			if (frm.doc.procedure_template) {
 				frm.add_custom_button(__('Clinical Procedure'), function(){
 					frappe.model.open_mapped_doc({
-						method: 'erpnext.healthcare.doctype.clinical_procedure.clinical_procedure.create_procedure',
+						method: 'erpnext.healthcare.doctype.clinical_procedure.clinical_procedure.make_procedure',
 						frm: frm,
 					});
 				}, __('Create'));