added CDR and LI access flags to admin view


			
			
				trunk@3605
			
			
		
Daniel Tiefnig 16 years ago
parent 9717fd5797
commit 3118da138c

@ -86,6 +86,10 @@ sub do_edit_admin : Local {
unless $admin eq $c->session->{admin}{login};
$settings{show_passwords} = $c->request->params->{show_passwords} ? 1 : 0
unless $admin eq $c->session->{admin}{login};
$settings{call_data} = $c->request->params->{call_data} ? 1 : 0
unless $admin eq $c->session->{admin}{login};
$settings{lawful_intercept} = $c->request->params->{lawful_intercept} ? 1 : 0
unless $admin eq $c->session->{admin}{login};
unless(keys %messages) {
if(keys %settings) {
@ -142,6 +146,8 @@ sub do_create_admin : Local {
$settings{is_active} = $c->request->params->{is_active} ? 1 : 0;
$settings{read_only} = $c->request->params->{read_only} ? 1 : 0;
$settings{show_passwords} = $c->request->params->{show_passwords} ? 1 : 0;
$settings{call_data} = $c->request->params->{call_data} ? 1 : 0;
$settings{lawful_intercept} = $c->request->params->{lawful_intercept} ? 1 : 0;
unless(keys %messages) {
if($c->model('Provisioning')->call_prov( $c, 'billing', 'create_admin',

@ -923,6 +923,176 @@ sub update_voicebox : Local {
return;
}
=head2 call_data
Display subscriber call list.
=cut
sub call_data : Local {
my ( $self, $c ) = @_;
$c->stash->{template} = 'tt/subscriber_call_data.tt';
my $subscriber_id = $c->request->params->{subscriber_id};
return unless $c->model('Provisioning')->call_prov( $c, 'voip', 'get_subscriber_byid',
{ subscriber_id => $subscriber_id },
\$c->session->{subscriber}
);
$c->stash->{subscriber} = $c->session->{subscriber};
$c->stash->{subscriber}{subscriber_id} = $subscriber_id;
my @localized_months = ( "foo" );
my $cts = $c->session->{subscriber}{create_timestamp};
if($cts =~ s/^(\d{4}-\d\d)-\d\d \d\d:\d\d:\d\d/$1/) {
my ($cyear, $cmonth) = split /-/, $cts;
my ($nyear, $nmonth) = (localtime)[5,4];
$nyear += 1900;
$nmonth++;
for(1 .. 12) {
push @localized_months,
$c->model('Provisioning')->localize($c->view($c->config->{view})->
config->{VARIABLES}{site_config}{language},
sprintf("Web.Months.%02d", $_));
}
my @selectmonths;
while($cyear < $nyear) {
my @yearmon;
for($cmonth .. 12) {
my $amon = sprintf("%02d", $_);
unshift @yearmon, { display => $localized_months[$amon] ." $cyear", link => $cyear.$amon };
}
unshift @selectmonths, { year => $cyear, months => \@yearmon };
$cmonth = 1;
$cyear++;
}
my @yearmon;
for($cmonth .. $nmonth) {
my $amon = sprintf("%02d", $_);
unshift @yearmon, { display => $localized_months[$amon] ." $cyear", link => $cyear.$amon };
}
unshift @selectmonths, { year => $cyear, months => \@yearmon };
$c->stash->{subscriber}{selectmonths} = \@selectmonths;
}
my $listfilter = $c->request->params->{list_filter};
if(defined $listfilter) {
if(length $listfilter) {
$listfilter =~ s/^\*//;
$listfilter =~ s/\*$//;
$c->session->{calllist}{filter} = $listfilter;
} else {
delete $c->session->{calllist}{filter};
undef $listfilter;
}
}
my @localtime = localtime;
my ($callmonth, $callyear);
my $monthselect = $c->request->params->{listmonth};
if(defined $monthselect and $monthselect =~ /^(\d{4})(\d{2})$/) {
$callyear = $1;
$callmonth = $2;
$listfilter = $c->session->{calllist}{filter};
delete $c->session->{calllist}{start};
delete $c->session->{calllist}{end};
} else {
$callyear = $localtime[5] + 1900;
$callmonth = $localtime[4] + 1;
delete $c->session->{calllist}{filter};
delete $c->session->{calllist}{start};
delete $c->session->{calllist}{end};
}
my $liststart = $c->request->params->{list_start};
if(defined $liststart) {
if(length $liststart) {
$c->stash->{subscriber}{list_start} = $liststart;
if($liststart =~ /^\d\d\.\d\d\.\d\d\d\d$/) {
$c->session->{calllist}{start} = $liststart;
} else {
$liststart = $c->session->{calllist}{start};
$c->session->{messages}{msgdate} = 'Client.Syntax.Date';
}
} else {
delete $c->session->{calllist}{start};
undef $liststart;
}
} else {
$c->stash->{subscriber}{list_start} = $c->session->{calllist}{start};
}
my $listend = $c->request->params->{list_end};
if(defined $listend) {
if(length $listend) {
$c->stash->{subscriber}{list_end} = $listend;
if($listend =~ /^\d\d\.\d\d\.\d\d\d\d$/) {
$c->session->{calls}{end} = $listend;
} else {
$listend = $c->session->{calllist}{end};
$c->session->{messages}{msgdate} = 'Client.Syntax.Date';
}
} else {
delete $c->session->{calllist}{end};
undef $listend;
}
} else {
$c->stash->{subscriber}{list_end} = $c->session->{calllist}{end};
}
my ($sdate, $edate);
if(!defined $liststart and !defined $listend) {
$sdate = { year => $callyear, month => $callmonth };
$edate = { year => $callyear, month => $callmonth };
$c->stash->{selected_month} = sprintf "%04d%02d", $callyear, $callmonth;
} else {
if(defined $liststart) {
my ($day, $month, $year) = split /\./, $liststart;
$sdate = { year => $year, month => $month, day => $day };
}
if (defined $listend) {
my ($day, $month, $year) = split /\./, $listend;
$edate = { year => $year, month => $month, day => $day };
}
}
my $calls;
return unless $c->model('Provisioning')->call_prov( $c, 'voip', 'get_subscriber_calls',
{ username => $c->session->{subscriber}{username},
domain => $c->session->{subscriber}{domain},
filter => { start_date => $sdate,
end_date => $edate,
}
},
\$calls
);
return unless $c->model('Provisioning')->call_prov( $c, 'billing', 'get_voip_account_by_id',
{ id => $c->session->{subscriber}{account_id} },
\$c->session->{voip_account}
);
if(eval { defined $c->session->{voip_account}{billing_profile} }) {
return 1 unless $c->model('Provisioning')->call_prov($c, 'billing', 'get_billing_profile',
{ handle => $c->session->{voip_account}{billing_profile} },
\$c->session->{voip_account}{billing_profile}
);
}
$c->stash->{call_list} = admin::Utils::prepare_call_list($c, $calls, $listfilter);
$c->stash->{subscriber}{list_filter} = $listfilter if defined $listfilter;
undef $c->stash->{call_list} unless eval { @{$c->stash->{call_list}} };
return;
}
sub edit_list : Local {
my ( $self, $c ) = @_;
$c->stash->{template} = 'tt/subscriber_edit_list.tt';

@ -2,6 +2,8 @@ package admin::Utils;
use strict;
use warnings;
use Time::Local;
# Takes a search result total count, an offset and a limit and returns
# an array containing offset values for a pagination link list
# where each page should list $limit elements.
@ -45,15 +47,15 @@ sub paginate {
#-# description gets default speed dial slot set from admin.conf
sub get_default_slot_list {
my ($c) = @_;
if (defined $c->config->{speed_dial_vsc_presets} and ref $c->config->{speed_dial_vsc_presets}->{vsc} eq 'ARRAY') {
return $c->config->{speed_dial_vsc_presets}->{vsc};
} else {
return [];
}
#my @slots = ();
#for (my $i = 0; $i < 10; $i++) {
# push @slots,'#' . $i;
#}
@ -67,7 +69,7 @@ sub get_default_slot_list {
#-# description gets a short representation of a (contract) contact
sub short_contact {
my ($c,$contact) = @_;
if (defined $contact->{company} and length($contact->{company})) {
return $contact->{company};
} elsif (defined $contact->{lastname} and length($contact->{lastname})) {
@ -91,7 +93,7 @@ sub short_contact {
#-# description defines contract contact form fields
sub get_contract_contact_form_fields {
my ($c,$contact) = @_;
return [ { field => 'firstname',
label => 'Firtst Name',
value => $contact->{firstname} },
@ -101,7 +103,7 @@ sub get_contract_contact_form_fields {
{ field => 'company',
label => 'Company',
value => $contact->{company} }];
}
sub get_qualified_number_for_subscriber {
@ -121,4 +123,119 @@ sub get_qualified_number_for_subscriber {
return $number;
}
# takes a catalyst session with subscriber information and a call list
# as returned by the prov. interface and returns a reference to an
# array suited for TT display
sub prepare_call_list {
my ($c, $call_list, $filter) = @_;
my $callentries = [];
my @time = localtime time;
my $tmtdy = timelocal(0,0,0,$time[3],$time[4],$time[5]);
if(defined $filter and length $filter) {
$filter =~ s/\*/.*/g;
} else {
undef $filter;
}
my $b = '';
my $ccdp = $c->config->{cc_dial_prefix};
foreach my $call (@$call_list) {
my %callentry;
$callentry{background} = $b ? '' : 'tr_alt';
my @date = localtime $$call{start_time};
$date[5] += 1900;
$date[4]++;
$callentry{date} = sprintf("%02d.%02d.%04d %02d:%02d:%02d", @date[3,4,5,2,1,0]);
if($$call{duration}) {
my $duration = $$call{duration};
while($duration > 59) {
my $left = sprintf("%02d", $duration % 60);
$callentry{duration} = ":$left". (defined $callentry{duration} ? $callentry{duration} : '');
$duration = int($duration / 60);
}
$callentry{duration} = defined $callentry{duration} ? sprintf("%02d", $duration) . $callentry{duration}
: sprintf("00:%02d", $duration);
} elsif($$call{call_status} eq 'ok') {
$callentry{duration} = '00:00';
}
if(defined $$call{call_fee}) {
# money is allways returned as cents
$callentry{call_fee} = sprintf $c->session->{voip_account}{billing_profile}{data}{currency} . " %.04f", $$call{call_fee}/100;
} else {
$callentry{call_fee} = '';
}
if(defined $$call{source_user}
and $$call{source_user} eq $c->session->{subscriber}{username}
and $$call{source_domain} eq $c->session->{subscriber}{domain})
{
if($$call{call_status} eq 'ok') {
$callentry{direction_icon} = 'anruf_aus_small.gif';
} else {
$callentry{direction_icon} = 'anruf_aus_err_small.gif';
}
if($$call{destination_user} =~ /^\+?\d+$/) {
my $partner = $$call{destination_user};
$partner =~ s/^$ccdp/+/;
$partner =~ s/^\+*/+/;
$callentry{partner} = $partner;
} else {
$callentry{partner} = $$call{destination_user} .'@'. $$call{destination_domain};
}
$callentry{partner_number} = $callentry{partner};
} elsif(defined $$call{destination_user}
and $$call{destination_user} eq $c->session->{subscriber}{username}
and $$call{destination_domain} eq $c->session->{subscriber}{domain})
{
if($$call{call_status} eq 'ok') {
$callentry{direction_icon} = 'anruf_ein_small.gif';
} else {
$callentry{direction_icon} = 'anruf_ein_err_small.gif';
}
if(!defined $$call{source_cli} or !length $$call{source_cli}
or $$call{source_cli} !~ /^\+?\d+$/)
{
if(!defined $$call{source_user} or !length $$call{source_user}) {
$callentry{partner} = 'anonym';
} elsif($$call{source_user} =~ /^\+?\d+$/) {
my $partner = $$call{source_user};
$partner =~ s/^$ccdp/+/;
$partner =~ s/^\+*/+/;
$callentry{partner} = $partner;
} else {
$callentry{partner} = $$call{source_user} .'@'. $$call{source_domain};
}
} else {
my $partner = $$call{source_cli};
$partner =~ s/^$ccdp/+/;
$partner =~ s/^\+*/+/;
$callentry{partner} = $partner;
}
$callentry{partner_number} = $callentry{partner};
} else {
$c->log->error("***Utils::prepare_call_list no match on user in call list");
next;
}
if(defined $filter) {
next unless $callentry{partner} =~ /$filter/i;
}
push @$callentries, \%callentry;
$b = !$b;
}
return $callentries;
}
1;

@ -43,7 +43,7 @@ h3 {
/* hmm, menu doesn't extend container height ... */
#container #content {
min-height: 570px;
min-height: 580px;
}
/* contentmenu's width and contentplace' margin-left should match */
@ -407,7 +407,7 @@ ul#topsubmenu {
/* colorful table rows */
#contentplace .tr_alt {
background-color: #ccffcc;
background-color: #eeffee;
}
#contentplace .orders,
@ -483,3 +483,70 @@ ul#topsubmenu {
#save_local_ac {
margin: 0 0 0 15px;
}
/* CDR display styles */
#contentplace .sortcalllist {
margin: 0px;
padding: 4px 0;
}
#contentplace .sortcalllist img {
vertical-align: middle;
padding: 0 0 2px 10px;
}
#contentplace .calllist {
width: 100%;
margin: 0 0 10px 0;
padding: 0px;
border: none;
border-collapse: collapse;
border-top: 1px solid #D0DCDF;
}
#contentplace .calllist td {
margin: 0px;
padding: 3px 5px;
vertical-align: top;
}
#contentplace .calllist .calllistheader td {
padding: 10px 0 3px 0;
font-weight: bold;
}
#contentplace .calllist .calltype {
width: 20px;
}
#contentplace .calllist .calltype img {
margin: 1px 0 0 0;
}
/* #contentplace .calllist .callnumber, */
#contentplace .calllist .callduration {
text-align: right;
}
#contentplace .calllist .callfee,
#contentplace .calllist .calldate {
text-align: right;
white-space: nowrap;
}
/* column layout using tables */
#columns31 {
width: 100%;
}
#columns31 .column1 {
width: 75%;
vertical-align: top;
}
#columns31 .column2 {
width: 25%;
border-left: 1px solid #D0DCDF;
vertical-align: top;
}
/* CDR search styles */
#contentplace h3#search_cdr {
margin-top: 1px;
}
#contentplace #callsearch select {
margin: 2px 0 10px 0;
}
#contentplace #callsearch input {
margin: 2px 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

