using System.ComponentModel.DataAnnotations;
namespace Domain.Entities.Stocks;
///
/// SEIBro 총회일정 정보 (getGmeetInfo) — 주총 일정·장소·전자투표 (Wave 3).
/// 자연키 UNIQUE (IssucoCustno, RgtStdDt, GmetKacd) — 한 회사·권리기준일·총회종류당 1행.
/// 이벤트 구동: RightsBaseDate(getStddtInfo 적재) 의 RGT_RACD∈{001,002,003,009} 인 (회사번호, 기준일)을 트리거로 수집한다.
///
public class GeneralMeeting
{
[Key]
public int ID { get; private set; }
/// 발행회사 고객번호 (ISSUCO_CUSTNO)
public int IssucoCustno { get; private set; }
/// 발행회사발행체번호 (ISSUIN_NO)
public string? IssuinNo { get; private set; }
/// 총회종류코드 (GMET_KACD) — 001정기 002임시 003종류 009기타
public string GmetKacd { get; private set; } = default!;
/// 권리사유세부유형코드 (RGT_RSN_DTAIL_SORT_CD)
public string? RgtRsnDetailSortCd { get; private set; }
/// 명부폐쇄시작일자 (ROST_CLOSE_BEGIN_DT)
public DateOnly? RostCloseBeginDt { get; private set; }
/// 명부폐쇄종료일자 (ROST_CLOSE_EXPRY_DT)
public DateOnly? RostCloseExpryDt { get; private set; }
/// 총회개최여부 (GMET_OMEET_YN, Y/N)
public bool? GmetOmeetYn { get; private set; }
/// 총회장소구분코드 (GMET_PLACE_TPCD) — 1서울 2지방 3해당없음
public string? GmetPlaceTpcd { get; private set; }
/// 이사회결의공시일자 (COUNCL_DTERMIN_PUBN_DT)
public DateOnly? CouncilDterminPubnDt { get; private set; }
/// 총회장소 (GMET_PLACE)
public string? GmetPlace { get; private set; }
/// 주식매수청구관련여부 (STK_BUYREQ_RL_YN, Y/N)
public bool? StkBuyreqRlYn { get; private set; }
/// 권리기준일자 (RGT_STD_DT)
public DateOnly RgtStdDt { get; private set; }
/// 총회일자 (GMET_DT)
public DateOnly? GmetDt { get; private set; }
/// 총회시각 (GMET_TTM) — HHmm 문자 (예 0900)
public string? GmetTtm { get; private set; }
/// 통지시한일자 (NOTC_DLINE_DT)
public DateOnly? NotcDlineDt { get; private set; }
/// 연기여부 (DFER_YN, Y/N)
public bool? DferYn { get; private set; }
/// 전자투표 적용여부 (EVOTE_YN, Y/N)
public bool? EvoteYn { get; private set; }
/// 전자증권 여부 (ELTSC_YN, Y/N)
public bool? IsElectronicSecurity { get; private set; }
public DateTime UpdatedAt { get; private set; } = DateTime.UtcNow;
private GeneralMeeting() { }
public static GeneralMeeting Create(
int issucoCustno,
string? issuinNo,
string gmetKacd,
string? rgtRsnDetailSortCd,
DateOnly? rostCloseBeginDt,
DateOnly? rostCloseExpryDt,
bool? gmetOmeetYn,
string? gmetPlaceTpcd,
DateOnly? councilDterminPubnDt,
string? gmetPlace,
bool? stkBuyreqRlYn,
DateOnly rgtStdDt,
DateOnly? gmetDt,
string? gmetTtm,
DateOnly? notcDlineDt,
bool? dferYn,
bool? evoteYn,
bool? isElectronicSecurity)
{
if (string.IsNullOrWhiteSpace(gmetKacd))
{
throw new ArgumentException("gmetKacd required", nameof(gmetKacd));
}
return new GeneralMeeting
{
IssucoCustno = issucoCustno,
IssuinNo = Trimmed(issuinNo),
GmetKacd = gmetKacd.Trim(),
RgtRsnDetailSortCd = Trimmed(rgtRsnDetailSortCd),
RostCloseBeginDt = rostCloseBeginDt,
RostCloseExpryDt = rostCloseExpryDt,
GmetOmeetYn = gmetOmeetYn,
GmetPlaceTpcd = Trimmed(gmetPlaceTpcd),
CouncilDterminPubnDt = councilDterminPubnDt,
GmetPlace = Trimmed(gmetPlace),
StkBuyreqRlYn = stkBuyreqRlYn,
RgtStdDt = rgtStdDt,
GmetDt = gmetDt,
GmetTtm = Trimmed(gmetTtm),
NotcDlineDt = notcDlineDt,
DferYn = dferYn,
EvoteYn = evoteYn,
IsElectronicSecurity = isElectronicSecurity
};
}
/// 재수집 반영 — 변경 필드가 있을 때만 UpdatedAt 갱신 (자연키는 불변)
public void Update(
string? issuinNo,
string? rgtRsnDetailSortCd,
DateOnly? rostCloseBeginDt,
DateOnly? rostCloseExpryDt,
bool? gmetOmeetYn,
string? gmetPlaceTpcd,
DateOnly? councilDterminPubnDt,
string? gmetPlace,
bool? stkBuyreqRlYn,
DateOnly? gmetDt,
string? gmetTtm,
DateOnly? notcDlineDt,
bool? dferYn,
bool? evoteYn,
bool? isElectronicSecurity)
{
var changed = false;
changed |= Set(Trimmed(issuinNo), IssuinNo, v => IssuinNo = v);
changed |= Set(Trimmed(rgtRsnDetailSortCd), RgtRsnDetailSortCd, v => RgtRsnDetailSortCd = v);
changed |= Set(rostCloseBeginDt, RostCloseBeginDt, v => RostCloseBeginDt = v);
changed |= Set(rostCloseExpryDt, RostCloseExpryDt, v => RostCloseExpryDt = v);
changed |= Set(gmetOmeetYn, GmetOmeetYn, v => GmetOmeetYn = v);
changed |= Set(Trimmed(gmetPlaceTpcd), GmetPlaceTpcd, v => GmetPlaceTpcd = v);
changed |= Set(councilDterminPubnDt, CouncilDterminPubnDt, v => CouncilDterminPubnDt = v);
changed |= Set(Trimmed(gmetPlace), GmetPlace, v => GmetPlace = v);
changed |= Set(stkBuyreqRlYn, StkBuyreqRlYn, v => StkBuyreqRlYn = v);
changed |= Set(gmetDt, GmetDt, v => GmetDt = v);
changed |= Set(Trimmed(gmetTtm), GmetTtm, v => GmetTtm = v);
changed |= Set(notcDlineDt, NotcDlineDt, v => NotcDlineDt = v);
changed |= Set(dferYn, DferYn, v => DferYn = v);
changed |= Set(evoteYn, EvoteYn, v => EvoteYn = v);
changed |= Set(isElectronicSecurity, IsElectronicSecurity, v => IsElectronicSecurity = 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;
}
}