TT#20322 TT#20344 basic /api/conversations

+ basic calls rs added
+ basic voicemails rs added
+ basic sms rs added
+ basic faxes rs added

+ calls+voicemails union-compatible
+ sms union-compatible
+ make call list suppressions work

+ add Tie::IxHash dependency

+ fax union-compatible
+ xmpp/sipwise_mam union-compatible

+ separate "timestamp" column for sorting

+ support explicity order-by column definitions
+ order by "timestamp" working
+ order by "type" working

+ "subscriber_id" filter parameter
+ "customer_id" filter parameter
+ "type" filter parameter
+ timestamp "from" filter parameter
+ timestamp "to" filter parameter
+ "direction" filter parameter

+ preliminary json fields: id, timestamp, type

+ cleanups for preliminary commit.

Change-Id: I7697635079b49bf2724731dee1c78e1801146b94
changes/04/15104/14
Rene Krenn 9 years ago
parent 52a838e56f
commit 94c9b92d1e

1
debian/control vendored

@ -110,6 +110,7 @@ Depends:
libuuid-perl,
libxml-mini-perl,
libxml-xpath-perl,
libtie-ixhash-perl,
lsb-base (>= 3.0-6),
ngcp-schema,
nginx-common,

@ -0,0 +1,64 @@
package NGCP::Panel::Controller::API::Conversations;
use Sipwise::Base;
#use NGCP::Panel::Utils::Generic qw(:all);
use HTTP::Status qw(:constants);
use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::Conversations/;
__PACKAGE__->set_config();
sub allowed_methods{
return [qw/GET OPTIONS HEAD/];
}
sub api_description {
return 'Combined collection of conversation events (calls, voice mails, sms, faxes, xmpp messages).';
};
sub query_params {
return [
{
param => 'subscriber_id',
description => 'Filter for conversation events of a specific subscriber. Either this or customer_id filter is mandatory if called by admin, reseller or subscriberadmin.',
},
{
param => 'customer_id',
description => 'Filter for conversation events for a specific customer. Either this or subscriber_id filter is mandatory if called by admin, reseller or subscriberadmin.',
},
{
param => 'direction',
description => 'Filter for conversation events with a specific direction. One of "in", "out". Voicemails are considered as incoming only.',
},
{
param => 'status',
description => 'todo',
},
{
param => 'type',
description => 'Filter for conversation events of given types ("call", "voicemail", "sms", "fax", "xmpp"). Multiple types can be included by concatenating type strings, eg. "?type=call-voicemial".',
},
{
param => 'from',
description => 'Filter for conversation events starting greater or equal the specified time stamp.',
},
{
param => 'to',
description => 'Filter for conversation events starting lower or equal the specified time stamp.',
},
];
}
sub order_by_cols {
return {
'timestamp' => 'me.timestamp',
'type' => 'me.type',
};
}
1;

@ -158,12 +158,16 @@ sub GET : Allow {
my ($form) = $full_mod->get_form($c);
my $sorting_cols = [];
my $item_rs;
try {
$item_rs = $full_mod->item_rs($c, "");
}
if ($item_rs) {
$sorting_cols = [$item_rs->result_source->columns];
if (my $order_by_cols = eval { $full_mod->order_by_cols(); }) {
$sorting_cols = [ keys %$order_by_cols ];
} else {
my $item_rs;
try {
$item_rs = $full_mod->item_rs($c, "");
}
if ($item_rs) {
$sorting_cols = [$item_rs->result_source->columns];
}
}
my ($form_fields,$form_fields_upload) = $form ? $self->get_collection_properties($form) : ([],[]);

@ -0,0 +1,24 @@
package NGCP::Panel::Form::Conversation::API;
use HTML::FormHandler::Moose;
extends 'HTML::FormHandler';
has_field 'type' => (
type => 'Text',
label => 'The conversation event type: call/voicemail/sms/fax/xmpp.',
required => 1,
);
has_field 'id' => (
type => 'PosInteger',
label => 'The original conversation record id - cdr id/voicemail id/sms id/fax journal record id/prosody message archive mgmt (mam) record id.',
required => 1,
);
has_field 'timestamp' => (
type => 'Text',
label => 'The timestamp of the conversation event.',
required => 1,
);
1;

@ -553,18 +553,18 @@ sub paginate_order_collection_rs {
page => $page,
rows => $rows,
});
if ($order_by && $item_rs->result_source->has_column($order_by)) {
my $me = $item_rs->current_source_alias;
if ($order_by && ((my $explicit = ($self->can('order_by_cols') && exists $self->order_by_cols()->{$order_by})) or $item_rs->result_source->has_column($order_by))) {
my $col = ($explicit ? $self->order_by_cols()->{$order_by} : $item_rs->current_source_alias . '.' . $order_by);
if (lc($direction) eq 'desc') {
$item_rs = $item_rs->search(undef, {
order_by => {-desc => "$me.$order_by"},
order_by => {-desc => $col},
});
$c->log->debug("ordering by $me.$order_by DESC");
$c->log->debug("ordering by $col DESC");
} else {
$item_rs = $item_rs->search(undef, {
order_by => "$me.$order_by",
order_by => "$col",
});
$c->log->debug("ordering by $me.$order_by");
$c->log->debug("ordering by $col");
}
}
return ($total_count, $item_rs);
@ -984,7 +984,7 @@ sub get_form {
sub get_item_id{
my($self, $c, $item, $resource, $form) = @_;
return int($item->id);
return int(blessed $item ? $item->id : $item->{id});
}
sub item_by_id {

@ -0,0 +1,669 @@
package NGCP::Panel::Role::API::Conversations;
use parent qw/NGCP::Panel::Role::API/;
use Sipwise::Base;
#use NGCP::Panel::Utils::Generic qw(:all);
use NGCP::Panel::Utils::CallList qw();
use NGCP::Panel::Utils::DateTime qw();
use DateTime::Format::Strptime qw();
use HTTP::Status qw(:constants);
use NGCP::Panel::Form::Conversation::API qw();
use Tie::IxHash;
my %call_fields = ();
tie(%call_fields, 'Tie::IxHash');
$call_fields{source_user_id} = 'me.source_user_id';
$call_fields{source_account_id} = 'me.source_account_id';
$call_fields{source_clir} = 'me.source_clir';
$call_fields{source_cli} = 'me.source_cli';
$call_fields{source_user} = 'me.source_user';
$call_fields{source_domain} = 'me.source_domain';
$call_fields{destination_user_id} = 'me.destination_user_id';
$call_fields{destination_account_id} = 'me.destination_account_id';
$call_fields{destination_user_in} = 'me.destination_user_in';
$call_fields{destination_domain} = 'me.destination_domain';
$call_fields{call_type} = 'me.call_type';
$call_fields{call_status} = 'me.call_status';
$call_fields{start_time} = 'me.start_time';
$call_fields{duration} = 'me.duration';
my %voicemail_fields = ();
tie(%voicemail_fields, 'Tie::IxHash');
$voicemail_fields{duration} = 'me.duration';
$voicemail_fields{origtime} = 'me.origtime';
$voicemail_fields{callerid} = 'me.callerid';
$voicemail_fields{mailboxuser} = 'me.mailboxuser';
$voicemail_fields{dir} = 'me.dir';
my %sms_fields = ();
tie(%sms_fields, 'Tie::IxHash');
$sms_fields{subscriber_id} = 'me.subscriber_id';
$sms_fields{time} = 'me.time';
$sms_fields{direction} = 'me.direction';
$sms_fields{caller} = 'me.callee';
$sms_fields{text} = 'me.text';
$sms_fields{reason} = 'me.reason';
$sms_fields{status} = 'me.status';
my %fax_fields = ();
tie(%fax_fields, 'Tie::IxHash');
$fax_fields{subscriber_id} = 'me.subscriber_id';
$fax_fields{time} = 'me.time';
$fax_fields{direction} = 'me.direction';
$fax_fields{duration} = 'duration';
$fax_fields{caller} = 'me.caller';
$fax_fields{callee} = 'me.callee';
$fax_fields{pages} = 'me.pages';
$fax_fields{reason} = 'me.reason';
$fax_fields{status} = 'me.status';
$fax_fields{signal_rate} = 'me.signal_rate';
$fax_fields{quality} = 'me.quality';
$fax_fields{filename} = 'me.filename';
$fax_fields{sid} = 'me.sid';
$fax_fields{caller_uuid} = 'me.caller_uuid';
$fax_fields{callee_uuid} = 'me.callee_uuid';
my %xmpp_fields = ();
tie(%xmpp_fields, 'Tie::IxHash');
$xmpp_fields{subscriber_id} = 'me.id';
$xmpp_fields{user} = 'me.user';
$xmpp_fields{with} = 'me.with';
$xmpp_fields{epoch} = 'me.epoch';
my $max_fields = scalar keys %call_fields;
$max_fields += scalar NGCP::Panel::Utils::CallList::get_suppression_id_colnames();
$max_fields = scalar keys %voicemail_fields if ((scalar keys %voicemail_fields) > $max_fields);
$max_fields = scalar keys %sms_fields if ((scalar keys %sms_fields) > $max_fields);
$max_fields = scalar keys %fax_fields if ((scalar keys %fax_fields) > $max_fields);
$max_fields = scalar keys %xmpp_fields if ((scalar keys %xmpp_fields) > $max_fields);
sub item_name{
return 'conversation';
}
sub resource_name{
return 'conversations';
}
sub dispatch_path{
return '/api/conversations/';
}
sub relation{
return 'http://purl.org/sipwise/ngcp-api/#rel-conversations';
}
sub config_allowed_roles {
return [qw/admin reseller subscriberadmin subscriber/];
}
sub _item_rs {
my ($self, $c, $params) = @_;
$params //= $c->req->params;
$params = { %$params };
my ($uuid,$contract_id,$reseller_id,$provider_id,$show);
if ($params->{subscriber_id}) {
my $subscriber;
eval {
$subscriber = $c->model('DB')->resultset('voip_subscriber')->find($params->{subscriber_id});
};
if ($subscriber) {
$uuid = $subscriber->uuid;
} else {
#die invalid subscriber_id '$params->{subscriber_id}'
}
}
if ($params->{customer_id}) {
# ensure integer, allow terminated
my $contract;
eval {
$contract = $c->model('DB')->resultset('contract')->find($params->{subscriber_id});
};
if ($contract) {
$contract_id = $contract->id;
} else {
#die invalid customer_id '$params->{customer_id}'
}
}
if ($c->user->roles eq "subscriber") {
$uuid = $c->user->voip_subscriber->uuid;
} elsif ($c->user->roles eq "subscriberadmin") {
$contract_id = $c->user->account_id;
} elsif ($c->user->roles eq "reseller") {
$reseller_id = $c->user->reseller_id;
$provider_id = $c->user->reseller->contract_id;
}
unless (defined $uuid or defined $contract_id) {
#die subscriber_id or customer_id required
}
my $item_rs;
my $type_param = ((exists $params->{type}) ? ($params->{type} // '') : undef);
foreach my $type (qw(call voicemail sms fax xmpp)) {
if ((not defined $type_param) or index(lc($type_param),$type) > -1) {
my $sub_name = '_get_' . $type . '_rs';
my $rs = $self->$sub_name(
c => $c,
uuid => $uuid,
contract_id => $contract_id,
reseller_id => $reseller_id,
provider_id => $provider_id,
params => $params);
if ($rs) {
$rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
$item_rs = (defined $item_rs ? $item_rs->union_all($rs) : $rs);
}
}
}
return $item_rs;
}
sub _apply_timestamp_from_to {
my $self = shift;
my %params = @_;
my ($rs,$params,$col,$cond_code) = @params{qw/rs params col cond/};
$cond_code //= sub { return shift->epoch; };
if (exists $params->{from}) {
my $from = NGCP::Panel::Utils::DateTime::from_string($params->{from});
if ($from) {
$rs = $rs->search_rs({
$col => { '>=' => &$cond_code($from) }
});
} else {
#die invalid from timestamp $params->{from}
}
}
if (exists $params->{to}) {
my $to = NGCP::Panel::Utils::DateTime::from_string($params->{to});
if ($to) {
$rs = $rs->search_rs({
$col => { '<=' => &$cond_code($to) }
});
} else {
#die invalid to timestamp $params->{to}
}
}
return $rs;
}
sub _apply_direction {
my $self = shift;
my %params = @_;
my ($params,$apply_in_code,$apply_out_code,$apply_inout_code) = @params{qw/params in out inout/};
$apply_in_code //= sub {};
$apply_out_code //= sub {};
$apply_inout_code //= sub {};
if (exists $params->{direction}) {
if ('in' eq lc($params->{direction})) {
&$apply_in_code();
} elsif ('out' eq lc($params->{direction})) {
&$apply_out_code();
} else {
#die invalid to direction $params->{direction}
}
} else {
&$apply_inout_code();
}
}
sub _get_call_rs {
my $self = shift;
my %params = @_;
my ($c,$uuid,$contract_id,$provider_id,$params) = @params{qw/c uuid contract_id provider_id params/};
my $rs = $c->model('DB')->resultset('cdr');
$rs = $self->_apply_timestamp_from_to(rs => $rs,params => $params,col => 'me.start_time');
if ($provider_id) {
$self->_apply_direction(params => $params,
in => sub {
$rs = $rs->search({
{ destination_provider_id => $provider_id },
});
},
out => sub {
$rs = $rs->search({
{ source_provider_id => $provider_id },
});
},
inout => sub {
$rs = $rs->search({
-or => [
{ source_provider_id => $provider_id },
{ destination_provider_id => $provider_id },
],
});
},
);
}
if ($contract_id) {
$self->_apply_direction(params => $params,
in => sub {
$rs = $rs->search({
{ destination_account_id => $contract_id },
});
},
out => sub {
$rs = $rs->search({
{ source_account_id => $contract_id },
});
},
inout => sub {
$rs = $rs->search_rs({
-or => [
{ source_account_id => $contract_id },
{ destination_account_id => $contract_id },
],
});
},
);
}
my $max = scalar keys %call_fields;
$rs = $rs->search(undef,{
'select' => [
{ '' => \'"call"', -as => 'type' },
{ '' => 'me.id', -as => 'id' },
{ '' => 'me.start_time', -as => 'timestamp' },
_get_select_list(\%call_fields,undef,$max), #_get_max_fields(1)),
],
'as' => [
'type',
'id',
'timestamp',
_get_as_list(\%call_fields,undef,$max), #_get_max_fields(1)),
],
});
my @suppression_aliases = ();
foreach (NGCP::Panel::Utils::CallList::get_suppression_id_colnames()) {
$max += 1;
push(@suppression_aliases,_get_alias($max));
}
if ($uuid) {
my $out_rs = NGCP::Panel::Utils::CallList::call_list_suppressions_rs($c,$rs->search_rs({
source_user_id => $uuid,
}),NGCP::Panel::Utils::CallList::SUPPRESS_OUT,@suppression_aliases);
my $in_rs = NGCP::Panel::Utils::CallList::call_list_suppressions_rs($c,$rs->search_rs({
destination_user_id => $uuid,
}),NGCP::Panel::Utils::CallList::SUPPRESS_IN,@suppression_aliases);
$self->_apply_direction(params => $params,
in => sub {
$rs = $in_rs;
},
out => sub {
$rs = $out_rs;
},
inout => sub {
$rs = $out_rs->union_all($in_rs);
},
);
} else {
$rs = NGCP::Panel::Utils::CallList::call_list_suppressions_rs($c,$rs,
NGCP::Panel::Utils::CallList::SUPPRESS_INOUT,@suppression_aliases);
}
return $rs->search(undef,{
'+select' => [
_get_select_list(\%call_fields,$max,undef), #_get_max_fields(1)),
],
'+as' => [
_get_as_list(\%call_fields,$max,undef), #_get_max_fields(1)),
],
}) if $max_fields > $max;
return $rs;
}
sub _get_voicemail_rs {
my $self = shift;
my %params = @_;
my ($c,$uuid,$contract_id,$reseller_id,$params) = @params{qw/c uuid contract_id reseller_id params/};
my $rs = $c->model('DB')->resultset('voicemail_spool')->search({
duration => { '!=' => '' },
});
$rs = $self->_apply_timestamp_from_to(rs => $rs,params => $params,col => 'me.origtime');
if ($reseller_id) {
$rs = $rs->search({
'contact.reseller_id' => $reseller_id,
},{
join => { mailboxuser => { provisioning_voip_subscriber => { voip_subscriber => { contract => 'contact' } } } },
});
}
if ($contract_id) {
$rs = $rs->search({
'contract.id' => $contract_id,
},{
join => { mailboxuser => { provisioning_voip_subscriber => { voip_subscriber => 'contract' } } },
});
}
if ($uuid) {
$rs = $rs->search({
'voip_subscriber.uuid' => $c->user->uuid,
},{
join => { mailboxuser => { provisioning_voip_subscriber => 'voip_subscriber' } },
});
} else {
$rs = $rs->search({
'voip_subscriber.id' => { '!=' => undef },
},{
join => { mailboxuser => { provisioning_voip_subscriber => 'voip_subscriber' } },
});
}
$rs = $rs->search(undef,{
select => [
{ '' => \'"voicemail"', -as => 'type' },
{ '' => 'me.id', -as => 'id' },
{ '' => 'me.origtime', -as => 'timestamp' },
_get_select_list(\%voicemail_fields),
],
as => ['type','id','timestamp',_get_as_list(\%voicemail_fields),],
});
$self->_apply_direction(params => $params,
out => sub {
undef $rs;
},
);
return $rs;
}
sub _get_sms_rs {
my $self = shift;
my %params = @_;
my ($c,$uuid,$contract_id,$reseller_id,$params) = @params{qw/c uuid contract_id reseller_id params/};
my $rs = $c->model('DB')->resultset('sms_journal');
$rs = $self->_apply_timestamp_from_to(rs => $rs,params => $params,col => 'me.time');
$self->_apply_direction(params => $params,
in => sub {
$rs = $rs->search_rs({
'me.direction' => 'in',
});
},
out => sub {
$rs = $rs->search_rs({
'me.direction' => 'out',
});
},
);
if ($reseller_id) {
$rs = $rs->search_rs({
'contact.reseller_id' => $reseller_id,
},{
join => { provisioning_voip_subscriber => { subscriber => { contract => 'contact'} } },
});
}
if ($contract_id) {
$rs = $rs->search({
'contract.id' => $contract_id,
},{
join => { provisioning_voip_subscriber => { subscriber => 'contract' } },
});
}
if ($uuid) {
$rs = $rs->search_rs({
'provisioning_voip_subscriber.uuid' => $uuid,
},{
join => 'provisioning_voip_subscriber',
});
}
return $rs->search(undef,{
select => [
{ '' => \'"sms"', -as => 'type' },
{ '' => 'me.id', -as => 'id' },
{ '' => 'me.time', -as => 'timestamp' },
_get_select_list(\%sms_fields),
],
as => ['type','id','timestamp',_get_as_list(\%sms_fields),],
});
}
sub _get_fax_rs {
my $self = shift;
my %params = @_;
my ($c,$uuid,$contract_id,$reseller_id,$params) = @params{qw/c uuid contract_id reseller_id params/};
my $rs = $c->model('DB')->resultset('voip_fax_journal');
$rs = $self->_apply_timestamp_from_to(rs => $rs,params => $params,col => 'me.time');
$self->_apply_direction(params => $params,
in => sub {
$rs = $rs->search_rs({
'me.direction' => 'in',
});
},
out => sub {
$rs = $rs->search_rs({
'me.direction' => 'out',
});
},
);
if ($reseller_id) {
$rs = $rs->search_rs({
'contact.reseller_id' => $reseller_id,
},{
join => { provisioning_voip_subscriber => { subscriber => { contract => 'contact'} } },
});
}
if ($contract_id) {
$rs = $rs->search({
'contract.id' => $contract_id,
},{
join => { provisioning_voip_subscriber => { subscriber => 'contract' } },
});
}
if ($uuid) {
$rs = $rs->search({
'voip_subscriber.uuid' => $c->user->uuid,
},{
join => { provisioning_voip_subscriber => 'voip_subscriber' },
});
} else {
$rs = $rs->search({
'voip_subscriber.id' => { '!=' => undef },
},{
join => { provisioning_voip_subscriber => 'voip_subscriber' },
});
}
return $rs->search(undef,{
select => [
{ '' => \'"fax"', -as => 'type' },
{ '' => 'me.id', -as => 'id' },
{ '' => 'me.time', -as => 'timestamp' },
_get_select_list(\%fax_fields),
],
as => ['type','id','timestamp',_get_as_list(\%fax_fields),],
});
}
sub _get_xmpp_rs {
my $self = shift;
my %params = @_;
my ($c,$uuid,$contract_id,$reseller_id,$params) = @params{qw/c uuid contract_id reseller_id params/};
my $rs = $c->model('DB')->resultset('provisioning_voip_subscribers')->search_rs(undef,{
#join => [ 'domain', 'sipwise_mam_user', 'sipwise_mam_with' ],
join => 'domain',
});
$rs = $self->_apply_timestamp_from_to(rs => $rs,params => $params,col => 'epoch');
if ($reseller_id) {
$rs = $rs->search_rs({
'contact.reseller_id' => $reseller_id,
},{
join => { voip_subscriber => { contract => 'contact'} },
});
}
if ($contract_id) {
$rs = $rs->search({
'contract.id' => $contract_id,
},{
join => { voip_subscriber => 'contract' },
});
}
if ($uuid) {
$rs = $rs->search({
'me.uuid' => $c->user->uuid,
});
}
my $out_rs = $rs->search_rs(undef,{
join => 'sipwise_mam_user',
'+select' => [
{ '' => \'"out"', -as => 'direction' },
{ '' => 'sipwise_mam_user.id', -as => 'mam_id' },
{ '' => 'sipwise_mam_user.username', -as => 'user' },
{ '' => 'sipwise_mam_user.with', -as => 'with' },
{ '' => 'sipwise_mam_user.epoch', -as => 'epoch' },
],
'+as' => ['direction','mam_id','user','with','epoch'],
});
my $in_rs = $rs->search_rs(undef,{
join => 'sipwise_mam_with',
'+select' => [
{ '' => \'"in"', -as => 'direction' },
{ '' => 'sipwise_mam_with.id', -as => 'mam_id' },
{ '' => 'sipwise_mam_with.username', -as => 'user' },
{ '' => 'sipwise_mam_with.with', -as => 'with' },
{ '' => 'sipwise_mam_with.epoch', -as => 'epoch' },
],
'+as' => ['direction','mam_id','user','with','epoch'],
});
$self->_apply_direction(params => $params,
in => sub {
$rs = $in_rs;
},
out => sub {
$rs = $out_rs;
},
inout => sub {
$rs = $out_rs->union_all($in_rs);
},
);
return $rs->search(undef,{
select => [
{ '' => \'"xmpp"', -as => 'type' },
{ '' => 'mam_id', -as => 'id' },
{ '' => 'epoch', -as => 'timestamp' },
_get_select_list(\%xmpp_fields),
],
as => ['type','id','timestamp',_get_as_list(\%xmpp_fields),],
});
}
sub _get_select_list {
my ($fields,$min,$max) = @_;
$min //= 1;
$max //= $max_fields;
my @projections = values %$fields;
my @select = ();
foreach my $i ($min..$max) {
push(@select,{
'' => ($projections[$i - 1] ? $projections[$i - 1] : \'""'),
-as => _get_alias($i)
});
}
return @select;
}
sub _get_as_list {
my ($fields,$min,$max) = @_;
$min //= 1;
$max //= $max_fields;
my @accessors = keys %$fields;
my @as = ();
foreach my $i ($min..$max) {
push(@as,_get_alias($i));
#push(@as,($accessors[$i - 1] ? $accessors[$i - 1] : 'field'.$i));
}
return @as;
}
sub _get_alias {
return 'field' . shift;
}
sub get_form {
my ($self, $c) = @_;
return (NGCP::Panel::Form::Conversation::API->new(ctx => $c),['id']);
}
sub process_hal_resource {
my($self, $c, $item, $resource, $form) = @_;
use Data::Dumper;
$c->log->debug(Dumper($item));
my $datetime_fmt = DateTime::Format::Strptime->new(
pattern => '%F %T',
);
my $timestamp = NGCP::Panel::Utils::DateTime::epoch_local($resource->{timestamp});
#if($c->req->param('tz') && DateTime::TimeZone->is_valid_name($c->req->param('tz'))) {
# $timestamp->set_time_zone($c->req->param('tz'));
#}
$resource->{timestamp} = $datetime_fmt->format_datetime($timestamp);
$resource->{timestamp} .= '.' . $timestamp->millisecond if $timestamp->millisecond > 0.0;
# todo: mashal specific fields, per conversation event type ...
return $resource;
}
sub hal_links {
my($self, $c, $item, $resource, $form) = @_;
return [
('call' eq $item->{type} ?
NGCP::Panel::Utils::DataHalLink->new(relation => 'ngcp:calls', href => sprintf("/api/calls/%d", $item->{id})) : ()),
('voicemail' eq $item->{type} ?
NGCP::Panel::Utils::DataHalLink->new(relation => 'ngcp:voicemails', href => sprintf("/api/voicemails/%d", $item->{id})) : ()),
('sms' eq $item->{type} ?
NGCP::Panel::Utils::DataHalLink->new(relation => 'ngcp:sms', href => sprintf("/api/sms/%d", $item->{id})) : ()),
('fax' eq $item->{type} ?
NGCP::Panel::Utils::DataHalLink->new(relation => 'ngcp:faxes', href => sprintf("/api/faxes/%d", $item->{id})) : ()),
# todo - add xmpp mam rail:
# ('xmpp' eq $item->{type} ?
# NGCP::Panel::Utils::DataHalLink->new(relation => 'ngcp:xmpp', href => sprintf("/api/xmpp/%d", $item->{id})) : ()),
];
}
1;

@ -335,55 +335,59 @@ sub _is_show_suppressions {
sub call_list_suppressions_rs {
my ($c,$rs,$mode) = @_;
my ($c,$rs,$mode,
$source_cli_suppression_id_colname,
$destination_user_in_suppression_id_colname) = @_;
return $rs unless ENABLE_SUPPRESSIONS;
$source_cli_suppression_id_colname //= SOURCE_CLI_SUPPRESSION_ID_COLNAME;
$destination_user_in_suppression_id_colname //= DESTINATION_USER_IN_SUPPRESSION_ID_COLNAME;
my %search_cond = ();
my %search_xtra = ();
if (_is_show_suppressions($c)) {
if (defined $mode and SUPPRESS_OUT == $mode) {
$search_xtra{'+select'} = [
#{ '' => \[ 'me.source_cli' ] , -as => SOURCE_CLI_SUPPRESSION_ID_COLNAME },
{ '' => \[ 'NULL' ] , -as => SOURCE_CLI_SUPPRESSION_ID_COLNAME },
{ '' => \[ _get_call_list_suppression_sq('outgoing',qw(filter obfuscate)) ] , -as => DESTINATION_USER_IN_SUPPRESSION_ID_COLNAME },
#{ '' => \[ 'me.source_cli' ] , -as => $source_cli_suppression_id_colname },
{ '' => \[ 'NULL' ] , -as => $source_cli_suppression_id_colname },
{ '' => \[ _get_call_list_suppression_sq('outgoing',qw(filter obfuscate)) ] , -as => $destination_user_in_suppression_id_colname },
];
} elsif (defined $mode and SUPPRESS_IN == $mode) {
$search_xtra{'+select'} = [
{ '' => \[ _get_call_list_suppression_sq('incoming',qw(filter obfuscate)) ] , -as => SOURCE_CLI_SUPPRESSION_ID_COLNAME },
#{ '' => \[ 'me.destination_user_in' ] , -as => DESTINATION_USER_IN_SUPPRESSION_ID_COLNAME },
{ '' => \[ 'NULL' ] , -as => DESTINATION_USER_IN_SUPPRESSION_ID_COLNAME },
{ '' => \[ _get_call_list_suppression_sq('incoming',qw(filter obfuscate)) ] , -as => $source_cli_suppression_id_colname },
#{ '' => \[ 'me.destination_user_in' ] , -as => $destination_user_in_suppression_id_colname },
{ '' => \[ 'NULL' ] , -as => $destination_user_in_suppression_id_colname },
];
} elsif (defined $mode and SUPPRESS_INOUT == $mode) {
$search_xtra{'+select'} = [
{ '' => \[ _get_call_list_suppression_sq('incoming',qw(filter obfuscate)) ] , -as => SOURCE_CLI_SUPPRESSION_ID_COLNAME },
{ '' => \[ _get_call_list_suppression_sq('outgoing',qw(filter obfuscate)) ] , -as => DESTINATION_USER_IN_SUPPRESSION_ID_COLNAME },
{ '' => \[ _get_call_list_suppression_sq('incoming',qw(filter obfuscate)) ] , -as => $source_cli_suppression_id_colname },
{ '' => \[ _get_call_list_suppression_sq('outgoing',qw(filter obfuscate)) ] , -as => $destination_user_in_suppression_id_colname },
];
} else {
$search_xtra{'+select'} = [
#{ '' => \[ 'me.source_cli' ] , -as => SOURCE_CLI_SUPPRESSION_ID_COLNAME },
{ '' => \[ 'NULL' ] , -as => SOURCE_CLI_SUPPRESSION_ID_COLNAME },
#{ '' => \[ 'me.destination_user_in' ] , -as => DESTINATION_USER_IN_SUPPRESSION_ID_COLNAME },
{ '' => \[ 'NULL' ] , -as => DESTINATION_USER_IN_SUPPRESSION_ID_COLNAME },
#{ '' => \[ 'me.source_cli' ] , -as => $source_cli_suppression_id_colname },
{ '' => \[ 'NULL' ] , -as => $source_cli_suppression_id_colname },
#{ '' => \[ 'me.destination_user_in' ] , -as => $destination_user_in_suppression_id_colname },
{ '' => \[ 'NULL' ] , -as => $destination_user_in_suppression_id_colname },
];
}
} else {
if (defined $mode and SUPPRESS_OUT == $mode) {
$search_xtra{'+select'} = [
#{ '' => \[ 'me.source_cli' ] , -as => SOURCE_CLI_SUPPRESSION_ID_COLNAME },
{ '' => \[ 'NULL' ] , -as => SOURCE_CLI_SUPPRESSION_ID_COLNAME },
{ '' => \[ _get_call_list_suppression_sq('outgoing',qw(obfuscate)) ] , -as => DESTINATION_USER_IN_SUPPRESSION_ID_COLNAME },
#{ '' => \[ 'me.source_cli' ] , -as => $source_cli_suppression_id_colname },
{ '' => \[ 'NULL' ] , -as => $source_cli_suppression_id_colname },
{ '' => \[ _get_call_list_suppression_sq('outgoing',qw(obfuscate)) ] , -as => $destination_user_in_suppression_id_colname },
];
$search_cond{'-not exists'} = \[ '('._get_call_list_suppression_sq('outgoing',qw(filter)).')' ];
} elsif (defined $mode and SUPPRESS_IN == $mode) {
$search_xtra{'+select'} = [
{ '' => \[ _get_call_list_suppression_sq('incoming',qw(obfuscate)) ] , -as => SOURCE_CLI_SUPPRESSION_ID_COLNAME },
#{ '' => \[ 'me.destination_user_in' ] , -as => DESTINATION_USER_IN_SUPPRESSION_ID_COLNAME },
{ '' => \[ 'NULL' ] , -as => DESTINATION_USER_IN_SUPPRESSION_ID_COLNAME },
{ '' => \[ _get_call_list_suppression_sq('incoming',qw(obfuscate)) ] , -as => $source_cli_suppression_id_colname },
#{ '' => \[ 'me.destination_user_in' ] , -as => $destination_user_in_suppression_id_colname },
{ '' => \[ 'NULL' ] , -as => $destination_user_in_suppression_id_colname },
];
$search_cond{'-not exists'} = \[ '('._get_call_list_suppression_sq('incoming',qw(filter)).')' ];
} elsif (defined $mode and SUPPRESS_INOUT == $mode) {
$search_xtra{'+select'} = [
{ '' => \[ _get_call_list_suppression_sq('incoming',qw(obfuscate)) ] , -as => SOURCE_CLI_SUPPRESSION_ID_COLNAME },
{ '' => \[ _get_call_list_suppression_sq('outgoing',qw(obfuscate)) ] , -as => DESTINATION_USER_IN_SUPPRESSION_ID_COLNAME },
{ '' => \[ _get_call_list_suppression_sq('incoming',qw(obfuscate)) ] , -as => $source_cli_suppression_id_colname },
{ '' => \[ _get_call_list_suppression_sq('outgoing',qw(obfuscate)) ] , -as => $destination_user_in_suppression_id_colname },
];
$search_cond{'-and'} = [
{ '-not exists' => \[ '('._get_call_list_suppression_sq('incoming',qw(filter)).')' ] },
@ -391,10 +395,10 @@ sub call_list_suppressions_rs {
];
} else {
$search_xtra{'+select'} = [
#{ '' => \[ 'me.source_cli' ] , -as => SOURCE_CLI_SUPPRESSION_ID_COLNAME },
{ '' => \[ 'NULL' ] , -as => SOURCE_CLI_SUPPRESSION_ID_COLNAME },
#{ '' => \[ 'me.destination_user_in' ] , -as => DESTINATION_USER_IN_SUPPRESSION_ID_COLNAME },
{ '' => \[ 'NULL' ] , -as => DESTINATION_USER_IN_SUPPRESSION_ID_COLNAME },
#{ '' => \[ 'me.source_cli' ] , -as => $source_cli_suppression_id_colname },
{ '' => \[ 'NULL' ] , -as => $source_cli_suppression_id_colname },
#{ '' => \[ 'me.destination_user_in' ] , -as => $destination_user_in_suppression_id_colname },
{ '' => \[ 'NULL' ] , -as => $destination_user_in_suppression_id_colname },
];
}
}

Loading…
Cancel
Save