@ -12,6 +12,10 @@
<td>active</td>
<td> r/o </td>
<td> PW </td>
<td> CDR </td>
[% IF Catalyst.config.lawful_intercept %]
<td> LI </td>
[% END %]
<td />
<td />
</tr>
@ -46,8 +50,22 @@
<input type="checkbox" class="checkbox" name="show_passwords"
[% IF admin.login == Catalyst.session.admin.login %]disabled="disabled"[% END %]
[% IF erefill.show_passwords or !erefill && admin.show_passwords %]checked="checked" [% END %]
title="if checked, the new administrator may view subscriber passwords" />
title="if checked, the administrator may view subscriber passwords" />
</td>
<td class="tdcenter">
<input type="checkbox" class="checkbox" name="call_data"
[% IF admin.login == Catalyst.session.admin.login %]disabled="disabled"[% END %]
[% IF erefill.call_data or !erefill && admin.call_data %]checked="checked" [% END %]
title="if checked, the administrator may view call detail records" />
</td>
[% IF Catalyst.config.lawful_intercept %]
<td class="tdcenter">
<input type="checkbox" class="checkbox" name="lawful_intercept"
[% IF admin.login == Catalyst.session.admin.login %]disabled="disabled"[% END %]
[% IF erefill.lawful_intercept or !erefill && admin.lawful_intercept %]checked="checked" [% END %]
title="if checked, the administrator may view and set lawful interceptions" />
</td>
[% END %]
<td>
<div class="postlink">
<label for="admsave[% id %]">save</label>
@ -76,8 +94,20 @@
<td class="tdcenter">
<input type="checkbox" class="checkbox" disabled="disabled"
[% IF admin.show_passwords %] checked="checked"[% END %]
title="if checked, the new administrator may view subscriber passwords" />
title="if checked, the administrator may view subscriber passwords" />
</td>
<td class="tdcenter">
<input type="checkbox" class="checkbox" disabled="disabled"
[% IF admin.call_data %] checked="checked"[% END %]
title="if checked, the administrator may view call detail records" />
</td>
[% IF Catalyst.config.lawful_intercept %]
<td class="tdcenter">
<input type="checkbox" class="checkbox" disabled="disabled"
[% IF admin.lawful_intercept %] checked="checked"[% END %]
title="if checked, the administrator may view and set lawful interceptions" />
</td>
[% END %]
<td>
[% UNLESS Catalyst.session.admin.read_only && admin.login != Catalyst.session.admin.login %]
<a href="/admin?edit_admin=[% admin.login %]" class="aaction">edit</a>
@ -165,6 +195,24 @@
title="if checked, the new administrator may view subscriber passwords" />
</td>
</tr>
<tr>
<td>show CDR data:</td>
<td>
<input type="checkbox" class="checkbox" name="call_data"
[% IF arefill.call_data %]checked="checked"[% END %]
title="if checked, the new administrator may view call detail records" />
</td>
</tr>
[% IF Catalyst.config.lawful_intercept %]
<tr>
<td>lawful intercepts:</td>
<td>
<input type="checkbox" class="checkbox" name="lawful_intercept"
[% IF arefill.lawful_intercept %]checked="checked"[% END %]
title="if checked, the new administrator may view and set lawful interceptions" />
</td>
</tr>
[% END %]
<tr>
<td>
<div class="postlink">

