using System.ComponentModel.DataAnnotations; namespace Domain.Entities.Stocks; /// /// SEIBro 주식관련사채 행사내역 (getXrcStkOptionXrcInfo) — CB/BW/EB 권리행사 내역 (Wave 3). /// 날짜 스윕(권리행사일 RGT_STD_DT) → 권리행사일 window delete+insert 로 반영. /// 반환된 DISTINCT BondIsin 이 ConvertibleBondTarget(getXrcStkStatInfo)의 발견 소스가 된다. /// ⚠️ getXrcStkOptionXrcInfo 실샘플이 result="0"(0행) 이라 필드 매핑은 주식.md 스펙 기준 — 운영 첫 수집 시 로그로 확인 필요. /// public class ConvertibleExercise { [Key] public int ID { get; private set; } /// 채권 종목코드 (BOND_ISIN) public string BondIsin { get; private set; } = default!; /// 채권 한글종목명 (BOND_KOR_SECN_NM) public string? BondKorSecnNm { get; private set; } /// 채권종류코드 (BOND_KIND_NM) — EB/CB/BW public string? BondKindNm { get; private set; } /// 행사주식 종목코드 (XRC_STK_ISIN) public string? XrcStkIsin { get; private set; } /// 행사주식명 (STK_KOR_SECN_NM) public string? StkKorSecnNm { get; private set; } /// 권리행사일 (RGT_STD_DT) public DateOnly RgtStdDt { get; private set; } /// 행사시작일 (XRC_POSS_BEGIN_DT) public DateOnly? XrcPossBeginDt { get; private set; } /// 행사종료일 (XRC_POSS_EXPRY_DT) public DateOnly? XrcPossExpryDt { get; private set; } /// 행사금액 (XRC_AMT) public decimal? XrcAmt { get; private set; } /// 행사주수 (XRC_QTY) public decimal? XrcQty { get; private set; } /// 행사가격 (XRC_PRICE) public decimal? XrcPrice { get; private set; } /// 주식상장일 (LIST_DT) public DateOnly? ListDt { get; private set; } public DateTime UpdatedAt { get; private set; } = DateTime.UtcNow; private ConvertibleExercise() { } public static ConvertibleExercise Create( string bondIsin, string? bondKorSecnNm, string? bondKindNm, string? xrcStkIsin, string? stkKorSecnNm, DateOnly rgtStdDt, DateOnly? xrcPossBeginDt, DateOnly? xrcPossExpryDt, decimal? xrcAmt, decimal? xrcQty, decimal? xrcPrice, DateOnly? listDt) { if (string.IsNullOrWhiteSpace(bondIsin)) { throw new ArgumentException("bondIsin required", nameof(bondIsin)); } return new ConvertibleExercise { BondIsin = bondIsin.Trim(), BondKorSecnNm = Trimmed(bondKorSecnNm), BondKindNm = Trimmed(bondKindNm), XrcStkIsin = Trimmed(xrcStkIsin), StkKorSecnNm = Trimmed(stkKorSecnNm), RgtStdDt = rgtStdDt, XrcPossBeginDt = xrcPossBeginDt, XrcPossExpryDt = xrcPossExpryDt, XrcAmt = xrcAmt, XrcQty = xrcQty, XrcPrice = xrcPrice, ListDt = listDt }; } private static string? Trimmed(string? value) { return string.IsNullOrWhiteSpace(value) ? null : value.Trim(); } }