using Domain.Entities.Stocks; namespace Infrastructure.StockData; /// /// SEIBro getAssetInfo(파생결합증권 기초자산 정보) 응답 파서 — 순수 C#. 공용 SeibroXml envelope 입력. /// 실샘플 래퍼 = <RESULT> **대문자** (readme §1 확정 — 파생결합 5종 중 하나). /// ISIN 은 응답에 존재하나(가이드 xlsx 누락분, 실샘플에 있음) 없으면 요청값을 배치가 스탬핑하므로 여기선 (AssetSeq, 필드묶음) 반환. /// 자연키 ASSET_SEQ 없으면 스킵. ⚠️ StndBassetCd 는 반환 원문(KSD31*/KR7* 체계 가능) 그대로 저장 — 매핑 흡수 금지. /// public static class SeibroAssetParser { public sealed record Row( int AssetSeq, DerivAssetFields Fields ); public static IReadOnlyList Parse(SeibroXml.Envelope envelope) { var rows = new List(); foreach (var fields in envelope.Rows) { var assetSeq = SeibroFieldParse.Int(SeibroXml.GetOrNull(fields, "ASSET_SEQ")); if (assetSeq is null) { continue; } rows.Add(new Row( assetSeq.Value, new DerivAssetFields( SeibroXml.GetOrNull(fields, "STND_BASSET_CD")?.Trim(), SeibroXml.GetOrNull(fields, "STND_BASSET_NM")?.Trim(), SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "XRC_STDPRC")), SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "XRC_STOP_LOLMT_RATIO")), SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "XRC_STOP_LOLMT_PRICE")), SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "XRC_STOP_UPLMT_RATIO")), SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "XRC_STOP_UPLMT_PRICE")), SeibroXml.GetOrNull(fields, "BASSET_FIRST_VALAT_TPCD")?.Trim(), SeibroXml.GetOrNull(fields, "BASSET_LAST_VALAT_TPCD")?.Trim(), SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "FIRST_STDPRC_DECSN_BEGIN_DT")), SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "FIRST_STDPRC_DECSN_EXPRY_DT")), SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "LAST_STDPRC_DECSN_BEGIN_DT")), SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "LAST_STDPRC_DECSN_EXPRY_DT")), SeibroXml.GetOrNull(fields, "RVLT_SEVER_TPCD")?.Trim() ) )); } return rows; } }