@ -0,0 +1,107 @@
<h3> Subscriber
<a class="noarrow" href="detail?subscriber_id=[% subscriber.subscriber_id %]">
[% subscriber.username %]@[% subscriber.domain %]</a>
</h3>
<ul id="topsubmenu">
<li>|</li>
<li class="inactive_submenu"><a href="detail?subscriber_id=[% subscriber.subscriber_id %]">User</a></li>
<li>|</li>
<li class="inactive_submenu"><a href="preferences?subscriber_id=[% subscriber.subscriber_id %]">Preferences</a></li>
<li>|</li>
[% IF Catalyst.session.admin.call_data %]
<li class="active_submenu"><a href="call_data?subscriber_id=[% subscriber.subscriber_id %]">CDRs</a></li>
<li>|</li>
[% END %]
</ul><br />
<hr id="topsubmenuhr" />
<h3 id="calldata">Call Data</h3>
<div class="p1">
<table id="columns31">
<tr>
<td class="column1">
<p class="sortcalllist">
<img src="/static/images/anruf_ein_small.gif" width="14" height="13" alt=""> incoming
<img src="/static/images/anruf_ein_err_small.gif" width="14" height="13" alt=""> missed
<img src="/static/images/anruf_aus_small.gif" width="14" height="13" alt=""> outgoing
<img src="/static/images/anruf_aus_err_small.gif" width="14" height="13" alt=""> failed
</p>
<table class="calllist">
[% IF call_list %]
<tr class="calllistheader">
<td />
<td class="callnumber">number</td>
<td class="callduration">duration</td>
[% IF Catalyst.config.billing_features %]
<td class="callfee">charges</td>
[% END %]
<td class="calldate">date</td>
</tr>
[% FOREACH callentry = call_list %]
<tr class="[% callentry.background %]">
<td class="calltype"><img src="/static/images/[% callentry.direction_icon %]" width="14" height="13" alt=""></td>
<td class="callnumber">[% callentry.partner %]</td>
<td class="callduration">[% callentry.duration %]</td>
[% IF Catalyst.config.billing_features %]
<td class="callfee">[% callentry.call_fee %]</td>
[% END %]
<td class="calldate">[% callentry.date %]</td>
</tr>
[% END %]
[% ELSE %]
<tr class="calllistheader"><td colspan="6" /></tr>
<tr class="alt">
<td colspan="6">No matching calls found.</td>
</tr>
[% END %]
</table>
</td>
<td class="column2">
<h3 id="search_cdr">Search</h3>
<form id="callsearch" method="post">
<label>select month</label><br />
<select name="listmonth">
<option> </option>
[% FOREACH year = subscriber.selectmonths %]
[% FOREACH month = year.months %]
<option value="[% month.link %]" [% 'selected="selected"' IF month.link == selected_month %]>[% month.display %]</option>
[% END %]
[% END %]
</select><br />
<label for="search_from">or from (DD.MM.YYYY)</label><br />
<input type="text" id="search_from" name="list_start" size="10" value="[% subscriber.list_start %]" /><br />
<label for="search_to">and to (DD.MM.YYYY)</label><br />
<input type="text" id="search_to" name="list_end" size="10" value="[% subscriber.list_end %]"/><br />
<div id="errormsg"><p>[% messages.msgdate %]</p></div>
<label for="search_filter">search term</label><br />
<input type="text" id="search_filter" name="list_filter" size="15" value="[% subscriber.list_filter %]" />
<br />
<br />
<div class="postlink">
<label for="calllist_apply_filter">apply filter</label><br />
<input type="image" class="hidden" src="/static/images/dot_trans.gif" alt="" id="calllist_apply_filter" />
</div>
</form>
</td>
</tr>
</table>
</div>

