mirror of
https://github.com/frappe/erpnext.git
synced 2026-10-29 22:57:42 +00:00
fix(telephony): notify call agents of call end even after their popup slot ends
Status events re-checked the popup schedule, so an agent whose slot ended
during the call got no ended or missed event and the popup stayed open.
Send these events to all agents of the call's number. The schedule only
decides who gets a new popup.
(cherry picked from commit 963af0b809)
This commit is contained in:
@@ -81,15 +81,15 @@ class CallLog(Document):
|
||||
self.update_received_by()
|
||||
|
||||
if _is_call_missed(doc_before_save, self):
|
||||
self.notify_popup_recipients(doc_before_save, "missed")
|
||||
self.notify_call_agents(doc_before_save, "missed")
|
||||
self.trigger_call_popup()
|
||||
|
||||
if _is_call_ended(doc_before_save, self):
|
||||
self.notify_popup_recipients(doc_before_save, "ended")
|
||||
self.notify_call_agents(doc_before_save, "ended")
|
||||
|
||||
def notify_popup_recipients(self, doc_before_save: "CallLog", event: str):
|
||||
# The popup was shown for the call as it was before this update.
|
||||
for email in doc_before_save.get_popup_recipients():
|
||||
def notify_call_agents(self, doc_before_save: "CallLog", event: str):
|
||||
# Skip the schedule check: an agent whose slot ended mid-call must still close the popup.
|
||||
for email in doc_before_save.get_agent_emails():
|
||||
frappe.publish_realtime(f"call_{self.id}_{event}", self, user=email)
|
||||
|
||||
def is_incoming_call(self):
|
||||
@@ -124,12 +124,11 @@ class CallLog(Document):
|
||||
for email in emails:
|
||||
frappe.publish_realtime("show_call_popup", self, user=email)
|
||||
|
||||
def get_popup_recipients(self) -> set[str]:
|
||||
def get_agent_emails(self) -> set[str]:
|
||||
if not self.is_incoming_call():
|
||||
return set()
|
||||
|
||||
employee_emails = [employee.get("user_id") for employee in get_employees_with_number(self.to)]
|
||||
return set(get_scheduled_employees_for_popup(self.medium)).intersection(employee_emails)
|
||||
return {employee.get("user_id") for employee in get_employees_with_number(self.to)}
|
||||
|
||||
def update_received_by(self):
|
||||
if employees := get_employees_with_number(self.get("to")):
|
||||
|
||||
@@ -180,26 +180,26 @@ class TestCallLog(ERPNextTestSuite):
|
||||
(second_agent, "test_call_agent_b@example.com"),
|
||||
)
|
||||
|
||||
def test_call_status_events_go_only_to_popup_recipients(self):
|
||||
def test_call_status_events_go_only_to_agents_of_the_call(self):
|
||||
agent = "test_call_agent_a@example.com"
|
||||
make_employee(agent, company="_Test Company", cell_number=f"+91{self.number}1")
|
||||
make_employee(
|
||||
"test_call_agent_b@example.com", company="_Test Company", cell_number=f"+91{self.number}2"
|
||||
)
|
||||
schedule = "erpnext.telephony.doctype.call_log.call_log.get_scheduled_employees_for_popup"
|
||||
|
||||
for scheduled, expected_users in (([agent], [agent]), ([], [])):
|
||||
with patch(schedule, return_value=[agent]):
|
||||
call_log = frappe.get_doc(
|
||||
"Call Log", self._make_call_log(to=f"+91{self.number}1", type="Incoming", status="Ringing")
|
||||
)
|
||||
call_log.status = "Completed"
|
||||
with (
|
||||
patch(
|
||||
"erpnext.telephony.doctype.call_log.call_log.get_scheduled_employees_for_popup",
|
||||
return_value=scheduled,
|
||||
),
|
||||
patch.object(frappe, "publish_realtime") as publish,
|
||||
):
|
||||
call_log.save(ignore_permissions=True)
|
||||
|
||||
ended = [c for c in publish.call_args_list if c.args[0] == f"call_{call_log.id}_ended"]
|
||||
self.assertEqual([c.kwargs.get("user") for c in ended], expected_users)
|
||||
# The agent's popup slot ends before the call does.
|
||||
call_log.status = "Completed"
|
||||
with patch(schedule, return_value=[]), patch.object(frappe, "publish_realtime") as publish:
|
||||
call_log.save(ignore_permissions=True)
|
||||
|
||||
ended = [c for c in publish.call_args_list if c.args[0] == f"call_{call_log.id}_ended"]
|
||||
self.assertEqual([c.kwargs.get("user") for c in ended], [agent])
|
||||
|
||||
def test_summary_can_be_saved_without_call_type(self):
|
||||
add_call_summary_and_call_type(self.linked_log, "No type chosen", None)
|
||||
|
||||
Reference in New Issue
Block a user