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.
rate-o-mat/t/rateomat-42-catchup-discard.t

292 lines
11 KiB

use strict;
use warnings;
use File::Basename;
use Cwd;
use lib Cwd::abs_path(File::Basename::dirname(__FILE__));
use Utils::Api qw();
use Utils::Rateomat qw($rateomat_timeout);
use Test::More;
use Storable qw();
### testcase outline:
### onnet calls of a caller with profile packages specifying settings to
### discard the cash balance.
###
### the tests verify, that balance is properly discarded (set to 0 euro)
### for all combinations of interval start modes and carry over modes,
### which also depends on topups performed.
### note: this tests takes longer time to complete
local $ENV{RATEOMAT_WRITE_CDR_RELATION_DATA} = 1;
local $ENV{RATEOMAT_PREPAID_UPDATE_BALANCE} = 1;
$rateomat_timeout = 10;
Utils::Api::set_time(Utils::Api::get_now->subtract(months => 5));
#provider contract needs to be created in the past as well:
my $provider = create_provider();
my $callee = Utils::Api::setup_subscriber($provider,$provider->{subscriber_fees}->[0]->{profile},undef,{ cc => 888, ac => '2<n>', sn => '<t>' });
Utils::Api::set_time();
my $amount = 5;
my $costs = ($provider->{subscriber_fees}->[0]->{fee}->{onpeak_init_rate} *
$provider->{subscriber_fees}->[0]->{fee}->{onpeak_init_interval})/100.0;
my $underrun_costs = ($provider->{subscriber_fees}->[1]->{fee}->{onpeak_init_rate} *
$provider->{subscriber_fees}->[1]->{fee}->{onpeak_init_interval})/100.0;
my $interval_days = 30;
my $timely_days = $interval_days / 3;
#goto SKIP;
foreach my $start_mode ('create','1st') {
foreach my $carry_over_mode ('carry_over','discard','carry_over_timely') {
my $begin = Utils::Api::get_now->subtract(days => (3 * $interval_days + 1));
my $profiles_setup = Utils::Api::setup_package($provider,
[ #initial:
$provider->{subscriber_fees}->[0]->{profile}
],
[ #topup:
],
[ #underrun:
],
balance_interval_start_mode => $start_mode,
balance_interval_value => $interval_days,
balance_interval_unit => 'day',
carry_over_mode => $carry_over_mode,
timely_duration_unit => 'day',
timely_duration_value => $timely_days,
notopup_discard_intervals => 2 * $interval_days,
)->{package};
Utils::Api::set_time($begin);
my $caller_notopup = Utils::Api::setup_subscriber($provider,$profiles_setup,$amount,{ cc => 888, ac => '1<n>', sn => '<t>' });
my $caller_topup = Utils::Api::setup_subscriber($provider,$profiles_setup,$amount,{ cc => 888, ac => '1<n>', sn => '<t>' });
my $caller_timelytopup = Utils::Api::setup_subscriber($provider,$profiles_setup,$amount,{ cc => 888, ac => '1<n>', sn => '<t>' });
$begin->truncate(to => 'month') if '1st' eq $start_mode;
my $within_first_interval = $begin->clone->add(days => ($interval_days / 2));
Utils::Api::set_time($within_first_interval);
Utils::Api::perform_topup($caller_topup->{subscriber},$amount);
my $within_first_timely = $begin->clone->add(days => ($interval_days - $timely_days / 2));
Utils::Api::set_time($within_first_timely);
Utils::Api::perform_topup($caller_timelytopup->{subscriber},$amount);
Utils::Api::set_time();
my $now = Utils::Api::get_now();
my @cdr_ids = map { $_->{id}; } @{ Utils::Rateomat::create_cdrs([
Utils::Rateomat::prepare_cdr($caller_notopup->{subscriber},undef,$caller_notopup->{reseller},
$callee->{subscriber},undef,$callee->{reseller},
'192.168.0.1',$within_first_interval->epoch,1),
Utils::Rateomat::prepare_cdr($caller_notopup->{subscriber},undef,$caller_notopup->{reseller},
$callee->{subscriber},undef,$callee->{reseller},
'192.168.0.1',$now->epoch,1),
Utils::Rateomat::prepare_cdr($caller_topup->{subscriber},undef,$caller_topup->{reseller},
$callee->{subscriber},undef,$callee->{reseller},
'192.168.0.1',$within_first_interval->epoch,1),
Utils::Rateomat::prepare_cdr($caller_topup->{subscriber},undef,$caller_topup->{reseller},
$callee->{subscriber},undef,$callee->{reseller},
'192.168.0.1',$now->epoch,1),
Utils::Rateomat::prepare_cdr($caller_timelytopup->{subscriber},undef,$caller_timelytopup->{reseller},
$callee->{subscriber},undef,$callee->{reseller},
'192.168.0.1',$within_first_interval->epoch,1),
Utils::Rateomat::prepare_cdr($caller_timelytopup->{subscriber},undef,$caller_timelytopup->{reseller},
$callee->{subscriber},undef,$callee->{reseller},
'192.168.0.1',$now->epoch,1),
]) };
if (ok((scalar @cdr_ids) > 0 && Utils::Rateomat::run_rateomat_threads(),'rate-o-mat executed')) {
ok(Utils::Rateomat::check_cdrs('',
map { $_ => { id => $_, rating_status => 'ok', }; } @cdr_ids
),'cdrs were all processed') or die;
my $label = $start_mode . '/' . $carry_over_mode;
$begin->truncate(to => 'day');
my @intervals = map { {
start => Utils::Api::datetime_to_string($begin),
stop => Utils::Api::datetime_to_string($begin->add(days => $interval_days)->clone->subtract(seconds => 1)),
}; } 1..4;
if ('carry_over' eq $carry_over_mode) {
Utils::Api::check_interval_history($label . ' no topup: ',$caller_notopup->{customer}->{id},[
set_cash($intervals[0],$amount - $costs),
set_cash($intervals[1],$amount - $costs),
set_cash($intervals[2],$amount - $costs), #0),
set_cash($intervals[3],0),
]);
#print "FAIL due to bug";
#}
Utils::Api::check_interval_history($label . ' topup: ',$caller_topup->{customer}->{id},[
set_cash($intervals[0],2*$amount - $costs),
set_cash($intervals[1],2*$amount - $costs),
set_cash($intervals[2],2*$amount - $costs),
set_cash($intervals[3],0),
]);
Utils::Api::check_interval_history($label . ' timely topup: ',$caller_timelytopup->{customer}->{id},[
set_cash($intervals[0],2*$amount - $costs),
set_cash($intervals[1],2*$amount - $costs),
set_cash($intervals[2],2*$amount - $costs),
set_cash($intervals[3],0),
]);
} elsif ('discard' eq $carry_over_mode) {
Utils::Api::check_interval_history($label . ' no topup: ',$caller_notopup->{customer}->{id},[
set_cash($intervals[0],$amount - $costs),
set_cash($intervals[1],0),
set_cash($intervals[2],0),
set_cash($intervals[3],0),
]);
Utils::Api::check_interval_history($label . ' topup: ',$caller_topup->{customer}->{id},[
set_cash($intervals[0],2*$amount - $costs),
set_cash($intervals[1],0),
set_cash($intervals[2],0),
set_cash($intervals[3],0),
]);
Utils::Api::check_interval_history($label . ' timely topup: ',$caller_timelytopup->{customer}->{id},[
set_cash($intervals[0],2*$amount - $costs),
set_cash($intervals[1],0),
set_cash($intervals[2],0),
set_cash($intervals[3],0),
]);
} elsif ('carry_over_timely' eq $carry_over_mode) {
Utils::Api::check_interval_history($label . ' no topup: ',$caller_notopup->{customer}->{id},[
set_cash($intervals[0],$amount - $costs),
set_cash($intervals[1],0),
set_cash($intervals[2],0),
set_cash($intervals[3],0),
]);
Utils::Api::check_interval_history($label . ' topup: ',$caller_topup->{customer}->{id},[
set_cash($intervals[0],2*$amount - $costs),
set_cash($intervals[1],0),
set_cash($intervals[2],0),
set_cash($intervals[3],0),
]);
Utils::Api::check_interval_history($label . ' timely topup: ',$caller_timelytopup->{customer}->{id},[
set_cash($intervals[0],2*$amount - $costs),
set_cash($intervals[1],2*$amount - $costs),
set_cash($intervals[2],0),
set_cash($intervals[3],0),
]);
}
}
}
}
#SKIP:
foreach my $carry_over_mode ('carry_over','carry_over_timely') {
my @cash_values;
@cash_values = ( [ cash => $amount - $costs, debit => $costs ], [ cash => $amount - $costs ], [ cash => 0, debit => $underrun_costs ] ) if 'carry_over' eq $carry_over_mode;
@cash_values = ( [ cash => $amount - $costs, debit => $costs ], [ cash => 0, debit => $underrun_costs ], [ cash => 0, debit => $underrun_costs ] ) if 'carry_over_timely' eq $carry_over_mode;
foreach my $start_mode ('topup','topup_interval') {
my $profiles_setup = Utils::Api::setup_package($provider,
[ #initial:
$provider->{subscriber_fees}->[0]->{profile}
],
[ #topup:
],
[ #underrun:
$provider->{subscriber_fees}->[1]->{profile}
],
balance_interval_start_mode => $start_mode,
balance_interval_value => $interval_days,
balance_interval_unit => 'day',
carry_over_mode => $carry_over_mode,
timely_duration_unit => 'day',
timely_duration_value => $timely_days,
notopup_discard_intervals => 2 * $interval_days,
initial_balance => 1,
underrun_lock_threshold => 1,
underrun_profile_threshold => 1,
underrun_lock_level => 4,
)->{package};
my $label = $start_mode . '/' . $carry_over_mode .': ';
my $i = 0;
foreach my $begin (Utils::Api::get_now->subtract(days => ($interval_days / 2)),
Utils::Api::get_now->subtract(days => (1.5*$interval_days)),
Utils::Api::get_now->subtract(days => (2.5*$interval_days))) {
Utils::Api::set_time($begin);
my $caller = Utils::Api::setup_subscriber($provider,$profiles_setup,$amount,{ cc => 888, ac => '1<n>', sn => '<t>' });
is(Utils::Api::get_subscriber_preferences($caller->{subscriber})->{lock},undef,$label.'subscriber is not locked initially');
is(Utils::Rateomat::get_usr_preferences($caller->{subscriber},'prepaid')->[0],undef,$label.'subscriber is not prepaid initially');
Utils::Api::set_time();
my $call_time = Utils::Api::get_now->subtract(minutes => 3);
my @cdr_ids = map { $_->{id}; } @{ Utils::Rateomat::create_cdrs([
Utils::Rateomat::prepare_cdr($caller->{subscriber},undef,$caller->{reseller},
$callee->{subscriber},undef,$callee->{reseller},
'192.168.0.1',$call_time->epoch,1),
]) };
if (ok((scalar @cdr_ids) > 0 && Utils::Rateomat::run_rateomat_threads(),'rate-o-mat executed')) {
ok(Utils::Rateomat::check_cdrs('',
map { $_ => { id => $_, rating_status => 'ok', }; } @cdr_ids
),'cdrs were all processed');
Utils::Api::check_interval_history($label,$caller->{customer}->{id},[
{ start => '~'.Utils::Api::datetime_to_string($begin),
stop => Utils::Api::datetime_to_string(Utils::Api::infinite_future()),
@{$cash_values[$i]} }
]);
if ({@{$cash_values[$i]}}->{cash} == 0) {
is(Utils::Api::get_subscriber_preferences($caller->{subscriber})->{lock},4,$label.'subscriber is locked now');
#not updated any longer:
#is(Utils::Rateomat::get_usr_preferences($caller->{subscriber},'prepaid')->[0]->{value},1,$label.'subscriber is prepaid now');
}
}
$i++;
}
}
}
done_testing();
exit;
sub create_provider {
return Utils::Api::setup_provider('test<n>.com',
[ #rates:
{ #initial:
onpeak_init_rate => 2,
onpeak_init_interval => 60,
onpeak_follow_rate => 1,
onpeak_follow_interval => 30,
offpeak_init_rate => 2,
offpeak_init_interval => 60,
offpeak_follow_rate => 1,
offpeak_follow_interval => 30,
},
{ #underrun prepaid:
prepaid => 1,
onpeak_init_rate => 3,
onpeak_init_interval => 60,
onpeak_follow_rate => 2,
onpeak_follow_interval => 30,
offpeak_init_rate => 3,
offpeak_init_interval => 60,
offpeak_follow_rate => 2,
offpeak_follow_interval => 30,
},
],
[ #billing networks:
]
);
}
sub set_cash {
my ($interval,$cash) = @_;
$interval = Storable::dclone($interval);
$interval->{cash} = $cash;
return $interval;
}