Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrate credit system for env usage #230

Merged
merged 2 commits into from
Jan 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .env.dev
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,12 @@ APP_DEBUG=1
DB_DSN=mysql:host=db;dbname=bikesharing;charset=utf8
DB_USER=bikesharing
DB_PASSWORD=password
[email protected]
[email protected]
CREDIT_SYSTEM_ENABLED=true
CREDIT_SYSTEM_CURRENCY=$
CREDIT_SYSTEM_MIN_BALANCE=2
CREDIT_SYSTEM_RENTAL_FEE=2
CREDIT_SYSTEM_PRICE_CYCLE=0
CREDIT_SYSTEM_LONG_RENTAL_FEE=5
CREDIT_SYSTEM_LIMIT_INCREASE_FEE=10
CREDIT_SYSTEM_VIOLATION_FEE=5
21 changes: 19 additions & 2 deletions .env.dist
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ SMS_CONNECTOR_CONFIG="
}
"
SENTRY_DSN=
# false = no notication send to users (when admins get notified), true = notification messages sent to users as well
#false = no notification send to users (when admins get notified)
#true = notification messages sent to users as well
NOTIFY_USER_ABOUT_LONG_RENTAL=false
DB_DSN=
DB_USER=
Expand All @@ -30,4 +31,20 @@ SMTP_PORT=465
SMTP_USER=
SMTP_PASSWORD=
SMTP_DEBUG_LEVEL=0
SMTP_FROM_EMAIL=
SMTP_FROM_EMAIL=
CREDIT_SYSTEM_ENABLED=false
CREDIT_SYSTEM_CURRENCY=€
#minimum credit required to allow any bike operations
CREDIT_SYSTEM_MIN_BALANCE=2
#rental fee (after $watches["freetime"])
CREDIT_SYSTEM_RENTAL_FEE=2
#0 = disabled,
#1 = charge flat price $credit["rent"] every $watches["flatpricecycle"] minutes
#2 = charge doubled price $credit["rent"] every $watches["doublepricecycle"] minutes
CREDIT_SYSTEM_PRICE_CYCLE=0
#long rental fee ($watches["longrental"] time)
CREDIT_SYSTEM_LONG_RENTAL_FEE=5
#credit needed to temporarily increase limit, applicable only when $limits["increase"]>0
CREDIT_SYSTEM_LIMIT_INCREASE_FEE=10
#credit deduction for rule violations (applied by admins)
CREDIT_SYSTEM_VIOLATION_FEE=5
12 changes: 9 additions & 3 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@
env('DB_DSN'),
env('DB_USER'),
env('DB_PASSWORD'),
service('logger')
]);

$services->alias(DbInterface::class, PdoDb::class);
Expand Down Expand Up @@ -112,10 +111,17 @@
]);

$services->get(CreditSystemFactory::class)
->bind('$creditConfiguration', expr("service('BikeShare\\\App\\\Configuration').get('credit')"));
->bind('$isEnabled', env('bool:CREDIT_SYSTEM_ENABLED'));

$services->get(CreditSystem::class)
->bind('$creditConfiguration', expr("service('BikeShare\\\App\\\Configuration').get('credit')"));
->bind('$isEnabled', env('bool:CREDIT_SYSTEM_ENABLED'))
->bind('$creditCurrency', env('CREDIT_SYSTEM_CURRENCY'))
->bind('$minBalanceCredit', env('float:CREDIT_SYSTEM_MIN_BALANCE'))
->bind('$rentalFee', env('float:CREDIT_SYSTEM_RENTAL_FEE'))
->bind('$priceCycle', env('int:CREDIT_SYSTEM_PRICE_CYCLE'))
->bind('$longRentalFee', env('float:CREDIT_SYSTEM_LONG_RENTAL_FEE'))
->bind('$limitIncreaseFee', env('float:CREDIT_SYSTEM_LIMIT_INCREASE_FEE'))
->bind('$violationFee', env('float:CREDIT_SYSTEM_VIOLATION_FEE'));

$services->load('BikeShare\\Rent\\', '../src/Rent')
->bind('$watchesConfig', expr("service('BikeShare\\\App\\\Configuration').get('watches')"))
Expand Down
136 changes: 57 additions & 79 deletions src/Credit/CreditSystem.php
Original file line number Diff line number Diff line change
@@ -1,43 +1,73 @@
<?php

declare(strict_types=1);

namespace BikeShare\Credit;

use BikeShare\Db\DbInterface;

class CreditSystem implements CreditSystemInterface
{
// 0 = no credit system, 1 = apply credit system rules and deductions
private $isEnabled = false;
// false = no credit system and Exceptions will be thrown
// true = apply credit system rules and deductions
private bool $isEnabled;
// currency used for credit system
private $creditCurrency = "€";
private string $creditCurrency;
// minimum credit required to allow any bike operations
private $minBalanceCredit = 2;
private float $minBalanceCredit;
// rental fee (after $watches["freetime"])
private $rentalFee = 2;
// 0 = disabled, 1 = charge flat price $credit["rent"] every $watches["flatpricecycle"] minutes,
private float $rentalFee;
// 0 = disabled,
// 1 = charge flat price $credit["rent"] every $watches["flatpricecycle"] minutes,
// 2 = charge doubled price $credit["rent"] every $watches["doublepricecycle"] minutes
private $priceCycle = 0;
private int $priceCycle;
// long rental fee ($watches["longrental"] time)
private $longRentalFee = 5;
private float $longRentalFee;
// credit needed to temporarily increase limit, applicable only when $limits["increase"]>0
private $limitIncreaseFee = 10;
private float $limitIncreaseFee;
// credit deduction for rule violations (applied by admins)
private $violationFee = 5;
private float $violationFee;

/**
* @var DbInterface
*/
private $db;
private DbInterface $db;

public function __construct(
array $creditConfiguration,
bool $isEnabled,
string $creditCurrency,
float $minBalanceCredit,
float $rentalFee,
int $priceCycle,
float $longRentalFee,
float $limitIncreaseFee,
float $violationFee,
DbInterface $db
) {
$this->parseConfiguration($creditConfiguration);
if (!$isEnabled) {
throw new \RuntimeException('Use DisabledCreditSystem instead');
}
if (
$minBalanceCredit < 0
|| $rentalFee < 0
|| $longRentalFee < 0
|| $limitIncreaseFee < 0
|| $violationFee < 0
) {
throw new \InvalidArgumentException('Credit values cannot be negative');
}
if (!in_array($priceCycle, [0, 1, 2], true)) {
throw new \InvalidArgumentException('Invalid price cycle value');
}
$this->isEnabled = $isEnabled;
$this->creditCurrency = $creditCurrency;
$this->minBalanceCredit = $minBalanceCredit;
$this->rentalFee = $rentalFee;
$this->priceCycle = $priceCycle;
$this->longRentalFee = $longRentalFee;
$this->limitIncreaseFee = $limitIncreaseFee;
$this->violationFee = $violationFee;
$this->db = $db;
}

public function getUserCredit($userId)
public function getUserCredit($userId): float
{
$result = $this->db->query('SELECT credit FROM credit WHERE userId = :userId', ['userId' => $userId]);
if ($result->rowCount() == 0) {
Expand All @@ -47,100 +77,48 @@ public function getUserCredit($userId)
return $result->fetchAssoc()['credit'];
}

public function getMinRequiredCredit()
public function getMinRequiredCredit(): float
{
return $this->minBalanceCredit + $this->rentalFee + $this->longRentalFee;
}

public function isEnoughCreditForRent($userid)
public function isEnoughCreditForRent($userid): bool
{
return $this->getUserCredit($userid) >= $this->getMinRequiredCredit();
}

/**
* @return bool
*/
public function isEnabled()
public function isEnabled(): bool
{
return $this->isEnabled;
}
/**
* @return string
*/
public function getCreditCurrency()

public function getCreditCurrency(): string
{
return $this->creditCurrency;
}

/**
* @return int
*/
public function getRentalFee()
public function getRentalFee(): float
{
return $this->rentalFee;
}

/**
* @return int
*/
public function getPriceCycle()
public function getPriceCycle(): int
{
return $this->priceCycle;
}

/**
* @return int
*/
public function getLongRentalFee()
public function getLongRentalFee(): float
{
return $this->longRentalFee;
}

/**
* @return int
*/
public function getLimitIncreaseFee()
public function getLimitIncreaseFee(): float
{
return $this->limitIncreaseFee;
}

/**
* @return int
*/
public function getViolationFee()
public function getViolationFee(): float
{
return $this->violationFee;
}

/**
* @TODO move to a CreditSystemFactory
* @param array $creditConfiguration
*/
private function parseConfiguration(array $creditConfiguration)
{
if (isset($creditConfiguration['enabled'])) {
$this->isEnabled = (bool)$creditConfiguration['enabled'];
}
if (isset($creditConfiguration['currency'])) {
$this->creditCurrency = (string)$creditConfiguration['currency'];
}
if (isset($creditConfiguration['min'])) {
$this->minBalanceCredit = (int)$creditConfiguration['min'];
}
if (isset($creditConfiguration['rent'])) {
$this->rentalFee = (int)$creditConfiguration['rent'];
}
if (isset($creditConfiguration['pricecycle'])) {
$this->priceCycle = (int)$creditConfiguration['pricecycle'];
}
if (isset($creditConfiguration['longrental'])) {
$this->longRentalFee = (int)$creditConfiguration['longrental'];
}
if (isset($creditConfiguration['limitincrease'])) {
$this->limitIncreaseFee = (int)$creditConfiguration['limitincrease'];
}
if (isset($creditConfiguration['violation'])) {
$this->violationFee = (int)$creditConfiguration['violation'];
}
}
}
11 changes: 4 additions & 7 deletions src/Credit/CreditSystemFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,19 @@
class CreditSystemFactory
{
private ServiceLocator $locator;
private array $creditConfiguration;
private bool $isEnabled;

public function __construct(
ServiceLocator $locator,
array $creditConfiguration
bool $isEnabled
) {
$this->locator = $locator;
$this->creditConfiguration = $creditConfiguration;
$this->isEnabled = $isEnabled;
}

public function getCreditSystem(): CreditSystemInterface
{
if (!isset($this->creditConfiguration["enabled"])) {
$this->creditConfiguration["enabled"] = false;
}
if (!$this->creditConfiguration["enabled"]) {
if (!$this->isEnabled) {
return $this->locator->get(DisabledCreditSystem::class);
} else {
return $this->locator->get(CreditSystem::class);
Expand Down
70 changes: 21 additions & 49 deletions src/Credit/CreditSystemInterface.php
Original file line number Diff line number Diff line change
@@ -1,56 +1,28 @@
<?php

declare(strict_types=1);

namespace BikeShare\Credit;

interface CreditSystemInterface
{
/**
* @return int
*/
public function getUserCredit($userId);

/**
* @return int
*/
public function getMinRequiredCredit();

/**
* @return bool
*/
public function isEnoughCreditForRent($userid);

/**
* @return bool
*/
public function isEnabled();

/**
* @return string
*/
public function getCreditCurrency();

/**
* @return int
*/
public function getRentalFee();

/**
* @return int
*/
public function getPriceCycle();

/**
* @return int
*/
public function getLongRentalFee();

/**
* @return int
*/
public function getLimitIncreaseFee();

/**
* @return int
*/
public function getViolationFee();
public function getUserCredit($userId): float;

public function getMinRequiredCredit(): float;

public function isEnoughCreditForRent($userid): bool;

public function isEnabled(): bool;

public function getCreditCurrency(): string;

public function getRentalFee(): float;

public function getPriceCycle(): int;

public function getLongRentalFee(): float;

public function getLimitIncreaseFee(): float;

public function getViolationFee(): float;
}
Loading
Loading