diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml
index 7e05d60..e2bd483 100644
--- a/.github/workflows/phpunit.yml
+++ b/.github/workflows/phpunit.yml
@@ -50,5 +50,6 @@ jobs:
with:
folder: php
project: ${{ github.event.repository.name }}
- secrets: inherit
+ secrets:
+ DOC_TOKEN: ${{ secrets.DOC_TOKEN }}
diff --git a/README.md b/README.md
index 5f5d281..95c0ea6 100644
--- a/README.md
+++ b/README.md
@@ -61,10 +61,10 @@ $statementBLL->withdrawFunds($statement);
// Add 50 USD hold to the account
$statement = new StatementDTO($accountId, 50);
-$statementId = $statementBLL->reserveFundsForDeposit($statement);
+$reserve = $statementBLL->reserveFundsForDeposit($statement);
// Accept the hold
-$statementBLL->acceptFundsById($statementId);
+$statementBLL->acceptFundsById($reserve->getStatementId());
```
## Installation
diff --git a/composer.phar b/composer.phar
deleted file mode 100644
index bb6ba64..0000000
Binary files a/composer.phar and /dev/null differ
diff --git a/db/migrations/down/00002-delete-laststatementid.sql b/db/migrations/down/00002-delete-laststatementid.sql
new file mode 100644
index 0000000..cd9317c
--- /dev/null
+++ b/db/migrations/down/00002-delete-laststatementid.sql
@@ -0,0 +1,2 @@
+alter table account
+ drop column laststatementid;
diff --git a/db/migrations/down/00003-delete-constraint.sql b/db/migrations/down/00003-delete-constraint.sql
new file mode 100644
index 0000000..1409149
--- /dev/null
+++ b/db/migrations/down/00003-delete-constraint.sql
@@ -0,0 +1,5 @@
+ALTER TABLE statement
+ DROP CONSTRAINT statement_chk_value_nonnegative;
+
+ALTER TABLE account
+ DROP CONSTRAINT account_chk_value_nonnegative;
\ No newline at end of file
diff --git a/db/migrations/up/00003-add-laststatementid.sql b/db/migrations/up/00003-add-laststatementid.sql
new file mode 100644
index 0000000..a2b585c
--- /dev/null
+++ b/db/migrations/up/00003-add-laststatementid.sql
@@ -0,0 +1,3 @@
+alter table account
+ add laststatementid int null;
+
diff --git a/db/migrations/up/00004-add-constraint.sql b/db/migrations/up/00004-add-constraint.sql
new file mode 100644
index 0000000..41e39d1
--- /dev/null
+++ b/db/migrations/up/00004-add-constraint.sql
@@ -0,0 +1,8 @@
+ALTER TABLE statement
+ ADD CONSTRAINT statement_chk_value_nonnegative
+ CHECK (netbalance >= 0);
+
+ALTER TABLE account
+ ADD CONSTRAINT account_chk_value_nonnegative
+ CHECK (netbalance >= 0);
+
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index a5ebdfc..93529d8 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -4,34 +4,21 @@ To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
-
-
-
-
-
-
-
-
-
-
-
-
- ./src
-
-
-
-
-
- ./tests/
-
-
-
-
\ No newline at end of file
+
+
+
+ ./src
+
+
+
+
+
+
+
+
+
+ ./tests/
+
+
+
diff --git a/src/Bll/AccountBLL.php b/src/Bll/AccountBLL.php
index a5ae1da..c1d3942 100644
--- a/src/Bll/AccountBLL.php
+++ b/src/Bll/AccountBLL.php
@@ -254,30 +254,26 @@ public function closeAccount(int $accountId): ?int
* @param int $accountId
* @param float $balance
* @param string $description
- * @return int|null
+ * @return StatementEntity
* @throws AccountException
* @throws AmountException
* @throws InvalidArgumentException
- * @throws OrmBeforeInvalidException
- * @throws OrmInvalidFieldsException
- * @throws RepositoryReadOnlyException
* @throws StatementException
- * @throws UpdateConstraintException
* @throws \ByJG\MicroOrm\Exception\InvalidArgumentException
*/
- public function partialBalance(int $accountId, float $balance, string $description = "Partial Balance"): ?int
+ public function partialBalance(int $accountId, float $balance, string $description = "Partial Balance"): StatementEntity
{
$account = $this->getById($accountId);
$amount = $balance - $account->getNetBalance();
if ($amount >= 0) {
- $statementId = $this->statementBLL->addFunds(StatementDTO::create($accountId, $amount)->setDescription($description));
+ $statement = $this->statementBLL->addFunds(StatementDTO::create($accountId, $amount)->setDescription($description));
} else {
- $statementId = $this->statementBLL->withdrawFunds(StatementDTO::create($accountId, abs($amount))->setDescription($description));
+ $statement = $this->statementBLL->withdrawFunds(StatementDTO::create($accountId, abs($amount))->setDescription($description));
}
- return $statementId;
+ return $statement;
}
/**
@@ -288,11 +284,7 @@ public function partialBalance(int $accountId, float $balance, string $descripti
* @throws AccountException
* @throws AmountException
* @throws InvalidArgumentException
- * @throws OrmBeforeInvalidException
- * @throws OrmInvalidFieldsException
- * @throws RepositoryReadOnlyException
* @throws StatementException
- * @throws UpdateConstraintException
* @throws \ByJG\MicroOrm\Exception\InvalidArgumentException
*/
public function transferFunds(int $accountSource, int $accountTarget, float $amount): array
@@ -315,10 +307,10 @@ public function transferFunds(int $accountSource, int $accountTarget, float $amo
$statementTargetDTO->setReferenceId($refSource);
$statementTargetDTO->setDescription('Transfer from account id ' . $accountSource);
- $statementSourceId = $this->statementBLL->withdrawFunds($statementSourceDTO);
- $statementTargetId = $this->statementBLL->addFunds($statementTargetDTO);
+ $statementSource = $this->statementBLL->withdrawFunds($statementSourceDTO);
+ $statementTarget = $this->statementBLL->addFunds($statementTargetDTO);
- return [ $statementSourceId, $statementTargetId ];
+ return [ $statementSource, $statementTarget ];
}
public function getRepository(): AccountRepository
diff --git a/src/Bll/AccountTypeBLL.php b/src/Bll/AccountTypeBLL.php
index c4afd08..c6d2aa9 100644
--- a/src/Bll/AccountTypeBLL.php
+++ b/src/Bll/AccountTypeBLL.php
@@ -31,10 +31,10 @@ public function __construct(AccountTypeRepository $accountTypeRepository)
* Se o ID não for passado, então devolve todos os AccountTypes.
*
* @param string $accountTypeId Opcional. Se não for passado obtém todos
- * @return AccountTypeEntity|AccountTypeEntity[]
+ * @return AccountTypeEntity|AccountTypeEntity[]|null
* @throws \ByJG\MicroOrm\Exception\InvalidArgumentException
*/
- public function getById(string $accountTypeId): array|AccountTypeEntity
+ public function getById(string $accountTypeId): array|AccountTypeEntity|null
{
return $this->accountTypeRepository->getById($accountTypeId);
}
diff --git a/src/Bll/StatementBLL.php b/src/Bll/StatementBLL.php
index 3b7d161..02846dc 100644
--- a/src/Bll/StatementBLL.php
+++ b/src/Bll/StatementBLL.php
@@ -3,7 +3,6 @@
namespace ByJG\AccountStatements\Bll;
use ByJG\AccountStatements\DTO\StatementDTO;
-use ByJG\AccountStatements\Entity\AccountEntity;
use ByJG\AccountStatements\Entity\StatementEntity;
use ByJG\AccountStatements\Exception\AccountException;
use ByJG\AccountStatements\Exception\AmountException;
@@ -15,9 +14,12 @@
use ByJG\MicroOrm\Exception\OrmInvalidFieldsException;
use ByJG\MicroOrm\Exception\RepositoryReadOnlyException;
use ByJG\MicroOrm\Exception\UpdateConstraintException;
+use ByJG\MicroOrm\InsertSelectQuery;
+use ByJG\MicroOrm\ORMSubject;
+use ByJG\MicroOrm\Query;
+use ByJG\MicroOrm\UpdateQuery;
use ByJG\Serializer\Exception\InvalidArgumentException;
use Exception;
-use KingPandaApi\Model\StatementCodes;
class StatementBLL
{
@@ -54,233 +56,331 @@ public function getById(int|string $statementId): mixed
return $this->statementRepository->getById($statementId);
}
+ protected function validateStatementDto(StatementDTO $dto): void
+ {
+ if (!$dto->hasAccount()) {
+ throw new StatementException('Account is required');
+ }
+ if ($dto->getAmount() < 0) {
+ throw new AmountException('Amount needs to be greater than zero');
+ }
+
+ if (round($dto->getAmount()*100)/100 != $dto->getAmount()) {
+ throw new AmountException('Amount needs to have two decimal places');
+ }
+ }
+
/**
- * Add funds to an account
+ * Central method to apply a balance-changing operation.
+ * - Creates a new statement row reflecting the post-operation balances
+ * - Updates the account with the same balances and the last statement id
*
- * @param StatementDTO $dto
- * @return int|null Statement ID
+ * @param string $operation One of StatementEntity::DEPOSIT, WITHDRAW, DEPOSIT_BLOCKED, WITHDRAW_BLOCKED
+ * @param StatementDTO $dto Input data (account, amount, description, etc.)
+ * @param bool $capAtZero When true and operation is WITHDRAW, caps the withdrawal so net balance never goes below zero
+ * @return StatementEntity
* @throws AccountException
* @throws AmountException
* @throws InvalidArgumentException
- * @throws OrmBeforeInvalidException
- * @throws OrmInvalidFieldsException
- * @throws RepositoryReadOnlyException
* @throws StatementException
- * @throws UpdateConstraintException
* @throws \ByJG\MicroOrm\Exception\InvalidArgumentException
*/
- public function addFunds(StatementDTO $dto): ?int
+ protected function updateFunds(string $operation, StatementDTO $dto, bool $capAtZero = false): StatementEntity
{
- // Validations
$this->validateStatementDto($dto);
- // Get an Account
- $this->getRepository()->getDbDriver()->beginTransaction(IsolationLevelEnum::SERIALIZABLE, true);
- try {
- $account = $this->accountRepository->getById($dto->getAccountId());
- if (is_null($account) || $account->getAccountId() == "") {
- throw new AccountException("addFunds: Account " . $dto->getAccountId() . " not found");
- }
+ // 1) Compute numeric deltas for balances (used for notifications) and the SQL expressions (used for insert/select)
+ [$grossDelta, $unclearedDelta, $netDelta] = $this->computeBalanceDeltas($operation, $dto->getAmount());
+ [$exprAmount, $exprGross, $exprNet] = $this->buildAmountAndExpressions($operation, $dto->getAmount(), $capAtZero);
- $result = $this->updateFunds(StatementEntity::DEPOSIT, $account, $dto);
+ // 2) Build the insert-select for the statement and the account update based on the new statement
+ $statementInsert = $this->getInsertStatementQuery(
+ $operation,
+ $dto,
+ $exprGross,
+ $exprNet,
+ $exprAmount,
+ (string)$unclearedDelta
+ );
- $this->getRepository()->getDbDriver()->commitTransaction();
+ $accountUpdate = $this->getAccountUpdateQuery($dto);
- return $result->getStatementId();
- } catch (Exception $ex) {
- $this->getRepository()->getDbDriver()->rollbackTransaction();
+ // 3) Execute both queries atomically
+ try {
+ $this->getRepository()->bulkExecute([
+ $statementInsert,
+ $accountUpdate,
+ ])->toArray();
+
+ // 4) Notify observers of account change, providing an oldAccount with pre-change balances
+ $account = $this->accountRepository->getById($dto->getAccountId());
+ if (empty($account)) {
+ throw new AccountException('Account not found');
+ }
+ $oldAccount = clone $account;
+ $oldAccount->setGrossbalance($oldAccount->getGrossbalance() - $grossDelta);
+ $oldAccount->setUncleared($oldAccount->getUncleared() - $unclearedDelta);
+ $oldAccount->setNetbalance($oldAccount->getNetbalance() - $netDelta);
+
+ ORMSubject::getInstance()->notify(
+ $this->accountRepository->getMapper()->getTable(),
+ ORMSubject::EVENT_UPDATE,
+ $account,
+ $oldAccount
+ );
+
+ // 5) Load the statement just created to notify and return
+ $statement = $this->statementRepository->getById($account->getLastStatementId());
+
+ ORMSubject::getInstance()->notify(
+ $this->statementRepository->getMapper()->getTable(),
+ ORMSubject::EVENT_INSERT,
+ $statement,
+ null
+ );
+
+ // If capping occurred on withdraw, the actual amount may differ from the DTO amount
+ $dto->setAmount($statement->getAmount());
+
+ return $statement;
+ } catch (\PDOException $ex) {
+ if (strpos($ex->getMessage(), 'chk_value_nonnegative') !== false) {
+ throw new AmountException('Cannot withdraw above the account balance');
+ }
throw $ex;
}
}
- protected function validateStatementDto(StatementDTO $dto): void
- {
- if (!$dto->hasAccount()) {
- throw new StatementException('Account is required');
- }
- if ($dto->getAmount() < 0) {
- throw new AmountException('Amount needs to be greater than zero');
- }
-
- if (round($dto->getAmount()*100)/100 != $dto->getAmount()) {
- throw new AmountException('Amount needs to have two decimal places');
- }
- }
+ // ---- Helpers: computations and query building ---------------------------------------------------------------
/**
- * @throws RepositoryReadOnlyException
- * @throws InvalidArgumentException
- * @throws \ByJG\MicroOrm\Exception\InvalidArgumentException
- * @throws OrmInvalidFieldsException
- * @throws UpdateConstraintException
- * @throws OrmBeforeInvalidException
+ * Compute numeric deltas for balances according to the operation and amount.
+ * Returns [grossDelta, unclearedDelta, netDelta].
*/
- protected function updateFunds(string $operation, AccountEntity $account, StatementDTO $dto): StatementEntity
+ private function computeBalanceDeltas(string $operation, float $amount): array
{
- $sumGrossBalance = $dto->getAmount() * match($operation) {
+ $grossDelta = $amount * match ($operation) {
StatementEntity::DEPOSIT => 1,
StatementEntity::WITHDRAW => -1,
default => 0,
};
- $sumUnCleared = $dto->getAmount() * match($operation) {
+
+ $unclearedDelta = $amount * match ($operation) {
StatementEntity::DEPOSIT_BLOCKED => -1,
StatementEntity::WITHDRAW_BLOCKED => 1,
default => 0,
};
- $sumNetBalance = $dto->getAmount() * match($operation) {
+
+ $netDelta = $amount * match ($operation) {
StatementEntity::DEPOSIT, StatementEntity::DEPOSIT_BLOCKED => 1,
StatementEntity::WITHDRAW, StatementEntity::WITHDRAW_BLOCKED => -1,
default => 0,
};
- // Update Values in an account
- $account->setGrossBalance($account->getGrossBalance() + $sumGrossBalance);
- $account->setUncleared($account->getUncleared() + $sumUnCleared);
- $account->setNetBalance($account->getNetBalance() + $sumNetBalance);
- $this->accountRepository->save($account);
-
- // Add the new line
- /** @var StatementEntity $statement */
- $statement = $this->statementRepository->getRepository()->entity([]);
- $dto->setToStatement($statement);
- $statement->setTypeId($operation);
- $statement->attachAccount($account);
-
- // Save to DB
- return $this->statementRepository->save($statement);
+ return [$grossDelta, $unclearedDelta, $netDelta];
}
/**
- * Withdraw funds from an account
- *
- * @param StatementDTO $dto
- * @param bool $allowZeroNoBalance
- * @return int|null Statement ID
- * @throws AccountException
- * @throws AmountException
- * @throws InvalidArgumentException
- * @throws OrmBeforeInvalidException
- * @throws OrmInvalidFieldsException
- * @throws RepositoryReadOnlyException
- * @throws StatementException
- * @throws UpdateConstraintException
- * @throws \ByJG\MicroOrm\Exception\InvalidArgumentException
+ * Build SQL literal expressions for amount, gross and net balances.
+ * When capping at zero (withdraw), it ensures the amount is reduced to avoid negative net balance.
+ * Returns [exprAmount, exprGross, exprNet].
*/
- public function withdrawFunds(StatementDTO $dto, bool $allowZeroNoBalance = false): ?int
+ private function buildAmountAndExpressions(string $operation, float $amount, bool $capAtZero): array
{
- // Validations
- $this->validateStatementDto($dto);
+ $exprGross = "grossbalance + " . ($amount * match ($operation) {
+ StatementEntity::DEPOSIT => 1,
+ StatementEntity::WITHDRAW => -1,
+ default => 0,
+ });
+ $exprNet = "netbalance + " . ($amount * match ($operation) {
+ StatementEntity::DEPOSIT, StatementEntity::DEPOSIT_BLOCKED => 1,
+ StatementEntity::WITHDRAW, StatementEntity::WITHDRAW_BLOCKED => -1,
+ default => 0,
+ });
+ $exprAmount = (string)$amount;
+
+ if ($capAtZero && $operation === StatementEntity::WITHDRAW) {
+ // Cap withdraw so netbalance never goes below zero
+ $exprAmount = "case when netbalance - {$amount} < 0 then {$amount} + (netbalance - {$amount}) else {$amount} end";
+ $exprGross = "grossbalance - $exprAmount";
+ $exprNet = "netbalance - $exprAmount";
+ }
- $this->getRepository()->getDbDriver()->beginTransaction(IsolationLevelEnum::SERIALIZABLE, true);
- try {
- $account = $this->accountRepository->getById($dto->getAccountId());
- if (is_null($account)) {
- throw new AccountException('addFunds: Account not found');
- }
+ return [$exprAmount, $exprGross, $exprNet];
+ }
- // Cannot withdraw above the account balance.
- $newBalance = $account->getNetBalance() - $dto->getAmount();
- if ($newBalance < $account->getMinValue()) {
- if (!$allowZeroNoBalance) {
- throw new AmountException('Cannot withdraw above the account balance.');
+ /**
+ * Append extra mapped fields from the DTO properties (extended entities) into the target/select lists.
+ */
+ private function appendExtraMappedFields(StatementDTO $dto, array &$targetColumns, array &$selectFields): void
+ {
+ $mapper = $this->statementRepository->getMapper();
+ foreach ($dto->getProperties() as $propertyName => $propertyValue) {
+ $fieldMap = $mapper->getFieldMap($propertyName);
+ if ($fieldMap && $fieldMap->isSyncWithDb()) {
+ $fieldName = $fieldMap->getFieldName();
+ if (!in_array($fieldName, $targetColumns, true)) {
+ $targetColumns[] = $fieldName;
+ $selectFields[] = !is_null($propertyValue) ? "'" . $propertyValue . "'" : 'null';
}
- $dto->setAmount($account->getNetBalance() - $account->getMinValue());
}
+ }
+ }
- $result = $this->updateFunds(StatementEntity::WITHDRAW, $account, $dto);
-
- $this->getRepository()->getDbDriver()->commitTransaction();
+ /**
+ * Subquery selecting the last inserted statement to update account fields with.
+ */
+ private function buildLastInsertedStatementSnapshotQuery(): Query
+ {
+ return Query::getInstance()
+ ->table($this->statementRepository->getMapper()->getTable())
+ ->fields(['statementid', 'accountid', 'grossbalance', 'netbalance', 'uncleared'])
+ ->where('statementid = (' . $this->statementRepository->getDbDriver()->getDbHelper()->getSqlLastInsertId() . ')');
+ }
- return $result->getStatementId();
- } catch (Exception $ex) {
- $this->getRepository()->getDbDriver()->rollbackTransaction();
+ protected function getInsertStatementQuery(
+ string $operation,
+ StatementDTO $dto,
+ string $expressionSumGrossBalance,
+ string $expressionSumNetBalance,
+ string $expressionAmount,
+ string $sumUnCleared
+ ): InsertSelectQuery
+ {
+ // Build base target columns and select fields
+ $targetColumns = [
+ 'accountid',
+ 'accounttypeid',
+ 'grossbalance',
+ 'netbalance',
+ 'uncleared',
+ 'price',
+ 'amount',
+ 'description',
+ 'code',
+ 'referenceid',
+ 'referencesource',
+ 'typeid',
+ 'date',
+ 'statementparentid',
+ ];
+
+ $selectFields = [
+ 'accountid',
+ 'accounttypeid',
+ $expressionSumGrossBalance,
+ $expressionSumNetBalance,
+ "uncleared + $sumUnCleared",
+ 'price',
+ $expressionAmount,
+ ':description',
+ ':code',
+ ':referenceid',
+ ':referencesource',
+ ':operation',
+ $this->statementRepository->getDbDriver()->getDbHelper()->sqlDate('Y-m-d H:i:s'),
+ 'null',
+ ];
+
+ // Append any extra mapped fields provided via DTO properties (for extended entities)
+ $this->appendExtraMappedFields($dto, $targetColumns, $selectFields);
+
+ $statementQuery = Query::getInstance()
+ ->table('account')
+ ->fields($selectFields)
+ ->where('accountid = :accid2', [
+ 'accid2' => $dto->getAccountId(),
+ 'description' => $dto->getDescription(),
+ 'code' => $dto->getCode(),
+ 'referenceid' => $dto->getReferenceId(),
+ 'referencesource' => $dto->getReferenceSource(),
+ 'operation' => $operation,
+ ]);
+
+ return InsertSelectQuery::getInstance(
+ $this->statementRepository->getMapper()->getTable(),
+ $targetColumns
+ )->fromQuery($statementQuery);
+ }
- throw $ex;
- }
+ public function getAccountUpdateQuery(StatementDTO $dto): UpdateQuery
+ {
+ $statementSnapshot = $this->buildLastInsertedStatementSnapshotQuery();
+
+ return UpdateQuery::getInstance()
+ ->table('account')
+ ->setLiteral('account.grossbalance', 'st.grossbalance')
+ ->setLiteral('account.uncleared', 'st.uncleared')
+ ->setLiteral('account.netbalance', 'st.netbalance')
+ ->setLiteral('account.laststatementid', 'st.statementid')
+ ->where('account.accountid = :accid', ['accid' => $dto->getAccountId()])
+ ->join($statementSnapshot, 'st.accountid = account.accountid', 'st');
}
/**
- * Reserve funds to future withdrawn. It affects the net balance but not the gross balance
+ * Add funds to an account
*
* @param StatementDTO $dto
- * @return int|null Statement ID
+ * @return StatementEntity Newly created statement entity
* @throws AccountException
* @throws AmountException
* @throws InvalidArgumentException
- * @throws OrmBeforeInvalidException
- * @throws OrmInvalidFieldsException
- * @throws RepositoryReadOnlyException
* @throws StatementException
- * @throws UpdateConstraintException
* @throws \ByJG\MicroOrm\Exception\InvalidArgumentException
*/
- public function reserveFundsForWithdraw(StatementDTO $dto): ?int
+ public function addFunds(StatementDTO $dto): StatementEntity
{
- // Validations
- $this->validateStatementDto($dto);
-
- $this->getRepository()->getDbDriver()->beginTransaction(IsolationLevelEnum::SERIALIZABLE, true);
- try {
- $account = $this->accountRepository->getById($dto->getAccountId());
- if (is_null($account)) {
- throw new AccountException('reserveFundsForWithdraw: Account not found');
- }
-
- // Cannot withdraw above the account balance.
- if ($account->getNetBalance() - $dto->getAmount() < $account->getMinValue()) {
- throw new AmountException('Cannot withdraw above the account balance.');
- }
-
- $result = $this->updateFunds(StatementEntity::WITHDRAW_BLOCKED, $account, $dto);
-
- $this->getRepository()->getDbDriver()->commitTransaction();
+ return $this->updateFunds(StatementEntity::DEPOSIT, $dto);
+ }
- return $result->getStatementId();
- } catch (Exception $ex) {
- $this->getRepository()->getDbDriver()->rollbackTransaction();
+ /**
+ * Withdraw funds from an account
+ *
+ * @param StatementDTO $dto
+ * @param bool $capAtZero
+ * @return StatementEntity Statement ID
+ * @throws AccountException
+ * @throws AmountException
+ * @throws InvalidArgumentException
+ * @throws StatementException
+ * @throws \ByJG\MicroOrm\Exception\InvalidArgumentException
+ */
+ public function withdrawFunds(StatementDTO $dto, bool $capAtZero = false): StatementEntity
+ {
+ return $this->updateFunds(StatementEntity::WITHDRAW, $dto, $capAtZero);
+ }
- throw $ex;
- }
+ /**
+ * Reserve funds to future withdrawn. It affects the net balance but not the gross balance
+ *
+ * @param StatementDTO $dto
+ * @return StatementEntity Statement ID
+ * @throws AccountException
+ * @throws AmountException
+ * @throws InvalidArgumentException
+ * @throws StatementException
+ * @throws \ByJG\MicroOrm\Exception\InvalidArgumentException
+ */
+ public function reserveFundsForWithdraw(StatementDTO $dto): StatementEntity
+ {
+ return $this->updateFunds(StatementEntity::WITHDRAW_BLOCKED, $dto);
}
/**
* Reserve funds to future deposit. Update net balance but not gross balance.
*
* @param StatementDTO $dto
- * @return int|null Statement ID
+ * @return StatementEntity Statement ID
* @throws AccountException
* @throws AmountException
* @throws InvalidArgumentException
- * @throws OrmBeforeInvalidException
- * @throws OrmInvalidFieldsException
- * @throws RepositoryReadOnlyException
* @throws StatementException
- * @throws UpdateConstraintException
* @throws \ByJG\MicroOrm\Exception\InvalidArgumentException
*/
- public function reserveFundsForDeposit(StatementDTO $dto): ?int
+ public function reserveFundsForDeposit(StatementDTO $dto): StatementEntity
{
- // Validações
- $this->validateStatementDto($dto);
-
- $this->getRepository()->getDbDriver()->beginTransaction(IsolationLevelEnum::SERIALIZABLE, true);
- try {
- $account = $this->accountRepository->getById($dto->getAccountId());
- if (is_null($account)) {
- throw new AccountException('reserveFundsForDeposit: Account not found');
- }
-
- $result = $this->updateFunds(StatementEntity::DEPOSIT_BLOCKED, $account, $dto);
-
- $this->getRepository()->getDbDriver()->commitTransaction();
-
- return $result->getStatementId();
- } catch (Exception $ex) {
- $this->getRepository()->getDbDriver()->rollbackTransaction();
-
- throw $ex;
- }
+ return $this->updateFunds(StatementEntity::DEPOSIT_BLOCKED, $dto);
}
/**
@@ -356,7 +456,7 @@ public function acceptFundsById(int $statementId, ?StatementDTO $statementDto =
* @param int $statementId
* @param StatementDTO $statementDtoWithdraw
* @param StatementDTO $statementDtoRefund
- * @return int|null
+ * @return StatementEntity
* @throws AccountException
* @throws AmountException
* @throws InvalidArgumentException
@@ -367,7 +467,7 @@ public function acceptFundsById(int $statementId, ?StatementDTO $statementDto =
* @throws UpdateConstraintException
* @throws \ByJG\MicroOrm\Exception\InvalidArgumentException
*/
- public function acceptPartialFundsById(int $statementId, StatementDTO $statementDtoWithdraw, StatementDTO $statementDtoRefund): ?int
+ public function acceptPartialFundsById(int $statementId, StatementDTO $statementDtoWithdraw, StatementDTO $statementDtoRefund): StatementEntity
{
$partialAmount = $statementDtoWithdraw->getAmount();
@@ -399,11 +499,11 @@ public function acceptPartialFundsById(int $statementId, StatementDTO $statement
$statementDtoWithdraw->setAccountId($statement->getAccountId());
- $finalDebitStatementId = $this->withdrawFunds($statementDtoWithdraw);
+ $finalDebitStatement = $this->withdrawFunds($statementDtoWithdraw);
$this->getRepository()->getDbDriver()->commitTransaction();
- return $finalDebitStatementId;
+ return $finalDebitStatement;
} catch (Exception $ex) {
$this->getRepository()->getDbDriver()->rollbackTransaction();
diff --git a/src/DTO/StatementDTO.php b/src/DTO/StatementDTO.php
index 3ce897e..e5b9ace 100644
--- a/src/DTO/StatementDTO.php
+++ b/src/DTO/StatementDTO.php
@@ -137,40 +137,40 @@ public function setAmount(float $amount): static
}
/**
- * @param string $description
+ * @param string|null $description
* @return $this
*/
- public function setDescription(string $description): static
+ public function setDescription(?string $description): static
{
$this->description = $description;
return $this;
}
/**
- * @param string $referenceId
+ * @param string|null $referenceId
* @return $this
*/
- public function setReferenceId(string $referenceId): static
+ public function setReferenceId(?string $referenceId): static
{
$this->referenceId = $referenceId;
return $this;
}
/**
- * @param string $referenceSource
+ * @param string|null $referenceSource
* @return $this
*/
- public function setReferenceSource(string $referenceSource): static
+ public function setReferenceSource(?string $referenceSource): static
{
$this->referenceSource = $referenceSource;
return $this;
}
/**
- * @param string $code
+ * @param string|null $code
* @return $this
*/
- public function setCode(string $code): static
+ public function setCode(?string $code): static
{
$this->code = $code;
return $this;
@@ -186,5 +186,4 @@ public function getProperties(): array
{
return $this->properties;
}
-
}
\ No newline at end of file
diff --git a/src/Entity/AccountEntity.php b/src/Entity/AccountEntity.php
index c977df0..0e5135b 100644
--- a/src/Entity/AccountEntity.php
+++ b/src/Entity/AccountEntity.php
@@ -73,6 +73,8 @@ class AccountEntity extends BaseModel
#[FieldAttribute(syncWithDb: false)]
protected ?string $entrydate = null;
+ protected ?int $laststatementid = null;
+
/**
* @var float|null
* @OA\Property()
@@ -179,6 +181,16 @@ public function setMinValue(?float $minvalue): void
$this->minvalue = $minvalue;
}
+ public function getLastStatementId(): ?int
+ {
+ return $this->laststatementid;
+ }
+
+ public function setLastStatementId(?int $laststatementid): void
+ {
+ $this->laststatementid = $laststatementid;
+ }
+
/**
*
* @throws AmountException
diff --git a/src/Repository/BaseRepository.php b/src/Repository/BaseRepository.php
index 3c0b45f..edfa903 100644
--- a/src/Repository/BaseRepository.php
+++ b/src/Repository/BaseRepository.php
@@ -2,8 +2,10 @@
namespace ByJG\AccountStatements\Repository;
+use ByJG\AnyDataset\Core\GenericIterator;
use ByJG\AnyDataset\Core\IteratorFilter;
use ByJG\AnyDataset\Db\DbDriverInterface;
+use ByJG\AnyDataset\Db\IsolationLevelEnum;
use ByJG\MicroOrm\Exception\OrmBeforeInvalidException;
use ByJG\MicroOrm\Exception\OrmInvalidFieldsException;
use ByJG\MicroOrm\Exception\RepositoryReadOnlyException;
@@ -89,6 +91,11 @@ public function save($model): mixed
return $this->repository->save($model);
}
+ public function bulkExecute(array $queries): ?GenericIterator
+ {
+ return $this->repository->bulkExecute($queries, IsolationLevelEnum::SERIALIZABLE);
+ }
+
public function getDbDriver(): DbDriverInterface
{
return $this->repository->getDbDriver();
diff --git a/tests/BaseDALTrait.php b/tests/BaseDALTrait.php
index dd1b34e..117b952 100644
--- a/tests/BaseDALTrait.php
+++ b/tests/BaseDALTrait.php
@@ -11,6 +11,7 @@
use ByJG\AccountStatements\Exception\AccountException;
use ByJG\AccountStatements\Exception\AccountTypeException;
use ByJG\AccountStatements\Exception\AmountException;
+use ByJG\AccountStatements\Exception\StatementException;
use ByJG\AccountStatements\Repository\AccountRepository;
use ByJG\AccountStatements\Repository\AccountTypeRepository;
use ByJG\AccountStatements\Repository\StatementRepository;
@@ -21,7 +22,8 @@
use ByJG\MicroOrm\Exception\OrmBeforeInvalidException;
use ByJG\MicroOrm\Exception\OrmInvalidFieldsException;
use ByJG\MicroOrm\Exception\OrmModelInvalidException;
-use ByJG\MicroOrm\Exception\TransactionException;
+use ByJG\MicroOrm\Exception\RepositoryReadOnlyException;
+use ByJG\MicroOrm\Exception\UpdateConstraintException;
use ByJG\Util\Uri;
use ReflectionException;
@@ -77,7 +79,13 @@ public function dbSetUp()
$migration = new Migration($this->uri, __DIR__ . "/../db");
$migration->prepareEnvironment();
- $migration->reset();
+ // This will delete the constraint to validate the negative amount
+ $maxVersion = null;
+ /** @psalm-suppress InternalMethod */
+ if (strpos($this->getName(), "Allow_Negativ") !== false) {
+ $maxVersion = 3;
+ }
+ $migration->reset($maxVersion);
$migration->getDbDriver()->execute("CREATE TABLE statement_extended LIKE statement");
$migration->getDbDriver()->execute("alter table statement_extended add extra_property varchar(100) null;");
@@ -109,7 +117,9 @@ protected function dbClear(): void
* @throws InvalidArgumentException
* @throws OrmBeforeInvalidException
* @throws OrmInvalidFieldsException
- * @throws TransactionException
+ * @throws StatementException
+ * @throws RepositoryReadOnlyException
+ * @throws UpdateConstraintException
* @throws \ByJG\Serializer\Exception\InvalidArgumentException
*/
protected function createDummyData()
@@ -126,9 +136,14 @@ protected function createDummyData()
$dto3->setAccountTypeId('ABCTEST');
$dto3->setName('Test 3');
+ $dto4 = new AccountTypeEntity();
+ $dto4->setAccountTypeId('NEGTEST');
+ $dto4->setName('Test 4');
+
$this->accountTypeBLL->update($dto1);
$this->accountTypeBLL->update($dto2);
$this->accountTypeBLL->update($dto3);
+ $this->accountTypeBLL->update($dto4);
$this->accountBLL->createAccount('BRLTEST', '___TESTUSER-1', 1000, 1);
}
diff --git a/tests/Classes/AccountRepositoryExtended.php b/tests/Classes/AccountRepositoryExtended.php
new file mode 100644
index 0000000..a5ce626
--- /dev/null
+++ b/tests/Classes/AccountRepositoryExtended.php
@@ -0,0 +1,42 @@
+getRepository()->addObserver(new ObserverAccount($this));
+ }
+
+ public function getReach(): bool
+ {
+ return $this->reach;
+ }
+
+ public function setReach(bool $reach): void
+ {
+ $this->reach = $reach;
+ }
+}
\ No newline at end of file
diff --git a/tests/Classes/ObserverAccount.php b/tests/Classes/ObserverAccount.php
new file mode 100644
index 0000000..bc5a4d2
--- /dev/null
+++ b/tests/Classes/ObserverAccount.php
@@ -0,0 +1,31 @@
+repository->setReach($observerData->getEvent() == 'update' && $observerData->getData()->getNetbalance() == 1250);
+ }
+
+ public function getObservedTable(): string
+ {
+ return "account";
+ }
+
+ public function onError(Throwable $exception, ObserverData $observerData): void
+ {
+ throw $exception;
+ }
+}
\ No newline at end of file
diff --git a/tests/Classes/ObserverStatement.php b/tests/Classes/ObserverStatement.php
new file mode 100644
index 0000000..9238af9
--- /dev/null
+++ b/tests/Classes/ObserverStatement.php
@@ -0,0 +1,31 @@
+repository->setReach($observerData->getData()->getStatementId() == 3 && $observerData->getData()->getAmount() == 250);
+ }
+
+ public function getObservedTable(): string
+ {
+ return "statement";
+ }
+
+ public function onError(Throwable $exception, ObserverData $observerData): void
+ {
+ throw $exception;
+ }
+}
\ No newline at end of file
diff --git a/tests/Classes/StatementRepositoryExtended.php b/tests/Classes/StatementRepositoryExtended.php
new file mode 100644
index 0000000..64cfe75
--- /dev/null
+++ b/tests/Classes/StatementRepositoryExtended.php
@@ -0,0 +1,27 @@
+getRepository()->addObserver(new ObserverStatement($this));
+ }
+
+ public function getReach(): bool
+ {
+ return $this->reach;
+ }
+
+ public function setReach(bool $reach): void
+ {
+ $this->reach = $reach;
+ }
+}
\ No newline at end of file
diff --git a/tests/Database/AccountStatementsTest.php b/tests/Database/AccountStatementsTest.php
index a882930..af1c8dd 100644
--- a/tests/Database/AccountStatementsTest.php
+++ b/tests/Database/AccountStatementsTest.php
@@ -3,19 +3,23 @@
namespace Tests\Database;
use ByJG\AccountStatements\DTO\StatementDTO;
+use ByJG\AccountStatements\Entity\AccountEntity;
use ByJG\AccountStatements\Entity\StatementEntity;
use ByJG\AccountStatements\Exception\AccountException;
use ByJG\AccountStatements\Exception\AccountTypeException;
use ByJG\AccountStatements\Exception\AmountException;
use ByJG\AnyDataset\Db\Exception\TransactionStartedException;
use ByJG\AnyDataset\Db\IsolationLevelEnum;
+use ByJG\MicroOrm\Exception\InvalidArgumentException;
use ByJG\MicroOrm\Exception\OrmBeforeInvalidException;
use ByJG\MicroOrm\Exception\OrmInvalidFieldsException;
use ByJG\MicroOrm\Exception\TransactionException;
use ByJG\Serializer\Serialize;
use PHPUnit\Framework\TestCase;
use Tests\BaseDALTrait;
+use Tests\Classes\AccountRepositoryExtended;
use Tests\Classes\StatementExtended;
+use Tests\Classes\StatementRepositoryExtended;
class AccountStatementsTest extends TestCase
@@ -45,15 +49,14 @@ protected function tearDown(): void
/**
* @return void
- * @throws \ByJG\MicroOrm\Exception\InvalidArgumentException
- * @throws \ByJG\Serializer\Exception\InvalidArgumentException
+ * @throws InvalidArgumentException
*/
public function testGetAccountType()
{
$accountTypeRepo = $this->accountTypeBLL->getRepository();
- $list = $accountTypeRepo->getAll(null, null, null, [["accounttypeid like '___TEST'", []]]);
+ $list = $accountTypeRepo->getAll(null, null, null, [["accounttypeid like '___TEST'", []]]);
- $this->assertEquals(3, count($list));
+ $this->assertEquals(4, count($list));
$this->assertEquals(
[
@@ -65,6 +68,10 @@ public function testGetAccountType()
'accounttypeid' => 'BRLTEST',
'name' => 'Test 2'
],
+ [
+ 'accounttypeid' => 'NEGTEST',
+ 'name' => 'Test 4'
+ ],
[
'accounttypeid' => 'USDTEST',
'name' => 'Test 1'
@@ -82,13 +89,13 @@ public function testGetById()
{
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->withdrawFunds(
+ $actual = $this->statementBLL->withdrawFunds(
StatementDTO::create($accountId, 10)
- ->setDescription( 'Test')
+ ->setDescription('Test')
->setReferenceId('Referencia')
->setReferenceSource('Source')
->setCode('XYZ')
- );
+ );
// Objeto que é esperado
$statement = new StatementEntity();
@@ -97,7 +104,7 @@ public function testGetById()
$statement->setDescription('Test');
$statement->setGrossBalance('990.00');
$statement->setAccountId($accountId);
- $statement->setStatementId($statementId);
+ $statement->setStatementId($actual->getStatementId());
$statement->setTypeId('W');
$statement->setNetBalance('990.00');
$statement->setPrice('1.00');
@@ -106,8 +113,6 @@ public function testGetById()
$statement->setReferenceSource('Source');
$statement->setCode('XYZ');
$statement->setAccountTypeId('USDTEST');
-
- $actual = $this->statementBLL->getById($statementId);
$statement->setDate($actual->getDate());
// Executar teste
@@ -118,9 +123,9 @@ public function testGetById_Zero()
{
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 0);
- $statementId = $this->statementBLL->addFunds(
+ $actual = $this->statementBLL->addFunds(
StatementDTO::create($accountId, 10)
- ->setDescription( 'Test')
+ ->setDescription('Test')
->setReferenceId('Referencia')
->setReferenceSource('Source')
->setCode('XYZ')
@@ -133,7 +138,7 @@ public function testGetById_Zero()
$statement->setDescription('Test');
$statement->setGrossBalance('10.00');
$statement->setAccountId($accountId);
- $statement->setStatementId($statementId);
+ $statement->setStatementId($actual->getStatementId());;
$statement->setTypeId('D');
$statement->setNetBalance('10.00');
$statement->setPrice('1.00');
@@ -142,8 +147,6 @@ public function testGetById_Zero()
$statement->setReferenceSource('Source');
$statement->setCode('XYZ');
$statement->setAccountTypeId('USDTEST');
-
- $actual = $this->statementBLL->getById($statementId);
$statement->setDate($actual->getDate());
// Executar teste
@@ -160,18 +163,18 @@ public function testGetAll()
{
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->withdrawFunds(
+ $statementResult = $this->statementBLL->withdrawFunds(
StatementDTO::create($accountId, 10)
- ->setDescription( 'Test')
+ ->setDescription('Test')
->setReferenceId('Referencia')
->setReferenceSource('Source')
- );
+ );
$this->statementBLL->withdrawFunds(
StatementDTO::create($accountId, 50)
->setDescription('Test')
->setReferenceId('Referencia')
->setReferenceSource('Source')
- );
+ );
$statement = [];
@@ -198,7 +201,7 @@ public function testGetAll()
$statement[1]->setDescription('Test');
$statement[1]->setGrossBalance('990.00');
$statement[1]->setAccountId($accountId);
- $statement[1]->setStatementId($statementId);
+ $statement[1]->setStatementId($statementResult->getStatementId());
$statement[1]->setTypeId('W');
$statement[1]->setNetBalance('990.00');
$statement[1]->setPrice('1.00');
@@ -222,10 +225,10 @@ public function testGetAll()
$statement[2]->setReferenceSource('Source');
$statement[2]->setAccountTypeId('USDTEST');
- $listAll = $this->statementBLL->getRepository()->getAll(null, null, null, [["accounttypeid = :id",["id" => 'USDTEST']]]);
+ $listAll = $this->statementBLL->getRepository()->getAll(null, null, null, [["accounttypeid = :id", ["id" => 'USDTEST']]]);
/** @psalm-suppress InvalidArrayOffset */
- for ($i=0; $isetDate(null);
$statement[$i]->setStatementId(null);
$listAll[$i]->setDate(null);
@@ -243,12 +246,12 @@ public function testAddFunds()
{
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->addFunds(
+ $actual = $this->statementBLL->addFunds(
StatementDTO::create($accountId, 250)
->setDescription('Test Add Funds')
->setReferenceId('Referencia Add Funds')
->setReferenceSource('Source Add Funds')
- );
+ );
// Check
$statement = new StatementEntity;
@@ -257,7 +260,7 @@ public function testAddFunds()
$statement->setDescription('Test Add Funds');
$statement->setGrossBalance('1250.00');
$statement->setAccountId($accountId);
- $statement->setStatementId($statementId);
+ $statement->setStatementId($actual->getStatementId());
$statement->setTypeId('D');
$statement->setNetBalance('1250.00');
$statement->setPrice('1.00');
@@ -265,8 +268,6 @@ public function testAddFunds()
$statement->setReferenceId('Referencia Add Funds');
$statement->setReferenceSource('Source Add Funds');
$statement->setAccountTypeId('USDTEST');
-
- $actual = $this->statementBLL->getById($statementId);
$statement->setDate($actual->getDate());
$this->assertEquals($statement->toArray(), $actual->toArray());
@@ -296,7 +297,7 @@ public function testAddFundsDecimal($amount)
{
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->addFunds(
+ $actual = $this->statementBLL->addFunds(
StatementDTO::create($accountId, $amount)
->setDescription('Test Add Funds')
->setReferenceId('Referencia Add Funds')
@@ -310,7 +311,7 @@ public function testAddFundsDecimal($amount)
$statement->setDescription('Test Add Funds');
$statement->setGrossBalance(1000 + $amount);
$statement->setAccountId($accountId);
- $statement->setStatementId($statementId);
+ $statement->setStatementId($actual->getStatementId());;
$statement->setTypeId('D');
$statement->setNetBalance(1000 + $amount);
$statement->setPrice('1.00');
@@ -318,8 +319,6 @@ public function testAddFundsDecimal($amount)
$statement->setReferenceId('Referencia Add Funds');
$statement->setReferenceSource('Source Add Funds');
$statement->setAccountTypeId('USDTEST');
-
- $actual = $this->statementBLL->getById($statementId);
$statement->setDate($actual->getDate());
$this->assertEquals($statement->toArray(), $actual->toArray());
@@ -353,12 +352,12 @@ public function testWithdrawFunds()
{
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->withdrawFunds(
+ $actual = $this->statementBLL->withdrawFunds(
StatementDTO::create($accountId, 350)
- ->setDescription( 'Test Withdraw')
+ ->setDescription('Test Withdraw')
->setReferenceId('Referencia Withdraw')
->setReferenceSource('Source Withdraw')
- );
+ );
// Objeto que é esperado
$statement = new StatementEntity();
@@ -367,7 +366,7 @@ public function testWithdrawFunds()
$statement->setDescription('Test Withdraw');
$statement->setGrossBalance('650.00');
$statement->setAccountId($accountId);
- $statement->setStatementId($statementId);
+ $statement->setStatementId($actual->getStatementId());
$statement->setTypeId('W');
$statement->setNetBalance('650.00');
$statement->setPrice('1.00');
@@ -375,8 +374,6 @@ public function testWithdrawFunds()
$statement->setReferenceId('Referencia Withdraw');
$statement->setReferenceSource('Source Withdraw');
$statement->setAccountTypeId('USDTEST');
-
- $actual = $this->statementBLL->getById($statementId);
$statement->setDate($actual->getDate());
// Executar teste
@@ -407,16 +404,16 @@ public function testWithdrawFunds_InvalidRound()
$this->statementBLL->withdrawFunds(StatementDTO::create($accountId, 10.001));
}
- public function testWithdrawFunds_Negative()
+ public function testWithdrawFunds_Allow_Negative()
{
// Populate Data!
- $accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000, 1, -400);
- $statementId = $this->statementBLL->withdrawFunds(
+ $accountId = $this->accountBLL->createAccount('NEGTEST', "___TESTUSER-1", 1000, 1, -400);
+ $actual = $this->statementBLL->withdrawFunds(
StatementDTO::create($accountId, 1150)
->setDescription('Test Withdraw')
->setReferenceId('Referencia Withdraw')
->setReferenceSource('Source Withdraw')
- );
+ );
// Objeto que é esperado
$statement = new StatementEntity();
@@ -425,40 +422,39 @@ public function testWithdrawFunds_Negative()
$statement->setDescription('Test Withdraw');
$statement->setGrossBalance('-150.00');
$statement->setAccountId($accountId);
- $statement->setStatementId($statementId);
+ $statement->setStatementId($actual->getStatementId());
$statement->setTypeId('W');
$statement->setNetBalance('-150.00');
$statement->setPrice('1.00');
$statement->setUnCleared('0.00');
$statement->setReferenceId('Referencia Withdraw');
$statement->setReferenceSource('Source Withdraw');
- $statement->setAccountTypeId('USDTEST');
-
- $actual = $this->statementBLL->getById($statementId);
+ $statement->setAccountTypeId('NEGTEST');
$statement->setDate($actual->getDate());
// Executar teste
$this->assertEquals($statement->toArray(), $actual->toArray());
}
- public function testWithdrawFunds_NegativeInvalid()
+ public function testWithdrawFunds_Allow_Negative2()
{
- $this->expectException(AmountException::class);
-
// Populate Data!
- $accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000, 1, -400);
- $this->statementBLL->withdrawFunds(StatementDTO::create($accountId, 1401)->setDescription('Test Withdraw')->setReferenceId('Referencia Withdraw'));
+ $accountId = $this->accountBLL->createAccount('NEGTEST', "___TESTUSER-1", 1000, 1, -400);
+ $statement = $this->statementBLL->withdrawFunds(StatementDTO::create($accountId, 1400)->setDescription('Test Withdraw')->setReferenceId('Referencia Withdraw'));
+
+ $statement = $this->statementBLL->getById($statement->getStatementId());
+ $this->assertEquals(-400, $statement->getNetBalance());
+ $this->assertEquals(1400, $statement->getAmount());
}
- public function testWithdrawFunds_NegativeInvalid_AllowZero()
+
+ public function testWithdrawFunds_NegativeInvalid()
{
+ $this->expectException(AmountException::class);
+
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000, 1, -400);
- $id = $this->statementBLL->withdrawFunds(StatementDTO::create($accountId, 1401)->setDescription('Test Withdraw')->setReferenceId('Referencia Withdraw'), true);
-
- $statement = $this->statementBLL->getById($id);
- $this->assertEquals(-400, $statement->getNetBalance());
- $this->assertEquals(1400, $statement->getAmount());
+ $this->statementBLL->withdrawFunds(StatementDTO::create($accountId, 1401)->setDescription('Test Withdraw')->setReferenceId('Referencia Withdraw'));
}
/**
@@ -496,11 +492,12 @@ public function testGetAccountByUserId()
"price" => 1,
"extra" => "Extra Information",
"entrydate" => null,
- "minvalue" => "0.00"
+ "minvalue" => "0.00",
+ "laststatementid" => 2,
]);
$this->assertEquals([
- $accountEntity
+ $accountEntity
], $account);
}
@@ -538,7 +535,8 @@ public function testGetAccountByAccountType()
"price" => 1,
"extra" => "Extra Information",
"entrydate" => null,
- "minvalue" => "0.00"
+ "minvalue" => "0.00",
+ "laststatementid" => 2,
]);
$this->assertEquals([
@@ -557,16 +555,17 @@ public function testOverrideFunds()
// Executar teste
$this->assertEquals([
- 'accountid' => $accountId,
- 'accounttypeid' => 'USDTEST',
- 'userid' => "___TESTUSER-1",
- 'grossbalance' => '650.00',
- 'uncleared' => '0.00',
- 'netbalance' => '650.00',
- 'price' => '1.00',
- 'extra' => '',
- 'minvalue' => '0.00',
- ],
+ 'accountid' => $accountId,
+ 'accounttypeid' => 'USDTEST',
+ 'userid' => "___TESTUSER-1",
+ 'grossbalance' => '650.00',
+ 'uncleared' => '0.00',
+ 'netbalance' => '650.00',
+ 'price' => '1.00',
+ 'extra' => '',
+ 'minvalue' => '0.00',
+ "laststatementid" => 2,
+ ],
$account
);
@@ -574,21 +573,21 @@ public function testOverrideFunds()
unset($statement["date"]);
$this->assertEquals([
- 'accountid' => $accountId,
- 'accounttypeid' => 'USDTEST',
- 'grossbalance' => '650.00',
- 'uncleared' => '0.00',
- 'netbalance' => '650.00',
- 'price' => '1.00',
- 'statementid' => $statementId,
- 'typeid' => 'B',
- 'amount' => '650.00',
- 'description' => 'Reset Balance',
- 'statementparentid' => '',
- 'code' => 'BAL',
- 'referenceid' => '',
- 'referencesource' => ''
- ],
+ 'accountid' => $accountId,
+ 'accounttypeid' => 'USDTEST',
+ 'grossbalance' => '650.00',
+ 'uncleared' => '0.00',
+ 'netbalance' => '650.00',
+ 'price' => '1.00',
+ 'statementid' => $statementId,
+ 'typeid' => 'B',
+ 'amount' => '650.00',
+ 'description' => 'Reset Balance',
+ 'statementparentid' => '',
+ 'code' => 'BAL',
+ 'referenceid' => '',
+ 'referencesource' => ''
+ ],
$statement
);
}
@@ -598,12 +597,13 @@ public function testPartialFunds()
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->accountBLL->partialBalance($accountId, 650);
+ $statementPartial = $this->accountBLL->partialBalance($accountId, 650);
$account = $this->accountBLL->getById($accountId)->toArray();
unset($account["entrydate"]);
// Executar teste
- $this->assertEquals([
+ $this->assertEquals(
+ [
'accountid' => $accountId,
'accounttypeid' => 'USDTEST',
'userid' => "___TESTUSER-1",
@@ -613,21 +613,23 @@ public function testPartialFunds()
'price' => '1.00',
'extra' => '',
'minvalue' => '0.00',
+ "laststatementid" => 3,
],
$account
);
- $statement = $this->statementBLL->getById($statementId)->toArray();
+ $statement = Serialize::from($statementPartial)->toArray();
unset($statement["date"]);
- $this->assertEquals([
+ $this->assertEquals(
+ [
'accountid' => $accountId,
'accounttypeid' => 'USDTEST',
'grossbalance' => '650.00',
'uncleared' => '0.00',
'netbalance' => '650.00',
'price' => '1.00',
- 'statementid' => $statementId,
+ 'statementid' => $statementPartial->getStatementId(),
'typeid' => 'W',
'amount' => '350.00',
'description' => 'Partial Balance',
@@ -666,6 +668,7 @@ public function testCloseAccount()
'price' => '0.00',
'extra' => '',
'minvalue' => '0.00',
+ "laststatementid" => 5,
],
$account
);
@@ -705,7 +708,7 @@ public function testGetByDate()
$ignore = $this->accountBLL->createAccount('BRLTEST', "___TESTUSER-999", 1000); // I dont want this account
$this->statementBLL->addFunds(StatementDTO::create($ignore, 200));
- $startDate = date('Y'). "/" . date('m') . "/01";
+ $startDate = date('Y') . "/" . date('m') . "/01";
$endDate = (intval(date('Y')) + (date('m') == 12 ? 1 : 0)) . "/" . (date('m') == 12 ? 1 : intval(date('m')) + 1) . "/01";
$statementList = $this->statementBLL->getByDate($accountId, $startDate, $endDate);
@@ -782,7 +785,7 @@ public function testGetByStatementId()
{
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->addFunds(StatementDTO::create($accountId, 400));
+ $statement = $this->statementBLL->addFunds(StatementDTO::create($accountId, 400));
$this->statementBLL->withdrawFunds(StatementDTO::create($accountId, 300));
$ignore = $this->accountBLL->createAccount('BRLTEST', "___TESTUSER-999", 1000); // I dont want this account
@@ -790,7 +793,7 @@ public function testGetByStatementId()
$accountRepo = $this->accountBLL->getRepository();
- $accountResult = $accountRepo->getByStatementId($statementId);
+ $accountResult = $accountRepo->getByStatementId($statement->getStatementId());;
$accountExpected = $accountRepo->getById($accountId);
// Executar testestatementBLL
@@ -901,10 +904,10 @@ public function testTransferFunds()
$accountBrlId = $this->accountBLL->getByAccountTypeId('BRLTEST')[0]->getAccountId();
$accountUsdId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- [ $statementSourceId, $statementTargetId ] = $this->accountBLL->transferFunds($accountBrlId, $accountUsdId, 300);
+ [$statementSource, $statementTarget] = $this->accountBLL->transferFunds($accountBrlId, $accountUsdId, 300);
- $accountSource = $this->accountBLL->getById($accountBrlId);
- $accountTarget = $this->accountBLL->getById($accountUsdId);
+ $accountSource = $this->accountBLL->getById($statementSource->getAccountId());
+ $accountTarget = $this->accountBLL->getById($statementTarget->getAccountId());
$this->assertEquals(700, $accountSource->getNetBalance());
$this->assertEquals(1300, $accountTarget->getNetBalance());
@@ -918,7 +921,7 @@ public function testTransferFundsFail()
$this->expectException(AmountException::class);
$this->expectExceptionMessage('Cannot withdraw above the account balance');
- [ $statementSourceId, $statementTargetId ] = $this->accountBLL->transferFunds($accountBrlId, $accountUsdId, 1100);
+ $this->accountBLL->transferFunds($accountBrlId, $accountUsdId, 1100);
}
public function testJoinTransactionAndCommit()
@@ -927,9 +930,9 @@ public function testJoinTransactionAndCommit()
$this->dbDriver->beginTransaction(IsolationLevelEnum::SERIALIZABLE);
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->withdrawFunds(
+ $statement = $this->statementBLL->withdrawFunds(
StatementDTO::create($accountId, 10)
- ->setDescription( 'Test')
+ ->setDescription('Test')
->setReferenceId('Referencia')
->setReferenceSource('Source')
->setCode('XYZ')
@@ -938,7 +941,7 @@ public function testJoinTransactionAndCommit()
// Needs to commit inside the context
$this->dbDriver->commitTransaction();
- $statement = $this->statementBLL->getById($statementId);
+ $statement = $this->statementBLL->getById($statement->getStatementId());
$this->assertNotNull($statement);
}
@@ -948,9 +951,9 @@ public function testJoinTransactionAndRollback()
$this->dbDriver->beginTransaction(IsolationLevelEnum::SERIALIZABLE);
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->withdrawFunds(
+ $statement = $this->statementBLL->withdrawFunds(
StatementDTO::create($accountId, 10)
- ->setDescription( 'Test')
+ ->setDescription('Test')
->setReferenceId('Referencia')
->setReferenceSource('Source')
->setCode('XYZ')
@@ -959,7 +962,7 @@ public function testJoinTransactionAndRollback()
// Needs to commit inside the context
$this->dbDriver->rollbackTransaction();
- $statement = $this->statementBLL->getById($statementId);
+ $statement = $this->statementBLL->getById($statement->getStatementId());
$this->assertNull($statement);
}
@@ -973,15 +976,14 @@ public function testJoinTransactionDifferentIsolationLevel()
try {
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->withdrawFunds(
+ $this->statementBLL->withdrawFunds(
StatementDTO::create($accountId, 10)
->setDescription('Test')
->setReferenceId('Referencia')
->setReferenceSource('Source')
->setCode('XYZ')
);
- }
- finally {
+ } finally {
$this->dbDriver->rollbackTransaction();
}
@@ -993,7 +995,7 @@ public function testAddFundsExtendedStatement()
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->addFunds(
+ $actual = $this->statementBLL->addFunds(
StatementDTO::create($accountId, 250)
->setDescription('Test Add Funds')
->setReferenceId('Referencia Add Funds')
@@ -1008,7 +1010,7 @@ public function testAddFundsExtendedStatement()
$statement->setDescription('Test Add Funds');
$statement->setGrossBalance('1250.00');
$statement->setAccountId($accountId);
- $statement->setStatementId($statementId);
+ $statement->setStatementId($actual->getStatementId());;
$statement->setTypeId('D');
$statement->setNetBalance('1250.00');
$statement->setPrice('1.00');
@@ -1017,11 +1019,136 @@ public function testAddFundsExtendedStatement()
$statement->setReferenceSource('Source Add Funds');
$statement->setAccountTypeId('USDTEST');
$statement->setExtraProperty('Extra');
-
- $actual = $this->statementBLL->getById($statementId);
$statement->setDate($actual->getDate());
$this->assertEquals($statement, $actual);
}
-}
+ public function testAddFundAccountNotFound()
+ {
+ $this->expectException(AccountException::class);
+ $this->expectExceptionMessage('Account not found');
+ $this->statementBLL->addFunds(StatementDTO::create(1023, 400)->setReferenceId('REFID')->setReferenceSource('REFSRC'));
+ }
+
+ public function testWithdrawFundAccountNotFound()
+ {
+ $this->expectException(AccountException::class);
+ $this->expectExceptionMessage('Account not found');
+ $this->statementBLL->withdrawFunds(StatementDTO::create(1023, 300)->setReferenceId('REFID2')->setReferenceSource('REFSRC'));
+ }
+
+ public function testReserveWithdrawFundAccountNotFound()
+ {
+ $this->expectException(AccountException::class);
+ $this->expectExceptionMessage('Account not found');
+ $this->statementBLL->reserveFundsForWithdraw(StatementDTO::create(1023, 300)->setReferenceId('REFID2')->setReferenceSource('REFSRC'));
+ }
+
+ public function testReserveDepositFundAccountNotFound()
+ {
+ $this->expectException(AccountException::class);
+ $this->expectExceptionMessage('Account not found');
+ $this->statementBLL->reserveFundsForDeposit(StatementDTO::create(1023, 300)->setReferenceId('REFID2')->setReferenceSource('REFSRC'));
+ }
+
+ public function testStatementObserver()
+ {
+ $accountRepository = new AccountRepositoryExtended($this->dbDriver, AccountEntity::class);
+ $statementRepository = new StatementRepositoryExtended($this->dbDriver, StatementEntity::class);
+
+ // Sanity Check
+ $this->assertFalse($accountRepository->getReach());
+ $this->assertFalse($statementRepository->getReach());
+
+ $accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
+ $this->statementBLL->addFunds(
+ StatementDTO::create($accountId, 250)
+ ->setDescription('Test Add Funds')
+ ->setReferenceId('Referencia Add Funds')
+ ->setReferenceSource('Source Add Funds')
+ );
+
+ // I don´t need to test the values, because it is tested before.
+ // I just need to check if the observer was called.
+ // And inside the observer, I will check the values.
+ $this->assertTrue($accountRepository->getReach());
+ $this->assertTrue($statementRepository->getReach());
+ }
+
+ public function testCapAtZeroFalse()
+ {
+ $this->expectException(AmountException::class);
+ $this->expectExceptionMessage('Cannot withdraw above the account balance');
+
+ $accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
+ $this->statementBLL->withdrawFunds(
+ StatementDTO::create($accountId, 1250)
+ ->setDescription('Test Add Funds')
+ ->setReferenceId('Referencia Add Funds')
+ ->setReferenceSource('Source Add Funds'),
+ capAtZero: false
+ );
+ }
+
+ public function testCapAtZeroTrue()
+ {
+ $accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
+
+ $dto = StatementDTO::create($accountId, 1100)
+ ->setDescription('Test Add Funds')
+ ->setReferenceId('Referencia Add Funds')
+ ->setReferenceSource('Source Add Funds');
+ $statement = $this->statementBLL->withdrawFunds(
+ $dto,
+ capAtZero: true
+ );
+
+ // Should be zero, because allow cap at zero
+ $account = $this->accountBLL->getById($accountId);
+ $this->assertEquals(0, $account->getGrossBalance());
+ $this->assertEquals(0, $account->getUnCleared());
+ $this->assertEquals(0, $account->getNetBalance());
+
+ // Needs to be adjusted to the new balance - 750
+ $statement = $this->statementBLL->getById($statement->getStatementId());
+ $this->assertEquals(1000, $statement->getAmount());
+
+ // The DTO should be the same
+ $this->assertEquals(1000, $dto->getAmount());;
+ }
+
+ public function testCapAtZeroTrueUncleared()
+ {
+ $accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
+
+ $this->statementBLL->reserveFundsForWithdraw(
+ StatementDTO::create($accountId, 250)
+ ->setDescription('Test Reserve Funds')
+ ->setReferenceId('Referencia Add Funds')
+ ->setReferenceSource('Source Add Funds')
+ );
+
+ $dto = StatementDTO::create($accountId, 800)
+ ->setDescription('Test Add Funds')
+ ->setReferenceId('Referencia Add Funds')
+ ->setReferenceSource('Source Add Funds');
+ $withdraw = $this->statementBLL->withdrawFunds(
+ $dto,
+ capAtZero: true
+ );
+
+ // Should be zero, because allow cap at zero
+ $account = $this->accountBLL->getById($accountId);
+ $this->assertEquals(250, $account->getGrossBalance());
+ $this->assertEquals(250, $account->getUnCleared());
+ $this->assertEquals(0, $account->getNetBalance());
+
+ // Needs to be adjusted to the new balance - 750
+ $statement = $this->statementBLL->getById($withdraw->getStatementId());
+ $this->assertEquals(750, $statement->getAmount());
+
+ // The DTO should be the same
+ $this->assertEquals(750, $dto->getAmount());;
+ }
+}
\ No newline at end of file
diff --git a/tests/Database/ReserveFundsDepositTest.php b/tests/Database/ReserveFundsDepositTest.php
index 12d63a1..61d0be8 100644
--- a/tests/Database/ReserveFundsDepositTest.php
+++ b/tests/Database/ReserveFundsDepositTest.php
@@ -38,7 +38,7 @@ public function testReserveForDepositFunds()
{
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->reserveFundsForDeposit(
+ $actual = $this->statementBLL->reserveFundsForDeposit(
StatementDTO::create($accountId, 350)
->setDescription('Test Deposit')
->setReferenceId('Referencia Deposit')
@@ -52,7 +52,7 @@ public function testReserveForDepositFunds()
$statement->setDescription('Test Deposit');
$statement->setGrossBalance('1000.00');
$statement->setAccountId($accountId);
- $statement->setStatementId($statementId);
+ $statement->setStatementId($actual->getStatementId());
$statement->setTypeId('DB');
$statement->setNetBalance('1350.00');
$statement->setPrice('1.00');
@@ -61,8 +61,6 @@ public function testReserveForDepositFunds()
$statement->setReferenceSource('Source Deposit');
$statement->setAccountTypeId('USDTEST');
$statement->setStatementParentId(null);
-
- $actual = $this->statementBLL->getById($statementId);
$statement->setDate($actual->getDate());
// Executar teste
@@ -89,11 +87,11 @@ public function testReserveForDepositFunds_InvalidRound()
$this->statementBLL->reserveFundsForDeposit(StatementDTO::create($accountId, 10.031)->setDescription('Test Withdraw')->setReferenceId('Referencia Withdraw'));
}
- public function testReserveForDepositFunds_Negative()
+ public function testReserveForDepositFunds_Allow_Negative()
{
// Populate Data!
- $accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", -200, 1, -400);
- $statementId = $this->statementBLL->reserveFundsForDeposit(
+ $accountId = $this->accountBLL->createAccount('NEGTEST', "___TESTUSER-1", -200, 1, -400);
+ $actual = $this->statementBLL->reserveFundsForDeposit(
StatementDTO::create($accountId, 300)
->setDescription('Test Deposit')
->setReferenceId('Referencia Deposit')
@@ -107,16 +105,14 @@ public function testReserveForDepositFunds_Negative()
$statement->setDescription('Test Deposit');
$statement->setGrossBalance('-200.00');
$statement->setAccountId($accountId);
- $statement->setStatementId($statementId);
+ $statement->setStatementId($actual->getStatementId());
$statement->setTypeId('DB');
$statement->setNetBalance('100.00');
$statement->setPrice('1.00');
$statement->setUnCleared('-300.00');
$statement->setReferenceId('Referencia Deposit');
$statement->setReferenceSource('Source Deposit');
- $statement->setAccountTypeId('USDTEST');
-
- $actual = $this->statementBLL->getById($statementId);
+ $statement->setAccountTypeId('NEGTEST');
$statement->setDate($actual->getDate());
// Executar teste
@@ -141,14 +137,14 @@ public function testAcceptFundsById_InvalidType()
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->addFunds(
+ $statement = $this->statementBLL->addFunds(
StatementDTO::create($accountId, 200)
->setDescription('Test Deposit')
->setReferenceId('Referencia Deposit')
->setReferenceSource('Source Deposit')
);
- $this->statementBLL->acceptFundsById($statementId);
+ $this->statementBLL->acceptFundsById($statement->getStatementId());;
}
public function testAcceptFundsById_HasParentTransation()
@@ -158,13 +154,13 @@ public function testAcceptFundsById_HasParentTransation()
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
$this->statementBLL->addFunds(StatementDTO::create($accountId, 150)->setDescription('Test Deposit')->setReferenceId('Referencia Deposit'));
- $statementId = $this->statementBLL->reserveFundsForDeposit(StatementDTO::create($accountId, 350)->setDescription('Test Deposit')->setReferenceId('Referencia Deposit'));
+ $statement = $this->statementBLL->reserveFundsForDeposit(StatementDTO::create($accountId, 350)->setDescription('Test Deposit')->setReferenceId('Referencia Deposit'));
// Executar ação
- $this->statementBLL->acceptFundsById($statementId);
+ $this->statementBLL->acceptFundsById($statement->getStatementId());;
// Provar o erro:
- $this->statementBLL->acceptFundsById($statementId);
+ $this->statementBLL->acceptFundsById($statement->getStatementId());;
}
public function testAcceptFundsById_OK()
@@ -177,7 +173,7 @@ public function testAcceptFundsById_OK()
->setReferenceId('Referencia Deposit')
->setReferenceSource('Source Deposit')
);
- $statementId = $this->statementBLL->reserveFundsForDeposit(
+ $reserveStatement = $this->statementBLL->reserveFundsForDeposit(
StatementDTO::create($accountId, 350)
->setDescription('Test Deposit')
->setReferenceId('Referencia Deposit')
@@ -185,7 +181,7 @@ public function testAcceptFundsById_OK()
);
// Executar ação
- $actualId = $this->statementBLL->acceptFundsById($statementId);
+ $actualId = $this->statementBLL->acceptFundsById($reserveStatement->getStatementId());
$actual = $this->statementBLL->getById($actualId);
// Objeto que é esperado
@@ -195,7 +191,7 @@ public function testAcceptFundsById_OK()
$statement->setGrossBalance('1500.00');
$statement->setAccountId($accountId);
$statement->setStatementId($actualId);
- $statement->setStatementParentId($statementId);
+ $statement->setStatementParentId($reserveStatement->getStatementId());
$statement->setTypeId('D');
$statement->setNetBalance('1500.00');
$statement->setPrice('1.00');
@@ -214,7 +210,7 @@ public function testAcceptPartialFundsById_PartialAmountZero()
$this->expectException(AmountException::class);
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $reserveStatementId = $this->statementBLL->reserveFundsForWithdraw(
+ $reserveStatement = $this->statementBLL->reserveFundsForWithdraw(
StatementDTO::create($accountId, 100)
);
@@ -223,7 +219,7 @@ public function testAcceptPartialFundsById_PartialAmountZero()
->setReferenceSource("test-source");
$statementDTO = StatementDTO::createEmpty()->setAmount(0);
- $this->statementBLL->acceptPartialFundsById($reserveStatementId, $statementDTO, $statementRefundDto);
+ $this->statementBLL->acceptPartialFundsById($reserveStatement->getStatementId(), $statementDTO, $statementRefundDto);
}
public function testAcceptPartialFundsById_AmountMoreThanWithdrawBlocked()
@@ -232,7 +228,7 @@ public function testAcceptPartialFundsById_AmountMoreThanWithdrawBlocked()
$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(
+ $reserveStatement = $this->statementBLL->reserveFundsForWithdraw(
StatementDTO::create($accountId, 100)
);
@@ -241,13 +237,13 @@ public function testAcceptPartialFundsById_AmountMoreThanWithdrawBlocked()
->setReferenceSource("test-source");
$statementDTO = StatementDTO::createEmpty()->setAmount(100.01);
- $this->statementBLL->acceptPartialFundsById($reserveStatementId, $statementDTO, $statementRefundDto);
+ $this->statementBLL->acceptPartialFundsById($reserveStatement->getStatementId(), $statementDTO, $statementRefundDto);
}
public function testAcceptPartialFundsById_OK()
{
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $reserveStatementId = $this->statementBLL->reserveFundsForWithdraw(
+ $reserveStatement = $this->statementBLL->reserveFundsForWithdraw(
StatementDTO::create($accountId, 100)->setDescription('Reserva para Aposta')
);
@@ -260,8 +256,8 @@ public function testAcceptPartialFundsById_OK()
->setDescription("Refund")
->setReferenceSource("test-source");
- $finalDebitStatementId = $this->statementBLL->acceptPartialFundsById(
- $reserveStatementId,
+ $finalDebitStatement = $this->statementBLL->acceptPartialFundsById(
+ $reserveStatement->getStatementId(),
$statementWithdrawDto,
$statementRefundDto
);
@@ -271,13 +267,13 @@ public function testAcceptPartialFundsById_OK()
$this->assertEquals('920.00', $accountAfter->getNetBalance());
$this->assertEquals('0.00', $accountAfter->getUnCleared());
- $rejectedStatement = $this->statementBLL->getRepository()->getByParentId($reserveStatementId);
+ $rejectedStatement = $this->statementBLL->getRepository()->getByParentId($reserveStatement->getStatementId());
$this->assertNotNull($rejectedStatement);
$this->assertEquals(StatementEntity::REJECT, $rejectedStatement->getTypeId());
$this->assertEquals('100.00', $rejectedStatement->getAmount());
/** @var StatementEntity $finalDebitStatement */
- $finalDebitStatement = $this->statementBLL->getById($finalDebitStatementId);
+ $finalDebitStatement = $this->statementBLL->getById($finalDebitStatement->getStatementId());
$this->assertEquals('80.00', $finalDebitStatement->getAmount());
$this->assertEquals(StatementEntity::WITHDRAW, $finalDebitStatement->getTypeId());
$this->assertEquals("Deposit", $finalDebitStatement->getDescription());
@@ -289,9 +285,9 @@ public function testRejectFundsById_InvalidType()
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->addFunds(StatementDTO::create($accountId, 300));
+ $statement = $this->statementBLL->addFunds(StatementDTO::create($accountId, 300));
- $this->statementBLL->rejectFundsById($statementId);
+ $this->statementBLL->rejectFundsById($statement->getStatementId());
}
public function testRejectFundsById_HasParentTransation()
@@ -301,13 +297,13 @@ public function testRejectFundsById_HasParentTransation()
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
$this->statementBLL->addFunds(StatementDTO::create($accountId, 150)->setDescription('Test Deposit')->setReferenceId('Referencia Deposit'));
- $statementId = $this->statementBLL->reserveFundsForDeposit(StatementDTO::create($accountId, 350)->setDescription('Test Deposit')->setReferenceId('Referencia Deposit'));
+ $reserveStatement = $this->statementBLL->reserveFundsForDeposit(StatementDTO::create($accountId, 350)->setDescription('Test Deposit')->setReferenceId('Referencia Deposit'));
// Executar ação
- $this->statementBLL->rejectFundsById($statementId);
+ $this->statementBLL->rejectFundsById($reserveStatement->getStatementId());
// Provocar o erro:
- $this->statementBLL->rejectFundsById($statementId);
+ $this->statementBLL->rejectFundsById($reserveStatement->getStatementId());
}
public function testRejectFundsById_OK()
@@ -320,7 +316,7 @@ public function testRejectFundsById_OK()
->setReferenceId('Referencia Deposit')
->setReferenceSource('Source Deposit')
);
- $statementId = $this->statementBLL->reserveFundsForDeposit(
+ $reserveStatement = $this->statementBLL->reserveFundsForDeposit(
StatementDTO::create($accountId, 350)
->setDescription('Test Deposit')
->setReferenceId('Referencia Deposit')
@@ -328,7 +324,7 @@ public function testRejectFundsById_OK()
);
// Executar ação
- $actualId = $this->statementBLL->rejectFundsById($statementId);
+ $actualId = $this->statementBLL->rejectFundsById($reserveStatement->getStatementId());
$actual = $this->statementBLL->getById($actualId);
// Objeto que é esperado
@@ -338,7 +334,7 @@ public function testRejectFundsById_OK()
$statement->setGrossBalance('1150.00');
$statement->setAccountId($accountId);
$statement->setStatementId($actualId);
- $statement->setStatementParentId($statementId);
+ $statement->setStatementParentId($reserveStatement->getStatementId());
$statement->setTypeId('R');
$statement->setNetBalance('1150.00');
$statement->setPrice('1.00');
diff --git a/tests/Database/ReserveFundsWithdrawTest.php b/tests/Database/ReserveFundsWithdrawTest.php
index 76dfa9d..81bfe72 100644
--- a/tests/Database/ReserveFundsWithdrawTest.php
+++ b/tests/Database/ReserveFundsWithdrawTest.php
@@ -37,7 +37,7 @@ public function testReserveForWithdrawFunds()
{
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->reserveFundsForWithdraw(
+ $actual = $this->statementBLL->reserveFundsForWithdraw(
StatementDTO::create($accountId, 350)
->setDescription('Test Withdraw')
->setReferenceId('Referencia Withdraw')
@@ -51,7 +51,7 @@ public function testReserveForWithdrawFunds()
$statement->setDescription('Test Withdraw');
$statement->setGrossBalance('1000.00');
$statement->setAccountId($accountId);
- $statement->setStatementId($statementId);
+ $statement->setStatementId($actual->getStatementId());;
$statement->setTypeId('WB');
$statement->setNetBalance('650.00');
$statement->setPrice('1.00');
@@ -59,8 +59,6 @@ public function testReserveForWithdrawFunds()
$statement->setReferenceId('Referencia Withdraw');
$statement->setReferenceSource('Source Withdraw');
$statement->setAccountTypeId('USDTEST');
-
- $actual = $this->statementBLL->getById($statementId);
$statement->setDate($actual->getDate());
// Executar teste
@@ -95,11 +93,11 @@ public function testReserveForWithdrawFunds_InvalidRound()
->setReferenceSource('Source Withdraw'));
}
- public function testReserveForWithdrawFunds_Negative()
+ public function testReserveForWithdrawFunds_Allow_Negative()
{
// Populate Data!
- $accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000, 1, -400);
- $statementId = $this->statementBLL->reserveFundsForWithdraw(
+ $accountId = $this->accountBLL->createAccount('NEGTEST', "___TESTUSER-1", 1000, 1, -400);
+ $actual = $this->statementBLL->reserveFundsForWithdraw(
StatementDTO::create($accountId, 1150)
->setDescription('Test Withdraw')
->setReferenceId('Referencia Withdraw')
@@ -113,16 +111,14 @@ public function testReserveForWithdrawFunds_Negative()
$statement->setDescription('Test Withdraw');
$statement->setGrossBalance('1000.00');
$statement->setAccountId($accountId);
- $statement->setStatementId($statementId);
+ $statement->setStatementId($actual->getStatementId());
$statement->setTypeId('WB');
$statement->setNetBalance('-150.00');
$statement->setPrice('1.00');
$statement->setUnCleared('1150.00');
$statement->setReferenceId('Referencia Withdraw');
$statement->setReferenceSource('Source Withdraw');
- $statement->setAccountTypeId('USDTEST');
-
- $actual = $this->statementBLL->getById($statementId);
+ $statement->setAccountTypeId('NEGTEST');
$statement->setDate($actual->getDate());
// Executar teste
@@ -159,14 +155,14 @@ public function testAcceptFundsById_InvalidType()
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->withdrawFunds(
+ $statement = $this->statementBLL->withdrawFunds(
StatementDTO::create($accountId, 200)
->setDescription('Test Withdraw')
->setReferenceId('Referencia Withdraw')
->setReferenceSource('Source Withdraw')
);
- $this->statementBLL->acceptFundsById($statementId);
+ $this->statementBLL->acceptFundsById($statement->getStatementId());
}
public function testAcceptFundsById_HasParentTransation()
@@ -176,13 +172,13 @@ public function testAcceptFundsById_HasParentTransation()
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
$this->statementBLL->withdrawFunds(StatementDTO::create($accountId, 150)->setDescription('Test Withdraw')->setReferenceId('Referencia Withdraw'));
- $statementId = $this->statementBLL->reserveFundsForWithdraw(StatementDTO::create($accountId, 350)->setDescription('Test Withdraw')->setReferenceId('Referencia Withdraw'));
+ $statement = $this->statementBLL->reserveFundsForWithdraw(StatementDTO::create($accountId, 350)->setDescription('Test Withdraw')->setReferenceId('Referencia Withdraw'));
// Executar ação
- $this->statementBLL->acceptFundsById($statementId);
+ $this->statementBLL->acceptFundsById($statement->getStatementId());
// Provar o erro:
- $this->statementBLL->acceptFundsById($statementId);
+ $this->statementBLL->acceptFundsById($statement->getStatementId());
}
public function testAcceptFundsById_OK()
@@ -195,7 +191,7 @@ public function testAcceptFundsById_OK()
->setReferenceId('Referencia Withdraw')
->setReferenceSource('Source Withdraw')
);
- $statementId = $this->statementBLL->reserveFundsForWithdraw(
+ $reserveStatement = $this->statementBLL->reserveFundsForWithdraw(
StatementDTO::create($accountId, 350)
->setDescription('Test Withdraw')
->setReferenceId('Referencia Withdraw')
@@ -203,7 +199,7 @@ public function testAcceptFundsById_OK()
);
// Executar ação
- $actualId = $this->statementBLL->acceptFundsById($statementId);
+ $actualId = $this->statementBLL->acceptFundsById($reserveStatement->getStatementId());
$actual = $this->statementBLL->getById($actualId);
// Objeto que é esperado
@@ -213,7 +209,7 @@ public function testAcceptFundsById_OK()
$statement->setGrossBalance('500.00');
$statement->setAccountId($accountId);
$statement->setStatementId($actualId);
- $statement->setStatementParentId($statementId);
+ $statement->setStatementParentId($reserveStatement->getStatementId());
$statement->setTypeId('W');
$statement->setNetBalance('500.00');
$statement->setPrice('1.00');
@@ -243,9 +239,9 @@ public function testRejectFundsById_InvalidType()
// Populate Data!
$accountId = $this->accountBLL->createAccount('USDTEST', "___TESTUSER-1", 1000);
- $statementId = $this->statementBLL->withdrawFunds(StatementDTO::create($accountId, 300));
+ $statement = $this->statementBLL->withdrawFunds(StatementDTO::create($accountId, 300));
- $this->statementBLL->rejectFundsById($statementId);
+ $this->statementBLL->rejectFundsById($statement->getStatementId());
}
public function testRejectFundsById_HasParentTransation()
@@ -260,7 +256,7 @@ public function testRejectFundsById_HasParentTransation()
->setReferenceId('Referencia Withdraw')
->setReferenceSource('Source Withdraw')
);
- $statementId = $this->statementBLL->reserveFundsForWithdraw(
+ $statement = $this->statementBLL->reserveFundsForWithdraw(
StatementDTO::create($accountId, 350)
->setDescription('Test Withdraw')
->setReferenceId('Referencia Withdraw')
@@ -268,10 +264,10 @@ public function testRejectFundsById_HasParentTransation()
);
// Executar ação
- $this->statementBLL->rejectFundsById($statementId);
+ $this->statementBLL->rejectFundsById($statement->getStatementId());
// Provocar o erro:
- $this->statementBLL->rejectFundsById($statementId);
+ $this->statementBLL->rejectFundsById($statement->getStatementId());
}
public function testRejectFundsById_OK()
@@ -284,7 +280,7 @@ public function testRejectFundsById_OK()
->setReferenceId('Referencia Withdraw')
->setReferenceSource('Source Withdraw')
);
- $statementId = $this->statementBLL->reserveFundsForWithdraw(
+ $reserveStatement = $this->statementBLL->reserveFundsForWithdraw(
StatementDTO::create($accountId, 350)
->setDescription('Test Withdraw')
->setReferenceId('Referencia Withdraw')
@@ -292,7 +288,7 @@ public function testRejectFundsById_OK()
);
// Executar ação
- $actualId = $this->statementBLL->rejectFundsById($statementId);
+ $actualId = $this->statementBLL->rejectFundsById($reserveStatement->getStatementId());
$actual = $this->statementBLL->getById($actualId);
// Objeto que é esperado
@@ -302,7 +298,7 @@ public function testRejectFundsById_OK()
$statement->setGrossBalance('850.00');
$statement->setAccountId($accountId);
$statement->setStatementId($actualId);
- $statement->setStatementParentId($statementId);
+ $statement->setStatementParentId($reserveStatement->getStatementId());
$statement->setTypeId('R');
$statement->setNetBalance('850.00');
$statement->setPrice('1.00');