Merge pull request #18241 from scmmishra/cash-flow-chart

feat: added chart to cash-flow report
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index dead1f0..5dce349 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -66,10 +66,11 @@
   "net_total",
   "total_net_weight",
   "taxes_section",
-  "taxes_and_charges",
+  "tax_category",
   "column_break_50",
   "shipping_rule",
   "section_break_52",
+  "taxes_and_charges",
   "taxes",
   "sec_tax_breakup",
   "other_charges_calculation",
@@ -569,7 +570,7 @@
   {
    "fieldname": "taxes_and_charges",
    "fieldtype": "Link",
-   "label": "Taxes and Charges",
+   "label": "Purchase Taxes and Charges Template",
    "oldfieldname": "purchase_other_charges",
    "oldfieldtype": "Link",
    "options": "Purchase Taxes and Charges Template",
@@ -1032,12 +1033,18 @@
    "fieldname": "update_auto_repeat_reference",
    "fieldtype": "Button",
    "label": "Update Auto Repeat Reference"
+  },
+  {
+   "fieldname": "tax_category",
+   "fieldtype": "Link",
+   "label": "Tax Category",
+   "options": "Tax Category"
   }
  ],
  "icon": "fa fa-file-text",
  "idx": 105,
  "is_submittable": 1,
- "modified": "2019-06-24 21:22:05.483429",
+ "modified": "2019-07-11 18:25:49.509343",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order",
diff --git a/erpnext/config/healthcare.py b/erpnext/config/healthcare.py
index 1311111..756d22e 100644
--- a/erpnext/config/healthcare.py
+++ b/erpnext/config/healthcare.py
@@ -26,8 +26,8 @@
 				},
 				{
 					"type": "page",
-					"name": "medical_record",
-					"label": _("Patient Medical Record"),
+					"name": "patient_history",
+					"label": _("Patient History"),
 				},
 				{
 					"type": "page",
diff --git a/erpnext/config/stock.py b/erpnext/config/stock.py
index 84aa847..f5e48b3 100644
--- a/erpnext/config/stock.py
+++ b/erpnext/config/stock.py
@@ -281,9 +281,9 @@
 				},
 				{
 					"type": "report",
+					"is_query_report": True,
 					"name": "Item Shortage Report",
-					"route": "#Report/Bin/Item Shortage Report",
-					"doctype": "Purchase Receipt"
+					"doctype": "Bin"
 				},
 				{
 					"type": "report",
diff --git a/erpnext/config/support.py b/erpnext/config/support.py
index 36b4214..151c4f7 100644
--- a/erpnext/config/support.py
+++ b/erpnext/config/support.py
@@ -21,13 +21,7 @@
 					"type": "doctype",
 					"name": "Issue Priority",
 					"description": _("Issue Priority."),
-				},
-				{
-					"type": "doctype",
-					"name": "Communication",
-					"description": _("Communication log."),
-					"onboard": 1,
-				},
+				}
 			]
 		},
 		{
diff --git a/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py b/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py
index 29a1a2b..96a533e 100644
--- a/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py
+++ b/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py
@@ -7,7 +7,9 @@
 from frappe import _
 from frappe.model.document import Document
 from requests_oauthlib import OAuth2Session
-import json, requests
+import json
+import requests
+import traceback
 from erpnext import encode_company_abbr
 
 # QuickBooks requires a redirect URL, User will be redirect to this URL
@@ -32,7 +34,6 @@
 class QuickBooksMigrator(Document):
 	def __init__(self, *args, **kwargs):
 		super(QuickBooksMigrator, self).__init__(*args, **kwargs)
-		from pprint import pprint
 		self.oauth = OAuth2Session(
 			client_id=self.client_id,
 			redirect_uri=self.redirect_url,
@@ -46,7 +47,9 @@
 		if self.company:
 			# We need a Cost Center corresponding to the selected erpnext Company
 			self.default_cost_center = frappe.db.get_value('Company', self.company, 'cost_center')
-			self.default_warehouse = frappe.get_all('Warehouse', filters={"company": self.company, "is_group": 0})[0]["name"]
+			company_warehouses = frappe.get_all('Warehouse', filters={"company": self.company, "is_group": 0})
+			if company_warehouses:
+				self.default_warehouse = company_warehouses[0].name
 		if self.authorization_endpoint:
 			self.authorization_url = self.oauth.authorization_url(self.authorization_endpoint)[0]
 
@@ -218,7 +221,7 @@
 
 	def _fetch_general_ledger(self):
 		try:
-			query_uri = "{}/company/{}/reports/GeneralLedger".format(self.api_endpoint ,self.quickbooks_company_id)
+			query_uri = "{}/company/{}/reports/GeneralLedger".format(self.api_endpoint, self.quickbooks_company_id)
 			response = self._get(query_uri,
 				params={
 					"columns": ",".join(["tx_date", "txn_type", "credit_amt", "debt_amt"]),
@@ -493,17 +496,17 @@
 						"account_currency": customer["CurrencyRef"]["value"],
 						"company": self.company,
 					})[0]["name"]
-				except Exception as e:
+				except Exception:
 					receivable_account = None
 				erpcustomer = frappe.get_doc({
 					"doctype": "Customer",
 					"quickbooks_id": customer["Id"],
-					"customer_name" : encode_company_abbr(customer["DisplayName"], self.company),
-					"customer_type" : "Individual",
-					"customer_group" : "Commercial",
+					"customer_name": encode_company_abbr(customer["DisplayName"], self.company),
+					"customer_type": "Individual",
+					"customer_group": "Commercial",
 					"default_currency": customer["CurrencyRef"]["value"],
 					"accounts": [{"company": self.company, "account": receivable_account}],
-					"territory" : "All Territories",
+					"territory": "All Territories",
 					"company": self.company,
 				}).insert()
 				if "BillAddr" in customer:
@@ -521,7 +524,7 @@
 					item_dict = {
 						"doctype": "Item",
 						"quickbooks_id": item["Id"],
-						"item_code" : encode_company_abbr(item["Name"], self.company),
+						"item_code": encode_company_abbr(item["Name"], self.company),
 						"stock_uom": "Unit",
 						"is_stock_item": 0,
 						"item_group": "All Item Groups",
@@ -549,14 +552,14 @@
 				erpsupplier = frappe.get_doc({
 					"doctype": "Supplier",
 					"quickbooks_id": vendor["Id"],
-					"supplier_name" : encode_company_abbr(vendor["DisplayName"], self.company),
-					"supplier_group" : "All Supplier Groups",
+					"supplier_name": encode_company_abbr(vendor["DisplayName"], self.company),
+					"supplier_group": "All Supplier Groups",
 					"company": self.company,
 				}).insert()
 				if "BillAddr" in vendor:
 					self._create_address(erpsupplier, "Supplier", vendor["BillAddr"], "Billing")
 				if "ShipAddr" in vendor:
-					self._create_address(erpsupplier, "Supplier",vendor["ShipAddr"], "Shipping")
+					self._create_address(erpsupplier, "Supplier", vendor["ShipAddr"], "Shipping")
 		except Exception as e:
 			self._log_error(e)
 
@@ -829,7 +832,7 @@
 					"currency": invoice["CurrencyRef"]["value"],
 					"conversion_rate": invoice.get("ExchangeRate", 1),
 					"posting_date": invoice["TxnDate"],
-					"due_date":  invoice.get("DueDate", invoice["TxnDate"]),
+					"due_date": invoice.get("DueDate", invoice["TxnDate"]),
 					"credit_to": credit_to_account,
 					"supplier": frappe.get_all("Supplier",
 						filters={
@@ -1200,7 +1203,7 @@
 
 
 	def _create_address(self, entity, doctype, address, address_type):
-		try :
+		try:
 			if not frappe.db.exists({"doctype": "Address", "quickbooks_id": address["Id"]}):
 				frappe.get_doc({
 					"doctype": "Address",
@@ -1252,8 +1255,6 @@
 
 
 	def _log_error(self, execption, data=""):
-		import json, traceback
-		traceback.print_exc()
 		frappe.log_error(title="QuickBooks Migration Error",
 			message="\n".join([
 				"Data",
diff --git a/erpnext/healthcare/doctype/patient/patient.js b/erpnext/healthcare/doctype/patient/patient.js
index 1692814..1a34fe8 100644
--- a/erpnext/healthcare/doctype/patient/patient.js
+++ b/erpnext/healthcare/doctype/patient/patient.js
@@ -21,9 +21,9 @@
 			});
 		}
 		if (frm.doc.patient_name && frappe.user.has_role("Physician")) {
-			frm.add_custom_button(__('Medical Record'), function () {
+			frm.add_custom_button(__('Patient History'), function () {
 				frappe.route_options = { "patient": frm.doc.name };
-				frappe.set_route("medical_record");
+				frappe.set_route("patient_history");
 			},"View");
 		}
 		if (!frm.doc.__islocal && (frappe.user.has_role("Nursing User") || frappe.user.has_role("Physician"))) {
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
index b3cbd1f..858145e 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
@@ -30,9 +30,9 @@
 			};
 		});
 		if(frm.doc.patient){
-			frm.add_custom_button(__('Medical Record'), function() {
+			frm.add_custom_button(__('Patient History'), function() {
 				frappe.route_options = {"patient": frm.doc.patient};
-				frappe.set_route("medical_record");
+				frappe.set_route("patient_history");
 			},__("View"));
 		}
 		if(frm.doc.status == "Open"){
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
index 7ea4568..088bc81 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
@@ -41,10 +41,10 @@
 				}
 			});
 		}
-		frm.add_custom_button(__('Medical Record'), function() {
+		frm.add_custom_button(__('Patient History'), function() {
 			if (frm.doc.patient) {
 				frappe.route_options = {"patient": frm.doc.patient};
-				frappe.set_route("medical_record");
+				frappe.set_route("patient_history");
 			} else {
 				frappe.msgprint(__("Please select Patient"));
 			}
diff --git a/erpnext/healthcare/page/medical_record/__init__.py b/erpnext/healthcare/page/medical_record/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/erpnext/healthcare/page/medical_record/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/erpnext/healthcare/page/medical_record/medical_record.js b/erpnext/healthcare/page/medical_record/medical_record.js
deleted file mode 100644
index df19d8f..0000000
--- a/erpnext/healthcare/page/medical_record/medical_record.js
+++ /dev/null
@@ -1,182 +0,0 @@
-frappe.provide("frappe.medical_record");
-frappe.pages['medical_record'].on_page_load = function(wrapper) {
-	var me = this;
-	var page = frappe.ui.make_app_page({
-		parent: wrapper,
-		title: 'Medical Record',
-	});
-
-	frappe.breadcrumbs.add("Medical");
-
-	page.main.html(frappe.render_template("patient_select", {}));
-	var patient = frappe.ui.form.make_control({
-		parent: page.main.find(".patient"),
-		df: {
-			fieldtype: "Link",
-			options: "Patient",
-			fieldname: "patient",
-			change: function(){
-				page.main.find(".frappe-list").html("");
-				draw_page(patient.get_value(), me);
-			}
-		},
-		only_input: true,
-	});
-	patient.refresh();
-
-
-	this.page.main.on("click", ".medical_record-message", function() {
-		var	doctype = $(this).attr("data-doctype"),
-			docname = $(this).attr("data-docname");
-
-		if (doctype && docname) {
-			frappe.route_options = {
-				scroll_to: { "doctype": doctype, "name": docname }
-			};
-			frappe.set_route(["Form", doctype, docname]);
-		}
-	});
-
-	this.page.sidebar.on("click", ".edit-details", function() {
-		patient = patient.get_value();
-		if (patient) {
-			frappe.set_route(["Form", "Patient", patient]);
-		}
-	});
-
-};
-
-frappe.pages['medical_record'].refresh = function() {
-	var me = this;
-
-	if(frappe.route_options) {
-		if(frappe.route_options.patient){
-			me.page.main.find(".frappe-list").html("");
-			var patient = frappe.route_options.patient;
-			draw_page(patient,me);
-			me.page.main.find("[data-fieldname='patient']").val(patient);
-			frappe.route_options = null;
-		}
-	}
-};
-var show_patient_info = function(patient, me){
-	frappe.call({
-		"method": "erpnext.healthcare.doctype.patient.patient.get_patient_detail",
-		args: {
-			patient: patient
-		},
-		callback: function (r) {
-			var data = r.message;
-			var details = "";
-			if(data.email) details += "<br><b>Email :</b> " + data.email;
-			if(data.mobile) details += "<br><b>Mobile :</b> " + data.mobile;
-			if(data.occupation) details += "<br><b>Occupation :</b> " + data.occupation;
-			if(data.blood_group) details += "<br><b>Blood group : </b> " + data.blood_group;
-			if(data.allergies) details +=  "<br><br><b>Allergies : </b> "+  data.allergies;
-			if(data.medication) details +=  "<br><b>Medication : </b> "+  data.medication;
-			if(data.alcohol_current_use) details +=  "<br><br><b>Alcohol use : </b> "+  data.alcohol_current_use;
-			if(data.alcohol_past_use) details +=  "<br><b>Alcohol past use : </b> "+  data.alcohol_past_use;
-			if(data.tobacco_current_use) details +=  "<br><b>Tobacco use : </b> "+  data.tobacco_current_use;
-			if(data.tobacco_past_use) details +=  "<br><b>Tobacco past use : </b> "+  data.tobacco_past_use;
-			if(data.medical_history) details +=  "<br><br><b>Medical history : </b> "+  data.medical_history;
-			if(data.surgical_history) details +=  "<br><b>Surgical history : </b> "+  data.surgical_history;
-			if(data.surrounding_factors) details +=  "<br><br><b>Occupational hazards : </b> "+  data.surrounding_factors;
-			if(data.other_risk_factors) details += "<br><b>Other risk factors : </b> " + data.other_risk_factors;
-			if(data.patient_details) details += "<br><br><b>More info : </b> " + data.patient_details;
-
-			if(details){
-				details = "<div style='padding-left:10px; font-size:13px;' align='center'></br><b class='text-muted'>Patient Details</b>" + details + "</div>";
-			}
-
-			var vitals = "";
-			if(data.temperature) vitals += "<br><b>Temperature :</b> " + data.temperature;
-			if(data.pulse) vitals += "<br><b>Pulse :</b> " + data.pulse;
-			if(data.respiratory_rate) vitals += "<br><b>Respiratory Rate :</b> " + data.respiratory_rate;
-			if(data.bp) vitals += "<br><b>BP :</b> " + data.bp;
-			if(data.bmi) vitals += "<br><b>BMI :</b> " + data.bmi;
-			if(data.height) vitals += "<br><b>Height :</b> " + data.height;
-			if(data.weight) vitals += "<br><b>Weight :</b> " + data.weight;
-			if(data.signs_date) vitals += "<br><b>Date :</b> " + data.signs_date;
-
-			if(vitals){
-				vitals = "<div style='padding-left:10px; font-size:13px;' align='center'></br><b class='text-muted'>Vital Signs</b>" + vitals + "<br></div>";
-				details = vitals + details;
-			}
-			if(details) details += "<div align='center'><br><a class='btn btn-default btn-sm edit-details'>Edit Details</a></b> </div>";
-
-			me.page.sidebar.addClass("col-sm-3");
-			me.page.sidebar.html(details);
-			me.page.wrapper.find(".layout-main-section-wrapper").addClass("col-sm-9");
-		}
-	});
-};
-var draw_page = function(patient, me){
-	frappe.model.with_doctype("Patient Medical Record", function() {
-		me.page.list = new frappe.ui.BaseList({
-			hide_refresh: true,
-			page: me.page,
-			method: 'erpnext.healthcare.page.medical_record.medical_record.get_feed',
-			args: {name: patient},
-			parent: $("<div></div>").appendTo(me.page.main),
-			render_view: function(values) {
-				var me = this;
-				var wrapper = me.page.main.find(".result-list").get(0);
-				values.map(function (value) {
-					var row = $('<div class="list-row">').data("data", value).appendTo($(wrapper)).get(0);
-					new frappe.medical_record.Feed(row, value);
-				});
-			},
-			show_filters: true,
-			doctype: "Patient Medical Record",
-		});
-		show_patient_info(patient, me);
-		me.page.list.run();
-	});
-};
-
-frappe.medical_record.last_feed_date = false;
-frappe.medical_record.Feed = Class.extend({
-	init: function(row, data) {
-		this.scrub_data(data);
-		this.add_date_separator(row, data);
-		if(!data.add_class)
-			data.add_class = "label-default";
-
-		data.link = "";
-		if (data.reference_doctype && data.reference_name) {
-			data.link = frappe.format(data.reference_name, {fieldtype: "Link", options: data.reference_doctype},
-				{label: __(data.reference_doctype)});
-		}
-
-		$(row)
-			.append(frappe.render_template("medical_record_row", data))
-			.find("a").addClass("grey");
-	},
-	scrub_data: function(data) {
-		data.by = frappe.user.full_name(data.owner);
-		data.imgsrc = frappe.utils.get_file_link(frappe.user_info(data.owner).image);
-
-		data.icon = "icon-flag";
-	},
-	add_date_separator: function(row, data) {
-		var date = frappe.datetime.str_to_obj(data.creation);
-		var last = frappe.medical_record.last_feed_date;
-
-		if((last && frappe.datetime.obj_to_str(last) != frappe.datetime.obj_to_str(date)) || (!last)) {
-			var diff = frappe.datetime.get_day_diff(frappe.datetime.get_today(), frappe.datetime.obj_to_str(date));
-			if(diff < 1) {
-				var pdate = 'Today';
-			} else if(diff < 2) {
-				pdate = 'Yesterday';
-			} else {
-				pdate = frappe.datetime.global_date_format(date);
-			}
-			data.date_sep = pdate;
-			data.date_class = pdate=='Today' ? "date-indicator blue" : "date-indicator";
-		} else {
-			data.date_sep = null;
-			data.date_class = "";
-		}
-		frappe.medical_record.last_feed_date = date;
-	}
-});
diff --git a/erpnext/healthcare/page/medical_record/medical_record.json b/erpnext/healthcare/page/medical_record/medical_record.json
deleted file mode 100644
index ca30c3b..0000000
--- a/erpnext/healthcare/page/medical_record/medical_record.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "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, 
- "system_page": 0, 
- "title": "Medical Record"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/page/medical_record/medical_record.py b/erpnext/healthcare/page/medical_record/medical_record.py
deleted file mode 100644
index 22c5852..0000000
--- a/erpnext/healthcare/page/medical_record/medical_record.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-import frappe
-from frappe.utils import cint
-
-@frappe.whitelist()
-def get_feed(start, page_length, name):
-	"""get feed"""
-	result = frappe.db.sql("""select name, owner, modified, creation,
-			reference_doctype, reference_name, subject
-		from `tabPatient Medical Record`
-		where patient=%(patient)s
-		order by creation desc
-		limit %(start)s, %(page_length)s""",
-		{
-			"start": cint(start),
-			"page_length": cint(page_length),
-			"patient": name
-		}, as_dict=True)
-
-	return result
diff --git a/erpnext/healthcare/page/medical_record/medical_record_row.html b/erpnext/healthcare/page/medical_record/medical_record_row.html
deleted file mode 100644
index 9a670c9..0000000
--- a/erpnext/healthcare/page/medical_record/medical_record_row.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<div class="row medical_record-row" data-creation="{%= creation.split(" ")[0] + " 00:00:00" %}">
-	<div class="col-xs-3 text-right medical_record-date"><span class="{%= date_class %}">
-		{%= date_sep || "" %}</span>
-	</div>
-	<div class="col-xs-9 medical_record-message"
-		data-doctype="{%= reference_doctype %}"
-		data-docname="{%= reference_name %}"
-		title="{%= by %} / {%= frappe.datetime.str_to_user(creation) %}">
-		<span class="avatar avatar-small">
-			<div class="avatar-frame" style="background-image: url({{ imgsrc }});"></div>
-			<!-- <img src="{%= imgsrc %}"> -->
-		</span>
-		<span class="small">
-		{% if (reference_doctype && reference_name) { %}
-			{%= __("{0}: {1}", [link, "<strong>" + subject + "</strong>"]) %}
-		{% } else { %}
-			{%= subject %}
-		{% } %}
-	</span>
-	</div>
-</div>
diff --git a/erpnext/healthcare/page/medical_record/patient_select.html b/erpnext/healthcare/page/medical_record/patient_select.html
deleted file mode 100644
index 321baf7..0000000
--- a/erpnext/healthcare/page/medical_record/patient_select.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<div class="text-center col-sm-9" style="padding: 40px;">
-
-    	<p>{%= __("Select Patient") %}</p>
-	<p class="patient" style="margin: auto; max-width: 300px; margin-bottom: 20px;"></p>
-</div>
diff --git a/erpnext/healthcare/page/patient_history/__init__.py b/erpnext/healthcare/page/patient_history/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/page/patient_history/__init__.py
diff --git a/erpnext/healthcare/page/medical_record/medical_record.css b/erpnext/healthcare/page/patient_history/patient_history.css
similarity index 62%
rename from erpnext/healthcare/page/medical_record/medical_record.css
rename to erpnext/healthcare/page/patient_history/patient_history.css
index 977625b..865d6ab 100644
--- a/erpnext/healthcare/page/medical_record/medical_record.css
+++ b/erpnext/healthcare/page/patient_history/patient_history.css
@@ -14,6 +14,10 @@
 	margin-bottom: -4px;
 }
 
+.medical_record-row > * {
+	z-index: -999;
+}
+
 .date-indicator {
     background:none;
     font-size:12px;
@@ -35,6 +39,61 @@
 	color: #5e64ff;
 }
 
+.div-bg-color {
+	background: #fafbfc;
+}
+
+.bg-color-white {
+	background: #FFFFFF;
+}
+
+.d-flex {
+	display: flex;
+}
+
+.width-full {
+	width: 100%;
+}
+
+.p-3 {
+	padding: 16px;
+}
+
+.mt-2 {
+	margin-top: 8px;
+}
+
+.mr-3 {
+	margin-right: 16px;
+}
+
+.Box {
+	background-color: #fff;
+	border: 1px solid #d1d5da;
+	border-radius: 3px;
+}
+
+.flex-column {
+	flex-direction: column;
+}
+
+.avatar {
+	display: inline-block;
+	overflow: hidden;
+	line-height: 1;
+	vertical-align: middle;
+	border-radius: 3px;
+}
+
+.py-3 {
+	padding-top: 16px;
+	padding-bottom: 16px;
+}
+
+.border-bottom {
+	border-bottom: 1px #e1e4e8 solid;
+}
+
 .date-indicator.blue::after {
 	background: #5e64ff;
 }
@@ -65,8 +124,3 @@
 #page-medical_record .list-filters {
 	display: none ;
 }
-
-#page-medical_record .octicon-heart {
-	color: #ff5858;
-	margin: 0px 5px;
-}
diff --git a/erpnext/healthcare/page/patient_history/patient_history.html b/erpnext/healthcare/page/patient_history/patient_history.html
new file mode 100644
index 0000000..7a9446d
--- /dev/null
+++ b/erpnext/healthcare/page/patient_history/patient_history.html
@@ -0,0 +1,20 @@
+<div class="col-sm-12">
+	<div class="col-sm-3">
+	<p class="text-center">{%= __("Select Patient") %}</p>
+	<p class="patient" style="margin: auto; max-width: 300px; margin-bottom: 20px;"></p>
+	<div class="patient_details" style="z-index=0"></div>
+	</div>
+	<div class="col-sm-9 patient_documents">
+		<div class="col-sm-12">
+			<div class="col-sm-12 show_chart_btns" align="center">
+			</div>
+			<div id="chart" class="col-sm-12 patient_vital_charts">
+			</div>
+		</div>
+		<div class="col-sm-12 patient_documents_list">
+		</div>
+		<div class="col-sm-12 text-center py-3">
+			<a class="btn btn-sm btn-default btn-get-records" style="display:none">More..</a>
+		</div>
+	</div>
+</div>
\ No newline at end of file
diff --git a/erpnext/healthcare/page/patient_history/patient_history.js b/erpnext/healthcare/page/patient_history/patient_history.js
new file mode 100644
index 0000000..87fe7ed
--- /dev/null
+++ b/erpnext/healthcare/page/patient_history/patient_history.js
@@ -0,0 +1,300 @@
+frappe.provide("frappe.patient_history");
+frappe.pages['patient_history'].on_page_load = function(wrapper) {
+	var me = this;
+	var page = frappe.ui.make_app_page({
+		parent: wrapper,
+		title: 'Patient History',
+		single_column: true
+	});
+
+	frappe.breadcrumbs.add("Healthcare");
+	let pid = '';
+	page.main.html(frappe.render_template("patient_history", {}));
+	var patient = frappe.ui.form.make_control({
+		parent: page.main.find(".patient"),
+		df: {
+			fieldtype: "Link",
+			options: "Patient",
+			fieldname: "patient",
+			change: function(){
+				if(pid != patient.get_value() && patient.get_value()){
+					me.start = 0;
+					me.page.main.find(".patient_documents_list").html("");
+					get_documents(patient.get_value(), me);
+					show_patient_info(patient.get_value(), me);
+					show_patient_vital_charts(patient.get_value(), me, "bp", "mmHg", "Blood Pressure");
+				}
+				pid = patient.get_value();
+			}
+		},
+		only_input: true,
+	});
+	patient.refresh();
+
+	if (frappe.route_options){
+		patient.set_value(frappe.route_options.patient);
+	}
+
+	this.page.main.on("click", ".btn-show-chart", function() {
+		var	btn_show_id = $(this).attr("data-show-chart-id"), pts = $(this).attr("data-pts");
+		var title = $(this).attr("data-title");
+		show_patient_vital_charts(patient.get_value(), me, btn_show_id, pts, title);
+	});
+
+	this.page.main.on("click", ".btn-more", function() {
+		var	doctype = $(this).attr("data-doctype"), docname = $(this).attr("data-docname");
+		if(me.page.main.find("."+docname).parent().find('.document-html').attr('data-fetched') == "1"){
+			me.page.main.find("."+docname).hide();
+			me.page.main.find("."+docname).parent().find('.document-html').show();
+		}else{
+			if(doctype && docname){
+				let exclude = ["patient", "patient_name", 'patient_sex', "encounter_date"];
+				frappe.call({
+					method: "erpnext.healthcare.utils.render_doc_as_html",
+					args:{
+						doctype: doctype,
+						docname: docname,
+						exclude_fields: exclude
+					},
+					callback: function(r) {
+						if (r.message){
+							me.page.main.find("."+docname).hide();
+							me.page.main.find("."+docname).parent().find('.document-html').html(r.message.html+"\
+							<div align='center'><a class='btn octicon octicon-chevron-up btn-default btn-xs\
+							btn-less' data-doctype='"+doctype+"' data-docname='"+docname+"'></a></div>");
+							me.page.main.find("."+docname).parent().find('.document-html').show();
+							me.page.main.find("."+docname).parent().find('.document-html').attr('data-fetched', "1");
+						}
+					},
+					freeze: true
+				});
+			}
+		}
+	});
+
+	this.page.main.on("click", ".btn-less", function() {
+		var docname = $(this).attr("data-docname");
+		me.page.main.find("."+docname).parent().find('.document-id').show();
+		me.page.main.find("."+docname).parent().find('.document-html').hide();
+	});
+	me.start = 0;
+	me.page.main.on("click", ".btn-get-records", function(){
+		get_documents(patient.get_value(), me);
+	});
+};
+
+var get_documents = function(patient, me){
+	frappe.call({
+		"method": "erpnext.healthcare.page.patient_history.patient_history.get_feed",
+		args: {
+			name: patient,
+			start: me.start,
+			page_length: 20
+		},
+		callback: function (r) {
+			var data = r.message;
+			if(data.length){
+				add_to_records(me, data);
+			}else{
+				me.page.main.find(".patient_documents_list").append("<div class='text-muted' align='center'><br><br>No more records..<br><br></div>");
+				me.page.main.find(".btn-get-records").hide();
+			}
+		}
+	});
+};
+
+var add_to_records = function(me, data){
+	var details = "<ul class='nav nav-pills nav-stacked'>";
+	var i;
+	for(i=0; i<data.length; i++){
+		if(data[i].reference_doctype){
+			let label = '';
+			if(data[i].subject){
+				label += "<br/>"+data[i].subject;
+			}
+			data[i] = add_date_separator(data[i]);
+			if(frappe.user_info(data[i].owner).image){
+				data[i].imgsrc = frappe.utils.get_file_link(frappe.user_info(data[i].owner).image);
+			}
+			else{
+				data[i].imgsrc = false;
+			}
+			var time_line_heading = data[i].practitioner ? `${data[i].practitioner} ` : ``;
+			time_line_heading += data[i].reference_doctype + " - "+ data[i].reference_name;
+			details += `<li data-toggle='pill' class='patient_doc_menu'
+			data-doctype='${data[i].reference_doctype}' data-docname='${data[i].reference_name}'>
+			<div class='col-sm-12 d-flex border-bottom py-3'>`;
+			if (data[i].imgsrc){
+				details += `<span class='mr-3'>
+					<img class='avtar' src='${data[i].imgsrc}' width='32' height='32'>
+					</img>
+			</span>`;
+			}else{
+				details += `<span class='mr-3 avatar avatar-small' style='width:32px; height:32px;'><div align='center' class='standard-image'
+					style='background-color: #fafbfc;'>${data[i].practitioner ? data[i].practitioner.charAt(0) : "U"}</div></span>`;
+			}
+			details += `<div class='d-flex flex-column width-full'>
+					<div>
+						`+time_line_heading+` on
+							<span>
+								${data[i].date_sep}
+							</span>
+					</div>
+					<div class='Box p-3 mt-2'>
+						<span class='${data[i].reference_name} document-id'>${label}
+							<div align='center'>
+								<a class='btn octicon octicon-chevron-down btn-default btn-xs btn-more'
+									data-doctype='${data[i].reference_doctype}' data-docname='${data[i].reference_name}'>
+								</a>
+							</div>
+						</span>
+						<span class='document-html' hidden  data-fetched="0">
+						</span>
+					</div>
+				</div>
+			</div>
+			</li>`;
+		}
+	}
+	details += "</ul>";
+	me.page.main.find(".patient_documents_list").append(details);
+	me.start += data.length;
+	if(data.length===20){
+		me.page.main.find(".btn-get-records").show();
+	}else{
+		me.page.main.find(".btn-get-records").hide();
+		me.page.main.find(".patient_documents_list").append("<div class='text-muted' align='center'><br><br>No more records..<br><br></div>");
+	}
+};
+
+var add_date_separator = function(data) {
+	var date = frappe.datetime.str_to_obj(data.creation);
+
+	var diff = frappe.datetime.get_day_diff(frappe.datetime.get_today(), frappe.datetime.obj_to_str(date));
+	if(diff < 1) {
+		var pdate = 'Today';
+	} else if(diff < 2) {
+		pdate = 'Yesterday';
+	} else {
+		pdate = frappe.datetime.global_date_format(date);
+	}
+	data.date_sep = pdate;
+	return data;
+};
+
+var show_patient_info = function(patient, me){
+	frappe.call({
+		"method": "erpnext.healthcare.doctype.patient.patient.get_patient_detail",
+		args: {
+			patient: patient
+		},
+		callback: function (r) {
+			var data = r.message;
+			var details = "";
+			if(data.image){
+				details += "<div><img class='thumbnail' width=75% src='"+data.image+"'></div>";
+			}
+			details += "<b>" + data.patient_name +"</b><br>" + data.sex;
+			if(data.email) details += "<br>" + data.email;
+			if(data.mobile) details += "<br>" + data.mobile;
+			if(data.occupation) details += "<br><br><b>Occupation :</b> " + data.occupation;
+			if(data.blood_group) details += "<br><b>Blood group : </b> " + data.blood_group;
+			if(data.allergies) details +=  "<br><br><b>Allergies : </b> "+  data.allergies.replace("\n", "<br>");
+			if(data.medication) details +=  "<br><b>Medication : </b> "+  data.medication.replace("\n", "<br>");
+			if(data.alcohol_current_use) details +=  "<br><br><b>Alcohol use : </b> "+  data.alcohol_current_use;
+			if(data.alcohol_past_use) details +=  "<br><b>Alcohol past use : </b> "+  data.alcohol_past_use;
+			if(data.tobacco_current_use) details +=  "<br><b>Tobacco use : </b> "+  data.tobacco_current_use;
+			if(data.tobacco_past_use) details +=  "<br><b>Tobacco past use : </b> "+  data.tobacco_past_use;
+			if(data.medical_history) details +=  "<br><br><b>Medical history : </b> "+  data.medical_history.replace("\n", "<br>");
+			if(data.surgical_history) details +=  "<br><b>Surgical history : </b> "+  data.surgical_history.replace("\n", "<br>");
+			if(data.surrounding_factors) details +=  "<br><br><b>Occupational hazards : </b> "+  data.surrounding_factors.replace("\n", "<br>");
+			if(data.other_risk_factors) details += "<br><b>Other risk factors : </b> " + data.other_risk_factors.replace("\n", "<br>");
+			if(data.patient_details) details += "<br><br><b>More info : </b> " + data.patient_details.replace("\n", "<br>");
+
+			if(details){
+				details = "<div style='padding-left:10px; font-size:13px;' align='center'>" + details + "</div>";
+			}
+			me.page.main.find(".patient_details").html(details);
+		}
+	});
+};
+
+var show_patient_vital_charts = function(patient, me, btn_show_id, pts, title) {
+	frappe.call({
+		method: "erpnext.healthcare.utils.get_patient_vitals",
+		args:{
+			patient: patient
+		},
+		callback: function(r) {
+			if (r.message){
+				var show_chart_btns_html = "<div style='padding-top:5px;'><a class='btn btn-default btn-xs btn-show-chart' \
+				data-show-chart-id='bp' data-pts='mmHg' data-title='Blood Pressure'>Blood Pressure</a>\
+				<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='pulse_rate' \
+				data-pts='per Minutes' data-title='Respiratory/Pulse Rate'>Respiratory/Pulse Rate</a>\
+				<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='temperature' \
+				data-pts='°C or °F' data-title='Temperature'>Temperature</a>\
+				<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='bmi' \
+				data-pts='bmi' data-title='BMI'>BMI</a></div>";
+				me.page.main.find(".show_chart_btns").html(show_chart_btns_html);
+				var data = r.message;
+				let labels = [], datasets = [];
+				let bp_systolic = [], bp_diastolic = [], temperature = [];
+				let pulse = [], respiratory_rate = [], bmi = [], height = [], weight = [];
+				for(var i=0; i<data.length; i++){
+					labels.push(data[i].signs_date+"||"+data[i].signs_time);
+					if(btn_show_id=="bp"){
+						bp_systolic.push(data[i].bp_systolic);
+						bp_diastolic.push(data[i].bp_diastolic);
+					}
+					if(btn_show_id=="temperature"){
+						temperature.push(data[i].temperature);
+					}
+					if(btn_show_id=="pulse_rate"){
+						pulse.push(data[i].pulse);
+						respiratory_rate.push(data[i].respiratory_rate);
+					}
+					if(btn_show_id=="bmi"){
+						bmi.push(data[i].bmi);
+						height.push(data[i].height);
+						weight.push(data[i].weight);
+					}
+				}
+				if(btn_show_id=="temperature"){
+					datasets.push({name: "Temperature", values: temperature, chartType:'line'});
+				}
+				if(btn_show_id=="bmi"){
+					datasets.push({name: "BMI", values: bmi, chartType:'line'});
+					datasets.push({name: "Height", values: height, chartType:'line'});
+					datasets.push({name: "Weight", values: weight, chartType:'line'});
+				}
+				if(btn_show_id=="bp"){
+					datasets.push({name: "BP Systolic", values: bp_systolic, chartType:'line'});
+					datasets.push({name: "BP Diastolic", values: bp_diastolic, chartType:'line'});
+				}
+				if(btn_show_id=="pulse_rate"){
+					datasets.push({name: "Heart Rate / Pulse", values: pulse, chartType:'line'});
+					datasets.push({name: "Respiratory Rate", values: respiratory_rate, chartType:'line'});
+				}
+				new Chart( ".patient_vital_charts", {
+					data: {
+						labels: labels,
+						datasets: datasets
+					},
+
+					title: title,
+					type: 'axis-mixed', // 'axis-mixed', 'bar', 'line', 'pie', 'percentage'
+					height: 150,
+					colors: ['purple', '#ffa3ef', 'light-blue'],
+
+					tooltipOptions: {
+						formatTooltipX: d => (d + '').toUpperCase(),
+						formatTooltipY: d => d + ' ' + pts,
+					}
+				});
+			}else{
+				me.page.main.find(".patient_vital_charts").html("");
+				me.page.main.find(".show_chart_btns").html("");
+			}
+		}
+	});
+};
diff --git a/erpnext/healthcare/page/patient_history/patient_history.json b/erpnext/healthcare/page/patient_history/patient_history.json
new file mode 100644
index 0000000..b3892a4
--- /dev/null
+++ b/erpnext/healthcare/page/patient_history/patient_history.json
@@ -0,0 +1,28 @@
+{
+ "content": null, 
+ "creation": "2018-08-08 17:09:13.816199", 
+ "docstatus": 0, 
+ "doctype": "Page", 
+ "icon": "", 
+ "idx": 0, 
+ "modified": "2018-08-08 17:09:55.969424", 
+ "modified_by": "Administrator", 
+ "module": "Healthcare", 
+ "name": "patient_history", 
+ "owner": "Administrator", 
+ "page_name": "patient_history", 
+ "restrict_to_domain": "Healthcare", 
+ "roles": [
+  {
+   "role": "Healthcare Administrator"
+  }, 
+  {
+   "role": "Physician"
+  }
+ ], 
+ "script": null, 
+ "standard": "Yes", 
+ "style": null, 
+ "system_page": 0, 
+ "title": "Patient History"
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/page/patient_history/patient_history.py b/erpnext/healthcare/page/patient_history/patient_history.py
new file mode 100644
index 0000000..772aa4e
--- /dev/null
+++ b/erpnext/healthcare/page/patient_history/patient_history.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, ESS LLP and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.utils import cint
+from erpnext.healthcare.utils import render_docs_as_html
+
+@frappe.whitelist()
+def get_feed(name, start=0, page_length=20):
+	"""get feed"""
+	result = frappe.db.sql("""select name, owner, creation,
+		reference_doctype, reference_name, subject
+		from `tabPatient Medical Record`
+		where patient=%(patient)s
+		order by creation desc
+		limit %(start)s, %(page_length)s""",
+		{
+			"patient": name,
+			"start": cint(start),
+			"page_length": cint(page_length)
+		}, as_dict=True)
+	return result
+
+@frappe.whitelist()
+def get_feed_for_dt(doctype, docname):
+	"""get feed"""
+	result = frappe.db.sql("""select name, owner, modified, creation,
+			reference_doctype, reference_name, subject
+		from `tabPatient Medical Record`
+		where reference_name=%(docname)s and reference_doctype=%(doctype)s
+		order by creation desc""",
+		{
+			"docname": docname,
+			"doctype": doctype
+		}, as_dict=True)
+
+	return result
diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py
index 6a226d9..97bb98f 100644
--- a/erpnext/healthcare/utils.py
+++ b/erpnext/healthcare/utils.py
@@ -429,3 +429,116 @@
 					occupancy_msg = str(occupied) + " Occupied out of " + str(occupancy_total)
 			each["occupied_out_of_vacant"] = occupancy_msg
 	return hc_service_units
+
+@frappe.whitelist()
+def get_patient_vitals(patient, from_date=None, to_date=None):
+	if not patient: return
+	vitals = frappe.db.sql("""select * from `tabVital Signs` where \
+	docstatus=1 and patient=%s order by signs_date, signs_time""", \
+	(patient), as_dict=1)
+	if vitals and vitals[0]:
+		return vitals
+	else:
+		return False
+
+@frappe.whitelist()
+def render_docs_as_html(docs):
+	# docs key value pair {doctype: docname}
+	docs_html = "<div class='col-md-12 col-sm-12 text-muted'>"
+	for doc in docs:
+		docs_html += render_doc_as_html(doc['doctype'], doc['docname'])['html'] + "<br/>"
+		return {'html': docs_html}
+
+@frappe.whitelist()
+def render_doc_as_html(doctype, docname, exclude_fields = []):
+	#render document as html, three column layout will break
+	doc = frappe.get_doc(doctype, docname)
+	meta = frappe.get_meta(doctype)
+	doc_html = "<div class='col-md-12 col-sm-12'>"
+	section_html = ""
+	section_label = ""
+	html = ""
+	sec_on = False
+	col_on = 0
+	has_data = False
+	for df in meta.fields:
+		#on section break append append previous section and html to doc html
+		if df.fieldtype == "Section Break":
+			if has_data and col_on and sec_on:
+				doc_html += section_html + html + "</div>"
+			elif has_data and not col_on and sec_on:
+				doc_html += "<div class='col-md-12 col-sm-12'\
+				><div class='col-md-12 col-sm-12'>" \
+				+ section_html + html +"</div></div>"
+			while col_on:
+				doc_html += "</div>"
+				col_on -= 1
+			sec_on = True
+			has_data= False
+			col_on = 0
+			section_html = ""
+			html = ""
+			if df.label:
+				section_label = df.label
+			continue
+		#on column break append html to section html or doc html
+		if df.fieldtype == "Column Break":
+			if sec_on and has_data:
+				section_html += "<div class='col-md-12 col-sm-12'\
+				><div class='col-md-6 col\
+				-sm-6'><b>" + section_label + "</b>" + html + "</div><div \
+				class='col-md-6 col-sm-6'>"
+			elif has_data:
+				doc_html += "<div class='col-md-12 col-sm-12'><div class='col-m\
+				d-6 col-sm-6'>" + html + "</div><div class='col-md-6 col-sm-6'>"
+			elif sec_on and not col_on:
+				section_html += "<div class='col-md-6 col-sm-6'>"
+			html = ""
+			col_on += 1
+			if df.label:
+				html += '<br>' + df.label
+			continue
+		#on table iterate in items and create table based on in_list_view, append to section html or doc html
+		if df.fieldtype == "Table":
+			items = doc.get(df.fieldname)
+			if not items: continue
+			child_meta = frappe.get_meta(df.options)
+			if not has_data : has_data = True
+			table_head = ""
+			table_row = ""
+			create_head = True
+			for item in items:
+				table_row += '<tr>'
+				for cdf in child_meta.fields:
+					if cdf.in_list_view:
+						if create_head:
+							table_head += '<th>' + cdf.label + '</th>'
+						if item.get(cdf.fieldname):
+							table_row += '<td>' + str(item.get(cdf.fieldname)) \
+							+ '</td>'
+						else:
+							table_row += '<td></td>'
+				create_head = False
+				table_row += '</tr>'
+			if sec_on:
+				section_html += '<table class="table table-condensed \
+				bordered">' + table_head +  table_row + '</table>'
+			else:
+				html += '<table class="table table-condensed table-bordered">' \
+				+ table_head +  table_row + '</table>'
+			continue
+		#on other field types add label and value to html
+		if not df.hidden and not df.print_hide and doc.get(df.fieldname) and df.fieldname not in exclude_fields:
+			html +=  "<br>{0} : {1}".format(df.label or df.fieldname, \
+			doc.get(df.fieldname))
+			if not has_data : has_data = True
+	if sec_on and col_on and has_data:
+		doc_html += section_html + html + "</div></div>"
+	elif sec_on and not col_on and has_data:
+		doc_html += "<div class='col-md-12 col-sm-12'\
+		><div class='col-md-12 col-sm-12'>" \
+		+ section_html + html +"</div></div>"
+	if doc_html:
+		doc_html = "<div class='small'><div class='col-md-12 text-right'><a class='btn btn-default btn-xs' href='#Form/%s/%s'></a></div>" %(doctype, docname) + doc_html + "</div>"
+
+	return {'html': doc_html}
diff --git a/erpnext/hr/doctype/employee_loan_application/employee_loan_application.py b/erpnext/hr/doctype/employee_loan_application/employee_loan_application.py
deleted file mode 100644
index b6c6502..0000000
--- a/erpnext/hr/doctype/employee_loan_application/employee_loan_application.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-import frappe, math
-from frappe import _
-from frappe.utils import flt, rounded
-from frappe.model.mapper import get_mapped_doc
-from frappe.model.document import Document
-
-from erpnext.hr.doctype.employee_loan.employee_loan import get_monthly_repayment_amount, check_repayment_method
-
-class EmployeeLoanApplication(Document):
-	def validate(self):
-		check_repayment_method(self.repayment_method, self.loan_amount, self.repayment_amount, self.repayment_periods)
-		self.validate_loan_amount()
-		self.get_repayment_details()
-
-	def validate_loan_amount(self):
-		maximum_loan_limit = frappe.db.get_value('Loan Type', self.loan_type, 'maximum_loan_amount')
-		if maximum_loan_limit and self.loan_amount > maximum_loan_limit:
-			frappe.throw(_("Loan Amount cannot exceed Maximum Loan Amount of {0}").format(maximum_loan_limit))
-
-	def get_repayment_details(self):
-		if self.repayment_method == "Repay Over Number of Periods":
-			self.repayment_amount = get_monthly_repayment_amount(self.repayment_method, self.loan_amount, self.rate_of_interest, self.repayment_periods)
-
-		if self.repayment_method == "Repay Fixed Amount per Period":
-			monthly_interest_rate = flt(self.rate_of_interest) / (12 *100)
-			if monthly_interest_rate:
-				monthly_interest_amount = self.loan_amount * monthly_interest_rate
-				if monthly_interest_amount >= self.repayment_amount:
-					frappe.throw(_("Repayment amount {} should be greater than monthly interest amount {}").
-						format(self.repayment_amount, monthly_interest_amount))
-
-				self.repayment_periods = math.ceil((math.log(self.repayment_amount) - 
-					math.log(self.repayment_amount - (monthly_interest_amount))) /
-					(math.log(1 + monthly_interest_rate)))
-			else:
-				self.repayment_periods = self.loan_amount / self.repayment_amount
-
-		self.calculate_payable_amount()
-		
-	def calculate_payable_amount(self):
-		balance_amount = self.loan_amount
-		self.total_payable_amount = 0
-		self.total_payable_interest = 0
-
-		while(balance_amount > 0):
-			interest_amount = rounded(balance_amount * flt(self.rate_of_interest) / (12*100))
-			balance_amount = rounded(balance_amount + interest_amount - self.repayment_amount)
-
-			self.total_payable_interest += interest_amount
-			
-		self.total_payable_amount = self.loan_amount + self.total_payable_interest
-		
-@frappe.whitelist()
-def make_employee_loan(source_name, target_doc = None):
-	doclist = get_mapped_doc("Employee Loan Application", source_name, {
-		"Employee Loan Application": {
-			"doctype": "Employee Loan",
-			"validation": {
-				"docstatus": ["=", 1]
-			}
-		}
-	}, target_doc)
-
-	return doclist
\ No newline at end of file
diff --git a/erpnext/hr/doctype/loan/loan.js b/erpnext/hr/doctype/loan/loan.js
index e1b4178..3f5c30c 100644
--- a/erpnext/hr/doctype/loan/loan.js
+++ b/erpnext/hr/doctype/loan/loan.js
@@ -39,31 +39,19 @@
 	},
 
 	refresh: function (frm) {
-		if (frm.doc.docstatus == 1 && frm.doc.status == "Sanctioned") {
-			frm.add_custom_button(__('Create Disbursement Entry'), function() {
-				frm.trigger("make_jv");
-			})
-		}
-		if (frm.doc.repayment_schedule) {
-			let total_amount_paid = 0;
-			$.each(frm.doc.repayment_schedule || [], function(i, row) {
-				if (row.paid) {
-					total_amount_paid += row.total_payment;
-				}
-			});
-			frm.set_value("total_amount_paid", total_amount_paid);
-;		}
-		if (frm.doc.docstatus == 1 && frm.doc.repayment_start_date && (frm.doc.applicant_type == 'Member' || frm.doc.repay_from_salary == 0)) {
-			frm.add_custom_button(__('Create Repayment Entry'), function() {
-				frm.trigger("make_repayment_entry");
-			})
+		if (frm.doc.docstatus == 1) {
+			if (frm.doc.status == "Sanctioned") {
+				frm.add_custom_button(__('Create Disbursement Entry'), function() {
+					frm.trigger("make_jv");
+				}).addClass("btn-primary");
+			} else if (frm.doc.status == "Disbursed" && frm.doc.repayment_start_date && (frm.doc.applicant_type == 'Member' || frm.doc.repay_from_salary == 0)) {
+				frm.add_custom_button(__('Create Repayment Entry'), function() {
+					frm.trigger("make_repayment_entry");
+				}).addClass("btn-primary");
+			}
 		}
 		frm.trigger("toggle_fields");
 	},
-	status: function (frm) {
-		frm.toggle_reqd("disbursement_date", frm.doc.status == 'Disbursed')
-		frm.toggle_reqd("repayment_start_date", frm.doc.status == 'Disbursed')
-	},
 
 	make_jv: function (frm) {
 		frappe.call({
diff --git a/erpnext/hr/doctype/loan/loan.json b/erpnext/hr/doctype/loan/loan.json
index 587b301..505b601 100644
--- a/erpnext/hr/doctype/loan/loan.json
+++ b/erpnext/hr/doctype/loan/loan.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
  "allow_guest_to_view": 0, 
  "allow_import": 1, 
  "allow_rename": 0, 
@@ -20,6 +21,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "applicant_type", 
    "fieldtype": "Select", 
    "hidden": 0, 
@@ -53,6 +55,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "applicant", 
    "fieldtype": "Dynamic Link", 
    "hidden": 0, 
@@ -86,6 +89,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "applicant_name", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -118,6 +122,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "loan_application", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -151,6 +156,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "loan_type", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -184,6 +190,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "column_break_3", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -215,7 +222,8 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "default": "", 
+   "default": "Today", 
+   "fetch_if_empty": 0, 
    "fieldname": "posting_date", 
    "fieldtype": "Date", 
    "hidden": 0, 
@@ -248,6 +256,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "company", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -282,6 +291,7 @@
    "collapsible": 0, 
    "columns": 0, 
    "default": "Sanctioned", 
+   "fetch_if_empty": 0, 
    "fieldname": "status", 
    "fieldtype": "Select", 
    "hidden": 0, 
@@ -299,7 +309,7 @@
    "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -316,6 +326,7 @@
    "collapsible": 0, 
    "columns": 0, 
    "depends_on": "eval:doc.applicant_type==\"Employee\"", 
+   "fetch_if_empty": 0, 
    "fieldname": "repay_from_salary", 
    "fieldtype": "Check", 
    "hidden": 0, 
@@ -348,6 +359,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "section_break_8", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -380,6 +392,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "loan_amount", 
    "fieldtype": "Currency", 
    "hidden": 0, 
@@ -415,6 +428,7 @@
    "columns": 0, 
    "default": "", 
    "fetch_from": "loan_type.rate_of_interest", 
+   "fetch_if_empty": 0, 
    "fieldname": "rate_of_interest", 
    "fieldtype": "Percent", 
    "hidden": 0, 
@@ -448,6 +462,8 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "depends_on": "eval:doc.status==\"Disbursed\"", 
+   "fetch_if_empty": 0, 
    "fieldname": "disbursement_date", 
    "fieldtype": "Date", 
    "hidden": 0, 
@@ -480,6 +496,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "repayment_start_date", 
    "fieldtype": "Date", 
    "hidden": 0, 
@@ -499,7 +516,7 @@
    "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
-   "reqd": 0, 
+   "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
    "translatable": 0, 
@@ -512,6 +529,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "column_break_11", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -544,6 +562,7 @@
    "collapsible": 0, 
    "columns": 0, 
    "default": "Repay Over Number of Periods", 
+   "fetch_if_empty": 0, 
    "fieldname": "repayment_method", 
    "fieldtype": "Select", 
    "hidden": 0, 
@@ -579,6 +598,7 @@
    "columns": 0, 
    "default": "", 
    "depends_on": "", 
+   "fetch_if_empty": 0, 
    "fieldname": "repayment_periods", 
    "fieldtype": "Int", 
    "hidden": 0, 
@@ -613,6 +633,7 @@
    "columns": 0, 
    "default": "", 
    "depends_on": "", 
+   "fetch_if_empty": 0, 
    "fieldname": "monthly_repayment_amount", 
    "fieldtype": "Currency", 
    "hidden": 0, 
@@ -646,6 +667,7 @@
    "bold": 0, 
    "collapsible": 1, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "account_info", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -678,6 +700,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "mode_of_payment", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -711,6 +734,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "payment_account", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -744,6 +768,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "column_break_9", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -775,6 +800,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "loan_account", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -808,6 +834,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "interest_income_account", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -841,6 +868,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "section_break_15", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -873,6 +901,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "repayment_schedule", 
    "fieldtype": "Table", 
    "hidden": 0, 
@@ -906,6 +935,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "section_break_17", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -939,6 +969,7 @@
    "collapsible": 0, 
    "columns": 0, 
    "default": "0", 
+   "fetch_if_empty": 0, 
    "fieldname": "total_payment", 
    "fieldtype": "Currency", 
    "hidden": 0, 
@@ -972,6 +1003,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "column_break_19", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -1004,6 +1036,7 @@
    "collapsible": 0, 
    "columns": 0, 
    "default": "0", 
+   "fetch_if_empty": 0, 
    "fieldname": "total_interest_payable", 
    "fieldtype": "Currency", 
    "hidden": 0, 
@@ -1037,6 +1070,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "total_amount_paid", 
    "fieldtype": "Currency", 
    "hidden": 0, 
@@ -1070,6 +1104,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "amended_from", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -1106,7 +1141,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-21 16:15:53.267145", 
+ "modified": "2019-07-10 13:04:20.953694", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Loan", 
@@ -1149,7 +1184,6 @@
    "set_user_permissions": 0, 
    "share": 0, 
    "submit": 0, 
-   "user_permission_doctypes": "[\"Employee\"]", 
    "write": 0
   }
  ], 
diff --git a/erpnext/hr/doctype/loan/loan.py b/erpnext/hr/doctype/loan/loan.py
index 58c9b8f..a803863 100644
--- a/erpnext/hr/doctype/loan/loan.py
+++ b/erpnext/hr/doctype/loan/loan.py
@@ -6,29 +6,33 @@
 import frappe, math, json
 import erpnext
 from frappe import _
-from frappe.utils import flt, rounded, add_months, nowdate
+from frappe.utils import flt, rounded, add_months, nowdate, getdate
 from erpnext.controllers.accounts_controller import AccountsController
 
 class Loan(AccountsController):
 	def validate(self):
-		check_repayment_method(self.repayment_method, self.loan_amount, self.monthly_repayment_amount, self.repayment_periods)
+		validate_repayment_method(self.repayment_method, self.loan_amount, self.monthly_repayment_amount, self.repayment_periods)
+		self.set_missing_fields()
+		self.make_repayment_schedule()
+		self.set_repayment_period()
+		self.calculate_totals()
+
+	def set_missing_fields(self):
 		if not self.company:
 			self.company = erpnext.get_default_company()
+
 		if not self.posting_date:
 			self.posting_date = nowdate()
+
 		if self.loan_type and not self.rate_of_interest:
 			self.rate_of_interest = frappe.db.get_value("Loan Type", self.loan_type, "rate_of_interest")
+
 		if self.repayment_method == "Repay Over Number of Periods":
 			self.monthly_repayment_amount = get_monthly_repayment_amount(self.repayment_method, self.loan_amount, self.rate_of_interest, self.repayment_periods)
+
 		if self.status == "Repaid/Closed":
 			self.total_amount_paid = self.total_payment
-		if self.status == 'Disbursed' and self.repayment_start_date < self.disbursement_date:
-			frappe.throw(_("Repayment Start Date cannot be before Disbursement Date."))
 
-		if self.status == "Disbursed":
-			self.make_repayment_schedule()
-			self.set_repayment_period()
-			self.calculate_totals()
 
 	def make_jv_entry(self):
 		self.check_permission('write')
@@ -105,20 +109,31 @@
 	frappe.db.set_value("Loan", doc.name, "total_amount_paid", total_amount_paid)
 
 def update_disbursement_status(doc):
-	disbursement = frappe.db.sql("""select posting_date, ifnull(sum(credit_in_account_currency), 0) as disbursed_amount
-		from `tabGL Entry` where account = %s and against_voucher_type = 'Loan' and against_voucher = %s""",
-		(doc.payment_account, doc.name), as_dict=1)[0]
-	if disbursement.disbursed_amount == doc.loan_amount:
-		frappe.db.set_value("Loan", doc.name , "status", "Disbursed")
-	if disbursement.disbursed_amount == 0:
-		frappe.db.set_value("Loan", doc.name , "status", "Sanctioned")
-	if disbursement.disbursed_amount > doc.loan_amount:
-		frappe.throw(_("Disbursed Amount cannot be greater than Loan Amount {0}").format(doc.loan_amount))
-	if disbursement.disbursed_amount > 0:
-		frappe.db.set_value("Loan", doc.name , "disbursement_date", disbursement.posting_date)
-		frappe.db.set_value("Loan", doc.name , "repayment_start_date", disbursement.posting_date)
+	disbursement = frappe.db.sql("""
+		select posting_date, ifnull(sum(credit_in_account_currency), 0) as disbursed_amount
+		from `tabGL Entry`
+		where account = %s and against_voucher_type = 'Loan' and against_voucher = %s
+	""", (doc.payment_account, doc.name), as_dict=1)[0]
 
-def check_repayment_method(repayment_method, loan_amount, monthly_repayment_amount, repayment_periods):
+	disbursement_date = None
+	if not disbursement or disbursement.disbursed_amount == 0:
+		status = "Sanctioned"
+	elif disbursement.disbursed_amount == doc.loan_amount:
+		disbursement_date = disbursement.posting_date
+		status = "Disbursed"
+	elif disbursement.disbursed_amount > doc.loan_amount:
+		frappe.throw(_("Disbursed Amount cannot be greater than Loan Amount {0}").format(doc.loan_amount))
+
+	if status == 'Disbursed' and getdate(disbursement_date) > getdate(frappe.db.get_value("Loan", doc.name, "repayment_start_date")):
+			frappe.throw(_("Disbursement Date cannot be after Loan Repayment Start Date"))
+
+	frappe.db.sql("""
+		update `tabLoan`
+		set status = %s, disbursement_date = %s
+		where name = %s
+	""", (status, disbursement_date, doc.name))
+
+def validate_repayment_method(repayment_method, loan_amount, monthly_repayment_amount, repayment_periods):
 	if repayment_method == "Repay Over Number of Periods" and not repayment_periods:
 		frappe.throw(_("Please enter Repayment Periods"))
 
@@ -222,4 +237,4 @@
 		"reference_name": loan,
 		})
 	journal_entry.set("accounts", account_amt_list)
-	return journal_entry.as_dict()
\ No newline at end of file
+	return journal_entry.as_dict()
diff --git a/erpnext/hr/doctype/loan_application/loan_application.js b/erpnext/hr/doctype/loan_application/loan_application.js
index febcbd8..a73b62a 100644
--- a/erpnext/hr/doctype/loan_application/loan_application.js
+++ b/erpnext/hr/doctype/loan_application/loan_application.js
@@ -23,9 +23,8 @@
 	},
 	add_toolbar_buttons: function(frm) {
 		if (frm.doc.status == "Approved") {
-			frm.add_custom_button(__('Loan'), function() {
+			frm.add_custom_button(__('Create Loan'), function() {
 				frappe.call({
-					type: "GET",
 					method: "erpnext.hr.doctype.loan_application.loan_application.make_loan",
 					args: {
 						"source_name": frm.doc.name
@@ -37,7 +36,7 @@
 						}
 					}
 				});
-			})
+			}).addClass("btn-primary");
 		}
 	}
 });
diff --git a/erpnext/hr/doctype/loan_application/loan_application.py b/erpnext/hr/doctype/loan_application/loan_application.py
index 706c964..5dbcf15 100644
--- a/erpnext/hr/doctype/loan_application/loan_application.py
+++ b/erpnext/hr/doctype/loan_application/loan_application.py
@@ -9,11 +9,11 @@
 from frappe.model.mapper import get_mapped_doc
 from frappe.model.document import Document
 
-from erpnext.hr.doctype.loan.loan import get_monthly_repayment_amount, check_repayment_method
+from erpnext.hr.doctype.loan.loan import get_monthly_repayment_amount, validate_repayment_method
 
 class LoanApplication(Document):
 	def validate(self):
-		check_repayment_method(self.repayment_method, self.loan_amount, self.repayment_amount, self.repayment_periods)
+		validate_repayment_method(self.repayment_method, self.loan_amount, self.repayment_amount, self.repayment_periods)
 		self.validate_loan_amount()
 		self.get_repayment_details()
 
@@ -29,14 +29,14 @@
 		if self.repayment_method == "Repay Fixed Amount per Period":
 			monthly_interest_rate = flt(self.rate_of_interest) / (12 *100)
 			if monthly_interest_rate:
-				self.repayment_periods = math.ceil((math.log(self.repayment_amount) - 
+				self.repayment_periods = math.ceil((math.log(self.repayment_amount) -
 					math.log(self.repayment_amount - (self.loan_amount*monthly_interest_rate))) /
 					(math.log(1 + monthly_interest_rate)))
 			else:
 				self.repayment_periods = self.loan_amount / self.repayment_amount
 
 		self.calculate_payable_amount()
-		
+
 	def calculate_payable_amount(self):
 		balance_amount = self.loan_amount
 		self.total_payable_amount = 0
@@ -47,9 +47,9 @@
 			balance_amount = rounded(balance_amount + interest_amount - self.repayment_amount)
 
 			self.total_payable_interest += interest_amount
-			
+
 		self.total_payable_amount = self.loan_amount + self.total_payable_interest
-		
+
 @frappe.whitelist()
 def make_loan(source_name, target_doc = None):
 	doclist = get_mapped_doc("Loan Application", source_name, {
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 75eb794..766f675 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -594,6 +594,7 @@
 				sum(bom_item.{qty_field}/ifnull(bom.quantity, 1)) * %(qty)s as qty,
 				item.description,
 				item.image,
+				bom.project,
 				item.stock_uom,
 				item.allow_alternative_item,
 				item_default.default_warehouse,
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 571c2dc..a293785 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -605,6 +605,7 @@
 erpnext.patches.v12_0.make_custom_fields_for_bank_remittance #14-06-2019
 execute:frappe.delete_doc_if_exists("Page", "support-analytics")
 erpnext.patches.v12_0.make_item_manufacturer
+erpnext.patches.v12_0.remove_patient_medical_record_page
 erpnext.patches.v11_1.move_customer_lead_to_dynamic_column
 erpnext.patches.v11_1.set_default_action_for_quality_inspection
 erpnext.patches.v11_1.delete_bom_browser
diff --git a/erpnext/patches/v12_0/remove_patient_medical_record_page.py b/erpnext/patches/v12_0/remove_patient_medical_record_page.py
new file mode 100644
index 0000000..904bfe4
--- /dev/null
+++ b/erpnext/patches/v12_0/remove_patient_medical_record_page.py
@@ -0,0 +1,7 @@
+# Copyright (c) 2019
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	frappe.delete_doc("Page", "medical_record")
diff --git a/erpnext/patches/v12_0/set_priority_for_support.py b/erpnext/patches/v12_0/set_priority_for_support.py
index cc29039..5096ed4 100644
--- a/erpnext/patches/v12_0/set_priority_for_support.py
+++ b/erpnext/patches/v12_0/set_priority_for_support.py
@@ -33,19 +33,23 @@
 		service_level_priorities = frappe.get_list("Service Level", fields=["name", "priority", "response_time", "response_time_period", "resolution_time", "resolution_time_period"])
 
 		frappe.reload_doc("support", "doctype", "service_level")
+		frappe.reload_doc("support", "doctype", "support_settings")
+		frappe.db.set_value('Support Settings', None, 'track_service_level_agreement', 1)
 
 		for service_level in service_level_priorities:
 			if service_level:
 				doc = frappe.get_doc("Service Level", service_level.name)
-				doc.append("priorities", {
-					"priority": service_level.priority,
-					"default_priority": 1,
-					"response_time": service_level.response_time,
-					"response_time_period": service_level.response_time_period,
-					"resolution_time": service_level.resolution_time,
-					"resolution_time_period": service_level.resolution_time_period
-				})
-				doc.save(ignore_permissions=True)
+				if not doc.priorities:
+					doc.append("priorities", {
+						"priority": service_level.priority,
+						"default_priority": 1,
+						"response_time": service_level.response_time,
+						"response_time_period": service_level.response_time_period,
+						"resolution_time": service_level.resolution_time,
+						"resolution_time_period": service_level.resolution_time_period
+					})
+					doc.flags.ignore_validate = True
+					doc.save(ignore_permissions=True)
 	except frappe.db.TableMissingError:
 		frappe.reload_doc("support", "doctype", "service_level")
 
@@ -73,6 +77,7 @@
 					"resolution_time": service_level_agreement.resolution_time,
 					"resolution_time_period": service_level_agreement.resolution_time_period
 				})
+				doc.flags.ignore_validate = True
 				doc.save(ignore_permissions=True)
 	except frappe.db.TableMissingError:
 		frappe.reload_doc("support", "doctype", "service_level_agreement")
\ No newline at end of file
diff --git a/erpnext/patches/v12_0/update_due_date_in_gle.py b/erpnext/patches/v12_0/update_due_date_in_gle.py
index 4c47a82..3484872 100644
--- a/erpnext/patches/v12_0/update_due_date_in_gle.py
+++ b/erpnext/patches/v12_0/update_due_date_in_gle.py
@@ -13,5 +13,5 @@
             WHERE
                 `tabGL Entry`.voucher_no = `tab{doctype}`.name and `tabGL Entry`.party is not null
                 and `tabGL Entry`.voucher_type in ('Sales Invoice', 'Purchase Invoice', 'Journal Entry')
-                and account in (select name from `tabAccount` where account_type in ('Receivable', 'Payable') )""" #nosec
+                and `tabGL Entry`.account in (select name from `tabAccount` where account_type in ('Receivable', 'Payable'))""" #nosec
             .format(doctype=doctype))
diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js
index ec71df3..095e744 100644
--- a/erpnext/public/js/conf.js
+++ b/erpnext/public/js/conf.js
@@ -52,3 +52,13 @@
 	"Sales Partner": "Selling",
 	"Brand": "Selling"
 });
+
+$.extend(frappe.breadcrumbs.module_map, {
+	'ERPNext Integrations': 'Integrations',
+	'Geo': 'Settings',
+	'Accounts': 'Accounting',
+	'Portal': 'Website',
+	'Utilities': 'Settings',
+	'Shopping Cart': 'Website',
+	'Contacts': 'CRM'
+});
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index cf48be4..0cd648e 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -573,7 +573,6 @@
 				if(!r.exc) {
 					var doc = frappe.model.sync(r.message);
 					cur_frm.dirty();
-					erpnext.utils.clear_duplicates();
 					cur_frm.refresh();
 				}
 			}
@@ -604,28 +603,6 @@
 	}
 }
 
