DerivRedemptionCondition.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. using System.ComponentModel.DataAnnotations;
  2. namespace Domain.Entities.Stocks;
  3. /// <summary>
  4. /// SEIBro 파생결합증권 상환조건 (getRedCondiInfo) — 중간평가일·상환조건·계산식 (Wave 5). 자연키 UNIQUE (Isin, RedCondiTpcd, ValatNtimesSeq).
  5. /// rolling per-ISIN(DerivMaster 있는 것). 상환조건구분(1중간평가/2만기)×평가횟수(ValatNtimesSeq)별 조건문·계산식 다수 행.
  6. /// ⚠️ 응답에 ISIN 이 없어(요청 파라미터로만 받음) 배치가 요청 ISIN 을 스탬핑한다.
  7. /// 조건/계산식은 최대 1000자 자유 텍스트(VARCHAR2(1000)).
  8. /// </summary>
  9. public class DerivRedemptionCondition
  10. {
  11. [Key]
  12. public int ID { get; private set; }
  13. /// <summary>종목코드 (ISIN, 스탬핑)</summary>
  14. public string Isin { get; private set; } = default!;
  15. /// <summary>상환조건구분코드 (RED_CONDI_TPCD) — 1중간평가 2만기상환</summary>
  16. public string RedCondiTpcd { get; private set; } = default!;
  17. /// <summary>평가횟수일련번호 (VALAT_NTIMES_SEQ)</summary>
  18. public int ValatNtimesSeq { get; private set; }
  19. /// <summary>중간평가지급일자 (MID_VALAT_PAY_DT)</summary>
  20. public DateOnly? MidValatPayDt { get; private set; }
  21. /// <summary>중간평가시작일자 (MID_VALAT_BEGIN_DT)</summary>
  22. public DateOnly? MidValatBeginDt { get; private set; }
  23. /// <summary>중간평가종료일자 (MID_VALAT_EXPRY_DT)</summary>
  24. public DateOnly? MidValatExpryDt { get; private set; }
  25. /// <summary>상환조건내용 (RED_CONDI_CONTENT) — 최대 1000자</summary>
  26. public string? RedCondiContent { get; private set; }
  27. /// <summary>상환계산식내용 (RED_FORMULA_CONTENT) — 최대 1000자</summary>
  28. public string? RedFormulaContent { get; private set; }
  29. public DateTime UpdatedAt { get; private set; } = DateTime.UtcNow;
  30. private DerivRedemptionCondition() { }
  31. public static DerivRedemptionCondition Create(
  32. string isin,
  33. string redCondiTpcd,
  34. int valatNtimesSeq,
  35. DateOnly? midValatPayDt,
  36. DateOnly? midValatBeginDt,
  37. DateOnly? midValatExpryDt,
  38. string? redCondiContent,
  39. string? redFormulaContent)
  40. {
  41. if (string.IsNullOrWhiteSpace(isin))
  42. {
  43. throw new ArgumentException("isin required", nameof(isin));
  44. }
  45. return new DerivRedemptionCondition
  46. {
  47. Isin = isin.Trim(),
  48. RedCondiTpcd = redCondiTpcd.Trim(),
  49. ValatNtimesSeq = valatNtimesSeq,
  50. MidValatPayDt = midValatPayDt,
  51. MidValatBeginDt = midValatBeginDt,
  52. MidValatExpryDt = midValatExpryDt,
  53. RedCondiContent = Trimmed(redCondiContent),
  54. RedFormulaContent = Trimmed(redFormulaContent)
  55. };
  56. }
  57. /// <summary>재수집 반영 — 변경 필드가 있을 때만 UpdatedAt 갱신 (자연키 Isin/RedCondiTpcd/ValatNtimesSeq 은 불변)</summary>
  58. public void Update(
  59. DateOnly? midValatPayDt,
  60. DateOnly? midValatBeginDt,
  61. DateOnly? midValatExpryDt,
  62. string? redCondiContent,
  63. string? redFormulaContent)
  64. {
  65. var changed = false;
  66. changed |= Set(midValatPayDt, MidValatPayDt, v => MidValatPayDt = v);
  67. changed |= Set(midValatBeginDt, MidValatBeginDt, v => MidValatBeginDt = v);
  68. changed |= Set(midValatExpryDt, MidValatExpryDt, v => MidValatExpryDt = v);
  69. changed |= Set(Trimmed(redCondiContent), RedCondiContent, v => RedCondiContent = v);
  70. changed |= Set(Trimmed(redFormulaContent), RedFormulaContent, v => RedFormulaContent = v);
  71. if (changed)
  72. {
  73. UpdatedAt = DateTime.UtcNow;
  74. }
  75. }
  76. private static string? Trimmed(string? value)
  77. {
  78. return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
  79. }
  80. private static bool Set<T>(T incoming, T current, Action<T> assign)
  81. {
  82. if (EqualityComparer<T>.Default.Equals(incoming, current))
  83. {
  84. return false;
  85. }
  86. assign(incoming);
  87. return true;
  88. }
  89. }