fix: load lead contact data if contact doesn't exist

This commit is contained in:
Shariq Ansari 2024-01-12 16:05:44 +05:30
parent 4dcaab9fc2
commit 75c4b35d08
6 changed files with 94 additions and 18 deletions

View File

@ -60,6 +60,27 @@ def get_contacts():
return contacts return contacts
@frappe.whitelist()
def get_lead_contacts():
if frappe.session.user == "Guest":
frappe.throw("Authentication failed", exc=frappe.AuthenticationError)
lead_contacts = frappe.get_all(
"CRM Lead",
fields=[
"name",
"lead_name",
"mobile_no",
"phone",
"image",
"modified"
],
order_by="lead_name asc",
distinct=True,
)
return lead_contacts
@frappe.whitelist() @frappe.whitelist()
def get_organizations(): def get_organizations():
if frappe.session.user == "Guest": if frappe.session.user == "Guest":

View File

@ -727,7 +727,7 @@ import { ref, computed, h, defineModel, markRaw, watch, nextTick } from 'vue'
const { makeCall } = globalStore() const { makeCall } = globalStore()
const { getUser } = usersStore() const { getUser } = usersStore()
const { getContact } = contactsStore() const { getContact, getLeadContact } = contactsStore()
const props = defineProps({ const props = defineProps({
title: { title: {
@ -783,8 +783,11 @@ const calls = createListResource({
doc.duration = secondsToDuration(doc.duration) doc.duration = secondsToDuration(doc.duration)
if (doc.type === 'Incoming') { if (doc.type === 'Incoming') {
doc.caller = { doc.caller = {
label: getContact(doc.from)?.full_name || 'Unknown', label:
image: getContact(doc.from)?.image, getContact(doc.from)?.full_name ||
getLeadContact(doc.from)?.full_name ||
'Unknown',
image: getContact(doc.from)?.image || getLeadContact(doc.from)?.image,
} }
doc.receiver = { doc.receiver = {
label: getUser(doc.receiver).full_name, label: getUser(doc.receiver).full_name,
@ -796,8 +799,11 @@ const calls = createListResource({
image: getUser(doc.caller).user_image, image: getUser(doc.caller).user_image,
} }
doc.receiver = { doc.receiver = {
label: getContact(doc.to)?.full_name || 'Unknown', label:
image: getContact(doc.to)?.image, getContact(doc.to)?.full_name ||
getLeadContact(doc.to)?.full_name ||
'Unknown',
image: getContact(doc.to)?.image || getLeadContact(doc.to)?.image,
} }
} }
}) })

View File

@ -188,7 +188,7 @@ import { contactsStore } from '@/stores/contacts'
import { Avatar, call } from 'frappe-ui' import { Avatar, call } from 'frappe-ui'
import { onMounted, ref, watch } from 'vue' import { onMounted, ref, watch } from 'vue'
const { getContact } = contactsStore() const { getContact, getLeadContact } = contactsStore()
const { setMakeCall, setTwilioEnabled } = globalStore() const { setMakeCall, setTwilioEnabled } = globalStore()
let device = '' let device = ''
@ -309,8 +309,10 @@ function handleIncomingCall(call) {
log.value = `Incoming call from ${call.parameters.From}` log.value = `Incoming call from ${call.parameters.From}`
// get name of the caller from the phone number // get name of the caller from the phone number
contact.value = getContact(call.parameters.From) contact.value = getContact(call.parameters.From)
if (!contact.value) {
contact.value = getLeadContact(call.parameters.From)
}
if (!contact.value) { if (!contact.value) {
contact.value = { contact.value = {
@ -381,6 +383,9 @@ function handleDisconnectedIncomingCall() {
async function makeOutgoingCall(number) { async function makeOutgoingCall(number) {
contact.value = getContact(number) contact.value = getContact(number)
if (!contact.value) {
contact.value = getLeadContact(number)
}
if (device) { if (device) {
log.value = `Attempting to call ${contact.value.mobile_no} ...` log.value = `Attempting to call ${contact.value.mobile_no} ...`

View File

@ -164,7 +164,7 @@ import { useRouter } from 'vue-router'
const router = useRouter() const router = useRouter()
const { getUser } = usersStore() const { getUser } = usersStore()
const { contacts, getContact } = contactsStore() const { contacts, getContact, getLeadContact } = contactsStore()
const props = defineProps({ const props = defineProps({
callLogId: { callLogId: {
@ -186,8 +186,11 @@ const callLog = createResource({
doc.duration = secondsToDuration(doc.duration) doc.duration = secondsToDuration(doc.duration)
if (doc.type === 'Incoming') { if (doc.type === 'Incoming') {
doc.caller = { doc.caller = {
label: getContact(doc.from)?.full_name || 'Unknown', label:
image: getContact(doc.from)?.image, getContact(doc.from)?.full_name ||
getLeadContact(doc.from)?.full_name ||
'Unknown',
image: getContact(doc.from)?.image || getLeadContact(doc.from)?.image,
} }
doc.receiver = { doc.receiver = {
label: getUser(doc.receiver).full_name, label: getUser(doc.receiver).full_name,
@ -199,8 +202,11 @@ const callLog = createResource({
image: getUser(doc.caller).user_image, image: getUser(doc.caller).user_image,
} }
doc.receiver = { doc.receiver = {
label: getContact(doc.to)?.full_name || 'Unknown', label:
image: getContact(doc.to)?.image, getContact(doc.to)?.full_name ||
getLeadContact(doc.to)?.full_name ||
'Unknown',
image: getContact(doc.to)?.image || getLeadContact(doc.to)?.image,
} }
} }
return doc return doc

View File

@ -4,7 +4,11 @@
<Breadcrumbs :items="breadcrumbs" /> <Breadcrumbs :items="breadcrumbs" />
</template> </template>
</LayoutHeader> </LayoutHeader>
<ViewControls v-model="callLogs" v-model:loadMore="loadMore" doctype="CRM Call Log" /> <ViewControls
v-model="callLogs"
v-model:loadMore="loadMore"
doctype="CRM Call Log"
/>
<CallLogsListView <CallLogsListView
v-if="callLogs.data && rows.length" v-if="callLogs.data && rows.length"
v-model="callLogs.data.page_length_count" v-model="callLogs.data.page_length_count"
@ -46,7 +50,7 @@ import { Breadcrumbs } from 'frappe-ui'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
const { getUser } = usersStore() const { getUser } = usersStore()
const { getContact } = contactsStore() const { getContact, getLeadContact } = contactsStore()
const breadcrumbs = [{ label: 'Call Logs', route: { name: 'Call Logs' } }] const breadcrumbs = [{ label: 'Call Logs', route: { name: 'Call Logs' } }]
@ -66,20 +70,26 @@ const rows = computed(() => {
if (row === 'caller') { if (row === 'caller') {
_rows[row] = { _rows[row] = {
label: incoming label: incoming
? getContact(callLog.from)?.full_name || 'Unknown' ? getContact(callLog.from)?.full_name ||
getLeadContact(callLog.from)?.full_name ||
'Unknown'
: getUser(callLog.caller).full_name, : getUser(callLog.caller).full_name,
image: incoming image: incoming
? getContact(callLog.from)?.image ? getContact(callLog.from)?.image ||
getLeadContact(callLog.from)?.image
: getUser(callLog.caller).user_image, : getUser(callLog.caller).user_image,
} }
} else if (row === 'receiver') { } else if (row === 'receiver') {
_rows[row] = { _rows[row] = {
label: incoming label: incoming
? getUser(callLog.receiver).full_name ? getUser(callLog.receiver).full_name
: getContact(callLog.to)?.full_name || 'Unknown', : getContact(callLog.to)?.full_name ||
getLeadContact(callLog.to)?.full_name ||
'Unknown',
image: incoming image: incoming
? getUser(callLog.receiver).user_image ? getUser(callLog.receiver).user_image
: getContact(callLog.to)?.image, : getContact(callLog.to)?.image ||
getLeadContact(callLog.to)?.image,
} }
} else if (row === 'duration') { } else if (row === 'duration') {
_rows[row] = { _rows[row] = {

View File

@ -5,6 +5,7 @@ import { reactive } from 'vue'
export const contactsStore = defineStore('crm-contacts', () => { export const contactsStore = defineStore('crm-contacts', () => {
let contactsByPhone = reactive({}) let contactsByPhone = reactive({})
let contactsByName = reactive({}) let contactsByName = reactive({})
let leadContactsByPhone = reactive({})
const contacts = createResource({ const contacts = createResource({
url: 'crm.api.session.get_contacts', url: 'crm.api.session.get_contacts',
@ -28,6 +29,28 @@ export const contactsStore = defineStore('crm-contacts', () => {
}, },
}) })
const leadContacts = createResource({
url: 'crm.api.session.get_lead_contacts',
cache: 'lead_contacts',
initialData: [],
auto: true,
transform(lead_contacts) {
for (let lead_contact of lead_contacts) {
// remove special characters from phone number to make it easier to search
// also remove spaces but keep + sign at the start
lead_contact.mobile_no = lead_contact.mobile_no.replace(/[^0-9+]/g, '')
lead_contact.full_name = lead_contact.lead_name
leadContactsByPhone[lead_contact.mobile_no] = lead_contact
}
return lead_contacts
},
onError(error) {
if (error && error.exc_type === 'AuthenticationError') {
router.push('/login')
}
},
})
function getContact(mobile_no) { function getContact(mobile_no) {
mobile_no = mobile_no.replace(/[^0-9+]/g, '') mobile_no = mobile_no.replace(/[^0-9+]/g, '')
return contactsByPhone[mobile_no] return contactsByPhone[mobile_no]
@ -35,10 +58,15 @@ export const contactsStore = defineStore('crm-contacts', () => {
function getContactByName(name) { function getContactByName(name) {
return contactsByName[name] return contactsByName[name]
} }
function getLeadContact(mobile_no) {
mobile_no = mobile_no.replace(/[^0-9+]/g, '')
return leadContactsByPhone[mobile_no]
}
return { return {
contacts, contacts,
getContact, getContact,
getContactByName, getContactByName,
getLeadContact,
} }
}) })