From 34f8a717df07a761059db2e593657d0e3ee21352 Mon Sep 17 00:00:00 2001 From: Gerhard Jungwirth Date: Wed, 19 Jun 2013 17:11:36 +0200 Subject: [PATCH] CRUD NCOS Levels and NCOS Number Patterns. --- lib/NGCP/Panel/Controller/NCOS.pm | 319 ++++++++++++++++++ lib/NGCP/Panel/Form/NCOSLevel.pm | 73 ++++ lib/NGCP/Panel/Form/NCOSPattern.pm | 64 ++++ share/templates/ncos/list.tt | 23 ++ share/templates/ncos/pattern_list.tt | 22 ++ .../widgets/admin_topmenu_settings.tt | 1 + t/controller_NCOS.t | 10 + 7 files changed, 512 insertions(+) create mode 100644 lib/NGCP/Panel/Controller/NCOS.pm create mode 100644 lib/NGCP/Panel/Form/NCOSLevel.pm create mode 100644 lib/NGCP/Panel/Form/NCOSPattern.pm create mode 100644 share/templates/ncos/list.tt create mode 100644 share/templates/ncos/pattern_list.tt create mode 100644 t/controller_NCOS.t diff --git a/lib/NGCP/Panel/Controller/NCOS.pm b/lib/NGCP/Panel/Controller/NCOS.pm new file mode 100644 index 0000000000..8d310c2044 --- /dev/null +++ b/lib/NGCP/Panel/Controller/NCOS.pm @@ -0,0 +1,319 @@ +package NGCP::Panel::Controller::NCOS; +use Sipwise::Base; +use namespace::autoclean; + +BEGIN { extends 'Catalyst::Controller'; } + +use NGCP::Panel::Form::NCOSLevel; +use NGCP::Panel::Form::NCOSPattern; + +sub auto :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { + my ($self, $c) = @_; + $c->log->debug(__PACKAGE__ . '::auto'); + return 1; +} + +sub levels_list :Chained('/') :PathPart('ncos') :CaptureArgs(0) { + my ( $self, $c ) = @_; + + my $levels_rs = $c->model('billing')->resultset('ncos_levels'); + $c->stash(levels_rs => $levels_rs); + + $c->stash(has_edit => 1); + $c->stash(has_delete => 1); + $c->stash(template => 'ncos/list.tt'); +} + +sub root :Chained('levels_list') :PathPart('') :Args(0) { + my ($self, $c) = @_; +} + +sub ajax :Chained('levels_list') :PathPart('ajax') :Args(0) { + my ($self, $c) = @_; + + my $resultset = $c->stash->{levels_rs}; + + $c->forward( "/ajax_process_resultset", [$resultset, + ["id", "level", "mode", "description"], + [1,2,3]]); + + $c->detach( $c->view("JSON") ); +} + +sub base :Chained('levels_list') :PathPart('') :CaptureArgs(1) { + my ($self, $c, $level_id) = @_; + + unless($level_id && $level_id->is_integer) { + $c->flash(messages => [{type => 'error', text => 'Invalid NCOS Level id detected!'}]); + $c->response->redirect($c->uri_for()); + $c->detach; + return; + } + + my $res = $c->stash->{levels_rs}->find($level_id); + unless(defined($res)) { + $c->flash(messages => [{type => 'error', text => 'NCOS Level does not exist!'}]); + $c->response->redirect($c->uri_for()); + $c->detach; + return; + } + $c->stash(level_result => $res); +} + +sub edit :Chained('base') :PathPart('edit') { + my ($self, $c) = @_; + + my $posted = ($c->request->method eq 'POST'); + my $form = NGCP::Panel::Form::NCOSLevel->new; + $form->process( + posted => $posted, + params => $c->request->params, + action => $c->uri_for_action('/ncos/edit'), + item => $c->stash->{level_result}, + ); + if($form->validated) { + $c->flash(messages => [{type => 'success', text => 'NCOS Level successfully changed!'}]); + $c->response->redirect($c->uri_for()); + return; + } + + $c->stash(form => $form); + $c->stash(edit_flag => 1); +} + +sub delete :Chained('base') :PathPart('delete') { + my ($self, $c) = @_; + + try { + $c->stash->{level_result}->delete; + $c->flash(messages => [{type => 'success', text => 'NCOS Level successfully deleted!'}]); + } catch (DBIx::Class::Exception $e) { + $c->flash(messages => [{type => 'error', text => 'Delete failed.'}]); + $c->log->info("Delete failed: " . $e); + }; + $c->response->redirect($c->uri_for()); +} + +sub create :Chained('levels_list') :PathPart('create') :Args(0) { + my ($self, $c) = @_; + + my $form = NGCP::Panel::Form::NCOSLevel->new; + $form->process( + posted => ($c->request->method eq 'POST'), + params => $c->request->params, + action => $c->uri_for_action('/ncos/create'), + item => $c->stash->{levels_rs}->new_result({}), + ); + if($form->validated) { + $c->flash(messages => [{type => 'success', text => 'NCOS Level successfully created!'}]); + $c->response->redirect($c->uri_for_action('/ncos/root')); + return; + } + + $c->stash(close_target => $c->uri_for()); + $c->stash(create_flag => 1); + $c->stash(form => $form); +} + +sub pattern_list :Chained('base') :PathPart('pattern') :CaptureArgs(0) { + my ( $self, $c ) = @_; + + my $pattern_rs = $c->stash->{level_result}->ncos_pattern_lists; + $c->stash(pattern_rs => $pattern_rs); + $c->stash(pattern_base_uri => + $c->uri_for_action("/ncos/pattern_root", [$c->req->captures->[0]])); + + $c->stash(has_edit => 1); + $c->stash(has_delete => 1); + $c->stash(template => 'ncos/pattern_list.tt'); +} + +sub pattern_root :Chained('pattern_list') :PathPart('') :Args(0) { + my ($self, $c) = @_; +} + +sub pattern_ajax :Chained('pattern_list') :PathPart('ajax') :Args(0) { + my ($self, $c) = @_; + + my $resultset = $c->stash->{pattern_rs}; + + $c->forward( "/ajax_process_resultset", [$resultset, + ["id", "pattern", "description"], + [1,2]]); + + $c->detach( $c->view("JSON") ); +} + +sub pattern_base :Chained('pattern_list') :PathPart('') :CaptureArgs(1) { + my ($self, $c, $pattern_id) = @_; + + unless($pattern_id && $pattern_id->is_integer) { + $c->flash(messages => [{type => 'error', text => 'Invalid NCOS Pattern id detected!'}]); + $c->response->redirect($c->stash->{pattern_base_uri}); + $c->detach; + return; + } + + my $res = $c->stash->{pattern_rs}->find($pattern_id); + unless(defined($res)) { + $c->flash(messages => [{type => 'error', text => 'Pattern does not exist!'}]); + $c->response->redirect($c->stash->{pattern_base_uri}); + $c->detach; + return; + } + $c->stash(pattern_result => $res); +} + +sub pattern_edit :Chained('pattern_base') :PathPart('edit') { + my ($self, $c) = @_; + + my $posted = ($c->request->method eq 'POST'); + my $form = NGCP::Panel::Form::NCOSPattern->new; + $form->process( + posted => $posted, + params => $c->request->params, + action => $c->uri_for_action('/ncos/pattern_edit', $c->req->captures), + item => $c->stash->{pattern_result}, + ); + if($form->validated) { + $c->flash(messages => [{type => 'success', text => 'Pattern successfully changed!'}]); + $c->response->redirect($c->stash->{pattern_base_uri}); + return; + } + + $c->stash(close_target => $c->stash->{pattern_base_uri}); + $c->stash(form => $form); + $c->stash(edit_flag => 1); +} + +sub pattern_delete :Chained('pattern_base') :PathPart('delete') { + my ($self, $c) = @_; + + try { + $c->stash->{pattern_result}->delete; + $c->flash(messages => [{type => 'success', text => 'Pattern successfully deleted!'}]); + } catch (DBIx::Class::Exception $e) { + $c->flash(messages => [{type => 'error', text => 'Delete failed.'}]); + $c->log->info("Delete failed: " . $e); + }; + $c->response->redirect($c->stash->{pattern_base_uri}); +} + +sub pattern_create :Chained('pattern_list') :PathPart('create') :Args(0) { + my ($self, $c) = @_; + + my $form = NGCP::Panel::Form::NCOSPattern->new; + $form->process( + posted => ($c->request->method eq 'POST'), + params => $c->request->params, + action => $c->uri_for_action('/ncos/pattern_create'), + item => $c->stash->{pattern_rs}->new_result({}), + ); + if($form->validated) { + $c->flash(messages => [{type => 'success', text => 'Pattern successfully created!'}]); + $c->response->redirect($c->stash->{pattern_base_uri}); + return; + } + + $c->stash(close_target => $c->stash->{pattern_base_uri}); + $c->stash(create_flag => 1); + $c->stash(form => $form); +} + + +__PACKAGE__->meta->make_immutable; + +1; + +=head1 NAME + +NGCP::Panel::Controller::NCOS - manage NCOS levels/patterns + +=head1 DESCRIPTION + +Show/Edit/Create/Delete NCOS Levels. + +Show/Edit/Create/Delete Number patterns. + +=head1 METHODS + +=head2 auto + +Grants access to admin and reseller role. + +=head2 levels_list + +Basis for billing.ncos_levels. + +=head2 root + +Display NCOS Levels through F template. + +=head2 ajax + +Get billing.ncos_levels from db and output them as JSON. +The format is meant for parsing with datatables. + +=head2 base + +Fetch a billing.ncos_levels row from the database by its id. +The resultset is exported to stash as "level_result". + +=head2 edit + +Show a modal to edit the NCOS Level determined by L. + +=head2 delete + +Delete the NCOS Level determined by L. + +=head2 create + +Show modal to create a new NCOS Level using the form +L. + +=head2 pattern_list + +Basis for billing.ncos_pattern_list. +Fetches all patterns related to the level determined by L and stashes +the resultset under "pattern_rs". + +=head2 pattern_root + +Display NCOS Number Patterns through F template. + +=head2 pattern_ajax + +Get patterns from db using the resultset from L and +output them as JSON. The format is meant for parsing with datatables. + +=head2 pattern_base + +Fetch a billing.ncos_pattern_list row from the database by its id. +The resultset is exported to stash as "pattern_result". + +=head2 pattern_edit + +Show a modal to edit the Number Pattern determined by L. + +=head2 pattern_delete + +Delete the Number Pattern determined by L. + +=head2 pattern_create + +Show modal to create a new Number Pattern for the current Level using the form +L. + +=head1 AUTHOR + +Gerhard Jungwirth C<< >> + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Form/NCOSLevel.pm b/lib/NGCP/Panel/Form/NCOSLevel.pm new file mode 100644 index 0000000000..41544db8e2 --- /dev/null +++ b/lib/NGCP/Panel/Form/NCOSLevel.pm @@ -0,0 +1,73 @@ +package NGCP::Panel::Form::NCOSLevel; + +use HTML::FormHandler::Moose; +extends 'HTML::FormHandler::Model::DBIC'; +use Moose::Util::TypeConstraints; + +use HTML::FormHandler::Widget::Block::Bootstrap; + +has '+widget_wrapper' => ( default => 'Bootstrap' ); +sub build_render_list {[qw/fields actions/]} +sub build_form_element_class { [qw/form-horizontal/] } + +has_field 'level' => ( + type => 'Text', + label => 'Name', + required => 1, +); + +has_field 'mode' => ( + type => 'Select', + options => [ + {value => 'whitelist', label => 'whitelist'}, + {value => 'blacklist', label => 'blacklist'}, + ], +); + +has_field 'description' => ( + type => 'Text', +); + +has_field 'save' => ( + type => 'Submit', + value => 'Save', + element_class => [qw/btn btn-primary/], + label => '', +); + +has_block 'fields' => ( + tag => 'div', + class => [qw/modal-body/], + render_list => [qw/level mode description/], +); + +has_block 'actions' => ( + tag => 'div', + class => [qw/modal-footer/], + render_list => [qw/save/], +); + +1; + +=head1 NAME + +NGCP::Panel::Form::NCOSLevel + +=head1 DESCRIPTION + +Form to modify a billing.ncos_levels row. + +=head1 METHODS + +=head1 AUTHOR + +Gerhard Jungwirth + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Form/NCOSPattern.pm b/lib/NGCP/Panel/Form/NCOSPattern.pm new file mode 100644 index 0000000000..8eaaf82f08 --- /dev/null +++ b/lib/NGCP/Panel/Form/NCOSPattern.pm @@ -0,0 +1,64 @@ +package NGCP::Panel::Form::NCOSPattern; + +use HTML::FormHandler::Moose; +extends 'HTML::FormHandler::Model::DBIC'; +use Moose::Util::TypeConstraints; + +use HTML::FormHandler::Widget::Block::Bootstrap; + +has '+widget_wrapper' => ( default => 'Bootstrap' ); +sub build_render_list {[qw/fields actions/]} +sub build_form_element_class { [qw/form-horizontal/] } + +has_field 'pattern' => ( + type => '+NGCP::Panel::Field::Regexp', + required => 1, +); + +has_field 'description' => ( + type => 'Text', +); + +has_field 'save' => ( + type => 'Submit', + value => 'Save', + element_class => [qw/btn btn-primary/], + label => '', +); + +has_block 'fields' => ( + tag => 'div', + class => [qw/modal-body/], + render_list => [qw/pattern description/], +); + +has_block 'actions' => ( + tag => 'div', + class => [qw/modal-footer/], + render_list => [qw/save/], +); + +1; + +=head1 NAME + +NGCP::Panel::Form::NCOSPattern + +=head1 DESCRIPTION + +Form to modify a billing.ncos_pattern_list row. + +=head1 METHODS + +=head1 AUTHOR + +Gerhard Jungwirth + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +# vim: set tabstop=4 expandtab: diff --git a/share/templates/ncos/list.tt b/share/templates/ncos/list.tt new file mode 100644 index 0000000000..69fcfcdaff --- /dev/null +++ b/share/templates/ncos/list.tt @@ -0,0 +1,23 @@ +[% META title = 'NCOS Levels' -%] +[% + helper.name = 'NCOS Levels'; + helper.messages = messages; + helper.column_titles = [ '#', 'Level', 'Mode', 'Description' ]; + helper.column_fields = [ 'id', 'level', 'mode', 'description' ]; + + helper.close_target = close_target; + helper.create_flag = create_flag; + helper.edit_flag = edit_flag; + helper.form_object = form; + helper.has_edit = has_edit; + helper.has_delete = has_delete; + helper.ajax_uri = c.uri_for_action( "/ncos/ajax" ); + helper.base_uri = c.uri_for_action( "/ncos/root" ); + + helper.extra_buttons = [ + [ 'Patterns', 'pattern'], + ]; + + PROCESS 'helpers/datatables.tt'; +-%] +[% # vim: set tabstop=4 syntax=html expandtab: -%] diff --git a/share/templates/ncos/pattern_list.tt b/share/templates/ncos/pattern_list.tt new file mode 100644 index 0000000000..61bbba102d --- /dev/null +++ b/share/templates/ncos/pattern_list.tt @@ -0,0 +1,22 @@ +[% site_config.title = 'Number Patterns for ' _ level_result.level -%] + +< Back + +[% + helper.name = 'Number Pattern'; + helper.messages = messages; + helper.column_titles = [ '#', 'Pattern', 'Description' ]; + helper.column_fields = [ 'id', 'pattern', 'description' ]; + + helper.close_target = close_target; + helper.create_flag = create_flag; + helper.edit_flag = edit_flag; + helper.form_object = form; + helper.has_edit = has_edit; + helper.has_delete = has_delete; + helper.ajax_uri = c.uri_for_action( "/ncos/pattern_ajax", [c.req.captures.0] ); + helper.base_uri = c.uri_for_action( "/ncos/pattern_root", [c.req.captures.0] ); + + PROCESS 'helpers/datatables.tt'; +-%] +[% # vim: set tabstop=4 syntax=html expandtab: -%] diff --git a/share/templates/widgets/admin_topmenu_settings.tt b/share/templates/widgets/admin_topmenu_settings.tt index 2025624ebb..2e7bac8ad9 100644 --- a/share/templates/widgets/admin_topmenu_settings.tt +++ b/share/templates/widgets/admin_topmenu_settings.tt @@ -11,6 +11,7 @@
  • Billing
  • Peerings
  • Rewrite Rule Sets
  • +
  • NCOS Levels
  • [% # vim: set tabstop=4 syntax=html expandtab: -%] diff --git a/t/controller_NCOS.t b/t/controller_NCOS.t new file mode 100644 index 0000000000..4fa8ae0e88 --- /dev/null +++ b/t/controller_NCOS.t @@ -0,0 +1,10 @@ +use strict; +use warnings; +use Test::More; + + +use Catalyst::Test 'NGCP::Panel'; +use NGCP::Panel::Controller::NCOS; + +ok( request('/ncos')->is_success || request('/ncos')->is_redirect, 'Request should succeed' ); +done_testing();