Updates for VERM in the admin web screens

git-svn-id: svn://192.168.202.10@3689 3d104415-ff17-0410-8863-d5cf3c621b8a
This commit is contained in:
mattf
2023-02-27 16:55:00 +00:00
parent 6499c0adf0
commit 70e9be89a4
40 changed files with 15830 additions and 225 deletions
@@ -5224,7 +5224,7 @@ INSERT INTO vicidial_settings_containers(container_id,container_notes,container_
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('USER_LOCATIONS_SYSTEM','User Locations List','OTHER','---ALL---',';location|description\n|default\n');
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('USER_CODES_SYSTEM','User Codes List','OTHER','---ALL---','');
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('VICIPHONE_SETTINGS','VICIphone WebRTC Extra Settings','WEBPHONE_SETTINGS','---ALL---','# determines if automatic gain control is enabled\nautoGain : 0\n\n# determines if echo cancellation is enabled\nechoCan : 0\n\n# determines if noise suppression is enabled\nnoiseSup :0\n\n# determines if the reg_exten is called upon successful registration\ndialRegExten : 1\n\n# determines the regional sound to use for progress audio\nprogReg : na\n\n# English translation phrases\nlangAttempting:"Attempting"\nlangConnected:"WS Connected"\nlangDisconnected:"WS Disconnected"\nlangExten:"Extension"\nlangIncall:"Incall"\nlangInit:"Initializing..."\nlangRedirect:"Redirect"\nlangRegFailed:"Reg. Failed"\nlangRegistering:"Registering"\nlangRegistered:"Registered"\nlangReject:"Rejected"\nlangRinging:"Ringing"\nlangSend:"Send"\nlangTrying:"Trying"\nlangUnregFailed:"Unreg. Failed"\nlangUnregistered:"Unregistered"\nlangUnregistering:"Unregistering"\nlangWebrtcError:"Something went wrong with WebRTC. Either your browser does not support the necessary WebRTC functions, you did not allow your browser to access the microphone, or there is a configuration issue. Please check your browsers error console for more details. For a list of compatible browsers please vist http://webrtc.org/"');
INSERT INTO `vicidial_settings_containers` VALUES ('VERM_STATUS_NAMES_OVERRIDE','Override dialer status names in enhanced reporting','OTHER','---ALL---','; For each status name you want overridden, type the status followed by\r\n; a pipe, then the new status name\r\n; Ex:\r\n; NZ|Taumatawhakatangihangakoauauotamateaturipukakapikimaungahoronukupoka\r\n201214|Request To Cancel\r\n210200|No Answer-Incomplete Call\r\n210201|Contact Established\r\n210202|Provider Review - HB\r\n210203|Promise to Pay\r\n210204|Setup Payment Plan\r\n210205|Research-Inquiry\r\n210206|Voice Mail Left - HB\r\n210207|Do Not Call\r\n210208|Appeal Verification\r\n210209|Bad Phone\r\n210210|Bad Address\r\n210211|Direct Pay Verification\r\n210213|Provider Approved\r\n210215|Update Notes Only\r\n210216|Voicemail-No Status Change\r\n210217|Sent Letter Request - HB\r\n210218|Auto VoiceMail Left - HB\r\n210219|Auto VoiceMail-No Status Change\r\n210302|Provider Review - LB\r\n210306|Voice Mail Left - LB\r\n210317|Sent Letter Request - LB\r\n210318|Auto VoiceMail Left - LB\r\n211503|Provider - COVID-19\r\n211603|Transferred Call to MLA\r\n'), ('VERM_REPORT_OPTIONS','Container for customizing VERM report output','OTHER','---ALL---','; This is the report queue used if none is chosen by the user\r\n; It\'s preloaded in some forms as well\r\nVERM_default_report_queue => ALL\r\n\r\n; If there are statuses to exclude from reports, list them here\r\n; Separate with commas. Default is AFTHRS\r\nexc_addtl_statuses => AFTHRS\r\n\r\n; Set the below value to 1 (or anything non-blank/non-zero) in order to \r\n; show the agents ID in addition to their full name in the report results\r\nshow_full_agent_info => 1\r\n\r\n; Some reports count \"lost\" calls - which are defined by the below variable\r\n; listing what you define as \"lost\" dispos. Separate with commas.\r\nlost_statuses => LOST,210208,DISPO\r\n\r\n; You can create a detailed IVR survey report for ingroups by defining\r\n; \"ivr_survey_ingroups_detail\" and \"ivr_survey_ingroups_voicemails.\"\r\n; For \"details\", supply an ingroup used as a tracking group on call menus.\r\n; Then, add a pipe and after that list all call menus that use the ingroup\r\n; as the tracking group, separating each with a comma\r\n; To track whether the calls went to voicemail, list every call menu/option\r\n; combination that goes to voicemail, separating the call menu from the \r\n; option with a pipe. One callmenu/option combo per line.\r\nivr_survey_ingroups_detail => 521205|561401,561402,561403,561404,561505\r\nivr_survey_ingroups_voicemails => 561505|t\r\n\r\n; #####################################################\r\n; # ALL of the below are used in the wallboard report #\r\n; #####################################################\r\nVERM_default_outb_widget_queue => ALL_OUT\r\nVERM_default_inb_widget_queue1 => 514915v_USA_Shared\r\nVERM_default_inb_widget_queue2 => 515915v_MLA_Shared\r\n\r\n; Used specifically for the SLA widget\r\n; Uses ingroups - separate multiple ingroups by commas\r\n; Comment out or leave blank to count all ingroups\r\nSLA_LEVEL_PCT_ingroups => 514915v,515915v\r\n\r\n; This removes remote agents from the wallboard reports\r\n; Comment out to include remote agents (or set to zero)\r\nomit_remote_agents => 1\r\n');
INSERT INTO `vicidial_settings_containers` VALUES ('VERM_STATUS_NAMES_OVERRIDE','Override dialer status names in enhanced reporting','OTHER','---ALL---','; For each status name you want overridden, type the status followed by\r\n; a pipe, then the new status name\r\n; Ex:\r\n; NZ|Taumatawhakatangihangakoauauotamateaturipukakapikimaungahoronukupoka\r\n201214|Request To Cancel\r\n210200|No Answer-Incomplete Call\r\n210201|Contact Established\r\n210202|Provider Review - HB\r\n210203|Promise to Pay\r\n210204|Setup Payment Plan\r\n210205|Research-Inquiry\r\n210206|Voice Mail Left - HB\r\n210207|Do Not Call\r\n210208|Appeal Verification\r\n210209|Bad Phone\r\n210210|Bad Address\r\n210211|Direct Pay Verification\r\n210213|Provider Approved\r\n210215|Update Notes Only\r\n210216|Voicemail-No Status Change\r\n210217|Sent Letter Request - HB\r\n210218|Auto VoiceMail Left - HB\r\n210219|Auto VoiceMail-No Status Change\r\n210302|Provider Review - LB\r\n210306|Voice Mail Left - LB\r\n210317|Sent Letter Request - LB\r\n210318|Auto VoiceMail Left - LB\r\n211503|Provider - COVID-19\r\n211603|Transferred Call to MLA\r\n'), ('VERM_REPORT_OPTIONS','Container for customizing VERM report output','OTHER','---ALL---','; This is the report queue used if none is chosen by the user\r\n; It\'s preloaded in some forms as well\r\nVERM_default_report_queue => ALL\r\n\r\n; If there are statuses to exclude from reports, list them here\r\n; Separate with commas. Default is AFTHRS\r\nexc_addtl_statuses => AFTHRS\r\n\r\n; Set the below value to 1 (or anything non-blank/non-zero) in order to \r\n; show the agents ID in addition to their full name in the report results\r\nshow_full_agent_info => 1\r\n\r\n; Some reports count \"lost\" calls - which are defined by the below variable\r\n; listing what you define as \"lost\" dispos. Separate with commas.\r\nlost_statuses => LOST,210208,DISPO\r\n\r\n; You can create a detailed IVR survey report for ingroups by defining\r\n; \"ivr_survey_ingroups_detail\" and \"ivr_survey_ingroups_voicemails.\"\r\n; For \"details\", supply an ingroup used as a tracking group on call menus.\r\n; Then, add a pipe and after that list all call menus that use the ingroup\r\n; as the tracking group, separating each with a comma\r\n; To track whether the calls went to voicemail, list every call menu/option\r\n; combination that goes to voicemail, separating the call menu from the \r\n; option with a pipe. One callmenu/option combo per line.\r\nivr_survey_ingroups_detail => 521205|561401,561402,561403,561404,561505\r\nivr_survey_ingroups_voicemails => 561505|t\r\n\r\n; #####################################################\r\n; # ALL of the below are used in the wallboard report #\r\n; #####################################################\r\nVERM_default_outb_widget_queue => ALL_OUT\r\nVERM_default_inb_widget_queue1 => 514915v_USA_Shared\r\nVERM_default_inb_widget_queue2 => 515915v_MLA_Shared\r\n\r\n; Used specifically for the SLA widget\r\n; Uses ingroups - separate multiple ingroups by commas\r\n; Comment out or leave blank to count all ingroups\r\nSLA_LEVEL_PCT_ingroups => 514915v,515915v\r\n\r\n; This removes remote agents from the wallboard reports\r\n; Comment out to include remote agents (or set to zero)\r\nomit_remote_agents => 1\r\n\r\n\r\n; #### AUTO DOWNLOAD ####\r\n; If the "total calls" value on any report requested exceeds the below \r\n; limit, automatically download the three "DETAILS" reports instead\r\n; of attempting to display that many records on-screen\r\nauto_download_limit => 50000\r\n\r\n; #### OUTCOMES report overrides ####\r\n; Use "outcome_lagged_status_overrides" for conditions where the call \r\n; record in the vicidial_log or vicidial_closer_log table has no uniqueid\r\n; value despite having a status/outcome, which can indicate a call \r\n; affected by network lag for certain statuses. This will change the call \r\n; status to "LAGGED". Separate statuses with commas. Default is the \r\n; automatic "PU" status.\r\noutcome_lagged_status_overrides => PU\r\n\r\n; Use "unknown_network_statuses" to change call statuses to read "Network/\r\n; LAGGED" on the OUTCOMES report. Separate statuses with commas.\r\n; IMPORTANT: if you are using the outcome_lagged_status_overrides option \r\n; above, make sure "LAGGED" is one of the unknown_network_statuses here\r\n; unknown_network_statuses => LAGGED\r\n\r\n; Use "outcome_status_overrides" to change one status to another on the \r\n; OUTCOMES report. Overrides are comma-separated pairs of dispositions \r\n; where the first disposition is the disposition to change, and the second\r\n; is the disposition to change to. Separate pairs with a pipe character as\r\n; in the below example. Off by default.\r\n; outcome_status_overrides => CBHOLD,DISPO|XFER,AL');
INSERT INTO `wallboard_widgets` VALUES ('queues_widget_1','AGENTS_AND_QUEUES','queues','','TEXT',5,'N',1,'Queue Information','','',NULL,'','',NULL,2),('queues_widget_0','AGENTS_AND_QUEUES','queues','','LOGO',2,'N',1,NULL,'','',NULL,'','',NULL,1),('queues_widget_2','AGENTS_AND_QUEUES','queues','SLA Level %','SLA_LEVEL_PCT',1,'N',1,NULL,'','>60',NULL,'','',NULL,3),('queues_widget_3','AGENTS_AND_QUEUES','queues','Outbound calls','LIVE_QUEUE_INFO',1,'N',1,'','201201','','','','','yellow_alarm,|red_alarm,',4),('queues_widget_4','AGENTS_AND_QUEUES','queues','USA Ded Inbound','LIVE_QUEUE_INFO',1,'N',1,'','ALL_IN','','','','','yellow_alarm,|red_alarm,',5),('queues_widget_5','AGENTS_AND_QUEUES','queues','MLA Ded Inbound','LIVE_QUEUE_INFO',1,'N',1,'','514911','','','','','yellow_alarm,|red_alarm,',6),('queues_widget_6','AGENTS_AND_QUEUES','queues','N Waiting Calls','N_WAITING_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,7),('queues_widget_7','AGENTS_AND_QUEUES','queues','Offered Calls','OFFERED_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,8),('queues_widget_8','AGENTS_AND_QUEUES','queues','Answered Calls','ANSWERED_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,9),('queues_widget_9','AGENTS_AND_QUEUES','queues','Lost Calls','LOST_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,10),('queues_widget_10','AGENTS_AND_QUEUES','queues','Longest Wait','LONGEST_WAIT',1,'N',1,NULL,'','',NULL,'','',NULL,11),('queues_widget_11','AGENTS_AND_QUEUES','queues','Live Queues','LIVE_QUEUES',1,'Y',1,NULL,'','',NULL,'','',NULL,12),('queues_widget_12','AGENTS_AND_QUEUES','queues','Live Calls','LIVE_CALLS',1,'Y',2,NULL,'','',NULL,'','',NULL,13),('agent_widget_0','AGENTS_AND_QUEUES','agents','','LOGO',2,'N',1,NULL,'','',NULL,'','',NULL,1),('agent_widget_1','AGENTS_AND_QUEUES','agents','N Waiting Calls','N_WAITING_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,2),('agent_widget_2','AGENTS_AND_QUEUES','agents','Agents Ready','AGENTS_READY',1,'N',1,NULL,'','',NULL,'','',NULL,3),('agent_widget_3','AGENTS_AND_QUEUES','agents','Agents On Call','N_AGENTS_ON_CALL',1,'N',1,NULL,'','',NULL,'','',NULL,4),('agent_widget_4','AGENTS_AND_QUEUES','agents','N Answered Calls','N_ANSWERED_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,5),('agent_widget_5','AGENTS_AND_QUEUES','agents','Clock','CLOCK',1,'N',1,NULL,'','',NULL,'','',NULL,6),('agent_widget_6','AGENTS_AND_QUEUES','agents','Live Agents','LIVE_AGENTS',1,'Y',3,NULL,'','',NULL,'','',NULL,7);
@@ -5232,4 +5232,4 @@ INSERT INTO `wallboard_reports` VALUES ('AGENTS_AND_QUEUES','Agents and Queues',
UPDATE system_settings set vdc_agent_api_active='1';
UPDATE system_settings SET db_schema_version='1676',db_schema_update_date=NOW(),reload_timestamp=NOW();
UPDATE system_settings SET db_schema_version='1677',db_schema_update_date=NOW(),reload_timestamp=NOW();
+4
View File
@@ -2139,3 +2139,7 @@ index (call_date)
) ENGINE=MyISAM;
UPDATE system_settings SET db_schema_version='1676',db_schema_update_date=NOW() where db_schema_version < 1676;
update vicidial_settings_containers set container_entry=CONCAT(container_entry, '\r\n\r\n; #### AUTO DOWNLOAD ####\r\n; If the "total calls" value on any report requested exceeds the below \r\n; limit, automatically download the three "DETAILS" reports instead\r\n; of attempting to display that many records on-screen\r\nauto_download_limit => 50000\r\n\r\n; #### OUTCOMES report overrides ####\r\n; Use "outcome_lagged_status_overrides" for conditions where the call \r\n; record in the vicidial_log or vicidial_closer_log table has no uniqueid\r\n; value despite having a status/outcome, which can indicate a call \r\n; affected by network lag for certain statuses. This will change the call \r\n; status to "LAGGED". Separate statuses with commas. Default is the \r\n; automatic "PU" status.\r\noutcome_lagged_status_overrides => PU\r\n\r\n; Use "unknown_network_statuses" to change call statuses to read "Network/\r\n; LAGGED" on the OUTCOMES report. Separate statuses with commas.\r\n; IMPORTANT: if you are using the outcome_lagged_status_overrides option \r\n; above, make sure "LAGGED" is one of the unknown_network_statuses here\r\n; unknown_network_statuses => LAGGED\r\n\r\n; Use "outcome_status_overrides" to change one status to another on the \r\n; OUTCOMES report. Overrides are comma-separated pairs of dispositions \r\n; where the first disposition is the disposition to change, and the second\r\n; is the disposition to change to. Separate pairs with a pipe character as\r\n; in the below example. Off by default.\r\n; outcome_status_overrides => CBHOLD,DISPO|XFER,AL') WHERE container_id='VERM_REPORT_OPTIONS' and container_entry NOT LIKE "%outcome_status_overrides%";
UPDATE system_settings SET db_schema_version='1677',db_schema_update_date=NOW() where db_schema_version < 1677;
+36 -5
View File
@@ -5,6 +5,7 @@
#
# CHANGELOG:
# 220825-1632 - First build
# 230106-1301 - Added auto-download for large page displays to avoid memory errors
#
# NANQUE, not an unanswered call?
@@ -147,20 +148,43 @@ while ($session_row=mysqli_fetch_array($session_rslt))
$agent_logged_in=1;
}
# 6/3/22 - added $agent_sessions_array["$user"]["$start_date_epoch"]["start_hour"] to skip dual logouts
if (preg_match('/LOGOUT/', $event) && $agent_sessions_array["$user"]["$start_date_epoch"]["start_hour"]) # && $agent_logged_in==1
if (preg_match('/LOGOUT/', $event)) # && $agent_logged_in==1
{
$agent_sessions_array["$user"]["$start_date_epoch"]["end_hour"]=$event_epoch;
$agent_sessions_array["$user"]["$start_date_epoch"]["duration"]=($agent_sessions_array["$user"]["$start_date_epoch"]["end_hour"]-$agent_sessions_array["$user"]["$start_date_epoch"]["start_hour"]);
$agent_sessions_array["$user"]["$start_date_epoch"]["notes"]=$notes;
/* Removed 9/20 - leaving in just in case
$pause_stmt="select sec_to_time(sum(pause_sec)), count(*) from vicidial_agent_log where event_time>=from_unixtime(".$agent_sessions_array["$user"]["$start_date_epoch"]["start_hour"].") and event_time<=from_unixtime(".$agent_sessions_array["$user"]["$start_date_epoch"]["end_hour"].") and user='$user' and pause_sec>0";
# print $pause_stmt."<BR>\n";
$pause_rslt=mysql_to_mysqli($pause_stmt, $link);
$pause_row=mysqli_fetch_row($pause_rslt);
$agent_sessions_array["$user"]["$start_date_epoch"]["pauses"]=$pause_row[1];
$agent_sessions_array["$user"]["$start_date_epoch"]["pause_time"]=($pause_row[0]!="" ? $pause_row[0] : "00:00:00");
*/
if ($agent_sessions_array["$user"]["$start_date_epoch"]["start_hour"]) # 9/8/22 added to prevent warnings
{
$pause_stmt="select sec_to_time(sum(pause_sec)), count(*) from vicidial_agent_log where event_time>=from_unixtime(".$agent_sessions_array["$user"]["$start_date_epoch"]["start_hour"].") and event_time<=from_unixtime(".$agent_sessions_array["$user"]["$start_date_epoch"]["end_hour"].") and user='$user' and pause_sec>0";
# print $pause_stmt."<BR>\n";
$pause_rslt=mysql_to_mysqli($pause_stmt, $link);
if (mysqli_num_rows($pause_rslt)>0) # 9/8/22 added to prevent warnings
{
$pause_row=mysqli_fetch_row($pause_rslt);
$agent_sessions_array["$user"]["$start_date_epoch"]["pauses"]=$pause_row[1];
$agent_sessions_array["$user"]["$start_date_epoch"]["pause_time"]=($pause_row[0]!="" ? $pause_row[0] : "00:00:00");
}
else
{
$agent_sessions_array["$user"]["$start_date_epoch"]["pauses"]=0;
$agent_sessions_array["$user"]["$start_date_epoch"]["pause_time"]="00:00:00";
}
}
else
{
$agent_sessions_array["$user"]["$start_date_epoch"]["pauses"]=0;
$agent_sessions_array["$user"]["$start_date_epoch"]["pause_time"]="00:00:00";
}
$start_date_epoch=0;
$agent_logged_in=0;
}
@@ -234,6 +258,8 @@ $HTML_output.="<th><a class='header_link' name='agent_sessions_sort_server_ip' i
$HTML_output.="</tr>\n";
$CSV_output["agent_sessions"]="\""._QXZ("Agent")."\",\""._QXZ("Start hour")."\",\""._QXZ("End hour")."\",\""._QXZ("Duration")."\",\""._QXZ("Ext.")."\",\""._QXZ("Termination")."\",\""._QXZ("Pause")."\",\""._QXZ("P.Time")."\",\""._QXZ("Srv")."\"\n";
$CSV_output["auto_download"]="\"WARNING:\",\"OVER $auto_download_limit RECORDS\",\"AUTOMATIC DOWNLOAD\"\n\n\n";
$CSV_output["auto_download"]="\""._QXZ("Agent")."\",\""._QXZ("Start hour")."\",\""._QXZ("End hour")."\",\""._QXZ("Duration")."\",\""._QXZ("Ext.")."\",\""._QXZ("Termination")."\",\""._QXZ("Pause")."\",\""._QXZ("P.Time")."\",\""._QXZ("Srv")."\"\n";
## Compress multi-multi-dimensional array into multi-dimensional array
$agent_sessions_final_array=array();
@@ -305,6 +331,7 @@ foreach ($agent_sessions_final_array as $i => $row)
$HTML_output.="</tr>\n";
$CSV_output["agent_sessions"].="\"".$row["full_name"]."\",\"".$row["start_hour"]."\",\"".$row["end_hour"]."\",\"".$row["duration"]."\",\"".$row["extension"]."\",\"".$row["notes"]."\",\"".$row["pauses"]."\",\"".$row["pause_time"]."\",\"".$row["server_ip"]."\"\n";
$CSV_output["auto_download"].="\"".$row["full_name"]."\",\"".$row["start_hour"]."\",\"".$row["end_hour"]."\",\"".$row["duration"]."\",\"".$row["extension"]."\",\"".$row["notes"]."\",\"".$row["pauses"]."\",\"".$row["pause_time"]."\",\"".$row["server_ip"]."\"\n";
}
$HTML_output.="<tr class='export_row'>";
@@ -373,6 +400,7 @@ $HTML_output.="<th><a class='header_link' name='agent_pause_sort_duration' id='a
$HTML_output.="</tr>\n";
$CSV_output["agent_pause_details"]="\""._QXZ("Agent")."\",\""._QXZ("Ext.")."\",\""._QXZ("Code")."\",\""._QXZ("Activity")."\",\"...\",\""._QXZ("Billable?")."\",\""._QXZ("Start hour")."\",\""._QXZ("End hour")."\",\""._QXZ("Duration")."\"\n";
$CSV_output["auto_download"].="\n\n\""._QXZ("Agent")."\",\""._QXZ("Ext.")."\",\""._QXZ("Code")."\",\""._QXZ("Activity")."\",\"...\",\""._QXZ("Billable?")."\",\""._QXZ("Start hour")."\",\""._QXZ("End hour")."\",\""._QXZ("Duration")."\"\n";
$agent_pause_stmt="select campaign_id, user, '' as extension, if (sub_status in ('BLANK', '') or sub_status is null, '-', sub_status) as pause_code, event_time, event_time+INTERVAL pause_sec SECOND as end_hour, sec_to_time(pause_sec) as duration from vicidial_agent_log $vicidial_agent_log_SQL and pause_sec>0";
if ($DB) {$HTML_output.="<B>$agent_pause_stmt</B>";}
@@ -435,9 +463,10 @@ if ($sort_apd_index)
# print_r($agent_pause_array);
}
$q=0;
foreach ($agent_pause_array as $i => $row)
{
$q++;
$myDateTime = DateTime::createFromFormat('Y-m-d H:i:s', $row["start_hour"]);
$start_hour_value = $myDateTime->format('m/d - H:i:s');
@@ -455,8 +484,11 @@ foreach ($agent_pause_array as $i => $row)
$HTML_output.="<td>".$end_hour_value."</td>";
$HTML_output.="<td>".$row["duration"]."</td>";
$HTML_output.="</tr>\n";
if (!$download_rpt && $q%100==0) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$CSV_output["agent_pause_details"].="\"".$row["user"]."\",\"".$row["extension"]."\",\"".$row["pause_code"]."\",\"".$row["pause_code_name"]."\",\"".$row["billable_code"]."\",\"".$row["is_billable"]."\",\"".$start_hour_value."\",\"".$end_hour_value."\",\"".$row["duration"]."\"\n";
$CSV_output["auto_download"].="\"".$row["user"]."\",\"".$row["extension"]."\",\"".$row["pause_code"]."\",\"".$row["pause_code_name"]."\",\"".$row["billable_code"]."\",\"".$row["is_billable"]."\",\"".$start_hour_value."\",\"".$end_hour_value."\",\"".$row["duration"]."\"\n";
}
$HTML_output.="<tr class='export_row'>";
@@ -508,7 +540,6 @@ if ($download_rpt)
}
echo $HTML_output;
?>
</body>
+31 -3
View File
@@ -5,6 +5,7 @@
#
# CHANGELOG:
# 220825-1631 - First build
# 230106-1304 - Added data flushing for large page outputs
#
# NANQUE, not an unanswered call?
@@ -26,6 +27,8 @@ if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];}
# No campaigns, need to query for all.
$vicidial_user_log_SQL=preg_replace('/and campaign_id in \(\'\'\)/', '', $vicidial_user_log_SQL);
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
# Sessions
$vicidial_user_stmt="select distinct user from vicidial_user_log $vicidial_user_log_SQL and event in ('LOGIN', 'LOGOUT', 'TIMEOUTLOGOUT') order by user asc";
if ($DB) {$HTML_output.="<B>$vicidial_user_stmt</B>";}
@@ -368,6 +371,7 @@ foreach ($agent_sessions_array as $user => $sessions)
{
$vcl_uniqueid_stmt="select uniqueid, status, length_in_sec-queue_seconds from vicidial_closer_log $vicidial_closer_log_SQL and call_date+INTERVAL ceil(queue_seconds) SECOND>=from_unixtime(".$agent_sessions_array["$user"]["$start_event_date"]["start_hour"].") and call_date+INTERVAL ceil(queue_seconds) SECOND<=from_unixtime(".$agent_sessions_array["$user"]["$start_event_date"]["end_hour"].") and user='$user' and status!='AFTHRS'";
$vcl_uniqueid_stmt.=" and call_date>=from_unixtime(".$agent_sessions_array["$user"]["$start_event_date"]["start_hour"].")-INTERVAL 24 HOUR and call_date<=from_unixtime(".$agent_sessions_array["$user"]["$start_event_date"]["end_hour"].")+INTERVAL 24 HOUR";
# $DB=1;
if ($DB) {print "\n\n<!--\n $vcl_uniqueid_stmt \n//-->\n\n";}
@@ -643,7 +647,6 @@ foreach ($campaign_sessions_array as $campaign_id => $logins)
# Fill in hour array
foreach ($agent_sessions_hour_array as $user => $hour)
{
for ($i=0; $i<=23; $i++)
{
$agent_sessions_hour_array["$user"][$i]+=0;
@@ -704,6 +707,8 @@ $CSV_output["agent_session_detail"].="\""._QXZ("Average agent time").":\",\"".($
$CSV_output["agent_session_detail"].="\""._QXZ("Min agent time").":\",\"".($min_agent_time>=3600 ? floor($min_agent_time/3600).":" : "").gmdate("i:s", $min_agent_time)."\"\n";
$CSV_output["agent_session_detail"].="\""._QXZ("Max agent time").":\",\"".($max_agent_time>=3600 ? floor($max_agent_time/3600).":" : "").gmdate("i:s", $max_agent_time)."\"\n";
$CSV_output["agent_session_detail"].="\""._QXZ("Total agent time").":\",\"".sprintf("%.1f", ($total_agent_time/3600))." H\"\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
########################################
######### AGENT PAUSE DETAIL ###########
@@ -789,6 +794,8 @@ $HTML_output.="<tr class='export_row'>\n";
$HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('AGENTS', 'agent_pause_detail')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>\n";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
########################################
######### AGENT AVAILABILITY ###########
@@ -853,6 +860,8 @@ $HTML_output.="<tr class='export_row'>\n";
$HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('AGENTS', 'agent_availability')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>\n";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
########################################
######### ANSWERED CALLS ###########
@@ -913,6 +922,8 @@ $HTML_output.="<tr class='export_row'>\n";
$HTML_output.="<td class='export_row_cell' colspan='6'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('AGENTS', 'answered_calls')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>\n";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
########################################
######### ANSWERED CALLS BY USER GROUP ###########
@@ -952,6 +963,8 @@ $HTML_output.="<tr class='export_row'>\n";
$HTML_output.="<td class='export_row_cell' colspan='5'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('AGENTS', 'answered_calls_by_user_group')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>\n";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
####################################
######### ANSWERED CALLS BY LOCATION ###########
@@ -994,6 +1007,8 @@ $HTML_output.="<tr class='export_row'>\n";
$HTML_output.="<td class='export_row_cell' colspan='6'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('AGENTS', 'answered_calls_by_location')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>\n";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
####################################
######### DREADED OCCUPANCY ###########
@@ -1083,6 +1098,8 @@ $HTML_output.="<tr class='export_row'>\n";
$HTML_output.="<td class='export_row_cell' colspan='9'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('AGENTS', 'occupancy')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>\n";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
####################################
##### AGENT SESSION TIME BY HOUR ###
@@ -1129,6 +1146,8 @@ $HTML_output.="<tr class='export_row'>\n";
$HTML_output.="<td class='export_row_cell' colspan='26'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('AGENTS', 'agent_sessions_by_hour')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>\n";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
####################################
# No payable, not used
@@ -1177,6 +1196,8 @@ $HTML_output.="<tr class='export_row'>\n";
$HTML_output.="<td class='export_row_cell' colspan='26'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('AGENTS', 'agent_billable_by_hour')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>\n";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
####################################
#### AGENTS BY HOUR ###
@@ -1230,6 +1251,8 @@ $HTML_output.="<tr class='export_row'>\n";
$HTML_output.="<td class='export_row_cell' colspan='26'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('AGENTS', 'agents_by_hour')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>\n";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
####################################
######## AGENT SESSIONS VIEW #######
@@ -1368,9 +1391,9 @@ foreach ($agent_sessions_array as $user => $sessions)
$HTML_output.="<td class='small_text'>0</td>";
$HTML_output.="<td class='small_text'>0</td>";
$HTML_output.="<td class='small_text'>$avg_talk_His</td>";
$HTML_output.="<td><a onClick=\"ShowOutcomesDetails('', '$start_date $start_time', '$end_date $end_time', '$user')\"><svg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
$HTML_output.="<td><a onClick=\"ShowOutcomesDetails('', '$start_date $start_time', '$end_date $end_time', '$user')\"><svg width='20' height='20' viewBox='0 0 20 20' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
### Removed 6/14, may re-instate if "taken/lost" becomes necessary/desired
### $HTML_output.="<td><a onClick=\"ShowOutcomesDetails('THERE IS NO SUCH THING', '$start_date $start_time', '$end_date $end_time')\"><svg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
### $HTML_output.="<td><a onClick=\"ShowOutcomesDetails('THERE IS NO SUCH THING', '$start_date $start_time', '$end_date $end_time')\"><svg width='20' height='20' viewBox='0 0 20 20' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
$HTML_output.="</tr>\n";
$CSV_output["agent_sessions_view"].="\"".$agentName."\",\"$total_duration_His\",\"$total_talk_His\",\"$total_idle_His\",\"$total_pause_His\",\"$total_billable_His\",\"$total_nonbillable_His\",\"$total_wait_His\",\"$total_sales\",\"$sph\",\"$total_contacts\",\"$ccph\",\"$total_human_answered\",\"$haph\",\"$total_calls\",\"$ha_conv\",\"$cc_conv\",\"0\",\"0\",\"$avg_talk_His\"\n";
@@ -1379,6 +1402,8 @@ $HTML_output.="<tr class='export_row'>\n";
$HTML_output.="<td class='export_row_cell' colspan='21'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('AGENTS', 'agent_sessions_view')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>\n";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
####################################
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Campaign/Ingroup Sessions View")." $NWB#VERM_AGENTS-queue_sessions_view$NWE</h2>"; # Inbound
@@ -1517,6 +1542,7 @@ $HTML_output.="<td class='export_row_cell' colspan='18'>"._QXZ("Export as")."...
$HTML_output.="</tr>\n";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
####################################
/* Removed 5/19
@@ -1543,6 +1569,8 @@ $HTML_output.="</tr>\n";
$HTML_output.="</table>";
*/
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
if ($download_rpt)
{
@@ -5,6 +5,7 @@
#
# CHANGELOG:
# 220825-1630 - First build
# 230106-1307 - Auto download for large data output
#
if (isset($_GET["page_no"])) {$page_no=$_GET["page_no"];}
@@ -114,6 +115,12 @@ $HTML_output.="</td>";
$HTML_output.="</tr>";
$HTML_output.="<tr>";
$CSV_output="";
if ($total_calls>$auto_download_limit)
{
$CSV_output.="\""._QXZ("WARNING").":\",\""._QXZ("OVER")." $auto_download_limit "._QXZ("RECORDS")."\",\""._QXZ("AUTOMATIC DOWNLOAD")."\"\n\n\n";
}
foreach ($selected_columns as $display_name => $column_name)
{
if ($display_name!="uniqueid")
@@ -208,7 +215,7 @@ foreach ($output_array as $data_row)
}
else
{
$HTML_output.="<td><a onClick=\"ShowCallDetails('$value', 'ANSWERED_DT')\"><svg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
$HTML_output.="<td><a onClick=\"ShowCallDetails('$value', 'ANSWERED_DT')\"><svg width='20' height='20' viewBox='0 0 20 20' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
# $HTML_output.="<td><IMG SRC=\"images/glass.png\" onClick=\"ShowCallDetails('$value')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP></td>";
}
}
@@ -337,4 +344,4 @@ function GetDID($uniqueid)
return $did_str;
}
?>
?>
+46 -3
View File
@@ -5,6 +5,7 @@
#
# CHANGELOG:
# 220825-1629 - First build
# 230106-1310 - Added auto download and page flushing for large data output, modification to uniqueid handling to speed up page load
#
# DROP, WAITTO, TIMEOT are unanswered statuses, not NANQUE
@@ -119,7 +120,8 @@ while ($calls_row=mysqli_fetch_array($calls_rslt))
}
else
{
array_push($uniqueid_array, $calls_row["uniqueid"]);
# array_push($uniqueid_array, $calls_row["uniqueid"]);
$uniqueid_array["$calls_row[uniqueid]"]="Y";
$total_answered_calls++;
if ($calls_row["direction"]=="O")
{
@@ -135,6 +137,7 @@ while ($calls_row=mysqli_fetch_array($calls_rslt))
# Use full name here so we can sort in the 'Agents on queue' section painlessly.
$agent_full_name=$fullname_info["$calls_row[user]"];
if (!$agent_full_name) {$agent_full_name=$calls_row["user"];}
$agent_full_name=($show_full_agent_info ? $calls_row["user"]." - " : "").$fullname_info["$calls_row[user]"];
$agent_call_counts["$agent_full_name"]++;
$agent_call_lengths["$agent_full_name"]+=$calls_row["length_in_sec"];
@@ -280,6 +283,8 @@ $HTML_output.="<td class='export_row_cell' colspan='2'>"._QXZ("Export as")."...<
$HTML_output.="</tr>\n";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$CSV_output["all_calls"]="\""._QXZ("All calls")."\",\"\"\n";
$CSV_output["all_calls"].="\""._QXZ("N. calls answered by operators").":\",\"$total_answered_calls\"\n";
$CSV_output["all_calls"].="\""._QXZ("Average call length").":\",\"$average_call_length s.\"\n";
@@ -367,6 +372,8 @@ $HTML_output.="<td colspan='2' class='export_row_cell'>"._QXZ("Export as")."...<
$HTML_output.="</tr>\n";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$CSV_output["all_calls_wi"]="\""._QXZ("All calls fully within the given time interval")."\",\"\"\n";
$CSV_output["all_calls_wi"].="\""._QXZ("N. calls answered by operators").":\",\"$total_answered_calls_wi\"\n";
$CSV_output["all_calls_wi"].="\""._QXZ("Average call length").":\",\"$average_call_length_wi s.\"\n";
@@ -505,6 +512,9 @@ $HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:80vh; width:80vh\"><canvas id='agents_on_queue_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
$HTML_output.="<input type='hidden' name='sort_agents_on_queue' id='sort_agents_on_queue' value='sort_agents_on_queue'>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
######################
#### SERVICE LEVEL ####
@@ -588,6 +598,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:80vh; width:80vh\"><canvas id='service_level_agreement_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
######################
#### DISCONNECTIONS ###
@@ -645,6 +658,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:50vh; width:50vh\"><canvas id='disconnection_causes_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
######################
#### TRANSFERS ###
@@ -694,6 +710,9 @@ $HTML_output.="<tr class='export_row'>";
$HTML_output.="<td colspan='4' class='export_row_cell'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('ANSWERED', 'transfers')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>\n";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
######################
#### ANSWERED CALLS BY CAMPAIGN/INGROUP ###
@@ -753,6 +772,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:40vh; width:60vh\"><canvas id='answered_calls_by_queue_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#####################
#### ANSWERED CALLS BY DIRECTION ###
@@ -814,6 +836,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:40vh; width:40vh\"><canvas id='answered_calls_by_direction_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#####################
/*
@@ -909,11 +934,15 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div style=\"height:20px; width:300px\"><canvas id='queue_position_display' style=\"height:200px; width:300px\" role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#####################
##### IVR STATS #####
$ivr_stmt="select uniqueid,extension,start_time,comment_a,comment_b,comment_d,UNIX_TIMESTAMP(start_time),phone_ext from live_inbound_log $live_inbound_log_SQL and comment_a IN('CALLMENU') order by uniqueid,start_time";
if ($DB) {$HTML_output.="<B>$ivr_stmt</B>";}
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$ivr_rslt=mysql_to_mysqli($ivr_stmt, $link);
$ivr_paths=array(); # 0 - total calls, 1 - total time, 2 - min time, 3 - max time
$ivr_counts=array();
@@ -922,7 +951,8 @@ while ($ivr_row=mysqli_fetch_array($ivr_rslt))
{
$uniqueid=$ivr_row[0];
if (in_array($uniqueid, $uniqueid_array))
# if (in_array($uniqueid, $uniqueid_array))
if (isset($uniqueid_array["$uniqueid"]))
{
if (!$prev_id)
{
@@ -1025,6 +1055,8 @@ $CSV_output["ivr_selection"]="\""._QXZ("IVR selection").":\"\n";
$CSV_output["ivr_selection"].="\""._QXZ("IVR")."\",\""._QXZ("N. Calls")."\",\"\",\"\",\""._QXZ("Total Duration")."\",\""._QXZ("Average Duration")."\",\""._QXZ("Min Duration")."\",\""._QXZ("Max Duration")."\"\n";
$CSV_output["ivr_selection"].="\""._QXZ("Untracked")."\",\"$untracked_calls\",\"".$untracked_ivr_pct." %\",\"\",\"\",\"\",\"\",\"\"\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
ksort($ivr_paths);
$x=1;
foreach ($ivr_paths as $pathname => $value)
@@ -1069,6 +1101,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:60vh; width:30vw\"><canvas id='ivr_selection_display' style=\"height:60vh; width:30vw\" role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#####################
###### Inbound DID used #####
@@ -1080,7 +1115,8 @@ $did_counts=array(); # 0 - total calls, 1 - total time, 2 - min time, 3 - max ti
$untracked_did_calls=$total_answered_calls;
while ($did_row=mysqli_fetch_array($did_rslt))
{
if(in_array($did_row["uniqueid"], $uniqueid_array))
# if(in_array($did_row["uniqueid"], $uniqueid_array))
if (isset($uniqueid_array["$did_row[uniqueid]"]))
{
$did_counts["$did_row[extension]"]++;
$untracked_did_calls--;
@@ -1137,6 +1173,8 @@ foreach ($did_counts as $did => $value)
$did_used_graph_bgcolor.="\"".$background_colors[$x]."\",";
$did_used_graph_hovborder.="\"".$border_colors[$x]."\",";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$x++;
}
$did_used_graph_labels=preg_replace('/,$/', '', $did_used_graph_labels)."]";
@@ -1152,6 +1190,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:40vh; width:40vw\"><canvas id='did_used_display' style=\"height:40vh; width:40vw\" role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
######################
#### MUSIC ON HOLD ####
@@ -1204,6 +1245,8 @@ $HTML_output.="<tr class='export_row'>";
$HTML_output.="<td class='export_row_cell' colspan='5'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('ANSWERED', 'moh_agent')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>\n";
$HTML_output.="</table>\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#####################
if ($download_rpt)
+5
View File
@@ -5,6 +5,7 @@
#
# CHANGELOG:
# 220825-1627 - First build
# 230106-1729 - Added page flushing so page elements appear as they load
#
# if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];}
@@ -192,6 +193,8 @@ $HTML_output.="<tr class='export_row'>";
$HTML_output.="<td class='export_row_cell' colspan='5'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('AREA', 'answered_area')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#############################
##### UNANSWERED OUTPUT #####
@@ -231,6 +234,8 @@ $HTML_output.="<tr class='export_row'>";
$HTML_output.="<td class='export_row_cell' colspan='4'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('AREA', 'unanswered_area')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#############################
if ($download_rpt)
+5
View File
@@ -5,6 +5,7 @@
#
# CHANGELOG:
# 220825-1626 - First build
# 230106-1311 - Added page flushing to show page load progress
#
# if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];}
@@ -134,6 +135,8 @@ $HTML_output.="<tr class='export_row'>";
$HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('ATT', 'acd_attempts_by_queue')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>";
$HTML_output.="</table><BR>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
####################################
@@ -196,6 +199,8 @@ $HTML_output.="<tr class='export_row'>";
$HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('ATT', 'acd_attempts_by_terminal')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>";
$HTML_output.="</table><BR>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#############################
if ($download_rpt)
+3 -3
View File
@@ -228,7 +228,7 @@ foreach ($output_array as $data_row)
}
else
{
$HTML_output.="<td><a onClick=\"ShowCallDetails('$value', 'CALLS')\"><svg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
$HTML_output.="<td><a onClick=\"ShowCallDetails('$value', 'CALLS')\"><svg width='20' height='20' viewBox='0 0 20 20' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
# $HTML_output.="<td><IMG SRC=\"images/glass.png\" onClick=\"ShowCallDetails('$value')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP></td>";
}
}
@@ -414,7 +414,7 @@ foreach ($output_array as $data_row)
}
else
{
$HTML_output.="<td><a onClick=\"ShowCallDetails('$value', 'answered')\"><svg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
$HTML_output.="<td><a onClick=\"ShowCallDetails('$value', 'answered')\"><svg width='20' height='20' viewBox='0 0 20 20' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
# $HTML_output.="<td><IMG SRC=\"images/glass.png\" onClick=\"ShowCallDetails('$value')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP></td>";
}
}
@@ -554,4 +554,4 @@ function GetDID($uniqueid)
return $did_str;
}
?>
?>
+21
View File
@@ -5,6 +5,7 @@
#
# CHANGELOG:
# 220825-1624 - First build
# 230106-1311 - Added page flushing to show page load progress
#
$vicidial_user_log_table="vicidial_user_log";
@@ -307,6 +308,8 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
# $HTML_output.="<div class=\"chart-container\" style=\"height:80vh; width:80vh\"><canvas id='agents_on_queue_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### ANSWERED CALL WAIT TIME PER DAY ###
@@ -368,6 +371,8 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
# $HTML_output.="<div class=\"chart-container\" style=\"height:80vh; width:80vh\"><canvas id='agents_on_queue_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### UNANSWERED CALL WAIT TIME PER DAY ###
@@ -432,6 +437,8 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
# $HTML_output.="<div class=\"chart-container\" style=\"height:80vh; width:80vh\"><canvas id='agents_on_queue_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### SALES PER DAY ###
@@ -479,6 +486,8 @@ $HTML_output.="<tr class='export_row'>";
$HTML_output.="<td class='export_row_cell' colspan='10'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('DAY', 'sales_per_day')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### QUEUE LENGTH PER DAY ###
@@ -523,6 +532,8 @@ $HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<
$HTML_output.="</tr>";
$HTML_output.="</table>";
### $HTML_output.="** - coverage = percent of calls with queue position. Assumed 100% if including outbound with a default position of '1' - also true for avg position<BR><BR>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### SCHEDULE ADHERENCE PER DAY ###
@@ -547,6 +558,8 @@ foreach ($user_array as $call_date_key => $users_that_day)
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".sprintf("%.1f", (100*count($users_that_day)/$total_distinct_users_per_date))."%'></td>";
$HTML_output.="</tr>\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$CSV_output["schedule_adherence_per_day"].="\"$call_date_key\",\"".count($users_that_day)."\",\"".sprintf("%.1f", (100*count($users_that_day)/$total_distinct_users_per_date))." %\",\"\"\n";
# print "agents for $call_date_key: ".count($users_that_day)."\n";
@@ -581,6 +594,9 @@ $HTML_output.="<td class='export_row_cell' colspan='4'>"._QXZ("Export as")."...<
$HTML_output.="</tr>";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### SERVICE LEVEL PER DAY ####
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Inclusive SLA per day (inbound and outbound)").": $NWB#VERM_DAY-inclusive_SLA$NWE</h2>";
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
@@ -629,6 +645,8 @@ foreach ($calls_array as $call_date_key => $data)
}
$HTML_output.="</tr>\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$CSV_output["inclusive_sla_per_day"].="\n";
$prev_int=$interval;
@@ -639,6 +657,9 @@ $HTML_output.="<td class='export_row_cell' colspan='".(4+count($svc_lvl_row))."'
$HTML_output.="</tr>";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
if ($download_rpt)
{
$data_to_download=$CSV_output["$download_rpt"];
+20
View File
@@ -373,6 +373,8 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:80vh; width:80vh\"><canvas id='answered_call_distribution_graph' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### ANSWERED CALL WAIT TIME PER DAY OF WEEK ###
@@ -458,6 +460,8 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:80vh; width:80vh\"><canvas id='answered_call_wait_time_graph' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### UNANSWERED CALL WAIT TIME PER DAY OF WEEK ###
@@ -545,6 +549,8 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:80vh; width:80vh\"><canvas id='unanswered_call_wait_time_graph' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### SALES PER DAY OF WEEK ###
@@ -592,6 +598,8 @@ $HTML_output.="<tr class='export_row'>";
$HTML_output.="<td class='export_row_cell' colspan='10'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('DOW', 'sales_per_day')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### QUEUE LENGTH PER DAY OF WEEK ###
@@ -636,6 +644,8 @@ $HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<
$HTML_output.="</tr>";
$HTML_output.="</table>";
### $HTML_output.="** - coverage = percent of calls with queue position. Assumed 100% if including outbound with a default position of '1' - also true for avg position<BR><BR>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### SCHEDULE ADHERENCE PER DAY OF WEEK ###
@@ -660,6 +670,8 @@ foreach ($user_array as $call_date_key => $users_that_day)
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".sprintf("%.1f", (100*count($users_that_day)/$total_distinct_users_per_date))."%'></td>";
$HTML_output.="</tr>\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$CSV_output["schedule_adherence_per_day"].="\"$call_date_key\",\"".count($users_that_day)."\",\"".sprintf("%.1f", (100*count($users_that_day)/$total_distinct_users_per_date))." %\",\"\"\n";
# print "agents for $call_date_key: ".count($users_that_day)."\n";
@@ -694,6 +706,9 @@ $HTML_output.="<td class='export_row_cell' colspan='4'>"._QXZ("Export as")."...<
$HTML_output.="</tr>";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### SERVICE LEVEL PER DAY OF WEEK ####
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Inclusive SLA per day of week (inbound and outbound)").": $NWB#VERM_DOW-inclusive_SLA$NWE</h2>";
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
@@ -742,6 +757,8 @@ foreach ($calls_array as $call_date_key => $data)
}
$HTML_output.="</tr>\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$CSV_output["inclusive_sla_per_day"].="\n";
$prev_int=$interval;
@@ -752,6 +769,9 @@ $HTML_output.="<td class='export_row_cell' colspan='".(4+count($svc_lvl_row))."'
$HTML_output.="</tr>";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
/*
# Traffic analysis per day
$HTML_output.="<BR><h2 class='rpt_header'>Traffic Analysis by period - per day:</h2>";
+21
View File
@@ -5,6 +5,7 @@
#
# CHANGELOG:
# 220825-1620 - First build
# 230106-1311 - Added page flushing to show page load progress
#
# NANQUE, not an unanswered call?
@@ -388,6 +389,8 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:80vh; width:80vh\"><canvas id='answered_call_distribution_graph' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### ANSWERED CALL WAIT TIME PER HOUR ###
@@ -473,6 +476,8 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:80vh; width:80vh\"><canvas id='answered_call_wait_time_graph' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### UNANSWERED CALL WAIT TIME PER HOUR ###
@@ -560,6 +565,8 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:80vh; width:80vh\"><canvas id='unanswered_call_wait_time_graph' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### SALES PER HOUR ###
@@ -607,6 +614,8 @@ $HTML_output.="<tr class='export_row'>";
$HTML_output.="<td class='export_row_cell' colspan='10'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('HOUR', 'sales_per_day')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### QUEUE LENGTH PER HOUR ###
@@ -651,6 +660,8 @@ $HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<
$HTML_output.="</tr>";
$HTML_output.="</table>";
### $HTML_output.="** - coverage = percent of calls with queue position. Assumed 100% if including outbound with a default position of '1' - also true for avg position<BR><BR>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### SCHEDULE ADHERENCE PER HOUR ###
@@ -675,6 +686,8 @@ foreach ($user_array as $call_date_key => $users_that_day)
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".sprintf("%.1f", (100*count($users_that_day)/$total_distinct_users_per_date))."%'></td>";
$HTML_output.="</tr>\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$CSV_output["schedule_adherence_per_day"].="\"$call_date_key\",\"".count($users_that_day)."\",\"".sprintf("%.1f", (100*count($users_that_day)/$total_distinct_users_per_date))." %\",\"\"\n";
# print "agents for $call_date_key: ".count($users_that_day)."\n";
@@ -709,6 +722,9 @@ $HTML_output.="<td class='export_row_cell' colspan='4'>"._QXZ("Export as")."...<
$HTML_output.="</tr>";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
#### SERVICE LEVEL PER HOUR ####
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Inclusive SLA per hour (inbound and outbound)").": $NWB#VERM_HOUR-inclusive_SLA$NWE</h2>";
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
@@ -757,6 +773,8 @@ foreach ($calls_array as $call_date_key => $data)
}
$HTML_output.="</tr>\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$CSV_output["inclusive_sla_per_day"].="\n";
$prev_int=$interval;
@@ -767,6 +785,9 @@ $HTML_output.="<td class='export_row_cell' colspan='".(4+count($svc_lvl_row))."'
$HTML_output.="</tr>";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###########################################
/*
# Traffic analysis per day
$HTML_output.="<BR><h2 class='rpt_header'>Traffic Analysis by period - per day:</h2>";
+60 -39
View File
@@ -5,6 +5,7 @@
#
# CHANGELOG:
# 220825-1619 - First build
# 230106-1328 - Added page flushing to show page load progress
#
if (isset($_GET["page_no"])) {$page_no=$_GET["page_no"];}
@@ -183,6 +184,8 @@ $HTML_output.="<th>"._QXZ("Hangups")."</th>";
$HTML_output.="<th>"._QXZ("Attrition rate")."</th>";
$HTML_output.="</tr>\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$CSV_output["ivr_traversal"]="\""._QXZ("IVR path")."\",\""._QXZ("N. Calls")."\",\""._QXZ("IVR goal report")."\",\""._QXZ("Success rate")."\",\""._QXZ("Hangups")."\",\""._QXZ("Attrition rate")."\"\n";
$prev_ivr_key="";
@@ -264,6 +267,8 @@ foreach ($ivr_data as $ivr_path => $data)
$HTML_output.="<td>".sprintf("%.1f", (100*$data["hangups"]/$data["calls"]))." %</td>";
$HTML_output.="</tr>\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$CSV_output["ivr_traversal"].="\"".$CSV_ivr_value."\",\"".$data["calls"]."\",\"".($data["calls"]-$data["hangups"])."\",\"".sprintf("%.1f", (100*($data["calls"]-$data["hangups"])/$data["calls"]))." %\",\"".$data["hangups"]."\",\"".sprintf("%.1f", (100*$data["hangups"]/$data["calls"]))." %\"\n";
if(preg_match('/\-TOTAL$/', $ivr_path)) {unset($ivr_data["$ivr_path"]);} # Remove total, don't need anymore
@@ -275,6 +280,8 @@ $HTML_output.="<td class='export_row_cell' colspan='6'>"._QXZ("Export as")."...<
$HTML_output.="</tr>";
$HTML_output.="</table>\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
# print $HTML_output; die;
# print_r($ivr_data); die;
@@ -292,6 +299,8 @@ $HTML_output.="<th>"._QXZ("Minimum time")."</th>";
$HTML_output.="<th>"._QXZ("Maximum time")."</th>";
$HTML_output.="</tr>\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$CSV_output["ivr_timing"]="\""._QXZ("IVR path")."\",\""._QXZ("N. Calls")."\",\""._QXZ("Average time")."\",\""._QXZ("Total time")."\",\""._QXZ("Minimum time")."\",\""._QXZ("Maximum time")."\"\n";
foreach ($ivr_data as $comment_d => $data)
@@ -333,6 +342,8 @@ foreach ($ivr_data as $comment_d => $data)
$HTML_output.=$HTML_subheader.$HTML_datarows;
$HTML_datarows="";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$CSV_header="\"$base_path_output\",\"$total_prompt_calls\",\"$base_average_time\",\"$base_total_time\",\"$base_minimum_time\",\"$base_maximum_time\"\n";
$CSV_output["ivr_timing"].=$CSV_header.$CSV_row_output;
$CSV_row_output="";
@@ -391,6 +402,8 @@ $HTML_output.="<td class='export_row_cell' colspan='6'>"._QXZ("Export as")."...<
$HTML_output.="</tr>";
$HTML_output.="</table>\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$CSV_header="\"$prev_base_path - $callmenu_names[$prev_base_path]\",\"$total_prompt_calls\",\"$base_average_time\",\"$base_total_time\",\"$base_minimum_time\",\"$base_maximum_time\"\n";
$CSV_output["ivr_timing"].=$CSV_header.$CSV_row_output;
@@ -442,7 +455,7 @@ foreach ($path_data as $goal => $path)
$maximum_time=($data["maximum_time"]>=3600 ? intval(floor($data["maximum_time"]/3600)).date(":i:s", $data["maximum_time"]) : intval(date("i", $data["maximum_time"])).":".date("s", $data["maximum_time"]));
$HTML_output.="<tr class='standard_font_small'>";
$HTML_output.="<td>Campaign/ingroup: ".$ingroup_names["$goal"]."</td>";
$HTML_output.="<td>"._QXZ("Campaign/ingroup").": ".$ingroup_names["$goal"]."</td>";
# $HTML_output.="<td>".$key_array[0]." - ".$callmenu_names["$key_array[0]"]."</td>";
$HTML_output.="<td>".$final_key_path."</td>";
$HTML_output.="<td>".$key_array[1]."</td>";
@@ -452,7 +465,9 @@ foreach ($path_data as $goal => $path)
$HTML_output.="<td>".$maximum_time."</td>";
$HTML_output.="</tr>\n";
$CSV_output["ivr_goal"].="\"Campaign/ingroup: ".$ingroup_names["$goal"]."\",";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
$CSV_output["ivr_goal"].="\""._QXZ("Campaign/ingroup").": ".$ingroup_names["$goal"]."\",";
# $CSV_output["ivr_goal"].="\"".$key_array[0]." - ".$callmenu_names["$key_array[0]"]."\",";
$CSV_output["ivr_goal"].="\"".$CSV_final_key_path."\",";
$CSV_output["ivr_goal"].="\"".$key_array[1]."\",";
@@ -471,6 +486,8 @@ $HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<
$HTML_output.="</tr>";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#############################
$HTML_output.="<BR><h2 class='rpt_header' id='sid_anchor'>"._QXZ("IVR Details").": $NWB#VERM_IVR-ivr_details$NWE</h2>";
@@ -507,6 +524,8 @@ foreach ($ivr_details_columns as $display_name => $column_name)
# $HTML_output.="<th><a class='header_link' name='call_detail_sort_".$column_name."' id='call_detail_sort_".$column_name."' href='".$PHP_SELF."?sort_ivr_details=".($column_name==$sort_ivr_details_preg ? "$reverse_link" : "$column_name")."&page_no=".$page_no."#call_detail_sort_".$column_name."'>".$display_name.($column_name==$sort_ivr_details_preg ? " $sort_char" : "")."</a></th>";
$HTML_output.="<th><input type='button' class='sort_button' value='".$display_name.($column_name==$sort_ivr_details_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_ivr_details').value='".($column_name==$sort_ivr_details_preg ? "$reverse_link" : "$column_name")."'; this.form.action+='#sid_anchor'; this.form.submit()\"></th>\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
}
}
$CSV_output["ivr_details"].="\n";
@@ -534,49 +553,51 @@ foreach ($ivr_details as $uniqueid => $data_row)
if (preg_match("/$ivr_choice/i", $data_row["ivr_path"])) # from search results
{
$HTML_output.="<tr class='standard_font_small'>";
foreach ($data_row as $key => $value)
{
if ($key=="closecallid")
$HTML_output.="<tr class='standard_font_small'>";
foreach ($data_row as $key => $value)
{
$detail_id.="|$value";
}
else
{
if ($key=="date")
if ($key=="closecallid")
{
$myDateTime = DateTime::createFromFormat('Y-m-d H:i:s', $value);
$value = $myDateTime->format('m/d - H:i:s');
$detail_id.="|$value";
}
if ($key=="goal")
else
{
$value=$ingroup_names["$value"];
}
if ($key=="ivr_path")
{
$final_key_path="";
$ivr_path_array=explode(">", $value);
$ivr_array=explode(",", $ivr_path_array[0]);
for($i=0; $i<count($ivr_array); $i++)
if ($key=="date")
{
# if ($callmenu_names["$ivr_array[$i]"]) {$ivr_base=preg_replace("/$ivr_array[$i]/", $callmenu_names["$ivr_array[$i]"], $ivr_base);}
$final_key_path.=$ivr_array[$i].($callmenu_names["$ivr_array[$i]"] ? " - ".$callmenu_names["$ivr_array[$i]"] : "")." => ";
$myDateTime = DateTime::createFromFormat('Y-m-d H:i:s', $value);
$value = $myDateTime->format('m/d - H:i:s');
}
if ($key=="goal")
{
$value=$ingroup_names["$value"];
}
if ($key=="ivr_path")
{
$final_key_path="";
$ivr_path_array=explode(">", $value);
$ivr_array=explode(",", $ivr_path_array[0]);
for($i=0; $i<count($ivr_array); $i++)
{
# if ($callmenu_names["$ivr_array[$i]"]) {$ivr_base=preg_replace("/$ivr_array[$i]/", $callmenu_names["$ivr_array[$i]"], $ivr_base);}
$final_key_path.=$ivr_array[$i].($callmenu_names["$ivr_array[$i]"] ? " - ".$callmenu_names["$ivr_array[$i]"] : "")." => ";
}
$final_key_path=preg_replace('/ \=\> $/', "", $final_key_path)." > ".$ivr_path_array[1];
$value=$final_key_path;
}
$final_key_path=preg_replace('/ \=\> $/', "", $final_key_path)." > ".$ivr_path_array[1];
$value=$final_key_path;
}
$HTML_output.="<td>".$value."</td>";
$CSV_output["ivr_details"].="\"".$value."\",";
$HTML_output.="<td>".$value."</td>";
$CSV_output["ivr_details"].="\"".$value."\",";
}
}
}
$HTML_output.="<td><a onClick=\"ShowCallDetails('$detail_id', 'ivr')\"><svg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
$CSV_output["ivr_details"].="\n";
$HTML_output.="<td><a onClick=\"ShowCallDetails('$detail_id', 'ivr')\"><svg width='20' height='20' viewBox='0 0 20 20' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
$CSV_output["ivr_details"].="\n";
$HTML_output.="</tr>";
$HTML_output.="</tr>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
}
}
$HTML_output.="<tr class='export_row'>";
@@ -598,14 +619,14 @@ $HTML_output.="</table>";
$HTML_output.="<input type=hidden name=page_no id=page_no value='$page_no'>";
$HTML_output.="<input type='hidden' name='sort_ivr_details' id='sort_ivr_details' value='$sort_ivr_details'>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
if ($ivr_survey_ingroups_detail && count($ivr_survey_ingroups_detail)>0)
{
require("VERM_IVR_survey_details.inc");
}
else
{
# $HTML_output.="<H2>NOPE</H2>";
}
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
if ($download_rpt)
{
@@ -5,14 +5,16 @@
#
# CHANGELOG:
# 220825-1618 - First build
# 230106-1329 - Added CSV output, page flushing, and recording access logging
#
# $DB=1;
$CSV_output["ivr_survey_details"]="";
foreach ($ivr_survey_ingroups_detail as $comment_a => $callmenu_list)
{
$ingrp_stmt="select group_name from vicidial_inbound_groups where group_id='$comment_a' UNION select menu_name from vicidial_call_menu where menu_id='$comment_a'";
echo "<!-- $ingrp_stmt //-->\n";
# echo "<!-- $ingrp_stmt //-->\n";
if ($DB){$HTML_output.="$ingrp_stmt<BR>";}
$ingrp_rslt=mysql_to_mysqli($ingrp_stmt, $link);
while($ingrp_row=mysqli_fetch_row($ingrp_rslt))
@@ -34,6 +36,8 @@ foreach ($ivr_survey_ingroups_detail as $comment_a => $callmenu_list)
$HTML_output.="<th>"._QXZ("Date")."</th>";
$HTML_output.="<th>"._QXZ("Caller")."</th>";
$HTML_output.="<th>"._QXZ("DID")."</th>";
$CSV_output["ivr_survey_details"].="\""._QXZ("IVR Details for survey")." $survey_name:\"\n\""._QXZ("Date")."\",\""._QXZ("Caller")."\",\""._QXZ("DID")."\",";
for ($t=0; $t<count($callmenu_list); $t++)
{
$svy_menu=$callmenu_list[$t];
@@ -41,11 +45,13 @@ foreach ($ivr_survey_ingroups_detail as $comment_a => $callmenu_list)
$cm_rslt=mysql_to_mysqli($cm_stmt, $link);
$cm_row=mysqli_fetch_row($cm_rslt);
$HTML_output.="<th>".$svy_menu." - ".$cm_row[0]."</th>";
$CSV_output["ivr_survey_details"].="\"$svy_menu - $cm_row[0]\",";
}
$HTML_output.="<th>"._QXZ("Survey voicemail")."</th>";
$HTML_output.="<th>"._QXZ("Agent who handled call prior to survey")."</th>";
$HTML_output.="<th>"._QXZ("Link to call recording prior to survey")."</th>";
$HTML_output.="</tr>\n";
$CSV_output["ivr_survey_details"].="\""._QXZ("Survey voicemail")."\",\""._QXZ("Agent who handled call prior to survey")."\",\""._QXZ("Link to call recording prior to survey")."\"\n";
while ($ivr_row=mysqli_fetch_row($ivr_rslt))
{
@@ -64,10 +70,15 @@ foreach ($ivr_survey_ingroups_detail as $comment_a => $callmenu_list)
$xfercallid=$vcl_row["xfercallid"];
$closer_lead_id=$vcl_row["lead_id"];
$rec_stmt="select filename, location from recording_log where vicidial_id='$vicidial_id'";
$rec_stmt="select filename, location, recording_id, lead_id from recording_log where vicidial_id='$vicidial_id'";
$rec_rslt=mysql_to_mysqli($rec_stmt, $link);
$rec_row=mysqli_fetch_row($rec_rslt);
$rec_link="<a href='$rec_row[1]'>$rec_row[0]</a>";
# $rec_link="<a href='$rec_row[1]'>$rec_row[0]</a>";
if ($log_recording_access<1)
{$rec_link="<a href='$rec_row[1]'>$rec_row[0]</a>";}
else
{$rec_link = "<a href=\"recording_log_redirect.php?recording_id=$rec_row[2]&lead_id=$rec_row[3]&search_archived_data=$search_archived_data\" target=\"_blank\">$rec_row[0]</a>";}
}
$failsafe=0;
@@ -113,11 +124,13 @@ foreach ($ivr_survey_ingroups_detail as $comment_a => $callmenu_list)
$HTML_output.="<td>$date</td>";
$HTML_output.="<td>$caller</td>";
$HTML_output.="<td>$did_pattern</td>";
$CSV_output["ivr_survey_details"].="\"$date\",\"$caller\",\"$did_pattern\",";
for ($i=0; $i<count($callmenu_list); $i++)
{
$svy_menu=$callmenu_list[$i];
$HTML_output.="<td>".(!$survey_array["$svy_menu"] ? "&nbsp;" : $survey_array["$svy_menu"])."</td>";
$CSV_output["ivr_survey_details"].="\"".$survey_array["$svy_menu"]."\",";
}
if ($ivr_survey_ingroups_voicemails)
@@ -141,10 +154,17 @@ foreach ($ivr_survey_ingroups_detail as $comment_a => $callmenu_list)
$HTML_output.="<td>$agent_who_handled</td>";
$HTML_output.="<td>$rec_link</td>";
$HTML_output.="</tr>\n";
$CSV_output["ivr_survey_details"].="\"$voicemail\",\"$agent_who_handled\",\"$rec_row[1]\"\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
}
$HTML_output.="<tr class='export_row'>";
$HTML_output.="<td class='export_row_cell' colspan='".(6+count($callmenu_list))."'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('IVR', 'ivr_survey_details')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>\n";
$HTML_output.="</table>";
$CSV_output["ivr_survey_details"].="\n";
}
}
?>
+100 -25
View File
@@ -5,6 +5,8 @@
#
# CHANGELOG:
# 220825-1617 - First build
# 230106-1500 - Added page flushing
# 230124-1218 - Updated LookupCall function, added unknown statuses option, outcome status/lagged status overrides
#
# NANQUE, not an unanswered call?
@@ -27,12 +29,15 @@ if (isset($_GET["sort_nonbillable_activities"])) {$sort_nonbillable_activities=
if (isset($_GET["sort_outcomes_per_agent"])) {$sort_outcomes_per_agent=$_GET["sort_outcomes_per_agent"];}
elseif (isset($_POST["sort_outcomes_per_agent"])) {$sort_outcomes_per_agent=$_POST["sort_outcomes_per_agent"];}
if (!$known_outcome_statuses) {$known_outcome_statues=array();}
if ($non_latin < 1)
{
$sort_call_results = preg_replace('/[^\s\-_0-9a-zA-Z]/','',$sort_call_results);
$sort_billable_activities = preg_replace('/[^\s\-_0-9a-zA-Z]/','',$sort_billable_activities);
$sort_nonbillable_activities = preg_replace('/[^\s\-_0-9a-zA-Z]/','',$sort_nonbillable_activities);
$sort_outcomes_per_agent = preg_replace('/[^\s\-_0-9a-zA-Z]/','',$sort_outcomes_per_agent);
$known_outcome_statuses = preg_replace('/[^- \.\,\_0-9a-zA-Z]/u','',$known_outcome_statuses);
}
else
{
@@ -40,32 +45,36 @@ else
$sort_billable_activities = preg_replace('/[^\s\-_0-9\p{L}]/u','',$sort_billable_activities);
$sort_nonbillable_activities = preg_replace('/[^\s\-_0-9\p{L}]/u','',$sort_nonbillable_activities);
$sort_outcomes_per_agent = preg_replace('/[^\s\-_0-9\p{L}]/u','',$sort_outcomes_per_agent);
$known_outcome_statuses = preg_replace('/[^- \.\,\_0-9\p{L}]/u','',$known_outcome_statuses);
}
### FUNCTION
function LookUpCall($uniqueid, $comments)
function LookUpCall($uniqueid, $comments, $user)
{
global $link, $DB;
$call_outcome="";
if ($comments=="INBOUND")
if ($uniqueid && strlen($uniqueid)>0)
{
$table_name="vicidial_closer_log";
}
else
{
$table_name="vicidial_log";
}
if ($comments=="INBOUND")
{
$table_name="vicidial_closer_log";
}
else
{
$table_name="vicidial_log";
}
$vl_stmt="select status from ".$table_name." where uniqueid='$uniqueid'";
$vl_rslt=mysqli_query($link, $vl_stmt);
if (mysqli_num_rows($vl_rslt)>0)
{
$vl_row=mysqli_fetch_row($vl_rslt);
$call_outcome=$vl_row[0];
$vl_stmt="select status from ".$table_name." where uniqueid='$uniqueid' and user='$user'";
$vl_rslt=mysqli_query($link, $vl_stmt);
if (mysqli_num_rows($vl_rslt)>0)
{
$vl_row=mysqli_fetch_row($vl_rslt);
$call_outcome=$vl_row[0];
}
return $call_outcome;
}
return $call_outcome;
}
@@ -88,13 +97,14 @@ if ($DB) {$HTML_output.="<B>$vcl_uniqueid_stmt</B><BR>$included_campaigns_ct<BR>
$outcomes_stmt_outb="";
if ($atomic_queue_campaigns_str!="")
{
$outcomes_stmt_outb="select *, if (sub_status in ('BLANK', '') or sub_status is null, '-', sub_status) as pause_code from vicidial_agent_log $vicidial_agent_log_SQL and status!='' and comments!='INBOUND' ";
$outcomes_stmt_outb="select *, if (sub_status in ('BLANK', '') or sub_status is null, '-', sub_status) as pause_code from vicidial_agent_log $vicidial_agent_log_SQL and comments!='INBOUND' "; # and status!=''
}
$outcomes_stmt_inb="";
if ($atomic_queue_ingroups_str!="" && count($val_uniqueid_array)>0)
if ($atomic_queue_ingroups_str!="") # && count($val_uniqueid_array)>0
{
$outcomes_stmt_inb="select *, if (sub_status in ('BLANK', '') or sub_status is null, '-', sub_status) as pause_code from vicidial_agent_log $vicidial_agent_log_UID_SQL and uniqueid in ('".implode("', '", $val_uniqueid_array)."')";
$outcomes_stmt_inb="select *, if (sub_status in ('BLANK', '') or sub_status is null, '-', sub_status) as pause_code from vicidial_agent_log $vicidial_agent_log_UID_SQL and comments='INBOUND'";
# and uniqueid in ('".implode("', '", $val_uniqueid_array)."')
}
$outcomes_stmt=$outcomes_stmt_outb.($outcomes_stmt_outb!="" && $outcomes_stmt_inb!="" ? " UNION " : "").$outcomes_stmt_inb;
@@ -208,21 +218,57 @@ while ($outcomes_row=mysqli_fetch_array($outcomes_rslt))
if (strlen($call_outcome)<=1)
{
$call_type="None";
$status=LookUpCall($uniqueid, $comments);
$status=LookUpCall($uniqueid, $comments, $user);
# print "$status=LookUpCall($uniqueid, $comments);<BR>\n";
$call_outcome=$status;
}
# JCJ 12/6/22 - added for overriding certain statuses
if (array_key_exists($status, $outcome_status_overrides))
{
$call_outcome=$outcome_status_overrides["$status"];
$status=$call_outcome;
}
# JCJ 12/6/22 - added for removing certain statuses that should basically be lagged in certain conditions
# 1/27/23 - changed $outcome_lagged_status_overrides to normal array instead of associative
else if (in_array($status, $outcome_lagged_status_overrides) && strlen($uniqueid)<1)
{
$status="LAGGED";
$call_outcome="";
}
/* JCJ 12/6/22 - commented out, may be useful later
# 1/27/23 - changed $outcome_lagged_status_overrides to normal array instead of associative, below section won't work now
else if (array_key_exists($status, $outcome_lagged_status_overrides))
{
# print_r($outcome_lagged_status_overrides);
# $HTML_output.="<!-- \n*** $uniqueid, $call_outcome, $status\n";
$status=LookUpCall($uniqueid, $comments, $user);
if (in_array($status, $outcome_lagged_status_overrides["$call_outcome"]))
{
$status="LAGGED";
$call_outcome="";
}
else
{
$status=$call_outcome;
}
# $HTML_output.="*** $uniqueid, $call_outcome, $status //-->\n";
}
*/
if ($status_names["$status"])
if ($status_names["$status"] && !in_array($status, $unknown_network_statuses))
{
$call_outcome=$status_names["$status"];
$call_type="Known";
}
else if (in_array($status, $unknown_network_statuses) || strlen($call_outcome)<=1)
{
# $call_outcome.=" (unknown)";
$call_outcome="Network/LAGGED";
}
else
{
$call_outcome.=" (unknown)";
$call_outcome.=" (unknown)"; # commented out 10/13, uncommented 11/2 (known_outcome_stauses not working as they expect)
}
if (strlen($call_outcome)<=1)
@@ -230,6 +276,23 @@ while ($outcomes_row=mysqli_fetch_array($outcomes_rslt))
$call_type="None";
}
/* Added 10/13, removed 11/2 - known_outcome_statuses not having desired effect
if (in_array($status, $selectable_array["$campaign_id"]) || in_array($status, $selectable_array["SYSTEM"]) || in_array($status, $known_outcome_statuses))
{
$outcomes_array["selected"]++;
$agent_details_array["$full_name"]["selected"]++;
$call_type="Known";
}
else
{
$status="---";
$call_type="System/Auto";
$call_outcome="(unknown)";
}
*/
# Human answered (contact)
if (in_array($status, $human_ans_array["$campaign_id"]) || in_array($status, $human_ans_array["SYSTEM"]))
{
@@ -419,6 +482,8 @@ $HTML_output.="<tr class='export_row'>";
$HTML_output.="<td class='export_row_cell' colspan='2'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('OUTCOMES', 'outcomes')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
##################
#### CALL RESULTS OUTCOMES ####
@@ -504,7 +569,7 @@ foreach ($call_results_array as $outcome => $data)
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$data["total_pct"])/$max_call_results_total_pct)."%'></td>";
$HTML_output.="<td>".$data["taken_pct"]." %</td>";
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$data["taken_pct"])/$max_call_results_taken_pct)."%'></td>";
$HTML_output.="<td><a onClick=\"ShowOutcomesDetails('', '$start_date $start_time', '$end_date $end_time', '', '', '".trim(preg_replace("/\(unknown\)/", "", $outcome))."')\"><svg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
$HTML_output.="<td><a onClick=\"ShowOutcomesDetails('', '$start_date $start_time', '$end_date $end_time', '', '', '".trim(preg_replace("/\(unknown\)/", "", $outcome))."')\"><svg width='20' height='20' viewBox='0 0 20 20' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
$HTML_output.="</tr>\n";
$CSV_output["call_results"].="\"$outcome\",\"$data[call_type]\",\"$data[total]\",\"$data[taken]\",\"$data[lost]\",\"$data[total_pct] %\",\"\",\"$data[taken_pct] %\",\n";
@@ -516,6 +581,8 @@ $HTML_output.="<td class='export_row_cell' colspan='10'>"._QXZ("Export as")."...
$HTML_output.="</tr>";
$HTML_output.="</table>";
$HTML_output.="<input type='hidden' name='sort_call_results' id='sort_call_results' value='$sort_call_results'>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###############################
#### BILLABLE ACTIVITIES ####
@@ -573,7 +640,7 @@ $HTML_output.="<th><a class='header_link' name='billable_activities_min' id='bil
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Avg.").("avg"==$sort_billable_activities_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_billable_activities').value='".("avg"==$sort_billable_activities_preg ? "$reverse_link" : "avg")."'; this.form.action+='#sba_anchor'; this.form.submit()\"></th>\n";
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Min.").("min"==$sort_billable_activities_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_billable_activities').value='".("min"==$sort_billable_activities_preg ? "$reverse_link" : "min")."'; this.form.action+='#sba_anchor'; this.form.submit()\"></th>\n";
$HTML_output.="<th>Max.</a></th>";
$HTML_output.="<th>"._QXZ("Max.")."</a></th>";
$HTML_output.="<th>%</th>";
$HTML_output.="<th>&nbsp;</th>";
$HTML_output.="</tr>\n";
@@ -604,6 +671,8 @@ $HTML_output.="<td class='export_row_cell' colspan='10'>"._QXZ("Export as")."...
$HTML_output.="</tr>";
$HTML_output.="</table>";
$HTML_output.="<input type='hidden' name='sort_billable_activities' id='sort_billable_activities' value='$sort_billable_activities'>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###############################
#### NONBILLABLE ACTIVITIES ####
@@ -691,6 +760,8 @@ $HTML_output.="<td class='export_row_cell' colspan='10'>"._QXZ("Export as")."...
$HTML_output.="</tr>";
$HTML_output.="</table>";
$HTML_output.="<input type='hidden' name='sort_nonbillable_activities' id='sort_nonbillable_activities' value='$sort_billable_activities'>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###############################
#### AGENT DETAILS REPORT #####
@@ -760,6 +831,8 @@ $HTML_output.="<tr class='export_row'>";
$HTML_output.="<td class='export_row_cell' colspan='15'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('OUTCOMES', 'agent_details')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###############################
#### AGENT OUTCOMES REPORT ####
@@ -868,6 +941,8 @@ $HTML_output.="</tr>";
$HTML_output.="</table>";
$HTML_output.="<input type='hidden' name='sort_outcomes_per_agent' id='sort_outcomes_per_agent' value='$sort_outcomes_per_agent'>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###############################
if ($download_rpt)
@@ -918,4 +993,4 @@ echo $HTML_header;
echo $HTML_output;
?>
</body>
</html>
</html>
@@ -5,6 +5,7 @@
#
# CHANGELOG:
# 220825-1615 - First build
# 230123-1827 - Added auto download limits
#
if (isset($_GET["page_no"])) {$page_no=$_GET["page_no"];}
@@ -152,6 +153,12 @@ $HTML_output.="</td>";
$HTML_output.="</tr>";
$HTML_output.="<tr>";
$CSV_output="";
if ($total_calls>$auto_download_limit)
{
$CSV_output.="\""._QXZ("WARNING").":\",\""._QXZ("OVER")." $auto_download_limit "._QXZ("RECORDS")."\",\""._QXZ("AUTOMATIC DOWNLOAD")."\"\n\n\n";
}
foreach ($selected_columns as $display_name => $column_name)
{
if ($display_name!="uniqueid")
@@ -247,7 +254,7 @@ foreach ($output_array as $data_row)
}
else
{
$HTML_output.="<td><a onClick=\"ShowCallDetails('$value', 'answered')\"><svg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
$HTML_output.="<td><a onClick=\"ShowCallDetails('$value', 'answered')\"><svg width='20' height='20' viewBox='0 0 20 20' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
# $HTML_output.="<td><IMG SRC=\"images/glass.png\" onClick=\"ShowCallDetails('$value')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP></td>";
}
}
@@ -263,7 +270,7 @@ $HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetail
$HTML_output.="</td>";
# $HTML_output.="<td class='export_row_cell' align='center' colspan='".(count($selected_columns)-2)."'>"._QXZ("Export as")."... &nbsp;&nbsp;&nbsp;&nbsp;<a href=\"".$PHP_SELF."?download_rpt=answer_details&sort_unanswered_details=".$sort_unanswered_details."\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a>&nbsp;&nbsp;&nbsp;&nbsp;Current page: $page_no / $total_pages</td>";
$HTML_output.="<td class='export_row_cell' colspan='".(count($selected_columns)-2)."'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('UNANSWERED_DT', 'answer_details')\" title=\"Export as a CSV file\" value='CSV'>&nbsp;&nbsp;&nbsp;&nbsp;"._QXZ("Current page").": $page_no / $total_pages</td>";
# $HTML_output.="<td class='export_row_cell' align='right'><B><a class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&page_no=".($page_no+1)."#page_anchor' alt='Next page of results'>>></a>&nbsp;&nbsp;&nbsp;&nbsp;<a class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&page_no=".($total_pages-1)."#page_anchor' alt='Last page of results'>>|</a></B></td>";
$HTML_output.="<td class='export_row_cell' align='right'><B><a class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&page_no=".($page_no+1)."#page_anchor' alt='Next page of results'>>></a>&nbsp;&nbsp;&nbsp;&nbsp;<a class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&page_no=".($total_pages-1)."#page_anchor' alt='Last page of results'>>|</a></B></td>";
$HTML_output.="<td class='export_row_cell' align='right'>";
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('UNANSWERED_DT', '".($page_no<$total_pages ? $page_no+1 : $total_pages)."')\" title=\"Next page\" value='>>'>&nbsp;&nbsp;&nbsp;&nbsp;";
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('UNANSWERED_DT', '".($total_pages)."')\" title=\"Last page\" value='>|'>";
+62 -10
View File
@@ -5,6 +5,7 @@
#
# CHANGELOG:
# 220825-1614 - First build
# 230106-1506 - Uniqueid array modification to speed up page loading, added page flushing
#
if (isset($_GET["sort_agents_on_queue"])) {$sort_agents_on_queue=$_GET["sort_agents_on_queue"];}
@@ -96,7 +97,8 @@ $agent_stats_wi=array();
############################
$uniqueid_array=array();
$unanswered_uniqueid_array=array();
$unans_uniqueid_array=array(); # For implosion in SQL queries
$unanswered_uniqueid_array=array(); # Associative, for checking
while ($calls_row=mysqli_fetch_array($calls_rslt))
{
@@ -122,7 +124,9 @@ while ($calls_row=mysqli_fetch_array($calls_rslt))
# {
$total_unanswered_calls++;
$total_unanswered_call_length+=$calls_row["length_in_sec"];
array_push($unanswered_uniqueid_array, $calls_row["uniqueid"]);
# array_push($unanswered_uniqueid_array, $calls_row["uniqueid"]);
array_push($unans_uniqueid_array, $calls_row["uniqueid"]);
$unanswered_uniqueid_array["$calls_row[uniqueid]"]="Y";
$total_unanswered_wait_time+=$calls_row["queue_seconds"];
if (preg_match('/^DROP$/', $calls_row["status"])) {$unanswered_coverage_calls++;}
if ($calls_row["direction"]=="O")
@@ -160,7 +164,8 @@ while ($calls_row=mysqli_fetch_array($calls_rslt))
}
else
{
array_push($uniqueid_array, $calls_row["uniqueid"]);
# array_push($uniqueid_array, $calls_row["uniqueid"]);
$uniqueid_array["$calls_row[uniqueid]"]="Y";
$total_answered_calls++;
$answered_coverage_calls++;
$total_answered_wait_time+=$calls_row["queue_seconds"];
@@ -387,6 +392,7 @@ $CSV_output["all_calls"].="\""._QXZ("Total waiting time").":\",\"".$total_unansw
$CSV_output["all_calls"].="\""._QXZ("Average initial position").":\",\"".$average_unanswered_position."\"\n";
$CSV_output["all_calls"].="\""._QXZ("Min initial position").":\",\"".$min_unanswered_position."\"\n";
$CSV_output["all_calls"].="\""._QXZ("Max initial position").":\",\"".$max_unanswered_position."\"\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
### Commented out 5/19/22 - not needed
### $CSV_output["all_calls"].="\""._QXZ("Coverage").":\",\"".$coverage." H\"\n";
@@ -468,6 +474,7 @@ $CSV_output["all_calls_wi"].="\""._QXZ("Total waiting time").":\",\"".$total_una
$CSV_output["all_calls_wi"].="\""._QXZ("Average initial position").":\",\"".$average_unanswered_position_wi."\"\n";
$CSV_output["all_calls_wi"].="\""._QXZ("Min initial position").":\",\"".$min_unanswered_position_wi."\"\n";
$CSV_output["all_calls_wi"].="\""._QXZ("Max initial position").":\",\"".$max_unanswered_position_wi."\"\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
### Commented out 5/19/22 - not needed
### $CSV_output["all_calls_wi"].="\""._QXZ("Coverage").":\",\"".$coverage_wi." H\"\n";
@@ -514,7 +521,7 @@ switch ($sort_agents_on_queue)
break;
}
$HTML_output.="<BR><h2 class='rpt_header'>Agents on queue: $NWB#VERM_UNANSWERED-calls_by_queue$NWE</h2>";
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Agents on queue").": $NWB#VERM_UNANSWERED-calls_by_queue$NWE</h2>";
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
$HTML_output.="<table border='0' cellpadding='0' cellspacing='0'>";
$HTML_output.="<tr><td width='60%'>";
@@ -580,7 +587,7 @@ $HTML_output.="</td></tr></table>";
######################
#### SERVICE LEVEL ####
$HTML_output.="<BR><h2 class='rpt_header'>Service Level Agreement (inbound calls only): $NWB#VERM_UNANSWERED-inclusive_SLA$NWE</h2>";
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Service Level Agreement (inbound calls only)").": $NWB#VERM_UNANSWERED-inclusive_SLA$NWE</h2>";
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
$HTML_output.="<table border='0' cellpadding='0' cellspacing='0'>";
$HTML_output.="<tr><td width='60%'>";
@@ -714,6 +721,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:50vh; width:50vh\"><canvas id='disconnection_causes_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
######################
/*
@@ -812,6 +822,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:40vh; width:60vh\"><canvas id='unanswered_calls_by_queue_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#####################
#### UNANSWERED CALLS BY AGENT ###
@@ -851,6 +864,9 @@ $HTML_output.="<tr class='export_row'>";
$HTML_output.="<td colspan='5' class='export_row_cell'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('UNANSWERED', 'unanswered_calls_by_agent')\" title=\"Export as a CSV file\" value='CSV'></td>";
$HTML_output.="</tr>";
$HTML_output.="</table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#####################
#### UNANSWERED CALLS - DISTRIBUTION BY LENGTH ###
@@ -935,6 +951,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:80vh; width:80vh\"><canvas id='unanswered_calls_by_distribution_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
###############################
#### SERVICE LEVEL ####
@@ -1013,6 +1032,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:80vh; width:80vh\"><canvas id='service_level_agreement_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
######################
#### UNANSWERED CALLS BY KEYPRESS ###
@@ -1028,7 +1050,7 @@ $HTML_output.="</tr>";
$CSV_output["unanswered_calls_by_keypress"].="\""._QXZ("Key")."\",\""._QXZ("N. Calls")."\",\"\",\"...\"\n";
$keypress_stmt="select extension, count(*) as ct From live_inbound_log where uniqueid in ('".implode("', '", $unanswered_uniqueid_array)."') and extension not in ('s', 'i', 't') and comment_a='CALLMENU' group by extension order by extension";
$keypress_stmt="select extension, count(*) as ct From live_inbound_log where uniqueid in ('".implode("', '", $unans_uniqueid_array)."') and extension not in ('s', 'i', 't') and comment_a='CALLMENU' group by extension order by extension";
if ($DB) {$HTML_output.="<B>$keypress_stmt</B>";}
$keypress_rslt=mysql_to_mysqli($keypress_stmt, $link);
while ($kp_row=mysqli_fetch_array($keypress_rslt))
@@ -1058,6 +1080,9 @@ $HTML_output.="<td colspan='5' class='export_row_cell'>"._QXZ("Export as")."...<
$HTML_output.="</tr>";
$HTML_output.="</table>";
$HTML_output.="** does not include start/invalid/timeout options<BR>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#####################################
/*
@@ -1218,6 +1243,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:40vh; width:40vh\"><canvas id='queue_position_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#####################
#### UNANSWERED CALLS BY POSITION ###
@@ -1276,6 +1304,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:40vh; width:40vh\"><canvas id='queue_position_all_calls_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#####################
##### UN ANSWERED IVR STATS #####
@@ -1289,7 +1320,8 @@ while ($ivr_row=mysqli_fetch_array($ivr_rslt))
{
$uniqueid=$ivr_row[0];
if (in_array($uniqueid, $unanswered_uniqueid_array))
# if (in_array($uniqueid, $unanswered_uniqueid_array))
if (isset($unanswered_uniqueid_array["$uniqueid"]))
{
if (!$prev_id)
{
@@ -1437,6 +1469,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:400px; width:500px\"><canvas id='unanswered_ivr_selection_display' style=\"height:400px; width:500px\" role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#####################
##### IVR STATS #####
@@ -1451,7 +1486,8 @@ while ($ivr_row=mysqli_fetch_array($ivr_rslt))
{
$uniqueid=$ivr_row[0];
if (in_array($uniqueid, $unanswered_uniqueid_array) || in_array($uniqueid, $uniqueid_array))
# if (in_array($uniqueid, $unanswered_uniqueid_array) || in_array($uniqueid, $uniqueid_array))
if (isset($unanswered_uniqueid_array["$uniqueid"])|| isset($uniqueid_array["$uniqueid"]))
{
if (!$prev_id)
{
@@ -1599,6 +1635,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:500px; width:400px\"><canvas id='ivr_selection_display' style=\"height:500px; width:400px\" role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#####################
###### UNANSWERED inbound DID used #####
@@ -1610,7 +1649,8 @@ $did_counts=array(); # 0 - total calls, 1 - total time, 2 - min time, 3 - max ti
$untracked_did_calls=$total_unanswered_calls;
while ($did_row=mysqli_fetch_array($did_rslt))
{
if(in_array($did_row["uniqueid"], $unanswered_uniqueid_array))
# if(in_array($did_row["uniqueid"], $unanswered_uniqueid_array))
if(isset($unanswered_uniqueid_array["$did_row[uniqueid]"]))
{
$did_counts["$did_row[extension]"]++;
$untracked_did_calls--;
@@ -1682,6 +1722,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:600px; width:400px\"><canvas id='unanswered_did_used_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
######################
###### Inbound DID used #####
@@ -1693,7 +1736,8 @@ $did_counts=array(); # 0 - total calls, 1 - total time, 2 - min time, 3 - max ti
$untracked_did_calls=$total_calls;
while ($did_row=mysqli_fetch_array($did_rslt))
{
if(in_array($did_row["uniqueid"], $unanswered_uniqueid_array) || in_array($did_row["uniqueid"], $uniqueid_array))
# if(in_array($did_row["uniqueid"], $unanswered_uniqueid_array) || in_array($did_row["uniqueid"], $uniqueid_array))
if(isset($unanswered_uniqueid_array["$did_row[uniqueid]"]) || isset($uniqueid_array["$did_row[uniqueid]"]))
{
$did_counts["$did_row[extension]"]++;
$untracked_did_calls--;
@@ -1765,6 +1809,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:600px; width:400px\"><canvas id='did_used_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
######################
#### CALL OVERVIEW ####
@@ -1855,6 +1902,8 @@ $HTML_output.="</table>";
$CSV_output["call_overview"].="\"TOTAL\",\"".$total_queue_calls."\",\"".$total_queue_answered."\",\"".$total_queue_unanswered."\",\"".($avg_call_time>=3600 ? floor($avg_call_time/3600).":" : "").gmdate("i:s", $avg_call_time)."\",\"".($total_queue_call_time>=3600 ? floor($total_queue_call_time/3600).":" : "").gmdate("i:s", $total_queue_call_time)."\",\"".($avg_wait_time>=3600 ? floor($avg_wait_time/3600).":" : "").gmdate("i:s", $avg_wait_time)."\",\"".($total_queue_wait_time>=3600 ? floor($total_queue_wait_time/3600).":" : "").gmdate("i:s", $total_queue_wait_time)."\"\n";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
#######################
#### SERVICE LEVEL ####
@@ -1934,6 +1983,9 @@ $HTML_output.="</table>";
$HTML_output.="</td><td width='*' align='center' valign='top'>";
$HTML_output.="<div class=\"chart-container\" style=\"height:80vh; width:80vh\"><canvas id='answered_service_level_agreement_display' role=\"img\"> </canvas></div>";
$HTML_output.="</td></tr></table>";
if (!$download_rpt) {echo $HTML_output; ob_flush(); flush(); $HTML_output="";}
######################
if ($download_rpt)
+15 -18
View File
@@ -1,7 +1,7 @@
<?php
# VERM_admin.php - Vicidial Enhanced Reporting administration page
#
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
#
# CHANGELOG:
# 220825-1609 - First build
@@ -10,8 +10,8 @@
$startMS = microtime();
$version = '2.14-1';
$build = '220825-1609';
$version = '2.14-873';
$build = '230127-1750';
$report_name = 'VERM Reports';
@@ -21,18 +21,6 @@ require("dbconnect_mysqli.php");
require("functions.php");
require("VERM_options.php"); # Added cuz I'm sick of keeping track.
#### CUSTOM REPORT VARIABLES ####
if (isset($_GET["vicidial_queue_groups"])) {$vicidial_queue_groups=$_GET["vicidial_queue_groups"];}
elseif (isset($_POST["vicidial_queue_groups"])) {$vicidial_queue_groups=$_POST["vicidial_queue_groups"];}
if (isset($_GET["report_types_to_display"])) {$report_types_to_display=$_GET["report_types_to_display"];}
elseif (isset($_POST["report_types_to_display"])) {$report_types_to_display=$_POST["report_types_to_display"];}
if (isset($_GET["start_date"])) {$start_date=$_GET["start_date"];}
elseif (isset($_POST["start_date"])) {$start_date=$_POST["start_date"];}
if (isset($_GET["end_date"])) {$end_date=$_GET["end_date"];}
elseif (isset($_POST["end_date"])) {$end_date=$_POST["end_date"];}
if (isset($_GET["DB"])) {$DB=$_GET["DB"];}
elseif (isset($_POST["DB"])) {$DB=$_POST["DB"];}
#############################################
##### START SYSTEM_SETTINGS LOOKUP #####
$stmt = "SELECT use_non_latin,outbound_autodial_active,slave_db_server,reports_use_slave_db,enable_languages,language_method,agent_whisper_enabled,report_default_format,enable_pause_code_limits,allow_web_debug,admin_screen_colors,admin_web_directory FROM system_settings;";
@@ -71,6 +59,16 @@ if (file_exists('options.php'))
require('options.php');
}
#### CUSTOM REPORT VARIABLES ####
if (isset($_GET["vicidial_queue_groups"])) {$vicidial_queue_groups=$_GET["vicidial_queue_groups"];}
elseif (isset($_POST["vicidial_queue_groups"])) {$vicidial_queue_groups=$_POST["vicidial_queue_groups"];}
if (isset($_GET["report_types_to_display"])) {$report_types_to_display=$_GET["report_types_to_display"];}
elseif (isset($_POST["report_types_to_display"])) {$report_types_to_display=$_POST["report_types_to_display"];}
if (isset($_GET["start_date"])) {$start_date=$_GET["start_date"];}
elseif (isset($_POST["start_date"])) {$start_date=$_POST["start_date"];}
if (isset($_GET["end_date"])) {$end_date=$_GET["end_date"];}
elseif (isset($_POST["end_date"])) {$end_date=$_POST["end_date"];}
### Force hard-coded variables
# $report_display_type='LIMITED';
# $ingroup_filter=array('_STAY','TEST_IN2','TEST_IN3');
@@ -697,8 +695,7 @@ function LaunchWallboard(wallboard_id)
}
</script>
<link rel="stylesheet" type="text/css" href="VERM_stylesheet.php">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="jquery.min.js"></script>
<script language="JavaScript" src="help.js"></script>
<?php
@@ -734,7 +731,7 @@ echo "<div id='HelpDisplayDiv' class='help_info' style='display:none;'></div>";
echo "</tr>";
echo "<tr class='export_row'>";
echo "<td align='right'>Queue:</td>";
echo "<td align='right'>"._QXZ("Queue")."</td>";
echo "<td align='left' width='320' nowrap>";
echo " <input list='VERM_report_queues' type='text' size='40' maxlength='255' class='VERM_form_field' id='vicidial_queue_groups' name='vicidial_queue_groups' onClick=\"javascript:this.value=''\" value=''>\n"; # $vicidial_queue_groups
echo " <datalist id=\"VERM_report_queues\" name=\"VERM_report_queues\">";
@@ -0,0 +1,205 @@
function GoToReport(selected_report, realtime_override)
{
// alert(selected_report);
if (realtime_override) {document.location.href='/vicidial/realtime_report.php'; exit;}
document.getElementById("report_type").value=selected_report;
document.getElementById("download_rpt").value='';
document.forms[0].submit();
}
function DownloadReport(selected_report, selected_subreport, sort_param, sort_value)
{
// alert(selected_report);
// alert(document.getElementById("report_type").value);
document.getElementById("report_type").value=selected_report;
document.getElementById("download_rpt").value=selected_subreport;
document.forms[0].submit();
}
function GoToDetailsPage(selected_report, page_no)
{
// alert(document.getElementById("report_type").value);
document.getElementById("report_type").value=selected_report;
document.getElementById("page_no").value=page_no;
document.forms[0].submit();
}
function GoToCustomReport(realtime_override)
{
var full_report_var_str="";
if (realtime_override) {document.location.href='/vicidial/realtime_report.php'; exit;}
var report_queues_value=$( "input[type=text][id=vicidial_queue_groups]" ).val();
if (report_queues_value!="")
{
var vicidial_queue_groups=$('#VERM_report_queues [value="' + report_queues_value + '"]').data('value');
full_report_var_str+="&vicidial_queue_groups="+vicidial_queue_groups;
}
else
{
vicidial_queue_groups="000_MCRR_ALL_Calls";
full_report_var_str+="&vicidial_queue_groups="+vicidial_queue_groups;
}
var report_types_value=$( "input[type=text][id=report_types]" ).val();
if (report_types_value!="")
{
var report_type=$('#VERM_reports [value="' + report_types_value + '"]').data('value');
full_report_var_str+="&report_type="+report_type;
}
var time_period_value=$( "input[type=text][id=time_period]" ).val();
if (time_period_value!="")
{
var time_period=$('#VERM_time_period [value="' + time_period_value + '"]').data('value');
full_report_var_str+="&time_period="+time_period;
}
var start_date=document.getElementById('start_date').value;
if (start_date!="") {full_report_var_str+="&start_date="+start_date;}
var start_time_hour=document.getElementById('start_time_hour').value;
if (start_time_hour!="") {full_report_var_str+="&start_time_hour="+start_time_hour;}
var start_time_min=document.getElementById('start_time_min').value;
if (start_time_min!="") {full_report_var_str+="&start_time_min="+start_time_min;}
var end_date=document.getElementById('end_date').value;
if (end_date!="") {full_report_var_str+="&end_date="+end_date;}
var end_time_hour=document.getElementById('end_time_hour').value;
if (end_time_hour!="") {full_report_var_str+="&end_time_hour="+end_time_hour;}
var end_time_min=document.getElementById('end_time_min').value;
if (end_time_min!="") {full_report_var_str+="&end_time_min="+end_time_min;}
var hourly_slot=document.getElementById('hourly_slot').value;
if (hourly_slot!="") {full_report_var_str+="&hourly_slot="+hourly_slot;}
var SLA_initial_period=document.getElementById('SLA_initial_period').value;
if (SLA_initial_period!="") {full_report_var_str+="&SLA_initial_period="+SLA_initial_period;}
var SLA_initial_interval=document.getElementById('SLA_initial_interval').value;
if (SLA_initial_interval!="") {full_report_var_str+="&SLA_initial_interval="+SLA_initial_interval;}
var SLA_max_period=document.getElementById('SLA_max_period').value;
if (SLA_max_period!="") {full_report_var_str+="&SLA_max_period="+SLA_max_period;}
var SLA_interval=document.getElementById('SLA_interval').value;
if (SLA_interval!="") {full_report_var_str+="&SLA_interval="+SLA_interval;}
var short_call_wait_limit=document.getElementById('short_call_wait_limit').value;
if (short_call_wait_limit!="") {full_report_var_str+="&short_call_wait_limit="+short_call_wait_limit;}
var short_call_talk_limit=document.getElementById('short_call_talk_limit').value;
if (short_call_wait_limit!="") {full_report_var_str+="&short_call_talk_limit="+short_call_talk_limit;}
var short_attempt_wait_limit=document.getElementById('short_attempt_wait_limit').value;
if (short_attempt_wait_limit!="") {full_report_var_str+="&short_attempt_wait_limit="+short_attempt_wait_limit;}
var users_value=$( "input[type=text][id=users]" ).val();
if (users_value!="")
{
var users=$('#agent_filter_list [value="' + users_value + '"]').data('value');
full_report_var_str+="&users="+users;
}
var dialer_location_value=$( "input[type=text][id=location]" ).val();
if (dialer_location_value!="")
{
var dialer_location=$('#location_filter_list [value="' + dialer_location_value + '"]').data('value');
full_report_var_str+="&location="+dialer_location;
}
var user_group_value=$( "input[type=text][id=user_group]" ).val();
if (user_group_value!="")
{
var user_group=$('#user_group_filter_list [value="' + user_group_value + '"]').data('value');
full_report_var_str+="&user_group="+user_group;
}
var statuses_value=$( "input[type=text][id=statuses]" ).val();
if (statuses_value!="")
{
var statuses=$('#statuses_filter_list [value="' + statuses_value + '"]').data('value');
full_report_var_str+="&statuses="+statuses;
}
var asterisk_cid=document.getElementById('asterisk_cid').value;
if (asterisk_cid!="") {full_report_var_str+="&asterisk_cid="+asterisk_cid;}
var phone_number=document.getElementById('phone_number').value;
if (phone_number!="") {full_report_var_str+="&phone_number="+phone_number;}
var wait_sec_min=document.getElementById('wait_sec_min').value;
if (wait_sec_min!="") {full_report_var_str+="&wait_sec_min="+wait_sec_min;}
var wait_sec_max=document.getElementById('wait_sec_max').value;
if (wait_sec_max!="") {full_report_var_str+="&wait_sec_max="+wait_sec_max;}
var length_in_sec_min=document.getElementById('length_in_sec_min').value;
if (length_in_sec_min!="") {full_report_var_str+="&length_in_sec_min="+length_in_sec_min;}
var length_in_sec_max=document.getElementById('length_in_sec_max').value;
if (length_in_sec_max!="") {full_report_var_str+="&length_in_sec_max="+length_in_sec_max;}
var disconnection_cause_value=$( "input[type=text][id=disconnection_cause]" ).val();
if (disconnection_cause_value!="")
{
var disconnection_cause=$('#disconnection_cause_list [value="' + disconnection_cause_value + '"]').data('value');
full_report_var_str+="&disconnection_cause="+disconnection_cause;
}
var queue_position_min=document.getElementById('queue_position_min').value;
if (queue_position_min!="") {full_report_var_str+="&queue_position_min="+queue_position_min;}
var queue_position_max=document.getElementById('queue_position_max').value;
if (queue_position_max!="") {full_report_var_str+="&queue_position_max="+queue_position_max;}
var call_count_min=document.getElementById('call_count_min').value;
if (call_count_min!="") {full_report_var_str+="&call_count_min="+call_count_min;}
var call_count_max=document.getElementById('call_count_max').value;
if (call_count_max!="") {full_report_var_str+="&call_count_max="+call_count_max;}
var did_value=$( "input[type=text][id=did]" ).val();
if (did_value!="")
{
var did=$('#did_list [value="' + did_value + '"]').data('value');
full_report_var_str+="&did="+did;
}
var ivr_choice=document.getElementById('ivr_choice').value;
if (ivr_choice!="") {full_report_var_str+="&ivr_choice="+ivr_choice;}
var server_value=$( "input[type=text][id=server]" ).val();
if (server_value!="")
{
var server=$('#server_list [value="' + server_value + '"]').data('value');
full_report_var_str+="&server="+server;
}
var dow_menu = document.getElementById('dow[]');
for (var i=0; i<dow_menu.options.length; i++)
{
if (dow_menu.options[i].selected)
{
full_report_var_str+="&dow[]="+dow_menu.options[i].value;
}
}
// if (dow!="") {full_report_var_str+="&dow[]="+dow;}
var time_of_day_start=document.getElementById('time_of_day_start').value;
if (time_of_day_start!="") {full_report_var_str+="&time_of_day_start="+time_of_day_start;}
var time_of_day_end=document.getElementById('time_of_day_start').value;
if (time_of_day_end!="") {full_report_var_str+="&time_of_day_end="+time_of_day_end;}
// alert(full_report_var_str);
document.location.href=document.forms[0].action+"?"+full_report_var_str;
}
@@ -5,10 +5,11 @@
#
# CHANGELOG:
# 220825-1607 - First build
# 230123-1735 - Changed require files to local dbconnect/function files
#
require("../vicidial/dbconnect_mysqli.php");
require("../vicidial/functions.php");
require("dbconnect_mysqli.php");
require("functions.php");
require("VERM_options.php");
?>
@@ -9,8 +9,8 @@
$startMS = microtime();
$version = '2.14-1';
$build = '220825-1606';
$version = '2.14-873';
$build = '230127-1750';
header ("Content-type: text/html; charset=utf-8");
@@ -688,7 +688,7 @@ $F=''; $FG=''; $B=''; $BG='';
<HTML>
<HEAD>
<link rel="stylesheet" type="text/css" href="VERM_stylesheet.php">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="jquery.min.js"></script>
<script language="JavaScript" src="calendar_db.js"></script>
<script language="JavaScript" src="help.js"></script>
<script language="JavaScript" src="VERM_custom_form_functions.php"></script>
+31 -1
View File
@@ -1,3 +1,7 @@
var IE = document.all?true:false
// If NS -- that is, !IE -- then set up for mouse capture
if (!IE) document.captureEvents(Event.MOUSEMOVE)
// LINK BUTTON FUNCTION
function GenerateLink(e) {
document.getElementById("DisplayLinkDiv").innerHTML="";
@@ -264,4 +268,30 @@ function ToggleVisibility(span_name, display_type) {
{
span_vis.display = display_type;
}
}
}
function AutoDownloadWarning(e, report_name, limit)
{
document.getElementById("HelpDisplayDiv").innerHTML="";
if (IE) { // grab the x-y pos.s if browser is IE
tempX = event.clientX + document.body.scrollLeft+250
tempY = event.clientY + document.body.scrollTop
} else { // grab the x-y pos.s if browser is NS
tempX = e.pageX
tempY = e.pageY
}
// catch possible negative values in NS4
if (tempX < 0){tempX = 0}
if (tempY < 0){tempY = 0}
// show the position values in the form named Show
// in the text fields named MouseX and MouseY
tempX+=20;
document.getElementById("HelpDisplayDiv").style.display="block";
document.getElementById("HelpDisplayDiv").style.left = tempX + "px";
document.getElementById("HelpDisplayDiv").style.top = tempY + "px";
document.getElementById("HelpDisplayDiv").innerHTML="<TABLE CELLPADDING=2 CELLSPACING=0 border='0' class='help_td' width='300'><TR><TD VALIGN='TOP' width='280'><FONT class='help_bold'>NOTICE:</B></font></td><TD VALIGN='TOP' align='right' width='20'>&nbsp;</td></tr><TR><TD VALIGN='TOP' colspan='2'>"+report_name+" report is over "+limit+" records, and will auto-download as a CSV file rather than attempt to display to your screen.</td></tr></TABLE>";
}
+26 -16
View File
@@ -5,6 +5,7 @@
#
# CHANGELOG:
# 220825-1622 - First build
# 230106-1317 - Added missing QXZ, added pull of selectable statuses, human answered statues now include DISPO and SYSTEM
#
if (isset($_GET["start_date"])) {$start_date=$_GET["start_date"];}
@@ -305,8 +306,17 @@ while ($sale_row=mysqli_fetch_array($sale_rslt))
array_push($sale_array["$sale_row[campaign_id]"], $sale_row["status"]);
}
$selectable_array=array("SYSTEM" => array());
$selectable_stmt="select distinct status, 'SYSTEM' as campaign_id from vicidial_statuses where selectable='Y' UNION select distinct status, campaign_id from vicidial_campaign_statuses where selectable='Y'";
$selectable_rslt=mysql_to_mysqli($selectable_stmt, $link);
while ($selectable_row=mysqli_fetch_array($selectable_rslt))
{
if (!array_key_exists("$selectable_row[campaign_id]", $selectable_array)) {$selectable_array["$selectable_row[campaign_id]"]=array();}
array_push($selectable_array["$selectable_row[campaign_id]"], $selectable_row["status"]);
}
$human_ans_array=array("SYSTEM" => array());
$human_ans_stmt="select distinct status, 'SYSTEM' as campaign_id from vicidial_statuses where human_answered='Y' UNION select distinct status, campaign_id from vicidial_campaign_statuses where human_answered='Y'";
$human_ans_stmt="select distinct status, 'SYSTEM' as campaign_id from vicidial_statuses where human_answered='Y' UNION select distinct status, campaign_id from vicidial_campaign_statuses where human_answered='Y' UNION select 'DISPO', 'SYSTEM'";
$human_ans_rslt=mysql_to_mysqli($human_ans_stmt, $link);
while ($human_ans_row=mysqli_fetch_array($human_ans_rslt))
{
@@ -442,20 +452,20 @@ $border_colors=array("#00FF00", "#FF0000", "#0000FF", "#FFFF00", "#FF00FF", "#00
###########################
### REPORT FULL NAMES ###
$report_full_names_array["ANSWERED"]="Answered calls";
$report_full_names_array["ANSWERED_DT"]="Answered calls details";
$report_full_names_array["UNANSWERED"]="Unanswered calls";
$report_full_names_array["UNANSWERED_DT"]="Unanswered calls details";
$report_full_names_array["IVR"]="IVR call statistics";
$report_full_names_array["AREA"]="Answered/unanswered call counts by area code";
$report_full_names_array["ATT"]="Inbound call distribution";
$report_full_names_array["DAY"]="Call reports - day/date breakdown";
$report_full_names_array["HOUR"]="Call reports - hourly breakdown";
$report_full_names_array["DOW"]="Call reports - day-of-week breakdown";
$report_full_names_array["AGENTS"]="Agent statistics";
$report_full_names_array["AGENTS_DT"]="Agent call details";
$report_full_names_array["OUTCOMES"]="Outcome/status call statistics";
$report_full_names_array["STATS"]="Selected call statistics";
$report_full_names_array["CALLS"]="Combined answered/unanswered call details";
$report_full_names_array["ANSWERED"]=_QXZ("Answered calls");
$report_full_names_array["ANSWERED_DT"]=_QXZ("Answered calls details");
$report_full_names_array["UNANSWERED"]=_QXZ("Unanswered calls");
$report_full_names_array["UNANSWERED_DT"]=_QXZ("Unanswered calls details");
$report_full_names_array["IVR"]=_QXZ("IVR call statistics");
$report_full_names_array["AREA"]=_QXZ("Answered/unanswered call counts by area code");
$report_full_names_array["ATT"]=_QXZ("Inbound call distribution");
$report_full_names_array["DAY"]=_QXZ("Call reports - day/date breakdown");
$report_full_names_array["HOUR"]=_QXZ("Call reports - hourly breakdown");
$report_full_names_array["DOW"]=_QXZ("Call reports - day-of-week breakdown");
$report_full_names_array["AGENTS"]=_QXZ("Agent statistics");
$report_full_names_array["AGENTS_DT"]=_QXZ("Agent call details");
$report_full_names_array["OUTCOMES"]=_QXZ("Outcome/status call statistics");
$report_full_names_array["STATS"]=_QXZ("Selected call statistics");
$report_full_names_array["CALLS"]=_QXZ("Combined answered/unanswered call details");
#########################
?>
+41 -41
View File
@@ -1,10 +1,11 @@
<?php
# VERM_header.inc - Vicidial Enhanced Reporting header output
#
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
#
# CHANGELOG:
# 220825-1621 - First build
# 230106-1321 - Added missing QXZ functions, removed debug output
#
/* 08/26 - redundant, already used in parent VERM_main_report_page.php
@@ -104,7 +105,7 @@ $HTML_header="<html>\n";
$HTML_header.="<TITLE>"._QXZ("$report_name").": $report_full_names_array[$report_type]</TITLE>\n";
$HTML_header.="<HEAD>\n";
$HTML_header.="<link rel=\"stylesheet\" type=\"text/css\" href=\"VERM_stylesheet.php\">\n";
$HTML_header.="<script src=\"https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n";
$HTML_header.="<script src=\"jquery.min.js\"></script>\n";
$HTML_header.="<script language=\"JavaScript\" src=\"calendar_db.js\"></script>\n";
$HTML_header.="<script language=\"JavaScript\" src=\"help.js\"></script>\n";
$HTML_header.="<script language=\"JavaScript\" src=\"VERM_custom_form_functions.php\"></script>\n";
@@ -118,9 +119,6 @@ $HTML_header.="<div id='AgentDetailsDiv' class='details_info' style='display:non
$HTML_header.="<div id='OutcomesDetailsDiv' class='details_info' style='display:none;z-index:5;'></div>\n";
$HTML_header.="<div id='HelpDisplayDiv' class='help_info' style='display:none;z-index:99;'></div>";
$HTML_header.="\n\n<!--\n$calls_stmt\n-->\n\n";
$HTML_header.="<form action='$PHP_SELF' method='POST'>\n";
echo $HTML_header;
@@ -171,13 +169,13 @@ echo "<input type='hidden' name='DB' id='DB' value='$DB'>\n";
echo "<input type='hidden' name='report_types_to_display' id='report_types_to_display' value='$report_types_to_display'>\n";
?>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.1/chart.js" integrity="sha512-9fQaGKKJO2zXOYXpPTEEyzIdx7r3ou0nZgvxS9VICh70AGvdangg7lUVonofpBYrNWd6h2e/FQHoWSCRZkwOUQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="chart.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<table id="nav_table">
<?php
echo "<tr>\n";
echo "<td align='left' valign='top' class='title_cell'><A HREF='VERM_admin.php'><IMG SRC='$selected_logo' BORDER=0 ALT='System logo'></A> &nbsp; </td>\n";
echo "<td align='right' valign='middle' class='title_cell'><B>$PHP_AUTH_USER</B> | $PHP_AUTH_USER_fullname<BR><BR>";
echo "<a class='header_link' href='javascript:window.location.reload()'>RELOAD &#8635;</a> | <a class='header_link' href='javascript:if(window.print)window.print()'>PRINT <img src='./images/print_icon.png' width='15' height='15'></a> | <a class='header_link' href='VERM_admin.php?start_date=$start_date&end_date=$end_date'>NEW REPORT</a> | <a class='header_link' href='/".$SSadmin_web_directory."/admin.php?force_logout=1'>LOG OUT</a>";
echo "<a class='header_link' href='javascript:window.location.reload()'>"._QXZ("RELOAD")." &#8635;</a> | <a class='header_link' href='javascript:if(window.print)window.print()'>"._QXZ("PRINT")." <img src='./images/print_icon.png' width='15' height='15'></a> | <a class='header_link' href='VERM_admin.php?start_date=$start_date&end_date=$end_date'>"._QXZ("NEW REPORT"). "</a> | <a class='header_link' href='/".$SSadmin_web_directory."/admin.php?force_logout=1'>"._QXZ("LOG OUT")."</a>";
echo "</td>\n";
echo "</tr>\n";
?>
@@ -188,12 +186,12 @@ if ($report_types_to_display=="Quick agents report") {
<tr>
<td colspan='2' class='nav_header' align='left'>
<ul class='navigation_list'>
<li style="display:inline"><input type='button' class='transparent_button' value='HOME' onClick="document.location.href='VERM_admin.php'"></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="ANSWERED" ? " current_report" : ""); ?>' value='ANSWERED' id='ANSWERED' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="ANSWERED_DT" ? " current_report" : ""); ?>' value='ANS.DT.' id='ANSWERED_DT' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="AGENTS" ? " current_report" : ""); ?>' value='AGENTS' id='AGENTS' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="AGENTS_DT" ? " current_report" : ""); ?>' value='AG.DT.' id='AGENTS_DT' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="OUTCOMES" ? " current_report" : ""); ?>' value='OUTCOMES' id='OUTCOMES' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button' value='<?php echo _QXZ("HOME"); ?>' onClick="document.location.href='VERM_admin.php'"></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="ANSWERED" ? " current_report" : ""); ?>' value='<?php echo _QXZ("ANSWERED"); ?>' id='ANSWERED' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="ANSWERED_DT" ? " current_report" : ""); ?>' value='<?php echo _QXZ("ANS.DT."); ?>' id='ANSWERED_DT' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="AGENTS" ? " current_report" : ""); ?>' value='<?php echo _QXZ("AGENTS"); ?>' id='AGENTS' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="AGENTS_DT" ? " current_report" : ""); ?>' value='<?php echo _QXZ("AG.DT."); ?>' id='AGENTS_DT' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="OUTCOMES" ? " current_report" : ""); ?>' value='<?php echo _QXZ("OUTCOMES"); ?>' id='OUTCOMES' onClick='GoToReport(this.id)'></li>
</ul>
</td>
</tr>
@@ -205,9 +203,9 @@ if ($report_types_to_display=="Quick agents report") {
<tr>
<td colspan='2' class='nav_header' align='left'>
<ul class='navigation_list'>
<li style="display:inline"><input type='button' class='transparent_button' value='HOME' onClick="document.location.href='VERM_admin.php'"></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="STATS" ? " current_report" : ""); ?>' value='STATS' id='STATS' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="CALLS" ? " current_report" : ""); ?>' value='CALLS' id='CALLS' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button' value='<?php echo _QXZ("HOME"); ?>' onClick="document.location.href='VERM_admin.php'"></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="STATS" ? " current_report" : ""); ?>' value='<?php echo _QXZ("STATS"); ?>' id='STATS' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="CALLS" ? " current_report" : ""); ?>' value='<?php echo _QXZ("CALLS"); ?>' id='CALLS' onClick='GoToReport(this.id)'></li>
</ul>
</td>
</tr>
@@ -217,20 +215,20 @@ if ($report_types_to_display=="Quick agents report") {
<tr>
<td colspan='2' class='nav_header' align='left'>
<ul class='navigation_list'>
<li style="display:inline"><input type='button' class='transparent_button' value='HOME' onClick="document.location.href='VERM_admin.php'"></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="ANSWERED" ? " current_report" : ""); ?>' value='ANSWERED' id='ANSWERED' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="ANSWERED_DT" ? " current_report" : ""); ?>' value='ANS.DT.' id='ANSWERED_DT' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="UNANSWERED" ? " current_report" : ""); ?>' value='UNANS.' id='UNANSWERED' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="UNANSWERED_DT" ? " current_report" : ""); ?>' value='UNANS.DT.' id='UNANSWERED_DT' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="IVR" ? " current_report" : ""); ?>' value='IVR' id='IVR' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="AREA" ? " current_report" : ""); ?>' value='AREA' id='AREA' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="ATT" ? " current_report" : ""); ?>' value='ATT.' id='ATT' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="DAY" ? " current_report" : ""); ?>' value='DAY' id='DAY' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="HOUR" ? " current_report" : ""); ?>' value='HR.' id='HOUR' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="DOW" ? " current_report" : ""); ?>' value='DOW' id='DOW' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="AGENTS" ? " current_report" : ""); ?>' value='AGENTS' id='AGENTS' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="AGENTS_DT" ? " current_report" : ""); ?>' value='AG.DT.' id='AGENTS_DT' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="OUTCOMES" ? " current_report" : ""); ?>' value='OUTCOMES' id='OUTCOMES' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button' value='<?php echo _QXZ("HOME"); ?>' onClick="document.location.href='VERM_admin.php'"></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="ANSWERED" ? " current_report" : ""); ?>' value='<?php echo _QXZ("ANSWERED"); ?>' id='ANSWERED' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="ANSWERED_DT" ? " current_report" : ""); ?>' value='<?php echo _QXZ("ANS.DT."); ?>' id='ANSWERED_DT' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="UNANSWERED" ? " current_report" : ""); ?>' value='<?php echo _QXZ("UNANS."); ?>' id='UNANSWERED' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="UNANSWERED_DT" ? " current_report" : ""); ?>' value='<?php echo _QXZ("UNANS.DT."); ?>' id='UNANSWERED_DT' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="IVR" ? " current_report" : ""); ?>' value='<?php echo _QXZ("IVR"); ?>' id='IVR' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="AREA" ? " current_report" : ""); ?>' value='<?php echo _QXZ("AREA"); ?>' id='AREA' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="ATT" ? " current_report" : ""); ?>' value='<?php echo _QXZ("ATT."); ?>' id='ATT' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="DAY" ? " current_report" : ""); ?>' value='<?php echo _QXZ("DAY"); ?>' id='DAY' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="HOUR" ? " current_report" : ""); ?>' value='<?php echo _QXZ("HR."); ?>' id='HOUR' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="DOW" ? " current_report" : ""); ?>' value='<?php echo _QXZ("DOW"); ?>' id='DOW' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="AGENTS" ? " current_report" : ""); ?>' value='<?php echo _QXZ("AGENTS"); ?>' id='AGENTS' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="AGENTS_DT" ? " current_report" : ""); ?>' value='<?php echo _QXZ("AG.DT."); ?>' id='AGENTS_DT' onClick='GoToReport(this.id)'></li>
<li style="display:inline"><input type='button' class='transparent_button<?php echo ($report_type=="OUTCOMES" ? " current_report" : ""); ?>' value='<?php echo _QXZ("OUTCOMES"); ?>' id='OUTCOMES' onClick='GoToReport(this.id)'></li>
</ul>
</td>
</tr>
@@ -242,7 +240,7 @@ if ($report_types_to_display=="Quick agents report") {
<table id="rpt_table">
<tr>
<th style="width:25vw">Report Details:</th>
<th style="width:25vw"><?php echo _QXZ("Report Details"); ?>:</th>
<td style="width:75vw"></td>
</tr>
<?php
@@ -250,14 +248,14 @@ if ($report_full_names_array["$report_type"])
{
?>
<tr>
<td style="width:25vw" class='bold_cell'>Currently viewing:</th>
<td style="width:25vw" class='bold_cell'><?php echo _QXZ("Currently viewing:"); ?></th>
<td style="width:75vw" class='bold_cell'><?php echo $report_full_names_array["$report_type"]; ?></td>
</tr>
<?php
}
?>
<tr>
<td style="width:25vw" class='bold_cell'>Report queue:</td>
<td style="width:25vw" class='bold_cell'><?php echo _QXZ("Report queue"); ?>:</td>
<td style="width:75vw" class='bold_cell'>
<?php
echo $vicidial_queue_groups;
@@ -265,11 +263,11 @@ if ($report_full_names_array["$report_type"])
</td>
</tr>
<tr>
<td style="width:25vw">Report generated on:</td>
<td style="width:25vw"><?php echo _QXZ("Report generated on"); ?>:</td>
<td style="width:75vw"><?php echo date("F j Y, G:i"); ?></td>
</tr>
<tr>
<td style="width:25vw">Campaigns/ingroups considered: <?php echo "$NWB#VERM_header-atomic_queues$NWE"; ?></td>
<td style="width:25vw"><?php echo _QXZ("Campaigns/ingroups considered"); ?>: <?php echo "$NWB#VERM_header-atomic_queues$NWE"; ?></td>
<td style="width:75vw" class='queue_cell'>
<?php
echo $atomic_queue_str;
@@ -277,19 +275,19 @@ if ($report_full_names_array["$report_type"])
</td>
</tr>
<tr>
<td style="width:25vw">Period start date: <?php echo "$NWB#VERM_header-period_start_date$NWE"; ?></td>
<td style="width:25vw"><?php echo _QXZ("Period start date"); ?>: <?php echo "$NWB#VERM_header-period_start_date$NWE"; ?></td>
<td style="width:75vw"><?php echo date('F j Y, H:i', strtotime("$start_date $start_time")); ?></td>
</tr>
<tr>
<td style="width:25vw">Period end date: <?php echo "$NWB#VERM_header-period_end_date$NWE"; ?></td>
<td style="width:25vw"><?php echo _QXZ("Period end date"); ?>: <?php echo "$NWB#VERM_header-period_end_date$NWE"; ?></td>
<td style="width:75vw"><?php echo date('F j Y, H:i', strtotime("$end_date $end_time")); ?></td>
</tr>
<tr>
<td style="width:25vw">Total calls processed: <?php echo "$NWB#VERM_header-total_calls_processed$NWE"; ?></td>
<td style="width:25vw"><?php echo _QXZ("Total calls processed"); ?>: <?php echo "$NWB#VERM_header-total_calls_processed$NWE"; ?></td>
<td style="width:75vw"><?php echo $total_calls." (".$total_answered_calls." ans / ".$total_unanswered_calls." unans)"; ?></td>
</tr>
<tr>
<td style="width:25vw">Ratio: <?php echo "$NWB#VERM_header-ratio$NWE"; ?></td>
<td style="width:25vw"><?php echo _QXZ("Ratio"); ?>: <?php echo "$NWB#VERM_header-ratio$NWE"; ?></td>
<td style="width:75vw"><?php
$answered_percentage=sprintf("%.1f", MathZDC((100*$total_answered_calls), $total_calls));
$unanswered_percentage=sprintf("%.1f", MathZDC((100*$total_unanswered_calls), $total_calls));
@@ -298,11 +296,11 @@ if ($report_full_names_array["$report_type"])
</tr>
<tr>
<td style="width:25vw">&nbsp;</td>
<td style="width:75vw"><input type="button" class="actButton" value="Search" alt="DIRECTS BACK TO CUSTOM REPORT INTERFACE" onclick="javascript:document.location.href='VERM_custom_report.php'"> <?php echo "$NWB#VERM_header-buttons$NWE"; ?></td>
<td style="width:75vw"><input type="button" class="actButton" value="<?php echo _QXZ("Search"); ?>" alt="DIRECTS BACK TO CUSTOM REPORT INTERFACE" onclick="javascript:document.location.href='VERM_custom_report.php'"> <?php echo "$NWB#VERM_header-buttons$NWE"; ?></td>
</tr>
<tr>
<td style="width:25vw">&nbsp;</td>
<td style="width:75vw"><input type="button" class="actButton" value="Link" alt="GIVES LINK DIRECTLY TO PAGE" onclick="GenerateLink(event);">
<td style="width:75vw"><input type="button" class="actButton" value="<?php echo _QXZ("Link"); ?>" alt="GIVES LINK DIRECTLY TO PAGE" onclick="GenerateLink(event);">
<input type="button" class="actButton" value="CSV" onClick="DownloadReport('<?php echo $report_type; ?>', 'header')">
</td>
</tr>
@@ -310,6 +308,7 @@ if ($report_full_names_array["$report_type"])
<td colspan='2' class='export_row_cell' valign='top'><div class="chart-container" style="height:25vw; width:40vh"><canvas id='answered_unanswered_display' role="img"> </canvas></div>
<!--
<?php
/*
echo "<BR><BR>Vicidial log SQL: $vicidial_log_SQL<BR><B>$and_vicidial_log_SQL</b><BR>\n";
echo "<BR>Vicidial CLOSER log SQL: $vicidial_closer_log_SQL\n";
echo "<BR>Vicidial DID log SQL: $vicidial_did_log_SQL\n";
@@ -331,6 +330,7 @@ if ($report_full_names_array["$report_type"])
# echo "Asterisk CID: $and_caller_code_sql<BR>\n";
print_r($extended_log_uniqueid_array);
echo "Day of week: $and_call_date_DOWsql<BR>\n";
*/
?>
//-->
</td>
File diff suppressed because it is too large Load Diff
@@ -5,6 +5,8 @@
#
# CHANGELOG:
# 220828-1402 - First build
# 230106-1332 - Added auto download variables, permissions, report logging
# 230116-1640 - Ingroup-related clauses no longer allow blank campaign_id values (double-dipping issue)
#
# NANQUE, not an unanswered call?
@@ -122,7 +124,7 @@ if (isset($_GET["time_of_day_end"])) {$time_of_day_end=$_GET["time_of_day_end"
#############################################
##### START SYSTEM_SETTINGS LOOKUP #####
$stmt = "SELECT use_non_latin,outbound_autodial_active,slave_db_server,reports_use_slave_db,enable_languages,language_method,agent_whisper_enabled,report_default_format,enable_pause_code_limits,allow_web_debug,admin_screen_colors,admin_web_directory FROM system_settings;";
$stmt = "SELECT use_non_latin,outbound_autodial_active,slave_db_server,reports_use_slave_db,enable_languages,language_method,agent_whisper_enabled,report_default_format,enable_pause_code_limits,allow_web_debug,admin_screen_colors,admin_web_directory,log_recording_access FROM system_settings;";
$rslt=mysql_to_mysqli($stmt, $link);
if ($DB) {echo "$stmt\n";}
$qm_conf_ct = mysqli_num_rows($rslt);
@@ -141,6 +143,7 @@ if ($qm_conf_ct > 0)
$SSallow_web_debug = $row[9];
$SSadmin_screen_colors = $row[10];
$SSadmin_web_directory = $row[11];
$log_recording_access = $row[12];
}
if ($SSallow_web_debug < 1) {$DB=0;}
##### END SETTINGS LOOKUP #####
@@ -603,7 +606,8 @@ while($ingroups_id_row=mysqli_fetch_array($ingroups_id_rslt))
$atomic_queue_str.=" <i>[".$ingroups_id_row["group_id"]."]</i>,";
$atomic_queue_ingroups_str.="$ingroups_id_row[group_id]', '";
}
$and_atomic_queue_ingroups_clause="and campaign_id in ('".$atomic_queue_ingroups_str."')";
#### IMPORTANT - 1/26/23 - added "and campaign_id!=''" - may need to add to and_atomic_queue_campaigns_clause as well.
$and_atomic_queue_ingroups_clause="and campaign_id in ('".$atomic_queue_ingroups_str."') and campaign_id!=''";
$atomic_queue_str=preg_replace('/,$/', '', $atomic_queue_str);
if (strlen($atomic_queue_str)==0)
@@ -1087,17 +1091,17 @@ else
if ($time_of_day_end)
{
$and_call_date_TODEsql=" and time(call_date)<='$time_of_day_end' ";
$where_call_date_TODEsql=" where time(call_date)<='$time_of_day_end' ";
# Agent log
$and_event_time_TODEsql=" and time(event_time)<='$time_of_day_end' ";
$where_event_time_TODEsql=" where time(event_time)<='$time_of_day_end' ";
# Live inbound log
$and_start_time_TODEsql=" and time(start_time)<='$time_of_day_end' ";
$where_start_time_TODEsql=" where time(start_time)<='$time_of_day_end' ";
# Park log
$and_parked_time_TODEsql=" and time(parked_time)<='$time_of_day_end' ";
$where_parked_time_TODEsql=" where time(parked_time)<='$time_of_day_end' ";
$and_call_date_TODEsql=" and time(call_date)<='$time_of_day_end' ";
$where_call_date_TODEsql=" where time(call_date)<='$time_of_day_end' ";
# Agent log
$and_event_time_TODEsql=" and time(event_time)<='$time_of_day_end' ";
$where_event_time_TODEsql=" where time(event_time)<='$time_of_day_end' ";
# Live inbound log
$and_start_time_TODEsql=" and time(start_time)<='$time_of_day_end' ";
$where_start_time_TODEsql=" where time(start_time)<='$time_of_day_end' ";
# Park log
$and_parked_time_TODEsql=" and time(parked_time)<='$time_of_day_end' ";
$where_parked_time_TODEsql=" where time(parked_time)<='$time_of_day_end' ";
$vicidial_log_SQL.=$and_call_date_TODEsql;
@@ -1245,13 +1249,26 @@ if (!$total_calls || !$total_unanswered_calls || !$total_answered_calls)
$unanswered_percentage=sprintf("%.1f", MathZDC((100*$total_unanswered_calls), $total_calls));
}
$CSV_output["header"]="\"Report Details:\"\n";
$CSV_output["header"].="\"Report generated on:\",\"".date("F j Y, G:i")."\"\n";
$CSV_output["header"].="\"Atomic queue(s) considered:\",\"".strip_tags($atomic_queue_str)."\"\n";
$CSV_output["header"].="\"Period start date:\",\"".date('F j Y, H:i', strtotime("$start_date $start_time"))."\"\n";
$CSV_output["header"].="\"Period end date:\",\"".date('F j Y, H:i', strtotime("$end_date $end_time"))."\"\n";
$CSV_output["header"].="\"Total calls processed:\",\"".$total_calls." (".$total_answered_calls." ans / ".$total_unanswered_calls." unans)"."\"\n";
$CSV_output["header"].="\"Ratio:\",\"".$answered_percentage."% ans / ".$unanswered_percentage."% unans"."\"\n";
$CSV_output["header"]="\""._QXZ("Report Details").":\"\n";
$CSV_output["header"].="\""._QXZ("Report generated on").":\",\"".date("F j Y, G:i")."\"\n";
$CSV_output["header"].="\""._QXZ("Atomic queue(s) considered").":\",\"".strip_tags($atomic_queue_str)."\"\n";
$CSV_output["header"].="\""._QXZ("Period start date").":\",\"".date('F j Y, H:i', strtotime("$start_date $start_time"))."\"\n";
$CSV_output["header"].="\""._QXZ("Period end date").":\",\"".date('F j Y, H:i', strtotime("$end_date $end_time"))."\"\n";
$CSV_output["header"].="\""._QXZ("Total calls processed").":\",\"".$total_calls." (".$total_answered_calls." ans / ".$total_unanswered_calls." unans)"."\"\n";
$CSV_output["header"].="\""._QXZ("Ratio").":\",\"".$answered_percentage."% ans / ".$unanswered_percentage."% unans"."\"\n";
$report_log_count=0;
if (!$auto_download_limit) {$auto_download_limit=99999999999;}
if ($total_calls>$auto_download_limit) {$agents_dt_download_notice=1;}
if ($total_answered_calls>$auto_download_limit) {$answered_dt_download_notice=1;}
if ($total_unanswered_calls>$auto_download_limit) {$unanswered_dt_download_notice=1;}
if ( ($total_calls>$auto_download_limit && $report_type=="AGENTS_DT") || ($total_answered_calls>$auto_download_limit && $report_type=="ANSWERED_DT") || ($total_unanswered_calls>$auto_download_limit && $report_type=="UNANSWERED_DT") )
{
$download_rpt="auto_download";
}
if (!$download_rpt)
{
+44
View File
@@ -5,6 +5,7 @@
#
# CHANGELOG:
# 220825-1604 - First build
# 230106-1355 - Added auto-download limit and special status settings for outcomes report
#
/*
@@ -42,8 +43,13 @@ print "\n\n\n";
*/
$exc_addtl_statuses="";
$auto_download_limit=99999999999;
$lost_statuses_array=array();
$known_outcome_statuses=array();
$unknown_network_statuses=array();
$outcome_status_overrides=array();
$outcome_lagged_status_overrides=array();
$lost_statuses="";
$exc_lost_statuses="";
@@ -139,6 +145,44 @@ if (mysqli_num_rows($options_rslt)>0)
}
}
if ($setting_name=="outcome_lagged_status_overrides" && $setting_value)
{
$outcome_lagged_status_overrides=explode(",", $setting_value);
}
if ($setting_name=="unknown_network_statuses" && $setting_value)
{
$unknown_network_statuses=explode(",", $setting_value);
}
/*
if ($setting_name=="outcome_lagged_status_overrides" && $setting_value)
{
$setting_value_ary=explode("|", $setting_value);
for ($i=0; $i<count($setting_value_ary); $i++)
{
$olso_ary=explode(",", $setting_value_ary[$i]);
if (strlen($olso_ary[0])>0 && strlen($olso_ary[1])>0)
{
$outcome_lagged_status_overrides["$olso_ary[0]"]=explode("-", $olso_ary[1]);
}
}
}
*/
if ($setting_name=="outcome_status_overrides" && $setting_value)
{
$setting_value_ary=explode("|", $setting_value);
for ($i=0; $i<count($setting_value_ary); $i++)
{
$oso_ary=explode(",", $setting_value_ary[$i]);
if (strlen($oso_ary[0])>0 && strlen($oso_ary[1])>0)
{
$outcome_status_overrides["$oso_ary[0]"]=$oso_ary[1];
}
}
}
if ($setting_name=="SLA_LEVEL_PCT_ingroups" && $setting_value)
{
$sla_percents=explode(",", $setting_value);
+4 -3
View File
@@ -7,13 +7,14 @@
#
# CHANGELOG:
# 220825-1603 - First build
# 230123-1825 - Changed require statements to local files
#
require("../vicidial/dbconnect_mysqli.php");
require("../vicidial/functions.php");
require("dbconnect_mysqli.php");
require("functions.php");
header("Content-type: text/css");
require("../vicidial/screen_colors.php");
require("screen_colors.php");
?>
div.help_info {position:absolute; top:0; left:0; display:none;}
@@ -7,13 +7,14 @@
#
# CHANGELOG:
# 220825-1602 - First build
# 230123-1830 - Changed require statements to use local files, not relative
#
require("../vicidial/dbconnect_mysqli.php");
require("../vicidial/functions.php");
require("dbconnect_mysqli.php");
require("functions.php");
header("Content-type: text/css");
require("../vicidial/screen_colors.php");
require("screen_colors.php");
?>
/*
@@ -9,8 +9,8 @@
$startMS = microtime();
#$version = '2.14-1';
#$build = '220825-1601';
#$version = '2.14-873';
#$build = '230127-1750';
header ("Content-type: text/html; charset=utf-8");
@@ -564,7 +564,7 @@ if ($widget_type=="LIVE_QUEUE_INFO")
}
if ($widget_type=="LOGO")
{
{
$logo_stmt="select web_logo from vicidial_screen_colors, system_settings where colors_id=admin_screen_colors;";
$logo_rslt=mysql_to_mysqli($logo_stmt, $link);
if (mysqli_num_rows($logo_rslt)>0)
+2 -2
View File
@@ -9,8 +9,8 @@
$startMS = microtime();
#$version = '2.14-1';
#$build = '220825-1600';
#$version = '2.14-873';
#$build = '230127-1750';
header ("Content-type: text/html; charset=utf-8");
File diff suppressed because it is too large Load Diff
@@ -5,6 +5,7 @@
#
# CHANGELOG:
# 220825-1611 - First build
# 230126-1158 - Added recording log access, QXZ translation
#
$PHP_AUTH_USER=$_SERVER['PHP_AUTH_USER'];
@@ -25,7 +26,7 @@ if (isset($_GET["detail_span_height"])) {$detail_span_height=$_GET["detail_spa
#############################################
##### START SYSTEM_SETTINGS LOOKUP #####
$stmt = "SELECT use_non_latin,outbound_autodial_active,slave_db_server,reports_use_slave_db,enable_languages,language_method,agent_whisper_enabled,report_default_format,enable_pause_code_limits,allow_web_debug,admin_screen_colors,admin_web_directory FROM system_settings;";
$stmt = "SELECT use_non_latin,outbound_autodial_active,slave_db_server,reports_use_slave_db,enable_languages,language_method,agent_whisper_enabled,report_default_format,enable_pause_code_limits,allow_web_debug,admin_screen_colors,admin_web_directory,log_recording_access FROM system_settings;";
$rslt=mysql_to_mysqli($stmt, $link);
if ($DB) {echo "$stmt\n";}
$qm_conf_ct = mysqli_num_rows($rslt);
@@ -44,6 +45,7 @@ if ($qm_conf_ct > 0)
$SSallow_web_debug = $row[9];
$SSadmin_screen_colors = $row[10];
$SSadmin_web_directory = $row[11];
$log_recording_access = $row[12];
}
if ($SSallow_web_debug < 1) {$DB=0;}
##### END SETTINGS LOOKUP #####
@@ -78,12 +80,12 @@ $closecallid=$lookup_data[1];
### Lookup of call details for display
if (!$closecallid)
{
$stmt="select date_format(call_date, '%m/%d - %H:%i:%s') as call_date, phone_number, campaign_id, 0 as ivr, '0' as wait, length_in_sec as duration, '1' as queue_position, CAST(term_reason AS CHAR) as term_reason, user, '1' as attempts, status, uniqueid, 0 as moh_events, '00:00:00' as moh_duration, '' as ivr_duration, '' as ivr_path, '' as dnis, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, 0 as xfercallid, 'O' as direction from vicidial_log where uniqueid='$uniqueid'";
$stmt="select date_format(call_date, '%m/%d - %H:%i:%s') as call_date, phone_number, campaign_id, 0 as ivr, '0' as wait, length_in_sec as duration, '1' as queue_position, CAST(term_reason AS CHAR) as term_reason, user, '1' as attempts, status, uniqueid, 0 as moh_events, '00:00:00' as moh_duration, '' as ivr_duration, '' as ivr_path, '' as dnis, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, 0 as xfercallid, 'O' as direction, lead_id from vicidial_log where uniqueid='$uniqueid'";
$vicidial_id=$uniqueid;
}
else
{
$stmt="select date_format(call_date, '%m/%d - %H:%i:%s') as call_date, phone_number, campaign_id, 0 as ivr, queue_seconds as wait, length_in_sec-queue_seconds as duration, queue_position, CAST(term_reason AS CHAR) as term_reason, user, '1' as attempts, status, uniqueid, 0 as moh_events, '00:00:00' as moh_duration, '' as ivr_duration, '' as ivr_path, '' as dnis, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, xfercallid, 'I' as direction from vicidial_closer_log where uniqueid='$uniqueid' and closecallid='$closecallid'";
$stmt="select date_format(call_date, '%m/%d - %H:%i:%s') as call_date, phone_number, campaign_id, 0 as ivr, queue_seconds as wait, length_in_sec-queue_seconds as duration, queue_position, CAST(term_reason AS CHAR) as term_reason, user, '1' as attempts, status, uniqueid, 0 as moh_events, '00:00:00' as moh_duration, '' as ivr_duration, '' as ivr_path, '' as dnis, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, xfercallid, 'I' as direction, lead_id from vicidial_closer_log where uniqueid='$uniqueid' and closecallid='$closecallid'";
$vicidial_id=$closecallid;
}
@@ -104,7 +106,12 @@ if ($row["xfercallid"]==0 || $call_type=="ivr") # Possible origin call, need to
}
$dnis=GetDNIS($uniqueid);
$recording_array=GetRecording($vicidial_id);
$recording_link="<a href='$recording_array[1]'>$recording_array[0]</a>";
if ($log_recording_access<1)
{$recording_link="<a href='$recording_array[1]'>$recording_array[0]</a>";}
else
{$recording_link = "<a href=\"recording_log_redirect.php?recording_id=$recording_array[2]&lead_id=$row[lead_id]&search_archived_data=$search_archived_data\" target=\"_blank\">$recording_array[0]</a>";}
# $xfer_array=GetTransferInfo($uniqueid);
echo "<table border=0 width='100%' bgcolor='#FFF'><tr>";
@@ -125,7 +132,7 @@ echo "</td>";
echo "</tr>";
#echo "<tr><td colspan='2'>";
#echo "<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'></td></tr>";
echo "<tr><td colspan='2'><input type='button' class='actButton' value='Call details' onClick=\"ToggleVisibility('all_call_details', 'block'); ToggleVisibility('all_ivr_details', 'none');\"> $NWB#VERM_display_call_details$NWE&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<input type='button' class='actButton' value='IVR events: $ivr_events' onClick=\"ToggleVisibility('all_call_details', 'none'); ToggleVisibility('all_ivr_details', 'block');\"> $NWB#VERM_display_call_details-IVR$NWE</td></tr>";
echo "<tr><td colspan='2'><input type='button' class='actButton' value='"._QXZ("Call details")."' onClick=\"ToggleVisibility('all_call_details', 'block'); ToggleVisibility('all_ivr_details', 'none');\"> $NWB#VERM_display_call_details$NWE&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<input type='button' class='actButton' value='IVR events: $ivr_events' onClick=\"ToggleVisibility('all_call_details', 'none'); ToggleVisibility('all_ivr_details', 'block');\"> $NWB#VERM_display_call_details-IVR$NWE</td></tr>";
echo "<tr><td colspan='2'>";
@@ -233,11 +240,11 @@ function GetRecording($vicidial_id)
$rec_str="";
$rec_stmt="select filename, location from recording_log where vicidial_id='$vicidial_id'";
$rec_stmt="select filename, location, recording_id from recording_log where vicidial_id='$vicidial_id'";
$rec_rslt=mysqli_query($link, $rec_stmt);
$rec_row=mysqli_fetch_array($rec_rslt);
return array("$rec_row[filename]", "$rec_row[location]");
return array("$rec_row[filename]", "$rec_row[location]", "$rec_row[recording_id]");
}
?>
?>
+2 -2
View File
@@ -18,8 +18,8 @@ $help_file_time=0;
if ( file_exists($help_file) )
{$help_file_time = filemtime($help_file);}
require("../vicidial/dbconnect_mysqli.php");
require("../vicidial/functions.php");
require("dbconnect_mysqli.php");
require("functions.php");
$PHP_AUTH_USER=$_SERVER['PHP_AUTH_USER'];
$PHP_AUTH_PW=$_SERVER['PHP_AUTH_PW'];
@@ -587,7 +587,7 @@ foreach ($output_array as $data_row)
{
if ($value && $value!="")
{
$HTML_output.="<td><a onClick=\"ShowCallDetails('$value', 'answered', '80', '70')\"><svg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
$HTML_output.="<td><a onClick=\"ShowCallDetails('$value', 'answered', '80', '70')\"><svg width='20' height='20' viewBox='0 0 20 20' data-svg='search'><circle fill='none' stroke='#000' stroke-width='1.1' cx='9' cy='9' r='7'></circle><path fill='none' stroke='#000' stroke-width='1.1' d='M14,14 L18,18 L14,14 Z'></path></svg></a></td>";
}
else
{
@@ -1,5 +1,5 @@
# version: 20220827175401
VERM_admin-queue Queue <QXZ>A queue is a collection of campaigns and ingroups to report on - these are created and modified through the admin Queue Groups section if the user has the privileges to use them.</QXZ>
# version: 20230227095801
VERM_admin-queue Queue <QXZ>A queue is a collection of campaigns and ingroups to report on - these are created and modified through the admin section if the user has the privileges to use them.</QXZ>
VERM_admin-report Report <QXZ>Enhanced report can run one of three report types - "All reports" will show all report sections enhanced reporting offers, "Quick agents reports" limits it to 5 report sections all relating to agent activity: ANSWERED, ANSWERED DETAILS, AGENTS, AGENT DETAILS, and OUTCOMES. "Quick reports" generates two report sections, STATS and CALLS, that combine together specific sub-reports found under other report sections.</QXZ>
VERM_admin-agent Agent Report <QXZ>You can run the "All reports" report type for a specific agent under the selected/default queue via selecting said agent from this dropdown, and then selecting a date interval underneath the dropdown.</QXZ>
VERM_admin-qa Quality Assessment <QXZ>This is simply another link to the main wallboard.</QXZ>
File diff suppressed because one or more lines are too long
@@ -0,0 +1,196 @@
<?php
# recording_log_redirect.php - audio recording access logging and redirect script
#
# Copyright (C) 2022 Joe Johnson, Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
# CHANGELOG
# 160116-1349 - First Build
# 170409-1538 - Added IP List validation code
# 210401-1625 - Added no_redirect for logging when playing a Javascript audio object
# 220227-0858 - Added allow_web_debug system setting
#
require("dbconnect_mysqli.php");
require("functions.php");
$PHP_AUTH_USER=$_SERVER['PHP_AUTH_USER'];
$PHP_AUTH_PW=$_SERVER['PHP_AUTH_PW'];
$PHP_SELF=$_SERVER['PHP_SELF'];
$PHP_SELF = preg_replace('/\.php.*/i','.php',$PHP_SELF);
$ip = getenv("REMOTE_ADDR");
if (isset($_GET["recording_id"])) {$recording_id=$_GET["recording_id"];}
elseif (isset($_POST["recording_id"])) {$recording_id=$_POST["recording_id"];}
if (isset($_GET["lead_id"])) {$lead_id=$_GET["lead_id"];}
elseif (isset($_POST["lead_id"])) {$lead_id=$_POST["lead_id"];}
if (isset($_GET["no_redirect"])) {$no_redirect=$_GET["no_redirect"];}
elseif (isset($_POST["no_redirect"])) {$no_redirect=$_POST["no_redirect"];}
if (isset($_GET["search_archived_data"])) {$search_archived_data=$_GET["search_archived_data"];}
elseif (isset($_POST["search_archived_data"])) {$search_archived_data=$_POST["search_archived_data"];}
if (isset($_GET["DB"])) {$DB=$_GET["DB"];}
elseif (isset($_POST["DB"])) {$DB=$_POST["DB"];}
$DB=preg_replace("/[^0-9a-zA-Z]/","",$DB);
#############################################
##### START SYSTEM_SETTINGS LOOKUP #####
$stmt = "SELECT use_non_latin,custom_fields_enabled,webroot_writable,allow_emails,enable_languages,language_method,active_modules,log_recording_access,allow_web_debug FROM system_settings;";
$rslt=mysql_to_mysqli($stmt, $link);
#if ($DB) {echo "$stmt\n";}
$qm_conf_ct = mysqli_num_rows($rslt);
if ($qm_conf_ct > 0)
{
$row=mysqli_fetch_row($rslt);
$non_latin = $row[0];
$custom_fields_enabled = $row[1];
$webroot_writable = $row[2];
$allow_emails = $row[3];
$SSenable_languages = $row[4];
$SSlanguage_method = $row[5];
$active_modules = $row[6];
$log_recording_access = $row[7];
$SSallow_web_debug = $row[8];
}
if ($SSallow_web_debug < 1) {$DB=0;}
##### END SETTINGS LOOKUP #####
###########################################
$recording_id = preg_replace('/[^0-9]/','',$recording_id);
$lead_id = preg_replace('/[^0-9]/','',$lead_id);
$no_redirect = preg_replace('/[^-_0-9a-zA-Z]/','',$no_redirect);
$search_archived_data = preg_replace("/\<|\>|\'|\"|\\\\|;/","",$search_archived_data);
if ($non_latin < 1)
{
$PHP_AUTH_USER = preg_replace('/[^-_0-9a-zA-Z]/','',$PHP_AUTH_USER);
$PHP_AUTH_PW = preg_replace('/[^-_0-9a-zA-Z]/','',$PHP_AUTH_PW);
}
else
{
$PHP_AUTH_USER = preg_replace('/[^-_0-9\p{L}]/u', '', $PHP_AUTH_USER);
$PHP_AUTH_PW = preg_replace('/[^-_0-9\p{L}]/u', '', $PHP_AUTH_PW);
}
if ($search_archived_data)
{$recording_log_table=use_archive_table("recording_log");}
else
{$recording_log_table="recording_log";}
$auth=0;
$auth_message = user_authorization($PHP_AUTH_USER,$PHP_AUTH_PW,'REPORTS',1,0);
if ($auth_message == 'GOOD')
{$auth=1;}
if ($auth < 1)
{
$VDdisplayMESSAGE = _QXZ("Login incorrect, please try again");
$log_stmt="insert into vicidial_recording_access_log(recording_id, lead_id, user, access_datetime, access_result, ip) VALUES('$recording_id', '$lead_id', '$PHP_AUTH_USER', now(), 'INVALID USER', '$ip');";
$log_rslt=mysql_to_mysqli($log_stmt, $link);
if ($auth_message == 'LOCK')
{
$VDdisplayMESSAGE = _QXZ("Too many login attempts, try again in 15 minutes");
Header ("Content-type: text/html; charset=utf-8");
echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n";
exit;
}
if ($auth_message == 'IPBLOCK')
{
$VDdisplayMESSAGE = _QXZ("Your IP Address is not allowed") . ": $ip";
Header ("Content-type: text/html; charset=utf-8");
echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n";
exit;
}
Header("WWW-Authenticate: Basic realm=\"CONTACT-CENTER-ADMIN\"");
Header("HTTP/1.0 401 Unauthorized");
echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$PHP_AUTH_PW|$auth_message|\n";
exit;
}
if ($non_latin > 0) {$rslt=mysql_to_mysqli("SET NAMES 'UTF8'", $link);}
$rights_stmt = "SELECT access_recordings,selected_language from vicidial_users where user='$PHP_AUTH_USER';";
if ($DB) {echo "|$stmt|\n";}
$rights_rslt=mysql_to_mysqli($rights_stmt, $link);
$rights_row=mysqli_fetch_row($rights_rslt);
$access_recordings = $rights_row[0];
$VUselected_language = $rights_row[1];
# check their permissions
if ( ( $access_recordings < 1 ) or ( $log_recording_access < 1 ) )
{
header ("Content-type: text/html; charset=utf-8");
echo _QXZ("You do not have permissions to access recordings")."\n";
$log_stmt="insert into vicidial_recording_access_log(recording_id, lead_id, user, access_datetime, access_result, ip) VALUES('$recording_id', '$lead_id', '$PHP_AUTH_USER', now(), 'INVALID PERMISSIONS', '$ip')";
$log_rslt=mysql_to_mysqli($log_stmt, $link);
exit;
}
if (!$recording_id)
{
exit;
}
else
{
$rec_lookup_stmt="select recording_id,channel,server_ip,extension,start_time,start_epoch,end_time,end_epoch,length_in_sec,length_in_min,filename,location,lead_id,user,vicidial_id from ".$recording_log_table." where recording_id='$recording_id'";
$rec_lookup_rslt=mysql_to_mysqli($rec_lookup_stmt, $link);
if (mysqli_num_rows($rec_lookup_rslt)==0)
{
$log_stmt="insert into vicidial_recording_access_log(recording_id, user, access_datetime, access_result, ip, lead_id) VALUES ('$recording_id', '$PHP_AUTH_USER', now(), 'NO RECORDING', '$ip', '$lead_id');";
$log_rslt=mysql_to_mysqli($log_stmt, $link);
echo _QXZ("Not a valid recording")."\n";
exit;
}
else
{
$rec_row=mysqli_fetch_array($rec_lookup_rslt);
$lead_id=$rec_row["lead_id"];
$location=$rec_row["location"];
if (strlen($location)>2)
{
$URLserver_ip = $location;
$URLserver_ip = preg_replace('/http:\/\//i', '',$URLserver_ip);
$URLserver_ip = preg_replace('/https:\/\//i', '',$URLserver_ip);
$URLserver_ip = preg_replace('/\/.*/i', '',$URLserver_ip);
$stmt="SELECT count(*) from servers where server_ip='$URLserver_ip';";
$rsltx=mysql_to_mysqli($stmt, $link);
$rowx=mysqli_fetch_row($rsltx);
if ($rowx[0] > 0)
{
$stmt="SELECT recording_web_link,alt_server_ip,external_server_ip from servers where server_ip='$URLserver_ip';";
$rsltx=mysql_to_mysqli($stmt, $link);
$rowx=mysqli_fetch_row($rsltx);
if (preg_match("/ALT_IP/i",$rowx[0]))
{
$location = preg_replace("/$URLserver_ip/i", "$rowx[1]", $location);
}
if (preg_match("/EXTERNAL_IP/i",$rowx[0]))
{
$location = preg_replace("/$URLserver_ip/i", "$rowx[2]", $location);
}
}
}
else
{
$log_stmt="insert into vicidial_recording_access_log(recording_id, lead_id, user, access_datetime, access_result, ip) VALUES ('$recording_id', '$lead_id', '$PHP_AUTH_USER', now(), 'RECORDING UNAVAILABLE', '$ip');";
$log_rslt=mysql_to_mysqli($log_stmt, $link);
echo _QXZ("Recording is not available yet. Try again later.")."\n";
exit;
}
}
}
$log_stmt="insert into vicidial_recording_access_log(recording_id, lead_id, user, access_datetime, access_result, ip) VALUES('$recording_id', '$lead_id', '$PHP_AUTH_USER', now(), 'ACCESSED', '$ip')";
$log_rslt=mysql_to_mysqli($log_stmt, $link);
if (!$no_redirect)
{
header("Location: $location");
}
else
{
echo "OK"; // DO NOT TRANSLATE THIS - IT'S A FLAG FOR JAVASCRIPT
exit;
}
?>
+56
View File
@@ -0,0 +1,56 @@
<?php
#
# screen_colors.php version 2.14
#
# include file to generate screen colors - normally in admin_header.php,
# but most reports include admin_header.php after the colors need to be set
#
# Copyright (C) 2020 Joseph Johnson <freewermadmin@gmail.com>, Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
#
# CHANGES:
# 170828-2345 - First Build
# 200814-2247 - Added button color
#
##### BEGIN Define colors and logo #####
$SSmenu_background='015B91';
$SSframe_background='D9E6FE';
$SSstd_row1_background='9BB9FB';
$SSstd_row2_background='B9CBFD';
$SSstd_row3_background='8EBCFD';
$SSstd_row4_background='B6D3FC';
$SSstd_row5_background='FFFFFF';
$SSalt_row1_background='BDFFBD';
$SSalt_row2_background='99FF99';
$SSalt_row3_background='CCFFCC';
$SSbutton_color='EFEFEF';
$screen_color_stmt="SELECT admin_screen_colors from system_settings";
$screen_color_rslt=mysql_to_mysqli($screen_color_stmt, $link);
$screen_color_row=mysqli_fetch_row($screen_color_rslt);
$agent_screen_colors="$screen_color_row[0]";
if ($agent_screen_colors != 'default')
{
$asc_stmt = "SELECT menu_background,frame_background,std_row1_background,std_row2_background,std_row3_background,std_row4_background,std_row5_background,alt_row1_background,alt_row2_background,alt_row3_background,web_logo,button_color FROM vicidial_screen_colors where colors_id='$agent_screen_colors';";
$asc_rslt=mysql_to_mysqli($asc_stmt, $link);
$qm_conf_ct = mysqli_num_rows($asc_rslt);
if ($qm_conf_ct > 0)
{
$asc_row=mysqli_fetch_row($asc_rslt);
$SSmenu_background = $asc_row[0];
$SSframe_background = $asc_row[1];
$SSstd_row1_background = $asc_row[2];
$SSstd_row2_background = $asc_row[3];
$SSstd_row3_background = $asc_row[4];
$SSstd_row4_background = $asc_row[5];
$SSstd_row5_background = $asc_row[6];
$SSalt_row1_background = $asc_row[7];
$SSalt_row2_background = $asc_row[8];
$SSalt_row3_background = $asc_row[9];
$SSweb_logo = $asc_row[10];
$SSbutton_color = $asc_row[11];
}
}
?>
+10 -2
View File
@@ -5969,12 +5969,13 @@ if ($SSscript_remove_js > 0)
# 221230-2231 - Added Postal Codes Cities display
# 230117-0838 - Added Agent Call Hangup Routing options, changed year to 2023
# 230204-1642 - Added No Agent Call URL "ALT" multi-url options
# 230227-1150 - Updated VERM code and notices
#
# make sure you have added a user to the vicidial_users MySQL table with at least user_level 9 to access this page the first time
$admin_version = '2.14-873a';
$build = '230204-1642';
$admin_version = '2.14-874a';
$build = '230227-1150';
$STARTtime = date("U");
$SQLdate = date("Y-m-d H:i:s");
@@ -49639,6 +49640,13 @@ if ($ADD==999995)
echo "<tr bgcolor=#$SSstd_row4_background><td align=right valign=top><B><font size=2>"._QXZ("License").": </B></td><td align=left><font size=1> &nbsp; "._QXZ("classAudioFile is licensed under the")." <a href=\"http://www.opensource.org/licenses/gpl-license.html\" target=\"_blank\">GPL "._QXZ("open source license")."</a></td></tr>\n";
echo "<tr bgcolor=#$SSstd_row4_background><td align=right valign=top nowrap><B><font size=2>"._QXZ("Source Code").": </B></td><td align=left><font size=1> &nbsp; "._QXZ("classAudioFile original source code is available at")." <a href=\"https://www.phpclasses.org/audiofile\" target=\"_blank\">"._QXZ("this link")."</a>.</td></tr>\n";
echo "<tr><td colspan=3> &nbsp; </tr>";
echo "<tr bgcolor=#$SSstd_row4_background><td align=right valign=middle rowspan=3 nowrap><B><font size=3>"._QXZ("Jquery").": </B></td>";
echo "<td align=right valign=top><B><font size=2>"._QXZ("Copyright").": </B></td><td align=left><font size=1> &nbsp; "._QXZ("The Jquery javascript library was written by OpenJS Foundation contributors").", &copy; 2023</td></tr>\n";
echo "<tr bgcolor=#$SSstd_row4_background><td align=right valign=top><B><font size=2>"._QXZ("License").": </B></td><td align=left><font size=1> &nbsp; "._QXZ("Jquery is licensed under the")." <a href=\"https://jquery.org/license/\" target=\"_blank\">MIT "._QXZ("open source license")."</a></td></tr>\n";
echo "<tr bgcolor=#$SSstd_row4_background><td align=right valign=top nowrap><B><font size=2>"._QXZ("Source Code").": </B></td><td align=left><font size=1> &nbsp; "._QXZ("Jquery original source code is available at")." <a href=\"https://jquery.com/download/\" target=\"_blank\">"._QXZ("this link")."</a>.</td></tr>\n";
echo "</TABLE></center>\n";
}
##### END copyright trademark license page #####