MT#3971 Implement limitation of subscribers.

Enforce max_subscribers field and allow editing a customer.
agranig/rest
Andreas Granig 12 years ago
parent dce2f45785
commit b9d03df0bd

@ -393,7 +393,19 @@ sub customer_ajax :Chained('customer_list') :PathPart('ajax') :Args(0) {
my ($self, $c) = @_;
my $rs = $c->stash->{customer_rs};
NGCP::Panel::Utils::Datatables::process($c, $rs, $c->stash->{contract_dt_columns});
my $contract_dt_col = NGCP::Panel::Utils::Datatables::set_columns($c, [
{ name => "id", search => 1, title => "#" },
{ name => "external_id", search => 1, title => "External #" },
{ name => "contact.reseller.name", search => 1, title => "Reseller" },
{ name => "contact.email", search => 1, title => "Contact Email" },
{ name => "billing_mappings.product.name", search => 1, title => "Product" },
{ name => "billing_mappings.billing_profile.name", search => 1, title => "Billing Profile" },
{ name => "status", search => 1, title => "Status" },
{ name => "max_subscribers", search => 1, title => "Max Number of Subscribers" },
]);
push @{ $c->stash->{contract_dt_columns} },
{ name => "max_subscribers", search => 1, title => "Max Number of Subscribers" };
NGCP::Panel::Utils::Datatables::process($c, $rs, $contract_dt_col);
$c->detach( $c->view("JSON") );
}
@ -451,7 +463,7 @@ sub customer_create :Chained('customer_list') :PathPart('create') :Args(0) {
my $schema = $c->model('DB');
$schema->txn_do(sub {
$form->params->{contact_id} = $form->params->{contact}{id};
delete $form->params->{contract};
delete $form->params->{contact};
my $bprof_id = $form->params->{billing_profile}{id};
delete $form->params->{billing_profile};
$form->{create_timestamp} = $form->{modify_timestamp} = NGCP::Panel::Utils::DateTime::current_local;
@ -495,6 +507,102 @@ sub customer_create :Chained('customer_list') :PathPart('create') :Args(0) {
$c->stash(form => $form);
}
sub customer_base :Chained('customer_list') :PathPart('') :CaptureArgs(1) {
my ($self, $c, $contract_id) = @_;
unless($contract_id->is_int) {
NGCP::Panel::Utils::Message->error(
c => $c,
error => "customer contract id '$contract_id' is not valid",
desc => "Invalid customer contract id",
);
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/customer'));
}
my $contract_rs = $c->stash->{customer_rs};
$c->stash->{contract} = $contract_rs->find($contract_id);
unless($c->stash->{contract}) {
NGCP::Panel::Utils::Message->error(
c => $c,
error => "customer contract id '$contract_id' not found",
desc => "Customer contract id not found",
);
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/customer'));
}
}
sub customer_edit :Chained('customer_base') :PathPart('edit') :Args(0) {
my ($self, $c) = @_;
my $contract = $c->stash->{contract};
my $posted = ($c->request->method eq 'POST');
my $form;
my $params = { $contract->get_inflated_columns };
$params->{contact}{id} = delete $params->{contact_id};
$params->{product}{id} = $contract->billing_mappings->first->product_id;
$params->{billing_profile}{id} = $contract->billing_mappings->first->billing_profile_id;
$params = $params->merge($c->session->{created_objects});
if($c->config->{features}->{cloudpbx}) {
$form = NGCP::Panel::Form::Contract::ProductSelect->new;
} else {
$form = NGCP::Panel::Form::Contract::Basic->new;
}
$form->process(
posted => $posted,
params => $c->request->params,
item => $params
);
NGCP::Panel::Utils::Navigation::check_form_buttons(
c => $c,
form => $form,
fields => {'contact.create' => $c->uri_for('/contact/create'),
'billing_profile.create' => $c->uri_for('/billing/create')},
back_uri => $c->req->uri,
);
if($posted && $form->validated) {
try {
my $schema = $c->model('DB');
$schema->txn_do(sub {
$form->params->{contact_id} = $form->params->{contact}{id};
delete $form->params->{contact};
my $bprof_id = $form->params->{billing_profile}{id};
delete $form->params->{billing_profile};
$form->{modify_timestamp} = NGCP::Panel::Utils::DateTime::current_local;
my $product_id = $form->params->{product}{id};
delete $form->params->{product};
unless($form->params->{max_subscribers} && length($form->params->{max_subscribers})) {
$form->params->{max_subscribers} = undef;
}
my $old_bprof_id = $contract->billing_mappings->first->billing_profile_id;
say ">>>>>>>>>>> old bprof_id=$old_bprof_id";
$contract->update($form->params);
if($bprof_id != $old_bprof_id) {
$contract->billing_mappings->create({
billing_profile_id => $bprof_id,
product_id => $product_id,
start_date => NGCP::Panel::Utils::DateTime::current_local,
});
}
delete $c->session->{created_objects}->{contact};
delete $c->session->{created_objects}->{billing_profile};
my $contract_id = $contract->id;
$c->flash(messages => [{type => 'success', text => "Customer #$contract_id successfully updated"}]);
});
} catch($e) {
NGCP::Panel::Utils::Message->error(
c => $c,
error => $e,
desc => "Failed to update customer contract.",
);
}
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/customer'));
}
$c->stash(edit_flag => 1);
$c->stash(form => $form);
}
sub reseller_list :Chained('contract_list') :PathPart('reseller') :CaptureArgs(0) {
my ($self, $c) = @_;

@ -51,6 +51,7 @@ sub list_customer :Chained('/') :PathPart('customer') :CaptureArgs(0) {
{ name => "billing_mappings.product.name", search => 1, title => "Product" },
{ name => "billing_mappings.billing_profile.name", search => 1, title => "Billing Profile" },
{ name => "status", search => 1, title => "Status" },
{ name => "max_subscribers", search => 1, title => "Max Number of Subscribers" },
]);
$c->stash(
@ -182,11 +183,31 @@ sub details :Chained('base') :PathPart('details') :Args(0) {
NGCP::Panel::Utils::Sounds::stash_soundset_list(c => $c, contract => $c->stash->{contract});
$c->stash->{contact_hash} = { $c->stash->{contract}->contact->get_inflated_columns };
if(defined $c->stash->{contract}->max_subscribers) {
$c->stash->{subscriber_count} = $c->stash->{contract}->voip_subscribers
->search({ status => { -not_in => ['terminated'] } })
->count;
}
}
sub subscriber_create :Chained('base') :PathPart('subscriber/create') :Args(0) {
my ($self, $c) = @_;
if(defined $c->stash->{contract}->max_subscribers &&
$c->stash->{contract}->voip_subscribers
->search({ status => { -not_in => ['terminated'] } })
->count >= $c->stash->{contract}->max_subscribers) {
NGCP::Panel::Utils::Message->error(
c => $c,
error => "tried to exceed max number of subscribers of " . $c->stash->{contract}->max_subscribers,
desc => "Maximum number of subscribers for this customer reached",
);
NGCP::Panel::Utils::Navigation::back_or($c,
$c->uri_for_action('/customer/details', [$c->stash->{contract}->id])
);
}
my $pbx = 0; my $pbxadmin = 0;
$pbx = 1 if $c->stash->{product}->class eq 'pbxaccount';
my $form;
@ -401,6 +422,21 @@ sub pbx_group_ajax :Chained('base') :PathPart('pbx/group/ajax') :Args(0) {
sub pbx_group_create :Chained('base') :PathPart('pbx/group/create') :Args(0) {
my ($self, $c) = @_;
if(defined $c->stash->{contract}->max_subscribers &&
$c->stash->{contract}->voip_subscribers
->search({ status => { -not_in => ['terminated'] } })
->count >= $c->stash->{contract}->max_subscribers) {
NGCP::Panel::Utils::Message->error(
c => $c,
error => "tried to exceed max number of subscribers of " . $c->stash->{contract}->max_subscribers,
desc => "Maximum number of subscribers for this customer reached",
);
NGCP::Panel::Utils::Navigation::back_or($c,
$c->uri_for_action('/customer/details', [$c->stash->{contract}->id])
);
}
my $posted = ($c->request->method eq 'POST');
my $admin_subscribers = NGCP::Panel::Utils::Subscriber::get_admin_subscribers(
voip_subscribers => $c->stash->{subscribers});

@ -153,7 +153,12 @@
</div>
<div class="accordion-body collapse" id="collapse_subs">
<div class="accordion-inner">
<a class="btn btn-large btn-primary" href="[% c.uri_for_action('/customer/subscriber_create', [ c.req.captures.0 ]) %]"><i class="icon-star"></i> Create Subscriber</a>
[% IF contract.max_subscribers.defined && subscriber_count < contract.max_subscribers -%]
<div class="alert alert-info">[% subscriber_count -%] of maximum [% contract.max_subscribers %] subscribers [% IF c.config.features.cloudpbx %](including PBX groups) [% END %]created</div>
<a class="btn btn-large btn-primary" href="[% c.uri_for_action('/customer/subscriber_create', [ c.req.captures.0 ]) %]"><i class="icon-star"></i> Create Subscriber</a>
[% ELSIF contract.max_subscribers.defined -%]
<div class="alert">Maximum number of [% contract.max_subscribers %] subscribers [% IF c.config.features.cloudpbx %](including PBX groups) [% END %]created</div>
[% END -%]
<div class="ngcp-separator"></div>
<table class="table table-bordered table-striped table-highlight table-hover" id="subscribers_table">
<thead>
@ -206,7 +211,13 @@
</div>
<div class="accordion-body collapse" id="collapse_pbxgroups">
<div class="accordion-inner">
<a class="btn btn-large btn-primary" href="[% c.uri_for_action('/customer/pbx_group_create', [ c.req.captures.0 ]) %]"><i class="icon-star"></i> Create PBX Group</a>
[% IF contract.max_subscribers.defined && subscriber_count < contract.max_subscribers -%]
<div class="alert alert-info">[% subscriber_count -%] of maximum [% contract.max_subscribers %] subscribers [% IF c.config.features.cloudpbx %](including PBX groups) [% END %]created</div>
<a class="btn btn-large btn-primary" href="[% c.uri_for_action('/customer/pbx_group_create', [ c.req.captures.0 ]) %]"><i class="icon-star"></i> Create PBX Group</a>
[% ELSIF contract.max_subscribers.defined -%]
<div class="alert">Maximum number of [% contract.max_subscribers %] subscribers [% IF c.config.features.cloudpbx %](including PBX groups) [% END %]created</div>
[% END -%]
<div class="ngcp-separator"></div>
<table class="table table-bordered table-striped table-highlight table-hover" id="subscribers_table">
<thead>

@ -14,7 +14,7 @@
UNLESS c.user.read_only;
helper.dt_buttons = [
{ name = 'Edit', uri = "/contract/'+full.id+'/edit", class = 'btn-small btn-primary', icon = 'icon-edit' },
{ name = 'Edit', uri = "/contract/customer/'+full.id+'/edit", class = 'btn-small btn-primary', icon = 'icon-edit' },
{ name = 'Terminate', uri = "/contract/'+full.id+'/terminate", class = 'btn-small btn-secondary', icon = 'icon-remove' },
{ name = 'Details', uri = "/customer/'+full.id+'/details", class = 'btn-small btn-tertiary', icon = 'icon-list' },
];

Loading…
Cancel
Save