fix: calculate variance
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 5beaea7..f559597 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -242,7 +242,8 @@
 		"erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_mws_settings.schedule_get_order_details",
 		"erpnext.accounts.doctype.gl_entry.gl_entry.rename_gle_sle_docs",
 		"erpnext.projects.doctype.project.project.hourly_reminder",
-		"erpnext.projects.doctype.project.project.collect_project_status"
+		"erpnext.projects.doctype.project.project.collect_project_status",
+		"erpnext.support.doctype.issue.issue.set_service_level_agreement_variance"
 	],
 	"daily": [
 		"erpnext.stock.reorder_item.reorder_item",
diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js
index 1475050..e2e6997 100644
--- a/erpnext/support/doctype/issue/issue.js
+++ b/erpnext/support/doctype/issue/issue.js
@@ -5,7 +5,7 @@
 
 	refresh: function (frm) {
 
-		if (frm.doc.status !== "Closed") {
+		if (frm.doc.status !== "Closed" && frm.doc.agreement_fulfilled === "Ongoing") {
 			if (frm.doc.service_level_agreement) {
 				set_time_to_resolve_and_response(frm);
 			}
@@ -25,14 +25,14 @@
 			if (frm.doc.service_level_agreement) {
 				frm.dashboard.clear_headline();
 
-				let agreement_status = (frm.doc.agreement_status == "Fulfilled") ?
+				let agreement_fulfilled = (frm.doc.agreement_fulfilled == "Fulfilled") ?
 						{"indicator": "green", "msg": "Service Level Agreement has been fulfilled"} :
 						{"indicator": "red", "msg": "Service Level Agreement Failed"};
 
 					frm.dashboard.set_headline_alert(
 					'<div class="row">' +
 						'<div class="col-xs-12">' +
-							'<span class="indicator whitespace-nowrap '+ agreement_status.indicator +'"><span class="hidden-xs">'+ agreement_status.msg +'</span></span> ' +
+							'<span class="indicator whitespace-nowrap '+ agreement_fulfilled.indicator +'"><span class="hidden-xs">'+ agreement_fulfilled.msg +'</span></span> ' +
 						'</div>' +
 					'</div>'
 				);
@@ -112,8 +112,8 @@
 function set_time_to_resolve_and_response(frm) {
 	frm.dashboard.clear_headline();
 
-	var time_to_respond = get_time_left(frm.doc.response_by, frm.doc.agreement_status);
-	var time_to_resolve = get_time_left(frm.doc.resolution_by, frm.doc.agreement_status);
+	var time_to_respond = get_time_left(frm.doc.response_by, frm.doc.agreement_fulfilled);
+	var time_to_resolve = get_time_left(frm.doc.resolution_by, frm.doc.agreement_fulfilled);
 
 	frm.dashboard.set_headline_alert(
 		'<div class="row">' +
@@ -127,9 +127,9 @@
 	);
 }
 
-function get_time_left(timestamp, agreement_status) {
+function get_time_left(timestamp, agreement_fulfilled) {
 	const diff = moment(timestamp).diff(moment());
 	const diff_display = diff >= 44500 ? moment.duration(diff).humanize() : moment(0, 'seconds').format('HH:mm');
-	let indicator = (diff_display == '00:00' && agreement_status != "Fulfilled") ? "red" : "green";
+	let indicator = (diff_display == '00:00' && agreement_fulfilled != "Fulfilled") ? "red" : "green";
 	return {"diff_display": diff_display, "indicator": indicator};
 }
diff --git a/erpnext/support/doctype/issue/issue.json b/erpnext/support/doctype/issue/issue.json
index 9639702..29cad62 100644
--- a/erpnext/support/doctype/issue/issue.json
+++ b/erpnext/support/doctype/issue/issue.json
@@ -21,9 +21,11 @@
   "service_level_section",
   "service_level_agreement",
   "response_by",
+  "response_by_variance",
   "cb",
-  "agreement_status",
+  "agreement_fulfilled",
   "resolution_by",
+  "resolution_by_variance",
   "response",
   "mins_to_first_response",
   "first_responded_on",
@@ -167,14 +169,6 @@
    "read_only": 1
   },
   {
-   "default": "Ongoing",
-   "fieldname": "agreement_status",
-   "fieldtype": "Select",
-   "label": "Agreement Status",
-   "options": "Ongoing\nFulfilled\nFailed",
-   "read_only": 1
-  },
-  {
    "fieldname": "resolution_by",
    "fieldtype": "Datetime",
    "label": "Resolution By",
@@ -317,11 +311,33 @@
    "fieldname": "via_customer_portal",
    "fieldtype": "Check",
    "label": "Via Customer Portal"
+  },
+  {
+   "default": "Ongoing",
+   "fieldname": "agreement_fulfilled",
+   "fieldtype": "Select",
+   "label": "Agreement Fulfilled",
+   "options": "Ongoing\nFulfilled\nFailed",
+   "read_only": 1
+  },
+  {
+   "description": "in hours",
+   "fieldname": "response_by_variance",
+   "fieldtype": "Int",
+   "label": "Response By Variance",
+   "read_only": 1
+  },
+  {
+   "description": "in hours",
+   "fieldname": "resolution_by_variance",
+   "fieldtype": "Int",
+   "label": "Resolution By Variance",
+   "read_only": 1
   }
  ],
  "icon": "fa fa-ticket",
  "idx": 7,
- "modified": "2019-05-03 14:36:19.117560",
+ "modified": "2019-05-10 22:31:09.391044",
  "modified_by": "Administrator",
  "module": "Support",
  "name": "Issue",
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index 2b73440..965e53c 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -68,22 +68,27 @@
 		status = frappe.db.get_value("Issue", self.name, "status")
 		if self.status!="Open" and status =="Open" and not self.first_responded_on:
 			self.first_responded_on = now()
+
 		if self.status=="Closed" and status !="Closed":
 			self.resolution_date = now()
-			self.update_agreement_status()
+			if not frappe.db.get_value("Issue", self.name, "agreement_fulfilled") == "Ongoing":
+				self.set_service_level_agreement_variance(issue=self.name)
+				self.update_agreement_status()
+
 		if self.status=="Open" and status !="Open":
 			# if no date, it should be set as None and not a blank string "", as per mysql strict config
 			self.resolution_date = None
 
 	def update_agreement_status(self):
 		current_time = frappe.flags.current_time or now_datetime()
-		if self.service_level_agreement and self.agreement_status == "Ongoing":
+		if self.service_level_agreement and self.agreement_fulfilled == "Ongoing":
 			response_time_diff = round(time_diff_in_hours(self.response_by, current_time), 2)
 			resolution_time_diff = round(time_diff_in_hours(self.resolution_by, current_time), 2)
+
 			if response_time_diff < 0 or resolution_time_diff < 0:
-				self.agreement_status = "Failed"
+				self.agreement_fulfilled = "Failed"
 			else:
-				self.agreement_status = "Fulfilled"
+				self.agreement_fulfilled = "Fulfilled"
 
 	def create_communication(self):
 		communication = frappe.new_doc("Communication")
@@ -151,6 +156,9 @@
 		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)
 
+		self.response_by_variance = round(time_diff_in_hours(self.response_by, now_datetime()))
+		self.resolution_by_variance = round(time_diff_in_hours(self.resolution_by, now_datetime()))
+
 	@frappe.whitelist()
 	def change_sla_priority(self, priority):
 		self.set_response_and_resolution_time(priority=priority)
@@ -222,16 +230,32 @@
 	return current_date_time
 
 def set_service_level_agreement_status():
-	issues = frappe.get_list("Issue", filters={"status": "Open", "agreement_status": "Ongoing"})
+	issues = frappe.get_list("Issue", filters={"status": "Open", "agreement_fulfilled": "Ongoing"})
 	for issue in issues:
 		doc = frappe.get_doc("Issue", issue.name)
-		if doc.service_level_agreement and doc.agreement_status == "Ongoing":
+		if doc.service_level_agreement and doc.agreement_fulfilled == "Ongoing":
 			response_time_diff = round(time_diff_in_hours(doc.response_by, now_datetime()), 2)
 			resolution_time_diff = round(time_diff_in_hours(doc.resolution_by, now_datetime()), 2)
 			if response_time_diff < 0 or resolution_time_diff < 0:
-				frappe.db.set_value("Issue", doc.name, "agreement_status", "Failed")
+				frappe.db.set_value("Issue", doc.name, "agreement_fulfilled", "Failed")
 			else:
-				frappe.db.set_value("Issue", doc.name, "agreement_status", "Fulfilled")
+				frappe.db.set_value("Issue", doc.name, "agreement_fulfilled", "Fulfilled")
+
+def set_service_level_agreement_variance(issue=None):
+	filters = {"status": "Open", "agreement_fulfilled": "Ongoing"}
+
+	if issue:
+		filters = {"status": issue}
+
+	issues = frappe.get_list("Issue", filters=filters)
+	for issue in issues:
+		doc = frappe.get_doc("Issue", issue.name)
+		if not doc.first_responded_on and not doc.agreement_fulfilled == "Ongoing":
+			variance = round(time_diff_in_hours(doc.response_by, now_datetime()))
+			frappe.db.set_value("Issue", doc.name, "response_by_variance", variance)
+		if not doc.resolution_dateand and not doc.agreement_fulfilled == "Ongoing":
+			variance = round(time_diff_in_hours(self.resolution_by, now_datetime()))
+			frappe.db.set_value("Issue", doc.name, "resolution_by_variance", variance)
 
 def get_list_context(context=None):
 	return {