package NGCP::Panel::Role::API::CallLists; use Moose::Role; use Sipwise::Base; with 'NGCP::Panel::Role::API' => { -alias =>{ item_rs => '_item_rs', }, -excludes => [ 'item_rs' ], }; use boolean qw(true); use TryCatch; use Data::HAL qw(); use Data::HAL::Link qw(); use HTTP::Status qw(:constants); use POSIX; use DateTime::Format::Strptime; use NGCP::Panel::Utils::DateTime; use NGCP::Panel::Utils::Subscriber; use NGCP::Panel::Form::CallList::Subscriber; sub item_rs { my ($self, $c) = @_; my $item_rs = $c->model('DB')->resultset('cdr'); if($c->user->roles eq "admin") { } elsif($c->user->roles eq "reseller") { $item_rs = $item_rs->search({ -or => [ { source_provider_id => $c->user->reseller->contract_id }, { destination_provider_id => $c->user->reseller->contract_id }, ], }); } elsif($c->user->roles eq "subscriberadmin") { $item_rs = $item_rs->search({ -or => [ { 'source_account_id' => $c->user->account_id }, { 'destination_account_id' => $c->user->account_id }, ], }); } else { $item_rs = $item_rs->search({ -or => [ { 'source_subscriber.id' => $c->user->voip_subscriber->id }, { 'destination_subscriber.id' => $c->user->voip_subscriber->id }, ], },{ join => ['source_subscriber', 'destination_subscriber'], }); } return $item_rs; } sub get_form { my ($self, $c) = @_; if($c->user->roles eq "admin") { return NGCP::Panel::Form::CallList::Subscriber->new; } elsif($c->user->roles eq "reseller") { return NGCP::Panel::Form::CallList::Subscriber->new; } else { return NGCP::Panel::Form::CallList::Subscriber->new; } } sub hal_from_item { my ($self, $c, $item, $sub, $form) = @_; my $resource = $self->resource_from_item($c, $item, $sub, $form); my $hal = Data::HAL->new( links => [ Data::HAL::Link->new( relation => 'curies', href => 'http://purl.org/sipwise/ngcp-api/#rel-{rel}', name => 'ngcp', templated => true, ), Data::HAL::Link->new(relation => 'collection', href => sprintf("/api/%s/", $self->resource_name)), Data::HAL::Link->new(relation => 'profile', href => 'http://purl.org/sipwise/ngcp-api/'), Data::HAL::Link->new(relation => 'self', href => sprintf("%s%d?subscriber_id=%d", $self->dispatch_path, $item->id, $sub->id)), # todo: customer can be in source_account_id or destination_account_id # Data::HAL::Link->new(relation => 'ngcp:customers', href => sprintf("/api/customers/%d", $item->source_customer_id)), ], relation => 'ngcp:'.$self->resource_name, ); $form //= $self->get_form($c); $self->validate_form( c => $c, resource => $resource, form => $form, run => 0, exceptions => [], ); $resource->{id} = int($item->id); $hal->resource($resource); return $hal; } sub resource_from_item { my ($self, $c, $item, $sub, $form) = @_; my $resource = {}; my $datetime_fmt = DateTime::Format::Strptime->new( pattern => '%F %T', ); my $intra = 0; if($item->source_user_id && $item->source_account_id == $item->destination_account_id) { $resource->{intra_customer} = JSON::true; $intra = 1; } else { $resource->{intra_customer} = JSON::false; $intra = 0; } $resource->{direction} = $sub->uuid eq $item->source_user_id ? "out" : "in"; my ($src_sub, $dst_sub); if($item->source_subscriber && $item->source_subscriber->provisioning_voip_subscriber) { $src_sub = $item->source_subscriber->provisioning_voip_subscriber; } if($item->destination_subscriber && $item->destination_subscriber->provisioning_voip_subscriber) { $dst_sub = $item->destination_subscriber->provisioning_voip_subscriber; } my ($own_normalize, $other_normalize); if($resource->{direction} eq "out") { # for pbx out calls, use extension as own cli if($src_sub && $src_sub->pbx_extension) { $resource->{own_cli} = $src_sub->pbx_extension; } else { $resource->{own_cli} = $item->source_cli; $own_normalize = 1; } # for intra pbx out calls, use extension as other cli if($intra && $dst_sub && $dst_sub->pbx_extension) { $resource->{other_cli} = $dst_sub->pbx_extension; # if there is an alias field (e.g. gpp0), use this } elsif($item->destination_account_id && $c->req->param('alias_field')) { my $alias = $item->get_column('destination_'.$c->req->param('alias_field')); $c->log->error("+++++++++++++++++ alias_field=".$c->req->param('alias_field')); $c->log->error("+++++++++++++++++ destination_alias_field=".($alias // '')); $resource->{other_cli} = $alias // $item->destination_user_in; $other_normalize = 1; } else { $resource->{other_cli} = $item->destination_user_in; $other_normalize = 1; } } else { # for pbx in calls, use extension as own cli if($dst_sub && $dst_sub->pbx_extension) { $resource->{own_cli} = $dst_sub->pbx_extension; } else { $resource->{own_cli} = $item->destination_user_in; $own_normalize = 1; } # for intra pbx in calls, use extension as other cli if($intra && $src_sub && $src_sub->pbx_extension) { $resource->{other_cli} = $src_sub->pbx_extension; # if there is an alias field (e.g. gpp0), use this } elsif($item->source_account_id && $c->req->param('alias_field')) { my $alias = $item->get_column('source_'.$c->req->param('alias_field')); $resource->{other_cli} = $alias // $item->source_cli; $other_normalize = 1; } else { $resource->{other_cli} = $item->source_cli; $other_normalize = 1; } } if($resource->{own_cli} !~ /^\d+$/) { $resource->{own_cli} .= '@'.$sub->domain->domain; } elsif($own_normalize) { $resource->{own_cli} = NGCP::Panel::Utils::Subscriber::apply_rewrite( c => $c, subscriber => $sub, number => $resource->{own_cli}, direction => "caller_out" ); } if($resource->{direction} eq "in" && $item->source_clir) { $resource->{other_cli} = undef; } elsif($resource->{other_cli} !~ /^\d+$/) { $resource->{other_cli} .= '@'. ($resource->{direction} eq "in" ? $item->destination_domain_in : $sub->domain->domain); } elsif($other_normalize) { $resource->{other_cli} = NGCP::Panel::Utils::Subscriber::apply_rewrite( c => $c, subscriber => $sub, number => $resource->{other_cli}, direction => "caller_out" ); } $resource->{status} = $item->call_status; $resource->{type} = $item->call_type; $resource->{start_time} = $datetime_fmt->format_datetime($item->start_time); $resource->{duration} = NGCP::Panel::Utils::DateTime::sec_to_hms(ceil($item->duration)); $resource->{customer_cost} = $resource->{direction} eq "out" ? $item->source_customer_cost : $item->destination_customer_cost; $resource->{customer_free_time} = $resource->{direction} eq "out" ? $item->source_customer_free_time : 0; return $resource; } sub item_by_id { my ($self, $c, $id) = @_; my $item_rs = $self->item_rs($c); return $item_rs->find($id); } sub get_subscriber { my ($self, $c, $schema) = @_; my $sub; if($c->user->roles ne "subscriber") { unless($c->req->param('subscriber_id')) { $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Mandatory parameter 'subscriber_id' missing in request"); return; } $sub = $schema->resultset('voip_subscribers')->find($c->req->param('subscriber_id')); unless($sub) { $self->error($c, HTTP_NOT_FOUND, "Invalid 'subscriber_id'."); return; } if(($c->user->roles eq "subscriberadmin" && $sub->contract_id != $c->user->account_id) || ($c->user->roles eq "reseller" && $sub->contract->contact->reseller_id != $c->user->reseller_id)) { $self->error($c, HTTP_NOT_FOUND, "Invalid 'subscriber_id'."); return; } } else { $sub = $c->user->voip_subscriber; } return $sub; } 1; # vim: set tabstop=4 expandtab: