Beispiel #1
0
        private async Task <DomainValidationResult <ITransaction> > CreateChargeTransactionAsync(
            IMoneyAccount account,
            Money money,
            TransactionMetadata?metadata        = null,
            CancellationToken cancellationToken = default
            )
        {
            var result = new DomainValidationResult <ITransaction>();

            if (!account.HaveSufficientMoney(money))
            {
                result.AddFailedPreconditionError("Insufficient funds.");
            }

            if (result.IsValid)
            {
                var transaction = account.Charge(money, metadata);

                await _accountRepository.CommitAsync(true, cancellationToken);

                return(transaction.Cast <Transaction>());
            }

            return(result);
        }
Beispiel #2
0
        private async Task <DomainValidationResult <ITransaction> > CreateWithdrawTransactionAsync(
            IMoneyAccount account,
            Money money,
            CancellationToken cancellationToken = default
            )
        {
            var result = new DomainValidationResult <ITransaction>();

            var transactionBundles = await this.FetchTransactionBundlesAsync(EnumTransactionType.Withdraw, EnumCurrencyType.Money);

            if (transactionBundles.All(withdraw => withdraw.Currency.Amount != money.Amount))
            {
                result.AddFailedPreconditionError(
                    $"The amount of {nameof(Money)} is invalid. These are valid amounts: [{string.Join(", ", transactionBundles.Select(deposit => deposit.Currency.Amount))}].");
            }

            if (!account.HaveSufficientMoney(money))
            {
                result.AddFailedPreconditionError("Insufficient funds.");
            }

            if (!account.IsWithdrawAvailable())
            {
                result.AddFailedPreconditionError(
                    $"Withdraw is unavailable until {account.LastWithdraw?.Add(MoneyAccountDecorator.WithdrawInterval)}. For security reason we limit the number of financial transaction that can be done in {MoneyAccountDecorator.WithdrawInterval.TotalHours} hours.");
            }

            if (result.IsValid)
            {
                var transaction = account.Withdraw(money);

                await _accountRepository.CommitAsync(true, cancellationToken);

                return(transaction.Cast <Transaction>());
            }

            return(result);
        }