MT#7791 Manage Callthrough CLIs in Panel

agranig/pbx-dev-map
Gerhard Jungwirth 12 years ago
parent edff2c4120
commit b7eb095540

@ -19,6 +19,7 @@ use NGCP::Panel::Utils::Kamailio;
use NGCP::Panel::Utils::Events;
use NGCP::Panel::Form::Subscriber;
use NGCP::Panel::Form::SubscriberEdit;
use NGCP::Panel::Form::CCMapEntries;
use NGCP::Panel::Form::Customer::PbxSubscriberEdit;
use NGCP::Panel::Form::Customer::PbxExtensionSubscriberEditSubadmin;
use NGCP::Panel::Form::Customer::PbxExtensionSubscriberEditSubadminNoGroup;
@ -271,6 +272,12 @@ sub base :Chained('sub_list') :PathPart('') :CaptureArgs(1) {
{ name => "pages", search => 1, title => $c->loc('Pages') },
]);
$c->stash->{ccmap_dt_columns} = NGCP::Panel::Utils::Datatables::set_columns($c, [
{ name => "id", search => 1, title => $c->loc('#') },
{ name => "auth_key", search => 1, title => $c->loc('CLI') },
{ name => "source_uuid", search => 1, title => $c->loc('Source UUID') },
]);
if($c->stash->{billing_mapping}->product->class eq "pbxaccount") {
$c->stash->{pbx_groups} = $c->model('DB')->resultset('voip_subscribers')->search({
contract_id => $c->stash->{subscriber}->contract->id,
@ -3493,6 +3500,119 @@ sub edit_autoattendant :Chained('base') :PathPart('preferences/speeddial/edit')
);
}
sub ajax_ccmappings :Chained('base') :PathPart('preferences/ccmappings/ajax') :Args(0) {
my ($self, $c) = @_;
my $prov_subscriber = $c->stash->{subscriber}->provisioning_voip_subscriber;
my $aa_rs = $prov_subscriber->voip_cc_mappings;
NGCP::Panel::Utils::Datatables::process($c, $aa_rs, $c->stash->{ccmap_dt_columns});
$c->detach( $c->view("JSON") );
return;
}
sub ccmappings :Chained('base') :PathPart('preferences/ccmappings') :CaptureArgs(1) {
my ($self, $c, $aa_id) = @_;
my $ccmapping = $c->stash->{subscriber}->provisioning_voip_subscriber->voip_cc_mappings
->find($aa_id);
unless($ccmapping) {
NGCP::Panel::Utils::Message->error(
c => $c,
log => "no such ccmapping with id '$aa_id' for uuid ".$c->stash->{subscriber}->uuid,
desc => $c->loc('No such auto ccmapping id.'),
);
NGCP::Panel::Utils::Navigation::back_or($c,
$c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]]));
}
$c->stash->{ccmapping} = $ccmapping;
return;
}
sub delete_ccmapping :Chained('ccmappings') :PathPart('delete') :Args(0) {
my ($self, $c) = @_;
$c->detach('/denied_page')
if(($c->user->roles eq "admin" || $c->user->roles eq "reseller") && $c->user->read_only);
try {
$c->stash->{ccmapping}->delete;
$c->flash(messages => [{type => 'success', text => $c->loc('Successfully deleted ccmapping.') }]);
} catch($e) {
NGCP::Panel::Utils::Message->error(
c => $c,
error => $e,
desc => $c->loc('Failed to delete ccmapping.'),
);
}
NGCP::Panel::Utils::Navigation::back_or($c,
$c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]]));
return;
}
sub edit_ccmapping :Chained('base') :PathPart('preferences/ccmappings/edit') :Args(0) {
my ($self, $c) = @_;
$c->detach('/denied_page')
if(($c->user->roles eq "admin" || $c->user->roles eq "reseller") && $c->user->read_only);
my $posted = ($c->request->method eq 'POST');
my $prov_subscriber = $c->stash->{subscriber}->provisioning_voip_subscriber;
my $ccmappings = $prov_subscriber->voip_cc_mappings;
my $form = NGCP::Panel::Form::CCMapEntries->new;
my $params = {};
unless($posted) {
$params->{mappings} = [];
foreach my $mapping ($ccmappings->all) {
push @{ $params->{mappings} }, { $mapping->get_inflated_columns };
}
}
$form->process(
posted => $posted,
params => $c->req->params,
item => $params,
);
NGCP::Panel::Utils::Navigation::check_form_buttons(
c => $c,
form => $form,
fields => {},
back_uri => $c->req->uri,
);
if($posted && $form->validated) {
try {
my $schema = $c->model('DB');
$schema->txn_do(sub {
$ccmappings->delete_all;
my @fields = $form->field('mappings')->fields;
foreach my $map (@fields) {
$ccmappings->create({
source_uuid => $map->field('source_uuid')->value || $prov_subscriber->uuid,
auth_key => $map->field('auth_key')->value,
});
}
});
$c->flash(messages => [{type => 'success', text => $c->loc('Successfully updated ccmappings.')}]);
} catch($e) {
NGCP::Panel::Utils::Message->error(
c => $c,
error => $e,
desc => $c->loc('Failed to update ccmappings'),
);
}
NGCP::Panel::Utils::Navigation::back_or($c,
$c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]]));
}
$c->stash(
template => 'subscriber/preferences.tt',
edit_ccmap_flag => 1,
ccmap_form => $form,
);
return;
}
sub callflow_base :Chained('base') :PathPart('callflow') :CaptureArgs(1) :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) {
my ($self, $c, $callid) = @_;

@ -0,0 +1,90 @@
package NGCP::Panel::Form::CCMapEntries;
use HTML::FormHandler::Moose;
extends 'HTML::FormHandler';
use Moose::Util::TypeConstraints;
with 'NGCP::Panel::Render::RepeatableJs';
use HTML::FormHandler::Widget::Block::Bootstrap;
has '+widget_wrapper' => ( default => 'Bootstrap' );
has_field 'submitid' => ( type => 'Hidden' );
sub build_render_list {return [qw/submitid fields actions/]}
sub build_form_element_class {return [qw/form-horizontal/] }
has_field 'subscriber_id' => (
type => 'Hidden',
required => 0,
element_attr => {
rel => ['tooltip'],
title => ['The subscriber ID.'],
},
);
has_field 'mappings' => (
type => 'Repeatable',
required => 1,
setup_for_js => 1,
do_wrapper => 1,
do_label => 0,
tags => {
controls_div => 1,
},
wrapper_class => [qw/hfh-rep/],
element_attr => {
rel => ['tooltip'],
title => ['An Array of mappings, each entry containing the mandatory key "auth_key".'],
},
);
has_field 'mappings.id' => (
type => 'Hidden',
);
has_field 'mappings.source_uuid' => (
type => 'Hidden',
);
has_field 'mappings.auth_key' => (
type => 'Text',
wrapper_class => [qw/hfh-rep-field/],
);
has_field 'mappings.rm' => (
type => 'RmElement',
value => 'Remove',
element_class => [qw/btn btn-primary pull-right/],
);
has_field 'mappings_add' => (
type => 'AddElement',
repeatable => 'mappings',
value => 'Add another Mapping',
element_class => [qw/btn btn-primary pull-right/],
);
has_block 'fields' => (
tag => 'div',
class => [qw(modal-body)],
render_list => [qw(mappings mappings_add)],
);
has_block 'actions' => (
tag => 'div',
class => [qw/modal-footer/],
render_list => [qw/save/],
);
has_field 'save' => (
type => 'Submit',
value => 'Save',
element_class => [qw/btn btn-primary/],
label => '',
);
1;
# vim: set tabstop=4 expandtab:

@ -1,39 +0,0 @@
package NGCP::Panel::Form::CCMapEntriesAPI;
use HTML::FormHandler::Moose;
use Moose::Util::TypeConstraints;
extends 'HTML::FormHandler';
sub build_render_list {return [qw/fields actions/]}
sub build_form_element_class {return [qw(form-horizontal)]}
has_field 'subscriber_id' => (
type => 'Repeatable',
required => 0,
element_attr => {
rel => ['tooltip'],
title => ['The subscriber ID.'],
},
);
has_field 'mappings' => (
type => 'Repeatable',
required => 1,
element_attr => {
rel => ['tooltip'],
title => ['An Array of mappings, each entry containing the mandatory key "auth_key".'],
},
);
has_field 'mappings.auth_key' => (
type => 'Text',
);
has_block 'fields' => (
tag => 'div',
class => [qw(modal-body)],
render_list => [qw(cfu cfb cft cfna)],
);
1;
# vim: set tabstop=4 expandtab:

@ -14,12 +14,12 @@ use HTTP::Status qw(:constants);
use JSON::Types;
use NGCP::Panel::Form::CFSimpleAPI;
use NGCP::Panel::Utils::Subscriber;
use NGCP::Panel::Form::CCMapEntriesAPI;
use NGCP::Panel::Form::CCMapEntries;
sub get_form {
my ($self, $c) = @_;
return NGCP::Panel::Form::CCMapEntriesAPI->new;
return NGCP::Panel::Form::CCMapEntries->new;
}
sub hal_from_item {

@ -19,14 +19,16 @@ log4perl.appender.Default.layout.ConversionPattern=%d{ISO8601} [%p] [%F +%L] %m{
</contact>
<features>
callflow 1
multidomain 1
callflow 1
multidomain 1
faxserver 1
conference 1
faxserver 1
conference 1
debug 1
cloudpbx 1
debug 1
cloudpbx 1
callingcard 1
</features>
<faxserver>

@ -486,6 +486,42 @@
</div>
[% END -%]
[% IF c.config.features.callingcard && (
c.user.roles == "admin" || c.user.roles == "reseller"
) -%]
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#preference_groups" href="#collapse_ccmap">[% c.loc('Callthrough CLIs') %]</a>
</div>
<div class="accordion-body collapse" id="collapse_ccmap">
<div class="accordion-inner">
[% IF c.user.roles == "subscriber" || c.user.roles == "subscriberadmin" || ((c.user.roles == "admin" || c.user.roles == "reseller") && c.user.read_only != 1) -%]
<a class="btn btn-tertiary btn-large" href="[% c.uri_for_action('/subscriber/edit_ccmapping', [c.req.captures.0]) %]">
<i class="icon-star"></i> [% c.loc('Edit Callthrough CLIs') %]
</a>
[% END -%]
[%
helper.messages = '';
helper.name = c.loc('foobar');
helper.identifier = 'ccmapentries';
helper.column_sort = undef;
helper.dt_columns = ccmap_dt_columns;
helper.length_change = 1;
helper.ajax_uri = c.uri_for_action('/subscriber/ajax_ccmappings', [c.req.captures.0]);
helper.dt_buttons = [
{ name = c.loc('Delete'), uri = "/subscriber/"_ c.req.captures.0 _"/preferences/ccmappings/'+full.id+'/delete", class = 'btn-small btn-secondary', icon = 'icon-trash' },
];
PROCESS 'helpers/datatables.tt';
%]
</div>
</div>
</div>
[% END -%]
[% UNLESS c.user.roles == 'subscriber' || c.user.roles == 'subscriberadmin' -%]
<div class="accordion-group">
<div class="accordion-heading">
@ -659,6 +695,21 @@
[% END -%]
</div>
[%
modal_footer();
modal_script(m.close_target = close_target ? close_target : c.uri_for_action('/subscriber/preferences', [c.req.captures.0]));
-%]
[% ELSIF edit_ccmap_flag -%]
[%
PROCESS "helpers/modal.tt";
modal_header(m.name = 'Callthrough CLIs');
-%]
[% IF ccmap_form.has_for_js -%]
[% ccmap_form.render_repeatable_js %]
[% END -%]
[% translate_form(ccmap_form).render %]
[%
modal_footer();
modal_script(m.close_target = close_target ? close_target : c.uri_for_action('/subscriber/preferences', [c.req.captures.0]));

Loading…
Cancel
Save