diff --git a/config/packages/zenstruck_foundry.yaml b/config/packages/zenstruck_foundry.yaml index e3ed04b..71fd8fe 100644 --- a/config/packages/zenstruck_foundry.yaml +++ b/config/packages/zenstruck_foundry.yaml @@ -1,5 +1,7 @@ when@dev: &dev # See full configuration: https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#full-default-bundle-configuration zenstruck_foundry: + persistence: + flush_once: true when@test: *dev diff --git a/config/services.yaml b/config/services.yaml index f79be2c..8282741 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -14,7 +14,7 @@ services: _instanceof: App\Gateway\GatewayInterface: tags: ['app.gateway.gateway'] - App\Library\Economy\Currency\ExchangeInterface: + App\Money\Currency\ExchangeInterface: tags: ['app.lib.economy.currency.exchange'] App\Matchfunding\Formula\FormulaInterface: tags: ['app.matchfunding.formula'] @@ -94,7 +94,7 @@ services: $hosts: - 'peertube.plataformess.org' - App\Library\Economy\Currency\ExchangeLocator: + App\Money\Currency\ExchangeLocator: arguments: - !tagged 'app.lib.economy.currency.exchange' diff --git a/src/ApiResource/Accounting/AccountingBalance.php b/src/ApiResource/Accounting/AccountingBalance.php index 4bb9c71..d8a7b57 100644 --- a/src/ApiResource/Accounting/AccountingBalance.php +++ b/src/ApiResource/Accounting/AccountingBalance.php @@ -3,8 +3,7 @@ namespace App\ApiResource\Accounting; use ApiPlatform\Metadata as API; -use App\Entity\Accounting\Accounting; -use App\Entity\Money; +use App\ApiResource\ApiMoney; use App\State\Accounting\AccountingBalanceStateProvider; /** @@ -35,5 +34,5 @@ class AccountingBalance * The money currently held by the Accounting. */ #[API\ApiProperty(security: 'is_granted("ACCOUNTING_VIEW", object.accounting)')] - public Money $balance; + public ApiMoney $balance; } diff --git a/src/ApiResource/Accounting/AccountingBalancePoint.php b/src/ApiResource/Accounting/AccountingBalancePoint.php index 6ca16fc..80c3c11 100644 --- a/src/ApiResource/Accounting/AccountingBalancePoint.php +++ b/src/ApiResource/Accounting/AccountingBalancePoint.php @@ -4,7 +4,7 @@ namespace App\ApiResource\Accounting; use ApiPlatform\Metadata as API; use ApiPlatform\Metadata\QueryParameter; -use App\Entity\Money; +use App\ApiResource\ApiMoney; use App\State\Accounting\AccountingBalancePointStateProvider; use Symfony\Component\Validator\Constraints as Assert; @@ -57,7 +57,7 @@ class AccountingBalancePoint /** * Resulting balance for items in this point. */ - public Money $balance; + public ApiMoney $balance; /** * The number of items aggregated in this point. diff --git a/src/ApiResource/Accounting/TransactionApiResource.php b/src/ApiResource/Accounting/TransactionApiResource.php index 85e13c6..06ba51a 100644 --- a/src/ApiResource/Accounting/TransactionApiResource.php +++ b/src/ApiResource/Accounting/TransactionApiResource.php @@ -5,8 +5,8 @@ namespace App\ApiResource\Accounting; use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; use ApiPlatform\Doctrine\Orm\State\Options; use ApiPlatform\Metadata as API; +use App\ApiResource\ApiMoney; use App\Entity\Accounting\Transaction; -use App\Entity\Money; use App\State\ApiResourceStateProvider; /** @@ -33,7 +33,7 @@ class TransactionApiResource /** * The monetary value received at target and issued at origin. */ - public Money $money; + public ApiMoney $money; /** * The Accounting from which the Transaction comes from. diff --git a/src/ApiResource/ApiMoney.php b/src/ApiResource/ApiMoney.php new file mode 100644 index 0000000..9f2e3fd --- /dev/null +++ b/src/ApiResource/ApiMoney.php @@ -0,0 +1,50 @@ +amount = $amount; + $this->currency = $currency; + } + + public static function of(MoneyInterface $moneyInterface): self + { + return new self( + $moneyInterface->getAmount(), + $moneyInterface->getCurrency() + ); + } + + public function getAmount(): int + { + return $this->amount; + } + + public function getCurrency(): string + { + return $this->currency; + } +} diff --git a/src/ApiResource/Gateway/ChargeApiResource.php b/src/ApiResource/Gateway/ChargeApiResource.php index c7480f6..ef8db2c 100644 --- a/src/ApiResource/Gateway/ChargeApiResource.php +++ b/src/ApiResource/Gateway/ChargeApiResource.php @@ -6,9 +6,9 @@ use ApiPlatform\Doctrine\Orm\Filter; use ApiPlatform\Doctrine\Orm\State\Options; use ApiPlatform\Metadata as API; use App\ApiResource\Accounting\AccountingApiResource; +use App\ApiResource\ApiMoney; use App\Dto\Gateway\ChargeUpdationDto; use App\Entity\Gateway\Charge; -use App\Entity\Money; use App\Filter\GatewayFilter; use App\Gateway\ChargeStatus; use App\Gateway\ChargeType; @@ -81,7 +81,7 @@ class ChargeApiResource #[Assert\NotBlank()] #[API\ApiFilter(Filter\RangeFilter::class, properties: ['money.amount'])] #[API\ApiFilter(Filter\SearchFilter::class, properties: ['money.currency' => 'exact'])] - public Money $money; + public ApiMoney $money; /** * The status of the charge item with the Gateway. diff --git a/src/ApiResource/Matchfunding/MatchStrategyApiResource.php b/src/ApiResource/Matchfunding/MatchStrategyApiResource.php index c13485a..a58c382 100644 --- a/src/ApiResource/Matchfunding/MatchStrategyApiResource.php +++ b/src/ApiResource/Matchfunding/MatchStrategyApiResource.php @@ -6,7 +6,7 @@ use ApiPlatform\Doctrine\Orm\Filter\OrderFilter; use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; use ApiPlatform\Doctrine\Orm\State\Options; use ApiPlatform\Metadata as API; -use App\ApiResource\Money; +use App\ApiResource\ApiMoney; use App\Entity\Matchfunding\MatchAgainst; use App\Entity\Matchfunding\MatchStrategy; use App\Mapping\Transformer\MatchFormulaMapTransformer; @@ -81,7 +81,7 @@ class MatchStrategyApiResource */ #[Assert\NotBlank()] #[Assert\Valid()] - public Money $limit; + public ApiMoney $limit; /** * The `x` factor used to calculate the resulting match of funds with the MatchFormula. diff --git a/src/ApiResource/Money.php b/src/ApiResource/Money.php deleted file mode 100644 index 9fba1f0..0000000 --- a/src/ApiResource/Money.php +++ /dev/null @@ -1,23 +0,0 @@ -setType($this->getCostType($record)); $budgetItem->setTitle($record['cost']); $budgetItem->setDescription($record['description'] ?? $record['cost']); - $budgetItem->setMoney(new Money($record['amount'] * 100, 'EUR')); + $budgetItem->setMoney(new EmbeddableMoney($record['amount'] * 100, 'EUR')); $budgetItem->setDeadline($this->getDeadline($record)); $localizations = $this->getCostLocalizations($budgetItem, $context); diff --git a/src/Benzina/ProjectsRewardsPump.php b/src/Benzina/ProjectsRewardsPump.php index 8c53a22..04795ac 100644 --- a/src/Benzina/ProjectsRewardsPump.php +++ b/src/Benzina/ProjectsRewardsPump.php @@ -2,7 +2,7 @@ namespace App\Benzina; -use App\Entity\Money; +use App\Entity\EmbeddableMoney; use App\Entity\Project\BudgetItemType; use App\Entity\Project\Project; use App\Entity\Project\Reward; @@ -73,7 +73,7 @@ class ProjectsRewardsPump implements PumpInterface $reward->setMigratedId($record['id']); $reward->setTitle($record['reward']); $reward->setDescription($record['description'] ?? $record['reward']); - $reward->setMoney(new Money($record['amount'] * 100, 'EUR')); + $reward->setMoney(new EmbeddableMoney($record['amount'] * 100, 'EUR')); $reward->setHasUnits($record['units'] > 0); $reward->setUnitsTotal($record['units'] ?? 0); $reward->setUnitsAvailable($record['units'] ?? 0); diff --git a/src/Entity/Accounting/Transaction.php b/src/Entity/Accounting/Transaction.php index 2de26fc..c630345 100644 --- a/src/Entity/Accounting/Transaction.php +++ b/src/Entity/Accounting/Transaction.php @@ -2,7 +2,7 @@ namespace App\Entity\Accounting; -use App\Entity\Money; +use App\Entity\EmbeddableMoney as Money; use App\Entity\Trait\TimestampedCreationEntity; use App\Mapping\Provider\EntityMapProvider; use App\Repository\Accounting\TransactionRepository; diff --git a/src/Entity/Money.php b/src/Entity/EmbeddableMoney.php similarity index 61% rename from src/Entity/Money.php rename to src/Entity/EmbeddableMoney.php index c3625d5..9f79eae 100644 --- a/src/Entity/Money.php +++ b/src/Entity/EmbeddableMoney.php @@ -2,6 +2,7 @@ namespace App\Entity; +use App\Money\MoneyInterface; use Doctrine\ORM\Mapping as ORM; /** @@ -11,7 +12,7 @@ use Doctrine\ORM\Mapping as ORM; * @see \Brick\Money */ #[ORM\Embeddable] -class Money +class EmbeddableMoney implements MoneyInterface { /** * An amount of currency.\ @@ -33,4 +34,22 @@ class Money $this->amount = $amount; $this->currency = $currency; } + + public static function of(MoneyInterface $moneyInterface): self + { + return new self( + $moneyInterface->getAmount(), + $moneyInterface->getCurrency() + ); + } + + public function getAmount(): int + { + return $this->amount; + } + + public function getCurrency(): string + { + return $this->currency; + } } diff --git a/src/Entity/Gateway/Charge.php b/src/Entity/Gateway/Charge.php index 8bf56f4..cd52fc1 100644 --- a/src/Entity/Gateway/Charge.php +++ b/src/Entity/Gateway/Charge.php @@ -4,7 +4,7 @@ namespace App\Entity\Gateway; use App\Entity\Accounting\Accounting; use App\Entity\Accounting\Transaction; -use App\Entity\Money; +use App\Entity\EmbeddableMoney as Money; use App\Entity\Trait\TimestampedCreationEntity; use App\Entity\Trait\TimestampedUpdationEntity; use App\Gateway\ChargeStatus; diff --git a/src/Entity/Matchfunding/MatchStrategy.php b/src/Entity/Matchfunding/MatchStrategy.php index 8f9b002..7f45ba1 100644 --- a/src/Entity/Matchfunding/MatchStrategy.php +++ b/src/Entity/Matchfunding/MatchStrategy.php @@ -2,7 +2,7 @@ namespace App\Entity\Matchfunding; -use App\Entity\Money; +use App\Entity\EmbeddableMoney as Money; use App\Mapping\Provider\EntityMapProvider; use App\Matchfunding\Formula\MultiplicationFormula; use App\Repository\Matchfunding\MatchStrategyRepository; diff --git a/src/Entity/Project/BudgetItem.php b/src/Entity/Project/BudgetItem.php index 4933eb5..0d752f8 100644 --- a/src/Entity/Project/BudgetItem.php +++ b/src/Entity/Project/BudgetItem.php @@ -2,8 +2,8 @@ namespace App\Entity\Project; +use App\Entity\EmbeddableMoney as Money; use App\Entity\Interface\LocalizedEntityInterface; -use App\Entity\Money; use App\Entity\Trait\LocalizedEntityTrait; use App\Entity\Trait\MigratedEntity; use App\Mapping\Provider\EntityMapProvider; diff --git a/src/Entity/Project/Reward.php b/src/Entity/Project/Reward.php index dc3f60d..6ea2a3b 100644 --- a/src/Entity/Project/Reward.php +++ b/src/Entity/Project/Reward.php @@ -2,8 +2,8 @@ namespace App\Entity\Project; +use App\Entity\EmbeddableMoney as Money; use App\Entity\Interface\LocalizedEntityInterface; -use App\Entity\Money; use App\Entity\Trait\LocalizedEntityTrait; use App\Entity\Trait\MigratedEntity; use App\Mapping\Provider\EntityMapProvider; diff --git a/src/Entity/Project/Support.php b/src/Entity/Project/Support.php index 7d86673..0605984 100644 --- a/src/Entity/Project/Support.php +++ b/src/Entity/Project/Support.php @@ -13,10 +13,9 @@ use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; #[MapProvider(EntityMapProvider::class)] +#[ORM\Table(name: 'project_support')] +#[ORM\UniqueConstraint(fields: ['project', 'origin'])] #[ORM\Entity(repositoryClass: SupportRepository::class)] -#[ORM\Table(name: 'project_support', uniqueConstraints: [ - new ORM\UniqueConstraint(fields: ['project', 'origin']), -])] class Support { #[ORM\Id] diff --git a/src/Entity/WalletFinancement.php b/src/Entity/Wallet/WalletFinancement.php similarity index 82% rename from src/Entity/WalletFinancement.php rename to src/Entity/Wallet/WalletFinancement.php index 34f7ddc..de8f454 100644 --- a/src/Entity/WalletFinancement.php +++ b/src/Entity/Wallet/WalletFinancement.php @@ -1,8 +1,9 @@ id; } - public function getMoney(): ?Money + public function getMoney(): ?EmbeddableMoney { return $this->money; } - public function setMoney(Money $money): static + public function setMoney(EmbeddableMoney $money): static { $this->money = $money; diff --git a/src/Entity/WalletStatement.php b/src/Entity/Wallet/WalletStatement.php similarity index 93% rename from src/Entity/WalletStatement.php rename to src/Entity/Wallet/WalletStatement.php index be15c70..1a91524 100644 --- a/src/Entity/WalletStatement.php +++ b/src/Entity/Wallet/WalletStatement.php @@ -1,10 +1,11 @@ balance; } - public function setBalance(Money $balance): static + public function setBalance(EmbeddableMoney $balance): static { $this->balance = $balance; diff --git a/src/EventSubscriber/AuthorizationTokenSubscriber.php b/src/EventSubscriber/AuthorizationTokenSubscriber.php index 1c9541f..e9a11a4 100644 --- a/src/EventSubscriber/AuthorizationTokenSubscriber.php +++ b/src/EventSubscriber/AuthorizationTokenSubscriber.php @@ -17,7 +17,7 @@ final class AuthorizationTokenSubscriber implements EventSubscriberInterface private AuthService $authService, ) {} - public static function getSubscribedEvents() + public static function getSubscribedEvents(): array { return [ KernelEvents::VIEW => ['onView', EventPriorities::POST_WRITE], diff --git a/src/Gateway/Wallet/WalletGateway.php b/src/Gateway/Wallet/WalletGateway.php index e380239..d0bcbde 100644 --- a/src/Gateway/Wallet/WalletGateway.php +++ b/src/Gateway/Wallet/WalletGateway.php @@ -5,12 +5,12 @@ namespace App\Gateway\Wallet; use App\Entity\Accounting\Transaction; use App\Entity\Gateway\Charge; use App\Entity\Gateway\Checkout; -use App\Entity\Money; use App\Gateway\ChargeStatus; use App\Gateway\ChargeType; use App\Gateway\CheckoutStatus; use App\Gateway\GatewayInterface; -use App\Library\Economy\MoneyService; +use App\Money\Money; +use App\Money\MoneyService; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; diff --git a/src/Gateway/Wallet/WalletService.php b/src/Gateway/Wallet/WalletService.php index 3ef2724..66f14a2 100644 --- a/src/Gateway/Wallet/WalletService.php +++ b/src/Gateway/Wallet/WalletService.php @@ -4,11 +4,12 @@ namespace App\Gateway\Wallet; use App\Entity\Accounting\Accounting; use App\Entity\Accounting\Transaction; -use App\Entity\Money; -use App\Entity\WalletFinancement; -use App\Entity\WalletStatement; -use App\Library\Economy\MoneyService; -use App\Repository\WalletStatementRepository; +use App\Entity\EmbeddableMoney; +use App\Entity\Wallet\WalletFinancement; +use App\Entity\Wallet\WalletStatement; +use App\Money\Money; +use App\Money\MoneyService; +use App\Repository\Wallet\WalletStatementRepository; use Brick\Money as Brick; use Doctrine\ORM\EntityManagerInterface; @@ -39,7 +40,10 @@ class WalletService $total = $total->plus($balance); } - return $this->money->toMoney($total); + return new Money( + $total->getMinorAmount()->toInt(), + $total->getCurrency()->getCurrencyCode() + ); } /** @@ -77,7 +81,7 @@ class WalletService $origin = $transaction->getOrigin(); $spendGoal = $transaction->getMoney(); - $spentTotal = new Money(0, $spendGoal->currency); + $spentTotal = new Money(0, $spendGoal->getCurrency()); $outgoing = new WalletStatement(); $outgoing->setTransaction($transaction); @@ -85,7 +89,7 @@ class WalletService $statements = $this->getStatements($origin); foreach ($statements as $statement) { - if ($spendGoal->amount === 0) { + if ($spendGoal->getAmount() === 0) { break; } @@ -94,9 +98,9 @@ class WalletService } $incoming = $statement; - $balance = $incoming->getBalance(); - if ($balance->amount === 0) { + $balance = $incoming->getBalance(); + if ($balance->getAmount() === 0) { continue; } @@ -107,12 +111,14 @@ class WalletService } $financement = new WalletFinancement(); - $financement->setMoney($balanceSpent); + $financement->setMoney(EmbeddableMoney::of($balanceSpent)); - $incoming->setBalance($this->money->substract($balanceSpent, $balance)); + $substracted = $this->money->substract($balanceSpent, $balance); + $incoming->setBalance(EmbeddableMoney::of($substracted)); $incoming->addFinancesTo($financement); - $outgoing->setBalance($this->money->add($balanceSpent, $spentTotal)); + $added = $this->money->add($balanceSpent, $spentTotal); + $outgoing->setBalance(EmbeddableMoney::of($added)); $outgoing->addFinancedBy($financement); $this->entityManager->persist($incoming); diff --git a/src/Mapping/Transformer/BudgetMapTransformer.php b/src/Mapping/Transformer/BudgetMapTransformer.php index c9af004..c9bdd15 100644 --- a/src/Mapping/Transformer/BudgetMapTransformer.php +++ b/src/Mapping/Transformer/BudgetMapTransformer.php @@ -2,6 +2,7 @@ namespace App\Mapping\Transformer; +use App\ApiResource\ApiMoney; use App\ApiResource\Project\Budget; use App\ApiResource\Project\BudgetSummary; use App\Entity\Project\BudgetItem; @@ -45,25 +46,25 @@ class BudgetMapTransformer implements PropertyTransformerInterface $summary = new BudgetSummary(); - $summary->money = $this->budgetService->calcBudget( + $summary->money = ApiMoney::of($this->budgetService->calcBudget( $items, $currency - )[$deadline]; + )[$deadline]); - $summary->task = $this->budgetService->calcBudget( + $summary->task = ApiMoney::of($this->budgetService->calcBudget( $this->filterItemsByType($items, BudgetItemType::Task), $currency - )[$deadline]; + )[$deadline]); - $summary->material = $this->budgetService->calcBudget( + $summary->material = ApiMoney::of($this->budgetService->calcBudget( $this->filterItemsByType($items, BudgetItemType::Material), $currency - )[$deadline]; + )[$deadline]); - $summary->infra = $this->budgetService->calcBudget( + $summary->infra = ApiMoney::of($this->budgetService->calcBudget( $this->filterItemsByType($items, BudgetItemType::Infrastructure), $currency - )[$deadline]; + )[$deadline]); return $summary; } diff --git a/src/Mapping/Transformer/SupportMoneyMapTransformer.php b/src/Mapping/Transformer/SupportMoneyMapTransformer.php index b5998aa..a6cccd2 100644 --- a/src/Mapping/Transformer/SupportMoneyMapTransformer.php +++ b/src/Mapping/Transformer/SupportMoneyMapTransformer.php @@ -2,9 +2,10 @@ namespace App\Mapping\Transformer; -use App\Entity\Money; +use App\ApiResource\ApiMoney; use App\Entity\Project\Support; -use App\Library\Economy\MoneyService; +use App\Money\Money; +use App\Money\MoneyService; use AutoMapper\Transformer\PropertyTransformer\PropertyTransformerInterface; class SupportMoneyMapTransformer implements PropertyTransformerInterface @@ -25,6 +26,6 @@ class SupportMoneyMapTransformer implements PropertyTransformerInterface $money = $this->moneyService->add($transaction->getMoney(), $money); } - return $money; + return ApiMoney::of($money); } } diff --git a/src/Matchfunding/Formula/FormulaInterface.php b/src/Matchfunding/Formula/FormulaInterface.php index 461ed26..499c83a 100644 --- a/src/Matchfunding/Formula/FormulaInterface.php +++ b/src/Matchfunding/Formula/FormulaInterface.php @@ -2,7 +2,8 @@ namespace App\Matchfunding\Formula; -use App\Entity\Money; +use App\Money\Money; +use App\Money\MoneyInterface; interface FormulaInterface { @@ -19,11 +20,11 @@ interface FormulaInterface /** * Process an input Money and obtain a delta Money, which is the Money to be given by the Matcher. * - * @param float $factor A matching factor for the formula to use - * @param Money $money The input Money that is to be matched - * @param Money $limit An upper bound for the matching formula, the delta won't be higher than this + * @param float $factor A matching factor for the formula to use + * @param MoneyInterface $money The input Money that is to be matched + * @param MoneyInterface $limit An upper bound for the matching formula, the delta won't be higher than this * * @return Money The output Money delta */ - public function match(float $factor, Money $money, Money $limit): Money; + public function match(float $factor, MoneyInterface $money, MoneyInterface $limit): Money; } diff --git a/src/Matchfunding/Formula/MultiplicationFormula.php b/src/Matchfunding/Formula/MultiplicationFormula.php index 105f5fa..a989a8a 100644 --- a/src/Matchfunding/Formula/MultiplicationFormula.php +++ b/src/Matchfunding/Formula/MultiplicationFormula.php @@ -2,8 +2,9 @@ namespace App\Matchfunding\Formula; -use App\Entity\Money; -use App\Library\Economy\MoneyService; +use App\Money\Money; +use App\Money\MoneyInterface; +use App\Money\MoneyService; class MultiplicationFormula implements FormulaInterface { @@ -17,12 +18,11 @@ class MultiplicationFormula implements FormulaInterface return 'min(factor * money, limit)'; } - public function match(float $factor, Money $money, Money $limit): Money + public function match(float $factor, MoneyInterface $money, MoneyInterface $limit): Money { $delta = \Brick\Money\Money::min( MoneyService::toBrick($limit), - MoneyService::toBrick($money) - ->multipliedBy($factor) + MoneyService::toBrick($money)->multipliedBy($factor) ); return MoneyService::toMoney($delta); diff --git a/src/Matchfunding/Formula/PercentageFormula.php b/src/Matchfunding/Formula/PercentageFormula.php index ecd1c0f..50328a5 100644 --- a/src/Matchfunding/Formula/PercentageFormula.php +++ b/src/Matchfunding/Formula/PercentageFormula.php @@ -2,8 +2,9 @@ namespace App\Matchfunding\Formula; -use App\Entity\Money; -use App\Library\Economy\MoneyService; +use App\Money\Money; +use App\Money\MoneyInterface; +use App\Money\MoneyService; class PercentageFormula implements FormulaInterface { @@ -17,13 +18,11 @@ class PercentageFormula implements FormulaInterface return 'min(factor * money / 100, limit)'; } - public function match(float $factor, Money $money, Money $limit): Money + public function match(float $factor, MoneyInterface $money, MoneyInterface $limit): Money { $delta = \Brick\Money\Money::min( MoneyService::toBrick($limit), - MoneyService::toBrick($money) - ->multipliedBy($factor) - ->dividedBy(100) + MoneyService::toBrick($money)->multipliedBy($factor)->dividedBy(100) ); return MoneyService::toMoney($delta); diff --git a/src/Library/Economy/Currency/EuropeanCentralBankExchange.php b/src/Money/Currency/EuropeanCentralBankExchange.php similarity index 96% rename from src/Library/Economy/Currency/EuropeanCentralBankExchange.php rename to src/Money/Currency/EuropeanCentralBankExchange.php index 976e247..e293acf 100644 --- a/src/Library/Economy/Currency/EuropeanCentralBankExchange.php +++ b/src/Money/Currency/EuropeanCentralBankExchange.php @@ -1,9 +1,10 @@ converter->convert( MoneyService::toBrick($money), diff --git a/src/Library/Economy/Currency/ExchangeInterface.php b/src/Money/Currency/ExchangeInterface.php similarity index 78% rename from src/Library/Economy/Currency/ExchangeInterface.php rename to src/Money/Currency/ExchangeInterface.php index a4c2aee..94fb469 100644 --- a/src/Library/Economy/Currency/ExchangeInterface.php +++ b/src/Money/Currency/ExchangeInterface.php @@ -1,8 +1,8 @@ getWeight() < $b->getWeight(); + return $a->getWeight() <=> $b->getWeight(); }); foreach ($exchanges as $exchange) { diff --git a/src/Library/Economy/Currency/FrankfurterExchange.php b/src/Money/Currency/FrankfurterExchange.php similarity index 91% rename from src/Library/Economy/Currency/FrankfurterExchange.php rename to src/Money/Currency/FrankfurterExchange.php index 5774d59..04fef52 100644 --- a/src/Library/Economy/Currency/FrankfurterExchange.php +++ b/src/Money/Currency/FrankfurterExchange.php @@ -1,9 +1,10 @@ converter = new CurrencyConverter($this->provider); } - public function convert(Money $money, string $toCurrency): Money + public function convert(MoneyInterface $money, string $toCurrency): MoneyInterface { $converted = $this->converter->convert( MoneyService::toBrick($money), diff --git a/src/Money/Money.php b/src/Money/Money.php new file mode 100644 index 0000000..d714474 --- /dev/null +++ b/src/Money/Money.php @@ -0,0 +1,21 @@ +amount; + } + + public function getCurrency(): string + { + return $this->currency; + } +} diff --git a/src/Money/MoneyInterface.php b/src/Money/MoneyInterface.php new file mode 100644 index 0000000..ed1f99a --- /dev/null +++ b/src/Money/MoneyInterface.php @@ -0,0 +1,16 @@ +getMinorAmount()->toInt(), @@ -20,17 +19,17 @@ class MoneyService ); } - public static function toBrick(Money $money): Brick\Money + public static function toBrick(MoneyInterface $money): BrickMoney { - return Brick\Money::ofMinor($money->amount, $money->currency); + return BrickMoney::ofMinor($money->getAmount(), $money->getCurrency()); } /** * Adds `a` to `b`. */ - public function add(Money $a, Money $b): Money + public function add(MoneyInterface $a, MoneyInterface $b): Money { - $a = $this->convert($a, $b->currency); + $a = $this->convert($a, $b->getCurrency()); $ab = self::toBrick($b)->plus($a); return self::toMoney($ab); @@ -39,9 +38,9 @@ class MoneyService /** * Substracts `a` from `b`. */ - public function substract(Money $a, Money $b): Money + public function substract(MoneyInterface $a, MoneyInterface $b): Money { - $a = $this->convert($a, $b->currency); + $a = $this->convert($a, $b->getCurrency()); $ab = self::toBrick($b)->minus($a); return self::toMoney($ab); @@ -52,9 +51,9 @@ class MoneyService * * @return bool `true` if `$money` is less than `$than` */ - public function isLess(Money $money, Money $than): bool + public function isLess(MoneyInterface $money, MoneyInterface $than): bool { - $money = $this->convert($money, $than->currency); + $money = $this->convert($money, $than->getCurrency()); return $money->isLessThan(self::toBrick($than)); } @@ -64,16 +63,16 @@ class MoneyService * * @return bool `true` if `$money` is more than or same as `$than` */ - public function isMoreOrSame(Money $money, Money $than): bool + public function isMoreOrSame(MoneyInterface $money, MoneyInterface $than): bool { - $money = $this->convert($money, $than->currency); + $money = $this->convert($money, $than->getCurrency()); return $money->isGreaterThanOrEqualTo(self::toBrick($than)); } - private function convert(Money $money, string $toCurrency): Brick\Money + private function convert(MoneyInterface $money, string $toCurrency): BrickMoney { - $fromCurrency = $money->currency; + $fromCurrency = $money->getCurrency(); if ($fromCurrency === $toCurrency) { return self::toBrick($money); } diff --git a/src/Repository/WalletFinancementRepository.php b/src/Repository/Wallet/WalletFinancementRepository.php similarity index 94% rename from src/Repository/WalletFinancementRepository.php rename to src/Repository/Wallet/WalletFinancementRepository.php index 0704d8c..aad9e74 100644 --- a/src/Repository/WalletFinancementRepository.php +++ b/src/Repository/Wallet/WalletFinancementRepository.php @@ -1,8 +1,8 @@ start = $lowerBound; $point->end = $upperBound; - $point->balance = $balance; + $point->balance = ApiMoney::of($balance); $point->length = count($transactions); return $point; diff --git a/src/Service/Project/BudgetService.php b/src/Service/Project/BudgetService.php index 4272f6e..fb9f24f 100644 --- a/src/Service/Project/BudgetService.php +++ b/src/Service/Project/BudgetService.php @@ -2,10 +2,10 @@ namespace App\Service\Project; -use App\Entity\Money; use App\Entity\Project\BudgetItem; use App\Entity\Project\ProjectDeadline; -use App\Library\Economy\MoneyService; +use App\Money\Money; +use App\Money\MoneyService; class BudgetService { diff --git a/src/Validator/EnoughRewardChargeValidator.php b/src/Validator/EnoughRewardChargeValidator.php index bbf4017..6880951 100644 --- a/src/Validator/EnoughRewardChargeValidator.php +++ b/src/Validator/EnoughRewardChargeValidator.php @@ -3,7 +3,7 @@ namespace App\Validator; use App\ApiResource\Project\RewardClaimApiResource; -use App\Library\Economy\MoneyService; +use App\Money\MoneyService; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; diff --git a/tests/Gateway/Wallet/WalletServiceTest.php b/tests/Gateway/Wallet/WalletServiceTest.php index d7c45c7..65ba9af 100644 --- a/tests/Gateway/Wallet/WalletServiceTest.php +++ b/tests/Gateway/Wallet/WalletServiceTest.php @@ -3,7 +3,7 @@ namespace App\Tests\Gateway\Wallet; use App\Entity\Accounting\Transaction; -use App\Entity\Money; +use App\Entity\EmbeddableMoney; use App\Entity\Tipjar; use App\Entity\User\User; use App\Gateway\Wallet\StatementDirection; @@ -62,19 +62,19 @@ class WalletServiceTest extends KernelTestCase $balance = $this->walletService->getBalance($user); - $this->assertEquals(0, $balance->amount); - $this->assertEquals($user->getCurrency(), $balance->currency); + $this->assertEquals(0, $balance->getAmount()); + $this->assertEquals($user->getCurrency(), $balance->getCurrency()); $incoming = new Transaction(); - $incoming->setMoney(new Money(100, 'EUR')); + $incoming->setMoney(new EmbeddableMoney(100, 'EUR')); $incoming->setOrigin($tipjar); $incoming->setTarget($user); $income = $this->walletService->save($incoming); - $this->assertEquals(100, $income->getBalance()->amount); + $this->assertEquals(100, $income->getBalance()->getAmount()); $this->assertEquals(StatementDirection::Incoming->value, $income->getDirection()->value); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals('EUR', $balance->getCurrency()); $this->assertCount(0, $income->getFinancesTo()); $this->assertCount(0, $income->getFinancedBy()); @@ -83,17 +83,17 @@ class WalletServiceTest extends KernelTestCase $balance = $this->walletService->getBalance($user); - $this->assertEquals(100, $balance->amount); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals(100, $balance->getAmount()); + $this->assertEquals('EUR', $balance->getCurrency()); $statements = $this->walletService->getStatements($user); $this->assertCount(1, $statements); $statement = $statements[0]; - $this->assertEquals(100, $statement->getBalance()->amount); + $this->assertEquals(100, $statement->getBalance()->getAmount()); $this->assertEquals(StatementDirection::Incoming->value, $statement->getDirection()->value); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals('EUR', $balance->getCurrency()); $this->assertCount(0, $statement->getFinancesTo()); $this->assertCount(0, $statement->getFinancedBy()); } @@ -109,11 +109,11 @@ class WalletServiceTest extends KernelTestCase $balance = $this->walletService->getBalance($user); - $this->assertEquals(0, $balance->amount); - $this->assertEquals($user->getCurrency(), $balance->currency); + $this->assertEquals(0, $balance->getAmount()); + $this->assertEquals($user->getCurrency(), $balance->getCurrency()); $incoming = new Transaction(); - $incoming->setMoney(new Money(100, 'EUR')); + $incoming->setMoney(new EmbeddableMoney(100, 'EUR')); $incoming->setOrigin($tipjar); $incoming->setTarget($user); @@ -122,17 +122,17 @@ class WalletServiceTest extends KernelTestCase $balance = $this->walletService->getBalance($user); - $this->assertEquals(100, $balance->amount); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals(100, $balance->getAmount()); + $this->assertEquals('EUR', $balance->getCurrency()); $statements = $this->walletService->getStatements($user); $this->assertCount(1, $statements); $statement = $statements[0]; - $this->assertEquals(100, $statement->getBalance()->amount); + $this->assertEquals(100, $statement->getBalance()->getAmount()); $this->assertEquals(StatementDirection::Incoming->value, $statement->getDirection()->value); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals('EUR', $balance->getCurrency()); $this->assertCount(0, $statement->getFinancesTo()); $this->assertCount(0, $statement->getFinancedBy()); } @@ -143,7 +143,7 @@ class WalletServiceTest extends KernelTestCase $user = $this->getUser()->getAccounting(); $incoming = new Transaction(); - $incoming->setMoney(new Money(100, 'EUR')); + $incoming->setMoney(new EmbeddableMoney(100, 'EUR')); $incoming->setOrigin($tipjar); $incoming->setTarget($user); @@ -151,7 +151,7 @@ class WalletServiceTest extends KernelTestCase $this->entityManager->flush(); $outgoing = new Transaction(); - $outgoing->setMoney(new Money(20, 'EUR')); + $outgoing->setMoney(new EmbeddableMoney(20, 'EUR')); $outgoing->setOrigin($user); $outgoing->setTarget($tipjar); @@ -162,29 +162,29 @@ class WalletServiceTest extends KernelTestCase $balance = $this->walletService->getBalance($user); - $this->assertEquals(80, $balance->amount); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals(80, $balance->getAmount()); + $this->assertEquals('EUR', $balance->getCurrency()); $statements = $this->walletService->getStatements($user); $this->assertCount(2, $statements); $statement = $statements[0]; - $this->assertEquals(80, $statement->getBalance()->amount); + $this->assertEquals(80, $statement->getBalance()->getAmount()); $this->assertEquals(StatementDirection::Incoming->value, $statement->getDirection()->value); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals('EUR', $balance->getCurrency()); $this->assertCount(1, $statement->getFinancesTo()); $this->assertCount(0, $statement->getFinancedBy()); $statement = $statements[1]; - $this->assertEquals(20, $statement->getBalance()->amount); + $this->assertEquals(20, $statement->getBalance()->getAmount()); $this->assertEquals(StatementDirection::Outgoing->value, $statement->getDirection()->value); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals('EUR', $balance->getCurrency()); $this->assertCount(0, $statement->getFinancesTo()); $this->assertCount(1, $statement->getFinancedBy()); $outgoing = new Transaction(); - $outgoing->setMoney(new Money(30, 'EUR')); + $outgoing->setMoney(new EmbeddableMoney(30, 'EUR')); $outgoing->setOrigin($user); $outgoing->setTarget($tipjar); @@ -195,43 +195,43 @@ class WalletServiceTest extends KernelTestCase $balance = $this->walletService->getBalance($user); - $this->assertEquals(50, $balance->amount); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals(50, $balance->getAmount()); + $this->assertEquals('EUR', $balance->getCurrency()); $statements = $this->walletService->getStatements($user); $this->assertCount(3, $statements); $statement = $statements[0]; - $this->assertEquals(50, $statement->getBalance()->amount); + $this->assertEquals(50, $statement->getBalance()->getAmount()); $this->assertEquals(StatementDirection::Incoming->value, $statement->getDirection()->value); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals('EUR', $balance->getCurrency()); $this->assertCount(2, $statement->getFinancesTo()); $this->assertCount(0, $statement->getFinancedBy()); $statement = $statements[1]; - $this->assertEquals(20, $statement->getBalance()->amount); + $this->assertEquals(20, $statement->getBalance()->getAmount()); $this->assertEquals(StatementDirection::Outgoing->value, $statement->getDirection()->value); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals('EUR', $balance->getCurrency()); $this->assertCount(0, $statement->getFinancesTo()); $this->assertCount(1, $statement->getFinancedBy()); $financement = $statements[0]->getFinancesTo()[0]; - $this->assertEquals(20, $financement->getMoney()->amount); - $this->assertEquals('EUR', $financement->getMoney()->currency); + $this->assertEquals(20, $financement->getMoney()->getAmount()); + $this->assertEquals('EUR', $financement->getMoney()->getCurrency()); $this->assertSame($financement, $statement->getFinancedBy()[0]); $this->assertEquals($financement->getId(), $statement->getFinancedBy()[0]->getId()); $statement = $statements[2]; - $this->assertEquals(30, $statement->getBalance()->amount); + $this->assertEquals(30, $statement->getBalance()->getAmount()); $this->assertEquals(StatementDirection::Outgoing->value, $statement->getDirection()->value); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals('EUR', $balance->getCurrency()); $this->assertCount(0, $statement->getFinancesTo()); $this->assertCount(1, $statement->getFinancedBy()); $financement = $statements[0]->getFinancesTo()[1]; - $this->assertEquals(30, $financement->getMoney()->amount); - $this->assertEquals('EUR', $financement->getMoney()->currency); + $this->assertEquals(30, $financement->getMoney()->getAmount()); + $this->assertEquals('EUR', $financement->getMoney()->getCurrency()); $this->assertSame($financement, $statement->getFinancedBy()[0]); $this->assertEquals($financement->getId(), $statement->getFinancedBy()[0]->getId()); } @@ -242,7 +242,7 @@ class WalletServiceTest extends KernelTestCase $user = $this->getUser()->getAccounting(); $incoming = new Transaction(); - $incoming->setMoney(new Money(10, 'EUR')); + $incoming->setMoney(new EmbeddableMoney(10, 'EUR')); $incoming->setOrigin($tipjar); $incoming->setTarget($user); @@ -250,7 +250,7 @@ class WalletServiceTest extends KernelTestCase $this->entityManager->flush(); $incoming = new Transaction(); - $incoming->setMoney(new Money(11, 'EUR')); + $incoming->setMoney(new EmbeddableMoney(11, 'EUR')); $incoming->setOrigin($tipjar); $incoming->setTarget($user); @@ -258,7 +258,7 @@ class WalletServiceTest extends KernelTestCase $this->entityManager->flush(); $outgoing = new Transaction(); - $outgoing->setMoney(new Money(12, 'EUR')); + $outgoing->setMoney(new EmbeddableMoney(12, 'EUR')); $outgoing->setOrigin($user); $outgoing->setTarget($tipjar); @@ -268,7 +268,7 @@ class WalletServiceTest extends KernelTestCase $this->entityManager->flush(); $incoming = new Transaction(); - $incoming->setMoney(new Money(13, 'EUR')); + $incoming->setMoney(new EmbeddableMoney(13, 'EUR')); $incoming->setOrigin($tipjar); $incoming->setTarget($user); @@ -277,38 +277,38 @@ class WalletServiceTest extends KernelTestCase $balance = $this->walletService->getBalance($user); - $this->assertEquals(22, $balance->amount); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals(22, $balance->getAmount()); + $this->assertEquals('EUR', $balance->getCurrency()); $statements = $this->walletService->getStatements($user); $this->assertCount(4, $statements); $statement = $statements[0]; - $this->assertEquals(0, $statement->getBalance()->amount); + $this->assertEquals(0, $statement->getBalance()->getAmount()); $this->assertEquals(StatementDirection::Incoming->value, $statement->getDirection()->value); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals('EUR', $balance->getCurrency()); $this->assertCount(1, $statement->getFinancesTo()); $this->assertCount(0, $statement->getFinancedBy()); $statement = $statements[1]; - $this->assertEquals(9, $statement->getBalance()->amount); + $this->assertEquals(9, $statement->getBalance()->getAmount()); $this->assertEquals(StatementDirection::Incoming->value, $statement->getDirection()->value); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals('EUR', $balance->getCurrency()); $this->assertCount(1, $statement->getFinancesTo()); $this->assertCount(0, $statement->getFinancedBy()); $statement = $statements[2]; - $this->assertEquals(12, $statement->getBalance()->amount); + $this->assertEquals(12, $statement->getBalance()->getAmount()); $this->assertEquals(StatementDirection::Outgoing->value, $statement->getDirection()->value); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals('EUR', $balance->getCurrency()); $this->assertCount(0, $statement->getFinancesTo()); $this->assertCount(2, $statement->getFinancedBy()); $statement = $statements[3]; - $this->assertEquals(13, $statement->getBalance()->amount); + $this->assertEquals(13, $statement->getBalance()->getAmount()); $this->assertEquals(StatementDirection::Incoming->value, $statement->getDirection()->value); - $this->assertEquals('EUR', $balance->currency); + $this->assertEquals('EUR', $balance->getCurrency()); $this->assertCount(0, $statement->getFinancesTo()); $this->assertCount(0, $statement->getFinancedBy()); } diff --git a/tests/Library/Economy/Currency/EuropeanCentralBankExchangeTest.php b/tests/Library/Economy/Currency/EuropeanCentralBankExchangeTest.php index bebbe84..9097391 100644 --- a/tests/Library/Economy/Currency/EuropeanCentralBankExchangeTest.php +++ b/tests/Library/Economy/Currency/EuropeanCentralBankExchangeTest.php @@ -2,7 +2,7 @@ namespace App\Tests\Library\Economy\Currency; -use App\Library\Economy\Currency\EuropeanCentralBankExchange; +use App\Money\Currency\EuropeanCentralBankExchange; use PHPUnit\Framework\TestCase; use Symfony\Component\Cache\Adapter\FilesystemAdapter; diff --git a/tests/Library/Economy/MoneyServiceTest.php b/tests/Library/Economy/MoneyServiceTest.php index 2ad6b97..8255e08 100644 --- a/tests/Library/Economy/MoneyServiceTest.php +++ b/tests/Library/Economy/MoneyServiceTest.php @@ -2,8 +2,8 @@ namespace App\Tests\Library\Economy; -use App\Entity\Money; -use App\Library\Economy\MoneyService; +use App\Money\Money; +use App\Money\MoneyService; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; /** @@ -64,17 +64,17 @@ class MoneyServiceTest extends KernelTestCase $c = $this->moneyService->add($a, $b); - $this->assertEquals(100, $a->amount); - $this->assertEquals(110, $b->amount); - $this->assertEquals(210, $c->amount); + $this->assertEquals(100, $a->getAmount()); + $this->assertEquals(110, $b->getAmount()); + $this->assertEquals(210, $c->getAmount()); $d = new Money(100, 'USD'); $e = $this->moneyService->add($a, $d); - $this->assertEquals($d->amount, $a->amount); - $this->assertEquals($d->currency, $e->currency); + $this->assertEquals($d->getAmount(), $a->getAmount()); + $this->assertEquals($d->getCurrency(), $e->getCurrency()); - $this->assertNotEquals($d->amount, $e->amount); + $this->assertNotEquals($d->getAmount(), $e->getAmount()); $this->assertTrue($this->moneyService->isMoreOrSame($e, $d)); $this->assertTrue($this->moneyService->isMoreOrSame($e, $a)); } @@ -86,16 +86,16 @@ class MoneyServiceTest extends KernelTestCase $c = $this->moneyService->substract($a, $b); - $this->assertEquals(101, $a->amount); - $this->assertEquals(210, $b->amount); - $this->assertEquals(109, $c->amount); + $this->assertEquals(101, $a->getAmount()); + $this->assertEquals(210, $b->getAmount()); + $this->assertEquals(109, $c->getAmount()); $d = new Money(500, 'USD'); $e = $this->moneyService->substract($a, $d); - $this->assertEquals($d->currency, $e->currency); + $this->assertEquals($d->getCurrency(), $e->getCurrency()); - $this->assertNotEquals($d->amount, $e->amount); + $this->assertNotEquals($d->getAmount(), $e->getAmount()); $this->assertTrue($this->moneyService->isLess($e, $d)); $this->assertTrue($this->moneyService->isMoreOrSame($e, $a)); } diff --git a/tests/Service/AccountingServiceTest.php b/tests/Service/AccountingServiceTest.php index 097952b..8585a54 100644 --- a/tests/Service/AccountingServiceTest.php +++ b/tests/Service/AccountingServiceTest.php @@ -4,7 +4,7 @@ namespace App\Tests\Service; use App\ApiResource\Accounting\AccountingBalancePoint; use App\Entity\Accounting\Transaction; -use App\Entity\Money; +use App\Entity\EmbeddableMoney; use App\Entity\Tipjar; use App\Service\AccountingService; use Doctrine\ORM\EntityManagerInterface; @@ -46,7 +46,7 @@ class AccountingServiceTest extends KernelTestCase $target = $i % 2 ? $tipjars[\random_int(5, 9)] : $tipjars[\random_int(0, 5)]; $trx = new Transaction(); - $trx->setMoney(new Money(random_int(100, 999), 'EUR')); + $trx->setMoney(new EmbeddableMoney(random_int(100, 999), 'EUR')); $trx->setOrigin($origin->getAccounting()); $trx->setTarget($target->getAccounting());