Skip to content
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
Binary file added composer.phar
Binary file not shown.
70 changes: 66 additions & 4 deletions src/Bll/StatementBLL.php
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ public function reserveFundsForDeposit(StatementDTO $dto): ?int
* Accept a reserved fund and update gross balance
*
* @param int $statementId
* @param null $statementDto
* @param StatementDTO|null $statementDto
* @return int Statement ID
* @throws InvalidArgumentException
* @throws OrmBeforeInvalidException
Expand All @@ -296,7 +296,7 @@ public function reserveFundsForDeposit(StatementDTO $dto): ?int
* @throws UpdateConstraintException
* @throws \ByJG\MicroOrm\Exception\InvalidArgumentException
*/
public function acceptFundsById(int $statementId, $statementDto = null): int
public function acceptFundsById(int $statementId, ?StatementDTO $statementDto = null): int
{
if (is_null($statementDto)) {
$statementDto = StatementDTO::createEmpty();
Expand Down Expand Up @@ -351,11 +351,73 @@ public function acceptFundsById(int $statementId, $statementDto = null): int
}
}

/**
* @param int $statementId
* @param StatementDTO|null $statementDto
* @return int|null
* @throws AccountException
* @throws AmountException
* @throws InvalidArgumentException
* @throws OrmBeforeInvalidException
* @throws OrmInvalidFieldsException
* @throws RepositoryReadOnlyException
* @throws StatementException
* @throws UpdateConstraintException
* @throws \ByJG\MicroOrm\Exception\InvalidArgumentException
*/
public function acceptPartialFundsById(int $statementId, ?StatementDTO $statementDto): ?int
{
if (is_null($statementDto)) {
throw new StatementException('acceptPartialFundsById: StatementDTO cannot be null.');
}

$partialAmount = $statementDto->getAmount();

if ($partialAmount <= 0) {
throw new AmountException('Partial amount must be greater than zero.');
}

$this->getRepository()->getDbDriver()->beginTransaction(IsolationLevelEnum::SERIALIZABLE, true);
try {
$statement = $this->statementRepository->getById($statementId);
if (is_null($statement)) {
throw new StatementException('acceptPartialFundsById: Statement not found');
}
if ($statement->getTypeId() != StatementEntity::WITHDRAW_BLOCKED) {
throw new StatementException("The statement id doesn't belong to a reserved withdraw fund.");
}
if ($this->statementRepository->getByParentId($statementId) != null) {
throw new StatementException('The statement has been processed already');
}

$originalAmount = $statement->getAmount();
if ($partialAmount <= 0 || $partialAmount >= $originalAmount) {
throw new AmountException(
'Partial amount must be greater than zero and less than the original reserved amount.'
);
}

$this->rejectFundsById($statementId, StatementDTO::createEmpty()->setDescription('Reversal of partial acceptance for reserve ' . $statementId));

$statementDto->setAccountId($statement->getAccountId());

$finalDebitStatementId = $this->withdrawFunds($statementDto);

$this->getRepository()->getDbDriver()->commitTransaction();

return $finalDebitStatementId;

} catch (Exception $ex) {
$this->getRepository()->getDbDriver()->rollbackTransaction();
throw $ex;
}
Comment thread
byjg marked this conversation as resolved.
}

/**
* Reject a reserved fund and return the net balance
*
* @param int $statementId
* @param null $statementDto
* @param StatementDTO|null $statementDto
* @return int Statement ID
* @throws InvalidArgumentException
* @throws OrmBeforeInvalidException
Expand All @@ -365,7 +427,7 @@ public function acceptFundsById(int $statementId, $statementDto = null): int
* @throws UpdateConstraintException
* @throws \ByJG\MicroOrm\Exception\InvalidArgumentException
*/
public function rejectFundsById(int $statementId, $statementDto = null): int
public function rejectFundsById(int $statementId, ?StatementDTO $statementDto = null): int
{
if (is_null($statementDto)) {
$statementDto = StatementDTO::createEmpty();
Expand Down
73 changes: 73 additions & 0 deletions tests/Database/ReserveFundsDepositTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,79 @@ public function testAcceptFundsById_OK()
$this->assertEquals($statement->toArray(), $actual->toArray());
}

public function testAcceptPartialFundsById_StatementDTONull()
{
$this->expectException(StatementException::class);

$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
$reserveStatementId = $this->statementBLL->reserveFundsForWithdraw(
StatementDTO::create($accountId, 100)
);

$this->statementBLL->acceptPartialFundsById($reserveStatementId, null);
}

public function testAcceptPartialFundsById_PartialAmountZero()
{
$this->expectException(AmountException::class);

$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
$reserveStatementId = $this->statementBLL->reserveFundsForWithdraw(
StatementDTO::create($accountId, 100)
);

$statementDTO = StatementDTO::createEmpty()->setAmount(0);
$this->statementBLL->acceptPartialFundsById($reserveStatementId, $statementDTO);
}

public function testAcceptPartialFundsById_AmountMoreThanWithdrawBlocked()
{
$this->expectException(AmountException::class);
$this->expectExceptionMessage('Partial amount must be greater than zero and less than the original reserved amount.');

$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
$reserveStatementId = $this->statementBLL->reserveFundsForWithdraw(
StatementDTO::create($accountId, 100)
);

$statementDTO = StatementDTO::createEmpty()->setAmount(100.01);
$this->statementBLL->acceptPartialFundsById($reserveStatementId, $statementDTO);
}

public function testAcceptPartialFundsById_OK()
{
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
$reserveStatementId = $this->statementBLL->reserveFundsForWithdraw(
StatementDTO::create($accountId, 100)->setDescription('Reserva para Aposta')
);

$statementDTO = StatementDTO::createEmpty()
->setAmount(80.00)
->setDescription("Deposit")
->setReferenceSource("test-source");

$finalDebitStatementId = $this->statementBLL->acceptPartialFundsById(
$reserveStatementId,
$statementDTO
);

$accountAfter = $this->accountBLL->getById($accountId);
$this->assertEquals('920.00', $accountAfter->getGrossBalance());
$this->assertEquals('920.00', $accountAfter->getNetBalance());
$this->assertEquals('0.00', $accountAfter->getUnCleared());

$rejectedStatement = $this->statementBLL->getRepository()->getByParentId($reserveStatementId);
$this->assertNotNull($rejectedStatement);
$this->assertEquals(StatementEntity::REJECT, $rejectedStatement->getTypeId());
$this->assertEquals('100.00', $rejectedStatement->getAmount());

/** @var StatementEntity $finalDebitStatement */
$finalDebitStatement = $this->statementBLL->getById($finalDebitStatementId);
$this->assertEquals('80.00', $finalDebitStatement->getAmount());
$this->assertEquals(StatementEntity::WITHDRAW, $finalDebitStatement->getTypeId());
$this->assertEquals("Deposit", $finalDebitStatement->getDescription());
}

public function testRejectFundsById_InvalidType()
{
$this->expectException(StatementException::class);
Expand Down