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):
|
class CRMDeal(Document):
|
||||||
|
def before_validate(self):
|
||||||
|
self.set_sla()
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.set_primary_contact()
|
self.set_primary_contact()
|
||||||
self.set_primary_email_mobile_no()
|
self.set_primary_email_mobile_no()
|
||||||
|
|
||||||
|
def before_save(self):
|
||||||
|
self.apply_sla()
|
||||||
|
|
||||||
def set_primary_contact(self, contact=None):
|
def set_primary_contact(self, contact=None):
|
||||||
if not self.contacts:
|
if not self.contacts:
|
||||||
return
|
return
|
||||||
@ -45,6 +51,22 @@ class CRMDeal(Document):
|
|||||||
self.email = ""
|
self.email = ""
|
||||||
self.mobile_no = ""
|
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
|
@staticmethod
|
||||||
def sort_options():
|
def sort_options():
|
||||||
return [
|
return [
|
||||||
@ -145,4 +167,10 @@ def set_primary_contact(deal, contact):
|
|||||||
deal = frappe.get_cached_doc("CRM Deal", deal)
|
deal = frappe.get_cached_doc("CRM Deal", deal)
|
||||||
deal.set_primary_contact(contact)
|
deal.set_primary_contact(contact)
|
||||||
deal.save()
|
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>
|
||||||
</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-1 flex-col justify-between overflow-hidden">
|
||||||
<div class="flex flex-col overflow-y-auto">
|
<div class="flex flex-col overflow-y-auto">
|
||||||
<div
|
<div
|
||||||
@ -275,7 +341,14 @@ import ContactModal from '@/components/Modals/ContactModal.vue'
|
|||||||
import Link from '@/components/Controls/Link.vue'
|
import Link from '@/components/Controls/Link.vue'
|
||||||
import Section from '@/components/Section.vue'
|
import Section from '@/components/Section.vue'
|
||||||
import SectionFields from '@/components/SectionFields.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 { usersStore } from '@/stores/users'
|
||||||
import { contactsStore } from '@/stores/contacts'
|
import { contactsStore } from '@/stores/contacts'
|
||||||
import { organizationsStore } from '@/stores/organizations'
|
import { organizationsStore } from '@/stores/organizations'
|
||||||
@ -313,6 +386,15 @@ const deal = createResource({
|
|||||||
params: { name: props.dealId },
|
params: { name: props.dealId },
|
||||||
cache: ['deal', props.dealId],
|
cache: ['deal', props.dealId],
|
||||||
auto: true,
|
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)
|
const reload = ref(false)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user