CdMaster.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. using System.ComponentModel.DataAnnotations;
  2. namespace Domain.Entities.Stocks;
  3. /// <summary>
  4. /// SEIBro CD 종목 정보 (getCDInfo) — 발행금액·할인율·이자지급방식·만기 (Wave 4). PK Isin.
  5. /// ⚠️ 실샘플 fixture 가 result="0"(빈) 이라 필드 매핑은 채권.md 스펙 기준 — 운영 첫 수집 시 로그로 확인.
  6. /// rolling per-ISIN 대상 = ShortTermIssuance 발견분 중 SECN_TPCD=13(CD).
  7. /// </summary>
  8. public class CdMaster
  9. {
  10. /// <summary>종목코드 (ISIN) — PK</summary>
  11. [Key]
  12. [MaxLength(12)]
  13. public string Isin { get; private set; } = default!;
  14. /// <summary>발행사 번호 (ISSUCO_CUSTNO)</summary>
  15. public int? IssucoCustno { get; private set; }
  16. /// <summary>한글종목명 (KOR_SECN_NM)</summary>
  17. public string? KorSecnNm { get; private set; }
  18. /// <summary>발행통화코드 (ISSU_CUR_CD) — KRW</summary>
  19. public string? IssuCurCd { get; private set; }
  20. /// <summary>최초발행금액 (FIRST_ISSU_AMT)</summary>
  21. public decimal? FirstIssuAmt { get; private set; }
  22. /// <summary>발행방법코드 (ISSU_WHCD)</summary>
  23. public string? IssuWhcd { get; private set; }
  24. /// <summary>액면금액 (FACE_AMT)</summary>
  25. public decimal? FaceAmt { get; private set; }
  26. /// <summary>매출금액 (SALE_AMT)</summary>
  27. public decimal? SaleAmt { get; private set; }
  28. /// <summary>할인율 (DISCN_RATE)</summary>
  29. public decimal? DiscnRate { get; private set; }
  30. /// <summary>이자지급방식구분코드 (INT_PAY_MANN_TPCD) — 1할인식 2부리식</summary>
  31. public string? IntPayMannTpcd { get; private set; }
  32. /// <summary>발행일자 (ISSU_DT)</summary>
  33. public DateOnly? IssuDt { get; private set; }
  34. /// <summary>만기일자 (XPIR_DT) — CD 상환일</summary>
  35. public DateOnly? XpirDt { get; private set; }
  36. /// <summary>전자증권 여부 (ELTSC_YN)</summary>
  37. public bool? EltscYn { get; private set; }
  38. public DateTime UpdatedAt { get; private set; } = DateTime.UtcNow;
  39. private CdMaster() { }
  40. public static CdMaster Create(
  41. string isin,
  42. int? issucoCustno,
  43. string? korSecnNm,
  44. string? issuCurCd,
  45. decimal? firstIssuAmt,
  46. string? issuWhcd,
  47. decimal? faceAmt,
  48. decimal? saleAmt,
  49. decimal? discnRate,
  50. string? intPayMannTpcd,
  51. DateOnly? issuDt,
  52. DateOnly? xpirDt,
  53. bool? eltscYn)
  54. {
  55. if (string.IsNullOrWhiteSpace(isin))
  56. {
  57. throw new ArgumentException("isin required", nameof(isin));
  58. }
  59. var entity = new CdMaster { Isin = isin.Trim() };
  60. entity.Apply(issucoCustno, korSecnNm, issuCurCd, firstIssuAmt, issuWhcd, faceAmt, saleAmt, discnRate, intPayMannTpcd, issuDt, xpirDt, eltscYn);
  61. return entity;
  62. }
  63. /// <summary>재수집 반영 (PK Isin 은 불변) — 변경 시에만 UpdatedAt</summary>
  64. public void Update(
  65. int? issucoCustno,
  66. string? korSecnNm,
  67. string? issuCurCd,
  68. decimal? firstIssuAmt,
  69. string? issuWhcd,
  70. decimal? faceAmt,
  71. decimal? saleAmt,
  72. decimal? discnRate,
  73. string? intPayMannTpcd,
  74. DateOnly? issuDt,
  75. DateOnly? xpirDt,
  76. bool? eltscYn)
  77. {
  78. Apply(issucoCustno, korSecnNm, issuCurCd, firstIssuAmt, issuWhcd, faceAmt, saleAmt, discnRate, intPayMannTpcd, issuDt, xpirDt, eltscYn);
  79. }
  80. private void Apply(
  81. int? issucoCustno,
  82. string? korSecnNm,
  83. string? issuCurCd,
  84. decimal? firstIssuAmt,
  85. string? issuWhcd,
  86. decimal? faceAmt,
  87. decimal? saleAmt,
  88. decimal? discnRate,
  89. string? intPayMannTpcd,
  90. DateOnly? issuDt,
  91. DateOnly? xpirDt,
  92. bool? eltscYn)
  93. {
  94. var changed = false;
  95. changed |= Set(issucoCustno, IssucoCustno, v => IssucoCustno = v);
  96. changed |= Set(Trimmed(korSecnNm), KorSecnNm, v => KorSecnNm = v);
  97. changed |= Set(Trimmed(issuCurCd), IssuCurCd, v => IssuCurCd = v);
  98. changed |= Set(firstIssuAmt, FirstIssuAmt, v => FirstIssuAmt = v);
  99. changed |= Set(Trimmed(issuWhcd), IssuWhcd, v => IssuWhcd = v);
  100. changed |= Set(faceAmt, FaceAmt, v => FaceAmt = v);
  101. changed |= Set(saleAmt, SaleAmt, v => SaleAmt = v);
  102. changed |= Set(discnRate, DiscnRate, v => DiscnRate = v);
  103. changed |= Set(Trimmed(intPayMannTpcd), IntPayMannTpcd, v => IntPayMannTpcd = v);
  104. changed |= Set(issuDt, IssuDt, v => IssuDt = v);
  105. changed |= Set(xpirDt, XpirDt, v => XpirDt = v);
  106. changed |= Set(eltscYn, EltscYn, v => EltscYn = v);
  107. if (changed)
  108. {
  109. UpdatedAt = DateTime.UtcNow;
  110. }
  111. }
  112. private static string? Trimmed(string? value)
  113. {
  114. return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
  115. }
  116. private static bool Set<T>(T incoming, T current, Action<T> assign)
  117. {
  118. if (EqualityComparer<T>.Default.Equals(incoming, current))
  119. {
  120. return false;
  121. }
  122. assign(incoming);
  123. return true;
  124. }
  125. }