using System.ComponentModel.DataAnnotations; namespace Domain.Entities.Stocks; /// /// SEIBro 단주대금 정보 (getOddLotInfo) — 단주대금 사유·산정기준·권리락일 (Wave 3). /// 자연키 UNIQUE (IssucoCustno, PayDate, RgtStdDt) — 회사·지급일·권리기준일당 1행. /// 이벤트 구동: PaymentSchedule 중 PAY_COST_TPCD=3(단주) 인 (회사번호, 지급일)을 트리거로 수집한다. /// ⚠️ 응답엔 ISSUCO_CUSTNO·지급일(TH1_PAY_TERM_BEGIN_DT)이 없어 요청값을 스탬핑한다. /// public class OddLotPayment { [Key] public int ID { get; private set; } /// 발행회사 고객번호 (ISSUCO_CUSTNO, 요청 스탬핑) public int IssucoCustno { get; private set; } /// 대금지급일 (TH1_PAY_TERM_BEGIN_DT, 요청 스탬핑) public DateOnly PayDate { get; private set; } /// 권리기준일자 (RGT_STD_DT) public DateOnly RgtStdDt { get; private set; } /// 권리사유코드 (RGT_RACD) public string? RgtRacd { get; private set; } /// 권리사유명 (RGT_RACD_NM) — 예 무상증자 public string? RgtRacdNm { get; private set; } /// 권리사유세부유형코드 (RGT_RSN_DTAIL_SORT_CD) public string? RgtRsnDetailSortCd { get; private set; } /// 산정기준구분코드 (ESTM_STD_TPCD) — 04상장일종가 10액면가 … public string? EstmStdTpcd { get; private set; } /// 산정기준일자 (ESTM_STD_DT) public DateOnly? EstmStdDt { get; private set; } /// 산정기준가 (ESTM_STDPRC) public decimal? EstmStdprc { get; private set; } /// 명부폐쇄시작일자 (ROST_CLOSE_BEGIN_DT) public DateOnly? RostCloseBeginDt { get; private set; } /// 명부폐쇄종료일자 (ROST_CLOSE_EXPRY_DT) public DateOnly? RostCloseExpryDt { get; private set; } /// 권리락일자 (XRGT_DT) public DateOnly? XrgtDt { get; private set; } public DateTime UpdatedAt { get; private set; } = DateTime.UtcNow; private OddLotPayment() { } public static OddLotPayment Create( int issucoCustno, DateOnly payDate, DateOnly rgtStdDt, string? rgtRacd, string? rgtRacdNm, string? rgtRsnDetailSortCd, string? estmStdTpcd, DateOnly? estmStdDt, decimal? estmStdprc, DateOnly? rostCloseBeginDt, DateOnly? rostCloseExpryDt, DateOnly? xrgtDt) { return new OddLotPayment { IssucoCustno = issucoCustno, PayDate = payDate, RgtStdDt = rgtStdDt, RgtRacd = Trimmed(rgtRacd), RgtRacdNm = Trimmed(rgtRacdNm), RgtRsnDetailSortCd = Trimmed(rgtRsnDetailSortCd), EstmStdTpcd = Trimmed(estmStdTpcd), EstmStdDt = estmStdDt, EstmStdprc = estmStdprc, RostCloseBeginDt = rostCloseBeginDt, RostCloseExpryDt = rostCloseExpryDt, XrgtDt = xrgtDt }; } /// 재수집 반영 — 변경 필드가 있을 때만 UpdatedAt 갱신 (자연키는 불변) public void Update( string? rgtRacd, string? rgtRacdNm, string? rgtRsnDetailSortCd, string? estmStdTpcd, DateOnly? estmStdDt, decimal? estmStdprc, DateOnly? rostCloseBeginDt, DateOnly? rostCloseExpryDt, DateOnly? xrgtDt) { var changed = false; changed |= Set(Trimmed(rgtRacd), RgtRacd, v => RgtRacd = v); changed |= Set(Trimmed(rgtRacdNm), RgtRacdNm, v => RgtRacdNm = v); changed |= Set(Trimmed(rgtRsnDetailSortCd), RgtRsnDetailSortCd, v => RgtRsnDetailSortCd = v); changed |= Set(Trimmed(estmStdTpcd), EstmStdTpcd, v => EstmStdTpcd = v); changed |= Set(estmStdDt, EstmStdDt, v => EstmStdDt = v); changed |= Set(estmStdprc, EstmStdprc, v => EstmStdprc = v); changed |= Set(rostCloseBeginDt, RostCloseBeginDt, v => RostCloseBeginDt = v); changed |= Set(rostCloseExpryDt, RostCloseExpryDt, v => RostCloseExpryDt = v); changed |= Set(xrgtDt, XrgtDt, v => XrgtDt = v); if (changed) { UpdatedAt = DateTime.UtcNow; } } private static string? Trimmed(string? value) { return string.IsNullOrWhiteSpace(value) ? null : value.Trim(); } private static bool Set(T incoming, T current, Action assign) { if (EqualityComparer.Default.Equals(incoming, current)) { return false; } assign(incoming); return true; } }