fix: show sla details on deal page
This commit is contained in:
parent
548b71b403
commit
78b9353735
@ -7,10 +7,16 @@ from frappe.model.document import Document
|
||||
|
||||
|
||||
class CRMDeal(Document):
|
||||
def before_validate(self):
|
||||
self.set_sla()
|
||||
|
||||
def validate(self):
|
||||
self.set_primary_contact()
|
||||
self.set_primary_email_mobile_no()
|
||||
|
||||
def before_save(self):
|
||||
self.apply_sla()
|
||||
|
||||
def set_primary_contact(self, contact=None):
|
||||
if not self.contacts:
|
||||
return
|
||||
@ -45,6 +51,22 @@ class CRMDeal(Document):
|
||||
self.email = ""
|
||||
self.mobile_no = ""
|
||||
|
||||
def set_sla(self):
|
||||
"""
|
||||
Find an SLA to apply to the deal.
|
||||
"""
|
||||
if sla := get_sla("CRM Deal"):
|
||||
if not sla:
|
||||
return
|
||||
self.sla = sla.name
|
||||
|
||||
def apply_sla(self):
|
||||
"""
|
||||
Apply SLA if set.
|
||||
"""
|
||||
if sla := frappe.get_last_doc("CRM Service Level Agreement", {"name": self.sla}):
|
||||
sla.apply(self)
|
||||
|
||||
@staticmethod
|
||||
def sort_options():
|
||||
return [
|
||||
@ -145,4 +167,10 @@ def set_primary_contact(deal, contact):
|
||||
deal = frappe.get_cached_doc("CRM Deal", deal)
|
||||
deal.set_primary_contact(contact)
|
||||
deal.save()
|
||||
return True
|
||||
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)
|
||||
|
||||
@ -94,6 +94,72 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="deal.data.sla_status" class="flex flex-col gap-2 border-b p-5">
|
||||
<div
|
||||
v-if="deal.data.sla_status == 'First Response Due'"
|
||||
class="flex items-center gap-4 text-base leading-5"
|
||||
>
|
||||
<div class="w-[106px] text-gray-600">Response By</div>
|
||||
<Tooltip
|
||||
:text="dateFormat(deal.data.response_by, 'ddd, MMM D, YYYY h:mm A')"
|
||||
class="cursor-pointer"
|
||||
>
|
||||
{{ timeAgo(deal.data.response_by) }}
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div
|
||||
v-if="deal.data.sla_status == 'Fulfilled'"
|
||||
class="flex items-center gap-4 text-base leading-5"
|
||||
>
|
||||
<div class="w-[106px] text-gray-600">Fulfilled In</div>
|
||||
<Tooltip
|
||||
:text="
|
||||
dateFormat(
|
||||
deal.data.first_responded_on,
|
||||
'ddd, MMM D, YYYY h:mm A'
|
||||
)
|
||||
"
|
||||
class="cursor-pointer"
|
||||
>
|
||||
{{ formatTime(deal.data.first_response_time) }}
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div
|
||||
v-if="
|
||||
deal.data.sla_status == 'Failed' && deal.data.first_responded_on
|
||||
"
|
||||
class="flex items-center gap-4 text-base leading-5"
|
||||
>
|
||||
<div class="w-[106px] text-gray-600">Fulfilled In</div>
|
||||
<Tooltip
|
||||
:text="
|
||||
dateFormat(
|
||||
deal.data.first_responded_on,
|
||||
'ddd, MMM D, YYYY h:mm A'
|
||||
)
|
||||
"
|
||||
class="cursor-pointer"
|
||||
>
|
||||
{{ formatTime(deal.data.first_response_time) }}
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div class="flex items-center gap-4 text-base leading-5">
|
||||
<div class="w-[106px] text-gray-600">Status</div>
|
||||
<div class="">
|
||||
<Badge
|
||||
:label="deal.data.sla_status"
|
||||
variant="outline"
|
||||
:theme="
|
||||
deal.data.sla_status === 'Failed'
|
||||
? 'red'
|
||||
: deal.data.sla_status === 'Fulfilled'
|
||||
? 'green'
|
||||
: 'gray'
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-1 flex-col justify-between overflow-hidden">
|
||||
<div class="flex flex-col overflow-y-auto">
|
||||
<div
|
||||
@ -275,7 +341,14 @@ import ContactModal from '@/components/Modals/ContactModal.vue'
|
||||
import Link from '@/components/Controls/Link.vue'
|
||||
import Section from '@/components/Section.vue'
|
||||
import SectionFields from '@/components/SectionFields.vue'
|
||||
import { openWebsite, createToast, activeAgents } from '@/utils'
|
||||
import {
|
||||
openWebsite,
|
||||
createToast,
|
||||
activeAgents,
|
||||
dateFormat,
|
||||
timeAgo,
|
||||
formatTime,
|
||||
} from '@/utils'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { contactsStore } from '@/stores/contacts'
|
||||
import { organizationsStore } from '@/stores/organizations'
|
||||
@ -313,6 +386,15 @@ const deal = createResource({
|
||||
params: { name: props.dealId },
|
||||
cache: ['deal', props.dealId],
|
||||
auto: true,
|
||||
onSuccess: (data) => {
|
||||
if (
|
||||
data.response_by &&
|
||||
data.sla_status == 'First Response Due' &&
|
||||
new Date(data.response_by) < new Date()
|
||||
) {
|
||||
updateField('sla_status', 'Failed')
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const reload = ref(false)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user