Added Latency Gaps logging
Added Demographic Quotas campaign features Added more logging for campaign test calls git-svn-id: svn://192.168.202.10@3723 3d104415-ff17-0410-8863-d5cf3c621b8a
This commit is contained in:
@@ -790,7 +790,12 @@ OTHER CHANGES:
|
|||||||
of calls with no audio data. This is a campaign feature.
|
of calls with no audio data. This is a campaign feature.
|
||||||
|
|
||||||
222. Added agent screen latency logging, viewable in the Real-Time Report and
|
222. Added agent screen latency logging, viewable in the Real-Time Report and
|
||||||
the new Agent Latency Report.
|
the new Agent Latency Report and Latency Gaps Report.
|
||||||
|
|
||||||
|
223. Added Demographic Quotas, allowing for setting of quota goals for leads
|
||||||
|
based upon lead field values for demographic parameters like: gender,
|
||||||
|
age-group, political-party, etc... For more information on this set of
|
||||||
|
features, read the DEMOGRAPHIC_QUOTAS.txt document.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,7 @@
|
|||||||
# 220312-0859 - Added vicidial_dial_cid_log table archiving, same as vicidial_dial_log
|
# 220312-0859 - Added vicidial_dial_cid_log table archiving, same as vicidial_dial_log
|
||||||
# 230418-1341 - Added vicidial_user_dial_log archiving, same as vicidial_dial_log
|
# 230418-1341 - Added vicidial_user_dial_log archiving, same as vicidial_dial_log
|
||||||
# 230421-0057 - Added vicidial_agent_latency_summary_log archiving
|
# 230421-0057 - Added vicidial_agent_latency_summary_log archiving
|
||||||
|
# 230507-0804 - Added vicidial_latency_gaps archiving
|
||||||
#
|
#
|
||||||
|
|
||||||
$CALC_TEST=0;
|
$CALC_TEST=0;
|
||||||
@@ -3237,7 +3238,7 @@ if (!$T)
|
|||||||
if ($wipe_all > 0)
|
if ($wipe_all > 0)
|
||||||
{$stmtA = "DELETE FROM vicidial_agent_latency_summary_log;";}
|
{$stmtA = "DELETE FROM vicidial_agent_latency_summary_log;";}
|
||||||
else
|
else
|
||||||
{$stmtA = "DELETE FROM vicidial_agent_latency_summary_log WHERE db_time < '$del_time';";}
|
{$stmtA = "DELETE FROM vicidial_agent_latency_summary_log WHERE log_date < '$del_time';";}
|
||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
$sthArows = $sthA->rows;
|
$sthArows = $sthA->rows;
|
||||||
@@ -3253,6 +3254,58 @@ if (!$T)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##### vicidial_latency_gaps
|
||||||
|
$stmtA = "SELECT count(*) from vicidial_latency_gaps;";
|
||||||
|
$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;
|
||||||
|
$vicidial_latency_gaps_count = $aryA[0];
|
||||||
|
}
|
||||||
|
$sthA->finish();
|
||||||
|
|
||||||
|
$stmtA = "SELECT count(*) from vicidial_latency_gaps_archive;";
|
||||||
|
$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;
|
||||||
|
$vicidial_latency_gaps_archive_count = $aryA[0];
|
||||||
|
}
|
||||||
|
$sthA->finish();
|
||||||
|
|
||||||
|
if (!$Q) {print "\nProcessing vicidial_latency_gaps table... ($vicidial_latency_gaps_count|$vicidial_latency_gaps_archive_count)\n";}
|
||||||
|
$stmtA = "INSERT IGNORE INTO vicidial_latency_gaps_archive SELECT * from vicidial_latency_gaps;";
|
||||||
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
|
$sthArows = $sthA->rows;
|
||||||
|
if (!$Q) {print "$sthArows rows inserted into vicidial_latency_gaps_archive table \n";}
|
||||||
|
|
||||||
|
$rv = $sthA->err();
|
||||||
|
if (!$rv)
|
||||||
|
{
|
||||||
|
if ($wipe_all > 0)
|
||||||
|
{$stmtA = "DELETE FROM vicidial_latency_gaps;";}
|
||||||
|
else
|
||||||
|
{$stmtA = "DELETE FROM vicidial_latency_gaps WHERE gap_date < '$del_time';";}
|
||||||
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
|
$sthArows = $sthA->rows;
|
||||||
|
if (!$Q) {print "$sthArows rows deleted from vicidial_latency_gaps table \n";}
|
||||||
|
|
||||||
|
$stmtA = "optimize table vicidial_latency_gaps;";
|
||||||
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
|
|
||||||
|
$stmtA = "optimize table vicidial_latency_gaps_archive;";
|
||||||
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
##### vicidial_carrier_log
|
##### vicidial_carrier_log
|
||||||
$stmtA = "SELECT count(*) from vicidial_carrier_log;";
|
$stmtA = "SELECT count(*) from vicidial_carrier_log;";
|
||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
|
|||||||
@@ -163,9 +163,10 @@
|
|||||||
# 230331-2155 - Fix for issue #1458
|
# 230331-2155 - Fix for issue #1458
|
||||||
# 230412-1405 - Added daily rolling of vicidial_agent_notifications table, truncating of vicidial_agent_notifications_queue table
|
# 230412-1405 - Added daily rolling of vicidial_agent_notifications table, truncating of vicidial_agent_notifications_queue table
|
||||||
# 230420-2321 - Added latency live agent detail updates and log rolling nightly
|
# 230420-2321 - Added latency live agent detail updates and log rolling nightly
|
||||||
|
# 230511-0825 - Added log_latency_gaps trigger, demographic_quotas trigger
|
||||||
#
|
#
|
||||||
|
|
||||||
$build = '230420-2321';
|
$build = '230511-0825';
|
||||||
|
|
||||||
$DB=0; # Debug flag
|
$DB=0; # Debug flag
|
||||||
$teodDB=0; # flag to log Timeclock End of Day processes to log file
|
$teodDB=0; # flag to log Timeclock End of Day processes to log file
|
||||||
@@ -460,7 +461,7 @@ $dbhA = DBI->connect("DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port", "$VA
|
|||||||
|
|
||||||
|
|
||||||
##### Get the settings from system_settings #####
|
##### Get the settings from system_settings #####
|
||||||
$stmtA = "SELECT sounds_central_control_active,active_voicemail_server,custom_dialplan_entry,default_codecs,generate_cross_server_exten,voicemail_timezones,default_voicemail_timezone,call_menu_qualify_enabled,allow_voicemail_greeting,reload_timestamp,meetme_enter_login_filename,meetme_enter_leave3way_filename,allow_chats,enable_auto_reports,enable_drop_lists,expired_lists_inactive,sip_event_logging,call_quota_lead_ranking,inbound_answer_config FROM system_settings;";
|
$stmtA = "SELECT sounds_central_control_active,active_voicemail_server,custom_dialplan_entry,default_codecs,generate_cross_server_exten,voicemail_timezones,default_voicemail_timezone,call_menu_qualify_enabled,allow_voicemail_greeting,reload_timestamp,meetme_enter_login_filename,meetme_enter_leave3way_filename,allow_chats,enable_auto_reports,enable_drop_lists,expired_lists_inactive,sip_event_logging,call_quota_lead_ranking,inbound_answer_config,log_latency_gaps,demographic_quotas FROM system_settings;";
|
||||||
# print "$stmtA\n";
|
# print "$stmtA\n";
|
||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
@@ -487,6 +488,8 @@ if ($sthArows > 0)
|
|||||||
$SSsip_event_logging = $aryA[16];
|
$SSsip_event_logging = $aryA[16];
|
||||||
$SScall_quota_lead_ranking = $aryA[17];
|
$SScall_quota_lead_ranking = $aryA[17];
|
||||||
$SSinbound_answer_config = $aryA[18];
|
$SSinbound_answer_config = $aryA[18];
|
||||||
|
$SSlog_latency_gaps = $aryA[19];
|
||||||
|
$SSdemographic_quotas = $aryA[20];
|
||||||
}
|
}
|
||||||
$sthA->finish();
|
$sthA->finish();
|
||||||
if ($DBXXX > 0) {print "SYSTEM SETTINGS: $sounds_central_control_active|$active_voicemail_server|$SScustom_dialplan_entry|$SSdefault_codecs\n";}
|
if ($DBXXX > 0) {print "SYSTEM SETTINGS: $sounds_central_control_active|$active_voicemail_server|$SScustom_dialplan_entry|$SSdefault_codecs\n";}
|
||||||
@@ -5557,6 +5560,16 @@ if ( ($active_voicemail_server =~ /$server_ip/) && ((length($active_voicemail_se
|
|||||||
}
|
}
|
||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# trigger the latency gaps logging process if enabled
|
||||||
|
if ($SSlog_latency_gaps > 0)
|
||||||
|
{
|
||||||
|
$LL_email='';
|
||||||
|
if ($SSlog_latency_gaps < 2)
|
||||||
|
{$LL_email='--email-gaps-notice';}
|
||||||
|
if ($DB) {print "running agent latency gaps logging process...\n";}
|
||||||
|
`/usr/bin/screen -d -m -S Gaps$reset_test $PATHhome/AST_latency_gaps.pl -q --container=AGENT_LATENCY_LOGGING --live $LL_email 2>/dev/null 1>&2`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
################################################################################
|
################################################################################
|
||||||
##### END latency log live agent details updates
|
##### END latency log live agent details updates
|
||||||
@@ -5565,6 +5578,44 @@ if ( ($active_voicemail_server =~ /$server_ip/) && ((length($active_voicemail_se
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
##### START launch Demographic Quotas process, if enabled on any active campaigns
|
||||||
|
################################################################################
|
||||||
|
# only run this on active voicemail server
|
||||||
|
if ( ($active_voicemail_server =~ /$server_ip/) && ((length($active_voicemail_server)) eq (length($server_ip))) && ($SSdemographic_quotas > 0) )
|
||||||
|
{
|
||||||
|
##### look for active campaigns with DQ enabled on them #####
|
||||||
|
$demographic_quotas=0;
|
||||||
|
$stmtA = "SELECT count(*) FROM vicidial_campaigns where active='Y' and demographic_quotas='ENABLED';";
|
||||||
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
|
$sthArows=$sthA->rows;
|
||||||
|
if ($DBX) {print "$sthArows|$stmtA|\n";}
|
||||||
|
if ($sthArows > 0)
|
||||||
|
{
|
||||||
|
@aryA = $sthA->fetchrow_array;
|
||||||
|
$demographic_quotas = $aryA[0];
|
||||||
|
}
|
||||||
|
$sthA->finish();
|
||||||
|
|
||||||
|
if ($demographic_quotas > 0)
|
||||||
|
{
|
||||||
|
if ($DB) {print "Demographic Quotas campaigns enabled on this system, launching process: $demographic_quotas \n";}
|
||||||
|
`/usr/bin/screen -d -m -S DQrun$reset_test $PATHhome/AST_VDdemographic_quotas.pl 2>/dev/null 1>&2`;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($DB) {print "No Demographic Quotas campaigns enabled on this system: $demographic_quotas \n";}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
################################################################################
|
||||||
|
##### START launch Demographic Quotas process, if enabled on any active campaigns
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
##### BEGIN Audio Store sync
|
##### BEGIN Audio Store sync
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -106,10 +106,11 @@
|
|||||||
# 210718-0343 - Fixes for 24-Hour Call Count Limits with standard Auto-Alt-Dialing
|
# 210718-0343 - Fixes for 24-Hour Call Count Limits with standard Auto-Alt-Dialing
|
||||||
# 210719-1519 - Added additional state override methods for call_limit_24hour
|
# 210719-1519 - Added additional state override methods for call_limit_24hour
|
||||||
# 220822-0938 - Change DNC check queries to put phone_number in double-quotes instead of single-quotes
|
# 220822-0938 - Change DNC check queries to put phone_number in double-quotes instead of single-quotes
|
||||||
|
# 230428-2017 - Added demographic_quotas code
|
||||||
#
|
#
|
||||||
|
|
||||||
# constants
|
# constants
|
||||||
$build = '220822-0938';
|
$build = '230428-2017';
|
||||||
$script='AST_VDhopper';
|
$script='AST_VDhopper';
|
||||||
$DB=0; # Debug flag, set to 0 for no debug messages. Can be overriden with CLI --debug flag
|
$DB=0; # Debug flag, set to 0 for no debug messages. Can be overriden with CLI --debug flag
|
||||||
$US='__';
|
$US='__';
|
||||||
@@ -117,6 +118,7 @@ $MT[0]='';
|
|||||||
#$vicidial_hopper='TEST_vicidial_hopper'; # for testing only
|
#$vicidial_hopper='TEST_vicidial_hopper'; # for testing only
|
||||||
$vicidial_hopper='vicidial_hopper';
|
$vicidial_hopper='vicidial_hopper';
|
||||||
$count_only=0;
|
$count_only=0;
|
||||||
|
$run_check=0;
|
||||||
|
|
||||||
# options
|
# options
|
||||||
$insert_auto_CB_to_hopper = 1; # set to 1 to automatically insert ANYONE callbacks into the hopper, default = 1
|
$insert_auto_CB_to_hopper = 1; # set to 1 to automatically insert ANYONE callbacks into the hopper, default = 1
|
||||||
@@ -202,6 +204,7 @@ if (length($ARGV[0])>1)
|
|||||||
print " [--help] = this screen\n";
|
print " [--help] = this screen\n";
|
||||||
print " [--version] = print version of this script, then exit\n";
|
print " [--version] = print version of this script, then exit\n";
|
||||||
print " [--count-only] = only display the number of leads in the hopper, then exit\n";
|
print " [--count-only] = only display the number of leads in the hopper, then exit\n";
|
||||||
|
print " [--run-check] = concurrency check, exit if already running\n";
|
||||||
print " [--debug] = debug\n";
|
print " [--debug] = debug\n";
|
||||||
print " [--debugX] = super debug\n";
|
print " [--debugX] = super debug\n";
|
||||||
print " [--dbgmt] = show GMT offset of records as they are inserted into hopper\n";
|
print " [--dbgmt] = show GMT offset of records as they are inserted into hopper\n";
|
||||||
@@ -281,6 +284,11 @@ if (length($ARGV[0])>1)
|
|||||||
{
|
{
|
||||||
$count_only=1;
|
$count_only=1;
|
||||||
}
|
}
|
||||||
|
if ($args =~ /--run-check/i)
|
||||||
|
{
|
||||||
|
$run_check=1;
|
||||||
|
if ($DB) {print "\n----- CONCURRENCY CHECK -----\n\n";}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -288,6 +296,21 @@ else
|
|||||||
print "no command line options set\n";
|
print "no command line options set\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
### concurrency check (hopper runs should be unique)
|
||||||
|
if ($run_check > 0)
|
||||||
|
{
|
||||||
|
my $grepout = `/bin/ps ax | grep $0 | grep -v grep | grep -v '/bin/sh'`;
|
||||||
|
my $grepnum=0;
|
||||||
|
$grepnum++ while ($grepout =~ m/\n/g);
|
||||||
|
if ($grepnum > 1)
|
||||||
|
{
|
||||||
|
if ($DB) {print "I am not alone! Another $0 is running! Exiting...\n";}
|
||||||
|
$event_string = "I am not alone! Another $0 is running! Exiting...";
|
||||||
|
&event_logger;
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# default path to astguiclient configuration file:
|
# default path to astguiclient configuration file:
|
||||||
$PATHconf = '/etc/astguiclient.conf';
|
$PATHconf = '/etc/astguiclient.conf';
|
||||||
|
|
||||||
@@ -1254,11 +1277,11 @@ $ANY_hopper_vlc_dup_check='N';
|
|||||||
|
|
||||||
if (length($CLIcampaign)>1)
|
if (length($CLIcampaign)>1)
|
||||||
{
|
{
|
||||||
$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,dial_statuses,list_order_mix,use_campaign_dnc,drop_lockout_time,no_hopper_dialing,auto_alt_dial_statuses,dial_timeout,auto_hopper_multi,use_auto_hopper,auto_trim_hopper,lead_order_randomize,lead_order_secondary,call_count_limit,hopper_vlc_dup_check,use_other_campaign_dnc,callback_dnc,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override from vicidial_campaigns where campaign_id IN('$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,dial_statuses,list_order_mix,use_campaign_dnc,drop_lockout_time,no_hopper_dialing,auto_alt_dial_statuses,dial_timeout,auto_hopper_multi,use_auto_hopper,auto_trim_hopper,lead_order_randomize,lead_order_secondary,call_count_limit,hopper_vlc_dup_check,use_other_campaign_dnc,callback_dnc,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,demographic_quotas,demographic_quotas_container from vicidial_campaigns where campaign_id IN('$CLIcampaign');";
|
||||||
}
|
}
|
||||||
else
|
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,dial_statuses,list_order_mix,use_campaign_dnc,drop_lockout_time,no_hopper_dialing,auto_alt_dial_statuses,dial_timeout,auto_hopper_multi,use_auto_hopper,auto_trim_hopper,lead_order_randomize,lead_order_secondary,call_count_limit,hopper_vlc_dup_check,use_other_campaign_dnc,callback_dnc,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override from vicidial_campaigns where active='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,dial_statuses,list_order_mix,use_campaign_dnc,drop_lockout_time,no_hopper_dialing,auto_alt_dial_statuses,dial_timeout,auto_hopper_multi,use_auto_hopper,auto_trim_hopper,lead_order_randomize,lead_order_secondary,call_count_limit,hopper_vlc_dup_check,use_other_campaign_dnc,callback_dnc,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,demographic_quotas,demographic_quotas_container from vicidial_campaigns where active='Y';";
|
||||||
}
|
}
|
||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
@@ -1304,8 +1327,12 @@ while ($sthArows > $rec_count)
|
|||||||
$call_limit_24hour_scope[$rec_count] = $aryA[31];
|
$call_limit_24hour_scope[$rec_count] = $aryA[31];
|
||||||
$call_limit_24hour[$rec_count] = $aryA[32];
|
$call_limit_24hour[$rec_count] = $aryA[32];
|
||||||
$call_limit_24hour_override[$rec_count] = $aryA[33];
|
$call_limit_24hour_override[$rec_count] = $aryA[33];
|
||||||
|
$demographic_quotas[$rec_count] = $aryA[34];
|
||||||
|
$demographic_quotas_container[$rec_count] = $aryA[35];
|
||||||
|
$demographic_quotasSQL[$rec_count] = '';
|
||||||
|
|
||||||
|
if ( ($demographic_quotas[$rec_count] =~ /ENABLED|COMPLETE/) && ( (length($demographic_quotas_container[$rec_count]) > 0) && ($demographic_quotas_container[$rec_count] !~ /DISABLED/) ) )
|
||||||
|
{$demographic_quotasSQL[$rec_count] = "and rank!='-9999'";}
|
||||||
if ($hopper_vlc_dup_check[$rec_count] =~ /Y/)
|
if ($hopper_vlc_dup_check[$rec_count] =~ /Y/)
|
||||||
{$ANY_hopper_vlc_dup_check = 'Y';}
|
{$ANY_hopper_vlc_dup_check = 'Y';}
|
||||||
|
|
||||||
@@ -2903,12 +2930,12 @@ foreach(@campaign_id)
|
|||||||
##### Get count of leads that are dialable #####
|
##### Get count of leads that are dialable #####
|
||||||
if ($list_order_mix[$i] =~ /DISABLED/)
|
if ($list_order_mix[$i] =~ /DISABLED/)
|
||||||
{
|
{
|
||||||
$stmtA = "SELECT count(*) FROM vicidial_list $VLforce_index where $cslrSQL status IN($STATUSsql[$i]) and ($list_id_sql[$i]) and ($all_gmtSQL[$i]) $lead_filter_sql[$i] $DLTsql[$i] $CCLsql[$i];";
|
$stmtA = "SELECT count(*) FROM vicidial_list $VLforce_index where $cslrSQL status IN($STATUSsql[$i]) and ($list_id_sql[$i]) and ($all_gmtSQL[$i]) $lead_filter_sql[$i] $DLTsql[$i] $CCLsql[$i] $demographic_quotasSQL[$i];";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (length($list_mix_dialableSQL)<3) {$list_mix_dialableSQL="called_count < 0";}
|
if (length($list_mix_dialableSQL)<3) {$list_mix_dialableSQL="called_count < 0";}
|
||||||
$stmtA = "SELECT count(*) FROM vicidial_list $VLforce_index where $cslrSQL ($list_mix_dialableSQL) and ($all_gmtSQL[$i]) $lead_filter_sql[$i] $DLTsql[$i] $CCLsql[$i];";
|
$stmtA = "SELECT count(*) FROM vicidial_list $VLforce_index where $cslrSQL ($list_mix_dialableSQL) and ($all_gmtSQL[$i]) $lead_filter_sql[$i] $DLTsql[$i] $CCLsql[$i] $demographic_quotasSQL[$i];";
|
||||||
}
|
}
|
||||||
if ($DBX) {print " |$stmtA|\n";}
|
if ($DBX) {print " |$stmtA|\n";}
|
||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
@@ -2926,7 +2953,7 @@ foreach(@campaign_id)
|
|||||||
|
|
||||||
if ( ($lead_order[$i] =~ / 2nd NEW$| 3rd NEW$| 4th NEW$| 5th NEW$| 6th NEW$/) && ($list_order_mix[$i] =~ /DISABLED/) )
|
if ( ($lead_order[$i] =~ / 2nd NEW$| 3rd NEW$| 4th NEW$| 5th NEW$| 6th NEW$/) && ($list_order_mix[$i] =~ /DISABLED/) )
|
||||||
{
|
{
|
||||||
$stmtA = "SELECT count(*) FROM vicidial_list $VLforce_index where $cslrSQL status IN('NEW') and ($list_id_sql[$i]) and ($all_gmtSQL[$i]) $lead_filter_sql[$i] $DLTsql[$i];";
|
$stmtA = "SELECT count(*) FROM vicidial_list $VLforce_index where $cslrSQL status IN('NEW') and ($list_id_sql[$i]) and ($all_gmtSQL[$i]) $lead_filter_sql[$i] $DLTsql[$i] $demographic_quotasSQL[$i];";
|
||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
$sthArows=$sthA->rows;
|
$sthArows=$sthA->rows;
|
||||||
@@ -3074,7 +3101,7 @@ foreach(@campaign_id)
|
|||||||
if ($hopper_vlc_dup_check[$i] =~ /Y/)
|
if ($hopper_vlc_dup_check[$i] =~ /Y/)
|
||||||
{$vlc_dup_check_SQL = "and vendor_lead_code NOT IN($live_vlc$vlc_lists)";}
|
{$vlc_dup_check_SQL = "and vendor_lead_code NOT IN($live_vlc$vlc_lists)";}
|
||||||
|
|
||||||
$stmtA = "SELECT lead_id,list_id,gmt_offset_now,phone_number,state,status,modify_date,user,vendor_lead_code,phone_code,postal_code FROM vicidial_list $VLforce_index where $recycle_SQL[$i] and ($list_id_sql[$i]) and lead_id NOT IN($lead_id_lists) $vlc_dup_check_SQL and ($all_gmtSQL[$i]) $lead_filter_sql[$i] $CCLsql[$i] $DLTsql[$i] $dnc_blocked_lists_SQL $order_stmt limit $hopper_level[$i];";
|
$stmtA = "SELECT lead_id,list_id,gmt_offset_now,phone_number,state,status,modify_date,user,vendor_lead_code,phone_code,postal_code FROM vicidial_list $VLforce_index where $recycle_SQL[$i] and ($list_id_sql[$i]) and lead_id NOT IN($lead_id_lists) $vlc_dup_check_SQL and ($all_gmtSQL[$i]) $lead_filter_sql[$i] $CCLsql[$i] $DLTsql[$i] $demographic_quotasSQL[$i] $dnc_blocked_lists_SQL $order_stmt limit $hopper_level[$i];";
|
||||||
if ($DBX) {print " |$stmtA|\n";}
|
if ($DBX) {print " |$stmtA|\n";}
|
||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
@@ -3135,7 +3162,7 @@ foreach(@campaign_id)
|
|||||||
if ($hopper_vlc_dup_check[$i] =~ /Y/)
|
if ($hopper_vlc_dup_check[$i] =~ /Y/)
|
||||||
{$vlc_dup_check_SQL = "and vendor_lead_code NOT IN($live_vlc$vlc_lists)";}
|
{$vlc_dup_check_SQL = "and vendor_lead_code NOT IN($live_vlc$vlc_lists)";}
|
||||||
|
|
||||||
$stmtA = "SELECT lead_id,list_id,gmt_offset_now,phone_number,state,status,modify_date,user,vendor_lead_code,phone_code,postal_code FROM vicidial_list $VLforce_index where $cslrSQL status IN('NEW') and ($list_id_sql[$i]) and lead_id NOT IN($lead_id_lists) $vlc_dup_check_SQL and ($all_gmtSQL[$i]) $lead_filter_sql[$i] $CCLsql[$i] $DLTsql[$i] $dnc_blocked_lists_SQL $order_stmt limit $NEW_level;";
|
$stmtA = "SELECT lead_id,list_id,gmt_offset_now,phone_number,state,status,modify_date,user,vendor_lead_code,phone_code,postal_code FROM vicidial_list $VLforce_index where $cslrSQL status IN('NEW') and ($list_id_sql[$i]) and lead_id NOT IN($lead_id_lists) $vlc_dup_check_SQL and ($all_gmtSQL[$i]) $lead_filter_sql[$i] $CCLsql[$i] $DLTsql[$i] $demographic_quotasSQL[$i] $dnc_blocked_lists_SQL $order_stmt limit $NEW_level;";
|
||||||
if ($DBX) {print " |$stmtA|\n";}
|
if ($DBX) {print " |$stmtA|\n";}
|
||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
@@ -3194,7 +3221,7 @@ foreach(@campaign_id)
|
|||||||
|
|
||||||
if ($list_order_mix[$i] =~ /DISABLED/)
|
if ($list_order_mix[$i] =~ /DISABLED/)
|
||||||
{
|
{
|
||||||
$stmtA = "SELECT lead_id,list_id,gmt_offset_now,phone_number,state,status,modify_date,user,vendor_lead_code,phone_code,postal_code FROM vicidial_list $VLforce_index where $cslrSQL status IN($STATUSsql[$i]) and ($list_id_sql[$i]) and lead_id NOT IN($lead_id_lists) $vlc_dup_check_SQL and ($all_gmtSQL[$i]) $lead_filter_sql[$i] $CCLsql[$i] $DLTsql[$i] $dnc_blocked_lists_SQL $order_stmt limit $OTHER_level;";
|
$stmtA = "SELECT lead_id,list_id,gmt_offset_now,phone_number,state,status,modify_date,user,vendor_lead_code,phone_code,postal_code FROM vicidial_list $VLforce_index where $cslrSQL status IN($STATUSsql[$i]) and ($list_id_sql[$i]) and lead_id NOT IN($lead_id_lists) $vlc_dup_check_SQL and ($all_gmtSQL[$i]) $lead_filter_sql[$i] $CCLsql[$i] $DLTsql[$i] $demographic_quotasSQL[$i] $dnc_blocked_lists_SQL $order_stmt limit $OTHER_level;";
|
||||||
if ($DBX) {print " |$stmtA|\n";}
|
if ($DBX) {print " |$stmtA|\n";}
|
||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
@@ -3303,7 +3330,7 @@ foreach(@campaign_id)
|
|||||||
if ($hopper_vlc_dup_check[$i] =~ /Y/)
|
if ($hopper_vlc_dup_check[$i] =~ /Y/)
|
||||||
{$vlc_dup_check_SQL = "and vendor_lead_code NOT IN($live_vlc$vlc_lists)";}
|
{$vlc_dup_check_SQL = "and vendor_lead_code NOT IN($live_vlc$vlc_lists)";}
|
||||||
|
|
||||||
$stmtA = "SELECT lead_id,list_id,gmt_offset_now,phone_number,state,status,modify_date,user,vendor_lead_code,phone_code,postal_code FROM vicidial_list $VLforce_index where $cslrSQL ($list_mix_dialableSQL) and lead_id NOT IN($lead_id_lists) $vlc_dup_check_SQL and ($all_gmtSQL[$i]) $lead_filter_sql[$i] $CCLsql[$i] $DLTsql[$i] $dnc_blocked_lists_SQL $order_stmt limit $LM_step_goal[$x];";
|
$stmtA = "SELECT lead_id,list_id,gmt_offset_now,phone_number,state,status,modify_date,user,vendor_lead_code,phone_code,postal_code FROM vicidial_list $VLforce_index where $cslrSQL ($list_mix_dialableSQL) and lead_id NOT IN($lead_id_lists) $vlc_dup_check_SQL and ($all_gmtSQL[$i]) $lead_filter_sql[$i] $CCLsql[$i] $DLTsql[$i] $demographic_quotasSQL[$i] $dnc_blocked_lists_SQL $order_stmt limit $LM_step_goal[$x];";
|
||||||
if ($DBX) {print " |$stmtA|\n";}
|
if ($DBX) {print " |$stmtA|\n";}
|
||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
@@ -3673,7 +3700,7 @@ if($DB)
|
|||||||
|
|
||||||
if (!$q) {print "DONE. Script execution time in seconds: $secZ\n";}
|
if (!$q) {print "DONE. Script execution time in seconds: $secZ\n";}
|
||||||
}
|
}
|
||||||
exit;
|
exit 0;
|
||||||
|
|
||||||
|
|
||||||
##### SUBROUTINES #####
|
##### SUBROUTINES #####
|
||||||
|
|||||||
@@ -812,7 +812,7 @@ while($one_day_interval > 0)
|
|||||||
}
|
}
|
||||||
$sthA->finish();
|
$sthA->finish();
|
||||||
|
|
||||||
$stmtA = "INSERT INTO vicidial_live_agents (user,server_ip,conf_exten,extension,status,campaign_id,random_id,last_call_time,last_update_time,last_call_finish,closer_campaigns,channel,uniqueid,callerid,user_level,comments,last_state_change,outbound_autodial,ra_user,on_hook_agent,on_hook_ring_time,last_inbound_call_time,last_inbound_call_finish) values('$DBremote_user[$h]','$server_ip','$DBremote_conf_exten[$h]','R/$DBremote_user[$h]','READY','$DBremote_campaign[$h]','$DBremote_random[$h]','$SQLdate','$FDtsSQLdate','$SQLdate','$DBremote_closer[$h]','','','','$DBuser_level[$h]','REMOTE','$SQLdate','$CAMPAIGN_autodial[$h]','$DBuser_start[$h]','$DBon_hook_agent[$h]','$DBon_hook_ring_time[$h]','$SQLdate','$SQLdate');";
|
$stmtA = "INSERT INTO vicidial_live_agents (user,server_ip,conf_exten,extension,status,campaign_id,random_id,last_call_time,last_update_time,last_call_finish,closer_campaigns,channel,uniqueid,callerid,user_level,comments,last_state_change,outbound_autodial,ra_user,on_hook_agent,on_hook_ring_time,last_inbound_call_time,last_inbound_call_finish,lead_id) values('$DBremote_user[$h]','$server_ip','$DBremote_conf_exten[$h]','R/$DBremote_user[$h]','READY','$DBremote_campaign[$h]','$DBremote_random[$h]','$SQLdate','$FDtsSQLdate','$SQLdate','$DBremote_closer[$h]','','','','$DBuser_level[$h]','REMOTE','$SQLdate','$CAMPAIGN_autodial[$h]','$DBuser_start[$h]','$DBon_hook_agent[$h]','$DBon_hook_ring_time[$h]','$SQLdate','$SQLdate','0');";
|
||||||
$affected_rows = $dbhA->do($stmtA);
|
$affected_rows = $dbhA->do($stmtA);
|
||||||
if ($DBX) {print STDERR "$DBremote_user[$h] NEW INSERT\n";}
|
if ($DBX) {print STDERR "$DBremote_user[$h] NEW INSERT\n";}
|
||||||
if ($TESTrun > 0)
|
if ($TESTrun > 0)
|
||||||
@@ -831,7 +831,7 @@ while($one_day_interval > 0)
|
|||||||
if ($number_of_lines > $LSC_count)
|
if ($number_of_lines > $LSC_count)
|
||||||
{
|
{
|
||||||
$SIqueryCID = "T$CIDdate$DBremote_conf_exten[$h]";
|
$SIqueryCID = "T$CIDdate$DBremote_conf_exten[$h]";
|
||||||
$stmtA="INSERT INTO vicidial_manager values('','','$SQLdate','NEW','N','$server_ip','','Originate','$SIqueryCID','Channel: $local_DEF$DBremote_conf_exten[$h]$local_AMP$ext_context','Context: $ext_context','Exten: 999999999999','Priority: 1','Callerid: $SIqueryCID','','','','','');";
|
$stmtA="INSERT INTO vicidial_manager set uniqueid = '', entry_date = '$SQLdate', status = 'NEW', response = 'N', server_ip = '$server_ip', channel = '', action = 'Originate', callerid = '$SIqueryCID', cmd_line_b = 'Channel: $local_DEF$DBremote_conf_exten[$h]$local_AMP$ext_context', cmd_line_c = 'Context: $ext_context', cmd_line_d = 'Exten: 999999999999', cmd_line_e = 'Priority: 1', cmd_line_f = 'Callerid: $SIqueryCID', cmd_line_g = '', cmd_line_h = '', cmd_line_i = '', cmd_line_j = '', cmd_line_k = '';";
|
||||||
$affected_rows = $dbhA->do($stmtA);
|
$affected_rows = $dbhA->do($stmtA);
|
||||||
if ($DBX) {print STDERR " TESTrun CALL PLACED: 999999999999 $DBremote_conf_exten[$h] $DBremote_user[$h] NEW INSERT: |$affected_rows|\n";}
|
if ($DBX) {print STDERR " TESTrun CALL PLACED: 999999999999 $DBremote_conf_exten[$h] $DBremote_user[$h] NEW INSERT: |$affected_rows|\n";}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
AGENT SCREEN LOGGING Started: 2023-04-20 Updated: 2023-04-21
|
AGENT SCREEN LOGGING Started: 2023-04-20 Updated: 2023-05-08
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -10,6 +10,7 @@ Agent Screen Usage Logging Items:
|
|||||||
- Agent IP Addresses Viewable in the User Stats page and the User Logins Report and others
|
- Agent IP Addresses Viewable in the User Stats page and the User Logins Report and others
|
||||||
- Agent Screen Visibility Viewable in the User Stats page
|
- Agent Screen Visibility Viewable in the User Stats page
|
||||||
- Agent Screen Latency Viewable in the Real-Time Report, the Agent Latency Report and the Agent Debug Log Report
|
- Agent Screen Latency Viewable in the Real-Time Report, the Agent Latency Report and the Agent Debug Log Report
|
||||||
|
- Agent Screen Latency Gaps Viewable in the Agent Latency Report and the Latency Gaps Report, email alerts also available
|
||||||
- Agent Screen Debug Viewable in the Agent Debug Log Report
|
- Agent Screen Debug Viewable in the Agent Debug Log Report
|
||||||
|
|
||||||
|
|
||||||
@@ -50,6 +51,13 @@ On the back-end, the 'vicidial_agent_latency_log' database table stores the per-
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AGENT SCREEN LATENCY GAPS:
|
||||||
|
|
||||||
|
This metric is derived from the agent screen latency logging. There is a back-end script "AST_latency_gaps.pl" that is run every minute, on the active voicemail server in a cluster, that will analyze the latency logs for all logged-in agents and log the gaps that happen within those logs in real-time. The above script can also send out email alerts as soon as the gaps are detected and those emails can be segregated by User Group as well. There is also the option to send an End-of-Day email with a list of all of the gaps that have happened for that day. For more informaiton on how to configure the "AST_latency_gaps.pl" script, see the named section below. The latency gaps information can also be viewed in the Latency Gaps Report available in the Admin Utilities page.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AGENT SCREEN DEBUG:
|
AGENT SCREEN DEBUG:
|
||||||
|
|
||||||
This metric is really a collection of all of the available agent screen debug data put together. This metric is not enabled by default, to use it you need to enable the "Agent Screen Debug Logging" option in System Settings. The data that is collected is only stored on your system for 7 days.
|
This metric is really a collection of all of the available agent screen debug data put together. This metric is not enabled by default, to use it you need to enable the "Agent Screen Debug Logging" option in System Settings. The data that is collected is only stored on your system for 7 days.
|
||||||
@@ -62,6 +70,47 @@ The "Agent Debug Log Report" will show all of this data, including the back-end
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CONFIGURING THE "AST_latency_gaps.pl" SCRIPT:
|
||||||
|
|
||||||
|
This script is run every minute on the active voicemail server in your cluster to analyze the latency log gaps for logged-in agents. This script required a Settings Container to run(added by default: 'AGENT_LATENCY_LOGGING'). If you would like to use the End-of-Day email feature, you can set up an additional Settings Container with only those settings in it and then use that as a crontab entry on one of the servers in your cluster.
|
||||||
|
|
||||||
|
As for the options available in the AGENT_LATENCY_LOGGING container:
|
||||||
|
(All settings below are optional except for 'minimum_gap')
|
||||||
|
|
||||||
|
minimum_gap The minimum gap in agent latency log entries before a gap will be logged. We suggest 30 seconds, should be 10 of higher.
|
||||||
|
email_sender The email address that the alert emails will be sent from
|
||||||
|
email_list The list of email addresses that the alert emails will be sent to, if more than one separate by commas
|
||||||
|
email_subject The subject of the alert emails
|
||||||
|
group01_groups Segregated alert emails by User Group, if more than one separate by commas, can add multiple groups, increment number by 1
|
||||||
|
group01_email Email list for the above group of user group alerts, can add multiple groups, increment number by 1
|
||||||
|
day_end_email_list For the End-of-Day process, the list of email addresses that the alert emails will be sent to
|
||||||
|
day_end_email_subject For the End-of-Day process, the subject of the end-of-day emails
|
||||||
|
day_end_minimum_gap For the End-of-Day process, the minimum gap in agent latency log entries that will be sent in the email, must be equal to or greater than minimum_gap
|
||||||
|
day_end_hours For the End-of-Day process, the number of hours into the past to gather latency gaps from
|
||||||
|
day_end_groups For the End-of-Day process, the user groups to gather gaps from, if more than one separate by commas
|
||||||
|
|
||||||
|
|
||||||
|
Here is an example Settings Container for the "AST_latency_gaps.pl" script:
|
||||||
|
|
||||||
|
minimum_gap => 10
|
||||||
|
email_sender => vicidial@gmail.com
|
||||||
|
email_list => info@vicidial.com,support@vicidial.com
|
||||||
|
email_subject => Agent Latency Gap Detected
|
||||||
|
group01_groups => ADMIN,AGENTS
|
||||||
|
group01_email => vicidial@gmail.com
|
||||||
|
group02_groups => SUPPORT
|
||||||
|
group02_email => support@vicidial.com
|
||||||
|
group03_groups => SALES
|
||||||
|
group03_email => info@vicidial.com
|
||||||
|
day_end_email_list => info@vicidial.com
|
||||||
|
day_end_email_subject => Day-End Agent Latency Gaps Report
|
||||||
|
day_end_minimum_gap => 11
|
||||||
|
day_end_hours => 16
|
||||||
|
day_end_groups => ADMIN,AGENTS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,276 @@
|
|||||||
|
DEMOGRAPHIC QUOTAS DOC Started: 2023-04-25 Updated: 2023-05-15
|
||||||
|
|
||||||
|
|
||||||
|
THIS FEATURE WAS DESIGNED FOR SURVEYS AND POLLING BASED ON DEMOGRAPHICS
|
||||||
|
|
||||||
|
*This feature was added to the VICIdial svn/trunk codebase in revision 3723
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The Demographic Quotas features, which allow for a dialing pattern that is based around a set of demographic types and values(like: gender(M,F,U), age-group(18-24,25-34,...), political-party(R,D,I), etc...) with associated quota goals in order of priority. The leads are ranked and dialed in order of priority and as each goal is filled(set to a specific status) the leads are re-ranked until all goals are met and the campaign dialing is deactivated.
|
||||||
|
|
||||||
|
This document is written for call center managers and IT staff that already know how to run a standard campaign on their VICIdial system.
|
||||||
|
|
||||||
|
|
||||||
|
In order to use these Demographic Quotas features in a campaign, here are the required steps you should take, in order:
|
||||||
|
|
||||||
|
1. In System Settings, set the 'Demographic Quotas' option to "1" and submit the form
|
||||||
|
2. Create a new List, load your leads into the list with demographic data in it, see the 'LEADS' section below
|
||||||
|
3. Create a new Settings Container, see the 'SETTINGS CONTAINER' section below
|
||||||
|
4. Create a new Campaign, see the 'CAMPAIGN' section below
|
||||||
|
5. Set the campaign to Active to 'Y', the Demographic Quotas to 'ENABLED' and the Demographic Quotas to 'NOW'
|
||||||
|
6. Log agents into the campaign and start dialing
|
||||||
|
7. Look at the "Demographic Quotas Report" to follow the progress of your campaign, see the 'REPORTS' section below
|
||||||
|
8. When all quota goals are met, the Demographic Quotas setting will change to 'COMPLETE' automatically and all dialing will stop on the campaign within one minute
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
LEADS - demographic data:
|
||||||
|
|
||||||
|
The demographic data used for these features need to be stored in the 'vicidial_list' database table directly, in order to be able to efficiently filter and update leads as active/inactive for dialing.
|
||||||
|
|
||||||
|
The demographic field values need to be strictly defined, that means for example age ranges specifically defined(like '18-24') instead of a specific age('23'). The demographic quotas used will be looking for exact values in these fields, so any extra characters or spaces in a record's values will not find a match.
|
||||||
|
|
||||||
|
As for the field mapping, you can use any of the following default vicidial_list fields for your demographic data:
|
||||||
|
|
||||||
|
SIZE FIELD NOTES
|
||||||
|
20 vendor_lead_code
|
||||||
|
50 source_id
|
||||||
|
4 title
|
||||||
|
30 first_name
|
||||||
|
1 middle_initial
|
||||||
|
30 last_name
|
||||||
|
100 address1
|
||||||
|
100 address2
|
||||||
|
100 address3
|
||||||
|
50 city
|
||||||
|
2 state
|
||||||
|
50 province
|
||||||
|
10 postal_code
|
||||||
|
3 country_code
|
||||||
|
1 gender *only: 'M','F','U'
|
||||||
|
10 date_of_birth *format: 'YYYY-MM-DD'
|
||||||
|
12 alt_phone
|
||||||
|
70 email
|
||||||
|
100 security_phrase
|
||||||
|
20 owner
|
||||||
|
|
||||||
|
Data Field Notes: Some of the above fields are smaller than others, some have data restrictions(like 'gender' and 'date_of_birth'), and some of the fields like 'security_phrase' may be altered by inbound call handling depending on how your system is configured. The 'rank' field is not included in the above list specifically because it is used for ranking the leads by the demographic priorities set for the campaign(details on that further down).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
SETTINGS CONTAINER - demographic fields and value parameters:
|
||||||
|
|
||||||
|
This new "Demographic Quotas" campaign feature uses a "Settings Container" to define the fields to be used for each demographic, the quota count for each field value, and the priority order in which each value should be dialed.
|
||||||
|
|
||||||
|
A sample of a Settings Container using an example set of demographic quotas(container type = DEMOGRAPHIC_QUOTAS), would look something like this:
|
||||||
|
|
||||||
|
|
||||||
|
; define finished lead statuses for this campaign that will meet quota:
|
||||||
|
finished_statuses => SVDONE,COMPLT
|
||||||
|
|
||||||
|
; demo 01 - age range
|
||||||
|
demo01_field => address3
|
||||||
|
; field values(in dial priority order), quota goal of finished leads
|
||||||
|
demo01_value01 => 18-24,47
|
||||||
|
demo01_value02 => 25-34,70
|
||||||
|
demo01_value03 => 35-44,72
|
||||||
|
demo01_value04 => 45-54,85
|
||||||
|
demo01_value05 => 55-64,90
|
||||||
|
demo01_value06 => 65-74,79
|
||||||
|
demo01_value07 => 75,57
|
||||||
|
|
||||||
|
; demo 02 - region
|
||||||
|
demo02_field => province
|
||||||
|
demo02_value01 => Central,100
|
||||||
|
demo02_value02 => Cumberland Plateau,174
|
||||||
|
demo02_value03 => Eastern Panhandle,92
|
||||||
|
demo02_value04 => Northern Panhandle,34
|
||||||
|
demo02_value05 => South West,100
|
||||||
|
|
||||||
|
; demo 03 - political party
|
||||||
|
demo03_field => address3
|
||||||
|
demo03_value01 => Registered GOP,475
|
||||||
|
demo03_value02 => Non-GOP,25
|
||||||
|
|
||||||
|
; demo 04 - gender
|
||||||
|
demo04_field => gender
|
||||||
|
demo04_value01 => M,253
|
||||||
|
demo04_value02 => F,247
|
||||||
|
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- This system allows up to 10 demographics in the above configuration, as well as up to 10 field values for each demographic, which makes this system extremely flexible different types of polling/survey campaigns.
|
||||||
|
|
||||||
|
- Since each lead covers multiple demographics. For example, one lead may be a 26-year-old, GOP, Female from the Central region. If that person completes a survey, that satisfies 4 separate demographic quotas. There is no need to call that person again for another quota goal because they already completed the survey. So, you are never really calling only one demographic at a time.
|
||||||
|
|
||||||
|
- There is another example of a Demographic Quota Settings Container further down in this document. That example can be used to test these features on any VICIdial system with the included "performance_test_leads.txt" leads file.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
CAMPAIGN - Demographic Quota settings:
|
||||||
|
|
||||||
|
When you create your new campaign, make sure you first set the campaign's 'List Order' to "UP RANK".
|
||||||
|
|
||||||
|
The 'Demographic Quotas' setting will enable or disable the Demographic Quotas feature for this campaign. For these features to work, you will first need to select a Settings Container for it in that setting below. Once your leads are loaded and all other campaign settings are defined properly, you need to set this field to "ENABLED" and the Re-Rank setting to "NOW" or "NOW_HOUR" for the lead ranking process to start. Once that is complete, your agents can log in and begin dialing on this campaign. If this field is changed by the system to be "INVALID" then something in your configuration is wrong and needs to be corrected before you try setting this field to ENABLED again. To see debug output to help you identify configuration problems, you can click on the "DQ Debug" link directly to the right of this setting field. After your quota goals have all been filled, this field will change to COMPLETE and all dialing will be halted within one minute. NOTE: This feature is not related to Call Quota Lead Ranking and the two features should not be active on any single campaign at the same time.
|
||||||
|
|
||||||
|
The optional 'Demographic Quotas Force Re-Rank' setting is off by default. Demographic Quotas will only re-rank the leads in the campaign lists either when a quota has been reached or the campaign has run out of leads to dial. But this setting can force the system to re-rank the leads once using NOW, every hour using HOUR or every minute using the MINUTE setting. Keep in mind that depending on your system capacity and the number of leads in the campaign lists, this re-ranking process may lead to temporary system disruption, especially if it is run very frequently. When NOW is used, after the re-ranking process, the value of this setting will go back to NO. Default is NO.
|
||||||
|
|
||||||
|
The optional 'Demographic Quotas List Resets' setting can automatically reset the active lists in this campaign if there are leads within the call time available and there are no more dialable leads in the campaign lists or the hopper. We do not recommend activating this setting in most cases because it can result in customers being called an excessive number of times in a single day. Default is MANUAL. If enabled, it will not auto-reset any lists if any list in the campaign has been reset in the last 5 mintues, and any single list within the last 3 hours. Also, no single list can be auto-reset more than 4 times in a single day, even if the list reset limit setting is higher.
|
||||||
|
|
||||||
|
There must be a 'Dispo Call URL' entry set up for the "agc/DQ_dispo.php" script set and active for this campaign, with the 'dispo=--A--dispo--B--' and 'campaign_id=XXXX' values included the URL(the campaign's ID must be in place of the 'XXXX' in the above example). for an example, here is the Dispo Call URL as defined for a campaign ID of "DQTEST":
|
||||||
|
http://192.168.1.3/agc/DQ_dispo.php?lead_id=--A--lead_id--B--&dispo=--A--dispo--B--&campaign_id=DQTEST&user=--A--user--B--&pass=--A--pass--B--
|
||||||
|
|
||||||
|
Other important notes:
|
||||||
|
- If you use a non-default AST_VDhopper.pl flags in your crontab, they need to be added to the HOPPER_CLI_FLAGS Settings Container
|
||||||
|
- You should disable the "Automatic Hopper Level" campaign setting
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
REPORT - Demographic Quota reporting options:
|
||||||
|
|
||||||
|
A new 'Demographic Quota Goals Report' is also available that will allow you to check on the status of your campaign's quota goals at any time to see what goals have been met and which goals are still being filled. A link to this report is on the Campaign Detail page, next to the "Demographic Quota" setting, it is marked as "DQ Report". This report will show the details of a single campaign's Demographic Quota settings, goals and other basic campaign calling information all on one screen. As quota goals are filled, the goal table rows will change from a green to a purple background color. The numbers in this report are updated once per minute, but the 'count' column can also be updated as agents disposition calls. It is possible for the 'count' column to be higher than it really is if a call is dispositioned at the same time as the back-end process runs, but this will not impact the functions of this feature and the numbers will be corrected within one minute. There are also links near the top of the report to go to the campaign modify page and the debug page to see more information on the last time the Demographic Quotas process ran.
|
||||||
|
|
||||||
|
The 'Campaign Debug' report will also have debug output data from the back-end process that runs the Demographic Quotas features. This output can be useful for many reasons, for example if your configuration is invalid, the reason why will be shown in the Campaign Debug report.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
BACK-END PROCESSES - Demographic Quota process flow:
|
||||||
|
|
||||||
|
The new back-end process and 'Dispo Call URL' script that will read the above quota specifications for the campaign will start with the "demo01" demographic and dial until either the quotas were filled, or all leads that match those quota values for that demo had been called once. Then, the campaign would move on to "demo02" and then to "demo03" and "demo04". After one run through all lists in the campaign, if any quotas had not been met, the lists can be automatically reset(optional campaign setting for this) and a second pass would start with the dialable leads that were left. This system allows up to 10 demographics in the above configuration, as well as up to 10 field values for each demographic, which makes this system extremely flexible different types of polling/survey campaigns.
|
||||||
|
|
||||||
|
For campaigns that have Demographic Quotas enabled on them, the standard back-end hopper filling process will add a filter to exclude leads with a rank of '-9999'. This is both for improved system performance and also so that leads that are for already filled quota values can be excluded from dialing in the campaign.
|
||||||
|
|
||||||
|
As for any perceptible system lag, that depends on the size of your lists and the capacity of your DB server. The resets should not be very frequent, and you should only have the lists active that you are actively dialing on at any time, which will help with the speed of the quota list management. The back-end process will actually log the amount of time it takes to run the ranking queries and the longest query run time will be shown as part of the Campaign Debug "DEMO_QUOTAS" output. To help reduce database load, if the Re-Rank option is set to HOUR or MINUTE, the number of ranked leads will be limited to the number of leads that can be put into the hopper in a few hours/minutes instead of re-ranking all leads every time the re-ranking process is run.
|
||||||
|
|
||||||
|
On the technical side, the 'AST_VDdemographic_quotas.pl' script is responsible for this set of features, and it is triggered automatically on the server in your cluster defined in System Settings as the "Active Voicemail Server". This is also the server that will run the 'AST_VDhopper.pl' script as it is triggered by the Demographic Quotas processes.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-------------- TESTING EXAMPLE USING BUILT-IN PERFORMANCE TEST LIST AND LOOPBACK CALLING -----------
|
||||||
|
|
||||||
|
Another Settings Container example for Demographic Quotas:
|
||||||
|
|
||||||
|
|
||||||
|
; define finished lead statuses for this campaign that will meet quota:
|
||||||
|
finished_statuses => SVYCLM,AFTHRS
|
||||||
|
|
||||||
|
; demo 01 - age range
|
||||||
|
demo01_field => address3
|
||||||
|
; field values(in dial priority order), quota goal of finished leads
|
||||||
|
demo01_value01 => 18-24,2
|
||||||
|
demo01_value02 => 25-34,7
|
||||||
|
demo01_value03 => 35-44,8
|
||||||
|
demo01_value04 => 45-54,8
|
||||||
|
demo01_value05 => 55-64,9
|
||||||
|
demo01_value06 => 65-74,10
|
||||||
|
demo01_value07 => 75,5
|
||||||
|
|
||||||
|
; demo 02 - region
|
||||||
|
demo02_field => province
|
||||||
|
demo02_value01 => North,15
|
||||||
|
demo02_value02 => Central,20
|
||||||
|
demo02_value03 => South,15
|
||||||
|
|
||||||
|
; demo 03 - political party
|
||||||
|
demo03_field => title
|
||||||
|
demo03_value01 => REP,20
|
||||||
|
demo03_value02 => DEM,20
|
||||||
|
demo03_value03 => OTH,10
|
||||||
|
|
||||||
|
; demo 04 - gender
|
||||||
|
demo04_field => gender
|
||||||
|
demo04_value01 => M,22
|
||||||
|
demo04_value02 => F,28
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
To test the above, load the "performance_test_list.txt" sample leads file into list 999884, then perform the following MySQL queries:
|
||||||
|
|
||||||
|
DELETE FROM vicidial_list where list_id=999884 order by RAND() limit 10000;
|
||||||
|
|
||||||
|
UPDATE vicidial_list set gender='U' where list_id=999884;
|
||||||
|
UPDATE vicidial_list set gender='M' where list_id=999884 order by RAND() limit 22000;
|
||||||
|
UPDATE vicidial_list set gender='F' where list_id=999884 and gender!='M' order by RAND() limit 28000;
|
||||||
|
|
||||||
|
UPDATE vicidial_list set title='X' where list_id=999884;
|
||||||
|
UPDATE vicidial_list set title='REP' where list_id=999884 order by RAND() limit 20000;
|
||||||
|
UPDATE vicidial_list set title='DEM' where list_id=999884 and title NOT IN('REP') order by RAND() limit 20000;
|
||||||
|
UPDATE vicidial_list set title='OTH' where list_id=999884 and title NOT IN('REP','DEM') order by RAND() limit 10000;
|
||||||
|
|
||||||
|
UPDATE vicidial_list set province='Y' where list_id=999884;
|
||||||
|
UPDATE vicidial_list set province='North' where list_id=999884 order by RAND() limit 15000;
|
||||||
|
UPDATE vicidial_list set province='Central' where list_id=999884 and province NOT IN('North') order by RAND() limit 20000;
|
||||||
|
UPDATE vicidial_list set province='South' where list_id=999884 and province NOT IN('North','Central') order by RAND() limit 15000;
|
||||||
|
|
||||||
|
UPDATE vicidial_list set address3='0' where list_id=999884;
|
||||||
|
UPDATE vicidial_list set address3='18-24' where list_id=999884 order by RAND() limit 2000;
|
||||||
|
UPDATE vicidial_list set address3='25-34' where list_id=999884 and address3='0' order by RAND() limit 7000;
|
||||||
|
UPDATE vicidial_list set address3='35-44' where list_id=999884 and address3='0' order by RAND() limit 8000;
|
||||||
|
UPDATE vicidial_list set address3='45-54' where list_id=999884 and address3='0' order by RAND() limit 8000;
|
||||||
|
UPDATE vicidial_list set address3='55-64' where list_id=999884 and address3='0' order by RAND() limit 9000;
|
||||||
|
UPDATE vicidial_list set address3='65-74' where list_id=999884 and address3='0' order by RAND() limit 10000;
|
||||||
|
UPDATE vicidial_list set address3='75' where list_id=999884 and address3='0' order by RAND() limit 5000;
|
||||||
|
|
||||||
|
UPDATE vicidial_list set status='SVYCLM' where list_id=999884 order by RAND() limit 50;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
FOR REFERENCE ONLY, DO NOT RUN THESE QUERIES!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
Demographic Quotas SQL changes:
|
||||||
|
|
||||||
|
ALTER TABLE system_settings ADD demographic_quotas ENUM('0','1','2','3','4','5','6','7') default '0';
|
||||||
|
|
||||||
|
ALTER TABLE vicidial_campaigns ADD demographic_quotas ENUM('DISABLED','ENABLED','INVALID','COMPLETE') default 'DISABLED';
|
||||||
|
ALTER TABLE vicidial_campaigns ADD demographic_quotas_container VARCHAR(40) default 'DISABLED';
|
||||||
|
ALTER TABLE vicidial_campaigns ADD demographic_quotas_rerank ENUM('NO','NOW','HOUR','MINUTE','NOW_HOUR') default 'NO';
|
||||||
|
ALTER TABLE vicidial_campaigns ADD demographic_quotas_last_rerank DATETIME default '2000-01-01 00:00:00';
|
||||||
|
ALTER TABLE vicidial_campaigns ADD demographic_quotas_list_resets ENUM('AUTO','MANUAL') default 'MANUAL';
|
||||||
|
|
||||||
|
CREATE TABLE vicidial_demographic_quotas_goals (
|
||||||
|
vdqg_id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
|
||||||
|
campaign_id VARCHAR(8) default '',
|
||||||
|
demographic_quotas_container VARCHAR(40) default '',
|
||||||
|
quota_field VARCHAR(20) default '',
|
||||||
|
quota_field_order TINYINT(3) default '0',
|
||||||
|
quota_value VARCHAR(100) default '',
|
||||||
|
quota_value_order TINYINT(3) default '0',
|
||||||
|
quota_goal MEDIUMINT(7) default '0',
|
||||||
|
quota_count MEDIUMINT(7) default '0',
|
||||||
|
quota_leads_total MEDIUMINT(7) default '0',
|
||||||
|
quota_leads_active MEDIUMINT(7) default '0',
|
||||||
|
quota_status VARCHAR(10) default 'ACTIVE',
|
||||||
|
quota_modify_date DATETIME,
|
||||||
|
last_lead_id INT(9) UNSIGNED default '0',
|
||||||
|
last_list_id BIGINT(14) UNSIGNED default '0',
|
||||||
|
last_call_date DATETIME,
|
||||||
|
last_status VARCHAR(6) default '',
|
||||||
|
index(campaign_id),
|
||||||
|
index(quota_field),
|
||||||
|
index(quota_value),
|
||||||
|
unique index vdqgi (campaign_id,quota_field,quota_field_order,quota_value,quota_value_order)
|
||||||
|
) ENGINE=MyISAM;
|
||||||
|
|
||||||
|
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('HOPPER_CLI_FLAGS', 'Comand-line flags for hopper process', 'PERL_CLI', '---ALL---', '');
|
||||||
@@ -0,0 +1,666 @@
|
|||||||
|
[general]
|
||||||
|
static=yes
|
||||||
|
writeprotect=no
|
||||||
|
|
||||||
|
[globals]
|
||||||
|
CONSOLE=Console/dsp ; Console interface for demo
|
||||||
|
TRUNK=DAHDI/r1 ; Trunk interface
|
||||||
|
TRUNKX=DAHDI/r2 ; 2nd trunk interface
|
||||||
|
TRUNKIAX=IAX2/ASTtest1:test@10.10.10.16:4569 ; IAX trunk interface
|
||||||
|
TRUNKIAX1=IAX2/ASTtest1:test@10.10.10.16:4569 ; IAX trunk interface
|
||||||
|
TRUNKBINFONE=IAX2/1112223333:PASSWORD@iax.binfone.com ; IAX trunk interface
|
||||||
|
SIPtrunk=SIP/1234:PASSWORD@sip.provider.net ; SIP trunk
|
||||||
|
|
||||||
|
#include extensions-vicidial.conf
|
||||||
|
|
||||||
|
[trunkinbound]
|
||||||
|
; DID call routing process
|
||||||
|
; exten => _XXXXXXXXXX,1,AGI(agi-DID_route.agi) ; use this one instead of the one below if you are having delay issues, and match to number of received digits
|
||||||
|
exten => _X.,1,AGI(agi-DID_route.agi)
|
||||||
|
exten => _X.,n,Hangup()
|
||||||
|
; If you have DIDs that arrive with a plus sign at the beginning then uncomment
|
||||||
|
;exten => _+X.,1,AGI(agi-DID_route.agi)
|
||||||
|
;exten => _+X.,n,Hangup()
|
||||||
|
; If you have DIDs that arrive with a plus and 1 at the beginning that you want to filter out, then uncomment
|
||||||
|
;exten => _+1X.,1,Goto(trunkinbound,${EXTEN:2},1)
|
||||||
|
|
||||||
|
; FastAGI for VICIDIAL/astGUIclient call logging
|
||||||
|
exten => h,1,AGI(agi://127.0.0.1:4577/call_log--HVcauses--PRI-----NODEBUG-----${HANGUPCAUSE}-----${DIALSTATUS}-----${DIALEDTIME}-----${ANSWEREDTIME}-----${HANGUPCAUSE(${HANGUPCAUSE_KEYS()},tech)}))
|
||||||
|
|
||||||
|
[loopback-no-log]
|
||||||
|
; This context is to accept calls that have already been logged in another context in Vicidial
|
||||||
|
; and has been sent through one of the loopbacks. This is why this context is missing the h extension.
|
||||||
|
; Do not put any extensions in this context unless you specifically understand what this means.
|
||||||
|
|
||||||
|
;exten => _91NXXNXXXXXX,1,Dial(${TRUNKX}/${EXTEN:1},,To)
|
||||||
|
;exten => _91NXXNXXXXXX,n,Hangup()
|
||||||
|
|
||||||
|
; special Canadian PRI callerIDname settings FOR USE IN LOOPBACK CONTEXT ONLY
|
||||||
|
;exten => _91NXXNXXXXXX,1,Set(CALLERID(name)="ACME Widgets")
|
||||||
|
;exten => _91NXXNXXXXXX,n,AGI(agi-CANADA_PRI_CIDname.agi)
|
||||||
|
;exten => _91NXXNXXXXXX,n,Dial(${TRUNKX}/${EXTEN:1},,To)
|
||||||
|
;exten => _91NXXNXXXXXX,n,Hangup()
|
||||||
|
|
||||||
|
exten => _999XX11112,1,Wait(2)
|
||||||
|
exten => _999XX11112,n,Answer()
|
||||||
|
exten => _999XX11112,n,Playback(ss-noservice)
|
||||||
|
exten => _999XX11112,n,Playback(vm-goodbye)
|
||||||
|
exten => _999XX11112,n,Hangup()
|
||||||
|
|
||||||
|
[default]
|
||||||
|
include => vicidial-auto
|
||||||
|
|
||||||
|
; Local agent alert extensions
|
||||||
|
exten => _8600XXX*.,1,AGI(agi-VDADfixCXFER.agi)
|
||||||
|
exten => _8600XXX*.,n,Hangup()
|
||||||
|
exten => _78600XXX*.,1,AGI(agi-VDADfixCXFER.agi)
|
||||||
|
exten => _78600XXX*.,n,Hangup()
|
||||||
|
|
||||||
|
; Local blind monitoring
|
||||||
|
exten => _08600XXX,1,Dial(${TRUNKblind}/6${EXTEN:1},55,To)
|
||||||
|
exten => _08600XXX,n,Hangup()
|
||||||
|
|
||||||
|
|
||||||
|
; playback of recorded prompts
|
||||||
|
exten => _851XXXXX,1,Answer()
|
||||||
|
exten => _851XXXXX,n,Playback(${EXTEN})
|
||||||
|
exten => _851XXXXX,n,Hangup()
|
||||||
|
|
||||||
|
; this is used for playing a message to an answering machine forwarded from AMD in VICIDIAL
|
||||||
|
exten => _6851XXXXX,1,Answer()
|
||||||
|
exten => _6851XXXXX,n,WaitForSilence(2000,1,90)
|
||||||
|
exten => _6851XXXXX,n,Playback(sip-silence)
|
||||||
|
exten => _6851XXXXX,n,Playback(${EXTEN:1})
|
||||||
|
exten => _6851XXXXX,n,Hangup()
|
||||||
|
exten => _7851XXXXX,1,WaitForSilence(2000,2) ; AMD got machine. leave message after recording
|
||||||
|
exten => _7851XXXXX,n,Playback(${EXTEN:1})
|
||||||
|
exten => _7851XXXXX,n,AGI(VD_amd_post.agi,${EXTEN:1})
|
||||||
|
exten => _7851XXXXX,n,Hangup()
|
||||||
|
|
||||||
|
|
||||||
|
; FastAGI for VICIDIAL/astGUIclient call logging
|
||||||
|
exten => h,1,AGI(agi://127.0.0.1:4577/call_log--HVcauses--PRI-----NODEBUG-----${HANGUPCAUSE}-----${DIALSTATUS}-----${DIALEDTIME}-----${ANSWEREDTIME}-----${HANGUPCAUSE(${HANGUPCAUSE_KEYS()},tech)}))
|
||||||
|
|
||||||
|
; Example phone extensions
|
||||||
|
; 100-350 phone extensions now auto-generated, so no need to uncommend them
|
||||||
|
; extensions for other SIP and IAX call center phones
|
||||||
|
; cc100-cc150 SIP Phones
|
||||||
|
;exten => _1[0-5]X,1,Dial(sip/cc${EXTEN},20,to)
|
||||||
|
;exten => _1[0-5]X,n,Hangup()
|
||||||
|
; cc300-cc350 IAX Phones
|
||||||
|
;exten => _3[0-5]X,1,Dial(IAX2/cc${EXTEN},20,to)
|
||||||
|
;exten => _3[0-5]X,n,Hangup()
|
||||||
|
; extensions if using a T1 channelbank
|
||||||
|
;exten => _19XX,1,Dial(Zap/${EXTEN:2},30,o)
|
||||||
|
;exten => _19XX,n,Hangup()
|
||||||
|
; Extension 4001 rings Zap phone (this example for FXS on Zap port 1)
|
||||||
|
;exten => 4001,1,Dial(Zap/1,30,o) ; ring Zap device 1
|
||||||
|
;exten => 4001,n,Voicemail(u4001) ; Send to voicemail...
|
||||||
|
;exten => 4001,n,Hangup()
|
||||||
|
|
||||||
|
|
||||||
|
; # timeout invalid rules
|
||||||
|
exten => #,1,Playback(invalid) ; "Thanks for trying the demo"
|
||||||
|
exten => #,2,Hangup() ; Hang them up.
|
||||||
|
exten => t,1,Goto(#,1) ; If they take too long, give up
|
||||||
|
exten => t,n,Hangup()
|
||||||
|
exten => i,1,Playback(invalid) ; "That's not valid, try again"
|
||||||
|
exten => i,n,Hangup()
|
||||||
|
|
||||||
|
|
||||||
|
; Extensions for performance testing
|
||||||
|
;exten => _91999NXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
;exten => _91999NXXXXXX,n,Dial(${TRUNKloop}/${EXTEN:2},,tTo)
|
||||||
|
;exten => _91999NXXXXXX,n,Hangup()
|
||||||
|
;exten => 999999999999,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
;exten => 999999999999,n,Dial(${TRUNKloop}/${EXTEN:1},,tTo)
|
||||||
|
;exten => 999999999999,n,Hangup()
|
||||||
|
|
||||||
|
; This is a loopback dialaround to allow for hearing of ringing for 3way calls
|
||||||
|
exten => _881NXXNXXXXXX,1,Answer()
|
||||||
|
exten => _881NXXNXXXXXX,n,Dial(${TRUNKloop}/9${EXTEN:2},,To)
|
||||||
|
exten => _881NXXNXXXXXX,n,Hangup()
|
||||||
|
|
||||||
|
; Vtiger fax and email log extensions
|
||||||
|
exten => _9118XXXXXXXX,1,Dial(${TRUNKblind}/9998818112,55,to)
|
||||||
|
exten => _9118XXXXXXXX,n,Hangup()
|
||||||
|
exten => _9119XXXXXXXX,1,Dial(${TRUNKblind}/9998819112,55,to)
|
||||||
|
exten => _9119XXXXXXXX,n,Hangup()
|
||||||
|
|
||||||
|
|
||||||
|
; CARRIER DIALING EXTENSIONS, USE THE ADMIN INTERFACE TO PROGRAM THESE
|
||||||
|
; dial an 800 outbound number
|
||||||
|
;exten => _91800NXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
;exten => _91800NXXXXXX,n,Dial(${TRUNK}/${EXTEN:1},,To)
|
||||||
|
;exten => _91800NXXXXXX,n,Hangup()
|
||||||
|
;exten => _91888NXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
;exten => _91888NXXXXXX,n,Dial(${TRUNK}/${EXTEN:1},,To)
|
||||||
|
;exten => _91888NXXXXXX,n,Hangup()
|
||||||
|
;exten => _91877NXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
;exten => _91877NXXXXXX,n,Dial(${TRUNK}/${EXTEN:1},,To)
|
||||||
|
;exten => _91877NXXXXXX,n,Hangup()
|
||||||
|
;exten => _91866NXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
;exten => _91866NXXXXXX,n,Dial(${TRUNK}/${EXTEN:1},,To)
|
||||||
|
;exten => _91866NXXXXXX,n,Hangup()
|
||||||
|
;exten => _91855NXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
;exten => _91855NXXXXXX,n,Dial(${TRUNK}/${EXTEN:1},,To)
|
||||||
|
;exten => _91855NXXXXXX,n,Hangup()
|
||||||
|
|
||||||
|
; dial a long distance outbound number
|
||||||
|
; This 'o' Dial flag is VERY important for VICIDIAL on outbound calls
|
||||||
|
;exten => _91NXXNXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
;exten => _91NXXNXXXXXX,n,Dial(${TRUNKX}/${EXTEN:1},,To)
|
||||||
|
;exten => _91NXXNXXXXXX,n,Hangup()
|
||||||
|
|
||||||
|
; dial a local outbound number (modified because of only LD T1)
|
||||||
|
;exten => _9NXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
;exten => _9NXXXXXX,n,Dial(${TRUNK}/1727${EXTEN:1},,To)
|
||||||
|
;exten => _9NXXXXXX,n,Hangup()
|
||||||
|
|
||||||
|
; dial a local 727 outbound number with area code
|
||||||
|
;exten => _9727NXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
;exten => _9727NXXXXXX,n,Dial(${TRUNK}/1${EXTEN:1},,To)
|
||||||
|
;exten => _9727NXXXXXX,n,Hangup()
|
||||||
|
|
||||||
|
; dial a long distance outbound number to the UK
|
||||||
|
; This 'o' Dial flag is VERY important for VICIDIAL on outbound calls,
|
||||||
|
;exten => _901144XXXXXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
;exten => _901144XXXXXXXXXX,n,Dial(${TRUNKX}/${EXTEN:1},55,To)
|
||||||
|
;exten => _901144XXXXXXXXXX,n,Hangup()
|
||||||
|
|
||||||
|
; dial a long distance outbound number to Australia
|
||||||
|
; This 'o' Dial flag is VERY important for VICIDIAL on outbound calls,
|
||||||
|
;exten => _901161XXXXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
;exten => _901161XXXXXXXXX,n,Dial(${TRUNKX}/${EXTEN:1},,To)
|
||||||
|
;exten => _901161XXXXXXXXX,n,Hangup()
|
||||||
|
|
||||||
|
; dial a long distance outbound number through BINFONE
|
||||||
|
; exten => _91NXXNXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
; exten => _91NXXNXXXXXX,n,Dial(${TRUNKIAX}/${EXTEN:1},55,To)
|
||||||
|
; exten => _91NXXNXXXXXX,n,Hangup()
|
||||||
|
; dial a long distance outbound number through a SIP provider
|
||||||
|
; exten => _91NXXNXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
; exten => _91NXXNXXXXXX,n,Dial(sip/${EXTEN:1}@SIPtrunk,55,o)
|
||||||
|
; exten => _91NXXNXXXXXX,n,Hangup()
|
||||||
|
; special extensions for North America to catch invalid phone numbers
|
||||||
|
; exten => _91XXX[0-1]XXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
; exten => _91XXX[0-1]XXXXXX,n,Dial(${TRUNKloop}/8889990011112,,to)
|
||||||
|
; exten => _91XXX[0-1]XXXXXX,n,Hangup()
|
||||||
|
; exten => _91[0-1]XXXXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
; exten => _91[0-1]XXXXXXXXX,n,Dial(${TRUNKloop}/8889990011112,,to)
|
||||||
|
; exten => _91[0-1]XXXXXXXXX,n,Hangup()
|
||||||
|
; exten => _91XXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
; exten => _91XXXXXX,n,Dial(${TRUNKloop}/8889990011112,,to)
|
||||||
|
; exten => _91XXXXXX,n,Hangup()
|
||||||
|
; exten => _91XXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
; exten => _91XXXXXXX,n,Dial(${TRUNKloop}/8889990011112,,to)
|
||||||
|
; exten => _91XXXXXXX,n,Hangup()
|
||||||
|
; exten => _91XXXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
; exten => _91XXXXXXXX,n,Dial(${TRUNKloop}/8889990011112,,to)
|
||||||
|
; exten => _91XXXXXXXX,n,Hangup()
|
||||||
|
; exten => _91XXXXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
; exten => _91XXXXXXXXX,n,Dial(${TRUNKloop}/8889990011112,,to)
|
||||||
|
; exten => _91XXXXXXXXX,n,Hangup()
|
||||||
|
; exten => _91XXXXXXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
; exten => _91XXXXXXXXXXX,n,Dial(${TRUNKloop}/8889990011112,,to)
|
||||||
|
; exten => _91XXXXXXXXXXX,n,Hangup()
|
||||||
|
; exten => _91XXXXXXXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
; exten => _91XXXXXXXXXXXX,n,Dial(${TRUNKloop}/8889990011112,,to)
|
||||||
|
; exten => _91XXXXXXXXXXXX,n,Hangup()
|
||||||
|
; exten => _91XXXXXXXXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
; exten => _91XXXXXXXXXXXXX,n,Dial(${TRUNKloop}/8889990011112,,to)
|
||||||
|
; exten => _91XXXXXXXXXXXXX,n,Hangup()
|
||||||
|
; block calls to 555 numbers
|
||||||
|
; exten => _91NXX555NXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
; exten => _91NXX555NXXX,n,Dial(${TRUNKloop}/8889990011112,,to)
|
||||||
|
; exten => _91NXX555NXXX,n,Hangup()
|
||||||
|
; dial a USA long distance outbound number through the loopback-no-log context
|
||||||
|
; exten => _91NXXNXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
; exten => _91NXXNXXXXXX,n,Dial(${TRUNKloop}/888${EXTEN:2},55,o)
|
||||||
|
; exten => _91NXXNXXXXXX,n,Hangup()
|
||||||
|
;exten => _888NXXNXXXXXX,1,Goto(loopback-no-log,91${EXTEN:3},1)
|
||||||
|
;exten => _888NXXNXXXXXX,n,Hangup()
|
||||||
|
|
||||||
|
exten => 8889990011112,1,Goto(loopback-no-log,9990011112,1)
|
||||||
|
exten => 8889990011112,n,Hangup()
|
||||||
|
|
||||||
|
|
||||||
|
; Inbound call from BINFONE
|
||||||
|
; exten => 1112223333,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
; exten => 1112223333,n,Dial(sip/gs102,55,o)
|
||||||
|
; exten => 1112223333,n,Hangup()
|
||||||
|
|
||||||
|
; Extension 7275551212 - Inbound local number from PRI with 10 digit delivery
|
||||||
|
;exten => 7275551212,1,Ringing()
|
||||||
|
;exten => 7275551212,n,Wait(1)
|
||||||
|
;exten => 7275551212,n,AGI(agi://127.0.0.1:4577/call_log--fullCID--${EXTEN}-----${CALLERID(all)}-----${CALLERID(num)}-----${CALLERID(name)})
|
||||||
|
;exten => 7275551212,n,Answer()
|
||||||
|
;exten => 7275551212,n,Dial(sip/spa2000&sip/spa2001,30,To)
|
||||||
|
;exten => 7275551212,n,Voicemail(u2000)
|
||||||
|
;exten => 7275551212,n,Hangup()
|
||||||
|
|
||||||
|
; parameters for call_inbound.agi (7 fields separated by five dashes "-----"):
|
||||||
|
; 1. the extension of the phone to ring as defined in the asterisk.phones table
|
||||||
|
; 2. the phone number that was called, for the live_inbound/_log entry
|
||||||
|
; 3. a text description of the number that was called in
|
||||||
|
; 4-7. optional fields, they are also passed as fields in the GUI to web browser
|
||||||
|
; This is not part of VICIDIAL, it is for astGUIclient agent use only
|
||||||
|
|
||||||
|
; Extension 3429 - Inbound 800 number (1-800-555-3429) example of RBS T1
|
||||||
|
; with 10 digit ANI and 4 digit DNIS star separated
|
||||||
|
;exten => _**3429,1,Ringing
|
||||||
|
;exten => _**3429,n,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
;exten => _**3429,n,AGI(call_inbound.agi,spa2000-----8005553429-----Inbound 800-----x-----y-----z-----w)
|
||||||
|
;exten => _**3429,n,Answer()
|
||||||
|
;exten => _**3429,n,Dial(sip/spa2000&sip/spa2001,30,to)
|
||||||
|
;exten => _**3429,n,Voicemail(u2000)
|
||||||
|
;exten => _**3429,n,Hangup()
|
||||||
|
; Extension 3429 - with ANI [callerID]
|
||||||
|
;exten => _*NXXNXXXXXX*3429,1,Ringing
|
||||||
|
;exten => _*NXXNXXXXXX*3429,n,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
;exten => _*NXXNXXXXXX*3429,n,AGI(call_inbound.agi,spa2000-----8005553429-----Inbound 800-----x-----y-----z-----w)
|
||||||
|
;exten => _*NXXNXXXXXX*3429,n,Answer()
|
||||||
|
;exten => _*NXXNXXXXXX*3429,n,Dial(sip/spa2000&sip/spa2001,30,to)
|
||||||
|
;exten => _*NXXNXXXXXX*3429,n,Voicemail(u2000)
|
||||||
|
;exten => _*NXXNXXXXXX*3429,n,Hangup()
|
||||||
|
|
||||||
|
|
||||||
|
; parameters for agi-VDAD_ALL_inbound.agi (upto 12 fields separated by five dashes "-----"):
|
||||||
|
; Below are the parameters needed for the script to be run properly
|
||||||
|
; 1. the method of call handling for the script:
|
||||||
|
; - CID - CID received, add record with phone number
|
||||||
|
; - CIDLOOKUP - Lookup CID to find record in whole system
|
||||||
|
; - CIDLOOKUPRL - Restrict lookup to one list
|
||||||
|
; - CIDLOOKUPRC - Restrict lookup to one campaign's lists
|
||||||
|
; - CLOSER - Closer calls from VICIDIAL fronters
|
||||||
|
; - ANI - ANI received, add record with phone number (based on RBS T1s)
|
||||||
|
; - ANILOOKUP - Lookup ANI to find record in whole system
|
||||||
|
; - ANILOOKUPRL - Restrict lookup to one list
|
||||||
|
; - ANILOOKUPRC - Restrict lookup to one campaign's lists
|
||||||
|
; - VID - Add record with Vendor Lead Code received as argument 12
|
||||||
|
; - VIDLOOKUP - Lookup Vendor Lead Code received as argument 12 to find record in whole system
|
||||||
|
; - VIDLOOKUPRL - Restrict lookup to one list (argument 12)
|
||||||
|
; - VIDLOOKUPRC - Restrict lookup to one campaign's lists (argument 12)
|
||||||
|
; - VIDPROMPT - Prompt Vendor Lead Code to User with IVR to add record with Vendor Lead Code
|
||||||
|
; - VIDPROMPTLOOKUP - Prompt Vendor Lead Code to User with IVR to find record in whole system
|
||||||
|
; - VIDPROMPTLOOKUPRL - Restrict lookup to one list
|
||||||
|
; - VIDPROMPTLOOKUPRC - Restrict lookup to one campaign's lists
|
||||||
|
; - 3DIGITID - Enter 3 digit code to go to agent
|
||||||
|
; - 4DIGITID - Enter 4 digit code to go to agent
|
||||||
|
; - XDIGITID - Enter X digit code to go to agent(variable, i.e. 9DIGITID, 12DIGITID, etc...)
|
||||||
|
; 2. the method of searching for an available agent:
|
||||||
|
; - LO - Load Balance Overflow only (priority to home server)
|
||||||
|
; - LB - <default> Load Balance total system
|
||||||
|
; - SO - Home server only
|
||||||
|
; 3. the full name of the IN GROUP to be used in vicidial for the inbound call
|
||||||
|
; 4. the phone number that was called, for the log entry
|
||||||
|
; 5. the callerID or lead_id of the person that called(usually overridden)
|
||||||
|
; 6. the park extension audio file name if used
|
||||||
|
; 7. the status of the call initially(usually not used)
|
||||||
|
; 8. the list_id to insert the new lead under if it is new (and CID/ANI available)
|
||||||
|
; 9. the phone dialing code to insert with the new lead if new (and CID/ANI available)
|
||||||
|
; 10. the campaign_id to search within lists if CIDLOOKUPRC
|
||||||
|
; 11. the user to queue the call to for AGENTDIRECT in-group calls
|
||||||
|
; 12. vendor_lead_code if external mechanism like custom IVR is used to prompt user for ID
|
||||||
|
;
|
||||||
|
; inbound VICIDIAL call with CID delivery through T1 PRI
|
||||||
|
;exten => 1234,1,Answer() ; Answer the line
|
||||||
|
;exten => 1234,n,AGI(agi-VDAD_ALL_inbound.agi,CID-----LB-----CL_GALLERIA-----7274515134-----Closer-----park----------999-----1)
|
||||||
|
;exten => 1234,n,Hangup()
|
||||||
|
|
||||||
|
; inbound VICIDIAL transfer calls [can arrive through PRI T1 crossover, IAX or SIP channel]
|
||||||
|
exten => _90009.,1,Answer() ; Answer the line
|
||||||
|
exten => _90009.,n,Dial(${TRUNKloop}/9${EXTEN},,to)
|
||||||
|
exten => _90009.,n,Hangup()
|
||||||
|
exten => _990009.,1,Answer() ; Answer the line, Sometimes needs to be removed
|
||||||
|
exten => _990009.,n,AGI(agi-VDAD_ALL_inbound.agi,CLOSER-----LB-----CL_TESTCAMP-----7275551212-----Closer-----park----------999-----1)
|
||||||
|
exten => _990009.,n,Hangup()
|
||||||
|
; DID forwarded calls
|
||||||
|
exten => _99909*.,1,Answer()
|
||||||
|
exten => _99909*.,n,AGI(agi-VDAD_ALL_inbound.agi)
|
||||||
|
exten => _99909*.,n,Hangup()
|
||||||
|
|
||||||
|
|
||||||
|
; barge monitoring extension
|
||||||
|
exten => 8159,1,ZapBarge()
|
||||||
|
exten => 8159,n,Hangup()
|
||||||
|
|
||||||
|
; ZapBarge direct channel extensions
|
||||||
|
exten => _86120XX,1,ZapBarge(${EXTEN:5})
|
||||||
|
exten => _86120XX,n,Hangup()
|
||||||
|
|
||||||
|
; MeetMe Adjustment Extensions
|
||||||
|
exten => _X48600XXX,1,MeetMeAdmin(${EXTEN:2},T,${EXTEN:0:1})
|
||||||
|
exten => _X48600XXX,2,Hangup()
|
||||||
|
|
||||||
|
exten => _X38600XXX,1,MeetMeAdmin(${EXTEN:2},t,${EXTEN:0:1})
|
||||||
|
exten => _X38600XXX,2,Hangup()
|
||||||
|
|
||||||
|
exten => _X28600XXX,1,MeetMeAdmin(${EXTEN:2},m,${EXTEN:0:1})
|
||||||
|
exten => _X28600XXX,2,Hangup()
|
||||||
|
|
||||||
|
exten => _X18600XXX,1,MeetMeAdmin(${EXTEN:2},M,${EXTEN:0:1})
|
||||||
|
exten => _X18600XXX,2,Hangup()
|
||||||
|
|
||||||
|
exten => _55558600XXX,1,MeetMeAdmin(${EXTEN:4},K)
|
||||||
|
exten => _55558600XXX,2,Hangup()
|
||||||
|
|
||||||
|
; immediate hangup extension
|
||||||
|
exten => 8300,1,Hangup()
|
||||||
|
|
||||||
|
; astGUIclient conferences
|
||||||
|
exten => _86000[0-4]X,1,Meetme(${EXTEN},q)
|
||||||
|
exten => _86000[0-4]X,n,Hangup()
|
||||||
|
|
||||||
|
; VICIDIAL conferences
|
||||||
|
exten => _86000[5-9]X,1,Meetme(${EXTEN},F)
|
||||||
|
exten => _86000[5-9]X,n,Hangup()
|
||||||
|
exten => _8600[1-2]XX,1,Meetme(${EXTEN},F)
|
||||||
|
exten => _8600[1-2]XX,n,Hangup()
|
||||||
|
|
||||||
|
; quiet entry and leaving conferences for VICIDIAL (inbound announce, SendDTMF and ring-agent)
|
||||||
|
exten => _78600XXX,1,Meetme(${EXTEN:1},Fq)
|
||||||
|
exten => _78600XXX,n,Hangup()
|
||||||
|
|
||||||
|
; quiet monitor-only extensions for meetme rooms (for room managers)
|
||||||
|
exten => _68600XXX,1,Meetme(${EXTEN:1},Fmq)
|
||||||
|
exten => _68600XXX,n,Hangup()
|
||||||
|
|
||||||
|
; Asterisk 1.8 workaround
|
||||||
|
exten => _58600XXX,1,Meetme(${EXTEN:1},Fmq)
|
||||||
|
exten => _58600XXX,n,Hangup()
|
||||||
|
|
||||||
|
; quiet monitor-only entry and leaving conferences for VICIDIAL (recording)
|
||||||
|
exten => _558600XXX,1,Meetme(${EXTEN:2},Fmq)
|
||||||
|
exten => _558600XXX,n,Hangup()
|
||||||
|
|
||||||
|
; voicelab exten
|
||||||
|
exten => _86009XX,1,Meetme(${EXTEN},Fmq)
|
||||||
|
; voicelab exten moderator
|
||||||
|
exten => _986009XX,1,Meetme(${EXTEN:1})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; park channel for client GUI parking, hangup after 30 minutes
|
||||||
|
; create a GSM formatted audio file named "park.gsm" that is 30 minutes long
|
||||||
|
; and put it in /var/lib/asterisk/sounds
|
||||||
|
exten => 8301,1,Answer()
|
||||||
|
exten => 8301,n,AGI(park_CID.agi)
|
||||||
|
exten => 8301,n,Playback(park)
|
||||||
|
exten => 8301,n,Hangup()
|
||||||
|
exten => 8303,1,Answer()
|
||||||
|
exten => 8303,n,AGI(park_CID.agi)
|
||||||
|
exten => 8303,n,Playback(conf)
|
||||||
|
exten => 8303,n,Hangup()
|
||||||
|
|
||||||
|
; park channel for client GUI conferencing, hangup after 30 minutes
|
||||||
|
; create a GSM formatted audio file named "conf.gsm" that is 30 minutes long
|
||||||
|
; and put it in /var/lib/asterisk/sounds
|
||||||
|
exten => 8302,1,Answer()
|
||||||
|
exten => 8302,n,Playback(conf)
|
||||||
|
exten => 8302,n,Hangup()
|
||||||
|
|
||||||
|
exten => 8304,1,Answer()
|
||||||
|
exten => 8304,n,Playback(ding)
|
||||||
|
exten => 8304,n,Hangup()
|
||||||
|
|
||||||
|
; default audio for safe harbor 2-second-after-hello message then hangup
|
||||||
|
; create a GSM formatted audio file complies with safe harbor rules
|
||||||
|
; and put it in /var/lib/asterisk/sounds then change filename below
|
||||||
|
exten => 8307,1,Answer()
|
||||||
|
exten => 8307,n,Playback(vm-goodbye)
|
||||||
|
exten => 8307,n,Hangup()
|
||||||
|
|
||||||
|
; this is used for playing a message to an answering machine forwarded from AMD in VICIDIAL
|
||||||
|
exten => 8320,1,AGI(VD_amd.agi,${EXTEN}-----YES)
|
||||||
|
exten => 8320,n,Hangup()
|
||||||
|
exten => _8320*.,1,AGI(VD_amd.agi,${EXTEN}-----YES)
|
||||||
|
exten => _8320*.,n,Hangup()
|
||||||
|
|
||||||
|
; these are used for the ring_all function in VICIDIAL
|
||||||
|
exten => _8331*.,1,Playback(sip-silence)
|
||||||
|
exten => _8331*.,n,AGI(agi-VDAD_RINGALL.agi,${EXTEN})
|
||||||
|
exten => _8331*.,n,AGI(agi-VDAD_RINGALL.agi,${EXTEN})
|
||||||
|
exten => _8331*.,n,AGI(agi-VDAD_RINGALL.agi,${EXTEN})
|
||||||
|
exten => _8331*.,n,Hangup()
|
||||||
|
|
||||||
|
|
||||||
|
; use for selective CallerID hangup by area code(hard-coded)
|
||||||
|
exten => 8352,1,AGI(agi-VDADselective_CID_hangup.agi,${EXTEN})
|
||||||
|
exten => 8352,n,Playback(safe_harbor)
|
||||||
|
exten => 8352,n,Hangup()
|
||||||
|
|
||||||
|
; this is used for sending DTMF signals within conference calls, the client app
|
||||||
|
; sends the digits to be played in the callerID field
|
||||||
|
; sound files must be placed in /var/lib/asterisk/sounds
|
||||||
|
exten => 8500998,1,Answer()
|
||||||
|
exten => 8500998,n,Playback(silence)
|
||||||
|
exten => 8500998,n,AGI(agi-dtmf.agi,signalonly)
|
||||||
|
exten => 8500998,n,Hangup()
|
||||||
|
|
||||||
|
; multi-remote-monitor entry extensions
|
||||||
|
exten => 8162,1,Dial(${TRUNKblind}/34567890123456789,55,to)
|
||||||
|
exten => 8162,n,Hangup()
|
||||||
|
|
||||||
|
exten => 34567890123456789,1,Answer()
|
||||||
|
exten => 34567890123456789,n,Goto(monitor,s,1)
|
||||||
|
exten => 34567890123456789,n,Hangup()
|
||||||
|
|
||||||
|
;#### VDAD STANDARD TRANSFER ENTRIES ####
|
||||||
|
; Below are the parameters needed for the agi-VDAD_ALL_outbound.agi script to be run properly
|
||||||
|
; 1. the method of call handling for the script:
|
||||||
|
; - NORMAL - <default> Standard outbound routing to agent
|
||||||
|
; - TEST - For performance testing only
|
||||||
|
; - BROADCAST - For no-agent broadcast dialing
|
||||||
|
; - SURVEY - For survery question then on to agent
|
||||||
|
; - REMINDER - Reminder campaign
|
||||||
|
; - REMINDX - Reminder with transfer to agent
|
||||||
|
; 2. the method of searching for an available agent:
|
||||||
|
; - LB - <default> Load Balance total system
|
||||||
|
; - LO - Load Balance Overflow only (priority to home server)
|
||||||
|
; - SO - Home server only
|
||||||
|
; 3. the sound file to play when doing a SURVEY, REMINDER, REMINDX campaign
|
||||||
|
; 4. the acceptible dtmf digits for a SURVEY
|
||||||
|
; 5. the out-opt digit for a SURVEY (must be in the digit map)
|
||||||
|
; 6. the sound file to play for a SURVEY when transfering to an agent
|
||||||
|
; 7. the sound file to play for a SURVEY when DNCing the call
|
||||||
|
; 8. OPTIN or OPTOUT: if OPTIN call is only sent to agent with button press
|
||||||
|
; if OPTOUT call is sent to agent if no button press at all
|
||||||
|
; 9. the status that is use for a SURVEY when someone opts out
|
||||||
|
; if the status is DNC it will also add them to the internal dnc table
|
||||||
|
|
||||||
|
; Local channel resolution fix for Asterisk 13
|
||||||
|
exten => _1383XX,1,AGI(agi-VDAD_local_optimize.agi,${CONNECTEDLINE(name)})
|
||||||
|
exten => _1383XX,n,Wait(2)
|
||||||
|
exten => _1383XX,n,Hangup()
|
||||||
|
|
||||||
|
exten => _138331*.,1,AGI(agi-VDAD_local_optimize.agi,${CONNECTEDLINE(name)})
|
||||||
|
exten => _138331*.,n,Wait(2)
|
||||||
|
exten => _138331*.,n,Hangup()
|
||||||
|
|
||||||
|
; VICIDIAL_auto_dialer transfer script for no-agent campaigns:
|
||||||
|
exten => 8364,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
exten => 8364,n,AGI(agi-VDAD_ALL_outbound.agi,NORMAL-----LB-----${CONNECTEDLINE(name)})
|
||||||
|
exten => 8364,n,Hangup()
|
||||||
|
|
||||||
|
; VICIDIAL_auto_dialer transfer script:
|
||||||
|
exten => 8365,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
exten => 8365,n,AGI(agi-VDAD_ALL_outbound.agi,NORMAL-----SO-----${CONNECTEDLINE(name)})
|
||||||
|
exten => 8365,n,Hangup()
|
||||||
|
|
||||||
|
; VICIDIAL_auto_dialer transfer script SURVEY at beginning:
|
||||||
|
exten => 8366,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
exten => 8366,n,AGI(agi-VDAD_ALL_outbound.agi,SURVEYCAMP-----LB-----${CONNECTEDLINE(name)})
|
||||||
|
exten => 8366,n,Hangup()
|
||||||
|
|
||||||
|
; VICIDIAL_auto_dialer transfer script Load Balance Overflow:
|
||||||
|
exten => 8367,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
exten => 8367,n,AGI(agi-VDAD_ALL_outbound.agi,NORMAL-----LO-----${CONNECTEDLINE(name)})
|
||||||
|
exten => 8367,n,Hangup()
|
||||||
|
|
||||||
|
; VICIDIAL_auto_dialer transfer script Load Balanced:
|
||||||
|
exten => 8368,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
exten => 8368,n,AGI(agi-VDAD_ALL_outbound.agi,NORMAL-----LB-----${CONNECTEDLINE(name)})
|
||||||
|
exten => 8368,n,Hangup()
|
||||||
|
|
||||||
|
; VICIDIAL_auto_dialer transfer script AMD with Load Balanced:
|
||||||
|
exten => 8369,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
exten => 8369,n,Playback(sip-silence)
|
||||||
|
exten => 8369,n,AMD(2000,2000,1000,5000,120,50,4,256)
|
||||||
|
exten => 8369,n,AGI(VD_amd.agi,${EXTEN})
|
||||||
|
exten => 8369,n,AGI(agi-VDAD_ALL_outbound.agi,NORMAL-----LB-----${CONNECTEDLINE(name)})
|
||||||
|
exten => 8369,n,Hangup()
|
||||||
|
|
||||||
|
; VICIDIAL auto-dial reminder script
|
||||||
|
exten => 8372,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
exten => 8372,n,AGI(agi-VDADautoREMINDER.agi,${EXTEN})
|
||||||
|
exten => 8372,n,Hangup()
|
||||||
|
|
||||||
|
; VICIDIAL SURVEY transfer script AMD with Load Balanced:
|
||||||
|
exten => 8373,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
exten => 8373,n,Playback(sip-silence)
|
||||||
|
exten => 8373,n,AMD(2000,2000,1000,5000,120,50,4,256)
|
||||||
|
exten => 8373,n,AGI(VD_amd.agi,${EXTEN})
|
||||||
|
exten => 8373,n,AGI(agi-VDAD_ALL_outbound.agi,SURVEYCAMP-----LB-----${CONNECTEDLINE(name)})
|
||||||
|
exten => 8373,n,Hangup()
|
||||||
|
|
||||||
|
; VICIDIAL SURVEY transfer script with Cepstral names:
|
||||||
|
exten => 8374,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
exten => 8374,n,AGI(agi-VDAD_ALL_outbound.agi,SURVEYCAMPCEP-----LB-----${CONNECTEDLINE(name)})
|
||||||
|
exten => 8374,n,Hangup()
|
||||||
|
|
||||||
|
; VICIDIAL SURVEY transfer script AMD with Cepstral variables:
|
||||||
|
exten => 8375,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
exten => 8375,n,Playback(sip-silence)
|
||||||
|
exten => 8375,n,AMD(2000,2000,1000,5000,120,50,4,256)
|
||||||
|
exten => 8375,n,AGI(VD_amd.agi,${EXTEN})
|
||||||
|
exten => 8375,n,AGI(agi-VDAD_ALL_outbound.agi,SURVEYCAMPCEP-----LB-----${CONNECTEDLINE(name)})
|
||||||
|
exten => 8375,n,Hangup()
|
||||||
|
|
||||||
|
; BETA VICIDIAL_auto_dialer transfer script Load Balanced:
|
||||||
|
exten => 8377,1,AGI(agi://127.0.0.1:4577/call_log)
|
||||||
|
exten => 8377,n,Set(LRct=1)
|
||||||
|
exten => 8377,n,While($[${LRct} < 100])
|
||||||
|
exten => 8377,n,AGI(agi-VDAD_ALL_outboundBETA.agi,NORMAL-----LB-----${CONNECTEDLINE(name)})
|
||||||
|
exten => 8377,n,Set(LRct=$[${LRct} + 1])
|
||||||
|
exten => 8377,n,EndWhile()
|
||||||
|
exten => 8377,n,AGI(agi-VDAD_ALL_outboundBETA.agi,NORMAL-----LB-----${CONNECTEDLINE(name)})
|
||||||
|
exten => 8377,n,Hangup()
|
||||||
|
|
||||||
|
|
||||||
|
; PERFORMANCE TESTING
|
||||||
|
exten => _999XXXXXX1,1,Answer()
|
||||||
|
exten => _999XXXXXX1,n,Wait(2)
|
||||||
|
exten => _999XXXXXX1,n,Playback(vicidial-welcome)
|
||||||
|
exten => _999XXXXXX1,n,Hangup()
|
||||||
|
|
||||||
|
exten => _999XX11112,1,Wait(2)
|
||||||
|
exten => _999XX11112,n,Answer()
|
||||||
|
exten => _999XX11112,n,Playback(ss-noservice)
|
||||||
|
exten => _999XX11112,n,Playback(vm-goodbye)
|
||||||
|
exten => _999XX11112,n,Hangup()
|
||||||
|
|
||||||
|
exten => _999XX18112,1,Wait(2)
|
||||||
|
exten => _999XX18112,n,Answer()
|
||||||
|
exten => _999XX18112,n,Playback(vtiger-fax)
|
||||||
|
exten => _999XX18112,n,Playback(vtiger-fax)
|
||||||
|
exten => _999XX18112,n,Hangup()
|
||||||
|
|
||||||
|
exten => _999XX19112,1,Wait(2)
|
||||||
|
exten => _999XX19112,n,Answer()
|
||||||
|
exten => _999XX19112,n,Playback(vtiger-email)
|
||||||
|
exten => _999XX19112,n,Playback(vtiger-email)
|
||||||
|
exten => _999XX19112,n,Hangup()
|
||||||
|
|
||||||
|
exten => _999XXXX112,1,Wait(5)
|
||||||
|
exten => _999XXXX112,n,Answer()
|
||||||
|
exten => _999XXXX112,n,Playback(demo-instruct)
|
||||||
|
exten => _999XXXX112,n,Playback(demo-instruct)
|
||||||
|
exten => _999XXXX112,n,Hangup()
|
||||||
|
|
||||||
|
exten => _999XXXXXX2,1,Wait(8)
|
||||||
|
exten => _999XXXXXX2,n,Answer()
|
||||||
|
exten => _999XXXXXX2,n,Playback(demo-instruct)
|
||||||
|
exten => _999XXXXXX2,n,Hangup()
|
||||||
|
|
||||||
|
exten => _999XXXXXX3,1,Set(PRI_CAUSE=1)
|
||||||
|
exten => _999XXXXXX3,n,Hangup()
|
||||||
|
|
||||||
|
exten => _999XXXXXX4,1,Set(PRI_CAUSE=27)
|
||||||
|
exten => _999XXXXXX4,n,Hangup()
|
||||||
|
|
||||||
|
exten => _999XXXXXX5,1,Ringing
|
||||||
|
exten => _999XXXXXX5,n,Wait(120)
|
||||||
|
exten => _999XXXXXX5,n,Hangup()
|
||||||
|
|
||||||
|
exten => _999XXXXXX6,1,Wait(10)
|
||||||
|
exten => _999XXXXXX6,n,Answer()
|
||||||
|
exten => _999XXXXXX6,n,Playback(demo-instruct)
|
||||||
|
exten => _999XXXXXX6,n,Hangup()
|
||||||
|
|
||||||
|
exten => _999XXXXXX7,1,Wait(12)
|
||||||
|
exten => _999XXXXXX7,n,Answer()
|
||||||
|
exten => _999XXXXXX7,n,Playback(demo-enterkeywords)
|
||||||
|
exten => _999XXXXXX7,n,Hangup()
|
||||||
|
|
||||||
|
exten => _999XXXXXX8,1,Set(PRI_CAUSE=17)
|
||||||
|
exten => _999XXXXXX8,n,Hangup()
|
||||||
|
|
||||||
|
exten => _999XXXXXX9,1,Wait(6)
|
||||||
|
exten => _999XXXXXX9,n,Answer()
|
||||||
|
exten => _999XXXXXX9,n,Playback(demo-abouttotry)
|
||||||
|
exten => _999XXXXXX9,n,Hangup()
|
||||||
|
|
||||||
|
exten => _999XXXXXX0,1,Wait(5)
|
||||||
|
exten => _999XXXXXX0,n,Answer()
|
||||||
|
exten => _999XXXXXX0,n,Playback(vm-goodbye)
|
||||||
|
exten => _999XXXXXX0,n,Hangup()
|
||||||
|
|
||||||
|
;exten => 99999999999,1,Answer()
|
||||||
|
;exten => 99999999999,n,Playback(conf)
|
||||||
|
;exten => 99999999999,n,Playback(conf)
|
||||||
|
;exten => 99999999999,n,Playback(conf)
|
||||||
|
;exten => 99999999999,n,Playback(conf)
|
||||||
|
;exten => 99999999999,n,Playback(conf)
|
||||||
|
;exten => 99999999999,n,Playback(conf)
|
||||||
|
;exten => 99999999999,n,Playback(conf)
|
||||||
|
;exten => 99999999999,n,Playback(conf)
|
||||||
|
;exten => 99999999999,n,Playback(conf)
|
||||||
|
;exten => 99999999999,n,Playback(conf)
|
||||||
|
;exten => 99999999999,n,Playback(conf)
|
||||||
|
;exten => 99999999999,n,Playback(conf)
|
||||||
|
;exten => 99999999999,n,Hangup()
|
||||||
|
|
||||||
|
|
||||||
|
[monitor]
|
||||||
|
exten => h,1,AGI(agi://127.0.0.1:4577/call_log--HVcauses--PRI-----NODEBUG-----${HANGUPCAUSE}-----${DIALSTATUS}-----${DIALEDTIME}-----${ANSWEREDTIME}-----${HANGUPCAUSE(${HANGUPCAUSE_KEYS()},tech)}))
|
||||||
|
exten => s,1,Set(TIMEOUT(digit)=10)
|
||||||
|
exten => s,n,Set(TIMEOUT(response)=10)
|
||||||
|
exten => s,n,Set(MEETME_EXIT_CONTEXT=monitor_exit)
|
||||||
|
exten => s,n,Background(vm-extension) ; need audio prompt.
|
||||||
|
exten => s,n,WaitExten(10)
|
||||||
|
exten => s,n,Hangup()
|
||||||
|
|
||||||
|
exten => i,1,Goto(monitor_exit,s,1)
|
||||||
|
exten => i,n,Hangup()
|
||||||
|
exten => #,1,Goto(monitor_exit,s,1)
|
||||||
|
exten => #,n,Hangup()
|
||||||
|
exten => t,1,Goto(monitor_exit,s,1)
|
||||||
|
exten => t,n,Hangup()
|
||||||
|
|
||||||
|
exten => _8[0-2]XX,1,Meetme(8600${EXTEN:1},mqX) ; Listen
|
||||||
|
exten => _8[0-2]XX,n,Hangup()
|
||||||
|
exten => _99[0-2]XX,1,Meetme(8600${EXTEN:2},X) ; Barge
|
||||||
|
exten => _99[0-2]XX,n,Hangup()
|
||||||
|
|
||||||
|
[monitor_exit]
|
||||||
|
exten => h,1,AGI(agi://127.0.0.1:4577/call_log--HVcauses--PRI-----NODEBUG-----${HANGUPCAUSE}-----${DIALSTATUS}-----${DIALEDTIME}-----${ANSWEREDTIME}-----${HANGUPCAUSE(${HANGUPCAUSE_KEYS()},tech)}))
|
||||||
|
exten => _X,1,Goto(monitor,s,1)
|
||||||
|
exten => _X,n,Hangup()
|
||||||
|
|
||||||
|
exten => i,1,Goto(monitor,s,1)
|
||||||
|
exten => i,n,Hangup()
|
||||||
|
exten => #,1,Goto(monitor,s,1)
|
||||||
|
exten => #,n,Hangup()
|
||||||
|
exten => t,1,Goto(monitor,s,1)
|
||||||
|
exten => t,n,Hangup()
|
||||||
@@ -1104,7 +1104,12 @@ user_group_script ENUM('DISABLED','ENABLED') default 'DISABLED',
|
|||||||
agent_hangup_route ENUM('HANGUP','MESSAGE','EXTENSION','IN_GROUP','CALLMENU') default 'HANGUP',
|
agent_hangup_route ENUM('HANGUP','MESSAGE','EXTENSION','IN_GROUP','CALLMENU') default 'HANGUP',
|
||||||
agent_hangup_value TEXT,
|
agent_hangup_value TEXT,
|
||||||
agent_hangup_ig_override ENUM('Y','N') default 'N',
|
agent_hangup_ig_override ENUM('Y','N') default 'N',
|
||||||
show_confetti ENUM('DISABLED','SALES','CALLBACKS','SALES_AND_CALLBACKS') default 'DISABLED'
|
show_confetti ENUM('DISABLED','SALES','CALLBACKS','SALES_AND_CALLBACKS') default 'DISABLED',
|
||||||
|
demographic_quotas ENUM('DISABLED','ENABLED','INVALID','COMPLETE') default 'DISABLED',
|
||||||
|
demographic_quotas_container VARCHAR(40) default 'DISABLED',
|
||||||
|
demographic_quotas_rerank ENUM('NO','NOW','HOUR','MINUTE','NOW_HOUR') default 'NO',
|
||||||
|
demographic_quotas_last_rerank DATETIME default '2000-01-01 00:00:00',
|
||||||
|
demographic_quotas_list_resets ENUM('AUTO','MANUAL') default 'MANUAL'
|
||||||
) ENGINE=MyISAM;
|
) ENGINE=MyISAM;
|
||||||
|
|
||||||
CREATE TABLE vicidial_lists (
|
CREATE TABLE vicidial_lists (
|
||||||
@@ -1981,7 +1986,9 @@ max_logged_in_agents ENUM('0','1','2','3','4','5','6','7') default '0',
|
|||||||
user_codes_admin ENUM('0','1','2','3','4','5','6','7') default '0',
|
user_codes_admin ENUM('0','1','2','3','4','5','6','7') default '0',
|
||||||
login_kickall ENUM('0','1','2','3','4','5','6','7') default '0',
|
login_kickall ENUM('0','1','2','3','4','5','6','7') default '0',
|
||||||
abandon_check_queue ENUM('0','1','2','3','4','5','6','7') default '0',
|
abandon_check_queue ENUM('0','1','2','3','4','5','6','7') default '0',
|
||||||
agent_notifications ENUM('0','1','2','3','4','5','6','7') default '0'
|
agent_notifications ENUM('0','1','2','3','4','5','6','7') default '0',
|
||||||
|
demographic_quotas ENUM('0','1','2','3','4','5','6','7') default '0',
|
||||||
|
log_latency_gaps ENUM('0','1','2','3','4','5','6','7') default '1'
|
||||||
) ENGINE=MyISAM;
|
) ENGINE=MyISAM;
|
||||||
|
|
||||||
CREATE TABLE vicidial_campaigns_list_mix (
|
CREATE TABLE vicidial_campaigns_list_mix (
|
||||||
@@ -4969,6 +4976,43 @@ index (user),
|
|||||||
index (log_date)
|
index (log_date)
|
||||||
) ENGINE=MyISAM;
|
) ENGINE=MyISAM;
|
||||||
|
|
||||||
|
CREATE TABLE vicidial_demographic_quotas_goals (
|
||||||
|
vdqg_id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
|
||||||
|
campaign_id VARCHAR(8) default '',
|
||||||
|
demographic_quotas_container VARCHAR(40) default '',
|
||||||
|
quota_field VARCHAR(20) default '',
|
||||||
|
quota_field_order TINYINT(3) default '0',
|
||||||
|
quota_value VARCHAR(100) default '',
|
||||||
|
quota_value_order TINYINT(3) default '0',
|
||||||
|
quota_goal MEDIUMINT(7) default '0',
|
||||||
|
quota_count MEDIUMINT(7) default '0',
|
||||||
|
quota_leads_total MEDIUMINT(7) default '0',
|
||||||
|
quota_leads_active MEDIUMINT(7) default '0',
|
||||||
|
quota_status VARCHAR(10) default 'ACTIVE',
|
||||||
|
quota_modify_date DATETIME,
|
||||||
|
last_lead_id INT(9) UNSIGNED default '0',
|
||||||
|
last_list_id BIGINT(14) UNSIGNED default '0',
|
||||||
|
last_call_date DATETIME,
|
||||||
|
last_status VARCHAR(6) default '',
|
||||||
|
index(campaign_id),
|
||||||
|
index(quota_field),
|
||||||
|
index(quota_value),
|
||||||
|
unique index vdqgi (campaign_id,quota_field,quota_field_order,quota_value,quota_value_order)
|
||||||
|
) ENGINE=MyISAM;
|
||||||
|
|
||||||
|
CREATE TABLE vicidial_latency_gaps (
|
||||||
|
user VARCHAR(20) default '',
|
||||||
|
user_ip VARCHAR(45) default '',
|
||||||
|
gap_date DATETIME,
|
||||||
|
gap_length MEDIUMINT(5) UNSIGNED default '0',
|
||||||
|
last_login_date DATETIME,
|
||||||
|
check_date DATETIME,
|
||||||
|
index(user),
|
||||||
|
index(gap_date),
|
||||||
|
index(check_date),
|
||||||
|
unique index vlgi (user,gap_date)
|
||||||
|
) ENGINE=MyISAM;
|
||||||
|
|
||||||
|
|
||||||
ALTER TABLE vicidial_email_list MODIFY message text character set utf8;
|
ALTER TABLE vicidial_email_list MODIFY message text character set utf8;
|
||||||
|
|
||||||
@@ -5248,6 +5292,9 @@ CREATE UNIQUE INDEX vdalla on vicidial_agent_latency_log_archive (user,log_date)
|
|||||||
CREATE TABLE vicidial_agent_latency_summary_log_archive LIKE vicidial_agent_latency_summary_log;
|
CREATE TABLE vicidial_agent_latency_summary_log_archive LIKE vicidial_agent_latency_summary_log;
|
||||||
CREATE UNIQUE INDEX vdalsla on vicidial_agent_latency_summary_log_archive (user,log_date,web_ip);
|
CREATE UNIQUE INDEX vdalsla on vicidial_agent_latency_summary_log_archive (user,log_date,web_ip);
|
||||||
|
|
||||||
|
CREATE TABLE vicidial_latency_gaps_archive LIKE vicidial_latency_gaps;
|
||||||
|
CREATE UNIQUE INDEX vdlga on vicidial_latency_gaps_archive (user,gap_date);
|
||||||
|
|
||||||
GRANT RELOAD ON *.* TO cron@'%';
|
GRANT RELOAD ON *.* TO cron@'%';
|
||||||
GRANT RELOAD ON *.* TO cron@localhost;
|
GRANT RELOAD ON *.* TO cron@localhost;
|
||||||
|
|
||||||
@@ -5334,6 +5381,8 @@ INSERT INTO vicidial_settings_containers(container_id,container_notes,container_
|
|||||||
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('USER_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(container_id,container_notes,container_type,user_group,container_entry) VALUES ('VICIPHONE_SETTINGS','VICIphone WebRTC Extra Settings','WEBPHONE_SETTINGS','---ALL---','# determines if automatic gain control is enabled\nautoGain : 0\n\n# determines if echo cancellation is enabled\nechoCan : 0\n\n# determines if noise suppression is enabled\nnoiseSup :0\n\n# determines if the reg_exten is called upon successful registration\ndialRegExten : 1\n\n# determines the regional sound to use for progress audio\nprogReg : na\n\n# English translation phrases\nlangAttempting:"Attempting"\nlangConnected:"WS Connected"\nlangDisconnected:"WS Disconnected"\nlangExten:"Extension"\nlangIncall:"Incall"\nlangInit:"Initializing..."\nlangRedirect:"Redirect"\nlangRegFailed:"Reg. Failed"\nlangRegistering:"Registering"\nlangRegistered:"Registered"\nlangReject:"Rejected"\nlangRinging:"Ringing"\nlangSend:"Send"\nlangTrying:"Trying"\nlangUnregFailed:"Unreg. Failed"\nlangUnregistered:"Unregistered"\nlangUnregistering:"Unregistering"\nlangWebrtcError:"Something went wrong with WebRTC. Either your browser does not support the necessary WebRTC functions, you did not allow your browser to access the microphone, or there is a configuration issue. Please check your browsers error console for more details. For a list of compatible browsers please vist http://webrtc.org/"');
|
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('VICIPHONE_SETTINGS','VICIphone WebRTC Extra Settings','WEBPHONE_SETTINGS','---ALL---','# determines if automatic gain control is enabled\nautoGain : 0\n\n# determines if echo cancellation is enabled\nechoCan : 0\n\n# determines if noise suppression is enabled\nnoiseSup :0\n\n# determines if the reg_exten is called upon successful registration\ndialRegExten : 1\n\n# determines the regional sound to use for progress audio\nprogReg : na\n\n# English translation phrases\nlangAttempting:"Attempting"\nlangConnected:"WS Connected"\nlangDisconnected:"WS Disconnected"\nlangExten:"Extension"\nlangIncall:"Incall"\nlangInit:"Initializing..."\nlangRedirect:"Redirect"\nlangRegFailed:"Reg. Failed"\nlangRegistering:"Registering"\nlangRegistered:"Registered"\nlangReject:"Rejected"\nlangRinging:"Ringing"\nlangSend:"Send"\nlangTrying:"Trying"\nlangUnregFailed:"Unreg. Failed"\nlangUnregistered:"Unregistered"\nlangUnregistering:"Unregistering"\nlangWebrtcError:"Something went wrong with WebRTC. Either your browser does not support the necessary WebRTC functions, you did not allow your browser to access the microphone, or there is a configuration issue. Please check your browsers error console for more details. For a list of compatible browsers please vist http://webrtc.org/"');
|
||||||
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('CONFETTI_SETTINGS', 'Confetti settings for screen display', 'OTHER', '---ALL---', '; Confetti settings, to add visual interest to certain events\r\n; duration is how long the confetti animation runs, maxParticleCount is the\r\n; max number of confetti \"pieces\", and particleSpeed is how fast they float\r\nduration => 2\r\nmaxParticleCount => 2350\r\nparticleSpeed => 2\r\n');
|
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('CONFETTI_SETTINGS', 'Confetti settings for screen display', 'OTHER', '---ALL---', '; Confetti settings, to add visual interest to certain events\r\n; duration is how long the confetti animation runs, maxParticleCount is the\r\n; max number of confetti \"pieces\", and particleSpeed is how fast they float\r\nduration => 2\r\nmaxParticleCount => 2350\r\nparticleSpeed => 2\r\n');
|
||||||
|
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('HOPPER_CLI_FLAGS', 'Comand-line flags for hopper process', 'PERL_CLI', '---ALL---', '');
|
||||||
|
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('AGENT_LATENCY_LOGGING','Default agent latency logging settings','PERL_CLI','---ALL---','minimum_gap => 30\r\nemail_sender => \r\nemail_list => \r\nemail_subject => Agent Network Alert');
|
||||||
INSERT INTO `vicidial_settings_containers` VALUES ('VERM_STATUS_NAMES_OVERRIDE','Override dialer status names in enhanced reporting','OTHER','---ALL---','; For each status name you want overridden, type the status followed by\r\n; a pipe, then the new status name\r\n; Ex:\r\n; NZ|Taumatawhakatangihangakoauauotamateaturipukakapikimaungahoronukupoka\r\n201214|Request To Cancel\r\n210200|No Answer-Incomplete Call\r\n210201|Contact Established\r\n210202|Provider Review - HB\r\n210203|Promise to Pay\r\n210204|Setup Payment Plan\r\n210205|Research-Inquiry\r\n210206|Voice Mail Left - HB\r\n210207|Do Not Call\r\n210208|Appeal Verification\r\n210209|Bad Phone\r\n210210|Bad Address\r\n210211|Direct Pay Verification\r\n210213|Provider Approved\r\n210215|Update Notes Only\r\n210216|Voicemail-No Status Change\r\n210217|Sent Letter Request - HB\r\n210218|Auto VoiceMail Left - HB\r\n210219|Auto VoiceMail-No Status Change\r\n210302|Provider Review - LB\r\n210306|Voice Mail Left - LB\r\n210317|Sent Letter Request - LB\r\n210318|Auto VoiceMail Left - LB\r\n211503|Provider - COVID-19\r\n211603|Transferred Call to MLA\r\n'), ('VERM_REPORT_OPTIONS','Container for customizing VERM report output','OTHER','---ALL---','; This is the report queue used if none is chosen by the user\r\n; It\'s preloaded in some forms as well\r\nVERM_default_report_queue => ALL\r\n\r\n; If there are statuses to exclude from reports, list them here\r\n; Separate with commas. Default is AFTHRS\r\nexc_addtl_statuses => AFTHRS\r\n\r\n; Set the below value to 1 (or anything non-blank/non-zero) in order to \r\n; show the agents ID in addition to their full name in the report results\r\nshow_full_agent_info => 1\r\n\r\n; Some reports count \"lost\" calls - which are defined by the below variable\r\n; listing what you define as \"lost\" dispos. Separate with commas.\r\nlost_statuses => LOST,210208,DISPO\r\n\r\n; You can create a detailed IVR survey report for ingroups by defining\r\n; \"ivr_survey_ingroups_detail\" and \"ivr_survey_ingroups_voicemails.\"\r\n; For \"details\", supply an ingroup used as a tracking group on call menus.\r\n; Then, add a pipe and after that list all call menus that use the ingroup\r\n; as the tracking group, separating each with a comma\r\n; To track whether the calls went to voicemail, list every call menu/option\r\n; combination that goes to voicemail, separating the call menu from the \r\n; option with a pipe. One callmenu/option combo per line.\r\nivr_survey_ingroups_detail => 521205|561401,561402,561403,561404,561505\r\nivr_survey_ingroups_voicemails => 561505|t\r\n\r\n; #####################################################\r\n; # ALL of the below are used in the wallboard report #\r\n; #####################################################\r\nVERM_default_outb_widget_queue => ALL_OUT\r\nVERM_default_inb_widget_queue1 => 514915v_USA_Shared\r\nVERM_default_inb_widget_queue2 => 515915v_MLA_Shared\r\n\r\n; Used specifically for the SLA widget\r\n; Uses ingroups - separate multiple ingroups by commas\r\n; Comment out or leave blank to count all ingroups\r\nSLA_LEVEL_PCT_ingroups => 514915v,515915v\r\n\r\n; This removes remote agents from the wallboard reports\r\n; Comment out to include remote agents (or set to zero)\r\nomit_remote_agents => 1\r\n\r\n\r\n; #### AUTO DOWNLOAD ####\r\n; If the "total calls" value on any report requested exceeds the below \r\n; limit, automatically download the three "DETAILS" reports instead\r\n; of attempting to display that many records on-screen\r\nauto_download_limit => 50000\r\n\r\n; #### OUTCOMES report overrides ####\r\n; Use "outcome_lagged_status_overrides" for conditions where the call \r\n; record in the vicidial_log or vicidial_closer_log table has no uniqueid\r\n; value despite having a status/outcome, which can indicate a call \r\n; affected by network lag for certain statuses. This will change the call \r\n; status to "LAGGED". Separate statuses with commas. Default is the \r\n; automatic "PU" status.\r\noutcome_lagged_status_overrides => PU\r\n\r\n; Use "unknown_network_statuses" to change call statuses to read "Network/\r\n; LAGGED" on the OUTCOMES report. Separate statuses with commas.\r\n; IMPORTANT: if you are using the outcome_lagged_status_overrides option \r\n; above, make sure "LAGGED" is one of the unknown_network_statuses here\r\n; unknown_network_statuses => LAGGED\r\n\r\n; Use "outcome_status_overrides" to change one status to another on the \r\n; OUTCOMES report. Overrides are comma-separated pairs of dispositions \r\n; where the first disposition is the disposition to change, and the second\r\n; is the disposition to change to. Separate pairs with a pipe character as\r\n; in the below example. Off by default.\r\n; outcome_status_overrides => CBHOLD,DISPO|XFER,AL');
|
INSERT INTO `vicidial_settings_containers` VALUES ('VERM_STATUS_NAMES_OVERRIDE','Override dialer status names in enhanced reporting','OTHER','---ALL---','; For each status name you want overridden, type the status followed by\r\n; a pipe, then the new status name\r\n; Ex:\r\n; NZ|Taumatawhakatangihangakoauauotamateaturipukakapikimaungahoronukupoka\r\n201214|Request To Cancel\r\n210200|No Answer-Incomplete Call\r\n210201|Contact Established\r\n210202|Provider Review - HB\r\n210203|Promise to Pay\r\n210204|Setup Payment Plan\r\n210205|Research-Inquiry\r\n210206|Voice Mail Left - HB\r\n210207|Do Not Call\r\n210208|Appeal Verification\r\n210209|Bad Phone\r\n210210|Bad Address\r\n210211|Direct Pay Verification\r\n210213|Provider Approved\r\n210215|Update Notes Only\r\n210216|Voicemail-No Status Change\r\n210217|Sent Letter Request - HB\r\n210218|Auto VoiceMail Left - HB\r\n210219|Auto VoiceMail-No Status Change\r\n210302|Provider Review - LB\r\n210306|Voice Mail Left - LB\r\n210317|Sent Letter Request - LB\r\n210318|Auto VoiceMail Left - LB\r\n211503|Provider - COVID-19\r\n211603|Transferred Call to MLA\r\n'), ('VERM_REPORT_OPTIONS','Container for customizing VERM report output','OTHER','---ALL---','; This is the report queue used if none is chosen by the user\r\n; It\'s preloaded in some forms as well\r\nVERM_default_report_queue => ALL\r\n\r\n; If there are statuses to exclude from reports, list them here\r\n; Separate with commas. Default is AFTHRS\r\nexc_addtl_statuses => AFTHRS\r\n\r\n; Set the below value to 1 (or anything non-blank/non-zero) in order to \r\n; show the agents ID in addition to their full name in the report results\r\nshow_full_agent_info => 1\r\n\r\n; Some reports count \"lost\" calls - which are defined by the below variable\r\n; listing what you define as \"lost\" dispos. Separate with commas.\r\nlost_statuses => LOST,210208,DISPO\r\n\r\n; You can create a detailed IVR survey report for ingroups by defining\r\n; \"ivr_survey_ingroups_detail\" and \"ivr_survey_ingroups_voicemails.\"\r\n; For \"details\", supply an ingroup used as a tracking group on call menus.\r\n; Then, add a pipe and after that list all call menus that use the ingroup\r\n; as the tracking group, separating each with a comma\r\n; To track whether the calls went to voicemail, list every call menu/option\r\n; combination that goes to voicemail, separating the call menu from the \r\n; option with a pipe. One callmenu/option combo per line.\r\nivr_survey_ingroups_detail => 521205|561401,561402,561403,561404,561505\r\nivr_survey_ingroups_voicemails => 561505|t\r\n\r\n; #####################################################\r\n; # ALL of the below are used in the wallboard report #\r\n; #####################################################\r\nVERM_default_outb_widget_queue => ALL_OUT\r\nVERM_default_inb_widget_queue1 => 514915v_USA_Shared\r\nVERM_default_inb_widget_queue2 => 515915v_MLA_Shared\r\n\r\n; Used specifically for the SLA widget\r\n; Uses ingroups - separate multiple ingroups by commas\r\n; Comment out or leave blank to count all ingroups\r\nSLA_LEVEL_PCT_ingroups => 514915v,515915v\r\n\r\n; This removes remote agents from the wallboard reports\r\n; Comment out to include remote agents (or set to zero)\r\nomit_remote_agents => 1\r\n\r\n\r\n; #### AUTO DOWNLOAD ####\r\n; If the "total calls" value on any report requested exceeds the below \r\n; limit, automatically download the three "DETAILS" reports instead\r\n; of attempting to display that many records on-screen\r\nauto_download_limit => 50000\r\n\r\n; #### OUTCOMES report overrides ####\r\n; Use "outcome_lagged_status_overrides" for conditions where the call \r\n; record in the vicidial_log or vicidial_closer_log table has no uniqueid\r\n; value despite having a status/outcome, which can indicate a call \r\n; affected by network lag for certain statuses. This will change the call \r\n; status to "LAGGED". Separate statuses with commas. Default is the \r\n; automatic "PU" status.\r\noutcome_lagged_status_overrides => PU\r\n\r\n; Use "unknown_network_statuses" to change call statuses to read "Network/\r\n; LAGGED" on the OUTCOMES report. Separate statuses with commas.\r\n; IMPORTANT: if you are using the outcome_lagged_status_overrides option \r\n; above, make sure "LAGGED" is one of the unknown_network_statuses here\r\n; unknown_network_statuses => LAGGED\r\n\r\n; Use "outcome_status_overrides" to change one status to another on the \r\n; OUTCOMES report. Overrides are comma-separated pairs of dispositions \r\n; where the first disposition is the disposition to change, and the second\r\n; is the disposition to change to. Separate pairs with a pipe character as\r\n; in the below example. Off by default.\r\n; outcome_status_overrides => CBHOLD,DISPO|XFER,AL');
|
||||||
|
|
||||||
INSERT INTO `wallboard_widgets` VALUES ('queues_widget_1','AGENTS_AND_QUEUES','queues','','TEXT',5,'N',1,'Queue Information','','',NULL,'','',NULL,2),('queues_widget_0','AGENTS_AND_QUEUES','queues','','LOGO',2,'N',1,NULL,'','',NULL,'','',NULL,1),('queues_widget_2','AGENTS_AND_QUEUES','queues','SLA Level %','SLA_LEVEL_PCT',1,'N',1,NULL,'','>60',NULL,'','',NULL,3),('queues_widget_3','AGENTS_AND_QUEUES','queues','Outbound calls','LIVE_QUEUE_INFO',1,'N',1,'','201201','','','','','yellow_alarm,|red_alarm,',4),('queues_widget_4','AGENTS_AND_QUEUES','queues','USA Ded Inbound','LIVE_QUEUE_INFO',1,'N',1,'','ALL_IN','','','','','yellow_alarm,|red_alarm,',5),('queues_widget_5','AGENTS_AND_QUEUES','queues','MLA Ded Inbound','LIVE_QUEUE_INFO',1,'N',1,'','514911','','','','','yellow_alarm,|red_alarm,',6),('queues_widget_6','AGENTS_AND_QUEUES','queues','N Waiting Calls','N_WAITING_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,7),('queues_widget_7','AGENTS_AND_QUEUES','queues','Offered Calls','OFFERED_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,8),('queues_widget_8','AGENTS_AND_QUEUES','queues','Answered Calls','ANSWERED_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,9),('queues_widget_9','AGENTS_AND_QUEUES','queues','Lost Calls','LOST_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,10),('queues_widget_10','AGENTS_AND_QUEUES','queues','Longest Wait','LONGEST_WAIT',1,'N',1,NULL,'','',NULL,'','',NULL,11),('queues_widget_11','AGENTS_AND_QUEUES','queues','Live Queues','LIVE_QUEUES',1,'Y',1,NULL,'','',NULL,'','',NULL,12),('queues_widget_12','AGENTS_AND_QUEUES','queues','Live Calls','LIVE_CALLS',1,'Y',2,NULL,'','',NULL,'','',NULL,13),('agent_widget_0','AGENTS_AND_QUEUES','agents','','LOGO',2,'N',1,NULL,'','',NULL,'','',NULL,1),('agent_widget_1','AGENTS_AND_QUEUES','agents','N Waiting Calls','N_WAITING_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,2),('agent_widget_2','AGENTS_AND_QUEUES','agents','Agents Ready','AGENTS_READY',1,'N',1,NULL,'','',NULL,'','',NULL,3),('agent_widget_3','AGENTS_AND_QUEUES','agents','Agents On Call','N_AGENTS_ON_CALL',1,'N',1,NULL,'','',NULL,'','',NULL,4),('agent_widget_4','AGENTS_AND_QUEUES','agents','N Answered Calls','N_ANSWERED_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,5),('agent_widget_5','AGENTS_AND_QUEUES','agents','Clock','CLOCK',1,'N',1,NULL,'','',NULL,'','',NULL,6),('agent_widget_6','AGENTS_AND_QUEUES','agents','Live Agents','LIVE_AGENTS',1,'Y',3,NULL,'','',NULL,'','',NULL,7);
|
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);
|
||||||
@@ -5342,4 +5391,4 @@ INSERT INTO `wallboard_reports` VALUES ('AGENTS_AND_QUEUES','Agents and Queues',
|
|||||||
|
|
||||||
UPDATE system_settings set vdc_agent_api_active='1';
|
UPDATE system_settings set vdc_agent_api_active='1';
|
||||||
|
|
||||||
UPDATE system_settings SET db_schema_version='1682',db_schema_update_date=NOW(),reload_timestamp=NOW();
|
UPDATE system_settings SET db_schema_version='1683',db_schema_update_date=NOW(),reload_timestamp=NOW();
|
||||||
|
|||||||
@@ -2269,3 +2269,58 @@ CREATE TABLE vicidial_agent_latency_summary_log_archive LIKE vicidial_agent_late
|
|||||||
CREATE UNIQUE INDEX vdalsla on vicidial_agent_latency_summary_log_archive (user,log_date,web_ip);
|
CREATE UNIQUE INDEX vdalsla on vicidial_agent_latency_summary_log_archive (user,log_date,web_ip);
|
||||||
|
|
||||||
UPDATE system_settings SET db_schema_version='1682',db_schema_update_date=NOW() where db_schema_version < 1682;
|
UPDATE system_settings SET db_schema_version='1682',db_schema_update_date=NOW() where db_schema_version < 1682;
|
||||||
|
|
||||||
|
ALTER TABLE system_settings ADD demographic_quotas ENUM('0','1','2','3','4','5','6','7') default '0';
|
||||||
|
ALTER TABLE system_settings ADD log_latency_gaps ENUM('0','1','2','3','4','5','6','7') default '1';
|
||||||
|
|
||||||
|
ALTER TABLE vicidial_campaigns ADD demographic_quotas ENUM('DISABLED','ENABLED','INVALID','COMPLETE') default 'DISABLED';
|
||||||
|
ALTER TABLE vicidial_campaigns ADD demographic_quotas_container VARCHAR(40) default 'DISABLED';
|
||||||
|
ALTER TABLE vicidial_campaigns ADD demographic_quotas_rerank ENUM('NO','NOW','HOUR','MINUTE','NOW_HOUR') default 'NO';
|
||||||
|
ALTER TABLE vicidial_campaigns ADD demographic_quotas_last_rerank DATETIME default '2000-01-01 00:00:00';
|
||||||
|
ALTER TABLE vicidial_campaigns ADD demographic_quotas_list_resets ENUM('AUTO','MANUAL') default 'MANUAL';
|
||||||
|
|
||||||
|
CREATE TABLE vicidial_demographic_quotas_goals (
|
||||||
|
vdqg_id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
|
||||||
|
campaign_id VARCHAR(8) default '',
|
||||||
|
demographic_quotas_container VARCHAR(40) default '',
|
||||||
|
quota_field VARCHAR(20) default '',
|
||||||
|
quota_field_order TINYINT(3) default '0',
|
||||||
|
quota_value VARCHAR(100) default '',
|
||||||
|
quota_value_order TINYINT(3) default '0',
|
||||||
|
quota_goal MEDIUMINT(7) default '0',
|
||||||
|
quota_count MEDIUMINT(7) default '0',
|
||||||
|
quota_leads_total MEDIUMINT(7) default '0',
|
||||||
|
quota_leads_active MEDIUMINT(7) default '0',
|
||||||
|
quota_status VARCHAR(10) default 'ACTIVE',
|
||||||
|
quota_modify_date DATETIME,
|
||||||
|
last_lead_id INT(9) UNSIGNED default '0',
|
||||||
|
last_list_id BIGINT(14) UNSIGNED default '0',
|
||||||
|
last_call_date DATETIME,
|
||||||
|
last_status VARCHAR(6) default '',
|
||||||
|
index(campaign_id),
|
||||||
|
index(quota_field),
|
||||||
|
index(quota_value),
|
||||||
|
unique index vdqgi (campaign_id,quota_field,quota_field_order,quota_value,quota_value_order)
|
||||||
|
) ENGINE=MyISAM;
|
||||||
|
|
||||||
|
CREATE TABLE vicidial_latency_gaps (
|
||||||
|
user VARCHAR(20) default '',
|
||||||
|
user_ip VARCHAR(45) default '',
|
||||||
|
gap_date DATETIME,
|
||||||
|
gap_length MEDIUMINT(5) UNSIGNED default '0',
|
||||||
|
last_login_date DATETIME,
|
||||||
|
check_date DATETIME,
|
||||||
|
index(user),
|
||||||
|
index(gap_date),
|
||||||
|
index(check_date),
|
||||||
|
unique index vlgi (user,gap_date)
|
||||||
|
) ENGINE=MyISAM;
|
||||||
|
|
||||||
|
CREATE TABLE vicidial_latency_gaps_archive LIKE vicidial_latency_gaps;
|
||||||
|
CREATE UNIQUE INDEX vdlga on vicidial_latency_gaps_archive (user,gap_date);
|
||||||
|
|
||||||
|
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('HOPPER_CLI_FLAGS', 'Comand-line flags for hopper process', 'PERL_CLI', '---ALL---', '');
|
||||||
|
|
||||||
|
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('AGENT_LATENCY_LOGGING','Default agent latency logging settings','PERL_CLI','---ALL---','minimum_gap => 30\r\nemail_sender => \r\nemail_list => \r\nemail_subject => Agent Network Alert');
|
||||||
|
|
||||||
|
UPDATE system_settings SET db_schema_version='1683',db_schema_update_date=NOW() where db_schema_version < 1683;
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
# 220829-1434 - Added 'C' keepalive option
|
# 220829-1434 - Added 'C' keepalive option
|
||||||
# 221228-2049 - Added KhompEnabled option
|
# 221228-2049 - Added KhompEnabled option
|
||||||
# 230117-2220 - Added --khomp-enable CLI flag
|
# 230117-2220 - Added --khomp-enable CLI flag
|
||||||
|
# 230508-0809 - Added Asterisk 18 compatibility
|
||||||
#
|
#
|
||||||
|
|
||||||
############################################
|
############################################
|
||||||
@@ -2741,11 +2742,24 @@ if ( ($PROMPTcopy_conf_files =~ /y/i) || ($CLIcopy_conf_files =~ /y/i) )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
`cp -f ./docs/conf_examples/extensions.conf.sample-1.4 /etc/asterisk/extensions.conf`;
|
if ($VARasterisk_version =~ /^18|^20/)
|
||||||
`cp -f ./docs/conf_examples/iax.conf.sample-1.4 /etc/asterisk/iax.conf`;
|
{
|
||||||
`cp -f ./docs/conf_examples/sip.conf.sample-1.4 /etc/asterisk/sip.conf`;
|
`cp -f ./docs/conf_examples/extensions.conf.sample-18 /etc/asterisk/extensions.conf`;
|
||||||
`cp -f ./docs/conf_examples/manager.conf.sample /etc/asterisk/manager.conf`;
|
`cp -f ./docs/conf_examples/iax.conf.sample-1.4 /etc/asterisk/iax.conf`;
|
||||||
`cp -f ./docs/conf_examples/voicemail.conf.sample /etc/asterisk/voicemail.conf`;
|
`cp -f ./docs/conf_examples/sip.conf.sample-13 /etc/asterisk/sip.conf`;
|
||||||
|
`cp -f ./docs/conf_examples/manager.conf.sample-13 /etc/asterisk/manager.conf`;
|
||||||
|
`cp -f ./docs/conf_examples/voicemail.conf.sample-1.8 /etc/asterisk/voicemail.conf`;
|
||||||
|
`cp -f ./docs/conf_examples/pjsip.conf.sample-16 /etc/asterisk/pjsip.conf`;
|
||||||
|
`cp -f ./docs/conf_examples/pjsip_wizard.conf.sample-16 /etc/asterisk/pjsip_wizard.conf`;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
`cp -f ./docs/conf_examples/extensions.conf.sample-1.4 /etc/asterisk/extensions.conf`;
|
||||||
|
`cp -f ./docs/conf_examples/iax.conf.sample-1.4 /etc/asterisk/iax.conf`;
|
||||||
|
`cp -f ./docs/conf_examples/sip.conf.sample-1.4 /etc/asterisk/sip.conf`;
|
||||||
|
`cp -f ./docs/conf_examples/manager.conf.sample /etc/asterisk/manager.conf`;
|
||||||
|
`cp -f ./docs/conf_examples/voicemail.conf.sample /etc/asterisk/voicemail.conf`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,371 @@
|
|||||||
|
<?php
|
||||||
|
# DQ_dispo.php
|
||||||
|
#
|
||||||
|
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# This script is designed to be used in the "Dispo Call URL" field of a campaign
|
||||||
|
# It should take in the 'lead_id' and 'dispo' to check for the campaign's
|
||||||
|
# Demographic Quotas settings, and if there is a match, increment the count
|
||||||
|
#
|
||||||
|
# This script is part of the API group and any modifications of data are
|
||||||
|
# logged to the vicidial_api_log table.
|
||||||
|
#
|
||||||
|
# This script is a required part of the Demographic Quotas feature, for more
|
||||||
|
# information on how it works, read the DEMOGRAPHIC_QUOTAS.txt document.
|
||||||
|
#
|
||||||
|
# Example of what to put in the Dispo URL field:
|
||||||
|
# VARhttp://192.168.1.1/agc/DQ_dispo.php?lead_id=--A--lead_id--B--&dispo=--A--dispo--B--&campaign_id=TESTCAMP&user=--A--user--B--&pass=--A--pass--B--&log_to_file=1
|
||||||
|
#
|
||||||
|
# Example of what to put in the No Agent Call URL field:
|
||||||
|
# (IMPORTANT: user needs to be NOAGENTURL and pass needs to be set to the call_id)
|
||||||
|
# VARhttp://192.168.1.1/agc/DQ_dispo.php?lead_id=--A--lead_id--B--&dispo=--A--dispo--B--&campaign_id=TESTCAMP&user=NOAGENTURL&pass=--A--call_id--B--&log_to_file=1
|
||||||
|
#
|
||||||
|
# Definable Fields: (other fields should be left as they are)
|
||||||
|
# - log_to_file - (0,1) if set to 1, will create a log file in the agc directory
|
||||||
|
# - campaign_id - (MUST BE SET TO THE CAMPAIGN ID)
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# CHANGES
|
||||||
|
# 230511-1100 - First Build
|
||||||
|
#
|
||||||
|
|
||||||
|
$api_script = 'DQdispo';
|
||||||
|
$php_script = 'DQ_dispo.php';
|
||||||
|
|
||||||
|
require_once("dbconnect_mysqli.php");
|
||||||
|
require_once("functions.php");
|
||||||
|
|
||||||
|
$filedate = date("Ymd");
|
||||||
|
$filetime = date("H:i:s");
|
||||||
|
$IP = getenv ("REMOTE_ADDR");
|
||||||
|
$BR = getenv ("HTTP_USER_AGENT");
|
||||||
|
|
||||||
|
$PHP_AUTH_USER=$_SERVER['PHP_AUTH_USER'];
|
||||||
|
$PHP_AUTH_PW=$_SERVER['PHP_AUTH_PW'];
|
||||||
|
if (isset($_GET["lead_id"])) {$lead_id=$_GET["lead_id"];}
|
||||||
|
elseif (isset($_POST["lead_id"])) {$lead_id=$_POST["lead_id"];}
|
||||||
|
if (isset($_GET["campaign_id"])) {$campaign_id=$_GET["campaign_id"];}
|
||||||
|
elseif (isset($_POST["campaign_id"])) {$campaign_id=$_POST["campaign_id"];}
|
||||||
|
if (isset($_GET["dispo"])) {$dispo=$_GET["dispo"];}
|
||||||
|
elseif (isset($_POST["dispo"])) {$dispo=$_POST["dispo"];}
|
||||||
|
if (isset($_GET["user"])) {$user=$_GET["user"];}
|
||||||
|
elseif (isset($_POST["user"])) {$user=$_POST["user"];}
|
||||||
|
if (isset($_GET["pass"])) {$pass=$_GET["pass"];}
|
||||||
|
elseif (isset($_POST["pass"])) {$pass=$_POST["pass"];}
|
||||||
|
if (isset($_GET["DB"])) {$DB=$_GET["DB"];}
|
||||||
|
elseif (isset($_POST["DB"])) {$DB=$_POST["DB"];}
|
||||||
|
if (isset($_GET["log_to_file"])) {$log_to_file=$_GET["log_to_file"];}
|
||||||
|
elseif (isset($_POST["log_to_file"])) {$log_to_file=$_POST["log_to_file"];}
|
||||||
|
|
||||||
|
$DB=preg_replace("/[^0-9a-zA-Z]/","",$DB);
|
||||||
|
|
||||||
|
#$DB = '1'; # DEBUG override
|
||||||
|
$US = '_';
|
||||||
|
$TD = '---';
|
||||||
|
$STARTtime = date("U");
|
||||||
|
$NOW_TIME = date("Y-m-d H:i:s");
|
||||||
|
$k=0;
|
||||||
|
$DQupdates=0;
|
||||||
|
$DQupdate_notes='';
|
||||||
|
$DQgoals_reached=0;
|
||||||
|
|
||||||
|
# filter variables
|
||||||
|
$user=preg_replace("/\'|\"|\\\\|;| /","",$user);
|
||||||
|
$pass=preg_replace("/\'|\"|\\\\|;| /","",$pass);
|
||||||
|
|
||||||
|
# if options file exists, use the override values for the above variables
|
||||||
|
# see the options-example.php file for more information
|
||||||
|
if (file_exists('options.php'))
|
||||||
|
{
|
||||||
|
require_once('options.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
header ("Content-type: text/html; charset=utf-8");
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
##### START SYSTEM_SETTINGS AND USER LANGUAGE LOOKUP #####
|
||||||
|
$stmt = "SELECT use_non_latin,enable_languages,language_method,allow_web_debug,demographic_quotas 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];
|
||||||
|
$SSallow_web_debug = $row[3];
|
||||||
|
$SSdemographic_quotas = $row[4];
|
||||||
|
}
|
||||||
|
if ($SSallow_web_debug < 1) {$DB=0;}
|
||||||
|
|
||||||
|
if ($SSdemographic_quotas < 1)
|
||||||
|
{
|
||||||
|
echo "demographic_quotas is disabled on this system: $SSdemographic_quotas \n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$VUselected_language = '';
|
||||||
|
$stmt="SELECT selected_language from vicidial_users where user='$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];
|
||||||
|
}
|
||||||
|
##### END SETTINGS LOOKUP #####
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
$lead_id = preg_replace('/[^_0-9]/', '', $lead_id);
|
||||||
|
$log_to_file = preg_replace('/[^-_0-9a-zA-Z]/', '', $log_to_file);
|
||||||
|
|
||||||
|
if ($non_latin < 1)
|
||||||
|
{
|
||||||
|
$user=preg_replace("/[^-_0-9a-zA-Z]/","",$user);
|
||||||
|
$pass=preg_replace("/[^-\.\+\/\=_0-9a-zA-Z]/","",$pass);
|
||||||
|
$dispo = preg_replace('/[^-_0-9a-zA-Z]/', '', $dispo);
|
||||||
|
$campaign_id = preg_replace('/[^-_0-9a-zA-Z]/', '', $campaign_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$user = preg_replace('/[^-_0-9\p{L}]/u','',$user);
|
||||||
|
$pass = preg_replace('/[^-\.\+\/\=_0-9\p{L}]/u','',$pass);
|
||||||
|
$dispo = preg_replace('/[^-_0-9\p{L}]/u', '', $dispo);
|
||||||
|
$campaign_id = preg_replace('/[^-_0-9\p{L}]/u', '', $campaign_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($DB>0) {echo "$lead_id|$dispo|$campaign_id|$user|$pass|$DB|$log_to_file|\n";}
|
||||||
|
|
||||||
|
if (strlen($dispo) < 1)
|
||||||
|
{
|
||||||
|
echo "no dispo value given, exiting: $dispo \n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
if (strlen($campaign_id) < 1)
|
||||||
|
{
|
||||||
|
echo "no campaign_id value given, exiting: $campaign_id \n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
if (strlen($lead_id) < 1)
|
||||||
|
{
|
||||||
|
echo "no lead_id value given, exiting: $lead_id \n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# gather campaign details from campaign_id, and what the Demographic Quotas settings are
|
||||||
|
$DQcontainer='';
|
||||||
|
$stmt="SELECT demographic_quotas_container,demographic_quotas_rerank from vicidial_campaigns where campaign_id='$campaign_id' and active='Y' and demographic_quotas IN('ENABLED','COMPLETE');";
|
||||||
|
if ($DB) {echo "|$stmt|\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$DQcamprows = mysqli_num_rows($rslt);
|
||||||
|
if ($DQcamprows > 0)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$DQcontainer = $row[0];
|
||||||
|
$demographic_quotas_rerank = $row[1];
|
||||||
|
}
|
||||||
|
if (strlen($DQcontainer) < 1)
|
||||||
|
{
|
||||||
|
echo _QXZ("demographic_quotas not enabled on campaign:")." |$campaign_id| \n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$DQcontainer_entry='';
|
||||||
|
$stmt="SELECT container_entry from vicidial_settings_containers where container_id='$DQcontainer';";
|
||||||
|
if ($DB) {echo "|$stmt|\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$DQcontrows = mysqli_num_rows($rslt);
|
||||||
|
if ($DQcontrows > 0)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$DQcontainer_entry = $row[0];
|
||||||
|
}
|
||||||
|
if (strlen($DQcontainer_entry) < 10)
|
||||||
|
{
|
||||||
|
echo _QXZ("demographic_quotas container is invalid:")." |$DQcontainer| \n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($non_latin < 1)
|
||||||
|
{
|
||||||
|
$user=preg_replace("/[^-_0-9a-zA-Z]/","",$user);
|
||||||
|
# $pass=preg_replace("/[^-_0-9a-zA-Z]/","",$pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match("/NOAGENTURL/",$user))
|
||||||
|
{
|
||||||
|
$PADlead_id = sprintf("%010s", $lead_id);
|
||||||
|
if ( (strlen($pass) > 15) and (preg_match("/$PADlead_id$/",$pass)) )
|
||||||
|
{
|
||||||
|
$four_hours_ago = date("Y-m-d H:i:s", mktime(date("H")-4,date("i"),date("s"),date("m"),date("d"),date("Y")));
|
||||||
|
|
||||||
|
$stmt="SELECT count(*) from vicidial_log_extended where caller_code='$pass' and call_date > \"$four_hours_ago\";";
|
||||||
|
if ($DB) {echo "|$stmt|\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$authlive=$row[0];
|
||||||
|
$auth=$row[0];
|
||||||
|
if ($authlive < 1)
|
||||||
|
{
|
||||||
|
echo _QXZ("Call Not Found:")." 2|$user|$pass|$authlive|\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo _QXZ("Invalid Call ID:")." 1|$user|$pass|$PADlead_id|\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$auth=0;
|
||||||
|
$auth_message = user_authorization($user,$pass,'',0,0,0,0,'dispo_move_list');
|
||||||
|
if ($auth_message == 'GOOD')
|
||||||
|
{$auth=1;}
|
||||||
|
|
||||||
|
$stmt="SELECT count(*) from vicidial_live_agents where user='$user';";
|
||||||
|
if ($DB) {echo "|$stmt|\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$authlive=$row[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (strlen($user)<2) or (strlen($pass)<2) or ($auth==0) or ($authlive==0))
|
||||||
|
{
|
||||||
|
echo _QXZ("Invalid Username/Password:")." |$user|$pass|$auth|$authlive|$auth_message|\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen($lead_id) > 0)
|
||||||
|
{
|
||||||
|
# go through DQ container, gather finished_statuses
|
||||||
|
$DQcontainer_entry = preg_replace("/\r|\t|\'|\"/",'',$DQcontainer_entry);
|
||||||
|
$DQ_settings = explode("\n",$DQcontainer_entry);
|
||||||
|
$DQ_settings_ct = count($DQ_settings);
|
||||||
|
$finished_statuses='';
|
||||||
|
$finished_statusesSQL='';
|
||||||
|
$sea=0;
|
||||||
|
while ($DQ_settings_ct >= $sea)
|
||||||
|
{
|
||||||
|
if (preg_match("/^finished_statuses=>|^finished_statuses => /",$DQ_settings[$sea]))
|
||||||
|
{
|
||||||
|
$finished_statuses = $DQ_settings[$sea];
|
||||||
|
$finished_statuses = preg_replace("/^finished_statuses=>|^finished_statuses => /i",'',$finished_statuses);
|
||||||
|
$finished_statusesSQL = preg_replace("/,/","','",$finished_statuses);
|
||||||
|
$finished_statusesSQL = "'$finished_statusesSQL'";
|
||||||
|
if ($DB) {print "DEBUG finished_statuses defined: |$finished_statuses|$finished_statusesSQL| \n";}
|
||||||
|
}
|
||||||
|
$sea++;
|
||||||
|
}
|
||||||
|
if (strlen($finished_statuses) < 1)
|
||||||
|
{
|
||||||
|
echo _QXZ("No finished_statuses defined in container:")." |$DQcontainer|\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match("/'$dispo'/",$finished_statusesSQL))
|
||||||
|
{
|
||||||
|
if ($DB) {print "DEBUG finished_statuses match with dispo: |$dispo|$finished_statusesSQL| \n";}
|
||||||
|
|
||||||
|
# confirm lead_id exists in the system, and gather lead field values for demographics
|
||||||
|
$stmt="SELECT rank,vendor_lead_code,source_id,title,first_name,middle_initial,last_name,address1,address2,address3,city,state,province,postal_code,country_code,gender,date_of_birth,alt_phone,email,security_phrase,owner,list_id from vicidial_list where lead_id='$lead_id' limit 1;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$VLrows = mysqli_num_rows($rslt);
|
||||||
|
if ($DB) {echo "$VLrows|$stmt|\n";}
|
||||||
|
if ($VLrows > 0)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$DQfields = array('rank','vendor_lead_code','source_id','title','first_name','middle_initial','last_name','address1','address2','address3','city','state','province','postal_code','country_code','gender','date_of_birth','alt_phone','email','security_phrase','owner');
|
||||||
|
$DQfield_values = array("$row[0]","$row[1]","$row[2]","$row[3]","$row[4]","$row[5]","$row[6]","$row[7]","$row[8]","$row[9]","$row[10]","$row[11]","$row[12]","$row[13]","$row[14]","$row[15]","$row[16]","$row[17]","$row[18]","$row[19]","$row[20]");
|
||||||
|
$last_list_id = $row[21];
|
||||||
|
|
||||||
|
$DQc=0;
|
||||||
|
while ($DQc <= 20)
|
||||||
|
{
|
||||||
|
$stmt="SELECT quota_goal,quota_count,quota_status from vicidial_demographic_quotas_goals where campaign_id='$campaign_id' and demographic_quotas_container='$DQcontainer' and quota_field='$DQfields[$DQc]' and quota_value='$DQfield_values[$DQc]' and quota_status!='ARCHIVE' limit 1;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$VDQGrows = mysqli_num_rows($rslt);
|
||||||
|
if ($DB) {echo "$VDQGrows|$stmt|\n";}
|
||||||
|
if ($VDQGrows > 0)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$quota_goal = $row[0];
|
||||||
|
$quota_count = $row[1];
|
||||||
|
$quota_status = $row[2];
|
||||||
|
$new_quota_count = ($quota_count + 1);
|
||||||
|
if ($DB) {print "DEBUG DQ field value match: |$DQfields[$DQc]|$DQfield_values[$DQc]| |$quota_goal|$quota_count|$quota_status| \n";}
|
||||||
|
|
||||||
|
if ($new_quota_count == $quota_goal)
|
||||||
|
{
|
||||||
|
$DQgoals_reached++;
|
||||||
|
if ($DB) {print "DEBUG DQ goal reached: |$new_quota_count == $quota_goal| \n";}
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="UPDATE vicidial_demographic_quotas_goals SET quota_count=(quota_count+1),last_lead_id='$lead_id',last_list_id='$last_list_id',last_call_date=NOW(),last_status='$dispo' where campaign_id='$campaign_id' and demographic_quotas_container='$DQcontainer' and quota_field='$DQfields[$DQc]' and quota_value='$DQfield_values[$DQc]' and quota_status!='ARCHIVE' limit 1;";
|
||||||
|
if ($DB) {echo "$stmt\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$affected_rows = mysqli_affected_rows($link);
|
||||||
|
$DQupdates = ($DQupdates + $affected_rows);
|
||||||
|
$DQupdate_notes .= "$DQfields[$DQc] = $DQfield_values[$DQc] update $affected_rows|";
|
||||||
|
if ($DB) {print "DEBUG DQ quota goals updated: |$affected_rows|$last_list_id| \n";}
|
||||||
|
}
|
||||||
|
$DQc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo _QXZ("Lead ID not found in system:")." |$lead_id|$VLrows|\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($DQupdates > 0)
|
||||||
|
{
|
||||||
|
if ($DQgoals_reached > 0)
|
||||||
|
{
|
||||||
|
if ($demographic_quotas_rerank == 'HOUR')
|
||||||
|
{$demographic_quotas_rerank == 'NOW_HOUR';}
|
||||||
|
if ($demographic_quotas_rerank == 'NO')
|
||||||
|
{$demographic_quotas_rerank == 'NOW';}
|
||||||
|
# update campaign to force refresh of DQ leads if one of the goals reached
|
||||||
|
$stmt="UPDATE vicidial_campaigns SET demographic_quotas_rerank='$demographic_quotas_rerank' where campaign_id='$campaign_id' limit 1;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$affected_rows = mysqli_affected_rows($link);
|
||||||
|
if ($DB) {echo "$affected_rows|$stmt|\n";}
|
||||||
|
}
|
||||||
|
|
||||||
|
$SQL_log = "$DQupdate_notes";
|
||||||
|
$SQL_log = preg_replace('/;/','',$SQL_log);
|
||||||
|
$SQL_log = addslashes($SQL_log);
|
||||||
|
$stmt="INSERT INTO vicidial_api_log set user='$user',agent_user='$user',function='DQdispo',value='$lead_id',result='$DQupdates',result_reason='$lead_id',source='vdc',data='$SQL_log',api_date='$NOW_TIME',api_script='$api_script';";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
|
||||||
|
$MESSAGE = _QXZ("DONE: %1s DQ updates made, for lead_id %2s goals reached %3s",0,'',$DQupdates,$lead_id,$DQgoals_reached);
|
||||||
|
echo "$MESSAGE\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$MESSAGE = _QXZ("DONE: no match found for lead %1s",0,'',$lead_id);
|
||||||
|
echo "$MESSAGE\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$MESSAGE = _QXZ("DONE: lead_id %1s is not populated",0,'',$lead_id);
|
||||||
|
echo "$MESSAGE\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($log_to_file > 0)
|
||||||
|
{
|
||||||
|
$fp = fopen ("./DQ_dispo.txt", "w");
|
||||||
|
# fwrite ($fp, "$NOW_TIME|$k|$lead_id|$dispo|$user|$campaign_id|$DB|$log_to_file|$campaign_id|$MESSAGE|\n");
|
||||||
|
fwrite ($fp, "$NOW_TIME|\n");
|
||||||
|
fclose($fp);
|
||||||
|
}
|
||||||
@@ -0,0 +1,486 @@
|
|||||||
|
<?php
|
||||||
|
# AST_latency_gaps_report.php
|
||||||
|
#
|
||||||
|
# Copyright (C) 2023 Joe Johnson, Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGES
|
||||||
|
# 230430-1952 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
$startMS = microtime();
|
||||||
|
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
require("functions.php");
|
||||||
|
|
||||||
|
$report_name='Latency Gaps Report';
|
||||||
|
|
||||||
|
$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["query_date"])) {$query_date=$_GET["query_date"];}
|
||||||
|
elseif (isset($_POST["query_date"])) {$query_date=$_POST["query_date"];}
|
||||||
|
if (isset($_GET["query_date_D"])) {$query_date_D=$_GET["query_date_D"];}
|
||||||
|
elseif (isset($_POST["query_date_D"])) {$query_date_D=$_POST["query_date_D"];}
|
||||||
|
if (isset($_GET["query_date_T"])) {$query_date_T=$_GET["query_date_T"];}
|
||||||
|
elseif (isset($_POST["query_date_T"])) {$query_date_T=$_POST["query_date_T"];}
|
||||||
|
if (isset($_GET["file_download"])) {$file_download=$_GET["file_download"];}
|
||||||
|
elseif (isset($_POST["file_download"])) {$file_download=$_POST["file_download"];}
|
||||||
|
if (isset($_GET["lower_limit"])) {$lower_limit=$_GET["lower_limit"];}
|
||||||
|
elseif (isset($_POST["lower_limit"])) {$lower_limit=$_POST["lower_limit"];}
|
||||||
|
if (isset($_GET["upper_limit"])) {$upper_limit=$_GET["upper_limit"];}
|
||||||
|
elseif (isset($_POST["upper_limit"])) {$upper_limit=$_POST["upper_limit"];}
|
||||||
|
if (isset($_GET["DB"])) {$DB=$_GET["DB"];}
|
||||||
|
elseif (isset($_POST["DB"])) {$DB=$_POST["DB"];}
|
||||||
|
if (isset($_GET["submit"])) {$submit=$_GET["submit"];}
|
||||||
|
elseif (isset($_POST["submit"])) {$submit=$_POST["submit"];}
|
||||||
|
if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];}
|
||||||
|
elseif (isset($_POST["SUBMIT"])) {$SUBMIT=$_POST["SUBMIT"];}
|
||||||
|
if (isset($_GET["report_display_type"])) {$report_display_type=$_GET["report_display_type"];}
|
||||||
|
elseif (isset($_POST["report_display_type"])) {$report_display_type=$_POST["report_display_type"];}
|
||||||
|
|
||||||
|
$DB=preg_replace("/[^0-9a-zA-Z]/","",$DB);
|
||||||
|
|
||||||
|
$NOW_DATE = date("Y-m-d");
|
||||||
|
if (!isset($query_date)) {$query_date = $NOW_DATE;}
|
||||||
|
if (strlen($query_date_D) < 6) {$query_date_D = "00:00:00";}
|
||||||
|
if (strlen($query_date_T) < 6) {$query_date_T = "23:59:59";}
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
##### START SYSTEM_SETTINGS LOOKUP #####
|
||||||
|
$stmt = "SELECT use_non_latin,outbound_autodial_active,slave_db_server,reports_use_slave_db,enable_languages,language_method,allow_web_debug FROM system_settings;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
#if ($DB) {$MAIN.="$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];
|
||||||
|
$SSallow_web_debug = $row[6];
|
||||||
|
}
|
||||||
|
if ($SSallow_web_debug < 1) {$DB=0;}
|
||||||
|
##### END SETTINGS LOOKUP #####
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
$query_date = preg_replace('/[^- \:\_0-9a-zA-Z]/', '', $query_date);
|
||||||
|
$query_date_D = preg_replace('/[^- \:\_0-9a-zA-Z]/', '', $query_date_D);
|
||||||
|
$query_date_T = preg_replace('/[^- \:\_0-9a-zA-Z]/', '', $query_date_T);
|
||||||
|
$lower_limit = preg_replace('/[^-_0-9a-zA-Z]/', '', $lower_limit);
|
||||||
|
$upper_limit = preg_replace('/[^-_0-9a-zA-Z]/', '', $upper_limit);
|
||||||
|
$submit = preg_replace('/[^-_0-9a-zA-Z]/', '', $submit);
|
||||||
|
$SUBMIT = preg_replace('/[^-_0-9a-zA-Z]/', '', $SUBMIT);
|
||||||
|
$report_display_type = preg_replace('/[^-_0-9a-zA-Z]/', '', $report_display_type);
|
||||||
|
$file_download = preg_replace('/[^-_0-9a-zA-Z]/', '', $file_download);
|
||||||
|
|
||||||
|
if ($non_latin < 1)
|
||||||
|
{
|
||||||
|
$PHP_AUTH_USER = preg_replace('/[^-_0-9a-zA-Z]/', '', $PHP_AUTH_USER);
|
||||||
|
$PHP_AUTH_PW = preg_replace('/[^-_0-9a-zA-Z]/', '', $PHP_AUTH_PW);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$PHP_AUTH_USER = preg_replace('/[^-_0-9\p{L}]/u', '', $PHP_AUTH_USER);
|
||||||
|
$PHP_AUTH_PW = preg_replace('/[^-_0-9\p{L}]/u', '', $PHP_AUTH_PW);
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="SELECT selected_language,user_group 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];
|
||||||
|
$LOGuser_group = $row[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
$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')
|
||||||
|
{$auth=1;}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="SELECT allowed_campaigns,allowed_reports,admin_viewable_groups,admin_viewable_call_times from vicidial_user_groups where user_group='$LOGuser_group';";
|
||||||
|
if ($DB) {$HTML_text.="|$stmt|\n";}
|
||||||
|
$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_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')";
|
||||||
|
$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 "You are not allowed to view this report: |$PHP_AUTH_USER|$report_name|\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);
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="INSERT INTO vicidial_report_log set event_date=NOW(), user='$PHP_AUTH_USER', ip_address='$LOGip', report_name='$report_name', browser='$LOGbrowser', referer='$LOGhttp_referer', notes='$LOGserver_name:$LOGserver_port $LOGscript_name |$query_date, $end_date, $lower_limit, $upper_limit, $file_download|', url='$LOGfull_url', webserver='$webserver_id';";
|
||||||
|
if ($DB) {echo "|$stmt|\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$report_log_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");
|
||||||
|
$MAIN.="<!-- Using slave server $slave_db_server $db_source -->\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$HEADER.="<HTML>\n";
|
||||||
|
$HEADER.="<HEAD>\n";
|
||||||
|
$HEADER.="<STYLE type=\"text/css\">\n";
|
||||||
|
$HEADER.="<!--\n";
|
||||||
|
$HEADER.=" .green {color: white; background-color: green}\n";
|
||||||
|
$HEADER.=" .red {color: white; background-color: red}\n";
|
||||||
|
$HEADER.=" .blue {color: white; background-color: blue}\n";
|
||||||
|
$HEADER.=" .purple {color: white; background-color: purple}\n";
|
||||||
|
$HEADER.=" .small_standard { font-family: Arial, Helvetica, sans-serif; font-size: 8pt}\n";
|
||||||
|
$HEADER.=" .small_standard_bold { font-family: Arial, Helvetica, sans-serif; font-size: 8pt; font-weight: bold}\n";
|
||||||
|
$HEADER.="-->\n";
|
||||||
|
$HEADER.=" </STYLE>\n";
|
||||||
|
$HEADER.="<script language=\"JavaScript\" src=\"calendar_db.js\"></script>\n";
|
||||||
|
$HEADER.="<link rel=\"stylesheet\" href=\"calendar.css\">\n";
|
||||||
|
$HEADER.="<link rel=\"stylesheet\" href=\"horizontalbargraph.css\">\n";
|
||||||
|
$HEADER.="<link rel=\"stylesheet\" href=\"verticalbargraph.css\">\n";
|
||||||
|
$HEADER.="<script language=\"JavaScript\" src=\"wz_jsgraphics.js\"></script>\n";
|
||||||
|
$HEADER.="<script language=\"JavaScript\" src=\"line.js\"></script>\n";
|
||||||
|
$HEADER.="<script type=\"text/javascript\" src=\"dygraph.js\"></script>\n";
|
||||||
|
$HEADER.="<script type=\"text/javascript\" src=\"dygraph_vici.js\"></script>\n";
|
||||||
|
$HEADER.="<link rel=\"stylesheet\" type=\"text/css\" href=\"dygraph.css\" />\n";
|
||||||
|
$HEADER.="<link rel=\"stylesheet\" type=\"text/css\" href=\"dygraph_vici.css\" />\n";
|
||||||
|
|
||||||
|
$HEADER.="<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=utf-8\">\n";
|
||||||
|
$HEADER.="<TITLE>"._QXZ("$report_name")."</TITLE></HEAD><BODY BGCOLOR=WHITE marginheight=0 marginwidth=0 leftmargin=0 topmargin=0 onLoad=\"DrawGraph('---ALL---', '$query_date', '---ALL---', 'latency_gaps')\">\n";
|
||||||
|
|
||||||
|
$short_header=1;
|
||||||
|
|
||||||
|
$MAIN.="<TABLE CELLPADDING=4 CELLSPACING=0><TR><TD>";
|
||||||
|
$MAIN.="<FORM ACTION=\"$PHP_SELF\" METHOD=GET name=vicidial_report id=vicidial_report>\n";
|
||||||
|
$MAIN.="<TABLE BORDER=0 cellspacing=5 cellpadding=5><TR><TD VALIGN=TOP align=center>\n";
|
||||||
|
$MAIN.="<INPUT TYPE=HIDDEN NAME=DB VALUE=\"$DB\">\n";
|
||||||
|
$MAIN.=_QXZ("Date").":\n";
|
||||||
|
$MAIN.="<INPUT TYPE=TEXT NAME=query_date SIZE=10 MAXLENGTH=10 VALUE=\"$query_date\">";
|
||||||
|
$MAIN.="<script language=\"JavaScript\">\n";
|
||||||
|
$MAIN.="var o_cal = new tcal ({\n";
|
||||||
|
$MAIN.=" // form name\n";
|
||||||
|
$MAIN.=" 'formname': 'vicidial_report',\n";
|
||||||
|
$MAIN.=" // input name\n";
|
||||||
|
$MAIN.=" 'controlname': 'query_date'\n";
|
||||||
|
$MAIN.="});\n";
|
||||||
|
$MAIN.="o_cal.a_tpl.yearscroll = false;\n";
|
||||||
|
$MAIN.="// o_cal.a_tpl.weekstart = 1; // Monday week start\n";
|
||||||
|
$MAIN.="</script></tD>\n";
|
||||||
|
|
||||||
|
$MAIN.="<TD VALIGN=TOP align=center><INPUT TYPE=TEXT NAME=query_date_D SIZE=9 MAXLENGTH=8 VALUE=\"$query_date_D\">";
|
||||||
|
|
||||||
|
$MAIN.=" "._QXZ("to")." <INPUT TYPE=TEXT NAME=query_date_T SIZE=9 MAXLENGTH=8 VALUE=\"$query_date_T\">";
|
||||||
|
|
||||||
|
$MAIN.="</TD><TD VALIGN=middle align=center>\n";
|
||||||
|
$MAIN.=_QXZ("Display as").":";
|
||||||
|
$MAIN.="<select name='report_display_type'>";
|
||||||
|
if ($report_display_type) {$MAIN.="<option value='$report_display_type' selected>$report_display_type</option>";}
|
||||||
|
$MAIN.="<option value='TEXT'>"._QXZ("TEXT")."</option><option value='HTML'>"._QXZ("HTML")."</option></select></TD>";
|
||||||
|
$MAIN.="<TD VALIGN=TOP align=center><INPUT TYPE=submit NAME=SUBMIT VALUE='"._QXZ("SUBMIT")."'>\n";
|
||||||
|
$MAIN.="</TD></TR></TABLE>\n";
|
||||||
|
if ($SUBMIT && $query_date)
|
||||||
|
{
|
||||||
|
$distinct_users='|';
|
||||||
|
$distinct_users_ct=0;
|
||||||
|
$users_ary[0]='';
|
||||||
|
$users_ct_ary[0]=0;
|
||||||
|
$rpt_stmt="SELECT * from vicidial_latency_gaps where gap_date>='$query_date $query_date_D' and gap_date<='$query_date $query_date_T' order by user, gap_date asc";
|
||||||
|
$rpt_rslt=mysql_to_mysqli($rpt_stmt, $link);
|
||||||
|
$ASCII_text="<PRE><font size=2>\n";
|
||||||
|
$HTML_text="";
|
||||||
|
if ($DB) {$ASCII_text.=$rpt_stmt."\n";}
|
||||||
|
if (mysqli_num_rows($rpt_rslt)>0)
|
||||||
|
{
|
||||||
|
if (!$lower_limit) {$lower_limit=1;}
|
||||||
|
if ($lower_limit+999>=mysqli_num_rows($rpt_rslt)) {$upper_limit=($lower_limit+mysqli_num_rows($rpt_rslt)%1000)-1;} else {$upper_limit=$lower_limit+999;}
|
||||||
|
|
||||||
|
$ASCII_text.="--- "._QXZ("LATENCY GAP RECORDS FOR")." $query_date, $query_date_D "._QXZ("TO")." $query_date_T $server_rpt_string, "._QXZ("RECORDS")." #$lower_limit-$upper_limit <a href=\"$PHP_SELF?SUBMIT=$SUBMIT&DB=$DB&type=$type&query_date=$query_date&query_date_D=$query_date_D&query_date_T=$query_date_T&lower_limit=$lower_limit&upper_limit=$upper_limit&file_download=1\">["._QXZ("DOWNLOAD")."]</a>\n";
|
||||||
|
$lagged_rpt.="+----------------------+-----------------+---------------------+-----------+----------------------+----------------------+\n";
|
||||||
|
$lagged_rpt.="| "._QXZ("USER",20)." | "._QXZ("USER WEB IP",15)." | "._QXZ("GAP BEGIN",19)." | "._QXZ("GAP SEC",9)." | "._QXZ("LAST LOGIN",20)." | "._QXZ("GAP DETECTION TIME",20)." |\n";
|
||||||
|
$lagged_rpt.="+----------------------+-----------------+---------------------+-----------+----------------------+----------------------+\n";
|
||||||
|
|
||||||
|
$HTML_text.="<BR><BR><table border='0' cellpadding='0' cellspacing='2' width='1000'>";
|
||||||
|
$HTML_rpt.="<TR><TH colspan='9' class='small_standard_bold grey_graph_cell'>"._QXZ("LATENCY GAP RECORDS FOR")." $query_date, $query_date_D "._QXZ("TO")." $query_date_T $server_rpt_string, "._QXZ("RECORDS")." #$lower_limit-$upper_limit</TH><TD align='right' class='small_standard_bold grey_graph_cell'><a href=\"$PHP_SELF?SUBMIT=$SUBMIT&DB=$DB&type=$type&query_date=$query_date&query_date_D=$query_date_D&query_date_T=$query_date_T&lower_limit=$lower_limit&upper_limit=$upper_limit&file_download=1\">["._QXZ("DOWNLOAD")."]</a></td></TR>";
|
||||||
|
$HTML_rpt.="<TR><TH class='small_standard_bold grey_graph_cell' width='80'>"._QXZ("USER")."</TH><TH class='small_standard_bold grey_graph_cell' width='120'>"._QXZ("USER WEB IP")."</TH><TH class='small_standard_bold grey_graph_cell' width='100'>"._QXZ("GAP BEGIN")."</TH><TH class='small_standard_bold grey_graph_cell' width='80'>"._QXZ("GAP SEC")."</TH><TH class='small_standard_bold grey_graph_cell' width='80'>"._QXZ("LAST LOGIN")."</TH><TH class='small_standard_bold grey_graph_cell' width='60'>"._QXZ("GAP DETECTION TIME")."</TH></TR>";
|
||||||
|
|
||||||
|
$CSV_text="\""._QXZ("USER")."\",\""._QXZ("USER WEB IP")."\",\""._QXZ("GAP BEGIN")."\",\""._QXZ("GAP SEC")."\",\""._QXZ("LAST LOGIN")."\",\""._QXZ("GAP DETECTION TIME")."\"\n";
|
||||||
|
|
||||||
|
for ($i=1; $i<=mysqli_num_rows($rpt_rslt); $i++)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_array($rpt_rslt);
|
||||||
|
$temp_user=$row[user];
|
||||||
|
if ($i == '1')
|
||||||
|
{
|
||||||
|
$users_ary[$distinct_users_ct] = $temp_user;
|
||||||
|
$users_ct_ary[$distinct_users_ct]++;
|
||||||
|
$distinct_users .= "$temp_user|";
|
||||||
|
$distinct_users_ct++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!preg_match("/\|$temp_user\|/",$distinct_users))
|
||||||
|
{
|
||||||
|
$users_ary[$distinct_users_ct] = $temp_user;
|
||||||
|
$users_ct_ary[$distinct_users_ct]++;
|
||||||
|
$distinct_users .= "$temp_user|";
|
||||||
|
$distinct_users_ct++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$users_ct_ary[$distinct_users_ct]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$CSV_text.="\"$row[user]\",\"$row[user_ip]\",\"$row[gap_date]\",\"$row[gap_length]\",\"$row[last_login_date]\",\"$row[check_date]\"\n";
|
||||||
|
if ($i>=$lower_limit && $i<=$upper_limit)
|
||||||
|
{
|
||||||
|
if ($i%2==0) {$color_class="grey_graph_cell";} else {$color_class='white_graph_cell';}
|
||||||
|
|
||||||
|
$HTML_rpt.="<TR valign='top'><td class='small_standard_bold $color_class' width='80'>$row[user]</td><td class='small_standard_bold $color_class' width='120'>$row[user_ip]</td><td class='small_standard_bold $color_class' width='100'>$row[gap_date]</td><td class='small_standard_bold $color_class' width='80'>$row[last_login_date]</td><td class='small_standard_bold $color_class' width='80'>$row[check_date]</td></TR>";
|
||||||
|
|
||||||
|
$lagged_rpt.="| <a href=\"javascript:void(0)\" onClick=\"DrawGraph('$row[user]', '$query_date', '---ALL---', 'latency_gaps')\">".sprintf("%-21s", $row["user"])."</a>";
|
||||||
|
$lagged_rpt.="| ".sprintf("%-16s", $row["user_ip"]);
|
||||||
|
$lagged_rpt.="| ".sprintf("%-20s", $row["gap_date"]);
|
||||||
|
$lagged_rpt.="| ".sprintf("%-10s", $row["gap_length"]);
|
||||||
|
$lagged_rpt.="| ".sprintf("%-21s", $row["last_login_date"]);
|
||||||
|
$lagged_rpt.="| ".sprintf("%-21s", $row["check_date"]);
|
||||||
|
$lagged_rpt.="|\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$lagged_rpt.="+----------------------+-----------------+---------------------+-----------+----------------------+----------------------+\n";
|
||||||
|
|
||||||
|
$lagged_rpt_hf="";
|
||||||
|
$HTML_rpt_hf="<TR>";
|
||||||
|
$ll=$lower_limit-1000;
|
||||||
|
if ($ll<1 || ($lower_limit+1000)>=mysqli_num_rows($rpt_rslt)) {$HTML_colspan=6;} else {$HTML_colspan=3;}
|
||||||
|
|
||||||
|
if ($ll>=1)
|
||||||
|
{
|
||||||
|
$lagged_rpt_hf.="<a href=\"$PHP_SELF?SUBMIT=$SUBMIT&DB=$DB&report_display_type=$report_display_type&type=$type&query_date=$query_date&query_date_D=$query_date_D&query_date_T=$query_date_T&lower_limit=$ll\">[<<< "._QXZ("PREV 1000 records")."]</a>";
|
||||||
|
$HTML_rpt_hf.="<Td colspan='$HTML_colspan' class='small_standard_bold grey_graph_cell' align='left'><a href=\"$PHP_SELF?SUBMIT=$SUBMIT&DB=$DB&report_display_type=$report_display_type&type=$type&query_date=$query_date&query_date_D=$query_date_D&query_date_T=$query_date_T&lower_limit=$ll\">[<<< "._QXZ("PREV 1000 records")."]</a></TH>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$lagged_rpt_hf.=sprintf("%-23s", " ");
|
||||||
|
}
|
||||||
|
$lagged_rpt_hf.=sprintf("%-145s", " ");
|
||||||
|
if (($lower_limit+1000)<mysqli_num_rows($rpt_rslt))
|
||||||
|
{
|
||||||
|
if ($upper_limit+1000>=mysqli_num_rows($rpt_rslt)) {$max_limit=mysqli_num_rows($rpt_rslt)-$upper_limit;} else {$max_limit=1000;}
|
||||||
|
$lagged_rpt_hf.="<a href=\"$PHP_SELF?SUBMIT=$SUBMIT&DB=$DB&report_display_type=$report_display_type&type=$type&query_date=$query_date&query_date_D=$query_date_D&query_date_T=$query_date_T&lower_limit=".($lower_limit+1000)."\">["._QXZ("NEXT")." $max_limit "._QXZ("records")." >>>]</a>";
|
||||||
|
$HTML_rpt_hf.="<Td colspan='$HTML_colspan' class='small_standard_bold grey_graph_cell' align='right'><a href=\"$PHP_SELF?SUBMIT=$SUBMIT&DB=$DB&report_display_type=$report_display_type&type=$type&query_date=$query_date&query_date_D=$query_date_D&query_date_T=$query_date_T&lower_limit=".($lower_limit+1000)."\">["._QXZ("NEXT")." $max_limit "._QXZ("records")." >>>]</a></TH>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$lagged_rpt_hf.=sprintf("%23s", " ");
|
||||||
|
}
|
||||||
|
$HTML_rpt_hf.="</TR>";
|
||||||
|
$lagged_rpt_hf.="\n";
|
||||||
|
$temp_user_count_output = "Users: $distinct_users_ct\n";
|
||||||
|
$ASCII_text.=$temp_user_count_output;
|
||||||
|
$ASCII_text.=$lagged_rpt_hf.$lagged_rpt.$lagged_rpt_hf;
|
||||||
|
$HTML_text.=$HTML_rpt_hf.$HTML_rpt.$HTML_rpt_hf."</table>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$MAIN.="*** "._QXZ("NO RECORDS FOUND")." ***\n";
|
||||||
|
}
|
||||||
|
$ASCII_text.="</font></PRE>\n";
|
||||||
|
|
||||||
|
if ($report_display_type=="HTML")
|
||||||
|
{
|
||||||
|
$MAIN.=$HTML_text;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$MAIN.=$ASCII_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
$MAIN.="</form>\n";
|
||||||
|
|
||||||
|
$MAIN.="<table>\n";
|
||||||
|
$MAIN.="<tr><td>\n";
|
||||||
|
$MAIN.="</style>\n";
|
||||||
|
$MAIN.="<div class='loading_text' id='loading_please_wait' style=\"width:800px; height:400px; display:none;\">\n";
|
||||||
|
$MAIN.="<center>LOADING, PLEASE WAIT...</center> \n";
|
||||||
|
$MAIN.="</div>\n";
|
||||||
|
$MAIN.="<div id=\"chart_div\" class=\"chart\" style=\"width:800px; height:400px;\">\n";
|
||||||
|
$MAIN.="<div id='latency_graph_div' style=\"width:800px;height:400px\"></div>\n";
|
||||||
|
$MAIN.="</div>\n";
|
||||||
|
$MAIN.="</td>\n";
|
||||||
|
$MAIN.="<td align='left' valign='top'>\n";
|
||||||
|
$MAIN.="<div id='legend_div' class='dygraph-legend' style=\"width:200px;height:300px\"></div>\n";
|
||||||
|
$MAIN.="</TD>\n";
|
||||||
|
$MAIN.="</TR></TABLE>\n";
|
||||||
|
|
||||||
|
$MAIN.="</BODY></HTML>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($file_download>0)
|
||||||
|
{
|
||||||
|
$FILE_TIME = date("Ymd-His");
|
||||||
|
$CSVfilename = "AST_url_log_report_$US$FILE_TIME.csv";
|
||||||
|
$CSV_text=preg_replace('/ +\"/', '"', $CSV_text);
|
||||||
|
$CSV_text=preg_replace('/\" +/', '"', $CSV_text);
|
||||||
|
// We'll be outputting a TXT file
|
||||||
|
header('Content-type: application/octet-stream');
|
||||||
|
|
||||||
|
// It will be called LIST_101_20090209-121212.txt
|
||||||
|
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 "$CSV_text";
|
||||||
|
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo $HEADER;
|
||||||
|
require("admin_header.php");
|
||||||
|
echo $MAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
?>
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,464 @@
|
|||||||
|
<?php
|
||||||
|
# demographic_quotas_report.php
|
||||||
|
#
|
||||||
|
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGES
|
||||||
|
# 230515-0922 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
$startMS = microtime();
|
||||||
|
|
||||||
|
$report_name='Demographic Quotas Report';
|
||||||
|
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
require("functions.php");
|
||||||
|
|
||||||
|
$PHP_AUTH_USER=$_SERVER['PHP_AUTH_USER'];
|
||||||
|
$PHP_AUTH_PW=$_SERVER['PHP_AUTH_PW'];
|
||||||
|
$PHP_SELF=$_SERVER['PHP_SELF'];
|
||||||
|
$PHP_SELF = preg_replace('/\.php.*/i','.php',$PHP_SELF);
|
||||||
|
if (isset($_GET["DB"])) {$DB=$_GET["DB"];}
|
||||||
|
elseif (isset($_POST["DB"])) {$DB=$_POST["DB"];}
|
||||||
|
if (isset($_GET["group"])) {$group=$_GET["group"];}
|
||||||
|
elseif (isset($_POST["group"])) {$group=$_POST["group"];}
|
||||||
|
if (isset($_GET["submit"])) {$submit=$_GET["submit"];}
|
||||||
|
elseif (isset($_POST["submit"])) {$submit=$_POST["submit"];}
|
||||||
|
if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];}
|
||||||
|
elseif (isset($_POST["SUBMIT"])) {$SUBMIT=$_POST["SUBMIT"];}
|
||||||
|
|
||||||
|
$DB=preg_replace("/[^0-9a-zA-Z]/","",$DB);
|
||||||
|
|
||||||
|
$NOW_DATE = date("Y-m-d");
|
||||||
|
$NOW_TIME = date("Y-m-d H:i:s");
|
||||||
|
$STARTtime = date("U");
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
##### START SYSTEM_SETTINGS LOOKUP #####
|
||||||
|
$stmt = "SELECT use_non_latin,webroot_writable,outbound_autodial_active,user_territories_active,enable_languages,language_method,allow_shared_dial,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];
|
||||||
|
$webroot_writable = $row[1];
|
||||||
|
$SSoutbound_autodial_active = $row[2];
|
||||||
|
$user_territories_active = $row[3];
|
||||||
|
$SSenable_languages = $row[4];
|
||||||
|
$SSlanguage_method = $row[5];
|
||||||
|
$SSallow_shared_dial = $row[6];
|
||||||
|
$SSallow_web_debug = $row[7];
|
||||||
|
}
|
||||||
|
if ($SSallow_web_debug < 1) {$DB=0;}
|
||||||
|
##### END SETTINGS LOOKUP #####
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
$submit = preg_replace('/[^-_0-9a-zA-Z]/', '', $submit);
|
||||||
|
$SUBMIT = preg_replace('/[^-_0-9a-zA-Z]/', '', $SUBMIT);
|
||||||
|
|
||||||
|
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);
|
||||||
|
$group = preg_replace('/[^-_0-9a-zA-Z]/', '', $group);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
$group = preg_replace('/[^-_0-9\p{L}]/u', '', $group);
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="SELECT selected_language,user_group 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];
|
||||||
|
$LOGuser_group = $row[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
$auth=0;
|
||||||
|
$reports_auth=0;
|
||||||
|
$admin_auth=0;
|
||||||
|
$auth_message = user_authorization($PHP_AUTH_USER,$PHP_AUTH_PW,'',1,0);
|
||||||
|
if ($auth_message == 'GOOD')
|
||||||
|
{$auth=1;}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="SELECT modify_campaigns,user_group from vicidial_users where user='$PHP_AUTH_USER';";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$LOGmodify_campaigns = $row[0];
|
||||||
|
$LOGuser_group = $row[1];
|
||||||
|
|
||||||
|
if ($LOGmodify_campaigns < 1)
|
||||||
|
{
|
||||||
|
Header ("Content-type: text/html; charset=utf-8");
|
||||||
|
echo _QXZ("You do not have permissions for campaign debugging").": |$PHP_AUTH_USER|\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="SELECT allowed_campaigns,allowed_reports,admin_viewable_groups,admin_viewable_call_times from vicidial_user_groups where user_group='$LOGuser_group';";
|
||||||
|
if ($DB) {$HTML_text.="|$stmt|\n";}
|
||||||
|
$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_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')";
|
||||||
|
$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 "You are not allowed to view this report: |$PHP_AUTH_USER|$report_name|\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);
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="INSERT INTO vicidial_report_log set event_date=NOW(), user='$PHP_AUTH_USER', ip_address='$LOGip', report_name='$report_name', browser='$LOGbrowser', referer='$LOGhttp_referer', notes='$LOGserver_name:$LOGserver_port $LOGscript_name', url='$LOGfull_url', webserver='$webserver_id';";
|
||||||
|
if ($DB) {echo "|$stmt|\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$report_log_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");
|
||||||
|
$MAIN.="<!-- Using slave server $slave_db_server $db_source -->\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="select campaign_id,campaign_name from vicidial_campaigns order by campaign_id;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
if ($DB) {echo "$stmt\n";}
|
||||||
|
$campaigns_to_print = mysqli_num_rows($rslt);
|
||||||
|
$i=0;
|
||||||
|
while ($i < $campaigns_to_print)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$campaign_id[$i] =$row[0];
|
||||||
|
$campaign_name[$i] =$row[1];
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$NWB = "<IMG SRC=\"help.png\" onClick=\"FillAndShowHelpDiv(event, '";
|
||||||
|
$NWE = "')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP>";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<STYLE type="text/css">
|
||||||
|
<!--
|
||||||
|
.green {color: white; background-color: green}
|
||||||
|
.red {color: white; background-color: red}
|
||||||
|
.blue {color: white; background-color: blue}
|
||||||
|
.purple {color: white; background-color: purple}
|
||||||
|
-->
|
||||||
|
</STYLE>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
echo "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=utf-8\">\n";
|
||||||
|
echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"vicidial_stylesheet.php\">\n";
|
||||||
|
echo "<script language=\"JavaScript\" src=\"help.js\"></script>\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;
|
||||||
|
|
||||||
|
require("admin_header.php");
|
||||||
|
|
||||||
|
echo "<b>"._QXZ("$report_name")."</b> $NWB#DQreport$NWE\n";
|
||||||
|
|
||||||
|
echo "<TABLE CELLPADDING=4 CELLSPACING=0><TR><TD>";
|
||||||
|
echo "<FORM ACTION=\"$PHP_SELF\" METHOD=GET>\n";
|
||||||
|
echo "<SELECT SIZE=1 NAME=group>\n";
|
||||||
|
$o=0;
|
||||||
|
while ($campaigns_to_print > $o)
|
||||||
|
{
|
||||||
|
if ($campaign_id[$o] == $group) {echo "<option selected value=\"$campaign_id[$o]\">$campaign_id[$o] - $campaign_name[$o]</option>\n";}
|
||||||
|
else {echo "<option value=\"$campaign_id[$o]\">$campaign_id[$o] - $campaign_name[$o]</option>\n";}
|
||||||
|
$o++;
|
||||||
|
}
|
||||||
|
echo "</SELECT>\n";
|
||||||
|
echo "<INPUT TYPE=SUBMIT NAME=SUBMIT VALUE='"._QXZ("SUBMIT")."'>\n";
|
||||||
|
echo " <a href=\"./admin.php?ADD=31&campaign_id=$group\">"._QXZ("MODIFY")."</a> | <a href=\"./campaign_debug.php?group=$group\">"._QXZ("DQ Debug")."</a>\n";
|
||||||
|
echo "</FORM>\n\n";
|
||||||
|
|
||||||
|
echo "<PRE><FONT SIZE=2>\n\n";
|
||||||
|
|
||||||
|
|
||||||
|
if (!$group)
|
||||||
|
{
|
||||||
|
echo "\n\n";
|
||||||
|
echo _QXZ("PLEASE SELECT A CAMPAIGN ABOVE AND CLICK SUBMIT")."\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$stmt="select count(*) from vicidial_hopper where campaign_id='" . mysqli_real_escape_string($link, $group) . "';";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
if ($DB) {echo "$stmt\n";}
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$TOTALcalls = sprintf("%10s", $row[0]);
|
||||||
|
|
||||||
|
|
||||||
|
echo _QXZ("Report run time").": $NOW_TIME\n</PRE>";
|
||||||
|
|
||||||
|
|
||||||
|
$campaign_activeSTATUS = "<font color=red><b>"._QXZ("INACTIVE")."</b></font>";
|
||||||
|
$stmt="select demographic_quotas,demographic_quotas_container,demographic_quotas_rerank,demographic_quotas_list_resets,campaign_logindate,campaign_calldate,campaign_name,active,dial_statuses,hopper_level,demographic_quotas_last_rerank from vicidial_campaigns where campaign_id='" . mysqli_real_escape_string($link, $group) . "';";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$camp_ct = mysqli_num_rows($rslt);
|
||||||
|
if ($DB) {echo "$camp_ct|$stmt|\n";}
|
||||||
|
if ($camp_ct > 0)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$demographic_quotas = $row[0];
|
||||||
|
$demographic_quotas_container = $row[1];
|
||||||
|
$demographic_quotas_rerank = $row[2];
|
||||||
|
$demographic_quotas_list_resets = $row[3];
|
||||||
|
$campaign_logindate = $row[4];
|
||||||
|
$campaign_calldate = $row[5];
|
||||||
|
$campaign_name = $row[6];
|
||||||
|
$campaign_active = $row[7];
|
||||||
|
$dial_statuses = $row[8];
|
||||||
|
$hopper_level = $row[9];
|
||||||
|
$demographic_quotas_last_rerank = $row[10];
|
||||||
|
if ($campaign_active == 'Y')
|
||||||
|
{$campaign_activeSTATUS = "<font color=green><b>"._QXZ("ACTIVE")."</b></font>";}
|
||||||
|
}
|
||||||
|
|
||||||
|
$dialable_leads=0;
|
||||||
|
$calls_today=0;
|
||||||
|
$calls_hour=0;
|
||||||
|
$calls_fivemin=0;
|
||||||
|
$stmt="select dialable_leads,calls_today,calls_hour,calls_fivemin from vicidial_campaign_stats where campaign_id='" . mysqli_real_escape_string($link, $group) . "';";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$camp_ct = mysqli_num_rows($rslt);
|
||||||
|
if ($DB) {echo "$camp_ct|$stmt|\n";}
|
||||||
|
if ($camp_ct > 0)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$dialable_leads = $row[0];
|
||||||
|
$calls_today = $row[1];
|
||||||
|
$calls_hour = $row[2];
|
||||||
|
$calls_fivemin = $row[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($demographic_quotas == 'INVALID')
|
||||||
|
{$DQdebug = " <font color=red><b>"._QXZ("DQ configuration invalid")."<b></font>";}
|
||||||
|
if ($demographic_quotas == 'COMPLETE')
|
||||||
|
{$DQdebug = " <b>"._QXZ("DQ goals have been met")."<b>$DQdebug";}
|
||||||
|
|
||||||
|
echo "<table width=800 border=0 cellspacing=2 cellpadding=0> <tr bgcolor='#E6E6E6'><td>"._QXZ("Campaign").": </td><td>$group - $campaign_name $campaign_activeSTATUS</td></tr>\n";
|
||||||
|
echo "<tr bgcolor='#E6E6E6'><td>"._QXZ("Total leads in hopper right now").": </td><td>$TOTALcalls <i>"._QXZ("level").": $hopper_level</i> "._QXZ("dialable").": $dialable_leads</td></tr>\n";
|
||||||
|
echo "<tr bgcolor='#E6E6E6'><td>"._QXZ("Dial statuses").": </td><td>$dial_statuses</td></tr>\n";
|
||||||
|
echo "<tr bgcolor='#E6E6E6'><td>"._QXZ("Campaign last call date").": </td><td>$campaign_calldate <i>"._QXZ("calls today").": $calls_today ("._QXZ("calls, last hour / five-min").": $calls_hour / $calls_fivemin)</i></td></tr>\n";
|
||||||
|
echo "<tr bgcolor='#E6E6E6'><td>"._QXZ("Campaign last agent login date").": </td><td>$campaign_logindate</td></tr>\n";
|
||||||
|
echo "<tr bgcolor='#E6E6E6'><td>"._QXZ("Demographic Quotas").": </td><td>$demographic_quotas $DQdebug</td></tr>\n";
|
||||||
|
echo "<tr bgcolor='#E6E6E6'><td><a href=\"admin.php?ADD=392111111111&container_id=$demographic_quotas_container\">"._QXZ("Demographic Quotas Container")."</a>: </td><td>$demographic_quotas_container</td></tr>\n";
|
||||||
|
echo "<tr bgcolor='#E6E6E6'><td>"._QXZ("Demographic Quotas Re-Rank").": </td><td>$demographic_quotas_rerank <i>"._QXZ("last re-rank").": $demographic_quotas_last_rerank</i></td></tr>\n";
|
||||||
|
echo "<tr bgcolor='#E6E6E6'><td>"._QXZ("Demographic Quotas List Resets").": </td><td>$demographic_quotas_list_resets</td></tr>\n";
|
||||||
|
|
||||||
|
echo "</table>\n";
|
||||||
|
|
||||||
|
$DQgoals_content='';
|
||||||
|
$active_goals_count=0;
|
||||||
|
$filled_goals_count=0;
|
||||||
|
$stmt="SELECT quota_field,quota_field_order,quota_value,quota_value_order,quota_goal,quota_count,quota_leads_total,quota_leads_active,quota_status,quota_modify_date from vicidial_demographic_quotas_goals where campaign_id='" . mysqli_real_escape_string($link, $group) . "' and demographic_quotas_container='$demographic_quotas_container' and quota_status!='ARCHIVE' order by quota_field_order,quota_value_order limit 200;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
if ($DB) {echo "$stmt\n";}
|
||||||
|
$debugs_to_print = mysqli_num_rows($rslt);
|
||||||
|
$i=0;
|
||||||
|
while ($debugs_to_print > $i)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$quota_field = $row[0];
|
||||||
|
$quota_field_order = $row[1];
|
||||||
|
$quota_value = $row[2];
|
||||||
|
$quota_value_order = $row[3];
|
||||||
|
$quota_goal = $row[4];
|
||||||
|
$quota_count = $row[5];
|
||||||
|
$quota_leads_total = $row[6];
|
||||||
|
$quota_leads_active = $row[7];
|
||||||
|
$quota_status = $row[8];
|
||||||
|
$quota_modify_date = $row[9];
|
||||||
|
|
||||||
|
$i++;
|
||||||
|
|
||||||
|
$row_color='#CCCCCC';
|
||||||
|
if (preg_match("/ACTIVE/",$quota_status)) {$row_color='#33FF33'; $active_goals_count++;}
|
||||||
|
if (preg_match("/FILLED/",$quota_status)) {$row_color='#CC99CC'; $filled_goals_count++;}
|
||||||
|
$DQgoals_content .= "<tr bgcolor='$row_color'>";
|
||||||
|
$DQgoals_content .= "<td align=right>$i</td>\n";
|
||||||
|
$DQgoals_content .= "<td align=right>$quota_field</td>\n";
|
||||||
|
$DQgoals_content .= "<td align=right>$quota_field_order</td>\n";
|
||||||
|
$DQgoals_content .= "<td align=right>$quota_value</td>\n";
|
||||||
|
$DQgoals_content .= "<td align=right>$quota_value_order</td>\n";
|
||||||
|
$DQgoals_content .= "<td align=right>$quota_goal</td>\n";
|
||||||
|
$DQgoals_content .= "<td align=right>$quota_count</td>\n";
|
||||||
|
$DQgoals_content .= "<td align=right>$quota_leads_total</td>\n";
|
||||||
|
$DQgoals_content .= "<td align=right>$quota_leads_active</td>\n";
|
||||||
|
$DQgoals_content .= "<td align=right>$quota_status</td>\n";
|
||||||
|
$DQgoals_content .= "<td align=right>$quota_modify_date</td>\n";
|
||||||
|
$DQgoals_content .= "</tr>\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen($DQgoals_content) > 10)
|
||||||
|
{
|
||||||
|
$DQgoals_header = "<br><b>"._QXZ("Demographic Quota Goals")." - "._QXZ("Active").": $active_goals_count "._QXZ("Filled").": $filled_goals_count</b>.";
|
||||||
|
$DQgoals_header .= "<table width=900 border=0 cellspacing=2 cellpadding=0>";
|
||||||
|
$DQgoals_header .= "<tr bgcolor='#999999'>";
|
||||||
|
$DQgoals_header .= "<td align=right>#</td>\n";
|
||||||
|
$DQgoals_header .= "<td align=right> "._QXZ("Quota Field")." </td>\n";
|
||||||
|
$DQgoals_header .= "<td align=right> "._QXZ("Field Order")." </td>\n";
|
||||||
|
$DQgoals_header .= "<td align=right> "._QXZ("Value")." </td>\n";
|
||||||
|
$DQgoals_header .= "<td align=right> "._QXZ("Value Order")." </td>\n";
|
||||||
|
$DQgoals_header .= "<td align=right> "._QXZ("Goal")." </td>\n";
|
||||||
|
$DQgoals_header .= "<td align=right> "._QXZ("Count")." </td>\n";
|
||||||
|
$DQgoals_header .= "<td align=right> "._QXZ("Leads Total")." </td>\n";
|
||||||
|
$DQgoals_header .= "<td align=right> "._QXZ("Leads Active")." </td>\n";
|
||||||
|
$DQgoals_header .= "<td align=right> "._QXZ("Quota Status")." </td>\n";
|
||||||
|
$DQgoals_header .= "<td align=right> "._QXZ("Last Update")." </td>\n";
|
||||||
|
$DQgoals_header .= "</tr>\n";
|
||||||
|
echo "$DQgoals_header$DQgoals_content</table>\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo "<br><br><b>"._QXZ("No Goals found for this campaign")."</b>.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
echo "<br><br><font size=1>"._QXZ("report run time").": $TOTALrun</font>.";
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
</BODY></HTML>
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
/**
|
||||||
|
* Default styles for the dygraphs charting library.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.dygraph-legend {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 14px;
|
||||||
|
z-index: 10;
|
||||||
|
width: 250px; /* labelsDivWidth */
|
||||||
|
/*
|
||||||
|
dygraphs determines these based on the presence of chart labels.
|
||||||
|
It might make more sense to create a wrapper div around the chart proper.
|
||||||
|
top: 0px;
|
||||||
|
right: 2px;
|
||||||
|
*/
|
||||||
|
background: white;
|
||||||
|
line-height: normal;
|
||||||
|
text-align: left;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dygraph-legend[dir="rtl"] {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* styles for a solid line in the legend */
|
||||||
|
.dygraph-legend-line {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
bottom: .5ex;
|
||||||
|
padding-left: 1em;
|
||||||
|
height: 1px;
|
||||||
|
border-bottom-width: 2px;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
/* border-bottom-color is set based on the series color */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* styles for a dashed line in the legend, e.g. when strokePattern is set */
|
||||||
|
.dygraph-legend-dash {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
bottom: .5ex;
|
||||||
|
height: 1px;
|
||||||
|
border-bottom-width: 2px;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
/* border-bottom-color is set based on the series color */
|
||||||
|
/* margin-right is set based on the stroke pattern */
|
||||||
|
/* padding-left is set based on the stroke pattern */
|
||||||
|
}
|
||||||
|
|
||||||
|
.dygraph-roller {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This class is shared by all annotations, including those with icons */
|
||||||
|
.dygraph-annotation {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 10;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This class only applies to annotations without icons */
|
||||||
|
/* Old class name: .dygraphDefaultAnnotation */
|
||||||
|
.dygraph-default-annotation {
|
||||||
|
border: 1px solid black;
|
||||||
|
background-color: white;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dygraph-axis-label {
|
||||||
|
/* position: absolute; */
|
||||||
|
/* font-size: 14px; */
|
||||||
|
z-index: 10;
|
||||||
|
line-height: normal;
|
||||||
|
overflow: hidden;
|
||||||
|
color: black; /* replaces old axisLabelColor option */
|
||||||
|
}
|
||||||
|
|
||||||
|
.dygraph-axis-label-x {
|
||||||
|
}
|
||||||
|
|
||||||
|
.dygraph-axis-label-y {
|
||||||
|
}
|
||||||
|
|
||||||
|
.dygraph-axis-label-y2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
.dygraph-title {
|
||||||
|
font-weight: bold;
|
||||||
|
z-index: 10;
|
||||||
|
text-align: center;
|
||||||
|
/* font-size: based on titleHeight option */
|
||||||
|
}
|
||||||
|
|
||||||
|
.dygraph-xlabel {
|
||||||
|
text-align: center;
|
||||||
|
/* font-size: based on xLabelHeight option */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For y-axis label */
|
||||||
|
.dygraph-label-rotate-left {
|
||||||
|
text-align: center;
|
||||||
|
/* See http://caniuse.com/#feat=transforms2d */
|
||||||
|
transform: rotate(90deg);
|
||||||
|
-webkit-transform: rotate(90deg);
|
||||||
|
-moz-transform: rotate(90deg);
|
||||||
|
-o-transform: rotate(90deg);
|
||||||
|
-ms-transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For y2-axis label */
|
||||||
|
.dygraph-label-rotate-right {
|
||||||
|
text-align: center;
|
||||||
|
/* See http://caniuse.com/#feat=transforms2d */
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
-webkit-transform: rotate(-90deg);
|
||||||
|
-moz-transform: rotate(-90deg);
|
||||||
|
-o-transform: rotate(-90deg);
|
||||||
|
-ms-transform: rotate(-90deg);
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,356 @@
|
|||||||
|
<?php
|
||||||
|
# dygraph_functions.php
|
||||||
|
#
|
||||||
|
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# CHANGES
|
||||||
|
# 230508-0247 - First build
|
||||||
|
#
|
||||||
|
|
||||||
|
require("dbconnect_mysqli.php");
|
||||||
|
require("functions.php");
|
||||||
|
|
||||||
|
$php_script = 'dygraph_functions.php';
|
||||||
|
|
||||||
|
$PHP_AUTH_USER=$_SERVER['PHP_AUTH_USER'];
|
||||||
|
$PHP_AUTH_PW=$_SERVER['PHP_AUTH_PW'];
|
||||||
|
$PHP_SELF=$_SERVER['PHP_SELF'];
|
||||||
|
$PHP_SELF = preg_replace('/\.php.*/i','.php',$PHP_SELF);
|
||||||
|
if (isset($_GET["DB"])) {$DB=$_GET["DB"];}
|
||||||
|
elseif (isset($_POST["DB"])) {$DB=$_POST["DB"];}
|
||||||
|
if (isset($_GET["user"])) {$user=$_GET["user"];}
|
||||||
|
elseif (isset($_POST["user"])) {$user=$_POST["user"];}
|
||||||
|
if (isset($_GET["log_date"])) {$log_date=$_GET["log_date"];}
|
||||||
|
elseif (isset($_POST["log_date"])) {$log_date=$_POST["log_date"];}
|
||||||
|
if (isset($_GET["web_ip"])) {$web_ip=$_GET["web_ip"];}
|
||||||
|
elseif (isset($_POST["web_ip"])) {$web_ip=$_POST["web_ip"];}
|
||||||
|
if (isset($_GET["ACTION"])) {$ACTION=$_GET["ACTION"];}
|
||||||
|
elseif (isset($_POST["ACTION"])) {$ACTION=$_POST["ACTION"];}
|
||||||
|
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
##### START SYSTEM_SETTINGS LOOKUP #####
|
||||||
|
$VUselected_language = '';
|
||||||
|
$stmt = "SELECT use_non_latin,enable_languages,language_method,default_language,allow_web_debug FROM system_settings;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00XXX',$user,$server_ip,$session_name,$one_mysql_log);}
|
||||||
|
#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];
|
||||||
|
$SSdefault_language = $row[3];
|
||||||
|
$SSallow_web_debug = $row[4];
|
||||||
|
}
|
||||||
|
$VUselected_language = $SSdefault_language;
|
||||||
|
if ($SSallow_web_debug < 1) {$DB=0;}
|
||||||
|
##### END SETTINGS LOOKUP #####
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
$DB = preg_replace('/[^-_0-9a-zA-Z]/', '', $DB);
|
||||||
|
$log_date = preg_replace('/[^-_0-9a-zA-Z]/', '', $log_date);
|
||||||
|
$web_ip = preg_replace('/[^-:\._0-9a-zA-Z]/', '', $web_ip);
|
||||||
|
$ACTION = preg_replace('/[^-_0-9a-zA-Z]/', '', $ACTION);
|
||||||
|
|
||||||
|
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);
|
||||||
|
$user = preg_replace('/[^-_0-9a-zA-Z]/', '', $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);
|
||||||
|
$user = preg_replace('/[^-_0-9\p{L}]/u', '', $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="SELECT selected_language,user_group 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];
|
||||||
|
$LOGuser_group = $row[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
$auth=0;
|
||||||
|
$reports_auth=0;
|
||||||
|
$admin_auth=0;
|
||||||
|
$auth_message = user_authorization($PHP_AUTH_USER,$PHP_AUTH_PW,'',1,0);
|
||||||
|
if ($auth_message == 'GOOD')
|
||||||
|
{$auth=1;}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="SELECT modify_campaigns,user_group from vicidial_users where user='$PHP_AUTH_USER';";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$LOGmodify_campaigns = $row[0];
|
||||||
|
$LOGuser_group = $row[1];
|
||||||
|
|
||||||
|
$stmt="SELECT allowed_campaigns,allowed_reports,admin_viewable_groups,admin_viewable_call_times from vicidial_user_groups where user_group='$LOGuser_group';";
|
||||||
|
if ($DB) {$HTML_text.="|$stmt|\n";}
|
||||||
|
$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_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')";
|
||||||
|
$whereLOGallowed_campaignsSQL = "where campaign_id IN('$rawLOGallowed_campaignsSQL')";
|
||||||
|
}
|
||||||
|
$regexLOGallowed_campaigns = " $LOGallowed_campaigns ";
|
||||||
|
|
||||||
|
$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 ";
|
||||||
|
|
||||||
|
|
||||||
|
# if options file exists, use the override values for the above variables
|
||||||
|
# see the options-example.php file for more information
|
||||||
|
if (file_exists('options.php'))
|
||||||
|
{
|
||||||
|
require_once('options.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
header ("Content-type: text/html; charset=utf-8");
|
||||||
|
header ("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
|
||||||
|
header ("Pragma: no-cache"); // HTTP/1.0
|
||||||
|
|
||||||
|
if ($ACTION=="latency_by_user" && $user && $log_date && $web_ip)
|
||||||
|
{
|
||||||
|
if ($log_date!=date("Y-m-d")) {$latency_tbl="vicidial_agent_latency_log_archive";} else {$latency_tbl="vicidial_agent_latency_log";}
|
||||||
|
if (!preg_match('/\-\-\-ALL\-\-\-/', $web_ip))
|
||||||
|
{
|
||||||
|
$ip_clause="and web_ip='$web_ip'";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$ip_clause="";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preg_match('/\-\-\-ALL\-\-\-/', $user))
|
||||||
|
{
|
||||||
|
$user_clause="and user='$user'";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$user_clause="";
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="select log_date, latency, unix_timestamp(log_date) from ".$latency_tbl." where date(log_date)='$log_date' $LOGadmin_viewable_groupsSQL $user_clause $ip_clause order by log_date asc";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$output="Date/Time,Latency\n";
|
||||||
|
while ($row=mysqli_fetch_row($rslt))
|
||||||
|
{
|
||||||
|
if ($prev_ldate && $row[2]>($prev_ldate+1))
|
||||||
|
{
|
||||||
|
$dummy_ldate=date("Y-m-d H:i:s", floor(($row[2]+$prev_ldate)/2));
|
||||||
|
$output.="$dummy_ldate,\n";
|
||||||
|
}
|
||||||
|
$output.="$row[0],$row[1]\n";
|
||||||
|
$prev_ldate=$row[2];
|
||||||
|
}
|
||||||
|
echo $output;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ACTION=="all_agent_latency" && $log_date)
|
||||||
|
{
|
||||||
|
if ($log_date!=date("Y-m-d")) {$latency_tbl="vicidial_agent_latency_log_archive";} else {$latency_tbl="vicidial_agent_latency_log";}
|
||||||
|
|
||||||
|
$group_array=array();
|
||||||
|
$user_array=array();
|
||||||
|
|
||||||
|
$full_name_array=array();
|
||||||
|
$fn_stmt="select user, full_name from vicidial_users where user>0 $LOGadmin_viewable_groupsSQL";
|
||||||
|
$fn_rslt=mysql_to_mysqli($fn_stmt, $link);
|
||||||
|
while ($fn_row=mysqli_fetch_row($fn_rslt))
|
||||||
|
{
|
||||||
|
# $user_split=explode("_", $fn_row[1]);
|
||||||
|
$full_name_array["$fn_row[0]"]="$fn_row[0] - $fn_row[1]";
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="select log_date, latency, user, unix_timestamp(log_date) from ".$latency_tbl." where date(log_date)='$log_date' $LOGadmin_viewable_groupsSQL order by user, log_date asc";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$output="";
|
||||||
|
while ($row=mysqli_fetch_row($rslt))
|
||||||
|
{
|
||||||
|
$user_array["$row[2]"]++;
|
||||||
|
$group_array["$row[0]"]["$row[2]"]=$row[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
$output="Date/Time";
|
||||||
|
foreach ($user_array as $user => $lags)
|
||||||
|
{
|
||||||
|
$output.=",".$full_name_array["$user"];
|
||||||
|
}
|
||||||
|
$output.="\n";
|
||||||
|
|
||||||
|
foreach($group_array as $log_date => $agents)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($prev_ldate && strtotime($log_date)>($prev_ldate+1))
|
||||||
|
{
|
||||||
|
$dummy_ldate=date("Y-m-d H:i:s", floor((strtotime($log_date)+$prev_ldate)/2));
|
||||||
|
$output.="$dummy_ldate";
|
||||||
|
foreach ($user_array as $user => $lags)
|
||||||
|
{
|
||||||
|
$output.=",";
|
||||||
|
}
|
||||||
|
$output.="\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$output.="$log_date";
|
||||||
|
foreach ($user_array as $user => $lags)
|
||||||
|
{
|
||||||
|
$output.=",".$group_array["$log_date"]["$user"];
|
||||||
|
}
|
||||||
|
$output.="\n";
|
||||||
|
|
||||||
|
$prev_ldate=strtotime($log_date);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ACTION=="latency_gaps" && $log_date)
|
||||||
|
{
|
||||||
|
if ($archive_flag) {$latency_tbl="vicidial_latency_gaps_archive";} else {$latency_tbl="vicidial_latency_gaps";}
|
||||||
|
|
||||||
|
$group_array=array();
|
||||||
|
$user_array=array();
|
||||||
|
|
||||||
|
$full_name_array=array();
|
||||||
|
$fn_stmt="select user, full_name from vicidial_users where user>0 $LOGadmin_viewable_groupsSQL";
|
||||||
|
if($DB){echo $fn_stmt."<BR>\n";}
|
||||||
|
$fn_rslt=mysql_to_mysqli($fn_stmt, $link);
|
||||||
|
while ($fn_row=mysqli_fetch_row($fn_rslt))
|
||||||
|
{
|
||||||
|
# $user_split=explode("_", $fn_row[1]);
|
||||||
|
$full_name_array["$fn_row[0]"]="$fn_row[0] - $fn_row[1]";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($user && !preg_match('/\-\-\-ALL\-\-\-/', $user))
|
||||||
|
{
|
||||||
|
$user_SQL="and user='$user'";
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt="select gap_date, gap_length, user, unix_timestamp(gap_date) from ".$latency_tbl." where date(gap_date)='$log_date' $user_SQL $LOGadmin_viewable_groupsSQL order by gap_date, user asc";
|
||||||
|
if($DB){echo $stmt."<BR>\n";}
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$output="";
|
||||||
|
while ($row=mysqli_fetch_row($rslt))
|
||||||
|
{
|
||||||
|
$user_array["$row[2]"]++;
|
||||||
|
$group_array["$row[0]"]["$row[2]"]=$row[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
$output="Date/Time";
|
||||||
|
foreach ($user_array as $user => $lags)
|
||||||
|
{
|
||||||
|
$output.=",".$full_name_array["$user"];
|
||||||
|
}
|
||||||
|
$output.="\n";
|
||||||
|
|
||||||
|
foreach($group_array as $gap_date => $agents)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($prev_ldate && strtotime($gap_date)>($prev_ldate+1))
|
||||||
|
{
|
||||||
|
$dummy_ldate=date("Y-m-d H:i:s", floor((strtotime($gap_date)+$prev_ldate)/2));
|
||||||
|
$output.="$dummy_ldate";
|
||||||
|
foreach ($user_array as $user => $lags)
|
||||||
|
{
|
||||||
|
$output.=",";
|
||||||
|
}
|
||||||
|
$output.="\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$output.="$gap_date";
|
||||||
|
foreach ($user_array as $user => $lags)
|
||||||
|
{
|
||||||
|
$output.=",".$group_array["$gap_date"]["$user"];
|
||||||
|
}
|
||||||
|
$output.="\n";
|
||||||
|
|
||||||
|
$prev_ldate=strtotime($gap_date);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $output;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# version: 20230421085001
|
# version: 20230515164601
|
||||||
users-user User ID <QXZ>This field is where you put the users ID number, can be up to 20 digits in length, Must be at least 2 characters in length. We strongly recommend not reusing user accounts for different users, for reporting accuracy. To disable a user account, set the Active option to -N-.</QXZ>
|
users-user User ID <QXZ>This field is where you put the users ID number, can be up to 20 digits in length, Must be at least 2 characters in length. We strongly recommend not reusing user accounts for different users, for reporting accuracy. To disable a user account, set the Active option to -N-.</QXZ>
|
||||||
users-pass Password <QXZ>This field is where you put the users password. Must be at least 2 characters in length. Only letters and numbers are allowed in user passwords. A medium strength user password will be at least 10 characters in length, and a strong user password will be at least 20 characters in length and have letters as well as at least one number. It is recommended that you use a longer password if possible, stringing together several unrelated words with no spaces, and a number somewhere in the string. The maximum size of a password is 100 characters.</QXZ>
|
users-pass Password <QXZ>This field is where you put the users password. Must be at least 2 characters in length. Only letters and numbers are allowed in user passwords. A medium strength user password will be at least 10 characters in length, and a strong user password will be at least 20 characters in length and have letters as well as at least one number. It is recommended that you use a longer password if possible, stringing together several unrelated words with no spaces, and a number somewhere in the string. The maximum size of a password is 100 characters.</QXZ>
|
||||||
users-force_change_password Force Change Password <QXZ>If this option is set to Y then the user will be prompted to change their password the next time they log in to the administration webpage or the agent screen. Default is N.</QXZ>
|
users-force_change_password Force Change Password <QXZ>If this option is set to Y then the user will be prompted to change their password the next time they log in to the administration webpage or the agent screen. Default is N.</QXZ>
|
||||||
@@ -147,6 +147,10 @@ campaigns-manual_dial_hopper_check Manual Dial Hopper Check <QXZ>Setting this to
|
|||||||
campaigns-lead_filter_id Lead Filter <QXZ>This is a method of filtering your leads using a fragment of a SQL query. Use this feature with caution, it is easy to stop dialing accidentally with the slightest alteration to the SQL statement. Default is NONE.</QXZ>
|
campaigns-lead_filter_id Lead Filter <QXZ>This is a method of filtering your leads using a fragment of a SQL query. Use this feature with caution, it is easy to stop dialing accidentally with the slightest alteration to the SQL statement. Default is NONE.</QXZ>
|
||||||
campaigns-auto_active_list_new Auto Active List New <QXZ>This setting will automatically set an inactive list to active when it contains dialable NEW status leads and the campaign has less than this setting number of NEW status leads to be dialed. The order in which the next list is set to active is determined by the List Auto Active List Rank. This feature will only work if there has been calling on this campaign within the last hour. If no leads have been dialed within the last hour in this campaign, then this feature will not function. Default is DISABLED. This feature will only work if the Call Quota Lead Ranking feature is also enabled.</QXZ>
|
campaigns-auto_active_list_new Auto Active List New <QXZ>This setting will automatically set an inactive list to active when it contains dialable NEW status leads and the campaign has less than this setting number of NEW status leads to be dialed. The order in which the next list is set to active is determined by the List Auto Active List Rank. This feature will only work if there has been calling on this campaign within the last hour. If no leads have been dialed within the last hour in this campaign, then this feature will not function. Default is DISABLED. This feature will only work if the Call Quota Lead Ranking feature is also enabled.</QXZ>
|
||||||
campaigns-call_quota_lead_ranking Call Quota Lead Ranking <QXZ>This setting will allow you to choose a Settings Container which has the settings you want to use for Call Quota Lead Ranking. Default is DISABLED.</QXZ>
|
campaigns-call_quota_lead_ranking Call Quota Lead Ranking <QXZ>This setting will allow you to choose a Settings Container which has the settings you want to use for Call Quota Lead Ranking. Default is DISABLED.</QXZ>
|
||||||
|
campaigns-demographic_quotas Demographic Quotas <QXZ>This setting will enable or disable the Demographic Quotas feature for this campaign. For these features to work, you will need to select a value Container in the setting below. This feature is not related to Call Quota Lead Ranking and the two features should not be active on any single campaign at the same time. For more information, read the DEMOGRAPHIC_QUOTAS.txt document. Default is DISABLED.</QXZ>
|
||||||
|
campaigns-demographic_quotas_rerank Demographic Quotas Force Re-Rank <QXZ>By default, Demographic Quotas will only re-rank the leads in the campaign lists either when a quota has been reached or the campaign has run out of leads to dial. But this setting can force the system to re-rank the leads once using NOW, every hour using HOUR or every minute using the MINUTE setting. Keep in mind that depending on your system capacity and the number of leads in the campaign lists, this re-ranking process may lead to temporary system disruption, especially if it is run very frequently. When NOW is used, after the re-ranking process, the value of this setting will go back to NO. Default is NO.</QXZ>
|
||||||
|
campaigns-demographic_quotas_list_resets Demographic Quotas List Resets <QXZ>This optional setting can reset the active lists in this campaign if there are leads within the call time available and there are no more dialable leads in the campaign lists. We do not recommend activating this setting in most cases because it can result in customers being called an excessive number of times in a single day. Default is MANUAL.</QXZ>
|
||||||
|
campaigns-demographic_quotas_container Demographic Quotas Container <QXZ>This setting is where you select a DEMOGRAPHIC_QUOTAS container to be used for the Demographic Quota features to use for quota goals. For more information, read the DEMOGRAPHIC_QUOTAS.txt document. Default is DISABLED.</QXZ>
|
||||||
campaigns-call_count_limit Call Count Limit <QXZ>This enforces a limit on the number of call attempts for the leads dialed in this campaign. A lead may go over this limit slightly if Lead Recycling or Auto-Alt-Dialing is enabled. Default is 0 for no limit.</QXZ>
|
campaigns-call_count_limit Call Count Limit <QXZ>This enforces a limit on the number of call attempts for the leads dialed in this campaign. A lead may go over this limit slightly if Lead Recycling or Auto-Alt-Dialing is enabled. Default is 0 for no limit.</QXZ>
|
||||||
campaigns-call_count_target Call Count Target <QXZ>This option is only used for reporting purposes and has no effect on leads dialed. Default is 3.</QXZ>
|
campaigns-call_count_target Call Count Target <QXZ>This option is only used for reporting purposes and has no effect on leads dialed. Default is 3.</QXZ>
|
||||||
campaigns-daily_call_count_limit Daily Call Count Limit <QXZ>This feature, if enabled, will limit the number of times a lead can be called in a single day. Once a lead has reached this set limit, if the lead is selected to be dialed again, the called-since-last-reset flag on the lead will be changed to -Y- and the call will not be dialed. If you want to raise this daily limit during the day, you might need to reset your lists to be able to dial the leads that hit the previous limit earlier in the day. This feature may conflict with Auto-Alt-Dial features if they are enabled on a campaign. Default is 0 for disabled.</QXZ>
|
campaigns-daily_call_count_limit Daily Call Count Limit <QXZ>This feature, if enabled, will limit the number of times a lead can be called in a single day. Once a lead has reached this set limit, if the lead is selected to be dialed again, the called-since-last-reset flag on the lead will be changed to -Y- and the call will not be dialed. If you want to raise this daily limit during the day, you might need to reset your lists to be able to dial the leads that hit the previous limit earlier in the day. This feature may conflict with Auto-Alt-Dial features if they are enabled on a campaign. Default is 0 for disabled.</QXZ>
|
||||||
@@ -1141,6 +1145,7 @@ settings-user_new_lead_limit New Leads Per List Limit <QXZ>This setting enables
|
|||||||
settings-daily_call_count_limit Enable Daily Called Count Limits <QXZ>Enabling this setting will allow you to define a daily called count limit on a per campaign basis. Default is 0 for disabled.</QXZ>
|
settings-daily_call_count_limit Enable Daily Called Count Limits <QXZ>Enabling this setting will allow you to define a daily called count limit on a per campaign basis. Default is 0 for disabled.</QXZ>
|
||||||
settings-call_limit_24hour Enable 24-Hour Called Count Limits <QXZ>Enabling this setting will allow you to define a 24-hour called count limit on a per campaign basis. Default is 0 for disabled.</QXZ>
|
settings-call_limit_24hour Enable 24-Hour Called Count Limits <QXZ>Enabling this setting will allow you to define a 24-hour called count limit on a per campaign basis. Default is 0 for disabled.</QXZ>
|
||||||
settings-call_quota_lead_ranking Call Quota Lead Ranking <QXZ>This setting allows you to use the campaign setting for Call Quota Lead Ranking, which allows for a complex set of recycle dialing priorities for non-contact calls. Default is 0 for disabled.</QXZ>
|
settings-call_quota_lead_ranking Call Quota Lead Ranking <QXZ>This setting allows you to use the campaign setting for Call Quota Lead Ranking, which allows for a complex set of recycle dialing priorities for non-contact calls. Default is 0 for disabled.</QXZ>
|
||||||
|
settings-demographic_quotas Demographic Quotas <QXZ>This setting allows you to use the campaign Demographic Quotas feature, which allows for a dialing pattern that is based around a set of demographic types and values with associated quota goals. This feature is not related to Call Quota Lead Ranking and the two features should not be active on any single campaign at the same time. For more information, read the DEMOGRAPHIC_QUOTAS.txt document. Default is 0 for disabled.</QXZ>
|
||||||
settings-custom_fields_enabled Enable Custom List Fields <QXZ>This setting enables the custom list fields feature that allows for custom data fields to be defined in the administration web interface on a per-list basis and then have those fields available in a FORM tab to the agent in the agent web interface. Default is 0 for disabled.</QXZ>
|
settings-custom_fields_enabled Enable Custom List Fields <QXZ>This setting enables the custom list fields feature that allows for custom data fields to be defined in the administration web interface on a per-list basis and then have those fields available in a FORM tab to the agent in the agent web interface. Default is 0 for disabled.</QXZ>
|
||||||
settings-expanded_list_stats Enable Expanded List Stats <QXZ>This setting enables two additional columns to be displayed on most of the List status breakdown tables on the list modification and campaign modification pages. Penetration is defined as the percent of leads that are at or above the campaign Call Count Limit and-or the status is marked as Completed. Default is 1 for enabled.</QXZ>
|
settings-expanded_list_stats Enable Expanded List Stats <QXZ>This setting enables two additional columns to be displayed on most of the List status breakdown tables on the list modification and campaign modification pages. Penetration is defined as the percent of leads that are at or above the campaign Call Count Limit and-or the status is marked as Completed. Default is 1 for enabled.</QXZ>
|
||||||
settings-hide_inactive_lists Hide Inactive Lists <QXZ>This setting allows you to hide inactive lists from the Lists Listing page. Similar to the default Users feature, a link to display all lists will be available at the top of the listings section. Default is 0 for disabled.</QXZ>
|
settings-hide_inactive_lists Hide Inactive Lists <QXZ>This setting allows you to hide inactive lists from the Lists Listing page. Similar to the default Users feature, a link to display all lists will be available at the top of the listings section. Default is 0 for disabled.</QXZ>
|
||||||
@@ -1153,6 +1158,7 @@ settings-enable_drop_lists Enable Drop Lists <QXZ>This setting if enabled will m
|
|||||||
settings-source_id_display Admin Lead Source ID Display <QXZ>This setting will make the Source ID lead field show up in the Admin Modify Lead screen. Default is 0 for disabled.</QXZ>
|
settings-source_id_display Admin Lead Source ID Display <QXZ>This setting will make the Source ID lead field show up in the Admin Modify Lead screen. Default is 0 for disabled.</QXZ>
|
||||||
settings-allow_web_debug Allow Web DB Debug <QXZ>This option will allow the DB query string option to be used in most web pages on this system to show debug output. Default is 0 for disabled.</QXZ>
|
settings-allow_web_debug Allow Web DB Debug <QXZ>This option will allow the DB query string option to be used in most web pages on this system to show debug output. Default is 0 for disabled.</QXZ>
|
||||||
settings-agent_debug_logging Agent Screen Debug Logging <QXZ>This setting if enabled will log almost all agent screen mouse clicks and AJAX processes triggered by the agent screen. To enable for all agents, set this option to 1. To enable only for one agent on the system, set this option to the user that you want to log. Warning, this feature can log hundreds of entries per phone call, so use with caution. These agent debug records are deleted after 7 days. Default is 0 for disabled.</QXZ>
|
settings-agent_debug_logging Agent Screen Debug Logging <QXZ>This setting if enabled will log almost all agent screen mouse clicks and AJAX processes triggered by the agent screen. To enable for all agents, set this option to 1. To enable only for one agent on the system, set this option to the user that you want to log. Warning, this feature can log hundreds of entries per phone call, so use with caution. These agent debug records are deleted after 7 days. Default is 0 for disabled.</QXZ>
|
||||||
|
settings-log_latency_gaps Agent Latency Gaps Logging <QXZ>This setting if enabled will look for gaps in the latency logging for agents logged into the agent screen. This process can be configured in the AGENT_LATENCY_LOGGING Settings Container. For more information on this feature, read the AGENT_SCREEN_LOGGING.txt document. Default is 1 for enabled.</QXZ>
|
||||||
settings-agent_screen_timer Agent Screen Timer <QXZ>This will select the method of JavaScript timer to be used by the Agent Screen. The original method is setTimeout, which maintains the timer directly in JavaScript. An alternative method is setTimeoutAudioLoop, which uses the HTML -audio- tag with the -loop- option to play a 20Hz audio sound repeatedly to keep the browser tab active, this method will break Agent Browser Call Alerts if enabled. Another alternative is EventSource, which uses a script on the server to trigger the timer. You may want to use EventSource if your agents are using a Chromium-based web browser that has limitations on how native JavaScript timers work, although using this method may possibly cause issues if you have a poor network connection to the server or are on an older network or proxy that does not handle streaming web services well. Default is setTimeout</QXZ>
|
settings-agent_screen_timer Agent Screen Timer <QXZ>This will select the method of JavaScript timer to be used by the Agent Screen. The original method is setTimeout, which maintains the timer directly in JavaScript. An alternative method is setTimeoutAudioLoop, which uses the HTML -audio- tag with the -loop- option to play a 20Hz audio sound repeatedly to keep the browser tab active, this method will break Agent Browser Call Alerts if enabled. Another alternative is EventSource, which uses a script on the server to trigger the timer. You may want to use EventSource if your agents are using a Chromium-based web browser that has limitations on how native JavaScript timers work, although using this method may possibly cause issues if you have a poor network connection to the server or are on an older network or proxy that does not handle streaming web services well. Default is setTimeout</QXZ>
|
||||||
settings-enhanced_disconnect_logging Enhanced Disconnect Logging <QXZ>This setting, set to 1, enables logging of calls that get a CONGESTION signal with a cause code of 1, 19, 21, 34 or 38. Setting this to 2 will additionally log calls with cause codes of 18-CHANUNAVAIL and 102. Setting this to 3 will alternatively prevent some temporary error SIP messages on failed calls from sending the lead to ADC status. Instead, the status will be set as HUCXXX where XXX is the hangup_cause code. Eg. HUC18 for Cause 18 (SIP 408 Request timeout). Default is 0 for disabled.</QXZ>
|
settings-enhanced_disconnect_logging Enhanced Disconnect Logging <QXZ>This setting, set to 1, enables logging of calls that get a CONGESTION signal with a cause code of 1, 19, 21, 34 or 38. Setting this to 2 will additionally log calls with cause codes of 18-CHANUNAVAIL and 102. Setting this to 3 will alternatively prevent some temporary error SIP messages on failed calls from sending the lead to ADC status. Instead, the status will be set as HUCXXX where XXX is the hangup_cause code. Eg. HUC18 for Cause 18 (SIP 408 Request timeout). Default is 0 for disabled.</QXZ>
|
||||||
settings-sip_event_logging SIP Event Logging <QXZ>This setting will enable logging of SIP events on outbound phone calls for servers that are running patched versions of Asterisk 13 or higher. Default is 0 for disabled.</QXZ>
|
settings-sip_event_logging SIP Event Logging <QXZ>This setting will enable logging of SIP events on outbound phone calls for servers that are running patched versions of Asterisk 13 or higher. Default is 0 for disabled.</QXZ>
|
||||||
@@ -1349,6 +1355,7 @@ usergroup_login User Group Login Report <QXZ>This report includes information on
|
|||||||
agent_timeclock_detail User Timeclock Detail Report <QXZ>Pulls all timeclock records for agents meeting the selected parameters.</QXZ><BR><QXZ><U>TIME CLOCK</U> = Total amount of time agent spent logged in.</QXZ><BR><QXZ><U>TIME CLOCK PUNCHES</U> = A list of the punch-in and punch-out times for each agent. Punch-out times marked with an asterisk (*) denotes AUTOLOGOUT from timeclock.</QXZ>
|
agent_timeclock_detail User Timeclock Detail Report <QXZ>Pulls all timeclock records for agents meeting the selected parameters.</QXZ><BR><QXZ><U>TIME CLOCK</U> = Total amount of time agent spent logged in.</QXZ><BR><QXZ><U>TIME CLOCK PUNCHES</U> = A list of the punch-in and punch-out times for each agent. Punch-out times marked with an asterisk (*) denotes AUTOLOGOUT from timeclock.</QXZ>
|
||||||
campaign_status_list_report Campaign Status List Report <QXZ>This report is designed to show the breakdown by list_id of the calls and their statuses for all lists within a campaign for a set time period.</QXZ><BR><QXZ><U>DISPOSITION</U> = The distinct dispositions made for the list within the time frame specified.</QXZ><BR><QXZ><U>CALLS</U> = The number of calls ending with the disposition listed.</QXZ><BR><QXZ><U>DURATION</U> = Sum of the length of the calls ending with the disposition listed.</QXZ><BR><QXZ><U>HANDLE TIME</U> = Sum of the time the calls ending with the disposition listed were handled by an agent (<U>TALK</U> + <U>DEAD</U>).</QXZ><BR><BR><QXZ><U>TOTAL CALLS</U> = Number of calls placed to leads belonging to lists in this campaign within the time frame specified.</QXZ><BR><QXZ><U>STATUS FLAGS BREAKDOWN</U> = Breakdown of the total calls into status categories, including counts per category and percentage relative to the number of calls to leads in the list within the time frame specified.</QXZ>
|
campaign_status_list_report Campaign Status List Report <QXZ>This report is designed to show the breakdown by list_id of the calls and their statuses for all lists within a campaign for a set time period.</QXZ><BR><QXZ><U>DISPOSITION</U> = The distinct dispositions made for the list within the time frame specified.</QXZ><BR><QXZ><U>CALLS</U> = The number of calls ending with the disposition listed.</QXZ><BR><QXZ><U>DURATION</U> = Sum of the length of the calls ending with the disposition listed.</QXZ><BR><QXZ><U>HANDLE TIME</U> = Sum of the time the calls ending with the disposition listed were handled by an agent (<U>TALK</U> + <U>DEAD</U>).</QXZ><BR><BR><QXZ><U>TOTAL CALLS</U> = Number of calls placed to leads belonging to lists in this campaign within the time frame specified.</QXZ><BR><QXZ><U>STATUS FLAGS BREAKDOWN</U> = Breakdown of the total calls into status categories, including counts per category and percentage relative to the number of calls to leads in the list within the time frame specified.</QXZ>
|
||||||
campaign_debug Campaign Debug <QXZ>Shows campaign stats and debug output for a selected campaign.</QXZ>
|
campaign_debug Campaign Debug <QXZ>Shows campaign stats and debug output for a selected campaign.</QXZ>
|
||||||
|
DQreport Demographic Quotas Report <QXZ>This report will show the details of a single campaigns Demographic Quota settings, goals and other basic campaign calling information all on one screen. As quota goals are filled, the goal rows will change from a green to a purple background color. The numbers in this report are updated once per minute, but the -count- column can also be updated as agents disposition calls. It is possible for the -count- column to be higher than it really is if a call is dispositioned at the same time as the back-end process runs, but this will not impact the function of this feature and the numbers will be corrected within one minute. There are also links near the top of the report to go to the campaign modify page and the debug page to see more information on the last time the Demographic Quotas process ran.</QXZ>
|
||||||
user_logins_report User Logins Report <QXZ>This report will show the last login information for a user on the last several days that they logged into the system</QXZ>
|
user_logins_report User Logins Report <QXZ>This report will show the last login information for a user on the last several days that they logged into the system</QXZ>
|
||||||
user_latency_report User Latency Report <QXZ>This report will show the agent screen web connection latency information for agents that are currently or recently logged in to the agent screen.</QXZ>
|
user_latency_report User Latency Report <QXZ>This report will show the agent screen web connection latency information for agents that are currently or recently logged in to the agent screen.</QXZ>
|
||||||
carrier_log_report Carrier Log Report <QXZ>This report will show dial status breakdowns, SIP error reason breakdowns, and carrier log records for a selected date, and can be filtered by server.</QXZ>
|
carrier_log_report Carrier Log Report <QXZ>This report will show dial status breakdowns, SIP error reason breakdowns, and carrier log records for a selected date, and can be filtered by server.</QXZ>
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
# user_latency_report.php
|
# user_latency_report.php
|
||||||
#
|
#
|
||||||
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
|
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com>, Joe Johnson <joej@vicidial.com> LICENSE: AGPLv2
|
||||||
#
|
#
|
||||||
# CHANGES
|
# CHANGES
|
||||||
# 230421-0843 - First build
|
# 230421-0843 - First build
|
||||||
# 230422-0820 - Header fixes and no-records output
|
# 230422-0820 - Header fixes and no-records output
|
||||||
|
# 230508-0247 - Graph links added
|
||||||
#
|
#
|
||||||
|
|
||||||
$startMS = microtime();
|
$startMS = microtime();
|
||||||
@@ -283,6 +284,123 @@ $NWE = "')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP>";
|
|||||||
.purple {color: white; background-color: purple}
|
.purple {color: white; background-color: purple}
|
||||||
-->
|
-->
|
||||||
</STYLE>
|
</STYLE>
|
||||||
|
<script type="text/javascript" src="dygraph.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="dygraph.css" />
|
||||||
|
<script language="Javascript">
|
||||||
|
var RawGraphData="";
|
||||||
|
function DrawGraph(user, LogDate, IPAddress, API_action)
|
||||||
|
{
|
||||||
|
document.getElementById('loading_please_wait').style.display='block';
|
||||||
|
document.getElementById('chart_div').style.display='none';
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
var GraphQuery = "user=" + user + "&log_date=" + LogDate + "&web_ip=" + IPAddress + "&ACTION="+API_action;
|
||||||
|
xmlhttp.open('POST', 'dygraph_functions.php');
|
||||||
|
xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
|
||||||
|
xmlhttp.send(GraphQuery);
|
||||||
|
xmlhttp.onreadystatechange = function()
|
||||||
|
{
|
||||||
|
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
|
||||||
|
{
|
||||||
|
RawGraphData = xmlhttp.responseText;
|
||||||
|
|
||||||
|
if (API_action=="all_agent_latency")
|
||||||
|
{
|
||||||
|
var LSL_value=1;
|
||||||
|
var stacked=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var LSL_value=0;
|
||||||
|
var stacked=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var graphTitle='Latency';
|
||||||
|
if (!user.match("---ALL---"))
|
||||||
|
{
|
||||||
|
graphTitle+=' for agent '+user;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
graphTitle+=' for ALL agents';
|
||||||
|
}
|
||||||
|
|
||||||
|
graphTitle+=' for '+LogDate;
|
||||||
|
|
||||||
|
if (!IPAddress.match("---ALL---"))
|
||||||
|
{
|
||||||
|
graphTitle+=' on IP address '+IPAddress;
|
||||||
|
}
|
||||||
|
//var graph_data=[];
|
||||||
|
//var maxLatency=0;
|
||||||
|
//var graph_array=RawGraphData.split("|");
|
||||||
|
//alert(graph_array.length);
|
||||||
|
//for (var i=0; i<graph_array.length; i++)
|
||||||
|
// {
|
||||||
|
// dataset=graph_array[i].split(",");
|
||||||
|
// if (i<5) {alert(dataset[0]);}
|
||||||
|
// graph_data.push([dataset[0], parseInt(dataset[1])]);
|
||||||
|
// if (parseInt(dataset[1])>maxLatency)
|
||||||
|
// {
|
||||||
|
// maxLatency=parseInt(dataset[1]);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
if (!LatencyGraph)
|
||||||
|
{
|
||||||
|
// alert(RawGraphData);
|
||||||
|
var LatencyGraph=new Dygraph(document.getElementById("latency_graph_div"), RawGraphData,
|
||||||
|
{
|
||||||
|
title: graphTitle,
|
||||||
|
labelsDiv: document.getElementById("legend_div"),
|
||||||
|
drawPoints: true,
|
||||||
|
showRoller: false,
|
||||||
|
resizable: "both",
|
||||||
|
// legend: 'follow',
|
||||||
|
// legendFollowOffsetX: 5,
|
||||||
|
// legendFollowOffsetY: -5,
|
||||||
|
labelsSeparateLines: LSL_value,
|
||||||
|
connectSeparatedPoints: false,
|
||||||
|
drawGapEdgePoints: false,
|
||||||
|
ylabel: 'Latency',
|
||||||
|
xlabel: 'Time (HH:mm:ss)',
|
||||||
|
strokeWidth: 1.5
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LatencyGraph.updateOptions( {'file': RawGraphData, title: graphTitle} );
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('loading_please_wait').style.display='none';
|
||||||
|
document.getElementById('chart_div').style.display='block';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
echo "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=utf-8\">\n";
|
echo "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=utf-8\">\n";
|
||||||
@@ -334,7 +452,7 @@ else
|
|||||||
$multi_user=0;
|
$multi_user=0;
|
||||||
$latencies_to_print=0;
|
$latencies_to_print=0;
|
||||||
$Hlatencies_to_print=0;
|
$Hlatencies_to_print=0;
|
||||||
$stmt="SELECT vlad.user,vlad.update_date,vlad.web_ip,vlad.latency,vlad.latency_min_avg,vlad.latency_min_peak,vlad.latency_hour_avg,vlad.latency_hour_peak,vlad.latency_today_avg,vlad.latency_today_peak from vicidial_live_agents_details vlad where vlad.user='" . mysqli_real_escape_string($link, $user) . "' $vmLOGadmin_viewable_groupsSQL order by user limit 1000;";
|
$stmt="SELECT vlad.user,vlad.update_date,vlad.web_ip,vlad.latency,vlad.latency_min_avg,vlad.latency_min_peak,vlad.latency_hour_avg,vlad.latency_hour_peak,vlad.latency_today_avg,vlad.latency_today_peak from vicidial_live_agents_details vlad where vlad.user='" . mysqli_real_escape_string($link, $user) . "' $LOGadmin_viewable_groupsSQL order by user limit 1000;";
|
||||||
if ($user == '--ACTIVE-USERS-TODAY--')
|
if ($user == '--ACTIVE-USERS-TODAY--')
|
||||||
{
|
{
|
||||||
$multi_user=1;
|
$multi_user=1;
|
||||||
@@ -353,7 +471,7 @@ else
|
|||||||
|
|
||||||
$archive_output .= "| ".sprintf("%-20s", $row[0])." |";
|
$archive_output .= "| ".sprintf("%-20s", $row[0])." |";
|
||||||
$archive_output .= " ".sprintf("%-19s", $row[1])." |";
|
$archive_output .= " ".sprintf("%-19s", $row[1])." |";
|
||||||
$archive_output .= " ".sprintf("%-20s", $row[2])." |";
|
$archive_output .= " <a href=\"javascript:void(0)\" onClick=\"DrawGraph('$row[0]', '".substr($row[1], 0, 10)."', '---ALL---', 'latency_by_user')\">".sprintf("%-20s", $row[2])."</a> |";
|
||||||
$archive_output .= " ".sprintf("%-10s", $row[3])." |";
|
$archive_output .= " ".sprintf("%-10s", $row[3])." |";
|
||||||
$archive_output .= " ".sprintf("%-10s", $row[4])." |";
|
$archive_output .= " ".sprintf("%-10s", $row[4])." |";
|
||||||
$archive_output .= " ".sprintf("%-10s", $row[5])." |";
|
$archive_output .= " ".sprintf("%-10s", $row[5])." |";
|
||||||
@@ -369,7 +487,7 @@ else
|
|||||||
|
|
||||||
if ($multi_user < 1)
|
if ($multi_user < 1)
|
||||||
{
|
{
|
||||||
$stmt="select user,log_date,web_ip,latency_avg,latency_peak from vicidial_agent_latency_summary_log where user='" . mysqli_real_escape_string($link, $user) . "' $LOGadmin_viewable_groupsSQL order by log_date desc,web_ip limit 1000;";
|
$stmt="select user,log_date,web_ip,latency_avg,latency_peak,if(date(log_date)>=date(now()-INTERVAL 7 DAY), 1, 0) as show_link from vicidial_agent_latency_summary_log where user='" . mysqli_real_escape_string($link, $user) . "' $LOGadmin_viewable_groupsSQL order by log_date desc,web_ip limit 1000;";
|
||||||
$rslt=mysql_to_mysqli($stmt, $link);
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
if ($DB) {echo "$stmt\n";}
|
if ($DB) {echo "$stmt\n";}
|
||||||
$Hlatencies_to_print = mysqli_num_rows($rslt);
|
$Hlatencies_to_print = mysqli_num_rows($rslt);
|
||||||
@@ -382,7 +500,14 @@ else
|
|||||||
|
|
||||||
echo "| ".sprintf("%-20s", $row[0])." |";
|
echo "| ".sprintf("%-20s", $row[0])." |";
|
||||||
echo " ".sprintf("%-19s", $row[1])." |";
|
echo " ".sprintf("%-19s", $row[1])." |";
|
||||||
echo " ".sprintf("%-20s", $row[2])." |";
|
if ($row[5])
|
||||||
|
{
|
||||||
|
echo " <a href=\"javascript:void(0)\" onClick=\"DrawGraph('$row[0]', '".substr($row[1], 0, 10)."', '$row[2]', 'latency_by_user')\">".sprintf("%-20s", $row[2])."</a> |";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo " ".sprintf("%-20s", $row[2])." |";
|
||||||
|
}
|
||||||
echo " ".sprintf("%-10s", ' ')." |";
|
echo " ".sprintf("%-10s", ' ')." |";
|
||||||
echo " ".sprintf("%-10s", ' ')." |";
|
echo " ".sprintf("%-10s", ' ')." |";
|
||||||
echo " ".sprintf("%-10s", ' ')." |";
|
echo " ".sprintf("%-10s", ' ')." |";
|
||||||
@@ -394,8 +519,26 @@ else
|
|||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo "+----------------------+---------------------+----------------------+------------+------------+------------+------------+------------+------------+------------+\n";
|
||||||
|
echo "| GRAPH AGENTS BY DATE: <a href=\"javascript:void(0)\" onClick=\"DrawGraph('---ALL---', '".date("Y-m-d")."', '---ALL---', 'all_agent_latency')\">[ ".date("Y-m-d")." ]</a>";
|
||||||
|
$date_stmt="select distinct date(log_date) as ldate from vicidial_agent_latency_log_archive order by ldate desc";
|
||||||
|
$date_rslt=mysql_to_mysqli($date_stmt, $link);
|
||||||
|
$col_width=119;
|
||||||
|
while ($date_row=mysqli_fetch_row($date_rslt))
|
||||||
|
{
|
||||||
|
echo " <a href=\"javascript:void(0)\" onClick=\"DrawGraph('---ALL---', '".$date_row[0]."', '---ALL---', 'all_agent_latency')\">[ $date_row[0] ]</a>";
|
||||||
|
$col_width-=17;
|
||||||
|
}
|
||||||
|
echo sprintf("%-".$col_width."s", ' ')."|\n";
|
||||||
|
echo "+----------------------+---------------------+----------------------+------------+------------+------------+------------+------------+------------+------------+\n";
|
||||||
|
}
|
||||||
if ( ($latencies_to_print < 1) and ($Hlatencies_to_print < 1) )
|
if ( ($latencies_to_print < 1) and ($Hlatencies_to_print < 1) )
|
||||||
{echo _QXZ("No records to report");}
|
{echo _QXZ("No records to report");}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
echo "\n";
|
echo "\n";
|
||||||
}
|
}
|
||||||
@@ -423,6 +566,73 @@ $rslt=mysql_to_mysqli($stmt, $link);
|
|||||||
|
|
||||||
</PRE>
|
</PRE>
|
||||||
|
|
||||||
</TD></TR></TABLE>
|
<table>
|
||||||
|
<tr><td>
|
||||||
|
<style>
|
||||||
|
.dygraph-legend {
|
||||||
|
font-family: Arial, Helvetica, serif;
|
||||||
|
font-size: 10pt;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.dygraph-title {
|
||||||
|
font-family: Arial, Helvetica, serif;
|
||||||
|
color: #000;
|
||||||
|
text-shadow: #999 2px 2px 2px;
|
||||||
|
}
|
||||||
|
dygraph-axis-label {
|
||||||
|
font-family: Arial, Helvetica, serif;
|
||||||
|
font-size: 10pt;
|
||||||
|
color: #900;
|
||||||
|
text-shadow: #999 1px 1px 1px;
|
||||||
|
}
|
||||||
|
.dygraph-axis-label-x {
|
||||||
|
font-family: Arial, Helvetica, serif;
|
||||||
|
font-size: 10pt;
|
||||||
|
color: #900;
|
||||||
|
text-shadow: #999 1px 1px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dygraph-axis-label-y {
|
||||||
|
font-family: Arial, Helvetica, serif;
|
||||||
|
font-size: 10pt;
|
||||||
|
color: #900;
|
||||||
|
text-shadow: #999 1px 1px 1px;
|
||||||
|
}
|
||||||
|
.dygraph-xlabel {
|
||||||
|
font-family: Arial, Helvetica, serif;
|
||||||
|
font-size: 12pt;
|
||||||
|
font-weight: bold;
|
||||||
|
text-shadow: #999 1px 1px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dygraph-ylabel {
|
||||||
|
font-family: Arial, Helvetica, serif;
|
||||||
|
font-size: 12pt;
|
||||||
|
font-weight: bold;
|
||||||
|
text-shadow: #999 1px 1px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading_text {
|
||||||
|
font-family: Arial, Helvetica, serif;
|
||||||
|
font-size: 36pt;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #009;
|
||||||
|
text-shadow: #999 5px 5px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<div class='loading_text' id='loading_please_wait' style="width:800px; height:400px; display:none;">
|
||||||
|
<center>LOADING, PLEASE WAIT...</center>
|
||||||
|
</div>
|
||||||
|
<div id="chart_div" class="chart" style="width:800px; height:400px;">
|
||||||
|
<div id='latency_graph_div' style="width:800px;height:400px"></div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td align='left' valign='top'>
|
||||||
|
<div id='legend_div' class='dygraph-legend' style="width:200px;height:300px"></div>
|
||||||
|
</TD>
|
||||||
|
|
||||||
|
</TR></TABLE>
|
||||||
|
|
||||||
</BODY></HTML>
|
</BODY></HTML>
|
||||||
|
|||||||
Reference in New Issue
Block a user