From 2c3f1677f8f7f2cd19bd97a3460492366f201292 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Tue, 28 Apr 2020 14:11:58 +0530 Subject: [PATCH] fix: commonify SLA and Service Level Doctypes --- .../service_level_agreement.js | 25 +----- .../service_level_agreement.json | 44 ++++----- .../service_level_agreement.py | 89 ++++++++++++++++++- .../service_level_priority.json | 23 ++--- .../support_settings/support_settings.json | 4 +- 5 files changed, 122 insertions(+), 63 deletions(-) diff --git a/erpnext/support/doctype/service_level_agreement/service_level_agreement.js b/erpnext/support/doctype/service_level_agreement/service_level_agreement.js index 1d486f48346..7aeaae48bab 100644 --- a/erpnext/support/doctype/service_level_agreement/service_level_agreement.js +++ b/erpnext/support/doctype/service_level_agreement/service_level_agreement.js @@ -2,28 +2,5 @@ // For license information, please see license.txt frappe.ui.form.on('Service Level Agreement', { - service_level: function(frm) { - frm.fields_dict.support_and_resolution.grid.remove_all(); - frappe.call({ - "method": "frappe.client.get", - args: { - doctype: "Service Level", - name: frm.doc.service_level - }, - callback: function(data){ - let count = Math.max(data.message.priorities.length, data.message.support_and_resolution.length); - let i = 0; - while (i < count){ - if (data.message.priorities[i]) { - frm.add_child("priorities", data.message.priorities[i]); - } - if (data.message.support_and_resolution[i]) { - frm.add_child("support_and_resolution", data.message.support_and_resolution[i]); - } - i++; - } - frm.refresh(); - } - }); - }, + }); diff --git a/erpnext/support/doctype/service_level_agreement/service_level_agreement.json b/erpnext/support/doctype/service_level_agreement/service_level_agreement.json index 9a83ca7ac04..3725e15a549 100644 --- a/erpnext/support/doctype/service_level_agreement/service_level_agreement.json +++ b/erpnext/support/doctype/service_level_agreement/service_level_agreement.json @@ -1,4 +1,5 @@ { + "actions": [], "autoname": "format:SLA-{service_level}-{####}", "creation": "2018-12-26 21:08:15.448812", "doctype": "DocType", @@ -6,12 +7,12 @@ "engine": "InnoDB", "field_order": [ "enable", + "section_break_2", "service_level", "default_service_level_agreement", - "holiday_list", "column_break_2", "employee_group", - "default_priority", + "holiday_list", "entity_section", "entity_type", "column_break_10", @@ -27,43 +28,31 @@ "support_and_resolution" ], "fields": [ - { - "default": "0", - "depends_on": "eval: !doc.customer;", - "fieldname": "default_service_level_agreement", - "fieldtype": "Check", - "label": "Default Service Level Agreement" - }, { "fieldname": "service_level", - "fieldtype": "Link", + "fieldtype": "Data", "in_list_view": 1, "in_standard_filter": 1, "label": "Service Level", - "options": "Service Level", "reqd": 1 }, { - "fetch_from": "service_level.holiday_list", "fieldname": "holiday_list", "fieldtype": "Link", "label": "Holiday List", - "options": "Holiday List", - "read_only": 1 + "options": "Holiday List" }, { "fieldname": "column_break_2", "fieldtype": "Column Break" }, { - "fetch_from": "service_level.employee_group", "fieldname": "employee_group", "fieldtype": "Link", "in_list_view": 1, "in_standard_filter": 1, "label": "Employee Group", - "options": "Employee Group", - "read_only": 1 + "options": "Employee Group" }, { "fieldname": "agreement_details_section", @@ -111,14 +100,6 @@ "label": "Priorities", "options": "Service Level Priority" }, - { - "fetch_from": "service_level.default_priority", - "fieldname": "default_priority", - "fieldtype": "Link", - "label": "Default Priority", - "options": "Issue Priority", - "read_only": 1 - }, { "default": "1", "fieldname": "active", @@ -156,9 +137,20 @@ "fieldname": "enable", "fieldtype": "Check", "label": "Enable" + }, + { + "fieldname": "section_break_2", + "fieldtype": "Section Break" + }, + { + "default": "0", + "fieldname": "default_service_level_agreement", + "fieldtype": "Check", + "label": "Default Service Level Agreement" } ], - "modified": "2019-07-09 17:22:16.402939", + "links": [], + "modified": "2020-04-28 14:10:18.767202", "modified_by": "Administrator", "module": "Support", "name": "Service Level Agreement", diff --git a/erpnext/support/doctype/service_level_agreement/service_level_agreement.py b/erpnext/support/doctype/service_level_agreement/service_level_agreement.py index a399c58b168..9fa0e238f96 100644 --- a/erpnext/support/doctype/service_level_agreement/service_level_agreement.py +++ b/erpnext/support/doctype/service_level_agreement/service_level_agreement.py @@ -6,11 +6,85 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document from frappe import _ -from frappe.utils import getdate +from frappe.utils import getdate, get_weekdays +from datetime import datetime class ServiceLevelAgreement(Document): def validate(self): + self.validate_doc() + self.check_priorities() + self.check_support_and_resolution() + + def check_priorities(self): + default_priority = [] + priorities = [] + + for priority in self.priorities: + # Check if response and resolution time is set for every priority + if not (priority.response_time or priority.resolution_time): + frappe.throw(_("Set Response Time and Resolution for Priority {0} at index {1}.").format(priority.priority, priority.idx)) + + priorities.append(priority.priority) + + if priority.default_priority: + default_priority.append(priority.default_priority) + + if priority.response_time_period == "Hour": + response = priority.response_time * 0.0416667 + elif priority.response_time_period == "Day": + response = priority.response_time + elif priority.response_time_period == "Week": + response = priority.response_time * 7 + + if priority.resolution_time_period == "Hour": + resolution = priority.resolution_time * 0.0416667 + elif priority.resolution_time_period == "Day": + resolution = priority.resolution_time + elif priority.resolution_time_period == "Week": + resolution = priority.resolution_time * 7 + + if response > resolution: + frappe.throw(_("Response Time for {0} at index {1} can't be greater than Resolution Time.").format(priority.priority, priority.idx)) + + # Check if repeated priority + if not len(set(priorities)) == len(priorities): + repeated_priority = get_repeated(priorities) + frappe.throw(_("Priority {0} has been repeated.").format(repeated_priority)) + + # Check if repeated default priority + if not len(set(default_priority)) == len(default_priority): + frappe.throw(_("Select only one Priority as Default.")) + + # set default priority from priorities + try: + self.default_priority = next(d.priority for d in self.priorities if d.default_priority) + except Exception: + frappe.throw(_("Select a Default Priority.")) + + def check_support_and_resolution(self): + week = get_weekdays() + support_days = [] + + for support_and_resolution in self.support_and_resolution: + # Check if start and end time is set for every support day + if not (support_and_resolution.start_time or support_and_resolution.end_time): + frappe.throw(_("Set Start Time and End Time for \ + Support Day {0} at index {1}.".format(support_and_resolution.workday, support_and_resolution.idx))) + + support_days.append(support_and_resolution.workday) + support_and_resolution.idx = week.index(support_and_resolution.workday) + 1 + + if support_and_resolution.start_time >= support_and_resolution.end_time: + frappe.throw(_("Start Time can't be greater than or equal to End Time \ + for {0}.".format(support_and_resolution.workday))) + + # Check for repeated workday + if not len(set(support_days)) == len(support_days): + repeated_days = get_repeated(support_days) + frappe.throw(_("Workday {0} has been repeated.").format(repeated_days)) + + def validate_doc(self): if not frappe.db.get_single_value("Support Settings", "track_service_level_agreement"): frappe.throw(_("Service Level Agreement tracking is not enabled.")) @@ -110,4 +184,15 @@ def get_service_level_agreement_filters(name, customer=None): return { "priority": [priority.priority for priority in frappe.get_list("Service Level Priority", filters={"parent": name}, fields=["priority"])], "service_level_agreements": [d.name for d in frappe.get_list("Service Level Agreement", filters=filters, or_filters=or_filters)] - } \ No newline at end of file + } + +def get_repeated(values): + unique_list = [] + diff = [] + for value in values: + if value not in unique_list: + unique_list.append(str(value)) + else: + if value not in diff: + diff.append(str(value)) + return " ".join(diff) diff --git a/erpnext/support/doctype/service_level_priority/service_level_priority.json b/erpnext/support/doctype/service_level_priority/service_level_priority.json index cd87a1c1131..f56008eb4cf 100644 --- a/erpnext/support/doctype/service_level_priority/service_level_priority.json +++ b/erpnext/support/doctype/service_level_priority/service_level_priority.json @@ -1,4 +1,5 @@ { + "actions": [], "creation": "2019-05-04 05:54:03.658991", "doctype": "DocType", "editable_grid": 1, @@ -16,7 +17,7 @@ ], "fields": [ { - "columns": 2, + "columns": 1, "fieldname": "priority", "fieldtype": "Link", "in_list_view": 1, @@ -28,14 +29,7 @@ "fieldtype": "Section Break" }, { - "columns": 1, - "fieldname": "response_time", - "fieldtype": "Int", - "in_list_view": 1, - "label": "Response Time" - }, - { - "columns": 1, + "columns": 2, "fieldname": "resolution_time", "fieldtype": "Int", "in_list_view": 1, @@ -66,15 +60,24 @@ "fieldtype": "Column Break" }, { + "columns": 1, "default": "0", "fieldname": "default_priority", "fieldtype": "Check", "in_list_view": 1, "label": "Default Priority" + }, + { + "columns": 2, + "fieldname": "response_time", + "fieldtype": "Int", + "in_list_view": 1, + "label": "First Response Time" } ], "istable": 1, - "modified": "2019-05-21 06:54:42.674377", + "links": [], + "modified": "2020-04-24 14:50:13.774308", "modified_by": "Administrator", "module": "Support", "name": "Service Level Priority", diff --git a/erpnext/support/doctype/support_settings/support_settings.json b/erpnext/support/doctype/support_settings/support_settings.json index be9e0645915..3f52181a465 100644 --- a/erpnext/support/doctype/support_settings/support_settings.json +++ b/erpnext/support/doctype/support_settings/support_settings.json @@ -1,4 +1,5 @@ { + "actions": [], "creation": "2017-02-17 13:07:35.686409", "doctype": "DocType", "editable_grid": 1, @@ -128,7 +129,8 @@ } ], "issingle": 1, - "modified": "2019-07-10 22:52:39.663873", + "links": [], + "modified": "2020-04-28 14:11:15.117019", "modified_by": "Administrator", "module": "Support", "name": "Support Settings",