Handler.cs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Microsoft.EntityFrameworkCore;
  4. using SharedKernel.Results;
  5. namespace Application.Features.Api.Stocks.GetLockupCalendar;
  6. internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Result<Response>>
  7. {
  8. private const ushort MaxPerPage = 200;
  9. public async Task<Result<Response>> Handle(Query request, CancellationToken ct)
  10. {
  11. var page = request.Page < 1 ? 1 : request.Page;
  12. var perPage = request.PerPage is 0 or > MaxPerPage ? (ushort)30 : request.PerPage;
  13. var query = db.LockupEvent.AsNoTracking();
  14. // 대표일(EffectiveDate = ReturnDt ?? SafedpDt) 하나로 단일 범위 판정 — from/to 를 각각 (Safedp OR Return) 로 걸면
  15. // 서로 다른 필드가 각 절을 따로 만족해 범위 밖 이벤트가 누출되므로(예: Safedp=2019 & Return=2030, 조회 2025) 대표일 단일 축으로 필터.
  16. // from/to 미지정 시 전체. 정렬 기준도 동일 대표일이라 EF 로 번역된다.
  17. if (request.From.HasValue)
  18. {
  19. var from = request.From.Value;
  20. query = query.Where(c => (c.ReturnDt ?? c.SafedpDt) >= from);
  21. }
  22. if (request.To.HasValue)
  23. {
  24. var to = request.To.Value;
  25. query = query.Where(c => (c.ReturnDt ?? c.SafedpDt) <= to);
  26. }
  27. var total = await query.CountAsync(ct);
  28. // 정렬 기준: 반환일 있으면 반환일, 없으면 예수일 (락업 해제 캘린더 관점) 내림차순
  29. var list = await query
  30. .OrderByDescending(c => c.ReturnDt ?? c.SafedpDt)
  31. .ThenByDescending(c => c.SafedpDt)
  32. .Skip((page - 1) * perPage)
  33. .Take(perPage)
  34. .Select(c => new Response.Row
  35. {
  36. IssucoCustno = c.IssucoCustno,
  37. ShortCode = c.ShotnIsin,
  38. Name = c.KorSecnNm,
  39. OccrSeq = c.OccrSeq,
  40. SafedpDt = c.SafedpDt,
  41. SafedpQty = c.SafedpQty,
  42. ReasonCode = c.DutySafedpRacd,
  43. ReturnDt = c.ReturnDt,
  44. ReturnQty = c.ReturnQty,
  45. TotalStkCnt = c.TotalStkCnt
  46. })
  47. .ToListAsync(ct);
  48. return new Response
  49. {
  50. Total = total,
  51. List = list
  52. };
  53. }
  54. }