namespace Infrastructure.StockData;
///
/// SEIBro getStkIncdecDetails(주식증감내역) 응답 파서 — 순수 C#. 공용 SeibroXml envelope 입력.
/// 자연키(ISIN, SECN_ISSU_NTIMES, ISSU_DT, SECN_ISSU_RACD) 중 하나라도 없거나 비형식인 행은 건너뛴다.
/// ISSU_QTY 는 감소(소각) 시 음수 → Long 이 부호 보존. ISSUPRC 0 은 유효값(무상).
///
public static class SeibroStkIncdecParser
{
public sealed record Row(
int? IssucoCustno,
string Isin,
string? SecnKacd,
int SecnIssuNtimes,
DateOnly IssuDt,
decimal? Issuprc,
long? IssuQty,
string SecnIssuRacd,
string? SecnIssuNm,
DateOnly? ListDt
);
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 ntimes = SeibroFieldParse.Int(SeibroXml.GetOrNull(fields, "SECN_ISSU_NTIMES"));
var issuDt = SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "ISSU_DT"));
var racd = SeibroXml.GetOrNull(fields, "SECN_ISSU_RACD")?.Trim();
if (string.IsNullOrEmpty(isin) || ntimes is null || issuDt is null || string.IsNullOrEmpty(racd))
{
continue;
}
rows.Add(new Row(
SeibroFieldParse.Int(SeibroXml.GetOrNull(fields, "ISSUCO_CUSTNO")),
isin,
SeibroXml.GetOrNull(fields, "SECN_KACD")?.Trim(),
ntimes.Value,
issuDt.Value,
SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "ISSUPRC")),
SeibroFieldParse.Long(SeibroXml.GetOrNull(fields, "ISSU_QTY")),
racd,
SeibroXml.GetOrNull(fields, "SECN_ISSU_NM")?.Trim(),
SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "LIST_DT"))
));
}
return rows;
}
}