From bfb1d71ae09660916aea55987fbf6040f1e94215 Mon Sep 17 00:00:00 2001 From: mattf Date: Thu, 23 Oct 2008 08:31:31 +0000 Subject: [PATCH] Added agi-AGENT_dial_in.agi script to allow for agent dial-in to vicidial sessions. bug fixes in CLOSER report and agent PHP scripts git-svn-id: svn://192.168.202.10@987 3d104415-ff17-0410-8863-d5cf3c621b8a --- UPGRADE | 13 + agi/agi-AGENT_dial_in.agi | 463 ++++++++++++++++++ docs/conf_examples/extensions.conf.sample | 6 + docs/conf_examples/extensions.conf.sample-1.4 | 6 + extras/first_server_install.sql | 1 + sounds/enter-password.gsm | Bin 0 -> 4917 bytes sounds/login-fail.gsm | Bin 0 -> 2409 bytes sounds/pin-invalid.gsm | Bin 0 -> 4752 bytes sounds/pin-number-accepted.gsm | Bin 0 -> 2343 bytes sounds/you-must-be-logged-in.gsm | Bin 0 -> 5643 bytes www/agc/manager_send.php | 5 + www/agc/vicidial.php | 22 +- www/vicidial/AST_CLOSERstats.php | 14 +- 13 files changed, 518 insertions(+), 12 deletions(-) create mode 100644 agi/agi-AGENT_dial_in.agi create mode 100644 sounds/enter-password.gsm create mode 100644 sounds/login-fail.gsm create mode 100644 sounds/pin-invalid.gsm create mode 100644 sounds/pin-number-accepted.gsm create mode 100644 sounds/you-must-be-logged-in.gsm diff --git a/UPGRADE b/UPGRADE index 30491339..62803c3a 100644 --- a/UPGRADE +++ b/UPGRADE @@ -195,6 +195,19 @@ NOTE: Upgrading from 1.1.12-3 to 2.0.1 is at the bottom 43. Added INBOUND_MAN dial method to allow for inbound call handling by agents that are also placing manual dial list calls through their campaign lists +44. Added option to see the inbound group call stats in the Real-time screen + +45. Added ability for agents to dial in to an AGI script(agi-AGENT_dial_in.agi) + to log their phone into the session instead of having VICIDIAL call them. + The user ID and password for the agent must be digits only for this to work! + This requires the following to be added to the dialplan on the dial-in DID + or extension that you want to use: + exten => 2345,1,Answer ; Answer the line + exten => 2345,2,AGI(agi-AGENT_dial_in.agi) + exten => 2345,3,Hangup + + + diff --git a/agi/agi-AGENT_dial_in.agi b/agi/agi-AGENT_dial_in.agi new file mode 100644 index 00000000..aae8bf06 --- /dev/null +++ b/agi/agi-AGENT_dial_in.agi @@ -0,0 +1,463 @@ +#!/usr/bin/perl +# +# agi-AGENT_dial_in.agi version 0.1 +# +# This script is designed to allow agents the ability to dial in to an extension +# to establish the phone connection to their VICIDIAL session. The user login +# and password must be only digits and nothing but digits to use this utility. +# +# user is prompted for their user ID then press # +# user is prompted for their passcode then press # +# then the user is forwarded to the active vicidial agent session +# +# ;agent dial-in: +#exten => 2345,1,Answer ; Answer the line +#exten => 2345,2,AGI(agi-AGENT_dial_in.agi) +#exten => 2345,3,Hangup +# +# +# Copyright (C) 2008 Matt Florell LICENSE: AGPLv2 +# +# CHANGELOG +# 81022-2115 - First build +# + +&get_time_now; + $start_epoch = $now_date_epoch; + +$script = 'agi-AGENT_dial_in.agi'; + +$now_date_epoch = time(); +$now_date = "$year-$mon-$mday $hour:$min:$sec"; + +($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +$year = ($year + 1900); +$mon++; +if ($mon < 10) {$mon = "0$mon";} +if ($mday < 10) {$mday = "0$mday";} +if ($hour < 10) {$Fhour = "0$hour";} +if ($min < 10) {$min = "0$min";} +if ($sec < 10) {$sec = "0$sec";} + +$US='_'; + + +# default path to astguiclient configuration file: +$PATHconf = '/etc/astguiclient.conf'; + +open(conf, "$PATHconf") || die "can't open $PATHconf: $!\n"; +@conf = ; +close(conf); +$i=0; +foreach(@conf) + { + $line = $conf[$i]; + $line =~ s/ |>|\n|\r|\t|\#.*|;.*//gi; + if ( ($line =~ /^PATHlogs/) && ($CLIlogs < 1) ) + {$PATHlogs = $line; $PATHlogs =~ s/.*=//gi;} + if ( ($line =~ /^PATHsounds/) && ($CLIsounds < 1) ) + {$PATHsounds = $line; $PATHsounds =~ s/.*=//gi;} + if ( ($line =~ /^PATHmonitor/) && ($CLImonitor < 1) ) + {$PATHmonitor = $line; $PATHmonitor =~ s/.*=//gi;} + if ( ($line =~ /^VARserver_ip/) && ($CLIserver_ip < 1) ) + {$VARserver_ip = $line; $VARserver_ip =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_server/) && ($CLIDB_server < 1) ) + {$VARDB_server = $line; $VARDB_server =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_database/) && ($CLIDB_database < 1) ) + {$VARDB_database = $line; $VARDB_database =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_user/) && ($CLIDB_user < 1) ) + {$VARDB_user = $line; $VARDB_user =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_pass/) && ($CLIDB_pass < 1) ) + {$VARDB_pass = $line; $VARDB_pass =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_port/) && ($CLIDB_port < 1) ) + {$VARDB_port = $line; $VARDB_port =~ s/.*=//gi;} + $i++; + } + +if (!$VARDB_port) {$VARDB_port='3306';} +if (!$AGILOGfile) {$AGILOGfile = "$PATHlogs/ivrout.$year-$mon-$mday";} + +use DBI; +use Asterisk::AGI; +$AGI = new Asterisk::AGI; + +$dbhA = DBI->connect("DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port", "$VARDB_user", "$VARDB_pass") + or die "Couldn't connect to database: " . DBI->errstr; + + +$|=1; +while() +{ + chomp; + last unless length($_); + if ($V) + { + if (/^agi_(\w+)\:\s+(.*)$/) + { + $AGI{$1} = $2; + } + } + + if (/^agi_uniqueid\:\s+(.*)$/) {$unique_id = $1;} + if (/^agi_extension\:\s+(.*)$/) {$extension = $1;} + if (/^agi_channel\:\s+(.*)$/) {$channel = $1;} + if (/^agi_callerid\:\s+(.*)$/) {$callerid = $1;} + if (/^agi_calleridname\:\s+(.*)$/) {$calleridname = $1;} +} + +if ( ($callerid =~ /\".*\"/) && ( (!$calleridname) or ($calleridname =~ /unknown/) ) ) + { + $calleridname = $callerid; + $calleridname =~ s/\<\d\d\d\d\d\d\d\d\d\d\>//gi; + $calleridname =~ s/\"|\" //gi; + } + + $callerid =~ s/\D//gi; + $calleridname =~ s/unknown//gi; +if ( (!$callerid) or ($callerid =~ /unknown/) ) + {$callerid = $calleridname;} +$phone_number=$callerid; + +### Grab Server values from the database +$stmtA = "SELECT ext_context,agi_output FROM servers where server_ip = '$VARserver_ip';"; +$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; +$sthA->execute or die "executing: $stmtA ", $dbhA->errstr; +$sthArows=$sthA->rows; + $rec_count=0; +while ($sthArows > $rec_count) + { + @aryA = $sthA->fetchrow_array; + $DBext_context = "$aryA[0]"; + $DBagi_output = "$aryA[1]"; + if ($DBext_context) {$ext_context = $DBext_context;} + if ($DBagi_output =~ /STDERR/) {$AGILOG = '1';} + if ($DBagi_output =~ /FILE/) {$AGILOG = '2';} + if ($DBagi_output =~ /BOTH/) {$AGILOG = '3';} + $rec_count++; + } +$sthA->finish(); + + + +$AGI->stream_file('sip-silence'); +$AGI->stream_file('sip-silence'); + + +$entry_chances=0; +$VALID_login=0; +$ACTIVE_login=0; +$VDADremDIALstr=''; +while ( ($entry_chances < 3) && ($VALID_login < 1) ) + { + $entry_chances++; + + + &user_password_gather; + + + ###### Check userID and password against vicidial_users table + $stmtA = "SELECT count(*) FROM vicidial_users where user='$PIN_number' and pass='$PASS_word';"; + $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; + $VALID_login = "$aryA[0]"; + } + $sthA->finish(); + + + if ($VALID_login > 0) + { + $AGI->stream_file('pin-number-accepted'); + } + else + { + $AGI->stream_file('pin-invalid'); + } + } + + + +if ($VALID_login < 1) + { + if ($AGILOG) {$agi_string = "DIAL-IN END: Invalid Login |$VALID_login|$PIN_number|$PASS_word|"; &agi_output;} + + $AGI->stream_file('vm-goodbye'); + + $AGI->hangup(); + + $dbhA->disconnect(); + exit; + } +else + { + $secX = time(); + $PDtarget = ($secX - 30); + ($Psec,$Pmin,$Phour,$Pmday,$Pmon,$Pyear,$Pwday,$Pyday,$Pisdst) = localtime($PDtarget); + $Pyear = ($Pyear + 1900); + $Pmon++; + if ($Pmon < 10) {$Pmon = "0$Pmon";} + if ($Pmday < 10) {$Pmday = "0$Pmday";} + if ($Phour < 10) {$Phour = "0$Phour";} + if ($Pmin < 10) {$Pmin = "0$Pmin";} + if ($Psec < 10) {$Psec = "0$Psec";} + $PDtsSQLdate = "$Pyear$Pmon$Pmday$Phour$Pmin$Psec"; + + ###### Check if user is logged in, vicidial_live_agents table + $stmtA = "SELECT count(*) FROM vicidial_live_agents where user='$PIN_number' and last_update_time > \"$PDtsSQLdate\";"; + $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; + $ACTIVE_login = "$aryA[0]"; + } + $sthA->finish(); + + if ($ACTIVE_login < 1) + { + if ($AGILOG) {$agi_string = "DIAL-IN END: Inactive Login |$VALID_login|$PIN_number|$PASS_word| |$ACTIVE_login|$PDtsSQLdate|"; &agi_output;} + + $AGI->stream_file('login-fail'); + $AGI->stream_file('you-must-be-logged-in'); + $AGI->stream_file('vm-goodbye'); + + $AGI->hangup(); + + $dbhA->disconnect(); + exit; + } + else + { + $stmtA = "SELECT conf_exten,extension,server_ip from vicidial_live_agents WHERE user='$PIN_number' limit 1;"; + if ($AGILOG) {$agi_string = "|$stmtA|"; &agi_output;} + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $rec_countCUSTDATA=0; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + + $VDADconf_exten = "$aryA[0]"; + $VDADextension = "$aryA[1]"; + $VDADserver_ip = "$aryA[2]"; + } + $sthA->finish(); + + ### format the remote server dialstring to get the call to the overflow agent meetme room + $S='*'; + if( $VDADserver_ip =~ m/(\S+)\.(\S+)\.(\S+)\.(\S+)/ ) + { + $a = leading_zero($1); + $b = leading_zero($2); + $c = leading_zero($3); + $d = leading_zero($4); + $VDADremDIALstr = "$a$S$b$S$c$S$d$S"; + } + $VDADremDIALstr .= "$VDADconf_exten"; + + if ($AGILOG) {$agi_string = "Agent $PIN_number sent to $VDADremDIALstr"; &agi_output;} + + print "SET CONTEXT $ext_context\n"; + checkresult($result); + print "SET EXTENSION $VDADremDIALstr\n"; + checkresult($result); + print "SET PRIORITY 1\n"; + checkresult($result); + } + } + + + +$dbhA->disconnect(); + +exit; + + + + + +################################################################################ +##### SUBROUTINES ############################################################## +################################################################################ + + +##### BEGIN collect the user and password ###################################### +sub user_password_gather +{ +################################################################################ +# please enter the pin number followed by the pound key + +$interrupt_digit=''; + +$interrupt_digit = $AGI->stream_file('ld_welcome_pin_number','0123456789'); + + print STDERR "interrupt_digit |$interrupt_digit|\n"; + +$digits_being_entered=1; +$PIN_number=''; +if ($interrupt_digit > 0) + { +# if ($interrupt_digit == 35) {$interrupt_digit='#';} +# if ($interrupt_digit == 42) {$interrupt_digit='*';} + if ($interrupt_digit == 48) {$interrupt_digit=0;} + if ($interrupt_digit == 49) {$interrupt_digit=1;} + if ($interrupt_digit == 50) {$interrupt_digit=2;} + if ($interrupt_digit == 51) {$interrupt_digit=3;} + if ($interrupt_digit == 52) {$interrupt_digit=4;} + if ($interrupt_digit == 53) {$interrupt_digit=5;} + if ($interrupt_digit == 54) {$interrupt_digit=6;} + if ($interrupt_digit == 55) {$interrupt_digit=7;} + if ($interrupt_digit == 56) {$interrupt_digit=8;} + if ($interrupt_digit == 57) {$interrupt_digit=9;} + + $PIN_number=$interrupt_digit; + } + +$digit_loop_counter=0; +while ( ($digits_being_entered > 0) && ($digit_loop_counter < 20) ) + { + $digit = chr($AGI->wait_for_digit('10000')); # wait 10 seconds for input or until the pound key is pressed + if ($digit =~ /\d/) + { + $PIN_number = "$PIN_number$digit"; + print STDERR "digit |$digit| PIN_number |$PIN_number|\n"; +# $AGI->say_digits("$digit"); + undef $digit; + } + else + { + $digits_being_entered=0; + } + + $digit_loop_counter++; + } + +$PIN_number =~ s/\D//gi; +if ($PIN_number) {print STDERR "digit |$digit| PIN_number |$PIN_number|\n";} + + + +################################################################################ +# please enter your password followed by the pound key + +$interrupt_digit=''; + +$interrupt_digit = $AGI->stream_file('enter-password','0123456789'); + + print STDERR "interrupt_digit |$interrupt_digit|\n"; + +$digits_being_entered=1; +$PASS_word=''; +if ($interrupt_digit > 0) + { +# if ($interrupt_digit == 35) {$interrupt_digit='#';} +# if ($interrupt_digit == 42) {$interrupt_digit='*';} + if ($interrupt_digit == 48) {$interrupt_digit=0;} + if ($interrupt_digit == 49) {$interrupt_digit=1;} + if ($interrupt_digit == 50) {$interrupt_digit=2;} + if ($interrupt_digit == 51) {$interrupt_digit=3;} + if ($interrupt_digit == 52) {$interrupt_digit=4;} + if ($interrupt_digit == 53) {$interrupt_digit=5;} + if ($interrupt_digit == 54) {$interrupt_digit=6;} + if ($interrupt_digit == 55) {$interrupt_digit=7;} + if ($interrupt_digit == 56) {$interrupt_digit=8;} + if ($interrupt_digit == 57) {$interrupt_digit=9;} + + $PASS_word=$interrupt_digit; + } + +$digit_loop_counter=0; +while ( ($digits_being_entered > 0) && ($digit_loop_counter < 20) ) + { + $digit = chr($AGI->wait_for_digit('10000')); # wait 10 seconds for input or until the pound key is pressed + if ($digit =~ /\d/) + { + $PASS_word = "$PASS_word$digit"; + print STDERR "digit |$digit| PASS_word |$PASS_word|\n"; +# $AGI->say_digits("$digit"); + undef $digit; + } + else + { + $digits_being_entered=0; + } + + $digit_loop_counter++; + } + +$PASS_word =~ s/\D//gi; +if ($PASS_word) {print STDERR "digit |$digit| PASS_word |$PASS_word| PIN_number |$PIN_number|\n";} + +} +##### END collect the user and password ############################################### + + + + + +sub get_time_now #get the current date and time and epoch for logging call lengths and datetimes +{ +($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +$year = ($year + 1900); +$mon++; +if ($mon < 10) {$mon = "0$mon";} +if ($mday < 10) {$mday = "0$mday";} +if ($hour < 10) {$Fhour = "0$hour";} +if ($min < 10) {$min = "0$min";} +if ($sec < 10) {$sec = "0$sec";} + +$now_date_epoch = time(); +$now_date = "$year-$mon-$mday $hour:$min:$sec"; +$filedate = "$year$mon$mday$hour$min$sec"; +} + + + +sub checkresult { + my ($res) = @_; + my $retval; + $tests++; + chomp $res; + if ($res =~ /^200/) { + $res =~ /result=(-?\d+)/; + if (!length($1)) { + print STDERR "FAIL ($res)\n"; + $fail++; + } else { + print STDERR "PASS ($1)\n"; + $pass++; + } + } else { + print STDERR "FAIL (unexpected result '$res')\n"; + $fail++; + } +} + +sub agi_output +{ +if ($AGILOG >=2) + { + ### open the log file for writing ### + open(Lout, ">>$AGILOGfile") + || die "Can't open $AGILOGfile: $!\n"; + print Lout "$now_date|$script|$agi_string\n"; + close(Lout); + } + ### send to STDERR writing ### +if ( ($AGILOG == '1') || ($AGILOG == '3') ) + {print STDERR "$now_date|$script|$agi_string\n";} +$agi_string=''; +} + +sub leading_zero($) +{ + $_ = $_[0]; + s/^(\d)$/0$1/; + s/^(\d\d)$/0$1/; + return $_; +} # End of the leading_zero() routine. diff --git a/docs/conf_examples/extensions.conf.sample b/docs/conf_examples/extensions.conf.sample index cc22ac1f..38a7cfc7 100644 --- a/docs/conf_examples/extensions.conf.sample +++ b/docs/conf_examples/extensions.conf.sample @@ -14,6 +14,12 @@ TRUNKloop = IAX2/ASTloop:test@127.0.0.1:40569 ; used for blind monitoring TRUNKblind = IAX2/ASTblind:test@127.0.0.1:41569 ; used for testing [testtrunkinbound] +; agent dial-in: +exten => 2345,1,Answer ; Answer the line +exten => 2345,2,AGI(agi-AGENT_dial_in.agi) +exten => 2345,3,Hangup + +; DID call routing process exten => _X.,1,AGI(agi-DID_route.agi) [default] diff --git a/docs/conf_examples/extensions.conf.sample-1.4 b/docs/conf_examples/extensions.conf.sample-1.4 index 6ea41905..749738b5 100644 --- a/docs/conf_examples/extensions.conf.sample-1.4 +++ b/docs/conf_examples/extensions.conf.sample-1.4 @@ -14,6 +14,12 @@ TRUNKloop = IAX2/ASTloop:test@127.0.0.1:40569 ; used for blind monitoring TRUNKblind = IAX2/ASTblind:test@127.0.0.1:41569 ; used for testing [testtrunkinbound] +; agent dial-in: +exten => 2345,1,Answer ; Answer the line +exten => 2345,2,AGI(agi-AGENT_dial_in.agi) +exten => 2345,3,Hangup + +; DID call routing process exten => _X.,1,AGI(agi-DID_route.agi) [default] diff --git a/extras/first_server_install.sql b/extras/first_server_install.sql index 136f0b9f..b90de772 100644 --- a/extras/first_server_install.sql +++ b/extras/first_server_install.sql @@ -3,6 +3,7 @@ INSERT INTO servers (server_id,server_description,server_ip,active,asterisk_vers INSERT INTO server_updater values('10.10.10.15',''); INSERT INTO phones (extension, dialplan_number, voicemail_id, phone_ip, computer_ip, server_ip, login, pass, status, active, phone_type, fullname, company, picture, messages, old_messages, protocol) values('gs102','102','102','10.10.10.16','10.10.9.16','10.10.10.15','gs102','test', 'ADMIN','Y','Grandstream BT 102','Test Admin Phone','TEST','','0','0','SIP'); +INSERT INTO phones (extension, dialplan_number, voicemail_id, phone_ip, computer_ip, server_ip, login, pass, status, active, phone_type, fullname, company, protocol) values('callin','8300','8300','10.10.10.15','10.10.10.15','10.10.10.15','callin','test', 'ACTIVE','Y','Dial-in agent phone','Dial-in Agent Phone','TEST','EXTERNAL'); INSERT INTO vicidial_users (user,pass,full_name,user_level,user_group,load_leads,campaign_detail,ast_admin_access,modify_users) values('6666','1234','Admin','9','ADMIN','1','1','1','1'); diff --git a/sounds/enter-password.gsm b/sounds/enter-password.gsm new file mode 100644 index 0000000000000000000000000000000000000000..00feba18be85363b5277f52707333c34799f6cc3 GIT binary patch literal 4917 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 z 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 literal 0 HcmV?d00001 diff --git a/sounds/pin-invalid.gsm b/sounds/pin-invalid.gsm new file mode 100644 index 0000000000000000000000000000000000000000..d3108f8997446c4c6bbc2310b91865fa8593c11c GIT binary patch literal 4752 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 ACIA2c literal 0 HcmV?d00001 diff --git a/sounds/pin-number-accepted.gsm b/sounds/pin-number-accepted.gsm new file mode 100644 index 0000000000000000000000000000000000000000..8faf8f927b556bea13ec3206782e281fdad61bb5 GIT binary patch literal 2343 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 aiVmZDi_=EHVJ$lh=Utq?7T$#9g!w";} $rslt=mysql_query($stmtD, $link); diff --git a/www/agc/vicidial.php b/www/agc/vicidial.php index 96ae411a..a0a90fa2 100644 --- a/www/agc/vicidial.php +++ b/www/agc/vicidial.php @@ -199,10 +199,11 @@ # 81015-0405 - Fixed bug related to hangups on 3way calls # 81016-0703 - Changed leave 3way to allow function at any time transfer-conf is available # 81020-1501 - Fixed bugs in queue_log logging +# 81023-0411 - Added compatibility for dial-in agents using AGI, bug fixes # -$version = '2.0.5-178'; -$build = '81020-1501'; +$version = '2.0.5-179'; +$build = '81023-0411'; require("dbconnect.php"); @@ -1237,6 +1238,11 @@ else $extension = "$dialplan_number$AT$ext_context"; } $SIP_user = "$protocol/$extension"; + $SIP_user_DiaL = "$protocol/$extension"; + if ( (ereg('8300',$dialplan_number)) and (strlen($dialplan_number)<5) and ($protocol == 'Local') ) + { + $SIP_user = "$protocol/$extension$VD_login"; + } $stmt="SELECT asterisk_version from servers where server_ip='$server_ip';"; if ($DB) {echo "|$stmt|\n";} @@ -1405,11 +1411,11 @@ else } ### insert a NEW record to the vicidial_manager table to be processed - $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','Originate','$SIqueryCID','Channel: $SIP_user','Context: $ext_context','Exten: $session_id','Priority: 1','Callerid: $SIqueryCID','','','','','');"; + $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','Originate','$SIqueryCID','Channel: $SIP_user_DiaL','Context: $ext_context','Exten: $session_id','Priority: 1','Callerid: $SIqueryCID','','','','','');"; if ($DB) {echo "$stmt\n";} $rslt=mysql_query($stmt, $link); $affected_rows = mysql_affected_rows($link); - print "\n"; + print "\n"; if ($auto_dial_level > 0) { @@ -2266,7 +2272,7 @@ if ($enable_fast_refresh < 1) {echo "\tvar refresh_interval = 1000;\n";} if (taskFromConf == 'YES') {basic_originate_call(manual_string,'NO','YES',dial_conf_exten,'NO',taskFromConf,threeway_cid);} else - {basic_originate_call(manual_string,'NO','NO');} + {basic_originate_call(manual_string,'NO','NO','','','','1');} MD_ring_secondS=0; } @@ -3396,7 +3402,7 @@ if ($enable_fast_refresh < 1) {echo "\tvar refresh_interval = 1000;\n";} if (MDDiaLOverridEform.length > 0) { - basic_originate_call(session_id,'NO','YES',MDDiaLOverridEform,'YES'); + basic_originate_call(session_id,'NO','YES',MDDiaLOverridEform,'YES','','1'); } else { @@ -5617,13 +5623,13 @@ if ($enable_fast_refresh < 1) {echo "\tvar refresh_interval = 1000;\n";} { document.vicidial_form.conf_dtmf.value = CalL_XC_a_Dtmf; document.vicidial_form.xfernumber.value = CalL_XC_a_NuMber; - basic_originate_call(CalL_XC_a_NuMber,'NO','YES',session_id,'YES'); + basic_originate_call(CalL_XC_a_NuMber,'NO','YES',session_id,'YES','','1'); } function DtMf_PreSet_b_DiaL() { document.vicidial_form.conf_dtmf.value = CalL_XC_b_Dtmf; document.vicidial_form.xfernumber.value = CalL_XC_b_NuMber; - basic_originate_call(CalL_XC_b_NuMber,'NO','YES',session_id,'YES'); + basic_originate_call(CalL_XC_b_NuMber,'NO','YES',session_id,'YES','','1'); } // ################################################################################ diff --git a/www/vicidial/AST_CLOSERstats.php b/www/vicidial/AST_CLOSERstats.php index b00eee31..03765e4f 100644 --- a/www/vicidial/AST_CLOSERstats.php +++ b/www/vicidial/AST_CLOSERstats.php @@ -460,8 +460,11 @@ while ($i < $statuses_to_print) } $TOTALcalls = ($TOTALcalls + $row[0]); - $STATUSrate = ($STATUScount / ($TOTALsec / 3600) ); - $STATUSrate = sprintf("%.2f", $STATUSrate); + if ( ($STATUScount < 1) or ($TOTALsec < 1) ) + {$STATUSrate = 0;} + else + {$STATUSrate = ($STATUScount / ($TOTALsec / 3600) );} + $STATUSrate = sprintf("%.2f", $STATUSrate); $STATUShours_H = ($row[2] / 3600); $STATUShours_H_int = round($STATUShours_H, 2); @@ -526,8 +529,11 @@ if ($TOTALcalls < 1) } else { - $TOTALrate = ($TOTALcalls / ($TOTALsec / 3600) ); - $TOTALrate = sprintf("%.2f", $TOTALrate); + if ( ($TOTALcalls < 1) or ($TOTALsec < 1) ) + {$TOTALrate = 0;} + else + {$TOTALrate = ($TOTALcalls / ($TOTALsec / 3600) );} + $TOTALrate = sprintf("%.2f", $TOTALrate); $TOTALhours_H = ($TOTALsec / 3600); $TOTALhours_H_int = round($TOTALhours_H, 2);