Project

General

Profile

Statistiques Call Center

Added by Mathieu ANDRE over 2 years ago

Bonjour,

J'ai une demande un peu spécifique de statistiques, j'ai fais le tour des options de configuration mais je ne pense pas que ce soit possible. Dans le doute, voici ce que je cherche à avoir :

Pouvoir afficher pour plusieurs jours simultanément les stats d'appels sur une plage horaire fixe. Par exemple connaitre le nombre d'appels reçus sur une semaine entre 8h et 10h sur une seule vue.

Actuellement la solution trouvée est de regarder jour par jour et d'additionner, peut on faire plus simple ?

Merci d'avance.


Replies (3)

RE: Statistiques Call Center - Added by dudu clx over 2 years ago

coucou,

sur spago bi ?
en requête postgresql sur la base xivocc ??

appels sur une file d'attente ou sur un(des) agent(s) ?

genre
statistiques file blablabla de 8h à 9h:
jour 1 | appels présentés | appels répondus | etc...
jour 2 | appels présentés | appels répondus | etc...

je te mets un exemple de tableau réaliser depuis du php, en tapant la bdd du xivo-cc.

exemple de requête:
$query_asterisk = "SELECT to_char(cq.queue_time,'YYYY-MM-DD') as date,
COUNT(CASE WHEN cq.status IN ('answered', 'abandoned', 'leaveempty', 'timeout', 'exit_with_key') OR cq.status IS NULL THEN 1 END) AS presente,
COUNT(CASE WHEN cq.answer_time IS NOT NULL THEN 1 END) as repondu,
to_char(AVG(CASE WHEN cq.answer_time IS NOT NULL THEN cq.hangup_time - cq.answer_time END), 'HH24:MI:SS') as duree_moyenne,
COUNT(CASE WHEN cq.status = 'timeout' THEN 1 END) as dissuade,
COUNT(CASE WHEN cq.status = 'abandoned' THEN 1 END) as abandonne,
COUNT(CASE WHEN cq.status = 'closed' THEN 1 END) as hors_horaires,
COUNT(CASE WHEN cq.status = 'abandoned' AND (cd.end_time - cq.queue_time) < '15 seconds'::interval THEN 1 END) as abandonne_t1,
to_char(SUM(CASE WHEN cq.status = 'answered' THEN
EXTRACT(epoch FROM (cq.answer_time - cq.queue_time)) ELSE 0 END) /
NULLIF(COUNT(CASE WHEN cq.status IN ('answered', 'abandoned', 'leaveempty', 'timeout', 'exit_with_key')
OR cq.status IS NULL THEN 1 END),0) * INTERVAL '1 second', 'HH24:MI:SS') as moyenne_temps_attente,
SUM(CASE WHEN cd.transfered THEN 1 ELSE 0 END) AS transfer,
ROUND(COUNT(CASE WHEN cq.answer_time IS NOT NULL THEN 1 END)::numeric /
NULLIF(COUNT(CASE WHEN cq.status IN ('answered', 'abandoned', 'leaveempty', 'timeout', 'exit_with_key')
OR cq.status IS NULL THEN 1 END),0)::numeric * 100,2) as pourcentage_decroche
FROM call_on_queue cq
LEFT JOIN call_data cd ON cq.callid = cd.uniqueid
WHERE to_char(cq.queue_time,'YYYY-MM-DD') between '$debut' AND '$fin'
AND queue_ref = '$real_fa_select'
GROUP BY 1";

$debut = date du jour au format YYYY-MM-DD
$fin = date du jour au format YYYY-MM-DD
$real_fa_select = nom de la file d'attente

tu peux donc limiter la vue à une tranche horaire, en rajoutant une condition:

AND to_char(cq.queue_time,'HH24:MI:SS') between '$heuredebut' AND '$heurefin'

et dans ta demande:
$heuredebut = 08:00:00
$heurefin = 09:00:00

de qui pourrait donner:

