public AccountRepository_Test() { var dbLogger = new Mock <ILogger <ChilindoContext> >(); // Given // https://docs.microsoft.com/en-us/ef/core/miscellaneous/testing/in-memory var options = new DbContextOptionsBuilder <ChilindoContext>() .UseInMemoryDatabase(databaseName: "Chilindo") .Options; using (var context = new ChilindoContext(options, dbLogger.Object)) { context.Database.EnsureDeleted(); context.Accounts.Add(new Account { AccountNumber = 1234, IsActive = true, Balances = new List <AccountBalance> { new AccountBalance { AccountNumber = 1234, Currency = "THB", Balance = 5000 }, new AccountBalance { AccountNumber = 1234, Currency = "USD", Balance = 250 } } }); context.Accounts.Add(new Account { AccountNumber = 3456, IsActive = true, Balances = new List <AccountBalance> { new AccountBalance { AccountNumber = 3456, Currency = "THB", Balance = 22500 } } }); context.Accounts.Add(new Account { AccountNumber = 7890, IsActive = true, Balances = new List <AccountBalance> { new AccountBalance { AccountNumber = 7890, Currency = "USD", Balance = 750 } } }); context.SaveChanges(); } var starWarsContext = new ChilindoContext(options, dbLogger.Object); var repoLogger = new Mock <ILogger <AccountRepository> >(); _accountRepository = new AccountRepository(starWarsContext, repoLogger.Object); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ChilindoContext db) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseCors(builder => builder .AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); app.UseMvc(); db.EnsureSeedData(); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ChilindoContext db) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions { HotModuleReplacement = true, ReactHotModuleReplacement = true }); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); routes.MapSpaFallbackRoute( name: "spa-fallback", defaults: new { controller = "Home", action = "Index" }); }); db.EnsureSeedData(); }
public static void EnsureSeedData(this ChilindoContext db) { if (db.Accounts == null) { return; } db._logger.LogInformation("Seeding database"); //Account 1 var account1 = new Account { AccountNumber = 1234, IsActive = true }; account1.Balances = new List <AccountBalance> { new AccountBalance { AccountNumber = 1234, Currency = "THB", Balance = 15000 }, new AccountBalance { AccountNumber = 1234, Currency = "USD", Balance = 250 }, }; //Account 2 var account2 = new Account { AccountNumber = 3456, IsActive = true }; account2.Balances = new List <AccountBalance> { new AccountBalance { AccountNumber = 3456, Currency = "THB", Balance = 25000 }, new AccountBalance { AccountNumber = 3456, Currency = "USD", Balance = 0 }, }; //Account 3 var account3 = new Account { AccountNumber = 7890, IsActive = true }; account3.Balances = new List <AccountBalance> { new AccountBalance { AccountNumber = 7890, Currency = "THB", Balance = 0 }, new AccountBalance { AccountNumber = 7890, Currency = "USD", Balance = 500 }, }; var accounts = new List <Account> { account1, account2, account3 }; if (!db.Accounts.Any()) { db._logger.LogInformation("Seeding accounts"); db.Accounts.AddRange(accounts); db.SaveChanges(); } }
public async Task <AccountTransactionResponse> Deposit(AccountTransactionRequest request, int maxRetry = 10, int retry = 1) { try { _logger.LogInformation($"Deposit amount to account number: {request.AccountNumber}"); var account = await _db.Accounts .Include(a => a.Balances) .FirstOrDefaultAsync(acc => acc.AccountNumber == request.AccountNumber); if (account == null) { return(ErrorResponse(request.AccountNumber, $"Invalid Account Number: {request.AccountNumber}")); } var balanceWithCurr = account.Balances.FirstOrDefault(b => b.Currency == request.Currency); if (balanceWithCurr == null) { account.Balances.Add(new Core.Models.AccountBalance { Currency = request.Currency, Balance = request.Amount }); } else { balanceWithCurr.Balance += request.Amount; } _db.TransactionHistories.Add(new TransactionHistory { AccountNumber = request.AccountNumber, TransactionType = TransactionType.Deposit, Currency = request.Currency, Amount = request.Amount, TransactionTime = DateTime.Now }); await _db.SaveChangesAsync(); account = await _db.Accounts .Include(a => a.Balances) .FirstOrDefaultAsync(acc => acc.AccountNumber == request.AccountNumber); return(ConvertToResponse(account, request.Currency)); } catch (Exception ex) { if (maxRetry >= retry) { _db = new ChilindoContext(_db._options, _db._logger); await Task.Delay(200); retry += 1; return(await Deposit(request, maxRetry, retry)); } else { return(ErrorResponse(request.AccountNumber, ex.Message)); } } }
public AccountRepository(ChilindoContext db, ILogger <AccountRepository> logger) { _db = db; _logger = logger; }
public async Task <AccountTransactionResponse> Withdraw(AccountTransactionRequest request, int maxRetry = 10, int retry = 1) { try { _logger.LogInformation($"Withdraw amount to account number: {request.AccountNumber}"); var account = await _db.Accounts .Include(a => a.Balances) .FirstOrDefaultAsync(acc => acc.AccountNumber == request.AccountNumber); if (account == null) { return(ErrorResponse(request.AccountNumber, $"Invalid Account Number: {request.AccountNumber}")); } var balanceWithCurr = account.Balances.FirstOrDefault(b => b.Currency == request.Currency); if (balanceWithCurr == null || balanceWithCurr.Balance < request.Amount) { return(new AccountTransactionResponse { AccountNumber = request.AccountNumber, Successful = false, Message = $"Insufficient balance", Currency = request.Currency, Balance = balanceWithCurr.Balance }); } balanceWithCurr.Balance -= request.Amount; _db.TransactionHistories.Add(new TransactionHistory { AccountNumber = request.AccountNumber, TransactionType = TransactionType.Withdraw, Currency = request.Currency, Amount = request.Amount, TransactionTime = DateTime.Now }); await _db.SaveChangesAsync(); account = await _db.Accounts .Include(a => a.Balances) .FirstOrDefaultAsync(acc => acc.AccountNumber == request.AccountNumber); return(ConvertToResponse(account, request.Currency)); } catch (Exception ex) { if (maxRetry >= retry) { _db = new ChilindoContext(_db._options, _db._logger); await Task.Delay(200); retry += 1; return(await Withdraw(request, maxRetry, retry)); } else { return(ErrorResponse(request.AccountNumber, ex.Message)); } } }