fix: send and receive whatsapp message from/on lead/deal
This commit is contained in:
parent
4abd7291ad
commit
803d02f796
@ -336,25 +336,3 @@ def get_linked_tasks(name):
|
||||
],
|
||||
)
|
||||
return tasks or []
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_whatsapp_messages(doctype, name):
|
||||
whatsapp_messages = frappe.db.get_all(
|
||||
"WhatsApp Message",
|
||||
filters={"reference_doctype": doctype, "reference_name": name, "status": ("not in", ["failed"])},
|
||||
fields=["name", "type", "to", "from", "content_type", "creation", "message", "status"],
|
||||
)
|
||||
return whatsapp_messages or []
|
||||
|
||||
@frappe.whitelist()
|
||||
def create_whatsapp_message(reference_doctype, reference_name, to, message, content_type="text"):
|
||||
doc = frappe.new_doc("WhatsApp Message")
|
||||
doc.update({
|
||||
"reference_doctype": reference_doctype,
|
||||
"reference_name": reference_name,
|
||||
"to": to,
|
||||
"message": message,
|
||||
"content_type": content_type,
|
||||
})
|
||||
doc.insert(ignore_permissions=True)
|
||||
return doc.name
|
||||
54
crm/api/whatsapp.py
Normal file
54
crm/api/whatsapp.py
Normal file
@ -0,0 +1,54 @@
|
||||
import frappe
|
||||
|
||||
def validate(doc, method):
|
||||
if doc.type == "Incoming" and doc.get("from"):
|
||||
name, doctype = get_lead_or_deal_from_number(doc.get("from"))
|
||||
doc.reference_doctype = doctype
|
||||
doc.reference_name = name
|
||||
|
||||
def get_lead_or_deal_from_number(number):
|
||||
"""Get lead/deal from the given number.
|
||||
"""
|
||||
|
||||
def find_record(doctype, mobile_no, where=''):
|
||||
mobile_no = parse_mobile_no(mobile_no)
|
||||
|
||||
query = f"""
|
||||
SELECT name, mobile_no
|
||||
FROM `tab{doctype}`
|
||||
WHERE CONCAT('+', REGEXP_REPLACE(mobile_no, '[^0-9]', '')) = {mobile_no}
|
||||
"""
|
||||
|
||||
data = frappe.db.sql(query + where, as_dict=True)
|
||||
return data[0].name if data else None
|
||||
|
||||
doctype = "CRM Deal"
|
||||
|
||||
doc = find_record(doctype, number) or None
|
||||
if not doc:
|
||||
doctype = "CRM Lead"
|
||||
doc = find_record(doctype, number, 'AND converted is not True')
|
||||
if not doc:
|
||||
doc = find_record(doctype, number)
|
||||
|
||||
return doc, doctype
|
||||
|
||||
def parse_mobile_no(mobile_no: str):
|
||||
"""Parse mobile number to remove spaces, brackets, etc.
|
||||
>>> parse_mobile_no('+91 (766) 667 6666')
|
||||
... '+917666676666'
|
||||
"""
|
||||
return ''.join([c for c in mobile_no if c.isdigit() or c == '+'])
|
||||
|
||||
@frappe.whitelist()
|
||||
def create_whatsapp_message(reference_doctype, reference_name, to, message, content_type="text"):
|
||||
doc = frappe.new_doc("WhatsApp Message")
|
||||
doc.update({
|
||||
"reference_doctype": reference_doctype,
|
||||
"reference_name": reference_name,
|
||||
"to": to,
|
||||
"message": message,
|
||||
"content_type": content_type,
|
||||
})
|
||||
doc.insert(ignore_permissions=True)
|
||||
return doc.name
|
||||
@ -135,7 +135,10 @@ doc_events = {
|
||||
},
|
||||
"Comment": {
|
||||
"on_update": ["crm.api.comment.on_update"],
|
||||
}
|
||||
},
|
||||
"WhatsApp Message": {
|
||||
"validate": ["crm.api.whatsapp.validate"],
|
||||
},
|
||||
}
|
||||
|
||||
# Scheduled Tasks
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
<RefreshIcon class="h-4 w-4" />
|
||||
</template>
|
||||
</Button>
|
||||
<Button variant="solid" @click="$refs.whatsappBox.show = true">
|
||||
<Button variant="solid" @click="$refs.whatsappBox.show()">
|
||||
<template #prefix>
|
||||
<FeatherIcon name="plus" class="h-4 w-4" />
|
||||
</template>
|
||||
@ -78,7 +78,7 @@
|
||||
{
|
||||
icon: h(WhatsAppIcon, { class: 'h-4 w-4' }),
|
||||
label: __('New WhatsApp Message'),
|
||||
onClick: () => ($refs.emailBox.show = true),
|
||||
onClick: () => (tabIndex = 5),
|
||||
},
|
||||
]"
|
||||
@click.stop
|
||||
@ -845,6 +845,7 @@ import {
|
||||
TextEditor,
|
||||
Avatar,
|
||||
createResource,
|
||||
createListResource,
|
||||
call,
|
||||
} from 'frappe-ui'
|
||||
import { useElementVisibility } from '@vueuse/core'
|
||||
@ -868,6 +869,7 @@ const props = defineProps({
|
||||
|
||||
const doc = defineModel()
|
||||
const reload = defineModel('reload')
|
||||
const tabIndex = defineModel('tabIndex')
|
||||
|
||||
const reload_email = ref(false)
|
||||
|
||||
@ -915,10 +917,27 @@ const all_activities = createResource({
|
||||
},
|
||||
})
|
||||
|
||||
const whatsappMessages = createResource({
|
||||
url: 'crm.api.activities.get_whatsapp_messages',
|
||||
params: { doctype: props.doctype, name: doc.value.data.name },
|
||||
cache: ['whatsapp', doc.value.data.name],
|
||||
const whatsappMessages = createListResource({
|
||||
type: 'list',
|
||||
doctype: 'WhatsApp Message',
|
||||
cache: ['whatsapp_message', doc.value.data.name],
|
||||
fields: [
|
||||
'name',
|
||||
'type',
|
||||
'to',
|
||||
'from',
|
||||
'content_type',
|
||||
'creation',
|
||||
'message',
|
||||
'status',
|
||||
],
|
||||
filters: {
|
||||
reference_doctype: props.doctype,
|
||||
reference_name: doc.value.data.name,
|
||||
status: ['!=', 'failed'],
|
||||
},
|
||||
orderBy: 'modified desc',
|
||||
pageLength: 99999,
|
||||
auto: true,
|
||||
transform: (data) => sortByCreation(data),
|
||||
onSuccess: () => nextTick(() => scroll()),
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="flex items-end gap-2 px-10 py-2.5">
|
||||
<Textarea
|
||||
ref="textarea"
|
||||
type="textarea"
|
||||
class="min-h-8 w-full"
|
||||
:rows="rows"
|
||||
@ -8,6 +9,7 @@
|
||||
:placeholder="placeholder"
|
||||
@focus="rows = 6"
|
||||
@blur="rows = 1"
|
||||
@keydown.meta.enter="sendWhatsAppMessage"
|
||||
/>
|
||||
<div class="flex justify-end gap-2">
|
||||
<Button
|
||||
@ -32,6 +34,7 @@ const props = defineProps({
|
||||
const doc = defineModel()
|
||||
const whatsapp = defineModel('whatsapp')
|
||||
const rows = ref(1)
|
||||
const textarea = ref(null)
|
||||
|
||||
const content = ref('')
|
||||
const placeholder = ref(__('Type your message here...'))
|
||||
@ -40,6 +43,10 @@ const isEmpty = computed(() => {
|
||||
return !content.value || content.value === '<p></p>'
|
||||
})
|
||||
|
||||
function show() {
|
||||
nextTick(() => textarea.value.$el.focus())
|
||||
}
|
||||
|
||||
async function sendWhatsAppMessage() {
|
||||
let args = {
|
||||
reference_doctype: props.doctype,
|
||||
@ -50,10 +57,12 @@ async function sendWhatsAppMessage() {
|
||||
}
|
||||
content.value = ''
|
||||
createResource({
|
||||
url: 'crm.api.activities.create_whatsapp_message',
|
||||
url: 'crm.api.whatsapp.create_whatsapp_message',
|
||||
params: args,
|
||||
auto: true,
|
||||
onSuccess: () => nextTick(() => whatsapp.value?.reload()),
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
doctype="CRM Deal"
|
||||
:title="tab.name"
|
||||
v-model:reload="reload"
|
||||
v-model:tabIndex="tabIndex"
|
||||
v-model="deal"
|
||||
/>
|
||||
</Tabs>
|
||||
|
||||
@ -46,6 +46,7 @@
|
||||
doctype="CRM Lead"
|
||||
:title="tab.name"
|
||||
v-model:reload="reload"
|
||||
v-model:tabIndex="tabIndex"
|
||||
v-model="lead"
|
||||
/>
|
||||
</Tabs>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user