Баг в Invoice модуле, присутствует во всех версиях, включая и 1.3.1
Описание и решение:
http://forum.asterisk2billing.org/viewtopic.php?t=2993
Если удалить эккаунт, не зависмо что стоит в конфиге в строке:
| Цитата: |
| ; 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
Решение проблемы:
http://forum.asterisk2billing.org/viewtopic.php?p=11208
Bug "always 90 minutes left"
Решение проблемы:
http://forum.asterisk2billing.org/viewtopic.php?p=12010
/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)
Привязка и отвязка 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)
ps: проапдейтиться до 1.3.2 не желаете? между 1.3.1 и 1.3.2 огромное количество фиксов!
а сам процесс апдейта очень прост и без потери данных.
т.е. в детализации видим 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 из перечисленного поправлено?" Если это вообще считать багом...
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)
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]); } |
Это не баг непосредственно системы, это прикол 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)]))."' "; } } |
| Код: |
| [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
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){ |