root/trunk/common/lib/Class.A2Billing.php

Revision 974, 113.3 kB (checked in by rach, 2 years ago)

Add 0* only like redial number

  • Property svn:executable set to *
Line 
1 <?php
2 /***************************************************************************
3  *
4  * Class.A2Billing.php : PHP A2Billing Functions for A2Billing
5  * Written for PHP 4.x & PHP 5.X versions.
6  *
7  * A2Billing -- Asterisk billing solution.
8  * Copyright (C) 2004, 2007 Belaid Arezqui <areski _atl_ gmail com>
9  *
10  * See http://www.asterisk2billing.org for more information about
11  * the A2Billing project.
12  * Please submit bug reports, patches, etc to <areski _atl_ gmail com>
13  *
14  * This software is released under the terms of the GNU Lesser General Public License v2.1
15  * A copy of which is available from http://www.gnu.org/copyleft/lesser.html
16  *
17  ****************************************************************************/
18
19
20 define('AST_CONFIG_DIR', '/etc/asterisk/');
21 define('DEFAULT_A2BILLING_CONFIG', AST_CONFIG_DIR . '/a2billing.conf');
22
23 // DEFINE STATUS FOR DEBUG
24 define ('VERBOSE',            1);
25 define ('WRITELOG',            2);            // 1 << 1
26
27 class A2Billing {
28
29
30     /**
31     * Config variables
32     *
33     * @var array
34     * @access public
35     */
36     var $config;
37
38     /**
39     * Config AGI variables
40     * Create for coding readability facilities
41     *
42     * @var array
43     * @access public
44     */
45     var $agiconfig;
46
47     /**
48     * IDConfig variables
49     *
50     * @var interger
51     * @access public
52     */
53     var $idconfig=1;
54
55
56     /**
57     * cardnumber & CallerID variables
58     *
59     * @var string
60     * @access public
61     */
62     var $cardnumber;
63     var $CallerID;
64
65
66     /**
67     * Buffer variables
68     *
69     * @var string
70     * @access public
71     */
72     var $BUFFER;
73
74
75     /**
76     * DBHandle variables
77     *
78     * @var object
79     * @access public
80     */
81     var $DBHandle;
82
83
84     /**
85     * instance_table variables
86     *
87     * @var object
88     * @access public
89     */
90     var $instance_table;
91
92     /**
93     * store the file name to store the logs
94     *
95     * @var string
96     * @access public
97     */
98     var $log_file = '';
99
100
101     /**
102     * request AGI variables
103     *
104     * @var string
105     * @access public
106     */
107
108     var $channel;
109     var $uniqueid;
110     var $accountcode;
111     var $dnid;
112
113     // from apply_rules, if a prefix is removed we keep it to track exactly what the user introduce
114
115     var $countrycode;
116     var $subcode;
117     var $myprefix;
118     var $ipaddress;
119     var $rate;
120     var $destination;
121     var $sip_iax_buddy;
122     var $credit;
123     var $tariff;
124     var $active;
125     var $status;
126     var $hostname='';
127     var $currency='usd';
128
129     var $mode = '';
130     var $timeout;
131     var $newdestination;
132     var $tech;
133     var $prefix;
134     var $username;
135
136     var $typepaid = 0;
137     var $removeinterprefix = 1;
138     var $redial;
139     var $nbused = 0;
140
141     var $enableexpire;
142     var $expirationdate;
143     var $expiredays;
144     var $firstusedate;
145     var $creationdate;
146
147     var $languageselected;
148     var $current_language;
149
150
151     var $cardholder_lastname;
152     var $cardholder_firstname;
153     var $cardholder_email;
154     var $cardholder_uipass;
155     var $id_campaign;
156     var $id_card;
157     var $useralias;
158
159     // Enable voicemail for this card. For DID and SIP/IAX call
160     var $voicemail = 0;
161
162     // Flag to know that we ask for an othercardnumber when for instance we doesnt have enough credit to make a call
163     var $ask_other_cardnumber=0;
164
165     var $ivr_voucher;
166     var $vouchernumber;
167     var $add_credit;
168
169     var $cardnumber_range;
170
171     // Define if we have changed the status of the card
172     var $set_inuse = 0;
173
174     /**
175     * CC_TESTING variables
176     * for developer purpose, will replace some get_data inputs in order to test the application from shell
177     *
178     * @var interger
179     * @access public
180     */
181     var $CC_TESTING;
182
183
184     /* CONSTRUCTOR */
185
186     function A2Billing()
187     {
188         $this -> agiconfig['debug'] = true;
189         //$this -> DBHandle = $DBHandle;
190     }
191
192
193     /* Init */
194
195     function Reinit()
196     {
197         $this -> countrycode='';
198         $this -> subcode='';
199         $this -> myprefix='';
200         $this -> ipaddress='';
201         $this -> rate='';
202         $this -> destination='';
203     }
204
205
206     /*
207      * Debug
208      *
209      * usage : $A2B -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, $buffer_debug);
210      */
211     function debug( $debug, $agi, $file, $line, $buffer_debug)
212     {
213         $file = basename($file);
214
215         // RUN VERBOSE ON CLI
216         if ($debug & VERBOSE) {
217             if ($this->agiconfig['debug']>=1)   $agi->verbose('file:'.$file.' - line:'.$line.' - uniqueid:'.$this->uniqueid.' - '.$buffer_debug);
218         }
219
220         // RIGHT DEBUG IN LOG FILE
221         if ($debug & WRITELOG) {
222             $this -> write_log ($buffer_debug, 1, "[file:$file - line:$line - uniqueid:".$this->uniqueid."]:");
223         }
224     }
225
226     /*
227      * Write log into file
228      */
229     function write_log($output, $tobuffer = 1, $line_file_info = '')
230     {
231         //$tobuffer = 0;
232
233         if (strlen($this->log_file) > 1) {
234             $string_log = "[".date("d/m/Y H:i:s")."]:".$line_file_info."[CallerID:".$this->CallerID."]:[CN:".$this->cardnumber."]:[$output]\n";
235             if ($this->CC_TESTING) echo $string_log;
236
237             $this -> BUFFER .= $string_log;
238             if (!$tobuffer || $this->CC_TESTING) {
239                 error_log ($this -> BUFFER, 3, $this->log_file);
240                 $this-> BUFFER = '';
241             }
242         }
243     }
244
245     /*
246      * set the DB handler
247      */
248     function set_dbhandler ($DBHandle)
249     {
250         $this->DBHandle    = $DBHandle;
251     }
252
253     /*
254      * set_instance_table
255      */
256     function set_instance_table ($instance_table)
257     {
258         $this->instance_table = $instance_table;
259     }
260
261     /*
262      * load_conf
263      */
264     function load_conf( &$agi, $config=NULL, $webui=0, $idconfig=1, $optconfig=array())
265     {
266         $this -> idconfig = $idconfig;
267         // load config
268         if(!is_null($config) && file_exists($config)) {
269             $this->config = parse_ini_file($config, true);
270         } elseif(file_exists(DEFAULT_A2BILLING_CONFIG)) {
271             $this->config = parse_ini_file(DEFAULT_A2BILLING_CONFIG, true);
272         }
273
274           /*  We don't need to do this twice.  load_conf_db() will do it
275         // If optconfig is specified, stuff vals and vars into 'a2billing' config array.
276         foreach($optconfig as $var=>$val) {
277             $this->config["agi-conf$idconfig"][$var] = $val;
278         }*/
279
280         // conf for the database connection
281         if(!isset($this->config['database']['hostname']))    $this->config['database']['hostname'] = 'localhost';
282         if(!isset($this->config['database']['port']))        $this->config['database']['port'] = '5432';
283         if(!isset($this->config['database']['user']))        $this->config['database']['user'] = 'postgres';
284         if(!isset($this->config['database']['password']))    $this->config['database']['password'] = '';
285         if(!isset($this->config['database']['dbname']))        $this->config['database']['dbname'] = 'a2billing';
286         if(!isset($this->config['database']['dbtype']))        $this->config['database']['dbtype'] = 'postgres';
287
288         return $this->load_conf_db($agi, NULL, 0, $idconfig, $optconfig);
289     }
290
291     /*
292      * Load config from Database
293      */
294     function load_conf_db( &$agi, $config=NULL, $webui=0, $idconfig=1, $optconfig=array())
295     {
296         $this -> idconfig = $idconfig;
297         // load config
298         $config_table = new Table("cc_config ccc, cc_config_group ccg", "ccc.config_key as cfgkey, ccc.config_value as cfgvalue, ccg.group_title as cfggname, ccc.config_valuetype as cfgtype");
299         $this->DbConnect();
300
301         $config_res = $config_table -> Get_list($this->DBHandle, "ccc.config_group_id = ccg.id");
302         if (!$config_res) {
303             echo 'Error : cannot load conf : load_conf_db';
304             return false;
305         }
306
307         foreach ($config_res as $conf)
308         {
309             // FOR DEBUG
310             /*if ($conf['cfgkey'] == 'sip_iax_pstn_direct_call_prefix') {
311                 $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "\n\n conf :".$conf['cfgkey']);
312                 $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "\n\n conf :".$conf['cfgvalue']);
313             }*/
314             if($conf['cfgtype'] == 0) // if its type is text
315             {
316                 $this->config[$conf['cfggname']][$conf['cfgkey']] = $conf['cfgvalue'];
317             }
318             elseif($conf['cfgtype'] == 1) // if its type is boolean
319             {
320                 if(strtoupper($conf['cfgvalue']) == "YES" || $conf['cfgvalue'] == 1 || strtoupper($conf['cfgvalue']) == "TRUE") // if equal to 'yes'
321                 {
322                     $this->config[$conf['cfggname']][$conf['cfgkey']] = 1;
323                 }
324                 else // if equal to 'no'
325                 {
326                     $this->config[$conf['cfggname']][$conf['cfgkey']] = 0;
327                 }
328             }
329         }
330         $this->DbDisconnect($this->DBHandle);
331
332         // If optconfig is specified, stuff vals and vars into 'a2billing' config array.
333         foreach($optconfig as $var=>$val)
334         {
335             $this->config["agi-conf$idconfig"][$var] = $val;
336         }
337
338         // add default values to config for uninitialized values
339         //Card Number Length Code
340         $card_length_range = isset($this->config['global']['interval_len_cardnumber'])?$this->config['global']['interval_len_cardnumber']:null;
341         $this -> cardnumber_range = $this -> splitable_data ($card_length_range);
342
343         if(is_array($this -> cardnumber_range) && ($this -> cardnumber_range[0] >= 4))
344         {
345             define ("CARDNUMBER_LENGTH_MIN", $this -> cardnumber_range[0]);
346             define ("CARDNUMBER_LENGTH_MAX", $this -> cardnumber_range[count($this -> cardnumber_range)-1]);
347             define ("LEN_CARDNUMBER", CARDNUMBER_LENGTH_MIN);
348         }
349         else
350         {
351             echo gettext("Invalid card number lenght defined in configuration.");
352             exit;
353         }
354         if(!isset($this->config['global']['len_aliasnumber']))        $this->config['global']['len_aliasnumber'] = 15;
355         if(!isset($this->config['global']['len_voucher']))            $this->config['global']['len_voucher'] = 15;
356         if(!isset($this->config['global']['base_currency']))         $this->config['global']['base_currency'] = 'usd';
357         if(!isset($this->config['global']['didbilling_daytopay']))     $this->config['global']['didbilling_daytopay'] = 5;
358         if(!isset($this->config['global']['admin_email']))             $this->config['global']['admin_email'] = 'root@localhost';
359
360                 // Conf for the Callback
361         if(!isset($this->config['callback']['context_callback']))    $this->config['callback']['context_callback'] = 'a2billing-callback';
362         if(!isset($this->config['callback']['ani_callback_delay']))    $this->config['callback']['ani_callback_delay'] = '10';
363         if(!isset($this->config['callback']['extension']))        $this->config['callback']['extension'] = '1000';
364         if(!isset($this->config['callback']['sec_avoid_repeate']))    $this->config['callback']['sec_avoid_repeate'] = '30';
365         if(!isset($this->config['callback']['timeout']))        $this->config['callback']['timeout'] = '20';
366         if(!isset($this->config['callback']['answer_call']))        $this->config['callback']['answer_call'] = '1';
367         if(!isset($this->config['callback']['nb_predictive_call']))    $this->config['callback']['nb_predictive_call'] = '10';
368         if(!isset($this->config['callback']['nb_day_wait_before_retry']))    $this->config['callback']['nb_day_wait_before_retry'] = '1';
369         if(!isset($this->config['callback']['context_preditctivedialer']))    $this->config['callback']['context_preditctivedialer'] = 'a2billing-predictivedialer';
370         if(!isset($this->config['callback']['predictivedialer_maxtime_tocall']))    $this->config['callback']['predictivedialer_maxtime_tocall'] = '5400';
371         if(!isset($this->config['callback']['sec_wait_before_callback']))    $this->config['callback']['sec_wait_before_callback'] = '10';
372
373         // Conf for the signup
374         if(!isset($this->config['signup']['enable_signup']))$this->config['signup']['enable_signup'] = '1';
375         if(!isset($this->config['signup']['credit']))        $this->config['signup']['credit'] = '0';
376         if(!isset($this->config['signup']['tariff']))        $this->config['signup']['tariff'] = '8';
377         if(!isset($this->config['signup']['activated']))    $this->config['signup']['activated'] = 't';
378         if(!isset($this->config['signup']['simultaccess']))    $this->config['signup']['simultaccess'] = '0';
379         if(!isset($this->config['signup']['typepaid']))        $this->config['signup']['typepaid'] = '0';
380         if(!isset($this->config['signup']['creditlimit']))    $this->config['signup']['creditlimit'] = '0';
381         if(!isset($this->config['signup']['runservice']))    $this->config['signup']['runservice'] = '0';
382         if(!isset($this->config['signup']['enableexpire']))    $this->config['signup']['enableexpire'] = '0';
383         if(!isset($this->config['signup']['expiredays']))    $this->config['signup']['expiredays'] = '0';
384
385         // Conf for Paypal
386         if(!isset($this->config['paypal']['item_name']))    $this->config['paypal']['item_name'] = 'Credit Purchase';
387         if(!isset($this->config['paypal']['currency_code']))    $this->config['paypal']['currency_code'] = 'USD';
388         if(!isset($this->config['paypal']['purchase_amount']))    $this->config['paypal']['purchase_amount'] = '5;10;15';
389         if(!isset($this->config['paypal']['paypal_fees']))   $this->config['paypal']['paypal_fees'] = '1';
390
391         // Conf for Backup
392         if(!isset($this->config['backup']['backup_path']))    $this->config['backup']['backup_path'] ='/tmp';
393         if(!isset($this->config['backup']['gzip_exe']))        $this->config['backup']['gzip_exe'] ='/bin/gzip';
394         if(!isset($this->config['backup']['gunzip_exe']))    $this->config['backup']['gunzip_exe'] ='/bin/gunzip';
395         if(!isset($this->config['backup']['mysqldump']))    $this->config['backup']['mysqldump'] ='/usr/bin/mysqldump';
396         if(!isset($this->config['backup']['pg_dump']))        $this->config['backup']['pg_dump'] ='/usr/bin/pg_dump';
397         if(!isset($this->config['backup']['mysql']))        $this->config['backup']['mysql'] ='/usr/bin/mysql';
398         if(!isset($this->config['backup']['psql']))        $this->config['backup']['psql'] ='/usr/bin/psql';
399         if(!isset($this->config['backup']['archive_data_x_month']))        $this->config['backup']['archive_data_x_month'] ='3';
400
401         // Conf for Customer Web UI
402         if(!isset($this->config['webcustomerui']['customerinfo']))    $this->config['webcustomerui']['customerinfo'] = '1';
403         if(!isset($this->config['webcustomerui']['sipiaxinfo']))    $this->config['webcustomerui']['sipiaxinfo'] = '1';
404         if(!isset($this->config['webcustomerui']['personalinfo']))    $this->config['webcustomerui']['personalinfo'] = '1';
405         if(!isset($this->config['webcustomerui']['cdr']))        $this->config['webcustomerui']['cdr'] = '1';
406         if(!isset($this->config['webcustomerui']['invoice']))        $this->config['webcustomerui']['invoice'] = '1';
407         if(!isset($this->config['webcustomerui']['voucher']))        $this->config['webcustomerui']['voucher'] = '1';
408         if(!isset($this->config['webcustomerui']['paypal']))        $this->config['webcustomerui']['paypal'] = '1';
409         if(!isset($this->config['webcustomerui']['speeddial']))        $this->config['webcustomerui']['speeddial'] = '1';
410         if(!isset($this->config['webcustomerui']['did']))        $this->config['webcustomerui']['did'] = '1';
411         if(!isset($this->config['webcustomerui']['ratecard']))        $this->config['webcustomerui']['ratecard'] = '1';
412         if(!isset($this->config['webcustomerui']['simulator']))        $this->config['webcustomerui']['simulator'] = '1';
413         if(!isset($this->config['webcustomerui']['callback']))        $this->config['webcustomerui']['callback'] = '1';
414         if(!isset($this->config['webcustomerui']['predictivedialer']))    $this->config['webcustomerui']['predictivedialer'] = '1';
415         if(!isset($this->config['webcustomerui']['webphone']))        $this->config['webcustomerui']['webphone'] = '1';
416         if(!isset($this->config['webcustomerui']['callerid']))        $this->config['webcustomerui']['callerid'] = '1';
417         if(!isset($this->config['webcustomerui']['limit_callerid']))    $this->config['webcustomerui']['limit_callerid'] = '5';
418         if(!isset($this->config['webcustomerui']['error_email']))    $this->config['webcustomerui']['error_email'] = 'root@localhost';
419         if(!isset($this->config['webcustomerui']['support']))    $this->config['webcustomerui']['support'] = '1';
420         if(!isset($this->config['webcustomerui']['notification']))    $this->config['webcustomerui']['notification'] = '1';
421         if(!isset($this->config['webcustomerui']['payment']))    $this->config['webcustomerui']['payment'] = '1';
422         // conf for the web ui
423         if(!isset($this->config['webui']['buddy_sip_file']))        $this->config['webui']['buddy_sip_file'] = '/etc/asterisk/additional_a2billing_sip.conf';
424         if(!isset($this->config['webui']['buddy_iax_file']))        $this->config['webui']['buddy_iax_file'] = '/etc/asterisk/additional_a2billing_iax.conf';
425         if(!isset($this->config['webui']['api_logfile']))        $this->config['webui']['api_logfile'] = '/tmp/api_ecommerce_request.log';
426         if(isset($this->config['webui']['api_ip_auth']))        $this->config['webui']['api_ip_auth'] = explode(";", $this->config['webui']['api_ip_auth']);
427
428         if(!isset($this->config['webui']['dir_store_mohmp3']))        $this->config['webui']['dir_store_mohmp3'] = '/var/lib/asterisk/mohmp3';
429         if(!isset($this->config['webui']['num_musiconhold_class']))    $this->config['webui']['num_musiconhold_class'] = 10;
430         if(!isset($this->config['webui']['show_help']))            $this->config['webui']['show_help'] = 1;
431         if(!isset($this->config['webui']['my_max_file_size_import']))    $this->config['webui']['my_max_file_size_import'] = 1024000;
432         if(!isset($this->config['webui']['dir_store_audio']))        $this->config['webui']['dir_store_audio'] = '/var/lib/asterisk/sounds/a2billing';
433         if(!isset($this->config['webui']['my_max_file_size_audio']))    $this->config['webui']['my_max_file_size_audio'] = 3072000;
434
435         if(isset($this->config['webui']['file_ext_allow']))        $this->config['webui']['file_ext_allow'] = explode(",", $this->config['webui']['file_ext_allow']);
436         else $this->config['webui']['file_ext_allow'] = explode(",", "gsm, mp3, wav");
437
438         if(isset($this->config['webui']['file_ext_allow_musiconhold']))    $this->config['webui']['file_ext_allow_musiconhold'] = explode(",", $this->config['webui']['file_ext_allow_musiconhold']);
439         else $this->config['webui']['file_ext_allow_musiconhold'] = explode(",", "mp3");
440
441         if(!isset($this->config['webui']['show_top_frame']))         $this->config['webui']['show_top_frame'] = 1;
442         if(!isset($this->config['webui']['currency_choose']))         $this->config['webui']['currency_choose'] = 'all';
443         if(!isset($this->config['webui']['card_export_field_list']))    $this->config['webui']['card_export_field_list'] = 'creationdate, username, credit, lastname, firstname';
444         if(!isset($this->config['webui']['voucher_export_field_list']))    $this->config['webui']['voucher_export_field_list'] = 'id, voucher, credit, tag, activated, usedcardnumber, usedate, currency';
445         if(!isset($this->config['webui']['advanced_mode']))                $this->config['webui']['advanced_mode'] = 0;
446         if(!isset($this->config['webui']['delete_fk_card']))            $this->config['webui']['delete_fk_card'] = 1;
447
448         // conf for the recurring process
449         if(!isset($this->config["recprocess"]['batch_log_file']))     $this->config["recprocess"]['batch_log_file'] = '/tmp/batch-a2billing.log';
450
451         // conf for the peer_friend
452         if(!isset($this->config['peer_friend']['type']))         $this->config['peer_friend']['type'] = 'friend';
453         if(!isset($this->config['peer_friend']['allow']))         $this->config['peer_friend']['allow'] = 'ulaw,alaw,gsm,g729';
454         if(!isset($this->config['peer_friend']['context']))     $this->config['peer_friend']['context'] = 'a2billing';
455         if(!isset($this->config['peer_friend']['nat']))         $this->config['peer_friend']['nat'] = 'yes';
456         if(!isset($this->config['peer_friend']['amaflags']))     $this->config['peer_friend']['amaflags'] = 'billing';
457         if(!isset($this->config['peer_friend']['qualify']))     $this->config['peer_friend']['qualify'] = 'yes';
458         if(!isset($this->config['peer_friend']['host']))         $this->config['peer_friend']['host'] = 'dynamic';
459         if(!isset($this->config['peer_friend']['dtmfmode']))     $this->config['peer_friend']['dtmfmode'] = 'RFC2833';
460
461
462         //conf for the notifications
463         if(!isset($this->config['notifications']['values_notifications'])) $this->config['notifications']['values_notifications'] = '0';
464         if(!isset($this->config['notifications']['cron_notifications'])) $this->config['notifications']['cron_notifications'] = '1';
465         if(!isset($this->config['notifications']['delay_notifications'])) $this->config['notifications']['delay_notifications'] = '1';
466
467         // conf for the log-files
468         if(isset($this->config['log-files']['agi']) && strlen ($this->config['log-files']['agi']) > 1)
469         {
470             $this -> log_file = $this -> config['log-files']['agi'];
471         }
472         define ("LOGFILE_CRONT_ALARM",             isset($this->config['log-files']['cront_alarm'])            ?$this->config['log-files']['cront_alarm']:null);
473         define ("LOGFILE_CRONT_AUTOREFILL",     isset($this->config['log-files']['cront_autorefill'])        ?$this->config['log-files']['cront_autorefill']:null);
474         define ("LOGFILE_CRONT_BATCH_PROCESS",     isset($this->config['log-files']['cront_batch_process'])    ?$this->config['log-files']['cront_batch_process']:null);
475         define ("LOGFILE_CRONT_ARCHIVE_DATA",     isset($this->config['log-files']['cront_archive_data'])    ?$this->config['log-files']['cront_archive_data']:null);
476         define ("LOGFILE_CRONT_BILL_DIDUSE",     isset($this->config['log-files']['cront_bill_diduse'])        ?$this->config['log-files']['cront_bill_diduse']:null);
477         define ("LOGFILE_CRONT_SUBSCRIPTIONFEE",isset($this->config['log-files']['cront_subscriptionfee'])    ?$this->config['log-files']['cront_subscriptionfee']:null);
478         define ("LOGFILE_CRONT_CURRENCY_UPDATE",isset($this->config['log-files']['cront_currency_update'])    ?$this->config['log-files']['cront_currency_update']:null);
479         define ("LOGFILE_CRONT_INVOICE",        isset($this->config['log-files']['cront_invoice'])            ?$this->config['log-files']['cront_invoice']:null);
480         define ("LOGFILE_CRONT_CHECKACCOUNT",    isset($this->config['log-files']['cront_check_account'])    ?$this->config['log-files']['cront_check_account']:null);
481
482         define ("LOGFILE_API_ECOMMERCE",         isset($this->config['log-files']['api_ecommerce'])            ?$this->config['log-files']['api_ecommerce']:null);
483         define ("LOGFILE_API_CALLBACK",         isset($this->config['log-files']['api_callback'])            ?$this->config['log-files']['api_callback']:null);
484         define ("LOGFILE_PAYPAL",                 isset($this->config['log-files']['paypal'])                    ?$this->config['log-files']['paypal']:null);
485         define ("LOGFILE_EPAYMENT",             isset($this->config['log-files']['epayment'])                ?$this->config['log-files']['epayment']:null);
486
487
488         // conf for the AGI
489         if(!isset($this->config["agi-conf$idconfig"]['play_audio']))     $this->config["agi-conf$idconfig"]['play_audio'] = 1;
490         define ("PLAY_AUDIO",                                             $this->config["agi-conf$idconfig"]['play_audio']);
491
492         if(!isset($this->config["agi-conf$idconfig"]['debug']))     $this->config["agi-conf$idconfig"]['debug'] = false;
493         if(!isset($this->config["agi-conf$idconfig"]['logger_enable'])) $this->config["agi-conf$idconfig"]['logger_enable'] = 1;
494         if(!isset($this->config["agi-conf$idconfig"]['log_file'])) $this->config["agi-conf$idconfig"]['log_file'] = '/tmp/a2billing.log';
495
496         if(!isset($this->config["agi-conf$idconfig"]['answer_call'])) $this->config["agi-conf$idconfig"]['answer_call'] = 1;
497         if(!isset($this->config["agi-conf$idconfig"]['auto_setcallerid'])) $this->config["agi-conf$idconfig"]['auto_setcallerid'] = 1;
498         if(!isset($this->config["agi-conf$idconfig"]['say_goodbye'])) $this->config["agi-conf$idconfig"]['say_goodbye'] = 0;
499         if(!isset($this->config["agi-conf$idconfig"]['play_menulanguage'])) $this->config["agi-conf$idconfig"]['play_menulanguage'] = 0;
500         if(!isset($this->config["agi-conf$idconfig"]['force_language'])) $this->config["agi-conf$idconfig"]['force_language'] = 'EN';
501         if(!isset($this->config["agi-conf$idconfig"]['min_credit_2call'])) $this->config["agi-conf$idconfig"]['min_credit_2call'] = 0;
502         if(!isset($this->config["agi-conf$idconfig"]['min_duration_2bill'])) $this->config["agi-conf$idconfig"]['min_duration_2bill'] = 0;
503
504         if(!isset($this->config["agi-conf$idconfig"]['use_dnid'])) $this->config["agi-conf$idconfig"]['use_dnid'] = 0;
505         // Explode the no_auth_dnid string
506         if(isset($this->config["agi-conf$idconfig"]['no_auth_dnid'])) $this->config["agi-conf$idconfig"]['no_auth_dnid'] = explode(",",$this->config["agi-conf$idconfig"]['no_auth_dnid']);
507
508         // Explode the international_prefixes, extracharge_did and extracharge_fee strings
509         if(isset($this->config["agi-conf$idconfig"]['extracharge_did'])) $this->config["agi-conf$idconfig"]['extracharge_did'] = explode(",",$this->config["agi-conf$idconfig"]['extracharge_did']);
510         if(isset($this->config["agi-conf$idconfig"]['extracharge_fee'])) $this->config["agi-conf$idconfig"]['extracharge_fee'] = explode(",",$this->config["agi-conf$idconfig"]['extracharge_fee']);
511         if(isset($this->config["agi-conf$idconfig"]['extracharge_buyfee'])) $this->config["agi-conf$idconfig"]['extracharge_buyfee'] = explode(",",$this->config["agi-conf$idconfig"]['extracharge_buyfee']);
512
513         if(isset($this->config["agi-conf$idconfig"]['international_prefixes'])) {
514             $this->config["agi-conf$idconfig"]['international_prefixes'] = explode(",",$this->config["agi-conf$idconfig"]['international_prefixes']);
515         } else {
516             // to retain config file compatibility assume a default unless config option is set
517             $this->config["agi-conf$idconfig"]['international_prefixes'] = explode(",","011,09,00,1");
518         }
519
520
521
522         if(!isset($this->config["agi-conf$idconfig"]['number_try'])) $this->config["agi-conf$idconfig"]['number_try'] = 3;
523         if(!isset($this->config["agi-conf$idconfig"]['say_balance_after_auth'])) $this->config["agi-conf$idconfig"]['say_balance_after_auth'] = 1;
524         if(!isset($this->config["agi-conf$idconfig"]['say_balance_after_call'])) $this->config["agi-conf$idconfig"]['say_balance_after_call'] = 0;
525         if(!isset($this->config["agi-conf$idconfig"]['say_rateinitial'])) $this->config["agi-conf$idconfig"]['say_rateinitial'] = 0;
526         if(!isset($this->config["agi-conf$idconfig"]['say_timetocall'])) $this->config["agi-conf$idconfig"]['say_timetocall'] = 1;
527         if(!isset($this->config["agi-conf$idconfig"]['cid_enable'])) $this->config["agi-conf$idconfig"]['cid_enable'] = 0;
528         if(!isset($this->config["agi-conf$idconfig"]['cid_sanitize'])) $this->config["agi-conf$idconfig"]['cid_sanitize'] = 0;
529         if(!isset($this->config["agi-conf$idconfig"]['cid_askpincode_ifnot_callerid'])) $this->config["agi-conf$idconfig"]['cid_askpincode_ifnot_callerid'] = 1;
530         if(!isset($this->config["agi-conf$idconfig"]['cid_auto_assign_card_to_cid'])) $this->config["agi-conf$idconfig"]['cid_auto_assign_card_to_cid'] = 0;
531         if(!isset($this->config["agi-conf$idconfig"]['notenoughcredit_cardnumber'])) $this->config["agi-conf$idconfig"]['notenoughcredit_cardnumber'] = 0;
532         if(!isset($this->config["agi-conf$idconfig"]['notenoughcredit_assign_newcardnumber_cid'])) $this->config["agi-conf$idconfig"]['notenoughcredit_assign_newcardnumber_cid'] = 0;
533         if(!isset($this->config["agi-conf$idconfig"]['maxtime_tocall_negatif_free_route'])) $this->config["agi-conf$idconfig"]['maxtime_tocall_negatif_free_route'] = 1800;
534         if(!isset($this->config["agi-conf$idconfig"]['callerid_authentication_over_cardnumber'])) $this->config["agi-conf$idconfig"]['callerid_authentication_over_cardnumber'] = 0;
535         if(!isset($this->config["agi-conf$idconfig"]['cid_auto_create_card_len'])) $this->config["agi-conf$idconfig"]['cid_auto_create_card_len'] = 10;
536
537         if(!isset($this->config["agi-conf$idconfig"]['sip_iax_friends'])) $this->config["agi-conf$idconfig"]['sip_iax_friends'] = 0;
538         if(!isset($this->config["agi-conf$idconfig"]['sip_iax_pstn_direct_call'])) $this->config["agi-conf$idconfig"]['sip_iax_pstn_direct_call'] = 0;
539         if(!isset($this->config["agi-conf$idconfig"]['dialcommand_param'])) $this->config["agi-conf$idconfig"]['dialcommand_param'] = '|30|HL(%timeout%:61000:30000)';
540         if(!isset($this->config["agi-conf$idconfig"]['dialcommand_param_sipiax_friend'])) $this->config["agi-conf$idconfig"]['dialcommand_param_sipiax_friend'] = '|30|HL(3600000:61000:30000)';
541         if(!isset($this->config["agi-conf$idconfig"]['switchdialcommand'])) $this->config["agi-conf$idconfig"]['switchdialcommand'] = 0;
542         if(!isset($this->config["agi-conf$idconfig"]['failover_recursive_limit'])) $this->config["agi-conf$idconfig"]['failover_recursive_limit'] = 1;
543         if(!isset($this->config["agi-conf$idconfig"]['record_call'])) $this->config["agi-conf$idconfig"]['record_call'] = 0;
544         if(!isset($this->config["agi-conf$idconfig"]['monitor_formatfile'])) $this->config["agi-conf$idconfig"]['monitor_formatfile'] = 'gsm';
545         if(!isset($this->config["agi-conf$idconfig"]['currency_association']))    $this->config["agi-conf$idconfig"]['currency_association'] = 'all:credit';
546         $this->config["agi-conf$idconfig"]['currency_association'] = explode(",",$this->config["agi-conf$idconfig"]['currency_association']);
547
548         foreach($this->config["agi-conf$idconfig"]['currency_association'] as $cur_val) {
549             $cur_val = explode(":",$cur_val);
550             $this->config["agi-conf$idconfig"]['currency_association_internal'][$cur_val[0]]=$cur_val[1];
551         }
552
553         if(!isset($this->config["agi-conf$idconfig"]['currency_association_minor']))    $this->config["agi-conf$idconfig"]['currency_association_minor'] = 'all:prepaid-cents';
554         $this->config["agi-conf$idconfig"]['currency_association_minor'] = explode(",",$this->config["agi-conf$idconfig"]['currency_association_minor']);
555
556         foreach($this->config["agi-conf$idconfig"]['currency_association_minor'] as $cur_val) {
557             $cur_val = explode(":",$cur_val);
558             $this->config["agi-conf$idconfig"]['currency_association_minor_internal'][$cur_val[0]]=$cur_val[1];
559         }
560
561         if(!isset($this->config["agi-conf$idconfig"]['file_conf_enter_destination']))    $this->config["agi-conf$idconfig"]['file_conf_enter_destination'] = 'prepaid-enter-number-u-calling-1-or-011';
562         if(!isset($this->config["agi-conf$idconfig"]['file_conf_enter_menulang']))    $this->config["agi-conf$idconfig"]['file_conf_enter_menulang'] = 'prepaid-menulang';
563         if(!isset($this->config["agi-conf$idconfig"]['send_reminder'])) $this->config["agi-conf$idconfig"]['send_reminder'] = 0;
564         if(isset($this->config["agi-conf$idconfig"]['debugshell']) && $this->config["agi-conf$idconfig"]['debugshell'] == 1 && isset($agi)) $agi->nlinetoread = 0;
565
566         if(!isset($this->config["agi-conf$idconfig"]['ivr_voucher'])) $this->config["agi-conf$idconfig"]['ivr_voucher'] = 0;
567         if(!isset($this->config["agi-conf$idconfig"]['ivr_voucher_prefixe'])) $this->config["agi-conf$idconfig"]['ivr_voucher_prefixe'] = 8;
568         if(!isset($this->config["agi-conf$idconfig"]['jump_voucher_if_min_credit'])) $this->config["agi-conf$idconfig"]['jump_voucher_if_min_credit'] = 0;
569         if(!isset($this->config["agi-conf$idconfig"]['failover_lc_prefix'])) $this->config["agi-conf$idconfig"]['failover_lc_prefix'] = 0;
570
571         // Define the agiconfig property
572         $this->agiconfig = $this->config["agi-conf$idconfig"];
573
574         // Print out on CLI for debug purpose
575         if (!$webui) $this->conlog ('A2Billing AGI internal configuration:');
576         if (!$webui) $this->conlog (print_r($this->agiconfig, true));
577         return true;
578     }
579
580
581     /**
582     * Log to console if debug mode.
583     *
584     * @example examples/ping.php Ping an IP address
585     *
586     * @param string $str
587     * @param integer $vbl verbose level
588     */
589     function conlog($str, $vbl=1)
590     {
591         global $agi;
592         static $busy = false;
593
594         if($this->agiconfig['debug'] != false)
595         {
596             if(!$busy) // no conlogs inside conlog!!!
597             {
598               $busy = true;
599               if (isset($agi)) $agi->verbose($str, $vbl);
600               $busy = false;
601             }
602         }
603     }
604
605     /*
606      * Function to create a menu to select the language
607      */
608     function play_menulanguage ($agi)
609     {
610         // MENU LANGUAGE
611         if ($this->agiconfig['play_menulanguage']==1){
612             
613             $list_prompt_menulang = explode(':',$this->agiconfig['conf_order_menulang']);
614             $i=1;
615             foreach ($list_prompt_menulang as $lg_value ){
616                 $res_dtmf = $agi->get_data("menu_".$lg_value, 100, 1);
617                 if(!empty($res_dtmf["result"]) && is_numeric($res_dtmf["result"] && $res_dtmf["result"]>0))break;
618                 $res_dtmf = $agi->get_data("num_".$lg_value."_".$i,100, 1);
619                 if(!empty($res_dtmf["result"]) && is_numeric($res_dtmf["result"]) && $res_dtmf["result"]>0 )break;
620                 $i++;
621             }
622             
623             $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "RES Menu Language DTMF : ".$res_dtmf ["result"]);
624
625             $this -> languageselected = $res_dtmf ["result"];
626             
627             if($this -> languageselected>0 && $this -> languageselected<=sizeof($list_prompt_menulang) ){
628                 $language = $list_prompt_menulang[$this -> languageselected-1];
629             }else{
630                 if (strlen($this->agiconfig['force_language'])==2) {
631                     $language = strtolower($this->agiconfig['force_language']);
632                 } else {
633                     $language = 'en';
634                 }
635                 
636             }
637
638             $this ->current_language = $language
639             
640             $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, " CURRENT LANGUAGE : ".$language);
641             
642             
643             if($this->agiconfig['asterisk_version'] == "1_2") {
644                 $lg_var_set = 'LANGUAGE()';
645             } else {
646                 $lg_var_set = 'CHANNEL(language)';
647             }
648             $agi -> set_variable($lg_var_set, $language);
649             $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[SET $lg_var_set $language]");
650             $this->languageselected = 1;
651
652         } elseif (strlen($this->agiconfig['force_language'])==2) {
653
654             $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "FORCE LANGUAGE : ".$this->agiconfig['force_language']);
655             $this->languageselected = 1;
656             $language = strtolower($this->agiconfig['force_language']);
657             $this ->current_language = $language;
658             if($this->agiconfig['asterisk_version'] == "1_2") {
659                 $lg_var_set = 'LANGUAGE()';
660             } else {
661                 $lg_var_set = 'CHANNEL(language)';
662             }
663             $agi -> set_variable($lg_var_set, $language);
664             $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[SET $lg_var_set $language]");
665         }
666     }
667
668
669
670     /*
671      * intialize evironement variables from the agi values
672      */
673     function get_agi_request_parameter($agi)
674     {
675         $this->CallerID     = $agi->request['agi_callerid'];
676         $this->channel        = $agi->request['agi_channel'];
677         $this->uniqueid        = $agi->request['agi_uniqueid'];
678         $this->accountcode    = $agi->request['agi_accountcode'];
679         //$this->dnid        = $agi->request['agi_dnid'];
680         $this->dnid            = $agi->request['agi_extension'];
681         
682         //Call function to find the cid number
683         $this -> isolate_cid();
684
685         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, ' get_agi_request_parameter = '.$this->CallerID.' ; '.$this->channel.' ; '.$this->uniqueid.' ; '.$this->accountcode.' ; '.$this->dnid);
686     }
687
688
689
690     /*
691      *    function to find the cid number
692      */
693     function isolate_cid()
694     {
695         $pos_lt = strpos($this->CallerID, '<');
696         $pos_gt = strpos($this->CallerID, '>');
697
698         if (($pos_lt !== false) && ($pos_gt !== false)) {
699             $len_gt = $pos_gt - $pos_lt - 1;
700             $this->CallerID = substr($this->CallerID,$pos_lt+1,$len_gt);
701         }
702     }
703
704
705     /*
706      *    function would set when the card is used or when it release
707      */
708     function callingcard_acct_start_inuse($agi, $inuse)
709     {
710         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[CARD STATUS UPDATE]");
711         if ($inuse) {
712             $QUERY = "UPDATE cc_card SET inuse=inuse+1 WHERE username='".$this->username."'";
713             $this -> set_inuse = 1;
714         } else {
715             $QUERY = "UPDATE cc_card SET inuse=inuse-1 WHERE username='".$this->username."'";
716             $this -> set_inuse = 0;
717         }
718         
719         if (!$this -> CC_TESTING) $result = $this -> instance_table -> SQLExec ($this->DBHandle, $QUERY, 0);
720
721         return 0;
722     }
723
724
725
726     /**
727      *    Function callingcard_ivr_authorize : check the dialed/dialing number and play the time to call
728      *
729      *  @param object $agi
730      *  @param float $credit
731      *  @return 1 if Ok ; -1 if error
732     **/
733     function callingcard_ivr_authorize($agi, &$RateEngine, $try_num)
734     {
735         $res=0;
736
737         /**************     ASK DESTINATION     ******************/
738         $prompt_enter_dest = $this->agiconfig['file_conf_enter_destination'];
739
740         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__$this->agiconfig['use_dnid']." && ".in_array ($this->dnid, $this->agiconfig['no_auth_dnid'])." && ".strlen($this->dnid)."&& $try_num");
741
742         // CHECK IF USE_DNID IF NOT GET THE DESTINATION NUMBER
743         if ($this->agiconfig['use_dnid']==1 && !in_array ($this->dnid, $this->agiconfig['no_auth_dnid']) && strlen($this->dnid)>2 && $try_num==0){
744             $this->destination = $this->dnid;
745         }else{
746             $res_dtmf = $agi->get_data($prompt_enter_dest, 6000, 20);
747             $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "RES DTMF : ".$res_dtmf ["result"]);
748             $this->destination = $res_dtmf ["result"];
749         }
750         
751         //REDIAL FIND THE LAST DIALED NUMBER (STORED IN THE DATABASE)
752         if (strlen($this->destination)<=2 && is_numeric($this->destination) && $this->destination>=0){
753
754             $QUERY = "SELECT phone FROM cc_speeddial WHERE id_cc_card='".$this->id_card."' AND speeddial='".$this->destination."'";
755             $result = $this -> instance_table -> SQLExec ($this->DBHandle, $QUERY);
756             if( is_array($result))    $this->destination = $result[0][0];
757             $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "REDIAL : DESTINATION ::> ".$this->destination);
758         }
759         
760         // FOR TESTING : ENABLE THE DESTINATION NUMBER
761         if ($this->CC_TESTING) $this->destination="1800300200";
762         if ($this->CC_TESTING) $this->destination="3390010022";
763
764         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "DESTINATION ::> ".$this->destination);
765         if ($this->removeinterprefix) $this->destination = $this -> apply_rules ($this->destination);
766         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "RULES APPLY ON DESTINATION ::> ".$this->destination);
767
768         // TRIM THE "#"s IN THE END, IF ANY
769         // usefull for SIP or IAX friends with "use_dnid" when their device sends also the "#"
770         // it should be safe for normal use
771         $this->destination = rtrim($this->destination, "#");
772
773         // SAY BALANCE AND FT2C PACKAGE IF APPLICABLE
774         // this is hardcoded for now but we might have a setting in a2billing.conf for the combination
775         if ($this->destination=='*0'){
776             $this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "[SAY BALANCE ::> ".$this->credit."]");
777             $this -> fct_say_balance ($agi, $this->credit);
778
779             // Retrieve this customer's FT2C package details
780             $QUERY = "SELECT freetimetocall, label, packagetype, billingtype, startday, id_cc_package_offer FROM cc_card RIGHT JOIN cc_tariffgroup ON cc_tariffgroup.id=cc_card.tariff RIGHT JOIN cc_package_offer ON cc_package_offer.id=cc_tariffgroup.id_cc_package_offer WHERE cc_card.id='".$this->id_card."'";
781             $result = $this -> instance_table -> SQLExec ($this->DBHandle, $QUERY);
782             if (is_array($result) && ($result[0][0] > 0) ) {
783                 $freetime = $result[0][0];
784                 $label = $result[0][1];
785                 $packagetype = $result[0][2];
786                 $billingtype = $result[0][3];
787                 $startday = $result[0][4];
788                 $id_cc_package_offer = $result[0][5];
789                 $freetimetocall_used = $this->FT2C_used_seconds($this->DBHandle, $this->id_card, $id_cc_package_offer, $billingtype, $startday);
790                 
791                 //TO MANAGE BY PACKAGE TYPE IT -> only for freetime
792                 if (($packagetype == 0) || ($packagetype == 1)) {
793                     $minutes=intval(($freetime-$freetimetocall_used)/60);
794                     $seconds=($freetime-$freetimetocall_used) % 60;
795                 } else {
796                     $minutes=intval($freetimetocall_used/60);
797                     $seconds=$freetimetocall_used % 60;
798                 }
799                 // Now say either "You have X minutes and Y seconds of free package calls remaining this week/month"
800                 // or "You have dialed X minutes and Y seconds of free package calls this week/month"
801                 if (($packagetype == 0) || ($packagetype == 1)) {
802                     $agi-> stream_file('prepaid-you-have', '#');
803                 } else {
804                     $agi-> stream_file('prepaid-you-have-dialed', '#');
805                 }
806                 if (($minutes > 0) || ($seconds == 0)) {
807                     $agi->say_number($minutes);
808                     if ($minutes==1){
809                         $agi-> stream_file('prepaid-minute', '#');
810                     }else{
811                         
812                         if((strtolower($this->agiconfig['force_language'])=='ru')&& ( ( $minutes%10==2) || ($minutes%10==3 )|| ($minutes%10==4)) ){
813                             // test for the specific grammatical rules in RUssian
814                             $agi-> stream_file('prepaid-minute2', '#');
815                         }else{
816                             $agi-> stream_file('prepaid-minutes', '#');
817                         }
818                     }
819                 }
820                 if ($seconds > 0) {
821                     if ($minutes > 0) $agi-> stream_file('vm-and', '#');
822                     $agi->say_number($seconds);
823                     if ($seconds == 1) {
824                         $agi-> stream_file('prepaid-second', '#');
825                     } else {
826                         if((strtolower($this->agiconfig['force_language'])=='ru')&& ( ( $seconds%10==2) || ($seconds%10==3 )|| ($seconds%10==4)) ){
827                             // test for the specific grammatical rules in RUssian
828                             $agi-> stream_file('prepaid-second2', '#');
829                         }else{
830                             $agi-> stream_file('prepaid-seconds', '#');
831                         }
832                     }
833                 }
834                 $agi-> stream_file('prepaid-of-free-package-calls', '#');
835                 if (($packagetype == 0) || ($packagetype == 1)) {
836                     $agi-> stream_file('prepaid-remaining', '#');
837                     $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[SAY FT2C REMAINING ::> ".$minutes.":".$seconds."]");
838                 } else {
839                     $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[SAY FT2C USED ::> ".$minutes.":".$seconds."]");
840                 }
841                 $agi-> stream_file('this', '#');
842                 if ($billingtype == 0) {
843                     $agi-> stream_file('month', '#');
844                 } else {
845                     $agi-> stream_file('weeks', '#');
846                 }
847             }
848             return -1;
849         }
850
851         //REDIAL FIND THE LAST DIALED NUMBER (STORED IN THE DATABASE)
852         if ( $this->destination=='0*' ){
853             $this->destination = $this->redial;
854             $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[REDIAL : DTMF DESTINATION ::> ".$this->destination."]");
855         }
856
857         if ($this->destination<=0){
858             $prompt = "prepaid-invalid-digits";
859             // do not play the error message if the destination number is not numeric
860             // because most probably it wasn't entered by user (he has a phone keypad remember?)
861             // it helps with using "use_dnid" and extensions.conf routing
862             if (is_numeric($this->destination)) $agi-> stream_file($prompt, '#');
863             return -1;
864         }
865
866         // STRIP * FROM DESTINATION NUMBER
867         $this->destination = str_replace('*', '', $this->destination);
868
869         $this->save_redial_number($agi, $this->destination);
870         
871         // LOOKUP RATE : FIND A RATE FOR THIS DESTINATION
872         $resfindrate = $RateEngine->rate_engine_findrates($this, $this->destination,$this->tariff);
873         if ($resfindrate==0){
874             $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "ERROR ::> RateEngine didnt succeed to match the dialed number over the ratecard (Please check : id the ratecard is well create ; if the removeInter_Prefix is set according to your prefix in the ratecard ; if you hooked the ratecard to the Call Plan)");
875         }else{
876             $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "OK - RESFINDRATE::> ".$resfindrate);
877         }
878
879
880         // IF DONT FIND RATE
881         if ($resfindrate==0){
882             $prompt="prepaid-dest-unreachable";
883             $agi-> stream_file($prompt, '#');
884             return -1;
885         }
886
887         /*$rate=$result[0][0];
888         if ($rate<=0){
889             //$prompt="prepaid-dest-blocked";
890             $prompt="prepaid-dest-unreachable";
891             continue;
892         }*/
893
894
895         // CHECKING THE TIMEOUT
896         $res_all_calcultimeout = $RateEngine->rate_engine_all_calcultimeout($this, $this->credit);
897
898         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "RES_ALL_CALCULTIMEOUT ::> $res_all_calcultimeout");
899         if (!$res_all_calcultimeout){
900             $prompt="prepaid-no-enough-credit";
901             $agi-> stream_file($prompt, '#');
902             return -1;
903         }
904
905
906         // calculate timeout
907         //$this->timeout = intval(($this->credit * 60*100) / $rate);  // -- RATE is millime cents && credit is 1cents
908
909         $this->timeout = $RateEngine-> ratecard_obj[0]['timeout'];
910         $timeout = $this->timeout;
911         if ($this->agiconfig['cheat_on_announcement_time']==1){
912          $timeout = $RateEngine-> ratecard_obj[0]['timeout_without_rules'];   
913         }
914         // set destination and timeout
915         // say 'you have x minutes and x seconds'
916         $minutes = intval($timeout / 60);
917         $seconds = $timeout % 60;
918
919         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "TIMEOUT::> ".$this->timeout."  : minutes=$minutes - seconds=$seconds");
920         if (!($minutes>0)){
921             $prompt="prepaid-no-enough-credit";
922             $agi-> stream_file($prompt, '#');
923             return -1;
924         }
925
926         if ($this->agiconfig['say_rateinitial']==1){
927             $this -> fct_say_rate ($agi, $RateEngine->ratecard_obj[0][12]);
928         }
929
930         if ($this->agiconfig['say_timetocall']==1){
931             $agi-> stream_file('prepaid-you-have', '#');
932             if ($minutes>0){
933                 $agi->say_number($minutes);
934                 if ($minutes==1){
935                     $agi-> stream_file('prepaid-minute', '#');
936                 }else{
937                     if((strtolower($this->agiconfig['force_language'])=='ru')&& ( ( $minutes%10==2) || ($minutes%10==3 )|| ($minutes%10==4)) ){
938                             // test for the specific grammatical rules in RUssian
939                             $agi-> stream_file('prepaid-minute2', '#');
940                         }else{
941                             $agi-> stream_file('prepaid-minutes', '#');
942                         }
943
944                 }
945             }
946             if ($seconds>0 && ($this->agiconfig['disable_announcement_seconds']==0)){
947                 if ($minutes>0) $agi-> stream_file('vm-and', '#');
948
949                 $agi->say_number($seconds);
950                 if ($seconds==1){
951                     $agi-> stream_file('prepaid-second', '#');
952                 }else{
953                     if((strtolower($this->agiconfig['force_language'])=='ru')&& ( ( $seconds%10==2) || ($seconds%10==3 )|| ($seconds%10==4)) ){
954                                 // test for the specific grammatical rules in RUssian
955                         $agi-> stream_file('prepaid-second2', '#');
956                     }else{
957                         $agi-> stream_file('prepaid-seconds', '#');
958                     }
959                 }
960             }
961         }
962         return 1;
963     }
964
965
966     /**
967      *    Function call_sip_iax_buddy : make the Sip/IAX free calls
968      *
969      *  @param object $agi
970      *  @param object $RateEngine
971      *  @param integer $try_num
972      *  @return 1 if Ok ; -1 if error
973     **/
974     function call_sip_iax_buddy($agi, &$RateEngine, $try_num)
975     {
976         $res = 0;
977
978         if ( ($this->agiconfig['use_dnid']==1) && (!in_array ($this->dnid, $this->agiconfig['no_auth_dnid'])) && (strlen($this->dnid)>2 ))
979         {
980             $this->destination = $this->dnid;
981         } else {
982             $res_dtmf = $agi->get_data('prepaid-sipiax-enternumber', 6000, $this->config['global']['len_aliasnumber'], '#');
983             $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "RES DTMF : ".$res_dtmf ["result"]);
984             $this->destination = $res_dtmf ["result"];
985
986             if ($this->destination<=0) {
987                 return -1;
988             }
989         }
990
991         $this->save_redial_number($this->destination);
992
993         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "SIP o IAX DESTINATION : ".$this->destination);
994         $sip_buddies = 0;
995         $iax_buddies = 0;
996
997         $QUERY = "SELECT name FROM cc_iax_buddies, cc_card WHERE cc_iax_buddies.name=cc_card.username AND useralias='".$this->destination."'";
998         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, $QUERY);
999
1000         $result = $this -> instance_table -> SQLExec ($this->DBHandle, $QUERY);
1001         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, $result);
1002
1003         if( is_array($result) && count($result) > 0) {
1004             $iax_buddies = 1;
1005             $destiax=$result[0][0];
1006         }
1007
1008         $card_alias = $this->destination;
1009         $QUERY = "SELECT name FROM cc_sip_buddies, cc_card WHERE cc_sip_buddies.name=cc_card.username AND useralias='".$this->destination."'";
1010         $result = $this -> instance_table -> SQLExec ($this->DBHandle, $QUERY);
1011         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "RESULT : ".print_r($result,true));
1012         
1013         if( is_array($result) && count($result) > 0) {
1014             $sip_buddies = 1;
1015             $destsip=$result[0][0];
1016         }
1017
1018         if (!$sip_buddies && !$iax_buddies){
1019             $agi-> stream_file('prepaid-sipiax-num-nomatch', '#');
1020             return -1;
1021         }
1022         
1023         for ($k=0;$k< $sip_buddies+$iax_buddies;$k++)
1024         {
1025             if ($k==0 && $sip_buddies) {
1026                 $this->tech = 'SIP';
1027                 $this->destination= $destsip;
1028             } else {
1029                 $this->tech = 'IAX2';
1030                 $this->destination = $destiax;
1031             }
1032             if ($this -> CC_TESTING) $this->destination = "kphone";
1033
1034             if ($this->agiconfig['record_call'] == 1){
1035                 $myres = $agi->exec("MixMonitor {$this->uniqueid}.{$this->agiconfig['monitor_formatfile']}|b");
1036                 $this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "EXEC MixMonitor {$this->uniqueid}.{$this->agiconfig['monitor_formatfile']}|b");
1037             }
1038
1039             $agi->set_callerid($this->useralias);
1040             $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[EXEC SetCallerID : ".$this->useralias."]");
1041
1042             $dialparams = $this->agiconfig['dialcommand_param_sipiax_friend'];
1043             $dialstr = $this->tech."/".$this->destination.$dialparams;
1044
1045             $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "app_callingcard sip/iax friend: Dialing '$dialstr' ".$this->tech." Friend.\n");
1046
1047             //# Channel: technology/number@ip_of_gw_to PSTN
1048             // Dial(IAX2/guest@misery.digium.com/s@default)
1049             $myres = $agi->exec("DIAL $dialstr");
1050             $this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "DIAL");
1051
1052             $answeredtime = $agi->get_variable("ANSWEREDTIME");
1053             $answeredtime = $answeredtime['data'];
1054             $dialstatus = $agi->get_variable("DIALSTATUS");
1055             $dialstatus = $dialstatus['data'];
1056
1057             if ($this->agiconfig['record_call'] == 1) {
1058                 // Monitor(wav,kiki,m)
1059                 $myres = $agi->exec("STOPMONITOR");
1060                 $this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "EXEC StopMonitor (".$this->uniqueid."-".$this->cardnumber.")");
1061             }
1062
1063             $this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "[".$this->tech." Friend][K=$k]:[ANSWEREDTIME=".$answeredtime."-DIALSTATUS=".$dialstatus."]");
1064
1065             //# Ooh, something actually happend!
1066             if ($dialstatus  == "BUSY") {
1067                 $answeredtime=0;
1068                 $agi-> stream_file('prepaid-isbusy', '#');
1069             } elseif ($this->dialstatus == "NOANSWER") {
1070                 $answeredtime=0;
1071                 $agi-> stream_file('prepaid-noanswer', '#');
1072             } elseif ($dialstatus == "CANCEL") {
1073                 $answeredtime=0;
1074             } elseif ($dialstatus == "ANSWER") {
1075                 $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "-> dialstatus : $dialstatus, answered time is ".$answeredtime." \n");
1076             } elseif ($k+1 == $sip_buddies+$iax_buddies){
1077                 $prompt="prepaid-dest-unreachable";
1078                 $agi-> stream_file($prompt, '#');
1079             }
1080
1081             if (($dialstatus  == "CHANUNAVAIL") || ($dialstatus  == "CONGESTION"))    continue;
1082
1083             if ($answeredtime > 0){
1084                 $this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "[CC_RATE_ENGINE_UPDATESYSTEM: usedratecard K=$K - (answeredtime=$answeredtime :: dialstatus=$dialstatus :: cost=$cost)]");
1085                 $QUERY = "INSERT INTO cc_call (uniqueid,sessionid,username,nasipaddress,starttime,sessiontime, calledstation, ".
1086                     " terminatecause, stoptime, calledrate, sessionbill, calledcountry, calledsub, destination, id_tariffgroup, id_tariffplan, id_ratecard, id_trunk, src, sipiax) VALUES ".
1087                     "('".$this->uniqueid."', '".$this->channel."',  '".$this->username."', '".$this->hostname."',";
1088                 if ($this->config['database']['dbtype'] == "postgres"){
1089                     $QUERY .= " CURRENT_TIMESTAMP - interval '$answeredtime seconds' ";
1090                 }else{
1091                     $QUERY .= " CURRENT_TIMESTAMP - INTERVAL $answeredtime SECOND ";
1092                 }
1093                 $QUERY .= ", '$answeredtime', '".$card_alias."', '$dialstatus', now(), '0', '0', ".
1094                     " '".$this->countrycode."', '".$this->subcode."', '".$this->tech." CALL', '0', '0', '0', '0', '$this->CallerID', '1' )";
1095
1096                 $result = $this -> instance_table -> SQLExec ($this->DBHandle, $QUERY, 0);
1097                 return 1;
1098             }
1099         }
1100         if ($this->voicemail) {
1101             if (($dialstatus =="CHANUNAVAIL") || ($dialstatus == "CONGESTION") ||($dialstatus == "NOANSWER")) {
1102                 // The following section will send the caller to VoiceMail with the unavailable priority.
1103                 // $dest = "u".$card_alias;
1104                 $dest = $card_alias;
1105                 $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[STATUS] CHANNEL UNAVAILABLE - GOTO VOICEMAIL ($dest)");
1106                 $agi-> exec(VoiceMail,$dest);
1107             }
1108
1109             if (($dialstatus =="BUSY")) {
1110                 // The following section will send the caller to VoiceMail with the busy priority.
1111                 // $dest = "b".$card_alias;
1112                 $dest = $card_alias;
1113                 $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[STATUS] CHANNEL BUSY - GOTO VOICEMAIL ($dest)");
1114                 $agi-> exec(VoiceMail,$dest);
1115             }
1116         }
1117
1118         return -1;
1119     }
1120
1121
1122     /**
1123      *    Function call_did
1124      *
1125      *  @param object $agi
1126      *  @param object $RateEngine
1127      *  @param object $listdestination
1128          cc_did.id, cc_did_destination.id, billingtype, cc_did.id_trunk,    destination, cc_did.id_trunk, voip_call
1129
1130      *  @return 1 if Ok ; -1 if error
1131     **/
1132     function call_did ($agi, &$RateEngine, $listdestination)
1133     {
1134         $res=0;
1135
1136         if ($this -> CC_TESTING) $this->destination="kphone";
1137         $this->agiconfig['say_balance_after_auth']=0;
1138         $this->agiconfig['say_timetocall']=0;
1139
1140
1141         if (($listdestination[0][2]==0) || ($listdestination[0][2]==2)) {
1142             $doibill = 1;
1143         } else {
1144             $doibill = 0;
1145         }
1146
1147         $callcount=0;
1148         foreach ($listdestination as $inst_listdestination) {
1149             $callcount++;
1150
1151             $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[A2Billing] DID call friend: FOLLOWME=$callcount (cardnumber:".$inst_listdestination[6]."|destination:".$inst_listdestination[4]."|tariff:".$inst_listdestination[3].")\n");
1152
1153             $this->agiconfig['cid_enable']            = 0;
1154             $this->accountcode                 = $inst_listdestination[6];
1155             $this->tariff                     = $inst_listdestination[3];
1156             $this->destination                 = $inst_listdestination[4];
1157             $this->username                 = $inst_listdestination[6];
1158             $this->useralias                 = $inst_listdestination[7];
1159
1160             // MAKE THE AUTHENTICATION TO GET ALL VALUE : CREDIT - EXPIRATION - ...
1161             if ($this -> callingcard_ivr_authenticate($agi)!=0) {
1162                 $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[A2Billing] DID call friend: AUTHENTICATION FAILS !!!\n");
1163             } else {
1164                 // CHECK IF DESTINATION IS SET
1165                 if (strlen($inst_listdestination[4])==0) continue;
1166
1167                 // IF VOIP CALL
1168                 if ($inst_listdestination[5]==1){
1169
1170                     // RUN MIXMONITOR TO RECORD CALL
1171                     if ($this->agiconfig['record_call'] == 1){
1172                         $myres = $agi->exec("MixMonitor {$this->uniqueid}.{$this->agiconfig['monitor_formatfile']}|b");
1173                         $this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "EXEC MixMonitor {$this->uniqueid}.{$this->agiconfig['monitor_formatfile']}|b");
1174                     }
1175
1176                     $dialparams = $this->agiconfig['dialcommand_param_sipiax_friend'];
1177                     $dialstr     = $inst_listdestination[4].$dialparams;
1178
1179                     $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[A2Billing] DID call friend: Dialing '$dialstr' Friend.\n");
1180
1181                     //# Channel: technology/number@ip_of_gw_to PSTN
1182                     // Dial(IAX2/guest@misery.digium.com/s@default)
1183                     // DIAL OUT
1184                     $myres = $agi->exec("DIAL $dialstr");
1185                     $this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "DIAL");
1186
1187                     $answeredtime     = $agi->get_variable("ANSWEREDTIME");
1188                     $answeredtime     = $answeredtime['data'];
1189                     $dialstatus     = $agi->get_variable("DIALSTATUS");
1190                     $dialstatus     = $dialstatus['data'];
1191
1192                     if ($this->agiconfig['record_call'] == 1){
1193                         $myres = $agi->exec("STOPMONITOR");
1194                         $this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "EXEC StopMonitor (".$this->uniqueid."-".$this->cardnumber.")");
1195                     }
1196
1197                     $this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "[".$inst_listdestination[4]." Friend][followme=$callcount]:[ANSWEREDTIME=".$answeredtime."-DIALSTATUS=".$dialstatus."]");
1198
1199
1200                     //# Ooh, something actually happend!
1201                     if ($dialstatus  == "BUSY") {
1202                         $answeredtime=0;
1203                         $agi-> stream_file('prepaid-isbusy', '#');
1204                         // FOR FOLLOWME IF THERE IS MORE WE PASS TO THE NEXT ONE OTHERWISE WE NEED TO LOG THE CALL MADE
1205                         if (count($listdestination)>$callcount) continue;
1206                     } elseif ($this->dialstatus == "NOANSWER") {
1207                         $answeredtime=0;
1208                         $agi-> stream_file('prepaid-callfollowme', '#');
1209                         // FOR FOLLOWME IF THERE IS MORE WE PASS TO THE NEXT ONE OTHERWISE WE NEED TO LOG THE CALL MADE
1210                         if (count($listdestination)>$callcount) continue;
1211                     } elseif ($dialstatus == "CANCEL") {
1212                         $answeredtime=0;
1213                         // FOR FOLLOWME IF THERE IS MORE WE PASS TO THE NEXT ONE OTHERWISE WE NEED TO LOG THE CALL MADE
1214                         if (count($listdestination)>$callcount) continue;
1215                     } elseif ($dialstatus == "ANSWER") {
1216                         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[A2Billing] DID call friend: dialstatus : $dialstatus, answered time is ".$answeredtime." \n");
1217                     } elseif (($dialstatus  == "CHANUNAVAIL") || ($dialstatus  == "CONGESTION")) {
1218                         $answeredtime=0;
1219                         // FOR FOLLOWME IF THERE IS MORE WE PASS TO THE NEXT ONE OTHERWISE WE NEED TO LOG THE CALL MADE
1220                         if (count($listdestination)>$callcount) continue;
1221                     } else{
1222                         $agi-> stream_file('prepaid-callfollowme', '#');
1223                         // FOR FOLLOWME IF THERE IS MORE WE PASS TO THE NEXT ONE OTHERWISE WE NEED TO LOG THE CALL MADE
1224                         if (count($listdestination)>$callcount) continue;
1225                     }
1226
1227                     if ($answeredtime >0) {
1228
1229                         $this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "[DID CALL - LOG CC_CALL: FOLLOWME=$callcount - (answeredtime=$answeredtime :: dialstatus=$dialstatus :: cost=$cost)]");
1230
1231                         $QUERY = "INSERT INTO cc_call (uniqueid,sessionid,username,nasipaddress,starttime,sessiontime, calledstation, ".
1232                             " terminatecause, stoptime, calledrate, sessionbill, calledcountry, calledsub, destination, id_tariffgroup, id_tariffplan, id_ratecard, id_trunk, src, sipiax) VALUES ".
1233                             "('".$this->uniqueid."', '".$this->channel."',  '".$this->username."', '".$this->hostname."',";
1234                         if ($this->config['database']['dbtype'] == "postgres"){
1235                             $QUERY .= " CURRENT_TIMESTAMP - interval '$answeredtime seconds' ";
1236                         }else{
1237                             $QUERY .= " CURRENT_TIMESTAMP - INTERVAL $answeredtime SECOND ";
1238                         }
1239                         $QUERY .= ", '$answeredtime', '".$inst_listdestination[4]."', '$dialstatus', now(), '0', '0', ".
1240                             " '".$this->countrycode."', '".$this->subcode."', 'DID CALL', '0', '0', '0', '0', '$this->CallerID', '3' )";
1241
1242                         $result = $this -> instance_table -> SQLExec ($this->DBHandle, $QUERY, 0);
1243                         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[DID CALL - LOG CC_CALL: SQL: $QUERY]:[result:$result]");
1244
1245                         // CC_DID & CC_DID_DESTINATION - cc_did.id, cc_did_destination.id
1246                         $QUERY = "UPDATE cc_did SET secondusedreal = secondusedreal + $answeredtime WHERE id='".$inst_listdestination[0]."'";
1247                         $result = $this->instance_table -> SQLExec ($this -> DBHandle, $QUERY, 0);
1248                         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[UPDATE DID]:[result:$result]");
1249
1250                         $QUERY = "UPDATE cc_did_destination SET secondusedreal = secondusedreal + $answeredtime WHERE id='".$inst_listdestination[1]."'";
1251                         $result = $this->instance_table -> SQLExec ($this -> DBHandle, $QUERY, 0);
1252                         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[UPDATE DID_DESTINATION]:[result:$result]");
1253
1254                         return 1;
1255                     }
1256
1257                 // ELSEIF NOT VOIP CALL
1258                 } else {
1259
1260                     $this->agiconfig['use_dnid']=1;
1261                     $this->agiconfig['say_timetocall']=0;
1262
1263                     $this->dnid = $this->destination = $inst_listdestination[4];
1264                     if ($this->CC_TESTING) $this->dnid = $this->destination="011324885";
1265
1266
1267                     if ($this -> callingcard_ivr_authorize($agi, $RateEngine, 0)==1){
1268
1269                         // PERFORM THE CALL
1270                         $result_callperf = $RateEngine->rate_engine_performcall ($agi, $this -> destination, $this);
1271                         if (!$result_callperf) {
1272                             $prompt="prepaid-callfollowme";
1273                             $agi-> stream_file($prompt, '#');
1274                             continue;
1275                         }
1276
1277                         $dialstatus = $RateEngine->dialstatus;
1278                         if (($RateEngine->dialstatus == "NOANSWER") || ($RateEngine->dialstatus == "CANCEL") || ($RateEngine->dialstatus == "BUSY") || ($RateEngine->dialstatus == "CHANUNAVAIL") || ($RateEngine->dialstatus == "CONGESTION")) continue;
1279
1280                         // INSERT CDR  & UPDATE SYSTEM
1281                         $RateEngine->rate_engine_updatesystem($this, $agi, $this-> destination, $doibill, 1);
1282                         // CC_DID & CC_DID_DESTINATION - cc_did.id, cc_did_destination.id
1283                         $QUERY = "UPDATE cc_did SET secondusedreal = secondusedreal + ".$RateEngine->answeredtime." WHERE id='".$inst_listdestination[0]."'";
1284                         $result = $this->instance_table -> SQLExec ($this -> DBHandle, $QUERY, 0);
1285                         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[UPDATE DID]:[result:$result]");
1286
1287                         $QUERY = "UPDATE cc_did_destination SET secondusedreal = secondusedreal + ".$RateEngine->answeredtime." WHERE id='".$inst_listdestination[1]."'";
1288                         $result = $this->instance_table -> SQLExec ($this -> DBHandle, $QUERY, 0);
1289                         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[UPDATE DID_DESTINATION]:[result:$result]");
1290                         
1291                         // THEN STATUS IS ANSWER
1292                         break;
1293                     }
1294                 }
1295             } // END IF AUTHENTICATE
1296         }// END FOR
1297         
1298         if ($this->voicemail) {
1299             if (($dialstatus =="CHANUNAVAIL") || ($dialstatus == "CONGESTION") ||($dialstatus == "NOANSWER")) {
1300                 // The following section will send the caller to VoiceMail with the unavailable priority.
1301                 // $dest = "u".$this->useralias;
1302                 $dest = $this->useralias;
1303                 $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[STATUS] CHANNEL UNAVAILABLE - GOTO VOICEMAIL ($dest)");
1304                 $agi-> exec(VoiceMail,$dest);
1305             }
1306
1307             if (($dialstatus =="BUSY")) {
1308                 // The following section will send the caller to VoiceMail with the busy priority.
1309                 // $dest = "b".$this->useralias;
1310                 $dest = $this->useralias;
1311                 $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[STATUS] CHANNEL BUSY - GOTO VOICEMAIL ($dest)");
1312                 $agi-> exec(VoiceMail,$dest);
1313             }
1314         }
1315     }
1316
1317
1318     /**
1319      *    Function to play the balance
1320      *     format : "you have 100 dollars and 28 cents"
1321      *
1322      *  @param object $agi
1323      *  @param float $credit
1324      *  @return nothing
1325     **/
1326     function fct_say_balance ($agi, $credit, $fromvoucher = 0)
1327     {
1328         global $currencies_list;
1329
1330         if (isset($this->agiconfig['agi_force_currency']) && strlen($this->agiconfig['agi_force_currency'])==3)
1331         {
1332             $this->currency = $this->agiconfig['agi_force_currency'];
1333         }
1334
1335         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[CURRENCY : $this->currency]");
1336         if (!isset($currencies_list[strtoupper($this->currency)][2]) || !is_numeric($currencies_list[strtoupper($this->currency)][2])) $mycur = 1;
1337         else $mycur = $currencies_list[strtoupper($this->currency)][2];
1338         $credit_cur = $credit / $mycur;
1339
1340         list($units, $cents)=split('[.]', sprintf('%01.2f', $credit_cur));
1341
1342         $this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "[BEFORE: $credit_cur SPRINTF : ".sprintf('%01.2f', $credit_cur)."]");
1343
1344         if (isset($this->