DonationAlert.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using System.ComponentModel.DataAnnotations;
  2. using System.ComponentModel.DataAnnotations.Schema;
  3. using Domain.Entities.Donations.ValueObject;
  4. using Domain.Entities.Members;
  5. namespace Domain.Entities.Donations;
  6. public class DonationAlert
  7. {
  8. [ForeignKey(nameof(DonationID))]
  9. public virtual Donation Donation { get; private set; } = default!;
  10. [ForeignKey(nameof(SponsorMemberID))]
  11. public virtual Member? Sponsor { get; private set; }
  12. [ForeignKey(nameof(ReceiverMemberID))]
  13. public virtual Member? Receiver { get; private set; }
  14. private readonly List<DonationAlertAttempt> _attempts = [];
  15. public IReadOnlyCollection<DonationAlertAttempt> Attempts => _attempts;
  16. [Key]
  17. public int ID { get; private set; }
  18. public int DonationID { get; private set; }
  19. public int SponsorMemberID { get; private set; }
  20. public int ReceiverMemberID { get; private set; }
  21. public AlertStatus Status { get; private set; } = AlertStatus.Queued;
  22. public Guid CorrelationID { get; private set; } = Guid.NewGuid();
  23. public DateTime StartAt { get; private set; } = DateTime.UtcNow;
  24. public DateTime? ArrivedAt { get; private set; }
  25. public double? TotalDelayMs { get; private set; }
  26. public string? IpAddress { get; private set; }
  27. public string? UserAgent { get; private set; }
  28. public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
  29. private DonationAlert() { }
  30. public static DonationAlert Create(
  31. int donationID,
  32. int sponsorMemberID,
  33. int receiverMemberID,
  34. string? ipAddress = null,
  35. string? userAgent = null
  36. )
  37. {
  38. return new DonationAlert
  39. {
  40. DonationID = donationID,
  41. SponsorMemberID = sponsorMemberID,
  42. ReceiverMemberID = receiverMemberID,
  43. IpAddress = ipAddress,
  44. UserAgent = userAgent
  45. };
  46. }
  47. public void MarkPlaying()
  48. {
  49. Status = AlertStatus.Playing;
  50. }
  51. public void MarkDelivered()
  52. {
  53. Status = AlertStatus.Delivered;
  54. ArrivedAt = DateTime.UtcNow;
  55. TotalDelayMs = (ArrivedAt.Value - StartAt).TotalMilliseconds;
  56. }
  57. public void MarkSkipped()
  58. {
  59. if (Status != AlertStatus.Playing)
  60. {
  61. throw new InvalidOperationException("Only playing alerts can be skipped.");
  62. }
  63. Status = AlertStatus.Skipped;
  64. }
  65. public void MarkIgnored()
  66. {
  67. if (Status == AlertStatus.Playing)
  68. {
  69. throw new InvalidOperationException("Cannot ignore a playing alert.");
  70. }
  71. Status = AlertStatus.Ignored;
  72. }
  73. public void MarkFailed()
  74. {
  75. Status = AlertStatus.Failed;
  76. }
  77. public void Resend()
  78. {
  79. if (Status is not (AlertStatus.Failed or AlertStatus.Skipped))
  80. {
  81. throw new InvalidOperationException("Only failed or skipped alerts can be resent.");
  82. }
  83. Status = AlertStatus.Queued;
  84. ArrivedAt = null;
  85. TotalDelayMs = null;
  86. }
  87. }