OrderRefundItem.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. using System.ComponentModel.DataAnnotations;
  2. using System.ComponentModel.DataAnnotations.Schema;
  3. using Domain.Entities.Store.ValueObject;
  4. namespace Domain.Entities.Store;
  5. /// <summary>
  6. /// 환불 단위 — 쿠폰 1개 = 1행. OrderRefund 1건에 N개의 OrderRefundItem (일괄 환불 지원).
  7. ///
  8. /// 설계 이유: OrderRefund 자체는 Amount 합계만 가지고 있어 어떤 쿠폰/OrderItem 이
  9. /// 환불되는지 추적 불가. 이 테이블이 정확한 환불 대상 + 후처리(회수/만료) 정책을 보관.
  10. ///
  11. /// ProcessRefund 시 이 행들을 순회해:
  12. /// - 다날 부분 취소 (OrderRefund.Amount 단위로 1회)
  13. /// - 각 CouponCode 에 PostRefundAction 적용 (Restore / Expire)
  14. /// - MemberInventory 의 해당 행 제거
  15. /// </summary>
  16. public class OrderRefundItem
  17. {
  18. [ForeignKey(nameof(OrderRefundID))]
  19. public virtual OrderRefund? OrderRefund { get; private set; }
  20. [ForeignKey(nameof(OrderItemID))]
  21. public virtual OrderItem? OrderItem { get; private set; }
  22. [ForeignKey(nameof(CouponCodeID))]
  23. public virtual CouponCode? CouponCode { get; private set; }
  24. [Key]
  25. public int ID { get; private set; }
  26. public int OrderRefundID { get; private set; }
  27. public int OrderItemID { get; private set; }
  28. public int CouponCodeID { get; private set; }
  29. /// <summary>환불 단가 (스냅샷). OrderItem.UnitPrice 와 동일하지만 OrderItem 가격 변동 대비 보관.</summary>
  30. public int UnitAmount { get; private set; }
  31. public CouponPostRefundAction PostRefundAction { get; private set; }
  32. public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
  33. private OrderRefundItem() { }
  34. public static OrderRefundItem Create(int orderRefundID, int orderItemID, int couponCodeID, int unitAmount, CouponPostRefundAction action)
  35. {
  36. if (orderRefundID <= 0)
  37. {
  38. throw new ArgumentOutOfRangeException(nameof(orderRefundID));
  39. }
  40. if (orderItemID <= 0)
  41. {
  42. throw new ArgumentOutOfRangeException(nameof(orderItemID));
  43. }
  44. if (couponCodeID <= 0)
  45. {
  46. throw new ArgumentOutOfRangeException(nameof(couponCodeID));
  47. }
  48. if (unitAmount <= 0)
  49. {
  50. throw new ArgumentOutOfRangeException(nameof(unitAmount), "UnitAmount must be positive.");
  51. }
  52. return new OrderRefundItem
  53. {
  54. OrderRefundID = orderRefundID,
  55. OrderItemID = orderItemID,
  56. CouponCodeID = couponCodeID,
  57. UnitAmount = unitAmount,
  58. PostRefundAction = action
  59. };
  60. }
  61. }