public TransactionViewModel(Transaction transaction) { TransactionId = transaction.TransactionId; Message = transaction.Message; IsCommited = transaction.IsCommited; Amount = transaction.Amount; Type = transaction.Type.ToString(); }
/// <summary> /// Initiales a new instance of <see cref="BusinessRuleBase"/> /// </summary> /// <param name="transaction"></param> public BusinessRuleBase(Transaction transaction) { if (transaction == null) throw new ArgumentNullException("transaction"); Transaction = transaction; _errors = new List<BusinessError>(); }
/// <summary> /// Executes the transaction /// </summary> /// <param name="transaction"><see cref="Transaction"/> entity</param> public void Execute(Transaction transaction) { if (transaction == null) throw new ArgumentNullException("transaction"); if (transaction.IsCommited) throw new ArgumentException("Cann't execute a commited transaction"); var account = transaction.Account; var amount = transaction.Amount; account.Balance += amount; transaction.IsCommited = true; }
/// <summary> /// Validates <see cref="Transaction"/> transaction /// </summary> /// <param name="userAccounts">Collection of the user's accounts</param> /// <param name="transaction"><see cref="Transaction"/> entity</param> /// <returns>Collection of <see cref="BusinessError"/></returns> public IEnumerable<BusinessError> Validate(IEnumerable<Account> userAccounts, Transaction transaction) { if (!userAccounts.All(x => x.User == transaction.Account.User)) throw new ArgumentException("Not all accounts belong to this user"); var rules = GetBusinessRules(userAccounts, transaction); var errors = new List<BusinessError>(); foreach (var rule in rules) { if(!rule.CanExecuteTransaction()) errors.AddRange(rule.GetErrors()); } if (errors.Count > 0) { var sb = new StringBuilder(); errors.ForEach(x => sb.AppendLine(x.Message)); transaction.Message = sb.ToString(); } return errors; }
/// <summary> /// Initializes a new instance of <see cref="AccountCantHaveLess100"/> /// </summary> /// <param name="transaction">Transaction</param> public AccountCantHaveLess100(Transaction transaction) : base(transaction) { }
/// <summary> /// Creates a new transaction /// </summary> /// <param name="transactionType">The type of the transaction</param> /// <param name="account"><see cref="Account"/> entity</param> /// <param name="amount">Amount</param> /// <returns>Created transaction</returns> public Transaction CreateTransaction(TransactionType transactionType, Account account, Decimal amount) { if (transactionType == TransactionType.NotSpecified) throw new ArgumentException("The transaction's type cann't be not specified"); if (account == null) throw new ArgumentNullException("account"); if (amount <= 0) throw new ArgumentException("Amount cann't be less or equal 0"); if (!DoesTheAccountExist(account)) throw new ArgumentException(String.Format("Account with ID {0} wasn't found", account.AccountId)); var transaction = new Transaction { Account = account, Amount = amount, Type = transactionType, IsCommited = false }; _transactionRepository.Add(transaction); return transaction; }
/// <summary> /// Checks exist the transaction in the collection of the transactions /// </summary> /// <param name="transaction"></param> /// <returns></returns> private Boolean DoesTheTransactionExist(Transaction transaction) { if (transaction == null) throw new ArgumentNullException("transaction"); return _transactionRepository.Query().Any(x => x.TransactionId == transaction.TransactionId); }
/// <summary> /// Executes the transaction /// </summary> /// <param name="transaction"><see cref="Transaction"/> entity</param> public IEnumerable<BusinessError> ExecuteTransaction(Transaction transaction) { if (transaction == null) throw new ArgumentNullException("transaction"); if (transaction.IsCommited) throw new ArgumentException("Cann't execute a commited transaction"); if (!DoesTheTransactionExist(transaction)) throw new ArgumentException(String.Format("The transaction with ID {0} wasn't found", transaction.TransactionId)); // validate transaction by business rules var userAccounts = _accountRepository.GetAccountsForUser(transaction.Account.User); var errors = _rulesService.Validate(userAccounts, transaction); var isValid = !errors.Any(); // if it doesn't have errors then execute transaction if (isValid) { var executer = GetTransactionExecutorByType(transaction.Type); executer.Execute(transaction); } _transactionRepository.Update(transaction); return errors; }
/// <summary> /// Initializes a new instance of <see cref="UserCantDepositMoreThan10000InTransaction"/> /// </summary> /// <param name="transaction"></param> public UserCantDepositMoreThan10000InTransaction(Transaction transaction) : base(transaction) { }
/// <summary> /// Gets business rules /// </summary> /// <param name="userAccounts">Collection of the user's accounts</param> /// <param name="transaction"><see cref="Transaction"/> entity</param> /// <returns>Collection of <see cref="IBusinessRule"/></returns> private IEnumerable<IBusinessRule> GetBusinessRules(IEnumerable<Account> userAccounts, Transaction transaction) { yield return new AccountCantHaveLess100(transaction); yield return new UserCantWithdrawMoreThan90PercentTotalBalance(userAccounts, transaction); yield return new UserCantDepositMoreThan10000InTransaction(transaction); }
/// <summary> /// Initializes a new instance of <see cref="UserCantWithdrawMoreThan90PercentTotalBalance"/> /// </summary> /// <param name="userAccounts">Collection of the accounts of the user</param> /// <param name="transaction"><see cref="Transaction"/> entity</param> public UserCantWithdrawMoreThan90PercentTotalBalance(IEnumerable<Account> userAccounts, Transaction transaction) : base(transaction) { _userAccounts = userAccounts; }