SeibroOddLotParser.cs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. namespace Infrastructure.StockData;
  2. /// <summary>
  3. /// SEIBro getOddLotInfo(단주대금) 응답 파서 — 순수 C#. 공용 SeibroXml envelope 입력.
  4. /// ⚠️ 응답엔 ISSUCO_CUSTNO·지급일(TH1_PAY_TERM_BEGIN_DT)이 없다 — 요청 파라미터라 수집 배치가 스탬핑한다.
  5. /// 따라서 Row 는 권리기준일 이하 필드만 담는다. RGT_STD_DT 가 없으면 건너뛴다(자연키 일부).
  6. /// ESTM_STDPRC(산정기준가)는 NUMBER(9) 정수지만 방어적으로 decimal 로 읽는다.
  7. /// </summary>
  8. public static class SeibroOddLotParser
  9. {
  10. public sealed record Row(
  11. DateOnly RgtStdDt,
  12. string? RgtRacd,
  13. string? RgtRacdNm,
  14. string? RgtRsnDetailSortCd,
  15. string? EstmStdTpcd,
  16. DateOnly? EstmStdDt,
  17. decimal? EstmStdprc,
  18. DateOnly? RostCloseBeginDt,
  19. DateOnly? RostCloseExpryDt,
  20. DateOnly? XrgtDt
  21. );
  22. public static IReadOnlyList<Row> Parse(SeibroXml.Envelope envelope)
  23. {
  24. var rows = new List<Row>();
  25. foreach (var fields in envelope.Rows)
  26. {
  27. var rgtStdDt = SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "RGT_STD_DT"));
  28. if (rgtStdDt is null)
  29. {
  30. continue;
  31. }
  32. rows.Add(new Row(
  33. rgtStdDt.Value,
  34. SeibroXml.GetOrNull(fields, "RGT_RACD")?.Trim(),
  35. SeibroXml.GetOrNull(fields, "RGT_RACD_NM")?.Trim(),
  36. SeibroXml.GetOrNull(fields, "RGT_RSN_DTAIL_SORT_CD")?.Trim(),
  37. SeibroXml.GetOrNull(fields, "ESTM_STD_TPCD")?.Trim(),
  38. SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "ESTM_STD_DT")),
  39. SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "ESTM_STDPRC")),
  40. SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "ROST_CLOSE_BEGIN_DT")),
  41. SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "ROST_CLOSE_EXPRY_DT")),
  42. SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "XRGT_DT"))
  43. ));
  44. }
  45. return rows;
  46. }
  47. }