Handler.cs 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  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. // ReturnDt(락업 해제) 또는 SafedpDt(예수)가 기간 안에 걸리는 이벤트. from/to 미지정 시 전체.
  15. if (request.From.HasValue)
  16. {
  17. var from = request.From.Value;
  18. query = query.Where(c => c.SafedpDt >= from || (c.ReturnDt != null && c.ReturnDt >= from));
  19. }
  20. if (request.To.HasValue)
  21. {
  22. var to = request.To.Value;
  23. query = query.Where(c => c.SafedpDt <= to || (c.ReturnDt != null && c.ReturnDt <= to));
  24. }
  25. var total = await query.CountAsync(ct);
  26. // 정렬 기준: 반환일 있으면 반환일, 없으면 예수일 (락업 해제 캘린더 관점) 내림차순
  27. var list = await query
  28. .OrderByDescending(c => c.ReturnDt ?? c.SafedpDt)
  29. .ThenByDescending(c => c.SafedpDt)
  30. .Skip((page - 1) * perPage)
  31. .Take(perPage)
  32. .Select(c => new Response.Row
  33. {
  34. IssucoCustno = c.IssucoCustno,
  35. ShortCode = c.ShotnIsin,
  36. Name = c.KorSecnNm,
  37. OccrSeq = c.OccrSeq,
  38. SafedpDt = c.SafedpDt,
  39. SafedpQty = c.SafedpQty,
  40. ReasonCode = c.DutySafedpRacd,
  41. ReturnDt = c.ReturnDt,
  42. ReturnQty = c.ReturnQty,
  43. TotalStkCnt = c.TotalStkCnt
  44. })
  45. .ToListAsync(ct);
  46. return new Response
  47. {
  48. Total = total,
  49. List = list
  50. };
  51. }
  52. }