Added testing code for VERM(VICIdial Enhanced Reporting Module)
git-svn-id: svn://192.168.202.10@3627 3d104415-ff17-0410-8863-d5cf3c621b8a
@@ -4752,6 +4752,47 @@ UNIQUE KEY `serverconf` (`server_ip`,`conf_exten`),
|
|||||||
UNIQUE KEY `conf_exten` (`conf_exten`,`server_ip`)
|
UNIQUE KEY `conf_exten` (`conf_exten`,`server_ip`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
|
|
||||||
|
CREATE TABLE `verm_custom_report_holder` (
|
||||||
|
`custom_report_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`user` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`report_name` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`report_parameters` TEXT COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`modify_date` TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||||
|
PRIMARY KEY (`custom_report_id`),
|
||||||
|
UNIQUE KEY `verm_custom_report_holder_pkey` (`user`,`report_name`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
|
|
||||||
|
CREATE TABLE `wallboard_widgets` (
|
||||||
|
`widget_id` VARCHAR(100) COLLATE utf8_unicode_ci NOT NULL,
|
||||||
|
`wallboard_report_id` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`view_id` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_title` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_type` VARCHAR(30) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_width` TINYINT(3) UNSIGNED DEFAULT NULL,
|
||||||
|
`widget_is_row` ENUM('Y','N') COLLATE utf8_unicode_ci DEFAULT 'N',
|
||||||
|
`widget_rowspan` TINYINT(3) UNSIGNED DEFAULT 1,
|
||||||
|
`widget_text` TEXT COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_queue` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_sla_level` VARCHAR(5) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_agent` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_color` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_color2` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_alarms` TEXT COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_order` TINYINT(3) UNSIGNED DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`widget_id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
|
|
||||||
|
CREATE TABLE `wallboard_reports` (
|
||||||
|
`wallboard_report_id` VARCHAR(20) COLLATE utf8_unicode_ci NOT NULL,
|
||||||
|
`wallboard_name` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`wallboard_views` TINYINT(3) UNSIGNED DEFAULT NULL,
|
||||||
|
`date_created` DATETIME DEFAULT NULL,
|
||||||
|
`last_modified` TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||||
|
`data_refresh_rate` SMALLINT(5) UNSIGNED DEFAULT 10,
|
||||||
|
`view_refresh_rate` SMALLINT(5) UNSIGNED DEFAULT 30,
|
||||||
|
PRIMARY KEY (`wallboard_report_id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
|
|
||||||
|
|
||||||
ALTER TABLE vicidial_email_list MODIFY message text character set utf8;
|
ALTER TABLE vicidial_email_list MODIFY message text character set utf8;
|
||||||
|
|
||||||
@@ -5098,7 +5139,12 @@ 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 ('INTERNATIONAL_DNC_IMPORT','Process DNC lists of various countries from FTP site','PERL_CLI','---ALL---','# This setting container is used for the international DNC system. \r\n# The below two settings are mandatory for importing suppression lists\r\n# and tell the import process where to look for new files and where to\r\n# move them when handled. These settings cannot have the same value. \r\n--file-dir=/root/ftp\r\n--file-destination=/root/ftp/DONE\r\n\r\n# Uncomment below and set the status to whatever custom disposition you \r\n# would like already-loaded leads to be set to when they dedupe against\r\n# a country\'s DNC list (default is \"DNCI\")\r\n# --dnc-status-override=BMNR\r\n\r\n# The below settings are optional for when files are stored on a remote\r\n# server. It is strongly recommended these settings are not used and\r\n# that the processing scripts and files are stored locally on the same\r\n# server. \r\n# --ftp-host=localhost\r\n# --ftp-user=user\r\n# --ftp-pwd=pwd\r\n# --ftp-port=21\r\n# --ftp-passive=1\r\n'),('DNC_IMPORT_FORMATS','Import formats for DNC files','OTHER','---ALL---','# This setting container is used for storing file formats used when \r\n# loading DNC suppression lists into the dialer. \r\n#\r\n# import template => (delimited|fixed),delimiter,phone1(,phone2,phone3)\r\n#\r\n# For delimited files, the phone1 value should be the index value of\r\n# the field where the phone appears. The first array index is 0 and\r\n# indexes continue through the natural numbers.\r\n\r\n# In delimited files, acceptable values for the \"delimiter\" field are:\r\n# - \"tab\", \"pipe\", \"comma\", \"quote-comma\"\r\nBASIC_DELIMITED_FORMAT => delimited,pipe,0\r\n\r\n# If the phone number is split into multiple fields (ex: area code in\r\n# one field, rest of the number in another), simply list additional \r\n# indices of the phone number fields separated by commas in the order \r\n# in which the data should be combined to make the complete phone \r\n# number \r\nDELIMITED_WITH_AC_AND_EXCHANGE_SPLIT => delimited,tab,0,1\r\n\r\n# For fixed-length files, the phone field values should be of the type:\r\n# - \"starting_position|length\"\r\nBASIC_FIXED_FORMAT => fixed,,0|10\r\n\r\n# (delimited|fixed) is not used for CSV/Excel files, so all that needs \r\n# providing for those is the index field value(s) of the phone number\r\nBASIC_CSV_OR_EXCEL_FORMAT => ,,0'),('DNC_CURRENT_BLOCKED_LISTS','Lists currently blocked due to pending DNC scrub','READ_ONLY','---ALL---','');
|
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('INTERNATIONAL_DNC_IMPORT','Process DNC lists of various countries from FTP site','PERL_CLI','---ALL---','# This setting container is used for the international DNC system. \r\n# The below two settings are mandatory for importing suppression lists\r\n# and tell the import process where to look for new files and where to\r\n# move them when handled. These settings cannot have the same value. \r\n--file-dir=/root/ftp\r\n--file-destination=/root/ftp/DONE\r\n\r\n# Uncomment below and set the status to whatever custom disposition you \r\n# would like already-loaded leads to be set to when they dedupe against\r\n# a country\'s DNC list (default is \"DNCI\")\r\n# --dnc-status-override=BMNR\r\n\r\n# The below settings are optional for when files are stored on a remote\r\n# server. It is strongly recommended these settings are not used and\r\n# that the processing scripts and files are stored locally on the same\r\n# server. \r\n# --ftp-host=localhost\r\n# --ftp-user=user\r\n# --ftp-pwd=pwd\r\n# --ftp-port=21\r\n# --ftp-passive=1\r\n'),('DNC_IMPORT_FORMATS','Import formats for DNC files','OTHER','---ALL---','# This setting container is used for storing file formats used when \r\n# loading DNC suppression lists into the dialer. \r\n#\r\n# import template => (delimited|fixed),delimiter,phone1(,phone2,phone3)\r\n#\r\n# For delimited files, the phone1 value should be the index value of\r\n# the field where the phone appears. The first array index is 0 and\r\n# indexes continue through the natural numbers.\r\n\r\n# In delimited files, acceptable values for the \"delimiter\" field are:\r\n# - \"tab\", \"pipe\", \"comma\", \"quote-comma\"\r\nBASIC_DELIMITED_FORMAT => delimited,pipe,0\r\n\r\n# If the phone number is split into multiple fields (ex: area code in\r\n# one field, rest of the number in another), simply list additional \r\n# indices of the phone number fields separated by commas in the order \r\n# in which the data should be combined to make the complete phone \r\n# number \r\nDELIMITED_WITH_AC_AND_EXCHANGE_SPLIT => delimited,tab,0,1\r\n\r\n# For fixed-length files, the phone field values should be of the type:\r\n# - \"starting_position|length\"\r\nBASIC_FIXED_FORMAT => fixed,,0|10\r\n\r\n# (delimited|fixed) is not used for CSV/Excel files, so all that needs \r\n# providing for those is the index field value(s) of the phone number\r\nBASIC_CSV_OR_EXCEL_FORMAT => ,,0'),('DNC_CURRENT_BLOCKED_LISTS','Lists currently blocked due to pending DNC scrub','READ_ONLY','---ALL---','');
|
||||||
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_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 ('USER_CODES_SYSTEM','User Codes List','OTHER','---ALL---','');
|
||||||
|
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 `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);
|
||||||
|
|
||||||
|
INSERT INTO `wallboard_reports` VALUES ('AGENTS_AND_QUEUES','Agents and Queues',2,'2022-01-18 09:00:23','2022-01-18 15:00:23',10,30);
|
||||||
|
|
||||||
UPDATE system_settings set vdc_agent_api_active='1';
|
UPDATE system_settings set vdc_agent_api_active='1';
|
||||||
|
|
||||||
UPDATE system_settings SET db_schema_version='1664',db_schema_update_date=NOW(),reload_timestamp=NOW();
|
UPDATE system_settings SET db_schema_version='1665',db_schema_update_date=NOW(),reload_timestamp=NOW();
|
||||||
|
|||||||
@@ -1963,3 +1963,52 @@ UNIQUE KEY `conf_exten` (`conf_exten`,`server_ip`)
|
|||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
|
|
||||||
UPDATE system_settings SET db_schema_version='1664',db_schema_update_date=NOW() where db_schema_version < 1664;
|
UPDATE system_settings SET db_schema_version='1664',db_schema_update_date=NOW() where db_schema_version < 1664;
|
||||||
|
|
||||||
|
CREATE TABLE `verm_custom_report_holder` (
|
||||||
|
`custom_report_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`user` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`report_name` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`report_parameters` TEXT COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`modify_date` TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||||
|
PRIMARY KEY (`custom_report_id`),
|
||||||
|
UNIQUE KEY `verm_custom_report_holder_pkey` (`user`,`report_name`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
|
|
||||||
|
CREATE TABLE `wallboard_widgets` (
|
||||||
|
`widget_id` VARCHAR(100) COLLATE utf8_unicode_ci NOT NULL,
|
||||||
|
`wallboard_report_id` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`view_id` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_title` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_type` VARCHAR(30) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_width` TINYINT(3) UNSIGNED DEFAULT NULL,
|
||||||
|
`widget_is_row` ENUM('Y','N') COLLATE utf8_unicode_ci DEFAULT 'N',
|
||||||
|
`widget_rowspan` TINYINT(3) UNSIGNED DEFAULT 1,
|
||||||
|
`widget_text` TEXT COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_queue` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_sla_level` VARCHAR(5) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_agent` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_color` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_color2` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_alarms` TEXT COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`widget_order` TINYINT(3) UNSIGNED DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`widget_id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
|
|
||||||
|
CREATE TABLE `wallboard_reports` (
|
||||||
|
`wallboard_report_id` VARCHAR(20) COLLATE utf8_unicode_ci NOT NULL,
|
||||||
|
`wallboard_name` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`wallboard_views` TINYINT(3) UNSIGNED DEFAULT NULL,
|
||||||
|
`date_created` DATETIME DEFAULT NULL,
|
||||||
|
`last_modified` TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||||
|
`data_refresh_rate` SMALLINT(5) UNSIGNED DEFAULT 10,
|
||||||
|
`view_refresh_rate` SMALLINT(5) UNSIGNED DEFAULT 30,
|
||||||
|
PRIMARY KEY (`wallboard_report_id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
|
|
||||||
|
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,'','SALESLINE','','','','','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);
|
||||||
|
|
||||||
|
INSERT INTO `wallboard_reports` VALUES ('AGENTS_AND_QUEUES','Agents and Queues',2,'2022-01-18 09:00:23','2022-01-18 15:00:23',10,30);
|
||||||
|
|
||||||
|
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 => SALESLINE\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 => SALESLINE,SUPPORT\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');
|
||||||
|
|
||||||
|
UPDATE system_settings SET db_schema_version='1665',db_schema_update_date=NOW() where db_schema_version < 1665;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# install.pl version 2.14
|
# install.pl version 2.14
|
||||||
#
|
#
|
||||||
# Copyright (C) 2021 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
|
||||||
#
|
#
|
||||||
|
|
||||||
# CHANGES
|
# CHANGES
|
||||||
@@ -46,6 +46,7 @@
|
|||||||
# 190530-1511 - Added 'S' keepalive option
|
# 190530-1511 - Added 'S' keepalive option
|
||||||
# 210813-0925 - Added Asteirsk 16 option
|
# 210813-0925 - Added Asteirsk 16 option
|
||||||
# 210827-0926 - Added PJSIP default conf files to Asterisk 16 install
|
# 210827-0926 - Added PJSIP default conf files to Asterisk 16 install
|
||||||
|
# 220827-2239 - Added VERM web directory
|
||||||
#
|
#
|
||||||
|
|
||||||
############################################
|
############################################
|
||||||
@@ -2570,6 +2571,7 @@ if ($NOWEB < 1)
|
|||||||
if (!-e "$PATHweb/vicidial/agent_reports/") {`mkdir -p $PATHweb/vicidial/agent_reports/`;}
|
if (!-e "$PATHweb/vicidial/agent_reports/") {`mkdir -p $PATHweb/vicidial/agent_reports/`;}
|
||||||
if (!-e "$PATHweb/vicidial/server_reports/") {`mkdir -p $PATHweb/vicidial/server_reports/`;}
|
if (!-e "$PATHweb/vicidial/server_reports/") {`mkdir -p $PATHweb/vicidial/server_reports/`;}
|
||||||
if (!-e "$PATHweb/chat_customer/") {`mkdir -p $PATHweb/chat_customer/`;}
|
if (!-e "$PATHweb/chat_customer/") {`mkdir -p $PATHweb/chat_customer/`;}
|
||||||
|
if (!-e "$PATHweb/VERM/") {`mkdir -p $PATHweb/VERM/`;}
|
||||||
|
|
||||||
print "Copying web files...\n";
|
print "Copying web files...\n";
|
||||||
# save custom.css if its not empty
|
# save custom.css if its not empty
|
||||||
@@ -2582,12 +2584,14 @@ if ($NOWEB < 1)
|
|||||||
`cp -f ./www/vicidial/robots.txt $PATHweb/vicidial/server_reports/`;
|
`cp -f ./www/vicidial/robots.txt $PATHweb/vicidial/server_reports/`;
|
||||||
if (-e "$PATHweb/agc/css/custom.css.save_user_changes") {`mv $PATHweb/agc/css/custom.css.save_user_changes $PATHweb/agc/css/custom.css`;}
|
if (-e "$PATHweb/agc/css/custom.css.save_user_changes") {`mv $PATHweb/agc/css/custom.css.save_user_changes $PATHweb/agc/css/custom.css`;}
|
||||||
`cp -f ./www/vicidial/robots.txt $PATHweb/chat_customer/`;
|
`cp -f ./www/vicidial/robots.txt $PATHweb/chat_customer/`;
|
||||||
|
`cp -f ./www/vicidial/robots.txt $PATHweb/VERM/`;
|
||||||
|
|
||||||
print "setting web scripts to executable...\n";
|
print "setting web scripts to executable...\n";
|
||||||
`chmod 0777 $PATHweb/`;
|
`chmod 0777 $PATHweb/`;
|
||||||
`chmod -R 0755 $PATHweb/agc/`;
|
`chmod -R 0755 $PATHweb/agc/`;
|
||||||
`chmod -R 0755 $PATHweb/vicidial/`;
|
`chmod -R 0755 $PATHweb/vicidial/`;
|
||||||
`chmod -R 0755 $PATHweb/chat_customer/`;
|
`chmod -R 0755 $PATHweb/chat_customer/`;
|
||||||
|
`chmod -R 0755 $PATHweb/VERM/`;
|
||||||
`chmod 0777 $PATHweb/agc/`;
|
`chmod 0777 $PATHweb/agc/`;
|
||||||
`chmod 0777 $PATHweb/vicidial/`;
|
`chmod 0777 $PATHweb/vicidial/`;
|
||||||
`chmod 0777 $PATHweb/vicidial/ploticus/`;
|
`chmod 0777 $PATHweb/vicidial/ploticus/`;
|
||||||
@@ -2603,6 +2607,9 @@ if ($NOWEB < 1)
|
|||||||
`rm -f $PATHweb/vicidial/listloader_super.pl`;
|
`rm -f $PATHweb/vicidial/listloader_super.pl`;
|
||||||
`rm -f $PATHweb/vicidial/listloader.pl`;
|
`rm -f $PATHweb/vicidial/listloader.pl`;
|
||||||
`chmod 0777 $PATHweb/chat_customer/`;
|
`chmod 0777 $PATHweb/chat_customer/`;
|
||||||
|
`cp -f /dev/null $PATHweb/VERM/project_auth_entries.txt`;
|
||||||
|
`chmod 0777 $PATHweb/VERM/project_auth_entries.txt`;
|
||||||
|
`chmod 0777 $PATHweb/VERM/`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ($PROMPTcopy_web_lang =~ /y/i) || ($CLIcopy_web_lang =~ /y/i) )
|
if ( ($PROMPTcopy_web_lang =~ /y/i) || ($CLIcopy_web_lang =~ /y/i) )
|
||||||
@@ -2632,6 +2639,7 @@ if ($PATHconf !~ /\/etc\/astguiclient.conf/)
|
|||||||
`sed -i 's/$PATHconfDEFAULT/$PATHconfEREG/g' $PATHweb/vicidial/listloader_rowdisplay.pl `;
|
`sed -i 's/$PATHconfDEFAULT/$PATHconfEREG/g' $PATHweb/vicidial/listloader_rowdisplay.pl `;
|
||||||
`sed -i 's/$PATHconfDEFAULT/$PATHconfEREG/g' $PATHweb/vicidial/spreadsheet_sales_viewer.pl `;
|
`sed -i 's/$PATHconfDEFAULT/$PATHconfEREG/g' $PATHweb/vicidial/spreadsheet_sales_viewer.pl `;
|
||||||
`sed -i 's/$PATHconfDEFAULT/$PATHconfEREG/g' $PATHweb/chat_customer/dbconnect_mysqli.php `;
|
`sed -i 's/$PATHconfDEFAULT/$PATHconfEREG/g' $PATHweb/chat_customer/dbconnect_mysqli.php `;
|
||||||
|
`sed -i 's/$PATHconfDEFAULT/$PATHconfEREG/g' $PATHweb/VERM/dbconnect_mysqli.php `;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ($PROMPTcopy_conf_files =~ /y/i) || ($CLIcopy_conf_files =~ /y/i) )
|
if ( ($PROMPTcopy_conf_files =~ /y/i) || ($CLIcopy_conf_files =~ /y/i) )
|
||||||
|
|||||||
@@ -0,0 +1,515 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_AGENTS_DT_rpt.inc - Vicidial Enhanced Reporting agent detail report
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1632 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
# NANQUE, not an unanswered call?
|
||||||
|
# TIMEOT, unanswered even though it was dropped into a call that was picked up
|
||||||
|
# Warm transfers count as two calls
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
$vicidial_agent_log_table="vicidial_agent_log";
|
||||||
|
|
||||||
|
# if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];}
|
||||||
|
# elseif (isset($_POST["SUBMIT"])) {$SUBMIT=$_POST["SUBMIT"];}
|
||||||
|
|
||||||
|
if (isset($_GET["sort_agent_sessions_detail"])) {$sort_agent_sessions_detail=$_GET["sort_agent_sessions_detail"];}
|
||||||
|
elseif (isset($_POST["sort_agent_sessions_detail"])) {$sort_agent_sessions_detail=$_POST["sort_agent_sessions_detail"];}
|
||||||
|
if (isset($_GET["sort_agent_pause_detail"])) {$sort_agent_pause_detail=$_GET["sort_agent_pause_detail"];}
|
||||||
|
elseif (isset($_POST["sort_agent_pause_detail"])) {$sort_agent_pause_detail=$_POST["sort_agent_pause_detail"];}
|
||||||
|
|
||||||
|
# No campaigns, need to query for all.
|
||||||
|
$vicidial_user_log_SQL=preg_replace('/and campaign_id in \(\'\'\)/', '', $vicidial_user_log_SQL);
|
||||||
|
$vicidial_agent_log_SQL=preg_replace('/and campaign_id in \(\'\'\)/', '', $vicidial_agent_log_SQL);
|
||||||
|
|
||||||
|
if ($non_latin < 1)
|
||||||
|
{
|
||||||
|
$sort_agent_sessions_detail = preg_replace('/[^\s\-_0-9a-zA-Z]/','',$sort_agent_sessions_detail);
|
||||||
|
$sort_agent_pause_detail = preg_replace('/[^\s\-_0-9a-zA-Z]/','',$sort_agent_pause_detail);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_agent_sessions_detail = preg_replace('/[^\s\-_0-9\p{L}]/u','',$sort_agent_sessions_detail);
|
||||||
|
$sort_agent_pause_detail = preg_replace('/[^\s\-_0-9\p{L}]/u','',$sort_agent_pause_detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('/ desc$/', $sort_agent_pause_detail))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_agent_pause_detail);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_agent_pause_detail." desc";
|
||||||
|
}
|
||||||
|
$sort_agent_pause_detail_preg=preg_replace('/ desc$/', '', $sort_agent_pause_detail);
|
||||||
|
|
||||||
|
/*
|
||||||
|
$start_date="2021-12-20";
|
||||||
|
$start_time="00:00:00";
|
||||||
|
$end_date="2021-12-20";
|
||||||
|
$end_time="23:59:59";
|
||||||
|
*/
|
||||||
|
|
||||||
|
$agent_sessions_array=array();
|
||||||
|
|
||||||
|
$session_stmt="select *,if(event='LOGOUT' or event='TIMEOUTLOGOUT', 1, 0) as priority from vicidial_user_log $vicidial_user_log_SQL and event in ('LOGIN', 'LOGOUT', 'TIMEOUTLOGOUT') order by user, event_date, priority asc";
|
||||||
|
if ($DB) {$HTML_output.="<B>$session_stmt</B>";}
|
||||||
|
# print "$session_stmt<BR>\n";
|
||||||
|
$session_rslt=mysql_to_mysqli($session_stmt, $link);
|
||||||
|
|
||||||
|
# WHILE loop constants
|
||||||
|
$agent_logged_in=0;
|
||||||
|
$interval_start_date="";
|
||||||
|
$interval_end_date="";
|
||||||
|
$prev_user="";
|
||||||
|
$prev_full_name="";
|
||||||
|
$prev_date="";
|
||||||
|
$TODAY=date("Y-m-d");
|
||||||
|
$NOW_TIME=date("H:i:s");
|
||||||
|
|
||||||
|
while ($session_row=mysqli_fetch_array($session_rslt))
|
||||||
|
{
|
||||||
|
$full_name=$fullname_info["$session_row[user]"];
|
||||||
|
$user=$session_row["user"];
|
||||||
|
$extension=$session_row["extension"];
|
||||||
|
$event=$session_row["event"];
|
||||||
|
$notes=$session_row["extension"];
|
||||||
|
$event_epoch=$session_row["event_epoch"];
|
||||||
|
$event_time=$session_row["event_date"];
|
||||||
|
$server_ip=$session_row["server_ip"];
|
||||||
|
$event_date=substr($event_time, 0, 10);
|
||||||
|
|
||||||
|
# END date in case agent is still logged in at that time
|
||||||
|
if ($prev_date!=$TODAY)
|
||||||
|
{
|
||||||
|
$prev_date_eod="$prev_date 23:59:59";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$prev_date_eod="$prev_date $NOW_TIME";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($event_date!=$TODAY)
|
||||||
|
{
|
||||||
|
$event_date_eod="$event_date 23:59:59";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$event_date_eod="$event_date $NOW_TIME";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($prev_user!=$user || $event_date!=$prev_date) && $prev_user!="" && $prev_date!="")
|
||||||
|
{
|
||||||
|
#
|
||||||
|
# Agent is no longer logged in
|
||||||
|
if ($agent_logged_in)
|
||||||
|
{
|
||||||
|
$eod_epoch_stmt="select unix_timestamp('$prev_date_eod')"; # , '$prev_user' as previous_user, '$prev_full_name' as prev_full_name
|
||||||
|
$eod_epoch_rslt=mysql_to_mysqli($eod_epoch_stmt, $link);
|
||||||
|
$eod_epoch_row=mysqli_fetch_row($eod_epoch_rslt);
|
||||||
|
$agent_sessions_array["$prev_user"]["$start_date_epoch"]["end_hour"]=$eod_epoch_row[0];
|
||||||
|
$agent_sessions_array["$prev_user"]["$start_date_epoch"]["full_name"]=$prev_full_name;
|
||||||
|
|
||||||
|
# Agent logged in and day is today, they are currently logged in, else EOD LOGOUT
|
||||||
|
$notes=($eod_epoch_row[0]>=strtotime(date("Y-m-d 00:00:00")) ? "CURRENTLY LOGGED IN" : "EOD LOGOUT");
|
||||||
|
$agent_sessions_array["$prev_user"]["$start_date_epoch"]["notes"]=$notes;
|
||||||
|
|
||||||
|
$agent_logged_in=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($event=="LOGIN")
|
||||||
|
{
|
||||||
|
if ($agent_logged_in==0)
|
||||||
|
{
|
||||||
|
# $start_date_epoch=$event_epoch;
|
||||||
|
$start_date_epoch=$event_time;
|
||||||
|
$agent_sessions_array["$user"]["$start_date_epoch"]["full_name"]=$full_name;
|
||||||
|
$agent_sessions_array["$user"]["$start_date_epoch"]["start_hour"]=$event_epoch;
|
||||||
|
$agent_sessions_array["$user"]["$start_date_epoch"]["extension"]=$extension;
|
||||||
|
$agent_sessions_array["$user"]["$start_date_epoch"]["server_ip"]=$server_ip;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
"$session_row[user] is already logged in at $start_date_epoch<BR>\n";
|
||||||
|
}
|
||||||
|
$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
|
||||||
|
{
|
||||||
|
$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;
|
||||||
|
|
||||||
|
$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");
|
||||||
|
|
||||||
|
$start_date_epoch=0;
|
||||||
|
$agent_logged_in=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$prev_user=$user;
|
||||||
|
$prev_full_name=$full_name;
|
||||||
|
$prev_date=$event_date;
|
||||||
|
$prev_event_epoch=$event_epoch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($agent_logged_in)
|
||||||
|
{
|
||||||
|
$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;
|
||||||
|
|
||||||
|
|
||||||
|
$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];
|
||||||
|
if ($pause_row[1]==0) {$pause_row[0]=0;}
|
||||||
|
$agent_sessions_array["$user"]["$start_date_epoch"]["pause_time"]=$pause_row[0];
|
||||||
|
|
||||||
|
}
|
||||||
|
ksort($agent_sessions_array, SORT_NATURAL | SORT_FLAG_CASE);
|
||||||
|
# print_r($agent_sessions_array); die;
|
||||||
|
|
||||||
|
####### AGENT SESSION DETAIL ##########
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header' id='sasd_anchor'>"._QXZ("Detail of agent sessions").": $NWB#VERM_AGENTS_DT-detail_of_agent_sessions$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>";
|
||||||
|
|
||||||
|
$sort_asd_index=preg_replace('/ desc/', '', $sort_agent_sessions_detail);
|
||||||
|
if (preg_match('/ desc$/', $sort_agent_sessions_detail))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_agent_sessions_detail);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_agent_sessions_detail." desc";
|
||||||
|
}
|
||||||
|
$sort_agent_sessions_detail_preg=preg_replace('/ desc$/', '', $sort_agent_sessions_detail);
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
/*
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_sessions_sort_agent' id='agent_sessions_sort_agent' href='".$PHP_SELF."?sort_agent_pause_detail=".$sort_agent_pause_detail."&sort_agent_sessions_detail=".("full_name"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "full_name")."#agent_sessions_sort_agent'>Agent".("full_name"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_sessions_sort_start_hour' id='agent_sessions_sort_start_hour' href='".$PHP_SELF."?sort_agent_pause_detail=".$sort_agent_pause_detail."&sort_agent_sessions_detail=".("start_hour"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "start_hour")."#agent_sessions_sort_start_hour'>Start hour".("start_hour"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_sessions_sort_end_hour' id='agent_sessions_sort_end_hour' href='".$PHP_SELF."?sort_agent_pause_detail=".$sort_agent_pause_detail."&sort_agent_sessions_detail=".("end_hour"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "end_hour")."#agent_sessions_sort_end_hour'>End hour".("end_hour"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_sessions_sort_duration' id='agent_sessions_sort_duration' href='".$PHP_SELF."?sort_agent_pause_detail=".$sort_agent_pause_detail."&sort_agent_sessions_detail=".("duration"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "duration")."#agent_sessions_sort_duration'>Duration".("duration"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_sessions_sort_extension' id='agent_sessions_sort_extension' href='".$PHP_SELF."?sort_agent_pause_detail=".$sort_agent_pause_detail."&sort_agent_sessions_detail=".("extension"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "extension")."#agent_sessions_sort_extension'>Ext.".("extension"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_sessions_sort_notes' id='agent_sessions_sort_notes' href='".$PHP_SELF."?sort_agent_pause_detail=".$sort_agent_pause_detail."&sort_agent_sessions_detail=".("notes"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "notes")."#agent_sessions_sort_notes'>Termination".("notes"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_sessions_sort_pauses' id='agent_sessions_sort_pauses' href='".$PHP_SELF."?sort_agent_pause_detail=".$sort_agent_pause_detail."&sort_agent_sessions_detail=".("pauses"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "pauses")."#agent_sessions_sort_pauses'>Pause".("pauses"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_sessions_sort_pause_time' id='agent_sessions_sort_pause_time' href='".$PHP_SELF."?sort_agent_pause_detail=".$sort_agent_pause_detail."&sort_agent_sessions_detail=".("pause_time"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "pause_time")."#agent_sessions_sort_pause_time'>P. Time".("pause_time"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_sessions_sort_server_ip' id='agent_sessions_sort_server_ip' href='".$PHP_SELF."?sort_agent_pause_detail=".$sort_agent_pause_detail."&sort_agent_sessions_detail=".("server_ip"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "server_ip")."#agent_sessions_sort_server_ip'>Srv".("server_ip"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
*/
|
||||||
|
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Agent").("full_name"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_sessions_detail').value='".("full_name"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "full_name")."'; this.form.action+='#sasd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Start hour").("start_hour"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_sessions_detail').value='".("start_hour"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "start_hour")."'; this.form.action+='#sasd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("End hour").("end_hour"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_sessions_detail').value='".("end_hour"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "end_hour")."'; this.form.action+='#sasd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Duration").("duration"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_sessions_detail').value='".("duration"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "duration")."'; this.form.action+='#sasd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Ext.").("extension"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_sessions_detail').value='".("extension"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "extension")."'; this.form.action+='#sasd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Termination").("notes"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_sessions_detail').value='".("notes"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "notes")."'; this.form.action+='#sasd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Pause").("pauses"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_sessions_detail').value='".("pauses"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "pauses")."'; this.form.action+='#sasd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("P. Time").("pause_time"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_sessions_detail').value='".("pause_time"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "pause_time")."'; this.form.action+='#sasd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Srv").("server_ip"==$sort_agent_sessions_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_sessions_detail').value='".("server_ip"==$sort_agent_sessions_detail_preg ? "$reverse_link" : "server_ip")."'; this.form.action+='#sasd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
|
||||||
|
$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";
|
||||||
|
|
||||||
|
## Compress multi-multi-dimensional array into multi-dimensional array
|
||||||
|
$agent_sessions_final_array=array();
|
||||||
|
$i=0;
|
||||||
|
foreach ($agent_sessions_array as $user => $sessions)
|
||||||
|
{
|
||||||
|
foreach ($sessions as $login_start_date => $session_data)
|
||||||
|
{
|
||||||
|
$pauses=$session_data["pauses"];
|
||||||
|
$pause_time=$session_data["pause_time"];
|
||||||
|
$server_ip=$session_data["server_ip"];
|
||||||
|
# $agentName=$session_data["full_name"];
|
||||||
|
$agentName=($show_full_agent_info ? $user." - " : "").$session_data["full_name"];
|
||||||
|
|
||||||
|
|
||||||
|
$time_stmt="select from_unixtime(".$session_data["start_hour"]."), from_unixtime(".$session_data["end_hour"]."), sec_to_time(".($session_data["end_hour"]-$session_data["start_hour"]).")";
|
||||||
|
# print $time_stmt."<BR>\n";
|
||||||
|
$time_rslt=mysql_to_mysqli($time_stmt, $link);
|
||||||
|
$time_row=mysqli_fetch_row($time_rslt);
|
||||||
|
$start_hour=$time_row[0];
|
||||||
|
$end_hour=$time_row[1];
|
||||||
|
$duration=$time_row[2];
|
||||||
|
|
||||||
|
$agent_sessions_final_array[$i]["full_name"]=$agentName;
|
||||||
|
$agent_sessions_final_array[$i]["start_hour"]=$start_hour;
|
||||||
|
$agent_sessions_final_array[$i]["end_hour"]=$end_hour;
|
||||||
|
$agent_sessions_final_array[$i]["duration"]=$duration;
|
||||||
|
$agent_sessions_final_array[$i]["extension"]=$session_data["extension"];
|
||||||
|
$agent_sessions_final_array[$i]["notes"]=$session_data["notes"];
|
||||||
|
$agent_sessions_final_array[$i]["pauses"]=$pauses;
|
||||||
|
$agent_sessions_final_array[$i]["pause_time"]=$pause_time;
|
||||||
|
$agent_sessions_final_array[$i]["server_ip"]=$server_ip;
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ($sort_asd_index)
|
||||||
|
{
|
||||||
|
# print_r($agent_sessions_final_array);
|
||||||
|
|
||||||
|
$col = array_column( $agent_sessions_final_array, "$sort_asd_index" );
|
||||||
|
if (preg_match('/ desc$/', $sort_agent_sessions_detail))
|
||||||
|
{
|
||||||
|
array_multisort( $col, SORT_DESC, SORT_STRING, $agent_sessions_final_array );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_multisort( $col, SORT_ASC, SORT_STRING, $agent_sessions_final_array );
|
||||||
|
}
|
||||||
|
|
||||||
|
# print_r($agent_sessions_final_array);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($agent_sessions_final_array as $i => $row)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr class='standard_font'>";
|
||||||
|
$HTML_output.="<td>".$row["full_name"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["start_hour"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["end_hour"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["duration"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["extension"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["notes"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["pauses"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["pause_time"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["server_ip"]."</td>";
|
||||||
|
$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";
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='9' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=agent_sessions&sort_agent_pause_detail=".$sort_agent_pause_detail."&sort_agent_sessions_detail=".$sort_agent_sessions_detail."\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td colspan='9' class='export_row_cell'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('AGENTS_DT', 'agent_sessions')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$HTML_output.="</table>\n";
|
||||||
|
$HTML_output.="<input type='hidden' name='sort_agent_sessions_detail' id='sort_agent_sessions_detail' value='$sort_agent_sessions_detail'>";
|
||||||
|
#####################################
|
||||||
|
|
||||||
|
|
||||||
|
####### AGENT PAUSE DETAIL ##########
|
||||||
|
$sort_apd_index=preg_replace('/ desc/', '', $sort_agent_pause_detail);
|
||||||
|
if (preg_match('/ desc$/', $sort_agent_pause_detail))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_agent_pause_detail);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_agent_pause_detail." desc";
|
||||||
|
}
|
||||||
|
$sort_agent_pause_detail_preg=preg_replace('/ desc$/', '', $sort_agent_pause_detail);
|
||||||
|
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header' id='sapd_anchor'>"._QXZ("Detail of agent pauses").": $NWB#VERM_AGENTS_DT-detail_of_agent_pauses$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>";
|
||||||
|
/*
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
$HTML_output.="<th>Agent</th>";
|
||||||
|
$HTML_output.="<th>Ext.</th>";
|
||||||
|
$HTML_output.="<th>Code</th>";
|
||||||
|
$HTML_output.="<th>Activity</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="<th>Billable?</th>";
|
||||||
|
$HTML_output.="<th>Start hour</th>";
|
||||||
|
$HTML_output.="<th>End hour</th>";
|
||||||
|
$HTML_output.="<th>Duration</th>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
*/
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
/*
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_pause_sort_agent' id='agent_pause_sort_agent' href='".$PHP_SELF."?sort_agent_sessions_detail=".$sort_agent_sessions_detail."&sort_agent_pause_detail=".("user"==$sort_agent_pause_detail_preg ? "$reverse_link" : "user")."#agent_pause_sort_agent'>Agent".("user"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_pause_sort_extension' id='agent_pause_sort_extension' href='".$PHP_SELF."?sort_agent_sessions_detail=".$sort_agent_sessions_detail."&sort_agent_pause_detail=".("extension"==$sort_agent_pause_detail_preg ? "$reverse_link" : "extension")."#agent_pause_sort_extension'>Ext.".("extension"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_pause_sort_pause_code' id='agent_pause_sort_pause_code' href='".$PHP_SELF."?sort_agent_sessions_detail=".$sort_agent_sessions_detail."&sort_agent_pause_detail=".("pause_code"==$sort_agent_pause_detail_preg ? "$reverse_link" : "pause_code")."#agent_pause_sort_pause_code'>Code".("pause_code"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_pause_sort_pause_code_name' id='agent_pause_sort_pause_code_name' href='".$PHP_SELF."?sort_agent_sessions_detail=".$sort_agent_sessions_detail."&sort_agent_pause_detail=".("pause_code_name"==$sort_agent_pause_detail_preg ? "$reverse_link" : "pause_code_name")."#agent_pause_sort_pause_code_name'>Activity".("pause_code_name"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_pause_sort_billable_code' id='agent_pause_sort_billable_code' href='".$PHP_SELF."?sort_agent_sessions_detail=".$sort_agent_sessions_detail."&sort_agent_pause_detail=".("billable_code"==$sort_agent_pause_detail_preg ? "$reverse_link" : "billable_code")."#agent_pause_sort_billable_code'>...".("billable_code"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_pause_sort_is_billable' id='agent_pause_sort_is_billable' href='".$PHP_SELF."?sort_agent_sessions_detail=".$sort_agent_sessions_detail."&sort_agent_pause_detail=".("is_billable"==$sort_agent_pause_detail_preg ? "$reverse_link" : "is_billable")."#agent_pause_sort_is_billable'>Billable?".("is_billable"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_pause_sort_start_hour' id='agent_pause_sort_start_hour' href='".$PHP_SELF."?sort_agent_sessions_detail=".$sort_agent_sessions_detail."&sort_agent_pause_detail=".("start_hour"==$sort_agent_pause_detail_preg ? "$reverse_link" : "start_hour")."#agent_pause_sort_start_hour'>Start hour".("start_hour"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_pause_sort_end_hour' id='agent_pause_sort_end_hour' href='".$PHP_SELF."?sort_agent_sessions_detail=".$sort_agent_sessions_detail."&sort_agent_pause_detail=".("end_hour"==$sort_agent_pause_detail_preg ? "$reverse_link" : "end_hour")."#agent_pause_sort_end_hour'>End hour".("end_hour"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='agent_pause_sort_duration' id='agent_pause_sort_duration' href='".$PHP_SELF."?sort_agent_sessions_detail=".$sort_agent_sessions_detail."&sort_agent_pause_detail=".("duration"==$sort_agent_pause_detail_preg ? "$reverse_link" : "duration")."#agent_pause_sort_duration'>Duration".("duration"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
*/
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Agent").("user"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_pause_detail').value='".("user"==$sort_agent_pause_detail_preg ? "$reverse_link" : "user")."'; this.form.action+='#sapd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Ext.").("extension"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_pause_detail').value='".("extension"==$sort_agent_pause_detail_preg ? "$reverse_link" : "extension")."'; this.form.action+='#sapd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Code").("pause_code"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_pause_detail').value='".("pause_code"==$sort_agent_pause_detail_preg ? "$reverse_link" : "pause_code")."'; this.form.action+='#sapd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Activity").("pause_code_name"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_pause_detail').value='".("pause_code_name"==$sort_agent_pause_detail_preg ? "$reverse_link" : "pause_code_name")."'; this.form.action+='#sapd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='...".("billable_code"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_pause_detail').value='".("billable_code"==$sort_agent_pause_detail_preg ? "$reverse_link" : "billable_code")."'; this.form.action+='#sapd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Billable?").("is_billable"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_pause_detail').value='".("is_billable"==$sort_agent_pause_detail_preg ? "$reverse_link" : "is_billable")."'; this.form.action+='#sapd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Start hour").("start_hour"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_pause_detail').value='".("start_hour"==$sort_agent_pause_detail_preg ? "$reverse_link" : "start_hour")."'; this.form.action+='#sapd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("End hour").("end_hour"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_pause_detail').value='".("end_hour"==$sort_agent_pause_detail_preg ? "$reverse_link" : "end_hour")."'; this.form.action+='#sapd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Duration").("duration"==$sort_agent_pause_detail_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agent_pause_detail').value='".("duration"==$sort_agent_pause_detail_preg ? "$reverse_link" : "duration")."'; this.form.action+='#sapd_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
|
||||||
|
$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";
|
||||||
|
|
||||||
|
$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>";}
|
||||||
|
$agent_pause_rslt=mysql_to_mysqli($agent_pause_stmt, $link);
|
||||||
|
$agent_pause_array=array(); $i=0;
|
||||||
|
while ($agent_pause_row=mysqli_fetch_array($agent_pause_rslt))
|
||||||
|
{
|
||||||
|
$campaign_id=$agent_pause_row["campaign_id"];
|
||||||
|
$user=$agent_pause_row["user"];
|
||||||
|
$extension=$agent_pause_row["extension"];
|
||||||
|
$start_hour=$agent_pause_row["event_time"];
|
||||||
|
$end_hour=$agent_pause_row["end_hour"];
|
||||||
|
$duration=$agent_pause_row["duration"];
|
||||||
|
$pause_code=$agent_pause_row["pause_code"];
|
||||||
|
# $agentName=$fullname_info["$user"];
|
||||||
|
$agentName=($show_full_agent_info ? $user." - " : "").$fullname_info["$user"];
|
||||||
|
|
||||||
|
$pause_key=$campaign_id."-".$pause_code;
|
||||||
|
$pause_code_name=$pause_code_names["$pause_key"];
|
||||||
|
if (strlen($pause_code_name)==0) {$pause_code_name="-";}
|
||||||
|
|
||||||
|
$is_billable="No"; $bp="N"; $pp="N";
|
||||||
|
if (in_array($pause_code, $billable_pause_codes["$campaign_id"]) || in_array($pause_code, $billable_pause_codes["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$is_billable="Yes"; $bp="";
|
||||||
|
}
|
||||||
|
if (!in_array($pause_code, $payable_pause_codes["$campaign_id"]) && in_array($pause_code, $payable_pause_codes["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$pp="";
|
||||||
|
}
|
||||||
|
|
||||||
|
$billable_code=$bp."B".$pp."P";
|
||||||
|
|
||||||
|
$agent_pause_array[$i]["user"]=$agentName;
|
||||||
|
$agent_pause_array[$i]["extension"]=$extension;
|
||||||
|
$agent_pause_array[$i]["pause_code"]=$pause_code;
|
||||||
|
$agent_pause_array[$i]["pause_code_name"]=$pause_code_name;
|
||||||
|
$agent_pause_array[$i]["billable_code"]=$billable_code;
|
||||||
|
$agent_pause_array[$i]["is_billable"]=$is_billable;
|
||||||
|
$agent_pause_array[$i]["start_hour"]=$start_hour;
|
||||||
|
$agent_pause_array[$i]["end_hour"]=$end_hour;
|
||||||
|
$agent_pause_array[$i]["duration"]=$duration;
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($sort_apd_index)
|
||||||
|
{
|
||||||
|
# print_r($agent_pause_array);
|
||||||
|
|
||||||
|
$col = array_column( $agent_pause_array, "$sort_apd_index" );
|
||||||
|
if (preg_match('/ desc$/', $sort_agent_pause_detail))
|
||||||
|
{
|
||||||
|
array_multisort( $col, SORT_DESC, SORT_STRING, $agent_pause_array );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_multisort( $col, SORT_ASC, SORT_STRING, $agent_pause_array );
|
||||||
|
}
|
||||||
|
|
||||||
|
# print_r($agent_pause_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($agent_pause_array as $i => $row)
|
||||||
|
{
|
||||||
|
|
||||||
|
$myDateTime = DateTime::createFromFormat('Y-m-d H:i:s', $row["start_hour"]);
|
||||||
|
$start_hour_value = $myDateTime->format('m/d - H:i:s');
|
||||||
|
|
||||||
|
$myDateTime = DateTime::createFromFormat('Y-m-d H:i:s', $row["end_hour"]);
|
||||||
|
$end_hour_value = $myDateTime->format('m/d - H:i:s');
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='standard_font'>";
|
||||||
|
$HTML_output.="<td>".$row["user"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["extension"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["pause_code"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["pause_code_name"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["billable_code"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["is_billable"]."</td>";
|
||||||
|
$HTML_output.="<td>".$start_hour_value."</td>";
|
||||||
|
$HTML_output.="<td>".$end_hour_value."</td>";
|
||||||
|
$HTML_output.="<td>".$row["duration"]."</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$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";
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='9' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=agent_pause_details&sort_agent_sessions_detail=".$sort_agent_sessions_detail."&sort_agent_pause_detail=".$sort_agent_pause_detail."\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td colspan='9' class='export_row_cell'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('AGENTS_DT', 'agent_pause_details')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
$HTML_output.="<input type='hidden' name='sort_agent_pause_detail' id='sort_agent_pause_detail' value='$sort_agent_pause_detail'>";
|
||||||
|
#####################################
|
||||||
|
|
||||||
|
|
||||||
|
if ($download_rpt)
|
||||||
|
{
|
||||||
|
$data_to_download=$CSV_output["$download_rpt"];
|
||||||
|
|
||||||
|
$FILE_TIME = date("Ymd-His");
|
||||||
|
$CSVfilename = "AGENTS_DT_RPT_".$download_rpt."_".$FILE_TIME.".csv";
|
||||||
|
header('Content-type: application/octet-stream');
|
||||||
|
|
||||||
|
header("Content-Disposition: attachment; filename=\"$CSVfilename\"");
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
ob_clean();
|
||||||
|
flush();
|
||||||
|
|
||||||
|
echo "$data_to_download";
|
||||||
|
|
||||||
|
if ($db_source == 'S')
|
||||||
|
{
|
||||||
|
mysqli_close($link);
|
||||||
|
$use_slave_server=0;
|
||||||
|
$db_source = 'M';
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
$endMS = microtime();
|
||||||
|
$startMSary = explode(" ",$startMS);
|
||||||
|
$endMSary = explode(" ",$endMS);
|
||||||
|
$runS = ($endMSary[0] - $startMSary[0]);
|
||||||
|
$runM = ($endMSary[1] - $startMSary[1]);
|
||||||
|
$TOTALrun = ($runS + $runM);
|
||||||
|
|
||||||
|
# $stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';";
|
||||||
|
# if ($DB) {echo "|$stmt|\n";}
|
||||||
|
# $rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
echo $HTML_output;
|
||||||
|
?>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_AJAX_functions.php - Vicidial Enhanced Reporting AJAX functions page
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1608 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
$startMS = microtime();
|
||||||
|
$STARTtime = date("U");
|
||||||
|
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
require("functions.php");
|
||||||
|
|
||||||
|
if (isset($_GET["function"])) {$function=$_GET["function"];}
|
||||||
|
elseif (isset($_POST["function"])) {$function=$_POST["function"];}
|
||||||
|
if (isset($_GET["custom_report_vars"])) {$custom_report_vars=$_GET["custom_report_vars"];}
|
||||||
|
elseif (isset($_POST["custom_report_vars"])) {$custom_report_vars=$_POST["custom_report_vars"];}
|
||||||
|
if (isset($_GET["custom_report_name"])) {$custom_report_name=$_GET["custom_report_name"];}
|
||||||
|
elseif (isset($_POST["custom_report_name"])) {$custom_report_name=$_POST["custom_report_name"];}
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
##### 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;";
|
||||||
|
$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];
|
||||||
|
$outbound_autodial_active = $row[1];
|
||||||
|
$slave_db_server = $row[2];
|
||||||
|
$reports_use_slave_db = $row[3];
|
||||||
|
$SSenable_languages = $row[4];
|
||||||
|
$SSlanguage_method = $row[5];
|
||||||
|
$agent_whisper_enabled = $row[6];
|
||||||
|
$SSreport_default_format = $row[7];
|
||||||
|
$SSenable_pause_code_limits = $row[8];
|
||||||
|
$SSallow_web_debug = $row[9];
|
||||||
|
$SSadmin_screen_colors = $row[10];
|
||||||
|
$SSadmin_web_directory = $row[11];
|
||||||
|
}
|
||||||
|
if ($SSallow_web_debug < 1) {$DB=0;}
|
||||||
|
##### END SETTINGS LOOKUP #####
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
if ($non_latin < 1)
|
||||||
|
{
|
||||||
|
$function = preg_replace('/[^\-_0-9a-zA-Z]/','',$function);
|
||||||
|
$custom_report_vars = preg_replace('/[^-\/\|\_\#\*\,\.\_\[\]0-9a-zA-Z]/','',$custom_report_vars);
|
||||||
|
$custom_report_name = preg_replace('/[^\-_0-9a-zA-Z]/','',$custom_report_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$function = preg_replace('/[^-_0-9\p{L}/u','',$function);
|
||||||
|
$custom_report_vars = preg_replace('/[^-\/\|\_\#\*\,\.\_\[\]0-9\p{L}]/u','',$custom_report_vars);
|
||||||
|
$custom_report_name = preg_replace('/[^-_0-9\p{L}/u','',$custom_report_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##### BEGIN log visit to the vicidial_report_log table #####
|
||||||
|
$LOGip = getenv("REMOTE_ADDR");
|
||||||
|
$LOGbrowser = getenv("HTTP_USER_AGENT");
|
||||||
|
$LOGscript_name = getenv("SCRIPT_NAME");
|
||||||
|
$LOGserver_name = getenv("SERVER_NAME");
|
||||||
|
$LOGserver_port = getenv("SERVER_PORT");
|
||||||
|
$LOGrequest_uri = getenv("REQUEST_URI");
|
||||||
|
$LOGhttp_referer = getenv("HTTP_REFERER");
|
||||||
|
$LOGbrowser=preg_replace("/\'|\"|\\\\/","",$LOGbrowser);
|
||||||
|
$LOGrequest_uri=preg_replace("/\'|\"|\\\\/","",$LOGrequest_uri);
|
||||||
|
$LOGhttp_referer=preg_replace("/\'|\"|\\\\/","",$LOGhttp_referer);
|
||||||
|
if (preg_match("/443/i",$LOGserver_port)) {$HTTPprotocol = 'https://';}
|
||||||
|
else {$HTTPprotocol = 'http://';}
|
||||||
|
if (($LOGserver_port == '80') or ($LOGserver_port == '443') ) {$LOGserver_port='';}
|
||||||
|
else {$LOGserver_port = ":$LOGserver_port";}
|
||||||
|
$LOGfull_url = "$HTTPprotocol$LOGserver_name$LOGserver_port$LOGrequest_uri";
|
||||||
|
|
||||||
|
$LOGhostname = php_uname('n');
|
||||||
|
if (strlen($LOGhostname)<1) {$LOGhostname='X';}
|
||||||
|
if (strlen($LOGserver_name)<1) {$LOGserver_name='X';}
|
||||||
|
|
||||||
|
|
||||||
|
if ($function=="log_custom_report")
|
||||||
|
{
|
||||||
|
$rpt_log_stmt="insert ignore into verm_custom_report_holder(user, report_name, report_parameters) values('$PHP_AUTH_USER', '$custom_report_name', '$LOGhttp_referer') ON DUPLICATE KEY UPDATE report_name='$custom_report_name', report_parameters='$custom_report_vars'";
|
||||||
|
$rpt_log_rslt=mysql_to_mysqli($rpt_log_stmt, $link);
|
||||||
|
return mysqli_affected_rows($rpt_log_rslt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -0,0 +1,340 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_ANSWERED_DT_rpt.inc - Vicidial Enhanced Reporting answered call detail report
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1630 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
if (isset($_GET["page_no"])) {$page_no=$_GET["page_no"];}
|
||||||
|
elseif (isset($_POST["page_no"])) {$page_no=$_POST["page_no"];}
|
||||||
|
if (isset($_GET["sort_answered_details"])) {$sort_answered_details=$_GET["sort_answered_details"];}
|
||||||
|
elseif (isset($_POST["sort_answered_details"])) {$sort_answered_details=$_POST["sort_answered_details"];}
|
||||||
|
|
||||||
|
if ($non_latin < 1)
|
||||||
|
{
|
||||||
|
$sort_answered_details = preg_replace('/[^\s\-_0-9a-zA-Z]/','',$sort_answered_details);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_answered_details = preg_replace('/[^\s\-_0-9\p{L}]/u','',$sort_answered_details);
|
||||||
|
}
|
||||||
|
$page_no=preg_replace('/[^0-9]/', '', $page_no);
|
||||||
|
if (!$page_no || $page_no<1) {$page_no=1;}
|
||||||
|
|
||||||
|
$ll=($page_no-1)*20;
|
||||||
|
$ul=($page_no*20);
|
||||||
|
|
||||||
|
$available_columns=array(
|
||||||
|
"Date" => "call_date",
|
||||||
|
"Caller" => "phone_number",
|
||||||
|
"Campaign/ingroup" => "campaign_id",
|
||||||
|
"IVR" => "ivr",
|
||||||
|
"Wait" => "wait",
|
||||||
|
"Duration" => "length_in_sec",
|
||||||
|
"Pos." => "queue_position",
|
||||||
|
"Disconnection" => "term_reason",
|
||||||
|
"Transferred to" => "transferred_to",
|
||||||
|
"Handled by" => "user",
|
||||||
|
"Attempts" => "attempts",
|
||||||
|
"Code" => "status",
|
||||||
|
"Stints" => "stints",
|
||||||
|
"Srv" => "srv",
|
||||||
|
"Asterisk UID" => "caller_code",
|
||||||
|
"MOH events" => "moh_events",
|
||||||
|
"MOH duration" => "moh_duration",
|
||||||
|
"IVR duration" => "ivr_duration",
|
||||||
|
"IVR path" => "ivr_path",
|
||||||
|
"DID" => "did",
|
||||||
|
"CRM" => "",
|
||||||
|
"Tag" => "tag",
|
||||||
|
"Feat" => "feat",
|
||||||
|
"Vars" => "vars",
|
||||||
|
"Feature Codes" => "feature_codes",
|
||||||
|
"Variables" => "variables"
|
||||||
|
);
|
||||||
|
|
||||||
|
$selected_columns=array(
|
||||||
|
_QXZ("Date") => "call_date",
|
||||||
|
_QXZ("Caller") => "phone_number",
|
||||||
|
_QXZ("Campaign/ingroup") => "campaign_id",
|
||||||
|
_QXZ("IVR") => "ivr_duration",
|
||||||
|
_QXZ("Wait") => "wait",
|
||||||
|
_QXZ("Duration") => "duration",
|
||||||
|
_QXZ("Pos.") => "queue_position",
|
||||||
|
_QXZ("Disconnection") => "term_reason",
|
||||||
|
_QXZ("Handled by") => "user",
|
||||||
|
_QXZ("Attempts") => "attempts",
|
||||||
|
_QXZ("Code") => "status",
|
||||||
|
"uniqueid" => "detail_id"
|
||||||
|
);
|
||||||
|
# "Transferred to" => "transferred_to",
|
||||||
|
|
||||||
|
|
||||||
|
$sort_char="";
|
||||||
|
$sort_index="";
|
||||||
|
|
||||||
|
$sort_clause=" order by call_date";
|
||||||
|
$sort_index=preg_replace('/ desc/', '', $sort_answered_details);
|
||||||
|
if (preg_match('/ desc$/', $sort_answered_details))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_answered_details);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_answered_details." desc";
|
||||||
|
}
|
||||||
|
$sort_answered_details_preg=preg_replace('/ desc$/', '', $sort_answered_details);
|
||||||
|
|
||||||
|
$stmt="select call_date, phone_number, campaign_id, 0 as ivr, '0:00' as wait, sec_to_time(round(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 did, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, uniqueid as detail_id, 'O' as direction from vicidial_log $vicidial_log_SQL and user not in ('VDAD') UNION select call_date, phone_number, campaign_id, 0 as ivr, sec_to_time(round(queue_seconds)) as wait, sec_to_time(round(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 did, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, CONCAT(uniqueid, '|', closecallid) as detail_id, 'I' as direction from vicidial_closer_log $vicidial_closer_log_SQL and (user!='VDCL') $sort_clause";
|
||||||
|
|
||||||
|
if ($DB) {$HTML_output.="<B>$stmt</B>";}
|
||||||
|
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$total_pages=ceil(mysqli_num_rows($rslt)/20);
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header' id='sad_anchor'>"._QXZ("Answered Call Details").": $NWB#VERM_ANSWERED_DT-details$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='left'><B><a name='page_anchor' class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&page_no=1#page_anchor' alt='First page of results'>|<</a> <a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&page_no=".($page_no-1)."#page_anchor' alt='Prev page of results'><<</a></B></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='left'>";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('ANSWERED_DT', '1')\" title=\"First page\" value='|<'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('ANSWERED_DT', '".($page_no-1)."')\" title=\"Prev page\" value='<<'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='center' colspan='".(count($selected_columns)-2)."'> </td>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='right'><B><a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&page_no=".($page_no+1)."#page_anchor' alt='Next page of results'>>></a> <a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&page_no=".$total_pages."#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('ANSWERED_DT', '".($page_no<$total_pages ? $page_no+1 : $total_pages)."')\" title=\"Next page\" value='>>'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('ANSWERED_DT', '".($total_pages)."')\" title=\"Last page\" value='>|'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$CSV_output="";
|
||||||
|
foreach ($selected_columns as $display_name => $column_name)
|
||||||
|
{
|
||||||
|
if ($display_name!="uniqueid")
|
||||||
|
{
|
||||||
|
$CSV_output.="\"$display_name\",";
|
||||||
|
# $HTML_output.="<th><a class='header_link' name='call_detail_sort_".$column_name."' id='call_detail_sort_".$column_name."' href='".$PHP_SELF."?sort_answered_details=".($column_name==$sort_answered_details_preg ? "$reverse_link" : "$column_name")."&page_no=".$page_no."#call_detail_sort_".$column_name."'>".$display_name.($column_name==$sort_answered_details_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='".$display_name.($column_name==$sort_answered_details_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_answered_details').value='".($column_name==$sort_answered_details_preg ? "$reverse_link" : "$column_name")."'; this.form.action+='#sad_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$CSV_output.="\n";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$output_array=array();
|
||||||
|
$i=0;
|
||||||
|
while ($row=mysqli_fetch_array($rslt))
|
||||||
|
{
|
||||||
|
$row["caller_code"]="";
|
||||||
|
$row["ivr"]="00:00";
|
||||||
|
$row["ivr_duration"]="00:00";
|
||||||
|
$row["ivr_path"]="";
|
||||||
|
$row["did"]="";
|
||||||
|
|
||||||
|
$uniqueid=$row["uniqueid"];
|
||||||
|
$row["campaign_id"]=$queue_names["$row[campaign_id]"];
|
||||||
|
$row["status"]=($status_names["$row[status]"] ? $status_names["$row[status]"] : $row["status"]);
|
||||||
|
$row["user"]=($show_full_agent_info ? "$row[user] - ".$fullname_info["$row[user]"] : $fullname_info["$row[user]"]);
|
||||||
|
|
||||||
|
|
||||||
|
$row["caller_code"]=GetCallerCode($row["uniqueid"]);
|
||||||
|
if ($row["direction"]=="I")
|
||||||
|
{
|
||||||
|
$ivr_info_array=GetIVRInfo($row["uniqueid"], $row["call_date"]);
|
||||||
|
$row["ivr"]=$ivr_info_array[0];
|
||||||
|
$row["ivr_duration"]=$ivr_info_array[1];
|
||||||
|
$row["ivr_path"]=$ivr_info_array[2];
|
||||||
|
$row["call_date"]=$ivr_info_array[3];
|
||||||
|
$row["did"]=GetDID($row["uniqueid"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($i>=$ll && $i<$ul || $download_rpt)
|
||||||
|
{
|
||||||
|
$current_row=array();
|
||||||
|
foreach ($selected_columns as $display_name => $column_name)
|
||||||
|
{
|
||||||
|
$current_row["$column_name"]=$row["$column_name"];
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($output_array, $current_row);
|
||||||
|
}
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($sort_index)
|
||||||
|
{
|
||||||
|
#$sort_index=8;
|
||||||
|
# print "***** $sort_index ********\n";
|
||||||
|
# array_multisort($output_array[$sort_index], SORT_ASC, SORT_STRING);
|
||||||
|
|
||||||
|
foreach ($output_array as $sorting_array) {
|
||||||
|
$sort_array_holder[] = $sorting_array["$sort_index"];
|
||||||
|
}
|
||||||
|
if (preg_match('/ desc$/', $sort_answered_details))
|
||||||
|
{
|
||||||
|
array_multisort($sort_array_holder,SORT_DESC, SORT_STRING,$output_array);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_multisort($sort_array_holder,SORT_ASC, SORT_STRING,$output_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
#usort($output_array, function($a, $b){
|
||||||
|
# return strcmp($a[$sort_index], $b[$sort_index]);
|
||||||
|
#});
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($output_array as $data_row)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
foreach ($data_row as $key => $value)
|
||||||
|
{
|
||||||
|
if ($key=="call_date")
|
||||||
|
{
|
||||||
|
$myDateTime = DateTime::createFromFormat('Y-m-d H:i:s', $value);
|
||||||
|
$value = $myDateTime->format('m/d - H:i:s');
|
||||||
|
}
|
||||||
|
if ($key!="detail_id")
|
||||||
|
{
|
||||||
|
$HTML_output.="<td>".$value."</td>";
|
||||||
|
$CSV_output.="\"".$value."\",";
|
||||||
|
}
|
||||||
|
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><IMG SRC=\"images/glass.png\" onClick=\"ShowCallDetails('$value')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP></td>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$CSV_output.="\n";
|
||||||
|
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='left'><B><a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&page_no=1#page_anchor' alt='First page of results'>|<</a> <a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&page_no=".($page_no-1)."#page_anchor' alt='Prev page of results'><<</a></B></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='left'>";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('ANSWERED_DT', '1')\" title=\"First page\" value='|<'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('ANSWERED_DT', '".($page_no-1)."')\" title=\"Prev page\" value='<<'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='center' colspan='".(count($selected_columns)-2)."'>"._QXZ("Export as")."... <a href=\"".$PHP_SELF."?download_rpt=answer_details&sort_answered_details=".$sort_answered_details."\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a> "._QXZ("Current page").": $page_no / $total_pages</td>";
|
||||||
|
$HTML_output.="<td colspan='".(count($selected_columns)-2)."' align='center' class='export_row_cell'>"._QXZ("Export as")."... <input type='button' class='download_button' onClick=\"DownloadReport('ANSWERED_DT', 'answer_details')\" title=\"Export as a CSV file\" value='CSV'> "._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_answered_details=".$sort_answered_details."&page_no=".($page_no+1)."#page_anchor' alt='Next page of results'>>></a> <a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_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('ANSWERED_DT', '".($page_no<$total_pages ? $page_no+1 : $total_pages)."')\" title=\"Next page\" value='>>'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('ANSWERED_DT', '".($total_pages)."')\" title=\"Last page\" value='>|'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
$HTML_output.="<input type=hidden name=page_no id=page_no value='$page_no'>";
|
||||||
|
$HTML_output.="<input type='hidden' name='sort_answered_details' id='sort_answered_details' value='$sort_answered_details'>";
|
||||||
|
|
||||||
|
if ($download_rpt)
|
||||||
|
{
|
||||||
|
$data_to_download=$CSV_output;
|
||||||
|
|
||||||
|
$FILE_TIME = date("Ymd-His");
|
||||||
|
$CSVfilename = "ANSWERED_DT_RPT_".$download_rpt."_".$FILE_TIME.".csv";
|
||||||
|
header('Content-type: application/octet-stream');
|
||||||
|
|
||||||
|
header("Content-Disposition: attachment; filename=\"$CSVfilename\"");
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
ob_clean();
|
||||||
|
flush();
|
||||||
|
|
||||||
|
echo "$data_to_download";
|
||||||
|
|
||||||
|
if ($db_source == 'S')
|
||||||
|
{
|
||||||
|
mysqli_close($link);
|
||||||
|
$use_slave_server=0;
|
||||||
|
$db_source = 'M';
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
$endMS = microtime();
|
||||||
|
$startMSary = explode(" ",$startMS);
|
||||||
|
$endMSary = explode(" ",$endMS);
|
||||||
|
$runS = ($endMSary[0] - $startMSary[0]);
|
||||||
|
$runM = ($endMSary[1] - $startMSary[1]);
|
||||||
|
$TOTALrun = ($runS + $runM);
|
||||||
|
|
||||||
|
# $stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';";
|
||||||
|
# if ($DB) {echo "|$stmt|\n";}
|
||||||
|
# $rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $HTML_output;
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
function GetCallerCode($uniqueid)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
$caller_code="";
|
||||||
|
$cc_stmt="select caller_code from vicidial_log_extended where uniqueid='$uniqueid'";
|
||||||
|
$cc_rslt=mysqli_query($link, $cc_stmt);
|
||||||
|
$cc_row=mysqli_fetch_array($cc_rslt);
|
||||||
|
$caller_code=$cc_row[0];
|
||||||
|
return $caller_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetIVRInfo($uniqueid, $actual_start_time)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
|
||||||
|
$ivr_path="";
|
||||||
|
$ivr_length=0;
|
||||||
|
$ivr_duration=0;
|
||||||
|
|
||||||
|
$ivr_stmt="select extension,start_time,comment_a,comment_b,comment_d,UNIX_TIMESTAMP(start_time),phone_ext from live_inbound_log where uniqueid='$uniqueid' and comment_a IN('CALLMENU') order by start_time";
|
||||||
|
$ivr_rslt=mysqli_query($link, $ivr_stmt);
|
||||||
|
$ivr_paths=array(); # 0 - total calls, 1 - total time, 2 - min time, 3 - max time
|
||||||
|
$ivr_counts=array();
|
||||||
|
while ($ivr_row=mysqli_fetch_array($ivr_rslt))
|
||||||
|
{
|
||||||
|
if(!$prev_time) {$prev_time=$ivr_row[5];}
|
||||||
|
if(!$ivr_start_time)
|
||||||
|
{
|
||||||
|
$actual_start_time=$ivr_row[1];
|
||||||
|
$ivr_start_time=$ivr_row[5];
|
||||||
|
}
|
||||||
|
$ivrpath.=$ivr_row["comment_b"];
|
||||||
|
|
||||||
|
$ivr_duration=$ivr_row[5]-$ivr_start_time;
|
||||||
|
$ivr_length+=$ivr_duration;
|
||||||
|
$prev_time=$ivr_row[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
$ivr_duration_fmt=($ivr_duration>=3600 ? floor($ivr_duration/3600).":" : "").gmdate("i:s", $ivr_duration);
|
||||||
|
$ivr_length_fmt=($ivr_length>=3600 ? floor($ivr_length/3600).":" : "").gmdate("i:s", $ivr_length);
|
||||||
|
|
||||||
|
return array("$ivr_length_fmt", "$ivr_duration_fmt", "$ivr_path", "$actual_start_time");
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetDID($uniqueid)
|
||||||
|
{
|
||||||
|
global $link, $DB, $did_id_info, $did_pattern_info;
|
||||||
|
|
||||||
|
$did_str="";
|
||||||
|
|
||||||
|
$did_stmt="select extension, did_id from vicidial_did_log where uniqueid in ('$uniqueid')";
|
||||||
|
$did_rslt=mysqli_query($link, $did_stmt);
|
||||||
|
$did_row=mysqli_fetch_array($did_rslt);
|
||||||
|
$did_str=$did_row["extension"]." - ".$did_id_info["$did_row[extension]"];
|
||||||
|
|
||||||
|
return $did_str;
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,299 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_AREA_rpt.inc - Vicidial Enhanced Reporting area code/prefix report
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1627 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
# if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];}
|
||||||
|
# elseif (isset($_POST["SUBMIT"])) {$SUBMIT=$_POST["SUBMIT"];}
|
||||||
|
if (isset($_GET["CLI_digits"])) {$CLI_digits=$_GET["CLI_digits"];}
|
||||||
|
elseif (isset($_POST["CLI_digits"])) {$CLI_digits=$_POST["CLI_digits"];}
|
||||||
|
if (isset($_GET["CLI_position"])) {$CLI_position=$_GET["CLI_position"];}
|
||||||
|
elseif (isset($_POST["CLI_position"])) {$CLI_position=$_POST["CLI_position"];}
|
||||||
|
|
||||||
|
$CLI_digits=preg_replace('/[^0-9]/', '', $CLI_digits);
|
||||||
|
$CLI_position=preg_replace('/[^0-9]/', '', $CLI_position);
|
||||||
|
|
||||||
|
if (!$CLI_digits) {$CLI_digits=3;}
|
||||||
|
if (!$CLI_position) {$CLI_position=1;}
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Area Code Report").":</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
|
||||||
|
# $HTML_output.="<form action='".$PHP_SELF."' method='post'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="\t<td>"._QXZ("Number of CLID digits to search").": $NWB#VERM_AREA-CLID$NWE</td>";
|
||||||
|
$HTML_output.="\t<td><select name='CLI_digits' id='CLI_digits'>";
|
||||||
|
for ($i=1; $i<=12; $i++)
|
||||||
|
{
|
||||||
|
$HTML_output.="<option value='$i'".($i==$CLI_digits ? " selected" : "").">$i</option>";
|
||||||
|
}
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="\t<td>"._QXZ("Starting from position").": $NWB#VERM_AREA-starting_position$NWE</td>";
|
||||||
|
$HTML_output.="\t<td><select name='CLI_position' id='CLI_position'>";
|
||||||
|
for ($i=1; $i<=12; $i++)
|
||||||
|
{
|
||||||
|
$HTML_output.="<option value='$i'".($i==$CLI_position ? " selected" : "").">$i</option>";
|
||||||
|
}
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td> </td>";
|
||||||
|
$HTML_output.="<td><input type='submit' name='SUBMIT' class='actButton' value='"._QXZ("SEARCH")."'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
# $HTML_output.="</form>";
|
||||||
|
|
||||||
|
$answered_array=array();
|
||||||
|
$answered_waiting_array=array();
|
||||||
|
$unanswered_array=array();
|
||||||
|
$unanswered_waiting_array=array();
|
||||||
|
$uid_array=array();
|
||||||
|
|
||||||
|
$outb_stmt="select substr(phone_number, $CLI_position, $CLI_digits) as snippet, user, length_in_sec, uniqueid, lead_id from vicidial_log $vicidial_log_SQL $and_NANQUE_clause $exc_addtl_statuses";
|
||||||
|
if ($DB) {$HTML_output.="<B>$outb_stmt</B>";}
|
||||||
|
# print $outb_stmt."\n";
|
||||||
|
$outb_rslt=mysql_to_mysqli($outb_stmt, $link);
|
||||||
|
while ($outb_row=mysqli_fetch_array($outb_rslt))
|
||||||
|
{
|
||||||
|
$snippet=$outb_row["snippet"];
|
||||||
|
$user=$outb_row["user"];
|
||||||
|
$length_in_sec=$outb_row["length_in_sec"];
|
||||||
|
$uniqueid=$outb_row["uniqueid"];
|
||||||
|
$lead_id=$outb_row["lead_id"];
|
||||||
|
|
||||||
|
if (preg_match("/VDAD/", $user))
|
||||||
|
{
|
||||||
|
$xfer_stmt="select close_uniqueid from vicidial_xfer_log where front_uniqueid='$uniqueid'";
|
||||||
|
$xfer_rslt=mysql_to_mysqli($xfer_stmt, $link);
|
||||||
|
# if (mysqli_num_rows($xfer_rslt)==0)
|
||||||
|
# {
|
||||||
|
# while ($xfer_row=mysqli_fetch_row($xfer_rslt))
|
||||||
|
# {
|
||||||
|
#
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# else
|
||||||
|
# {
|
||||||
|
$unanswered_array["$snippet"]["calls"]++;
|
||||||
|
$unanswered_array["$snippet"]["outbound_calls"]++;
|
||||||
|
$unanswered_array["$snippet"]["wait_time"]+=$length_in_sec;
|
||||||
|
|
||||||
|
$unanswered_waiting_array["$snippet"]["calls"]++;
|
||||||
|
$unanswered_waiting_array["$snippet"]["wait_time"]+=$length_in_sec;
|
||||||
|
# }
|
||||||
|
array_push($uid_array, "$uniqueid");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# $length_in_sec=GetAgentLogTalkTime($uniqueid, $user, $lead_id, $length_in_sec);
|
||||||
|
$answered_array["$snippet"]["calls"]++;
|
||||||
|
$answered_array["$snippet"]["outbound_calls"]++;
|
||||||
|
$answered_array["$snippet"]["call_time"]+=$length_in_sec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$inb_stmt="select substr(phone_number, $CLI_position, $CLI_digits) as snippet, user, uniqueid, length_in_sec-queue_seconds as talk_time, queue_seconds, queue_position, lead_id from vicidial_closer_log $vicidial_closer_log_SQL $and_NANQUE_clause $exc_addtl_statuses";
|
||||||
|
if ($DB) {$HTML_output.="<B>$inb_stmt</B>";}
|
||||||
|
# print $inb_stmt."\n";
|
||||||
|
$inb_rslt=mysql_to_mysqli($inb_stmt, $link);
|
||||||
|
while ($inb_row=mysqli_fetch_array($inb_rslt))
|
||||||
|
{
|
||||||
|
$snippet=$inb_row["snippet"];
|
||||||
|
$user=$inb_row["user"];
|
||||||
|
$length_in_sec=$inb_row["talk_time"];
|
||||||
|
$wait_time=$inb_row["queue_seconds"];
|
||||||
|
$uniqueid=$inb_row["uniqueid"];
|
||||||
|
$position=$inb_row["queue_position"];
|
||||||
|
$lead_id=$inb_row["lead_id"];
|
||||||
|
|
||||||
|
if (preg_match("/VDCL/", $user))
|
||||||
|
{
|
||||||
|
# $xfer_stmt="select close_uniqueid from vicidial_xfer_log where front_uniqueid='$uniqueid'";
|
||||||
|
# $xfer_rslt=mysql_to_mysqli($xfer_stmt, $link);
|
||||||
|
# if (mysqli_num_rows($xfer_rslt)==0)
|
||||||
|
# {
|
||||||
|
$unanswered_array["$snippet"]["calls"]++;
|
||||||
|
$unanswered_array["$snippet"]["inbound_calls"]++;
|
||||||
|
$unanswered_array["$snippet"]["wait_time"]+=$wait_time;
|
||||||
|
$unanswered_array["$snippet"]["position"]+=$position;
|
||||||
|
|
||||||
|
$unanswered_waiting_array["$snippet"]["calls"]++;
|
||||||
|
$unanswered_waiting_array["$snippet"]["wait_time"]+=$wait_time;
|
||||||
|
# }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# $length_in_sec=GetAgentLogTalkTime($uniqueid, $user, $lead_id, $length_in_sec);
|
||||||
|
$answered_array["$snippet"]["calls"]++;
|
||||||
|
$answered_array["$snippet"]["inbound_calls"]++;
|
||||||
|
$answered_array["$snippet"]["position"]+=$position;
|
||||||
|
$answered_array["$snippet"]["call_time"]+=$length_in_sec;
|
||||||
|
$answered_array["$snippet"]["wait_time"]+=$wait_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ksort($answered_array);
|
||||||
|
ksort($unanswered_array);
|
||||||
|
|
||||||
|
if ($show_an)
|
||||||
|
{
|
||||||
|
print_r($answered_array);
|
||||||
|
}
|
||||||
|
if ($show_un)
|
||||||
|
{
|
||||||
|
print_r($unanswered_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
##### ANSWERED OUTPUT #####
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Detail for answered calls").": $NWB#VERM_AREA-answered_details$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr><th>"._QXZ("Area code/Caller id")."</th><th>"._QXZ("Taken calls")."</th><th>"._QXZ("Total calling time")."</th><th>"._QXZ("Average time per call")."</th><th>"._QXZ("Average wait time per call")."</th></tr>";
|
||||||
|
|
||||||
|
$CSV_output["answered_area"]="\""._QXZ("Area code/Caller id")."\",\""._QXZ("Taken calls")."\",\""._QXZ("Total calling time")."\",\""._QXZ("Average time per call")."\",\""._QXZ("Average wait time per call")."\"\n";
|
||||||
|
|
||||||
|
$i=0;
|
||||||
|
foreach ($answered_array as $prefix => $data)
|
||||||
|
{
|
||||||
|
$i++;
|
||||||
|
$call_time=($data["call_time"]>=3600 ? intval(floor($data["call_time"]/3600)).date(":i:s", $data["call_time"]) : intval(date("i", $data["call_time"])).":".date("s", $data["call_time"]));
|
||||||
|
|
||||||
|
$average_time=round($data["call_time"]/$data["calls"]);
|
||||||
|
$average_time=($average_time>=3600 ? intval(floor($average_time/3600)).date(":i:s", $average_time) : intval(date("i", $average_time)).":".date("s", $average_time));
|
||||||
|
|
||||||
|
$average_wait_time=round($data["wait_time"]/$data["calls"]);
|
||||||
|
$average_wait_time=($average_wait_time>=3600 ? intval(floor($average_wait_time/3600)).date(":i:s", $average_wait_time) : intval(date("i", $average_wait_time)).":".date("s", $average_wait_time));
|
||||||
|
|
||||||
|
$CSV_output["answered_area"].="\"".$prefix."\",";
|
||||||
|
$CSV_output["answered_area"].="\"".$data["calls"]."\",";
|
||||||
|
$CSV_output["answered_area"].="\"".$call_time."\",";
|
||||||
|
$CSV_output["answered_area"].="\"".$average_time."\",";
|
||||||
|
$CSV_output["answered_area"].="\"".$average_wait_time."\"";
|
||||||
|
$CSV_output["answered_area"].="\n";
|
||||||
|
|
||||||
|
$HTML_output.="<tr bgcolor=\"#".($i%2==0 ? "FFF" : "CCC")."\">";
|
||||||
|
$HTML_output.="<td>".$prefix."</td>";
|
||||||
|
$HTML_output.="<td>".$data["calls"]."</td>";
|
||||||
|
$HTML_output.="<td>".$call_time."</td>";
|
||||||
|
$HTML_output.="<td>".$average_time."</td>";
|
||||||
|
$HTML_output.="<td>".$average_wait_time."</td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' colspan='5'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?CLI_position=$CLI_position&CLI_digits=$CLI_digits&download_rpt=answered_area\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$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>";
|
||||||
|
#############################
|
||||||
|
|
||||||
|
##### UNANSWERED OUTPUT #####
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Detail for unanswered calls").": $NWB#VERM_AREA-unanswered_details$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr><th>"._QXZ("Area code/Caller id")."</th><th>"._QXZ("Lost calls")."</th><th>"._QXZ("Average wait time per call")."</th><th>"._QXZ("Average position")."</th></tr>";
|
||||||
|
|
||||||
|
$CSV_output["unanswered_area"]="\""._QXZ("Area code/Caller id")."\",\""._QXZ("Lost calls")."\",\""._QXZ("Average wait time per call")."\",\""._QXZ("Average position")."\"\n";
|
||||||
|
$i=0;
|
||||||
|
foreach ($unanswered_array as $prefix => $data)
|
||||||
|
{
|
||||||
|
$i++;
|
||||||
|
$call_time=($data["call_time"]>=3600 ? intval(floor($data["call_time"]/3600)).date(":i:s", $data["call_time"]) : intval(date("i", $data["call_time"])).":".date("s", $data["call_time"]));
|
||||||
|
|
||||||
|
$average_position=sprintf("%.1f", ($data["position"]/$data["calls"]));
|
||||||
|
$average_time=($average_time>=3600 ? intval(floor($average_time/3600)).date(":i:s", $average_time) : intval(date("i", $average_time)).":".date("s", $average_time));
|
||||||
|
|
||||||
|
$average_wait_time=round($data["wait_time"]/$data["calls"]);
|
||||||
|
$average_wait_time=($average_wait_time>=3600 ? intval(floor($average_wait_time/3600)).date(":i:s", $average_wait_time) : intval(date("i", $average_wait_time)).":".date("s", $average_wait_time));
|
||||||
|
|
||||||
|
$CSV_output["unanswered_area"].="\"".$prefix."\",";
|
||||||
|
$CSV_output["unanswered_area"].="\"".$data["calls"]."\",";
|
||||||
|
$CSV_output["unanswered_area"].="\"".$average_wait_time."\"";
|
||||||
|
$CSV_output["unanswered_area"].="\"".$average_position."\"";
|
||||||
|
$CSV_output["unanswered_area"].="\n";
|
||||||
|
|
||||||
|
$HTML_output.="<tr bgcolor=\"#".($i%2==0 ? "FFF" : "CCC")."\">";
|
||||||
|
$HTML_output.="<td>".$prefix."</td>";
|
||||||
|
$HTML_output.="<td>".$data["calls"]."</td>";
|
||||||
|
$HTML_output.="<td>".$average_wait_time."</td>";
|
||||||
|
$HTML_output.="<td>".$average_position."</td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' colspan='4'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?CLI_position=$CLI_position&CLI_digits=$CLI_digits&download_rpt=unanswered_area\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$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)
|
||||||
|
{
|
||||||
|
$data_to_download=$CSV_output["$download_rpt"];
|
||||||
|
|
||||||
|
$FILE_TIME = date("Ymd-His");
|
||||||
|
$CSVfilename = "AREA_RPT_".$download_rpt."_".$FILE_TIME.".csv";
|
||||||
|
header('Content-type: application/octet-stream');
|
||||||
|
|
||||||
|
header("Content-Disposition: attachment; filename=\"$CSVfilename\"");
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
ob_clean();
|
||||||
|
flush();
|
||||||
|
|
||||||
|
echo "$data_to_download";
|
||||||
|
|
||||||
|
if ($db_source == 'S')
|
||||||
|
{
|
||||||
|
mysqli_close($link);
|
||||||
|
$use_slave_server=0;
|
||||||
|
$db_source = 'M';
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
$endMS = microtime();
|
||||||
|
$startMSary = explode(" ",$startMS);
|
||||||
|
$endMSary = explode(" ",$endMS);
|
||||||
|
$runS = ($endMSary[0] - $startMSary[0]);
|
||||||
|
$runM = ($endMSary[1] - $startMSary[1]);
|
||||||
|
$TOTALrun = ($runS + $runM);
|
||||||
|
|
||||||
|
# $stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';";
|
||||||
|
# if ($DB) {echo "|$stmt|\n";}
|
||||||
|
# $rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
echo $HTML_output;
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
function GetAgentLogTalkTime($call_uniqueid, $call_user, $call_lead_id, $current_call_time)
|
||||||
|
{
|
||||||
|
global $DB, $link;
|
||||||
|
$val_stmt="select length_in_sec from vicidial_agent_log where lead_id='$call_lead_id' and uniqueid='$call_uniqueid' and user='$call_user' order by event_time asc limit 1";
|
||||||
|
$val_rslt=mysql_to_mysqli($val_stmt, $link);
|
||||||
|
while ($val_row=mysqli_fetch_row($val_rslt))
|
||||||
|
{
|
||||||
|
$talk_sec=$val_row[0];
|
||||||
|
if ($talk_sec<$current_call_time-1 || $talk_sec>$current_call_time+1)
|
||||||
|
{
|
||||||
|
echo "WARNING: $call_uniqueid shows $current_call_time length, agent logs show $talk_sec\n";
|
||||||
|
$current_call_time=$talk_sec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $current_call_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -0,0 +1,243 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_ATT_rpt.inc - Vicidial Enhanced Reporting ACD report
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1626 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
# if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];}
|
||||||
|
# elseif (isset($_POST["SUBMIT"])) {$SUBMIT=$_POST["SUBMIT"];}
|
||||||
|
|
||||||
|
$PHP_SELF=$_SERVER['PHP_SELF'];
|
||||||
|
|
||||||
|
$ACD_queue_counts=array();
|
||||||
|
$ACD_terminal_counts=array();
|
||||||
|
|
||||||
|
# ONLY COUNT ANSWERED CALLS
|
||||||
|
$stmt="select campaign_id, user, status, 0 as ring_time from vicidial_log $vicidial_log_SQL $and_NANQUE_clause UNION ALL select campaign_id, user, status, queue_seconds as ring_time from vicidial_closer_log $vicidial_closer_log_SQL $and_NANQUE_clause";
|
||||||
|
if ($DB) {$HTML_output.="<B>$stmt</B>";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
while ($row=mysqli_fetch_array($rslt))
|
||||||
|
{
|
||||||
|
$campaign_id=$row["campaign_id"];
|
||||||
|
$user=$row["user"];
|
||||||
|
$status=$row["status"];
|
||||||
|
$ring_time=$row["ring_time"];
|
||||||
|
|
||||||
|
if (preg_match('/VDAD|VDCL/', $user) && preg_match('/^DROP$|TIMEOT|WAITTO/', $status))
|
||||||
|
{
|
||||||
|
# UNANSWERED, DO NOTHING
|
||||||
|
$unanswered++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (in_array($status, $lost_statuses_array))
|
||||||
|
{
|
||||||
|
$ACD_queue_counts["$campaign_id"]["lost"]++;
|
||||||
|
$ACD_queue_counts["$campaign_id"]["lost_ring_time"]+=$ring_time;
|
||||||
|
|
||||||
|
$ACD_terminal_counts["$user"]["lost"]++;
|
||||||
|
$ACD_terminal_counts["$user"]["lost_ring_time"]+=$ring_time;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$ACD_queue_counts["$campaign_id"]["calls"]++;
|
||||||
|
$ACD_queue_counts["$campaign_id"]["ring_time"]+=$ring_time;
|
||||||
|
|
||||||
|
$ACD_terminal_counts["$user"]["calls"]++;
|
||||||
|
$ACD_terminal_counts["$user"]["ring_time"]+=$ring_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
$stmt="";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
while ($row=mysqli_fetch_array($rslt))
|
||||||
|
{
|
||||||
|
$campaign_id=$row["campaign_id"];
|
||||||
|
$user=$row["user"];
|
||||||
|
$calls=$row["ct"];
|
||||||
|
$ring_time=$row["ring_time"];
|
||||||
|
|
||||||
|
$ACD_queue_counts["$campaign_id"]["calls"]+=$calls;
|
||||||
|
$ACD_queue_counts["$campaign_id"]["ring_time"]+=$ring_time;
|
||||||
|
|
||||||
|
$ACD_terminal_counts["$user"]["calls"]+=$calls;
|
||||||
|
$ACD_terminal_counts["$user"]["ring_time"]+=$ring_time;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
ksort($ACD_queue_counts);
|
||||||
|
ksort($ACD_terminal_counts);
|
||||||
|
|
||||||
|
|
||||||
|
##### ACD ATTEMPTS BY CAMPAIGN/INGROUP #####
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("ACD attempts by Campaign/ingroup").": $NWB#VERM_ATT-acd_by_queue$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr><th>"._QXZ("Campaign/ingroup")."</th><th>"._QXZ("N. lost")."</th><th>"._QXZ("Avr ring")."</th><th>"._QXZ("Ring (s)")."</th><th>"._QXZ("N. Taken")."</th><th>"._QXZ("Avg ring")."</th><th>"._QXZ("Ring (s)")."</th></tr>";
|
||||||
|
|
||||||
|
$CSV_output["acd_attempts_by_queue"]="\""._QXZ("Campaign/ingroup")."\",\""._QXZ("N. lost")."\",\""._QXZ("Avg ring")."\",\""._QXZ("Ring (s)")."\",\""._QXZ("N. Taken")."\",\""._QXZ("Avg ring")."\",\""._QXZ("Ring (s)")."\"\n";
|
||||||
|
$i=0;
|
||||||
|
foreach ($ACD_queue_counts as $queue => $data)
|
||||||
|
{
|
||||||
|
if (!$data["lost"]) # !$data["lost_ring_time"] || - commented out 6/13/22 because we want avr ring to show zero if there ARE lost.
|
||||||
|
{
|
||||||
|
$avg_lost_time=" - ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$avg_lost_time=round($data["lost_ring_time"]/$data["lost"]);
|
||||||
|
$avg_lost_time=($avg_lost_time>=3600 ? intval(floor($avg_lost_time/3600)).date(":i:s", $avg_lost_time) : intval(date("i", $avg_lost_time)).":".date("s", $avg_lost_time));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$data["ring_time"] || !$data["calls"])
|
||||||
|
{
|
||||||
|
$avg_ring_time="0:00";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$avg_ring_time=round($data["ring_time"]/$data["calls"]);
|
||||||
|
$avg_ring_time=($avg_ring_time>=3600 ? intval(floor($avg_ring_time/3600)).date(":i:s", $avg_ring_time) : intval(date("i", $avg_ring_time)).":".date("s", $avg_ring_time));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$lost_time=($data["lost_ring_time"]>=3600 ? intval(floor($data["lost_ring_time"]/3600)).date(":i:s", $data["lost_ring_time"]) : intval(date("i", $data["lost_ring_time"])).":".date("s", $data["lost_ring_time"]));
|
||||||
|
$ring_time=($data["ring_time"]>=3600 ? intval(floor($data["ring_time"]/3600)).date(":i:s", $data["ring_time"]) : intval(date("i", $data["ring_time"])).":".date("s", $data["ring_time"]));
|
||||||
|
|
||||||
|
$queue_name=$queue_names["$queue"];
|
||||||
|
|
||||||
|
$CSV_output["acd_attempts_by_queue"].="\"".$queue_name."\",";
|
||||||
|
$CSV_output["acd_attempts_by_queue"].="\"".(!$data["lost"] ? "0" : $data["lost"])."\",";
|
||||||
|
$CSV_output["acd_attempts_by_queue"].="\"".$avg_lost_time."\",";
|
||||||
|
$CSV_output["acd_attempts_by_queue"].="\"".$lost_time."\",";
|
||||||
|
$CSV_output["acd_attempts_by_queue"].="\"".(!$data["calls"] ? "0" : $data["calls"])."\",";
|
||||||
|
$CSV_output["acd_attempts_by_queue"].="\"".$avg_ring_time."\",";
|
||||||
|
$CSV_output["acd_attempts_by_queue"].="\"".$ring_time."\",";
|
||||||
|
$CSV_output["acd_attempts_by_queue"].="\n";
|
||||||
|
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>".$queue_name."</td>";
|
||||||
|
$HTML_output.="<td>".(!$data["lost"] ? "0" : $data["lost"])."</td>";
|
||||||
|
$HTML_output.="<td>".$avg_lost_time."</td>";
|
||||||
|
$HTML_output.="<td>".$lost_time."</td>";
|
||||||
|
$HTML_output.="<td>".(!$data["calls"] ? "0": $data["calls"])."</td>";
|
||||||
|
$HTML_output.="<td>".$avg_ring_time."</td>";
|
||||||
|
$HTML_output.="<td>".$ring_time."</td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=acd_attempts_by_queue\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$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>";
|
||||||
|
####################################
|
||||||
|
|
||||||
|
|
||||||
|
##### ACD ATTEMPTS BY AGENT #####
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("ACD attempts by agent").": $NWB#VERM_ATT-acd_by_agent$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr><th>"._QXZ("Agent")."</th><th>"._QXZ("N. lost")."</th><th>"._QXZ("Avr ring")."</th><th>"._QXZ("Ring (s)")."</th><th>"._QXZ("N. Taken")."</th><th>"._QXZ("Avg ring")."</th><th>"._QXZ("Ring (s)")."</th></tr>";
|
||||||
|
|
||||||
|
$CSV_output["acd_attempts_by_terminal"]="\""._QXZ("Campaign/ingroup")."\",\""._QXZ("N. lost")."\",\""._QXZ("Avg ring")."\",\""._QXZ("Ring (s)")."\",\""._QXZ("N. Taken")."\",\""._QXZ("Avg ring")."\",\""._QXZ("Ring (s)")."\"\n";
|
||||||
|
$i=0;
|
||||||
|
foreach ($ACD_terminal_counts as $queue => $data)
|
||||||
|
{
|
||||||
|
if (!$data["lost"]) # !$data["lost_ring_time"] || - commented out 6/13/22 because we want avr ring to show zero if there ARE lost.
|
||||||
|
{
|
||||||
|
$avg_lost_time=" - ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$avg_lost_time=round($data["lost_ring_time"]/$data["lost"]);
|
||||||
|
$avg_lost_time=($avg_lost_time>=3600 ? intval(floor($avg_lost_time/3600)).date(":i:s", $avg_lost_time) : intval(date("i", $avg_lost_time)).":".date("s", $avg_lost_time));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$data["ring_time"] || !$data["calls"])
|
||||||
|
{
|
||||||
|
$avg_ring_time="0:00";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$avg_ring_time=round($data["ring_time"]/$data["calls"]);
|
||||||
|
$avg_ring_time=($avg_ring_time>=3600 ? intval(floor($avg_ring_time/3600)).date(":i:s", $avg_ring_time) : intval(date("i", $avg_ring_time)).":".date("s", $avg_ring_time));
|
||||||
|
}
|
||||||
|
|
||||||
|
$terminal=($show_full_agent_info && $terminal_names["$queue"]!="" ? "$queue - " : "").($terminal_names["$queue"]!="" ? $terminal_names["$queue"] : "($queue)");
|
||||||
|
|
||||||
|
$lost_time=($data["lost_ring_time"]>=3600 ? intval(floor($data["lost_ring_time"]/3600)).date(":i:s", $data["lost_ring_time"]) : intval(date("i", $data["lost_ring_time"])).":".date("s", $data["lost_ring_time"]));
|
||||||
|
$ring_time=($data["ring_time"]>=3600 ? intval(floor($data["ring_time"]/3600)).date(":i:s", $data["ring_time"]) : intval(date("i", $data["ring_time"])).":".date("s", $data["ring_time"]));
|
||||||
|
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\"".$terminal."\",";
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\"".(!$data["lost"] ? "0" : $data["lost"])."\",";
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\"".$avg_lost_time."\",";
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\"".$lost_time."\",";
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\"".(!$data["calls"] ? "0" : $data["calls"])."\",";
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\"".$avg_ring_time."\",";
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\"".$ring_time."\",";
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\n";
|
||||||
|
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>".$terminal."</td>";
|
||||||
|
$HTML_output.="<td>".(!$data["lost"] ? "0": $data["lost"])."</td>";
|
||||||
|
$HTML_output.="<td>".$avg_lost_time."</td>";
|
||||||
|
$HTML_output.="<td>".$lost_time."</td>";
|
||||||
|
$HTML_output.="<td>".(!$data["calls"] ? "0" : $data["calls"])."</td>";
|
||||||
|
$HTML_output.="<td>".$avg_ring_time."</td>";
|
||||||
|
$HTML_output.="<td>".$ring_time."</td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=acd_attempts_by_terminal\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$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)
|
||||||
|
{
|
||||||
|
$data_to_download=$CSV_output["$download_rpt"];
|
||||||
|
|
||||||
|
$FILE_TIME = date("Ymd-His");
|
||||||
|
$CSVfilename = "ATT_RPT_".$download_rpt."_".$FILE_TIME.".csv";
|
||||||
|
header('Content-type: application/octet-stream');
|
||||||
|
|
||||||
|
header("Content-Disposition: attachment; filename=\"$CSVfilename\"");
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
ob_clean();
|
||||||
|
flush();
|
||||||
|
|
||||||
|
echo "$data_to_download";
|
||||||
|
|
||||||
|
if ($db_source == 'S')
|
||||||
|
{
|
||||||
|
mysqli_close($link);
|
||||||
|
$use_slave_server=0;
|
||||||
|
$db_source = 'M';
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
$endMS = microtime();
|
||||||
|
$startMSary = explode(" ",$startMS);
|
||||||
|
$endMSary = explode(" ",$endMS);
|
||||||
|
$runS = ($endMSary[0] - $startMSary[0]);
|
||||||
|
$runM = ($endMSary[1] - $startMSary[1]);
|
||||||
|
$TOTALrun = ($runS + $runM);
|
||||||
|
|
||||||
|
# $stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';";
|
||||||
|
# if ($DB) {echo "|$stmt|\n";}
|
||||||
|
# $rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
echo $HTML_output;
|
||||||
|
?>
|
||||||
@@ -0,0 +1,557 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_CALLS_rpt.inc - Vicidial Enhanced Reporting calls
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1625 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
if (isset($_GET["page_no"])) {$page_no=$_GET["page_no"];}
|
||||||
|
elseif (isset($_POST["page_no"])) {$page_no=$_POST["page_no"];}
|
||||||
|
if (isset($_GET["ans_page_no"])) {$ans_page_no=$_GET["ans_page_no"];}
|
||||||
|
elseif (isset($_POST["ans_page_no"])) {$ans_page_no=$_POST["ans_page_no"];}
|
||||||
|
if (isset($_GET["unans_page_no"])) {$unans_page_no=$_GET["unans_page_no"];}
|
||||||
|
elseif (isset($_POST["unans_page_no"])) {$unans_page_no=$_POST["unans_page_no"];}
|
||||||
|
if (isset($_GET["sort_answered_details"])) {$sort_answered_details=$_GET["sort_answered_details"];}
|
||||||
|
elseif (isset($_POST["sort_answered_details"])) {$sort_answered_details=$_POST["sort_answered_details"];}
|
||||||
|
if (isset($_GET["sort_unanswered_details"])) {$sort_unanswered_details=$_GET["sort_unanswered_details"];}
|
||||||
|
elseif (isset($_POST["sort_unanswered_details"])) {$sort_unanswered_details=$_POST["sort_unanswered_details"];}
|
||||||
|
|
||||||
|
if ($non_latin < 1)
|
||||||
|
{
|
||||||
|
$sort_answered_details = preg_replace('/[^\s-_0-9a-zA-Z]/','',$sort_answered_details);
|
||||||
|
$sort_unanswered_details = preg_replace('/[^\s-_0-9a-zA-Z]/','',$sort_unanswered_details);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_answered_details = preg_replace('/[^\s-_0-9\p{L}]/u','',$sort_answered_details);
|
||||||
|
$sort_unanswered_details = preg_replace('/[^\s-_0-9\p{L}]/u','',$sort_unanswered_details);
|
||||||
|
}
|
||||||
|
$page_no=preg_replace('/[^0-9]/', '', $page_no);
|
||||||
|
$ans_page_no=preg_replace('/[^0-9]/', '', $ans_page_no);
|
||||||
|
$unans_page_no=preg_replace('/[^0-9]/', '', $unans_page_no);
|
||||||
|
|
||||||
|
if (!$ans_page_no || $ans_page_no<1) {$ans_page_no=1;}
|
||||||
|
|
||||||
|
$ans_ll=($ans_page_no-1)*20;
|
||||||
|
$ans_ul=($ans_page_no*20);
|
||||||
|
|
||||||
|
$unans_page_no=preg_replace('/[^0-9]/', '', $unans_page_no);
|
||||||
|
if (!$unans_page_no || $unans_page_no<1) {$unans_page_no=1;}
|
||||||
|
|
||||||
|
$unans_ll=($unans_page_no-1)*20; ### !!! ###
|
||||||
|
$unans_ul=($unans_page_no*20); ### !!! ###
|
||||||
|
|
||||||
|
#### SAME FOR BOTH ANSWERED AND UNANSWERED
|
||||||
|
$available_columns=array(
|
||||||
|
"Date" => "call_date",
|
||||||
|
"Caller" => "phone_number",
|
||||||
|
"Queue" => "campaign_id",
|
||||||
|
"IVR" => "ivr",
|
||||||
|
"Wait" => "wait",
|
||||||
|
"Duration" => "length_in_sec",
|
||||||
|
"Pos." => "queue_position",
|
||||||
|
"Disconnection" => "term_reason",
|
||||||
|
"Transferred to" => "transferred_to",
|
||||||
|
"Handled by" => "user",
|
||||||
|
"Attempts" => "attempts",
|
||||||
|
"Code" => "status",
|
||||||
|
"Stints" => "stints",
|
||||||
|
"Srv" => "srv",
|
||||||
|
"Asterisk UID" => "caller_code",
|
||||||
|
"MOH events" => "moh_events",
|
||||||
|
"MOH duration" => "moh_duration",
|
||||||
|
"IVR duration" => "ivr_duration",
|
||||||
|
"IVR path" => "ivr_path",
|
||||||
|
"DID" => "did",
|
||||||
|
"CRM" => "",
|
||||||
|
"Tag" => "tag",
|
||||||
|
"Feat" => "feat",
|
||||||
|
"Vars" => "vars",
|
||||||
|
"Feature Codes" => "feature_codes",
|
||||||
|
"Variables" => "variables"
|
||||||
|
);
|
||||||
|
|
||||||
|
### !!! ###
|
||||||
|
$selected_columns=array(
|
||||||
|
_QXZ("Date") => "call_date",
|
||||||
|
_QXZ("Caller") => "phone_number",
|
||||||
|
_QXZ("Queue") => "campaign_id",
|
||||||
|
_QXZ("IVR") => "ivr_duration",
|
||||||
|
_QXZ("Wait") => "wait",
|
||||||
|
_QXZ("Duration") => "duration",
|
||||||
|
_QXZ("Pos.") => "queue_position",
|
||||||
|
_QXZ("Disconnection") => "term_reason",
|
||||||
|
_QXZ("Handled by") => "user",
|
||||||
|
_QXZ("Attempts") => "attempts",
|
||||||
|
_QXZ("Code") => "status",
|
||||||
|
"uniqueid" => "detail_id"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
############################################
|
||||||
|
$sort_char=""; ### !!! ###
|
||||||
|
$sort_index=""; ### !!! ###
|
||||||
|
|
||||||
|
$sort_clause=" order by call_date";
|
||||||
|
$sort_index=preg_replace('/ desc/', '', $sort_answered_details);
|
||||||
|
if (preg_match('/ desc$/', $sort_answered_details))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_answered_details);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_answered_details." desc";
|
||||||
|
}
|
||||||
|
$sort_answered_details_preg=preg_replace('/ desc$/', '', $sort_answered_details);
|
||||||
|
|
||||||
|
$stmt="select call_date, phone_number, campaign_id, 0 as ivr, '0:00' as wait, sec_to_time(round(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 did, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, uniqueid as detail_id, 'O' as direction from vicidial_log $vicidial_log_SQL and user not in ('VDAD') UNION select call_date, phone_number, campaign_id, 0 as ivr, sec_to_time(round(queue_seconds)) as wait, sec_to_time(round(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 did, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, CONCAT(uniqueid, '|', closecallid) as detail_id, 'I' as direction from vicidial_closer_log $vicidial_closer_log_SQL and (user!='VDCL') $sort_clause";
|
||||||
|
|
||||||
|
if ($DB) {$HTML_output.="<B>$stmt</B>";}
|
||||||
|
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$total_pages=ceil(mysqli_num_rows($rslt)/20);
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header' id='sad_anchor'>"._QXZ("Answered Call Details").":</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='left'><B><a name='page_anchor' class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&ans_page_no=1#page_anchor' alt='First page of results'>|<</a> <a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&ans_page_no=".($ans_page_no-1)."#page_anchor' alt='Prev page of results'><<</a></B></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='left'>";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"javascript:this.form.action+='#sad_anchor'; GoToDetailsPage('CALLS', '1', 'ans_page_no')\" title=\"First page\" value='|<'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"javascript:this.form.action+='#sad_anchor'; GoToDetailsPage('CALLS', '".($ans_page_no-1)."', 'ans_page_no')\" title=\"Prev page\" value='<<'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='center' colspan='".(count($selected_columns)-2)."'> </td>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='right'><B><a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&ans_page_no=".($ans_page_no+1)."#page_anchor' alt='Next page of results'>>></a> <a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&ans_page_no=".$total_pages."#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=\"javascript:this.form.action+='#sad_anchor'; GoToDetailsPage('CALLS', '".($ans_page_no<$total_pages ? $ans_page_no+1 : $total_pages)."', 'ans_page_no')\" title=\"Next page\" value='>>'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"javascript:this.form.action+='#sad_anchor'; GoToDetailsPage('CALLS', '".($total_pages)."', 'ans_page_no')\" title=\"Last page\" value='>|'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$CSV_output["answer_details"]="";
|
||||||
|
foreach ($selected_columns as $display_name => $column_name)
|
||||||
|
{
|
||||||
|
if ($display_name!="uniqueid")
|
||||||
|
{
|
||||||
|
$CSV_output["answer_details"].="\"$display_name\",";
|
||||||
|
# $HTML_output.="<th><a class='header_link' name='call_detail_sort_".$column_name."' id='call_detail_sort_".$column_name."' href='".$PHP_SELF."?sort_answered_details=".($column_name==$sort_answered_details_preg ? "$reverse_link" : "$column_name")."&ans_page_no=".$ans_page_no."#call_detail_sort_".$column_name."'>".$display_name.($column_name==$sort_answered_details_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='".$display_name.($column_name==$sort_answered_details_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_answered_details').value='".($column_name==$sort_answered_details_preg ? "$reverse_link" : "$column_name")."'; this.form.action+='#sad_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$CSV_output["answer_details"].="\n";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$output_array=array();
|
||||||
|
$i=0;
|
||||||
|
while ($row=mysqli_fetch_array($rslt))
|
||||||
|
{
|
||||||
|
$row["caller_code"]="";
|
||||||
|
$row["ivr"]="00:00";
|
||||||
|
$row["ivr_duration"]="00:00";
|
||||||
|
$row["ivr_path"]="";
|
||||||
|
$row["did"]="";
|
||||||
|
|
||||||
|
$uniqueid=$row["uniqueid"];
|
||||||
|
$row["campaign_id"]=$queue_names["$row[campaign_id]"];
|
||||||
|
$row["status"]=($status_names["$row[status]"] ? $status_names["$row[status]"] : $row["status"]);
|
||||||
|
$row["user"]=$fullname_info["$row[user]"];
|
||||||
|
|
||||||
|
|
||||||
|
$row["caller_code"]=GetCallerCode($row["uniqueid"]);
|
||||||
|
if ($row["direction"]=="I")
|
||||||
|
{
|
||||||
|
$ivr_info_array=GetIVRInfo($row["uniqueid"], $row["call_date"]);
|
||||||
|
$row["ivr"]=$ivr_info_array[0];
|
||||||
|
$row["ivr_duration"]=$ivr_info_array[1];
|
||||||
|
$row["ivr_path"]=$ivr_info_array[2];
|
||||||
|
$row["call_date"]=$ivr_info_array[3];
|
||||||
|
$row["did"]=GetDID($row["uniqueid"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($i>=$ans_ll && $i<$ans_ul || $download_rpt)
|
||||||
|
{
|
||||||
|
$current_row=array();
|
||||||
|
foreach ($selected_columns as $display_name => $column_name)
|
||||||
|
{
|
||||||
|
$current_row["$column_name"]=$row["$column_name"];
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($output_array, $current_row);
|
||||||
|
}
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sort_array_holder=array();
|
||||||
|
if ($sort_index)
|
||||||
|
{
|
||||||
|
#$sort_index=8;
|
||||||
|
# print "***** $sort_index ********\n";
|
||||||
|
# array_multisort($output_array[$sort_index], SORT_ASC, SORT_STRING);
|
||||||
|
|
||||||
|
foreach ($output_array as $sorting_array) {
|
||||||
|
$sort_array_holder[] = $sorting_array["$sort_index"];
|
||||||
|
}
|
||||||
|
if (preg_match('/ desc$/', $sort_answered_details))
|
||||||
|
{
|
||||||
|
array_multisort($sort_array_holder,SORT_DESC, SORT_STRING,$output_array);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_multisort($sort_array_holder,SORT_ASC, SORT_STRING,$output_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
#usort($output_array, function($a, $b){
|
||||||
|
# return strcmp($a[$sort_index], $b[$sort_index]);
|
||||||
|
#});
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($output_array as $data_row)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
foreach ($data_row as $key => $value)
|
||||||
|
{
|
||||||
|
if ($key=="call_date")
|
||||||
|
{
|
||||||
|
$myDateTime = DateTime::createFromFormat('Y-m-d H:i:s', $value);
|
||||||
|
$value = $myDateTime->format('m/d - H:i:s');
|
||||||
|
}
|
||||||
|
if ($key!="detail_id")
|
||||||
|
{
|
||||||
|
$HTML_output.="<td>".$value."</td>";
|
||||||
|
$CSV_output["answer_details"].="\"".$value."\",";
|
||||||
|
}
|
||||||
|
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><IMG SRC=\"images/glass.png\" onClick=\"ShowCallDetails('$value')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP></td>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$CSV_output["answer_details"].="\n";
|
||||||
|
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='left'><B><a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&ans_page_no=1#page_anchor' alt='First page of results'>|<</a> <a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&ans_page_no=".($ans_page_no-1)."#page_anchor' alt='Prev page of results'><<</a></B></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='left'>";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"javascript:this.form.action+='#sad_anchor'; GoToDetailsPage('CALLS', '1', 'ans_page_no')\" title=\"First page\" value='|<'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"javascript:this.form.action+='#sad_anchor'; GoToDetailsPage('CALLS', '".($ans_page_no-1)."', 'ans_page_no')\" title=\"Prev page\" value='<<'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='center' colspan='".(count($selected_columns)-2)."'>"._QXZ("Export as")."... <a href=\"".$PHP_SELF."?download_rpt=answer_details&sort_answered_details=".$sort_answered_details."\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a> Current page: $ans_page_no / $total_pages</td>";
|
||||||
|
$HTML_output.="<td colspan='".(count($selected_columns)-2)."' align='center' class='export_row_cell'>"._QXZ("Export as")."... <input type='button' class='download_button' onClick=\"DownloadReport('CALLS', 'answer_details')\" title=\"Export as a CSV file\" value='CSV'> "._QXZ("Current page").": $ans_page_no / $total_pages</td>";
|
||||||
|
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='right'><B><a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&ans_page_no=".($ans_page_no+1)."#page_anchor' alt='Next page of results'>>></a> <a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&ans_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=\"javascript:this.form.action+='#sad_anchor'; GoToDetailsPage('CALLS', '".($ans_page_no<$total_pages ? $ans_page_no+1 : $total_pages)."', 'ans_page_no')\" title=\"Next page\" value='>>'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"javascript:this.form.action+='#sad_anchor'; GoToDetailsPage('CALLS', '".($total_pages)."', 'ans_page_no')\" title=\"Last page\" value='>|'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
$HTML_output.="<input type=hidden name=ans_page_no id=ans_page_no value='$ans_page_no'>";
|
||||||
|
$HTML_output.="<input type='hidden' name='sort_answered_details' id='sort_answered_details' value='$sort_answered_details'>";
|
||||||
|
############################################
|
||||||
|
|
||||||
|
$HTML_output.="<BR><BR><BR>";
|
||||||
|
|
||||||
|
########## UNANSWERED DETAILS ##############
|
||||||
|
$selected_columns=array(
|
||||||
|
_QXZ("Date") => "call_date",
|
||||||
|
_QXZ("Agent") => "user",
|
||||||
|
_QXZ("Caller") => "phone_number",
|
||||||
|
_QXZ("Queue") => "campaign_id",
|
||||||
|
_QXZ("Disconnection") => "term_reason",
|
||||||
|
_QXZ("Position") => "queue_position",
|
||||||
|
_QXZ("IVR") => "ivr_duration",
|
||||||
|
_QXZ("Wait") => "wait",
|
||||||
|
_QXZ("Attempts") => "attempts",
|
||||||
|
_QXZ("Code") => "status",
|
||||||
|
_QXZ("Key") => "key",
|
||||||
|
"uniqueid" => "detail_id"
|
||||||
|
);
|
||||||
|
|
||||||
|
$sort_char="";
|
||||||
|
$sort_index="";
|
||||||
|
|
||||||
|
$sort_clause=" order by call_date";
|
||||||
|
$sort_index=preg_replace('/ desc/', '', $sort_unanswered_details);
|
||||||
|
if (preg_match('/ desc$/', $sort_unanswered_details))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_unanswered_details);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_unanswered_details." desc";
|
||||||
|
}
|
||||||
|
$sort_unanswered_details_preg=preg_replace('/ desc$/', '', $sort_unanswered_details);
|
||||||
|
|
||||||
|
$stmt="select call_date, phone_number, campaign_id, 0 as ivr, '0:00' as wait, sec_to_time(round(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 did, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, uniqueid as detail_id, 'O' as direction from vicidial_log $vicidial_log_SQL and user in ('VDAD') UNION select call_date, phone_number, campaign_id, 0 as ivr, sec_to_time(round(queue_seconds)) as wait, sec_to_time(round(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 did, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, CONCAT(uniqueid, '|', closecallid) as detail_id, 'I' as direction from vicidial_closer_log $vicidial_closer_log_SQL and user in ('VDCL') $and_NANQUE_clause $sort_clause";
|
||||||
|
|
||||||
|
if ($DB) {$HTML_output.="<B>$stmt</B>";}
|
||||||
|
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$total_pages=ceil(mysqli_num_rows($rslt)/20);
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header' id='sud_anchor'>"._QXZ("Unanswered Call Details").":</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'><a name='make_it_work' id='make_it_work'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='left'><B><a name='page_anchor' class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&unans_page_no=1#page_anchor' alt='First page of results'>|<</a> <a class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&unans_page_no=".($unans_page_no-1)."#page_anchor' alt='Prev page of results'><<</a></B></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='left'>";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"javascript:this.form.action+='#sud_anchor'; GoToDetailsPage('CALLS', '1', 'unans_page_no')\" title=\"First page\" value='|<'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"javascript:this.form.action+='#sud_anchor'; GoToDetailsPage('CALLS', '".($unans_page_no-1)."', 'unans_page_no')\" title=\"Prev page\" value='<<'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='center' colspan='".(count($selected_columns)-2)."'> </td>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='right'><B><a class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&unans_page_no=".($unans_page_no+1)."#page_anchor' alt='Next page of results'>>></a> <a class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&unans_page_no=".$total_pages."#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=\"javascript:this.form.action+='#sud_anchor'; GoToDetailsPage('CALLS', '".($unans_page_no<$total_pages ? $unans_page_no+1 : $total_pages)."', 'unans_page_no')\" title=\"Next page\" value='>>'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"javascript:this.form.action+='#sud_anchor'; GoToDetailsPage('CALLS', '".($total_pages)."', 'unans_page_no')\" title=\"Last page\" value='>|'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$CSV_output["unanswered_details"]="";
|
||||||
|
foreach ($selected_columns as $display_name => $column_name)
|
||||||
|
{
|
||||||
|
if ($display_name!="uniqueid")
|
||||||
|
{
|
||||||
|
$CSV_output["unanswered_details"].="\"$display_name\",";
|
||||||
|
# $HTML_output.="<th><a class='header_link' name='call_detail_sort_".$column_name."' id='call_detail_sort_".$column_name."' href='".$PHP_SELF."?sort_unanswered_details=".($column_name==$sort_unanswered_details_preg ? "$reverse_link" : "$column_name")."&unans_page_no=".$unans_page_no."#call_detail_sort_".$column_name."'>".$display_name.($column_name==$sort_unanswered_details_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='".$display_name.($column_name==$sort_unanswered_details_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_unanswered_details').value='".($column_name==$sort_unanswered_details_preg ? "$reverse_link" : "$column_name")."'; this.form.action+='#sud_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$CSV_output["unanswered_details"].="\n";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$output_array=array();
|
||||||
|
$i=0;
|
||||||
|
while ($row=mysqli_fetch_array($rslt))
|
||||||
|
{
|
||||||
|
$row["caller_code"]="";
|
||||||
|
$row["ivr"]="00:00";
|
||||||
|
$row["ivr_duration"]="00:00";
|
||||||
|
$row["ivr_path"]="";
|
||||||
|
$row["did"]="";
|
||||||
|
|
||||||
|
$uniqueid=$row["uniqueid"];
|
||||||
|
$row["campaign_id"]=$queue_names["$row[campaign_id]"];
|
||||||
|
$row["status"]=($status_names["$row[status]"] ? $status_names["$row[status]"] : $row["status"]);
|
||||||
|
$row["user"]=$fullname_info["$row[user]"];
|
||||||
|
|
||||||
|
$row["key"]=GetKeyPress($row["uniqueid"]);
|
||||||
|
|
||||||
|
$row["caller_code"]=GetCallerCode($row["uniqueid"]);
|
||||||
|
if ($row["direction"]=="I")
|
||||||
|
{
|
||||||
|
$ivr_info_array=GetIVRInfo($row["uniqueid"], $row["call_date"]);
|
||||||
|
$row["ivr"]=$ivr_info_array[0];
|
||||||
|
$row["ivr_duration"]=$ivr_info_array[1];
|
||||||
|
$row["ivr_path"]=$ivr_info_array[2];
|
||||||
|
$row["call_date"]=$ivr_info_array[3];
|
||||||
|
$row["did"]=GetDID($row["uniqueid"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($i>=$unans_ll && $i<$unans_ul || $download_rpt)
|
||||||
|
{
|
||||||
|
$current_row=array();
|
||||||
|
foreach ($selected_columns as $display_name => $column_name)
|
||||||
|
{
|
||||||
|
$current_row["$column_name"]=$row["$column_name"];
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($output_array, $current_row);
|
||||||
|
}
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sort_array_holder=array();
|
||||||
|
if ($sort_index)
|
||||||
|
{
|
||||||
|
#$sort_index=8;
|
||||||
|
# print "***** $sort_index ********\n";
|
||||||
|
# array_multisort($output_array[$sort_index], SORT_ASC, SORT_STRING);
|
||||||
|
|
||||||
|
foreach ($output_array as $sorting_array)
|
||||||
|
{
|
||||||
|
$sort_array_holder[] = $sorting_array["$sort_index"];
|
||||||
|
}
|
||||||
|
if (preg_match('/ desc$/', $sort_unanswered_details))
|
||||||
|
{
|
||||||
|
array_multisort($sort_array_holder,SORT_DESC, SORT_STRING,$output_array);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_multisort($sort_array_holder,SORT_ASC, SORT_STRING,$output_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
#usort($output_array, function($a, $b){
|
||||||
|
# return strcmp($a[$sort_index], $b[$sort_index]);
|
||||||
|
#});
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($output_array as $data_row)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
foreach ($data_row as $key => $value)
|
||||||
|
{
|
||||||
|
if ($key=="call_date")
|
||||||
|
{
|
||||||
|
$myDateTime = DateTime::createFromFormat('Y-m-d H:i:s', $value);
|
||||||
|
$value = $myDateTime->format('m/d - H:i:s');
|
||||||
|
}
|
||||||
|
if ($key!="detail_id")
|
||||||
|
{
|
||||||
|
$HTML_output.="<td>".$value."</td>";
|
||||||
|
$CSV_output["unanswered_details"].="\"".$value."\",";
|
||||||
|
}
|
||||||
|
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><IMG SRC=\"images/glass.png\" onClick=\"ShowCallDetails('$value')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP></td>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$CSV_output["unanswered_details"].="\n";
|
||||||
|
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='left'><B><a class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&unans_page_no=1#page_anchor' alt='First page of results'>|<</a> <a class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&unans_page_no=".($unans_page_no-1)."#page_anchor' alt='Prev page of results'><<</a></B></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='left'>";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"javascript:this.form.action+='#sud_anchor'; GoToDetailsPage('CALLS', '1', 'unans_page_no')\" title=\"First page\" value='|<'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"javascript:this.form.action+='#sud_anchor'; GoToDetailsPage('CALLS', '".($unans_page_no-1)."', 'unans_page_no')\" title=\"Prev page\" value='<<'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='center' colspan='".(count($selected_columns)-2)."'>"._QXZ("Export as")."... <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> Current page: $unans_page_no / $total_pages</td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='center' colspan='".(count($selected_columns)-2)."'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('CALLS', 'unanswered_details')\" title=\"Export as a CSV file\" value='CSV'> Current page: $unans_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."&unans_page_no=".($unans_page_no+1)."#page_anchor' alt='Next page of results'>>></a> <a class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&unans_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=\"javascript:this.form.action+='#sud_anchor'; GoToDetailsPage('CALLS', '".($unans_page_no<$total_pages ? $unans_page_no+1 : $total_pages)."', 'unans_page_no')\" title=\"Next page\" value='>>'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"javascript:this.form.action+='#sud_anchor'; GoToDetailsPage('CALLS', '".($total_pages)."', 'unans_page_no')\" title=\"Last page\" value='>|'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
$HTML_output.="<input type=hidden name=unans_page_no id=unans_page_no value='$unans_page_no'>";
|
||||||
|
$HTML_output.="<input type=hidden name=sort_unanswered_details id=sort_unanswered_details value='$sort_unanswered_details'>";
|
||||||
|
############################################
|
||||||
|
|
||||||
|
if ($download_rpt)
|
||||||
|
{
|
||||||
|
$data_to_download=$CSV_output["$download_rpt"];
|
||||||
|
|
||||||
|
$FILE_TIME = date("Ymd-His");
|
||||||
|
$CSVfilename = "CALLS_RPT_".$download_rpt."_".$FILE_TIME.".csv";
|
||||||
|
header('Content-type: application/octet-stream');
|
||||||
|
|
||||||
|
header("Content-Disposition: attachment; filename=\"$CSVfilename\"");
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
ob_clean();
|
||||||
|
flush();
|
||||||
|
|
||||||
|
echo "$data_to_download";
|
||||||
|
|
||||||
|
if ($db_source == 'S')
|
||||||
|
{
|
||||||
|
mysqli_close($link);
|
||||||
|
$use_slave_server=0;
|
||||||
|
$db_source = 'M';
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
$endMS = microtime();
|
||||||
|
$startMSary = explode(" ",$startMS);
|
||||||
|
$endMSary = explode(" ",$endMS);
|
||||||
|
$runS = ($endMSary[0] - $startMSary[0]);
|
||||||
|
$runM = ($endMSary[1] - $startMSary[1]);
|
||||||
|
$TOTALrun = ($runS + $runM);
|
||||||
|
|
||||||
|
# $stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';";
|
||||||
|
# if ($DB) {echo "|$stmt|\n";}
|
||||||
|
# $rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $HTML_output;
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
function GetCallerCode($uniqueid)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
$caller_code="";
|
||||||
|
$cc_stmt="select caller_code from vicidial_log_extended where uniqueid='$uniqueid'";
|
||||||
|
$cc_rslt=mysqli_query($link, $cc_stmt);
|
||||||
|
$cc_row=mysqli_fetch_array($cc_rslt);
|
||||||
|
$caller_code=$cc_row[0];
|
||||||
|
return $caller_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetKeyPress($uniqueid)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
$keypress="";
|
||||||
|
$keypress_stmt="select extension, max(start_time) From live_inbound_log where uniqueid='$uniqueid' and extension not in ('s', 'i', 't') and comment_a='CALLMENU' group by extension";
|
||||||
|
$keypress_rslt=mysql_to_mysqli($keypress_stmt, $link);
|
||||||
|
$keypress_row=mysqli_fetch_array($keypress_rslt);
|
||||||
|
$keypress=$keypress_row[0];
|
||||||
|
return $keypress;
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetIVRInfo($uniqueid, $actual_start_time)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
|
||||||
|
$ivr_path="";
|
||||||
|
$ivr_length=0;
|
||||||
|
$ivr_duration=0;
|
||||||
|
|
||||||
|
$ivr_stmt="select extension,start_time,comment_a,comment_b,comment_d,UNIX_TIMESTAMP(start_time),phone_ext from live_inbound_log where uniqueid='$uniqueid' and comment_a IN('CALLMENU') order by start_time";
|
||||||
|
$ivr_rslt=mysqli_query($link, $ivr_stmt);
|
||||||
|
$ivr_paths=array(); # 0 - total calls, 1 - total time, 2 - min time, 3 - max time
|
||||||
|
$ivr_counts=array();
|
||||||
|
while ($ivr_row=mysqli_fetch_array($ivr_rslt))
|
||||||
|
{
|
||||||
|
if(!$prev_time) {$prev_time=$ivr_row[5];}
|
||||||
|
if(!$ivr_start_time)
|
||||||
|
{
|
||||||
|
$actual_start_time=$ivr_row[1];
|
||||||
|
$ivr_start_time=$ivr_row[5];
|
||||||
|
}
|
||||||
|
$ivrpath.=$ivr_row["comment_b"];
|
||||||
|
|
||||||
|
$ivr_duration=$ivr_row[5]-$ivr_start_time;
|
||||||
|
$ivr_length+=$ivr_duration;
|
||||||
|
$prev_time=$ivr_row[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
$ivr_duration_fmt=($ivr_duration>=3600 ? floor($ivr_duration/3600).":" : "").gmdate("i:s", $ivr_duration);
|
||||||
|
$ivr_length_fmt=($ivr_length>=3600 ? floor($ivr_length/3600).":" : "").gmdate("i:s", $ivr_length);
|
||||||
|
|
||||||
|
return array("$ivr_length_fmt", "$ivr_duration_fmt", "$ivr_path", "$actual_start_time");
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetDID($uniqueid)
|
||||||
|
{
|
||||||
|
global $link, $DB, $did_id_info, $did_pattern_info;
|
||||||
|
|
||||||
|
$did_str="";
|
||||||
|
|
||||||
|
$did_stmt="select extension, did_id from vicidial_did_log where uniqueid in ('$uniqueid')";
|
||||||
|
$did_rslt=mysqli_query($link, $did_stmt);
|
||||||
|
$did_row=mysqli_fetch_array($did_rslt);
|
||||||
|
$did_str=$did_row["extension"]." - ".$did_id_info["$did_row[extension]"];
|
||||||
|
|
||||||
|
return $did_str;
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,684 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_DAY_rpt.inc - Vicidial Enhanced Reporting per-day report
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1624 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
$vicidial_user_log_table="vicidial_user_log";
|
||||||
|
|
||||||
|
# if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];}
|
||||||
|
# elseif (isset($_POST["SUBMIT"])) {$SUBMIT=$_POST["SUBMIT"];}
|
||||||
|
|
||||||
|
#### CUSTOM REPORT VARIABLES ####
|
||||||
|
#if (isset($_GET["agents"])) {$agents=$_GET["agents"];}
|
||||||
|
# elseif (isset($_POST["agents"])) {$agents=$_POST["agents"];}
|
||||||
|
#if (isset($_GET["locations"])) {$locations=$_GET["locations"];}
|
||||||
|
# elseif (isset($_POST["locations"])) {$locations=$_POST["locations"];}
|
||||||
|
#if (isset($_GET["user_groups"])) {$user_groups=$_GET["user_groups"];}
|
||||||
|
# elseif (isset($_POST["user_groups"])) {$user_groups=$_POST["user_groups"];}
|
||||||
|
#if (isset($_GET["statuses"])) {$statuses=$_GET["statuses"];}
|
||||||
|
# elseif (isset($_POST["statuses"])) {$statuses=$_POST["statuses"];}
|
||||||
|
#if (isset($_GET["disconnection_causes"])) {$disconnection_causes=$_GET["disconnection_causes"];}
|
||||||
|
# elseif (isset($_POST["disconnection_causes"])) {$disconnection_causes=$_POST["disconnection_causes"];}
|
||||||
|
#if (isset($_GET["call_counts"])) {$call_counts=$_GET["call_counts"];}
|
||||||
|
# elseif (isset($_POST["call_counts"])) {$call_counts=$_POST["call_counts"];}
|
||||||
|
#if (isset($_GET["DIDs"])) {$DIDs=$_GET["DIDs"];}
|
||||||
|
# elseif (isset($_POST["DIDs"])) {$DIDs=$_POST["DIDs"];}
|
||||||
|
#if (isset($_GET["IVR_choice"])) {$IVR_choice=$_GET["IVR_choice"];}
|
||||||
|
# elseif (isset($_POST["IVR_choice"])) {$IVR_choice=$_POST["IVR_choice"];}
|
||||||
|
#if (isset($_GET["server"])) {$server=$_GET["server"];}
|
||||||
|
# elseif (isset($_POST["server"])) {$server=$_POST["server"];}
|
||||||
|
#if (isset($_GET["days_of_week"])) {$days_of_week=$_GET["days_of_week"];}
|
||||||
|
# elseif (isset($_POST["days_of_week"])) {$days_of_week=$_POST["days_of_week"];}
|
||||||
|
#if (isset($_GET["hour_of_day"])) {$hour_of_day=$_GET["hour_of_day"];}
|
||||||
|
# elseif (isset($_POST["hour_of_day"])) {$hour_of_day=$_POST["hour_of_day"];}
|
||||||
|
|
||||||
|
### VARIABLES ###
|
||||||
|
$total_calls=0;
|
||||||
|
$total_answered_calls=0;
|
||||||
|
$unanswered_calls=0;
|
||||||
|
$max_call_length=0;
|
||||||
|
$min_call_length=1000000;
|
||||||
|
$total_call_length=0;
|
||||||
|
$max_wait_time=0;
|
||||||
|
$min_wait_time=1000000;
|
||||||
|
$total_wait_time=0;
|
||||||
|
$total_position=0;
|
||||||
|
$max_position=0;
|
||||||
|
$min_position=1000000;
|
||||||
|
$total_distinct_users_per_date=0;
|
||||||
|
$total_agent_login_time=0;
|
||||||
|
$all_calls_array=array(); # Regardless of outcome
|
||||||
|
$calls_array=array(); # Dependent on outcome
|
||||||
|
$answered_calls_array=array(); # Dependent on outcome
|
||||||
|
$unanswered_calls_array=array(); # Dependent on outcome
|
||||||
|
$user_array=array();
|
||||||
|
$agent_login_time_array=array();
|
||||||
|
$sales_array=array();
|
||||||
|
$queue_array=array();
|
||||||
|
|
||||||
|
$agent_call_counts=array();
|
||||||
|
$transferred_counts=array();
|
||||||
|
$agent_call_lengths=array();
|
||||||
|
$queue_stats=array(); # campaign id breakdown BY ANSWERED CALLS
|
||||||
|
$term_reasons=array(); # ANSWERED CALLS ONLY
|
||||||
|
$call_directions=array(); # ANSWERED CALLS
|
||||||
|
$call_stints=array(); # ANSWERED CALLS
|
||||||
|
$agent_events=array(); # ANSWERED CALLS
|
||||||
|
$coverage="100%";
|
||||||
|
$coverage_wi="100%";
|
||||||
|
#################
|
||||||
|
|
||||||
|
|
||||||
|
$stmt="select substr(call_date, 1, 10) as cdate, campaign_id, status, user, length_in_sec as call_length, uniqueid, '0' as wait_sec, 'O' as direction, '1' as queue_position, lead_id from vicidial_log $vicidial_log_SQL $and_NANQUE_clause $exc_addtl_statuses UNION ALL select substr(call_date, 1, 10) as cdate, campaign_id, status, user, length_in_sec-queue_seconds as call_length, uniqueid, queue_seconds as wait_sec, 'I' as direction, queue_position, lead_id from vicidial_closer_log $vicidial_closer_log_SQL $and_NANQUE_clause $exc_addtl_statuses";
|
||||||
|
if ($DB) {$HTML_output.="<B>$stmt</B>";}
|
||||||
|
# print $stmt."\n";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
while ($row=mysqli_fetch_array($rslt))
|
||||||
|
{
|
||||||
|
$call_date=$row["cdate"];
|
||||||
|
$status=$row["status"];
|
||||||
|
$user=$row["user"];
|
||||||
|
$lead_id=$row["lead_id"];
|
||||||
|
$length_in_sec=$row["call_length"];
|
||||||
|
$wait_sec=$row["wait_sec"];
|
||||||
|
$uniqueid=$row["uniqueid"];
|
||||||
|
$direction=$row["direction"];
|
||||||
|
$campaign_id=$row["campaign_id"];
|
||||||
|
$queue_position=$row["queue_position"];
|
||||||
|
|
||||||
|
# $total_calls++; # Doesn't factor out NANQUE
|
||||||
|
|
||||||
|
if ($direction=="I")
|
||||||
|
{
|
||||||
|
$calls_array["$call_date"]["inbound"]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$calls_array["$call_date"]["outbound"]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('/VDAD|VDCL/', $user)) # && preg_match('/^DROP$|TIMEOT|WAITTO/', $status)
|
||||||
|
{
|
||||||
|
$total_unanswered_calls++;
|
||||||
|
|
||||||
|
$unanswered_calls_array["$call_date"]["total_length"]+=$length_in_sec;
|
||||||
|
$unanswered_calls_array["$call_date"]["total_wait"]+=$wait_sec;
|
||||||
|
|
||||||
|
$calls_array["$call_date"]["unanswered"]++;
|
||||||
|
if ($direction=="I")
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["inbound"]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["outbound"]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Min/max call length
|
||||||
|
if (!$unanswered_calls_array["$call_date"]["min_call_length"] || $length_in_sec<$unanswered_calls_array["$call_date"]["min_call_length"])
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["min_call_length"]=$length_in_sec;
|
||||||
|
}
|
||||||
|
if (!$unanswered_calls_array["$call_date"]["max_call_length"] || $length_in_sec>$unanswered_calls_array["$call_date"]["max_call_length"])
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["max_call_length"]=$length_in_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Min/max wait length
|
||||||
|
if (!$unanswered_calls_array["$call_date"]["min_wait_time"] || $wait_sec<$unanswered_calls_array["$call_date"]["min_wait_time"])
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["min_wait_time"]=$wait_sec;
|
||||||
|
}
|
||||||
|
if (!$unanswered_calls_array["$call_date"]["max_wait_time"] || $wait_sec>$unanswered_calls_array["$call_date"]["max_wait_time"])
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["max_wait_time"]=$wait_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$total_answered_calls++;
|
||||||
|
|
||||||
|
|
||||||
|
# Total counts/lengths
|
||||||
|
$calls_array["$call_date"]["answered"]++;
|
||||||
|
$calls_array["$call_date"]["total_length"]+=$length_in_sec;
|
||||||
|
$calls_array["$call_date"]["total_wait"]+=$wait_sec;
|
||||||
|
|
||||||
|
$answered_calls_array["$call_date"]["total_length"]+=$length_in_sec;
|
||||||
|
$answered_calls_array["$call_date"]["total_wait"]+=$wait_sec;
|
||||||
|
|
||||||
|
# Min/max call length
|
||||||
|
if (!$answered_calls_array["$call_date"]["min_call_length"] || $length_in_sec<$answered_calls_array["$call_date"]["min_call_length"])
|
||||||
|
{
|
||||||
|
$answered_calls_array["$call_date"]["min_call_length"]=$length_in_sec;
|
||||||
|
}
|
||||||
|
if (!$answered_calls_array["$call_date"]["max_call_length"] || $length_in_sec>$answered_calls_array["$call_date"]["max_call_length"])
|
||||||
|
{
|
||||||
|
$answered_calls_array["$call_date"]["max_call_length"]=$length_in_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Min/max wait length
|
||||||
|
if (!$answered_calls_array["$call_date"]["min_wait_time"] || $wait_sec<$answered_calls_array["$call_date"]["min_wait_time"])
|
||||||
|
{
|
||||||
|
$answered_calls_array["$call_date"]["min_wait_time"]=$wait_sec;
|
||||||
|
}
|
||||||
|
if (!$answered_calls_array["$call_date"]["max_wait_time"] || $wait_sec>$answered_calls_array["$call_date"]["max_wait_time"])
|
||||||
|
{
|
||||||
|
$answered_calls_array["$call_date"]["max_wait_time"]=$wait_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($direction=="I")
|
||||||
|
{
|
||||||
|
$inbound_calls["$call_date"]++;
|
||||||
|
$answered_calls_array["$call_date"]["inbound"]++;
|
||||||
|
$campaign_id_stmt="select campaign_id from vicidial_agent_log where lead_id='$lead_id' and user='$user' and uniqueid='$uniqueid'";
|
||||||
|
$campaign_id_rslt=mysql_to_mysqli($campaign_id_stmt, $link);
|
||||||
|
if(mysqli_num_rows($campaign_id_rslt)>0)
|
||||||
|
{
|
||||||
|
$campaign_id_row=mysqli_fetch_array($campaign_id_rslt);
|
||||||
|
$campaign_id=$campaign_id_row["campaign_id"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$answered_calls_array["$call_date"]["outbound"]++;
|
||||||
|
$outbound_calls["$call_date"]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
### These counts are in here because by definition these SHOULD be answers, but you never know with some morons.
|
||||||
|
### "Real" campaign_id should have been gotten under the direction clause above
|
||||||
|
if (in_array($status, $sale_array["$campaign_id"]) || in_array($status, $sale_array["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$calls_array["$call_date"]["sales"]++;
|
||||||
|
$total_sales++;
|
||||||
|
}
|
||||||
|
if (in_array($status, $human_ans_array["$campaign_id"]) || in_array($status, $human_ans_array["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$calls_array["$call_date"]["human_answered"]++;
|
||||||
|
$total_human_answered++;
|
||||||
|
}
|
||||||
|
if (in_array($status, $contact_array["$campaign_id"]) || in_array($status, $contact_array["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$calls_array["$call_date"]["customer_contacts"]++;
|
||||||
|
$total_customer_contacts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# User counts
|
||||||
|
if (!array_key_exists("$call_date", $user_array)) {$user_array["$call_date"]=array();}
|
||||||
|
if (!in_array($user, $user_array["$call_date"]) && !preg_match('/VDAD|VDCL/', $user))
|
||||||
|
{
|
||||||
|
$total_distinct_users_per_date++; # Need for adherence report
|
||||||
|
array_push($user_array["$call_date"], $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Sale check
|
||||||
|
if (in_array($status, $sale_array["SYSTEM"]) || (array_key_exists("$campaign_id", $sale_array) && in_array($status, $sale_array["$campaign_id"])))
|
||||||
|
{
|
||||||
|
$sales_array["$call_date"]["sales"]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Contact check
|
||||||
|
if (in_array($status, $contact_array["SYSTEM"]) || (array_key_exists("$campaign_id", $contact_array) && in_array($status, $contact_array["$campaign_id"])))
|
||||||
|
{
|
||||||
|
$sales_array["$call_date"]["contacts"]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Queue array
|
||||||
|
$queue_array["$call_date"]["total_calls"]++;
|
||||||
|
$queue_array["$call_date"]["total_queue"]+=$queue_position;
|
||||||
|
$queue_array["$call_date"]["avg_position"]=($queue_array["$call_date"]["total_queue"]/$queue_array["$call_date"]["total_calls"]);
|
||||||
|
# Min/max queue
|
||||||
|
if (!$queue_array["$call_date"]["min_queue_position"] || $queue_position<$queue_array["$call_date"]["min_queue_position"])
|
||||||
|
{
|
||||||
|
$queue_array["$call_date"]["min_queue_position"]=$queue_position;
|
||||||
|
}
|
||||||
|
if (!$queue_array["$call_date"]["max_queue_position"] || $queue_position>$queue_array["$call_date"]["max_queue_position"])
|
||||||
|
{
|
||||||
|
$queue_array["$call_date"]["max_queue_position"]=$queue_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
$total_calls=$total_answered_calls+$total_unanswered_calls;
|
||||||
|
|
||||||
|
# print_r($calls_array); die;
|
||||||
|
#### ANSWERED CALL DISTRIBUTION PER DAY ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Answered call distribution per day").": $NWB#VERM_DAY-answered_call_distribution$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%' valign='top'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Num")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Answered calls")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Min")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Max")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg Duration")."</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["answered_call_distribution"]="\""._QXZ("Day")."\",\""._QXZ("Num")."\",\"\",\""._QXZ("Answered calls")."\",\""._QXZ("Avg")."\",\""._QXZ("Min")."\",\""._QXZ("Max")."\",\""._QXZ("Avg Duration")."\"\n";
|
||||||
|
|
||||||
|
$max_avg_call_length=0;
|
||||||
|
foreach ($calls_array as $call_date_key => $call_date_data) # Use calls array here to iterate through all dates that have calls
|
||||||
|
{
|
||||||
|
$avg_call_length=round($answered_calls_array["$call_date_key"]["total_length"]/($answered_calls_array["$call_date_key"]["inbound"]+$answered_calls_array["$call_date_key"]["outbound"]));
|
||||||
|
$answered_calls_array["$call_date_key"]["avg_call_length"]=$avg_call_length+0;
|
||||||
|
if ($max_avg_call_length<$avg_call_length) {$max_avg_call_length=$avg_call_length;}
|
||||||
|
}
|
||||||
|
foreach ($answered_calls_array as $call_date_key => $call_date_data)
|
||||||
|
{
|
||||||
|
$total_date_calls=($call_date_data["inbound"]+$call_date_data["outbound"]);
|
||||||
|
$total_date_calls_answered=($answered_calls_array["$call_date_key"]["inbound"]+$answered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
$total_date_calls_unanswered=($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
|
||||||
|
$avg_call_length=round($answered_calls_array["$call_date_key"]["total_length"]/$total_date_calls_answered);
|
||||||
|
$avg_call_length_fmt=($avg_call_length>=3600 ? floor($avg_call_length/3600).":" : "").gmdate("i:s", $avg_call_length);
|
||||||
|
|
||||||
|
$min_call_length_fmt=($answered_calls_array["$call_date_key"]["min_call_length"]>=3600 ? floor($answered_calls_array["$call_date_key"]["min_call_length"]/3600).":" : "").gmdate("i:s", $answered_calls_array["$call_date_key"]["min_call_length"]);
|
||||||
|
$max_call_length_fmt=($answered_calls_array["$call_date_key"]["max_call_length"]>=3600 ? floor($answered_calls_array["$call_date_key"]["max_call_length"]/3600).":" : "").gmdate("i:s", $answered_calls_array["$call_date_key"]["max_call_length"]);
|
||||||
|
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>".$call_date_key."</td>";
|
||||||
|
$HTML_output.="<td>".$total_date_calls_answered."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", ((100*$total_date_calls_answered)/$total_answered_calls))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$total_date_calls_answered)/$total_answered_calls)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$avg_call_length_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$min_call_length_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$max_call_length_fmt."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$avg_call_length)/$max_avg_call_length)."%'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$CSV_output["answered_call_distribution"].="\"".$call_date_key."\",\"".$total_date_calls_answered."\",\"".sprintf("%.1f", ((100*$total_date_calls_answered)/$total_answered_calls))." %\",\"\",\"".$avg_call_length_fmt."\",\"".$min_call_length_fmt."\",\"".$max_call_length_fmt."\",\"\"\n";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='8' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=answered_call_distribution\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='8'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('DAY', 'answered_call_distribution')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$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>";
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
#### ANSWERED CALL WAIT TIME PER DAY ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Answered call wait time per day").": $NWB#VERM_DAY-answered_call_wait_time$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%' valign='top'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Num")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Answered calls")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Min")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Max")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg Duration")."</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["answered_call_wait_time"]="\""._QXZ("Day")."\",\""._QXZ("Num")."\",\"\",\""._QXZ("Answered calls")."\",\""._QXZ("Avg")."\",\""._QXZ("Min")."\",\""._QXZ("Max")."\",\""._QXZ("Avg Duration")."\"\n";
|
||||||
|
|
||||||
|
$max_avg_wait_time=0;
|
||||||
|
foreach ($calls_array as $call_date_key => $call_date_data)
|
||||||
|
{
|
||||||
|
$avg_wait_time=round($answered_calls_array["$call_date_key"]["total_wait"]/($answered_calls_array["$call_date_key"]["inbound"]+$answered_calls_array["$call_date_key"]["outbound"]));
|
||||||
|
$answered_calls_array["$call_date_key"]["avg_wait_time"]=$avg_wait_time+0;
|
||||||
|
if ($max_avg_wait_time<$avg_wait_time) {$max_avg_wait_time=$avg_wait_time;}
|
||||||
|
}
|
||||||
|
foreach ($answered_calls_array as $call_date_key => $call_date_data)
|
||||||
|
{
|
||||||
|
$total_date_calls=($call_date_data["inbound"]+$call_date_data["outbound"]);
|
||||||
|
$total_date_calls_answered=($answered_calls_array["$call_date_key"]["inbound"]+$answered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
$total_date_calls_unanswered=($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
|
||||||
|
$avg_wait_time=round($answered_calls_array["$call_date_key"]["total_wait"]/$total_date_calls_answered);
|
||||||
|
$avg_wait_time_fmt=($avg_wait_time>=3600 ? floor($avg_wait_time/3600).":" : "").gmdate("i:s", $avg_wait_time);
|
||||||
|
|
||||||
|
$min_wait_time_fmt=($answered_calls_array["$call_date_key"]["min_wait_time"]>=3600 ? floor($answered_calls_array["$call_date_key"]["min_wait_time"]/3600).":" : "").gmdate("i:s", $answered_calls_array["$call_date_key"]["min_wait_time"]);
|
||||||
|
$max_wait_time_fmt=($answered_calls_array["$call_date_key"]["max_wait_time"]>=3600 ? floor($answered_calls_array["$call_date_key"]["max_wait_time"]/3600).":" : "").gmdate("i:s", $answered_calls_array["$call_date_key"]["max_wait_time"]);
|
||||||
|
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>".$call_date_key."</td>";
|
||||||
|
$HTML_output.="<td>".$total_date_calls_answered."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", ((100*$total_date_calls_answered)/$total_answered_calls))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$total_date_calls_answered)/$total_answered_calls)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$avg_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$min_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$max_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$avg_wait_time)/$max_avg_wait_time)."%'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$CSV_output["answered_call_wait_time"].="\"".$call_date_key."\",\"".$total_date_calls_answered."\",\"".sprintf("%.1f", ((100*$total_date_calls_answered)/$total_answered_calls))." %\",\"\",\"".$avg_wait_time_fmt."\",\"".$min_wait_time_fmt."\",\"".$max_wait_time_fmt."\",\"\"\n";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='8' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=answered_call_wait_time\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='8'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('DAY', 'answered_call_wait_time')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$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>";
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
#### UNANSWERED CALL WAIT TIME PER DAY ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Unanswered call wait time per day").": $NWB#VERM_DAY-unanswered_call_wait_time$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%' valign='top'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Num")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Unanswered calls")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Min")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Max")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg Duration")."</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["unanswered_call_wait_time"]="\""._QXZ("Day")."\",\""._QXZ("Num")."\",\"\",\""._QXZ("Unanswered calls")."\",\""._QXZ("Avg")."\",\""._QXZ("Min")."\",\""._QXZ("Max")."\",\""._QXZ("Avg Duration")."\"\n";
|
||||||
|
|
||||||
|
$max_avg_wait_time=0;
|
||||||
|
foreach ($calls_array as $call_date_key => $call_date_data)
|
||||||
|
{
|
||||||
|
$avg_wait_time=round($unanswered_calls_array["$call_date_key"]["total_wait"]/($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"]));
|
||||||
|
# print $unanswered_calls_array["$call_date_key"]["total_wait"]."/".($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"])."\n";
|
||||||
|
$unanswered_calls_array["$call_date_key"]["avg_wait_time"]=$avg_wait_time+0;
|
||||||
|
if ($max_avg_wait_time<$avg_wait_time) {$max_avg_wait_time=$avg_wait_time;}
|
||||||
|
}
|
||||||
|
# print_r($unanswered_calls_array); die;
|
||||||
|
foreach ($unanswered_calls_array as $call_date_key => $call_date_data)
|
||||||
|
{
|
||||||
|
$total_date_calls=($call_date_data["inbound"]+$call_date_data["outbound"]);
|
||||||
|
$total_date_calls_answered=($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
$total_date_calls_unanswered=($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
|
||||||
|
$avg_wait_time=round($unanswered_calls_array["$call_date_key"]["total_wait"]/$total_date_calls_unanswered);
|
||||||
|
$avg_wait_time_fmt=($avg_wait_time>=3600 ? floor($avg_wait_time/3600).":" : "").gmdate("i:s", $avg_wait_time);
|
||||||
|
|
||||||
|
$min_wait_time_fmt=($unanswered_calls_array["$call_date_key"]["min_wait_time"]>=3600 ? floor($unanswered_calls_array["$call_date_key"]["min_wait_time"]/3600).":" : "").gmdate("i:s", $unanswered_calls_array["$call_date_key"]["min_wait_time"]);
|
||||||
|
$max_wait_time_fmt=($unanswered_calls_array["$call_date_key"]["max_wait_time"]>=3600 ? floor($unanswered_calls_array["$call_date_key"]["max_wait_time"]/3600).":" : "").gmdate("i:s", $unanswered_calls_array["$call_date_key"]["max_wait_time"]);
|
||||||
|
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>".$call_date_key."</td>";
|
||||||
|
$HTML_output.="<td>".$total_date_calls_unanswered."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", ((100*$total_date_calls_unanswered)/$total_unanswered_calls))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$total_date_calls_unanswered)/$total_unanswered_calls)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$avg_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$min_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$max_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$avg_wait_time)/$max_avg_wait_time)."%'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$CSV_output["unanswered_call_wait_time"].="\"".$call_date_key."\",\"".$total_date_calls_unanswered."\",\"".sprintf("%.1f", ((100*$total_date_calls_unanswered)/$total_unanswered_calls))." %\",\"\",\"".$avg_wait_time_fmt."\",\"".$min_wait_time_fmt."\",\"".$max_wait_time_fmt."\",\"\"\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='8' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=unanswered_call_wait_time\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='8'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('DAY', 'unanswered_call_wait_time')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$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>";
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
#### SALES PER DAY ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Sales per Day").": $NWB#VERM_DAY-sales_per_day$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Human ans. conv")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Customer cont. conv")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Sales")."</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Human answers")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Customer contacts")."</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["sales_per_day"]="\""._QXZ("Day")."\",\""._QXZ("Human ans. conv")."\",\""._QXZ("Customer cont. conv")."\",\""._QXZ("Sales")."\",\"\",\"\",\""._QXZ("Human answers")."\",\""._QXZ("Customer contacts")."\",\"\",\"\"\n";
|
||||||
|
|
||||||
|
#print_r($calls_array);
|
||||||
|
$max_day_sales=max(array_column($calls_array, 'sales'));
|
||||||
|
$max_day_customer_contacts=max(array_column($calls_array, 'customer_contacts'));
|
||||||
|
#print "<BR>$max_day_sales<BR>\n";
|
||||||
|
foreach ($calls_array as $call_date_key => $data)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>$call_date_key</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", ((100*$data["sales"])/$data["human_answered"]))." %</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", ((100*$data["sales"])/$data["customer_contacts"]))." %</td>";
|
||||||
|
$HTML_output.="<td>".($data["sales"]+0)."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", ((100*$data["sales"])/$total_sales))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$data["sales"])/$max_day_sales)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$data["human_answered"]."</td>";
|
||||||
|
$HTML_output.="<td>".$data["customer_contacts"]."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", ((100*$data["customer_contacts"])/$total_customer_contacts))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$data["customer_contacts"])/$max_day_customer_contacts)."%'></td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["sales_per_day"].="\"$call_date_key\",\"".sprintf("%.1f", ((100*$data["sales"])/$data["human_answered"]))." %\",\"".sprintf("%.1f", ((100*$data["sales"])/$data["customer_contacts"]))." %\",\"".($data["sales"]+0)."\",\"".sprintf("%.1f", ((100*$data["sales"])/$total_sales))." %\",\"\",\"".$data["human_answered"]."\",\"".$data["customer_contacts"]."\",\"".sprintf("%.1f", ((100*$data["customer_contacts"])/$total_customer_contacts))." %\",\"\"\n";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='10' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=sales_per_day\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$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>";
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
#### QUEUE LENGTH PER DAY ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Queue length per day").": $NWB#VERM_DAY-queue_length_per_day$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Min")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Max")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
### Removed 5/19/22
|
||||||
|
### $HTML_output.="<th>Cover.</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("ASQPPH")." $NWB#VERM_DAY-queue_length_per_day$NWE</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
### Removed Coverage column before Steps 5/19/22 - not needed
|
||||||
|
$CSV_output["queue_length_per_day"]="\""._QXZ("Day")."\",\""._QXZ("Avg")."\",\"...\",\""._QXZ("Min")."\",\""._QXZ("Max")."\",\"...\",\""._QXZ("Average Sum of Queue Positions Per Hour")."\"\n";
|
||||||
|
|
||||||
|
$max_call_position=max(array_column($queue_array, 'max_queue_position'));
|
||||||
|
$max_avg_position=max(array_column($queue_array, 'avg_position'));
|
||||||
|
foreach ($queue_array as $call_date_key => $data)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>$call_date_key</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", $queue_array["$call_date"]["avg_position"])."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$queue_array["$call_date_key"]["avg_position"])/$max_avg_position)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$queue_array["$call_date_key"]["min_queue_position"]."</td>";
|
||||||
|
$HTML_output.="<td>".$queue_array["$call_date_key"]["max_queue_position"]."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$queue_array["$call_date_key"]["max_queue_position"])/$max_call_position)."%'></td>";
|
||||||
|
### $HTML_output.="<td>100% **</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", $queue_array["$call_date_key"]["total_queue"]/24)."</td>"; # Always seems to be 24 hours for the date - even when I ran starting at 8am.
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["queue_length_per_day"].="\"$call_date_key\",\"".sprintf("%.1f", $queue_array["$call_date"]["avg_position"])."\",\"...\",\"".$queue_array["$call_date_key"]["min_queue_position"]."\",\"".$queue_array["$call_date_key"]["max_queue_position"]."\",\"...\",\"".sprintf("%.1f", $queue_array["$call_date_key"]["total_queue"]/24)."\"\n";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='8' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=queue_length_per_day\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('DAY', 'queue_length_per_day')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$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>";
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
#### SCHEDULE ADHERENCE PER DAY ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Schedule Adherence per Day").": $NWB#VERM_DAY-schedule_adherence$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Agents")."</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["schedule_adherence_per_day"]="\""._QXZ("Day")."\",\""._QXZ("Agents")."\",\"\",\"\"\n";
|
||||||
|
|
||||||
|
foreach ($user_array as $call_date_key => $users_that_day)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>$call_date_key</td>";
|
||||||
|
$HTML_output.="<td>".count($users_that_day)."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", (100*count($users_that_day)/$total_distinct_users_per_date))." %</td>";
|
||||||
|
$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";
|
||||||
|
|
||||||
|
$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";
|
||||||
|
|
||||||
|
for ($i=0; $i<count($users_that_day); $i++)
|
||||||
|
{
|
||||||
|
# Get total agent time
|
||||||
|
$stmt="SELECT event,event_epoch,event_date,campaign_id,user_group,session_id,server_ip,extension,computer_ip,phone_login,phone_ip from ".$vicidial_user_log_table." where user='" . mysqli_real_escape_string($link, $users_that_day[$i]) . "' and event_date >= '" . mysqli_real_escape_string($link, $call_date_key) . " 0:00:01' and event_date <= '" . mysqli_real_escape_string($link, $call_date_key) . " 23:59:59' order by event_date;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
while ($row=mysqli_fetch_row($rslt))
|
||||||
|
{
|
||||||
|
if (preg_match('/LOGIN/', $row[0]))
|
||||||
|
{
|
||||||
|
$event_start_seconds = $row[1];
|
||||||
|
}
|
||||||
|
if (preg_match('/LOGOUT/', $row[0]))
|
||||||
|
{
|
||||||
|
if ($event_start_seconds)
|
||||||
|
{
|
||||||
|
$event_stop_seconds = $row[1];
|
||||||
|
$event_seconds = ($event_stop_seconds - $event_start_seconds);
|
||||||
|
$agent_login_time_array["$call_date_key"]+=$event_seconds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#print_r($agent_login_time_array);
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='4' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=schedule_adherence_per_day\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='4'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('DAY', 'schedule_adherence_per_day')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
|
||||||
|
#### 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;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Answered")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Unanswered")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Num")."</th>";
|
||||||
|
|
||||||
|
$CSV_output["inclusive_sla_per_day"]="\""._QXZ("Day")."\",\""._QXZ("Answered")."\",\""._QXZ("Unanswered")."\",\""._QXZ("Num")."\"";
|
||||||
|
|
||||||
|
for ($i=0; $i<count($SLA_column_names); $i++)
|
||||||
|
{
|
||||||
|
$HTML_output.="<th>".$SLA_column_names[$i]."</th>";
|
||||||
|
$CSV_output["inclusive_sla_per_day"].=",\"".$SLA_column_names[$i]."\"";
|
||||||
|
}
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["inclusive_sla_per_day"].="\n";
|
||||||
|
|
||||||
|
foreach ($calls_array as $call_date_key => $data)
|
||||||
|
{
|
||||||
|
$svc_lvl_stmt="select $SLA_query from vicidial_closer_log where call_date>='".$call_date_key." $start_time' and call_date<='".$call_date_key." $end_time' $and_vicidial_closer_log_SQL and (user!='VDCL')"; # and campaign_id in ($ingroup_str) and user in ('VDCL', $user_str)
|
||||||
|
if ($DB) {$HTML_output.="<B>$svc_lvl_stmt</B><BR>";}
|
||||||
|
$svc_lvl_rslt=mysql_to_mysqli($svc_lvl_stmt, $link);
|
||||||
|
# print $svc_lvl_stmt."\n";
|
||||||
|
$svc_lvl_row=mysqli_fetch_row($svc_lvl_rslt);
|
||||||
|
|
||||||
|
$answered_calls=$answered_calls_array["$call_date_key"]["inbound"]+0;
|
||||||
|
$answered_calls+=$answered_calls_array["$call_date_key"]["outbound"]+0; # "Inclusive" remember
|
||||||
|
|
||||||
|
$HTML_output.="<tr bgcolor='$bgcolor'>";
|
||||||
|
$HTML_output.="<td>$call_date_key</td>";
|
||||||
|
$HTML_output.="<td>".($data["answered"]+0)."</td>";
|
||||||
|
$HTML_output.="<td>".($data["unanswered"]+0)."</td>";
|
||||||
|
$HTML_output.="<td>".($data["answered"]+$data["unanswered"]+0)."</td>";
|
||||||
|
|
||||||
|
$CSV_output["inclusive_sla_per_day"].="\"$call_date_key\",\"".($data["answered"]+0)."\",\"".($data["unanswered"]+0)."\",\"".($data["answered"]+$data["unanswered"]+0)."\"";
|
||||||
|
|
||||||
|
for ($f=0; $f<count($svc_lvl_row); $f++)
|
||||||
|
{
|
||||||
|
$svc_lvl_row[$f]+=$answered_calls_array["$call_date_key"]["outbound"];
|
||||||
|
$HTML_output.="<td align='right'>".sprintf("%.1f", ((100*$svc_lvl_row[$f])/$answered_calls))." %</td>";
|
||||||
|
$CSV_output["inclusive_sla_per_day"].=",\"".sprintf("%.1f", ((100*$svc_lvl_row[$f])/$answered_calls))." %\"";
|
||||||
|
}
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["inclusive_sla_per_day"].="\n";
|
||||||
|
|
||||||
|
$prev_int=$interval;
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='".(4+count($svc_lvl_row))."' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=inclusive_sla_per_day\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='".(4+count($svc_lvl_row))."'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('DAY', 'inclusive_sla_per_day')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
|
||||||
|
if ($download_rpt)
|
||||||
|
{
|
||||||
|
$data_to_download=$CSV_output["$download_rpt"];
|
||||||
|
|
||||||
|
$FILE_TIME = date("Ymd-His");
|
||||||
|
$CSVfilename = "DAY_RPT_".$download_rpt."_".$FILE_TIME.".csv";
|
||||||
|
header('Content-type: application/octet-stream');
|
||||||
|
|
||||||
|
header("Content-Disposition: attachment; filename=\"$CSVfilename\"");
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
ob_clean();
|
||||||
|
flush();
|
||||||
|
|
||||||
|
echo "$data_to_download";
|
||||||
|
|
||||||
|
if ($db_source == 'S')
|
||||||
|
{
|
||||||
|
mysqli_close($link);
|
||||||
|
$use_slave_server=0;
|
||||||
|
$db_source = 'M';
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
$endMS = microtime();
|
||||||
|
$startMSary = explode(" ",$startMS);
|
||||||
|
$endMSary = explode(" ",$endMS);
|
||||||
|
$runS = ($endMSary[0] - $startMSary[0]);
|
||||||
|
$runM = ($endMSary[1] - $startMSary[1]);
|
||||||
|
$TOTALrun = ($runS + $runM);
|
||||||
|
|
||||||
|
# $stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';";
|
||||||
|
# if ($DB) {echo "|$stmt|\n";}
|
||||||
|
# $rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
echo $HTML_output;
|
||||||
|
?>
|
||||||
@@ -0,0 +1,964 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_DOW_rpt.inc - Vicidial Enhanced Reporting per-day-of-week report
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1623 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
# NANQUE, not an unanswered call?
|
||||||
|
# TIMEOT, unanswered even though it was dropped into a call that was picked up
|
||||||
|
# Warm transfers count as two calls
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
$vicidial_user_log_table="vicidial_user_log";
|
||||||
|
|
||||||
|
# if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];}
|
||||||
|
# elseif (isset($_POST["SUBMIT"])) {$SUBMIT=$_POST["SUBMIT"];}
|
||||||
|
|
||||||
|
#### CUSTOM REPORT VARIABLES ####
|
||||||
|
#if (isset($_GET["agents"])) {$agents=$_GET["agents"];}
|
||||||
|
# elseif (isset($_POST["agents"])) {$agents=$_POST["agents"];}
|
||||||
|
#if (isset($_GET["locations"])) {$locations=$_GET["locations"];}
|
||||||
|
# elseif (isset($_POST["locations"])) {$locations=$_POST["locations"];}
|
||||||
|
#if (isset($_GET["user_groups"])) {$user_groups=$_GET["user_groups"];}
|
||||||
|
# elseif (isset($_POST["user_groups"])) {$user_groups=$_POST["user_groups"];}
|
||||||
|
#if (isset($_GET["statuses"])) {$statuses=$_GET["statuses"];}
|
||||||
|
# elseif (isset($_POST["statuses"])) {$statuses=$_POST["statuses"];}
|
||||||
|
#if (isset($_GET["disconnection_causes"])) {$disconnection_causes=$_GET["disconnection_causes"];}
|
||||||
|
# elseif (isset($_POST["disconnection_causes"])) {$disconnection_causes=$_POST["disconnection_causes"];}
|
||||||
|
#if (isset($_GET["call_counts"])) {$call_counts=$_GET["call_counts"];}
|
||||||
|
# elseif (isset($_POST["call_counts"])) {$call_counts=$_POST["call_counts"];}
|
||||||
|
#if (isset($_GET["DIDs"])) {$DIDs=$_GET["DIDs"];}
|
||||||
|
# elseif (isset($_POST["DIDs"])) {$DIDs=$_POST["DIDs"];}
|
||||||
|
#if (isset($_GET["IVR_choice"])) {$IVR_choice=$_GET["IVR_choice"];}
|
||||||
|
# elseif (isset($_POST["IVR_choice"])) {$IVR_choice=$_POST["IVR_choice"];}
|
||||||
|
#if (isset($_GET["server"])) {$server=$_GET["server"];}
|
||||||
|
# elseif (isset($_POST["server"])) {$server=$_POST["server"];}
|
||||||
|
#if (isset($_GET["days_of_week"])) {$days_of_week=$_GET["days_of_week"];}
|
||||||
|
# elseif (isset($_POST["days_of_week"])) {$days_of_week=$_POST["days_of_week"];}
|
||||||
|
#if (isset($_GET["hour_of_day"])) {$hour_of_day=$_GET["hour_of_day"];}
|
||||||
|
# elseif (isset($_POST["hour_of_day"])) {$hour_of_day=$_POST["hour_of_day"];}
|
||||||
|
|
||||||
|
/*
|
||||||
|
$start_date='2021-12-14';
|
||||||
|
$start_time='00:00:00';
|
||||||
|
$end_date='2021-12-20';
|
||||||
|
$end_time='23:59:59';
|
||||||
|
*/
|
||||||
|
|
||||||
|
### VARIABLES ###
|
||||||
|
$total_calls=0;
|
||||||
|
$total_answered_calls=0;
|
||||||
|
$unanswered_calls=0;
|
||||||
|
$max_call_length=0;
|
||||||
|
$min_call_length=1000000;
|
||||||
|
$total_call_length=0;
|
||||||
|
$max_wait_time=0;
|
||||||
|
$min_wait_time=1000000;
|
||||||
|
$total_wait_time=0;
|
||||||
|
$total_position=0;
|
||||||
|
$max_position=0;
|
||||||
|
$min_position=1000000;
|
||||||
|
$total_distinct_users_per_date=0;
|
||||||
|
$total_agent_login_time=0;
|
||||||
|
$all_calls_array=array(); # Regardless of outcome
|
||||||
|
$calls_array=array(); # Dependent on outcome
|
||||||
|
$answered_calls_array=array(); # Dependent on outcome
|
||||||
|
$unanswered_calls_array=array(); # Dependent on outcome
|
||||||
|
$user_array=array();
|
||||||
|
$agent_login_time_array=array();
|
||||||
|
$sales_array=array();
|
||||||
|
$queue_array=array();
|
||||||
|
|
||||||
|
$agent_call_counts=array();
|
||||||
|
$transferred_counts=array();
|
||||||
|
$agent_call_lengths=array();
|
||||||
|
$queue_stats=array(); # campaign id breakdown BY ANSWERED CALLS
|
||||||
|
$term_reasons=array(); # ANSWERED CALLS ONLY
|
||||||
|
$call_directions=array(); # ANSWERED CALLS
|
||||||
|
$call_stints=array(); # ANSWERED CALLS
|
||||||
|
$agent_events=array(); # ANSWERED CALLS
|
||||||
|
$coverage="100%";
|
||||||
|
$coverage_wi="100%";
|
||||||
|
#################
|
||||||
|
|
||||||
|
# Initialize variables so inactive days of the week populate...
|
||||||
|
|
||||||
|
for ($q=0; $q<=6; $q++)
|
||||||
|
{
|
||||||
|
$key = date('l', strtotime("Sunday +{$q} days"));
|
||||||
|
|
||||||
|
$calls_array["$key"]["outbound"]=0;
|
||||||
|
$calls_array["$key"]["inbound"]=0;
|
||||||
|
$calls_array["$key"]["human_answered"]=0;
|
||||||
|
$calls_array["$key"]["customer_contacts"]=0;
|
||||||
|
|
||||||
|
$unanswered_calls_array["$key"]["outbound"]=0;
|
||||||
|
$unanswered_calls_array["$key"]["inbound"]=0;
|
||||||
|
|
||||||
|
$answered_calls_array["$key"]["outbound"]=0;
|
||||||
|
$answered_calls_array["$key"]["inbound"]=0;
|
||||||
|
|
||||||
|
$queue_array["$key"]["total_calls"]=0;
|
||||||
|
$queue_array["$key"]["total_queue"]=0;
|
||||||
|
$queue_array["$key"]["min_queue_position"]=0;
|
||||||
|
$queue_array["$key"]["max_queue_position"]=0;
|
||||||
|
$queue_array["$key"]["avg_position"]=0;
|
||||||
|
|
||||||
|
$user_array["$key"]=array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="select dayname(call_date) as cdate, dayofweek(call_date) as day_no, campaign_id, status, user, length_in_sec as call_length, uniqueid, '0' as wait_sec, 'O' as direction, '1' as queue_position, lead_id from vicidial_log $vicidial_log_SQL $and_NANQUE_clause $exc_addtl_statuses UNION ALL select dayname(call_date) as cdate, dayofweek(call_date) as day_no, campaign_id, status, user, length_in_sec-queue_seconds as call_length, uniqueid, queue_seconds as wait_sec, 'I' as direction, queue_position, lead_id from vicidial_closer_log $vicidial_closer_log_SQL $and_NANQUE_clause $exc_addtl_statuses order by day_no";
|
||||||
|
if ($DB) {$HTML_output.="<B>$stmt</B>";}
|
||||||
|
# print $stmt."\n";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
while ($row=mysqli_fetch_array($rslt))
|
||||||
|
{
|
||||||
|
$call_date=$row["cdate"];
|
||||||
|
$status=$row["status"];
|
||||||
|
$user=$row["user"];
|
||||||
|
$lead_id=$row["lead_id"];
|
||||||
|
$length_in_sec=$row["call_length"];
|
||||||
|
$wait_sec=$row["wait_sec"];
|
||||||
|
$uniqueid=$row["uniqueid"];
|
||||||
|
$direction=$row["direction"];
|
||||||
|
$campaign_id=$row["campaign_id"];
|
||||||
|
$queue_position=$row["queue_position"];
|
||||||
|
|
||||||
|
# $total_calls++; # Doesn't factor out NANQUE
|
||||||
|
|
||||||
|
if ($direction=="I")
|
||||||
|
{
|
||||||
|
$calls_array["$call_date"]["inbound"]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$calls_array["$call_date"]["outbound"]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('/VDAD|VDCL/', $user)) # && preg_match('/^DROP$|TIMEOT|WAITTO/', $status)
|
||||||
|
{
|
||||||
|
$total_unanswered_calls++;
|
||||||
|
|
||||||
|
$unanswered_calls_array["$call_date"]["total_length"]+=$length_in_sec;
|
||||||
|
$unanswered_calls_array["$call_date"]["total_wait"]+=$wait_sec;
|
||||||
|
|
||||||
|
$calls_array["$call_date"]["unanswered"]++;
|
||||||
|
if ($direction=="I")
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["inbound"]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["outbound"]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Min/max call length
|
||||||
|
if (!$unanswered_calls_array["$call_date"]["min_call_length"] || $length_in_sec<$unanswered_calls_array["$call_date"]["min_call_length"])
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["min_call_length"]=$length_in_sec;
|
||||||
|
}
|
||||||
|
if (!$unanswered_calls_array["$call_date"]["max_call_length"] || $length_in_sec>$unanswered_calls_array["$call_date"]["max_call_length"])
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["max_call_length"]=$length_in_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Min/max wait length
|
||||||
|
if (!$unanswered_calls_array["$call_date"]["min_wait_time"] || $wait_sec<$unanswered_calls_array["$call_date"]["min_wait_time"])
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["min_wait_time"]=$wait_sec;
|
||||||
|
}
|
||||||
|
if (!$unanswered_calls_array["$call_date"]["max_wait_time"] || $wait_sec>$unanswered_calls_array["$call_date"]["max_wait_time"])
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["max_wait_time"]=$wait_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$total_answered_calls++;
|
||||||
|
|
||||||
|
|
||||||
|
# Total counts/lengths
|
||||||
|
$calls_array["$call_date"]["answered"]++;
|
||||||
|
$calls_array["$call_date"]["total_length"]+=$length_in_sec;
|
||||||
|
$calls_array["$call_date"]["total_wait"]+=$wait_sec;
|
||||||
|
|
||||||
|
$answered_calls_array["$call_date"]["total_length"]+=$length_in_sec;
|
||||||
|
$answered_calls_array["$call_date"]["total_wait"]+=$wait_sec;
|
||||||
|
|
||||||
|
# Min/max call length
|
||||||
|
if (!$answered_calls_array["$call_date"]["min_call_length"] || $length_in_sec<$answered_calls_array["$call_date"]["min_call_length"])
|
||||||
|
{
|
||||||
|
$answered_calls_array["$call_date"]["min_call_length"]=$length_in_sec;
|
||||||
|
}
|
||||||
|
if (!$answered_calls_array["$call_date"]["max_call_length"] || $length_in_sec>$answered_calls_array["$call_date"]["max_call_length"])
|
||||||
|
{
|
||||||
|
$answered_calls_array["$call_date"]["max_call_length"]=$length_in_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Min/max wait length
|
||||||
|
if (!$answered_calls_array["$call_date"]["min_wait_time"] || $wait_sec<$answered_calls_array["$call_date"]["min_wait_time"])
|
||||||
|
{
|
||||||
|
$answered_calls_array["$call_date"]["min_wait_time"]=$wait_sec;
|
||||||
|
}
|
||||||
|
if (!$answered_calls_array["$call_date"]["max_wait_time"] || $wait_sec>$answered_calls_array["$call_date"]["max_wait_time"])
|
||||||
|
{
|
||||||
|
$answered_calls_array["$call_date"]["max_wait_time"]=$wait_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($direction=="I")
|
||||||
|
{
|
||||||
|
$inbound_calls["$call_date"]++;
|
||||||
|
$answered_calls_array["$call_date"]["inbound"]++;
|
||||||
|
$campaign_id_stmt="select campaign_id from vicidial_agent_log where lead_id='$lead_id' and user='$user' and uniqueid='$uniqueid'";
|
||||||
|
$campaign_id_rslt=mysql_to_mysqli($campaign_id_stmt, $link);
|
||||||
|
if(mysqli_num_rows($campaign_id_rslt)>0)
|
||||||
|
{
|
||||||
|
$campaign_id_row=mysqli_fetch_array($campaign_id_rslt);
|
||||||
|
$campaign_id=$campaign_id_row["campaign_id"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$answered_calls_array["$call_date"]["outbound"]++;
|
||||||
|
$outbound_calls["$call_date"]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
### These counts are in here because by definition these SHOULD be answers, but you never know with some morons.
|
||||||
|
### "Real" campaign_id should have been gotten under the direction clause above
|
||||||
|
if (in_array($status, $sale_array["$campaign_id"]) || in_array($status, $sale_array["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$calls_array["$call_date"]["sales"]++;
|
||||||
|
$total_sales++;
|
||||||
|
}
|
||||||
|
if (in_array($status, $human_ans_array["$campaign_id"]) || in_array($status, $human_ans_array["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$calls_array["$call_date"]["human_answered"]++;
|
||||||
|
$total_human_answered++;
|
||||||
|
}
|
||||||
|
if (in_array($status, $contact_array["$campaign_id"]) || in_array($status, $contact_array["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$calls_array["$call_date"]["customer_contacts"]++;
|
||||||
|
$total_customer_contacts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# User counts
|
||||||
|
if (!array_key_exists("$call_date", $user_array)) {$user_array["$call_date"]=array();}
|
||||||
|
if (!in_array($user, $user_array["$call_date"]) && !preg_match('/VDAD|VDCL/', $user))
|
||||||
|
{
|
||||||
|
$total_distinct_users_per_date++; # Need for adherence report
|
||||||
|
array_push($user_array["$call_date"], $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Sale check
|
||||||
|
if (in_array($status, $sale_array["SYSTEM"]) || (array_key_exists("$campaign_id", $sale_array) && in_array($status, $sale_array["$campaign_id"])))
|
||||||
|
{
|
||||||
|
$sales_array["$call_date"]["sales"]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Contact check
|
||||||
|
if (in_array($status, $contact_array["SYSTEM"]) || (array_key_exists("$campaign_id", $contact_array) && in_array($status, $contact_array["$campaign_id"])))
|
||||||
|
{
|
||||||
|
$sales_array["$call_date"]["contacts"]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Queue array
|
||||||
|
$queue_array["$call_date"]["total_calls"]++;
|
||||||
|
$queue_array["$call_date"]["total_queue"]+=$queue_position;
|
||||||
|
$queue_array["$call_date"]["avg_position"]=($queue_array["$call_date"]["total_queue"]/$queue_array["$call_date"]["total_calls"]);
|
||||||
|
# Min/max queue
|
||||||
|
if (!$queue_array["$call_date"]["min_queue_position"] || $queue_position<$queue_array["$call_date"]["min_queue_position"])
|
||||||
|
{
|
||||||
|
$queue_array["$call_date"]["min_queue_position"]=$queue_position;
|
||||||
|
}
|
||||||
|
if (!$queue_array["$call_date"]["max_queue_position"] || $queue_position>$queue_array["$call_date"]["max_queue_position"])
|
||||||
|
{
|
||||||
|
$queue_array["$call_date"]["max_queue_position"]=$queue_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
$total_calls=$total_answered_calls+$total_unanswered_calls;
|
||||||
|
|
||||||
|
# print_r($user_array); die;
|
||||||
|
#### ANSWERED CALL DISTRIBUTION PER DAY OF WEEK ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Answered call distribution per day of week").": $NWB#VERM_DOW-answered_call_distribution$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%' valign='top'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Num")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Answered calls")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Min")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Max")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg Duration")."</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["answered_call_distribution"]="\""._QXZ("Day")."\",\""._QXZ("Num")."\",\"\",\""._QXZ("Answered calls")."\",\""._QXZ("Avg")."\",\""._QXZ("Min")."\",\""._QXZ("Max")."\",\""._QXZ("Avg Duration")."\"\n";
|
||||||
|
|
||||||
|
$answered_call_distribution_graph_labels="[";
|
||||||
|
$answered_call_distribution_graph_data1="[";
|
||||||
|
$answered_call_distribution_graph_bgcolor1="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$answered_call_distribution_graph_hovborder1="[";
|
||||||
|
$answered_call_distribution_graph_data2="[";
|
||||||
|
$answered_call_distribution_graph_bgcolor2="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$answered_call_distribution_graph_hovborder2="[";
|
||||||
|
|
||||||
|
$max_avg_call_length=0;
|
||||||
|
foreach ($calls_array as $call_date_key => $call_date_data) # Use calls array here to iterate through all dates that have calls
|
||||||
|
{
|
||||||
|
$avg_call_length=round(MathZDC($answered_calls_array["$call_date_key"]["total_length"], ($answered_calls_array["$call_date_key"]["inbound"]+$answered_calls_array["$call_date_key"]["outbound"])));
|
||||||
|
$answered_calls_array["$call_date_key"]["avg_call_length"]=$avg_call_length+0;
|
||||||
|
if ($max_avg_call_length<$avg_call_length) {$max_avg_call_length=$avg_call_length;}
|
||||||
|
}
|
||||||
|
foreach ($answered_calls_array as $call_date_key => $call_date_data)
|
||||||
|
{
|
||||||
|
$total_date_calls=($call_date_data["inbound"]+$call_date_data["outbound"]);
|
||||||
|
$total_date_calls_answered=($answered_calls_array["$call_date_key"]["inbound"]+$answered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
$total_date_calls_unanswered=($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
|
||||||
|
$avg_call_length=round(MathZDC($answered_calls_array["$call_date_key"]["total_length"], $total_date_calls_answered));
|
||||||
|
$avg_call_length_fmt=($avg_call_length>=3600 ? floor($avg_call_length/3600).":" : "").gmdate("i:s", $avg_call_length);
|
||||||
|
|
||||||
|
$min_call_length_fmt=($answered_calls_array["$call_date_key"]["min_call_length"]>=3600 ? floor($answered_calls_array["$call_date_key"]["min_call_length"]/3600).":" : "").gmdate("i:s", $answered_calls_array["$call_date_key"]["min_call_length"]);
|
||||||
|
$max_call_length_fmt=($answered_calls_array["$call_date_key"]["max_call_length"]>=3600 ? floor($answered_calls_array["$call_date_key"]["max_call_length"]/3600).":" : "").gmdate("i:s", $answered_calls_array["$call_date_key"]["max_call_length"]);
|
||||||
|
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>".$call_date_key."</td>";
|
||||||
|
$HTML_output.="<td>".$total_date_calls_answered."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", ((100*$total_date_calls_answered)/$total_answered_calls))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$total_date_calls_answered)/$total_answered_calls)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$avg_call_length_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$min_call_length_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$max_call_length_fmt."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$avg_call_length)/$max_avg_call_length)."%'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$CSV_output["answered_call_distribution"].="\"".$call_date_key."\",\"".$total_date_calls_answered."\",\"".sprintf("%.1f", ((100*$total_date_calls_answered)/$total_answered_calls))." %\",\"\",\"".$avg_call_length_fmt."\",\"".$min_call_length_fmt."\",\"".$max_call_length_fmt."\",\"\"\n";
|
||||||
|
|
||||||
|
$answered_call_distribution_graph_labels.="\"$call_date_key\",";
|
||||||
|
$answered_call_distribution_graph_data1.="\"$total_date_calls_answered\",";
|
||||||
|
$answered_call_distribution_graph_bgcolor1.="\"".$background_colors[0]."\",";
|
||||||
|
$answered_call_distribution_graph_hovborder1.="\"".$border_colors[0]."\",";
|
||||||
|
$answered_call_distribution_graph_data2.="\"$avg_call_length\",";
|
||||||
|
$answered_call_distribution_graph_bgcolor2.="\"".$background_colors[1]."\",";
|
||||||
|
$answered_call_distribution_graph_hovborder2.="\"".$border_colors[1]."\",";
|
||||||
|
}
|
||||||
|
$answered_call_distribution_graph_labels=preg_replace('/,$/', '', $answered_call_distribution_graph_labels)."]";
|
||||||
|
$answered_call_distribution_graph_data1=preg_replace('/,$/', '', $answered_call_distribution_graph_data1)."]";
|
||||||
|
$answered_call_distribution_graph_bgcolor1=preg_replace('/,$/', '', $answered_call_distribution_graph_bgcolor1)."]";
|
||||||
|
$answered_call_distribution_graph_hovborder1=preg_replace('/,$/', '', $answered_call_distribution_graph_hovborder1)."]";
|
||||||
|
$answered_call_distribution_graph_data2=preg_replace('/,$/', '', $answered_call_distribution_graph_data2)."]";
|
||||||
|
$answered_call_distribution_graph_bgcolor2=preg_replace('/,$/', '', $answered_call_distribution_graph_bgcolor2)."]";
|
||||||
|
$answered_call_distribution_graph_hovborder2=preg_replace('/,$/', '', $answered_call_distribution_graph_hovborder2)."]";
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='8' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=answered_call_distribution\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='8'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('DOW', 'answered_call_distribution')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$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>";
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
#### ANSWERED CALL WAIT TIME PER DAY OF WEEK ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Answered call wait time per day of week").": $NWB#VERM_DOW-answered_call_wait_time$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%' valign='top'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Num")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Answered calls")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Min")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Max")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg Duration")."</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["answered_call_wait_time"]="\""._QXZ("Day")."\",\""._QXZ("Num")."\",\"\",\""._QXZ("Answered calls")."\",\""._QXZ("Avg")."\",\""._QXZ("Min")."\",\""._QXZ("Max")."\",\""._QXZ("Avg Duration")."\"\n";
|
||||||
|
|
||||||
|
$answered_call_wait_time_graph_labels="[";
|
||||||
|
$answered_call_wait_time_graph_data1="[";
|
||||||
|
$answered_call_wait_time_graph_bgcolor1="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$answered_call_wait_time_graph_hovborder1="[";
|
||||||
|
$answered_call_wait_time_graph_data2="[";
|
||||||
|
$answered_call_wait_time_graph_bgcolor2="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$answered_call_wait_time_graph_hovborder2="[";
|
||||||
|
|
||||||
|
$max_avg_wait_time=0;
|
||||||
|
foreach ($calls_array as $call_date_key => $call_date_data)
|
||||||
|
{
|
||||||
|
$avg_wait_time=round(MathZDC($answered_calls_array["$call_date_key"]["total_wait"], ($answered_calls_array["$call_date_key"]["inbound"]+$answered_calls_array["$call_date_key"]["outbound"])));
|
||||||
|
$answered_calls_array["$call_date_key"]["avg_wait_time"]=$avg_wait_time+0;
|
||||||
|
if ($max_avg_wait_time<$avg_wait_time) {$max_avg_wait_time=$avg_wait_time;}
|
||||||
|
}
|
||||||
|
foreach ($answered_calls_array as $call_date_key => $call_date_data)
|
||||||
|
{
|
||||||
|
$total_date_calls=($call_date_data["inbound"]+$call_date_data["outbound"]);
|
||||||
|
$total_date_calls_answered=($answered_calls_array["$call_date_key"]["inbound"]+$answered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
$total_date_calls_unanswered=($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
|
||||||
|
$avg_wait_time=round(MathZDC($answered_calls_array["$call_date_key"]["total_wait"], $total_date_calls_answered));
|
||||||
|
$avg_wait_time_fmt=($avg_wait_time>=3600 ? floor($avg_wait_time/3600).":" : "").gmdate("i:s", $avg_wait_time);
|
||||||
|
|
||||||
|
$min_wait_time_fmt=($answered_calls_array["$call_date_key"]["min_wait_time"]>=3600 ? floor($answered_calls_array["$call_date_key"]["min_wait_time"]/3600).":" : "").gmdate("i:s", $answered_calls_array["$call_date_key"]["min_wait_time"]);
|
||||||
|
$max_wait_time_fmt=($answered_calls_array["$call_date_key"]["max_wait_time"]>=3600 ? floor($answered_calls_array["$call_date_key"]["max_wait_time"]/3600).":" : "").gmdate("i:s", $answered_calls_array["$call_date_key"]["max_wait_time"]);
|
||||||
|
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>".$call_date_key."</td>";
|
||||||
|
$HTML_output.="<td>".$total_date_calls_answered."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", ((100*$total_date_calls_answered)/$total_answered_calls))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$total_date_calls_answered)/$total_answered_calls)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$avg_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$min_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$max_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$avg_wait_time)/$max_avg_wait_time)."%'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$CSV_output["answered_call_wait_time"].="\"".$call_date_key."\",\"".$total_date_calls_answered."\",\"".sprintf("%.1f", ((100*$total_date_calls_answered)/$total_answered_calls))." %\",\"\",\"".$avg_wait_time_fmt."\",\"".$min_wait_time_fmt."\",\"".$max_wait_time_fmt."\",\"\"\n";
|
||||||
|
|
||||||
|
$answered_call_wait_time_graph_labels.="\"$call_date_key\",";
|
||||||
|
$answered_call_wait_time_graph_data1.="\"$total_date_calls_answered\",";
|
||||||
|
$answered_call_wait_time_graph_bgcolor1.="\"".$background_colors[0]."\",";
|
||||||
|
$answered_call_wait_time_graph_hovborder1.="\"".$border_colors[0]."\",";
|
||||||
|
$answered_call_wait_time_graph_data2.="\"$avg_wait_time\",";
|
||||||
|
$answered_call_wait_time_graph_bgcolor2.="\"".$background_colors[1]."\",";
|
||||||
|
$answered_call_wait_time_graph_hovborder2.="\"".$border_colors[1]."\",";
|
||||||
|
}
|
||||||
|
$answered_call_wait_time_graph_labels=preg_replace('/,$/', '', $answered_call_wait_time_graph_labels)."]";
|
||||||
|
$answered_call_wait_time_graph_data1=preg_replace('/,$/', '', $answered_call_wait_time_graph_data1)."]";
|
||||||
|
$answered_call_wait_time_graph_bgcolor1=preg_replace('/,$/', '', $answered_call_wait_time_graph_bgcolor1)."]";
|
||||||
|
$answered_call_wait_time_graph_hovborder1=preg_replace('/,$/', '', $answered_call_wait_time_graph_hovborder1)."]";
|
||||||
|
$answered_call_wait_time_graph_data2=preg_replace('/,$/', '', $answered_call_wait_time_graph_data2)."]";
|
||||||
|
$answered_call_wait_time_graph_bgcolor2=preg_replace('/,$/', '', $answered_call_wait_time_graph_bgcolor2)."]";
|
||||||
|
$answered_call_wait_time_graph_hovborder2=preg_replace('/,$/', '', $answered_call_wait_time_graph_hovborder2)."]";
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='8' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=answered_call_wait_time\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='8'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('DOW', 'answered_call_wait_time')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$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>";
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
#### UNANSWERED CALL WAIT TIME PER DAY OF WEEK ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Unanswered call wait time per day of week").": $NWB#VERM_DOW-unanswered_call_wait_time$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%' valign='top'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Num")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Unanswered calls")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Min")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Max")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg Duration")."</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["unanswered_call_wait_time"]="\""._QXZ("Day")."\",\""._QXZ("Num")."\",\"\",\""._QXZ("Unanswered calls")."\",\""._QXZ("Avg")."\",\""._QXZ("Min")."\",\""._QXZ("Max")."\",\""._QXZ("Avg Duration")."\"\n";
|
||||||
|
|
||||||
|
$unanswered_call_wait_time_graph_labels="[";
|
||||||
|
$unanswered_call_wait_time_graph_data1="[";
|
||||||
|
$unanswered_call_wait_time_graph_bgcolor1="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$unanswered_call_wait_time_graph_hovborder1="[";
|
||||||
|
$unanswered_call_wait_time_graph_data2="[";
|
||||||
|
$unanswered_call_wait_time_graph_bgcolor2="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$unanswered_call_wait_time_graph_hovborder2="[";
|
||||||
|
|
||||||
|
$max_avg_wait_time=0;
|
||||||
|
foreach ($calls_array as $call_date_key => $call_date_data)
|
||||||
|
{
|
||||||
|
$avg_wait_time=round(MathZDC($unanswered_calls_array["$call_date_key"]["total_wait"], ($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"])));
|
||||||
|
# print $unanswered_calls_array["$call_date_key"]["total_wait"]."/".($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"])."\n";
|
||||||
|
$unanswered_calls_array["$call_date_key"]["avg_wait_time"]=$avg_wait_time+0;
|
||||||
|
if ($max_avg_wait_time<$avg_wait_time) {$max_avg_wait_time=$avg_wait_time;}
|
||||||
|
}
|
||||||
|
# print_r($unanswered_calls_array); die;
|
||||||
|
foreach ($unanswered_calls_array as $call_date_key => $call_date_data)
|
||||||
|
{
|
||||||
|
$total_date_calls=($call_date_data["inbound"]+$call_date_data["outbound"]);
|
||||||
|
$total_date_calls_answered=($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
$total_date_calls_unanswered=($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
|
||||||
|
$avg_wait_time=round(MathZDC($unanswered_calls_array["$call_date_key"]["total_wait"], $total_date_calls_unanswered));
|
||||||
|
$avg_wait_time_fmt=($avg_wait_time>=3600 ? floor($avg_wait_time/3600).":" : "").gmdate("i:s", $avg_wait_time);
|
||||||
|
|
||||||
|
$min_wait_time_fmt=($unanswered_calls_array["$call_date_key"]["min_wait_time"]>=3600 ? floor($unanswered_calls_array["$call_date_key"]["min_wait_time"]/3600).":" : "").gmdate("i:s", $unanswered_calls_array["$call_date_key"]["min_wait_time"]);
|
||||||
|
$max_wait_time_fmt=($unanswered_calls_array["$call_date_key"]["max_wait_time"]>=3600 ? floor($unanswered_calls_array["$call_date_key"]["max_wait_time"]/3600).":" : "").gmdate("i:s", $unanswered_calls_array["$call_date_key"]["max_wait_time"]);
|
||||||
|
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>".$call_date_key."</td>";
|
||||||
|
$HTML_output.="<td>".$total_date_calls_unanswered."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", ((100*$total_date_calls_unanswered)/$total_unanswered_calls))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$total_date_calls_unanswered)/$total_unanswered_calls)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$avg_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$min_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$max_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$avg_wait_time)/$max_avg_wait_time)."%'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$CSV_output["unanswered_call_wait_time"].="\"".$call_date_key."\",\"".$total_date_calls_unanswered."\",\"".sprintf("%.1f", ((100*$total_date_calls_unanswered)/$total_unanswered_calls))." %\",\"\",\"".$avg_wait_time_fmt."\",\"".$min_wait_time_fmt."\",\"".$max_wait_time_fmt."\",\"\"\n";
|
||||||
|
|
||||||
|
$unanswered_call_wait_time_graph_labels.="\"$call_date_key\",";
|
||||||
|
$unanswered_call_wait_time_graph_data1.="\"$total_date_calls_unanswered\",";
|
||||||
|
$unanswered_call_wait_time_graph_bgcolor1.="\"".$background_colors[0]."\",";
|
||||||
|
$unanswered_call_wait_time_graph_hovborder1.="\"".$border_colors[0]."\",";
|
||||||
|
$unanswered_call_wait_time_graph_data2.="\"$avg_wait_time\",";
|
||||||
|
$unanswered_call_wait_time_graph_bgcolor2.="\"".$background_colors[1]."\",";
|
||||||
|
$unanswered_call_wait_time_graph_hovborder2.="\"".$border_colors[1]."\",";
|
||||||
|
}
|
||||||
|
$unanswered_call_wait_time_graph_labels=preg_replace('/,$/', '', $unanswered_call_wait_time_graph_labels)."]";
|
||||||
|
$unanswered_call_wait_time_graph_data1=preg_replace('/,$/', '', $unanswered_call_wait_time_graph_data1)."]";
|
||||||
|
$unanswered_call_wait_time_graph_bgcolor1=preg_replace('/,$/', '', $unanswered_call_wait_time_graph_bgcolor1)."]";
|
||||||
|
$unanswered_call_wait_time_graph_hovborder1=preg_replace('/,$/', '', $unanswered_call_wait_time_graph_hovborder1)."]";
|
||||||
|
$unanswered_call_wait_time_graph_data2=preg_replace('/,$/', '', $unanswered_call_wait_time_graph_data2)."]";
|
||||||
|
$unanswered_call_wait_time_graph_bgcolor2=preg_replace('/,$/', '', $unanswered_call_wait_time_graph_bgcolor2)."]";
|
||||||
|
$unanswered_call_wait_time_graph_hovborder2=preg_replace('/,$/', '', $unanswered_call_wait_time_graph_hovborder2)."]";
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='8' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=unanswered_call_wait_time\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='8'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('DOW', 'unanswered_call_wait_time')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$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>";
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
#### SALES PER DAY OF WEEK ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Sales per day of week").": $NWB#VERM_DOW-sales_per_DOW$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Human ans. conv")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Customer cont. conv")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Sales")."</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Human answers")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Customer contacts")."</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["sales_per_day"]="\""._QXZ("Day")."\",\""._QXZ("Human ans. conv")."\",\""._QXZ("Customer cont. conv")."\",\""._QXZ("Sales")."\",\"\",\"\",\""._QXZ("Human answers")."\",\""._QXZ("Customer contacts")."\",\"\",\"\"\n";
|
||||||
|
|
||||||
|
#print_r($calls_array);
|
||||||
|
$max_day_sales=max(array_column($calls_array, 'sales'));
|
||||||
|
$max_day_customer_contacts=max(array_column($calls_array, 'customer_contacts'));
|
||||||
|
#print "<BR>$max_day_sales<BR>\n";
|
||||||
|
foreach ($calls_array as $call_date_key => $data)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>$call_date_key</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", MathZDC((100*$data["sales"]), $data["human_answered"]))." %</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", MathZDC((100*$data["sales"]), $data["customer_contacts"]))." %</td>";
|
||||||
|
$HTML_output.="<td>".($data["sales"]+0)."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", ((100*$data["sales"])/$total_sales))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$data["sales"])/$max_day_sales)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$data["human_answered"]."</td>";
|
||||||
|
$HTML_output.="<td>".$data["customer_contacts"]."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", ((100*$data["customer_contacts"])/$total_customer_contacts))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$data["customer_contacts"])/$max_day_customer_contacts)."%'></td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["sales_per_day"].="\"$call_date_key\",\"".sprintf("%.1f", MathZDC((100*$data["sales"]), $data["human_answered"]))." %\",\"".sprintf("%.1f", MathZDC((100*$data["sales"]), $data["customer_contacts"]))." %\",\"".($data["sales"]+0)."\",\"".sprintf("%.1f", MathZDC((100*$data["sales"]), $total_sales))." %\",\"\",\"".$data["human_answered"]."\",\"".$data["customer_contacts"]."\",\"".sprintf("%.1f", ((100*$data["customer_contacts"])/$total_customer_contacts))." %\",\"\"\n";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='10' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=sales_per_day\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$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>";
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
#### QUEUE LENGTH PER DAY OF WEEK ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Queue length per day of week").": $NWB#VERM_DOW-queue_length_per_DOW$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Min")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Max")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
### Removed 5/19/22
|
||||||
|
### $HTML_output.="<th>Cover.</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("ASQPPH")." $NWB#VERM_DAY-queue_length_per_day$NWE</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
### Removed Coverage column before Steps 5/19/22 - not needed
|
||||||
|
$CSV_output["queue_length_per_day"]="\""._QXZ("Day")."\",\""._QXZ("Avg")."\",\"...\",\""._QXZ("Min")."\",\""._QXZ("Max")."\",\"...\",\""._QXZ("Average Sum of Queue Positions Per Hour")."\"\n";
|
||||||
|
|
||||||
|
$max_call_position=max(array_column($queue_array, 'max_queue_position'));
|
||||||
|
$max_avg_position=max(array_column($queue_array, 'avg_position'));
|
||||||
|
foreach ($queue_array as $call_date_key => $data)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>$call_date_key</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", $queue_array["$call_date_key"]["avg_position"])."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$queue_array["$call_date_key"]["avg_position"])/$max_avg_position)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$queue_array["$call_date_key"]["min_queue_position"]."</td>";
|
||||||
|
$HTML_output.="<td>".$queue_array["$call_date_key"]["max_queue_position"]."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$queue_array["$call_date_key"]["max_queue_position"])/$max_call_position)."%'></td>";
|
||||||
|
### $HTML_output.="<td>100% **</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", $queue_array["$call_date_key"]["total_queue"]/24)."</td>"; # Always seems to be 24 hours for the date - even when I ran starting at 8am.
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["queue_length_per_day"].="\"$call_date_key\",\"".sprintf("%.1f", $queue_array["$call_date"]["avg_position"])."\",\"...\",\"".$queue_array["$call_date_key"]["min_queue_position"]."\",\"".$queue_array["$call_date_key"]["max_queue_position"]."\",\"...\",\"".sprintf("%.1f", $queue_array["$call_date_key"]["total_queue"]/24)."\"\n";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='8' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=queue_length_per_day\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('DOW', 'queue_length_per_day')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$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>";
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
#### SCHEDULE ADHERENCE PER DAY OF WEEK ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Schedule Adherence per day of week").": $NWB#VERM_DOW-schedule_adherence$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Agents")."</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["schedule_adherence_per_day"]="\""._QXZ("Day")."\",\""._QXZ("Agents")."\",\"\",\"\"\n";
|
||||||
|
|
||||||
|
foreach ($user_array as $call_date_key => $users_that_day)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>$call_date_key</td>";
|
||||||
|
$HTML_output.="<td>".count($users_that_day)."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", (100*count($users_that_day)/$total_distinct_users_per_date))." %</td>";
|
||||||
|
$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";
|
||||||
|
|
||||||
|
$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";
|
||||||
|
|
||||||
|
for ($i=0; $i<count($users_that_day); $i++)
|
||||||
|
{
|
||||||
|
# Get total agent time
|
||||||
|
$stmt="SELECT event,event_epoch,event_date,campaign_id,user_group,session_id,server_ip,extension,computer_ip,phone_login,phone_ip from ".$vicidial_user_log_table." where user='" . mysqli_real_escape_string($link, $users_that_day[$i]) . "' and event_date >= '" . mysqli_real_escape_string($link, $call_date_key) . " 0:00:01' and event_date <= '" . mysqli_real_escape_string($link, $call_date_key) . " 23:59:59' order by event_date;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
while ($row=mysqli_fetch_row($rslt))
|
||||||
|
{
|
||||||
|
if (preg_match('/LOGIN/', $row[0]))
|
||||||
|
{
|
||||||
|
$event_start_seconds = $row[1];
|
||||||
|
}
|
||||||
|
if (preg_match('/LOGOUT/', $row[0]))
|
||||||
|
{
|
||||||
|
if ($event_start_seconds)
|
||||||
|
{
|
||||||
|
$event_stop_seconds = $row[1];
|
||||||
|
$event_seconds = ($event_stop_seconds - $event_start_seconds);
|
||||||
|
$agent_login_time_array["$call_date_key"]+=$event_seconds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#print_r($agent_login_time_array);
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='4' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=schedule_adherence_per_day\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='4'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('DOW', 'schedule_adherence_per_day')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
|
||||||
|
#### 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;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Answered")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Unanswered")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Num")."</th>";
|
||||||
|
|
||||||
|
$CSV_output["inclusive_sla_per_day"]="\""._QXZ("Day")."\",\""._QXZ("Answered")."\",\""._QXZ("Unanswered")."\",\""._QXZ("Num")."\"";
|
||||||
|
|
||||||
|
for ($i=0; $i<count($SLA_column_names); $i++)
|
||||||
|
{
|
||||||
|
$HTML_output.="<th>".$SLA_column_names[$i]."</th>";
|
||||||
|
$CSV_output["inclusive_sla_per_day"].=",\"".$SLA_column_names[$i]."\"";
|
||||||
|
}
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["inclusive_sla_per_day"].="\n";
|
||||||
|
|
||||||
|
foreach ($calls_array as $call_date_key => $data)
|
||||||
|
{
|
||||||
|
$svc_lvl_stmt="select $SLA_query from vicidial_closer_log where call_date>='$start_date $start_time' and call_date<='$end_date $end_time' and dayname(call_date)='$call_date_key' $and_vicidial_closer_log_SQL and (user!='VDCL')"; # and campaign_id in ($ingroup_str) and user in ('VDCL', $user_str)
|
||||||
|
if ($DB) {$HTML_output.="<B>$svc_lvl_stmt<B>";}
|
||||||
|
$svc_lvl_rslt=mysql_to_mysqli($svc_lvl_stmt, $link);
|
||||||
|
# print $svc_lvl_stmt."\n";
|
||||||
|
$svc_lvl_row=mysqli_fetch_row($svc_lvl_rslt);
|
||||||
|
|
||||||
|
$answered_calls=$answered_calls_array["$call_date_key"]["inbound"]+0;
|
||||||
|
$answered_calls+=$answered_calls_array["$call_date_key"]["outbound"]+0; # "Inclusive" remember
|
||||||
|
|
||||||
|
$HTML_output.="<tr bgcolor='$bgcolor'>";
|
||||||
|
$HTML_output.="<td>$call_date_key</td>";
|
||||||
|
$HTML_output.="<td>".($data["answered"]+0)."</td>";
|
||||||
|
$HTML_output.="<td>".($data["unanswered"]+0)."</td>";
|
||||||
|
$HTML_output.="<td>".($data["answered"]+$data["unanswered"]+0)."</td>";
|
||||||
|
|
||||||
|
$CSV_output["inclusive_sla_per_day"].="\"$call_date_key\",\"".($data["answered"]+0)."\",\"".($data["unanswered"]+0)."\",\"".($data["answered"]+$data["unanswered"]+0)."\"";
|
||||||
|
|
||||||
|
for ($f=0; $f<count($svc_lvl_row); $f++)
|
||||||
|
{
|
||||||
|
$svc_lvl_row[$f]+=$answered_calls_array["$call_date_key"]["outbound"];
|
||||||
|
$HTML_output.="<td align='right'>".sprintf("%.1f", MathZDC((100*$svc_lvl_row[$f]), $answered_calls))." %</td>";
|
||||||
|
$CSV_output["inclusive_sla_per_day"].=",\"".sprintf("%.1f", MathZDC((100*$svc_lvl_row[$f]), $answered_calls))." %\"";
|
||||||
|
}
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["inclusive_sla_per_day"].="\n";
|
||||||
|
|
||||||
|
$prev_int=$interval;
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='".(4+count($svc_lvl_row))."' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=inclusive_sla_per_day\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='".(4+count($svc_lvl_row))."'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('DOW', 'inclusive_sla_per_day')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
|
||||||
|
/*
|
||||||
|
# Traffic analysis per day
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>Traffic Analysis by period - per day:</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>Day</th>";
|
||||||
|
$HTML_output.="<th>Avg ag</th>";
|
||||||
|
$HTML_output.="<th>Calls/Ag</th>";
|
||||||
|
$HTML_output.="<th>Svc Lvl</th>";
|
||||||
|
$HTML_output.="<th>Unans</th>";
|
||||||
|
$HTML_output.="<th>Unans short</th>";
|
||||||
|
$HTML_output.="<th>Avg out</th>";
|
||||||
|
$HTML_output.="<th>Out/in</th>";
|
||||||
|
$HTML_output.="<th>Avg ans</th>";
|
||||||
|
$HTML_output.="<th>Avg talk</th>";
|
||||||
|
$HTML_output.="<th>Max wait ans</th>";
|
||||||
|
$HTML_output.="<th>Max wait lost</th>";
|
||||||
|
$HTML_output.="<th>Max dur</th>";
|
||||||
|
$HTML_output.="<th>Max dur out</th>";
|
||||||
|
$HTML_output.="<th>Off.</th>";
|
||||||
|
$HTML_output.="<th>Ans.</th>";
|
||||||
|
$HTML_output.="<th>Ans. out</th>";
|
||||||
|
$HTML_output.="<th>Min Ag.</th>";
|
||||||
|
$HTML_output.="<th>Max Ag.</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ($download_rpt)
|
||||||
|
{
|
||||||
|
$data_to_download=$CSV_output["$download_rpt"];
|
||||||
|
|
||||||
|
$FILE_TIME = date("Ymd-His");
|
||||||
|
$CSVfilename = "DAY_RPT_".$download_rpt."_".$FILE_TIME.".csv";
|
||||||
|
header('Content-type: application/octet-stream');
|
||||||
|
|
||||||
|
header("Content-Disposition: attachment; filename=\"$CSVfilename\"");
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
ob_clean();
|
||||||
|
flush();
|
||||||
|
|
||||||
|
echo "$data_to_download";
|
||||||
|
|
||||||
|
if ($db_source == 'S')
|
||||||
|
{
|
||||||
|
mysqli_close($link);
|
||||||
|
$use_slave_server=0;
|
||||||
|
$db_source = 'M';
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
$endMS = microtime();
|
||||||
|
$startMSary = explode(" ",$startMS);
|
||||||
|
$endMSary = explode(" ",$endMS);
|
||||||
|
$runS = ($endMSary[0] - $startMSary[0]);
|
||||||
|
$runM = ($endMSary[1] - $startMSary[1]);
|
||||||
|
$TOTALrun = ($runS + $runM);
|
||||||
|
|
||||||
|
# $stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';";
|
||||||
|
# if ($DB) {echo "|$stmt|\n";}
|
||||||
|
# $rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
echo $HTML_output;
|
||||||
|
?>
|
||||||
|
<script language='Javascript'>
|
||||||
|
var answered_call_distribution = document.getElementById('answered_call_distribution_graph');
|
||||||
|
new Chart(answered_call_distribution, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: <?php echo $answered_call_distribution_graph_labels; ?>,
|
||||||
|
datasets: [{
|
||||||
|
label: 'Answered calls',
|
||||||
|
yAxisID: 'Answered calls',
|
||||||
|
data: <?php echo $answered_call_distribution_graph_data1; ?>,
|
||||||
|
borderColor: <?php echo $answered_call_distribution_graph_bgcolor1; ?>,
|
||||||
|
backgroundColor: <?php echo $answered_call_distribution_graph_bgcolor1; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $answered_call_distribution_graph_bgcolor1; ?>,
|
||||||
|
hoverBorderColor: <?php echo $answered_call_distribution_graph_hovborder1; ?>,
|
||||||
|
}, {
|
||||||
|
label: 'Average duration (seconds)',
|
||||||
|
yAxisID: 'Average duration (seconds)',
|
||||||
|
data: <?php echo $answered_call_distribution_graph_data2; ?>,
|
||||||
|
borderColor: <?php echo $answered_call_distribution_graph_bgcolor2; ?>,
|
||||||
|
backgroundColor: <?php echo $answered_call_distribution_graph_bgcolor2; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $answered_call_distribution_graph_bgcolor2; ?>,
|
||||||
|
hoverBorderColor: <?php echo $answered_call_distribution_graph_hovborder2; ?>,
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
scales: {
|
||||||
|
'Answered calls': {
|
||||||
|
type: 'linear',
|
||||||
|
position: 'left',
|
||||||
|
ticks: {
|
||||||
|
max: 5,
|
||||||
|
min: 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Average duration (seconds)': {
|
||||||
|
type: 'linear',
|
||||||
|
position: 'right',
|
||||||
|
ticks: {
|
||||||
|
max: 5,
|
||||||
|
min: 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var answered_call_wait_time = document.getElementById('answered_call_wait_time_graph');
|
||||||
|
new Chart(answered_call_wait_time, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: <?php echo $answered_call_wait_time_graph_labels; ?>,
|
||||||
|
datasets: [{
|
||||||
|
label: 'Answered calls',
|
||||||
|
yAxisID: 'Answered calls',
|
||||||
|
data: <?php echo $answered_call_wait_time_graph_data1; ?>,
|
||||||
|
borderColor: <?php echo $answered_call_wait_time_graph_bgcolor1; ?>,
|
||||||
|
backgroundColor: <?php echo $answered_call_wait_time_graph_bgcolor1; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $answered_call_wait_time_graph_bgcolor1; ?>,
|
||||||
|
hoverBorderColor: <?php echo $answered_call_wait_time_graph_hovborder1; ?>,
|
||||||
|
}, {
|
||||||
|
label: 'Average wait time (seconds)',
|
||||||
|
yAxisID: 'Average wait time (seconds)',
|
||||||
|
data: <?php echo $answered_call_wait_time_graph_data2; ?>,
|
||||||
|
borderColor: <?php echo $answered_call_wait_time_graph_bgcolor2; ?>,
|
||||||
|
backgroundColor: <?php echo $answered_call_wait_time_graph_bgcolor2; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $answered_call_wait_time_graph_bgcolor2; ?>,
|
||||||
|
hoverBorderColor: <?php echo $answered_call_wait_time_graph_hovborder2; ?>,
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
scales: {
|
||||||
|
'Answered calls': {
|
||||||
|
type: 'linear',
|
||||||
|
position: 'left',
|
||||||
|
ticks: {
|
||||||
|
max: 5,
|
||||||
|
min: 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Average wait time (seconds)': {
|
||||||
|
type: 'linear',
|
||||||
|
position: 'right',
|
||||||
|
ticks: {
|
||||||
|
max: 5,
|
||||||
|
min: 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var unanswered_call_wait_time = document.getElementById('unanswered_call_wait_time_graph');
|
||||||
|
new Chart(unanswered_call_wait_time, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: <?php echo $unanswered_call_wait_time_graph_labels; ?>,
|
||||||
|
datasets: [{
|
||||||
|
label: 'Unanswered calls',
|
||||||
|
yAxisID: 'Unanswered calls',
|
||||||
|
data: <?php echo $unanswered_call_wait_time_graph_data1; ?>,
|
||||||
|
borderColor: <?php echo $unanswered_call_wait_time_graph_bgcolor1; ?>,
|
||||||
|
backgroundColor: <?php echo $unanswered_call_wait_time_graph_bgcolor1; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $unanswered_call_wait_time_graph_bgcolor1; ?>,
|
||||||
|
hoverBorderColor: <?php echo $unanswered_call_wait_time_graph_hovborder1; ?>,
|
||||||
|
}, {
|
||||||
|
label: 'Average wait time (seconds)',
|
||||||
|
yAxisID: 'Average wait time (seconds)',
|
||||||
|
data: <?php echo $unanswered_call_wait_time_graph_data2; ?>,
|
||||||
|
borderColor: <?php echo $unanswered_call_wait_time_graph_bgcolor2; ?>,
|
||||||
|
backgroundColor: <?php echo $unanswered_call_wait_time_graph_bgcolor2; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $unanswered_call_wait_time_graph_bgcolor2; ?>,
|
||||||
|
hoverBorderColor: <?php echo $unanswered_call_wait_time_graph_hovborder2; ?>,
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
scales: {
|
||||||
|
'Unanswered calls': {
|
||||||
|
type: 'linear',
|
||||||
|
position: 'left',
|
||||||
|
ticks: {
|
||||||
|
max: 5,
|
||||||
|
min: 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Average wait time (seconds)': {
|
||||||
|
type: 'linear',
|
||||||
|
position: 'right',
|
||||||
|
ticks: {
|
||||||
|
max: 5,
|
||||||
|
min: 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,977 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_HOUR_rpt.inc - Vicidial Enhanced Reporting per-hour report
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1620 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
# NANQUE, not an unanswered call?
|
||||||
|
# TIMEOT, unanswered even though it was dropped into a call that was picked up
|
||||||
|
# Warm transfers count as two calls
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
$vicidial_user_log_table="vicidial_user_log";
|
||||||
|
|
||||||
|
# if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];}
|
||||||
|
# elseif (isset($_POST["SUBMIT"])) {$SUBMIT=$_POST["SUBMIT"];}
|
||||||
|
|
||||||
|
#### CUSTOM REPORT VARIABLES ####
|
||||||
|
#if (isset($_GET["agents"])) {$agents=$_GET["agents"];}
|
||||||
|
# elseif (isset($_POST["agents"])) {$agents=$_POST["agents"];}
|
||||||
|
#if (isset($_GET["locations"])) {$locations=$_GET["locations"];}
|
||||||
|
# elseif (isset($_POST["locations"])) {$locations=$_POST["locations"];}
|
||||||
|
#if (isset($_GET["user_groups"])) {$user_groups=$_GET["user_groups"];}
|
||||||
|
# elseif (isset($_POST["user_groups"])) {$user_groups=$_POST["user_groups"];}
|
||||||
|
#if (isset($_GET["statuses"])) {$statuses=$_GET["statuses"];}
|
||||||
|
# elseif (isset($_POST["statuses"])) {$statuses=$_POST["statuses"];}
|
||||||
|
#if (isset($_GET["disconnection_causes"])) {$disconnection_causes=$_GET["disconnection_causes"];}
|
||||||
|
# elseif (isset($_POST["disconnection_causes"])) {$disconnection_causes=$_POST["disconnection_causes"];}
|
||||||
|
#if (isset($_GET["call_counts"])) {$call_counts=$_GET["call_counts"];}
|
||||||
|
# elseif (isset($_POST["call_counts"])) {$call_counts=$_POST["call_counts"];}
|
||||||
|
#if (isset($_GET["DIDs"])) {$DIDs=$_GET["DIDs"];}
|
||||||
|
# elseif (isset($_POST["DIDs"])) {$DIDs=$_POST["DIDs"];}
|
||||||
|
#if (isset($_GET["IVR_choice"])) {$IVR_choice=$_GET["IVR_choice"];}
|
||||||
|
# elseif (isset($_POST["IVR_choice"])) {$IVR_choice=$_POST["IVR_choice"];}
|
||||||
|
#if (isset($_GET["server"])) {$server=$_GET["server"];}
|
||||||
|
# elseif (isset($_POST["server"])) {$server=$_POST["server"];}
|
||||||
|
#if (isset($_GET["days_of_week"])) {$days_of_week=$_GET["days_of_week"];}
|
||||||
|
# elseif (isset($_POST["days_of_week"])) {$days_of_week=$_POST["days_of_week"];}
|
||||||
|
#if (isset($_GET["hour_of_day"])) {$hour_of_day=$_GET["hour_of_day"];}
|
||||||
|
# elseif (isset($_POST["hour_of_day"])) {$hour_of_day=$_POST["hour_of_day"];}
|
||||||
|
|
||||||
|
/* None of the above are used below
|
||||||
|
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);
|
||||||
|
$agents = preg_replace('/[^-_0-9a-zA-Z]/','',$agents);
|
||||||
|
$locations = preg_replace('/[^-_0-9a-zA-Z]/','',$locations);
|
||||||
|
$user_groups = preg_replace('/[^-_0-9a-zA-Z]/','',$user_groups);
|
||||||
|
$statuses = preg_replace('/[^-_0-9a-zA-Z]/','',$statuses);
|
||||||
|
$disconnection_causes = preg_replace('/[^\s-_0-9a-zA-Z]/','',$disconnection_causes);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
$agents = preg_replace('/[^-_0-9\p{L}]/u','',$agents);
|
||||||
|
$locations = preg_replace('/[^-_0-9\p{L}]/u','',$locations);
|
||||||
|
$user_groups = preg_replace('/[^-_0-9\p{L}]/u','',$user_groups);
|
||||||
|
$statuses = preg_replace('/[^-_0-9\p{L}]/u','',$statuses);
|
||||||
|
$disconnection_causes = preg_replace('/[^\s-_0-9\p{L}]/u','',$disconnection_causes);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!$hourly_slot) {$hourly_slot=30;}
|
||||||
|
|
||||||
|
### VARIABLES ###
|
||||||
|
$total_calls=0;
|
||||||
|
$total_answered_calls=0;
|
||||||
|
$unanswered_calls=0;
|
||||||
|
$max_call_length=0;
|
||||||
|
$min_call_length=1000000;
|
||||||
|
$total_call_length=0;
|
||||||
|
$max_wait_time=0;
|
||||||
|
$min_wait_time=1000000;
|
||||||
|
$total_wait_time=0;
|
||||||
|
$total_position=0;
|
||||||
|
$max_position=0;
|
||||||
|
$min_position=1000000;
|
||||||
|
$total_distinct_users_per_date=0;
|
||||||
|
$total_agent_login_time=0;
|
||||||
|
$all_calls_array=array(); # Regardless of outcome
|
||||||
|
$calls_array=array(); # Dependent on outcome
|
||||||
|
$answered_calls_array=array(); # Dependent on outcome
|
||||||
|
$unanswered_calls_array=array(); # Dependent on outcome
|
||||||
|
$user_array=array();
|
||||||
|
$agent_login_time_array=array();
|
||||||
|
$sales_array=array();
|
||||||
|
$queue_array=array();
|
||||||
|
|
||||||
|
$agent_call_counts=array();
|
||||||
|
$transferred_counts=array();
|
||||||
|
$agent_call_lengths=array();
|
||||||
|
$queue_stats=array(); # campaign id breakdown BY ANSWERED CALLS
|
||||||
|
$term_reasons=array(); # ANSWERED CALLS ONLY
|
||||||
|
$call_directions=array(); # ANSWERED CALLS
|
||||||
|
$call_stints=array(); # ANSWERED CALLS
|
||||||
|
$agent_events=array(); # ANSWERED CALLS
|
||||||
|
$coverage="100%";
|
||||||
|
$coverage_wi="100%";
|
||||||
|
#################
|
||||||
|
|
||||||
|
# Initialize variables so inactive days of the week populate...
|
||||||
|
|
||||||
|
for ($q=0; $q<1440; $q+=$hourly_slot)
|
||||||
|
{
|
||||||
|
$key=date('H:i', mktime(0,$q));
|
||||||
|
$calls_array["$key"]["outbound"]=0;
|
||||||
|
$calls_array["$key"]["inbound"]=0;
|
||||||
|
$calls_array["$key"]["human_answered"]=0;
|
||||||
|
$calls_array["$key"]["customer_contacts"]=0;
|
||||||
|
|
||||||
|
$unanswered_calls_array["$key"]["outbound"]=0;
|
||||||
|
$unanswered_calls_array["$key"]["inbound"]=0;
|
||||||
|
|
||||||
|
$answered_calls_array["$key"]["outbound"]=0;
|
||||||
|
$answered_calls_array["$key"]["inbound"]=0;
|
||||||
|
|
||||||
|
$queue_array["$key"]["total_calls"]=0;
|
||||||
|
$queue_array["$key"]["total_queue"]=0;
|
||||||
|
$queue_array["$key"]["min_queue_position"]=0;
|
||||||
|
$queue_array["$key"]["max_queue_position"]=0;
|
||||||
|
$queue_array["$key"]["avg_position"]=0;
|
||||||
|
|
||||||
|
$user_array["$key"]=array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="select substr(call_date-INTERVAL (unix_timestamp(call_date)%".($hourly_slot*60).") SECOND, 12, 5) as cdate, campaign_id, status, user, length_in_sec as call_length, uniqueid, '0' as wait_sec, 'O' as direction, '1' as queue_position, lead_id from vicidial_log $vicidial_log_SQL $and_NANQUE_clause $exc_addtl_statuses UNION ALL select substr(call_date-INTERVAL (unix_timestamp(call_date)%".($hourly_slot*60).") SECOND, 12, 5) as cdate, campaign_id, status, user, length_in_sec-queue_seconds as call_length, uniqueid, queue_seconds as wait_sec, 'I' as direction, queue_position, lead_id from vicidial_closer_log $vicidial_closer_log_SQL $and_NANQUE_clause $exc_addtl_statuses order by cdate";
|
||||||
|
# print $stmt."\n"; die;
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
while ($row=mysqli_fetch_array($rslt))
|
||||||
|
{
|
||||||
|
$call_date=$row["cdate"];
|
||||||
|
$status=$row["status"];
|
||||||
|
$user=$row["user"];
|
||||||
|
$lead_id=$row["lead_id"];
|
||||||
|
$length_in_sec=$row["call_length"];
|
||||||
|
$wait_sec=$row["wait_sec"];
|
||||||
|
$uniqueid=$row["uniqueid"];
|
||||||
|
$direction=$row["direction"];
|
||||||
|
$campaign_id=$row["campaign_id"];
|
||||||
|
$queue_position=$row["queue_position"];
|
||||||
|
|
||||||
|
# $total_calls++; # Doesn't factor out NANQUE
|
||||||
|
|
||||||
|
if ($direction=="I")
|
||||||
|
{
|
||||||
|
$calls_array["$call_date"]["inbound"]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$calls_array["$call_date"]["outbound"]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('/VDAD|VDCL/', $user)) # && preg_match('/^DROP$|TIMEOT|WAITTO/', $status)
|
||||||
|
{
|
||||||
|
$total_unanswered_calls++;
|
||||||
|
|
||||||
|
$unanswered_calls_array["$call_date"]["total_length"]+=$length_in_sec;
|
||||||
|
$unanswered_calls_array["$call_date"]["total_wait"]+=$wait_sec;
|
||||||
|
|
||||||
|
$calls_array["$call_date"]["unanswered"]++;
|
||||||
|
if ($direction=="I")
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["inbound"]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["outbound"]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Min/max call length
|
||||||
|
if (!$unanswered_calls_array["$call_date"]["min_call_length"] || $length_in_sec<$unanswered_calls_array["$call_date"]["min_call_length"])
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["min_call_length"]=$length_in_sec;
|
||||||
|
}
|
||||||
|
if (!$unanswered_calls_array["$call_date"]["max_call_length"] || $length_in_sec>$unanswered_calls_array["$call_date"]["max_call_length"])
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["max_call_length"]=$length_in_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Min/max wait length
|
||||||
|
if (!$unanswered_calls_array["$call_date"]["min_wait_time"] || $wait_sec<$unanswered_calls_array["$call_date"]["min_wait_time"])
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["min_wait_time"]=$wait_sec;
|
||||||
|
}
|
||||||
|
if (!$unanswered_calls_array["$call_date"]["max_wait_time"] || $wait_sec>$unanswered_calls_array["$call_date"]["max_wait_time"])
|
||||||
|
{
|
||||||
|
$unanswered_calls_array["$call_date"]["max_wait_time"]=$wait_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$total_answered_calls++;
|
||||||
|
|
||||||
|
|
||||||
|
# Total counts/lengths
|
||||||
|
$calls_array["$call_date"]["answered"]++;
|
||||||
|
$calls_array["$call_date"]["total_length"]+=$length_in_sec;
|
||||||
|
$calls_array["$call_date"]["total_wait"]+=$wait_sec;
|
||||||
|
|
||||||
|
$answered_calls_array["$call_date"]["total_length"]+=$length_in_sec;
|
||||||
|
$answered_calls_array["$call_date"]["total_wait"]+=$wait_sec;
|
||||||
|
|
||||||
|
# Min/max call length
|
||||||
|
if (!$answered_calls_array["$call_date"]["min_call_length"] || $length_in_sec<$answered_calls_array["$call_date"]["min_call_length"])
|
||||||
|
{
|
||||||
|
$answered_calls_array["$call_date"]["min_call_length"]=$length_in_sec;
|
||||||
|
}
|
||||||
|
if (!$answered_calls_array["$call_date"]["max_call_length"] || $length_in_sec>$answered_calls_array["$call_date"]["max_call_length"])
|
||||||
|
{
|
||||||
|
$answered_calls_array["$call_date"]["max_call_length"]=$length_in_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Min/max wait length
|
||||||
|
if (!$answered_calls_array["$call_date"]["min_wait_time"] || $wait_sec<$answered_calls_array["$call_date"]["min_wait_time"])
|
||||||
|
{
|
||||||
|
$answered_calls_array["$call_date"]["min_wait_time"]=$wait_sec;
|
||||||
|
}
|
||||||
|
if (!$answered_calls_array["$call_date"]["max_wait_time"] || $wait_sec>$answered_calls_array["$call_date"]["max_wait_time"])
|
||||||
|
{
|
||||||
|
$answered_calls_array["$call_date"]["max_wait_time"]=$wait_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($direction=="I")
|
||||||
|
{
|
||||||
|
$inbound_calls["$call_date"]++;
|
||||||
|
$answered_calls_array["$call_date"]["inbound"]++;
|
||||||
|
$campaign_id_stmt="select campaign_id from vicidial_agent_log where lead_id='$lead_id' and user='$user' and uniqueid='$uniqueid'";
|
||||||
|
$campaign_id_rslt=mysql_to_mysqli($campaign_id_stmt, $link);
|
||||||
|
if(mysqli_num_rows($campaign_id_rslt)>0)
|
||||||
|
{
|
||||||
|
$campaign_id_row=mysqli_fetch_array($campaign_id_rslt);
|
||||||
|
$campaign_id=$campaign_id_row["campaign_id"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$answered_calls_array["$call_date"]["outbound"]++;
|
||||||
|
$outbound_calls["$call_date"]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
### These counts are in here because by definition these SHOULD be answers, but you never know with some morons.
|
||||||
|
### "Real" campaign_id should have been gotten under the direction clause above
|
||||||
|
if (in_array($status, $sale_array["$campaign_id"]) || in_array($status, $sale_array["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$calls_array["$call_date"]["sales"]++;
|
||||||
|
$total_sales++;
|
||||||
|
}
|
||||||
|
if (in_array($status, $human_ans_array["$campaign_id"]) || in_array($status, $human_ans_array["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$calls_array["$call_date"]["human_answered"]++;
|
||||||
|
$total_human_answered++;
|
||||||
|
}
|
||||||
|
if (in_array($status, $contact_array["$campaign_id"]) || in_array($status, $contact_array["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$calls_array["$call_date"]["customer_contacts"]++;
|
||||||
|
$total_customer_contacts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# User counts
|
||||||
|
if (!array_key_exists("$call_date", $user_array)) {$user_array["$call_date"]=array();}
|
||||||
|
if (!in_array($user, $user_array["$call_date"]) && !preg_match('/VDAD|VDCL/', $user))
|
||||||
|
{
|
||||||
|
$total_distinct_users_per_date++; # Need for adherence report
|
||||||
|
array_push($user_array["$call_date"], $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Sale check
|
||||||
|
if (in_array($status, $sale_array["SYSTEM"]) || (array_key_exists("$campaign_id", $sale_array) && in_array($status, $sale_array["$campaign_id"])))
|
||||||
|
{
|
||||||
|
$sales_array["$call_date"]["sales"]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Contact check
|
||||||
|
if (in_array($status, $contact_array["SYSTEM"]) || (array_key_exists("$campaign_id", $contact_array) && in_array($status, $contact_array["$campaign_id"])))
|
||||||
|
{
|
||||||
|
$sales_array["$call_date"]["contacts"]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Queue array
|
||||||
|
$queue_array["$call_date"]["total_calls"]++;
|
||||||
|
$queue_array["$call_date"]["total_queue"]+=$queue_position;
|
||||||
|
$queue_array["$call_date"]["avg_position"]=($queue_array["$call_date"]["total_queue"]/$queue_array["$call_date"]["total_calls"]);
|
||||||
|
# Min/max queue
|
||||||
|
if (!$queue_array["$call_date"]["min_queue_position"] || $queue_position<$queue_array["$call_date"]["min_queue_position"])
|
||||||
|
{
|
||||||
|
$queue_array["$call_date"]["min_queue_position"]=$queue_position;
|
||||||
|
}
|
||||||
|
if (!$queue_array["$call_date"]["max_queue_position"] || $queue_position>$queue_array["$call_date"]["max_queue_position"])
|
||||||
|
{
|
||||||
|
$queue_array["$call_date"]["max_queue_position"]=$queue_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
$total_calls=$total_answered_calls+$total_unanswered_calls;
|
||||||
|
|
||||||
|
# print_r($user_array); die;
|
||||||
|
#### ANSWERED CALL DISTRIBUTION PER HOUR ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Answered call distribution per hour").": $NWB#VERM_HOUR-acd_per_hour$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%' valign='top'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Num")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Answered calls")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Min")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Max")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg Duration")."</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["answered_call_distribution"]="\""._QXZ("Day")."\",\""._QXZ("Num")."\",\"\",\""._QXZ("Answered calls")."\",\""._QXZ("Avg")."\",\""._QXZ("Min")."\",\""._QXZ("Max")."\",\""._QXZ("Avg Duration")."\"\n";
|
||||||
|
|
||||||
|
$answered_call_distribution_graph_labels="[";
|
||||||
|
$answered_call_distribution_graph_data1="[";
|
||||||
|
$answered_call_distribution_graph_bgcolor1="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$answered_call_distribution_graph_hovborder1="[";
|
||||||
|
$answered_call_distribution_graph_data2="[";
|
||||||
|
$answered_call_distribution_graph_bgcolor2="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$answered_call_distribution_graph_hovborder2="[";
|
||||||
|
|
||||||
|
$max_avg_call_length=0;
|
||||||
|
foreach ($calls_array as $call_date_key => $call_date_data) # Use calls array here to iterate through all dates that have calls
|
||||||
|
{
|
||||||
|
$avg_call_length=round(MathZDC($answered_calls_array["$call_date_key"]["total_length"], ($answered_calls_array["$call_date_key"]["inbound"]+$answered_calls_array["$call_date_key"]["outbound"])));
|
||||||
|
$answered_calls_array["$call_date_key"]["avg_call_length"]=$avg_call_length+0;
|
||||||
|
if ($max_avg_call_length<$avg_call_length) {$max_avg_call_length=$avg_call_length;}
|
||||||
|
}
|
||||||
|
foreach ($answered_calls_array as $call_date_key => $call_date_data)
|
||||||
|
{
|
||||||
|
$total_date_calls=($call_date_data["inbound"]+$call_date_data["outbound"]);
|
||||||
|
$total_date_calls_answered=($answered_calls_array["$call_date_key"]["inbound"]+$answered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
$total_date_calls_unanswered=($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
|
||||||
|
$avg_call_length=round(MathZDC($answered_calls_array["$call_date_key"]["total_length"], $total_date_calls_answered));
|
||||||
|
$avg_call_length_fmt=($avg_call_length>=3600 ? floor($avg_call_length/3600).":" : "").gmdate("i:s", floor($avg_call_length));
|
||||||
|
|
||||||
|
$min_call_length_fmt=($answered_calls_array["$call_date_key"]["min_call_length"]>=3600 ? floor($answered_calls_array["$call_date_key"]["min_call_length"]/3600).":" : "").gmdate("i:s", $answered_calls_array["$call_date_key"]["min_call_length"]);
|
||||||
|
$max_call_length_fmt=($answered_calls_array["$call_date_key"]["max_call_length"]>=3600 ? floor($answered_calls_array["$call_date_key"]["max_call_length"]/3600).":" : "").gmdate("i:s", $answered_calls_array["$call_date_key"]["max_call_length"]);
|
||||||
|
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>".$call_date_key."</td>";
|
||||||
|
$HTML_output.="<td>".$total_date_calls_answered."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", ((100*$total_date_calls_answered)/$total_answered_calls))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$total_date_calls_answered)/$total_answered_calls)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$avg_call_length_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$min_call_length_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$max_call_length_fmt."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$avg_call_length)/$max_avg_call_length)."%'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$CSV_output["answered_call_distribution"].="\"".$call_date_key."\",\"".$total_date_calls_answered."\",\"".sprintf("%.1f", ((100*$total_date_calls_answered)/$total_answered_calls))." %\",\"\",\"".$avg_call_length_fmt."\",\"".$min_call_length_fmt."\",\"".$max_call_length_fmt."\",\"\"\n";
|
||||||
|
|
||||||
|
$answered_call_distribution_graph_labels.="\"$call_date_key\",";
|
||||||
|
$answered_call_distribution_graph_data1.="\"$total_date_calls_answered\",";
|
||||||
|
$answered_call_distribution_graph_bgcolor1.="\"".$background_colors[0]."\",";
|
||||||
|
$answered_call_distribution_graph_hovborder1.="\"".$border_colors[0]."\",";
|
||||||
|
$answered_call_distribution_graph_data2.="\"$avg_call_length\",";
|
||||||
|
$answered_call_distribution_graph_bgcolor2.="\"".$background_colors[1]."\",";
|
||||||
|
$answered_call_distribution_graph_hovborder2.="\"".$border_colors[1]."\",";
|
||||||
|
}
|
||||||
|
$answered_call_distribution_graph_labels=preg_replace('/,$/', '', $answered_call_distribution_graph_labels)."]";
|
||||||
|
$answered_call_distribution_graph_data1=preg_replace('/,$/', '', $answered_call_distribution_graph_data1)."]";
|
||||||
|
$answered_call_distribution_graph_bgcolor1=preg_replace('/,$/', '', $answered_call_distribution_graph_bgcolor1)."]";
|
||||||
|
$answered_call_distribution_graph_hovborder1=preg_replace('/,$/', '', $answered_call_distribution_graph_hovborder1)."]";
|
||||||
|
$answered_call_distribution_graph_data2=preg_replace('/,$/', '', $answered_call_distribution_graph_data2)."]";
|
||||||
|
$answered_call_distribution_graph_bgcolor2=preg_replace('/,$/', '', $answered_call_distribution_graph_bgcolor2)."]";
|
||||||
|
$answered_call_distribution_graph_hovborder2=preg_replace('/,$/', '', $answered_call_distribution_graph_hovborder2)."]";
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='8' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=answered_call_distribution\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='8'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('HOUR', 'answered_call_distribution')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$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>";
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
#### ANSWERED CALL WAIT TIME PER HOUR ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Answered call wait time per hour").": $NWB#VERM_HOUR-answered_cw_per_hour$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%' valign='top'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Num")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Answered calls")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Min")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Max")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg Duration")."</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["answered_call_wait_time"]="\""._QXZ("Day")."\",\""._QXZ("Num")."\",\"\",\""._QXZ("Answered calls")."\",\""._QXZ("Avg")."\",\""._QXZ("Min")."\",\""._QXZ("Max")."\",\""._QXZ("Avg Duration")."\"\n";
|
||||||
|
|
||||||
|
$answered_call_wait_time_graph_labels="[";
|
||||||
|
$answered_call_wait_time_graph_data1="[";
|
||||||
|
$answered_call_wait_time_graph_bgcolor1="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$answered_call_wait_time_graph_hovborder1="[";
|
||||||
|
$answered_call_wait_time_graph_data2="[";
|
||||||
|
$answered_call_wait_time_graph_bgcolor2="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$answered_call_wait_time_graph_hovborder2="[";
|
||||||
|
|
||||||
|
$max_avg_wait_time=0;
|
||||||
|
foreach ($calls_array as $call_date_key => $call_date_data)
|
||||||
|
{
|
||||||
|
$avg_wait_time=round(MathZDC($answered_calls_array["$call_date_key"]["total_wait"], ($answered_calls_array["$call_date_key"]["inbound"]+$answered_calls_array["$call_date_key"]["outbound"])));
|
||||||
|
$answered_calls_array["$call_date_key"]["avg_wait_time"]=$avg_wait_time+0;
|
||||||
|
if ($max_avg_wait_time<$avg_wait_time) {$max_avg_wait_time=$avg_wait_time;}
|
||||||
|
}
|
||||||
|
foreach ($answered_calls_array as $call_date_key => $call_date_data)
|
||||||
|
{
|
||||||
|
$total_date_calls=($call_date_data["inbound"]+$call_date_data["outbound"]);
|
||||||
|
$total_date_calls_answered=($answered_calls_array["$call_date_key"]["inbound"]+$answered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
$total_date_calls_unanswered=($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
|
||||||
|
$avg_wait_time=round(MathZDC($answered_calls_array["$call_date_key"]["total_wait"], $total_date_calls_answered));
|
||||||
|
$avg_wait_time_fmt=($avg_wait_time>=3600 ? floor($avg_wait_time/3600).":" : "").gmdate("i:s", floor($avg_wait_time));
|
||||||
|
|
||||||
|
$min_wait_time_fmt=($answered_calls_array["$call_date_key"]["min_wait_time"]>=3600 ? floor($answered_calls_array["$call_date_key"]["min_wait_time"]/3600).":" : "").gmdate("i:s", $answered_calls_array["$call_date_key"]["min_wait_time"]);
|
||||||
|
$max_wait_time_fmt=($answered_calls_array["$call_date_key"]["max_wait_time"]>=3600 ? floor($answered_calls_array["$call_date_key"]["max_wait_time"]/3600).":" : "").gmdate("i:s", $answered_calls_array["$call_date_key"]["max_wait_time"]);
|
||||||
|
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>".$call_date_key."</td>";
|
||||||
|
$HTML_output.="<td>".$total_date_calls_answered."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", ((100*$total_date_calls_answered)/$total_answered_calls))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$total_date_calls_answered)/$total_answered_calls)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$avg_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$min_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$max_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$avg_wait_time)/$max_avg_wait_time)."%'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$CSV_output["answered_call_wait_time"].="\"".$call_date_key."\",\"".$total_date_calls_answered."\",\"".sprintf("%.1f", ((100*$total_date_calls_answered)/$total_answered_calls))." %\",\"\",\"".$avg_wait_time_fmt."\",\"".$min_wait_time_fmt."\",\"".$max_wait_time_fmt."\",\"\"\n";
|
||||||
|
|
||||||
|
$answered_call_wait_time_graph_labels.="\"$call_date_key\",";
|
||||||
|
$answered_call_wait_time_graph_data1.="\"$total_date_calls_answered\",";
|
||||||
|
$answered_call_wait_time_graph_bgcolor1.="\"".$background_colors[0]."\",";
|
||||||
|
$answered_call_wait_time_graph_hovborder1.="\"".$border_colors[0]."\",";
|
||||||
|
$answered_call_wait_time_graph_data2.="\"$avg_wait_time\",";
|
||||||
|
$answered_call_wait_time_graph_bgcolor2.="\"".$background_colors[1]."\",";
|
||||||
|
$answered_call_wait_time_graph_hovborder2.="\"".$border_colors[1]."\",";
|
||||||
|
}
|
||||||
|
$answered_call_wait_time_graph_labels=preg_replace('/,$/', '', $answered_call_wait_time_graph_labels)."]";
|
||||||
|
$answered_call_wait_time_graph_data1=preg_replace('/,$/', '', $answered_call_wait_time_graph_data1)."]";
|
||||||
|
$answered_call_wait_time_graph_bgcolor1=preg_replace('/,$/', '', $answered_call_wait_time_graph_bgcolor1)."]";
|
||||||
|
$answered_call_wait_time_graph_hovborder1=preg_replace('/,$/', '', $answered_call_wait_time_graph_hovborder1)."]";
|
||||||
|
$answered_call_wait_time_graph_data2=preg_replace('/,$/', '', $answered_call_wait_time_graph_data2)."]";
|
||||||
|
$answered_call_wait_time_graph_bgcolor2=preg_replace('/,$/', '', $answered_call_wait_time_graph_bgcolor2)."]";
|
||||||
|
$answered_call_wait_time_graph_hovborder2=preg_replace('/,$/', '', $answered_call_wait_time_graph_hovborder2)."]";
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='8' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=answered_call_wait_time\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='8'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('HOUR', 'answered_call_wait_time')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$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>";
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
#### UNANSWERED CALL WAIT TIME PER HOUR ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Unanswered call wait time per hour").": $NWB#VERM_HOUR-unanswered_cw_per_hour$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%' valign='top'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Num")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Unanswered calls")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Min")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Max")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg Duration")."</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["unanswered_call_wait_time"]="\""._QXZ("Day")."\",\""._QXZ("Num")."\",\"\",\""._QXZ("Unanswered calls")."\",\""._QXZ("Avg")."\",\""._QXZ("Min")."\",\""._QXZ("Max")."\",\""._QXZ("Avg Duration")."\"\n";
|
||||||
|
|
||||||
|
$unanswered_call_wait_time_graph_labels="[";
|
||||||
|
$unanswered_call_wait_time_graph_data1="[";
|
||||||
|
$unanswered_call_wait_time_graph_bgcolor1="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$unanswered_call_wait_time_graph_hovborder1="[";
|
||||||
|
$unanswered_call_wait_time_graph_data2="[";
|
||||||
|
$unanswered_call_wait_time_graph_bgcolor2="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$unanswered_call_wait_time_graph_hovborder2="[";
|
||||||
|
|
||||||
|
$max_avg_wait_time=0;
|
||||||
|
foreach ($calls_array as $call_date_key => $call_date_data)
|
||||||
|
{
|
||||||
|
$avg_wait_time=round(MathZDC($unanswered_calls_array["$call_date_key"]["total_wait"], ($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"])));
|
||||||
|
# print $unanswered_calls_array["$call_date_key"]["total_wait"]."/".($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"])."\n";
|
||||||
|
$unanswered_calls_array["$call_date_key"]["avg_wait_time"]=$avg_wait_time+0;
|
||||||
|
if ($max_avg_wait_time<$avg_wait_time) {$max_avg_wait_time=$avg_wait_time;}
|
||||||
|
}
|
||||||
|
# print_r($unanswered_calls_array); die;
|
||||||
|
foreach ($unanswered_calls_array as $call_date_key => $call_date_data)
|
||||||
|
{
|
||||||
|
$total_date_calls=($call_date_data["inbound"]+$call_date_data["outbound"]);
|
||||||
|
$total_date_calls_answered=($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
$total_date_calls_unanswered=($unanswered_calls_array["$call_date_key"]["inbound"]+$unanswered_calls_array["$call_date_key"]["outbound"]);
|
||||||
|
|
||||||
|
$avg_wait_time=round(MathZDC($unanswered_calls_array["$call_date_key"]["total_wait"], $total_date_calls_unanswered));
|
||||||
|
$avg_wait_time_fmt=($avg_wait_time>=3600 ? floor($avg_wait_time/3600).":" : "").gmdate("i:s", floor($avg_wait_time));
|
||||||
|
|
||||||
|
$min_wait_time_fmt=($unanswered_calls_array["$call_date_key"]["min_wait_time"]>=3600 ? floor($unanswered_calls_array["$call_date_key"]["min_wait_time"]/3600).":" : "").gmdate("i:s", $unanswered_calls_array["$call_date_key"]["min_wait_time"]);
|
||||||
|
$max_wait_time_fmt=($unanswered_calls_array["$call_date_key"]["max_wait_time"]>=3600 ? floor($unanswered_calls_array["$call_date_key"]["max_wait_time"]/3600).":" : "").gmdate("i:s", $unanswered_calls_array["$call_date_key"]["max_wait_time"]);
|
||||||
|
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>".$call_date_key."</td>";
|
||||||
|
$HTML_output.="<td>".$total_date_calls_unanswered."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", MathZDC((100*$total_date_calls_unanswered), $total_unanswered_calls))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".MathZDC((100*$total_date_calls_unanswered), $total_unanswered_calls)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$avg_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$min_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$max_wait_time_fmt."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".MathZDC((100*$avg_wait_time), $max_avg_wait_time)."%'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$CSV_output["unanswered_call_wait_time"].="\"".$call_date_key."\",\"".$total_date_calls_unanswered."\",\"".sprintf("%.1f", MathZDC((100*$total_date_calls_unanswered), $total_unanswered_calls))." %\",\"\",\"".$avg_wait_time_fmt."\",\"".$min_wait_time_fmt."\",\"".$max_wait_time_fmt."\",\"\"\n";
|
||||||
|
|
||||||
|
$unanswered_call_wait_time_graph_labels.="\"$call_date_key\",";
|
||||||
|
$unanswered_call_wait_time_graph_data1.="\"$total_date_calls_unanswered\",";
|
||||||
|
$unanswered_call_wait_time_graph_bgcolor1.="\"".$background_colors[0]."\",";
|
||||||
|
$unanswered_call_wait_time_graph_hovborder1.="\"".$border_colors[0]."\",";
|
||||||
|
$unanswered_call_wait_time_graph_data2.="\"$avg_wait_time\",";
|
||||||
|
$unanswered_call_wait_time_graph_bgcolor2.="\"".$background_colors[1]."\",";
|
||||||
|
$unanswered_call_wait_time_graph_hovborder2.="\"".$border_colors[1]."\",";
|
||||||
|
}
|
||||||
|
$unanswered_call_wait_time_graph_labels=preg_replace('/,$/', '', $unanswered_call_wait_time_graph_labels)."]";
|
||||||
|
$unanswered_call_wait_time_graph_data1=preg_replace('/,$/', '', $unanswered_call_wait_time_graph_data1)."]";
|
||||||
|
$unanswered_call_wait_time_graph_bgcolor1=preg_replace('/,$/', '', $unanswered_call_wait_time_graph_bgcolor1)."]";
|
||||||
|
$unanswered_call_wait_time_graph_hovborder1=preg_replace('/,$/', '', $unanswered_call_wait_time_graph_hovborder1)."]";
|
||||||
|
$unanswered_call_wait_time_graph_data2=preg_replace('/,$/', '', $unanswered_call_wait_time_graph_data2)."]";
|
||||||
|
$unanswered_call_wait_time_graph_bgcolor2=preg_replace('/,$/', '', $unanswered_call_wait_time_graph_bgcolor2)."]";
|
||||||
|
$unanswered_call_wait_time_graph_hovborder2=preg_replace('/,$/', '', $unanswered_call_wait_time_graph_hovborder2)."]";
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='8' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=unanswered_call_wait_time\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='8'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('HOUR', 'unanswered_call_wait_time')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$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>";
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
#### SALES PER HOUR ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Sales per hour").": $NWB#VERM_HOUR-sales_per_hour$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Human ans. conv")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Customer cont. conv")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Sales")."</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Human answers")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Customer contacts")."</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["sales_per_day"]="\""._QXZ("Day")."\",\""._QXZ("Human ans. conv")."\",\""._QXZ("Customer cont. conv")."\",\""._QXZ("Sales")."\",\"\",\"\",\""._QXZ("Human answers")."\",\""._QXZ("Customer contacts")."\",\"\",\"\"\n";
|
||||||
|
|
||||||
|
#print_r($calls_array);
|
||||||
|
$max_day_sales=max(array_column($calls_array, 'sales'));
|
||||||
|
$max_day_customer_contacts=max(array_column($calls_array, 'customer_contacts'));
|
||||||
|
#print "<BR>$max_day_sales<BR>\n";
|
||||||
|
foreach ($calls_array as $call_date_key => $data)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>$call_date_key</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", MathZDC((100*$data["sales"]), $data["human_answered"]))." %</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", MathZDC((100*$data["sales"]), $data["customer_contacts"]))." %</td>";
|
||||||
|
$HTML_output.="<td>".($data["sales"]+0)."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", MathZDC((100*$data["sales"]), $total_sales))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".MathZDC((100*$data["sales"]), $max_day_sales)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$data["human_answered"]."</td>";
|
||||||
|
$HTML_output.="<td>".$data["customer_contacts"]."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", MathZDC((100*$data["customer_contacts"]), $total_customer_contacts))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".MathZDC((100*$data["customer_contacts"]), $max_day_customer_contacts)."%'></td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["sales_per_day"].="\"$call_date_key\",\"".sprintf("%.1f", MathZDC((100*$data["sales"]), $data["human_answered"]))." %\",\"".sprintf("%.1f", MathZDC((100*$data["sales"]), $data["customer_contacts"]))." %\",\"".($data["sales"]+0)."\",\"".sprintf("%.1f", MathZDC((100*$data["sales"]), $total_sales))." %\",\"\",\"".$data["human_answered"]."\",\"".$data["customer_contacts"]."\",\"".sprintf("%.1f", MathZDC((100*$data["customer_contacts"]), $total_customer_contacts))." %\",\"\"\n";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='10' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=sales_per_day\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$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>";
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
#### QUEUE LENGTH PER HOUR ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Queue length per hour").": $NWB#VERM_HOUR-queue_length_per_hour$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avg")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Min")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Max")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
### Removed 5/19/22
|
||||||
|
### $HTML_output.="<th>Cover.</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("ASQPPH")." $NWB#VERM_DAY-queue_length_per_day$NWE</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
### Removed Coverage column before Steps 5/19/22 - not needed
|
||||||
|
$CSV_output["queue_length_per_day"]="\""._QXZ("Day")."\",\""._QXZ("Avg")."\",\"...\",\""._QXZ("Min")."\",\""._QXZ("Max")."\",\"...\",\""._QXZ("Average Sum of Queue Positions Per Hour")."\"\n";
|
||||||
|
|
||||||
|
$max_call_position=max(array_column($queue_array, 'max_queue_position'));
|
||||||
|
$max_avg_position=max(array_column($queue_array, 'avg_position'));
|
||||||
|
foreach ($queue_array as $call_date_key => $data)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>$call_date_key</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", $queue_array["$call_date_key"]["avg_position"])."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$queue_array["$call_date_key"]["avg_position"])/$max_avg_position)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$queue_array["$call_date_key"]["min_queue_position"]."</td>";
|
||||||
|
$HTML_output.="<td>".$queue_array["$call_date_key"]["max_queue_position"]."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$queue_array["$call_date_key"]["max_queue_position"])/$max_call_position)."%'></td>";
|
||||||
|
### $HTML_output.="<td>100% **</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", $queue_array["$call_date_key"]["total_queue"]/24)."</td>"; # Always seems to be 24 hours for the date - even when I ran starting at 8am.
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["queue_length_per_day"].="\"$call_date_key\",\"".sprintf("%.1f", $queue_array["$call_date"]["avg_position"])."\",\"...\",\"".$queue_array["$call_date_key"]["min_queue_position"]."\",\"".$queue_array["$call_date_key"]["max_queue_position"]."\",\"...\",\"".sprintf("%.1f", $queue_array["$call_date_key"]["total_queue"]/24)."\"\n";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='8' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=queue_length_per_day\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('HOUR', 'queue_length_per_day')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$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>";
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
#### SCHEDULE ADHERENCE PER HOUR ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Schedule Adherence per hour").": $NWB#VERM_HOUR-schedule_adherence$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Agents")."</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["schedule_adherence_per_day"]="\""._QXZ("Day")."\",\""._QXZ("Agents")."\",\"\",\"\"\n";
|
||||||
|
|
||||||
|
foreach ($user_array as $call_date_key => $users_that_day)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>$call_date_key</td>";
|
||||||
|
$HTML_output.="<td>".count($users_that_day)."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", (100*count($users_that_day)/$total_distinct_users_per_date))." %</td>";
|
||||||
|
$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";
|
||||||
|
|
||||||
|
$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";
|
||||||
|
|
||||||
|
for ($i=0; $i<count($users_that_day); $i++)
|
||||||
|
{
|
||||||
|
# Get total agent time
|
||||||
|
$stmt="SELECT event,event_epoch,event_date,campaign_id,user_group,session_id,server_ip,extension,computer_ip,phone_login,phone_ip from ".$vicidial_user_log_table." where user='" . mysqli_real_escape_string($link, $users_that_day[$i]) . "' and event_date >= '" . mysqli_real_escape_string($link, $call_date_key) . " 0:00:01' and event_date <= '" . mysqli_real_escape_string($link, $call_date_key) . " 23:59:59' order by event_date;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
while ($row=mysqli_fetch_row($rslt))
|
||||||
|
{
|
||||||
|
if (preg_match('/LOGIN/', $row[0]))
|
||||||
|
{
|
||||||
|
$event_start_seconds = $row[1];
|
||||||
|
}
|
||||||
|
if (preg_match('/LOGOUT/', $row[0]))
|
||||||
|
{
|
||||||
|
if ($event_start_seconds)
|
||||||
|
{
|
||||||
|
$event_stop_seconds = $row[1];
|
||||||
|
$event_seconds = ($event_stop_seconds - $event_start_seconds);
|
||||||
|
$agent_login_time_array["$call_date_key"]+=$event_seconds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#print_r($agent_login_time_array);
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='4' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=schedule_adherence_per_day\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='4'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('HOUR', 'schedule_adherence_per_day')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
|
||||||
|
#### 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;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Day")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Answered")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Unanswered")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Num")."</th>";
|
||||||
|
|
||||||
|
$CSV_output["inclusive_sla_per_day"]="\""._QXZ("Day")."\",\""._QXZ("Answered")."\",\""._QXZ("Unanswered")."\",\""._QXZ("Num")."\"";
|
||||||
|
|
||||||
|
for ($i=0; $i<count($SLA_column_names); $i++)
|
||||||
|
{
|
||||||
|
$HTML_output.="<th>".$SLA_column_names[$i]."</th>";
|
||||||
|
$CSV_output["inclusive_sla_per_day"].=",\"".$SLA_column_names[$i]."\"";
|
||||||
|
}
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["inclusive_sla_per_day"].="\n";
|
||||||
|
|
||||||
|
foreach ($calls_array as $call_date_key => $data)
|
||||||
|
{
|
||||||
|
$svc_lvl_stmt="select $SLA_query from vicidial_closer_log where call_date>='$start_date $start_time' and call_date<='$end_date $end_time' and substr(call_date-INTERVAL (unix_timestamp(call_date)%".($hourly_slot*60).") SECOND, 12, 5)='$call_date_key' $and_vicidial_closer_log_SQL and (user!='VDCL')"; # and campaign_id in ($ingroup_str) and user in ('VDCL', $user_str)
|
||||||
|
if ($DB) {$HTML_output.="<B>$svc_lvl_stmt</B>";}
|
||||||
|
$svc_lvl_rslt=mysql_to_mysqli($svc_lvl_stmt, $link);
|
||||||
|
# print $svc_lvl_stmt."\n";
|
||||||
|
$svc_lvl_row=mysqli_fetch_row($svc_lvl_rslt);
|
||||||
|
|
||||||
|
$answered_calls=$answered_calls_array["$call_date_key"]["inbound"]+0;
|
||||||
|
$answered_calls+=$answered_calls_array["$call_date_key"]["outbound"]+0; # "Inclusive" remember
|
||||||
|
|
||||||
|
$HTML_output.="<tr bgcolor='$bgcolor'>";
|
||||||
|
$HTML_output.="<td>$call_date_key</td>";
|
||||||
|
$HTML_output.="<td>".($data["answered"]+0)."</td>";
|
||||||
|
$HTML_output.="<td>".($data["unanswered"]+0)."</td>";
|
||||||
|
$HTML_output.="<td>".($data["answered"]+$data["unanswered"]+0)."</td>";
|
||||||
|
|
||||||
|
$CSV_output["inclusive_sla_per_day"].="\"$call_date_key\",\"".($data["answered"]+0)."\",\"".($data["unanswered"]+0)."\",\"".($data["answered"]+$data["unanswered"]+0)."\"";
|
||||||
|
|
||||||
|
for ($f=0; $f<count($svc_lvl_row); $f++)
|
||||||
|
{
|
||||||
|
$svc_lvl_row[$f]+=$answered_calls_array["$call_date_key"]["outbound"];
|
||||||
|
$HTML_output.="<td align='right'>".sprintf("%.1f", MathZDC((100*$svc_lvl_row[$f]), $answered_calls))." %</td>";
|
||||||
|
$CSV_output["inclusive_sla_per_day"].=",\"".sprintf("%.1f", MathZDC((100*$svc_lvl_row[$f]), $answered_calls))." %\"";
|
||||||
|
}
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["inclusive_sla_per_day"].="\n";
|
||||||
|
|
||||||
|
$prev_int=$interval;
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='".(4+count($svc_lvl_row))."' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=inclusive_sla_per_day\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='".(4+count($svc_lvl_row))."'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('HOUR', 'inclusive_sla_per_day')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
|
||||||
|
/*
|
||||||
|
# Traffic analysis per day
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>Traffic Analysis by period - per day:</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<th>Day</th>";
|
||||||
|
$HTML_output.="<th>Avg ag</th>";
|
||||||
|
$HTML_output.="<th>Calls/Ag</th>";
|
||||||
|
$HTML_output.="<th>Svc Lvl</th>";
|
||||||
|
$HTML_output.="<th>Unans</th>";
|
||||||
|
$HTML_output.="<th>Unans short</th>";
|
||||||
|
$HTML_output.="<th>Avg out</th>";
|
||||||
|
$HTML_output.="<th>Out/in</th>";
|
||||||
|
$HTML_output.="<th>Avg ans</th>";
|
||||||
|
$HTML_output.="<th>Avg talk</th>";
|
||||||
|
$HTML_output.="<th>Max wait ans</th>";
|
||||||
|
$HTML_output.="<th>Max wait lost</th>";
|
||||||
|
$HTML_output.="<th>Max dur</th>";
|
||||||
|
$HTML_output.="<th>Max dur out</th>";
|
||||||
|
$HTML_output.="<th>Off.</th>";
|
||||||
|
$HTML_output.="<th>Ans.</th>";
|
||||||
|
$HTML_output.="<th>Ans. out</th>";
|
||||||
|
$HTML_output.="<th>Min Ag.</th>";
|
||||||
|
$HTML_output.="<th>Max Ag.</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ($download_rpt)
|
||||||
|
{
|
||||||
|
$data_to_download=$CSV_output["$download_rpt"];
|
||||||
|
|
||||||
|
$FILE_TIME = date("Ymd-His");
|
||||||
|
$CSVfilename = "DAY_RPT_".$download_rpt."_".$FILE_TIME.".csv";
|
||||||
|
header('Content-type: application/octet-stream');
|
||||||
|
|
||||||
|
header("Content-Disposition: attachment; filename=\"$CSVfilename\"");
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
ob_clean();
|
||||||
|
flush();
|
||||||
|
|
||||||
|
echo "$data_to_download";
|
||||||
|
|
||||||
|
if ($db_source == 'S')
|
||||||
|
{
|
||||||
|
mysqli_close($link);
|
||||||
|
$use_slave_server=0;
|
||||||
|
$db_source = 'M';
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
$endMS = microtime();
|
||||||
|
$startMSary = explode(" ",$startMS);
|
||||||
|
$endMSary = explode(" ",$endMS);
|
||||||
|
$runS = ($endMSary[0] - $startMSary[0]);
|
||||||
|
$runM = ($endMSary[1] - $startMSary[1]);
|
||||||
|
$TOTALrun = ($runS + $runM);
|
||||||
|
|
||||||
|
# $stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';";
|
||||||
|
# if ($DB) {echo "|$stmt|\n";}
|
||||||
|
# $rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
echo $HTML_output;
|
||||||
|
?>
|
||||||
|
<script language='Javascript'>
|
||||||
|
var answered_call_distribution = document.getElementById('answered_call_distribution_graph');
|
||||||
|
new Chart(answered_call_distribution, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: <?php echo $answered_call_distribution_graph_labels; ?>,
|
||||||
|
datasets: [{
|
||||||
|
label: 'Answered calls',
|
||||||
|
yAxisID: 'Answered calls',
|
||||||
|
data: <?php echo $answered_call_distribution_graph_data1; ?>,
|
||||||
|
borderColor: <?php echo $answered_call_distribution_graph_bgcolor1; ?>,
|
||||||
|
backgroundColor: <?php echo $answered_call_distribution_graph_bgcolor1; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $answered_call_distribution_graph_bgcolor1; ?>,
|
||||||
|
hoverBorderColor: <?php echo $answered_call_distribution_graph_hovborder1; ?>,
|
||||||
|
}, {
|
||||||
|
label: 'Average duration (seconds)',
|
||||||
|
yAxisID: 'Average duration (seconds)',
|
||||||
|
data: <?php echo $answered_call_distribution_graph_data2; ?>,
|
||||||
|
borderColor: <?php echo $answered_call_distribution_graph_bgcolor2; ?>,
|
||||||
|
backgroundColor: <?php echo $answered_call_distribution_graph_bgcolor2; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $answered_call_distribution_graph_bgcolor2; ?>,
|
||||||
|
hoverBorderColor: <?php echo $answered_call_distribution_graph_hovborder2; ?>,
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
scales: {
|
||||||
|
'Answered calls': {
|
||||||
|
type: 'linear',
|
||||||
|
position: 'left',
|
||||||
|
ticks: {
|
||||||
|
max: 5,
|
||||||
|
min: 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Average duration (seconds)': {
|
||||||
|
type: 'linear',
|
||||||
|
position: 'right',
|
||||||
|
ticks: {
|
||||||
|
max: 5,
|
||||||
|
min: 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var answered_call_wait_time = document.getElementById('answered_call_wait_time_graph');
|
||||||
|
new Chart(answered_call_wait_time, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: <?php echo $answered_call_wait_time_graph_labels; ?>,
|
||||||
|
datasets: [{
|
||||||
|
label: 'Answered calls',
|
||||||
|
yAxisID: 'Answered calls',
|
||||||
|
data: <?php echo $answered_call_wait_time_graph_data1; ?>,
|
||||||
|
borderColor: <?php echo $answered_call_wait_time_graph_bgcolor1; ?>,
|
||||||
|
backgroundColor: <?php echo $answered_call_wait_time_graph_bgcolor1; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $answered_call_wait_time_graph_bgcolor1; ?>,
|
||||||
|
hoverBorderColor: <?php echo $answered_call_wait_time_graph_hovborder1; ?>,
|
||||||
|
}, {
|
||||||
|
label: 'Average wait time (seconds)',
|
||||||
|
yAxisID: 'Average wait time (seconds)',
|
||||||
|
data: <?php echo $answered_call_wait_time_graph_data2; ?>,
|
||||||
|
borderColor: <?php echo $answered_call_wait_time_graph_bgcolor2; ?>,
|
||||||
|
backgroundColor: <?php echo $answered_call_wait_time_graph_bgcolor2; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $answered_call_wait_time_graph_bgcolor2; ?>,
|
||||||
|
hoverBorderColor: <?php echo $answered_call_wait_time_graph_hovborder2; ?>,
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
scales: {
|
||||||
|
'Answered calls': {
|
||||||
|
type: 'linear',
|
||||||
|
position: 'left',
|
||||||
|
ticks: {
|
||||||
|
max: 5,
|
||||||
|
min: 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Average wait time (seconds)': {
|
||||||
|
type: 'linear',
|
||||||
|
position: 'right',
|
||||||
|
ticks: {
|
||||||
|
max: 5,
|
||||||
|
min: 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var unanswered_call_wait_time = document.getElementById('unanswered_call_wait_time_graph');
|
||||||
|
new Chart(unanswered_call_wait_time, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: <?php echo $unanswered_call_wait_time_graph_labels; ?>,
|
||||||
|
datasets: [{
|
||||||
|
label: 'Unanswered calls',
|
||||||
|
yAxisID: 'Unanswered calls',
|
||||||
|
data: <?php echo $unanswered_call_wait_time_graph_data1; ?>,
|
||||||
|
borderColor: <?php echo $unanswered_call_wait_time_graph_bgcolor1; ?>,
|
||||||
|
backgroundColor: <?php echo $unanswered_call_wait_time_graph_bgcolor1; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $unanswered_call_wait_time_graph_bgcolor1; ?>,
|
||||||
|
hoverBorderColor: <?php echo $unanswered_call_wait_time_graph_hovborder1; ?>,
|
||||||
|
}, {
|
||||||
|
label: 'Average wait time (seconds)',
|
||||||
|
yAxisID: 'Average wait time (seconds)',
|
||||||
|
data: <?php echo $unanswered_call_wait_time_graph_data2; ?>,
|
||||||
|
borderColor: <?php echo $unanswered_call_wait_time_graph_bgcolor2; ?>,
|
||||||
|
backgroundColor: <?php echo $unanswered_call_wait_time_graph_bgcolor2; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $unanswered_call_wait_time_graph_bgcolor2; ?>,
|
||||||
|
hoverBorderColor: <?php echo $unanswered_call_wait_time_graph_hovborder2; ?>,
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
scales: {
|
||||||
|
'Unanswered calls': {
|
||||||
|
type: 'linear',
|
||||||
|
position: 'left',
|
||||||
|
ticks: {
|
||||||
|
max: 5,
|
||||||
|
min: 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Average wait time (seconds)': {
|
||||||
|
type: 'linear',
|
||||||
|
position: 'right',
|
||||||
|
ticks: {
|
||||||
|
max: 5,
|
||||||
|
min: 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,729 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_IVR_rpt.inc - Vicidial Enhanced Reporting IVR report
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1619 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
if (isset($_GET["page_no"])) {$page_no=$_GET["page_no"];}
|
||||||
|
elseif (isset($_POST["page_no"])) {$page_no=$_POST["page_no"];}
|
||||||
|
if (isset($_GET["sort_ivr_details"])) {$sort_ivr_details=$_GET["sort_ivr_details"];}
|
||||||
|
elseif (isset($_POST["sort_ivr_details"])) {$sort_ivr_details=$_POST["sort_ivr_details"];}
|
||||||
|
|
||||||
|
if ($non_latin < 1)
|
||||||
|
{
|
||||||
|
$sort_ivr_details = preg_replace('/[^\s\-_0-9a-zA-Z]/','',$sort_ivr_details);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_ivr_details = preg_replace('/[^\s\-_0-9\p{L}]/u','',$sort_ivr_details);
|
||||||
|
}
|
||||||
|
$page_no=preg_replace('/[^0-9]/', '', $page_no);
|
||||||
|
if (!$page_no || $page_no<1) {$page_no=1;}
|
||||||
|
|
||||||
|
$ll=($page_no-1)*20;
|
||||||
|
$ul=($page_no*20);
|
||||||
|
$sort_clause=" order by call_date";
|
||||||
|
$sort_index=preg_replace('/ desc/', '', $sort_ivr_details);
|
||||||
|
if (preg_match('/ desc$/', $sort_ivr_details))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_ivr_details);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_ivr_details." desc";
|
||||||
|
}
|
||||||
|
$sort_ivr_details_preg=preg_replace('/ desc$/', '', $sort_ivr_details);
|
||||||
|
|
||||||
|
$ivr_data=array();
|
||||||
|
$ivr_data_totals=array();
|
||||||
|
$path_data=array();
|
||||||
|
$ivr_details=array();
|
||||||
|
|
||||||
|
# For IVR details we can't use the comment_d clause as it kicks out records that should be in there
|
||||||
|
$stmt="select distinct uniqueid, comment_a from live_inbound_log $live_inbound_log_SQL order by uniqueid asc";
|
||||||
|
if ($DB) {$HTML_output.="<B>$stmt</B>";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$i=0;
|
||||||
|
while ($row=mysqli_fetch_row($rslt))
|
||||||
|
{
|
||||||
|
$uniqueid=$row[0];
|
||||||
|
$comment_a=$row[1];
|
||||||
|
$total_call_flow="";
|
||||||
|
$prompt_stmt="select start_time, comment_d, phone_ext from live_inbound_log where uniqueid='$uniqueid' and comment_a='$comment_a' order by start_time, comment_d asc";
|
||||||
|
# print "$prompt_stmt\n";
|
||||||
|
$prompt_rslt=mysql_to_mysqli($prompt_stmt, $link);
|
||||||
|
|
||||||
|
$current_call_total_time=0;
|
||||||
|
$prev_start_time="";
|
||||||
|
$uid_is_valid=0;
|
||||||
|
while ($prompt_row=mysqli_fetch_array($prompt_rslt))
|
||||||
|
{
|
||||||
|
$current_prompt=$prompt_row["comment_d"];
|
||||||
|
|
||||||
|
if (preg_match("/$ivr_choice/i", $current_prompt)) # from search results
|
||||||
|
{$uid_is_valid=1;}
|
||||||
|
|
||||||
|
$current_start_time=$prompt_row["start_time"];
|
||||||
|
# if (mysqli_num_rows($prompt_rslt)==1) {$prev_start_time=$current_start_time;} # Need this in case only one record is returned
|
||||||
|
if (!$prev_start_time) {$prev_start_time=$current_start_time;}
|
||||||
|
|
||||||
|
$array_key=preg_replace('/\>[^,]+,/', ',', $total_call_flow);
|
||||||
|
$current_interval=strtotime("$current_start_time")-strtotime("$prev_start_time");
|
||||||
|
$total_call_flow.="$current_prompt,";
|
||||||
|
$array_key.="$current_prompt";
|
||||||
|
$current_call_total_time+=$current_interval;
|
||||||
|
|
||||||
|
if ($i>=$ll && $i<$ul || $download_rpt)
|
||||||
|
{
|
||||||
|
$current_call_total_time_fmt=($current_call_total_time>=3600 ? intval(floor($current_call_total_time/3600)).date(":i:s", $current_call_total_time) : intval(date("i", $current_call_total_time)).":".date("s", $current_call_total_time));
|
||||||
|
|
||||||
|
$ivr_details["$uniqueid"]["date"]=$prev_start_time;
|
||||||
|
$ivr_details["$uniqueid"]["caller"]=$prompt_row["phone_ext"];
|
||||||
|
$ivr_details["$uniqueid"]["ivr"]=$current_call_total_time_fmt;
|
||||||
|
$ivr_details["$uniqueid"]["ivr_path"]=$array_key;
|
||||||
|
$ivr_details["$uniqueid"]["did"]=GetDID($uniqueid);
|
||||||
|
$ivr_details["$uniqueid"]["goal"]="";
|
||||||
|
$ivr_details["$uniqueid"]["closecallid"]="";
|
||||||
|
|
||||||
|
GetGoal($uniqueid);
|
||||||
|
}
|
||||||
|
|
||||||
|
$prev_prompt=$prompt_row["comment_d"];
|
||||||
|
$prev_start_time=$prompt_row["start_time"];
|
||||||
|
}
|
||||||
|
|
||||||
|
# Does uid contain IVR choice?
|
||||||
|
if ($uid_is_valid)
|
||||||
|
{
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($ivr_details["$uniqueid"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$ivr_records=$i;
|
||||||
|
$total_pages=ceil($i/20);
|
||||||
|
|
||||||
|
$stmt="select distinct uniqueid, comment_a from live_inbound_log $live_inbound_log_SQL and comment_d like '%>%' order by uniqueid asc";
|
||||||
|
if ($DB) {$HTML_output.="<B>$stmt</B>";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
while ($row=mysqli_fetch_row($rslt))
|
||||||
|
{
|
||||||
|
$uniqueid=$row[0];
|
||||||
|
$comment_a=$row[1];
|
||||||
|
$total_call_flow="";
|
||||||
|
$current_call_total_time=0;
|
||||||
|
$prompt_stmt="select start_time, comment_d, phone_ext from live_inbound_log where uniqueid='$uniqueid' and comment_a='$comment_a' order by start_time, comment_d asc";
|
||||||
|
$prompt_rslt=mysql_to_mysqli($prompt_stmt, $link);
|
||||||
|
|
||||||
|
while ($prompt_row=mysqli_fetch_array($prompt_rslt))
|
||||||
|
{
|
||||||
|
$current_prompt=$prompt_row["comment_d"];
|
||||||
|
$current_start_time=$prompt_row["start_time"];
|
||||||
|
if (preg_match('/\>/', $current_prompt))
|
||||||
|
{
|
||||||
|
$array_key=preg_replace('/\>[^,]+,/', ',', $total_call_flow);
|
||||||
|
$total_call_flow.="$current_prompt,";
|
||||||
|
$array_key.="$current_prompt";
|
||||||
|
$current_interval=strtotime("$current_start_time")-strtotime("$prev_start_time");
|
||||||
|
$current_call_total_time+=$current_interval;
|
||||||
|
$ivr_data["$array_key"]["calls"]++;
|
||||||
|
$hangup_array=GetHangups($uniqueid);
|
||||||
|
$ivr_data["$array_key"]["hangups"]+=$hangup_array[0];
|
||||||
|
if ($hangup_array[0]==0)
|
||||||
|
{
|
||||||
|
$ivr_data["$array_key"]["goals"]++;
|
||||||
|
$ivr_data["$array_key"]["goal_time"]+=$hangup_array[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$ivr_data["$array_key"]["goals"]+=0;
|
||||||
|
$ivr_data["$array_key"]["goal_time"]+=0;
|
||||||
|
}
|
||||||
|
$ivr_data["$array_key"]["time"]+=$current_interval;
|
||||||
|
|
||||||
|
#$ivr_details["$uniqueid"]["date"]=$prev_start_time;
|
||||||
|
#$ivr_details["$uniqueid"]["caller"]=$prompt_row["phone_ext"];
|
||||||
|
#$ivr_details["$uniqueid"]["ivr"]=$current_interval;
|
||||||
|
#$ivr_details["$uniqueid"]["ivr_path"]=$array_key;
|
||||||
|
#$ivr_details["$uniqueid"]["did"]=GetDID($uniqueid);
|
||||||
|
#$ivr_details["$uniqueid"]["goal"]="";
|
||||||
|
|
||||||
|
if (!$ivr_data["$array_key"]["minimum_time"]) {$ivr_data["$array_key"]["minimum_time"]=86400;}
|
||||||
|
if (!$ivr_data["$array_key"]["maximum_time"]) {$ivr_data["$array_key"]["maximum_time"]=0;}
|
||||||
|
if ($ivr_data["$array_key"]["minimum_time"]>$current_interval) {$ivr_data["$array_key"]["minimum_time"]=$current_interval;}
|
||||||
|
if ($ivr_data["$array_key"]["maximum_time"]<$current_interval) {$ivr_data["$array_key"]["maximum_time"]=$current_interval;}
|
||||||
|
|
||||||
|
GetCallPath($uniqueid, $comment_a); # , $array_key, $current_interval
|
||||||
|
}
|
||||||
|
$prev_prompt=$prompt_row["comment_d"];
|
||||||
|
$prev_start_time=$prompt_row["start_time"];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ksort($ivr_data);
|
||||||
|
ksort($path_data);
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("IVR Traversal").": $NWB#VERM_IVR-ivr_traversal$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>\n";
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
$HTML_output.="<th>"._QXZ("IVR path")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("N. calls")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("IVR goal report")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Success rate")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Hangups")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Attrition rate")."</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$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="";
|
||||||
|
$IVR_prompt_header=array();
|
||||||
|
$IVR_prompt_subrows="";
|
||||||
|
foreach ($ivr_data as $ivr_path => $data)
|
||||||
|
{
|
||||||
|
if (preg_match("/$ivr_choice/i", $ivr_path)) # from search results
|
||||||
|
{
|
||||||
|
$ivr_path_array=explode(">", $ivr_path);
|
||||||
|
$ivr_path_base=$ivr_path_array[0]."-TOTAL";
|
||||||
|
$ivr_prompt=$ivr_path_array[1];
|
||||||
|
|
||||||
|
$ivr_data["$ivr_path_base"]["calls"]+=$data["calls"];
|
||||||
|
$ivr_data["$ivr_path_base"]["hangups"]+=$data["hangups"];
|
||||||
|
$ivr_data["$ivr_path_base"]["time"]+=$data["time"];
|
||||||
|
$ivr_data["$ivr_path_base"]["goals"]+=$data["goals"];
|
||||||
|
$ivr_data["$ivr_path_base"]["goal_time"]+=$data["goal_time"];
|
||||||
|
if (!$ivr_data["$ivr_path_base"]["minimum_time"]) {$ivr_data["$ivr_path_base"]["minimum_time"]=86400;}
|
||||||
|
if (!$ivr_data["$ivr_path_base"]["maximum_time"]) {$ivr_data["$ivr_path_base"]["maximum_time"]=0;}
|
||||||
|
if ($ivr_data["$ivr_path_base"]["minimum_time"]>$ivr_data["$ivr_path"]["minimum_time"]) {$ivr_data["$ivr_path_base"]["minimum_time"]=$ivr_data["$ivr_path"]["minimum_time"];}
|
||||||
|
if ($ivr_data["$ivr_path_base"]["maximum_time"]<$ivr_data["$ivr_path"]["maximum_time"]) {$ivr_data["$ivr_path_base"]["maximum_time"]=$ivr_data["$ivr_path"]["maximum_time"];}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if ($prev_ivr_key!=$ivr_path_base)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
$HTML_output.="<th>".$callmenu_names["$ivr_prompt"]."</th>";
|
||||||
|
$HTML_output.="<th>".$IVR_prompt_header["$ivr_prompt"]["calls"]."</th>";
|
||||||
|
$HTML_output.="<th>IVR goal report</th>";
|
||||||
|
$HTML_output.="<th>Success rate</th>";
|
||||||
|
$HTML_output.="<th>Hangups</th>";
|
||||||
|
$HTML_output.="<th>Attrition rate</th>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$IVR_prompt_header=array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$prev_ivr_key=$ivr_path_base;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ksort($ivr_data); # Again, so we have totals
|
||||||
|
|
||||||
|
# print_r($ivr_data);
|
||||||
|
|
||||||
|
foreach ($ivr_data as $ivr_path => $data)
|
||||||
|
{
|
||||||
|
if(preg_match("/$ivr_choice/i", $ivr_path)) # from search results
|
||||||
|
{
|
||||||
|
if(preg_match('/\-TOTAL$/', $ivr_path))
|
||||||
|
{
|
||||||
|
$ivr_value="";
|
||||||
|
$ivr_base=preg_replace('/\-TOTAL$/', '', $ivr_path);
|
||||||
|
$ivr_array=explode(",", $ivr_base);
|
||||||
|
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);}
|
||||||
|
$ivr_value.=$ivr_array[$i].($callmenu_names["$ivr_array[$i]"] ? " - ".$callmenu_names["$ivr_array[$i]"] : "")." => ";
|
||||||
|
}
|
||||||
|
# $ivr_value=$ivr_base." - ".$callmenu_names["$ivr_base"];
|
||||||
|
# $CSV_ivr_value=$ivr_base." - ".$callmenu_names["$ivr_base"];
|
||||||
|
$ivr_value=preg_replace('/ \=\> $/', "", $ivr_value);
|
||||||
|
$CSV_ivr_value=$ivr_value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$ivr_value=preg_replace("/^$ivr_base\>/", " # ", $ivr_path);
|
||||||
|
$CSV_ivr_value=preg_replace("/^$ivr_base\>/", " # ", $ivr_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='standard_font_small'>";
|
||||||
|
$HTML_output.="<td>".$ivr_value."</td>";
|
||||||
|
$HTML_output.="<td>".$data["calls"]."</td>";
|
||||||
|
$HTML_output.="<td>".$data["goals"]."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", (100*($data["calls"]-$data["hangups"])/$data["calls"]))." %</td>";
|
||||||
|
$HTML_output.="<td>".$data["hangups"]."</td>";
|
||||||
|
$HTML_output.="<td>".sprintf("%.1f", (100*$data["hangups"]/$data["calls"]))." %</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' colspan='6'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=ivr_traversal\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='6'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('IVR', 'ivr_traversal')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>\n";
|
||||||
|
|
||||||
|
# print $HTML_output; die;
|
||||||
|
# print_r($ivr_data); die;
|
||||||
|
|
||||||
|
# IVR traversal & timing output
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("IVR Timing").": $NWB#VERM_IVR-ivr_timing$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>\n";
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
$HTML_output.="<th>"._QXZ("IVR path")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("N. calls")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Average time")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Total time")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Minimum time")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Maximum time")."</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$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)
|
||||||
|
{
|
||||||
|
if (preg_match("/$ivr_choice/i", $comment_d)) # from search results
|
||||||
|
{
|
||||||
|
|
||||||
|
$base_path=preg_replace('/\>.+$/', '', $comment_d);
|
||||||
|
$selection=preg_replace('/^[^\>]+\>/', '', $comment_d);
|
||||||
|
if(!$prev_base_path) {$prev_base_path=$base_path;}
|
||||||
|
if (!$total_minimum_time) {$total_minimum_time=86400;}
|
||||||
|
if (!$total_maximum_time) {$total_maximum_time=0;}
|
||||||
|
|
||||||
|
if ($prev_base_path!=$base_path)
|
||||||
|
{
|
||||||
|
# Calculate totals for base path
|
||||||
|
$total_success_rate=sprintf("%.1f", (100*(($total_prompt_calls-$total_prompt_hangups)/$total_prompt_calls)));
|
||||||
|
$total_hangup_rate=sprintf("%.1f", (100*($total_prompt_hangups/$total_prompt_calls)));
|
||||||
|
$total_average_sec=round($total_prompt_time/$total_prompt_calls);
|
||||||
|
$base_average_time=($total_average_sec>=3600 ? intval(floor($total_average_sec/3600)).date(":i:s", $total_average_sec) : intval(date("i", $total_average_sec)).":".date("s", $total_average_sec));
|
||||||
|
$base_total_time=($total_prompt_time>=3600 ? intval(floor($total_prompt_time/3600)).date(":i:s", $total_prompt_time) : intval(date("i", $total_prompt_time)).":".date("s", $total_prompt_time));
|
||||||
|
$base_minimum_time=($total_minimum_time>=3600 ? intval(floor($total_minimum_time/3600)).date(":i:s", $total_minimum_time) : intval(date("i", $total_minimum_time)).":".date("s", $total_minimum_time));
|
||||||
|
$base_maximum_time=($total_maximum_time>=3600 ? intval(floor($total_maximum_time/3600)).date(":i:s", $total_maximum_time) : intval(date("i", $total_maximum_time)).":".date("s", $total_maximum_time));
|
||||||
|
|
||||||
|
$base_path_array=explode(",", $prev_base_path);
|
||||||
|
for ($i=0; $i<count($base_path_array); $i++)
|
||||||
|
{
|
||||||
|
$base_path_array[$i].=" - ".$callmenu_names["$base_path_array[$i]"];
|
||||||
|
}
|
||||||
|
$base_path_output=implode(" => ", $base_path_array);
|
||||||
|
|
||||||
|
#$traversal_header="$base_path_output -> $total_prompt_calls, ".($total_prompt_calls-$total_prompt_hangups).", $total_success_rate %, $total_prompt_hangups, $total_hangup_rate %\n";
|
||||||
|
#$traversal_output.=$traversal_header.$traversal_outputs."\n";
|
||||||
|
|
||||||
|
# $time_header="$base_path_output -> $total_prompt_calls, $base_average_time, $base_total_time, $base_minimum_time, $base_maximum_time \n";
|
||||||
|
# $CSV_time_output.=$time_header.$CSV_time_outputs."\n";
|
||||||
|
|
||||||
|
$HTML_subheader="<tr class='standard_font_small'><td>$base_path_output</td><td>$total_prompt_calls</td><td>$base_average_time</td><td>$base_total_time</td><td>$base_minimum_time</td><td>$base_maximum_time</td></tr>";
|
||||||
|
$HTML_output.=$HTML_subheader.$HTML_datarows;
|
||||||
|
$HTML_datarows="";
|
||||||
|
|
||||||
|
$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="";
|
||||||
|
|
||||||
|
|
||||||
|
# Reset data
|
||||||
|
$traversal_outputs="";
|
||||||
|
$CSV_time_outputs="";
|
||||||
|
$total_prompt_calls=0;
|
||||||
|
$total_prompt_hangups=0;
|
||||||
|
$total_prompt_time=0;
|
||||||
|
$total_minimum_time=86400;
|
||||||
|
$total_maximum_time=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$average_sec=round($data["time"]/$data["calls"]);
|
||||||
|
$average_time=($average_sec>=3600 ? intval(floor($average_sec/3600)).date(":i:s", $average_sec) : intval(date("i", $average_sec)).":".date("s", $average_sec));
|
||||||
|
$total_time=($data["time"]>=3600 ? intval(floor($data["time"]/3600)).date(":i:s", $data["time"]) : intval(date("i", $data["time"])).":".date("s", $data["time"]));
|
||||||
|
$minimum_time=($data["minimum_time"]>=3600 ? intval(floor($data["minimum_time"]/3600)).date(":i:s", $data["minimum_time"]) : intval(date("i", $data["minimum_time"])).":".date("s", $data["minimum_time"]));
|
||||||
|
$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"]));
|
||||||
|
|
||||||
|
$success_rate=sprintf("%.1f", (100*(($data["calls"]-$data["hangups"])/$data["calls"])));
|
||||||
|
$hangup_rate=sprintf("%.1f", (100*($data["hangups"]/$data["calls"])));
|
||||||
|
#$traversal_outputs.=" - $selection -> ".$data["calls"].", ".($data["calls"]-$data["hangups"]).", $success_rate %, ".$data["hangups"].", $hangup_rate % \n";
|
||||||
|
#$CSV_time_outputs.=" - $selection -> ".$data["calls"].", $average_time, $total_time, $minimum_time, $maximum_time\n";
|
||||||
|
$HTML_datarows.="<tr class='standard_font_small'><td> # $selection</td><td>".$data["calls"]."</td><td>$average_time</td><td>$total_time</td><td>$minimum_time</td><td>$maximum_time</td></tr>\n";
|
||||||
|
$CSV_row_output.="\" # $selection\",\"".$data["calls"]."\",\"$average_time\",\"$total_time\",\"$minimum_time\",\"$maximum_time\"\n";
|
||||||
|
$total_prompt_calls+=$data["calls"];
|
||||||
|
$total_prompt_hangups+=$data["hangups"];
|
||||||
|
$total_prompt_time+=$data["time"];
|
||||||
|
|
||||||
|
if ($total_minimum_time>$data["minimum_time"]) {$total_minimum_time=$data["minimum_time"];}
|
||||||
|
if ($total_maximum_time<$data["maximum_time"]) {$total_maximum_time=$data["maximum_time"];}
|
||||||
|
|
||||||
|
$prev_base_path=$base_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$total_average_sec=round($total_prompt_time/$total_prompt_calls);
|
||||||
|
$base_average_time=($total_average_sec>=3600 ? intval(floor($total_average_sec/3600)).date(":i:s", $total_average_sec) : intval(date("i", $total_average_sec)).":".date("s", $total_average_sec));
|
||||||
|
$base_total_time=($total_prompt_time>=3600 ? intval(floor($total_prompt_time/3600)).date(":i:s", $total_prompt_time) : intval(date("i", $total_prompt_time)).":".date("s", $total_prompt_time));
|
||||||
|
$base_minimum_time=($total_minimum_time>=3600 ? intval(floor($total_minimum_time/3600)).date(":i:s", $total_minimum_time) : intval(date("i", $total_minimum_time)).":".date("s", $total_minimum_time));
|
||||||
|
$base_maximum_time=($total_maximum_time>=3600 ? intval(floor($total_maximum_time/3600)).date(":i:s", $total_maximum_time) : intval(date("i", $total_maximum_time)).":".date("s", $total_maximum_time));
|
||||||
|
|
||||||
|
#$traversal_header="$prev_base_path -> $total_prompt_calls, ".($total_prompt_calls-$total_prompt_hangups).", $total_success_rate %, $total_prompt_hangups, $total_hangup_rate %\n";
|
||||||
|
#$traversal_output.=$traversal_header.$traversal_outputs;
|
||||||
|
|
||||||
|
# $time_header="$prev_base_path -> $total_prompt_calls, $base_average_time, $base_total_time, $base_minimum_time, $base_maximum_time \n";
|
||||||
|
# $CSV_time_output.=$time_header.$CSV_time_outputs."\n";
|
||||||
|
|
||||||
|
$HTML_subheader="<tr class='standard_font_small'><td>$prev_base_path - $callmenu_names[$prev_base_path]</td><td>$total_prompt_calls</td><td>$base_average_time</td><td>$base_total_time</td><td>$base_minimum_time</td><td>$base_maximum_time</td></tr>\n";
|
||||||
|
$HTML_output.=$HTML_subheader.$HTML_datarows;
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' colspan='6'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=ivr_timing\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='6'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('IVR', 'ivr_timing')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>\n";
|
||||||
|
|
||||||
|
$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;
|
||||||
|
|
||||||
|
# print $CSV_time_output;
|
||||||
|
|
||||||
|
# print $CSV_output["ivr_timing"]; die;
|
||||||
|
|
||||||
|
# print $HTML_output;
|
||||||
|
|
||||||
|
# IVR goal output
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("IVR Goals").": $NWB#VERM_IVR-ivr_goals$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>\n";
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Goal")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("IVR path")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Selection")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("N. calls")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Average time")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Minimum time")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Maximum time")."</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["ivr_goal"]="\""._QXZ("Goal")."\",\""._QXZ("IVR path")."\",\""._QXZ("Selection")."\",\""._QXZ("N. calls")."\",\""._QXZ("Average time")."\",\""._QXZ("Minimum time")."\",\""._QXZ("Maximum time")."\"\n";
|
||||||
|
|
||||||
|
foreach ($path_data as $goal => $path)
|
||||||
|
{
|
||||||
|
ksort($path);
|
||||||
|
foreach ($path as $key => $data)
|
||||||
|
{
|
||||||
|
if (preg_match("/$ivr_choice/i", $key)) # from search results
|
||||||
|
{
|
||||||
|
$key_array=explode(">", $key);
|
||||||
|
|
||||||
|
$final_key_path="";
|
||||||
|
$ivr_array=explode(",", $key_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);
|
||||||
|
$CSV_final_key_path=$final_key_path;
|
||||||
|
|
||||||
|
$average_sec=round($data["time"]/$data["calls"]);
|
||||||
|
$average_time=($average_sec>=3600 ? intval(floor($average_sec/3600)).date(":i:s", $average_sec) : intval(date("i", $average_sec)).":".date("s", $average_sec));
|
||||||
|
$minimum_time=($data["minimum_time"]>=3600 ? intval(floor($data["minimum_time"]/3600)).date(":i:s", $data["minimum_time"]) : intval(date("i", $data["minimum_time"])).":".date("s", $data["minimum_time"]));
|
||||||
|
$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>".$key_array[0]." - ".$callmenu_names["$key_array[0]"]."</td>";
|
||||||
|
$HTML_output.="<td>".$final_key_path."</td>";
|
||||||
|
$HTML_output.="<td>".$key_array[1]."</td>";
|
||||||
|
$HTML_output.="<td>".$data["calls"]."</td>";
|
||||||
|
$HTML_output.="<td>".$average_time."</td>";
|
||||||
|
$HTML_output.="<td>".$minimum_time."</td>";
|
||||||
|
$HTML_output.="<td>".$maximum_time."</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["ivr_goal"].="\"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]."\",";
|
||||||
|
$CSV_output["ivr_goal"].="\"".$data["calls"]."\",";
|
||||||
|
$CSV_output["ivr_goal"].="\"".$average_time."\",";
|
||||||
|
$CSV_output["ivr_goal"].="\"".$minimum_time."\",";
|
||||||
|
$CSV_output["ivr_goal"].="\"".$maximum_time."\"";
|
||||||
|
$CSV_output["ivr_goal"].="\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=ivr_goal\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('IVR', 'ivr_goal')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
|
||||||
|
#############################
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header' id='sid_anchor'>"._QXZ("IVR Details").": $NWB#VERM_IVR-ivr_details$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>\n";
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='left'>";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('IVR', '1')\" title=\"First page\" value='|<'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('IVR', '".($page_no-1)."')\" title=\"Prev page\" value='<<'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='center' colspan='5'> </td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='right'>";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('IVR', '".($page_no<$total_pages ? $page_no+1 : $total_pages)."')\" title=\"Next page\" value='>>'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('IVR', '".($total_pages)."')\" title=\"Last page\" value='>|'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$ivr_details_columns=array(
|
||||||
|
_QXZ("Date") => "date",
|
||||||
|
_QXZ("Caller") => "caller",
|
||||||
|
_QXZ("IVR") => "ivr",
|
||||||
|
_QXZ("IVR Path") => "ivr_path",
|
||||||
|
_QXZ("DID") => "did",
|
||||||
|
_QXZ("Goal") => "goal",
|
||||||
|
);
|
||||||
|
|
||||||
|
$CSV_output["ivr_details"]="";
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
foreach ($ivr_details_columns as $display_name => $column_name)
|
||||||
|
{
|
||||||
|
if ($display_name!="uniqueid")
|
||||||
|
{
|
||||||
|
$CSV_output["ivr_details"].="\"$display_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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$CSV_output["ivr_details"].="\n";
|
||||||
|
$HTML_output.="<th> </th></tr>\n";
|
||||||
|
|
||||||
|
if ($sort_index)
|
||||||
|
{
|
||||||
|
foreach ($ivr_details as $sorting_array) {
|
||||||
|
$sort_array_holder[] = $sorting_array["$sort_index"];
|
||||||
|
}
|
||||||
|
if (preg_match('/ desc$/', $sort_ivr_details))
|
||||||
|
{
|
||||||
|
array_multisort($sort_array_holder,SORT_DESC, SORT_STRING,$ivr_details);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_multisort($sort_array_holder,SORT_ASC, SORT_STRING,$ivr_details);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($ivr_details as $uniqueid => $data_row)
|
||||||
|
{
|
||||||
|
$detail_id=$uniqueid;
|
||||||
|
|
||||||
|
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")
|
||||||
|
{
|
||||||
|
$detail_id.="|$value";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($key=="date")
|
||||||
|
{
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$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.="</tr>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='left'><B><a class='header_link' href='".$PHP_SELF."?sort_ivr_details=".$sort_ivr_details."&page_no=1#page_anchor' alt='First page of results'>|<</a> <a class='header_link' href='".$PHP_SELF."?sort_ivr_details=".$sort_ivr_details."&page_no=".($page_no-1)."#page_anchor' alt='Prev page of results'><<</a></B></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='left'>";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('IVR', '1')\" title=\"First page\" value='|<'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('IVR', '".($page_no-1)."')\" title=\"Prev page\" value='<<'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='center' colspan='5'>"._QXZ("Export as")."... <a href=\"".$PHP_SELF."?download_rpt=ivr_details&sort_ivr_details=".$sort_ivr_details."\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a> "._QXZ("Current page").": $page_no / $total_pages</td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='center' colspan='5'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('IVR', 'ivr_details')\" title=\"Export as a CSV file\" value='CSV'> "._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_ivr_details=".$sort_ivr_details."&page_no=".($page_no+1)."#page_anchor' alt='Next page of results'>>></a> <a class='header_link' href='".$PHP_SELF."?sort_ivr_details=".$sort_ivr_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('IVR', '".($page_no<$total_pages ? $page_no+1 : $total_pages)."')\" title=\"Next page\" value='>>'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('IVR', '".($total_pages)."')\" title=\"Last page\" value='>|'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$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 ($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)
|
||||||
|
{
|
||||||
|
$data_to_download=$CSV_output["$download_rpt"];
|
||||||
|
|
||||||
|
$FILE_TIME = date("Ymd-His");
|
||||||
|
$CSVfilename = "IVR_RPT_".$download_rpt."_".$FILE_TIME.".csv";
|
||||||
|
header('Content-type: application/octet-stream');
|
||||||
|
|
||||||
|
header("Content-Disposition: attachment; filename=\"$CSVfilename\"");
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
ob_clean();
|
||||||
|
flush();
|
||||||
|
|
||||||
|
echo "$data_to_download";
|
||||||
|
|
||||||
|
if ($db_source == 'S')
|
||||||
|
{
|
||||||
|
mysqli_close($link);
|
||||||
|
$use_slave_server=0;
|
||||||
|
$db_source = 'M';
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
$endMS = microtime();
|
||||||
|
$startMSary = explode(" ",$startMS);
|
||||||
|
$endMSary = explode(" ",$endMS);
|
||||||
|
$runS = ($endMSary[0] - $startMSary[0]);
|
||||||
|
$runM = ($endMSary[1] - $startMSary[1]);
|
||||||
|
$TOTALrun = ($runS + $runM);
|
||||||
|
|
||||||
|
# $stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';";
|
||||||
|
# if ($DB) {echo "|$stmt|\n";}
|
||||||
|
# $rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
echo $HTML_output;
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
function GetHangups($call_uniqueid)
|
||||||
|
{
|
||||||
|
global $DB, $link;
|
||||||
|
$hangups=array("AFTHRS", "NANQUE");
|
||||||
|
$status="";
|
||||||
|
|
||||||
|
$vcl_stmt="select status, campaign_id, queue_seconds from vicidial_closer_log where uniqueid='$call_uniqueid' order by call_date asc limit 1";
|
||||||
|
$vcl_rslt=mysql_to_mysqli($vcl_stmt, $link);
|
||||||
|
while ($vcl_row=mysqli_fetch_row($vcl_rslt))
|
||||||
|
{
|
||||||
|
# if (!in_array("$vcl_row[0]", $hangups))
|
||||||
|
# {
|
||||||
|
return array(0, $vcl_row[2]);
|
||||||
|
# }
|
||||||
|
}
|
||||||
|
return array(1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetGoal($call_uniqueid)
|
||||||
|
{
|
||||||
|
global $DB, $link, $path_data, $ivr_details, $array_key;
|
||||||
|
$vcl_stmt="select campaign_id, closecallid from vicidial_closer_log where uniqueid='$call_uniqueid' order by call_date asc limit 1";
|
||||||
|
#print $vcl_stmt."\n";
|
||||||
|
$vcl_rslt=mysql_to_mysqli($vcl_stmt, $link);
|
||||||
|
while ($vcl_row=mysqli_fetch_row($vcl_rslt))
|
||||||
|
{
|
||||||
|
$ivr_details["$call_uniqueid"]["goal"]=$vcl_row[0];
|
||||||
|
$ivr_details["$call_uniqueid"]["closecallid"]=$vcl_row[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetCallPath($call_uniqueid, $comment_a)
|
||||||
|
{
|
||||||
|
global $DB, $link, $path_data, $array_key;
|
||||||
|
$vcl_stmt="select campaign_id from vicidial_closer_log where uniqueid='$call_uniqueid' order by call_date asc limit 1";
|
||||||
|
#print $vcl_stmt."\n";
|
||||||
|
$vcl_rslt=mysql_to_mysqli($vcl_stmt, $link);
|
||||||
|
while ($vcl_row=mysqli_fetch_row($vcl_rslt))
|
||||||
|
{
|
||||||
|
$path_data["$vcl_row[0]"]["$array_key"]["calls"]++;
|
||||||
|
# $ivr_details["$call_uniqueid"]["goal"]=$vcl_row[0];
|
||||||
|
|
||||||
|
$time_stmt="select timestampdiff(SECOND, min(start_time), max(start_time)) from live_inbound_log where uniqueid='$call_uniqueid' and comment_a='$comment_a'";
|
||||||
|
$time_rslt=mysql_to_mysqli($time_stmt, $link);
|
||||||
|
if (mysqli_num_rows($time_rslt)>0)
|
||||||
|
{
|
||||||
|
$time_row=mysqli_fetch_row($time_rslt);
|
||||||
|
$total_call_time=$time_row[0];
|
||||||
|
|
||||||
|
$path_data["$vcl_row[0]"]["$array_key"]["time"]+=$total_call_time;
|
||||||
|
|
||||||
|
if (!$path_data["$vcl_row[0]"]["$array_key"]["minimum_time"]) {$path_data["$vcl_row[0]"]["$array_key"]["minimum_time"]=86400;}
|
||||||
|
if (!$path_data["$vcl_row[0]"]["$array_key"]["maximum_time"]) {$path_data["$vcl_row[0]"]["$array_key"]["maximum_time"]=0;}
|
||||||
|
|
||||||
|
if ($path_data["$vcl_row[0]"]["$array_key"]["minimum_time"]>$total_call_time) {$path_data["$vcl_row[0]"]["$array_key"]["minimum_time"]=$total_call_time;}
|
||||||
|
if ($path_data["$vcl_row[0]"]["$array_key"]["maximum_time"]<$total_call_time) {$path_data["$vcl_row[0]"]["$array_key"]["maximum_time"]=$total_call_time;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetDID($uniqueid)
|
||||||
|
{
|
||||||
|
global $link, $DB, $did_id_info, $did_pattern_info;
|
||||||
|
|
||||||
|
$did_str="";
|
||||||
|
|
||||||
|
$did_stmt="select extension, did_id from vicidial_did_log where uniqueid in ('$uniqueid')";
|
||||||
|
$did_rslt=mysqli_query($link, $did_stmt);
|
||||||
|
$did_row=mysqli_fetch_array($did_rslt);
|
||||||
|
$did_str=$did_row["extension"]." - ".$did_id_info["$did_row[did_id]"];
|
||||||
|
|
||||||
|
return $did_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_IVR_survey_details_rpt.inc - Vicidial Enhanced Reporting IVR survey detail report
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1618 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
# $DB=1;
|
||||||
|
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";
|
||||||
|
if ($DB){$HTML_output.="$ingrp_stmt<BR>";}
|
||||||
|
$ingrp_rslt=mysql_to_mysqli($ingrp_stmt, $link);
|
||||||
|
while($ingrp_row=mysqli_fetch_row($ingrp_rslt))
|
||||||
|
{
|
||||||
|
$survey_name=$ingrp_row[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$comment_a_clause=" and comment_a='$comment_a' ";
|
||||||
|
$ivr_stmt="select distinct uniqueid from live_inbound_log $live_inbound_log_SQL $comment_a_clause order by uniqueid asc";
|
||||||
|
if ($DB){$HTML_output.="$ivr_stmt<BR>";}
|
||||||
|
$ivr_rslt=mysql_to_mysqli($ivr_stmt, $link);
|
||||||
|
if (mysqli_num_rows($ivr_rslt)>0)
|
||||||
|
{
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("IVR Details for survey")." $survey_name: $NWB#VERM_IVR-ivr_survey_details$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>\n";
|
||||||
|
$HTML_output.="<tr class='standard_font_small bold'>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Date")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Caller")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("DID")."</th>";
|
||||||
|
for ($t=0; $t<count($callmenu_list); $t++)
|
||||||
|
{
|
||||||
|
$svy_menu=$callmenu_list[$t];
|
||||||
|
$cm_stmt="select menu_name from vicidial_call_menu where menu_id='$svy_menu'";
|
||||||
|
$cm_rslt=mysql_to_mysqli($cm_stmt, $link);
|
||||||
|
$cm_row=mysqli_fetch_row($cm_rslt);
|
||||||
|
$HTML_output.="<th>".$svy_menu." - ".$cm_row[0]."</th>";
|
||||||
|
}
|
||||||
|
$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";
|
||||||
|
|
||||||
|
while ($ivr_row=mysqli_fetch_row($ivr_rslt))
|
||||||
|
{
|
||||||
|
$did_found=0;
|
||||||
|
$svy_uniqueid=$ivr_row[0];
|
||||||
|
$svy_goal=$ivr_details["$svy_uniqueid"]["goal"];
|
||||||
|
|
||||||
|
$vcl_stmt="select user, phone_number, closecallid, xfercallid, call_date, lead_id from vicidial_closer_log where uniqueid='$svy_uniqueid' order by call_date desc limit 1";
|
||||||
|
$vcl_rslt=mysql_to_mysqli($vcl_stmt, $link);
|
||||||
|
while($vcl_row=mysqli_fetch_array($vcl_rslt))
|
||||||
|
{
|
||||||
|
$agent_who_handled=$fullname_info["$vcl_row[user]"];
|
||||||
|
$caller=$vcl_row["phone_number"];
|
||||||
|
$date=$vcl_row["call_date"];
|
||||||
|
$vicidial_id=$vcl_row["closecallid"];
|
||||||
|
$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_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>";
|
||||||
|
}
|
||||||
|
|
||||||
|
$failsafe=0;
|
||||||
|
$did_pattern="";
|
||||||
|
$did_uniqueid=$svy_uniqueid;
|
||||||
|
while(!$did_found)
|
||||||
|
{
|
||||||
|
$did_stmt="select call_date, did_id, extension, caller_id_number from vicidial_did_log where uniqueid='$did_uniqueid' order by call_date asc limit 1";
|
||||||
|
if ($DB){$HTML_output.="$did_stmt<BR>";}
|
||||||
|
$did_rslt=mysql_to_mysqli($did_stmt, $link);
|
||||||
|
if (mysqli_num_rows($did_rslt)>0)
|
||||||
|
{
|
||||||
|
$did_row=mysqli_fetch_row($did_rslt);
|
||||||
|
$did_id=$did_row[1];
|
||||||
|
$did_pattern_stmt="select did_pattern from vicidial_inbound_dids where did_id='$did_id'";
|
||||||
|
$did_pattern_rslt=mysql_to_mysqli($did_pattern_stmt, $link);
|
||||||
|
$did_found=1;
|
||||||
|
$did_pattern_row=mysqli_fetch_row($did_pattern_rslt);
|
||||||
|
$did_pattern=$did_pattern_row[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$failsafe++;
|
||||||
|
if ($failsafe>=5) {$did_found=1;}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$lil_stmt="select group_concat(comment_b) as survey_path from live_inbound_log where uniqueid='$svy_uniqueid' $comment_a_clause order by start_time";
|
||||||
|
if ($DB){$HTML_output.="$lil_stmt<BR>";}
|
||||||
|
$lil_rslt=mysql_to_mysqli($lil_stmt, $link);
|
||||||
|
$lil_row=mysqli_fetch_row($lil_rslt);
|
||||||
|
$lil_array=explode(",", $lil_row[0]);
|
||||||
|
$full_path=$lil_row[0];
|
||||||
|
|
||||||
|
$survey_array=array();
|
||||||
|
for ($i=0; $i<count($lil_array); $i+=2)
|
||||||
|
{
|
||||||
|
$survey=$lil_array[$i];
|
||||||
|
$survey_answer=$lil_array[($i+1)];
|
||||||
|
$survey_array["$survey"]=$survey_answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='standard_font_small'>";
|
||||||
|
$HTML_output.="<td>$date</td>";
|
||||||
|
$HTML_output.="<td>$caller</td>";
|
||||||
|
$HTML_output.="<td>$did_pattern</td>";
|
||||||
|
|
||||||
|
for ($i=0; $i<count($callmenu_list); $i++)
|
||||||
|
{
|
||||||
|
$svy_menu=$callmenu_list[$i];
|
||||||
|
$HTML_output.="<td>".(!$survey_array["$svy_menu"] ? " " : $survey_array["$svy_menu"])."</td>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ivr_survey_ingroups_voicemails)
|
||||||
|
{
|
||||||
|
$voicemail="No";
|
||||||
|
foreach($ivr_survey_ingroups_voicemails as $callmenu => $prompt)
|
||||||
|
{
|
||||||
|
$vm_prompt="$callmenu,$prompt";
|
||||||
|
if (preg_match("/$vm_prompt/", $full_path))
|
||||||
|
{
|
||||||
|
$voicemail="Yes";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$voicemail="N/A";
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="<td>".$voicemail."</td>";
|
||||||
|
$HTML_output.="<td>$agent_who_handled</td>";
|
||||||
|
$HTML_output.="<td>$rec_link</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,921 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_OUTCOEMS_rpt.inc - Vicidial Enhanced Reporting call outcomes report
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1617 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
# NANQUE, not an unanswered call?
|
||||||
|
# TIMEOT, unanswered even though it was dropped into a call that was picked up
|
||||||
|
# Warm transfers count as two calls
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
# if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];}
|
||||||
|
# elseif (isset($_POST["SUBMIT"])) {$SUBMIT=$_POST["SUBMIT"];}
|
||||||
|
if (isset($_GET["sort_call_results"])) {$sort_call_results=$_GET["sort_call_results"];}
|
||||||
|
elseif (isset($_POST["sort_call_results"])) {$sort_call_results=$_POST["sort_call_results"];}
|
||||||
|
if (isset($_GET["sort_billable_activities"])) {$sort_billable_activities=$_GET["sort_billable_activities"];}
|
||||||
|
elseif (isset($_POST["sort_billable_activities"])) {$sort_billable_activities=$_POST["sort_billable_activities"];}
|
||||||
|
if (isset($_GET["sort_nonbillable_activities"])) {$sort_nonbillable_activities=$_GET["sort_nonbillable_activities"];}
|
||||||
|
elseif (isset($_POST["sort_nonbillable_activities"])) {$sort_nonbillable_activities=$_POST["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 ($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);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_call_results = preg_replace('/[^\s\-_0-9\p{L}]/u','',$sort_call_results);
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
|
||||||
|
### FUNCTION
|
||||||
|
function LookUpCall($uniqueid, $comments)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
|
||||||
|
$call_outcome="";
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
return $call_outcome;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (preg_match('/ desc$/', $sort_agent_pause_detail))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_agent_pause_detail);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_agent_pause_detail." desc";
|
||||||
|
}
|
||||||
|
$sort_agent_pause_detail_preg=preg_replace('/ desc$/', '', $sort_agent_pause_detail);
|
||||||
|
if ($DB) {$HTML_output.="<B>$vcl_uniqueid_stmt</B><BR>$included_campaigns_ct<BR>";}
|
||||||
|
# COVERS AGENT ANSWERED CALLS ONLY - NEED SEPARATE SECTION FOR NON-ANSWERS!!!!
|
||||||
|
# 1/23/2022- added status!='' call, meaning calls with no dispos don't get displayed
|
||||||
|
# Had to add this otherwise the counts go screwy
|
||||||
|
|
||||||
|
$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_inb="";
|
||||||
|
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=$outcomes_stmt_outb.($outcomes_stmt_outb!="" && $outcomes_stmt_inb!="" ? " UNION " : "").$outcomes_stmt_inb;
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (count($val_uniqueid_array)>0 && $atomic_queue_campaigns_str=="") // No OUTBOUND campaigns in queue, INBOUND ONLY. Need to account for this!
|
||||||
|
{
|
||||||
|
$outcomes_stmt.=" UNION 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)."')";
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
# $HTML_output.="\n\n<!-- $outcomes_stmt //-->\n\n";
|
||||||
|
|
||||||
|
if ($DB) {$HTML_output.="Statuses:<B>$outcomes_stmt</B><BR>";}
|
||||||
|
|
||||||
|
$outcomes_rslt=mysql_to_mysqli($outcomes_stmt, $link);
|
||||||
|
$outcomes_array=array();
|
||||||
|
$call_results_array=array();
|
||||||
|
$call_types_array=array();
|
||||||
|
$billable_activities_array=array();
|
||||||
|
$nonbillable_activities_array=array();
|
||||||
|
$agent_details_array=array();
|
||||||
|
$outcomes_per_agent_array=array();
|
||||||
|
$call_results_total_calls=0;
|
||||||
|
while ($outcomes_row=mysqli_fetch_array($outcomes_rslt))
|
||||||
|
{
|
||||||
|
$lead_id=$outcomes_row["lead_id"];
|
||||||
|
$campaign_id=$outcomes_row["campaign_id"];
|
||||||
|
$status=$outcomes_row["status"];
|
||||||
|
$user=$outcomes_row["user"];
|
||||||
|
$pause_code=$outcomes_row["pause_code"];
|
||||||
|
$pause_sec=$outcomes_row["pause_sec"];
|
||||||
|
$talk_sec=$outcomes_row["talk_sec"];
|
||||||
|
$wait_sec=$outcomes_row["wait_sec"];
|
||||||
|
$dispo_sec=$outcomes_row["dispo_sec"];
|
||||||
|
$uniqueid=$outcomes_row["uniqueid"];
|
||||||
|
$comments=$outcomes_row["comments"];
|
||||||
|
$call_type="Unknown";
|
||||||
|
$pause_name_key=$campaign_id."-".$pause_code;
|
||||||
|
$pause_code_name=$pause_code;
|
||||||
|
|
||||||
|
$full_name=$fullname_info["$user"];
|
||||||
|
if (!$agent_details_array["$full_name"])
|
||||||
|
{
|
||||||
|
$agent_details_array["$full_name"]["available"]=0;
|
||||||
|
$agent_details_array["$full_name"]["billable"]=0;
|
||||||
|
$agent_details_array["$full_name"]["nonbillable"]=0;
|
||||||
|
$agent_details_array["$full_name"]["sales"]=0;
|
||||||
|
$agent_details_array["$full_name"]["human_answered"]=0;
|
||||||
|
$agent_details_array["$full_name"]["customer_contacts"]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$outcomes_array["total_billable_time"]+=($talk_sec+$wait_sec+$dispo_sec);
|
||||||
|
$outcomes_array["total_agent_available_time"]+=($talk_sec+$wait_sec+$dispo_sec);
|
||||||
|
|
||||||
|
$agent_details_array["$full_name"]["available"]+=($talk_sec+$wait_sec+$dispo_sec);
|
||||||
|
|
||||||
|
# Billable/nonbillable activity
|
||||||
|
if (in_array($pause_code, $billable_pause_codes["$campaign_id"]) || in_array($pause_code, $billable_pause_codes["SYSTEM"]))
|
||||||
|
{
|
||||||
|
if ($pause_code_names["$pause_name_key"])
|
||||||
|
{
|
||||||
|
$pause_code_name=$pause_code_names["$pause_name_key"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$outcomes_array["total_billable_time"]+=$pause_sec;
|
||||||
|
$outcomes_array["total_agent_billable_activities"]+=$pause_sec;
|
||||||
|
|
||||||
|
if (!$billable_activities_array["$pause_code_name"])
|
||||||
|
{
|
||||||
|
$billable_activities_array["$pause_code_name"]["n_times"]=0;
|
||||||
|
$billable_activities_array["$pause_code_name"]["total_time"]=0;
|
||||||
|
$billable_activities_array["$pause_code_name"]["max"]=0;
|
||||||
|
$billable_activities_array["$pause_code_name"]["min"]=100000;
|
||||||
|
}
|
||||||
|
$billable_activities_array["$pause_code_name"]["n_times"]++;
|
||||||
|
$billable_activities_array["$pause_code_name"]["total_time"]+=$pause_sec;
|
||||||
|
if ($billable_activities_array["$pause_code_name"]["max"]<$pause_sec) {$billable_activities_array["$pause_code_name"]["max"]=$pause_sec;}
|
||||||
|
if ($billable_activities_array["$pause_code_name"]["min"]>$pause_sec) {$billable_activities_array["$pause_code_name"]["min"]=$pause_sec;}
|
||||||
|
|
||||||
|
$agent_details_array["$full_name"]["billable"]+=$pause_sec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($pause_code_names["$pause_name_key"])
|
||||||
|
{
|
||||||
|
$pause_code_name=$pause_code_names["$pause_name_key"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$outcomes_array["total_nonbillable_time"]+=$pause_sec;
|
||||||
|
|
||||||
|
if (!$nonbillable_activities_array["$pause_code_name"])
|
||||||
|
{
|
||||||
|
$nonbillable_activities_array["$pause_code_name"]["n_times"]=0;
|
||||||
|
$nonbillable_activities_array["$pause_code_name"]["total_time"]=0;
|
||||||
|
$nonbillable_activities_array["$pause_code_name"]["max"]=0;
|
||||||
|
$nonbillable_activities_array["$pause_code_name"]["min"]=100000;
|
||||||
|
}
|
||||||
|
|
||||||
|
$nonbillable_activities_array["$pause_code_name"]["n_times"]++;
|
||||||
|
$nonbillable_activities_array["$pause_code_name"]["total_time"]+=$pause_sec;
|
||||||
|
if ($nonbillable_activities_array["$pause_code_name"]["max"]<$pause_sec) {$nonbillable_activities_array["$pause_code_name"]["max"]=$pause_sec;}
|
||||||
|
if ($nonbillable_activities_array["$pause_code_name"]["min"]>$pause_sec) {$nonbillable_activities_array["$pause_code_name"]["min"]=$pause_sec;}
|
||||||
|
|
||||||
|
$agent_details_array["$full_name"]["nonbillable"]+=$pause_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
$call_outcome=$status;
|
||||||
|
|
||||||
|
if (strlen($call_outcome)<=1)
|
||||||
|
{
|
||||||
|
$call_type="None";
|
||||||
|
$status=LookUpCall($uniqueid, $comments);
|
||||||
|
# print "$status=LookUpCall($uniqueid, $comments);<BR>\n";
|
||||||
|
$call_outcome=$status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($status_names["$status"])
|
||||||
|
{
|
||||||
|
$call_outcome=$status_names["$status"];
|
||||||
|
|
||||||
|
$call_type="Known";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$call_outcome.=" (unknown)";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen($call_outcome)<=1)
|
||||||
|
{
|
||||||
|
$call_type="None";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Human answered (contact)
|
||||||
|
if (in_array($status, $human_ans_array["$campaign_id"]) || in_array($status, $human_ans_array["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$outcomes_array["human_answered"]++;
|
||||||
|
|
||||||
|
$agent_details_array["$full_name"]["human_answered"]++;
|
||||||
|
|
||||||
|
$call_type="Human answered";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Customer contact (qualified contact)
|
||||||
|
if (in_array($status, $contact_array["$campaign_id"]) || in_array($status, $contact_array["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$outcomes_array["customer_contacts"]++;
|
||||||
|
|
||||||
|
$agent_details_array["$full_name"]["customer_contacts"]++;
|
||||||
|
|
||||||
|
$call_type="Customer contact";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Sales
|
||||||
|
if (in_array($status, $sale_array["$campaign_id"]) || in_array($status, $sale_array["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$outcomes_array["sales"]++;
|
||||||
|
|
||||||
|
$agent_details_array["$full_name"]["sales"]++;
|
||||||
|
|
||||||
|
$call_type="Sale";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$call_types_array["$call_outcome"]) {$call_types_array["$call_outcome"]=$call_type;}
|
||||||
|
|
||||||
|
# Only count results if this is an agent log record with a lead id, i.e. an actual call
|
||||||
|
if (strlen($lead_id)>0)
|
||||||
|
{
|
||||||
|
$call_results_array["$call_outcome"]["total"]++;
|
||||||
|
$call_results_total_calls++;
|
||||||
|
|
||||||
|
if (in_array($status, $lost_statuses_array))
|
||||||
|
{
|
||||||
|
$call_results_array["$call_outcome"]["lost"]++;
|
||||||
|
$call_results_array["$call_outcome"]["taken"]+=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$call_results_array["$call_outcome"]["lost"]+=0;
|
||||||
|
$call_results_array["$call_outcome"]["taken"]++;
|
||||||
|
}
|
||||||
|
$call_results_array["$call_outcome"]["call_type"]=$call_type;
|
||||||
|
|
||||||
|
# $outcomes_per_agent_array["$full_name"]["$call_type"]["$call_outcome"]["$status"]++; #
|
||||||
|
|
||||||
|
$opa_key="$full_name|$call_type|$call_outcome|$status";
|
||||||
|
$outcomes_per_agent_array["$opa_key"]++;
|
||||||
|
|
||||||
|
# $outcomes_per_agent_array_agents["$full_name"]++; #
|
||||||
|
# $outcomes_per_agent_array_types["$call_type"]++; #
|
||||||
|
# $outcomes_per_agent_array_outcomes["$call_outcome"]++; #
|
||||||
|
# $outcomes_per_agent_array_statuses["$full_name"]++; #
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# print "\n\n<!-- $outcomes_stmt //-->\n\n";
|
||||||
|
# print_r($call_results_array); die;
|
||||||
|
|
||||||
|
# Get LOST calls here for $call_results_array values - query for VDAD and VDCL
|
||||||
|
/* COMMENTED OUT 2/17 - DOES NOTHING (missing "nousers" variables) AND ERRORS ANYWAY
|
||||||
|
$lost_stmt="select status, campaign_id, user from vicidial_log $vicidial_log_SQL_nousers and user='VDAD' $and_NANQUE_clause UNION ALL select status, campaign_id, user from vicidial_closer_log $vicidial_closer_log_SQL_nousers and user='VDCL' $and_NANQUE_clause";
|
||||||
|
if ($DB) {$HTML_output.="<B>Lost: $lost_stmt</B>";}
|
||||||
|
$lost_rslt=mysql_to_mysqli($lost_stmt, $link);
|
||||||
|
while ($lost_row=mysqli_fetch_row($lost_rslt))
|
||||||
|
{
|
||||||
|
$status=$lost_row[0];
|
||||||
|
$campaign_id=$lost_row[1];
|
||||||
|
# print "$status - $campaign_id<BR>\n";
|
||||||
|
|
||||||
|
$call_outcome=$status;
|
||||||
|
if ($status_names["$status"])
|
||||||
|
{
|
||||||
|
$call_outcome=$status_names["$status"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$call_outcome=$status_names["$status"]." (unknown)";
|
||||||
|
# print "$status not in all statuses...<BR>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($status)
|
||||||
|
{
|
||||||
|
case $status_names["$status"]:
|
||||||
|
$call_type="Known";
|
||||||
|
break;
|
||||||
|
case (strlen($call_outcome)<=1):
|
||||||
|
$call_type="None";
|
||||||
|
break;
|
||||||
|
case (in_array($status, $human_ans_array["$campaign_id"]) || in_array($status, $human_ans_array["SYSTEM"])):
|
||||||
|
$call_type="Human answered";
|
||||||
|
break;
|
||||||
|
case (in_array($status, $contact_array["$campaign_id"]) || in_array($status, $contact_array["SYSTEM"])):
|
||||||
|
$call_type="Customer contact";
|
||||||
|
break;
|
||||||
|
case (in_array($status, $sale_array["$campaign_id"]) || in_array($status, $sale_array["SYSTEM"])):
|
||||||
|
$call_type="Sale";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$call_type="Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$call_results_array["$call_outcome"]["call_type"]) {$call_results_array["$call_outcome"]["call_type"]=$call_type;}
|
||||||
|
|
||||||
|
$call_results_array["$call_outcome"]["total"]++;
|
||||||
|
$call_results_total_calls++;
|
||||||
|
$call_results_array["$call_outcome"]["taken"]+=0;
|
||||||
|
$call_results_array["$call_outcome"]["lost"]++;
|
||||||
|
}
|
||||||
|
# print_r($status_names);
|
||||||
|
*/
|
||||||
|
|
||||||
|
$max_call_results_total_pct=0;
|
||||||
|
$max_call_results_taken_pct=0;
|
||||||
|
foreach ($call_results_array as $outcome => $data)
|
||||||
|
{
|
||||||
|
$call_results_array["$outcome"]["total_pct"]=sprintf("%.1f", 100*($data["total"]/$call_results_total_calls));
|
||||||
|
$call_results_array["$outcome"]["taken_pct"]=sprintf("%.1f", 100*($data["taken"]/$call_results_total_calls));
|
||||||
|
if ($max_call_results_total_pct<$call_results_array["$outcome"]["total_pct"]) {$max_call_results_total_pct=$call_results_array["$outcome"]["total_pct"];}
|
||||||
|
if ($max_call_results_taken_pct<$call_results_array["$outcome"]["taken_pct"]) {$max_call_results_taken_pct=$call_results_array["$outcome"]["taken_pct"];}
|
||||||
|
}
|
||||||
|
|
||||||
|
$max_billable_activities_total_time=0;
|
||||||
|
$billable_activities_grand_total_time=0;
|
||||||
|
foreach ($billable_activities_array as $pause_code => $data)
|
||||||
|
{
|
||||||
|
$billable_activities_array["$pause_code"]["avg"]=round($data["total_time"]/$data["n_times"]);
|
||||||
|
if ($max_billable_activities_total_time<$data["total_time"]) {$max_billable_activities_total_time=$data["total_time"];}
|
||||||
|
$billable_activities_grand_total_time+=$data["total_time"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$max_nonbillable_activities_total_time=0;
|
||||||
|
$nonbillable_activities_grand_total_time=0;
|
||||||
|
foreach ($nonbillable_activities_array as $pause_code => $data)
|
||||||
|
{
|
||||||
|
$nonbillable_activities_array["$pause_code"]["avg"]=round($data["total_time"]/$data["n_times"]);
|
||||||
|
if ($max_nonbillable_activities_total_time<$data["total_time"]) {$max_nonbillable_activities_total_time=$data["total_time"];}
|
||||||
|
$nonbillable_activities_grand_total_time+=$data["total_time"];
|
||||||
|
}
|
||||||
|
|
||||||
|
#### OUTCOMES ####
|
||||||
|
$sph=sprintf("%.1f", MathZDC($outcomes_array["sales"], ($outcomes_array["total_billable_time"] / 3600)));
|
||||||
|
$ccph=sprintf("%.1f", MathZDC($outcomes_array["customer_contacts"], ($outcomes_array["total_billable_time"] / 3600)));
|
||||||
|
$haph=sprintf("%.1f", MathZDC($outcomes_array["human_answered"], ($outcomes_array["total_billable_time"] / 3600)));
|
||||||
|
$ha_conv_index=sprintf("%.1f", 100*($outcomes_array["sales"]/$outcomes_array["customer_contacts"]));
|
||||||
|
$cc_conv_index=sprintf("%.1f", 100*($outcomes_array["sales"]/$outcomes_array["human_answered"]));
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Statuses").":$NWB#VERM_OUTCOMES-outcomes$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>";
|
||||||
|
$HTML_output.="<tr><th>"._QXZ("Report Details").":</th><td> </td></tr>";
|
||||||
|
$HTML_output.="<tr><td>"._QXZ("Total billable time").":</td><td>".floor($outcomes_array["total_billable_time"] / 3600).gmdate(":i:s", $outcomes_array["total_billable_time"] % 3600)."</td></tr>";
|
||||||
|
$HTML_output.="<tr><td>"._QXZ("Total agent available time").":</td><td>".floor($outcomes_array["total_agent_available_time"] / 3600).gmdate(":i:s", $outcomes_array["total_agent_available_time"] % 3600)."</td></tr>";
|
||||||
|
$HTML_output.="<tr><td>"._QXZ("Total agent billable activities").":</td><td>".floor($outcomes_array["total_agent_billable_activities"] / 3600).gmdate(":i:s", $outcomes_array["total_agent_billable_activities"] % 3600)."</td></tr>";
|
||||||
|
$HTML_output.="<tr><td>"._QXZ("Total nonbillable time").":</td><td>".floor($outcomes_array["total_nonbillable_time"] / 3600).gmdate(":i:s", $outcomes_array["total_nonbillable_time"] % 3600)."</td></tr>";
|
||||||
|
$HTML_output.="<tr><td>"._QXZ("Number of Sales").":</td><td>".$outcomes_array["sales"]."</td></tr>";
|
||||||
|
$HTML_output.="<tr><td>"._QXZ("Number of Customer Contacts").":</td><td>".$outcomes_array["customer_contacts"]."</td></tr>";
|
||||||
|
$HTML_output.="<tr><td>"._QXZ("Number of Human Answered").":</td><td>".$outcomes_array["human_answered"]."</td></tr>";
|
||||||
|
$HTML_output.="<tr><td>"._QXZ("Sales per Hour").":</td><td>".$sph."</td></tr>";
|
||||||
|
$HTML_output.="<tr><td>"._QXZ("Customer Contacts per Hour").":</td><td>".$ccph."</td></tr>";
|
||||||
|
$HTML_output.="<tr><td>"._QXZ("Human Answered per Hour").":</td><td>".$haph."</td></tr>";
|
||||||
|
$HTML_output.="<tr><td>"._QXZ("Conversion index").":</td><td>".$ha_conv_index." %</td></tr>";
|
||||||
|
$HTML_output.="<tr><td>"._QXZ("Contact conversion index").":</td><td>".$cc_conv_index." %</td></tr>";
|
||||||
|
|
||||||
|
$CSV_output["outcomes"]="\""._QXZ("Report Details").":\",\"\"\n";
|
||||||
|
$CSV_output["outcomes"].="\""._QXZ("Total billable time").":\",\"".floor($outcomes_array["total_billable_time"] / 3600).gmdate(":i:s", $outcomes_array["total_billable_time"] % 3600)."\"\n";
|
||||||
|
$CSV_output["outcomes"].="\""._QXZ("Total agent available time").":\",\"".floor($outcomes_array["total_agent_available_time"] / 3600).gmdate(":i:s", $outcomes_array["total_agent_available_time"] % 3600)."\"\n";
|
||||||
|
$CSV_output["outcomes"].="\""._QXZ("Total agent billable activities").":\",\"".floor($outcomes_array["total_agent_billable_activities"] / 3600).gmdate(":i:s", $outcomes_array["total_agent_billable_activities"] % 3600)."\"\n";
|
||||||
|
$CSV_output["outcomes"].="\""._QXZ("Total nonbillable time").":\",\"".floor($outcomes_array["total_nonbillable_time"] / 3600).gmdate(":i:s", $outcomes_array["total_nonbillable_time"] % 3600)."\"\n";
|
||||||
|
$CSV_output["outcomes"].="\""._QXZ("Number of Sales").":\",\"".$outcomes_array["sales"]."\"\n";
|
||||||
|
$CSV_output["outcomes"].="\""._QXZ("Number of Customer Contacts").":\",\"".$outcomes_array["customer_contacts"]."\"\n";
|
||||||
|
$CSV_output["outcomes"].="\""._QXZ("Number of Human Answered").":\",\"".$outcomes_array["human_answered"]."\"\n";
|
||||||
|
$CSV_output["outcomes"].="\""._QXZ("Sales per Hour").":\",\"$sph\"\n";
|
||||||
|
$CSV_output["outcomes"].="\""._QXZ("Customer Contacts per Hour").":\",\"$ccph\"\n";
|
||||||
|
$CSV_output["outcomes"].="\""._QXZ("Human Answered per Hour").":\",\"$haph\"\n";
|
||||||
|
$CSV_output["outcomes"].="\""._QXZ("Conversion index").":\",\"".$ha_conv_index." %\"\n";
|
||||||
|
$CSV_output["outcomes"].="\""._QXZ("Contact conversion index").":\",\"".$cc_conv_index." %\"\n";
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='2' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=outcomes\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$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>";
|
||||||
|
##################
|
||||||
|
|
||||||
|
#### CALL RESULTS OUTCOMES ####
|
||||||
|
|
||||||
|
#### SORT RESULTS OF MULTI-DIMENSIONAL ARRAY ###
|
||||||
|
#default sort by key, always do this so the subsort is by array key
|
||||||
|
ksort($call_results_array);
|
||||||
|
|
||||||
|
$sort_cr_index=preg_replace('/ desc/', '', $sort_call_results);
|
||||||
|
if (preg_match('/ desc$/', $sort_call_results))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_call_results);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_call_results." desc";
|
||||||
|
}
|
||||||
|
$sort_call_results_preg=preg_replace('/ desc$/', '', $sort_call_results);
|
||||||
|
|
||||||
|
if ($sort_call_results=="outcomes desc")
|
||||||
|
{
|
||||||
|
krsort($call_results_array);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($sort_cr_index)
|
||||||
|
{
|
||||||
|
$col = array_column( $call_results_array, "$sort_cr_index" );
|
||||||
|
if (preg_match('/ desc$/', $sort_call_results))
|
||||||
|
{
|
||||||
|
array_multisort( $col, SORT_DESC, $call_results_array );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_multisort( $col, SORT_ASC, $call_results_array );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header' id='scr_anchor'>"._QXZ("Call results, by statuses").":$NWB#VERM_OUTCOMES-call_results_by_outcomes$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>";
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
/*
|
||||||
|
$HTML_output.="<th><a class='header_link' name='call_results_call_outcome' id='call_results_call_outcome' href='".$PHP_SELF."?sort_call_results=".("outcomes"==$sort_call_results_preg ? "$reverse_link" : "outcomes")."#call_results_call_outcome'>Call outcome".("outcomes"==$sort_call_results_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='call_results_type' id='call_results_type' href='".$PHP_SELF."?sort_call_results=".("call_type"==$sort_call_results_preg ? "$reverse_link" : "call_type")."#call_results_type'>Type".("call_type"==$sort_call_results_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='call_results_total' id='call_results_total' href='".$PHP_SELF."?sort_call_results=".("total"==$sort_call_results_preg ? "$reverse_link" : "total")."#call_results_total'>Total".("total"==$sort_call_results_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='call_results_taken' id='call_results_taken' href='".$PHP_SELF."?sort_call_results=".("taken"==$sort_call_results_preg ? "$reverse_link" : "taken")."#call_results_taken'>Taken".("taken"==$sort_call_results_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='call_results_lost' id='call_results_lost' href='".$PHP_SELF."?sort_call_results=".("lost"==$sort_call_results_preg ? "$reverse_link" : "lost")."#call_results_lost'>Lost".("lost"==$sort_call_results_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='call_results_pct' id='call_results_pct' href='".$PHP_SELF."?sort_call_results=".("total_pct"==$sort_call_results_preg ? "$reverse_link" : "total_pct")."#call_results_pct'>%".("total_pct"==$sort_call_results_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='call_results_pct_taken' id='call_results_pct_taken' href='".$PHP_SELF."?sort_call_results=".("taken_pct"==$sort_call_results_preg ? "$reverse_link" : "taken_pct")."#call_results_pct_taken'>% taken".("taken_pct"==$sort_call_results_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
*/
|
||||||
|
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Call status").("outcomes"==$sort_call_results_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_call_results').value='".("outcomes"==$sort_call_results_preg ? "$reverse_link" : "outcomes")."'; this.form.action+='#scr_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Type").("call_type"==$sort_call_results_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_call_results').value='".("call_type"==$sort_call_results_preg ? "$reverse_link" : "call_type")."'; this.form.action+='#scr_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Total").("total"==$sort_call_results_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_call_results').value='".("total"==$sort_call_results_preg ? "$reverse_link" : "total")."'; this.form.action+='#scr_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Taken").("taken"==$sort_call_results_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_call_results').value='".("taken"==$sort_call_results_preg ? "$reverse_link" : "taken")."'; this.form.action+='#scr_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Lost").("lost"==$sort_call_results_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_call_results').value='".("lost"==$sort_call_results_preg ? "$reverse_link" : "lost")."'; this.form.action+='#scr_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='%".("total_pct"==$sort_call_results_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_call_results').value='".("total_pct"==$sort_call_results_preg ? "$reverse_link" : "total_pct")."'; this.form.action+='#scr_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='% "._QXZ("taken").("taken_pct"==$sort_call_results_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_call_results').value='".("taken_pct"==$sort_call_results_preg ? "$reverse_link" : "taken_pct")."'; this.form.action+='#scr_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
|
||||||
|
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["call_results"]="\""._QXZ("Call status")."\",\""._QXZ("Type")."\",\""._QXZ("Total")."\",\""._QXZ("Taken")."\",\""._QXZ("Lost")."\",\"%\",\"\",\"% "._QXZ("taken")."\"\n";
|
||||||
|
|
||||||
|
foreach ($call_results_array as $outcome => $data)
|
||||||
|
{
|
||||||
|
$dispo=array_search("$outcome", $status_names);
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
$HTML_output.="<td>".$outcome."</td>";
|
||||||
|
$HTML_output.="<td>".$data["call_type"]."</td>";
|
||||||
|
$HTML_output.="<td>".$data["total"]."</td>";
|
||||||
|
$HTML_output.="<td>".$data["taken"]."</td>";
|
||||||
|
$HTML_output.="<td>".$data["lost"]."</td>";
|
||||||
|
$HTML_output.="<td>".$data["total_pct"]." %</td>";
|
||||||
|
$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.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["call_results"].="\"$outcome\",\"$data[call_type]\",\"$data[total]\",\"$data[taken]\",\"$data[lost]\",\"$data[total_pct] %\",\"\",\"$data[taken_pct] %\",\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='10' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=call_results&sort_call_results=".$sort_call_results."\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='10'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('OUTCOMES', 'call_results')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
$HTML_output.="<input type='hidden' name='sort_call_results' id='sort_call_results' value='$sort_call_results'>";
|
||||||
|
###############################
|
||||||
|
|
||||||
|
#### BILLABLE ACTIVITIES ####
|
||||||
|
ksort($billable_activities_array);
|
||||||
|
|
||||||
|
$sort_ba_index=preg_replace('/ desc/', '', $sort_billable_activities);
|
||||||
|
if (preg_match('/ desc$/', $sort_billable_activities))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_billable_activities);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_billable_activities." desc";
|
||||||
|
}
|
||||||
|
$sort_billable_activities_preg=preg_replace('/ desc$/', '', $sort_billable_activities);
|
||||||
|
|
||||||
|
if ($sort_billable_activities=="activity desc")
|
||||||
|
{
|
||||||
|
krsort($billable_activities_array);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($sort_ba_index)
|
||||||
|
{
|
||||||
|
$col = array_column( $billable_activities_array, "$sort_ba_index" );
|
||||||
|
if (preg_match('/ desc$/', $sort_billable_activities))
|
||||||
|
{
|
||||||
|
array_multisort( $col, SORT_DESC, $billable_activities_array );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_multisort( $col, SORT_ASC, $billable_activities_array );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header' id='sba_anchor'>"._QXZ("Billable activities").":$NWB#VERM_OUTCOMES-billable_activities$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>";
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
/*
|
||||||
|
$HTML_output.="<th><a class='header_link' name='billable_activities_call_activity' id='billable_activities_call_activity' href='".$PHP_SELF."?sort_billable_activities=".("activity"==$sort_billable_activities_preg ? "$reverse_link" : "activity")."#billable_activities_call_activity'>Activity".("activity"==$sort_billable_activities_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='billable_activities_ntimes' id='billable_activities_ntimes' href='".$PHP_SELF."?sort_billable_activities=".("n_times"==$sort_billable_activities_preg ? "$reverse_link" : "n_times")."#billable_activities_ntimes'>N. Times".("n_times"==$sort_billable_activities_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='billable_activities_total_time' id='billable_activities_total_time' href='".$PHP_SELF."?sort_billable_activities=".("total_time"==$sort_billable_activities_preg ? "$reverse_link" : "total_time")."#billable_activities_total_time'>Tot. Time".("total_time"==$sort_billable_activities_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='billable_activities_avg' id='billable_activities_avg' href='".$PHP_SELF."?sort_billable_activities=".("avg"==$sort_billable_activities_preg ? "$reverse_link" : "avg")."#billable_activities_avg'>Avg.".("avg"==$sort_billable_activities_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='billable_activities_min' id='billable_activities_min' href='".$PHP_SELF."?sort_billable_activities=".("min"==$sort_billable_activities_preg ? "$reverse_link" : "min")."#billable_activities_min'>Min.".("min"==$sort_billable_activities_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
*/
|
||||||
|
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Activity").("activity"==$sort_billable_activities_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_billable_activities').value='".("activity"==$sort_billable_activities_preg ? "$reverse_link" : "activity")."'; this.form.action+='#sba_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("N. Times").("n_times"==$sort_billable_activities_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_billable_activities').value='".("n_times"==$sort_billable_activities_preg ? "$reverse_link" : "n_times")."'; this.form.action+='#sba_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Tot. Time").("total_time"==$sort_billable_activities_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_billable_activities').value='".("total_time"==$sort_billable_activities_preg ? "$reverse_link" : "total_time")."'; this.form.action+='#sba_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$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>%</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["billable_activities"]="\""._QXZ("Activity")."\",\""._QXZ("N. Times")."\",\""._QXZ("Tot. Time")."\",\""._QXZ("Avg.")."\",\""._QXZ("Min.")."\",\""._QXZ("Max.")."\",\"%\"\n";
|
||||||
|
|
||||||
|
foreach ($billable_activities_array as $pause_code => $data)
|
||||||
|
{
|
||||||
|
$pct=sprintf("%.1f", ((100*$data["total_time"])/$billable_activities_grand_total_time));
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
$HTML_output.="<td>".$pause_code."</td>";
|
||||||
|
$HTML_output.="<td>".$data["n_times"]."</td>";
|
||||||
|
$HTML_output.="<td>".($data["total_time"]>=3600 ? floor($data["total_time"]/3600).":" : "").gmdate("i:s", $data["total_time"])."</td>";
|
||||||
|
$HTML_output.="<td>".($data["avg"]>=3600 ? floor($data["avg"]/3600).":" : "").gmdate("i:s", $data["avg"])."</td>";
|
||||||
|
$HTML_output.="<td>".($data["min"]>=3600 ? floor($data["min"]/3600).":" : "").gmdate("i:s", $data["min"])."</td>";
|
||||||
|
$HTML_output.="<td>".($data["max"]>=3600 ? floor($data["max"]/3600).":" : "").gmdate("i:s", $data["max"])."</td>";
|
||||||
|
$HTML_output.="<td>".$pct." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".$pct."%'></td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["billable_activities"].="\"$pause_code\",\"$data[n_times]\",\"".($data["total_time"]>=3600 ? floor($data["total_time"]/3600).":" : "").gmdate("i:s", $data["total_time"])."\",\"".($data["avg"]>=3600 ? floor($data["avg"]/3600).":" : "").gmdate("i:s", $data["avg"])."\",\"".($data["min"]>=3600 ? floor($data["min"]/3600).":" : "").gmdate("i:s", $data["min"])."\",\"".($data["max"]>=3600 ? floor($data["max"]/3600).":" : "").gmdate("i:s", $data["max"])."\",\"$pct %\"\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='10' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=billable_activities&sort_billable_activities=".$sort_billable_activities."\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='10'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('OUTCOMES', 'billable_activities')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
$HTML_output.="<input type='hidden' name='sort_billable_activities' id='sort_billable_activities' value='$sort_billable_activities'>";
|
||||||
|
###############################
|
||||||
|
|
||||||
|
#### NONBILLABLE ACTIVITIES ####
|
||||||
|
ksort($nonbillable_activities_array);
|
||||||
|
|
||||||
|
$sort_nba_index=preg_replace('/ desc/', '', $sort_nonbillable_activities);
|
||||||
|
if (preg_match('/ desc$/', $sort_nonbillable_activities))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_nonbillable_activities);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_nonbillable_activities." desc";
|
||||||
|
}
|
||||||
|
$sort_nonbillable_activities_preg=preg_replace('/ desc$/', '', $sort_nonbillable_activities);
|
||||||
|
|
||||||
|
if ($sort_nonbillable_activities=="activity desc")
|
||||||
|
{
|
||||||
|
krsort($nonbillable_activities_array);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($sort_nba_index)
|
||||||
|
{
|
||||||
|
$col = array_column( $nonbillable_activities_array, "$sort_nba_index" );
|
||||||
|
if (preg_match('/ desc$/', $sort_nonbillable_activities))
|
||||||
|
{
|
||||||
|
array_multisort( $col, SORT_DESC, SORT_STRING, $nonbillable_activities_array );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_multisort( $col, SORT_ASC, SORT_STRING, $nonbillable_activities_array );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header' id='sna_anchor'>"._QXZ("Nonbillable activities").":$NWB#VERM_OUTCOMES-nonbillable_activities$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>";
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
/*
|
||||||
|
$HTML_output.="<th><a class='header_link' name='nonbillable_activity' id='nonbillable_activity' href='".$PHP_SELF."?sort_nonbillable_activities=".("activity"==$sort_nonbillable_activities_preg ? "$reverse_link" : "activity")."#nonbillable_activity'>Activity".("activity"==$sort_nonbillable_activities_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='nonbillable_activities_ntimes' id='nonbillable_activities_ntimes' href='".$PHP_SELF."?sort_nonbillable_activities=".("n_times"==$sort_nonbillable_activities_preg ? "$reverse_link" : "n_times")."#nonbillable_activities_ntimes'>N. Times".("n_times"==$sort_nonbillable_activities_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='nonbillable_activities_total_time' id='nonbillable_activities_total_time' href='".$PHP_SELF."?sort_nonbillable_activities=".("total_time"==$sort_nonbillable_activities_preg ? "$reverse_link" : "total_time")."#nonbillable_activities_total_time'>Tot. Time".("total_time"==$sort_nonbillable_activities_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='nonbillable_activities_avg' id='nonbillable_activities_avg' href='".$PHP_SELF."?sort_nonbillable_activities=".("avg"==$sort_nonbillable_activities_preg ? "$reverse_link" : "avg")."#nonbillable_activities_avg'>Avg.".("avg"==$sort_nonbillable_activities_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='nonbillable_activities_min' id='nonbillable_activities_min' href='".$PHP_SELF."?sort_nonbillable_activities=".("min"==$sort_nonbillable_activities_preg ? "$reverse_link" : "min")."#nonbillable_activities_min'>Min.".("min"==$sort_nonbillable_activities_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
*/
|
||||||
|
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Activity").("activity"==$sort_nonbillable_activities_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_nonbillable_activities').value='".("activity"==$sort_nonbillable_activities_preg ? "$reverse_link" : "activity")."'; this.form.action+='#sna_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("N. Times").("n_times"==$sort_nonbillable_activities_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_nonbillable_activities').value='".("n_times"==$sort_nonbillable_activities_preg ? "$reverse_link" : "n_times")."'; this.form.action+='#sna_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Tot. Time").("total_time"==$sort_nonbillable_activities_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_nonbillable_activities').value='".("total_time"==$sort_nonbillable_activities_preg ? "$reverse_link" : "total_time")."'; this.form.action+='#sna_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Avg.").("avg"==$sort_nonbillable_activities_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_nonbillable_activities').value='".("avg"==$sort_nonbillable_activities_preg ? "$reverse_link" : "avg")."'; this.form.action+='#sna_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Min.").("min"==$sort_nonbillable_activities_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_nonbillable_activities').value='".("min"==$sort_nonbillable_activities_preg ? "$reverse_link" : "min")."'; this.form.action+='#sna_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
|
||||||
|
$HTML_output.="<th>"._QXZ("Max.")."</a></th>";
|
||||||
|
$HTML_output.="<th>%</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["nonbillable_activities"]="\""._QXZ("Activity")."\",\""._QXZ("N. Times")."\",\""._QXZ("Tot. Time")."\",\""._QXZ("Avg.")."\",\""._QXZ("Min.")."\",\""._QXZ("Max.")."\",\"%\"\n";
|
||||||
|
|
||||||
|
foreach ($nonbillable_activities_array as $pause_code => $data)
|
||||||
|
{
|
||||||
|
$pct=sprintf("%.1f", ((100*$data["total_time"])/$nonbillable_activities_grand_total_time));
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
$HTML_output.="<td>".$pause_code."</td>";
|
||||||
|
$HTML_output.="<td>".$data["n_times"]."</td>";
|
||||||
|
$HTML_output.="<td>".($data["total_time"]>=3600 ? floor($data["total_time"]/3600).":" : "").gmdate("i:s", $data["total_time"])."</td>";
|
||||||
|
$HTML_output.="<td>".($data["avg"]>=3600 ? floor($data["avg"]/3600).":" : "").gmdate("i:s", $data["avg"])."</td>";
|
||||||
|
$HTML_output.="<td>".($data["min"]>=3600 ? floor($data["min"]/3600).":" : "").gmdate("i:s", $data["min"])."</td>";
|
||||||
|
$HTML_output.="<td>".($data["max"]>=3600 ? floor($data["max"]/3600).":" : "").gmdate("i:s", $data["max"])."</td>";
|
||||||
|
$HTML_output.="<td>".$pct." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".$pct."%'></td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["nonbillable_activities"].="\"$pause_code\",\"$data[n_times]\",\"".($data["total_time"]>=3600 ? floor($data["total_time"]/3600).":" : "").gmdate("i:s", $data["total_time"])."\",\"".($data["avg"]>=3600 ? floor($data["avg"]/3600).":" : "").gmdate("i:s", $data["avg"])."\",\"".($data["min"]>=3600 ? floor($data["min"]/3600).":" : "").gmdate("i:s", $data["min"])."\",\"".($data["max"]>=3600 ? floor($data["max"]/3600).":" : "").gmdate("i:s", $data["max"])."\",\"$pct %\"\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='10' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=nonbillable_activities&sort_nonbillable_activities=".$sort_nonbillable_activities."\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='10'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('OUTCOMES', 'nonbillable_activities')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
$HTML_output.="<input type='hidden' name='sort_nonbillable_activities' id='sort_nonbillable_activities' value='$sort_billable_activities'>";
|
||||||
|
###############################
|
||||||
|
|
||||||
|
#### AGENT DETAILS REPORT #####
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Detailed agent report").":$NWB#VERM_OUTCOMES-detailed_agent_report$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Agent name")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Avail.")."</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Bill.")."</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Nonb.")."</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Sales")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Cust Contact")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Human Ans.")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("SPH")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("CCPH")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("HAPH")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("HA CONV")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("CC CONV")."</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["agent_details"]="\""._QXZ("Agent name")."\",\""._QXZ("Avail.")."\",\" \",\""._QXZ("Bill.")."\",\" \",\""._QXZ("NonB.")."\",\" \",\""._QXZ("Sales")."\",\""._QXZ("Cust Contact")."\",\""._QXZ("Human Ans.")."\",\""._QXZ("SPH")."\",\""._QXZ("CCPH")."\",\""._QXZ("HAPH")."\",\""._QXZ("HA CONV")."\",\""._QXZ("CC CONV")."\"\n";
|
||||||
|
|
||||||
|
ksort($agent_details_array);
|
||||||
|
# print_r($agent_details_array);
|
||||||
|
foreach($agent_details_array as $agent_name => $data)
|
||||||
|
{
|
||||||
|
$billable_seconds=($data["available"]+$data["billable"]);
|
||||||
|
$billable_hours=$billable_seconds/3600;
|
||||||
|
|
||||||
|
$av_pct=sprintf("%.1f", (100*($data["available"]/$billable_seconds)));
|
||||||
|
$b_pct=sprintf("%.1f", (100*($data["billable"]/$billable_seconds)));
|
||||||
|
# ??? - Not sure of the logic below, but whatever.
|
||||||
|
$ha_conv_pct=sprintf("%.1f", (100*MathZDC($data["sales"], $data["human_answered"], 0)));
|
||||||
|
$cc_conv_pct=sprintf("%.1f", (100*MathZDC($data["sales"], $data["customer_contacts"], 0)));
|
||||||
|
|
||||||
|
$nb_pct=sprintf("%.1f", (100*($data["nonbillable"]/$billable_seconds)));
|
||||||
|
$sph=sprintf("%.1f", ($data["sales"]/$billable_hours));
|
||||||
|
$ccph=sprintf("%.1f", ($data["customer_contacts"]/$billable_hours));
|
||||||
|
$haph=sprintf("%.1f", ($data["human_answered"]/$billable_hours));
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
$HTML_output.="<td>".$agent_name."</td>";
|
||||||
|
$HTML_output.="<td>".($data["available"]>=3600 ? floor($data["available"]/3600).":" : "").gmdate("i:s", $data["available"])."</td>";
|
||||||
|
$HTML_output.="<td>".$av_pct." %</td>";
|
||||||
|
$HTML_output.="<td>".($data["billable"]>=3600 ? floor($data["billable"]/3600).":" : "").gmdate("i:s", $data["billable"])."</td>";
|
||||||
|
$HTML_output.="<td>".$b_pct." %</td>";
|
||||||
|
$HTML_output.="<td>".($data["nonbillable"]>=3600 ? floor($data["nonbillable"]/3600).":" : "").gmdate("i:s", $data["nonbillable"])."</td>";
|
||||||
|
$HTML_output.="<td>".$nb_pct." %</td>";
|
||||||
|
$HTML_output.="<td>".$data["sales"]."</td>";
|
||||||
|
$HTML_output.="<td>".$data["customer_contacts"]."</td>";
|
||||||
|
$HTML_output.="<td>".$data["human_answered"]."</td>";
|
||||||
|
$HTML_output.="<td>".$sph."</td>";
|
||||||
|
$HTML_output.="<td>".$ccph."</td>";
|
||||||
|
$HTML_output.="<td>".$haph."</td>";
|
||||||
|
$HTML_output.="<td>".$ha_conv_pct." %</td>";
|
||||||
|
$HTML_output.="<td>".$cc_conv_pct." %</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["agent_details"].="\"$agent_name\",\"".($data["available"]>=3600 ? floor($data["available"]/3600).":" : "").gmdate("i:s", $data["available"])."\",\"$av_pct %\",\"".($data["billable"]>=3600 ? floor($data["billable"]/3600).":" : "").gmdate("i:s", $data["billable"])."\",\"$b_pct %\",\"".($data["nonbillable"]>=3600 ? floor($data["nonbillable"]/3600).":" : "").gmdate("i:s", $data["nonbillable"])."\",\"$nb_pct %\",\"$data[sales]\",\"$data[customer_contacts]\",\"$data[human_answered]\",\"$sph\",\"$ccph\",\"$haph\",\"$ha_conv_pct %\",\"$cc_conv_pct %\"\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='15' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=agent_details\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$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>";
|
||||||
|
###############################
|
||||||
|
|
||||||
|
#### AGENT OUTCOMES REPORT ####
|
||||||
|
$final_opa_array=array();
|
||||||
|
$max_total_value=0;
|
||||||
|
foreach($outcomes_per_agent_array as $key => $value)
|
||||||
|
{
|
||||||
|
if ($value>$max_total_value) {$max_total_value=$value;}
|
||||||
|
|
||||||
|
$new_array=explode("|", $key);
|
||||||
|
$new_assoc_array=array(
|
||||||
|
"agent" => $new_array[0],
|
||||||
|
"type" => $new_array[1],
|
||||||
|
"outcome" => $new_array[2],
|
||||||
|
"status" => $new_array[3],
|
||||||
|
"total" => $value
|
||||||
|
);
|
||||||
|
# array_push($new_array, $value);
|
||||||
|
array_push($final_opa_array, $new_assoc_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sort_opa_index=preg_replace('/ desc/', '', $sort_outcomes_per_agent);
|
||||||
|
if (preg_match('/ desc$/', $sort_outcomes_per_agent))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_outcomes_per_agent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_outcomes_per_agent." desc";
|
||||||
|
}
|
||||||
|
$sort_outcomes_per_agent_preg=preg_replace('/ desc$/', '', $sort_outcomes_per_agent);
|
||||||
|
|
||||||
|
if (!$sort_opa_index) {$sort_opa_index="agent";}
|
||||||
|
|
||||||
|
# Default sort
|
||||||
|
$col = array_column( $final_opa_array, "agent" );
|
||||||
|
array_multisort( $col, SORT_ASC, $final_opa_array );
|
||||||
|
|
||||||
|
$col = array_column( $final_opa_array, "$sort_opa_index" );
|
||||||
|
if (preg_match('/ desc$/', $sort_outcomes_per_agent))
|
||||||
|
{
|
||||||
|
if ($sort_opa_index=="total")
|
||||||
|
{
|
||||||
|
array_multisort( $col, SORT_DESC, $final_opa_array );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_multisort( $col, SORT_DESC, SORT_STRING, $final_opa_array );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($sort_opa_index=="total")
|
||||||
|
{
|
||||||
|
array_multisort( $col, SORT_ASC, $final_opa_array );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_multisort( $col, SORT_ASC, SORT_STRING, $final_opa_array );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header' id='sopa_anchor'>"._QXZ("Statuses per agent").":$NWB#VERM_OUTCOMES-outcomes_per_agent$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>";
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
/*
|
||||||
|
$HTML_output.="<th><a class='header_link' name='outcomes_per_agent' id='outcomes_per_agent' href='".$PHP_SELF."?sort_outcomes_per_agent=".("agent"==$sort_outcomes_per_agent_preg ? "$reverse_link" : "agent")."#outcomes_per_agent'>"._QXZ("Agent Name").("agent"==$sort_outcomes_per_agent_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='outcomes_per_agent_statuses' id='outcomes_per_agent_statuses' href='".$PHP_SELF."?sort_outcomes_per_agent=".("status"==$sort_outcomes_per_agent_preg ? "$reverse_link" : "status")."#outcomes_per_agent_statuses'>"._QXZ("Status").("status"==$sort_outcomes_per_agent_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='outcomes_per_agent_outcome' id='outcomes_per_agent_outcome' href='".$PHP_SELF."?sort_outcomes_per_agent=".("outcome"==$sort_outcomes_per_agent_preg ? "$reverse_link" : "outcome")."#outcomes_per_agent_outcome'>"._QXZ("Status Name").("outcome"==$sort_outcomes_per_agent_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='outcomes_per_agent_type' id='outcomes_per_agent_type' href='".$PHP_SELF."?sort_outcomes_per_agent=".("type"==$sort_outcomes_per_agent_preg ? "$reverse_link" : "type")."#outcomes_per_agent_type'>"._QXZ("Type").("type"==$sort_outcomes_per_agent_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th><a class='header_link' name='outcomes_per_agent_total' id='outcomes_per_agent_total' href='".$PHP_SELF."?sort_outcomes_per_agent=".("total"==$sort_outcomes_per_agent_preg ? "$reverse_link" : "total")."#outcomes_per_agent_total'>"._QXZ("Total").("total"==$sort_outcomes_per_agent_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
*/
|
||||||
|
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Agent Name").("agent"==$sort_outcomes_per_agent_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_outcomes_per_agent').value='".("agent"==$sort_outcomes_per_agent_preg ? "$reverse_link" : "agent")."'; this.form.action+='#sopa_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Status").("status"==$sort_outcomes_per_agent_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_outcomes_per_agent').value='".("status"==$sort_outcomes_per_agent_preg ? "$reverse_link" : "status")."';this.form.action+='#sopa_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Status Name").("outcome"==$sort_outcomes_per_agent_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_outcomes_per_agent').value='".("outcome"==$sort_outcomes_per_agent_preg ? "$reverse_link" : "outcome")."'; this.form.action+='#sopa_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Type").("type"==$sort_outcomes_per_agent_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_outcomes_per_agent').value='".("type"==$sort_outcomes_per_agent_preg ? "$reverse_link" : "type")."'; this.form.action+='#sopa_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Total").("total"==$sort_outcomes_per_agent_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_outcomes_per_agent').value='".("total"==$sort_outcomes_per_agent_preg ? "$reverse_link" : "total")."'; this.form.action+='#sopa_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["agent_outcomes"]="\""._QXZ("Agent name")."\",\""._QXZ("Status")."\",\""._QXZ("Status name")."\",\""._QXZ("Type")."\",\""._QXZ("Total")."\",\n";
|
||||||
|
|
||||||
|
foreach($final_opa_array as $key => $row)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
$HTML_output.="<td>".$row["agent"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["status"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["outcome"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["type"]."</td>";
|
||||||
|
$HTML_output.="<td>".$row["total"]."</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$row["total"])/$max_total_value)."%'></td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["agent_outcomes"].="\"$row[agent]\",\"$row[status]\",\"$row[outcome]\",\"$row[type]\",\"$row[total]\"\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='6' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=agent_outcomes&sort_outcomes_per_agent=".$sort_outcomes_per_agent."\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='6'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('OUTCOMES', 'agent_outcomes')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$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)
|
||||||
|
{
|
||||||
|
$data_to_download=$CSV_output["$download_rpt"];
|
||||||
|
|
||||||
|
$FILE_TIME = date("Ymd-His");
|
||||||
|
$CSVfilename = "STATUSES_RPT_".$download_rpt."_".$FILE_TIME.".csv";
|
||||||
|
header('Content-type: application/octet-stream');
|
||||||
|
|
||||||
|
header("Content-Disposition: attachment; filename=\"$CSVfilename\"");
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
ob_clean();
|
||||||
|
flush();
|
||||||
|
|
||||||
|
echo "$data_to_download";
|
||||||
|
|
||||||
|
if ($db_source == 'S')
|
||||||
|
{
|
||||||
|
mysqli_close($link);
|
||||||
|
$use_slave_server=0;
|
||||||
|
$db_source = 'M';
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
$endMS = microtime();
|
||||||
|
$startMSary = explode(" ",$startMS);
|
||||||
|
$endMSary = explode(" ",$endMS);
|
||||||
|
$runS = ($endMSary[0] - $startMSary[0]);
|
||||||
|
$runM = ($endMSary[1] - $startMSary[1]);
|
||||||
|
$TOTALrun = ($runS + $runM);
|
||||||
|
|
||||||
|
# $stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';";
|
||||||
|
# if ($DB) {echo "|$stmt|\n";}
|
||||||
|
# $rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
echo $HTML_header;
|
||||||
|
|
||||||
|
echo $HTML_output;
|
||||||
|
?>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,804 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_STATS_rpt.inc - Vicidial Enhanced Reporting stats report
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1616 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
# DROP, WAITTO, TIMEOT are unanswered statuses, not NANQUE
|
||||||
|
$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);
|
||||||
|
|
||||||
|
if (isset($_GET["sort_agents_on_queue"])) {$sort_agents_on_queue=$_GET["sort_agents_on_queue"];}
|
||||||
|
elseif (isset($_POST["sort_agents_on_queue"])) {$sort_agents_on_queue=$_POST["sort_agents_on_queue"];}
|
||||||
|
|
||||||
|
if ($non_latin < 1)
|
||||||
|
{
|
||||||
|
$sort_agents_on_queue = preg_replace('/[^\s-_0-9a-zA-Z]/','',$sort_agents_on_queue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_agents_on_queue = preg_replace('/[^\s-_0-9\p{L}]/u','',$sort_agents_on_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
$calls_stmt="select call_date, call_date+INTERVAL (length_in_sec) SECOND as end_date, if(call_date+INTERVAL (length_in_sec) SECOND<='$end_date $end_time', '1', '0') as within_interval, campaign_id, user, length_in_sec, '0' as queue_seconds, 'O' as direction, '1' as queue_position, term_reason, comments, status, uniqueid From vicidial_log $vicidial_log_SQL and user!='VDAD' UNION select call_date, call_date+INTERVAL (length_in_sec) SECOND as end_date, if(call_date+INTERVAL (length_in_sec) SECOND<='$end_date $end_time', '1', '0') as within_interval, campaign_id, user, if(comments='EMAIL', length_in_sec, length_in_sec-queue_seconds) as length_in_sec, if(comments='EMAIL', '0', queue_seconds) as queue_seconds, 'I' as direction, queue_position, term_reason, comments, status, uniqueid From vicidial_closer_log $vicidial_closer_log_SQL and (user!='VDCL' $or_NANQUE_clause)";
|
||||||
|
|
||||||
|
if ($DB) {$HTML_output.="<B>$calls_stmt</B>";}
|
||||||
|
|
||||||
|
$calls_rslt=mysqli_query($link, $calls_stmt);
|
||||||
|
|
||||||
|
### VARIABLES ###
|
||||||
|
$total_calls=0;
|
||||||
|
$total_answered_calls=0;
|
||||||
|
$total_unanswered_calls=0;
|
||||||
|
$max_call_length=0;
|
||||||
|
$min_call_length=1000000;
|
||||||
|
$total_call_length=0;
|
||||||
|
$max_wait_time=0;
|
||||||
|
$min_wait_time=1000000;
|
||||||
|
$total_wait_time=0;
|
||||||
|
$total_position=0;
|
||||||
|
$max_position=0;
|
||||||
|
$min_position=1000000;
|
||||||
|
$agent_call_counts=array();
|
||||||
|
$transferred_counts=array();
|
||||||
|
$agent_call_lengths=array();
|
||||||
|
$queue_stats=array(); # campaign id breakdown BY ANSWERED CALLS
|
||||||
|
$term_reasons=array(); # ANSWERED CALLS ONLY
|
||||||
|
$call_directions=array(); # ANSWERED CALLS
|
||||||
|
$call_stints=array(); # ANSWERED CALLS
|
||||||
|
$agent_events=array(); # ANSWERED CALLS
|
||||||
|
$queue_positions=array("Untracked" => 0); # ANSWERED CALLS
|
||||||
|
$coverage="100%";
|
||||||
|
$coverage_wi="100%";
|
||||||
|
#################
|
||||||
|
|
||||||
|
### WITHIN-INTERVAL VARS ###
|
||||||
|
$total_calls_wi=0;
|
||||||
|
$total_answered_calls_wi=0;
|
||||||
|
$total_unanswered_calls_wi=0;
|
||||||
|
$max_call_length_wi=0;
|
||||||
|
$min_call_length_wi=1000000;
|
||||||
|
$total_call_length_wi=0;
|
||||||
|
$max_wait_time_wi=0;
|
||||||
|
$min_wait_time_wi=1000000;
|
||||||
|
$total_wait_time_wi=0;
|
||||||
|
$total_position_wi=0;
|
||||||
|
$max_position_wi=0;
|
||||||
|
$min_position_wi=1000000;
|
||||||
|
$agent_stats_wi=array();
|
||||||
|
############################
|
||||||
|
|
||||||
|
$uniqueid_array=array();
|
||||||
|
|
||||||
|
while ($calls_row=mysqli_fetch_array($calls_rslt))
|
||||||
|
{
|
||||||
|
$total_calls++;
|
||||||
|
if ($calls_row["direction"]=="O")
|
||||||
|
{
|
||||||
|
$total_outbound_calls++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$total_inbound_calls++;
|
||||||
|
}
|
||||||
|
# print "$total_call_length + $calls_row[length_in_sec] = ";
|
||||||
|
$total_call_length+=$calls_row["length_in_sec"];
|
||||||
|
# print "$total_call_length<BR>\n";
|
||||||
|
$total_wait_time+=$calls_row["queue_seconds"];
|
||||||
|
$stint=1;
|
||||||
|
|
||||||
|
if (preg_match('/VDAD|VDCL/', $calls_row["user"]))
|
||||||
|
{
|
||||||
|
/* IRRELEVANT
|
||||||
|
if (preg_match('/^DROP$|TIMEOT|WAITTO/', $calls_row["status"]))
|
||||||
|
{
|
||||||
|
$total_unanswered_calls++;
|
||||||
|
if ($calls_row["direction"]=="O")
|
||||||
|
{
|
||||||
|
$unanswered_outbound_calls++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$unanswered_inbound_calls++;
|
||||||
|
}
|
||||||
|
$call_was_answered=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# DO NOTHING FOR NANQUE - dunno why but phone 4698254386 shows only under one rep despite call length
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_push($uniqueid_array, $calls_row["uniqueid"]);
|
||||||
|
$total_answered_calls++;
|
||||||
|
if ($calls_row["direction"]=="O")
|
||||||
|
{
|
||||||
|
$answered_outbound_calls++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$answered_inbound_calls++;
|
||||||
|
}
|
||||||
|
$call_was_answered=1;
|
||||||
|
|
||||||
|
$transferred_counts["$transfer_status"]++;
|
||||||
|
|
||||||
|
# Use full name here so we can sort in the 'Agents on queue' section painlessly.
|
||||||
|
$agent_full_name=$fullname_info["$calls_row[user]"];
|
||||||
|
$agent_call_counts["$agent_full_name"]++;
|
||||||
|
$agent_call_lengths["$agent_full_name"]+=$calls_row["length_in_sec"];
|
||||||
|
|
||||||
|
# Events?
|
||||||
|
$agent_events["$calls_row[user]"][0]=0;
|
||||||
|
$agent_events["$calls_row[user]"][1]=0;
|
||||||
|
|
||||||
|
$term_reasons["$calls_row[term_reason]"]++;
|
||||||
|
|
||||||
|
$queue_stats["$calls_row[campaign_id]"]++;
|
||||||
|
|
||||||
|
if ($calls_row["direction"]=="O") {$call_directions["Outbound calls"]++;} else {$call_directions["Inbound calls"]++;}
|
||||||
|
|
||||||
|
$call_stints["$stint"]++;
|
||||||
|
|
||||||
|
$total_position+=$calls_row["queue_position"];
|
||||||
|
$queue_positions["$calls_row[queue_position]"]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($calls_row["length_in_sec"]>$max_call_length && $call_was_answered) {$max_call_length=$calls_row["length_in_sec"];}
|
||||||
|
if ($calls_row["length_in_sec"]<$min_call_length && $call_was_answered) {$min_call_length=$calls_row["length_in_sec"];}
|
||||||
|
|
||||||
|
if ($calls_row["queue_seconds"]>$max_wait_time && $call_was_answered) {$max_wait_time=$calls_row["queue_seconds"];}
|
||||||
|
if ($calls_row["queue_seconds"]<$min_wait_time && $call_was_answered) {$min_wait_time=$calls_row["queue_seconds"];}
|
||||||
|
|
||||||
|
if ($calls_row["queue_position"]>$max_position) {$max_position=$calls_row["queue_position"];}
|
||||||
|
if ($calls_row["queue_position"]<$min_position) {$min_position=$calls_row["queue_position"];}
|
||||||
|
|
||||||
|
### FILTER FOR FULLY WITHIN-INTERVAL CALLS, SHOULD BE EXACTLY THE SAME (FOR NOW)
|
||||||
|
if ($calls_row["within_interval"])
|
||||||
|
{
|
||||||
|
$total_calls_wi++;
|
||||||
|
$total_call_length_wi+=$calls_row["length_in_sec"];
|
||||||
|
$total_wait_time_wi+=$calls_row["queue_seconds"];
|
||||||
|
$total_position_wi+=$calls_row["queue_position"];
|
||||||
|
|
||||||
|
if (preg_match('/VDAD|VDCL/', $calls_row["user"]) && preg_match('/^DROP$|TIMEOT|WAITTO/', $calls_row["status"]))
|
||||||
|
{
|
||||||
|
$total_unanswered_calls_wi++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$total_answered_calls_wi++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($calls_row["length_in_sec"]>$max_call_length_wi) {$max_call_length_wi=$calls_row["length_in_sec"];}
|
||||||
|
if ($calls_row["length_in_sec"]<$min_call_length_wi) {$min_call_length_wi=$calls_row["length_in_sec"];}
|
||||||
|
|
||||||
|
if ($calls_row["queue_seconds"]>$max_wait_time_wi && $call_was_answered) {$max_wait_time_wi=$calls_row["queue_seconds"];}
|
||||||
|
if ($calls_row["queue_seconds"]<$min_wait_time_wi && $call_was_answered) {$min_wait_time_wi=$calls_row["queue_seconds"];}
|
||||||
|
|
||||||
|
if ($calls_row["queue_position"]>$max_position_wi) {$max_position_wi=$calls_row["queue_position"];}
|
||||||
|
if ($calls_row["queue_position"]<$min_position_wi) {$min_position_wi=$calls_row["queue_position"];}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$average_call_length=sprintf("%.1f", $total_call_length/$total_answered_calls); # Total calls instead?
|
||||||
|
$average_wait_time=sprintf("%.1f", $total_wait_time/$total_answered_calls); # Total calls instead?
|
||||||
|
$average_position=sprintf("%.1f", $total_position/$total_answered_calls);
|
||||||
|
$total_call_length_fmt=sprintf("%.1f", ($total_call_length/3600));
|
||||||
|
$total_wait_time_fmt=sprintf("%.1f", ($total_wait_time/3600));
|
||||||
|
|
||||||
|
$average_call_length_wi=sprintf("%.1f", $total_call_length_wi/$total_answered_calls_wi); # Total calls instead?
|
||||||
|
$average_wait_time_wi=sprintf("%.1f", $total_wait_time_wi/$answered_call_wis); # Total calls instead?
|
||||||
|
$average_position_wi=sprintf("%.1f", $total_position_wi/$total_answered_calls_wi);
|
||||||
|
$total_call_length_fmt_wi=sprintf("%.1f", ($total_call_length_wi/3600));
|
||||||
|
$total_wait_time_fmt_wi=sprintf("%.1f", ($total_wait_time_wi/3600));
|
||||||
|
|
||||||
|
# Wipe unadjusted variables (i.e. no records)
|
||||||
|
$min_call_length=($min_call_length==1000000 ? "0" : $min_call_length);
|
||||||
|
$min_wait_time=($min_wait_time==1000000 ? "0" : $min_wait_time);
|
||||||
|
$min_position=($min_position==1000000 ? "0" : $min_position);
|
||||||
|
$min_call_length_wi=($min_call_length_wi==1000000 ? "0" : $min_call_length_wi);
|
||||||
|
$min_wait_time_wi=($min_wait_time_wi==1000000 ? "0" : $min_wait_time_wi);
|
||||||
|
$min_position_wi=($min_position_wi==1000000 ? "0" : $min_position_wi);
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("All calls")."</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>";
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
$HTML_output.="<th>"._QXZ("All calls").":</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>"._QXZ("N. calls answered by operators").":</td>";
|
||||||
|
$HTML_output.="<td>".$total_answered_calls."</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>"._QXZ("Average call length").":</td>";
|
||||||
|
$HTML_output.="<td>".$average_call_length." s.</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>"._QXZ("Min call length").":</td>";
|
||||||
|
$HTML_output.="<td>".($min_call_length>=3600 ? floor($min_call_length/3600).":" : "").gmdate("i:s", $min_call_length)."</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>"._QXZ("Max call length").":</td>";
|
||||||
|
$HTML_output.="<td>".($max_call_length>=3600 ? floor($max_call_length/3600).":" : "").gmdate("i:s", $max_call_length)."</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>"._QXZ("Total call length").":</td>";
|
||||||
|
$HTML_output.="<td>".$total_call_length_fmt." H</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>"._QXZ("Average call waiting time").":</td>";
|
||||||
|
$HTML_output.="<td>".$average_wait_time." s</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>"._QXZ("Min waiting time").":</td>";
|
||||||
|
$HTML_output.="<td>".($min_wait_time>=3600 ? floor($min_wait_time/3600).":" : "").gmdate("i:s", $min_wait_time)."</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>"._QXZ("Max waiting time").":</td>";
|
||||||
|
$HTML_output.="<td>".($max_wait_time>=3600 ? floor($max_wait_time/3600).":" : "").gmdate("i:s", $max_wait_time)."</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>"._QXZ("Total waiting time").":</td>";
|
||||||
|
$HTML_output.="<td>".$total_wait_time_fmt." H</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>"._QXZ("Average initial position").":</td>";
|
||||||
|
$HTML_output.="<td>".$average_position."</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>"._QXZ("Min initial position").":</td>";
|
||||||
|
$HTML_output.="<td>".$min_position."</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>"._QXZ("Max initial position").":</td>";
|
||||||
|
$HTML_output.="<td>".$max_position."</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
### Commented out 5/19/22 - not needed
|
||||||
|
### $HTML_output.="<tr>";
|
||||||
|
### $HTML_output.="<td>Coverage:</td>";
|
||||||
|
### $HTML_output.="<td>".$coverage."</td>";
|
||||||
|
### $HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='2' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=all_calls\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='2'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('STATS', 'all_calls')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
|
||||||
|
$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";
|
||||||
|
$CSV_output["all_calls"].="\""._QXZ("Min call length").":\",\"".($min_call_length>=3600 ? floor($min_call_length/3600).":" : "").gmdate("i:s", $min_call_length)."\"\n";
|
||||||
|
$CSV_output["all_calls"].="\""._QXZ("Max call length").":\",\"".($max_call_length>=3600 ? floor($max_call_length/3600).":" : "").gmdate("i:s", $max_call_length)."\"\n";
|
||||||
|
$CSV_output["all_calls"].="\""._QXZ("Total call length").":\",\"".$total_call_length_fmt." H\"\n";
|
||||||
|
$CSV_output["all_calls"].="\""._QXZ("Average call waiting time").":\",\"".$average_wait_time." H\"\n";
|
||||||
|
$CSV_output["all_calls"].="\""._QXZ("Min waiting time").":\",\"".($min_wait_time>=3600 ? floor($min_wait_time/3600).":" : "").gmdate("i:s", $min_wait_time)."\"\n";
|
||||||
|
$CSV_output["all_calls"].="\""._QXZ("Max waiting time").":\",\"".($max_wait_time>=3600 ? floor($max_wait_time/3600).":" : "").gmdate("i:s", $max_wait_time)."\"\n";
|
||||||
|
$CSV_output["all_calls"].="\""._QXZ("Total waiting time").":\",\"".$total_wait_time_fmt." H\"\n";
|
||||||
|
$CSV_output["all_calls"].="\""._QXZ("Average initial position").":\",\"".$average_position."\"\n";
|
||||||
|
$CSV_output["all_calls"].="\""._QXZ("Min initial position").":\",\"".$min_position."\"\n";
|
||||||
|
$CSV_output["all_calls"].="\""._QXZ("Max initial position").":\",\"".$max_position."\"\n";
|
||||||
|
|
||||||
|
### Commented out 5/19/22 - not needed
|
||||||
|
### $CSV_output["all_calls"].="\"Coverage:\",\"".$coverage."\"\n";
|
||||||
|
######################
|
||||||
|
|
||||||
|
#### AGENTS ON QUEUE ####
|
||||||
|
switch ($sort_agents_on_queue)
|
||||||
|
{
|
||||||
|
case "ncalls":
|
||||||
|
$ncalls_sort_value="ncalls desc";
|
||||||
|
$agent_sort_value="agent";
|
||||||
|
$ncalls_char="↑";
|
||||||
|
$agent_char="";
|
||||||
|
asort($agent_call_counts);
|
||||||
|
break;
|
||||||
|
case "ncalls desc":
|
||||||
|
$ncalls_sort_value="ncalls";
|
||||||
|
$agent_sort_value="agent";
|
||||||
|
$ncalls_char="↓";
|
||||||
|
$agent_char="";
|
||||||
|
arsort($agent_call_counts);
|
||||||
|
break;
|
||||||
|
case "agent":
|
||||||
|
$ncalls_sort_value="ncalls";
|
||||||
|
$agent_sort_value="agent desc";
|
||||||
|
$ncalls_char="";
|
||||||
|
$agent_char="↑";
|
||||||
|
ksort($agent_call_counts, SORT_NATURAL | SORT_FLAG_CASE);
|
||||||
|
break;
|
||||||
|
case "agent desc":
|
||||||
|
$ncalls_sort_value="ncalls";
|
||||||
|
$agent_sort_value="agent";
|
||||||
|
$ncalls_char="";
|
||||||
|
$agent_char="↓";
|
||||||
|
krsort($agent_call_counts, SORT_NATURAL | SORT_FLAG_CASE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$ncalls_sort_value="ncalls";
|
||||||
|
$agent_sort_value="agent";
|
||||||
|
$ncalls_char="";
|
||||||
|
$agent_char="";
|
||||||
|
ksort($agent_call_counts, SORT_NATURAL | SORT_FLAG_CASE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (preg_match('/ desc$/', $sort_agents_on_queue))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_agents_on_queue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_agents_on_queue." desc";
|
||||||
|
}
|
||||||
|
$sort_agents_on_queue_preg=preg_replace('/ desc$/', '', $sort_agents_on_queue);
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header' name='aoq_anchor' id='aoq_anchor'>"._QXZ("Agents on queue").":</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%'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>";
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
|
||||||
|
# $HTML_output.="<th><a class='header_link' name='aoq_sort_agent' id='aoq_sort_agent' href='".$PHP_SELF."?sort_agents_on_queue=".$agent_sort_value."#aoq_sort_agent'>"._QXZ("Agent")." ".$agent_char."</a></th>";
|
||||||
|
# $HTML_output.="<th><a class='header_link' name='aoq_sort_ncalls' id='aoq_sort_ncalls' href='".$PHP_SELF."?sort_agents_on_queue=".$ncalls_sort_value."#aoq_sort_ncalls'>"._QXZ("N. Calls")." ".$ncalls_char."</a></th>";
|
||||||
|
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("Agent").("agent"==$sort_agents_on_queue_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agents_on_queue').value='".("agent"==$sort_agents_on_queue_preg ? "$reverse_link" : "agent")."'; this.form.action+='#aoq_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='"._QXZ("N. Calls").("ncalls"==$sort_agents_on_queue_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_agents_on_queue').value='".("ncalls"==$sort_agents_on_queue_preg ? "$reverse_link" : "ncalls")."'; this.form.action+='#aoq_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Total call time")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Average call time")."</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["agents_on_queue"]="\""._QXZ("Agents on queue")."\"\n";
|
||||||
|
$CSV_output["agents_on_queue"].="\""._QXZ("Agent")."\",\""._QXZ("N. Calls")."\",\"\",\"...\",\""._QXZ("Total call time")."\",\""._QXZ("Average call time")."\"\n";
|
||||||
|
|
||||||
|
$highest_agent_call_count=max($agent_call_counts);
|
||||||
|
|
||||||
|
$agents_on_queue_graph_labels="[";
|
||||||
|
$agents_on_queue_graph_data="[";
|
||||||
|
$agents_on_queue_graph_bgcolor="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$agents_on_queue_graph_hovborder="[";
|
||||||
|
$x=0;
|
||||||
|
foreach ($agent_call_counts as $agentName => $value)
|
||||||
|
{
|
||||||
|
$call_count_percent=sprintf("%.1f", (100*$value)/$total_answered_calls);
|
||||||
|
$agent_total_call_length=$agent_call_lengths["$agentName"];
|
||||||
|
$agent_total_call_length_fmt=($agent_total_call_length>=3600 ? floor($agent_total_call_length/3600).":" : "").gmdate("i:s", $agent_total_call_length);
|
||||||
|
$agent_avg_call_length=round($agent_total_call_length/$value);
|
||||||
|
$agent_avg_call_length_fmt=($agent_avg_call_length>=3600 ? floor($agent_avg_call_length/3600).":" : "").gmdate("i:s", $agent_avg_call_length);
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='standard_font rpt_background_".($x%2)."'>";
|
||||||
|
$HTML_output.="<td>".$agentName."</td>";
|
||||||
|
$HTML_output.="<td>".$value."</td>";
|
||||||
|
$HTML_output.="<td>".$call_count_percent." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$value)/$highest_agent_call_count)."%'></td>";
|
||||||
|
$HTML_output.="<td>".$agent_total_call_length_fmt."</td>";
|
||||||
|
$HTML_output.="<td>".$agent_avg_call_length_fmt."</td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["agents_on_queue"].="\"".$agentName."\",\"".$value."\",\"".$call_count_percent." %\",\"\",\"".$agent_total_call_length_fmt."\",\"".$agent_avg_call_length_fmt."\"\n";
|
||||||
|
|
||||||
|
$agents_on_queue_graph_labels.="\"$agentName\",";
|
||||||
|
$agents_on_queue_graph_data.="\"$value\",";
|
||||||
|
$agents_on_queue_graph_bgcolor.="\"".$background_colors[$x]."\",";
|
||||||
|
$agents_on_queue_graph_hovborder.="\"".$border_colors[$x]."\",";
|
||||||
|
|
||||||
|
$x++;
|
||||||
|
}
|
||||||
|
$agents_on_queue_graph_labels=preg_replace('/,$/', '', $agents_on_queue_graph_labels)."]";
|
||||||
|
$agents_on_queue_graph_data=preg_replace('/,$/', '', $agents_on_queue_graph_data)."]";
|
||||||
|
$agents_on_queue_graph_bgcolor=preg_replace('/,$/', '', $agents_on_queue_graph_bgcolor)."]";
|
||||||
|
$agents_on_queue_graph_hovborder=preg_replace('/,$/', '', $agents_on_queue_graph_hovborder)."]";
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td colspan='6' class='export_row_cell'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=agents_on_queue&sort_agents_on_queue=".$sort_agents_on_queue."\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td colspan='6' class='export_row_cell'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('STATS', 'agents_on_queue')\" title=\"Export as a CSV file\" value='CSV'><input type='hidden' name='sort_agents_on_queue' value='$sort_agents_on_queue'></td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$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>";
|
||||||
|
$HTML_output.="<input type='hidden' name='sort_agents_on_queue' id='sort_agents_on_queue' value='sort_agents_on_queue'>";
|
||||||
|
######################
|
||||||
|
|
||||||
|
#### SERVICE LEVEL ####
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Service Level Agreement (inbound calls only)").":</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%'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>";
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Answer")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("N. Calls")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Delta")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Percent")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Of Offered")."</th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["service_level_agreement"]="\""._QXZ("Service Level Agreement (inbound calls only)").\"\n";
|
||||||
|
$CSV_output["service_level_agreement"].="\""._QXZ("Answer").\",\""._QXZ("N. Calls").\",\""._QXZ("Delta").\",\""._QXZ("Percent").\",\""._QXZ("Of Offered").\",\"...\"\n";
|
||||||
|
|
||||||
|
# $SLA_query is in VERM_global_vars.inc
|
||||||
|
$svc_lvl_stmt="select $SLA_query from vicidial_closer_log $vicidial_closer_log_SQL and (user!='VDCL')"; # and campaign_id in ($ingroup_str) and user in ('VDCL', $user_str)
|
||||||
|
$svc_lvl_rslt=mysqli_query($link, $svc_lvl_stmt);
|
||||||
|
if ($DB) {$HTML_output.="<B>$svc_lvl_stmt</B>";}
|
||||||
|
$svc_lvl_row=mysqli_fetch_assoc($svc_lvl_rslt);
|
||||||
|
#print_r($svc_lvl_row);
|
||||||
|
# {
|
||||||
|
# print "$interval - $sum\n";
|
||||||
|
# }
|
||||||
|
|
||||||
|
$service_level_agreement_graph_labels="[";
|
||||||
|
$service_level_agreement_graph_delta_data="[";
|
||||||
|
$service_level_agreement_graph_delta_bgcolor="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$service_level_agreement_graph_delta_hovborder="[";
|
||||||
|
$service_level_agreement_graph_percent_data="[";
|
||||||
|
$service_level_agreement_graph_percent_bgcolor="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$service_level_agreement_graph_percent_hovborder="[";
|
||||||
|
|
||||||
|
$x=0;
|
||||||
|
foreach($svc_lvl_row as $interval => $sum)
|
||||||
|
{
|
||||||
|
$int_name=ucwords(preg_replace("/_/", " ", $interval));
|
||||||
|
if ($prev_int) {$delta="+ ".($sum-$prev_int);} else {$delta=" ";}
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='standard_font rpt_background_".($x%2)."'>";
|
||||||
|
$HTML_output.="<td>$int_name "._QXZ("seconds").:</td>";
|
||||||
|
$HTML_output.="<td>".$sum."</td>";
|
||||||
|
$HTML_output.="<td align='right'><i>$delta</i> </td>";
|
||||||
|
$HTML_output.="<td align='right'>".sprintf("%.1f", ((100*$sum)/$answered_inbound_calls))." %</td>";
|
||||||
|
$HTML_output.="<td align='right'>".sprintf("%.1f", ((100*$sum)/$total_inbound_calls))." %</td>";
|
||||||
|
$HTML_output.="<td width='200'><img src='images/shade-histo.gif' height='10' width='".((100*$sum)/$answered_inbound_calls)."%'></td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["service_level_agreement"].="\"$int_name seconds:\",\"$sum\",\"$delta\",\"".sprintf("%.1f", ((100*$sum)/$answered_inbound_calls))." %\",\"".sprintf("%.1f", ((100*$sum)/$total_inbound_calls))." %\"\n";
|
||||||
|
|
||||||
|
$service_level_agreement_graph_labels.="\"$int_name\",";
|
||||||
|
$service_level_agreement_graph_delta_data.="\"".($prev_int ? ($sum-$prev_int) : "0")."\",";
|
||||||
|
$service_level_agreement_graph_delta_bgcolor.="\"#33CCCC\",";
|
||||||
|
$service_level_agreement_graph_delta_hovborder.="\"#66FFFF\",";
|
||||||
|
$service_level_agreement_graph_percent_data.="\"".sprintf("%.1f", ((100*$sum)/$answered_inbound_calls))."\",";
|
||||||
|
$service_level_agreement_graph_percent_bgcolor.="\"#FFCC66\",";
|
||||||
|
$service_level_agreement_graph_percent_hovborder.="\"#FFFF99\",";
|
||||||
|
|
||||||
|
$prev_int=$sum;
|
||||||
|
$x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$service_level_agreement_graph_labels=preg_replace('/,$/', '', $service_level_agreement_graph_labels)."]";
|
||||||
|
$service_level_agreement_graph_delta_data=preg_replace('/,$/', '', $service_level_agreement_graph_delta_data)."]";
|
||||||
|
$service_level_agreement_graph_delta_bgcolor=preg_replace('/,$/', '', $service_level_agreement_graph_delta_bgcolor)."]";
|
||||||
|
$service_level_agreement_graph_delta_hovborder=preg_replace('/,$/', '', $service_level_agreement_graph_delta_hovborder)."]";
|
||||||
|
$service_level_agreement_graph_percent_data=preg_replace('/,$/', '', $service_level_agreement_graph_percent_data)."]";
|
||||||
|
$service_level_agreement_graph_percent_bgcolor=preg_replace('/,$/', '', $service_level_agreement_graph_percent_bgcolor)."]";
|
||||||
|
$service_level_agreement_graph_percent_hovborder=preg_replace('/,$/', '', $service_level_agreement_graph_percent_hovborder)."]";
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' colspan='6'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=service_level_agreement\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td colspan='2' class='export_row_cell'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('STATS', 'service_level_agreement')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$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>";
|
||||||
|
######################
|
||||||
|
|
||||||
|
############ ALL UNANSWERED CALLLS ###########
|
||||||
|
##############################################
|
||||||
|
|
||||||
|
|
||||||
|
#### DISCONNECTIONS ###
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("Disconnection causes").":</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='5'>";
|
||||||
|
$HTML_output.="<tr><td width='60%'>";
|
||||||
|
$HTML_output.="<table width='100%' id='rpt_table'>";
|
||||||
|
$HTML_output.="<tr class='standard_font bold'>";
|
||||||
|
$HTML_output.="<th>"._QXZ("Cause")."</th>";
|
||||||
|
$HTML_output.="<th>"._QXZ("N. Calls")."</th>";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="<th>...</th>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["disconnection_causes"]="\""._QXZ("Disconnection causes").":\"\n";
|
||||||
|
$CSV_output["disconnection_causes"].="\""._QXZ("Cause")."\",\""._QXZ("N. Calls")."\",\"\",\"...\"\n";
|
||||||
|
|
||||||
|
$disconnection_causes_graph_labels="[";
|
||||||
|
$disconnection_causes_graph_data="[";
|
||||||
|
$disconnection_causes_graph_bgcolor="["; # SAME FOR hoverBackgroundColor
|
||||||
|
$disconnection_causes_graph_hovborder="[";
|
||||||
|
|
||||||
|
$max_term_reason=max($term_reasons);
|
||||||
|
$x=0;
|
||||||
|
foreach ($term_reasons as $reason => $value)
|
||||||
|
{
|
||||||
|
$term_reason_pct=sprintf("%.1f", (100*$value)/$total_answered_calls);
|
||||||
|
$HTML_output.="<tr class='standard_font rpt_background_".($x%2)."'>";
|
||||||
|
$HTML_output.="<td class='rpt_cell'>".$reason."</td>";
|
||||||
|
$HTML_output.="<td class='rpt_cell'>".$value."</td>";
|
||||||
|
$HTML_output.="<td class='rpt_cell'>".$term_reason_pct." %</td>";
|
||||||
|
$HTML_output.="<td class='rpt_cell' width='200'><img src='images/shade-histo.gif' height='10' width='".(100*($value/$max_term_reason))."%'></td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
|
||||||
|
$CSV_output["disconnection_causes"].="\"".$reason."\",\"".$value."\",\"".$term_reason_pct." %\"\n";
|
||||||
|
|
||||||
|
$disconnection_causes_graph_labels.="\"$reason\",";
|
||||||
|
$disconnection_causes_graph_data.="\"$value\",";
|
||||||
|
$disconnection_causes_graph_bgcolor.="\"".$background_colors[$x]."\",";
|
||||||
|
$disconnection_causes_graph_hovborder.="\"".$border_colors[$x]."\",";
|
||||||
|
|
||||||
|
$x++;
|
||||||
|
}
|
||||||
|
$disconnection_causes_graph_labels=preg_replace('/,$/', '', $disconnection_causes_graph_labels)."]";
|
||||||
|
$disconnection_causes_graph_data=preg_replace('/,$/', '', $disconnection_causes_graph_data)."]";
|
||||||
|
$disconnection_causes_graph_bgcolor=preg_replace('/,$/', '', $disconnection_causes_graph_bgcolor)."]";
|
||||||
|
$disconnection_causes_graph_hovborder=preg_replace('/,$/', '', $disconnection_causes_graph_hovborder)."]";
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' colspan='4'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=disconnection_causes\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td colspan='4' class='export_row_cell'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('STATS', 'disconnection_causes')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>\n";
|
||||||
|
$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>";
|
||||||
|
######################
|
||||||
|
|
||||||
|
|
||||||
|
$ACD_queue_counts=array();
|
||||||
|
$ACD_terminal_counts=array();
|
||||||
|
|
||||||
|
# ONLY COUNT ANSWERED CALLS
|
||||||
|
$stmt="select campaign_id, user, status, 0 as ring_time from vicidial_log $vicidial_log_SQL $and_NANQUE_clause UNION ALL select campaign_id, user, status, queue_seconds as ring_time from vicidial_closer_log $vicidial_closer_log_SQL $and_NANQUE_clause";
|
||||||
|
if ($DB) {$HTML_output.="<B>$stmt</B>";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
while ($row=mysqli_fetch_array($rslt))
|
||||||
|
{
|
||||||
|
$campaign_id=$row["campaign_id"];
|
||||||
|
$user=$row["user"];
|
||||||
|
$status=$row["status"];
|
||||||
|
$ring_time=$row["ring_time"];
|
||||||
|
|
||||||
|
if (preg_match('/VDAD|VDCL/', $user)) # && preg_match('/^DROP$|TIMEOT|WAITTO/', $status)
|
||||||
|
{
|
||||||
|
# UNANSWERED, DO NOTHING
|
||||||
|
$unanswered++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$ACD_queue_counts["$campaign_id"]["calls"]++;
|
||||||
|
$ACD_queue_counts["$campaign_id"]["ring_time"]+=$ring_time;
|
||||||
|
|
||||||
|
$ACD_terminal_counts["$user"]["calls"]++;
|
||||||
|
$ACD_terminal_counts["$user"]["ring_time"]+=$ring_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ksort($ACD_queue_counts);
|
||||||
|
ksort($ACD_terminal_counts);
|
||||||
|
|
||||||
|
|
||||||
|
##### ACD ATTEMPTS BY TERMINAL #####
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header'>"._QXZ("ACD attempts by terminal").":</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr><th>"._QXZ("Queue")."</th><th>"._QXZ("N. lost")."</th><th>"._QXZ("Avr ring")."</th><th>"._QXZ("Ring (s)")."</th><th>"._QXZ("N. Taken</th><th>"._QXZ("Avg ring")."</th><th>"._QXZ("Ring (s)")."</th></tr>";
|
||||||
|
|
||||||
|
$CSV_output["acd_attempts_by_terminal"]="\""._QXZ("Queue")."\",\""._QXZ("N. lost")."\",\""._QXZ("Avg ring")."\",\""._QXZ("Ring (s)")."\",\""._QXZ("N. Taken")."\",\""._QXZ("Avg ring")."\",\""._QXZ("Ring (s)")."\"\n";
|
||||||
|
$i=0;
|
||||||
|
foreach ($ACD_terminal_counts as $queue => $data)
|
||||||
|
{
|
||||||
|
if (!$data["lost_ring_time"] || !$data["lost"])
|
||||||
|
{
|
||||||
|
$avg_lost_time=" - ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$avg_lost_time=round($data["lost_ring_time"]/$data["lost"]);
|
||||||
|
$avg_lost_time=($avg_lost_time>=3600 ? intval(floor($avg_lost_time/3600)).date(":i:s", $avg_lost_time) : intval(date("i", $avg_lost_time)).":".date("s", $avg_lost_time));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$data["ring_time"] || !$data["calls"])
|
||||||
|
{
|
||||||
|
$avg_ring_time="0:00";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$avg_ring_time=round($data["ring_time"]/$data["calls"]);
|
||||||
|
$avg_ring_time=($avg_ring_time>=3600 ? intval(floor($avg_ring_time/3600)).date(":i:s", $avg_ring_time) : intval(date("i", $avg_ring_time)).":".date("s", $avg_ring_time));
|
||||||
|
}
|
||||||
|
|
||||||
|
$terminal=($terminal_names["$queue"]!="" ? $terminal_names["$queue"] : "($queue)");
|
||||||
|
$lost_time=($data["lost_ring_time"]>=3600 ? intval(floor($data["lost_ring_time"]/3600)).date(":i:s", $data["lost_ring_time"]) : intval(date("i", $data["lost_ring_time"])).":".date("s", $data["lost_ring_time"]));
|
||||||
|
$ring_time=($data["ring_time"]>=3600 ? intval(floor($data["ring_time"]/3600)).date(":i:s", $data["ring_time"]) : intval(date("i", $data["ring_time"])).":".date("s", $data["ring_time"]));
|
||||||
|
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\"".$terminal."\",";
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\"".(!$data["lost"] ? "0" : $data["lost"])."\",";
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\"".$avg_lost_time."\",";
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\"".$lost_time."\",";
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\"".(!$data["calls"] ? "0" : $data["calls"])."\",";
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\"".$avg_ring_time."\",";
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\"".$ring_time."\",";
|
||||||
|
$CSV_output["acd_attempts_by_terminal"].="\n";
|
||||||
|
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$HTML_output.="<td>".$terminal."</td>";
|
||||||
|
$HTML_output.="<td>".(!$data["lost"] ? "0": $data["lost"])."</td>";
|
||||||
|
$HTML_output.="<td>".$avg_lost_time."</td>";
|
||||||
|
$HTML_output.="<td>".$lost_time."</td>";
|
||||||
|
$HTML_output.="<td>".(!$data["calls"] ? "0" : $data["calls"])."</td>";
|
||||||
|
$HTML_output.="<td>".$avg_ring_time."</td>";
|
||||||
|
$HTML_output.="<td>".$ring_time."</td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<a href=\"".$PHP_SELF."?download_rpt=acd_attempts_by_terminal\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' colspan='7'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('STATS', 'acd_attempts_by_terminal')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table><BR>";
|
||||||
|
#############################
|
||||||
|
|
||||||
|
if ($download_rpt)
|
||||||
|
{
|
||||||
|
$data_to_download=$CSV_output["$download_rpt"];
|
||||||
|
|
||||||
|
$FILE_TIME = date("Ymd-His");
|
||||||
|
$CSVfilename = "STATS_RPT_".$download_rpt."_".$FILE_TIME.".csv";
|
||||||
|
header('Content-type: application/octet-stream');
|
||||||
|
|
||||||
|
header("Content-Disposition: attachment; filename=\"$CSVfilename\"");
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
ob_clean();
|
||||||
|
flush();
|
||||||
|
|
||||||
|
echo "$data_to_download";
|
||||||
|
|
||||||
|
if ($db_source == 'S')
|
||||||
|
{
|
||||||
|
mysqli_close($link);
|
||||||
|
$use_slave_server=0;
|
||||||
|
$db_source = 'M';
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
$endMS = microtime();
|
||||||
|
$startMSary = explode(" ",$startMS);
|
||||||
|
$endMSary = explode(" ",$endMS);
|
||||||
|
$runS = ($endMSary[0] - $startMSary[0]);
|
||||||
|
$runM = ($endMSary[1] - $startMSary[1]);
|
||||||
|
$TOTALrun = ($runS + $runM);
|
||||||
|
|
||||||
|
# $stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';";
|
||||||
|
# if ($DB) {echo "|$stmt|\n";}
|
||||||
|
# $rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $HTML_output;
|
||||||
|
|
||||||
|
?>
|
||||||
|
<script language='Javascript'>
|
||||||
|
var agents_on_queue_data = {
|
||||||
|
labels: <?php echo $agents_on_queue_graph_labels; ?>,
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "",
|
||||||
|
fill: false,
|
||||||
|
data: <?php echo $agents_on_queue_graph_data; ?>,
|
||||||
|
backgroundColor: <?php echo $agents_on_queue_graph_bgcolor; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $agents_on_queue_graph_bgcolor; ?>,
|
||||||
|
hoverBorderColor: <?php echo $agents_on_queue_graph_hovborder; ?>,
|
||||||
|
hoverBorderWidth: 2,
|
||||||
|
tension: 0,
|
||||||
|
fillColor: "rgba(255,230,230,0.5)",
|
||||||
|
borderColor: "rgba(255,255,255,0.8)",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
var agents_on_queue_canvas = document.getElementById("agents_on_queue_display");
|
||||||
|
var agents_on_queue_graph = new Chart(agents_on_queue_canvas, {type: 'pie', options: { plugins: {legend: { position: 'right', maxHeight:900, labels: {font:{size:10}} }}},
|
||||||
|
data: agents_on_queue_data});
|
||||||
|
|
||||||
|
var service_level_agreement_data = {
|
||||||
|
labels: <?php echo $service_level_agreement_graph_labels; ?>,
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
type: 'bar',
|
||||||
|
label: "Delta",
|
||||||
|
fill: false,
|
||||||
|
data: <?php echo $service_level_agreement_graph_delta_data; ?>,
|
||||||
|
backgroundColor: <?php echo $service_level_agreement_graph_delta_bgcolor; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $service_level_agreement_graph_delta_bgcolor; ?>,
|
||||||
|
hoverBorderColor: <?php echo $service_level_agreement_graph_delta_hovborder; ?>,
|
||||||
|
hoverBorderWidth: 2,
|
||||||
|
tension: 0,
|
||||||
|
order: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'line',
|
||||||
|
label: "Percent",
|
||||||
|
fill: true,
|
||||||
|
data: <?php echo $service_level_agreement_graph_percent_data; ?>,
|
||||||
|
backgroundColor: "rgba(255,204,102,0.5)",
|
||||||
|
hoverBorderWidth: 2,
|
||||||
|
tension: 0,
|
||||||
|
fillColor: "rgba(255,204,102,0.5)",
|
||||||
|
borderColor: "rgba(255,204,102,0.8)",
|
||||||
|
pointBorderColor: "rgba(255,255,153,1)",
|
||||||
|
pointBackgroundColor: "#FF9",
|
||||||
|
pointHoverBackgroundColor: "rgba(255,255,153,0.75)",
|
||||||
|
pointHoverBorderColor: "rgba(255,255,153,1)",
|
||||||
|
order: 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
var service_level_agreement_canvas = document.getElementById("service_level_agreement_display");
|
||||||
|
var service_level_agreement_graph = new Chart(service_level_agreement_canvas, {options: { plugins: {legend: { position: 'right' }}},
|
||||||
|
data: service_level_agreement_data});
|
||||||
|
|
||||||
|
|
||||||
|
var disconnection_causes_data = {
|
||||||
|
labels: <?php echo $disconnection_causes_graph_labels; ?>,
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "",
|
||||||
|
fill: false,
|
||||||
|
data: <?php echo $disconnection_causes_graph_data; ?>,
|
||||||
|
backgroundColor: <?php echo $disconnection_causes_graph_bgcolor; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $disconnection_causes_graph_bgcolor; ?>,
|
||||||
|
hoverBorderColor: <?php echo $disconnection_causes_graph_hovborder; ?>,
|
||||||
|
hoverBorderWidth: 2,
|
||||||
|
tension: 0,
|
||||||
|
fillColor: "rgba(255,230,230,0.5)",
|
||||||
|
borderColor: "rgba(255,255,255,0.8)",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
var disconnection_causes_canvas = document.getElementById("disconnection_causes_display");
|
||||||
|
var disconnection_causes_graph = new Chart(disconnection_causes_canvas, {type: 'pie', options: { plugins: {legend: { position: 'right' }}},
|
||||||
|
data: disconnection_causes_data});
|
||||||
|
|
||||||
|
/*
|
||||||
|
var answered_calls_by_queue_data = {
|
||||||
|
labels: <?php echo $answered_calls_by_queue_graph_labels; ?>,
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "",
|
||||||
|
fill: false,
|
||||||
|
data: <?php echo $answered_calls_by_queue_graph_data; ?>,
|
||||||
|
backgroundColor: <?php echo $answered_calls_by_queue_graph_bgcolor; ?>,
|
||||||
|
hoverBackgroundColor: <?php echo $answered_calls_by_queue_graph_bgcolor; ?>,
|
||||||
|
hoverBorderColor: <?php echo $answered_calls_by_queue_graph_hovborder; ?>,
|
||||||
|
hoverBorderWidth: 2,
|
||||||
|
tension: 0,
|
||||||
|
fillColor: "rgba(255,230,230,0.5)",
|
||||||
|
borderColor: "rgba(255,255,255,0.8)",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
var answered_calls_by_queue_canvas = document.getElementById("answered_calls_by_queue_display");
|
||||||
|
var answered_calls_by_queue_graph = new Chart(answered_calls_by_queue_canvas, {type: 'pie', options: { plugins: {legend: { position: 'right' }}},
|
||||||
|
data: answered_calls_by_queue_data});
|
||||||
|
*/
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,390 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_UNANSWERED_DT_rpt.inc - Vicidial Enhanced Reporting unanswered call detail report
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1615 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
if (isset($_GET["page_no"])) {$page_no=$_GET["page_no"];}
|
||||||
|
elseif (isset($_POST["page_no"])) {$page_no=$_POST["page_no"];}
|
||||||
|
if (isset($_GET["sort_unanswered_details"])) {$sort_unanswered_details=$_GET["sort_unanswered_details"];}
|
||||||
|
elseif (isset($_POST["sort_unanswered_details"])) {$sort_unanswered_details=$_POST["sort_unanswered_details"];}
|
||||||
|
|
||||||
|
if ($non_latin < 1)
|
||||||
|
{
|
||||||
|
$sort_unanswered_details = preg_replace('/[^\s\-_0-9a-zA-Z]/','',$sort_unanswered_details);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_unanswered_details = preg_replace('/[^\s\-_0-9\p{L}]/u','',$sort_unanswered_details);
|
||||||
|
}
|
||||||
|
|
||||||
|
$page_no=preg_replace('/[^0-9]/', '', $page_no);
|
||||||
|
if (!$page_no || $page_no<1) {$page_no=1;}
|
||||||
|
|
||||||
|
$ll=($page_no-1)*20;
|
||||||
|
$ul=($page_no*20);
|
||||||
|
|
||||||
|
$available_columns=array(
|
||||||
|
"Date" => "call_date",
|
||||||
|
"Caller" => "phone_number",
|
||||||
|
"Campaign/ingroup" => "campaign_id",
|
||||||
|
"IVR" => "ivr",
|
||||||
|
"Wait" => "wait",
|
||||||
|
"Duration" => "length_in_sec",
|
||||||
|
"Pos." => "queue_position",
|
||||||
|
"Disconnection" => "term_reason",
|
||||||
|
"Transferred to" => "transferred_to",
|
||||||
|
"Handled by" => "user",
|
||||||
|
"Attempts" => "attempts",
|
||||||
|
"Code" => "status",
|
||||||
|
"Stints" => "stints",
|
||||||
|
"Srv" => "srv",
|
||||||
|
"Asterisk UID" => "caller_code",
|
||||||
|
"MOH events" => "moh_events",
|
||||||
|
"MOH duration" => "moh_duration",
|
||||||
|
"IVR duration" => "ivr_duration",
|
||||||
|
"IVR path" => "ivr_path",
|
||||||
|
"DID" => "did",
|
||||||
|
"CRM" => "",
|
||||||
|
"Tag" => "tag",
|
||||||
|
"Feat" => "feat",
|
||||||
|
"Vars" => "vars",
|
||||||
|
"Feature Codes" => "feature_codes",
|
||||||
|
"Variables" => "variables"
|
||||||
|
);
|
||||||
|
|
||||||
|
$selected_columns=array(
|
||||||
|
_QXZ("Date") => "call_date",
|
||||||
|
_QXZ("Agent") => "user",
|
||||||
|
_QXZ("Caller") => "phone_number",
|
||||||
|
_QXZ("Campaign/ingroup") => "campaign_id",
|
||||||
|
_QXZ("Disconnection") => "term_reason",
|
||||||
|
_QXZ("Position") => "queue_position",
|
||||||
|
_QXZ("IVR") => "ivr_duration",
|
||||||
|
_QXZ("Wait") => "wait",
|
||||||
|
_QXZ("Attempts") => "attempts",
|
||||||
|
_QXZ("Code") => "status",
|
||||||
|
_QXZ("Key") => "key",
|
||||||
|
"uniqueid" => "detail_id"
|
||||||
|
);
|
||||||
|
# "Transferred to" => "transferred_to",
|
||||||
|
|
||||||
|
|
||||||
|
$sort_char="";
|
||||||
|
$sort_index="";
|
||||||
|
/*
|
||||||
|
switch($sort_unanswered_details)
|
||||||
|
{
|
||||||
|
case "phone_number":
|
||||||
|
case "campaign_id":
|
||||||
|
case "queue_position":
|
||||||
|
case "wait":
|
||||||
|
case "duration":
|
||||||
|
case "term_reason":
|
||||||
|
case "attempts":
|
||||||
|
case "phone_number desc":
|
||||||
|
case "campaign_id desc":
|
||||||
|
case "queue_position desc":
|
||||||
|
case "wait desc":
|
||||||
|
case "duration desc":
|
||||||
|
case "term_reason desc":
|
||||||
|
case "attempts desc":
|
||||||
|
$sort_clause=" order by $sort_unanswered_details, call_date";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "call_date":
|
||||||
|
case "user":
|
||||||
|
case "status":
|
||||||
|
case "ivr_duration":
|
||||||
|
case "call_date desc":
|
||||||
|
case "user desc":
|
||||||
|
case "status desc":
|
||||||
|
case "ivr_duration desc":
|
||||||
|
$sort_index=preg_replace('/ desc/', '', $sort_unanswered_details);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$sort_clause=" order by call_date";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
$sort_clause=" order by call_date";
|
||||||
|
$sort_index=preg_replace('/ desc/', '', $sort_unanswered_details);
|
||||||
|
if (preg_match('/ desc$/', $sort_unanswered_details))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_unanswered_details);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_unanswered_details." desc";
|
||||||
|
}
|
||||||
|
$sort_unanswered_details_preg=preg_replace('/ desc$/', '', $sort_unanswered_details);
|
||||||
|
|
||||||
|
# $stmt="select call_date, phone_number, campaign_id, 0 as ivr, '0:00' as wait, sec_to_time(round(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 did, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, uniqueid as detail_id, 'O' as direction from vicidial_log where call_date>='$start_date $start_time' and call_date<='$end_date $end_time' and user in ('VDAD') UNION select call_date, phone_number, campaign_id, 0 as ivr, sec_to_time(round(queue_seconds)) as wait, sec_to_time(round(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 did, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, CONCAT(uniqueid, '|', closecallid) as detail_id, 'I' as direction from vicidial_closer_log where call_date>='$start_date $start_time' and call_date<='$end_date $end_time' and user in ('VDCL') $and_NANQUE_clause $sort_clause";
|
||||||
|
|
||||||
|
$stmt="select call_date, phone_number, campaign_id, 0 as ivr, '0:00' as wait, sec_to_time(round(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 did, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, uniqueid as detail_id, 'O' as direction from vicidial_log $vicidial_log_SQL $exc_addtl_statuses and user in ('VDAD') UNION select call_date, phone_number, campaign_id, 0 as ivr, sec_to_time(round(queue_seconds)) as wait, sec_to_time(round(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 did, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, CONCAT(uniqueid, '|', closecallid) as detail_id, 'I' as direction from vicidial_closer_log $vicidial_closer_log_SQL $exc_addtl_statuses and user in ('VDCL') $and_NANQUE_clause $sort_clause";
|
||||||
|
|
||||||
|
if ($DB) {$HTML_output.="<B>$stmt</B>";}
|
||||||
|
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$total_pages=ceil(mysqli_num_rows($rslt)/20);
|
||||||
|
|
||||||
|
$HTML_output.="<BR><h2 class='rpt_header' id='sud_anchor'>"._QXZ("Unanswered Call Details").": $NWB#VERM_UNANSWERED_DT-details$NWE</h2>";
|
||||||
|
$HTML_output.="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'><a name='make_it_work' id='make_it_work'>";
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='left'><B><a name='page_anchor' class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&page_no=1#page_anchor' alt='First page of results'>|<</a> <a class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&page_no=".($page_no-1)."#page_anchor' alt='Prev page of results'><<</a></B></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='left'>";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('UNANSWERED_DT', '1')\" title=\"First page\" value='|<'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('UNANSWERED_DT', '".($page_no-1)."')\" title=\"Prev page\" value='<<'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='center' colspan='".(count($selected_columns)-2)."'> </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> <a class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&page_no=".$total_pages."#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='>>'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('UNANSWERED_DT', '".($total_pages)."')\" title=\"Last page\" value='>|'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$CSV_output="";
|
||||||
|
foreach ($selected_columns as $display_name => $column_name)
|
||||||
|
{
|
||||||
|
if ($display_name!="uniqueid")
|
||||||
|
{
|
||||||
|
$CSV_output.="\"$display_name\",";
|
||||||
|
# $HTML_output.="<th><a class='header_link' name='call_detail_sort_".$column_name."' id='call_detail_sort_".$column_name."' href='".$PHP_SELF."?sort_unanswered_details=".($column_name==$sort_unanswered_details_preg ? "$reverse_link" : "$column_name")."&page_no=".$page_no."#call_detail_sort_".$column_name."'>".$display_name.($column_name==$sort_unanswered_details_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
|
||||||
|
$HTML_output.="<th><input type='button' class='sort_button' value='".$display_name.($column_name==$sort_unanswered_details_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_unanswered_details').value='".($column_name==$sort_unanswered_details_preg ? "$reverse_link" : "$column_name")."'; this.form.action+='#sud_anchor'; this.form.submit()\"></th>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$CSV_output.="\n";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$output_array=array();
|
||||||
|
$i=0;
|
||||||
|
while ($row=mysqli_fetch_array($rslt))
|
||||||
|
{
|
||||||
|
$row["caller_code"]="";
|
||||||
|
$row["ivr"]="00:00";
|
||||||
|
$row["ivr_duration"]="00:00";
|
||||||
|
$row["ivr_path"]="";
|
||||||
|
$row["did"]="";
|
||||||
|
|
||||||
|
$uniqueid=$row["uniqueid"];
|
||||||
|
$row["campaign_id"]=$queue_names["$row[campaign_id]"];
|
||||||
|
$row["status"]=($status_names["$row[status]"] ? $status_names["$row[status]"] : $row["status"]);
|
||||||
|
$row["user"]=$fullname_info["$row[user]"];
|
||||||
|
|
||||||
|
$row["key"]=GetKeyPress($row["uniqueid"]);
|
||||||
|
|
||||||
|
$row["caller_code"]=GetCallerCode($row["uniqueid"]);
|
||||||
|
if ($row["direction"]=="I")
|
||||||
|
{
|
||||||
|
$ivr_info_array=GetIVRInfo($row["uniqueid"], $row["call_date"]);
|
||||||
|
$row["ivr"]=$ivr_info_array[0];
|
||||||
|
$row["ivr_duration"]=$ivr_info_array[1];
|
||||||
|
$row["ivr_path"]=$ivr_info_array[2];
|
||||||
|
$row["call_date"]=$ivr_info_array[3];
|
||||||
|
$row["did"]=GetDID($row["uniqueid"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($i>=$ll && $i<$ul || $download_rpt)
|
||||||
|
{
|
||||||
|
$current_row=array();
|
||||||
|
foreach ($selected_columns as $display_name => $column_name)
|
||||||
|
{
|
||||||
|
$current_row["$column_name"]=$row["$column_name"];
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($output_array, $current_row);
|
||||||
|
}
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($sort_index)
|
||||||
|
{
|
||||||
|
#$sort_index=8;
|
||||||
|
# print "***** $sort_index ********\n";
|
||||||
|
# array_multisort($output_array[$sort_index], SORT_ASC, SORT_STRING);
|
||||||
|
|
||||||
|
foreach ($output_array as $sorting_array) {
|
||||||
|
$sort_array_holder[] = $sorting_array["$sort_index"];
|
||||||
|
}
|
||||||
|
if (preg_match('/ desc$/', $sort_unanswered_details))
|
||||||
|
{
|
||||||
|
array_multisort($sort_array_holder,SORT_DESC, SORT_STRING,$output_array);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_multisort($sort_array_holder,SORT_ASC, SORT_STRING,$output_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
#usort($output_array, function($a, $b){
|
||||||
|
# return strcmp($a[$sort_index], $b[$sort_index]);
|
||||||
|
#});
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($output_array as $data_row)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
foreach ($data_row as $key => $value)
|
||||||
|
{
|
||||||
|
if ($key=="call_date")
|
||||||
|
{
|
||||||
|
$myDateTime = DateTime::createFromFormat('Y-m-d H:i:s', $value);
|
||||||
|
$value = $myDateTime->format('m/d - H:i:s');
|
||||||
|
}
|
||||||
|
if ($key!="detail_id")
|
||||||
|
{
|
||||||
|
$HTML_output.="<td>".$value."</td>";
|
||||||
|
$CSV_output.="\"".$value."\",";
|
||||||
|
}
|
||||||
|
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><IMG SRC=\"images/glass.png\" onClick=\"ShowCallDetails('$value')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP></td>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$CSV_output.="\n";
|
||||||
|
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
}
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='left'><B><a class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&page_no=1#page_anchor' alt='First page of results'>|<</a> <a class='header_link' href='".$PHP_SELF."?sort_unanswered_details=".$sort_unanswered_details."&page_no=".($page_no-1)."#page_anchor' alt='Prev page of results'><<</a></B></td>";
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='left'>";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('UNANSWERED_DT', '1')\" title=\"First page\" value='|<'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('UNANSWERED_DT', '".($page_no-1)."')\" title=\"Prev page\" value='<<'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='center' colspan='".(count($selected_columns)-2)."'>"._QXZ("Export as")."... <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> 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'> "._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> <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='>>'> ";
|
||||||
|
$HTML_output.="<input type='button' class='download_button' onClick=\"GoToDetailsPage('UNANSWERED_DT', '".($total_pages)."')\" title=\"Last page\" value='>|'>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
$HTML_output.="<input type=hidden name=page_no id=page_no value='$page_no'>";
|
||||||
|
$HTML_output.="<input type=hidden name=sort_unanswered_details id=sort_unanswered_details value='$sort_unanswered_details'>";
|
||||||
|
|
||||||
|
|
||||||
|
if ($download_rpt)
|
||||||
|
{
|
||||||
|
$data_to_download=$CSV_output;
|
||||||
|
|
||||||
|
$FILE_TIME = date("Ymd-His");
|
||||||
|
$CSVfilename = "UNANSWERS_DT_RPT_".$download_rpt."_".$FILE_TIME.".csv";
|
||||||
|
header('Content-type: application/octet-stream');
|
||||||
|
|
||||||
|
header("Content-Disposition: attachment; filename=\"$CSVfilename\"");
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
ob_clean();
|
||||||
|
flush();
|
||||||
|
|
||||||
|
echo "$data_to_download";
|
||||||
|
|
||||||
|
if ($db_source == 'S')
|
||||||
|
{
|
||||||
|
mysqli_close($link);
|
||||||
|
$use_slave_server=0;
|
||||||
|
$db_source = 'M';
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
$endMS = microtime();
|
||||||
|
$startMSary = explode(" ",$startMS);
|
||||||
|
$endMSary = explode(" ",$endMS);
|
||||||
|
$runS = ($endMSary[0] - $startMSary[0]);
|
||||||
|
$runM = ($endMSary[1] - $startMSary[1]);
|
||||||
|
$TOTALrun = ($runS + $runM);
|
||||||
|
|
||||||
|
# $stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';";
|
||||||
|
# if ($DB) {echo "|$stmt|\n";}
|
||||||
|
# $rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $HTML_output;
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
function GetCallerCode($uniqueid)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
$caller_code="";
|
||||||
|
$cc_stmt="select caller_code from vicidial_log_extended where uniqueid='$uniqueid'";
|
||||||
|
$cc_rslt=mysqli_query($link, $cc_stmt);
|
||||||
|
$cc_row=mysqli_fetch_array($cc_rslt);
|
||||||
|
$caller_code=$cc_row[0];
|
||||||
|
return $caller_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetKeyPress($uniqueid)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
$keypress="";
|
||||||
|
$keypress_stmt="select extension, max(start_time) From live_inbound_log where uniqueid='$uniqueid' and extension not in ('s', 'i', 't') and comment_a='CALLMENU' group by extension";
|
||||||
|
$keypress_rslt=mysql_to_mysqli($keypress_stmt, $link);
|
||||||
|
$keypress_row=mysqli_fetch_array($keypress_rslt);
|
||||||
|
$keypress=$keypress_row[0];
|
||||||
|
return $keypress;
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetIVRInfo($uniqueid, $actual_start_time)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
|
||||||
|
$ivr_path="";
|
||||||
|
$ivr_length=0;
|
||||||
|
$ivr_duration=0;
|
||||||
|
|
||||||
|
$ivr_stmt="select extension,start_time,comment_a,comment_b,comment_d,UNIX_TIMESTAMP(start_time),phone_ext from live_inbound_log where uniqueid='$uniqueid' and comment_a IN('CALLMENU') order by start_time";
|
||||||
|
$ivr_rslt=mysqli_query($link, $ivr_stmt);
|
||||||
|
$ivr_paths=array(); # 0 - total calls, 1 - total time, 2 - min time, 3 - max time
|
||||||
|
$ivr_counts=array();
|
||||||
|
while ($ivr_row=mysqli_fetch_array($ivr_rslt))
|
||||||
|
{
|
||||||
|
if(!$prev_time) {$prev_time=$ivr_row[5];}
|
||||||
|
if(!$ivr_start_time)
|
||||||
|
{
|
||||||
|
$actual_start_time=$ivr_row[1];
|
||||||
|
$ivr_start_time=$ivr_row[5];
|
||||||
|
}
|
||||||
|
$ivrpath.=$ivr_row["comment_b"];
|
||||||
|
|
||||||
|
$ivr_duration=$ivr_row[5]-$ivr_start_time;
|
||||||
|
$ivr_length+=$ivr_duration;
|
||||||
|
$prev_time=$ivr_row[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
$ivr_duration_fmt=($ivr_duration>=3600 ? floor($ivr_duration/3600).":" : "").gmdate("i:s", $ivr_duration);
|
||||||
|
$ivr_length_fmt=($ivr_length>=3600 ? floor($ivr_length/3600).":" : "").gmdate("i:s", $ivr_length);
|
||||||
|
|
||||||
|
return array("$ivr_length_fmt", "$ivr_duration_fmt", "$ivr_path", "$actual_start_time");
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetDID($uniqueid)
|
||||||
|
{
|
||||||
|
global $link, $DB, $did_id_info, $did_pattern_info;
|
||||||
|
|
||||||
|
$did_str="";
|
||||||
|
|
||||||
|
$did_stmt="select extension, did_id from vicidial_did_log where uniqueid in ('$uniqueid')";
|
||||||
|
$did_rslt=mysqli_query($link, $did_stmt);
|
||||||
|
$did_row=mysqli_fetch_array($did_rslt);
|
||||||
|
$did_str=$did_row["extension"]." - ".$did_id_info["$did_row[extension]"];
|
||||||
|
|
||||||
|
return $did_str;
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,894 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_admin.php - Vicidial Enhanced Reporting administration page
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1609 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
$startMS = microtime();
|
||||||
|
|
||||||
|
$version = '2.14-1';
|
||||||
|
$build = '220825-1609';
|
||||||
|
|
||||||
|
$report_name = 'VERM Reports';
|
||||||
|
|
||||||
|
header ("Content-type: text/html; charset=utf-8");
|
||||||
|
|
||||||
|
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;";
|
||||||
|
$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];
|
||||||
|
$outbound_autodial_active = $row[1];
|
||||||
|
$slave_db_server = $row[2];
|
||||||
|
$reports_use_slave_db = $row[3];
|
||||||
|
$SSenable_languages = $row[4];
|
||||||
|
$SSlanguage_method = $row[5];
|
||||||
|
$agent_whisper_enabled = $row[6];
|
||||||
|
$SSreport_default_format = $row[7];
|
||||||
|
$SSenable_pause_code_limits = $row[8];
|
||||||
|
$SSallow_web_debug = $row[9];
|
||||||
|
$SSadmin_screen_colors = $row[10];
|
||||||
|
$SSadmin_web_directory = $row[11];
|
||||||
|
}
|
||||||
|
if ($SSallow_web_debug < 1) {$DB=0;}
|
||||||
|
##### END SETTINGS LOOKUP #####
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
$db_source = 'M';
|
||||||
|
|
||||||
|
if (file_exists('options.php'))
|
||||||
|
{
|
||||||
|
require('options.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
### Force hard-coded variables
|
||||||
|
# $report_display_type='LIMITED';
|
||||||
|
# $ingroup_filter=array('_STAY','TEST_IN2','TEST_IN3');
|
||||||
|
|
||||||
|
if ( (strlen($group)>1) and (strlen($groups[0])<1) ) {$groups[0] = $group;}
|
||||||
|
else {$group = $groups[0];}
|
||||||
|
if (!isset($user_group_filter)) {$user_group_filter=array();}
|
||||||
|
if (!isset($ingroup_filter)) {$ingroup_filter=array();}
|
||||||
|
|
||||||
|
$NOW_TIME = date("Y-m-d H:i:s");
|
||||||
|
$NOW_DAY = date("Y-m-d");
|
||||||
|
$NOW_HOUR = date("H:i:s");
|
||||||
|
$STARTtime = date("U");
|
||||||
|
$epoch_YESTERDAY = ($STARTtime - 86400);
|
||||||
|
$YESTERDAY = date("Y-m-d",$epoch_YESTERDAY);
|
||||||
|
$epoch_DAY_BEFORE_YESTERDAY = ($STARTtime - 86400*2);
|
||||||
|
$DAY_BEFORE_YESTERDAY = date("Y-m-d",$epoch_DAY_BEFORE_YESTERDAY);
|
||||||
|
$epoch_SEVEN_DAYS = ($STARTtime - 86400*7);
|
||||||
|
$SEVEN_DAYS = date("Y-m-d",$epoch_SEVEN_DAYS);
|
||||||
|
$epoch_THIRTY_DAYS = ($STARTtime - 86400*30);
|
||||||
|
$THIRTY_DAYS = date("Y-m-d",$epoch_THIRTY_DAYS);
|
||||||
|
$epoch_NINETY_DAYS = ($STARTtime - 86400*90);
|
||||||
|
$NINETY_DAYS = date("Y-m-d",$epoch_NINETY_DAYS);
|
||||||
|
$webphone_content='';
|
||||||
|
|
||||||
|
$start_date=preg_replace('/[^-0-9]/', '', $start_date);
|
||||||
|
$end_date=preg_replace('/[^-0-9]/', '', $end_date);
|
||||||
|
|
||||||
|
if ($non_latin < 1)
|
||||||
|
{
|
||||||
|
$DB=preg_replace("/[^0-9a-zA-Z]/","",$DB);
|
||||||
|
$PHP_AUTH_USER = preg_replace('/[^-_0-9a-zA-Z]/', '', $PHP_AUTH_USER);
|
||||||
|
$PHP_AUTH_PW = preg_replace('/[^-_0-9a-zA-Z]/', '', $PHP_AUTH_PW);
|
||||||
|
$group = preg_replace('/[^-_0-9a-zA-Z]/','',$group);
|
||||||
|
$vicidial_queue_groups = preg_replace('/[^-_0-9a-zA-Z]/','',$vicidial_queue_groups);
|
||||||
|
$user_group_filter = preg_replace('/[^-_0-9a-zA-Z]/','',$user_group_filter);
|
||||||
|
$ingroup_filter = preg_replace('/[^-_0-9a-zA-Z]/','',$ingroup_filter);
|
||||||
|
$report_types_to_display = preg_replace('/[^\s\-_0-9a-zA-Z]/','',$report_types_to_display);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$DB=preg_replace("/[^0-9\p{L}]/u","",$DB);
|
||||||
|
$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);
|
||||||
|
$group = preg_replace('/[^-_0-9\p{L}]/u','',$group);
|
||||||
|
$vicidial_queue_groups = preg_replace('/[^-_0-9\p{L}]/u','',$vicidial_queue_groups);
|
||||||
|
$user_group_filter = preg_replace('/[^-_0-9\p{L}]/u','',$user_group_filter);
|
||||||
|
$ingroup_filter = preg_replace('/[^-_0-9\p{L}]/u','',$ingroup_filter);
|
||||||
|
$report_types_to_display = preg_replace('/[^\s\-_0-9\p{L}]/u','',$report_types_to_display);
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="SELECT selected_language from vicidial_users where user='$PHP_AUTH_USER';";
|
||||||
|
if ($DB) {echo "|$stmt|\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$sl_ct = mysqli_num_rows($rslt);
|
||||||
|
if ($sl_ct > 0)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$VUselected_language = $row[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$auth=0;
|
||||||
|
$reports_auth=0;
|
||||||
|
$admin_auth=0;
|
||||||
|
$auth_message = user_authorization($PHP_AUTH_USER,$PHP_AUTH_PW,'REPORTS',1,0);
|
||||||
|
if ( ($auth_message == 'GOOD') or ($auth_message == '2FA') )
|
||||||
|
{
|
||||||
|
$auth=1;
|
||||||
|
if ($auth_message == '2FA')
|
||||||
|
{
|
||||||
|
header ("Content-type: text/html; charset=utf-8");
|
||||||
|
echo _QXZ("Your session is expired").". <a href=\"/".$SSadmin_web_directory."/admin.php\">"._QXZ("Click here to log in")."</a>.\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($auth > 0)
|
||||||
|
{
|
||||||
|
$stmt="SELECT count(*) from vicidial_users where user='$PHP_AUTH_USER' and user_level > 7 and view_reports='1';";
|
||||||
|
if ($DB) {echo "|$stmt|\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$admin_auth=$row[0];
|
||||||
|
|
||||||
|
$stmt="SELECT count(*) from vicidial_users where user='$PHP_AUTH_USER' and user_level > 6 and view_reports='1';";
|
||||||
|
if ($DB) {echo "|$stmt|\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$reports_auth=$row[0];
|
||||||
|
|
||||||
|
if ($reports_auth < 1)
|
||||||
|
{
|
||||||
|
$VDdisplayMESSAGE = _QXZ("You are not allowed to view reports");
|
||||||
|
Header ("Content-type: text/html; charset=utf-8");
|
||||||
|
echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
if ( ($reports_auth > 0) and ($admin_auth < 1) )
|
||||||
|
{
|
||||||
|
$ADD=999999;
|
||||||
|
$reports_only_user=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$VDdisplayMESSAGE = _QXZ("Login incorrect, please try again");
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
##### BEGIN log visit to the vicidial_report_log table #####
|
||||||
|
$LOGip = getenv("REMOTE_ADDR");
|
||||||
|
$LOGbrowser = getenv("HTTP_USER_AGENT");
|
||||||
|
$LOGscript_name = getenv("SCRIPT_NAME");
|
||||||
|
$LOGserver_name = getenv("SERVER_NAME");
|
||||||
|
$LOGserver_port = getenv("SERVER_PORT");
|
||||||
|
$LOGrequest_uri = getenv("REQUEST_URI");
|
||||||
|
$LOGhttp_referer = getenv("HTTP_REFERER");
|
||||||
|
$LOGbrowser=preg_replace("/\'|\"|\\\\/","",$LOGbrowser);
|
||||||
|
$LOGrequest_uri=preg_replace("/\'|\"|\\\\/","",$LOGrequest_uri);
|
||||||
|
$LOGhttp_referer=preg_replace("/\'|\"|\\\\/","",$LOGhttp_referer);
|
||||||
|
if (preg_match("/443/i",$LOGserver_port)) {$HTTPprotocol = 'https://';}
|
||||||
|
else {$HTTPprotocol = 'http://';}
|
||||||
|
if (($LOGserver_port == '80') or ($LOGserver_port == '443') ) {$LOGserver_port='';}
|
||||||
|
else {$LOGserver_port = ":$LOGserver_port";}
|
||||||
|
$LOGfull_url = "$HTTPprotocol$LOGserver_name$LOGserver_port$LOGrequest_uri";
|
||||||
|
|
||||||
|
$LOGhostname = php_uname('n');
|
||||||
|
if (strlen($LOGhostname)<1) {$LOGhostname='X';}
|
||||||
|
if (strlen($LOGserver_name)<1) {$LOGserver_name='X';}
|
||||||
|
|
||||||
|
$stmt="SELECT webserver_id FROM vicidial_webservers where webserver='$LOGserver_name' and hostname='$LOGhostname' LIMIT 1;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
if ($DB) {echo "$stmt\n";}
|
||||||
|
$webserver_id_ct = mysqli_num_rows($rslt);
|
||||||
|
if ($webserver_id_ct > 0)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$webserver_id = $row[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
##### insert webserver entry
|
||||||
|
$stmt="INSERT INTO vicidial_webservers (webserver,hostname) values('$LOGserver_name','$LOGhostname');";
|
||||||
|
if ($DB) {echo "$stmt\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$affected_rows = mysqli_affected_rows($link);
|
||||||
|
$webserver_id = mysqli_insert_id($link);
|
||||||
|
}
|
||||||
|
|
||||||
|
##### END log visit to the vicidial_report_log table #####
|
||||||
|
|
||||||
|
if ( (strlen($slave_db_server)>5) and (preg_match("/$report_name/",$reports_use_slave_db)) )
|
||||||
|
{
|
||||||
|
mysqli_close($link);
|
||||||
|
$use_slave_server=1;
|
||||||
|
$db_source = 'S';
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
echo "<!-- Using slave server $slave_db_server $db_source -->\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($auth)
|
||||||
|
{
|
||||||
|
$stmt="SELECT user_id,user,pass,full_name,user_level,user_group,phone_login,phone_pass,delete_users,delete_user_groups,delete_lists,delete_campaigns,delete_ingroups,delete_remote_agents,load_leads,campaign_detail,ast_admin_access,ast_delete_phones,delete_scripts,modify_leads,hotkeys_active,change_agent_campaign,agent_choose_ingroups,closer_campaigns,scheduled_callbacks,agentonly_callbacks,agentcall_manual,vicidial_recording,vicidial_transfers,delete_filters,alter_agent_interface_options,closer_default_blended,delete_call_times,modify_call_times,modify_users,modify_campaigns,modify_lists,modify_scripts,modify_filters,modify_ingroups,modify_usergroups,modify_remoteagents,modify_servers,view_reports,vicidial_recording_override,alter_custdata_override,qc_enabled,qc_user_level,qc_pass,qc_finish,qc_commit,add_timeclock_log,modify_timeclock_log,delete_timeclock_log,alter_custphone_override,vdc_agent_api_access,modify_inbound_dids,delete_inbound_dids,active,alert_enabled,download_lists,agent_shift_enforcement_override,manager_shift_enforcement_override,shift_override_flag,export_reports,delete_from_dnc,email,user_code,territory,allow_alerts,callcard_admin,force_change_password,modify_shifts,modify_phones,modify_carriers,modify_labels,modify_statuses,modify_voicemail,modify_audiostore,modify_moh,modify_tts,modify_contacts,modify_same_user_level, user_location from vicidial_users where user='$PHP_AUTH_USER';";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$LOGfull_name =$row[3];
|
||||||
|
$LOGuser_level =$row[4];
|
||||||
|
$LOGuser_group =$row[5];
|
||||||
|
$LOGdelete_users =$row[8];
|
||||||
|
$LOGdelete_user_groups =$row[9];
|
||||||
|
$LOGdelete_lists =$row[10];
|
||||||
|
$LOGdelete_campaigns =$row[11];
|
||||||
|
$LOGdelete_ingroups =$row[12];
|
||||||
|
$LOGdelete_remote_agents =$row[13];
|
||||||
|
$LOGload_leads =$row[14];
|
||||||
|
$LOGcampaign_detail =$row[15];
|
||||||
|
$LOGast_admin_access =$row[16];
|
||||||
|
$LOGast_delete_phones =$row[17];
|
||||||
|
$LOGdelete_scripts =$row[18];
|
||||||
|
$LOGdelete_filters =$row[29];
|
||||||
|
$LOGalter_agent_interface =$row[30];
|
||||||
|
$LOGdelete_call_times =$row[32];
|
||||||
|
$LOGmodify_call_times =$row[33];
|
||||||
|
$LOGmodify_users =$row[34];
|
||||||
|
$LOGmodify_campaigns =$row[35];
|
||||||
|
$LOGmodify_lists =$row[36];
|
||||||
|
$LOGmodify_scripts =$row[37];
|
||||||
|
$LOGmodify_filters =$row[38];
|
||||||
|
$LOGmodify_ingroups =$row[39];
|
||||||
|
$LOGmodify_usergroups =$row[40];
|
||||||
|
$LOGmodify_remoteagents =$row[41];
|
||||||
|
$LOGmodify_servers =$row[42];
|
||||||
|
$LOGview_reports =$row[43];
|
||||||
|
$LOGmodify_dids =$row[56];
|
||||||
|
$LOGdelete_dids =$row[57];
|
||||||
|
$LOGmanager_shift_enforcement_override=$row[61];
|
||||||
|
$LOGexport_reports =$row[64];
|
||||||
|
$LOGdelete_from_dnc =$row[65];
|
||||||
|
$LOGcallcard_admin =$row[70];
|
||||||
|
$LOGforce_change_password =$row[71];
|
||||||
|
$LOGmodify_shifts =$row[72];
|
||||||
|
$LOGmodify_phones =$row[73];
|
||||||
|
$LOGmodify_carriers =$row[74];
|
||||||
|
$LOGmodify_labels =$row[75];
|
||||||
|
$LOGmodify_statuses =$row[76];
|
||||||
|
$LOGmodify_voicemail =$row[77];
|
||||||
|
$LOGmodify_audiostore =$row[78];
|
||||||
|
$LOGmodify_moh =$row[79];
|
||||||
|
$LOGmodify_tts =$row[80];
|
||||||
|
$LOGmodify_contacts =$row[81];
|
||||||
|
$LOGmodify_same_user_level =$row[82];
|
||||||
|
$LOGuser_location =$row[83];
|
||||||
|
|
||||||
|
$stmt="SELECT allowed_campaigns,allowed_reports,admin_viewable_groups,admin_viewable_call_times,allowed_queue_groups,reports_header_override,admin_home_url from vicidial_user_groups where user_group='$LOGuser_group';";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$LOGallowed_campaigns = $row[0];
|
||||||
|
$LOGallowed_reports = $row[1];
|
||||||
|
$LOGadmin_viewable_groups = $row[2];
|
||||||
|
$LOGadmin_viewable_call_times = $row[3];
|
||||||
|
$LOGallowed_queue_groups = $row[4];
|
||||||
|
$LOGreports_header_override = $row[5];
|
||||||
|
$LOGadmin_home_url = $row[6];
|
||||||
|
if (strlen($LOGadmin_home_url) > 5) {$SSadmin_home_url = $LOGadmin_home_url;}
|
||||||
|
|
||||||
|
|
||||||
|
$LOGadmin_viewable_groupsSQL='';
|
||||||
|
$valLOGadmin_viewable_groupsSQL='';
|
||||||
|
$vmLOGadmin_viewable_groupsSQL='';
|
||||||
|
if ( (!preg_match('/\-\-ALL\-\-/i',$LOGadmin_viewable_groups)) and (strlen($LOGadmin_viewable_groups) > 3) )
|
||||||
|
{
|
||||||
|
$rawLOGadmin_viewable_groupsSQL = preg_replace("/ \-/",'',$LOGadmin_viewable_groups);
|
||||||
|
$rawLOGadmin_viewable_groupsSQL = preg_replace("/ /","','",$rawLOGadmin_viewable_groupsSQL);
|
||||||
|
$LOGadmin_viewable_groupsSQL = "and user_group IN('---ALL---','$rawLOGadmin_viewable_groupsSQL')";
|
||||||
|
$whereLOGadmin_viewable_groupsSQL = "where user_group IN('---ALL---','$rawLOGadmin_viewable_groupsSQL')";
|
||||||
|
$valLOGadmin_viewable_groupsSQL = "and val.user_group IN('---ALL---','$rawLOGadmin_viewable_groupsSQL')";
|
||||||
|
$vmLOGadmin_viewable_groupsSQL = "and vm.user_group IN('---ALL---','$rawLOGadmin_viewable_groupsSQL')";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{$admin_viewable_groupsALL=1;}
|
||||||
|
|
||||||
|
$LOGallowed_queue_groupsSQL='';
|
||||||
|
if ( (!preg_match('/\-ALL\-GROUPS\-/i',$LOGallowed_queue_groups)) and (strlen($LOGallowed_queue_groups) > 3) )
|
||||||
|
{
|
||||||
|
$rawLOGallowed_queue_groupsSQL = preg_replace("/ \-/",'',$LOGallowed_queue_groups);
|
||||||
|
$rawLOGallowed_queue_groupsSQL = preg_replace("/ /","','",$rawLOGallowed_queue_groupsSQL);
|
||||||
|
$LOGallowed_queue_groupsSQL = "and queue_group IN('---ALL---','$rawLOGallowed_queue_groupsSQL')";
|
||||||
|
$whereLOGallowed_queue_groupsSQL = "where queue_group IN('---ALL---','$rawLOGallowed_queue_groupsSQL')";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{$admin_viewable_groupsALL=1;}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="SELECT allowed_campaigns,allowed_reports,webphone_url_override,webphone_dialpad_override,webphone_systemkey_override,allowed_custom_reports from vicidial_user_groups where user_group='$LOGuser_group';";
|
||||||
|
if ($DB) {echo "|$stmt|\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$LOGallowed_campaigns = $row[0];
|
||||||
|
$LOGallowed_reports = "$row[1]$row[5]";
|
||||||
|
$webphone_url = $row[2];
|
||||||
|
$webphone_dialpad_override = $row[3];
|
||||||
|
$system_key = $row[4];
|
||||||
|
|
||||||
|
$LOGallowed_campaignsSQL='';
|
||||||
|
$whereLOGallowed_campaignsSQL='';
|
||||||
|
if ( (!preg_match("/ALL-/",$LOGallowed_campaigns)) )
|
||||||
|
{
|
||||||
|
$rawLOGallowed_campaignsSQL = preg_replace("/ -/",'',$LOGallowed_campaigns);
|
||||||
|
$rawLOGallowed_campaignsSQL = preg_replace("/ /","','",$rawLOGallowed_campaignsSQL);
|
||||||
|
$LOGallowed_campaignsSQL = "and campaign_id IN('$rawLOGallowed_campaignsSQL')";
|
||||||
|
$whereLOGallowed_campaignsSQL = "where campaign_id IN('$rawLOGallowed_campaignsSQL')";
|
||||||
|
}
|
||||||
|
$regexLOGallowed_campaigns = " $LOGallowed_campaigns ";
|
||||||
|
|
||||||
|
|
||||||
|
if ( (!preg_match("/$report_name/",$LOGallowed_reports)) and (!preg_match("/ALL REPORTS/",$LOGallowed_reports)) )
|
||||||
|
{
|
||||||
|
Header("WWW-Authenticate: Basic realm=\"CONTACT-CENTER-ADMIN\"");
|
||||||
|
Header("HTTP/1.0 401 Unauthorized");
|
||||||
|
echo _QXZ("You are not allowed to view this report").": |$PHP_AUTH_USER|$report_name|"._QXZ("$report_name")."|\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$allactivecampaigns='';
|
||||||
|
$stmt="select campaign_id,campaign_name from vicidial_campaigns where active='Y' $LOGallowed_campaignsSQL order by campaign_id;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
if ($DB) {echo "$stmt\n";}
|
||||||
|
$groups_to_print = mysqli_num_rows($rslt);
|
||||||
|
$LISTgroups=array();
|
||||||
|
$LISTnames=array();
|
||||||
|
$i=0;
|
||||||
|
$LISTgroups[$i]='ALL-ACTIVE';
|
||||||
|
$i++;
|
||||||
|
$groups_to_print++;
|
||||||
|
while ($i < $groups_to_print)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$LISTgroups[$i] =$row[0];
|
||||||
|
$LISTnames[$i] =$row[1];
|
||||||
|
$allactivecampaigns .= "'$LISTgroups[$i]',";
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
$allactivecampaigns .= "''";
|
||||||
|
|
||||||
|
$i=0;
|
||||||
|
$group_string='|';
|
||||||
|
if (!$groups) {$groups=array();}
|
||||||
|
$group_ct = count($groups);
|
||||||
|
while($i < $group_ct)
|
||||||
|
{
|
||||||
|
$groups[$i] = preg_replace('/[^-_0-9a-zA-Z]/', '', $groups[$i]);
|
||||||
|
if ( (preg_match("/ $groups[$i] /",$regexLOGallowed_campaigns)) or (preg_match("/ALL-/",$LOGallowed_campaigns)) )
|
||||||
|
{
|
||||||
|
$group_string .= "$groups[$i]|";
|
||||||
|
$group_SQL .= "'$groups[$i]',";
|
||||||
|
$groupQS .= "&groups[]=$groups[$i]";
|
||||||
|
}
|
||||||
|
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
$group_SQL = preg_replace('/,$/i', '',$group_SQL);
|
||||||
|
|
||||||
|
$i=0;
|
||||||
|
$user_group_string='|';
|
||||||
|
$user_group_ct = count($user_group_filter);
|
||||||
|
while($i < $user_group_ct)
|
||||||
|
{
|
||||||
|
$user_group_filter[$i] = preg_replace('/[^-_0-9a-zA-Z]/', '', $user_group_filter[$i]);
|
||||||
|
# if ( (preg_match("/ $user_group_filter[$i] /",$regexLOGallowed_campaigns)) or (preg_match("/ALL-/",$LOGallowed_campaigns)) )
|
||||||
|
# {
|
||||||
|
$user_group_string .= "$user_group_filter[$i]|";
|
||||||
|
$user_group_SQL .= "'$user_group_filter[$i]',";
|
||||||
|
$usergroupQS .= "&user_group_filter[]=$user_group_filter[$i]";
|
||||||
|
# }
|
||||||
|
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
$user_group_SQL = preg_replace('/,$/i', '',$user_group_SQL);
|
||||||
|
|
||||||
|
$i=0;
|
||||||
|
$ingroup_string='|';
|
||||||
|
$ingroup_ct = count($ingroup_filter);
|
||||||
|
while($i < $ingroup_ct)
|
||||||
|
{
|
||||||
|
$ingroup_filter[$i] = preg_replace('/[^-_0-9a-zA-Z]/', '', $ingroup_filter[$i]);
|
||||||
|
$ingroup_string .= "$ingroup_filter[$i]|";
|
||||||
|
$ingroup_SQL .= "'$ingroup_filter[$i]',";
|
||||||
|
$usergroupQS .= "&ingroup_filter[]=$ingroup_filter[$i]";
|
||||||
|
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
$ingroup_SQL = preg_replace('/,$/i', '',$ingroup_SQL);
|
||||||
|
|
||||||
|
### if no campaigns selected, display all
|
||||||
|
if ( ($group_ct < 1) or (strlen($group_string) < 2) )
|
||||||
|
{
|
||||||
|
$groups[0] = 'ALL-ACTIVE';
|
||||||
|
$group_string = '|ALL-ACTIVE|';
|
||||||
|
$group = 'ALL-ACTIVE';
|
||||||
|
$groupQS .= "&groups[]=ALL-ACTIVE";
|
||||||
|
}
|
||||||
|
### if no user groups selected, display all
|
||||||
|
$user_group_none=0;
|
||||||
|
if ( ($user_group_ct < 1) or (strlen($user_group_string) < 2) )
|
||||||
|
{
|
||||||
|
$user_group_filter[0] = 'ALL-GROUPS';
|
||||||
|
$user_group_string = '|ALL-GROUPS|';
|
||||||
|
$usergroupQS .= "&user_group_filter[]=ALL-GROUPS";
|
||||||
|
$user_group_none=1;
|
||||||
|
}
|
||||||
|
### if no ingroups selected, display all
|
||||||
|
$ingroup_none=0;
|
||||||
|
if ( ($ingroup_ct < 1) or (strlen($ingroup_string) < 2) )
|
||||||
|
{
|
||||||
|
$ingroup_filter[0] = 'ALL-INGROUPS';
|
||||||
|
$ingroup_string = '|ALL-INGROUPS|';
|
||||||
|
$ingroupQS .= "&ingroup_filter[]=ALL-INGROUPS";
|
||||||
|
$ingroup_none=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (preg_match('/\s\-\-NONE\-\-\s/',$group_string) ) or ($group_ct < 1) )
|
||||||
|
{
|
||||||
|
$all_active = 0;
|
||||||
|
$group_SQL = "''";
|
||||||
|
$group_SQLand = "and FALSE";
|
||||||
|
$group_SQLwhere = "where FALSE";
|
||||||
|
}
|
||||||
|
elseif ( preg_match('/ALL\-ACTIVE/i',$group_string) )
|
||||||
|
{
|
||||||
|
$all_active = 1;
|
||||||
|
$group_SQL = $allactivecampaigns;
|
||||||
|
$group_SQLand = "and campaign_id IN($allactivecampaigns)";
|
||||||
|
$group_SQLwhere = "where campaign_id IN($allactivecampaigns)";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$all_active = 0;
|
||||||
|
$group_SQLand = "and campaign_id IN($group_SQL)";
|
||||||
|
$group_SQLwhere = "where campaign_id IN($group_SQL)";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (preg_match('/\s\-\-NONE\-\-\s/',$user_group_string) ) or ($user_group_ct < 1) )
|
||||||
|
{
|
||||||
|
$all_active_groups = 0;
|
||||||
|
$user_group_SQL = "''";
|
||||||
|
# $user_group_SQLand = "and FALSE";
|
||||||
|
# $user_group_SQLwhere = "where FALSE";
|
||||||
|
}
|
||||||
|
elseif ( preg_match('/ALL\-GROUPS/i',$user_group_string) )
|
||||||
|
{
|
||||||
|
$all_active_groups = 1;
|
||||||
|
# $user_group_SQL = '';
|
||||||
|
$user_group_SQL = "'$rawLOGadmin_viewable_groupsSQL'";
|
||||||
|
# $group_SQLand = "and campaign_id IN($allactivecampaigns)";
|
||||||
|
# $group_SQLwhere = "where campaign_id IN($allactivecampaigns)";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$all_active_groups = 0;
|
||||||
|
# $user_group_SQLand = "and user_group IN($user_group_SQL)";
|
||||||
|
# $user_group_SQLwhere = "where user_group IN($user_group_SQL)";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( (preg_match('/\s\-\-NONE\-\-\s/',$ingroup_string) ) or ($ingroup_ct < 1) )
|
||||||
|
{
|
||||||
|
$all_active_ingroups = 0;
|
||||||
|
$ingroup_SQL = "''";
|
||||||
|
}
|
||||||
|
elseif ( preg_match('/ALL\-INGROUPS/i',$ingroup_string) )
|
||||||
|
{
|
||||||
|
$all_active_ingroups = 1;
|
||||||
|
$ingroup_SQL = "'$rawLOGadmin_viewable_groupsSQL'";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$all_active_ingroups = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$stmt="select user_group, group_name from vicidial_user_groups $whereLOGadmin_viewable_groupsSQL order by user_group;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
if (!isset($DB)) {$DB=0;}
|
||||||
|
if ($DB) {echo "$stmt\n";}
|
||||||
|
$usergroups_to_print = mysqli_num_rows($rslt);
|
||||||
|
$i=0;
|
||||||
|
$usergroups=array();
|
||||||
|
$usergroupnames=array();
|
||||||
|
$usergroups[$i]='ALL-GROUPS';
|
||||||
|
$usergroupnames[$i] = "All user groups";
|
||||||
|
$i++;
|
||||||
|
$usergroups_to_print++;
|
||||||
|
while ($i < $usergroups_to_print)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$usergroups[$i] =$row[0];
|
||||||
|
$usergroupnames[$i] =$row[1];
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="select group_id,group_name from vicidial_inbound_groups $whereLOGadmin_viewable_groupsSQL order by group_id;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
if ($DB) {$MAIN.="$stmt\n";}
|
||||||
|
$ingroups_to_print = mysqli_num_rows($rslt);
|
||||||
|
$i=0;
|
||||||
|
$LISTingroups=array();
|
||||||
|
$LISTingroup_names=array();
|
||||||
|
$LISTingroups[$i]='ALL-INGROUPS';
|
||||||
|
$i++;
|
||||||
|
$ingroups_to_print++;
|
||||||
|
$ingroups_string='|';
|
||||||
|
while ($i < $ingroups_to_print)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$LISTingroups[$i] = $row[0];
|
||||||
|
$LISTingroup_names[$i] = $row[1];
|
||||||
|
$ingroups_string .= "$LISTingroups[$i]|";
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$stmt="select * from vicidial_queue_groups where active='Y' $LOGallowed_queue_groupsSQL order by queue_group, queue_group_name;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
# echo $stmt;
|
||||||
|
if ($DB) {$MAIN.="$stmt\n";}
|
||||||
|
$queue_groups_to_print = mysqli_num_rows($rslt);
|
||||||
|
$i=0;
|
||||||
|
$LISTqueue_groups=array();
|
||||||
|
$LISTqueue_group_names=array();
|
||||||
|
$LISTqueue_groups[$i]='ALL-INGROUPS';
|
||||||
|
$i++;
|
||||||
|
$queue_groups_to_print++;
|
||||||
|
$queue_groups_string='|';
|
||||||
|
$queue_groups_dropdown="";
|
||||||
|
while ($i < $queue_groups_to_print)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_array($rslt);
|
||||||
|
$LISTqueue_groups[$i] = $row["queue_group"];
|
||||||
|
$LISTqueue_group_names[$i] = $row["queue_group_name"];
|
||||||
|
$queue_groups_string .= "$LISTqueue_groups[$i]|";
|
||||||
|
$queue_groups_dropdown .= "\t<option data-value='$row[queue_group]' value='$row[queue_group_name]'/>\n";
|
||||||
|
$i++;
|
||||||
|
|
||||||
|
if (!$default_queue_group) {$default_queue_group=$row["queue_group_name"];}
|
||||||
|
}
|
||||||
|
|
||||||
|
# require("screen_colors.php");
|
||||||
|
|
||||||
|
$NFB = '<b><font size=6 face="courier">';
|
||||||
|
$NFE = '</font></b>';
|
||||||
|
$F=''; $FG=''; $B=''; $BG='';
|
||||||
|
|
||||||
|
|
||||||
|
$NWB = "<IMG SRC=\"help.png\" onClick=\"FillAndShowHelpDiv(event, '";
|
||||||
|
$NWE = "')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP>";
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<script language="Javascript">
|
||||||
|
function LaunchReport(time_period, agent_flag)
|
||||||
|
{
|
||||||
|
if (!time_period) {return false;}
|
||||||
|
|
||||||
|
var full_report_var_str="";
|
||||||
|
|
||||||
|
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="<?php echo $VERM_default_report_queue; ?>";
|
||||||
|
full_report_var_str+="&vicidial_queue_groups="+vicidial_queue_groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (agent_flag)
|
||||||
|
{
|
||||||
|
full_report_var_str+="&report_types_to_display=All+reports";
|
||||||
|
full_report_var_str+="&users="+agent_flag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var report_types_to_display_value=$( "input[type=text][id=report_types_to_display]" ).val();
|
||||||
|
if (report_types_to_display_value!="")
|
||||||
|
{
|
||||||
|
var report_type=$('#VERM_reports [value="' + report_types_to_display_value + '"]').data('value');
|
||||||
|
full_report_var_str+="&report_types_to_display="+report_type;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
full_report_var_str+="&report_types_to_display=All+reports";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
full_report_var_str+="&time_period="+time_period;
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (start_date) {full_report_var_str+="&start_date="+start_date;}
|
||||||
|
|
||||||
|
var start_time_hour="";
|
||||||
|
var start_time_min="";
|
||||||
|
if (start_time)
|
||||||
|
{
|
||||||
|
start_time_array=start_time.split(":");
|
||||||
|
start_time_hour=start_time_array[0];
|
||||||
|
start_time_min=start_time_array[1];
|
||||||
|
}
|
||||||
|
if (start_time_hour) {full_report_var_str+="&start_time_hour="+start_time_hour;}
|
||||||
|
if (start_time_min) {full_report_var_str+="&start_time_min="+start_time_min;}
|
||||||
|
|
||||||
|
if (end_date) {full_report_var_str+="&end_date="+end_date;}
|
||||||
|
|
||||||
|
var end_time_hour="";
|
||||||
|
var end_time_min="";
|
||||||
|
if (end_time)
|
||||||
|
{
|
||||||
|
end_time_array=end_time.split(":");
|
||||||
|
end_time_hour=end_time_array[0];
|
||||||
|
end_time_min=end_time_array[1];
|
||||||
|
}
|
||||||
|
if (end_time_hour) {full_report_var_str+="&end_time_hour="+end_time_hour;}
|
||||||
|
if (end_time_min) {full_report_var_str+="&end_time_min="+end_time_min;}
|
||||||
|
*/
|
||||||
|
|
||||||
|
document.location.href=document.forms[0].action+"?"+full_report_var_str;
|
||||||
|
// alert(document.forms[0].action+"?"+full_report_var_str);
|
||||||
|
}
|
||||||
|
function LaunchWallboard(wallboard_id)
|
||||||
|
{
|
||||||
|
var report_queues_value=$( "input[type=text][id=vicidial_queue_groups]" ).val();
|
||||||
|
if (report_queues_value=="")
|
||||||
|
{
|
||||||
|
var vicidial_queue_groups="<?php echo $VERM_default_report_queue; ?>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var vicidial_queue_groups=$('#VERM_report_queues [value="' + report_queues_value + '"]').data('value');
|
||||||
|
}
|
||||||
|
document.location.href="VERM_wallboards.php?action=run&wallboard_user=<?php echo $PHP_AUTH_USER; ?>&wallboard_id=main&vicidial_queue_group="+vicidial_queue_groups;
|
||||||
|
}
|
||||||
|
</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 language="JavaScript" src="help.js"></script>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$stmt = "select count(*) from vicidial_campaigns where active='Y' and campaign_allow_inbound='Y' $group_SQLand;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
if ($DB) {echo "$stmt\n";}
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$campaign_allow_inbound = $row[0];
|
||||||
|
|
||||||
|
echo "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=utf-8\">\n";
|
||||||
|
echo "<TITLE>"._QXZ("$report_name")."</TITLE></HEAD><BODY BGCOLOR=WHITE marginheight=0 marginwidth=0 leftmargin=0 topmargin=0>\n";
|
||||||
|
echo "<div id='HelpDisplayDiv' class='help_info' style='display:none;'></div>";
|
||||||
|
|
||||||
|
$short_header=1;
|
||||||
|
$ADMIN="/$SSadmin_web_directory/admin.php";
|
||||||
|
require("../$SSadmin_web_directory/admin_header.php");
|
||||||
|
|
||||||
|
if (!$vicidial_queue_groups) {$vicidial_queue_groups=$VERM_default_report_queue;}
|
||||||
|
if (!$report_types_to_display) {$report_types_to_display='All reports';}
|
||||||
|
|
||||||
|
if (!$selected_report_type)
|
||||||
|
{
|
||||||
|
echo "<form action='VERM_main_report_page.php' method='POST'>";
|
||||||
|
echo "<TABLE style='width:".($LOGuser_level==9 ? "1000" : "800")."px' id='admin_table' CELLPADDING=4 CELLSPACING=0><TR><TD>";
|
||||||
|
echo "<TR>";
|
||||||
|
echo "<TH colspan='3'>";
|
||||||
|
echo "<table style='width:".($LOGuser_level==9 ? "1000" : "800")."px' align='left' border='0' cellpadding='2'>";
|
||||||
|
|
||||||
|
echo "<tr>";
|
||||||
|
echo "<td colspan='6' align='right' valign='middle' class='standard_font_small'><B>$PHP_AUTH_USER</B> | $LOGfull_name<BR><BR>";
|
||||||
|
echo "<a class='header_link' href='javascript:window.location.reload()'>"._QXZ("RELOAD")." ↻</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>";
|
||||||
|
|
||||||
|
echo "<tr class='export_row'>";
|
||||||
|
echo "<td align='right'>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\">";
|
||||||
|
echo $queue_groups_dropdown;
|
||||||
|
echo " </datalist>";
|
||||||
|
echo "$NWB#VERM_admin-queue$NWE";
|
||||||
|
echo "</td>";
|
||||||
|
echo "<td align='right'>"._QXZ("Report").":</td>";
|
||||||
|
echo "<td align='left' width='220' nowrap>";
|
||||||
|
# echo " <select id=\"report_types\" name=\"report_types\">";
|
||||||
|
echo " <input list='VERM_reports' type='text' class='VERM_form_field' id='report_types_to_display' name='report_types_to_display' value='$report_types_to_display' onMouseover=\"javascript:this.value=''\">\n"; # onMouseover=\"javascript:this.value=''\"
|
||||||
|
echo " <datalist id='VERM_reports'>\n";
|
||||||
|
echo " <option data-value='All reports' value='"._QXZ("All reports")."'/>\n";
|
||||||
|
echo " <option data-value='Quick agents report' value='"._QXZ("Quick agents report")."'/>\n";
|
||||||
|
echo " <option data-value='Quick reports' value='"._QXZ("Quick reports")."'/>\n";
|
||||||
|
echo " </datalist>\n";
|
||||||
|
echo "$NWB#VERM_admin-report$NWE";
|
||||||
|
# echo " </select>";
|
||||||
|
echo "</td>";
|
||||||
|
/*
|
||||||
|
echo "<td align='right'>Supervision:</td>";
|
||||||
|
echo "<td align='left'>";
|
||||||
|
echo " <select id=\"report_supervision\" name=\"report_supervision\">";
|
||||||
|
echo " <option value=''></option>\n";
|
||||||
|
echo " <option value='Y'>Yes</option>\n";
|
||||||
|
echo " <option value='N'>No</option>\n";
|
||||||
|
echo " </select>";
|
||||||
|
echo "</td>";
|
||||||
|
*/
|
||||||
|
echo "<td align='left' valign='middle' width='160px'>";
|
||||||
|
echo "<input type='button' class='actButton' value='-- "._QXZ("RUN REPORT")." -->' onClick=\"LaunchReport('LAST7DAYS')\">";
|
||||||
|
echo "</td>";
|
||||||
|
echo "<td align='left' valign='middle'>";
|
||||||
|
# echo "<img src='images/refresh.png' border='0' onClick='javascript:window.reload()'>"; #input type='button' class='refreshButton' value='↻'
|
||||||
|
echo "<input type='button' class='refreshButton' value='↻' onClick='javascript:document.forms[0].reset()'>";
|
||||||
|
echo "</td>";
|
||||||
|
echo "</tr>";
|
||||||
|
echo "</table>";
|
||||||
|
echo "</tH>";
|
||||||
|
echo "</TR>";
|
||||||
|
echo "<TR>";
|
||||||
|
echo "<TD width='".($LOGuser_level==9 ? "33" : "50")."%' valign='top' class='admin_column'>";
|
||||||
|
echo "<font class='rpt_header'>"._QXZ("Agent report")."$NWB#VERM_admin-agent$NWE</font><BR>";
|
||||||
|
echo " "._QXZ("Filtered for agent").":<BR><select id=\"users\" name=\"users\" class='VERM_form_field'>";
|
||||||
|
echo "<option value=''> - </option>";
|
||||||
|
$user_stmt="select user, full_name from vicidial_users $whereLOGadmin_viewable_groupsSQL order by full_name";
|
||||||
|
$user_rslt=mysql_to_mysqli($user_stmt, $link);
|
||||||
|
while ($user_row=mysqli_fetch_array($user_rslt))
|
||||||
|
{
|
||||||
|
echo "<option value='$user_row[user]'>$user_row[full_name]</option>";
|
||||||
|
}
|
||||||
|
echo " </select>";
|
||||||
|
|
||||||
|
echo "<ul>";
|
||||||
|
echo "<li><a class='report_link' onClick=\"LaunchReport('TODAY', document.getElementById('users').value)\">"._QXZ("Today")."</a></li>"; # href='VERM_main_report_page.php?report_type=AGENTS&time_period=TODAY'
|
||||||
|
echo "<li><a class='report_link' onClick=\"LaunchReport('YESTERDAY', document.getElementById('users').value)\">"._QXZ("Yesterday")."</a></li>"; # href='VERM_main_report_page.php?report_type=AGENTS&start_date=".$YESTERDAY."&start_time=00:00:00&end_date=".$YESTERDAY."&end_time=23:59:59'
|
||||||
|
echo "<li><a class='report_link' onClick=\"LaunchReport('DAYBEFORE', document.getElementById('users').value)\">"._QXZ("Day before yesterday")."</a></li>"; # href='VERM_main_report_page.php?report_type=AGENTS&start_date=".$DAY_BEFORE_YESTERDAY."&start_time=00:00:00&end_date=".$DAY_BEFORE_YESTERDAY."&end_time=23:59:59'
|
||||||
|
echo "<li><a class='report_link' onClick=\"LaunchReport('LAST24HOURS', document.getElementById('users').value)\">"._QXZ("Last 24 hours")."</a></li>"; # href='VERM_main_report_page.php?report_type=AGENTS&start_date=".$YESTERDAY."&end_date=".$TODAY."'
|
||||||
|
echo "<li><a class='report_link' onClick=\"LaunchReport('LAST7DAYS', document.getElementById('users').value)\">"._QXZ("Last 7 days")."</a></li>"; # href='VERM_main_report_page.php?report_type=AGENTS&start_date=".$SEVEN_DAYS."&end_date=".$TODAY."'
|
||||||
|
echo "<li><a class='report_link' onClick=\"LaunchReport('LAST30DAYS', document.getElementById('users').value)\">"._QXZ("Last 30 days")."</a></li>"; # href='VERM_main_report_page.php?report_type=AGENTS&start_date=".$THIRTY_DAYS."&end_date=".$TODAY."'
|
||||||
|
echo "<li><a class='report_link' onClick=\"LaunchReport('LAST90DAYS', document.getElementById('users').value)\">"._QXZ("Last 90 days")."</a></li>"; # href='VERM_main_report_page.php?report_type=AGENTS&start_date=".$NINETY_DAYS."&end_date=".$TODAY."'
|
||||||
|
echo "</ul><BR><BR>";
|
||||||
|
|
||||||
|
if ( ($LOGuser_level >= 9) and ( (preg_match("/VERM QA link/",$LOGallowed_reports)) or (preg_match("/ALL REPORTS/",$LOGallowed_reports)) ) )
|
||||||
|
{
|
||||||
|
echo "<font class='rpt_header'>"._QXZ("Quality Assessment")."$NWB#VERM_admin-qa$NWE</font><BR>";
|
||||||
|
echo "<a class='report_link' onClick=\"LaunchWallboard('main')\">"._QXZ("Start wallboard")."</a><BR><BR>";
|
||||||
|
}
|
||||||
|
echo "</TD>";
|
||||||
|
echo "<TD width='".($LOGuser_level>=9 ? "34" : "50")."' valign='top' class='admin_column'>";
|
||||||
|
echo "<font class='rpt_header'>"._QXZ("Real-time reports")."$NWB#VERM_admin-realtime_reports$NWE</font><BR>";
|
||||||
|
echo "<a class='report_link' onClick=\"LaunchWallboard('main')\">"._QXZ("Start wallboard")."</a><BR>";
|
||||||
|
echo "<a href='/".$SSadmin_web_directory."/realtime_report.php?report_display_type=HTML' class='report_link'>"._QXZ("Real-time report")."</a><BR><BR>";
|
||||||
|
echo "<font class='rpt_header'>"._QXZ("Quick activity reports")."$NWB#VERM_admin-quick_reports$NWE</font><BR>";
|
||||||
|
echo "<ul>";
|
||||||
|
echo "<li><a class='report_link' onClick=\"LaunchReport('TODAY')\">"._QXZ("Today")."</a></li>"; # href='VERM_main_report_page.php?report_type=ANSWERED&time_period=TODAY'
|
||||||
|
echo "<li><a class='report_link' onClick=\"LaunchReport('YESTERDAY')\">"._QXZ("Yesterday")."</a></li>";
|
||||||
|
echo "<li><a class='report_link' onClick=\"LaunchReport('DAYBEFORE')\">"._QXZ("Day before yesterday")."</a></li>"; # href='VERM_main_report_page.php?report_type=ANSWERED&time_period=DAYBEFORE'
|
||||||
|
echo "<li><a class='report_link' onClick=\"LaunchReport('LAST24HOURS')\">"._QXZ("Last 24 hours")."</a></li>"; # href='VERM_main_report_page.php?report_type=ANSWERED&time_period=LAST24HOURS'
|
||||||
|
echo "<li><a class='report_link' onClick=\"LaunchReport('LAST7DAYS')\">"._QXZ("Last 7 days")."</a></li>"; # href='VERM_main_report_page.php?report_type=ANSWERED&time_period=LAST7DAYS'
|
||||||
|
echo "<li><a class='report_link' onClick=\"LaunchReport('LAST30DAYS')\">"._QXZ("Last 30 days")."</a></li>"; # href='VERM_main_report_page.php?report_type=ANSWERED&time_period=LAST30DAYS'
|
||||||
|
echo "<li><a class='report_link' onClick=\"LaunchReport('LAST90DAYS')\">"._QXZ("Last 90 days")."</a></li>"; # href='VERM_main_report_page.php?report_type=ANSWERED&time_period=LAST90DAYS'
|
||||||
|
echo "</ul><BR><BR>";
|
||||||
|
echo "<font class='rpt_header'>"._QXZ("Custom report")."$NWB#VERM_admin-custom_report$NWE</font><BR>";
|
||||||
|
echo "<a href='VERM_custom_report.php".($start_date && $end_date ? "?start_date=$start_date&end_date=$end_date" : "")."' class='header_link'>"._QXZ("Run custom report")."</a><BR><BR>";
|
||||||
|
echo "<font class='rpt_header'>"._QXZ("Wallboards")."$NWB#VERM_admin-wallboards$NWE</font><BR>";
|
||||||
|
#$wb_stmt=
|
||||||
|
# echo "<a href='VERM_wallboards.php?action=run&wallboard_user=".$PHP_AUTH_USER."&wallboard_id=' class='header_link'>Wallboard</a><BR><BR>";
|
||||||
|
echo "<a class='report_link' onClick=\"LaunchWallboard('main')\">"._QXZ("Wallboard")."</a><BR><BR>";
|
||||||
|
|
||||||
|
echo "</TD>";
|
||||||
|
if ($LOGuser_level>=9)
|
||||||
|
{
|
||||||
|
echo "<TD width='33%' valign='top' class='admin_column'>";
|
||||||
|
echo "<font class='rpt_header'>"._QXZ("Settings").":$NWB#VERM_admin-settings$NWE</font><BR>";
|
||||||
|
echo "<ul>";
|
||||||
|
echo "<li><a class='report_link' href='/".$SSadmin_web_directory."/admin.php?ADD=0A'>"._QXZ("Users")."</a></li>";
|
||||||
|
echo "<li><a class='report_link' href='/".$SSadmin_web_directory."/admin.php?ADD=198000000000'>"._QXZ("Queues")."</a></li>";
|
||||||
|
echo "<li><a class='report_link' href='/".$SSadmin_web_directory."/admin.php?ADD=100000'>"._QXZ("User groups")."</a></li>";
|
||||||
|
echo "<li><a class='report_link' href='/".$SSadmin_web_directory."/admin.php?ADD=392111111111&container_id=USER_LOCATIONS_SYSTEM'>"._QXZ("Locations")."</a></li>";
|
||||||
|
echo "<li>"._QXZ("Statuses/Outcomes")."";
|
||||||
|
echo "<ul>";
|
||||||
|
echo "<li><a class='report_link' href='/".$SSadmin_web_directory."/admin.php?ADD=32'>"._QXZ("Campaign")."</a></li>";
|
||||||
|
echo "<li><a class='report_link' href='/".$SSadmin_web_directory."/admin.php?ADD=321111111111111'>"._QXZ("System")."</a></li>";
|
||||||
|
echo "</ul>";
|
||||||
|
echo "</li>";
|
||||||
|
echo "<li><a class='report_link' href='/".$SSadmin_web_directory."/admin.php?ADD=37'>"._QXZ("Pause codes")."</a></li>";
|
||||||
|
echo "<li><a class='report_link' href='/".$SSadmin_web_directory."/admin.php?ADD=1500'>"._QXZ("IVR/Call menus")."</a></li>";
|
||||||
|
echo "<li><a class='report_link' href='/".$SSadmin_web_directory."/admin.php?ADD=1300'>"._QXZ("DID/DNIS lines")."</a></li>";
|
||||||
|
echo "</ul>";
|
||||||
|
echo "</TD>";
|
||||||
|
}
|
||||||
|
echo "</TR>";
|
||||||
|
echo "</TABLE>";
|
||||||
|
echo "</form>";
|
||||||
|
}
|
||||||
|
if ($db_source == 'S')
|
||||||
|
{
|
||||||
|
mysqli_close($link);
|
||||||
|
$use_slave_server=0;
|
||||||
|
$db_source = 'M';
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
$endMS = microtime();
|
||||||
|
$startMSary = explode(" ",$startMS);
|
||||||
|
$endMSary = explode(" ",$endMS);
|
||||||
|
$runS = ($endMSary[0] - $startMSary[0]);
|
||||||
|
$runM = ($endMSary[1] - $startMSary[1]);
|
||||||
|
$TOTALrun = ($runS + $runM);
|
||||||
|
|
||||||
|
# $stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';";
|
||||||
|
if ($DB) {echo "|$stmt|\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
</TD></TR></TABLE>
|
||||||
|
</FORM>
|
||||||
|
</BODY>
|
||||||
|
<script language="Javascript">
|
||||||
|
/*
|
||||||
|
|
||||||
|
$('vicidial_queue_groups').on('click', function() {
|
||||||
|
$(this).val('');
|
||||||
|
});
|
||||||
|
$('vicidial_queue_groups').on('mouseleave', function() {
|
||||||
|
if ($(this).val() == '') {
|
||||||
|
$(this).val('apple');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$('vicidial_queue_groups').click(function() {
|
||||||
|
$('vicidial_queue_groups').click();
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
</script>
|
||||||
|
</HTML>
|
||||||
@@ -0,0 +1,380 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_custom_form_functions.php - Vicidial Enhanced Reporting Javascript functions
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1607 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
require("../vicidial/dbconnect_mysqli.php");
|
||||||
|
require("../vicidial/functions.php");
|
||||||
|
|
||||||
|
require("VERM_options.php");
|
||||||
|
?>
|
||||||
|
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='';
|
||||||
|
if (document.getElementById("page_no")) {document.getElementById("page_no").value=0;} // Reset for the one occurrence when navigating between UN/ANSWERED DT
|
||||||
|
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, page_no_field)
|
||||||
|
{
|
||||||
|
// alert(document.getElementById("report_type").value);
|
||||||
|
if (!page_no_field) {var page_no_field="page_no";}
|
||||||
|
|
||||||
|
document.getElementById("report_type").value=selected_report;
|
||||||
|
document.getElementById(page_no_field).value=page_no;
|
||||||
|
if (selected_report=="ANSWERED_DT") {document.forms[0].action+='#sad_anchor';}
|
||||||
|
if (selected_report=="UNANSWERED_DT") {document.forms[0].action+='#sud_anchor';}
|
||||||
|
document.forms[0].submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
function GoToCustomReport(realtime_override)
|
||||||
|
{
|
||||||
|
|
||||||
|
var full_report_var_str="log_custom_report=1";
|
||||||
|
var custom_report_vars="";
|
||||||
|
|
||||||
|
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;
|
||||||
|
custom_report_vars+="|vicidial_queue_groups="+report_queues_value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vicidial_queue_groups="<?php echo $VERM_default_report_queue; ?>";
|
||||||
|
full_report_var_str+="&vicidial_queue_groups="+vicidial_queue_groups;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|report_types="+report_types_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
custom_report_vars+="|time_period="+time_period_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var start_date=document.getElementById('start_date').value;
|
||||||
|
if (start_date!="")
|
||||||
|
{
|
||||||
|
full_report_var_str+="&start_date="+start_date;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|users="+users_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var teams_value=$( "input[type=text][id=teams]" ).val();
|
||||||
|
if (teams_value!="")
|
||||||
|
{
|
||||||
|
var teams=$('#team_filter_list [value="' + teams_value + '"]').data('value');
|
||||||
|
full_report_var_str+="&teams="+teams;
|
||||||
|
custom_report_vars+="|teams="+teams_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
custom_report_vars+="|location="+dialer_location_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
custom_report_vars+="|user_group="+user_group_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
custom_report_vars+="|statuses="+statuses_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var asterisk_cid=document.getElementById('asterisk_cid').value;
|
||||||
|
if (asterisk_cid!="")
|
||||||
|
{
|
||||||
|
full_report_var_str+="&asterisk_cid="+asterisk_cid;
|
||||||
|
custom_report_vars+="|asterisk_cid="+asterisk_cid;
|
||||||
|
}
|
||||||
|
|
||||||
|
var phone_number=document.getElementById('phone_number').value;
|
||||||
|
if (phone_number!="")
|
||||||
|
{
|
||||||
|
full_report_var_str+="&phone_number="+phone_number;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|disconnection_cause="+disconnection_cause_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var queue_position_min=document.getElementById('queue_position_min').value;
|
||||||
|
if (queue_position_min!="")
|
||||||
|
{
|
||||||
|
full_report_var_str+="&queue_position_min="+queue_position_min;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|did="+did_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ivr_choice=document.getElementById('ivr_choice').value;
|
||||||
|
if (ivr_choice!="")
|
||||||
|
{
|
||||||
|
full_report_var_str+="&ivr_choice="+ivr_choice;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|server="+server_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
custom_report_vars+="|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;
|
||||||
|
custom_report_vars+="|time_of_day_start="+time_of_day_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
var time_of_day_end=document.getElementById('time_of_day_end').value;
|
||||||
|
if (time_of_day_end!="")
|
||||||
|
{
|
||||||
|
full_report_var_str+="&time_of_day_end="+time_of_day_end;
|
||||||
|
custom_report_vars+="|time_of_day_end="+time_of_day_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// alert(full_report_var_str);
|
||||||
|
|
||||||
|
var encoded_report_vars=encodeURIComponent(custom_report_vars.substring(1));
|
||||||
|
|
||||||
|
custom_report_vars="function=log_custom_report&custom_report_vars="+encoded_report_vars;
|
||||||
|
|
||||||
|
var xmlhttp=false;
|
||||||
|
/*@cc_on @*/
|
||||||
|
/*@if (@_jscript_version >= 5)
|
||||||
|
// JScript gives us Conditional compilation, we can cope with old IE versions.
|
||||||
|
// and security blocked creation of the objects.
|
||||||
|
try {
|
||||||
|
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
|
||||||
|
} catch (e) {
|
||||||
|
try {
|
||||||
|
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
|
||||||
|
} catch (E) {
|
||||||
|
xmlhttp = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@end @*/
|
||||||
|
if (!xmlhttp && typeof XMLHttpRequest!='undefined')
|
||||||
|
{
|
||||||
|
xmlhttp = new XMLHttpRequest();
|
||||||
|
}
|
||||||
|
if (xmlhttp)
|
||||||
|
{
|
||||||
|
xmlhttp.open('POST', 'VERM_AJAX_functions.php');
|
||||||
|
xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
|
||||||
|
xmlhttp.send(custom_report_vars);
|
||||||
|
xmlhttp.onreadystatechange = function()
|
||||||
|
{
|
||||||
|
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
|
||||||
|
{
|
||||||
|
var update_rslt = xmlhttp.responseText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete xmlhttp;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.location.href=document.forms[0].action+"?"+full_report_var_str;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,267 @@
|
|||||||
|
// LINK BUTTON FUNCTION
|
||||||
|
function GenerateLink(e) {
|
||||||
|
document.getElementById("DisplayLinkDiv").innerHTML="";
|
||||||
|
|
||||||
|
var form_elements = document.forms[0].elements;
|
||||||
|
var link_str=window.location.href+"?";
|
||||||
|
for (i=0; i<form_elements.length; i++) {
|
||||||
|
if (form_elements[i].type!="button" && form_elements[i].type!="submit" && form_elements[i].value!="")
|
||||||
|
{
|
||||||
|
link_str+=form_elements[i].name+"="+encodeURIComponent(form_elements[i].value)+"&";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
link_str = link_str.substring(0, link_str.length - 1);
|
||||||
|
|
||||||
|
var LinkText="<table style='width:25vw' id='details_table' align='center' valign='middle'>";
|
||||||
|
LinkText+="<tr><td align='right' class='export_row_cell'><a onClick='javascript:document.getElementById(\"DisplayLinkDiv\").style.display=\"none\"'><h2 class='rpt_header'>[X]</h2></a></td></tr>";
|
||||||
|
LinkText+="<tr class='export_row'><td align='left' class='export_row_cell'><B>Link to this page:</B><BR><BR>";
|
||||||
|
// LinkText+="<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
LinkText+="<a href='"+link_str+"'>Right click and select 'Copy link address'</a>";
|
||||||
|
LinkText+="</td></tr>";
|
||||||
|
LinkText+="</table>";
|
||||||
|
|
||||||
|
document.getElementById("DisplayLinkDiv").innerHTML=LinkText;
|
||||||
|
|
||||||
|
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("DisplayLinkDiv").style.display="block";
|
||||||
|
document.getElementById("DisplayLinkDiv").style.left = "35vw";
|
||||||
|
document.getElementById("DisplayLinkDiv").style.top = "35vh";
|
||||||
|
document.getElementById("DisplayLinkDiv").style.width = "30vw";
|
||||||
|
document.getElementById("DisplayLinkDiv").style.height = "30vh";
|
||||||
|
}
|
||||||
|
|
||||||
|
// CALL DETAILS FUNCTIONS
|
||||||
|
function HideCallDetails() {
|
||||||
|
document.getElementById("CallDetailsDiv").innerHTML="";
|
||||||
|
document.getElementById("CallDetailsDiv").style.display="none";
|
||||||
|
}
|
||||||
|
function ShowCallDetails(detail_id, call_type, width_override, height_override) {
|
||||||
|
document.getElementById("CallDetailsDiv").style.display="block";
|
||||||
|
document.getElementById("AgentDetailsDiv").style.left = "5vw";
|
||||||
|
document.getElementById("AgentDetailsDiv").style.top = "5vh";
|
||||||
|
document.getElementById("AgentDetailsDiv").style.width = "90vw";
|
||||||
|
document.getElementById("AgentDetailsDiv").style.height = "80vh";
|
||||||
|
|
||||||
|
var helptext_query="";
|
||||||
|
if (width_override)
|
||||||
|
{
|
||||||
|
var new_width=parseInt(width_override);
|
||||||
|
left_override=Math.round((100-new_width)/2);
|
||||||
|
document.getElementById("CallDetailsDiv").style.width = new_width+"vw";
|
||||||
|
document.getElementById("CallDetailsDiv").style.left = left_override+"vw";
|
||||||
|
}
|
||||||
|
if (height_override)
|
||||||
|
{
|
||||||
|
var new_height=parseInt(height_override);
|
||||||
|
top_override=Math.round((100-new_height)/2);
|
||||||
|
document.getElementById("CallDetailsDiv").style.height = new_height+"vh";
|
||||||
|
document.getElementById("CallDetailsDiv").style.top = top_override+"vh";
|
||||||
|
helptext_query+="&detail_span_height="+new_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
var CallDetails = null;
|
||||||
|
|
||||||
|
var xmlhttp=false;
|
||||||
|
/*@cc_on @*/
|
||||||
|
/*@if (@_jscript_version >= 5)
|
||||||
|
// JScript gives us Conditional compilation, we can cope with old IE versions.
|
||||||
|
// and security blocked creation of the objects.
|
||||||
|
try {
|
||||||
|
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
|
||||||
|
} catch (e) {
|
||||||
|
try {
|
||||||
|
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
|
||||||
|
} catch (E) {
|
||||||
|
xmlhttp = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@end @*/
|
||||||
|
if (!xmlhttp && typeof XMLHttpRequest!='undefined')
|
||||||
|
{
|
||||||
|
xmlhttp = new XMLHttpRequest();
|
||||||
|
}
|
||||||
|
if (xmlhttp)
|
||||||
|
{
|
||||||
|
helptext_query += "&detail_id=" + detail_id + "&call_type=" + call_type;
|
||||||
|
xmlhttp.open('POST', 'display_call_details.php');
|
||||||
|
xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
|
||||||
|
xmlhttp.send(helptext_query);
|
||||||
|
xmlhttp.onreadystatechange = function()
|
||||||
|
{
|
||||||
|
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
|
||||||
|
{
|
||||||
|
CallDetails = xmlhttp.responseText;
|
||||||
|
document.getElementById("CallDetailsDiv").innerHTML=CallDetails;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete xmlhttp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AGENT DETAILS FUNCTIONS
|
||||||
|
function HideAgentDetails() {
|
||||||
|
document.getElementById("AgentDetailsDiv").innerHTML="";
|
||||||
|
document.getElementById("AgentDetailsDiv").style.display="none";
|
||||||
|
}
|
||||||
|
function ShowAgentDetails(user, start_datetime, end_datetime, total_duration_His, total_pause_His, total_all_billable_His, total_billable_His) {
|
||||||
|
document.getElementById("AgentDetailsDiv").style.display="block";
|
||||||
|
document.getElementById("AgentDetailsDiv").style.left = "5vw";
|
||||||
|
document.getElementById("AgentDetailsDiv").style.top = "5vh";
|
||||||
|
document.getElementById("AgentDetailsDiv").style.width = "90vw";
|
||||||
|
document.getElementById("AgentDetailsDiv").style.height = "80vh";
|
||||||
|
|
||||||
|
var form_elements = document.forms[0].elements;
|
||||||
|
var agent_request_query="user="+user+"&start_datetime="+start_datetime+"&end_datetime="+end_datetime+"&total_duration_His="+total_duration_His+"&total_pause_His="+total_pause_His+"&total_all_billable_His="+total_all_billable_His+"&total_billable_His="+total_billable_His;
|
||||||
|
|
||||||
|
for (i=0; i<form_elements.length; i++)
|
||||||
|
{
|
||||||
|
if (form_elements[i].type!="button" && form_elements[i].type!="submit" && form_elements[i].value!="")
|
||||||
|
{
|
||||||
|
agent_request_query+="&"+form_elements[i].name+"="+encodeURIComponent(form_elements[i].value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var xmlhttp=false;
|
||||||
|
/*@cc_on @*/
|
||||||
|
/*@if (@_jscript_version >= 5)
|
||||||
|
// JScript gives us Conditional compilation, we can cope with old IE versions.
|
||||||
|
// and security blocked creation of the objects.
|
||||||
|
try {
|
||||||
|
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
|
||||||
|
} catch (e) {
|
||||||
|
try {
|
||||||
|
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
|
||||||
|
} catch (E) {
|
||||||
|
xmlhttp = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@end @*/
|
||||||
|
if (!xmlhttp && typeof XMLHttpRequest!='undefined')
|
||||||
|
{
|
||||||
|
xmlhttp = new XMLHttpRequest();
|
||||||
|
}
|
||||||
|
if (xmlhttp)
|
||||||
|
{
|
||||||
|
xmlhttp.open('POST', 'display_agent_details.php');
|
||||||
|
xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
|
||||||
|
xmlhttp.send(agent_request_query);
|
||||||
|
xmlhttp.onreadystatechange = function()
|
||||||
|
{
|
||||||
|
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
|
||||||
|
{
|
||||||
|
AgentDetails = xmlhttp.responseText;
|
||||||
|
document.getElementById("AgentDetailsDiv").innerHTML=AgentDetails;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete xmlhttp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// OUTCOMES DETAILS FUNCTIONS
|
||||||
|
function HideOutcomesDetails() {
|
||||||
|
document.getElementById("OutcomesDetailsDiv").innerHTML="";
|
||||||
|
document.getElementById("OutcomesDetailsDiv").style.display="none";
|
||||||
|
}
|
||||||
|
function ShowOutcomesDetails(dispo, start_datetime, end_datetime, user, campaign_id, status_name, teams) {
|
||||||
|
document.getElementById("OutcomesDetailsDiv").style.display="block";
|
||||||
|
document.getElementById("OutcomesDetailsDiv").style.left = "5vw";
|
||||||
|
document.getElementById("OutcomesDetailsDiv").style.top = "5vh";
|
||||||
|
document.getElementById("OutcomesDetailsDiv").style.width = "90vw";
|
||||||
|
document.getElementById("OutcomesDetailsDiv").style.height = "80vh";
|
||||||
|
|
||||||
|
var vicidial_queue_groups=document.getElementById("vicidial_queue_groups").value;
|
||||||
|
var users=document.getElementById("users").value;
|
||||||
|
|
||||||
|
outcome_query = "&start_datetime=" + start_datetime + "&end_datetime=" + end_datetime + "&vicidial_queue_groups=" + vicidial_queue_groups;
|
||||||
|
if (users && users!="")
|
||||||
|
{
|
||||||
|
outcome_query += "&users=" + users;
|
||||||
|
}
|
||||||
|
if (teams && teams!="")
|
||||||
|
{
|
||||||
|
outcome_query += "&teams=" + teams;
|
||||||
|
}
|
||||||
|
if (dispo)
|
||||||
|
{
|
||||||
|
outcome_query += "&status=" + dispo;
|
||||||
|
}
|
||||||
|
if (user)
|
||||||
|
{
|
||||||
|
outcome_query += "&user=" + user;
|
||||||
|
}
|
||||||
|
if (campaign_id)
|
||||||
|
{
|
||||||
|
outcome_query += "&campaign_id=" + campaign_id;
|
||||||
|
}
|
||||||
|
if (status_name) // From OUTCOMES page
|
||||||
|
{
|
||||||
|
outcome_query += "&status_name=" + status_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// alert(outcome_query);
|
||||||
|
|
||||||
|
var OutcomesDetails = null;
|
||||||
|
|
||||||
|
var xmlhttp=false;
|
||||||
|
/*@cc_on @*/
|
||||||
|
/*@if (@_jscript_version >= 5)
|
||||||
|
// JScript gives us Conditional compilation, we can cope with old IE versions.
|
||||||
|
// and security blocked creation of the objects.
|
||||||
|
try {
|
||||||
|
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
|
||||||
|
} catch (e) {
|
||||||
|
try {
|
||||||
|
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
|
||||||
|
} catch (E) {
|
||||||
|
xmlhttp = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@end @*/
|
||||||
|
if (!xmlhttp && typeof XMLHttpRequest!='undefined')
|
||||||
|
{
|
||||||
|
xmlhttp = new XMLHttpRequest();
|
||||||
|
}
|
||||||
|
if (xmlhttp)
|
||||||
|
{
|
||||||
|
xmlhttp.open('POST', 'display_outcomes_details.php');
|
||||||
|
xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
|
||||||
|
xmlhttp.send(outcome_query);
|
||||||
|
xmlhttp.onreadystatechange = function()
|
||||||
|
{
|
||||||
|
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
|
||||||
|
{
|
||||||
|
OutcomesDetails = xmlhttp.responseText;
|
||||||
|
document.getElementById("OutcomesDetailsDiv").innerHTML=OutcomesDetails;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete xmlhttp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BASIC SPAN VISIBILITY HANDLER FUNCTION
|
||||||
|
function ToggleVisibility(span_name, display_type) {
|
||||||
|
var span_vis = document.getElementById(span_name).style;
|
||||||
|
if (!display_type)
|
||||||
|
{
|
||||||
|
if (span_vis.display=='none') { span_vis.display = 'block'; } else { span_vis.display = 'none'; }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
span_vis.display = display_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,461 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_global_vars.inc - Vicidial Enhanced Reporting global variables
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1622 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
if (isset($_GET["start_date"])) {$start_date=$_GET["start_date"];}
|
||||||
|
elseif (isset($_POST["start_date"])) {$start_date=$_POST["start_date"];}
|
||||||
|
if (isset($_GET["start_time"])) {$start_time=$_GET["start_time"];}
|
||||||
|
elseif (isset($_POST["start_time"])) {$start_time=$_POST["start_time"];}
|
||||||
|
if (isset($_GET["end_date"])) {$end_date=$_GET["end_date"];}
|
||||||
|
elseif (isset($_POST["end_date"])) {$end_date=$_POST["end_date"];}
|
||||||
|
if (isset($_GET["end_time"])) {$end_time=$_GET["end_time"];}
|
||||||
|
elseif (isset($_POST["end_time"])) {$end_time=$_POST["end_time"];}
|
||||||
|
if (isset($_GET["campaigns"])) {$campaigns=$_GET["campaigns"];}
|
||||||
|
elseif (isset($_POST["campaigns"])) {$campaigns=$_POST["campaigns"];}
|
||||||
|
if (isset($_GET["ingroups"])) {$ingroups=$_GET["ingroups"];}
|
||||||
|
elseif (isset($_POST["ingroups"])) {$ingroups=$_POST["ingroups"];}
|
||||||
|
if (isset($_GET["did"])) {$did=$_GET["did"];}
|
||||||
|
elseif (isset($_POST["did"])) {$did=$_POST["did"];}
|
||||||
|
if (isset($_GET["users"])) {$users=$_GET["users"];}
|
||||||
|
elseif (isset($_POST["users"])) {$users=$_POST["users"];}
|
||||||
|
if (isset($_GET["user_groups"])) {$user_groups=$_GET["user_groups"];}
|
||||||
|
elseif (isset($_POST["user_groups"])) {$user_groups=$_POST["user_groups"];}
|
||||||
|
if (isset($_GET["outcomes"])) {$outcomes=$_GET["outcomes"];}
|
||||||
|
elseif (isset($_POST["outcomes"])) {$outcomes=$_POST["outcomes"];}
|
||||||
|
|
||||||
|
$report_name="VICIdial Enhanced Reporting Module";
|
||||||
|
|
||||||
|
$start_date=preg_replace('/[^-0-9]/', '', $start_date);
|
||||||
|
$start_time=preg_replace('/[^:0-9]/', '', $start_time);
|
||||||
|
$end_date=preg_replace('/[^-0-9]/', '', $end_date);
|
||||||
|
$end_time=preg_replace('/[^:0-9]/', '', $end_time);
|
||||||
|
$did = preg_replace('/[^0-9]/','',$did);
|
||||||
|
|
||||||
|
if ($non_latin < 1)
|
||||||
|
{
|
||||||
|
$campaigns = preg_replace('/[^-_0-9a-zA-Z]/','',$campaigns);
|
||||||
|
$ingroups = preg_replace('/[^-_0-9a-zA-Z]/','',$ingroups);
|
||||||
|
$users = preg_replace('/[^-_0-9a-zA-Z]/','',$users);
|
||||||
|
$user_groups = preg_replace('/[^-_0-9a-zA-Z]/','',$user_groups);
|
||||||
|
$outcomes = preg_replace('/[^\s\-_0-9a-zA-Z]/','',$outcomes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$campaigns = preg_replace('/[^-_0-9\p{L}]/u','',$campaigns);
|
||||||
|
$ingroups = preg_replace('/[^-_0-9\p{L}]/u','',$ingroups);
|
||||||
|
$users = preg_replace('/[^-_0-9\p{L}]/u','',$users);
|
||||||
|
$user_groups = preg_replace('/[^-_0-9\p{L}]/u','',$user_groups);
|
||||||
|
$outcomes = preg_replace('/[^\s\-_0-9\p{L}]/u','',$outcomes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#### User account filtering ####
|
||||||
|
|
||||||
|
## ACCESS CONTROLLED BY USER GROUPS ##
|
||||||
|
$stmt="SELECT user_id,user,pass,full_name,user_level,user_group,phone_login,phone_pass,delete_users,delete_user_groups,delete_lists,delete_campaigns,delete_ingroups,delete_remote_agents,load_leads,campaign_detail,ast_admin_access,ast_delete_phones,delete_scripts,modify_leads,hotkeys_active,change_agent_campaign,agent_choose_ingroups,closer_campaigns,scheduled_callbacks,agentonly_callbacks,agentcall_manual,vicidial_recording,vicidial_transfers,delete_filters,alter_agent_interface_options,closer_default_blended,delete_call_times,modify_call_times,modify_users,modify_campaigns,modify_lists,modify_scripts,modify_filters,modify_ingroups,modify_usergroups,modify_remoteagents,modify_servers,view_reports,vicidial_recording_override,alter_custdata_override,qc_enabled,qc_user_level,qc_pass,qc_finish,qc_commit,add_timeclock_log,modify_timeclock_log,delete_timeclock_log,alter_custphone_override,vdc_agent_api_access,modify_inbound_dids,delete_inbound_dids,active,alert_enabled,download_lists,agent_shift_enforcement_override,manager_shift_enforcement_override,shift_override_flag,export_reports,delete_from_dnc,email,user_code,territory,allow_alerts,callcard_admin,force_change_password,modify_shifts,modify_phones,modify_carriers,modify_labels,modify_statuses,modify_voicemail,modify_audiostore,modify_moh,modify_tts,modify_contacts,modify_same_user_level,alter_admin_interface_options,modify_custom_dialplans,modify_languages,selected_language,user_choose_language,modify_colors,api_only_user,modify_auto_reports,modify_ip_lists,export_gdpr_leads,mobile_number,two_factor_override from vicidial_users where user='$PHP_AUTH_USER';";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$LOGfull_name =$row[3];
|
||||||
|
$LOGuser_level =$row[4];
|
||||||
|
$LOGuser_group =$row[5];
|
||||||
|
$LOGdelete_users =$row[8];
|
||||||
|
$LOGdelete_user_groups =$row[9];
|
||||||
|
$LOGdelete_lists =$row[10];
|
||||||
|
$LOGdelete_campaigns =$row[11];
|
||||||
|
$LOGdelete_ingroups =$row[12];
|
||||||
|
$LOGdelete_remote_agents =$row[13];
|
||||||
|
$LOGload_leads =$row[14];
|
||||||
|
$LOGcampaign_detail =$row[15];
|
||||||
|
$LOGast_admin_access =$row[16];
|
||||||
|
$LOGast_delete_phones =$row[17];
|
||||||
|
$LOGdelete_scripts =$row[18];
|
||||||
|
$LOGmodify_leads =$row[19];
|
||||||
|
$LOGdelete_filters =$row[29];
|
||||||
|
$LOGalter_agent_interface =$row[30];
|
||||||
|
$LOGdelete_call_times =$row[32];
|
||||||
|
$LOGmodify_call_times =$row[33];
|
||||||
|
$LOGmodify_users =$row[34];
|
||||||
|
$LOGmodify_campaigns =$row[35];
|
||||||
|
$LOGmodify_lists =$row[36];
|
||||||
|
$LOGmodify_scripts =$row[37];
|
||||||
|
$LOGmodify_filters =$row[38];
|
||||||
|
$LOGmodify_ingroups =$row[39];
|
||||||
|
$LOGmodify_usergroups =$row[40];
|
||||||
|
$LOGmodify_remoteagents =$row[41];
|
||||||
|
$LOGmodify_servers =$row[42];
|
||||||
|
$LOGview_reports =$row[43];
|
||||||
|
$LOGmodify_dids =$row[56];
|
||||||
|
$LOGdelete_dids =$row[57];
|
||||||
|
$LOGmanager_shift_enforcement_override=$row[61];
|
||||||
|
$LOGexport_reports =$row[64];
|
||||||
|
$LOGdelete_from_dnc =$row[65];
|
||||||
|
$LOGemail =$row[66];
|
||||||
|
$LOGcallcard_admin =$row[70];
|
||||||
|
$LOGforce_change_password =$row[71];
|
||||||
|
$LOGmodify_shifts =$row[72];
|
||||||
|
$LOGmodify_phones =$row[73];
|
||||||
|
$LOGmodify_carriers =$row[74];
|
||||||
|
$LOGmodify_labels =$row[75];
|
||||||
|
$LOGmodify_statuses =$row[76];
|
||||||
|
$LOGmodify_voicemail =$row[77];
|
||||||
|
$LOGmodify_audiostore =$row[78];
|
||||||
|
$LOGmodify_moh =$row[79];
|
||||||
|
$LOGmodify_tts =$row[80];
|
||||||
|
$LOGmodify_contacts =$row[81];
|
||||||
|
$LOGmodify_same_user_level =$row[82];
|
||||||
|
$LOGalter_admin_interface =$row[83];
|
||||||
|
$LOGmodify_custom_dialplans =$row[84];
|
||||||
|
$LOGmodify_languages =$row[85];
|
||||||
|
$LOGselected_language =$row[86];
|
||||||
|
$LOGuser_choose_language =$row[87];
|
||||||
|
$LOGmodify_colors =$row[88];
|
||||||
|
$LOGapi_only_user =$row[89];
|
||||||
|
$LOGmodify_auto_reports =$row[90];
|
||||||
|
$LOGmodify_ip_lists =$row[91];
|
||||||
|
$LOGexport_gdpr_leads =$row[92];
|
||||||
|
$LOGmobile_number =$row[93];
|
||||||
|
$LOGtwo_factor_override =$row[94];
|
||||||
|
|
||||||
|
$stmt="SELECT allowed_campaigns,allowed_reports,admin_viewable_groups,admin_viewable_call_times,qc_allowed_campaigns,qc_allowed_inbound_groups from vicidial_user_groups where user_group='$LOGuser_group';";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$LOGallowed_campaigns = $row[0];
|
||||||
|
$LOGallowed_reports = $row[1];
|
||||||
|
$LOGadmin_viewable_groups = $row[2];
|
||||||
|
$LOGadmin_viewable_call_times = $row[3];
|
||||||
|
$LOGqc_allowed_campaigns = $row[4];
|
||||||
|
$LOGqc_allowed_inbound_groups = $row[5];
|
||||||
|
|
||||||
|
$LOGallowed_campaignsSQL='';
|
||||||
|
$notLOGallowed_campaignsSQL = "and campaign_id IN('')";
|
||||||
|
$campLOGallowed_campaignsSQL='';
|
||||||
|
$whereLOGallowed_campaignsSQL='';
|
||||||
|
if ( (!preg_match('/\-ALL/i', $LOGallowed_campaigns)) )
|
||||||
|
{
|
||||||
|
$rawLOGallowed_campaignsSQL = preg_replace("/ -/",'',$LOGallowed_campaigns);
|
||||||
|
$rawLOGallowed_campaignsSQL = preg_replace("/ /","','",$rawLOGallowed_campaignsSQL);
|
||||||
|
$LOGallowed_campaignsSQL = "and campaign_id IN('$rawLOGallowed_campaignsSQL')";
|
||||||
|
$notLOGallowed_campaignsSQL = "and campaign_id NOT IN('$rawLOGallowed_campaignsSQL')";
|
||||||
|
$campLOGallowed_campaignsSQL = "and camp.campaign_id IN('$rawLOGallowed_campaignsSQL')";
|
||||||
|
$whereLOGallowed_campaignsSQL = "where campaign_id IN('$rawLOGallowed_campaignsSQL')";
|
||||||
|
}
|
||||||
|
$regexLOGallowed_campaigns = " $LOGallowed_campaigns ";
|
||||||
|
|
||||||
|
if (preg_match("/DRA/",$SShosted_settings))
|
||||||
|
{$LOGmodify_remoteagents=0;}
|
||||||
|
|
||||||
|
$admin_viewable_groupsALL=0;
|
||||||
|
$LOGadmin_viewable_groupsSQL='';
|
||||||
|
$whereLOGadmin_viewable_groupsSQL='';
|
||||||
|
$valLOGadmin_viewable_groupsSQL='';
|
||||||
|
$vmLOGadmin_viewable_groupsSQL='';
|
||||||
|
if ( (!preg_match('/\-\-ALL\-\-/i',$LOGadmin_viewable_groups)) and (strlen($LOGadmin_viewable_groups) > 3) )
|
||||||
|
{
|
||||||
|
$rawLOGadmin_viewable_groupsSQL = preg_replace("/ -/",'',$LOGadmin_viewable_groups);
|
||||||
|
$rawLOGadmin_viewable_groupsSQL = preg_replace("/ /","','",$rawLOGadmin_viewable_groupsSQL);
|
||||||
|
$LOGadmin_viewable_groupsSQL = "and user_group IN('---ALL---','$rawLOGadmin_viewable_groupsSQL')";
|
||||||
|
$whereLOGadmin_viewable_groupsSQL = "where user_group IN('---ALL---','$rawLOGadmin_viewable_groupsSQL')";
|
||||||
|
$valLOGadmin_viewable_groupsSQL = "and val.user_group IN('---ALL---','$rawLOGadmin_viewable_groupsSQL')";
|
||||||
|
$vmLOGadmin_viewable_groupsSQL = "and vm.user_group IN('---ALL---','$rawLOGadmin_viewable_groupsSQL')";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{$admin_viewable_groupsALL=1;}
|
||||||
|
$regexLOGadmin_viewable_groups = " $LOGadmin_viewable_groups ";
|
||||||
|
|
||||||
|
$LOGadmin_viewable_call_timesSQL='';
|
||||||
|
$whereLOGadmin_viewable_call_timesSQL='';
|
||||||
|
if ( (!preg_match('/\-\-ALL\-\-/i', $LOGadmin_viewable_call_times)) and (strlen($LOGadmin_viewable_call_times) > 3) )
|
||||||
|
{
|
||||||
|
$rawLOGadmin_viewable_call_timesSQL = preg_replace("/ -/",'',$LOGadmin_viewable_call_times);
|
||||||
|
$rawLOGadmin_viewable_call_timesSQL = preg_replace("/ /","','",$rawLOGadmin_viewable_call_timesSQL);
|
||||||
|
$LOGadmin_viewable_call_timesSQL = "and call_time_id IN('---ALL---','$rawLOGadmin_viewable_call_timesSQL')";
|
||||||
|
$whereLOGadmin_viewable_call_timesSQL = "where call_time_id IN('---ALL---','$rawLOGadmin_viewable_call_timesSQL')";
|
||||||
|
}
|
||||||
|
$regexLOGadmin_viewable_call_times = " $LOGadmin_viewable_call_times ";
|
||||||
|
|
||||||
|
$UUgroups_list='';
|
||||||
|
if ($admin_viewable_groupsALL > 0)
|
||||||
|
{$UUgroups_list .= "<option value=\"---ALL---\">"._QXZ("All Admin User Groups")."</option>\n";}
|
||||||
|
$stmt="SELECT user_group,group_name from vicidial_user_groups $whereLOGadmin_viewable_groupsSQL order by user_group;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$UUgroups_to_print = mysqli_num_rows($rslt);
|
||||||
|
$o=0;
|
||||||
|
while ($UUgroups_to_print > $o)
|
||||||
|
{
|
||||||
|
$rowx=mysqli_fetch_row($rslt);
|
||||||
|
$UUgroups_list .= "<option value=\"$rowx[0]\">$rowx[0] - $rowx[1]</option>\n";
|
||||||
|
$o++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$LOGqc_allowed_campaignsSQL='';
|
||||||
|
$whereLOGqc_allowed_campaignsSQL='';
|
||||||
|
if ( (!preg_match('/\-ALL/i', $LOGqc_allowed_campaigns)) )
|
||||||
|
{
|
||||||
|
$rawLOGqc_allowed_campaignsSQL = preg_replace("/ -/",'',$LOGqc_allowed_campaigns);
|
||||||
|
$rawLOGqc_allowed_campaignsSQL = preg_replace("/ /","','",$rawLOGqc_allowed_campaignsSQL);
|
||||||
|
$LOGqc_allowed_campaignsSQL = "and campaign_id IN('$rawLOGqc_allowed_campaignsSQL')";
|
||||||
|
$whereLOGqc_allowed_campaignsSQL = "where campaign_id IN('$rawLOGqc_allowed_campaignsSQL')";
|
||||||
|
}
|
||||||
|
|
||||||
|
$LOGqc_allowed_inbound_groupsSQL='';
|
||||||
|
$whereLOGqc_allowed_inbound_groupsSQL='';
|
||||||
|
if ( (!preg_match('/\-ALL/i', $LOGqc_allowed_inbound_groups)) )
|
||||||
|
{
|
||||||
|
$rawLOGqc_allowed_inbound_groupsSQL = preg_replace("/ -/",'',$LOGqc_allowed_inbound_groups);
|
||||||
|
$rawLOGqc_allowed_inbound_groupsSQL = preg_replace("/ /","','",$rawLOGqc_allowed_inbound_groupsSQL);
|
||||||
|
$LOGqc_allowed_inbound_groupsSQL = "and group_id IN('$rawLOGqc_allowed_inbound_groupsSQL')";
|
||||||
|
$whereLOGqc_allowed_inbound_groupsSQL = "where group_id IN('$rawLOGqc_allowed_inbound_groupsSQL')";
|
||||||
|
}
|
||||||
|
|
||||||
|
################################
|
||||||
|
|
||||||
|
|
||||||
|
### Full information assembly - needed for display #################
|
||||||
|
$did_stmt="select did_id, did_pattern, did_description from vicidial_inbound_dids";
|
||||||
|
$did_rslt=mysql_to_mysqli($did_stmt, $link);
|
||||||
|
while ($did_row=mysqli_fetch_array($did_rslt))
|
||||||
|
{
|
||||||
|
$did_id_info["$did_row[0]"]=$did_row[2];
|
||||||
|
$did_pattern_info["$did_row[1]"]=$did_row[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
$user_stmt="select user, full_name, user_group from vicidial_users";
|
||||||
|
$user_rslt=mysql_to_mysqli($user_stmt, $link);
|
||||||
|
while ($user_row=mysqli_fetch_array($user_rslt))
|
||||||
|
{
|
||||||
|
$fullname_info["$user_row[0]"]=$user_row[1];
|
||||||
|
$users_group_info["$user_row[0]"]=$user_row[2];
|
||||||
|
}
|
||||||
|
$PHP_AUTH_USER_fullname=$fullname_info["$PHP_AUTH_USER"];
|
||||||
|
|
||||||
|
$ug_stmt="select user_group, group_name from vicidial_user_groups";
|
||||||
|
$ug_rslt=mysql_to_mysqli($ug_stmt, $link);
|
||||||
|
while($ug_row=mysqli_fetch_array($ug_rslt))
|
||||||
|
{
|
||||||
|
$usergroup_info["$ug_row[0]"]=$ug_row[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
# $queueSQL_where="where campaign_id in ('".implode("','", $report_queues)."')";
|
||||||
|
# $queueSQL_and="where campaign_id in ('".implode("','", $report_queues)."')";
|
||||||
|
|
||||||
|
# Compile queue names into an array for later
|
||||||
|
$queue_names=array();
|
||||||
|
$queue_stmt="select group_id, group_name from vicidial_inbound_groups UNION select campaign_id, campaign_name from vicidial_campaigns $queueSQL_where";
|
||||||
|
$queue_rslt=mysql_to_mysqli($queue_stmt, $link);
|
||||||
|
while ($queue_row=mysqli_fetch_row($queue_rslt))
|
||||||
|
{
|
||||||
|
$queue_names["$queue_row[0]"]="$queue_row[1]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Compile group names into an array for later
|
||||||
|
$ingroup_stmt="select group_id, group_name from vicidial_inbound_groups order by group_id asc";
|
||||||
|
$ingroup_rslt=mysql_to_mysqli($ingroup_stmt, $link);
|
||||||
|
while ($ingroup_row=mysqli_fetch_row($ingroup_rslt))
|
||||||
|
{
|
||||||
|
$ingroup_names["$ingroup_row[0]"]="$ingroup_row[1]";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Compile callmenu names into an array for later
|
||||||
|
$callmenu_stmt="select menu_id, menu_name from vicidial_call_menu order by menu_id asc";
|
||||||
|
$callmenu_rslt=mysql_to_mysqli($callmenu_stmt, $link);
|
||||||
|
while ($callmenu_row=mysqli_fetch_row($callmenu_rslt))
|
||||||
|
{
|
||||||
|
$callmenu_names["$callmenu_row[0]"]="$callmenu_row[1]";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Compile closer campaigns for waiting calls
|
||||||
|
$campaign_closer_names=array();
|
||||||
|
$campaign_closer_stmt="select campaign_id, closer_campaigns from vicidial_campaigns $queueSQL_where";
|
||||||
|
$campaign_closer_rslt=mysql_to_mysqli($campaign_closer_stmt, $link);
|
||||||
|
while ($campaign_closer_row=mysqli_fetch_row($campaign_closer_rslt))
|
||||||
|
{
|
||||||
|
$campaign_closer_names["$campaign_closer_row[0]"]="$campaign_closer_row[1]";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Compile closer campaigns for waiting calls
|
||||||
|
$status_names=array();
|
||||||
|
$status_stmt="select status, status_name from vicidial_statuses UNION select status, status_name from vicidial_campaign_statuses";
|
||||||
|
$status_rslt=mysql_to_mysqli($status_stmt, $link);
|
||||||
|
while ($status_row=mysqli_fetch_row($status_rslt))
|
||||||
|
{
|
||||||
|
$status_names["$status_row[0]"]="$status_row[1]";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Compile "terminal" names into an array for later
|
||||||
|
$terminal_names=array();
|
||||||
|
$terminal_stmt="select user, full_name from vicidial_users";
|
||||||
|
$terminal_rslt=mysql_to_mysqli($terminal_stmt, $link);
|
||||||
|
while ($terminal_row=mysqli_fetch_row($terminal_rslt))
|
||||||
|
{
|
||||||
|
$terminal_names["$terminal_row[0]"]="$terminal_row[1]";
|
||||||
|
}
|
||||||
|
|
||||||
|
$sale_array=array("SYSTEM" => array());
|
||||||
|
$sale_stmt="select distinct status, 'SYSTEM' as campaign_id from vicidial_statuses where sale='Y' UNION select distinct status, campaign_id from vicidial_campaign_statuses where sale='Y'";
|
||||||
|
$sale_rslt=mysql_to_mysqli($sale_stmt, $link);
|
||||||
|
while ($sale_row=mysqli_fetch_array($sale_rslt))
|
||||||
|
{
|
||||||
|
if (!array_key_exists("$sale_row[campaign_id]", $sale_array)) {$sale_array["$sale_row[campaign_id]"]=array();}
|
||||||
|
array_push($sale_array["$sale_row[campaign_id]"], $sale_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_rslt=mysql_to_mysqli($human_ans_stmt, $link);
|
||||||
|
while ($human_ans_row=mysqli_fetch_array($human_ans_rslt))
|
||||||
|
{
|
||||||
|
if (!array_key_exists("$human_ans_row[campaign_id]", $human_ans_array)) {$human_ans_array["$human_ans_row[campaign_id]"]=array();}
|
||||||
|
array_push($human_ans_array["$human_ans_row[campaign_id]"], $human_ans_row["status"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$contact_array=array("SYSTEM" => array());
|
||||||
|
$contact_stmt="select distinct status, 'SYSTEM' as campaign_id from vicidial_statuses where customer_contact='Y' UNION select distinct status, campaign_id from vicidial_campaign_statuses where customer_contact='Y'";
|
||||||
|
$contact_rslt=mysql_to_mysqli($contact_stmt, $link);
|
||||||
|
while ($contact_row=mysqli_fetch_array($contact_rslt))
|
||||||
|
{
|
||||||
|
if (!array_key_exists("$contact_row[campaign_id]", $contact_array)) {$contact_array["$contact_row[campaign_id]"]=array();}
|
||||||
|
array_push($contact_array["$contact_row[campaign_id]"], $contact_row["status"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
### OVERRIDE ANY AND ALL STATUS NAMES FROM SETTING CONTAINERS
|
||||||
|
$container_stmt="select * from vicidial_settings_containers where container_id='VERM_STATUS_NAMES_OVERRIDE'";
|
||||||
|
$container_rslt=mysql_to_mysqli($container_stmt, $link);
|
||||||
|
if (mysqli_num_rows($container_rslt)>0)
|
||||||
|
{
|
||||||
|
while($container_row=mysqli_fetch_array($container_rslt))
|
||||||
|
{
|
||||||
|
$container_entry=$container_row["container_entry"];
|
||||||
|
$container_array=explode("\n", $container_entry);
|
||||||
|
for ($i=0; $i<count($container_array); $i++)
|
||||||
|
{
|
||||||
|
# Assumed format of status|status_name
|
||||||
|
if (!preg_match('/^;/', $container_array[$i]))
|
||||||
|
{
|
||||||
|
$new_status=explode("|", $container_array[$i]);
|
||||||
|
if (strlen($new_status[0])>0)
|
||||||
|
{
|
||||||
|
$status_names["$new_status[0]"]="$new_status[1]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pause_code_stmt="select * from vicidial_pause_codes";
|
||||||
|
$pause_code_rslt=mysql_to_mysqli($pause_code_stmt, $link);
|
||||||
|
$billable_pause_codes=array();
|
||||||
|
$payable_pause_codes=array();
|
||||||
|
$pause_code_names=array();
|
||||||
|
while ($pause_code_row=mysqli_fetch_array($pause_code_rslt))
|
||||||
|
{
|
||||||
|
$pause_code_campaign_id=$pause_code_row["campaign_id"];
|
||||||
|
$pause_code=$pause_code_row["pause_code"];
|
||||||
|
$pause_code_name=$pause_code_row["pause_code_name"];
|
||||||
|
$billable=$pause_code_row["billable"];
|
||||||
|
$pause_name_key=$pause_code_campaign_id."-".$pause_code;
|
||||||
|
$pause_name_login=$pause_code_campaign_id."-LOGIN";
|
||||||
|
$pause_name_lagged=$pause_code_campaign_id."-LAGGED";
|
||||||
|
|
||||||
|
$pause_code_names["$pause_name_key"]=$pause_code_name;
|
||||||
|
$pause_code_names["$pause_name_login"]="Login";
|
||||||
|
$pause_code_names["$pause_name_lagged"]="Network Delay";
|
||||||
|
if (!$billable_pause_codes["$pause_code_campaign_id"])
|
||||||
|
{
|
||||||
|
$billable_pause_codes["$pause_code_campaign_id"]=array();
|
||||||
|
}
|
||||||
|
if (!$payable_pause_codes["$pause_code_campaign_id"])
|
||||||
|
{
|
||||||
|
$payable_pause_codes["$pause_code_campaign_id"]=array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($pause_code, $billable_pause_codes["$pause_code_campaign_id"]) && $billable=="YES")
|
||||||
|
{
|
||||||
|
array_push($billable_pause_codes["$pause_code_campaign_id"], $pause_code);
|
||||||
|
}
|
||||||
|
if (!in_array($pause_code, $payable_pause_codes["$pause_code_campaign_id"]))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$billable_pause_codes["SYSTEM"]=array();
|
||||||
|
array_push($billable_pause_codes["SYSTEM"], "-");
|
||||||
|
array_push($billable_pause_codes["SYSTEM"], "BLANK");
|
||||||
|
array_push($billable_pause_codes["SYSTEM"], "LOGIN");
|
||||||
|
array_push($billable_pause_codes["SYSTEM"], "LAGGED");
|
||||||
|
|
||||||
|
$payable_pause_codes["SYSTEM"]=array();
|
||||||
|
array_push($payable_pause_codes["SYSTEM"], "-");
|
||||||
|
array_push($payable_pause_codes["SYSTEM"], "BLANK");
|
||||||
|
array_push($payable_pause_codes["SYSTEM"], "LOGIN");
|
||||||
|
array_push($payable_pause_codes["SYSTEM"], "LAGGED");
|
||||||
|
|
||||||
|
#print_r($billable_pause_codes);
|
||||||
|
#print_r($payable_pause_codes);
|
||||||
|
#print_r($pause_code_names); die;
|
||||||
|
#####################################################
|
||||||
|
|
||||||
|
|
||||||
|
### SLA query assembly ###
|
||||||
|
if (!$SLA_initial_interval) {$SLA_initial_interval=5;}
|
||||||
|
|
||||||
|
if (!$SLA_initial_period) {$SLA_initial_period=20;}
|
||||||
|
if ($SLA_initial_period<$SLA_initial_interval) {$SLA_initial_period=$SLA_initial_interval;}
|
||||||
|
|
||||||
|
if (!$SLA_interval) {$SLA_interval=10;}
|
||||||
|
|
||||||
|
if (!$SLA_max_period) {$SLA_max_period=120;}
|
||||||
|
if ($SLA_max_period<$SLA_interval) {$SLA_max_period=$SLA_interval;}
|
||||||
|
|
||||||
|
$SLA_query=""; $SLA_column_names=array();
|
||||||
|
for($i=$SLA_initial_interval; $i<$SLA_initial_period; $i+=$SLA_initial_interval)
|
||||||
|
{
|
||||||
|
$SLA_query.="sum(if(queue_seconds<=".$i.", 1, 0)) as within_".$i.", ";
|
||||||
|
$SLA_column_names[]="< $i";
|
||||||
|
}
|
||||||
|
|
||||||
|
for($i=$SLA_initial_period; $i<=$SLA_max_period; $i+=$SLA_interval)
|
||||||
|
{
|
||||||
|
$SLA_query.="sum(if(queue_seconds<=".$i.", 1, 0)) as within_".$i.", ";
|
||||||
|
$SLA_column_names[]="< $i";
|
||||||
|
}
|
||||||
|
|
||||||
|
$SLA_query=preg_replace('/, $/', '', $SLA_query);
|
||||||
|
############################
|
||||||
|
|
||||||
|
|
||||||
|
### NANQUE CLAUSES - MIGHT RECOGNIZE NANQUE ###
|
||||||
|
# $and_NANQUE_clause="and status!='NANQUE'";
|
||||||
|
# $or_NANQUE_clause="or status!='NANQUE'";
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
|
||||||
|
### GRAPH COLOR ARRAYS ###
|
||||||
|
$background_colors=array("#009900", "#990000", "#000099", "#999900", "#990099", "#009999", "#999999", "#339933", "#993333", "#333399", "#999933", "#993399", "#339999", "#339900", "#993300", "#330099", "#009933", "#990033", "#003399", "#00CC00", "#CC0000", "#0000CC", "#CCCC00", "#CC00CC", "#00CCCC", "#33CC33", "#CC3333", "#3333CC", "#CCCC33", "#CC33CC", "#33CCCC", "#33CC00", "#CC3300", "#3300CC", "#00CC33", "#CC0033", "#0033CC", "#66CC00", "#CC6600", "#6600CC", "#00CC66", "#CC0066", "#0066CC", "#33CC66", "#CC3366", "#3366CC", "#66CC33", "#CC6633", "#6633CC", "#66CC66", "#CC6666", "#6666CC", "#CCCC66", "#CC66CC", "#66CCCC", "#CCCCCC");
|
||||||
|
$border_colors=array("#00FF00", "#FF0000", "#0000FF", "#FFFF00", "#FF00FF", "#00FFFF", "#FFFFFF", "#00FF00", "#FF0000", "#0000FF", "#FFFF00", "#FF00FF", "#00FFFF", "#00FF00", "#FF0000", "#0000FF", "#00FF00", "#FF0000", "#0000FF", "#00FF00", "#FF0000", "#0000FF", "#FFFF00", "#FF00FF", "#00FFFF", "#00FF00", "#FF0000", "#0000FF", "#FFFF00", "#FF00FF", "#00FFFF", "#00FF00", "#FF0000", "#0000FF", "#00FF00", "#FF0000", "#0000FF", "#00FF00", "#FF0000", "#0000FF", "#00FF00", "#FF0000", "#0000FF", "#66FF66", "#FF6666", "#6666FF", "#66FF66", "#FF6666", "#6666FF", "#00FF00", "#FF0000", "#0000FF", "#FFFF00", "#FF00FF", "#00FFFF", "#FFFFFF");
|
||||||
|
###########################
|
||||||
|
|
||||||
|
### 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";
|
||||||
|
#########################
|
||||||
|
?>
|
||||||
@@ -0,0 +1,366 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_header.inc - Vicidial Enhanced Reporting header output
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1621 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
/* 08/26 - redundant, already used in parent VERM_main_report_page.php
|
||||||
|
$stmt="SELECT admin_home_url,enable_tts_integration,callcard_enabled,custom_fields_enabled,allow_emails,level_8_disable_add,allow_chats,enable_languages,admin_row_click,admin_screen_colors,user_new_lead_limit,user_territories_active,qc_features_active,agent_soundboards,enable_drop_lists,allow_ip_lists,admin_web_directory from system_settings;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$admin_home_url_LU = $row[0];
|
||||||
|
$SSenable_tts_integration = $row[1];
|
||||||
|
$SScallcard_enabled = $row[2];
|
||||||
|
$SScustom_fields_enabled = $row[3];
|
||||||
|
$SSemail_enabled = $row[4];
|
||||||
|
$SSlevel_8_disable_add = $row[5];
|
||||||
|
$SSchat_enabled = $row[6];
|
||||||
|
$SSenable_languages = $row[7];
|
||||||
|
$SSadmin_row_click = $row[8];
|
||||||
|
$SSadmin_screen_colors = $row[9];
|
||||||
|
$SSuser_new_lead_limit = $row[10];
|
||||||
|
$SSuser_territories_active = $row[11];
|
||||||
|
$SSqc_features_active = $row[12];
|
||||||
|
$SSagent_soundboards = $row[13];
|
||||||
|
$SSenable_drop_lists = $row[14];
|
||||||
|
$SSallow_ip_lists = $row[15];
|
||||||
|
$SSadmin_web_directory = $row[16];
|
||||||
|
*/
|
||||||
|
|
||||||
|
$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='A3C3D6';
|
||||||
|
$SSalt_row1_background='BDFFBD';
|
||||||
|
$SSalt_row2_background='99FF99';
|
||||||
|
$SSalt_row3_background='CCFFCC';
|
||||||
|
$SSbutton_color='EFEFEF';
|
||||||
|
|
||||||
|
if ($SSadmin_screen_colors != 'default')
|
||||||
|
{
|
||||||
|
$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='$SSadmin_screen_colors';";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
if ($DB) {echo "$stmt\n";}
|
||||||
|
$colors_ct = mysqli_num_rows($rslt);
|
||||||
|
if ($colors_ct > 0)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$SSmenu_background = $row[0];
|
||||||
|
$SSframe_background = $row[1];
|
||||||
|
$SSstd_row1_background = $row[2];
|
||||||
|
$SSstd_row2_background = $row[3];
|
||||||
|
$SSstd_row3_background = $row[4];
|
||||||
|
$SSstd_row4_background = $row[5];
|
||||||
|
$SSstd_row5_background = $row[6];
|
||||||
|
$SSalt_row1_background = $row[7];
|
||||||
|
$SSalt_row2_background = $row[8];
|
||||||
|
$SSalt_row3_background = $row[9];
|
||||||
|
$SSweb_logo = $row[10];
|
||||||
|
$SSbutton_color = $row[11];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$Mhead_color = $SSstd_row5_background;
|
||||||
|
$Mmain_bgcolor = $SSmenu_background;
|
||||||
|
$Mhead_color = $SSstd_row5_background;
|
||||||
|
|
||||||
|
$selected_logo = "/".$SSadmin_web_directory."/images/vicidial_admin_web_logo.png";
|
||||||
|
$selected_small_logo = "/".$SSadmin_web_directory."/images/vicidial_admin_web_logo.png";
|
||||||
|
$logo_new=0;
|
||||||
|
$logo_old=0;
|
||||||
|
$logo_small_old=0;
|
||||||
|
if (file_exists("/".$SSadmin_web_directory."/images/vicidial_admin_web_logo.png")) {$logo_new++;}
|
||||||
|
if (file_exists("/".$SSadmin_web_directory."/images/vicidial_admin_web_logo_small.gif")) {$logo_small_old++;}
|
||||||
|
if (file_exists("/".$SSadmin_web_directory."/images/vicidial_admin_web_logo.gif")) {$logo_old++;}
|
||||||
|
if ($SSweb_logo=='default_new')
|
||||||
|
{
|
||||||
|
$selected_logo = "/".$SSadmin_web_directory."/images/vicidial_admin_web_logo.png";
|
||||||
|
$selected_small_logo = "/".$SSadmin_web_directory."/images/vicidial_admin_web_logo.png";
|
||||||
|
}
|
||||||
|
if ( ($SSweb_logo=='default_old') and ($logo_old > 0) )
|
||||||
|
{
|
||||||
|
$selected_logo = "/".$SSadmin_web_directory."/vicidial_admin_web_logo.gif";
|
||||||
|
$selected_small_logo = "/".$SSadmin_web_directory."/vicidial_admin_web_logo_small.gif";
|
||||||
|
}
|
||||||
|
if ( ($SSweb_logo!='default_new') and ($SSweb_logo!='default_old') )
|
||||||
|
{
|
||||||
|
if (file_exists("/".$SSadmin_web_directory."/images/vicidial_admin_web_logo$SSweb_logo"))
|
||||||
|
{
|
||||||
|
$selected_logo = "/".$SSadmin_web_directory."/images/vicidial_admin_web_logo$SSweb_logo";
|
||||||
|
$selected_small_logo = "/".$SSadmin_web_directory."/images/vicidial_admin_web_logo$SSweb_logo";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$NWB = "<IMG SRC=\"help.png\" onClick=\"FillAndShowHelpDiv(event, '";
|
||||||
|
$NWE = "')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP>";
|
||||||
|
|
||||||
|
$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 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";
|
||||||
|
$HTML_header.="<link rel=\"stylesheet\" href=\"calendar.css\">\n";
|
||||||
|
$HTML_header.="<script language=\"JavaScript\" src=\"VERM_functions.js\"></script>\n";
|
||||||
|
$HTML_header.="</head>\n";
|
||||||
|
$HTML_header.="<body>\n";
|
||||||
|
$HTML_header.="<div id='DisplayLinkDiv' class='details_info' style='display:none;z-index:15;'></div>\n";
|
||||||
|
$HTML_header.="<div id='CallDetailsDiv' class='details_info' style='display:none;z-index:10;'></div>\n";
|
||||||
|
$HTML_header.="<div id='AgentDetailsDiv' class='details_info' style='display:none;z-index:11;'></div>\n";
|
||||||
|
$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;
|
||||||
|
|
||||||
|
#### VARIABLES FROM OTHER PAGES #####
|
||||||
|
echo "<input type='hidden' name='vicidial_queue_groups' id='vicidial_queue_groups' value='$vicidial_queue_groups'>\n";
|
||||||
|
# echo "<input type='hidden' name='report_types' id='report_types' value='$report_types'>\n";
|
||||||
|
echo "<input type='hidden' name='time_period' id='time_period' value='$time_period'>\n";
|
||||||
|
echo "<input type='hidden' name='start_date' id='start_date' value='$start_date'>\n";
|
||||||
|
echo "<input type='hidden' name='start_time_hour' id='start_time_hour' value='$start_time_hour'>\n";
|
||||||
|
echo "<input type='hidden' name='start_time_min' id='start_time_min' value='$start_time_min'>\n";
|
||||||
|
echo "<input type='hidden' name='end_date' id='end_date' value='$end_date'>\n";
|
||||||
|
echo "<input type='hidden' name='end_time_hour' id='end_time_hour' value='$end_time_hour'>\n";
|
||||||
|
echo "<input type='hidden' name='end_time_min' id='end_time_min' value='$end_time_min'>\n";
|
||||||
|
echo "<input type='hidden' name='hourly_slot' id='hourly_slot' value='$hourly_slot'>\n";
|
||||||
|
echo "<input type='hidden' name='SLA_initial_period' id='SLA_initial_period' value='$SLA_initial_period'>\n";
|
||||||
|
echo "<input type='hidden' name='SLA_initial_interval' id='SLA_initial_interval' value='$SLA_initial_interval'>\n";
|
||||||
|
echo "<input type='hidden' name='SLA_max_period' id='SLA_max_period' value='$SLA_max_period'>\n";
|
||||||
|
echo "<input type='hidden' name='SLA_interval' id='SLA_interval' value='$SLA_interval'>\n";
|
||||||
|
echo "<input type='hidden' name='short_call_wait_limit' id='short_call_wait_limit' value='$short_call_wait_limit'>\n";
|
||||||
|
echo "<input type='hidden' name='short_call_talk_limit' id='short_call_talk_limit' value='$short_call_talk_limit'>\n";
|
||||||
|
echo "<input type='hidden' name='short_attempt_wait_limit' id='short_attempt_wait_limit' value='$short_attempt_wait_limit'>\n";
|
||||||
|
echo "<input type='hidden' name='users' id='users' value='$users'>\n";
|
||||||
|
echo "<input type='hidden' name='teams' id='teams' value='$teams'>\n";
|
||||||
|
echo "<input type='hidden' name='location' id='location' value='$location'>\n";
|
||||||
|
echo "<input type='hidden' name='user_group' id='user_group' value='$user_group'>\n";
|
||||||
|
echo "<input type='hidden' name='statuses' id='statuses' value='$statuses'>\n";
|
||||||
|
echo "<input type='hidden' name='asterisk_cid' id='asterisk_cid' value='$asterisk_cid'>\n";
|
||||||
|
echo "<input type='hidden' name='phone_number' id='phone_number' value='$phone_number'>\n";
|
||||||
|
echo "<input type='hidden' name='wait_sec_min' id='wait_sec_min' value='$wait_sec_min'>\n";
|
||||||
|
echo "<input type='hidden' name='wait_sec_max' id='wait_sec_max' value='$wait_sec_max'>\n";
|
||||||
|
echo "<input type='hidden' name='length_in_sec_min' id='length_in_sec_min' value='$length_in_sec_min'>\n";
|
||||||
|
echo "<input type='hidden' name='length_in_sec_max' id='length_in_sec_max' value='$length_in_sec_max'>\n";
|
||||||
|
echo "<input type='hidden' name='disconnection_cause' id='disconnection_cause' value='$disconnection_cause'>\n";
|
||||||
|
echo "<input type='hidden' name='queue_position_min' id='queue_position_min' value='$queue_position_min'>\n";
|
||||||
|
echo "<input type='hidden' name='queue_position_max' id='queue_position_max' value='$queue_position_max'>\n";
|
||||||
|
echo "<input type='hidden' name='call_count_min' id='call_count_min' value='$call_count_min'>\n";
|
||||||
|
echo "<input type='hidden' name='call_count_max' id='call_count_max' value='$call_count_max'>\n";
|
||||||
|
echo "<input type='hidden' name='did' id='did' value='$did'>\n";
|
||||||
|
echo "<input type='hidden' name='ivr_choice' id='ivr_choice' value='$ivr_choice'>\n";
|
||||||
|
echo "<input type='hidden' name='server' id='server' value='$server'>\n";
|
||||||
|
echo "<input type='hidden' name='dow' id='dow' value='$dow_str'>\n";
|
||||||
|
echo "<input type='hidden' name='time_of_day_start' id='time_of_day_start' value='$time_of_day_start'>\n";
|
||||||
|
echo "<input type='hidden' name='time_of_day_end' id='time_of_day_end' value='$time_of_day_end'>\n";
|
||||||
|
echo "<input type='hidden' name='download_rpt' id='download_rpt'>\n";
|
||||||
|
echo "<input type='hidden' name='report_type' id='report_type' value='$report_type'>\n";
|
||||||
|
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>
|
||||||
|
<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> </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 ↻</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 "</td>\n";
|
||||||
|
echo "</tr>\n";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
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>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
} else if ($report_types_to_display=="Quick reports") {
|
||||||
|
# Gotta overwrite here
|
||||||
|
if (!$report_type || $report_type=="ANSWERED") {$report_type="STATS";}
|
||||||
|
?>
|
||||||
|
<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>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
} else {
|
||||||
|
?>
|
||||||
|
<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>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table id="rpt_table">
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th style="width:25vw">Report Details:</th>
|
||||||
|
<td style="width:75vw"></td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
if ($report_full_names_array["$report_type"])
|
||||||
|
{
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td style="width:25vw" class='bold_cell'>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:75vw" class='bold_cell'>
|
||||||
|
<?php
|
||||||
|
echo $vicidial_queue_groups;
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width:25vw">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:75vw" class='queue_cell'>
|
||||||
|
<?php
|
||||||
|
echo $atomic_queue_str;
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width:25vw">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: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: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:75vw"><?php
|
||||||
|
$answered_percentage=sprintf("%.1f", MathZDC((100*$total_answered_calls), $total_calls));
|
||||||
|
$unanswered_percentage=sprintf("%.1f", MathZDC((100*$total_unanswered_calls), $total_calls));
|
||||||
|
echo $answered_percentage."% ans / ".$unanswered_percentage."% unans";
|
||||||
|
?></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width:25vw"> </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>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width:25vw"> </td>
|
||||||
|
<td style="width:75vw"><input type="button" class="actButton" value="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>
|
||||||
|
<tr class='export_row'>
|
||||||
|
<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";
|
||||||
|
echo "<BR>Vicidial AGENT log SQL: $vicidial_agent_log_SQL\n";
|
||||||
|
echo "Users: $and_user_sql<BR>\n";
|
||||||
|
# echo "Location: $and_location_sql<BR>\n";
|
||||||
|
echo "Team users: $team - $and_team_sql<BR>\n";
|
||||||
|
echo "User group: $and_user_group_sql<BR>\n";
|
||||||
|
echo "Statuses: $and_status_sql<BR>\n";
|
||||||
|
echo "Outbound Phone: $and_phone_number_sql<BR>\n";
|
||||||
|
echo "Wait sec: $and_wait_sec_sql<BR>\n";
|
||||||
|
echo "Length in sec: $and_length_in_sec_sql<BR>\n";
|
||||||
|
echo "Disconnections: $and_term_reason_sql<BR>\n";
|
||||||
|
echo "Queue positions: $and_queue_position_sql<BR>\n";
|
||||||
|
echo "Called count: $and_called_count_sql<BR>\n";
|
||||||
|
# echo "Inbound DID: $and_did_sql<BR>\n";
|
||||||
|
print_r($did_uniqueid_array);
|
||||||
|
# echo "Server: $and_server_ip_sql<BR>\n";
|
||||||
|
# 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>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<script language='Javascript'>
|
||||||
|
var answered_unanswered_data = {
|
||||||
|
labels:["Ans %", "Unans %"],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "",
|
||||||
|
fill: false,
|
||||||
|
data: ["<?php echo $answered_percentage; ?>", "<?php echo $unanswered_percentage; ?>"],
|
||||||
|
backgroundColor: ["#009900","#990000"],
|
||||||
|
hoverBackgroundColor: ["#009900","#990000"],
|
||||||
|
hoverBorderColor: ["#00FF00","#FF0000"],
|
||||||
|
hoverBorderWidth: 2,
|
||||||
|
tension: 0,
|
||||||
|
fillColor: "rgba(255,230,230,0.5)",
|
||||||
|
borderColor: "rgba(255,255,255,0.8)",
|
||||||
|
pointBorderColor: "rgba(255,255,255,1)",
|
||||||
|
pointBackgroundColor: "#FFF",
|
||||||
|
pointHoverBackgroundColor: "rgba(255,255,255,0.75)",
|
||||||
|
pointHoverBorderColor: "rgba(255,230,230,1)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
var answered_unanswered_canvas = document.getElementById("answered_unanswered_display");
|
||||||
|
var answered_unanswered_graph = new Chart(answered_unanswered_canvas, {type: 'doughnut', options: { cutout: "40%", plugins: {legend: { position: 'right' }}},
|
||||||
|
data: answered_unanswered_data});
|
||||||
|
</script>
|
||||||
|
|
||||||
@@ -0,0 +1,205 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_options.php - Vicidial Enhanced Reporting options holder
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1604 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
/*
|
||||||
|
####################
|
||||||
|
$VERM_default_report_queue="000_ALL_Calls";
|
||||||
|
$VERM_default_outb_widget_queue="000_ALL_OUT";
|
||||||
|
$VERM_default_inb_widget_queue1="SALESLINE";
|
||||||
|
$VERM_default_inb_widget_queue2="SUPPORT";
|
||||||
|
|
||||||
|
$exc_addtl_statuses=" and status not in ('AFTHRS') ";
|
||||||
|
# $and_NANQUE_clause="and status!='NANQUE'";
|
||||||
|
# $or_NANQUE_clause="or status!='NANQUE'";
|
||||||
|
|
||||||
|
$SLA_LEVEL_PCT_clause=" and campaign_id in ('SALESLINE', 'SUPPORT') ";
|
||||||
|
|
||||||
|
$remote_agents_clause=" and extension not like 'R/%'";
|
||||||
|
|
||||||
|
$ivr_survey_ingroups_detail["521205"]=array("561401", "561402", "561403", "561404", "561505");
|
||||||
|
$ivr_survey_ingroups_voicemails["561505"]="t";
|
||||||
|
|
||||||
|
print "VERM_default_report_queue: $VERM_default_report_queue\n";
|
||||||
|
print "VERM_default_outb_widget_queue: $VERM_default_outb_widget_queue\n";
|
||||||
|
print "VERM_default_inb_widget_queue1: $VERM_default_inb_widget_queue1\n";
|
||||||
|
print "VERM_default_inb_widget_queue2: $VERM_default_inb_widget_queue2\n\n";
|
||||||
|
print "exc_addtl_statuses: $exc_addtl_statuses\n";
|
||||||
|
print "SLA_LEVEL_PCT_clause: $SLA_LEVEL_PCT_clause\n";
|
||||||
|
print "remote_agents_clause: $remote_agents_clause\n";
|
||||||
|
|
||||||
|
print "ivr_survey_ingroups_detail: ";
|
||||||
|
print_r($ivr_survey_ingroups_detail);
|
||||||
|
print "ivr_survey_ingroups_voicemails: ";
|
||||||
|
print_r($ivr_survey_ingroups_voicemails);
|
||||||
|
print "\n\n\n";
|
||||||
|
###################
|
||||||
|
*/
|
||||||
|
|
||||||
|
$exc_addtl_statuses="";
|
||||||
|
|
||||||
|
$lost_statuses_array=array();
|
||||||
|
$lost_statuses="";
|
||||||
|
$exc_lost_statuses="";
|
||||||
|
|
||||||
|
$ivr_survey_ingroups_detail=array();
|
||||||
|
$ivr_survey_ingroups_voicemails=array();
|
||||||
|
|
||||||
|
$VERM_default_report_queue="";
|
||||||
|
$VERM_default_outb_widget_queue="";
|
||||||
|
$VERM_default_inb_widget_queue1="";
|
||||||
|
$VERM_default_inb_widget_queue2="";
|
||||||
|
$SLA_LEVEL_PCT_clause="";
|
||||||
|
$remote_agents_clause="";
|
||||||
|
|
||||||
|
$options_stmt="select container_entry from vicidial_settings_containers where container_id='VERM_REPORT_OPTIONS'";
|
||||||
|
$options_rslt=mysql_to_mysqli($options_stmt, $link);
|
||||||
|
if (mysqli_num_rows($options_rslt)>0)
|
||||||
|
{
|
||||||
|
$options_row=mysqli_fetch_row($options_rslt);
|
||||||
|
$container_entry=explode("\n", $options_row[0]);
|
||||||
|
|
||||||
|
for ($q=0; $q<count($container_entry); $q++)
|
||||||
|
{
|
||||||
|
if (!preg_match('/^\;/', $container_entry[$q]) && preg_match('/\s\=\>\s/', $container_entry[$q]))
|
||||||
|
{
|
||||||
|
$container_setting=explode(" => ", trim($container_entry[$q]));
|
||||||
|
$setting_name=$container_setting[0];
|
||||||
|
$setting_value=$container_setting[1];
|
||||||
|
|
||||||
|
if ($setting_name=="omit_remote_agents" && $setting_value)
|
||||||
|
{$remote_agents_clause=" and extension not like 'R/%'";}
|
||||||
|
if ($setting_name=="VERM_default_report_queue" && $setting_value)
|
||||||
|
{$VERM_default_report_queue=$setting_value;}
|
||||||
|
|
||||||
|
if ($setting_name=="VERM_default_outb_widget_queue" && $setting_value)
|
||||||
|
{
|
||||||
|
$setting_value_ary=explode("|", $setting_value);
|
||||||
|
$VERM_default_outb_widget_queue=$setting_value_ary[0];
|
||||||
|
if (strlen($setting_value_ary[1])>0)
|
||||||
|
{
|
||||||
|
$VERM_default_outb_widget_queue_name=$setting_value_ary[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$VERM_default_outb_widget_queue_name=GetQueueName($VERM_default_outb_widget_queue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($setting_name=="VERM_default_inb_widget_queue1" && $setting_value)
|
||||||
|
{
|
||||||
|
$setting_value_ary=explode("|", $setting_value);
|
||||||
|
$VERM_default_inb_widget_queue1=$setting_value[0];
|
||||||
|
if (strlen($setting_value_ary[1])>0)
|
||||||
|
{
|
||||||
|
$VERM_default_inb_widget_queue1_name=$setting_value_ary[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$VERM_default_inb_widget_queue1_name=GetQueueName($VERM_default_inb_widget_queue1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($setting_name=="VERM_default_inb_widget_queue2" && $setting_value)
|
||||||
|
{
|
||||||
|
$setting_value_ary=explode("|", $setting_value);
|
||||||
|
$VERM_default_inb_widget_queue2=$setting_value[0];
|
||||||
|
if (strlen($setting_value_ary[1])>0)
|
||||||
|
{
|
||||||
|
$VERM_default_inb_widget_queue2_name=$setting_value_ary[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$VERM_default_inb_widget_queue2_name=GetQueueName($VERM_default_inb_widget_queue2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($setting_name=="show_full_agent_info" && $setting_value)
|
||||||
|
{$show_full_agent_info=$setting_value;}
|
||||||
|
|
||||||
|
if ($setting_name=="exc_addtl_statuses" && $setting_value)
|
||||||
|
{
|
||||||
|
$exc_statuses=explode(",", $setting_value);
|
||||||
|
if (count($exc_statuses)>0)
|
||||||
|
{
|
||||||
|
$exc_addtl_statuses=" and status not in ('".implode("', '", $exc_statuses)."') ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($setting_name=="lost_statuses" && $setting_value)
|
||||||
|
{
|
||||||
|
$lost_statuses_array=explode(",", $setting_value);
|
||||||
|
if (count($lost_statuses_array)>0)
|
||||||
|
{
|
||||||
|
$lost_statuses=" and status in ('".implode("', '", $lost_statuses_array)."') ";
|
||||||
|
$exc_lost_statuses=" and status NOT in ('".implode("', '", $lost_statuses_array)."') ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($setting_name=="SLA_LEVEL_PCT_ingroups" && $setting_value)
|
||||||
|
{
|
||||||
|
$sla_percents=explode(",", $setting_value);
|
||||||
|
if (count($sla_percents)>0)
|
||||||
|
{
|
||||||
|
$SLA_LEVEL_PCT_clause=" and campaign_id in ('".implode("', '", $sla_percents)."') ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($setting_name=="ivr_survey_ingroups_detail" && $setting_value && preg_match('/\|/', $setting_value))
|
||||||
|
{
|
||||||
|
$isid_array=explode("|", $setting_value);
|
||||||
|
$ingroup=$isid_array[0];
|
||||||
|
$callmenus=explode(",", $isid_array[1]);
|
||||||
|
if (count($callmenus)>0)
|
||||||
|
{
|
||||||
|
$ivr_survey_ingroups_detail["$ingroup"]=$callmenus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($setting_name=="ivr_survey_ingroups_voicemails" && $setting_value && preg_match('/\|/', $setting_value))
|
||||||
|
{
|
||||||
|
$isid_array=explode("|", $setting_value);
|
||||||
|
$ingroup=$isid_array[0];
|
||||||
|
$options=$isid_array[1];
|
||||||
|
if (strlen($options)>0)
|
||||||
|
{
|
||||||
|
$ivr_survey_ingroups_voicemails["$ingroup"]=$options;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# print "$container_entry[$q]\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetQueueName($temp_queue)
|
||||||
|
{
|
||||||
|
global $DB, $link;
|
||||||
|
$queue_name_stmt="select queue_group_name from vicidial_queue_groups where queue_group='$temp_queue'";
|
||||||
|
$queue_name_rslt=mysql_to_mysqli($queue_name_stmt, $link);
|
||||||
|
$temp_queue_name="";
|
||||||
|
while ($queue_name_row=mysqli_fetch_row($queue_name_rslt))
|
||||||
|
{
|
||||||
|
$temp_queue_name=$queue_name_row[0];
|
||||||
|
}
|
||||||
|
return $temp_queue_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
print "VERM_default_report_queue: $VERM_default_report_queue\n";
|
||||||
|
print "VERM_default_outb_widget_queue: $VERM_default_outb_widget_queue\n";
|
||||||
|
print "VERM_default_inb_widget_queue1: $VERM_default_inb_widget_queue1\n";
|
||||||
|
print "VERM_default_inb_widget_queue2: $VERM_default_inb_widget_queue2\n\n";
|
||||||
|
print "exc_addtl_statuses: $exc_addtl_statuses\n";
|
||||||
|
print "SLA_LEVEL_PCT_clause: $SLA_LEVEL_PCT_clause\n";
|
||||||
|
print "remote_agents_clause: $remote_agents_clause\n";
|
||||||
|
|
||||||
|
print "ivr_survey_ingroups_detail: ";
|
||||||
|
print_r($ivr_survey_ingroups_detail);
|
||||||
|
print "ivr_survey_ingroups_voicemails: ";
|
||||||
|
print_r($ivr_survey_ingroups_voicemails);
|
||||||
|
print "\n\n\n";
|
||||||
|
*/
|
||||||
|
?>
|
||||||
@@ -0,0 +1,460 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_stylesheet.php - Vicidial Enhanced Reporting stylesheet
|
||||||
|
#
|
||||||
|
# CSS/PHP file that uses the system-defined screen colors to display report elements
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1603 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
require("../vicidial/dbconnect_mysqli.php");
|
||||||
|
require("../vicidial/functions.php");
|
||||||
|
header("Content-type: text/css");
|
||||||
|
|
||||||
|
require("../vicidial/screen_colors.php");
|
||||||
|
?>
|
||||||
|
div.help_info {position:absolute; top:0; left:0; display:none;}
|
||||||
|
|
||||||
|
TABLE.help_td {
|
||||||
|
-moz-border-radius: 5px 5px 5px 5px;
|
||||||
|
-webkit-border-radius: 5px 5px 5px 5px;
|
||||||
|
border-radius: 5px 5px 5px 5px;
|
||||||
|
box-shadow: 5px 5px 12px #000000;
|
||||||
|
padding: 5px;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
color: black;
|
||||||
|
font-size: 10pt;
|
||||||
|
background: #<?php echo $SSframe_background; ?>;
|
||||||
|
color: #000000;
|
||||||
|
vertical-align: top;
|
||||||
|
border:solid 4px #<?php echo $SSmenu_background; ?>
|
||||||
|
}
|
||||||
|
|
||||||
|
.help_bold {
|
||||||
|
font-weight:bold;
|
||||||
|
font-size: 12pt;
|
||||||
|
opacity: 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel_td {
|
||||||
|
padding: 5px;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
color: black;
|
||||||
|
font-size: 12pt;
|
||||||
|
font-weight: bold;
|
||||||
|
background: #<?php echo $SSframe_background; ?>;
|
||||||
|
color: #000000;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.standard_font_small {
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 9pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.standard_font {
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 12pt;
|
||||||
|
}
|
||||||
|
.standard_font_lg {
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 14pt;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2.rpt_header {
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 18pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2.admin_sub_header {
|
||||||
|
font-family: "Arial";
|
||||||
|
font-size: 12pt;
|
||||||
|
color: #<?php echo $SSmenu_background; ?>;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2.admin_header {
|
||||||
|
font-family: "Arial";
|
||||||
|
font-size: 18pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#rpt_table {
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 12pt;
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#rpt_table td, #rpt_table th {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#rpt_table tr:nth-child(even){background-color: #f9f9f9;}
|
||||||
|
|
||||||
|
#rpt_table tr:hover {background-color: #ddf;}
|
||||||
|
|
||||||
|
#rpt_table tr.export_row
|
||||||
|
{
|
||||||
|
background-color: #fff;
|
||||||
|
padding-top: 12px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
background-color: #FFF;
|
||||||
|
color: black;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#rpt_table th {
|
||||||
|
padding-top: 12px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
background-color: #FFF;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#rpt_table {
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 12pt;
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#rpt_table td, #rpt_table th {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
#rpt_table td.export_row_cell
|
||||||
|
{
|
||||||
|
border: 0px;
|
||||||
|
background-color: #FFF;
|
||||||
|
}
|
||||||
|
#rpt_table td.bold_cell
|
||||||
|
{
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
#rpt_table td.queue_cell
|
||||||
|
{
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 8pt;
|
||||||
|
}
|
||||||
|
#rpt_table td.small_text
|
||||||
|
{
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#details_table {
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 12pt;
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#details_table td, #details_table th {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#details_table tr:hover {background-color: #ddf;}
|
||||||
|
|
||||||
|
#details_table tr.export_row
|
||||||
|
{
|
||||||
|
background-color: #fff;
|
||||||
|
padding-top: 6px;
|
||||||
|
padding-bottom: 6px;
|
||||||
|
background-color: #FFF;
|
||||||
|
color: black;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
#details_table td.export_row_cell
|
||||||
|
{
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#details_table th {
|
||||||
|
padding-top: 12px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
background-color: #FFF;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
#details_table td.bold_cell
|
||||||
|
{
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
#details_table td.queue_cell
|
||||||
|
{
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 8pt;
|
||||||
|
}
|
||||||
|
#details_table td.small_text
|
||||||
|
{
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#admin_table {
|
||||||
|
font-family: "Arial";
|
||||||
|
font-size: 12pt;
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#admin_table td, #admin_table th {
|
||||||
|
border: 0px;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#admin_table tr.export_row
|
||||||
|
{
|
||||||
|
background-color: #fff;
|
||||||
|
padding-top: 6px;
|
||||||
|
padding-bottom: 6px;
|
||||||
|
background-color: #FFF;
|
||||||
|
color: black;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#admin_table th {
|
||||||
|
padding-top: 12px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
background-color: #FFF;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#admin_table font.rpt_header {
|
||||||
|
font-weight: bold;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#nav_table
|
||||||
|
{
|
||||||
|
width:100%;
|
||||||
|
padding:0px;
|
||||||
|
margin:0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav_table td.nav_header
|
||||||
|
{
|
||||||
|
border-bottom: 2px solid black;
|
||||||
|
border-top: 2px solid black;
|
||||||
|
background-color: #CCC;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav_table td.title_cell
|
||||||
|
{
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.actButton{
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 12px;
|
||||||
|
color:#FFFFFF;
|
||||||
|
border: none;
|
||||||
|
padding: 0px 0px;
|
||||||
|
width: 150px;
|
||||||
|
height: 36px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
background-color:#<?php echo $SSmenu_background; ?>;
|
||||||
|
}
|
||||||
|
input.refreshButton{
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 24px;
|
||||||
|
color:#FFFFFF;
|
||||||
|
border: none;
|
||||||
|
padding: 0px 0px;
|
||||||
|
width: 50px;
|
||||||
|
height: 36px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
background-color:#<?php echo $SSmenu_background; ?>;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.header_link:link {
|
||||||
|
color: #900;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.header_link:visited {
|
||||||
|
color: #900;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.header_link:hover {
|
||||||
|
color: #66F;
|
||||||
|
text-decoration: underline;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.header_link:active {
|
||||||
|
color: #66F;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.report_link:link {
|
||||||
|
color: #009;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.report_link {
|
||||||
|
color: #009;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.report_link:visited {
|
||||||
|
color: #909;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.report_link:hover {
|
||||||
|
color: #66F;
|
||||||
|
text-decoration: underline;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.report_link:active {
|
||||||
|
color: #66F;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
a.popup_link:link {
|
||||||
|
color: #900;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.popup_link {
|
||||||
|
color: #900;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.popup_link:visited {
|
||||||
|
color: #900;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.popup_link:hover {
|
||||||
|
color: #F66;
|
||||||
|
text-decoration: underline;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.popup_link:active {
|
||||||
|
color: #F66;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.details_info {
|
||||||
|
position:fixed;
|
||||||
|
background-color: white;
|
||||||
|
top: 5vh,
|
||||||
|
left:5vw;
|
||||||
|
display:none;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
box-shadow: 10px 10px 10px 10px #666;
|
||||||
|
border:3px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VERM_form_field {
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 12px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
background-color: #<?php echo $SSalt_row1_background; ?>;
|
||||||
|
padding: 5px;
|
||||||
|
border: solid 3px #<?php echo $SSmenu_background; ?>;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.VERM_numeric_field
|
||||||
|
{
|
||||||
|
width:80px
|
||||||
|
}
|
||||||
|
|
||||||
|
input.transparent_button
|
||||||
|
{
|
||||||
|
background: none;
|
||||||
|
border: 0px;
|
||||||
|
padding: 10px 5px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.download_button
|
||||||
|
{
|
||||||
|
background: none;
|
||||||
|
border: 0px;
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 12pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.sort_button
|
||||||
|
{
|
||||||
|
background: none;
|
||||||
|
border: 0px;
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 12pt;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #900;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.download_button:hover
|
||||||
|
{
|
||||||
|
background: #F99;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.sort_button:hover
|
||||||
|
{
|
||||||
|
background: #99F;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.current_report
|
||||||
|
{
|
||||||
|
font-family: "Arial black";
|
||||||
|
font-weight: bold;
|
||||||
|
color: #F00;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.navigation_list
|
||||||
|
{
|
||||||
|
font-family: "Arial";
|
||||||
|
font-size: 10pt;
|
||||||
|
float: left; /* float all of this to the right */
|
||||||
|
padding-inline: 10px 20px; /* An absolute length */
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.navigation_list li
|
||||||
|
{
|
||||||
|
display: inline-block;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.navigation_list li.current_report
|
||||||
|
{
|
||||||
|
font-family: "Arial black";
|
||||||
|
font-weight: bold;
|
||||||
|
color: #F00;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 30px;
|
||||||
|
height: 38px;
|
||||||
|
position: relative;
|
||||||
|
left: -5px;
|
||||||
|
border: 1px solid #DDE1E4;
|
||||||
|
border-left: none;
|
||||||
|
background-color: #11E8EA;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
datalist {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
@@ -0,0 +1,355 @@
|
|||||||
|
<?php
|
||||||
|
# VERM_wallboard_stylesheet.php - Vicidial Enhanced Reporting stylesheet for the wallboards report
|
||||||
|
#
|
||||||
|
# CSS/PHP file that uses the system-defined screen colors to display report elements
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1602 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
require("../vicidial/dbconnect_mysqli.php");
|
||||||
|
require("../vicidial/functions.php");
|
||||||
|
header("Content-type: text/css");
|
||||||
|
|
||||||
|
require("../vicidial/screen_colors.php");
|
||||||
|
?>
|
||||||
|
|
||||||
|
/*
|
||||||
|
.play_pause_button {
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 20px;
|
||||||
|
|
||||||
|
border-color: transparent transparent transparent #202020;
|
||||||
|
transition: 100ms all ease;
|
||||||
|
will-change: border-width;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
// play state
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 10px 0 10px 16px;
|
||||||
|
|
||||||
|
// paused state
|
||||||
|
//&.pause {
|
||||||
|
// border-style: double;
|
||||||
|
// border-width: 0px 0 0px 16px;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
input.play_button {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
border-radius: 8px;
|
||||||
|
color:white;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: green;
|
||||||
|
}
|
||||||
|
input.stop_button {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
border-radius: 8px;
|
||||||
|
color:white;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topalign
|
||||||
|
{
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
div.top_center
|
||||||
|
{
|
||||||
|
vertical-align: top;
|
||||||
|
align: center;
|
||||||
|
}
|
||||||
|
div.total_center
|
||||||
|
{
|
||||||
|
vertical-align: middle;
|
||||||
|
align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.widget_cell
|
||||||
|
{
|
||||||
|
border: 1px solid white;
|
||||||
|
vertical-align: top;
|
||||||
|
// border-radius: 2px;
|
||||||
|
// cellspacing: 5px;
|
||||||
|
}
|
||||||
|
td.widget_cell:hover
|
||||||
|
{
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.widget_contents
|
||||||
|
{
|
||||||
|
border-collapse: collapse; border-spacing: 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.shaded
|
||||||
|
{
|
||||||
|
background-color: #<? echo $SSalt_row2_background; ?>;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.widget_cell_title_bar
|
||||||
|
{
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 12pt;
|
||||||
|
color: #444;
|
||||||
|
background-color: #FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.widget_cell_title_bar:hover
|
||||||
|
{
|
||||||
|
color: #FFF;
|
||||||
|
background-color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.widget_cell_text_type
|
||||||
|
{
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 36pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tr.wallboard_title_row
|
||||||
|
{
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 16pt;
|
||||||
|
color: #999;
|
||||||
|
background-color: #444;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.widget_settings_cell
|
||||||
|
{
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 12pt;
|
||||||
|
color: #CCC;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
th.widget_settings_title_cell
|
||||||
|
{
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 12pt;
|
||||||
|
color: #CCC;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
input.widget_settings_form_field {
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 10px;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
div.widget_settings {
|
||||||
|
position:fixed;
|
||||||
|
background-color: #444;
|
||||||
|
top: 0vh,
|
||||||
|
left:0vw;
|
||||||
|
display:none;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: auto;
|
||||||
|
box-shadow: 3px 3px 3px 3px #666;
|
||||||
|
border-radius: 3px;
|
||||||
|
border:3px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#widget_table {
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 12pt;
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
#widget_table tr.widget_table_header {
|
||||||
|
background-color: #666;
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#widget_table td, #widget_table th {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#widget_table tr:nth-child(even){background-color:#<? echo $SSalt_row3_background; ?>;}
|
||||||
|
|
||||||
|
.view_button {
|
||||||
|
padding: 6px;
|
||||||
|
border-radius: 50px;
|
||||||
|
display: inline-flex;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background .2s ease;
|
||||||
|
margin: 8px 0;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget_edit_button {
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
background-color: transparent;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.widget_edit_button:hover {
|
||||||
|
color: #0FF;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
input.inbound_marker_button
|
||||||
|
{
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 18px;
|
||||||
|
border: none;
|
||||||
|
background-color: #FFFF99;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
input.outbound_marker_button
|
||||||
|
{
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 18px;
|
||||||
|
border: none;
|
||||||
|
background-color: #99FF99;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
input.paused_marker_button
|
||||||
|
{
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 18px;
|
||||||
|
border: none;
|
||||||
|
background-color: #FF9999;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
input.ready_marker_button
|
||||||
|
{
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 18px;
|
||||||
|
border: none;
|
||||||
|
background-color: #9999FF;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
input.widget_form_button{
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 12px;
|
||||||
|
color:#000;
|
||||||
|
border: none;
|
||||||
|
padding: 5px 5px;
|
||||||
|
width: 100px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
background-color:#<?php echo $SSbutton_color; ?>;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.color_swatch_button {
|
||||||
|
border: none;
|
||||||
|
padding: 1px 1px;
|
||||||
|
width: 30px;
|
||||||
|
height: 10px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.color_swatch_button:hover {
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
box-shadow: 0px 0px 3px 3px rgba(255, 255, 255, .4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-wrap{
|
||||||
|
display: inline-block;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
border: 2px solid red;
|
||||||
|
border-radius: 15px;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: 0px 0px 4px rgba(0, 0, 0, .50);
|
||||||
|
margin: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-wrap:before {
|
||||||
|
content: "";
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: lime;
|
||||||
|
height: 10px;
|
||||||
|
width: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
position: absolute;
|
||||||
|
top: calc(50% - 5px);
|
||||||
|
left: calc(50% - 5px);
|
||||||
|
box-shadow: 0px 0px 8px rgba(0, 0, 0, .70);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallboard_tiny_text {
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
FONT-SIZE: calc(5px + 0.3vw);
|
||||||
|
}
|
||||||
|
.wallboard_small_text {
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
FONT-SIZE: calc(6px + 0.5vw);
|
||||||
|
}
|
||||||
|
.wallboard_medium_text {
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
FONT-SIZE: calc(12px + 0.6vw);
|
||||||
|
}
|
||||||
|
.wallboard_large_text {
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
FONT-SIZE: calc(18px + 0.8vw);
|
||||||
|
}
|
||||||
|
.wallboard_extra_large_text {
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
FONT-SIZE: calc(24px + 1vw);
|
||||||
|
}
|
||||||
|
.bold {
|
||||||
|
font-weight:bold;
|
||||||
|
}
|
||||||
|
.italics {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.centered_text {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.header_link:link {
|
||||||
|
color: #FFF;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.header_link:visited {
|
||||||
|
color: #FFF;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.header_link:hover {
|
||||||
|
color: #FFF;
|
||||||
|
text-decoration: underline;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.header_link:active {
|
||||||
|
color: #FFF;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
/* calendar icon */
|
||||||
|
img.tcalIcon {
|
||||||
|
cursor: pointer;
|
||||||
|
margin-left: 1px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
/* calendar container element */
|
||||||
|
div#tcal {
|
||||||
|
position: absolute;
|
||||||
|
visibility: hidden;
|
||||||
|
z-index: 100;
|
||||||
|
width: 158px;
|
||||||
|
padding: 2px 0 0 0;
|
||||||
|
}
|
||||||
|
/* all tables in calendar */
|
||||||
|
div#tcal table {
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid silver;
|
||||||
|
border-collapse: collapse;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
/* navigation table */
|
||||||
|
div#tcal table.ctrl {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
/* navigation buttons */
|
||||||
|
div#tcal table.ctrl td {
|
||||||
|
width: 15px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
/* month year header */
|
||||||
|
div#tcal table.ctrl th {
|
||||||
|
background-color: white;
|
||||||
|
color: black;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
/* week days header */
|
||||||
|
div#tcal th {
|
||||||
|
border: 1px solid silver;
|
||||||
|
border-collapse: collapse;
|
||||||
|
text-align: center;
|
||||||
|
padding: 3px 0;
|
||||||
|
font-family: tahoma, verdana, arial;
|
||||||
|
font-size: 10px;
|
||||||
|
background-color: gray;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
/* date cells */
|
||||||
|
div#tcal td {
|
||||||
|
border: 0;
|
||||||
|
border-collapse: collapse;
|
||||||
|
text-align: center;
|
||||||
|
padding: 2px 0;
|
||||||
|
font-family: tahoma, verdana, arial;
|
||||||
|
font-size: 11px;
|
||||||
|
width: 22px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
/* date highlight
|
||||||
|
in case of conflicting settings order here determines the priority from least to most important */
|
||||||
|
div#tcal td.othermonth {
|
||||||
|
color: silver;
|
||||||
|
}
|
||||||
|
div#tcal td.weekend {
|
||||||
|
background-color: #ACD6F5;
|
||||||
|
}
|
||||||
|
div#tcal td.today {
|
||||||
|
border: 1px solid red;
|
||||||
|
}
|
||||||
|
div#tcal td.selected {
|
||||||
|
background-color: #FFB3BE;
|
||||||
|
}
|
||||||
|
/* iframe element used to suppress windowed controls in IE5/6 */
|
||||||
|
iframe#tcalIF {
|
||||||
|
position: absolute;
|
||||||
|
visibility: hidden;
|
||||||
|
z-index: 98;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
/* transparent shadow */
|
||||||
|
div#tcalShade {
|
||||||
|
position: absolute;
|
||||||
|
visibility: hidden;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
div#tcalShade table {
|
||||||
|
border: 0;
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
div#tcalShade table td {
|
||||||
|
border: 0;
|
||||||
|
border-collapse: collapse;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,341 @@
|
|||||||
|
// Tigra Calendar v4.0.2 (2009-01-12) Database (yyyy-mm-dd)
|
||||||
|
// http://www.softcomplex.com/products/tigra_calendar/
|
||||||
|
// Public Domain Software... You're welcome.
|
||||||
|
|
||||||
|
// default settins
|
||||||
|
var A_TCALDEF = {
|
||||||
|
'months' : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
|
||||||
|
'weekdays' : ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
|
||||||
|
'yearscroll': true, // show year scroller
|
||||||
|
'weekstart': 0, // first day of week: 0-Su or 1-Mo
|
||||||
|
'centyear' : 70, // 2 digit years less than 'centyear' are in 20xx, othewise in 19xx.
|
||||||
|
'imgpath' : 'images/' // directory with calendar images
|
||||||
|
}
|
||||||
|
// date parsing function
|
||||||
|
function f_tcalParseDate (s_date) {
|
||||||
|
|
||||||
|
var re_date = /^\s*(\d{2,4})\-(\d{1,2})\-(\d{1,2})\s*$/;
|
||||||
|
if (!re_date.exec(s_date))
|
||||||
|
return alert ("Invalid date: '" + s_date + "'.\nAccepted format is yyyy-mm-dd.")
|
||||||
|
var n_day = Number(RegExp.$3),
|
||||||
|
n_month = Number(RegExp.$2),
|
||||||
|
n_year = Number(RegExp.$1);
|
||||||
|
|
||||||
|
if (n_year < 100)
|
||||||
|
n_year += (n_year < this.a_tpl.centyear ? 2000 : 1900);
|
||||||
|
if (n_month < 1 || n_month > 12)
|
||||||
|
return alert ("Invalid month value: '" + n_month + "'.\nAllowed range is 01-12.");
|
||||||
|
var d_numdays = new Date(n_year, n_month, 0);
|
||||||
|
if (n_day > d_numdays.getDate())
|
||||||
|
return alert("Invalid day of month value: '" + n_day + "'.\nAllowed range for selected month is 01 - " + d_numdays.getDate() + ".");
|
||||||
|
|
||||||
|
return new Date (n_year, n_month - 1, n_day);
|
||||||
|
}
|
||||||
|
// date generating function
|
||||||
|
function f_tcalGenerDate (d_date) {
|
||||||
|
return (
|
||||||
|
d_date.getFullYear() + "-"
|
||||||
|
+ (d_date.getMonth() < 9 ? '0' : '') + (d_date.getMonth() + 1) + "-"
|
||||||
|
+ (d_date.getDate() < 10 ? '0' : '') + d_date.getDate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// implementation
|
||||||
|
function tcal (a_cfg, a_tpl) {
|
||||||
|
|
||||||
|
// apply default template if not specified
|
||||||
|
if (!a_tpl)
|
||||||
|
a_tpl = A_TCALDEF;
|
||||||
|
|
||||||
|
// register in global collections
|
||||||
|
if (!window.A_TCALS)
|
||||||
|
window.A_TCALS = [];
|
||||||
|
if (!window.A_TCALSIDX)
|
||||||
|
window.A_TCALSIDX = [];
|
||||||
|
|
||||||
|
this.s_id = a_cfg.id ? a_cfg.id : A_TCALS.length;
|
||||||
|
window.A_TCALS[this.s_id] = this;
|
||||||
|
window.A_TCALSIDX[window.A_TCALSIDX.length] = this;
|
||||||
|
|
||||||
|
// assign methods
|
||||||
|
this.f_show = f_tcalShow;
|
||||||
|
this.f_hide = f_tcalHide;
|
||||||
|
this.f_toggle = f_tcalToggle;
|
||||||
|
this.f_update = f_tcalUpdate;
|
||||||
|
this.f_relDate = f_tcalRelDate;
|
||||||
|
this.f_parseDate = f_tcalParseDate;
|
||||||
|
this.f_generDate = f_tcalGenerDate;
|
||||||
|
|
||||||
|
// create calendar icon
|
||||||
|
this.s_iconId = 'tcalico_' + this.s_id;
|
||||||
|
this.e_icon = f_getElement(this.s_iconId);
|
||||||
|
if (!this.e_icon) {
|
||||||
|
document.write('<img src="' + a_tpl.imgpath + 'cal.gif" id="' + this.s_iconId + '" onclick="A_TCALS[\'' + this.s_id + '\'].f_toggle()" class="tcalIcon" alt="Open Calendar" />');
|
||||||
|
this.e_icon = f_getElement(this.s_iconId);
|
||||||
|
}
|
||||||
|
// save received parameters
|
||||||
|
this.a_cfg = a_cfg;
|
||||||
|
this.a_tpl = a_tpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_tcalShow (d_date) {
|
||||||
|
|
||||||
|
// find input field
|
||||||
|
if (!this.a_cfg.controlname)
|
||||||
|
throw("TC: control name is not specified");
|
||||||
|
if (this.a_cfg.formname) {
|
||||||
|
var e_form = document.forms[this.a_cfg.formname];
|
||||||
|
if (!e_form)
|
||||||
|
throw("TC: form '" + this.a_cfg.formname + "' can not be found");
|
||||||
|
this.e_input = e_form.elements[this.a_cfg.controlname];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this.e_input = f_getElement(this.a_cfg.controlname);
|
||||||
|
|
||||||
|
if (!this.e_input || !this.e_input.tagName || this.e_input.tagName != 'INPUT')
|
||||||
|
throw("TC: element '" + this.a_cfg.controlname + "' does not exist in "
|
||||||
|
+ (this.a_cfg.formname ? "form '" + this.a_cfg.controlname + "'" : 'this document'));
|
||||||
|
|
||||||
|
// dynamically create HTML elements if needed
|
||||||
|
this.e_div = f_getElement('tcal');
|
||||||
|
if (!this.e_div) {
|
||||||
|
this.e_div = document.createElement("DIV");
|
||||||
|
this.e_div.id = 'tcal';
|
||||||
|
document.body.appendChild(this.e_div);
|
||||||
|
}
|
||||||
|
this.e_shade = f_getElement('tcalShade');
|
||||||
|
if (!this.e_shade) {
|
||||||
|
this.e_shade = document.createElement("DIV");
|
||||||
|
this.e_shade.id = 'tcalShade';
|
||||||
|
document.body.appendChild(this.e_shade);
|
||||||
|
}
|
||||||
|
this.e_iframe = f_getElement('tcalIF')
|
||||||
|
if (b_ieFix && !this.e_iframe) {
|
||||||
|
this.e_iframe = document.createElement("IFRAME");
|
||||||
|
this.e_iframe.style.filter = 'alpha(opacity=0)';
|
||||||
|
this.e_iframe.id = 'tcalIF';
|
||||||
|
this.e_iframe.src = this.a_tpl.imgpath + 'pixel.gif';
|
||||||
|
document.body.appendChild(this.e_iframe);
|
||||||
|
}
|
||||||
|
|
||||||
|
// hide all calendars
|
||||||
|
f_tcalHideAll();
|
||||||
|
|
||||||
|
// generate HTML and show calendar
|
||||||
|
this.e_icon = f_getElement(this.s_iconId);
|
||||||
|
if (!this.f_update())
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.e_div.style.visibility = 'visible';
|
||||||
|
this.e_shade.style.visibility = 'visible';
|
||||||
|
if (this.e_iframe)
|
||||||
|
this.e_iframe.style.visibility = 'visible';
|
||||||
|
|
||||||
|
// change icon and status
|
||||||
|
this.e_icon.src = this.a_tpl.imgpath + 'no_cal.gif';
|
||||||
|
this.e_icon.title = 'Close Calendar';
|
||||||
|
this.b_visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_tcalHide (n_date) {
|
||||||
|
if (n_date)
|
||||||
|
this.e_input.value = this.f_generDate(new Date(n_date));
|
||||||
|
|
||||||
|
// no action if not visible
|
||||||
|
if (!this.b_visible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// hide elements
|
||||||
|
if (this.e_iframe)
|
||||||
|
this.e_iframe.style.visibility = 'hidden';
|
||||||
|
if (this.e_shade)
|
||||||
|
this.e_shade.style.visibility = 'hidden';
|
||||||
|
this.e_div.style.visibility = 'hidden';
|
||||||
|
|
||||||
|
// change icon and status
|
||||||
|
this.e_icon = f_getElement(this.s_iconId);
|
||||||
|
this.e_icon.src = this.a_tpl.imgpath + 'cal.gif';
|
||||||
|
this.e_icon.title = 'Open Calendar';
|
||||||
|
this.b_visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_tcalToggle () {
|
||||||
|
return this.b_visible ? this.f_hide() : this.f_show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_tcalUpdate (d_date) {
|
||||||
|
|
||||||
|
var d_today = this.a_cfg.today ? this.f_parseDate(this.a_cfg.today) : f_tcalResetTime(new Date());
|
||||||
|
var d_selected = this.e_input.value == ''
|
||||||
|
? (this.a_cfg.selected ? this.f_parseDate(this.a_cfg.selected) : d_today)
|
||||||
|
: this.f_parseDate(this.e_input.value);
|
||||||
|
|
||||||
|
// figure out date to display
|
||||||
|
if (!d_date)
|
||||||
|
// selected by default
|
||||||
|
d_date = d_selected;
|
||||||
|
else if (typeof(d_date) == 'number')
|
||||||
|
// get from number
|
||||||
|
d_date = f_tcalResetTime(new Date(d_date));
|
||||||
|
else if (typeof(d_date) == 'string')
|
||||||
|
// parse from string
|
||||||
|
this.f_parseDate(d_date);
|
||||||
|
|
||||||
|
if (!d_date) return false;
|
||||||
|
|
||||||
|
// first date to display
|
||||||
|
var d_firstday = new Date(d_date);
|
||||||
|
d_firstday.setDate(1);
|
||||||
|
d_firstday.setDate(1 - (7 + d_firstday.getDay() - this.a_tpl.weekstart) % 7);
|
||||||
|
|
||||||
|
var a_class, s_html = '<table class="ctrl"><tbody><tr>'
|
||||||
|
+ (this.a_tpl.yearscroll ? '<td' + this.f_relDate(d_date, -1, 'y') + ' title="Previous Year"><img src="' + this.a_tpl.imgpath + 'prev_year.gif" /></td>' : '')
|
||||||
|
+ '<td' + this.f_relDate(d_date, -1) + ' title="Previous Month"><img src="' + this.a_tpl.imgpath + 'prev_mon.gif" /></td><th>'
|
||||||
|
+ this.a_tpl.months[d_date.getMonth()] + ' ' + d_date.getFullYear()
|
||||||
|
+ '</th><td' + this.f_relDate(d_date, 1) + ' title="Next Month"><img src="' + this.a_tpl.imgpath + 'next_mon.gif" /></td>'
|
||||||
|
+ (this.a_tpl.yearscroll ? '<td' + this.f_relDate(d_date, 1, 'y') + ' title="Next Year"><img src="' + this.a_tpl.imgpath + 'next_year.gif" /></td></td>' : '')
|
||||||
|
+ '</tr></tbody></table><table><tbody><tr class="wd">';
|
||||||
|
|
||||||
|
// print weekdays titles
|
||||||
|
for (var i = 0; i < 7; i++)
|
||||||
|
s_html += '<th>' + this.a_tpl.weekdays[(this.a_tpl.weekstart + i) % 7] + '</th>';
|
||||||
|
s_html += '</tr>' ;
|
||||||
|
|
||||||
|
// print calendar table
|
||||||
|
var n_date, n_month, d_current = new Date(d_firstday);
|
||||||
|
while (d_current.getMonth() == d_date.getMonth() ||
|
||||||
|
d_current.getMonth() == d_firstday.getMonth()) {
|
||||||
|
|
||||||
|
// print row heder
|
||||||
|
s_html +='<tr>';
|
||||||
|
for (var n_wday = 0; n_wday < 7; n_wday++) {
|
||||||
|
|
||||||
|
a_class = [];
|
||||||
|
n_date = d_current.getDate();
|
||||||
|
n_month = d_current.getMonth();
|
||||||
|
|
||||||
|
// other month
|
||||||
|
if (d_current.getMonth() != d_date.getMonth())
|
||||||
|
a_class[a_class.length] = 'othermonth';
|
||||||
|
// weekend
|
||||||
|
if (d_current.getDay() == 0 || d_current.getDay() == 6)
|
||||||
|
a_class[a_class.length] = 'weekend';
|
||||||
|
// today
|
||||||
|
if (d_current.valueOf() == d_today.valueOf())
|
||||||
|
a_class[a_class.length] = 'today';
|
||||||
|
// selected
|
||||||
|
if (d_current.valueOf() == d_selected.valueOf())
|
||||||
|
a_class[a_class.length] = 'selected';
|
||||||
|
|
||||||
|
s_html += '<td onclick="A_TCALS[\'' + this.s_id + '\'].f_hide(' + d_current.valueOf() + ')"' + (a_class.length ? ' class="' + a_class.join(' ') + '">' : '>') + n_date + '</td>'
|
||||||
|
|
||||||
|
d_current.setDate(++n_date);
|
||||||
|
while (d_current.getDate() != n_date && d_current.getMonth() == n_month) {
|
||||||
|
d_current.setHours(d_current.getHours + 1);
|
||||||
|
d_current = f_tcalResetTime(d_current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// print row footer
|
||||||
|
s_html +='</tr>';
|
||||||
|
}
|
||||||
|
s_html +='</tbody></table>';
|
||||||
|
|
||||||
|
// update HTML, positions and sizes
|
||||||
|
this.e_div.innerHTML = s_html;
|
||||||
|
|
||||||
|
var n_width = this.e_div.offsetWidth;
|
||||||
|
var n_height = this.e_div.offsetHeight;
|
||||||
|
var n_top = f_getPosition (this.e_icon, 'Top') + this.e_icon.offsetHeight;
|
||||||
|
var n_left = f_getPosition (this.e_icon, 'Left') - n_width + this.e_icon.offsetWidth;
|
||||||
|
if (n_left < 0) n_left = 0;
|
||||||
|
|
||||||
|
this.e_div.style.left = n_left + 'px';
|
||||||
|
this.e_div.style.top = n_top + 'px';
|
||||||
|
|
||||||
|
this.e_shade.style.width = (n_width + 8) + 'px';
|
||||||
|
this.e_shade.style.left = (n_left - 1) + 'px';
|
||||||
|
this.e_shade.style.top = (n_top - 1) + 'px';
|
||||||
|
this.e_shade.innerHTML = b_ieFix
|
||||||
|
? '<table><tbody><tr><td rowspan="2" colspan="2" width="6"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td><td width="7" height="7" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + this.a_tpl.imgpath + 'shade_tr.png\', sizingMethod=\'scale\');"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td></tr><tr><td height="' + (n_height - 7) + '" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + this.a_tpl.imgpath + 'shade_mr.png\', sizingMethod=\'scale\');"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td></tr><tr><td width="7" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + this.a_tpl.imgpath + 'shade_bl.png\', sizingMethod=\'scale\');"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td><td style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + this.a_tpl.imgpath + 'shade_bm.png\', sizingMethod=\'scale\');" height="7" align="left"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td><td style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + this.a_tpl.imgpath + 'shade_br.png\', sizingMethod=\'scale\');"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td></tr><tbody></table>'
|
||||||
|
: '<table><tbody><tr><td rowspan="2" width="6"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td><td rowspan="2"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td><td width="7" height="7"><img src="' + this.a_tpl.imgpath + 'shade_tr.png"></td></tr><tr><td background="' + this.a_tpl.imgpath + 'shade_mr.png" height="' + (n_height - 7) + '"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td></tr><tr><td><img src="' + this.a_tpl.imgpath + 'shade_bl.png"></td><td background="' + this.a_tpl.imgpath + 'shade_bm.png" height="7" align="left"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td><td><img src="' + this.a_tpl.imgpath + 'shade_br.png"></td></tr><tbody></table>';
|
||||||
|
|
||||||
|
if (this.e_iframe) {
|
||||||
|
this.e_iframe.style.left = n_left + 'px';
|
||||||
|
this.e_iframe.style.top = n_top + 'px';
|
||||||
|
this.e_iframe.style.width = (n_width + 6) + 'px';
|
||||||
|
this.e_iframe.style.height = (n_height + 6) +'px';
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_getPosition (e_elemRef, s_coord) {
|
||||||
|
var n_pos = 0, n_offset,
|
||||||
|
e_elem = e_elemRef;
|
||||||
|
|
||||||
|
while (e_elem) {
|
||||||
|
n_offset = e_elem["offset" + s_coord];
|
||||||
|
n_pos += n_offset;
|
||||||
|
e_elem = e_elem.offsetParent;
|
||||||
|
}
|
||||||
|
// margin correction in some browsers
|
||||||
|
if (b_ieMac)
|
||||||
|
n_pos += parseInt(document.body[s_coord.toLowerCase() + 'Margin']);
|
||||||
|
else if (b_safari)
|
||||||
|
n_pos -= n_offset;
|
||||||
|
|
||||||
|
e_elem = e_elemRef;
|
||||||
|
while (e_elem != document.body) {
|
||||||
|
n_offset = e_elem["scroll" + s_coord];
|
||||||
|
if (n_offset && e_elem.style.overflow == 'scroll')
|
||||||
|
n_pos -= n_offset;
|
||||||
|
e_elem = e_elem.parentNode;
|
||||||
|
}
|
||||||
|
return n_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_tcalRelDate (d_date, d_diff, s_units) {
|
||||||
|
var s_units = (s_units == 'y' ? 'FullYear' : 'Month');
|
||||||
|
var d_result = new Date(d_date);
|
||||||
|
d_result['set' + s_units](d_date['get' + s_units]() + d_diff);
|
||||||
|
if (d_result.getDate() != d_date.getDate())
|
||||||
|
d_result.setDate(0);
|
||||||
|
return ' onclick="A_TCALS[\'' + this.s_id + '\'].f_update(' + d_result.valueOf() + ')"';
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_tcalHideAll ()
|
||||||
|
{
|
||||||
|
if (!window.A_TCALSIDX)
|
||||||
|
{var nothing=1;}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (var i = 0; i < window.A_TCALSIDX.length; i++)
|
||||||
|
{window.A_TCALSIDX[i].f_hide();}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_tcalResetTime (d_date) {
|
||||||
|
d_date.setHours(0);
|
||||||
|
d_date.setMinutes(0);
|
||||||
|
d_date.setSeconds(0);
|
||||||
|
d_date.setMilliseconds(0);
|
||||||
|
return d_date;
|
||||||
|
}
|
||||||
|
|
||||||
|
f_getElement = document.all ?
|
||||||
|
function (s_id) { return document.all[s_id] } :
|
||||||
|
function (s_id) { return document.getElementById(s_id) };
|
||||||
|
|
||||||
|
if (document.addEventListener)
|
||||||
|
window.addEventListener('scroll', f_tcalHideAll, false);
|
||||||
|
if (window.attachEvent)
|
||||||
|
window.attachEvent('onscroll', f_tcalHideAll);
|
||||||
|
|
||||||
|
// global variables
|
||||||
|
var s_userAgent = navigator.userAgent.toLowerCase(),
|
||||||
|
re_webkit = /WebKit\/(\d+)/i;
|
||||||
|
var b_mac = s_userAgent.indexOf('mac') != -1,
|
||||||
|
b_ie5 = s_userAgent.indexOf('msie 5') != -1,
|
||||||
|
b_ie6 = s_userAgent.indexOf('msie 6') != -1 && s_userAgent.indexOf('opera') == -1;
|
||||||
|
var b_ieFix = b_ie5 || b_ie6,
|
||||||
|
b_ieMac = b_mac && b_ie5,
|
||||||
|
b_safari = b_mac && re_webkit.exec(s_userAgent) && Number(RegExp.$1) < 500;
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
<?php
|
||||||
|
#
|
||||||
|
# dbconnect_mysqli.php version 2.12
|
||||||
|
#
|
||||||
|
# database connection settings and some global web settings
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGES:
|
||||||
|
# 130328-0022 - Converted ereg to preg functions
|
||||||
|
# 130802-0957 - Changed to PHP mysqli functions, added
|
||||||
|
# 131101-0713 - Fixed slave server setting
|
||||||
|
# 131210-1746 - Added ability to define slave server with port number, issue #687
|
||||||
|
# 150216-1529 - Removed non-latin set to 0
|
||||||
|
# 150313-0913 - Added ExpectedDBSchema conf file value
|
||||||
|
# 150626-2120 - Modified mysqli_error() to mysqli_connect_error() where appropriate
|
||||||
|
# 160325-1434 - Changes for sidebar update
|
||||||
|
# 220827-1948 - VERM version
|
||||||
|
#
|
||||||
|
|
||||||
|
if ( file_exists("/etc/astguiclient.conf") )
|
||||||
|
{
|
||||||
|
$DBCagc = file("/etc/astguiclient.conf");
|
||||||
|
foreach ($DBCagc as $DBCline)
|
||||||
|
{
|
||||||
|
$DBCline = preg_replace("/ |>|\n|\r|\t|\#.*|;.*/","",$DBCline);
|
||||||
|
if (preg_match("/^PATHlogs/", $DBCline))
|
||||||
|
{$PATHlogs = $DBCline; $PATHlogs = preg_replace("/.*=/","",$PATHlogs);}
|
||||||
|
if (preg_match("/^PATHweb/", $DBCline))
|
||||||
|
{$WeBServeRRooT = $DBCline; $WeBServeRRooT = preg_replace("/.*=/","",$WeBServeRRooT);}
|
||||||
|
if (preg_match("/^VARserver_ip/", $DBCline))
|
||||||
|
{$WEBserver_ip = $DBCline; $WEBserver_ip = preg_replace("/.*=/","",$WEBserver_ip);}
|
||||||
|
if (preg_match("/^VARDB_server/", $DBCline))
|
||||||
|
{$VARDB_server = $DBCline; $VARDB_server = preg_replace("/.*=/","",$VARDB_server);}
|
||||||
|
if (preg_match("/^VARDB_database/", $DBCline))
|
||||||
|
{$VARDB_database = $DBCline; $VARDB_database = preg_replace("/.*=/","",$VARDB_database);}
|
||||||
|
if (preg_match("/^VARDB_user/", $DBCline))
|
||||||
|
{$VARDB_user = $DBCline; $VARDB_user = preg_replace("/.*=/","",$VARDB_user);}
|
||||||
|
if (preg_match("/^VARDB_pass/", $DBCline))
|
||||||
|
{$VARDB_pass = $DBCline; $VARDB_pass = preg_replace("/.*=/","",$VARDB_pass);}
|
||||||
|
if (preg_match('/^VARDB_custom_user/', $DBCline))
|
||||||
|
{$VARDB_custom_user = $DBCline; $VARDB_custom_user = preg_replace("/.*=/","",$VARDB_custom_user);}
|
||||||
|
if (preg_match('/^VARDB_custom_pass/', $DBCline))
|
||||||
|
{$VARDB_custom_pass = $DBCline; $VARDB_custom_pass = preg_replace("/.*=/","",$VARDB_custom_pass);}
|
||||||
|
if (preg_match("/^VARDB_port/", $DBCline))
|
||||||
|
{$VARDB_port = $DBCline; $VARDB_port = preg_replace("/.*=/","",$VARDB_port);}
|
||||||
|
if (preg_match("/^ExpectedDBSchema/", $DBCline))
|
||||||
|
{$ExpectedDBSchema = $DBCline; $ExpectedDBSchema = preg_replace("/.*=/","",$ExpectedDBSchema);}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#defaults for DB connection
|
||||||
|
$VARDB_server = 'localhost';
|
||||||
|
$VARDB_port = '3306';
|
||||||
|
$VARDB_user = 'cron';
|
||||||
|
$VARDB_pass = '1234';
|
||||||
|
$VARDB_custom_user = 'custom';
|
||||||
|
$VARDB_custom_pass = 'custom1234';
|
||||||
|
$VARDB_database = '1234';
|
||||||
|
$WeBServeRRooT = '/usr/local/apache2/htdocs';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$server_string = $VARDB_server;
|
||||||
|
if ( ($use_slave_server > 0) and (strlen($slave_db_server)>1) )
|
||||||
|
{
|
||||||
|
if (preg_match("/\:/", $slave_db_server))
|
||||||
|
{
|
||||||
|
$temp_slave_db = explode(':',$slave_db_server);
|
||||||
|
$server_string = $temp_slave_db[0];
|
||||||
|
$VARDB_port = $temp_slave_db[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$server_string = $slave_db_server;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$link=mysqli_connect($server_string, "$VARDB_user", "$VARDB_pass", "$VARDB_database", $VARDB_port);
|
||||||
|
|
||||||
|
if (!$link)
|
||||||
|
{
|
||||||
|
// die("MySQL connect ERROR: |$server_string|$VARDB_user|$VARDB_pass|$VARDB_database|$VARDB_port|$temp_slave_db[0]|$temp_slave_db[1]|$slave_db_server|$use_slave_server|" . mysqli_error('mysqli'));
|
||||||
|
die("MySQL connect ERROR: " . mysqli_connect_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
$local_DEF = 'Local/';
|
||||||
|
$conf_silent_prefix = '7';
|
||||||
|
$local_AMP = '@';
|
||||||
|
$ext_context = 'default';
|
||||||
|
$recording_exten = '8309';
|
||||||
|
$WeBRooTWritablE = '1';
|
||||||
|
# $non_latin = '0'; # set to 1 for UTF rules, overridden by system_settings
|
||||||
|
$flag_channels=0;
|
||||||
|
$flag_string = 'VICIast20';
|
||||||
|
$Msubhead_color = '#E6E6E6';
|
||||||
|
$Mselected_color = '#C6C6C6';
|
||||||
|
$Mhead_color = '#A3C3D6';
|
||||||
|
$Mmain_bgcolor = '#015B91';
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -0,0 +1,647 @@
|
|||||||
|
<?php
|
||||||
|
# display_agent_details.php - Vicidial Enhanced Reporting agent details page
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1612 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
require("functions.php");
|
||||||
|
require("VERM_options.php");
|
||||||
|
require("VERM_global_vars.inc");
|
||||||
|
|
||||||
|
if (isset($_GET["user"])) {$user=$_GET["user"];}
|
||||||
|
elseif (isset($_POST["user"])) {$user=$_POST["user"];}
|
||||||
|
if (isset($_GET["campaign_id"])) {$campaign_id=$_GET["campaign_id"];}
|
||||||
|
elseif (isset($_POST["campaign_id"])) {$campaign_id=$_POST["campaign_id"];}
|
||||||
|
if (isset($_GET["users"])) {$users=$_GET["users"];}
|
||||||
|
elseif (isset($_POST["users"])) {$users=$_POST["users"];}
|
||||||
|
if (isset($_GET["user_group"])) {$user_group=$_GET["user_group"];}
|
||||||
|
elseif (isset($_POST["user_group"])) {$user_group=$_POST["user_group"];}
|
||||||
|
if (isset($_GET["location"])) {$location=$_GET["location"];}
|
||||||
|
elseif (isset($_POST["location"])) {$location=$_POST["location"];}
|
||||||
|
if (isset($_GET["status"])) {$status=$_GET["status"];}
|
||||||
|
elseif (isset($_POST["status"])) {$status=$_POST["status"];}
|
||||||
|
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["start_datetime"])) {$start_datetime=$_GET["start_datetime"];}
|
||||||
|
elseif (isset($_POST["start_datetime"])) {$start_datetime=$_POST["start_datetime"];}
|
||||||
|
if (isset($_GET["end_datetime"])) {$end_datetime=$_GET["end_datetime"];}
|
||||||
|
elseif (isset($_POST["end_datetime"])) {$end_datetime=$_POST["end_datetime"];}
|
||||||
|
if (isset($_GET["total_duration_His"])) {$total_duration_His=$_GET["total_duration_His"];}
|
||||||
|
elseif (isset($_POST["total_duration_His"])) {$total_duration_His=$_POST["total_duration_His"];}
|
||||||
|
if (isset($_GET["total_pause_His"])) {$total_pause_His=$_GET["total_pause_His"];}
|
||||||
|
elseif (isset($_POST["total_pause_His"])) {$total_pause_His=$_POST["total_pause_His"];}
|
||||||
|
if (isset($_GET["total_all_billable_His"])) {$total_all_billable_His=$_GET["total_all_billable_His"];}
|
||||||
|
elseif (isset($_POST["total_all_billable_His"])) {$total_all_billable_His=$_POST["total_all_billable_His"];}
|
||||||
|
if (isset($_GET["total_billable_His"])) {$total_billable_His=$_GET["total_billable_His"];}
|
||||||
|
elseif (isset($_POST["total_billable_His"])) {$total_billable_His=$_POST["total_billable_His"];}
|
||||||
|
|
||||||
|
# $report_name="Vox Enhanced Reporting Module - Agent detail display";
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
##### 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;";
|
||||||
|
$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];
|
||||||
|
$outbound_autodial_active = $row[1];
|
||||||
|
$slave_db_server = $row[2];
|
||||||
|
$reports_use_slave_db = $row[3];
|
||||||
|
$SSenable_languages = $row[4];
|
||||||
|
$SSlanguage_method = $row[5];
|
||||||
|
$agent_whisper_enabled = $row[6];
|
||||||
|
$SSreport_default_format = $row[7];
|
||||||
|
$SSenable_pause_code_limits = $row[8];
|
||||||
|
$SSallow_web_debug = $row[9];
|
||||||
|
$SSadmin_screen_colors = $row[10];
|
||||||
|
$SSadmin_web_directory = $row[11];
|
||||||
|
}
|
||||||
|
if ($SSallow_web_debug < 1) {$DB=0;}
|
||||||
|
##### END SETTINGS LOOKUP #####
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
$NWB = "<IMG SRC=\"help.png\" onClick=\"FillAndShowHelpDiv(event, '";
|
||||||
|
$NWE = "')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP>";
|
||||||
|
|
||||||
|
$start_datetime=preg_replace('/[^\s\-0-9\:]/', '', $start_datetime);
|
||||||
|
$end_datetime=preg_replace('/[^\s\-0-9\:]/', '', $end_datetime);
|
||||||
|
$total_duration_His=preg_replace('/[^0-9\:]/', '', $total_duration_His);
|
||||||
|
$total_pause_His=preg_replace('/[^0-9\:]/', '', $total_pause_His);
|
||||||
|
$total_all_billable_His=preg_replace('/[^0-9\:]/', '', $total_all_billable_His);
|
||||||
|
$total_billable_His=preg_replace('/[^0-9\:]/', '', $total_billable_His);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
$download_rpt = preg_replace('/[^\._0-9a-zA-Z]/','',$download_rpt);
|
||||||
|
$user = preg_replace('/[^\-_0-9a-zA-Z]/','',$user);
|
||||||
|
$users = preg_replace('/[^\-_0-9a-zA-Z]/','',$users);
|
||||||
|
$user_group = preg_replace('/[^\-_0-9a-zA-Z]/','',$user_group);
|
||||||
|
$campaign_id = preg_replace('/[^\-_0-9a-zA-Z]/','',$campaign_id);
|
||||||
|
$location = preg_replace('/[^\- \.\,\_0-9a-zA-Z]/','',$location);
|
||||||
|
$status = preg_replace('/[^\- \.\,\_0-9a-zA-Z]/','',$status);
|
||||||
|
$vicidial_queue_groups = preg_replace('/[^-_0-9a-zA-Z]/','',$vicidial_queue_groups);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
$download_rpt = preg_replace('/[^\._0-9\p{L}]/u','',$download_rpt);
|
||||||
|
$user = preg_replace('/[^-_0-9\p{L}]/u','',$user);
|
||||||
|
$users = preg_replace('/[^-_0-9\p{L}]/u','',$users);
|
||||||
|
$user_group = preg_replace('/[^-_0-9\p{L}/u','',$user_group);
|
||||||
|
$campaign_id = preg_replace('/[^-_0-9\p{L}/u','',$campaign_id);
|
||||||
|
$location = preg_replace('/[^- \.\,\_0-9\p{L}]/u','',$location);
|
||||||
|
$status = preg_replace('/[^- \.\,\_0-9\p{L}]/u','',$status);
|
||||||
|
$vicidial_queue_groups = preg_replace('/[^-_0-9\p{L}]/u','',$vicidial_queue_groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!$user || !$start_datetime || !$end_datetime) {echo "Missing information - needs a minimum of: user, start date/time, end date/time"; die;}
|
||||||
|
|
||||||
|
function RemoveEmptyArrayStrings($array)
|
||||||
|
{
|
||||||
|
if (is_array($array))
|
||||||
|
{
|
||||||
|
for ($i=0; $i<count($array); $i++)
|
||||||
|
{
|
||||||
|
if ($array[$i]=="") {unset($array[$i]);}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#### CLAUSE GENERATION ####
|
||||||
|
|
||||||
|
$where_event_time_sql="where event_time>='$start_datetime' and event_time<='$end_datetime' ";
|
||||||
|
$where_event_date_sql="where event_date>='$start_datetime' and event_date<='$end_datetime' ";
|
||||||
|
|
||||||
|
#### QUEUE GROUPS ####
|
||||||
|
$vicidial_queue_groups=preg_replace('/[^-_0-9\p{L}]/u','',$vicidial_queue_groups);
|
||||||
|
$vicidial_queue_groups=RemoveEmptyArrayStrings($vicidial_queue_groups);
|
||||||
|
|
||||||
|
if ($vicidial_queue_groups)
|
||||||
|
{
|
||||||
|
$vqg_stmt="select included_campaigns, included_inbound_groups from vicidial_queue_groups where queue_group='$vicidial_queue_groups'";
|
||||||
|
$vqg_rslt=mysql_to_mysqli($vqg_stmt, $link);
|
||||||
|
if(mysqli_num_rows($vqg_rslt)>0)
|
||||||
|
{
|
||||||
|
$vqg_row=mysqli_fetch_array($vqg_rslt);
|
||||||
|
$included_campaigns=trim(preg_replace('/\s\-$/', '', $vqg_row["included_campaigns"]));
|
||||||
|
$included_campaigns_clause="and campaign_id in ('".preg_replace('/\s/', "', '", $included_campaigns)."')";
|
||||||
|
$included_inbound_groups=trim(preg_replace('/\s\-$/', '', $vqg_row["included_inbound_groups"]));
|
||||||
|
$included_inbound_groups_clause="and group_id in ('".preg_replace('/\s/', "', '", $included_inbound_groups)."')";
|
||||||
|
$where_included_inbound_groups_clause="where group_id in ('".preg_replace('/\s/', "', '", $included_inbound_groups)."')";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get final list of 'atomic queues'
|
||||||
|
$atomic_queue_str="";
|
||||||
|
|
||||||
|
$atomic_queue_campaigns_str="";
|
||||||
|
$campaign_id_stmt="select campaign_id, campaign_name from vicidial_campaigns where campaign_id is not null $included_campaigns_clause order by campaign_id"; # $LOGallowed_campaignsSQL, removed for now per Matt's assurances
|
||||||
|
$campaign_id_rslt=mysql_to_mysqli($campaign_id_stmt, $link);
|
||||||
|
while($campaign_id_row=mysqli_fetch_array($campaign_id_rslt))
|
||||||
|
{
|
||||||
|
$atomic_queue_str.=$campaign_id_row["campaign_name"];
|
||||||
|
$atomic_queue_str.=" <i>[".$campaign_id_row["campaign_id"]."]</i>,";
|
||||||
|
$atomic_queue_campaigns_str.="$campaign_id_row[campaign_id]', '";
|
||||||
|
}
|
||||||
|
# 01/26/2022 - Fix, maybe a little too lax?
|
||||||
|
if ($atomic_queue_campaigns_str)
|
||||||
|
{
|
||||||
|
$and_atomic_queue_campaigns_clause="and campaign_id in ('".$atomic_queue_campaigns_str."') ";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if queue settings override user group settings
|
||||||
|
$closer_campaigns_stmt="select closer_campaigns from vicidial_campaigns where closer_campaigns is not null $LOGallowed_campaignsSQL"; # $included_campaigns_clause
|
||||||
|
$closer_campaigns_rslt=mysql_to_mysqli($closer_campaigns_stmt, $link);
|
||||||
|
$allowed_ingroups_array=array();
|
||||||
|
while ($closer_campaigns_row=mysqli_fetch_array($closer_campaigns_rslt))
|
||||||
|
{
|
||||||
|
$closer_campaigns_array=explode(" ", trim(preg_replace('/\s\-$/', '', $closer_campaigns_row["closer_campaigns"])));
|
||||||
|
for ($i=0; $i<count($closer_campaigns_array); $i++)
|
||||||
|
{
|
||||||
|
if (!in_array($closer_campaigns_array[$i], $allowed_ingroups_array))
|
||||||
|
{
|
||||||
|
array_push($allowed_ingroups_array, $closer_campaigns_array[$i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$atomic_queue_ingroups_str="";
|
||||||
|
$ingroups_id_stmt="select group_id, group_name from vicidial_inbound_groups $where_included_inbound_groups_clause"; #where group_id in ('".implode("', '", $allowed_ingroups_array)."') $included_inbound_groups_clause
|
||||||
|
$ingroups_id_rslt=mysql_to_mysqli($ingroups_id_stmt, $link);
|
||||||
|
while($ingroups_id_row=mysqli_fetch_array($ingroups_id_rslt))
|
||||||
|
{
|
||||||
|
$atomic_queue_str.=$ingroups_id_row["group_name"];
|
||||||
|
$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."')";
|
||||||
|
$atomic_queue_str=preg_replace('/,$/', '', $atomic_queue_str);
|
||||||
|
|
||||||
|
if (strlen($atomic_queue_str)==0)
|
||||||
|
{
|
||||||
|
$atomic_queue_str="NONE";
|
||||||
|
}
|
||||||
|
|
||||||
|
$vicidial_agent_log_SQL.="$and_atomic_queue_campaigns_clause";
|
||||||
|
$vicidial_log_SQL.="$and_atomic_queue_campaigns_clause";
|
||||||
|
$vicidial_closer_log_SQL.="$and_atomic_queue_ingroups_clause";
|
||||||
|
$vicidial_user_log_SQL.="$and_atomic_queue_campaigns_clause";
|
||||||
|
|
||||||
|
#### END QUEUE GROUPS ####
|
||||||
|
|
||||||
|
# For calls from the AGENT SESSIONS report
|
||||||
|
if ($user)
|
||||||
|
{
|
||||||
|
$user=preg_replace('/[^-_0-9\p{L}]/u','',$user);
|
||||||
|
$and_user_sql=" and user='$user' ";
|
||||||
|
$where_user_sql=" where user='$user' ";
|
||||||
|
|
||||||
|
$vicidial_agent_log_SQL.=$and_user_sql;
|
||||||
|
$vicidial_log_SQL.=$and_user_sql;
|
||||||
|
$vicidial_closer_log_SQL.=$and_user_sql;
|
||||||
|
$vicidial_user_log_SQL.=$and_user_sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
# For calls from the "QUEUE" SESSIONS report
|
||||||
|
if ($campaign_id)
|
||||||
|
{
|
||||||
|
$campaign_id=preg_replace('/[^-_0-9\p{L}]/u','',$campaign_id);
|
||||||
|
$and_campaign_id_sql=" and campaign_id='$campaign_id' ";
|
||||||
|
$where_campaign_id_sql=" where campaign_id='$campaign_id' ";
|
||||||
|
|
||||||
|
# For closer log - how's this work? Query for closer_campaigns? Or by uniqueids?
|
||||||
|
|
||||||
|
$vicidial_agent_log_SQL.=$and_campaign_id_sql;
|
||||||
|
$vicidial_log_SQL.=$and_campaign_id_sql;
|
||||||
|
$vicidial_closer_log_SQL.=$and_campaign_id_sql;
|
||||||
|
$vicidial_user_log_SQL.=$and_campaign_id_sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* THIS PAGE IS FOR SPECIFIC AGENTS, NOT NECESSARY TO FILTER FOR THIS
|
||||||
|
if ($users)
|
||||||
|
{
|
||||||
|
$users=preg_replace('/[^-_0-9\p{L}]/u','',$users);
|
||||||
|
$users=RemoveEmptyArrayStrings($users);
|
||||||
|
$users_str=is_array($users) ? implode("', '", $users) : "$users";
|
||||||
|
$and_users_sql=" and user in ('$users_str')";
|
||||||
|
$where_users_sql=" where user in ('$users_str')";
|
||||||
|
|
||||||
|
$vicidial_agent_log_SQL.=$and_users_sql;
|
||||||
|
$vicidial_log_SQL.=$and_users_sql;
|
||||||
|
$vicidial_closer_log_SQL.=$and_users_sql;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* THIS PAGE IS FOR SPECIFIC AGENTS, NOT NECESSARY TO FILTER FOR THIS
|
||||||
|
if ($location)
|
||||||
|
{
|
||||||
|
$location=preg_replace('/[^-_0-9\p{L}]/u','',$location);
|
||||||
|
$location=RemoveEmptyArrayStrings($location);
|
||||||
|
$location_str=is_array($location) ? implode("', '", $location) : "$location";
|
||||||
|
$and_location_sql.=" and user_location in ('$location_str')";
|
||||||
|
$where_location_sql.=" where user_location in ('$location_str')";
|
||||||
|
|
||||||
|
# Compile list of additional users based on location
|
||||||
|
$user_location_stmt="select user from vicidial_users where user is not null $LOGadmin_viewable_groupsSQL $and_location_sql";
|
||||||
|
$user_location_rslt=mysql_to_mysqli($user_location_stmt, $link);
|
||||||
|
$users_by_location=array();
|
||||||
|
while ($user_location_row=mysqli_fetch_row($user_location_rslt))
|
||||||
|
{
|
||||||
|
array_push($users_by_location, $user_location_row[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Combine location with selected user
|
||||||
|
if ($users)
|
||||||
|
{
|
||||||
|
array_push($users_by_location, $users);
|
||||||
|
}
|
||||||
|
|
||||||
|
$users_by_location_str=implode("', '", $users_by_location);
|
||||||
|
$and_users_by_location_sql=" and user in ('$users_by_location_str')";
|
||||||
|
$where_users_by_location_sql=" where user in ('$users_by_location_str')";
|
||||||
|
|
||||||
|
$vicidial_agent_log_SQL.=$and_users_by_location_sql;
|
||||||
|
$vicidial_log_SQL.=$and_users_by_location_sql;
|
||||||
|
$vicidial_closer_log_SQL.=$and_users_by_location_sql;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ($user_group)
|
||||||
|
{
|
||||||
|
$user_group=preg_replace('/[^-_0-9\p{L}]/u','',$user_group);
|
||||||
|
$user_group=RemoveEmptyArrayStrings($user_group);
|
||||||
|
$user_group_str=is_array($user_group) ? implode("', '", $user_group) : "$user_group";
|
||||||
|
$and_user_group_sql.=" and user_group in ('$user_group_str') ";
|
||||||
|
$where_user_group_sql.=" where user_group in ('$user_group_str') ";
|
||||||
|
|
||||||
|
$vicidial_agent_log_SQL.=$and_user_group_sql;
|
||||||
|
$vicidial_log_SQL.=$and_user_group_sql;
|
||||||
|
$vicidial_closer_log_SQL.=$and_user_group_sql;
|
||||||
|
$vicidial_user_log_SQL.=$and_user_group_sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($status)
|
||||||
|
{
|
||||||
|
$status=preg_replace('/[^-_0-9\p{L}]/u','',$status);
|
||||||
|
$and_status_sql.=" and status='$status' ";
|
||||||
|
|
||||||
|
$vicidial_agent_log_SQL.=$and_status_sql;
|
||||||
|
$vicidial_log_SQL.=$and_status_sql;
|
||||||
|
$vicidial_closer_log_SQL.=$and_status_sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
$vicidial_agent_log_SQL="$where_event_time_sql".$vicidial_agent_log_SQL;
|
||||||
|
$vicidial_log_SQL="$where_call_date_sql".$vicidial_log_SQL;
|
||||||
|
$vicidial_closer_log_SQL="$where_call_date_sql".$vicidial_closer_log_SQL;
|
||||||
|
$vicidial_user_log_SQL="$where_event_date_sql".$vicidial_user_log_SQL;
|
||||||
|
|
||||||
|
$sort_char="";
|
||||||
|
$sort_index="";
|
||||||
|
|
||||||
|
$sort_clause=" order by call_date";
|
||||||
|
$sort_index=preg_replace('/ desc/', '', $sort_answered_details);
|
||||||
|
if (preg_match('/ desc$/', $sort_answered_details))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_answered_details);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_answered_details." desc";
|
||||||
|
}
|
||||||
|
$sort_answered_details_preg=preg_replace('/ desc$/', '', $sort_answered_details);
|
||||||
|
|
||||||
|
|
||||||
|
#echo "<div style='position:fixed;'>";
|
||||||
|
#echo "<table align='right' border=0 width='100%' bgcolor='#FFF'><tr><td align='right'>";
|
||||||
|
#echo "<a onClick='HideAgentDetails()'><h2 class='rpt_header'>[X]</h2></a>";
|
||||||
|
#echo "</td></tr></table>";
|
||||||
|
#echo "</div>";
|
||||||
|
|
||||||
|
echo "<table border=0 width='100%' bgcolor='#FFF'><tr>";
|
||||||
|
echo "<td align='left'>";
|
||||||
|
#echo "<div style='position:fixed; top: -5; right: -30;'><a onClick='HideAgentDetails()'><h2 class='rpt_header'>[X]</h2></a></div>";
|
||||||
|
#echo "<div align='left'><h2 class='rpt_header'>Agent Detail: $user</h2></div>";
|
||||||
|
echo "<h2 class='rpt_header'>"._QXZ("Agent Detail").": $user $NWB#VERM_display_agent_details$NWE</h2>";
|
||||||
|
echo "</td>";
|
||||||
|
|
||||||
|
echo "<td align='right'>";
|
||||||
|
echo "<a onClick='HideAgentDetails()'><h2 class='rpt_header'>[X]</h2></a>";
|
||||||
|
echo "</td>";
|
||||||
|
echo "</tr>";
|
||||||
|
|
||||||
|
echo "<tr><td colspan='2'>";
|
||||||
|
echo "<span id='all_agent_details' style='display:block; overflow-y:auto; height: 70vh;'>\n";
|
||||||
|
|
||||||
|
echo "<table id=\"rpt_table\">\n";
|
||||||
|
echo " <tr>\n";
|
||||||
|
echo " <td style=\"width:25vw\">"._QXZ("Total session time").":</th>\n";
|
||||||
|
echo " <td style=\"width:75vw\">$total_duration_His</td>\n";
|
||||||
|
echo " </tr>\n";
|
||||||
|
echo " <tr>\n";
|
||||||
|
echo " <td style=\"width:25vw\">"._QXZ("Total pause time").":</td>\n";
|
||||||
|
echo " <td style=\"width:75vw\">$total_pause_His</td>\n";
|
||||||
|
echo " </tr>\n";
|
||||||
|
echo " <tr>\n";
|
||||||
|
echo " <td style=\"width:25vw\">"._QXZ("Total billable time (b. pauses + talk + wait + dispo)").":</td>\n";
|
||||||
|
echo " <td style=\"width:75vw\">$total_all_billable_His</td>\n";
|
||||||
|
echo " </tr>\n";
|
||||||
|
echo " <tr>\n";
|
||||||
|
echo " <td style=\"width:25vw\">"._QXZ("Total billable pauses").":</td>\n";
|
||||||
|
echo " <td style=\"width:75vw\">$total_billable_His</td>\n";
|
||||||
|
echo " </tr>\n";
|
||||||
|
echo "</table>\n";
|
||||||
|
|
||||||
|
echo "<hr style='height:2px;border-width:0;color:#ddd;background-color:#ddd;margin-bottom: 2em;'>";
|
||||||
|
|
||||||
|
### FUN STUFF
|
||||||
|
# Clause to deal with odd occurrence where agent's first record for the day is a LOGOUT (see Jamar Jenkins for 01/21/2022)
|
||||||
|
$event_date_clause_apx="";
|
||||||
|
if (!$overnight_agents)
|
||||||
|
{
|
||||||
|
$init_start_stmt="select min(event_date) from vicidial_user_log $vicidial_user_log_SQL and event='LOGIN' and user='$user'";
|
||||||
|
# print $init_start_stmt."<BR>\n";
|
||||||
|
$init_start_rslt=mysql_to_mysqli($init_start_stmt, $link);
|
||||||
|
if (mysqli_num_rows($init_start_rslt)>0)
|
||||||
|
{
|
||||||
|
$isr_row=mysqli_fetch_row($init_start_rslt);
|
||||||
|
$event_date_clause_apx=" and event_date>='$isr_row[0]' ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$session_stmt="select * from vicidial_user_log $vicidial_user_log_SQL $event_date_clause_apx and event in ('LOGIN', 'LOGOUT', 'TIMEOUTLOGOUT') and user='$user' order by event_date asc";
|
||||||
|
if ($DB) {$HTML_output.="<B>$session_stmt</B>";}
|
||||||
|
# print "$session_stmt<BR>\n";
|
||||||
|
$session_rslt=mysql_to_mysqli($session_stmt, $link);
|
||||||
|
$prev_date="";
|
||||||
|
$start_event_date="";
|
||||||
|
|
||||||
|
### ITERATE THROUGH ALL THE AGENTS SESSIONS MATCHING THE REPORT CRITERIA
|
||||||
|
$row_no=0; $agent_logged_in=0;
|
||||||
|
$agent_sessions_array=array();
|
||||||
|
while ($session_row=mysqli_fetch_array($session_rslt))
|
||||||
|
{
|
||||||
|
# Need this for when the report runs with a start date right in the middle of agents logged in
|
||||||
|
$original_session_start_date="$start_datetime";
|
||||||
|
$original_session_cutoff_date=substr($start_datetime, 10)." 00:00:00";
|
||||||
|
$original_session_cutoff_eod=substr($start_datetime, 10)." 23:59:59";
|
||||||
|
|
||||||
|
$user=$session_row["user"];
|
||||||
|
$campaign_id=$session_row["campaign_id"];
|
||||||
|
$extension=$session_row["extension"];
|
||||||
|
$event=$session_row["event"];
|
||||||
|
$event_epoch=$session_row["event_epoch"];
|
||||||
|
$event_time=$session_row["event_date"];
|
||||||
|
$event_date=substr($event_time, 0, 10);
|
||||||
|
if (!$prev_date) {$prev_date=$event_date;}
|
||||||
|
|
||||||
|
# END date in case agent is still logged in at that time
|
||||||
|
if ($event_date!=$TODAY)
|
||||||
|
{
|
||||||
|
$event_date_eod="$event_date 23:59:59";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$event_date_eod="$event_date $NOW_TIME";
|
||||||
|
}
|
||||||
|
|
||||||
|
#### CHECK IF THE USER WAS LOGGED IN AT THE START DATE/TIME, BUT ONLY DO THIS FOR THE FIRST ROW RETURNED
|
||||||
|
if ($row_no==0)
|
||||||
|
{
|
||||||
|
$override_login=0;
|
||||||
|
$previous_interval_stmt="select * from vicidial_user_log where user='$user' $and_vicidial_user_log_SQL and event_date<='$original_session_start_date' and event_date>='$original_session_cutoff_date' and event in ('LOGIN', 'LOGOUT', 'TIMEOUTLOGOUT') order by user, event_date desc limit 1";
|
||||||
|
$previous_interval_rslt=mysql_to_mysqli($previous_interval_stmt, $link);
|
||||||
|
# print "$previous_interval_stmt;\n";
|
||||||
|
if (mysqli_num_rows($previous_interval_rslt)>0)
|
||||||
|
{
|
||||||
|
|
||||||
|
#### GO BACKWARDS, IF THE PRECEDING RECORD IS A LOGIN, THEN USE THE SESSION DATE/TIME AS THE START TIME FOR THIS INTERVAL.
|
||||||
|
$previous_interval_row=mysqli_fetch_array($previous_interval_rslt);
|
||||||
|
if ($previous_interval_row["event"]=="LOGIN")
|
||||||
|
{
|
||||||
|
$override_login=1;
|
||||||
|
$login_notes="PRIOR LOGIN";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#### IF THE LAST RECORD IS A LOGOUT, CHECK THAT THE NEXT RECORD CHRONOLOGICALLY IS ALSO NOT A LOGOUT
|
||||||
|
#### BECAUSE IF SO, THE AGENT WAS LAGGED AND WAS STILL LOGGED IN (OR THE LOGIN WASN'T LOGGED)
|
||||||
|
$next_interval_stmt="select * from vicidial_user_log where user='$user' $and_vicidial_user_log_SQL and event_date>='$original_session_start_date' and event_date<='$original_session_cutoff_eod' and event in ('LOGIN', 'LOGOUT', 'TIMEOUTLOGOUT') order by user, event_date desc limit 1";
|
||||||
|
# print "$next_interval_stmt;\n";
|
||||||
|
$next_interval_rslt=mysql_to_mysqli($next_interval_stmt, $link);
|
||||||
|
if (mysqli_num_rows($next_interval_rslt)>0)
|
||||||
|
{
|
||||||
|
$next_interval_row=mysqli_fetch_array($next_interval_rslt);
|
||||||
|
if (preg_match('/LOGOUT/', $next_interval_row["event"]))
|
||||||
|
{
|
||||||
|
$override_login=1;
|
||||||
|
$login_notes="DOUBLE LOGOUT";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($override_login==1)
|
||||||
|
{
|
||||||
|
$start_event_date=$original_session_start_date;
|
||||||
|
$start_epoch_stmt="select unix_timestamp('$start_event_date')";
|
||||||
|
$start_epoch_rslt=mysql_to_mysqli($start_epoch_stmt, $link);
|
||||||
|
$start_epoch_row=mysqli_fetch_row($start_epoch_rslt);
|
||||||
|
$override_event_epoch=$start_epoch_row[0];
|
||||||
|
|
||||||
|
$agent_sessions_array["$start_event_date"]["start_hour"]=$override_event_epoch;
|
||||||
|
$agent_sessions_array["$start_event_date"]["extension"]=$extension;
|
||||||
|
$agent_sessions_array["$start_event_date"]["login_notes"]=$login_notes;
|
||||||
|
|
||||||
|
|
||||||
|
$agent_logged_in=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$row_no++; # Keeps from doing an override check
|
||||||
|
|
||||||
|
|
||||||
|
if ($event=="LOGIN")
|
||||||
|
{
|
||||||
|
#### IF AGENT IS NOT LOGGED IN, CREATE A NEW INTERVAL
|
||||||
|
# 2/23/22 - agent page when back-to-back logins, first login is overwritten, see Dougwanna Brown 2/15/22-2/22/22. Purge it here
|
||||||
|
if ($agent_logged_in!=0)
|
||||||
|
{
|
||||||
|
unset($agent_sessions_array["$start_event_date"]);
|
||||||
|
$agent_logged_in=0;
|
||||||
|
}
|
||||||
|
if ($agent_logged_in==0)
|
||||||
|
{
|
||||||
|
$start_event_date=$event_time;
|
||||||
|
$agent_sessions_array["$start_event_date"]["user_group"]=$user_group;
|
||||||
|
$agent_sessions_array["$start_event_date"]["start_hour"]=$event_epoch;
|
||||||
|
$agent_sessions_array["$start_event_date"]["extension"]=$extension;
|
||||||
|
$agent_sessions_array["$start_event_date"]["server_ip"]=$server_ip;
|
||||||
|
|
||||||
|
}
|
||||||
|
$agent_logged_in=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('/LOGOUT/', $event)) # && $agent_logged_in==1, removed this due to back to back logouts (see user 105110 for 2022-01-10)
|
||||||
|
{
|
||||||
|
# 2/23/22 - agent page when back-to-back logouts, second logout is ignored, see Dougwanna Brown 2/15/22-2/22/22.
|
||||||
|
# $agent_sessions_array["$start_event_date"]["end_hour"]=$event_epoch;
|
||||||
|
# $agent_sessions_array["$start_event_date"]["end_date"]=$event_time;
|
||||||
|
# $agent_sessions_array["$start_event_date"]["duration"]=($agent_sessions_array["$start_event_date"]["end_hour"]-$agent_sessions_array["$start_event_date"]["start_hour"]);
|
||||||
|
|
||||||
|
if ($agent_logged_in==1)
|
||||||
|
{
|
||||||
|
$agent_sessions_array["$start_event_date"]["end_hour"]=$event_epoch;
|
||||||
|
$agent_sessions_array["$start_event_date"]["end_date"]=$event_time;
|
||||||
|
$agent_sessions_array["$start_event_date"]["duration"]=($agent_sessions_array["$start_event_date"]["end_hour"]-$agent_sessions_array["$start_event_date"]["start_hour"]);
|
||||||
|
$agent_sessions_array["$start_event_date"]["notes"]="NORMAL LOGOUT";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$agent_sessions_array["$start_event_date"]["notes"]="REPEAT LOGOUT";
|
||||||
|
}
|
||||||
|
|
||||||
|
$agent_logged_in=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$override_login=0;
|
||||||
|
$prev_date=$event_date;
|
||||||
|
$prev_event=$event;
|
||||||
|
$prev_campaign_id=$campaign_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$TODAY=date("Y-m-d");
|
||||||
|
$NOW_TIME=date("H:i:s");
|
||||||
|
|
||||||
|
if($agent_logged_in)
|
||||||
|
{
|
||||||
|
if ($event_date!=$TODAY)
|
||||||
|
{
|
||||||
|
$event_date_eod="$event_date 23:59:59";
|
||||||
|
$notes="EOD LOGOUT";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$event_date_eod="$event_date $NOW_TIME";
|
||||||
|
$notes="STILL LOGGED IN";
|
||||||
|
}
|
||||||
|
|
||||||
|
$eod_epoch_stmt="select unix_timestamp('$start_event_date'), unix_timestamp('$event_date_eod')";
|
||||||
|
$eod_epoch_rslt=mysql_to_mysqli($eod_epoch_stmt, $link);
|
||||||
|
$eod_epoch_row=mysqli_fetch_row($eod_epoch_rslt);
|
||||||
|
$agent_sessions_array["$start_event_date"]["start_hour"]=$eod_epoch_row[0];
|
||||||
|
$agent_sessions_array["$start_event_date"]["end_hour"]=$eod_epoch_row[1];
|
||||||
|
$agent_sessions_array["$start_event_date"]["end_date"]=$event_date_eod;
|
||||||
|
$agent_sessions_array["$start_event_date"]["duration"]=($agent_sessions_array["$start_event_date"]["end_hour"]-$agent_sessions_array["$start_event_date"]["start_hour"]);
|
||||||
|
$agent_sessions_array["$start_event_date"]["notes"]=$notes;
|
||||||
|
|
||||||
|
$agent_logged_in=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($DB) {print_r($agent_sessions_array);}
|
||||||
|
|
||||||
|
echo "<table id=\"details_table\">\n";
|
||||||
|
echo "<tr>\n";
|
||||||
|
echo "<th>"._QXZ("Agent")."</th>\n";
|
||||||
|
echo "<th>"._QXZ("Ext.")."</th>\n";
|
||||||
|
echo "<th>"._QXZ("Duration")."</th>\n";
|
||||||
|
echo "<th>"._QXZ("On pause")."</th>\n";
|
||||||
|
echo "<th>"._QXZ("Overlapping")."</th>\n";
|
||||||
|
echo "<th>"._QXZ("Activity")."</th>\n";
|
||||||
|
echo "<th> </th>\n";
|
||||||
|
echo "<th>"._QXZ("Start hour")."</th>\n";
|
||||||
|
echo "<th>"._QXZ("End hour")."</th>\n";
|
||||||
|
echo "</tr>\n";
|
||||||
|
|
||||||
|
foreach ($agent_sessions_array as $session_start_date => $session)
|
||||||
|
{
|
||||||
|
echo "<tr>\n";
|
||||||
|
echo "<td class='small_text'>".$fullname_info["$user"]."</td>\n";
|
||||||
|
echo "<td class='small_text'>".$session["extension"]."</td>\n";
|
||||||
|
echo "<td class='small_text'>".sprintf('%02d', floor($session["duration"]/3600)).gmdate(":i:s", $session["duration"])."</td>\n";
|
||||||
|
echo "<td class='small_text'> </td>\n";
|
||||||
|
echo "<td class='small_text'>0:00</td>\n";
|
||||||
|
echo "<td class='small_text'>-</td>\n";
|
||||||
|
echo "<td class='small_text'> </td>\n";
|
||||||
|
echo "<td class='small_text'>".$session_start_date."</td>\n";
|
||||||
|
echo "<td class='small_text'>".$session["end_date"]."</td>\n";
|
||||||
|
echo "</tr>\n";
|
||||||
|
|
||||||
|
$agent_log_stmt="select sec_to_time(pause_sec) as pause_sec_fmt, event_time, event_time+INTERVAL pause_sec SECOND as end_time, if(sub_status is null or sub_status='BLANK', '-', sub_status) as pause_code, campaign_id from vicidial_agent_log where event_time>='$session_start_date' and event_time<='".$session["end_date"]."' and user='$user' order by event_time asc";
|
||||||
|
# print $agent_log_stmt;
|
||||||
|
$agent_log_rslt=mysql_to_mysqli($agent_log_stmt, $link);
|
||||||
|
while ($agent_log_row=mysqli_fetch_array($agent_log_rslt))
|
||||||
|
{
|
||||||
|
$campaign_id=$agent_log_row["campaign_id"];
|
||||||
|
|
||||||
|
$bp="N"; $pp="N";
|
||||||
|
if (in_array($agent_log_row["pause_code"], $billable_pause_codes["$campaign_id"]) || in_array($agent_log_row["pause_code"], $billable_pause_codes["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$is_billable="Yes"; $bp="";
|
||||||
|
}
|
||||||
|
if (!in_array($agent_log_row["pause_code"], $payable_pause_codes["$campaign_id"]) && in_array($agent_log_row["pause_code"], $payable_pause_codes["SYSTEM"]))
|
||||||
|
{
|
||||||
|
$pp="";
|
||||||
|
}
|
||||||
|
$billable_code=$bp."B".$pp."P";
|
||||||
|
|
||||||
|
$pause_name_key=$campaign_id."-".$agent_log_row["pause_code"];
|
||||||
|
|
||||||
|
echo "<tr>\n";
|
||||||
|
echo "<td class='small_text'> </td>\n";
|
||||||
|
echo "<td class='small_text'> </td>\n";
|
||||||
|
echo "<td class='small_text'> </td>\n";
|
||||||
|
echo "<td class='small_text'>".$agent_log_row["pause_sec_fmt"]."</td>\n";
|
||||||
|
echo "<td class='small_text'>0:00</td>\n";
|
||||||
|
echo "<td class='small_text'>".$pause_code_names["$pause_name_key"]."</td>\n";
|
||||||
|
echo "<td class='small_text'>$billable_code</td>\n";
|
||||||
|
echo "<td class='small_text'>".$agent_log_row["event_time"]."</td>\n";
|
||||||
|
echo "<td class='small_text'>".$agent_log_row["end_time"]."</td>\n";
|
||||||
|
echo "</tr>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "<tr>\n";
|
||||||
|
echo "<td class='small_text'>".$fullname_info["$user"]."</td>\n";
|
||||||
|
echo "<td class='small_text'>".$session["extension"]."</td>\n";
|
||||||
|
echo "<td class='small_text'>".sprintf('%02d', floor($session["duration"]/3600)).gmdate(":i:s", $session["duration"])."</td>\n";
|
||||||
|
echo "<td class='small_text'> </td>\n";
|
||||||
|
echo "<td class='small_text'> </td>\n";
|
||||||
|
echo "<td class='small_text'>"._QXZ("Logout")."</td>\n";
|
||||||
|
echo "<td class='small_text'>-</td>\n";
|
||||||
|
echo "<td class='small_text'>".$session_start_date."</td>\n";
|
||||||
|
echo "<td class='small_text'>".$session["end_date"]."</td>\n";
|
||||||
|
echo "</tr>\n";
|
||||||
|
echo "<tr>\n";
|
||||||
|
echo "<td colspan='9'> </td>\n";
|
||||||
|
echo "</tr>\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
echo "</table>";
|
||||||
|
|
||||||
|
echo "</span>\n";
|
||||||
|
|
||||||
|
echo "</td></tr></table>";
|
||||||
|
# print_r($agent_sessions_array);
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -0,0 +1,243 @@
|
|||||||
|
<?php
|
||||||
|
# display_call_details.php - Vicidial Enhanced Reporting call details page
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1611 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
require("functions.php");
|
||||||
|
require("VERM_global_vars.inc");
|
||||||
|
|
||||||
|
if (isset($_GET["detail_id"])) {$detail_id=$_GET["detail_id"];}
|
||||||
|
elseif (isset($_POST["detail_id"])) {$detail_id=$_POST["detail_id"];}
|
||||||
|
if (isset($_GET["call_type"])) {$call_type=$_GET["call_type"];}
|
||||||
|
elseif (isset($_POST["call_type"])) {$call_type=$_POST["call_type"];}
|
||||||
|
if (isset($_GET["detail_span_height"])) {$detail_span_height=$_GET["detail_span_height"];}
|
||||||
|
elseif (isset($_POST["detail_span_height"])) {$detail_span_height=$_POST["detail_span_height"];}
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
##### 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;";
|
||||||
|
$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];
|
||||||
|
$outbound_autodial_active = $row[1];
|
||||||
|
$slave_db_server = $row[2];
|
||||||
|
$reports_use_slave_db = $row[3];
|
||||||
|
$SSenable_languages = $row[4];
|
||||||
|
$SSlanguage_method = $row[5];
|
||||||
|
$agent_whisper_enabled = $row[6];
|
||||||
|
$SSreport_default_format = $row[7];
|
||||||
|
$SSenable_pause_code_limits = $row[8];
|
||||||
|
$SSallow_web_debug = $row[9];
|
||||||
|
$SSadmin_screen_colors = $row[10];
|
||||||
|
$SSadmin_web_directory = $row[11];
|
||||||
|
}
|
||||||
|
if ($SSallow_web_debug < 1) {$DB=0;}
|
||||||
|
##### END SETTINGS LOOKUP #####
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
if (!$detail_id) {echo "Beat it."; die;}
|
||||||
|
if (!$detail_span_height) {$detail_span_height="70";}
|
||||||
|
$detail_span_height-=15; # account for headers;
|
||||||
|
|
||||||
|
$detail_id = preg_replace('/[^0-9\.\|]/','',$detail_id);
|
||||||
|
$detail_span_height = preg_replace('/[^0-9]/','',$detail_span_height);
|
||||||
|
|
||||||
|
if ($non_latin < 1)
|
||||||
|
{
|
||||||
|
$call_type = preg_replace('/[^a-zA-Z]/','',$call_type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$call_type = preg_replace('/[^\p{L}]/u','',$call_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
# $report_name="Vox Enhanced Reporting Module - Call detail display";
|
||||||
|
|
||||||
|
$NWB = "<IMG SRC=\"help.png\" onClick=\"FillAndShowHelpDiv(event, '";
|
||||||
|
$NWE = "')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP>";
|
||||||
|
|
||||||
|
$lookup_data=explode("|", $detail_id);
|
||||||
|
|
||||||
|
$uniqueid=$lookup_data[0];
|
||||||
|
$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'";
|
||||||
|
$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'";
|
||||||
|
$vicidial_id=$closecallid;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
# if (mysqli_num_rows($rslt)==0) {echo "No records found for ".implode(", ", $lookup_data); die;}
|
||||||
|
$row=mysqli_fetch_array($rslt);
|
||||||
|
|
||||||
|
$asterisk_call_id=GetCallerCode($uniqueid);
|
||||||
|
$ivr_events=0;
|
||||||
|
if ($row["xfercallid"]==0 || $call_type=="ivr") # Possible origin call, need to lookup IVR (may add additional clause to do this on inbound calls only)
|
||||||
|
{
|
||||||
|
$ivr_info_array=GetIVRInfo($uniqueid, $row["call_date"]);
|
||||||
|
$ivr_duration=$ivr_info_array[1];
|
||||||
|
$ivr_path=$ivr_info_array[2];
|
||||||
|
$row["call_date"]=$ivr_info_array[3];
|
||||||
|
$ivr_HTML=$ivr_info_array[4];
|
||||||
|
$ivr_events=$ivr_info_array[5];
|
||||||
|
}
|
||||||
|
$dnis=GetDNIS($uniqueid);
|
||||||
|
$recording_array=GetRecording($vicidial_id);
|
||||||
|
$recording_link="<a href='$recording_array[1]'>$recording_array[0]</a>";
|
||||||
|
# $xfer_array=GetTransferInfo($uniqueid);
|
||||||
|
|
||||||
|
echo "<table border=0 width='100%' bgcolor='#FFF'><tr>";
|
||||||
|
# echo "<td>";
|
||||||
|
|
||||||
|
# echo "<div align='right'><a onClick='HideCallDetails()'><h2 class='rpt_header'>[X]</h2></a></div>";
|
||||||
|
# echo "<div align='left'><h2 class='rpt_header'>Call Detail:</h2></div>";
|
||||||
|
|
||||||
|
|
||||||
|
echo "<td align='left'>";
|
||||||
|
#echo "<div style='position:fixed; top: -5; right: -30;'><a onClick='HideAgentDetails()'><h2 class='rpt_header'>[X]</h2></a></div>";
|
||||||
|
#echo "<div align='left'><h2 class='rpt_header'>Agent Detail: $user</h2></div>";
|
||||||
|
echo "<h2 class='rpt_header'>"._QXZ("Call Detail").":</h2>";
|
||||||
|
echo "</td>";
|
||||||
|
echo "<td align='right'>";
|
||||||
|
echo "<a onClick='HideCallDetails()'><h2 class='rpt_header'>[X]</h2></a>";
|
||||||
|
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 <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'>";
|
||||||
|
|
||||||
|
echo "<span id='all_call_details' style='display:block; overflow-y:auto; height: ".$detail_span_height."vh;'>\n";
|
||||||
|
echo "<table id='rpt_table' width='100%'>";
|
||||||
|
echo "<tr><td class='bold_cell'>"._QXZ("Asterisk Call ID").":</td><td>".$asterisk_call_id."</td></tr>";
|
||||||
|
echo "<tr><td class='bold_cell'>"._QXZ("Date and time").":</td><td>".$row["call_date"]."</td></tr>";
|
||||||
|
echo "<tr><td class='bold_cell'>"._QXZ("Campaign/ingroup").":</td><td>".$queue_names["$row[campaign_id]"]." <i>[".$row["campaign_id"]."]</i></td></tr>";
|
||||||
|
echo "<tr><td class='bold_cell'>"._QXZ("Caller ID").":</td><td>".$row["phone_number"]."</td></tr>";
|
||||||
|
echo "<tr><td class='bold_cell'>"._QXZ("Handled by").":</td><td>".$fullname_info["$row[user]"]."</td></tr>";
|
||||||
|
echo "<tr><td class='bold_cell'>"._QXZ("Duration").":</td><td>".$row["duration"]." sec</td></tr>";
|
||||||
|
echo "<tr><td class='bold_cell'>"._QXZ("Time in IVR before queueing").":</td><td>".$ivr_duration."</td></tr>";
|
||||||
|
echo "<tr><td class='bold_cell'>"._QXZ("Waiting time").":</td><td>".$row["wait"]." sec</td></tr>";
|
||||||
|
echo "<tr><td class='bold_cell'>"._QXZ("Original position").":</td><td># ".$row["queue_position"]."</td></tr>";
|
||||||
|
echo "<tr><td class='bold_cell'>"._QXZ("Disconnection cause").":</td><td>".$row["term_reason"]."</td></tr>";
|
||||||
|
echo "<tr><td class='bold_cell'>"._QXZ("Transferred to").":</td><td></td></tr>";
|
||||||
|
echo "<tr><td class='bold_cell'>"._QXZ("Attempts").":</td><td>1</td></tr>";
|
||||||
|
echo "<tr><td class='bold_cell'>"._QXZ("Status code").":</td><td>".$row["status"].": ".$status_names["$row[status]"]."</td></tr>";
|
||||||
|
echo "<tr><td class='bold_cell'>"._QXZ("DNIS").":</td><td>".$dnis."</td></tr>";
|
||||||
|
echo "<tr><td class='bold_cell'>"._QXZ("IVR selection").":</td><td>".$ivr_path."</td></tr>";
|
||||||
|
echo "<tr><td class='bold_cell' colspan='2'>".$recording_link."</td></tr>";
|
||||||
|
echo "</table>";
|
||||||
|
echo "</span>\n";
|
||||||
|
|
||||||
|
echo "<span id='all_ivr_details' style='display:none; overflow-y:auto; height: ".$detail_span_height."vh;'>\n";
|
||||||
|
echo $ivr_HTML;
|
||||||
|
echo "</span>\n";
|
||||||
|
|
||||||
|
echo "</td></tr></table>";
|
||||||
|
#echo "</body>";
|
||||||
|
#echo "</html>";
|
||||||
|
|
||||||
|
function GetCallerCode($uniqueid)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
$caller_code="";
|
||||||
|
$cc_stmt="select caller_code from vicidial_log_extended where uniqueid='$uniqueid'";
|
||||||
|
$cc_rslt=mysqli_query($link, $cc_stmt);
|
||||||
|
$cc_row=mysqli_fetch_array($cc_rslt);
|
||||||
|
$caller_code=$cc_row[0];
|
||||||
|
return $caller_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetIVRInfo($uniqueid, $actual_start_time)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
|
||||||
|
$ivr_path="";
|
||||||
|
$ivr_length=0;
|
||||||
|
$ivr_duration=0;
|
||||||
|
$ivr_span_HTML="<table id='rpt_table' width='100%'>";
|
||||||
|
$ivr_span_HTML.="<tr><th>Hour</th><th>Duration</th><th>Event</th><th>Agent</th><th>...</th></tr>";
|
||||||
|
|
||||||
|
$ivr_stmt="select extension,date_format(start_time, '%m/%d - %H:%i:%s') as start_time,comment_a,comment_b,comment_d,UNIX_TIMESTAMP(start_time),phone_ext from live_inbound_log where uniqueid='$uniqueid' and comment_a IN('CALLMENU') order by start_time";
|
||||||
|
$ivr_rslt=mysqli_query($link, $ivr_stmt);
|
||||||
|
$ivr_paths=array(); # 0 - total calls, 1 - total time, 2 - min time, 3 - max time
|
||||||
|
$ivr_counts=array();
|
||||||
|
$ivr_event="START";
|
||||||
|
while ($ivr_row=mysqli_fetch_array($ivr_rslt))
|
||||||
|
{
|
||||||
|
if(!$prev_time) {$prev_time=$ivr_row[5];}
|
||||||
|
if(!$ivr_start_time)
|
||||||
|
{
|
||||||
|
$actual_start_time=$ivr_row[1];
|
||||||
|
$ivr_start_time=$ivr_row[5];
|
||||||
|
}
|
||||||
|
$ivr_path.=$ivr_row["comment_b"].",";
|
||||||
|
|
||||||
|
$ivr_duration=$ivr_row[5]-$ivr_start_time;
|
||||||
|
$ivr_interval_duration=$ivr_row[5]-$prev_time;
|
||||||
|
$ivr_interval_duration_fmt=($ivr_interval_duration>=3600 ? intval(floor($ivr_interval_duration/3600)).date(":i:s", $ivr_interval_duration) : intval(date("i", $ivr_interval_duration)).":".date("s", $ivr_interval_duration));
|
||||||
|
$ivr_length+=$ivr_duration;
|
||||||
|
$prev_time=$ivr_row[5];
|
||||||
|
|
||||||
|
if(preg_match('/\>/', $ivr_row["comment_d"])) {$ivr_event="Option: $ivr_row[comment_b]";}
|
||||||
|
$ivr_span_HTML.="<tr><th>".substr($ivr_row["start_time"], -8)."</th><th>$ivr_interval_duration_fmt</th><th>$ivr_event</th><th> </th><th>".$ivr_row["comment_b"]."</th></tr>";
|
||||||
|
$ivr_event="";
|
||||||
|
}
|
||||||
|
|
||||||
|
$ivr_path=preg_replace('/,$/', '', $ivr_path);
|
||||||
|
$ivr_duration_fmt=($ivr_duration>=3600 ? floor($ivr_duration/3600).":" : "").gmdate("i:s", $ivr_duration);
|
||||||
|
$ivr_length_fmt=($ivr_length>=3600 ? floor($ivr_length/3600).":" : "").gmdate("i:s", $ivr_length);
|
||||||
|
|
||||||
|
$ivr_span_events=mysqli_num_rows($ivr_rslt);
|
||||||
|
return array("$ivr_length_fmt", "$ivr_duration_fmt", "$ivr_path", "$actual_start_time", "$ivr_span_HTML", "$ivr_span_events");
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetDNIS($uniqueid)
|
||||||
|
{
|
||||||
|
global $link, $DB, $did_id_info, $did_pattern_info;
|
||||||
|
|
||||||
|
$did_str="";
|
||||||
|
|
||||||
|
$did_stmt="select extension, did_id from vicidial_did_log where uniqueid in ('$uniqueid')";
|
||||||
|
$did_rslt=mysqli_query($link, $did_stmt);
|
||||||
|
$did_row=mysqli_fetch_array($did_rslt);
|
||||||
|
$did_str=$did_row["extension"]." - ".$did_id_info["$did_row[did_id]"];
|
||||||
|
|
||||||
|
return $did_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetRecording($vicidial_id)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
|
||||||
|
$rec_str="";
|
||||||
|
|
||||||
|
$rec_stmt="select filename, location 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]");
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
<?php
|
||||||
|
# display_help.php
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <freewermadmin@gmail.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# pulls help text to display on the screen when the appropriate help link is clicked
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 180501-0045 - First build
|
||||||
|
# 180512-1055 - Added update of help_documentation.txt file if modified
|
||||||
|
# 220827-1946 - Added allow_web_debug system setting
|
||||||
|
#
|
||||||
|
|
||||||
|
$startMS = microtime();
|
||||||
|
$ip = getenv("REMOTE_ADDR");
|
||||||
|
$help_file = './help_documentation.txt';
|
||||||
|
$help_file_time=0;
|
||||||
|
if ( file_exists($help_file) )
|
||||||
|
{$help_file_time = filemtime($help_file);}
|
||||||
|
|
||||||
|
require("../vicidial/dbconnect_mysqli.php");
|
||||||
|
require("../vicidial/functions.php");
|
||||||
|
|
||||||
|
$PHP_AUTH_USER=$_SERVER['PHP_AUTH_USER'];
|
||||||
|
$PHP_AUTH_PW=$_SERVER['PHP_AUTH_PW'];
|
||||||
|
if (isset($_GET["help_id"])) {$help_id=$_GET["help_id"];}
|
||||||
|
elseif (isset($_POST["help_id"])) {$help_id=$_POST["help_id"];}
|
||||||
|
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,enable_languages,language_method,help_modification_date,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];
|
||||||
|
$SSenable_languages = $row[1];
|
||||||
|
$SSlanguage_method = $row[2];
|
||||||
|
$help_modification_date = $row[3];
|
||||||
|
$SSallow_web_debug = $row[4];
|
||||||
|
}
|
||||||
|
if ($SSallow_web_debug < 1) {$DB=0;}
|
||||||
|
##### END SETTINGS LOOKUP #####
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
$help_id = preg_replace('/[^-_0-9a-zA-Z]/', '',$help_id);
|
||||||
|
|
||||||
|
if ($non_latin < 1)
|
||||||
|
{
|
||||||
|
$PHP_AUTH_PW = preg_replace('/[^-_0-9a-zA-Z]/','',$PHP_AUTH_PW);
|
||||||
|
$PHP_AUTH_USER = preg_replace('/[^-_0-9a-zA-Z]/','',$PHP_AUTH_USER);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="SELECT selected_language from vicidial_users where user='$PHP_AUTH_USER';";
|
||||||
|
if ($DB) {echo "|$stmt|\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$sl_ct = mysqli_num_rows($rslt);
|
||||||
|
if ($sl_ct > 0)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$VUselected_language = $row[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$user_auth=0;
|
||||||
|
$auth=0;
|
||||||
|
$reports_auth=0;
|
||||||
|
$qc_auth=0;
|
||||||
|
$auth_message = user_authorization($PHP_AUTH_USER,$PHP_AUTH_PW,'QC',1,0);
|
||||||
|
if ($auth_message == 'GOOD')
|
||||||
|
{$user_auth=1;}
|
||||||
|
|
||||||
|
if ($user_auth < 1)
|
||||||
|
{
|
||||||
|
$VDdisplayMESSAGE = "Login incorrect, please try again";
|
||||||
|
if ($auth_message == 'LOCK')
|
||||||
|
{
|
||||||
|
$VDdisplayMESSAGE = "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;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
### Check for new help_documentation.txt file
|
||||||
|
if ($help_file_time > $help_modification_date)
|
||||||
|
{
|
||||||
|
$help_fp=fopen($help_file, "r");
|
||||||
|
$help_contentsRAW = fread($help_fp,filesize($help_file));
|
||||||
|
fclose($help_fp);
|
||||||
|
$help_contents = explode("\n",$help_contentsRAW);
|
||||||
|
$help_contents_ct = count($help_contents);
|
||||||
|
if ($DB > 0)
|
||||||
|
{echo "New $help_file found, loading contents: ($help_file_time <> $help_modification_date), ".filesize($help_file)."|$help_contents_ct\n";}
|
||||||
|
|
||||||
|
$h=0;
|
||||||
|
$help_comment=0;
|
||||||
|
$help_insert=0;
|
||||||
|
$help_update=0;
|
||||||
|
while($help_contents_ct > $h)
|
||||||
|
{
|
||||||
|
if (!preg_match("/^\#/",$help_contents[$h]))
|
||||||
|
{
|
||||||
|
$help_line = preg_replace("/\"/","'",$help_contents[$h]);
|
||||||
|
$help_line = preg_replace("/\r|\n|\\\\/",'',$help_contents[$h]);
|
||||||
|
$help_lineARY = explode("\t",$help_line);
|
||||||
|
$stmt="INSERT INTO help_documentation (help_id, help_title, help_text) VALUES (\"" . mysqli_real_escape_string($link, $help_lineARY[0]) . "\",\"" . mysqli_real_escape_string($link, $help_lineARY[1]) . "\",\"" . mysqli_real_escape_string($link, $help_lineARY[2]) . "\") ON DUPLICATE KEY UPDATE help_title=\"" . mysqli_real_escape_string($link, $help_lineARY[1]) . "\", help_text=\"" . mysqli_real_escape_string($link, $help_lineARY[2]) . "\";";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$inupdate_rows=mysqli_affected_rows($link);
|
||||||
|
if ($inupdate_rows == 1) {$help_insert++;}
|
||||||
|
if ($inupdate_rows == 2) {$help_update++;}
|
||||||
|
if ($DB) {echo "$inupdate_rows|$stmt|\n";}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$help_comment++;
|
||||||
|
if ($DB) {echo "Skipping comment row: $h|$help_contents[$h]|\n";}
|
||||||
|
}
|
||||||
|
$h++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="UPDATE system_settings SET help_modification_date='$help_file_time';";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
### LOG INSERTION Admin Log Table ###
|
||||||
|
$SQL_log = "$stmt|";
|
||||||
|
$SQL_log = preg_replace('/;/', '', $SQL_log);
|
||||||
|
$SQL_log = addslashes($SQL_log);
|
||||||
|
$stmt="INSERT INTO vicidial_admin_log set event_date=NOW(), user='$PHP_AUTH_USER', ip_address='$ip', event_section='HELP', event_type='MODIFY', record_id='$PHP_AUTH_USER', event_code='UPDATE HELP DOCUMENTATION', event_sql=\"$SQL_log\", event_notes='ROWS: $h UPDATES: $help_update INSERTS: $help_insert COMMENTS: $help_comment';";
|
||||||
|
if ($DB) {echo "|$stmt|\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### Lookup of help text for display
|
||||||
|
$help_stmt="select help_title, help_text from help_documentation where help_id='$help_id'";
|
||||||
|
$help_rslt=mysql_to_mysqli($help_stmt, $link);
|
||||||
|
while ($help_row=mysqli_fetch_row($help_rslt))
|
||||||
|
{
|
||||||
|
preg_match_all("/<QXZ>(.*?)<\/QXZ>/", $help_row[1], $QXZ_matches);
|
||||||
|
|
||||||
|
$qxz_match=$QXZ_matches[0];
|
||||||
|
$qxz_replace=$QXZ_matches[1];
|
||||||
|
for ($q=0; $q<count($qxz_replace); $q++)
|
||||||
|
{
|
||||||
|
# $qxz_match[$q]=preg_replace("/\//", '\\\/', $qxz_match[$q]);
|
||||||
|
$qxz_match[$q]=preg_quote($qxz_match[$q], '/');
|
||||||
|
$qxz_match[$q]="/".$qxz_match[$q]."/";
|
||||||
|
$qxz_replace[$q]=_QXZ($qxz_replace[$q]);
|
||||||
|
}
|
||||||
|
$help_row[1]=preg_replace($qxz_match, $qxz_replace, $help_row[1]);
|
||||||
|
|
||||||
|
# preg_replace('/"/', '\\"', $help_row[1]);
|
||||||
|
echo "<TABLE CELLPADDING=2 CELLSPACING=0 border='0' class='help_td' width='300'>";
|
||||||
|
echo "<TR><TD VALIGN='TOP' width='280'><FONT class='help_bold'>"._QXZ("$help_row[0]")."</font></td><TD VALIGN='TOP' align='right' width='20' onClick='ClearAndHideHelpDiv()'><B>[X]</B></tr>";
|
||||||
|
echo "<TR><TD VALIGN='TOP' colspan='2'>$help_row[1]</td></tr>";
|
||||||
|
echo "</TABLE>";
|
||||||
|
if ($DB > 0)
|
||||||
|
{echo "$help_file($help_file_time <> $help_modification_date)\n";}
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,766 @@
|
|||||||
|
<?php
|
||||||
|
# display_outcomes_details.php - Vicidial Enhanced Reporting outcomes details page
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220825-1610 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
require("functions.php");
|
||||||
|
require("VERM_global_vars.inc");
|
||||||
|
|
||||||
|
if (isset($_GET["download_rpt"])) {$download_rpt=$_GET["download_rpt"];}
|
||||||
|
elseif (isset($_POST["download_rpt"])) {$download_rpt=$_POST["download_rpt"];}
|
||||||
|
if (isset($_GET["user"])) {$user=$_GET["user"];}
|
||||||
|
elseif (isset($_POST["user"])) {$user=$_POST["user"];}
|
||||||
|
if (isset($_GET["campaign_id"])) {$campaign_id=$_GET["campaign_id"];}
|
||||||
|
elseif (isset($_POST["campaign_id"])) {$campaign_id=$_POST["campaign_id"];}
|
||||||
|
if (isset($_GET["users"])) {$users=$_GET["users"];}
|
||||||
|
elseif (isset($_POST["users"])) {$users=$_POST["users"];}
|
||||||
|
if (isset($_GET["teams"])) {$teams=$_GET["teams"];}
|
||||||
|
elseif (isset($_POST["teams"])) {$teams=$_POST["teams"];}
|
||||||
|
if (isset($_GET["user_group"])) {$user_group=$_GET["user_group"];}
|
||||||
|
elseif (isset($_POST["user_group"])) {$user_group=$_POST["user_group"];}
|
||||||
|
if (isset($_GET["location"])) {$location=$_GET["location"];}
|
||||||
|
elseif (isset($_POST["location"])) {$location=$_POST["location"];}
|
||||||
|
if (isset($_GET["status"])) {$status=$_GET["status"];}
|
||||||
|
elseif (isset($_POST["status"])) {$status=$_POST["status"];}
|
||||||
|
if (isset($_GET["status_name"])) {$status_name=$_GET["status_name"];}
|
||||||
|
elseif (isset($_POST["status_name"])) {$status_name=$_POST["status_name"];}
|
||||||
|
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["start_datetime"])) {$start_datetime=$_GET["start_datetime"];}
|
||||||
|
elseif (isset($_POST["start_datetime"])) {$start_datetime=$_POST["start_datetime"];}
|
||||||
|
if (isset($_GET["end_datetime"])) {$end_datetime=$_GET["end_datetime"];}
|
||||||
|
elseif (isset($_POST["end_datetime"])) {$end_datetime=$_POST["end_datetime"];}
|
||||||
|
if (isset($_GET["sort_answered_details"])) {$sort_answered_details=$_GET["sort_answered_details"];}
|
||||||
|
elseif (isset($_POST["sort_answered_details"])) {$sort_answered_details=$_POST["sort_answered_details"];}
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
##### 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;";
|
||||||
|
$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];
|
||||||
|
$outbound_autodial_active = $row[1];
|
||||||
|
$slave_db_server = $row[2];
|
||||||
|
$reports_use_slave_db = $row[3];
|
||||||
|
$SSenable_languages = $row[4];
|
||||||
|
$SSlanguage_method = $row[5];
|
||||||
|
$agent_whisper_enabled = $row[6];
|
||||||
|
$SSreport_default_format = $row[7];
|
||||||
|
$SSenable_pause_code_limits = $row[8];
|
||||||
|
$SSallow_web_debug = $row[9];
|
||||||
|
$SSadmin_screen_colors = $row[10];
|
||||||
|
$SSadmin_web_directory = $row[11];
|
||||||
|
}
|
||||||
|
if ($SSallow_web_debug < 1) {$DB=0;}
|
||||||
|
##### END SETTINGS LOOKUP #####
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
$NWB = "<IMG SRC=\"help.png\" onClick=\"FillAndShowHelpDiv(event, '";
|
||||||
|
$NWE = "')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP>";
|
||||||
|
|
||||||
|
$start_datetime=preg_replace('/[^\s\-0-9\:]/', '', $start_datetime);
|
||||||
|
$end_datetime=preg_replace('/[^\s\-0-9\:]/', '', $end_datetime);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
$download_rpt = preg_replace('/[^\._0-9a-zA-Z]/','',$download_rpt);
|
||||||
|
$user = preg_replace('/[^\-_0-9a-zA-Z]/','',$user);
|
||||||
|
$users = preg_replace('/[^\-_0-9a-zA-Z]/','',$users);
|
||||||
|
$teams = preg_replace('/[^\-_0-9a-zA-Z]/','',$teams);
|
||||||
|
$user_group = preg_replace('/[^\-_0-9a-zA-Z]/','',$user_group);
|
||||||
|
$campaign_id = preg_replace('/[^\-_0-9a-zA-Z]/','',$campaign_id);
|
||||||
|
$location = preg_replace('/[^\- \.\,\_0-9a-zA-Z]/','',$location);
|
||||||
|
$status = preg_replace('/[^\- \.\,\_0-9a-zA-Z]/','',$status);
|
||||||
|
$status_name = preg_replace('/[^\- \.\,\_0-9a-zA-Z]/','',$status_name);
|
||||||
|
$vicidial_queue_groups = preg_replace('/[^-_0-9a-zA-Z]/','',$vicidial_queue_groups);
|
||||||
|
$sort_answered_details = preg_replace('/[^\s-_0-9a-zA-Z]/','',$sort_answered_details);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
$download_rpt = preg_replace('/[^\._0-9\p{L}]/u','',$download_rpt);
|
||||||
|
$user = preg_replace('/[^-_0-9\p{L}]/u','',$user);
|
||||||
|
$users = preg_replace('/[^-_0-9\p{L}]/u','',$users);
|
||||||
|
$teams = preg_replace('/[^-_0-9\p{L}]/u','',$teams);
|
||||||
|
$user_group = preg_replace('/[^-_0-9\p{L}/u','',$user_group);
|
||||||
|
$campaign_id = preg_replace('/[^-_0-9\p{L}/u','',$campaign_id);
|
||||||
|
$location = preg_replace('/[^- \.\,\_0-9\p{L}]/u','',$location);
|
||||||
|
$status = preg_replace('/[^- \.\,\_0-9\p{L}]/u','',$status);
|
||||||
|
$status_name = preg_replace('/[^- \.\,\_0-9\p{L}]/u','',$status_name);
|
||||||
|
$vicidial_queue_groups = preg_replace('/[^-_0-9\p{L}]/u','',$vicidial_queue_groups);
|
||||||
|
$sort_answered_details = preg_replace('/[^\s-_0-9\p{L}]/u','',$sort_answered_details);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$start_datetime || !$end_datetime) {echo "Missing information - needs start date/time, end date/time"; $die=1;}
|
||||||
|
|
||||||
|
function RemoveEmptyArrayStrings($array)
|
||||||
|
{
|
||||||
|
if (is_array($array))
|
||||||
|
{
|
||||||
|
for ($i=0; $i<count($array); $i++)
|
||||||
|
{
|
||||||
|
if ($array[$i]=="") {unset($array[$i]);}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#### CLAUSE GENERATION ####
|
||||||
|
|
||||||
|
$where_call_date_sql="where call_date>='$start_datetime' and call_date<='$end_datetime'";
|
||||||
|
# 6/7/22 - changed because clause takes 100X longer
|
||||||
|
# $where_event_time_sql="where event_time+INTERVAL (pause_sec+wait_sec) SECOND>='$start_datetime' and event_time+INTERVAL (pause_sec+wait_sec) SECOND<='$end_datetime'";
|
||||||
|
$where_event_time_sql="where event_time>='$start_datetime' and event_time<='$end_datetime'";
|
||||||
|
|
||||||
|
#### QUEUE GROUPS ####
|
||||||
|
$vicidial_queue_groups=preg_replace('/[^-_0-9\p{L}]/u','',$vicidial_queue_groups);
|
||||||
|
$vicidial_queue_groups=RemoveEmptyArrayStrings($vicidial_queue_groups);
|
||||||
|
|
||||||
|
if ($vicidial_queue_groups)
|
||||||
|
{
|
||||||
|
$vqg_stmt="select included_campaigns, included_inbound_groups from vicidial_queue_groups where queue_group='$vicidial_queue_groups'";
|
||||||
|
$vqg_rslt=mysql_to_mysqli($vqg_stmt, $link);
|
||||||
|
if(mysqli_num_rows($vqg_rslt)>0)
|
||||||
|
{
|
||||||
|
$vqg_row=mysqli_fetch_array($vqg_rslt);
|
||||||
|
$included_campaigns=trim(preg_replace('/\s\-$/', '', $vqg_row["included_campaigns"]));
|
||||||
|
$included_campaigns_clause="and campaign_id in ('".preg_replace('/\s/', "', '", $included_campaigns)."')";
|
||||||
|
$included_inbound_groups=trim(preg_replace('/\s\-$/', '', $vqg_row["included_inbound_groups"]));
|
||||||
|
$included_inbound_groups_clause="and group_id in ('".preg_replace('/\s/', "', '", $included_inbound_groups)."')";
|
||||||
|
$where_included_inbound_groups_clause="where group_id in ('".preg_replace('/\s/', "', '", $included_inbound_groups)."')";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get final list of 'atomic queues'
|
||||||
|
$atomic_queue_str="";
|
||||||
|
|
||||||
|
$atomic_queue_campaigns_str="";
|
||||||
|
$campaign_id_stmt="select campaign_id, campaign_name from vicidial_campaigns where campaign_id is not null $included_campaigns_clause order by campaign_id"; # $LOGallowed_campaignsSQL, removed for now per Matt's assurances
|
||||||
|
$campaign_id_rslt=mysql_to_mysqli($campaign_id_stmt, $link);
|
||||||
|
while($campaign_id_row=mysqli_fetch_array($campaign_id_rslt))
|
||||||
|
{
|
||||||
|
$atomic_queue_str.=$campaign_id_row["campaign_name"];
|
||||||
|
$atomic_queue_str.=" <i>[".$campaign_id_row["campaign_id"]."]</i>,";
|
||||||
|
$atomic_queue_campaigns_str.="$campaign_id_row[campaign_id]', '";
|
||||||
|
}
|
||||||
|
$and_atomic_queue_campaigns_clause="and campaign_id in ('".$atomic_queue_campaigns_str."')";
|
||||||
|
|
||||||
|
# Check if queue settings override user group settings
|
||||||
|
$closer_campaigns_stmt="select closer_campaigns from vicidial_campaigns where closer_campaigns is not null $LOGallowed_campaignsSQL"; # $included_campaigns_clause
|
||||||
|
$closer_campaigns_rslt=mysql_to_mysqli($closer_campaigns_stmt, $link);
|
||||||
|
$allowed_ingroups_array=array();
|
||||||
|
while ($closer_campaigns_row=mysqli_fetch_array($closer_campaigns_rslt))
|
||||||
|
{
|
||||||
|
$closer_campaigns_array=explode(" ", trim(preg_replace('/\s\-$/', '', $closer_campaigns_row["closer_campaigns"])));
|
||||||
|
for ($i=0; $i<count($closer_campaigns_array); $i++)
|
||||||
|
{
|
||||||
|
if (!in_array($closer_campaigns_array[$i], $allowed_ingroups_array))
|
||||||
|
{
|
||||||
|
array_push($allowed_ingroups_array, $closer_campaigns_array[$i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$atomic_queue_ingroups_str="";
|
||||||
|
$ingroups_id_stmt="select group_id, group_name from vicidial_inbound_groups $where_included_inbound_groups_clause"; #where group_id in ('".implode("', '", $allowed_ingroups_array)."') $included_inbound_groups_clause
|
||||||
|
$ingroups_id_rslt=mysql_to_mysqli($ingroups_id_stmt, $link);
|
||||||
|
while($ingroups_id_row=mysqli_fetch_array($ingroups_id_rslt))
|
||||||
|
{
|
||||||
|
$atomic_queue_str.=$ingroups_id_row["group_name"];
|
||||||
|
$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."')";
|
||||||
|
$atomic_queue_str=preg_replace('/,$/', '', $atomic_queue_str);
|
||||||
|
|
||||||
|
if (strlen($atomic_queue_str)==0)
|
||||||
|
{
|
||||||
|
$atomic_queue_str="NONE";
|
||||||
|
}
|
||||||
|
|
||||||
|
$vicidial_log_SQL.="$and_atomic_queue_campaigns_clause";
|
||||||
|
$vicidial_closer_log_SQL.="$and_atomic_queue_ingroups_clause";
|
||||||
|
|
||||||
|
#### END QUEUE GROUPS ####
|
||||||
|
|
||||||
|
# For calls from the AGENT SESSIONS report
|
||||||
|
if ($user)
|
||||||
|
{
|
||||||
|
$user=preg_replace('/[^-_0-9\p{L}]/u','',$user);
|
||||||
|
$and_user_sql=" and user='$user'";
|
||||||
|
$where_user_sql=" where user='$user'";
|
||||||
|
|
||||||
|
$vicidial_log_SQL.=$and_user_sql;
|
||||||
|
$vicidial_closer_log_SQL.=$and_user_sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
# For calls from the "QUEUE" SESSIONS report
|
||||||
|
if ($campaign_id)
|
||||||
|
{
|
||||||
|
$campaign_id=preg_replace('/[^-_0-9\p{L}]/u','',$campaign_id);
|
||||||
|
$and_campaign_id_sql=" and campaign_id='$campaign_id'";
|
||||||
|
$where_campaign_id_sql=" where campaign_id='$campaign_id'";
|
||||||
|
|
||||||
|
# For closer log - how's this work? Query for closer_campaigns? Or by uniqueids?
|
||||||
|
|
||||||
|
$vicidial_log_SQL.=$and_campaign_id_sql;
|
||||||
|
$vicidial_closer_log_SQL.=$and_campaign_id_sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($users)
|
||||||
|
{
|
||||||
|
$users=preg_replace('/[^-_0-9\p{L}]/u','',$users);
|
||||||
|
$users=RemoveEmptyArrayStrings($users);
|
||||||
|
$users_str=is_array($users) ? implode("', '", $users) : "$users";
|
||||||
|
$and_user_sql=" and user in ('$users_str')";
|
||||||
|
$where_user_sql=" where user in ('$users_str')";
|
||||||
|
|
||||||
|
$vicidial_log_SQL.=$and_user_sql;
|
||||||
|
$vicidial_closer_log_SQL.=$and_user_sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($teams)
|
||||||
|
{
|
||||||
|
$teams=preg_replace('/[^-_0-9\p{L}]/u','',$teams);
|
||||||
|
$teams=RemoveEmptyArrayStrings($teams);
|
||||||
|
$teams_str=is_array($teams) ? implode("', '", $teams) : "$teams";
|
||||||
|
|
||||||
|
$team_users="";
|
||||||
|
$team_stmt="select user from vicidial_users where user_group_two in ('$teams_str')";
|
||||||
|
$team_rslt=mysql_to_mysqli($team_stmt, $link);
|
||||||
|
while ($team_row=mysqli_fetch_array($team_rslt))
|
||||||
|
{
|
||||||
|
$team_users.="'$team_row[user]', ";
|
||||||
|
}
|
||||||
|
$team_users=preg_replace('/, $/', "", $team_users);
|
||||||
|
$and_team_sql=" and user in ('$team_users')";
|
||||||
|
$where_team_sql=" where user in ('$team_users')";
|
||||||
|
|
||||||
|
$vicidial_log_SQL.=$and_team_sql;
|
||||||
|
$vicidial_closer_log_SQL.=$and_team_sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($location)
|
||||||
|
{
|
||||||
|
$location=preg_replace('/[^-_0-9\p{L}]/u','',$location);
|
||||||
|
$location=RemoveEmptyArrayStrings($location);
|
||||||
|
$location_str=is_array($location) ? implode("', '", $location) : "$location";
|
||||||
|
$and_location_sql.=" and user_location in ('$location_str')";
|
||||||
|
$where_location_sql.=" where user_location in ('$location_str')";
|
||||||
|
|
||||||
|
# Compile list of additional users based on location
|
||||||
|
$user_location_stmt="select user from vicidial_users where user is not null $LOGadmin_viewable_groupsSQL $and_location_sql";
|
||||||
|
$user_location_rslt=mysql_to_mysqli($user_location_stmt, $link);
|
||||||
|
$users_by_location=array();
|
||||||
|
while ($user_location_row=mysqli_fetch_row($user_location_rslt))
|
||||||
|
{
|
||||||
|
array_push($users_by_location, $user_location_row[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Combine location with selected user
|
||||||
|
if ($users)
|
||||||
|
{
|
||||||
|
array_push($users_by_location, $users);
|
||||||
|
}
|
||||||
|
|
||||||
|
$users_by_location_str=implode("', '", $users_by_location);
|
||||||
|
$and_users_by_location_sql=" and user in ('$users_by_location_str')";
|
||||||
|
$where_users_by_location_sql=" where user in ('$users_by_location_str')";
|
||||||
|
|
||||||
|
$vicidial_agent_log_SQL.=$and_users_by_location_sql;
|
||||||
|
$vicidial_log_SQL.=$and_users_by_location_sql;
|
||||||
|
$vicidial_closer_log_SQL.=$and_users_by_location_sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($user_group)
|
||||||
|
{
|
||||||
|
$user_group=preg_replace('/[^-_0-9\p{L}]/u','',$user_group);
|
||||||
|
$user_group=RemoveEmptyArrayStrings($user_group);
|
||||||
|
$user_group_str=is_array($user_group) ? implode("', '", $user_group) : "$user_group";
|
||||||
|
$and_user_group_sql.=" and user_group in ('$user_group_str')";
|
||||||
|
$where_user_group_sql.=" where user_group in ('$user_group_str')";
|
||||||
|
|
||||||
|
$vicidial_agent_log_SQL.=$and_user_group_sql;
|
||||||
|
$vicidial_log_SQL.=$and_user_group_sql;
|
||||||
|
$vicidial_closer_log_SQL.=$and_user_group_sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($status_name) // shouldn't ever have status and status name
|
||||||
|
{
|
||||||
|
$status_str="";
|
||||||
|
$status_stmt="select status from vicidial_campaign_statuses where status_name='$status_name' UNION select status from vicidial_statuses where status_name='$status_name'";
|
||||||
|
# echo $status_stmt."<BR>";
|
||||||
|
$status_rslt=mysql_to_mysqli($status_stmt, $link);
|
||||||
|
while($status_row=mysqli_fetch_row($status_rslt))
|
||||||
|
{
|
||||||
|
$status_str.="'$status_row[0]', ";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Query settings containers because the status name may be a long version from there...
|
||||||
|
$container_stmt="select * from vicidial_settings_containers where container_id='VERM_STATUS_NAMES_OVERRIDE'";
|
||||||
|
$container_rslt=mysql_to_mysqli($container_stmt, $link);
|
||||||
|
if (mysqli_num_rows($container_rslt)>0)
|
||||||
|
{
|
||||||
|
while($container_row=mysqli_fetch_array($container_rslt))
|
||||||
|
{
|
||||||
|
$container_entry=$container_row["container_entry"];
|
||||||
|
$container_array=explode("\n", $container_entry);
|
||||||
|
for ($i=0; $i<count($container_array); $i++)
|
||||||
|
{
|
||||||
|
# Assumed format of status|status_name
|
||||||
|
if (!preg_match('/^;/', $container_array[$i]))
|
||||||
|
{
|
||||||
|
$new_status=explode("|", $container_array[$i]);
|
||||||
|
if (trim($status_name)==trim($new_status[1]))
|
||||||
|
{
|
||||||
|
$status_str.="'$new_status[0]', ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$status_str=preg_replace('/, $/', "", $status_str);
|
||||||
|
|
||||||
|
|
||||||
|
if (strlen($status_str)>0)
|
||||||
|
{
|
||||||
|
$and_status_sql.=" and status in ($status_str) ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$and_status_sql.=" and status ='' ";
|
||||||
|
}
|
||||||
|
$vicidial_agent_log_SQL.=$and_status_sql;
|
||||||
|
$vicidial_log_SQL.=$and_status_sql;
|
||||||
|
$vicidial_closer_log_SQL.=$and_status_sql;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if ($status) - COmmented this out for when they want to look up no-status calls
|
||||||
|
# {
|
||||||
|
|
||||||
|
# Without this if clause requests coming from the AGENTS page will return zero results
|
||||||
|
if (!$user)
|
||||||
|
{
|
||||||
|
$status=preg_replace('/[^-_0-9\p{L}]/u','',$status);
|
||||||
|
$and_status_sql.=" and status='$status' ";
|
||||||
|
|
||||||
|
$vicidial_agent_log_SQL.=$and_status_sql;
|
||||||
|
$vicidial_log_SQL.=$and_status_sql;
|
||||||
|
$vicidial_closer_log_SQL.=$and_status_sql;
|
||||||
|
}
|
||||||
|
# }
|
||||||
|
}
|
||||||
|
|
||||||
|
$vicidial_agent_log_SQL="$where_event_time_sql".$vicidial_log_SQL;
|
||||||
|
$vicidial_log_SQL="$where_call_date_sql".$vicidial_log_SQL;
|
||||||
|
$vicidial_closer_log_SQL="$where_call_date_sql".$vicidial_closer_log_SQL;
|
||||||
|
|
||||||
|
$selected_columns=array(
|
||||||
|
"Date" => "call_date",
|
||||||
|
"Caller" => "phone_number",
|
||||||
|
"Queue" => "campaign_id",
|
||||||
|
"IVR" => "ivr_duration",
|
||||||
|
"Wait" => "wait",
|
||||||
|
"Duration" => "duration",
|
||||||
|
"Pos." => "queue_position",
|
||||||
|
"Disconnection" => "term_reason",
|
||||||
|
"Handled by" => "user",
|
||||||
|
"Attempts" => "attempts",
|
||||||
|
"Code" => "status",
|
||||||
|
"uniqueid" => "detail_id"
|
||||||
|
);
|
||||||
|
|
||||||
|
$sort_char="";
|
||||||
|
$sort_index="";
|
||||||
|
|
||||||
|
$sort_clause=" order by call_date";
|
||||||
|
$sort_index=preg_replace('/ desc/', '', $sort_answered_details);
|
||||||
|
if (preg_match('/ desc$/', $sort_answered_details))
|
||||||
|
{
|
||||||
|
$sort_char="↓";
|
||||||
|
$reverse_link=preg_replace('/ desc$/', '', $sort_answered_details);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sort_char="↑";
|
||||||
|
$reverse_link=$sort_answered_details." desc";
|
||||||
|
}
|
||||||
|
$sort_answered_details_preg=preg_replace('/ desc$/', '', $sort_answered_details);
|
||||||
|
|
||||||
|
### ALL CALLS FROM vicidial_log AND vicidial_closer_log TABLES - CONTAINS ALL INFO NEEDED BUT DISPO IS UNRELIABLE IN VoxQ
|
||||||
|
$stmt="select call_date, phone_number, campaign_id, 0 as ivr, '0:00' as wait, sec_to_time(round(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 did, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, uniqueid as detail_id, 'O' as direction from vicidial_log $vicidial_log_SQL and user not in ('VDAD') UNION select call_date, phone_number, campaign_id, 0 as ivr, sec_to_time(round(queue_seconds)) as wait, sec_to_time(round(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 did, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, CONCAT(uniqueid, '|', closecallid) as detail_id, 'I' as direction from vicidial_closer_log $vicidial_closer_log_SQL and user not in ('VDCL') $sort_clause";
|
||||||
|
# print $stmt;
|
||||||
|
|
||||||
|
### ALL CALLS FROM vicidial_agent_log - DISPO COUNTS RELIABLE, NEED TO FILL GAPS IN REPORT WITH ADDITIONAL QUERIES
|
||||||
|
# print date("U")."<BR>";
|
||||||
|
$stmt="select event_time+INTERVAL(pause_sec+wait_sec) SECOND as call_date, lead_id, campaign_id, 0 as ivr, '0:00' as wait, sec_to_time(round(talk_sec)) as duration, '1' as queue_position, '' 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 did, '' as url, '' as tag, '0' as feat, '0' as vars, '' as feature_codes, '' as variables, uniqueid as detail_id, if(comments='INBOUND', 'I', 'O') as direction from vicidial_agent_log $vicidial_agent_log_SQL and lead_id is not null";
|
||||||
|
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
# print $stmt.date("U")."<BR>";
|
||||||
|
|
||||||
|
#echo "<table border=0 width='100%' bgcolor='#FFF'><tr>";
|
||||||
|
#echo "<td>";
|
||||||
|
|
||||||
|
## echo "<h2 class='rpt_header'>Call Detail:</h2>";
|
||||||
|
#echo "<div align='right' style='position:fixed; top: 1em; right: 5em'><a onClick='HideOutcomesDetails()'><h2 class='rpt_header'>[X]</h2></a></div></td></tr>";
|
||||||
|
#echo "<tr><td>";
|
||||||
|
|
||||||
|
$HTML_output="<html>\n";
|
||||||
|
$HTML_output.="<title>"._QXZ("$report_name")." - "._QXZ("Outcomes detail display")."</title>";
|
||||||
|
$HTML_output.="<HEAD>\n";
|
||||||
|
$HTML_output.="<script language=\"JavaScript\" src=\"VERM_custom_form_functions.php\"></script>\n";
|
||||||
|
$HTML_output.="<link rel=\"stylesheet\" href=\"calendar.css\">\n";
|
||||||
|
$HTML_output.="<script language=\"JavaScript\" src=\"VERM_functions.js\"></script>\n";
|
||||||
|
$HTML_output.="</head>\n";
|
||||||
|
$HTML_output.="<body>\n";
|
||||||
|
$HTML_output.="<form action='$PHP_SELF' method='POST'>\n";
|
||||||
|
|
||||||
|
$HTML_output.="<input type='hidden' name='vicidial_queue_groups' id='vicidial_queue_groups' value='$vicidial_queue_groups'>\n";
|
||||||
|
$HTML_output.="<input type='hidden' name='user' id='user' value='$user'>\n";
|
||||||
|
$HTML_output.="<input type='hidden' name='users' id='users' value='$users'>\n";
|
||||||
|
$HTML_output.="<input type='hidden' name='user_group' id='user_group' value='$user_group'>\n";
|
||||||
|
$HTML_output.="<input type='hidden' name='campaign_id' id='campaign_id' value='$campaign_id'>\n";
|
||||||
|
$HTML_output.="<input type='hidden' name='location' id='location' value='$location'>\n";
|
||||||
|
$HTML_output.="<input type='hidden' name='status' id='status' value='$status'>\n";
|
||||||
|
$HTML_output.="<input type='hidden' name='status_name' id='status_name' value='$status_name'>\n";
|
||||||
|
$HTML_output.="<input type='hidden' name='start_datetime' id='start_datetime' value='$start_datetime'>\n";
|
||||||
|
$HTML_output.="<input type='hidden' name='end_datetime' id='end_datetime' value='$end_datetime'>\n";
|
||||||
|
$HTML_output.="<input type='hidden' name='report_type' id='report_type' value='$report_type'>\n";
|
||||||
|
$HTML_output.="<input type='hidden' name='download_rpt' id='download_rpt' value='$download_rpt'>\n";
|
||||||
|
$HTML_output.="<input type='hidden' name='sort_answered_details' id='sort_answered_details' value='$sort_answered_details'>\n";
|
||||||
|
|
||||||
|
|
||||||
|
$HTML_output.="<table border=0 width='100%' bgcolor='#FFF'><tr>";
|
||||||
|
$HTML_output.="<td align='left'>";
|
||||||
|
#$HTML_output.="<div style='position:fixed; top: -5; right: -30;'><a onClick='HideAgentDetails()'><h2 class='rpt_header'>[X]</h2></a></div>";
|
||||||
|
#$HTML_output.="<div align='left'><h2 class='rpt_header'>Agent Detail: $user</h2></div>";
|
||||||
|
$HTML_output.="<h2 class='rpt_header'>"._QXZ("Statuses Detail").": $NWB#VERM_display_outcomes_detail$NWE</h2>";
|
||||||
|
$HTML_output.="\n<!-- $stmt //-->\n";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
$HTML_output.="<td align='right'>";
|
||||||
|
$HTML_output.="<a onClick='HideOutcomesDetails()'><h2 class='rpt_header'>[X]</h2></a>";
|
||||||
|
$HTML_output.="</td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
if ($die) {$HTML_output.="</table>\n"; die;}
|
||||||
|
|
||||||
|
$HTML_output.="<tr><td colspan='2'>";
|
||||||
|
|
||||||
|
$HTML_output.="<span id='all_outcomes_details' style='display:block; overflow-y:auto; height: 70vh;'>\n";
|
||||||
|
|
||||||
|
$HTML_output.="<table width='100%' id='details_table'>";
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='left'><B><a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&page_no=1#page_anchor' alt='First page of results'>|<</a> <a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&page_no=".($page_no-1)."#page_anchor' alt='Prev page of results'><<</a></B></td>";
|
||||||
|
|
||||||
|
|
||||||
|
## $HTML_output.="<td class='export_row_cell' align='center' colspan='".(count($selected_columns))."'>Export as... <a href=\"".$PHP_SELF."?download_rpt=answer_details&sort_answered_details=".$sort_answered_details."\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>"; # Current page: $page_no / $total_pages
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='center' colspan='".(count($selected_columns))."'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('OUTCOMES', 'outcomes_details')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
|
||||||
|
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='right'><B><a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&page_no=".($page_no+1)."#page_anchor' alt='Next page of results'>>></a> <a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&page_no=".($total_pages-1)."#page_anchor' alt='Last page of results'>>|</a></B></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
$CSV_output="";
|
||||||
|
foreach ($selected_columns as $display_name => $column_name)
|
||||||
|
{
|
||||||
|
if ($display_name!="uniqueid")
|
||||||
|
{
|
||||||
|
$CSV_output.="\"$display_name\",";
|
||||||
|
# $HTML_output.="<th><a class='header_link' name='call_detail_sort_".$column_name."' id='call_detail_sort_".$column_name."' href='".$PHP_SELF."?sort_answered_details=".($column_name==$sort_answered_details_preg ? "$reverse_link" : "$column_name")."&page_no=".$page_no."#call_detail_sort_".$column_name."'>".$display_name.($column_name==$sort_answered_details_preg ? " $sort_char" : "")."</a></th>";
|
||||||
|
$HTML_output.="<th class='header_link'>".$display_name.($column_name==$sort_answered_details_preg ? " $sort_char" : "")."</th>";
|
||||||
|
|
||||||
|
# $HTML_output.="<th><input type='button' class='sort_button' value='".$display_name.($column_name==$sort_answered_details_preg ? " $sort_char" : "")."' onClick=\"javascript:document.getElementById('sort_answered_details').value='".($column_name==$sort_answered_details_preg ? "$reverse_link" : "$column_name")."'; this.form.submit()\"></th>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$CSV_output.="\n";
|
||||||
|
$HTML_output.="<th> </th>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
|
||||||
|
$output_array=array();
|
||||||
|
$i=0;
|
||||||
|
while ($row=mysqli_fetch_array($rslt))
|
||||||
|
{
|
||||||
|
$row["caller_code"]="";
|
||||||
|
$row["ivr"]="00:00";
|
||||||
|
$row["ivr_duration"]="00:00";
|
||||||
|
$row["ivr_path"]="";
|
||||||
|
$row["did"]="";
|
||||||
|
|
||||||
|
|
||||||
|
$call_info_array=GetCallInfo($row["uniqueid"], $row["lead_id"], $row["call_date"], $row["user"], $row["status"]);
|
||||||
|
$row["phone_number"]=$call_info_array[0];
|
||||||
|
$row["term_reason"]=$call_info_array[1];
|
||||||
|
$row["queue_position"]=$call_info_array[2];
|
||||||
|
|
||||||
|
$uniqueid=$row["uniqueid"];
|
||||||
|
$row["campaign_id"]=$queue_names["$row[campaign_id]"];
|
||||||
|
if ($status_names["$row[status]"]) {$row["status"]=$status_names["$row[status]"];}
|
||||||
|
$row["user"]=$fullname_info["$row[user]"];
|
||||||
|
|
||||||
|
|
||||||
|
$row["caller_code"]=GetCallerCode($row["uniqueid"]);
|
||||||
|
if ($row["direction"]=="I")
|
||||||
|
{
|
||||||
|
$ivr_info_array=GetIVRInfo($row["uniqueid"], $row["call_date"]);
|
||||||
|
$row["ivr"]=$ivr_info_array[0];
|
||||||
|
$row["ivr_duration"]=$ivr_info_array[1];
|
||||||
|
$row["ivr_path"]=$ivr_info_array[2];
|
||||||
|
$row["call_date"]=$ivr_info_array[3];
|
||||||
|
$row["did"]=GetDID($row["uniqueid"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
# if ($i>=$ll && $i<$ul || $download_rpt)
|
||||||
|
# {
|
||||||
|
$current_row=array();
|
||||||
|
foreach ($selected_columns as $display_name => $column_name)
|
||||||
|
{
|
||||||
|
$current_row["$column_name"]=$row["$column_name"];
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($output_array, $current_row);
|
||||||
|
# }
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($sort_index)
|
||||||
|
{
|
||||||
|
#$sort_index=8;
|
||||||
|
# print "***** $sort_index ********\n";
|
||||||
|
# array_multisort($output_array[$sort_index], SORT_ASC, SORT_STRING);
|
||||||
|
|
||||||
|
foreach ($output_array as $sorting_array) {
|
||||||
|
$sort_array_holder[] = $sorting_array["$sort_index"];
|
||||||
|
}
|
||||||
|
if (preg_match('/ desc$/', $sort_answered_details))
|
||||||
|
{
|
||||||
|
array_multisort($sort_array_holder,SORT_DESC, SORT_STRING,$output_array);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_multisort($sort_array_holder,SORT_ASC, SORT_STRING,$output_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
#usort($output_array, function($a, $b){
|
||||||
|
# return strcmp($a[$sort_index], $b[$sort_index]);
|
||||||
|
#});
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($output_array as $data_row)
|
||||||
|
{
|
||||||
|
$HTML_output.="<tr>";
|
||||||
|
foreach ($data_row as $key => $value)
|
||||||
|
{
|
||||||
|
if ($key=="call_date")
|
||||||
|
{
|
||||||
|
$myDateTime = DateTime::createFromFormat('Y-m-d H:i:s', $value);
|
||||||
|
$value = $myDateTime->format('m/d - H:i:s');
|
||||||
|
}
|
||||||
|
if ($key!="detail_id")
|
||||||
|
{
|
||||||
|
$HTML_output.="<td>".$value."</td>";
|
||||||
|
$CSV_output.="\"".$value."\",";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$HTML_output.="<td>-</td>";
|
||||||
|
}
|
||||||
|
# $HTML_output.="<td><IMG SRC=\"images/glass.png\" onClick=\"ShowCallDetails('$value')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP></td>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$CSV_output.="\n";
|
||||||
|
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML_output.="<tr class='export_row'>";
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='left'><B><a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&page_no=1#page_anchor' alt='First page of results'>|<</a> <a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&page_no=".($page_no-1)."#page_anchor' alt='Prev page of results'><<</a></B></td>";
|
||||||
|
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='center' colspan='".(count($selected_columns))."'>Export as... <a href=\"".$PHP_SELF."?download_rpt=answer_details&sort_answered_details=".$sort_answered_details."\" title=\"Export as a CSV file\" class=\"uk-icon\">CSV</a></td>"; # Current page: $page_no / $total_pages
|
||||||
|
$HTML_output.="<td class='export_row_cell' align='center' colspan='".(count($selected_columns))."'>"._QXZ("Export as")."...<input type='button' class='download_button' onClick=\"DownloadReport('OUTCOMES', 'outcomes_details')\" title=\"Export as a CSV file\" value='CSV'></td>";
|
||||||
|
|
||||||
|
# $HTML_output.="<td class='export_row_cell' align='right'><B><a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&page_no=".($page_no+1)."#page_anchor' alt='Next page of results'>>></a> <a class='header_link' href='".$PHP_SELF."?sort_answered_details=".$sort_answered_details."&page_no=".($total_pages-1)."#page_anchor' alt='Last page of results'>>|</a></B></td>";
|
||||||
|
$HTML_output.="</tr>";
|
||||||
|
$HTML_output.="</table>";
|
||||||
|
|
||||||
|
if ($download_rpt)
|
||||||
|
{
|
||||||
|
$data_to_download=$CSV_output;
|
||||||
|
|
||||||
|
$FILE_TIME = date("Ymd-His");
|
||||||
|
$CSVfilename = "OUTCOMES_RPT_".$download_rpt."_".$FILE_TIME.".csv";
|
||||||
|
header('Content-type: application/octet-stream');
|
||||||
|
|
||||||
|
header("Content-Disposition: attachment; filename=\"$CSVfilename\"");
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
ob_clean();
|
||||||
|
flush();
|
||||||
|
|
||||||
|
echo "$data_to_download";
|
||||||
|
|
||||||
|
if ($db_source == 'S')
|
||||||
|
{
|
||||||
|
mysqli_close($link);
|
||||||
|
$use_slave_server=0;
|
||||||
|
$db_source = 'M';
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
$endMS = microtime();
|
||||||
|
$startMSary = explode(" ",$startMS);
|
||||||
|
$endMSary = explode(" ",$endMS);
|
||||||
|
$runS = ($endMSary[0] - $startMSary[0]);
|
||||||
|
$runM = ($endMSary[1] - $startMSary[1]);
|
||||||
|
$TOTALrun = ($runS + $runM);
|
||||||
|
|
||||||
|
# $stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';";
|
||||||
|
# if ($DB) {echo "|$stmt|\n";}
|
||||||
|
# $rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $HTML_output;
|
||||||
|
|
||||||
|
echo "</span>\n";
|
||||||
|
|
||||||
|
echo "</td></tr></table>";
|
||||||
|
|
||||||
|
echo "</form></body></html>";
|
||||||
|
# echo "Download_rpt: $download_rpt";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
function GetCallerCode($uniqueid)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
$caller_code="";
|
||||||
|
$cc_stmt="select caller_code from vicidial_log_extended where uniqueid='$uniqueid'";
|
||||||
|
$cc_rslt=mysqli_query($link, $cc_stmt);
|
||||||
|
$cc_row=mysqli_fetch_array($cc_rslt);
|
||||||
|
$caller_code=$cc_row[0];
|
||||||
|
return $caller_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetCallInfo($uniqueid, $lead_id, $call_date, $user, $status)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
$phone_number="";
|
||||||
|
$term_reason="";
|
||||||
|
$queue_position="";
|
||||||
|
|
||||||
|
if (!$uniqueid)
|
||||||
|
{
|
||||||
|
$ph_stmt="select phone_number, term_reason, queue_position, '1' as priority from vicidial_closer_log where lead_id='$lead_id' and user='$user' and status='$status' UNION
|
||||||
|
select phone_number, term_reason, '1' as queue_position, '2' as priority from vicidial_log where lead_id='$lead_id' and user='$user' and status='$status' UNION
|
||||||
|
select phone_number, '' as term_reason, '1' as queue_position, '3' as priority from vicidial_list where lead_id='$lead_id' UNION
|
||||||
|
select phone_number, '' as term_reason, '1' as queue_position, '4' as priority from vicidial_list_archive where lead_id='$lead_id' order by priority asc limit 1";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$ph_stmt="select phone_number, term_reason, '1' as queue_position, if(lead_id='$lead_id', 2, 0) as priority from vicidial_log where uniqueid='$uniqueid' UNION select phone_number, term_reason, queue_position, if(lead_id='$lead_id', 3, 1) as priority from vicidial_closer_log where uniqueid='$uniqueid' order by priority desc limit 1";
|
||||||
|
}
|
||||||
|
$ph_rslt=mysqli_query($link, $ph_stmt);
|
||||||
|
$ph_row=mysqli_fetch_array($ph_rslt);
|
||||||
|
$phone_number=$ph_row[0];
|
||||||
|
$term_reason=$ph_row[1];
|
||||||
|
$queue_position=$ph_row[2];
|
||||||
|
# print $ph_stmt.date("U")."<BR>";
|
||||||
|
|
||||||
|
# return $phone_number;
|
||||||
|
return array("$phone_number", "$term_reason", "$queue_position");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function GetTermReason($uniqueid)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
$term_reason="NONE";
|
||||||
|
$term_stmt="select term_reason from vicidial_log where uniqueid='$uniqueid' UNION select term_reason from vicidial_closer_log where uniqueid='$uniqueid'";
|
||||||
|
$term_rslt=mysqli_query($link, $term_stmt);
|
||||||
|
if (mysqli_num_rows($term_rslt)>0)
|
||||||
|
{
|
||||||
|
$term_row=mysqli_fetch_array($term_rslt);
|
||||||
|
$term_reason=$term_row[0];
|
||||||
|
}
|
||||||
|
return $term_reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetIVRInfo($uniqueid, $actual_start_time)
|
||||||
|
{
|
||||||
|
global $link, $DB;
|
||||||
|
|
||||||
|
$ivr_path="";
|
||||||
|
$ivr_length=0;
|
||||||
|
$ivr_duration=0;
|
||||||
|
|
||||||
|
$ivr_stmt="select extension,start_time,comment_a,comment_b,comment_d,UNIX_TIMESTAMP(start_time),phone_ext from live_inbound_log where uniqueid='$uniqueid' and comment_a IN('CALLMENU') order by start_time";
|
||||||
|
$ivr_rslt=mysqli_query($link, $ivr_stmt);
|
||||||
|
$ivr_paths=array(); # 0 - total calls, 1 - total time, 2 - min time, 3 - max time
|
||||||
|
$ivr_counts=array();
|
||||||
|
while ($ivr_row=mysqli_fetch_array($ivr_rslt))
|
||||||
|
{
|
||||||
|
if(!$prev_time) {$prev_time=$ivr_row[5];}
|
||||||
|
if(!$ivr_start_time)
|
||||||
|
{
|
||||||
|
$actual_start_time=$ivr_row[1];
|
||||||
|
$ivr_start_time=$ivr_row[5];
|
||||||
|
}
|
||||||
|
$ivrpath.=$ivr_row["comment_b"];
|
||||||
|
|
||||||
|
$ivr_duration=$ivr_row[5]-$ivr_start_time;
|
||||||
|
$ivr_length+=$ivr_duration;
|
||||||
|
$prev_time=$ivr_row[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
$ivr_duration_fmt=($ivr_duration>=3600 ? floor($ivr_duration/3600).":" : "").gmdate("i:s", $ivr_duration);
|
||||||
|
$ivr_length_fmt=($ivr_length>=3600 ? floor($ivr_length/3600).":" : "").gmdate("i:s", $ivr_length);
|
||||||
|
|
||||||
|
return array("$ivr_length_fmt", "$ivr_duration_fmt", "$ivr_path", "$actual_start_time");
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetDID($uniqueid)
|
||||||
|
{
|
||||||
|
global $link, $DB, $did_id_info, $did_pattern_info;
|
||||||
|
|
||||||
|
$did_str="";
|
||||||
|
|
||||||
|
$did_stmt="select extension, did_id from vicidial_did_log where uniqueid in ('$uniqueid')";
|
||||||
|
$did_rslt=mysqli_query($link, $did_stmt);
|
||||||
|
$did_row=mysqli_fetch_array($did_rslt);
|
||||||
|
$did_str=$did_row["extension"]." - ".$did_id_info["$did_row[extension]"];
|
||||||
|
|
||||||
|
return $did_str;
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
// help.js
|
||||||
|
//
|
||||||
|
// Copyright (C) 2018 Matt Florell <vicidial@gmail.com>, Joe Johnson <freewermadmin@gmail.com> LICENSE: AGPLv2
|
||||||
|
//
|
||||||
|
// Javascript functions for displaying/hiding/moving/populating the help span with text
|
||||||
|
//
|
||||||
|
// CHANGELOG:
|
||||||
|
// 180501-0045 - First build
|
||||||
|
|
||||||
|
// Detect if the browser is IE or not.
|
||||||
|
// If it is not IE, we assume that the browser is NS.
|
||||||
|
var IE = document.all?true:false
|
||||||
|
// If NS -- that is, !IE -- then set up for mouse capture
|
||||||
|
if (!IE) document.captureEvents(Event.MOUSEMOVE)
|
||||||
|
|
||||||
|
|
||||||
|
function ClearAndHideHelpDiv() {
|
||||||
|
document.getElementById("HelpDisplayDiv").innerHTML="";
|
||||||
|
document.getElementById("HelpDisplayDiv").style.display="none";
|
||||||
|
}
|
||||||
|
|
||||||
|
function FillAndShowHelpDiv(e, help_id)
|
||||||
|
{
|
||||||
|
var help_text_id=help_id.replace("#", "");
|
||||||
|
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";
|
||||||
|
|
||||||
|
|
||||||
|
var HelpVerbiage = null;
|
||||||
|
|
||||||
|
var xmlhttp=false;
|
||||||
|
/*@cc_on @*/
|
||||||
|
/*@if (@_jscript_version >= 5)
|
||||||
|
// JScript gives us Conditional compilation, we can cope with old IE versions.
|
||||||
|
// and security blocked creation of the objects.
|
||||||
|
try {
|
||||||
|
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
|
||||||
|
} catch (e) {
|
||||||
|
try {
|
||||||
|
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
|
||||||
|
} catch (E) {
|
||||||
|
xmlhttp = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@end @*/
|
||||||
|
if (!xmlhttp && typeof XMLHttpRequest!='undefined')
|
||||||
|
{
|
||||||
|
xmlhttp = new XMLHttpRequest();
|
||||||
|
}
|
||||||
|
if (xmlhttp)
|
||||||
|
{
|
||||||
|
helptext_query = "action=grab_help_text&help_id=" + help_text_id;
|
||||||
|
xmlhttp.open('POST', 'display_help.php');
|
||||||
|
xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
|
||||||
|
xmlhttp.send(helptext_query);
|
||||||
|
xmlhttp.onreadystatechange = function()
|
||||||
|
{
|
||||||
|
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
|
||||||
|
{
|
||||||
|
HelpVerbiage = xmlhttp.responseText;
|
||||||
|
document.getElementById("HelpDisplayDiv").innerHTML=HelpVerbiage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete xmlhttp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,143 @@
|
|||||||
|
# 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>
|
||||||
|
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>
|
||||||
|
VERM_admin-realtime_reports Real-time reports <QXZ>These are links to the main wallboard report and the real-time report.</QXZ>
|
||||||
|
VERM_admin-quick_reports Quick Activity reports <QXZ>Clicking on any of these links will take you to a report for the date range you click on, for whatever queue/agent/report type is selected on the page at the time.</QXZ>
|
||||||
|
VERM_admin-custom_report Custom report <QXZ>This will take you to a web form allowing you to run a custom enhanced report you can define by many more parameters than are given from the main report page.</QXZ>
|
||||||
|
VERM_admin-wallboards Wallboard <QXZ>This is a link to a special real-time report that will show up-to-the-second stats for various ingroups/campaigns/users throughout the current day.</QXZ>
|
||||||
|
VERM_admin-settings Settings <QXZ>All links provided in this section point to the corresponding settings pages in the administrator interface, where users/queues/user groups/etc can be added/modified/deleted.</QXZ>
|
||||||
|
VERM_header-atomic_queues Campaigns/ingroups considered <QXZ>This is a list of all the campaigns and ingroups that are categorized under the selected report queue.</QXZ>
|
||||||
|
VERM_header-period_start_date Period start date <QXZ>This is the start date and time used for querying the database to generate the stats displayed.</QXZ>
|
||||||
|
VERM_header-period_end_date Period end date <QXZ>This is the end date and time used for querying the database to generate the stats displayed.</QXZ>
|
||||||
|
VERM_header-total_calls_processed Total calls processed <QXZ>This is the sum of all inbound and outbound calls from the outbound call log and inbound call log tables per the report parameters defined by the user, excluding any disposition given in the "exc_addtl_statuses" variable in the "VERM_REPORT_OPTIONS" settings container (by default only "AFTHRS" calls are excluded). Answered calls are counted as such if there is a user ID on the log other than "VDAD" or "VDCL". Ergo, calls are considered unanswered if the user ID on the log record reads "VDAD" or "VDCL".</QXZ>
|
||||||
|
VERM_header-ratio Ratio <QXZ>The percentage breakdown of answered and unanswered calls per the report parameters defined by the user. This is also visually represented by the donut graph below it.</QXZ>
|
||||||
|
VERM_header-buttons Search/Link/CSV buttons <QXZ>"Search" takes you to the custom report page. "Link" will give a full URL to the current page you're looking at. "CSV" will download the "Report details" section as a CSV file.</QXZ>
|
||||||
|
VERM_ANSWERED-all_calls All calls <QXZ>This is a set of information pertaining to ONLY answered calls within the report parameters based on the information in the outbound call log and inbound call log tables. "N. calls answered by operators" should always match the count of answered calls shown in the "Total calls processed" statistic in the report header.</QXZ>
|
||||||
|
VERM_ANSWERED-all_calls_call_length Average/Min/max/total call length <QXZ>Average call length is the sum of all answered call lengths divided by the number of answered calls, represented in seconds. Min call length is the shortest call length of all answered calls, based on the length_in_sec value in the log tables. Ergo, the max call length is the longest call length of the answered calls. Total call length is the sum of all length_in_sec values for all answered calls from both the outbound call log and inbound call log tables (if the report queue covers either/both tables), converted from seconds to hours as a decimal value. </QXZ>
|
||||||
|
VERM_ANSWERED-all_calls_waiting_time Average/Min/max/total waiting time <QXZ><B>Wait time only comes from inbound calls (queue_sec), as outbound calls do not have wait time.</B> Average call waiting time is the sum of all answered calls' wait time divided by the number of answered calls, represented in seconds. Min waiting time is the shortest wait time found on all answered calls within the report parameters. Ergo, the max wait time is the longest wait time found on the answered calls. Total wait time is the sum of all queue_sec values from the inbound call log tables (if the report queue covers inbound calls), and zero from the outbound call logs (see bolded text above), converted from seconds to hours as a decimal value. </QXZ>
|
||||||
|
VERM_ANSWERED-all_calls_position Average/Min/max initial positions <QXZ><B>Outbound calls have a position of '1'.</B> Position refers to the priority/order of a call based on when it is placed (outbound) or received (inbound). Average initial position is the sum of the positions of each call - for inbound calls this is the queue_position column from the closer log - divided by the number of answered calls within the report parameters. Min position is the smallest position value of all answered calls - this will always be '1' if any outbound calls are involved. Max position is the largest queue position of all answered calls. </QXZ>
|
||||||
|
VERM_ANSWERED-coverage Coverage <QXZ>This is always 100% - Ask Matt about removing</QXZ>
|
||||||
|
VERM_ANSWERED-all_calls_wi Calls - time interval <QXZ>This is the same set of data for answered calls, except this deals only with calls that are fully within the time frame given by the report parameters. This means that calls which start before the period start date or end after the period start date will not be counted here.</QXZ>
|
||||||
|
VERM_ANSWERED-all_calls_call_length_wi Average/Min/max/total call length <QXZ>Average call length is the sum of all answered call lengths divided by the number of answered calls, represented in seconds. Min call length is the shortest call length of all answered calls, based on the length_in_sec value in the log tables. Ergo, the max call length is the longest call length of the answered calls. Total call length is the sum of all length_in_sec values for all answered calls from both the outbound call log and inbound call log tables (if the report queue covers either/both tables), converted from seconds to hours as a decimal value. </QXZ>
|
||||||
|
VERM_ANSWERED-all_calls_waiting_time_wi Average/Min/max/total waiting time <QXZ><B>Wait time only comes from inbound calls (queue_sec), as outbound calls do not have wait time.</B> Average call waiting time is the sum of all answered calls' wait time divided by the number of answered calls, represented in seconds. Min waiting time is the shortest wait time found on all answered calls within the report parameters. Ergo, the max wait time is the longest wait time found on the answered calls. Total wait time is the sum of all queue_sec values from the inbound call log tables (if the report queue covers inbound calls), and zero from the outbound call logs (see bolded text above), converted from seconds to hours as a decimal value. </QXZ>
|
||||||
|
VERM_ANSWERED-all_calls_position_wi Average/Min/max init. positions <QXZ><B>Outbound calls have a position of '1'.</B> Position refers to the priority/order of a call based on when it is placed (outbound) or received (inbound). Average initial position is the sum of the positions of each call - for inbound calls this is the queue_position column from the closer log - divided by the number of answered calls within the report parameters. Min position is the smallest position value of all answered calls - this will always be '1' if any outbound calls are involved. Max position is the largest queue position of all answered calls. </QXZ>
|
||||||
|
VERM_ANSWERED-coverage_wi Coverage <QXZ>This is always 100% - Ask Matt about removing</QXZ>
|
||||||
|
VERM_ANSWERED-agents_on_queue Agents on queue <QXZ>This sub-report gives a per-agent breakdown of all answered calls within the report parameters. It shows how many calls each agent answered, the percentage of calls they answered relative to the total number of calls answered, a simple bar graph representation of said percentage, and also the total time the agent spent in calls (based on the length_in_sec from the outbound and inbound logs) and the average time per call the agent spent.</QXZ>
|
||||||
|
VERM_ANSWERED-SLA Service Level Agreement <QXZ>This sub-report deals with inbound calls and shows the number of calls answered within set intervals. By default the initial interval is 5 seconds, up to a period of 20 seconds, at which point the interval becomes 10 seconds up to 120 seconds. These values (initial interval, initial period, interval, max period) can be adjusted by running a custom report. The report shows the number of calls answered within each interval, along with the delta (change) from interval to interval. The "Percent" refers to the number of calls answered within the interval relative to the total calls, and the "Of offered" percent is the number of total calls within the interval relative to the total calls, along with a simple bar graph representing the answered calls percentage and line graph charting the deltas and percentages.</QXZ>
|
||||||
|
VERM_ANSWERED-disconnections Disconnections <QXZ>This sub-report is a simple breakdown of the disconnection causes for the answered calls found within the report parameters. It shows how many calls were disconnected for each reason, the percent of the total calls these causes comprise, and a simple bar graph showing the percentage of each cause relative to one another, along with a pie chart of all causes.</QXZ>
|
||||||
|
VERM_ANSWERED-transfers Transfers <QXZ>This is a relatively simple sub-report that breaks down, per in-group, the number of transfers made on calls matching the report criteria. Additionally, the report shows per-ingroup the percentage of transfers made to that ingroup against all transfers pulled for the report.</QXZ>
|
||||||
|
VERM_ANSWERED-calls_by_queue Answered calls, by queue <QXZ>As the name suggests, this sub-report breaks down the number of answered calls by queue element (i.e. campaign and ingroup). It will show the queue, number of calls, percentage of calls to this queue relative to all answered calls, a bar graph showing the number of answered calls relative to each queue, and a pie chart summing up the number of calls for each queue.</QXZ>
|
||||||
|
VERM_ANSWERED-calls_by_direction Answered calls, by direction <QXZ>This sub-report breaks down the number of answered calls by direction, inbound or outbound. It will show the direction, number of calls, percentage of calls to the direction relative to all answered calls, a bar graph showing the number of answered calls relative to each direction, and a pie chart summing up the number of calls for each direction.</QXZ>
|
||||||
|
VERM_ANSWERED-queue_position Queue position <QXZ>This sub-report breaks down the number of answered calls by position (i.e. what order the call was placed in when it was made from/received in the system). It will show the position, number of calls, percentage of calls to the position relative to all answered calls, a bar graph showing the number of answered calls relative to each position, and a pie chart summing up the number of calls for each position.</QXZ>
|
||||||
|
VERM_ANSWERED-ivr_selection IVR selection <QXZ>This sub-report breaks down the number of answered calls by IVR path (i.e. the call menus and prompts, if any, that a call went through), and "Untracked" if the call did not pass through an IVR. It will show the path, number of calls, percentage of calls to the path relative to all answered calls, a bar graph showing the number of answered calls relative to each path, and a pie chart summing up the number of calls for each path.</QXZ>
|
||||||
|
VERM_ANSWERED-did_used DID used <QXZ>This sub-report breaks down the number of answered calls by DID that the caller used, and will show "Untracked" if the call was not made through a DID. It will show the DID extension and DID name, number of calls, percentage of calls to the DID relative to all answered calls, a bar graph showing the number of answered calls relative to each DID, and a pie chart summing up the number of calls for each DID.</QXZ>
|
||||||
|
VERM_ANSWERED-parked_calls_by_agent Parked Calls by Agent <QXZ>This shows a breakdown per-agent of the number of times calls were parked based on the report criteria. The data is compiled using report parameters that are found in the park_log table: user, campaign, server, caller_code, parked_time, and uniqueid (uniqueIDs are gathered from the DID/inbound/outbound call log tables where appropriate). In addition to the park count breakdown per agent, the report will also calculate average park attempts per call, total time the agents left calls in park, and the average duration of the agent's total park intervals.</QXZ>
|
||||||
|
VERM_ANSWERED_DT-details Queue Details <QXZ>This shows each individual answered call matching the report criteria in a page format, 20 results per page. The results can be sorted by clicking on the corresponding column header - results are sorted <i>only for the current page</i>. Additionally, the magnifying glass icon next to each call can be clicked on to display even more detailed information. Also, the results can be downloaded as a CSV document via the CSV link.</QXZ>
|
||||||
|
VERM_UNANSWERED-all_calls All calls <QXZ>This is a set of information pertaining to ONLY unanswered calls within the report parameters based on the information in the outbound call log and inbound call log tables. "N. calls unanswered" should always match the count of unanswered calls shown in the "Total calls processed" statistic in the report header.</QXZ>
|
||||||
|
VERM_UNANSWERED-all_calls_waiting_time Average/Min/max/total waiting time before disconnection <QXZ><B>Wait time only comes from inbound calls (queue_sec), as outbound calls do not have wait time.</B> Average call waiting time is the sum of all unanswered calls' wait time divided by the number of unanswered calls, represented in seconds. Min waiting time is the shortest wait time found on all unanswered calls within the report parameters. Ergo, the max wait time is the longest wait time found on the unanswered calls. Total wait time is the sum of all queue_sec values from the inbound call log tables (if the report queue covers inbound calls), and zero from the outbound call logs (see bolded text above), converted from seconds to hours as a decimal value. </QXZ>
|
||||||
|
VERM_UNANSWERED-all_calls_position Average/min/max queue position at disconnect <QXZ><B>Outbound calls have a position of '1'.</B> Position refers to the priority/order of a call based on when it is placed (outbound) or received (inbound). Average initial position is the sum of the positions of each call - for inbound calls this is the queue_position column from the closer log - divided by the number of unanswered calls within the report parameters. Min position is the smallest position value of all unanswered calls - this will always be '1' if any outbound calls are involved. Max position is the largest queue position of all unanswered calls. </QXZ>
|
||||||
|
VERM_UNANSWERED-coverage Coverage <QXZ>This is always 100% - Ask Matt about removing</QXZ>
|
||||||
|
VERM_UNANSWERED-position Position at disconnection <QXZ>Unmeasurable - ask about removing.</QXZ>
|
||||||
|
VERM_UNANSWERED-all_calls_wi Calls - time interval <QXZ>This is the same set of data for unanswered calls, except this deals only with calls that are fully within the time frame given by the report parameters. This means that calls which start before the period start date or end after the period start date will not be counted here.</QXZ>
|
||||||
|
VERM_UNANSWERED-all_calls_waiting_time_wi Average/Min/max/total waiting time before disconnection <QXZ><B>Wait time only comes from inbound calls (queue_sec), as outbound calls do not have wait time.</B> Average call waiting time is the sum of all unanswered calls' wait time divided by the number of unanswered calls, represented in seconds. Min waiting time is the shortest wait time found on all unanswered calls within the report parameters. Ergo, the max wait time is the longest wait time found on the unanswered calls. Total wait time is the sum of all queue_sec values from the inbound call log tables (if the report queue covers inbound calls), and zero from the outbound call logs (see bolded text above), converted from seconds to hours as a decimal value. </QXZ>
|
||||||
|
VERM_UNANSWERED-all_calls_position_wi Average/min/max initial positions <QXZ><B>Outbound calls have a position of '1'.</B> Position refers to the priority/order of a call based on when it is placed (outbound) or received (inbound). Average initial position is the sum of the positions of each call - for inbound calls this is the queue_position column from the closer log - divided by the number of unanswered calls within the report parameters. Min position is the smallest position value of all unanswered calls - this will always be '1' if any outbound calls are involved. Max position is the largest queue position of all unanswered calls. </QXZ>
|
||||||
|
VERM_UNANSWERED-coverage_wi Coverage <QXZ>This is always 100% - Ask Matt about removing</QXZ>
|
||||||
|
VERM_UNANSWERED-position_wi Position at disconnection <QXZ>Unmeasurable - ask about removing.</QXZ>
|
||||||
|
VERM_UNANSWERED-disconnections Disconnection causes <QXZ>This sub-report is a simple breakdown of the disconnection causes for the unanswered calls found within the report parameters. It shows how many calls were disconnected for each reason, the percent of the total calls these causes comprise, and a simple bar graph showing the percentage of each cause relative to one another, along with a pie chart of all causes.</QXZ>
|
||||||
|
VERM_UNANSWERED-calls_by_queue Unanswered calls, by campaign/ingroup <QXZ>As the name suggests, this sub-report breaks down the number of unanswered calls by campaign/ingroup. It will show the campaign/ingroup, number of calls, percentage of calls to this campaign/ingroup relative to all unanswered calls, a bar graph showing the number of unanswered calls relative to each campaign/ingroup, and a pie chart summing up the number of calls for each campaign/ingroup.</QXZ>
|
||||||
|
VERM_UNANSWERED-calls_by_agent Unanswered calls, by agent <QXZ>As the name suggests, this sub-report breaks down the number of unanswered calls by agent. It will show the agent, number of calls, percentage of calls to this agent relative to all unanswered calls, a bar graph showing the number of unanswered calls relative to each agent, and a pie chart summing up the number of calls for each agent (this is almost always the standard VDAD/VDCL "agent").</QXZ>
|
||||||
|
VERM_UNANSWERED-calls_by_length Unanswered calls, distribution by length (inbound calls only) <QXZ>This sub-report deals with inbound calls and shows the number of calls unanswered within set intervals. By default the initial interval is 5 seconds, up to a period of 20 seconds, at which point the interval becomes 10 seconds up to 120 seconds. These values (initial interval, initial period, interval, max period) can be adjusted by running a custom report. The report shows the number of unanswered calls within each interval, along with the delta (change) from interval to interval. The "Percent" refers to the number of unanswered calls within the interval relative to the total calls, and the "Of offered" percent is the number of total calls within the interval relative to the total calls, along with a simple bar graph representing the unanswered calls percentage and line graph charting the deltas and percentages.</QXZ>
|
||||||
|
VERM_UNANSWERED-inclusive_SLA Inclusive SLA (computed on both answered and unanswered calls, inbound only) <QXZ>This sub-report deals with inbound calls and shows the number of calls within set intervals, both answered and unanswered. By default the initial interval is 5 seconds, up to a period of 20 seconds, at which point the interval becomes 10 seconds up to 120 seconds. These values (initial interval, initial period, interval, max period) can be adjusted by running a custom report. The report shows the number of calls within each interval, along with the delta (change) from interval to interval. The "Percent" refers to the number of calls within the interval relative to the total calls, and the "Of offered" percent is the number of total calls within the interval relative to the total calls, along with a simple bar graph representing the call percentages and line graph charting the deltas and percentages.</QXZ>
|
||||||
|
VERM_UNANSWERED-calls_by_keypress Unanswered calls, by keypress/option <QXZ>This sub-report breaks down the number of IVR (callmenu) keypresses/options all unanswered calls accumulated. Because a call can record multiple keypresses/options, the total here can be higher than the actual number of calls. It will show the keypress/option, number of times each keypress/option was selected, percentage of this keypress/option relative to all keypresses/options, a bar graph showing the number of keypresses/options relative to each other, and a pie chart summing up the number of keypresses/options.</QXZ>
|
||||||
|
VERM_UNANSWERED-queue_position Enter queue position <QXZ>This sub-report breaks down the number of unanswered calls by initial queue position (i.e. what order the call was placed in when it was made from/received in the system). It will show the position, number of calls, percentage of calls to the position relative to all unanswered calls, a bar graph showing the number of unanswered calls relative to each position, and a pie chart summing up the number of calls for each position.</QXZ>
|
||||||
|
VERM_UNANSWERED-queue_position_all_calls Queue position, all calls <QXZ>This sub-report breaks down the number of calls by initial queue position (i.e. what order the call was placed in when it was made from/received in the system). It will show the position, number of calls, percentage of calls to the position relative to the total of calls, a bar graph showing the number of calls relative to each position, and a pie chart summing up the number of calls for each position.</QXZ>
|
||||||
|
VERM_UNANSWERED-ivr_selection IVR selection <QXZ>This sub-report breaks down the number of unanswered calls by IVR path (i.e. the call menus and prompts, if any, that a call went through), and "Untracked" if the call did not pass through an IVR. It will show the path, number of calls, percentage of calls to the path relative to all unanswered calls, a bar graph showing the number of unanswered calls relative to each path, and a pie chart summing up the number of calls for each path.</QXZ>
|
||||||
|
VERM_UNANSWERED-ivr_selection_all_calls IVR selection, all calls <QXZ>This sub-report breaks down the number of calls by IVR path (i.e. the call menus and prompts, if any, that a call went through), and "Untracked" if the call did not pass through an IVR. It will show the path, number of calls, percentage of calls to the path relative to all calls, a bar graph showing the number of unanswered calls relative to each path, and a pie chart summing up the number of calls for each path.</QXZ>
|
||||||
|
VERM_UNANSWERED-did_used DID used <QXZ>This sub-report breaks down the number of unanswered calls by DID that the caller used, and will show "Untracked" if the call was not made through a DID. It will show the DID extension and DID name, number of calls, percentage of calls to the DID relative to all unanswered calls, a bar graph showing the number of unanswered calls relative to each DID, and a pie chart summing up the number of calls for each DID.</QXZ>
|
||||||
|
VERM_UNANSWERED-did_used_all_calls DID used, for all calls <QXZ>This sub-report breaks down the number of calls by DID that the caller used, and will show "Untracked" if the call was not made through a DID. It will show the DID extension and DID name, number of calls, percentage of calls to the DID relative to all calls, a bar graph showing the number of calls relative to each DID, and a pie chart summing up the number of calls for each DID.</QXZ>
|
||||||
|
VERM_UNANSWERED-call_overview Call overview <QXZ>This sub-report gives a per-queue breakdown of all calls within the report parameters. It shows how many calls were offered (i.e. made (outbound) or received (inbound)) in each queue, the number of calls answered in each queue, the number of calls lost (unanswered) in each queue, the average length of all offered calls, the total call length, the average time each call to the queue spent waiting, and the total amount of time calls to that queue were waiting.</QXZ>
|
||||||
|
VERM_UNANSWERED-inclusive_answered_SLA Inclusive answered SLA (inbound answered calls only) <QXZ>This sub-report deals with inbound answered calls and shows the number of calls answered within set intervals. By default the initial interval is 5 seconds, up to a period of 20 seconds, at which point the interval becomes 10 seconds up to 120 seconds. These values (initial interval, initial period, interval, max period) can be adjusted by running a custom report. The report shows the number of calls answered within each interval, along with the delta (change) from interval to interval. The "Percent" refers to the number of calls answered within the interval relative to the total calls, and the "Of offered" percent is the number of total calls within the interval relative to the total calls, along with a simple bar graph representing the answered calls percentage and line graph charting the deltas and percentages.</QXZ>
|
||||||
|
VERM_UNANSWERED_DT-details Unanswered Call Details <QXZ>This shows each individual unanswered call matching the report criteria in a page format, 20 results per page. The results can be sorted by clicking on the corresponding column header - results are sorted <i>only for the current page</i>. Additionally, the magnifying glass icon next to each call can be clicked on to display even more detailed information. Also, the results can be downloaded as a CSV document via the CSV link.</QXZ>
|
||||||
|
VERM_IVR-ivr_traversal IVR Traversal <QXZ>This subreport shows all IVR traversal paths taken for calls matching the report parameters and the number of calls that followed each path. A traversal path shows what IVR/callmenus the call went through, and each path also will show a breakdown of the keypresses/options that the calls ended with. In addition to the number of calls, the report will also show how many calls were "goals" (i.e. made it to a queue), and how many were hangups/unanswered, with corresponding percentages for each. Each keypress/option will also have it's own goals/hangups count as well.</QXZ>
|
||||||
|
VERM_IVR-ivr_timing IVR Timing <QXZ>This subreport shows all IVR traversal paths taken for calls matching the report parameters and the number of calls that followed each path, along with time statistics for each. A traversal path shows what IVR/callmenus the call went through, and each path also will show a breakdown of the keypresses/options that the calls ended with. In addition to the number of calls, the report will also show the average time a call spent on a path, as well as the total time, minimum time (shortest call of the ones counts) and maximum time (longest call of the ones counted). Each keypress/option will also have it's own time statistics calculated as well.</QXZ>
|
||||||
|
VERM_IVR-ivr_goals IVR Goals <QXZ>This subreport shows all goals reached for calls matching the report parameters and the IVR traversal path that was followed to reach said goal. If a goal is reached via multiple paths within the report results, each path is displayed as a separate line in the report. Each line will show the final selection/keypress/option followed to reach the goal, the number of calls that followed that exact path (including selection/keypress/option), along with the average, minimum, and maximum call length for the associated calls.</QXZ>
|
||||||
|
VERM_IVR-ivr_details IVR Details <QXZ>This subreport shows every individual call matching the report parameters that went through an IVR traversal path. It shows call date and time, the caller's phone number, the traversal path, the DID they called in from, and the goal the call reached. Additionally, the magnifying glass icon next to each call can be clicked on to display even more detailed information.</QXZ>
|
||||||
|
VERM_IVR-ivr_survey_details IVR Details for survey <QXZ>This is a special detailed report showing information for calls that went to a survey group and the survey results. It shows call date/time, the caller phone number, the inbound DID they dialed (if any), and the details report will also show every possible survey prompt for the survey group and what the caller entered at each prompt. If the survey has an associated voicemail, that will be shown. Also, the agent who spoke to the caller prior to passing the caller to the survey will be displayed as well as a link to the recording of said call with the agent.</QXZ>
|
||||||
|
VERM_AREA-CLID Number of CLID digits to search <QXZ>This report parameter tells how many digits to limit the area code length to. By default it's 3 digits but can be as high as 12.</QXZ>
|
||||||
|
VERM_AREA-starting_position Starting from position <QXZ>This report parameter tells what position to start at for all phone numbers when performing the area code search. By default it's set to "1", meaning it will pull the report results for the number of CLID digits starting at the first digit in the number. You can specify a different starting position depending on your needs. For instance if all your phone numbers start with a country code of "1", you can set the position to "2" to trim those off. Or if you wanted a breakdown by US exchange, you can start at position "4".</QXZ>
|
||||||
|
VERM_AREA-answered_details Detail for answered calls <QXZ>This report shows a breakdown of area codes/caller IDs (caller IDs defined by the agent via the CLID/position report settings) for the number of answered calls to each area code within the time code for the report. It also shows the total call length of the calls to each area code, the average time spent in each call, and the average time each call spent waiting to be answered.</QXZ>
|
||||||
|
VERM_AREA-unanswered_details Detail for unanswered calls <QXZ>This report shows a breakdown of area codes/caller IDs (caller IDs defined by the agent via the CLID/position report settings) for the number of unanswered calls to each area code within the time code for the report. It also shows the average time each call spent waiting to be answered, and the average initial queue position of the calls for each area code.</QXZ>
|
||||||
|
VERM_ATT-acd_by_queue ACD attempts by campaign/ingroup <QXZ>This shows a breakdown by campaign/ingroup of the number of calls to/from selected campaigns/ingroups. "Lost" calls are calls with statuses from the "lost_statuses" list of dispositions defined in the "VERM_REPORT_OPTIONS" settings container. Avr ring and ring refer to the average amount of time and total time lost calls were spent ringing (waiting). "N. taken" is the number of calls handled by a campaign/ingroup, and avg ring and ring refer to the average time and total time the calls in each campaign/ingroup spend in ringing/waiting mode. This only applies to inbound calls/ingroups, as outbound calls don't measure ring time.</QXZ>
|
||||||
|
VERM_ATT-acd_by_agent ACD attempts by agent <QXZ>This shows a breakdown by queue of the number of calls to/from agents. "Lost" calls are calls with statuses from the "lost_statuses" list of dispositions defined in the "VERM_REPORT_OPTIONS" settings container. Avr ring and ring refer to the average amount of time and total time lost calls were spent ringing (waiting). "N. taken" is the number of calls handled by an agent, and avg ring and ring refer to the average time and total time the calls to each agent spend in ringing/waiting mode. This only applies to inbound calls/ingroups, as outbound calls don't measure ring time.</QXZ>
|
||||||
|
VERM_DAY-answered_call_distribution Answered call distribution by day <QXZ>This shows the number of answered calls within the selected report parameters broken down by day. Each date displays the number of calls answered, the percentage that were answered that day relative to the entire date range, and a bar graph representing the number of calls answered that day relative to the other dates in the report date range. Additionally, each date shows the average/minimum/maximum call lengths for each date, and another simple bar graph representing the average call length for that date relative to the other dates' average call lengths.</QXZ>
|
||||||
|
VERM_DAY-answered_call_wait_time Answered call wait time per day <QXZ>This shows the number of answered calls within the selected report parameters broken down by day. Each date displays the number of calls answered, the percentage that were answered that day relative to the entire date range, and a bar graph representing the number of calls answered that day relative to the other dates in the report date range. Additionally, each date shows the average/minimum/maximum wait time for each date, and another simple bar graph representing the average wait time for that date relative to the other dates' average wait times.</QXZ>
|
||||||
|
VERM_DAY-unanswered_call_wait_time Unanswered call wait time per day <QXZ>This shows the number of unanswered calls within the selected report parameters broken down by day. Each date displays the number of unanswered calls, the percentage that went unanswered that day relative to the entire date range, and a bar graph representing the number of unanswered calls that day relative to the other dates in the report date range. Additionally, each date shows the average/minimum/maximum wait time, and another simple bar graph representing the average wait time for that date relative to the other dates' average wait times.</QXZ>
|
||||||
|
VERM_DAY-sales_per_day Sales per day <QXZ>This report gives information on sales per day. For each day within the given date range, the report gives the percentage of human answered calls (determined by the "human answered" parameter on statuses in the admin) that resulted in a sale. It also gives the percentage of customer contact calls for that day (determined by the "customer contact" parameter on statuses in the admin) that resulted in a sale. Following that is the count of sales for that date and the percentage of the total sales that came from that date, as well as a bar graph representing the number of sales relative to other date's sales in the same range. A call is determined to be a sale if the call status has it's "Sale" attribute set to "Y" in the system. After that is the total of human answers and customer contacts for the date, the percent of customer contacts from the total date range that came from that date, and a bar graph representing the number of customer contacts relative to other date's customer contacts in the same range.</QXZ>
|
||||||
|
VERM_DAY-queue_length_per_day Queue length per day <QXZ>This report gives information on the queue positions of calls within the report parameters. Per day, it will show the average queue position and a bar graph representing the average queue position per day relative to other dates' queue positions under the same report parameters. It will also show the minimum and maximum queue positions recorded for that date and another bar graph for the maximum queue position for that date relative to other dates. It will also show the coverage percentage (percent of calls with queue position), and the number of steps, which is the average sum of the queue positions per hour - 24 hours is used for this calculation, even for a partial day.</QXZ>
|
||||||
|
VERM_DAY-schedule_adherence Schedule Adherence per Day <QXZ>This report will show per day how many distinct agents were logged in for that day - days where there were no agents logged in are skipped. It will also show a percent which is the number of distinct agents that day against the total number of distinct agents per day for the report interval (i.e. the sum of all percentages show here should add up to 100%), and a bar graph representing the percentage.</QXZ>
|
||||||
|
VERM_DAY-inclusive_SLA Inclusive SLA per day (inbound and outbound) <QXZ>This sub-report shows the number of calls answered within set intervals of wait seconds per day. By default the initial interval is 5 seconds, up to a period of 20 seconds, at which point the interval becomes 10 seconds up to 120 seconds. These values (initial interval, initial period, interval, max period) can be adjusted by running a custom report. The report shows the number of calls answered and unanswered per day (with a total of both). Then the percentage of calls answered within each shown interval for that date is displayed.</QXZ>
|
||||||
|
VERM_HOUR-acd_per_hour Answered call distribution per hour <QXZ>This report breaks down the number of answered calls per interval (default is 30 minutes, and can be modified via the custom report form) over the hours of the day for the day or days covered by the report parameters. It will show every interval, including ones with no call activity, with the number of answered calls starting in that interval and the percentage of answered calls out of the total answered calls that were answered during that interval. Then there is a small bar graph representing the average percentage for that interval relative to the other intervals. Then the average, minimum, and maximum call lengths for calls answered during that interval are shown, with another bar graph representing the average call length relative to the average call length in all other intervals. Finally, there is a line graph tracking the answered calls and average call durations for the intervals.</QXZ>
|
||||||
|
VERM_HOUR-answered_cw_per_hour Answered call wait time per hour <QXZ>This report breaks down the number of answered calls per interval (default is 30 minutes, and can be modified via the custom report form) over the hours of the day for the day or days covered by the report parameters. It will show every interval, including ones with no call activity, with the number of answered calls starting in that interval and the percentage of answered calls out of the total answered calls that were answered during that interval. Then there is a small bar graph representing the average percentage for that interval relative to the other intervals. Then the average, minimum, and maximum wait times for calls answered during that interval are shown, with another bar graph representing the average wait time relative to the average wait time in all other intervals. Finally, there is a line graph tracking the answered calls and average wait times for answered calls for the intervals.</QXZ>
|
||||||
|
VERM_HOUR-unanswered_cw_per_hour Unanswered call wait time per hour <QXZ>This report breaks down the number of unanswered calls per interval (default is 30 minutes, and can be modified via the custom report form) over the hours of the day for the day or days covered by the report parameters. It will show every interval, including ones with no call activity, with the number of unanswered calls starting in that interval and the percentage of unanswered calls out of the total unanswered calls that were unanswered during that interval. Then there is a small bar graph representing the average percentage for that interval relative to the other intervals. Then the average, minimum, and maximum wait times for unanswered calls during that interval are shown, with another bar graph representing the average wait time relative to the average wait time in all other intervals. Finally, there is a line graph tracking the unanswered calls and average wait times for unanswered calls for the intervals.</QXZ>
|
||||||
|
VERM_HOUR-sales_per_hour Sales per hour <QXZ>This report gives information on sales per hour (actually, by default it is per 30-minute interval, but this can be modified via the custom report form). For each interval within the 24 hours of a day, the report gives the percentage of human answered calls (determined by the "human answered" parameter on statuses in the admin) that resulted in a sale. It also gives the percentage of customer contact calls for that interval (determined by the "customer contact" parameter on statuses in the admin) that resulted in a sale. Following that is the count of sales for that interval and the percentage of the total sales that started in that interval, as well as a bar graph representing the number of sales relative to other interval's sales in the same range. A call is determined to be a sale if the call status has it's "Sale" attribute set to "Y" in the system. After that is the total of human answers and customer contacts for the interval, the percent of customer contacts from the total 24-hour range that came from that interval, and a bar graph representing the number of customer contacts relative to other interval's customer contacts in the same report range.</QXZ>
|
||||||
|
VERM_HOUR-queue_length_per_hour Queue length per hour <QXZ>This report gives information on the queue positions of calls per hour (actually, by default it is per 30-minute interval, but this can be modified via the custom report form) within the report parameters. Per interval, it will show the average queue position and a bar graph representing the average queue position per interval relative to other dates' queue positions under the same report parameters. It will also show the minimum and maximum queue positions recorded for that date and another bar graph for the maximum queue position for that date relative to other dates. It will also show the coverage percentage (percent of calls with queue position), and the number of steps, which is the average sum of the queue positions per interval divided by 24, for the hours in the day.</QXZ>
|
||||||
|
VERM_HOUR-schedule_adherence Schedule Adherence per hour <QXZ>This report will show per interval (default is 30 minutes, and can be modified via the custom report form) how many distinct agents were logged in for that interval - intervals where there were no agents logged in are still reported on. It will also show a percent which is the number of distinct agents logging activity during that interval against the total number of distinct agents per interval for the report range (i.e. the sum of all percentages show here should add up to 100%), and a bar graph representing the percentage.</QXZ>
|
||||||
|
VERM_HOUR-inclusive_SLA Inclusive SLA per hour (inbound and outbound) <QXZ>This sub-report shows the number of calls answered within set intervals of wait seconds per hour (actually, by default it is per 30-minute interval, but this can be modified via the custom report form). By default the initial wait time interval is 5 seconds, up to a period of 20 seconds, at which point the wait time interval becomes 10 seconds up to 120 seconds. These values (initial interval, initial period, interval, max period) can be adjusted by running a custom report. The report shows the number of calls answered and unanswered per interval (with a total of both). Then the percentage of calls answered within each shown wait time interval for that hour/interval is displayed.</QXZ>
|
||||||
|
VERM_DOW-answered_call_distribution Answered call distribution per day of week <QXZ>This shows the number of answered calls within the selected report parameters broken down by day of the week. Each day displays the number of calls answered, the percentage that were answered that day relative to the entire report date range, and a bar graph representing the number of calls answered that day relative to the other days covered by the report date range. Additionally, each day shows the average/minimum/maximum call lengths for each day, and another simple bar graph representing the average call length for that day relative to the other days' average call lengths.</QXZ>
|
||||||
|
VERM_DOW-answered_call_wait_time Answered call wait time per day of week <QXZ>This shows the number of answered calls within the selected report parameters broken down by day of the week. Each day displays the number of calls answered, the percentage that were answered that day relative to the entire report date range, and a bar graph representing the number of calls answered that day relative to the other days in the report date range. Additionally, each day shows the average/minimum/maximum wait time, and another simple bar graph representing the average wait time for that day relative to the other days' average wait times.</QXZ>
|
||||||
|
VERM_DOW-unanswered_call_wait_time Unanswered call wait time per day of week <QXZ>This shows the number of unanswered calls within the selected report parameters broken down by day of the week. Each day displays the number of unanswered calls, the percentage that went unanswered that day relative to the entire report date range, and a bar graph representing the number of unanswered calls that day relative to the other days in the report date range. Additionally, each day shows the average/minimum/maximum wait time, and another simple bar graph representing the average wait time for that day relative to the other days' average wait times.</QXZ>
|
||||||
|
VERM_DOW-sales_per_DOW Sales per day of week <QXZ>This report gives information on sales per day of week. For each day within the given date range, the report gives the percentage of human answered calls (determined by the "human answered" parameter on statuses in the admin) that resulted in a sale. It also gives the percentage of customer contact calls for that day (determined by the "customer contact" parameter on statuses in the admin) that resulted in a sale. Following that is the count of sales for that day and the percentage of the total sales that were made on that day, as well as a bar graph representing the number of sales relative to other day's sales in the same range. A call is determined to be a sale if the call status has it's "Sale" attribute set to "Y" in the system. After that is the total of human answers and customer contacts for the day, the percent of customer contacts from the total date range that came from that day, and a bar graph representing the number of customer contacts relative to other day's customer contacts in the same range.</QXZ>
|
||||||
|
VERM_DOW-queue_length_per_DOW Queue length per day of week <QXZ>This report gives information on the queue positions of calls within the report parameters per day of week. It will show the average queue position and a bar graph representing the average queue position per day of week relative to other days' queue positions under the same report parameters. It will also show the minimum and maximum queue positions recorded for that day of the week and another bar graph for the maximum queue position for that day relative to other days. It will also show the coverage percentage (percent of calls with queue position), and the number of steps, which is the average sum of the queue positions per hour - 24 hours is used for this calculation, even for a partial day.</QXZ>
|
||||||
|
VERM_DOW-schedule_adherence Schedule Adherence by day of week <QXZ>This report will show per day of week how many distinct agents were logged in for that day - days where there were no agents logged in are skipped. It will also show a percent which is the number of distinct agents that day against the total number of distinct agents per day of week for the report interval (i.e. the sum of all percentages show here should add up to 100%), and a bar graph representing the percentage.</QXZ>
|
||||||
|
VERM_DOW-inclusive_SLA Inclusive SLA by day of week (inbound and outbound) <QXZ>This sub-report shows the number of calls answered within set intervals of wait seconds per day of week. By default the initial interval is 5 seconds, up to a period of 20 seconds, at which point the interval becomes 10 seconds up to 120 seconds. These values (initial interval, initial period, interval, max period) can be adjusted by running a custom report. The report shows the number of calls answered and unanswered per day of week (with a total of both). Then the percentage of calls answered within each shown interval for that date is displayed.</QXZ>
|
||||||
|
VERM_AGENTS-session_detail Agent Session Detail <QXZ>This is a summary report showing how many distinct agents were logged in under the report parameters, the average length of their login sessions, the length of the shortest and longest sessions, and the total amount of login time expressed as hours as a floating decimal number. All statistics for this report come from the inbound call log_agent_log table</QXZ>
|
||||||
|
VERM_AGENTS-pause_detail Agent Pause Detail <QXZ>This report shows session and pause detail per agent, for agent log records matching the report parameters. It will show each agent, how many sessions (i.e. instances where they logged into the system) they accrued during the date range in the report parameters, the average length of their sessions. Then it will show the total number of times they went on pause, the length of the average pause session, the percentage of their session time they spent being paused, and the average number of times they were paused per session. Pauses are counted as the number of records in the agent log table where the length of the pause_sec column is greater than zero. You can click on the name of the agent to get detailed information on the agent's activities.</QXZ>
|
||||||
|
VERM_AGENTS-agent_availability Agent availability (for all the campaigns/ingroups they are member of) <QXZ>This report details the available time of agents matching the report parameters, which is the time they are logged in and not paused. It will show each agent, the amount of time they spent active/available, the amount of time they were paused, and the amount of pause time that is billable and non-billable. Pause time is determined to be billable by taking the pause code from the agent log record and checking if the code is marked as "billable" in the inbound call log admin (if the pause code is campaign-specific, it is checked for that campaign). Then there is a column for the percentage representing how much each agent's available time takes up out of the sum total of available time shown in this report. Then there is a bar chart representing the agent's availability relative to the other agents. You can click on the name of the agent to get detailed information on the agent's activities.</QXZ>
|
||||||
|
VERM_AGENTS-answered_calls Answered calls (for selected campaigns/ingroups) <QXZ>This report shows data regarding answered calls, broken down by agent, for agent log records matching the report parameters. For each agent, the number of calls they answered is counted - counted calls come from records for that agent in the agent log table where the records have lead IDs, indicating a call. It also shows total call time (sum of talk_sec values from the agent log table for records with calls (lead_id is not null)), the average call time, the average amount of time the agent spends waiting (average wait_sec from the agent log table for records involving calls (lead_id is not null)). The final column shows what percentage of the total answered calls were fielded by the agent. You can click on the name of the agent to get detailed information on the agent's activities.</QXZ>
|
||||||
|
VERM_AGENTS-answered_by_user_group Answered calls by user group <QXZ>This report breaks down the number of answered calls by user group. It shows each user group that answered calls in the agent_log table for records matching the report parameters, the number of calls that were fielded by each user group, the total amount of time spent in call per user group (talk_sec from agent log), the average call time for that user group, and the percentage of the total calls that were answered by this user group.</QXZ>
|
||||||
|
VERM_AGENTS-answered_by_location Answered calls by location <QXZ>This report breaks down the number of answered calls by location, which is a parameter on the user account. The report shows all distinct user locations based on the users that show answered calls under the report parameters, followed by the total time spent in call (talk_sec from agent log for records where lead_id is not null), average time spent in call, average wait time leading up to a call (wait_sec from agent log for records where lead_id is not null), and the percentage of the total calls that were answered by this location.</QXZ>
|
||||||
|
VERM_AGENTS-occupancy Agent Occupancy Report <QXZ>This report tells how active/occupied agents were during the login sessions covered by the report parameters. It will show the total time agents were logged in, both in total along with per individual agent. It will also show total time spent in pause, broken down into billable and non-billable time. Whether or not time is billable is determined by the "billable" setting on pause codes under each campaign. Additionally, system statuses like 'BLANK', 'LOGIN', and 'LAGGED' are counted as billable ('null' pause codes are not billable for this report. It's counted as billable in most other reports). It will also show the total time spent in call and from the call/pause/session times, the occupancy percentage will be calculated. This is the total talk time divided by the total session time minus the total pause time.</QXZ>
|
||||||
|
VERM_AGENTS-session_time_by_hour Agent Session Time by Hour <QXZ>For the given report parameters, this report will show each individual agent's total time in session (logged in) per hour of the day, with a total time at the end.</QXZ>
|
||||||
|
VERM_AGENTS-billable_time_by_hour Agent Billable Time by Hour <QXZ>For the given in the report parameters, this report will show each individual agent's total billable time per hour of the day, with a total time at the end. The report arrives at this figure by taking the agent's total session time, then subtracting the time that is considered non-billable. Non-billable time is the pause_sec from the agent logs, where the pause code (sub_status column) is not and system pause code of 'BLANK', 'LOGIN', 'LAGGED', or null NOR is it a billable pause code for the campaign_id for the agent log record.</QXZ>
|
||||||
|
VERM_AGENTS-agents_by_hour Agents by Hour <QXZ>This is a very basic report that shows how many distinct agents were logged in per hour of the day for every date covered by the report parameters.</QXZ>
|
||||||
|
VERM_AGENTS-agent_sessions_view Agent Sessions View <QXZ>This is a comprehensive report of detailed agent information for all agents logged in during the date range covered by the report parameters. The first record is the sum of all statistics, followed by each individual agent's statistics. The report gives the total login time, total talk time, total idle (pause+wait) time, total "idle no wait" (pause) time, and total billable and non-billable pause time. Whether or not time is billable is determined by the "billable" setting on pause codes under each campaign. Additionally, system statuses like 'BLANK', 'LOGIN', and 'LAGGED' are counted as billable ('null' pause codes are not billable for this report. It's counted as billable in most other reports). The report also gives total wait (wait_sec) time. The report counts the total number of sales, customer contacts, and human-answered calls, and the same counts on a per-hour basis against the presence time ("sale", "customer contact", and "human answered" are status attributes that can be set on campaign or system statuses). Then the report shows a count on offered/answered calls - these are the same thing for this report, which is the total calls handled by agents. Then there is the human answered and customer contact conversion rate, which is the number of sales divided by the respective customer contact and human answered counts. Finally, the report gives the average talk time per call.</QXZ>
|
||||||
|
VERM_AGENTS-queue_sessions_view Campaign/Ingroup Sessions View <QXZ>This is a comprehensive report of detailed campaign/ingroup information for all campaigns/ingroups where agents were logged in during the date range covered by the report parameters. The first record is the sum of all statistics, followed by each individual campaign/ingroup statistics. The report gives the total login time, total talk time, total idle (pause+wait) time, and total billable and non-billable pause time. Whether or not time is billable is determined by the "billable" setting on pause codes under each campaign. Additionally, system statuses like 'BLANK', 'LOGIN', and 'LAGGED' are counted as billable ('null' pause codes are not billable for this report. It's counted as billable in most other reports). The report counts the total number of sales, human-answered, and customer-contact calls, and the same counts on a per-hour basis against the presence time ("sale", "customer contact", and "human answered" are status attributes that can be set on campaign or system statuses). Then the report shows a count on offered/answered calls - these are the same thing for this report, which is the total calls handled by agents. Then there is the human answered and customer contact conversion rate, which is the number of sales divided by the respective customer contact and human answered counts. Finally, the report gives the average talk time per call.</QXZ>
|
||||||
|
VERM_AGENTS_DT-detail_of_agent_sessions Detail of agent sessions <QXZ>This report will display every agent session that meets the report parameters (date range/agents/queues/etc), ordered by agent ID and then by start date/time of the session. Each row shows the agent, the time the session started and ended and the duration of said session. It will show what phone extension the agent used while logged in, and if there is a special reason their session terminated it will be displayed. For example, "MGR LOGOUT" means a manager manually logged the agent out, and "EOD LOGOUT" means the agent was shown to be logged in at the very end of a day. Additionally, it will show how many times the agent was paused - this is determined by the number of records in the agent log table for that agent during the given session where the pause_sec value is greater than zero. The total amount of time the agent spent in pause (sum of the non-zero pause_sec values) is shown. Finally, the server the agent was logged into is displayed.</QXZ>
|
||||||
|
VERM_AGENTS_DT-detail_of_agent_pauses Detail of agent pauses <QXZ>This report will show every pause occurrence in the agent log table that meets the report parameters (date range, agents, queues, etc), sorted by start date/time. It will show the agent who paused, pause code (if any) and name of the pause code (if any). 'BLANK' and null pause codes in the agent log are represented by a "-" here. It will show if the pause interval was billable or non-billable (B/NB) and payabale or non-payable (P/NP) as a single code of up to four characters, along with whether the interval is billable. The start/end time of the pause interval and it's duration will also be displayed.</QXZ>
|
||||||
|
VERM_OUTCOMES-outcomes Statuses <QXZ>This report will give summary stats of matching the report parameters. It will show total times broken down into billable/nonbillable/available, and total statuses based on categories of sale, human answered, and customer contact (defined in the admin). Additionally, these status categories will also have a per-hour count based on their quanitites against the "Total billable time".</QXZ>
|
||||||
|
VERM_OUTCOMES-call_results_by_outcomes Call results, by statuses <QXZ>This report shows a breakdown of every status that was encountered under the report parameters, initially sorted by call status. Each record will show the status name and the call type of that status. "Call type" is the most specific type fitting the status. Blank statuses are "none", subsequent ones are "Unknown" if the status is not found in the system, "Known" if the status IS in the system but not a human answer, customer contact, or sale. If the status is human answered, customer contact, and/or sale the call type prioritization is sale >> customer contact >> human answered. It will also show the call count per status, the percent of this count against the total number of calls with statuses, and a simple bar graph representing the number of calls relative to the total number of calls with statuses. Each status row also provides the option to see the details of each call having that status via clicking on the magnifying glass icon at the end of the row.</QXZ>
|
||||||
|
VERM_OUTCOMES-billable_activities Billable activities <QXZ>This report breaks down the individual billable activites that occurred under the report parameters. It shows the number of times each activity occurred, the total time spent in each activity, the average/minimum/maximum amount of time spent in each activity within the report parameters, and the percent of the time that billable activity accrued relative to the other billable activities, and a simple bar graph representing that percentage.</QXZ>
|
||||||
|
VERM_OUTCOMES-nonbillable_activities Nonbillable activities <QXZ>This report breaks down the individual nonbillable activites that occurred under the report parameters. It shows the number of times each activity occurred, the total time spent in each activity, the average/minimum/maximum amount of time spent in each activity within the report parameters, and the percent of the time that nonbillable activity accrued relative to the other nonbillable activities, and a simple bar graph representing that percentage.</QXZ>
|
||||||
|
VERM_OUTCOMES-detailed_agent_report Detailed agent report <QXZ>This report details agent time and statuses. It will show every agent having status-related activity under the report parameters. It displays their total time available (nonpause time), billable pause time, and nonbillable pause time along with the percentage each amount of time is of their total time. Additionally, there are counts of sales/customer contacts/human answered statuses. Each status category is given a per-hour calculation relative to their billable time (this is defined as available time plus billable pause time), and the conversion rates of their human answered and customer contact calls (this is the number of sales divided by each of the two categories).</QXZ>
|
||||||
|
VERM_OUTCOMES-outcomes_per_agent Statuses per agent <QXZ>This report breaks down counts of statuses per agent, ordered by agent and then call type. "Call type" is the most specific type fitting the status. Blank statuses are "none", subsequent ones are "Unknown" if the status is not found in the system, "Known" if the status IS in the system but not a human answer, customer contact, or sale. If the status is human answered, customer contact, and/or sale the call type prioritization is sale >> customer contact >> human answered. A total of each type of status per agent and a bar graph representing the total relative to the other totals is also given.</QXZ>
|
||||||
|
VERM_display_call_details Call detail <QXZ>"Call detail" is the default information displayed in this window when it loads. It provides some basic information on the call (phone number, agent, length of the call, recording link), but also additional detailed information such as time spent waiting and time spent in IVR, the IVR call path, and the number that was dialed to initiate this call (i.e. the inbound DID).</QXZ>
|
||||||
|
VERM_display_call_details-IVR IVR events <QXZ>This is a subset of detailed information for the IVR path of the specific selected call, wherein any IVR events passed during a call are displayed. The time of each event, the amount of time spent at each event, and the actual event is displayed.</QXZ>
|
||||||
|
VERM_display_outcomes_detail Statuses detail <QXZ>This displays every call <B>from the agent log table</b> within the report parameters of a specific status, selected from the statuses detail report. Clicking on the magnifying glass by any call will give even more detailed information about that specific call.</QXZ>
|
||||||
|
VERM_display_agent_details Agent detail <QXZ>This displays a summary of a single agent's time/activity within the report parameters. Beneath that is a detailed breakdown of every session and pause interval within each session logged by the agent. Each pause record shows the time spent on pause, the explanation of the pause activity (i.e. the name of the pause code from the agent log, if available), whether the pause interval is billable or payable, and the start and end time of the pause interval. Time spent in call is NOT detailed here.</QXZ>
|
||||||
|
VERM_custom_report_queue Queue <QXZ>A queue is a collection of campaigns and/or ingroups. These are built in the admin. This dropdown will display any active queue that is allowed to be viewed under the current user's user group.</QXZ>
|
||||||
|
VERM_custom_report_report Report <QXZ>The individual subreports that comprise VERM are displayed here. By default the first subreport displayed is ANSWERED, but selecting a report here will start the user at that specific report instead.</QXZ>
|
||||||
|
VERM_custom_report_time_period Time period <QXZ>This is a date range relative to the current date and time. Selecting an option from this and running the custom report will override the "call start/end date" values.</QXZ>
|
||||||
|
VERM_custom_report_hourly_slot Hourly slot (minutes) <QXZ>This is a parameter used in the "HR" report and is the interval in minutes in which call counts are broken down into.</QXZ>
|
||||||
|
VERM_custom_report_SLA_initial_period SLA initial period <QXZ>This parameter is used in SLA sub-reports in the Un/Answered reports. This refers to an initial time period in seconds over which call counts are broken down into, in intervals given by the "SLA initial interval" parameter.</QXZ>
|
||||||
|
VERM_custom_report_SLA_initial_interval SLA initial interval <QXZ>This parameter is used in SLA sub-reports in the Un/Answered reports. This refers to the interval in seconds in which call counts are broken into within the period given by the "SLA initial period" parameter.</QXZ>
|
||||||
|
VERM_custom_report_SLA_max_period SLA max period <QXZ>This parameter is used in SLA sub-reports in the Un/Answered reports. This refers to the maximum time period in seconds in which call counts are generated, in intervals given by the "SLA interval" parameter, for any intervals/counts beyond the values given in the "SLA initial period" and "SLA initial interval" parameters.</QXZ>
|
||||||
|
VERM_custom_report_SLA_interval SLA interval <QXZ>This parameter is used in SLA sub-reports in the Un/Answered reports. This refers to the time interval in seconds in which call counts are generated, up to the time in seconds given by the "SLA max period" parameter, for any intervals/counts beyond the values given in the "SLA initial period" and "SLA initial interval" parameters.</QXZ>
|
||||||
|
VERM_custom_report_agent Agent <QXZ>This will limit the report results to a particular agent. What agents the report user can select is determined by their account permissions.</QXZ>
|
||||||
|
VERM_custom_report_team Supervisor/Team <QXZ>This will filter reports to only include agents belonging to a particular supervisor/team, which is the value indicated in the "VERM Secondary User Group" setting on the user modification page in the admin.</QXZ>
|
||||||
|
VERM_custom_report_location Location <QXZ>This will limit report results to a particular location, which is set via the admin in the user's "user location" parameter. Locations are limited to the distinct locations found on the agents the report user is allowed to view.</QXZ>
|
||||||
|
VERM_custom_report_agent_group Agent Group <QXZ>This will limit report results to a particular user group. What user groups the report user can select is determined by their account permissions.</QXZ>
|
||||||
|
VERM_custom_report_outcome Status <QXZ>This will limit report results to a particular status/disposition.</QXZ>
|
||||||
|
VERM_custom_report_asterisk_CID Asterisk call-id <QXZ>If the report user can produce the caller code from a call in the outbound call log_extended table, it can be entered here. It will limit the report results considerably, of course.</QXZ>
|
||||||
|
VERM_custom_report_caller Caller <QXZ>This field is for entering a phone number to limit report results to, either as the number to which an outbound call was placed or as the number an inbound call came in from.</QXZ>
|
||||||
|
VERM_custom_report_wait_duration Wait duration <QXZ>These fields can be used to filter report results to phone calls that were answered within a particular number of seconds. If the range does not include zero seconds, no outbound calls will be in the results as outbound calls do not have wait time.</QXZ>
|
||||||
|
VERM_custom_report_call_duration Call duration <QXZ>These fields can be used to filter report results to phone calls that lasted a particular number of seconds within the range given by these fields.</QXZ>
|
||||||
|
VERM_custom_report_disconnection Disconnection cause <QXZ>The report user can use this dropdown menu to filter report results so that only calls that terminated in a particular way (per the inbound or outbound call logs) are considered.</QXZ>
|
||||||
|
VERM_custom_report_enter_position Enter position <QXZ>This will limit the report results to calls that were logged with a queue position within the range entered in these fields. NOTE: All outbound calls are considered to have a position of '1', so if '1' is not in the range entered by the report user then there will be no outbound calls in the report results.</QXZ>
|
||||||
|
VERM_custom_report_attempts Number of attempts <QXZ>The report user can limit report results to leads that were attempted a number of times between the range entered in these fields. This is based on the called_count value in the outbound and inbound log records.</QXZ>
|
||||||
|
VERM_custom_report_DID DID <QXZ>Entering a value in this field will filter report results to be only inbound calls that reached the queue via the DID in this field. This will, of course, mean the report results will be for inbound calls only.</QXZ>
|
||||||
|
VERM_custom_report_IVR_choice IVR choice <QXZ>This filter will limit report results to calls that passed through an IVR and show in the logs a choice containing the string entered in this field.</QXZ>
|
||||||
|
VERM_custom_report_server Server <QXZ>This filter will limit report results to calls that occurred on a particular server per the extended call logs.</QXZ>
|
||||||
|
VERM_custom_report_day_of_week Day of week <QXZ>As the name suggests, selecting an option from this menu will filter the report results to calls that occurred on a particular day (or days) of the week.</QXZ>
|
||||||
|
VERM_custom_report_between Between <QXZ>Entering a time range in this fields will filter the report results to calls that only occurred during the time of day covered by said time range.</QXZ>
|
||||||
|
After Width: | Height: | Size: 127 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 957 B |
|
After Width: | Height: | Size: 696 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 691 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 888 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 965 B |
|
After Width: | Height: | Size: 907 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 717 B |
|
After Width: | Height: | Size: 802 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 567 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 932 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1013 B |
|
After Width: | Height: | Size: 743 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1018 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 951 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 964 B |
|
After Width: | Height: | Size: 920 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 907 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.4 KiB |