diff --git a/lib/NGCP/Panel/Controller/Customer.pm b/lib/NGCP/Panel/Controller/Customer.pm index 5244f6e935..f180e410bf 100644 --- a/lib/NGCP/Panel/Controller/Customer.pm +++ b/lib/NGCP/Panel/Controller/Customer.pm @@ -6,7 +6,9 @@ use NGCP::Panel::Utils::Contract; use NGCP::Panel::Form::CustomerMonthlyFraud; use NGCP::Panel::Form::CustomerDailyFraud; use NGCP::Panel::Form::CustomerBalance; +use NGCP::Panel::Form::CustomerSubscriber; use NGCP::Panel::Utils::Navigation; +use UUID qw/generate unparse/; =head1 NAME @@ -117,6 +119,120 @@ sub details :Chained('base') :PathPart('details') :Args(0) { my ($self, $c) = @_; } +sub subscriber_create :Chained('base') :PathPart('subscriber/create') :Args(0) { + my ($self, $c) = @_; + + my $form = NGCP::Panel::Form::CustomerSubscriber->new; + $form->process( + posted => ($c->request->method eq 'POST'), + params => $c->request->params, + ); + return if NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, + form => $form, + fields => [qw/domain.create/], + back_uri => $c->uri_for_action('/customer/subscriber_create', [ $c->req->captures->[0]]), + ); + if($form->validated) { + my $schema = $c->model('DB'); + my $contract = $c->stash->{contract}; + my $reseller = $contract->reseller; + my $billing_domain = $schema->resultset('domains') + ->find($c->request->params->{'domain.id'}); + my $prov_domain = $schema->resultset('voip_domains') + ->find({domain => $billing_domain->domain}); + try { + $schema->txn_do(sub { + my ($uuid_bin, $uuid_string); + UUID::generate($uuid_bin); + UUID::unparse($uuid_bin, $uuid_string); + + # TODO: check if we find a reseller and contract and domains + + my $number; + if(defined $c->request->params->{'e164.cc'} && + $c->request->params->{'e164.cc'} ne '') { + + $number = $reseller->voip_numbers->create({ + cc => $c->request->params->{'e164.cc'}, + ac => $c->request->params->{'e164.ac'} || '', + sn => $c->request->params->{'e164.sn'}, + status => 'active', + }); + } + my $billing_subscriber = $contract->voip_subscribers->create({ + uuid => $uuid_string, + username => $c->request->params->{username}, + domain_id => $billing_domain->id, + status => $c->request->params->{status}, + primary_number_id => defined $number ? $number->id : undef, + }); + if(defined $number) { + $number->update({ subscriber_id => $billing_subscriber->id }); + } + + my $prov_subscriber = $schema->resultset('provisioning_voip_subscribers')->create({ + uuid => $uuid_string, + username => $c->request->params->{username}, + password => $c->request->params->{password}, + webusername => $c->request->params->{webusername} || $c->request->params->{username}, + webpassword => $c->request->params->{webpassword}, + admin => $c->request->params->{administrative} || 0, + account_id => $contract->id, + domain_id => $prov_domain->id, + }); + + my $voip_preferences = $schema->resultset('voip_preferences')->search({ + 'usr_pref' => 1, + }); + $voip_preferences->find({ 'attribute' => 'account_id' }) + ->voip_usr_preferences->create({ + 'subscriber_id' => $prov_subscriber->id, + 'value' => $contract->id, + }); + $voip_preferences->find({ 'attribute' => 'ac' }) + ->voip_usr_preferences->create({ + 'subscriber_id' => $prov_subscriber->id, + 'value' => $c->request->params->{'e164.ac'}, + }) if (defined $c->request->params->{'e164.ac'} && + length($c->request->params->{'e164.ac'}) > 0); + if(defined $c->request->params->{'e164.cc'} && + length($c->request->params->{'e164.cc'}) > 0) { + + $voip_preferences->find({ 'attribute' => 'cc' }) + ->voip_usr_preferences->create({ + 'subscriber_id' => $prov_subscriber->id, + 'value' => $c->request->params->{'e164.cc'}, + }); + my $cli = $c->request->params->{'e164.cc'} . + (defined $c->request->params->{'e164.ac'} && + length($c->request->params->{'e164.ac'}) > 0 ? + $c->request->params->{'e164.ac'} : '' + ) . + $c->request->params->{'e164.sn'}; + $voip_preferences->find({ 'attribute' => 'cli' }) + ->voip_usr_preferences->create({ + 'subscriber_id' => $prov_subscriber->id, + 'value' => $cli, + }); + } + }); + $c->flash(messages => [{type => 'success', text => 'Subscriber successfully created!'}]); + $c->response->redirect($c->uri_for_action('/customer/details', [$contract->id])); + return; + } catch($e) { + $c->log->error("Failed to create subscriber: $e"); + $c->flash(messages => [{type => 'error', text => 'Creating subscriber failed!'}]); + $c->response->redirect($c->uri_for_action('/customer/details', [$contract->id])); + return; + } + } + + $c->stash(close_target => $c->uri_for()); + $c->stash(create_flag => 1); + $c->stash(form => $form) +} + sub edit_fraud :Chained('base') :PathPart('fraud/edit') :Args(1) { my ($self, $c, $type) = @_; diff --git a/lib/NGCP/Panel/Controller/Subscriber.pm b/lib/NGCP/Panel/Controller/Subscriber.pm index 49ebad6bfa..193eff294d 100644 --- a/lib/NGCP/Panel/Controller/Subscriber.pm +++ b/lib/NGCP/Panel/Controller/Subscriber.pm @@ -44,11 +44,11 @@ sub sub_list :Chained('/') :PathPart('subscriber') :CaptureArgs(0) { ); NGCP::Panel::Utils::Datatables::set_columns($c, [ - { name => "id", title => "#" }, - { name => "username", "search" => 1, title => 'Username' }, - { name => "domain.domain", "search" => 1, title => 'Domain' }, - { name => "contract.status", "search" => 1, title => 'Contract Status' }, - { name => "status", "search" => 1, title => 'Status' }, + { name => "id", search => 1, title => "#" }, + { name => "username", search => 1, title => "Username" }, + { name => "domain.domain", search => 1, title => "Domain" }, + { name => "status", search => 1, title => "Status" }, + { name => "contract_id", search => 1, title => "Contract #"}, ]); #NGCP::Panel::Utils::Navigation::check_redirect_chain(c => $c); diff --git a/lib/NGCP/Panel/Form/CustomerSubscriber.pm b/lib/NGCP/Panel/Form/CustomerSubscriber.pm new file mode 100644 index 0000000000..1036692a37 --- /dev/null +++ b/lib/NGCP/Panel/Form/CustomerSubscriber.pm @@ -0,0 +1,189 @@ +package NGCP::Panel::Form::CustomerSubscriber; + +use HTML::FormHandler::Moose; +extends 'HTML::FormHandler'; +use Moose::Util::TypeConstraints; + +use HTML::FormHandler::Widget::Block::Bootstrap; + +use NGCP::Panel::Field::Domain; + +has '+widget_wrapper' => ( default => 'Bootstrap' ); +sub build_render_list {[qw/fields actions/]} +sub build_form_element_class { [qw/form-horizontal/] } + +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 => 'Password', + 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 'username' => ( + type => 'Text', + label => 'SIP Username', + required => 1, + noupdate => 1, + element_attr => { + rel => ['tooltip'], + title => ['The SIP username for the User-Agents'] + }, +); + +has_field 'domain' => ( + type => '+NGCP::Panel::Field::Domain', + label => 'SIP Domain', + not_nullable => 1, +); + +has_field 'password' => ( + type => 'Password', + label => 'SIP Password', + required => 1, + element_attr => { + rel => ['tooltip'], + title => ['The SIP password for the User-Agents'] + }, +); + +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 username domain password 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 79c1ddc04f..743897851c 100644 --- a/share/templates/customer/details.tt +++ b/share/templates/customer/details.tt @@ -26,11 +26,40 @@
-Type | +Billing Profile | ++ |
---|---|---|
Active Billing Profile | +fooo | ++ |
Other Billing Profiles | +
+ 2013-04-28 18:00:00 - 2013-04-09 23:59:59: bar + 2013-06-25 00:00:00 - 2013-07-01 23:59:59: blub + |
+ + |
SIP URI | @@ -41,7 +70,7 @@||||
---|---|---|---|---|
[% subscriber.username %]@[% subscriber.domain %] | [% subscriber.primary_number.cc %] [% subscriber.primary_number.ac %] [% subscriber.primary_number.sn %] |
@@ -49,7 +78,11 @@
[% location.user_agent %] [% END -%] |
- + |
+
+ Preferences
+
+ |