/// <summary>
        /// <see cref="Microsoft.Samples.NLayerApp.Domain.MainModule.BankAccounts.IBankTransferDomainService"/>
        /// </summary>
        /// <param name="originAccount"><see cref="Microsoft.Samples.NLayerApp.Domain.MainModule.BankAccounts.IBankTransferDomainService"/></param>
        /// <param name="destinationAccount"><see cref="Microsoft.Samples.NLayerApp.Domain.MainModule.BankAccounts.IBankTransferDomainService"/></param>
        /// <param name="amount"><see cref="Microsoft.Samples.NLayerApp.Domain.MainModule.BankAccounts.IBankTransferDomainService"/></param>
        public void PerformTransfer(BankAccount originAccount, BankAccount destinationAccount, decimal amount)
        {
            //Domain Logic
            //Process: Perform transfer operations to in-memory Domain-Model Objects        
            // 1.- Charge money to origin acc
            // 2.- Credit money to destination acc
            // 3.- Annotate transfer to origin account

            //Number Accounts must be different
            if (originAccount.BankAccountNumber != destinationAccount.BankAccountNumber)
            {
                //1. Charge to origin account (Domain Logic)
                originAccount.ChargeMoney(amount);

                //2. Credit to destination account (Domain Logic)
                destinationAccount.CreditMoney(amount);

                //3. Anotate transfer to related origin account                
                originAccount.BankTransfersFromThis.Add(new BankTransfer()
                {
                    Amount = amount,
                    TransferDate = DateTime.UtcNow,
                    ToBankAccountId = destinationAccount.BankAccountId
                });
            }
            else
                throw new InvalidOperationException(Resources.Messages.exception_InvalidAccountsForTransfer);

        }
        public void TransferRate_Invoke_Test()
        {
            //Arrange
            BankAccount bankAccount = new BankAccount()
            {
                BankAccountId = 1,
                Balance = 1000M,
                BankAccountNumber = "A001",
                CustomerId = 1,
                Locked = false,
                BankTransfersFromThis = new TrackableCollection<BankTransfer>()
                                       {
                                           new BankTransfer(){Amount=100,BankTransferId=1,TransferDate = DateTime.Now,FromBankAccountId=1,ToBankAccountId=2}
                                       },
                BankTransfersToThis = new TrackableCollection<BankTransfer>()
                                        {
                                            new BankTransfer(){Amount=100,BankTransferId=1,TransferDate = DateTime.Now,FromBankAccountId=2,ToBankAccountId=1}
                                        }
            };

            //act
            decimal result = bankAccount.TransferRate(DateTime.Now.AddDays(-1), DateTime.Now.AddDays(1));

            //Assert
            Assert.IsTrue(result == 0M);
        }
        public void CanTransferMoney_ExcesibeAmountReturnFalse_Test()
        {
            //Arrange
            BankAccount bankAccount = new BankAccount()
            {
                BankAccountId = 1,
                Balance = 100M,
                BankAccountNumber = "A001",
                CustomerId = 1,
                Locked = false
            };

            //Act
            bool canTransferMoney = bankAccount.CanBeCharged(1000);

            //Assert
            Assert.IsFalse(canTransferMoney);
        }
     private void FixupBankAccount1(BankAccount previousValue)
     {
         if (IsDeserializing)
         {
             return;
         }
 
         if (previousValue != null && previousValue.BankTransfersToThis.Contains(this))
         {
             previousValue.BankTransfersToThis.Remove(this);
         }
 
         if (BankAccount1 != null)
         {
             if (!BankAccount1.BankTransfersToThis.Contains(this))
             {
                 BankAccount1.BankTransfersToThis.Add(this);
             }
 
             ToBankAccountId = BankAccount1.BankAccountId;
         }
         if (ChangeTracker.ChangeTrackingEnabled)
         {
             if (ChangeTracker.OriginalValues.ContainsKey("BankAccount1")
                 && (ChangeTracker.OriginalValues["BankAccount1"] == BankAccount1))
             {
                 ChangeTracker.OriginalValues.Remove("BankAccount1");
             }
             else
             {
                 ChangeTracker.RecordOriginalValue("BankAccount1", previousValue);
             }
             if (BankAccount1 != null && !BankAccount1.ChangeTracker.ChangeTrackingEnabled)
             {
                 BankAccount1.StartTracking();
             }
         }
     }
        public void AddBankAccount_Invoke_Test()
        {
            //Arrange
            using (IBankingManagementService bankAccountService = IoCFactory.Instance.CurrentContainer.Resolve<IBankingManagementService>())
            {
                string bankAccountNumber = "BAC0000999";

                //Act
                BankAccount bankAccount = new BankAccount()
                {
                    Balance = 1000,
                    BankAccountNumber = bankAccountNumber,
                    CustomerId = 1
                };

                bankAccountService.AddBankAccount(bankAccount);
                BankAccount actual = bankAccountService.FindBankAccountByNumber(bankAccountNumber);

                //Assert
                Assert.IsNotNull(actual);
                Assert.AreEqual(actual.Balance, bankAccount.Balance);
            }
        }
        /// <summary>
        /// <see cref="Microsoft.Samples.NLayerApp.Application.MainModule.BankingManagement.IBankingManagementService"/>
        /// </summary>
        /// <param name="bankAccount"><see cref="Microsoft.Samples.NLayerApp.Application.MainModule.BankingManagement.IBankingManagementService"/></param>
        public void ChangeBankAccount(BankAccount bankAccount)
        {
            if (bankAccount == (BankAccount)null)
                throw new ArgumentNullException("bankAccount");

            IUnitOfWork unitOfWork = _bankAccountRepository.UnitOfWork as IUnitOfWork;

            //charge in balance and commit operation. This opeation is 
            //problematic with concurrency. "balance" propety in bankAccount
            //is configured to FIXED in "WHERE concurrency checked predicates"

            _bankAccountRepository.Modify(bankAccount);

            //complete changes in this unit of work
            unitOfWork.CommitAndRefreshChanges();

        }
        /// <summary>
        /// <see cref="Microsoft.Samples.NLayerApp.Application.MainModule.BankingManagement.IBankingManagementService"/>
        /// </summary>
        /// <param name="bankAccount"><see cref="Microsoft.Samples.NLayerApp.Application.MainModule.BankingManagement.IBankingManagementService"/></param>
        public void AddBankAccount(BankAccount bankAccount)
        {
            if (bankAccount == (BankAccount)null)
                throw new ArgumentNullException("bankAccount");

            IUnitOfWork unitOfWork = _bankAccountRepository.UnitOfWork as IUnitOfWork;



            _bankAccountRepository.Add(bankAccount);

            //complete changes in this unit of work
            unitOfWork.Commit();
        }
        public void Lock_Account_Locks_The_Given_Account()
        {
             /*
              *   Arrange 
              * 1º - Create a fake data
              * 2º - Initialize stub of IBankingManagementService
              * 3º - Create controller to test
              */

            string accountNumber = "EX325";
            BankAccount account = new BankAccount() { BankAccountNumber = accountNumber, Locked = false };

        
            SIBankingManagementService bankingService = new SIBankingManagementService();
            bankingService.FindBankAccountByNumberString = accNumber => account;
            bankingService.ChangeBankAccountBankAccount = bankAccount => { };
           
            BankAccountController controller = new BankAccountController(bankingService);


            //Act
            RedirectToRouteResult result = controller.LockAccount(accountNumber) as RedirectToRouteResult;
            
            //Assert
            Assert.IsNotNull(result, "Expected a RedirectToRouteResult");
            Assert.AreEqual("TransferMoney", result.RouteValues["action"], "Expected a redirection to TransferMoney");

        }