@ -10,6 +10,10 @@
<li>|</li>
<li class="inactive_submenu"><a href="preferences?subscriber_id=[% subscriber.subscriber_id %]">Preferences</a></li>
<li>|</li>
[% IF Catalyst.session.admin.call_data %]
<li class="inactive_submenu"><a href="call_data?subscriber_id=[% subscriber.subscriber_id %]">CDRs</a></li>
<li>|</li>
[% END %]
</ul><br />
<hr id="topsubmenuhr" />
@ -22,6 +26,10 @@
<li>|</li>
<li class="inactive_submenu">Preferences</li>
<li>|</li>
[% IF Catalyst.session.admin.call_data %]
<li class="inactive_submenu">CDRs</li>
<li>|</li>
[% END %]
</ul><br />
<hr id="topsubmenuhr" />

@ -9,6 +9,10 @@
<li>|</li>
<li class="active_submenu"><a href="preferences?subscriber_id=[% subscriber.subscriber_id %]">Preferences</a></li>
<li>|</li>
[% IF Catalyst.session.admin.call_data %]
<li class="inactive_submenu"><a href="call_data?subscriber_id=[% subscriber.subscriber_id %]">CDRs</a></li>
<li>|</li>
[% END %]
</ul><br />
<hr id="topsubmenuhr" />

Loading…
Cancel
Save