Skip to content

Instantly share code, notes, and snippets.

@Ensive
Last active February 1, 2022 14:13
Show Gist options
  • Select an option

  • Save Ensive/2d2bfc3929692bc22ad4be2e5b8bd833 to your computer and use it in GitHub Desktop.

Select an option

Save Ensive/2d2bfc3929692bc22ad4be2e5b8bd833 to your computer and use it in GitHub Desktop.
TopUpTradingAccountCommand.php
<?php
declare(strict_types=1);
namespace Fndx\Application\UseCase\TradingAccount;
use Fndx\Domain\Client\Contract\ClientServiceInterface;
use Fndx\Domain\Client\Exception\ClientNotFoundException;
use Fndx\Domain\Identity\Exception\IdentityNotFoundException;
use Fndx\Domain\Permission\AggregateRoot\Permission;
use Fndx\Domain\TradingAccount\Exception\InvalidTradingAccountStatusException;
use Fndx\Domain\TradingAccount\Exception\TradingAccountTopUpFromDemoException;
use Fndx\Domain\Transaction\ValueObject\TransactionCreationType;
use Fndx\Domain\Transaction\ValueObject\TransactionStatus;
use Fndx\Domain\Transaction\ValueObject\TransactionType;
use Fndx\Infrastructure\Core\Exception\AccessNotAllowedException;
use Fndx\Domain\Money\Exception\NegativeAmountException;
use Fndx\Domain\PaymentMethod\AggregateRoot\PaymentMethod;
use Fndx\Domain\Money\Exception\NotEnoughBalanceException;
use Fndx\Domain\Money\Exception\AmountCannotBeZeroException;
use Fndx\Domain\Transaction\Contract\TransactionServiceInterface;
use Fndx\Domain\PaymentMethod\Exception\InvalidPaymentMethodException;
use Fndx\Domain\Transaction\Exception\InvalidTransactionTypeException;
use Fndx\Domain\FundingRequest\Contract\FundingRequestServiceInterface;
use Fndx\Domain\TradingAccount\Contract\TradingAccountServiceInterface;
use Fndx\Domain\Transaction\Exception\InvalidTransactionStatusException;
use Fndx\Domain\PersonalAccount\Contract\PersonalAccountServiceInterface;
use Fndx\Domain\TradingAccount\Exception\TradingAccountNotFoundException;
use Fndx\Domain\PersonalAccount\Exception\PersonalAccountNotFoundException;
use Fndx\Domain\Transaction\Exception\InvalidTransactionCreationTypeException;
use Fndx\Application\UseCase\PaymentAndTransactionAwareFundingRequestCommandTrait;
use Fndx\Infrastructure\TradingAccount\DTO\Request\TopUpTradingAccountRequestDTO;
use Fndx\Infrastructure\Transaction\DTO\Request\CreateTransactionRequestDTO;
use function Fndx\Infrastructure\Helpers\map;
class TopUpTradingAccountCommand extends AbstractTradingAccountCommand
{
use PaymentAndTransactionAwareFundingRequestCommandTrait;
protected const TARGET_PERMISSION = Permission::TRADING_ACCOUNT_TOP_UP;
protected TradingAccountServiceInterface $tradingAccountService;
protected FundingRequestServiceInterface $fundingRequestService;
protected PersonalAccountServiceInterface $personalAccountService;
protected ClientServiceInterface $clientService;
public function __construct(
TradingAccountServiceInterface $tradingAccountService,
FundingRequestServiceInterface $fundingRequestService,
PersonalAccountServiceInterface $personalAccountService,
TransactionServiceInterface $transactionService,
ClientServiceInterface $clientService
) {
parent::__construct();
$this->tradingAccountService = $tradingAccountService;
$this->fundingRequestService = $fundingRequestService;
$this->personalAccountService = $personalAccountService;
$this->transactionService = $transactionService;
$this->clientService = $clientService;
}
/**
* @param TopUpTradingAccountRequestDTO $dto
* @param string $tradingAccountId
* @return void
* @throws AccessNotAllowedException
* @throws AmountCannotBeZeroException
* @throws IdentityNotFoundException
* @throws InvalidPaymentMethodException
* @throws InvalidTradingAccountStatusException
* @throws InvalidTransactionCreationTypeException
* @throws InvalidTransactionStatusException
* @throws InvalidTransactionTypeException
* @throws NegativeAmountException
* @throws NotEnoughBalanceException
* @throws PersonalAccountNotFoundException
* @throws TradingAccountNotFoundException
* @throws TradingAccountTopUpFromDemoException
* @throws ClientNotFoundException
*/
public function run(TopUpTradingAccountRequestDTO $dto, string $tradingAccountId): void
{
$tradingAccount = $this->tradingAccountService->getById($tradingAccountId);
$client = $this->clientService->getById($tradingAccount->clientId());
$this->checkPermission($client->identityId());
if ($tradingAccount->isDemo()) {
throw new TradingAccountTopUpFromDemoException();
}
if ($tradingAccount->status()->isPending()) {
throw new InvalidTradingAccountStatusException(
$this->lang->translate('exception.you_cannot_top_up_trading_account_in_pending_state')
);
}
$personalAccount = $this->personalAccountService->getByClientId($client->id());
$personalAccount->balance()->subtract($dto->amount);
$tradingAccount->topUp($dto->amount);
$transactionDto = map(CreateTransactionRequestDTO::class)->from(
[
'clientId' => $client->id(),
'createdByIdentityId' => $this->getPerformerIdentity()->id(),
'type' => TransactionType::INTERNAL_TRANSFER,
'creationType' => TransactionCreationType::MANUAL,
'amount' => $dto->amount,
'status' => TransactionStatus::COMPLETED,
'fundingRequestId' => null,
'productId' => null,
'fromPaymentMethodId' => PaymentMethod::PERSONAL_ACCOUNT,
'fromSourceId' => $client->id(),
'toPaymentMethodId' => PaymentMethod::TRADING_ACCOUNT,
'toSourceId' => $tradingAccount->id()
]
);
$transaction = $this->transactionService->create($transactionDto, $client->identityId());
$this->transactionService->save($transaction);
$this->personalAccountService->save($personalAccount);
$this->tradingAccountService->save($tradingAccount);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment