diff --git a/app/model/TrunkSipCodes.js b/app/model/TrunkSipCodes.js new file mode 100755 index 000000000..b8d27742d --- /dev/null +++ b/app/model/TrunkSipCodes.js @@ -0,0 +1,43 @@ +/** + * Classe que define a model "TrunkSIPCodes" + * + * ======================================= + * ################################### + * MagnusBilling + * + * @package MagnusBilling + * @author Adilson Leffa Magnus. + * @copyright Copyright (C) 2005 - 2021 MagnusBilling. All rights reserved. + * ################################### + * + * This software is released under the terms of the GNU Lesser General Public License v3 + * A copy of which is available from http://www.gnu.org/copyleft/lesser.html + * + * Please submit bug reports, patches, etc to https://github.com/magnusbilling/mbilling/issues + * ======================================= + * Magnusbilling.com + * 25/03/2021 + */ +Ext.define('MBilling.model.TrunkSipCodes', { + extend: 'Ext.data.Model', + fields: [{ + name: 'id', + type: 'int' + }, { + name: 'ip', + type: 'string' + }, { + name: 'code', + type: 'int' + }, { + name: 'total', + type: 'int' + }, { + name: 'percentage', + type: 'string' + }], + proxy: { + type: 'uxproxy', + module: 'trunkSipCodes' + } +}); \ No newline at end of file diff --git a/app/store/TrunkSipCodes.js b/app/store/TrunkSipCodes.js new file mode 100755 index 000000000..05b4f94dc --- /dev/null +++ b/app/store/TrunkSipCodes.js @@ -0,0 +1,25 @@ +/** + * Classe que define o store "TrunkSIPCodes" + * + * ======================================= + * ################################### + * MagnusBilling + * + * @package MagnusBilling + * @author Adilson Leffa Magnus. + * @copyright Copyright (C) 2005 - 2021 MagnusBilling. All rights reserved. + * ################################### + * + * This software is released under the terms of the GNU Lesser General Public License v3 + * A copy of which is available from http://www.gnu.org/copyleft/lesser.html + * + * Please submit bug reports, patches, etc to https://github.com/magnusbilling/mbilling/issues + * ======================================= + * Magnusbilling.com + * 25/03/2021 + */ +Ext.define('MBilling.store.TrunkSipCodes', { + extend: 'Ext.data.Store', + model: 'MBilling.model.TrunkSipCodes', + groupField: 'ip' +}); \ No newline at end of file diff --git a/build/MagnusBilling-current.tar.gz b/build/MagnusBilling-current.tar.gz index 42d3b660f..c311005db 100644 Binary files a/build/MagnusBilling-current.tar.gz and b/build/MagnusBilling-current.tar.gz differ diff --git a/classic/src/view/trunk/Controller.js b/classic/src/view/trunk/Controller.js index 762fb0da1..c4a11e16f 100755 --- a/classic/src/view/trunk/Controller.js +++ b/classic/src/view/trunk/Controller.js @@ -70,4 +70,5 @@ Ext.define('MBilling.view.trunk.Controller', { } }); } + }); \ No newline at end of file diff --git a/classic/src/view/trunk/List.js b/classic/src/view/trunk/List.js index 941a7d108..ff45bcdd0 100755 --- a/classic/src/view/trunk/List.js +++ b/classic/src/view/trunk/List.js @@ -25,6 +25,7 @@ Ext.define('MBilling.view.trunk.List', { fieldSearch: 'trunkcode', initComponent: function() { var me = this; + me.columns = me.columns || [{ header: t('ID'), dataIndex: 'id', diff --git a/classic/src/view/trunkSipCodes/Controller.js b/classic/src/view/trunkSipCodes/Controller.js new file mode 100755 index 000000000..76131fa27 --- /dev/null +++ b/classic/src/view/trunkSipCodes/Controller.js @@ -0,0 +1,24 @@ +/** + * Classe que define a lista de "CallShopCdr" + * + * ======================================= + * ################################### + * MagnusBilling + * + * @package MagnusBilling + * @author Adilson Leffa Magnus. + * @copyright Copyright (C) 2005 - 2021 MagnusBilling. All rights reserved. + * ################################### + * + * This software is released under the terms of the GNU Lesser General Public License v3 + * A copy of which is available from http://www.gnu.org/copyleft/lesser.html + * + * Please submit bug reports, patches, etc to https://github.com/magnussolution/magnusbilling7/issues + * ======================================= + * Magnusbilling.org + * 01/10/2013 + */ +Ext.define('MBilling.view.trunkSipCodes.Controller', { + extend: 'Ext.ux.app.ViewController', + alias: 'controller.trunksipcodes' +}); \ No newline at end of file diff --git a/classic/src/view/trunkSipCodes/Form.js b/classic/src/view/trunkSipCodes/Form.js new file mode 100755 index 000000000..29578025b --- /dev/null +++ b/classic/src/view/trunkSipCodes/Form.js @@ -0,0 +1,41 @@ +/** + * Classe que define o form de "Trunk" + * + * ======================================= + * ################################### + * MagnusBilling + * + * @package MagnusBilling + * @author Adilson Leffa Magnus. + * @copyright Copyright (C) 2005 - 2021 MagnusBilling. All rights reserved. + * ################################### + * + * This software is released under the terms of the GNU Lesser General Public License v3 + * A copy of which is available from http://www.gnu.org/copyleft/lesser.html + * + * Please submit bug reports, patches, etc to https://github.com/magnussolution/magnusbilling7/issues + * ======================================= + * Magnusbilling.org + * 25/06/2012 + */ +Ext.define('MBilling.view.trunkSipCodes.Form', { + extend: 'Ext.ux.form.Panel', + alias: 'widget.trunksipcodesform', + initComponent: function() { + var me = this; + me.items = [{ + xtype: 'textfield', + name: 'ip', + fieldLabel: t('IP') + }, { + xtype: 'numberfield', + name: 'code', + fieldLabel: t('Code') + }, { + xtype: 'numberfield', + name: 'total', + fieldLabel: t('Total') + }]; + me.callParent(arguments); + } +}); \ No newline at end of file diff --git a/classic/src/view/trunkSipCodes/List.js b/classic/src/view/trunkSipCodes/List.js new file mode 100755 index 000000000..dfe991102 --- /dev/null +++ b/classic/src/view/trunkSipCodes/List.js @@ -0,0 +1,53 @@ +/** + * Classe que define a lista de "Trunk" + * + * ======================================= + * ################################### + * MagnusBilling + * + * @package MagnusBilling + * @author Adilson Leffa Magnus. + * @copyright Copyright (C) 2005 - 2021 MagnusBilling. All rights reserved. + * ################################### + * + * This software is released under the terms of the GNU Lesser General Public License v3 + * A copy of which is available from http://www.gnu.org/copyleft/lesser.html + * + * Please submit bug reports, patches, etc to https://github.com/magnussolution/magnusbilling7/issues + * ======================================= + * Magnusbilling.org + * 25/06/2012 + */ +Ext.define('MBilling.view.trunkSipCodes.List', { + extend: 'Ext.ux.grid.Panel', + alias: 'widget.trunksipcodeslist', + store: 'TrunkSipCodes', + fieldSearch: 'ip', + initComponent: function() { + var me = this; + me.buttonCsv = false; + me.allowPrint = false; + me.buttonUpdateLot = false; + me.allowCreate = false; + me.allowUpdate = false; + me.textDelete = t('Reset'); + me.columns = me.columns || [{ + header: t('Ip'), + dataIndex: 'ip', + flex: 3 + }, { + header: t('SIP Code'), + dataIndex: 'code', + flex: 3 + }, { + header: t('Total'), + dataIndex: 'total', + flex: 3 + }, { + header: t('Percentage'), + dataIndex: 'percentage', + flex: 3 + }]; + me.callParent(arguments); + } +}); \ No newline at end of file diff --git a/classic/src/view/trunkSipCodes/Module.js b/classic/src/view/trunkSipCodes/Module.js new file mode 100755 index 000000000..b18bb9450 --- /dev/null +++ b/classic/src/view/trunkSipCodes/Module.js @@ -0,0 +1,11 @@ +/** + * Classe que define o panel de "Trunk" + * + * MagnusSolution.com + * 18/04/2012 + */ +Ext.define('MBilling.view.trunkSipCodes.Module', { + extend: 'Ext.ux.panel.Module', + alias: 'widget.trunksipcodesmodule', + controller: 'trunksipcodes' +}); \ No newline at end of file diff --git a/protected/commands/CallChartCommand.php b/protected/commands/CallChartCommand.php index e7ac3ccac..d94121801 100755 --- a/protected/commands/CallChartCommand.php +++ b/protected/commands/CallChartCommand.php @@ -190,7 +190,9 @@ public function user_cdr_show($calls) } if (!count($modelSip)) { - + if ($status == 'Ring') { + $sip_account = $originate; + } if (strlen($sip_account) > 3) { //echo "check per sip_account $originate\n"; if (false !== $key = array_search($originate, $this->sipNames)) { diff --git a/protected/commands/TrunkSIPCodesCommand.php b/protected/commands/TrunkSIPCodesCommand.php new file mode 100755 index 000000000..da3468629 --- /dev/null +++ b/protected/commands/TrunkSIPCodesCommand.php @@ -0,0 +1,120 @@ + + * + */ +class TrunkSIPCodesCommand extends ConsoleCommand +{ + public function run($args) + { + + $time = time(); + + $cache_path = '/tmp/cache_mbilling_codes.sqlite'; + exec('rm -rf ' . $cache_path); + $fields = "data,ip,code,msg"; + try { + $db = new SQLite3($cache_path); + $db->exec('CREATE TABLE IF NOT EXISTS sipcodes (' . $fields . ');'); + } catch (Exception $e) { + + } + + if (!file_exists('/var/log/asterisk/magnus_processed ')) { + exec('touch /var/log/asterisk/magnus_processed '); + } + + exec('cp -rf /var/log/asterisk/magnus /var/log/asterisk/magnus_new'); + + exec('diff -u /var/log/asterisk/magnus_processed /var/log/asterisk/magnus_new ', $lines); + + exec('rm -rf /var/log/asterisk/magnus_processed'); + exec('mv /var/log/asterisk/magnus_new /var/log/asterisk/magnus_processed'); + + $values = ''; + + $i = 0; + foreach ($lines as $key => $line) { + + preg_match_all('/\[(.*)\] DEBUG.*\.*\|(.*)\|(.*)/', $line, $output_array); + + if (count($output_array) < 4 || !isset($output_array[1][0])) { + + continue; + } + + $output_array[4][0] = preg_replace("/'/", '', $output_array[4][0]); + + $values .= "('" . $output_array[1][0] . "','" . $output_array[2][0] . "','" . $output_array[3][0] . "','" . $output_array[4][0] . "'),"; + + if ($i == 200) { + + $sql = "INSERT INTO sipcodes ($fields) VALUES " . substr($values, 0, -1); + try { + $db->exec($sql); + } catch (Exception $e) { + // + } + $values = ''; + $i = 0; + } else { + $i++; + } + + } + + if ($i < 200 && $i > 0) { + + $sql = "INSERT INTO sipcodes ($fields) VALUES " . substr($values, 0, -1); + try { + $db->exec($sql); + } catch (Exception $e) { + // + } + $values = ''; + $i = 0; + } + + $sql = "SELECT ip FROM sipcodes GROUP BY ip"; + $result = $db->query($sql); + while ($ip = $result->fetchArray(SQLITE3_ASSOC)) { + + $sql = "SELECT count(code) as total, code FROM sipcodes WHERE ip = '" . $ip['ip'] . "' GROUP BY code"; + $resultCodes = $db->query($sql); + while ($code = $resultCodes->fetchArray(SQLITE3_ASSOC)) { + + $sql = "SELECT id FROM pkg_trunk WHERE host = '" . $ip['ip'] . "' "; + $modelTrunk = Yii::app()->db->createCommand($sql)->queryAll(); + if (isset($modelTrunk[0]['id'])) { + $sql = "INSERT INTO pkg_trunk_error (ip, code,total) VALUES ( '" . $ip['ip'] . "', '" . $code['code'] . "', '" . $code['total'] . "')"; + try { + Yii::app()->db->createCommand($sql)->execute(); + } catch (Exception $e) { + + $sql = "UPDATE pkg_trunk_error SET total = total + " . $code['total'] . " WHERE ip = '" . $ip['ip'] . "' AND code = '" . $code['code'] . "'"; + try { + Yii::app()->db->createCommand($sql)->execute(); + } catch (Exception $e) { + print_r($e); + } + } + } + } + + } + } +} diff --git a/protected/commands/UpdateMysqlCommand.php b/protected/commands/UpdateMysqlCommand.php index 645f5fb4e..576dfb4cd 100755 --- a/protected/commands/UpdateMysqlCommand.php +++ b/protected/commands/UpdateMysqlCommand.php @@ -23,6 +23,12 @@ class UpdateMysqlCommand extends ConsoleCommand public function run($args) { + if (file_exists('/var/spool/cron/root')) { + $CRONPATH = '/var/spool/cron/root'; + } elseif (file_exists('/var/spool/cron/crontabs/root')) { + $CRONPATH = '/var/spool/cron/crontabs/root'; + } + $version = $this->config['global']['version']; $language = $this->config['global']['base_language']; @@ -490,7 +496,7 @@ public function run($args) $sql = "UPDATE pkg_configuration SET config_value = '" . $version . "' WHERE config_key = 'version' "; Yii::app()->db->createCommand($sql)->execute(); - exec("echo '\n* * * * * php /var/www/html/mbilling/cron.php didwww' >> /var/spool/cron/root"); + exec("echo '\n* * * * * php /var/www/html/mbilling/cron.php didwww' >> $CRONPATH"); } if ($version == '7.1.4') { @@ -1256,7 +1262,7 @@ public function run($args) $sql = "INSERT INTO pkg_group_module VALUES ((SELECT id FROM pkg_group_user WHERE id_user_type = 1 LIMIT 1), '" . $idServiceModule . "', 'crud', '1', '1', '1');"; $this->executeDB($sql); - exec("echo '\n*/5 * * * * php /var/www/html/mbilling/cron.php alarm' >> /var/spool/cron/root"); + exec("echo '\n*/5 * * * * php /var/www/html/mbilling/cron.php alarm' >> $CRONPATH"); $version = '7.5.9'; $sql = "UPDATE pkg_configuration SET config_value = '" . $version . "' WHERE config_key = 'version' "; @@ -1351,6 +1357,35 @@ public function run($args) Yii::app()->db->createCommand($sql)->execute(); } + //2021-03-18 + if ($version == '7.6.4') { + + $sql = " + CREATE TABLE IF NOT EXISTS `pkg_trunk_error` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ip` varchar(100) NOT NULL, + `code` int(5) NOT NULL, + `total` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `unique_index` (`ip`,`code`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + "; + $this->executeDB($sql); + + $sql = "INSERT INTO pkg_module VALUES (NULL, 't(''Trunk Errors'')', 'trunksipcodes', 'x-fa fa-desktop', 10,7)"; + $this->executeDB($sql); + $idServiceModule = Yii::app()->db->lastInsertID; + + $sql = "INSERT INTO pkg_group_module VALUES ((SELECT id FROM pkg_group_user WHERE id_user_type = 1 LIMIT 1), '" . $idServiceModule . "', 'crud', '1', '1', '1');"; + $this->executeDB($sql); + + exec("echo '\n* * * * * php /var/www/html/mbilling/cron.php TrunkSIPCodes' >> $CRONPATH"); + + $version = '7.6.5'; + $sql = "UPDATE pkg_configuration SET config_value = '" . $version . "' WHERE config_key = 'version' "; + Yii::app()->db->createCommand($sql)->execute(); + } + } public function executeDB($sql) diff --git a/protected/controllers/TrunkSipCodesController.php b/protected/controllers/TrunkSipCodesController.php new file mode 100755 index 000000000..a26772859 --- /dev/null +++ b/protected/controllers/TrunkSipCodesController.php @@ -0,0 +1,59 @@ + + * 23/03/2021 + */ + +class TrunkSipCodesController extends Controller +{ + + public $attributeOrder = 'ip, code'; + + public function init() + { + $this->instanceModel = new TrunkSipCodes; + $this->abstractModel = TrunkSipCodes::model(); + $this->titleReport = Yii::t('zii', 'TrunkSipCodes'); + + parent::init(); + } + + public function setAttributesModels($attributes, $models) + { + + $modelTrunkSipCodes = TrunkSipCodes::model()->findAll([ + 'select' => 'ip, sum(total) total', + 'group' => 'ip', + ]); + $total = []; + foreach ($modelTrunkSipCodes as $key => $value) { + $total[$value->ip] = $value['total']; + } + + $pkCount = is_array($attributes) || is_object($attributes) ? $attributes : []; + for ($i = 0; $i < count($pkCount); $i++) { + + $attributes[$i]['percentage'] = number_format(($attributes[$i]['total'] / $total[$attributes[$i]['ip']]) * 100, 2) . '%'; + + } + + return $attributes; + } + +} diff --git a/protected/models/TrunkSipCodes.php b/protected/models/TrunkSipCodes.php new file mode 100755 index 000000000..41c32ecda --- /dev/null +++ b/protected/models/TrunkSipCodes.php @@ -0,0 +1,68 @@ + + * 25/06/2012 + */ +class TrunkSipCodes extends Model +{ + protected $_module = 'trunk'; + public $percentage; + + /** + * Retorna a classe estatica da model. + * @return Trunk classe estatica da model. + */ + public static function model($className = __CLASS__) + { + return parent::model($className); + } + + /** + * @return nome da tabela. + */ + public function tableName() + { + return 'pkg_trunk_error'; + } + + /** + * @return nome da(s) chave(s) primaria(s). + */ + public function primaryKey() + { + return 'id'; + } + + /** + * @return array validacao dos campos da model. + */ + public function rules() + { + // NOTE: you should only define rules for those attributes that + // will receive user inputs. + return array( + array('ip, code, total,', 'required'), + array('total, code', 'numerical', 'integerOnly' => true), + array('ip', 'length', 'max' => 100), + array('code', 'length', 'max' => 5), + array('total', 'length', 'max' => 11), + + ); + } + +} diff --git a/resources/asterisk/CalcAgi.php b/resources/asterisk/CalcAgi.php index ea8fee398..dd51e8868 100755 --- a/resources/asterisk/CalcAgi.php +++ b/resources/asterisk/CalcAgi.php @@ -636,7 +636,6 @@ public function sendCall($agi, $destination, &$MAGNUS, $typecall = 0) $this->real_answeredtime = $this->answeredtime = 0; } elseif (($this->dialstatus == "CHANUNAVAIL") || ($this->dialstatus == "CONGESTION")) { $this->real_answeredtime = $this->answeredtime = 0; - return false; } return true; } diff --git a/resources/asterisk/StandardCallAgi.php b/resources/asterisk/StandardCallAgi.php index 480a8ae81..d49efaae1 100755 --- a/resources/asterisk/StandardCallAgi.php +++ b/resources/asterisk/StandardCallAgi.php @@ -30,11 +30,6 @@ public function processCall(&$MAGNUS, &$agi, &$CalcAgi) // INSERT CDR & UPDATE SYSTEM $CalcAgi->updateSystem($MAGNUS, $agi); - if (!$result_callperf) { - $MAGNUS->executePlayAudio("prepaid-dest-unreachable", $agi); - break; - } - if ($MAGNUS->agiconfig['say_balance_after_call'] == 1) { $MAGNUS->sayBalance($agi, $MAGNUS->credit); }