Пример #1
0
        private async Task <DomainValidationResult <ITransaction> > CreateDepositTransactionAsync(
            IMoneyAccount account,
            Money money,
            CancellationToken cancellationToken = default
            )
        {
            var result = new DomainValidationResult <ITransaction>();

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

            if (transactionBundles.All(deposit => deposit.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.IsDepositAvailable())
            {
                result.AddFailedPreconditionError(
                    $"Deposit is unavailable until {account.LastDeposit?.Add(MoneyAccountDecorator.DepositInterval)}. For security reason we limit the number of financial transaction that can be done in {MoneyAccountDecorator.DepositInterval.TotalHours} hours.");
            }

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

                await _accountRepository.CommitAsync(true, cancellationToken);

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

            return(result);
        }
Пример #2
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);
        }
Пример #3
0
        private async Task <DomainValidationResult <ITransaction> > CreateTransactionAsync(
            IMoneyAccount account,
            Money money,
            TransactionType type,
            TransactionMetadata?metadata        = null,
            CancellationToken cancellationToken = default
            )
        {
            if (type == TransactionType.Deposit)
            {
                return(await this.CreateDepositTransactionAsync(account, money, cancellationToken));
            }

            if (type == TransactionType.Withdraw)
            {
                return(await this.CreateWithdrawTransactionAsync(account, money, cancellationToken));
            }

            if (type == TransactionType.Charge)
            {
                return(await this.CreateChargeTransactionAsync(
                           account,
                           money,
                           metadata,
                           cancellationToken));
            }

            if (type == TransactionType.Payout)
            {
                return(await this.CreatePayoutTransactionAsync(
                           account,
                           money,
                           metadata,
                           cancellationToken));
            }

            if (type == TransactionType.Promotion)
            {
                return(await this.CreatePromotionTransactionAsync(
                           account,
                           money,
                           metadata,
                           cancellationToken));
            }

            return(DomainValidationResult <ITransaction> .Failure("Unsupported transaction type for money currency."));
        }
Пример #4
0
        private async Task <DomainValidationResult <ITransaction> > CreatePromotionTransactionAsync(
            IMoneyAccount account,
            Money money,
            TransactionMetadata?metadata        = null,
            CancellationToken cancellationToken = default
            )
        {
            var result = new DomainValidationResult <ITransaction>();

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

                transaction.MarkAsSucceeded();

                await _accountRepository.CommitAsync(true, cancellationToken);

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

            return(result);
        }