You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ngcp-panel/lib/NGCP/Panel/Utils/Contract.pm

219 lines
7.3 KiB

package NGCP::Panel::Utils::Contract;
use strict;
use warnings;
use Sipwise::Base;
use DBIx::Class::Exception;
use NGCP::Panel::Utils::DateTime;
sub create_contract_balance {
my %params = @_;
my $c = $params{c};
my $contract = $params{contract};
my $profile = $params{profile};
my ($cash_balance, $cash_balance_interval,
$free_time_balance, $free_time_balance_interval) = (0,0,0,0);
# first, calculate start and end time of current billing profile
# (we assume billing interval of 1 month)
my $stime = NGCP::Panel::Utils::DateTime::current_local->truncate(to => 'month');
my $etime = $stime->clone->add(months => 1)->subtract(seconds => 1);
# calculate free_time/cash ratio
my $free_time = $profile->interval_free_time || 0;
my $free_cash = $profile->interval_free_cash || 0;
if($free_time or $free_cash) {
$etime->add(seconds => 1);
my $ctime = NGCP::Panel::Utils::DateTime::current_local->truncate(to => 'day');
my $ratio = ($etime->epoch - $ctime->epoch) / ($etime->epoch - $stime->epoch);
$cash_balance = sprintf("%.4f", $free_cash * $ratio);
$cash_balance_interval = 0;
$free_time_balance = sprintf("%.0f", $free_time * $ratio);
$free_time_balance_interval = 0;
$etime->subtract(seconds => 1);
}
try {
my $schema = $c->model('DB');
$schema->txn_do(sub {
$schema->resultset('contract_balances')->create({
contract_id => $contract->id,
cash_balance => $cash_balance,
cash_balance_interval => $cash_balance_interval,
free_time_balance => $free_time_balance,
free_time_balance_interval => $free_time_balance_interval,
start => $stime,
end => $etime,
});
});
} catch($e) {
$c->log->error("Creating contract balance failed: " . $e);
$e->rethrow;
}
}
sub recursively_lock_contract {
my %params = @_;
my $c = $params{c};
my $contract = $params{contract};
my $status = $contract->status;
if($status eq 'terminated') {
$contract->autoprov_field_devices->delete_all;
}
# first, change all voip subscribers, in case there are any
for my $subscriber($contract->voip_subscribers->all) {
$subscriber->update({ status => $status });
if($status eq 'terminated') {
$subscriber->provisioning_voip_subscriber->delete
if($subscriber->provisioning_voip_subscriber);
} elsif($status eq 'locked') {
NGCP::Panel::Utils::Subscriber::lock_provisoning_voip_subscriber(
c => $c,
prov_subscriber => $subscriber->provisioning_voip_subscriber,
level => 4,
) if($subscriber->provisioning_voip_subscriber);
} elsif($status eq 'active') {
NGCP::Panel::Utils::Subscriber::lock_provisoning_voip_subscriber(
c => $c,
prov_subscriber => $subscriber->provisioning_voip_subscriber,
level => 0,
) if($subscriber->provisioning_voip_subscriber);
}
}
# then, check all child contracts in case of reseller
my $resellers = $c->model('DB')->resultset('resellers')->search({
contract_id => $contract->id
});
for my $reseller($resellers->all) {
if($status eq 'terminated') {
# remove domains in case of reseller termination
for my $domain($reseller->domain_resellers->all) {
$domain->domain->delete;
$domain->delete;
}
# remove admin logins in case of reseller termination
for my $admin($reseller->admins->all) {
if($admin->id == $c->user->id) {
die "Cannot delete the currently used account";
}
$admin->delete;
}
}
# fetch sub-contracts of this contract
my $customers = $c->model('DB')->resultset('contracts')->search({
'contact.reseller_id' => $reseller->id,
}, {
join => 'contact',
}
);
for my $customer($customers->all) {
$customer->update({ status => $status });
for my $subscriber($customer->voip_subscribers->all) {
$subscriber->update({ status => $status });
if($status eq 'terminated') {
$subscriber->provisioning_voip_subscriber->delete
if($subscriber->provisioning_voip_subscriber);
} elsif($status eq 'locked') {
NGCP::Panel::Utils::Subscriber::lock_provisoning_voip_subscriber(
c => $c,
prov_subscriber => $subscriber->provisioning_voip_subscriber,
level => 4,
) if($subscriber->provisioning_voip_subscriber);
} elsif($status eq 'active') {
NGCP::Panel::Utils::Subscriber::lock_provisoning_voip_subscriber(
c => $c,
prov_subscriber => $subscriber->provisioning_voip_subscriber,
level => 0,
) if($subscriber->provisioning_voip_subscriber);
}
}
}
}
}
sub get_contract_rs {
my %params = @_;
my $c = $params{c};
my $mapping_rs = $c->model('DB')->resultset('billing_mappings');
my $rs = $c->model('DB')->resultset('contracts')
->search({
'me.status' => { '!=' => 'terminated' },
'billing_mappings.id' => {
'=' => $mapping_rs->search({
contract_id => { -ident => 'me.id' },
start_date => [ -or =>
{ '<=' => NGCP::Panel::Utils::DateTime::current_local },
{ -is => undef },
],
end_date => [ -or =>
{ '>=' => NGCP::Panel::Utils::DateTime::current_local },
{ -is => undef },
],
},{
alias => 'bilmap',
rows => 1,
order_by => {-desc => ['bilmap.start_date', 'bilmap.id']},
})->get_column('id')->as_query,
},
},{
'join' => 'billing_mappings',
'+select' => [
'billing_mappings.id',
'billing_mappings.start_date',
'billing_mappings.product_id',
],
'+as' => [
'billing_mapping_id',
'billing_mapping_start_date',
'product_id',
],
alias => 'me',
});
return $rs;
}
1;
=head1 NAME
NGCP::Panel::Utils::Contract
=head1 DESCRIPTION
A temporary helper to manipulate Contract related data
=head1 METHODS
=head2 create_contract_balance
Parameters:
c The controller
contract The contract resultset
profile The billing_profile resultset
Creates a contract balance for the current month, if none exists yet
for this contract.
=head1 AUTHOR
Andreas Granig,
=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: