Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
AmiBX
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
bitrix
AmiBX
Commits
cf61be32
Commit
cf61be32
authored
Apr 19, 2022
by
Kulya
😊
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
first routeng added
parent
883eebf7
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
1965 additions
and
39 deletions
+1965
-39
command.php
command.php
+256
-1
inroutes.php
template/inroutes.php
+225
-0
footer_queues.js
template/js/footer_queues.js
+145
-32
footer_queues_orig.js
template/js/footer_queues_orig.js
+1242
-0
trunks.php
template/trunks.php
+45
-3
AloVoiceActions.php
vendor/alovoice/src/AloVoiceActions.php
+39
-1
AloVoiceConnector.php
vendor/alovoice/src/AloVoiceConnector.php
+1
-0
AloVoiceRest.php
vendor/alovoice/src/AloVoiceRest.php
+12
-2
No files found.
command.php
View file @
cf61be32
...
@@ -90,6 +90,21 @@ die();
...
@@ -90,6 +90,21 @@ die();
function
doCommandAjax
(
$cmd
,
$r
){
function
doCommandAjax
(
$cmd
,
$r
){
switch
(
$cmd
)
{
switch
(
$cmd
)
{
case
'removeInroute'
:
return
removeInroute
(
$r
);
break
;
case
'saveInroute'
:
return
saveInroute
(
$r
);
break
;
case
'loadDestinationsList'
:
return
loadDestinationsList
(
$r
);
break
;
case
'loadTrunksList'
:
return
loadTrunksList
(
$r
);
break
;
case
'loadInroutesList'
:
return
loadInroutesList
(
$r
);
break
;
case
'saveAudioFile'
:
case
'saveAudioFile'
:
return
saveAudioFile
(
$r
);
return
saveAudioFile
(
$r
);
break
;
break
;
...
@@ -108,6 +123,9 @@ function doCommandAjax($cmd,$r){
...
@@ -108,6 +123,9 @@ function doCommandAjax($cmd,$r){
case
'addNewQueue'
:
case
'addNewQueue'
:
return
addNewQueue
(
$r
);
return
addNewQueue
(
$r
);
break
;
break
;
case
'saveQueue'
:
return
saveQueue
(
$r
);
break
;
case
'getQueue'
:
case
'getQueue'
:
return
getQueue
(
$r
[
'queue'
]);
return
getQueue
(
$r
[
'queue'
]);
break
;
break
;
...
@@ -149,6 +167,239 @@ function doCommandAjax($cmd,$r){
...
@@ -149,6 +167,239 @@ function doCommandAjax($cmd,$r){
function
removeInroute
(
$r
=
[]){
if
(
empty
(
$r
[
"extension"
])
||
empty
(
$r
[
"cidnum"
])
)
{
return
[
"error"
=>
"Мало данных"
];
}
$extension
=
(
$r
[
"extension"
]
==
"Все"
)
?
""
:
$r
[
"extension"
];
$cidnum
=
(
$r
[
"cidnum"
]
==
"Все"
)
?
""
:
$r
[
"cidnum"
];
$db
=
\FreePBX
::
Database
();
$sql
=
"DELETE FROM incoming WHERE cidnum = '"
.
$cidnum
.
"' AND extension = '"
.
$extension
.
"'"
;
$res
=
$db
->
query
(
$sql
);
exec
(
"fwconsole reload"
);
return
true
;
}
function
saveInroute
(
$r
=
[]){
/*
extension // did
cidnum
mohclass
destination
delay_answer // 0
description
*/
// "app-blackhole,hangup,1",
// "ext-local,vms1098,1",
// timeconditions,1,1
// from-did-direct,2424,1
// ext-queues,99999,1
// ext-group,99998,1
if
(
empty
(
$r
[
"extension"
])
||
empty
(
$r
[
"cidnum"
])
||
empty
(
$r
[
"destination"
])
)
{
return
[
"error"
=>
"Мало данных"
];
}
$destination
=
''
;
if
(
!
empty
(
$r
[
"destination_code"
])){
if
(
$r
[
"destination"
]
==
"ext-queues"
){
$destination
=
$r
[
"destination"
]
.
','
.
$r
[
"destination_code"
]
.
',1'
;
}
if
(
$r
[
"destination"
]
==
"from-did-direct"
){
$destination
=
$r
[
"destination"
]
.
','
.
$r
[
"destination_code"
]
.
',1'
;
}
if
(
$r
[
"destination"
]
==
"timeconditions"
){
$destination
=
$r
[
"destination"
]
.
',1,1'
;
}
}
elseif
(
$r
[
"destination"
]
==
"timeconditions"
){
$destination
=
$r
[
"destination_code"
]
.
',1,1'
;
}
elseif
(
$r
[
"destination"
]
==
"hangup"
){
$destination
=
'app-blackhole,hangup,1'
;
}
elseif
(
$r
[
"destination"
]
==
"vm"
){
$destination
=
'ext-local,vms1098,1'
;
}
if
(
empty
(
$destination
)){
return
[
"error"
=>
"Направление не верная"
];
}
$did_vars
=
[
"extension"
=>
(
$r
[
"extension"
]
==
"Все"
)
?
""
:
$r
[
"extension"
],
"cidnum"
=>
(
$r
[
"cidnum"
]
==
"Все"
)
?
""
:
$r
[
"cidnum"
],
"mohclass"
=>
"default"
,
"destination"
=>
$destination
,
"delay_answer"
=>
0
,
"description"
=>
(
!
empty
(
$r
[
"description"
]))
?
$r
[
"description"
]
:
""
,
];
$res
=
\FreePBX
::
Core
()
->
createUpdateDID
(
$did_vars
);
if
(
!
empty
(
$res
)){
exec
(
"fwconsole reload"
);
}
return
[
"query"
=>
$r
,
"ardid"
=>
$did_vars
,
"save_res"
=>
$res
];
}
function
loadDestinationsList
(
$r
=
[]){
$destTitle
=
[];
$destTitle
[
"from-did-direct"
]
=
'Внут.номер'
;
$destTitle
[
"ext-queues"
]
=
'Очередь'
;
// $destTitle["ext-group"] = 'Группа';
$destTitle
[
"timeconditions"
]
=
'Правила по времени'
;
$destTitle
[
"vm"
]
=
'Голосовая почта'
;
$destTitle
[
"hangup"
]
=
'Завершить звонок'
;
return
$destTitle
;
}
function
loadInroutesList
(
$r
=
[]){
$arInroutes
=
[];
$db
=
\FreePBX
::
Database
();
$sql
=
"SELECT * FROM incoming ORDER BY extension,cidnum"
;
$ob
=
$db
->
query
(
$sql
,
\PDO
::
FETCH_ASSOC
);
if
(
$ob
->
rowCount
()){
$dbInroutes
=
$ob
->
fetchAll
();
}
foreach
(
$dbInroutes
as
$route
){
$arDest
=
explode
(
","
,
$route
[
'destination'
]);
$destTitle
=
''
;
if
(
!
empty
(
$arDest
[
0
])
&&
$arDest
[
0
]
==
"from-did-direct"
){
$destTitle
=
'Внут.номер'
;
}
if
(
!
empty
(
$arDest
[
0
])
&&
$arDest
[
0
]
==
"ext-queues"
){
$destTitle
=
'Очередь'
;
}
if
(
!
empty
(
$arDest
[
0
])
&&
$arDest
[
0
]
==
"ext-group"
){
$destTitle
=
'Группа'
;
}
if
(
!
empty
(
$arDest
[
0
])
&&
$arDest
[
0
]
==
"timeconditions"
){
$destTitle
=
'Правила по времени'
;
}
$arInroutes
[]
=
[
// 'id' => $route[''],
'name'
=>
$route
[
'description'
],
'route_cid'
=>
(
!
empty
(
$route
[
'cidnum'
]))
?
$route
[
'cidnum'
]
:
"Все"
,
'route_did'
=>
(
!
empty
(
$route
[
'extension'
]))
?
$route
[
'extension'
]
:
"Все"
,
'route_goto'
=>
$destTitle
.
" ("
.
$arDest
[
1
]
.
")"
,
'route_goto_code'
=>
$route
[
'destination'
],
'route_moh'
=>
$route
[
'mohclass'
]
];
}
$arHeaders
=
[
'name'
=>
'Название'
,
'route_cid'
=>
'Кто звонит'
,
'route_did'
=>
'Куда звонит'
,
'route_goto'
=>
'Назначение'
,
'route_moh'
=>
'Мелодия в ожидании'
,
];
$arReturn
=
[
'headers'
=>
$arHeaders
,
'datas'
=>
$arInroutes
,
];
return
$arReturn
;
}
function
loadTrunksList
(
$r
=
[]){
// TODO: $assoc default to true, eventually..
//outcid keepcid maxchans
// $trunks = \FreePBX::Core()->listTrunks();
$db
=
\FreePBX
::
Database
();
$sql
=
"SELECT `trunkid` , `tech` , `outcid`, `name`, `keepcid`, `maxchans`, `channelid` , `disabled` FROM `trunks` ORDER BY `trunkid`"
;
$ob
=
$db
->
query
(
$sql
,
\PDO
::
FETCH_ASSOC
);
$dbTrunks
=
[];
if
(
$ob
->
rowCount
()){
$dbTrunks
=
$ob
->
fetchAll
();
}
// $unique_trunks = array();
// foreach ($trunks as $trunk) {
// $trunk_id = "OUT_".$trunk['trunkid'];
// $disabled = $trunk['disabled'];
// if($disabled=="off"){ continue; }
// $tech = strtoupper($trunk['tech']);
// switch ($tech) {
// case 'IAX':
// $dialstring = 'IAX2/'.$trunk['channelid'];
// break;
// case 'CUSTOM':
// $dialstring = 'AMP:'.$trunk['channelid'];
// break;
// default:
// $dialstring = $tech.'/'.$trunk['channelid'];
// break;
// }
// $unique_trunks[] = array($trunk_id, $dialstring, $disabled);
// }
// $arTrunks = array();
foreach
(
$dbTrunks
as
$trunk
)
{
$arTrunks
[
$trunk
[
"trunkid"
]]
=
[
'id'
=>
$trunk
[
"trunkid"
],
'type'
=>
$trunk
[
"tech"
],
'name'
=>
$trunk
[
"name"
],
'number'
=>
(
!
empty
(
$trunk
[
"outcid"
]))
?
$trunk
[
"outcid"
]
:
"_"
,
'maxchannels'
=>
(
!
empty
(
$trunk
[
"maxchans"
]))
?
$trunk
[
"maxchans"
]
:
"-"
,
'status'
=>
(
!
empty
(
$trunk
[
"disabled"
])
&&
$trunk
[
"disabled"
]
==
"on"
)
?
"On"
:
"Off"
,
// 'globalvar' => $trunk[0], //OUT_4
];
}
$arHeaders
=
[
'id'
=>
'ID'
,
'name'
=>
'Название'
,
'type'
=>
'Тип'
,
'number'
=>
'Номер'
,
'maxchannels'
=>
'Максимум линий'
,
'status'
=>
'Статус'
,
];
$arReturn
=
[
'headers'
=>
$arHeaders
,
'datas'
=>
$arTrunks
,
'test'
=>
$rawTest
,
];
return
$arReturn
;
}
function
restartWork
(){
function
restartWork
(){
return
true
;
return
true
;
}
}
...
@@ -385,6 +636,10 @@ function saveQueue($data,$r=true){
...
@@ -385,6 +636,10 @@ function saveQueue($data,$r=true){
if
(
empty
(
$goto
))
{
if
(
empty
(
$goto
))
{
$goto
=
(
!
empty
(
$oQueue
[
"goto"
]))
?
$oQueue
[
"goto"
]
:
"app-blackhole,hangup,1"
;
$goto
=
(
!
empty
(
$oQueue
[
"goto"
]))
?
$oQueue
[
"goto"
]
:
"app-blackhole,hangup,1"
;
}
}
$strategy
=
(
!
empty
(
$data
[
"strategy"
]))
?
$data
[
"strategy"
]
:
false
;
if
(
empty
(
$strategy
)
&&
!
empty
(
$oQueue
[
"strategy"
]))
{
$strategy
=
$oQueue
[
"strategy"
];
}
else
{
$strategy
=
'ringall'
;}
$agentannounce_id
=
(
!
empty
(
$data
[
"agentannounce_id"
]))
?
$data
[
"agentannounce_id"
]
:
(
!
empty
(
$oQueue
[
"agentannounce_id"
]))
?
$oQueue
[
"agentannounce_id"
]
:
NULL
;
$agentannounce_id
=
(
!
empty
(
$data
[
"agentannounce_id"
]))
?
$data
[
"agentannounce_id"
]
:
(
!
empty
(
$oQueue
[
"agentannounce_id"
]))
?
$oQueue
[
"agentannounce_id"
]
:
NULL
;
$joinannounce_id
=
(
!
empty
(
$data
[
"joinannounce_id"
]))
?
$data
[
"joinannounce_id"
]
:
(
!
empty
(
$oQueue
[
"joinannounce_id"
]))
?
$oQueue
[
"joinannounce_id"
]
:
NULL
;
$joinannounce_id
=
(
!
empty
(
$data
[
"joinannounce_id"
]))
?
$data
[
"joinannounce_id"
]
:
(
!
empty
(
$oQueue
[
"joinannounce_id"
]))
?
$oQueue
[
"joinannounce_id"
]
:
NULL
;
$maxwait
=
(
!
empty
(
$data
[
"maxwait"
]))
?
$data
[
"maxwait"
]
:
(
!
empty
(
$oQueue
[
"maxwait"
]))
?
$oQueue
[
"maxwait"
]
:
""
;
$maxwait
=
(
!
empty
(
$data
[
"maxwait"
]))
?
$data
[
"maxwait"
]
:
(
!
empty
(
$oQueue
[
"maxwait"
]))
?
$oQueue
[
"maxwait"
]
:
""
;
...
@@ -399,7 +654,7 @@ function saveQueue($data,$r=true){
...
@@ -399,7 +654,7 @@ function saveQueue($data,$r=true){
$fields
[]
=
[
$account
,
'maxlen'
,(
!
empty
(
$oQueue
[
"maxlen"
]))
?
$oQueue
[
"maxlen"
]
:
'0'
,
0
];
$fields
[]
=
[
$account
,
'maxlen'
,(
!
empty
(
$oQueue
[
"maxlen"
]))
?
$oQueue
[
"maxlen"
]
:
'0'
,
0
];
$fields
[]
=
[
$account
,
'joinempty'
,(
!
empty
(
$oQueue
[
"joinempty"
]))
?
$oQueue
[
"joinempty"
]
:
'yes'
,
0
];
$fields
[]
=
[
$account
,
'joinempty'
,(
!
empty
(
$oQueue
[
"joinempty"
]))
?
$oQueue
[
"joinempty"
]
:
'yes'
,
0
];
$fields
[]
=
[
$account
,
'leavewhenempty'
,(
!
empty
(
$oQueue
[
"leavewhenempty"
]))
?
$oQueue
[
"leavewhenempty"
]
:
'no'
,
0
];
$fields
[]
=
[
$account
,
'leavewhenempty'
,(
!
empty
(
$oQueue
[
"leavewhenempty"
]))
?
$oQueue
[
"leavewhenempty"
]
:
'no'
,
0
];
$fields
[]
=
[
$account
,
'strategy'
,
(
!
empty
(
$oQueue
[
"strategy"
]))
?
$oQueue
[
"strategy"
]
:
'ringall'
,
0
];
$fields
[]
=
[
$account
,
'strategy'
,
$strategy
,
0
];
$fields
[]
=
[
$account
,
'timeout'
,(
!
empty
(
$oQueue
[
"timeout"
]))
?
$oQueue
[
"timeout"
]
:
'15'
,
0
];
$fields
[]
=
[
$account
,
'timeout'
,(
!
empty
(
$oQueue
[
"timeout"
]))
?
$oQueue
[
"timeout"
]
:
'15'
,
0
];
$fields
[]
=
[
$account
,
'retry'
,(
!
empty
(
$oQueue
[
"retry"
]))
?
$oQueue
[
"retry"
]
:
'5'
,
0
];
$fields
[]
=
[
$account
,
'retry'
,(
!
empty
(
$oQueue
[
"retry"
]))
?
$oQueue
[
"retry"
]
:
'5'
,
0
];
$fields
[]
=
[
$account
,
'wrapuptime'
,(
!
empty
(
$oQueue
[
"wrapuptime"
]))
?
$oQueue
[
"wrapuptime"
]
:
'0'
,
0
];
$fields
[]
=
[
$account
,
'wrapuptime'
,(
!
empty
(
$oQueue
[
"wrapuptime"
]))
?
$oQueue
[
"wrapuptime"
]
:
'0'
,
0
];
...
...
template/inroutes.php
0 → 100644
View file @
cf61be32
<?php
namespace
AloVoice
;
?>
<style>
.alv_table_lines
.nowrp
{
white-space
:
nowrap
;
}
.loadingline
{
display
:
none
;
}
</style>
<center>
<h3
class=
"h3 card-body"
>
Входящие звонки
</h3>
<div
class=
"loadingline"
></div>
<a
href=
"#"
onClick=
"addNewinRoute()"
id=
"inroute_add_button"
class=
"btn btn-primary title_line_button"
><i
class=
"fa fa-plus"
></i>
Добавить
</a>
</center>
<br/>
<table
class=
"table"
id=
"stats_block_table"
>
<thead>
<tr
id=
"inroutes_table_header"
></tr>
</thead>
<tbody
id=
"inroutes_table_body"
>
</tbody>
</table>
<script>
var
delOneDid
=
function
(
cid
,
did
,
me
){
if
(
typeof
me
!=
'
undefined
'
){
$
(
me
).
html
(
'
<i class="fa fa-spinner fa-spin"></i> Удаление...
'
);
}
doAloVoiceCmd
(
'
removeInroute
'
,
{
"
cidnum
"
:
cid
,
"
extension
"
:
did
},
function
(
res
)
{
console
.
log
(
"
--== DEL inROUTE RES:
"
,
res
);
$
(
"
#inroutes-tab
"
).
click
();
});
};
var
loadAlVOperators
=
function
(
destination_code
){
$
(
"
#destination_code_container
"
).
html
(
'
<span>Загрузка...</span>
'
);
loadAloVoiceInfo
(
"
alovoice_get_operators_nums
"
,
function
(
operators
){
$
(
"
#destination_code_container
"
).
html
(
''
);
$
(
"
#destination_code_container
"
).
append
(
'
<select id="inrt_destination_code" class="form-control inrouteinp"></select>
'
);
$
.
each
(
operators
,
function
(
num
,
operator
)
{
var
selexttxt
=
(
typeof
destination_code
!=
'
undefined
'
&&
destination_code
==
num
)
?
'
selected
'
:
''
;
$
(
"
#inrt_destination_code
"
).
append
(
'
<option value="
'
+
num
+
'
"
'
+
selexttxt
+
'
>
'
+
num
+
'
-
'
+
operator
.
NAME
+
'
'
+
operator
.
LAST_NAME
+
'
</option>
'
);
});
});
}
var
loadAlVQueues
=
function
(
destination_code
){
$
(
"
#destination_code_container
"
).
html
(
'
<span>Загрузка...</span>
'
);
loadAloVoiceInfo
(
"
alovoice_get_allqueues
"
,
function
(
queues
){
console
.
log
(
"
--== Loaded All QUEUEs:
"
,
queues
);
$
(
"
#destination_code_container
"
).
html
(
''
);
$
(
"
#destination_code_container
"
).
append
(
'
<select id="inrt_destination_code" class="form-control inrouteinp"></select>
'
);
$
.
each
(
queues
,
function
(
queue
,
strategy
)
{
var
selexttxt
=
(
typeof
destination_code
!=
'
undefined
'
&&
destination_code
==
queue
)
?
'
selected
'
:
''
;
$
(
"
#inrt_destination_code
"
).
append
(
'
<option value="
'
+
queue
+
'
"
'
+
selexttxt
+
'
>
'
+
queue
+
'
-
'
+
strategy
+
'
</option>
'
);
});
});
}
var
route_destination_change
=
function
(
me
){
var
route_dest
=
$
(
me
).
val
();
console
.
log
(
"
--== Changed dest:
"
,
route_dest
);
if
(
route_dest
==
"
from-did-direct
"
){
loadAlVOperators
();
}
if
(
route_dest
==
"
ext-queues
"
){
loadAlVQueues
();
}
if
(
route_dest
==
"
timeconditions
"
){
$
(
"
#destination_code_container
"
).
html
(
""
);
}
if
(
route_dest
==
"
hangup
"
){
$
(
"
#destination_code_container
"
).
html
(
""
);
}
}
var
addNewinRoute
=
function
(
vars
){
console
.
log
(
"
Begin adding inRoute ........
"
);
var
nowTime
=
Math
.
round
(
new
Date
().
getTime
()
/
1000
);
var
description
=
(
typeof
vars
!=
'
undefined
'
&&
typeof
vars
.
description
!=
'
undefined
'
&&
vars
.
description
.
length
>
2
)
?
vars
.
description
:
'
Все
'
+
nowTime
;
var
extension
=
(
typeof
vars
!=
'
undefined
'
&&
typeof
vars
.
extension
!=
'
undefined
'
&&
vars
.
extension
.
length
)
?
vars
.
extension
:
'
Все
'
;
var
cidnum
=
(
typeof
vars
!=
'
undefined
'
&&
typeof
vars
.
cidnum
!=
'
undefined
'
&&
vars
.
cidnum
.
length
)
?
vars
.
cidnum
:
'
Все
'
;
var
mohclass
=
(
typeof
vars
!=
'
undefined
'
&&
typeof
vars
.
mohclass
!=
'
undefined
'
&&
vars
.
mohclass
.
length
)
?
vars
.
mohclass
:
'
default
'
;
var
destination
=
(
typeof
vars
!=
'
undefined
'
&&
typeof
vars
.
destination
!=
'
undefined
'
&&
vars
.
destination
.
length
)
?
vars
.
destination
:
'
default
'
;
var
destination_code
=
(
typeof
vars
!=
'
undefined
'
&&
typeof
vars
.
destination_code
!=
'
undefined
'
)
?
vars
.
destination_code
:
''
;
doAloVoiceCmd
(
'
loadDestinationsList
'
,
{},
function
(
dests
)
{
console
.
log
(
"
--===Loaded Dests:
"
,
dests
);
var
allDestsTxt
=
'
<option value="">Выберите направление...</option>
'
;
$
.
each
(
dests
,
function
(
key
,
value
)
{
var
seltxt
=
(
destination
==
value
)
?
'
selected
'
:
''
;
allDestsTxt
+=
'
<option value="
'
+
key
+
'
"
'
+
seltxt
+
'
>
'
+
value
+
'
</option>
'
;
});
aloModal
({
label
:
"
Добавить входящий маршрут
"
,
body
:
'
<form>
'
+
'
<div class="form-group">
'
+
'
<input type="text" class="form-control inrouteinp" id="inrt_description" placeholder="Введите названия" value="
'
+
description
+
'
">
'
+
'
</div>
'
+
'
<div class="form-row">
'
+
'
<div class="col form-group">
'
+
'
<label>Звонок на: (DID)</label>
'
+
'
<input type="text" class="form-control inrouteinp" id="inrt_extension" value="
'
+
extension
+
'
">
'
+
'
</div>
'
+
'
<div class="col form-group">
'
+
'
<label>Кто звонит (CallerID)</label>
'
+
'
<input type="text" class="form-control inrouteinp" id="inrt_cidnum" value="
'
+
cidnum
+
'
">
'
+
'
</div>
'
+
'
</div>
'
+
'
<div class="form-group">
'
+
'
<label>Мелодия в ожидании</label>
'
+
'
<input type="text" class="form-control inrouteinp" id="inrt_mohclass" value="
'
+
mohclass
+
'
" disabled>
'
+
'
</div>
'
+
'
<div class="form-group">
'
+
'
<label>Направление</label>
'
+
'
<select class="form-control inrouteinp" id="inrt_destination" onChange="route_destination_change(this)">
'
+
allDestsTxt
+
'
</select>
'
+
'
</div>
'
+
'
<div class="form-group" id="destination_code_container"></div>
'
// +'
<
div
class
=
"
form-group
"
>
'
// +
'
<
label
for
=
"
alv_sound_file
"
class
=
"
btn btn-primary afilelabel
"
>
Выберите
файл
записи
-
*
.
mp3
<
/label>'
// +'
<
input
type
=
"
file
"
class
=
"
sound-file-input myfileinput
"
id
=
"
alv_sound_file
"
name
=
"
alv_sound_file
"
required
accept
=
"
.mp3
"
onChange
=
"
doUpload(this)
"
>
'
// +
'
<
/div>'
+
'
</form>
'
,
btn
:
"
Сохранить
"
,
nohide
:
true
,
callback
:
function
(){
var
saveElements
=
{};
saveElements
[
"
cmd
"
]
=
"
saveInroute
"
;
$
(
"
.inrouteinp
"
).
each
(
function
(){
var
inRouteInpId
=
$
(
this
).
attr
(
'
id
'
);
var
inRouteInpCode
=
inRouteInpId
.
substr
(
5
);
var
inRouteInpVal
=
$
(
this
).
val
();
saveElements
[
inRouteInpCode
]
=
inRouteInpVal
;
});
console
.
log
(
"
TEST saveElements:
"
,
saveElements
);
$
(
"
#alvModalFooter
"
).
html
(
'
<i class="fa fa-spinner fa-spin"></i> Сохранение...
'
);
// $("#modalCloseBtn").attr("disabled",true);
// $("#alvModalSendBtn").attr("disabled",true);
loadAloVoiceInfo
(
saveElements
,
function
(
res
){
console
.
log
(
"
Save RES:
"
,
res
);
$
(
'
#alvModal
'
).
modal
(
'
hide
'
);
$
(
"
#inroutes-tab
"
).
click
();
});
}
});
});
};
var
afterLoadPage
=
function
(){
var
isHeadered
=
false
;
var
inroutesUpdate
=
function
(){
doAloVoiceCmd
(
'
loadInroutesList
'
,
{},
function
(
res
)
{
console
.
log
(
"
AloVoice Trunks RES:
"
,
res
);
if
(
!
isHeadered
){
if
(
typeof
res
.
headers
!=
'
undefined
'
){
isHeadered
=
true
;
$
(
"
#inroutes_table_header
"
).
html
(
''
);
$
.
each
(
res
.
headers
,
function
(
key
,
value
)
{
console
.
log
(
"
Each Header:
"
,
key
,
value
);
$
(
"
#inroutes_table_header
"
).
append
(
'
<th id="hd_
'
+
key
+
'
">
'
+
value
+
'
</th>
'
);
});
}
}
if
(
typeof
res
.
datas
!=
'
undefined
'
){
$
(
"
#inroutes_table_body
"
).
html
(
''
);
$
.
each
(
res
.
datas
,
function
(
irkey
,
inroute
)
{
console
.
log
(
"
Each Trunk:
"
,
inroute
);
/*
'name' => 'Название',
'route_cid' => 'Кто звонит',
'route_did' => 'Куда звонит',
'route_goto' => 'Назначение',
'route_moh' => 'Мелодия в ожидании',
*/
var
lineHTML
=
'
<tr class="alv_table_lines" id="inroute_
'
+
irkey
+
'
_" data-cid="
'
+
inroute
.
route_cid
+
'
" data-did="
'
+
inroute
.
route_cid
+
'
">
'
+
'
<td class="nowrp" > <span>
'
+
inroute
.
name
+
'
</span></td>
'
+
'
<td class="nowrp" > <b>
'
+
inroute
.
route_cid
+
'
</b></td>
'
+
'
<td class="nowrp" >
'
+
inroute
.
route_did
+
'
</td>
'
+
'
<td class="nowrp" >
'
+
inroute
.
route_goto
+
'
</td>
'
+
'
<td class="nowrp" >
'
+
inroute
.
route_moh
+
'
</td>
'
+
'
<td class="nowrp" ><a href="#" onClick="delOneDid(
\'
'
+
inroute
.
route_cid
+
'
\'
,
\'
'
+
inroute
.
route_did
+
'
\'
,this);"><i class="fa fa-trash"></i> Удалить</a></td>
'
+
'
</tr>
'
;
$
(
"
#inroutes_table_body
"
).
append
(
lineHTML
);
});
}
//setTimeout(donglesUpdate,100000);
});
}
inroutesUpdate
();
};
</script>
\ No newline at end of file
template/js/footer_queues.js
View file @
cf61be32
...
@@ -3,7 +3,71 @@
...
@@ -3,7 +3,71 @@
*/
*/
$
().
ready
(()
=>
{
$
().
ready
(()
=>
{
window
.
getAllStrateges
=
function
()
{
return
[
{
title
:
"
Звонят все
"
,
value
:
"
ringall
"
,
select
:
true
},
{
title
:
"
Линейный
"
,
value
:
"
linear
"
,
},
{
title
:
"
Самому не занятому
"
,
value
:
"
leastrecent
"
,
},
{
title
:
"
Случайному
"
,
value
:
"
random
"
,
},
// {
// title: lng.strategy.rrmemory,
// value: "rrmemory",
// },
// {
// title: lng.strategy.rrordered,
// value: "rrordered",
// },
// {
// title: lng.strategy.wrandom,
// value: "wrandom",
// }
];
}
window
.
getAllGotos
=
function
()
{
var
result
=
[
// {
// title: "Не выбрано",
// value: "",
// },
{
title
:
"
Завершить звонок
"
,
value
:
"
app-blackhole,hangup,1
"
,
select
:
true
},
{
title
:
"
Голосовая почта
"
,
value
:
"
ext-local,vms1098,1
"
,
},
];
// res = res.map(function(d) {
// return {
// title: "Очередь: " + d[0],
// value: "ext-queues," + d[0] + ",1",
// };
// });
// result = [...result, ...res];
return
result
;
}
feather
.
replace
()
feather
.
replace
()
setWindowFunction
(
'
removeAgent
'
,
removeAgent
)
setWindowFunction
(
'
removeAgent
'
,
removeAgent
)
...
@@ -11,38 +75,75 @@ $().ready(() => {
...
@@ -11,38 +75,75 @@ $().ready(() => {
setWindowFunction
(
'
addAgent
'
,
addAgent
)
setWindowFunction
(
'
addAgent
'
,
addAgent
)
$
(
'
#queues_add
'
).
on
(
'
click
'
,
function
()
{
$
(
'
#queues_add
'
).
on
(
'
click
'
,
function
()
{
var
currGoto
=
''
;
var
gotosOpts
=
''
;
window
.
getAllGotos
().
forEach
(
function
(
elm
){
var
seltxt
=
(
elm
.
select
)
?
"
seleted
"
:
""
;
gotosOpts
+=
'
<option value="
'
+
elm
.
value
+
'
"
'
+
seltxt
+
'
>
'
+
elm
.
title
+
'
</option>
'
;
});
var
strategyOpts
=
''
;
window
.
getAllStrateges
().
forEach
(
function
(
elm
){
var
seltxt
=
(
elm
.
select
)
?
"
seleted
"
:
""
;
strategyOpts
+=
'
<option value="
'
+
elm
.
value
+
'
"
'
+
seltxt
+
'
>
'
+
elm
.
title
+
'
</option>
'
;
});
swal
.
fire
({
swal
.
fire
({
title
:
'
Введите номер очереди
'
,
title
:
'
Введите номер очереди
'
,
input
:
'
text
'
,
showCancelButton
:
true
,
inputAttributes
:
{
cancelButtonText
:
'
Отмена
'
,
autocapitalize
:
'
off
'
,
preConfirm
:
()
=>
{
placeholder
:
'
Номер очереди
'
,
var
queuenum
=
$
(
'
#add_queue_inp
'
).
val
();
id
:
'
add_queue_inp
'
,
var
final_destination
=
$
(
'
#final_destination
'
).
val
();
},
var
queue_strategy
=
$
(
'
#queue_strategy
'
).
val
();
preConfirm
:
(
val
)
=>
{
var
queuenum
=
queuenum
.
replace
(
/
\D
+/g
,
''
);
if
(
!
val
)
{
Swal
.
showValidationMessage
(
console
.
log
(
"
Queue Params:
"
,
queuenum
,
final_destination
,
queue_strategy
);
`Введите номер очереди`
)
return
false
;
if
(
queuenum
&&
(
queuenum
<
6000
||
queuenum
>
6999
))
{
}
if
(
val
.
replace
(
/
\d
+/g
,
''
))
{
Swal
.
showValidationMessage
(
Swal
.
showValidationMessage
(
`Некорректный номер очереди`
`Некорректный номер очереди
! <br>требуется от 6000 до 6999
`
)
)
return
false
;
return
false
;
}
}
return
true
;
},
},
html
:
''
showCancelButton
:
true
,
cancelButtonText
:
'
Отмена
'
,
+
'
<input id="add_queue_inp" class="swal2-input row mx-0" type="text">
'
+
'
<div class="row"></div>
'
+
'
<h2 class="swal2-title">Направление при не ответе: </h2>
'
+
'
<select id="final_destination" class="swal2-select row mx-0">
'
+
gotosOpts
+
'
</select>
'
+
'
<h2 class="swal2-title">Правила приёма звонок: </h2>
'
+
'
<select id="queue_strategy" class="swal2-select row mx-0">
'
+
strategyOpts
+
'
</select>
'
,
}).
then
((
result
)
=>
{
}).
then
((
result
)
=>
{
if
(
result
.
isConfirmed
)
{
if
(
result
.
isConfirmed
)
{
var
val
=
$
(
'
#add_queue_inp
'
).
val
();
uiLoading
();
var
queuenum
=
$
(
'
#add_queue_inp
'
).
val
();
if
(
val
)
{
var
final_destination
=
$
(
'
#final_destination
'
).
val
();
addNewQueue
(
val
);
var
queue_strategy
=
$
(
'
#queue_strategy
'
).
val
();
}
console
.
log
(
"
Queue SAVEing Params:
"
,
queuenum
,
final_destination
,
queue_strategy
);
doAloVoiceCmd
(
'
saveQueue
'
,
{
account
:
queuenum
,
goto
:
final_destination
,
strategy
:
queue_strategy
},
function
()
{
uiLoadingEnd
();
// alert(queuenum + ' успешно добавлен! ' + queue);
});
}
}
});
});
})
})
...
@@ -142,8 +243,11 @@ $().ready(() => {
...
@@ -142,8 +243,11 @@ $().ready(() => {
window
.
uiLoadingEnd
=
function
()
{
window
.
uiLoadingEnd
=
function
()
{
$
(
'
.app-loading
'
).
remove
();
$
(
'
.app-loading
'
).
remove
();
$
(
"
#queues-tab
"
).
click
();
}
}
window
.
addNewQueue
=
function
(
queue
)
{
window
.
addNewQueue
=
function
(
queue
)
{
uiLoading
();
uiLoading
();
doAloVoiceCmd
(
'
addNewQueue
'
,
{
doAloVoiceCmd
(
'
addNewQueue
'
,
{
...
@@ -154,14 +258,23 @@ $().ready(() => {
...
@@ -154,14 +258,23 @@ $().ready(() => {
});
});
}
}
window
.
removeQueue
=
function
(
queue
)
{
window
.
removeQueue
=
function
(
queue
)
{
uiLoading
();
swal
.
fire
({
doAloVoiceCmd
(
'
removeQueue
'
,
{
title
:
'
Удалить очередь
'
+
queue
,
queue
:
queue
,
html
:
"
Вы точно хотите удалить очередь:
"
+
queue
,
},
function
()
{
// backdrop: 'rgb(0 0 0 / 0%)'
uiLoadingEnd
();
showCancelButton
:
true
,
$
(
'
[queue-nav]:first
'
).
trigger
(
'
click
'
);
cancelButtonText
:
'
Отмена
'
,
alert
(
'
Очередь
'
+
queue
+
'
удалена
'
);
confirmButtonText
:
'
удалить
'
,
}).
then
(
function
(
result
)
{
console
.
log
(
"
Test Remove Queue confirming:
"
,
result
.
isConfirmed
);
if
(
result
.
isConfirmed
)
{
uiLoading
();
doAloVoiceCmd
(
'
removeQueue
'
,
{
queue
:
queue
},
function
()
{
uiLoadingEnd
();
});
}
});
});
}
}
function
createMembersList
(
list
)
{
function
createMembersList
(
list
)
{
...
...
template/js/footer_queues_orig.js
0 → 100644
View file @
cf61be32
/**
* @var feather
*/
$
().
ready
(()
=>
{
window
.
getAllGotos
=
function
()
{
var
result
=
[
// {
// title: "Не выбрано",
// value: "",
// },
{
title
:
"
Завершить звонок
"
,
value
:
"
app-blackhole,hangup,1
"
,
select
:
true
},
{
title
:
"
Голосовая почта
"
,
value
:
"
ext-local,vms1098,1
"
,
},
];
// res = res.map(function(d) {
// return {
// title: "Очередь: " + d[0],
// value: "ext-queues," + d[0] + ",1",
// };
// });
// result = [...result, ...res];
return
result
;
}
feather
.
replace
()
setWindowFunction
(
'
removeAgent
'
,
removeAgent
)
setWindowFunction
(
'
toggltAgentDnd
'
,
toggltAgentDnd
)
setWindowFunction
(
'
addAgent
'
,
addAgent
)
$
(
'
#queues_add
'
).
on
(
'
click
'
,
function
()
{
var
currGoto
=
''
;
var
gotosOpts
=
''
;
window
.
getAllGotos
().
forEach
(
function
(
elm
){
var
seltxt
=
(
elm
.
select
)
?
"
seleted
"
:
""
;
gotosOpts
+=
'
<option value="
'
+
elm
.
value
+
'
"
'
+
seltxt
+
'
>
'
+
elm
.
title
+
'
</option>
'
;
});
swal
.
fire
({
title
:
'
Введите номер очереди
'
,
// input: 'text',
// inputAttributes: {
// autocapitalize: 'off',
// placeholder: 'Номер очереди',
// id: 'add_queue_inp',
// },
// preConfirm: (val) => {
// if (!val) {
// Swal.showValidationMessage(
// `Введите номер очереди`
// )
// return false;
// }
// if (val.replace(/\d+/g, '')) {
// Swal.showValidationMessage(
// `Некорректный номер очереди`
// )
// return false;
// }
// return true;
// },
showCancelButton
:
true
,
cancelButtonText
:
'
Отмена
'
,
preConfirm
:
()
=>
{
var
queuenum
=
$
(
'
#add_queue_inp
'
).
val
();
var
queue_final_destination
=
$
(
'
#queue_final_destination
'
).
val
();
var
queuenum
=
queuenum
.
replace
(
/
\D
+/g
,
''
);
console
.
log
(
"
Queue Params:
"
,
queuenum
,
queuenum
.
length
,
queue_final_destination
);
if
(
queuenum
&&
(
queuenum
<
6000
||
queuenum
>
6999
))
{
Swal
.
showValidationMessage
(
`Некорректный номер очереди! <br>требуется от 6000 до 6999`
)
return
false
;
}
},
html
:
''
+
'
<input id="add_queue_inp" class="swal2-input row mx-0" type="text">
'
+
'
<div class="row"></div>
'
+
'
<h2 class="swal2-title">Направление при не ответе: </h2>
'
+
'
<select id="queue_final_destination" class="swal2-select row mx-0">
'
+
gotosOpts
+
'
</select>
'
,
}).
then
((
result
)
=>
{
if
(
result
.
isConfirmed
)
{
if
(
val
)
{
addNewQueue
(
val
);
}
}
});
})
/**
* if there is no function under key {key} add it to window
* @param {String} key
* @param {Function} func
* @returns {void}
*/
function
setWindowFunction
(
key
,
func
)
{
if
(
typeof
window
[
key
]
!==
'
function
'
)
{
window
[
key
]
=
func
}
}
/**
* remove agent from queue
* @param {String} agentId
* @returns {void}
*/
function
removeAgent
(
agentId
,
queue
)
{
uiLoading
();
const
agent
=
window
.
Queues
.
agents
.
get
(
agentId
);
if
(
!
agent
)
{
console
.
warn
(
agentId
+
'
is not defined
'
);
return
;
}
doAloVoiceCmd
(
'
delMemeberQueue
'
,
{
queue
:
queue
,
member
:
agent
.
number
},
function
()
{
uiLoadingEnd
();
alert
(
agent
.
number
+
'
удален из очереди
'
+
queue
);
});
}
window
.
addAgentToQueue
=
function
(
queue
)
{
var
list
=
getCurrentUsersAr
(
queue
);
var
el
=
createMembersList
(
list
);
swal
.
fire
({
title
:
'
Добавить в
'
+
queue
,
html
:
el
,
// backdrop: 'rgb(0 0 0 / 0%)'
showCancelButton
:
true
,
cancelButtonText
:
'
Отмена
'
,
confirmButtonText
:
'
Добавить
'
,
didOpen
:
function
()
{
$
(
'
[name="add_member"]
'
).
on
(
'
change
'
,
function
()
{
var
target
=
'
[for="
'
+
this
.
id
+
'
"]
'
;
if
(
$
(
this
).
is
(
'
:checked
'
))
{
$
(
target
).
addClass
(
'
btn-success
'
).
removeClass
(
'
btn-light
'
);
}
else
{
$
(
target
).
removeClass
(
'
btn-success
'
).
addClass
(
'
btn-light
'
);
}
})
}
}).
then
(
function
(
result
)
{
if
(
result
.
isConfirmed
)
{
// $('[name="add_member"]:checked').each(function () {
// var value = $(this).val();
// if (!value) {
// return;
// }
// addAgent(value, queue);
// });
uiLoading
();
addMember
(
$
(
'
[name="add_member"]:checked
'
),
0
);
}
});
function
addMember
(
elements
,
index
)
{
if
(
elements
.
length
-
1
<
index
)
{
uiLoadingEnd
();
return
;
}
var
el
=
elements
[
index
];
if
(
!
el
)
{
return
;
}
// return
addAgent
(
el
.
value
,
queue
,
function
()
{
addMember
(
elements
,
index
+
1
);
});
}
}
window
.
uiLoading
=
function
()
{
$
(
'
body
'
).
append
(
`<div class="app-loading d-flex align-items-center justify-content-center">
${
feather
.
icons
[
'
loader
'
].
toSvg
({
class
:
'
app-loading__icon
'
})}
</div>`
);
}
window
.
uiLoadingEnd
=
function
()
{
$
(
'
.app-loading
'
).
remove
();
}
window
.
addNewQueue
=
function
(
queue
)
{
uiLoading
();
doAloVoiceCmd
(
'
addNewQueue
'
,
{
number
:
queue
,
},
function
()
{
uiLoadingEnd
();
alert
(
'
Очередь
'
+
queue
+
'
добавлена
'
);
});
}
window
.
removeQueue
=
function
(
queue
)
{
swal
.
fire
({
title
:
'
Удалить очередь
'
+
queue
,
html
:
"
Вы точно хотите удалить очередь:
"
+
queue
,
// backdrop: 'rgb(0 0 0 / 0%)'
showCancelButton
:
true
,
cancelButtonText
:
'
Отмена
'
,
confirmButtonText
:
'
удалить
'
,
}).
then
(
function
(
result
)
{
console
.
log
(
"
Test Remove Queue confirming:
"
,
result
.
isConfirmed
);
if
(
result
.
isConfirmed
)
{
uiLoading
();
addMember
(
$
(
'
[name="add_member"]:checked
'
),
0
);
}
});
}
function
createMembersList
(
list
)
{
var
div
=
$
(
'
<form class="" style="max-height: 300px;max-height: calc(60vh - 100px);" />
'
);
// div.append('');
$
.
each
(
list
,
function
(
none
,
data
)
{
div
.
append
(
`<div class="mb-2">
<label class="d-block btn btn-light py-2 mb-0" for="member_
${
data
.
number
}
" style="cursor: pointer;">
<span class="mr-4">
${
data
.
number
}
</span>
<span>
${
data
.
fullname
}
</span>
</label>
<input name="add_member"
type="checkbox"
id="member_
${
data
.
number
}
"
value="
${
data
.
number
}
"
style="display: none;">
</div>`
);
});
return
div
.
get
(
0
);
}
function
getCurrentUsersAr
(
queue
)
{
var
result
=
[];
var
queueMembers
,
allMembers
,
queueData
;
if
(
!
window
.
Queues
&&
!
window
.
Queues
.
data
)
{
return
result
;
}
queueData
=
window
.
Queues
.
data
.
queues
[
queue
];
allMembers
=
window
.
Queues
.
data
.
agents
||
{};
if
(
!
queueData
)
{
return
result
;
}
queueMembers
=
queueData
.
QueueMember
||
{};
$
.
each
(
allMembers
,
function
(
number
,
data
)
{
if
(
number
in
queueMembers
)
{
return
;
}
result
.
push
(
data
);
});
return
result
;
}
function
addAgent
(
number
,
queue
,
success
)
{
doAloVoiceCmd
(
'
addMemeberQueue
'
,
{
queue
:
queue
,
member
:
number
},
function
()
{
alert
(
number
+
'
добавлен в очередь
'
+
queue
);
if
(
typeof
success
===
'
function
'
)
{
success
();
}
});
}
/**
* toggle agent dnd status
* @param {String} agentId
* @returns {void}
*/
function
toggltAgentDnd
(
number
)
{
if
(
!
number
)
{
return
;
}
uiLoading
();
loadAloVoiceInfo
({
restmethod
:
'
alovoice_dnd_toggle
'
,
number
:
number
,
// status:'off'
},
function
(
r
)
{
console
.
warn
(
"
RES:
"
,
r
);
uiLoadingEnd
();
if
(
r
.
status
===
'
on
'
)
{
alert
(
number
+
'
DND включен
'
);
}
else
{
alert
(
number
+
'
DND выключен
'
);
}
});
}
})
function
getQuesue
()
{
/**
* @class Quesue
* @param {{
* data: {
* agents: Array
* },
* locale: Object,
* params: Object,
* target: Object
* }} data
*/
function
Quesue
(
data
)
{
const
self
=
this
this
.
data
=
this
.
_toCurrentAgentData
(
data
.
data
)
// this.target = data.target
this
.
locale
=
data
.
locale
this
.
params
=
data
.
params
this
.
__setAgents
(
data
.
data
.
agents
)
this
.
$target
=
{}
$
.
each
(
data
.
target
,
function
(
key
,
value
)
{
self
.
$target
[
key
]
=
$
(
value
)
})
this
.
footerActivePill
=
0
this
.
_conf
=
{
calls
:
{
keys
:
{
ivr
:
[
'
ivr
'
],
in
:
[
'
Incom
'
],
out
:
[
"
Out
"
,
"
Outlines
"
],
}
}
}
}
Quesue
.
prototype
=
{
/**
*
*/
init
()
{
const
data
=
this
.
data
this
.
_channels
=
this
.
_getCurrentQueuesCalls
(
data
.
channels
)
this
.
$target
.
agents
.
append
(
this
.
renderQueuesBar
(
Object
.
keys
(
data
.
queues
))
)
this
.
$target
.
queues
.
html
(
this
.
renderChannelsBar
(
this
.
_channels
)
)
this
.
$target
.
agents
.
append
(
this
.
agentsController
(
data
.
queues
)
)
return
true
},
getAgentQueue
(
number
)
{
// this.data
var
result
=
''
;
if
(
!
this
.
data
.
queues
)
{
return
result
;
}
$
.
each
(
this
.
data
.
queues
,
function
(
key
,
data
)
{
if
(
data
.
QueueMember
&&
number
in
data
.
QueueMember
)
{
result
=
key
;
}
});
return
result
;
},
/**
* update ques data
* @param {Object} newData
* @returns {Boolean}
*/
update
(
newData
)
{
newData
=
this
.
_toCurrentAgentData
(
newData
)
const
self
=
this
const
prevData
=
this
.
data
;
this
.
_channels
=
this
.
_getCurrentQueuesCalls
(
newData
.
channels
)
this
.
channels
=
newData
.
channels
this
.
__setAgents
(
newData
.
agents
)
this
.
data
=
newData
$
.
each
(
prevData
.
queues
,
(
index
,
value
)
=>
{
// get current data
if
(
newData
.
queues
[
index
])
{
const
data
=
self
.
__getUpdateResult
(
value
.
QueueMember
,
newData
.
queues
[
index
].
QueueMember
)
self
.
_update
(
data
,
index
)
}
else
{
$
(
`[queue-nav="
${
index
}
"`
).
remove
();
$
(
`[data-queue-number="
${
index
}
"`
).
remove
();
}
})
this
.
$target
.
queues
.
html
(
this
.
renderChannelsBar
(
this
.
_channels
)
)
return
true
},
_toCurrentAgentData
(
data
)
{
var
agents
=
{};
Object
.
entries
(
data
.
agents
).
map
(
function
(
arr
)
{
var
key
=
arr
[
0
],
value
=
arr
[
1
];
if
(
value
.
connect
&&
value
.
status
===
'
off
'
)
{
value
.
status
=
'
free
'
}
agents
[
key
]
=
value
})
data
.
agents
=
agents
return
data
},
/**
* uppdate queue
* @private
* @param {Object} data queue data
* @param {Number|String} queue queue number
* @returns
*/
_update
(
data
,
queue
)
{
const
self
=
this
const
nav
=
$
(
`[queue-nav='
${
queue
}
']`
).
get
(
0
)
if
(
Array
.
isArray
(
data
.
new
)
&&
data
.
new
.
length
)
{
this
.
_updateAddNew
(
data
.
new
,
queue
)
}
if
(
Array
.
isArray
(
data
.
remove
)
&&
data
.
remove
.
length
)
{
this
.
_updateRemove
(
data
.
remove
,
queue
)
}
if
(
Array
.
isArray
(
data
.
data
)
&&
data
.
data
.
length
)
{
this
.
_updateData
(
data
.
data
,
queue
)
}
if
(
!
nav
)
{
const
$target
=
$
(
`#queues__container`
)
const
navs
=
$
(
`[queue-nav]`
).
length
$target
.
append
(
self
.
quesusItemView
({
index
:
navs
,
value
:
queue
,
isActive
:
false
})
)
$
(
`#queues_tab_content`
).
append
(
self
.
agentsContainer
({
data
:
data
,
index
:
navs
,
isActive
:
false
,
queue
:
queue
})
)
}
return
true
},
/**
* Adds a new agent to the queue
* @private _updateAddNew
* @param {Array} data - Array of users
* @param {String} queue - queue number
* @returns {void}
*/
_updateAddNew
(
data
,
queue
)
{
const
self
=
this
;
const
$target
=
$
(
`[data-queue-number="
${
queue
}
"] .row:first .add_agent_div`
)
if
(
$target
.
length
)
{
$target
.
before
(
data
.
map
(
d
=>
{
const
agent
=
self
.
agents
.
get
(
d
.
number
)
return
self
.
agentsView
({
data
:
agent
,
params
:
d
})
})
)
}
},
/**
* remove agent from the queue
* @private _updateRemove
* @param {Array} data - Array of users
* @param {String} queue - queue number
* @returns {void}
*/
_updateRemove
(
data
,
queue
)
{
const
$target
=
$
(
`[data-queue-number="
${
queue
}
"]`
)
if
(
$target
.
length
)
{
data
.
map
(
d
=>
$target
.
find
(
`[data-queue-agent=
${
d
.
number
}
]`
).
remove
())
}
},
/**
* updates the queue data
* @private _updateData
* @param {Array} data - Array of users
* @param {String} queue - queue number
* @returns {void}
*/
_updateData
(
data
,
queue
)
{
const
self
=
this
const
$target
=
$
(
`[data-queue-number="
${
queue
}
"]`
)
if
(
$target
.
length
)
{
data
.
map
(
d
=>
{
// const agent = self.agents.get(d.name)
const
agent
=
self
.
agents
.
get
(
d
.
number
)
if
(
!
agent
)
{
return
}
const
call
=
this
.
_getAgentCall
(
agent
.
number
,
agent
.
status
)
||
{}
const
$el
=
$target
.
find
(
`[data-queue-agent=
${
agent
.
number
}
]`
)
if
(
typeof
self
.
channels
.
Incom
!=
'
undefined
'
&&
typeof
self
.
channels
.
Incom
[
agent
.
number
]
!=
'
undefined
'
){
inCall
=
self
.
channels
.
Incom
[
agent
.
number
];
}
if
(
typeof
self
.
channels
.
Out
!=
'
undefined
'
&&
typeof
self
.
channels
.
Out
[
agent
.
number
]
!=
'
undefined
'
){
outCall
=
self
.
channels
.
Out
[
agent
.
number
];
}
$el
.
children
().
css
(
'
background-color
'
,
self
.
_getAgentStatusColor
(
agent
.
status
));
$el
.
find
(
'
[data-agent="name"]
'
).
html
(
agent
.
name
)
$el
.
find
(
'
[data-agent="status"]
'
).
html
(
self
.
_getAgentStatusValue
(
agent
,
call
))
$el
.
find
(
'
[data-agent="buttons"]
'
).
html
(
self
.
_getAgentButtons
(
agent
,
d
))
return
true
})
}
},
/**
* returns an object with elements to remove, update, add
* @param {Array} oldData
* @param {Array} newData
* @returns {Object}
*/
__getUpdateResult
(
oldData
,
newData
)
{
let
result
=
{
new
:
[],
// add elements
remove
:
[],
// remove elements
data
:
[]
// update elements
}
if
(
!
(
typeof
oldData
===
"
object
"
&&
typeof
newData
===
'
object
'
))
{
return
result
}
return
({
data
:
getUpdates
(
newData
,
oldData
),
new
:
getNews
(
newData
,
oldData
),
remove
:
getRemoves
(
newData
,
oldData
)
});
function
getUpdates
(
newData
,
curretData
)
{
var
result
=
[];
$
.
each
(
newData
,
function
(
key
,
data
)
{
if
(
curretData
[
key
])
{
result
.
push
(
data
);
}
});
return
result
;
}
function
getNews
(
newData
,
curretData
)
{
var
result
=
[];
$
.
each
(
newData
,
function
(
key
,
data
)
{
if
(
!
curretData
[
key
])
{
result
.
push
(
data
);
}
});
return
result
;
}
function
getRemoves
(
newData
,
curretData
)
{
var
result
=
[];
$
.
each
(
curretData
,
function
(
key
,
data
)
{
if
(
!
newData
[
key
])
{
result
.
push
(
data
);
}
});
return
result
;
}
},
/**
* render queues bar to target
* @param {JQElement} target
* @param {Array} data - array with queues and agents
* @returns
*/
renderQueuesBar
(
data
)
{
if
(
!
Array
.
isArray
(
data
))
{
console
.
error
(
"
Typeof data isn't Array
"
)
return
''
}
const
self
=
this
const
view
=
$
(
`<nav class="row">
<div class="col-2">
${
this
.
locale
.
queues
}
</div>
<div class="col-10">
<ul class="nav nav-pills mr-auto" id="queues__container"></ul>
</div>
</nav>`
)
const
cont
=
view
.
find
(
"
.nav-pills
"
)
cont
.
append
(
data
.
map
((
value
,
index
)
=>
{
return
self
.
quesusItemView
({
index
:
index
,
value
:
value
,
isActive
:
isActive
(
index
)
})
})
)
return
view
function
isActive
(
i
)
{
return
i
===
self
.
footerActivePill
}
},
/**
* render call queue bar
* @param {Object} data
*/
renderChannelsBar
(
data
)
{
const
self
=
this
const
view
=
$
(
`<div class="bg-light p-2">
<div class="text-center">
<h5>
${
this
.
locale
.
channelsTitle
}
</h5>
</div>
</div>`
);
const
cont
=
$
(
`<div></div>`
);
if
(
typeof
data
===
"
object
"
)
{
$
.
each
(
data
,
(
key
,
d
)
=>
{
cont
.
append
(
self
.
callQueueSection
(
d
.
title
,
d
.
data
)
)
})
}
view
.
append
(
cont
)
return
view
},
/**
* render channel observer NO_USED
* @param {JQElement} target
* @param {Object} data
*/
renderObservers
(
target
,
data
)
{
const
view
=
$
(
`<div class="p-1 bg-light">
<div class="text-center font-weight-bold">
${
data
.
TEXT
}
</div>
</div>`
);
const
cont
=
$
(
`<div></div>`
);
// cont.append(
// this.observersController(data.DATAS)
// )
target
.
append
(
view
.
append
(
cont
.
append
(
this
.
observersController
(
data
.
DATAS
)
)
)
)
},
/**
* render queue agents container with agens
* @param {JQElement} target
* @param {Object} data
*/
agentsController
(
data
)
{
const
self
=
this
const
keys
=
Object
.
keys
(
data
)
// craete tab container
const
tabVont
=
$
(
`<div class="tab-content" id="queues_tab_content"></div>`
)
tabVont
.
append
(
keys
.
map
((
key
,
index
)
=>
self
.
agentsContainer
({
data
:
data
[
key
].
QueueMember
,
index
:
index
,
isActive
:
isActive
(
index
),
queue
:
key
}))
)
return
tabVont
function
isActive
(
i
)
{
return
i
===
self
.
footerActivePill
}
},
/**
* @param {Object} param0
* @returns {String|HTMLElement}
*/
agentsContainer
({
data
,
index
,
isActive
,
queue
})
{
const
self
=
this
const
view
=
$
(
`<div class="tab-pane
${
isActive
?
"
active
"
:
""
}
" role="tabpanel" id="
${
index
}
" data-queue-number="
${
queue
}
"></div>`
)
const
cont
=
$
(
`<div class="row"></div>`
)
if
(
typeof
data
!==
"
object
"
||
!
Object
.
keys
(
data
).
length
)
{
return
view
.
append
(
cont
.
html
(
self
.
addAgentView
(
queue
)
))
}
const
elems
=
[]
$
.
each
(
data
,
(
index
,
params
)
=>
{
const
agent
=
self
.
agents
.
get
(
params
.
number
)
if
(
!
agent
)
{
return
''
}
elems
.
push
(
self
.
agentsView
({
data
:
agent
,
params
:
params
,
index
:
index
})
)
})
view
.
append
(
cont
.
append
(
elems
,
self
.
addAgentView
(
queue
)
),
)
return
view
;
},
/**
* template for agent
* @param {Object} param0
* @returns {String|HTMLElement}
*/
agentsView
({
data
,
params
,
index
})
{
const
self
=
this
const
call
=
this
.
_getAgentCall
(
data
.
number
,
data
.
status
)
||
{}
const
view
=
`<div class="col-4 p-2" style="position: relative;" data-queue-agent="
${
data
.
number
}
" title="
${
data
.
connect
}
${
data
.
useragent
}
${
data
.
secret
}
">
<div class="row align-items-center m-0 px-2 py-1 rounded h-100" style="background:
${
this
.
_getAgentStatusColor
(
data
.
status
)}
">
${
discription
(
data
.
name
)}
</div>
<div data-agent="buttons">
${
this
.
_getAgentButtons
(
data
,
params
).
join
(
''
)}
</div>
</div>`
return
view
;
function
discription
(
name
)
{
const
view
=
`<div class="col-12 p-0">
<p class="m-0" data-agent="name">
${
name
}
</p>
<p class="m-0" data-agent="status">
${
self
.
_getAgentStatusValue
(
data
,
call
)}
</p>
</div>`
;
return
view
;
}
function
callData
(
call
)
{
if
(
!
call
)
{
return
''
}
const
view
=
`<div class="col-12 p-0">
<p class="m-0" data-agent="phone">
${
call
.
phone1
}
</p>
</div>`
;
return
view
;
}
},
addAgentView
(
queue
)
{
const
view
=
`<div class="col-4 p-2 add_agent_div" style="position: relative;" >
<button type="button"
class="d-flex align-items-center justify-content-center btn btn-light w-100"
style="height: 56px"
onclick="window.addAgentToQueue('
${
queue
}
')"
data-queue="
${
queue
}
">
${
feather
.
icons
.
plus
.
toSvg
()}
Добавить агента</button>
</div>`
return
view
;
},
/**
* @private _getAgentStatusValue
* @param {Object} agent
* @param {Object} call
* @returns {String}
*/
_getAgentStatusValue
(
agent
,
call
)
{
let
value
=
[
this
.
_getAgentStatusText
(
agent
.
status
),
`<br> <span>
${
call
.
phone1
||
""
}
${
call
.
duration
||
""
}
</span>`
]
return
value
.
join
(
''
)
},
/**
* @private
* @param {} param0
* @returns {HTMLElement}
*/
_getAgentButtons
(
agent
,
params
)
{
const
className
=
"
queues_agent_icon rounded-circle d-flex align-icemt-center
"
let
result
=
[
`<button type="button" class="
${
className
}
bg-white text-danger mr-4"
title="Удалить из очереди"
onclick="window.removeAgent('
${
agent
.
id
}
', '
${
params
.
queue
}
')"
>
${
feather
.
icons
[
'
trash
'
].
toSvg
({
class
:
"
w-100 h-100
"
})}
</button>`
,
]
if
(
agent
.
dnd
===
'
Y
'
)
{
result
.
push
(
`<button type="button" class="
${
className
}
bg-white"
onclick="window.toggltAgentDnd('
${
agent
.
number
}
')"
title="Выключить DND">
${
feather
.
icons
[
'
phone-missed
'
].
toSvg
({
class
:
"
w-100 h-100
"
})}
</button>`
)
}
else
{
result
.
push
(
`<button type="button" class="
${
className
}
bg-white"
onclick="window.toggltAgentDnd('
${
agent
.
number
}
')"
title="Включить DND">
${
feather
.
icons
[
'
phone-incoming
'
].
toSvg
({
class
:
"
w-100 h-100
"
})}
</button>`
)
}
// switch (agent.status) {
// case 'off':
// result.push(`<button type="button" class="${className} bg-white" onclick
// title="off">${feather.icons['phone-missed'].toSvg({class: "w-100 h-100"})}</button>`)
// break
// case 'free':
// result.push(`<button type="button" class="${className} bg-white" onclick
// title="2">${feather.icons['phone-incoming'].toSvg({class: "w-100 h-100"})}</button>`)
// break
// case 'dnd':
// result.push(`<button type="button" class="${className} bg-white"
// onclick="window.toggltAgentDnd('${agent.number}')"
// title="3">${feather.icons['phone-incoming'].toSvg({class: "w-100 h-100"})}</button>`)
// break
// case 'incring':
// result.push(`<button type="button" class="${className} bg-white" onclick
// title="4">${feather.icons['phone-incoming'].toSvg({class: "w-100 h-100"})}</button>`)
// break
// case 'inccall':
// result.push(`<button type="button" class="${className} bg-white" onclick
// title="5">${feather.icons['phone-incoming'].toSvg({class: "w-100 h-100"})}</button>`)
// break
// case 'outring':
// result.push(`<button type="button" class="${className} bg-white" onclick
// title="6">${feather.icons['phone-incoming'].toSvg({class: "w-100 h-100"})}</button>`)
// break
// case 'outcall':
// result.push(`<button type="button" class="${className} bg-white" onclick
// title="7">${feather.icons['phone-incoming'].toSvg({class: "w-100 h-100"})}</button>`)
// break
// }
return
result
},
/**
* retorns status color
* @param {Number} status
* @returns {Object}
*/
_getAgentStatusColor
(
status
)
{
const
stcolor
=
this
.
params
.
agents
.
statuscolor
return
stcolor
[
status
]
||
'
#CCCCCC
'
},
_getAgentCall
(
agentId
,
status
)
{
const
self
=
this
let
result
getCall
.
bind
(
this
)
switch
(
status
)
{
case
"
incring
"
:
case
"
inccall
"
:
result
=
getCall
(
agentId
,
"
in
"
)
break
case
"
outring
"
:
case
"
outcall
"
:
result
=
getCall
(
agentId
,
"
out
"
)
break
}
if
(
result
)
{
result
=
this
.
_getCurrentCallData
(
result
)
}
return
result
function
getCall
(
agentId
,
key
)
{
const
calls
=
self
.
_channels
[
key
].
data
let
result
$
.
each
(
calls
,
(
none
,
call
)
=>
{
if
(
call
.
_agentNumber
!==
agentId
)
{
return
}
result
=
call
})
return
result
}
},
_getAgentStatusText
(
status
)
{
const
stcode
=
this
.
params
.
agents
.
statuscode
return
stcode
[
status
]
||
'
-----
'
},
/**
* template for queues bar item
* @param {Object} param0
* @returns {String|HTMLElement}
*/
quesusItemView
({
index
,
isActive
,
value
})
{
const
self
=
this
const
view
=
$
(
`<li class="nav-item">
<a class="nav-link
${
isActive
?
"
active
"
:
""
}
" href="#
${
index
}
" data-toggle="pill" aria-expanded="
${
isActive
}
" queue-nav="
${
value
}
">
${
value
}
<button type="button" class="ml-1 align-middle text-danger" onclick="window.removeQueue('
${
value
}
')">
${
feather
.
icons
[
'
trash
'
].
toSvg
({
width
:
'
18px
'
,
height
:
'
18px
'
})}
</button>
</a>
</li>`
)
view
.
on
(
"
click
"
,
function
()
{
const
$el
=
$
(
this
);
const
parent
=
$el
.
parent
();
self
.
footerActivePill
=
index
;
})
return
view
;
},
/**
*
* @param {Object} data
* @returns {String|HTMLElement}
*/
callQueueSection
(
title
,
data
)
{
const
self
=
this
const
view
=
$
(
`<div class="mb-3">
<div class="text-center font-weight-bold">
${
title
}
</div>
</div>`
)
const
cont
=
$
(
`<div></div>`
)
view
.
append
(
cont
.
append
(
self
.
queuesController
(
data
)
)
)
return
view
},
/**
*
* @param {Object} data
* @returns {Array}
*/
queuesController
(
data
)
{
const
self
=
this
if
(
!
Array
.
isArray
(
data
))
{
return
''
}
if
(
data
.
length
===
0
)
{
return
`<p class="text-center">
${
this
.
locale
.
queuesEmpty
}
</p>`
}
return
data
.
map
((
d
,
i
)
=>
{
const
current
=
self
.
_getCurrentCallData
(
d
)
return
self
.
queueCallView
(
current
,
i
+
1
)
})
},
/**
*
* @param {Object} data
* @returns {String|HTMLElement}
*/
queueCallView
(
data
,
key
)
{
const
view
=
$
(
`<div class="row align-items-center p-1 m-0 mt-1"
style="background:
${
data
.
bgColor
}
">
${
keyView
(
key
)}
${
phoneView
(
data
.
phone1
)}${
phoneView
(
data
.
phone2
)}
${
timeView
(
data
.
duration
)}
</div>`
)
function
keyView
(
val
=
""
)
{
const
view
=
`<div class="col-1 p-0">
${
val
}
</div>`
return
view
}
function
titleView
(
title
=
""
,
info
=
""
)
{
const
view
=
`<div class="col-auto p-0">
${
title
}
<span>
${
info
}
</spam> </div>`
;
return
view
}
function
phoneView
(
phone
=
""
)
{
const
view
=
`<div class="col-4 p-0">
${
phone
}
</div>`
return
view
}
function
phoneToView
(
phone
=
""
)
{
if
(
!
phone
.
length
){
return
""
;}
const
view
=
` <div class="col-4 p-0">
${
phone
}
</div>`
return
view
}
function
timeView
(
duration
=
""
)
{
const
view
=
`<div class="col-2 p-1 bg-light rounded d-flex justify-content-center ml-auto">
${
duration
.
substr
(
-
5
)}
</div>`
return
view
}
return
view
},
/**
* Takes call data and converts it to a standard form
* @param {Object} data
* @returns {Object}
*/
_getCurrentCallData
(
data
)
{
let
result
=
{
queue
:
""
,
phone1
:
""
,
phone2
:
""
,
duration
:
""
,
}
// console.log("CHECK: ", "_getCurrentCallData", data);
switch
(
data
.
_type
)
{
case
"
ivr
"
:
// IVR
result
.
phone1
=
data
.
calleridnum
// номер звонящего
result
.
phone2
=
data
.
language
// внутренний номер агента
//result.queue = "" //data.queue_number // номер очереди агента
break
case
"
incom
"
:
// входящий выхов
result
.
phone1
=
data
.
calleridnum
// номер звонящего
result
.
phone2
=
(
data
.
_agentNumber
)
?
data
.
_agentNumber
:
data
.
connectedlinenum
// внутренний номер агента
result
.
queue
=
data
.
queue_number
// номер очереди агента
break
case
"
out
"
:
// исходящий выхов
result
.
phone1
=
data
.
outnum
// исходящий номер
result
.
phone2
=
data
.
_agentNumber
||
data
.
calleridnum
// || data.connectedlinenum // внутренний номер агента || номер
result
.
queue
=
data
.
queue_number
// номер очереди агента
break
case
"
outlines
"
:
// внутренний входящий номер
result
.
phone1
=
data
.
calleridnum
// номер
result
.
phone2
=
data
.
_agentNumber
||
data
.
calleridnum
// внутренний номер агента || номер
// result.queue = data.queue_number // номер очереди агента
break
}
result
.
duration
=
data
.
duration
// console.log("CallRES: ",result);
return
result
},
_getCurrentQueuesCalls
(
data
)
{
let
result
=
{
ivr
:
{
title
:
'
IVR
'
,
data
:
[]
},
in
:
{
title
:
'
Входящие
'
,
data
:
[]
},
out
:
{
title
:
'
Исходящие
'
,
data
:
[]
}
}
setData
(
"
ivr
"
,
this
.
_conf
.
calls
.
keys
.
ivr
)
setData
(
"
in
"
,
this
.
_conf
.
calls
.
keys
.
in
)
setData
(
"
out
"
,
this
.
_conf
.
calls
.
keys
.
out
)
return
result
function
setData
(
mainKey
,
args
)
{
$
.
each
(
args
,
(
none
,
key
)
=>
{
const
k
=
key
.
toLocaleLowerCase
()
$
.
each
(
data
[
key
],
(
phone
,
value
)
=>
{
if
(
k
===
'
outlines
'
)
{
if
(
value
.
channelstate
==
5
)
{
return
}
}
value
=
$
.
extend
({},
value
)
value
.
_agentNumber
=
phone
value
.
_type
=
key
.
toLocaleLowerCase
()
result
[
mainKey
].
data
.
push
(
value
)
})
})
}
},
/**
*
* @param {Array} data
* @returns {Array} array with html elements
*/
observersController
(
data
)
{
const
self
=
this
if
(
!
Array
.
isArray
(
data
))
{
return
''
}
return
data
.
map
(
d
=>
{
return
self
.
observerView
(
d
)
})
},
/**
* tempalte for observers
* @param {Object} data
* @returns {String|HTMLElement}
*/
observerView
(
data
)
{
const
{
IMG
,
USER
}
=
data
;
const
view
=
`<div class="row align-items-center m-0 mt-2 p-1">
<div class="col-2">
<img src="
${
IMG
}
"
class="w-100 rounded-circle">
</div>
<div class="col-8">
<p class="m-0">
${
USER
}
</p>
</div>
</div>`
;
return
view
;
},
/**
*
* @private __setAgents
* @param {Array} agents
* @returns {Map}
*/
__setAgents
(
agents
)
{
let
map
=
new
Map
()
$
.
each
(
agents
,
function
(
i
,
agent
)
{
map
.
set
(
agent
.
number
,
agent
)
})
this
.
agents
=
map
return
map
}
}
return
Quesue
}
template/trunks.php
View file @
cf61be32
...
@@ -76,8 +76,8 @@ var afterLoadPage = function(){
...
@@ -76,8 +76,8 @@ var afterLoadPage = function(){
*/
*/
var
trunksUpdate
=
function
(){
var
trunksUpdate
=
function
(){
//if(updatingTm == true){ return; }
doAloVoiceCmd
(
'
loadTrunksList
'
,
{},
function
(
res
)
{
loadAloVoiceInfo
(
"
alovoice_trunks_list
"
,
function
(
res
){
console
.
log
(
"
AloVoice Trunks RES:
"
,
res
);
console
.
log
(
"
AloVoice Trunks RES:
"
,
res
);
if
(
!
isHeadered
){
if
(
!
isHeadered
){
...
@@ -109,7 +109,7 @@ var afterLoadPage = function(){
...
@@ -109,7 +109,7 @@ var afterLoadPage = function(){
+
'
<td>
'
+
trunk
.
number
+
'
</td>
'
+
'
<td>
'
+
trunk
.
number
+
'
</td>
'
+
'
<td>
'
+
trunk
.
maxchannels
+
'
</td>
'
+
'
<td>
'
+
trunk
.
maxchannels
+
'
</td>
'
+
'
<td>
'
+
status
+
'
</td>
'
+
'
<td>
'
+
status
+
'
</td>
'
+
'
<td class="nowrp" ><a href="#" onClick="updateOneTrunk(
\'
'
+
trunk
.
id
+
'
\'
);"><i class="fa fa-money"></i>
Проверить
</a></td>
'
+
'
<td class="nowrp" ><a href="#" onClick="updateOneTrunk(
\'
'
+
trunk
.
id
+
'
\'
);"><i class="fa fa-money"></i>
Настройки
</a></td>
'
+
'
</tr>
'
;
+
'
</tr>
'
;
$
(
"
#alvtrunks_table_body
"
).
append
(
lineHTML
);
$
(
"
#alvtrunks_table_body
"
).
append
(
lineHTML
);
...
@@ -118,6 +118,48 @@ var afterLoadPage = function(){
...
@@ -118,6 +118,48 @@ var afterLoadPage = function(){
//setTimeout(donglesUpdate,100000);
//setTimeout(donglesUpdate,100000);
});
});
// loadAloVoiceInfo("alovoice_trunks_list",function(res){
// console.log("AloVoice Trunks RES:",res);
// if(!isHeadered){
// if(typeof res.headers != 'undefined' ){
// isHeadered = true;
// $("#alvtrunks_table_header").html('');
// $.each( res.headers, function( key, value ) {
// console.log("Each Header:",key, value);
// $("#alvtrunks_table_header").append('
<
th
id
=
"
hd_'+key+'
"
>
'
+value+
'
<
/th>'
)
;
// });
// }
// }
// if(typeof res.datas != 'undefined' ){
// $("#alvtrunks_table_body").html('');
// $.each( res.datas, function( tkey, trunk ) {
// console.log("Each Trunk:",trunk);
// /*var statusLine = (val.datas[2]=="free") ? '
<
span
style
=
"
color:green;
"
>
'
+val.datas[2]+
'
<
/span>' : val.datas
[
2
]
;
// var statusLine = (statusLine=="dialing") ? '
<
span
style
=
"
color:yellow;
"
>
'
+statusLine+
'
<
/span>' : statusLine;
// var statusLine = (statusLine=="outgoing") ? '
<
span
style
=
"
color:blue;
"
>
'
+statusLine+
'
<
/span>' : statusLine;
// //var statusLine = (val.datas[2]=="dialing") ? '
<
span
style
=
"
color:yellow;
"
>
'
+val.datas[2]+
'
<
/span>' : val.datas
[
2
]
;
// */
// let status = (trunk.status == 'On') ? '
<
span
class
=
"
active_tg_status badge badge-success
"
>
Активный
<
/span>' : '<span class="off_tg_status badge badge-secondary">Выключен</
span
>
'
;
// var lineHTML =
'
<
tr
class
=
"
alv_table_lines
"
id
=
"
trk_line_'+trunk.id+'
"
data
-
device
=
"
'+trunk.type+'
"
data
-
numcode
=
"
'+trunk.name+'
"
>
'
// +
'
<
td
class
=
"
nowrp
"
>
<
span
>
'
+trunk.id+
'
<
/span></
td
>
'
// +
'
<
td
class
=
"
nowrp
"
>
<
b
>
'
+trunk.name+
'
<
/b></
td
>
'
// +
'
<
td
class
=
"
nowrp
"
>
'
+trunk.type +
'
<
/td>'
// +'
<
td
>
'
+trunk.number+
'
<
/td>'
// +'
<
td
>
'
+trunk.maxchannels+
'
<
/td>'
// +'
<
td
>
'
+status+
'
<
/td>'
// +'
<
td
class
=
"
nowrp
"
><
a
href
=
"
#
"
onClick
=
"
updateOneTrunk(
\
''+trunk.id+'
\
');
"
><
i
class
=
"
fa fa-money
"
><
/i> Проверить</
a
><
/td>'
// +'
<
/tr>';
// $("#alvtrunks_table_body").append(lineHTML);
// });
// }
// //setTimeout(donglesUpdate,100000);
// });
}
}
trunksUpdate
();
trunksUpdate
();
...
...
vendor/alovoice/src/AloVoiceActions.php
View file @
cf61be32
...
@@ -189,7 +189,45 @@ class AloVoiceActions
...
@@ -189,7 +189,45 @@ class AloVoiceActions
return
false
;
return
false
;
}
}
public
function
getAlovoiceOperators
(){
public
function
getAlovoiceOperatorsNums
(
$r
=
false
){
$bxOnlineUsers
=
BxRest
::
call
(
"user.get"
,
array
(
'UF_PHONE_INNER'
=>
'_%'
,
//'IS_ONLINE' => 'Y',
));
$bxPhoneUsers
=
array
();
if
(
!
empty
(
$bxOnlineUsers
[
"result"
])){
foreach
(
$bxOnlineUsers
[
"result"
]
as
$bxonUser
){
$bxPhoneUsers
[
$bxonUser
[
"UF_PHONE_INNER"
]]
=
$bxonUser
;
}
}
return
$bxPhoneUsers
;
}
public
function
getAlovoiceAllQueues
(
$r
=
false
){
$arQueues
=
[];
$doCmds
=
$this
->
runAsteriskAction
([
'queues'
=>
new
\PAMI\Message\Action\QueueStatusAction
(),
]);
if
(
!
empty
(
$doCmds
[
'queues'
])){
$QueueStatusEvents
=
$doCmds
[
'queues'
]
->
getEvents
();
foreach
(
$QueueStatusEvents
as
$qevnt
){
$qKeys
=
$qevnt
->
getKeys
();
if
(
!
empty
(
$qKeys
[
"queue"
])
&&
$qKeys
[
"queue"
]
!=
"default"
){
$arQueues
[
$qKeys
[
"queue"
]]
=
$qKeys
[
"strategy"
];
// $arQueues[$qKeys["queue"]] = $qKeys;
// $arQueues[] = $qKeys["queue"];
}
}
}
return
$arQueues
;
}
public
function
getAlovoiceOperators
(
$r
=
false
){
$doCmds
=
$this
->
runAsteriskAction
([
$doCmds
=
$this
->
runAsteriskAction
([
'dnds'
=>
new
\PAMI\Message\Action\CommandAction
(
'database show DND'
),
'dnds'
=>
new
\PAMI\Message\Action\CommandAction
(
'database show DND'
),
...
...
vendor/alovoice/src/AloVoiceConnector.php
View file @
cf61be32
...
@@ -1189,6 +1189,7 @@ class AloVoiceConnector
...
@@ -1189,6 +1189,7 @@ class AloVoiceConnector
"dashboard"
=>
array
(
"name"
=>
"АлоВойс"
,
"perms"
=>
"all"
),
"dashboard"
=>
array
(
"name"
=>
"АлоВойс"
,
"perms"
=>
"all"
),
"queues"
=>
array
(
"name"
=>
"Звонки"
,
"perms"
=>
"all"
),
"queues"
=>
array
(
"name"
=>
"Звонки"
,
"perms"
=>
"all"
),
// "chdongles" => array( "name" => "GSM линии", "perms" => "admin"),
// "chdongles" => array( "name" => "GSM линии", "perms" => "admin"),
"inroutes"
=>
array
(
"name"
=>
"Входящие"
,
"perms"
=>
"admin"
),
"trunks"
=>
array
(
"name"
=>
"Линии"
,
"perms"
=>
"admin"
),
"trunks"
=>
array
(
"name"
=>
"Линии"
,
"perms"
=>
"admin"
),
"peers"
=>
array
(
"name"
=>
"Внут.номера"
,
"perms"
=>
"admin"
),
"peers"
=>
array
(
"name"
=>
"Внут.номера"
,
"perms"
=>
"admin"
),
// "stats" => array( "name" => "Статистика агентов", "perms" => "all"),
// "stats" => array( "name" => "Статистика агентов", "perms" => "all"),
...
...
vendor/alovoice/src/AloVoiceRest.php
View file @
cf61be32
...
@@ -1436,9 +1436,19 @@ sessid: 40512ed0288d707e78dc4f7ef25214ef
...
@@ -1436,9 +1436,19 @@ sessid: 40512ed0288d707e78dc4f7ef25214ef
return
$alvActions
->
doDndToggle
(
$r
);
return
$alvActions
->
doDndToggle
(
$r
);
}
}
private
function
alovoice_get_operators_nums
(
$r
=
false
)
{
$alvActions
=
new
AloVoiceActions
(
$this
->
config
);
return
$alvActions
->
getAlovoiceOperatorsNums
(
$r
);
}
private
function
alovoice_get_allqueues
(
$r
=
false
)
{
$alvActions
=
new
AloVoiceActions
(
$this
->
config
);
return
$alvActions
->
getAlovoiceAllQueues
(
$r
);
}
private
function
alovoice_get_operators
(
$r
=
false
)
{
private
function
alovoice_get_operators
(
$r
=
false
)
{
$alvActions
=
new
AloVoiceActions
(
$this
->
config
);
$alvActions
=
new
AloVoiceActions
(
$this
->
config
);
return
$alvActions
->
getAlovoiceOperators
();
return
$alvActions
->
getAlovoiceOperators
(
$r
);
}
}
private
function
alovoice_peers_list
(
$r
=
false
)
{
private
function
alovoice_peers_list
(
$r
=
false
)
{
...
@@ -1478,7 +1488,7 @@ sessid: 40512ed0288d707e78dc4f7ef25214ef
...
@@ -1478,7 +1488,7 @@ sessid: 40512ed0288d707e78dc4f7ef25214ef
return
$alvActions
->
getAlovoiceSounds
();
return
$alvActions
->
getAlovoiceSounds
();
}
}
private
function
alovoice_
trunk
s_list
(
$r
=
false
)
{
private
function
alovoice_
line
s_list
(
$r
=
false
)
{
$alvActions
=
new
AloVoiceActions
(
$this
->
config
);
$alvActions
=
new
AloVoiceActions
(
$this
->
config
);
return
$alvActions
->
getAlovoiceTrunks
();
return
$alvActions
->
getAlovoiceTrunks
();
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment