Skip to content

Commit

Permalink
migrate credit system for env usage (#230)
Browse files Browse the repository at this point in the history
* migrate credit system for env usage

* credit system validation rules
  • Loading branch information
sveneld authored Jan 12, 2025
1 parent 19fbfdb commit af05d0c
Show file tree
Hide file tree
Showing 10 changed files with 253 additions and 215 deletions.
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
SMTP_FROM_EMAIL=[email protected]
SMTP_FROM_EMAIL=[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

0 comments on commit af05d0c

Please sign in to comment.