using IO.Swagger.Models.db; using IO.Swagger.Models.RequestDto; using IO.Swagger.Services; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace IO.Swagger.Repositories { /// /// The EF implementation of this interface /// /// public class TransactionRepository : ITransactionRepository { private readonly BankDbContext context; /// /// Initializes a new instance of the class. /// /// The context. /// context public TransactionRepository(BankDbContext context) { this.context = context ?? throw new ArgumentNullException(nameof(context)); } /// public async Task> GetTransactionsForUser(int userId) { var transactions = await context.Transactions.Where(t => t.ToUserId == userId || t.FromUserId == userId) .Include(t => t.Currency) .Include(t => t.FromUser) .Include(t => t.ToUser) .OrderByDescending(t => t.TransactionTime) .ToListAsync(); foreach (var t in transactions) if (t.ToUserId != t.FromUserId && t.FromUserId == userId) t.Amount *= -1; return transactions; } /// public async Task>> GetBalancesForUser(int userId) { var transactions = await context.Transactions.Where(t => t.ToUserId == userId || t.FromUserId == userId) .Include(t => t.Currency) .GroupBy(t => t.Currency) .Select(g => Tuple.Create( g.Key, g.Sum(t => t.ToUserId != t.FromUserId && t.FromUserId == userId ? -t.Amount : t.Amount ) ) ) .ToListAsync(); return transactions; } /// public async Task TransferPhysical(WalletTransferPhysicalBody request, int fromUserId) { var trimmedDest = request.DestUserEmail.Trim().ToLower(); var destUser = await context.Users.FirstOrDefaultAsync(u => u.Email == trimmedDest); if (destUser == null) return TransactionReturnCode.UnknownDestinationUser; var balances = await GetBalancesForUser(fromUserId); var balance = balances.FirstOrDefault(b => b.Item1.CurrencyId == request.CurrencyId); if (balance == null || balance.Item2 < request.Amount) return TransactionReturnCode.InsufficientFunds; await context.Transactions.AddAsync(new Transaction { Amount = request.Amount, CurrencyId = request.CurrencyId, ToUserId = destUser.Id, FromUserId = fromUserId, Memo = request.Memo }); return await context.SaveChangesAsync() > 0 ? TransactionReturnCode.Success : TransactionReturnCode.DbError; } } }