379b0de885
- AccountingDropdownHelper: wired into BillsController and ExpensesController, replacing 35-40 lines of duplicated DB queries per controller - AppConstants.StatusCodes: added Job.* and Quote.* constants to replace all magic status strings across Jobs, Quotes, Appointments, OvenScheduler, AiQuickQuote, QuoteApproval, and AccountingDropdownHelper - AccountingRules: extracted IsNormalDebitBalance into shared Infrastructure helper; removed duplicate private method from AccountBalanceService and LedgerService (~50 lines deleted) - AccountDataExportController: extracted 9 Fetch*Async methods (superset of includes) so Add*Sheet and Build*Csv no longer duplicate DB queries; each entity is queried once regardless of whether XLSX or CSV format is requested - BillsController.Create and ExpensesController.Create wrapped in ExecuteInTransactionAsync; blob uploads moved after commit to keep financial data atomic and prevent orphaned blobs from rolling back - Number generators (Appointments, CreditMemo, OvenBatch) fixed from full-table GetAllAsync to prefix-filtered FindAsync Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
42 lines
1.6 KiB
C#
42 lines
1.6 KiB
C#
using PowderCoating.Core.Enums;
|
|
|
|
namespace PowderCoating.Infrastructure.Services;
|
|
|
|
/// <summary>
|
|
/// Single source of truth for double-entry sign conventions shared by
|
|
/// <see cref="AccountBalanceService"/> and <see cref="LedgerService"/>.
|
|
/// Centralised here so that adding a new AccountSubType only requires
|
|
/// one edit rather than two independently maintained switch expressions.
|
|
/// </summary>
|
|
internal static class AccountingRules
|
|
{
|
|
/// <summary>
|
|
/// Returns <c>true</c> for sub-types whose normal balance is a debit
|
|
/// (Assets, COGS, Expenses). Sub-type is used rather than AccountType
|
|
/// because it is constrained to a known enum set and cannot be
|
|
/// misconfigured by a user. Expense enum values are ≥ 50 by convention,
|
|
/// allowing a catch-all range match for any future expense sub-types.
|
|
/// </summary>
|
|
internal static bool IsNormalDebitBalance(AccountSubType subType) => subType switch
|
|
{
|
|
// Asset subtypes → normal debit balance
|
|
AccountSubType.Cash
|
|
or AccountSubType.Checking
|
|
or AccountSubType.Savings
|
|
or AccountSubType.AccountsReceivable
|
|
or AccountSubType.Inventory
|
|
or AccountSubType.FixedAsset
|
|
or AccountSubType.OtherCurrentAsset
|
|
or AccountSubType.OtherAsset => true,
|
|
|
|
// COGS → normal debit balance
|
|
AccountSubType.CostOfGoodsSold => true,
|
|
|
|
// Expense subtypes (enum values ≥ 50) → normal debit balance
|
|
var st when (int)st >= 50 => true,
|
|
|
|
// Liability subtypes (AP, CreditCard, etc.), Equity, Revenue → normal credit balance
|
|
_ => false
|
|
};
|
|
}
|