BondInterestPayment.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. using System.ComponentModel.DataAnnotations;
  2. namespace Domain.Entities.Stocks;
  3. /// <summary>
  4. /// SEIBro 채권 이자지급 정보 (getIntPayInfo) — 이자지급 주기·방식·직전/차기 이표일 (Wave 4). PK Isin (스냅샷 갱신).
  5. /// ⚠️ 실샘플 fixture 가 result="0"(빈) 이라 필드 매핑은 채권.md 스펙 기준 — 운영 첫 수집 시 로그로 확인.
  6. /// 응답에 ISIN 필드가 없을 수 있어(getIntPayInfo 는 ISIN 을 요청 파라미터로만 받음) 배치가 요청 ISIN 을 스탬핑한다.
  7. /// </summary>
  8. public class BondInterestPayment
  9. {
  10. /// <summary>종목코드 (ISIN, 요청값 스탬핑) — PK</summary>
  11. [Key]
  12. [MaxLength(12)]
  13. public string Isin { get; private set; } = default!;
  14. /// <summary>표면이자율 (COUPON_RATE)</summary>
  15. public decimal? CouponRate { get; private set; }
  16. /// <summary>이자지급방법구분코드 (INT_PAY_WAY_TPCD) — 1이표 2할인 3복리 4단리</summary>
  17. public string? IntPayWayTpcd { get; private set; }
  18. /// <summary>이자지급주기기간수 (INT_PAY_CYCLE_TERMS)</summary>
  19. public int? IntPayCycleTerms { get; private set; }
  20. /// <summary>이자지급주기구분코드 (INT_PAY_CYCLE_TPCD) — 23개월 24분기 25반기 26년 99기타</summary>
  21. public string? IntPayCycleTpcd { get; private set; }
  22. /// <summary>절상절사구분코드 (RVLT_SEVER_TPCD) — 1올림 2버림 3반올림 9해당없음</summary>
  23. public string? RvltSeverTpcd { get; private set; }
  24. /// <summary>경과이자지급여부 (ACRINT_PAY_YN, Y/N)</summary>
  25. public bool? AcrintPayYn { get; private set; }
  26. /// <summary>은행휴무일이자지급일구분코드 (BANK_HOLIDAY_INT_PAYDD_TPCD) — 1직전영업일 2직후영업일 3해당일</summary>
  27. public string? BankHolidayIntPaydayTpcd { get; private set; }
  28. /// <summary>이자지급시기구분코드 (INT_PAY_TIMS_TPCD) — 01후급 02선급 03상환시 04발행시</summary>
  29. public string? IntPayTimsTpcd { get; private set; }
  30. /// <summary>직전이표일 (BEFORE_DATE)</summary>
  31. public DateOnly? BeforeDate { get; private set; }
  32. /// <summary>차기이표일 (AFTER_DATE)</summary>
  33. public DateOnly? AfterDate { get; private set; }
  34. public DateTime UpdatedAt { get; private set; } = DateTime.UtcNow;
  35. private BondInterestPayment() { }
  36. public static BondInterestPayment Create(
  37. string isin,
  38. decimal? couponRate,
  39. string? intPayWayTpcd,
  40. int? intPayCycleTerms,
  41. string? intPayCycleTpcd,
  42. string? rvltSeverTpcd,
  43. bool? acrintPayYn,
  44. string? bankHolidayIntPaydayTpcd,
  45. string? intPayTimsTpcd,
  46. DateOnly? beforeDate,
  47. DateOnly? afterDate)
  48. {
  49. if (string.IsNullOrWhiteSpace(isin))
  50. {
  51. throw new ArgumentException("isin required", nameof(isin));
  52. }
  53. return new BondInterestPayment
  54. {
  55. Isin = isin.Trim(),
  56. CouponRate = couponRate,
  57. IntPayWayTpcd = Trimmed(intPayWayTpcd),
  58. IntPayCycleTerms = intPayCycleTerms,
  59. IntPayCycleTpcd = Trimmed(intPayCycleTpcd),
  60. RvltSeverTpcd = Trimmed(rvltSeverTpcd),
  61. AcrintPayYn = acrintPayYn,
  62. BankHolidayIntPaydayTpcd = Trimmed(bankHolidayIntPaydayTpcd),
  63. IntPayTimsTpcd = Trimmed(intPayTimsTpcd),
  64. BeforeDate = beforeDate,
  65. AfterDate = afterDate
  66. };
  67. }
  68. /// <summary>재수집 반영 (PK Isin 은 불변) — 스냅샷 갱신, 변경 시에만 UpdatedAt</summary>
  69. public void Update(
  70. decimal? couponRate,
  71. string? intPayWayTpcd,
  72. int? intPayCycleTerms,
  73. string? intPayCycleTpcd,
  74. string? rvltSeverTpcd,
  75. bool? acrintPayYn,
  76. string? bankHolidayIntPaydayTpcd,
  77. string? intPayTimsTpcd,
  78. DateOnly? beforeDate,
  79. DateOnly? afterDate)
  80. {
  81. var changed = false;
  82. changed |= Set(couponRate, CouponRate, v => CouponRate = v);
  83. changed |= Set(Trimmed(intPayWayTpcd), IntPayWayTpcd, v => IntPayWayTpcd = v);
  84. changed |= Set(intPayCycleTerms, IntPayCycleTerms, v => IntPayCycleTerms = v);
  85. changed |= Set(Trimmed(intPayCycleTpcd), IntPayCycleTpcd, v => IntPayCycleTpcd = v);
  86. changed |= Set(Trimmed(rvltSeverTpcd), RvltSeverTpcd, v => RvltSeverTpcd = v);
  87. changed |= Set(acrintPayYn, AcrintPayYn, v => AcrintPayYn = v);
  88. changed |= Set(Trimmed(bankHolidayIntPaydayTpcd), BankHolidayIntPaydayTpcd, v => BankHolidayIntPaydayTpcd = v);
  89. changed |= Set(Trimmed(intPayTimsTpcd), IntPayTimsTpcd, v => IntPayTimsTpcd = v);
  90. changed |= Set(beforeDate, BeforeDate, v => BeforeDate = v);
  91. changed |= Set(afterDate, AfterDate, v => AfterDate = v);
  92. if (changed)
  93. {
  94. UpdatedAt = DateTime.UtcNow;
  95. }
  96. }
  97. private static string? Trimmed(string? value)
  98. {
  99. return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
  100. }
  101. private static bool Set<T>(T incoming, T current, Action<T> assign)
  102. {
  103. if (EqualityComparer<T>.Default.Equals(incoming, current))
  104. {
  105. return false;
  106. }
  107. assign(incoming);
  108. return true;
  109. }
  110. }