Handler.cs 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Application.Helpers;
  4. using Microsoft.EntityFrameworkCore;
  5. namespace Application.Features.Api.Paper.GetAccount;
  6. internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
  7. {
  8. public async Task<Response> Handle(Query request, CancellationToken ct)
  9. {
  10. var account = await db.PaperAccount.AsNoTracking().FirstOrDefaultAsync(c => c.MemberID == request.MemberID, ct);
  11. if (account is null)
  12. {
  13. return new Response(false, 0, 0, 0, 0, 0, 0);
  14. }
  15. var positions = await db.PaperPosition.AsNoTracking()
  16. .Where(c => c.AccountID == account.ID && c.Quantity > 0)
  17. .Select(c => new { c.StockCode, c.Quantity })
  18. .ToListAsync(ct);
  19. var codes = positions.Select(c => c.StockCode).Distinct().ToList();
  20. var latestCloses = await PaperValuation.GetLatestClosesAsync(db, codes, ct);
  21. var equity = PaperValuation.ComputeEquity(
  22. account.Token,
  23. account.ReservedToken,
  24. positions.Select(c => (c.StockCode, c.Quantity)),
  25. latestCloses);
  26. var nav = PaperValuation.ComputeNav(equity, account.Units);
  27. var cumReturnBp = (int)Math.Round((nav - 1m) * 10000m, MidpointRounding.AwayFromZero);
  28. return new Response(
  29. true,
  30. account.Token,
  31. account.ReservedToken,
  32. account.Units,
  33. equity,
  34. cumReturnBp,
  35. positions.Count);
  36. }
  37. }