Pass WalletGatewayServiceTest
This commit is contained in:
@@ -3,42 +3,113 @@
|
||||
namespace App\Library\Economy\Payment;
|
||||
|
||||
use App\Entity\Accounting;
|
||||
use App\Entity\AccountingTransaction;
|
||||
use App\Entity\Money;
|
||||
use App\Entity\WalletStatement;
|
||||
use App\Entity\WalletStatementDirection;
|
||||
use App\Library\Economy\MoneyService;
|
||||
use App\Repository\WalletStatementRepository;
|
||||
use Brick\Money as Brick;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
class WalletGatewayService
|
||||
{
|
||||
public function __construct(
|
||||
private MoneyService $money,
|
||||
private WalletStatementRepository $walletStatementRepository,
|
||||
private EntityManagerInterface $entityManager,
|
||||
) {}
|
||||
|
||||
public function getAccountingBalance(Accounting $accounting): Money
|
||||
/**
|
||||
* @return \App\Entity\WalletStatement[]
|
||||
*/
|
||||
public function getStatements(Accounting $accounting): array
|
||||
{
|
||||
$available = Brick\Money::ofMinor(0, $accounting->getCurrency());
|
||||
$statements = $this->walletStatementRepository->findByAccounting($accounting);
|
||||
return $this->walletStatementRepository->findByAccounting($accounting);
|
||||
}
|
||||
|
||||
public function getBalance(Accounting $accounting): Money
|
||||
{
|
||||
$total = Brick\Money::ofMinor(0, $accounting->getCurrency());
|
||||
$statements = $this->getStatements($accounting);
|
||||
|
||||
foreach ($statements as $statement) {
|
||||
$transaction = $statement->getTransaction();
|
||||
$money = Brick\Money::ofMinor(
|
||||
$transaction->getMoney()->amount,
|
||||
$transaction->getMoney()->currency
|
||||
);
|
||||
$transacted = $this->money->toBrick($statement->getTransaction()->getMoney());
|
||||
|
||||
switch ($statement->getDirection()) {
|
||||
case WalletStatementDirection::Incoming:
|
||||
$available = $available->plus($money);
|
||||
$total = $total->plus($transacted);
|
||||
break;
|
||||
case WalletStatementDirection::Outgoing:
|
||||
$available = $available->minus($money);
|
||||
$total = $total->minus($transacted);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new Money(
|
||||
$available->getMinorAmount()->toInt(),
|
||||
$available->getCurrency()->getCurrencyCode()
|
||||
);
|
||||
return $this->money->toMoney($total);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the money of a Transaction into the target wallet.
|
||||
*
|
||||
* @param AccountingTransaction $transaction The Transaction targetting a wallet
|
||||
* @return \App\Entity\WalletStatement An incoming statement for the target wallet
|
||||
*/
|
||||
public function save(AccountingTransaction $transaction): WalletStatement
|
||||
{
|
||||
$statement = new WalletStatement();
|
||||
$statement->setTransaction($transaction);
|
||||
$statement->setDirection(WalletStatementDirection::Incoming);
|
||||
$statement->setBalance($transaction->getMoney());
|
||||
|
||||
$this->entityManager->persist($statement);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the money of a Transaction from the origin wallet.
|
||||
*
|
||||
* @param AccountingTransaction $transaction The Transaction originating from a wallet
|
||||
* @return \App\Entity\WalletStatement An outgoing statement financed by previous incoming statements
|
||||
*/
|
||||
public function spend(AccountingTransaction $transaction): WalletStatement
|
||||
{
|
||||
$origin = $transaction->getOrigin();
|
||||
$toSpend = $transaction->getMoney();
|
||||
|
||||
$outgoing = new WalletStatement();
|
||||
$outgoing->setTransaction($transaction);
|
||||
$outgoing->setDirection(WalletStatementDirection::Outgoing);
|
||||
|
||||
$incomings = $this->getStatements($origin);
|
||||
foreach ($incomings as $incoming) {
|
||||
$spent = new Money(0, $toSpend->currency);
|
||||
$balance = $incoming->getBalance();
|
||||
|
||||
if ($balance->amount === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->money->isMoreOrSame($balance, $spent)) {
|
||||
$spent = $toSpend;
|
||||
} else {
|
||||
$spent = $this->money->add($balance, $spent);
|
||||
}
|
||||
|
||||
$balance = $this->money->substract($spent, $balance);
|
||||
|
||||
$incoming->setBalance($balance);
|
||||
|
||||
$outgoing->setBalance($spent);
|
||||
$outgoing->addFinancedBy($incoming);
|
||||
|
||||
$this->entityManager->persist($incoming);
|
||||
$this->entityManager->persist($outgoing);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $outgoing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user