diff --git a/UPGRADE b/UPGRADE index 1ab4802e..a8639256 100644 --- a/UPGRADE +++ b/UPGRADE @@ -256,6 +256,12 @@ OTHER CHANGES: 68. Added options to define color scheme and logo for admin web screens +69. Added new options to enable the recent changes to the UK OFCOM Drop Rate + calculations. There is a new System Setting to enable on the system, + and then each affected campaign must also have the new option enabled + for it as well. Affects the predictive algorithm and the Real-time and + Outbound Calling reports. + diff --git a/bin/AST_VDadapt.pl b/bin/AST_VDadapt.pl index 80d072c2..82377559 100644 --- a/bin/AST_VDadapt.pl +++ b/bin/AST_VDadapt.pl @@ -6,7 +6,7 @@ # adjusts the auto_dial_level for vicidial adaptive-predictive campaigns. # gather call stats for campaigns and in-groups # -# Copyright (C) 2015 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2016 Matt Florell LICENSE: AGPLv2 # # CHANGELOG # 60823-1302 - First build from AST_VDhopper.pl @@ -42,6 +42,7 @@ # 141109-1957 - Fixed issue #793 # 141113-1616 - Added concurrency check # 151124-1235 - Added function to cache carrier log stats +# 160515-2016 - Added code for new UK OFCOM drop calculations # # constants @@ -57,6 +58,7 @@ $run_check=1; # concurrency check # $vicidial_closer_log = 'vicidial_closer_log'; $generate_carrier_stats=1; +$SSofcom_uk_drop_calc=0; $i=0; $daily_stats=1; @@ -64,6 +66,7 @@ $drop_count_updater=0; $stat_it=15; $diff_ratio_updater=0; $stat_count=1; +$ofcom_uk_drop_calc_ANY=0; $VCScalls_today[$i]=0; $VCSdrops_today[$i]=0; $VCSdrops_today_pct[$i]=0; @@ -299,6 +302,20 @@ $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthA->finish(); +##### gather relevent system settings +$stmtA = "SELECT cache_carrier_stats_realtime,ofcom_uk_drop_calc from system_settings;"; +$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; +$sthA->execute or die "executing: $stmtA ", $dbhA->errstr; +$sthArows=$sthA->rows; +if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $generate_carrier_stats = $aryA[0]; + $SSofcom_uk_drop_calc = $aryA[1]; + } +$sthA->finish(); + + &get_time_now; ############################################# @@ -420,11 +437,11 @@ while ($master_loop < $CLIloops) if ($CLIcampaign) { - $stmtA = "SELECT campaign_id,lead_order,hopper_level,auto_dial_level,local_call_time,lead_filter_id,use_internal_dnc,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,UNIX_TIMESTAMP(campaign_changedate),campaign_stats_refresh,campaign_allow_inbound,drop_rate_group,UNIX_TIMESTAMP(campaign_calldate),realtime_agent_time_stats,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents from vicidial_campaigns where campaign_id='$CLIcampaign'"; + $stmtA = "SELECT campaign_id,lead_order,hopper_level,auto_dial_level,local_call_time,lead_filter_id,use_internal_dnc,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,UNIX_TIMESTAMP(campaign_changedate),campaign_stats_refresh,campaign_allow_inbound,drop_rate_group,UNIX_TIMESTAMP(campaign_calldate),realtime_agent_time_stats,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents,ofcom_uk_drop_calc from vicidial_campaigns where campaign_id='$CLIcampaign'"; } else { - $stmtA = "SELECT campaign_id,lead_order,hopper_level,auto_dial_level,local_call_time,lead_filter_id,use_internal_dnc,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,UNIX_TIMESTAMP(campaign_changedate),campaign_stats_refresh,campaign_allow_inbound,drop_rate_group,UNIX_TIMESTAMP(campaign_calldate),realtime_agent_time_stats,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents from vicidial_campaigns where ( (active='Y') or (campaign_stats_refresh='Y') )"; + $stmtA = "SELECT campaign_id,lead_order,hopper_level,auto_dial_level,local_call_time,lead_filter_id,use_internal_dnc,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,UNIX_TIMESTAMP(campaign_changedate),campaign_stats_refresh,campaign_allow_inbound,drop_rate_group,UNIX_TIMESTAMP(campaign_calldate),realtime_agent_time_stats,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents,ofcom_uk_drop_calc from vicidial_campaigns where ( (active='Y') or (campaign_stats_refresh='Y') )"; } $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; @@ -460,6 +477,7 @@ while ($master_loop < $CLIloops) $available_only_tally_threshold_agents[$rec_count] = $aryA[21]; $dial_level_threshold[$rec_count] = $aryA[22]; $dial_level_threshold_agents[$rec_count] = $aryA[23]; + $ofcom_uk_drop_calc[$rec_count] = $aryA[24]; $rec_count++; } @@ -624,14 +642,15 @@ while ($master_loop < $CLIloops) if ( (($stat_count =~ /00$|50$/) || ($stat_count==1)) ) { - $stmtA = "SELECT cache_carrier_stats_realtime from system_settings;"; + $stmtA = "SELECT cache_carrier_stats_realtime,ofcom_uk_drop_calc from system_settings;"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; if ($sthArows > 0) { @aryA = $sthA->fetchrow_array; - $generate_carrier_stats = $aryA[0]; + $generate_carrier_stats = $aryA[0]; + $SSofcom_uk_drop_calc = $aryA[1]; } $sthA->finish(); if ($generate_carrier_stats > 0) @@ -897,6 +916,7 @@ sub count_agents_lines sub calculate_drops { + $ofcom_uk_drop_calc_ANY=0; $camp_ANS_STAT_SQL=''; # GET LIST OF HUMAN-ANSWERED STATUSES $stmtA = "SELECT status from vicidial_statuses where human_answered='Y';"; @@ -932,9 +952,47 @@ sub calculate_drops $debug_camp_output .= " CAMPAIGN ANSWERED STATUSES: $campaign_id[$i]|$camp_ANS_STAT_SQL|\n"; if ($DBX) {print " CAMPAIGN ANSWERED STATUSES: $campaign_id[$i]|$camp_ANS_STAT_SQL|\n";} + + $camp_AM_STAT_SQL=''; + # GET LIST OF HUMAN-ANSWERED STATUSES + $stmtA = "SELECT status from vicidial_statuses where answering_machine='Y';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $rec_count=0; + while ($sthArows > $rec_count) + { + @aryA = $sthA->fetchrow_array; + $camp_AM_STAT_SQL .= "'$aryA[0]',"; + $rec_count++; + } + $sthA->finish(); + + $stmtA = "SELECT status from vicidial_campaign_statuses where campaign_id='$campaign_id[$i]' and answering_machine='Y';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $rec_count=0; + while ($sthArows > $rec_count) + { + @aryA = $sthA->fetchrow_array; + $camp_AM_STAT_SQL .= "'$aryA[0]',"; + $rec_count++; + } + $sthA->finish(); + + chop($camp_AM_STAT_SQL); + if (length($camp_AM_STAT_SQL)<2) + {$camp_AM_STAT_SQL="'-NONE-'";} + + $debug_camp_output .= " CAMPAIGN ANSWERING MACHINE STATUSES: $campaign_id[$i]|$camp_AM_STAT_SQL|\n"; + if ($DBX) {print " CAMPAIGN ANSWERING MACHINE STATUSES: $campaign_id[$i]|$camp_AM_STAT_SQL|\n";} + $RESETdrop_count_updater++; $VCScalls_today[$i]=0; $VCSanswers_today[$i]=0; + $VCSagenthandled_today[$i]=0; + $VCSam_today[$i]=0; $VCSdrops_today[$i]=0; $VCSdrops_today_pct[$i]=0; $VCSdrops_answers_today_pct[$i]=0; @@ -1033,6 +1091,30 @@ sub calculate_drops } $sthA->finish(); + # TODAY ANSWERING MACHINES CODED BY AGENTS FOR UK OFCOM CALCULATION + $stmtA = "SELECT count(*) from $vicidial_log where campaign_id='$campaign_id[$i]' and call_date > '$VDL_date' and status IN($camp_AM_STAT_SQL) and user != 'VDAD';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $VCSam_today[$i] = $aryA[0]; + } + $sthA->finish(); + + # TODAY AGENT HANDLED ANSWERED CALLS FOR UK OFCOM CALCULATION + $stmtA = "SELECT count(*) from $vicidial_log where campaign_id='$campaign_id[$i]' and call_date > '$VDL_date' and status IN($camp_ANS_STAT_SQL) and user != 'VDAD';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $VCSagenthandled_today[$i] = $aryA[0]; + } + $sthA->finish(); + # TODAY DROPS $stmtA = "SELECT count(*) from $vicidial_log where campaign_id='$campaign_id[$i]' and call_date > '$VDL_date' and status IN('DROP','XDROP');"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; @@ -1043,16 +1125,57 @@ sub calculate_drops { @aryA = $sthA->fetchrow_array; $VCSdrops_today[$i] = $aryA[0]; + $temp_raw_drop = $VCSdrops_today[$i]; if ($VCSdrops_today[$i] > 0) { + if ( ($SSofcom_uk_drop_calc > 0) && ($ofcom_uk_drop_calc[$i] =~ /Y/) ) + { + $ofcom_uk_drop_calc_ANY++; + + $debug_camp_output .= "UK OFCOM DROP CALCULATION TRIGGERED FOR THIS CAMPAIGN: ($SSofcom_uk_drop_calc|$ofcom_uk_drop_calc[$i]|$ofcom_uk_drop_calc_ANY)\n"; + if ($DBX) {print "UK OFCOM DROP CALCULATION TRIGGERED FOR THIS CAMPAIGN: ($SSofcom_uk_drop_calc|$ofcom_uk_drop_calc[$i]|$ofcom_uk_drop_calc_ANY)\n";} + + # As of December 2015, OFCOM in the UK changed their method for calculating + # the drop(or abandon) percentage for an outbound dialing campaign. The new + # formula is to estimate the number of drops that were answering machines. + # They do this by using the agent-answered percentage of answering machines + # and subtracting that percentage from the number of drops. Then that new + # drop number is divided by the total agent-answered human-answered calls + # PLUS the number of drops. This differs in several ways from the way it had + # been done, as well as the way the drop percentage has been calculated in + # the USA and Canada. This new UK drop calculation method is activated as a + # system setting AND a campaign option. Both must be enabled for the campaign + # to use the new method. You will see code similar to the section below for + # each time period that the drop percentage is calculated. In order for agent- + # statused answering machines to be calculated properly, we have added an + # answering machine status flag that is used to gather those statuses. + + if ($VCSam_today[$i] > 0) + { + $temp_am_pct = ($VCSam_today[$i] / ($VCSagenthandled_today[$i] + $VCSam_today[$i]) ); + $temp_am_drops = ($VCSdrops_today[$i] * $temp_am_pct); + $VCSdrops_today[$i] = ($VCSdrops_today[$i] - $temp_am_drops); + } + $VCSdrops_today[$i] = sprintf("%.3f", $VCSdrops_today[$i]); + $temp_answers_today = ($VCSagenthandled_today[$i] + $VCSdrops_today[$i]); + if ($temp_answers_today < 1) {$temp_answers_today = 1;} + $VCSdrops_answers_today_pct[$i] = ( ($VCSdrops_today[$i] / $temp_answers_today) * 100 ); + $VCSdrops_answers_today_pct[$i] = sprintf("%.2f", $VCSdrops_answers_today_pct[$i]); + } + else + { + if ($VCSanswers_today[$i] < 1) {$VCSanswers_today[$i] = 1;} + $VCSdrops_answers_today_pct[$i] = ( ($VCSdrops_today[$i] / $VCSanswers_today[$i]) * 100 ); + $VCSdrops_answers_today_pct[$i] = sprintf("%.2f", $VCSdrops_answers_today_pct[$i]); + } $VCSdrops_today_pct[$i] = ( ($VCSdrops_today[$i] / $VCScalls_today[$i]) * 100 ); $VCSdrops_today_pct[$i] = sprintf("%.2f", $VCSdrops_today_pct[$i]); - if ($VCSanswers_today[$i] < 1) {$VCSanswers_today[$i] = 1;} - $VCSdrops_answers_today_pct[$i] = ( ($VCSdrops_today[$i] / $VCSanswers_today[$i]) * 100 ); - $VCSdrops_answers_today_pct[$i] = sprintf("%.2f", $VCSdrops_answers_today_pct[$i]); } } $sthA->finish(); + + $debug_camp_output .= " CALLS: $VCScalls_today[$i] ANSWERs: $VCSanswers_today[$i] AGENT-ANS: $VCSagenthandled_today[$i] AGENT-AMs: $VCSam_today[$i] DROPs: $VCSdrops_today[$i]($temp_raw_drop) DROP-TOT PCT: $VCSdrops_today_pct[$i] DROP-ANS PCT: $VCSdrops_answers_today_pct[$i]\n"; + if ($DBX) {print " CALLS: $VCScalls_today[$i] ANSWERs: $VCSanswers_today[$i] AGENT-ANS: $VCSagenthandled_today[$i] AGENT-AMs: $VCSam_today[$i] DROPs: $VCSdrops_today[$i]($temp_raw_drop) DROP-TOT PCT: $VCSdrops_today_pct[$i] DROP-ANS PCT: $VCSdrops_answers_today_pct[$i]\n";} } # LAST HOUR CALL AND DROP STATS @@ -1300,15 +1423,15 @@ sub calculate_drops # If campaign is using a drop rate group, gather its stats if ($drop_rate_group[$i] !~ /DISABLED/) { - $stmtA = "SELECT drops_answers_today_pct from vicidial_drop_rate_groups where group_id='$drop_rate_group[$i]';"; + $stmtA = "SELECT drops_answers_today_pct,calls_today,answers_today,drops_today,answering_machines_today,agenthandled_today from vicidial_drop_rate_groups where group_id='$drop_rate_group[$i]';"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; if ($sthArows > 0) { @aryA = $sthA->fetchrow_array; - $debug_camp_output .= " DROP RATE GROUP USED: $drop_rate_group[$i] $aryA[0]|$VCSdrops_answers_today_pct[$i]\n"; - if ($DBX) {print " DROP RATE GROUP USED: $drop_rate_group[$i] $aryA[0]|$VCSdrops_answers_today_pct[$i]\n";} + $debug_camp_output .= " DROP RATE GROUP USED: $drop_rate_group[$i] $aryA[0]($VCSdrops_answers_today_pct[$i]) calls:$aryA[1]($VCScalls_today[$i]) ans:$aryA[2]($VCSanswers_today[$i]) drops:$aryA[3]($VCSdrops_today[$i]) agnt-am-ans:$aryA[4]($VCSam_today[$i])$aryA[5]($VCSagenthandled_today[$i])\n"; + if ($DBX) {print " DROP RATE GROUP USED: $drop_rate_group[$i] $aryA[0]($VCSdrops_answers_today_pct[$i]) calls:$aryA[1]($VCScalls_today[$i]) ans:$aryA[2]($VCSanswers_today[$i]) drops:$aryA[3]($VCSdrops_today[$i]) agnt-am-ans:$aryA[4]($VCSam_today[$i])$aryA[5]($VCSagenthandled_today[$i])\n";} $VCSdrops_answers_today_pct[$i] = $aryA[0]; } $sthA->finish(); @@ -1347,7 +1470,7 @@ sub calculate_drops $sthA->finish(); } - $stmtA = "UPDATE vicidial_campaign_stats SET calls_today='$VCScalls_today[$i]',answers_today='$VCSanswers_today[$i]',drops_today='$VCSdrops_today[$i]',drops_today_pct='$VCSdrops_today_pct[$i]',drops_answers_today_pct='$VCSdrops_answers_today_pct[$i]',calls_hour='$VCScalls_hour[$i]',answers_hour='$VCSanswers_hour[$i]',drops_hour='$VCSdrops_hour[$i]',drops_hour_pct='$VCSdrops_hour_pct[$i]',calls_halfhour='$VCScalls_halfhour[$i]',answers_halfhour='$VCSanswers_halfhour[$i]',drops_halfhour='$VCSdrops_halfhour[$i]',drops_halfhour_pct='$VCSdrops_halfhour_pct[$i]',calls_fivemin='$VCScalls_five[$i]',answers_fivemin='$VCSanswers_five[$i]',drops_fivemin='$VCSdrops_five[$i]',drops_fivemin_pct='$VCSdrops_five_pct[$i]',calls_onemin='$VCScalls_one[$i]',answers_onemin='$VCSanswers_one[$i]',drops_onemin='$VCSdrops_one[$i]',drops_onemin_pct='$VCSdrops_one_pct[$i]',agent_non_pause_sec='$VCSagent_nonpause_time[$i]',agent_calls_today='$VCSagent_calls_today[$i]',agent_pause_today='$VCSagent_pause_today[$i]',agent_wait_today='$VCSagent_wait_today[$i]',agent_custtalk_today='$VCSagent_custtalk_today[$i]',agent_acw_today='$VCSagent_acw_today[$i]',$VSCupdateSQL where campaign_id='$campaign_id[$i]';"; + $stmtA = "UPDATE vicidial_campaign_stats SET calls_today='$VCScalls_today[$i]',answers_today='$VCSanswers_today[$i]',drops_today='$VCSdrops_today[$i]',drops_today_pct='$VCSdrops_today_pct[$i]',drops_answers_today_pct='$VCSdrops_answers_today_pct[$i]',calls_hour='$VCScalls_hour[$i]',answers_hour='$VCSanswers_hour[$i]',drops_hour='$VCSdrops_hour[$i]',drops_hour_pct='$VCSdrops_hour_pct[$i]',calls_halfhour='$VCScalls_halfhour[$i]',answers_halfhour='$VCSanswers_halfhour[$i]',drops_halfhour='$VCSdrops_halfhour[$i]',drops_halfhour_pct='$VCSdrops_halfhour_pct[$i]',calls_fivemin='$VCScalls_five[$i]',answers_fivemin='$VCSanswers_five[$i]',drops_fivemin='$VCSdrops_five[$i]',drops_fivemin_pct='$VCSdrops_five_pct[$i]',calls_onemin='$VCScalls_one[$i]',answers_onemin='$VCSanswers_one[$i]',drops_onemin='$VCSdrops_one[$i]',drops_onemin_pct='$VCSdrops_one_pct[$i]',agent_non_pause_sec='$VCSagent_nonpause_time[$i]',agent_calls_today='$VCSagent_calls_today[$i]',agent_pause_today='$VCSagent_pause_today[$i]',agent_wait_today='$VCSagent_wait_today[$i]',agent_custtalk_today='$VCSagent_custtalk_today[$i]',agent_acw_today='$VCSagent_acw_today[$i]',answering_machines_today='$VCSam_today[$i]',agenthandled_today='$VCSagenthandled_today[$i]',$VSCupdateSQL where campaign_id='$campaign_id[$i]';"; $affected_rows = $dbhA->do($stmtA); if ($DBX) {print "OUTBOUND $campaign_id[$i]|$affected_rows|$stmtA|\n";} @@ -1411,6 +1534,7 @@ sub drop_rate_group_gather ################################################################################ #### BEGIN gather drop rate group stats ################################################################################ + if ($DB) {print "\n STARTING DROP RATE GROUP SECTION:\n";} # Gather drop rate groups @DRgroup=@MT; @@ -1435,7 +1559,9 @@ sub drop_rate_group_gather $DRdrops_today=0; $DRdrops_today_pct=0; $DRdrops_answers_today_pct=0; - $stmtA = "SELECT count(*),sum(calls_today),sum(answers_today),sum(drops_today) from vicidial_campaign_stats vcs, vicidial_campaigns vc where vcs.campaign_id=vc.campaign_id and vc.drop_rate_group='$DRgroup[$dr]';"; + $DRanswering_machines_today=0; + $DRagenthandled_today=0; + $stmtA = "SELECT count(*),sum(calls_today),sum(answers_today),sum(drops_today),sum(answering_machines_today),sum(agenthandled_today) from vicidial_campaign_stats vcs, vicidial_campaigns vc where vcs.campaign_id=vc.campaign_id and vc.drop_rate_group='$DRgroup[$dr]';"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; @@ -1444,24 +1570,43 @@ sub drop_rate_group_gather @aryA = $sthA->fetchrow_array; if ($aryA[0] > 0) { - $DRcalls_today = $aryA[1]; - $DRanswers_today = $aryA[2]; - $DRdrops_today = $aryA[3]; + $DRcalls_today = $aryA[1]; + $DRanswers_today = $aryA[2]; + $DRdrops_today = $aryA[3]; + $DRanswering_machines_today = $aryA[4]; + $DRagenthandled_today = $aryA[5]; } } $sthA->finish(); if ($DRdrops_today > 0) { + if ($DRanswers_today < 1) {$DRanswers_today = 1;} + + ##### UK OFCOM DROP PCT CALCULATION + if ($DB) {print " UK OFCOM DROP RATE CALCULATION CHECK: ($SSofcom_uk_drop_calc|$ofcom_uk_drop_calc_ANY)\n";} + if ( ($SSofcom_uk_drop_calc > 0) && ($ofcom_uk_drop_calc_ANY > 0) ) + { + # Keeping in mind that the campaign drop numbers are already adjusted to the OFCOM + # number of drops, so we just have to add the drops to answers to generate the new + # drop-group drop-answer percentage + + $temp_answers_today = ($DRagenthandled_today + $DRdrops_today); + if ($temp_answers_today < 1) {$temp_answers_today = 1;} + $DRdrops_answers_today_pct = ( ($DRdrops_today / $temp_answers_today) * 100 ); + $DRdrops_answers_today_pct = sprintf("%.2f", $DRdrops_answers_today_pct); + } + else + { + $DRdrops_answers_today_pct = ( ($DRdrops_today / $DRanswers_today) * 100 ); + $DRdrops_answers_today_pct = sprintf("%.2f", $DRdrops_answers_today_pct); + } $DRdrops_today_pct = ( ($DRdrops_today / $DRcalls_today) * 100 ); $DRdrops_today_pct = sprintf("%.2f", $DRdrops_today_pct); - if ($DRanswers_today < 1) {$DRanswers_today = 1;} - $DRdrops_answers_today_pct = ( ($DRdrops_today / $DRanswers_today) * 100 ); - $DRdrops_answers_today_pct = sprintf("%.2f", $DRdrops_answers_today_pct); } - $stmtA = "UPDATE vicidial_drop_rate_groups SET calls_today='$DRcalls_today',answers_today='$DRanswers_today',drops_today='$DRdrops_today',drops_today_pct='$DRdrops_today_pct',drops_answers_today_pct='$DRdrops_answers_today_pct' where group_id='$DRgroup[$dr]';"; + $stmtA = "UPDATE vicidial_drop_rate_groups SET calls_today='$DRcalls_today',answers_today='$DRanswers_today',drops_today='$DRdrops_today',drops_today_pct='$DRdrops_today_pct',drops_answers_today_pct='$DRdrops_answers_today_pct',answering_machines_today='$DRanswering_machines_today',agenthandled_today='$DRagenthandled_today' where group_id='$DRgroup[$dr]';"; $affected_rows = $dbhA->do($stmtA); - if ($DBX) {print "$DRgroup[$dr]|$affected_rows|$stmtA|\n";} + if ($DB) {print "DROP RATE GROUP UPDATE: $DRgroup[$dr]|$affected_rows|$stmtA|\n";} $stmtA = "UPDATE vicidial_campaign_stats vcs, vicidial_campaigns vc SET vcs.drops_answers_today_pct='$DRdrops_answers_today_pct' where vcs.campaign_id=vc.campaign_id and vc.drop_rate_group='$DRgroup[$dr]';"; $affected_rows = $dbhA->do($stmtA); diff --git a/bin/VICI_CSV_dump_call_log.pl b/bin/VICI_CSV_dump_call_log.pl new file mode 100644 index 00000000..1c671c0b --- /dev/null +++ b/bin/VICI_CSV_dump_call_log.pl @@ -0,0 +1,221 @@ +#!/usr/bin/perl + +# VICI_CSV_dump_call_log.pl + +# DESCRIPTION: +# adjusts the auto_dial_level for vicidial adaptive-predictive campaigns. +# gather call stats for campaigns and in-groups +# +# Copyright (C) 2016 Joe Johnson, Matt Florell LICENSE: AGPLv2 +# +# CHANGELOG +# 60823-1302 - First build +# + +$secX = time(); +$time = $secX; + ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +$year = ($year + 1900); +$mon++; +if ($mon < 10) {$mon = "0$mon";} +if ($mday < 10) {$mday = "0$mday";} +if ($hour < 10) {$hour = "0$hour";} +if ($min < 10) {$min = "0$min";} +if ($sec < 10) {$sec = "0$sec";} +$timestamp = "$year-$mon-$mday $hour:$min:$sec"; +$start_date = "$year-$mon-$mday"; +$filedate="$year$mon$mday"; +$dayofweek=$wday; +$datestamp = "$year/$mon/$mday $hour:$min"; + + +# default path to astguiclient configuration file: +if (length($PATHconf) < 5) + {$PATHconf = '/etc/astguiclient.conf';} + +open(conf, "$PATHconf") || die "can't open $PATHconf: $!\n"; +@conf = ; +close(conf); +$i=0; +foreach(@conf) + { + $line = $conf[$i]; + $line =~ s/ |>|\n|\r|\t|\#.*|;.*//gi; + if ( ($line =~ /^PATHhome/) && ($CLIhome < 1) ) + {$PATHhome = $line; $PATHhome =~ s/.*=//gi;} + if ( ($line =~ /^PATHlogs/) && ($CLIlogs < 1) ) + {$PATHlogs = $line; $PATHlogs =~ s/.*=//gi;} + if ( ($line =~ /^PATHagi/) && ($CLIagi < 1) ) + {$PATHagi = $line; $PATHagi =~ s/.*=//gi;} + if ( ($line =~ /^PATHweb/) && ($CLIweb < 1) ) + {$PATHweb = $line; $PATHweb =~ s/.*=//gi;} + if ( ($line =~ /^PATHsounds/) && ($CLIsounds < 1) ) + {$PATHsounds = $line; $PATHsounds =~ s/.*=//gi;} + if ( ($line =~ /^PATHmonitor/) && ($CLImonitor < 1) ) + {$PATHmonitor = $line; $PATHmonitor =~ s/.*=//gi;} + if ( ($line =~ /^VARserver_ip/) && ($CLIserver_ip < 1) ) + {$VARserver_ip = $line; $VARserver_ip =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_server/) && ($CLIDB_server < 1) ) + {$VARDB_server = $line; $VARDB_server =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_database/) && ($CLIDB_database < 1) ) + {$VARDB_database = $line; $VARDB_database =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_user/) && ($CLIDB_user < 1) ) + {$VARDB_user = $line; $VARDB_user =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_pass/) && ($CLIDB_pass < 1) ) + {$VARDB_pass = $line; $VARDB_pass =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_port/) && ($CLIDB_port < 1) ) + {$VARDB_port = $line; $VARDB_port =~ s/.*=//gi;} + if ( ($line =~ /^VARREPORT_host/) && ($CLIREPORT_host < 1) ) + {$VARREPORT_host = $line; $VARREPORT_host =~ s/.*=//gi;} + if ( ($line =~ /^VARREPORT_user/) && ($CLIREPORT_user < 1) ) + {$VARREPORT_user = $line; $VARREPORT_user =~ s/.*=//gi;} + if ( ($line =~ /^VARREPORT_pass/) && ($CLIREPORT_pass < 1) ) + {$VARREPORT_pass = $line; $VARREPORT_pass =~ s/.*=//gi;} + if ( ($line =~ /^VARREPORT_port/) && ($CLIREPORT_port < 1) ) + {$VARREPORT_port = $line; $VARREPORT_port =~ s/.*=//gi;} + if ( ($line =~ /^VARREPORT_dir/) && ($CLIREPORT_dir < 1) ) + {$VARREPORT_dir = $line; $VARREPORT_dir =~ s/.*=//gi;} + $i++; + } + +# DEFAULT VALUES +$file_type="csv"; +$delimiter=","; +$output_file="Vicidial_CSV_dump"; +$subdir="/"; + +for ($q=0; $q $output_dir/$output_file"); +} else { + die "\nOutput directory $PATHweb$subdir does not exist or is not a directory\n"; +} + +# Customized Variables +$server_ip = $VARserver_ip; # Asterisk server IP + +$start_time = time(); +$servers=0; + +use DBI; + +$dbh = DBI->connect("DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port", "$VARDB_user", "$VARDB_pass") + or die "Couldn't connect to database: " . DBI->errstr; + +# $user_stmt="SELECT distinct '' as full_name, user from ".$agent_log_table." where event_time >= '$start_date 00:00:00' and event_time <= '$start_date 23:59:59' order by user asc"; + +$status_stmt="select distinct status from vicidial_campaign_statuses where customer_contact='Y' UNION select distinct status from vicidial_statuses where customer_contact='Y' order by status"; +if ($DBX) {print "$status_stmt\n";} +$status_rslt=$dbh->prepare($status_stmt); +$status_rslt->execute(); +@status_array=(); +while (@row=$status_rslt->fetchrow_array) { + $status=$row[0]; + if (!grep(/^$status$/, @status_array)) {push(@status_array, "$status");} +} + +$status_str=join("','", @status_array); + +if ($DB || $DBX) {print "Status list: '$status_str'\n";} + +$agent_log_stmt="select event_time, vu.full_name, vu.user, talk_sec, v.phone_number from vicidial_list v, vicidial_agent_log val, vicidial_users vu where event_time >= '$start_date 00:00:00' and event_time <= '$start_date 23:59:59' and val.status in ('".$status_str."') and val.user=vu.user and val.lead_id=v.lead_id order by event_time asc"; +if ($DBX) {print "$agent_log_stmt\n";} +$agent_log_rslt=$dbh->prepare($agent_log_stmt); +$agent_log_rslt->execute(); +while (@row=$agent_log_rslt->fetchrow_array) { + for ($i=0; $i 0) $reports_use_slave_db = $row[3]; $SSenable_languages = $row[4]; $SSlanguage_method = $row[5]; + $SSofcom_uk_drop_calc = $row[6]; } ##### END SETTINGS LOOKUP ##### ########################################### @@ -360,6 +362,7 @@ while ($i < $campaigns_to_print) } $rollover_groups_count=0; +$ofcom_uk_drop_calc=0; $i=0; $group_string='|'; $group_ct = count($group); @@ -374,7 +377,7 @@ while($i < $group_ct) if (preg_match("/YES/i",$include_rollover)) { - $stmt="select drop_inbound_group from vicidial_campaigns where campaign_id='$group[$i]' $LOGallowed_campaignsSQL and drop_inbound_group NOT LIKE \"%NONE%\" and drop_inbound_group is NOT NULL and drop_inbound_group != '';"; + $stmt="SELECT drop_inbound_group from vicidial_campaigns where campaign_id='$group[$i]' $LOGallowed_campaignsSQL and drop_inbound_group NOT LIKE \"%NONE%\" and drop_inbound_group is NOT NULL and drop_inbound_group != '';"; $rslt=mysql_to_mysqli($stmt, $link); if ($DB) {echo "$stmt\n";} $in_groups_to_print = mysqli_num_rows($rslt); @@ -387,6 +390,23 @@ while($i < $group_ct) } } + ### UK OFCOM test + if ($SSofcom_uk_drop_calc > 0) + { + $stmt="SELECT ofcom_uk_drop_calc from vicidial_campaigns where campaign_id='$group[$i]' $LOGallowed_campaignsSQL;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {echo "$stmt\n";} + $ukofcom_to_print = mysqli_num_rows($rslt); + if ($ukofcom_to_print > 0) + { + $row=mysqli_fetch_row($rslt); + $ukofcom_test = $row[0]; + + if ($ukofcom_test == 'Y') + {$ofcom_uk_drop_calc++;} + } + } + $i++; } if (strlen($group_drop_SQL) < 2) @@ -798,14 +818,30 @@ else $OUToutput .= "\n"; - $OUToutput .= "---------- "._QXZ("HUMAN ANSWERS")."\n"; + $OUToutput .= "---------- "._QXZ("HUMAN ANSWERS"); + if ( ($SSofcom_uk_drop_calc > 0) and ($ofcom_uk_drop_calc > 0) ) + {$OUToutput .= "(uk)";} + $OUToutput .= "\n"; - $stmt="select count(*),sum(length_in_sec) from ".$vicidial_log_table." where call_date >= '$query_date_BEGIN' and call_date <= '$query_date_END' and status IN($customer_interactive_statuses) $group_SQLand $list_id_SQLand;"; - $rslt=mysql_to_mysqli($stmt, $link); - if ($DB) {$OUToutput .= "$stmt\n";} - $row=mysqli_fetch_row($rslt); - $CIcallsRAW = $row[0]; - $CIsec = $row[1]; + ### UK OFCOM test + if ( ($SSofcom_uk_drop_calc > 0) and ($ofcom_uk_drop_calc > 0) ) + { + $stmt="select count(*),sum(length_in_sec) from ".$vicidial_log_table." where call_date >= '$query_date_BEGIN' and call_date <= '$query_date_END' and user!='VDAD' and status IN($customer_interactive_statuses) $group_SQLand $list_id_SQLand;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {$OUToutput .= "$stmt\n";} + $row=mysqli_fetch_row($rslt); + $CIcallsRAW = $row[0]; + $CIsec = $row[1]; + } + else + { + $stmt="select count(*),sum(length_in_sec) from ".$vicidial_log_table." where call_date >= '$query_date_BEGIN' and call_date <= '$query_date_END' and status IN($customer_interactive_statuses) $group_SQLand $list_id_SQLand;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {$OUToutput .= "$stmt\n";} + $row=mysqli_fetch_row($rslt); + $CIcallsRAW = $row[0]; + $CIsec = $row[1]; + } if (preg_match("/YES/i",$include_rollover)) { @@ -851,20 +887,24 @@ else $OUToutput .= "\n"; - $OUToutput .= "---------- "._QXZ("DROPS")."\n"; + $OUToutput .= "---------- "._QXZ("DROPS"); + if ( ($SSofcom_uk_drop_calc > 0) and ($ofcom_uk_drop_calc > 0) ) + {$OUToutput .= "(uk)";} + $OUToutput .= "\n"; $stmt="select count(*),sum(length_in_sec) from ".$vicidial_log_table." where call_date >= '$query_date_BEGIN' and call_date <= '$query_date_END' $group_SQLand $list_id_SQLand and status='DROP' and (length_in_sec <= 6000 or length_in_sec is null);"; $rslt=mysql_to_mysqli($stmt, $link); if ($DB) {$OUToutput .= "$stmt\n";} $row=mysqli_fetch_row($rslt); $DROPcalls = sprintf("%10s", $row[0]); + $DROPcallsA = sprintf("%10s", $row[0]); $DROPcallsRAW = $row[0]; + $DROPcallsRAWraw = $row[0]; $DROPseconds = $row[1]; - # GET LIST OF ALL STATUSES and create SQL from human_answered statuses $q=0; - $stmt = "SELECT status,status_name,human_answered,category from vicidial_statuses;"; + $stmt = "SELECT status,status_name,human_answered,category,answering_machine from vicidial_statuses;"; $rslt=mysql_to_mysqli($stmt, $link); if ($DB) {$OUToutput .= "$stmt\n";} $statuses_to_print = mysqli_num_rows($rslt); @@ -876,15 +916,18 @@ else $status_name[$q] = $row[1]; $human_answered[$q] = $row[2]; $category[$q] = $row[3]; + $answering_machine[$q]= $row[4]; $statname_list["$status[$q]"] = "$status_name[$q]"; $statcat_list["$status[$q]"] = "$category[$q]"; if ($human_answered[$q]=='Y') {$camp_ANS_STAT_SQL .= "'$row[0]',";} + if ($answering_machine[$q]=='Y') + {$camp_AM_STAT_SQL .= "'$row[0]',";} $q++; $p++; } - $stmt = "SELECT distinct status,status_name,human_answered,category from vicidial_campaign_statuses $group_SQL;"; + $stmt = "SELECT distinct status,status_name,human_answered,category,answering_machine from vicidial_campaign_statuses $group_SQL;"; $rslt=mysql_to_mysqli($stmt, $link); if ($DB) {$OUToutput .= "$stmt\n";} $statuses_to_print = mysqli_num_rows($rslt); @@ -896,35 +939,78 @@ else $status_name[$q] = $row[1]; $human_answered[$q] = $row[2]; $category[$q] = $row[3]; + $answering_machine[$q]= $row[4]; $statname_list["$status[$q]"] = "$status_name[$q]"; $statcat_list["$status[$q]"] = "$category[$q]"; if ($human_answered[$q]=='Y') {$camp_ANS_STAT_SQL .= "'$row[0]',";} + if ($answering_machine[$q]=='Y') + {$camp_AM_STAT_SQL .= "'$row[0]',";} $q++; $p++; } $camp_ANS_STAT_SQL = preg_replace('/,$/i', '',$camp_ANS_STAT_SQL); + $camp_AM_STAT_SQL = preg_replace('/,$/i', '',$camp_AM_STAT_SQL); - $stmt="select count(*) from ".$vicidial_log_table." where call_date >= '$query_date_BEGIN' and call_date <= '$query_date_END' $group_SQLand $list_id_SQLand and status IN($camp_ANS_STAT_SQL);"; - $rslt=mysql_to_mysqli($stmt, $link); - if ($DB) {$OUToutput .= "$stmt\n";} - $row=mysqli_fetch_row($rslt); - $ANSWERcalls = $row[0]; + ### UK OFCOM test + if ( ($SSofcom_uk_drop_calc > 0) and ($ofcom_uk_drop_calc > 0) ) + { + $stmt="select count(*) from ".$vicidial_log_table." where call_date >= '$query_date_BEGIN' and call_date <= '$query_date_END' and user!='VDAD' $group_SQLand $list_id_SQLand and status IN($camp_ANS_STAT_SQL);"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {$OUToutput .= "$stmt\n";} + $row=mysqli_fetch_row($rslt); + $ANSWERcalls = $row[0]; + + $stmt="select count(*) from ".$vicidial_log_table." where call_date >= '$query_date_BEGIN' and call_date <= '$query_date_END' and user!='VDAD' $group_SQLand $list_id_SQLand and status IN($camp_AM_STAT_SQL);"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {$OUToutput .= "$stmt\n";} + $row=mysqli_fetch_row($rslt); + $agntAMcalls = $row[0]; + + if ($agntAMcalls > 0) + { + $temp_am_pct = ($agntAMcalls / ($ANSWERcalls + $agntAMcalls) ); + $temp_am_drops = ($DROPcallsRAW * $temp_am_pct); + $DROPcallsRAW = ($DROPcallsRAW - $temp_am_drops); + } + $temp_answers_today = ($ANSWERcalls + $DROPcallsRAW); + $DROPcallsA = sprintf("%10s", $DROPcallsRAW); + + $DROPANSWERpercent = (MathZDC($DROPcallsRAW, $temp_answers_today) * 100); + $DROPANSWERpercent = round($DROPANSWERpercent, 2); + + $ukDROPdebug = "($DROPcallsRAWraw - ( ($agntAMcalls / ($ANSWERcalls + $agntAMcalls) ) * $DROPcallsRAWraw)) / ($ANSWERcalls + ($DROPcallsRAWraw - ( ($agntAMcalls / ($ANSWERcalls + $agntAMcalls) ) * $DROPcallsRAWraw)) )"; + } + else + { + $stmt="select count(*) from ".$vicidial_log_table." where call_date >= '$query_date_BEGIN' and call_date <= '$query_date_END' $group_SQLand $list_id_SQLand and status IN($camp_ANS_STAT_SQL);"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {$OUToutput .= "$stmt\n";} + $row=mysqli_fetch_row($rslt); + $ANSWERcalls = $row[0]; + + # Change $DROPANSWERpercent_adjustment to '1' in options.php if you want to include the drop call count in addition to the answer call count when calculating the DROPANSWERpercent, although you really don't need to + $DROPANSWERpercent = (MathZDC($DROPcallsRAW, ($ANSWERcalls+($DROPcallsRAW*$DROPANSWERpercent_adjustment))) * 100); + $DROPANSWERpercent = round($DROPANSWERpercent, 2); + } $DROPpercent = (MathZDC($DROPcallsRAW, $TOTALcalls) * 100); $DROPpercent = round($DROPpercent, 2); - # Change $DROPANSWERpercent_adjustment to '1' in options.php if you want to include the drop call count in addition to the answer call count when calculating the DROPANSWERpercent, although you really don't need to - $DROPANSWERpercent = (MathZDC($DROPcallsRAW, ($ANSWERcalls+($DROPcallsRAW*$DROPANSWERpercent_adjustment))) * 100); - $DROPANSWERpercent = round($DROPANSWERpercent, 2); - $average_hold_seconds = MathZDC($DROPseconds, $DROPcallsRAW); $average_hold_seconds = round($average_hold_seconds, 2); $average_hold_seconds = sprintf("%10s", $average_hold_seconds); $OUToutput .= _QXZ("Total Outbound DROP Calls",44).": $DROPcalls $DROPpercent%\n"; - $OUToutput .= _QXZ("Percent of DROP Calls taken out of Answers",44).": $DROPcalls / ".($ANSWERcalls+($DROPcallsRAW*$DROPANSWERpercent_adjustment))." $DROPANSWERpercent%\n"; + $OUToutput .= _QXZ("Percent of DROP Calls taken out of Answers",44).": $DROPcallsA / "; + if ( ($SSofcom_uk_drop_calc > 0) and ($ofcom_uk_drop_calc > 0) ) {$OUToutput .= "$temp_answers_today";} + else {$OUToutput .= ($ANSWERcalls+($DROPcallsRAW*$DROPANSWERpercent_adjustment));} + $OUToutput .= " $DROPANSWERpercent%"; + if ( ($SSofcom_uk_drop_calc > 0) and ($ofcom_uk_drop_calc > 0) ) {$OUToutput .= " (uk)";} + + if ( ($DB > 0) and ($SSofcom_uk_drop_calc > 0) and ($ofcom_uk_drop_calc > 0) ) {$OUToutput .= " detail: $ukDROPdebug";} + $OUToutput .= "\n"; if (preg_match("/YES/i",$include_rollover)) { @@ -969,9 +1055,9 @@ else $AVG_ANSWERagent_non_pause_sec = sprintf("%10s", $AVG_ANSWERagent_non_pause_sec); if ($skip_productivity_calc) { - $OUToutput .= _QXZ("Productivity Rating",51).": N/A\n"; + $OUToutput .= _QXZ("Productivity Rating",44).": N/A\n"; } else { - $OUToutput .= _QXZ("Productivity Rating",51).": $AVG_ANSWERagent_non_pause_sec\n"; + $OUToutput .= _QXZ("Productivity Rating",44).": $AVG_ANSWERagent_non_pause_sec\n"; } diff --git a/www/vicidial/AST_timeonVDADall.php b/www/vicidial/AST_timeonVDADall.php index 29042f51..a2d22e49 100644 --- a/www/vicidial/AST_timeonVDADall.php +++ b/www/vicidial/AST_timeonVDADall.php @@ -102,10 +102,11 @@ # 160406-1858 - Added WALL options for report_display_type # 160413-2004 - Added WALL_4 option # 160418-2141 - Fixed issue with WALL displays +# 160515-1300 - Added UK OFCOM feature # -$version = '2.12-90'; -$build = '160418-2141'; +$version = '2.12-91'; +$build = '160515-1300'; header ("Content-type: text/html; charset=utf-8"); @@ -192,7 +193,7 @@ $db_source = 'M'; ############################################# ##### 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,allow_chats,cache_carrier_stats_realtime,report_default_format FROM system_settings;"; +$stmt = "SELECT use_non_latin,outbound_autodial_active,slave_db_server,reports_use_slave_db,enable_languages,language_method,agent_whisper_enabled,allow_chats,cache_carrier_stats_realtime,report_default_format,ofcom_uk_drop_calc FROM system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); if ($DB) {echo "$stmt\n";} $qm_conf_ct = mysqli_num_rows($rslt); @@ -209,6 +210,7 @@ if ($qm_conf_ct > 0) $allow_chats = $row[7]; $cache_carrier_stats_realtime = $row[8]; $SSreport_default_format = $row[9]; + $SSofcom_uk_drop_calc = $row[10]; } ##### END SETTINGS LOOKUP ##### ########################################### @@ -1721,9 +1723,9 @@ else else {$non_inboundSQL = "and campaign_id IN($group_SQL,$closer_campaignsSQL)";} $multi_drop++; - $stmt="SELECT avg(auto_dial_level),min(dial_status_a),min(dial_status_b),min(dial_status_c),min(dial_status_d),min(dial_status_e),min(lead_order),min(lead_filter_id),sum(hopper_level),min(dial_method),avg(adaptive_maximum_level),avg(adaptive_dropped_percentage),avg(adaptive_dl_diff_target),avg(adaptive_intensity),min(available_only_ratio_tally),min(adaptive_latest_server_time),min(local_call_time),avg(dial_timeout),min(dial_statuses),max(agent_pause_codes_active),max(list_order_mix),max(auto_hopper_level) from vicidial_campaigns where active='Y' $group_SQLand;"; + $stmt="SELECT avg(auto_dial_level),min(dial_status_a),min(dial_status_b),min(dial_status_c),min(dial_status_d),min(dial_status_e),min(lead_order),min(lead_filter_id),sum(hopper_level),min(dial_method),avg(adaptive_maximum_level),avg(adaptive_dropped_percentage),avg(adaptive_dl_diff_target),avg(adaptive_intensity),min(available_only_ratio_tally),min(adaptive_latest_server_time),min(local_call_time),avg(dial_timeout),min(dial_statuses),max(agent_pause_codes_active),max(list_order_mix),max(auto_hopper_level),max(ofcom_uk_drop_calc) from vicidial_campaigns where active='Y' $group_SQLand;"; - $stmtB="SELECT sum(dialable_leads),sum(calls_today),sum(drops_today),avg(drops_answers_today_pct),avg(differential_onemin),avg(agents_average_onemin),sum(balance_trunk_fill),$answersSQL,max(status_category_1),sum(status_category_count_1),max(status_category_2),sum(status_category_count_2),max(status_category_3),sum(status_category_count_3),max(status_category_4),sum(status_category_count_4),sum(agent_calls_today),sum(agent_wait_today),sum(agent_custtalk_today),sum(agent_acw_today),sum(agent_pause_today) from vicidial_campaign_stats where calls_today > -1 $non_inboundSQL;"; + $stmtB="SELECT sum(dialable_leads),sum(calls_today),sum(drops_today),avg(drops_answers_today_pct),avg(differential_onemin),avg(agents_average_onemin),sum(balance_trunk_fill),$answersSQL,max(status_category_1),sum(status_category_count_1),max(status_category_2),sum(status_category_count_2),max(status_category_3),sum(status_category_count_3),max(status_category_4),sum(status_category_count_4),sum(agent_calls_today),sum(agent_wait_today),sum(agent_custtalk_today),sum(agent_acw_today),sum(agent_pause_today),sum(agenthandled_today) from vicidial_campaign_stats where calls_today > -1 $non_inboundSQL;"; $stmtC="SELECT count(*) from vicidial_campaigns where agent_pause_codes_active!='N' and active='Y' $group_SQLand;"; } @@ -1736,17 +1738,17 @@ else $multi_drop++; if ($DB) {echo "with_inbound|$with_inbound|$campaign_allow_inbound\n";} - $stmt="SELECT auto_dial_level,dial_status_a,dial_status_b,dial_status_c,dial_status_d,dial_status_e,lead_order,lead_filter_id,hopper_level,dial_method,adaptive_maximum_level,adaptive_dropped_percentage,adaptive_dl_diff_target,adaptive_intensity,available_only_ratio_tally,adaptive_latest_server_time,local_call_time,dial_timeout,dial_statuses,agent_pause_codes_active,list_order_mix,auto_hopper_level from vicidial_campaigns where campaign_id IN ($group_SQL,$closer_campaignsSQL);"; + $stmt="SELECT auto_dial_level,dial_status_a,dial_status_b,dial_status_c,dial_status_d,dial_status_e,lead_order,lead_filter_id,hopper_level,dial_method,adaptive_maximum_level,adaptive_dropped_percentage,adaptive_dl_diff_target,adaptive_intensity,available_only_ratio_tally,adaptive_latest_server_time,local_call_time,dial_timeout,dial_statuses,agent_pause_codes_active,list_order_mix,auto_hopper_level,ofcom_uk_drop_calc from vicidial_campaigns where campaign_id IN ($group_SQL,$closer_campaignsSQL);"; - $stmtB="SELECT sum(dialable_leads),sum(calls_today),sum(drops_today),avg(drops_answers_today_pct),avg(differential_onemin),avg(agents_average_onemin),sum(balance_trunk_fill),$answersSQL,max(status_category_1),sum(status_category_count_1),max(status_category_2),sum(status_category_count_2),max(status_category_3),sum(status_category_count_3),max(status_category_4),sum(status_category_count_4),sum(agent_calls_today),sum(agent_wait_today),sum(agent_custtalk_today),sum(agent_acw_today),sum(agent_pause_today) from vicidial_campaign_stats where campaign_id IN ($group_SQL,$closer_campaignsSQL);"; + $stmtB="SELECT sum(dialable_leads),sum(calls_today),sum(drops_today),avg(drops_answers_today_pct),avg(differential_onemin),avg(agents_average_onemin),sum(balance_trunk_fill),$answersSQL,max(status_category_1),sum(status_category_count_1),max(status_category_2),sum(status_category_count_2),max(status_category_3),sum(status_category_count_3),max(status_category_4),sum(status_category_count_4),sum(agent_calls_today),sum(agent_wait_today),sum(agent_custtalk_today),sum(agent_acw_today),sum(agent_pause_today),sum(agenthandled_today) from vicidial_campaign_stats where campaign_id IN ($group_SQL,$closer_campaignsSQL);"; $stmtC="SELECT count(*) from vicidial_campaigns where agent_pause_codes_active!='N' and active='Y' and campaign_id IN ($group_SQL,$closer_campaignsSQL);"; } else { - $stmt="SELECT avg(auto_dial_level),max(dial_status_a),max(dial_status_b),max(dial_status_c),max(dial_status_d),max(dial_status_e),max(lead_order),max(lead_filter_id),max(hopper_level),max(dial_method),max(adaptive_maximum_level),avg(adaptive_dropped_percentage),avg(adaptive_dl_diff_target),avg(adaptive_intensity),max(available_only_ratio_tally),max(adaptive_latest_server_time),max(local_call_time),max(dial_timeout),max(dial_statuses),max(agent_pause_codes_active),max(list_order_mix),max(auto_hopper_level) from vicidial_campaigns where campaign_id IN($group_SQL);"; + $stmt="SELECT avg(auto_dial_level),max(dial_status_a),max(dial_status_b),max(dial_status_c),max(dial_status_d),max(dial_status_e),max(lead_order),max(lead_filter_id),max(hopper_level),max(dial_method),max(adaptive_maximum_level),avg(adaptive_dropped_percentage),avg(adaptive_dl_diff_target),avg(adaptive_intensity),max(available_only_ratio_tally),max(adaptive_latest_server_time),max(local_call_time),max(dial_timeout),max(dial_statuses),max(agent_pause_codes_active),max(list_order_mix),max(auto_hopper_level),max(ofcom_uk_drop_calc) from vicidial_campaigns where campaign_id IN($group_SQL);"; - $stmtB="SELECT sum(dialable_leads),sum(calls_today),sum(drops_today),avg(drops_answers_today_pct),avg(differential_onemin),avg(agents_average_onemin),sum(balance_trunk_fill),$answersSQL,max(status_category_1),sum(status_category_count_1),max(status_category_2),sum(status_category_count_2),max(status_category_3),sum(status_category_count_3),max(status_category_4),sum(status_category_count_4),sum(agent_calls_today),sum(agent_wait_today),sum(agent_custtalk_today),sum(agent_acw_today),sum(agent_pause_today) from vicidial_campaign_stats where campaign_id IN($group_SQL);"; + $stmtB="SELECT sum(dialable_leads),sum(calls_today),sum(drops_today),avg(drops_answers_today_pct),avg(differential_onemin),avg(agents_average_onemin),sum(balance_trunk_fill),$answersSQL,max(status_category_1),sum(status_category_count_1),max(status_category_2),sum(status_category_count_2),max(status_category_3),sum(status_category_count_3),max(status_category_4),sum(status_category_count_4),sum(agent_calls_today),sum(agent_wait_today),sum(agent_custtalk_today),sum(agent_acw_today),sum(agent_pause_today),sum(agenthandled_today) from vicidial_campaign_stats where campaign_id IN($group_SQL);"; $stmtC="SELECT count(*) from vicidial_campaigns where agent_pause_codes_active!='N' and active='Y' and campaign_id IN($group_SQL);"; } @@ -1776,6 +1778,7 @@ else $DIALstatuses = $row[18]; $DIALmix = $row[20]; $AHOPlev = $row[21]; + $UKocDROP = $row[22]; $rslt=mysql_to_mysqli($stmtC, $link); $row=mysqli_fetch_row($rslt); @@ -1796,12 +1799,6 @@ else $agentsONEMIN = $row[5]; $balanceFILL = $row[6]; $answersTODAY = $row[7]; - if ($multi_drop > 0) - { - $drpctTODAY = ( MathZDC($dropsTODAY, $answersTODAY) * 100); - $drpctTODAY = round($drpctTODAY, 2); - $drpctTODAY = sprintf("%01.2f", $drpctTODAY); - } $VSCcat1 = $row[8]; $VSCcat1tally = $row[9]; $VSCcat2 = $row[10]; @@ -1815,6 +1812,23 @@ else $VSCagentcust = $row[18]; $VSCagentacw = $row[19]; $VSCagentpause = $row[20]; + $AGNTansTODAY = $row[21]; + if ($multi_drop > 0) + { + if ( ($SSofcom_uk_drop_calc > 0) and ($UKocDROP == 'Y') ) + { + $temp_AGNTansPLUSdrop = ($AGNTansTODAY + $dropsTODAY); + $drpctTODAY = ( MathZDC($dropsTODAY, $temp_AGNTansPLUSdrop) * 100); + $drpctTODAY = round($drpctTODAY, 2); + $drpctTODAY = sprintf("%01.2f", $drpctTODAY); + } + else + { + $drpctTODAY = ( MathZDC($dropsTODAY, $answersTODAY) * 100); + $drpctTODAY = round($drpctTODAY, 2); + $drpctTODAY = sprintf("%01.2f", $drpctTODAY); + } + } $diffpctONEMIN = ( MathZDC($diffONEMIN, $agentsONEMIN) * 100); $diffpctONEMIN = sprintf("%01.2f", $diffpctONEMIN); @@ -1899,7 +1913,13 @@ else { echo ""._QXZ("LEADS IN HOPPER").":  $VDhop     "; } - echo ""._QXZ("DROPPED PERCENT").":  "; + echo ""._QXZ("DROPPED PERCENT"); + + if ( ($SSofcom_uk_drop_calc > 0) and ($UKocDROP == 'Y') ) + {echo "(uk)";} + echo ":  "; + + if ($drpctTODAY >= $DROPmax) {echo "$drpctTODAY%";} else diff --git a/www/vicidial/admin.php b/www/vicidial/admin.php index 82f8c879..a1bc16af 100644 --- a/www/vicidial/admin.php +++ b/www/vicidial/admin.php @@ -2093,6 +2093,10 @@ if (isset($_GET["admin_screen_colors"])) {$admin_screen_colors=$_GET["admin_sc elseif (isset($_POST["admin_screen_colors"])) {$admin_screen_colors=$_POST["admin_screen_colors"];} if (isset($_GET["web_logo"])) {$web_logo=$_GET["web_logo"];} elseif (isset($_POST["web_logo"])) {$web_logo=$_POST["web_logo"];} +if (isset($_GET["ofcom_uk_drop_calc"])) {$ofcom_uk_drop_calc=$_GET["ofcom_uk_drop_calc"];} + elseif (isset($_POST["ofcom_uk_drop_calc"])) {$ofcom_uk_drop_calc=$_POST["ofcom_uk_drop_calc"];} +if (isset($_GET["answering_machine"])) {$answering_machine=$_GET["answering_machine"];} + elseif (isset($_POST["answering_machine"])) {$answering_machine=$_POST["answering_machine"];} if (isset($script_id)) {$script_id= strtoupper($script_id);} @@ -2107,7 +2111,7 @@ if (strlen($dial_status) > 0) ############################################# ##### START SYSTEM_SETTINGS LOOKUP ##### -$stmt = "SELECT use_non_latin,enable_queuemetrics_logging,enable_vtiger_integration,qc_features_active,outbound_autodial_active,sounds_central_control_active,enable_second_webform,user_territories_active,custom_fields_enabled,admin_web_directory,webphone_url,first_login_trigger,hosted_settings,default_phone_registration_password,default_phone_login_password,default_server_password,test_campaign_calls,active_voicemail_server,voicemail_timezones,default_voicemail_timezone,default_local_gmt,campaign_cid_areacodes_enabled,pllb_grouping_limit,did_ra_extensions_enabled,expanded_list_stats,contacts_enabled,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,call_menu_qualify_enabled,admin_list_counts,allow_voicemail_greeting,svn_revision,allow_emails,level_8_disable_add,pass_key,pass_hash_enabled,disable_auto_dial,country_code_list_stats,frozen_server_call_clear,active_modules,allow_chats,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_did_entry_list_id,enable_third_webform,default_language,user_hide_realtime_enabled,log_recording_access,alt_ivr_logging,admin_row_click,admin_screen_colors FROM system_settings;"; +$stmt = "SELECT use_non_latin,enable_queuemetrics_logging,enable_vtiger_integration,qc_features_active,outbound_autodial_active,sounds_central_control_active,enable_second_webform,user_territories_active,custom_fields_enabled,admin_web_directory,webphone_url,first_login_trigger,hosted_settings,default_phone_registration_password,default_phone_login_password,default_server_password,test_campaign_calls,active_voicemail_server,voicemail_timezones,default_voicemail_timezone,default_local_gmt,campaign_cid_areacodes_enabled,pllb_grouping_limit,did_ra_extensions_enabled,expanded_list_stats,contacts_enabled,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,call_menu_qualify_enabled,admin_list_counts,allow_voicemail_greeting,svn_revision,allow_emails,level_8_disable_add,pass_key,pass_hash_enabled,disable_auto_dial,country_code_list_stats,frozen_server_call_clear,active_modules,allow_chats,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_did_entry_list_id,enable_third_webform,default_language,user_hide_realtime_enabled,log_recording_access,alt_ivr_logging,admin_row_click,admin_screen_colors,ofcom_uk_drop_calc FROM system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); if ($DB) {echo "$stmt\n";} $qm_conf_ct = mysqli_num_rows($rslt); @@ -2170,6 +2174,7 @@ if ($qm_conf_ct > 0) $SSalt_ivr_logging = $row[53]; $SSadmin_row_click = $row[54]; $SSadmin_screen_colors = $row[55]; + $SSofcom_uk_drop_calc = $row[56]; } ##### END SETTINGS LOOKUP ##### ########################################### @@ -2589,9 +2594,11 @@ if ($non_latin < 1) $webphone_mute = preg_replace('/[^NY]/','',$webphone_mute); $webphone_volume = preg_replace('/[^NY]/','',$webphone_volume); $webphone_debug = preg_replace('/[^NY]/','',$webphone_debug); + $answering_machine = preg_replace('/[^NY]/','',$answering_machine); $qc_enabled = preg_replace('/[^0-9NY]/','',$qc_enabled); $active = preg_replace('/[^0-9NY]/','',$active); + $ofcom_uk_drop_calc = preg_replace('/[^0-9NY]/','',$ofcom_uk_drop_calc); ### ALPHA-NUMERIC ONLY ### @@ -3809,12 +3816,13 @@ else # 160506-0644 - Fixed old mysql connector, issue #950 # 160508-1155 - Added screen colors admin section # 160508-1948 - Changed lists view to default to not show leads counts, with link to click to show counts +# 160514-1437 - Added ofcom_uk_drop_calc option # # make sure you have added a user to the vicidial_users MySQL table with at least user_level 9 to access this page the first time -$admin_version = '2.12-555a'; -$build = '160508-1948'; +$admin_version = '2.12-556a'; +$build = '160514-1437'; $STARTtime = date("U"); $SQLdate = date("Y-m-d H:i:s"); @@ -3898,6 +3906,9 @@ if ($qm_conf_ct > 0) $SSnocache_admin = $row[6]; $SSwebroot_writable = $row[7]; $SSemail_enabled = $row[8]; + + # slightly increase limit value, because PHP somehow thinks 2.8 > 2.8 + $SSauto_dial_limit = ($SSauto_dial_limit + 0.001); } ##### END SETTINGS LOOKUP ##### ########################################### @@ -5822,11 +5833,10 @@ if ($ADD==11) { echo ""._QXZ("Allow Closers").": $NWB#campaigns-allow_closers$NWE\n"; echo ""._QXZ("Minimum Hopper Level").": $NWB#campaigns-hopper_level$NWE\n"; - echo ""._QXZ("Auto Dial Level").": \n"; $adl=0; while($adl <= $SSauto_dial_limit) { - echo "\n"; if ($adl < 1) {$adl = ($adl + 1);} else @@ -5876,8 +5886,10 @@ if ($ADD==11) } } } + if ($adl > $SSauto_dial_limit) {$hmm=1;} + else {echo "\n";} } - echo "(0 = off)$NWB#campaigns-auto_dial_level$NWE\n"; + echo "(0 = off)$NWB#campaigns-auto_dial_level$NWE\n"; } echo ""._QXZ("Next Agent Call").": $NWB#campaigns-next_agent_call$NWE\n"; echo ""._QXZ("Local Call Time").": $NWB#campaigns-drop_lockout_time$NWE\n"; + echo ""._QXZ("Drop Lockout Time").": $NWB#campaigns-drop_lockout_time$NWE\n"; + + if ($SSofcom_uk_drop_calc > 0) + { + echo ""._QXZ("UK OFCOM Drop Calculation").": $NWB#settings-ofcom_uk_drop_calc$NWE\n"; + } + else + { + echo "\n"; + } echo ""._QXZ("Call Count Limit").": $NWB#campaigns-call_count_limit$NWE\n"; @@ -20518,11 +20540,10 @@ if ($ADD==31) } echo ""._QXZ("Dial Method").": $NWB#campaigns-dial_method$NWE\n"; - echo ""._QXZ("Auto Dial Level").": \n"; $adl=0; while($adl <= $SSauto_dial_limit) { - echo "\n"; if ($adl < 1) {$adl = ($adl + 1);} else @@ -20572,8 +20593,10 @@ if ($ADD==31) } } } + if ($adl > $SSauto_dial_limit) {$hmm=1;} + else {echo "\n";} } - echo "(0 = off)$NWB#campaigns-auto_dial_level$NWE       "._QXZ("ADAPT OVERRIDE")."\n"; + echo "(0 = off)$NWB#campaigns-auto_dial_level$NWE       "._QXZ("ADAPT OVERRIDE")."\n"; echo ""._QXZ("Auto Dial Level Threshold").": $NWB#campaigns-dial_level_threshold$NWE       "._QXZ("agents").": \n"; @@ -21667,6 +21690,7 @@ if ($ADD==31) echo ""._QXZ("UNWORKABLE")."\n"; echo ""._QXZ("SCHEDULED CALLBACK")."\n"; echo ""._QXZ("COMPLETED")."\n"; + echo ""._QXZ("ANSWERING MACHINE")."\n"; echo ""._QXZ("MIN SEC")."\n"; echo ""._QXZ("MAX SEC")."\n"; echo ""._QXZ("MODIFY/DELETE")."\n"; @@ -21687,7 +21711,7 @@ if ($ADD==31) $o++; } - $stmt="SELECT status,status_name,selectable,human_answered,category,sale,dnc,customer_contact,not_interested,unworkable,scheduled_callback,completed,min_sec,max_sec from vicidial_campaign_statuses where campaign_id='$campaign_id' $LOGallowed_campaignsSQL order by status;"; + $stmt="SELECT status,status_name,selectable,human_answered,category,sale,dnc,customer_contact,not_interested,unworkable,scheduled_callback,completed,min_sec,max_sec,answering_machine from vicidial_campaign_statuses where campaign_id='$campaign_id' $LOGallowed_campaignsSQL order by status;"; $rslt=mysql_to_mysqli($stmt, $link); $statuses_to_print = mysqli_num_rows($rslt); $o=0; @@ -21724,6 +21748,7 @@ if ($ADD==31) echo "\n"; echo "\n"; echo "\n"; + echo "\n"; echo "\n"; echo "\n"; echo "\n"; @@ -21758,6 +21783,7 @@ if ($ADD==31) echo _QXZ("Unworkable").":   \n"; echo _QXZ("Callback").":   \n"; echo _QXZ("Completed").":   \n"; + echo _QXZ("Answering Machine").":   \n"; echo _QXZ("Category").": \n"; echo "$NWB#campaigns-dial_method$NWE\n"; - echo ""._QXZ("Auto Dial Level").": \n"; $adl=0; while($adl <= $SSauto_dial_limit) { - echo "\n"; if ($adl < 1) {$adl = ($adl + 1);} else @@ -22765,8 +22790,10 @@ if ($ADD==34) } } } + if ($adl > $SSauto_dial_limit) {$hmm=1;} + else {echo "\n";} } - echo "(0 = off)$NWB#campaigns-auto_dial_level$NWE\n"; + echo "(0 = off)$NWB#campaigns-auto_dial_level$NWE\n"; echo ""._QXZ("Adapt Intensity Modifier").": \n"; echo "\n"; echo "\n"; + echo "\n"; echo "\n"; echo "\n"; echo "\n"; @@ -32169,6 +32198,7 @@ if ($ADD==393111111111) echo _QXZ("Unworkable").":   \n"; echo _QXZ("Callback").":   \n"; echo _QXZ("Completed").":   \n"; + echo _QXZ("Answering Machine").":   \n"; echo _QXZ("Category").": \n"; echo "$NWB#settings-outbound_autodial_active$NWE\n"; + echo ""._QXZ("UK OFCOM Drop Calculation").": $NWB#settings-ofcom_uk_drop_calc$NWE\n"; + echo ""._QXZ("Disable Auto-Dial").": $disable_auto_dial   $NWB#settings-disable_auto_dial$NWE\n"; echo ""._QXZ("Max FILL Calls per Second").": $NWB#settings-outbound_calls_per_second$NWE\n"; @@ -33088,6 +33121,7 @@ if ($ADD==321111111111111) echo ""._QXZ("UNWORKABLE")."\n"; echo ""._QXZ("SCHEDULED CALLBACK")."\n"; echo ""._QXZ("COMPLETED")."\n"; + echo ""._QXZ("ANSWERING MACHINE")."\n"; echo ""._QXZ("MIN SEC")."\n"; echo ""._QXZ("MAX SEC")."\n"; echo ""._QXZ("MODIFY/DELETE")."\n"; @@ -33108,7 +33142,7 @@ if ($ADD==321111111111111) $o++; } - $stmt="SELECT status,status_name,selectable,human_answered,category,sale,dnc,customer_contact,not_interested,unworkable,scheduled_callback,completed,min_sec,max_sec from vicidial_statuses order by status;"; + $stmt="SELECT status,status_name,selectable,human_answered,category,sale,dnc,customer_contact,not_interested,unworkable,scheduled_callback,completed,min_sec,max_sec,answering_machine from vicidial_statuses order by status;"; $rslt=mysql_to_mysqli($stmt, $link); $statuses_to_print = mysqli_num_rows($rslt); $o=0; @@ -33144,6 +33178,7 @@ if ($ADD==321111111111111) echo "\n"; echo "\n"; echo "\n"; + echo "\n"; echo "\n"; echo "\n"; echo "\n"; @@ -33176,6 +33211,7 @@ if ($ADD==321111111111111) echo _QXZ("Unworkable").":   \n"; echo _QXZ("Callback").":   \n"; echo _QXZ("Completed").":   \n"; + echo _QXZ("Answering Machine").":   \n"; echo _QXZ("Category").": \n"; echo "