SeibroLockupParser.cs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. namespace Infrastructure.StockData;
  2. /// <summary>
  3. /// SEIBro getSafeDpDutyDepoStatus(의무보호예수/반환) 응답 파서 — 순수 C#. 공용 SeibroXml envelope 입력.
  4. /// 자연키(ISSUCO_CUSTNO, SHOTN_ISIN, SAFEDP_DT, OCCR_SEQ, DUTY_SAFEDP_RACD) 중 하나라도 없거나 비형식인 행은 건너뛴다.
  5. /// ⚠️ SECN_KACD 는 실응답에서 코드가 아니라 명칭(보통주) 문자열이다(fixture 확인) — 문자열로 그대로 담는다.
  6. /// 반환 관련 필드(RETURN_DT/RETURN_QTY)는 예수 행에서 빈값 → null.
  7. /// </summary>
  8. public static class SeibroLockupParser
  9. {
  10. public sealed record Row(
  11. int IssucoCustno,
  12. string KorSecnNm,
  13. string? SecnKacd,
  14. string ShotnIsin,
  15. string? MartTpcd,
  16. string OccrSeq,
  17. DateOnly SafedpDt,
  18. long? SafedpQty,
  19. string DutySafedpRacd,
  20. DateOnly? ReturnDt,
  21. long? ReturnQty,
  22. long? TotalStkCnt
  23. );
  24. public static IReadOnlyList<Row> Parse(SeibroXml.Envelope envelope)
  25. {
  26. var rows = new List<Row>();
  27. foreach (var fields in envelope.Rows)
  28. {
  29. var custno = SeibroFieldParse.Int(SeibroXml.GetOrNull(fields, "ISSUCO_CUSTNO"));
  30. var korSecnNm = SeibroXml.GetOrNull(fields, "KOR_SECN_NM")?.Trim();
  31. var shotnIsin = SeibroXml.GetOrNull(fields, "SHOTN_ISIN")?.Trim();
  32. var occrSeq = SeibroXml.GetOrNull(fields, "OCCR_SEQ")?.Trim();
  33. var safedpDt = SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "SAFEDP_DT"));
  34. var racd = SeibroXml.GetOrNull(fields, "DUTY_SAFEDP_RACD")?.Trim();
  35. if (custno is null || string.IsNullOrEmpty(korSecnNm) || string.IsNullOrEmpty(shotnIsin) || string.IsNullOrEmpty(occrSeq) || safedpDt is null || string.IsNullOrEmpty(racd))
  36. {
  37. continue;
  38. }
  39. rows.Add(new Row(
  40. custno.Value,
  41. korSecnNm,
  42. SeibroXml.GetOrNull(fields, "SECN_KACD")?.Trim(),
  43. shotnIsin,
  44. SeibroXml.GetOrNull(fields, "MART_TPCD")?.Trim(),
  45. occrSeq,
  46. safedpDt.Value,
  47. SeibroFieldParse.Long(SeibroXml.GetOrNull(fields, "SAFEDP_QTY")),
  48. racd,
  49. SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "RETURN_DT")),
  50. SeibroFieldParse.Long(SeibroXml.GetOrNull(fields, "RETURN_QTY")),
  51. SeibroFieldParse.Long(SeibroXml.GetOrNull(fields, "TOTAL_STK_CNT"))
  52. ));
  53. }
  54. return rows;
  55. }
  56. }