diff --git a/lib/admin/Controller/admin.pm b/lib/admin/Controller/admin.pm index a2b280c..869db8c 100644 --- a/lib/admin/Controller/admin.pm +++ b/lib/admin/Controller/admin.pm @@ -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', diff --git a/lib/admin/Controller/subscriber.pm b/lib/admin/Controller/subscriber.pm index b17e94a..a5c5287 100644 --- a/lib/admin/Controller/subscriber.pm +++ b/lib/admin/Controller/subscriber.pm @@ -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'; diff --git a/lib/admin/Utils.pm b/lib/admin/Utils.pm index fcb6ec5..133fd0f 100644 --- a/lib/admin/Utils.pm +++ b/lib/admin/Utils.pm @@ -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; diff --git a/root/css/admin.css b/root/css/admin.css index 9e30d40..51a235a 100644 --- a/root/css/admin.css +++ b/root/css/admin.css @@ -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; +} diff --git a/root/static/images/anruf_alle_small.gif b/root/static/images/anruf_alle_small.gif new file mode 100644 index 0000000..df6421b Binary files /dev/null and b/root/static/images/anruf_alle_small.gif differ diff --git a/root/static/images/anruf_aus_err_small.gif b/root/static/images/anruf_aus_err_small.gif new file mode 100644 index 0000000..11e6d42 Binary files /dev/null and b/root/static/images/anruf_aus_err_small.gif differ diff --git a/root/static/images/anruf_aus_small.gif b/root/static/images/anruf_aus_small.gif new file mode 100644 index 0000000..3519b15 Binary files /dev/null and b/root/static/images/anruf_aus_small.gif differ diff --git a/root/static/images/anruf_ein_err_small.gif b/root/static/images/anruf_ein_err_small.gif new file mode 100644 index 0000000..e831235 Binary files /dev/null and b/root/static/images/anruf_ein_err_small.gif differ diff --git a/root/static/images/anruf_ein_small.gif b/root/static/images/anruf_ein_small.gif new file mode 100644 index 0000000..0a58f87 Binary files /dev/null and b/root/static/images/anruf_ein_small.gif differ diff --git a/root/tt/admin.tt b/root/tt/admin.tt index a7e0c69..a51715a 100644 --- a/root/tt/admin.tt +++ b/root/tt/admin.tt @@ -12,6 +12,10 @@
|
+
+
+
|
+
+ Search+ + |
+ ||||||||||||||||||||||