3CX 14.0.44241.523 CDRENABLE не работает

  • Автор темы Автор темы adgroup
  • Дата начала Дата начала

adgroup

Регистрация
18 Авг 2015
Сообщения
47
Обновил v 12.5 на 14 (удалил, переинсталировал и загрузил настройки через восстановление). Обратил внимание что функция CDRENABLE перестала работать, а именно не происходит экспорт протокола звонкой в текстовый файл, а также не делается выдача протокола звонков через TCP/UDP соединение согластно настроек в файлах CDRTemplate*.xml
 
После того, как при переходе с v 12.0 на v 12.5 в при выдаче CDR информации вместо зонального времени начало выдаваться время звонка без учета временного пояса, я уже ничему не удивляюсь. Тем более, что в анонсах v 14 отмечалось, что в ней будет радикально переработан модуль отчетов.
 
Время UTC меня не пугало, я быстро адаптировал систему к нему, там только была загвоздка с корректным переводом времени так как летнее/зимнее в разные года в разные даты происходит, по этому данный момент нужно было определять на базе самой даты в логах через API винды. В принципе это правильно, так как АТС может стоять одна а внутренние номера могут разбросаны быть по всему миру, попробуй потом по логам сообразить кто когда звонил если внутренние абоненты в разных часовых поясах сидят. Новшество вполне корректное, а вот с протоколом звонков беда, никак не получилось достать системными средствами, единственное пока решение это уже напрямую подключился к базе данных 3CX (PostgreSQL) и сижу разбираюсь с табличками.
 
http://www.toughdev.com/viewpost.php?id=3365167671865144840
 
Спасибо, полезная статься, только для версий до 12.5 включительно, в 14 версии протокол звонков находится уже в других таблицах (cl_calls, cl_participants, cl_party_info, cl_segments). Но все равно спасибо.
 
Удалось кому-то понять модель данных (cl_calls, cl_participants, cl_party_info, cl_segments), чтобы выгружать отчеты по звонкам?
 
В данный момент CDR логи не поддерживаются. Мы сообщим, как только этот функционал будет восстановлен.
 
>> Удалось кому-то понять модель данных (cl_calls, cl_participants, cl_party_info, cl_segments), чтобы выгружать отчеты по звонкам?

Да, я разобрался в таблицах (может не на 100%) и логи напрямую читаю из SQL базы. Намного удобнее чем раньше через CDR. Могу проконсультировать или подсказать в рамках того что знаю. Сейчас по факту я читаю лог, вывожу с своем приложении таблицу на экран и основная задача это выделить пропущенные звонки, чтоб можно было отзвониться про клиентам, это также реализовано.
 
В скором времени 3CX планирует выпустить универсальный API, который объединит в себе ныне разрозненные функции (CDR, CRM интеграция, управление вызовами, статусы номеров и т.п.)
 
Тоже интересно, будем разбираться.
 
Здорово, универсальный API это хорошо. Но до того времени надо как-то получать и обрабатывать информацию.
Ув. adgroup, если не сложно, можете сбросить пример, где видны связи между табицами? У меня основной затык в том, что звонки в результирующей выборке дублируются, т.к. каждый звонок (cl_calls) имеет кучу сегментов (cl_segments), и по каким условиям отбросить дублируюшие записи, пока не совсем ясно.
Если не в форуме, то на lospejos (at) gmail.com
Спасибо.
 
Боюсь тут не помогу. Дело в том, что я читаю все эти таблицы за определенный промежуток времени и раскладываю потом в памяти в виде объектной модели. При этом я не использую "сложных" SQL запросов. Тут нужно рассматривать конкретно Ваш случай и конкретный пример с дублирующимеся звонками чтоб понять в чем может быть причина.
 
Ну, просить Вас решить за меня проблему дубляжа было бы совсем наглостью с моей стороны.
А можете показать какие-то SQL, как вы связываете таблицы (cl_calls, cl_fragments, cl_participants)?
 
Буду писать вырезками из своего кода на Delphi с комментариями.
Суть следующего кода в том, чтоб получить протокол звонков за последние несколько (FLastDays) дней от текущей даты.
Для этой цели сначала на основе даты начала периода определяю cl_calls.id
Затем отдельно читаю таблицу cl_calls и отдельно читаю cl_segments с объединением в нее cl_participants и cl_party_info.
Последний запрос был взят по мотивам из самой базы PostgreeSQL, там есть встроенная функция database_single.cl_get_call_log
По идее она должна как раз и собирать лог звонков (судя из названия), внутри нее есть комментарии и выборка звонков на основе их типа и ряда условий, бегло пробежавшись видно что информация там очень полезная и выборка делается как-то с учетом специфики внутреннего хранения информации (анализируются типы звонков и ряд дополнительных значений). Возможно внутри нее и кроется ответ на Ваш вопрос. Но я не стал с ней разбираться, я был ограничен по времени. А вообще там есть много полезных готовых функций, даже по их названиям легко понять их назначения, но нужно разобраться как их правильно применять.

// получаем минимальное ID (текущая дата минус заданное число дней) от которого потом делаем чтение таблиц
mincallid:=0;
st:='SELECT min(id) FROM cl_calls WHERE start_time>='+#39+formatdatetime2('yyyy.mm.dd hh:nn:ss',int(now-FLastDays))+#39;
FDQuery1.Open(st);
if not FDQuery1.Eof then
begin
mincallid:=VariantToId(FDQuery1.Fields[0].Value);
end;

// получаем звонки
FDQuery1.SQL.Clear;
FDQuery1.Open('SELECT * FROM cl_calls WHERE id>='+IntToStr(mincallid));

// получаем сегменты звонков с доп информацией
FDQuery1.SQL.Clear;
FDQuery1.Open('SELECT cl_segments.*, '+
'src_p.id AS srcp_id, src_p.info_id AS srcp_info_id, src_p.start_time AS srcp_start_time, src_p.answer_time AS srcp_answer_time, src_p.end_time AS srcp_end_time, src_p.recording_url AS srcp_recording_url, '+
'dst_p.id AS dstp_id, dst_p.info_id AS dstp_info_id, dst_p.start_time AS dstp_start_time, dst_p.answer_time AS dstp_answer_time, dst_p.end_time AS dstp_end_time, dst_p.recording_url AS dstp_recording_url, '+
'src_info.id AS srci_id, src_info.dn_type AS srci_dn_type, src_info.dn AS srci_dn, src_info.caller_number AS srci_caller_number, src_info.display_name AS srci_display_name, src_info.dn_class AS srci_dn_class, '+
'dst_info.id AS dsti_id, dst_info.dn_type AS dsti_dn_type, dst_info.dn AS dsti_dn, dst_info.caller_number AS dsti_caller_number, dst_info.display_name AS dsti_display_name, dst_info.dn_class AS dsti_dn_class '+
'FROM cl_segments '+
'join cl_participants src_p on src_p.id = cl_segments.src_part_id '+
'join cl_participants dst_p on dst_p.id = cl_segments.dst_part_id '+
'join cl_party_info src_info on src_info.id = src_p.info_id '+
'join cl_party_info dst_info on dst_info.id = dst_p.info_id '+
'WHERE cl_segments.call_id>='+IntToStr(mincallid)+' ORDER BY cl_segments.id');
 
Спасибо огромное, буду разбираться.
 

Для администраторов

Статистика форума

Темы
44.777
Сообщения
233.707
Пользователи
78.510
Новый пользователь
florianb
#