fix: also consider condition in sla while setting it on lead/deal

This commit is contained in:
Shariq Ansari 2023-12-13 21:23:56 +05:30
parent 08311784b4
commit c9ff153412
3 changed files with 67 additions and 12 deletions

View File

@ -5,6 +5,8 @@ import frappe
from frappe import _
from frappe.model.document import Document
from crm.fcrm.doctype.crm_service_level_agreement.utils import get_sla
class CRMDeal(Document):
def before_validate(self):
@ -55,7 +57,7 @@ class CRMDeal(Document):
"""
Find an SLA to apply to the deal.
"""
sla = get_sla("CRM Deal")
sla = get_sla(self)
if not sla:
return
self.sla = sla.name
@ -176,8 +178,3 @@ def set_primary_contact(deal, contact):
deal.save()
return True
def get_sla(doctype):
sla = frappe.db.exists("CRM Service Level Agreement", {"apply_on": doctype, "enabled": 1})
if not sla:
return None
return frappe.get_cached_doc("CRM Service Level Agreement", sla)

View File

@ -6,6 +6,7 @@ from frappe import _
from frappe.model.document import Document
from frappe.utils import has_gravatar, validate_email_address
from crm.fcrm.doctype.crm_service_level_agreement.utils import get_sla
class CRMLead(Document):
@ -131,7 +132,7 @@ class CRMLead(Document):
"""
Find an SLA to apply to the lead.
"""
sla = get_sla("CRM Lead")
sla = get_sla(self)
if not sla:
return
self.sla = sla.name
@ -240,8 +241,3 @@ def convert_to_deal(lead):
lead.save()
return deal
def get_sla(doctype):
sla = frappe.db.exists("CRM Service Level Agreement", {"apply_on": doctype, "enabled": 1})
if not sla:
return None
return frappe.get_cached_doc("CRM Service Level Agreement", sla)

View File

@ -0,0 +1,62 @@
import frappe
from frappe.model.document import Document
from frappe.query_builder import JoinType
from frappe.utils.safe_exec import get_safe_globals
DOCTYPE = "CRM Service Level Agreement"
def get_sla(doc: Document) -> Document:
"""
Get Service Level Agreement for `doc`
:param doc: Lead/Deal to use
:return: Applicable SLA
"""
check_permissions(DOCTYPE, None)
SLA = frappe.qb.DocType(DOCTYPE)
Priority = frappe.qb.DocType("CRM Service Level Priority")
priority = doc.communication_status
q = (
frappe.qb.from_(SLA)
.select(SLA.name, SLA.condition)
.where(SLA.apply_on == doc.doctype)
.where(SLA.enabled == True)
)
if priority:
q = (
q.join(Priority, JoinType.inner)
.on(Priority.parent == SLA.name)
.where(Priority.priority == priority)
)
sla_list = q.run(as_dict=True)
res = None
for sla in sla_list:
cond = sla.get("condition")
if not cond or frappe.safe_eval(cond, None, get_context(doc)):
res = sla
break
return res
def check_permissions(doctype, parent):
user = frappe.session.user
permissions = ("select", "read")
has_select_permission, has_read_permission = [
frappe.has_permission(doctype, perm, user=user, parent_doctype=parent)
for perm in permissions
]
if not has_select_permission and not has_read_permission:
frappe.throw(f"Insufficient Permission for {doctype}", frappe.PermissionError)
def get_context(d: Document) -> dict:
"""
Get safe context for `safe_eval`
:param doc: `Document` to add in context
:return: Context with `doc` and safe variables
"""
utils = get_safe_globals().get("frappe").get("utils")
return {
"doc": d.as_dict(),
"frappe": frappe._dict(utils=utils),
}