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;
}
}