94 lines
3.6 KiB
C#
94 lines
3.6 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// The EF implementation of this interface
|
|
/// </summary>
|
|
/// <seealso cref="IO.Swagger.Repositories.ITransactionRepository" />
|
|
public class TransactionRepository : ITransactionRepository
|
|
{
|
|
private readonly BankDbContext context;
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="TransactionRepository"/> class.
|
|
/// </summary>
|
|
/// <param name="context">The context.</param>
|
|
/// <exception cref="System.ArgumentNullException">context</exception>
|
|
public TransactionRepository(BankDbContext context)
|
|
{
|
|
this.context = context ?? throw new ArgumentNullException(nameof(context));
|
|
}
|
|
|
|
|
|
/// <inheritdoc/>
|
|
public async Task<List<Transaction>> 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;
|
|
}
|
|
|
|
|
|
/// <inheritdoc/>
|
|
public async Task<List<Tuple<Currency, float>>> 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;
|
|
}
|
|
|
|
|
|
/// <inheritdoc/>
|
|
public async Task<TransactionReturnCode> 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;
|
|
}
|
|
|
|
}
|
|
}
|