54 lines
2.8 KiB
C#
54 lines
2.8 KiB
C#
using Baya.Domain.Entities.Booking;
|
|
using Baya.Domain.Entities.Identity;
|
|
using Baya.Domain.Entities.Messaging;
|
|
using Baya.Domain.Entities.Payments;
|
|
using Baya.Domain.Entities.Refunds;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
|
|
namespace Baya.Infrastructure.Persistence.Configuration.RefundsConfig;
|
|
|
|
/// <summary>
|
|
/// <c>refunds</c> — 1:N per <c>payment_transaction</c>. The <c>amount = fee_leg + payout_leg</c> reconciliation
|
|
/// is a DB CHECK (the "Σ refunded ≤ captured" invariant is a handler check under the booking refund lock, not a
|
|
/// single-row constraint). <c>ticket_id</c> is a nullable FK to <c>messaging.Tickets</c> (b15 shipped the table;
|
|
/// refinement-phase-6 added the constraint, <c>ON DELETE NO ACTION</c>).
|
|
/// </summary>
|
|
internal sealed class RefundConfig : IEntityTypeConfiguration<Refund>
|
|
{
|
|
public void Configure(EntityTypeBuilder<Refund> builder)
|
|
{
|
|
builder.ToTable("Refunds", "payments", t => t.HasCheckConstraint(
|
|
"CK_Refunds_LegSplit",
|
|
"[Amount] = [PlatformFeeRefundedIrr] + [NursePayoutRefundedIrr] " +
|
|
"AND [Amount] >= 0 AND [PlatformFeeRefundedIrr] >= 0 AND [NursePayoutRefundedIrr] >= 0"));
|
|
|
|
builder.Property(r => r.RefundChannel).HasMaxLength(20).IsRequired();
|
|
builder.Property(r => r.Status).HasMaxLength(20).IsRequired();
|
|
builder.Property(r => r.ReasonCategory).HasMaxLength(50);
|
|
builder.Property(r => r.ReasonNotes).HasMaxLength(1000);
|
|
builder.Property(r => r.AdminNotes).HasMaxLength(1000);
|
|
builder.Property(r => r.RejectedReason).HasMaxLength(500);
|
|
builder.Property(r => r.GatewayRefundReference).HasMaxLength(200);
|
|
builder.Property(r => r.ExternalRevertReference).HasMaxLength(200);
|
|
builder.Property(r => r.CancellationPolicyCode).HasMaxLength(50);
|
|
builder.Property(r => r.RefundPercentage).HasPrecision(6, 4);
|
|
builder.Property(r => r.RefundPercentageApplied).HasPrecision(5, 2);
|
|
|
|
builder.HasIndex(r => r.PaymentTransactionId);
|
|
builder.HasIndex(r => r.BookingId);
|
|
builder.HasIndex(r => r.RequestedByCustomerId);
|
|
builder.HasIndex(r => r.Status);
|
|
builder.HasIndex(r => r.TicketId);
|
|
|
|
builder.HasOne<PaymentTransaction>().WithMany().HasForeignKey(r => r.PaymentTransactionId).IsRequired();
|
|
builder.HasOne<Booking>().WithMany().HasForeignKey(r => r.BookingId).IsRequired();
|
|
builder.HasOne<CustomerProfile>().WithMany().HasForeignKey(r => r.RequestedByCustomerId).IsRequired();
|
|
// Forward-dep FK to the b15 tickets table (refinement-phase-6). Optional (nullable); NO ACTION so deleting
|
|
// a ticket never cascades into money rows.
|
|
builder.HasOne<Ticket>().WithMany().HasForeignKey(r => r.TicketId).OnDelete(DeleteBehavior.NoAction);
|
|
|
|
builder.HasQueryFilter(r => r.DeletedAt == null);
|
|
}
|
|
}
|