$query_asterisk = "SELECT to_char(cq.queue_time,'YYYY-MM-DD') as date,
COUNT(CASE WHEN cq.status IN ('answered', 'abandoned', 'leaveempty', 'timeout', 'exit_with_key') OR cq.status IS NULL THEN 1 END) AS presente,
COUNT(CASE WHEN cq.answer_time IS NOT NULL THEN 1 END) as repondu,
to_char(AVG(CASE WHEN cq.answer_time IS NOT NULL THEN cq.hangup_time - cq.answer_time END), 'HH24:MI:SS') as duree_moyenne,
COUNT(CASE WHEN cq.status = 'timeout' THEN 1 END) as dissuade,
COUNT(CASE WHEN cq.status = 'abandoned' THEN 1 END) as abandonne,
COUNT(CASE WHEN cq.status = 'closed' THEN 1 END) as hors_horaires,
COUNT(CASE WHEN cq.status = 'abandoned' AND (cd.end_time - cq.queue_time) < '15 seconds'::interval THEN 1 END) as abandonne_t1,
to_char(SUM(CASE WHEN cq.status = 'answered' THEN
EXTRACT(epoch FROM (cq.answer_time - cq.queue_time)) ELSE 0 END) /
NULLIF(COUNT(CASE WHEN cq.status IN ('answered', 'abandoned', 'leaveempty', 'timeout', 'exit_with_key')
OR cq.status IS NULL THEN 1 END),0) * INTERVAL '1 second', 'HH24:MI:SS') as moyenne_temps_attente,
SUM(CASE WHEN cd.transfered THEN 1 ELSE 0 END) AS transfer,
ROUND(COUNT(CASE WHEN cq.answer_time IS NOT NULL THEN 1 END)::numeric /
NULLIF(COUNT(CASE WHEN cq.status IN ('answered', 'abandoned', 'leaveempty', 'timeout', 'exit_with_key')
OR cq.status IS NULL THEN 1 END),0)::numeric * 100,2) as pourcentage_decroche
FROM call_on_queue cq
LEFT JOIN call_data cd ON cq.callid = cd.uniqueid
WHERE to_char(cq.queue_time,'YYYY-MM-DD') between '$debut' AND '$fin'
AND to_char(cq.queue_time,'HH24:MI:SS') between '$heuredebut' AND '$heurefin'
AND queue_ref = '$real_fa_select'
GROUP BY 1";

ensuite, si tu veux que ça soit sur une seule ligne, tu peux grouper tout ça.
y'a surement mieux à faire, mais je garde ma requpete d'avant, mais au lieux de groupe au jour (cf; to_char(cq.queue_time,'YYYY-MM-DD') as date) je peux grouper par année

$query_asterisk = "SELECT to_char(cq.queue_time,'YYYY') as date,
COUNT(CASE WHEN cq.status IN ('answered', 'abandoned', 'leaveempty', 'timeout', 'exit_with_key') OR cq.status IS NULL THEN 1 END) AS presente,
COUNT(CASE WHEN cq.answer_time IS NOT NULL THEN 1 END) as repondu,
to_char(AVG(CASE WHEN cq.answer_time IS NOT NULL THEN cq.hangup_time - cq.answer_time END), 'HH24:MI:SS') as duree_moyenne,
COUNT(CASE WHEN cq.status = 'timeout' THEN 1 END) as dissuade,
COUNT(CASE WHEN cq.status = 'abandoned' THEN 1 END) as abandonne,
COUNT(CASE WHEN cq.status = 'closed' THEN 1 END) as hors_horaires,
COUNT(CASE WHEN cq.status = 'abandoned' AND (cd.end_time - cq.queue_time) < '15 seconds'::interval THEN 1 END) as abandonne_t1,
to_char(SUM(CASE WHEN cq.status = 'answered' THEN
EXTRACT(epoch FROM (cq.answer_time - cq.queue_time)) ELSE 0 END) /
NULLIF(COUNT(CASE WHEN cq.status IN ('answered', 'abandoned', 'leaveempty', 'timeout', 'exit_with_key')
OR cq.status IS NULL THEN 1 END),0) * INTERVAL '1 second', 'HH24:MI:SS') as moyenne_temps_attente,
SUM(CASE WHEN cd.transfered THEN 1 ELSE 0 END) AS transfer,
ROUND(COUNT(CASE WHEN cq.answer_time IS NOT NULL THEN 1 END)::numeric /
NULLIF(COUNT(CASE WHEN cq.status IN ('answered', 'abandoned', 'leaveempty', 'timeout', 'exit_with_key')
OR cq.status IS NULL THEN 1 END),0)::numeric * 100,2) as pourcentage_decroche
FROM call_on_queue cq
LEFT JOIN call_data cd ON cq.callid = cd.uniqueid
WHERE to_char(cq.queue_time,'YYYY-MM-DD') between '$debut' AND '$fin'
AND to_char(cq.queue_time,'HH24:MI:SS') between '$heuredebut' AND '$heurefin'
AND queue_ref = '$real_fa_select'
GROUP BY 1";

