using System.ComponentModel.DataAnnotations;
namespace Domain.Entities.Stocks;
///
/// SEIBro 국가별 외화증권 보관현황 (getNationFrsecCusInfo) — KSD 를 통한 외화증권 보관금액(USD), 국가×종목구분별 (Wave 6). 자연키 UNIQUE (StdDt, NationCd, SecnTpcd).
/// 서학개미 위젯용 국가별 외화증권 보관금액 추이의 소스. 응답 필드는 SecnTpcd·FrsecCusAmt 2종 — 배치가 STD_DT·NATION_CD 를 요청값으로 스탬핑한다.
/// SecnTpcd 는 문자열 코드 그대로 저장 (71외화주식 72외화DR 73외화WRTS 74외화RGTS 75외화채권 76외화CD 77외화CP 78외화수익증권).
///
public class ForeignCustodyNation
{
[Key]
public int ID { get; private set; }
/// 기준일자 (STD_DT, 요청값 스탬핑)
public DateOnly StdDt { get; private set; }
/// 국가코드 (NATION_CD, 요청값 스탬핑) — US/JP/HK/CN/E1 등 43종
public string NationCd { get; private set; } = default!;
/// 종목구분코드 (SECN_TPCD) — 71외화주식~78외화수익증권
public string SecnTpcd { get; private set; } = default!;
/// 외화증권보관금액 (FRSEC_CUS_AMT) — USD
public decimal? FrsecCusAmt { get; private set; }
public DateTime UpdatedAt { get; private set; } = DateTime.UtcNow;
private ForeignCustodyNation() { }
public static ForeignCustodyNation Create(DateOnly stdDt, string nationCd, string secnTpcd, decimal? frsecCusAmt)
{
if (string.IsNullOrWhiteSpace(nationCd))
{
throw new ArgumentException("nationCd required", nameof(nationCd));
}
if (string.IsNullOrWhiteSpace(secnTpcd))
{
throw new ArgumentException("secnTpcd required", nameof(secnTpcd));
}
return new ForeignCustodyNation
{
StdDt = stdDt,
NationCd = nationCd.Trim(),
SecnTpcd = secnTpcd.Trim(),
FrsecCusAmt = frsecCusAmt
};
}
/// 재수집 반영 — 변경 필드가 있을 때만 UpdatedAt 갱신 (자연키 StdDt/NationCd/SecnTpcd 은 불변)
public void Update(decimal? frsecCusAmt)
{
var changed = Set(frsecCusAmt, FrsecCusAmt, v => FrsecCusAmt = v);
if (changed)
{
UpdatedAt = DateTime.UtcNow;
}
}
private static bool Set(T incoming, T current, Action assign)
{
if (EqualityComparer.Default.Equals(incoming, current))
{
return false;
}
assign(incoming);
return true;
}
}