DonorChannelStats.cs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. using System.ComponentModel.DataAnnotations.Schema;
  2. using Domain.Entities.Members;
  3. namespace Domain.Entities.Donations;
  4. /// <summary>
  5. /// 후원자별 × 채널별 누적 후원 금액 (칭호 획득 판정용).
  6. /// 복합 PK: (DonorMemberID, ChannelID)
  7. /// </summary>
  8. public sealed class DonorChannelStats
  9. {
  10. [ForeignKey(nameof(DonorMemberID))]
  11. public Member Donor { get; private set; } = null!;
  12. [ForeignKey(nameof(ChannelID))]
  13. public Channel Channel { get; private set; } = null!;
  14. public int DonorMemberID { get; private set; }
  15. public int ChannelID { get; private set; }
  16. public long CumulativeAmount { get; private set; }
  17. public int DonationCount { get; private set; }
  18. public DateTime? FirstDonatedAt { get; private set; }
  19. public DateTime? LastDonatedAt { get; private set; }
  20. public DateTime? UpdatedAt { get; private set; }
  21. public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
  22. private DonorChannelStats() { }
  23. private DonorChannelStats(int donorMemberID, int channelID)
  24. {
  25. if (donorMemberID <= 0)
  26. {
  27. throw new ArgumentOutOfRangeException(nameof(donorMemberID));
  28. }
  29. if (channelID <= 0)
  30. {
  31. throw new ArgumentOutOfRangeException(nameof(channelID));
  32. }
  33. DonorMemberID = donorMemberID;
  34. ChannelID = channelID;
  35. }
  36. public static DonorChannelStats Create(int donorMemberID, int channelID)
  37. {
  38. return new(donorMemberID, channelID);
  39. }
  40. public void AddDonation(long amount, DateTime when)
  41. {
  42. if (amount <= 0)
  43. {
  44. return;
  45. }
  46. CumulativeAmount += amount;
  47. DonationCount++;
  48. FirstDonatedAt ??= when;
  49. LastDonatedAt = when;
  50. UpdatedAt = DateTime.UtcNow;
  51. }
  52. }