-erpnext.utils.clear_duplicates = function() {
-	if(!cur_frm.doc.items) return;
-	const unique_items = new Map();
-	/*
-		Create a Map of items with
-		item_code => [qty, warehouse, batch_no]
-	*/
-	let items = [];
-
-	for (let item of cur_frm.doc.items) {
-		if (!(unique_items.has(item.item_code) && unique_items.get(item.item_code)[0] === item.qty &&
-			unique_items.get(item.item_code)[1] === item.warehouse && unique_items.get(item.item_code)[2] === item.batch_no &&
-			unique_items.get(item.item_code)[3] === item.delivery_date && unique_items.get(item.item_code)[4] === item.required_date &&
-			unique_items.get(item.item_code)[5] === item.rate)) {
-
-			unique_items.set(item.item_code, [item.qty, item.warehouse, item.batch_no, item.delivery_date, item.required_date, item.rate]);
-			items.push(item);
-		}
-	}
-	cur_frm.doc.items = items;
-}
-
 frappe.form.link_formatters['Item'] = function(value, doc) {
 	if(doc && doc.item_name && doc.item_name !== value) {
 		return value? value + ': ' + doc.item_name: doc.item_name;
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 26ca7c6..39dda92 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -107,7 +107,7 @@
 	refresh: function(doc, dt, dn) {
 		var me = this;
 		this._super();
-		var allow_delivery = false;
+		let allow_delivery = false;
 
 		if(doc.docstatus==1) {
 			if(this.frm.has_perm("submit")) {
@@ -132,6 +132,8 @@
 			if(doc.status !== 'Closed') {
 				if(doc.status !== 'On Hold') {
 
+					allow_delivery = this.frm.doc.items.some(item => item.delivered_by_supplier === 0 && item.qty > flt(item.delivered_qty))
+
 					if (this.frm.has_perm("submit")) {
 						if(flt(doc.per_delivered, 6) < 100 || flt(doc.per_billed) < 100) {
 							// hold
diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js
index 5351f32..96e31ff 100644
--- a/erpnext/stock/doctype/material_request/material_request.js
+++ b/erpnext/stock/doctype/material_request/material_request.js
@@ -211,6 +211,7 @@
 							d.stock_uom = item.stock_uom;
 							d.conversion_factor = 1;
 							d.qty = item.qty;
+							d.project = item.project;
 						});
 					}
 					d.hide();
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index 2b079e7..f2fe448 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -450,7 +450,7 @@
 			"field_map": {
 				"name": "material_request_item",
 				"parent": "material_request",
-				"uom": "stock_uom",
+				"uom": "stock_uom"
 			},
 			"postprocess": update_item,
 			"condition": lambda doc: doc.ordered_qty < doc.stock_qty
diff --git a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
index 5933700..912a465 100644
--- a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
+++ b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
@@ -61,7 +61,8 @@
   "ste_detail",
   "column_break_51",
   "transferred_qty",
-  "reference_purchase_receipt"
+  "reference_purchase_receipt",
+  "project"
  ],
  "fields": [
   {
@@ -472,11 +473,18 @@
    "label": "Reference Purchase Receipt",
    "options": "Purchase Receipt",
    "read_only": 1
+  },
+  {
+   "fieldname": "project",
+   "fieldtype": "Link",
+   "label": "Project",
+   "options": "Project",
+   "read_only": 1
   }
  ],
  "idx": 1,
  "istable": 1,
- "modified": "2019-06-14 11:58:41.958144",
+ "modified": "2019-07-12 11:34:53.190749",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Entry Detail",
diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js
index 9d93f37..aec9db9 100644
--- a/erpnext/support/doctype/issue/issue.js
+++ b/erpnext/support/doctype/issue/issue.js
@@ -2,6 +2,12 @@
 	onload: function(frm) {
 		frm.email_field = "raised_by";
 
+		frappe.db.get_value("Support Settings", {name: "Support Settings"}, "allow_resetting_service_level_agreement", (r) => {
+			if (!r.allow_resetting_service_level_agreement) {
+				frm.set_df_property("reset_service_level_agreement", "hidden", 1) ;
+			}
+		});
+
 		if (frm.doc.service_level_agreement) {
 			frappe.call({
 				method: "erpnext.support.doctype.service_level_agreement.service_level_agreement.get_service_level_agreement_filters",
@@ -73,6 +79,42 @@
 		}
 	},
 
+	reset_service_level_agreement: function(frm) {
+		let reset_sla = new frappe.ui.Dialog({
+			title: __("Reset Service Level Agreement"),
+			fields: [
+				{
+					fieldtype: "Data",
+					fieldname: "reason",
+					label: __("Reason"),
+					reqd: 1
+				}
+			],
+			primary_action_label: __("Reset"),
+			primary_action: (values) => {
+				reset_sla.disable_primary_action();
+				reset_sla.hide();
+				reset_sla.clear();
+
+				frappe.show_alert({
+					indicator: 'green',
+					message: __('Resetting Service Level Agreement.')
+				});
+
+				frm.call("reset_service_level_agreement", {
+					reason: values.reason,
+					user: frappe.session.user_email
+				}, () => {
+					reset_sla.enable_primary_action();
+					frm.refresh();
+					frappe.msgprint(__("Service Level Agreement Reset."));
+				});
+			}
+		});
+
+		reset_sla.show();
+	},
+
 	timeline_refresh: function(frm) {
 		// create button for "Help Article"
 		if(frappe.model.can_create('Help Article')) {
@@ -136,7 +178,7 @@
 
 	var time_to_resolve = get_status(frm.doc.resolution_by_variance);
 	if (!frm.doc.resolution_date && frm.doc.agreement_fulfilled === "Ongoing") {
-		time_to_resolve = get_time_left(frm.doc.response_by, frm.doc.agreement_fulfilled);
+		time_to_resolve = get_time_left(frm.doc.resolution_by, frm.doc.agreement_fulfilled);
 	}
 
 	frm.dashboard.set_headline_alert(
diff --git a/erpnext/support/doctype/issue/issue.json b/erpnext/support/doctype/issue/issue.json
index 72153dc..41fe380 100644
--- a/erpnext/support/doctype/issue/issue.json
+++ b/erpnext/support/doctype/issue/issue.json
@@ -22,10 +22,12 @@
   "service_level_agreement",
   "response_by",
   "response_by_variance",
+  "reset_service_level_agreement",
   "cb",
   "agreement_fulfilled",
   "resolution_by",
   "resolution_by_variance",
+  "service_level_agreement_creation",
   "response",
   "mins_to_first_response",
   "first_responded_on",
@@ -68,9 +70,9 @@
    "fieldname": "subject",
    "fieldtype": "Data",
    "in_global_search": 1,
+   "in_standard_filter": 1,
    "label": "Subject",
-   "reqd": 1,
-   "in_standard_filter": 1
+   "reqd": 1
   },
   {
    "fieldname": "customer",
@@ -336,11 +338,24 @@
    "fieldtype": "Float",
    "label": "Resolution By Variance",
    "read_only": 1
+  },
+  {
+   "fieldname": "service_level_agreement_creation",
+   "fieldtype": "Datetime",
+   "hidden": 1,
+   "label": "Service Level Agreement Creation",
+   "read_only": 1
+  },
+  {
+   "depends_on": "eval: doc.service_level_agreement",
+   "fieldname": "reset_service_level_agreement",
+   "fieldtype": "Button",
+   "label": "Reset Service Level Agreement"
   }
  ],
  "icon": "fa fa-ticket",
  "idx": 7,
- "modified": "2019-06-30 13:19:38.215525",
+ "modified": "2019-07-11 23:57:22.015881",
  "modified_by": "Administrator",
  "module": "Support",
  "name": "Issue",
@@ -365,4 +380,4 @@
  "timeline_field": "customer",
  "title_field": "subject",
  "track_seen": 1
-}
+}
\ No newline at end of file
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index 226676f..ce9fb12 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -121,6 +121,7 @@
 
 		# Reset SLA
 		if replicated_issue.service_level_agreement:
+			replicated_issue.service_level_agreement_creation = now_datetime()
 			replicated_issue.service_level_agreement = None
 			replicated_issue.agreement_fulfilled = "Ongoing"
 			replicated_issue.response_by = None
@@ -173,8 +174,9 @@
 
 		if not self.creation:
 			self.creation = now_datetime()
+			self.service_level_agreement_creation = now_datetime()
 
-		start_date_time = get_datetime(self.creation)
+		start_date_time = get_datetime(self.service_level_agreement_creation)
 		self.response_by = get_expected_time_for(parameter='response', service_level=priority, start_date_time=start_date_time)
 		self.resolution_by = get_expected_time_for(parameter='resolution', service_level=priority, start_date_time=start_date_time)
 
@@ -193,6 +195,23 @@
 				self.set_response_and_resolution_time(priority=self.priority, service_level_agreement=self.service_level_agreement)
 				frappe.msgprint(_("Service Level Agreement has been changed to {0}.").format(self.service_level_agreement))
 
+	def reset_service_level_agreement(self, reason, user):
+		if not frappe.db.get_single_value("Support Settings", "allow_resetting_service_level_agreement"):
+			frappe.throw(_("Allow Resetting Service Level Agreement from Support Settings."))
+
+		frappe.get_doc({
+			"doctype": "Comment",
+			"comment_type": "Info",
+			"reference_doctype": self.doctype,
+			"reference_name": self.name,
+			"comment_email": user,
+			"content": " resetted Service Level Agreement - {0}".format(_(reason)),
+		}).insert(ignore_permissions=True)
+
+		self.service_level_agreement_creation = now_datetime()
+		self.set_response_and_resolution_time(priority=self.priority, service_level_agreement=self.service_level_agreement)
+		self.save()
+
 def get_expected_time_for(parameter, service_level, start_date_time):
 	current_date_time = start_date_time
 	expected_time = current_date_time
diff --git a/erpnext/support/doctype/issue/test_issue.py b/erpnext/support/doctype/issue/test_issue.py
index eb1736e..7a5e3e3 100644
--- a/erpnext/support/doctype/issue/test_issue.py
+++ b/erpnext/support/doctype/issue/test_issue.py
@@ -80,7 +80,8 @@
 		"customer": customer,
 		"raised_by": "test@example.com",
 		"description": "Service Level Agreement Issue",
-		"creation": creation
+		"creation": creation,
+		"service_level_agreement_creation": creation
 	}).insert(ignore_permissions=True)
 
 	return issue
diff --git a/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py b/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py
index 68b82d1..4a741ea 100644
--- a/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py
+++ b/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py
@@ -76,6 +76,7 @@
 
 	service_level_agreement = frappe.get_doc({
 		"doctype": "Service Level Agreement",
+		"enable": 1,
 		"default_service_level_agreement": default_service_level_agreement,
 		"service_level": service_level,
 		"holiday_list": holiday_list,
diff --git a/erpnext/support/doctype/support_settings/support_settings.json b/erpnext/support/doctype/support_settings/support_settings.json
index 2dced15..be9e064 100644
--- a/erpnext/support/doctype/support_settings/support_settings.json
+++ b/erpnext/support/doctype/support_settings/support_settings.json
@@ -6,6 +6,7 @@
  "field_order": [
   "sb_00",
   "track_service_level_agreement",
+  "allow_resetting_service_level_agreement",
   "issues_sb",
   "close_issue_after_days",
   "portal_sb",
@@ -118,10 +119,16 @@
    "fieldname": "track_service_level_agreement",
    "fieldtype": "Check",
    "label": "Track Service Level Agreement"
+  },
+  {
+   "default": "0",
+   "fieldname": "allow_resetting_service_level_agreement",
+   "fieldtype": "Check",
+   "label": "Allow Resetting Service Level Agreement"
   }
  ],
  "issingle": 1,
- "modified": "2019-07-09 17:11:38.216732",
+ "modified": "2019-07-10 22:52:39.663873",
  "modified_by": "Administrator",
  "module": "Support",
  "name": "Support Settings",