AF
Asterisk Forum
обсуждения телефонии, VoIP и IP-PBX
12разделов
5 423тем
34 385сообщений
← К списку тем

A2Billing v1.3.x BUGS

Биллинг 15 сообщений -
#1

Сюда постить только найденные баги в этом биллинге и их решения.
#3

SIP/IAX buddies - Not being deleted

Если удалить эккаунт, не зависмо что стоит в конфиге в строке:
Цитата:
; Delete the SIP/IAX Friend & callerid when a card is deleted
delete_fk_card = yes

- sip/iax2 записи остаются в соответствующих конфигах и не удаляются.
Патч для этого бага (присутствует во всех версиях, включая и 1.3.1):
http://forum.asterisk2billing.org/viewto ... 1309#11309
#6

v 1.3.1 (1.3.3 Fixed)
/var/lib/asterisk/agi-bin/libs_a2billing/Class.RateEngine.php[415]: Undefined variable: callbackrate
В том же файле в строке 399
Код:
$callback_rate = array();

Меняем на
Код:
$callbackrate = array();


/var/lib/asterisk/agi-bin/libs_a2billing/Class.RateEngine.php[660]: Undefined variable: agi
/var/lib/asterisk/agi-bin/libs_a2billing/Class.RateEngine.php[699]: Undefined variable: agi
/var/lib/asterisk/agi-bin/libs_a2billing/Class.RateEngine.php[776]: Undefined variable: agi

В том же файле строка 641, вставляем первой строкой в функции rate_engine_calculcost
Код:
global $agi;


Последний раз редактировалось: busc (Ср Май 28, 2008 08:19)
#7

v 1.3.1, 1.3.3
Привязка и отвязка DID to CardHolder.
Система позволяет привязывать один и тотже DID в разное время одному и тому же CardHolder-у.
A2Customer_UI/A2B_entity_did.php. Строка 72
Код:
$QUERY = "UPDATE cc_did_use SET releasedate = now() WHERE id_did =$choose_did and activated = 1" ;

A2Customer_UI/A2B_entity_did.php. Строка 151
Код:
$QUERY1 = "UPDATE cc_did_use set releasedate = now() where id_did = '".$choose_did."' and activated = 0" ;

При выполнении такого запроса будут проапдейтчены кроме текущей записи еще и записи предыдущих привязок (Поломаем историю использования DID)
Меняем
Код:
72: $QUERY = "UPDATE cc_did_use SET releasedate = now() WHERE id_did =$choose_did and activated = 1 AND ( releasedate IS NULL OR releasedate < '1984-01-01 00:00:00')" ;
152: $QUERY1 = "UPDATE cc_did_use set releasedate = now() where id_did =$choose_did and activated = 0 AND ( releasedate IS NULL OR releasedate < '1984-01-01 00:00:00')" ;


Последний раз редактировалось: busc (Ср Май 28, 2008 08:22)
#8

спасибо!
ps: проапдейтиться до 1.3.2 не желаете? между 1.3.1 и 1.3.2 огромное количество фиксов!
а сам процесс апдейта очень прост и без потери данных.
#9

В версии 1.3.1 не сохраняется cc_call.id_did в случае входящих звонков на DID номера.
т.е. в детализации видим clid (cc_call.src), destination (сс_call.calledstation), а dialednumber (собственно сам DID) не видим.
Да и clid тоже не достаточно в ситуации с исходящим звонком, когда 2 SIP_buddie на одном карточном счете.
В этом случае есть номер счета (cc_call.username), есть clid (cc_call.src), есть destination (сс_call.calledstation), а инициатора (SIP_buddie) нет. Он есть в session-id, можно выкусывать, но ведь структура session-id может меняться.
Вопрос к использующим - "Что в версии 1.3.2 из перечисленного поправлено?" Если это вообще считать багом...
#10

Версия 1.3.1, 1.3.3
Class.A2Billing.php

Функции call_sip_iax_buddy и call_did, ищем
Код:
...
//# Ooh, something actually happend!
if ($dialstatus == "BUSY") {
$answeredtime=0;
$agi-> stream_file('prepaid-isbusy', '#');
} elseif ($this->dialstatus == "NOANSWER") {
$answeredtime=0;
$agi-> stream_file('prepaid-noanswer', '#');
...

в строке
elseif ($this->dialstatus == "NOANSWER")
такого свойства у объекта нет!
меняем на
elseif ($dialstatus == "NOANSWER")

Added after 12 minutes:

Функция call_sip_iax_buddy
$this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "[CC_RATE_ENGINE_UPDATESYSTEM: usedratecard K=$K - (answeredtime=$answeredtime :: dialstatus=$dialstatus :: cost=$cost)]");
убираем или ставим 0, переменная даже не объявлена, а в базу вставляется 0
$this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "[CC_RATE_ENGINE_UPDATESYSTEM: usedratecard K=$K - (answeredtime=$answeredtime :: dialstatus=$dialstatus :: cost=0)]");

