diff --git a/lib/NGCP/Panel/Controller/Subscriber.pm b/lib/NGCP/Panel/Controller/Subscriber.pm index d96767d37d..586418bd1d 100644 --- a/lib/NGCP/Panel/Controller/Subscriber.pm +++ b/lib/NGCP/Panel/Controller/Subscriber.pm @@ -115,6 +115,7 @@ sub sub_list :Chained('/') :PathPart('subscriber') :CaptureArgs(0) { { name => "status", search => 1, title => $c->loc('Status') }, { name => "number", search => 1, title => $c->loc('Number'), literal_sql => "concat(primary_number.cc, primary_number.ac, primary_number.sn)"}, { name => "primary_number.cc", search => 1, title => "" }, #need this to get the relationship + { name => "provisioning_voip_subscriber.voip_subscriber_profile.name", search => 1, title => $c->loc('Profile') }, ]); } @@ -142,6 +143,7 @@ sub create_list :Chained('sub_list') :PathPart('create') :Args(0) :Does(ACL) :AC 'domain.create' => $c->uri_for('/domain/create'), 'reseller.create' => $c->uri_for('/reseller/create'), 'contract.create' => $c->uri_for('/customer/create'), + 'profile.create' => $c->uri_for('/subscriberprofile/create'), }, back_uri => $c->req->uri, ); @@ -161,6 +163,27 @@ sub create_list :Chained('sub_list') :PathPart('create') :Args(0) :Does(ACL) :AC ->find({domain => $billing_domain->domain}); my $reseller = $contract->contact->reseller; + my $profile; + if($form->values->{profile}{id}) { + my $profile_rs = $c->model('DB')->resultset('voip_subscriber_profiles'); + if($c->user->roles eq "admin") { + } elsif($c->user->roles eq "reseller") { + $profile_rs = $profile_rs->search({ + reseller_id => $c->user->reseller_id, + }); + } + + $profile = $profile_rs->find($form->values->{profile}{id}); + unless($profile) { + NGCP::Panel::Utils::Message->error( + c => $c, + error => 'invalid subscriber profile id ' . $form->values->{profile}{id}, + desc => $c->loc('Invalid subscriber profile id'), + ); + return; + } + delete $form->values->{profile}; + } my $billing_subscriber = $contract->voip_subscribers->create({ uuid => $uuid_string, @@ -179,6 +202,7 @@ sub create_list :Chained('sub_list') :PathPart('create') :Args(0) :Does(ACL) :AC admin => $c->request->params->{administrative} || 0, account_id => $contract->id, domain_id => $prov_domain->id, + profile_id => $profile ? $profile->id : undef, create_timestamp => NGCP::Panel::Utils::DateTime::current_local, }); @@ -1790,6 +1814,8 @@ sub edit_master :Chained('master') :PathPart('edit') :Args(0) :Does(ACL) :ACLDet $c->request->params->{status} = $subscriber->status; } unless($posted) { + $params->{profile}{id} = $prov_subscriber->voip_subscriber_profile ? + $prov_subscriber->voip_subscriber_profile->id : undef; $params->{webusername} = $prov_subscriber->webusername; $params->{administrative} = $prov_subscriber->admin; if($subscriber->primary_number) { @@ -1808,9 +1834,11 @@ sub edit_master :Chained('master') :PathPart('edit') :Args(0) :Does(ACL) :ACLDet $params->{extension} = $full; } } - if($pbx_ext) { - $params->{group}{id} = $prov_subscriber->pbx_group_id; - } + } + if($pbx_ext) { + $params->{group}{id} = $prov_subscriber->pbx_group_id; + # TODO: rework to store ext in sub + #$params->{extension} = $prov_subscriber->pbx_group_id; } my @alias_options = (); @@ -1846,6 +1874,7 @@ sub edit_master :Chained('master') :PathPart('edit') :Args(0) :Does(ACL) :ACLDet form => $form, fields => { $pbx_ext ? ('group.create' => $c->uri_for_action('/customer/pbx_group_create', [$prov_subscriber->account_id])) : (), + 'profile.create' => $c->uri_for_action('/subscriberprofile/create'), }, back_uri => $c->req->uri, ); @@ -1870,6 +1899,32 @@ sub edit_master :Chained('master') :PathPart('edit') :Args(0) :Does(ACL) :ACLDet $prov_params->{pbx_group_id} = $form->params->{group}{id} if($pbx_ext); my $old_group_id = $prov_subscriber->pbx_group_id; + + my $profile; + if($form->values->{profile}{id}) { + my $profile_rs = $c->model('DB')->resultset('voip_subscriber_profiles'); + if($c->user->roles eq "admin") { + } elsif($c->user->roles eq "reseller") { + $profile_rs = $profile_rs->search({ + reseller_id => $c->user->reseller_id, + }); + } + + $profile = $profile_rs->find($form->values->{profile}{id}); + unless($profile) { + NGCP::Panel::Utils::Message->error( + c => $c, + error => 'invalid subscriber profile id ' . $form->values->{profile}{id}, + desc => $c->loc('Invalid subscriber profile id'), + ); + return; + } + delete $form->values->{profile}; + $prov_params->{profile_id} = $profile->id; + } else { + $prov_params->{profile_id} = undef; + } + $prov_subscriber->update($prov_params); NGCP::Panel::Utils::Subscriber::update_pbx_group_prefs( diff --git a/lib/NGCP/Panel/Controller/SubscriberProfile.pm b/lib/NGCP/Panel/Controller/SubscriberProfile.pm index 35edd5acf7..299c659601 100644 --- a/lib/NGCP/Panel/Controller/SubscriberProfile.pm +++ b/lib/NGCP/Panel/Controller/SubscriberProfile.pm @@ -9,7 +9,7 @@ use NGCP::Panel::Form::SubscriberProfile::Clone; use NGCP::Panel::Utils::Message; use NGCP::Panel::Utils::Navigation; -sub auto :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { +sub auto { my ($self, $c) = @_; $c->log->debug(__PACKAGE__ . '::auto'); NGCP::Panel::Utils::Navigation::check_redirect_chain(c => $c); @@ -21,11 +21,16 @@ sub profile_list :Chained('/') :PathPart('subscriberprofile') :CaptureArgs(0) { $c->stash->{profiles_rs} = $c->model('DB')->resultset('voip_subscriber_profiles'); if($c->user->roles eq "admin") { - } else { + } elsif($c->user->roles eq "reseller") { $c->stash->{profiles_rs} = $c->stash->{profiles_rs}->search({ reseller_id => $c->user->reseller_id }); + } else { + $c->stash->{profiles_rs} = $c->stash->{profiles_rs}->search({ + reseller_id => $c->user->voip_subscriber->contract->contact->reseller_id, + }); } + $c->stash->{profile_dt_columns} = NGCP::Panel::Utils::Datatables::set_columns($c, [ { name => 'id', search => 1, title => $c->loc('#') }, { name => 'reseller.name', search => 1, title => $c->loc('Reseller') }, @@ -36,7 +41,7 @@ sub profile_list :Chained('/') :PathPart('subscriberprofile') :CaptureArgs(0) { $c->stash(template => 'subprofile/list.tt'); } -sub root :Chained('profile_list') :PathPart('') :Args(0) { +sub root :Chained('profile_list') :PathPart('') :Args(0) :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c) = @_; } @@ -47,7 +52,7 @@ sub ajax :Chained('profile_list') :PathPart('ajax') :Args(0) { $c->detach( $c->view("JSON") ); } -sub base :Chained('profile_list') :PathPart('') :CaptureArgs(1) { +sub base :Chained('profile_list') :PathPart('') :CaptureArgs(1) :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c, $profile_id) = @_; unless($profile_id && $profile_id->is_integer) { @@ -71,7 +76,7 @@ sub base :Chained('profile_list') :PathPart('') :CaptureArgs(1) { $c->stash(profile_result => $res); } -sub create :Chained('profile_list') :PathPart('create') :Args(0) { +sub create :Chained('profile_list') :PathPart('create') :Args(0) :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c) = @_; my $posted = ($c->request->method eq 'POST'); @@ -143,7 +148,7 @@ sub create :Chained('profile_list') :PathPart('create') :Args(0) { $c->stash(create_flag => 1); } -sub edit :Chained('base') :PathPart('edit') { +sub edit :Chained('base') :PathPart('edit') :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c) = @_; my $profile = $c->stash->{profile_result}; @@ -224,7 +229,7 @@ sub edit :Chained('base') :PathPart('edit') { $c->stash(edit_flag => 1); } -sub delete :Chained('base') :PathPart('delete') { +sub delete :Chained('base') :PathPart('delete') :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c) = @_; try { @@ -240,7 +245,7 @@ sub delete :Chained('base') :PathPart('delete') { NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/subscriberprofile')); } -sub clone :Chained('base') :PathPart('clone') { +sub clone :Chained('base') :PathPart('clone') :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c) = @_; my $posted = ($c->request->method eq 'POST'); diff --git a/lib/NGCP/Panel/Field/SubscriberProfile.pm b/lib/NGCP/Panel/Field/SubscriberProfile.pm new file mode 100644 index 0000000000..0fde707cfd --- /dev/null +++ b/lib/NGCP/Panel/Field/SubscriberProfile.pm @@ -0,0 +1,26 @@ +package NGCP::Panel::Field::SubscriberProfile; +use HTML::FormHandler::Moose; +extends 'HTML::FormHandler::Field::Compound'; + +has_field 'id' => ( + type => '+NGCP::Panel::Field::DataTable', + label => 'Subscriber Profile', + do_label => 0, + do_wrapper => 0, + required => 1, + template => 'helpers/datatables_field.tt', + ajax_src => '/subscriberprofile/ajax', + table_titles => ['#', 'Reseller', 'Name'], + table_fields => ['id', 'reseller_name', 'name'], +); + +has_field 'create' => ( + type => 'Button', + do_label => 0, + value => 'Create Profile', + element_class => [qw/btn btn-tertiary pull-right/], +); + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Form/Customer/PbxAdminSubscriber.pm b/lib/NGCP/Panel/Form/Customer/PbxAdminSubscriber.pm index e3791551c6..c3a80b1426 100644 --- a/lib/NGCP/Panel/Form/Customer/PbxAdminSubscriber.pm +++ b/lib/NGCP/Panel/Form/Customer/PbxAdminSubscriber.pm @@ -22,7 +22,7 @@ has_field 'domain' => ( has_block 'fields' => ( tag => 'div', class => [qw/modal-body/], - render_list => [qw/domain e164 display_name webusername webpassword username password status external_id/ ], + render_list => [qw/domain e164 display_name webusername webpassword username password status external_id profile/ ], ); 1; diff --git a/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriber.pm b/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriber.pm index 5b22e12550..d8dbbc7dd3 100644 --- a/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriber.pm +++ b/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriber.pm @@ -23,7 +23,7 @@ has_field 'extension' => ( has_block 'fields' => ( tag => 'div', class => [qw/modal-body/], - render_list => [qw/group extension display_name webusername webpassword username password status external_id/ ], + render_list => [qw/group extension display_name webusername webpassword username password status external_id profile/ ], ); sub field_list { diff --git a/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEdit.pm b/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEdit.pm index 2c2a6baba2..84c9874b04 100644 --- a/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEdit.pm +++ b/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEdit.pm @@ -23,7 +23,7 @@ has_field 'extension' => ( has_block 'fields' => ( tag => 'div', class => [qw/modal-body/], - render_list => [qw/group extension display_name webusername webpassword password status external_id/ ], + render_list => [qw/group extension display_name webusername webpassword password status external_id profile/ ], ); sub update_fields { diff --git a/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEditAdmin.pm b/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEditAdmin.pm index 981fd9a7c3..71a879efc8 100644 --- a/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEditAdmin.pm +++ b/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEditAdmin.pm @@ -27,7 +27,7 @@ has_field 'alias_number_add' => ( has_block 'fields' => ( tag => 'div', class => [qw/modal-body/], - render_list => [qw/group extension alias_number alias_number_add display_name webusername webpassword password status external_id/ ], + render_list => [qw/group extension alias_number alias_number_add display_name webusername webpassword password status external_id profile/ ], ); 1; diff --git a/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEditSubadmin.pm b/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEditSubadmin.pm index 4704178751..df325e9e62 100644 --- a/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEditSubadmin.pm +++ b/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEditSubadmin.pm @@ -19,7 +19,7 @@ has_field 'alias_select' => ( has_block 'fields' => ( tag => 'div', class => [qw/modal-body/], - render_list => [qw/group extension display_name webusername webpassword password external_id alias_select/ ], + render_list => [qw/group extension display_name webusername webpassword password external_id alias_select profile/ ], ); sub update_fields { diff --git a/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEditSubadminNoGroup.pm b/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEditSubadminNoGroup.pm index a351b10672..933ca6a899 100644 --- a/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEditSubadminNoGroup.pm +++ b/lib/NGCP/Panel/Form/Customer/PbxExtensionSubscriberEditSubadminNoGroup.pm @@ -19,7 +19,7 @@ has_field 'alias_select' => ( has_block 'fields' => ( tag => 'div', class => [qw/modal-body/], - render_list => [qw/display_name webusername webpassword password external_id alias_select/ ], + render_list => [qw/display_name webusername webpassword password external_id alias_select profile/ ], ); sub update_fields { diff --git a/lib/NGCP/Panel/Form/Customer/PbxSubscriber.pm b/lib/NGCP/Panel/Form/Customer/PbxSubscriber.pm index 6e7ebd4b27..32f52b712b 100644 --- a/lib/NGCP/Panel/Form/Customer/PbxSubscriber.pm +++ b/lib/NGCP/Panel/Form/Customer/PbxSubscriber.pm @@ -81,6 +81,16 @@ has_field 'external_id' => ( }, ); +has_field 'profile' => ( + type => '+NGCP::Panel::Field::SubscriberProfile', + label => 'Subscriber Profile', + validate_when_empty => 0, + element_attr => { + rel => ['tooltip'], + title => ['The subscriber profile defining the feature set for this subscriber.'] + }, +); + has_field 'save' => ( type => 'Submit', value => 'Save', @@ -92,7 +102,7 @@ has_field 'save' => ( has_block 'fields' => ( tag => 'div', class => [qw/modal-body/], - render_list => [qw/display_name webusername webpassword username password status external_id/ ], + render_list => [qw/display_name webusername webpassword username password status external_id profile/ ], ); has_block 'actions' => ( diff --git a/lib/NGCP/Panel/Form/Customer/Subscriber.pm b/lib/NGCP/Panel/Form/Customer/Subscriber.pm index f72d849181..6539051695 100644 --- a/lib/NGCP/Panel/Form/Customer/Subscriber.pm +++ b/lib/NGCP/Panel/Form/Customer/Subscriber.pm @@ -98,6 +98,16 @@ has_field 'external_id' => ( }, ); +has_field 'profile' => ( + type => '+NGCP::Panel::Field::SubscriberProfile', + label => 'Subscriber Profile', + validate_when_empty => 0, + element_attr => { + rel => ['tooltip'], + title => ['The subscriber profile defining the feature set for this subscriber.'] + }, +); + has_field 'save' => ( type => 'Submit', @@ -110,7 +120,7 @@ has_field 'save' => ( has_block 'fields' => ( tag => 'div', class => [qw/modal-body/], - render_list => [qw/domain e164 webusername webpassword username password status external_id administrative/ ], + render_list => [qw/domain e164 webusername webpassword username password status external_id administrative profile/ ], ); has_block 'actions' => ( diff --git a/lib/NGCP/Panel/Form/Subscriber.pm b/lib/NGCP/Panel/Form/Subscriber.pm index 5bf138e4cf..a4d0ce8bb6 100644 --- a/lib/NGCP/Panel/Form/Subscriber.pm +++ b/lib/NGCP/Panel/Form/Subscriber.pm @@ -122,6 +122,16 @@ has_field 'external_id' => ( }, ); +has_field 'profile' => ( + type => '+NGCP::Panel::Field::SubscriberProfile', + label => 'Subscriber Profile', + validate_when_empty => 0, + element_attr => { + rel => ['tooltip'], + title => ['The subscriber profile defining the feature set for this subscriber.'] + }, +); + has_field 'save' => ( type => 'Submit', @@ -134,7 +144,7 @@ has_field 'save' => ( has_block 'fields' => ( tag => 'div', class => [qw/modal-body/], - render_list => [qw/contract domain e164 webusername webpassword username password status external_id administrative/ ], + render_list => [qw/contract domain e164 webusername webpassword username password status external_id administrative profile/ ], ); has_block 'actions' => ( diff --git a/lib/NGCP/Panel/Form/SubscriberEdit.pm b/lib/NGCP/Panel/Form/SubscriberEdit.pm index d4dbb97be6..e2283e3b34 100644 --- a/lib/NGCP/Panel/Form/SubscriberEdit.pm +++ b/lib/NGCP/Panel/Form/SubscriberEdit.pm @@ -111,6 +111,16 @@ has_field 'external_id' => ( }, ); +has_field 'profile' => ( + type => '+NGCP::Panel::Field::SubscriberProfile', + label => 'Subscriber Profile', + validate_when_empty => 0, + element_attr => { + rel => ['tooltip'], + title => ['The subscriber profile defining the feature set for this subscriber.'] + }, +); + has_field 'save' => ( type => 'Submit', value => 'Save', @@ -122,7 +132,7 @@ has_field 'save' => ( has_block 'fields' => ( tag => 'div', class => [qw/modal-body/], - render_list => [qw/e164 alias_number alias_number_add webusername webpassword password lock status external_id administrative/ ], + render_list => [qw/e164 alias_number alias_number_add webusername webpassword password lock status external_id administrative profile/ ], ); has_block 'actions' => ( diff --git a/lib/NGCP/Panel/Utils/Subscriber.pm b/lib/NGCP/Panel/Utils/Subscriber.pm index 5e8f9f4b38..d588f4ece5 100644 --- a/lib/NGCP/Panel/Utils/Subscriber.pm +++ b/lib/NGCP/Panel/Utils/Subscriber.pm @@ -140,6 +140,22 @@ sub create_subscriber { ->find($params->{domain}{id} // $params->{domain_id}); my $prov_domain = $schema->resultset('voip_domains') ->find({domain => $billing_domain->domain}); + + my $profile; + if($params->{profile}{id}) { + my $profile_rs = $c->model('DB')->resultset('voip_subscriber_profiles'); + if($c->user->roles eq "admin") { + } elsif($c->user->roles eq "reseller") { + $profile_rs = $profile_rs->search({ + reseller_id => $c->user->reseller_id, + }); + } + $profile = $profile_rs->find($params->{profile}{id}); + unless($profile) { + $c->log->error("invalid subscriber profile id '".$params->{profile}{id}."' detected"); + return; + } + } $schema->txn_do(sub { my ($uuid_bin, $uuid_string); @@ -187,6 +203,7 @@ sub create_subscriber { domain_id => $prov_domain->id, is_pbx_group => $params->{is_pbx_group} // 0, pbx_group_id => $params->{pbx_group_id}, + profile_id => $profile ? $profile->id : undef, create_timestamp => NGCP::Panel::Utils::DateTime::current_local, }); diff --git a/share/templates/subscriber/master.tt b/share/templates/subscriber/master.tt index 9522e40a94..958719503b 100644 --- a/share/templates/subscriber/master.tt +++ b/share/templates/subscriber/master.tt @@ -90,6 +90,12 @@ [% END -%] +