ainsi, tous les jours de la même année seront regroupé sur une même ligne.

pour faire à la semaine, (j'utilise datepicker pour récupérer la date sélectionner):
<?php
$query_week = "select extract(WEEK FROM '$semaine'::date) AS semaine";
$result_week = pg_query($query_week);
$get_week = pg_fetch_array($result_week);
$week = $get_week['semaine'];
?>
et avec ça, j'ai la semaine qui correspond au jour sélectionné.

avec tout ça, tu fais ton formulaire, tu choisi le jour de début et de fin, l'heure de début et de fin, la file d'attente ...
tu valide, et au POST, tu lance la reqûete et l'affiche dans un tableau.

tu peux permettre la sélection de plusieurs file d'attente,
foreach (POST as $fileattente)
{ faire la requête et print dans tableau, fermer le tableau)
}

j'ai fait une interface web pour les statistiques ...
je n'ai pas encore prévue de la partager sur du github, car je pense que les requêtes postgresql sont à bannir au profit de l'API.
mais j'ai pas l'impression que l'API du xivocc soit présente.

tu dois avoir des stats aussi côté xivo pabx, car après tout, le xivo-cc utilise un replica de bdd (mais avec des moulinettes supplémentaires pour consolider les stats)
cependant, la table call_on_queue existe surement aussi sur le xivo pabx, et peut-être même que l'API permet de la requêter.

hésites pas à faire un retour ! (et à utiliser un copie de la bdd pour les tests).

++

ex_stat_fa_jour.png (64.4 KB) ex_stat_fa_jour.png stat_jour_fa

RE: Statistiques Call Center - Added by Mathieu ANDRE over 2 years ago

Bonjour,

Merci beaucoup pour la réponse, je vais essayer de décrypter tout ça car je ne maitrise pas du tout ! Au moins j'ai une bonne base maintenant pour mes recherches.

Il ne s'agit pas de XiVO-CC mais du XiVO de base.

Je regarde tout ça et je te fais un retour.

RE: Statistiques Call Center - Added by dudu clx over 2 years ago

re,

ha ben ce que je t'ai donné ne marchera pas !

le xivo CC dispose de base de donnée consolidée.

sur xivo, tu as ces tables:
asterisk=# \dt
List of relations
Schema | Name | Type | Owner

