Revize cd149dd5
Přidáno uživatelem Ondřej Fibich před téměř 7 roky(ů)
application/controllers/members.php | ||
---|---|---|
}
|
||
|
||
// finds date of expiration of member fee
|
||
$expiration_date = '';
|
||
$expiration_info = '';
|
||
|
||
if (Settings::get('finance_enabled') &&
|
||
isset($account) && !$is_applicant && !$is_former)
|
||
{
|
||
$expiration_date = self::get_expiration_date($account);
|
||
$expiration_info = $this->services->injectMemberExpirationCalc()
|
||
->get_expiration_info($account);
|
||
}
|
||
|
||
// finds total traffic of member
|
||
... | ... | |
$view->content->contacts = $contacts;
|
||
$view->content->contact_types = $contact_types;
|
||
$view->content->variable_symbols = (isset($variable_symbols)) ? $variable_symbols : NULL;
|
||
$view->content->expiration_date = $expiration_date;
|
||
$view->content->expiration_info = $expiration_info;
|
||
$view->content->entrance_fee_paid = (isset($entrance_fee_paid)) ? $entrance_fee_paid : NULL;
|
||
$view->content->entrance_fee_left = (isset($entrance_fee_left)) ? $entrance_fee_left : NULL;
|
||
$view->content->account = (isset($account)) ? $account : NULL;
|
||
... | ... | |
$view->render(TRUE);
|
||
} // end of show function
|
||
|
||
|
||
|
||
/**
|
||
* Gets expiration date of member's payments.
|
||
*
|
||
* @author Michal Kliment, Ondrej Fibich
|
||
* @param object $account
|
||
* @return string
|
||
*/
|
||
public static function get_expiration_date($account)
|
||
{
|
||
// member's actual balance
|
||
$balance = $account->balance;
|
||
|
||
$transfer_model = new Transfer_Model();
|
||
|
||
$close_date = date_parse(
|
||
date::get_closses_deduct_date_to(
|
||
$transfer_model->get_last_transfer_datetime_of_account($account->id)
|
||
)
|
||
);
|
||
|
||
// date
|
||
$day = $close_date['day'];
|
||
$month = $close_date['month'];
|
||
$year = $close_date['year'];
|
||
|
||
// balance is in positive, we will go to the future
|
||
if ($balance > 0)
|
||
{
|
||
$sign = 1;
|
||
}
|
||
// balance is in negative, we will go to the past
|
||
else
|
||
{
|
||
$sign = -1;
|
||
}
|
||
|
||
// ttl = time to live - it is count how many ending conditions
|
||
// will have to happen to end cycle
|
||
// negative balance needs one extra more
|
||
$ttl = ($balance < 0) ? 2 : 1;
|
||
|
||
// negative balance will drawn by red color, else balance will drawn by green color
|
||
$color = ($balance < 0) ? 'red' : 'green';
|
||
|
||
$payments = array();
|
||
|
||
// finds entrance date of member
|
||
$entrance_date_str = date::get_closses_deduct_date_to($account->member->entrance_date);
|
||
$entrance_date = date_parse($entrance_date_str);
|
||
|
||
// finds debt payment rate of entrance fee
|
||
$debt_payment_rate = ($account->member->debt_payment_rate > 0)
|
||
? $account->member->debt_payment_rate : $account->member->entrance_fee;
|
||
|
||
// finds all debt payments of entrance fee
|
||
self::find_debt_payments(
|
||
$payments, $entrance_date['month'], $entrance_date['year'],
|
||
$account->member->entrance_fee, $debt_payment_rate
|
||
);
|
||
|
||
// finds all member's devices with debt payments
|
||
$devices = ORM::factory('device')->get_member_devices_with_debt_payments($account->member_id);
|
||
|
||
foreach ($devices as $device)
|
||
{
|
||
// finds buy date of this device
|
||
$buy_date = date_parse(date::get_closses_deduct_date_to($device->buy_date));
|
||
|
||
// finds all debt payments of this device
|
||
self::find_debt_payments(
|
||
$payments, $buy_date['month'], $buy_date['year'],
|
||
$device->price, $device->payment_rate
|
||
);
|
||
}
|
||
|
||
$fee_model = new Fee_Model();
|
||
|
||
// protection from unending loop
|
||
$too_long = FALSE;
|
||
|
||
// finds min and max date = due to prevent before unending loop
|
||
$min_fee_date = $fee_model->get_min_fromdate_fee_by_type ('regular member fee');
|
||
$max_fee_date = $fee_model->get_max_todate_fee_by_type ('regular member fee');
|
||
|
||
while (true)
|
||
{
|
||
$date = date::create(date::get_deduct_day_to($month, $year), $month, $year);
|
||
|
||
// date is bigger/smaller than max/min fee date, ends it (prevent before unending loop)
|
||
if (($sign == 1 && $date > $max_fee_date) || ($sign == -1 && $date < $min_fee_date))
|
||
break;
|
||
|
||
// finds regular member fee for this month
|
||
$fee = $fee_model->get_regular_member_fee_by_member_date($account->member_id, $date);
|
||
|
||
// if exist payment for this month, adds it to the fee
|
||
if (isset($payments[$year][$month]))
|
||
$fee += $payments[$year][$month];
|
||
|
||
// attributed / deduct fee to / from balance
|
||
$balance -= $sign * $fee;
|
||
|
||
if ($sign == -1 && $balance == 0)
|
||
$ttl--;
|
||
|
||
if ($balance * $sign < 0)
|
||
$ttl--;
|
||
|
||
if ($ttl == 0)
|
||
break;
|
||
|
||
$month += $sign;
|
||
|
||
if ($month == 0 OR $month == 13)
|
||
{
|
||
$month = ($month == 13) ? 1 : 12;
|
||
$year += $sign;
|
||
}
|
||
|
||
// if we are 5 years in future, there is no point of counting more
|
||
if (date('Y') + 10 < $year)
|
||
{
|
||
$too_long = TRUE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
$month--;
|
||
if ($month == 0)
|
||
{
|
||
$month = 12;
|
||
$year--;
|
||
}
|
||
|
||
$date = date::create(date::days_of_month($month), $month, $year);
|
||
|
||
if (strtotime($date) < strtotime($entrance_date_str))
|
||
$date = $entrance_date_str;
|
||
|
||
return '<span style="color: '.$color.'">'
|
||
. ($too_long ? '> ' : '')
|
||
. $date. '</span>';
|
||
}
|
||
|
||
/**
|
||
* It stores debt payments into double-dimensional array (indexes year, month)
|
||
*
|
||
* @author Michal Kliment
|
||
* @param array $payments
|
||
* @param int $month
|
||
* @param int $year
|
||
* @param float $payment_left
|
||
* @param float $payment_rate
|
||
*/
|
||
protected static function find_debt_payments(
|
||
&$payments, $month, $year, $payment_left, $payment_rate)
|
||
{
|
||
while ($payment_left > 0)
|
||
{
|
||
if ($payment_left > $payment_rate)
|
||
$payment = $payment_rate;
|
||
else
|
||
$payment = $payment_left;
|
||
|
||
if (isset($payments[$year][$month]))
|
||
$payments[$year][$month] += $payment;
|
||
else
|
||
$payments[$year][$month] = $payment;
|
||
|
||
$month++;
|
||
if ($month > 12)
|
||
{
|
||
$year++;
|
||
$month = 1;
|
||
}
|
||
$payment_left -= $payment;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Function adds new member to database.
|
||
* Creates user of type member assigned to this member.
|
application/controllers/transfers.php | ||
---|---|---|
if ($account->member->type != Member_Model::TYPE_APPLICANT &&
|
||
$account->member->type != Member_Model::TYPE_FORMER)
|
||
{
|
||
$view->content->expiration_date = Members_Controller::get_expiration_date($account);
|
||
$view->content->expiration_info = $this->services
|
||
->injectMemberExpirationCalc()
|
||
->get_expiration_info($account);
|
||
}
|
||
|
||
$view->content->transfers_grid = $transfers_grid;
|
application/libraries/MY_Controller.php | ||
---|---|---|
}
|
||
catch (InvalidArgumentException $iaex)
|
||
{
|
||
self::error(WRITABLE, server::base_dir() . 'upload');
|
||
self::error(WRITABLE, server::base_dir() . '/upload');
|
||
}
|
||
catch (NotEnabledDbUpgradeException $neu)
|
||
{
|
application/services/core/AclService.php | ||
---|---|---|
{
|
||
parent::__construct($factory);
|
||
// singleton resolver instance
|
||
if (empty($this->resolver))
|
||
if (empty(self::$resolver))
|
||
{
|
||
$this->resolver = new \Groups_aro_map_Model();
|
||
self::$resolver = new \Groups_aro_map_Model();
|
||
}
|
||
}
|
||
|
||
... | ... | |
if (($member_id == $_SESSION['member_id']) || $force_own)
|
||
{
|
||
// check own access
|
||
if ($this->resolver->has_access(
|
||
if (self::$resolver->has_access(
|
||
$_SESSION['user_id'], $aco_type . '_own',
|
||
$axo_section, $axo_value
|
||
))
|
||
... | ... | |
}
|
||
|
||
// check all
|
||
return $this->resolver->has_access(
|
||
return self::$resolver->has_access(
|
||
$_SESSION['user_id'], $aco_type . '_all',
|
||
$axo_section, $axo_value
|
||
);
|
||
... | ... | |
*/
|
||
public function is_user_in_group($aro_group_id, $aro_id)
|
||
{
|
||
return $this->resolver->groups_aro_map_exists($aro_group_id, $aro_id);
|
||
return self::$resolver->groups_aro_map_exists($aro_group_id, $aro_id);
|
||
}
|
||
|
||
/**
|
application/services/member/ExpirationCalcService.php | ||
---|---|---|
<?php
|
||
|
||
/*
|
||
* This file is part of open source system FreenetIS
|
||
* and it is release under GPLv3 licence.
|
||
*
|
||
* More info about licence can be found:
|
||
* http://www.gnu.org/licenses/gpl-3.0.html
|
||
*
|
||
* More info about project can be found:
|
||
* http://www.freenetis.org/
|
||
*/
|
||
|
||
namespace freenetis\service\member;
|
||
|
||
use date;
|
||
use Transfer_Model;
|
||
use Fee_Model;
|
||
use Device_Model;
|
||
|
||
/**
|
||
* Service that allows to calculate member payment expiration date.
|
||
*
|
||
* @author Ondřej Fibich <fibich@freenetis.org>
|
||
* @since 1.2
|
||
*/
|
||
class ExpirationCalcService extends \AbstractService
|
||
{
|
||
/**
|
||
* @var Transfer_Model
|
||
*/
|
||
protected $transfer_model;
|
||
/**
|
||
* @var Fee_Model
|
||
*/
|
||
protected $fee_model;
|
||
/**
|
||
* @var Device_Model
|
||
*/
|
||
protected $device_model;
|
||
|
||
/**
|
||
* Creates service.
|
||
*
|
||
* @param \ServiceFactory $factory
|
||
*/
|
||
public function __construct(\ServiceFactory $factory)
|
||
{
|
||
parent::__construct($factory);
|
||
$this->transfer_model = new Transfer_Model;
|
||
$this->fee_model = new Fee_Model;
|
||
$this->device_model = new Device_Model;
|
||
}
|
||
|
||
/**
|
||
* Gets expiration date of member's payments.
|
||
*
|
||
* @author Michal Kliment, Ondrej Fibich
|
||
* @param object $account
|
||
* @param int $shortened_on_year year to shortened expiration date from
|
||
* (10 years from now by default)
|
||
* @return ExpirationCalcResult
|
||
*/
|
||
public function get_expiration_info($account, $shortened_on_year = NULL)
|
||
{
|
||
if (!is_numeric($shortened_on_year))
|
||
{
|
||
$shortened_on_year = date('Y') + 10; // 10 year shortened by default
|
||
}
|
||
|
||
// member's actual balance
|
||
$balance = $account->balance;
|
||
|
||
$last_deduct_date = date_parse(
|
||
date::get_closses_deduct_date_to(
|
||
$this->transfer_model->get_last_transfer_datetime_of_account($account->id)
|
||
)
|
||
);
|
||
|
||
// date
|
||
$day = $last_deduct_date['day'];
|
||
$month = $last_deduct_date['month'];
|
||
$year = $last_deduct_date['year'];
|
||
|
||
// set algoritm firection by current balance
|
||
if ($balance > 0)
|
||
{
|
||
$sign = 1; // balance is in positive, we will go to the future
|
||
}
|
||
else
|
||
{
|
||
$sign = -1; // balance is in negative, we will go to the past
|
||
}
|
||
|
||
$payments = array();
|
||
|
||
// finds entrance date of member
|
||
$entrance_date_str = date::get_closses_deduct_date_to($account->member->entrance_date);
|
||
$entrance_date = date_parse($entrance_date_str);
|
||
|
||
// finds debt payment rate of entrance fee
|
||
$debt_payment_rate = ($account->member->debt_payment_rate > 0)
|
||
? $account->member->debt_payment_rate : $account->member->entrance_fee;
|
||
|
||
// finds all debt payments of entrance fee
|
||
self::find_debt_payments(
|
||
$payments, $entrance_date['month'], $entrance_date['year'],
|
||
$account->member->entrance_fee, $debt_payment_rate
|
||
);
|
||
|
||
// finds all member's devices with debt payments
|
||
$devices = $this->device_model->get_member_devices_with_debt_payments($account->member_id);
|
||
|
||
foreach ($devices as $device)
|
||
{
|
||
// finds buy date of this device
|
||
$buy_date = date_parse(date::get_closses_deduct_date_to($device->buy_date));
|
||
|
||
// finds all debt payments of this device
|
||
self::find_debt_payments(
|
||
$payments, $buy_date['month'], $buy_date['year'],
|
||
$device->price, $device->payment_rate
|
||
);
|
||
}
|
||
|
||
// protection from unending loop
|
||
$shortened = FALSE;
|
||
|
||
// finds min and max date = due to prevent before unending loop
|
||
$min_fee_date = $this->fee_model->get_min_fromdate_fee_by_type('regular member fee');
|
||
$max_fee_date = $this->fee_model->get_max_todate_fee_by_type('regular member fee');
|
||
|
||
while (true)
|
||
{
|
||
$date = date::create(date::get_deduct_day_to($month, $year), $month, $year);
|
||
|
||
// date is bigger/smaller than max/min fee date, ends it (prevent before unending loop)
|
||
if (($sign == 1 && $date > $max_fee_date) || ($sign == -1 && $date < $min_fee_date))
|
||
{
|
||
break;
|
||
}
|
||
|
||
// finds regular member fee for this month
|
||
$fee = $this->fee_model->get_regular_member_fee_by_member_date($account->member_id, $date);
|
||
|
||
// if exist payment for this month, adds it to the fee
|
||
if (isset($payments[$year][$month]))
|
||
$fee += $payments[$year][$month];
|
||
|
||
// attributed / deduct fee to / from balance
|
||
$balance -= $sign * $fee;
|
||
|
||
// break if we crossed dept border from any direction
|
||
if ($balance * $sign < 0)
|
||
{
|
||
break;
|
||
}
|
||
|
||
$month += $sign;
|
||
|
||
if ($month == 0 OR $month == 13)
|
||
{
|
||
$month = ($month == 13) ? 1 : 12;
|
||
$year += $sign;
|
||
}
|
||
|
||
// if we are X years in future, there is no point of counting more
|
||
if ($shortened_on_year < $year)
|
||
{
|
||
$shortened = TRUE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
$month--;
|
||
if ($month == 0)
|
||
{
|
||
$month = 12;
|
||
$year--;
|
||
}
|
||
|
||
$date = date::create(date::days_of_month($month), $month, $year);
|
||
|
||
// never exceed entrace day with expiration data
|
||
if (strtotime($date) < strtotime($entrance_date_str))
|
||
{
|
||
$date = $entrance_date_str;
|
||
}
|
||
|
||
return new ExpirationCalcResult($date, $shortened);
|
||
}
|
||
|
||
/**
|
||
* It stores debt payments into double-dimensional array (indexes year, month)
|
||
*
|
||
* @author Michal Kliment
|
||
* @param array $payments
|
||
* @param int $month
|
||
* @param int $year
|
||
* @param float $payment_left
|
||
* @param float $payment_rate
|
||
*/
|
||
protected static function find_debt_payments(
|
||
&$payments, $month, $year, $payment_left, $payment_rate)
|
||
{
|
||
while ($payment_left > 0)
|
||
{
|
||
if ($payment_left > $payment_rate)
|
||
{
|
||
$payment = $payment_rate;
|
||
}
|
||
else
|
||
{
|
||
$payment = $payment_left;
|
||
}
|
||
|
||
if (isset($payments[$year][$month]))
|
||
{
|
||
$payments[$year][$month] += $payment;
|
||
}
|
||
else
|
||
{
|
||
$payments[$year][$month] = $payment;
|
||
}
|
||
|
||
$month++;
|
||
if ($month > 12)
|
||
{
|
||
$month = 1;
|
||
$year++;
|
||
}
|
||
$payment_left -= $payment;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Holds expiration calculation result information.
|
||
*/
|
||
class ExpirationCalcResult
|
||
{
|
||
|
||
/**
|
||
* Calculated expiration in format YYYY-MM-DD.
|
||
*
|
||
* @var string
|
||
*/
|
||
public $expiration_date;
|
||
|
||
/**
|
||
* Flag whether the expiration was too long and was shortened.
|
||
*
|
||
* @var boolean
|
||
*/
|
||
public $shortened;
|
||
|
||
public function __construct($expiration_date, $shortened)
|
||
{
|
||
$this->expiration_date = $expiration_date;
|
||
$this->shortened = $shortened;
|
||
}
|
||
|
||
}
|
application/views/members/show.php | ||
---|---|---|
</td>
|
||
</tr>
|
||
<?php if ($member->type != Member_Model::TYPE_APPLICANT) { ?>
|
||
<?php if (isset($expiration_date) && ($entrance_fee_paid == $member->entrance_fee)) { ?>
|
||
<?php if (isset($expiration_info) && ($entrance_fee_paid == $member->entrance_fee)) { ?>
|
||
<tr>
|
||
<th><?php echo __('Payed to').' '.help::hint('payed_to') ?></th>
|
||
<td><?php echo $expiration_date ?></td>
|
||
<td><span style="color: <?php echo ($account->balance < 0) ? 'red' : 'green' ?>"><?php if ($expiration_info->shortened): ?>> <?php endif; ?><?php echo $expiration_info->expiration_date ?></span></td>
|
||
</tr>
|
||
<?php } ?>
|
||
<?php if (isset($fee)) { ?>
|
application/views/transfers/show_by_account.php | ||
---|---|---|
<?php endforeach; ?>
|
||
</td>
|
||
</tr>
|
||
<?php if (isset($expiration_date)) { ?>
|
||
<?php if (isset($expiration_info)) { ?>
|
||
<tr>
|
||
<th><?php echo __('Payed to')?></th>
|
||
<td><?php echo $expiration_date ?></td>
|
||
<td><span style="color: <?php echo ($balance < 0) ? 'red' : 'green' ?>"><?php if ($expiration_info->shortened): ?>> <?php endif; ?><?php echo $expiration_info->expiration_date ?></span></td>
|
||
</tr>
|
||
<?php } ?>
|
||
<?php } ?>
|
system/libraries/ServiceFactory.php | ||
---|---|---|
return $this->inject('core\SetupService');
|
||
}
|
||
|
||
/**
|
||
* @return \freenetis\service\member\ExpirationCalcService
|
||
*/
|
||
public function injectMemberExpirationCalc()
|
||
{
|
||
return $this->inject('member\ExpirationCalcService');
|
||
}
|
||
|
||
}
|
tests/AbstractItCase.php | ||
---|---|---|
{
|
||
self::reset_url_settings_to_current();
|
||
});
|
||
unlink($lck_file);
|
||
// get DB connection
|
||
self::$connection = Database::instance();
|
||
}
|
tests/application/controllers/api_endpoints/AbstractEndPointTestCase.php | ||
---|---|---|
protected $api_account;
|
||
|
||
/**
|
||
* Defines authentification type that is used for connecting to API.
|
||
* Defines authentication type that is used for connecting to API.
|
||
*
|
||
* @var string
|
||
*/
|
||
protected $auth_method;
|
||
|
||
/**
|
||
* Holds state of settings "api_enabled" during test.
|
||
*
|
||
* @var bool
|
||
*/
|
||
private static $old_api_enabled = TRUE;
|
||
|
||
/**
|
||
* Enable API and save old state before tests.
|
||
*/
|
||
public static function setUpBeforeClass() {
|
||
parent::setUpBeforeClass();
|
||
self::$old_api_enabled = module::e('api');
|
||
Settings::set('api_enabled', TRUE);
|
||
}
|
||
|
||
/**
|
||
* Restore old API state after all tests done.
|
||
*/
|
||
public static function tearDownAfterClass() {
|
||
parent::tearDownAfterClass();
|
||
Settings::set('api_enabled', self::$old_api_enabled);
|
||
}
|
||
|
||
/**
|
||
* Prepare base path and add API account.
|
||
*/
|
tests/application/helpers/dateTest.php | ||
---|---|---|
*/
|
||
class dateTest extends AbstractItCase
|
||
{
|
||
/**
|
||
* @covers date::create
|
||
*/
|
||
public function test_create()
|
||
{
|
||
$this->assertEquals('2017-01-01', date::create(1, 1, 2017));
|
||
$this->assertEquals('2017-12-01', date::create(1, 12, 2017));
|
||
$this->assertEquals('2017-01-31', date::create(31, 1, 2017));
|
||
}
|
||
|
||
/**
|
||
* @covers date::days_of_month
|
||
*/
|
||
public function test_days_of_month()
|
||
{
|
||
$this->assertEquals(31, date::days_of_month(1, 2017));
|
||
$this->assertEquals(28, date::days_of_month(2, 2014));
|
||
$this->assertEquals(28, date::days_of_month(2, 2015));
|
||
$this->assertEquals(29, date::days_of_month(2, 2016));
|
||
$this->assertEquals(28, date::days_of_month(2, 2017));
|
||
$this->assertEquals(31, date::days_of_month(3, 2017));
|
||
$this->assertEquals(30, date::days_of_month(4, 2017));
|
||
$this->assertEquals(31, date::days_of_month(5, 2017));
|
||
$this->assertEquals(30, date::days_of_month(6, 2017));
|
||
$this->assertEquals(31, date::days_of_month(7, 2017));
|
||
$this->assertEquals(31, date::days_of_month(8, 2017));
|
||
$this->assertEquals(30, date::days_of_month(9, 2017));
|
||
$this->assertEquals(31, date::days_of_month(10, 2017));
|
||
$this->assertEquals(30, date::days_of_month(11, 2017));
|
||
$this->assertEquals(31, date::days_of_month(12, 2017));
|
||
}
|
||
|
||
/**
|
||
* @covers date::get_next_deduct_date_to
|
tests/application/libraries/importers/importers.sql | ||
---|---|---|
TRUNCATE TABLE `address_points`;
|
||
INSERT INTO `address_points` (`id`, `name`, `country_id`, `town_id`, `street_id`, `street_number`, `gps`) VALUES
|
||
(1, NULL, 55, 1, 1, '594', NULL),
|
||
(2, NULL, 55, 1, 2, '784', ''),
|
||
(3, NULL, 55, 2, NULL, '78', ''),
|
||
(4, NULL, 55, 3, 3, '454/8a', '');
|
||
(2, NULL, 55, 1, 2, '784', NULL),
|
||
(3, NULL, 55, 2, NULL, '78', NULL),
|
||
(4, NULL, 55, 3, 3, '454/8a', NULL);
|
||
|
||
TRUNCATE TABLE `allowed_subnets`;
|
||
TRUNCATE TABLE `allowed_subnets_counts`;
|
||
... | ... | |
(3, 3, 1, '2004-01-15', '9999-12-31', 1, ''),
|
||
(4, 4, 1, '2004-01-15', '9999-12-31', 1, '');
|
||
|
||
TRUNCATE TABLE `members_traffics_daily`;
|
||
TRUNCATE TABLE `members_traffics_monthly`;
|
||
TRUNCATE TABLE `members_traffics_yearly`;
|
||
TRUNCATE TABLE `members_whitelists`;
|
||
INSERT INTO `members_whitelists` (`id`, `member_id`, `permanent`, `since`, `until`, `comment`) VALUES
|
||
(1, 1, 1, '2015-01-15', '9999-12-31', NULL);
|
tests/application/services/member/ExpirationCalcServiceTest.php | ||
---|---|---|
<?php
|
||
|
||
/*
|
||
* This file is part of open source system FreenetIS
|
||
* and it is release under GPLv3 licence.
|
||
*
|
||
* More info about licence can be found:
|
||
* http://www.gnu.org/licenses/gpl-3.0.html
|
||
*
|
||
* More info about project can be found:
|
||
* http://www.freenetis.org/
|
||
*/
|
||
|
||
namespace freenetis\service\member;
|
||
|
||
use AbstractItCase;
|
||
use Settings;
|
||
|
||
require_once APPPATH . '/services/member/ExpirationCalcService' . EXT;
|
||
|
||
/**
|
||
* Test case for ExpirationCalcService class.
|
||
*
|
||
* @author Ondřej Fibich <fibich@freenetis.org>
|
||
* @since 1.2
|
||
*/
|
||
class ExpirationCalcServiceTest extends AbstractItCase
|
||
{
|
||
|
||
/**
|
||
* @var ExpirationCalcService
|
||
*/
|
||
private $object;
|
||
|
||
/**
|
||
* Hold deduct day during test for recover.
|
||
*
|
||
* @var int day number
|
||
*/
|
||
private $old_deduct_day;
|
||
|
||
protected function setUp()
|
||
{
|
||
$this->object = new ConfigurableTestExpirationCalcService(self::$services);
|
||
$this->old_deduct_day = Settings::get('deduct_day');
|
||
}
|
||
|
||
protected function tearDown()
|
||
{
|
||
Settings::set('deduct_day', $this->old_deduct_day);
|
||
}
|
||
|
||
/**
|
||
* @see https://dev.freenetis.org/issues/1076
|
||
*/
|
||
public function test_get_expiration_info__issue1076()
|
||
{
|
||
Settings::set('deduct_day', 28);
|
||
|
||
$this->object->set_fee_model(new TestStaticFeeModel(2, 12.65));
|
||
$this->object->set_transfer_model(new TestStaticTransferModel(11, '2017-02-28'));
|
||
|
||
$account = new \stdClass();
|
||
$account->id = 11;
|
||
$account->balance = -37.95;
|
||
$account->member_id = 2;
|
||
$account->member = new \stdClass();
|
||
$account->member->entrance_date = '2016-06-01';
|
||
$account->member->entrance_fee = 9.9;
|
||
$account->member->debt_payment_rate = 0;
|
||
|
||
$res = $this->object->get_expiration_info($account);
|
||
$this->assertFalse($res->shortened);
|
||
$this->assertEquals($res->expiration_date, '2016-11-30', $res->expiration_date);
|
||
}
|
||
|
||
public function test_get_expiration_info__no_entrance_fee()
|
||
{
|
||
Settings::set('deduct_day', 15);
|
||
|
||
$this->object->set_fee_model(new TestStaticFeeModel(3, 150));
|
||
$this->object->set_transfer_model(new TestStaticTransferModel(12, '2017-10-15'));
|
||
|
||
$account = new \stdClass();
|
||
$account->id = 12;
|
||
$account->balance = 1500.00;
|
||
$account->member_id = 3;
|
||
$account->member = new \stdClass();
|
||
$account->member->entrance_date = '2017-09-01';
|
||
$account->member->entrance_fee = 0;
|
||
$account->member->debt_payment_rate = 0;
|
||
|
||
$res = $this->object->get_expiration_info($account);
|
||
$this->assertFalse($res->shortened);
|
||
$this->assertEquals('2018-08-31', $res->expiration_date);
|
||
|
||
// Shortened test
|
||
$res_shortened = $this->object->get_expiration_info($account, 2017);
|
||
$this->assertTrue($res_shortened->shortened);
|
||
$this->assertEquals('2017-12-31', $res_shortened->expiration_date);
|
||
}
|
||
|
||
public function test_get_expiration_info__debt_month()
|
||
{
|
||
Settings::set('deduct_day', 15);
|
||
|
||
$this->object->set_fee_model(new TestStaticFeeModel(4, 150));
|
||
$this->object->set_transfer_model(new TestStaticTransferModel(13, '2017-10-15'));
|
||
|
||
$account = new \stdClass();
|
||
$account->id = 13;
|
||
$account->balance = -150.00;
|
||
$account->member_id = 4;
|
||
$account->member = new \stdClass();
|
||
$account->member->entrance_date = '2017-09-01';
|
||
$account->member->entrance_fee = 0;
|
||
$account->member->debt_payment_rate = 0;
|
||
|
||
$res = $this->object->get_expiration_info($account);
|
||
$this->assertFalse($res->shortened);
|
||
$this->assertEquals('2017-09-30', $res->expiration_date);
|
||
}
|
||
|
||
public function test_get_expiration_info__entrance_fee()
|
||
{
|
||
Settings::set('deduct_day', 1);
|
||
|
||
$this->object->set_fee_model(new TestStaticFeeModel(10, 100));
|
||
$this->object->set_transfer_model(new TestStaticTransferModel(20, '2017-10-01'));
|
||
|
||
$account = new \stdClass();
|
||
$account->id = 20;
|
||
$account->balance = 600.00;
|
||
$account->member_id = 10;
|
||
$account->member = new \stdClass();
|
||
$account->member->entrance_date = '2017-09-01';
|
||
$account->member->entrance_fee = 1000;
|
||
$account->member->debt_payment_rate = 500;
|
||
|
||
$res = $this->object->get_expiration_info($account);
|
||
$this->assertFalse($res->shortened);
|
||
$this->assertEquals('2017-11-30', $res->expiration_date);
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Special ExpirationCalcService that allows to replace models for testing
|
||
* purposes.
|
||
*/
|
||
class ConfigurableTestExpirationCalcService extends ExpirationCalcService
|
||
{
|
||
public function set_transfer_model($transfer_model)
|
||
{
|
||
$this->transfer_model = $transfer_model;
|
||
}
|
||
|
||
public function set_fee_model($fee_model)
|
||
{
|
||
$this->fee_model = $fee_model;
|
||
}
|
||
|
||
public function set_device_model($device_model)
|
||
{
|
||
$this->device_model = $device_model;
|
||
}
|
||
}
|
||
|
||
class TestStaticTransferModel
|
||
{
|
||
private $account_id;
|
||
private $last_transfer_date;
|
||
|
||
function __construct($account_id, $last_transfer_date)
|
||
{
|
||
$this->account_id = $account_id;
|
||
$this->last_transfer_date = $last_transfer_date;
|
||
}
|
||
|
||
public function get_last_transfer_datetime_of_account($account_id)
|
||
{
|
||
return $this->account_id == $account_id ? $this->last_transfer_date : NULL;
|
||
}
|
||
}
|
||
|
||
class TestStaticFeeModel
|
||
{
|
||
private $member_id;
|
||
private $fee;
|
||
|
||
function __construct($member_id, $fee)
|
||
{
|
||
$this->member_id = $member_id;
|
||
$this->fee = $fee;
|
||
}
|
||
|
||
public function get_min_fromdate_fee_by_type($fee_name)
|
||
{
|
||
return '0000-00-00';
|
||
}
|
||
|
||
public function get_max_todate_fee_by_type($fee_name)
|
||
{
|
||
return '9999-12-31';
|
||
}
|
||
|
||
public function get_regular_member_fee_by_member_date($member_id, $date)
|
||
{
|
||
return ($this->member_id == $member_id) ? $this->fee : 0;
|
||
}
|
||
}
|
tests/config.sample.ini | ||
---|---|---|
|
||
; Database configuration
|
||
[db]
|
||
type = mysql
|
||
type = mysqli
|
||
user = root
|
||
pass =
|
||
host = localhost
|
Také k dispozici: Unified diff
Refs #1076: member expiration date calculation fix. The calc functionality was separate from Members controller to a new Expiration calc service. The new service comes with unit tests which tests the #1076. Additionally this patch comes with some fixes and improvements in already existing unit and integration tests.