mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-26 00:14:50 +00:00
fix: commonify SLA and Service Level Doctypes
This commit is contained in:
@@ -2,28 +2,5 @@
|
|||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on('Service Level Agreement', {
|
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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"autoname": "format:SLA-{service_level}-{####}",
|
"autoname": "format:SLA-{service_level}-{####}",
|
||||||
"creation": "2018-12-26 21:08:15.448812",
|
"creation": "2018-12-26 21:08:15.448812",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@@ -6,12 +7,12 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"enable",
|
"enable",
|
||||||
|
"section_break_2",
|
||||||
"service_level",
|
"service_level",
|
||||||
"default_service_level_agreement",
|
"default_service_level_agreement",
|
||||||
"holiday_list",
|
|
||||||
"column_break_2",
|
"column_break_2",
|
||||||
"employee_group",
|
"employee_group",
|
||||||
"default_priority",
|
"holiday_list",
|
||||||
"entity_section",
|
"entity_section",
|
||||||
"entity_type",
|
"entity_type",
|
||||||
"column_break_10",
|
"column_break_10",
|
||||||
@@ -27,43 +28,31 @@
|
|||||||
"support_and_resolution"
|
"support_and_resolution"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"depends_on": "eval: !doc.customer;",
|
|
||||||
"fieldname": "default_service_level_agreement",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Default Service Level Agreement"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "service_level",
|
"fieldname": "service_level",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Service Level",
|
"label": "Service Level",
|
||||||
"options": "Service Level",
|
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "service_level.holiday_list",
|
|
||||||
"fieldname": "holiday_list",
|
"fieldname": "holiday_list",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Holiday List",
|
"label": "Holiday List",
|
||||||
"options": "Holiday List",
|
"options": "Holiday List"
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_2",
|
"fieldname": "column_break_2",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "service_level.employee_group",
|
|
||||||
"fieldname": "employee_group",
|
"fieldname": "employee_group",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Employee Group",
|
"label": "Employee Group",
|
||||||
"options": "Employee Group",
|
"options": "Employee Group"
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "agreement_details_section",
|
"fieldname": "agreement_details_section",
|
||||||
@@ -111,14 +100,6 @@
|
|||||||
"label": "Priorities",
|
"label": "Priorities",
|
||||||
"options": "Service Level Priority"
|
"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",
|
"default": "1",
|
||||||
"fieldname": "active",
|
"fieldname": "active",
|
||||||
@@ -156,9 +137,20 @@
|
|||||||
"fieldname": "enable",
|
"fieldname": "enable",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Enable"
|
"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",
|
"modified_by": "Administrator",
|
||||||
"module": "Support",
|
"module": "Support",
|
||||||
"name": "Service Level Agreement",
|
"name": "Service Level Agreement",
|
||||||
|
|||||||
@@ -6,11 +6,85 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate, get_weekdays
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
class ServiceLevelAgreement(Document):
|
class ServiceLevelAgreement(Document):
|
||||||
|
|
||||||
def validate(self):
|
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"):
|
if not frappe.db.get_single_value("Support Settings", "track_service_level_agreement"):
|
||||||
frappe.throw(_("Service Level Agreement tracking is not enabled."))
|
frappe.throw(_("Service Level Agreement tracking is not enabled."))
|
||||||
|
|
||||||
@@ -110,4 +184,15 @@ def get_service_level_agreement_filters(name, customer=None):
|
|||||||
return {
|
return {
|
||||||
"priority": [priority.priority for priority in frappe.get_list("Service Level Priority", filters={"parent": name}, fields=["priority"])],
|
"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)]
|
"service_level_agreements": [d.name for d in frappe.get_list("Service Level Agreement", filters=filters, or_filters=or_filters)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"creation": "2019-05-04 05:54:03.658991",
|
"creation": "2019-05-04 05:54:03.658991",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
@@ -16,7 +17,7 @@
|
|||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"columns": 2,
|
"columns": 1,
|
||||||
"fieldname": "priority",
|
"fieldname": "priority",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@@ -28,14 +29,7 @@
|
|||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"columns": 1,
|
"columns": 2,
|
||||||
"fieldname": "response_time",
|
|
||||||
"fieldtype": "Int",
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Response Time"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"columns": 1,
|
|
||||||
"fieldname": "resolution_time",
|
"fieldname": "resolution_time",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@@ -66,15 +60,24 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"columns": 1,
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "default_priority",
|
"fieldname": "default_priority",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Default Priority"
|
"label": "Default Priority"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"columns": 2,
|
||||||
|
"fieldname": "response_time",
|
||||||
|
"fieldtype": "Int",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "First Response Time"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-05-21 06:54:42.674377",
|
"links": [],
|
||||||
|
"modified": "2020-04-24 14:50:13.774308",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Support",
|
"module": "Support",
|
||||||
"name": "Service Level Priority",
|
"name": "Service Level Priority",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"creation": "2017-02-17 13:07:35.686409",
|
"creation": "2017-02-17 13:07:35.686409",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
@@ -128,7 +129,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"modified": "2019-07-10 22:52:39.663873",
|
"links": [],
|
||||||
|
"modified": "2020-04-28 14:11:15.117019",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Support",
|
"module": "Support",
|
||||||
"name": "Support Settings",
|
"name": "Support Settings",
|
||||||
|
|||||||
Reference in New Issue
Block a user