fix: Update call_popup

- Setup missed & call ended listeners
- Show contacts based on links
This commit is contained in:
Suraj Shetty 2021-02-08 20:13:23 +05:30
parent c5248b30eb
commit dcc9947d10
2 changed files with 125 additions and 116 deletions

View File

@ -352,7 +352,7 @@ def get_lead_with_phone_number(number):
leads = frappe.get_all('Lead', or_filters={
'phone': ['like', '%{}'.format(number)],
'mobile_no': ['like', '%{}'.format(number)]
}, limit=1)
}, limit=1, order_by="creation DESC")
lead = leads[0].name if leads else None
@ -361,4 +361,4 @@ def get_lead_with_phone_number(number):
def daily_open_lead():
leads = frappe.get_all("Lead", filters = [["contact_date", "Between", [nowdate(), nowdate()]]])
for lead in leads:
frappe.db.set_value("Lead", lead.name, "status", "Open")
frappe.db.set_value("Lead", lead.name, "status", "Open")

View File

@ -7,10 +7,103 @@ class CallPopup {
}
make() {
frappe.utils.play_sound('incoming-call');
this.dialog = new frappe.ui.Dialog({
'static': true,
'minimizable': true,
'fields': [{
'minimizable': true
});
this.dialog.get_close_btn().show();
this.setup_dialog();
this.set_call_status();
frappe.utils.bind_actions_with_object(this.dialog.$body, this);
this.dialog.$wrapper.addClass('call-popup');
this.dialog.get_close_btn().unbind('click').click(this.close_modal.bind(this));
this.dialog.show();
}
setup_dialog() {
this.setup_call_details();
this.dialog.$body.empty().append(this.caller_info);
}
set_indicator(color, blink=false) {
let classes = `indicator ${color} ${blink ? 'blink': ''}`;
this.dialog.header.find('.indicator').attr('class', classes);
}
set_call_status(call_status) {
let title = '';
call_status = call_status || this.call_log.status;
if (['Ringing'].includes(call_status) || !call_status) {
title = __('Incoming call from {0}', [this.get_caller_name() || this.caller_number]);
this.set_indicator('blue', true);
} else if (call_status === 'In Progress') {
title = __('Call Connected');
this.set_indicator('green');
} else if (['No Answer', 'Missed'].includes(call_status)) {
this.set_indicator('yellow');
title = __('Call Missed');
} else if (['Completed', 'Busy', 'Failed'].includes(call_status)) {
this.set_indicator('red');
title = __('Call Ended');
} else {
this.set_indicator('blue');
title = call_status;
}
this.dialog.set_title(title);
}
update_call_log(call_log, missed) {
this.call_log = call_log;
this.set_call_status(missed ? 'Missed': null);
}
close_modal() {
this.dialog.hide();
delete erpnext.call_popup;
}
call_ended(call_log, missed) {
frappe.utils.play_sound('call-disconnect');
this.update_call_log(call_log, missed);
setTimeout(() => {
if (!this.dialog.get_value('call_summary')) {
this.close_modal();
}
}, 60000);
this.clear_listeners();
}
get_caller_name() {
const contact_link = this.get_contact_link();
return contact_link.link_title || contact_link.link_name;
}
get_contact_link() {
let log = this.call_log;
let contact_link = log.links.find(d => d.link_doctype === 'Contact');
return contact_link || {};
}
setup_listener() {
frappe.realtime.on(`call_${this.call_log.id}_ended`, call_log => {
this.call_ended(call_log);
});
frappe.realtime.on(`call_${this.call_log.id}_missed`, call_log => {
this.call_ended(call_log, true);
});
}
clear_listeners() {
frappe.realtime.off(`call_${this.call_log.id}_ended`);
frappe.realtime.off(`call_${this.call_log.id}_missed`);
}
setup_call_details() {
this.caller_info = $(`<div></div>`);
this.call_details = new frappe.ui.FieldGroup({
fields: [{
'fieldname': 'name',
'label': 'Name',
'default': this.get_caller_name() || __('Unknown Caller'),
@ -19,17 +112,17 @@ class CallPopup {
}, {
'fieldtype': 'Button',
'label': __('Open Contact'),
'click': () => frappe.set_route('Form', 'Contact', this.call_log.contact),
'depends_on': () => this.call_log.contact
}, {
'fieldtype': 'Button',
'label': __('Open Lead'),
'click': () => frappe.set_route('Form', 'Lead', this.call_log.lead),
'depends_on': () => this.call_log.lead
'click': () => frappe.set_route('Form', 'Contact', this.get_contact_link().link_name),
'depends_on': () => this.get_caller_name()
}, {
'fieldtype': 'Button',
'label': __('Create New Contact'),
'click': () => frappe.new_doc('Contact', { 'mobile_no': this.caller_number }),
'click': this.create_new_contact.bind(this),
'depends_on': () => !this.get_caller_name()
}, {
'fieldtype': 'Button',
'label': __('Create New Customer'),
'click': this.create_new_customer.bind(this),
'depends_on': () => !this.get_caller_name()
}, {
'fieldtype': 'Button',
@ -44,26 +137,9 @@ class CallPopup {
'fieldtype': 'Data',
'default': this.caller_number,
'read_only': 1
}, {
'fielname': 'last_interaction',
'fieldtype': 'Section Break',
'label': __('Activity'),
'depends_on': () => this.get_caller_name()
}, {
'fieldtype': 'Small Text',
'label': __('Last Issue'),
'fieldname': 'last_issue',
'read_only': true,
'depends_on': () => this.call_log.contact,
'default': `<i class="text-muted">${__('No issue has been raised by the caller.')}<i>`
}, {
'fieldtype': 'Small Text',
'label': __('Last Communication'),
'fieldname': 'last_communication',
'read_only': true,
'default': `<i class="text-muted">${__('No communication found.')}<i>`
}, {
'fieldtype': 'Section Break',
'hide_border': 1,
}, {
'fieldtype': 'Small Text',
'label': __('Call Summary'),
@ -72,7 +148,7 @@ class CallPopup {
'fieldtype': 'Button',
'label': __('Save'),
'click': () => {
const call_summary = this.dialog.get_value('call_summary');
const call_summary = this.call_details.get_value('call_summary');
if (!call_summary) return;
frappe.xcall('erpnext.telephony.doctype.call_log.call_log.add_call_summary', {
'call_log': this.call_log.name,
@ -94,98 +170,29 @@ class CallPopup {
});
}
}],
body: this.caller_info
});
this.set_call_status();
this.dialog.get_close_btn().show();
this.make_last_interaction_section();
this.dialog.$body.addClass('call-popup');
this.dialog.set_secondary_action(this.close_modal.bind(this));
frappe.utils.play_sound('incoming-call');
this.dialog.show();
this.call_details.make();
}
set_indicator(color, blink=false) {
let classes = `indicator ${color} ${blink ? 'blink': ''}`;
this.dialog.header.find('.indicator').attr('class', classes);
is_known_caller() {
return Boolean(this.get_caller_name());
}
set_call_status(call_status) {
let title = '';
call_status = call_status || this.call_log.status;
if (['Ringing'].includes(call_status) || !call_status) {
title = __('Incoming call from {0}', [this.get_caller_name() || this.caller_number]);
this.set_indicator('blue', true);
} else if (call_status === 'In Progress') {
title = __('Call Connected');
this.set_indicator('yellow');
} else if (call_status === 'Missed') {
this.set_indicator('red');
title = __('Call Missed');
} else if (['Completed', 'Disconnected'].includes(call_status)) {
this.set_indicator('red');
title = __('Call Disconnected');
} else {
this.set_indicator('blue');
title = call_status;
}
this.dialog.set_title(title);
create_new_customer() {
// to avoid quick entry form
const new_customer = frappe.model.get_new_doc('Customer');
new_customer.mobile_no = this.caller_number;
frappe.set_route('Form', new_customer.doctype, new_customer.name);
}
update_call_log(call_log) {
this.call_log = call_log;
this.set_call_status();
}
close_modal() {
this.dialog.hide();
delete erpnext.call_popup;
}
call_disconnected(call_log) {
frappe.utils.play_sound('call-disconnect');
this.update_call_log(call_log);
setTimeout(() => {
if (!this.dialog.get_value('call_summary')) {
this.close_modal();
}
}, 30000);
}
make_last_interaction_section() {
frappe.xcall('erpnext.crm.doctype.utils.get_last_interaction', {
'contact': this.call_log.contact,
'lead': this.call_log.lead
}).then(data => {
const comm_field = this.dialog.get_field('last_communication');
if (data.last_communication) {
const comm = data.last_communication;
comm_field.set_value(comm.content);
}
if (data.last_issue) {
const issue = data.last_issue;
const issue_field = this.dialog.get_field("last_issue");
issue_field.set_value(issue.subject);
issue_field.$wrapper.append(`
<a class="text-medium" href="/app/issue?customer=${issue.customer}">
${__('View all issues from {0}', [issue.customer])}
</a>
`);
}
});
}
get_caller_name() {
let log = this.call_log;
return log.contact_name || log.lead_name;
}
setup_listener() {
frappe.realtime.on(`call_${this.call_log.id}_disconnected`, call_log => {
this.call_disconnected(call_log);
// Remove call disconnect listener after the call is disconnected
frappe.realtime.off(`call_${this.call_log.id}_disconnected`);
});
create_new_contact() {
// TODO: fix new_doc, it should accept child table values
const new_contact = frappe.model.get_new_doc('Contact');
const phone_no = frappe.model.add_child(new_contact, 'Contact Phone', 'phone_nos');
phone_no.phone = this.caller_number;
phone_no.is_primary_mobile_no = 1;
frappe.set_route('Form', new_contact.doctype, new_contact.name);
}
}
@ -200,3 +207,5 @@ $(document).on('app_ready', function () {
}
});
});
window.CallPopup = CallPopup;