Функция call_did
$this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "[DID CALL - LOG CC_CALL: FOLLOWME=$callcount - (answeredtime=$answeredtime :: dialstatus=$dialstatus :: cost=$cost)]");
убираем или ставим 0, переменная даже не объявлена, а в базу вставляется 0
$this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "[DID CALL - LOG CC_CALL: FOLLOWME=$callcount - (answeredtime=$answeredtime :: dialstatus=$dialstatus :: cost=0)]");

Версия 1.3.1
Class.Table.php
По всему файлу используется переменная $sp которой нет, есть свойство объекта sp,
Баг не критикал. Используется только в запросах для экранирования имен таблиц, полей и передаваемых значений.
Но я лично люблю чтобы все было красиво, поэтому :

Сначала в начале объявлении класса
Код:
var $sp = "`"; //bound_caract

меняем на
Код:
var $sp = ""; //bound_caract


Потом
PATCH
Код:
Index: .
===================================================================
--- . (revision 551)
+++ . (working copy)
@@ -150,7 +150,7 @@

$sql_orderby = '';
if ( !is_null ($order) && ($order!='') && !is_null ($sens) && ($sens!='') ) {
- $sql_orderby = " ORDER BY $sp".$order."$sp $sens";
+ $sql_orderby = " ORDER BY {$this->sp}".$order."{$this->sp} $sens";
}

$sql_limit ='';
@@ -228,9 +228,9 @@
$this -> table = $func_table;
}
if ($subquery) {
- $QUERY = "INSERT INTO $sp".$this -> table."$sp (".$this -> fields.") (".trim ($value).")";
+ $QUERY = "INSERT INTO {$this->sp}".$this -> table."{$this->sp} (".$this -> fields.") (".trim ($value).")";
} else {
- $QUERY = "INSERT INTO $sp".$this -> table."$sp (".$this -> fields.") values (".trim ($value).")";
+ $QUERY = "INSERT INTO {$this->sp}".$this -> table."{$this->sp} (".$this -> fields.") values (".trim ($value).")";
}
if ($this -> debug_st) {
echo $this->start_message_debug.$QUERY.$this->end_message_debug;
@@ -288,7 +288,7 @@
$this -> table = $func_table;
}

- $QUERY = "UPDATE $sp".$this -> table."$sp SET ".trim ($param_update)." WHERE ".trim ($clause);
+ $QUERY = "UPDATE {$this->sp}".$this -> table."{$this->sp} SET ".trim ($param_update)." WHERE ".trim ($clause);
if ($this -> debug_st) {
echo $this->start_message_debug.$QUERY.$this->end_message_debug;
}
@@ -320,11 +320,11 @@
$countFK = count($this->FK_TABLES);
for ($i = 0; $i < $countFK; $i++) {
if ($this -> FK_DELETE == false) {
- $QUERY = "UPDATE $sp".$this -> FK_TABLES[$i]."$sp SET ".
+ $QUERY = "UPDATE {$this->sp}".$this -> FK_TABLES[$i]."{$this->sp} SET ".
trim ($this -> FK_EDITION_CLAUSE[$i])." = -1 WHERE (".trim ($this -> FK_EDITION_CLAUSE[$i])." = ".$this -> FK_ID_VALUE." )";
} else {
- $QUERY = "DELETE FROM $sp".$this -> FK_TABLES[$i].
- "$sp WHERE (".trim ($this -> FK_EDITION_CLAUSE[$i])." = ".$this -> FK_ID_VALUE." )";
+ $QUERY = "DELETE FROM {$this->sp}".$this -> FK_TABLES[$i].
+ "{$this->sp} WHERE (".trim ($this -> FK_EDITION_CLAUSE[$i])." = ".$this -> FK_ID_VALUE." )";
}
if ($this -> debug_st) echo "
$QUERY";
$res = $DBHandle -> Execute($QUERY);
@@ -330,7 +330,7 @@
$res = $DBHandle -> Execute($QUERY);
}

- $QUERY = "DELETE FROM $sp".$this -> table."$sp WHERE (".trim ($clause).")";
+ $QUERY = "DELETE FROM {$this->sp}".$this -> table."{$this->sp} WHERE (".trim ($clause).")";
if ($this -> debug_st) {
echo $this->start_message_debug.$QUERY.$this->end_message_debug;
}
Код:


Последний раз редактировалось: busc (Ср Май 28, 2008 08:29)
#11

Версия 1.3.3
module.access.php
function login ($user, $pass)

Если пользователь в базе отсутствует, то будет выдана ошибка уровня error=3
"Ваш Аккаунт заблокирован, пожалуйста свяжитесь с администратором!"
Вместо error=1 "В доступе отказано, проверьте Ваш логин/пароль!"

