Files
PowderCoatingLogix/src/PowderCoating.Core/Entities/Refund.cs
T
spouliot 27bfd4db4d Close all GL entry gaps across the accounting surface
- Stripe payments/refunds/chargebacks now post DR/CR entries (PaymentController)
- Vendor credit void now reverses the posted GL lines (VendorCreditsController)
- Gift certificate issue/redeem/void post GL to account 2500 GC Liability;
  FinancialReportService Trial Balance + Balance Sheet include GC liability and
  breakage income; P&L shows deferred revenue deduction and breakage income line
- Customer deposits now post DR Checking / CR 2300 on record, reverse on delete;
  invoice auto-apply uses DR 2300 / CR AR (not a second bank debit); draft
  invoice delete reverses deposit-apply GL before the AR reversal
- Deposit.DepositAccountId column added; account 2300 seeded via migration
- InvoicesController.ApplyCredit now posts DR Sales Discounts / CR AR,
  consistent with CreditMemosController.Apply
- IssueRefund (cash/card) posts DR AR / CR Bank and sets Refund.DepositAccountId;
  refund modal gains a bank account selector hidden for store-credit path
- CancelRefund (cash/card) reverses the IssueRefund GL entries
- LedgerService GetAccountLedgerAsync + ComputePriorBalanceAsync now include
  Refunds, CreditMemoApplications, VendorCreditApplications, GC Liability (2500),
  and Customer Deposits (2300) so account ledger view and RecalculateAllAsync
  produce correct balances
- Three EF migrations applied: SeedSalesDiscountsAccount, AccountingGapsPhase2,
  AccountingDepositsGL
- Unit tests updated for new IAccountBalanceService constructor params (200/200)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 12:42:46 -04:00

38 lines
1.5 KiB
C#

using PowderCoating.Core.Enums;
namespace PowderCoating.Core.Entities;
/// <summary>
/// Records a refund issued to a customer against an invoice.
/// Does not move actual money — the shop issues the refund manually.
/// </summary>
public class Refund : BaseEntity
{
public int InvoiceId { get; set; }
public int? PaymentId { get; set; } // Specific payment being refunded (optional)
public decimal Amount { get; set; }
public DateTime RefundDate { get; set; } = DateTime.UtcNow;
public PaymentMethod RefundMethod { get; set; }
public string Reason { get; set; } = string.Empty;
public string? Reference { get; set; } // Check #, transaction ID, etc.
public string? Notes { get; set; }
public RefundStatus Status { get; set; } = RefundStatus.Pending;
public DateTime? IssuedDate { get; set; }
public string? IssuedById { get; set; }
/// <summary>Bank/checking account the refund was paid from. Mirrors Payment.DepositAccountId so
/// the Trial Balance can credit this account when computing bank balance.</summary>
public int? DepositAccountId { get; set; }
// For store-credit refunds: the CreditMemo created on their behalf
public int? CreditMemoId { get; set; }
// Navigation
public virtual Invoice Invoice { get; set; } = null!;
public virtual Payment? Payment { get; set; }
public virtual ApplicationUser? IssuedBy { get; set; }
public virtual CreditMemo? CreditMemo { get; set; }
}