diff --git a/lib/NGCP/Panel.pm b/lib/NGCP/Panel.pm index c8af5af78b..7eb8a683e7 100644 --- a/lib/NGCP/Panel.pm +++ b/lib/NGCP/Panel.pm @@ -57,9 +57,6 @@ __PACKAGE__->config( }, 'View::HTML' => { INCLUDE_PATH => [ - '/usr/share/ngcp-panel/templates', - '/usr/share/ngcp-panel/layout', - '/usr/share/ngcp-panel/static', __PACKAGE__->path_to('share', 'templates'), __PACKAGE__->path_to('share', 'layout'), __PACKAGE__->path_to('share', 'static'), @@ -67,6 +64,16 @@ __PACKAGE__->config( ABSOLUTE => 1, EVAL_PERL => 1, }, + 'View::SVG' => { + INCLUDE_PATH => [ + __PACKAGE__->path_to('share', 'templates'), + __PACKAGE__->path_to('share', 'layout'), + __PACKAGE__->path_to('share', 'static'), + ], + ABSOLUTE => 1, + EVAL_PERL => 1, + WRAPPER => '', + }, 'View::JSON' => { #Set the stash keys to be exposed to a JSON response #(sEcho iTotalRecords iTotalDisplayRecords aaData) for datatables @@ -75,7 +82,6 @@ __PACKAGE__->config( 'Plugin::Static::Simple' => { include_path => [ - '/usr/share/ngcp-panel/static', __PACKAGE__->path_to('share', 'static'), ], mime_types => { diff --git a/lib/NGCP/Panel/Controller/Customer.pm b/lib/NGCP/Panel/Controller/Customer.pm index 8698726cf5..e77bfd888a 100644 --- a/lib/NGCP/Panel/Controller/Customer.pm +++ b/lib/NGCP/Panel/Controller/Customer.pm @@ -53,30 +53,7 @@ sub list_customer :Chained('/') :PathPart('customer') :CaptureArgs(0) { { name => "status", search => 1, title => $c->loc("Status") }, { name => "max_subscribers", search => 1, title => $c->loc("Max Number of Subscribers") }, ]); - - my $rs = NGCP::Panel::Utils::Contract::get_contract_rs( - schema => $c->model('DB')); - if($c->user->roles eq "reseller") { - $rs = $rs->search({ - 'contact.reseller_id' => $c->user->reseller_id, - }, { - join => 'contact', - }); - } elsif($c->user->roles eq "subscriberadmin") { - $rs = $rs->search({ - 'contact.reseller_id' => $c->user->contract->contact->reseller_id, - }, { - join => 'contact', - }); - } - $rs = $rs->search({ - '-or' => [ - 'product.class' => 'sipaccount', - 'product.class' => 'pbxaccount', - ], - }, { - 'join' => {'billing_mappings' => 'product'}, - }); + my $rs = NGCP::Panel::Utils::Contract::get_contracts_rs_sippbx( c => $c ); $c->stash( contract_select_rs => $rs, @@ -238,7 +215,6 @@ sub base :Chained('list_customer') :PathPart('') :CaptureArgs(1) { $c->detach('/denied_page'); } } - unless(defined($contract_rs->first)) { NGCP::Panel::Utils::Message->error( c => $c, @@ -252,6 +228,7 @@ sub base :Chained('list_customer') :PathPart('') :CaptureArgs(1) { my $stime = NGCP::Panel::Utils::DateTime::current_local()->truncate(to => 'month'); my $etime = $stime->clone->add(months => 1); + my $balance = $contract_rs->first->contract_balances ->find({ start => { '>=' => $stime }, @@ -280,12 +257,20 @@ sub base :Chained('list_customer') :PathPart('') :CaptureArgs(1) { }); } + my $zonecalls_rs = NGCP::Panel::Utils::Contract::get_contract_calls_rs( + c => $c, + contract_id => $contract_id, + stime => $stime, + etime => $etime, + ); + my $product_id = $contract_rs->first->get_column('product_id'); NGCP::Panel::Utils::Message->error( c => $c, error => "No product for customer contract id $contract_id found", desc => $c->loc('No product for this customer contract found.'), ) unless($product_id); + my $product = $c->model('DB')->resultset('products')->find($product_id); NGCP::Panel::Utils::Message->error( c => $c, @@ -318,6 +303,7 @@ sub base :Chained('list_customer') :PathPart('') :CaptureArgs(1) { $c->stash(template => 'customer/details.tt'); $c->stash(contract => $contract_rs->first); $c->stash(contract_rs => $contract_rs); + $c->stash(zonecalls_rs => $zonecalls_rs); $c->stash(billing_mapping => $billing_mapping); } @@ -715,6 +701,40 @@ sub edit_balance :Chained('base') :PathPart('balance/edit') :Args(0) { $c->stash(form => $form); $c->stash(edit_flag => 1); } +#https://10.15.20.100:1444/customer/3/balance/edit?back=https%3A%2F%2F10.15.20.100%3A1444%2Fcustomer%2F3%2Fdetails +sub calls :Chained('base') :PathPart('calls') :Args(0) { + my ($self, $c) = @_; + +# my $contract_id = $c->stash->{contract}->id; +# my $stime = NGCP::Panel::Utils::DateTime::current_local()->truncate(to => 'month'); +# my $etime = $stime->clone->add(months => 1); + +# my $zonecalls_rs = NGCP::Panel::Utils::Contract::get_contract_calls_rs( +# c => $c, +# contract_id => $contract_id, +# stime => $stime, +# etime => $etime, +# ); + $c->stash(template => 'customer/calls.tt'); + #$c->stash(zonecalls_rs => $c->stash{zonecalls_rs}); + #$c->detach($c->view('SVG')); +# return; + #$c->response->body(JSON::to_json({ methods => $allowed_methods })."\n"); + #$c->stash(template => 'customer/calls_svg.tt'); + + #$c->stash(close_target => $c->uri_for_action("/customer/details", [$c->stash->{contract}->id])); + #$c->stash(template => 'customer/calls.tt'); +# $c->stash(contract => $contract_rs->first); +} +sub calls_svg :Chained('base') :PathPart('calls/svg') :Args(0) { + my ($self, $c) = @_; + + #die(); + #$c->view('SVG'); + $c->response->content_type('image/svg+xml'); + $c->stash(template => 'customer/calls_svg.tt'); + $c->detach($c->view('SVG')); +} sub pbx_group_ajax :Chained('base') :PathPart('pbx/group/ajax') :Args(0) { my ($self, $c) = @_; diff --git a/lib/NGCP/Panel/Role/API/Customers.pm b/lib/NGCP/Panel/Role/API/Customers.pm index 0d99ad8a9c..57234fcde4 100644 --- a/lib/NGCP/Panel/Role/API/Customers.pm +++ b/lib/NGCP/Panel/Role/API/Customers.pm @@ -87,36 +87,9 @@ sub hal_from_customer { sub customer_by_id { my ($self, $c, $id) = @_; - - # we only return customers, that is, contracts with contacts with a - # reseller - my $customers = NGCP::Panel::Utils::Contract::get_contract_rs( - schema => $c->model('DB'), + my $customers = NGCP::Panel::Utils::Contract::get_contracts_rs_sippbx( + c => $c, ); - $customers = $customers->search({ - 'contact.reseller_id' => { '-not' => undef }, - },{ - join => 'contact' - }); - - $customers = $customers->search({ - '-or' => [ - 'product.class' => 'sipaccount', - 'product.class' => 'pbxaccount', - ], - },{ - join => {'billing_mappings' => 'product' }, - '+select' => 'billing_mappings.id', - '+as' => 'bmid', - }); - - if($c->user->roles eq "admin") { - } elsif($c->user->roles eq "reseller") { - $customers = $customers->search({ - 'contact.reseller_id' => $c->user->reseller_id, - }); - } - return $customers->find($id); } diff --git a/lib/NGCP/Panel/Utils/Contract.pm b/lib/NGCP/Panel/Utils/Contract.pm index 3b5cdd7c32..beb7bdd7e1 100644 --- a/lib/NGCP/Panel/Utils/Contract.pm +++ b/lib/NGCP/Panel/Utils/Contract.pm @@ -191,6 +191,95 @@ sub get_contract_rs { return $rs; } +sub get_contracts_rs_sippbx{ + my %params = @_; + #pass here $c isn't very good idea, it doesn't allow "simple" call with really relevant information + my $c = $params{c}; + # we only return customers, that is, contracts with contacts with a + # reseller + my $customers = get_contract_rs( + schema => $c->model('DB'), + ); + #really here we don't need role - we can pass only reseller_id, reseller_id should be tacken according to role in other method + my @reseller_condition = ({ '-not' => undef }); + if($c->user->roles eq "reseller") { + push @reseller_condition, $c->user->reseller_id; + } elsif($c->user->roles eq "subscriberadmin") { + push @reseller_condition, $c->user->contract->contact->reseller_id; + } elsif($c->user->roles eq "admin") { + } + my $reseller_condition = $#reseller_condition > 1 + ? { '-and' => \@reseller_condition } + : $reseller_condition[0]; + $customers = $customers->search({ + 'contact.reseller_id' => $reseller_condition , + },{ + join => 'contact' + }); + + $customers = $customers->search({ + '-or' => [ + 'product.class' => 'sipaccount', + 'product.class' => 'pbxaccount', + ], + },{ + join => {'billing_mappings' => 'product' }, + '+select' => 'billing_mappings.id', + '+as' => 'bmid', + }); + + return $customers; +} + +sub get_contract_calls_rs{ + my %params = @_; + (my ($c,$contract_id,$stime,$etime)) = @params{qw/c contract_id stime etime/}; + + # SELECT 'out' as direction, SUM(c.source_customer_cost) AS cost, b.zone, + # COUNT(*) AS number, SUM(c.duration) AS duration + # FROM accounting.cdr c + # LEFT JOIN billing.voip_subscribers v ON c.source_user_id = v.uuid + # LEFT JOIN billing.billing_zones_history b ON b.id = c.source_customer_billing_zone_id + # WHERE v.contract_id = ? + # AND c.call_status = 'ok' + # $start_time $end_time + # GROUP BY b.zone + + my $zonecalls_rs = $c->model('DB')->resultset('cdr')->search( { +# source_user_id => { 'in' => [ map {$_->uuid} @{$contract->{subscriber}} ] }, + call_status => 'ok', + source_user_id => { '!=' => '0' }, + source_account_id => $contract_id, + # start_time => + # [ -and => + # { '>=' => $stime->epoch}, + # { '<=' => $etime->epoch}, + # ], + + # { + # '>=' => ["unix_timestamp(?)", $stime], +# '<=' => ["unix_timestamp(?)",$etime] }, +# { '>=' => \[ "unix_timestamp(?)", $stime ] }, +# { '<=' => \[ "unix_timestamp(?)", $etime ] }, +#requires fix: 757 #$self->_assert_bindval_matches_bindtype(@sub_bind); +#in SQL::Abstract, + + },{ + 'select' => [ + { sum => 'me.source_customer_cost', -as => 'cost', }, + { sum => 'me.source_customer_free_time', -as => 'free_time', } , + { sum => 'me.duration', -as => 'duration', } , + { count => '*', -as => 'number', } , + 'billing_zones_history.zone', + ], + 'as' => [qw/cost free_time duration number zone/], + join => 'billing_zones_history', + group_by => 'billing_zones_history.zone', + } ); + + return $zonecalls_rs; +} + 1; =head1 NAME diff --git a/lib/NGCP/Panel/View/SVG.pm b/lib/NGCP/Panel/View/SVG.pm new file mode 100644 index 0000000000..da02cc512d --- /dev/null +++ b/lib/NGCP/Panel/View/SVG.pm @@ -0,0 +1,28 @@ +package NGCP::Panel::View::SVG; + +use Sipwise::Base; +use NGCP::Panel::Utils::I18N; + +use strict; +extends 'Catalyst::View::TT'; + + +__PACKAGE__->config( + TEMPLATE_EXTENSION => '.tt', + render_die => 1, + ENCODING => 'UTF-8', + WRAPPER => '', + FILTERS => {}, + ABSOLUTE => 0, + expose_methods => [], +); + +sub process +{ + my ( $self, $c ) = @_; + $c->res->content_type("image/svg+xml"); + $self->SUPER::process($c); + return 1; +} + +1; \ No newline at end of file diff --git a/share/templates/customer/calls.tt b/share/templates/customer/calls.tt new file mode 100644 index 0000000000..44ba397399 --- /dev/null +++ b/share/templates/customer/calls.tt @@ -0,0 +1,195 @@ +[% IF c.user.roles == "subscriber" || c.user.roles == "subscriberadmin" -%] + [% site_config.title = c.loc('Customer Calls') -%] +[% ELSE -%] + [% site_config.title = c.loc('Customer Calls for #[_1] ([_2])',contract.id, product.name) -%] +[% END -%] + +[% BLOCK accordion_group_internal %] +