--------+-----------------------------+-------+----------
public | accessfeatures | table | asterisk
public | accesswebservice | table | asterisk
public | agent_login_status | table | asterisk
public | agent_membership_status | table | asterisk
public | agentfeatures | table | asterisk
public | agentglobalparams | table | asterisk
public | agentgroup | table | asterisk
public | agentqueueskill | table | asterisk
public | alembic_version | table | asterisk
public | attachment | table | asterisk
public | call_log | table | asterisk
public | callerid | table | asterisk
public | callfilter | table | asterisk
public | callfiltermember | table | asterisk
public | cel | table | asterisk
public | context | table | asterisk
public | contextinclude | table | asterisk
public | contextmember | table | asterisk
public | contextnumbers | table | asterisk
public | contexttype | table | asterisk
public | cti_preference | table | asterisk
public | cti_profile | table | asterisk
public | cti_profile_preference | table | asterisk
public | cti_profile_service | table | asterisk
public | cti_profile_xlet | table | asterisk
public | cti_service | table | asterisk
public | cti_xlet | table | asterisk
public | cti_xlet_layout | table | asterisk
public | cticontexts | table | asterisk
public | ctidirectories | table | asterisk
public | ctidirectoryfields | table | asterisk
public | ctidisplays | table | asterisk
public | ctimain | table | asterisk
public | ctiphonehints | table | asterisk
public | ctiphonehintsgroup | table | asterisk
public | ctipresences | table | asterisk
public | ctireversedirectories | table | asterisk
public | ctisheetactions | table | asterisk
public | ctisheetevents | table | asterisk
public | ctistatus | table | asterisk
public | dhcp | table | asterisk
public | dialaction | table | asterisk
public | dialpattern | table | asterisk
public | directories | table | asterisk
public | entity | table | asterisk
public | extensions | table | asterisk
public | features | table | asterisk
public | func_key | table | asterisk
public | func_key_dest_agent | table | asterisk
public | func_key_dest_bsfilter | table | asterisk
public | func_key_dest_conference | table | asterisk
public | func_key_dest_custom | table | asterisk
public | func_key_dest_features | table | asterisk
public | func_key_dest_forward | table | asterisk
public | func_key_dest_group | table | asterisk
public | func_key_dest_paging | table | asterisk
public | func_key_dest_park_position | table | asterisk
public | func_key_dest_queue | table | asterisk
public | func_key_dest_service | table | asterisk
public | func_key_dest_user | table | asterisk
public | func_key_destination_type | table | asterisk
public | func_key_mapping | table | asterisk
public | func_key_template | table | asterisk
public | func_key_type | table | asterisk
public | general | table | asterisk
public | groupfeatures | table | asterisk
public | iaxcallnumberlimits | table | asterisk
public | incall | table | asterisk
public | infos | table | asterisk
public | ldapfilter | table | asterisk
public | ldapserver | table | asterisk
public | linefeatures | table | asterisk
public | mail | table | asterisk
public | meetmefeatures | table | asterisk
public | meetmeguest | table | asterisk
public | monitoring | table | asterisk
public | musiconhold | table | asterisk
public | netiface | table | asterisk
public | outcall | table | asterisk
public | outcalltrunk | table | asterisk
public | paging | table | asterisk
public | paginguser | table | asterisk
public | phonebook | table | asterisk
public | phonebookaddress | table | asterisk
public | phonebooknumber | table | asterisk
public | phonefunckey | table | asterisk
public | pickup | table | asterisk
public | pickupmember | table | asterisk
public | provisioning | table | asterisk
public | queue | table | asterisk
public | queue_info | table | asterisk
public | queue_log | table | asterisk
public | queuefeatures | table | asterisk
public | queuemember | table | asterisk
public | queuepenalty | table | asterisk
public | queuepenaltychange | table | asterisk
public | queueskill | table | asterisk
public | queueskillcat | table | asterisk
public | queueskillrule | table | asterisk
public | resolvconf | table | asterisk
public | rightcall | table | asterisk
public | rightcallexten | table | asterisk
public | rightcallmember | table | asterisk
public | sccpdevice | table | asterisk
public | sccpgeneralsettings | table | asterisk
public | sccpline | table | asterisk
public | schedule | table | asterisk
public | schedule_path | table | asterisk
public | schedule_time | table | asterisk
public | session | table | asterisk
public | sipauthentication | table | asterisk
public | stat_agent | table | asterisk
public | stat_agent_periodic | table | asterisk
public | stat_call_on_queue | table | asterisk
public | stat_queue | table | asterisk
public | stat_queue_periodic | table | asterisk
public | stat_switchboard_queue | table | asterisk
public | staticiax | table | asterisk
public | staticmeetme | table | asterisk
public | staticqueue | table | asterisk
public | staticsip | table | asterisk
public | staticvoicemail | table | asterisk
public | stats_conf | table | asterisk
public | stats_conf_agent | table | asterisk
public | stats_conf_queue | table | asterisk
public | stats_conf_xivouser | table | asterisk
public | trunkfeatures | table | asterisk
public | user | table | asterisk
public | user_contact | table | asterisk
public | user_line | table | asterisk
public | usercustom | table | asterisk
public | userfeatures | table | asterisk
public | useriax | table | asterisk
public | usersip | table | asterisk
public | voicemail | table | asterisk
(141 rows)

dans la table stat_queue_periodic, tu as les stats à l'heure des appels sur file d'attente.

Foreign-key constraints:
"stat_queue_periodic_queue_id_fkey" FOREIGN KEY (queue_id) REFERENCES stat_queue(id)

le nom de la file, se trouve donc dans la table stat_queue.

ex:
select * from stat_queue_periodic, stat_queue where stat_queue.id = stat_queue_periodic.queue_id

de là, tu peux trier et ordonner:
select * from stat_queue_periodic, stat_queue
where stat_queue.id = stat_queue_periodic.queue_id
and stat_queue.name = 'hotline'
and to_char(stat_queue_periodic.time, 'YYYY-MM-DD') = '2017-07-18'
order by stat_queue_periodic.time;

tu peux changer la date à extraire, avec un between ... and ... pour l'avoir sur des heures spécifiques de la journée.
cf, exemple plus haut.

donc, dans ton where, tu peux avoir
where to_char(stat_queue_periodic.time, 'YYYY-MM-DD') between 'jour de début' and 'jour de fin'
and to_char(stat_queue_periodic.time, 'HH24:MI:SS') between '08:00:00' and '09:00:00'

ainsi on va extraire que ce qui se passe entre 8h et 9h sur la plage de jours qui va de 'jour de début' à 'jour de fin'.

amuses toi bien !

    (1-3/3)