diff --git a/lib/NGCP/Panel/Controller/Subscriber.pm b/lib/NGCP/Panel/Controller/Subscriber.pm index 500e7e7654..a90e77f8a6 100644 --- a/lib/NGCP/Panel/Controller/Subscriber.pm +++ b/lib/NGCP/Panel/Controller/Subscriber.pm @@ -8,6 +8,7 @@ use NGCP::Panel::Utils::Contract; use NGCP::Panel::Utils::Subscriber; use NGCP::Panel::Utils::Datatables; use NGCP::Panel::Form::Subscriber; +use NGCP::Panel::Form::SubscriberEdit; use NGCP::Panel::Form::SubscriberCFSimple; use NGCP::Panel::Form::SubscriberCFTSimple; use NGCP::Panel::Form::SubscriberCFAdvanced; @@ -1309,6 +1310,83 @@ sub details :Chained('master') :PathPart('') :Args(0) { my ($self, $c) = @_; } +sub edit_master :Chained('master') :PathPart('edit') { + my ($self, $c, $attribute) = @_; + + my $form = NGCP::Panel::Form::SubscriberEdit->new; + my $posted = ($c->request->method eq 'POST'); + my $subscriber = $c->stash->{subscriber}; + my $prov_subscriber = $subscriber->provisioning_voip_subscriber; + + my $params; + my $lock = NGCP::Panel::Utils::Subscriber::get_usr_preference_rs( + c => $c, + attribute => 'lock', + prov_subscriber => $prov_subscriber, + ); + + unless($posted) { + $params->{webusername} = $prov_subscriber->webusername; + $params->{webpassword} = $prov_subscriber->webpassword; + $params->{password} = $prov_subscriber->password; + $params->{administrative} = $prov_subscriber->admin; + + $params->{e164}->{cc} = $subscriber->primary_number->cc; + $params->{e164}->{ac} = $subscriber->primary_number->ac; + $params->{e164}->{sn} = $subscriber->primary_number->sn; + $params->{status} = $subscriber->status; + $params->{external_id} = $subscriber->external_id; + + $params->{lock} = $lock->first ? $lock->first->value : undef; + } + + $form->process( + params => $posted ? $c->request->params : $params + ); + + if($posted && $form->validated) { + my $schema = $c->model('DB'); + try { + $schema->txn_do(sub { + $prov_subscriber->update({ + webusername => $form->field('webusername')->value, + webpassword => $form->field('webpassword')->value, + password => $form->field('password')->value, + admin => $form->field('administrative')->value, + }); + $subscriber->update({ + status => $form->field('status')->value, + external_id => $form->field('external_id')->value, + }); + # TODO: check for availablity of cc and sn + $subscriber->primary_number->update({ + cc => $form->field('e164')->field('cc')->value, + ac => $form->field('e164')->field('ac')->value, + sn => $form->field('e164')->field('sn')->value, + }); + if($lock->first) { + $lock->first->update({ value => $form->field('lock')->value }); + } else { + $lock->create({ value => $form->field('lock')->value }); + } + }); + $c->flash(messages => [{type => 'success', text => 'Successfully updated subscriber'}]); + } catch($e) { + $c->log->error("failed to update subscriber: $e"); + $c->flash(messages => [{type => 'error', text => 'Failed to update subscriber'}]); + } + + $c->response->redirect($c->uri_for_action('/subscriber/details', [$c->req->captures->[0]])); + return; + } + + $c->stash( + edit_flag => 1, + form => $form, + ); + +} + sub ajax_calls :Chained('master') :PathPart('calls/ajax') :Args(0) { my ($self, $c) = @_; diff --git a/lib/NGCP/Panel/Field/SubscriberLockSelect.pm b/lib/NGCP/Panel/Field/SubscriberLockSelect.pm new file mode 100644 index 0000000000..7cd7c9483f --- /dev/null +++ b/lib/NGCP/Panel/Field/SubscriberLockSelect.pm @@ -0,0 +1,19 @@ +package NGCP::Panel::Field::SubscriberLockSelect; +use Moose; +extends 'HTML::FormHandler::Field::Select'; + +sub build_options { + my ($self) = @_; + + return [ + { label => 'none', value => undef }, + { label => 'foreign', value => 1 }, + { label => 'outgoing', value => 2 }, + { label => 'incoming', value => 3 }, + { label => 'global', value => 4 }, + ]; +} + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Form/Subscriber.pm b/lib/NGCP/Panel/Form/Subscriber.pm index 550e3a8943..89136bdfb9 100644 --- a/lib/NGCP/Panel/Form/Subscriber.pm +++ b/lib/NGCP/Panel/Form/Subscriber.pm @@ -37,7 +37,7 @@ has_field 'webusername' => ( ); has_field 'webpassword' => ( - type => 'Password', + type => 'Text', label => 'Web Password', required => 0, element_attr => { @@ -106,7 +106,7 @@ has_field 'domain' => ( ); has_field 'password' => ( - type => 'Password', + type => 'Text', label => 'SIP Password', required => 1, element_attr => { diff --git a/lib/NGCP/Panel/Form/SubscriberEdit.pm b/lib/NGCP/Panel/Form/SubscriberEdit.pm new file mode 100644 index 0000000000..238f3dab87 --- /dev/null +++ b/lib/NGCP/Panel/Form/SubscriberEdit.pm @@ -0,0 +1,260 @@ +package NGCP::Panel::Form::SubscriberEdit; + +use HTML::FormHandler::Moose; +extends 'HTML::FormHandler'; +use Moose::Util::TypeConstraints; + +use HTML::FormHandler::Widget::Block::Bootstrap; + +use NGCP::Panel::Field::Domain; +use NGCP::Panel::Field::CustomerContract; +use NGCP::Panel::Field::Reseller; + +with 'NGCP::Panel::Render::RepeatableJs'; + +has '+widget_wrapper' => ( default => 'Bootstrap' ); +sub build_render_list {[qw/fields actions/]} +sub build_form_element_class { [qw/form-horizontal/] } + +has_field 'reseller' => ( + type => '+NGCP::Panel::Field::Reseller', + label => 'Reseller', + not_nullable => 1, +); + +has_field 'webusername' => ( + type => 'Text', + label => 'Web Username', + required => 0, + element_attr => { + rel => ['tooltip'], + title => ['The username to log into the CSC Panel'] + }, +); + +has_field 'webpassword' => ( + type => 'Text', + label => 'Web Password', + required => 0, + element_attr => { + rel => ['tooltip'], + title => ['The password to log into the CSC Panel'] + }, +); + +has_field 'e164' => ( + type => 'Compound', + order => 99, + required => 0, + label => 'E164 Number', + do_label => 1, + do_wrapper => 1, +); + +has_field 'e164.cc' => ( + type => 'PosInteger', + element_attr => { + class => ['ngcp_e164_cc'], + rel => ['tooltip'], + title => ['Country Code, e.g. 1 for US or 43 for Austria'] + }, + do_label => 0, + do_wrapper => 0, +); + +has_field 'e164.ac' => ( + type => 'PosInteger', + element_attr => { + class => ['ngcp_e164_ac'], + rel => ['tooltip'], + title => ['Area Code, e.g. 212 for NYC or 1 for Vienna'] + }, + do_label => 0, + do_wrapper => 0, +); + +has_field 'e164.sn' => ( + type => 'PosInteger', + element_attr => { + class => ['ngcp_e164_sn'], + rel => ['tooltip'], + title => ['Subscriber Number, e.g. 12345678'] + }, + do_label => 0, + do_wrapper => 0, +); + +has_field 'alias_number' => ( + type => 'Repeatable', + setup_for_js => 1, + do_wrapper => 1, + do_label => 0, + tags => { + controls_div => 1, + }, + wrapper_class => [qw/hfh-rep/], +); + +has_field 'alias_number.id' => ( + type => 'Hidden', +); + +has_field 'alias_number.e164' => ( + type => 'Compound', + order => 99, + required => 0, + label => 'Alias Number', + do_label => 1, + do_wrapper => 1, + wrapper_class => [qw/hfh-rep-field/], +); + +has_field 'alias_number.e164.cc' => ( + type => 'PosInteger', + element_attr => { + class => ['ngcp_e164_cc'], + rel => ['tooltip'], + title => ['Country Code, e.g. 1 for US or 43 for Austria'] + }, + do_label => 0, + do_wrapper => 0, +); + +has_field 'alias_number.e164.ac' => ( + type => 'PosInteger', + element_attr => { + class => ['ngcp_e164_ac'], + rel => ['tooltip'], + title => ['Area Code, e.g. 212 for NYC or 1 for Vienna'] + }, + do_label => 0, + do_wrapper => 0, +); + +has_field 'alias_number.e164.sn' => ( + type => 'PosInteger', + element_attr => { + class => ['ngcp_e164_sn'], + rel => ['tooltip'], + title => ['Subscriber Number, e.g. 12345678'] + }, + do_label => 0, + do_wrapper => 0, +); + +has_field 'alias_number.rm' => ( + type => 'RmElement', + value => 'Remove', + order => 100, + element_class => [qw/btn btn-primary pull-right/], +); + +has_field 'alias_number_add' => ( + type => 'AddElement', + repeatable => 'alias_number', + value => 'Add another number', + element_class => [qw/btn btn-primary pull-right/], +); + +has_field 'password' => ( + type => 'Text', + label => 'SIP Password', + required => 1, + element_attr => { + rel => ['tooltip'], + title => ['The SIP password for the User-Agents'] + }, +); + +has_field 'lock' => ( + type => '+NGCP::Panel::Field::SubscriberLockSelect', + label => 'Lock Level', + not_nullable => 1, +); + +has_field 'status' => ( + type => '+NGCP::Panel::Field::SubscriberStatusSelect', + label => 'Status', + not_nullable => 1, +); + +has_field 'administrative' => ( + type => 'Boolean', + label => 'Administrative', + required => 0, + element_attr => { + rel => ['tooltip'], + title => ['Subscriber can configure other subscribers within the Customer Account'] + }, +); + + +has_field 'external_id' => ( + type => 'Text', + label => 'External ID', + required => 0, + element_attr => { + rel => ['tooltip'], + title => ['An external id, e.g. provided by a 3rd party provisioning'] + }, +); + + +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/webusername webpassword e164 alias_number alias_number_add password lock status external_id administrative/ ], +); + +has_block 'actions' => ( + tag => 'div', + class => [qw/modal-footer/], + render_list => [qw/save/], +); + +sub validate { + my $self = shift; + my $cc = $self->field('e164.cc')->value; + my $sn = $self->field('e164.sn')->value; + + if (defined $cc && $cc ne '' && (!defined $sn || $sn eq '')) { + my $err_msg = 'Subscriber Number required if Country Code is set'; + $self->field('e164')->add_error($err_msg); + } elsif(defined $sn && $sn ne '' && (!defined $cc || $cc eq '')) { + my $err_msg = 'Country Code required if Subscriber Number is set'; + $self->field('e164')->add_error($err_msg); + } +} + +1; + +=head1 NAME + +NGCP::Panel::Form::Subscriber + +=head1 DESCRIPTION + +Form to modify a subscriber. + +=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/customer/details.tt b/share/templates/customer/details.tt index d33debd33f..3f33632794 100644 --- a/share/templates/customer/details.tt +++ b/share/templates/customer/details.tt @@ -55,9 +55,7 @@
| Setting | Values | -|
|---|---|---|
| Customer # | [% subscriber.contract.id %] | -
-
- Customer
-
- |
-
| CSC Username | -[% subscriber.webusername %] | -
-
- Preferences
-
- |
-
| CSC Password | -[% subscriber.webpassword%] | -
-
- Preferences
-
- |
| SIP URI | -[% subscriber.username %]@[% subscriber.domain.domain %] | -
-
- Preferences
-
- |
-
| SIP Password | -[% subscriber.password %] | -
-
- Preferences
-
- |
-
| Primary Number | -[% subscriber.primary_number.cc %] [% subscriber.primary_number.ac %] [% subscriber.primary_number.sn %] | -
-
- Preferences
-
- |
-
| Alias Numbers | -[% subscriber.primary_number.cc %] [% subscriber.primary_number.ac %] [% subscriber.primary_number.sn %] | -
-
- Preferences
-
- |
-
| Administrative | -[% subscriber.administrative ? 'yes' : 'no' %] | -
-
- Preferences
-
- |
-
| [% elem.desc %] | +[% elem.value %] | +|
| UUID | [% subscriber.uuid %] | -
-
- Preferences
-
- |
-
| External # | -[% subscriber.external_id %] | -
-
- Preferences
-
- |