feat: pause SLA on statuses configuration
diff --git a/erpnext/support/doctype/issue/issue.json b/erpnext/support/doctype/issue/issue.json
index 70595e4..712b70c 100644
--- a/erpnext/support/doctype/issue/issue.json
+++ b/erpnext/support/doctype/issue/issue.json
@@ -403,6 +403,7 @@
{
"fieldname": "on_hold_since",
"fieldtype": "Datetime",
+ "hidden": 1,
"label": "On Hold Since",
"read_only": 1,
"show_days": 1,
@@ -420,7 +421,7 @@
"icon": "fa fa-ticket",
"idx": 7,
"links": [],
- "modified": "2020-06-04 15:53:38.322514",
+ "modified": "2020-06-05 15:45:24.474425",
"modified_by": "Administrator",
"module": "Support",
"name": "Issue",
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index ac700c9..146eb5a 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -78,40 +78,44 @@
self.handle_hold_time(status)
def handle_hold_time(self, status):
- # set response and resolution variance as None as the issue is on Hold for status as Replied
- if self.status == "Replied" and status != "Replied":
- self.on_hold_since = frappe.flags.current_time or now_datetime()
- if not self.first_responded_on:
- self.response_by = None
- self.response_by_variance = None
- self.resolution_by = None
- self.resolution_by_variance = None
+ if frappe.db.get_single_value("Support Settings", "track_service_level_agreement"):
+ # set response and resolution variance as None as the issue is on Hold for status as Replied
+ pause_sla_on = frappe.db.get_all("Pause SLA On Status", fields=["status"])
+ hold_statuses = [entry.status for entry in pause_sla_on]
- # calculate hold time when status is changed from Replied to any other status
- if self.status != "Replied" and status == "Replied":
- hold_time = self.total_hold_time if self.total_hold_time else 0
- now_time = frappe.flags.current_time or now_datetime()
- self.total_hold_time = hold_time + time_diff_in_seconds(now_time, self.on_hold_since)
+ if self.status in hold_statuses and status not in hold_statuses:
+ self.on_hold_since = frappe.flags.current_time or now_datetime()
+ if not self.first_responded_on:
+ self.response_by = None
+ self.response_by_variance = None
+ self.resolution_by = None
+ self.resolution_by_variance = None
- # re-calculate SLA variables after issue changes from Replied to Open
- # add hold time to SLA variables
- if self.status == "Open" and status == "Replied":
- start_date_time = get_datetime(self.service_level_agreement_creation)
- priority = get_priority(self)
- now_time = frappe.flags.current_time or now_datetime()
- hold_time = time_diff_in_seconds(now_time, self.on_hold_since)
+ # calculate hold time when status is changed from Replied to any other status
+ if self.status not in hold_statuses and status in hold_statuses:
+ hold_time = self.total_hold_time if self.total_hold_time else 0
+ now_time = frappe.flags.current_time or now_datetime()
+ self.total_hold_time = hold_time + time_diff_in_seconds(now_time, self.on_hold_since)
- if not self.first_responded_on:
- response_by = get_expected_time_for(parameter="response", service_level=priority, start_date_time=start_date_time)
- self.response_by = add_to_date(response_by, seconds=round(hold_time))
- response_by_variance = round(time_diff_in_hours(self.response_by, now_time))
- self.response_by_variance = response_by_variance + (hold_time // 3600)
+ # re-calculate SLA variables after issue changes from Replied to Open
+ # add hold time to SLA variables
+ if self.status == "Open" and status in hold_statuses:
+ start_date_time = get_datetime(self.service_level_agreement_creation)
+ priority = get_priority(self)
+ now_time = frappe.flags.current_time or now_datetime()
+ hold_time = time_diff_in_seconds(now_time, self.on_hold_since)
- resolution_by = get_expected_time_for(parameter="resolution", service_level=priority, start_date_time=start_date_time)
- self.resolution_by = add_to_date(resolution_by, seconds=round(hold_time))
- resolution_by_variance = round(time_diff_in_hours(self.resolution_by, now_time))
- self.resolution_by_variance = resolution_by_variance + (hold_time // 3600)
- self.on_hold_since = None
+ if not self.first_responded_on:
+ response_by = get_expected_time_for(parameter="response", service_level=priority, start_date_time=start_date_time)
+ self.response_by = add_to_date(response_by, seconds=round(hold_time))
+ response_by_variance = round(time_diff_in_hours(self.response_by, now_time))
+ self.response_by_variance = response_by_variance + (hold_time // 3600)
+
+ resolution_by = get_expected_time_for(parameter="resolution", service_level=priority, start_date_time=start_date_time)
+ self.resolution_by = add_to_date(resolution_by, seconds=round(hold_time))
+ resolution_by_variance = round(time_diff_in_hours(self.resolution_by, now_time))
+ self.resolution_by_variance = resolution_by_variance + (hold_time // 3600)
+ self.on_hold_since = None
def update_agreement_status(self):
if self.service_level_agreement and self.agreement_fulfilled == "Ongoing":
diff --git a/erpnext/support/doctype/pause_sla_on_status/__init__.py b/erpnext/support/doctype/pause_sla_on_status/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/support/doctype/pause_sla_on_status/__init__.py
diff --git a/erpnext/support/doctype/pause_sla_on_status/pause_sla_on_status.json b/erpnext/support/doctype/pause_sla_on_status/pause_sla_on_status.json
new file mode 100644
index 0000000..5b03f25
--- /dev/null
+++ b/erpnext/support/doctype/pause_sla_on_status/pause_sla_on_status.json
@@ -0,0 +1,33 @@
+{
+ "actions": [],
+ "creation": "2020-06-05 13:59:43.265588",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "status"
+ ],
+ "fields": [
+ {
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "label": "Status",
+ "reqd": 1,
+ "show_days": 1,
+ "show_seconds": 1
+ }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-06-05 15:15:29.986608",
+ "modified_by": "Administrator",
+ "module": "Support",
+ "name": "Pause SLA On Status",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/support/doctype/pause_sla_on_status/pause_sla_on_status.py b/erpnext/support/doctype/pause_sla_on_status/pause_sla_on_status.py
new file mode 100644
index 0000000..a3b547e
--- /dev/null
+++ b/erpnext/support/doctype/pause_sla_on_status/pause_sla_on_status.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class PauseSLAOnStatus(Document):
+ pass
diff --git a/erpnext/support/doctype/support_settings/support_settings.js b/erpnext/support/doctype/support_settings/support_settings.js
index 1d1069d..33ddf0b 100644
--- a/erpnext/support/doctype/support_settings/support_settings.js
+++ b/erpnext/support/doctype/support_settings/support_settings.js
@@ -2,7 +2,15 @@
// For license information, please see license.txt
frappe.ui.form.on('Support Settings', {
- refresh: function(frm) {
+ setup: function(frm) {
+ let allow_statuses = [];
+ const exclude_statuses = ['Open', 'Closed', 'Resolved'];
+ frappe.model.with_doctype('Issue', () => {
+ let statuses = frappe.meta.get_docfield('Issue', 'status', frm.doc.name).options;
+ statuses = statuses.split('\n');
+ allow_statuses = statuses.filter((status) => !exclude_statuses.includes(status));
+ frappe.meta.get_docfield('Pause SLA On Status', 'status', frm.doc.name).options = [''].concat(allow_statuses);
+ });
}
});
diff --git a/erpnext/support/doctype/support_settings/support_settings.json b/erpnext/support/doctype/support_settings/support_settings.json
index 3f52181..da4b607 100644
--- a/erpnext/support/doctype/support_settings/support_settings.json
+++ b/erpnext/support/doctype/support_settings/support_settings.json
@@ -10,6 +10,7 @@
"allow_resetting_service_level_agreement",
"issues_sb",
"close_issue_after_days",
+ "pause_sla_on_status",
"portal_sb",
"get_started_sections",
"show_latest_forum_posts",
@@ -123,14 +124,24 @@
},
{
"default": "0",
+ "depends_on": "eval:doc.track_service_level_agreement;",
"fieldname": "allow_resetting_service_level_agreement",
"fieldtype": "Check",
"label": "Allow Resetting Service Level Agreement"
+ },
+ {
+ "depends_on": "eval:doc.track_service_level_agreement;",
+ "fieldname": "pause_sla_on_status",
+ "fieldtype": "Table",
+ "label": "Pause SLA On",
+ "options": "Pause SLA On Status",
+ "show_days": 1,
+ "show_seconds": 1
}
],
"issingle": 1,
"links": [],
- "modified": "2020-04-28 14:11:15.117019",
+ "modified": "2020-06-05 16:35:13.905096",
"modified_by": "Administrator",
"module": "Support",
"name": "Support Settings",