Rework reseller handling.

agranig/1_0_subfix
Andreas Granig 13 years ago
parent 6e7ddeeac3
commit bee006efcd

@ -7,8 +7,8 @@ use DateTime::Format::ISO8601;
BEGIN { extends 'Catalyst::Controller'; }
use NGCP::Panel::Form::BillingProfile_admin;
use NGCP::Panel::Form::BillingProfile_reseller;
use NGCP::Panel::Form::BillingProfile::Admin;
use NGCP::Panel::Form::BillingProfile::Reseller;
use NGCP::Panel::Form::BillingFee;
use NGCP::Panel::Form::BillingZone;
use NGCP::Panel::Form::BillingPeaktimeWeekdays;
@ -111,15 +111,22 @@ sub edit :Chained('base') :PathPart('edit') {
}
sub create :Chained('profile_list') :PathPart('create') :Args(0) {
my ($self, $c) = @_;
my ($self, $c, $no_reseller) = @_;
my $posted = ($c->request->method eq 'POST'),
my $dispatch_to = 'NGCP::Panel::Form::BillingProfile_' . $c->user->auth_realm;
my $form = $dispatch_to->new;
my $posted = ($c->request->method eq 'POST');
my $form;
my $params = {};
if($c->user->is_superuser && $no_reseller) {
$form = NGCP::Panel::Form::BillingProfile::Reseller->new;
} elsif($c->user->is_superuser) {
$form = NGCP::Panel::Form::BillingProfile::Admin->new;
} else {
$form = NGCP::Panel::Form::BillingProfile::Reseller->new;
}
$form->process(
posted => $posted,
params => $c->request->params,
action => $c->uri_for('create'),
item => $params,
);
NGCP::Panel::Utils::Navigation::check_form_buttons(
c => $c,
@ -129,7 +136,9 @@ sub create :Chained('profile_list') :PathPart('create') :Args(0) {
);
if($posted && $form->validated) {
try {
if($c->user->is_superuser) {
if($c->user->is_superuser && $no_reseller) {
$form->values->{reseller_id} = $c->user->reseller_id;
} elsif($c->user->is_superuser) {
$form->values->{reseller_id} = $form->values->{reseller}{id};
} else {
$form->values->{reseller_id} = $c->user->reseller_id;
@ -152,6 +161,13 @@ sub create :Chained('profile_list') :PathPart('create') :Args(0) {
$c->stash(form => $form);
}
sub create_without_reseller :Chained('profile_list') :PathPart('create/noreseller') :Args(0) {
my ($self, $c) = @_;
$self->create($c, 1);
}
sub fees_list :Chained('base') :PathPart('fees') :CaptureArgs(0) {
my ($self, $c) = @_;

@ -40,12 +40,16 @@ sub root :Chained('list_contact') :PathPart('') :Args(0) {
}
sub create :Chained('list_contact') :PathPart('create') :Args(0) {
my ($self, $c) = @_;
my ($self, $c, $no_reseller) = @_;
my $posted = ($c->request->method eq 'POST');
my $form;
my $params = {};
if($c->user->is_superuser) {
if($c->user->is_superuser && $no_reseller) {
$form = NGCP::Panel::Form::Contact::Reseller->new;
$params->{reseller}{id} = $c->user->reseller_id;
# we'll delete this after validation, as we don't need the reseller in this case
} elsif($c->user->is_superuser) {
$form = NGCP::Panel::Form::Contact::Admin->new;
} else {
$form = NGCP::Panel::Form::Contact::Reseller->new;
@ -63,6 +67,9 @@ sub create :Chained('list_contact') :PathPart('create') :Args(0) {
);
if($posted && $form->validated) {
try {
if($c->user->is_superuser && $no_reseller) {
delete $form->values->{reseller};
}
my $contact = $c->stash->{contacts}->create($form->values);
$c->session->{created_objects}->{contact} = { id => $contact->id };
$c->flash(messages => [{type => 'success', text => 'Contact successfully created'}]);
@ -78,6 +85,12 @@ sub create :Chained('list_contact') :PathPart('create') :Args(0) {
$c->stash(form => $form);
}
sub create_without_reseller :Chained('list_contact') :PathPart('create/noreseller') :Args(0) {
my ($self, $c) = @_;
$self->create($c, 1);
}
sub base :Chained('list_contact') :PathPart('') :CaptureArgs(1) {
my ($self, $c, $contact_id) = @_;

@ -21,6 +21,7 @@ sub contract_list :Chained('/') :PathPart('contract') :CaptureArgs(0) {
{ name => "id", search => 1, title => "#" },
{ name => "external_id", search => 1, title => "External #" },
{ name => "contact.reseller.name", search => 1, title => "Reseller" },
{ name => "contact.reseller.name", search => 1, title => "Reseller" },
{ name => "contact.email", search => 1, title => "Contact Email" },
{ name => "billing_mappings.billing_profile.name", search => 1, title => "Billing Profile" },
{ name => "status", search => 1, title => "Status" },
@ -77,7 +78,7 @@ sub root :Chained('contract_list') :PathPart('') :Args(0) {
}
sub create :Chained('contract_list') :PathPart('create') :Args(0) {
my ($self, $c) = @_;
my ($self, $c, $no_reseller) = @_;
my $posted = ($c->request->method eq 'POST');
my $params = {};
@ -89,11 +90,16 @@ sub create :Chained('contract_list') :PathPart('create') :Args(0) {
params => $c->request->params,
item => $params
);
my $suffix = '';
if($c->user->is_superuser && $no_reseller) {
$suffix = '/noreseller';
}
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')},
fields => {'contact.create' => $c->uri_for('/contact/create'.$suffix),
'billing_profile.create' => $c->uri_for('/billing/create'.$suffix)},
back_uri => $c->req->uri,
);
if($posted && $form->validated) {
@ -132,6 +138,11 @@ sub create :Chained('contract_list') :PathPart('create') :Args(0) {
$c->stash(form => $form);
}
sub create_without_reseller :Chained('contract_list') :PathPart('create/noreseller') :Args(0) {
my ($self, $c) = @_;
$self->create($c, 1);
}
sub base :Chained('contract_list') :PathPart('') :CaptureArgs(1) {
my ($self, $c, $contract_id) = @_;
@ -192,7 +203,6 @@ sub edit :Chained('base') :PathPart('edit') :Args(0) {
my $schema = $c->model('DB');
$schema->txn_do(sub {
if($form->values->{billing_profile}{id} != $billing_mapping->billing_profile->id) {
say ">>>>>>>> billing profile changed, update mapping";
$contract->billing_mappings->create({
start_date => DateTime->now(),
billing_profile_id => $form->values->{billing_profile}{id},
@ -287,9 +297,6 @@ sub peering_create :Chained('peering_list') :PathPart('create') :Args(0) {
my $posted = ($c->request->method eq 'POST');
my $params = {};
$params = Hash::Merge->new('RIGHT_PRECEDENT')->merge($params, $c->session->{created_objects});
# TODO: where to store created contact and billing profile?
say ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ";
use Data::Printer; p $params;
my $form = NGCP::Panel::Form::Contract->new;
$form->process(
posted => $posted,
@ -299,8 +306,8 @@ sub peering_create :Chained('peering_list') :PathPart('create') :Args(0) {
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')},
fields => {'contact.create' => $c->uri_for('/contact/create/noreseller'),
'billing_profile.create' => $c->uri_for('/billing/create/noreseller')},
back_uri => $c->req->uri,
);
if($posted && $form->validated) {
@ -358,55 +365,63 @@ sub customer_ajax :Chained('customer_list') :PathPart('ajax') :Args(0) {
my $rs = $base_rs->search({
'product_id' => undef,
}, {
'join' => {
'billing_mappings' => 'product',
},
'join' => {'billing_mappings' => 'product'},
});
$c->forward( "/ajax_process_resultset", [$rs,
["id","contact_id", "external_id", "billing_profile_id", "billing_profile_name","status"],
["external_id", "billing_profile.name", "status"]]);
NGCP::Panel::Utils::Datatables::process($c, $rs, $c->stash->{contract_dt_columns});
$c->detach( $c->view("JSON") );
}
sub customer_create :Chained('customer_list') :PathPart('create') :Args(0) {
my ($self, $c) = @_;
my $item = $c->model('DB')->resultset('billing_mappings')->new_result({});
$item->product(undef);
my $posted = ($c->request->method eq 'POST');
my $params = {};
$params = Hash::Merge->new('RIGHT_PRECEDENT')->merge($params, $c->session->{created_objects});
my $form = NGCP::Panel::Form::Contract->new;
if($form->process(
posted => ($c->request->method eq 'POST'),
$form->process(
posted => $posted,
params => $c->request->params,
item => $item,
)) {
# insert ok, populate contract_balance table
try {
NGCP::Panel::Utils::Contract::create_contract_balance(
c => $c,
profile => $item->billing_profile,
contract => $item->contract,
);
} catch($e) {
# TODO: roll back contract and billing_mappings creation and
# redirect to correct entry point
$c->log->error($e);
$c->flash(messages => [{type => 'error', text => 'Failed to create contract balance!'}]);
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/customer'));
}
}
item => $params
);
NGCP::Panel::Utils::Navigation::check_form_buttons(
c => $c, form => $form,
fields => {'contract.contact.create' => $c->uri_for('/contact/create'),
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($form->validated) {
$c->flash(messages => [{type => 'success', text => 'Contract successfully created!'}]);
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for_action('/customer/details', [$item->contract->id]));
}
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->{contract};
my $bprof_id = $form->params->{billing_profile}{id};
delete $form->params->{billing_profile};
my $contract = $schema->resultset('contracts')->create($form->params);
my $billing_profile = $schema->resultset('billing_profiles')->find($bprof_id);
$contract->billing_mappings->create({
billing_profile_id => $bprof_id,
});
NGCP::Panel::Utils::Contract::create_contract_balance(
c => $c,
profile => $billing_profile,
contract => $contract,
);
$c->session->{created_objects}->{contract} = { id => $contract->id };
delete $c->session->{created_objects}->{contact};
delete $c->session->{created_objects}->{billing_profile};
$c->flash(messages => [{type => 'success', text => 'Contract successfully created'}]);
});
} catch($e) {
$c->log->error("Failed to create contract: $e");
$c->flash(messages => [{type => 'error', text => 'Failed to create contract'}]);
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for_action('/contract/root'));
}
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for_action('/contract/root'));
}
$c->stash(create_flag => 1);
$c->stash(form => $form);

@ -32,6 +32,15 @@ sub auto :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRol
sub list_customer :Chained('/') :PathPart('customer') :CaptureArgs(0) {
my ($self, $c) = @_;
$c->stash->{contract_dt_columns} = 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.billing_profile.name", search => 1, title => "Billing Profile" },
{ name => "status", search => 1, title => "Status" },
]);
$c->stash(
template => 'customer/list.tt'
);

@ -36,7 +36,6 @@ sub index :Path :Args(0) {
$c->stash(template => 'dashboard.tt');
delete $c->session->{redirect_targets};
delete $c->session->{created_objects};
}
=head1 AUTHOR

@ -81,7 +81,7 @@ sub edit :Chained('base') :PathPart('edit') {
);
NGCP::Panel::Utils::Navigation::check_form_buttons(
c => $c, form => $form,
fields => {'contract.create' => $c->uri_for('/contract/peering/create')},
fields => {'contract.create' => $c->uri_for('/contract/peering/create/noreseller')},
back_uri => $c->req->uri,
);
if($posted && $form->validated) {
@ -89,9 +89,9 @@ sub edit :Chained('base') :PathPart('edit') {
$c->stash->{group_result}->update($form->custom_get_values);
$self->_sip_lcr_reload;
delete $c->session->{created_objects}->{contract};
$c->flash(messages => [{type => 'success', text => 'Peering Group successfully changed!'}]);
$c->flash(messages => [{type => 'success', text => 'Peering group successfully updated'}]);
} catch (DBIx::Class::Exception $e) {
$c->flash(messages => [{type => 'error', text => 'Update of peering group failed.'}]);
$c->flash(messages => [{type => 'error', text => 'Failed to update peering group'}]);
$c->log->info("Update failed: " . $e);
};
$c->response->redirect($c->uri_for());
@ -108,9 +108,9 @@ sub delete :Chained('base') :PathPart('delete') {
try {
$c->stash->{group_result}->delete;
$self->_sip_lcr_reload;
$c->flash(messages => [{type => 'success', text => 'Peering Group successfully deleted!'}]);
$c->flash(messages => [{type => 'success', text => 'Peering Group successfully deleted'}]);
} catch (DBIx::Class::Exception $e) {
$c->flash(messages => [{type => 'error', text => 'Delete failed.'}]);
$c->flash(messages => [{type => 'error', text => 'Failed to delete peering group'}]);
$c->log->info("Delete failed: " . $e);
};
$c->response->redirect($c->uri_for());
@ -123,8 +123,6 @@ sub create :Chained('group_list') :PathPart('create') :Args(0) {
my $form = NGCP::Panel::Form::PeeringGroup->new;
my $params = {};
$params = Hash::Merge->new('RIGHT_PRECEDENT')->merge($params, $c->session->{created_objects});
say ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> got new contract:";
use Data::Printer; p $params;
$form->process(
posted => $posted,
params => $c->request->params,
@ -142,9 +140,9 @@ sub create :Chained('group_list') :PathPart('create') :Args(0) {
$formdata );
$self->_sip_lcr_reload;
delete $c->session->{created_objects}->{contract};
$c->flash(messages => [{type => 'success', text => 'Peering group successfully created!'}]);
$c->flash(messages => [{type => 'success', text => 'Peering group successfully created'}]);
} catch (DBIx::Class::Exception $e) {
$c->flash(rules_messages => [{type => 'error', text => 'Creation of peering group failed.'}]);
$c->flash(rules_messages => [{type => 'error', text => 'Failed to create peering group'}]);
$c->log->info("Create failed: " . $e);
};
$c->response->redirect($c->uri_for_action('/peering/root'));
@ -194,9 +192,9 @@ sub servers_create :Chained('servers_list') :PathPart('create') :Args(0) {
try {
$c->stash->{group_result}->voip_peer_hosts->create( $form->fif );
$self->_sip_lcr_reload;
$c->flash(messages => [{type => 'success', text => 'Peering server successfully created!'}]);
$c->flash(messages => [{type => 'success', text => 'Peering server successfully created'}]);
} catch (DBIx::Class::Exception $e) {
$c->flash(messages => [{type => 'error', text => 'Creation of Peering server failed.'}]);
$c->flash(messages => [{type => 'error', text => 'Failed to create peering server'}]);
$c->log->info("Create failed: " . $e);
};
$c->response->redirect($c->stash->{sr_list_uri});
@ -212,7 +210,7 @@ sub servers_base :Chained('servers_list') :PathPart('') :CaptureArgs(1) {
my ($self, $c, $server_id) = @_;
unless($server_id && $server_id->is_integer) {
$c->flash(messages => [{type => 'error', text => 'Invalid peering sever (host) id detected!'}]);
$c->flash(messages => [{type => 'error', text => 'Invalid peering server id'}]);
$c->response->redirect($c->stash->{sr_list_uri});
$c->detach;
return;
@ -220,7 +218,7 @@ sub servers_base :Chained('servers_list') :PathPart('') :CaptureArgs(1) {
my $res = $c->stash->{group_result}->voip_peer_hosts->find($server_id);
unless(defined($res)) {
$c->flash(messages => [{type => 'error', text => 'Peering Server does not exist!'}]);
$c->flash(messages => [{type => 'error', text => 'Peering server does not exist'}]);
$c->response->redirect($c->stash->{sr_list_uri});
$c->detach;
return;
@ -243,9 +241,9 @@ sub servers_edit :Chained('servers_base') :PathPart('edit') :Args(0) {
try {
$c->stash->{server_result}->update($form->fif);
$self->_sip_lcr_reload;
$c->flash(messages => [{type => 'success', text => 'Peering Server successfully changed!'}]);
$c->flash(messages => [{type => 'success', text => 'Peering server successfully updated'}]);
} catch (DBIx::Class::Exception $e) {
$c->flash(messages => [{type => 'error', text => 'Updating of Peering server failed.'}]);
$c->flash(messages => [{type => 'error', text => 'Failed to update peering server'}]);
$c->log->info("Update failed: " . $e);
};
@ -264,9 +262,9 @@ sub servers_delete :Chained('servers_base') :PathPart('delete') :Args(0) {
try {
$c->stash->{server_result}->delete;
$self->_sip_lcr_reload;
$c->flash(messages => [{type => 'success', text => 'Peering Server successfully deleted!'}]);
$c->flash(messages => [{type => 'success', text => 'Peering server successfully deleted'}]);
} catch (DBIx::Class::Exception $e) {
$c->flash(rules_messages => [{type => 'error', text => 'Delete failed.'}]);
$c->flash(rules_messages => [{type => 'error', text => 'Failed to delete peering server'}]);
$c->log->info("Delete failed: " . $e);
};
$c->response->redirect($c->stash->{sr_list_uri});
@ -386,9 +384,9 @@ sub rules_create :Chained('rules_list') :PathPart('create') :Args(0) {
try {
$c->stash->{group_result}->voip_peer_rules->create( $form->fif );
$self->_sip_lcr_reload;
$c->flash(rules_messages => [{type => 'success', text => 'Peering rule successfully created!'}]);
$c->flash(rules_messages => [{type => 'success', text => 'Peering rule successfully created'}]);
} catch (DBIx::Class::Exception $e) {
$c->flash(rules_messages => [{type => 'error', text => 'Create failed.'}]);
$c->flash(rules_messages => [{type => 'error', text => 'Failed to create peering rule'}]);
$c->log->info("Create failed: " . $e);
};
$c->response->redirect($c->stash->{sr_list_uri});
@ -404,7 +402,7 @@ sub rules_base :Chained('rules_list') :PathPart('') :CaptureArgs(1) {
my ($self, $c, $rule_id) = @_;
unless($rule_id && $rule_id->is_integer) {
$c->flash(rules_messages => [{type => 'error', text => 'Invalid peering rule id detected!'}]);
$c->flash(rules_messages => [{type => 'error', text => 'Invalid peering rule id detected'}]);
$c->response->redirect($c->stash->{sr_list_uri});
$c->detach;
return;
@ -412,7 +410,7 @@ sub rules_base :Chained('rules_list') :PathPart('') :CaptureArgs(1) {
my $res = $c->stash->{group_result}->voip_peer_rules->find($rule_id);
unless(defined($res)) {
$c->flash(rules_messages => [{type => 'error', text => 'Peering Rule does not exist!'}]);
$c->flash(rules_messages => [{type => 'error', text => 'Peering Rule does not exist'}]);
$c->response->redirect($c->stash->{sr_list_uri});
$c->detach;
return;
@ -435,9 +433,9 @@ sub rules_edit :Chained('rules_base') :PathPart('edit') :Args(0) {
try {
$c->stash->{rule_result}->update($form->fif);
$self->_sip_lcr_reload;
$c->flash(rules_messages => [{type => 'success', text => 'Peering Rule successfully changed!'}]);
$c->flash(rules_messages => [{type => 'success', text => 'Peering rule successfully changed'}]);
} catch (DBIx::Class::Exception $e) {
$c->flash(rules_messages => [{type => 'error', text => 'Edit failed.'}]);
$c->flash(rules_messages => [{type => 'error', text => 'Failed to update peering rule'}]);
$c->log->info("Update failed: " . $e);
};
$c->response->redirect($c->stash->{sr_list_uri});
@ -455,9 +453,9 @@ sub rules_delete :Chained('rules_base') :PathPart('delete') :Args(0) {
try {
$c->stash->{rule_result}->delete;
$self->_sip_lcr_reload;
$c->flash(rules_messages => [{type => 'success', text => 'Peering Rule successfully deleted!'}]);
$c->flash(rules_messages => [{type => 'success', text => 'Peering rule successfully deleted'}]);
} catch (DBIx::Class::Exception $e) {
$c->flash(rules_messages => [{type => 'error', text => 'Delete failed.'}]);
$c->flash(rules_messages => [{type => 'error', text => 'Failed to delete peering rule'}]);
$c->log->info("Delete failed: " . $e);
};
$c->response->redirect($c->stash->{sr_list_uri});

@ -30,6 +30,15 @@ sub list_reseller :Chained('/') :PathPart('reseller') :CaptureArgs(0) {
{ name => "name", search => 1, title => "Name" },
{ name => "status", search => 1, title => "Status" },
]);
# we need this in ajax_contracts also
$c->stash->{contract_dt_columns} = NGCP::Panel::Utils::Datatables::set_columns($c, [
{ name => "id", search => 1, title => "#" },
{ name => "external_id", search => 1, title => "External #" },
{ name => "contact.email", search => 1, title => "Contact Email" },
{ name => "billing_mappings.billing_profile.name", search => 1, title => "Billing Profile" },
{ name => "status", search => 1, title => "Status" },
]);
}
sub root :Chained('list_reseller') :PathPart('') :Args(0) {
@ -63,7 +72,7 @@ sub create :Chained('list_reseller') :PathPart('create') :Args(0) {
NGCP::Panel::Utils::Navigation::check_form_buttons(
c => $c,
form => $form,
fields => [qw/contract.create/],
fields => {'contract.create' => $c->uri_for('/contract/create/noreseller') },
back_uri => $c->req->uri,
);
@ -71,13 +80,13 @@ sub create :Chained('list_reseller') :PathPart('create') :Args(0) {
try {
$form->params->{contract_id} = delete $form->params->{contract}->{id};
delete $form->params->{contract};
$c->model('DB')->resultset('resellers')->create($form->params);
my $reseller = $c->model('DB')->resultset('resellers')->create($form->params);
delete $c->session->{created_objects}->{contract};
$c->flash(messages => [{type => 'success', text => 'Reseller successfully created.'}]);
$c->flash(messages => [{type => 'success', text => 'Reseller successfully created'}]);
} catch($e) {
$c->log->error($e);
$c->flash(messages => [{type => 'error', text => 'Creating reseller failed.'}]);
$c->flash(messages => [{type => 'error', text => 'Failed to create reseller'}]);
}
$c->response->redirect($c->uri_for());
return;
@ -91,40 +100,56 @@ sub create :Chained('list_reseller') :PathPart('create') :Args(0) {
sub base :Chained('list_reseller') :PathPart('') :CaptureArgs(1) {
my ($self, $c, $reseller_id) = @_;
$c->detach('/denied_page')
if($c->user->read_only);
unless($reseller_id && $reseller_id =~ /^\d+$/) {
$c->flash(messages => [{type => 'error', text => 'Invalid reseller id detected.'}]);
$c->flash(messages => [{type => 'error', text => 'Invalid reseller id detected'}]);
$c->response->redirect($c->uri_for());
return;
}
$c->stash->{contact_dt_columns} = NGCP::Panel::Utils::Datatables::set_columns($c, [
{ name => "id", search => 1, title => "#" },
{ name => "firstname", search => 1, title => "First Name" },
{ name => "lastname", search => 1, title => "Last Name" },
{ name => "company", search => 1, title => "Company" },
{ name => "email", search => 1, title => "Email" },
]);
$c->stash->{reseller_dt_columns} = NGCP::Panel::Utils::Datatables::set_columns($c, [
{ name => "id", search => 1, title => "#" },
{ name => "name", search => 1, title => "Name" },
{ name => "status", search => 1, title => "Status" },
]);
$c->stash->{admin_dt_columns} = NGCP::Panel::Utils::Datatables::set_columns($c, [
{ name => "id", search => 1, title => "#" },
{ name => "login", search => 1, title => "Name" },
{ name => "is_master", title => "Master" },
{ name => "is_active", title => "Active" },
{ name => "read_only", title => "Read-Only" },
{ name => "show_passwords", title => "Show Passwords" },
{ name => "call_data", title => "Show CDRs" },
]);
$c->stash->{customer_dt_columns} = NGCP::Panel::Utils::Datatables::set_columns($c, [
{ name => "id", search => 1, title => "#" },
{ name => "external_id", search => 1, title => "External #" },
{ name => "contact.email", search => 1, title => "Contact Email" },
{ name => "status", search => 1, title => "Status" },
]);
$c->stash(reseller => $c->stash->{resellers}->search_rs({ id => $reseller_id }));
}
sub reseller_contacts :Chained('base') :PathPart('contacts') :Args(0) {
my ($self, $c) = @_;
$c->forward(
'/ajax_process_resultset', [
$c->stash->{reseller}->first->contract->search_related_rs('contact'),
[qw(id firstname lastname email create_timestamp)],
[ "firstname", "lastname", "email" ]
]
);
use Data::Printer;
p $c->stash->{contact_dt_columns};
my $rs = $c->stash->{reseller}->first->contract->search_related_rs('contact');
NGCP::Panel::Utils::Datatables::process($c, $rs, $c->stash->{contact_dt_columns});
$c->detach($c->view('JSON'));
return;
}
sub reseller_contracts :Chained('base') :PathPart('contracts') :Args(0) {
my ($self, $c) = @_;
$c->forward(
'/ajax_process_resultset', [
$c->stash->{reseller}->first->search_related_rs('contract'),
[qw(id contact_id)],
[ "contact_id" ]
]
);
my $rs = $c->stash->{reseller}->first->search_related_rs('contract');
NGCP::Panel::Utils::Datatables::process($c, $rs, $c->stash->{contract_dt_columns});
$c->detach($c->view('JSON'));
return;
}
@ -132,42 +157,28 @@ sub reseller_contracts :Chained('base') :PathPart('contracts') :Args(0) {
sub reseller_single :Chained('base') :PathPart('single') :Args(0) {
my ($self, $c) = @_;
$c->forward(
'/ajax_process_resultset', [
$c->stash->{reseller},
[qw(id contract_id name status)],
[ "contract_id", "name", "status" ]
]
);
NGCP::Panel::Utils::Datatables::process($c, $c->stash->{reseller}, $c->stash->{reseller_dt_columns});
$c->detach($c->view('JSON'));
return;
}
sub reseller_admin :Chained('base') :PathPart('admins') :Args(0) {
my ($self, $c) = @_;
$c->forward(
'/ajax_process_resultset', [
$c->stash->{reseller}->first->search_related_rs('admins'),
[qw(id reseller_id login)],
[ "reseller_id", "login" ]
]
);
my $rs = $c->stash->{reseller}->first->search_related_rs('admins');
NGCP::Panel::Utils::Datatables::process($c, $rs, $c->stash->{admin_dt_columns});
$c->detach($c->view('JSON'));
return;
}
sub reseller_customers :Chained('base') :PathPart('customers') :Args(0)
{
sub reseller_customers :Chained('base') :PathPart('customers') :Args(0) {
my ($self, $c) = @_;
$c->forward(
'/ajax_process_resultset', [
$c->stash->{reseller}->first->search_related_rs('contracts'),
# TODO: also external_id (same in Customer list)
[qw(id contact_id status)],
[ "contact_id", "status" ]
]
);
my $rs = $c->model('DB')->resultset('contracts')->search({
'contact.reseller_id' => $c->stash->{reseller}->first->id
}, {
join => 'contact'
});
NGCP::Panel::Utils::Datatables::process($c, $rs, $c->stash->{customer_dt_columns});
$c->detach($c->view('JSON'));
return;
}
@ -175,8 +186,15 @@ sub reseller_customers :Chained('base') :PathPart('customers') :Args(0)
sub edit :Chained('base') :PathPart('edit') :Args(0) {
my ($self, $c) = @_;
$c->detach('/denied_page')
if($c->user->read_only);
my $posted = $c->request->method eq 'POST';
my $form = NGCP::Panel::Form::Reseller->new;
# we need this in the ajax call to not filter it as used contract
$c->session->{edit_contract_id} = $c->stash->{reseller}->first->contract_id;
my $params = { $c->stash->{reseller}->first->get_inflated_columns };
$params->{contract}{id} = delete $params->{contract_id};
$params = Hash::Merge->new('RIGHT_PRECEDENT')->merge($params, $c->session->{created_objects});
@ -196,10 +214,11 @@ sub edit :Chained('base') :PathPart('edit') :Args(0) {
delete $form->params->{contract};
$c->stash->{reseller}->first->update($form->params);
delete $c->session->{created_objects}->{contract};
$c->flash(messages => [{type => 'success', text => 'Reseller successfully changed.'}]);
delete $c->session->{edit_contract_id};
$c->flash(messages => [{type => 'success', text => 'Reseller successfully updated'}]);
} catch($e) {
$c->log->error($e);
$c->flash(messages => [{type => 'error', text => 'Updating reseller failed.'}]);
$c->flash(messages => [{type => 'error', text => 'Failed to update reseller'}]);
}
$c->response->redirect($c->uri_for());
}
@ -208,20 +227,21 @@ sub edit :Chained('base') :PathPart('edit') :Args(0) {
$c->stash(form => $form);
$c->stash(edit_flag => 1);
$c->session(contract_id => $c->stash->{reseller}->first->get_column('contract_id'));
return;
}
sub delete :Chained('base') :PathPart('delete') :Args(0) {
my ($self, $c) = @_;
$c->detach('/denied_page')
if($c->user->read_only);
try {
$c->stash->{reseller}->first->delete;
$c->flash(messages => [{type => 'success', text => 'Reseller successfully deleted.'}]);
$c->flash(messages => [{type => 'success', text => 'Reseller successfully deleted'}]);
} catch($e) {
$c->log->error($e);
$c->flash(messages => [{type => 'error', text => 'Deleting reseller failed.'}]);
$c->flash(messages => [{type => 'error', text => 'Failed to delete reseller'}]);
}
$c->response->redirect($c->uri_for());
}
@ -234,27 +254,18 @@ sub details :Chained('base') :PathPart('details') :Args(0) {
sub ajax_contract :Chained('list_reseller') :PathPart('ajax_contract') :Args(0) {
my ($self, $c) = @_;
my $contract_id = $c->session->{contract_id};
my $edit_contract_id = $c->session->{edit_contract_id};
my @used_contracts = map {
$_->get_column('contract_id') unless(
$contract_id &&
$contract_id == $_->get_column('contract_id')
)
$_->get_column('contract_id')
unless($edit_contract_id && $edit_contract_id == $_->get_column('contract_id'))
} $c->stash->{resellers}->all;
my $free_contracts = $c->model('DB')
->resultset('contracts')
->search_rs({
id => { 'not in' => \@used_contracts }
'me.id' => { 'not in' => \@used_contracts }
});
$c->forward("/ajax_process_resultset", [
$free_contracts,
["id", "contact_id", "external_id", "status"],
["contact_id", "external_id", "status"]
]);
NGCP::Panel::Utils::Datatables::process($c, $free_contracts, $c->stash->{contract_dt_columns});
$c->detach( $c->view("JSON") );
}
@ -323,9 +334,9 @@ sub create_defaults :Path('create_defaults') :Args(0) {
});
} catch($e) {
$c->log->error($e);
$c->flash(messages => [{type => 'error', text => 'Creating reseller failed.'}]);
$c->flash(messages => [{type => 'error', text => 'Failed to create reseller'}]);
};
$c->flash(messages => [{type => 'success', text => "Reseller successfully created with login <b>".$defaults{admins}->{login}."</b> and password <b>".$defaults{admins}->{md5pass}."</b>, please review your settings below!" }]);
$c->flash(messages => [{type => 'success', text => "Reseller successfully created with login <b>".$defaults{admins}->{login}."</b> and password <b>".$defaults{admins}->{md5pass}."</b>, please review your settings below" }]);
$c->res->redirect(sprintf('/reseller/%d/details', $r{resellers}->id), HTTP_SEE_OTHER);
$c->detach;
return;

@ -61,6 +61,9 @@ sub auto :Private {
}
$c->stash(topmenu => $topmenu_templates);
$c->session->{created_objects} = {} unless(defined $c->session->{created_objects});
return 1;
}

@ -10,8 +10,8 @@ has_field 'id' => (
required => 1,
template => 'share/templates/helpers/datatables_field.tt',
ajax_src => '/contact/ajax',
table_titles => ['#', 'First Name', 'Last Name', 'Email'],
table_fields => ['id', 'firstname', 'lastname', 'email'],
table_titles => ['#', 'Reseller', 'First Name', 'Last Name', 'Email'],
table_fields => ['id', 'reseller_name', 'firstname', 'lastname', 'email'],
);
has_field 'create' => (

@ -10,8 +10,8 @@ has_field 'id' => (
required => 1,
template => 'share/templates/helpers/datatables_field.tt',
ajax_src => '/reseller/ajax_contract',
table_titles => ['#', 'Contact #', 'External #', 'Status'],
table_fields => ['id', 'contact_id', 'external_id', 'status'],
table_titles => ['#', 'Contact Email', 'External #', 'Status'],
table_fields => ['id', 'contact_email', 'external_id', 'status'],
);
has_field 'create' => (

@ -1,7 +1,7 @@
package NGCP::Panel::Form::BillingProfile_admin;
package NGCP::Panel::Form::BillingProfile::Admin;
use HTML::FormHandler::Moose;
extends 'NGCP::Panel::Form::BillingProfile_reseller';
extends 'NGCP::Panel::Form::BillingProfile::Reseller';
has_field 'reseller' => (
type => '+NGCP::Panel::Field::Reseller',

@ -1,4 +1,4 @@
package NGCP::Panel::Form::BillingProfile_reseller;
package NGCP::Panel::Form::BillingProfile::Reseller;
use HTML::FormHandler::Moose;
extends 'HTML::FormHandler';

@ -3,8 +3,7 @@
helper.name = 'Customers';
helper.data = contracts;
helper.messages = messages;
helper.column_titles = [ '#', 'Contact #', 'Billing Profile', 'Status' ];
helper.column_fields = [ 'id', 'contact_id', 'billing_profile_name', 'status' ];
helper.dt_columns = contract_dt_columns;
helper.close_target = close_target;
helper.create_flag = create_flag;
@ -12,15 +11,21 @@
helper.form_object = form;
helper.ajax_uri = c.uri_for('/contract/customer/ajax');
helper.dt_buttons = [
{ name = 'Edit', uri = "/contract/'+full[\"id\"]+'/edit", class = 'btn-small btn-primary', icon = 'icon-edit' },
{ name = 'Delete', uri = "/contract/'+full[\"id\"]+'/delete", class = 'btn-small btn-secondary', icon = 'icon-trash' },
{ name = 'Details', uri = "/customer/'+full[\"id\"]+'/details", class = 'btn-small btn-tertiary', icon = 'icon-list' },
];
helper.top_buttons = [
{ name = 'Create Customer', uri = c.uri_for_action('/contract/customer_create'), icon = 'icon-star' },
];
UNLESS c.user.read_only;
helper.dt_buttons = [
{ name = 'Edit', uri = "/contract/'+full.id+'/edit", class = 'btn-small btn-primary', icon = 'icon-edit' },
{ name = 'Delete', uri = "/contract/'+full.id+'/delete", class = 'btn-small btn-secondary', icon = 'icon-trash' },
{ name = 'Details', uri = "/customer/'+full.id+'/details", class = 'btn-small btn-tertiary', icon = 'icon-list' },
];
helper.top_buttons = [
{ name = 'Create Customer', uri = c.uri_for_action('/contract/customer_create'), icon = 'icon-star' },
];
ELSE;
helper.dt_buttons = [
{ name = 'Details', uri = "/customer/'+full.id+'/details", class = 'btn-small btn-tertiary', icon = 'icon-list' },
];
END;
PROCESS 'helpers/datatables.tt';
-%]
[% # vim: set tabstop=4 syntax=html expandtab: -%]

@ -15,48 +15,48 @@
<div class="accordion" id="reseller_details">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#reseller_details" href="#collapse_contact">Contact</a>
<a class="accordion-toggle" data-toggle="collapse" data-parent="#reseller_details" href="#collapse_reseller">Reseller Base Information</a>
</div>
<div class="accordion-body collapse" id="collapse_contact">
<div class="accordion-body collapse" id="collapse_reseller">
<div class="accordion-inner">
[%
helper.name = 'Contact';
helper.name = 'Reseller';
helper.messages = messages;
helper.column_titles = [ '#', 'First name', 'Last name', 'Email address', 'created' ];
helper.column_fields = [ 'id', 'firstname', 'lastname', 'email', 'create_timestamp' ];
helper.dt_columns = reseller_dt_columns;
helper.paginate = 'false';
helper.filter = 'false';
helper.close_target = c.uri_for('');
helper.close_target = close_target;
helper.create_flag = create_flag;
helper.edit_flag = edit_flag;
helper.form_object = form;
helper.ajax_uri = c.uri_for_action('/reseller/reseller_contacts', c.req.captures );
helper.base_uri = c.uri_for_action('/contact/root');
helper.ajax_uri = c.uri_for_action('/reseller/reseller_single', c.req.captures );
helper.base_uri = c.uri_for_action('/reseller/root');
PROCESS 'helpers/datatables.tt';
-%]
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#reseller_details" href="#collapse_contract">Contract</a>
<a class="accordion-toggle" data-toggle="collapse" data-parent="#reseller_details" href="#collapse_contract">Reseller Contract</a>
</div>
<div class="accordion-body collapse" id="collapse_contract">
<div class="accordion-inner">
[%
helper.name = 'Contract';
helper.messages = messages;
helper.column_titles = [ '#', 'Contact #'];
helper.column_fields = [ 'id', 'contact_id'];
helper.paginate = 'false';
helper.filter = 'false';
helper.dt_columns = contract_dt_columns;
helper.close_target = close_target;
helper.create_flag = create_flag;
helper.edit_flag = edit_flag;
helper.form_object = form;
helper.paginate = 'false';
helper.filter = 'false';
helper.ajax_uri = c.uri_for_action('/reseller/reseller_contracts', c.req.captures );
helper.base_uri = c.uri_for_action('/contract/root');
@ -65,44 +65,42 @@
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#reseller_details" href="#collapse_reseller">Reseller</a>
<a class="accordion-toggle" data-toggle="collapse" data-parent="#reseller_details" href="#collapse_contact">Reseller Contact</a>
</div>
<div class="accordion-body collapse" id="collapse_reseller">
<div class="accordion-body collapse" id="collapse_contact">
<div class="accordion-inner">
[%
helper.name = 'Reseller';
helper.name = 'Contact';
helper.messages = messages;
helper.column_titles = [ '#', 'Contract #', 'Name', 'Status' ];
helper.column_fields = [ 'id', 'contract_id', 'name', 'status' ];
helper.paginate = 'false';
helper.filter = 'false';
helper.close_target = close_target;
helper.dt_columns = contact_dt_columns;
helper.close_target = c.uri_for('');
helper.create_flag = create_flag;
helper.edit_flag = edit_flag;
helper.form_object = form;
helper.ajax_uri = c.uri_for_action('/reseller/reseller_single', c.req.captures );
helper.base_uri = c.uri_for_action('/reseller/root');
helper.paginate = 'false';
helper.filter = 'false';
helper.ajax_uri = c.uri_for_action('/reseller/reseller_contacts', c.req.captures );
helper.base_uri = c.uri_for_action('/contact/root');
PROCESS 'helpers/datatables.tt';
-%]
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#reseller_details" href="#collapse_admin">Administrator</a>
<a class="accordion-toggle" data-toggle="collapse" data-parent="#reseller_details" href="#collapse_admin">Administrator Logins</a>
</div>
<div class="accordion-body collapse" id="collapse_admin">
<div class="accordion-inner">
[%
helper.name = 'Administrator';
helper.messages = messages;
helper.column_titles = [ '#', 'Reseller #', 'Login' ];
helper.column_fields = [ 'id', 'reseller_id', 'login' ];
helper.paginate = 'false';
helper.filter = 'false';
helper.dt_columns = admin_dt_columns;
helper.close_target = close_target;
helper.create_flag = create_flag;
helper.edit_flag = edit_flag;
@ -124,8 +122,7 @@
[%
helper.name = 'Customer';
helper.messages = messages;
helper.column_titles = [ '#', 'Contact #', 'Status' ];
helper.column_fields = [ 'id', 'contact_id', 'status' ];
helper.dt_columns = customer_dt_columns;
helper.paginate = 'true';
helper.filter = 'true';
helper.close_target = close_target;
@ -134,11 +131,17 @@
helper.form_object = form;
helper.ajax_uri = c.uri_for_action('/reseller/reseller_customers', c.req.captures );
helper.dt_buttons = [
{ name = 'Edit', uri = "/contract/'+full[\"id\"]+'/edit", class = 'btn-small btn-primary', icon = 'icon-edit' },
{ name = 'Delete', uri = "/contract/'+full[\"id\"]+'/delete", class = 'btn-small btn-secondary', icon = 'icon-trash' },
{ name = 'Details', uri = "/customer/'+full[\"id\"]+'/details", class = 'btn-small btn-tertiary', icon = 'icon-list' },
];
UNLESS c.user.read_only;
helper.dt_buttons = [
{ name = 'Edit', uri = "/contract/'+full.id+'/edit", class = 'btn-small btn-primary', icon = 'icon-edit' },
{ name = 'Delete', uri = "/contract/'+full.id+'/delete", class = 'btn-small btn-secondary', icon = 'icon-trash' },
{ name = 'Details', uri = "/customer/'+full.id+'/details", class = 'btn-small btn-tertiary', icon = 'icon-list' },
];
ELSE;
helper.dt_buttons = [
{ name = 'Details', uri = "/customer/'+full.id+'/details", class = 'btn-small btn-tertiary', icon = 'icon-list' },
];
END;
PROCESS 'helpers/datatables.tt';
-%]
@ -146,3 +149,4 @@
</div>
</div>
</div>
[% # vim: set tabstop=4 syntax=html expandtab: -%]

Loading…
Cancel
Save