feat: dynamic conditions for applying SLA (#26806)
This commit is contained in:
parent
24da00cada
commit
5719198576
@ -235,8 +235,7 @@ class Issue(Document):
|
|||||||
self.set_response_and_resolution_time()
|
self.set_response_and_resolution_time()
|
||||||
|
|
||||||
def set_response_and_resolution_time(self, priority=None, service_level_agreement=None):
|
def set_response_and_resolution_time(self, priority=None, service_level_agreement=None):
|
||||||
service_level_agreement = get_active_service_level_agreement_for(priority=priority,
|
service_level_agreement = get_active_service_level_agreement_for(self)
|
||||||
customer=self.customer, service_level_agreement=service_level_agreement)
|
|
||||||
|
|
||||||
if not service_level_agreement:
|
if not service_level_agreement:
|
||||||
if frappe.db.get_value("Issue", self.name, "service_level_agreement"):
|
if frappe.db.get_value("Issue", self.name, "service_level_agreement"):
|
||||||
@ -247,7 +246,8 @@ class Issue(Document):
|
|||||||
frappe.throw(_("This Service Level Agreement is specific to Customer {0}").format(service_level_agreement.customer))
|
frappe.throw(_("This Service Level Agreement is specific to Customer {0}").format(service_level_agreement.customer))
|
||||||
|
|
||||||
self.service_level_agreement = service_level_agreement.name
|
self.service_level_agreement = service_level_agreement.name
|
||||||
self.priority = service_level_agreement.default_priority if not priority else priority
|
if not self.priority:
|
||||||
|
self.priority = service_level_agreement.default_priority
|
||||||
|
|
||||||
priority = get_priority(self)
|
priority = get_priority(self)
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,10 @@
|
|||||||
"entity_type",
|
"entity_type",
|
||||||
"column_break_10",
|
"column_break_10",
|
||||||
"entity",
|
"entity",
|
||||||
|
"filters_section",
|
||||||
|
"condition",
|
||||||
|
"column_break_15",
|
||||||
|
"condition_description",
|
||||||
"agreement_details_section",
|
"agreement_details_section",
|
||||||
"start_date",
|
"start_date",
|
||||||
"active",
|
"active",
|
||||||
@ -171,10 +175,30 @@
|
|||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Pause SLA On",
|
"label": "Pause SLA On",
|
||||||
"options": "Pause SLA On Status"
|
"options": "Pause SLA On Status"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "filters_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Assignment Condition"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_15",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "condition",
|
||||||
|
"fieldtype": "Code",
|
||||||
|
"label": "Condition",
|
||||||
|
"options": "Python"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "condition_description",
|
||||||
|
"fieldtype": "HTML",
|
||||||
|
"options": "<p><strong>Condition Examples:</strong></p>\n<pre>doc.status==\"Open\"<br>doc.due_date==nowdate()<br>doc.total > 40000\n</pre>"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-06-10 12:30:15.050785",
|
"modified": "2021-07-27 11:16:45.596579",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Support",
|
"module": "Support",
|
||||||
"name": "Service Level Agreement",
|
"name": "Service Level Agreement",
|
||||||
|
|||||||
@ -3,10 +3,12 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
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, get_weekdays, get_link_to_form
|
from frappe.utils import getdate, get_weekdays, get_link_to_form, nowdate
|
||||||
|
from frappe.utils.safe_exec import get_safe_globals
|
||||||
|
|
||||||
class ServiceLevelAgreement(Document):
|
class ServiceLevelAgreement(Document):
|
||||||
|
|
||||||
@ -14,6 +16,7 @@ class ServiceLevelAgreement(Document):
|
|||||||
self.validate_doc()
|
self.validate_doc()
|
||||||
self.check_priorities()
|
self.check_priorities()
|
||||||
self.check_support_and_resolution()
|
self.check_support_and_resolution()
|
||||||
|
self.validate_condition()
|
||||||
|
|
||||||
def check_priorities(self):
|
def check_priorities(self):
|
||||||
default_priority = []
|
default_priority = []
|
||||||
@ -92,6 +95,14 @@ class ServiceLevelAgreement(Document):
|
|||||||
if frappe.db.exists("Service Level Agreement", {"entity_type": self.entity_type, "entity": self.entity, "name": ["!=", self.name]}):
|
if frappe.db.exists("Service Level Agreement", {"entity_type": self.entity_type, "entity": self.entity, "name": ["!=", self.name]}):
|
||||||
frappe.throw(_("Service Level Agreement with Entity Type {0} and Entity {1} already exists.").format(self.entity_type, self.entity))
|
frappe.throw(_("Service Level Agreement with Entity Type {0} and Entity {1} already exists.").format(self.entity_type, self.entity))
|
||||||
|
|
||||||
|
def validate_condition(self):
|
||||||
|
temp_doc = frappe.new_doc('Issue')
|
||||||
|
if self.condition:
|
||||||
|
try:
|
||||||
|
frappe.safe_eval(self.condition, None, get_context(temp_doc))
|
||||||
|
except Exception:
|
||||||
|
frappe.throw(_("The Condition '{0}' is invalid").format(self.condition))
|
||||||
|
|
||||||
def get_service_level_agreement_priority(self, priority):
|
def get_service_level_agreement_priority(self, priority):
|
||||||
priority = frappe.get_doc("Service Level Priority", {"priority": priority, "parent": self.name})
|
priority = frappe.get_doc("Service Level Priority", {"priority": priority, "parent": self.name})
|
||||||
|
|
||||||
@ -112,7 +123,7 @@ def check_agreement_status():
|
|||||||
if doc.end_date and getdate(doc.end_date) < getdate(frappe.utils.getdate()):
|
if doc.end_date and getdate(doc.end_date) < getdate(frappe.utils.getdate()):
|
||||||
frappe.db.set_value("Service Level Agreement", service_level_agreement.name, "active", 0)
|
frappe.db.set_value("Service Level Agreement", service_level_agreement.name, "active", 0)
|
||||||
|
|
||||||
def get_active_service_level_agreement_for(priority, customer=None, service_level_agreement=None):
|
def get_active_service_level_agreement_for(doc):
|
||||||
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"):
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -121,23 +132,42 @@ def get_active_service_level_agreement_for(priority, customer=None, service_leve
|
|||||||
["Service Level Agreement", "enable", "=", 1]
|
["Service Level Agreement", "enable", "=", 1]
|
||||||
]
|
]
|
||||||
|
|
||||||
if priority:
|
if doc.get('priority'):
|
||||||
filters.append(["Service Level Priority", "priority", "=", priority])
|
filters.append(["Service Level Priority", "priority", "=", doc.get('priority')])
|
||||||
|
|
||||||
|
customer = doc.get('customer')
|
||||||
or_filters = [
|
or_filters = [
|
||||||
["Service Level Agreement", "entity", "in", [customer, get_customer_group(customer), get_customer_territory(customer)]]
|
["Service Level Agreement", "entity", "in", [customer, get_customer_group(customer), get_customer_territory(customer)]]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
service_level_agreement = doc.get('service_level_agreement')
|
||||||
if service_level_agreement:
|
if service_level_agreement:
|
||||||
or_filters = [
|
or_filters = [
|
||||||
["Service Level Agreement", "name", "=", service_level_agreement],
|
["Service Level Agreement", "name", "=", doc.get('service_level_agreement')],
|
||||||
]
|
]
|
||||||
|
|
||||||
or_filters.append(["Service Level Agreement", "default_service_level_agreement", "=", 1])
|
default_sla_filter = filters + [["Service Level Agreement", "default_service_level_agreement", "=", 1]]
|
||||||
|
default_sla = frappe.get_all("Service Level Agreement", filters=default_sla_filter,
|
||||||
|
fields=["name", "default_priority", "condition"])
|
||||||
|
|
||||||
agreement = frappe.get_list("Service Level Agreement", filters=filters, or_filters=or_filters,
|
filters += [["Service Level Agreement", "default_service_level_agreement", "=", 0]]
|
||||||
fields=["name", "default_priority"])
|
agreements = frappe.get_all("Service Level Agreement", filters=filters, or_filters=or_filters,
|
||||||
|
fields=["name", "default_priority", "condition"])
|
||||||
|
|
||||||
return agreement[0] if agreement else None
|
# check if the current document on which SLA is to be applied fulfills all the conditions
|
||||||
|
filtered_agreements = []
|
||||||
|
for agreement in agreements:
|
||||||
|
condition = agreement.get('condition')
|
||||||
|
if not condition or (condition and frappe.safe_eval(condition, None, get_context(doc))):
|
||||||
|
filtered_agreements.append(agreement)
|
||||||
|
|
||||||
|
# if any default sla
|
||||||
|
filtered_agreements += default_sla
|
||||||
|
|
||||||
|
return filtered_agreements[0] if filtered_agreements else None
|
||||||
|
|
||||||
|
def get_context(doc):
|
||||||
|
return {"doc": doc.as_dict(), "nowdate": nowdate, "frappe": frappe._dict(utils=get_safe_globals().get("frappe").get("utils"))}
|
||||||
|
|
||||||
def get_customer_group(customer):
|
def get_customer_group(customer):
|
||||||
if customer:
|
if customer:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user