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>
This commit is contained in:
2026-05-13 12:42:46 -04:00
parent 787d1504ef
commit 27bfd4db4d
24 changed files with 33296 additions and 83 deletions
@@ -2892,6 +2892,9 @@ namespace PowderCoating.Infrastructure.Migrations
b.Property<string>("DeletedBy")
.HasColumnType("nvarchar(max)");
b.Property<int?>("DepositAccountId")
.HasColumnType("int");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
@@ -6574,7 +6577,7 @@ namespace PowderCoating.Infrastructure.Migrations
{
Id = 1,
CompanyId = 0,
CreatedAt = new DateTime(2026, 5, 13, 1, 34, 45, 450, DateTimeKind.Utc).AddTicks(8377),
CreatedAt = new DateTime(2026, 5, 13, 14, 57, 30, 15, DateTimeKind.Utc).AddTicks(5641),
Description = "Standard pricing for regular customers",
DiscountPercent = 0m,
IsActive = true,
@@ -6585,7 +6588,7 @@ namespace PowderCoating.Infrastructure.Migrations
{
Id = 2,
CompanyId = 0,
CreatedAt = new DateTime(2026, 5, 13, 1, 34, 45, 450, DateTimeKind.Utc).AddTicks(8383),
CreatedAt = new DateTime(2026, 5, 13, 14, 57, 30, 15, DateTimeKind.Utc).AddTicks(5655),
Description = "5% discount for preferred customers",
DiscountPercent = 5m,
IsActive = true,
@@ -6596,7 +6599,7 @@ namespace PowderCoating.Infrastructure.Migrations
{
Id = 3,
CompanyId = 0,
CreatedAt = new DateTime(2026, 5, 13, 1, 34, 45, 450, DateTimeKind.Utc).AddTicks(8385),
CreatedAt = new DateTime(2026, 5, 13, 14, 57, 30, 15, DateTimeKind.Utc).AddTicks(5656),
Description = "10% discount for premium customers",
DiscountPercent = 10m,
IsActive = true,
@@ -7654,6 +7657,9 @@ namespace PowderCoating.Infrastructure.Migrations
b.Property<string>("DeletedBy")
.HasColumnType("nvarchar(max)");
b.Property<int?>("DepositAccountId")
.HasColumnType("int");
b.Property<int>("InvoiceId")
.HasColumnType("int");
@@ -8384,6 +8390,9 @@ namespace PowderCoating.Infrastructure.Migrations
b.Property<string>("Memo")
.HasColumnType("nvarchar(max)");
b.Property<DateTime?>("PostedDate")
.HasColumnType("datetime2");
b.Property<decimal>("RemainingAmount")
.HasColumnType("decimal(18,2)");