Предлагаемое решение (проверяем пустой ли recordset):
Код:
function login ($user, $pass) {
global $DBHandle;
$user = trim($user);
$pass = trim($pass);
if (strlen($user)==0 || strlen($user)>=50 || strlen($pass)==0 || strlen($pass)>=50) return false;

$QUERY = "SELECT username, credit, activated, id, id_didgroup, tariff, vat, activatedbyuser FROM cc_card WHERE (email = '".$user."' OR useralias = '".$user."') AND uipass = '".$pass."'";
$res = $DBHandle -> Execute($QUERY);

if (!$res) {
$errstr = $DBHandle->ErrorMsg();
return (false);
}

$row [] =$res -> fetchRow();

if( ! is_array($row[0]) ) {

if( $row [0][2] != "t" && $row [0][2] != "1" ) {
return -1;
}

if( ACTIVATEDBYUSER==1 && $row [0][7] != "t" && $row [0][7] != "1" ) {
return -2;
}
}

return ($row[0]);
}
#12

v. 1.3.3 + PHP 5.1.6 + Apache/2.2.3

Это не баг непосредственно системы, это прикол PHP.
Если слепить свою страничку на которой используется ФормГенератор (таблица) разработанный Арески и одну из колонок добавить с использованием точки по типу:
Код:
$HD_Form -> AddEditElement ("Прямой номер", "sb.id_cc_did",
....
$HD_Form -> FieldEditElement ('sb.id_cc_did, ...

Необходимость использовать алиас таблицы вызвана UPDATE-ом полей в двух таблицах с одинаковым полем (id_cc_did).
Ключевой момент здесь в методе AddEditElement, там определяется как будет названа POST переменная при нажатии кнопки "Сохранить". Так вот PHP при вталкивании ему параметра с точкой заменяет его на "_" и получается sb_id_cc_did - соответственно при конструировании запроса UPDATE ФормГенератор ищет в массиве POST переменную sb.id_cc_did и не находит ее (ВСТАВЛЯЕТ В ЗАПРОС sb.id_cc_did='' - ПУСТОЕ ЗНАЧЕНИЕ).

Полечил следующим образом
Код:
Class.FormHandler.inc.php line 1675:
if (empty($processed[$fields_name]) && strtoupper(substr($this->FG_TABLE_ADITION[$i][13],3,4))=="NULL"){
$param_update .= $fields_name." = NULL ";
}else{
if($this->FG_TABLE_EDITION[$i][3]!= "SPAN")
{
$param_update .= $fields_name." = '".addslashes(trim($processed[$fields_name]))."' ";
}
}

Заменил на
Код:
if (empty($processed[str_replace(".", "_", $fields_name)]) && strtoupper(substr($this->FG_TABLE_ADITION[$i][13],3,4))=="NULL"){
$param_update .= $fields_name." = NULL ";
}else{
if($this->FG_TABLE_EDITION[$i][3]!= "SPAN")
{
$param_update .= $fields_name." = '".addslashes(trim($processed[str_replace(".", "_", $fields_name)]))."' ";
}
}
#13

Clap 2
#14

a2billing.conf
Код:
[database]
hostname = localhost
port = 5432
user = a2billinguser
password = a2billing
dbname = mya2billing
dbtype = postgres
;dbtype = mysql

Параметр port не используется это видно по строке подключения:
Код:
$datasource = 'mysql://'.$this->config['database']['user'].':'.$this->config['database']['password'].'@'.$this->config['database']['hostname'].'/'.$this->config['database']['dbname'];

Кроме того у меня на рабочей системе стоит port=5432, а реально MySQL слушает по умолчанию 3306
#15

v.1.3.4
Class.A2Billing.php, function callingcard_ivr_authorize, line 679:
Код:
if ($this->agiconfig['use_dnid']==1 && !in_array ($this->dnid, $this->agiconfig['no_auth_dnid']) && strlen($this->dnid)>2 && $try_num==0){
$this->destination = $this->dnid;
}else{
$res_dtmf = $agi->get_data($prompt_enter_dest, 6000, 20);
$this -> debug( VERBOSE | WRITELOG, $agi, __FILE__, __LINE__, "RES DTMF : ".$res_dtmf ["result"]);
$this->destination = $res_dtmf ["result"];
}

в проверке стоит strlen($this->dnid)>2 - значит если звоним на *0, *1 то оно всегда спрашивает ввод номера на который хочется позвонить.
А ниже по коду проверка
Код:
// SAY BALANCE
// this is hardcoded for now but we might have a setting in a2billing.conf for the combination
if ($this->destination=='*0'){
$this -> debug( WRITELOG, $agi, __FILE__, __LINE__, "[SAY BALANCE ::> ".$this->credit."]");
$this -> fct_say_balance ($agi, $this->credit);
return -1;
}

//REDIAL FIND THE LAST DIALED NUMBER (STORED IN THE DATABASE)
if ($this->destination=='*1'){
......

Которая по понятным причинам не срабатывает.

Вылечил так
Class.A2Billing.php, function callingcard_ivr_authorize, line 679:
Код:
if ($this->agiconfig['use_dnid']==1 && !in_array ($this->dnid, $this->agiconfig['no_auth_dnid']) && (strlen($this->dnid)>2 || preg_match("/^\*[0-9]$/", $this->dnid)) && $try_num==0){