namespace Infrastructure.StockData;
///
/// SEIBro getBondOptionXrcInfo(채권 조기상환 정보) 응답 파서 — 순수 C#. 공용 SeibroXml envelope 입력.
/// 자연키 (ISIN, ERLY_RED_DT) 중 하나라도 없으면 건너뛴다. 날짜(YYYYMMDD)→DateOnly, 콤마 포함 숫자→decimal.
///
public static class SeibroBondOptionXrcParser
{
public sealed record Row(
string Isin,
string? KorSecnNm,
DateOnly? XrcBeginDt,
DateOnly? XrcExpryDt,
DateOnly ErlyRedDt,
string? OptionTpcd,
decimal? ApliIrate,
decimal? ErlyRedamtVal,
decimal? IntPayAmt,
decimal? IssuRema,
decimal? XrcRatio
);
public static IReadOnlyList Parse(SeibroXml.Envelope envelope)
{
var rows = new List();
foreach (var fields in envelope.Rows)
{
var isin = SeibroXml.GetOrNull(fields, "ISIN")?.Trim();
var erlyRedDt = SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "ERLY_RED_DT"));
if (string.IsNullOrEmpty(isin) || erlyRedDt is null)
{
continue;
}
rows.Add(new Row(
isin,
SeibroXml.GetOrNull(fields, "KOR_SECN_NM")?.Trim(),
SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "XRC_BEGIN_DT")),
SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "XRC_EXPRY_DT")),
erlyRedDt.Value,
SeibroXml.GetOrNull(fields, "OPTION_TPCD")?.Trim(),
SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "APLI_IRATE")),
SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "ERLY_REDAMT_VAL")),
SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "INT_PAY_AMT")),
SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "ISSU_REMA")),
SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "XRC_RATIO"))
));
}
return rows;
}
}